From c9252b32bd8ecd2417a8eb34a34f4e58da3c2883 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sun, 5 Oct 2014 06:33:34 +0000 Subject: [PATCH] [NTOSKRNL] Apply indentation of 4 spaces, no code change. svn path=/trunk/; revision=64531 --- reactos/ntoskrnl/mm/balance.c | 447 +-- reactos/ntoskrnl/mm/freelist.c | 134 +- reactos/ntoskrnl/mm/marea.c | 1096 +++--- reactos/ntoskrnl/mm/mmfault.c | 254 +- reactos/ntoskrnl/mm/mminit.c | 92 +- reactos/ntoskrnl/mm/pagefile.c | 1088 +++--- reactos/ntoskrnl/mm/region.c | 416 +- reactos/ntoskrnl/mm/rmap.c | 694 ++-- reactos/ntoskrnl/mm/section.c | 6452 ++++++++++++++++---------------- 9 files changed, 5340 insertions(+), 5333 deletions(-) diff --git a/reactos/ntoskrnl/mm/balance.c b/reactos/ntoskrnl/mm/balance.c index 3296b223ef1..7e1a3fb5650 100644 --- a/reactos/ntoskrnl/mm/balance.c +++ b/reactos/ntoskrnl/mm/balance.c @@ -26,9 +26,9 @@ /* TYPES ********************************************************************/ typedef struct _MM_ALLOCATION_REQUEST { - PFN_NUMBER Page; - LIST_ENTRY ListEntry; - KEVENT Event; + PFN_NUMBER Page; + LIST_ENTRY ListEntry; + KEVENT Event; } MM_ALLOCATION_REQUEST, *PMM_ALLOCATION_REQUEST; /* GLOBALS ******************************************************************/ @@ -52,15 +52,15 @@ INIT_FUNCTION NTAPI MmInitializeBalancer(ULONG NrAvailablePages, ULONG NrSystemPages) { - memset(MiMemoryConsumers, 0, sizeof(MiMemoryConsumers)); - InitializeListHead(&AllocationListHead); - KeInitializeSpinLock(&AllocationListLock); + memset(MiMemoryConsumers, 0, sizeof(MiMemoryConsumers)); + InitializeListHead(&AllocationListHead); + KeInitializeSpinLock(&AllocationListLock); - MiNrTotalPages = NrAvailablePages; + MiNrTotalPages = NrAvailablePages; - /* Set up targets. */ - MiMinimumAvailablePages = 128; - MiMinimumPagesPerRun = 256; + /* Set up targets. */ + MiMinimumAvailablePages = 128; + MiMinimumPagesPerRun = 256; if ((NrAvailablePages + NrSystemPages) >= 8192) { MiMemoryConsumers[MC_CACHE].PagesTarget = NrAvailablePages / 4 * 3; @@ -73,17 +73,17 @@ MmInitializeBalancer(ULONG NrAvailablePages, ULONG NrSystemPages) { MiMemoryConsumers[MC_CACHE].PagesTarget = NrAvailablePages / 8; } - MiMemoryConsumers[MC_USER].PagesTarget = NrAvailablePages - MiMinimumAvailablePages; + MiMemoryConsumers[MC_USER].PagesTarget = NrAvailablePages - MiMinimumAvailablePages; } VOID INIT_FUNCTION NTAPI -MmInitializeMemoryConsumer(ULONG Consumer, - NTSTATUS (*Trim)(ULONG Target, ULONG Priority, - PULONG NrFreed)) +MmInitializeMemoryConsumer( + ULONG Consumer, + NTSTATUS (*Trim)(ULONG Target, ULONG Priority, PULONG NrFreed)) { - MiMemoryConsumers[Consumer].Trim = Trim; + MiMemoryConsumers[Consumer].Trim = Trim; } VOID @@ -96,42 +96,42 @@ NTSTATUS NTAPI MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page) { - PMM_ALLOCATION_REQUEST Request; - PLIST_ENTRY Entry; - KIRQL OldIrql; + PMM_ALLOCATION_REQUEST Request; + PLIST_ENTRY Entry; + KIRQL OldIrql; - if (Page == 0) - { - DPRINT1("Tried to release page zero.\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } + if (Page == 0) + { + DPRINT1("Tried to release page zero.\n"); + KeBugCheck(MEMORY_MANAGEMENT); + } - if (MmGetReferenceCountPage(Page) == 1) - { - if(Consumer == MC_USER) MmRemoveLRUUserPage(Page); - (void)InterlockedDecrementUL(&MiMemoryConsumers[Consumer].PagesUsed); - if ((Entry = ExInterlockedRemoveHeadList(&AllocationListHead, &AllocationListLock)) == NULL) - { - OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); - MmDereferencePage(Page); - KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); - } - else - { - Request = CONTAINING_RECORD(Entry, MM_ALLOCATION_REQUEST, ListEntry); - MiZeroPhysicalPage(Page); - Request->Page = Page; - KeSetEvent(&Request->Event, IO_NO_INCREMENT, FALSE); - } - } - else - { - OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); - MmDereferencePage(Page); - KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); - } + if (MmGetReferenceCountPage(Page) == 1) + { + if(Consumer == MC_USER) MmRemoveLRUUserPage(Page); + (void)InterlockedDecrementUL(&MiMemoryConsumers[Consumer].PagesUsed); + if ((Entry = ExInterlockedRemoveHeadList(&AllocationListHead, &AllocationListLock)) == NULL) + { + OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); + MmDereferencePage(Page); + KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); + } + else + { + Request = CONTAINING_RECORD(Entry, MM_ALLOCATION_REQUEST, ListEntry); + MiZeroPhysicalPage(Page); + Request->Page = Page; + KeSetEvent(&Request->Event, IO_NO_INCREMENT, FALSE); + } + } + else + { + OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); + MmDereferencePage(Page); + KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); + } - return(STATUS_SUCCESS); + return(STATUS_SUCCESS); } ULONG @@ -230,8 +230,8 @@ MmTrimUserMemory(ULONG Target, ULONG Priority, PULONG NrFreedPages) static BOOLEAN MiIsBalancerThread(VOID) { - return (MiBalancerThreadHandle != NULL) && - (PsGetCurrentThreadId() == MiBalancerThreadId.UniqueThread); + return (MiBalancerThreadHandle != NULL) && + (PsGetCurrentThreadId() == MiBalancerThreadId.UniqueThread); } VOID @@ -257,181 +257,182 @@ NTAPI MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, PPFN_NUMBER AllocatedPage) { - ULONG PagesUsed; - PFN_NUMBER Page; - KIRQL OldIrql; + ULONG PagesUsed; + PFN_NUMBER Page; + KIRQL OldIrql; - /* - * Make sure we don't exceed our individual target. - */ - PagesUsed = InterlockedIncrementUL(&MiMemoryConsumers[Consumer].PagesUsed); - if (PagesUsed > MiMemoryConsumers[Consumer].PagesTarget && - !MiIsBalancerThread()) - { - MmRebalanceMemoryConsumers(); - } + /* + * Make sure we don't exceed our individual target. + */ + PagesUsed = InterlockedIncrementUL(&MiMemoryConsumers[Consumer].PagesUsed); + if (PagesUsed > MiMemoryConsumers[Consumer].PagesTarget && + !MiIsBalancerThread()) + { + MmRebalanceMemoryConsumers(); + } - /* - * Allocate always memory for the non paged pool and for the pager thread. - */ - if ((Consumer == MC_SYSTEM) || MiIsBalancerThread()) - { - OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); - Page = MmAllocPage(Consumer); - KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); - if (Page == 0) - { - KeBugCheck(NO_PAGES_AVAILABLE); - } - if (Consumer == MC_USER) MmInsertLRULastUserPage(Page); - *AllocatedPage = Page; - if (MmAvailablePages < MiMinimumAvailablePages) - MmRebalanceMemoryConsumers(); - return(STATUS_SUCCESS); - } + /* + * Allocate always memory for the non paged pool and for the pager thread. + */ + if ((Consumer == MC_SYSTEM) || MiIsBalancerThread()) + { + OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); + Page = MmAllocPage(Consumer); + KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); + if (Page == 0) + { + KeBugCheck(NO_PAGES_AVAILABLE); + } + if (Consumer == MC_USER) MmInsertLRULastUserPage(Page); + *AllocatedPage = Page; + if (MmAvailablePages < MiMinimumAvailablePages) + MmRebalanceMemoryConsumers(); + return(STATUS_SUCCESS); + } - /* - * Make sure we don't exceed global targets. - */ - if (MmAvailablePages < MiMinimumAvailablePages) - { - MM_ALLOCATION_REQUEST Request; + /* + * Make sure we don't exceed global targets. + */ + if (MmAvailablePages < MiMinimumAvailablePages) + { + MM_ALLOCATION_REQUEST Request; - if (!CanWait) - { - (void)InterlockedDecrementUL(&MiMemoryConsumers[Consumer].PagesUsed); - MmRebalanceMemoryConsumers(); - return(STATUS_NO_MEMORY); - } + if (!CanWait) + { + (void)InterlockedDecrementUL(&MiMemoryConsumers[Consumer].PagesUsed); + MmRebalanceMemoryConsumers(); + return(STATUS_NO_MEMORY); + } - /* Insert an allocation request. */ - Request.Page = 0; - KeInitializeEvent(&Request.Event, NotificationEvent, FALSE); + /* Insert an allocation request. */ + Request.Page = 0; + KeInitializeEvent(&Request.Event, NotificationEvent, FALSE); - ExInterlockedInsertTailList(&AllocationListHead, &Request.ListEntry, &AllocationListLock); - MmRebalanceMemoryConsumers(); + ExInterlockedInsertTailList(&AllocationListHead, &Request.ListEntry, &AllocationListLock); + MmRebalanceMemoryConsumers(); - KeWaitForSingleObject(&Request.Event, - 0, - KernelMode, - FALSE, - NULL); + KeWaitForSingleObject(&Request.Event, + 0, + KernelMode, + FALSE, + NULL); - Page = Request.Page; - if (Page == 0) - { - KeBugCheck(NO_PAGES_AVAILABLE); - } + Page = Request.Page; + if (Page == 0) + { + KeBugCheck(NO_PAGES_AVAILABLE); + } - if(Consumer == MC_USER) MmInsertLRULastUserPage(Page); - *AllocatedPage = Page; + if(Consumer == MC_USER) MmInsertLRULastUserPage(Page); + *AllocatedPage = Page; - if (MmAvailablePages < MiMinimumAvailablePages) - { - MmRebalanceMemoryConsumers(); - } + if (MmAvailablePages < MiMinimumAvailablePages) + { + MmRebalanceMemoryConsumers(); + } - return(STATUS_SUCCESS); - } + return(STATUS_SUCCESS); + } - /* - * Actually allocate the page. - */ - OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); - Page = MmAllocPage(Consumer); - KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); - if (Page == 0) - { - KeBugCheck(NO_PAGES_AVAILABLE); - } - if(Consumer == MC_USER) MmInsertLRULastUserPage(Page); - *AllocatedPage = Page; + /* + * Actually allocate the page. + */ + OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); + Page = MmAllocPage(Consumer); + KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); + if (Page == 0) + { + KeBugCheck(NO_PAGES_AVAILABLE); + } + if(Consumer == MC_USER) MmInsertLRULastUserPage(Page); + *AllocatedPage = Page; - if (MmAvailablePages < MiMinimumAvailablePages) - { - MmRebalanceMemoryConsumers(); - } + if (MmAvailablePages < MiMinimumAvailablePages) + { + MmRebalanceMemoryConsumers(); + } - return(STATUS_SUCCESS); + return(STATUS_SUCCESS); } VOID NTAPI MiBalancerThread(PVOID Unused) { - PVOID WaitObjects[2]; - NTSTATUS Status; - ULONG i; + PVOID WaitObjects[2]; + NTSTATUS Status; + ULONG i; - WaitObjects[0] = &MiBalancerEvent; - WaitObjects[1] = &MiBalancerTimer; + WaitObjects[0] = &MiBalancerEvent; + WaitObjects[1] = &MiBalancerTimer; - while (1) - { - Status = KeWaitForMultipleObjects(2, - WaitObjects, - WaitAny, - Executive, - KernelMode, - FALSE, - NULL, - NULL); + while (1) + { + Status = KeWaitForMultipleObjects(2, + WaitObjects, + WaitAny, + Executive, + KernelMode, + FALSE, + NULL, + NULL); - if (Status == STATUS_WAIT_0 || Status == STATUS_WAIT_1) - { - ULONG InitialTarget = 0; + if (Status == STATUS_WAIT_0 || Status == STATUS_WAIT_1) + { + ULONG InitialTarget = 0; #if (_MI_PAGING_LEVELS == 2) - if (!MiIsBalancerThread()) - { - /* Clean up the unused PDEs */ - ULONG_PTR Address; - PEPROCESS Process = PsGetCurrentProcess(); - - /* Acquire PFN lock */ - KIRQL OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); - PMMPDE pointerPde; - for (Address = (ULONG_PTR)MI_LOWEST_VAD_ADDRESS; - Address < (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS; - Address += (PAGE_SIZE * PTE_COUNT)) + if (!MiIsBalancerThread()) { - if (MiQueryPageTableReferences((PVOID)Address) == 0) + /* Clean up the unused PDEs */ + ULONG_PTR Address; + PEPROCESS Process = PsGetCurrentProcess(); + + /* Acquire PFN lock */ + KIRQL OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); + PMMPDE pointerPde; + for (Address = (ULONG_PTR)MI_LOWEST_VAD_ADDRESS; + Address < (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS; + Address += (PAGE_SIZE * PTE_COUNT)) { - pointerPde = MiAddressToPde(Address); - if (pointerPde->u.Hard.Valid) - MiDeletePte(pointerPde, MiPdeToPte(pointerPde), Process, NULL); - ASSERT(pointerPde->u.Hard.Valid == 0); + if (MiQueryPageTableReferences((PVOID)Address) == 0) + { + pointerPde = MiAddressToPde(Address); + if (pointerPde->u.Hard.Valid) + MiDeletePte(pointerPde, MiPdeToPte(pointerPde), Process, NULL); + ASSERT(pointerPde->u.Hard.Valid == 0); + } + } + /* Release lock */ + KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); + } +#endif + do + { + ULONG OldTarget = InitialTarget; + + /* Trim each consumer */ + for (i = 0; i < MC_MAXIMUM; i++) + { + InitialTarget = MiTrimMemoryConsumer(i, InitialTarget); + } + + /* No pages left to swap! */ + if (InitialTarget != 0 && + InitialTarget == OldTarget) + { + /* Game over */ + KeBugCheck(NO_PAGES_AVAILABLE); } } - /* Release lock */ - KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); + while (InitialTarget != 0); } -#endif - do - { - ULONG OldTarget = InitialTarget; - - /* Trim each consumer */ - for (i = 0; i < MC_MAXIMUM; i++) - { - InitialTarget = MiTrimMemoryConsumer(i, InitialTarget); - } - - /* No pages left to swap! */ - if (InitialTarget != 0 && - InitialTarget == OldTarget) - { - /* Game over */ - KeBugCheck(NO_PAGES_AVAILABLE); - } - } while (InitialTarget != 0); - } - else - { - DPRINT1("KeWaitForMultipleObjects failed, status = %x\n", Status); - KeBugCheck(MEMORY_MANAGEMENT); - } - } + else + { + DPRINT1("KeWaitForMultipleObjects failed, status = %x\n", Status); + KeBugCheck(MEMORY_MANAGEMENT); + } + } } VOID @@ -439,44 +440,44 @@ INIT_FUNCTION NTAPI MiInitBalancerThread(VOID) { - KPRIORITY Priority; - NTSTATUS Status; + KPRIORITY Priority; + NTSTATUS Status; #if !defined(__GNUC__) - LARGE_INTEGER dummyJunkNeeded; - dummyJunkNeeded.QuadPart = -20000000; /* 2 sec */ - ; + LARGE_INTEGER dummyJunkNeeded; + dummyJunkNeeded.QuadPart = -20000000; /* 2 sec */ + ; #endif - KeInitializeEvent(&MiBalancerEvent, SynchronizationEvent, FALSE); - KeInitializeTimerEx(&MiBalancerTimer, SynchronizationTimer); - KeSetTimerEx(&MiBalancerTimer, + KeInitializeEvent(&MiBalancerEvent, SynchronizationEvent, FALSE); + KeInitializeTimerEx(&MiBalancerTimer, SynchronizationTimer); + KeSetTimerEx(&MiBalancerTimer, #if defined(__GNUC__) - (LARGE_INTEGER)(LONGLONG)-20000000LL, /* 2 sec */ + (LARGE_INTEGER)(LONGLONG)-20000000LL, /* 2 sec */ #else - dummyJunkNeeded, + dummyJunkNeeded, #endif - 2000, /* 2 sec */ - NULL); + 2000, /* 2 sec */ + NULL); - Status = PsCreateSystemThread(&MiBalancerThreadHandle, - THREAD_ALL_ACCESS, - NULL, - NULL, - &MiBalancerThreadId, - MiBalancerThread, - NULL); - if (!NT_SUCCESS(Status)) - { - KeBugCheck(MEMORY_MANAGEMENT); - } + Status = PsCreateSystemThread(&MiBalancerThreadHandle, + THREAD_ALL_ACCESS, + NULL, + NULL, + &MiBalancerThreadId, + MiBalancerThread, + NULL); + if (!NT_SUCCESS(Status)) + { + KeBugCheck(MEMORY_MANAGEMENT); + } - Priority = LOW_REALTIME_PRIORITY + 1; - NtSetInformationThread(MiBalancerThreadHandle, - ThreadPriority, - &Priority, - sizeof(Priority)); + Priority = LOW_REALTIME_PRIORITY + 1; + NtSetInformationThread(MiBalancerThreadHandle, + ThreadPriority, + &Priority, + sizeof(Priority)); } diff --git a/reactos/ntoskrnl/mm/freelist.c b/reactos/ntoskrnl/mm/freelist.c index e65ba48ffbb..568ba1343bf 100644 --- a/reactos/ntoskrnl/mm/freelist.c +++ b/reactos/ntoskrnl/mm/freelist.c @@ -448,76 +448,76 @@ VOID NTAPI MmSetSavedSwapEntryPage(PFN_NUMBER Pfn, SWAPENTRY SwapEntry) { - KIRQL oldIrql; - PMMPFN Pfn1; + KIRQL oldIrql; + PMMPFN Pfn1; - Pfn1 = MiGetPfnEntry(Pfn); - ASSERT(Pfn1); - ASSERT_IS_ROS_PFN(Pfn1); + Pfn1 = MiGetPfnEntry(Pfn); + ASSERT(Pfn1); + ASSERT_IS_ROS_PFN(Pfn1); - oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); - Pfn1->u1.SwapEntry = SwapEntry; - KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); + oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); + Pfn1->u1.SwapEntry = SwapEntry; + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); } SWAPENTRY NTAPI MmGetSavedSwapEntryPage(PFN_NUMBER Pfn) { - SWAPENTRY SwapEntry; - KIRQL oldIrql; - PMMPFN Pfn1; + SWAPENTRY SwapEntry; + KIRQL oldIrql; + PMMPFN Pfn1; - Pfn1 = MiGetPfnEntry(Pfn); - ASSERT(Pfn1); - ASSERT_IS_ROS_PFN(Pfn1); + Pfn1 = MiGetPfnEntry(Pfn); + ASSERT(Pfn1); + ASSERT_IS_ROS_PFN(Pfn1); - oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); - SwapEntry = Pfn1->u1.SwapEntry; - KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); + oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); + SwapEntry = Pfn1->u1.SwapEntry; + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); - return(SwapEntry); + return(SwapEntry); } VOID NTAPI MmReferencePage(PFN_NUMBER Pfn) { - PMMPFN Pfn1; + PMMPFN Pfn1; - DPRINT("MmReferencePage(PysicalAddress %x)\n", Pfn << PAGE_SHIFT); + DPRINT("MmReferencePage(PysicalAddress %x)\n", Pfn << PAGE_SHIFT); - ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); - ASSERT(Pfn != 0); - ASSERT(Pfn <= MmHighestPhysicalPage); + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + ASSERT(Pfn != 0); + ASSERT(Pfn <= MmHighestPhysicalPage); - Pfn1 = MiGetPfnEntry(Pfn); - ASSERT(Pfn1); - ASSERT_IS_ROS_PFN(Pfn1); + Pfn1 = MiGetPfnEntry(Pfn); + ASSERT(Pfn1); + ASSERT_IS_ROS_PFN(Pfn1); - ASSERT(Pfn1->u3.e2.ReferenceCount != 0); - Pfn1->u3.e2.ReferenceCount++; + ASSERT(Pfn1->u3.e2.ReferenceCount != 0); + Pfn1->u3.e2.ReferenceCount++; } ULONG NTAPI MmGetReferenceCountPage(PFN_NUMBER Pfn) { - KIRQL oldIrql; - ULONG RCount; - PMMPFN Pfn1; + KIRQL oldIrql; + ULONG RCount; + PMMPFN Pfn1; - DPRINT("MmGetReferenceCountPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT); + DPRINT("MmGetReferenceCountPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT); - oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); - Pfn1 = MiGetPfnEntry(Pfn); - ASSERT(Pfn1); - ASSERT_IS_ROS_PFN(Pfn1); + oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); + Pfn1 = MiGetPfnEntry(Pfn); + ASSERT(Pfn1); + ASSERT_IS_ROS_PFN(Pfn1); - RCount = Pfn1->u3.e2.ReferenceCount; + RCount = Pfn1->u3.e2.ReferenceCount; - KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); - return(RCount); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); + return(RCount); } BOOLEAN @@ -531,17 +531,17 @@ VOID NTAPI MmDereferencePage(PFN_NUMBER Pfn) { - PMMPFN Pfn1; - DPRINT("MmDereferencePage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT); + PMMPFN Pfn1; + DPRINT("MmDereferencePage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT); - Pfn1 = MiGetPfnEntry(Pfn); - ASSERT(Pfn1); - ASSERT_IS_ROS_PFN(Pfn1); + Pfn1 = MiGetPfnEntry(Pfn); + ASSERT(Pfn1); + ASSERT_IS_ROS_PFN(Pfn1); - ASSERT(Pfn1->u3.e2.ReferenceCount != 0); - Pfn1->u3.e2.ReferenceCount--; - if (Pfn1->u3.e2.ReferenceCount == 0) - { + ASSERT(Pfn1->u3.e2.ReferenceCount != 0); + Pfn1->u3.e2.ReferenceCount--; + if (Pfn1->u3.e2.ReferenceCount == 0) + { /* Mark the page temporarily as valid, we're going to make it free soon */ Pfn1->u3.e1.PageLocation = ActiveAndValid; @@ -551,37 +551,37 @@ MmDereferencePage(PFN_NUMBER Pfn) /* Bring it back into the free list */ DPRINT("Legacy free: %lx\n", Pfn); MiInsertPageInFreeList(Pfn); - } + } } PFN_NUMBER NTAPI MmAllocPage(ULONG Type) { - PFN_NUMBER PfnOffset; - PMMPFN Pfn1; + PFN_NUMBER PfnOffset; + PMMPFN Pfn1; - PfnOffset = MiRemoveZeroPage(MI_GET_NEXT_COLOR()); + PfnOffset = MiRemoveZeroPage(MI_GET_NEXT_COLOR()); - if (!PfnOffset) - { - DPRINT1("MmAllocPage(): Out of memory\n"); - return 0; - } + if (!PfnOffset) + { + DPRINT1("MmAllocPage(): Out of memory\n"); + return 0; + } - DPRINT("Legacy allocate: %lx\n", PfnOffset); - Pfn1 = MiGetPfnEntry(PfnOffset); - Pfn1->u3.e2.ReferenceCount = 1; - Pfn1->u3.e1.PageLocation = ActiveAndValid; + DPRINT("Legacy allocate: %lx\n", PfnOffset); + Pfn1 = MiGetPfnEntry(PfnOffset); + Pfn1->u3.e2.ReferenceCount = 1; + Pfn1->u3.e1.PageLocation = ActiveAndValid; - /* This marks the PFN as a ReactOS PFN */ - Pfn1->u4.AweAllocation = TRUE; + /* This marks the PFN as a ReactOS PFN */ + Pfn1->u4.AweAllocation = TRUE; - /* Allocate the extra ReactOS Data and zero it out */ - Pfn1->u1.SwapEntry = 0; - Pfn1->RmapListHead = NULL; + /* Allocate the extra ReactOS Data and zero it out */ + Pfn1->u1.SwapEntry = 0; + Pfn1->RmapListHead = NULL; - return PfnOffset; + return PfnOffset; } /* EOF */ diff --git a/reactos/ntoskrnl/mm/marea.c b/reactos/ntoskrnl/mm/marea.c index 12a7afae3ac..39fc28ef3c8 100644 --- a/reactos/ntoskrnl/mm/marea.c +++ b/reactos/ntoskrnl/mm/marea.c @@ -65,10 +65,10 @@ ULONG MiStaticMemoryAreaCount; static PMEMORY_AREA MmIterateFirstNode(PMEMORY_AREA Node) { - while (Node->LeftChild != NULL) - Node = Node->LeftChild; + while (Node->LeftChild != NULL) + Node = Node->LeftChild; - return Node; + return Node; } /** @@ -82,28 +82,28 @@ static PMEMORY_AREA MmIterateFirstNode(PMEMORY_AREA Node) static PMEMORY_AREA MmIterateNextNode(PMEMORY_AREA Node) { - if (Node->RightChild != NULL) - { - Node = Node->RightChild; - while (Node->LeftChild != NULL) - Node = Node->LeftChild; - } - else - { - PMEMORY_AREA TempNode = NULL; + if (Node->RightChild != NULL) + { + Node = Node->RightChild; + while (Node->LeftChild != NULL) + Node = Node->LeftChild; + } + else + { + PMEMORY_AREA TempNode = NULL; - do - { - /* Check if we're at the end of tree. */ - if (Node->Parent == NULL) - return NULL; + do + { + /* Check if we're at the end of tree. */ + if (Node->Parent == NULL) + return NULL; - TempNode = Node; - Node = Node->Parent; - } - while (TempNode == Node->RightChild); - } - return Node; + TempNode = Node; + Node = Node->Parent; + } + while (TempNode == Node->RightChild); + } + return Node; } /** @@ -118,10 +118,10 @@ static PMEMORY_AREA MmIterateNextNode(PMEMORY_AREA Node) static PMEMORY_AREA MmIterateLastNode(PMEMORY_AREA Node) { - while (Node->RightChild != NULL) - Node = Node->RightChild; + while (Node->RightChild != NULL) + Node = Node->RightChild; - return Node; + return Node; } /** @@ -135,108 +135,108 @@ static PMEMORY_AREA MmIterateLastNode(PMEMORY_AREA Node) static PMEMORY_AREA MmIteratePrevNode(PMEMORY_AREA Node) { - if (Node->LeftChild != NULL) - { - Node = Node->LeftChild; - while (Node->RightChild != NULL) - Node = Node->RightChild; - } - else - { - PMEMORY_AREA TempNode = NULL; + if (Node->LeftChild != NULL) + { + Node = Node->LeftChild; + while (Node->RightChild != NULL) + Node = Node->RightChild; + } + else + { + PMEMORY_AREA TempNode = NULL; - do - { - /* Check if we're at the end of tree. */ - if (Node->Parent == NULL) - return NULL; + do + { + /* Check if we're at the end of tree. */ + if (Node->Parent == NULL) + return NULL; - TempNode = Node; - Node = Node->Parent; - } - while (TempNode == Node->LeftChild); - } - return Node; + TempNode = Node; + Node = Node->Parent; + } + while (TempNode == Node->LeftChild); + } + return Node; } PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress( - PMMSUPPORT AddressSpace, - PVOID Address) + PMMSUPPORT AddressSpace, + PVOID Address) { - PMEMORY_AREA Node = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink; + PMEMORY_AREA Node = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink; - DPRINT("MmLocateMemoryAreaByAddress(AddressSpace %p, Address %p)\n", + DPRINT("MmLocateMemoryAreaByAddress(AddressSpace %p, Address %p)\n", AddressSpace, Address); - while (Node != NULL) - { - if (Address < Node->StartingAddress) - Node = Node->LeftChild; - else if (Address >= Node->EndingAddress) - Node = Node->RightChild; - else - { - DPRINT("MmLocateMemoryAreaByAddress(%p): %p [%p - %p]\n", - Address, Node, Node->StartingAddress, Node->EndingAddress); - return Node; - } - } + while (Node != NULL) + { + if (Address < Node->StartingAddress) + Node = Node->LeftChild; + else if (Address >= Node->EndingAddress) + Node = Node->RightChild; + else + { + DPRINT("MmLocateMemoryAreaByAddress(%p): %p [%p - %p]\n", + Address, Node, Node->StartingAddress, Node->EndingAddress); + return Node; + } + } - DPRINT("MmLocateMemoryAreaByAddress(%p): 0\n", Address); - return NULL; + DPRINT("MmLocateMemoryAreaByAddress(%p): 0\n", Address); + return NULL; } PMEMORY_AREA NTAPI MmLocateMemoryAreaByRegion( - PMMSUPPORT AddressSpace, - PVOID Address, - ULONG_PTR Length) + PMMSUPPORT AddressSpace, + PVOID Address, + ULONG_PTR Length) { - PMEMORY_AREA Node; - PVOID Extent = (PVOID)((ULONG_PTR)Address + Length); + PMEMORY_AREA Node; + PVOID Extent = (PVOID)((ULONG_PTR)Address + Length); - /* Special case for empty tree. */ - if (AddressSpace->WorkingSetExpansionLinks.Flink == NULL) - return NULL; + /* Special case for empty tree. */ + if (AddressSpace->WorkingSetExpansionLinks.Flink == NULL) + return NULL; - /* Traverse the tree from left to right. */ - for (Node = MmIterateFirstNode((PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink); - Node != NULL; - Node = MmIterateNextNode(Node)) - { - if (Node->StartingAddress >= Address && - Node->StartingAddress < Extent) - { - DPRINT("MmLocateMemoryAreaByRegion(%p - %p): %p - %p\n", - Address, (ULONG_PTR)Address + Length, Node->StartingAddress, - Node->EndingAddress); - return Node; - } - if (Node->EndingAddress > Address && - Node->EndingAddress < Extent) - { - DPRINT("MmLocateMemoryAreaByRegion(%p - %p): %p - %p\n", - Address, (ULONG_PTR)Address + Length, Node->StartingAddress, - Node->EndingAddress); - return Node; - } - if (Node->StartingAddress <= Address && - Node->EndingAddress >= Extent) - { - DPRINT("MmLocateMemoryAreaByRegion(%p - %p): %p - %p\n", - Address, (ULONG_PTR)Address + Length, Node->StartingAddress, - Node->EndingAddress); - return Node; - } - if (Node->StartingAddress >= Extent) - { - DPRINT("Finished MmLocateMemoryAreaByRegion() = NULL\n"); - return NULL; - } - } + /* Traverse the tree from left to right. */ + for (Node = MmIterateFirstNode((PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink); + Node != NULL; + Node = MmIterateNextNode(Node)) + { + if (Node->StartingAddress >= Address && + Node->StartingAddress < Extent) + { + DPRINT("MmLocateMemoryAreaByRegion(%p - %p): %p - %p\n", + Address, (ULONG_PTR)Address + Length, Node->StartingAddress, + Node->EndingAddress); + return Node; + } + if (Node->EndingAddress > Address && + Node->EndingAddress < Extent) + { + DPRINT("MmLocateMemoryAreaByRegion(%p - %p): %p - %p\n", + Address, (ULONG_PTR)Address + Length, Node->StartingAddress, + Node->EndingAddress); + return Node; + } + if (Node->StartingAddress <= Address && + Node->EndingAddress >= Extent) + { + DPRINT("MmLocateMemoryAreaByRegion(%p - %p): %p - %p\n", + Address, (ULONG_PTR)Address + Length, Node->StartingAddress, + Node->EndingAddress); + return Node; + } + if (Node->StartingAddress >= Extent) + { + DPRINT("Finished MmLocateMemoryAreaByRegion() = NULL\n"); + return NULL; + } + } - return NULL; + return NULL; } /** @@ -248,33 +248,33 @@ MmLocateMemoryAreaByRegion( static VOID MmCompressHelper( - PMMSUPPORT AddressSpace, - ULONG Count) + PMMSUPPORT AddressSpace, + ULONG Count) { - PMEMORY_AREA Root = NULL; - PMEMORY_AREA Red = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink; - PMEMORY_AREA Black = Red->LeftChild; + PMEMORY_AREA Root = NULL; + PMEMORY_AREA Red = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink; + PMEMORY_AREA Black = Red->LeftChild; - while (Count--) - { - if (Root) - Root->LeftChild = Black; - else - AddressSpace->WorkingSetExpansionLinks.Flink = (PVOID)Black; - Black->Parent = Root; - Red->LeftChild = Black->RightChild; - if (Black->RightChild) - Black->RightChild->Parent = Red; - Black->RightChild = Red; - Red->Parent = Black; - Root = Black; + while (Count--) + { + if (Root) + Root->LeftChild = Black; + else + AddressSpace->WorkingSetExpansionLinks.Flink = (PVOID)Black; + Black->Parent = Root; + Red->LeftChild = Black->RightChild; + if (Black->RightChild) + Black->RightChild->Parent = Red; + Black->RightChild = Red; + Red->Parent = Black; + Root = Black; - if (Count) - { - Red = Root->LeftChild; - Black = Red->LeftChild; - } - } + if (Count) + { + Red = Root->LeftChild; + Black = Red->LeftChild; + } + } } /** @@ -287,77 +287,77 @@ MmCompressHelper( static VOID MmRebalanceTree( - PMMSUPPORT AddressSpace) + PMMSUPPORT AddressSpace) { - PMEMORY_AREA PreviousNode; - PMEMORY_AREA CurrentNode; - PMEMORY_AREA TempNode; - ULONG NodeCount = 0; - ULONG Vine; /* Number of nodes in main vine. */ - ULONG Leaves; /* Nodes in incomplete bottom level, if any. */ - INT Height; /* Height of produced balanced tree. */ + PMEMORY_AREA PreviousNode; + PMEMORY_AREA CurrentNode; + PMEMORY_AREA TempNode; + ULONG NodeCount = 0; + ULONG Vine; /* Number of nodes in main vine. */ + ULONG Leaves; /* Nodes in incomplete bottom level, if any. */ + INT Height; /* Height of produced balanced tree. */ - /* Transform the tree into Vine. */ + /* Transform the tree into Vine. */ - PreviousNode = NULL; - CurrentNode = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink; - while (CurrentNode != NULL) - { - if (CurrentNode->RightChild == NULL) - { - PreviousNode = CurrentNode; - CurrentNode = CurrentNode->LeftChild; - NodeCount++; - } - else - { - TempNode = CurrentNode->RightChild; + PreviousNode = NULL; + CurrentNode = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink; + while (CurrentNode != NULL) + { + if (CurrentNode->RightChild == NULL) + { + PreviousNode = CurrentNode; + CurrentNode = CurrentNode->LeftChild; + NodeCount++; + } + else + { + TempNode = CurrentNode->RightChild; - CurrentNode->RightChild = TempNode->LeftChild; - if (TempNode->LeftChild) - TempNode->LeftChild->Parent = CurrentNode; + CurrentNode->RightChild = TempNode->LeftChild; + if (TempNode->LeftChild) + TempNode->LeftChild->Parent = CurrentNode; - TempNode->LeftChild = CurrentNode; - CurrentNode->Parent = TempNode; + TempNode->LeftChild = CurrentNode; + CurrentNode->Parent = TempNode; - CurrentNode = TempNode; + CurrentNode = TempNode; - if (PreviousNode != NULL) - PreviousNode->LeftChild = TempNode; - else - AddressSpace->WorkingSetExpansionLinks.Flink = (PVOID)TempNode; - TempNode->Parent = PreviousNode; - } - } + if (PreviousNode != NULL) + PreviousNode->LeftChild = TempNode; + else + AddressSpace->WorkingSetExpansionLinks.Flink = (PVOID)TempNode; + TempNode->Parent = PreviousNode; + } + } - /* Transform Vine back into a balanced tree. */ + /* Transform Vine back into a balanced tree. */ - Leaves = NodeCount + 1; - for (;;) - { - ULONG Next = Leaves & (Leaves - 1); - if (Next == 0) - break; - Leaves = Next; - } - Leaves = NodeCount + 1 - Leaves; + Leaves = NodeCount + 1; + for (;;) + { + ULONG Next = Leaves & (Leaves - 1); + if (Next == 0) + break; + Leaves = Next; + } + Leaves = NodeCount + 1 - Leaves; - MmCompressHelper(AddressSpace, Leaves); + MmCompressHelper(AddressSpace, Leaves); - Vine = NodeCount - Leaves; - Height = 1 + (Leaves > 0); - while (Vine > 1) - { - MmCompressHelper(AddressSpace, Vine / 2); - Vine /= 2; - Height++; - } + Vine = NodeCount - Leaves; + Height = 1 + (Leaves > 0); + while (Vine > 1) + { + MmCompressHelper(AddressSpace, Vine / 2); + Vine /= 2; + Height++; + } } VOID NTAPI MiInsertVad(IN PMMVAD Vad, -IN PEPROCESS Process); + IN PEPROCESS Process); ULONG NTAPI @@ -367,29 +367,29 @@ MiMakeProtectionMask( static VOID MmInsertMemoryArea( - PMMSUPPORT AddressSpace, - PMEMORY_AREA marea) + PMMSUPPORT AddressSpace, + PMEMORY_AREA marea) { - PMEMORY_AREA Node; - PMEMORY_AREA PreviousNode; - ULONG Depth = 0; - PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace); + PMEMORY_AREA Node; + PMEMORY_AREA PreviousNode; + ULONG Depth = 0; + PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace); - /* Build a lame VAD if this is a user-space allocation */ - if ((marea->EndingAddress < MmSystemRangeStart) && (marea->Type != MEMORY_AREA_OWNED_BY_ARM3)) - { - PMMVAD Vad; + /* Build a lame VAD if this is a user-space allocation */ + if ((marea->EndingAddress < MmSystemRangeStart) && (marea->Type != MEMORY_AREA_OWNED_BY_ARM3)) + { + PMMVAD Vad; - ASSERT(marea->Type == MEMORY_AREA_SECTION_VIEW || marea->Type == MEMORY_AREA_CACHE); - Vad = ExAllocatePoolWithTag(NonPagedPool, sizeof(MMVAD), TAG_MVAD); - ASSERT(Vad); - RtlZeroMemory(Vad, sizeof(MMVAD)); - Vad->StartingVpn = PAGE_ROUND_DOWN(marea->StartingAddress) >> PAGE_SHIFT; - /* - * For some strange reason, it is perfectly valid to create a MAREA from 0x1000 to... 0x1000. - * In a normal OS/Memory Manager, this would be retarded, but ReactOS allows this (how it works - * I don't even want to know). - */ + ASSERT(marea->Type == MEMORY_AREA_SECTION_VIEW || marea->Type == MEMORY_AREA_CACHE); + Vad = ExAllocatePoolWithTag(NonPagedPool, sizeof(MMVAD), TAG_MVAD); + ASSERT(Vad); + RtlZeroMemory(Vad, sizeof(MMVAD)); + Vad->StartingVpn = PAGE_ROUND_DOWN(marea->StartingAddress) >> PAGE_SHIFT; + /* + * For some strange reason, it is perfectly valid to create a MAREA from 0x1000 to... 0x1000. + * In a normal OS/Memory Manager, this would be retarded, but ReactOS allows this (how it works + * I don't even want to know). + */ if (marea->EndingAddress != marea->StartingAddress) { Vad->EndingVpn = PAGE_ROUND_DOWN((ULONG_PTR)marea->EndingAddress - 1) >> PAGE_SHIFT; @@ -398,68 +398,68 @@ MmInsertMemoryArea( { Vad->EndingVpn = Vad->StartingVpn; } - Vad->u.VadFlags.Spare = 1; - Vad->u.VadFlags.Protection = MiMakeProtectionMask(marea->Protect); + Vad->u.VadFlags.Spare = 1; + Vad->u.VadFlags.Protection = MiMakeProtectionMask(marea->Protect); - /* Insert the VAD */ - MiInsertVad(Vad, Process); - marea->Vad = Vad; - } - else - { - marea->Vad = NULL; - } + /* Insert the VAD */ + MiInsertVad(Vad, Process); + marea->Vad = Vad; + } + else + { + marea->Vad = NULL; + } - if (AddressSpace->WorkingSetExpansionLinks.Flink == NULL) - { - AddressSpace->WorkingSetExpansionLinks.Flink = (PVOID)marea; - marea->LeftChild = marea->RightChild = marea->Parent = NULL; - return; - } + if (AddressSpace->WorkingSetExpansionLinks.Flink == NULL) + { + AddressSpace->WorkingSetExpansionLinks.Flink = (PVOID)marea; + marea->LeftChild = marea->RightChild = marea->Parent = NULL; + return; + } - Node = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink; - do - { - DPRINT("marea->EndingAddress: %p Node->StartingAddress: %p\n", - marea->EndingAddress, Node->StartingAddress); - DPRINT("marea->StartingAddress: %p Node->EndingAddress: %p\n", - marea->StartingAddress, Node->EndingAddress); - ASSERT(marea->EndingAddress <= Node->StartingAddress || - marea->StartingAddress >= Node->EndingAddress); - ASSERT(marea->StartingAddress != Node->StartingAddress); + Node = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink; + do + { + DPRINT("marea->EndingAddress: %p Node->StartingAddress: %p\n", + marea->EndingAddress, Node->StartingAddress); + DPRINT("marea->StartingAddress: %p Node->EndingAddress: %p\n", + marea->StartingAddress, Node->EndingAddress); + ASSERT(marea->EndingAddress <= Node->StartingAddress || + marea->StartingAddress >= Node->EndingAddress); + ASSERT(marea->StartingAddress != Node->StartingAddress); - PreviousNode = Node; + PreviousNode = Node; - if (marea->StartingAddress < Node->StartingAddress) - Node = Node->LeftChild; - else - Node = Node->RightChild; + if (marea->StartingAddress < Node->StartingAddress) + Node = Node->LeftChild; + else + Node = Node->RightChild; - if (Node) - { - Depth++; - if (Depth == 22) - { - MmRebalanceTree(AddressSpace); - PreviousNode = Node->Parent; - } - } - } - while (Node != NULL); + if (Node) + { + Depth++; + if (Depth == 22) + { + MmRebalanceTree(AddressSpace); + PreviousNode = Node->Parent; + } + } + } + while (Node != NULL); - marea->LeftChild = marea->RightChild = NULL; - marea->Parent = PreviousNode; - if (marea->StartingAddress < PreviousNode->StartingAddress) - PreviousNode->LeftChild = marea; - else - PreviousNode->RightChild = marea; + marea->LeftChild = marea->RightChild = NULL; + marea->Parent = PreviousNode; + if (marea->StartingAddress < PreviousNode->StartingAddress) + PreviousNode->LeftChild = marea; + else + PreviousNode->RightChild = marea; } static PVOID MmFindGapBottomUp( - PMMSUPPORT AddressSpace, - ULONG_PTR Length, - ULONG_PTR Granularity) + PMMSUPPORT AddressSpace, + ULONG_PTR Length, + ULONG_PTR Granularity) { ULONG_PTR LowestAddress, HighestAddress, Candidate; PMEMORY_AREA Root, Node; @@ -528,9 +528,9 @@ MmFindGapBottomUp( static PVOID MmFindGapTopDown( - PMMSUPPORT AddressSpace, - ULONG_PTR Length, - ULONG_PTR Granularity) + PMMSUPPORT AddressSpace, + ULONG_PTR Length, + ULONG_PTR Granularity) { ULONG_PTR LowestAddress, HighestAddress, Candidate; PMEMORY_AREA Root, Node; @@ -599,88 +599,88 @@ MmFindGapTopDown( PVOID NTAPI MmFindGap( - PMMSUPPORT AddressSpace, - ULONG_PTR Length, - ULONG_PTR Granularity, - BOOLEAN TopDown) + PMMSUPPORT AddressSpace, + ULONG_PTR Length, + ULONG_PTR Granularity, + BOOLEAN TopDown) { - if (TopDown) - return MmFindGapTopDown(AddressSpace, Length, Granularity); + if (TopDown) + return MmFindGapTopDown(AddressSpace, Length, Granularity); - return MmFindGapBottomUp(AddressSpace, Length, Granularity); + return MmFindGapBottomUp(AddressSpace, Length, Granularity); } ULONG_PTR NTAPI MmFindGapAtAddress( - PMMSUPPORT AddressSpace, - PVOID Address) + PMMSUPPORT AddressSpace, + PVOID Address) { - PMEMORY_AREA Node = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink; - PMEMORY_AREA RightNeighbour = NULL; - PVOID LowestAddress = MmGetAddressSpaceOwner(AddressSpace) ? MM_LOWEST_USER_ADDRESS : MmSystemRangeStart; - PVOID HighestAddress = MmGetAddressSpaceOwner(AddressSpace) ? - (PVOID)((ULONG_PTR)MmSystemRangeStart - 1) : (PVOID)MAXULONG_PTR; + PMEMORY_AREA Node = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink; + PMEMORY_AREA RightNeighbour = NULL; + PVOID LowestAddress = MmGetAddressSpaceOwner(AddressSpace) ? MM_LOWEST_USER_ADDRESS : MmSystemRangeStart; + PVOID HighestAddress = MmGetAddressSpaceOwner(AddressSpace) ? + (PVOID)((ULONG_PTR)MmSystemRangeStart - 1) : (PVOID)MAXULONG_PTR; - Address = MM_ROUND_DOWN(Address, PAGE_SIZE); + Address = MM_ROUND_DOWN(Address, PAGE_SIZE); - if (LowestAddress < MmSystemRangeStart) - { - if (Address >= MmSystemRangeStart) - { - return 0; - } - } - else - { - if (Address < LowestAddress) - { - return 0; - } - } + if (LowestAddress < MmSystemRangeStart) + { + if (Address >= MmSystemRangeStart) + { + return 0; + } + } + else + { + if (Address < LowestAddress) + { + return 0; + } + } - while (Node != NULL) - { - if (Address < Node->StartingAddress) - { - RightNeighbour = Node; - Node = Node->LeftChild; - } - else if (Address >= Node->EndingAddress) - { - Node = Node->RightChild; - } - else - { - DPRINT("MmFindGapAtAddress: 0\n"); - return 0; - } - } + while (Node != NULL) + { + if (Address < Node->StartingAddress) + { + RightNeighbour = Node; + Node = Node->LeftChild; + } + else if (Address >= Node->EndingAddress) + { + Node = Node->RightChild; + } + else + { + DPRINT("MmFindGapAtAddress: 0\n"); + return 0; + } + } - if (RightNeighbour) - { - DPRINT("MmFindGapAtAddress: %p [%p]\n", Address, - (ULONG_PTR)RightNeighbour->StartingAddress - (ULONG_PTR)Address); - return (ULONG_PTR)RightNeighbour->StartingAddress - (ULONG_PTR)Address; - } - else - { - DPRINT("MmFindGapAtAddress: %p [%p]\n", Address, - (ULONG_PTR)HighestAddress - (ULONG_PTR)Address); - return (ULONG_PTR)HighestAddress - (ULONG_PTR)Address; - } + if (RightNeighbour) + { + DPRINT("MmFindGapAtAddress: %p [%p]\n", Address, + (ULONG_PTR)RightNeighbour->StartingAddress - (ULONG_PTR)Address); + return (ULONG_PTR)RightNeighbour->StartingAddress - (ULONG_PTR)Address; + } + else + { + DPRINT("MmFindGapAtAddress: %p [%p]\n", Address, + (ULONG_PTR)HighestAddress - (ULONG_PTR)Address); + return (ULONG_PTR)HighestAddress - (ULONG_PTR)Address; + } } VOID NTAPI MiRemoveNode(IN PMMADDRESS_NODE Node, -IN PMM_AVL_TABLE Table); + IN PMM_AVL_TABLE Table); #if DBG static VOID MiRosCheckMemoryAreasRecursive( - PMEMORY_AREA Node) + PMEMORY_AREA Node) { /* Check if the allocation is ok */ ExpCheckPoolAllocation(Node, NonPagedPool, 'ERAM'); @@ -693,7 +693,7 @@ MiRosCheckMemoryAreasRecursive( ASSERT((ULONG_PTR)Node->StartingAddress < (ULONG_PTR)Node->EndingAddress); ASSERT((Node->Type == 0) || (Node->Type == MEMORY_AREA_CACHE) || - // (Node->Type == MEMORY_AREA_CACHE_SEGMENT) || + // (Node->Type == MEMORY_AREA_CACHE_SEGMENT) || (Node->Type == MEMORY_AREA_SECTION_VIEW) || (Node->Type == MEMORY_AREA_OWNED_BY_ARM3) || (Node->Type == (MEMORY_AREA_OWNED_BY_ARM3 | MEMORY_AREA_STATIC))); @@ -708,7 +708,7 @@ MiRosCheckMemoryAreasRecursive( VOID NTAPI MiRosCheckMemoryAreas( - PMMSUPPORT AddressSpace) + PMMSUPPORT AddressSpace) { PMEMORY_AREA RootNode; PEPROCESS AddressSpaceOwner; @@ -796,54 +796,54 @@ MiDeletePte(IN PMMPTE PointerPte, NTSTATUS NTAPI MmFreeMemoryArea( - PMMSUPPORT AddressSpace, - PMEMORY_AREA MemoryArea, - PMM_FREE_PAGE_FUNC FreePage, - PVOID FreePageContext) + PMMSUPPORT AddressSpace, + PMEMORY_AREA MemoryArea, + PMM_FREE_PAGE_FUNC FreePage, + PVOID FreePageContext) { - PMEMORY_AREA *ParentReplace; - ULONG_PTR Address; - PVOID EndAddress; + PMEMORY_AREA *ParentReplace; + ULONG_PTR Address; + PVOID EndAddress; - /* Make sure we own the address space lock! */ - ASSERT(CONTAINING_RECORD(AddressSpace, EPROCESS, Vm)->AddressCreationLock.Owner == KeGetCurrentThread()); + /* Make sure we own the address space lock! */ + ASSERT(CONTAINING_RECORD(AddressSpace, EPROCESS, Vm)->AddressCreationLock.Owner == KeGetCurrentThread()); /* Check magic */ ASSERT(MemoryArea->Magic == 'erAM'); - if (MemoryArea->Type != MEMORY_AREA_OWNED_BY_ARM3) - { - PEPROCESS CurrentProcess = PsGetCurrentProcess(); - PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace); + if (MemoryArea->Type != MEMORY_AREA_OWNED_BY_ARM3) + { + PEPROCESS CurrentProcess = PsGetCurrentProcess(); + PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace); - if (Process != NULL && - Process != CurrentProcess) - { - KeAttachProcess(&Process->Pcb); - } + if (Process != NULL && + Process != CurrentProcess) + { + KeAttachProcess(&Process->Pcb); + } - EndAddress = MM_ROUND_UP(MemoryArea->EndingAddress, PAGE_SIZE); - for (Address = (ULONG_PTR)MemoryArea->StartingAddress; - Address < (ULONG_PTR)EndAddress; - Address += PAGE_SIZE) - { - BOOLEAN Dirty = FALSE; - SWAPENTRY SwapEntry = 0; - PFN_NUMBER Page = 0; + EndAddress = MM_ROUND_UP(MemoryArea->EndingAddress, PAGE_SIZE); + for (Address = (ULONG_PTR)MemoryArea->StartingAddress; + Address < (ULONG_PTR)EndAddress; + Address += PAGE_SIZE) + { + BOOLEAN Dirty = FALSE; + SWAPENTRY SwapEntry = 0; + PFN_NUMBER Page = 0; - if (MmIsPageSwapEntry(Process, (PVOID)Address)) - { + if (MmIsPageSwapEntry(Process, (PVOID)Address)) + { MmDeletePageFileMapping(Process, (PVOID)Address, &SwapEntry); - } - else - { + } + else + { MmDeleteVirtualMapping(Process, (PVOID)Address, FALSE, &Dirty, &Page); - } - if (FreePage != NULL) - { + } + if (FreePage != NULL) + { FreePage(FreePageContext, MemoryArea, (PVOID)Address, Page, SwapEntry, (BOOLEAN)Dirty); - } + } #if (_MI_PAGING_LEVELS == 2) /* Remove page table reference */ ASSERT(KeGetCurrentIrql() <= APC_LEVEL); @@ -862,90 +862,90 @@ MmFreeMemoryArea( } } #endif - } + } - if (Process != NULL && - Process != CurrentProcess) - { - KeDetachProcess(); - } + if (Process != NULL && + Process != CurrentProcess) + { + KeDetachProcess(); + } - if (MemoryArea->Vad) - { - ASSERT(MemoryArea->EndingAddress < MmSystemRangeStart); - ASSERT(MemoryArea->Type == MEMORY_AREA_SECTION_VIEW || MemoryArea->Type == MEMORY_AREA_CACHE); + if (MemoryArea->Vad) + { + ASSERT(MemoryArea->EndingAddress < MmSystemRangeStart); + ASSERT(MemoryArea->Type == MEMORY_AREA_SECTION_VIEW || MemoryArea->Type == MEMORY_AREA_CACHE); - /* MmCleanProcessAddressSpace might have removed it (and this would be MmDeleteProcessAdressSpace) */ - ASSERT(((PMMVAD)MemoryArea->Vad)->u.VadFlags.Spare != 0); - if (((PMMVAD)MemoryArea->Vad)->u.VadFlags.Spare == 1) - { - MiRemoveNode(MemoryArea->Vad, &Process->VadRoot); - } + /* MmCleanProcessAddressSpace might have removed it (and this would be MmDeleteProcessAdressSpace) */ + ASSERT(((PMMVAD)MemoryArea->Vad)->u.VadFlags.Spare != 0); + if (((PMMVAD)MemoryArea->Vad)->u.VadFlags.Spare == 1) + { + MiRemoveNode(MemoryArea->Vad, &Process->VadRoot); + } - ExFreePoolWithTag(MemoryArea->Vad, TAG_MVAD); - MemoryArea->Vad = NULL; - } + ExFreePoolWithTag(MemoryArea->Vad, TAG_MVAD); + MemoryArea->Vad = NULL; + } } - /* Remove the tree item. */ - { - if (MemoryArea->Parent != NULL) - { - if (MemoryArea->Parent->LeftChild == MemoryArea) - ParentReplace = &MemoryArea->Parent->LeftChild; - else - ParentReplace = &MemoryArea->Parent->RightChild; - } - else - ParentReplace = (PMEMORY_AREA*)&AddressSpace->WorkingSetExpansionLinks.Flink; + /* Remove the tree item. */ + { + if (MemoryArea->Parent != NULL) + { + if (MemoryArea->Parent->LeftChild == MemoryArea) + ParentReplace = &MemoryArea->Parent->LeftChild; + else + ParentReplace = &MemoryArea->Parent->RightChild; + } + else + ParentReplace = (PMEMORY_AREA*)&AddressSpace->WorkingSetExpansionLinks.Flink; - if (MemoryArea->RightChild == NULL) - { - *ParentReplace = MemoryArea->LeftChild; - if (MemoryArea->LeftChild) - MemoryArea->LeftChild->Parent = MemoryArea->Parent; - } - else - { - if (MemoryArea->RightChild->LeftChild == NULL) - { - MemoryArea->RightChild->LeftChild = MemoryArea->LeftChild; + if (MemoryArea->RightChild == NULL) + { + *ParentReplace = MemoryArea->LeftChild; if (MemoryArea->LeftChild) - MemoryArea->LeftChild->Parent = MemoryArea->RightChild; + MemoryArea->LeftChild->Parent = MemoryArea->Parent; + } + else + { + if (MemoryArea->RightChild->LeftChild == NULL) + { + MemoryArea->RightChild->LeftChild = MemoryArea->LeftChild; + if (MemoryArea->LeftChild) + MemoryArea->LeftChild->Parent = MemoryArea->RightChild; - *ParentReplace = MemoryArea->RightChild; - MemoryArea->RightChild->Parent = MemoryArea->Parent; - } - else - { - PMEMORY_AREA LowestNode; + *ParentReplace = MemoryArea->RightChild; + MemoryArea->RightChild->Parent = MemoryArea->Parent; + } + else + { + PMEMORY_AREA LowestNode; - LowestNode = MemoryArea->RightChild->LeftChild; - while (LowestNode->LeftChild != NULL) - LowestNode = LowestNode->LeftChild; + LowestNode = MemoryArea->RightChild->LeftChild; + while (LowestNode->LeftChild != NULL) + LowestNode = LowestNode->LeftChild; - LowestNode->Parent->LeftChild = LowestNode->RightChild; - if (LowestNode->RightChild) - LowestNode->RightChild->Parent = LowestNode->Parent; + LowestNode->Parent->LeftChild = LowestNode->RightChild; + if (LowestNode->RightChild) + LowestNode->RightChild->Parent = LowestNode->Parent; - LowestNode->LeftChild = MemoryArea->LeftChild; - if (MemoryArea->LeftChild) - MemoryArea->LeftChild->Parent = LowestNode; + LowestNode->LeftChild = MemoryArea->LeftChild; + if (MemoryArea->LeftChild) + MemoryArea->LeftChild->Parent = LowestNode; - LowestNode->RightChild = MemoryArea->RightChild; - MemoryArea->RightChild->Parent = LowestNode; + LowestNode->RightChild = MemoryArea->RightChild; + MemoryArea->RightChild->Parent = LowestNode; - *ParentReplace = LowestNode; - LowestNode->Parent = MemoryArea->Parent; - } - } - } + *ParentReplace = LowestNode; + LowestNode->Parent = MemoryArea->Parent; + } + } + } - ExFreePoolWithTag(MemoryArea, TAG_MAREA); + ExFreePoolWithTag(MemoryArea, TAG_MAREA); - DPRINT("MmFreeMemoryAreaByNode() succeeded\n"); + DPRINT("MmFreeMemoryAreaByNode() succeeded\n"); - return STATUS_SUCCESS; + return STATUS_SUCCESS; } /** @@ -985,55 +985,55 @@ MmCreateMemoryArea(PMMSUPPORT AddressSpace, ULONG AllocationFlags, ULONG Granularity) { - ULONG_PTR tmpLength; - PMEMORY_AREA MemoryArea; - ULONG_PTR EndingAddress; + ULONG_PTR tmpLength; + PMEMORY_AREA MemoryArea; + ULONG_PTR EndingAddress; - DPRINT("MmCreateMemoryArea(Type 0x%lx, BaseAddress %p, " - "*BaseAddress %p, Length %p, AllocationFlags %x, " - "FixedAddress %x, Result %p)\n", - Type, BaseAddress, *BaseAddress, Length, AllocationFlags, - FixedAddress, Result); + DPRINT("MmCreateMemoryArea(Type 0x%lx, BaseAddress %p, " + "*BaseAddress %p, Length %p, AllocationFlags %x, " + "FixedAddress %x, Result %p)\n", + Type, BaseAddress, *BaseAddress, Length, AllocationFlags, + FixedAddress, Result); - if ((*BaseAddress) == 0 && !FixedAddress) - { - tmpLength = (ULONG_PTR)MM_ROUND_UP(Length, PAGE_SIZE); - *BaseAddress = MmFindGap(AddressSpace, - tmpLength, - Granularity, - (AllocationFlags & MEM_TOP_DOWN) == MEM_TOP_DOWN); - if ((*BaseAddress) == 0) - { - DPRINT("No suitable gap\n"); - return STATUS_NO_MEMORY; - } - } - else - { - EndingAddress = ((ULONG_PTR)*BaseAddress + Length - 1) | (PAGE_SIZE - 1); - *BaseAddress = ALIGN_DOWN_POINTER_BY(*BaseAddress, Granularity); - tmpLength = EndingAddress + 1 - (ULONG_PTR)*BaseAddress; + if ((*BaseAddress) == 0 && !FixedAddress) + { + tmpLength = (ULONG_PTR)MM_ROUND_UP(Length, PAGE_SIZE); + *BaseAddress = MmFindGap(AddressSpace, + tmpLength, + Granularity, + (AllocationFlags & MEM_TOP_DOWN) == MEM_TOP_DOWN); + if ((*BaseAddress) == 0) + { + DPRINT("No suitable gap\n"); + return STATUS_NO_MEMORY; + } + } + else + { + EndingAddress = ((ULONG_PTR)*BaseAddress + Length - 1) | (PAGE_SIZE - 1); + *BaseAddress = ALIGN_DOWN_POINTER_BY(*BaseAddress, Granularity); + tmpLength = EndingAddress + 1 - (ULONG_PTR)*BaseAddress; - if (!MmGetAddressSpaceOwner(AddressSpace) && *BaseAddress < MmSystemRangeStart) - { - return STATUS_ACCESS_VIOLATION; - } + if (!MmGetAddressSpaceOwner(AddressSpace) && *BaseAddress < MmSystemRangeStart) + { + return STATUS_ACCESS_VIOLATION; + } - if (MmGetAddressSpaceOwner(AddressSpace) && - (ULONG_PTR)(*BaseAddress) + tmpLength > (ULONG_PTR)MmSystemRangeStart) - { - DPRINT("Memory area for user mode address space exceeds MmSystemRangeStart\n"); - return STATUS_ACCESS_VIOLATION; - } + if (MmGetAddressSpaceOwner(AddressSpace) && + (ULONG_PTR)(*BaseAddress) + tmpLength > (ULONG_PTR)MmSystemRangeStart) + { + DPRINT("Memory area for user mode address space exceeds MmSystemRangeStart\n"); + return STATUS_ACCESS_VIOLATION; + } - if (MmLocateMemoryAreaByRegion(AddressSpace, - *BaseAddress, - tmpLength) != NULL) - { - DPRINT("Memory area already occupied\n"); - return STATUS_CONFLICTING_ADDRESSES; - } - } + if (MmLocateMemoryAreaByRegion(AddressSpace, + *BaseAddress, + tmpLength) != NULL) + { + DPRINT("Memory area already occupied\n"); + return STATUS_CONFLICTING_ADDRESSES; + } + } // // Is this a static memory area? @@ -1057,28 +1057,28 @@ MmCreateMemoryArea(PMMSUPPORT AddressSpace, TAG_MAREA); } - if (!MemoryArea) - { - DPRINT1("Not enough memory.\n"); - return STATUS_NO_MEMORY; - } + if (!MemoryArea) + { + DPRINT1("Not enough memory.\n"); + return STATUS_NO_MEMORY; + } - RtlZeroMemory(MemoryArea, sizeof(MEMORY_AREA)); - MemoryArea->Type = Type; - MemoryArea->StartingAddress = *BaseAddress; - MemoryArea->EndingAddress = (PVOID)((ULONG_PTR)*BaseAddress + tmpLength); - MemoryArea->Protect = Protect; - MemoryArea->Flags = AllocationFlags; - //MemoryArea->LockCount = 0; - MemoryArea->Magic = 'erAM'; - MemoryArea->DeleteInProgress = FALSE; + RtlZeroMemory(MemoryArea, sizeof(MEMORY_AREA)); + MemoryArea->Type = Type; + MemoryArea->StartingAddress = *BaseAddress; + MemoryArea->EndingAddress = (PVOID)((ULONG_PTR)*BaseAddress + tmpLength); + MemoryArea->Protect = Protect; + MemoryArea->Flags = AllocationFlags; + //MemoryArea->LockCount = 0; + MemoryArea->Magic = 'erAM'; + MemoryArea->DeleteInProgress = FALSE; - MmInsertMemoryArea(AddressSpace, MemoryArea); + MmInsertMemoryArea(AddressSpace, MemoryArea); - *Result = MemoryArea; + *Result = MemoryArea; - DPRINT("MmCreateMemoryArea() succeeded (%p)\n", *BaseAddress); - return STATUS_SUCCESS; + DPRINT("MmCreateMemoryArea() succeeded (%p)\n", *BaseAddress); + return STATUS_SUCCESS; } VOID NTAPI @@ -1087,32 +1087,32 @@ MmMapMemoryArea(PVOID BaseAddress, ULONG Consumer, ULONG Protection) { - ULONG i; - NTSTATUS Status; + ULONG i; + NTSTATUS Status; - ASSERT(((ULONG_PTR)BaseAddress % PAGE_SIZE) == 0); + ASSERT(((ULONG_PTR)BaseAddress % PAGE_SIZE) == 0); - for (i = 0; i < PAGE_ROUND_UP(Length) / PAGE_SIZE; i++) - { - PFN_NUMBER Page; + for (i = 0; i < PAGE_ROUND_UP(Length) / PAGE_SIZE; i++) + { + PFN_NUMBER Page; - Status = MmRequestPageMemoryConsumer(Consumer, TRUE, &Page); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Unable to allocate page\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - Status = MmCreateVirtualMapping (NULL, - (PVOID)((ULONG_PTR)BaseAddress + (i * PAGE_SIZE)), - Protection, - &Page, - 1); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Unable to create virtual mapping\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - } + Status = MmRequestPageMemoryConsumer(Consumer, TRUE, &Page); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Unable to allocate page\n"); + KeBugCheck(MEMORY_MANAGEMENT); + } + Status = MmCreateVirtualMapping (NULL, + (PVOID)((ULONG_PTR)BaseAddress + (i * PAGE_SIZE)), + Protection, + &Page, + 1); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Unable to create virtual mapping\n"); + KeBugCheck(MEMORY_MANAGEMENT); + } + } } VOID @@ -1123,46 +1123,46 @@ NTSTATUS NTAPI MmDeleteProcessAddressSpace(PEPROCESS Process) { - PVOID Address; - PMEMORY_AREA MemoryArea; + PVOID Address; + PMEMORY_AREA MemoryArea; - DPRINT("MmDeleteProcessAddressSpace(Process %p (%s))\n", Process, - Process->ImageFileName); + DPRINT("MmDeleteProcessAddressSpace(Process %p (%s))\n", Process, + Process->ImageFileName); #ifndef _M_AMD64 - RemoveEntryList(&Process->MmProcessLinks); + RemoveEntryList(&Process->MmProcessLinks); #endif - MmLockAddressSpace(&Process->Vm); + MmLockAddressSpace(&Process->Vm); - while ((MemoryArea = (PMEMORY_AREA)Process->Vm.WorkingSetExpansionLinks.Flink) != NULL) - { - switch (MemoryArea->Type) - { - case MEMORY_AREA_SECTION_VIEW: - Address = (PVOID)MemoryArea->StartingAddress; - MmUnlockAddressSpace(&Process->Vm); - MmUnmapViewOfSection(Process, Address); - MmLockAddressSpace(&Process->Vm); - break; + while ((MemoryArea = (PMEMORY_AREA)Process->Vm.WorkingSetExpansionLinks.Flink) != NULL) + { + switch (MemoryArea->Type) + { + case MEMORY_AREA_SECTION_VIEW: + Address = (PVOID)MemoryArea->StartingAddress; + MmUnlockAddressSpace(&Process->Vm); + MmUnmapViewOfSection(Process, Address); + MmLockAddressSpace(&Process->Vm); + break; - case MEMORY_AREA_CACHE: - Address = (PVOID)MemoryArea->StartingAddress; - MmUnlockAddressSpace(&Process->Vm); - MmUnmapViewOfCacheSegment(&Process->Vm, Address); - MmLockAddressSpace(&Process->Vm); - break; + case MEMORY_AREA_CACHE: + Address = (PVOID)MemoryArea->StartingAddress; + MmUnlockAddressSpace(&Process->Vm); + MmUnmapViewOfCacheSegment(&Process->Vm, Address); + MmLockAddressSpace(&Process->Vm); + break; - case MEMORY_AREA_OWNED_BY_ARM3: - MmFreeMemoryArea(&Process->Vm, - MemoryArea, - NULL, - NULL); - break; + case MEMORY_AREA_OWNED_BY_ARM3: + MmFreeMemoryArea(&Process->Vm, + MemoryArea, + NULL, + NULL); + break; - default: + default: KeBugCheck(MEMORY_MANAGEMENT); - } - } + } + } #if (_MI_PAGING_LEVELS == 2) { @@ -1175,8 +1175,8 @@ MmDeleteProcessAddressSpace(PEPROCESS Process) OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); for (Address = MI_LOWEST_VAD_ADDRESS; - Address < MM_HIGHEST_VAD_ADDRESS; - Address =(PVOID)((ULONG_PTR)Address + (PAGE_SIZE * PTE_COUNT))) + Address < MM_HIGHEST_VAD_ADDRESS; + Address =(PVOID)((ULONG_PTR)Address + (PAGE_SIZE * PTE_COUNT))) { /* At this point all references should be dead */ if (MiQueryPageTableReferences(Address) != 0) @@ -1202,11 +1202,11 @@ MmDeleteProcessAddressSpace(PEPROCESS Process) } #endif - MmUnlockAddressSpace(&Process->Vm); + MmUnlockAddressSpace(&Process->Vm); - DPRINT("Finished MmDeleteProcessAddressSpace()\n"); - MmDeleteProcessAddressSpace2(Process); - return(STATUS_SUCCESS); + DPRINT("Finished MmDeleteProcessAddressSpace()\n"); + MmDeleteProcessAddressSpace2(Process); + return(STATUS_SUCCESS); } /* EOF */ diff --git a/reactos/ntoskrnl/mm/mmfault.c b/reactos/ntoskrnl/mm/mmfault.c index 602d708fc3a..2390854ace7 100644 --- a/reactos/ntoskrnl/mm/mmfault.c +++ b/reactos/ntoskrnl/mm/mmfault.c @@ -21,180 +21,180 @@ NTSTATUS NTAPI MmpAccessFault(KPROCESSOR_MODE Mode, - ULONG_PTR Address, - BOOLEAN FromMdl) + ULONG_PTR Address, + BOOLEAN FromMdl) { - PMMSUPPORT AddressSpace; - MEMORY_AREA* MemoryArea; - NTSTATUS Status; + PMMSUPPORT AddressSpace; + MEMORY_AREA* MemoryArea; + NTSTATUS Status; - DPRINT("MmAccessFault(Mode %d, Address %x)\n", Mode, Address); + DPRINT("MmAccessFault(Mode %d, Address %x)\n", Mode, Address); - if (KeGetCurrentIrql() >= DISPATCH_LEVEL) - { - DPRINT1("Page fault at high IRQL was %u\n", KeGetCurrentIrql()); - return(STATUS_UNSUCCESSFUL); - } + if (KeGetCurrentIrql() >= DISPATCH_LEVEL) + { + DPRINT1("Page fault at high IRQL was %u\n", KeGetCurrentIrql()); + return(STATUS_UNSUCCESSFUL); + } - /* - * Find the memory area for the faulting address - */ - if (Address >= (ULONG_PTR)MmSystemRangeStart) - { - /* - * Check permissions - */ - if (Mode != KernelMode) - { - DPRINT1("MmAccessFault(Mode %d, Address %x)\n", Mode, Address); - return(STATUS_ACCESS_VIOLATION); - } - AddressSpace = MmGetKernelAddressSpace(); - } - else - { - AddressSpace = &PsGetCurrentProcess()->Vm; - } + /* + * Find the memory area for the faulting address + */ + if (Address >= (ULONG_PTR)MmSystemRangeStart) + { + /* + * Check permissions + */ + if (Mode != KernelMode) + { + DPRINT1("MmAccessFault(Mode %d, Address %x)\n", Mode, Address); + return(STATUS_ACCESS_VIOLATION); + } + AddressSpace = MmGetKernelAddressSpace(); + } + else + { + AddressSpace = &PsGetCurrentProcess()->Vm; + } - if (!FromMdl) - { - MmLockAddressSpace(AddressSpace); - } - do - { - MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, (PVOID)Address); - if (MemoryArea == NULL || MemoryArea->DeleteInProgress) - { - if (!FromMdl) - { - MmUnlockAddressSpace(AddressSpace); - } - return (STATUS_ACCESS_VIOLATION); - } + if (!FromMdl) + { + MmLockAddressSpace(AddressSpace); + } + do + { + MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, (PVOID)Address); + if (MemoryArea == NULL || MemoryArea->DeleteInProgress) + { + if (!FromMdl) + { + MmUnlockAddressSpace(AddressSpace); + } + return (STATUS_ACCESS_VIOLATION); + } - switch (MemoryArea->Type) - { - case MEMORY_AREA_SECTION_VIEW: + switch (MemoryArea->Type) + { + case MEMORY_AREA_SECTION_VIEW: Status = MmAccessFaultSectionView(AddressSpace, MemoryArea, (PVOID)Address); break; - case MEMORY_AREA_CACHE: + case MEMORY_AREA_CACHE: // This code locks for itself to keep from having to break a lock // passed in. if (!FromMdl) - MmUnlockAddressSpace(AddressSpace); + MmUnlockAddressSpace(AddressSpace); Status = MmAccessFaultCacheSection(Mode, Address, FromMdl); if (!FromMdl) - MmLockAddressSpace(AddressSpace); + MmLockAddressSpace(AddressSpace); break; - default: + default: Status = STATUS_ACCESS_VIOLATION; break; - } - } - while (Status == STATUS_MM_RESTART_OPERATION); + } + } + while (Status == STATUS_MM_RESTART_OPERATION); - DPRINT("Completed page fault handling\n"); - if (!FromMdl) - { - MmUnlockAddressSpace(AddressSpace); - } - return(Status); + DPRINT("Completed page fault handling\n"); + if (!FromMdl) + { + MmUnlockAddressSpace(AddressSpace); + } + return(Status); } NTSTATUS NTAPI MmNotPresentFault(KPROCESSOR_MODE Mode, - ULONG_PTR Address, - BOOLEAN FromMdl) + ULONG_PTR Address, + BOOLEAN FromMdl) { - PMMSUPPORT AddressSpace; - MEMORY_AREA* MemoryArea; - NTSTATUS Status; + PMMSUPPORT AddressSpace; + MEMORY_AREA* MemoryArea; + NTSTATUS Status; - DPRINT("MmNotPresentFault(Mode %d, Address %x)\n", Mode, Address); + DPRINT("MmNotPresentFault(Mode %d, Address %x)\n", Mode, Address); - if (KeGetCurrentIrql() >= DISPATCH_LEVEL) - { - DPRINT1("Page fault at high IRQL was %u, address %x\n", KeGetCurrentIrql(), Address); - return(STATUS_UNSUCCESSFUL); - } + if (KeGetCurrentIrql() >= DISPATCH_LEVEL) + { + DPRINT1("Page fault at high IRQL was %u, address %x\n", KeGetCurrentIrql(), Address); + return(STATUS_UNSUCCESSFUL); + } - /* - * Find the memory area for the faulting address - */ - if (Address >= (ULONG_PTR)MmSystemRangeStart) - { - /* - * Check permissions - */ - if (Mode != KernelMode) - { - DPRINT1("Address: %x\n", Address); - return(STATUS_ACCESS_VIOLATION); - } - AddressSpace = MmGetKernelAddressSpace(); - } - else - { - AddressSpace = &PsGetCurrentProcess()->Vm; - } + /* + * Find the memory area for the faulting address + */ + if (Address >= (ULONG_PTR)MmSystemRangeStart) + { + /* + * Check permissions + */ + if (Mode != KernelMode) + { + DPRINT1("Address: %x\n", Address); + return(STATUS_ACCESS_VIOLATION); + } + AddressSpace = MmGetKernelAddressSpace(); + } + else + { + AddressSpace = &PsGetCurrentProcess()->Vm; + } - if (!FromMdl) - { - MmLockAddressSpace(AddressSpace); - } + if (!FromMdl) + { + MmLockAddressSpace(AddressSpace); + } - /* - * Call the memory area specific fault handler - */ - do - { - MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, (PVOID)Address); - if (MemoryArea == NULL || MemoryArea->DeleteInProgress) - { - if (!FromMdl) - { - MmUnlockAddressSpace(AddressSpace); - } - return (STATUS_ACCESS_VIOLATION); - } + /* + * Call the memory area specific fault handler + */ + do + { + MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, (PVOID)Address); + if (MemoryArea == NULL || MemoryArea->DeleteInProgress) + { + if (!FromMdl) + { + MmUnlockAddressSpace(AddressSpace); + } + return (STATUS_ACCESS_VIOLATION); + } - switch (MemoryArea->Type) - { - case MEMORY_AREA_SECTION_VIEW: + switch (MemoryArea->Type) + { + case MEMORY_AREA_SECTION_VIEW: Status = MmNotPresentFaultSectionView(AddressSpace, MemoryArea, (PVOID)Address, FromMdl); break; - case MEMORY_AREA_CACHE: + case MEMORY_AREA_CACHE: // This code locks for itself to keep from having to break a lock // passed in. if (!FromMdl) - MmUnlockAddressSpace(AddressSpace); + MmUnlockAddressSpace(AddressSpace); Status = MmNotPresentFaultCacheSection(Mode, Address, FromMdl); if (!FromMdl) - MmLockAddressSpace(AddressSpace); + MmLockAddressSpace(AddressSpace); break; - default: + default: Status = STATUS_ACCESS_VIOLATION; break; - } - } - while (Status == STATUS_MM_RESTART_OPERATION); + } + } + while (Status == STATUS_MM_RESTART_OPERATION); - DPRINT("Completed page fault handling\n"); - if (!FromMdl) - { - MmUnlockAddressSpace(AddressSpace); - } - return(Status); + DPRINT("Completed page fault handling\n"); + if (!FromMdl) + { + MmUnlockAddressSpace(AddressSpace); + } + return(Status); } extern BOOLEAN Mmi386MakeKernelPageTableGlobal(PVOID Address); @@ -235,8 +235,8 @@ MmAccessFault(IN BOOLEAN StoreInstruction, /* Is this an ARM3 memory area, or is there no address space yet? */ if (((MemoryArea) && (MemoryArea->Type == MEMORY_AREA_OWNED_BY_ARM3)) || - (!(MemoryArea) && ((ULONG_PTR)Address >= (ULONG_PTR)MmPagedPoolStart)) || - (!MmGetKernelAddressSpace())) + (!(MemoryArea) && ((ULONG_PTR)Address >= (ULONG_PTR)MmPagedPoolStart)) || + (!MmGetKernelAddressSpace())) { /* This is an ARM3 fault */ DPRINT("ARM3 fault %p\n", MemoryArea); diff --git a/reactos/ntoskrnl/mm/mminit.c b/reactos/ntoskrnl/mm/mminit.c index 910f3973dae..41732e3c672 100644 --- a/reactos/ntoskrnl/mm/mminit.c +++ b/reactos/ntoskrnl/mm/mminit.c @@ -299,36 +299,36 @@ VOID NTAPI MmMpwThreadMain(PVOID Parameter) { - NTSTATUS Status; - ULONG PagesWritten; - LARGE_INTEGER Timeout; + NTSTATUS Status; + ULONG PagesWritten; + LARGE_INTEGER Timeout; - UNREFERENCED_PARAMETER(Parameter); + UNREFERENCED_PARAMETER(Parameter); - Timeout.QuadPart = -50000000; + Timeout.QuadPart = -50000000; - for(;;) - { - Status = KeWaitForSingleObject(&MpwThreadEvent, - 0, - KernelMode, - FALSE, - &Timeout); - if (!NT_SUCCESS(Status)) - { - DbgPrint("MpwThread: Wait failed\n"); - KeBugCheck(MEMORY_MANAGEMENT); - return; - } + for(;;) + { + Status = KeWaitForSingleObject(&MpwThreadEvent, + 0, + KernelMode, + FALSE, + &Timeout); + if (!NT_SUCCESS(Status)) + { + DbgPrint("MpwThread: Wait failed\n"); + KeBugCheck(MEMORY_MANAGEMENT); + return; + } - PagesWritten = 0; + PagesWritten = 0; #ifndef NEWCC - // XXX arty -- we flush when evicting pages or destorying cache - // sections. - CcRosFlushDirtyPages(128, &PagesWritten, FALSE); + // XXX arty -- we flush when evicting pages or destorying cache + // sections. + CcRosFlushDirtyPages(128, &PagesWritten, FALSE); #endif - } + } } NTSTATUS @@ -336,31 +336,31 @@ NTAPI INIT_FUNCTION MmInitMpwThread(VOID) { - KPRIORITY Priority; - NTSTATUS Status; - CLIENT_ID MpwThreadId; + KPRIORITY Priority; + NTSTATUS Status; + CLIENT_ID MpwThreadId; - KeInitializeEvent(&MpwThreadEvent, SynchronizationEvent, FALSE); + KeInitializeEvent(&MpwThreadEvent, SynchronizationEvent, FALSE); - Status = PsCreateSystemThread(&MpwThreadHandle, - THREAD_ALL_ACCESS, - NULL, - NULL, - &MpwThreadId, - MmMpwThreadMain, - NULL); - if (!NT_SUCCESS(Status)) - { - return(Status); - } + Status = PsCreateSystemThread(&MpwThreadHandle, + THREAD_ALL_ACCESS, + NULL, + NULL, + &MpwThreadId, + MmMpwThreadMain, + NULL); + if (!NT_SUCCESS(Status)) + { + return(Status); + } - Priority = 27; - NtSetInformationThread(MpwThreadHandle, - ThreadPriority, - &Priority, - sizeof(Priority)); + Priority = 27; + NtSetInformationThread(MpwThreadHandle, + ThreadPriority, + &Priority, + sizeof(Priority)); - return(STATUS_SUCCESS); + return(STATUS_SUCCESS); } NTSTATUS @@ -430,8 +430,8 @@ MmInitSystem(IN ULONG Phase, // by the fault handler. // MmSharedUserDataPte = ExAllocatePoolWithTag(PagedPool, - sizeof(MMPTE), - ' mM'); + sizeof(MMPTE), + ' mM'); if (!MmSharedUserDataPte) return FALSE; // diff --git a/reactos/ntoskrnl/mm/pagefile.c b/reactos/ntoskrnl/mm/pagefile.c index a1ffb08cc22..e5b88a58a3d 100644 --- a/reactos/ntoskrnl/mm/pagefile.c +++ b/reactos/ntoskrnl/mm/pagefile.c @@ -44,23 +44,23 @@ MiFindExportedRoutineByName(IN PVOID DllBase, typedef struct _PAGINGFILE { - LIST_ENTRY PagingFileListEntry; - PFILE_OBJECT FileObject; - LARGE_INTEGER MaximumSize; - LARGE_INTEGER CurrentSize; - PFN_NUMBER FreePages; - PFN_NUMBER UsedPages; - PULONG AllocMap; - KSPIN_LOCK AllocMapLock; - ULONG AllocMapSize; - PRETRIEVAL_POINTERS_BUFFER RetrievalPointers; + LIST_ENTRY PagingFileListEntry; + PFILE_OBJECT FileObject; + LARGE_INTEGER MaximumSize; + LARGE_INTEGER CurrentSize; + PFN_NUMBER FreePages; + PFN_NUMBER UsedPages; + PULONG AllocMap; + KSPIN_LOCK AllocMapLock; + ULONG AllocMapSize; + PRETRIEVAL_POINTERS_BUFFER RetrievalPointers; } PAGINGFILE, *PPAGINGFILE; typedef struct _RETRIEVEL_DESCRIPTOR_LIST { - struct _RETRIEVEL_DESCRIPTOR_LIST* Next; - RETRIEVAL_POINTERS_BUFFER RetrievalPointers; + struct _RETRIEVEL_DESCRIPTOR_LIST* Next; + RETRIEVAL_POINTERS_BUFFER RetrievalPointers; } RETRIEVEL_DESCRIPTOR_LIST, *PRETRIEVEL_DESCRIPTOR_LIST; @@ -153,67 +153,67 @@ VOID NTAPI MmShowOutOfSpaceMessagePagingFile(VOID) { - if (!MmSwapSpaceMessage) - { - DPRINT1("MM: Out of swap space.\n"); - MmSwapSpaceMessage = TRUE; - } + if (!MmSwapSpaceMessage) + { + DPRINT1("MM: Out of swap space.\n"); + MmSwapSpaceMessage = TRUE; + } } static LARGE_INTEGER MmGetOffsetPageFile(PRETRIEVAL_POINTERS_BUFFER RetrievalPointers, LARGE_INTEGER Offset) { - /* Simple binary search */ - ULONG first, last, mid; - first = 0; - last = RetrievalPointers->ExtentCount - 1; - while (first <= last) - { - mid = (last - first) / 2 + first; - if (Offset.QuadPart < RetrievalPointers->Extents[mid].NextVcn.QuadPart) - { - if (mid == 0) - { - Offset.QuadPart += RetrievalPointers->Extents[0].Lcn.QuadPart - RetrievalPointers->StartingVcn.QuadPart; - return Offset; - } - else - { - if (Offset.QuadPart >= RetrievalPointers->Extents[mid-1].NextVcn.QuadPart) + /* Simple binary search */ + ULONG first, last, mid; + first = 0; + last = RetrievalPointers->ExtentCount - 1; + while (first <= last) + { + mid = (last - first) / 2 + first; + if (Offset.QuadPart < RetrievalPointers->Extents[mid].NextVcn.QuadPart) + { + if (mid == 0) { - Offset.QuadPart += RetrievalPointers->Extents[mid].Lcn.QuadPart - RetrievalPointers->Extents[mid-1].NextVcn.QuadPart; - return Offset; + Offset.QuadPart += RetrievalPointers->Extents[0].Lcn.QuadPart - RetrievalPointers->StartingVcn.QuadPart; + return Offset; } - last = mid - 1; - } - } - else - { - if (mid == RetrievalPointers->ExtentCount - 1) - { - break; - } - if (Offset.QuadPart < RetrievalPointers->Extents[mid+1].NextVcn.QuadPart) - { - Offset.QuadPart += RetrievalPointers->Extents[mid+1].Lcn.QuadPart - RetrievalPointers->Extents[mid].NextVcn.QuadPart; - return Offset; - } - first = mid + 1; - } - } - KeBugCheck(MEMORY_MANAGEMENT); + else + { + if (Offset.QuadPart >= RetrievalPointers->Extents[mid-1].NextVcn.QuadPart) + { + Offset.QuadPart += RetrievalPointers->Extents[mid].Lcn.QuadPart - RetrievalPointers->Extents[mid-1].NextVcn.QuadPart; + return Offset; + } + last = mid - 1; + } + } + else + { + if (mid == RetrievalPointers->ExtentCount - 1) + { + break; + } + if (Offset.QuadPart < RetrievalPointers->Extents[mid+1].NextVcn.QuadPart) + { + Offset.QuadPart += RetrievalPointers->Extents[mid+1].Lcn.QuadPart - RetrievalPointers->Extents[mid].NextVcn.QuadPart; + return Offset; + } + first = mid + 1; + } + } + KeBugCheck(MEMORY_MANAGEMENT); #if defined(__GNUC__) - return (LARGE_INTEGER)0LL; + return (LARGE_INTEGER)0LL; #else - { - const LARGE_INTEGER dummy = - { + { + const LARGE_INTEGER dummy = + { 0 - }; - return dummy; - } + }; + return dummy; + } #endif } @@ -221,57 +221,57 @@ NTSTATUS NTAPI MmWriteToSwapPage(SWAPENTRY SwapEntry, PFN_NUMBER Page) { - ULONG i; - ULONG_PTR offset; - LARGE_INTEGER file_offset; - IO_STATUS_BLOCK Iosb; - NTSTATUS Status; - KEVENT Event; - UCHAR MdlBase[sizeof(MDL) + sizeof(ULONG)]; - PMDL Mdl = (PMDL)MdlBase; + ULONG i; + ULONG_PTR offset; + LARGE_INTEGER file_offset; + IO_STATUS_BLOCK Iosb; + NTSTATUS Status; + KEVENT Event; + UCHAR MdlBase[sizeof(MDL) + sizeof(ULONG)]; + PMDL Mdl = (PMDL)MdlBase; - DPRINT("MmWriteToSwapPage\n"); + DPRINT("MmWriteToSwapPage\n"); - if (SwapEntry == 0) - { - KeBugCheck(MEMORY_MANAGEMENT); - return(STATUS_UNSUCCESSFUL); - } + if (SwapEntry == 0) + { + KeBugCheck(MEMORY_MANAGEMENT); + return(STATUS_UNSUCCESSFUL); + } - i = FILE_FROM_ENTRY(SwapEntry); - offset = OFFSET_FROM_ENTRY(SwapEntry); + i = FILE_FROM_ENTRY(SwapEntry); + offset = OFFSET_FROM_ENTRY(SwapEntry); - if (PagingFileList[i]->FileObject == NULL || - PagingFileList[i]->FileObject->DeviceObject == NULL) - { - DPRINT1("Bad paging file 0x%.8X\n", SwapEntry); - KeBugCheck(MEMORY_MANAGEMENT); - } + if (PagingFileList[i]->FileObject == NULL || + PagingFileList[i]->FileObject->DeviceObject == NULL) + { + DPRINT1("Bad paging file 0x%.8X\n", SwapEntry); + KeBugCheck(MEMORY_MANAGEMENT); + } - MmInitializeMdl(Mdl, NULL, PAGE_SIZE); - MmBuildMdlFromPages(Mdl, &Page); - Mdl->MdlFlags |= MDL_PAGES_LOCKED; + MmInitializeMdl(Mdl, NULL, PAGE_SIZE); + MmBuildMdlFromPages(Mdl, &Page); + Mdl->MdlFlags |= MDL_PAGES_LOCKED; - file_offset.QuadPart = offset * PAGE_SIZE; - file_offset = MmGetOffsetPageFile(PagingFileList[i]->RetrievalPointers, file_offset); + file_offset.QuadPart = offset * PAGE_SIZE; + file_offset = MmGetOffsetPageFile(PagingFileList[i]->RetrievalPointers, file_offset); - KeInitializeEvent(&Event, NotificationEvent, FALSE); - Status = IoSynchronousPageWrite(PagingFileList[i]->FileObject, - Mdl, - &file_offset, - &Event, - &Iosb); - if (Status == STATUS_PENDING) - { - KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); - Status = Iosb.Status; - } + KeInitializeEvent(&Event, NotificationEvent, FALSE); + Status = IoSynchronousPageWrite(PagingFileList[i]->FileObject, + Mdl, + &file_offset, + &Event, + &Iosb); + if (Status == STATUS_PENDING) + { + KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); + Status = Iosb.Status; + } - if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) - { - MmUnmapLockedPages (Mdl->MappedSystemVa, Mdl); - } - return(Status); + if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) + { + MmUnmapLockedPages (Mdl->MappedSystemVa, Mdl); + } + return(Status); } @@ -279,65 +279,65 @@ NTSTATUS NTAPI MmReadFromSwapPage(SWAPENTRY SwapEntry, PFN_NUMBER Page) { - return MiReadPageFile(Page, FILE_FROM_ENTRY(SwapEntry), OFFSET_FROM_ENTRY(SwapEntry)); + return MiReadPageFile(Page, FILE_FROM_ENTRY(SwapEntry), OFFSET_FROM_ENTRY(SwapEntry)); } NTSTATUS NTAPI MiReadPageFile( - _In_ PFN_NUMBER Page, - _In_ ULONG PageFileIndex, - _In_ ULONG_PTR PageFileOffset) + _In_ PFN_NUMBER Page, + _In_ ULONG PageFileIndex, + _In_ ULONG_PTR PageFileOffset) { - LARGE_INTEGER file_offset; - IO_STATUS_BLOCK Iosb; - NTSTATUS Status; - KEVENT Event; - UCHAR MdlBase[sizeof(MDL) + sizeof(ULONG)]; - PMDL Mdl = (PMDL)MdlBase; - PPAGINGFILE PagingFile; + LARGE_INTEGER file_offset; + IO_STATUS_BLOCK Iosb; + NTSTATUS Status; + KEVENT Event; + UCHAR MdlBase[sizeof(MDL) + sizeof(ULONG)]; + PMDL Mdl = (PMDL)MdlBase; + PPAGINGFILE PagingFile; - DPRINT("MiReadSwapFile\n"); + DPRINT("MiReadSwapFile\n"); - if (PageFileOffset == 0) - { - KeBugCheck(MEMORY_MANAGEMENT); - return(STATUS_UNSUCCESSFUL); - } + if (PageFileOffset == 0) + { + KeBugCheck(MEMORY_MANAGEMENT); + return(STATUS_UNSUCCESSFUL); + } - ASSERT(PageFileIndex < MAX_PAGING_FILES); + ASSERT(PageFileIndex < MAX_PAGING_FILES); - PagingFile = PagingFileList[PageFileIndex]; + PagingFile = PagingFileList[PageFileIndex]; - if (PagingFile->FileObject == NULL || PagingFile->FileObject->DeviceObject == NULL) - { - DPRINT1("Bad paging file %u\n", PageFileIndex); - KeBugCheck(MEMORY_MANAGEMENT); - } + if (PagingFile->FileObject == NULL || PagingFile->FileObject->DeviceObject == NULL) + { + DPRINT1("Bad paging file %u\n", PageFileIndex); + KeBugCheck(MEMORY_MANAGEMENT); + } - MmInitializeMdl(Mdl, NULL, PAGE_SIZE); - MmBuildMdlFromPages(Mdl, &Page); - Mdl->MdlFlags |= MDL_PAGES_LOCKED; + MmInitializeMdl(Mdl, NULL, PAGE_SIZE); + MmBuildMdlFromPages(Mdl, &Page); + Mdl->MdlFlags |= MDL_PAGES_LOCKED; - file_offset.QuadPart = PageFileOffset * PAGE_SIZE; - file_offset = MmGetOffsetPageFile(PagingFile->RetrievalPointers, file_offset); + file_offset.QuadPart = PageFileOffset * PAGE_SIZE; + file_offset = MmGetOffsetPageFile(PagingFile->RetrievalPointers, file_offset); - KeInitializeEvent(&Event, NotificationEvent, FALSE); - Status = IoPageRead(PagingFile->FileObject, - Mdl, - &file_offset, - &Event, - &Iosb); - if (Status == STATUS_PENDING) - { - KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); - Status = Iosb.Status; - } - if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) - { - MmUnmapLockedPages (Mdl->MappedSystemVa, Mdl); - } - return(Status); + KeInitializeEvent(&Event, NotificationEvent, FALSE); + Status = IoPageRead(PagingFile->FileObject, + Mdl, + &file_offset, + &Event, + &Iosb); + if (Status == STATUS_PENDING) + { + KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); + Status = Iosb.Status; + } + if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) + { + MmUnmapLockedPages (Mdl->MappedSystemVa, Mdl); + } + return(Status); } VOID @@ -345,135 +345,135 @@ INIT_FUNCTION NTAPI MmInitPagingFile(VOID) { - ULONG i; + ULONG i; - KeInitializeSpinLock(&PagingFileListLock); + KeInitializeSpinLock(&PagingFileListLock); - MiFreeSwapPages = 0; - MiUsedSwapPages = 0; - MiReservedSwapPages = 0; + MiFreeSwapPages = 0; + MiUsedSwapPages = 0; + MiReservedSwapPages = 0; - for (i = 0; i < MAX_PAGING_FILES; i++) - { - PagingFileList[i] = NULL; - } - MmNumberOfPagingFiles = 0; + for (i = 0; i < MAX_PAGING_FILES; i++) + { + PagingFileList[i] = NULL; + } + MmNumberOfPagingFiles = 0; } static ULONG MiAllocPageFromPagingFile(PPAGINGFILE PagingFile) { - KIRQL oldIrql; - ULONG i, j; + KIRQL oldIrql; + ULONG i, j; - KeAcquireSpinLock(&PagingFile->AllocMapLock, &oldIrql); + KeAcquireSpinLock(&PagingFile->AllocMapLock, &oldIrql); - for (i = 0; i < PagingFile->AllocMapSize; i++) - { - for (j = 0; j < 32; j++) - { - if (!(PagingFile->AllocMap[i] & (1 << j))) - { - PagingFile->AllocMap[i] |= (1 << j); - PagingFile->UsedPages++; - PagingFile->FreePages--; - KeReleaseSpinLock(&PagingFile->AllocMapLock, oldIrql); - return((i * 32) + j); - } - } - } + for (i = 0; i < PagingFile->AllocMapSize; i++) + { + for (j = 0; j < 32; j++) + { + if (!(PagingFile->AllocMap[i] & (1 << j))) + { + PagingFile->AllocMap[i] |= (1 << j); + PagingFile->UsedPages++; + PagingFile->FreePages--; + KeReleaseSpinLock(&PagingFile->AllocMapLock, oldIrql); + return((i * 32) + j); + } + } + } - KeReleaseSpinLock(&PagingFile->AllocMapLock, oldIrql); - return(0xFFFFFFFF); + KeReleaseSpinLock(&PagingFile->AllocMapLock, oldIrql); + return(0xFFFFFFFF); } VOID NTAPI MmFreeSwapPage(SWAPENTRY Entry) { - ULONG i; - ULONG_PTR off; - KIRQL oldIrql; + ULONG i; + ULONG_PTR off; + KIRQL oldIrql; - i = FILE_FROM_ENTRY(Entry); - off = OFFSET_FROM_ENTRY(Entry); + i = FILE_FROM_ENTRY(Entry); + off = OFFSET_FROM_ENTRY(Entry); - KeAcquireSpinLock(&PagingFileListLock, &oldIrql); - if (PagingFileList[i] == NULL) - { - KeBugCheck(MEMORY_MANAGEMENT); - } - KeAcquireSpinLockAtDpcLevel(&PagingFileList[i]->AllocMapLock); + KeAcquireSpinLock(&PagingFileListLock, &oldIrql); + if (PagingFileList[i] == NULL) + { + KeBugCheck(MEMORY_MANAGEMENT); + } + KeAcquireSpinLockAtDpcLevel(&PagingFileList[i]->AllocMapLock); - PagingFileList[i]->AllocMap[off >> 5] &= (~(1 << (off % 32))); + PagingFileList[i]->AllocMap[off >> 5] &= (~(1 << (off % 32))); - PagingFileList[i]->FreePages++; - PagingFileList[i]->UsedPages--; + PagingFileList[i]->FreePages++; + PagingFileList[i]->UsedPages--; - MiFreeSwapPages++; - MiUsedSwapPages--; + MiFreeSwapPages++; + MiUsedSwapPages--; - KeReleaseSpinLockFromDpcLevel(&PagingFileList[i]->AllocMapLock); - KeReleaseSpinLock(&PagingFileListLock, oldIrql); + KeReleaseSpinLockFromDpcLevel(&PagingFileList[i]->AllocMapLock); + KeReleaseSpinLock(&PagingFileListLock, oldIrql); } SWAPENTRY NTAPI MmAllocSwapPage(VOID) { - KIRQL oldIrql; - ULONG i; - ULONG off; - SWAPENTRY entry; + KIRQL oldIrql; + ULONG i; + ULONG off; + SWAPENTRY entry; - KeAcquireSpinLock(&PagingFileListLock, &oldIrql); + KeAcquireSpinLock(&PagingFileListLock, &oldIrql); - if (MiFreeSwapPages == 0) - { - KeReleaseSpinLock(&PagingFileListLock, oldIrql); - return(0); - } + if (MiFreeSwapPages == 0) + { + KeReleaseSpinLock(&PagingFileListLock, oldIrql); + return(0); + } - for (i = 0; i < MAX_PAGING_FILES; i++) - { - if (PagingFileList[i] != NULL && - PagingFileList[i]->FreePages >= 1) - { - off = MiAllocPageFromPagingFile(PagingFileList[i]); - if (off == 0xFFFFFFFF) - { - KeBugCheck(MEMORY_MANAGEMENT); + for (i = 0; i < MAX_PAGING_FILES; i++) + { + if (PagingFileList[i] != NULL && + PagingFileList[i]->FreePages >= 1) + { + off = MiAllocPageFromPagingFile(PagingFileList[i]); + if (off == 0xFFFFFFFF) + { + KeBugCheck(MEMORY_MANAGEMENT); + KeReleaseSpinLock(&PagingFileListLock, oldIrql); + return(STATUS_UNSUCCESSFUL); + } + MiUsedSwapPages++; + MiFreeSwapPages--; KeReleaseSpinLock(&PagingFileListLock, oldIrql); - return(STATUS_UNSUCCESSFUL); - } - MiUsedSwapPages++; - MiFreeSwapPages--; - KeReleaseSpinLock(&PagingFileListLock, oldIrql); - entry = ENTRY_FROM_FILE_OFFSET(i, off); - return(entry); - } - } + entry = ENTRY_FROM_FILE_OFFSET(i, off); + return(entry); + } + } - KeReleaseSpinLock(&PagingFileListLock, oldIrql); - KeBugCheck(MEMORY_MANAGEMENT); - return(0); + KeReleaseSpinLock(&PagingFileListLock, oldIrql); + KeBugCheck(MEMORY_MANAGEMENT); + return(0); } static PRETRIEVEL_DESCRIPTOR_LIST FASTCALL MmAllocRetrievelDescriptorList(ULONG Pairs) { - ULONG Size; - PRETRIEVEL_DESCRIPTOR_LIST RetDescList; + ULONG Size; + PRETRIEVEL_DESCRIPTOR_LIST RetDescList; - Size = sizeof(RETRIEVEL_DESCRIPTOR_LIST) + Pairs * 2 * sizeof(LARGE_INTEGER); - RetDescList = ExAllocatePool(NonPagedPool, Size); - if (RetDescList) - { - RtlZeroMemory(RetDescList, Size); - } + Size = sizeof(RETRIEVEL_DESCRIPTOR_LIST) + Pairs * 2 * sizeof(LARGE_INTEGER); + RetDescList = ExAllocatePool(NonPagedPool, Size); + if (RetDescList) + { + RtlZeroMemory(RetDescList, Size); + } - return RetDescList; + return RetDescList; } NTSTATUS NTAPI @@ -482,341 +482,341 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName, IN PLARGE_INTEGER MaximumSize, IN ULONG Reserved) { - NTSTATUS Status; - OBJECT_ATTRIBUTES ObjectAttributes; - HANDLE FileHandle; - IO_STATUS_BLOCK IoStatus; - PFILE_OBJECT FileObject; - PPAGINGFILE PagingFile; - KIRQL oldIrql; - ULONG AllocMapSize; - FILE_FS_SIZE_INFORMATION FsSizeInformation; - PRETRIEVEL_DESCRIPTOR_LIST RetDescList; - PRETRIEVEL_DESCRIPTOR_LIST CurrentRetDescList; - ULONG i; - ULONG BytesPerAllocationUnit; - LARGE_INTEGER Vcn; - ULONG ExtentCount; - LARGE_INTEGER MaxVcn; - ULONG Count; - ULONG Size; - KPROCESSOR_MODE PreviousMode; - UNICODE_STRING CapturedFileName; - LARGE_INTEGER SafeInitialSize, SafeMaximumSize; + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE FileHandle; + IO_STATUS_BLOCK IoStatus; + PFILE_OBJECT FileObject; + PPAGINGFILE PagingFile; + KIRQL oldIrql; + ULONG AllocMapSize; + FILE_FS_SIZE_INFORMATION FsSizeInformation; + PRETRIEVEL_DESCRIPTOR_LIST RetDescList; + PRETRIEVEL_DESCRIPTOR_LIST CurrentRetDescList; + ULONG i; + ULONG BytesPerAllocationUnit; + LARGE_INTEGER Vcn; + ULONG ExtentCount; + LARGE_INTEGER MaxVcn; + ULONG Count; + ULONG Size; + KPROCESSOR_MODE PreviousMode; + UNICODE_STRING CapturedFileName; + LARGE_INTEGER SafeInitialSize, SafeMaximumSize; - DPRINT("NtCreatePagingFile(FileName %wZ, InitialSize %I64d)\n", - FileName, InitialSize->QuadPart); + DPRINT("NtCreatePagingFile(FileName %wZ, InitialSize %I64d)\n", + FileName, InitialSize->QuadPart); - if (MmNumberOfPagingFiles >= MAX_PAGING_FILES) - { - return(STATUS_TOO_MANY_PAGING_FILES); - } + if (MmNumberOfPagingFiles >= MAX_PAGING_FILES) + { + return(STATUS_TOO_MANY_PAGING_FILES); + } - PreviousMode = ExGetPreviousMode(); + PreviousMode = ExGetPreviousMode(); - if (PreviousMode != KernelMode) - { - _SEH2_TRY - { - SafeInitialSize = ProbeForReadLargeInteger(InitialSize); - SafeMaximumSize = ProbeForReadLargeInteger(MaximumSize); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - /* Return the exception code */ - _SEH2_YIELD(return _SEH2_GetExceptionCode()); - } - _SEH2_END; - } - else - { - SafeInitialSize = *InitialSize; - SafeMaximumSize = *MaximumSize; - } + if (PreviousMode != KernelMode) + { + _SEH2_TRY + { + SafeInitialSize = ProbeForReadLargeInteger(InitialSize); + SafeMaximumSize = ProbeForReadLargeInteger(MaximumSize); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Return the exception code */ + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + } + else + { + SafeInitialSize = *InitialSize; + SafeMaximumSize = *MaximumSize; + } - /* Pagefiles can't be larger than 4GB and ofcourse the minimum should be - smaller than the maximum */ - if (0 != SafeInitialSize.u.HighPart) - { - return STATUS_INVALID_PARAMETER_2; - } - if (0 != SafeMaximumSize.u.HighPart) - { - return STATUS_INVALID_PARAMETER_3; - } - if (SafeMaximumSize.u.LowPart < SafeInitialSize.u.LowPart) - { - return STATUS_INVALID_PARAMETER_MIX; - } + /* Pagefiles can't be larger than 4GB and ofcourse the minimum should be + smaller than the maximum */ + if (0 != SafeInitialSize.u.HighPart) + { + return STATUS_INVALID_PARAMETER_2; + } + if (0 != SafeMaximumSize.u.HighPart) + { + return STATUS_INVALID_PARAMETER_3; + } + if (SafeMaximumSize.u.LowPart < SafeInitialSize.u.LowPart) + { + return STATUS_INVALID_PARAMETER_MIX; + } - Status = ProbeAndCaptureUnicodeString(&CapturedFileName, - PreviousMode, - FileName); - if (!NT_SUCCESS(Status)) - { - return(Status); - } + Status = ProbeAndCaptureUnicodeString(&CapturedFileName, + PreviousMode, + FileName); + if (!NT_SUCCESS(Status)) + { + return(Status); + } - InitializeObjectAttributes(&ObjectAttributes, - &CapturedFileName, - 0, - NULL, - NULL); - - Status = IoCreateFile(&FileHandle, - FILE_ALL_ACCESS, - &ObjectAttributes, - &IoStatus, - NULL, - 0, - 0, - FILE_OPEN_IF, - FILE_SYNCHRONOUS_IO_NONALERT, - NULL, - 0, - CreateFileTypeNone, - NULL, - SL_OPEN_PAGING_FILE | IO_NO_PARAMETER_CHECKING); - - ReleaseCapturedUnicodeString(&CapturedFileName, - PreviousMode); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - - Status = ZwQueryVolumeInformationFile(FileHandle, - &IoStatus, - &FsSizeInformation, - sizeof(FILE_FS_SIZE_INFORMATION), - FileFsSizeInformation); - if (!NT_SUCCESS(Status)) - { - ZwClose(FileHandle); - return Status; - } - - BytesPerAllocationUnit = FsSizeInformation.SectorsPerAllocationUnit * - FsSizeInformation.BytesPerSector; - /* FIXME: If we have 2048 BytesPerAllocationUnit (FAT16 < 128MB) there is - * a problem if the paging file is fragmented. Suppose the first cluster - * of the paging file is cluster 3042 but cluster 3043 is NOT part of the - * paging file but of another file. We can't write a complete page (4096 - * bytes) to the physical location of cluster 3042 then. */ - if (BytesPerAllocationUnit % PAGE_SIZE) - { - DPRINT1("BytesPerAllocationUnit %lu is not a multiple of PAGE_SIZE %d\n", - BytesPerAllocationUnit, PAGE_SIZE); - ZwClose(FileHandle); - return STATUS_UNSUCCESSFUL; - } - - Status = ZwSetInformationFile(FileHandle, - &IoStatus, - &SafeInitialSize, - sizeof(LARGE_INTEGER), - FileAllocationInformation); - if (!NT_SUCCESS(Status)) - { - ZwClose(FileHandle); - return(Status); - } - - Status = ObReferenceObjectByHandle(FileHandle, - FILE_ALL_ACCESS, - IoFileObjectType, - PreviousMode, - (PVOID*)&FileObject, - NULL); - if (!NT_SUCCESS(Status)) - { - ZwClose(FileHandle); - return(Status); - } - - CurrentRetDescList = RetDescList = MmAllocRetrievelDescriptorList(PAIRS_PER_RUN); - - if (CurrentRetDescList == NULL) - { - ObDereferenceObject(FileObject); - ZwClose(FileHandle); - return(STATUS_NO_MEMORY); - } - -#if defined(__GNUC__) - Vcn.QuadPart = 0LL; -#else - - Vcn.QuadPart = 0; -#endif - - ExtentCount = 0; - MaxVcn.QuadPart = (SafeInitialSize.QuadPart + BytesPerAllocationUnit - 1) / BytesPerAllocationUnit; - while(1) - { - Status = ZwFsControlFile(FileHandle, + InitializeObjectAttributes(&ObjectAttributes, + &CapturedFileName, 0, NULL, - NULL, - &IoStatus, - FSCTL_GET_RETRIEVAL_POINTERS, - &Vcn, - sizeof(LARGE_INTEGER), - &CurrentRetDescList->RetrievalPointers, - sizeof(RETRIEVAL_POINTERS_BUFFER) + PAIRS_PER_RUN * 2 * sizeof(LARGE_INTEGER)); - if (!NT_SUCCESS(Status)) - { - while (RetDescList) - { - CurrentRetDescList = RetDescList; - RetDescList = RetDescList->Next; - ExFreePool(CurrentRetDescList); - } - ObDereferenceObject(FileObject); - ZwClose(FileHandle); - return(Status); - } - ExtentCount += CurrentRetDescList->RetrievalPointers.ExtentCount; - if (CurrentRetDescList->RetrievalPointers.Extents[CurrentRetDescList->RetrievalPointers.ExtentCount-1].NextVcn.QuadPart < MaxVcn.QuadPart) - { - CurrentRetDescList->Next = MmAllocRetrievelDescriptorList(PAIRS_PER_RUN); - if (CurrentRetDescList->Next == NULL) - { + NULL); + + Status = IoCreateFile(&FileHandle, + FILE_ALL_ACCESS, + &ObjectAttributes, + &IoStatus, + NULL, + 0, + 0, + FILE_OPEN_IF, + FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0, + CreateFileTypeNone, + NULL, + SL_OPEN_PAGING_FILE | IO_NO_PARAMETER_CHECKING); + + ReleaseCapturedUnicodeString(&CapturedFileName, + PreviousMode); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + + Status = ZwQueryVolumeInformationFile(FileHandle, + &IoStatus, + &FsSizeInformation, + sizeof(FILE_FS_SIZE_INFORMATION), + FileFsSizeInformation); + if (!NT_SUCCESS(Status)) + { + ZwClose(FileHandle); + return Status; + } + + BytesPerAllocationUnit = FsSizeInformation.SectorsPerAllocationUnit * + FsSizeInformation.BytesPerSector; + /* FIXME: If we have 2048 BytesPerAllocationUnit (FAT16 < 128MB) there is + * a problem if the paging file is fragmented. Suppose the first cluster + * of the paging file is cluster 3042 but cluster 3043 is NOT part of the + * paging file but of another file. We can't write a complete page (4096 + * bytes) to the physical location of cluster 3042 then. */ + if (BytesPerAllocationUnit % PAGE_SIZE) + { + DPRINT1("BytesPerAllocationUnit %lu is not a multiple of PAGE_SIZE %d\n", + BytesPerAllocationUnit, PAGE_SIZE); + ZwClose(FileHandle); + return STATUS_UNSUCCESSFUL; + } + + Status = ZwSetInformationFile(FileHandle, + &IoStatus, + &SafeInitialSize, + sizeof(LARGE_INTEGER), + FileAllocationInformation); + if (!NT_SUCCESS(Status)) + { + ZwClose(FileHandle); + return(Status); + } + + Status = ObReferenceObjectByHandle(FileHandle, + FILE_ALL_ACCESS, + IoFileObjectType, + PreviousMode, + (PVOID*)&FileObject, + NULL); + if (!NT_SUCCESS(Status)) + { + ZwClose(FileHandle); + return(Status); + } + + CurrentRetDescList = RetDescList = MmAllocRetrievelDescriptorList(PAIRS_PER_RUN); + + if (CurrentRetDescList == NULL) + { + ObDereferenceObject(FileObject); + ZwClose(FileHandle); + return(STATUS_NO_MEMORY); + } + +#if defined(__GNUC__) + Vcn.QuadPart = 0LL; +#else + + Vcn.QuadPart = 0; +#endif + + ExtentCount = 0; + MaxVcn.QuadPart = (SafeInitialSize.QuadPart + BytesPerAllocationUnit - 1) / BytesPerAllocationUnit; + while(1) + { + Status = ZwFsControlFile(FileHandle, + 0, + NULL, + NULL, + &IoStatus, + FSCTL_GET_RETRIEVAL_POINTERS, + &Vcn, + sizeof(LARGE_INTEGER), + &CurrentRetDescList->RetrievalPointers, + sizeof(RETRIEVAL_POINTERS_BUFFER) + PAIRS_PER_RUN * 2 * sizeof(LARGE_INTEGER)); + if (!NT_SUCCESS(Status)) + { while (RetDescList) { - CurrentRetDescList = RetDescList; - RetDescList = RetDescList->Next; - ExFreePool(CurrentRetDescList); + CurrentRetDescList = RetDescList; + RetDescList = RetDescList->Next; + ExFreePool(CurrentRetDescList); } ObDereferenceObject(FileObject); ZwClose(FileHandle); - return(STATUS_NO_MEMORY); - } - Vcn = CurrentRetDescList->RetrievalPointers.Extents[CurrentRetDescList->RetrievalPointers.ExtentCount-1].NextVcn; - CurrentRetDescList = CurrentRetDescList->Next; - } - else - { - break; - } - } + return(Status); + } + ExtentCount += CurrentRetDescList->RetrievalPointers.ExtentCount; + if (CurrentRetDescList->RetrievalPointers.Extents[CurrentRetDescList->RetrievalPointers.ExtentCount-1].NextVcn.QuadPart < MaxVcn.QuadPart) + { + CurrentRetDescList->Next = MmAllocRetrievelDescriptorList(PAIRS_PER_RUN); + if (CurrentRetDescList->Next == NULL) + { + while (RetDescList) + { + CurrentRetDescList = RetDescList; + RetDescList = RetDescList->Next; + ExFreePool(CurrentRetDescList); + } + ObDereferenceObject(FileObject); + ZwClose(FileHandle); + return(STATUS_NO_MEMORY); + } + Vcn = CurrentRetDescList->RetrievalPointers.Extents[CurrentRetDescList->RetrievalPointers.ExtentCount-1].NextVcn; + CurrentRetDescList = CurrentRetDescList->Next; + } + else + { + break; + } + } - PagingFile = ExAllocatePool(NonPagedPool, sizeof(*PagingFile)); - if (PagingFile == NULL) - { - while (RetDescList) - { - CurrentRetDescList = RetDescList; - RetDescList = RetDescList->Next; - ExFreePool(CurrentRetDescList); - } - ObDereferenceObject(FileObject); - ZwClose(FileHandle); - return(STATUS_NO_MEMORY); - } + PagingFile = ExAllocatePool(NonPagedPool, sizeof(*PagingFile)); + if (PagingFile == NULL) + { + while (RetDescList) + { + CurrentRetDescList = RetDescList; + RetDescList = RetDescList->Next; + ExFreePool(CurrentRetDescList); + } + ObDereferenceObject(FileObject); + ZwClose(FileHandle); + return(STATUS_NO_MEMORY); + } - RtlZeroMemory(PagingFile, sizeof(*PagingFile)); + RtlZeroMemory(PagingFile, sizeof(*PagingFile)); - PagingFile->FileObject = FileObject; - PagingFile->MaximumSize.QuadPart = SafeMaximumSize.QuadPart; - PagingFile->CurrentSize.QuadPart = SafeInitialSize.QuadPart; - PagingFile->FreePages = (ULONG)(SafeInitialSize.QuadPart / PAGE_SIZE); - PagingFile->UsedPages = 0; - KeInitializeSpinLock(&PagingFile->AllocMapLock); + PagingFile->FileObject = FileObject; + PagingFile->MaximumSize.QuadPart = SafeMaximumSize.QuadPart; + PagingFile->CurrentSize.QuadPart = SafeInitialSize.QuadPart; + PagingFile->FreePages = (ULONG)(SafeInitialSize.QuadPart / PAGE_SIZE); + PagingFile->UsedPages = 0; + KeInitializeSpinLock(&PagingFile->AllocMapLock); - AllocMapSize = (PagingFile->FreePages / 32) + 1; - PagingFile->AllocMap = ExAllocatePool(NonPagedPool, - AllocMapSize * sizeof(ULONG)); - PagingFile->AllocMapSize = AllocMapSize; + AllocMapSize = (PagingFile->FreePages / 32) + 1; + PagingFile->AllocMap = ExAllocatePool(NonPagedPool, + AllocMapSize * sizeof(ULONG)); + PagingFile->AllocMapSize = AllocMapSize; - if (PagingFile->AllocMap == NULL) - { - while (RetDescList) - { - CurrentRetDescList = RetDescList; - RetDescList = RetDescList->Next; - ExFreePool(CurrentRetDescList); - } - ExFreePool(PagingFile); - ObDereferenceObject(FileObject); - ZwClose(FileHandle); - return(STATUS_NO_MEMORY); - } - DPRINT("ExtentCount: %lu\n", ExtentCount); - Size = sizeof(RETRIEVAL_POINTERS_BUFFER) + ExtentCount * 2 * sizeof(LARGE_INTEGER); - PagingFile->RetrievalPointers = ExAllocatePool(NonPagedPool, Size); - if (PagingFile->RetrievalPointers == NULL) - { - while (RetDescList) - { - CurrentRetDescList = RetDescList; - RetDescList = RetDescList->Next; - ExFreePool(CurrentRetDescList); - } - ExFreePool(PagingFile->AllocMap); - ExFreePool(PagingFile); - ObDereferenceObject(FileObject); - ZwClose(FileHandle); - return(STATUS_NO_MEMORY); - } + if (PagingFile->AllocMap == NULL) + { + while (RetDescList) + { + CurrentRetDescList = RetDescList; + RetDescList = RetDescList->Next; + ExFreePool(CurrentRetDescList); + } + ExFreePool(PagingFile); + ObDereferenceObject(FileObject); + ZwClose(FileHandle); + return(STATUS_NO_MEMORY); + } + DPRINT("ExtentCount: %lu\n", ExtentCount); + Size = sizeof(RETRIEVAL_POINTERS_BUFFER) + ExtentCount * 2 * sizeof(LARGE_INTEGER); + PagingFile->RetrievalPointers = ExAllocatePool(NonPagedPool, Size); + if (PagingFile->RetrievalPointers == NULL) + { + while (RetDescList) + { + CurrentRetDescList = RetDescList; + RetDescList = RetDescList->Next; + ExFreePool(CurrentRetDescList); + } + ExFreePool(PagingFile->AllocMap); + ExFreePool(PagingFile); + ObDereferenceObject(FileObject); + ZwClose(FileHandle); + return(STATUS_NO_MEMORY); + } - RtlZeroMemory(PagingFile->AllocMap, AllocMapSize * sizeof(ULONG)); - RtlZeroMemory(PagingFile->RetrievalPointers, Size); + RtlZeroMemory(PagingFile->AllocMap, AllocMapSize * sizeof(ULONG)); + RtlZeroMemory(PagingFile->RetrievalPointers, Size); - Count = 0; - PagingFile->RetrievalPointers->ExtentCount = ExtentCount; - PagingFile->RetrievalPointers->StartingVcn = RetDescList->RetrievalPointers.StartingVcn; - CurrentRetDescList = RetDescList; - while (CurrentRetDescList) - { - memcpy(&PagingFile->RetrievalPointers->Extents[Count], - CurrentRetDescList->RetrievalPointers.Extents, - CurrentRetDescList->RetrievalPointers.ExtentCount * 2 * sizeof(LARGE_INTEGER)); - Count += CurrentRetDescList->RetrievalPointers.ExtentCount; - RetDescList = CurrentRetDescList; - CurrentRetDescList = CurrentRetDescList->Next; - ExFreePool(RetDescList); - } + Count = 0; + PagingFile->RetrievalPointers->ExtentCount = ExtentCount; + PagingFile->RetrievalPointers->StartingVcn = RetDescList->RetrievalPointers.StartingVcn; + CurrentRetDescList = RetDescList; + while (CurrentRetDescList) + { + memcpy(&PagingFile->RetrievalPointers->Extents[Count], + CurrentRetDescList->RetrievalPointers.Extents, + CurrentRetDescList->RetrievalPointers.ExtentCount * 2 * sizeof(LARGE_INTEGER)); + Count += CurrentRetDescList->RetrievalPointers.ExtentCount; + RetDescList = CurrentRetDescList; + CurrentRetDescList = CurrentRetDescList->Next; + ExFreePool(RetDescList); + } - if (PagingFile->RetrievalPointers->ExtentCount != ExtentCount || - PagingFile->RetrievalPointers->Extents[ExtentCount - 1].NextVcn.QuadPart != MaxVcn.QuadPart) - { - ExFreePool(PagingFile->RetrievalPointers); - ExFreePool(PagingFile->AllocMap); - ExFreePool(PagingFile); - ObDereferenceObject(FileObject); - ZwClose(FileHandle); - return(STATUS_UNSUCCESSFUL); - } + if (PagingFile->RetrievalPointers->ExtentCount != ExtentCount || + PagingFile->RetrievalPointers->Extents[ExtentCount - 1].NextVcn.QuadPart != MaxVcn.QuadPart) + { + ExFreePool(PagingFile->RetrievalPointers); + ExFreePool(PagingFile->AllocMap); + ExFreePool(PagingFile); + ObDereferenceObject(FileObject); + ZwClose(FileHandle); + return(STATUS_UNSUCCESSFUL); + } - /* - * Change the entries from lcn's to volume offset's. - */ - PagingFile->RetrievalPointers->StartingVcn.QuadPart *= BytesPerAllocationUnit; - for (i = 0; i < ExtentCount; i++) - { - PagingFile->RetrievalPointers->Extents[i].Lcn.QuadPart *= BytesPerAllocationUnit; - PagingFile->RetrievalPointers->Extents[i].NextVcn.QuadPart *= BytesPerAllocationUnit; - } + /* + * Change the entries from lcn's to volume offset's. + */ + PagingFile->RetrievalPointers->StartingVcn.QuadPart *= BytesPerAllocationUnit; + for (i = 0; i < ExtentCount; i++) + { + PagingFile->RetrievalPointers->Extents[i].Lcn.QuadPart *= BytesPerAllocationUnit; + PagingFile->RetrievalPointers->Extents[i].NextVcn.QuadPart *= BytesPerAllocationUnit; + } - KeAcquireSpinLock(&PagingFileListLock, &oldIrql); - for (i = 0; i < MAX_PAGING_FILES; i++) - { - if (PagingFileList[i] == NULL) - { - PagingFileList[i] = PagingFile; - break; - } - } - MiFreeSwapPages = MiFreeSwapPages + PagingFile->FreePages; - MmNumberOfPagingFiles++; - KeReleaseSpinLock(&PagingFileListLock, oldIrql); + KeAcquireSpinLock(&PagingFileListLock, &oldIrql); + for (i = 0; i < MAX_PAGING_FILES; i++) + { + if (PagingFileList[i] == NULL) + { + PagingFileList[i] = PagingFile; + break; + } + } + MiFreeSwapPages = MiFreeSwapPages + PagingFile->FreePages; + MmNumberOfPagingFiles++; + KeReleaseSpinLock(&PagingFileListLock, oldIrql); - ZwClose(FileHandle); + ZwClose(FileHandle); - MmSwapSpaceMessage = FALSE; + MmSwapSpaceMessage = FALSE; - return(STATUS_SUCCESS); + return(STATUS_SUCCESS); } /* EOF */ diff --git a/reactos/ntoskrnl/mm/region.c b/reactos/ntoskrnl/mm/region.c index eb71540fa16..d62fcb4791e 100644 --- a/reactos/ntoskrnl/mm/region.c +++ b/reactos/ntoskrnl/mm/region.c @@ -22,12 +22,12 @@ InsertAfterEntry(PLIST_ENTRY Previous, * FUNCTION: Insert a list entry after another entry in the list */ { - Previous->Flink->Blink = Entry; + Previous->Flink->Blink = Entry; - Entry->Flink = Previous->Flink; - Entry->Blink = Previous; + Entry->Flink = Previous->Flink; + Entry->Blink = Previous; - Previous->Flink = Entry; + Previous->Flink = Entry; } static PMM_REGION @@ -36,71 +36,71 @@ MmSplitRegion(PMM_REGION InitialRegion, PVOID InitialBaseAddress, ULONG NewProtect, PMMSUPPORT AddressSpace, PMM_ALTER_REGION_FUNC AlterFunc) { - PMM_REGION NewRegion1; - PMM_REGION NewRegion2; - SIZE_T InternalLength; + PMM_REGION NewRegion1; + PMM_REGION NewRegion2; + SIZE_T InternalLength; - /* Allocate this in front otherwise the failure case is too difficult. */ - NewRegion2 = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION), - TAG_MM_REGION); - if (NewRegion2 == NULL) - { - return(NULL); - } + /* Allocate this in front otherwise the failure case is too difficult. */ + NewRegion2 = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION), + TAG_MM_REGION); + if (NewRegion2 == NULL) + { + return(NULL); + } - /* Create the new region. */ - NewRegion1 = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION), - TAG_MM_REGION); - if (NewRegion1 == NULL) - { - ExFreePoolWithTag(NewRegion2, TAG_MM_REGION); - return(NULL); - } - NewRegion1->Type = NewType; - NewRegion1->Protect = NewProtect; - InternalLength = ((char*)InitialBaseAddress + InitialRegion->Length) - (char*)StartAddress; - InternalLength = min(InternalLength, Length); - NewRegion1->Length = InternalLength; - InsertAfterEntry(&InitialRegion->RegionListEntry, - &NewRegion1->RegionListEntry); + /* Create the new region. */ + NewRegion1 = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION), + TAG_MM_REGION); + if (NewRegion1 == NULL) + { + ExFreePoolWithTag(NewRegion2, TAG_MM_REGION); + return(NULL); + } + NewRegion1->Type = NewType; + NewRegion1->Protect = NewProtect; + InternalLength = ((char*)InitialBaseAddress + InitialRegion->Length) - (char*)StartAddress; + InternalLength = min(InternalLength, Length); + NewRegion1->Length = InternalLength; + InsertAfterEntry(&InitialRegion->RegionListEntry, + &NewRegion1->RegionListEntry); - /* - * Call our helper function to do the changes on the addresses contained - * in the initial region. - */ - AlterFunc(AddressSpace, StartAddress, InternalLength, InitialRegion->Type, - InitialRegion->Protect, NewType, NewProtect); + /* + * Call our helper function to do the changes on the addresses contained + * in the initial region. + */ + AlterFunc(AddressSpace, StartAddress, InternalLength, InitialRegion->Type, + InitialRegion->Protect, NewType, NewProtect); - /* - * If necessary create a new region for the portion of the initial region - * beyond the range of addresses to alter. - */ - if (((char*)InitialBaseAddress + InitialRegion->Length) > ((char*)StartAddress + Length)) - { - NewRegion2->Type = InitialRegion->Type; - NewRegion2->Protect = InitialRegion->Protect; - NewRegion2->Length = ((char*)InitialBaseAddress + InitialRegion->Length) - - ((char*)StartAddress + Length); - InsertAfterEntry(&NewRegion1->RegionListEntry, - &NewRegion2->RegionListEntry); - } - else - { - ExFreePoolWithTag(NewRegion2, TAG_MM_REGION); - } + /* + * If necessary create a new region for the portion of the initial region + * beyond the range of addresses to alter. + */ + if (((char*)InitialBaseAddress + InitialRegion->Length) > ((char*)StartAddress + Length)) + { + NewRegion2->Type = InitialRegion->Type; + NewRegion2->Protect = InitialRegion->Protect; + NewRegion2->Length = ((char*)InitialBaseAddress + InitialRegion->Length) - + ((char*)StartAddress + Length); + InsertAfterEntry(&NewRegion1->RegionListEntry, + &NewRegion2->RegionListEntry); + } + else + { + ExFreePoolWithTag(NewRegion2, TAG_MM_REGION); + } - /* Either remove or shrink the initial region. */ - if (InitialBaseAddress == StartAddress) - { - RemoveEntryList(&InitialRegion->RegionListEntry); - ExFreePoolWithTag(InitialRegion, TAG_MM_REGION); - } - else - { - InitialRegion->Length = (char*)StartAddress - (char*)InitialBaseAddress; - } + /* Either remove or shrink the initial region. */ + if (InitialBaseAddress == StartAddress) + { + RemoveEntryList(&InitialRegion->RegionListEntry); + ExFreePoolWithTag(InitialRegion, TAG_MM_REGION); + } + else + { + InitialRegion->Length = (char*)StartAddress - (char*)InitialBaseAddress; + } - return(NewRegion1); + return(NewRegion1); } NTSTATUS @@ -109,129 +109,129 @@ MmAlterRegion(PMMSUPPORT AddressSpace, PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID StartAddress, SIZE_T Length, ULONG NewType, ULONG NewProtect, PMM_ALTER_REGION_FUNC AlterFunc) { - PMM_REGION InitialRegion; - PVOID InitialBaseAddress = NULL; - PMM_REGION NewRegion; - PLIST_ENTRY CurrentEntry; - PMM_REGION CurrentRegion = NULL; - PVOID CurrentBaseAddress; - SIZE_T RemainingLength; + PMM_REGION InitialRegion; + PVOID InitialBaseAddress = NULL; + PMM_REGION NewRegion; + PLIST_ENTRY CurrentEntry; + PMM_REGION CurrentRegion = NULL; + PVOID CurrentBaseAddress; + SIZE_T RemainingLength; - /* - * Find the first region containing part of the range of addresses to - * be altered. - */ - InitialRegion = MmFindRegion(BaseAddress, RegionListHead, StartAddress, - &InitialBaseAddress); - /* - * If necessary then split the region into the affected and unaffected parts. - */ - if (InitialRegion->Type != NewType || InitialRegion->Protect != NewProtect) - { - NewRegion = MmSplitRegion(InitialRegion, InitialBaseAddress, - StartAddress, Length, NewType, NewProtect, - AddressSpace, AlterFunc); - if (NewRegion == NULL) - { - return(STATUS_NO_MEMORY); - } - if(NewRegion->Length < Length) - RemainingLength = Length - NewRegion->Length; - else - RemainingLength = 0; - } - else - { - NewRegion = InitialRegion; - if(((ULONG_PTR)InitialBaseAddress + NewRegion->Length) < - ((ULONG_PTR)StartAddress + Length)) - RemainingLength = ((ULONG_PTR)StartAddress + Length) - ((ULONG_PTR)InitialBaseAddress + NewRegion->Length); - else - RemainingLength = 0; - } + /* + * Find the first region containing part of the range of addresses to + * be altered. + */ + InitialRegion = MmFindRegion(BaseAddress, RegionListHead, StartAddress, + &InitialBaseAddress); + /* + * If necessary then split the region into the affected and unaffected parts. + */ + if (InitialRegion->Type != NewType || InitialRegion->Protect != NewProtect) + { + NewRegion = MmSplitRegion(InitialRegion, InitialBaseAddress, + StartAddress, Length, NewType, NewProtect, + AddressSpace, AlterFunc); + if (NewRegion == NULL) + { + return(STATUS_NO_MEMORY); + } + if(NewRegion->Length < Length) + RemainingLength = Length - NewRegion->Length; + else + RemainingLength = 0; + } + else + { + NewRegion = InitialRegion; + if(((ULONG_PTR)InitialBaseAddress + NewRegion->Length) < + ((ULONG_PTR)StartAddress + Length)) + RemainingLength = ((ULONG_PTR)StartAddress + Length) - ((ULONG_PTR)InitialBaseAddress + NewRegion->Length); + else + RemainingLength = 0; + } - /* - * Free any complete regions that are containing in the range of addresses - * and call the helper function to actually do the changes. - */ - CurrentEntry = NewRegion->RegionListEntry.Flink; - CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, - RegionListEntry); - CurrentBaseAddress = (char*)StartAddress + NewRegion->Length; - while (RemainingLength > 0 && CurrentRegion->Length <= RemainingLength && - CurrentEntry != RegionListHead) - { - if (CurrentRegion->Type != NewType || - CurrentRegion->Protect != NewProtect) - { - AlterFunc(AddressSpace, CurrentBaseAddress, CurrentRegion->Length, - CurrentRegion->Type, CurrentRegion->Protect, - NewType, NewProtect); - } + /* + * Free any complete regions that are containing in the range of addresses + * and call the helper function to actually do the changes. + */ + CurrentEntry = NewRegion->RegionListEntry.Flink; + CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, + RegionListEntry); + CurrentBaseAddress = (char*)StartAddress + NewRegion->Length; + while (RemainingLength > 0 && CurrentRegion->Length <= RemainingLength && + CurrentEntry != RegionListHead) + { + if (CurrentRegion->Type != NewType || + CurrentRegion->Protect != NewProtect) + { + AlterFunc(AddressSpace, CurrentBaseAddress, CurrentRegion->Length, + CurrentRegion->Type, CurrentRegion->Protect, + NewType, NewProtect); + } - CurrentBaseAddress = (PVOID)((ULONG_PTR)CurrentBaseAddress + CurrentRegion->Length); - NewRegion->Length += CurrentRegion->Length; - RemainingLength -= CurrentRegion->Length; - CurrentEntry = CurrentEntry->Flink; - RemoveEntryList(&CurrentRegion->RegionListEntry); - ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION); - CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, - RegionListEntry); - } + CurrentBaseAddress = (PVOID)((ULONG_PTR)CurrentBaseAddress + CurrentRegion->Length); + NewRegion->Length += CurrentRegion->Length; + RemainingLength -= CurrentRegion->Length; + CurrentEntry = CurrentEntry->Flink; + RemoveEntryList(&CurrentRegion->RegionListEntry); + ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION); + CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, + RegionListEntry); + } - /* - * Split any final region. - */ - if (RemainingLength > 0 && CurrentEntry != RegionListHead) - { - CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, - RegionListEntry); - if (CurrentRegion->Type != NewType || - CurrentRegion->Protect != NewProtect) - { - AlterFunc(AddressSpace, CurrentBaseAddress, RemainingLength, - CurrentRegion->Type, CurrentRegion->Protect, - NewType, NewProtect); - } - NewRegion->Length += RemainingLength; - CurrentRegion->Length -= RemainingLength; - } + /* + * Split any final region. + */ + if (RemainingLength > 0 && CurrentEntry != RegionListHead) + { + CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, + RegionListEntry); + if (CurrentRegion->Type != NewType || + CurrentRegion->Protect != NewProtect) + { + AlterFunc(AddressSpace, CurrentBaseAddress, RemainingLength, + CurrentRegion->Type, CurrentRegion->Protect, + NewType, NewProtect); + } + NewRegion->Length += RemainingLength; + CurrentRegion->Length -= RemainingLength; + } - /* - * If the region after the new region has the same type then merge them. - */ - if (NewRegion->RegionListEntry.Flink != RegionListHead) - { - CurrentEntry = NewRegion->RegionListEntry.Flink; - CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, - RegionListEntry); - if (CurrentRegion->Type == NewRegion->Type && - CurrentRegion->Protect == NewRegion->Protect) - { - NewRegion->Length += CurrentRegion->Length; - RemoveEntryList(&CurrentRegion->RegionListEntry); - ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION); - } - } + /* + * If the region after the new region has the same type then merge them. + */ + if (NewRegion->RegionListEntry.Flink != RegionListHead) + { + CurrentEntry = NewRegion->RegionListEntry.Flink; + CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, + RegionListEntry); + if (CurrentRegion->Type == NewRegion->Type && + CurrentRegion->Protect == NewRegion->Protect) + { + NewRegion->Length += CurrentRegion->Length; + RemoveEntryList(&CurrentRegion->RegionListEntry); + ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION); + } + } - /* - * If the region before the new region has the same type then merge them. - */ - if (NewRegion->RegionListEntry.Blink != RegionListHead) - { - CurrentEntry = NewRegion->RegionListEntry.Blink; - CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, - RegionListEntry); - if (CurrentRegion->Type == NewRegion->Type && - CurrentRegion->Protect == NewRegion->Protect) - { - NewRegion->Length += CurrentRegion->Length; - RemoveEntryList(&CurrentRegion->RegionListEntry); - ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION); - } - } + /* + * If the region before the new region has the same type then merge them. + */ + if (NewRegion->RegionListEntry.Blink != RegionListHead) + { + CurrentEntry = NewRegion->RegionListEntry.Blink; + CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, + RegionListEntry); + if (CurrentRegion->Type == NewRegion->Type && + CurrentRegion->Protect == NewRegion->Protect) + { + NewRegion->Length += CurrentRegion->Length; + RemoveEntryList(&CurrentRegion->RegionListEntry); + ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION); + } + } - return(STATUS_SUCCESS); + return(STATUS_SUCCESS); } VOID @@ -239,17 +239,17 @@ NTAPI MmInitializeRegion(PLIST_ENTRY RegionListHead, SIZE_T Length, ULONG Type, ULONG Protect) { - PMM_REGION Region; + PMM_REGION Region; - Region = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION), - TAG_MM_REGION); - if (!Region) return; + Region = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION), + TAG_MM_REGION); + if (!Region) return; - Region->Type = Type; - Region->Protect = Protect; - Region->Length = Length; - InitializeListHead(RegionListHead); - InsertHeadList(RegionListHead, &Region->RegionListEntry); + Region->Type = Type; + Region->Protect = Protect; + Region->Length = Length; + InitializeListHead(RegionListHead); + InsertHeadList(RegionListHead, &Region->RegionListEntry); } PMM_REGION @@ -257,29 +257,29 @@ NTAPI MmFindRegion(PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID Address, PVOID* RegionBaseAddress) { - PLIST_ENTRY current_entry; - PMM_REGION current; - PVOID StartAddress = BaseAddress; + PLIST_ENTRY current_entry; + PMM_REGION current; + PVOID StartAddress = BaseAddress; - current_entry = RegionListHead->Flink; - while (current_entry != RegionListHead) - { - current = CONTAINING_RECORD(current_entry, MM_REGION, RegionListEntry); + current_entry = RegionListHead->Flink; + while (current_entry != RegionListHead) + { + current = CONTAINING_RECORD(current_entry, MM_REGION, RegionListEntry); - if (StartAddress <= Address && - ((char*)StartAddress + current->Length) > (char*)Address) - { - if (RegionBaseAddress != NULL) - { - *RegionBaseAddress = StartAddress; - } - return(current); - } + if (StartAddress <= Address && + ((char*)StartAddress + current->Length) > (char*)Address) + { + if (RegionBaseAddress != NULL) + { + *RegionBaseAddress = StartAddress; + } + return(current); + } - current_entry = current_entry->Flink; + current_entry = current_entry->Flink; - StartAddress = (PVOID)((ULONG_PTR)StartAddress + current->Length); + StartAddress = (PVOID)((ULONG_PTR)StartAddress + current->Length); - } - return(NULL); + } + return(NULL); } diff --git a/reactos/ntoskrnl/mm/rmap.c b/reactos/ntoskrnl/mm/rmap.c index d177f3c04cd..b5034d8d05a 100644 --- a/reactos/ntoskrnl/mm/rmap.c +++ b/reactos/ntoskrnl/mm/rmap.c @@ -42,224 +42,224 @@ INIT_FUNCTION NTAPI MmInitializeRmapList(VOID) { - ExInitializeFastMutex(&RmapListLock); - ExInitializeNPagedLookasideList (&RmapLookasideList, - NULL, - RmapListFree, - 0, - sizeof(MM_RMAP_ENTRY), - TAG_RMAP, - 50); + ExInitializeFastMutex(&RmapListLock); + ExInitializeNPagedLookasideList (&RmapLookasideList, + NULL, + RmapListFree, + 0, + sizeof(MM_RMAP_ENTRY), + TAG_RMAP, + 50); } NTSTATUS NTAPI MmPageOutPhysicalAddress(PFN_NUMBER Page) { - PMM_RMAP_ENTRY entry; - PMEMORY_AREA MemoryArea; - PMMSUPPORT AddressSpace; - ULONG Type; - PVOID Address; - PEPROCESS Process; - ULONGLONG Offset; - NTSTATUS Status = STATUS_SUCCESS; + PMM_RMAP_ENTRY entry; + PMEMORY_AREA MemoryArea; + PMMSUPPORT AddressSpace; + ULONG Type; + PVOID Address; + PEPROCESS Process; + ULONGLONG Offset; + NTSTATUS Status = STATUS_SUCCESS; - ExAcquireFastMutex(&RmapListLock); - entry = MmGetRmapListHeadPage(Page); + ExAcquireFastMutex(&RmapListLock); + entry = MmGetRmapListHeadPage(Page); #ifdef NEWCC - // Special case for NEWCC: we can have a page that's only in a segment - // page table - if (entry && RMAP_IS_SEGMENT(entry->Address) && entry->Next == NULL) - { - /* NEWCC does locking itself */ - ExReleaseFastMutex(&RmapListLock); - return MmpPageOutPhysicalAddress(Page); - } + // Special case for NEWCC: we can have a page that's only in a segment + // page table + if (entry && RMAP_IS_SEGMENT(entry->Address) && entry->Next == NULL) + { + /* NEWCC does locking itself */ + ExReleaseFastMutex(&RmapListLock); + return MmpPageOutPhysicalAddress(Page); + } #endif - while (entry && RMAP_IS_SEGMENT(entry->Address)) - entry = entry->Next; + while (entry && RMAP_IS_SEGMENT(entry->Address)) + entry = entry->Next; - if (entry == NULL) - { - ExReleaseFastMutex(&RmapListLock); - return(STATUS_UNSUCCESSFUL); - } + if (entry == NULL) + { + ExReleaseFastMutex(&RmapListLock); + return(STATUS_UNSUCCESSFUL); + } - Process = entry->Process; + Process = entry->Process; - Address = entry->Address; + Address = entry->Address; - if ((((ULONG_PTR)Address) & 0xFFF) != 0) - { - KeBugCheck(MEMORY_MANAGEMENT); - } + if ((((ULONG_PTR)Address) & 0xFFF) != 0) + { + KeBugCheck(MEMORY_MANAGEMENT); + } - if (Address < MmSystemRangeStart) - { - if (!ExAcquireRundownProtection(&Process->RundownProtect)) - { - ExReleaseFastMutex(&RmapListLock); - return STATUS_PROCESS_IS_TERMINATING; - } + if (Address < MmSystemRangeStart) + { + if (!ExAcquireRundownProtection(&Process->RundownProtect)) + { + ExReleaseFastMutex(&RmapListLock); + return STATUS_PROCESS_IS_TERMINATING; + } - Status = ObReferenceObjectByPointer(Process, PROCESS_ALL_ACCESS, NULL, KernelMode); - ExReleaseFastMutex(&RmapListLock); - if (!NT_SUCCESS(Status)) - { - ExReleaseRundownProtection(&Process->RundownProtect); - return Status; - } - AddressSpace = &Process->Vm; - } - else - { - ExReleaseFastMutex(&RmapListLock); - AddressSpace = MmGetKernelAddressSpace(); - } + Status = ObReferenceObjectByPointer(Process, PROCESS_ALL_ACCESS, NULL, KernelMode); + ExReleaseFastMutex(&RmapListLock); + if (!NT_SUCCESS(Status)) + { + ExReleaseRundownProtection(&Process->RundownProtect); + return Status; + } + AddressSpace = &Process->Vm; + } + else + { + ExReleaseFastMutex(&RmapListLock); + AddressSpace = MmGetKernelAddressSpace(); + } - MmLockAddressSpace(AddressSpace); - MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address); - if (MemoryArea == NULL || MemoryArea->DeleteInProgress) - { - MmUnlockAddressSpace(AddressSpace); - if (Address < MmSystemRangeStart) - { - ExReleaseRundownProtection(&Process->RundownProtect); - ObDereferenceObject(Process); - } - return(STATUS_UNSUCCESSFUL); - } - Type = MemoryArea->Type; - if (Type == MEMORY_AREA_SECTION_VIEW) - { - ULONG_PTR Entry; - Offset = MemoryArea->Data.SectionData.ViewOffset.QuadPart + - ((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress); - - MmLockSectionSegment(MemoryArea->Data.SectionData.Segment); - - /* - * Get or create a pageop - */ - Entry = MmGetPageEntrySectionSegment(MemoryArea->Data.SectionData.Segment, - (PLARGE_INTEGER)&Offset); - if (Entry && IS_SWAP_FROM_SSE(Entry) && SWAPENTRY_FROM_SSE(Entry) == MM_WAIT_ENTRY) - { - MmUnlockSectionSegment(MemoryArea->Data.SectionData.Segment); - MmUnlockAddressSpace(AddressSpace); - if (Address < MmSystemRangeStart) - { + MmLockAddressSpace(AddressSpace); + MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address); + if (MemoryArea == NULL || MemoryArea->DeleteInProgress) + { + MmUnlockAddressSpace(AddressSpace); + if (Address < MmSystemRangeStart) + { ExReleaseRundownProtection(&Process->RundownProtect); ObDereferenceObject(Process); - } - return(STATUS_UNSUCCESSFUL); - } + } + return(STATUS_UNSUCCESSFUL); + } + Type = MemoryArea->Type; + if (Type == MEMORY_AREA_SECTION_VIEW) + { + ULONG_PTR Entry; + Offset = MemoryArea->Data.SectionData.ViewOffset.QuadPart + + ((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress); - MmSetPageEntrySectionSegment(MemoryArea->Data.SectionData.Segment, (PLARGE_INTEGER)&Offset, MAKE_SWAP_SSE(MM_WAIT_ENTRY)); + MmLockSectionSegment(MemoryArea->Data.SectionData.Segment); - /* - * Release locks now we have a page op. - */ - MmUnlockSectionSegment(MemoryArea->Data.SectionData.Segment); - MmUnlockAddressSpace(AddressSpace); + /* + * Get or create a pageop + */ + Entry = MmGetPageEntrySectionSegment(MemoryArea->Data.SectionData.Segment, + (PLARGE_INTEGER)&Offset); + if (Entry && IS_SWAP_FROM_SSE(Entry) && SWAPENTRY_FROM_SSE(Entry) == MM_WAIT_ENTRY) + { + MmUnlockSectionSegment(MemoryArea->Data.SectionData.Segment); + MmUnlockAddressSpace(AddressSpace); + if (Address < MmSystemRangeStart) + { + ExReleaseRundownProtection(&Process->RundownProtect); + ObDereferenceObject(Process); + } + return(STATUS_UNSUCCESSFUL); + } - /* - * Do the actual page out work. - */ - Status = MmPageOutSectionView(AddressSpace, MemoryArea, Address, Entry); - } - else if (Type == MEMORY_AREA_CACHE) - { - /* NEWCC does locking itself */ - MmUnlockAddressSpace(AddressSpace); - Status = MmpPageOutPhysicalAddress(Page); - } - else - { - KeBugCheck(MEMORY_MANAGEMENT); - } + MmSetPageEntrySectionSegment(MemoryArea->Data.SectionData.Segment, (PLARGE_INTEGER)&Offset, MAKE_SWAP_SSE(MM_WAIT_ENTRY)); - if (Address < MmSystemRangeStart) - { - ExReleaseRundownProtection(&Process->RundownProtect); - ObDereferenceObject(Process); - } - return(Status); + /* + * Release locks now we have a page op. + */ + MmUnlockSectionSegment(MemoryArea->Data.SectionData.Segment); + MmUnlockAddressSpace(AddressSpace); + + /* + * Do the actual page out work. + */ + Status = MmPageOutSectionView(AddressSpace, MemoryArea, Address, Entry); + } + else if (Type == MEMORY_AREA_CACHE) + { + /* NEWCC does locking itself */ + MmUnlockAddressSpace(AddressSpace); + Status = MmpPageOutPhysicalAddress(Page); + } + else + { + KeBugCheck(MEMORY_MANAGEMENT); + } + + if (Address < MmSystemRangeStart) + { + ExReleaseRundownProtection(&Process->RundownProtect); + ObDereferenceObject(Process); + } + return(Status); } VOID NTAPI MmSetCleanAllRmaps(PFN_NUMBER Page) { - PMM_RMAP_ENTRY current_entry; + PMM_RMAP_ENTRY current_entry; - ExAcquireFastMutex(&RmapListLock); - current_entry = MmGetRmapListHeadPage(Page); - if (current_entry == NULL) - { - DPRINT1("MmIsDirtyRmap: No rmaps.\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - while (current_entry != NULL) - { - if (!RMAP_IS_SEGMENT(current_entry->Address)) - MmSetCleanPage(current_entry->Process, current_entry->Address); - current_entry = current_entry->Next; - } - ExReleaseFastMutex(&RmapListLock); + ExAcquireFastMutex(&RmapListLock); + current_entry = MmGetRmapListHeadPage(Page); + if (current_entry == NULL) + { + DPRINT1("MmIsDirtyRmap: No rmaps.\n"); + KeBugCheck(MEMORY_MANAGEMENT); + } + while (current_entry != NULL) + { + if (!RMAP_IS_SEGMENT(current_entry->Address)) + MmSetCleanPage(current_entry->Process, current_entry->Address); + current_entry = current_entry->Next; + } + ExReleaseFastMutex(&RmapListLock); } VOID NTAPI MmSetDirtyAllRmaps(PFN_NUMBER Page) { - PMM_RMAP_ENTRY current_entry; + PMM_RMAP_ENTRY current_entry; - ExAcquireFastMutex(&RmapListLock); - current_entry = MmGetRmapListHeadPage(Page); - if (current_entry == NULL) - { - DPRINT1("MmIsDirtyRmap: No rmaps.\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - while (current_entry != NULL) - { - if (!RMAP_IS_SEGMENT(current_entry->Address)) - MmSetDirtyPage(current_entry->Process, current_entry->Address); - current_entry = current_entry->Next; - } - ExReleaseFastMutex(&RmapListLock); + ExAcquireFastMutex(&RmapListLock); + current_entry = MmGetRmapListHeadPage(Page); + if (current_entry == NULL) + { + DPRINT1("MmIsDirtyRmap: No rmaps.\n"); + KeBugCheck(MEMORY_MANAGEMENT); + } + while (current_entry != NULL) + { + if (!RMAP_IS_SEGMENT(current_entry->Address)) + MmSetDirtyPage(current_entry->Process, current_entry->Address); + current_entry = current_entry->Next; + } + ExReleaseFastMutex(&RmapListLock); } BOOLEAN NTAPI MmIsDirtyPageRmap(PFN_NUMBER Page) { - PMM_RMAP_ENTRY current_entry; + PMM_RMAP_ENTRY current_entry; - ExAcquireFastMutex(&RmapListLock); - current_entry = MmGetRmapListHeadPage(Page); - if (current_entry == NULL) - { - ExReleaseFastMutex(&RmapListLock); - return(FALSE); - } - while (current_entry != NULL) - { - if ( - !RMAP_IS_SEGMENT(current_entry->Address) && - MmIsDirtyPage(current_entry->Process, current_entry->Address)) - { - ExReleaseFastMutex(&RmapListLock); - return(TRUE); - } - current_entry = current_entry->Next; - } - ExReleaseFastMutex(&RmapListLock); - return(FALSE); + ExAcquireFastMutex(&RmapListLock); + current_entry = MmGetRmapListHeadPage(Page); + if (current_entry == NULL) + { + ExReleaseFastMutex(&RmapListLock); + return(FALSE); + } + while (current_entry != NULL) + { + if ( + !RMAP_IS_SEGMENT(current_entry->Address) && + MmIsDirtyPage(current_entry->Process, current_entry->Address)) + { + ExReleaseFastMutex(&RmapListLock); + return(TRUE); + } + current_entry = current_entry->Next; + } + ExReleaseFastMutex(&RmapListLock); + return(FALSE); } VOID @@ -267,75 +267,75 @@ NTAPI MmInsertRmap(PFN_NUMBER Page, PEPROCESS Process, PVOID Address) { - PMM_RMAP_ENTRY current_entry; - PMM_RMAP_ENTRY new_entry; - ULONG PrevSize; - if (!RMAP_IS_SEGMENT(Address)) - Address = (PVOID)PAGE_ROUND_DOWN(Address); + PMM_RMAP_ENTRY current_entry; + PMM_RMAP_ENTRY new_entry; + ULONG PrevSize; + if (!RMAP_IS_SEGMENT(Address)) + Address = (PVOID)PAGE_ROUND_DOWN(Address); - new_entry = ExAllocateFromNPagedLookasideList(&RmapLookasideList); - if (new_entry == NULL) - { - KeBugCheck(MEMORY_MANAGEMENT); - } - new_entry->Address = Address; - new_entry->Process = (PEPROCESS)Process; + new_entry = ExAllocateFromNPagedLookasideList(&RmapLookasideList); + if (new_entry == NULL) + { + KeBugCheck(MEMORY_MANAGEMENT); + } + new_entry->Address = Address; + new_entry->Process = (PEPROCESS)Process; #if DBG #ifdef __GNUC__ - new_entry->Caller = __builtin_return_address(0); + new_entry->Caller = __builtin_return_address(0); #else - new_entry->Caller = _ReturnAddress(); + new_entry->Caller = _ReturnAddress(); #endif #endif - if ( - !RMAP_IS_SEGMENT(Address) && - MmGetPfnForProcess(Process, Address) != Page) - { - DPRINT1("Insert rmap (%d, 0x%.8X) 0x%.8X which doesn't match physical " - "address 0x%.8X\n", Process ? Process->UniqueProcessId : 0, - Address, - MmGetPfnForProcess(Process, Address) << PAGE_SHIFT, - Page << PAGE_SHIFT); - KeBugCheck(MEMORY_MANAGEMENT); - } + if ( + !RMAP_IS_SEGMENT(Address) && + MmGetPfnForProcess(Process, Address) != Page) + { + DPRINT1("Insert rmap (%d, 0x%.8X) 0x%.8X which doesn't match physical " + "address 0x%.8X\n", Process ? Process->UniqueProcessId : 0, + Address, + MmGetPfnForProcess(Process, Address) << PAGE_SHIFT, + Page << PAGE_SHIFT); + KeBugCheck(MEMORY_MANAGEMENT); + } - ExAcquireFastMutex(&RmapListLock); - current_entry = MmGetRmapListHeadPage(Page); - new_entry->Next = current_entry; + ExAcquireFastMutex(&RmapListLock); + current_entry = MmGetRmapListHeadPage(Page); + new_entry->Next = current_entry; #if DBG - while (current_entry) - { - if (current_entry->Address == new_entry->Address && current_entry->Process == new_entry->Process) - { - DbgPrint("MmInsertRmap tries to add a second rmap entry for address %p\n current caller ", - current_entry->Address); - DbgPrint("%p", new_entry->Caller); - DbgPrint("\n previous caller "); - DbgPrint("%p", current_entry->Caller); - DbgPrint("\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - current_entry = current_entry->Next; - } + while (current_entry) + { + if (current_entry->Address == new_entry->Address && current_entry->Process == new_entry->Process) + { + DbgPrint("MmInsertRmap tries to add a second rmap entry for address %p\n current caller ", + current_entry->Address); + DbgPrint("%p", new_entry->Caller); + DbgPrint("\n previous caller "); + DbgPrint("%p", current_entry->Caller); + DbgPrint("\n"); + KeBugCheck(MEMORY_MANAGEMENT); + } + current_entry = current_entry->Next; + } #endif - MmSetRmapListHeadPage(Page, new_entry); - ExReleaseFastMutex(&RmapListLock); - if (!RMAP_IS_SEGMENT(Address)) - { - if (Process == NULL) - { - Process = PsInitialSystemProcess; - } - if (Process) - { - PrevSize = InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, PAGE_SIZE); - if (PrevSize >= Process->Vm.PeakWorkingSetSize) - { - Process->Vm.PeakWorkingSetSize = PrevSize + PAGE_SIZE; - } - } - } + MmSetRmapListHeadPage(Page, new_entry); + ExReleaseFastMutex(&RmapListLock); + if (!RMAP_IS_SEGMENT(Address)) + { + if (Process == NULL) + { + Process = PsInitialSystemProcess; + } + if (Process) + { + PrevSize = InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, PAGE_SIZE); + if (PrevSize >= Process->Vm.PeakWorkingSetSize) + { + Process->Vm.PeakWorkingSetSize = PrevSize + PAGE_SIZE; + } + } + } } VOID @@ -344,47 +344,47 @@ MmDeleteAllRmaps(PFN_NUMBER Page, PVOID Context, VOID (*DeleteMapping)(PVOID Context, PEPROCESS Process, PVOID Address)) { - PMM_RMAP_ENTRY current_entry; - PMM_RMAP_ENTRY previous_entry; - PEPROCESS Process; + PMM_RMAP_ENTRY current_entry; + PMM_RMAP_ENTRY previous_entry; + PEPROCESS Process; - ExAcquireFastMutex(&RmapListLock); - current_entry = MmGetRmapListHeadPage(Page); - if (current_entry == NULL) - { - DPRINT1("MmDeleteAllRmaps: No rmaps.\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - MmSetRmapListHeadPage(Page, NULL); - ExReleaseFastMutex(&RmapListLock); + ExAcquireFastMutex(&RmapListLock); + current_entry = MmGetRmapListHeadPage(Page); + if (current_entry == NULL) + { + DPRINT1("MmDeleteAllRmaps: No rmaps.\n"); + KeBugCheck(MEMORY_MANAGEMENT); + } + MmSetRmapListHeadPage(Page, NULL); + ExReleaseFastMutex(&RmapListLock); - while (current_entry != NULL) - { - previous_entry = current_entry; - current_entry = current_entry->Next; - if (!RMAP_IS_SEGMENT(previous_entry->Address)) - { - if (DeleteMapping) - { - DeleteMapping(Context, previous_entry->Process, - previous_entry->Address); - } - Process = previous_entry->Process; - ExFreeToNPagedLookasideList(&RmapLookasideList, previous_entry); - if (Process == NULL) - { - Process = PsInitialSystemProcess; - } - if (Process) - { - (void)InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, -PAGE_SIZE); - } - } - else - { - ExFreeToNPagedLookasideList(&RmapLookasideList, previous_entry); - } - } + while (current_entry != NULL) + { + previous_entry = current_entry; + current_entry = current_entry->Next; + if (!RMAP_IS_SEGMENT(previous_entry->Address)) + { + if (DeleteMapping) + { + DeleteMapping(Context, previous_entry->Process, + previous_entry->Address); + } + Process = previous_entry->Process; + ExFreeToNPagedLookasideList(&RmapLookasideList, previous_entry); + if (Process == NULL) + { + Process = PsInitialSystemProcess; + } + if (Process) + { + (void)InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, -PAGE_SIZE); + } + } + else + { + ExFreeToNPagedLookasideList(&RmapLookasideList, previous_entry); + } + } } VOID @@ -392,44 +392,44 @@ NTAPI MmDeleteRmap(PFN_NUMBER Page, PEPROCESS Process, PVOID Address) { - PMM_RMAP_ENTRY current_entry, previous_entry; + PMM_RMAP_ENTRY current_entry, previous_entry; - ExAcquireFastMutex(&RmapListLock); - previous_entry = NULL; - current_entry = MmGetRmapListHeadPage(Page); + ExAcquireFastMutex(&RmapListLock); + previous_entry = NULL; + current_entry = MmGetRmapListHeadPage(Page); - while (current_entry != NULL) - { - if (current_entry->Process == (PEPROCESS)Process && - current_entry->Address == Address) - { - if (previous_entry == NULL) - { - MmSetRmapListHeadPage(Page, current_entry->Next); - } - else - { - previous_entry->Next = current_entry->Next; - } - ExReleaseFastMutex(&RmapListLock); - ExFreeToNPagedLookasideList(&RmapLookasideList, current_entry); - if (!RMAP_IS_SEGMENT(Address)) - { - if (Process == NULL) + while (current_entry != NULL) + { + if (current_entry->Process == (PEPROCESS)Process && + current_entry->Address == Address) + { + if (previous_entry == NULL) { - Process = PsInitialSystemProcess; + MmSetRmapListHeadPage(Page, current_entry->Next); } - if (Process) + else { - (void)InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, -PAGE_SIZE); + previous_entry->Next = current_entry->Next; } - } - return; - } - previous_entry = current_entry; - current_entry = current_entry->Next; - } - KeBugCheck(MEMORY_MANAGEMENT); + ExReleaseFastMutex(&RmapListLock); + ExFreeToNPagedLookasideList(&RmapLookasideList, current_entry); + if (!RMAP_IS_SEGMENT(Address)) + { + if (Process == NULL) + { + Process = PsInitialSystemProcess; + } + if (Process) + { + (void)InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, -PAGE_SIZE); + } + } + return; + } + previous_entry = current_entry; + current_entry = current_entry->Next; + } + KeBugCheck(MEMORY_MANAGEMENT); } /* @@ -450,27 +450,27 @@ PVOID NTAPI MmGetSegmentRmap(PFN_NUMBER Page, PULONG RawOffset) { - PCACHE_SECTION_PAGE_TABLE Result = NULL; - PMM_RMAP_ENTRY current_entry;//, previous_entry; + PCACHE_SECTION_PAGE_TABLE Result = NULL; + PMM_RMAP_ENTRY current_entry;//, previous_entry; - ExAcquireFastMutex(&RmapListLock); - //previous_entry = NULL; - current_entry = MmGetRmapListHeadPage(Page); - while (current_entry != NULL) - { - if (RMAP_IS_SEGMENT(current_entry->Address)) - { - Result = (PCACHE_SECTION_PAGE_TABLE)current_entry->Process; - *RawOffset = (ULONG_PTR)current_entry->Address & ~RMAP_SEGMENT_MASK; - InterlockedIncrementUL(&Result->Segment->ReferenceCount); - ExReleaseFastMutex(&RmapListLock); - return Result; - } - //previous_entry = current_entry; - current_entry = current_entry->Next; - } - ExReleaseFastMutex(&RmapListLock); - return NULL; + ExAcquireFastMutex(&RmapListLock); + //previous_entry = NULL; + current_entry = MmGetRmapListHeadPage(Page); + while (current_entry != NULL) + { + if (RMAP_IS_SEGMENT(current_entry->Address)) + { + Result = (PCACHE_SECTION_PAGE_TABLE)current_entry->Process; + *RawOffset = (ULONG_PTR)current_entry->Address & ~RMAP_SEGMENT_MASK; + InterlockedIncrementUL(&Result->Segment->ReferenceCount); + ExReleaseFastMutex(&RmapListLock); + return Result; + } + //previous_entry = current_entry; + current_entry = current_entry->Next; + } + ExReleaseFastMutex(&RmapListLock); + return NULL; } /* @@ -483,29 +483,29 @@ VOID NTAPI MmDeleteSectionAssociation(PFN_NUMBER Page) { - PMM_RMAP_ENTRY current_entry, previous_entry; + PMM_RMAP_ENTRY current_entry, previous_entry; - ExAcquireFastMutex(&RmapListLock); - previous_entry = NULL; - current_entry = MmGetRmapListHeadPage(Page); - while (current_entry != NULL) - { - if (RMAP_IS_SEGMENT(current_entry->Address)) - { - if (previous_entry == NULL) - { - MmSetRmapListHeadPage(Page, current_entry->Next); - } - else - { - previous_entry->Next = current_entry->Next; - } - ExReleaseFastMutex(&RmapListLock); - ExFreeToNPagedLookasideList(&RmapLookasideList, current_entry); - return; - } - previous_entry = current_entry; - current_entry = current_entry->Next; - } - ExReleaseFastMutex(&RmapListLock); + ExAcquireFastMutex(&RmapListLock); + previous_entry = NULL; + current_entry = MmGetRmapListHeadPage(Page); + while (current_entry != NULL) + { + if (RMAP_IS_SEGMENT(current_entry->Address)) + { + if (previous_entry == NULL) + { + MmSetRmapListHeadPage(Page, current_entry->Next); + } + else + { + previous_entry->Next = current_entry->Next; + } + ExReleaseFastMutex(&RmapListLock); + ExFreeToNPagedLookasideList(&RmapLookasideList, current_entry); + return; + } + previous_entry = current_entry; + current_entry = current_entry->Next; + } + ExReleaseFastMutex(&RmapListLock); } diff --git a/reactos/ntoskrnl/mm/section.c b/reactos/ntoskrnl/mm/section.c index fc7c343b7f9..587b35e4fa3 100644 --- a/reactos/ntoskrnl/mm/section.c +++ b/reactos/ntoskrnl/mm/section.c @@ -69,20 +69,20 @@ extern MMSESSION MmSession; NTSTATUS NTAPI MiMapViewInSystemSpace(IN PVOID Section, -IN PVOID Session, -OUT PVOID *MappedBase, -IN OUT PSIZE_T ViewSize); + IN PVOID Session, + OUT PVOID *MappedBase, + IN OUT PSIZE_T ViewSize); NTSTATUS NTAPI MmCreateArm3Section(OUT PVOID *SectionObject, -IN ACCESS_MASK DesiredAccess, -IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, -IN PLARGE_INTEGER InputMaximumSize, -IN ULONG SectionPageProtection, -IN ULONG AllocationAttributes, -IN HANDLE FileHandle OPTIONAL, -IN PFILE_OBJECT FileObject OPTIONAL); + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN PLARGE_INTEGER InputMaximumSize, + IN ULONG SectionPageProtection, + IN ULONG AllocationAttributes, + IN HANDLE FileHandle OPTIONAL, + IN PFILE_OBJECT FileObject OPTIONAL); NTSTATUS NTAPI @@ -121,13 +121,13 @@ C_ASSERT(PEFMT_FIELDS_EQUAL(IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, Si typedef struct { - PROS_SECTION_OBJECT Section; - PMM_SECTION_SEGMENT Segment; - LARGE_INTEGER Offset; - BOOLEAN WasDirty; - BOOLEAN Private; - PEPROCESS CallingProcess; - ULONG_PTR SectionEntry; + PROS_SECTION_OBJECT Section; + PMM_SECTION_SEGMENT Segment; + LARGE_INTEGER Offset; + BOOLEAN WasDirty; + BOOLEAN Private; + PEPROCESS CallingProcess; + ULONG_PTR SectionEntry; } MM_SECTION_PAGEOUT_CONTEXT; @@ -163,16 +163,18 @@ static ULONG SectionCharacteristicsToProtect[16] = extern ULONG MmMakeFileAccess []; ACCESS_MASK NTAPI MiArm3GetCorrectFileAccessMask(IN ACCESS_MASK SectionPageProtection); -static GENERIC_MAPPING MmpSectionMapping = { - STANDARD_RIGHTS_READ | SECTION_MAP_READ | SECTION_QUERY, - STANDARD_RIGHTS_WRITE | SECTION_MAP_WRITE, - STANDARD_RIGHTS_EXECUTE | SECTION_MAP_EXECUTE, - SECTION_ALL_ACCESS}; +static GENERIC_MAPPING MmpSectionMapping = +{ + STANDARD_RIGHTS_READ | SECTION_MAP_READ | SECTION_QUERY, + STANDARD_RIGHTS_WRITE | SECTION_MAP_WRITE, + STANDARD_RIGHTS_EXECUTE | SECTION_MAP_EXECUTE, + SECTION_ALL_ACCESS +}; static const INFORMATION_CLASS_INFO ExSectionInfoClass[] = { - ICI_SQ_SAME( sizeof(SECTION_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* SectionBasicInformation */ - ICI_SQ_SAME( sizeof(SECTION_IMAGE_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* SectionImageInformation */ + ICI_SQ_SAME( sizeof(SECTION_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* SectionBasicInformation */ + ICI_SQ_SAME( sizeof(SECTION_IMAGE_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* SectionImageInformation */ }; /* FUNCTIONS *****************************************************************/ @@ -266,7 +268,7 @@ NTSTATUS NTAPI PeFmtCreateSection(IN CONST VOID * FileHeader, * need to read the header from the file */ if(FileHeaderSize < cbFileHeaderOffsetSize || - (UINT_PTR)pinhNtHeader % TYPE_ALIGNMENT(IMAGE_NT_HEADERS32) != 0) + (UINT_PTR)pinhNtHeader % TYPE_ALIGNMENT(IMAGE_NT_HEADERS32) != 0) { ULONG cbNtHeaderSize; ULONG cbReadSize; @@ -358,16 +360,16 @@ l_ReadHeaderFromFile: switch(piohOptHeader->Magic) { - case IMAGE_NT_OPTIONAL_HDR32_MAGIC: - case IMAGE_NT_OPTIONAL_HDR64_MAGIC: - break; + case IMAGE_NT_OPTIONAL_HDR32_MAGIC: + case IMAGE_NT_OPTIONAL_HDR64_MAGIC: + break; - default: - DIE(("Unrecognized optional header, Magic is %X\n", piohOptHeader->Magic)); + default: + DIE(("Unrecognized optional header, Magic is %X\n", piohOptHeader->Magic)); } if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SectionAlignment) && - RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, FileAlignment)) + RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, FileAlignment)) { /* See [1], section 3.4.2 */ if(piohOptHeader->SectionAlignment < PAGE_SIZE) @@ -395,153 +397,153 @@ l_ReadHeaderFromFile: switch(piohOptHeader->Magic) { - /* PE32 */ - case IMAGE_NT_OPTIONAL_HDR32_MAGIC: + /* PE32 */ + case IMAGE_NT_OPTIONAL_HDR32_MAGIC: + { + if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, ImageBase)) + ImageBase = piohOptHeader->ImageBase; + + if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfImage)) + ImageSectionObject->ImageInformation.ImageFileSize = piohOptHeader->SizeOfImage; + + if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfStackReserve)) + ImageSectionObject->ImageInformation.MaximumStackSize = piohOptHeader->SizeOfStackReserve; + + if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfStackCommit)) + ImageSectionObject->ImageInformation.CommittedStackSize = piohOptHeader->SizeOfStackCommit; + + if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, Subsystem)) { - if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, ImageBase)) - ImageBase = piohOptHeader->ImageBase; + ImageSectionObject->ImageInformation.SubSystemType = piohOptHeader->Subsystem; - if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfImage)) - ImageSectionObject->ImageInformation.ImageFileSize = piohOptHeader->SizeOfImage; - - if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfStackReserve)) - ImageSectionObject->ImageInformation.MaximumStackSize = piohOptHeader->SizeOfStackReserve; - - if(RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfStackCommit)) - ImageSectionObject->ImageInformation.CommittedStackSize = piohOptHeader->SizeOfStackCommit; - - if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, Subsystem)) - { - ImageSectionObject->ImageInformation.SubSystemType = piohOptHeader->Subsystem; - - if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, MinorSubsystemVersion) && + if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, MinorSubsystemVersion) && RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, MajorSubsystemVersion)) - { - ImageSectionObject->ImageInformation.SubSystemMinorVersion = piohOptHeader->MinorSubsystemVersion; - ImageSectionObject->ImageInformation.SubSystemMajorVersion = piohOptHeader->MajorSubsystemVersion; - } - } - - if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, AddressOfEntryPoint)) { - ImageSectionObject->ImageInformation.TransferAddress = (PVOID) (ImageBase + - piohOptHeader->AddressOfEntryPoint); + ImageSectionObject->ImageInformation.SubSystemMinorVersion = piohOptHeader->MinorSubsystemVersion; + ImageSectionObject->ImageInformation.SubSystemMajorVersion = piohOptHeader->MajorSubsystemVersion; } - - if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfCode)) - ImageSectionObject->ImageInformation.ImageContainsCode = piohOptHeader->SizeOfCode != 0; - else - ImageSectionObject->ImageInformation.ImageContainsCode = TRUE; - - if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, AddressOfEntryPoint)) - { - if (piohOptHeader->AddressOfEntryPoint == 0) - { - ImageSectionObject->ImageInformation.ImageContainsCode = FALSE; - } - } - - if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, LoaderFlags)) - ImageSectionObject->ImageInformation.LoaderFlags = piohOptHeader->LoaderFlags; - - if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, DllCharacteristics)) - { - ImageSectionObject->ImageInformation.DllCharacteristics = piohOptHeader->DllCharacteristics; - - /* - * Since we don't really implement SxS yet and LD doesn't supoprt /ALLOWISOLATION:NO, hard-code - * this flag here, which will prevent the loader and other code from doing any .manifest or SxS - * magic to any binary. - * - * This will break applications that depend on SxS when running with real Windows Kernel32/SxS/etc - * but honestly that's not tested. It will also break them when running no ReactOS once we implement - * the SxS support -- at which point, duh, this should be removed. - * - * But right now, any app depending on SxS is already broken anyway, so this flag only helps. - */ - ImageSectionObject->ImageInformation.DllCharacteristics |= IMAGE_DLLCHARACTERISTICS_NO_ISOLATION; - } - - break; } -#ifdef _WIN64 - /* PE64 */ - case IMAGE_NT_OPTIONAL_HDR64_MAGIC: + + if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, AddressOfEntryPoint)) { - const IMAGE_OPTIONAL_HEADER64 * pioh64OptHeader; - - pioh64OptHeader = (const IMAGE_OPTIONAL_HEADER64 *)piohOptHeader; - - if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, ImageBase)) - { - ImageBase = pioh64OptHeader->ImageBase; - if(pioh64OptHeader->ImageBase > MAXULONG_PTR) - DIE(("ImageBase exceeds the address space\n")); - } - - if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfImage)) - { - if(pioh64OptHeader->SizeOfImage > MAXULONG_PTR) - DIE(("SizeOfImage exceeds the address space\n")); - - ImageSectionObject->ImageInformation.ImageFileSize = pioh64OptHeader->SizeOfImage; - } - - if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfStackReserve)) - { - if(pioh64OptHeader->SizeOfStackReserve > MAXULONG_PTR) - DIE(("SizeOfStackReserve exceeds the address space\n")); - - ImageSectionObject->ImageInformation.MaximumStackSize = (ULONG_PTR) pioh64OptHeader->SizeOfStackReserve; - } - - if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfStackCommit)) - { - if(pioh64OptHeader->SizeOfStackCommit > MAXULONG_PTR) - DIE(("SizeOfStackCommit exceeds the address space\n")); - - ImageSectionObject->ImageInformation.CommittedStackSize = (ULONG_PTR) pioh64OptHeader->SizeOfStackCommit; - } - - if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, Subsystem)) - { - ImageSectionObject->ImageInformation.SubSystemType = pioh64OptHeader->Subsystem; - - if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, MinorSubsystemVersion) && - RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, MajorSubsystemVersion)) - { - ImageSectionObject->ImageInformation.SubSystemMinorVersion = pioh64OptHeader->MinorSubsystemVersion; - ImageSectionObject->ImageInformation.SubSystemMajorVersion = pioh64OptHeader->MajorSubsystemVersion; - } - } - - if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, AddressOfEntryPoint)) - { - ImageSectionObject->ImageInformation.TransferAddress = (PVOID) (ImageBase + - pioh64OptHeader->AddressOfEntryPoint); - } - - if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfCode)) - ImageSectionObject->ImageInformation.ImageContainsCode = pioh64OptHeader->SizeOfCode != 0; - else - ImageSectionObject->ImageInformation.ImageContainsCode = TRUE; - - if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, AddressOfEntryPoint)) - { - if (pioh64OptHeader->AddressOfEntryPoint == 0) - { - ImageSectionObject->ImageInformation.ImageContainsCode = FALSE; - } - } - - if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, LoaderFlags)) - ImageSectionObject->ImageInformation.LoaderFlags = pioh64OptHeader->LoaderFlags; - - if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, DllCharacteristics)) - ImageSectionObject->ImageInformation.DllCharacteristics = pioh64OptHeader->DllCharacteristics; - - break; + ImageSectionObject->ImageInformation.TransferAddress = (PVOID) (ImageBase + + piohOptHeader->AddressOfEntryPoint); } + + if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, SizeOfCode)) + ImageSectionObject->ImageInformation.ImageContainsCode = piohOptHeader->SizeOfCode != 0; + else + ImageSectionObject->ImageInformation.ImageContainsCode = TRUE; + + if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, AddressOfEntryPoint)) + { + if (piohOptHeader->AddressOfEntryPoint == 0) + { + ImageSectionObject->ImageInformation.ImageContainsCode = FALSE; + } + } + + if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, LoaderFlags)) + ImageSectionObject->ImageInformation.LoaderFlags = piohOptHeader->LoaderFlags; + + if (RTL_CONTAINS_FIELD(piohOptHeader, cbOptHeaderSize, DllCharacteristics)) + { + ImageSectionObject->ImageInformation.DllCharacteristics = piohOptHeader->DllCharacteristics; + + /* + * Since we don't really implement SxS yet and LD doesn't supoprt /ALLOWISOLATION:NO, hard-code + * this flag here, which will prevent the loader and other code from doing any .manifest or SxS + * magic to any binary. + * + * This will break applications that depend on SxS when running with real Windows Kernel32/SxS/etc + * but honestly that's not tested. It will also break them when running no ReactOS once we implement + * the SxS support -- at which point, duh, this should be removed. + * + * But right now, any app depending on SxS is already broken anyway, so this flag only helps. + */ + ImageSectionObject->ImageInformation.DllCharacteristics |= IMAGE_DLLCHARACTERISTICS_NO_ISOLATION; + } + + break; + } +#ifdef _WIN64 + /* PE64 */ + case IMAGE_NT_OPTIONAL_HDR64_MAGIC: + { + const IMAGE_OPTIONAL_HEADER64 * pioh64OptHeader; + + pioh64OptHeader = (const IMAGE_OPTIONAL_HEADER64 *)piohOptHeader; + + if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, ImageBase)) + { + ImageBase = pioh64OptHeader->ImageBase; + if(pioh64OptHeader->ImageBase > MAXULONG_PTR) + DIE(("ImageBase exceeds the address space\n")); + } + + if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfImage)) + { + if(pioh64OptHeader->SizeOfImage > MAXULONG_PTR) + DIE(("SizeOfImage exceeds the address space\n")); + + ImageSectionObject->ImageInformation.ImageFileSize = pioh64OptHeader->SizeOfImage; + } + + if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfStackReserve)) + { + if(pioh64OptHeader->SizeOfStackReserve > MAXULONG_PTR) + DIE(("SizeOfStackReserve exceeds the address space\n")); + + ImageSectionObject->ImageInformation.MaximumStackSize = (ULONG_PTR) pioh64OptHeader->SizeOfStackReserve; + } + + if(RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfStackCommit)) + { + if(pioh64OptHeader->SizeOfStackCommit > MAXULONG_PTR) + DIE(("SizeOfStackCommit exceeds the address space\n")); + + ImageSectionObject->ImageInformation.CommittedStackSize = (ULONG_PTR) pioh64OptHeader->SizeOfStackCommit; + } + + if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, Subsystem)) + { + ImageSectionObject->ImageInformation.SubSystemType = pioh64OptHeader->Subsystem; + + if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, MinorSubsystemVersion) && + RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, MajorSubsystemVersion)) + { + ImageSectionObject->ImageInformation.SubSystemMinorVersion = pioh64OptHeader->MinorSubsystemVersion; + ImageSectionObject->ImageInformation.SubSystemMajorVersion = pioh64OptHeader->MajorSubsystemVersion; + } + } + + if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, AddressOfEntryPoint)) + { + ImageSectionObject->ImageInformation.TransferAddress = (PVOID) (ImageBase + + pioh64OptHeader->AddressOfEntryPoint); + } + + if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, SizeOfCode)) + ImageSectionObject->ImageInformation.ImageContainsCode = pioh64OptHeader->SizeOfCode != 0; + else + ImageSectionObject->ImageInformation.ImageContainsCode = TRUE; + + if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, AddressOfEntryPoint)) + { + if (pioh64OptHeader->AddressOfEntryPoint == 0) + { + ImageSectionObject->ImageInformation.ImageContainsCode = FALSE; + } + } + + if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, LoaderFlags)) + ImageSectionObject->ImageInformation.LoaderFlags = pioh64OptHeader->LoaderFlags; + + if (RTL_CONTAINS_FIELD(pioh64OptHeader, cbOptHeaderSize, DllCharacteristics)) + ImageSectionObject->ImageInformation.DllCharacteristics = pioh64OptHeader->DllCharacteristics; + + break; + } #endif // _WIN64 } @@ -623,7 +625,7 @@ l_ReadHeaderFromFile: * read the headers from the file */ if(FileHeaderSize < cbSectionHeadersOffsetSize || - (UINT_PTR)pishSectionHeaders % TYPE_ALIGNMENT(IMAGE_SECTION_HEADER) != 0) + (UINT_PTR)pishSectionHeaders % TYPE_ALIGNMENT(IMAGE_SECTION_HEADER) != 0) { PVOID pData; ULONG cbReadSize; @@ -793,53 +795,53 @@ NTSTATUS MmspWaitForFileLock(PFILE_OBJECT File) { return STATUS_SUCCESS; - //return KeWaitForSingleObject(&File->Lock, 0, KernelMode, FALSE, NULL); + //return KeWaitForSingleObject(&File->Lock, 0, KernelMode, FALSE, NULL); } VOID NTAPI MmFreeSectionSegments(PFILE_OBJECT FileObject) { - if (FileObject->SectionObjectPointer->ImageSectionObject != NULL) - { - PMM_IMAGE_SECTION_OBJECT ImageSectionObject; - PMM_SECTION_SEGMENT SectionSegments; - ULONG NrSegments; - ULONG i; + if (FileObject->SectionObjectPointer->ImageSectionObject != NULL) + { + PMM_IMAGE_SECTION_OBJECT ImageSectionObject; + PMM_SECTION_SEGMENT SectionSegments; + ULONG NrSegments; + ULONG i; - ImageSectionObject = (PMM_IMAGE_SECTION_OBJECT)FileObject->SectionObjectPointer->ImageSectionObject; - NrSegments = ImageSectionObject->NrSegments; - SectionSegments = ImageSectionObject->Segments; - for (i = 0; i < NrSegments; i++) - { - if (SectionSegments[i].ReferenceCount != 0) - { - DPRINT1("Image segment %lu still referenced (was %lu)\n", i, - SectionSegments[i].ReferenceCount); + ImageSectionObject = (PMM_IMAGE_SECTION_OBJECT)FileObject->SectionObjectPointer->ImageSectionObject; + NrSegments = ImageSectionObject->NrSegments; + SectionSegments = ImageSectionObject->Segments; + for (i = 0; i < NrSegments; i++) + { + if (SectionSegments[i].ReferenceCount != 0) + { + DPRINT1("Image segment %lu still referenced (was %lu)\n", i, + SectionSegments[i].ReferenceCount); + KeBugCheck(MEMORY_MANAGEMENT); + } + MmFreePageTablesSectionSegment(&SectionSegments[i], NULL); + } + ExFreePool(ImageSectionObject->Segments); + ExFreePool(ImageSectionObject); + FileObject->SectionObjectPointer->ImageSectionObject = NULL; + } + if (FileObject->SectionObjectPointer->DataSectionObject != NULL) + { + PMM_SECTION_SEGMENT Segment; + + Segment = (PMM_SECTION_SEGMENT)FileObject->SectionObjectPointer-> + DataSectionObject; + + if (Segment->ReferenceCount != 0) + { + DPRINT1("Data segment still referenced\n"); KeBugCheck(MEMORY_MANAGEMENT); - } - MmFreePageTablesSectionSegment(&SectionSegments[i], NULL); - } - ExFreePool(ImageSectionObject->Segments); - ExFreePool(ImageSectionObject); - FileObject->SectionObjectPointer->ImageSectionObject = NULL; - } - if (FileObject->SectionObjectPointer->DataSectionObject != NULL) - { - PMM_SECTION_SEGMENT Segment; - - Segment = (PMM_SECTION_SEGMENT)FileObject->SectionObjectPointer-> - DataSectionObject; - - if (Segment->ReferenceCount != 0) - { - DPRINT1("Data segment still referenced\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - MmFreePageTablesSectionSegment(Segment, NULL); - ExFreePool(Segment); - FileObject->SectionObjectPointer->DataSectionObject = NULL; - } + } + MmFreePageTablesSectionSegment(Segment, NULL); + ExFreePool(Segment); + FileObject->SectionObjectPointer->DataSectionObject = NULL; + } } VOID @@ -847,25 +849,25 @@ NTAPI MmSharePageEntrySectionSegment(PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset) { - ULONG_PTR Entry; + ULONG_PTR Entry; - Entry = MmGetPageEntrySectionSegment(Segment, Offset); - if (Entry == 0) - { - DPRINT1("Entry == 0 for MmSharePageEntrySectionSegment\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - if (SHARE_COUNT_FROM_SSE(Entry) == MAX_SHARE_COUNT) - { - DPRINT1("Maximum share count reached\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - if (IS_SWAP_FROM_SSE(Entry)) - { - KeBugCheck(MEMORY_MANAGEMENT); - } - Entry = MAKE_SSE(PAGE_FROM_SSE(Entry), SHARE_COUNT_FROM_SSE(Entry) + 1); - MmSetPageEntrySectionSegment(Segment, Offset, Entry); + Entry = MmGetPageEntrySectionSegment(Segment, Offset); + if (Entry == 0) + { + DPRINT1("Entry == 0 for MmSharePageEntrySectionSegment\n"); + KeBugCheck(MEMORY_MANAGEMENT); + } + if (SHARE_COUNT_FROM_SSE(Entry) == MAX_SHARE_COUNT) + { + DPRINT1("Maximum share count reached\n"); + KeBugCheck(MEMORY_MANAGEMENT); + } + if (IS_SWAP_FROM_SSE(Entry)) + { + KeBugCheck(MEMORY_MANAGEMENT); + } + Entry = MAKE_SSE(PAGE_FROM_SSE(Entry), SHARE_COUNT_FROM_SSE(Entry) + 1); + MmSetPageEntrySectionSegment(Segment, Offset, Entry); } BOOLEAN @@ -877,163 +879,163 @@ MmUnsharePageEntrySectionSegment(PROS_SECTION_OBJECT Section, BOOLEAN PageOut, ULONG_PTR *InEntry) { - ULONG_PTR Entry = InEntry ? *InEntry : MmGetPageEntrySectionSegment(Segment, Offset); - BOOLEAN IsDirectMapped = FALSE; + ULONG_PTR Entry = InEntry ? *InEntry : MmGetPageEntrySectionSegment(Segment, Offset); + BOOLEAN IsDirectMapped = FALSE; - if (Entry == 0) - { - DPRINT1("Entry == 0 for MmUnsharePageEntrySectionSegment\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - if (SHARE_COUNT_FROM_SSE(Entry) == 0) - { - DPRINT1("Zero share count for unshare (Seg %p Offset %x Page %x)\n", Segment, Offset->LowPart, PFN_FROM_SSE(Entry)); - KeBugCheck(MEMORY_MANAGEMENT); - } - if (IS_SWAP_FROM_SSE(Entry)) - { - KeBugCheck(MEMORY_MANAGEMENT); - } - Entry = MAKE_SSE(PAGE_FROM_SSE(Entry), SHARE_COUNT_FROM_SSE(Entry) - 1); - /* - * If we reducing the share count of this entry to zero then set the entry - * to zero and tell the cache the page is no longer mapped. - */ - if (SHARE_COUNT_FROM_SSE(Entry) == 0) - { - PFILE_OBJECT FileObject; + if (Entry == 0) + { + DPRINT1("Entry == 0 for MmUnsharePageEntrySectionSegment\n"); + KeBugCheck(MEMORY_MANAGEMENT); + } + if (SHARE_COUNT_FROM_SSE(Entry) == 0) + { + DPRINT1("Zero share count for unshare (Seg %p Offset %x Page %x)\n", Segment, Offset->LowPart, PFN_FROM_SSE(Entry)); + KeBugCheck(MEMORY_MANAGEMENT); + } + if (IS_SWAP_FROM_SSE(Entry)) + { + KeBugCheck(MEMORY_MANAGEMENT); + } + Entry = MAKE_SSE(PAGE_FROM_SSE(Entry), SHARE_COUNT_FROM_SSE(Entry) - 1); + /* + * If we reducing the share count of this entry to zero then set the entry + * to zero and tell the cache the page is no longer mapped. + */ + if (SHARE_COUNT_FROM_SSE(Entry) == 0) + { + PFILE_OBJECT FileObject; #ifndef NEWCC - PROS_SHARED_CACHE_MAP SharedCacheMap; + PROS_SHARED_CACHE_MAP SharedCacheMap; #endif - SWAPENTRY SavedSwapEntry; - PFN_NUMBER Page; - BOOLEAN IsImageSection; - LARGE_INTEGER FileOffset; + SWAPENTRY SavedSwapEntry; + PFN_NUMBER Page; + BOOLEAN IsImageSection; + LARGE_INTEGER FileOffset; - FileOffset.QuadPart = Offset->QuadPart + Segment->Image.FileOffset; + FileOffset.QuadPart = Offset->QuadPart + Segment->Image.FileOffset; - IsImageSection = Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE; + IsImageSection = Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE; - Page = PFN_FROM_SSE(Entry); - FileObject = Section->FileObject; - if (FileObject != NULL && - !(Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED)) - { + Page = PFN_FROM_SSE(Entry); + FileObject = Section->FileObject; + if (FileObject != NULL && + !(Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED)) + { #ifndef NEWCC - if ((FileOffset.QuadPart % PAGE_SIZE) == 0 && - (Offset->QuadPart + PAGE_SIZE <= Segment->RawLength.QuadPart || !IsImageSection)) - { - NTSTATUS Status; - SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap; - IsDirectMapped = TRUE; + if ((FileOffset.QuadPart % PAGE_SIZE) == 0 && + (Offset->QuadPart + PAGE_SIZE <= Segment->RawLength.QuadPart || !IsImageSection)) + { + NTSTATUS Status; + SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap; + IsDirectMapped = TRUE; #ifndef NEWCC - Status = CcRosUnmapVacb(SharedCacheMap, FileOffset.QuadPart, Dirty); + Status = CcRosUnmapVacb(SharedCacheMap, FileOffset.QuadPart, Dirty); #else - Status = STATUS_SUCCESS; + Status = STATUS_SUCCESS; #endif - if (!NT_SUCCESS(Status)) - { - DPRINT1("CcRosUnmapVacb failed, status = %x\n", Status); - KeBugCheck(MEMORY_MANAGEMENT); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CcRosUnmapVacb failed, status = %x\n", Status); + KeBugCheck(MEMORY_MANAGEMENT); + } } - } #endif - } + } - SavedSwapEntry = MmGetSavedSwapEntryPage(Page); - if (SavedSwapEntry == 0) - { - if (!PageOut && - ((Segment->Flags & MM_PAGEFILE_SEGMENT) || - (Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))) - { - /* - * FIXME: - * Try to page out this page and set the swap entry - * within the section segment. There exist no rmap entry - * for this page. The pager thread can't page out a - * page without a rmap entry. - */ + SavedSwapEntry = MmGetSavedSwapEntryPage(Page); + if (SavedSwapEntry == 0) + { + if (!PageOut && + ((Segment->Flags & MM_PAGEFILE_SEGMENT) || + (Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED))) + { + /* + * FIXME: + * Try to page out this page and set the swap entry + * within the section segment. There exist no rmap entry + * for this page. The pager thread can't page out a + * page without a rmap entry. + */ + MmSetPageEntrySectionSegment(Segment, Offset, Entry); + if (InEntry) *InEntry = Entry; + MiSetPageEvent(NULL, NULL); + } + else + { + MmSetPageEntrySectionSegment(Segment, Offset, 0); + if (InEntry) *InEntry = 0; + MiSetPageEvent(NULL, NULL); + if (!IsDirectMapped) + { + MmReleasePageMemoryConsumer(MC_USER, Page); + } + } + } + else + { + if ((Segment->Flags & MM_PAGEFILE_SEGMENT) || + (Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED)) + { + if (!PageOut) + { + if (Dirty) + { + /* + * FIXME: + * We hold all locks. Nobody can do something with the current + * process and the current segment (also not within an other process). + */ + NTSTATUS Status; + Status = MmWriteToSwapPage(SavedSwapEntry, Page); + if (!NT_SUCCESS(Status)) + { + DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n", Status); + KeBugCheck(MEMORY_MANAGEMENT); + } + } + MmSetPageEntrySectionSegment(Segment, Offset, MAKE_SWAP_SSE(SavedSwapEntry)); + if (InEntry) *InEntry = MAKE_SWAP_SSE(SavedSwapEntry); + MmSetSavedSwapEntryPage(Page, 0); + MiSetPageEvent(NULL, NULL); + } + MmReleasePageMemoryConsumer(MC_USER, Page); + } + else + { + DPRINT1("Found a swapentry for a non private page in an image or data file sgment\n"); + KeBugCheck(MEMORY_MANAGEMENT); + } + } + } + else + { + if (InEntry) + *InEntry = Entry; + else MmSetPageEntrySectionSegment(Segment, Offset, Entry); - if (InEntry) *InEntry = Entry; - MiSetPageEvent(NULL, NULL); - } - else - { - MmSetPageEntrySectionSegment(Segment, Offset, 0); - if (InEntry) *InEntry = 0; - MiSetPageEvent(NULL, NULL); - if (!IsDirectMapped) - { - MmReleasePageMemoryConsumer(MC_USER, Page); - } - } - } - else - { - if ((Segment->Flags & MM_PAGEFILE_SEGMENT) || - (Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED)) - { - if (!PageOut) - { - if (Dirty) - { - /* - * FIXME: - * We hold all locks. Nobody can do something with the current - * process and the current segment (also not within an other process). - */ - NTSTATUS Status; - Status = MmWriteToSwapPage(SavedSwapEntry, Page); - if (!NT_SUCCESS(Status)) - { - DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n", Status); - KeBugCheck(MEMORY_MANAGEMENT); - } - } - MmSetPageEntrySectionSegment(Segment, Offset, MAKE_SWAP_SSE(SavedSwapEntry)); - if (InEntry) *InEntry = MAKE_SWAP_SSE(SavedSwapEntry); - MmSetSavedSwapEntryPage(Page, 0); - MiSetPageEvent(NULL, NULL); - } - MmReleasePageMemoryConsumer(MC_USER, Page); - } - else - { - DPRINT1("Found a swapentry for a non private page in an image or data file sgment\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - } - } - else - { - if (InEntry) - *InEntry = Entry; - else - MmSetPageEntrySectionSegment(Segment, Offset, Entry); - } - return(SHARE_COUNT_FROM_SSE(Entry) > 0); + } + return(SHARE_COUNT_FROM_SSE(Entry) > 0); } BOOLEAN MiIsPageFromCache(PMEMORY_AREA MemoryArea, - LONGLONG SegOffset) + LONGLONG SegOffset) { #ifndef NEWCC - if (!(MemoryArea->Data.SectionData.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED)) - { - PROS_SHARED_CACHE_MAP SharedCacheMap; - PROS_VACB Vacb; - SharedCacheMap = MemoryArea->Data.SectionData.Section->FileObject->SectionObjectPointer->SharedCacheMap; - Vacb = CcRosLookupVacb(SharedCacheMap, SegOffset + MemoryArea->Data.SectionData.Segment->Image.FileOffset); - if (Vacb) - { - CcRosReleaseVacb(SharedCacheMap, Vacb, Vacb->Valid, FALSE, TRUE); - return TRUE; - } - } + if (!(MemoryArea->Data.SectionData.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED)) + { + PROS_SHARED_CACHE_MAP SharedCacheMap; + PROS_VACB Vacb; + SharedCacheMap = MemoryArea->Data.SectionData.Section->FileObject->SectionObjectPointer->SharedCacheMap; + Vacb = CcRosLookupVacb(SharedCacheMap, SegOffset + MemoryArea->Data.SectionData.Segment->Image.FileOffset); + if (Vacb) + { + CcRosReleaseVacb(SharedCacheMap, Vacb, Vacb->Valid, FALSE, TRUE); + return TRUE; + } + } #endif - return FALSE; + return FALSE; } NTSTATUS @@ -1073,149 +1075,55 @@ MiReadPage(PMEMORY_AREA MemoryArea, * Page - Variable that receives a page contains the read data. */ { - LONGLONG BaseOffset; - LONGLONG FileOffset; - PVOID BaseAddress; - BOOLEAN UptoDate; - PROS_VACB Vacb; - PFILE_OBJECT FileObject; - NTSTATUS Status; - LONGLONG RawLength; - PROS_SHARED_CACHE_MAP SharedCacheMap; - BOOLEAN IsImageSection; - LONGLONG Length; + LONGLONG BaseOffset; + LONGLONG FileOffset; + PVOID BaseAddress; + BOOLEAN UptoDate; + PROS_VACB Vacb; + PFILE_OBJECT FileObject; + NTSTATUS Status; + LONGLONG RawLength; + PROS_SHARED_CACHE_MAP SharedCacheMap; + BOOLEAN IsImageSection; + LONGLONG Length; - FileObject = MemoryArea->Data.SectionData.Section->FileObject; - SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap; - RawLength = MemoryArea->Data.SectionData.Segment->RawLength.QuadPart; - FileOffset = SegOffset + MemoryArea->Data.SectionData.Segment->Image.FileOffset; - IsImageSection = MemoryArea->Data.SectionData.Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE; + FileObject = MemoryArea->Data.SectionData.Section->FileObject; + SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap; + RawLength = MemoryArea->Data.SectionData.Segment->RawLength.QuadPart; + FileOffset = SegOffset + MemoryArea->Data.SectionData.Segment->Image.FileOffset; + IsImageSection = MemoryArea->Data.SectionData.Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE; - ASSERT(SharedCacheMap); + ASSERT(SharedCacheMap); - DPRINT("%S %I64x\n", FileObject->FileName.Buffer, FileOffset); + DPRINT("%S %I64x\n", FileObject->FileName.Buffer, FileOffset); - /* - * If the file system is letting us go directly to the cache and the - * memory area was mapped at an offset in the file which is page aligned - * then get the related VACB. - */ - if (((FileOffset % PAGE_SIZE) == 0) && - ((SegOffset + PAGE_SIZE <= RawLength) || !IsImageSection) && - !(MemoryArea->Data.SectionData.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED)) - { + /* + * If the file system is letting us go directly to the cache and the + * memory area was mapped at an offset in the file which is page aligned + * then get the related VACB. + */ + if (((FileOffset % PAGE_SIZE) == 0) && + ((SegOffset + PAGE_SIZE <= RawLength) || !IsImageSection) && + !(MemoryArea->Data.SectionData.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED)) + { - /* - * Get the related VACB; we use a lower level interface than - * filesystems do because it is safe for us to use an offset with an - * alignment less than the file system block size. - */ - Status = CcRosGetVacb(SharedCacheMap, - FileOffset, - &BaseOffset, - &BaseAddress, - &UptoDate, - &Vacb); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - if (!UptoDate) - { - /* - * If the VACB isn't up to date then call the file - * system to read in the data. - */ - Status = CcReadVirtualAddress(Vacb); - if (!NT_SUCCESS(Status)) - { - CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE, FALSE); - return Status; - } - } - - /* Probe the page, since it's PDE might not be synced */ - (void)*((volatile char*)BaseAddress + FileOffset - BaseOffset); - - /* - * Retrieve the page from the view that we actually want. - */ - (*Page) = MmGetPhysicalAddress((char*)BaseAddress + - FileOffset - BaseOffset).LowPart >> PAGE_SHIFT; - - CcRosReleaseVacb(SharedCacheMap, Vacb, TRUE, FALSE, TRUE); - } - else - { - PEPROCESS Process; - KIRQL Irql; - PVOID PageAddr; - LONGLONG VacbOffset; - - /* - * Allocate a page, this is rather complicated by the possibility - * we might have to move other things out of memory - */ - MI_SET_USAGE(MI_USAGE_SECTION); - MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName); - Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, Page); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - Status = CcRosGetVacb(SharedCacheMap, - FileOffset, - &BaseOffset, - &BaseAddress, - &UptoDate, - &Vacb); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - if (!UptoDate) - { - /* - * If the VACB isn't up to date then call the file - * system to read in the data. - */ - Status = CcReadVirtualAddress(Vacb); - if (!NT_SUCCESS(Status)) - { - CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE, FALSE); - return Status; - } - } - - Process = PsGetCurrentProcess(); - PageAddr = MiMapPageInHyperSpace(Process, *Page, &Irql); - VacbOffset = BaseOffset + VACB_MAPPING_GRANULARITY - FileOffset; - Length = RawLength - SegOffset; - if (Length <= VacbOffset && Length <= PAGE_SIZE) - { - memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, Length); - } - else if (VacbOffset >= PAGE_SIZE) - { - memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, PAGE_SIZE); - } - else - { - memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, VacbOffset); - MiUnmapPageInHyperSpace(Process, PageAddr, Irql); - CcRosReleaseVacb(SharedCacheMap, Vacb, TRUE, FALSE, FALSE); - Status = CcRosGetVacb(SharedCacheMap, - FileOffset + VacbOffset, - &BaseOffset, - &BaseAddress, - &UptoDate, - &Vacb); - if (!NT_SUCCESS(Status)) - { + /* + * Get the related VACB; we use a lower level interface than + * filesystems do because it is safe for us to use an offset with an + * alignment less than the file system block size. + */ + Status = CcRosGetVacb(SharedCacheMap, + FileOffset, + &BaseOffset, + &BaseAddress, + &UptoDate, + &Vacb); + if (!NT_SUCCESS(Status)) + { return(Status); - } - if (!UptoDate) - { + } + if (!UptoDate) + { /* * If the VACB isn't up to date then call the file * system to read in the data. @@ -1223,24 +1131,118 @@ MiReadPage(PMEMORY_AREA MemoryArea, Status = CcReadVirtualAddress(Vacb); if (!NT_SUCCESS(Status)) { - CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE, FALSE); - return Status; + CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE, FALSE); + return Status; } - } - PageAddr = MiMapPageInHyperSpace(Process, *Page, &Irql); - if (Length < PAGE_SIZE) - { - memcpy((char*)PageAddr + VacbOffset, BaseAddress, Length - VacbOffset); - } - else - { - memcpy((char*)PageAddr + VacbOffset, BaseAddress, PAGE_SIZE - VacbOffset); - } - } - MiUnmapPageInHyperSpace(Process, PageAddr, Irql); - CcRosReleaseVacb(SharedCacheMap, Vacb, TRUE, FALSE, FALSE); - } - return(STATUS_SUCCESS); + } + + /* Probe the page, since it's PDE might not be synced */ + (void)*((volatile char*)BaseAddress + FileOffset - BaseOffset); + + /* + * Retrieve the page from the view that we actually want. + */ + (*Page) = MmGetPhysicalAddress((char*)BaseAddress + + FileOffset - BaseOffset).LowPart >> PAGE_SHIFT; + + CcRosReleaseVacb(SharedCacheMap, Vacb, TRUE, FALSE, TRUE); + } + else + { + PEPROCESS Process; + KIRQL Irql; + PVOID PageAddr; + LONGLONG VacbOffset; + + /* + * Allocate a page, this is rather complicated by the possibility + * we might have to move other things out of memory + */ + MI_SET_USAGE(MI_USAGE_SECTION); + MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName); + Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, Page); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + Status = CcRosGetVacb(SharedCacheMap, + FileOffset, + &BaseOffset, + &BaseAddress, + &UptoDate, + &Vacb); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + if (!UptoDate) + { + /* + * If the VACB isn't up to date then call the file + * system to read in the data. + */ + Status = CcReadVirtualAddress(Vacb); + if (!NT_SUCCESS(Status)) + { + CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE, FALSE); + return Status; + } + } + + Process = PsGetCurrentProcess(); + PageAddr = MiMapPageInHyperSpace(Process, *Page, &Irql); + VacbOffset = BaseOffset + VACB_MAPPING_GRANULARITY - FileOffset; + Length = RawLength - SegOffset; + if (Length <= VacbOffset && Length <= PAGE_SIZE) + { + memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, Length); + } + else if (VacbOffset >= PAGE_SIZE) + { + memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, PAGE_SIZE); + } + else + { + memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, VacbOffset); + MiUnmapPageInHyperSpace(Process, PageAddr, Irql); + CcRosReleaseVacb(SharedCacheMap, Vacb, TRUE, FALSE, FALSE); + Status = CcRosGetVacb(SharedCacheMap, + FileOffset + VacbOffset, + &BaseOffset, + &BaseAddress, + &UptoDate, + &Vacb); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + if (!UptoDate) + { + /* + * If the VACB isn't up to date then call the file + * system to read in the data. + */ + Status = CcReadVirtualAddress(Vacb); + if (!NT_SUCCESS(Status)) + { + CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE, FALSE); + return Status; + } + } + PageAddr = MiMapPageInHyperSpace(Process, *Page, &Irql); + if (Length < PAGE_SIZE) + { + memcpy((char*)PageAddr + VacbOffset, BaseAddress, Length - VacbOffset); + } + else + { + memcpy((char*)PageAddr + VacbOffset, BaseAddress, PAGE_SIZE - VacbOffset); + } + } + MiUnmapPageInHyperSpace(Process, PageAddr, Irql); + CcRosReleaseVacb(SharedCacheMap, Vacb, TRUE, FALSE, FALSE); + } + return(STATUS_SUCCESS); } #else NTSTATUS @@ -1256,22 +1258,22 @@ MiReadPage(PMEMORY_AREA MemoryArea, * Page - Variable that receives a page contains the read data. */ { - MM_REQUIRED_RESOURCES Resources; - NTSTATUS Status; + MM_REQUIRED_RESOURCES Resources; + NTSTATUS Status; - RtlZeroMemory(&Resources, sizeof(MM_REQUIRED_RESOURCES)); + RtlZeroMemory(&Resources, sizeof(MM_REQUIRED_RESOURCES)); - Resources.Context = MemoryArea->Data.SectionData.Section->FileObject; - Resources.FileOffset.QuadPart = SegOffset + - MemoryArea->Data.SectionData.Segment->Image.FileOffset; - Resources.Consumer = MC_USER; - Resources.Amount = PAGE_SIZE; + Resources.Context = MemoryArea->Data.SectionData.Section->FileObject; + Resources.FileOffset.QuadPart = SegOffset + + MemoryArea->Data.SectionData.Segment->Image.FileOffset; + Resources.Consumer = MC_USER; + Resources.Amount = PAGE_SIZE; - DPRINT("%S, offset 0x%x, len 0x%x, page 0x%x\n", ((PFILE_OBJECT)Resources.Context)->FileName.Buffer, Resources.FileOffset.LowPart, Resources.Amount, Resources.Page[0]); + DPRINT("%S, offset 0x%x, len 0x%x, page 0x%x\n", ((PFILE_OBJECT)Resources.Context)->FileName.Buffer, Resources.FileOffset.LowPart, Resources.Amount, Resources.Page[0]); - Status = MiReadFilePage(MmGetKernelAddressSpace(), MemoryArea, &Resources); - *Page = Resources.Page[0]; - return Status; + Status = MiReadFilePage(MmGetKernelAddressSpace(), MemoryArea, &Resources); + *Page = Resources.Page[0]; + return Status; } #endif @@ -1282,386 +1284,386 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace, PVOID Address, BOOLEAN Locked) { - LARGE_INTEGER Offset; - PFN_NUMBER Page; - NTSTATUS Status; - PROS_SECTION_OBJECT Section; - PMM_SECTION_SEGMENT Segment; - ULONG_PTR Entry; - ULONG_PTR Entry1; - ULONG Attributes; - PMM_REGION Region; - BOOLEAN HasSwapEntry; - PVOID PAddress; - PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace); - SWAPENTRY SwapEntry; + LARGE_INTEGER Offset; + PFN_NUMBER Page; + NTSTATUS Status; + PROS_SECTION_OBJECT Section; + PMM_SECTION_SEGMENT Segment; + ULONG_PTR Entry; + ULONG_PTR Entry1; + ULONG Attributes; + PMM_REGION Region; + BOOLEAN HasSwapEntry; + PVOID PAddress; + PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace); + SWAPENTRY SwapEntry; - /* - * There is a window between taking the page fault and locking the - * address space when another thread could load the page so we check - * that. - */ - if (MmIsPagePresent(Process, Address)) - { - return(STATUS_SUCCESS); - } + /* + * There is a window between taking the page fault and locking the + * address space when another thread could load the page so we check + * that. + */ + if (MmIsPagePresent(Process, Address)) + { + return(STATUS_SUCCESS); + } - if (MmIsDisabledPage(Process, Address)) - { - return(STATUS_ACCESS_VIOLATION); - } + if (MmIsDisabledPage(Process, Address)) + { + return(STATUS_ACCESS_VIOLATION); + } - /* - * Check for the virtual memory area being deleted. - */ - if (MemoryArea->DeleteInProgress) - { - return(STATUS_UNSUCCESSFUL); - } + /* + * Check for the virtual memory area being deleted. + */ + if (MemoryArea->DeleteInProgress) + { + return(STATUS_UNSUCCESSFUL); + } - PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE); - Offset.QuadPart = (ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress - + MemoryArea->Data.SectionData.ViewOffset.QuadPart; + PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE); + Offset.QuadPart = (ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress + + MemoryArea->Data.SectionData.ViewOffset.QuadPart; - Segment = MemoryArea->Data.SectionData.Segment; - Section = MemoryArea->Data.SectionData.Section; - Region = MmFindRegion(MemoryArea->StartingAddress, - &MemoryArea->Data.SectionData.RegionListHead, - Address, NULL); - ASSERT(Region != NULL); - /* - * Lock the segment - */ - MmLockSectionSegment(Segment); - Entry = MmGetPageEntrySectionSegment(Segment, &Offset); - /* - * Check if this page needs to be mapped COW - */ - if ((Segment->WriteCopy) && - (Region->Protect == PAGE_READWRITE || - Region->Protect == PAGE_EXECUTE_READWRITE)) - { - Attributes = Region->Protect == PAGE_READWRITE ? PAGE_READONLY : PAGE_EXECUTE_READ; - } - else - { - Attributes = Region->Protect; - } + Segment = MemoryArea->Data.SectionData.Segment; + Section = MemoryArea->Data.SectionData.Section; + Region = MmFindRegion(MemoryArea->StartingAddress, + &MemoryArea->Data.SectionData.RegionListHead, + Address, NULL); + ASSERT(Region != NULL); + /* + * Lock the segment + */ + MmLockSectionSegment(Segment); + Entry = MmGetPageEntrySectionSegment(Segment, &Offset); + /* + * Check if this page needs to be mapped COW + */ + if ((Segment->WriteCopy) && + (Region->Protect == PAGE_READWRITE || + Region->Protect == PAGE_EXECUTE_READWRITE)) + { + Attributes = Region->Protect == PAGE_READWRITE ? PAGE_READONLY : PAGE_EXECUTE_READ; + } + else + { + Attributes = Region->Protect; + } - /* - * Check if someone else is already handling this fault, if so wait - * for them - */ - if (Entry && IS_SWAP_FROM_SSE(Entry) && SWAPENTRY_FROM_SSE(Entry) == MM_WAIT_ENTRY) - { - MmUnlockSectionSegment(Segment); - MmUnlockAddressSpace(AddressSpace); - MiWaitForPageEvent(NULL, NULL); - MmLockAddressSpace(AddressSpace); - DPRINT("Address 0x%p\n", Address); - return(STATUS_MM_RESTART_OPERATION); - } + /* + * Check if someone else is already handling this fault, if so wait + * for them + */ + if (Entry && IS_SWAP_FROM_SSE(Entry) && SWAPENTRY_FROM_SSE(Entry) == MM_WAIT_ENTRY) + { + MmUnlockSectionSegment(Segment); + MmUnlockAddressSpace(AddressSpace); + MiWaitForPageEvent(NULL, NULL); + MmLockAddressSpace(AddressSpace); + DPRINT("Address 0x%p\n", Address); + return(STATUS_MM_RESTART_OPERATION); + } - HasSwapEntry = MmIsPageSwapEntry(Process, Address); + HasSwapEntry = MmIsPageSwapEntry(Process, Address); - if (HasSwapEntry) - { - SWAPENTRY DummyEntry; + if (HasSwapEntry) + { + SWAPENTRY DummyEntry; - /* - * Is it a wait entry? - */ - MmGetPageFileMapping(Process, Address, &SwapEntry); + /* + * Is it a wait entry? + */ + MmGetPageFileMapping(Process, Address, &SwapEntry); - if (SwapEntry == MM_WAIT_ENTRY) - { - MmUnlockSectionSegment(Segment); - MmUnlockAddressSpace(AddressSpace); - MiWaitForPageEvent(NULL, NULL); - MmLockAddressSpace(AddressSpace); - return STATUS_MM_RESTART_OPERATION; - } + if (SwapEntry == MM_WAIT_ENTRY) + { + MmUnlockSectionSegment(Segment); + MmUnlockAddressSpace(AddressSpace); + MiWaitForPageEvent(NULL, NULL); + MmLockAddressSpace(AddressSpace); + return STATUS_MM_RESTART_OPERATION; + } - /* - * Must be private page we have swapped out. - */ + /* + * Must be private page we have swapped out. + */ - /* - * Sanity check - */ - if (Segment->Flags & MM_PAGEFILE_SEGMENT) - { - DPRINT1("Found a swaped out private page in a pagefile section.\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } + /* + * Sanity check + */ + if (Segment->Flags & MM_PAGEFILE_SEGMENT) + { + DPRINT1("Found a swaped out private page in a pagefile section.\n"); + KeBugCheck(MEMORY_MANAGEMENT); + } - MmUnlockSectionSegment(Segment); - MmDeletePageFileMapping(Process, Address, &SwapEntry); - MmCreatePageFileMapping(Process, Address, MM_WAIT_ENTRY); + MmUnlockSectionSegment(Segment); + MmDeletePageFileMapping(Process, Address, &SwapEntry); + MmCreatePageFileMapping(Process, Address, MM_WAIT_ENTRY); - MmUnlockAddressSpace(AddressSpace); - MI_SET_USAGE(MI_USAGE_SECTION); - if (Process) MI_SET_PROCESS2(Process->ImageFileName); - if (!Process) MI_SET_PROCESS2("Kernel Section"); - Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page); - if (!NT_SUCCESS(Status)) - { - KeBugCheck(MEMORY_MANAGEMENT); - } + MmUnlockAddressSpace(AddressSpace); + MI_SET_USAGE(MI_USAGE_SECTION); + if (Process) MI_SET_PROCESS2(Process->ImageFileName); + if (!Process) MI_SET_PROCESS2("Kernel Section"); + Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page); + if (!NT_SUCCESS(Status)) + { + KeBugCheck(MEMORY_MANAGEMENT); + } - Status = MmReadFromSwapPage(SwapEntry, Page); - if (!NT_SUCCESS(Status)) - { - DPRINT1("MmReadFromSwapPage failed, status = %x\n", Status); - KeBugCheck(MEMORY_MANAGEMENT); - } - MmLockAddressSpace(AddressSpace); - MmDeletePageFileMapping(Process, PAddress, &DummyEntry); - Status = MmCreateVirtualMapping(Process, - PAddress, - Region->Protect, - &Page, - 1); - if (!NT_SUCCESS(Status)) - { - DPRINT("MmCreateVirtualMapping failed, not out of memory\n"); - KeBugCheck(MEMORY_MANAGEMENT); - return(Status); - } + Status = MmReadFromSwapPage(SwapEntry, Page); + if (!NT_SUCCESS(Status)) + { + DPRINT1("MmReadFromSwapPage failed, status = %x\n", Status); + KeBugCheck(MEMORY_MANAGEMENT); + } + MmLockAddressSpace(AddressSpace); + MmDeletePageFileMapping(Process, PAddress, &DummyEntry); + Status = MmCreateVirtualMapping(Process, + PAddress, + Region->Protect, + &Page, + 1); + if (!NT_SUCCESS(Status)) + { + DPRINT("MmCreateVirtualMapping failed, not out of memory\n"); + KeBugCheck(MEMORY_MANAGEMENT); + return(Status); + } - /* - * Store the swap entry for later use. - */ - MmSetSavedSwapEntryPage(Page, SwapEntry); + /* + * Store the swap entry for later use. + */ + MmSetSavedSwapEntryPage(Page, SwapEntry); - /* - * Add the page to the process's working set - */ - MmInsertRmap(Page, Process, Address); - /* - * Finish the operation - */ - MiSetPageEvent(Process, Address); - DPRINT("Address 0x%p\n", Address); - return(STATUS_SUCCESS); - } + /* + * Add the page to the process's working set + */ + MmInsertRmap(Page, Process, Address); + /* + * Finish the operation + */ + MiSetPageEvent(Process, Address); + DPRINT("Address 0x%p\n", Address); + return(STATUS_SUCCESS); + } - /* - * Satisfying a page fault on a map of /Device/PhysicalMemory is easy - */ - if (Section->AllocationAttributes & SEC_PHYSICALMEMORY) - { - MmUnlockSectionSegment(Segment); - /* - * Just map the desired physical page - */ - Page = (PFN_NUMBER)(Offset.QuadPart >> PAGE_SHIFT); - Status = MmCreateVirtualMappingUnsafe(Process, - PAddress, - Region->Protect, - &Page, - 1); - if (!NT_SUCCESS(Status)) - { - DPRINT("MmCreateVirtualMappingUnsafe failed, not out of memory\n"); - KeBugCheck(MEMORY_MANAGEMENT); - return(Status); - } + /* + * Satisfying a page fault on a map of /Device/PhysicalMemory is easy + */ + if (Section->AllocationAttributes & SEC_PHYSICALMEMORY) + { + MmUnlockSectionSegment(Segment); + /* + * Just map the desired physical page + */ + Page = (PFN_NUMBER)(Offset.QuadPart >> PAGE_SHIFT); + Status = MmCreateVirtualMappingUnsafe(Process, + PAddress, + Region->Protect, + &Page, + 1); + if (!NT_SUCCESS(Status)) + { + DPRINT("MmCreateVirtualMappingUnsafe failed, not out of memory\n"); + KeBugCheck(MEMORY_MANAGEMENT); + return(Status); + } - /* - * Cleanup and release locks - */ - MiSetPageEvent(Process, Address); - DPRINT("Address 0x%p\n", Address); - return(STATUS_SUCCESS); - } + /* + * Cleanup and release locks + */ + MiSetPageEvent(Process, Address); + DPRINT("Address 0x%p\n", Address); + return(STATUS_SUCCESS); + } - /* - * Get the entry corresponding to the offset within the section - */ - Entry = MmGetPageEntrySectionSegment(Segment, &Offset); + /* + * Get the entry corresponding to the offset within the section + */ + Entry = MmGetPageEntrySectionSegment(Segment, &Offset); - if (Entry == 0) - { - SWAPENTRY FakeSwapEntry; + if (Entry == 0) + { + SWAPENTRY FakeSwapEntry; - /* - * If the entry is zero (and it can't change because we have - * locked the segment) then we need to load the page. - */ + /* + * If the entry is zero (and it can't change because we have + * locked the segment) then we need to load the page. + */ - /* - * Release all our locks and read in the page from disk - */ - MmSetPageEntrySectionSegment(Segment, &Offset, MAKE_SWAP_SSE(MM_WAIT_ENTRY)); - MmUnlockSectionSegment(Segment); - MmCreatePageFileMapping(Process, PAddress, MM_WAIT_ENTRY); - MmUnlockAddressSpace(AddressSpace); + /* + * Release all our locks and read in the page from disk + */ + MmSetPageEntrySectionSegment(Segment, &Offset, MAKE_SWAP_SSE(MM_WAIT_ENTRY)); + MmUnlockSectionSegment(Segment); + MmCreatePageFileMapping(Process, PAddress, MM_WAIT_ENTRY); + MmUnlockAddressSpace(AddressSpace); - if ((Segment->Flags & MM_PAGEFILE_SEGMENT) || - ((Offset.QuadPart >= (LONGLONG)PAGE_ROUND_UP(Segment->RawLength.QuadPart) && - (Section->AllocationAttributes & SEC_IMAGE)))) - { - MI_SET_USAGE(MI_USAGE_SECTION); - if (Process) MI_SET_PROCESS2(Process->ImageFileName); - if (!Process) MI_SET_PROCESS2("Kernel Section"); - Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page); - if (!NT_SUCCESS(Status)) - { - DPRINT1("MmRequestPageMemoryConsumer failed (Status %x)\n", Status); - } + if ((Segment->Flags & MM_PAGEFILE_SEGMENT) || + ((Offset.QuadPart >= (LONGLONG)PAGE_ROUND_UP(Segment->RawLength.QuadPart) && + (Section->AllocationAttributes & SEC_IMAGE)))) + { + MI_SET_USAGE(MI_USAGE_SECTION); + if (Process) MI_SET_PROCESS2(Process->ImageFileName); + if (!Process) MI_SET_PROCESS2("Kernel Section"); + Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page); + if (!NT_SUCCESS(Status)) + { + DPRINT1("MmRequestPageMemoryConsumer failed (Status %x)\n", Status); + } - } - else - { - Status = MiReadPage(MemoryArea, Offset.QuadPart, &Page); - if (!NT_SUCCESS(Status)) - { - DPRINT1("MiReadPage failed (Status %x)\n", Status); - } - } - if (!NT_SUCCESS(Status)) - { - /* - * FIXME: What do we know in this case? - */ - /* - * Cleanup and release locks - */ - MmLockAddressSpace(AddressSpace); - MiSetPageEvent(Process, Address); - DPRINT("Address 0x%p\n", Address); - return(Status); - } + } + else + { + Status = MiReadPage(MemoryArea, Offset.QuadPart, &Page); + if (!NT_SUCCESS(Status)) + { + DPRINT1("MiReadPage failed (Status %x)\n", Status); + } + } + if (!NT_SUCCESS(Status)) + { + /* + * FIXME: What do we know in this case? + */ + /* + * Cleanup and release locks + */ + MmLockAddressSpace(AddressSpace); + MiSetPageEvent(Process, Address); + DPRINT("Address 0x%p\n", Address); + return(Status); + } - /* - * Mark the offset within the section as having valid, in-memory - * data - */ - MmLockAddressSpace(AddressSpace); - MmLockSectionSegment(Segment); - Entry = MAKE_SSE(Page << PAGE_SHIFT, 1); - MmSetPageEntrySectionSegment(Segment, &Offset, Entry); - MmUnlockSectionSegment(Segment); + /* + * Mark the offset within the section as having valid, in-memory + * data + */ + MmLockAddressSpace(AddressSpace); + MmLockSectionSegment(Segment); + Entry = MAKE_SSE(Page << PAGE_SHIFT, 1); + MmSetPageEntrySectionSegment(Segment, &Offset, Entry); + MmUnlockSectionSegment(Segment); - MmDeletePageFileMapping(Process, PAddress, &FakeSwapEntry); - DPRINT("CreateVirtualMapping Page %x Process %p PAddress %p Attributes %x\n", - Page, Process, PAddress, Attributes); - Status = MmCreateVirtualMapping(Process, - PAddress, - Attributes, - &Page, - 1); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Unable to create virtual mapping\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - ASSERT(MmIsPagePresent(Process, PAddress)); - MmInsertRmap(Page, Process, Address); + MmDeletePageFileMapping(Process, PAddress, &FakeSwapEntry); + DPRINT("CreateVirtualMapping Page %x Process %p PAddress %p Attributes %x\n", + Page, Process, PAddress, Attributes); + Status = MmCreateVirtualMapping(Process, + PAddress, + Attributes, + &Page, + 1); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Unable to create virtual mapping\n"); + KeBugCheck(MEMORY_MANAGEMENT); + } + ASSERT(MmIsPagePresent(Process, PAddress)); + MmInsertRmap(Page, Process, Address); - MiSetPageEvent(Process, Address); - DPRINT("Address 0x%p\n", Address); - return(STATUS_SUCCESS); - } - else if (IS_SWAP_FROM_SSE(Entry)) - { - SWAPENTRY SwapEntry; + MiSetPageEvent(Process, Address); + DPRINT("Address 0x%p\n", Address); + return(STATUS_SUCCESS); + } + else if (IS_SWAP_FROM_SSE(Entry)) + { + SWAPENTRY SwapEntry; - SwapEntry = SWAPENTRY_FROM_SSE(Entry); + SwapEntry = SWAPENTRY_FROM_SSE(Entry); - /* - * Release all our locks and read in the page from disk - */ - MmUnlockSectionSegment(Segment); + /* + * Release all our locks and read in the page from disk + */ + MmUnlockSectionSegment(Segment); - MmUnlockAddressSpace(AddressSpace); - MI_SET_USAGE(MI_USAGE_SECTION); - if (Process) MI_SET_PROCESS2(Process->ImageFileName); - if (!Process) MI_SET_PROCESS2("Kernel Section"); - Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page); - if (!NT_SUCCESS(Status)) - { - KeBugCheck(MEMORY_MANAGEMENT); - } + MmUnlockAddressSpace(AddressSpace); + MI_SET_USAGE(MI_USAGE_SECTION); + if (Process) MI_SET_PROCESS2(Process->ImageFileName); + if (!Process) MI_SET_PROCESS2("Kernel Section"); + Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page); + if (!NT_SUCCESS(Status)) + { + KeBugCheck(MEMORY_MANAGEMENT); + } - Status = MmReadFromSwapPage(SwapEntry, Page); - if (!NT_SUCCESS(Status)) - { - KeBugCheck(MEMORY_MANAGEMENT); - } + Status = MmReadFromSwapPage(SwapEntry, Page); + if (!NT_SUCCESS(Status)) + { + KeBugCheck(MEMORY_MANAGEMENT); + } - /* - * Relock the address space and segment - */ - MmLockAddressSpace(AddressSpace); - MmLockSectionSegment(Segment); + /* + * Relock the address space and segment + */ + MmLockAddressSpace(AddressSpace); + MmLockSectionSegment(Segment); - /* - * Check the entry. No one should change the status of a page - * that has a pending page-in. - */ - Entry1 = MmGetPageEntrySectionSegment(Segment, &Offset); - if (Entry != Entry1) - { - DPRINT1("Someone changed ppte entry while we slept (%x vs %x)\n", Entry, Entry1); - KeBugCheck(MEMORY_MANAGEMENT); - } + /* + * Check the entry. No one should change the status of a page + * that has a pending page-in. + */ + Entry1 = MmGetPageEntrySectionSegment(Segment, &Offset); + if (Entry != Entry1) + { + DPRINT1("Someone changed ppte entry while we slept (%x vs %x)\n", Entry, Entry1); + KeBugCheck(MEMORY_MANAGEMENT); + } - /* - * Mark the offset within the section as having valid, in-memory - * data - */ - Entry = MAKE_SSE(Page << PAGE_SHIFT, 1); - MmSetPageEntrySectionSegment(Segment, &Offset, Entry); - MmUnlockSectionSegment(Segment); + /* + * Mark the offset within the section as having valid, in-memory + * data + */ + Entry = MAKE_SSE(Page << PAGE_SHIFT, 1); + MmSetPageEntrySectionSegment(Segment, &Offset, Entry); + MmUnlockSectionSegment(Segment); - /* - * Save the swap entry. - */ - MmSetSavedSwapEntryPage(Page, SwapEntry); - Status = MmCreateVirtualMapping(Process, - PAddress, - Region->Protect, - &Page, - 1); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Unable to create virtual mapping\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - MmInsertRmap(Page, Process, Address); - MiSetPageEvent(Process, Address); - DPRINT("Address 0x%p\n", Address); - return(STATUS_SUCCESS); - } - else - { - /* - * If the section offset is already in-memory and valid then just - * take another reference to the page - */ + /* + * Save the swap entry. + */ + MmSetSavedSwapEntryPage(Page, SwapEntry); + Status = MmCreateVirtualMapping(Process, + PAddress, + Region->Protect, + &Page, + 1); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Unable to create virtual mapping\n"); + KeBugCheck(MEMORY_MANAGEMENT); + } + MmInsertRmap(Page, Process, Address); + MiSetPageEvent(Process, Address); + DPRINT("Address 0x%p\n", Address); + return(STATUS_SUCCESS); + } + else + { + /* + * If the section offset is already in-memory and valid then just + * take another reference to the page + */ - Page = PFN_FROM_SSE(Entry); + Page = PFN_FROM_SSE(Entry); - MmSharePageEntrySectionSegment(Segment, &Offset); - MmUnlockSectionSegment(Segment); + MmSharePageEntrySectionSegment(Segment, &Offset); + MmUnlockSectionSegment(Segment); - Status = MmCreateVirtualMapping(Process, - PAddress, - Attributes, - &Page, - 1); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Unable to create virtual mapping\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - MmInsertRmap(Page, Process, Address); - MiSetPageEvent(Process, Address); - DPRINT("Address 0x%p\n", Address); - return(STATUS_SUCCESS); - } + Status = MmCreateVirtualMapping(Process, + PAddress, + Attributes, + &Page, + 1); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Unable to create virtual mapping\n"); + KeBugCheck(MEMORY_MANAGEMENT); + } + MmInsertRmap(Page, Process, Address); + MiSetPageEvent(Process, Address); + DPRINT("Address 0x%p\n", Address); + return(STATUS_SUCCESS); + } } NTSTATUS @@ -1670,134 +1672,134 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace, MEMORY_AREA* MemoryArea, PVOID Address) { - PMM_SECTION_SEGMENT Segment; - PROS_SECTION_OBJECT Section; - PFN_NUMBER OldPage; - PFN_NUMBER NewPage; - NTSTATUS Status; - PVOID PAddress; - LARGE_INTEGER Offset; - PMM_REGION Region; - ULONG_PTR Entry; - PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace); - SWAPENTRY SwapEntry; + PMM_SECTION_SEGMENT Segment; + PROS_SECTION_OBJECT Section; + PFN_NUMBER OldPage; + PFN_NUMBER NewPage; + NTSTATUS Status; + PVOID PAddress; + LARGE_INTEGER Offset; + PMM_REGION Region; + ULONG_PTR Entry; + PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace); + SWAPENTRY SwapEntry; - DPRINT("MmAccessFaultSectionView(%p, %p, %p)\n", AddressSpace, MemoryArea, Address); + DPRINT("MmAccessFaultSectionView(%p, %p, %p)\n", AddressSpace, MemoryArea, Address); - /* - * Check if the page has already been set readwrite - */ - if (MmGetPageProtect(Process, Address) & PAGE_READWRITE) - { - DPRINT("Address 0x%p\n", Address); - return(STATUS_SUCCESS); - } + /* + * Check if the page has already been set readwrite + */ + if (MmGetPageProtect(Process, Address) & PAGE_READWRITE) + { + DPRINT("Address 0x%p\n", Address); + return(STATUS_SUCCESS); + } - /* - * Find the offset of the page - */ - PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE); - Offset.QuadPart = (ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress - + MemoryArea->Data.SectionData.ViewOffset.QuadPart; + /* + * Find the offset of the page + */ + PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE); + Offset.QuadPart = (ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress + + MemoryArea->Data.SectionData.ViewOffset.QuadPart; - Segment = MemoryArea->Data.SectionData.Segment; - Section = MemoryArea->Data.SectionData.Section; - Region = MmFindRegion(MemoryArea->StartingAddress, - &MemoryArea->Data.SectionData.RegionListHead, - Address, NULL); - ASSERT(Region != NULL); - /* - * Lock the segment - */ - MmLockSectionSegment(Segment); + Segment = MemoryArea->Data.SectionData.Segment; + Section = MemoryArea->Data.SectionData.Section; + Region = MmFindRegion(MemoryArea->StartingAddress, + &MemoryArea->Data.SectionData.RegionListHead, + Address, NULL); + ASSERT(Region != NULL); + /* + * Lock the segment + */ + MmLockSectionSegment(Segment); - OldPage = MmGetPfnForProcess(Process, Address); - Entry = MmGetPageEntrySectionSegment(Segment, &Offset); + OldPage = MmGetPfnForProcess(Process, Address); + Entry = MmGetPageEntrySectionSegment(Segment, &Offset); - MmUnlockSectionSegment(Segment); + MmUnlockSectionSegment(Segment); - /* - * Check if we are doing COW - */ - if (!((Segment->WriteCopy) && - (Region->Protect == PAGE_READWRITE || - Region->Protect == PAGE_EXECUTE_READWRITE))) - { - DPRINT("Address 0x%p\n", Address); - return(STATUS_ACCESS_VIOLATION); - } + /* + * Check if we are doing COW + */ + if (!((Segment->WriteCopy) && + (Region->Protect == PAGE_READWRITE || + Region->Protect == PAGE_EXECUTE_READWRITE))) + { + DPRINT("Address 0x%p\n", Address); + return(STATUS_ACCESS_VIOLATION); + } - if (IS_SWAP_FROM_SSE(Entry) || - PFN_FROM_SSE(Entry) != OldPage) - { - /* This is a private page. We must only change the page protection. */ - MmSetPageProtect(Process, Address, Region->Protect); - return(STATUS_SUCCESS); - } + if (IS_SWAP_FROM_SSE(Entry) || + PFN_FROM_SSE(Entry) != OldPage) + { + /* This is a private page. We must only change the page protection. */ + MmSetPageProtect(Process, Address, Region->Protect); + return(STATUS_SUCCESS); + } - if(OldPage == 0) - DPRINT("OldPage == 0!\n"); + if(OldPage == 0) + DPRINT("OldPage == 0!\n"); - /* - * Get or create a pageop - */ - MmLockSectionSegment(Segment); - Entry = MmGetPageEntrySectionSegment(Segment, &Offset); + /* + * Get or create a pageop + */ + MmLockSectionSegment(Segment); + Entry = MmGetPageEntrySectionSegment(Segment, &Offset); - /* - * Wait for any other operations to complete - */ - if (Entry == SWAPENTRY_FROM_SSE(MM_WAIT_ENTRY)) - { - MmUnlockSectionSegment(Segment); - MmUnlockAddressSpace(AddressSpace); - MiWaitForPageEvent(NULL, NULL); - /* - * Restart the operation - */ - MmLockAddressSpace(AddressSpace); - DPRINT("Address 0x%p\n", Address); - return(STATUS_MM_RESTART_OPERATION); - } + /* + * Wait for any other operations to complete + */ + if (Entry == SWAPENTRY_FROM_SSE(MM_WAIT_ENTRY)) + { + MmUnlockSectionSegment(Segment); + MmUnlockAddressSpace(AddressSpace); + MiWaitForPageEvent(NULL, NULL); + /* + * Restart the operation + */ + MmLockAddressSpace(AddressSpace); + DPRINT("Address 0x%p\n", Address); + return(STATUS_MM_RESTART_OPERATION); + } - MmDeleteRmap(OldPage, Process, PAddress); - MmDeleteVirtualMapping(Process, PAddress, FALSE, NULL, NULL); - MmCreatePageFileMapping(Process, PAddress, MM_WAIT_ENTRY); + MmDeleteRmap(OldPage, Process, PAddress); + MmDeleteVirtualMapping(Process, PAddress, FALSE, NULL, NULL); + MmCreatePageFileMapping(Process, PAddress, MM_WAIT_ENTRY); - /* - * Release locks now we have the pageop - */ - MmUnlockSectionSegment(Segment); - MmUnlockAddressSpace(AddressSpace); + /* + * Release locks now we have the pageop + */ + MmUnlockSectionSegment(Segment); + MmUnlockAddressSpace(AddressSpace); - /* - * Allocate a page - */ - MI_SET_USAGE(MI_USAGE_SECTION); - if (Process) MI_SET_PROCESS2(Process->ImageFileName); - if (!Process) MI_SET_PROCESS2("Kernel Section"); - Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &NewPage); - if (!NT_SUCCESS(Status)) - { - KeBugCheck(MEMORY_MANAGEMENT); - } + /* + * Allocate a page + */ + MI_SET_USAGE(MI_USAGE_SECTION); + if (Process) MI_SET_PROCESS2(Process->ImageFileName); + if (!Process) MI_SET_PROCESS2("Kernel Section"); + Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &NewPage); + if (!NT_SUCCESS(Status)) + { + KeBugCheck(MEMORY_MANAGEMENT); + } - /* - * Copy the old page - */ - MiCopyFromUserPage(NewPage, OldPage); + /* + * Copy the old page + */ + MiCopyFromUserPage(NewPage, OldPage); - MmLockAddressSpace(AddressSpace); + MmLockAddressSpace(AddressSpace); - /* - * Set the PTE to point to the new page - */ - MmDeletePageFileMapping(Process, PAddress, &SwapEntry); - Status = MmCreateVirtualMapping(Process, - PAddress, - Region->Protect, - &NewPage, - 1); + /* + * Set the PTE to point to the new page + */ + MmDeletePageFileMapping(Process, PAddress, &SwapEntry); + Status = MmCreateVirtualMapping(Process, + PAddress, + Region->Protect, + &NewPage, + 1); if (!NT_SUCCESS(Status)) { DPRINT1("MmCreateVirtualMapping failed, unable to create virtual mapping, not out of memory\n"); @@ -1805,62 +1807,62 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace, return(Status); } - /* - * Unshare the old page. - */ - DPRINT("Swapping page (Old %x New %x)\n", OldPage, NewPage); - MmInsertRmap(NewPage, Process, PAddress); - MmLockSectionSegment(Segment); - MmUnsharePageEntrySectionSegment(Section, Segment, &Offset, FALSE, FALSE, NULL); - MmUnlockSectionSegment(Segment); + /* + * Unshare the old page. + */ + DPRINT("Swapping page (Old %x New %x)\n", OldPage, NewPage); + MmInsertRmap(NewPage, Process, PAddress); + MmLockSectionSegment(Segment); + MmUnsharePageEntrySectionSegment(Section, Segment, &Offset, FALSE, FALSE, NULL); + MmUnlockSectionSegment(Segment); - MiSetPageEvent(Process, Address); - DPRINT("Address 0x%p\n", Address); - return(STATUS_SUCCESS); + MiSetPageEvent(Process, Address); + DPRINT("Address 0x%p\n", Address); + return(STATUS_SUCCESS); } VOID MmPageOutDeleteMapping(PVOID Context, PEPROCESS Process, PVOID Address) { - MM_SECTION_PAGEOUT_CONTEXT* PageOutContext; - BOOLEAN WasDirty; - PFN_NUMBER Page = 0; + MM_SECTION_PAGEOUT_CONTEXT* PageOutContext; + BOOLEAN WasDirty; + PFN_NUMBER Page = 0; - PageOutContext = (MM_SECTION_PAGEOUT_CONTEXT*)Context; - if (Process) - { - MmLockAddressSpace(&Process->Vm); - } + PageOutContext = (MM_SECTION_PAGEOUT_CONTEXT*)Context; + if (Process) + { + MmLockAddressSpace(&Process->Vm); + } - MmDeleteVirtualMapping(Process, - Address, - FALSE, - &WasDirty, - &Page); - if (WasDirty) - { - PageOutContext->WasDirty = TRUE; - } - if (!PageOutContext->Private) - { - MmLockSectionSegment(PageOutContext->Segment); - MmUnsharePageEntrySectionSegment((PROS_SECTION_OBJECT)PageOutContext->Section, - PageOutContext->Segment, - &PageOutContext->Offset, - PageOutContext->WasDirty, - TRUE, - &PageOutContext->SectionEntry); - MmUnlockSectionSegment(PageOutContext->Segment); - } - if (Process) - { - MmUnlockAddressSpace(&Process->Vm); - } + MmDeleteVirtualMapping(Process, + Address, + FALSE, + &WasDirty, + &Page); + if (WasDirty) + { + PageOutContext->WasDirty = TRUE; + } + if (!PageOutContext->Private) + { + MmLockSectionSegment(PageOutContext->Segment); + MmUnsharePageEntrySectionSegment((PROS_SECTION_OBJECT)PageOutContext->Section, + PageOutContext->Segment, + &PageOutContext->Offset, + PageOutContext->WasDirty, + TRUE, + &PageOutContext->SectionEntry); + MmUnlockSectionSegment(PageOutContext->Segment); + } + if (Process) + { + MmUnlockAddressSpace(&Process->Vm); + } - if (PageOutContext->Private) - { - MmReleasePageMemoryConsumer(MC_USER, Page); - } + if (PageOutContext->Private) + { + MmReleasePageMemoryConsumer(MC_USER, Page); + } } NTSTATUS @@ -1869,288 +1871,338 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace, MEMORY_AREA* MemoryArea, PVOID Address, ULONG_PTR Entry) { - PFN_NUMBER Page; - MM_SECTION_PAGEOUT_CONTEXT Context; - SWAPENTRY SwapEntry; - ULONGLONG FileOffset; - NTSTATUS Status; - PFILE_OBJECT FileObject; + PFN_NUMBER Page; + MM_SECTION_PAGEOUT_CONTEXT Context; + SWAPENTRY SwapEntry; + ULONGLONG FileOffset; + NTSTATUS Status; + PFILE_OBJECT FileObject; #ifndef NEWCC - PROS_SHARED_CACHE_MAP SharedCacheMap = NULL; + PROS_SHARED_CACHE_MAP SharedCacheMap = NULL; #endif - BOOLEAN DirectMapped; - BOOLEAN IsImageSection; - PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace); - KIRQL OldIrql; + BOOLEAN DirectMapped; + BOOLEAN IsImageSection; + PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace); + KIRQL OldIrql; - Address = (PVOID)PAGE_ROUND_DOWN(Address); + Address = (PVOID)PAGE_ROUND_DOWN(Address); - /* - * Get the segment and section. - */ - Context.Segment = MemoryArea->Data.SectionData.Segment; - Context.Section = MemoryArea->Data.SectionData.Section; - Context.SectionEntry = Entry; - Context.CallingProcess = Process; + /* + * Get the segment and section. + */ + Context.Segment = MemoryArea->Data.SectionData.Segment; + Context.Section = MemoryArea->Data.SectionData.Section; + Context.SectionEntry = Entry; + Context.CallingProcess = Process; - Context.Offset.QuadPart = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress - + MemoryArea->Data.SectionData.ViewOffset.QuadPart; - FileOffset = Context.Offset.QuadPart + Context.Segment->Image.FileOffset; + Context.Offset.QuadPart = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress + + MemoryArea->Data.SectionData.ViewOffset.QuadPart; + FileOffset = Context.Offset.QuadPart + Context.Segment->Image.FileOffset; - IsImageSection = Context.Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE; + IsImageSection = Context.Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE; - FileObject = Context.Section->FileObject; - DirectMapped = FALSE; + FileObject = Context.Section->FileObject; + DirectMapped = FALSE; - MmLockSectionSegment(Context.Segment); + MmLockSectionSegment(Context.Segment); #ifndef NEWCC - if (FileObject != NULL && - !(Context.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED)) - { - SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap; - - /* - * If the file system is letting us go directly to the cache and the - * memory area was mapped at an offset in the file which is page aligned - * then note this is a direct mapped page. - */ - if ((FileOffset % PAGE_SIZE) == 0 && - (Context.Offset.QuadPart + PAGE_SIZE <= Context.Segment->RawLength.QuadPart || !IsImageSection)) - { - DirectMapped = TRUE; - } - } -#endif - - - /* - * This should never happen since mappings of physical memory are never - * placed in the rmap lists. - */ - if (Context.Section->AllocationAttributes & SEC_PHYSICALMEMORY) - { - DPRINT1("Trying to page out from physical memory section address 0x%p " - "process %p\n", Address, - Process ? Process->UniqueProcessId : 0); - KeBugCheck(MEMORY_MANAGEMENT); - } - - /* - * Get the section segment entry and the physical address. - */ - if (!MmIsPagePresent(Process, Address)) - { - DPRINT1("Trying to page out not-present page at (%p,0x%p).\n", - Process ? Process->UniqueProcessId : 0, Address); - KeBugCheck(MEMORY_MANAGEMENT); - } - Page = MmGetPfnForProcess(Process, Address); - SwapEntry = MmGetSavedSwapEntryPage(Page); - - /* - * Check the reference count to ensure this page can be paged out - */ - if (MmGetReferenceCountPage(Page) != 1) - { - DPRINT("Cannot page out locked section page: 0x%lu (RefCount: %lu)\n", - Page, MmGetReferenceCountPage(Page)); - MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry); - MmUnlockSectionSegment(Context.Segment); - return STATUS_UNSUCCESSFUL; - } - - /* - * Prepare the context structure for the rmap delete call. - */ - MmUnlockSectionSegment(Context.Segment); - Context.WasDirty = FALSE; - if (Context.Segment->Image.Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA || - IS_SWAP_FROM_SSE(Entry) || - PFN_FROM_SSE(Entry) != Page) - { - Context.Private = TRUE; - } - else - { - Context.Private = FALSE; - } - - /* - * Take an additional reference to the page or the VACB. - */ - if (DirectMapped && !Context.Private) - { - if(!MiIsPageFromCache(MemoryArea, Context.Offset.QuadPart)) - { - DPRINT1("Direct mapped non private page is not associated with the cache.\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - } - else - { - OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); - MmReferencePage(Page); - KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); - } - - MmDeleteAllRmaps(Page, (PVOID)&Context, MmPageOutDeleteMapping); - - /* Since we passed in a surrogate, we'll get back the page entry - * state in our context. This is intended to make intermediate - * decrements of share count not release the wait entry. - */ - Entry = Context.SectionEntry; - - /* - * If this wasn't a private page then we should have reduced the entry to - * zero by deleting all the rmaps. - */ - if (!Context.Private && Entry != 0) - { - if (!(Context.Segment->Flags & MM_PAGEFILE_SEGMENT) && + if (FileObject != NULL && !(Context.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED)) - { - KeBugCheckEx(MEMORY_MANAGEMENT, Entry, (ULONG_PTR)Process, (ULONG_PTR)Address, 0); - } - } + { + SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap; - /* - * If the page wasn't dirty then we can just free it as for a readonly page. - * Since we unmapped all the mappings above we know it will not suddenly - * become dirty. - * If the page is from a pagefile section and has no swap entry, - * we can't free the page at this point. - */ - SwapEntry = MmGetSavedSwapEntryPage(Page); - if (Context.Segment->Flags & MM_PAGEFILE_SEGMENT) - { - if (Context.Private) - { - DPRINT1("Found a %s private page (address %p) in a pagefile segment.\n", - Context.WasDirty ? "dirty" : "clean", Address); - KeBugCheckEx(MEMORY_MANAGEMENT, SwapEntry, (ULONG_PTR)Process, (ULONG_PTR)Address, 0); - } - if (!Context.WasDirty && SwapEntry != 0) - { - MmSetSavedSwapEntryPage(Page, 0); - MmLockSectionSegment(Context.Segment); - MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, MAKE_SWAP_SSE(SwapEntry)); - MmUnlockSectionSegment(Context.Segment); - MmReleasePageMemoryConsumer(MC_USER, Page); - MiSetPageEvent(NULL, NULL); - return(STATUS_SUCCESS); - } - } - else if (Context.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED) - { - if (Context.Private) - { - DPRINT1("Found a %s private page (address %p) in a shared section segment.\n", - Context.WasDirty ? "dirty" : "clean", Address); - KeBugCheckEx(MEMORY_MANAGEMENT, Page, (ULONG_PTR)Process, (ULONG_PTR)Address, 0); - } - if (!Context.WasDirty || SwapEntry != 0) - { - MmSetSavedSwapEntryPage(Page, 0); - if (SwapEntry != 0) - { + /* + * If the file system is letting us go directly to the cache and the + * memory area was mapped at an offset in the file which is page aligned + * then note this is a direct mapped page. + */ + if ((FileOffset % PAGE_SIZE) == 0 && + (Context.Offset.QuadPart + PAGE_SIZE <= Context.Segment->RawLength.QuadPart || !IsImageSection)) + { + DirectMapped = TRUE; + } + } +#endif + + + /* + * This should never happen since mappings of physical memory are never + * placed in the rmap lists. + */ + if (Context.Section->AllocationAttributes & SEC_PHYSICALMEMORY) + { + DPRINT1("Trying to page out from physical memory section address 0x%p " + "process %p\n", Address, + Process ? Process->UniqueProcessId : 0); + KeBugCheck(MEMORY_MANAGEMENT); + } + + /* + * Get the section segment entry and the physical address. + */ + if (!MmIsPagePresent(Process, Address)) + { + DPRINT1("Trying to page out not-present page at (%p,0x%p).\n", + Process ? Process->UniqueProcessId : 0, Address); + KeBugCheck(MEMORY_MANAGEMENT); + } + Page = MmGetPfnForProcess(Process, Address); + SwapEntry = MmGetSavedSwapEntryPage(Page); + + /* + * Check the reference count to ensure this page can be paged out + */ + if (MmGetReferenceCountPage(Page) != 1) + { + DPRINT("Cannot page out locked section page: 0x%lu (RefCount: %lu)\n", + Page, MmGetReferenceCountPage(Page)); + MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry); + MmUnlockSectionSegment(Context.Segment); + return STATUS_UNSUCCESSFUL; + } + + /* + * Prepare the context structure for the rmap delete call. + */ + MmUnlockSectionSegment(Context.Segment); + Context.WasDirty = FALSE; + if (Context.Segment->Image.Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA || + IS_SWAP_FROM_SSE(Entry) || + PFN_FROM_SSE(Entry) != Page) + { + Context.Private = TRUE; + } + else + { + Context.Private = FALSE; + } + + /* + * Take an additional reference to the page or the VACB. + */ + if (DirectMapped && !Context.Private) + { + if(!MiIsPageFromCache(MemoryArea, Context.Offset.QuadPart)) + { + DPRINT1("Direct mapped non private page is not associated with the cache.\n"); + KeBugCheck(MEMORY_MANAGEMENT); + } + } + else + { + OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); + MmReferencePage(Page); + KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); + } + + MmDeleteAllRmaps(Page, (PVOID)&Context, MmPageOutDeleteMapping); + + /* Since we passed in a surrogate, we'll get back the page entry + * state in our context. This is intended to make intermediate + * decrements of share count not release the wait entry. + */ + Entry = Context.SectionEntry; + + /* + * If this wasn't a private page then we should have reduced the entry to + * zero by deleting all the rmaps. + */ + if (!Context.Private && Entry != 0) + { + if (!(Context.Segment->Flags & MM_PAGEFILE_SEGMENT) && + !(Context.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED)) + { + KeBugCheckEx(MEMORY_MANAGEMENT, Entry, (ULONG_PTR)Process, (ULONG_PTR)Address, 0); + } + } + + /* + * If the page wasn't dirty then we can just free it as for a readonly page. + * Since we unmapped all the mappings above we know it will not suddenly + * become dirty. + * If the page is from a pagefile section and has no swap entry, + * we can't free the page at this point. + */ + SwapEntry = MmGetSavedSwapEntryPage(Page); + if (Context.Segment->Flags & MM_PAGEFILE_SEGMENT) + { + if (Context.Private) + { + DPRINT1("Found a %s private page (address %p) in a pagefile segment.\n", + Context.WasDirty ? "dirty" : "clean", Address); + KeBugCheckEx(MEMORY_MANAGEMENT, SwapEntry, (ULONG_PTR)Process, (ULONG_PTR)Address, 0); + } + if (!Context.WasDirty && SwapEntry != 0) + { + MmSetSavedSwapEntryPage(Page, 0); MmLockSectionSegment(Context.Segment); MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, MAKE_SWAP_SSE(SwapEntry)); MmUnlockSectionSegment(Context.Segment); - } - MmReleasePageMemoryConsumer(MC_USER, Page); - MiSetPageEvent(NULL, NULL); - return(STATUS_SUCCESS); - } - } - else if (!Context.Private && DirectMapped) - { - if (SwapEntry != 0) - { - DPRINT1("Found a swapentry for a non private and direct mapped page (address %p)\n", - Address); - KeBugCheckEx(MEMORY_MANAGEMENT, STATUS_UNSUCCESSFUL, SwapEntry, (ULONG_PTR)Process, (ULONG_PTR)Address); - } + MmReleasePageMemoryConsumer(MC_USER, Page); + MiSetPageEvent(NULL, NULL); + return(STATUS_SUCCESS); + } + } + else if (Context.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED) + { + if (Context.Private) + { + DPRINT1("Found a %s private page (address %p) in a shared section segment.\n", + Context.WasDirty ? "dirty" : "clean", Address); + KeBugCheckEx(MEMORY_MANAGEMENT, Page, (ULONG_PTR)Process, (ULONG_PTR)Address, 0); + } + if (!Context.WasDirty || SwapEntry != 0) + { + MmSetSavedSwapEntryPage(Page, 0); + if (SwapEntry != 0) + { + MmLockSectionSegment(Context.Segment); + MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, MAKE_SWAP_SSE(SwapEntry)); + MmUnlockSectionSegment(Context.Segment); + } + MmReleasePageMemoryConsumer(MC_USER, Page); + MiSetPageEvent(NULL, NULL); + return(STATUS_SUCCESS); + } + } + else if (!Context.Private && DirectMapped) + { + if (SwapEntry != 0) + { + DPRINT1("Found a swapentry for a non private and direct mapped page (address %p)\n", + Address); + KeBugCheckEx(MEMORY_MANAGEMENT, STATUS_UNSUCCESSFUL, SwapEntry, (ULONG_PTR)Process, (ULONG_PTR)Address); + } #ifndef NEWCC - Status = CcRosUnmapVacb(SharedCacheMap, FileOffset, FALSE); + Status = CcRosUnmapVacb(SharedCacheMap, FileOffset, FALSE); #else - Status = STATUS_SUCCESS; + Status = STATUS_SUCCESS; #endif #ifndef NEWCC - if (!NT_SUCCESS(Status)) - { - DPRINT1("CcRosUnmapVacb failed, status = %x\n", Status); - KeBugCheckEx(MEMORY_MANAGEMENT, Status, (ULONG_PTR)SharedCacheMap, (ULONG_PTR)FileOffset, (ULONG_PTR)Address); - } + if (!NT_SUCCESS(Status)) + { + DPRINT1("CcRosUnmapVacb failed, status = %x\n", Status); + KeBugCheckEx(MEMORY_MANAGEMENT, Status, (ULONG_PTR)SharedCacheMap, (ULONG_PTR)FileOffset, (ULONG_PTR)Address); + } #endif - MiSetPageEvent(NULL, NULL); - return(STATUS_SUCCESS); - } - else if (!Context.WasDirty && !DirectMapped && !Context.Private) - { - if (SwapEntry != 0) - { - DPRINT1("Found a swap entry for a non dirty, non private and not direct mapped page (address %p)\n", - Address); - KeBugCheckEx(MEMORY_MANAGEMENT, SwapEntry, Page, (ULONG_PTR)Process, (ULONG_PTR)Address); - } - MmReleasePageMemoryConsumer(MC_USER, Page); - MiSetPageEvent(NULL, NULL); - return(STATUS_SUCCESS); - } - else if (!Context.WasDirty && Context.Private && SwapEntry != 0) - { - DPRINT("Not dirty and private and not swapped (%p:%p)\n", Process, Address); - MmSetSavedSwapEntryPage(Page, 0); - MmLockAddressSpace(AddressSpace); - Status = MmCreatePageFileMapping(Process, - Address, - SwapEntry); - MmUnlockAddressSpace(AddressSpace); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Status %x Swapping out %p:%p\n", Status, Process, Address); - KeBugCheckEx(MEMORY_MANAGEMENT, Status, (ULONG_PTR)Process, (ULONG_PTR)Address, SwapEntry); - } - MmReleasePageMemoryConsumer(MC_USER, Page); - MiSetPageEvent(NULL, NULL); - return(STATUS_SUCCESS); - } + MiSetPageEvent(NULL, NULL); + return(STATUS_SUCCESS); + } + else if (!Context.WasDirty && !DirectMapped && !Context.Private) + { + if (SwapEntry != 0) + { + DPRINT1("Found a swap entry for a non dirty, non private and not direct mapped page (address %p)\n", + Address); + KeBugCheckEx(MEMORY_MANAGEMENT, SwapEntry, Page, (ULONG_PTR)Process, (ULONG_PTR)Address); + } + MmReleasePageMemoryConsumer(MC_USER, Page); + MiSetPageEvent(NULL, NULL); + return(STATUS_SUCCESS); + } + else if (!Context.WasDirty && Context.Private && SwapEntry != 0) + { + DPRINT("Not dirty and private and not swapped (%p:%p)\n", Process, Address); + MmSetSavedSwapEntryPage(Page, 0); + MmLockAddressSpace(AddressSpace); + Status = MmCreatePageFileMapping(Process, + Address, + SwapEntry); + MmUnlockAddressSpace(AddressSpace); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Status %x Swapping out %p:%p\n", Status, Process, Address); + KeBugCheckEx(MEMORY_MANAGEMENT, Status, (ULONG_PTR)Process, (ULONG_PTR)Address, SwapEntry); + } + MmReleasePageMemoryConsumer(MC_USER, Page); + MiSetPageEvent(NULL, NULL); + return(STATUS_SUCCESS); + } - /* - * If necessary, allocate an entry in the paging file for this page - */ - if (SwapEntry == 0) - { - SwapEntry = MmAllocSwapPage(); - if (SwapEntry == 0) - { - MmShowOutOfSpaceMessagePagingFile(); - MmLockAddressSpace(AddressSpace); - /* - * For private pages restore the old mappings. - */ - if (Context.Private) - { - Status = MmCreateVirtualMapping(Process, - Address, - MemoryArea->Protect, - &Page, - 1); - MmSetDirtyPage(Process, Address); - MmInsertRmap(Page, - Process, - Address); - } - else - { - ULONG_PTR OldEntry; + /* + * If necessary, allocate an entry in the paging file for this page + */ + if (SwapEntry == 0) + { + SwapEntry = MmAllocSwapPage(); + if (SwapEntry == 0) + { + MmShowOutOfSpaceMessagePagingFile(); + MmLockAddressSpace(AddressSpace); /* - * For non-private pages if the page wasn't direct mapped then - * set it back into the section segment entry so we don't loose - * our copy. Otherwise it will be handled by the cache manager. + * For private pages restore the old mappings. */ + if (Context.Private) + { + Status = MmCreateVirtualMapping(Process, + Address, + MemoryArea->Protect, + &Page, + 1); + MmSetDirtyPage(Process, Address); + MmInsertRmap(Page, + Process, + Address); + } + else + { + ULONG_PTR OldEntry; + /* + * For non-private pages if the page wasn't direct mapped then + * set it back into the section segment entry so we don't loose + * our copy. Otherwise it will be handled by the cache manager. + */ + Status = MmCreateVirtualMapping(Process, + Address, + MemoryArea->Protect, + &Page, + 1); + MmSetDirtyPage(Process, Address); + MmInsertRmap(Page, + Process, + Address); + // If we got here, the previous entry should have been a wait + Entry = MAKE_SSE(Page << PAGE_SHIFT, 1); + MmLockSectionSegment(Context.Segment); + OldEntry = MmGetPageEntrySectionSegment(Context.Segment, &Context.Offset); + ASSERT(OldEntry == 0 || OldEntry == MAKE_SWAP_SSE(MM_WAIT_ENTRY)); + MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry); + MmUnlockSectionSegment(Context.Segment); + } + MmUnlockAddressSpace(AddressSpace); + MiSetPageEvent(NULL, NULL); + return(STATUS_PAGEFILE_QUOTA); + } + } + + /* + * Write the page to the pagefile + */ + Status = MmWriteToSwapPage(SwapEntry, Page); + if (!NT_SUCCESS(Status)) + { + DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n", + Status); + /* + * As above: undo our actions. + * FIXME: Also free the swap page. + */ + MmLockAddressSpace(AddressSpace); + if (Context.Private) + { + Status = MmCreateVirtualMapping(Process, + Address, + MemoryArea->Protect, + &Page, + 1); + MmSetDirtyPage(Process, Address); + MmInsertRmap(Page, + Process, + Address); + } + else + { Status = MmCreateVirtualMapping(Process, Address, MemoryArea->Protect, @@ -2160,111 +2212,61 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace, MmInsertRmap(Page, Process, Address); - // If we got here, the previous entry should have been a wait Entry = MAKE_SSE(Page << PAGE_SHIFT, 1); - MmLockSectionSegment(Context.Segment); - OldEntry = MmGetPageEntrySectionSegment(Context.Segment, &Context.Offset); - ASSERT(OldEntry == 0 || OldEntry == MAKE_SWAP_SSE(MM_WAIT_ENTRY)); MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry); - MmUnlockSectionSegment(Context.Segment); - } - MmUnlockAddressSpace(AddressSpace); - MiSetPageEvent(NULL, NULL); - return(STATUS_PAGEFILE_QUOTA); - } - } + } + MmUnlockAddressSpace(AddressSpace); + MiSetPageEvent(NULL, NULL); + return(STATUS_UNSUCCESSFUL); + } - /* - * Write the page to the pagefile - */ - Status = MmWriteToSwapPage(SwapEntry, Page); - if (!NT_SUCCESS(Status)) - { - DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n", - Status); - /* - * As above: undo our actions. - * FIXME: Also free the swap page. - */ - MmLockAddressSpace(AddressSpace); - if (Context.Private) - { - Status = MmCreateVirtualMapping(Process, + /* + * Otherwise we have succeeded. + */ + DPRINT("MM: Wrote section page 0x%.8X to swap!\n", Page << PAGE_SHIFT); + MmSetSavedSwapEntryPage(Page, 0); + if (Context.Segment->Flags & MM_PAGEFILE_SEGMENT || + Context.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED) + { + MmLockSectionSegment(Context.Segment); + MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, MAKE_SWAP_SSE(SwapEntry)); + MmUnlockSectionSegment(Context.Segment); + } + else + { + MmReleasePageMemoryConsumer(MC_USER, Page); + } + + if (Context.Private) + { + MmLockAddressSpace(AddressSpace); + MmLockSectionSegment(Context.Segment); + Status = MmCreatePageFileMapping(Process, Address, - MemoryArea->Protect, - &Page, - 1); - MmSetDirtyPage(Process, Address); - MmInsertRmap(Page, - Process, - Address); - } - else - { - Status = MmCreateVirtualMapping(Process, - Address, - MemoryArea->Protect, - &Page, - 1); - MmSetDirtyPage(Process, Address); - MmInsertRmap(Page, - Process, - Address); - Entry = MAKE_SSE(Page << PAGE_SHIFT, 1); - MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry); - } - MmUnlockAddressSpace(AddressSpace); - MiSetPageEvent(NULL, NULL); - return(STATUS_UNSUCCESSFUL); - } + SwapEntry); + /* We had placed a wait entry upon entry ... replace it before leaving */ + MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry); + MmUnlockSectionSegment(Context.Segment); + MmUnlockAddressSpace(AddressSpace); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Status %x Creating page file mapping for %p:%p\n", Status, Process, Address); + KeBugCheckEx(MEMORY_MANAGEMENT, Status, (ULONG_PTR)Process, (ULONG_PTR)Address, SwapEntry); + } + } + else + { + MmLockAddressSpace(AddressSpace); + MmLockSectionSegment(Context.Segment); + Entry = MAKE_SWAP_SSE(SwapEntry); + /* We had placed a wait entry upon entry ... replace it before leaving */ + MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry); + MmUnlockSectionSegment(Context.Segment); + MmUnlockAddressSpace(AddressSpace); + } - /* - * Otherwise we have succeeded. - */ - DPRINT("MM: Wrote section page 0x%.8X to swap!\n", Page << PAGE_SHIFT); - MmSetSavedSwapEntryPage(Page, 0); - if (Context.Segment->Flags & MM_PAGEFILE_SEGMENT || - Context.Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED) - { - MmLockSectionSegment(Context.Segment); - MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, MAKE_SWAP_SSE(SwapEntry)); - MmUnlockSectionSegment(Context.Segment); - } - else - { - MmReleasePageMemoryConsumer(MC_USER, Page); - } - - if (Context.Private) - { - MmLockAddressSpace(AddressSpace); - MmLockSectionSegment(Context.Segment); - Status = MmCreatePageFileMapping(Process, - Address, - SwapEntry); - /* We had placed a wait entry upon entry ... replace it before leaving */ - MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry); - MmUnlockSectionSegment(Context.Segment); - MmUnlockAddressSpace(AddressSpace); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Status %x Creating page file mapping for %p:%p\n", Status, Process, Address); - KeBugCheckEx(MEMORY_MANAGEMENT, Status, (ULONG_PTR)Process, (ULONG_PTR)Address, SwapEntry); - } - } - else - { - MmLockAddressSpace(AddressSpace); - MmLockSectionSegment(Context.Segment); - Entry = MAKE_SWAP_SSE(SwapEntry); - /* We had placed a wait entry upon entry ... replace it before leaving */ - MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry); - MmUnlockSectionSegment(Context.Segment); - MmUnlockAddressSpace(AddressSpace); - } - - MiSetPageEvent(NULL, NULL); - return(STATUS_SUCCESS); + MiSetPageEvent(NULL, NULL); + return(STATUS_SUCCESS); } NTSTATUS @@ -2274,148 +2276,148 @@ MmWritePageSectionView(PMMSUPPORT AddressSpace, PVOID Address, ULONG PageEntry) { - LARGE_INTEGER Offset; - PROS_SECTION_OBJECT Section; - PMM_SECTION_SEGMENT Segment; - PFN_NUMBER Page; - SWAPENTRY SwapEntry; - ULONG_PTR Entry; - BOOLEAN Private; - NTSTATUS Status; - PFILE_OBJECT FileObject; - PROS_SHARED_CACHE_MAP SharedCacheMap = NULL; - BOOLEAN DirectMapped; - BOOLEAN IsImageSection; - PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace); + LARGE_INTEGER Offset; + PROS_SECTION_OBJECT Section; + PMM_SECTION_SEGMENT Segment; + PFN_NUMBER Page; + SWAPENTRY SwapEntry; + ULONG_PTR Entry; + BOOLEAN Private; + NTSTATUS Status; + PFILE_OBJECT FileObject; + PROS_SHARED_CACHE_MAP SharedCacheMap = NULL; + BOOLEAN DirectMapped; + BOOLEAN IsImageSection; + PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace); - Address = (PVOID)PAGE_ROUND_DOWN(Address); + Address = (PVOID)PAGE_ROUND_DOWN(Address); - Offset.QuadPart = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress - + MemoryArea->Data.SectionData.ViewOffset.QuadPart; + Offset.QuadPart = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress + + MemoryArea->Data.SectionData.ViewOffset.QuadPart; - /* - * Get the segment and section. - */ - Segment = MemoryArea->Data.SectionData.Segment; - Section = MemoryArea->Data.SectionData.Section; - IsImageSection = Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE; + /* + * Get the segment and section. + */ + Segment = MemoryArea->Data.SectionData.Segment; + Section = MemoryArea->Data.SectionData.Section; + IsImageSection = Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE; - FileObject = Section->FileObject; - DirectMapped = FALSE; - if (FileObject != NULL && - !(Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED)) - { - SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap; + FileObject = Section->FileObject; + DirectMapped = FALSE; + if (FileObject != NULL && + !(Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED)) + { + SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap; - /* - * If the file system is letting us go directly to the cache and the - * memory area was mapped at an offset in the file which is page aligned - * then note this is a direct mapped page. - */ - if (((Offset.QuadPart + Segment->Image.FileOffset) % PAGE_SIZE) == 0 && - (Offset.QuadPart + PAGE_SIZE <= Segment->RawLength.QuadPart || !IsImageSection)) - { - DirectMapped = TRUE; - } - } + /* + * If the file system is letting us go directly to the cache and the + * memory area was mapped at an offset in the file which is page aligned + * then note this is a direct mapped page. + */ + if (((Offset.QuadPart + Segment->Image.FileOffset) % PAGE_SIZE) == 0 && + (Offset.QuadPart + PAGE_SIZE <= Segment->RawLength.QuadPart || !IsImageSection)) + { + DirectMapped = TRUE; + } + } - /* - * This should never happen since mappings of physical memory are never - * placed in the rmap lists. - */ - if (Section->AllocationAttributes & SEC_PHYSICALMEMORY) - { - DPRINT1("Trying to write back page from physical memory mapped at %p " - "process %p\n", Address, - Process ? Process->UniqueProcessId : 0); - KeBugCheck(MEMORY_MANAGEMENT); - } + /* + * This should never happen since mappings of physical memory are never + * placed in the rmap lists. + */ + if (Section->AllocationAttributes & SEC_PHYSICALMEMORY) + { + DPRINT1("Trying to write back page from physical memory mapped at %p " + "process %p\n", Address, + Process ? Process->UniqueProcessId : 0); + KeBugCheck(MEMORY_MANAGEMENT); + } - /* - * Get the section segment entry and the physical address. - */ - Entry = MmGetPageEntrySectionSegment(Segment, &Offset); - if (!MmIsPagePresent(Process, Address)) - { - DPRINT1("Trying to page out not-present page at (%p,0x%p).\n", - Process ? Process->UniqueProcessId : 0, Address); - KeBugCheck(MEMORY_MANAGEMENT); - } - Page = MmGetPfnForProcess(Process, Address); - SwapEntry = MmGetSavedSwapEntryPage(Page); + /* + * Get the section segment entry and the physical address. + */ + Entry = MmGetPageEntrySectionSegment(Segment, &Offset); + if (!MmIsPagePresent(Process, Address)) + { + DPRINT1("Trying to page out not-present page at (%p,0x%p).\n", + Process ? Process->UniqueProcessId : 0, Address); + KeBugCheck(MEMORY_MANAGEMENT); + } + Page = MmGetPfnForProcess(Process, Address); + SwapEntry = MmGetSavedSwapEntryPage(Page); - /* - * Check for a private (COWed) page. - */ - if (Segment->Image.Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA || - IS_SWAP_FROM_SSE(Entry) || - PFN_FROM_SSE(Entry) != Page) - { - Private = TRUE; - } - else - { - Private = FALSE; - } + /* + * Check for a private (COWed) page. + */ + if (Segment->Image.Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA || + IS_SWAP_FROM_SSE(Entry) || + PFN_FROM_SSE(Entry) != Page) + { + Private = TRUE; + } + else + { + Private = FALSE; + } - /* - * Speculatively set all mappings of the page to clean. - */ - MmSetCleanAllRmaps(Page); + /* + * Speculatively set all mappings of the page to clean. + */ + MmSetCleanAllRmaps(Page); - /* - * If this page was direct mapped from the cache then the cache manager - * will take care of writing it back to disk. - */ - if (DirectMapped && !Private) - { - //LARGE_INTEGER SOffset; - ASSERT(SwapEntry == 0); - //SOffset.QuadPart = Offset.QuadPart + Segment->Image.FileOffset; + /* + * If this page was direct mapped from the cache then the cache manager + * will take care of writing it back to disk. + */ + if (DirectMapped && !Private) + { + //LARGE_INTEGER SOffset; + ASSERT(SwapEntry == 0); + //SOffset.QuadPart = Offset.QuadPart + Segment->Image.FileOffset; #ifndef NEWCC - CcRosMarkDirtyVacb(SharedCacheMap, Offset.QuadPart); + CcRosMarkDirtyVacb(SharedCacheMap, Offset.QuadPart); #endif - MmLockSectionSegment(Segment); - MmSetPageEntrySectionSegment(Segment, &Offset, PageEntry); - MmUnlockSectionSegment(Segment); - MiSetPageEvent(NULL, NULL); - return(STATUS_SUCCESS); - } + MmLockSectionSegment(Segment); + MmSetPageEntrySectionSegment(Segment, &Offset, PageEntry); + MmUnlockSectionSegment(Segment); + MiSetPageEvent(NULL, NULL); + return(STATUS_SUCCESS); + } - /* - * If necessary, allocate an entry in the paging file for this page - */ - if (SwapEntry == 0) - { - SwapEntry = MmAllocSwapPage(); - if (SwapEntry == 0) - { - MmSetDirtyAllRmaps(Page); - MiSetPageEvent(NULL, NULL); - return(STATUS_PAGEFILE_QUOTA); - } - MmSetSavedSwapEntryPage(Page, SwapEntry); - } + /* + * If necessary, allocate an entry in the paging file for this page + */ + if (SwapEntry == 0) + { + SwapEntry = MmAllocSwapPage(); + if (SwapEntry == 0) + { + MmSetDirtyAllRmaps(Page); + MiSetPageEvent(NULL, NULL); + return(STATUS_PAGEFILE_QUOTA); + } + MmSetSavedSwapEntryPage(Page, SwapEntry); + } - /* - * Write the page to the pagefile - */ - Status = MmWriteToSwapPage(SwapEntry, Page); - if (!NT_SUCCESS(Status)) - { - DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n", - Status); - MmSetDirtyAllRmaps(Page); - MiSetPageEvent(NULL, NULL); - return(STATUS_UNSUCCESSFUL); - } + /* + * Write the page to the pagefile + */ + Status = MmWriteToSwapPage(SwapEntry, Page); + if (!NT_SUCCESS(Status)) + { + DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n", + Status); + MmSetDirtyAllRmaps(Page); + MiSetPageEvent(NULL, NULL); + return(STATUS_UNSUCCESSFUL); + } - /* - * Otherwise we have succeeded. - */ - DPRINT("MM: Wrote section page 0x%.8X to swap!\n", Page << PAGE_SHIFT); - MiSetPageEvent(NULL, NULL); - return(STATUS_SUCCESS); + /* + * Otherwise we have succeeded. + */ + DPRINT("MM: Wrote section page 0x%.8X to swap!\n", Page << PAGE_SHIFT); + MiSetPageEvent(NULL, NULL); + return(STATUS_SUCCESS); } static VOID @@ -2427,76 +2429,78 @@ MmAlterViewAttributes(PMMSUPPORT AddressSpace, ULONG NewType, ULONG NewProtect) { - PMEMORY_AREA MemoryArea; - PMM_SECTION_SEGMENT Segment; - BOOLEAN DoCOW = FALSE; - ULONG i; - PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace); + PMEMORY_AREA MemoryArea; + PMM_SECTION_SEGMENT Segment; + BOOLEAN DoCOW = FALSE; + ULONG i; + PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace); - MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, BaseAddress); - ASSERT(MemoryArea != NULL); - Segment = MemoryArea->Data.SectionData.Segment; - MmLockSectionSegment(Segment); + MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, BaseAddress); + ASSERT(MemoryArea != NULL); + Segment = MemoryArea->Data.SectionData.Segment; + MmLockSectionSegment(Segment); - if ((Segment->WriteCopy) && - (NewProtect == PAGE_READWRITE || NewProtect == PAGE_EXECUTE_READWRITE)) - { - DoCOW = TRUE; - } + if ((Segment->WriteCopy) && + (NewProtect == PAGE_READWRITE || NewProtect == PAGE_EXECUTE_READWRITE)) + { + DoCOW = TRUE; + } - if (OldProtect != NewProtect) - { - for (i = 0; i < PAGE_ROUND_UP(RegionSize) / PAGE_SIZE; i++) - { - SWAPENTRY SwapEntry; - PVOID Address = (char*)BaseAddress + (i * PAGE_SIZE); - ULONG Protect = NewProtect; + if (OldProtect != NewProtect) + { + for (i = 0; i < PAGE_ROUND_UP(RegionSize) / PAGE_SIZE; i++) + { + SWAPENTRY SwapEntry; + PVOID Address = (char*)BaseAddress + (i * PAGE_SIZE); + ULONG Protect = NewProtect; - /* Wait for a wait entry to disappear */ - do { - MmGetPageFileMapping(Process, Address, &SwapEntry); - if (SwapEntry != MM_WAIT_ENTRY) - break; - MiWaitForPageEvent(Process, Address); - } while (TRUE); - - /* - * If we doing COW for this segment then check if the page is - * already private. - */ - if (DoCOW && MmIsPagePresent(Process, Address)) - { - LARGE_INTEGER Offset; - ULONG_PTR Entry; - PFN_NUMBER Page; - - Offset.QuadPart = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress - + MemoryArea->Data.SectionData.ViewOffset.QuadPart; - Entry = MmGetPageEntrySectionSegment(Segment, &Offset); - /* - * An MM_WAIT_ENTRY is ok in this case... It'll just count as - * IS_SWAP_FROM_SSE and we'll do the right thing. - */ - Page = MmGetPfnForProcess(Process, Address); - - Protect = PAGE_READONLY; - if (Segment->Image.Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA || - IS_SWAP_FROM_SSE(Entry) || - PFN_FROM_SSE(Entry) != Page) + /* Wait for a wait entry to disappear */ + do { - Protect = NewProtect; + MmGetPageFileMapping(Process, Address, &SwapEntry); + if (SwapEntry != MM_WAIT_ENTRY) + break; + MiWaitForPageEvent(Process, Address); } - } + while (TRUE); - if (MmIsPagePresent(Process, Address) || MmIsDisabledPage(Process, Address)) - { - MmSetPageProtect(Process, Address, - Protect); - } - } - } + /* + * If we doing COW for this segment then check if the page is + * already private. + */ + if (DoCOW && MmIsPagePresent(Process, Address)) + { + LARGE_INTEGER Offset; + ULONG_PTR Entry; + PFN_NUMBER Page; - MmUnlockSectionSegment(Segment); + Offset.QuadPart = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress + + MemoryArea->Data.SectionData.ViewOffset.QuadPart; + Entry = MmGetPageEntrySectionSegment(Segment, &Offset); + /* + * An MM_WAIT_ENTRY is ok in this case... It'll just count as + * IS_SWAP_FROM_SSE and we'll do the right thing. + */ + Page = MmGetPfnForProcess(Process, Address); + + Protect = PAGE_READONLY; + if (Segment->Image.Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA || + IS_SWAP_FROM_SSE(Entry) || + PFN_FROM_SSE(Entry) != Page) + { + Protect = NewProtect; + } + } + + if (MmIsPagePresent(Process, Address) || MmIsDisabledPage(Process, Address)) + { + MmSetPageProtect(Process, Address, + Protect); + } + } + } + + MmUnlockSectionSegment(Segment); } NTSTATUS @@ -2508,32 +2512,32 @@ MmProtectSectionView(PMMSUPPORT AddressSpace, ULONG Protect, PULONG OldProtect) { - PMM_REGION Region; - NTSTATUS Status; - ULONG_PTR MaxLength; + PMM_REGION Region; + NTSTATUS Status; + ULONG_PTR MaxLength; - MaxLength = (ULONG_PTR)MemoryArea->EndingAddress - (ULONG_PTR)BaseAddress; - if (Length > MaxLength) - Length = (ULONG)MaxLength; + MaxLength = (ULONG_PTR)MemoryArea->EndingAddress - (ULONG_PTR)BaseAddress; + if (Length > MaxLength) + Length = (ULONG)MaxLength; - Region = MmFindRegion(MemoryArea->StartingAddress, - &MemoryArea->Data.SectionData.RegionListHead, - BaseAddress, NULL); - ASSERT(Region != NULL); - - if ((MemoryArea->Flags & SEC_NO_CHANGE) && - Region->Protect != Protect) - { - return STATUS_INVALID_PAGE_PROTECTION; - } - - *OldProtect = Region->Protect; - Status = MmAlterRegion(AddressSpace, MemoryArea->StartingAddress, + Region = MmFindRegion(MemoryArea->StartingAddress, &MemoryArea->Data.SectionData.RegionListHead, - BaseAddress, Length, Region->Type, Protect, - MmAlterViewAttributes); + BaseAddress, NULL); + ASSERT(Region != NULL); - return(Status); + if ((MemoryArea->Flags & SEC_NO_CHANGE) && + Region->Protect != Protect) + { + return STATUS_INVALID_PAGE_PROTECTION; + } + + *OldProtect = Region->Protect; + Status = MmAlterRegion(AddressSpace, MemoryArea->StartingAddress, + &MemoryArea->Data.SectionData.RegionListHead, + BaseAddress, Length, Region->Type, Protect, + MmAlterViewAttributes); + + return(Status); } NTSTATUS NTAPI @@ -2542,87 +2546,87 @@ MmQuerySectionView(PMEMORY_AREA MemoryArea, PMEMORY_BASIC_INFORMATION Info, PSIZE_T ResultLength) { - PMM_REGION Region; - PVOID RegionBaseAddress; - PROS_SECTION_OBJECT Section; - PMM_SECTION_SEGMENT Segment; + PMM_REGION Region; + PVOID RegionBaseAddress; + PROS_SECTION_OBJECT Section; + PMM_SECTION_SEGMENT Segment; - Region = MmFindRegion((PVOID)MemoryArea->StartingAddress, - &MemoryArea->Data.SectionData.RegionListHead, - Address, &RegionBaseAddress); - if (Region == NULL) - { - return STATUS_UNSUCCESSFUL; - } + Region = MmFindRegion((PVOID)MemoryArea->StartingAddress, + &MemoryArea->Data.SectionData.RegionListHead, + Address, &RegionBaseAddress); + if (Region == NULL) + { + return STATUS_UNSUCCESSFUL; + } - Section = MemoryArea->Data.SectionData.Section; - if (Section->AllocationAttributes & SEC_IMAGE) - { - Segment = MemoryArea->Data.SectionData.Segment; - Info->AllocationBase = (PUCHAR)MemoryArea->StartingAddress - Segment->Image.VirtualAddress; - Info->Type = MEM_IMAGE; - } - else - { - Info->AllocationBase = MemoryArea->StartingAddress; - Info->Type = MEM_MAPPED; - } - Info->BaseAddress = RegionBaseAddress; - Info->AllocationProtect = MemoryArea->Protect; - Info->RegionSize = Region->Length; - Info->State = MEM_COMMIT; - Info->Protect = Region->Protect; + Section = MemoryArea->Data.SectionData.Section; + if (Section->AllocationAttributes & SEC_IMAGE) + { + Segment = MemoryArea->Data.SectionData.Segment; + Info->AllocationBase = (PUCHAR)MemoryArea->StartingAddress - Segment->Image.VirtualAddress; + Info->Type = MEM_IMAGE; + } + else + { + Info->AllocationBase = MemoryArea->StartingAddress; + Info->Type = MEM_MAPPED; + } + Info->BaseAddress = RegionBaseAddress; + Info->AllocationProtect = MemoryArea->Protect; + Info->RegionSize = Region->Length; + Info->State = MEM_COMMIT; + Info->Protect = Region->Protect; - *ResultLength = sizeof(MEMORY_BASIC_INFORMATION); - return(STATUS_SUCCESS); + *ResultLength = sizeof(MEMORY_BASIC_INFORMATION); + return(STATUS_SUCCESS); } VOID NTAPI MmpFreePageFileSegment(PMM_SECTION_SEGMENT Segment) { - ULONG Length; - LARGE_INTEGER Offset; - ULONG_PTR Entry; - SWAPENTRY SavedSwapEntry; - PFN_NUMBER Page; + ULONG Length; + LARGE_INTEGER Offset; + ULONG_PTR Entry; + SWAPENTRY SavedSwapEntry; + PFN_NUMBER Page; - Page = 0; + Page = 0; - MmLockSectionSegment(Segment); + MmLockSectionSegment(Segment); - Length = PAGE_ROUND_UP(Segment->Length.QuadPart); - for (Offset.QuadPart = 0; Offset.QuadPart < Length; Offset.QuadPart += PAGE_SIZE) - { - Entry = MmGetPageEntrySectionSegment(Segment, &Offset); - if (Entry) - { - MmSetPageEntrySectionSegment(Segment, &Offset, 0); - if (IS_SWAP_FROM_SSE(Entry)) - { - MmFreeSwapPage(SWAPENTRY_FROM_SSE(Entry)); - } - else - { - Page = PFN_FROM_SSE(Entry); - SavedSwapEntry = MmGetSavedSwapEntryPage(Page); - if (SavedSwapEntry != 0) + Length = PAGE_ROUND_UP(Segment->Length.QuadPart); + for (Offset.QuadPart = 0; Offset.QuadPart < Length; Offset.QuadPart += PAGE_SIZE) + { + Entry = MmGetPageEntrySectionSegment(Segment, &Offset); + if (Entry) + { + MmSetPageEntrySectionSegment(Segment, &Offset, 0); + if (IS_SWAP_FROM_SSE(Entry)) { - MmSetSavedSwapEntryPage(Page, 0); - MmFreeSwapPage(SavedSwapEntry); + MmFreeSwapPage(SWAPENTRY_FROM_SSE(Entry)); } - MmReleasePageMemoryConsumer(MC_USER, Page); - } - } - } + else + { + Page = PFN_FROM_SSE(Entry); + SavedSwapEntry = MmGetSavedSwapEntryPage(Page); + if (SavedSwapEntry != 0) + { + MmSetSavedSwapEntryPage(Page, 0); + MmFreeSwapPage(SavedSwapEntry); + } + MmReleasePageMemoryConsumer(MC_USER, Page); + } + } + } - MmUnlockSectionSegment(Segment); + MmUnlockSectionSegment(Segment); } VOID NTAPI MmpDeleteSection(PVOID ObjectBody) { - PROS_SECTION_OBJECT Section = (PROS_SECTION_OBJECT)ObjectBody; + PROS_SECTION_OBJECT Section = (PROS_SECTION_OBJECT)ObjectBody; /* Check if it's an ARM3, or ReactOS section */ if (!MiIsRosSectionObject(Section)) @@ -2631,91 +2635,91 @@ MmpDeleteSection(PVOID ObjectBody) return; } - DPRINT("MmpDeleteSection(ObjectBody %p)\n", ObjectBody); - if (Section->AllocationAttributes & SEC_IMAGE) - { - ULONG i; - ULONG NrSegments; - ULONG RefCount; - PMM_SECTION_SEGMENT SectionSegments; + DPRINT("MmpDeleteSection(ObjectBody %p)\n", ObjectBody); + if (Section->AllocationAttributes & SEC_IMAGE) + { + ULONG i; + ULONG NrSegments; + ULONG RefCount; + PMM_SECTION_SEGMENT SectionSegments; - /* - * NOTE: Section->ImageSection can be NULL for short time - * during the section creating. If we fail for some reason - * until the image section is properly initialized we shouldn't - * process further here. - */ - if (Section->ImageSection == NULL) - return; + /* + * NOTE: Section->ImageSection can be NULL for short time + * during the section creating. If we fail for some reason + * until the image section is properly initialized we shouldn't + * process further here. + */ + if (Section->ImageSection == NULL) + return; - SectionSegments = Section->ImageSection->Segments; - NrSegments = Section->ImageSection->NrSegments; + SectionSegments = Section->ImageSection->Segments; + NrSegments = Section->ImageSection->NrSegments; - for (i = 0; i < NrSegments; i++) - { - if (SectionSegments[i].Image.Characteristics & IMAGE_SCN_MEM_SHARED) - { - MmLockSectionSegment(&SectionSegments[i]); - } - RefCount = InterlockedDecrementUL(&SectionSegments[i].ReferenceCount); - if (SectionSegments[i].Image.Characteristics & IMAGE_SCN_MEM_SHARED) - { - MmUnlockSectionSegment(&SectionSegments[i]); - if (RefCount == 0) + for (i = 0; i < NrSegments; i++) + { + if (SectionSegments[i].Image.Characteristics & IMAGE_SCN_MEM_SHARED) { - MmpFreePageFileSegment(&SectionSegments[i]); + MmLockSectionSegment(&SectionSegments[i]); } - } - } - } + RefCount = InterlockedDecrementUL(&SectionSegments[i].ReferenceCount); + if (SectionSegments[i].Image.Characteristics & IMAGE_SCN_MEM_SHARED) + { + MmUnlockSectionSegment(&SectionSegments[i]); + if (RefCount == 0) + { + MmpFreePageFileSegment(&SectionSegments[i]); + } + } + } + } #ifdef NEWCC - else if (Section->Segment && Section->Segment->Flags & MM_DATAFILE_SEGMENT) - { - ULONG RefCount = 0; - PMM_SECTION_SEGMENT Segment = Section->Segment; + else if (Section->Segment && Section->Segment->Flags & MM_DATAFILE_SEGMENT) + { + ULONG RefCount = 0; + PMM_SECTION_SEGMENT Segment = Section->Segment; - if (Segment && - (RefCount = InterlockedDecrementUL(&Segment->ReferenceCount)) == 0) - { - DPRINT("Freeing section segment\n"); - Section->Segment = NULL; - MmFinalizeSegment(Segment); - } - else - { - DPRINT("RefCount %d\n", RefCount); - } - } + if (Segment && + (RefCount = InterlockedDecrementUL(&Segment->ReferenceCount)) == 0) + { + DPRINT("Freeing section segment\n"); + Section->Segment = NULL; + MmFinalizeSegment(Segment); + } + else + { + DPRINT("RefCount %d\n", RefCount); + } + } #endif - else - { - /* - * NOTE: Section->Segment can be NULL for short time - * during the section creating. - */ - if (Section->Segment == NULL) - return; + else + { + /* + * NOTE: Section->Segment can be NULL for short time + * during the section creating. + */ + if (Section->Segment == NULL) + return; - if (Section->Segment->Flags & MM_PAGEFILE_SEGMENT) - { - MmpFreePageFileSegment(Section->Segment); - MmFreePageTablesSectionSegment(Section->Segment, NULL); - ExFreePool(Section->Segment); - Section->Segment = NULL; - } - else - { - (void)InterlockedDecrementUL(&Section->Segment->ReferenceCount); - } - } - if (Section->FileObject != NULL) - { + if (Section->Segment->Flags & MM_PAGEFILE_SEGMENT) + { + MmpFreePageFileSegment(Section->Segment); + MmFreePageTablesSectionSegment(Section->Segment, NULL); + ExFreePool(Section->Segment); + Section->Segment = NULL; + } + else + { + (void)InterlockedDecrementUL(&Section->Segment->ReferenceCount); + } + } + if (Section->FileObject != NULL) + { #ifndef NEWCC - CcRosDereferenceCache(Section->FileObject); + CcRosDereferenceCache(Section->FileObject); #endif - ObDereferenceObject(Section->FileObject); - Section->FileObject = NULL; - } + ObDereferenceObject(Section->FileObject); + Section->FileObject = NULL; + } } VOID NTAPI @@ -2733,50 +2737,50 @@ INIT_FUNCTION NTAPI MmCreatePhysicalMemorySection(VOID) { - PROS_SECTION_OBJECT PhysSection; - NTSTATUS Status; - OBJECT_ATTRIBUTES Obj; - UNICODE_STRING Name = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory"); - LARGE_INTEGER SectionSize; - HANDLE Handle; + PROS_SECTION_OBJECT PhysSection; + NTSTATUS Status; + OBJECT_ATTRIBUTES Obj; + UNICODE_STRING Name = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory"); + LARGE_INTEGER SectionSize; + HANDLE Handle; - /* - * Create the section mapping physical memory - */ - SectionSize.QuadPart = 0xFFFFFFFF; - InitializeObjectAttributes(&Obj, - &Name, - OBJ_PERMANENT, - NULL, - NULL); - Status = MmCreateSection((PVOID)&PhysSection, - SECTION_ALL_ACCESS, - &Obj, - &SectionSize, - PAGE_EXECUTE_READWRITE, - SEC_PHYSICALMEMORY, + /* + * Create the section mapping physical memory + */ + SectionSize.QuadPart = 0xFFFFFFFF; + InitializeObjectAttributes(&Obj, + &Name, + OBJ_PERMANENT, + NULL, + NULL); + Status = MmCreateSection((PVOID)&PhysSection, + SECTION_ALL_ACCESS, + &Obj, + &SectionSize, + PAGE_EXECUTE_READWRITE, + SEC_PHYSICALMEMORY, + NULL, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to create PhysicalMemory section\n"); + KeBugCheck(MEMORY_MANAGEMENT); + } + Status = ObInsertObject(PhysSection, NULL, - NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to create PhysicalMemory section\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - Status = ObInsertObject(PhysSection, - NULL, - SECTION_ALL_ACCESS, - 0, - NULL, - &Handle); - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(PhysSection); - } - ObCloseHandle(Handle, KernelMode); - PhysSection->AllocationAttributes |= SEC_PHYSICALMEMORY; - PhysSection->Segment->Flags &= ~MM_PAGEFILE_SEGMENT; + SECTION_ALL_ACCESS, + 0, + NULL, + &Handle); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(PhysSection); + } + ObCloseHandle(Handle, KernelMode); + PhysSection->AllocationAttributes |= SEC_PHYSICALMEMORY; + PhysSection->Segment->Flags &= ~MM_PAGEFILE_SEGMENT; - return(STATUS_SUCCESS); + return(STATUS_SUCCESS); } NTSTATUS @@ -2784,32 +2788,32 @@ INIT_FUNCTION NTAPI MmInitSectionImplementation(VOID) { - OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; - UNICODE_STRING Name; + OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; + UNICODE_STRING Name; - DPRINT("Creating Section Object Type\n"); + DPRINT("Creating Section Object Type\n"); - /* Initialize the section based root */ - ASSERT(MmSectionBasedRoot.NumberGenericTableElements == 0); - MmSectionBasedRoot.BalancedRoot.u1.Parent = &MmSectionBasedRoot.BalancedRoot; + /* Initialize the section based root */ + ASSERT(MmSectionBasedRoot.NumberGenericTableElements == 0); + MmSectionBasedRoot.BalancedRoot.u1.Parent = &MmSectionBasedRoot.BalancedRoot; - /* Initialize the Section object type */ - RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); - RtlInitUnicodeString(&Name, L"Section"); - ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); - ObjectTypeInitializer.DefaultPagedPoolCharge = sizeof(ROS_SECTION_OBJECT); - ObjectTypeInitializer.PoolType = PagedPool; - ObjectTypeInitializer.UseDefaultObject = TRUE; - ObjectTypeInitializer.GenericMapping = MmpSectionMapping; - ObjectTypeInitializer.DeleteProcedure = MmpDeleteSection; - ObjectTypeInitializer.CloseProcedure = MmpCloseSection; - ObjectTypeInitializer.ValidAccessMask = SECTION_ALL_ACCESS; - ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK; - ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &MmSectionObjectType); + /* Initialize the Section object type */ + RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); + RtlInitUnicodeString(&Name, L"Section"); + ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); + ObjectTypeInitializer.DefaultPagedPoolCharge = sizeof(ROS_SECTION_OBJECT); + ObjectTypeInitializer.PoolType = PagedPool; + ObjectTypeInitializer.UseDefaultObject = TRUE; + ObjectTypeInitializer.GenericMapping = MmpSectionMapping; + ObjectTypeInitializer.DeleteProcedure = MmpDeleteSection; + ObjectTypeInitializer.CloseProcedure = MmpCloseSection; + ObjectTypeInitializer.ValidAccessMask = SECTION_ALL_ACCESS; + ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK; + ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &MmSectionObjectType); - MmCreatePhysicalMemorySection(); + MmCreatePhysicalMemorySection(); - return(STATUS_SUCCESS); + return(STATUS_SUCCESS); } NTSTATUS @@ -2824,67 +2828,67 @@ MmCreatePageFileSection(PROS_SECTION_OBJECT *SectionObject, * Create a section which is backed by the pagefile */ { - LARGE_INTEGER MaximumSize; - PROS_SECTION_OBJECT Section; - PMM_SECTION_SEGMENT Segment; - NTSTATUS Status; + LARGE_INTEGER MaximumSize; + PROS_SECTION_OBJECT Section; + PMM_SECTION_SEGMENT Segment; + NTSTATUS Status; - if (UMaximumSize == NULL) - { - DPRINT1("MmCreatePageFileSection: (UMaximumSize == NULL)\n"); - return(STATUS_INVALID_PARAMETER); - } - MaximumSize = *UMaximumSize; + if (UMaximumSize == NULL) + { + DPRINT1("MmCreatePageFileSection: (UMaximumSize == NULL)\n"); + return(STATUS_INVALID_PARAMETER); + } + MaximumSize = *UMaximumSize; - /* - * Create the section - */ - Status = ObCreateObject(ExGetPreviousMode(), - MmSectionObjectType, - ObjectAttributes, - ExGetPreviousMode(), - NULL, - sizeof(ROS_SECTION_OBJECT), - 0, - 0, - (PVOID*)(PVOID)&Section); - if (!NT_SUCCESS(Status)) - { - DPRINT1("MmCreatePageFileSection: failed to create object (0x%lx)\n", Status); - return(Status); - } + /* + * Create the section + */ + Status = ObCreateObject(ExGetPreviousMode(), + MmSectionObjectType, + ObjectAttributes, + ExGetPreviousMode(), + NULL, + sizeof(ROS_SECTION_OBJECT), + 0, + 0, + (PVOID*)(PVOID)&Section); + if (!NT_SUCCESS(Status)) + { + DPRINT1("MmCreatePageFileSection: failed to create object (0x%lx)\n", Status); + return(Status); + } - /* - * Initialize it - */ - RtlZeroMemory(Section, sizeof(ROS_SECTION_OBJECT)); - Section->Type = 'SC'; - Section->Size = 'TN'; - Section->SectionPageProtection = SectionPageProtection; - Section->AllocationAttributes = AllocationAttributes; - Section->MaximumSize = MaximumSize; - Segment = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_SECTION_SEGMENT), - TAG_MM_SECTION_SEGMENT); - if (Segment == NULL) - { - ObDereferenceObject(Section); - return(STATUS_NO_MEMORY); - } - RtlZeroMemory(Segment, sizeof(MM_SECTION_SEGMENT)); - Section->Segment = Segment; - Segment->ReferenceCount = 1; - ExInitializeFastMutex(&Segment->Lock); - Segment->Image.FileOffset = 0; - Segment->Protection = SectionPageProtection; - Segment->RawLength.QuadPart = MaximumSize.u.LowPart; - Segment->Length.QuadPart = PAGE_ROUND_UP(MaximumSize.u.LowPart); - Segment->Flags = MM_PAGEFILE_SEGMENT; - Segment->WriteCopy = FALSE; - Segment->Image.VirtualAddress = 0; - Segment->Image.Characteristics = 0; - *SectionObject = Section; - MiInitializeSectionPageTable(Segment); - return(STATUS_SUCCESS); + /* + * Initialize it + */ + RtlZeroMemory(Section, sizeof(ROS_SECTION_OBJECT)); + Section->Type = 'SC'; + Section->Size = 'TN'; + Section->SectionPageProtection = SectionPageProtection; + Section->AllocationAttributes = AllocationAttributes; + Section->MaximumSize = MaximumSize; + Segment = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_SECTION_SEGMENT), + TAG_MM_SECTION_SEGMENT); + if (Segment == NULL) + { + ObDereferenceObject(Section); + return(STATUS_NO_MEMORY); + } + RtlZeroMemory(Segment, sizeof(MM_SECTION_SEGMENT)); + Section->Segment = Segment; + Segment->ReferenceCount = 1; + ExInitializeFastMutex(&Segment->Lock); + Segment->Image.FileOffset = 0; + Segment->Protection = SectionPageProtection; + Segment->RawLength.QuadPart = MaximumSize.u.LowPart; + Segment->Length.QuadPart = PAGE_ROUND_UP(MaximumSize.u.LowPart); + Segment->Flags = MM_PAGEFILE_SEGMENT; + Segment->WriteCopy = FALSE; + Segment->Image.VirtualAddress = 0; + Segment->Image.Characteristics = 0; + *SectionObject = Section; + MiInitializeSectionPageTable(Segment); + return(STATUS_SUCCESS); } NTSTATUS @@ -2900,228 +2904,228 @@ MmCreateDataFileSection(PROS_SECTION_OBJECT *SectionObject, * Create a section backed by a data file */ { - PROS_SECTION_OBJECT Section; - NTSTATUS Status; - LARGE_INTEGER MaximumSize; - PFILE_OBJECT FileObject; - PMM_SECTION_SEGMENT Segment; - ULONG FileAccess; - IO_STATUS_BLOCK Iosb; - LARGE_INTEGER Offset; - CHAR Buffer; - FILE_STANDARD_INFORMATION FileInfo; - ULONG Length; + PROS_SECTION_OBJECT Section; + NTSTATUS Status; + LARGE_INTEGER MaximumSize; + PFILE_OBJECT FileObject; + PMM_SECTION_SEGMENT Segment; + ULONG FileAccess; + IO_STATUS_BLOCK Iosb; + LARGE_INTEGER Offset; + CHAR Buffer; + FILE_STANDARD_INFORMATION FileInfo; + ULONG Length; - /* - * Create the section - */ - Status = ObCreateObject(ExGetPreviousMode(), - MmSectionObjectType, - ObjectAttributes, - ExGetPreviousMode(), - NULL, - sizeof(ROS_SECTION_OBJECT), - 0, - 0, - (PVOID*)&Section); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - /* - * Initialize it - */ - RtlZeroMemory(Section, sizeof(ROS_SECTION_OBJECT)); - Section->Type = 'SC'; - Section->Size = 'TN'; - Section->SectionPageProtection = SectionPageProtection; - Section->AllocationAttributes = AllocationAttributes; + /* + * Create the section + */ + Status = ObCreateObject(ExGetPreviousMode(), + MmSectionObjectType, + ObjectAttributes, + ExGetPreviousMode(), + NULL, + sizeof(ROS_SECTION_OBJECT), + 0, + 0, + (PVOID*)&Section); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + /* + * Initialize it + */ + RtlZeroMemory(Section, sizeof(ROS_SECTION_OBJECT)); + Section->Type = 'SC'; + Section->Size = 'TN'; + Section->SectionPageProtection = SectionPageProtection; + Section->AllocationAttributes = AllocationAttributes; - /* - * Reference the file handle - */ + /* + * Reference the file handle + */ FileAccess = MiArm3GetCorrectFileAccessMask(SectionPageProtection); Status = ObReferenceObjectByHandle(FileHandle, - FileAccess, - IoFileObjectType, - ExGetPreviousMode(), - (PVOID*)(PVOID)&FileObject, - NULL); - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(Section); - return(Status); - } + FileAccess, + IoFileObjectType, + ExGetPreviousMode(), + (PVOID*)(PVOID)&FileObject, + NULL); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(Section); + return(Status); + } - /* - * FIXME: This is propably not entirely correct. We can't look into - * the standard FCB header because it might not be initialized yet - * (as in case of the EXT2FS driver by Manoj Paul Joseph where the - * standard file information is filled on first request). - */ - Status = IoQueryFileInformation(FileObject, - FileStandardInformation, - sizeof(FILE_STANDARD_INFORMATION), - &FileInfo, - &Length); - Iosb.Information = Length; - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(Section); - ObDereferenceObject(FileObject); - return Status; - } + /* + * FIXME: This is propably not entirely correct. We can't look into + * the standard FCB header because it might not be initialized yet + * (as in case of the EXT2FS driver by Manoj Paul Joseph where the + * standard file information is filled on first request). + */ + Status = IoQueryFileInformation(FileObject, + FileStandardInformation, + sizeof(FILE_STANDARD_INFORMATION), + &FileInfo, + &Length); + Iosb.Information = Length; + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(Section); + ObDereferenceObject(FileObject); + return Status; + } - /* - * FIXME: Revise this once a locking order for file size changes is - * decided - */ - if ((UMaximumSize != NULL) && (UMaximumSize->QuadPart != 0)) - { - MaximumSize = *UMaximumSize; - } - else - { - MaximumSize = FileInfo.EndOfFile; - /* Mapping zero-sized files isn't allowed. */ - if (MaximumSize.QuadPart == 0) - { - ObDereferenceObject(Section); - ObDereferenceObject(FileObject); - return STATUS_FILE_INVALID; - } - } + /* + * FIXME: Revise this once a locking order for file size changes is + * decided + */ + if ((UMaximumSize != NULL) && (UMaximumSize->QuadPart != 0)) + { + MaximumSize = *UMaximumSize; + } + else + { + MaximumSize = FileInfo.EndOfFile; + /* Mapping zero-sized files isn't allowed. */ + if (MaximumSize.QuadPart == 0) + { + ObDereferenceObject(Section); + ObDereferenceObject(FileObject); + return STATUS_FILE_INVALID; + } + } - if (MaximumSize.QuadPart > FileInfo.EndOfFile.QuadPart) - { - Status = IoSetInformation(FileObject, - FileAllocationInformation, - sizeof(LARGE_INTEGER), - &MaximumSize); - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(Section); - ObDereferenceObject(FileObject); - return(STATUS_SECTION_NOT_EXTENDED); - } - } + if (MaximumSize.QuadPart > FileInfo.EndOfFile.QuadPart) + { + Status = IoSetInformation(FileObject, + FileAllocationInformation, + sizeof(LARGE_INTEGER), + &MaximumSize); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(Section); + ObDereferenceObject(FileObject); + return(STATUS_SECTION_NOT_EXTENDED); + } + } - if (FileObject->SectionObjectPointer == NULL || - FileObject->SectionObjectPointer->SharedCacheMap == NULL) - { - /* - * Read a bit so caching is initiated for the file object. - * This is only needed because MiReadPage currently cannot - * handle non-cached streams. - */ - Offset.QuadPart = 0; - Status = ZwReadFile(FileHandle, - NULL, - NULL, - NULL, - &Iosb, - &Buffer, - sizeof (Buffer), - &Offset, - 0); - if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE)) - { - ObDereferenceObject(Section); - ObDereferenceObject(FileObject); - return(Status); - } - if (FileObject->SectionObjectPointer == NULL || + if (FileObject->SectionObjectPointer == NULL || FileObject->SectionObjectPointer->SharedCacheMap == NULL) - { - /* FIXME: handle this situation */ - ObDereferenceObject(Section); - ObDereferenceObject(FileObject); - return STATUS_INVALID_PARAMETER; - } - } + { + /* + * Read a bit so caching is initiated for the file object. + * This is only needed because MiReadPage currently cannot + * handle non-cached streams. + */ + Offset.QuadPart = 0; + Status = ZwReadFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + &Buffer, + sizeof (Buffer), + &Offset, + 0); + if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE)) + { + ObDereferenceObject(Section); + ObDereferenceObject(FileObject); + return(Status); + } + if (FileObject->SectionObjectPointer == NULL || + FileObject->SectionObjectPointer->SharedCacheMap == NULL) + { + /* FIXME: handle this situation */ + ObDereferenceObject(Section); + ObDereferenceObject(FileObject); + return STATUS_INVALID_PARAMETER; + } + } - /* - * Lock the file - */ - Status = MmspWaitForFileLock(FileObject); - if (Status != STATUS_SUCCESS) - { - ObDereferenceObject(Section); - ObDereferenceObject(FileObject); - return(Status); - } + /* + * Lock the file + */ + Status = MmspWaitForFileLock(FileObject); + if (Status != STATUS_SUCCESS) + { + ObDereferenceObject(Section); + ObDereferenceObject(FileObject); + return(Status); + } - /* - * If this file hasn't been mapped as a data file before then allocate a - * section segment to describe the data file mapping - */ - if (FileObject->SectionObjectPointer->DataSectionObject == NULL) - { - Segment = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_SECTION_SEGMENT), - TAG_MM_SECTION_SEGMENT); - if (Segment == NULL) - { - //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE); - ObDereferenceObject(Section); - ObDereferenceObject(FileObject); - return(STATUS_NO_MEMORY); - } - Section->Segment = Segment; - Segment->ReferenceCount = 1; - ExInitializeFastMutex(&Segment->Lock); - /* - * Set the lock before assigning the segment to the file object - */ - ExAcquireFastMutex(&Segment->Lock); - FileObject->SectionObjectPointer->DataSectionObject = (PVOID)Segment; + /* + * If this file hasn't been mapped as a data file before then allocate a + * section segment to describe the data file mapping + */ + if (FileObject->SectionObjectPointer->DataSectionObject == NULL) + { + Segment = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_SECTION_SEGMENT), + TAG_MM_SECTION_SEGMENT); + if (Segment == NULL) + { + //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE); + ObDereferenceObject(Section); + ObDereferenceObject(FileObject); + return(STATUS_NO_MEMORY); + } + Section->Segment = Segment; + Segment->ReferenceCount = 1; + ExInitializeFastMutex(&Segment->Lock); + /* + * Set the lock before assigning the segment to the file object + */ + ExAcquireFastMutex(&Segment->Lock); + FileObject->SectionObjectPointer->DataSectionObject = (PVOID)Segment; - Segment->Image.FileOffset = 0; - Segment->Protection = SectionPageProtection; - Segment->Flags = MM_DATAFILE_SEGMENT; - Segment->Image.Characteristics = 0; - Segment->WriteCopy = (SectionPageProtection & (PAGE_WRITECOPY | PAGE_EXECUTE_WRITECOPY)); - if (AllocationAttributes & SEC_RESERVE) - { - Segment->Length.QuadPart = Segment->RawLength.QuadPart = 0; - } - else - { - Segment->RawLength.QuadPart = MaximumSize.QuadPart; - Segment->Length.QuadPart = PAGE_ROUND_UP(Segment->RawLength.QuadPart); - } - Segment->Image.VirtualAddress = 0; - Segment->Locked = TRUE; - MiInitializeSectionPageTable(Segment); - } - else - { - /* - * If the file is already mapped as a data file then we may need - * to extend it - */ - Segment = - (PMM_SECTION_SEGMENT)FileObject->SectionObjectPointer-> - DataSectionObject; - Section->Segment = Segment; - (void)InterlockedIncrementUL(&Segment->ReferenceCount); - MmLockSectionSegment(Segment); + Segment->Image.FileOffset = 0; + Segment->Protection = SectionPageProtection; + Segment->Flags = MM_DATAFILE_SEGMENT; + Segment->Image.Characteristics = 0; + Segment->WriteCopy = (SectionPageProtection & (PAGE_WRITECOPY | PAGE_EXECUTE_WRITECOPY)); + if (AllocationAttributes & SEC_RESERVE) + { + Segment->Length.QuadPart = Segment->RawLength.QuadPart = 0; + } + else + { + Segment->RawLength.QuadPart = MaximumSize.QuadPart; + Segment->Length.QuadPart = PAGE_ROUND_UP(Segment->RawLength.QuadPart); + } + Segment->Image.VirtualAddress = 0; + Segment->Locked = TRUE; + MiInitializeSectionPageTable(Segment); + } + else + { + /* + * If the file is already mapped as a data file then we may need + * to extend it + */ + Segment = + (PMM_SECTION_SEGMENT)FileObject->SectionObjectPointer-> + DataSectionObject; + Section->Segment = Segment; + (void)InterlockedIncrementUL(&Segment->ReferenceCount); + MmLockSectionSegment(Segment); - if (MaximumSize.QuadPart > Segment->RawLength.QuadPart && - !(AllocationAttributes & SEC_RESERVE)) - { - Segment->RawLength.QuadPart = MaximumSize.QuadPart; - Segment->Length.QuadPart = PAGE_ROUND_UP(Segment->RawLength.QuadPart); - } - } - MmUnlockSectionSegment(Segment); - Section->FileObject = FileObject; - Section->MaximumSize = MaximumSize; + if (MaximumSize.QuadPart > Segment->RawLength.QuadPart && + !(AllocationAttributes & SEC_RESERVE)) + { + Segment->RawLength.QuadPart = MaximumSize.QuadPart; + Segment->Length.QuadPart = PAGE_ROUND_UP(Segment->RawLength.QuadPart); + } + } + MmUnlockSectionSegment(Segment); + Section->FileObject = FileObject; + Section->MaximumSize = MaximumSize; #ifndef NEWCC - CcRosReferenceCache(FileObject); + CcRosReferenceCache(FileObject); #endif - //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE); - *SectionObject = Section; - return(STATUS_SUCCESS); + //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE); + *SectionObject = Section; + return(STATUS_SUCCESS); } /* @@ -3130,24 +3134,24 @@ MmCreateDataFileSection(PROS_SECTION_OBJECT *SectionObject, */ extern NTSTATUS NTAPI PeFmtCreateSection ( - IN CONST VOID * FileHeader, - IN SIZE_T FileHeaderSize, - IN PVOID File, - OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, - OUT PULONG Flags, - IN PEXEFMT_CB_READ_FILE ReadFileCb, - IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb + IN CONST VOID * FileHeader, + IN SIZE_T FileHeaderSize, + IN PVOID File, + OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, + OUT PULONG Flags, + IN PEXEFMT_CB_READ_FILE ReadFileCb, + IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb ); extern NTSTATUS NTAPI ElfFmtCreateSection ( - IN CONST VOID * FileHeader, - IN SIZE_T FileHeaderSize, - IN PVOID File, - OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, - OUT PULONG Flags, - IN PEXEFMT_CB_READ_FILE ReadFileCb, - IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb + IN CONST VOID * FileHeader, + IN SIZE_T FileHeaderSize, + IN PVOID File, + OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, + OUT PULONG Flags, + IN PEXEFMT_CB_READ_FILE ReadFileCb, + IN PEXEFMT_CB_ALLOCATE_SEGMENTS AllocateSegmentsCb ); /* TODO: this is a standard DDK/PSDK macro */ @@ -3157,9 +3161,9 @@ extern NTSTATUS NTAPI ElfFmtCreateSection static PEXEFMT_LOADER ExeFmtpLoaders[] = { - PeFmtCreateSection, + PeFmtCreateSection, #ifdef __ELF - ElfFmtCreateSection + ElfFmtCreateSection #endif }; @@ -3168,20 +3172,20 @@ PMM_SECTION_SEGMENT NTAPI ExeFmtpAllocateSegments(IN ULONG NrSegments) { - SIZE_T SizeOfSegments; - PMM_SECTION_SEGMENT Segments; + SIZE_T SizeOfSegments; + PMM_SECTION_SEGMENT Segments; - /* TODO: check for integer overflow */ - SizeOfSegments = sizeof(MM_SECTION_SEGMENT) * NrSegments; + /* TODO: check for integer overflow */ + SizeOfSegments = sizeof(MM_SECTION_SEGMENT) * NrSegments; - Segments = ExAllocatePoolWithTag(NonPagedPool, - SizeOfSegments, - TAG_MM_SECTION_SEGMENT); + Segments = ExAllocatePoolWithTag(NonPagedPool, + SizeOfSegments, + TAG_MM_SECTION_SEGMENT); - if(Segments) - RtlZeroMemory(Segments, SizeOfSegments); + if(Segments) + RtlZeroMemory(Segments, SizeOfSegments); - return Segments; + return Segments; } static @@ -3194,76 +3198,76 @@ ExeFmtpReadFile(IN PVOID File, OUT PVOID * AllocBase, OUT PULONG ReadSize) { - NTSTATUS Status; - LARGE_INTEGER FileOffset; - ULONG AdjustOffset; - ULONG OffsetAdjustment; - ULONG BufferSize; - ULONG UsedSize; - PVOID Buffer; - PFILE_OBJECT FileObject = File; - IO_STATUS_BLOCK Iosb; + NTSTATUS Status; + LARGE_INTEGER FileOffset; + ULONG AdjustOffset; + ULONG OffsetAdjustment; + ULONG BufferSize; + ULONG UsedSize; + PVOID Buffer; + PFILE_OBJECT FileObject = File; + IO_STATUS_BLOCK Iosb; - ASSERT_IRQL_LESS(DISPATCH_LEVEL); + ASSERT_IRQL_LESS(DISPATCH_LEVEL); - if(Length == 0) - { - KeBugCheck(MEMORY_MANAGEMENT); - } + if(Length == 0) + { + KeBugCheck(MEMORY_MANAGEMENT); + } - FileOffset = *Offset; + FileOffset = *Offset; - /* Negative/special offset: it cannot be used in this context */ - if(FileOffset.u.HighPart < 0) - { - KeBugCheck(MEMORY_MANAGEMENT); - } + /* Negative/special offset: it cannot be used in this context */ + if(FileOffset.u.HighPart < 0) + { + KeBugCheck(MEMORY_MANAGEMENT); + } - AdjustOffset = PAGE_ROUND_DOWN(FileOffset.u.LowPart); - OffsetAdjustment = FileOffset.u.LowPart - AdjustOffset; - FileOffset.u.LowPart = AdjustOffset; + AdjustOffset = PAGE_ROUND_DOWN(FileOffset.u.LowPart); + OffsetAdjustment = FileOffset.u.LowPart - AdjustOffset; + FileOffset.u.LowPart = AdjustOffset; - BufferSize = Length + OffsetAdjustment; - BufferSize = PAGE_ROUND_UP(BufferSize); + BufferSize = Length + OffsetAdjustment; + BufferSize = PAGE_ROUND_UP(BufferSize); - /* - * It's ok to use paged pool, because this is a temporary buffer only used in - * the loading of executables. The assumption is that MmCreateSection is - * always called at low IRQLs and that these buffers don't survive a brief - * initialization phase - */ - Buffer = ExAllocatePoolWithTag(PagedPool, - BufferSize, - 'rXmM'); - if (!Buffer) - { - KeBugCheck(MEMORY_MANAGEMENT); - } + /* + * It's ok to use paged pool, because this is a temporary buffer only used in + * the loading of executables. The assumption is that MmCreateSection is + * always called at low IRQLs and that these buffers don't survive a brief + * initialization phase + */ + Buffer = ExAllocatePoolWithTag(PagedPool, + BufferSize, + 'rXmM'); + if (!Buffer) + { + KeBugCheck(MEMORY_MANAGEMENT); + } - UsedSize = 0; + UsedSize = 0; - Status = MiSimpleRead(FileObject, &FileOffset, Buffer, BufferSize, TRUE, &Iosb); + Status = MiSimpleRead(FileObject, &FileOffset, Buffer, BufferSize, TRUE, &Iosb); - UsedSize = (ULONG)Iosb.Information; + UsedSize = (ULONG)Iosb.Information; - if(NT_SUCCESS(Status) && UsedSize < OffsetAdjustment) - { - Status = STATUS_IN_PAGE_ERROR; - ASSERT(!NT_SUCCESS(Status)); - } + if(NT_SUCCESS(Status) && UsedSize < OffsetAdjustment) + { + Status = STATUS_IN_PAGE_ERROR; + ASSERT(!NT_SUCCESS(Status)); + } - if(NT_SUCCESS(Status)) - { - *Data = (PVOID)((ULONG_PTR)Buffer + OffsetAdjustment); - *AllocBase = Buffer; - *ReadSize = UsedSize - OffsetAdjustment; - } - else - { - ExFreePoolWithTag(Buffer, 'rXmM'); - } + if(NT_SUCCESS(Status)) + { + *Data = (PVOID)((ULONG_PTR)Buffer + OffsetAdjustment); + *AllocBase = Buffer; + *ReadSize = UsedSize - OffsetAdjustment; + } + else + { + ExFreePoolWithTag(Buffer, 'rXmM'); + } - return Status; + return Status; } #ifdef NASSERT @@ -3276,13 +3280,13 @@ VOID NTAPI MmspAssertSegmentsSorted(IN PMM_IMAGE_SECTION_OBJECT ImageSectionObject) { - ULONG i; + ULONG i; - for( i = 1; i < ImageSectionObject->NrSegments; ++ i ) - { - ASSERT(ImageSectionObject->Segments[i].Image.VirtualAddress >= - ImageSectionObject->Segments[i - 1].Image.VirtualAddress); - } + for( i = 1; i < ImageSectionObject->NrSegments; ++ i ) + { + ASSERT(ImageSectionObject->Segments[i].Image.VirtualAddress >= + ImageSectionObject->Segments[i - 1].Image.VirtualAddress); + } } static @@ -3290,21 +3294,21 @@ VOID NTAPI MmspAssertSegmentsNoOverlap(IN PMM_IMAGE_SECTION_OBJECT ImageSectionObject) { - ULONG i; + ULONG i; - MmspAssertSegmentsSorted(ImageSectionObject); + MmspAssertSegmentsSorted(ImageSectionObject); - for( i = 0; i < ImageSectionObject->NrSegments; ++ i ) - { - ASSERT(ImageSectionObject->Segments[i].Length.QuadPart > 0); + for( i = 0; i < ImageSectionObject->NrSegments; ++ i ) + { + ASSERT(ImageSectionObject->Segments[i].Length.QuadPart > 0); - if(i > 0) - { - ASSERT(ImageSectionObject->Segments[i].Image.VirtualAddress >= - (ImageSectionObject->Segments[i - 1].Image.VirtualAddress + - ImageSectionObject->Segments[i - 1].Length.QuadPart)); - } - } + if(i > 0) + { + ASSERT(ImageSectionObject->Segments[i].Image.VirtualAddress >= + (ImageSectionObject->Segments[i - 1].Image.VirtualAddress + + ImageSectionObject->Segments[i - 1].Length.QuadPart)); + } + } } static @@ -3312,13 +3316,13 @@ VOID NTAPI MmspAssertSegmentsPageAligned(IN PMM_IMAGE_SECTION_OBJECT ImageSectionObject) { - ULONG i; + ULONG i; - for( i = 0; i < ImageSectionObject->NrSegments; ++ i ) - { - ASSERT((ImageSectionObject->Segments[i].Image.VirtualAddress % PAGE_SIZE) == 0); - ASSERT((ImageSectionObject->Segments[i].Length.QuadPart % PAGE_SIZE) == 0); - } + for( i = 0; i < ImageSectionObject->NrSegments; ++ i ) + { + ASSERT((ImageSectionObject->Segments[i].Image.VirtualAddress % PAGE_SIZE) == 0); + ASSERT((ImageSectionObject->Segments[i].Length.QuadPart % PAGE_SIZE) == 0); + } } #endif @@ -3328,12 +3332,12 @@ __cdecl MmspCompareSegments(const void * x, const void * y) { - const MM_SECTION_SEGMENT *Segment1 = (const MM_SECTION_SEGMENT *)x; - const MM_SECTION_SEGMENT *Segment2 = (const MM_SECTION_SEGMENT *)y; + const MM_SECTION_SEGMENT *Segment1 = (const MM_SECTION_SEGMENT *)x; + const MM_SECTION_SEGMENT *Segment2 = (const MM_SECTION_SEGMENT *)y; - return - (Segment1->Image.VirtualAddress - Segment2->Image.VirtualAddress) >> - ((sizeof(ULONG_PTR) - sizeof(int)) * 8); + return + (Segment1->Image.VirtualAddress - Segment2->Image.VirtualAddress) >> + ((sizeof(ULONG_PTR) - sizeof(int)) * 8); } /* @@ -3345,17 +3349,17 @@ NTAPI MmspSortSegments(IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, IN ULONG Flags) { - if (Flags & EXEFMT_LOAD_ASSUME_SEGMENTS_SORTED) - { - MmspAssertSegmentsSorted(ImageSectionObject); - } - else - { - qsort(ImageSectionObject->Segments, - ImageSectionObject->NrSegments, - sizeof(ImageSectionObject->Segments[0]), - MmspCompareSegments); - } + if (Flags & EXEFMT_LOAD_ASSUME_SEGMENTS_SORTED) + { + MmspAssertSegmentsSorted(ImageSectionObject); + } + else + { + qsort(ImageSectionObject->Segments, + ImageSectionObject->NrSegments, + sizeof(ImageSectionObject->Segments[0]), + MmspCompareSegments); + } } @@ -3369,46 +3373,46 @@ BOOLEAN NTAPI MmspCheckSegmentBounds ( - IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, - IN ULONG Flags + IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, + IN ULONG Flags ) { - ULONG i; + ULONG i; - if (Flags & EXEFMT_LOAD_ASSUME_SEGMENTS_NO_OVERLAP) - { - MmspAssertSegmentsNoOverlap(ImageSectionObject); - return TRUE; - } + if (Flags & EXEFMT_LOAD_ASSUME_SEGMENTS_NO_OVERLAP) + { + MmspAssertSegmentsNoOverlap(ImageSectionObject); + return TRUE; + } - ASSERT(ImageSectionObject->NrSegments >= 1); + ASSERT(ImageSectionObject->NrSegments >= 1); - for ( i = 0; i < ImageSectionObject->NrSegments; ++ i ) - { - if(ImageSectionObject->Segments[i].Length.QuadPart == 0) - { - return FALSE; - } - - if(i > 0) - { - /* - * TODO: relax the limitation on gaps. For example, gaps smaller than a - * page could be OK (Windows seems to be OK with them), and larger gaps - * could lead to image sections spanning several discontiguous regions - * (NtMapViewOfSection could then refuse to map them, and they could - * e.g. only be allowed as parameters to NtCreateProcess, like on UNIX) - */ - if ((ImageSectionObject->Segments[i - 1].Image.VirtualAddress + - ImageSectionObject->Segments[i - 1].Length.QuadPart) != - ImageSectionObject->Segments[i].Image.VirtualAddress) - { + for ( i = 0; i < ImageSectionObject->NrSegments; ++ i ) + { + if(ImageSectionObject->Segments[i].Length.QuadPart == 0) + { return FALSE; - } - } - } + } - return TRUE; + if(i > 0) + { + /* + * TODO: relax the limitation on gaps. For example, gaps smaller than a + * page could be OK (Windows seems to be OK with them), and larger gaps + * could lead to image sections spanning several discontiguous regions + * (NtMapViewOfSection could then refuse to map them, and they could + * e.g. only be allowed as parameters to NtCreateProcess, like on UNIX) + */ + if ((ImageSectionObject->Segments[i - 1].Image.VirtualAddress + + ImageSectionObject->Segments[i - 1].Length.QuadPart) != + ImageSectionObject->Segments[i].Image.VirtualAddress) + { + return FALSE; + } + } + } + + return TRUE; } /* @@ -3420,334 +3424,334 @@ BOOLEAN NTAPI MmspPageAlignSegments ( - IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, - IN ULONG Flags + IN OUT PMM_IMAGE_SECTION_OBJECT ImageSectionObject, + IN ULONG Flags ) { - ULONG i; - ULONG LastSegment; - PMM_SECTION_SEGMENT EffectiveSegment; + ULONG i; + ULONG LastSegment; + PMM_SECTION_SEGMENT EffectiveSegment; - if (Flags & EXEFMT_LOAD_ASSUME_SEGMENTS_PAGE_ALIGNED) - { - MmspAssertSegmentsPageAligned(ImageSectionObject); - return TRUE; - } + if (Flags & EXEFMT_LOAD_ASSUME_SEGMENTS_PAGE_ALIGNED) + { + MmspAssertSegmentsPageAligned(ImageSectionObject); + return TRUE; + } - LastSegment = 0; - EffectiveSegment = &ImageSectionObject->Segments[LastSegment]; + LastSegment = 0; + EffectiveSegment = &ImageSectionObject->Segments[LastSegment]; - for ( i = 0; i < ImageSectionObject->NrSegments; ++ i ) - { - /* - * The first segment requires special handling - */ - if (i == 0) - { - ULONG_PTR VirtualAddress; - ULONG_PTR VirtualOffset; + for ( i = 0; i < ImageSectionObject->NrSegments; ++ i ) + { + /* + * The first segment requires special handling + */ + if (i == 0) + { + ULONG_PTR VirtualAddress; + ULONG_PTR VirtualOffset; - VirtualAddress = EffectiveSegment->Image.VirtualAddress; + VirtualAddress = EffectiveSegment->Image.VirtualAddress; - /* Round down the virtual address to the nearest page */ - EffectiveSegment->Image.VirtualAddress = PAGE_ROUND_DOWN(VirtualAddress); + /* Round down the virtual address to the nearest page */ + EffectiveSegment->Image.VirtualAddress = PAGE_ROUND_DOWN(VirtualAddress); - /* Round up the virtual size to the nearest page */ - EffectiveSegment->Length.QuadPart = PAGE_ROUND_UP(VirtualAddress + EffectiveSegment->Length.QuadPart) - - EffectiveSegment->Image.VirtualAddress; + /* Round up the virtual size to the nearest page */ + EffectiveSegment->Length.QuadPart = PAGE_ROUND_UP(VirtualAddress + EffectiveSegment->Length.QuadPart) - + EffectiveSegment->Image.VirtualAddress; - /* Adjust the raw address and size */ - VirtualOffset = VirtualAddress - EffectiveSegment->Image.VirtualAddress; + /* Adjust the raw address and size */ + VirtualOffset = VirtualAddress - EffectiveSegment->Image.VirtualAddress; - if (EffectiveSegment->Image.FileOffset < VirtualOffset) - { - return FALSE; - } - - /* - * Garbage in, garbage out: unaligned base addresses make the file - * offset point in curious and odd places, but that's what we were - * asked for - */ - EffectiveSegment->Image.FileOffset -= VirtualOffset; - EffectiveSegment->RawLength.QuadPart += VirtualOffset; - } - else - { - PMM_SECTION_SEGMENT Segment = &ImageSectionObject->Segments[i]; - ULONG_PTR EndOfEffectiveSegment; - - EndOfEffectiveSegment = (ULONG_PTR)(EffectiveSegment->Image.VirtualAddress + EffectiveSegment->Length.QuadPart); - ASSERT((EndOfEffectiveSegment % PAGE_SIZE) == 0); - - /* - * The current segment begins exactly where the current effective - * segment ended, therefore beginning a new effective segment - */ - if (EndOfEffectiveSegment == Segment->Image.VirtualAddress) - { - LastSegment ++; - ASSERT(LastSegment <= i); - ASSERT(LastSegment < ImageSectionObject->NrSegments); - - EffectiveSegment = &ImageSectionObject->Segments[LastSegment]; - - if (LastSegment != i) + if (EffectiveSegment->Image.FileOffset < VirtualOffset) { - /* - * Copy the current segment. If necessary, the effective segment - * will be expanded later - */ - *EffectiveSegment = *Segment; + return FALSE; } /* - * Page-align the virtual size. We know for sure the virtual address - * already is + * Garbage in, garbage out: unaligned base addresses make the file + * offset point in curious and odd places, but that's what we were + * asked for */ - ASSERT((EffectiveSegment->Image.VirtualAddress % PAGE_SIZE) == 0); - EffectiveSegment->Length.QuadPart = PAGE_ROUND_UP(EffectiveSegment->Length.QuadPart); - } - /* - * The current segment is still part of the current effective segment: - * extend the effective segment to reflect this - */ - else if (EndOfEffectiveSegment > Segment->Image.VirtualAddress) - { - static const ULONG FlagsToProtection[16] = - { - PAGE_NOACCESS, - PAGE_READONLY, - PAGE_READWRITE, - PAGE_READWRITE, - PAGE_EXECUTE_READ, - PAGE_EXECUTE_READ, - PAGE_EXECUTE_READWRITE, - PAGE_EXECUTE_READWRITE, - PAGE_WRITECOPY, - PAGE_WRITECOPY, - PAGE_WRITECOPY, - PAGE_WRITECOPY, - PAGE_EXECUTE_WRITECOPY, - PAGE_EXECUTE_WRITECOPY, - PAGE_EXECUTE_WRITECOPY, - PAGE_EXECUTE_WRITECOPY - }; + EffectiveSegment->Image.FileOffset -= VirtualOffset; + EffectiveSegment->RawLength.QuadPart += VirtualOffset; + } + else + { + PMM_SECTION_SEGMENT Segment = &ImageSectionObject->Segments[i]; + ULONG_PTR EndOfEffectiveSegment; - unsigned ProtectionFlags; + EndOfEffectiveSegment = (ULONG_PTR)(EffectiveSegment->Image.VirtualAddress + EffectiveSegment->Length.QuadPart); + ASSERT((EndOfEffectiveSegment % PAGE_SIZE) == 0); /* - * Extend the file size + * The current segment begins exactly where the current effective + * segment ended, therefore beginning a new effective segment */ - - /* Unaligned segments must be contiguous within the file */ - if (Segment->Image.FileOffset != (EffectiveSegment->Image.FileOffset + - EffectiveSegment->RawLength.QuadPart)) + if (EndOfEffectiveSegment == Segment->Image.VirtualAddress) { - return FALSE; + LastSegment ++; + ASSERT(LastSegment <= i); + ASSERT(LastSegment < ImageSectionObject->NrSegments); + + EffectiveSegment = &ImageSectionObject->Segments[LastSegment]; + + if (LastSegment != i) + { + /* + * Copy the current segment. If necessary, the effective segment + * will be expanded later + */ + *EffectiveSegment = *Segment; + } + + /* + * Page-align the virtual size. We know for sure the virtual address + * already is + */ + ASSERT((EffectiveSegment->Image.VirtualAddress % PAGE_SIZE) == 0); + EffectiveSegment->Length.QuadPart = PAGE_ROUND_UP(EffectiveSegment->Length.QuadPart); } - - EffectiveSegment->RawLength.QuadPart += Segment->RawLength.QuadPart; - /* - * Extend the virtual size + * The current segment is still part of the current effective segment: + * extend the effective segment to reflect this */ - ASSERT(PAGE_ROUND_UP(Segment->Image.VirtualAddress + Segment->Length.QuadPart) >= EndOfEffectiveSegment); - - EffectiveSegment->Length.QuadPart = PAGE_ROUND_UP(Segment->Image.VirtualAddress + Segment->Length.QuadPart) - - EffectiveSegment->Image.VirtualAddress; - - /* - * Merge the protection - */ - EffectiveSegment->Protection |= Segment->Protection; - - /* Clean up redundance */ - ProtectionFlags = 0; - - if(EffectiveSegment->Protection & PAGE_IS_READABLE) - ProtectionFlags |= 1 << 0; - - if(EffectiveSegment->Protection & PAGE_IS_WRITABLE) - ProtectionFlags |= 1 << 1; - - if(EffectiveSegment->Protection & PAGE_IS_EXECUTABLE) - ProtectionFlags |= 1 << 2; - - if(EffectiveSegment->Protection & PAGE_IS_WRITECOPY) - ProtectionFlags |= 1 << 3; - - ASSERT(ProtectionFlags < 16); - EffectiveSegment->Protection = FlagsToProtection[ProtectionFlags]; - - /* If a segment was required to be shared and cannot, fail */ - if(!(Segment->Protection & PAGE_IS_WRITECOPY) && - EffectiveSegment->Protection & PAGE_IS_WRITECOPY) + else if (EndOfEffectiveSegment > Segment->Image.VirtualAddress) { - return FALSE; - } - } - /* - * We assume no holes between segments at this point - */ - else - { - KeBugCheck(MEMORY_MANAGEMENT); - } - } - } - ImageSectionObject->NrSegments = LastSegment + 1; + static const ULONG FlagsToProtection[16] = + { + PAGE_NOACCESS, + PAGE_READONLY, + PAGE_READWRITE, + PAGE_READWRITE, + PAGE_EXECUTE_READ, + PAGE_EXECUTE_READ, + PAGE_EXECUTE_READWRITE, + PAGE_EXECUTE_READWRITE, + PAGE_WRITECOPY, + PAGE_WRITECOPY, + PAGE_WRITECOPY, + PAGE_WRITECOPY, + PAGE_EXECUTE_WRITECOPY, + PAGE_EXECUTE_WRITECOPY, + PAGE_EXECUTE_WRITECOPY, + PAGE_EXECUTE_WRITECOPY + }; - return TRUE; + unsigned ProtectionFlags; + + /* + * Extend the file size + */ + + /* Unaligned segments must be contiguous within the file */ + if (Segment->Image.FileOffset != (EffectiveSegment->Image.FileOffset + + EffectiveSegment->RawLength.QuadPart)) + { + return FALSE; + } + + EffectiveSegment->RawLength.QuadPart += Segment->RawLength.QuadPart; + + /* + * Extend the virtual size + */ + ASSERT(PAGE_ROUND_UP(Segment->Image.VirtualAddress + Segment->Length.QuadPart) >= EndOfEffectiveSegment); + + EffectiveSegment->Length.QuadPart = PAGE_ROUND_UP(Segment->Image.VirtualAddress + Segment->Length.QuadPart) - + EffectiveSegment->Image.VirtualAddress; + + /* + * Merge the protection + */ + EffectiveSegment->Protection |= Segment->Protection; + + /* Clean up redundance */ + ProtectionFlags = 0; + + if(EffectiveSegment->Protection & PAGE_IS_READABLE) + ProtectionFlags |= 1 << 0; + + if(EffectiveSegment->Protection & PAGE_IS_WRITABLE) + ProtectionFlags |= 1 << 1; + + if(EffectiveSegment->Protection & PAGE_IS_EXECUTABLE) + ProtectionFlags |= 1 << 2; + + if(EffectiveSegment->Protection & PAGE_IS_WRITECOPY) + ProtectionFlags |= 1 << 3; + + ASSERT(ProtectionFlags < 16); + EffectiveSegment->Protection = FlagsToProtection[ProtectionFlags]; + + /* If a segment was required to be shared and cannot, fail */ + if(!(Segment->Protection & PAGE_IS_WRITECOPY) && + EffectiveSegment->Protection & PAGE_IS_WRITECOPY) + { + return FALSE; + } + } + /* + * We assume no holes between segments at this point + */ + else + { + KeBugCheck(MEMORY_MANAGEMENT); + } + } + } + ImageSectionObject->NrSegments = LastSegment + 1; + + return TRUE; } NTSTATUS ExeFmtpCreateImageSection(HANDLE FileHandle, PMM_IMAGE_SECTION_OBJECT ImageSectionObject) { - LARGE_INTEGER Offset; - PVOID FileHeader; - PVOID FileHeaderBuffer; - ULONG FileHeaderSize; - ULONG Flags; - ULONG OldNrSegments; - NTSTATUS Status; - ULONG i; + LARGE_INTEGER Offset; + PVOID FileHeader; + PVOID FileHeaderBuffer; + ULONG FileHeaderSize; + ULONG Flags; + ULONG OldNrSegments; + NTSTATUS Status; + ULONG i; - /* - * Read the beginning of the file (2 pages). Should be enough to contain - * all (or most) of the headers - */ - Offset.QuadPart = 0; + /* + * Read the beginning of the file (2 pages). Should be enough to contain + * all (or most) of the headers + */ + Offset.QuadPart = 0; - /* FIXME: use FileObject instead of FileHandle */ - Status = ExeFmtpReadFile (FileHandle, - &Offset, - PAGE_SIZE * 2, - &FileHeader, - &FileHeaderBuffer, - &FileHeaderSize); + /* FIXME: use FileObject instead of FileHandle */ + Status = ExeFmtpReadFile (FileHandle, + &Offset, + PAGE_SIZE * 2, + &FileHeader, + &FileHeaderBuffer, + &FileHeaderSize); - if (!NT_SUCCESS(Status)) - return Status; + if (!NT_SUCCESS(Status)) + return Status; - if (FileHeaderSize == 0) - { - ExFreePool(FileHeaderBuffer); - return STATUS_UNSUCCESSFUL; - } + if (FileHeaderSize == 0) + { + ExFreePool(FileHeaderBuffer); + return STATUS_UNSUCCESSFUL; + } - /* - * Look for a loader that can handle this executable - */ - for (i = 0; i < RTL_NUMBER_OF(ExeFmtpLoaders); ++ i) - { - RtlZeroMemory(ImageSectionObject, sizeof(*ImageSectionObject)); - Flags = 0; + /* + * Look for a loader that can handle this executable + */ + for (i = 0; i < RTL_NUMBER_OF(ExeFmtpLoaders); ++ i) + { + RtlZeroMemory(ImageSectionObject, sizeof(*ImageSectionObject)); + Flags = 0; - /* FIXME: use FileObject instead of FileHandle */ - Status = ExeFmtpLoaders[i](FileHeader, - FileHeaderSize, - FileHandle, - ImageSectionObject, - &Flags, - ExeFmtpReadFile, - ExeFmtpAllocateSegments); + /* FIXME: use FileObject instead of FileHandle */ + Status = ExeFmtpLoaders[i](FileHeader, + FileHeaderSize, + FileHandle, + ImageSectionObject, + &Flags, + ExeFmtpReadFile, + ExeFmtpAllocateSegments); - if (!NT_SUCCESS(Status)) - { - if (ImageSectionObject->Segments) - { - ExFreePool(ImageSectionObject->Segments); - ImageSectionObject->Segments = NULL; - } - } + if (!NT_SUCCESS(Status)) + { + if (ImageSectionObject->Segments) + { + ExFreePool(ImageSectionObject->Segments); + ImageSectionObject->Segments = NULL; + } + } - if (Status != STATUS_ROS_EXEFMT_UNKNOWN_FORMAT) - break; - } + if (Status != STATUS_ROS_EXEFMT_UNKNOWN_FORMAT) + break; + } - ExFreePoolWithTag(FileHeaderBuffer, 'rXmM'); + ExFreePoolWithTag(FileHeaderBuffer, 'rXmM'); - /* - * No loader handled the format - */ - if (Status == STATUS_ROS_EXEFMT_UNKNOWN_FORMAT) - { - Status = STATUS_INVALID_IMAGE_NOT_MZ; - ASSERT(!NT_SUCCESS(Status)); - } + /* + * No loader handled the format + */ + if (Status == STATUS_ROS_EXEFMT_UNKNOWN_FORMAT) + { + Status = STATUS_INVALID_IMAGE_NOT_MZ; + ASSERT(!NT_SUCCESS(Status)); + } - if (!NT_SUCCESS(Status)) - return Status; + if (!NT_SUCCESS(Status)) + return Status; - ASSERT(ImageSectionObject->Segments != NULL); + ASSERT(ImageSectionObject->Segments != NULL); - /* - * Some defaults - */ - /* FIXME? are these values platform-dependent? */ - if (ImageSectionObject->ImageInformation.MaximumStackSize == 0) - ImageSectionObject->ImageInformation.MaximumStackSize = 0x40000; + /* + * Some defaults + */ + /* FIXME? are these values platform-dependent? */ + if (ImageSectionObject->ImageInformation.MaximumStackSize == 0) + ImageSectionObject->ImageInformation.MaximumStackSize = 0x40000; - if(ImageSectionObject->ImageInformation.CommittedStackSize == 0) - ImageSectionObject->ImageInformation.CommittedStackSize = 0x1000; + if(ImageSectionObject->ImageInformation.CommittedStackSize == 0) + ImageSectionObject->ImageInformation.CommittedStackSize = 0x1000; - if(ImageSectionObject->BasedAddress == NULL) - { - if(ImageSectionObject->ImageInformation.ImageCharacteristics & IMAGE_FILE_DLL) - ImageSectionObject->BasedAddress = (PVOID)0x10000000; - else - ImageSectionObject->BasedAddress = (PVOID)0x00400000; - } + if(ImageSectionObject->BasedAddress == NULL) + { + if(ImageSectionObject->ImageInformation.ImageCharacteristics & IMAGE_FILE_DLL) + ImageSectionObject->BasedAddress = (PVOID)0x10000000; + else + ImageSectionObject->BasedAddress = (PVOID)0x00400000; + } - /* - * And now the fun part: fixing the segments - */ + /* + * And now the fun part: fixing the segments + */ - /* Sort them by virtual address */ - MmspSortSegments(ImageSectionObject, Flags); + /* Sort them by virtual address */ + MmspSortSegments(ImageSectionObject, Flags); - /* Ensure they don't overlap in memory */ - if (!MmspCheckSegmentBounds(ImageSectionObject, Flags)) - return STATUS_INVALID_IMAGE_FORMAT; + /* Ensure they don't overlap in memory */ + if (!MmspCheckSegmentBounds(ImageSectionObject, Flags)) + return STATUS_INVALID_IMAGE_FORMAT; - /* Ensure they are aligned */ - OldNrSegments = ImageSectionObject->NrSegments; + /* Ensure they are aligned */ + OldNrSegments = ImageSectionObject->NrSegments; - if (!MmspPageAlignSegments(ImageSectionObject, Flags)) - return STATUS_INVALID_IMAGE_FORMAT; + if (!MmspPageAlignSegments(ImageSectionObject, Flags)) + return STATUS_INVALID_IMAGE_FORMAT; - /* Trim them if the alignment phase merged some of them */ - if (ImageSectionObject->NrSegments < OldNrSegments) - { - PMM_SECTION_SEGMENT Segments; - SIZE_T SizeOfSegments; + /* Trim them if the alignment phase merged some of them */ + if (ImageSectionObject->NrSegments < OldNrSegments) + { + PMM_SECTION_SEGMENT Segments; + SIZE_T SizeOfSegments; - SizeOfSegments = sizeof(MM_SECTION_SEGMENT) * ImageSectionObject->NrSegments; + SizeOfSegments = sizeof(MM_SECTION_SEGMENT) * ImageSectionObject->NrSegments; - Segments = ExAllocatePoolWithTag(PagedPool, - SizeOfSegments, - TAG_MM_SECTION_SEGMENT); + Segments = ExAllocatePoolWithTag(PagedPool, + SizeOfSegments, + TAG_MM_SECTION_SEGMENT); - if (Segments == NULL) - return STATUS_INSUFFICIENT_RESOURCES; + if (Segments == NULL) + return STATUS_INSUFFICIENT_RESOURCES; - RtlCopyMemory(Segments, ImageSectionObject->Segments, SizeOfSegments); - ExFreePool(ImageSectionObject->Segments); - ImageSectionObject->Segments = Segments; - } + RtlCopyMemory(Segments, ImageSectionObject->Segments, SizeOfSegments); + ExFreePool(ImageSectionObject->Segments); + ImageSectionObject->Segments = Segments; + } - /* And finish their initialization */ - for ( i = 0; i < ImageSectionObject->NrSegments; ++ i ) - { - ExInitializeFastMutex(&ImageSectionObject->Segments[i].Lock); - ImageSectionObject->Segments[i].ReferenceCount = 1; - MiInitializeSectionPageTable(&ImageSectionObject->Segments[i]); - } + /* And finish their initialization */ + for ( i = 0; i < ImageSectionObject->NrSegments; ++ i ) + { + ExInitializeFastMutex(&ImageSectionObject->Segments[i].Lock); + ImageSectionObject->Segments[i].ReferenceCount = 1; + MiInitializeSectionPageTable(&ImageSectionObject->Segments[i]); + } - ASSERT(NT_SUCCESS(Status)); - return Status; + ASSERT(NT_SUCCESS(Status)); + return Status; } NTSTATUS @@ -3759,149 +3763,149 @@ MmCreateImageSection(PROS_SECTION_OBJECT *SectionObject, ULONG AllocationAttributes, PFILE_OBJECT FileObject) { - PROS_SECTION_OBJECT Section; - NTSTATUS Status; - PMM_SECTION_SEGMENT SectionSegments; - PMM_IMAGE_SECTION_OBJECT ImageSectionObject; - ULONG i; + PROS_SECTION_OBJECT Section; + NTSTATUS Status; + PMM_SECTION_SEGMENT SectionSegments; + PMM_IMAGE_SECTION_OBJECT ImageSectionObject; + ULONG i; - if (FileObject == NULL) - return STATUS_INVALID_FILE_FOR_SECTION; + if (FileObject == NULL) + return STATUS_INVALID_FILE_FOR_SECTION; - /* - * Create the section - */ - Status = ObCreateObject (ExGetPreviousMode(), - MmSectionObjectType, - ObjectAttributes, - ExGetPreviousMode(), - NULL, - sizeof(ROS_SECTION_OBJECT), - 0, - 0, - (PVOID*)(PVOID)&Section); - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(FileObject); - return(Status); - } + /* + * Create the section + */ + Status = ObCreateObject (ExGetPreviousMode(), + MmSectionObjectType, + ObjectAttributes, + ExGetPreviousMode(), + NULL, + sizeof(ROS_SECTION_OBJECT), + 0, + 0, + (PVOID*)(PVOID)&Section); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(FileObject); + return(Status); + } - /* - * Initialize it - */ - RtlZeroMemory(Section, sizeof(ROS_SECTION_OBJECT)); - Section->Type = 'SC'; - Section->Size = 'TN'; - Section->SectionPageProtection = SectionPageProtection; - Section->AllocationAttributes = AllocationAttributes; + /* + * Initialize it + */ + RtlZeroMemory(Section, sizeof(ROS_SECTION_OBJECT)); + Section->Type = 'SC'; + Section->Size = 'TN'; + Section->SectionPageProtection = SectionPageProtection; + Section->AllocationAttributes = AllocationAttributes; #ifndef NEWCC - /* - * Initialized caching for this file object if previously caching - * was initialized for the same on disk file - */ - Status = CcTryToInitializeFileCache(FileObject); + /* + * Initialized caching for this file object if previously caching + * was initialized for the same on disk file + */ + Status = CcTryToInitializeFileCache(FileObject); #else - Status = STATUS_SUCCESS; + Status = STATUS_SUCCESS; #endif - if (!NT_SUCCESS(Status) || FileObject->SectionObjectPointer->ImageSectionObject == NULL) - { - NTSTATUS StatusExeFmt; + if (!NT_SUCCESS(Status) || FileObject->SectionObjectPointer->ImageSectionObject == NULL) + { + NTSTATUS StatusExeFmt; - ImageSectionObject = ExAllocatePoolWithTag(PagedPool, sizeof(MM_IMAGE_SECTION_OBJECT), TAG_MM_SECTION_SEGMENT); - if (ImageSectionObject == NULL) - { - ObDereferenceObject(FileObject); - ObDereferenceObject(Section); - return(STATUS_NO_MEMORY); - } + ImageSectionObject = ExAllocatePoolWithTag(PagedPool, sizeof(MM_IMAGE_SECTION_OBJECT), TAG_MM_SECTION_SEGMENT); + if (ImageSectionObject == NULL) + { + ObDereferenceObject(FileObject); + ObDereferenceObject(Section); + return(STATUS_NO_MEMORY); + } - RtlZeroMemory(ImageSectionObject, sizeof(MM_IMAGE_SECTION_OBJECT)); + RtlZeroMemory(ImageSectionObject, sizeof(MM_IMAGE_SECTION_OBJECT)); - StatusExeFmt = ExeFmtpCreateImageSection(FileObject, ImageSectionObject); + StatusExeFmt = ExeFmtpCreateImageSection(FileObject, ImageSectionObject); - if (!NT_SUCCESS(StatusExeFmt)) - { - if(ImageSectionObject->Segments != NULL) + if (!NT_SUCCESS(StatusExeFmt)) + { + if(ImageSectionObject->Segments != NULL) + ExFreePool(ImageSectionObject->Segments); + + ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT); + ObDereferenceObject(Section); + ObDereferenceObject(FileObject); + return(StatusExeFmt); + } + + Section->ImageSection = ImageSectionObject; + ASSERT(ImageSectionObject->Segments); + + /* + * Lock the file + */ + Status = MmspWaitForFileLock(FileObject); + if (!NT_SUCCESS(Status)) + { ExFreePool(ImageSectionObject->Segments); + ExFreePool(ImageSectionObject); + ObDereferenceObject(Section); + ObDereferenceObject(FileObject); + return(Status); + } - ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT); - ObDereferenceObject(Section); - ObDereferenceObject(FileObject); - return(StatusExeFmt); - } + if (NULL != InterlockedCompareExchangePointer(&FileObject->SectionObjectPointer->ImageSectionObject, + ImageSectionObject, NULL)) + { + /* + * An other thread has initialized the same image in the background + */ + ExFreePool(ImageSectionObject->Segments); + ExFreePool(ImageSectionObject); + ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject; + Section->ImageSection = ImageSectionObject; + SectionSegments = ImageSectionObject->Segments; - Section->ImageSection = ImageSectionObject; - ASSERT(ImageSectionObject->Segments); + for (i = 0; i < ImageSectionObject->NrSegments; i++) + { + (void)InterlockedIncrementUL(&SectionSegments[i].ReferenceCount); + } + } - /* - * Lock the file - */ - Status = MmspWaitForFileLock(FileObject); - if (!NT_SUCCESS(Status)) - { - ExFreePool(ImageSectionObject->Segments); - ExFreePool(ImageSectionObject); - ObDereferenceObject(Section); - ObDereferenceObject(FileObject); - return(Status); - } + Status = StatusExeFmt; + } + else + { + /* + * Lock the file + */ + Status = MmspWaitForFileLock(FileObject); + if (Status != STATUS_SUCCESS) + { + ObDereferenceObject(Section); + ObDereferenceObject(FileObject); + return(Status); + } - if (NULL != InterlockedCompareExchangePointer(&FileObject->SectionObjectPointer->ImageSectionObject, - ImageSectionObject, NULL)) - { - /* - * An other thread has initialized the same image in the background - */ - ExFreePool(ImageSectionObject->Segments); - ExFreePool(ImageSectionObject); - ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject; - Section->ImageSection = ImageSectionObject; - SectionSegments = ImageSectionObject->Segments; + ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject; + Section->ImageSection = ImageSectionObject; + SectionSegments = ImageSectionObject->Segments; - for (i = 0; i < ImageSectionObject->NrSegments; i++) - { + /* + * Otherwise just reference all the section segments + */ + for (i = 0; i < ImageSectionObject->NrSegments; i++) + { (void)InterlockedIncrementUL(&SectionSegments[i].ReferenceCount); - } - } + } - Status = StatusExeFmt; - } - else - { - /* - * Lock the file - */ - Status = MmspWaitForFileLock(FileObject); - if (Status != STATUS_SUCCESS) - { - ObDereferenceObject(Section); - ObDereferenceObject(FileObject); - return(Status); - } - - ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject; - Section->ImageSection = ImageSectionObject; - SectionSegments = ImageSectionObject->Segments; - - /* - * Otherwise just reference all the section segments - */ - for (i = 0; i < ImageSectionObject->NrSegments; i++) - { - (void)InterlockedIncrementUL(&SectionSegments[i].ReferenceCount); - } - - Status = STATUS_SUCCESS; - } - Section->FileObject = FileObject; + Status = STATUS_SUCCESS; + } + Section->FileObject = FileObject; #ifndef NEWCC - CcRosReferenceCache(FileObject); + CcRosReferenceCache(FileObject); #endif - //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE); - *SectionObject = Section; - return(Status); + //KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE); + *SectionObject = Section; + return(Status); } @@ -3916,65 +3920,66 @@ MmMapViewOfSegment(PMMSUPPORT AddressSpace, ULONG ViewOffset, ULONG AllocationType) { - PMEMORY_AREA MArea; - NTSTATUS Status; - ULONG Granularity; + PMEMORY_AREA MArea; + NTSTATUS Status; + ULONG Granularity; - if (Segment->WriteCopy) - { - /* We have to do this because the not present fault - * and access fault handlers depend on the protection - * that should be granted AFTER the COW fault takes - * place to be in Region->Protect. The not present fault - * handler changes this to the correct protection for COW when - * mapping the pages into the process's address space. If a COW - * fault takes place, the access fault handler sets the page protection - * to these values for the newly copied pages - */ - if (Protect == PAGE_WRITECOPY) - Protect = PAGE_READWRITE; - else if (Protect == PAGE_EXECUTE_WRITECOPY) - Protect = PAGE_EXECUTE_READWRITE; - } + if (Segment->WriteCopy) + { + /* We have to do this because the not present fault + * and access fault handlers depend on the protection + * that should be granted AFTER the COW fault takes + * place to be in Region->Protect. The not present fault + * handler changes this to the correct protection for COW when + * mapping the pages into the process's address space. If a COW + * fault takes place, the access fault handler sets the page protection + * to these values for the newly copied pages + */ + if (Protect == PAGE_WRITECOPY) + Protect = PAGE_READWRITE; + else if (Protect == PAGE_EXECUTE_WRITECOPY) + Protect = PAGE_EXECUTE_READWRITE; + } - if (*BaseAddress == NULL) - Granularity = MM_ALLOCATION_GRANULARITY; - else - Granularity = PAGE_SIZE; + if (*BaseAddress == NULL) + Granularity = MM_ALLOCATION_GRANULARITY; + else + Granularity = PAGE_SIZE; #ifdef NEWCC - if (Segment->Flags & MM_DATAFILE_SEGMENT) { - LARGE_INTEGER FileOffset; - FileOffset.QuadPart = ViewOffset; - ObReferenceObject(Section); - return _MiMapViewOfSegment(AddressSpace, Segment, BaseAddress, ViewSize, Protect, &FileOffset, AllocationType, __FILE__, __LINE__); - } + if (Segment->Flags & MM_DATAFILE_SEGMENT) + { + LARGE_INTEGER FileOffset; + FileOffset.QuadPart = ViewOffset; + ObReferenceObject(Section); + return _MiMapViewOfSegment(AddressSpace, Segment, BaseAddress, ViewSize, Protect, &FileOffset, AllocationType, __FILE__, __LINE__); + } #endif - Status = MmCreateMemoryArea(AddressSpace, - MEMORY_AREA_SECTION_VIEW, - BaseAddress, - ViewSize, - Protect, - &MArea, - FALSE, - AllocationType, - Granularity); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Mapping between 0x%p and 0x%p failed (%X).\n", - (*BaseAddress), (char*)(*BaseAddress) + ViewSize, Status); - return(Status); - } + Status = MmCreateMemoryArea(AddressSpace, + MEMORY_AREA_SECTION_VIEW, + BaseAddress, + ViewSize, + Protect, + &MArea, + FALSE, + AllocationType, + Granularity); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Mapping between 0x%p and 0x%p failed (%X).\n", + (*BaseAddress), (char*)(*BaseAddress) + ViewSize, Status); + return(Status); + } - ObReferenceObject((PVOID)Section); + ObReferenceObject((PVOID)Section); - MArea->Data.SectionData.Segment = Segment; - MArea->Data.SectionData.Section = Section; - MArea->Data.SectionData.ViewOffset.QuadPart = ViewOffset; - MmInitializeRegion(&MArea->Data.SectionData.RegionListHead, - ViewSize, 0, Protect); + MArea->Data.SectionData.Segment = Segment; + MArea->Data.SectionData.Section = Section; + MArea->Data.SectionData.ViewOffset.QuadPart = ViewOffset; + MmInitializeRegion(&MArea->Data.SectionData.RegionListHead, + ViewSize, 0, Protect); - return(STATUS_SUCCESS); + return(STATUS_SUCCESS); } @@ -3982,123 +3987,123 @@ static VOID MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, PFN_NUMBER Page, SWAPENTRY SwapEntry, BOOLEAN Dirty) { - ULONG_PTR Entry; - PFILE_OBJECT FileObject; - PROS_SHARED_CACHE_MAP SharedCacheMap; - LARGE_INTEGER Offset; - SWAPENTRY SavedSwapEntry; - PROS_SECTION_OBJECT Section; - PMM_SECTION_SEGMENT Segment; - PMMSUPPORT AddressSpace; - PEPROCESS Process; + ULONG_PTR Entry; + PFILE_OBJECT FileObject; + PROS_SHARED_CACHE_MAP SharedCacheMap; + LARGE_INTEGER Offset; + SWAPENTRY SavedSwapEntry; + PROS_SECTION_OBJECT Section; + PMM_SECTION_SEGMENT Segment; + PMMSUPPORT AddressSpace; + PEPROCESS Process; - AddressSpace = (PMMSUPPORT)Context; - Process = MmGetAddressSpaceOwner(AddressSpace); + AddressSpace = (PMMSUPPORT)Context; + Process = MmGetAddressSpaceOwner(AddressSpace); - Address = (PVOID)PAGE_ROUND_DOWN(Address); + Address = (PVOID)PAGE_ROUND_DOWN(Address); - Offset.QuadPart = ((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress) + - MemoryArea->Data.SectionData.ViewOffset.QuadPart; + Offset.QuadPart = ((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress) + + MemoryArea->Data.SectionData.ViewOffset.QuadPart; - Section = MemoryArea->Data.SectionData.Section; - Segment = MemoryArea->Data.SectionData.Segment; + Section = MemoryArea->Data.SectionData.Section; + Segment = MemoryArea->Data.SectionData.Segment; - Entry = MmGetPageEntrySectionSegment(Segment, &Offset); - while (Entry && IS_SWAP_FROM_SSE(Entry) && SWAPENTRY_FROM_SSE(Entry) == MM_WAIT_ENTRY) - { - MmUnlockSectionSegment(Segment); - MmUnlockAddressSpace(AddressSpace); + Entry = MmGetPageEntrySectionSegment(Segment, &Offset); + while (Entry && IS_SWAP_FROM_SSE(Entry) && SWAPENTRY_FROM_SSE(Entry) == MM_WAIT_ENTRY) + { + MmUnlockSectionSegment(Segment); + MmUnlockAddressSpace(AddressSpace); - MiWaitForPageEvent(NULL, NULL); + MiWaitForPageEvent(NULL, NULL); - MmLockAddressSpace(AddressSpace); - MmLockSectionSegment(Segment); - Entry = MmGetPageEntrySectionSegment(Segment, &Offset); - } + MmLockAddressSpace(AddressSpace); + MmLockSectionSegment(Segment); + Entry = MmGetPageEntrySectionSegment(Segment, &Offset); + } - /* - * For a dirty, datafile, non-private page mark it as dirty in the - * cache manager. - */ - if (Segment->Flags & MM_DATAFILE_SEGMENT) - { - if (Page == PFN_FROM_SSE(Entry) && Dirty) - { - FileObject = MemoryArea->Data.SectionData.Section->FileObject; - SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap; + /* + * For a dirty, datafile, non-private page mark it as dirty in the + * cache manager. + */ + if (Segment->Flags & MM_DATAFILE_SEGMENT) + { + if (Page == PFN_FROM_SSE(Entry) && Dirty) + { + FileObject = MemoryArea->Data.SectionData.Section->FileObject; + SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap; #ifndef NEWCC - CcRosMarkDirtyVacb(SharedCacheMap, Offset.QuadPart + Segment->Image.FileOffset); + CcRosMarkDirtyVacb(SharedCacheMap, Offset.QuadPart + Segment->Image.FileOffset); #endif - ASSERT(SwapEntry == 0); - } - } + ASSERT(SwapEntry == 0); + } + } - if (SwapEntry != 0) - { - /* - * Sanity check - */ - if (Segment->Flags & MM_PAGEFILE_SEGMENT) - { - DPRINT1("Found a swap entry for a page in a pagefile section.\n"); - KeBugCheck(MEMORY_MANAGEMENT); - } - MmFreeSwapPage(SwapEntry); - } - else if (Page != 0) - { - if (IS_SWAP_FROM_SSE(Entry) || - Page != PFN_FROM_SSE(Entry)) - { - /* - * Sanity check - */ - if (Segment->Flags & MM_PAGEFILE_SEGMENT) - { - DPRINT1("Found a private page in a pagefile section.\n"); + if (SwapEntry != 0) + { + /* + * Sanity check + */ + if (Segment->Flags & MM_PAGEFILE_SEGMENT) + { + DPRINT1("Found a swap entry for a page in a pagefile section.\n"); KeBugCheck(MEMORY_MANAGEMENT); - } - /* - * Just dereference private pages - */ - SavedSwapEntry = MmGetSavedSwapEntryPage(Page); - if (SavedSwapEntry != 0) - { - MmFreeSwapPage(SavedSwapEntry); - MmSetSavedSwapEntryPage(Page, 0); - } - MmDeleteRmap(Page, Process, Address); - MmReleasePageMemoryConsumer(MC_USER, Page); - } - else - { - MmDeleteRmap(Page, Process, Address); - MmUnsharePageEntrySectionSegment(Section, Segment, &Offset, Dirty, FALSE, NULL); - } - } + } + MmFreeSwapPage(SwapEntry); + } + else if (Page != 0) + { + if (IS_SWAP_FROM_SSE(Entry) || + Page != PFN_FROM_SSE(Entry)) + { + /* + * Sanity check + */ + if (Segment->Flags & MM_PAGEFILE_SEGMENT) + { + DPRINT1("Found a private page in a pagefile section.\n"); + KeBugCheck(MEMORY_MANAGEMENT); + } + /* + * Just dereference private pages + */ + SavedSwapEntry = MmGetSavedSwapEntryPage(Page); + if (SavedSwapEntry != 0) + { + MmFreeSwapPage(SavedSwapEntry); + MmSetSavedSwapEntryPage(Page, 0); + } + MmDeleteRmap(Page, Process, Address); + MmReleasePageMemoryConsumer(MC_USER, Page); + } + else + { + MmDeleteRmap(Page, Process, Address); + MmUnsharePageEntrySectionSegment(Section, Segment, &Offset, Dirty, FALSE, NULL); + } + } } static NTSTATUS MmUnmapViewOfSegment(PMMSUPPORT AddressSpace, PVOID BaseAddress) { - NTSTATUS Status; - PMEMORY_AREA MemoryArea; - PROS_SECTION_OBJECT Section; - PMM_SECTION_SEGMENT Segment; - PLIST_ENTRY CurrentEntry; - PMM_REGION CurrentRegion; - PLIST_ENTRY RegionListHead; + NTSTATUS Status; + PMEMORY_AREA MemoryArea; + PROS_SECTION_OBJECT Section; + PMM_SECTION_SEGMENT Segment; + PLIST_ENTRY CurrentEntry; + PMM_REGION CurrentRegion; + PLIST_ENTRY RegionListHead; - MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, - BaseAddress); - if (MemoryArea == NULL) - { - return(STATUS_UNSUCCESSFUL); - } + MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, + BaseAddress); + if (MemoryArea == NULL) + { + return(STATUS_UNSUCCESSFUL); + } - Section = MemoryArea->Data.SectionData.Section; - Segment = MemoryArea->Data.SectionData.Segment; + Section = MemoryArea->Data.SectionData.Section; + Segment = MemoryArea->Data.SectionData.Segment; #ifdef NEWCC if (Segment->Flags & MM_DATAFILE_SEGMENT) @@ -4111,35 +4116,35 @@ MmUnmapViewOfSegment(PMMSUPPORT AddressSpace, } #endif - MemoryArea->DeleteInProgress = TRUE; + MemoryArea->DeleteInProgress = TRUE; - MmLockSectionSegment(Segment); + MmLockSectionSegment(Segment); - RegionListHead = &MemoryArea->Data.SectionData.RegionListHead; - while (!IsListEmpty(RegionListHead)) - { - CurrentEntry = RemoveHeadList(RegionListHead); - CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, RegionListEntry); - ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION); - } + RegionListHead = &MemoryArea->Data.SectionData.RegionListHead; + while (!IsListEmpty(RegionListHead)) + { + CurrentEntry = RemoveHeadList(RegionListHead); + CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, RegionListEntry); + ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION); + } - if (Section->AllocationAttributes & SEC_PHYSICALMEMORY) - { - Status = MmFreeMemoryArea(AddressSpace, - MemoryArea, - NULL, - NULL); - } - else - { - Status = MmFreeMemoryArea(AddressSpace, - MemoryArea, - MmFreeSectionPage, - AddressSpace); - } - MmUnlockSectionSegment(Segment); - ObDereferenceObject(Section); - return(Status); + if (Section->AllocationAttributes & SEC_PHYSICALMEMORY) + { + Status = MmFreeMemoryArea(AddressSpace, + MemoryArea, + NULL, + NULL); + } + else + { + Status = MmFreeMemoryArea(AddressSpace, + MemoryArea, + MmFreeSectionPage, + AddressSpace); + } + MmUnlockSectionSegment(Segment); + ObDereferenceObject(Section); + return(Status); } NTSTATUS @@ -4148,91 +4153,91 @@ MiRosUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress, IN ULONG Flags) { - NTSTATUS Status; - PMEMORY_AREA MemoryArea; - PMMSUPPORT AddressSpace; - PROS_SECTION_OBJECT Section; - PVOID ImageBaseAddress = 0; + NTSTATUS Status; + PMEMORY_AREA MemoryArea; + PMMSUPPORT AddressSpace; + PROS_SECTION_OBJECT Section; + PVOID ImageBaseAddress = 0; - DPRINT("Opening memory area Process %p BaseAddress %p\n", - Process, BaseAddress); + DPRINT("Opening memory area Process %p BaseAddress %p\n", + Process, BaseAddress); - ASSERT(Process); + ASSERT(Process); - AddressSpace = Process ? &Process->Vm : MmGetKernelAddressSpace(); + AddressSpace = Process ? &Process->Vm : MmGetKernelAddressSpace(); - MmLockAddressSpace(AddressSpace); - MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, - BaseAddress); - if (MemoryArea == NULL || - ((MemoryArea->Type != MEMORY_AREA_SECTION_VIEW) && - (MemoryArea->Type != MEMORY_AREA_CACHE)) || - MemoryArea->DeleteInProgress) - { - if (MemoryArea) NT_ASSERT(MemoryArea->Type != MEMORY_AREA_OWNED_BY_ARM3); - MmUnlockAddressSpace(AddressSpace); - return STATUS_NOT_MAPPED_VIEW; - } + MmLockAddressSpace(AddressSpace); + MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, + BaseAddress); + if (MemoryArea == NULL || + ((MemoryArea->Type != MEMORY_AREA_SECTION_VIEW) && + (MemoryArea->Type != MEMORY_AREA_CACHE)) || + MemoryArea->DeleteInProgress) + { + if (MemoryArea) NT_ASSERT(MemoryArea->Type != MEMORY_AREA_OWNED_BY_ARM3); + MmUnlockAddressSpace(AddressSpace); + return STATUS_NOT_MAPPED_VIEW; + } - Section = MemoryArea->Data.SectionData.Section; + Section = MemoryArea->Data.SectionData.Section; - if ((Section != NULL) && (Section->AllocationAttributes & SEC_IMAGE)) - { - ULONG i; - ULONG NrSegments; - PMM_IMAGE_SECTION_OBJECT ImageSectionObject; - PMM_SECTION_SEGMENT SectionSegments; - PMM_SECTION_SEGMENT Segment; + if ((Section != NULL) && (Section->AllocationAttributes & SEC_IMAGE)) + { + ULONG i; + ULONG NrSegments; + PMM_IMAGE_SECTION_OBJECT ImageSectionObject; + PMM_SECTION_SEGMENT SectionSegments; + PMM_SECTION_SEGMENT Segment; - Segment = MemoryArea->Data.SectionData.Segment; - ImageSectionObject = Section->ImageSection; - SectionSegments = ImageSectionObject->Segments; - NrSegments = ImageSectionObject->NrSegments; + Segment = MemoryArea->Data.SectionData.Segment; + ImageSectionObject = Section->ImageSection; + SectionSegments = ImageSectionObject->Segments; + NrSegments = ImageSectionObject->NrSegments; - MemoryArea->DeleteInProgress = TRUE; + MemoryArea->DeleteInProgress = TRUE; - /* Search for the current segment within the section segments - * and calculate the image base address */ - for (i = 0; i < NrSegments; i++) - { - if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD)) - { - if (Segment == &SectionSegments[i]) + /* Search for the current segment within the section segments + * and calculate the image base address */ + for (i = 0; i < NrSegments; i++) + { + if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD)) { - ImageBaseAddress = (char*)BaseAddress - (ULONG_PTR)SectionSegments[i].Image.VirtualAddress; - break; + if (Segment == &SectionSegments[i]) + { + ImageBaseAddress = (char*)BaseAddress - (ULONG_PTR)SectionSegments[i].Image.VirtualAddress; + break; + } } - } - } - if (i >= NrSegments) - { - KeBugCheck(MEMORY_MANAGEMENT); - } + } + if (i >= NrSegments) + { + KeBugCheck(MEMORY_MANAGEMENT); + } - for (i = 0; i < NrSegments; i++) - { - if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD)) - { - PVOID SBaseAddress = (PVOID) - ((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress); + for (i = 0; i < NrSegments; i++) + { + if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD)) + { + PVOID SBaseAddress = (PVOID) + ((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress); - Status = MmUnmapViewOfSegment(AddressSpace, SBaseAddress); - NT_ASSERT(NT_SUCCESS(Status)); - } - } - } - else - { - Status = MmUnmapViewOfSegment(AddressSpace, BaseAddress); - NT_ASSERT(NT_SUCCESS(Status)); - } + Status = MmUnmapViewOfSegment(AddressSpace, SBaseAddress); + NT_ASSERT(NT_SUCCESS(Status)); + } + } + } + else + { + Status = MmUnmapViewOfSegment(AddressSpace, BaseAddress); + NT_ASSERT(NT_SUCCESS(Status)); + } - MmUnlockAddressSpace(AddressSpace); + MmUnlockAddressSpace(AddressSpace); - /* Notify debugger */ - if (ImageBaseAddress) DbgkUnMapViewOfSection(ImageBaseAddress); + /* Notify debugger */ + if (ImageBaseAddress) DbgkUnMapViewOfSection(ImageBaseAddress); - return(STATUS_SUCCESS); + return(STATUS_SUCCESS); } @@ -4267,105 +4272,105 @@ NtQuerySection(IN HANDLE SectionHandle, IN SIZE_T SectionInformationLength, OUT PSIZE_T ResultLength OPTIONAL) { - PROS_SECTION_OBJECT Section; - KPROCESSOR_MODE PreviousMode; - NTSTATUS Status; - PAGED_CODE(); + PROS_SECTION_OBJECT Section; + KPROCESSOR_MODE PreviousMode; + NTSTATUS Status; + PAGED_CODE(); - PreviousMode = ExGetPreviousMode(); + PreviousMode = ExGetPreviousMode(); - Status = DefaultQueryInfoBufferCheck(SectionInformationClass, - ExSectionInfoClass, - sizeof(ExSectionInfoClass) / sizeof(ExSectionInfoClass[0]), - SectionInformation, - (ULONG)SectionInformationLength, - NULL, - ResultLength, - PreviousMode); + Status = DefaultQueryInfoBufferCheck(SectionInformationClass, + ExSectionInfoClass, + sizeof(ExSectionInfoClass) / sizeof(ExSectionInfoClass[0]), + SectionInformation, + (ULONG)SectionInformationLength, + NULL, + ResultLength, + PreviousMode); - if(!NT_SUCCESS(Status)) - { - DPRINT1("NtQuerySection() failed, Status: 0x%x\n", Status); - return Status; - } + if(!NT_SUCCESS(Status)) + { + DPRINT1("NtQuerySection() failed, Status: 0x%x\n", Status); + return Status; + } - Status = ObReferenceObjectByHandle(SectionHandle, - SECTION_QUERY, - MmSectionObjectType, - PreviousMode, - (PVOID*)(PVOID)&Section, - NULL); - if (NT_SUCCESS(Status)) - { - switch (SectionInformationClass) - { - case SectionBasicInformation: - { + Status = ObReferenceObjectByHandle(SectionHandle, + SECTION_QUERY, + MmSectionObjectType, + PreviousMode, + (PVOID*)(PVOID)&Section, + NULL); + if (NT_SUCCESS(Status)) + { + switch (SectionInformationClass) + { + case SectionBasicInformation: + { PSECTION_BASIC_INFORMATION Sbi = (PSECTION_BASIC_INFORMATION)SectionInformation; _SEH2_TRY { - Sbi->Attributes = Section->AllocationAttributes; - if (Section->AllocationAttributes & SEC_IMAGE) - { - Sbi->BaseAddress = 0; - Sbi->Size.QuadPart = 0; - } - else - { - Sbi->BaseAddress = (PVOID)Section->Segment->Image.VirtualAddress; - Sbi->Size.QuadPart = Section->Segment->Length.QuadPart; - } + Sbi->Attributes = Section->AllocationAttributes; + if (Section->AllocationAttributes & SEC_IMAGE) + { + Sbi->BaseAddress = 0; + Sbi->Size.QuadPart = 0; + } + else + { + Sbi->BaseAddress = (PVOID)Section->Segment->Image.VirtualAddress; + Sbi->Size.QuadPart = Section->Segment->Length.QuadPart; + } - if (ResultLength != NULL) - { - *ResultLength = sizeof(SECTION_BASIC_INFORMATION); - } - Status = STATUS_SUCCESS; + if (ResultLength != NULL) + { + *ResultLength = sizeof(SECTION_BASIC_INFORMATION); + } + Status = STATUS_SUCCESS; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - Status = _SEH2_GetExceptionCode(); + Status = _SEH2_GetExceptionCode(); } _SEH2_END; break; - } + } - case SectionImageInformation: - { + case SectionImageInformation: + { PSECTION_IMAGE_INFORMATION Sii = (PSECTION_IMAGE_INFORMATION)SectionInformation; _SEH2_TRY { - if (Section->AllocationAttributes & SEC_IMAGE) - { - PMM_IMAGE_SECTION_OBJECT ImageSectionObject; - ImageSectionObject = Section->ImageSection; + if (Section->AllocationAttributes & SEC_IMAGE) + { + PMM_IMAGE_SECTION_OBJECT ImageSectionObject; + ImageSectionObject = Section->ImageSection; - *Sii = ImageSectionObject->ImageInformation; - } + *Sii = ImageSectionObject->ImageInformation; + } - if (ResultLength != NULL) - { - *ResultLength = sizeof(SECTION_IMAGE_INFORMATION); - } - Status = STATUS_SUCCESS; + if (ResultLength != NULL) + { + *ResultLength = sizeof(SECTION_IMAGE_INFORMATION); + } + Status = STATUS_SUCCESS; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - Status = _SEH2_GetExceptionCode(); + Status = _SEH2_GetExceptionCode(); } _SEH2_END; break; - } - } + } + } - ObDereferenceObject(Section); - } + ObDereferenceObject(Section); + } - return(Status); + return(Status); } /********************************************************************** @@ -4429,222 +4434,222 @@ MmMapViewOfSection(IN PVOID SectionObject, IN ULONG AllocationType, IN ULONG Protect) { - PROS_SECTION_OBJECT Section; - PMMSUPPORT AddressSpace; - ULONG ViewOffset; - NTSTATUS Status = STATUS_SUCCESS; - BOOLEAN NotAtBase = FALSE; + PROS_SECTION_OBJECT Section; + PMMSUPPORT AddressSpace; + ULONG ViewOffset; + NTSTATUS Status = STATUS_SUCCESS; + BOOLEAN NotAtBase = FALSE; - if (MiIsRosSectionObject(SectionObject) == FALSE) - { - DPRINT("Mapping ARM3 section into %s\n", Process->ImageFileName); - return MmMapViewOfArm3Section(SectionObject, - Process, - BaseAddress, - ZeroBits, - CommitSize, - SectionOffset, - ViewSize, - InheritDisposition, - AllocationType, - Protect); - } + if (MiIsRosSectionObject(SectionObject) == FALSE) + { + DPRINT("Mapping ARM3 section into %s\n", Process->ImageFileName); + return MmMapViewOfArm3Section(SectionObject, + Process, + BaseAddress, + ZeroBits, + CommitSize, + SectionOffset, + ViewSize, + InheritDisposition, + AllocationType, + Protect); + } - ASSERT(Process); + ASSERT(Process); - if (!Protect || Protect & ~PAGE_FLAGS_VALID_FOR_SECTION) - { - return STATUS_INVALID_PAGE_PROTECTION; - } + if (!Protect || Protect & ~PAGE_FLAGS_VALID_FOR_SECTION) + { + return STATUS_INVALID_PAGE_PROTECTION; + } - Section = (PROS_SECTION_OBJECT)SectionObject; - AddressSpace = &Process->Vm; + Section = (PROS_SECTION_OBJECT)SectionObject; + AddressSpace = &Process->Vm; - AllocationType |= (Section->AllocationAttributes & SEC_NO_CHANGE); + AllocationType |= (Section->AllocationAttributes & SEC_NO_CHANGE); - MmLockAddressSpace(AddressSpace); + MmLockAddressSpace(AddressSpace); - if (Section->AllocationAttributes & SEC_IMAGE) - { - ULONG i; - ULONG NrSegments; - ULONG_PTR ImageBase; - SIZE_T ImageSize; - PMM_IMAGE_SECTION_OBJECT ImageSectionObject; - PMM_SECTION_SEGMENT SectionSegments; + if (Section->AllocationAttributes & SEC_IMAGE) + { + ULONG i; + ULONG NrSegments; + ULONG_PTR ImageBase; + SIZE_T ImageSize; + PMM_IMAGE_SECTION_OBJECT ImageSectionObject; + PMM_SECTION_SEGMENT SectionSegments; - ImageSectionObject = Section->ImageSection; - SectionSegments = ImageSectionObject->Segments; - NrSegments = ImageSectionObject->NrSegments; + ImageSectionObject = Section->ImageSection; + SectionSegments = ImageSectionObject->Segments; + NrSegments = ImageSectionObject->NrSegments; - ImageBase = (ULONG_PTR)*BaseAddress; - if (ImageBase == 0) - { - ImageBase = (ULONG_PTR)ImageSectionObject->BasedAddress; - } + ImageBase = (ULONG_PTR)*BaseAddress; + if (ImageBase == 0) + { + ImageBase = (ULONG_PTR)ImageSectionObject->BasedAddress; + } - ImageSize = 0; - for (i = 0; i < NrSegments; i++) - { - if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD)) - { - ULONG_PTR MaxExtent; - MaxExtent = (ULONG_PTR)(SectionSegments[i].Image.VirtualAddress + - SectionSegments[i].Length.QuadPart); - ImageSize = max(ImageSize, MaxExtent); - } - } - - ImageSectionObject->ImageInformation.ImageFileSize = (ULONG)ImageSize; - - /* Check for an illegal base address */ - if (((ImageBase + ImageSize) > (ULONG_PTR)MmHighestUserAddress) || - ((ImageBase + ImageSize) < ImageSize)) - { - NT_ASSERT(*BaseAddress == NULL); - ImageBase = ALIGN_DOWN_BY((ULONG_PTR)MmHighestUserAddress - ImageSize, - MM_VIRTMEM_GRANULARITY); - NotAtBase = TRUE; - } - else if (ImageBase != ALIGN_DOWN_BY(ImageBase, MM_VIRTMEM_GRANULARITY)) - { - NT_ASSERT(*BaseAddress == NULL); - ImageBase = ALIGN_DOWN_BY(ImageBase, MM_VIRTMEM_GRANULARITY); - NotAtBase = TRUE; - } - - /* Check there is enough space to map the section at that point. */ - if (MmLocateMemoryAreaByRegion(AddressSpace, (PVOID)ImageBase, - PAGE_ROUND_UP(ImageSize)) != NULL) - { - /* Fail if the user requested a fixed base address. */ - if ((*BaseAddress) != NULL) - { - MmUnlockAddressSpace(AddressSpace); - return(STATUS_CONFLICTING_ADDRESSES); - } - /* Otherwise find a gap to map the image. */ - ImageBase = (ULONG_PTR)MmFindGap(AddressSpace, PAGE_ROUND_UP(ImageSize), MM_VIRTMEM_GRANULARITY, FALSE); - if (ImageBase == 0) - { - MmUnlockAddressSpace(AddressSpace); - return(STATUS_CONFLICTING_ADDRESSES); - } - /* Remember that we loaded image at a different base address */ - NotAtBase = TRUE; - } - - for (i = 0; i < NrSegments; i++) - { - if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD)) - { - PVOID SBaseAddress = (PVOID) - ((char*)ImageBase + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress); - MmLockSectionSegment(&SectionSegments[i]); - Status = MmMapViewOfSegment(AddressSpace, - Section, - &SectionSegments[i], - &SBaseAddress, - SectionSegments[i].Length.LowPart, - SectionSegments[i].Protection, - 0, - 0); - MmUnlockSectionSegment(&SectionSegments[i]); - if (!NT_SUCCESS(Status)) + ImageSize = 0; + for (i = 0; i < NrSegments; i++) + { + if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD)) { - MmUnlockAddressSpace(AddressSpace); - return(Status); + ULONG_PTR MaxExtent; + MaxExtent = (ULONG_PTR)(SectionSegments[i].Image.VirtualAddress + + SectionSegments[i].Length.QuadPart); + ImageSize = max(ImageSize, MaxExtent); } - } - } + } - *BaseAddress = (PVOID)ImageBase; - *ViewSize = ImageSize; - } - else - { - /* check for write access */ - if ((Protect & (PAGE_READWRITE|PAGE_EXECUTE_READWRITE)) && - !(Section->SectionPageProtection & (PAGE_READWRITE|PAGE_EXECUTE_READWRITE))) - { - MmUnlockAddressSpace(AddressSpace); - return STATUS_SECTION_PROTECTION; - } - /* check for read access */ - if ((Protect & (PAGE_READONLY|PAGE_WRITECOPY|PAGE_EXECUTE_READ|PAGE_EXECUTE_WRITECOPY)) && - !(Section->SectionPageProtection & (PAGE_READONLY|PAGE_READWRITE|PAGE_WRITECOPY|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY))) - { - MmUnlockAddressSpace(AddressSpace); - return STATUS_SECTION_PROTECTION; - } - /* check for execute access */ - if ((Protect & (PAGE_EXECUTE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY)) && - !(Section->SectionPageProtection & (PAGE_EXECUTE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY))) - { - MmUnlockAddressSpace(AddressSpace); - return STATUS_SECTION_PROTECTION; - } + ImageSectionObject->ImageInformation.ImageFileSize = (ULONG)ImageSize; - if (ViewSize == NULL) - { - /* Following this pointer would lead to us to the dark side */ - /* What to do? Bugcheck? Return status? Do the mambo? */ - KeBugCheck(MEMORY_MANAGEMENT); - } + /* Check for an illegal base address */ + if (((ImageBase + ImageSize) > (ULONG_PTR)MmHighestUserAddress) || + ((ImageBase + ImageSize) < ImageSize)) + { + NT_ASSERT(*BaseAddress == NULL); + ImageBase = ALIGN_DOWN_BY((ULONG_PTR)MmHighestUserAddress - ImageSize, + MM_VIRTMEM_GRANULARITY); + NotAtBase = TRUE; + } + else if (ImageBase != ALIGN_DOWN_BY(ImageBase, MM_VIRTMEM_GRANULARITY)) + { + NT_ASSERT(*BaseAddress == NULL); + ImageBase = ALIGN_DOWN_BY(ImageBase, MM_VIRTMEM_GRANULARITY); + NotAtBase = TRUE; + } - if (SectionOffset == NULL) - { - ViewOffset = 0; - } - else - { - ViewOffset = SectionOffset->u.LowPart; - } + /* Check there is enough space to map the section at that point. */ + if (MmLocateMemoryAreaByRegion(AddressSpace, (PVOID)ImageBase, + PAGE_ROUND_UP(ImageSize)) != NULL) + { + /* Fail if the user requested a fixed base address. */ + if ((*BaseAddress) != NULL) + { + MmUnlockAddressSpace(AddressSpace); + return(STATUS_CONFLICTING_ADDRESSES); + } + /* Otherwise find a gap to map the image. */ + ImageBase = (ULONG_PTR)MmFindGap(AddressSpace, PAGE_ROUND_UP(ImageSize), MM_VIRTMEM_GRANULARITY, FALSE); + if (ImageBase == 0) + { + MmUnlockAddressSpace(AddressSpace); + return(STATUS_CONFLICTING_ADDRESSES); + } + /* Remember that we loaded image at a different base address */ + NotAtBase = TRUE; + } - if ((ViewOffset % PAGE_SIZE) != 0) - { - MmUnlockAddressSpace(AddressSpace); - return(STATUS_MAPPED_ALIGNMENT); - } + for (i = 0; i < NrSegments; i++) + { + if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD)) + { + PVOID SBaseAddress = (PVOID) + ((char*)ImageBase + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress); + MmLockSectionSegment(&SectionSegments[i]); + Status = MmMapViewOfSegment(AddressSpace, + Section, + &SectionSegments[i], + &SBaseAddress, + SectionSegments[i].Length.LowPart, + SectionSegments[i].Protection, + 0, + 0); + MmUnlockSectionSegment(&SectionSegments[i]); + if (!NT_SUCCESS(Status)) + { + MmUnlockAddressSpace(AddressSpace); + return(Status); + } + } + } - if ((*ViewSize) == 0) - { - (*ViewSize) = Section->MaximumSize.u.LowPart - ViewOffset; - } - else if (((*ViewSize)+ViewOffset) > Section->MaximumSize.u.LowPart) - { - (*ViewSize) = Section->MaximumSize.u.LowPart - ViewOffset; - } + *BaseAddress = (PVOID)ImageBase; + *ViewSize = ImageSize; + } + else + { + /* check for write access */ + if ((Protect & (PAGE_READWRITE|PAGE_EXECUTE_READWRITE)) && + !(Section->SectionPageProtection & (PAGE_READWRITE|PAGE_EXECUTE_READWRITE))) + { + MmUnlockAddressSpace(AddressSpace); + return STATUS_SECTION_PROTECTION; + } + /* check for read access */ + if ((Protect & (PAGE_READONLY|PAGE_WRITECOPY|PAGE_EXECUTE_READ|PAGE_EXECUTE_WRITECOPY)) && + !(Section->SectionPageProtection & (PAGE_READONLY|PAGE_READWRITE|PAGE_WRITECOPY|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY))) + { + MmUnlockAddressSpace(AddressSpace); + return STATUS_SECTION_PROTECTION; + } + /* check for execute access */ + if ((Protect & (PAGE_EXECUTE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY)) && + !(Section->SectionPageProtection & (PAGE_EXECUTE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY))) + { + MmUnlockAddressSpace(AddressSpace); + return STATUS_SECTION_PROTECTION; + } - *ViewSize = PAGE_ROUND_UP(*ViewSize); + if (ViewSize == NULL) + { + /* Following this pointer would lead to us to the dark side */ + /* What to do? Bugcheck? Return status? Do the mambo? */ + KeBugCheck(MEMORY_MANAGEMENT); + } - MmLockSectionSegment(Section->Segment); - Status = MmMapViewOfSegment(AddressSpace, - Section, - Section->Segment, - BaseAddress, - *ViewSize, - Protect, - ViewOffset, - AllocationType & (MEM_TOP_DOWN|SEC_NO_CHANGE)); - MmUnlockSectionSegment(Section->Segment); - if (!NT_SUCCESS(Status)) - { - MmUnlockAddressSpace(AddressSpace); - return(Status); - } - } + if (SectionOffset == NULL) + { + ViewOffset = 0; + } + else + { + ViewOffset = SectionOffset->u.LowPart; + } - MmUnlockAddressSpace(AddressSpace); - NT_ASSERT(*BaseAddress == ALIGN_DOWN_POINTER_BY(*BaseAddress, MM_VIRTMEM_GRANULARITY)); + if ((ViewOffset % PAGE_SIZE) != 0) + { + MmUnlockAddressSpace(AddressSpace); + return(STATUS_MAPPED_ALIGNMENT); + } - if (NotAtBase) - Status = STATUS_IMAGE_NOT_AT_BASE; - else - Status = STATUS_SUCCESS; + if ((*ViewSize) == 0) + { + (*ViewSize) = Section->MaximumSize.u.LowPart - ViewOffset; + } + else if (((*ViewSize)+ViewOffset) > Section->MaximumSize.u.LowPart) + { + (*ViewSize) = Section->MaximumSize.u.LowPart - ViewOffset; + } - return Status; + *ViewSize = PAGE_ROUND_UP(*ViewSize); + + MmLockSectionSegment(Section->Segment); + Status = MmMapViewOfSegment(AddressSpace, + Section, + Section->Segment, + BaseAddress, + *ViewSize, + Protect, + ViewOffset, + AllocationType & (MEM_TOP_DOWN|SEC_NO_CHANGE)); + MmUnlockSectionSegment(Section->Segment); + if (!NT_SUCCESS(Status)) + { + MmUnlockAddressSpace(AddressSpace); + return(Status); + } + } + + MmUnlockAddressSpace(AddressSpace); + NT_ASSERT(*BaseAddress == ALIGN_DOWN_POINTER_BY(*BaseAddress, MM_VIRTMEM_GRANULARITY)); + + if (NotAtBase) + Status = STATUS_IMAGE_NOT_AT_BASE; + else + Status = STATUS_SUCCESS; + + return Status; } /* @@ -4654,68 +4659,68 @@ BOOLEAN NTAPI MmCanFileBeTruncated (IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN PLARGE_INTEGER NewFileSize) { - /* Check whether an ImageSectionObject exists */ - if (SectionObjectPointer->ImageSectionObject != NULL) - { - DPRINT1("ERROR: File can't be truncated because it has an image section\n"); - return FALSE; - } + /* Check whether an ImageSectionObject exists */ + if (SectionObjectPointer->ImageSectionObject != NULL) + { + DPRINT1("ERROR: File can't be truncated because it has an image section\n"); + return FALSE; + } - if (SectionObjectPointer->DataSectionObject != NULL) - { - PMM_SECTION_SEGMENT Segment; + if (SectionObjectPointer->DataSectionObject != NULL) + { + PMM_SECTION_SEGMENT Segment; - Segment = (PMM_SECTION_SEGMENT)SectionObjectPointer-> - DataSectionObject; + Segment = (PMM_SECTION_SEGMENT)SectionObjectPointer-> + DataSectionObject; - if (Segment->ReferenceCount != 0) - { + if (Segment->ReferenceCount != 0) + { #ifdef NEWCC - CC_FILE_SIZES FileSizes; - CcpLock(); - if (SectionObjectPointer->SharedCacheMap && (Segment->ReferenceCount > CcpCountCacheSections((PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap))) - { - CcpUnlock(); + CC_FILE_SIZES FileSizes; + CcpLock(); + if (SectionObjectPointer->SharedCacheMap && (Segment->ReferenceCount > CcpCountCacheSections((PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap))) + { + CcpUnlock(); + /* Check size of file */ + if (SectionObjectPointer->SharedCacheMap) + { + if (!CcGetFileSizes(Segment->FileObject, &FileSizes)) + { + return FALSE; + } + + if (NewFileSize->QuadPart <= FileSizes.FileSize.QuadPart) + { + return FALSE; + } + } + } + else + CcpUnlock(); +#else /* Check size of file */ if (SectionObjectPointer->SharedCacheMap) { - if (!CcGetFileSizes(Segment->FileObject, &FileSizes)) - { - return FALSE; - } - - if (NewFileSize->QuadPart <= FileSizes.FileSize.QuadPart) - { - return FALSE; - } + PROS_SHARED_CACHE_MAP SharedCacheMap = SectionObjectPointer->SharedCacheMap; + if (NewFileSize->QuadPart <= SharedCacheMap->FileSize.QuadPart) + { + return FALSE; + } } - } - else - CcpUnlock(); -#else - /* Check size of file */ - if (SectionObjectPointer->SharedCacheMap) - { - PROS_SHARED_CACHE_MAP SharedCacheMap = SectionObjectPointer->SharedCacheMap; - if (NewFileSize->QuadPart <= SharedCacheMap->FileSize.QuadPart) - { - return FALSE; - } - } #endif - } - else - { - /* Something must gone wrong - * how can we have a Section but no - * reference? */ - DPRINT("ERROR: DataSectionObject without reference!\n"); - } - } + } + else + { + /* Something must gone wrong + * how can we have a Section but no + * reference? */ + DPRINT("ERROR: DataSectionObject without reference!\n"); + } + } - DPRINT("FIXME: didn't check for outstanding write probes\n"); + DPRINT("FIXME: didn't check for outstanding write probes\n"); - return TRUE; + return TRUE; } @@ -4728,45 +4733,46 @@ BOOLEAN NTAPI MmFlushImageSection (IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN MMFLUSH_TYPE FlushType) { - BOOLEAN Result = TRUE; + BOOLEAN Result = TRUE; #ifdef NEWCC - PMM_SECTION_SEGMENT Segment; + PMM_SECTION_SEGMENT Segment; #endif - switch(FlushType) - { - case MmFlushForDelete: - if (SectionObjectPointer->ImageSectionObject || - SectionObjectPointer->DataSectionObject) - { + switch(FlushType) + { + case MmFlushForDelete: + if (SectionObjectPointer->ImageSectionObject || + SectionObjectPointer->DataSectionObject) + { return FALSE; - } + } #ifndef NEWCC - CcRosRemoveIfClosed(SectionObjectPointer); + CcRosRemoveIfClosed(SectionObjectPointer); #endif - return TRUE; - case MmFlushForWrite: - { - DPRINT("MmFlushImageSection(%d)\n", FlushType); + return TRUE; + case MmFlushForWrite: + { + DPRINT("MmFlushImageSection(%d)\n", FlushType); #ifdef NEWCC - Segment = (PMM_SECTION_SEGMENT)SectionObjectPointer->DataSectionObject; + Segment = (PMM_SECTION_SEGMENT)SectionObjectPointer->DataSectionObject; #endif - if (SectionObjectPointer->ImageSectionObject) { + if (SectionObjectPointer->ImageSectionObject) + { DPRINT1("SectionObject has ImageSection\n"); return FALSE; - } + } #ifdef NEWCC - CcpLock(); - Result = !SectionObjectPointer->SharedCacheMap || (Segment->ReferenceCount == CcpCountCacheSections((PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap)); - CcpUnlock(); - DPRINT("Result %d\n", Result); + CcpLock(); + Result = !SectionObjectPointer->SharedCacheMap || (Segment->ReferenceCount == CcpCountCacheSections((PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap)); + CcpUnlock(); + DPRINT("Result %d\n", Result); #endif - return Result; - } - } - return FALSE; + return Result; + } + } + return FALSE; } /* @@ -4777,10 +4783,10 @@ MmMapViewInSystemSpace (IN PVOID SectionObject, OUT PVOID * MappedBase, IN OUT PSIZE_T ViewSize) { - PROS_SECTION_OBJECT Section; - PMMSUPPORT AddressSpace; - NTSTATUS Status; - PAGED_CODE(); + PROS_SECTION_OBJECT Section; + PMMSUPPORT AddressSpace; + NTSTATUS Status; + PAGED_CODE(); if (MiIsRosSectionObject(SectionObject) == FALSE) { @@ -4790,59 +4796,59 @@ MmMapViewInSystemSpace (IN PVOID SectionObject, ViewSize); } - DPRINT("MmMapViewInSystemSpace() called\n"); + DPRINT("MmMapViewInSystemSpace() called\n"); - Section = (PROS_SECTION_OBJECT)SectionObject; - AddressSpace = MmGetKernelAddressSpace(); + Section = (PROS_SECTION_OBJECT)SectionObject; + AddressSpace = MmGetKernelAddressSpace(); - MmLockAddressSpace(AddressSpace); + MmLockAddressSpace(AddressSpace); - if ((*ViewSize) == 0) - { - (*ViewSize) = Section->MaximumSize.u.LowPart; - } - else if ((*ViewSize) > Section->MaximumSize.u.LowPart) - { - (*ViewSize) = Section->MaximumSize.u.LowPart; - } + if ((*ViewSize) == 0) + { + (*ViewSize) = Section->MaximumSize.u.LowPart; + } + else if ((*ViewSize) > Section->MaximumSize.u.LowPart) + { + (*ViewSize) = Section->MaximumSize.u.LowPart; + } - MmLockSectionSegment(Section->Segment); + MmLockSectionSegment(Section->Segment); - Status = MmMapViewOfSegment(AddressSpace, - Section, - Section->Segment, - MappedBase, - *ViewSize, - PAGE_READWRITE, - 0, - 0); + Status = MmMapViewOfSegment(AddressSpace, + Section, + Section->Segment, + MappedBase, + *ViewSize, + PAGE_READWRITE, + 0, + 0); - MmUnlockSectionSegment(Section->Segment); - MmUnlockAddressSpace(AddressSpace); + MmUnlockSectionSegment(Section->Segment); + MmUnlockAddressSpace(AddressSpace); - return Status; + return Status; } NTSTATUS NTAPI MiRosUnmapViewInSystemSpace(IN PVOID MappedBase) { - PMMSUPPORT AddressSpace; - NTSTATUS Status; + PMMSUPPORT AddressSpace; + NTSTATUS Status; - DPRINT("MmUnmapViewInSystemSpace() called\n"); + DPRINT("MmUnmapViewInSystemSpace() called\n"); - AddressSpace = MmGetKernelAddressSpace(); + AddressSpace = MmGetKernelAddressSpace(); - MmLockAddressSpace(AddressSpace); + MmLockAddressSpace(AddressSpace); - Status = MmUnmapViewOfSegment(AddressSpace, MappedBase); + Status = MmUnmapViewOfSegment(AddressSpace, MappedBase); - MmUnlockAddressSpace(AddressSpace); + MmUnlockAddressSpace(AddressSpace); - return Status; + return Status; } /**********************************************************************