Author: ion
Date: Wed Aug 1 07:54:37 2012
New Revision: 57011
URL:
http://svn.reactos.org/svn/reactos?rev=57011&view=rev
Log:
[NTOSKRNL]: Implement last bits of session space support (minus session pool). Processes
now have a ->Session pointer! Implement and enable MmSessionId in a bunch of places.
[NTOSKRNL]: Set MiSessionSpaceWs address and use where needed.
[NTOSKRNL]: Initialize the session working set, and add support to MiLockWorkingSet and
MiUnlockWorkingSet for session WS.
[NTOSKRNL]: Implement MiSessionAddProcess and MiSessionRemoveProcess which does the work
required for this.
[NTOSKRNL]: Fix IoGetIrpRequestorProcess.
In my private branch, MmMapViewInSessionSpace is working fine for the user and GDI heaps.
Will enable after TestBot tests.
Modified:
trunk/reactos/ntoskrnl/include/internal/mm.h
trunk/reactos/ntoskrnl/io/iomgr/irp.c
trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c
trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
trunk/reactos/ntoskrnl/mm/ARM3/mminit.c
trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
trunk/reactos/ntoskrnl/mm/ARM3/procsup.c
trunk/reactos/ntoskrnl/mm/ARM3/section.c
trunk/reactos/ntoskrnl/ps/process.c
trunk/reactos/ntoskrnl/ps/security.c
Modified: trunk/reactos/ntoskrnl/include/internal/mm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/mm.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/mm.h [iso-8859-1] Wed Aug 1 07:54:37 2012
@@ -496,6 +496,12 @@
IN PVOID Address
);
+ULONG
+NTAPI
+MmGetSessionId(
+ IN PEPROCESS Process
+);
+
/* marea.c *******************************************************************/
NTSTATUS
Modified: trunk/reactos/ntoskrnl/io/iomgr/irp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/irp.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/irp.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/irp.c [iso-8859-1] Wed Aug 1 07:54:37 2012
@@ -1615,7 +1615,14 @@
/* Return the requestor process */
if (Irp->Tail.Overlay.Thread)
{
- return Irp->Tail.Overlay.Thread->ThreadsProcess;
+ if (Irp->ApcEnvironment == OriginalApcEnvironment)
+ {
+ return Irp->Tail.Overlay.Thread->ThreadsProcess;
+ }
+ else if (Irp->ApcEnvironment == AttachedApcEnvironment)
+ {
+ return (PEPROCESS)Irp->Tail.Overlay.Thread->Tcb.ApcState.Process;
+ }
}
return NULL;
@@ -1631,10 +1638,8 @@
PEPROCESS Process;
/* Return the requestor process' id */
- if ((Process = IoGetRequestorProcess(Irp)))
- {
- return PtrToUlong(Process->UniqueProcessId);
- }
+ Process = IoGetRequestorProcess(Irp);
+ if (Process) return PtrToUlong(Process->UniqueProcessId);
return 0;
}
@@ -1650,10 +1655,10 @@
PEPROCESS Process;
/* Return the session */
- if ((Process = IoGetRequestorProcess(Irp)))
- {
- // FIXME: broken
- *pSessionId = PtrToUlong(Process->Session);
+ if (Irp->Tail.Overlay.Thread)
+ {
+ Process = Irp->Tail.Overlay.Thread->ThreadsProcess;
+ *pSessionId = MmGetSessionId(Process);
return STATUS_SUCCESS;
}
Modified: trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/i386/init…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c [iso-8859-1] Wed Aug 1 07:54:37 2012
@@ -110,6 +110,7 @@
MiSessionImagePteStart = MiAddressToPte(MiSessionImageStart);
MiSessionImagePteEnd = MiAddressToPte(MiSessionImageEnd);
MiSessionBasePte = MiAddressToPte(MmSessionBase);
+ MiSessionSpaceWs = (PVOID)((ULONG_PTR)MiSessionViewStart + MmSessionViewSize);
MiSessionLastPte = MiAddressToPte(MiSessionSpaceEnd);
/* Initialize session space */
Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/miarm.h?r…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] Wed Aug 1 07:54:37 2012
@@ -687,6 +687,7 @@
extern PVOID MiSessionPoolEnd; // 0xBE000000
extern PVOID MiSessionPoolStart; // 0xBD000000
extern PVOID MiSessionViewStart; // 0xBE000000
+extern PVOID MiSessionSpaceWs;
extern ULONG MmMaximumDeadKernelStacks;
extern SLIST_HEADER MmDeadStackSListHead;
extern MM_AVL_TABLE MmSectionBasedRoot;
@@ -1059,9 +1060,10 @@
}
else if (WorkingSet->Flags.SessionSpace)
{
- /* We don't implement this yet */
- UNIMPLEMENTED;
- while (TRUE);
+ /* Own the session working set */
+ ASSERT((Thread->OwnsSessionWorkingSetExclusive == FALSE) &&
+ (Thread->OwnsSessionWorkingSetShared == FALSE));
+ Thread->OwnsSessionWorkingSetExclusive = TRUE;
}
else
{
@@ -1093,9 +1095,10 @@
}
else if (WorkingSet->Flags.SessionSpace)
{
- /* We don't implement this yet */
- UNIMPLEMENTED;
- while (TRUE);
+ /* Release the session working set */
+ ASSERT((Thread->OwnsSessionWorkingSetExclusive == TRUE) ||
+ (Thread->OwnsSessionWorkingSetShared == TRUE));
+ Thread->OwnsSessionWorkingSetExclusive = 0;
}
else
{
@@ -1608,6 +1611,24 @@
NTAPI
MiInitializeSystemSpaceMap(
IN PMMSESSION InputSession OPTIONAL
+);
+
+VOID
+NTAPI
+MiSessionRemoveProcess(
+ VOID
+);
+
+VOID
+NTAPI
+MiReleaseProcessReferenceToSessionDataPage(
+ IN PMM_SESSION_SPACE SessionGlobal
+);
+
+VOID
+NTAPI
+MiSessionAddProcess(
+ IN PEPROCESS NewProcess
);
NTSTATUS
Modified: trunk/reactos/ntoskrnl/mm/ARM3/mminit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/mminit.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/mminit.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/mminit.c [iso-8859-1] Wed Aug 1 07:54:37 2012
@@ -128,6 +128,7 @@
PVOID MiSessionSpaceEnd; // 0xC0000000
PVOID MiSessionImageEnd; // 0xC0000000
PVOID MiSessionImageStart; // 0xBF800000
+PVOID MiSessionSpaceWs;
PVOID MiSessionViewStart; // 0xBE000000
PVOID MiSessionPoolEnd; // 0xBE000000
PVOID MiSessionPoolStart; // 0xBD000000
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pagfault.…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] Wed Aug 1 07:54:37 2012
@@ -153,9 +153,79 @@
FASTCALL
MiCheckPdeForSessionSpace(IN PVOID Address)
{
- /* Code not yet tested */
- ASSERT(FALSE);
- return STATUS_NOT_IMPLEMENTED;
+ MMPTE TempPde;
+ PMMPTE PointerPde;
+ PVOID SessionPageTable;
+ ULONG Index;
+
+ /* Is this a session PTE? */
+ if (MI_IS_SESSION_PTE(Address))
+ {
+ /* Make sure the PDE for session space is valid */
+ PointerPde = MiAddressToPde(MmSessionSpace);
+ if (!PointerPde->u.Hard.Valid)
+ {
+ /* This means there's no valid session, bail out */
+ DbgPrint("MiCheckPdeForSessionSpace: No current session for PTE
%p\n",
+ Address);
+ DbgBreakPoint();
+ return STATUS_ACCESS_VIOLATION;
+ }
+
+ /* Now get the session-specific page table for this address */
+ SessionPageTable = MiPteToAddress(Address);
+ PointerPde = MiPteToAddress(Address);
+ if (PointerPde->u.Hard.Valid) return STATUS_WAIT_1;
+
+ /* It's not valid, so find it in the page table array */
+ Index = ((ULONG_PTR)SessionPageTable - (ULONG_PTR)MmSessionBase) >> 22;
+ TempPde.u.Long = MmSessionSpace->PageTables[Index].u.Long;
+ if (TempPde.u.Hard.Valid)
+ {
+ /* The copy is valid, so swap it in */
+ InterlockedExchange((PLONG)PointerPde, TempPde.u.Long);
+ return STATUS_WAIT_1;
+ }
+
+ /* We don't seem to have allocated a page table for this address yet? */
+ DbgPrint("MiCheckPdeForSessionSpace: No Session PDE for PTE %p, %p\n",
+ PointerPde->u.Long, SessionPageTable);
+ DbgBreakPoint();
+ return STATUS_ACCESS_VIOLATION;
+ }
+
+ /* Is the address also a session address? If not, we're done */
+ if (!MI_IS_SESSION_ADDRESS(Address)) return STATUS_SUCCESS;
+
+ /* It is, so again get the PDE for session space */
+ PointerPde = MiAddressToPde(MmSessionSpace);
+ if (!PointerPde->u.Hard.Valid)
+ {
+ /* This means there's no valid session, bail out */
+ DbgPrint("MiCheckPdeForSessionSpace: No current session for VA %p\n",
+ Address);
+ DbgBreakPoint();
+ return STATUS_ACCESS_VIOLATION;
+ }
+
+ /* Now get the PDE for the address itself */
+ PointerPde = MiAddressToPde(Address);
+ if (!PointerPde->u.Hard.Valid)
+ {
+ /* Do the swap, we should be good to go */
+ Index = ((ULONG_PTR)Address - (ULONG_PTR)MmSessionBase) >> 22;
+ PointerPde->u.Long = MmSessionSpace->PageTables[Index].u.Long;
+ if (PointerPde->u.Hard.Valid) return STATUS_WAIT_1;
+
+ /* We had not allocated a page table for this session address yet, fail! */
+ DbgPrint("MiCheckPdeForSessionSpace: No Session PDE for VA %p, %p\n",
+ PointerPde->u.Long, Address);
+ DbgBreakPoint();
+ return STATUS_ACCESS_VIOLATION;
+ }
+
+ /* It's valid, so there's nothing to do */
+ return STATUS_SUCCESS;
}
NTSTATUS
@@ -305,16 +375,14 @@
/* Check if we need a zero page */
NeedZero = (OldIrql != MM_NOIRQL);
-#if 0
/* Session-backed image views must be zeroed */
if ((Process == HYDRA_PROCESS) &&
((MI_IS_SESSION_IMAGE_ADDRESS(Address)) ||
- ((Address >= (PVOID)MiSessionViewStart) &&
- (Address < (PVOID)MiSessionSpaceWs))))
+ ((Address >= MiSessionViewStart) && (Address <
MiSessionSpaceWs))))
{
NeedZero = TRUE;
}
-#endif
+
/* Hardcode unknown color */
Color = 0xFFFFFFFF;
}
@@ -1200,18 +1268,22 @@
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
return STATUS_SUCCESS;
}
- else
- {
- /* Not yet handled */
- ASSERT(FALSE);
- }
}
/* Check if this was a session PTE that needs to remap the session PDE */
if (MI_IS_SESSION_PTE(Address))
{
- /* Not yet handled */
- ASSERT(FALSE);
+ /* Do the remapping */
+ Status = MiCheckPdeForSessionSpace(Address);
+ if (!NT_SUCCESS(Status))
+ {
+ /* It failed, this address is invalid */
+ KeBugCheckEx(PAGE_FAULT_IN_NONPAGED_AREA,
+ (ULONG_PTR)Address,
+ StoreInstruction,
+ (ULONG_PTR)TrapInformation,
+ 6);
+ }
}
/* Check for a fault on the page table or hyperspace */
@@ -1249,8 +1321,17 @@
}
else
{
- /* Not yet handled */
- ASSERT(FALSE);
+ /* Use the session process and working set */
+ CurrentProcess = HYDRA_PROCESS;
+ WorkingSet = &MmSessionSpace->GlobalVirtualAddress->Vm;
+
+ /* Make sure we don't have a recursive working set lock */
+ if ((CurrentThread->OwnsSessionWorkingSetExclusive) ||
+ (CurrentThread->OwnsSessionWorkingSetShared))
+ {
+ /* Fail */
+ return STATUS_IN_PAGE_ERROR | 0x10000000;
+ }
}
/* Acquire the working set lock */
@@ -1282,8 +1363,28 @@
}
}
- /* Case not yet handled */
- ASSERT(!IsSessionAddress);
+ /* Check for read-only write in session space */
+ if ((IsSessionAddress) &&
+ (StoreInstruction) &&
+ !(TempPte.u.Hard.Write))
+ {
+ /* Sanity check */
+ ASSERT(MI_IS_SESSION_IMAGE_ADDRESS(Address));
+
+ /* Was this COW? */
+ if (TempPte.u.Hard.CopyOnWrite == 0)
+ {
+ /* Then this is not allowed */
+ KeBugCheckEx(ATTEMPTED_WRITE_TO_READONLY_MEMORY,
+ (ULONG_PTR)Address,
+ (ULONG_PTR)TempPte.u.Long,
+ (ULONG_PTR)TrapInformation,
+ 13);
+ }
+
+ /* Otherwise, handle COW */
+ ASSERT(FALSE);
+ }
/* Release the working set */
MiUnlockWorkingSet(CurrentThread, WorkingSet);
@@ -1315,8 +1416,16 @@
/* Get the prototype PTE! */
ProtoPte = MiProtoPteToPte(&TempPte);
- /* Case not yet handled */
- ASSERT(!IsSessionAddress);
+ /* Do we need to locate the prototype PTE in session space? */
+ if ((IsSessionAddress) &&
+ (TempPte.u.Soft.PageFileHigh == MI_PTE_LOOKUP_NEEDED))
+ {
+ /* Yep, go find it as well as the VAD for it */
+ ProtoPte = MiCheckVirtualAddress(Address,
+ &ProtectionCode,
+ &Vad);
+ ASSERT(ProtoPte != NULL);
+ }
}
else
{
Modified: trunk/reactos/ntoskrnl/mm/ARM3/procsup.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/procsup.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/procsup.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/procsup.c [iso-8859-1] Wed Aug 1 07:54:37 2012
@@ -577,9 +577,7 @@
//
// Get the Locale ID
//
-#if ROS_HAS_SESSIONS
return ((PMM_SESSION_SPACE)Process->Session)->LocaleId;
-#endif
}
}
@@ -698,7 +696,7 @@
//
// Session ID
//
- if (Process->Session) Peb->SessionId = 0; // MmGetSessionId(Process);
+ MmGetSessionId(Process);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@@ -1317,6 +1315,9 @@
/* Let go of the system PTE */
MiReleaseSystemPtes(PointerPte, 1, SystemPteSpace);
+
+ /* Add the process to the session */
+ MiSessionAddProcess(Process);
return TRUE;
}
#endif
@@ -1331,6 +1332,9 @@
/* Only support this */
ASSERT(Process->AddressSpaceInitialized == 2);
+
+ /* Remove from the session */
+ MiSessionRemoveProcess();
/* Lock the process address space from changes */
MmLockAddressSpace(&Process->Vm);
@@ -1383,6 +1387,7 @@
/* Free the VAD memory */
ExFreePool(Vad);
}
+
/* Delete the shared user data section */
MiDeleteVirtualAddresses(USER_SHARED_DATA, USER_SHARED_DATA, NULL);
@@ -1447,8 +1452,8 @@
/* Release the PFN lock */
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
- /* No support for sessions yet */
- ASSERT(Process->Session == 0);
+ /* Drop a reference on the session */
+ if (Process->Session)
MiReleaseProcessReferenceToSessionDataPage(Process->Session);
/* Clear out the PDE pages */
Process->Pcb.DirectoryTableBase[0] = 0;
@@ -1526,6 +1531,257 @@
OldIrql = KeAcquireQueuedSpinLock(LockQueueExpansionLock);
Process->Vm.Flags.SessionLeader = TRUE;
KeReleaseQueuedSpinLock(LockQueueExpansionLock, OldIrql);
+}
+
+ULONG
+NTAPI
+MmGetSessionId(IN PEPROCESS Process)
+{
+ PMM_SESSION_SPACE SessionGlobal;
+
+ /* The session leader is always session zero */
+ if (Process->Vm.Flags.SessionLeader == 1) return 0;
+
+ /* Otherwise, get the session global, and read the session ID from it */
+ SessionGlobal = (PMM_SESSION_SPACE)Process->Session;
+ if (!SessionGlobal) return 0;
+ return SessionGlobal->SessionId;
+}
+
+VOID
+NTAPI
+MiReleaseProcessReferenceToSessionDataPage(IN PMM_SESSION_SPACE SessionGlobal)
+{
+ ULONG i, SessionId;
+ PMMPTE PointerPte;
+ PFN_NUMBER PageFrameIndex[MI_SESSION_DATA_PAGES_MAXIMUM];
+ PMMPFN Pfn1;
+ KIRQL OldIrql;
+
+ /* Is there more than just this reference? If so, bail out */
+ if (InterlockedDecrement(&SessionGlobal->ProcessReferenceToSession)) return;
+
+ /* Get the session ID */
+ SessionId = SessionGlobal->SessionId;
+ DPRINT1("Last process in sessino %d going down!!!\n", SessionId);
+
+ /* Free the session page tables */
+ ExFreePool(SessionGlobal->PageTables);
+ ASSERT(!MI_IS_PHYSICAL_ADDRESS(SessionGlobal));
+
+ /* Capture the data page PFNs */
+ PointerPte = MiAddressToPte(SessionGlobal);
+ for (i = 0; i < MiSessionDataPages; i++)
+ {
+ PageFrameIndex[i] = PFN_FROM_PTE(PointerPte + i);
+ }
+
+ /* Release them */
+ MiReleaseSystemPtes(PointerPte, MiSessionDataPages, SystemPteSpace);
+
+ /* Mark them as deleted */
+ for (i = 0; i < MiSessionDataPages; i++)
+ {
+ Pfn1 = MI_PFN_ELEMENT(PageFrameIndex[i]);
+ MI_SET_PFN_DELETED(Pfn1);
+ }
+
+ /* Loop every data page and drop a reference count */
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+ for (i = 0; i < MiSessionDataPages; i++)
+ {
+ /* Sanity check that the page is correct, then decrement it */
+ Pfn1 = MI_PFN_ELEMENT(PageFrameIndex[i]);
+ ASSERT(Pfn1->u2.ShareCount == 1);
+ ASSERT(Pfn1->u3.e2.ReferenceCount == 1);
+ MiDecrementShareCount(Pfn1, PageFrameIndex[i]);
+ }
+
+ /* Done playing with pages, release the lock */
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+
+ /* Decrement the number of data pages */
+ InterlockedDecrement(&MmSessionDataPages);
+
+ /* Free this session ID from the session bitmap */
+ KeAcquireGuardedMutex(&MiSessionIdMutex);
+ ASSERT(RtlCheckBit(MiSessionIdBitmap, SessionId));
+ RtlClearBit(MiSessionIdBitmap, SessionId);
+ KeReleaseGuardedMutex(&MiSessionIdMutex);
+}
+
+VOID
+NTAPI
+MiSessionRemoveProcess(VOID)
+{
+ PEPROCESS CurrentProcess = PsGetCurrentProcess();
+
+ /* If the process isn't already in a session, or if it's the leader... */
+ if (!(CurrentProcess->Flags & PSF_PROCESS_IN_SESSION_BIT) ||
+ (CurrentProcess->Vm.Flags.SessionLeader))
+ {
+ /* Then there's nothing to do */
+ return;
+ }
+
+ /* Sanity check */
+ ASSERT(MmIsAddressValid(MmSessionSpace) == TRUE);
+
+ /* Remove the process from the list ,and dereference the session */
+ RemoveEntryList(&CurrentProcess->SessionProcessLinks);
+ //MiDereferenceSession();
+}
+
+VOID
+NTAPI
+MiSessionAddProcess(IN PEPROCESS NewProcess)
+{
+ PMM_SESSION_SPACE SessionGlobal;
+
+ /* The current process must already be in a session */
+ if (!(PsGetCurrentProcess()->Flags & PSF_PROCESS_IN_SESSION_BIT)) return;
+
+ /* Sanity check */
+ ASSERT(MmIsAddressValid(MmSessionSpace) == TRUE);
+
+ /* Get the global session */
+ SessionGlobal = MmSessionSpace->GlobalVirtualAddress;
+
+ /* Increment counters */
+ InterlockedIncrement((PLONG)&SessionGlobal->ReferenceCount);
+ InterlockedIncrement(&SessionGlobal->ResidentProcessCount);
+ InterlockedIncrement(&SessionGlobal->ProcessReferenceToSession);
+
+ /* Set the session pointer */
+ ASSERT(NewProcess->Session == NULL);
+ NewProcess->Session = SessionGlobal;
+
+ /* Insert it into the process list */
+ InsertTailList(&SessionGlobal->ProcessList,
&NewProcess->SessionProcessLinks);
+
+ /* Set the flag */
+ PspSetProcessFlag(NewProcess, PSF_PROCESS_IN_SESSION_BIT);
+}
+
+NTSTATUS
+NTAPI
+MiSessionInitializeWorkingSetList(VOID)
+{
+ KIRQL OldIrql;
+ PMMPTE PointerPte, PointerPde;
+ MMPTE TempPte;
+ ULONG Color, Index;
+ PFN_NUMBER PageFrameIndex;
+ PMM_SESSION_SPACE SessionGlobal;
+ BOOLEAN AllocatedPageTable;
+ PMMWSL WorkingSetList;
+
+ /* Get pointers to session global and the session working set list */
+ SessionGlobal = MmSessionSpace->GlobalVirtualAddress;
+ WorkingSetList = (PMMWSL)MiSessionSpaceWs;
+
+ /* Fill out the two pointers */
+ MmSessionSpace->Vm.VmWorkingSetList = WorkingSetList;
+ MmSessionSpace->Wsle = (PMMWSLE)WorkingSetList->UsedPageTableEntries;
+
+ /* Get the PDE for the working set, and check if it's already allocated */
+ PointerPde = MiAddressToPde(WorkingSetList);
+ if (PointerPde->u.Hard.Valid == 1)
+ {
+ /* Nope, we'll have to do it */
+ ASSERT(PointerPde->u.Hard.Global == 0);
+ AllocatedPageTable = FALSE;
+ }
+ else
+ {
+ /* Yep, that makes our job easier */
+ AllocatedPageTable = TRUE;
+ }
+
+ /* Get the PTE for the working set */
+ PointerPte = MiAddressToPte(WorkingSetList);
+
+ /* Initialize the working set lock, and lock the PFN database */
+ ExInitializePushLock(&SessionGlobal->Vm.WorkingSetMutex);
+ //MmLockPageableSectionByHandle(ExPageLockHandle);
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+
+ /* Check if we need a page table */
+ if (AllocatedPageTable == TRUE)
+ {
+ /* Get a zeroed colored zero page */
+ Color = MI_GET_NEXT_COLOR();
+ PageFrameIndex = MiRemoveZeroPageSafe(Color);
+ if (!PageFrameIndex)
+ {
+ /* No zero pages, grab a free one */
+ PageFrameIndex = MiRemoveAnyPage(Color);
+
+ /* Zero it outside the PFN lock */
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+ MiZeroPhysicalPage(PageFrameIndex);
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+ }
+
+ /* Write a valid PDE for it */
+ TempPte.u.Long = ValidKernelPdeLocal.u.Long;
+ TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
+ MI_WRITE_VALID_PTE(PointerPde, TempPte);
+
+ /* Add this into the list */
+ Index = ((ULONG_PTR)WorkingSetList - (ULONG_PTR)MmSessionBase) >> 22;
+ MmSessionSpace->PageTables[Index] = TempPte;
+
+ /* Initialize the page directory page, and now zero the working set list itself
*/
+ MiInitializePfnForOtherProcess(PageFrameIndex,
+ PointerPde,
+ MmSessionSpace->SessionPageDirectoryIndex);
+ KeZeroPages(PointerPte, PAGE_SIZE);
+ }
+
+ /* Get a zeroed colored zero page */
+ Color = MI_GET_NEXT_COLOR();
+ PageFrameIndex = MiRemoveZeroPageSafe(Color);
+ if (!PageFrameIndex)
+ {
+ /* No zero pages, grab a free one */
+ PageFrameIndex = MiRemoveAnyPage(Color);
+
+ /* Zero it outside the PFN lock */
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+ MiZeroPhysicalPage(PageFrameIndex);
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+ }
+
+ /* Write a valid PTE for it */
+ TempPte.u.Long = ValidKernelPteLocal.u.Long;
+ TempPte.u.Hard.Dirty = TRUE;
+ TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
+
+ /* Initialize the working set list page */
+ MiInitializePfnAndMakePteValid(PageFrameIndex, PointerPte, TempPte);
+
+ /* Now we can release the PFN database lock */
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+
+ /* Fill out the working set structure */
+ MmSessionSpace->Vm.Flags.SessionSpace = 1;
+ MmSessionSpace->Vm.MinimumWorkingSetSize = 20;
+ MmSessionSpace->Vm.MaximumWorkingSetSize = 384;
+ WorkingSetList->LastEntry = 20;
+ WorkingSetList->HashTable = NULL;
+ WorkingSetList->HashTableSize = 0;
+ WorkingSetList->Wsle = MmSessionSpace->Wsle;
+
+ /* FIXME: Handle list insertions */
+ ASSERT(SessionGlobal->WsListEntry.Flink == NULL);
+ ASSERT(SessionGlobal->WsListEntry.Blink == NULL);
+ ASSERT(SessionGlobal->Vm.WorkingSetExpansionLinks.Flink == NULL);
+ ASSERT(SessionGlobal->Vm.WorkingSetExpansionLinks.Blink == NULL);
+
+ /* All done, return */
+ //MmUnlockPageableImageSection(ExPageLockHandle);
+ return STATUS_SUCCESS;
}
NTSTATUS
@@ -1770,12 +2026,31 @@
MiSessionLeader(Process);
}
- /* FIXME: Actually create a session */
+ /* Create the session */
KeEnterCriticalRegion();
Status = MiSessionCreateInternal(SessionId);
+ if (!NT_SUCCESS(Status))
+ {
+ KeLeaveCriticalRegion();
+ return Status;
+ }
+
+ /* Set up the session working set */
+ Status = MiSessionInitializeWorkingSetList();
+ if (!NT_SUCCESS(Status))
+ {
+ /* Fail */
+ //MiDereferenceSession();
+ ASSERT(FALSE);
+ KeLeaveCriticalRegion();
+ return Status;
+ }
+
+ /* All done */
KeLeaveCriticalRegion();
/* Set and assert the flags, and return */
+ MmSessionSpace->u.Flags.Initialized = 1;
PspSetProcessFlag(Process, PSF_PROCESS_IN_SESSION_BIT);
ASSERT(MiSessionLeaderExists == 1);
return Status;
Modified: trunk/reactos/ntoskrnl/mm/ARM3/section.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/section.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/section.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/section.c [iso-8859-1] Wed Aug 1 07:54:37 2012
@@ -827,7 +827,7 @@
/* Get the start and end PDE, then loop each one */
StartPde = MiAddressToPde(StartVa);
EndPde = MiAddressToPde((PVOID)((ULONG_PTR)EndVa - 1));
- Index = (ULONG_PTR)StartVa >> 22;
+ Index = ((ULONG_PTR)StartVa - (ULONG_PTR)MmSessionBase) >> 22;
while (StartPde <= EndPde)
{
/* If we don't already have a page table for it, increment count */
@@ -843,7 +843,7 @@
/* Reset the start PDE and index */
StartPde = MiAddressToPde(StartVa);
- Index = (ULONG_PTR)StartVa >> 22;
+ Index = ((ULONG_PTR)StartVa - (ULONG_PTR)MmSessionBase) >> 22;
/* Loop each PDE while holding the working set lock */
// MiLockWorkingSet(PsGetCurrentThread(),
@@ -2330,7 +2330,6 @@
/* Use the system space API, but with the session view instead */
ASSERT(MmIsAddressValid(MmSessionSpace) == TRUE);
- ASSERT(FALSE);
return MiMapViewInSystemSpace(Section,
&MmSessionSpace->Session,
MappedBase,
Modified: trunk/reactos/ntoskrnl/ps/process.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/process.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/ps/process.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ps/process.c [iso-8859-1] Wed Aug 1 07:54:37 2012
@@ -1114,8 +1114,7 @@
NTAPI
PsGetCurrentProcessSessionId(VOID)
{
- // FIXME: this is broken!
- return PtrToUlong(PsGetCurrentProcess()->Session);
+ return MmGetSessionId(PsGetCurrentProcess());
}
/*
Modified: trunk/reactos/ntoskrnl/ps/security.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/security.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/ps/security.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ps/security.c [iso-8859-1] Wed Aug 1 07:54:37 2012
@@ -86,7 +86,7 @@
Status = SeSubProcessToken(ParentToken,
&NewToken,
TRUE,
- 0);//MmGetSessionId(Process));
+ MmGetSessionId(Process));
/* Dereference the Parent */
ObFastDereferenceObject(&Parent->Token, ParentToken);