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/m... ============================================================================== --- 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?rev... ============================================================================== --- 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?re... ============================================================================== --- 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?r... ============================================================================== --- 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.c... ============================================================================== --- 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=5... ============================================================================== --- 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);