From dbb520a63f0c6053c29468f7412dbe75f06f23b4 Mon Sep 17 00:00:00 2001 From: Gunnar Dalsnes Date: Sat, 10 Apr 2004 22:36:07 +0000 Subject: [PATCH] indent using astyle v1.15.3: astyle --style=ansi -c -s3 -S --convert-tabs %1 svn path=/trunk/; revision=9077 --- reactos/ntoskrnl/mm/anonmem.c | 1106 +++--- reactos/ntoskrnl/mm/aspace.c | 80 +- reactos/ntoskrnl/mm/balance.c | 538 +-- reactos/ntoskrnl/mm/cont.c | 300 +- reactos/ntoskrnl/mm/drvlck.c | 35 +- reactos/ntoskrnl/mm/freelist.c | 1199 +++--- reactos/ntoskrnl/mm/i386/page.c | 1340 +++---- reactos/ntoskrnl/mm/i386/pfault.c | 92 +- reactos/ntoskrnl/mm/iospace.c | 167 +- reactos/ntoskrnl/mm/kmap.c | 104 +- reactos/ntoskrnl/mm/marea.c | 700 ++-- reactos/ntoskrnl/mm/mdl.c | 615 ++-- reactos/ntoskrnl/mm/mm.c | 524 +-- reactos/ntoskrnl/mm/mminit.c | 396 +- reactos/ntoskrnl/mm/mpw.c | 136 +- reactos/ntoskrnl/mm/ncache.c | 132 +- reactos/ntoskrnl/mm/npool.c | 2194 +++++------ reactos/ntoskrnl/mm/pagefile.c | 1128 +++--- reactos/ntoskrnl/mm/pageop.c | 330 +- reactos/ntoskrnl/mm/pager.c | 91 +- reactos/ntoskrnl/mm/pagfault.c | 14 +- reactos/ntoskrnl/mm/pool.c | 121 +- reactos/ntoskrnl/mm/ppool.c | 656 ++-- reactos/ntoskrnl/mm/region.c | 404 ++- reactos/ntoskrnl/mm/rmap.c | 571 +-- reactos/ntoskrnl/mm/section.c | 5644 +++++++++++++++-------------- reactos/ntoskrnl/mm/slab.c | 387 +- reactos/ntoskrnl/mm/virtual.c | 662 ++-- reactos/ntoskrnl/mm/wset.c | 36 +- 29 files changed, 9925 insertions(+), 9777 deletions(-) diff --git a/reactos/ntoskrnl/mm/anonmem.c b/reactos/ntoskrnl/mm/anonmem.c index d01162cd205..05b9ce4c144 100644 --- a/reactos/ntoskrnl/mm/anonmem.c +++ b/reactos/ntoskrnl/mm/anonmem.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: anonmem.c,v 1.26 2004/03/07 17:48:41 arty Exp $ +/* $Id: anonmem.c,v 1.27 2004/04/10 22:35:25 gdalsnes Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/mm/anonmem.c @@ -38,96 +38,96 @@ /* FUNCTIONS *****************************************************************/ -NTSTATUS +NTSTATUS MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace, - PMEMORY_AREA MemoryArea, - PVOID Address, - PMM_PAGEOP PageOp) + PMEMORY_AREA MemoryArea, + PVOID Address, + PMM_PAGEOP PageOp) { - SWAPENTRY SwapEntry; - LARGE_INTEGER PhysicalAddress; - PMDL Mdl; - NTSTATUS Status; + SWAPENTRY SwapEntry; + LARGE_INTEGER PhysicalAddress; + PMDL Mdl; + NTSTATUS Status; - /* - * Check for paging out from a deleted virtual memory area. - */ - if (MemoryArea->DeleteInProgress) - { + /* + * Check for paging out from a deleted virtual memory area. + */ + if (MemoryArea->DeleteInProgress) + { PageOp->Status = STATUS_UNSUCCESSFUL; KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); MmReleasePageOp(PageOp); return(STATUS_UNSUCCESSFUL); - } + } - PhysicalAddress = - MmGetPhysicalAddressForProcess(AddressSpace->Process, Address); + PhysicalAddress = + MmGetPhysicalAddressForProcess(AddressSpace->Process, Address); - /* - * Get that the page actually is dirty. - */ - if (!MmIsDirtyPage(MemoryArea->Process, Address)) - { + /* + * Get that the page actually is dirty. + */ + if (!MmIsDirtyPage(MemoryArea->Process, Address)) + { PageOp->Status = STATUS_SUCCESS; KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); MmReleasePageOp(PageOp); return(STATUS_SUCCESS); - } + } - /* - * Speculatively set the mapping to clean. - */ - MmSetCleanPage(MemoryArea->Process, Address); - - /* - * If necessary, allocate an entry in the paging file for this page - */ - SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress); - if (SwapEntry == 0) - { + /* + * Speculatively set the mapping to clean. + */ + MmSetCleanPage(MemoryArea->Process, Address); + + /* + * If necessary, allocate an entry in the paging file for this page + */ + SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress); + if (SwapEntry == 0) + { SwapEntry = MmAllocSwapPage(); if (SwapEntry == 0) - { - MmSetDirtyPage(MemoryArea->Process, Address); - PageOp->Status = STATUS_PAGEFILE_QUOTA_EXCEEDED; - KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); - MmReleasePageOp(PageOp); - return(STATUS_PAGEFILE_QUOTA_EXCEEDED); - } - } + { + MmSetDirtyPage(MemoryArea->Process, Address); + PageOp->Status = STATUS_PAGEFILE_QUOTA_EXCEEDED; + KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); + MmReleasePageOp(PageOp); + return(STATUS_PAGEFILE_QUOTA_EXCEEDED); + } + } - /* - * Write the page to the pagefile - */ - Mdl = MmCreateMdl(NULL, NULL, PAGE_SIZE); - MmBuildMdlFromPages(Mdl, (PULONG)&PhysicalAddress); - Status = MmWriteToSwapPage(SwapEntry, Mdl); - if (!NT_SUCCESS(Status)) - { - DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n", - Status); + /* + * Write the page to the pagefile + */ + Mdl = MmCreateMdl(NULL, NULL, PAGE_SIZE); + MmBuildMdlFromPages(Mdl, (PULONG)&PhysicalAddress); + Status = MmWriteToSwapPage(SwapEntry, Mdl); + if (!NT_SUCCESS(Status)) + { + DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n", + Status); MmSetDirtyPage(MemoryArea->Process, Address); PageOp->Status = STATUS_UNSUCCESSFUL; KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); MmReleasePageOp(PageOp); return(STATUS_UNSUCCESSFUL); - } - - /* - * Otherwise we have succeeded. - */ - MmSetSavedSwapEntryPage(PhysicalAddress, SwapEntry); - PageOp->Status = STATUS_SUCCESS; - KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); - MmReleasePageOp(PageOp); - return(STATUS_SUCCESS); + } + + /* + * Otherwise we have succeeded. + */ + MmSetSavedSwapEntryPage(PhysicalAddress, SwapEntry); + PageOp->Status = STATUS_SUCCESS; + KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); + MmReleasePageOp(PageOp); + return(STATUS_SUCCESS); } -NTSTATUS +NTSTATUS MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace, - PMEMORY_AREA MemoryArea, - PVOID Address, - PMM_PAGEOP PageOp) + PMEMORY_AREA MemoryArea, + PVOID Address, + PMM_PAGEOP PageOp) { PHYSICAL_ADDRESS PhysicalAddress; BOOL WasDirty; @@ -136,67 +136,67 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace, PMDL Mdl; DPRINT("MmPageOutVirtualMemory(Address 0x%.8X) PID %d\n", - Address, MemoryArea->Process->UniqueProcessId); + Address, MemoryArea->Process->UniqueProcessId); /* * Check for paging out from a deleted virtual memory area. */ if (MemoryArea->DeleteInProgress) - { - PageOp->Status = STATUS_UNSUCCESSFUL; - KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); - MmReleasePageOp(PageOp); - return(STATUS_UNSUCCESSFUL); - } + { + PageOp->Status = STATUS_UNSUCCESSFUL; + KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); + MmReleasePageOp(PageOp); + return(STATUS_UNSUCCESSFUL); + } /* * Disable the virtual mapping. */ MmDisableVirtualMapping(MemoryArea->Process, Address, - &WasDirty, &PhysicalAddress); + &WasDirty, &PhysicalAddress); if (PhysicalAddress.QuadPart == 0) - { - KEBUGCHECK(0); - } + { + KEBUGCHECK(0); + } /* * Paging out non-dirty data is easy. */ if (!WasDirty) - { - MmDeleteVirtualMapping(MemoryArea->Process, Address, FALSE, NULL, NULL); - MmDeleteAllRmaps(PhysicalAddress, NULL, NULL); - if ((SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress)) != 0) - { - MmCreatePageFileMapping(MemoryArea->Process, Address, SwapEntry); - MmSetSavedSwapEntryPage(PhysicalAddress, 0); - } - MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress); - PageOp->Status = STATUS_SUCCESS; - KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); - MmReleasePageOp(PageOp); - return(STATUS_SUCCESS); - } + { + MmDeleteVirtualMapping(MemoryArea->Process, Address, FALSE, NULL, NULL); + MmDeleteAllRmaps(PhysicalAddress, NULL, NULL); + if ((SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress)) != 0) + { + MmCreatePageFileMapping(MemoryArea->Process, Address, SwapEntry); + MmSetSavedSwapEntryPage(PhysicalAddress, 0); + } + MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress); + PageOp->Status = STATUS_SUCCESS; + KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); + MmReleasePageOp(PageOp); + return(STATUS_SUCCESS); + } /* * If necessary, allocate an entry in the paging file for this page */ SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress); if (SwapEntry == 0) - { - SwapEntry = MmAllocSwapPage(); - if (SwapEntry == 0) - { - MmShowOutOfSpaceMessagePagingFile(); - MmEnableVirtualMapping(MemoryArea->Process, Address); - PageOp->Status = STATUS_UNSUCCESSFUL; - KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); - MmReleasePageOp(PageOp); - return(STATUS_PAGEFILE_QUOTA); - } - } - + { + SwapEntry = MmAllocSwapPage(); + if (SwapEntry == 0) + { + MmShowOutOfSpaceMessagePagingFile(); + MmEnableVirtualMapping(MemoryArea->Process, Address); + PageOp->Status = STATUS_UNSUCCESSFUL; + KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); + MmReleasePageOp(PageOp); + return(STATUS_PAGEFILE_QUOTA); + } + } + /* * Write the page to the pagefile */ @@ -204,15 +204,15 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace, MmBuildMdlFromPages(Mdl, (ULONG *)&PhysicalAddress.u.LowPart); Status = MmWriteToSwapPage(SwapEntry, Mdl); if (!NT_SUCCESS(Status)) - { - DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n", - Status); - MmEnableVirtualMapping(MemoryArea->Process, Address); - PageOp->Status = STATUS_UNSUCCESSFUL; - KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); - MmReleasePageOp(PageOp); - return(STATUS_UNSUCCESSFUL); - } + { + DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n", + Status); + MmEnableVirtualMapping(MemoryArea->Process, Address); + PageOp->Status = STATUS_UNSUCCESSFUL; + KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); + MmReleasePageOp(PageOp); + return(STATUS_UNSUCCESSFUL); + } /* * Otherwise we have succeeded, free the page @@ -231,9 +231,9 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace, NTSTATUS MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace, - MEMORY_AREA* MemoryArea, - PVOID Address, - BOOLEAN Locked) + MEMORY_AREA* MemoryArea, + PVOID Address, + BOOLEAN Locked) /* * FUNCTION: Move data into memory to satisfy a page not present fault * ARGUMENTS: @@ -248,118 +248,118 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace, NTSTATUS Status; PMM_REGION Region; PMM_PAGEOP PageOp; - + /* * 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(NULL, Address)) - { - if (Locked) - { - MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address)); - } - return(STATUS_SUCCESS); - } + { + if (Locked) + { + MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address)); + } + return(STATUS_SUCCESS); + } /* * Check for the virtual memory area being deleted. */ if (MemoryArea->DeleteInProgress) - { - return(STATUS_UNSUCCESSFUL); - } + { + return(STATUS_UNSUCCESSFUL); + } /* * Get the segment corresponding to the virtual address */ - Region = MmFindRegion(MemoryArea->BaseAddress, - &MemoryArea->Data.VirtualMemoryData.RegionListHead, - Address, NULL); + Region = MmFindRegion(MemoryArea->BaseAddress, + &MemoryArea->Data.VirtualMemoryData.RegionListHead, + Address, NULL); if (Region->Type == MEM_RESERVE || Region->Protect == PAGE_NOACCESS) - { - return(STATUS_ACCESS_VIOLATION); - } + { + return(STATUS_ACCESS_VIOLATION); + } /* * Get or create a page operation */ - PageOp = MmGetPageOp(MemoryArea, (ULONG)MemoryArea->Process->UniqueProcessId, - (PVOID)PAGE_ROUND_DOWN(Address), NULL, 0, - MM_PAGEOP_PAGEIN, FALSE); + PageOp = MmGetPageOp(MemoryArea, (ULONG)MemoryArea->Process->UniqueProcessId, + (PVOID)PAGE_ROUND_DOWN(Address), NULL, 0, + MM_PAGEOP_PAGEIN, FALSE); if (PageOp == NULL) - { - DPRINT1("MmGetPageOp failed"); - KEBUGCHECK(0); - } + { + DPRINT1("MmGetPageOp failed"); + KEBUGCHECK(0); + } /* * Check if someone else is already handling this fault, if so wait * for them */ if (PageOp->Thread != PsGetCurrentThread()) - { - MmUnlockAddressSpace(AddressSpace); - Status = KeWaitForSingleObject(&PageOp->CompletionEvent, - 0, - KernelMode, - FALSE, - NULL); - /* - * Check for various strange conditions - */ - if (Status != STATUS_SUCCESS) - { - DPRINT1("Failed to wait for page op\n"); - KEBUGCHECK(0); - } - if (PageOp->Status == STATUS_PENDING) - { - DPRINT1("Woke for page op before completion\n"); - KEBUGCHECK(0); - } - /* - * If this wasn't a pagein then we need to restart the handling - */ - if (PageOp->OpType != MM_PAGEOP_PAGEIN) - { - MmLockAddressSpace(AddressSpace); - KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); - MmReleasePageOp(PageOp); - return(STATUS_MM_RESTART_OPERATION); - } - /* - * If the thread handling this fault has failed then we don't retry - */ - if (!NT_SUCCESS(PageOp->Status)) - { - MmLockAddressSpace(AddressSpace); - KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); - Status = PageOp->Status; - MmReleasePageOp(PageOp); - return(Status); - } - MmLockAddressSpace(AddressSpace); - if (Locked) - { - MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address)); - } - KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); - MmReleasePageOp(PageOp); - return(STATUS_SUCCESS); - } - + { + MmUnlockAddressSpace(AddressSpace); + Status = KeWaitForSingleObject(&PageOp->CompletionEvent, + 0, + KernelMode, + FALSE, + NULL); + /* + * Check for various strange conditions + */ + if (Status != STATUS_SUCCESS) + { + DPRINT1("Failed to wait for page op\n"); + KEBUGCHECK(0); + } + if (PageOp->Status == STATUS_PENDING) + { + DPRINT1("Woke for page op before completion\n"); + KEBUGCHECK(0); + } + /* + * If this wasn't a pagein then we need to restart the handling + */ + if (PageOp->OpType != MM_PAGEOP_PAGEIN) + { + MmLockAddressSpace(AddressSpace); + KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); + MmReleasePageOp(PageOp); + return(STATUS_MM_RESTART_OPERATION); + } + /* + * If the thread handling this fault has failed then we don't retry + */ + if (!NT_SUCCESS(PageOp->Status)) + { + MmLockAddressSpace(AddressSpace); + KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); + Status = PageOp->Status; + MmReleasePageOp(PageOp); + return(Status); + } + MmLockAddressSpace(AddressSpace); + if (Locked) + { + MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address)); + } + KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); + MmReleasePageOp(PageOp); + return(STATUS_SUCCESS); + } + /* * Try to allocate a page */ Status = MmRequestPageMemoryConsumer(MC_USER, FALSE, &Page); if (Status == STATUS_NO_MEMORY) - { - MmUnlockAddressSpace(AddressSpace); - Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page); - MmLockAddressSpace(AddressSpace); - } + { + MmUnlockAddressSpace(AddressSpace); + Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page); + MmLockAddressSpace(AddressSpace); + } if (!NT_SUCCESS(Status)) { DPRINT1("MmRequestPageMemoryConsumer failed, status = %x\n", Status); @@ -370,46 +370,46 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace, * Handle swapped out pages. */ if (MmIsPageSwapEntry(NULL, Address)) - { - SWAPENTRY SwapEntry; - PMDL Mdl; + { + SWAPENTRY SwapEntry; + PMDL Mdl; + + MmDeletePageFileMapping(MemoryArea->Process, Address, &SwapEntry); + Mdl = MmCreateMdl(NULL, NULL, PAGE_SIZE); + MmBuildMdlFromPages(Mdl, (PULONG)&Page); + Status = MmReadFromSwapPage(SwapEntry, Mdl); + if (!NT_SUCCESS(Status)) + { + KEBUGCHECK(0); + } + MmSetSavedSwapEntryPage(Page, SwapEntry); + } - MmDeletePageFileMapping(MemoryArea->Process, Address, &SwapEntry); - Mdl = MmCreateMdl(NULL, NULL, PAGE_SIZE); - MmBuildMdlFromPages(Mdl, (PULONG)&Page); - Status = MmReadFromSwapPage(SwapEntry, Mdl); - if (!NT_SUCCESS(Status)) - { - KEBUGCHECK(0); - } - MmSetSavedSwapEntryPage(Page, SwapEntry); - } - /* * Set the page. If we fail because we are out of memory then * try again */ - Status = MmCreateVirtualMapping(MemoryArea->Process, - (PVOID)PAGE_ROUND_DOWN(Address), - Region->Protect, - Page, - FALSE); + Status = MmCreateVirtualMapping(MemoryArea->Process, + (PVOID)PAGE_ROUND_DOWN(Address), + Region->Protect, + Page, + FALSE); while (Status == STATUS_NO_MEMORY) - { - MmUnlockAddressSpace(AddressSpace); - Status = MmCreateVirtualMapping(MemoryArea->Process, - Address, - Region->Protect, - Page, - TRUE); - MmLockAddressSpace(AddressSpace); - } + { + MmUnlockAddressSpace(AddressSpace); + Status = MmCreateVirtualMapping(MemoryArea->Process, + Address, + Region->Protect, + Page, + TRUE); + MmLockAddressSpace(AddressSpace); + } if (!NT_SUCCESS(Status)) - { - DPRINT1("MmCreateVirtualMapping failed, not out of memory\n"); - KEBUGCHECK(0); - return(Status); - } + { + DPRINT1("MmCreateVirtualMapping failed, not out of memory\n"); + KEBUGCHECK(0); + return(Status); + } /* * Add the page to the process's working set @@ -420,9 +420,9 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace, * Finish the operation */ if (Locked) - { - MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address)); - } + { + MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address)); + } PageOp->Status = STATUS_SUCCESS; KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); MmReleasePageOp(PageOp); @@ -431,92 +431,92 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace, VOID STATIC MmModifyAttributes(PMADDRESS_SPACE AddressSpace, - PVOID BaseAddress, - ULONG RegionSize, - ULONG OldType, - ULONG OldProtect, - ULONG NewType, - ULONG NewProtect) + PVOID BaseAddress, + ULONG RegionSize, + ULONG OldType, + ULONG OldProtect, + ULONG NewType, + ULONG NewProtect) /* * FUNCTION: Modify the attributes of a memory region */ -{ - /* - * If we are switching a previously committed region to reserved then - * free any allocated pages within the region - */ - if (NewType == MEM_RESERVE && OldType == MEM_COMMIT) - { +{ + /* + * If we are switching a previously committed region to reserved then + * free any allocated pages within the region + */ + if (NewType == MEM_RESERVE && OldType == MEM_COMMIT) + { ULONG i; - + for (i=0; i < PAGE_ROUND_UP(RegionSize)/PAGE_SIZE; i++) - { - LARGE_INTEGER PhysicalAddr; + { + LARGE_INTEGER PhysicalAddr; - if (MmIsPageSwapEntry(AddressSpace->Process, - (char*)BaseAddress + (i * PAGE_SIZE))) - { - SWAPENTRY SwapEntry; - - MmDeletePageFileMapping(AddressSpace->Process, - (char*)BaseAddress + (i * PAGE_SIZE), - &SwapEntry); - MmFreeSwapPage(SwapEntry); - } - else - { - MmDeleteVirtualMapping(AddressSpace->Process, - (char*)BaseAddress + (i*PAGE_SIZE), - FALSE, NULL, &PhysicalAddr); - if (PhysicalAddr.QuadPart != 0) - { - SWAPENTRY SavedSwapEntry; - SavedSwapEntry = MmGetSavedSwapEntryPage(PhysicalAddr); - if (SavedSwapEntry != 0) - { - MmFreeSwapPage(SavedSwapEntry); - MmSetSavedSwapEntryPage(PhysicalAddr, 0); - } - MmDeleteRmap(PhysicalAddr, AddressSpace->Process, - (char*)BaseAddress + (i * PAGE_SIZE)); - MmReleasePageMemoryConsumer(MC_USER, PhysicalAddr); - } - } - } - } + if (MmIsPageSwapEntry(AddressSpace->Process, + (char*)BaseAddress + (i * PAGE_SIZE))) + { + SWAPENTRY SwapEntry; - /* - * If we are changing the protection attributes of a committed region then - * alter the attributes for any allocated pages within the region - */ - if (NewType == MEM_COMMIT && OldType == MEM_COMMIT && - OldProtect != NewProtect) - { + MmDeletePageFileMapping(AddressSpace->Process, + (char*)BaseAddress + (i * PAGE_SIZE), + &SwapEntry); + MmFreeSwapPage(SwapEntry); + } + else + { + MmDeleteVirtualMapping(AddressSpace->Process, + (char*)BaseAddress + (i*PAGE_SIZE), + FALSE, NULL, &PhysicalAddr); + if (PhysicalAddr.QuadPart != 0) + { + SWAPENTRY SavedSwapEntry; + SavedSwapEntry = MmGetSavedSwapEntryPage(PhysicalAddr); + if (SavedSwapEntry != 0) + { + MmFreeSwapPage(SavedSwapEntry); + MmSetSavedSwapEntryPage(PhysicalAddr, 0); + } + MmDeleteRmap(PhysicalAddr, AddressSpace->Process, + (char*)BaseAddress + (i * PAGE_SIZE)); + MmReleasePageMemoryConsumer(MC_USER, PhysicalAddr); + } + } + } + } + + /* + * If we are changing the protection attributes of a committed region then + * alter the attributes for any allocated pages within the region + */ + if (NewType == MEM_COMMIT && OldType == MEM_COMMIT && + OldProtect != NewProtect) + { ULONG i; - + for (i=0; i < PAGE_ROUND_UP(RegionSize)/PAGE_SIZE; i++) - { - if (MmIsPagePresent(AddressSpace->Process, - (char*)BaseAddress + (i*PAGE_SIZE))) - { - MmSetPageProtect(AddressSpace->Process, - (char*)BaseAddress + (i*PAGE_SIZE), - NewProtect); - } - } - } + { + if (MmIsPagePresent(AddressSpace->Process, + (char*)BaseAddress + (i*PAGE_SIZE))) + { + MmSetPageProtect(AddressSpace->Process, + (char*)BaseAddress + (i*PAGE_SIZE), + NewProtect); + } + } + } } /* * @implemented */ NTSTATUS STDCALL -NtAllocateVirtualMemory(IN HANDLE ProcessHandle, - IN OUT PVOID* UBaseAddress, - IN ULONG ZeroBits, - IN OUT PULONG URegionSize, - IN ULONG AllocationType, - IN ULONG Protect) +NtAllocateVirtualMemory(IN HANDLE ProcessHandle, + IN OUT PVOID* UBaseAddress, + IN ULONG ZeroBits, + IN OUT PULONG URegionSize, + IN ULONG AllocationType, + IN ULONG Protect) /* * FUNCTION: Allocates a block of virtual memory in the process address space * ARGUMENTS: @@ -551,120 +551,120 @@ NtAllocateVirtualMemory(IN HANDLE ProcessHandle, PHYSICAL_ADDRESS BoundaryAddressMultiple; DPRINT("NtAllocateVirtualMemory(*UBaseAddress %x, " - "ZeroBits %d, *URegionSize %x, AllocationType %x, Protect %x)\n", - *UBaseAddress,ZeroBits,*URegionSize,AllocationType, - Protect); - + "ZeroBits %d, *URegionSize %x, AllocationType %x, Protect %x)\n", + *UBaseAddress,ZeroBits,*URegionSize,AllocationType, + Protect); + /* * Check the validity of the parameters */ if ((Protect & PAGE_FLAGS_VALID_FROM_USER_MODE) != Protect) - { - return(STATUS_INVALID_PAGE_PROTECTION); - } + { + return(STATUS_INVALID_PAGE_PROTECTION); + } if ((AllocationType & (MEM_COMMIT | MEM_RESERVE)) == 0) - { - return(STATUS_INVALID_PARAMETER); - } - + { + return(STATUS_INVALID_PARAMETER); + } + PBaseAddress = *UBaseAddress; PRegionSize = *URegionSize; BoundaryAddressMultiple.QuadPart = 0; - + BaseAddress = (PVOID)PAGE_ROUND_DOWN(PBaseAddress); RegionSize = PAGE_ROUND_UP(PBaseAddress + PRegionSize) - - PAGE_ROUND_DOWN(PBaseAddress); - + PAGE_ROUND_DOWN(PBaseAddress); + Status = ObReferenceObjectByHandle(ProcessHandle, - PROCESS_VM_OPERATION, - NULL, - UserMode, - (PVOID*)(&Process), - NULL); + PROCESS_VM_OPERATION, + NULL, + UserMode, + (PVOID*)(&Process), + NULL); if (!NT_SUCCESS(Status)) - { - DPRINT("NtAllocateVirtualMemory() = %x\n",Status); - return(Status); - } - + { + DPRINT("NtAllocateVirtualMemory() = %x\n",Status); + return(Status); + } + Type = (AllocationType & MEM_COMMIT) ? MEM_COMMIT : MEM_RESERVE; DPRINT("Type %x\n", Type); - + AddressSpace = &Process->AddressSpace; MmLockAddressSpace(AddressSpace); - + if (PBaseAddress != 0) - { - MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, - BaseAddress); - - if (MemoryArea != NULL && - MemoryArea->Type == MEMORY_AREA_VIRTUAL_MEMORY && - MemoryArea->Length >= RegionSize) - { - Status = - MmAlterRegion(AddressSpace, - MemoryArea->BaseAddress, - &MemoryArea->Data.VirtualMemoryData.RegionListHead, - BaseAddress, RegionSize, - Type, Protect, MmModifyAttributes); - MmUnlockAddressSpace(AddressSpace); - ObDereferenceObject(Process); - DPRINT("NtAllocateVirtualMemory() = %x\n",Status); - return(Status); - } - else if (MemoryArea != NULL && MemoryArea->Length >= RegionSize) - { - Status = - MmAlterRegion(AddressSpace, - MemoryArea->BaseAddress, - &MemoryArea->Data.SectionData.RegionListHead, - BaseAddress, RegionSize, - Type, Protect, MmModifyAttributes); - MmUnlockAddressSpace(AddressSpace); - ObDereferenceObject(Process); - DPRINT("NtAllocateVirtualMemory() = %x\n",Status); - return(Status); - } - else if (MemoryArea != NULL) - { - MmUnlockAddressSpace(AddressSpace); - ObDereferenceObject(Process); - return(STATUS_UNSUCCESSFUL); - } - } - + { + MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, + BaseAddress); + + if (MemoryArea != NULL && + MemoryArea->Type == MEMORY_AREA_VIRTUAL_MEMORY && + MemoryArea->Length >= RegionSize) + { + Status = + MmAlterRegion(AddressSpace, + MemoryArea->BaseAddress, + &MemoryArea->Data.VirtualMemoryData.RegionListHead, + BaseAddress, RegionSize, + Type, Protect, MmModifyAttributes); + MmUnlockAddressSpace(AddressSpace); + ObDereferenceObject(Process); + DPRINT("NtAllocateVirtualMemory() = %x\n",Status); + return(Status); + } + else if (MemoryArea != NULL && MemoryArea->Length >= RegionSize) + { + Status = + MmAlterRegion(AddressSpace, + MemoryArea->BaseAddress, + &MemoryArea->Data.SectionData.RegionListHead, + BaseAddress, RegionSize, + Type, Protect, MmModifyAttributes); + MmUnlockAddressSpace(AddressSpace); + ObDereferenceObject(Process); + DPRINT("NtAllocateVirtualMemory() = %x\n",Status); + return(Status); + } + else if (MemoryArea != NULL) + { + MmUnlockAddressSpace(AddressSpace); + ObDereferenceObject(Process); + return(STATUS_UNSUCCESSFUL); + } + } + Status = MmCreateMemoryArea(Process, - AddressSpace, - MEMORY_AREA_VIRTUAL_MEMORY, - &BaseAddress, - RegionSize, - Protect, - &MemoryArea, - PBaseAddress != 0, - (AllocationType & MEM_TOP_DOWN), - BoundaryAddressMultiple); + AddressSpace, + MEMORY_AREA_VIRTUAL_MEMORY, + &BaseAddress, + RegionSize, + Protect, + &MemoryArea, + PBaseAddress != 0, + (AllocationType & MEM_TOP_DOWN), + BoundaryAddressMultiple); if (!NT_SUCCESS(Status)) - { - MmUnlockAddressSpace(AddressSpace); - ObDereferenceObject(Process); - DPRINT("NtAllocateVirtualMemory() = %x\n",Status); - return(Status); - } + { + MmUnlockAddressSpace(AddressSpace); + ObDereferenceObject(Process); + DPRINT("NtAllocateVirtualMemory() = %x\n",Status); + return(Status); + } MmInitialiseRegion(&MemoryArea->Data.VirtualMemoryData.RegionListHead, - RegionSize, Type, Protect); - + RegionSize, Type, Protect); + if ((AllocationType & MEM_COMMIT) && - ((Protect & PAGE_READWRITE) || - (Protect & PAGE_EXECUTE_READWRITE))) - { - MmReserveSwapPages(RegionSize); - } - + ((Protect & PAGE_READWRITE) || + (Protect & PAGE_EXECUTE_READWRITE))) + { + MmReserveSwapPages(RegionSize); + } + *UBaseAddress = BaseAddress; *URegionSize = RegionSize; DPRINT("*UBaseAddress %x *URegionSize %x\n", BaseAddress, RegionSize); - + MmUnlockAddressSpace(AddressSpace); ObDereferenceObject(Process); return(STATUS_SUCCESS); @@ -672,109 +672,109 @@ NtAllocateVirtualMemory(IN HANDLE ProcessHandle, VOID STATIC MmFreeVirtualMemoryPage(PVOID Context, - MEMORY_AREA* MemoryArea, - PVOID Address, - PHYSICAL_ADDRESS PhysicalAddr, - SWAPENTRY SwapEntry, - BOOLEAN Dirty) + MEMORY_AREA* MemoryArea, + PVOID Address, + PHYSICAL_ADDRESS PhysicalAddr, + SWAPENTRY SwapEntry, + BOOLEAN Dirty) { - PEPROCESS Process = (PEPROCESS)Context; - - if (PhysicalAddr.QuadPart != 0) - { + PEPROCESS Process = (PEPROCESS)Context; + + if (PhysicalAddr.QuadPart != 0) + { SWAPENTRY SavedSwapEntry; SavedSwapEntry = MmGetSavedSwapEntryPage(PhysicalAddr); if (SavedSwapEntry != 0) - { - MmFreeSwapPage(SavedSwapEntry); - MmSetSavedSwapEntryPage(PhysicalAddr, 0); - } + { + MmFreeSwapPage(SavedSwapEntry); + MmSetSavedSwapEntryPage(PhysicalAddr, 0); + } MmDeleteRmap(PhysicalAddr, Process, Address); MmReleasePageMemoryConsumer(MC_USER, PhysicalAddr); - } - else if (SwapEntry != 0) - { + } + else if (SwapEntry != 0) + { MmFreeSwapPage(SwapEntry); - } + } } VOID MmFreeVirtualMemory(PEPROCESS Process, - PMEMORY_AREA MemoryArea) + PMEMORY_AREA MemoryArea) { - PLIST_ENTRY current_entry; - PMM_REGION current; - ULONG i; - - DPRINT("MmFreeVirtualMemory(Process %p MemoryArea %p)\n", Process, - MemoryArea); - - /* Mark this memory area as about to be deleted. */ - MemoryArea->DeleteInProgress = TRUE; + PLIST_ENTRY current_entry; + PMM_REGION current; + ULONG i; - /* - * Wait for any ongoing paging operations. Notice that since we have - * flagged this memory area as deleted no more page ops will be added. - */ - if (MemoryArea->PageOpCount > 0) - { + DPRINT("MmFreeVirtualMemory(Process %p MemoryArea %p)\n", Process, + MemoryArea); + + /* Mark this memory area as about to be deleted. */ + MemoryArea->DeleteInProgress = TRUE; + + /* + * Wait for any ongoing paging operations. Notice that since we have + * flagged this memory area as deleted no more page ops will be added. + */ + if (MemoryArea->PageOpCount > 0) + { for (i = 0; i < PAGE_ROUND_UP(MemoryArea->Length) / PAGE_SIZE; i++) - { - PMM_PAGEOP PageOp; + { + PMM_PAGEOP PageOp; - if (MemoryArea->PageOpCount == 0) - { - break; - } - - PageOp = MmCheckForPageOp(MemoryArea, Process->UniqueProcessId, - (char*)MemoryArea->BaseAddress + (i * PAGE_SIZE), - NULL, 0); - if (PageOp != NULL) - { - NTSTATUS Status; - MmUnlockAddressSpace(&Process->AddressSpace); - Status = KeWaitForSingleObject(&PageOp->CompletionEvent, - 0, - KernelMode, - FALSE, - NULL); - if (Status != STATUS_SUCCESS) - { - DPRINT1("Failed to wait for page op\n"); - KEBUGCHECK(0); - } - MmLockAddressSpace(&Process->AddressSpace); - MmReleasePageOp(PageOp); - } - } - } + if (MemoryArea->PageOpCount == 0) + { + break; + } - /* Free all the individual segments. */ - current_entry = MemoryArea->Data.VirtualMemoryData.RegionListHead.Flink; - while (current_entry != &MemoryArea->Data.VirtualMemoryData.RegionListHead) - { + PageOp = MmCheckForPageOp(MemoryArea, Process->UniqueProcessId, + (char*)MemoryArea->BaseAddress + (i * PAGE_SIZE), + NULL, 0); + if (PageOp != NULL) + { + NTSTATUS Status; + MmUnlockAddressSpace(&Process->AddressSpace); + Status = KeWaitForSingleObject(&PageOp->CompletionEvent, + 0, + KernelMode, + FALSE, + NULL); + if (Status != STATUS_SUCCESS) + { + DPRINT1("Failed to wait for page op\n"); + KEBUGCHECK(0); + } + MmLockAddressSpace(&Process->AddressSpace); + MmReleasePageOp(PageOp); + } + } + } + + /* Free all the individual segments. */ + current_entry = MemoryArea->Data.VirtualMemoryData.RegionListHead.Flink; + while (current_entry != &MemoryArea->Data.VirtualMemoryData.RegionListHead) + { current = CONTAINING_RECORD(current_entry, MM_REGION, RegionListEntry); current_entry = current_entry->Flink; ExFreePool(current); - } + } - /* Actually free the memory area. */ - MmFreeMemoryArea(&Process->AddressSpace, - MemoryArea->BaseAddress, - 0, - MmFreeVirtualMemoryPage, - (PVOID)Process); + /* Actually free the memory area. */ + MmFreeMemoryArea(&Process->AddressSpace, + MemoryArea->BaseAddress, + 0, + MmFreeVirtualMemoryPage, + (PVOID)Process); } /* * @unimplemented */ -NTSTATUS STDCALL -NtFreeVirtualMemory(IN HANDLE ProcessHandle, - IN PVOID* PBaseAddress, - IN PULONG PRegionSize, - IN ULONG FreeType) +NTSTATUS STDCALL +NtFreeVirtualMemory(IN HANDLE ProcessHandle, + IN PVOID* PBaseAddress, + IN PULONG PRegionSize, + IN ULONG FreeType) /* * FUNCTION: Frees a range of virtual memory * ARGUMENTS: @@ -794,67 +794,67 @@ NtFreeVirtualMemory(IN HANDLE ProcessHandle, PMADDRESS_SPACE AddressSpace; PVOID BaseAddress; ULONG RegionSize; - + DPRINT("NtFreeVirtualMemory(ProcessHandle %x, *PBaseAddress %x, " - "*PRegionSize %x, FreeType %x)\n",ProcessHandle,*PBaseAddress, - *PRegionSize,FreeType); - + "*PRegionSize %x, FreeType %x)\n",ProcessHandle,*PBaseAddress, + *PRegionSize,FreeType); + BaseAddress = (PVOID)PAGE_ROUND_DOWN((*PBaseAddress)); RegionSize = PAGE_ROUND_UP((*PBaseAddress) + (*PRegionSize)) - - PAGE_ROUND_DOWN((*PBaseAddress)); - + PAGE_ROUND_DOWN((*PBaseAddress)); + Status = ObReferenceObjectByHandle(ProcessHandle, - PROCESS_VM_OPERATION, - PsProcessType, - UserMode, - (PVOID*)(&Process), - NULL); + PROCESS_VM_OPERATION, + PsProcessType, + UserMode, + (PVOID*)(&Process), + NULL); if (!NT_SUCCESS(Status)) - { - return(Status); - } - + { + return(Status); + } + AddressSpace = &Process->AddressSpace; - + MmLockAddressSpace(AddressSpace); MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, - BaseAddress); + BaseAddress); if (MemoryArea == NULL) - { - MmUnlockAddressSpace(AddressSpace); - ObDereferenceObject(Process); - return(STATUS_UNSUCCESSFUL); - } - + { + MmUnlockAddressSpace(AddressSpace); + ObDereferenceObject(Process); + return(STATUS_UNSUCCESSFUL); + } + switch (FreeType) - { + { case MEM_RELEASE: - /* We can only free a memory area in one step. */ - if (MemoryArea->BaseAddress != BaseAddress) - { - MmUnlockAddressSpace(AddressSpace); - ObDereferenceObject(Process); - return(STATUS_UNSUCCESSFUL); - } - MmFreeVirtualMemory(Process, MemoryArea); - MmUnlockAddressSpace(AddressSpace); - ObDereferenceObject(Process); - return(STATUS_SUCCESS); - + /* We can only free a memory area in one step. */ + if (MemoryArea->BaseAddress != BaseAddress) + { + MmUnlockAddressSpace(AddressSpace); + ObDereferenceObject(Process); + return(STATUS_UNSUCCESSFUL); + } + MmFreeVirtualMemory(Process, MemoryArea); + MmUnlockAddressSpace(AddressSpace); + ObDereferenceObject(Process); + return(STATUS_SUCCESS); + case MEM_DECOMMIT: - Status = - MmAlterRegion(AddressSpace, - MemoryArea->BaseAddress, - &MemoryArea->Data.VirtualMemoryData.RegionListHead, - BaseAddress, - RegionSize, - MEM_RESERVE, - PAGE_NOACCESS, - MmModifyAttributes); - MmUnlockAddressSpace(AddressSpace); - ObDereferenceObject(Process); - return(Status); - } + Status = + MmAlterRegion(AddressSpace, + MemoryArea->BaseAddress, + &MemoryArea->Data.VirtualMemoryData.RegionListHead, + BaseAddress, + RegionSize, + MEM_RESERVE, + PAGE_NOACCESS, + MmModifyAttributes); + MmUnlockAddressSpace(AddressSpace); + ObDereferenceObject(Process); + return(Status); + } MmUnlockAddressSpace(AddressSpace); ObDereferenceObject(Process); return(STATUS_NOT_IMPLEMENTED); @@ -862,49 +862,49 @@ NtFreeVirtualMemory(IN HANDLE ProcessHandle, NTSTATUS MmProtectAnonMem(PMADDRESS_SPACE AddressSpace, - PMEMORY_AREA MemoryArea, - PVOID BaseAddress, - ULONG Length, - ULONG Protect, - PULONG OldProtect) + PMEMORY_AREA MemoryArea, + PVOID BaseAddress, + ULONG Length, + ULONG Protect, + PULONG OldProtect) { - PMM_REGION Region; - NTSTATUS Status; + PMM_REGION Region; + NTSTATUS Status; - Region = MmFindRegion(MemoryArea->BaseAddress, - &MemoryArea->Data.VirtualMemoryData.RegionListHead, - BaseAddress, NULL); - *OldProtect = Region->Protect; - Status = MmAlterRegion(AddressSpace, MemoryArea->BaseAddress, - &MemoryArea->Data.VirtualMemoryData.RegionListHead, - BaseAddress, Length, Region->Type, Protect, - MmModifyAttributes); - return(Status); + Region = MmFindRegion(MemoryArea->BaseAddress, + &MemoryArea->Data.VirtualMemoryData.RegionListHead, + BaseAddress, NULL); + *OldProtect = Region->Protect; + Status = MmAlterRegion(AddressSpace, MemoryArea->BaseAddress, + &MemoryArea->Data.VirtualMemoryData.RegionListHead, + BaseAddress, Length, Region->Type, Protect, + MmModifyAttributes); + return(Status); } NTSTATUS STDCALL MmQueryAnonMem(PMEMORY_AREA MemoryArea, - PVOID Address, - PMEMORY_BASIC_INFORMATION Info, - PULONG ResultLength) + PVOID Address, + PMEMORY_BASIC_INFORMATION Info, + PULONG ResultLength) { - PMM_REGION Region; - PVOID RegionBase; + PMM_REGION Region; + PVOID RegionBase; - Info->BaseAddress = (PVOID)PAGE_ROUND_DOWN(Address); + Info->BaseAddress = (PVOID)PAGE_ROUND_DOWN(Address); - Region = MmFindRegion(MemoryArea->BaseAddress, - &MemoryArea->Data.VirtualMemoryData.RegionListHead, - Address, &RegionBase); - Info->AllocationBase = RegionBase; - Info->AllocationProtect = Region->Protect; /* FIXME */ - Info->RegionSize = (char*)RegionBase + Region->Length - (char*)Info->BaseAddress; - Info->State = Region->Type; - Info->Protect = Region->Protect; - Info->Type = MEM_PRIVATE; + Region = MmFindRegion(MemoryArea->BaseAddress, + &MemoryArea->Data.VirtualMemoryData.RegionListHead, + Address, &RegionBase); + Info->AllocationBase = RegionBase; + Info->AllocationProtect = Region->Protect; /* FIXME */ + Info->RegionSize = (char*)RegionBase + Region->Length - (char*)Info->BaseAddress; + Info->State = Region->Type; + Info->Protect = Region->Protect; + Info->Type = MEM_PRIVATE; - *ResultLength = sizeof(MEMORY_BASIC_INFORMATION); - return(STATUS_SUCCESS); + *ResultLength = sizeof(MEMORY_BASIC_INFORMATION); + return(STATUS_SUCCESS); } /* EOF */ diff --git a/reactos/ntoskrnl/mm/aspace.c b/reactos/ntoskrnl/mm/aspace.c index c2df1d76790..948cbddc076 100644 --- a/reactos/ntoskrnl/mm/aspace.c +++ b/reactos/ntoskrnl/mm/aspace.c @@ -1,4 +1,4 @@ -/* $Id: aspace.c,v 1.16 2004/03/04 00:07:01 navaraf Exp $ +/* $Id: aspace.c,v 1.17 2004/04/10 22:35:25 gdalsnes Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -26,30 +26,30 @@ STATIC MADDRESS_SPACE KernelAddressSpace; /* FUNCTIONS *****************************************************************/ -VOID +VOID MmLockAddressSpace(PMADDRESS_SPACE AddressSpace) { - /* - * Don't bother with locking if we are the first thread. - */ - if (KeGetCurrentThread() == NULL) - { + /* + * Don't bother with locking if we are the first thread. + */ + if (KeGetCurrentThread() == NULL) + { return; - } - ExAcquireFastMutex(&AddressSpace->Lock); + } + ExAcquireFastMutex(&AddressSpace->Lock); } -VOID +VOID MmUnlockAddressSpace(PMADDRESS_SPACE AddressSpace) { - /* - * Don't bother locking if we are the first thread. - */ - if (KeGetCurrentThread() == NULL) - { + /* + * Don't bother locking if we are the first thread. + */ + if (KeGetCurrentThread() == NULL) + { return; - } - ExReleaseFastMutex(&AddressSpace->Lock); + } + ExReleaseFastMutex(&AddressSpace->Lock); } VOID INIT_FUNCTION @@ -68,44 +68,44 @@ PMADDRESS_SPACE MmGetKernelAddressSpace(VOID) return(&KernelAddressSpace); } -NTSTATUS +NTSTATUS MmInitializeAddressSpace(PEPROCESS Process, - PMADDRESS_SPACE AddressSpace) + PMADDRESS_SPACE AddressSpace) { InitializeListHead(&AddressSpace->MAreaListHead); ExInitializeFastMutex(&AddressSpace->Lock); if (Process != NULL) - { - AddressSpace->LowestAddress = MM_LOWEST_USER_ADDRESS; - } + { + AddressSpace->LowestAddress = MM_LOWEST_USER_ADDRESS; + } else - { - AddressSpace->LowestAddress = KERNEL_BASE; - } + { + AddressSpace->LowestAddress = KERNEL_BASE; + } AddressSpace->Process = Process; if (Process != NULL) - { - AddressSpace->PageTableRefCountTable = - ExAllocatePoolWithTag(NonPagedPool, 768 * sizeof(USHORT), - TAG_PTRC); - RtlZeroMemory(AddressSpace->PageTableRefCountTable, 768 * sizeof(USHORT)); - AddressSpace->PageTableRefCountTableSize = 768; - } + { + AddressSpace->PageTableRefCountTable = + ExAllocatePoolWithTag(NonPagedPool, 768 * sizeof(USHORT), + TAG_PTRC); + RtlZeroMemory(AddressSpace->PageTableRefCountTable, 768 * sizeof(USHORT)); + AddressSpace->PageTableRefCountTableSize = 768; + } else - { - AddressSpace->PageTableRefCountTable = NULL; - AddressSpace->PageTableRefCountTableSize = 0; - } + { + AddressSpace->PageTableRefCountTable = NULL; + AddressSpace->PageTableRefCountTableSize = 0; + } return(STATUS_SUCCESS); } -NTSTATUS +NTSTATUS MmDestroyAddressSpace(PMADDRESS_SPACE AddressSpace) { - if (AddressSpace->PageTableRefCountTable != NULL) - { + if (AddressSpace->PageTableRefCountTable != NULL) + { ExFreePool(AddressSpace->PageTableRefCountTable); - } + } return(STATUS_SUCCESS); } diff --git a/reactos/ntoskrnl/mm/balance.c b/reactos/ntoskrnl/mm/balance.c index 75ee583e9fd..3ed4d1c49ba 100644 --- a/reactos/ntoskrnl/mm/balance.c +++ b/reactos/ntoskrnl/mm/balance.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: balance.c,v 1.26 2004/03/05 11:31:59 hbirr Exp $ +/* $Id: balance.c,v 1.27 2004/04/10 22:35:25 gdalsnes Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/mm/balance.c @@ -39,17 +39,19 @@ typedef struct _MM_MEMORY_CONSUMER { - ULONG PagesUsed; - ULONG PagesTarget; - NTSTATUS (*Trim)(ULONG Target, ULONG Priority, PULONG NrFreed); -} MM_MEMORY_CONSUMER, *PMM_MEMORY_CONSUMER; + ULONG PagesUsed; + ULONG PagesTarget; + NTSTATUS (*Trim)(ULONG Target, ULONG Priority, PULONG NrFreed); +} +MM_MEMORY_CONSUMER, *PMM_MEMORY_CONSUMER; typedef struct _MM_ALLOCATION_REQUEST { - PHYSICAL_ADDRESS Page; - LIST_ENTRY ListEntry; - KEVENT Event; -} MM_ALLOCATION_REQUEST, *PMM_ALLOCATION_REQUEST; + PHYSICAL_ADDRESS Page; + LIST_ENTRY ListEntry; + KEVENT Event; +} +MM_ALLOCATION_REQUEST, *PMM_ALLOCATION_REQUEST; /* GLOBALS ******************************************************************/ @@ -72,381 +74,397 @@ static LONG MiBalancerWork = 0; VOID MmPrintMemoryStatistic(VOID) { - DbgPrint("MC_CACHE %d, MC_USER %d, MC_PPOOL %d, MC_NPPOOL %d, MiNrAvailablePages %d\n", - MiMemoryConsumers[MC_CACHE].PagesUsed, MiMemoryConsumers[MC_USER].PagesUsed, - MiMemoryConsumers[MC_PPOOL].PagesUsed, MiMemoryConsumers[MC_NPPOOL].PagesUsed, - MiNrAvailablePages); + DbgPrint("MC_CACHE %d, MC_USER %d, MC_PPOOL %d, MC_NPPOOL %d, MiNrAvailablePages %d\n", + MiMemoryConsumers[MC_CACHE].PagesUsed, MiMemoryConsumers[MC_USER].PagesUsed, + MiMemoryConsumers[MC_PPOOL].PagesUsed, MiMemoryConsumers[MC_NPPOOL].PagesUsed, + MiNrAvailablePages); } VOID INIT_FUNCTION MmInitializeBalancer(ULONG NrAvailablePages, ULONG NrSystemPages) { - memset(MiMemoryConsumers, 0, sizeof(MiMemoryConsumers)); - InitializeListHead(&AllocationListHead); - KeInitializeSpinLock(&AllocationListLock); + memset(MiMemoryConsumers, 0, sizeof(MiMemoryConsumers)); + InitializeListHead(&AllocationListHead); + KeInitializeSpinLock(&AllocationListLock); - MiNrAvailablePages = MiNrTotalPages = NrAvailablePages; + MiNrAvailablePages = MiNrTotalPages = NrAvailablePages; - /* Set up targets. */ - MiMinimumAvailablePages = 64; - MiMemoryConsumers[MC_CACHE].PagesTarget = NrAvailablePages / 2; - MiMemoryConsumers[MC_USER].PagesTarget = - NrAvailablePages - MiMinimumAvailablePages; - MiMemoryConsumers[MC_PPOOL].PagesTarget = NrAvailablePages / 2; - MiMemoryConsumers[MC_NPPOOL].PagesTarget = 0xFFFFFFFF; - MiMemoryConsumers[MC_NPPOOL].PagesUsed = NrSystemPages; + /* Set up targets. */ + MiMinimumAvailablePages = 64; + MiMemoryConsumers[MC_CACHE].PagesTarget = NrAvailablePages / 2; + MiMemoryConsumers[MC_USER].PagesTarget = + NrAvailablePages - MiMinimumAvailablePages; + MiMemoryConsumers[MC_PPOOL].PagesTarget = NrAvailablePages / 2; + MiMemoryConsumers[MC_NPPOOL].PagesTarget = 0xFFFFFFFF; + MiMemoryConsumers[MC_NPPOOL].PagesUsed = NrSystemPages; } VOID INIT_FUNCTION -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; } NTSTATUS MmReleasePageMemoryConsumer(ULONG Consumer, PHYSICAL_ADDRESS Page) { - PMM_ALLOCATION_REQUEST Request; - PLIST_ENTRY Entry; - KIRQL oldIrql; - ULONG OldAvailable; + PMM_ALLOCATION_REQUEST Request; + PLIST_ENTRY Entry; + KIRQL oldIrql; + ULONG OldAvailable; #if defined(__GNUC__) - if (Page.QuadPart == 0LL) + + if (Page.QuadPart == 0LL) #else - if (Page.QuadPart == 0) + + if (Page.QuadPart == 0) #endif - { + + { DPRINT1("Tried to release page zero.\n"); KEBUGCHECK(0); - } + } - KeAcquireSpinLock(&AllocationListLock, &oldIrql); - if (MmGetReferenceCountPage(Page) == 1) - { + KeAcquireSpinLock(&AllocationListLock, &oldIrql); + if (MmGetReferenceCountPage(Page) == 1) + { InterlockedDecrement((LONG *)&MiMemoryConsumers[Consumer].PagesUsed); OldAvailable = InterlockedIncrement((LONG *)&MiNrAvailablePages); if (IsListEmpty(&AllocationListHead) || OldAvailable + 1 < MiMinimumAvailablePages) - { - KeReleaseSpinLock(&AllocationListLock, oldIrql); - MmDereferencePage(Page); - } + { + KeReleaseSpinLock(&AllocationListLock, oldIrql); + MmDereferencePage(Page); + } else - { - Entry = RemoveHeadList(&AllocationListHead); - Request = CONTAINING_RECORD(Entry, MM_ALLOCATION_REQUEST, ListEntry); - KeReleaseSpinLock(&AllocationListLock, oldIrql); - Request->Page = Page; - KeSetEvent(&Request->Event, IO_NO_INCREMENT, FALSE); - } - } - else - { + { + Entry = RemoveHeadList(&AllocationListHead); + Request = CONTAINING_RECORD(Entry, MM_ALLOCATION_REQUEST, ListEntry); + KeReleaseSpinLock(&AllocationListLock, oldIrql); + Request->Page = Page; + KeSetEvent(&Request->Event, IO_NO_INCREMENT, FALSE); + } + } + else + { KeReleaseSpinLock(&AllocationListLock, oldIrql); MmDereferencePage(Page); - } + } - return(STATUS_SUCCESS); + return(STATUS_SUCCESS); } VOID MiTrimMemoryConsumer(ULONG Consumer) { - LONG Target; - ULONG NrFreedPages; + LONG Target; + ULONG NrFreedPages; - Target = MiMemoryConsumers[Consumer].PagesUsed - - MiMemoryConsumers[Consumer].PagesTarget; - if (Target < 1) - { + Target = MiMemoryConsumers[Consumer].PagesUsed - + MiMemoryConsumers[Consumer].PagesTarget; + if (Target < 1) + { Target = 1; - } + } - if (MiMemoryConsumers[Consumer].Trim != NULL) - { + if (MiMemoryConsumers[Consumer].Trim != NULL) + { MiMemoryConsumers[Consumer].Trim(Target, 0, &NrFreedPages); - } + } } VOID MmRebalanceMemoryConsumers(VOID) { - LONG Target; - ULONG i; - ULONG NrFreedPages; - NTSTATUS Status; + LONG Target; + ULONG i; + ULONG NrFreedPages; + NTSTATUS Status; - Target = (MiMinimumAvailablePages - MiNrAvailablePages) + MiPagesRequired; - Target = max(Target, (LONG) MiMinimumPagesPerRun); + Target = (MiMinimumAvailablePages - MiNrAvailablePages) + MiPagesRequired; + Target = max(Target, (LONG) MiMinimumPagesPerRun); - for (i = 0; i < MC_MAXIMUM && Target > 0; i++) - { + for (i = 0; i < MC_MAXIMUM && Target > 0; i++) + { if (MiMemoryConsumers[i].Trim != NULL) - { - Status = MiMemoryConsumers[i].Trim(Target, 0, &NrFreedPages); - if (!NT_SUCCESS(Status)) - { - KEBUGCHECK(0); - } - Target = Target - NrFreedPages; - } - } + { + Status = MiMemoryConsumers[i].Trim(Target, 0, &NrFreedPages); + if (!NT_SUCCESS(Status)) + { + KEBUGCHECK(0); + } + Target = Target - NrFreedPages; + } + } } static BOOLEAN MiIsBalancerThread(VOID) { - return MiBalancerThreadHandle != NULL && - PsGetCurrentThread() == MiBalancerThreadId.UniqueThread; + return MiBalancerThreadHandle != NULL && + PsGetCurrentThread() == MiBalancerThreadId.UniqueThread; } NTSTATUS -MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, - PHYSICAL_ADDRESS* AllocatedPage) +MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, + PHYSICAL_ADDRESS* AllocatedPage) { - ULONG OldUsed; - ULONG OldAvailable; - PHYSICAL_ADDRESS Page; - KIRQL oldIrql; - - /* - * Make sure we don't exceed our individual target. - */ - OldUsed = InterlockedIncrement((LONG *)&MiMemoryConsumers[Consumer].PagesUsed); - if (OldUsed >= (MiMemoryConsumers[Consumer].PagesTarget - 1) && - !MiIsBalancerThread()) - { - if (!CanWait) - { - InterlockedDecrement((LONG *)&MiMemoryConsumers[Consumer].PagesUsed); - return(STATUS_NO_MEMORY); - } - MiTrimMemoryConsumer(Consumer); - } + ULONG OldUsed; + ULONG OldAvailable; + PHYSICAL_ADDRESS Page; + KIRQL oldIrql; - OldAvailable = InterlockedDecrement((LONG *)&MiNrAvailablePages); - /* - * Allocate always memory for the non paged pool and for the pager thread. - */ - if (Consumer == MC_NPPOOL || MiIsBalancerThread()) - { + /* + * Make sure we don't exceed our individual target. + */ + OldUsed = InterlockedIncrement((LONG *)&MiMemoryConsumers[Consumer].PagesUsed); + if (OldUsed >= (MiMemoryConsumers[Consumer].PagesTarget - 1) && + !MiIsBalancerThread()) + { + if (!CanWait) + { + InterlockedDecrement((LONG *)&MiMemoryConsumers[Consumer].PagesUsed); + return(STATUS_NO_MEMORY); + } + MiTrimMemoryConsumer(Consumer); + } + + OldAvailable = InterlockedDecrement((LONG *)&MiNrAvailablePages); + /* + * Allocate always memory for the non paged pool and for the pager thread. + */ + if (Consumer == MC_NPPOOL || MiIsBalancerThread()) + { Page = MmAllocPage(Consumer, 0); #if defined(__GNUC__) + if (Page.QuadPart == 0LL) #else + if (Page.QuadPart == 0) #endif - { - KEBUGCHECK(0); - } + + { + KEBUGCHECK(0); + } *AllocatedPage = Page; if (OldAvailable < MiMinimumAvailablePages && - MiBalancerThreadHandle != NULL) - { - KeSetEvent(&MiBalancerEvent, IO_NO_INCREMENT, FALSE); - } + MiBalancerThreadHandle != NULL) + { + KeSetEvent(&MiBalancerEvent, IO_NO_INCREMENT, FALSE); + } return(STATUS_SUCCESS); - } + } - /* - * Make sure we don't exceed global targets. - */ - if (OldAvailable < MiMinimumAvailablePages) - { + /* + * Make sure we don't exceed global targets. + */ + if (OldAvailable < MiMinimumAvailablePages) + { MM_ALLOCATION_REQUEST Request; if (!CanWait) - { - InterlockedIncrement((LONG *)&MiNrAvailablePages); - InterlockedDecrement((LONG *)&MiMemoryConsumers[Consumer].PagesUsed); - return(STATUS_NO_MEMORY); - } + { + InterlockedIncrement((LONG *)&MiNrAvailablePages); + InterlockedDecrement((LONG *)&MiMemoryConsumers[Consumer].PagesUsed); + return(STATUS_NO_MEMORY); + } /* Insert an allocation request. */ #if defined(__GNUC__) Request.Page.QuadPart = 0LL; #else + Request.Page.QuadPart = 0; #endif + KeInitializeEvent(&Request.Event, NotificationEvent, FALSE); InterlockedIncrement((LONG *)&MiPagesRequired); - KeAcquireSpinLock(&AllocationListLock, &oldIrql); + KeAcquireSpinLock(&AllocationListLock, &oldIrql); if (MiBalancerThreadHandle != NULL) - { - KeSetEvent(&MiBalancerEvent, IO_NO_INCREMENT, FALSE); - } + { + KeSetEvent(&MiBalancerEvent, IO_NO_INCREMENT, FALSE); + } InsertTailList(&AllocationListHead, &Request.ListEntry); KeReleaseSpinLock(&AllocationListLock, oldIrql); KeWaitForSingleObject(&Request.Event, - 0, - KernelMode, - FALSE, - NULL); - + 0, + KernelMode, + FALSE, + NULL); + Page = Request.Page; #if defined(__GNUC__) + if (Page.QuadPart == 0LL) #else + if (Page.QuadPart == 0) #endif - { - KEBUGCHECK(0); - } + + { + KEBUGCHECK(0); + } MmTransferOwnershipPage(Page, Consumer); *AllocatedPage = Page; InterlockedDecrement((LONG *)&MiPagesRequired); return(STATUS_SUCCESS); - } - - /* - * Actually allocate the page. - */ - Page = MmAllocPage(Consumer, 0); -#if defined(__GNUC__) - if (Page.QuadPart == 0LL) -#else - if (Page.QuadPart == 0) -#endif - { - KEBUGCHECK(0); - } - *AllocatedPage = Page; + } - return(STATUS_SUCCESS); + /* + * Actually allocate the page. + */ + Page = MmAllocPage(Consumer, 0); +#if defined(__GNUC__) + + if (Page.QuadPart == 0LL) +#else + + if (Page.QuadPart == 0) +#endif + + { + KEBUGCHECK(0); + } + *AllocatedPage = Page; + + return(STATUS_SUCCESS); } VOID STDCALL MiBalancerThread(PVOID Unused) { - PVOID WaitObjects[2]; - NTSTATUS Status; - ULONG i; - ULONG NrFreedPages; - ULONG NrPagesUsed; - ULONG Target; - BOOLEAN ShouldRun; + PVOID WaitObjects[2]; + NTSTATUS Status; + ULONG i; + ULONG NrFreedPages; + ULONG NrPagesUsed; + ULONG Target; + BOOLEAN ShouldRun; - WaitObjects[0] = &MiBalancerEvent; - WaitObjects[1] = &MiBalancerTimer; + WaitObjects[0] = &MiBalancerEvent; + WaitObjects[1] = &MiBalancerTimer; - while (1) - { + while (1) + { Status = KeWaitForMultipleObjects(2, - WaitObjects, - WaitAny, - Executive, - KernelMode, - FALSE, - NULL, - NULL); + WaitObjects, + WaitAny, + Executive, + KernelMode, + FALSE, + NULL, + NULL); if (Status == STATUS_SUCCESS) - { - /* MiBalancerEvent */ - CHECKPOINT; - while (MiNrAvailablePages < MiMinimumAvailablePages + 5) - { - for (i = 0; i < MC_MAXIMUM; i++) - { - if (MiMemoryConsumers[i].Trim != NULL) - { - NrFreedPages = 0; - Status = MiMemoryConsumers[i].Trim(MiMinimumPagesPerRun, 0, &NrFreedPages); - if (!NT_SUCCESS(Status)) - { - KEBUGCHECK(0); - } - } - } - } - InterlockedExchange(&MiBalancerWork, 0); - CHECKPOINT; - } + { + /* MiBalancerEvent */ + CHECKPOINT; + while (MiNrAvailablePages < MiMinimumAvailablePages + 5) + { + for (i = 0; i < MC_MAXIMUM; i++) + { + if (MiMemoryConsumers[i].Trim != NULL) + { + NrFreedPages = 0; + Status = MiMemoryConsumers[i].Trim(MiMinimumPagesPerRun, 0, &NrFreedPages); + if (!NT_SUCCESS(Status)) + { + KEBUGCHECK(0); + } + } + } + } + InterlockedExchange(&MiBalancerWork, 0); + CHECKPOINT; + } else if (Status == STATUS_SUCCESS + 1) - { - /* MiBalancerTimer */ - ShouldRun = MiNrAvailablePages < MiMinimumAvailablePages + 5 ? TRUE : FALSE; - for (i = 0; i < MC_MAXIMUM; i++) - { - if (MiMemoryConsumers[i].Trim != NULL) - { - NrPagesUsed = MiMemoryConsumers[i].PagesUsed; - if (NrPagesUsed > MiMemoryConsumers[i].PagesTarget || ShouldRun) - { - if (NrPagesUsed > MiMemoryConsumers[i].PagesTarget) - { - Target = max (NrPagesUsed - MiMemoryConsumers[i].PagesTarget, - MiMinimumPagesPerRun); - } - else - { - Target = MiMinimumPagesPerRun; - } - NrFreedPages = 0; - Status = MiMemoryConsumers[i].Trim(Target, 0, &NrFreedPages); - if (!NT_SUCCESS(Status)) - { - KEBUGCHECK(0); - } - } - } - } - } + { + /* MiBalancerTimer */ + ShouldRun = MiNrAvailablePages < MiMinimumAvailablePages + 5 ? TRUE : FALSE; + for (i = 0; i < MC_MAXIMUM; i++) + { + if (MiMemoryConsumers[i].Trim != NULL) + { + NrPagesUsed = MiMemoryConsumers[i].PagesUsed; + if (NrPagesUsed > MiMemoryConsumers[i].PagesTarget || ShouldRun) + { + if (NrPagesUsed > MiMemoryConsumers[i].PagesTarget) + { + Target = max (NrPagesUsed - MiMemoryConsumers[i].PagesTarget, + MiMinimumPagesPerRun); + } + else + { + Target = MiMinimumPagesPerRun; + } + NrFreedPages = 0; + Status = MiMemoryConsumers[i].Trim(Target, 0, &NrFreedPages); + if (!NT_SUCCESS(Status)) + { + KEBUGCHECK(0); + } + } + } + } + } else - { - DPRINT1("KeWaitForMultipleObjects failt, status = %x\n", Status); - KEBUGCHECK(0); - } - } + { + DPRINT1("KeWaitForMultipleObjects failt, status = %x\n", Status); + KEBUGCHECK(0); + } + } } VOID INIT_FUNCTION 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 - CHECKPOINT; + CHECKPOINT; - 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, - (PKSTART_ROUTINE) MiBalancerThread, - NULL); - if (!NT_SUCCESS(Status)) - { + Status = PsCreateSystemThread(&MiBalancerThreadHandle, + THREAD_ALL_ACCESS, + NULL, + NULL, + &MiBalancerThreadId, + (PKSTART_ROUTINE) MiBalancerThread, + NULL); + if (!NT_SUCCESS(Status)) + { KEBUGCHECK(0); - } - - 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/cont.c b/reactos/ntoskrnl/mm/cont.c index 03493ce7de3..7f316100fc7 100644 --- a/reactos/ntoskrnl/mm/cont.c +++ b/reactos/ntoskrnl/mm/cont.c @@ -1,4 +1,4 @@ -/* $Id: cont.c,v 1.30 2003/12/31 05:33:03 jfilby Exp $ +/* $Id: cont.c,v 1.31 2004/04/10 22:35:25 gdalsnes Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -20,24 +20,24 @@ /* FUNCTIONS *****************************************************************/ VOID STATIC -MmFreeContinuousPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, - PHYSICAL_ADDRESS PhysAddr, SWAPENTRY SwapEntry, - BOOLEAN Dirty) +MmFreeContinuousPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, + PHYSICAL_ADDRESS PhysAddr, SWAPENTRY SwapEntry, + BOOLEAN Dirty) { - assert(SwapEntry == 0); - if (PhysAddr.QuadPart != 0) - { + assert(SwapEntry == 0); + if (PhysAddr.QuadPart != 0) + { MmReleasePageMemoryConsumer(MC_NPPOOL, PhysAddr); - } + } } PVOID STDCALL MmAllocateContiguousAlignedMemory(IN ULONG NumberOfBytes, - IN PHYSICAL_ADDRESS LowestAcceptableAddress OPTIONAL, - IN PHYSICAL_ADDRESS HighestAcceptableAddress, - IN PHYSICAL_ADDRESS BoundaryAddressMultiple OPTIONAL, - IN MEMORY_CACHING_TYPE CacheType OPTIONAL, - IN ULONG Alignment) + IN PHYSICAL_ADDRESS LowestAcceptableAddress OPTIONAL, + IN PHYSICAL_ADDRESS HighestAcceptableAddress, + IN PHYSICAL_ADDRESS BoundaryAddressMultiple OPTIONAL, + IN MEMORY_CACHING_TYPE CacheType OPTIONAL, + IN ULONG Alignment) { PMEMORY_AREA MArea; NTSTATUS Status; @@ -45,7 +45,7 @@ MmAllocateContiguousAlignedMemory(IN ULONG NumberOfBytes, PHYSICAL_ADDRESS PBase; ULONG Attributes; ULONG i; - + Attributes = PAGE_EXECUTE_READWRITE | PAGE_SYSTEM; if (CacheType == MmNonCached || CacheType == MmWriteCombined) { @@ -55,227 +55,231 @@ MmAllocateContiguousAlignedMemory(IN ULONG NumberOfBytes, { Attributes |= PAGE_WRITECOMBINE; } - + MmLockAddressSpace(MmGetKernelAddressSpace()); Status = MmCreateMemoryArea(NULL, - MmGetKernelAddressSpace(), - MEMORY_AREA_CONTINUOUS_MEMORY, - &BaseAddress, - NumberOfBytes, - 0, - &MArea, - FALSE, - FALSE, - BoundaryAddressMultiple); + MmGetKernelAddressSpace(), + MEMORY_AREA_CONTINUOUS_MEMORY, + &BaseAddress, + NumberOfBytes, + 0, + &MArea, + FALSE, + FALSE, + BoundaryAddressMultiple); MmUnlockAddressSpace(MmGetKernelAddressSpace()); if (!NT_SUCCESS(Status)) - { - return(NULL); - } + { + return(NULL); + } DPRINT( "Base = %x\n", BaseAddress ); PBase = MmGetContinuousPages(NumberOfBytes, - LowestAcceptableAddress, - HighestAcceptableAddress, - Alignment); + LowestAcceptableAddress, + HighestAcceptableAddress, + Alignment); #if defined(__GNUC__) + if (PBase.QuadPart == 0LL) #else + if (PBase.QuadPart == 0) #endif - { - MmLockAddressSpace(MmGetKernelAddressSpace()); - MmFreeMemoryArea(MmGetKernelAddressSpace(), - BaseAddress, - 0, - NULL, - NULL); - MmUnlockAddressSpace(MmGetKernelAddressSpace()); - return(NULL); - } + + { + MmLockAddressSpace(MmGetKernelAddressSpace()); + MmFreeMemoryArea(MmGetKernelAddressSpace(), + BaseAddress, + 0, + NULL, + NULL); + MmUnlockAddressSpace(MmGetKernelAddressSpace()); + return(NULL); + } for (i = 0; i < (PAGE_ROUND_UP(NumberOfBytes) / 4096); i++) - { + { #if !defined(__GNUC__) - LARGE_INTEGER dummyJunkNeeded; - dummyJunkNeeded.QuadPart = PBase.QuadPart + (i * 4096); + LARGE_INTEGER dummyJunkNeeded; + dummyJunkNeeded.QuadPart = PBase.QuadPart + (i * 4096); #endif - MmCreateVirtualMapping(NULL, - (char*)BaseAddress + (i * 4096), - Attributes, + + MmCreateVirtualMapping(NULL, + (char*)BaseAddress + (i * 4096), + Attributes, #if defined(__GNUC__) - (LARGE_INTEGER)(PBase.QuadPart + (i * 4096)), + (LARGE_INTEGER)(PBase.QuadPart + (i * 4096)), #else - dummyJunkNeeded, + dummyJunkNeeded, #endif - TRUE); - } + TRUE); + } return(BaseAddress); } /********************************************************************** - * NAME EXPORTED - * MmAllocateContiguousMemory@12 + * NAME EXPORTED + * MmAllocateContiguousMemory@12 * * DESCRIPTION - * Allocates a range of physically contiguous cache aligned - * memory from the non-paged pool. - * + * Allocates a range of physically contiguous cache aligned + * memory from the non-paged pool. + * * ARGUMENTS - * NumberOfBytes - * Size of the memory block to allocate; - * - * HighestAcceptableAddress - * Highest address valid for the caller. - * + * NumberOfBytes + * Size of the memory block to allocate; + * + * HighestAcceptableAddress + * Highest address valid for the caller. + * * RETURN VALUE - * The virtual address of the memory block on success; - * NULL on error. + * The virtual address of the memory block on success; + * NULL on error. * * NOTE - * Description taken from include/ddk/mmfuncs.h. - * Code taken from ntoskrnl/mm/special.c. + * Description taken from include/ddk/mmfuncs.h. + * Code taken from ntoskrnl/mm/special.c. * * REVISIONS * * @implemented */ -PVOID STDCALL +PVOID STDCALL MmAllocateContiguousMemory (IN ULONG NumberOfBytes, - IN PHYSICAL_ADDRESS HighestAcceptableAddress) + IN PHYSICAL_ADDRESS HighestAcceptableAddress) { - PHYSICAL_ADDRESS LowestAcceptableAddress; - PHYSICAL_ADDRESS BoundaryAddressMultiple; - - LowestAcceptableAddress.QuadPart = 0; - BoundaryAddressMultiple.QuadPart = 0; - - return(MmAllocateContiguousAlignedMemory(NumberOfBytes, - LowestAcceptableAddress, - HighestAcceptableAddress, - BoundaryAddressMultiple, - MmCached, - PAGE_SIZE)); + PHYSICAL_ADDRESS LowestAcceptableAddress; + PHYSICAL_ADDRESS BoundaryAddressMultiple; + + LowestAcceptableAddress.QuadPart = 0; + BoundaryAddressMultiple.QuadPart = 0; + + return(MmAllocateContiguousAlignedMemory(NumberOfBytes, + LowestAcceptableAddress, + HighestAcceptableAddress, + BoundaryAddressMultiple, + MmCached, + PAGE_SIZE)); } /********************************************************************** - * NAME EXPORTED - * MmFreeContiguousMemory@4 + * NAME EXPORTED + * MmFreeContiguousMemory@4 * * DESCRIPTION - * Releases a range of physically contiguous memory allocated - * with MmAllocateContiguousMemory. - * + * Releases a range of physically contiguous memory allocated + * with MmAllocateContiguousMemory. + * * ARGUMENTS - * BaseAddress - * Virtual address of the memory to be freed. + * BaseAddress + * Virtual address of the memory to be freed. * * RETURN VALUE - * None. + * None. * * NOTE - * Description taken from include/ddk/mmfuncs.h. - * Code taken from ntoskrnl/mm/special.c. + * Description taken from include/ddk/mmfuncs.h. + * Code taken from ntoskrnl/mm/special.c. * * REVISIONS * * @implemented */ -VOID STDCALL +VOID STDCALL MmFreeContiguousMemory(IN PVOID BaseAddress) { MmLockAddressSpace(MmGetKernelAddressSpace()); MmFreeMemoryArea(MmGetKernelAddressSpace(), - BaseAddress, - 0, - MmFreeContinuousPage, - NULL); + BaseAddress, + 0, + MmFreeContinuousPage, + NULL); MmUnlockAddressSpace(MmGetKernelAddressSpace()); } /********************************************************************** - * NAME EXPORTED - * MmAllocateContiguousMemorySpecifyCache@32 + * NAME EXPORTED + * MmAllocateContiguousMemorySpecifyCache@32 * * DESCRIPTION - * Allocates a range of physically contiguous memory - * with a cache parameter. - * + * Allocates a range of physically contiguous memory + * with a cache parameter. + * * ARGUMENTS - * NumberOfBytes - * Size of the memory block to allocate; - * - * LowestAcceptableAddress - * Lowest address valid for the caller. - * - * HighestAcceptableAddress - * Highest address valid for the caller. - * - * BoundaryAddressMultiple - * Address multiple not to be crossed by allocated buffer (optional). - * - * CacheType - * Type of caching to use. - * + * NumberOfBytes + * Size of the memory block to allocate; + * + * LowestAcceptableAddress + * Lowest address valid for the caller. + * + * HighestAcceptableAddress + * Highest address valid for the caller. + * + * BoundaryAddressMultiple + * Address multiple not to be crossed by allocated buffer (optional). + * + * CacheType + * Type of caching to use. + * * RETURN VALUE - * The virtual address of the memory block on success; - * NULL on error. + * The virtual address of the memory block on success; + * NULL on error. * * REVISIONS * * @implemented */ -PVOID STDCALL +PVOID STDCALL MmAllocateContiguousMemorySpecifyCache (IN ULONG NumberOfBytes, - IN PHYSICAL_ADDRESS LowestAcceptableAddress, - IN PHYSICAL_ADDRESS HighestAcceptableAddress, - IN PHYSICAL_ADDRESS BoundaryAddressMultiple OPTIONAL, - IN MEMORY_CACHING_TYPE CacheType) + IN PHYSICAL_ADDRESS LowestAcceptableAddress, + IN PHYSICAL_ADDRESS HighestAcceptableAddress, + IN PHYSICAL_ADDRESS BoundaryAddressMultiple OPTIONAL, + IN MEMORY_CACHING_TYPE CacheType) { - return(MmAllocateContiguousAlignedMemory(NumberOfBytes, - LowestAcceptableAddress, - HighestAcceptableAddress, - BoundaryAddressMultiple, - CacheType, - PAGE_SIZE)); + return(MmAllocateContiguousAlignedMemory(NumberOfBytes, + LowestAcceptableAddress, + HighestAcceptableAddress, + BoundaryAddressMultiple, + CacheType, + PAGE_SIZE)); } /********************************************************************** - * NAME EXPORTED - * MmFreeContiguousMemorySpecifyCache@12 + * NAME EXPORTED + * MmFreeContiguousMemorySpecifyCache@12 * * DESCRIPTION - * Releases a range of physically contiguous memory allocated - * with MmAllocateContiguousMemorySpecifyCache. - * + * Releases a range of physically contiguous memory allocated + * with MmAllocateContiguousMemorySpecifyCache. + * * ARGUMENTS - * BaseAddress - * Virtual address of the memory to be freed. + * BaseAddress + * Virtual address of the memory to be freed. * - * NumberOfBytes - * Size of the memory block to free. - * - * CacheType - * Type of caching used. - * + * NumberOfBytes + * Size of the memory block to free. + * + * CacheType + * Type of caching used. + * * RETURN VALUE - * None. + * None. * * REVISIONS * * @implemented */ -VOID STDCALL +VOID STDCALL MmFreeContiguousMemorySpecifyCache(IN PVOID BaseAddress, - IN ULONG NumberOfBytes, - IN MEMORY_CACHING_TYPE CacheType) + IN ULONG NumberOfBytes, + IN MEMORY_CACHING_TYPE CacheType) { MmLockAddressSpace(MmGetKernelAddressSpace()); MmFreeMemoryArea(MmGetKernelAddressSpace(), - BaseAddress, - NumberOfBytes, - MmFreeContinuousPage, - NULL); + BaseAddress, + NumberOfBytes, + MmFreeContinuousPage, + NULL); MmUnlockAddressSpace(MmGetKernelAddressSpace()); } diff --git a/reactos/ntoskrnl/mm/drvlck.c b/reactos/ntoskrnl/mm/drvlck.c index c9e7367d0a9..27ab0dd75c2 100644 --- a/reactos/ntoskrnl/mm/drvlck.c +++ b/reactos/ntoskrnl/mm/drvlck.c @@ -1,4 +1,4 @@ -/* $Id: drvlck.c,v 1.4 2003/07/10 21:05:03 royce Exp $ +/* $Id: drvlck.c,v 1.5 2004/04/10 22:35:25 gdalsnes Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -30,8 +30,8 @@ MmUnlockPagableImageSection(IN PVOID ImageSectionHandle) * MmLockPagableDataSection */ { -// MmUnlockMemoryArea((MEMORY_AREA *)ImageSectionHandle); - UNIMPLEMENTED; + // MmUnlockMemoryArea((MEMORY_AREA *)ImageSectionHandle); + UNIMPLEMENTED; } #endif @@ -42,8 +42,8 @@ MmUnlockPagableImageSection(IN PVOID ImageSectionHandle) VOID STDCALL MmLockPagableSectionByHandle(IN PVOID ImageSectionHandle) { -// MmLockMemoryArea((MEMORY_AREA *)ImageSectionHandle); - UNIMPLEMENTED; + // MmLockMemoryArea((MEMORY_AREA *)ImageSectionHandle); + UNIMPLEMENTED; } @@ -51,10 +51,10 @@ MmLockPagableSectionByHandle(IN PVOID ImageSectionHandle) PVOID MmLockPagableCodeSection(IN PVOID AddressWithinSection) { - PVOID Handle; - Handle = MmOpenMemoryAreaByAddress(NULL,AddressWithinSection); - MmLockPagableSectionByHandle(Handle); - return(Handle); + PVOID Handle; + Handle = MmOpenMemoryAreaByAddress(NULL,AddressWithinSection); + MmLockPagableSectionByHandle(Handle); + return(Handle); } #endif @@ -65,10 +65,10 @@ MmLockPagableCodeSection(IN PVOID AddressWithinSection) PVOID STDCALL MmLockPagableDataSection(IN PVOID AddressWithinSection) { - PVOID Handle; - Handle = MmOpenMemoryAreaByAddress(NULL,AddressWithinSection); - MmLockPagableSectionByHandle(Handle); - return(Handle); + PVOID Handle; + Handle = MmOpenMemoryAreaByAddress(NULL,AddressWithinSection); + MmLockPagableSectionByHandle(Handle); + return(Handle); } @@ -77,8 +77,7 @@ MmLockPagableDataSection(IN PVOID AddressWithinSection) */ VOID STDCALL MmUnlockPagableImageSection(IN PVOID ImageSectionHandle) -{ -} +{} /* @@ -86,8 +85,7 @@ MmUnlockPagableImageSection(IN PVOID ImageSectionHandle) */ VOID STDCALL MmPageEntireDriver(IN PVOID AddressWithinSection) -{ -} +{} /* @@ -95,7 +93,6 @@ MmPageEntireDriver(IN PVOID AddressWithinSection) */ VOID STDCALL MmResetDriverPaging(IN PVOID AddressWithinSection) -{ -} +{} /* EOF */ diff --git a/reactos/ntoskrnl/mm/freelist.c b/reactos/ntoskrnl/mm/freelist.c index c764a574647..f6987b9cbe2 100644 --- a/reactos/ntoskrnl/mm/freelist.c +++ b/reactos/ntoskrnl/mm/freelist.c @@ -26,23 +26,27 @@ typedef struct _PHYSICAL_PAGE { - union - { - struct - { - ULONG Type:2; - ULONG Consumer:3; - }Flags; - ULONG AllFlags; - }; + union + { + struct + { +ULONG Type: + 2; +ULONG Consumer: + 3; + } + Flags; + ULONG AllFlags; + }; - LIST_ENTRY ListEntry; - ULONG ReferenceCount; - SWAPENTRY SavedSwapEntry; - ULONG LockCount; - ULONG MapCount; - struct _MM_RMAP_ENTRY* RmapListHead; -} PHYSICAL_PAGE, *PPHYSICAL_PAGE; + LIST_ENTRY ListEntry; + ULONG ReferenceCount; + SWAPENTRY SavedSwapEntry; + ULONG LockCount; + ULONG MapCount; + struct _MM_RMAP_ENTRY* RmapListHead; +} +PHYSICAL_PAGE, *PPHYSICAL_PAGE; /* GLOBALS ****************************************************************/ @@ -67,112 +71,124 @@ static ULONG UnzeroedPageCount = 0; VOID MmTransferOwnershipPage(PHYSICAL_ADDRESS PhysicalAddress, ULONG NewConsumer) { - ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE; - KIRQL oldIrql; + ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE; + KIRQL oldIrql; - KeAcquireSpinLock(&PageListLock, &oldIrql); - if (MmPageArray[Start].MapCount != 0) - { + KeAcquireSpinLock(&PageListLock, &oldIrql); + if (MmPageArray[Start].MapCount != 0) + { DbgPrint("Transfering mapped page.\n"); KEBUGCHECK(0); - } - RemoveEntryList(&MmPageArray[Start].ListEntry); - InsertTailList(&UsedPageListHeads[NewConsumer], - &MmPageArray[Start].ListEntry); - MmPageArray[Start].Flags.Consumer = NewConsumer; - KeReleaseSpinLock(&PageListLock, oldIrql); - MiZeroPage(PhysicalAddress); + } + RemoveEntryList(&MmPageArray[Start].ListEntry); + InsertTailList(&UsedPageListHeads[NewConsumer], + &MmPageArray[Start].ListEntry); + MmPageArray[Start].Flags.Consumer = NewConsumer; + KeReleaseSpinLock(&PageListLock, oldIrql); + MiZeroPage(PhysicalAddress); } PHYSICAL_ADDRESS MmGetLRUFirstUserPage(VOID) { - PLIST_ENTRY NextListEntry; - PHYSICAL_ADDRESS Next; - PHYSICAL_PAGE* PageDescriptor; - KIRQL oldIrql; + PLIST_ENTRY NextListEntry; + PHYSICAL_ADDRESS Next; + PHYSICAL_PAGE* PageDescriptor; + KIRQL oldIrql; - KeAcquireSpinLock(&PageListLock, &oldIrql); - NextListEntry = UsedPageListHeads[MC_USER].Flink; - if (NextListEntry == &UsedPageListHeads[MC_USER]) - { + KeAcquireSpinLock(&PageListLock, &oldIrql); + NextListEntry = UsedPageListHeads[MC_USER].Flink; + if (NextListEntry == &UsedPageListHeads[MC_USER]) + { KeReleaseSpinLock(&PageListLock, oldIrql); #if defined(__GNUC__) + return((PHYSICAL_ADDRESS)0LL); #else + { - const PHYSICAL_ADDRESS dummyJunkNeeded = { 0 }; - return dummyJunkNeeded; + const PHYSICAL_ADDRESS dummyJunkNeeded = + { + 0 + }; + return dummyJunkNeeded; } #endif - } - PageDescriptor = CONTAINING_RECORD(NextListEntry, PHYSICAL_PAGE, ListEntry); - Next.QuadPart = (ULONG)((ULONG)PageDescriptor - (ULONG)MmPageArray); - Next.QuadPart = (Next.QuadPart / sizeof(PHYSICAL_PAGE)) * PAGE_SIZE; - KeReleaseSpinLock(&PageListLock, oldIrql); - return(Next); + + } + PageDescriptor = CONTAINING_RECORD(NextListEntry, PHYSICAL_PAGE, ListEntry); + Next.QuadPart = (ULONG)((ULONG)PageDescriptor - (ULONG)MmPageArray); + Next.QuadPart = (Next.QuadPart / sizeof(PHYSICAL_PAGE)) * PAGE_SIZE; + KeReleaseSpinLock(&PageListLock, oldIrql); + return(Next); } VOID MmSetLRULastPage(PHYSICAL_ADDRESS PhysicalAddress) { - ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE; - KIRQL oldIrql; + ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE; + KIRQL oldIrql; - KeAcquireSpinLock(&PageListLock, &oldIrql); - if (MmPageArray[Start].Flags.Type == MM_PHYSICAL_PAGE_USED && - MmPageArray[Start].Flags.Consumer == MC_USER) - { + KeAcquireSpinLock(&PageListLock, &oldIrql); + if (MmPageArray[Start].Flags.Type == MM_PHYSICAL_PAGE_USED && + MmPageArray[Start].Flags.Consumer == MC_USER) + { RemoveEntryList(&MmPageArray[Start].ListEntry); - InsertTailList(&UsedPageListHeads[MC_USER], - &MmPageArray[Start].ListEntry); - } - KeReleaseSpinLock(&PageListLock, oldIrql); + InsertTailList(&UsedPageListHeads[MC_USER], + &MmPageArray[Start].ListEntry); + } + KeReleaseSpinLock(&PageListLock, oldIrql); } PHYSICAL_ADDRESS MmGetLRUNextUserPage(PHYSICAL_ADDRESS PreviousPhysicalAddress) { - ULONG Start = PreviousPhysicalAddress.u.LowPart / PAGE_SIZE; - PLIST_ENTRY NextListEntry; - PHYSICAL_ADDRESS Next; - PHYSICAL_PAGE* PageDescriptor; - KIRQL oldIrql; + ULONG Start = PreviousPhysicalAddress.u.LowPart / PAGE_SIZE; + PLIST_ENTRY NextListEntry; + PHYSICAL_ADDRESS Next; + PHYSICAL_PAGE* PageDescriptor; + KIRQL oldIrql; - KeAcquireSpinLock(&PageListLock, &oldIrql); - if (MmPageArray[Start].Flags.Type != MM_PHYSICAL_PAGE_USED || - MmPageArray[Start].Flags.Consumer != MC_USER) - { + KeAcquireSpinLock(&PageListLock, &oldIrql); + if (MmPageArray[Start].Flags.Type != MM_PHYSICAL_PAGE_USED || + MmPageArray[Start].Flags.Consumer != MC_USER) + { NextListEntry = UsedPageListHeads[MC_USER].Flink; - } - else - { + } + else + { NextListEntry = MmPageArray[Start].ListEntry.Flink; - } - if (NextListEntry == &UsedPageListHeads[MC_USER]) - { + } + if (NextListEntry == &UsedPageListHeads[MC_USER]) + { KeReleaseSpinLock(&PageListLock, oldIrql); #if defined(__GNUC__) + return((PHYSICAL_ADDRESS)0LL); #else + { - const PHYSICAL_ADDRESS dummyJunkNeeded = { 0 }; - return dummyJunkNeeded; + const PHYSICAL_ADDRESS dummyJunkNeeded = + { + 0 + }; + return dummyJunkNeeded; } #endif - } - PageDescriptor = CONTAINING_RECORD(NextListEntry, PHYSICAL_PAGE, ListEntry); - Next.QuadPart = (ULONG)((ULONG)PageDescriptor - (ULONG)MmPageArray); - Next.QuadPart = (Next.QuadPart / sizeof(PHYSICAL_PAGE)) * PAGE_SIZE; - KeReleaseSpinLock(&PageListLock, oldIrql); - return(Next); + + } + PageDescriptor = CONTAINING_RECORD(NextListEntry, PHYSICAL_PAGE, ListEntry); + Next.QuadPart = (ULONG)((ULONG)PageDescriptor - (ULONG)MmPageArray); + Next.QuadPart = (Next.QuadPart / sizeof(PHYSICAL_PAGE)) * PAGE_SIZE; + KeReleaseSpinLock(&PageListLock, oldIrql); + return(Next); } PHYSICAL_ADDRESS MmGetContinuousPages(ULONG NumberOfBytes, - PHYSICAL_ADDRESS LowestAcceptableAddress, - PHYSICAL_ADDRESS HighestAcceptableAddress, - ULONG Alignment) + PHYSICAL_ADDRESS LowestAcceptableAddress, + PHYSICAL_ADDRESS HighestAcceptableAddress, + ULONG Alignment) { ULONG NrPages; ULONG i; @@ -187,64 +203,75 @@ MmGetContinuousPages(ULONG NumberOfBytes, start = -1; length = 0; for (i = (LowestAcceptableAddress.QuadPart / PAGE_SIZE); i < (HighestAcceptableAddress.QuadPart / PAGE_SIZE); ) - { - if (MmPageArray[i].Flags.Type == MM_PHYSICAL_PAGE_FREE) - { - if (start == -1) - { - start = i; - length = 1; - } - else - { - length++; - } - i++; - if (length == NrPages) - { - break; - } - } - else - { - start = -1; - /* - * Fast forward to the base of the next aligned region - */ - i = ROUND_UP((i + 1), (Alignment / PAGE_SIZE)); - } - } + { + if (MmPageArray[i].Flags.Type == MM_PHYSICAL_PAGE_FREE) + { + if (start == -1) + { + start = i; + length = 1; + } + else + { + length++; + } + i++; + if (length == NrPages) + { + break; + } + } + else + { + start = -1; + /* + * Fast forward to the base of the next aligned region + */ + i = ROUND_UP((i + 1), (Alignment / PAGE_SIZE)); + } + } if (start == -1 || length != NrPages) - { - KeReleaseSpinLock(&PageListLock, oldIrql); + { + KeReleaseSpinLock(&PageListLock, oldIrql); #if defined(__GNUC__) - return((PHYSICAL_ADDRESS)(LONGLONG)0); + + return((PHYSICAL_ADDRESS)(LONGLONG)0); #else - { - const PHYSICAL_ADDRESS dummyJunkNeeded = { 0 }; - return dummyJunkNeeded; + + { + const PHYSICAL_ADDRESS dummyJunkNeeded = + { + 0 + }; + return dummyJunkNeeded; } #endif - } + + } for (i = start; i < (start + length); i++) - { - RemoveEntryList(&MmPageArray[i].ListEntry); - MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_USED; - MmPageArray[i].Flags.Consumer = MC_NPPOOL; - MmPageArray[i].ReferenceCount = 1; - MmPageArray[i].LockCount = 0; - MmPageArray[i].MapCount = 0; - MmPageArray[i].SavedSwapEntry = 0; - InsertTailList(&UsedPageListHeads[MC_NPPOOL], - &MmPageArray[i].ListEntry); - } + { + RemoveEntryList(&MmPageArray[i].ListEntry); + MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_USED; + MmPageArray[i].Flags.Consumer = MC_NPPOOL; + MmPageArray[i].ReferenceCount = 1; + MmPageArray[i].LockCount = 0; + MmPageArray[i].MapCount = 0; + MmPageArray[i].SavedSwapEntry = 0; + InsertTailList(&UsedPageListHeads[MC_NPPOOL], + &MmPageArray[i].ListEntry); + } KeReleaseSpinLock(&PageListLock, oldIrql); #if defined(__GNUC__) + return((PHYSICAL_ADDRESS)((LONGLONG)start * PAGE_SIZE)); #else + { - const PHYSICAL_ADDRESS dummyJunkNeeded = { start * PAGE_SIZE }; - return dummyJunkNeeded; + const PHYSICAL_ADDRESS dummyJunkNeeded = + { + start * PAGE_SIZE + }; + return dummyJunkNeeded; } #endif } @@ -252,91 +279,91 @@ MmGetContinuousPages(ULONG NumberOfBytes, VOID INIT_FUNCTION MiParseRangeToFreeList(PADDRESS_RANGE Range) { - ULONG i, first, last; + ULONG i, first, last; - /* FIXME: Not 64-bit ready */ + /* FIXME: Not 64-bit ready */ - DPRINT("Range going to free list (Base 0x%X, Length 0x%X, Type 0x%X)\n", - Range->BaseAddrLow, - Range->LengthLow, - Range->Type); - - first = (Range->BaseAddrLow + PAGE_SIZE - 1) / PAGE_SIZE; - last = first + ((Range->LengthLow + PAGE_SIZE - 1) / PAGE_SIZE); - for (i = first; i < last && i < MmPageArraySize; i++) - { + DPRINT("Range going to free list (Base 0x%X, Length 0x%X, Type 0x%X)\n", + Range->BaseAddrLow, + Range->LengthLow, + Range->Type); + + first = (Range->BaseAddrLow + PAGE_SIZE - 1) / PAGE_SIZE; + last = first + ((Range->LengthLow + PAGE_SIZE - 1) / PAGE_SIZE); + for (i = first; i < last && i < MmPageArraySize; i++) + { if (MmPageArray[i].Flags.Type == 0) - { - MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_FREE; - MmPageArray[i].ReferenceCount = 0; - InsertTailList(&FreeUnzeroedPageListHead, - &MmPageArray[i].ListEntry); - UnzeroedPageCount++; - } - } + { + MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_FREE; + MmPageArray[i].ReferenceCount = 0; + InsertTailList(&FreeUnzeroedPageListHead, + &MmPageArray[i].ListEntry); + UnzeroedPageCount++; + } + } } VOID INIT_FUNCTION MiParseRangeToBiosList(PADDRESS_RANGE Range) { - ULONG i, first, last; - - /* FIXME: Not 64-bit ready */ + ULONG i, first, last; - DPRINT("Range going to bios list (Base 0x%X, Length 0x%X, Type 0x%X)\n", - Range->BaseAddrLow, - Range->LengthLow, - Range->Type); - - first = (Range->BaseAddrLow + PAGE_SIZE - 1) / PAGE_SIZE; - last = first + ((Range->LengthLow + PAGE_SIZE - 1) / PAGE_SIZE); - for (i = first; i < last && i < MmPageArraySize; i++) - { + /* FIXME: Not 64-bit ready */ + + DPRINT("Range going to bios list (Base 0x%X, Length 0x%X, Type 0x%X)\n", + Range->BaseAddrLow, + Range->LengthLow, + Range->Type); + + first = (Range->BaseAddrLow + PAGE_SIZE - 1) / PAGE_SIZE; + last = first + ((Range->LengthLow + PAGE_SIZE - 1) / PAGE_SIZE); + for (i = first; i < last && i < MmPageArraySize; i++) + { /* Remove the page from the free list if it is there */ if (MmPageArray[i].Flags.Type == MM_PHYSICAL_PAGE_FREE) - { - RemoveEntryList(&MmPageArray[i].ListEntry); - } - + { + RemoveEntryList(&MmPageArray[i].ListEntry); + } + if (MmPageArray[i].Flags.Type != MM_PHYSICAL_PAGE_BIOS) - { - MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_BIOS; - MmPageArray[i].Flags.Consumer = MC_NPPOOL; - MmPageArray[i].ReferenceCount = 1; - InsertTailList(&BiosPageListHead, - &MmPageArray[i].ListEntry); - } - } + { + MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_BIOS; + MmPageArray[i].Flags.Consumer = MC_NPPOOL; + MmPageArray[i].ReferenceCount = 1; + InsertTailList(&BiosPageListHead, + &MmPageArray[i].ListEntry); + } + } } VOID INIT_FUNCTION MiParseBIOSMemoryMap(PADDRESS_RANGE BIOSMemoryMap, - ULONG AddressRangeCount) + ULONG AddressRangeCount) { - PADDRESS_RANGE p; - ULONG i; + PADDRESS_RANGE p; + ULONG i; - p = BIOSMemoryMap; - for (i = 0; i < AddressRangeCount; i++, p++) - { + p = BIOSMemoryMap; + for (i = 0; i < AddressRangeCount; i++, p++) + { if (p->Type == 1) - { - MiParseRangeToFreeList(p); - } + { + MiParseRangeToFreeList(p); + } else - { - MiParseRangeToBiosList(p); - } - } + { + MiParseRangeToBiosList(p); + } + } } PVOID INIT_FUNCTION MmInitializePageList(PVOID FirstPhysKernelAddress, - PVOID LastPhysKernelAddress, - ULONG MemorySizeInPages, - ULONG LastKernelAddress, - PADDRESS_RANGE BIOSMemoryMap, - ULONG AddressRangeCount) + PVOID LastPhysKernelAddress, + ULONG MemorySizeInPages, + ULONG LastKernelAddress, + PADDRESS_RANGE BIOSMemoryMap, + ULONG AddressRangeCount) /* * FUNCTION: Initializes the page list with all pages free * except those known to be reserved and those used by the kernel @@ -351,17 +378,17 @@ MmInitializePageList(PVOID FirstPhysKernelAddress, NTSTATUS Status; DPRINT("MmInitializePageList(FirstPhysKernelAddress %x, " - "LastPhysKernelAddress %x, " - "MemorySizeInPages %x, LastKernelAddress %x)\n", - FirstPhysKernelAddress, - LastPhysKernelAddress, - MemorySizeInPages, - LastKernelAddress); + "LastPhysKernelAddress %x, " + "MemorySizeInPages %x, LastKernelAddress %x)\n", + FirstPhysKernelAddress, + LastPhysKernelAddress, + MemorySizeInPages, + LastKernelAddress); for (i = 0; i < MC_MAXIMUM; i++) - { - InitializeListHead(&UsedPageListHeads[i]); - } + { + InitializeListHead(&UsedPageListHeads[i]); + } KeInitializeSpinLock(&PageListLock); InitializeListHead(&FreeUnzeroedPageListHead); InitializeListHead(&FreeZeroedPageListHead); @@ -370,8 +397,8 @@ MmInitializePageList(PVOID FirstPhysKernelAddress, LastKernelAddress = PAGE_ROUND_UP(LastKernelAddress); MmPageArraySize = MemorySizeInPages; - Reserved = - PAGE_ROUND_UP((MmPageArraySize * sizeof(PHYSICAL_PAGE))) / PAGE_SIZE; + Reserved = + PAGE_ROUND_UP((MmPageArraySize * sizeof(PHYSICAL_PAGE))) / PAGE_SIZE; MmPageArray = (PHYSICAL_PAGE *)LastKernelAddress; DPRINT("Reserved %d\n", Reserved); @@ -387,39 +414,41 @@ MmInitializePageList(PVOID FirstPhysKernelAddress, MmStats.NrReservedPages = 0; MmStats.NrFreePages = 0; MmStats.NrLockedPages = 0; - + for (i = 0; i < Reserved; i++) - { - PVOID Address = (char*)(ULONG)MmPageArray + (i * PAGE_SIZE); - if (!MmIsPagePresent(NULL, Address)) - { + { + PVOID Address = (char*)(ULONG)MmPageArray + (i * PAGE_SIZE); + if (!MmIsPagePresent(NULL, Address)) + { #if !defined(__GNUC__) - const PHYSICAL_ADDRESS dummyJunkNeeded = { - (ULONG)LastPhysKernelAddress - - (Reserved * PAGE_SIZE) + (i * PAGE_SIZE) - }; + const PHYSICAL_ADDRESS dummyJunkNeeded = + { + (ULONG)LastPhysKernelAddress - + (Reserved * PAGE_SIZE) + (i * PAGE_SIZE) + }; #endif - ULONG PhysicalAddress = (ULONG)LastPhysKernelAddress - - (Reserved * PAGE_SIZE) + (i * PAGE_SIZE); - Status = - MmCreateVirtualMappingUnsafe(NULL, - Address, - PAGE_READWRITE, + + ULONG PhysicalAddress = (ULONG)LastPhysKernelAddress - + (Reserved * PAGE_SIZE) + (i * PAGE_SIZE); + Status = + MmCreateVirtualMappingUnsafe(NULL, + Address, + PAGE_READWRITE, #if defined(__GNUC__) - (PHYSICAL_ADDRESS)(LONGLONG)PhysicalAddress, + (PHYSICAL_ADDRESS)(LONGLONG)PhysicalAddress, #else - dummyJunkNeeded, + dummyJunkNeeded, #endif - FALSE); - if (!NT_SUCCESS(Status)) - { - DbgPrint("Unable to create virtual mapping\n"); - KEBUGCHECK(0); - } - } - memset((char*)MmPageArray + (i * PAGE_SIZE), 0, PAGE_SIZE); - } - + FALSE); + if (!NT_SUCCESS(Status)) + { + DbgPrint("Unable to create virtual mapping\n"); + KEBUGCHECK(0); + } + } + memset((char*)MmPageArray + (i * PAGE_SIZE), 0, PAGE_SIZE); + } + /* * Page zero is reserved @@ -428,7 +457,7 @@ MmInitializePageList(PVOID FirstPhysKernelAddress, MmPageArray[0].Flags.Consumer = MC_NPPOOL; MmPageArray[0].ReferenceCount = 0; InsertTailList(&BiosPageListHead, - &MmPageArray[0].ListEntry); + &MmPageArray[0].ListEntry); /* * Page one is reserved for the initial KPCR @@ -437,118 +466,118 @@ MmInitializePageList(PVOID FirstPhysKernelAddress, MmPageArray[1].Flags.Consumer = MC_NPPOOL; MmPageArray[1].ReferenceCount = 0; InsertTailList(&BiosPageListHead, - &MmPageArray[1].ListEntry); + &MmPageArray[1].ListEntry); i = 2; if ((ULONG)FirstPhysKernelAddress < 0xa0000) - { - MmStats.NrFreePages += (((ULONG)FirstPhysKernelAddress/PAGE_SIZE) - 2); - for (; i<((ULONG)FirstPhysKernelAddress/PAGE_SIZE); i++) - { - MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_FREE; - MmPageArray[i].ReferenceCount = 0; - InsertTailList(&FreeUnzeroedPageListHead, - &MmPageArray[i].ListEntry); - UnzeroedPageCount++; - } - MmStats.NrSystemPages += - ((((ULONG)LastPhysKernelAddress) / PAGE_SIZE) - i); - for (; i<((ULONG)LastPhysKernelAddress / PAGE_SIZE); i++) - { - MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_USED; - MmPageArray[i].Flags.Consumer = MC_NPPOOL; - MmPageArray[i].ReferenceCount = 1; - MmPageArray[i].MapCount = 1; - InsertTailList(&UsedPageListHeads[MC_NPPOOL], - &MmPageArray[i].ListEntry); - } - MmStats.NrFreePages += ((0xa0000/PAGE_SIZE) - i); - for (; i<(0xa0000/PAGE_SIZE); i++) - { - MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_FREE; - MmPageArray[i].ReferenceCount = 0; - InsertTailList(&FreeUnzeroedPageListHead, - &MmPageArray[i].ListEntry); - UnzeroedPageCount++; - } - MmStats.NrReservedPages += ((0x100000/PAGE_SIZE) - i); - for (; i<(0x100000 / PAGE_SIZE); i++) - { - MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_BIOS; - MmPageArray[i].Flags.Consumer = MC_NPPOOL; - MmPageArray[i].ReferenceCount = 1; - InsertTailList(&BiosPageListHead, - &MmPageArray[i].ListEntry); - } - } + { + MmStats.NrFreePages += (((ULONG)FirstPhysKernelAddress/PAGE_SIZE) - 2); + for (; i<((ULONG)FirstPhysKernelAddress/PAGE_SIZE); i++) + { + MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_FREE; + MmPageArray[i].ReferenceCount = 0; + InsertTailList(&FreeUnzeroedPageListHead, + &MmPageArray[i].ListEntry); + UnzeroedPageCount++; + } + MmStats.NrSystemPages += + ((((ULONG)LastPhysKernelAddress) / PAGE_SIZE) - i); + for (; i<((ULONG)LastPhysKernelAddress / PAGE_SIZE); i++) + { + MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_USED; + MmPageArray[i].Flags.Consumer = MC_NPPOOL; + MmPageArray[i].ReferenceCount = 1; + MmPageArray[i].MapCount = 1; + InsertTailList(&UsedPageListHeads[MC_NPPOOL], + &MmPageArray[i].ListEntry); + } + MmStats.NrFreePages += ((0xa0000/PAGE_SIZE) - i); + for (; i<(0xa0000/PAGE_SIZE); i++) + { + MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_FREE; + MmPageArray[i].ReferenceCount = 0; + InsertTailList(&FreeUnzeroedPageListHead, + &MmPageArray[i].ListEntry); + UnzeroedPageCount++; + } + MmStats.NrReservedPages += ((0x100000/PAGE_SIZE) - i); + for (; i<(0x100000 / PAGE_SIZE); i++) + { + MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_BIOS; + MmPageArray[i].Flags.Consumer = MC_NPPOOL; + MmPageArray[i].ReferenceCount = 1; + InsertTailList(&BiosPageListHead, + &MmPageArray[i].ListEntry); + } + } else - { - MmStats.NrFreePages += ((0xa0000 / PAGE_SIZE) - 2); - for (; i<(0xa0000 / PAGE_SIZE); i++) - { - MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_FREE; - MmPageArray[i].ReferenceCount = 0; - InsertTailList(&FreeUnzeroedPageListHead, - &MmPageArray[i].ListEntry); - UnzeroedPageCount++; - } - MmStats.NrReservedPages += (0x60000 / PAGE_SIZE); - for (; i<(0x100000 / PAGE_SIZE); i++) - { - MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_BIOS; - MmPageArray[i].Flags.Consumer = MC_NPPOOL; - MmPageArray[i].ReferenceCount = 1; - InsertTailList(&BiosPageListHead, - &MmPageArray[i].ListEntry); - } - MmStats.NrFreePages += (((ULONG)FirstPhysKernelAddress/PAGE_SIZE) - i); - for (; i<((ULONG)FirstPhysKernelAddress/PAGE_SIZE); i++) - { - MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_FREE; - MmPageArray[i].ReferenceCount = 0; - InsertTailList(&FreeUnzeroedPageListHead, - &MmPageArray[i].ListEntry); - UnzeroedPageCount++; - } - MmStats.NrSystemPages += - (((ULONG)LastPhysKernelAddress/PAGE_SIZE) - i); - for (; i<((ULONG)LastPhysKernelAddress/PAGE_SIZE); i++) - { - MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_USED; - MmPageArray[i].Flags.Consumer = MC_NPPOOL; - MmPageArray[i].ReferenceCount = 1; - MmPageArray[i].MapCount = 1; - InsertTailList(&UsedPageListHeads[MC_NPPOOL], - &MmPageArray[i].ListEntry); - } - } - + { + MmStats.NrFreePages += ((0xa0000 / PAGE_SIZE) - 2); + for (; i<(0xa0000 / PAGE_SIZE); i++) + { + MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_FREE; + MmPageArray[i].ReferenceCount = 0; + InsertTailList(&FreeUnzeroedPageListHead, + &MmPageArray[i].ListEntry); + UnzeroedPageCount++; + } + MmStats.NrReservedPages += (0x60000 / PAGE_SIZE); + for (; i<(0x100000 / PAGE_SIZE); i++) + { + MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_BIOS; + MmPageArray[i].Flags.Consumer = MC_NPPOOL; + MmPageArray[i].ReferenceCount = 1; + InsertTailList(&BiosPageListHead, + &MmPageArray[i].ListEntry); + } + MmStats.NrFreePages += (((ULONG)FirstPhysKernelAddress/PAGE_SIZE) - i); + for (; i<((ULONG)FirstPhysKernelAddress/PAGE_SIZE); i++) + { + MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_FREE; + MmPageArray[i].ReferenceCount = 0; + InsertTailList(&FreeUnzeroedPageListHead, + &MmPageArray[i].ListEntry); + UnzeroedPageCount++; + } + MmStats.NrSystemPages += + (((ULONG)LastPhysKernelAddress/PAGE_SIZE) - i); + for (; i<((ULONG)LastPhysKernelAddress/PAGE_SIZE); i++) + { + MmPageArray[i].Flags.Type = MM_PHYSICAL_PAGE_USED; + MmPageArray[i].Flags.Consumer = MC_NPPOOL; + MmPageArray[i].ReferenceCount = 1; + MmPageArray[i].MapCount = 1; + InsertTailList(&UsedPageListHeads[MC_NPPOOL], + &MmPageArray[i].ListEntry); + } + } + MmStats.NrFreePages += (MemorySizeInPages - i); for (; i 0)) - { + if ((BIOSMemoryMap != NULL) && (AddressRangeCount > 0)) + { MiParseBIOSMemoryMap( - BIOSMemoryMap, - AddressRangeCount); - } + BIOSMemoryMap, + AddressRangeCount); + } KeInitializeEvent(&ZeroPageThreadEvent, NotificationEvent, TRUE); MmStats.NrTotalPages = MmStats.NrFreePages + MmStats.NrSystemPages + - MmStats.NrReservedPages + MmStats.NrUserPages; + MmStats.NrReservedPages + MmStats.NrUserPages; MmInitializeBalancer(MmStats.NrFreePages, MmStats.NrSystemPages + MmStats.NrReservedPages); return((PVOID)LastKernelAddress); } -VOID +VOID MmSetFlagsPage(PHYSICAL_ADDRESS PhysicalAddress, ULONG Flags) { ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE; @@ -559,9 +588,9 @@ MmSetFlagsPage(PHYSICAL_ADDRESS PhysicalAddress, ULONG Flags) KeReleaseSpinLock(&PageListLock, oldIrql); } -VOID -MmSetRmapListHeadPage(PHYSICAL_ADDRESS PhysicalAddress, - struct _MM_RMAP_ENTRY* ListHead) +VOID +MmSetRmapListHeadPage(PHYSICAL_ADDRESS PhysicalAddress, + struct _MM_RMAP_ENTRY* ListHead) { ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE; @@ -569,57 +598,57 @@ MmSetRmapListHeadPage(PHYSICAL_ADDRESS PhysicalAddress, } struct _MM_RMAP_ENTRY* -MmGetRmapListHeadPage(PHYSICAL_ADDRESS PhysicalAddress) + MmGetRmapListHeadPage(PHYSICAL_ADDRESS PhysicalAddress) { - ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE; + ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE; - return(MmPageArray[Start].RmapListHead); + return(MmPageArray[Start].RmapListHead); } -VOID +VOID MmMarkPageMapped(PHYSICAL_ADDRESS PhysicalAddress) { - ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE; - KIRQL oldIrql; + ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE; + KIRQL oldIrql; - if (Start < MmPageArraySize) - { + if (Start < MmPageArraySize) + { KeAcquireSpinLock(&PageListLock, &oldIrql); if (MmPageArray[Start].Flags.Type == MM_PHYSICAL_PAGE_FREE) - { - DbgPrint("Mapping non-used page\n"); - KEBUGCHECK(0); - } + { + DbgPrint("Mapping non-used page\n"); + KEBUGCHECK(0); + } MmPageArray[Start].MapCount++; KeReleaseSpinLock(&PageListLock, oldIrql); - } + } } -VOID +VOID MmMarkPageUnmapped(PHYSICAL_ADDRESS PhysicalAddress) { - ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE; - KIRQL oldIrql; + ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE; + KIRQL oldIrql; - if (Start < MmPageArraySize) - { + if (Start < MmPageArraySize) + { KeAcquireSpinLock(&PageListLock, &oldIrql); if (MmPageArray[Start].Flags.Type == MM_PHYSICAL_PAGE_FREE) - { - DbgPrint("Unmapping non-used page\n"); - KEBUGCHECK(0); - } + { + DbgPrint("Unmapping non-used page\n"); + KEBUGCHECK(0); + } if (MmPageArray[Start].MapCount == 0) - { - DbgPrint("Unmapping not mapped page\n"); - KEBUGCHECK(0); - } + { + DbgPrint("Unmapping not mapped page\n"); + KEBUGCHECK(0); + } MmPageArray[Start].MapCount--; KeReleaseSpinLock(&PageListLock, oldIrql); - } + } } -ULONG +ULONG MmGetFlagsPage(PHYSICAL_ADDRESS PhysicalAddress) { ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE; @@ -629,14 +658,14 @@ MmGetFlagsPage(PHYSICAL_ADDRESS PhysicalAddress) KeAcquireSpinLock(&PageListLock, &oldIrql); Flags = MmPageArray[Start].AllFlags; KeReleaseSpinLock(&PageListLock, oldIrql); - + return(Flags); } -VOID +VOID MmSetSavedSwapEntryPage(PHYSICAL_ADDRESS PhysicalAddress, - SWAPENTRY SavedSwapEntry) + SWAPENTRY SavedSwapEntry) { ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE; KIRQL oldIrql; @@ -646,7 +675,7 @@ MmSetSavedSwapEntryPage(PHYSICAL_ADDRESS PhysicalAddress, KeReleaseSpinLock(&PageListLock, oldIrql); } -SWAPENTRY +SWAPENTRY MmGetSavedSwapEntryPage(PHYSICAL_ADDRESS PhysicalAddress) { ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE; @@ -660,7 +689,7 @@ MmGetSavedSwapEntryPage(PHYSICAL_ADDRESS PhysicalAddress) return(SavedSwapEntry); } -VOID +VOID MmReferencePage(PHYSICAL_ADDRESS PhysicalAddress) { ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE; @@ -669,17 +698,17 @@ MmReferencePage(PHYSICAL_ADDRESS PhysicalAddress) DPRINT("MmReferencePage(PhysicalAddress %x)\n", PhysicalAddress); if (PhysicalAddress.u.LowPart == 0) - { - KEBUGCHECK(0); - } + { + KEBUGCHECK(0); + } KeAcquireSpinLock(&PageListLock, &oldIrql); - + if (MmPageArray[Start].Flags.Type != MM_PHYSICAL_PAGE_USED) - { - DbgPrint("Referencing non-used page\n"); - KEBUGCHECK(0); - } + { + DbgPrint("Referencing non-used page\n"); + KEBUGCHECK(0); + } MmPageArray[Start].ReferenceCount++; KeReleaseSpinLock(&PageListLock, oldIrql); @@ -695,17 +724,17 @@ MmGetReferenceCountPage(PHYSICAL_ADDRESS PhysicalAddress) DPRINT("MmGetReferenceCountPage(PhysicalAddress %x)\n", PhysicalAddress); if (PhysicalAddress.u.LowPart == 0) - { - KEBUGCHECK(0); - } + { + KEBUGCHECK(0); + } KeAcquireSpinLock(&PageListLock, &oldIrql); - + if (MmPageArray[Start].Flags.Type != MM_PHYSICAL_PAGE_USED) - { - DbgPrint("Getting reference count for free page\n"); - KEBUGCHECK(0); - } + { + DbgPrint("Getting reference count for free page\n"); + KEBUGCHECK(0); + } RCount = MmPageArray[Start].ReferenceCount; @@ -721,87 +750,87 @@ MmIsUsablePage(PHYSICAL_ADDRESS PhysicalAddress) DPRINT("MmIsUsablePage(PhysicalAddress %x)\n", PhysicalAddress); if (PhysicalAddress.u.LowPart == 0) - { - KEBUGCHECK(0); - } + { + KEBUGCHECK(0); + } if (MmPageArray[Start].Flags.Type != MM_PHYSICAL_PAGE_USED && - MmPageArray[Start].Flags.Type != MM_PHYSICAL_PAGE_BIOS) - { - return(FALSE); - } + MmPageArray[Start].Flags.Type != MM_PHYSICAL_PAGE_BIOS) + { + return(FALSE); + } return(TRUE); } -VOID +VOID MmDereferencePage(PHYSICAL_ADDRESS PhysicalAddress) { ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE; KIRQL oldIrql; - + DPRINT("MmDereferencePage(PhysicalAddress %I64x)\n", PhysicalAddress); if (PhysicalAddress.u.LowPart == 0) - { - KEBUGCHECK(0); - } - + { + KEBUGCHECK(0); + } + KeAcquireSpinLock(&PageListLock, &oldIrql); - + if (MmPageArray[Start].Flags.Type != MM_PHYSICAL_PAGE_USED) - { - DbgPrint("Dereferencing free page\n"); - KEBUGCHECK(0); - } + { + DbgPrint("Dereferencing free page\n"); + KEBUGCHECK(0); + } MmPageArray[Start].ReferenceCount--; if (MmPageArray[Start].ReferenceCount == 0) - { - MmStats.NrFreePages++; - MmStats.NrSystemPages--; - RemoveEntryList(&MmPageArray[Start].ListEntry); - if (MmPageArray[Start].RmapListHead != NULL) - { - DbgPrint("Freeing page with rmap entries.\n"); - KEBUGCHECK(0); - } - if (MmPageArray[Start].MapCount != 0) - { - DbgPrint("Freeing mapped page (0x%I64x count %d)\n", - PhysicalAddress, MmPageArray[Start].MapCount); - KEBUGCHECK(0); - } - if (MmPageArray[Start].LockCount > 0) - { - DbgPrint("Freeing locked page\n"); - KEBUGCHECK(0); - } - if (MmPageArray[Start].SavedSwapEntry != 0) - { - DbgPrint("Freeing page with swap entry.\n"); - KEBUGCHECK(0); - } - if (MmPageArray[Start].Flags.Type != MM_PHYSICAL_PAGE_USED) - { - DbgPrint("Freeing page with flags %x\n", - MmPageArray[Start].Flags.Type); - KEBUGCHECK(0); - } - MmPageArray[Start].Flags.Type = MM_PHYSICAL_PAGE_FREE; - InsertTailList(&FreeUnzeroedPageListHead, - &MmPageArray[Start].ListEntry); - UnzeroedPageCount++; - if (UnzeroedPageCount > 8 && 0 == KeReadStateEvent(&ZeroPageThreadEvent)) - { - KeSetEvent(&ZeroPageThreadEvent, IO_NO_INCREMENT, FALSE); - } - } + { + MmStats.NrFreePages++; + MmStats.NrSystemPages--; + RemoveEntryList(&MmPageArray[Start].ListEntry); + if (MmPageArray[Start].RmapListHead != NULL) + { + DbgPrint("Freeing page with rmap entries.\n"); + KEBUGCHECK(0); + } + if (MmPageArray[Start].MapCount != 0) + { + DbgPrint("Freeing mapped page (0x%I64x count %d)\n", + PhysicalAddress, MmPageArray[Start].MapCount); + KEBUGCHECK(0); + } + if (MmPageArray[Start].LockCount > 0) + { + DbgPrint("Freeing locked page\n"); + KEBUGCHECK(0); + } + if (MmPageArray[Start].SavedSwapEntry != 0) + { + DbgPrint("Freeing page with swap entry.\n"); + KEBUGCHECK(0); + } + if (MmPageArray[Start].Flags.Type != MM_PHYSICAL_PAGE_USED) + { + DbgPrint("Freeing page with flags %x\n", + MmPageArray[Start].Flags.Type); + KEBUGCHECK(0); + } + MmPageArray[Start].Flags.Type = MM_PHYSICAL_PAGE_FREE; + InsertTailList(&FreeUnzeroedPageListHead, + &MmPageArray[Start].ListEntry); + UnzeroedPageCount++; + if (UnzeroedPageCount > 8 && 0 == KeReadStateEvent(&ZeroPageThreadEvent)) + { + KeSetEvent(&ZeroPageThreadEvent, IO_NO_INCREMENT, FALSE); + } + } KeReleaseSpinLock(&PageListLock, oldIrql); } -ULONG +ULONG MmGetLockCountPage(PHYSICAL_ADDRESS PhysicalAddress) { ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE; @@ -811,17 +840,17 @@ MmGetLockCountPage(PHYSICAL_ADDRESS PhysicalAddress) DPRINT("MmGetLockCountPage(PhysicalAddress %x)\n", PhysicalAddress); if (PhysicalAddress.u.LowPart == 0) - { - KEBUGCHECK(0); - } + { + KEBUGCHECK(0); + } KeAcquireSpinLock(&PageListLock, &oldIrql); if (MmPageArray[Start].Flags.Type != MM_PHYSICAL_PAGE_USED) - { - DbgPrint("Getting lock count for free page\n"); - KEBUGCHECK(0); - } + { + DbgPrint("Getting lock count for free page\n"); + KEBUGCHECK(0); + } LockCount = MmPageArray[Start].LockCount; KeReleaseSpinLock(&PageListLock, oldIrql); @@ -829,7 +858,7 @@ MmGetLockCountPage(PHYSICAL_ADDRESS PhysicalAddress) return(LockCount); } -VOID +VOID MmLockPage(PHYSICAL_ADDRESS PhysicalAddress) { ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE; @@ -838,23 +867,23 @@ MmLockPage(PHYSICAL_ADDRESS PhysicalAddress) DPRINT("MmLockPage(PhysicalAddress %x)\n", PhysicalAddress); if (PhysicalAddress.u.LowPart == 0) - { - KEBUGCHECK(0); - } + { + KEBUGCHECK(0); + } KeAcquireSpinLock(&PageListLock, &oldIrql); if (MmPageArray[Start].Flags.Type != MM_PHYSICAL_PAGE_USED) - { - DbgPrint("Locking free page\n"); - KEBUGCHECK(0); - } + { + DbgPrint("Locking free page\n"); + KEBUGCHECK(0); + } MmPageArray[Start].LockCount++; KeReleaseSpinLock(&PageListLock, oldIrql); } -VOID +VOID MmUnlockPage(PHYSICAL_ADDRESS PhysicalAddress) { ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE; @@ -863,18 +892,18 @@ MmUnlockPage(PHYSICAL_ADDRESS PhysicalAddress) DPRINT("MmUnlockPage(PhysicalAddress %I64x)\n", PhysicalAddress); if (PhysicalAddress.u.LowPart == 0) - { - KEBUGCHECK(0); - } - + { + KEBUGCHECK(0); + } + KeAcquireSpinLock(&PageListLock, &oldIrql); - + if (MmPageArray[Start].Flags.Type != MM_PHYSICAL_PAGE_USED) - { - DbgPrint("Unlocking free page\n"); - KEBUGCHECK(0); - } - + { + DbgPrint("Unlocking free page\n"); + KEBUGCHECK(0); + } + MmPageArray[Start].LockCount--; KeReleaseSpinLock(&PageListLock, oldIrql); } @@ -882,180 +911,186 @@ MmUnlockPage(PHYSICAL_ADDRESS PhysicalAddress) PHYSICAL_ADDRESS MmAllocPage(ULONG Consumer, SWAPENTRY SavedSwapEntry) { - PHYSICAL_ADDRESS PageOffset; - PLIST_ENTRY ListEntry; - PPHYSICAL_PAGE PageDescriptor; - KIRQL oldIrql; - BOOLEAN NeedClear = FALSE; - - DPRINT("MmAllocPage()\n"); - - KeAcquireSpinLock(&PageListLock, &oldIrql); - if (IsListEmpty(&FreeZeroedPageListHead)) - { + PHYSICAL_ADDRESS PageOffset; + PLIST_ENTRY ListEntry; + PPHYSICAL_PAGE PageDescriptor; + KIRQL oldIrql; + BOOLEAN NeedClear = FALSE; + + DPRINT("MmAllocPage()\n"); + + KeAcquireSpinLock(&PageListLock, &oldIrql); + if (IsListEmpty(&FreeZeroedPageListHead)) + { if (IsListEmpty(&FreeUnzeroedPageListHead)) - { - DPRINT1("MmAllocPage(): Out of memory\n"); - KeReleaseSpinLock(&PageListLock, oldIrql); + { + DPRINT1("MmAllocPage(): Out of memory\n"); + KeReleaseSpinLock(&PageListLock, oldIrql); #if defined(__GNUC__) - return((PHYSICAL_ADDRESS)0LL); + + return((PHYSICAL_ADDRESS)0LL); #else - { - const PHYSICAL_ADDRESS dummyJunkNeeded = { 0 }; - return dummyJunkNeeded; - } + + { + const PHYSICAL_ADDRESS dummyJunkNeeded = + { + 0 + }; + return dummyJunkNeeded; + } #endif - } + + } ListEntry = RemoveTailList(&FreeUnzeroedPageListHead); UnzeroedPageCount--; - + PageDescriptor = CONTAINING_RECORD(ListEntry, PHYSICAL_PAGE, ListEntry); - + NeedClear = TRUE; - } - else - { + } + else + { ListEntry = RemoveTailList(&FreeZeroedPageListHead); - + PageDescriptor = CONTAINING_RECORD(ListEntry, PHYSICAL_PAGE, ListEntry); - } - - if (PageDescriptor->Flags.Type != MM_PHYSICAL_PAGE_FREE) - { + } + + if (PageDescriptor->Flags.Type != MM_PHYSICAL_PAGE_FREE) + { DbgPrint("Got non-free page from freelist\n"); KEBUGCHECK(0); - } - if (PageDescriptor->MapCount != 0) - { + } + if (PageDescriptor->MapCount != 0) + { DbgPrint("Got mapped page from freelist\n"); KEBUGCHECK(0); - } - PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_USED; - PageDescriptor->Flags.Consumer = Consumer; - PageDescriptor->ReferenceCount = 1; - PageDescriptor->LockCount = 0; - PageDescriptor->MapCount = 0; - PageDescriptor->SavedSwapEntry = SavedSwapEntry; - InsertTailList(&UsedPageListHeads[Consumer], ListEntry); - - MmStats.NrSystemPages++; - MmStats.NrFreePages--; + } + PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_USED; + PageDescriptor->Flags.Consumer = Consumer; + PageDescriptor->ReferenceCount = 1; + PageDescriptor->LockCount = 0; + PageDescriptor->MapCount = 0; + PageDescriptor->SavedSwapEntry = SavedSwapEntry; + InsertTailList(&UsedPageListHeads[Consumer], ListEntry); - KeReleaseSpinLock(&PageListLock, oldIrql); + MmStats.NrSystemPages++; + MmStats.NrFreePages--; - PageOffset.QuadPart = (ULONG)((ULONG)PageDescriptor - (ULONG)MmPageArray); - PageOffset.QuadPart = - (PageOffset.QuadPart / sizeof(PHYSICAL_PAGE)) * PAGE_SIZE; - if (NeedClear) - { + KeReleaseSpinLock(&PageListLock, oldIrql); + + PageOffset.QuadPart = (ULONG)((ULONG)PageDescriptor - (ULONG)MmPageArray); + PageOffset.QuadPart = + (PageOffset.QuadPart / sizeof(PHYSICAL_PAGE)) * PAGE_SIZE; + if (NeedClear) + { MiZeroPage(PageOffset); - } - if (PageDescriptor->MapCount != 0) - { + } + if (PageDescriptor->MapCount != 0) + { DbgPrint("Returning mapped page.\n"); KEBUGCHECK(0); - } - return(PageOffset); + } + return(PageOffset); } NTSTATUS STDCALL MmZeroPageThreadMain(PVOID Ignored) { - NTSTATUS Status; - KIRQL oldIrql; - PLIST_ENTRY ListEntry; - PPHYSICAL_PAGE PageDescriptor; - PHYSICAL_ADDRESS PhysPage; - static PVOID Address = NULL; - ULONG Count; - - while(1) - { + NTSTATUS Status; + KIRQL oldIrql; + PLIST_ENTRY ListEntry; + PPHYSICAL_PAGE PageDescriptor; + PHYSICAL_ADDRESS PhysPage; + static PVOID Address = NULL; + ULONG Count; + + while(1) + { Status = KeWaitForSingleObject(&ZeroPageThreadEvent, - 0, - KernelMode, - FALSE, - NULL); + 0, + KernelMode, + FALSE, + NULL); if (!NT_SUCCESS(Status)) - { - DbgPrint("ZeroPageThread: Wait failed\n"); - KEBUGCHECK(0); - return(STATUS_UNSUCCESSFUL); - } + { + DbgPrint("ZeroPageThread: Wait failed\n"); + KEBUGCHECK(0); + return(STATUS_UNSUCCESSFUL); + } Count = 0; KeAcquireSpinLock(&PageListLock, &oldIrql); while (!IsListEmpty(&FreeUnzeroedPageListHead)) { ListEntry = RemoveTailList(&FreeUnzeroedPageListHead); - UnzeroedPageCount--; + UnzeroedPageCount--; PageDescriptor = CONTAINING_RECORD(ListEntry, PHYSICAL_PAGE, ListEntry); - /* We set the page to used, because MmCreateVirtualMapping failed with unused pages */ - PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_USED; + /* We set the page to used, because MmCreateVirtualMapping failed with unused pages */ + PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_USED; KeReleaseSpinLock(&PageListLock, oldIrql); - Count++; + Count++; PhysPage.QuadPart = (ULONG)((ULONG)PageDescriptor - (ULONG)MmPageArray); PhysPage.QuadPart = (PhysPage.QuadPart / sizeof(PHYSICAL_PAGE)) * PAGE_SIZE; - if (Address == NULL) - { - Address = ExAllocatePageWithPhysPage(PhysPage); - } - else - { - Status = MmCreateVirtualMapping(NULL, - Address, - PAGE_READWRITE | PAGE_SYSTEM, - PhysPage, - FALSE); + if (Address == NULL) + { + Address = ExAllocatePageWithPhysPage(PhysPage); + } + else + { + Status = MmCreateVirtualMapping(NULL, + Address, + PAGE_READWRITE | PAGE_SYSTEM, + PhysPage, + FALSE); if (!NT_SUCCESS(Status)) { DbgPrint("Unable to create virtual mapping\n"); - KEBUGCHECK(0); + KEBUGCHECK(0); } - } + } memset(Address, 0, PAGE_SIZE); MmDeleteVirtualMapping(NULL, (PVOID)Address, FALSE, NULL, NULL); KeAcquireSpinLock(&PageListLock, &oldIrql); - if (PageDescriptor->MapCount != 0) - { - DbgPrint("Mapped page on freelist.\n"); - KEBUGCHECK(0); - } - PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_FREE; - InsertHeadList(&FreeZeroedPageListHead, ListEntry); + if (PageDescriptor->MapCount != 0) + { + DbgPrint("Mapped page on freelist.\n"); + KEBUGCHECK(0); + } + PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_FREE; + InsertHeadList(&FreeZeroedPageListHead, ListEntry); } DPRINT("Zeroed %d pages.\n", Count); KeResetEvent(&ZeroPageThreadEvent); KeReleaseSpinLock(&PageListLock, oldIrql); - } + } } - + NTSTATUS INIT_FUNCTION MmInitZeroPageThread(VOID) { - KPRIORITY Priority; - NTSTATUS Status; - - Status = PsCreateSystemThread(&ZeroPageThreadHandle, - THREAD_ALL_ACCESS, - NULL, - NULL, - &ZeroPageThreadId, - (PKSTART_ROUTINE) MmZeroPageThreadMain, - NULL); - if (!NT_SUCCESS(Status)) - { + KPRIORITY Priority; + NTSTATUS Status; + + Status = PsCreateSystemThread(&ZeroPageThreadHandle, + THREAD_ALL_ACCESS, + NULL, + NULL, + &ZeroPageThreadId, + (PKSTART_ROUTINE) MmZeroPageThreadMain, + NULL); + if (!NT_SUCCESS(Status)) + { return(Status); - } - - Priority = 1; - NtSetInformationThread(ZeroPageThreadHandle, - ThreadPriority, - &Priority, - sizeof(Priority)); - - return(STATUS_SUCCESS); + } + + Priority = 1; + NtSetInformationThread(ZeroPageThreadHandle, + ThreadPriority, + &Priority, + sizeof(Priority)); + + return(STATUS_SUCCESS); } - + /* EOF */ diff --git a/reactos/ntoskrnl/mm/i386/page.c b/reactos/ntoskrnl/mm/i386/page.c index da6ba4667c6..340caaae5f0 100644 --- a/reactos/ntoskrnl/mm/i386/page.c +++ b/reactos/ntoskrnl/mm/i386/page.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: page.c,v 1.63 2004/03/09 21:49:53 dwelch Exp $ +/* $Id: page.c,v 1.64 2004/04/10 22:36:07 gdalsnes Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/mm/i386/page.c @@ -66,15 +66,15 @@ ULONG MmGlobalKernelPageDirectory[1024] = {0, }; #else __inline LARGE_INTEGER PTE_TO_PAGE(ULONG npage) { - LARGE_INTEGER dummy; - dummy.QuadPart = (LONGLONG)(PAGE_MASK(npage)); - return dummy; + LARGE_INTEGER dummy; + dummy.QuadPart = (LONGLONG)(PAGE_MASK(npage)); + return dummy; } #endif /* FUNCTIONS ***************************************************************/ -PULONG +PULONG MmGetPageDirectory(VOID) { unsigned int page_dir=0; @@ -82,42 +82,42 @@ MmGetPageDirectory(VOID) return((PULONG)page_dir); } -static ULONG +static ULONG ProtectToPTE(ULONG flProtect) { - ULONG Attributes = 0; - - if (flProtect & PAGE_NOACCESS || flProtect & PAGE_GUARD) - { + ULONG Attributes = 0; + + if (flProtect & PAGE_NOACCESS || flProtect & PAGE_GUARD) + { Attributes = 0; - } - else if (flProtect & PAGE_READWRITE || flProtect & PAGE_EXECUTE_READWRITE) - { + } + else if (flProtect & PAGE_READWRITE || flProtect & PAGE_EXECUTE_READWRITE) + { Attributes = PA_PRESENT | PA_READWRITE; - } - else if (flProtect & PAGE_READONLY || flProtect & PAGE_EXECUTE || - flProtect & PAGE_EXECUTE_READ) - { - Attributes = PA_PRESENT; - } - else - { + } + else if (flProtect & PAGE_READONLY || flProtect & PAGE_EXECUTE || + flProtect & PAGE_EXECUTE_READ) + { + Attributes = PA_PRESENT; + } + else + { DPRINT1("Unknown main protection type.\n"); KEBUGCHECK(0); - } - if (!(flProtect & PAGE_SYSTEM)) - { + } + if (!(flProtect & PAGE_SYSTEM)) + { Attributes = Attributes | PA_USER; - } - if (flProtect & PAGE_NOCACHE) - { + } + if (flProtect & PAGE_NOCACHE) + { Attributes = Attributes | PA_CD; - } - if (flProtect & PAGE_WRITETHROUGH) - { + } + if (flProtect & PAGE_WRITETHROUGH) + { Attributes = Attributes | PA_WT; - } - return(Attributes); + } + return(Attributes); } #define ADDR_TO_PAGE_TABLE(v) (((ULONG)(v)) / (4 * 1024 * 1024)) @@ -137,23 +137,25 @@ NTSTATUS Mmi386ReleaseMmInfo(PEPROCESS Process) LdtDescriptor = (PUSHORT) &Process->Pcb.LdtDescriptor[0]; LdtBase = LdtDescriptor[1] | - ((LdtDescriptor[2] & 0xff) << 16) | - ((LdtDescriptor[3] & ~0xff) << 16); + ((LdtDescriptor[2] & 0xff) << 16) | + ((LdtDescriptor[3] & ~0xff) << 16); DPRINT("LdtBase: %x\n", LdtBase); - + if (LdtBase) - { - ExFreePool((PVOID) LdtBase); - } - + { + ExFreePool((PVOID) LdtBase); + } + MmReleasePageMemoryConsumer(MC_NPPOOL, Process->Pcb.DirectoryTableBase); #if defined(__GNUC__) + Process->Pcb.DirectoryTableBase.QuadPart = 0LL; #else + Process->Pcb.DirectoryTableBase.QuadPart = 0; #endif - + DPRINT("Finished Mmi386ReleaseMmInfo()\n"); return(STATUS_SUCCESS); } @@ -163,28 +165,28 @@ NTSTATUS MmCopyMmInfo(PEPROCESS Src, PEPROCESS Dest) PHYSICAL_ADDRESS PhysPageDirectory; PULONG PageDirectory; PKPROCESS KProcess = &Dest->Pcb; - + DPRINT("MmCopyMmInfo(Src %x, Dest %x)\n", Src, Dest); - + PageDirectory = ExAllocatePage(); if (PageDirectory == NULL) - { - return(STATUS_UNSUCCESSFUL); - } + { + return(STATUS_UNSUCCESSFUL); + } PhysPageDirectory = MmGetPhysicalAddress(PageDirectory); - KProcess->DirectoryTableBase = PhysPageDirectory; - + KProcess->DirectoryTableBase = PhysPageDirectory; + memset(PageDirectory,0, ADDR_TO_PDE_OFFSET(KERNEL_BASE) * sizeof(ULONG)); - memcpy(PageDirectory + ADDR_TO_PDE_OFFSET(KERNEL_BASE), - MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(KERNEL_BASE), - (1024 - ADDR_TO_PDE_OFFSET(KERNEL_BASE)) * sizeof(ULONG)); + memcpy(PageDirectory + ADDR_TO_PDE_OFFSET(KERNEL_BASE), + MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(KERNEL_BASE), + (1024 - ADDR_TO_PDE_OFFSET(KERNEL_BASE)) * sizeof(ULONG)); DPRINT("Addr %x\n",PAGETABLE_MAP / (4*1024*1024)); - PageDirectory[PAGETABLE_MAP / (4*1024*1024)] = - PhysPageDirectory.u.LowPart | PA_PRESENT | PA_READWRITE; - + PageDirectory[PAGETABLE_MAP / (4*1024*1024)] = + PhysPageDirectory.u.LowPart | PA_PRESENT | PA_READWRITE; + ExUnmapPage(PageDirectory); - + DPRINT("Finished MmCopyMmInfo()\n"); return(STATUS_SUCCESS); } @@ -192,22 +194,22 @@ NTSTATUS MmCopyMmInfo(PEPROCESS Src, PEPROCESS Dest) VOID MmDeletePageTable(PEPROCESS Process, PVOID Address) { PEPROCESS CurrentProcess = PsGetCurrentProcess(); - + if (Process != NULL && Process != CurrentProcess) - { - KeAttachProcess(Process); - } + { + KeAttachProcess(Process); + } *(ADDR_TO_PDE(Address)) = 0; if (Address >= (PVOID)KERNEL_BASE) - { - KEBUGCHECK(0); -// MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] = 0; - } + { + KEBUGCHECK(0); + // MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] = 0; + } FLUSH_TLB; if (Process != NULL && Process != CurrentProcess) - { - KeDetachProcess(); - } + { + KeDetachProcess(); + } } VOID MmFreePageTable(PEPROCESS Process, PVOID Address) @@ -216,7 +218,7 @@ VOID MmFreePageTable(PEPROCESS Process, PVOID Address) PULONG PageTable; ULONG i; ULONG npage; - + if (Process != NULL && Process != CurrentProcess) { KeAttachProcess(Process); @@ -228,8 +230,8 @@ VOID MmFreePageTable(PEPROCESS Process, PVOID Address) if (PageTable[i] != 0) { DbgPrint("Page table entry not clear at %x/%x (is %x)\n", - ((ULONG)Address / 4*1024*1024), i, PageTable[i]); - KEBUGCHECK(0); + ((ULONG)Address / 4*1024*1024), i, PageTable[i]); + KEBUGCHECK(0); } } npage = *(ADDR_TO_PDE(Address)); @@ -238,7 +240,7 @@ VOID MmFreePageTable(PEPROCESS Process, PVOID Address) if (Address >= (PVOID)KERNEL_BASE) { -// MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] = 0; + // MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] = 0; KEBUGCHECK(0); } else @@ -261,53 +263,53 @@ NTSTATUS MmGetPageEntry2(PVOID PAddress, PULONG* Pte, BOOLEAN MayWait) BOOLEAN Free = FALSE; NTSTATUS Status; KIRQL oldIrql; - + DPRINT("MmGetPageEntry(Address %x)\n", PAddress); Pde = ADDR_TO_PDE(PAddress); - if (*Pde == 0) + if (*Pde == 0) { if (PAddress >= (PVOID)KERNEL_BASE) { - kePde = MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(PAddress); + kePde = MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(PAddress); oldIrql = KeRaiseIrqlToSynchLevel(); - if (*kePde != 0) - { - *Pde = *kePde; - FLUSH_TLB; - } + if (*kePde != 0) + { + *Pde = *kePde; + FLUSH_TLB; + } else - { - KeLowerIrql(oldIrql); - Status = MmRequestPageMemoryConsumer(MC_NPPOOL, MayWait, &npage); - if (!NT_SUCCESS(Status)) - { - KEBUGCHECK(0); - } - oldIrql = KeRaiseIrqlToSynchLevel(); - /* An other thread can set this pde entry, we must check again */ - if (*kePde == 0) - { - *kePde = npage.u.LowPart | PA_PRESENT | PA_READWRITE; - } - else - { - Free = TRUE; - } - *Pde = *kePde; - FLUSH_TLB; - } - KeLowerIrql(oldIrql); + { + KeLowerIrql(oldIrql); + Status = MmRequestPageMemoryConsumer(MC_NPPOOL, MayWait, &npage); + if (!NT_SUCCESS(Status)) + { + KEBUGCHECK(0); + } + oldIrql = KeRaiseIrqlToSynchLevel(); + /* An other thread can set this pde entry, we must check again */ + if (*kePde == 0) + { + *kePde = npage.u.LowPart | PA_PRESENT | PA_READWRITE; + } + else + { + Free = TRUE; + } + *Pde = *kePde; + FLUSH_TLB; + } + KeLowerIrql(oldIrql); } else { - Status = MmRequestPageMemoryConsumer(MC_NPPOOL, MayWait, &npage); + Status = MmRequestPageMemoryConsumer(MC_NPPOOL, MayWait, &npage); if (!NT_SUCCESS(Status)) - { - return(Status); - } - *Pde = npage.u.LowPart | PA_PRESENT | PA_READWRITE | PA_USER; - FLUSH_TLB; + { + return(Status); + } + *Pde = npage.u.LowPart | PA_PRESENT | PA_READWRITE | PA_USER; + FLUSH_TLB; } } *Pte = (PULONG)ADDR_TO_PTE(PAddress); @@ -322,16 +324,16 @@ ULONG MmGetPageEntryForProcess(PEPROCESS Process, PVOID Address) { ULONG Entry; PEPROCESS CurrentProcess = PsGetCurrentProcess(); - + if (Process != NULL && Process != CurrentProcess) - { - KeAttachProcess(Process); - } + { + KeAttachProcess(Process); + } Entry = *MmGetPageEntry(Address); if (Process != NULL && Process != CurrentProcess) - { - KeDetachProcess(); - } + { + KeDetachProcess(); + } return(Entry); } @@ -342,22 +344,22 @@ ULONG MmGetPageEntry1(PVOID PAddress) { PULONG Pde, kePde; ULONG Entry = 0; - + DPRINT("MmGetPageEntry(Address %x)\n", PAddress); - + Pde = ADDR_TO_PDE(PAddress); if (*Pde == 0) { - if (PAddress >= (PVOID)KERNEL_BASE) - { - kePde = MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(PAddress); - if (*kePde != 0) - { - *Pde = *kePde; - FLUSH_TLB; - Entry = *(PULONG)ADDR_TO_PTE(PAddress); - } - } + if (PAddress >= (PVOID)KERNEL_BASE) + { + kePde = MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(PAddress); + if (*kePde != 0) + { + *Pde = *kePde; + FLUSH_TLB; + Entry = *(PULONG)ADDR_TO_PTE(PAddress); + } + } } else { @@ -370,39 +372,41 @@ ULONG MmGetPageEntryForProcess1(PEPROCESS Process, PVOID Address) { ULONG Entry; PEPROCESS CurrentProcess = PsGetCurrentProcess(); - + if (Process != NULL && Process != CurrentProcess) - { - KeAttachProcess(Process); - } + { + KeAttachProcess(Process); + } Entry = MmGetPageEntry1(Address); if (Process != NULL && Process != CurrentProcess) - { - KeDetachProcess(); - } + { + KeDetachProcess(); + } return(Entry); } PHYSICAL_ADDRESS MmGetPhysicalAddressForProcess(PEPROCESS Process, - PVOID Address) + PVOID Address) { ULONG PageEntry; - + PageEntry = MmGetPageEntryForProcess(Process, Address); - + if (!(PageEntry & PA_PRESENT)) - { + { #if defined(__GNUC__) - return((LARGE_INTEGER)0LL); + return((LARGE_INTEGER)0LL); #else - { - PHYSICAL_ADDRESS dummy = { 0 }; - return dummy; - } + + { + PHYSICAL_ADDRESS dummy = { 0 }; + return dummy; + } #endif - } + + } return(PTE_TO_PAGE(PageEntry)); } @@ -422,25 +426,25 @@ MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOL* WasDirty, PHYSIC * context. */ if (Process != NULL && Process != CurrentProcess) - { - KeAttachProcess(Process); - } + { + KeAttachProcess(Process); + } /* * Set the page directory entry, we may have to copy the entry from * the global page directory. */ Pde = ADDR_TO_PDE(Address); - if ((*Pde) == 0 && - MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] != 0) - { - (*Pde) = MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)]; - FLUSH_TLB; - } + if ((*Pde) == 0 && + MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] != 0) + { + (*Pde) = MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)]; + FLUSH_TLB; + } if ((*Pde) == 0) - { - KEBUGCHECK(0); - } + { + KEBUGCHECK(0); + } /* * Atomically set the entry to zero and get the old value. @@ -450,30 +454,30 @@ MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOL* WasDirty, PHYSIC FLUSH_TLB; WasValid = (PAGE_MASK(Pte) != 0); if (!WasValid) - { - KEBUGCHECK(0); - } + { + KEBUGCHECK(0); + } /* * If necessary go back to the original context */ if (Process != NULL && Process != CurrentProcess) - { - KeDetachProcess(); - } + { + KeDetachProcess(); + } /* * Return some information to the caller */ if (WasDirty != NULL) - { - *WasDirty = Pte & PA_DIRTY; - } + { + *WasDirty = Pte & PA_DIRTY; + } if (PhysicalAddr != NULL) - { - PhysicalAddr->u.HighPart = 0; - PhysicalAddr->u.LowPart = PAGE_MASK(Pte); - } + { + PhysicalAddr->u.HighPart = 0; + PhysicalAddr->u.LowPart = PAGE_MASK(Pte); + } } VOID @@ -492,14 +496,14 @@ MmRawDeleteVirtualMapping(PVOID Address) if (*kePde != 0) { *Pde = *kePde; - FLUSH_TLB; + FLUSH_TLB; } } - + if (*Pde == 0) - { - return; - } + { + return; + } /* * Set the entry to zero @@ -510,7 +514,7 @@ MmRawDeleteVirtualMapping(PVOID Address) VOID MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage, - BOOL* WasDirty, PHYSICAL_ADDRESS* PhysicalAddr) + BOOL* WasDirty, PHYSICAL_ADDRESS* PhysicalAddr) /* * FUNCTION: Delete a virtual mapping */ @@ -525,9 +529,9 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage, * context. */ if (Process != NULL && Process != CurrentProcess) - { - KeAttachProcess(Process); - } + { + KeAttachProcess(Process); + } /* * Set the page directory entry, we may have to copy the entry from @@ -540,30 +544,32 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage, if (*kePde != 0) { *Pde = *kePde; - FLUSH_TLB; + FLUSH_TLB; } } - + if (*Pde == 0) - { - if (Process != NULL && Process != CurrentProcess) - { - KeDetachProcess(); - } - if (WasDirty != NULL) - { - *WasDirty = FALSE; - } - if (PhysicalAddr != NULL) - { + { + if (Process != NULL && Process != CurrentProcess) + { + KeDetachProcess(); + } + if (WasDirty != NULL) + { + *WasDirty = FALSE; + } + if (PhysicalAddr != NULL) + { #if defined(__GNUC__) - *PhysicalAddr = (LARGE_INTEGER)0LL; + *PhysicalAddr = (LARGE_INTEGER)0LL; #else - PhysicalAddr->QuadPart = 0; + + PhysicalAddr->QuadPart = 0; #endif - } - return; - } + + } + return; + } /* * Atomically set the entry to zero and get the old value. @@ -572,63 +578,63 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage, FLUSH_TLB; WasValid = (PAGE_MASK(Pte) != 0); if (WasValid) - { - MmMarkPageUnmapped(PTE_TO_PAGE(Pte)); - } + { + MmMarkPageUnmapped(PTE_TO_PAGE(Pte)); + } if (FreePage && WasValid) - { - MmReleasePageMemoryConsumer(MC_NPPOOL, PTE_TO_PAGE(Pte)); - } + { + MmReleasePageMemoryConsumer(MC_NPPOOL, PTE_TO_PAGE(Pte)); + } /* * Decrement the reference count for this page table. */ if (Process != NULL && WasValid && - Process->AddressSpace.PageTableRefCountTable != NULL && - Address < (PVOID)KERNEL_BASE) - { - PUSHORT Ptrc; - - Ptrc = Process->AddressSpace.PageTableRefCountTable; - - Ptrc[ADDR_TO_PAGE_TABLE(Address)]--; - if (Ptrc[ADDR_TO_PAGE_TABLE(Address)] == 0) - { - MmFreePageTable(Process, Address); - } - } + Process->AddressSpace.PageTableRefCountTable != NULL && + Address < (PVOID)KERNEL_BASE) + { + PUSHORT Ptrc; + + Ptrc = Process->AddressSpace.PageTableRefCountTable; + + Ptrc[ADDR_TO_PAGE_TABLE(Address)]--; + if (Ptrc[ADDR_TO_PAGE_TABLE(Address)] == 0) + { + MmFreePageTable(Process, Address); + } + } /* * If necessary go back to the original context */ if (Process != NULL && Process != CurrentProcess) - { - KeDetachProcess(); - } + { + KeDetachProcess(); + } /* * Return some information to the caller */ if (WasDirty != NULL) - { - if (Pte & PA_DIRTY) - { - *WasDirty = TRUE; - } - else - { - *WasDirty = FALSE; - } - } + { + if (Pte & PA_DIRTY) + { + *WasDirty = TRUE; + } + else + { + *WasDirty = FALSE; + } + } if (PhysicalAddr != NULL) - { - *PhysicalAddr = PTE_TO_PAGE(Pte); - } + { + *PhysicalAddr = PTE_TO_PAGE(Pte); + } } VOID -MmDeletePageFileMapping(PEPROCESS Process, PVOID Address, - SWAPENTRY* SwapEntry) +MmDeletePageFileMapping(PEPROCESS Process, PVOID Address, + SWAPENTRY* SwapEntry) /* * FUNCTION: Delete a virtual mapping */ @@ -643,9 +649,9 @@ MmDeletePageFileMapping(PEPROCESS Process, PVOID Address, * context. */ if (Process != NULL && Process != CurrentProcess) - { - KeAttachProcess(Process); - } + { + KeAttachProcess(Process); + } /* * Set the page directory entry, we may have to copy the entry from @@ -657,22 +663,22 @@ MmDeletePageFileMapping(PEPROCESS Process, PVOID Address, if (Address >= (PVOID)KERNEL_BASE) { kePde = MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(Address); - if (*kePde != 0) - { - *Pde = *kePde; - FLUSH_TLB; - } + if (*kePde != 0) + { + *Pde = *kePde; + FLUSH_TLB; + } } } if (*Pde == 0) - { - if (Process != NULL && Process != CurrentProcess) - { - KeDetachProcess(); - } - *SwapEntry = 0; - return; - } + { + if (Process != NULL && Process != CurrentProcess) + { + KeDetachProcess(); + } + *SwapEntry = 0; + return; + } /* * Atomically set the entry to zero and get the old value. @@ -686,27 +692,27 @@ MmDeletePageFileMapping(PEPROCESS Process, PVOID Address, * Decrement the reference count for this page table. */ if (Process != NULL && WasValid && - Process->AddressSpace.PageTableRefCountTable != NULL && - Address < (PVOID)KERNEL_BASE) - { - PUSHORT Ptrc; - - Ptrc = Process->AddressSpace.PageTableRefCountTable; - - Ptrc[ADDR_TO_PAGE_TABLE(Address)]--; - if (Ptrc[ADDR_TO_PAGE_TABLE(Address)] == 0) - { - MmFreePageTable(Process, Address); - } - } + Process->AddressSpace.PageTableRefCountTable != NULL && + Address < (PVOID)KERNEL_BASE) + { + PUSHORT Ptrc; + + Ptrc = Process->AddressSpace.PageTableRefCountTable; + + Ptrc[ADDR_TO_PAGE_TABLE(Address)]--; + if (Ptrc[ADDR_TO_PAGE_TABLE(Address)] == 0) + { + MmFreePageTable(Process, Address); + } + } /* * If necessary go back to the original context */ if (Process != NULL && Process != CurrentProcess) - { - KeDetachProcess(); - } + { + KeDetachProcess(); + } /* * Return some information to the caller @@ -714,11 +720,11 @@ MmDeletePageFileMapping(PEPROCESS Process, PVOID Address, *SwapEntry = Pte >> 1; } -BOOLEAN +BOOLEAN Mmi386MakeKernelPageTableGlobal(PVOID PAddress) { PULONG kePde, Pde; - + Pde = ADDR_TO_PDE(PAddress); if (*Pde == 0) { @@ -726,7 +732,7 @@ Mmi386MakeKernelPageTableGlobal(PVOID PAddress) if (*kePde != 0) { *Pde = *kePde; - FLUSH_TLB; + FLUSH_TLB; return(TRUE); } } @@ -736,7 +742,7 @@ Mmi386MakeKernelPageTableGlobal(PVOID PAddress) BOOLEAN MmIsPageTablePresent(PVOID PAddress) { PULONG Pde, kePde; - + Pde = ADDR_TO_PDE(PAddress); if (*Pde == 0) { @@ -744,8 +750,8 @@ BOOLEAN MmIsPageTablePresent(PVOID PAddress) if (*kePde != 0) { *Pde = *kePde; - FLUSH_TLB; - return TRUE; + FLUSH_TLB; + return TRUE; } } return FALSE; @@ -756,9 +762,9 @@ NTSTATUS MmCreatePageTable(PVOID PAddress) PULONG Pde, kePde; PHYSICAL_ADDRESS npage; NTSTATUS Status; - + DPRINT("MmGetPageEntry(Address %x)\n", PAddress); - + Pde = ADDR_TO_PDE(PAddress); DPRINT("page_dir %x *page_dir %x\n", Pde, *Pde); if (*Pde == 0 && PAddress >= (PVOID)KERNEL_BASE) @@ -766,9 +772,9 @@ NTSTATUS MmCreatePageTable(PVOID PAddress) kePde = MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(PAddress); if (*kePde != 0) { - *Pde = *kePde; - FLUSH_TLB; - return STATUS_SUCCESS; + *Pde = *kePde; + FLUSH_TLB; + return STATUS_SUCCESS; } /* Should we create a kernel page table? */ DPRINT1("!!!!!!!!!!!!!!!!!!\n"); @@ -799,60 +805,60 @@ PULONG MmGetPageEntry(PVOID PAddress) KIRQL oldIrql; BOOLEAN Free = FALSE; NTSTATUS Status; - + DPRINT("MmGetPageEntry(Address %x)\n", PAddress); - + Pde = ADDR_TO_PDE(PAddress); DPRINT("page_dir %x *page_dir %x\n",Pde,*Pde); if (*Pde == 0) { if (PAddress >= (PVOID)KERNEL_BASE) { - oldIrql = KeRaiseIrqlToSynchLevel(); - kePde = MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(PAddress); - if (*kePde != 0) - { - *Pde = *kePde; - FLUSH_TLB; - } - else - { - KeLowerIrql(oldIrql); - Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &npage); + oldIrql = KeRaiseIrqlToSynchLevel(); + kePde = MmGlobalKernelPageDirectory + ADDR_TO_PDE_OFFSET(PAddress); + if (*kePde != 0) + { + *Pde = *kePde; + FLUSH_TLB; + } + else + { + KeLowerIrql(oldIrql); + Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &npage); if (!NT_SUCCESS(Status)) - { - KEBUGCHECK(0); - } - MiZeroPage(npage); - oldIrql = KeRaiseIrqlToSynchLevel(); - if (*kePde != 0) - { - *Pde = *kePde; - FLUSH_TLB; - Free = TRUE; - } - else - { + { + KEBUGCHECK(0); + } + MiZeroPage(npage); + oldIrql = KeRaiseIrqlToSynchLevel(); + if (*kePde != 0) + { + *Pde = *kePde; + FLUSH_TLB; + Free = TRUE; + } + else + { *Pde = *kePde = npage.u.LowPart | PA_PRESENT | PA_READWRITE; - FLUSH_TLB; - } - } - KeLowerIrql(oldIrql); + FLUSH_TLB; + } + } + KeLowerIrql(oldIrql); } else { - Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &npage); + Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &npage); if (!NT_SUCCESS(Status)) - { - KEBUGCHECK(0); - } - MiZeroPage(npage); - *Pde = npage.u.LowPart | PA_PRESENT | PA_READWRITE | PA_USER; - FLUSH_TLB; + { + KEBUGCHECK(0); + } + MiZeroPage(npage); + *Pde = npage.u.LowPart | PA_PRESENT | PA_READWRITE | PA_USER; + FLUSH_TLB; } if (Free) { - MmReleasePageMemoryConsumer(MC_NPPOOL, npage); + MmReleasePageMemoryConsumer(MC_NPPOOL, npage); } } @@ -864,7 +870,7 @@ BOOLEAN MmIsDirtyPage(PEPROCESS Process, PVOID Address) return (BOOLEAN)((MmGetPageEntryForProcess(Process, Address)) & PA_DIRTY); } -BOOLEAN +BOOLEAN MmIsAccessedAndResetAccessPage(PEPROCESS Process, PVOID Address) { PULONG PageEntry; @@ -872,34 +878,34 @@ MmIsAccessedAndResetAccessPage(PEPROCESS Process, PVOID Address) BOOLEAN Accessed; if (Process) - { - CurrentProcess = PsGetCurrentProcess(); - if (Process != CurrentProcess) - { - KeAttachProcess(Process); - } - } - else - { - if (((ULONG)Address & ~0xFFF) < KERNEL_BASE) - { - DPRINT1("MmIsAccessedAndResetAccessPage is called for user space without a process.\n"); - KEBUGCHECK(0); - } - CurrentProcess = NULL; - } + { + CurrentProcess = PsGetCurrentProcess(); + if (Process != CurrentProcess) + { + KeAttachProcess(Process); + } + } + else + { + if (((ULONG)Address & ~0xFFF) < KERNEL_BASE) + { + DPRINT1("MmIsAccessedAndResetAccessPage is called for user space without a process.\n"); + KEBUGCHECK(0); + } + CurrentProcess = NULL; + } PageEntry = MmGetPageEntry(Address); Accessed = (BOOLEAN)((*PageEntry) & PA_ACCESSED); if (Accessed) - { - (*PageEntry) = (*PageEntry) & (~PA_ACCESSED); - FLUSH_TLB; - } + { + (*PageEntry) = (*PageEntry) & (~PA_ACCESSED); + FLUSH_TLB; + } if (Process != CurrentProcess) - { - KeDetachProcess(); - } + { + KeDetachProcess(); + } return(Accessed); } @@ -910,29 +916,29 @@ VOID MmSetCleanPage(PEPROCESS Process, PVOID Address) PEPROCESS CurrentProcess; if (Process) - { - CurrentProcess = PsGetCurrentProcess(); - if (Process != CurrentProcess) - { - KeAttachProcess(Process); - } - } - else - { - if (((ULONG)Address & ~0xFFF) < KERNEL_BASE) - { - DPRINT1("MmSetCleanPage is called for user space without a process.\n"); - KEBUGCHECK(0); - } - CurrentProcess = NULL; - } + { + CurrentProcess = PsGetCurrentProcess(); + if (Process != CurrentProcess) + { + KeAttachProcess(Process); + } + } + else + { + if (((ULONG)Address & ~0xFFF) < KERNEL_BASE) + { + DPRINT1("MmSetCleanPage is called for user space without a process.\n"); + KEBUGCHECK(0); + } + CurrentProcess = NULL; + } PageEntry = MmGetPageEntry(Address); (*PageEntry) = (*PageEntry) & (~PA_DIRTY); FLUSH_TLB; if (Process != CurrentProcess) - { - KeDetachProcess(); - } + { + KeDetachProcess(); + } } VOID MmSetDirtyPage(PEPROCESS Process, PVOID Address) @@ -941,47 +947,47 @@ VOID MmSetDirtyPage(PEPROCESS Process, PVOID Address) PEPROCESS CurrentProcess = NULL; if (Process) - { - CurrentProcess = PsGetCurrentProcess(); - if (Process != CurrentProcess) - { - KeAttachProcess(Process); - } - } - else - { - if (((ULONG)Address & ~0xFFF) < KERNEL_BASE) - { - DPRINT1("MmSetDirtyPage is called for user space without a process.\n"); - KEBUGCHECK(0); - } - CurrentProcess = NULL; - } + { + CurrentProcess = PsGetCurrentProcess(); + if (Process != CurrentProcess) + { + KeAttachProcess(Process); + } + } + else + { + if (((ULONG)Address & ~0xFFF) < KERNEL_BASE) + { + DPRINT1("MmSetDirtyPage is called for user space without a process.\n"); + KEBUGCHECK(0); + } + CurrentProcess = NULL; + } PageEntry = MmGetPageEntry(Address); (*PageEntry) = (*PageEntry) | PA_DIRTY; FLUSH_TLB; if (Process != CurrentProcess) - { - KeDetachProcess(); - } + { + KeDetachProcess(); + } } VOID MmEnableVirtualMapping(PEPROCESS Process, PVOID Address) { PULONG PageEntry; PEPROCESS CurrentProcess = PsGetCurrentProcess(); - + if (Process != CurrentProcess) - { - KeAttachProcess(Process); - } + { + KeAttachProcess(Process); + } PageEntry = MmGetPageEntry(Address); (*PageEntry) = (*PageEntry) | PA_PRESENT; FLUSH_TLB; if (Process != CurrentProcess) - { - KeDetachProcess(); - } + { + KeDetachProcess(); + } } BOOLEAN MmIsPagePresent(PEPROCESS Process, PVOID Address) @@ -991,324 +997,324 @@ BOOLEAN MmIsPagePresent(PEPROCESS Process, PVOID Address) BOOLEAN MmIsPageSwapEntry(PEPROCESS Process, PVOID Address) { - ULONG Pte; - Pte = MmGetPageEntryForProcess1(Process, Address); - return((!(Pte & PA_PRESENT)) && Pte != 0); + ULONG Pte; + Pte = MmGetPageEntryForProcess1(Process, Address); + return((!(Pte & PA_PRESENT)) && Pte != 0); } -NTSTATUS -MmCreateVirtualMappingDump(PVOID Address, - ULONG flProtect, - PHYSICAL_ADDRESS PhysicalAddress) +NTSTATUS +MmCreateVirtualMappingDump(PVOID Address, + ULONG flProtect, + PHYSICAL_ADDRESS PhysicalAddress) { ULONG Attributes; PULONG Pte; NTSTATUS Status; if (Address < (PVOID)KERNEL_BASE) - { - DPRINT1("No process\n"); - KEBUGCHECK(0); - } - - Attributes = ProtectToPTE(flProtect); - if (!(Attributes & PA_PRESENT) && PhysicalAddress.QuadPart != 0) - { - DPRINT1("Setting physical address but not allowing access at address " - "0x%.8X with attributes %x/%x.\n", - Address, Attributes, flProtect); - KEBUGCHECK(0); - } - - Status = MmGetPageEntry2(Address, &Pte, FALSE); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - if (PAGE_MASK((*Pte)) != 0 && !((*Pte) & PA_PRESENT)) - { - KEBUGCHECK(0); - } - *Pte = (ULONG)(PhysicalAddress.QuadPart | Attributes); - FLUSH_TLB; - return(STATUS_SUCCESS); -} - - -NTSTATUS -MmCreateVirtualMappingForKernel(PVOID Address, - ULONG flProtect, - PHYSICAL_ADDRESS PhysicalAddress) -{ - PEPROCESS CurrentProcess; - ULONG Attributes; - PULONG Pte; - NTSTATUS Status; - PEPROCESS Process = NULL; - - if (Process != NULL) - { - CurrentProcess = PsGetCurrentProcess(); - } - else - { - CurrentProcess = NULL; - } - - if (Process == NULL && Address < (PVOID)KERNEL_BASE) - { - DPRINT1("No process\n"); - KEBUGCHECK(0); - } - if (Process != NULL && Address >= (PVOID)KERNEL_BASE) - { - DPRINT1("Setting kernel address with process context\n"); - KEBUGCHECK(0); - } - Attributes = ProtectToPTE(flProtect); - - if (Process != NULL && Process != CurrentProcess) - { - KeAttachProcess(Process); - } - - Status = MmGetPageEntry2(Address, &Pte, FALSE); - if (!NT_SUCCESS(Status)) - { - if (Process != NULL && Process != CurrentProcess) - { - KeDetachProcess(); - } - return(Status); - } - if (PAGE_MASK((*Pte)) != 0 && !((*Pte) & PA_PRESENT)) - { - KEBUGCHECK(0); - } - if (PAGE_MASK((*Pte)) != 0) - { - MmMarkPageUnmapped(PTE_TO_PAGE((*Pte))); - } - *Pte = (ULONG)(PhysicalAddress.QuadPart | Attributes); - if (Process != NULL && - Process->AddressSpace.PageTableRefCountTable != NULL && - Address < (PVOID)KERNEL_BASE && - Attributes & PA_PRESENT) - { - PUSHORT Ptrc; - - Ptrc = Process->AddressSpace.PageTableRefCountTable; - - Ptrc[ADDR_TO_PAGE_TABLE(Address)]++; - } - FLUSH_TLB; - if (Process != NULL && Process != CurrentProcess) - { - KeDetachProcess(); - } - return(STATUS_SUCCESS); -} - -NTSTATUS -MmCreatePageFileMapping(PEPROCESS Process, - PVOID Address, - SWAPENTRY SwapEntry) -{ - PEPROCESS CurrentProcess; - PULONG Pte; - NTSTATUS Status; - - if (Process != NULL) - { - CurrentProcess = PsGetCurrentProcess(); - } - else - { - CurrentProcess = NULL; - } - - if (Process == NULL && Address < (PVOID)KERNEL_BASE) - { + { DPRINT1("No process\n"); KEBUGCHECK(0); - } - if (Process != NULL && Address >= (PVOID)KERNEL_BASE) - { + } + + Attributes = ProtectToPTE(flProtect); + if (!(Attributes & PA_PRESENT) && PhysicalAddress.QuadPart != 0) + { + DPRINT1("Setting physical address but not allowing access at address " + "0x%.8X with attributes %x/%x.\n", + Address, Attributes, flProtect); + KEBUGCHECK(0); + } + + Status = MmGetPageEntry2(Address, &Pte, FALSE); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + if (PAGE_MASK((*Pte)) != 0 && !((*Pte) & PA_PRESENT)) + { + KEBUGCHECK(0); + } + *Pte = (ULONG)(PhysicalAddress.QuadPart | Attributes); + FLUSH_TLB; + return(STATUS_SUCCESS); +} + + +NTSTATUS +MmCreateVirtualMappingForKernel(PVOID Address, + ULONG flProtect, + PHYSICAL_ADDRESS PhysicalAddress) +{ + PEPROCESS CurrentProcess; + ULONG Attributes; + PULONG Pte; + NTSTATUS Status; + PEPROCESS Process = NULL; + + if (Process != NULL) + { + CurrentProcess = PsGetCurrentProcess(); + } + else + { + CurrentProcess = NULL; + } + + if (Process == NULL && Address < (PVOID)KERNEL_BASE) + { + DPRINT1("No process\n"); + KEBUGCHECK(0); + } + if (Process != NULL && Address >= (PVOID)KERNEL_BASE) + { DPRINT1("Setting kernel address with process context\n"); KEBUGCHECK(0); - } - if (SwapEntry & (1 << 31)) - { - KEBUGCHECK(0); - } + } + Attributes = ProtectToPTE(flProtect); - if (Process != NULL && Process != CurrentProcess) - { - KeAttachProcess(Process); - } - - Status = MmGetPageEntry2(Address, &Pte, FALSE); - if (!NT_SUCCESS(Status)) - { - if (Process != NULL && Process != CurrentProcess) - { - KeDetachProcess(); - } - return(Status); - } - if (PAGE_MASK((*Pte)) != 0) - { + if (Process != NULL && Process != CurrentProcess) + { + KeAttachProcess(Process); + } + + Status = MmGetPageEntry2(Address, &Pte, FALSE); + if (!NT_SUCCESS(Status)) + { + if (Process != NULL && Process != CurrentProcess) + { + KeDetachProcess(); + } + return(Status); + } + if (PAGE_MASK((*Pte)) != 0 && !((*Pte) & PA_PRESENT)) + { + KEBUGCHECK(0); + } + if (PAGE_MASK((*Pte)) != 0) + { MmMarkPageUnmapped(PTE_TO_PAGE((*Pte))); - } - *Pte = SwapEntry << 1; - if (Process != NULL && - Process->AddressSpace.PageTableRefCountTable != NULL && - Address < (PVOID)KERNEL_BASE) - { + } + *Pte = (ULONG)(PhysicalAddress.QuadPart | Attributes); + if (Process != NULL && + Process->AddressSpace.PageTableRefCountTable != NULL && + Address < (PVOID)KERNEL_BASE && + Attributes & PA_PRESENT) + { PUSHORT Ptrc; - + Ptrc = Process->AddressSpace.PageTableRefCountTable; - + Ptrc[ADDR_TO_PAGE_TABLE(Address)]++; - } - FLUSH_TLB; - if (Process != NULL && Process != CurrentProcess) - { + } + FLUSH_TLB; + if (Process != NULL && Process != CurrentProcess) + { KeDetachProcess(); - } - return(STATUS_SUCCESS); + } + return(STATUS_SUCCESS); +} + +NTSTATUS +MmCreatePageFileMapping(PEPROCESS Process, + PVOID Address, + SWAPENTRY SwapEntry) +{ + PEPROCESS CurrentProcess; + PULONG Pte; + NTSTATUS Status; + + if (Process != NULL) + { + CurrentProcess = PsGetCurrentProcess(); + } + else + { + CurrentProcess = NULL; + } + + if (Process == NULL && Address < (PVOID)KERNEL_BASE) + { + DPRINT1("No process\n"); + KEBUGCHECK(0); + } + if (Process != NULL && Address >= (PVOID)KERNEL_BASE) + { + DPRINT1("Setting kernel address with process context\n"); + KEBUGCHECK(0); + } + if (SwapEntry & (1 << 31)) + { + KEBUGCHECK(0); + } + + if (Process != NULL && Process != CurrentProcess) + { + KeAttachProcess(Process); + } + + Status = MmGetPageEntry2(Address, &Pte, FALSE); + if (!NT_SUCCESS(Status)) + { + if (Process != NULL && Process != CurrentProcess) + { + KeDetachProcess(); + } + return(Status); + } + if (PAGE_MASK((*Pte)) != 0) + { + MmMarkPageUnmapped(PTE_TO_PAGE((*Pte))); + } + *Pte = SwapEntry << 1; + if (Process != NULL && + Process->AddressSpace.PageTableRefCountTable != NULL && + Address < (PVOID)KERNEL_BASE) + { + PUSHORT Ptrc; + + Ptrc = Process->AddressSpace.PageTableRefCountTable; + + Ptrc[ADDR_TO_PAGE_TABLE(Address)]++; + } + FLUSH_TLB; + if (Process != NULL && Process != CurrentProcess) + { + KeDetachProcess(); + } + return(STATUS_SUCCESS); } -NTSTATUS +NTSTATUS MmCreateVirtualMappingUnsafe(PEPROCESS Process, - PVOID Address, - ULONG flProtect, - PHYSICAL_ADDRESS PhysicalAddress, - BOOLEAN MayWait) + PVOID Address, + ULONG flProtect, + PHYSICAL_ADDRESS PhysicalAddress, + BOOLEAN MayWait) { PEPROCESS CurrentProcess; ULONG Attributes; PULONG Pte; NTSTATUS Status; - if (Process != NULL) - { + if (Process != NULL) + { CurrentProcess = PsGetCurrentProcess(); - } - else - { + } + else + { CurrentProcess = NULL; - } - + } + if (Process == NULL && Address < (PVOID)KERNEL_BASE) - { - DPRINT1("No process\n"); - KEBUGCHECK(0); - } + { + DPRINT1("No process\n"); + KEBUGCHECK(0); + } if (Process != NULL && Address >= (PVOID)KERNEL_BASE) - { - DPRINT1("Setting kernel address with process context\n"); - KEBUGCHECK(0); - } + { + DPRINT1("Setting kernel address with process context\n"); + KEBUGCHECK(0); + } MmMarkPageMapped(PhysicalAddress); - + Attributes = ProtectToPTE(flProtect); if (!(Attributes & PA_PRESENT) && PhysicalAddress.QuadPart != 0) - { - DPRINT1("Setting physical address but not allowing access at address " - "0x%.8X with attributes %x/%x.\n", - Address, Attributes, flProtect); - KEBUGCHECK(0); - } - + { + DPRINT1("Setting physical address but not allowing access at address " + "0x%.8X with attributes %x/%x.\n", + Address, Attributes, flProtect); + KEBUGCHECK(0); + } + if (Process != NULL && Process != CurrentProcess) - { - KeAttachProcess(Process); - } - + { + KeAttachProcess(Process); + } + Status = MmGetPageEntry2(Address, &Pte, MayWait); if (!NT_SUCCESS(Status)) - { - if (Process != NULL && Process != CurrentProcess) - { - KeDetachProcess(); - } - return(Status); - } + { + if (Process != NULL && Process != CurrentProcess) + { + KeDetachProcess(); + } + return(Status); + } if (PAGE_MASK((*Pte)) != 0 && !((*Pte) & PA_PRESENT)) - { - KEBUGCHECK(0); - } + { + KEBUGCHECK(0); + } if (PAGE_MASK((*Pte)) != 0) - { - MmMarkPageUnmapped(PTE_TO_PAGE((*Pte))); - } + { + MmMarkPageUnmapped(PTE_TO_PAGE((*Pte))); + } *Pte = (ULONG)(PhysicalAddress.QuadPart | Attributes); - if (Process != NULL && - Process->AddressSpace.PageTableRefCountTable != NULL && - Address < (PVOID)KERNEL_BASE && - Attributes & PA_PRESENT) - { - PUSHORT Ptrc; - - Ptrc = Process->AddressSpace.PageTableRefCountTable; - - Ptrc[ADDR_TO_PAGE_TABLE(Address)]++; - } + if (Process != NULL && + Process->AddressSpace.PageTableRefCountTable != NULL && + Address < (PVOID)KERNEL_BASE && + Attributes & PA_PRESENT) + { + PUSHORT Ptrc; + + Ptrc = Process->AddressSpace.PageTableRefCountTable; + + Ptrc[ADDR_TO_PAGE_TABLE(Address)]++; + } FLUSH_TLB; if (Process != NULL && Process != CurrentProcess) - { - KeDetachProcess(); - } + { + KeDetachProcess(); + } return(STATUS_SUCCESS); } -NTSTATUS +NTSTATUS MmCreateVirtualMapping(PEPROCESS Process, - PVOID Address, - ULONG flProtect, - PHYSICAL_ADDRESS PhysicalAddress, - BOOLEAN MayWait) + PVOID Address, + ULONG flProtect, + PHYSICAL_ADDRESS PhysicalAddress, + BOOLEAN MayWait) { - if (!MmIsUsablePage(PhysicalAddress)) - { + if (!MmIsUsablePage(PhysicalAddress)) + { DPRINT1("Page at address %x not usable\n", PhysicalAddress); KEBUGCHECK(0); - } - - return(MmCreateVirtualMappingUnsafe(Process, - Address, - flProtect, - PhysicalAddress, - MayWait)); + } + + return(MmCreateVirtualMappingUnsafe(Process, + Address, + flProtect, + PhysicalAddress, + MayWait)); } ULONG MmGetPageProtect(PEPROCESS Process, PVOID Address) { - ULONG Entry; - ULONG Protect; + ULONG Entry; + ULONG Protect; - Entry = MmGetPageEntryForProcess1(Process, Address); + Entry = MmGetPageEntryForProcess1(Process, Address); - if (!(Entry & PA_PRESENT)) - { + if (!(Entry & PA_PRESENT)) + { Protect = PAGE_NOACCESS; - } - else if (Entry & PA_READWRITE) - { + } + else if (Entry & PA_READWRITE) + { Protect = PAGE_READWRITE; - } - else - { + } + else + { Protect = PAGE_EXECUTE_READ; - } - return(Protect); + } + return(Protect); } -VOID +VOID MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect) { ULONG Attributes = 0; @@ -1316,26 +1322,26 @@ MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect) PEPROCESS CurrentProcess = PsGetCurrentProcess(); DPRINT("MmSetPageProtect(Process %x Address %x flProtect %x)\n", - Process, Address, flProtect); + Process, Address, flProtect); Attributes = ProtectToPTE(flProtect); if (Process != NULL && Process != CurrentProcess) - { - KeAttachProcess(Process); - } + { + KeAttachProcess(Process); + } PageEntry = MmGetPageEntry(Address); (*PageEntry) = PAGE_MASK(*PageEntry) | Attributes; FLUSH_TLB; if (Process != NULL && Process != CurrentProcess) - { - KeDetachProcess(); - } + { + KeDetachProcess(); + } } /* * @implemented */ -PHYSICAL_ADDRESS STDCALL +PHYSICAL_ADDRESS STDCALL MmGetPhysicalAddress(PVOID vaddr) /* * FUNCTION: Returns the physical address corresponding to a virtual address @@ -1348,14 +1354,14 @@ MmGetPhysicalAddress(PVOID vaddr) Pte = *MmGetPageEntry(vaddr); if (Pte & PA_PRESENT) - { - p.QuadPart = PAGE_MASK(Pte); - } + { + p.QuadPart = PAGE_MASK(Pte); + } else - { - p.QuadPart = 0; - } - + { + p.QuadPart = 0; + } + return p; } @@ -1363,33 +1369,33 @@ MmGetPhysicalAddress(PVOID vaddr) VOID MmUpdateStackPageDir(PULONG LocalPageDir, PKTHREAD PThread) { - unsigned EntryBase = ADDR_TO_PDE_OFFSET(PThread->StackLimit); - unsigned EntryTop = ADDR_TO_PDE_OFFSET((char*)PThread->InitialStack - PAGE_SIZE); + unsigned EntryBase = ADDR_TO_PDE_OFFSET(PThread->StackLimit); + unsigned EntryTop = ADDR_TO_PDE_OFFSET((char*)PThread->InitialStack - PAGE_SIZE); - if (0 == LocalPageDir[EntryBase]) - { + if (0 == LocalPageDir[EntryBase]) + { LocalPageDir[EntryBase] = MmGlobalKernelPageDirectory[EntryBase]; - } - if (EntryBase != EntryTop && 0 == LocalPageDir[EntryTop]) - { + } + if (EntryBase != EntryTop && 0 == LocalPageDir[EntryTop]) + { LocalPageDir[EntryTop] = MmGlobalKernelPageDirectory[EntryTop]; - } + } } VOID INIT_FUNCTION MmInitGlobalKernelPageDirectory(VOID) { - ULONG i; - PULONG CurrentPageDirectory = (PULONG)PAGEDIRECTORY_MAP; + ULONG i; + PULONG CurrentPageDirectory = (PULONG)PAGEDIRECTORY_MAP; - for (i = ADDR_TO_PDE_OFFSET(KERNEL_BASE); i < 1024; i++) - { - if (i != ADDR_TO_PDE_OFFSET(PAGETABLE_MAP) && - 0 == MmGlobalKernelPageDirectory[i] && 0 != CurrentPageDirectory[i]) - { - MmGlobalKernelPageDirectory[i] = CurrentPageDirectory[i]; - } - } + for (i = ADDR_TO_PDE_OFFSET(KERNEL_BASE); i < 1024; i++) + { + if (i != ADDR_TO_PDE_OFFSET(PAGETABLE_MAP) && + 0 == MmGlobalKernelPageDirectory[i] && 0 != CurrentPageDirectory[i]) + { + MmGlobalKernelPageDirectory[i] = CurrentPageDirectory[i]; + } + } } /* EOF */ diff --git a/reactos/ntoskrnl/mm/i386/pfault.c b/reactos/ntoskrnl/mm/i386/pfault.c index fe09febff12..12b27f5cf38 100644 --- a/reactos/ntoskrnl/mm/i386/pfault.c +++ b/reactos/ntoskrnl/mm/i386/pfault.c @@ -28,68 +28,68 @@ extern VOID MmSafeCopyToUserRestart(VOID); extern ULONG MmGlobalKernelPageDirectory[1024]; -BOOLEAN +BOOLEAN Mmi386MakeKernelPageTableGlobal(PVOID Address); /* FUNCTIONS *****************************************************************/ NTSTATUS MmPageFault(ULONG Cs, - PULONG Eip, - PULONG Eax, - ULONG Cr2, - ULONG ErrorCode) + PULONG Eip, + PULONG Eax, + ULONG Cr2, + ULONG ErrorCode) { KPROCESSOR_MODE Mode; NTSTATUS Status; - + DPRINT("MmPageFault(Eip %x, Cr2 %x, ErrorCode %x)\n", - Eip, Cr2, ErrorCode); - + Eip, Cr2, ErrorCode); + if (ErrorCode & 0x4) - { - Mode = UserMode; - } + { + Mode = UserMode; + } else - { - Mode = KernelMode; - } - - if (Mode == KernelMode && Cr2 >= KERNEL_BASE && - Mmi386MakeKernelPageTableGlobal((PVOID)Cr2)) - { - return(STATUS_SUCCESS); - } + { + Mode = KernelMode; + } + + if (Mode == KernelMode && Cr2 >= KERNEL_BASE && + Mmi386MakeKernelPageTableGlobal((PVOID)Cr2)) + { + return(STATUS_SUCCESS); + } if (ErrorCode & 0x1) - { - Status = MmAccessFault(Mode, Cr2, FALSE); - } + { + Status = MmAccessFault(Mode, Cr2, FALSE); + } else - { - Status = MmNotPresentFault(Mode, Cr2, FALSE); - } - + { + Status = MmNotPresentFault(Mode, Cr2, FALSE); + } + if (KeGetCurrentThread() != NULL && - KeGetCurrentThread()->Alerted[1] != 0 && - Cs != KERNEL_CS) - { - KiDeliverNormalApc(); - } + KeGetCurrentThread()->Alerted[1] != 0 && + Cs != KERNEL_CS) + { + KiDeliverNormalApc(); + } if (!NT_SUCCESS(Status) && (Mode == KernelMode) && - ((*Eip) >= (ULONG)MmSafeCopyFromUserUnsafeStart) && - ((*Eip) <= (ULONG)MmSafeCopyFromUserRestart)) - { - (*Eip) = (ULONG)MmSafeCopyFromUserRestart; - (*Eax) = STATUS_ACCESS_VIOLATION; - return(STATUS_SUCCESS); - } + ((*Eip) >= (ULONG)MmSafeCopyFromUserUnsafeStart) && + ((*Eip) <= (ULONG)MmSafeCopyFromUserRestart)) + { + (*Eip) = (ULONG)MmSafeCopyFromUserRestart; + (*Eax) = STATUS_ACCESS_VIOLATION; + return(STATUS_SUCCESS); + } if (!NT_SUCCESS(Status) && (Mode == KernelMode) && - ((*Eip) >= (ULONG)MmSafeCopyToUserUnsafeStart) && - ((*Eip) <= (ULONG)MmSafeCopyToUserRestart)) - { - (*Eip) = (ULONG)MmSafeCopyToUserRestart; - (*Eax) = STATUS_ACCESS_VIOLATION; - return(STATUS_SUCCESS); - } + ((*Eip) >= (ULONG)MmSafeCopyToUserUnsafeStart) && + ((*Eip) <= (ULONG)MmSafeCopyToUserRestart)) + { + (*Eip) = (ULONG)MmSafeCopyToUserRestart; + (*Eax) = STATUS_ACCESS_VIOLATION; + return(STATUS_SUCCESS); + } return(Status); } diff --git a/reactos/ntoskrnl/mm/iospace.c b/reactos/ntoskrnl/mm/iospace.c index 78e0400967d..18ab3e919ca 100644 --- a/reactos/ntoskrnl/mm/iospace.c +++ b/reactos/ntoskrnl/mm/iospace.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: iospace.c,v 1.25 2004/01/09 22:52:30 gvg Exp $ +/* $Id: iospace.c,v 1.26 2004/04/10 22:35:25 gdalsnes Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/mm/iospace.c @@ -38,37 +38,37 @@ /* FUNCTIONS *****************************************************************/ /********************************************************************** - * NAME EXPORTED - * MmMapIoSpace@16 + * NAME EXPORTED + * MmMapIoSpace@16 * * DESCRIPTION - * Maps a physical memory range into system space. - * + * Maps a physical memory range into system space. + * * ARGUMENTS - * PhysicalAddress - * First physical address to map; - * - * NumberOfBytes - * Number of bytes to map; - * - * CacheEnable - * TRUE if the range can be cached. + * PhysicalAddress + * First physical address to map; + * + * NumberOfBytes + * Number of bytes to map; + * + * CacheEnable + * TRUE if the range can be cached. * * RETURN VALUE - * The base virtual address which maps the region. + * The base virtual address which maps the region. * * NOTE - * Description moved here from include/ddk/mmfuncs.h. - * Code taken from ntoskrnl/mm/special.c. + * Description moved here from include/ddk/mmfuncs.h. + * Code taken from ntoskrnl/mm/special.c. * * REVISIONS * * @implemented */ -PVOID STDCALL +PVOID STDCALL MmMapIoSpace (IN PHYSICAL_ADDRESS PhysicalAddress, - IN ULONG NumberOfBytes, - IN BOOLEAN CacheEnable) + IN ULONG NumberOfBytes, + IN BOOLEAN CacheEnable) { PVOID Result; MEMORY_AREA* marea; @@ -83,110 +83,113 @@ MmMapIoSpace (IN PHYSICAL_ADDRESS PhysicalAddress, MmLockAddressSpace(MmGetKernelAddressSpace()); Result = NULL; Status = MmCreateMemoryArea (NULL, - MmGetKernelAddressSpace(), - MEMORY_AREA_IO_MAPPING, - &Result, - NumberOfBytes, - 0, - &marea, - FALSE, - FALSE, - BoundaryAddressMultiple); + MmGetKernelAddressSpace(), + MEMORY_AREA_IO_MAPPING, + &Result, + NumberOfBytes, + 0, + &marea, + FALSE, + FALSE, + BoundaryAddressMultiple); MmUnlockAddressSpace(MmGetKernelAddressSpace()); if (!NT_SUCCESS(Status)) - { - DPRINT("MmMapIoSpace failed (%lx)\n", Status); - return (NULL); - } + { + DPRINT("MmMapIoSpace failed (%lx)\n", Status); + return (NULL); + } Attributes = PAGE_EXECUTE_READWRITE | PAGE_SYSTEM; if (!CacheEnable) - { - Attributes |= (PAGE_NOCACHE | PAGE_WRITETHROUGH); - } + { + Attributes |= (PAGE_NOCACHE | PAGE_WRITETHROUGH); + } for (i = 0; (i < (PAGE_ROUND_UP(NumberOfBytes) / PAGE_SIZE)); i++) - { + { #if !defined(__GNUC__) - PHYSICAL_ADDRESS dummyJunkNeeded; - dummyJunkNeeded.QuadPart = PhysicalAddress.QuadPart + (i * PAGE_SIZE); + PHYSICAL_ADDRESS dummyJunkNeeded; + dummyJunkNeeded.QuadPart = PhysicalAddress.QuadPart + (i * PAGE_SIZE); #endif - Status = - MmCreateVirtualMappingForKernel((char*)Result + (i * PAGE_SIZE), - Attributes, + + Status = + MmCreateVirtualMappingForKernel((char*)Result + (i * PAGE_SIZE), + Attributes, #if defined(__GNUC__) - (PHYSICAL_ADDRESS) - (PhysicalAddress.QuadPart + - (i * PAGE_SIZE)) + (PHYSICAL_ADDRESS) + (PhysicalAddress.QuadPart + + (i * PAGE_SIZE)) #else - dummyJunkNeeded + dummyJunkNeeded #endif - ); - if (!NT_SUCCESS(Status)) - { - DbgPrint("Unable to create virtual mapping\n"); - KEBUGCHECK(0); - } + ); + if (!NT_SUCCESS(Status)) + { + DbgPrint("Unable to create virtual mapping\n"); + KEBUGCHECK(0); + } #if defined(__GNUC__) - MmMarkPageMapped((PHYSICAL_ADDRESS) (PhysicalAddress.QuadPart + - (i * PAGE_SIZE))); + MmMarkPageMapped((PHYSICAL_ADDRESS) (PhysicalAddress.QuadPart + + (i * PAGE_SIZE))); #else - MmMarkPageMapped(dummyJunkNeeded); + + MmMarkPageMapped(dummyJunkNeeded); #endif - } + + } return ((PVOID)((char*)Result + PhysicalAddress.QuadPart % PAGE_SIZE)); } - + /********************************************************************** - * NAME EXPORTED - * MmUnmapIoSpace@8 + * NAME EXPORTED + * MmUnmapIoSpace@8 * * DESCRIPTION - * Unmaps a physical memory range from system space. - * + * Unmaps a physical memory range from system space. + * * ARGUMENTS - * BaseAddress - * The base virtual address which maps the region; - * - * NumberOfBytes - * Number of bytes to unmap. + * BaseAddress + * The base virtual address which maps the region; + * + * NumberOfBytes + * Number of bytes to unmap. * * RETURN VALUE - * None. + * None. * * NOTE - * Code taken from ntoskrnl/mm/special.c. + * Code taken from ntoskrnl/mm/special.c. * * REVISIONS * * @implemented */ -VOID STDCALL +VOID STDCALL MmUnmapIoSpace (IN PVOID BaseAddress, - IN ULONG NumberOfBytes) + IN ULONG NumberOfBytes) { MmLockAddressSpace(MmGetKernelAddressSpace()); MmFreeMemoryArea(MmGetKernelAddressSpace(), - (PVOID)(((ULONG)BaseAddress / PAGE_SIZE) * PAGE_SIZE), - NumberOfBytes, - NULL, - NULL); + (PVOID)(((ULONG)BaseAddress / PAGE_SIZE) * PAGE_SIZE), + NumberOfBytes, + NULL, + NULL); MmUnlockAddressSpace(MmGetKernelAddressSpace()); } /********************************************************************** - * NAME EXPORTED - * MmMapVideoDisplay@16 + * NAME EXPORTED + * MmMapVideoDisplay@16 * * @implemented */ PVOID STDCALL -MmMapVideoDisplay (IN PHYSICAL_ADDRESS PhysicalAddress, - IN ULONG NumberOfBytes, - IN MEMORY_CACHING_TYPE CacheType) +MmMapVideoDisplay (IN PHYSICAL_ADDRESS PhysicalAddress, + IN ULONG NumberOfBytes, + IN MEMORY_CACHING_TYPE CacheType) { - return MmMapIoSpace (PhysicalAddress, NumberOfBytes, (BOOLEAN)CacheType); + return MmMapIoSpace (PhysicalAddress, NumberOfBytes, (BOOLEAN)CacheType); } @@ -194,10 +197,10 @@ MmMapVideoDisplay (IN PHYSICAL_ADDRESS PhysicalAddress, * @implemented */ VOID STDCALL -MmUnmapVideoDisplay (IN PVOID BaseAddress, - IN ULONG NumberOfBytes) +MmUnmapVideoDisplay (IN PVOID BaseAddress, + IN ULONG NumberOfBytes) { - MmUnmapIoSpace (BaseAddress, NumberOfBytes); + MmUnmapIoSpace (BaseAddress, NumberOfBytes); } diff --git a/reactos/ntoskrnl/mm/kmap.c b/reactos/ntoskrnl/mm/kmap.c index f33660bb438..972bafda599 100644 --- a/reactos/ntoskrnl/mm/kmap.c +++ b/reactos/ntoskrnl/mm/kmap.c @@ -1,4 +1,4 @@ -/* $Id: kmap.c,v 1.31 2004/01/05 14:28:21 weiden Exp $ +/* $Id: kmap.c,v 1.32 2004/04/10 22:35:25 gdalsnes Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -36,64 +36,64 @@ extern ULONG MiKernelMapLength; /* FUNCTIONS ***************************************************************/ -VOID +VOID ExUnmapPage(PVOID Addr) { KIRQL oldIrql; ULONG Base = ((char*)Addr - (char*)MiKernelMapStart) / PAGE_SIZE; - + DPRINT("ExUnmapPage(Addr %x)\n",Addr); - + MmDeleteVirtualMapping(NULL, (PVOID)Addr, FALSE, NULL, NULL); - KeAcquireSpinLock(&AllocMapLock, &oldIrql); + KeAcquireSpinLock(&AllocMapLock, &oldIrql); RtlClearBits(&AllocMap, Base, 1); AllocMapHint = min(AllocMapHint, Base); KeReleaseSpinLock(&AllocMapLock, oldIrql); } -PVOID +PVOID ExAllocatePage(VOID) { - PHYSICAL_ADDRESS PhysPage; - NTSTATUS Status; + PHYSICAL_ADDRESS PhysPage; + NTSTATUS Status; - Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &PhysPage); - if (!NT_SUCCESS(Status)) - { + Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &PhysPage); + if (!NT_SUCCESS(Status)) + { return(NULL); - } + } - return(ExAllocatePageWithPhysPage(PhysPage)); + return(ExAllocatePageWithPhysPage(PhysPage)); } NTSTATUS MiZeroPage(PHYSICAL_ADDRESS PhysPage) { - PVOID TempAddress; + PVOID TempAddress; - TempAddress = ExAllocatePageWithPhysPage(PhysPage); - if (TempAddress == NULL) - { + TempAddress = ExAllocatePageWithPhysPage(PhysPage); + if (TempAddress == NULL) + { return(STATUS_NO_MEMORY); - } - memset(TempAddress, 0, PAGE_SIZE); - ExUnmapPage(TempAddress); - return(STATUS_SUCCESS); + } + memset(TempAddress, 0, PAGE_SIZE); + ExUnmapPage(TempAddress); + return(STATUS_SUCCESS); } NTSTATUS MiCopyFromUserPage(PHYSICAL_ADDRESS DestPhysPage, PVOID SourceAddress) { - PVOID TempAddress; + PVOID TempAddress; - TempAddress = ExAllocatePageWithPhysPage(DestPhysPage); - if (TempAddress == NULL) - { + TempAddress = ExAllocatePageWithPhysPage(DestPhysPage); + if (TempAddress == NULL) + { return(STATUS_NO_MEMORY); - } - memcpy(TempAddress, SourceAddress, PAGE_SIZE); - ExUnmapPage(TempAddress); - return(STATUS_SUCCESS); + } + memcpy(TempAddress, SourceAddress, PAGE_SIZE); + ExUnmapPage(TempAddress); + return(STATUS_SUCCESS); } PVOID @@ -111,15 +111,15 @@ ExAllocatePageWithPhysPage(PHYSICAL_ADDRESS PhysPage) AllocMapHint = Base + 1; KeReleaseSpinLock(&AllocMapLock, oldlvl); Addr = (char*)MiKernelMapStart + Base * PAGE_SIZE; - Status = MmCreateVirtualMapping(NULL, - Addr, - PAGE_READWRITE | PAGE_SYSTEM, - PhysPage, - TRUE); + Status = MmCreateVirtualMapping(NULL, + Addr, + PAGE_READWRITE | PAGE_SYSTEM, + PhysPage, + TRUE); if (!NT_SUCCESS(Status)) { - DbgPrint("Unable to create virtual mapping\n"); - KEBUGCHECK(0); + DbgPrint("Unable to create virtual mapping\n"); + KEBUGCHECK(0); } return Addr; } @@ -138,22 +138,22 @@ MiInitKernelMap(VOID) VOID MiFreeNonPagedPoolRegion(PVOID Addr, ULONG Count, BOOLEAN Free) { - ULONG i; - ULONG Base = ((char*)Addr - (char*)MiKernelMapStart) / PAGE_SIZE; - KIRQL oldlvl; - - for (i = 0; i < Count; i++) - { - MmDeleteVirtualMapping(NULL, - (char*)Addr + (i * PAGE_SIZE), - Free, - NULL, - NULL); - } - KeAcquireSpinLock(&AllocMapLock, &oldlvl); - RtlClearBits(&AllocMap, Base, Count); - AllocMapHint = min(AllocMapHint, Base); - KeReleaseSpinLock(&AllocMapLock, oldlvl); + ULONG i; + ULONG Base = ((char*)Addr - (char*)MiKernelMapStart) / PAGE_SIZE; + KIRQL oldlvl; + + for (i = 0; i < Count; i++) + { + MmDeleteVirtualMapping(NULL, + (char*)Addr + (i * PAGE_SIZE), + Free, + NULL, + NULL); + } + KeAcquireSpinLock(&AllocMapLock, &oldlvl); + RtlClearBits(&AllocMap, Base, Count); + AllocMapHint = min(AllocMapHint, Base); + KeReleaseSpinLock(&AllocMapLock, oldlvl); } PVOID diff --git a/reactos/ntoskrnl/mm/marea.c b/reactos/ntoskrnl/mm/marea.c index d2e4cac2778..fc0475d3ab3 100644 --- a/reactos/ntoskrnl/mm/marea.c +++ b/reactos/ntoskrnl/mm/marea.c @@ -45,163 +45,163 @@ VOID MmDumpMemoryAreas(PLIST_ENTRY ListHead) { PLIST_ENTRY current_entry; MEMORY_AREA* current; - + DbgPrint("MmDumpMemoryAreas()\n"); - + current_entry = ListHead->Flink; while (current_entry!=ListHead) - { - current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry); - DbgPrint("Base %x Length %x End %x Attributes %x Flink %x\n", - current->BaseAddress,current->Length, - (char*)current->BaseAddress+current->Length,current->Attributes, - current->Entry.Flink); - current_entry = current_entry->Flink; - } + { + current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry); + DbgPrint("Base %x Length %x End %x Attributes %x Flink %x\n", + current->BaseAddress,current->Length, + (char*)current->BaseAddress+current->Length,current->Attributes, + current->Entry.Flink); + current_entry = current_entry->Flink; + } DbgPrint("Finished MmDumpMemoryAreas()\n"); } MEMORY_AREA* MmOpenMemoryAreaByAddress(PMADDRESS_SPACE AddressSpace, - PVOID Address) + PVOID Address) { PLIST_ENTRY current_entry; MEMORY_AREA* current; PLIST_ENTRY previous_entry; DPRINT("MmOpenMemoryAreaByAddress(AddressSpace %x, Address %x)\n", - AddressSpace, Address); - + AddressSpace, Address); + previous_entry = &AddressSpace->MAreaListHead; current_entry = AddressSpace->MAreaListHead.Flink; while (current_entry != &AddressSpace->MAreaListHead) - { - current = CONTAINING_RECORD(current_entry, - MEMORY_AREA, - Entry); - assert(current_entry->Blink->Flink == current_entry); - assert(current_entry->Flink->Blink == current_entry); - assert(previous_entry->Flink == current_entry); - if (current->BaseAddress <= Address && - (PVOID)((char*)current->BaseAddress + current->Length) > Address) - { - DPRINT("%s() = %x\n",__FUNCTION__,current); - return(current); - } - if (current->BaseAddress > Address) - { - DPRINT("%s() = NULL\n",__FUNCTION__); - return(NULL); - } - previous_entry = current_entry; - current_entry = current_entry->Flink; - } + { + current = CONTAINING_RECORD(current_entry, + MEMORY_AREA, + Entry); + assert(current_entry->Blink->Flink == current_entry); + assert(current_entry->Flink->Blink == current_entry); + assert(previous_entry->Flink == current_entry); + if (current->BaseAddress <= Address && + (PVOID)((char*)current->BaseAddress + current->Length) > Address) + { + DPRINT("%s() = %x\n",__FUNCTION__,current); + return(current); + } + if (current->BaseAddress > Address) + { + DPRINT("%s() = NULL\n",__FUNCTION__); + return(NULL); + } + previous_entry = current_entry; + current_entry = current_entry->Flink; + } DPRINT("%s() = NULL\n",__FUNCTION__); return(NULL); } -MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace, - PVOID Address, - ULONG Length) +MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace, + PVOID Address, + ULONG Length) { PLIST_ENTRY current_entry; MEMORY_AREA* current; ULONG Extent; - + DPRINT("MmOpenMemoryByRegion(AddressSpace %x, Address %x, Length %x)\n", - AddressSpace, Address, Length); - + AddressSpace, Address, Length); + current_entry = AddressSpace->MAreaListHead.Flink; while (current_entry != &AddressSpace->MAreaListHead) - { - current = CONTAINING_RECORD(current_entry, - MEMORY_AREA, - Entry); - DPRINT("current->BaseAddress %x current->Length %x\n", - current->BaseAddress,current->Length); - if (current->BaseAddress >= Address && - current->BaseAddress < (PVOID)((char*)Address+Length)) - { - DPRINT("Finished MmOpenMemoryAreaByRegion() = %x\n", - current); - return(current); - } - Extent = (ULONG)current->BaseAddress + current->Length; - if (Extent > (ULONG)Address && - Extent < (ULONG)((char*)Address+Length)) - { - DPRINT("Finished MmOpenMemoryAreaByRegion() = %x\n", - current); - return(current); - } - if (current->BaseAddress <= Address && - Extent >= (ULONG)((char*)Address+Length)) - { - DPRINT("Finished MmOpenMemoryAreaByRegion() = %x\n", - current); - return(current); - } - if (current->BaseAddress >= (PVOID)((char*)Address+Length)) - { - DPRINT("Finished MmOpenMemoryAreaByRegion()= NULL\n",0); - return(NULL); - } - current_entry = current_entry->Flink; - } + { + current = CONTAINING_RECORD(current_entry, + MEMORY_AREA, + Entry); + DPRINT("current->BaseAddress %x current->Length %x\n", + current->BaseAddress,current->Length); + if (current->BaseAddress >= Address && + current->BaseAddress < (PVOID)((char*)Address+Length)) + { + DPRINT("Finished MmOpenMemoryAreaByRegion() = %x\n", + current); + return(current); + } + Extent = (ULONG)current->BaseAddress + current->Length; + if (Extent > (ULONG)Address && + Extent < (ULONG)((char*)Address+Length)) + { + DPRINT("Finished MmOpenMemoryAreaByRegion() = %x\n", + current); + return(current); + } + if (current->BaseAddress <= Address && + Extent >= (ULONG)((char*)Address+Length)) + { + DPRINT("Finished MmOpenMemoryAreaByRegion() = %x\n", + current); + return(current); + } + if (current->BaseAddress >= (PVOID)((char*)Address+Length)) + { + DPRINT("Finished MmOpenMemoryAreaByRegion()= NULL\n",0); + return(NULL); + } + current_entry = current_entry->Flink; + } DPRINT("Finished MmOpenMemoryAreaByRegion() = NULL\n",0); return(NULL); } static VOID MmInsertMemoryArea(PMADDRESS_SPACE AddressSpace, - MEMORY_AREA* marea) + MEMORY_AREA* marea) { PLIST_ENTRY ListHead; PLIST_ENTRY current_entry; PLIST_ENTRY inserted_entry = &marea->Entry; MEMORY_AREA* current; - MEMORY_AREA* next; - + MEMORY_AREA* next; + DPRINT("MmInsertMemoryArea(marea %x)\n", marea); DPRINT("marea->BaseAddress %x\n", marea->BaseAddress); DPRINT("marea->Length %x\n", marea->Length); - + ListHead = &AddressSpace->MAreaListHead; - + current_entry = ListHead->Flink; if (IsListEmpty(ListHead)) - { - InsertHeadList(ListHead,&marea->Entry); - return; - } + { + InsertHeadList(ListHead,&marea->Entry); + return; + } current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry); if (current->BaseAddress > marea->BaseAddress) - { - InsertHeadList(ListHead,&marea->Entry); - return; - } + { + InsertHeadList(ListHead,&marea->Entry); + return; + } while (current_entry->Flink!=ListHead) - { - current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry); - next = CONTAINING_RECORD(current_entry->Flink,MEMORY_AREA,Entry); - if (current->BaseAddress < marea->BaseAddress && - current->Entry.Flink==ListHead) - { - current_entry->Flink = inserted_entry; - inserted_entry->Flink=ListHead; - inserted_entry->Blink=current_entry; - ListHead->Blink = inserted_entry; - return; - } - if (current->BaseAddress < marea->BaseAddress && - next->BaseAddress > marea->BaseAddress) - { - inserted_entry->Flink = current_entry->Flink; - inserted_entry->Blink = current_entry; - inserted_entry->Flink->Blink = inserted_entry; - current_entry->Flink=inserted_entry; - return; - } - current_entry = current_entry->Flink; - } + { + current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry); + next = CONTAINING_RECORD(current_entry->Flink,MEMORY_AREA,Entry); + if (current->BaseAddress < marea->BaseAddress && + current->Entry.Flink==ListHead) + { + current_entry->Flink = inserted_entry; + inserted_entry->Flink=ListHead; + inserted_entry->Blink=current_entry; + ListHead->Blink = inserted_entry; + return; + } + if (current->BaseAddress < marea->BaseAddress && + next->BaseAddress > marea->BaseAddress) + { + inserted_entry->Flink = current_entry->Flink; + inserted_entry->Blink = current_entry; + inserted_entry->Flink->Blink = inserted_entry; + current_entry->Flink=inserted_entry; + return; + } + current_entry = current_entry->Flink; + } InsertTailList(ListHead,inserted_entry); } @@ -214,136 +214,136 @@ PVOID MmFindGapBottomUp(PMADDRESS_SPACE AddressSpace, ULONG Length) MEMORY_AREA* next; ULONG Gap; PVOID Address; - + DPRINT("MmFindGapBottomUp(Length %x)\n",Length); - + ListHead = &AddressSpace->MAreaListHead; - + current_entry = ListHead->Flink; while (current_entry->Flink!=ListHead) - { - current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry); - next = CONTAINING_RECORD(current_entry->Flink,MEMORY_AREA,Entry); - Gap = (char*)next->BaseAddress - ((char*)current->BaseAddress + PAGE_ROUND_UP(current->Length)); - if (Gap >= Length) - { - return((char*)current->BaseAddress + PAGE_ROUND_UP(current->Length)); - } - current_entry = current_entry->Flink; - } - + { + current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry); + next = CONTAINING_RECORD(current_entry->Flink,MEMORY_AREA,Entry); + Gap = (char*)next->BaseAddress - ((char*)current->BaseAddress + PAGE_ROUND_UP(current->Length)); + if (Gap >= Length) + { + return((char*)current->BaseAddress + PAGE_ROUND_UP(current->Length)); + } + current_entry = current_entry->Flink; + } + if (current_entry == ListHead) - { - Address = (PVOID)AddressSpace->LowestAddress; - } + { + Address = (PVOID)AddressSpace->LowestAddress; + } else - { - current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry); - Address = (char*)current->BaseAddress + PAGE_ROUND_UP(current->Length); - } + { + current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry); + Address = (char*)current->BaseAddress + PAGE_ROUND_UP(current->Length); + } /* Check if enough space for the block */ if (AddressSpace->LowestAddress < KERNEL_BASE) - { - if ((ULONG)Address >= KERNEL_BASE || Length > KERNEL_BASE - (ULONG)Address) - { - return NULL; - } - } + { + if ((ULONG)Address >= KERNEL_BASE || Length > KERNEL_BASE - (ULONG)Address) + { + return NULL; + } + } else - { - if (Length >= 0xFFFFFFFF - (ULONG)Address) - { - return NULL; - } - } + { + if (Length >= 0xFFFFFFFF - (ULONG)Address) + { + return NULL; + } + } return Address; } PVOID MmFindGapTopDown(PMADDRESS_SPACE AddressSpace, ULONG Length) { - PLIST_ENTRY ListHead; - PLIST_ENTRY current_entry; - MEMORY_AREA* current; - ULONG Gap; - PVOID Address; - PVOID TopAddress; - PVOID BottomAddress; - PVOID HighestAddress; + PLIST_ENTRY ListHead; + PLIST_ENTRY current_entry; + MEMORY_AREA* current; + ULONG Gap; + PVOID Address; + PVOID TopAddress; + PVOID BottomAddress; + PVOID HighestAddress; - DPRINT("MmFindGapTopDown(Length %lx)\n",Length); + DPRINT("MmFindGapTopDown(Length %lx)\n",Length); - if (AddressSpace->LowestAddress < KERNEL_BASE) //(ULONG_PTR)MmSystemRangeStart) - { + if (AddressSpace->LowestAddress < KERNEL_BASE) //(ULONG_PTR)MmSystemRangeStart) + { HighestAddress = MmHighestUserAddress; - } - else - { + } + else + { HighestAddress = (PVOID)0xFFFFFFFF; - } + } - TopAddress = HighestAddress; + TopAddress = HighestAddress; - ListHead = &AddressSpace->MAreaListHead; - current_entry = ListHead->Blink; - while (current_entry->Blink != ListHead) - { + ListHead = &AddressSpace->MAreaListHead; + current_entry = ListHead->Blink; + while (current_entry->Blink != ListHead) + { current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry); BottomAddress = (char*)current->BaseAddress + PAGE_ROUND_UP(current->Length); DPRINT("Base %p Length %lx\n", current->BaseAddress, PAGE_ROUND_UP(current->Length)); if (BottomAddress < HighestAddress) - { - Gap = (char*)TopAddress - (char*)BottomAddress + 1; - DPRINT("Bottom %p Top %p Gap %lx\n", BottomAddress, TopAddress, Gap); - if (Gap >= Length) - { - DPRINT("Found gap at %p\n", (char*)TopAddress - Length); - return((char*)TopAddress - Length + 1); - } - TopAddress = (char*)current->BaseAddress - 1; - } + { + Gap = (char*)TopAddress - (char*)BottomAddress + 1; + DPRINT("Bottom %p Top %p Gap %lx\n", BottomAddress, TopAddress, Gap); + if (Gap >= Length) + { + DPRINT("Found gap at %p\n", (char*)TopAddress - Length); + return((char*)TopAddress - Length + 1); + } + TopAddress = (char*)current->BaseAddress - 1; + } current_entry = current_entry->Blink; - } + } - if (current_entry == ListHead) - { + if (current_entry == ListHead) + { Address = (char*)HighestAddress - Length + 1; - } - else - { - Address = (char*)TopAddress - Length + 1; - } - - /* Check if enough space for the block */ - if (AddressSpace->LowestAddress < KERNEL_BASE) - { - if ((ULONG)Address >= KERNEL_BASE || Length > KERNEL_BASE - (ULONG)Address) - { - DPRINT("Failed to find gap\n"); - return NULL; - } - } + } else - { - if (Length >= 0xFFFFFFFF - (ULONG)Address) - { - DPRINT("Failed to find gap\n"); - return NULL; - } - } + { + Address = (char*)TopAddress - Length + 1; + } - DPRINT("Found gap at %p\n", Address); - return Address; + /* Check if enough space for the block */ + if (AddressSpace->LowestAddress < KERNEL_BASE) + { + if ((ULONG)Address >= KERNEL_BASE || Length > KERNEL_BASE - (ULONG)Address) + { + DPRINT("Failed to find gap\n"); + return NULL; + } + } + else + { + if (Length >= 0xFFFFFFFF - (ULONG)Address) + { + DPRINT("Failed to find gap\n"); + return NULL; + } + } + + DPRINT("Found gap at %p\n", Address); + return Address; } PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length, BOOL TopDown) { - if (TopDown) - return MmFindGapTopDown(AddressSpace, Length); + if (TopDown) + return MmFindGapTopDown(AddressSpace, Length); - return MmFindGapBottomUp(AddressSpace, Length); + return MmFindGapBottomUp(AddressSpace, Length); } @@ -357,92 +357,94 @@ MmInitMemoryAreas(VOID) return(STATUS_SUCCESS); } -NTSTATUS +NTSTATUS MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace, - PVOID BaseAddress, - ULONG Length, - VOID (*FreePage)(PVOID Context, MEMORY_AREA* MemoryArea, - PVOID Address, PHYSICAL_ADDRESS PhysAddr, - SWAPENTRY SwapEntry, BOOLEAN Dirty), - PVOID FreePageContext) + PVOID BaseAddress, + ULONG Length, + VOID (*FreePage)(PVOID Context, MEMORY_AREA* MemoryArea, + PVOID Address, PHYSICAL_ADDRESS PhysAddr, + SWAPENTRY SwapEntry, BOOLEAN Dirty), + PVOID FreePageContext) { MEMORY_AREA* MemoryArea; ULONG i; PEPROCESS CurrentProcess = PsGetCurrentProcess(); - + DPRINT("MmFreeMemoryArea(AddressSpace %x, BaseAddress %x, Length %x," - "FreePageContext %d)\n",AddressSpace,BaseAddress,Length, - FreePageContext); + "FreePageContext %d)\n",AddressSpace,BaseAddress,Length, + FreePageContext); MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, - BaseAddress); + BaseAddress); if (MemoryArea == NULL) - { - KEBUGCHECK(0); - return(STATUS_UNSUCCESSFUL); - } - if (AddressSpace->Process != NULL && - AddressSpace->Process != CurrentProcess) - { - KeAttachProcess(AddressSpace->Process); - } - for (i=0; i<(PAGE_ROUND_UP(MemoryArea->Length)/PAGE_SIZE); i++) - { -#if defined(__GNUC__) - PHYSICAL_ADDRESS PhysAddr = (PHYSICAL_ADDRESS)0LL; -#else - PHYSICAL_ADDRESS PhysAddr = { 0 }; -#endif - BOOL Dirty = FALSE; - SWAPENTRY SwapEntry = 0; - - if (MmIsPageSwapEntry(AddressSpace->Process, - (char*)MemoryArea->BaseAddress + (i * PAGE_SIZE))) - { - MmDeletePageFileMapping(AddressSpace->Process, - (char*)MemoryArea->BaseAddress + (i * PAGE_SIZE), - &SwapEntry); - } - else - { - MmDeleteVirtualMapping(AddressSpace->Process, - (char*)MemoryArea->BaseAddress + (i*PAGE_SIZE), - FALSE, &Dirty, &PhysAddr); - - } - if (FreePage != NULL) - { - FreePage(FreePageContext, MemoryArea, - (char*)MemoryArea->BaseAddress + (i * PAGE_SIZE), PhysAddr, - SwapEntry, (BOOLEAN)Dirty); - } - } + { + KEBUGCHECK(0); + return(STATUS_UNSUCCESSFUL); + } if (AddressSpace->Process != NULL && - AddressSpace->Process != CurrentProcess) - { - KeDetachProcess(); - } + AddressSpace->Process != CurrentProcess) + { + KeAttachProcess(AddressSpace->Process); + } + for (i=0; i<(PAGE_ROUND_UP(MemoryArea->Length)/PAGE_SIZE); i++) + { +#if defined(__GNUC__) + PHYSICAL_ADDRESS PhysAddr = (PHYSICAL_ADDRESS)0LL; +#else + + PHYSICAL_ADDRESS PhysAddr = { 0 }; +#endif + + BOOL Dirty = FALSE; + SWAPENTRY SwapEntry = 0; + + if (MmIsPageSwapEntry(AddressSpace->Process, + (char*)MemoryArea->BaseAddress + (i * PAGE_SIZE))) + { + MmDeletePageFileMapping(AddressSpace->Process, + (char*)MemoryArea->BaseAddress + (i * PAGE_SIZE), + &SwapEntry); + } + else + { + MmDeleteVirtualMapping(AddressSpace->Process, + (char*)MemoryArea->BaseAddress + (i*PAGE_SIZE), + FALSE, &Dirty, &PhysAddr); + + } + if (FreePage != NULL) + { + FreePage(FreePageContext, MemoryArea, + (char*)MemoryArea->BaseAddress + (i * PAGE_SIZE), PhysAddr, + SwapEntry, (BOOLEAN)Dirty); + } + } + if (AddressSpace->Process != NULL && + AddressSpace->Process != CurrentProcess) + { + KeDetachProcess(); + } RemoveEntryList(&MemoryArea->Entry); ExFreePool(MemoryArea); - + DPRINT("MmFreeMemoryArea() succeeded\n"); - + return(STATUS_SUCCESS); } PMEMORY_AREA MmSplitMemoryArea(PEPROCESS Process, - PMADDRESS_SPACE AddressSpace, - PMEMORY_AREA OriginalMemoryArea, - PVOID BaseAddress, - ULONG Length, - ULONG NewType, - ULONG NewAttributes) + PMADDRESS_SPACE AddressSpace, + PMEMORY_AREA OriginalMemoryArea, + PVOID BaseAddress, + ULONG Length, + ULONG NewType, + ULONG NewAttributes) { PMEMORY_AREA Result; PMEMORY_AREA Split; - - Result = ExAllocatePoolWithTag(NonPagedPool, sizeof(MEMORY_AREA), - TAG_MAREA); + + Result = ExAllocatePoolWithTag(NonPagedPool, sizeof(MEMORY_AREA), + TAG_MAREA); RtlZeroMemory(Result,sizeof(MEMORY_AREA)); Result->Type = NewType; Result->BaseAddress = BaseAddress; @@ -450,45 +452,45 @@ PMEMORY_AREA MmSplitMemoryArea(PEPROCESS Process, Result->Attributes = NewAttributes; Result->LockCount = 0; Result->Process = Process; - - if (BaseAddress == OriginalMemoryArea->BaseAddress) - { - OriginalMemoryArea->BaseAddress = (char*)BaseAddress + Length; - OriginalMemoryArea->Length = OriginalMemoryArea->Length - Length; - MmInsertMemoryArea(AddressSpace, Result); - return(Result); - } - if (((char*)BaseAddress + Length) == - ((char*)OriginalMemoryArea->BaseAddress + OriginalMemoryArea->Length)) - { - OriginalMemoryArea->Length = OriginalMemoryArea->Length - Length; - MmInsertMemoryArea(AddressSpace, Result); - return(Result); - } - + if (BaseAddress == OriginalMemoryArea->BaseAddress) + { + OriginalMemoryArea->BaseAddress = (char*)BaseAddress + Length; + OriginalMemoryArea->Length = OriginalMemoryArea->Length - Length; + MmInsertMemoryArea(AddressSpace, Result); + return(Result); + } + if (((char*)BaseAddress + Length) == + ((char*)OriginalMemoryArea->BaseAddress + OriginalMemoryArea->Length)) + { + OriginalMemoryArea->Length = OriginalMemoryArea->Length - Length; + MmInsertMemoryArea(AddressSpace, Result); + + return(Result); + } + Split = ExAllocatePoolWithTag(NonPagedPool, sizeof(MEMORY_AREA), - TAG_MAREA); + TAG_MAREA); RtlCopyMemory(Split,OriginalMemoryArea,sizeof(MEMORY_AREA)); Split->BaseAddress = (char*)BaseAddress + Length; - Split->Length = OriginalMemoryArea->Length - (((ULONG)BaseAddress) - + Length); - + Split->Length = OriginalMemoryArea->Length - (((ULONG)BaseAddress) + + Length); + OriginalMemoryArea->Length = (char*)BaseAddress - (char*)OriginalMemoryArea->BaseAddress; - + return(Split); } NTSTATUS MmCreateMemoryArea(PEPROCESS Process, - PMADDRESS_SPACE AddressSpace, - ULONG Type, - PVOID* BaseAddress, - ULONG Length, - ULONG Attributes, - MEMORY_AREA** Result, - BOOL FixedAddress, - BOOL TopDown, - PHYSICAL_ADDRESS BoundaryAddressMultiple) + PMADDRESS_SPACE AddressSpace, + ULONG Type, + PVOID* BaseAddress, + ULONG Length, + ULONG Attributes, + MEMORY_AREA** Result, + BOOL FixedAddress, + BOOL TopDown, + PHYSICAL_ADDRESS BoundaryAddressMultiple) /* * FUNCTION: Create a memory area * ARGUMENTS: @@ -505,64 +507,66 @@ NTSTATUS MmCreateMemoryArea(PEPROCESS Process, PVOID EndAddress; ULONG tmpLength; DPRINT("MmCreateMemoryArea(Type %d, BaseAddress %x," - "*BaseAddress %x, Length %x, Attributes %x, Result %x)\n", - Type,BaseAddress,*BaseAddress,Length,Attributes,Result); + "*BaseAddress %x, Length %x, Attributes %x, Result %x)\n", + Type,BaseAddress,*BaseAddress,Length,Attributes,Result); if ((*BaseAddress) == 0 && !FixedAddress) - { - tmpLength = PAGE_ROUND_UP(Length); - *BaseAddress = MmFindGap(AddressSpace, - PAGE_ROUND_UP(Length) +(PAGE_SIZE*2), - TopDown); - if ((*BaseAddress) == 0) - { - DPRINT("No suitable gap\n"); - return(STATUS_NO_MEMORY); - } + { + tmpLength = PAGE_ROUND_UP(Length); + *BaseAddress = MmFindGap(AddressSpace, + PAGE_ROUND_UP(Length) +(PAGE_SIZE*2), + TopDown); + if ((*BaseAddress) == 0) + { + DPRINT("No suitable gap\n"); + return(STATUS_NO_MEMORY); + } #if defined(__GNUC__) - (*BaseAddress)=(*BaseAddress)+PAGE_SIZE; + (*BaseAddress)=(*BaseAddress)+PAGE_SIZE; #else - { - char* pTemp = *BaseAddress; - pTemp += PAGE_SIZE; - *BaseAddress = pTemp; - } + + { + char* pTemp = *BaseAddress; + pTemp += PAGE_SIZE; + *BaseAddress = pTemp; + } #endif - } + + } else - { - tmpLength = (ULONG)*BaseAddress + Length - PAGE_ROUND_DOWN((*BaseAddress)); - (*BaseAddress) = (PVOID)PAGE_ROUND_DOWN((*BaseAddress)); + { + tmpLength = (ULONG)*BaseAddress + Length - PAGE_ROUND_DOWN((*BaseAddress)); + (*BaseAddress) = (PVOID)PAGE_ROUND_DOWN((*BaseAddress)); - if (AddressSpace->LowestAddress == KERNEL_BASE && - (*BaseAddress) < (PVOID)KERNEL_BASE) - { - return STATUS_ACCESS_VIOLATION; - } + if (AddressSpace->LowestAddress == KERNEL_BASE && + (*BaseAddress) < (PVOID)KERNEL_BASE) + { + return STATUS_ACCESS_VIOLATION; + } - if (AddressSpace->LowestAddress < KERNEL_BASE && - (PVOID)((char*)(*BaseAddress) + tmpLength) > (PVOID)KERNEL_BASE) - { - return STATUS_ACCESS_VIOLATION; - } + if (AddressSpace->LowestAddress < KERNEL_BASE && + (PVOID)((char*)(*BaseAddress) + tmpLength) > (PVOID)KERNEL_BASE) + { + return STATUS_ACCESS_VIOLATION; + } - if (BoundaryAddressMultiple.QuadPart != 0) - { - EndAddress = ((char*)(*BaseAddress)) + tmpLength-1; - assert(((DWORD_PTR)*BaseAddress/BoundaryAddressMultiple.QuadPart) == ((DWORD_PTR)EndAddress/BoundaryAddressMultiple.QuadPart)); - } + if (BoundaryAddressMultiple.QuadPart != 0) + { + EndAddress = ((char*)(*BaseAddress)) + tmpLength-1; + assert(((DWORD_PTR)*BaseAddress/BoundaryAddressMultiple.QuadPart) == ((DWORD_PTR)EndAddress/BoundaryAddressMultiple.QuadPart)); + } - if (MmOpenMemoryAreaByRegion(AddressSpace, - *BaseAddress, - tmpLength)!=NULL) - { - DPRINT("Memory area already occupied\n"); - return(STATUS_CONFLICTING_ADDRESSES); - } - } + if (MmOpenMemoryAreaByRegion(AddressSpace, + *BaseAddress, + tmpLength)!=NULL) + { + DPRINT("Memory area already occupied\n"); + return(STATUS_CONFLICTING_ADDRESSES); + } + } *Result = ExAllocatePoolWithTag(NonPagedPool, sizeof(MEMORY_AREA), - TAG_MAREA); + TAG_MAREA); RtlZeroMemory(*Result,sizeof(MEMORY_AREA)); (*Result)->Type = Type; (*Result)->BaseAddress = *BaseAddress; @@ -572,9 +576,9 @@ NTSTATUS MmCreateMemoryArea(PEPROCESS Process, (*Result)->Process = Process; (*Result)->PageOpCount = 0; (*Result)->DeleteInProgress = FALSE; - + MmInsertMemoryArea(AddressSpace, *Result); - + DPRINT("MmCreateMemoryArea() succeeded\n"); return(STATUS_SUCCESS); } diff --git a/reactos/ntoskrnl/mm/mdl.c b/reactos/ntoskrnl/mm/mdl.c index 869bde7b68f..6585b8aab1c 100644 --- a/reactos/ntoskrnl/mm/mdl.c +++ b/reactos/ntoskrnl/mm/mdl.c @@ -1,4 +1,4 @@ -/* $Id: mdl.c,v 1.60 2004/03/13 19:14:16 dwelch Exp $ +/* $Id: mdl.c,v 1.61 2004/04/10 22:35:25 gdalsnes Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -36,55 +36,55 @@ static KSPIN_LOCK MiMdlMappingRegionLock; VOID INIT_FUNCTION MmInitializeMdlImplementation(VOID) { - MEMORY_AREA* Result; - NTSTATUS Status; - PVOID Buffer; - PHYSICAL_ADDRESS BoundaryAddressMultiple; + MEMORY_AREA* Result; + NTSTATUS Status; + PVOID Buffer; + PHYSICAL_ADDRESS BoundaryAddressMultiple; - BoundaryAddressMultiple.QuadPart = 0; - MiMdlMappingRegionHint = 0; - MiMdlMappingRegionBase = NULL; + BoundaryAddressMultiple.QuadPart = 0; + MiMdlMappingRegionHint = 0; + MiMdlMappingRegionBase = NULL; - MmLockAddressSpace(MmGetKernelAddressSpace()); - Status = MmCreateMemoryArea(NULL, - MmGetKernelAddressSpace(), - MEMORY_AREA_MDL_MAPPING, - &MiMdlMappingRegionBase, - MI_MDL_MAPPING_REGION_SIZE, - 0, - &Result, - FALSE, - FALSE, - BoundaryAddressMultiple); - if (!NT_SUCCESS(Status)) - { + MmLockAddressSpace(MmGetKernelAddressSpace()); + Status = MmCreateMemoryArea(NULL, + MmGetKernelAddressSpace(), + MEMORY_AREA_MDL_MAPPING, + &MiMdlMappingRegionBase, + MI_MDL_MAPPING_REGION_SIZE, + 0, + &Result, + FALSE, + FALSE, + BoundaryAddressMultiple); + if (!NT_SUCCESS(Status)) + { MmUnlockAddressSpace(MmGetKernelAddressSpace()); KEBUGCHECK(0); - } - MmUnlockAddressSpace(MmGetKernelAddressSpace()); + } + MmUnlockAddressSpace(MmGetKernelAddressSpace()); - Buffer = ExAllocatePool(NonPagedPool, MI_MDL_MAPPING_REGION_SIZE / (PAGE_SIZE * 8)); + Buffer = ExAllocatePool(NonPagedPool, MI_MDL_MAPPING_REGION_SIZE / (PAGE_SIZE * 8)); - RtlInitializeBitMap(&MiMdlMappingRegionAllocMap, Buffer, MI_MDL_MAPPING_REGION_SIZE / PAGE_SIZE); - RtlClearAllBits(&MiMdlMappingRegionAllocMap); + RtlInitializeBitMap(&MiMdlMappingRegionAllocMap, Buffer, MI_MDL_MAPPING_REGION_SIZE / PAGE_SIZE); + RtlClearAllBits(&MiMdlMappingRegionAllocMap); - KeInitializeSpinLock(&MiMdlMappingRegionLock); + KeInitializeSpinLock(&MiMdlMappingRegionLock); } -PVOID +PVOID MmGetMdlPageAddress(PMDL Mdl, PVOID Offset) { PULONG MdlPages; - + MdlPages = (PULONG)(Mdl + 1); - + return((PVOID)MdlPages[((ULONG)Offset) / PAGE_SIZE]); } /* * @unimplemented */ -VOID STDCALL +VOID STDCALL MmUnlockPages(PMDL Mdl) /* * FUNCTION: Unlocks the physical pages described by a given MDL @@ -97,37 +97,39 @@ MmUnlockPages(PMDL Mdl) { ULONG i; PULONG MdlPages; - - /* + + /* * FIXME: I don't know whether this right, but it looks sensible */ if ((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) || - (Mdl->MdlFlags & MDL_IO_PAGE_READ)) - { - return; - } - + (Mdl->MdlFlags & MDL_IO_PAGE_READ)) + { + return; + } + /* * FIXME: Seems sensible */ if (!(Mdl->MdlFlags & MDL_PAGES_LOCKED)) - { - return; - } - + { + return; + } + MdlPages = (PULONG)(Mdl + 1); for (i=0; i<(PAGE_ROUND_UP(Mdl->ByteCount+Mdl->ByteOffset)/PAGE_SIZE); i++) - { + { #if defined(__GNUC__) - MmUnlockPage((LARGE_INTEGER)(LONGLONG)MdlPages[i]); - MmDereferencePage((LARGE_INTEGER)(LONGLONG)MdlPages[i]); + MmUnlockPage((LARGE_INTEGER)(LONGLONG)MdlPages[i]); + MmDereferencePage((LARGE_INTEGER)(LONGLONG)MdlPages[i]); #else - PHYSICAL_ADDRESS dummyJunkNeeded; - dummyJunkNeeded.QuadPart = MdlPages[i]; - MmUnlockPage(dummyJunkNeeded); - MmDereferencePage(dummyJunkNeeded); + + PHYSICAL_ADDRESS dummyJunkNeeded; + dummyJunkNeeded.QuadPart = MdlPages[i]; + MmUnlockPage(dummyJunkNeeded); + MmDereferencePage(dummyJunkNeeded); #endif - } + + } Mdl->MdlFlags = Mdl->MdlFlags & (~MDL_PAGES_LOCKED); } @@ -157,103 +159,105 @@ MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode) DPRINT("MmMapLockedPages(Mdl %x, AccessMode %x)\n", Mdl, AccessMode); if ((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) && AccessMode != UserMode) - { - return(Mdl->MappedSystemVa); - } + { + return(Mdl->MappedSystemVa); + } /* Calculate the number of pages required. */ RegionSize = PAGE_ROUND_UP(Mdl->ByteCount + Mdl->ByteOffset) / PAGE_SIZE; if (AccessMode == UserMode) - { - MEMORY_AREA *Result; - LARGE_INTEGER BoundaryAddressMultiple; - NTSTATUS Status; + { + MEMORY_AREA *Result; + LARGE_INTEGER BoundaryAddressMultiple; + NTSTATUS Status; - BoundaryAddressMultiple.QuadPart = 0; - Base = NULL; + BoundaryAddressMultiple.QuadPart = 0; + Base = NULL; - CurrentProcess = OldProcess = PsGetCurrentProcess(); - if (Mdl->Process != CurrentProcess) - { - KeAttachProcess(Mdl->Process); - CurrentProcess = Mdl->Process; - } + CurrentProcess = OldProcess = PsGetCurrentProcess(); + if (Mdl->Process != CurrentProcess) + { + KeAttachProcess(Mdl->Process); + CurrentProcess = Mdl->Process; + } - MmLockAddressSpace(&CurrentProcess->AddressSpace); - Status = MmCreateMemoryArea(CurrentProcess, - &CurrentProcess->AddressSpace, - MEMORY_AREA_MDL_MAPPING, - &Base, - RegionSize * PAGE_SIZE, - 0, /* PAGE_READWRITE? */ - &Result, - FALSE, - FALSE, - BoundaryAddressMultiple); - MmUnlockAddressSpace(&CurrentProcess->AddressSpace); - if (!NT_SUCCESS(Status)) - { - KEBUGCHECK(0); - /* FIXME: handle this? */ - } - } + MmLockAddressSpace(&CurrentProcess->AddressSpace); + Status = MmCreateMemoryArea(CurrentProcess, + &CurrentProcess->AddressSpace, + MEMORY_AREA_MDL_MAPPING, + &Base, + RegionSize * PAGE_SIZE, + 0, /* PAGE_READWRITE? */ + &Result, + FALSE, + FALSE, + BoundaryAddressMultiple); + MmUnlockAddressSpace(&CurrentProcess->AddressSpace); + if (!NT_SUCCESS(Status)) + { + KEBUGCHECK(0); + /* FIXME: handle this? */ + } + } else - { - CurrentProcess = OldProcess = NULL; + { + CurrentProcess = OldProcess = NULL; - /* Allocate that number of pages from the mdl mapping region. */ - KeAcquireSpinLock(&MiMdlMappingRegionLock, &oldIrql); + /* Allocate that number of pages from the mdl mapping region. */ + KeAcquireSpinLock(&MiMdlMappingRegionLock, &oldIrql); - StartingOffset = RtlFindClearBitsAndSet(&MiMdlMappingRegionAllocMap, RegionSize, MiMdlMappingRegionHint); + StartingOffset = RtlFindClearBitsAndSet(&MiMdlMappingRegionAllocMap, RegionSize, MiMdlMappingRegionHint); - if (StartingOffset == 0xffffffff) - { - DPRINT1("Out of MDL mapping space\n"); - KEBUGCHECK(0); - } + if (StartingOffset == 0xffffffff) + { + DPRINT1("Out of MDL mapping space\n"); + KEBUGCHECK(0); + } - Base = (char*)MiMdlMappingRegionBase + StartingOffset * PAGE_SIZE; + Base = (char*)MiMdlMappingRegionBase + StartingOffset * PAGE_SIZE; - if (MiMdlMappingRegionHint == StartingOffset) - { - MiMdlMappingRegionHint +=RegionSize; - } + if (MiMdlMappingRegionHint == StartingOffset) + { + MiMdlMappingRegionHint +=RegionSize; + } - KeReleaseSpinLock(&MiMdlMappingRegionLock, oldIrql); - } + KeReleaseSpinLock(&MiMdlMappingRegionLock, oldIrql); + } /* Set the virtual mappings for the MDL pages. */ MdlPages = (PULONG)(Mdl + 1); for (i = 0; i < RegionSize; i++) - { - NTSTATUS Status; + { + NTSTATUS Status; #if !defined(__GNUC__) - PHYSICAL_ADDRESS dummyJunkNeeded; - dummyJunkNeeded.QuadPart = MdlPages[i]; + + PHYSICAL_ADDRESS dummyJunkNeeded; + dummyJunkNeeded.QuadPart = MdlPages[i]; #endif - Status = MmCreateVirtualMapping(CurrentProcess, - (PVOID)((ULONG)Base+(i*PAGE_SIZE)), - PAGE_READWRITE, + + Status = MmCreateVirtualMapping(CurrentProcess, + (PVOID)((ULONG)Base+(i*PAGE_SIZE)), + PAGE_READWRITE, #if defined(__GNUC__) - (LARGE_INTEGER)(LONGLONG)MdlPages[i], + (LARGE_INTEGER)(LONGLONG)MdlPages[i], #else - dummyJunkNeeded, + dummyJunkNeeded, #endif - FALSE); - if (!NT_SUCCESS(Status)) - { - DbgPrint("Unable to create virtual mapping\n"); - KEBUGCHECK(0); - } - } + FALSE); + if (!NT_SUCCESS(Status)) + { + DbgPrint("Unable to create virtual mapping\n"); + KEBUGCHECK(0); + } + } if (AccessMode == UserMode && CurrentProcess != OldProcess) - { - KeDetachProcess(); - } + { + KeDetachProcess(); + } /* Mark the MDL has having being mapped. */ Mdl->MdlFlags = Mdl->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA; @@ -273,62 +277,64 @@ MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl) * MemoryDescriptorList = MDL describing the mapped pages */ { - KIRQL oldIrql; - ULONG i; - ULONG RegionSize; - ULONG Base; - PEPROCESS CurrentProcess, OldProcess; + KIRQL oldIrql; + ULONG i; + ULONG RegionSize; + ULONG Base; + PEPROCESS CurrentProcess, OldProcess; - DPRINT("MmUnmapLockedPages(BaseAddress %x, Mdl %x)\n", BaseAddress, Mdl); + DPRINT("MmUnmapLockedPages(BaseAddress %x, Mdl %x)\n", BaseAddress, Mdl); - /* - * In this case, the MDL has the same system address as the base address - * so there is no need to free it - */ - if ((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) && - ((ULONG_PTR)BaseAddress >= KERNEL_BASE)) - { + /* + * In this case, the MDL has the same system address as the base address + * so there is no need to free it + */ + if ((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) && + ((ULONG_PTR)BaseAddress >= KERNEL_BASE)) + { return; - } + } - if ((ULONG_PTR)BaseAddress >= KERNEL_BASE) - { + if ((ULONG_PTR)BaseAddress >= KERNEL_BASE) + { CurrentProcess = OldProcess = NULL; - } - else - { + } + else + { CurrentProcess = OldProcess = PsGetCurrentProcess(); if (Mdl->Process != CurrentProcess) - { - KeAttachProcess(Mdl->Process); - CurrentProcess = Mdl->Process; - } - } + { + KeAttachProcess(Mdl->Process); + CurrentProcess = Mdl->Process; + } + } - /* Calculate the number of pages we mapped. */ - RegionSize = PAGE_ROUND_UP(Mdl->ByteCount + Mdl->ByteOffset) / PAGE_SIZE; + /* Calculate the number of pages we mapped. */ + RegionSize = PAGE_ROUND_UP(Mdl->ByteCount + Mdl->ByteOffset) / PAGE_SIZE; #if defined(__GNUC__) - BaseAddress -= Mdl->ByteOffset; + + BaseAddress -= Mdl->ByteOffset; #else - { - char* pTemp = BaseAddress; - pTemp -= Mdl->ByteOffset; - BaseAddress = pTemp; - } + + { + char* pTemp = BaseAddress; + pTemp -= Mdl->ByteOffset; + BaseAddress = pTemp; + } #endif - /* Unmap all the pages. */ - for (i = 0; i < RegionSize; i++) - { + /* Unmap all the pages. */ + for (i = 0; i < RegionSize; i++) + { MmDeleteVirtualMapping(NULL, - (char*)BaseAddress + (i * PAGE_SIZE), - FALSE, - NULL, - NULL); - } + (char*)BaseAddress + (i * PAGE_SIZE), + FALSE, + NULL, + NULL); + } - if ((DWORD)BaseAddress >= KERNEL_BASE) - { + if ((DWORD)BaseAddress >= KERNEL_BASE) + { KeAcquireSpinLock(&MiMdlMappingRegionLock, &oldIrql); /* Deallocate all the pages used. */ Base = (ULONG)((char*)BaseAddress - (char*)MiMdlMappingRegionBase) / PAGE_SIZE; @@ -338,55 +344,55 @@ MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl) MiMdlMappingRegionHint = min (MiMdlMappingRegionHint, Base); KeReleaseSpinLock(&MiMdlMappingRegionLock, oldIrql); - } - else - { + } + else + { MEMORY_AREA *Marea; Marea = MmOpenMemoryAreaByAddress( &CurrentProcess->AddressSpace, BaseAddress ); if (Marea == NULL) - { - DPRINT1( "Couldn't open memory area when unmapping user-space pages!\n" ); - KEBUGCHECK(0); - } + { + DPRINT1( "Couldn't open memory area when unmapping user-space pages!\n" ); + KEBUGCHECK(0); + } MmFreeMemoryArea( &CurrentProcess->AddressSpace, Marea->BaseAddress, 0, NULL, NULL ); if (CurrentProcess != OldProcess) - { - KeDetachProcess(); - } - } + { + KeDetachProcess(); + } + } - /* Reset the MDL state. */ - Mdl->MdlFlags = Mdl->MdlFlags & ~MDL_MAPPED_TO_SYSTEM_VA; - Mdl->MappedSystemVa = NULL; + /* Reset the MDL state. */ + Mdl->MdlFlags = Mdl->MdlFlags & ~MDL_MAPPED_TO_SYSTEM_VA; + Mdl->MappedSystemVa = NULL; } -VOID +VOID MmBuildMdlFromPages(PMDL Mdl, PULONG Pages) { ULONG i; PULONG MdlPages; - - Mdl->MdlFlags = Mdl->MdlFlags | - (MDL_PAGES_LOCKED | MDL_IO_PAGE_READ); - + + Mdl->MdlFlags = Mdl->MdlFlags | + (MDL_PAGES_LOCKED | MDL_IO_PAGE_READ); + MdlPages = (PULONG)(Mdl + 1); - + for (i=0;i<(PAGE_ROUND_UP(Mdl->ByteOffset+Mdl->ByteCount)/PAGE_SIZE);i++) - { - MdlPages[i] = Pages[i]; - } + { + MdlPages[i] = Pages[i]; + } } /* * @unimplemented */ VOID STDCALL MmProbeAndLockPages (PMDL Mdl, - KPROCESSOR_MODE AccessMode, - LOCK_OPERATION Operation) + KPROCESSOR_MODE AccessMode, + LOCK_OPERATION Operation) /* * FUNCTION: Probes the specified pages, makes them resident and locks them * ARGUMENTS: @@ -403,106 +409,113 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl, PEPROCESS CurrentProcess = NULL; DPRINT("MmProbeAndLockPages(Mdl %x)\n", Mdl); - + /* * FIXME: Check behaviour against NT */ if (Mdl->MdlFlags & MDL_PAGES_LOCKED) - { - return; - } - + { + return; + } + if (Mdl->StartVa >= (PVOID)KERNEL_BASE) - { - Mode = KernelMode; - } + { + Mode = KernelMode; + } else - { - Mode = UserMode; - CurrentProcess = PsGetCurrentProcess(); - if (Mdl->Process != CurrentProcess) - { - KeAttachProcess(Mdl->Process); - } - } + { + Mode = UserMode; + CurrentProcess = PsGetCurrentProcess(); + if (Mdl->Process != CurrentProcess) + { + KeAttachProcess(Mdl->Process); + } + } /* * Lock the pages */ MmLockAddressSpace(&Mdl->Process->AddressSpace); - MdlPages = (ULONG *)(Mdl + 1); + MdlPages = (ULONG *)(Mdl + 1); NrPages = PAGE_ROUND_UP(Mdl->ByteOffset + Mdl->ByteCount) / PAGE_SIZE; for (i = 0; i < NrPages; i++) - { - PVOID Address; - - Address = (char*)Mdl->StartVa + (i*PAGE_SIZE); - - if (!MmIsPagePresent(NULL, Address)) - { - Status = MmNotPresentFault(Mode, (ULONG)Address, TRUE); - if (!NT_SUCCESS(Status)) - { - for (j = 0; j < i; j++) - { + { + PVOID Address; + + Address = (char*)Mdl->StartVa + (i*PAGE_SIZE); + + if (!MmIsPagePresent(NULL, Address)) + { + Status = MmNotPresentFault(Mode, (ULONG)Address, TRUE); + if (!NT_SUCCESS(Status)) + { + for (j = 0; j < i; j++) + { #if defined(__GNUC__) - MmUnlockPage((LARGE_INTEGER)(LONGLONG)MdlPages[j]); - MmDereferencePage((LARGE_INTEGER)(LONGLONG)MdlPages[j]); + MmUnlockPage((LARGE_INTEGER)(LONGLONG)MdlPages[j]); + MmDereferencePage((LARGE_INTEGER)(LONGLONG)MdlPages[j]); #else - PHYSICAL_ADDRESS dummyJunkNeeded; - dummyJunkNeeded.QuadPart = MdlPages[j]; - MmUnlockPage(dummyJunkNeeded); - MmDereferencePage(dummyJunkNeeded); + + PHYSICAL_ADDRESS dummyJunkNeeded; + dummyJunkNeeded.QuadPart = MdlPages[j]; + MmUnlockPage(dummyJunkNeeded); + MmDereferencePage(dummyJunkNeeded); #endif - } - ExRaiseStatus(Status); - } - } - else - { - MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address)); - } - if ((Operation == IoWriteAccess || Operation == IoModifyAccess) && - (!(MmGetPageProtect(NULL, (PVOID)Address) & PAGE_READWRITE))) - { - Status = MmAccessFault(Mode, (ULONG)Address, TRUE); - if (!NT_SUCCESS(Status)) - { - for (j = 0; j < i; j++) - { + + } + ExRaiseStatus(Status); + } + } + else + { + MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address)); + } + if ((Operation == IoWriteAccess || Operation == IoModifyAccess) && + (!(MmGetPageProtect(NULL, (PVOID)Address) & PAGE_READWRITE))) + { + Status = MmAccessFault(Mode, (ULONG)Address, TRUE); + if (!NT_SUCCESS(Status)) + { + for (j = 0; j < i; j++) + { #if defined(__GNUC__) - MmUnlockPage((LARGE_INTEGER)(LONGLONG)MdlPages[j]); - MmDereferencePage( - (LARGE_INTEGER)(LONGLONG)MdlPages[j]); + MmUnlockPage((LARGE_INTEGER)(LONGLONG)MdlPages[j]); + MmDereferencePage( + (LARGE_INTEGER)(LONGLONG)MdlPages[j]); #else - PHYSICAL_ADDRESS dummyJunkNeeded; - dummyJunkNeeded.QuadPart = MdlPages[j]; - MmUnlockPage(dummyJunkNeeded); - MmDereferencePage(dummyJunkNeeded); + + PHYSICAL_ADDRESS dummyJunkNeeded; + dummyJunkNeeded.QuadPart = MdlPages[j]; + MmUnlockPage(dummyJunkNeeded); + MmDereferencePage(dummyJunkNeeded); #endif - } - ExRaiseStatus(Status); - } - } - MdlPages[i] = MmGetPhysicalAddressForProcess(NULL, Address).u.LowPart; + + } + ExRaiseStatus(Status); + } + } + MdlPages[i] = MmGetPhysicalAddressForProcess(NULL, Address).u.LowPart; #if defined(__GNUC__) - MmReferencePage((LARGE_INTEGER)(LONGLONG)MdlPages[i]); + + MmReferencePage((LARGE_INTEGER)(LONGLONG)MdlPages[i]); #else - { - PHYSICAL_ADDRESS dummyJunkNeeded; - dummyJunkNeeded.QuadPart = MdlPages[i]; - MmReferencePage(dummyJunkNeeded); - } + + { + PHYSICAL_ADDRESS dummyJunkNeeded; + dummyJunkNeeded.QuadPart = MdlPages[i]; + MmReferencePage(dummyJunkNeeded); + } #endif - } + + } MmUnlockAddressSpace(&Mdl->Process->AddressSpace); if (Mode == UserMode && Mdl->Process != CurrentProcess) - { - KeDetachProcess(); - } + { + KeDetachProcess(); + } Mdl->MdlFlags = Mdl->MdlFlags | MDL_PAGES_LOCKED; } @@ -510,8 +523,8 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl, /* * @implemented */ -ULONG STDCALL MmSizeOfMdl (PVOID Base, - ULONG Length) +ULONG STDCALL MmSizeOfMdl (PVOID Base, + ULONG Length) /* * FUNCTION: Returns the number of bytes to allocate for an MDL describing * the given address range @@ -521,9 +534,9 @@ ULONG STDCALL MmSizeOfMdl (PVOID Base, */ { ULONG len; - + len = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base,Length); - + return(sizeof(MDL)+(len*sizeof(ULONG))); } @@ -531,8 +544,8 @@ ULONG STDCALL MmSizeOfMdl (PVOID Base, /* * @implemented */ -VOID STDCALL -MmBuildMdlForNonPagedPool (PMDL Mdl) +VOID STDCALL +MmBuildMdlForNonPagedPool (PMDL Mdl) /* * FUNCTION: Fills in the corresponding physical page array of a given * MDL for a buffer in nonpaged system space @@ -542,13 +555,13 @@ MmBuildMdlForNonPagedPool (PMDL Mdl) */ { ULONG va; - Mdl->MdlFlags = Mdl->MdlFlags | - (MDL_SOURCE_IS_NONPAGED_POOL | MDL_PAGES_LOCKED); + Mdl->MdlFlags = Mdl->MdlFlags | + (MDL_SOURCE_IS_NONPAGED_POOL | MDL_PAGES_LOCKED); for (va=0; va < ((Mdl->Size - sizeof(MDL)) / sizeof(ULONG)); va++) - { - ((PULONG)(Mdl + 1))[va] = - (MmGetPhysicalAddress((char*)Mdl->StartVa + (va * PAGE_SIZE))).u.LowPart; - } + { + ((PULONG)(Mdl + 1))[va] = + (MmGetPhysicalAddress((char*)Mdl->StartVa + (va * PAGE_SIZE))).u.LowPart; + } Mdl->MappedSystemVa = (char*)Mdl->StartVa + Mdl->ByteOffset; } @@ -556,10 +569,10 @@ MmBuildMdlForNonPagedPool (PMDL Mdl) /* * @implemented */ -PMDL STDCALL -MmCreateMdl (PMDL MemoryDescriptorList, - PVOID Base, - ULONG Length) +PMDL STDCALL +MmCreateMdl (PMDL MemoryDescriptorList, + PVOID Base, + ULONG Length) /* * FUNCTION: Allocates and initalizes an MDL * ARGUMENTS: @@ -571,17 +584,17 @@ MmCreateMdl (PMDL MemoryDescriptorList, */ { if (MemoryDescriptorList == NULL) - { - ULONG Size; - - Size = MmSizeOfMdl(Base,Length); - MemoryDescriptorList = - (PMDL)ExAllocatePoolWithTag(NonPagedPool, Size, TAG_MDL); - if (MemoryDescriptorList == NULL) - { - return(NULL); - } - } + { + ULONG Size; + + Size = MmSizeOfMdl(Base,Length); + MemoryDescriptorList = + (PMDL)ExAllocatePoolWithTag(NonPagedPool, Size, TAG_MDL); + if (MemoryDescriptorList == NULL) + { + return(NULL); + } + } MmInitializeMdl(MemoryDescriptorList, (char*)Base, Length); @@ -591,8 +604,8 @@ MmCreateMdl (PMDL MemoryDescriptorList, /* * @unimplemented */ -VOID STDCALL -MmMapMemoryDumpMdl (PVOID Unknown0) +VOID STDCALL +MmMapMemoryDumpMdl (PVOID Unknown0) /* * FIXME: Has something to do with crash dumps. Do we want to implement * this? @@ -603,30 +616,30 @@ MmMapMemoryDumpMdl (PVOID Unknown0) PMDL STDCALL MmAllocatePagesForMdl ( IN PHYSICAL_ADDRESS LowAddress, - IN PHYSICAL_ADDRESS HighAddress, - IN PHYSICAL_ADDRESS SkipBytes, - IN SIZE_T Totalbytes ) + IN PHYSICAL_ADDRESS HighAddress, + IN PHYSICAL_ADDRESS SkipBytes, + IN SIZE_T Totalbytes ) { - DPRINT1("MmAllocatePagesForMdl(): Unimplemented.\n"); - return(NULL); + DPRINT1("MmAllocatePagesForMdl(): Unimplemented.\n"); + return(NULL); } VOID STDCALL MmFreePagesFromMdl ( IN PMDL Mdl ) { - DPRINT1("MmFreePagesFromMdl(): Unimplemented.\n"); + DPRINT1("MmFreePagesFromMdl(): Unimplemented.\n"); } PVOID STDCALL MmMapLockedPagesSpecifyCache ( IN PMDL Mdl, - IN KPROCESSOR_MODE AccessMode, - IN MEMORY_CACHING_TYPE CacheType, - IN PVOID BaseAddress, - IN ULONG BugCheckOnFailure, - IN ULONG Priority ) + IN KPROCESSOR_MODE AccessMode, + IN MEMORY_CACHING_TYPE CacheType, + IN PVOID BaseAddress, + IN ULONG BugCheckOnFailure, + IN ULONG Priority ) { - DPRINT1("MmMapLockedPagesSpecifyCache(): Ignoring extra parameters.\n"); - return MmMapLockedPages (Mdl, AccessMode); + DPRINT1("MmMapLockedPagesSpecifyCache(): Ignoring extra parameters.\n"); + return MmMapLockedPages (Mdl, AccessMode); } /* EOF */ diff --git a/reactos/ntoskrnl/mm/mm.c b/reactos/ntoskrnl/mm/mm.c index b843e5bedbf..a9f453080f2 100644 --- a/reactos/ntoskrnl/mm/mm.c +++ b/reactos/ntoskrnl/mm/mm.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: mm.c,v 1.72 2004/04/08 20:49:15 jfilby Exp $ +/* $Id: mm.c,v 1.73 2004/04/10 22:35:25 gdalsnes Exp $ * * COPYRIGHT: See COPYING in the top directory * PROJECT: ReactOS kernel @@ -53,41 +53,41 @@ MM_STATS MmStats; NTSTATUS MmReleaseMemoryArea(PEPROCESS Process, PMEMORY_AREA Marea) { NTSTATUS Status; - + DPRINT("MmReleaseMemoryArea(Process %x, Marea %x)\n",Process,Marea); - + DPRINT("Releasing %x between %x %x (type %d)\n", - Marea, Marea->BaseAddress, (char*)Marea->BaseAddress + Marea->Length, - Marea->Type); - + Marea, Marea->BaseAddress, (char*)Marea->BaseAddress + Marea->Length, + Marea->Type); + switch (Marea->Type) - { - case MEMORY_AREA_SECTION_VIEW: - Status = MmUnmapViewOfSection(Process, Marea->BaseAddress); - assert(Status == STATUS_SUCCESS); - return(STATUS_SUCCESS); + { + case MEMORY_AREA_SECTION_VIEW: + Status = MmUnmapViewOfSection(Process, Marea->BaseAddress); + assert(Status == STATUS_SUCCESS); + return(STATUS_SUCCESS); - case MEMORY_AREA_VIRTUAL_MEMORY: - MmFreeVirtualMemory(Process, Marea); - break; + case MEMORY_AREA_VIRTUAL_MEMORY: + MmFreeVirtualMemory(Process, Marea); + break; - case MEMORY_AREA_SHARED_DATA: - case MEMORY_AREA_NO_ACCESS: - Status = MmFreeMemoryArea(&Process->AddressSpace, - Marea->BaseAddress, - 0, - NULL, - NULL); - break; + case MEMORY_AREA_SHARED_DATA: + case MEMORY_AREA_NO_ACCESS: + Status = MmFreeMemoryArea(&Process->AddressSpace, + Marea->BaseAddress, + 0, + NULL, + NULL); + break; - case MEMORY_AREA_MDL_MAPPING: - KEBUGCHECK(PROCESS_HAS_LOCKED_PAGES); - break; + case MEMORY_AREA_MDL_MAPPING: + KEBUGCHECK(PROCESS_HAS_LOCKED_PAGES); + break; + + default: + KEBUGCHECK(0); + } - default: - KEBUGCHECK(0); - } - return(STATUS_SUCCESS); } @@ -95,24 +95,24 @@ NTSTATUS MmReleaseMmInfo(PEPROCESS Process) { PLIST_ENTRY CurrentEntry; PMEMORY_AREA Current; - + DPRINT("MmReleaseMmInfo(Process %x (%s))\n", Process, - Process->ImageFileName); - + Process->ImageFileName); + MmLockAddressSpace(&Process->AddressSpace); while(!IsListEmpty(&Process->AddressSpace.MAreaListHead)) - { - CurrentEntry = Process->AddressSpace.MAreaListHead.Flink; - Current = CONTAINING_RECORD(CurrentEntry, MEMORY_AREA, Entry); - MmReleaseMemoryArea(Process, Current); - } - + { + CurrentEntry = Process->AddressSpace.MAreaListHead.Flink; + Current = CONTAINING_RECORD(CurrentEntry, MEMORY_AREA, Entry); + MmReleaseMemoryArea(Process, Current); + } + Mmi386ReleaseMmInfo(Process); - + MmUnlockAddressSpace(&Process->AddressSpace); MmDestroyAddressSpace(&Process->AddressSpace); - + DPRINT("Finished MmReleaseMmInfo()\n"); return(STATUS_SUCCESS); } @@ -142,282 +142,282 @@ BOOLEAN STDCALL MmIsAddressValid(PVOID VirtualAddress) { MEMORY_AREA* MemoryArea; PMADDRESS_SPACE AddressSpace; - + if ((ULONG)VirtualAddress >= KERNEL_BASE) - { - AddressSpace = MmGetKernelAddressSpace(); - } + { + AddressSpace = MmGetKernelAddressSpace(); + } else - { - AddressSpace = &PsGetCurrentProcess()->AddressSpace; - } - + { + AddressSpace = &PsGetCurrentProcess()->AddressSpace; + } + MmLockAddressSpace(AddressSpace); MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, - VirtualAddress); - + VirtualAddress); + if (MemoryArea == NULL || MemoryArea->DeleteInProgress) - { - MmUnlockAddressSpace(AddressSpace); - return(FALSE); - } + { + MmUnlockAddressSpace(AddressSpace); + return(FALSE); + } MmUnlockAddressSpace(AddressSpace); return(TRUE); } NTSTATUS MmAccessFault(KPROCESSOR_MODE Mode, - ULONG Address, - BOOLEAN FromMdl) + ULONG Address, + BOOLEAN FromMdl) { PMADDRESS_SPACE AddressSpace; MEMORY_AREA* MemoryArea; NTSTATUS Status; BOOLEAN Locked = FromMdl; - + DPRINT("MmAccessFault(Mode %d, Address %x)\n", Mode, Address); - + if (KeGetCurrentIrql() >= DISPATCH_LEVEL) - { - DbgPrint("Page fault at high IRQL was %d\n", KeGetCurrentIrql()); - return(STATUS_UNSUCCESSFUL); - } + { + DbgPrint("Page fault at high IRQL was %d\n", KeGetCurrentIrql()); + return(STATUS_UNSUCCESSFUL); + } if (PsGetCurrentProcess() == NULL) - { - DbgPrint("No current process\n"); - return(STATUS_UNSUCCESSFUL); - } - + { + DbgPrint("No current process\n"); + return(STATUS_UNSUCCESSFUL); + } + /* * Find the memory area for the faulting address */ if (Address >= KERNEL_BASE) - { - /* - * Check permissions - */ - if (Mode != KernelMode) - { - DbgPrint("%s:%d\n",__FILE__,__LINE__); - return(STATUS_UNSUCCESSFUL); - } - AddressSpace = MmGetKernelAddressSpace(); - } + { + /* + * Check permissions + */ + if (Mode != KernelMode) + { + DbgPrint("%s:%d\n",__FILE__,__LINE__); + return(STATUS_UNSUCCESSFUL); + } + AddressSpace = MmGetKernelAddressSpace(); + } else - { - AddressSpace = &PsGetCurrentProcess()->AddressSpace; - } - + { + AddressSpace = &PsGetCurrentProcess()->AddressSpace; + } + if (!FromMdl) - { - MmLockAddressSpace(AddressSpace); - } + { + MmLockAddressSpace(AddressSpace); + } do - { - MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, (PVOID)Address); - if (MemoryArea == NULL || MemoryArea->DeleteInProgress) - { - if (!FromMdl) - { - MmUnlockAddressSpace(AddressSpace); - } - return (STATUS_UNSUCCESSFUL); - } - - switch (MemoryArea->Type) - { - case MEMORY_AREA_SYSTEM: - Status = STATUS_UNSUCCESSFUL; - break; + { + MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, (PVOID)Address); + if (MemoryArea == NULL || MemoryArea->DeleteInProgress) + { + if (!FromMdl) + { + MmUnlockAddressSpace(AddressSpace); + } + return (STATUS_UNSUCCESSFUL); + } - case MEMORY_AREA_PAGED_POOL: - Status = STATUS_SUCCESS; - break; + switch (MemoryArea->Type) + { + case MEMORY_AREA_SYSTEM: + Status = STATUS_UNSUCCESSFUL; + break; - case MEMORY_AREA_SECTION_VIEW: - Status = MmAccessFaultSectionView(AddressSpace, - MemoryArea, - (PVOID)Address, - Locked); - break; + case MEMORY_AREA_PAGED_POOL: + Status = STATUS_SUCCESS; + break; - case MEMORY_AREA_VIRTUAL_MEMORY: - Status = STATUS_UNSUCCESSFUL; - break; + case MEMORY_AREA_SECTION_VIEW: + Status = MmAccessFaultSectionView(AddressSpace, + MemoryArea, + (PVOID)Address, + Locked); + break; - case MEMORY_AREA_SHARED_DATA: - Status = STATUS_UNSUCCESSFUL; - break; + case MEMORY_AREA_VIRTUAL_MEMORY: + Status = STATUS_UNSUCCESSFUL; + break; - default: - Status = STATUS_UNSUCCESSFUL; - break; - } - } + case MEMORY_AREA_SHARED_DATA: + Status = STATUS_UNSUCCESSFUL; + break; + + default: + Status = STATUS_UNSUCCESSFUL; + break; + } + } while (Status == STATUS_MM_RESTART_OPERATION); DPRINT("Completed page fault handling\n"); if (!FromMdl) - { - MmUnlockAddressSpace(AddressSpace); - } + { + MmUnlockAddressSpace(AddressSpace); + } return(Status); } NTSTATUS MmCommitPagedPoolAddress(PVOID Address, BOOLEAN Locked) { - NTSTATUS Status; - PHYSICAL_ADDRESS AllocatedPage; - Status = MmRequestPageMemoryConsumer(MC_PPOOL, FALSE, &AllocatedPage); - if (!NT_SUCCESS(Status)) - { + NTSTATUS Status; + PHYSICAL_ADDRESS AllocatedPage; + Status = MmRequestPageMemoryConsumer(MC_PPOOL, FALSE, &AllocatedPage); + if (!NT_SUCCESS(Status)) + { MmUnlockAddressSpace(MmGetKernelAddressSpace()); Status = MmRequestPageMemoryConsumer(MC_PPOOL, TRUE, &AllocatedPage); MmLockAddressSpace(MmGetKernelAddressSpace()); - } - Status = - MmCreateVirtualMapping(NULL, - (PVOID)PAGE_ROUND_DOWN(Address), - PAGE_READWRITE, - AllocatedPage, - FALSE); - if (!NT_SUCCESS(Status)) - { + } + Status = + MmCreateVirtualMapping(NULL, + (PVOID)PAGE_ROUND_DOWN(Address), + PAGE_READWRITE, + AllocatedPage, + FALSE); + if (!NT_SUCCESS(Status)) + { MmUnlockAddressSpace(MmGetKernelAddressSpace()); - Status = - MmCreateVirtualMapping(NULL, - (PVOID)PAGE_ROUND_DOWN(Address), - PAGE_READWRITE, - AllocatedPage, - FALSE); + Status = + MmCreateVirtualMapping(NULL, + (PVOID)PAGE_ROUND_DOWN(Address), + PAGE_READWRITE, + AllocatedPage, + FALSE); MmLockAddressSpace(MmGetKernelAddressSpace()); - } - if (Locked) - { + } + if (Locked) + { MmLockPage(AllocatedPage); - } - return(Status); + } + return(Status); } NTSTATUS MmNotPresentFault(KPROCESSOR_MODE Mode, - ULONG Address, - BOOLEAN FromMdl) + ULONG Address, + BOOLEAN FromMdl) { PMADDRESS_SPACE AddressSpace; MEMORY_AREA* MemoryArea; NTSTATUS Status; BOOLEAN Locked = FromMdl; - + DPRINT("MmNotPresentFault(Mode %d, Address %x)\n", Mode, Address); - + if (KeGetCurrentIrql() >= DISPATCH_LEVEL) - { - DbgPrint("Page fault at high IRQL was %d\n", KeGetCurrentIrql()); - return(STATUS_UNSUCCESSFUL); - } + { + DbgPrint("Page fault at high IRQL was %d\n", KeGetCurrentIrql()); + return(STATUS_UNSUCCESSFUL); + } if (PsGetCurrentProcess() == NULL) - { - DbgPrint("No current process\n"); - return(STATUS_UNSUCCESSFUL); - } - + { + DbgPrint("No current process\n"); + return(STATUS_UNSUCCESSFUL); + } + /* * Find the memory area for the faulting address */ if (Address >= KERNEL_BASE) - { - /* - * Check permissions - */ - if (Mode != KernelMode) - { - DbgPrint("%s:%d\n",__FILE__,__LINE__); - return(STATUS_UNSUCCESSFUL); - } - AddressSpace = MmGetKernelAddressSpace(); - } + { + /* + * Check permissions + */ + if (Mode != KernelMode) + { + DbgPrint("%s:%d\n",__FILE__,__LINE__); + return(STATUS_UNSUCCESSFUL); + } + AddressSpace = MmGetKernelAddressSpace(); + } else - { - AddressSpace = &PsGetCurrentProcess()->AddressSpace; - } - + { + AddressSpace = &PsGetCurrentProcess()->AddressSpace; + } + if (!FromMdl) - { - MmLockAddressSpace(AddressSpace); - } + { + MmLockAddressSpace(AddressSpace); + } /* * Call the memory area specific fault handler */ do - { - MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, (PVOID)Address); - if (MemoryArea == NULL || MemoryArea->DeleteInProgress) - { - if (!FromMdl) - { - MmUnlockAddressSpace(AddressSpace); - } - return (STATUS_UNSUCCESSFUL); - } + { + MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, (PVOID)Address); + if (MemoryArea == NULL || MemoryArea->DeleteInProgress) + { + if (!FromMdl) + { + MmUnlockAddressSpace(AddressSpace); + } + return (STATUS_UNSUCCESSFUL); + } - switch (MemoryArea->Type) - { - case MEMORY_AREA_PAGED_POOL: - { - Status = MmCommitPagedPoolAddress((PVOID)Address, Locked); - break; - } + switch (MemoryArea->Type) + { + case MEMORY_AREA_PAGED_POOL: + { + Status = MmCommitPagedPoolAddress((PVOID)Address, Locked); + break; + } - case MEMORY_AREA_SYSTEM: - Status = STATUS_UNSUCCESSFUL; - break; - - case MEMORY_AREA_SECTION_VIEW: - Status = MmNotPresentFaultSectionView(AddressSpace, - MemoryArea, - (PVOID)Address, - Locked); - break; - - case MEMORY_AREA_VIRTUAL_MEMORY: - Status = MmNotPresentFaultVirtualMemory(AddressSpace, - MemoryArea, - (PVOID)Address, - Locked); - break; - - case MEMORY_AREA_SHARED_DATA: - Status = - MmCreateVirtualMapping(PsGetCurrentProcess(), - (PVOID)PAGE_ROUND_DOWN(Address), - PAGE_READONLY, - MmSharedDataPagePhysicalAddress, - FALSE); - if (!NT_SUCCESS(Status)) - { - MmUnlockAddressSpace(&PsGetCurrentProcess()->AddressSpace); - Status = - MmCreateVirtualMapping(PsGetCurrentProcess(), - (PVOID)PAGE_ROUND_DOWN(Address), - PAGE_READONLY, - MmSharedDataPagePhysicalAddress, - TRUE); - MmLockAddressSpace(&PsGetCurrentProcess()->AddressSpace); - } - break; - - default: - Status = STATUS_UNSUCCESSFUL; - break; - } - } + case MEMORY_AREA_SYSTEM: + Status = STATUS_UNSUCCESSFUL; + break; + + case MEMORY_AREA_SECTION_VIEW: + Status = MmNotPresentFaultSectionView(AddressSpace, + MemoryArea, + (PVOID)Address, + Locked); + break; + + case MEMORY_AREA_VIRTUAL_MEMORY: + Status = MmNotPresentFaultVirtualMemory(AddressSpace, + MemoryArea, + (PVOID)Address, + Locked); + break; + + case MEMORY_AREA_SHARED_DATA: + Status = + MmCreateVirtualMapping(PsGetCurrentProcess(), + (PVOID)PAGE_ROUND_DOWN(Address), + PAGE_READONLY, + MmSharedDataPagePhysicalAddress, + FALSE); + if (!NT_SUCCESS(Status)) + { + MmUnlockAddressSpace(&PsGetCurrentProcess()->AddressSpace); + Status = + MmCreateVirtualMapping(PsGetCurrentProcess(), + (PVOID)PAGE_ROUND_DOWN(Address), + PAGE_READONLY, + MmSharedDataPagePhysicalAddress, + TRUE); + MmLockAddressSpace(&PsGetCurrentProcess()->AddressSpace); + } + break; + + default: + Status = STATUS_UNSUCCESSFUL; + break; + } + } while (Status == STATUS_MM_RESTART_OPERATION); DPRINT("Completed page fault handling\n"); if (!FromMdl) - { - MmUnlockAddressSpace(AddressSpace); - } + { + MmUnlockAddressSpace(AddressSpace); + } return(Status); } @@ -427,24 +427,24 @@ NTSTATUS MmNotPresentFault(KPROCESSOR_MODE Mode, * @unimplemented */ DWORD STDCALL -MmAdjustWorkingSetSize (DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2) +MmAdjustWorkingSetSize (DWORD Unknown0, + DWORD Unknown1, + DWORD Unknown2) { - UNIMPLEMENTED; - return (0); + UNIMPLEMENTED; + return (0); } DWORD STDCALL MmDbgTranslatePhysicalAddress ( - DWORD Unknown0, - DWORD Unknown1 - ) + DWORD Unknown0, + DWORD Unknown1 +) { - UNIMPLEMENTED; - return (0); + UNIMPLEMENTED; + return (0); } @@ -454,11 +454,11 @@ MmDbgTranslatePhysicalAddress ( NTSTATUS STDCALL MmGrowKernelStack ( - DWORD Unknown0 - ) + DWORD Unknown0 +) { - UNIMPLEMENTED; - return (STATUS_NOT_IMPLEMENTED); + UNIMPLEMENTED; + return (STATUS_NOT_IMPLEMENTED); } @@ -468,12 +468,12 @@ MmGrowKernelStack ( BOOLEAN STDCALL MmSetAddressRangeModified ( - DWORD Unknown0, - DWORD Unknown1 - ) + DWORD Unknown0, + DWORD Unknown1 +) { - UNIMPLEMENTED; - return (FALSE); + UNIMPLEMENTED; + return (FALSE); } /* EOF */ diff --git a/reactos/ntoskrnl/mm/mminit.c b/reactos/ntoskrnl/mm/mminit.c index 10e43f6bf0a..ddc238d04d4 100644 --- a/reactos/ntoskrnl/mm/mminit.c +++ b/reactos/ntoskrnl/mm/mminit.c @@ -1,4 +1,4 @@ -/* $Id: mminit.c,v 1.62 2004/03/16 22:45:56 dwelch Exp $ +/* $Id: mminit.c,v 1.63 2004/04/10 22:35:25 gdalsnes Exp $ * * COPYRIGHT: See COPYING in the top directory * PROJECT: ReactOS kernel @@ -48,7 +48,7 @@ static MEMORY_AREA* kernel_data_desc = NULL; static MEMORY_AREA* kernel_param_desc = NULL; static MEMORY_AREA* kernel_pool_desc = NULL; static MEMORY_AREA* kernel_shared_data_desc = NULL; -static MEMORY_AREA* kernel_mapped_vga_framebuffer_desc = NULL; +static MEMORY_AREA* kernel_mapped_vga_framebuffer_desc = NULL; static MEMORY_AREA* MiKernelMapDescriptor = NULL; static MEMORY_AREA* MiPagedPoolDescriptor = NULL; @@ -78,12 +78,11 @@ MM_SYSTEM_SIZE STDCALL MmQuerySystemSize(VOID) } VOID MiShutdownMemoryManager(VOID) -{ -} +{} VOID INIT_FUNCTION MmInitVirtualMemory(ULONG LastKernelAddress, - ULONG KernelLength) + ULONG KernelLength) /* * FUNCTION: Intialize the memory areas list * ARGUMENTS: @@ -97,9 +96,9 @@ MmInitVirtualMemory(ULONG LastKernelAddress, NTSTATUS Status; PHYSICAL_ADDRESS BoundaryAddressMultiple; //ULONG i; - + DPRINT("MmInitVirtualMemory(%x, %x)\n",LastKernelAddress, KernelLength); - + BoundaryAddressMultiple.QuadPart = 0; LastKernelAddress = PAGE_ROUND_UP(LastKernelAddress); @@ -124,58 +123,58 @@ MmInitVirtualMemory(ULONG LastKernelAddress, */ BaseAddress = (PVOID)0xf0000000; MmCreateMemoryArea(NULL, - MmGetKernelAddressSpace(), - MEMORY_AREA_SYSTEM, - &BaseAddress, - 0x400000, - 0, - &kernel_map_desc, - FALSE, - FALSE, - BoundaryAddressMultiple); + MmGetKernelAddressSpace(), + MEMORY_AREA_SYSTEM, + &BaseAddress, + 0x400000, + 0, + &kernel_map_desc, + FALSE, + FALSE, + BoundaryAddressMultiple); BaseAddress = (PVOID)KPCR_BASE; MmCreateMemoryArea(NULL, - MmGetKernelAddressSpace(), - MEMORY_AREA_SYSTEM, - &BaseAddress, - PAGE_SIZE * MAXIMUM_PROCESSORS, - 0, - &kernel_kpcr_desc, - FALSE, - FALSE, - BoundaryAddressMultiple); + MmGetKernelAddressSpace(), + MEMORY_AREA_SYSTEM, + &BaseAddress, + PAGE_SIZE * MAXIMUM_PROCESSORS, + 0, + &kernel_kpcr_desc, + FALSE, + FALSE, + BoundaryAddressMultiple); BaseAddress = (PVOID)0xFF3A0000; MmCreateMemoryArea(NULL, - MmGetKernelAddressSpace(), - MEMORY_AREA_SYSTEM, - &BaseAddress, - 0x20000, - 0, - &kernel_mapped_vga_framebuffer_desc, - FALSE, - FALSE, - BoundaryAddressMultiple); + MmGetKernelAddressSpace(), + MEMORY_AREA_SYSTEM, + &BaseAddress, + 0x20000, + 0, + &kernel_mapped_vga_framebuffer_desc, + FALSE, + FALSE, + BoundaryAddressMultiple); BaseAddress = (PVOID)KERNEL_BASE; Length = PAGE_ROUND_UP(((ULONG)&_text_end__)) - KERNEL_BASE; ParamLength = ParamLength - Length; - + /* * No need to lock the address space at this point since no * other threads are running. */ MmCreateMemoryArea(NULL, - MmGetKernelAddressSpace(), - MEMORY_AREA_SYSTEM, - &BaseAddress, - Length, - 0, - &kernel_text_desc, - FALSE, - FALSE, - BoundaryAddressMultiple); + MmGetKernelAddressSpace(), + MEMORY_AREA_SYSTEM, + &BaseAddress, + Length, + 0, + &kernel_text_desc, + FALSE, + FALSE, + BoundaryAddressMultiple); BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&_text_end__)); assert (BaseAddress == (PVOID)&_init_start__); @@ -184,17 +183,17 @@ MmInitVirtualMemory(ULONG LastKernelAddress, ParamLength = ParamLength - Length; MmCreateMemoryArea(NULL, - MmGetKernelAddressSpace(), - MEMORY_AREA_SYSTEM, - &BaseAddress, - Length, - 0, - &kernel_init_desc, - FALSE, - FALSE, - BoundaryAddressMultiple); + MmGetKernelAddressSpace(), + MEMORY_AREA_SYSTEM, + &BaseAddress, + Length, + 0, + &kernel_init_desc, + FALSE, + FALSE, + BoundaryAddressMultiple); - Length = PAGE_ROUND_UP(((ULONG)&_bss_end__)) - + Length = PAGE_ROUND_UP(((ULONG)&_bss_end__)) - PAGE_ROUND_UP(((ULONG)&_init_end__)); ParamLength = ParamLength - Length; DPRINT("Length %x\n",Length); @@ -206,64 +205,64 @@ MmInitVirtualMemory(ULONG LastKernelAddress, * the only thread running. */ MmCreateMemoryArea(NULL, - MmGetKernelAddressSpace(), - MEMORY_AREA_SYSTEM, - &BaseAddress, - Length, - 0, - &kernel_data_desc, - FALSE, - FALSE, - BoundaryAddressMultiple); + MmGetKernelAddressSpace(), + MEMORY_AREA_SYSTEM, + &BaseAddress, + Length, + 0, + &kernel_data_desc, + FALSE, + FALSE, + BoundaryAddressMultiple); BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&_bss_end__)); Length = LastKernelAddress - (ULONG)BaseAddress; MmCreateMemoryArea(NULL, - MmGetKernelAddressSpace(), - MEMORY_AREA_SYSTEM, - &BaseAddress, - Length, - 0, - &kernel_param_desc, - FALSE, - FALSE, - BoundaryAddressMultiple); - + MmGetKernelAddressSpace(), + MEMORY_AREA_SYSTEM, + &BaseAddress, + Length, + 0, + &kernel_param_desc, + FALSE, + FALSE, + BoundaryAddressMultiple); + BaseAddress = MiNonPagedPoolStart; MmCreateMemoryArea(NULL, - MmGetKernelAddressSpace(), - MEMORY_AREA_SYSTEM, - &BaseAddress, - MiNonPagedPoolLength, - 0, - &kernel_pool_desc, - FALSE, - FALSE, - BoundaryAddressMultiple); + MmGetKernelAddressSpace(), + MEMORY_AREA_SYSTEM, + &BaseAddress, + MiNonPagedPoolLength, + 0, + &kernel_pool_desc, + FALSE, + FALSE, + BoundaryAddressMultiple); BaseAddress = MiKernelMapStart; Status = MmCreateMemoryArea(NULL, - MmGetKernelAddressSpace(), - MEMORY_AREA_SYSTEM, - &BaseAddress, - MiKernelMapLength, - 0, - &MiKernelMapDescriptor, - FALSE, - FALSE, - BoundaryAddressMultiple); - + MmGetKernelAddressSpace(), + MEMORY_AREA_SYSTEM, + &BaseAddress, + MiKernelMapLength, + 0, + &MiKernelMapDescriptor, + FALSE, + FALSE, + BoundaryAddressMultiple); + BaseAddress = MmPagedPoolBase; Status = MmCreateMemoryArea(NULL, - MmGetKernelAddressSpace(), - MEMORY_AREA_PAGED_POOL, - &BaseAddress, - MmPagedPoolSize, - 0, - &MiPagedPoolDescriptor, - FALSE, - FALSE, - BoundaryAddressMultiple); + MmGetKernelAddressSpace(), + MEMORY_AREA_PAGED_POOL, + &BaseAddress, + MmPagedPoolSize, + 0, + &MiPagedPoolDescriptor, + FALSE, + FALSE, + BoundaryAddressMultiple); MmInitializePagedPool(); @@ -273,27 +272,27 @@ MmInitVirtualMemory(ULONG LastKernelAddress, BaseAddress = (PVOID)KI_USER_SHARED_DATA; Length = PAGE_SIZE; MmCreateMemoryArea(NULL, - MmGetKernelAddressSpace(), - MEMORY_AREA_SYSTEM, - &BaseAddress, - Length, - 0, - &kernel_shared_data_desc, - FALSE, - FALSE, - BoundaryAddressMultiple); - Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, - &MmSharedDataPagePhysicalAddress); + MmGetKernelAddressSpace(), + MEMORY_AREA_SYSTEM, + &BaseAddress, + Length, + 0, + &kernel_shared_data_desc, + FALSE, + FALSE, + BoundaryAddressMultiple); + Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, + &MmSharedDataPagePhysicalAddress); Status = MmCreateVirtualMapping(NULL, - (PVOID)KI_USER_SHARED_DATA, - PAGE_READWRITE, - MmSharedDataPagePhysicalAddress, - TRUE); + (PVOID)KI_USER_SHARED_DATA, + PAGE_READWRITE, + MmSharedDataPagePhysicalAddress, + TRUE); if (!NT_SUCCESS(Status)) - { - DbgPrint("Unable to create virtual mapping\n"); - KEBUGCHECK(0); - } + { + DbgPrint("Unable to create virtual mapping\n"); + KEBUGCHECK(0); + } RtlZeroMemory(BaseAddress, Length); /* @@ -304,11 +303,11 @@ MmInitVirtualMemory(ULONG LastKernelAddress, VOID INIT_FUNCTION MmInit1(ULONG FirstKrnlPhysAddr, - ULONG LastKrnlPhysAddr, - ULONG LastKernelAddress, - PADDRESS_RANGE BIOSMemoryMap, - ULONG AddressRangeCount, - ULONG MaxMem) + ULONG LastKrnlPhysAddr, + ULONG LastKernelAddress, + PADDRESS_RANGE BIOSMemoryMap, + ULONG AddressRangeCount, + ULONG MaxMem) /* * FUNCTION: Initalize memory managment */ @@ -316,37 +315,38 @@ MmInit1(ULONG FirstKrnlPhysAddr, ULONG i; ULONG kernel_len; #ifndef MP + extern unsigned int unmap_me, unmap_me2, unmap_me3; #endif DPRINT("MmInit1(FirstKrnlPhysAddr, %x, LastKrnlPhysAddr %x, LastKernelAddress %x)\n", - FirstKrnlPhysAddr, - LastKrnlPhysAddr, - LastKernelAddress); + FirstKrnlPhysAddr, + LastKrnlPhysAddr, + LastKernelAddress); if ((BIOSMemoryMap != NULL) && (AddressRangeCount > 0)) - { - // If we have a bios memory map, recalulate the memory size - ULONG last = 0; - for (i = 0; i < AddressRangeCount; i++) - { - if (BIOSMemoryMap[i].Type == 1 - && (BIOSMemoryMap[i].BaseAddrLow + BIOSMemoryMap[i].LengthLow + PAGE_SIZE -1) / PAGE_SIZE > last) - { - last = (BIOSMemoryMap[i].BaseAddrLow + BIOSMemoryMap[i].LengthLow + PAGE_SIZE -1) / PAGE_SIZE; - } - } - if ((last - 256) * 4 > KeLoaderBlock.MemHigher) - { - KeLoaderBlock.MemHigher = (last - 256) * 4; - } - } + { + // If we have a bios memory map, recalulate the memory size + ULONG last = 0; + for (i = 0; i < AddressRangeCount; i++) + { + if (BIOSMemoryMap[i].Type == 1 + && (BIOSMemoryMap[i].BaseAddrLow + BIOSMemoryMap[i].LengthLow + PAGE_SIZE -1) / PAGE_SIZE > last) + { + last = (BIOSMemoryMap[i].BaseAddrLow + BIOSMemoryMap[i].LengthLow + PAGE_SIZE -1) / PAGE_SIZE; + } + } + if ((last - 256) * 4 > KeLoaderBlock.MemHigher) + { + KeLoaderBlock.MemHigher = (last - 256) * 4; + } + } if (KeLoaderBlock.MemHigher >= (MaxMem - 1) * 1024) - { - KeLoaderBlock.MemHigher = (MaxMem - 1) * 1024; - } + { + KeLoaderBlock.MemHigher = (MaxMem - 1) * 1024; + } /* * FIXME: Set this based on the system command line @@ -354,7 +354,7 @@ MmInit1(ULONG FirstKrnlPhysAddr, MmSystemRangeStart = (PVOID)KERNEL_BASE; // 0xC0000000 MmUserProbeAddress = (PVOID)0x7fff0000; MmHighestUserAddress = (PVOID)0x7ffeffff; - + MmInitGlobalKernelPageDirectory(); /* @@ -370,7 +370,7 @@ MmInit1(ULONG FirstKrnlPhysAddr, MmStats.PagingRequestsInLastMinute = 0; MmStats.PagingRequestsInLastFiveMinutes = 0; MmStats.PagingRequestsInLastFifteenMinutes = 0; - + /* * Initialize the kernel address space */ @@ -380,7 +380,7 @@ MmInit1(ULONG FirstKrnlPhysAddr, * Unmap low memory */ #ifndef MP - /* In SMP mode we unmap the low memory in MmInit3. + /* In SMP mode we unmap the low memory in MmInit3. The APIC needs the mapping of the first pages while the processors are starting up. */ MmDeletePageTable(NULL, 0); @@ -391,35 +391,36 @@ MmInit1(ULONG FirstKrnlPhysAddr, * memory) */ DPRINT("first krnl %x\nlast krnl %x\n",FirstKrnlPhysAddr, - LastKrnlPhysAddr); - + LastKrnlPhysAddr); + /* * Free physical memory not used by the kernel */ MmStats.NrTotalPages = KeLoaderBlock.MemHigher/4; if (!MmStats.NrTotalPages) - { - DbgPrint("Memory not detected, default to 8 MB\n"); - MmStats.NrTotalPages = 2048; - } + { + DbgPrint("Memory not detected, default to 8 MB\n"); + MmStats.NrTotalPages = 2048; + } else - { - /* add 1MB for standard memory (not extended) */ - MmStats.NrTotalPages += 256; - } + { + /* add 1MB for standard memory (not extended) */ + MmStats.NrTotalPages += 256; + } #ifdef BIOS_MEM_FIX MmStats.NrTotalPages += 16; #endif + DbgPrint("Used memory %dKb\n", (MmStats.NrTotalPages * PAGE_SIZE) / 1024); LastKernelAddress = (ULONG)MmInitializePageList((PVOID)FirstKrnlPhysAddr, - (PVOID)LastKrnlPhysAddr, - MmStats.NrTotalPages, - PAGE_ROUND_UP(LastKernelAddress), - BIOSMemoryMap, - AddressRangeCount); + (PVOID)LastKrnlPhysAddr, + MmStats.NrTotalPages, + PAGE_ROUND_UP(LastKernelAddress), + BIOSMemoryMap, + AddressRangeCount); kernel_len = LastKrnlPhysAddr - FirstKrnlPhysAddr; - + /* * Create a trap for null pointer references and protect text * segment @@ -427,27 +428,27 @@ MmInit1(ULONG FirstKrnlPhysAddr, CHECKPOINT; DPRINT("_text_start__ %x _init_end__ %x\n",(int)&_text_start__,(int)&_init_end__); for (i=PAGE_ROUND_DOWN(((int)&_text_start__)); - i 0) + + while (Page.QuadPart != 0LL && Target > 0) #else - while (Page.QuadPart && Target > 0) + + while (Page.QuadPart && Target > 0) #endif - { + + { /* * FIXME: While the current page is write back it is possible * that the next page is freed and not longer a user page. */ NextPage = MmGetLRUNextUserPage(Page); if (MmIsDirtyPageRmap(Page)) - { - Status = MmWritePagePhysicalAddress(Page); - if (NT_SUCCESS(Status)) - { - Target--; - } - } + { + Status = MmWritePagePhysicalAddress(Page); + if (NT_SUCCESS(Status)) + { + Target--; + } + } Page = NextPage; - } - *Actual = Target; - return(STATUS_SUCCESS); + } + *Actual = Target; + return(STATUS_SUCCESS); } NTSTATUS STDCALL MmMpwThreadMain(PVOID Ignored) { - NTSTATUS Status; - ULONG PagesWritten; - LARGE_INTEGER Timeout; - - Timeout.QuadPart = -50000000; - - for(;;) - { + NTSTATUS Status; + ULONG PagesWritten; + LARGE_INTEGER Timeout; + + Timeout.QuadPart = -50000000; + + for(;;) + { Status = KeWaitForSingleObject(&MpwThreadEvent, - 0, - KernelMode, - FALSE, - &Timeout); + 0, + KernelMode, + FALSE, + &Timeout); if (!NT_SUCCESS(Status)) - { - DbgPrint("MpwThread: Wait failed\n"); - KEBUGCHECK(0); - return(STATUS_UNSUCCESSFUL); - } + { + DbgPrint("MpwThread: Wait failed\n"); + KEBUGCHECK(0); + return(STATUS_UNSUCCESSFUL); + } if (MpwThreadShouldTerminate) - { - DbgPrint("MpwThread: Terminating\n"); - return(STATUS_SUCCESS); - } - + { + DbgPrint("MpwThread: Terminating\n"); + return(STATUS_SUCCESS); + } + PagesWritten = 0; #if 0 - /* + /* * FIXME: MmWriteDirtyPages doesn't work correctly. */ MmWriteDirtyPages(128, &PagesWritten); #endif + CcRosFlushDirtyPages(128, &PagesWritten); - } + } } NTSTATUS MmInitMpwThread(VOID) { - KPRIORITY Priority; - NTSTATUS Status; - - MpwThreadShouldTerminate = FALSE; - KeInitializeEvent(&MpwThreadEvent, SynchronizationEvent, FALSE); - - Status = PsCreateSystemThread(&MpwThreadHandle, - THREAD_ALL_ACCESS, - NULL, - NULL, - &MpwThreadId, - (PKSTART_ROUTINE) MmMpwThreadMain, - NULL); - if (!NT_SUCCESS(Status)) - { + KPRIORITY Priority; + NTSTATUS Status; + + MpwThreadShouldTerminate = FALSE; + KeInitializeEvent(&MpwThreadEvent, SynchronizationEvent, FALSE); + + Status = PsCreateSystemThread(&MpwThreadHandle, + THREAD_ALL_ACCESS, + NULL, + NULL, + &MpwThreadId, + (PKSTART_ROUTINE) MmMpwThreadMain, + NULL); + if (!NT_SUCCESS(Status)) + { return(Status); - } - - Priority = 1; - NtSetInformationThread(MpwThreadHandle, - ThreadPriority, - &Priority, - sizeof(Priority)); - - return(STATUS_SUCCESS); + } + + Priority = 1; + NtSetInformationThread(MpwThreadHandle, + ThreadPriority, + &Priority, + sizeof(Priority)); + + return(STATUS_SUCCESS); } diff --git a/reactos/ntoskrnl/mm/ncache.c b/reactos/ntoskrnl/mm/ncache.c index b488d62eaa7..271d6394e56 100644 --- a/reactos/ntoskrnl/mm/ncache.c +++ b/reactos/ntoskrnl/mm/ncache.c @@ -1,4 +1,4 @@ -/* $Id: ncache.c,v 1.27 2003/12/31 05:33:04 jfilby Exp $ +/* $Id: ncache.c,v 1.28 2004/04/10 22:35:25 gdalsnes Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -22,30 +22,30 @@ /********************************************************************** - * NAME EXPORTED - * MmAllocateNonCachedMemory@4 + * NAME EXPORTED + * MmAllocateNonCachedMemory@4 * * DESCRIPTION - * Allocates a virtual address range of noncached and cache - * aligned memory. - * + * Allocates a virtual address range of noncached and cache + * aligned memory. + * * ARGUMENTS - * NumberOfBytes - * Size of region to allocate. - * + * NumberOfBytes + * Size of region to allocate. + * * RETURN VALUE - * The base address of the range on success; - * NULL on failure. + * The base address of the range on success; + * NULL on failure. * * NOTE - * Description taken from include/ddk/mmfuncs.h. - * Code taken from ntoskrnl/mm/special.c. + * Description taken from include/ddk/mmfuncs.h. + * Code taken from ntoskrnl/mm/special.c. * * REVISIONS * * @implemented */ -PVOID STDCALL +PVOID STDCALL MmAllocateNonCachedMemory(IN ULONG NumberOfBytes) { PVOID Result; @@ -59,85 +59,85 @@ MmAllocateNonCachedMemory(IN ULONG NumberOfBytes) MmLockAddressSpace(MmGetKernelAddressSpace()); Result = NULL; Status = MmCreateMemoryArea (NULL, - MmGetKernelAddressSpace(), - MEMORY_AREA_NO_CACHE, - &Result, - NumberOfBytes, - 0, - &marea, - FALSE, - FALSE, - BoundaryAddressMultiple); + MmGetKernelAddressSpace(), + MEMORY_AREA_NO_CACHE, + &Result, + NumberOfBytes, + 0, + &marea, + FALSE, + FALSE, + BoundaryAddressMultiple); MmUnlockAddressSpace(MmGetKernelAddressSpace()); if (!NT_SUCCESS(Status)) - { - return (NULL); - } - Attributes = PAGE_READWRITE | PAGE_SYSTEM | PAGE_NOCACHE | - PAGE_WRITETHROUGH; + { + return (NULL); + } + Attributes = PAGE_READWRITE | PAGE_SYSTEM | PAGE_NOCACHE | + PAGE_WRITETHROUGH; for (i = 0; i < (PAGE_ROUND_UP(NumberOfBytes) / PAGE_SIZE); i++) - { - PHYSICAL_ADDRESS NPage; + { + PHYSICAL_ADDRESS NPage; - Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &NPage); - MmCreateVirtualMapping (NULL, - (char*)Result + (i * PAGE_SIZE), - Attributes, - NPage, - TRUE); - } + Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &NPage); + MmCreateVirtualMapping (NULL, + (char*)Result + (i * PAGE_SIZE), + Attributes, + NPage, + TRUE); + } return ((PVOID)Result); } VOID STATIC -MmFreeNonCachedPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, - PHYSICAL_ADDRESS PhysAddr, SWAPENTRY SwapEntry, - BOOLEAN Dirty) +MmFreeNonCachedPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, + PHYSICAL_ADDRESS PhysAddr, SWAPENTRY SwapEntry, + BOOLEAN Dirty) { - assert(SwapEntry == 0); - if (PhysAddr.QuadPart != 0) - { + assert(SwapEntry == 0); + if (PhysAddr.QuadPart != 0) + { MmReleasePageMemoryConsumer(MC_NPPOOL, PhysAddr); - } + } } /********************************************************************** - * NAME EXPORTED - * MmFreeNonCachedMemory@8 + * NAME EXPORTED + * MmFreeNonCachedMemory@8 * * DESCRIPTION - * Releases a range of noncached memory allocated with - * MmAllocateNonCachedMemory. - * + * Releases a range of noncached memory allocated with + * MmAllocateNonCachedMemory. + * * ARGUMENTS - * BaseAddress - * Virtual address to be freed; - * - * NumberOfBytes - * Size of the region to be freed. - * + * BaseAddress + * Virtual address to be freed; + * + * NumberOfBytes + * Size of the region to be freed. + * * RETURN VALUE - * None. + * None. * * NOTE - * Description taken from include/ddk/mmfuncs.h. - * Code taken from ntoskrnl/mm/special.c. + * Description taken from include/ddk/mmfuncs.h. + * Code taken from ntoskrnl/mm/special.c. * * REVISIONS * * @implemented */ VOID STDCALL MmFreeNonCachedMemory (IN PVOID BaseAddress, - IN ULONG NumberOfBytes) + IN ULONG NumberOfBytes) { - MmLockAddressSpace(MmGetKernelAddressSpace()); - MmFreeMemoryArea (MmGetKernelAddressSpace(), - BaseAddress, - NumberOfBytes, - MmFreeNonCachedPage, - NULL); - MmUnlockAddressSpace(MmGetKernelAddressSpace()); + MmLockAddressSpace(MmGetKernelAddressSpace()); + MmFreeMemoryArea (MmGetKernelAddressSpace(), + BaseAddress, + NumberOfBytes, + MmFreeNonCachedPage, + NULL); + MmUnlockAddressSpace(MmGetKernelAddressSpace()); } /* EOF */ diff --git a/reactos/ntoskrnl/mm/npool.c b/reactos/ntoskrnl/mm/npool.c index ded9a3bbfe1..f1345d461a7 100644 --- a/reactos/ntoskrnl/mm/npool.c +++ b/reactos/ntoskrnl/mm/npool.c @@ -1,4 +1,4 @@ -/* $Id: npool.c,v 1.84 2004/03/15 22:22:53 dwelch Exp $ +/* $Id: npool.c,v 1.85 2004/04/10 22:35:25 gdalsnes Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -30,7 +30,7 @@ /* Enable tracking of statistics about the tagged blocks in the pool */ #define TAG_STATISTICS_TRACKING -/* +/* * Put each block in its own range of pages and position the block at the * end of the range so any accesses beyond the end of block are to invalid * memory locations. @@ -50,7 +50,7 @@ #define POOL_TRACE(args...) #else #define POOL_TRACE -#endif /* __GNUC__ */ +#endif /* __GNUC__ */ #endif /* avl types ****************************************************************/ @@ -61,10 +61,11 @@ typedef struct _NODE { - struct _NODE* link[2]; - struct _NODE* parent; - signed char balance; -} NODE, *PNODE; + struct _NODE* link[2]; + struct _NODE* parent; + signed char balance; +} +NODE, *PNODE; /* TYPES *******************************************************************/ @@ -76,29 +77,32 @@ typedef struct _NODE */ typedef struct _BLOCK_HDR { - ULONG Magic; - ULONG Size; - struct _BLOCK_HDR* previous; - union - { - struct - { - LIST_ENTRY ListEntry; - ULONG Tag; - PVOID Caller; - LIST_ENTRY TagListEntry; - BOOLEAN Dumped; - } Used; - struct - { - NODE Node; - } Free; - }; -} BLOCK_HDR; + ULONG Magic; + ULONG Size; + struct _BLOCK_HDR* previous; + union + { + struct + { + LIST_ENTRY ListEntry; + ULONG Tag; + PVOID Caller; + LIST_ENTRY TagListEntry; + BOOLEAN Dumped; + } + Used; + struct + { + NODE Node; + } + Free; + }; +} +BLOCK_HDR; -#define BLOCK_HDR_SIZE ROUND_UP(sizeof(BLOCK_HDR), MM_POOL_ALIGNMENT) +#define BLOCK_HDR_SIZE ROUND_UP(sizeof(BLOCK_HDR), MM_POOL_ALIGNMENT) -PVOID STDCALL +PVOID STDCALL ExAllocateWholePageBlock(ULONG Size); VOID STDCALL ExFreeWholePageBlock(PVOID Addr); @@ -174,74 +178,74 @@ static ULONG MiNonPagedPoolNrOfPages; void DumpFreeBlockNode(PNODE p) { - static int count = 0; - BLOCK_HDR* blk; + static int count = 0; + BLOCK_HDR* blk; - count++; + count++; - if (p) - { + if (p) + { DumpFreeBlockNode(p->link[0]); blk = CONTAINING_RECORD(p, BLOCK_HDR, Free.Node); DbgPrint("%08x %8d (%d)\n", blk, blk->Size, count); DumpFreeBlockNode(p->link[1]); - } + } - count--; + count--; } void DumpFreeBlockTree(void) { - DbgPrint("--- Begin tree ------------------\n"); - DbgPrint("%08x\n", CONTAINING_RECORD(FreeBlockListRoot, BLOCK_HDR, Free.Node)); - DumpFreeBlockNode(FreeBlockListRoot); - DbgPrint("--- End tree --------------------\n"); + DbgPrint("--- Begin tree ------------------\n"); + DbgPrint("%08x\n", CONTAINING_RECORD(FreeBlockListRoot, BLOCK_HDR, Free.Node)); + DumpFreeBlockNode(FreeBlockListRoot); + DbgPrint("--- End tree --------------------\n"); } int compare_node(PNODE p1, PNODE p2) { - BLOCK_HDR* blk1 = CONTAINING_RECORD(p1, BLOCK_HDR, Free.Node); - BLOCK_HDR* blk2 = CONTAINING_RECORD(p2, BLOCK_HDR, Free.Node); + BLOCK_HDR* blk1 = CONTAINING_RECORD(p1, BLOCK_HDR, Free.Node); + BLOCK_HDR* blk2 = CONTAINING_RECORD(p2, BLOCK_HDR, Free.Node); - if (blk1->Size == blk2->Size) - { + if (blk1->Size == blk2->Size) + { if (blk1 < blk2) - { - return -1; - } + { + return -1; + } if (blk1 > blk2) - { - return 1; - } - } - else - { + { + return 1; + } + } + else + { if (blk1->Size < blk2->Size) - { - return -1; - } + { + return -1; + } if (blk1->Size > blk2->Size) - { - return 1; - } - } - return 0; + { + return 1; + } + } + return 0; } int compare_value(PVOID value, PNODE p) { - BLOCK_HDR* blk = CONTAINING_RECORD(p, BLOCK_HDR, Free.Node); - ULONG v = *(PULONG)value; + BLOCK_HDR* blk = CONTAINING_RECORD(p, BLOCK_HDR, Free.Node); + ULONG v = *(PULONG)value; - if (v < blk->Size) - { + if (v < blk->Size) + { return -1; - } - if (v > blk->Size) - { + } + if (v > blk->Size) + { return 1; - } - return 0; + } + return 0; } /* avl functions **********************************************************/ @@ -254,490 +258,490 @@ int compare_value(PVOID value, PNODE p) void avl_insert (PNODE * root, PNODE n, int (*compare)(PNODE, PNODE)) { - PNODE y; /* Top node to update balance factor, and parent. */ - PNODE p, q; /* Iterator, and parent. */ - PNODE w; /* New root of rebalanced subtree. */ - int dir = 0; /* Direction to descend. */ + PNODE y; /* Top node to update balance factor, and parent. */ + PNODE p, q; /* Iterator, and parent. */ + PNODE w; /* New root of rebalanced subtree. */ + int dir = 0; /* Direction to descend. */ - n->link[0] = n->link[1] = n->parent = NULL; - n->balance = 0; + n->link[0] = n->link[1] = n->parent = NULL; + n->balance = 0; - y = *root; - for (q = NULL, p = *root; p != NULL; q = p, p = p->link[dir]) - { + y = *root; + for (q = NULL, p = *root; p != NULL; q = p, p = p->link[dir]) + { dir = compare(n, p) > 0; if (p->balance != 0) - { - y = p; - } - } + { + y = p; + } + } - n->parent = q; - if (q != NULL) - { + n->parent = q; + if (q != NULL) + { q->link[dir] = n; - } - else - { + } + else + { *root = n; - } + } - if (*root == n) - { + if (*root == n) + { return; - } + } - for (p = n; p != y; p = q) - { + for (p = n; p != y; p = q) + { q = p->parent; dir = q->link[0] != p; if (dir == 0) - { - q->balance--; - } + { + q->balance--; + } else - { - q->balance++; - } - } + { + q->balance++; + } + } - if (y->balance == -2) - { + if (y->balance == -2) + { PNODE x = y->link[0]; if (x->balance == -1) - { - w = x; - y->link[0] = x->link[1]; - x->link[1] = y; - x->balance = y->balance = 0; - x->parent = y->parent; - y->parent = x; - if (y->link[0] != NULL) - { - y->link[0]->parent = y; - } - } + { + w = x; + y->link[0] = x->link[1]; + x->link[1] = y; + x->balance = y->balance = 0; + x->parent = y->parent; + y->parent = x; + if (y->link[0] != NULL) + { + y->link[0]->parent = y; + } + } else - { - assert (x->balance == +1); - w = x->link[1]; - x->link[1] = w->link[0]; - w->link[0] = x; - y->link[0] = w->link[1]; - w->link[1] = y; - if (w->balance == -1) - { - x->balance = 0; - y->balance = +1; - } - else if (w->balance == 0) - { - x->balance = y->balance = 0; - } - else /* |w->pavl_balance == +1| */ - { - x->balance = -1; - y->balance = 0; - } - w->balance = 0; - w->parent = y->parent; - x->parent = y->parent = w; - if (x->link[1] != NULL) - { - x->link[1]->parent = x; - } - if (y->link[0] != NULL) - { - y->link[0]->parent = y; - } - } - } - else if (y->balance == +2) - { + { + assert (x->balance == +1); + w = x->link[1]; + x->link[1] = w->link[0]; + w->link[0] = x; + y->link[0] = w->link[1]; + w->link[1] = y; + if (w->balance == -1) + { + x->balance = 0; + y->balance = +1; + } + else if (w->balance == 0) + { + x->balance = y->balance = 0; + } + else /* |w->pavl_balance == +1| */ + { + x->balance = -1; + y->balance = 0; + } + w->balance = 0; + w->parent = y->parent; + x->parent = y->parent = w; + if (x->link[1] != NULL) + { + x->link[1]->parent = x; + } + if (y->link[0] != NULL) + { + y->link[0]->parent = y; + } + } + } + else if (y->balance == +2) + { PNODE x = y->link[1]; if (x->balance == +1) - { - w = x; - y->link[1] = x->link[0]; - x->link[0] = y; - x->balance = y->balance = 0; - x->parent = y->parent; - y->parent = x; - if (y->link[1] != NULL) - { - y->link[1]->parent = y; - } - } + { + w = x; + y->link[1] = x->link[0]; + x->link[0] = y; + x->balance = y->balance = 0; + x->parent = y->parent; + y->parent = x; + if (y->link[1] != NULL) + { + y->link[1]->parent = y; + } + } else - { - assert (x->balance == -1); - w = x->link[0]; - x->link[0] = w->link[1]; - w->link[1] = x; - y->link[1] = w->link[0]; - w->link[0] = y; - if (w->balance == 1) - { - x->balance = 0; - y->balance = -1; - } - else if (w->balance == 0) - { - x->balance = y->balance = 0; - } - else /* |w->pavl_balance == -1| */ - { - x->balance = +1; - y->balance = 0; - } - w->balance = 0; - w->parent = y->parent; - x->parent = y->parent = w; - if (x->link[0] != NULL) - { - x->link[0]->parent = x; - } - if (y->link[1] != NULL) - { - y->link[1]->parent = y; - } - } - } - else - { + { + assert (x->balance == -1); + w = x->link[0]; + x->link[0] = w->link[1]; + w->link[1] = x; + y->link[1] = w->link[0]; + w->link[0] = y; + if (w->balance == 1) + { + x->balance = 0; + y->balance = -1; + } + else if (w->balance == 0) + { + x->balance = y->balance = 0; + } + else /* |w->pavl_balance == -1| */ + { + x->balance = +1; + y->balance = 0; + } + w->balance = 0; + w->parent = y->parent; + x->parent = y->parent = w; + if (x->link[0] != NULL) + { + x->link[0]->parent = x; + } + if (y->link[1] != NULL) + { + y->link[1]->parent = y; + } + } + } + else + { return; - } - if (w->parent != NULL) - { + } + if (w->parent != NULL) + { w->parent->link[y != w->parent->link[0]] = w; - } - else - { + } + else + { *root = w; - } + } - return; + return; } void avl_remove (PNODE *root, PNODE item, int (*compare)(PNODE, PNODE)) { - PNODE p; /* Traverses tree to find node to delete. */ - PNODE q; /* Parent of |p|. */ - int dir; /* Side of |q| on which |p| is linked. */ + PNODE p; /* Traverses tree to find node to delete. */ + PNODE q; /* Parent of |p|. */ + int dir; /* Side of |q| on which |p| is linked. */ - if (root == NULL || *root == NULL) - { + if (root == NULL || *root == NULL) + { return ; - } + } - p = item; - q = p->parent; - if (q == NULL) - { + p = item; + q = p->parent; + if (q == NULL) + { q = (PNODE) root; dir = 0; - } - else - { + } + else + { dir = compare(p, q) > 0; - } + } - if (p->link[1] == NULL) - { + if (p->link[1] == NULL) + { q->link[dir] = p->link[0]; if (q->link[dir] != NULL) - { - q->link[dir]->parent = p->parent; - } - } - else - { + { + q->link[dir]->parent = p->parent; + } + } + else + { PNODE r = p->link[1]; if (r->link[0] == NULL) - { - r->link[0] = p->link[0]; - q->link[dir] = r; - r->parent = p->parent; - if (r->link[0] != NULL) - { - r->link[0]->parent = r; - } - r->balance = p->balance; - q = r; - dir = 1; - } + { + r->link[0] = p->link[0]; + q->link[dir] = r; + r->parent = p->parent; + if (r->link[0] != NULL) + { + r->link[0]->parent = r; + } + r->balance = p->balance; + q = r; + dir = 1; + } else - { - PNODE s = r->link[0]; - while (s->link[0] != NULL) - { - s = s->link[0]; - } - r = s->parent; - r->link[0] = s->link[1]; - s->link[0] = p->link[0]; - s->link[1] = p->link[1]; - q->link[dir] = s; - if (s->link[0] != NULL) - { - s->link[0]->parent = s; - } - s->link[1]->parent = s; - s->parent = p->parent; - if (r->link[0] != NULL) - { - r->link[0]->parent = r; - } - s->balance = p->balance; - q = r; - dir = 0; - } - } + { + PNODE s = r->link[0]; + while (s->link[0] != NULL) + { + s = s->link[0]; + } + r = s->parent; + r->link[0] = s->link[1]; + s->link[0] = p->link[0]; + s->link[1] = p->link[1]; + q->link[dir] = s; + if (s->link[0] != NULL) + { + s->link[0]->parent = s; + } + s->link[1]->parent = s; + s->parent = p->parent; + if (r->link[0] != NULL) + { + r->link[0]->parent = r; + } + s->balance = p->balance; + q = r; + dir = 0; + } + } - item->link[0] = item->link[1] = item->parent = NULL; - item->balance = 0; + item->link[0] = item->link[1] = item->parent = NULL; + item->balance = 0; - while (q != (PNODE) root) - { + while (q != (PNODE) root) + { PNODE y = q; if (y->parent != NULL) - { - q = y->parent; - } + { + q = y->parent; + } else - { - q = (PNODE) root; - } + { + q = (PNODE) root; + } if (dir == 0) - { - dir = q->link[0] != y; - y->balance++; - if (y->balance == +1) - { - break; - } - else if (y->balance == +2) + { + dir = q->link[0] != y; + y->balance++; + if (y->balance == +1) + { + break; + } + else if (y->balance == +2) + { + PNODE x = y->link[1]; + if (x->balance == -1) { - PNODE x = y->link[1]; - if (x->balance == -1) - { - PNODE w; + PNODE w; - assert (x->balance == -1); - w = x->link[0]; - x->link[0] = w->link[1]; - w->link[1] = x; - y->link[1] = w->link[0]; - w->link[0] = y; - if (w->balance == +1) - { - x->balance = 0; - y->balance = -1; - } - else if (w->balance == 0) - { - x->balance = y->balance = 0; - } - else /* |w->pavl_balance == -1| */ - { - x->balance = +1; - y->balance = 0; - } - w->balance = 0; - w->parent = y->parent; - x->parent = y->parent = w; - if (x->link[0] != NULL) - { - x->link[0]->parent = x; - } - if (y->link[1] != NULL) - { - y->link[1]->parent = y; - } - q->link[dir] = w; - } - else - { - y->link[1] = x->link[0]; - x->link[0] = y; - x->parent = y->parent; - y->parent = x; - if (y->link[1] != NULL) - { - y->link[1]->parent = y; - } - q->link[dir] = x; - if (x->balance == 0) - { - x->balance = -1; - y->balance = +1; - break; - } - else - { - x->balance = y->balance = 0; - y = x; - } - } + assert (x->balance == -1); + w = x->link[0]; + x->link[0] = w->link[1]; + w->link[1] = x; + y->link[1] = w->link[0]; + w->link[0] = y; + if (w->balance == +1) + { + x->balance = 0; + y->balance = -1; + } + else if (w->balance == 0) + { + x->balance = y->balance = 0; + } + else /* |w->pavl_balance == -1| */ + { + x->balance = +1; + y->balance = 0; + } + w->balance = 0; + w->parent = y->parent; + x->parent = y->parent = w; + if (x->link[0] != NULL) + { + x->link[0]->parent = x; + } + if (y->link[1] != NULL) + { + y->link[1]->parent = y; + } + q->link[dir] = w; } - } - else - { - dir = q->link[0] != y; - y->balance--; - if (y->balance == -1) - { - break; - } - else if (y->balance == -2) + else { - PNODE x = y->link[0]; - if (x->balance == +1) - { - PNODE w; - assert (x->balance == +1); - w = x->link[1]; - x->link[1] = w->link[0]; - w->link[0] = x; - y->link[0] = w->link[1]; - w->link[1] = y; - if (w->balance == -1) - { - x->balance = 0; - y->balance = +1; - } - else if (w->balance == 0) - { - x->balance = y->balance = 0; - } - else /* |w->pavl_balance == +1| */ - { - x->balance = -1; - y->balance = 0; - } - w->balance = 0; - w->parent = y->parent; - x->parent = y->parent = w; - if (x->link[1] != NULL) - { - x->link[1]->parent = x; - } - if (y->link[0] != NULL) - { - y->link[0]->parent = y; - } - q->link[dir] = w; - } - else - { - y->link[0] = x->link[1]; - x->link[1] = y; - x->parent = y->parent; - y->parent = x; - if (y->link[0] != NULL) - { - y->link[0]->parent = y; - } - q->link[dir] = x; - if (x->balance == 0) - { - x->balance = +1; - y->balance = -1; - break; - } - else - { - x->balance = y->balance = 0; - y = x; - } - } + y->link[1] = x->link[0]; + x->link[0] = y; + x->parent = y->parent; + y->parent = x; + if (y->link[1] != NULL) + { + y->link[1]->parent = y; + } + q->link[dir] = x; + if (x->balance == 0) + { + x->balance = -1; + y->balance = +1; + break; + } + else + { + x->balance = y->balance = 0; + y = x; + } } - } - } + } + } + else + { + dir = q->link[0] != y; + y->balance--; + if (y->balance == -1) + { + break; + } + else if (y->balance == -2) + { + PNODE x = y->link[0]; + if (x->balance == +1) + { + PNODE w; + assert (x->balance == +1); + w = x->link[1]; + x->link[1] = w->link[0]; + w->link[0] = x; + y->link[0] = w->link[1]; + w->link[1] = y; + if (w->balance == -1) + { + x->balance = 0; + y->balance = +1; + } + else if (w->balance == 0) + { + x->balance = y->balance = 0; + } + else /* |w->pavl_balance == +1| */ + { + x->balance = -1; + y->balance = 0; + } + w->balance = 0; + w->parent = y->parent; + x->parent = y->parent = w; + if (x->link[1] != NULL) + { + x->link[1]->parent = x; + } + if (y->link[0] != NULL) + { + y->link[0]->parent = y; + } + q->link[dir] = w; + } + else + { + y->link[0] = x->link[1]; + x->link[1] = y; + x->parent = y->parent; + y->parent = x; + if (y->link[0] != NULL) + { + y->link[0]->parent = y; + } + q->link[dir] = x; + if (x->balance == 0) + { + x->balance = +1; + y->balance = -1; + break; + } + else + { + x->balance = y->balance = 0; + y = x; + } + } + } + } + } } PNODE _cdecl avl_get_first(PNODE root) { - PNODE p; - if (root == NULL) - { + PNODE p; + if (root == NULL) + { return NULL; - } - p = root; - while (p->link[0]) - { + } + p = root; + while (p->link[0]) + { p = p->link[0]; - } - return p; + } + return p; } PNODE avl_get_next(PNODE root, PNODE p) { - PNODE q; - if (p->link[1]) - { + PNODE q; + if (p->link[1]) + { p = p->link[1]; while(p->link[0]) - { - p = p->link[0]; - } + { + p = p->link[0]; + } return p; - } - else - { + } + else + { q = p->parent; while (q && q->link[1] == p) - { - p = q; - q = q->parent; - } + { + p = q; + q = q->parent; + } if (q == NULL) - { - return NULL; - } + { + return NULL; + } else - { - return q; - } - } + { + return q; + } + } } PNODE avl_find_equal_or_greater(PNODE root, ULONG size, int (compare)(PVOID, PNODE)) { - PNODE p; - PNODE prev = NULL; - int cmp; + PNODE p; + PNODE prev = NULL; + int cmp; - for (p = root; p != NULL;) - { + for (p = root; p != NULL;) + { cmp = compare((PVOID)&size, p); if (cmp < 0) - { - prev = p; - p = p->link[0]; - } + { + prev = p; + p = p->link[0]; + } else if (cmp > 0) - { - p = p->link[1]; - } + { + p = p->link[1]; + } else - { - while (p->link[0]) - { - cmp = compare((PVOID)&size, p->link[0]); - if (cmp != 0) - { - break; - } - p = p->link[0]; - } - return p; - } - } - return prev; + { + while (p->link[0]) + { + cmp = compare((PVOID)&size, p->link[0]); + if (cmp != 0) + { + break; + } + p = p->link[0]; + } + return p; + } + } + return prev; } /* non paged pool functions ************************************************/ @@ -745,34 +749,34 @@ PNODE avl_find_equal_or_greater(PNODE root, ULONG size, int (compare)(PVOID, PNO #ifdef TAG_STATISTICS_TRACKING VOID MiRemoveFromTagHashTable(BLOCK_HDR* block) - /* - * Remove a block from the tag hash table - */ +/* + * Remove a block from the tag hash table + */ { - if (block->Used.Tag == 0) - { + if (block->Used.Tag == 0) + { return; - } + } - RemoveEntryList(&block->Used.TagListEntry); + RemoveEntryList(&block->Used.TagListEntry); } VOID MiAddToTagHashTable(BLOCK_HDR* block) - /* - * Add a block to the tag hash table - */ +/* + * Add a block to the tag hash table + */ { - ULONG hash; + ULONG hash; - if (block->Used.Tag == 0) - { + if (block->Used.Tag == 0) + { return; - } + } - hash = block->Used.Tag % TAG_HASH_TABLE_SIZE; + hash = block->Used.Tag % TAG_HASH_TABLE_SIZE; - InsertHeadList(&tag_hash_table[hash], &block->Used.TagListEntry); + InsertHeadList(&tag_hash_table[hash], &block->Used.TagListEntry); } #endif /* TAG_STATISTICS_TRACKING */ @@ -780,25 +784,25 @@ MiAddToTagHashTable(BLOCK_HDR* block) VOID STATIC MiDumpTagStats(ULONG CurrentTag, ULONG CurrentNrBlocks, ULONG CurrentSize) { - CHAR c1, c2, c3, c4; - - c1 = (CHAR)((CurrentTag >> 24) & 0xFF); - c2 = (CHAR)((CurrentTag >> 16) & 0xFF); - c3 = (CHAR)((CurrentTag >> 8) & 0xFF); - c4 = (CHAR)(CurrentTag & 0xFF); - - if (isprint(c1) && isprint(c2) && isprint(c3) && isprint(c4)) - { + CHAR c1, c2, c3, c4; + + c1 = (CHAR)((CurrentTag >> 24) & 0xFF); + c2 = (CHAR)((CurrentTag >> 16) & 0xFF); + c3 = (CHAR)((CurrentTag >> 8) & 0xFF); + c4 = (CHAR)(CurrentTag & 0xFF); + + if (isprint(c1) && isprint(c2) && isprint(c3) && isprint(c4)) + { DbgPrint("Tag %x (%c%c%c%c) Blocks %d Total Size %d Average Size %d\n", - CurrentTag, c4, c3, c2, c1, CurrentNrBlocks, - CurrentSize, CurrentSize / CurrentNrBlocks); - } - else - { + CurrentTag, c4, c3, c2, c1, CurrentNrBlocks, + CurrentSize, CurrentSize / CurrentNrBlocks); + } + else + { DbgPrint("Tag %x Blocks %d Total Size %d Average Size %d\n", - CurrentTag, CurrentNrBlocks, CurrentSize, - CurrentSize / CurrentNrBlocks); - } + CurrentTag, CurrentNrBlocks, CurrentSize, + CurrentSize / CurrentNrBlocks); + } } #endif /* defined(TAG_STATISTICS_TRACKING) && !defined(WHOLE_PAGE_ALLOCATIONS); */ @@ -806,80 +810,80 @@ VOID MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly) { #if defined(TAG_STATISTICS_TRACKING) && !defined(WHOLE_PAGE_ALLOCATIONS) - ULONG i; - BLOCK_HDR* current; - ULONG CurrentTag; - ULONG CurrentNrBlocks = 0; - ULONG CurrentSize = 0; - ULONG TotalBlocks; - ULONG TotalSize; - ULONG Size; - LIST_ENTRY tmpListHead; - PLIST_ENTRY current_entry; + ULONG i; + BLOCK_HDR* current; + ULONG CurrentTag; + ULONG CurrentNrBlocks = 0; + ULONG CurrentSize = 0; + ULONG TotalBlocks; + ULONG TotalSize; + ULONG Size; + LIST_ENTRY tmpListHead; + PLIST_ENTRY current_entry; - DbgPrint("******* Dumping non paging pool stats ******\n"); - TotalBlocks = 0; - TotalSize = 0; - for (i = 0; i < TAG_HASH_TABLE_SIZE; i++) - { + DbgPrint("******* Dumping non paging pool stats ******\n"); + TotalBlocks = 0; + TotalSize = 0; + for (i = 0; i < TAG_HASH_TABLE_SIZE; i++) + { InitializeListHead(&tmpListHead); while (!IsListEmpty(&tag_hash_table[i])) - { - CurrentTag = 0; + { + CurrentTag = 0; - current_entry = tag_hash_table[i].Flink; - while (current_entry != &tag_hash_table[i]) - { - current = CONTAINING_RECORD(current_entry, BLOCK_HDR, Used.TagListEntry); - current_entry = current_entry->Flink; - if (CurrentTag == 0) - { - CurrentTag = current->Used.Tag; - CurrentNrBlocks = 0; - CurrentSize = 0; - } - if (current->Used.Tag == CurrentTag) - { - RemoveEntryList(¤t->Used.TagListEntry); - InsertHeadList(&tmpListHead, ¤t->Used.TagListEntry); - if (!NewOnly || !current->Used.Dumped) - { - CurrentNrBlocks++; - TotalBlocks++; - CurrentSize += current->Size; - TotalSize += current->Size; - current->Used.Dumped = TRUE; - } - } - } - if (CurrentTag != 0 && CurrentNrBlocks != 0) - { - MiDumpTagStats(CurrentTag, CurrentNrBlocks, CurrentSize); - } - } + current_entry = tag_hash_table[i].Flink; + while (current_entry != &tag_hash_table[i]) + { + current = CONTAINING_RECORD(current_entry, BLOCK_HDR, Used.TagListEntry); + current_entry = current_entry->Flink; + if (CurrentTag == 0) + { + CurrentTag = current->Used.Tag; + CurrentNrBlocks = 0; + CurrentSize = 0; + } + if (current->Used.Tag == CurrentTag) + { + RemoveEntryList(¤t->Used.TagListEntry); + InsertHeadList(&tmpListHead, ¤t->Used.TagListEntry); + if (!NewOnly || !current->Used.Dumped) + { + CurrentNrBlocks++; + TotalBlocks++; + CurrentSize += current->Size; + TotalSize += current->Size; + current->Used.Dumped = TRUE; + } + } + } + if (CurrentTag != 0 && CurrentNrBlocks != 0) + { + MiDumpTagStats(CurrentTag, CurrentNrBlocks, CurrentSize); + } + } if (!IsListEmpty(&tmpListHead)) - { - tag_hash_table[i].Flink = tmpListHead.Flink; - tag_hash_table[i].Flink->Blink = &tag_hash_table[i]; - tag_hash_table[i].Blink = tmpListHead.Blink; - tag_hash_table[i].Blink->Flink = &tag_hash_table[i]; - } - } - if (TotalBlocks != 0) - { + { + tag_hash_table[i].Flink = tmpListHead.Flink; + tag_hash_table[i].Flink->Blink = &tag_hash_table[i]; + tag_hash_table[i].Blink = tmpListHead.Blink; + tag_hash_table[i].Blink->Flink = &tag_hash_table[i]; + } + } + if (TotalBlocks != 0) + { DbgPrint("TotalBlocks %d TotalSize %d AverageSize %d\n", - TotalBlocks, TotalSize, TotalSize / TotalBlocks); - } - else - { + TotalBlocks, TotalSize, TotalSize / TotalBlocks); + } + else + { DbgPrint("TotalBlocks %d TotalSize %d\n", - TotalBlocks, TotalSize); - } - Size = EiFreeNonPagedPool - (MiNonPagedPoolLength - MiNonPagedPoolNrOfPages * PAGE_SIZE); - DbgPrint("Freeblocks %d TotalFreeSize %d AverageFreeSize %d\n", - EiNrFreeBlocks, Size, EiNrFreeBlocks ? Size / EiNrFreeBlocks : 0); - DbgPrint("***************** Dump Complete ***************\n"); + TotalBlocks, TotalSize); + } + Size = EiFreeNonPagedPool - (MiNonPagedPoolLength - MiNonPagedPoolNrOfPages * PAGE_SIZE); + DbgPrint("Freeblocks %d TotalFreeSize %d AverageFreeSize %d\n", + EiNrFreeBlocks, Size, EiNrFreeBlocks ? Size / EiNrFreeBlocks : 0); + DbgPrint("***************** Dump Complete ***************\n"); #endif /* defined(TAG_STATISTICS_TRACKING) && !defined(WHOLE_PAGE_ALLOCATIONS) */ } @@ -890,38 +894,38 @@ MiDebugDumpNonPagedPool(BOOLEAN NewOnly) BLOCK_HDR* current; PLIST_ENTRY current_entry; KIRQL oldIrql; - + KeAcquireSpinLock(&MmNpoolLock, &oldIrql); DbgPrint("******* Dumping non paging pool contents ******\n"); current_entry = UsedBlockListHead.Flink; while (current_entry != &UsedBlockListHead) - { - current = CONTAINING_RECORD(current_entry, BLOCK_HDR, Used.ListEntry); - if (!NewOnly || !current->Used.Dumped) - { - CHAR c1, c2, c3, c4; + { + current = CONTAINING_RECORD(current_entry, BLOCK_HDR, Used.ListEntry); + if (!NewOnly || !current->Used.Dumped) + { + CHAR c1, c2, c3, c4; - c1 = (CHAR)((current->Used.Tag >> 24) & 0xFF); - c2 = (CHAR)((current->Used.Tag >> 16) & 0xFF); - c3 = (CHAR)((current->Used.Tag >> 8) & 0xFF); - c4 = (CHAR)(current->Used.Tag & 0xFF); + c1 = (CHAR)((current->Used.Tag >> 24) & 0xFF); + c2 = (CHAR)((current->Used.Tag >> 16) & 0xFF); + c3 = (CHAR)((current->Used.Tag >> 8) & 0xFF); + c4 = (CHAR)(current->Used.Tag & 0xFF); - if (isprint(c1) && isprint(c2) && isprint(c3) && isprint(c4)) - { - DbgPrint("Size 0x%x Tag 0x%x (%c%c%c%c) Allocator 0x%x\n", - current->Size, current->Used.Tag, c4, c3, c2, c1, - current->Used.Caller); - } - else - { - DbgPrint("Size 0x%x Tag 0x%x Allocator 0x%x\n", - current->Size, current->Used.Tag, current->Used.Caller); - } - current->Used.Dumped = TRUE; - } - current_entry = current_entry->Flink; - } + if (isprint(c1) && isprint(c2) && isprint(c3) && isprint(c4)) + { + DbgPrint("Size 0x%x Tag 0x%x (%c%c%c%c) Allocator 0x%x\n", + current->Size, current->Used.Tag, c4, c3, c2, c1, + current->Used.Caller); + } + else + { + DbgPrint("Size 0x%x Tag 0x%x Allocator 0x%x\n", + current->Size, current->Used.Tag, current->Used.Caller); + } + current->Used.Dumped = TRUE; + } + current_entry = current_entry->Flink; + } DbgPrint("***************** Dump Complete ***************\n"); KeReleaseSpinLock(&MmNpoolLock, oldIrql); #endif /* not WHOLE_PAGE_ALLOCATIONS */ @@ -936,42 +940,42 @@ static void validate_free_list(void) */ { BLOCK_HDR* current; - unsigned int blocks_seen=0; + unsigned int blocks_seen=0; PNODE p; p = avl_get_first(FreeBlockListRoot); while(p) - { - PVOID base_addr; + { + PVOID base_addr; - current = CONTAINING_RECORD(p, BLOCK_HDR, Free.Node); - base_addr = (PVOID)current; + current = CONTAINING_RECORD(p, BLOCK_HDR, Free.Node); + base_addr = (PVOID)current; - if (current->Magic != BLOCK_HDR_FREE_MAGIC) - { - DbgPrint("Bad block magic (probable pool corruption) at %x\n", - current); - KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0); - } - - if (base_addr < MiNonPagedPoolStart || - base_addr + BLOCK_HDR_SIZE + current->Size > MiNonPagedPoolStart + MiNonPagedPoolLength) - { - DbgPrint("Block %x found outside pool area\n",current); - DbgPrint("Size %d\n",current->Size); - DbgPrint("Limits are %x %x\n",MiNonPagedPoolStart, - MiNonPagedPoolStart+MiNonPagedPoolLength); - KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0); - } - blocks_seen++; - if (blocks_seen > EiNrFreeBlocks) - { - DbgPrint("Too many blocks on free list\n"); - KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0); - } - p = avl_get_next(FreeBlockListRoot, p); - } + if (current->Magic != BLOCK_HDR_FREE_MAGIC) + { + DbgPrint("Bad block magic (probable pool corruption) at %x\n", + current); + KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0); + } + + if (base_addr < MiNonPagedPoolStart || + base_addr + BLOCK_HDR_SIZE + current->Size > MiNonPagedPoolStart + MiNonPagedPoolLength) + { + DbgPrint("Block %x found outside pool area\n",current); + DbgPrint("Size %d\n",current->Size); + DbgPrint("Limits are %x %x\n",MiNonPagedPoolStart, + MiNonPagedPoolStart+MiNonPagedPoolLength); + KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0); + } + blocks_seen++; + if (blocks_seen > EiNrFreeBlocks) + { + DbgPrint("Too many blocks on free list\n"); + KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0); + } + p = avl_get_next(FreeBlockListRoot, p); + } } static void validate_used_list(void) @@ -982,49 +986,49 @@ static void validate_used_list(void) BLOCK_HDR* current; PLIST_ENTRY current_entry; unsigned int blocks_seen=0; - + current_entry = UsedBlockListHead.Flink; while (current_entry != &UsedBlockListHead) - { - PVOID base_addr; + { + PVOID base_addr; - current = CONTAINING_RECORD(current_entry, BLOCK_HDR, Used.ListEntry); - base_addr = (PVOID)current; - - if (current->Magic != BLOCK_HDR_USED_MAGIC) - { - DbgPrint("Bad block magic (probable pool corruption) at %x\n", - current); - KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0); - } - if (base_addr < MiNonPagedPoolStart || - (base_addr+BLOCK_HDR_SIZE+current->Size) > - MiNonPagedPoolStart+MiNonPagedPoolLength) - { - DbgPrint("Block %x found outside pool area\n",current); - DbgPrint("Size %d\n",current->Size); - DbgPrint("Limits are %x %x\n",MiNonPagedPoolStart, - MiNonPagedPoolStart+MiNonPagedPoolLength); - KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0); - } - blocks_seen++; - if (blocks_seen > EiNrUsedBlocks) - { - DbgPrint("Too many blocks on used list\n"); - KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0); - } - if (current->Used.ListEntry.Flink != &UsedBlockListHead && - current->Used.ListEntry.Flink->Blink != ¤t->Used.ListEntry) - { - DbgPrint("%s:%d:Break in list (current %x next %x " - "current->next->previous %x)\n", - __FILE__,__LINE__,current, current->Used.ListEntry.Flink, - current->Used.ListEntry.Flink->Blink); - KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0); - } + current = CONTAINING_RECORD(current_entry, BLOCK_HDR, Used.ListEntry); + base_addr = (PVOID)current; - current_entry = current_entry->Flink; - } + if (current->Magic != BLOCK_HDR_USED_MAGIC) + { + DbgPrint("Bad block magic (probable pool corruption) at %x\n", + current); + KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0); + } + if (base_addr < MiNonPagedPoolStart || + (base_addr+BLOCK_HDR_SIZE+current->Size) > + MiNonPagedPoolStart+MiNonPagedPoolLength) + { + DbgPrint("Block %x found outside pool area\n",current); + DbgPrint("Size %d\n",current->Size); + DbgPrint("Limits are %x %x\n",MiNonPagedPoolStart, + MiNonPagedPoolStart+MiNonPagedPoolLength); + KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0); + } + blocks_seen++; + if (blocks_seen > EiNrUsedBlocks) + { + DbgPrint("Too many blocks on used list\n"); + KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0); + } + if (current->Used.ListEntry.Flink != &UsedBlockListHead && + current->Used.ListEntry.Flink->Blink != ¤t->Used.ListEntry) + { + DbgPrint("%s:%d:Break in list (current %x next %x " + "current->next->previous %x)\n", + __FILE__,__LINE__,current, current->Used.ListEntry.Flink, + current->Used.ListEntry.Flink->Blink); + KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0); + } + + current_entry = current_entry->Flink; + } } static void check_duplicates(BLOCK_HDR* blk) @@ -1044,52 +1048,52 @@ static void check_duplicates(BLOCK_HDR* blk) p = avl_get_first(FreeBlockListRoot); while (p) - { - current = CONTAINING_RECORD(p, BLOCK_HDR, Free.Node); + { + current = CONTAINING_RECORD(p, BLOCK_HDR, Free.Node); - if (current->Magic != BLOCK_HDR_FREE_MAGIC) - { - DbgPrint("Bad block magic (probable pool corruption) at %x\n", - current); - KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0); - } - - if ( (char*)current > base && (char*)current < last ) - { - DbgPrint("intersecting blocks on list\n"); - KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0); - } - if ( (char*)current < base && - ((char*)current + current->Size + BLOCK_HDR_SIZE) - > base ) - { - DbgPrint("intersecting blocks on list\n"); - KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0); - } - p = avl_get_next(FreeBlockListRoot, p); - } + if (current->Magic != BLOCK_HDR_FREE_MAGIC) + { + DbgPrint("Bad block magic (probable pool corruption) at %x\n", + current); + KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0); + } + + if ( (char*)current > base && (char*)current < last ) + { + DbgPrint("intersecting blocks on list\n"); + KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0); + } + if ( (char*)current < base && + ((char*)current + current->Size + BLOCK_HDR_SIZE) + > base ) + { + DbgPrint("intersecting blocks on list\n"); + KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0); + } + p = avl_get_next(FreeBlockListRoot, p); + } current_entry = UsedBlockListHead.Flink; while (current_entry != &UsedBlockListHead) - { - current = CONTAINING_RECORD(current_entry, BLOCK_HDR, Used.ListEntry); + { + current = CONTAINING_RECORD(current_entry, BLOCK_HDR, Used.ListEntry); + + if ( (char*)current > base && (char*)current < last ) + { + DbgPrint("intersecting blocks on list\n"); + KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0); + } + if ( (char*)current < base && + ((char*)current + current->Size + BLOCK_HDR_SIZE) + > base ) + { + DbgPrint("intersecting blocks on list\n"); + KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0); + } + + current_entry = current_entry->Flink; + } - if ( (char*)current > base && (char*)current < last ) - { - DbgPrint("intersecting blocks on list\n"); - KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0); - } - if ( (char*)current < base && - ((char*)current + current->Size + BLOCK_HDR_SIZE) - > base ) - { - DbgPrint("intersecting blocks on list\n"); - KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0); - } - - current_entry = current_entry->Flink; - } - } static void validate_kernel_pool(void) @@ -1100,24 +1104,24 @@ static void validate_kernel_pool(void) BLOCK_HDR* current; PLIST_ENTRY current_entry; PNODE p; - + validate_free_list(); validate_used_list(); p = avl_get_first(FreeBlockListRoot); while (p) - { - current = CONTAINING_RECORD(p, BLOCK_HDR, Free.Node); - check_duplicates(current); - p = avl_get_next(FreeBlockListRoot, p); - } + { + current = CONTAINING_RECORD(p, BLOCK_HDR, Free.Node); + check_duplicates(current); + p = avl_get_next(FreeBlockListRoot, p); + } current_entry = UsedBlockListHead.Flink; while (current_entry != &UsedBlockListHead) - { - current = CONTAINING_RECORD(current_entry, BLOCK_HDR, Used.ListEntry); - check_duplicates(current); - current_entry = current_entry->Flink; - } + { + current = CONTAINING_RECORD(current_entry, BLOCK_HDR, Used.ListEntry); + check_duplicates(current); + current_entry = current_entry->Flink; + } } #endif @@ -1125,91 +1129,93 @@ static void validate_kernel_pool(void) STATIC VOID free_pages(BLOCK_HDR* blk) { - ULONG start; - ULONG end; - ULONG i; + ULONG start; + ULONG end; + ULONG i; - start = (ULONG)blk; - end = (ULONG)blk + BLOCK_HDR_SIZE + blk->Size; + start = (ULONG)blk; + end = (ULONG)blk + BLOCK_HDR_SIZE + blk->Size; - /* - * If the block doesn't contain a whole page then there is nothing to do - */ - if (PAGE_ROUND_UP(start) >= PAGE_ROUND_DOWN(end)) - { + /* + * If the block doesn't contain a whole page then there is nothing to do + */ + if (PAGE_ROUND_UP(start) >= PAGE_ROUND_DOWN(end)) + { return; - } + } } #endif static void remove_from_used_list(BLOCK_HDR* current) { - RemoveEntryList(¤t->Used.ListEntry); - EiUsedNonPagedPool -= current->Size; - EiNrUsedBlocks--; + RemoveEntryList(¤t->Used.ListEntry); + EiUsedNonPagedPool -= current->Size; + EiNrUsedBlocks--; } static void remove_from_free_list(BLOCK_HDR* current) { - DPRINT("remove_from_free_list %d\n", current->Size); + DPRINT("remove_from_free_list %d\n", current->Size); - avl_remove(&FreeBlockListRoot, ¤t->Free.Node, compare_node); + avl_remove(&FreeBlockListRoot, ¤t->Free.Node, compare_node); - EiFreeNonPagedPool -= current->Size; - EiNrFreeBlocks--; - DPRINT("remove_from_free_list done\n"); + EiFreeNonPagedPool -= current->Size; + EiNrFreeBlocks--; + DPRINT("remove_from_free_list done\n"); #ifdef DUMP_AVL - DumpFreeBlockTree(); + + DumpFreeBlockTree(); #endif } -static void +static void add_to_free_list(BLOCK_HDR* blk) /* * FUNCTION: add the block to the free list (internal) */ { - BLOCK_HDR* current; - BOOL UpdatePrevPtr = FALSE; + BLOCK_HDR* current; + BOOL UpdatePrevPtr = FALSE; - DPRINT("add_to_free_list (%d)\n", blk->Size); + DPRINT("add_to_free_list (%d)\n", blk->Size); - EiNrFreeBlocks++; - - current = blk->previous; - if (current && current->Magic == BLOCK_HDR_FREE_MAGIC) - { + EiNrFreeBlocks++; + + current = blk->previous; + if (current && current->Magic == BLOCK_HDR_FREE_MAGIC) + { remove_from_free_list(current); current->Size = current->Size + BLOCK_HDR_SIZE + blk->Size; current->Magic = BLOCK_HDR_USED_MAGIC; memset(blk, 0xcc, BLOCK_HDR_SIZE); blk = current; UpdatePrevPtr = TRUE; - } + } - current = (BLOCK_HDR*)((char*)blk + BLOCK_HDR_SIZE + blk->Size); - if ((char*)current < (char*)MiNonPagedPoolStart + MiNonPagedPoolLength && - current->Magic == BLOCK_HDR_FREE_MAGIC) - { + current = (BLOCK_HDR*)((char*)blk + BLOCK_HDR_SIZE + blk->Size); + if ((char*)current < (char*)MiNonPagedPoolStart + MiNonPagedPoolLength && + current->Magic == BLOCK_HDR_FREE_MAGIC) + { remove_from_free_list(current); blk->Size += BLOCK_HDR_SIZE + current->Size; memset(current, 0xcc, BLOCK_HDR_SIZE); UpdatePrevPtr = TRUE; current = (BLOCK_HDR*)((char*)blk + BLOCK_HDR_SIZE + blk->Size); - } - if (UpdatePrevPtr && - (char*)current < (char*)MiNonPagedPoolStart + MiNonPagedPoolLength) - { + } + if (UpdatePrevPtr && + (char*)current < (char*)MiNonPagedPoolStart + MiNonPagedPoolLength) + { current->previous = blk; - } - DPRINT("%d\n", blk->Size); - blk->Magic = BLOCK_HDR_FREE_MAGIC; - EiFreeNonPagedPool += blk->Size; - avl_insert(&FreeBlockListRoot, &blk->Free.Node, compare_node); + } + DPRINT("%d\n", blk->Size); + blk->Magic = BLOCK_HDR_FREE_MAGIC; + EiFreeNonPagedPool += blk->Size; + avl_insert(&FreeBlockListRoot, &blk->Free.Node, compare_node); - DPRINT("add_to_free_list done\n"); + DPRINT("add_to_free_list done\n"); #ifdef DUMP_AVL - DumpFreeBlockTree(); + + DumpFreeBlockTree(); #endif } @@ -1218,9 +1224,9 @@ static void add_to_used_list(BLOCK_HDR* blk) * FUNCTION: add the block to the used list (internal) */ { - InsertHeadList(&UsedBlockListHead, &blk->Used.ListEntry); - EiUsedNonPagedPool += blk->Size; - EiNrUsedBlocks++; + InsertHeadList(&UsedBlockListHead, &blk->Used.ListEntry); + EiUsedNonPagedPool += blk->Size; + EiNrUsedBlocks++; } inline static void* block_to_address(BLOCK_HDR* blk) @@ -1229,13 +1235,13 @@ inline static void* block_to_address(BLOCK_HDR* blk) * address (internal) */ { - return ( (void *) ((char*)blk + BLOCK_HDR_SIZE)); + return ( (void *) ((char*)blk + BLOCK_HDR_SIZE)); } inline static BLOCK_HDR* address_to_block(void* addr) { - return (BLOCK_HDR *) - ( ((char*)addr) - BLOCK_HDR_SIZE ); + return (BLOCK_HDR *) + ( ((char*)addr) - BLOCK_HDR_SIZE ); } static BOOLEAN @@ -1250,42 +1256,45 @@ grow_block(BLOCK_HDR* blk, PVOID end) end = (PVOID)PAGE_ROUND_UP(end); index = (ULONG)((char*)start - (char*)MiNonPagedPoolStart) / PAGE_SIZE; while (start < end) - { - if (!(MiNonPagedPoolAllocMap[index / 32] & (1 << (index % 32)))) + { + if (!(MiNonPagedPoolAllocMap[index / 32] & (1 << (index % 32)))) + { + Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Page); + if (!NT_SUCCESS(Status)) { - Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Page); - if (!NT_SUCCESS(Status)) - { - result = FALSE; - break; - } - Status = MmCreateVirtualMapping(NULL, - start, - PAGE_READWRITE|PAGE_SYSTEM, - Page, - FALSE); - if (!NT_SUCCESS(Status)) - { - DbgPrint("Unable to create virtual mapping\n"); - MmReleasePageMemoryConsumer(MC_NPPOOL, Page); - result = FALSE; - break; - } - MiNonPagedPoolAllocMap[index / 32] |= (1 << (index % 32)); - memset(start, 0xcc, PAGE_SIZE); - MiNonPagedPoolNrOfPages++; - } - index++; + result = FALSE; + break; + } + Status = MmCreateVirtualMapping(NULL, + start, + PAGE_READWRITE|PAGE_SYSTEM, + Page, + FALSE); + if (!NT_SUCCESS(Status)) + { + DbgPrint("Unable to create virtual mapping\n"); + MmReleasePageMemoryConsumer(MC_NPPOOL, Page); + result = FALSE; + break; + } + MiNonPagedPoolAllocMap[index / 32] |= (1 << (index % 32)); + memset(start, 0xcc, PAGE_SIZE); + MiNonPagedPoolNrOfPages++; + } + index++; #if defined(__GNUC__) - start += PAGE_SIZE; + + start += PAGE_SIZE; #else - { - char* pTemp = start; - pTemp += PAGE_SIZE; - start = pTemp; - } + + { + char* pTemp = start; + pTemp += PAGE_SIZE; + start = pTemp; + } #endif - } + + } return result; } @@ -1296,164 +1305,164 @@ static BLOCK_HDR* get_block(unsigned int size, unsigned long alignment) PVOID end; PVOID addr, aligned_addr; PNODE p; - + DPRINT("get_block %d\n", size); if (alignment == 0) - { - p = avl_find_equal_or_greater(FreeBlockListRoot, size, compare_value); - if (p) - { - best = CONTAINING_RECORD(p, BLOCK_HDR, Free.Node); - addr = block_to_address(best); - } - } + { + p = avl_find_equal_or_greater(FreeBlockListRoot, size, compare_value); + if (p) + { + best = CONTAINING_RECORD(p, BLOCK_HDR, Free.Node); + addr = block_to_address(best); + } + } else - { - p = avl_find_equal_or_greater(FreeBlockListRoot, size, compare_value); + { + p = avl_find_equal_or_greater(FreeBlockListRoot, size, compare_value); - while(p) + while(p) + { + current = CONTAINING_RECORD(p, BLOCK_HDR, Free.Node); + addr = block_to_address(current); + /* calculate first aligned address available within this block */ + aligned_addr = MM_ROUND_UP(addr, alignment); + /* check to see if this address is already aligned */ + if (addr == aligned_addr) { - current = CONTAINING_RECORD(p, BLOCK_HDR, Free.Node); - addr = block_to_address(current); - /* calculate first aligned address available within this block */ - aligned_addr = MM_ROUND_UP(addr, alignment); - /* check to see if this address is already aligned */ - if (addr == aligned_addr) - { - if (current->Size >= size && - (best == NULL || current->Size < best->Size)) - { - best = current; - } - } - else - { - /* make sure there's enough room to make a free block by the space skipped - * from alignment. If not, calculate forward to the next alignment - * and see if we allocate there... - */ + if (current->Size >= size && + (best == NULL || current->Size < best->Size)) + { + best = current; + } + } + else + { + /* make sure there's enough room to make a free block by the space skipped + * from alignment. If not, calculate forward to the next alignment + * and see if we allocate there... + */ + new_size = (ULONG)aligned_addr - (ULONG)addr + size; + if ((ULONG)aligned_addr - (ULONG)addr < BLOCK_HDR_SIZE) + { + /* not enough room for a free block header, add some more bytes */ + aligned_addr = MM_ROUND_UP(block_to_address((BLOCK_HDR*)((char*)current + BLOCK_HDR_SIZE)), alignment); new_size = (ULONG)aligned_addr - (ULONG)addr + size; - if ((ULONG)aligned_addr - (ULONG)addr < BLOCK_HDR_SIZE) - { - /* not enough room for a free block header, add some more bytes */ - aligned_addr = MM_ROUND_UP(block_to_address((BLOCK_HDR*)((char*)current + BLOCK_HDR_SIZE)), alignment); - new_size = (ULONG)aligned_addr - (ULONG)addr + size; - } - if (current->Size >= new_size && - (best == NULL || current->Size < best->Size)) - { - best = current; - } - } - if (best && current->Size >= size + alignment + 2 * BLOCK_HDR_SIZE) - { - break; - } - p = avl_get_next(FreeBlockListRoot, p); + } + if (current->Size >= new_size && + (best == NULL || current->Size < best->Size)) + { + best = current; + } + } + if (best && current->Size >= size + alignment + 2 * BLOCK_HDR_SIZE) + { + break; + } + p = avl_get_next(FreeBlockListRoot, p); - } - } + } + } /* * We didn't find anything suitable at all. */ if (best == NULL) - { - return NULL; - } + { + return NULL; + } current = best; current_size = current->Size; if (alignment > 0) - { - addr = block_to_address(current); - aligned_addr = MM_ROUND_UP(addr, alignment); - if (addr != aligned_addr) + { + addr = block_to_address(current); + aligned_addr = MM_ROUND_UP(addr, alignment); + if (addr != aligned_addr) + { + blk = address_to_block(aligned_addr); + if ((char*)blk < (char*)current + BLOCK_HDR_SIZE) { - blk = address_to_block(aligned_addr); - if ((char*)blk < (char*)current + BLOCK_HDR_SIZE) - { - aligned_addr = MM_ROUND_UP(block_to_address((BLOCK_HDR*)((char*)current + BLOCK_HDR_SIZE)), alignment); - blk = address_to_block(aligned_addr); - } - /* - * if size-aligned, break off the preceding bytes into their own block... - */ - previous = current; - previous_size = (ULONG)blk - (ULONG)previous - BLOCK_HDR_SIZE; - current = blk; - current_size -= ((ULONG)current - (ULONG)previous); - } - } + aligned_addr = MM_ROUND_UP(block_to_address((BLOCK_HDR*)((char*)current + BLOCK_HDR_SIZE)), alignment); + blk = address_to_block(aligned_addr); + } + /* + * if size-aligned, break off the preceding bytes into their own block... + */ + previous = current; + previous_size = (ULONG)blk - (ULONG)previous - BLOCK_HDR_SIZE; + current = blk; + current_size -= ((ULONG)current - (ULONG)previous); + } + } end = (char*)current + BLOCK_HDR_SIZE + size; if (current_size >= size + BLOCK_HDR_SIZE + MM_POOL_ALIGNMENT) - { - /* create a new free block after our block, if the memory size is >= 4 byte for this block */ - next = (BLOCK_HDR*)((ULONG)current + size + BLOCK_HDR_SIZE); - next_size = current_size - size - BLOCK_HDR_SIZE; - current_size = size; - end = (char*)next + BLOCK_HDR_SIZE; - } + { + /* create a new free block after our block, if the memory size is >= 4 byte for this block */ + next = (BLOCK_HDR*)((ULONG)current + size + BLOCK_HDR_SIZE); + next_size = current_size - size - BLOCK_HDR_SIZE; + current_size = size; + end = (char*)next + BLOCK_HDR_SIZE; + } if (previous) - { - remove_from_free_list(previous); - if (!grow_block(previous, end)) + { + remove_from_free_list(previous); + if (!grow_block(previous, end)) + { + add_to_free_list(previous); + return NULL; + } + memset(current, 0, BLOCK_HDR_SIZE); + current->Size = current_size; + current->Magic = BLOCK_HDR_USED_MAGIC; + current->previous = previous; + previous->Size = previous_size; + if (next == NULL) + { + blk = (BLOCK_HDR*)((char*)current + BLOCK_HDR_SIZE + current->Size); + if ((char*)blk < (char*)MiNonPagedPoolStart + MiNonPagedPoolLength) { - add_to_free_list(previous); - return NULL; - } - memset(current, 0, BLOCK_HDR_SIZE); - current->Size = current_size; - current->Magic = BLOCK_HDR_USED_MAGIC; - current->previous = previous; - previous->Size = previous_size; - if (next == NULL) - { - blk = (BLOCK_HDR*)((char*)current + BLOCK_HDR_SIZE + current->Size); - if ((char*)blk < (char*)MiNonPagedPoolStart + MiNonPagedPoolLength) - { - blk->previous = current; - } - } + blk->previous = current; + } + } - add_to_free_list(previous); - } + add_to_free_list(previous); + } else - { - remove_from_free_list(current); + { + remove_from_free_list(current); - if (!grow_block(current, end)) - { - add_to_free_list(current); - return NULL; - } + if (!grow_block(current, end)) + { + add_to_free_list(current); + return NULL; + } + + current->Magic = BLOCK_HDR_USED_MAGIC; + if (next) + { + current->Size = current_size; + } + } - current->Magic = BLOCK_HDR_USED_MAGIC; - if (next) - { - current->Size = current_size; - } - } - if (next) - { - memset(next, 0, BLOCK_HDR_SIZE); + { + memset(next, 0, BLOCK_HDR_SIZE); - next->Size = next_size; - next->Magic = BLOCK_HDR_FREE_MAGIC; - next->previous = current; - blk = (BLOCK_HDR*)((char*)next + BLOCK_HDR_SIZE + next->Size); - if ((char*)blk < (char*)MiNonPagedPoolStart + MiNonPagedPoolLength) - { - blk->previous = next; - } - add_to_free_list(next); - } + next->Size = next_size; + next->Magic = BLOCK_HDR_FREE_MAGIC; + next->previous = current; + blk = (BLOCK_HDR*)((char*)next + BLOCK_HDR_SIZE + next->Size); + if ((char*)blk < (char*)MiNonPagedPoolStart + MiNonPagedPoolLength) + { + blk->previous = next; + } + add_to_free_list(next); + } add_to_used_list(current); VALIDATE_POOL; @@ -1473,19 +1482,19 @@ VOID STDCALL ExFreeNonPagedPool (PVOID block) KIRQL oldIrql; if (block == NULL) - { - return; - } + { + return; + } DPRINT("freeing block %x\n",blk); - + POOL_TRACE("ExFreePool(block %x), size %d, caller %x\n",block,blk->size, - ((PULONG)&block)[-1]); - + ((PULONG)&block)[-1]); + KeAcquireSpinLock(&MmNpoolLock, &oldIrql); ExFreeWholePageBlock(block); - KeReleaseSpinLock(&MmNpoolLock, oldIrql); + KeReleaseSpinLock(&MmNpoolLock, oldIrql); #else /* not WHOLE_PAGE_ALLOCATIONS */ @@ -1493,38 +1502,40 @@ VOID STDCALL ExFreeNonPagedPool (PVOID block) KIRQL oldIrql; if (block == NULL) - { - return; - } + { + return; + } DPRINT("freeing block %x\n",blk); - + POOL_TRACE("ExFreePool(block %x), size %d, caller %x\n",block,blk->Size, - ((PULONG)&block)[-1]); - + ((PULONG)&block)[-1]); + KeAcquireSpinLock(&MmNpoolLock, &oldIrql); VALIDATE_POOL; - + if (blk->Magic != BLOCK_HDR_USED_MAGIC) - { - if (blk->Magic == BLOCK_HDR_FREE_MAGIC) - { - DbgPrint("ExFreePool of already freed address %x\n", block); - } - else - { - DbgPrint("ExFreePool of non-allocated address %x (magic %x)\n", - block, blk->Magic); - } - KEBUGCHECK(0); - return; - } - + { + if (blk->Magic == BLOCK_HDR_FREE_MAGIC) + { + DbgPrint("ExFreePool of already freed address %x\n", block); + } + else + { + DbgPrint("ExFreePool of non-allocated address %x (magic %x)\n", + block, blk->Magic); + } + KEBUGCHECK(0); + return; + } + memset(block, 0xcc, blk->Size); #ifdef TAG_STATISTICS_TRACKING + MiRemoveFromTagHashTable(blk); #endif + remove_from_used_list(blk); blk->Magic = BLOCK_HDR_FREE_MAGIC; add_to_free_list(blk); @@ -1534,46 +1545,47 @@ VOID STDCALL ExFreeNonPagedPool (PVOID block) #endif /* WHOLE_PAGE_ALLOCATIONS */ } -PVOID STDCALL +PVOID STDCALL ExAllocateNonPagedPoolWithTag(ULONG Type, ULONG Size, ULONG Tag, PVOID Caller) { #ifdef WHOLE_PAGE_ALLOCATIONS PVOID block; KIRQL oldIrql; - + POOL_TRACE("ExAllocatePool(NumberOfBytes %d) caller %x ", - Size,Caller); - + Size,Caller); + KeAcquireSpinLock(&MmNpoolLock, &oldIrql); - + /* * accomodate this useful idiom */ if (Size == 0) - { - POOL_TRACE("= NULL\n"); - KeReleaseSpinLock(&MmNpoolLock, oldIrql); - return(NULL); - } + { + POOL_TRACE("= NULL\n"); + KeReleaseSpinLock(&MmNpoolLock, oldIrql); + return(NULL); + } block = ExAllocateWholePageBlock(Size); KeReleaseSpinLock(&MmNpoolLock, oldIrql); if (NULL == block) - { - DPRINT1("Trying to allocate %lu bytes from nonpaged pool - nothing suitable found, returning NULL\n", - Size ); - } + { + DPRINT1("Trying to allocate %lu bytes from nonpaged pool - nothing suitable found, returning NULL\n", + Size ); + } return(block); #else /* not WHOLE_PAGE_ALLOCATIONS */ + PVOID block; BLOCK_HDR* best = NULL; KIRQL oldIrql; ULONG alignment; - + POOL_TRACE("ExAllocatePool(NumberOfBytes %d) caller %x ", - Size,Caller); - + Size,Caller); + KeAcquireSpinLock(&MmNpoolLock, &oldIrql); VALIDATE_POOL; @@ -1581,131 +1593,134 @@ ExAllocateNonPagedPoolWithTag(ULONG Type, ULONG Size, ULONG Tag, PVOID Caller) #if 0 /* after some allocations print the npaged pool stats */ #ifdef TAG_STATISTICS_TRACKING + { - static ULONG counter = 0; - if (counter++ % 100000 == 0) - { - MiDebugDumpNonPagedPoolStats(FALSE); - } + static ULONG counter = 0; + if (counter++ % 100000 == 0) + { + MiDebugDumpNonPagedPoolStats(FALSE); + } } #endif #endif /* - * accomodate this useful idiom - */ + * accomodate this useful idiom + */ if (Size == 0) - { - POOL_TRACE("= NULL\n"); - KeReleaseSpinLock(&MmNpoolLock, oldIrql); - return(NULL); - } - /* Make the size dword alligned, this makes the block dword alligned */ + { + POOL_TRACE("= NULL\n"); + KeReleaseSpinLock(&MmNpoolLock, oldIrql); + return(NULL); + } + /* Make the size dword alligned, this makes the block dword alligned */ Size = ROUND_UP(Size, MM_POOL_ALIGNMENT); if (Size >= PAGE_SIZE) - { - alignment = PAGE_SIZE; - } + { + alignment = PAGE_SIZE; + } else if (Type == NonPagedPoolCacheAligned || Type == NonPagedPoolCacheAlignedMustS) - { - alignment = MM_CACHE_LINE_SIZE; - } + { + alignment = MM_CACHE_LINE_SIZE; + } else - { - alignment = 0; - } + { + alignment = 0; + } best = get_block(Size, alignment); if (best == NULL) - { + { KeReleaseSpinLock(&MmNpoolLock, oldIrql); DPRINT1("Trying to allocate %lu bytes from nonpaged pool - nothing suitable found, returning NULL\n", Size ); return NULL; - } + } best->Used.Tag = Tag; best->Used.Caller = Caller; best->Used.Dumped = FALSE; best->Used.TagListEntry.Flink = best->Used.TagListEntry.Blink = NULL; #ifdef TAG_STATISTICS_TRACKING + MiAddToTagHashTable(best); #endif + KeReleaseSpinLock(&MmNpoolLock, oldIrql); block = block_to_address(best); -/* RtlZeroMemory(block, Size);*/ + /* RtlZeroMemory(block, Size);*/ return(block); #endif /* WHOLE_PAGE_ALLOCATIONS */ } #ifdef WHOLE_PAGE_ALLOCATIONS -PVOID STDCALL +PVOID STDCALL ExAllocateWholePageBlock(ULONG Size) { - PVOID Address; - PHYSICAL_ADDRESS Page; - ULONG i; - ULONG NrPages; - ULONG Base; + PVOID Address; + PHYSICAL_ADDRESS Page; + ULONG i; + ULONG NrPages; + ULONG Base; - NrPages = ROUND_UP(Size, PAGE_SIZE) / PAGE_SIZE; + NrPages = ROUND_UP(Size, PAGE_SIZE) / PAGE_SIZE; - Base = RtlFindClearBitsAndSet(&NonPagedPoolAllocMap, NrPages + 1, NonPagedPoolAllocMapHint); - if (Base == 0xffffffff) - { + Base = RtlFindClearBitsAndSet(&NonPagedPoolAllocMap, NrPages + 1, NonPagedPoolAllocMapHint); + if (Base == 0xffffffff) + { DbgPrint("Out of non paged pool space.\n"); KEBUGCHECK(0); - } - if (NonPagedPoolAllocMapHint == Base) - { + } + if (NonPagedPoolAllocMapHint == Base) + { NonPagedPoolAllocMapHint += (NrPages + 1); - } - Address = MiNonPagedPoolStart + Base * PAGE_SIZE; + } + Address = MiNonPagedPoolStart + Base * PAGE_SIZE; - for (i = 0; i < NrPages; i++) - { + for (i = 0; i < NrPages; i++) + { Page = MmAllocPage(MC_NPPOOL, 0); if (Page.QuadPart == 0LL) - { - KEBUGCHECK(0); - } - MmCreateVirtualMapping(NULL, - Address + (i * PAGE_SIZE), - PAGE_READWRITE | PAGE_SYSTEM, - Page, - TRUE); - } + { + KEBUGCHECK(0); + } + MmCreateVirtualMapping(NULL, + Address + (i * PAGE_SIZE), + PAGE_READWRITE | PAGE_SYSTEM, + Page, + TRUE); + } - MiCurrentNonPagedPoolLength = max(MiCurrentNonPagedPoolLength, (Base + NrPages) * PAGE_SIZE); - Size = (Size + 7) & ~7; - return((PVOID)((PUCHAR)Address + (NrPages * PAGE_SIZE) - Size)); + MiCurrentNonPagedPoolLength = max(MiCurrentNonPagedPoolLength, (Base + NrPages) * PAGE_SIZE); + Size = (Size + 7) & ~7; + return((PVOID)((PUCHAR)Address + (NrPages * PAGE_SIZE) - Size)); } VOID STDCALL ExFreeWholePageBlock(PVOID Addr) { - ULONG Base; - - if (Addr < MiNonPagedPoolStart || - Addr >= (MiNonPagedPoolStart + MiCurrentNonPagedPoolLength)) - { + ULONG Base; + + if (Addr < MiNonPagedPoolStart || + Addr >= (MiNonPagedPoolStart + MiCurrentNonPagedPoolLength)) + { DbgPrint("Block %x found outside pool area\n", Addr); KEBUGCHECK(0); - } - Base = (Addr - MiNonPagedPoolStart) / PAGE_SIZE; - NonPagedPoolAllocMapHint = min(NonPagedPoolAllocMapHint, Base); - while (MmIsPagePresent(NULL, Addr)) - { + } + Base = (Addr - MiNonPagedPoolStart) / PAGE_SIZE; + NonPagedPoolAllocMapHint = min(NonPagedPoolAllocMapHint, Base); + while (MmIsPagePresent(NULL, Addr)) + { MmDeleteVirtualMapping(NULL, - Addr, - TRUE, - NULL, - NULL); + Addr, + TRUE, + NULL, + NULL); RtlClearBits(&NonPagedPoolAllocMap, Base, 1); Base++; Addr += PAGE_SIZE; - } + } } #endif /* WHOLE_PAGE_ALLOCATIONS */ @@ -1713,77 +1728,81 @@ ExFreeWholePageBlock(PVOID Addr) VOID INIT_FUNCTION MiInitializeNonPagedPool(VOID) { - NTSTATUS Status; - PHYSICAL_ADDRESS Page; - ULONG i; - PVOID Address; + NTSTATUS Status; + PHYSICAL_ADDRESS Page; + ULONG i; + PVOID Address; #ifdef WHOLE_PAGE_ALLOCATIONS #else - BLOCK_HDR* blk; + + BLOCK_HDR* blk; #endif #ifdef TAG_STATISTICS_TRACKING - for (i = 0; i < TAG_HASH_TABLE_SIZE; i++) - { + + for (i = 0; i < TAG_HASH_TABLE_SIZE; i++) + { InitializeListHead(&tag_hash_table[i]); - } + } #endif KeInitializeSpinLock(&MmNpoolLock); InitializeListHead(&UsedBlockListHead); InitializeListHead(&AddressListHead); FreeBlockListRoot = NULL; #ifdef WHOLE_PAGE_ALLOCATIONS + NonPagedPoolAllocMapHint = PAGE_ROUND_UP(MiNonPagedPoolLength / PAGE_SIZE / 8) / PAGE_SIZE; MiCurrentNonPagedPoolLength = NonPagedPoolAllocMapHint * PAGE_SIZE; Address = MiNonPagedPoolStart; for (i = 0; i < NonPagedPoolAllocMapHint; i++) - { - Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Page); - if (!NT_SUCCESS(Status)) - { - DbgPrint("Unable to allocate a page\n"); - KEBUGCHECK(0); - } - Status = MmCreateVirtualMapping(NULL, - Address, - PAGE_READWRITE|PAGE_SYSTEM, - Page, - FALSE); - if (!NT_SUCCESS(Status)) - { - DbgPrint("Unable to create virtual mapping\n"); - KEBUGCHECK(0); - } - Address += PAGE_SIZE; - } + { + Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Page); + if (!NT_SUCCESS(Status)) + { + DbgPrint("Unable to allocate a page\n"); + KEBUGCHECK(0); + } + Status = MmCreateVirtualMapping(NULL, + Address, + PAGE_READWRITE|PAGE_SYSTEM, + Page, + FALSE); + if (!NT_SUCCESS(Status)) + { + DbgPrint("Unable to create virtual mapping\n"); + KEBUGCHECK(0); + } + Address += PAGE_SIZE; + } RtlInitializeBitMap(&NonPagedPoolAllocMap, MiNonPagedPoolStart, MM_NONPAGED_POOL_SIZE / PAGE_SIZE); - RtlClearAllBits(&NonPagedPoolAllocMap); + RtlClearAllBits(&NonPagedPoolAllocMap); RtlSetBits(&NonPagedPoolAllocMap, 0, NonPagedPoolAllocMapHint); #else + MiNonPagedPoolAllocMap = block_to_address((BLOCK_HDR*)MiNonPagedPoolStart); MiNonPagedPoolNrOfPages = PAGE_ROUND_UP(ROUND_UP(MiNonPagedPoolLength / PAGE_SIZE, 32) / 8 + 2 * BLOCK_HDR_SIZE); MiNonPagedPoolNrOfPages /= PAGE_SIZE; Address = MiNonPagedPoolStart; for (i = 0; i < MiNonPagedPoolNrOfPages; i++) - { - Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Page); - if (!NT_SUCCESS(Status)) - { - DbgPrint("Unable to allocate a page\n"); - KEBUGCHECK(0); - } - Status = MmCreateVirtualMapping(NULL, - Address, - PAGE_READWRITE|PAGE_SYSTEM, - Page, - FALSE); - if (!NT_SUCCESS(Status)) - { - DbgPrint("Unable to create virtual mapping\n"); - KEBUGCHECK(0); - } - MiNonPagedPoolAllocMap[i / 32] |= (1 << (i % 32)); - Address = (PVOID)((ULONG_PTR)Address + PAGE_SIZE); - } + { + Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Page); + if (!NT_SUCCESS(Status)) + { + DbgPrint("Unable to allocate a page\n"); + KEBUGCHECK(0); + } + Status = MmCreateVirtualMapping(NULL, + Address, + PAGE_READWRITE|PAGE_SYSTEM, + Page, + FALSE); + if (!NT_SUCCESS(Status)) + { + DbgPrint("Unable to create virtual mapping\n"); + KEBUGCHECK(0); + } + MiNonPagedPoolAllocMap[i / 32] |= (1 << (i % 32)); + Address = (PVOID)((ULONG_PTR)Address + PAGE_SIZE); + } /* the first block contains the non paged pool bitmap */ blk = (BLOCK_HDR*)MiNonPagedPoolStart; memset(blk, 0, BLOCK_HDR_SIZE); @@ -1795,6 +1814,7 @@ MiInitializeNonPagedPool(VOID) blk->Used.Dumped = FALSE; add_to_used_list(blk); #ifdef TAG_STATISTICS_TRACKING + MiAddToTagHashTable(blk); #endif /* the second block is the first free block */ diff --git a/reactos/ntoskrnl/mm/pagefile.c b/reactos/ntoskrnl/mm/pagefile.c index e205f72c9cb..7583f681cb4 100644 --- a/reactos/ntoskrnl/mm/pagefile.c +++ b/reactos/ntoskrnl/mm/pagefile.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: pagefile.c,v 1.42 2004/03/04 00:07:01 navaraf Exp $ +/* $Id: pagefile.c,v 1.43 2004/04/10 22:35:25 gdalsnes Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/mm/pagefile.c @@ -53,18 +53,19 @@ typedef struct _PAGINGFILE KSPIN_LOCK AllocMapLock; ULONG AllocMapSize; PGET_RETRIEVAL_DESCRIPTOR RetrievalPointers; -} PAGINGFILE, *PPAGINGFILE; +} +PAGINGFILE, *PPAGINGFILE; typedef struct _RETRIEVEL_DESCRIPTOR_LIST { - struct _RETRIEVEL_DESCRIPTOR_LIST* Next; - GET_RETRIEVAL_DESCRIPTOR RetrievalPointers; + struct _RETRIEVEL_DESCRIPTOR_LIST* Next; + GET_RETRIEVAL_DESCRIPTOR RetrievalPointers; } RETRIEVEL_DESCRIPTOR_LIST, *PRETRIEVEL_DESCRIPTOR_LIST; /* GLOBALS *******************************************************************/ -#define PAIRS_PER_RUN (1024) +#define PAIRS_PER_RUN (1024) #define MAX_PAGING_FILES (32) @@ -83,12 +84,12 @@ static ULONG MiFreeSwapPages; /* Number of pages that have been allocated for swapping */ static ULONG MiUsedSwapPages; -/* +/* * Number of pages that have been reserved for swapping but not yet allocated */ static ULONG MiReservedSwapPages; -/* +/* * Ratio between reserved and available swap pages, e.g. setting this to five * forces one swap page to be available for every five swap pages that are * reserved. Setting this to zero turns off commit checking altogether. @@ -126,11 +127,11 @@ static BOOLEAN MmSwapSpaceMessage = FALSE; VOID MmShowOutOfSpaceMessagePagingFile(VOID) { - if (!MmSwapSpaceMessage) - { + if (!MmSwapSpaceMessage) + { DPRINT1("MM: Out of swap space.\n"); MmSwapSpaceMessage = TRUE; - } + } } LARGE_INTEGER STATIC @@ -141,46 +142,51 @@ MmGetOffsetPageFile(PGET_RETRIEVAL_DESCRIPTOR RetrievalPointers, LARGE_INTEGER O first = 0; last = RetrievalPointers->NumberOfPairs - 1; while (first <= last) - { - mid = (last - first) / 2 + first; - if ((ULONGLONG) Offset.QuadPart < RetrievalPointers->Pair[mid].Vcn) + { + mid = (last - first) / 2 + first; + if ((ULONGLONG) Offset.QuadPart < RetrievalPointers->Pair[mid].Vcn) + { + if (mid == 0) { - if (mid == 0) - { - Offset.QuadPart += RetrievalPointers->Pair[0].Lcn - RetrievalPointers->StartVcn; - return Offset; - } - else - { - if ((ULONGLONG) Offset.QuadPart >= RetrievalPointers->Pair[mid-1].Vcn) - { - Offset.QuadPart += RetrievalPointers->Pair[mid].Lcn - RetrievalPointers->Pair[mid-1].Vcn; - return Offset; - } - last = mid - 1; - } - } - else + Offset.QuadPart += RetrievalPointers->Pair[0].Lcn - RetrievalPointers->StartVcn; + return Offset; + } + else { - if (mid == RetrievalPointers->NumberOfPairs - 1) - { - break; - } - if ((ULONGLONG) Offset.QuadPart < RetrievalPointers->Pair[mid+1].Vcn) - { - Offset.QuadPart += RetrievalPointers->Pair[mid+1].Lcn - RetrievalPointers->Pair[mid].Vcn; - return Offset; - } - first = mid + 1; - } - } + if ((ULONGLONG) Offset.QuadPart >= RetrievalPointers->Pair[mid-1].Vcn) + { + Offset.QuadPart += RetrievalPointers->Pair[mid].Lcn - RetrievalPointers->Pair[mid-1].Vcn; + return Offset; + } + last = mid - 1; + } + } + else + { + if (mid == RetrievalPointers->NumberOfPairs - 1) + { + break; + } + if ((ULONGLONG) Offset.QuadPart < RetrievalPointers->Pair[mid+1].Vcn) + { + Offset.QuadPart += RetrievalPointers->Pair[mid+1].Lcn - RetrievalPointers->Pair[mid].Vcn; + return Offset; + } + first = mid + 1; + } + } KEBUGCHECK(0); #if defined(__GNUC__) + return (LARGE_INTEGER)0LL; #else + { - const LARGE_INTEGER dummy = { 0 }; - return dummy; + const LARGE_INTEGER dummy = + { + 0 + }; + return dummy; } #endif } @@ -194,37 +200,37 @@ NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PMDL Mdl) KEVENT Event; DPRINT("MmWriteToSwapPage\n"); - + if (SwapEntry == 0) - { - KEBUGCHECK(0); - return(STATUS_UNSUCCESSFUL); - } - + { + KEBUGCHECK(0); + return(STATUS_UNSUCCESSFUL); + } + i = FILE_FROM_ENTRY(SwapEntry); offset = OFFSET_FROM_ENTRY(SwapEntry); if (i >= MAX_PAGING_FILES) - { - DPRINT1("Bad swap entry 0x%.8X\n", SwapEntry); - KEBUGCHECK(0); - } + { + DPRINT1("Bad swap entry 0x%.8X\n", SwapEntry); + KEBUGCHECK(0); + } if (PagingFileList[i]->FileObject == NULL || - PagingFileList[i]->FileObject->DeviceObject == NULL) - { - DPRINT1("Bad paging file 0x%.8X\n", SwapEntry); - KEBUGCHECK(0); - } - + PagingFileList[i]->FileObject->DeviceObject == NULL) + { + DPRINT1("Bad paging file 0x%.8X\n", SwapEntry); + KEBUGCHECK(0); + } + file_offset.QuadPart = offset * PAGE_SIZE; file_offset = MmGetOffsetPageFile(PagingFileList[i]->RetrievalPointers, file_offset); - + KeInitializeEvent(&Event, NotificationEvent, FALSE); Status = IoPageWrite(PagingFileList[i]->FileObject, - Mdl, - &file_offset, - &Event, - &Iosb); + Mdl, + &file_offset, + &Event, + &Iosb); if (Status == STATUS_PENDING) { KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); @@ -242,37 +248,37 @@ NTSTATUS MmReadFromSwapPage(SWAPENTRY SwapEntry, PMDL Mdl) KEVENT Event; DPRINT("MmReadFromSwapPage\n"); - + if (SwapEntry == 0) - { - KEBUGCHECK(0); - return(STATUS_UNSUCCESSFUL); - } - + { + KEBUGCHECK(0); + return(STATUS_UNSUCCESSFUL); + } + i = FILE_FROM_ENTRY(SwapEntry); offset = OFFSET_FROM_ENTRY(SwapEntry); if (i >= MAX_PAGING_FILES) - { - DPRINT1("Bad swap entry 0x%.8X\n", SwapEntry); - KEBUGCHECK(0); - } + { + DPRINT1("Bad swap entry 0x%.8X\n", SwapEntry); + KEBUGCHECK(0); + } if (PagingFileList[i]->FileObject == NULL || - PagingFileList[i]->FileObject->DeviceObject == NULL) - { - DPRINT1("Bad paging file 0x%.8X\n", SwapEntry); - KEBUGCHECK(0); - } + PagingFileList[i]->FileObject->DeviceObject == NULL) + { + DPRINT1("Bad paging file 0x%.8X\n", SwapEntry); + KEBUGCHECK(0); + } file_offset.QuadPart = offset * PAGE_SIZE; file_offset = MmGetOffsetPageFile(PagingFileList[i]->RetrievalPointers, file_offset); - + KeInitializeEvent(&Event, NotificationEvent, FALSE); Status = IoPageRead(PagingFileList[i]->FileObject, - Mdl, - &file_offset, - &Event, - &Iosb); + Mdl, + &file_offset, + &Event, + &Iosb); if (Status == STATUS_PENDING) { KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); @@ -285,34 +291,34 @@ VOID INIT_FUNCTION MmInitPagingFile(VOID) { ULONG i; - + KeInitializeSpinLock(&PagingFileListLock); - + MiFreeSwapPages = 0; MiUsedSwapPages = 0; MiReservedSwapPages = 0; - + for (i = 0; i < MAX_PAGING_FILES; i++) - { - PagingFileList[i] = NULL; - } + { + PagingFileList[i] = NULL; + } MiPagingFileCount = 0; /* * Initialize the crash dump support. */ if (MmCoreDumpType != MM_CORE_DUMP_TYPE_NONE) - { - MmCoreDumpPageFrame = MmAllocateSection(PAGE_SIZE); - if (MmCoreDumpType == MM_CORE_DUMP_TYPE_FULL) - { - MmCoreDumpSize = MmStats.NrTotalPages * 4096 + 1024 * 1024; - } - else - { - MmCoreDumpSize = 1024 * 1024; - } - } + { + MmCoreDumpPageFrame = MmAllocateSection(PAGE_SIZE); + if (MmCoreDumpType == MM_CORE_DUMP_TYPE_FULL) + { + MmCoreDumpSize = MmStats.NrTotalPages * 4096 + 1024 * 1024; + } + else + { + MmCoreDumpSize = 1024 * 1024; + } + } } BOOLEAN @@ -320,87 +326,87 @@ MmReserveSwapPages(ULONG Nr) { KIRQL oldIrql; ULONG MiAvailSwapPages; - + KeAcquireSpinLock(&PagingFileListLock, &oldIrql); MiAvailSwapPages = - (MiFreeSwapPages * MM_PAGEFILE_COMMIT_RATIO) + MM_PAGEFILE_COMMIT_GRACE; + (MiFreeSwapPages * MM_PAGEFILE_COMMIT_RATIO) + MM_PAGEFILE_COMMIT_GRACE; MiReservedSwapPages = MiReservedSwapPages + Nr; if (MM_PAGEFILE_COMMIT_RATIO != 0 && MiAvailSwapPages < MiReservedSwapPages) - { - KeReleaseSpinLock(&PagingFileListLock, oldIrql); - return(FALSE); - } + { + KeReleaseSpinLock(&PagingFileListLock, oldIrql); + return(FALSE); + } KeReleaseSpinLock(&PagingFileListLock, oldIrql); return(TRUE); } -VOID +VOID MmDereserveSwapPages(ULONG Nr) { KIRQL oldIrql; - + KeAcquireSpinLock(&PagingFileListLock, &oldIrql); MiReservedSwapPages = MiReservedSwapPages - Nr; KeReleaseSpinLock(&PagingFileListLock, oldIrql); } -static ULONG +static ULONG MiAllocPageFromPagingFile(PPAGINGFILE PagingFile) { KIRQL oldIrql; ULONG i, j; - + KeAcquireSpinLock(&PagingFile->AllocMapLock, &oldIrql); - + for (i = 0; i < PagingFile->AllocMapSize; i++) - { - for (j = 0; j < 32; j++) - { - if (!(PagingFile->AllocMap[i] & (1 << j))) - { - break; - } - } - if (j == 32) - { - continue; - } - PagingFile->AllocMap[i] |= (1 << j); - PagingFile->UsedPages++; - PagingFile->FreePages--; - KeReleaseSpinLock(&PagingFile->AllocMapLock, oldIrql); - return((i * 32) + j); - } - + { + for (j = 0; j < 32; j++) + { + if (!(PagingFile->AllocMap[i] & (1 << j))) + { + break; + } + } + if (j == 32) + { + continue; + } + PagingFile->AllocMap[i] |= (1 << j); + PagingFile->UsedPages++; + PagingFile->FreePages--; + KeReleaseSpinLock(&PagingFile->AllocMapLock, oldIrql); + return((i * 32) + j); + } + KeReleaseSpinLock(&PagingFile->AllocMapLock, oldIrql); return(0xFFFFFFFF); } -VOID +VOID MmFreeSwapPage(SWAPENTRY Entry) { ULONG i; ULONG off; KIRQL oldIrql; - + i = FILE_FROM_ENTRY(Entry); off = OFFSET_FROM_ENTRY(Entry); - + KeAcquireSpinLock(&PagingFileListLock, &oldIrql); if (PagingFileList[i] == NULL) - { - KEBUGCHECK(0); - } + { + KEBUGCHECK(0); + } KeAcquireSpinLockAtDpcLevel(&PagingFileList[i]->AllocMapLock); - + PagingFileList[i]->AllocMap[off / 32] &= (~(1 << (off % 32))); - + PagingFileList[i]->FreePages++; PagingFileList[i]->UsedPages--; - + MiFreeSwapPages++; MiUsedSwapPages--; - + KeReleaseSpinLockFromDpcLevel(&PagingFileList[i]->AllocMapLock); KeReleaseSpinLock(&PagingFileListLock, oldIrql); } @@ -408,47 +414,47 @@ MmFreeSwapPage(SWAPENTRY Entry) BOOLEAN MmIsAvailableSwapPage(VOID) { - return(MiFreeSwapPages > 0); + return(MiFreeSwapPages > 0); } -SWAPENTRY +SWAPENTRY MmAllocSwapPage(VOID) { KIRQL oldIrql; ULONG i; ULONG off; - SWAPENTRY entry; - + SWAPENTRY entry; + KeAcquireSpinLock(&PagingFileListLock, &oldIrql); - + if (MiFreeSwapPages == 0) - { - KeReleaseSpinLock(&PagingFileListLock, oldIrql); - return(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(0); - KeReleaseSpinLock(&PagingFileListLock, oldIrql); - return(STATUS_UNSUCCESSFUL); - } - MiUsedSwapPages++; - MiFreeSwapPages--; - KeReleaseSpinLock(&PagingFileListLock, oldIrql); - - entry = ENTRY_FROM_FILE_OFFSET(i, off); - return(entry); - } - } - - KeReleaseSpinLock(&PagingFileListLock, oldIrql); + { + if (PagingFileList[i] != NULL && + PagingFileList[i]->FreePages >= 1) + { + off = MiAllocPageFromPagingFile(PagingFileList[i]); + if (off == 0xFFFFFFFF) + { + KEBUGCHECK(0); + KeReleaseSpinLock(&PagingFileListLock, oldIrql); + return(STATUS_UNSUCCESSFUL); + } + MiUsedSwapPages++; + MiFreeSwapPages--; + KeReleaseSpinLock(&PagingFileListLock, oldIrql); + + entry = ENTRY_FROM_FILE_OFFSET(i, off); + return(entry); + } + } + + KeReleaseSpinLock(&PagingFileListLock, oldIrql); KEBUGCHECK(0); return(0); } @@ -462,267 +468,275 @@ MmAllocRetrievelDescriptorList(ULONG Pairs) Size = sizeof(RETRIEVEL_DESCRIPTOR_LIST) + Pairs * sizeof(MAPPING_PAIR); RetDescList = ExAllocatePool(NonPagedPool, Size); if (RetDescList) - { - RtlZeroMemory(RetDescList, Size); - } + { + RtlZeroMemory(RetDescList, Size); + } return RetDescList; } -NTSTATUS STDCALL +NTSTATUS STDCALL MmDumpToPagingFile(ULONG BugCode, - ULONG BugCodeParameter1, - ULONG BugCodeParameter2, - ULONG BugCodeParameter3, - ULONG BugCodeParameter4, - PKTRAP_FRAME TrapFrame) + ULONG BugCodeParameter1, + ULONG BugCodeParameter2, + ULONG BugCodeParameter3, + ULONG BugCodeParameter4, + PKTRAP_FRAME TrapFrame) { - PMM_CORE_DUMP_HEADER Headers; - NTSTATUS Status; - UCHAR MdlBase[sizeof(MDL) + sizeof(PVOID)]; - PMDL Mdl = (PMDL)MdlBase; - PETHREAD Thread = PsGetCurrentThread(); - ULONG StackSize; - PULONG MdlMap; - LONGLONG NextOffset = 0; - ULONG i; - PGET_RETRIEVAL_DESCRIPTOR RetrievalPointers; - LARGE_INTEGER DiskOffset; + PMM_CORE_DUMP_HEADER Headers; + NTSTATUS Status; + UCHAR MdlBase[sizeof(MDL) + sizeof(PVOID)]; + PMDL Mdl = (PMDL)MdlBase; + PETHREAD Thread = PsGetCurrentThread(); + ULONG StackSize; + PULONG MdlMap; + LONGLONG NextOffset = 0; + ULONG i; + PGET_RETRIEVAL_DESCRIPTOR RetrievalPointers; + LARGE_INTEGER DiskOffset; - if (MmCoreDumpPageFile == 0xFFFFFFFF) - { + if (MmCoreDumpPageFile == 0xFFFFFFFF) + { return(STATUS_UNSUCCESSFUL); - } + } - DbgPrint("\nMM: Dumping core: "); + DbgPrint("\nMM: Dumping core: "); - /* Prepare the dump headers. */ - Headers = (PMM_CORE_DUMP_HEADER)MmCoreDumpPageFrame; - Headers->Magic = MM_CORE_DUMP_HEADER_MAGIC; - Headers->Version = MM_CORE_DUMP_HEADER_VERSION; - Headers->Type = MmCoreDumpType; - if (TrapFrame != NULL) - { + /* Prepare the dump headers. */ + Headers = (PMM_CORE_DUMP_HEADER)MmCoreDumpPageFrame; + Headers->Magic = MM_CORE_DUMP_HEADER_MAGIC; + Headers->Version = MM_CORE_DUMP_HEADER_VERSION; + Headers->Type = MmCoreDumpType; + if (TrapFrame != NULL) + { if (!(TrapFrame->Eflags & (1 << 17))) - { - memcpy(&Headers->TrapFrame, TrapFrame, - sizeof(KTRAP_FRAME) - (4 * sizeof(DWORD))); - } + { + memcpy(&Headers->TrapFrame, TrapFrame, + sizeof(KTRAP_FRAME) - (4 * sizeof(DWORD))); + } else - { - memcpy(&Headers->TrapFrame, TrapFrame, sizeof(KTRAP_FRAME)); - } - } - Headers->BugCheckCode = BugCode; - Headers->BugCheckParameters[0] = BugCodeParameter1; - Headers->BugCheckParameters[1] = BugCodeParameter2; - Headers->BugCheckParameters[2] = BugCodeParameter3; - Headers->BugCheckParameters[3] = BugCodeParameter4; - Headers->FaultingStackBase = (PVOID)Thread->Tcb.StackLimit; - Headers->FaultingStackSize = StackSize = - (ULONG)((char*)Thread->Tcb.StackBase - Thread->Tcb.StackLimit); - Headers->PhysicalMemorySize = MmStats.NrTotalPages * PAGE_SIZE; + { + memcpy(&Headers->TrapFrame, TrapFrame, sizeof(KTRAP_FRAME)); + } + } + Headers->BugCheckCode = BugCode; + Headers->BugCheckParameters[0] = BugCodeParameter1; + Headers->BugCheckParameters[1] = BugCodeParameter2; + Headers->BugCheckParameters[2] = BugCodeParameter3; + Headers->BugCheckParameters[3] = BugCodeParameter4; + Headers->FaultingStackBase = (PVOID)Thread->Tcb.StackLimit; + Headers->FaultingStackSize = StackSize = + (ULONG)((char*)Thread->Tcb.StackBase - Thread->Tcb.StackLimit); + Headers->PhysicalMemorySize = MmStats.NrTotalPages * PAGE_SIZE; - /* Initialize the dump device. */ - Status = MmCoreDumpFunctions->DumpInit(); - if (!NT_SUCCESS(Status)) - { + /* Initialize the dump device. */ + Status = MmCoreDumpFunctions->DumpInit(); + if (!NT_SUCCESS(Status)) + { DPRINT1("MM: Failed to initialize core dump device.\n"); return(Status); - } + } - /* Initialize the MDL. */ - Mdl->Next = NULL; - Mdl->Size = sizeof(MDL) + sizeof(PVOID); - Mdl->MdlFlags = MDL_SOURCE_IS_NONPAGED_POOL; - Mdl->Process = NULL; - Mdl->MappedSystemVa = MmCoreDumpPageFrame; - Mdl->StartVa = NULL; - Mdl->ByteCount = PAGE_SIZE; - Mdl->ByteOffset = 0; - MdlMap = (PULONG)(Mdl + 1); + /* Initialize the MDL. */ + Mdl->Next = NULL; + Mdl->Size = sizeof(MDL) + sizeof(PVOID); + Mdl->MdlFlags = MDL_SOURCE_IS_NONPAGED_POOL; + Mdl->Process = NULL; + Mdl->MappedSystemVa = MmCoreDumpPageFrame; + Mdl->StartVa = NULL; + Mdl->ByteCount = PAGE_SIZE; + Mdl->ByteOffset = 0; + MdlMap = (PULONG)(Mdl + 1); - - /* Initialize the retrieval offsets. */ - RetrievalPointers = PagingFileList[MmCoreDumpPageFile]->RetrievalPointers; - /* Dump the header. */ - MdlMap[0] = MmGetPhysicalAddress(MmCoreDumpPageFrame).u.LowPart; + /* Initialize the retrieval offsets. */ + RetrievalPointers = PagingFileList[MmCoreDumpPageFile]->RetrievalPointers; + + /* Dump the header. */ + MdlMap[0] = MmGetPhysicalAddress(MmCoreDumpPageFrame).u.LowPart; #if defined(__GNUC__) - DiskOffset = MmGetOffsetPageFile(RetrievalPointers, (LARGE_INTEGER)0LL); + + DiskOffset = MmGetOffsetPageFile(RetrievalPointers, (LARGE_INTEGER)0LL); #else - { - const LARGE_INTEGER dummy = { 0 }; - DiskOffset = MmGetOffsetPageFile(RetrievalPointers, dummy); - } + + { + const LARGE_INTEGER dummy = + { + 0 + }; + DiskOffset = MmGetOffsetPageFile(RetrievalPointers, dummy); + } #endif - DiskOffset.QuadPart += MmCoreDumpLcnMapping.LcnDiskOffset.QuadPart; - Status = MmCoreDumpFunctions->DumpWrite(DiskOffset, Mdl); - if (!NT_SUCCESS(Status)) - { + DiskOffset.QuadPart += MmCoreDumpLcnMapping.LcnDiskOffset.QuadPart; + Status = MmCoreDumpFunctions->DumpWrite(DiskOffset, Mdl); + if (!NT_SUCCESS(Status)) + { DPRINT1("MM: Failed to write core dump header\n."); return(Status); - } - NextOffset += PAGE_SIZE;; - DbgPrint("00"); + } + NextOffset += PAGE_SIZE; + ; + DbgPrint("00"); - - /* Write out the contents of physical memory. */ - if (MmCoreDumpType == MM_CORE_DUMP_TYPE_FULL) - { + + /* Write out the contents of physical memory. */ + if (MmCoreDumpType == MM_CORE_DUMP_TYPE_FULL) + { for (i = 0; i < MmStats.NrTotalPages; i++) - { - LARGE_INTEGER PhysicalAddress; - PhysicalAddress.QuadPart = i * PAGE_SIZE; - MdlMap[0] = i * PAGE_SIZE; - MmCreateVirtualMappingDump(MmCoreDumpPageFrame, - PAGE_READWRITE, - PhysicalAddress); + { + LARGE_INTEGER PhysicalAddress; + PhysicalAddress.QuadPart = i * PAGE_SIZE; + MdlMap[0] = i * PAGE_SIZE; + MmCreateVirtualMappingDump(MmCoreDumpPageFrame, + PAGE_READWRITE, + PhysicalAddress); #if defined(__GNUC__) - DiskOffset = MmGetOffsetPageFile(RetrievalPointers, - (LARGE_INTEGER)NextOffset); -#else - { - LARGE_INTEGER dummy; - dummy.QuadPart = NextOffset; - DiskOffset = MmGetOffsetPageFile(RetrievalPointers, dummy); - } -#endif - DiskOffset.QuadPart += MmCoreDumpLcnMapping.LcnDiskOffset.QuadPart; - Status = MmCoreDumpFunctions->DumpWrite(DiskOffset, Mdl); - if (!NT_SUCCESS(Status)) - { - DPRINT1("MM: Failed to write page to core dump.\n"); - return(Status); - } - if ((i % ((1024*1024) / PAGE_SIZE)) == 0) - { - DbgPrint("\b\b%.2d", i / ((1024*1024)/PAGE_SIZE)); - } - NextOffset += PAGE_SIZE; - } - } - DbgPrint("\n"); - MmCoreDumpFunctions->DumpFinish(); - return(STATUS_SUCCESS); + DiskOffset = MmGetOffsetPageFile(RetrievalPointers, + (LARGE_INTEGER)NextOffset); +#else + + { + LARGE_INTEGER dummy; + dummy.QuadPart = NextOffset; + DiskOffset = MmGetOffsetPageFile(RetrievalPointers, dummy); + } +#endif + DiskOffset.QuadPart += MmCoreDumpLcnMapping.LcnDiskOffset.QuadPart; + Status = MmCoreDumpFunctions->DumpWrite(DiskOffset, Mdl); + if (!NT_SUCCESS(Status)) + { + DPRINT1("MM: Failed to write page to core dump.\n"); + return(Status); + } + if ((i % ((1024*1024) / PAGE_SIZE)) == 0) + { + DbgPrint("\b\b%.2d", i / ((1024*1024)/PAGE_SIZE)); + } + NextOffset += PAGE_SIZE; + } + } + + DbgPrint("\n"); + MmCoreDumpFunctions->DumpFinish(); + return(STATUS_SUCCESS); } NTSTATUS STDCALL MmInitializeCrashDump(HANDLE PageFileHandle, ULONG PageFileNum) { - PFILE_OBJECT PageFile; - PDEVICE_OBJECT PageFileDevice; - NTSTATUS Status; - PIRP Irp; - KEVENT Event; - IO_STATUS_BLOCK Iosb; - UNICODE_STRING DiskDumpName; - ANSI_STRING ProcName; - PIO_STACK_LOCATION StackPtr; - PMODULE_OBJECT ModuleObject; + PFILE_OBJECT PageFile; + PDEVICE_OBJECT PageFileDevice; + NTSTATUS Status; + PIRP Irp; + KEVENT Event; + IO_STATUS_BLOCK Iosb; + UNICODE_STRING DiskDumpName; + ANSI_STRING ProcName; + PIO_STACK_LOCATION StackPtr; + PMODULE_OBJECT ModuleObject; - Status = ZwFsControlFile(PageFileHandle, - 0, - NULL, - NULL, - &Iosb, - FSCTL_ROS_QUERY_LCN_MAPPING, - NULL, - 0, - &MmCoreDumpLcnMapping, - sizeof(ROS_QUERY_LCN_MAPPING)); - if (!NT_SUCCESS(Status) || - Iosb.Information != sizeof(ROS_QUERY_LCN_MAPPING)) - { + Status = ZwFsControlFile(PageFileHandle, + 0, + NULL, + NULL, + &Iosb, + FSCTL_ROS_QUERY_LCN_MAPPING, + NULL, + 0, + &MmCoreDumpLcnMapping, + sizeof(ROS_QUERY_LCN_MAPPING)); + if (!NT_SUCCESS(Status) || + Iosb.Information != sizeof(ROS_QUERY_LCN_MAPPING)) + { return(Status); - } + } - /* Get the underlying storage device. */ - Status = - ObReferenceObjectByHandle(PageFileHandle, - FILE_ALL_ACCESS, - NULL, - KernelMode, - (PVOID*)&PageFile, - NULL); - if (!NT_SUCCESS(Status)) - { + /* Get the underlying storage device. */ + Status = + ObReferenceObjectByHandle(PageFileHandle, + FILE_ALL_ACCESS, + NULL, + KernelMode, + (PVOID*)&PageFile, + NULL); + if (!NT_SUCCESS(Status)) + { return(Status); - } + } - PageFileDevice = PageFile->Vpb->RealDevice; + PageFileDevice = PageFile->Vpb->RealDevice; - /* Get the dump pointers. */ - KeInitializeEvent(&Event, NotificationEvent, FALSE); - Irp = IoBuildDeviceIoControlRequest(IOCTL_SCSI_GET_DUMP_POINTERS, - PageFileDevice, - NULL, - 0, - &MmCoreDumpPointers, - sizeof(MmCoreDumpPointers), - FALSE, - &Event, - &Iosb); - StackPtr = IoGetNextIrpStackLocation(Irp); - StackPtr->FileObject = PageFile; - StackPtr->DeviceObject = PageFileDevice; - StackPtr->Parameters.DeviceIoControl.InputBufferLength = 0; - StackPtr->Parameters.DeviceIoControl.OutputBufferLength = sizeof(MmCoreDumpPointers); - - Status = IoCallDriver(PageFileDevice,Irp); - if (Status == STATUS_PENDING) - { + /* Get the dump pointers. */ + KeInitializeEvent(&Event, NotificationEvent, FALSE); + Irp = IoBuildDeviceIoControlRequest(IOCTL_SCSI_GET_DUMP_POINTERS, + PageFileDevice, + NULL, + 0, + &MmCoreDumpPointers, + sizeof(MmCoreDumpPointers), + FALSE, + &Event, + &Iosb); + StackPtr = IoGetNextIrpStackLocation(Irp); + StackPtr->FileObject = PageFile; + StackPtr->DeviceObject = PageFileDevice; + StackPtr->Parameters.DeviceIoControl.InputBufferLength = 0; + StackPtr->Parameters.DeviceIoControl.OutputBufferLength = sizeof(MmCoreDumpPointers); + + Status = IoCallDriver(PageFileDevice,Irp); + if (Status == STATUS_PENDING) + { Status = KeWaitForSingleObject(&Event, - Executive, - KernelMode, - FALSE, - NULL); - } - if (Status != STATUS_SUCCESS || - Iosb.Information != sizeof(MmCoreDumpPointers)) - { + Executive, + KernelMode, + FALSE, + NULL); + } + if (Status != STATUS_SUCCESS || + Iosb.Information != sizeof(MmCoreDumpPointers)) + { ObDereferenceObject(PageFile); return(Status); - } + } - /* Load the diskdump driver. */ - RtlRosInitUnicodeStringFromLiteral(&DiskDumpName, L"DiskDump"); - ModuleObject = LdrGetModuleObject(&DiskDumpName); - if (ModuleObject == NULL) - { + /* Load the diskdump driver. */ + RtlRosInitUnicodeStringFromLiteral(&DiskDumpName, L"DiskDump"); + ModuleObject = LdrGetModuleObject(&DiskDumpName); + if (ModuleObject == NULL) + { return(STATUS_OBJECT_NAME_NOT_FOUND); - } - RtlInitAnsiString(&ProcName, "DiskDumpFunctions"); - Status = LdrGetProcedureAddress(ModuleObject->Base, - &ProcName, - 0, - (PVOID*)&MmCoreDumpFunctions); - if (!NT_SUCCESS(Status)) - { + } + RtlInitAnsiString(&ProcName, "DiskDumpFunctions"); + Status = LdrGetProcedureAddress(ModuleObject->Base, + &ProcName, + 0, + (PVOID*)&MmCoreDumpFunctions); + if (!NT_SUCCESS(Status)) + { ObDereferenceObject(PageFile); return(Status); - } + } - /* Prepare for disk dumping. */ - Status = MmCoreDumpFunctions->DumpPrepare(PageFileDevice, - &MmCoreDumpPointers); - if (!NT_SUCCESS(Status)) - { + /* Prepare for disk dumping. */ + Status = MmCoreDumpFunctions->DumpPrepare(PageFileDevice, + &MmCoreDumpPointers); + if (!NT_SUCCESS(Status)) + { ObDereferenceObject(PageFile); return(Status); - } + } - MmCoreDumpPageFile = PageFileNum; - ObDereferenceObject(PageFile); - return(STATUS_SUCCESS); + MmCoreDumpPageFile = PageFileNum; + ObDereferenceObject(PageFile); + return(STATUS_SUCCESS); } NTSTATUS STDCALL NtCreatePagingFile(IN PUNICODE_STRING FileName, - IN PLARGE_INTEGER InitialSize, - IN PLARGE_INTEGER MaximumSize, - IN ULONG Reserved) + IN PLARGE_INTEGER InitialSize, + IN PLARGE_INTEGER MaximumSize, + IN ULONG Reserved) { NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; @@ -744,158 +758,160 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName, ULONG Size; DPRINT("NtCreatePagingFile(FileName %wZ, InitialSize %I64d)\n", - FileName, InitialSize->QuadPart); - + FileName, InitialSize->QuadPart); + if (MiPagingFileCount >= MAX_PAGING_FILES) - { - return(STATUS_TOO_MANY_PAGING_FILES); - } - + { + return(STATUS_TOO_MANY_PAGING_FILES); + } + InitializeObjectAttributes(&ObjectAttributes, - FileName, - 0, - NULL, - NULL); - + FileName, + 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); + FILE_ALL_ACCESS, + &ObjectAttributes, + &IoStatus, + NULL, + 0, + 0, + FILE_OPEN_IF, + FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0, + CreateFileTypeNone, + NULL, + SL_OPEN_PAGING_FILE); if (!NT_SUCCESS(Status)) - { - return(Status); - } - + { + return(Status); + } + Status = NtQueryVolumeInformationFile(FileHandle, &IoStatus, - &FsSizeInformation, - sizeof(FILE_FS_SIZE_INFORMATION), - FileFsSizeInformation); + &FsSizeInformation, + sizeof(FILE_FS_SIZE_INFORMATION), + FileFsSizeInformation); if (!NT_SUCCESS(Status)) - { - NtClose(FileHandle); - return Status; - } - + { + NtClose(FileHandle); + return Status; + } + BytesPerAllocationUnit = FsSizeInformation.SectorsPerAllocationUnit * FsSizeInformation.BytesPerSector; if (BytesPerAllocationUnit % PAGE_SIZE) - { - NtClose(FileHandle); - return STATUS_UNSUCCESSFUL; - } + { + NtClose(FileHandle); + return STATUS_UNSUCCESSFUL; + } Status = NtSetInformationFile(FileHandle, - &IoStatus, - InitialSize, - sizeof(LARGE_INTEGER), - FileAllocationInformation); + &IoStatus, + InitialSize, + sizeof(LARGE_INTEGER), + FileAllocationInformation); if (!NT_SUCCESS(Status)) - { - NtClose(FileHandle); - return(Status); - } + { + NtClose(FileHandle); + return(Status); + } Status = ObReferenceObjectByHandle(FileHandle, - FILE_ALL_ACCESS, - IoFileObjectType, - UserMode, - (PVOID*)&FileObject, - NULL); + FILE_ALL_ACCESS, + IoFileObjectType, + UserMode, + (PVOID*)&FileObject, + NULL); if (!NT_SUCCESS(Status)) - { - NtClose(FileHandle); - return(Status); - } + { + NtClose(FileHandle); + return(Status); + } CurrentRetDescList = RetDescList = MmAllocRetrievelDescriptorList(PAIRS_PER_RUN); if (CurrentRetDescList == NULL) - { - ObDereferenceObject(FileObject); - NtClose(FileHandle); - return(STATUS_NO_MEMORY); - } + { + ObDereferenceObject(FileObject); + NtClose(FileHandle); + return(STATUS_NO_MEMORY); + } #if defined(__GNUC__) Vcn.QuadPart = 0LL; #else + Vcn.QuadPart = 0; #endif + ExtentCount = 0; MaxVcn = (ULONG)((InitialSize->QuadPart + BytesPerAllocationUnit - 1) / BytesPerAllocationUnit); while(1) - { - Status = NtFsControlFile(FileHandle, - 0, - NULL, - NULL, - &IoStatus, - FSCTL_GET_RETRIEVAL_POINTERS, - &Vcn, - sizeof(LARGE_INTEGER), - &CurrentRetDescList->RetrievalPointers, - sizeof(GET_RETRIEVAL_DESCRIPTOR) + PAIRS_PER_RUN * sizeof(MAPPING_PAIR)); - if (!NT_SUCCESS(Status)) + { + Status = NtFsControlFile(FileHandle, + 0, + NULL, + NULL, + &IoStatus, + FSCTL_GET_RETRIEVAL_POINTERS, + &Vcn, + sizeof(LARGE_INTEGER), + &CurrentRetDescList->RetrievalPointers, + sizeof(GET_RETRIEVAL_DESCRIPTOR) + PAIRS_PER_RUN * sizeof(MAPPING_PAIR)); + if (!NT_SUCCESS(Status)) + { + while (RetDescList) { - while (RetDescList) - { - CurrentRetDescList = RetDescList; - RetDescList = RetDescList->Next; - ExFreePool(CurrentRetDescList); - } - ObDereferenceObject(FileObject); - NtClose(FileHandle); - return(Status); + CurrentRetDescList = RetDescList; + RetDescList = RetDescList->Next; + ExFreePool(CurrentRetDescList); } - ExtentCount += CurrentRetDescList->RetrievalPointers.NumberOfPairs; - if ((ULONG)CurrentRetDescList->RetrievalPointers.Pair[CurrentRetDescList->RetrievalPointers.NumberOfPairs-1].Vcn < MaxVcn) + ObDereferenceObject(FileObject); + NtClose(FileHandle); + return(Status); + } + ExtentCount += CurrentRetDescList->RetrievalPointers.NumberOfPairs; + if ((ULONG)CurrentRetDescList->RetrievalPointers.Pair[CurrentRetDescList->RetrievalPointers.NumberOfPairs-1].Vcn < MaxVcn) + { + CurrentRetDescList->Next = MmAllocRetrievelDescriptorList(PAIRS_PER_RUN); + if (CurrentRetDescList->Next == NULL) { - CurrentRetDescList->Next = MmAllocRetrievelDescriptorList(PAIRS_PER_RUN); - if (CurrentRetDescList->Next == NULL) - { - while (RetDescList) - { - CurrentRetDescList = RetDescList; - RetDescList = RetDescList->Next; - ExFreePool(CurrentRetDescList); - } - ObDereferenceObject(FileObject); - NtClose(FileHandle); - return(STATUS_NO_MEMORY); - } - Vcn.QuadPart = CurrentRetDescList->RetrievalPointers.Pair[CurrentRetDescList->RetrievalPointers.NumberOfPairs-1].Vcn; - CurrentRetDescList = CurrentRetDescList->Next; + while (RetDescList) + { + CurrentRetDescList = RetDescList; + RetDescList = RetDescList->Next; + ExFreePool(CurrentRetDescList); + } + ObDereferenceObject(FileObject); + NtClose(FileHandle); + return(STATUS_NO_MEMORY); } - else - { - break; - } - } + Vcn.QuadPart = CurrentRetDescList->RetrievalPointers.Pair[CurrentRetDescList->RetrievalPointers.NumberOfPairs-1].Vcn; + CurrentRetDescList = CurrentRetDescList->Next; + } + else + { + break; + } + } PagingFile = ExAllocatePool(NonPagedPool, sizeof(*PagingFile)); if (PagingFile == NULL) - { - while (RetDescList) - { - CurrentRetDescList = RetDescList; - RetDescList = RetDescList->Next; - ExFreePool(CurrentRetDescList); - } - ObDereferenceObject(FileObject); - NtClose(FileHandle); - return(STATUS_NO_MEMORY); - } - + { + while (RetDescList) + { + CurrentRetDescList = RetDescList; + RetDescList = RetDescList->Next; + ExFreePool(CurrentRetDescList); + } + ObDereferenceObject(FileObject); + NtClose(FileHandle); + return(STATUS_NO_MEMORY); + } + RtlZeroMemory(PagingFile, sizeof(*PagingFile)); PagingFile->FileObject = FileObject; @@ -904,36 +920,36 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName, PagingFile->FreePages = (ULONG)(InitialSize->QuadPart / PAGE_SIZE); PagingFile->UsedPages = 0; KeInitializeSpinLock(&PagingFile->AllocMapLock); - + AllocMapSize = (PagingFile->FreePages / 32) + 1; - PagingFile->AllocMap = ExAllocatePool(NonPagedPool, - AllocMapSize * sizeof(ULONG)); + 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); - } + { + while (RetDescList) + { + CurrentRetDescList = RetDescList; + RetDescList = RetDescList->Next; + ExFreePool(CurrentRetDescList); + } + ExFreePool(PagingFile); + ObDereferenceObject(FileObject); + ZwClose(FileHandle); + return(STATUS_NO_MEMORY); + } DPRINT("ExtentCount: %d\n", ExtentCount); Size = sizeof(GET_RETRIEVAL_DESCRIPTOR) + ExtentCount * sizeof(MAPPING_PAIR); PagingFile->RetrievalPointers = ExAllocatePool(NonPagedPool, Size); if (PagingFile->RetrievalPointers == NULL) { - while (RetDescList) - { - CurrentRetDescList = RetDescList; - RetDescList = RetDescList->Next; - ExFreePool(CurrentRetDescList); - } + while (RetDescList) + { + CurrentRetDescList = RetDescList; + RetDescList = RetDescList->Next; + ExFreePool(CurrentRetDescList); + } ExFreePool(PagingFile->AllocMap); ExFreePool(PagingFile); ObDereferenceObject(FileObject); @@ -949,57 +965,57 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName, PagingFile->RetrievalPointers->StartVcn = RetDescList->RetrievalPointers.StartVcn; CurrentRetDescList = RetDescList; while (CurrentRetDescList) - { - memcpy(&PagingFile->RetrievalPointers->Pair[Count], - CurrentRetDescList->RetrievalPointers.Pair, - CurrentRetDescList->RetrievalPointers.NumberOfPairs * sizeof(MAPPING_PAIR)); - Count += CurrentRetDescList->RetrievalPointers.NumberOfPairs; - RetDescList = CurrentRetDescList; - CurrentRetDescList = CurrentRetDescList->Next; - ExFreePool(RetDescList); - } + { + memcpy(&PagingFile->RetrievalPointers->Pair[Count], + CurrentRetDescList->RetrievalPointers.Pair, + CurrentRetDescList->RetrievalPointers.NumberOfPairs * sizeof(MAPPING_PAIR)); + Count += CurrentRetDescList->RetrievalPointers.NumberOfPairs; + RetDescList = CurrentRetDescList; + CurrentRetDescList = CurrentRetDescList->Next; + ExFreePool(RetDescList); + } - if (PagingFile->RetrievalPointers->NumberOfPairs != ExtentCount || - (ULONG)PagingFile->RetrievalPointers->Pair[ExtentCount - 1].Vcn != MaxVcn) - { - ExFreePool(PagingFile->RetrievalPointers); - ExFreePool(PagingFile->AllocMap); - ExFreePool(PagingFile); - ObDereferenceObject(FileObject); - NtClose(FileHandle); - return(STATUS_UNSUCCESSFUL); - } + if (PagingFile->RetrievalPointers->NumberOfPairs != ExtentCount || + (ULONG)PagingFile->RetrievalPointers->Pair[ExtentCount - 1].Vcn != MaxVcn) + { + ExFreePool(PagingFile->RetrievalPointers); + ExFreePool(PagingFile->AllocMap); + ExFreePool(PagingFile); + ObDereferenceObject(FileObject); + NtClose(FileHandle); + return(STATUS_UNSUCCESSFUL); + } - /* + /* * Change the entries from lcn's to volume offset's. */ PagingFile->RetrievalPointers->StartVcn *= BytesPerAllocationUnit; for (i = 0; i < ExtentCount; i++) - { - PagingFile->RetrievalPointers->Pair[i].Lcn *= BytesPerAllocationUnit; - PagingFile->RetrievalPointers->Pair[i].Vcn *= BytesPerAllocationUnit; - } + { + PagingFile->RetrievalPointers->Pair[i].Lcn *= BytesPerAllocationUnit; + PagingFile->RetrievalPointers->Pair[i].Vcn *= BytesPerAllocationUnit; + } KeAcquireSpinLock(&PagingFileListLock, &oldIrql); for (i = 0; i < MAX_PAGING_FILES; i++) - { - if (PagingFileList[i] == NULL) - { - PagingFileList[i] = PagingFile; - break; - } - } + { + if (PagingFileList[i] == NULL) + { + PagingFileList[i] = PagingFile; + break; + } + } MiFreeSwapPages = MiFreeSwapPages + PagingFile->FreePages; MiPagingFileCount++; KeReleaseSpinLock(&PagingFileListLock, oldIrql); - + /* Check whether this pagefile can be a crash dump target. */ if (MmCoreDumpType != MM_CORE_DUMP_TYPE_NONE && - PagingFile->CurrentSize.QuadPart >= MmCoreDumpSize && - MmCoreDumpPageFile == 0xFFFFFFFF) - { - MmInitializeCrashDump(FileHandle, i); - } + PagingFile->CurrentSize.QuadPart >= MmCoreDumpSize && + MmCoreDumpPageFile == 0xFFFFFFFF) + { + MmInitializeCrashDump(FileHandle, i); + } NtClose(FileHandle); MmSwapSpaceMessage = FALSE; diff --git a/reactos/ntoskrnl/mm/pageop.c b/reactos/ntoskrnl/mm/pageop.c index 5e57dea8445..b57897d00e3 100644 --- a/reactos/ntoskrnl/mm/pageop.c +++ b/reactos/ntoskrnl/mm/pageop.c @@ -1,4 +1,4 @@ -/* $Id: pageop.c,v 1.19 2004/03/05 11:31:59 hbirr Exp $ +/* $Id: pageop.c,v 1.20 2004/04/10 22:35:25 gdalsnes Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -32,227 +32,227 @@ static NPAGED_LOOKASIDE_LIST MmPageOpLookasideList; VOID MmReleasePageOp(PMM_PAGEOP PageOp) - /* - * FUNCTION: Release a reference to a page operation descriptor - */ +/* + * FUNCTION: Release a reference to a page operation descriptor + */ { - KIRQL oldIrql; - PMM_PAGEOP PrevPageOp; + KIRQL oldIrql; + PMM_PAGEOP PrevPageOp; - KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql); - PageOp->ReferenceCount--; - if (PageOp->ReferenceCount > 0) - { + KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql); + PageOp->ReferenceCount--; + if (PageOp->ReferenceCount > 0) + { KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); return; - } - InterlockedDecrement((LONG *)&PageOp->MArea->PageOpCount); - PrevPageOp = MmPageOpHashTable[PageOp->Hash]; - if (PrevPageOp == PageOp) - { + } + InterlockedDecrement((LONG *)&PageOp->MArea->PageOpCount); + PrevPageOp = MmPageOpHashTable[PageOp->Hash]; + if (PrevPageOp == PageOp) + { MmPageOpHashTable[PageOp->Hash] = PageOp->Next; KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); ExFreeToNPagedLookasideList(&MmPageOpLookasideList, PageOp); return; - } - while (PrevPageOp->Next != NULL) - { + } + while (PrevPageOp->Next != NULL) + { if (PrevPageOp->Next == PageOp) - { - PrevPageOp->Next = PageOp->Next; - KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); - ExFreeToNPagedLookasideList(&MmPageOpLookasideList, PageOp); - return; - } + { + PrevPageOp->Next = PageOp->Next; + KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); + ExFreeToNPagedLookasideList(&MmPageOpLookasideList, PageOp); + return; + } PrevPageOp = PrevPageOp->Next; - } - KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); - KEBUGCHECK(0); + } + KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); + KEBUGCHECK(0); } PMM_PAGEOP MmCheckForPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address, - PMM_SECTION_SEGMENT Segment, ULONG Offset) + PMM_SECTION_SEGMENT Segment, ULONG Offset) { - ULONG Hash; - KIRQL oldIrql; - PMM_PAGEOP PageOp; - - /* - * Calcuate the hash value for pageop structure - */ - if (MArea->Type == MEMORY_AREA_SECTION_VIEW) - { + ULONG Hash; + KIRQL oldIrql; + PMM_PAGEOP PageOp; + + /* + * Calcuate the hash value for pageop structure + */ + if (MArea->Type == MEMORY_AREA_SECTION_VIEW) + { Hash = (((ULONG)Segment) | (((ULONG)Offset) / PAGE_SIZE)); - } - else - { + } + else + { Hash = (((ULONG)Pid) | (((ULONG)Address) / PAGE_SIZE)); - } - Hash = Hash % PAGEOP_HASH_TABLE_SIZE; + } + Hash = Hash % PAGEOP_HASH_TABLE_SIZE; - KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql); + KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql); - /* - * Check for an existing pageop structure - */ - PageOp = MmPageOpHashTable[Hash]; - while (PageOp != NULL) - { + /* + * Check for an existing pageop structure + */ + PageOp = MmPageOpHashTable[Hash]; + while (PageOp != NULL) + { if (MArea->Type == MEMORY_AREA_SECTION_VIEW) - { - if (PageOp->Segment == Segment && - PageOp->Offset == Offset) - { - break; - } - } + { + if (PageOp->Segment == Segment && + PageOp->Offset == Offset) + { + break; + } + } else - { - if (PageOp->Pid == Pid && - PageOp->Address == Address) - { - break; - } - } + { + if (PageOp->Pid == Pid && + PageOp->Address == Address) + { + break; + } + } PageOp = PageOp->Next; - } - - /* - * If we found an existing pageop then increment the reference count - * and return it. - */ - if (PageOp != NULL) - { + } + + /* + * If we found an existing pageop then increment the reference count + * and return it. + */ + if (PageOp != NULL) + { PageOp->ReferenceCount++; KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); return(PageOp); - } - KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); - return(NULL); + } + KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); + return(NULL); } PMM_PAGEOP MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address, - PMM_SECTION_SEGMENT Segment, ULONG Offset, ULONG OpType, BOOL First) - /* - * FUNCTION: Get a page operation descriptor corresponding to - * the memory area and either the segment, offset pair or the - * pid, address pair. - */ + PMM_SECTION_SEGMENT Segment, ULONG Offset, ULONG OpType, BOOL First) +/* + * FUNCTION: Get a page operation descriptor corresponding to + * the memory area and either the segment, offset pair or the + * pid, address pair. + */ { - ULONG Hash; - KIRQL oldIrql; - PMM_PAGEOP PageOp; + ULONG Hash; + KIRQL oldIrql; + PMM_PAGEOP PageOp; - /* - * Calcuate the hash value for pageop structure - */ - if (MArea->Type == MEMORY_AREA_SECTION_VIEW) - { + /* + * Calcuate the hash value for pageop structure + */ + if (MArea->Type == MEMORY_AREA_SECTION_VIEW) + { Hash = (((ULONG)Segment) | (((ULONG)Offset) / PAGE_SIZE)); - } - else - { + } + else + { Hash = (((ULONG)Pid) | (((ULONG)Address) / PAGE_SIZE)); - } - Hash = Hash % PAGEOP_HASH_TABLE_SIZE; + } + Hash = Hash % PAGEOP_HASH_TABLE_SIZE; - KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql); + KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql); - /* - * Check for an existing pageop structure - */ - PageOp = MmPageOpHashTable[Hash]; - while (PageOp != NULL) - { + /* + * Check for an existing pageop structure + */ + PageOp = MmPageOpHashTable[Hash]; + while (PageOp != NULL) + { if (MArea->Type == MEMORY_AREA_SECTION_VIEW) - { - if (PageOp->Segment == Segment && - PageOp->Offset == Offset) - { - break; - } - } + { + if (PageOp->Segment == Segment && + PageOp->Offset == Offset) + { + break; + } + } else - { - if (PageOp->Pid == Pid && - PageOp->Address == Address) - { - break; - } - } + { + if (PageOp->Pid == Pid && + PageOp->Address == Address) + { + break; + } + } PageOp = PageOp->Next; - } - - /* - * If we found an existing pageop then increment the reference count - * and return it. - */ - if (PageOp != NULL) - { + } + + /* + * If we found an existing pageop then increment the reference count + * and return it. + */ + if (PageOp != NULL) + { if (First) - { - PageOp = NULL; - } + { + PageOp = NULL; + } else - { - PageOp->ReferenceCount++; - } + { + PageOp->ReferenceCount++; + } KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); return(PageOp); - } + } - /* - * Otherwise add a new pageop. - */ - PageOp = ExAllocateFromNPagedLookasideList(&MmPageOpLookasideList); - if (PageOp == NULL) - { + /* + * Otherwise add a new pageop. + */ + PageOp = ExAllocateFromNPagedLookasideList(&MmPageOpLookasideList); + if (PageOp == NULL) + { KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); KEBUGCHECK(0); return(NULL); - } - - if (MArea->Type != MEMORY_AREA_SECTION_VIEW) - { + } + + if (MArea->Type != MEMORY_AREA_SECTION_VIEW) + { PageOp->Pid = Pid; PageOp->Address = Address; - } - else - { + } + else + { PageOp->Segment = Segment; PageOp->Offset = Offset; - } - PageOp->ReferenceCount = 1; - PageOp->Next = MmPageOpHashTable[Hash]; - PageOp->Hash = Hash; - PageOp->Thread = PsGetCurrentThread(); - PageOp->Abandoned = FALSE; - PageOp->Status = STATUS_PENDING; - PageOp->OpType = OpType; - PageOp->MArea = MArea; - KeInitializeEvent(&PageOp->CompletionEvent, NotificationEvent, FALSE); - MmPageOpHashTable[Hash] = PageOp; - InterlockedIncrement((LONG *)&MArea->PageOpCount); + } + PageOp->ReferenceCount = 1; + PageOp->Next = MmPageOpHashTable[Hash]; + PageOp->Hash = Hash; + PageOp->Thread = PsGetCurrentThread(); + PageOp->Abandoned = FALSE; + PageOp->Status = STATUS_PENDING; + PageOp->OpType = OpType; + PageOp->MArea = MArea; + KeInitializeEvent(&PageOp->CompletionEvent, NotificationEvent, FALSE); + MmPageOpHashTable[Hash] = PageOp; + InterlockedIncrement((LONG *)&MArea->PageOpCount); - KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); - return(PageOp); + KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); + return(PageOp); } VOID INIT_FUNCTION MmInitializePageOp(VOID) { - memset(MmPageOpHashTable, 0, sizeof(MmPageOpHashTable)); - KeInitializeSpinLock(&MmPageOpHashTableLock); + memset(MmPageOpHashTable, 0, sizeof(MmPageOpHashTable)); + KeInitializeSpinLock(&MmPageOpHashTableLock); - ExInitializeNPagedLookasideList (&MmPageOpLookasideList, - NULL, - NULL, - 0, - sizeof(MM_PAGEOP), - TAG_MM_PAGEOP, - 50); + ExInitializeNPagedLookasideList (&MmPageOpLookasideList, + NULL, + NULL, + 0, + sizeof(MM_PAGEOP), + TAG_MM_PAGEOP, + 50); } diff --git a/reactos/ntoskrnl/mm/pager.c b/reactos/ntoskrnl/mm/pager.c index 7bb64e5e5fb..04c8dca557f 100644 --- a/reactos/ntoskrnl/mm/pager.c +++ b/reactos/ntoskrnl/mm/pager.c @@ -1,4 +1,4 @@ -/* $Id: pager.c,v 1.16 2003/11/16 15:20:39 hbirr Exp $ +/* $Id: pager.c,v 1.17 2004/04/10 22:35:25 gdalsnes Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -35,25 +35,25 @@ static ULONG PagerThreadWorkCount; BOOLEAN MiIsPagerThread(VOID) { - return(PsGetCurrentThreadId() == PagerThreadId.UniqueThread); + return(PsGetCurrentThreadId() == PagerThreadId.UniqueThread); } VOID MiStartPagerThread(VOID) { - ULONG WasWorking; + ULONG WasWorking; - WasWorking = InterlockedIncrement(&PagerThreadWorkCount); - if (WasWorking == 1) - { + WasWorking = InterlockedIncrement(&PagerThreadWorkCount); + if (WasWorking == 1) + { KeSetEvent(&PagerThreadEvent, IO_NO_INCREMENT, FALSE); - } + } } VOID MiStopPagerThread(VOID) { - (VOID)InterlockedDecrement(&PagerThreadWorkCount); + (VOID)InterlockedDecrement(&PagerThreadWorkCount); } static NTSTATUS STDCALL @@ -62,53 +62,54 @@ MmPagerThreadMain(PVOID Ignored) NTSTATUS Status; for(;;) - { - /* Wake for a low memory situation or a terminate request. */ - Status = KeWaitForSingleObject(&PagerThreadEvent, - 0, - KernelMode, - FALSE, - NULL); - if (!NT_SUCCESS(Status)) - { - DbgPrint("PagerThread: Wait failed\n"); - KEBUGCHECK(0); - } - if (PagerThreadShouldTerminate) - { - DbgPrint("PagerThread: Terminating\n"); - return(STATUS_SUCCESS); - } - do - { - /* Try and make some memory available to the system. */ - MmRebalanceMemoryConsumers(); - } while(PagerThreadWorkCount > 0); - } + { + /* Wake for a low memory situation or a terminate request. */ + Status = KeWaitForSingleObject(&PagerThreadEvent, + 0, + KernelMode, + FALSE, + NULL); + if (!NT_SUCCESS(Status)) + { + DbgPrint("PagerThread: Wait failed\n"); + KEBUGCHECK(0); + } + if (PagerThreadShouldTerminate) + { + DbgPrint("PagerThread: Terminating\n"); + return(STATUS_SUCCESS); + } + do + { + /* Try and make some memory available to the system. */ + MmRebalanceMemoryConsumers(); + } + while(PagerThreadWorkCount > 0); + } } NTSTATUS MmInitPagerThread(VOID) { NTSTATUS Status; - + PagerThreadShouldTerminate = FALSE; PagerThreadWorkCount = 0; KeInitializeEvent(&PagerThreadEvent, - SynchronizationEvent, - FALSE); - + SynchronizationEvent, + FALSE); + Status = PsCreateSystemThread(&PagerThreadHandle, - THREAD_ALL_ACCESS, - NULL, - NULL, - &PagerThreadId, - (PKSTART_ROUTINE) MmPagerThreadMain, - NULL); + THREAD_ALL_ACCESS, + NULL, + NULL, + &PagerThreadId, + (PKSTART_ROUTINE) MmPagerThreadMain, + NULL); if (!NT_SUCCESS(Status)) - { - return(Status); - } - + { + return(Status); + } + return(STATUS_SUCCESS); } #endif diff --git a/reactos/ntoskrnl/mm/pagfault.c b/reactos/ntoskrnl/mm/pagfault.c index 1a247d29791..9b2adeb18f7 100644 --- a/reactos/ntoskrnl/mm/pagfault.c +++ b/reactos/ntoskrnl/mm/pagfault.c @@ -1,4 +1,4 @@ -/* $Id: pagfault.c,v 1.5 2003/07/10 21:05:03 royce Exp $ */ +/* $Id: pagfault.c,v 1.6 2004/04/10 22:35:25 gdalsnes Exp $ */ #include #include @@ -8,14 +8,14 @@ BOOLEAN STDCALL MmIsRecursiveIoFault ( - VOID - ) + VOID +) { - PETHREAD Thread = PsGetCurrentThread (); + PETHREAD Thread = PsGetCurrentThread (); - return ( Thread->DisablePageFaultClustering - | Thread->ForwardClusterOnly - ); + return ( Thread->DisablePageFaultClustering + | Thread->ForwardClusterOnly + ); } diff --git a/reactos/ntoskrnl/mm/pool.c b/reactos/ntoskrnl/mm/pool.c index 05321286819..c1c682baea1 100644 --- a/reactos/ntoskrnl/mm/pool.c +++ b/reactos/ntoskrnl/mm/pool.c @@ -1,4 +1,4 @@ -/* $Id: pool.c,v 1.27 2004/02/26 18:54:52 navaraf Exp $ +/* $Id: pool.c,v 1.28 2004/04/10 22:35:25 gdalsnes Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -25,40 +25,40 @@ STATIC PVOID STDCALL EiAllocatePool(POOL_TYPE PoolType, - ULONG NumberOfBytes, - ULONG Tag, - PVOID Caller) + ULONG NumberOfBytes, + ULONG Tag, + PVOID Caller) { PVOID Block; - - + + switch(PoolType) - { + { case NonPagedPool: case NonPagedPoolMustSucceed: case NonPagedPoolCacheAligned: case NonPagedPoolCacheAlignedMustS: - Block = - ExAllocateNonPagedPoolWithTag(PoolType, - NumberOfBytes, - Tag, - Caller); - break; - + Block = + ExAllocateNonPagedPoolWithTag(PoolType, + NumberOfBytes, + Tag, + Caller); + break; + case PagedPool: case PagedPoolCacheAligned: - Block = ExAllocatePagedPoolWithTag(PoolType,NumberOfBytes,Tag); - break; - + Block = ExAllocatePagedPoolWithTag(PoolType,NumberOfBytes,Tag); + break; + default: - return(NULL); - }; - - if ((PoolType==NonPagedPoolMustSucceed || - PoolType==NonPagedPoolCacheAlignedMustS) && Block==NULL) - { - KEBUGCHECK(MUST_SUCCEED_POOL_EMPTY); - } + return(NULL); + }; + + if ((PoolType==NonPagedPoolMustSucceed || + PoolType==NonPagedPoolCacheAlignedMustS) && Block==NULL) + { + KEBUGCHECK(MUST_SUCCEED_POOL_EMPTY); + } return(Block); } @@ -91,18 +91,21 @@ ExAllocatePool (POOL_TYPE PoolType, ULONG NumberOfBytes) { PVOID Block; #if defined(__GNUC__) + Block = EiAllocatePool(PoolType, - NumberOfBytes, - TAG_NONE, - (PVOID)__builtin_return_address(0)); + NumberOfBytes, + TAG_NONE, + (PVOID)__builtin_return_address(0)); #elif defined(_MSC_VER) + Block = EiAllocatePool(PoolType, - NumberOfBytes, - TAG_NONE, - &ExAllocatePool); + NumberOfBytes, + TAG_NONE, + &ExAllocatePool); #else #error Unknown compiler #endif + return(Block); } @@ -115,18 +118,21 @@ ExAllocatePoolWithTag (ULONG PoolType, ULONG NumberOfBytes, ULONG Tag) { PVOID Block; #if defined(__GNUC__) + Block = EiAllocatePool(PoolType, - NumberOfBytes, - Tag, - (PVOID)__builtin_return_address(0)); + NumberOfBytes, + Tag, + (PVOID)__builtin_return_address(0)); #elif defined(_MSC_VER) + Block = EiAllocatePool(PoolType, - NumberOfBytes, - Tag, - &ExAllocatePoolWithTag); + NumberOfBytes, + Tag, + &ExAllocatePoolWithTag); #else #error Unknown compiler #endif + return(Block); } @@ -137,7 +143,7 @@ ExAllocatePoolWithTag (ULONG PoolType, ULONG NumberOfBytes, ULONG Tag) PVOID STDCALL ExAllocatePoolWithQuota (POOL_TYPE PoolType, ULONG NumberOfBytes) { - return(ExAllocatePoolWithQuotaTag(PoolType, NumberOfBytes, TAG_NONE)); + return(ExAllocatePoolWithQuotaTag(PoolType, NumberOfBytes, TAG_NONE)); } @@ -145,20 +151,21 @@ ExAllocatePoolWithQuota (POOL_TYPE PoolType, ULONG NumberOfBytes) * @unimplemented */ PVOID STDCALL -ExAllocatePoolWithQuotaTag (IN POOL_TYPE PoolType, - IN ULONG NumberOfBytes, - IN ULONG Tag) +ExAllocatePoolWithQuotaTag (IN POOL_TYPE PoolType, + IN ULONG NumberOfBytes, + IN ULONG Tag) { #if 0 - PVOID Block; - Block = EiAllocatePool(PoolType, - NumberOfBytes, - Tag, - (PVOID)__builtin_return_address(0)); - return(Block); + PVOID Block; + Block = EiAllocatePool(PoolType, + NumberOfBytes, + Tag, + (PVOID)__builtin_return_address(0)); + return(Block); #else - UNIMPLEMENTED; - return(NULL); + + UNIMPLEMENTED; + return(NULL); #endif } @@ -168,14 +175,14 @@ ExAllocatePoolWithQuotaTag (IN POOL_TYPE PoolType, VOID STDCALL ExFreePool(IN PVOID Block) { - if (Block >= MmPagedPoolBase && (char*)Block < ((char*)MmPagedPoolBase + MmPagedPoolSize)) - { + if (Block >= MmPagedPoolBase && (char*)Block < ((char*)MmPagedPoolBase + MmPagedPoolSize)) + { ExFreePagedPool(Block); - } - else - { + } + else + { ExFreeNonPagedPool(Block); - } + } } /* @@ -184,8 +191,8 @@ ExFreePool(IN PVOID Block) VOID STDCALL ExFreePoolWithTag(IN PVOID Block, IN ULONG Tag) { - /* FIXME: Validate the tag */ - ExFreePool(Block); + /* FIXME: Validate the tag */ + ExFreePool(Block); } /* EOF */ diff --git a/reactos/ntoskrnl/mm/ppool.c b/reactos/ntoskrnl/mm/ppool.c index f37237c66fe..cdcd2b10320 100644 --- a/reactos/ntoskrnl/mm/ppool.c +++ b/reactos/ntoskrnl/mm/ppool.c @@ -1,4 +1,4 @@ -/* $Id: ppool.c,v 1.27 2004/03/30 09:28:44 gvg Exp $ +/* $Id: ppool.c,v 1.28 2004/04/10 22:35:25 gdalsnes Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -34,18 +34,21 @@ typedef struct _MM_PPOOL_FREE_BLOCK_HEADER { - ULONG Size; - struct _MM_PPOOL_FREE_BLOCK_HEADER* NextFree; -} MM_PPOOL_FREE_BLOCK_HEADER, *PMM_PPOOL_FREE_BLOCK_HEADER; + ULONG Size; + struct _MM_PPOOL_FREE_BLOCK_HEADER* NextFree; +} +MM_PPOOL_FREE_BLOCK_HEADER, *PMM_PPOOL_FREE_BLOCK_HEADER; typedef struct _MM_PPOOL_USED_BLOCK_HEADER { - ULONG Size; + ULONG Size; #if MM_PPOOL_REDZONE_BYTES - ULONG UserSize; // how many bytes the user actually asked for... - struct _MM_PPOOL_USED_BLOCK_HEADER* NextUsed; + + ULONG UserSize; // how many bytes the user actually asked for... + struct _MM_PPOOL_USED_BLOCK_HEADER* NextUsed; #endif//MM_PPOOL_REDZONE_BYTES -} MM_PPOOL_USED_BLOCK_HEADER, *PMM_PPOOL_USED_BLOCK_HEADER; +} +MM_PPOOL_USED_BLOCK_HEADER, *PMM_PPOOL_USED_BLOCK_HEADER; PVOID MmPagedPoolBase; ULONG MmPagedPoolSize; @@ -63,49 +66,50 @@ inline static void* block_to_address ( PVOID blk ) * address (internal) */ { - return ( (void *) ((char*)blk + sizeof(MM_PPOOL_USED_BLOCK_HEADER) + MM_PPOOL_REDZONE_BYTES) ); + return ( (void *) ((char*)blk + sizeof(MM_PPOOL_USED_BLOCK_HEADER) + MM_PPOOL_REDZONE_BYTES) ); } inline static PMM_PPOOL_USED_BLOCK_HEADER address_to_block(PVOID addr) { - return (PMM_PPOOL_USED_BLOCK_HEADER) - ( ((char*)addr) - sizeof(MM_PPOOL_USED_BLOCK_HEADER) - MM_PPOOL_REDZONE_BYTES ); + return (PMM_PPOOL_USED_BLOCK_HEADER) + ( ((char*)addr) - sizeof(MM_PPOOL_USED_BLOCK_HEADER) - MM_PPOOL_REDZONE_BYTES ); } VOID INIT_FUNCTION MmInitializePagedPool(VOID) { - MmPagedPoolFirstFreeBlock = (PMM_PPOOL_FREE_BLOCK_HEADER)MmPagedPoolBase; - /* - * We are still at a high IRQL level at this point so explicitly commit - * the first page of the paged pool before writing the first block header. - */ - MmCommitPagedPoolAddress((PVOID)MmPagedPoolFirstFreeBlock, FALSE); - MmPagedPoolFirstFreeBlock->Size = MmPagedPoolSize; - MmPagedPoolFirstFreeBlock->NextFree = NULL; + MmPagedPoolFirstFreeBlock = (PMM_PPOOL_FREE_BLOCK_HEADER)MmPagedPoolBase; + /* + * We are still at a high IRQL level at this point so explicitly commit + * the first page of the paged pool before writing the first block header. + */ + MmCommitPagedPoolAddress((PVOID)MmPagedPoolFirstFreeBlock, FALSE); + MmPagedPoolFirstFreeBlock->Size = MmPagedPoolSize; + MmPagedPoolFirstFreeBlock->NextFree = NULL; #if MM_PPOOL_REDZONE_BYTES - MmPagedPoolFirstUsedBlock = NULL; + + MmPagedPoolFirstUsedBlock = NULL; #endif//MM_PPOOL_REDZONE_BYTES - ExInitializeFastMutex(&MmPagedPoolLock); + ExInitializeFastMutex(&MmPagedPoolLock); } #ifdef ENABLE_VALIDATE_POOL static void VerifyPagedPool ( int line ) { - PMM_PPOOL_FREE_BLOCK_HEADER p = MmPagedPoolFirstFreeBlock; - int count = 0; - DPRINT ( "VerifyPagedPool(%i):\n", line ); - while ( p ) - { - DPRINT ( " 0x%x: %lu bytes (next 0x%x)\n", p, p->Size, p->NextFree ); - ASSERT_PTR(p); - ASSERT_SIZE(p->Size); - count++; - p = p->NextFree; - } - DPRINT ( "VerifyPagedPool(%i): (%lu blocks)\n", line, count ); + PMM_PPOOL_FREE_BLOCK_HEADER p = MmPagedPoolFirstFreeBlock; + int count = 0; + DPRINT ( "VerifyPagedPool(%i):\n", line ); + while ( p ) + { + DPRINT ( " 0x%x: %lu bytes (next 0x%x)\n", p, p->Size, p->NextFree ); + ASSERT_PTR(p); + ASSERT_SIZE(p->Size); + count++; + p = p->NextFree; + } + DPRINT ( "VerifyPagedPool(%i): (%lu blocks)\n", line, count ); } #define VerifyPagedPool() VerifyPagedPool(__LINE__) #else @@ -116,38 +120,38 @@ VOID STDCALL MmDbgPagedPoolRedZoneCheck ( const char* file, int line ) { #if MM_PPOOL_REDZONE_BYTES - PMM_PPOOL_USED_BLOCK_HEADER pUsed = MmPagedPoolFirstUsedBlock; - int i; - BOOL bLow = TRUE; - BOOL bHigh = TRUE; + PMM_PPOOL_USED_BLOCK_HEADER pUsed = MmPagedPoolFirstUsedBlock; + int i; + BOOL bLow = TRUE; + BOOL bHigh = TRUE; - while ( pUsed ) - { - PUCHAR Addr = (PUCHAR)block_to_address(pUsed); - for ( i = 0; i < MM_PPOOL_REDZONE_BYTES; i++ ) - { - bLow = bLow && ( *(Addr-i-1) == MM_PPOOL_REDZONE_VALUE ); - bHigh = bHigh && ( *(Addr+pUsed->UserSize+i) == MM_PPOOL_REDZONE_VALUE ); - } - if ( !bLow || !bHigh ) - { - const char* violation = "High and Low-side"; - if ( bHigh ) // high is okay, so it was just low failed - violation = "Low-side"; - else if ( bLow ) // low side is okay, so it was just high failed - violation = "High-side"; - DbgPrint("%s(%i): %s redzone violation detected for paged pool address 0x%x\n", - file, line, violation, Addr ); - KEBUGCHECK(0); - } - pUsed = pUsed->NextUsed; - } + while ( pUsed ) + { + PUCHAR Addr = (PUCHAR)block_to_address(pUsed); + for ( i = 0; i < MM_PPOOL_REDZONE_BYTES; i++ ) + { + bLow = bLow && ( *(Addr-i-1) == MM_PPOOL_REDZONE_VALUE ); + bHigh = bHigh && ( *(Addr+pUsed->UserSize+i) == MM_PPOOL_REDZONE_VALUE ); + } + if ( !bLow || !bHigh ) + { + const char* violation = "High and Low-side"; + if ( bHigh ) // high is okay, so it was just low failed + violation = "Low-side"; + else if ( bLow ) // low side is okay, so it was just high failed + violation = "High-side"; + DbgPrint("%s(%i): %s redzone violation detected for paged pool address 0x%x\n", + file, line, violation, Addr ); + KEBUGCHECK(0); + } + pUsed = pUsed->NextUsed; + } #endif//MM_PPOOL_REDZONE_BYTES } /********************************************************************** - * NAME INTERNAL - * ExAllocatePagedPoolWithTag@12 + * NAME INTERNAL + * ExAllocatePagedPoolWithTag@12 * * DESCRIPTION * @@ -156,181 +160,182 @@ MmDbgPagedPoolRedZoneCheck ( const char* file, int line ) * RETURN VALUE */ PVOID STDCALL -ExAllocatePagedPoolWithTag (IN POOL_TYPE PoolType, - IN ULONG NumberOfBytes, - IN ULONG Tag) +ExAllocatePagedPoolWithTag (IN POOL_TYPE PoolType, + IN ULONG NumberOfBytes, + IN ULONG Tag) { - PMM_PPOOL_FREE_BLOCK_HEADER BestBlock; - PMM_PPOOL_FREE_BLOCK_HEADER CurrentBlock; - ULONG BlockSize; - PMM_PPOOL_USED_BLOCK_HEADER NewBlock; - PMM_PPOOL_FREE_BLOCK_HEADER NextBlock; - PMM_PPOOL_FREE_BLOCK_HEADER PreviousBlock; - PMM_PPOOL_FREE_BLOCK_HEADER BestPreviousBlock; - PVOID BlockAddress; - ULONG Alignment; + PMM_PPOOL_FREE_BLOCK_HEADER BestBlock; + PMM_PPOOL_FREE_BLOCK_HEADER CurrentBlock; + ULONG BlockSize; + PMM_PPOOL_USED_BLOCK_HEADER NewBlock; + PMM_PPOOL_FREE_BLOCK_HEADER NextBlock; + PMM_PPOOL_FREE_BLOCK_HEADER PreviousBlock; + PMM_PPOOL_FREE_BLOCK_HEADER BestPreviousBlock; + PVOID BlockAddress; + ULONG Alignment; - ExAcquireFastMutex(&MmPagedPoolLock); + ExAcquireFastMutex(&MmPagedPoolLock); - /* - * Don't bother allocating anything for a zero-byte block. - */ - if (NumberOfBytes == 0) - { + /* + * Don't bother allocating anything for a zero-byte block. + */ + if (NumberOfBytes == 0) + { MmDbgPagedPoolRedZoneCheck(__FILE__,__LINE__); ExReleaseFastMutex(&MmPagedPoolLock); return(NULL); - } + } - DPRINT ( "ExAllocatePagedPoolWithTag(%i,%lu,%lu)\n", PoolType, NumberOfBytes, Tag ); - VerifyPagedPool(); + DPRINT ( "ExAllocatePagedPoolWithTag(%i,%lu,%lu)\n", PoolType, NumberOfBytes, Tag ); + VerifyPagedPool(); - if (NumberOfBytes >= PAGE_SIZE) - { + if (NumberOfBytes >= PAGE_SIZE) + { Alignment = PAGE_SIZE; - } - else if (PoolType == PagedPoolCacheAligned) - { + } + else if (PoolType == PagedPoolCacheAligned) + { Alignment = MM_CACHE_LINE_SIZE; - } - else - { + } + else + { Alignment = MM_POOL_ALIGNMENT; - } + } - /* - * Calculate the total number of bytes we will need. - */ - BlockSize = NumberOfBytes + sizeof(MM_PPOOL_USED_BLOCK_HEADER) + 2*MM_PPOOL_REDZONE_BYTES; - if (BlockSize < sizeof(MM_PPOOL_FREE_BLOCK_HEADER)) - { - /* At least we need the size of the free block header. */ - BlockSize = sizeof(MM_PPOOL_FREE_BLOCK_HEADER); - } + /* + * Calculate the total number of bytes we will need. + */ + BlockSize = NumberOfBytes + sizeof(MM_PPOOL_USED_BLOCK_HEADER) + 2*MM_PPOOL_REDZONE_BYTES; + if (BlockSize < sizeof(MM_PPOOL_FREE_BLOCK_HEADER)) + { + /* At least we need the size of the free block header. */ + BlockSize = sizeof(MM_PPOOL_FREE_BLOCK_HEADER); + } - /* - * Find the best-fitting block. - */ - PreviousBlock = NULL; - BestPreviousBlock = BestBlock = NULL; - CurrentBlock = MmPagedPoolFirstFreeBlock; - if ( Alignment > 0 ) - { + /* + * Find the best-fitting block. + */ + PreviousBlock = NULL; + BestPreviousBlock = BestBlock = NULL; + CurrentBlock = MmPagedPoolFirstFreeBlock; + if ( Alignment > 0 ) + { PVOID BestAlignedAddr = NULL; while ( CurrentBlock != NULL ) - { - PVOID Addr = block_to_address(CurrentBlock); - PVOID CurrentBlockEnd = (char*)CurrentBlock + CurrentBlock->Size; - /* calculate last size-aligned address available within this block */ - PVOID AlignedAddr = MM_ROUND_DOWN((char*)CurrentBlockEnd-NumberOfBytes-MM_PPOOL_REDZONE_BYTES, Alignment); - assert ( (char*)AlignedAddr+NumberOfBytes+MM_PPOOL_REDZONE_BYTES <= (char*)CurrentBlockEnd ); + { + PVOID Addr = block_to_address(CurrentBlock); + PVOID CurrentBlockEnd = (char*)CurrentBlock + CurrentBlock->Size; + /* calculate last size-aligned address available within this block */ + PVOID AlignedAddr = MM_ROUND_DOWN((char*)CurrentBlockEnd-NumberOfBytes-MM_PPOOL_REDZONE_BYTES, Alignment); + assert ( (char*)AlignedAddr+NumberOfBytes+MM_PPOOL_REDZONE_BYTES <= (char*)CurrentBlockEnd ); - /* special case, this address is already size-aligned, and the right size */ - if ( Addr == AlignedAddr ) - { - BestAlignedAddr = AlignedAddr; - BestPreviousBlock = PreviousBlock; - BestBlock = CurrentBlock; - break; - } - else if ( Addr < (PVOID)address_to_block(AlignedAddr) ) - { - /* - * there's enough room to allocate our size-aligned memory out - * of this block, see if it's a better choice than any previous - * finds - */ - if ( BestBlock == NULL || BestBlock->Size > CurrentBlock->Size ) - { - BestAlignedAddr = AlignedAddr; - BestPreviousBlock = PreviousBlock; - BestBlock = CurrentBlock; - } - } + /* special case, this address is already size-aligned, and the right size */ + if ( Addr == AlignedAddr ) + { + BestAlignedAddr = AlignedAddr; + BestPreviousBlock = PreviousBlock; + BestBlock = CurrentBlock; + break; + } + else if ( Addr < (PVOID)address_to_block(AlignedAddr) ) + { + /* + * there's enough room to allocate our size-aligned memory out + * of this block, see if it's a better choice than any previous + * finds + */ + if ( BestBlock == NULL || BestBlock->Size > CurrentBlock->Size ) + { + BestAlignedAddr = AlignedAddr; + BestPreviousBlock = PreviousBlock; + BestBlock = CurrentBlock; + } + } - PreviousBlock = CurrentBlock; - CurrentBlock = CurrentBlock->NextFree; - } + PreviousBlock = CurrentBlock; + CurrentBlock = CurrentBlock->NextFree; + } /* * we found a best block can/should we chop a few bytes off the beginning * into a separate memory block? */ if ( BestBlock != NULL ) - { - PVOID Addr = block_to_address(BestBlock); - if ( BestAlignedAddr != Addr ) - { - PMM_PPOOL_FREE_BLOCK_HEADER NewFreeBlock = - (PMM_PPOOL_FREE_BLOCK_HEADER)address_to_block(BestAlignedAddr); - assert ( BestAlignedAddr > Addr ); - NewFreeBlock->Size = (char*)Addr + BestBlock->Size - (char*)BestAlignedAddr; - ASSERT_SIZE(NewFreeBlock->Size); - BestBlock->Size = (size_t)NewFreeBlock - (size_t)Addr; - ASSERT_SIZE(BestBlock->Size); + { + PVOID Addr = block_to_address(BestBlock); + if ( BestAlignedAddr != Addr ) + { + PMM_PPOOL_FREE_BLOCK_HEADER NewFreeBlock = + (PMM_PPOOL_FREE_BLOCK_HEADER)address_to_block(BestAlignedAddr); + assert ( BestAlignedAddr > Addr ); + NewFreeBlock->Size = (char*)Addr + BestBlock->Size - (char*)BestAlignedAddr; + ASSERT_SIZE(NewFreeBlock->Size); + BestBlock->Size = (size_t)NewFreeBlock - (size_t)Addr; + ASSERT_SIZE(BestBlock->Size); - DPRINT ( "breaking off preceding bytes into their own block...\n" ); - DPRINT ( "NewFreeBlock 0x%x Size %lu (Old Block's new size %lu) NextFree 0x%x\n", - NewFreeBlock, NewFreeBlock->Size, BestBlock->Size, BestBlock->NextFree ); + DPRINT ( "breaking off preceding bytes into their own block...\n" ); + DPRINT ( "NewFreeBlock 0x%x Size %lu (Old Block's new size %lu) NextFree 0x%x\n", + NewFreeBlock, NewFreeBlock->Size, BestBlock->Size, BestBlock->NextFree ); - /* insert the new block into the chain */ - NewFreeBlock->NextFree = BestBlock->NextFree; - BestBlock->NextFree = NewFreeBlock; + /* insert the new block into the chain */ + NewFreeBlock->NextFree = BestBlock->NextFree; + BestBlock->NextFree = NewFreeBlock; - /* we want the following code to use our size-aligned block */ - BestPreviousBlock = BestBlock; - BestBlock = NewFreeBlock; + /* we want the following code to use our size-aligned block */ + BestPreviousBlock = BestBlock; + BestBlock = NewFreeBlock; - //VerifyPagedPool(); - } - } - } - /* - * non-size-aligned block search - */ - else while ( CurrentBlock != NULL ) - { - if ( CurrentBlock->Size >= BlockSize - && ( BestBlock == NULL || BestBlock->Size > CurrentBlock->Size ) - ) - { - BestPreviousBlock = PreviousBlock; - BestBlock = CurrentBlock; - } + //VerifyPagedPool(); + } + } + } + /* + * non-size-aligned block search + */ + else + while ( CurrentBlock != NULL ) + { + if ( CurrentBlock->Size >= BlockSize + && ( BestBlock == NULL || BestBlock->Size > CurrentBlock->Size ) + ) + { + BestPreviousBlock = PreviousBlock; + BestBlock = CurrentBlock; + } - PreviousBlock = CurrentBlock; - CurrentBlock = CurrentBlock->NextFree; - } + PreviousBlock = CurrentBlock; + CurrentBlock = CurrentBlock->NextFree; + } - /* - * We didn't find anything suitable at all. - */ - if (BestBlock == NULL) - { + /* + * We didn't find anything suitable at all. + */ + if (BestBlock == NULL) + { DPRINT1("Trying to allocate %lu bytes from paged pool - nothing suitable found, returning NULL\n", NumberOfBytes ); ExReleaseFastMutex(&MmPagedPoolLock); return(NULL); - } + } - DPRINT("BestBlock 0x%x NextFree 0x%x\n", BestBlock, BestBlock->NextFree ); + DPRINT("BestBlock 0x%x NextFree 0x%x\n", BestBlock, BestBlock->NextFree ); - //VerifyPagedPool(); + //VerifyPagedPool(); - /* - * Is there enough space to create a second block from the unused portion. - */ - if ( BestBlock->Size > BlockSize - && (BestBlock->Size - BlockSize) > sizeof(MM_PPOOL_FREE_BLOCK_HEADER) - ) - { + /* + * Is there enough space to create a second block from the unused portion. + */ + if ( BestBlock->Size > BlockSize + && (BestBlock->Size - BlockSize) > sizeof(MM_PPOOL_FREE_BLOCK_HEADER) + ) + { ULONG NewSize = BestBlock->Size - BlockSize; ASSERT_SIZE ( NewSize ); //DPRINT("creating 2nd block from unused portion\n"); DPRINT("BestBlock 0x%x Size 0x%x BlockSize 0x%x NewSize 0x%x\n", - BestBlock, BestBlock->Size, BlockSize, NewSize ); + BestBlock, BestBlock->Size, BlockSize, NewSize ); /* * Create the new free block. @@ -349,15 +354,15 @@ ExAllocatePagedPoolWithTag (IN POOL_TYPE PoolType, */ //DPRINT("replacing old free block with it"); if (BestPreviousBlock == NULL) - { - //DPRINT("(from beginning)"); - MmPagedPoolFirstFreeBlock = NextBlock; - } + { + //DPRINT("(from beginning)"); + MmPagedPoolFirstFreeBlock = NextBlock; + } else - { - //DPRINT("(from previous)"); - BestPreviousBlock->NextFree = NextBlock; - } + { + //DPRINT("(from previous)"); + BestPreviousBlock->NextFree = NextBlock; + } //DPRINT(".\n"); /* @@ -369,9 +374,9 @@ ExAllocatePagedPoolWithTag (IN POOL_TYPE PoolType, NewBlock->Size = BlockSize; ASSERT_SIZE ( NewBlock->Size ); //DPRINT(".\n"); - } - else - { + } + else + { ULONG NewSize = BestBlock->Size; /* @@ -379,13 +384,13 @@ ExAllocatePagedPoolWithTag (IN POOL_TYPE PoolType, */ //DPRINT ( "Removing selected block from free block list\n" ); if (BestPreviousBlock == NULL) - { - MmPagedPoolFirstFreeBlock = BestBlock->NextFree; - } + { + MmPagedPoolFirstFreeBlock = BestBlock->NextFree; + } else - { - BestPreviousBlock->NextFree = BestBlock->NextFree; - } + { + BestPreviousBlock->NextFree = BestBlock->NextFree; + } /* * Set up the header of the new block @@ -393,167 +398,168 @@ ExAllocatePagedPoolWithTag (IN POOL_TYPE PoolType, NewBlock = (PMM_PPOOL_USED_BLOCK_HEADER)BestBlock; NewBlock->Size = NewSize; ASSERT_SIZE ( NewBlock->Size ); - } + } #if MM_PPOOL_REDZONE_BYTES - // now add the block to the used block list - NewBlock->NextUsed = MmPagedPoolFirstUsedBlock; - MmPagedPoolFirstUsedBlock = NewBlock; + // now add the block to the used block list + NewBlock->NextUsed = MmPagedPoolFirstUsedBlock; + MmPagedPoolFirstUsedBlock = NewBlock; #endif//MM_PPOOL_REDZONE_BYTES - VerifyPagedPool(); + VerifyPagedPool(); - ExReleaseFastMutex(&MmPagedPoolLock); + ExReleaseFastMutex(&MmPagedPoolLock); - BlockAddress = block_to_address ( NewBlock ); -/* RtlZeroMemory(BlockAddress, NumberOfBytes);*/ + BlockAddress = block_to_address ( NewBlock ); + /* RtlZeroMemory(BlockAddress, NumberOfBytes);*/ #if MM_PPOOL_REDZONE_BYTES - NewBlock->UserSize = NumberOfBytes; - // write out buffer-overrun detection bytes - { - PUCHAR Addr = (PUCHAR)BlockAddress; - //DbgPrint ( "writing buffer-overrun detection bytes" ); - memset ( Addr - MM_PPOOL_REDZONE_BYTES, - MM_PPOOL_REDZONE_VALUE, MM_PPOOL_REDZONE_BYTES ); - memset ( Addr + NewBlock->UserSize, MM_PPOOL_REDZONE_VALUE, - MM_PPOOL_REDZONE_BYTES ); - /*for ( i = 0; i < MM_PPOOL_REDZONE_BYTES; i++ ) - { - //DbgPrint("."); - *(Addr-i-1) = 0xCD; - //DbgPrint("o"); - *(Addr+NewBlock->UserSize+i) = 0xCD; - }*/ - //DbgPrint ( "done!\n" ); - } + + NewBlock->UserSize = NumberOfBytes; + // write out buffer-overrun detection bytes + { + PUCHAR Addr = (PUCHAR)BlockAddress; + //DbgPrint ( "writing buffer-overrun detection bytes" ); + memset ( Addr - MM_PPOOL_REDZONE_BYTES, + MM_PPOOL_REDZONE_VALUE, MM_PPOOL_REDZONE_BYTES ); + memset ( Addr + NewBlock->UserSize, MM_PPOOL_REDZONE_VALUE, + MM_PPOOL_REDZONE_BYTES ); + /*for ( i = 0; i < MM_PPOOL_REDZONE_BYTES; i++ ) + { + //DbgPrint("."); + *(Addr-i-1) = 0xCD; + //DbgPrint("o"); + *(Addr+NewBlock->UserSize+i) = 0xCD; + }*/ + //DbgPrint ( "done!\n" ); + } #endif//MM_PPOOL_REDZONE_BYTES - return(BlockAddress); + return(BlockAddress); } VOID STDCALL ExFreePagedPool(IN PVOID Block) { - PMM_PPOOL_FREE_BLOCK_HEADER PreviousBlock; - PMM_PPOOL_USED_BLOCK_HEADER UsedBlock = address_to_block(Block); - ULONG UsedSize = UsedBlock->Size; - PMM_PPOOL_FREE_BLOCK_HEADER FreeBlock = - (PMM_PPOOL_FREE_BLOCK_HEADER)UsedBlock; - PMM_PPOOL_FREE_BLOCK_HEADER NextBlock; - PMM_PPOOL_FREE_BLOCK_HEADER NextNextBlock; + PMM_PPOOL_FREE_BLOCK_HEADER PreviousBlock; + PMM_PPOOL_USED_BLOCK_HEADER UsedBlock = address_to_block(Block); + ULONG UsedSize = UsedBlock->Size; + PMM_PPOOL_FREE_BLOCK_HEADER FreeBlock = + (PMM_PPOOL_FREE_BLOCK_HEADER)UsedBlock; + PMM_PPOOL_FREE_BLOCK_HEADER NextBlock; + PMM_PPOOL_FREE_BLOCK_HEADER NextNextBlock; #if MM_PPOOL_REDZONE_BYTES - // write out buffer-overrun detection bytes - { - int i; - PUCHAR Addr = (PUCHAR)Block; - //DbgPrint ( "checking buffer-overrun detection bytes..." ); - for ( i = 0; i < MM_PPOOL_REDZONE_BYTES; i++ ) - { - if (*(Addr-i-1) != MM_PPOOL_REDZONE_VALUE) + // write out buffer-overrun detection bytes + { + int i; + PUCHAR Addr = (PUCHAR)Block; + //DbgPrint ( "checking buffer-overrun detection bytes..." ); + for ( i = 0; i < MM_PPOOL_REDZONE_BYTES; i++ ) { - DPRINT1("Attempt to free memory %#08x. Redzone underrun!\n", Block); - } - if (*(Addr+UsedBlock->UserSize+i) != MM_PPOOL_REDZONE_VALUE) - { - DPRINT1("Attempt to free memory %#08x. Redzone overrun!\n", Block); - } + if (*(Addr-i-1) != MM_PPOOL_REDZONE_VALUE) + { + DPRINT1("Attempt to free memory %#08x. Redzone underrun!\n", Block); + } + if (*(Addr+UsedBlock->UserSize+i) != MM_PPOOL_REDZONE_VALUE) + { + DPRINT1("Attempt to free memory %#08x. Redzone overrun!\n", Block); + } - assert ( *(Addr-i-1) == MM_PPOOL_REDZONE_VALUE ); - assert ( *(Addr+UsedBlock->UserSize+i) == MM_PPOOL_REDZONE_VALUE ); - } - //DbgPrint ( "done!\n" ); - } + assert ( *(Addr-i-1) == MM_PPOOL_REDZONE_VALUE ); + assert ( *(Addr+UsedBlock->UserSize+i) == MM_PPOOL_REDZONE_VALUE ); + } + //DbgPrint ( "done!\n" ); + } #endif//MM_PPOOL_REDZONE_BYTES - ExAcquireFastMutex(&MmPagedPoolLock); + ExAcquireFastMutex(&MmPagedPoolLock); #if MM_PPOOL_REDZONE_BYTES - // remove from used list... - { - PMM_PPOOL_USED_BLOCK_HEADER pPrev = MmPagedPoolFirstUsedBlock; - if ( pPrev == UsedBlock ) - { - // special-case, our freeing block is first in list... - MmPagedPoolFirstUsedBlock = pPrev->NextUsed; - } - else - { - while ( pPrev && pPrev->NextUsed != UsedBlock ) - pPrev = pPrev->NextUsed; - // if this assert fails - memory has been corrupted - // ( or I have a logic error...! ) - assert ( pPrev->NextUsed == UsedBlock ); - pPrev->NextUsed = UsedBlock->NextUsed; - } - } + // remove from used list... + { + PMM_PPOOL_USED_BLOCK_HEADER pPrev = MmPagedPoolFirstUsedBlock; + if ( pPrev == UsedBlock ) + { + // special-case, our freeing block is first in list... + MmPagedPoolFirstUsedBlock = pPrev->NextUsed; + } + else + { + while ( pPrev && pPrev->NextUsed != UsedBlock ) + pPrev = pPrev->NextUsed; + // if this assert fails - memory has been corrupted + // ( or I have a logic error...! ) + assert ( pPrev->NextUsed == UsedBlock ); + pPrev->NextUsed = UsedBlock->NextUsed; + } + } #endif//MM_PPOOL_REDZONE_BYTES - /* - * Begin setting up the newly freed block's header. - */ - FreeBlock->Size = UsedSize; - ASSERT_SIZE ( FreeBlock->Size ); + /* + * Begin setting up the newly freed block's header. + */ + FreeBlock->Size = UsedSize; + ASSERT_SIZE ( FreeBlock->Size ); - /* - * Find the blocks immediately before and after the newly freed block on the free list. - */ - PreviousBlock = NULL; - NextBlock = MmPagedPoolFirstFreeBlock; - while (NextBlock != NULL && NextBlock < FreeBlock) - { + /* + * Find the blocks immediately before and after the newly freed block on the free list. + */ + PreviousBlock = NULL; + NextBlock = MmPagedPoolFirstFreeBlock; + while (NextBlock != NULL && NextBlock < FreeBlock) + { PreviousBlock = NextBlock; NextBlock = NextBlock->NextFree; - } + } - /* - * Insert the freed block on the free list. - */ - if (PreviousBlock == NULL) - { + /* + * Insert the freed block on the free list. + */ + if (PreviousBlock == NULL) + { FreeBlock->NextFree = MmPagedPoolFirstFreeBlock; MmPagedPoolFirstFreeBlock = FreeBlock; - } - else - { + } + else + { PreviousBlock->NextFree = FreeBlock; FreeBlock->NextFree = NextBlock; - } + } - /* - * If the next block is immediately adjacent to the newly freed one then - * merge them. - */ - if (NextBlock != NULL && - ((char*)FreeBlock + FreeBlock->Size) == (char*)NextBlock) - { + /* + * If the next block is immediately adjacent to the newly freed one then + * merge them. + */ + if (NextBlock != NULL && + ((char*)FreeBlock + FreeBlock->Size) == (char*)NextBlock) + { FreeBlock->Size = FreeBlock->Size + NextBlock->Size; ASSERT_SIZE ( FreeBlock->Size ); FreeBlock->NextFree = NextBlock->NextFree; NextNextBlock = NextBlock->NextFree; - } - else - { + } + else + { NextNextBlock = NextBlock; - } + } - /* - * If the previous block is adjacent to the newly freed one then - * merge them. - */ - if (PreviousBlock != NULL && - ((char*)PreviousBlock + PreviousBlock->Size) == (char*)FreeBlock) - { + /* + * If the previous block is adjacent to the newly freed one then + * merge them. + */ + if (PreviousBlock != NULL && + ((char*)PreviousBlock + PreviousBlock->Size) == (char*)FreeBlock) + { PreviousBlock->Size = PreviousBlock->Size + FreeBlock->Size; ASSERT_SIZE ( PreviousBlock->Size ); PreviousBlock->NextFree = NextNextBlock; - } + } - VerifyPagedPool(); + VerifyPagedPool(); - ExReleaseFastMutex(&MmPagedPoolLock); + ExReleaseFastMutex(&MmPagedPoolLock); } /* EOF */ diff --git a/reactos/ntoskrnl/mm/region.c b/reactos/ntoskrnl/mm/region.c index 697158c777a..4dae3a96d7f 100644 --- a/reactos/ntoskrnl/mm/region.c +++ b/reactos/ntoskrnl/mm/region.c @@ -16,14 +16,14 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: region.c,v 1.6 2003/12/30 18:52:05 fireball Exp $ +/* $Id: region.c,v 1.7 2004/04/10 22:35:25 gdalsnes Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/mm/region.c * PROGRAMMER: David Welch * PURPOSE: */ - + /* INCLUDE *****************************************************************/ #include @@ -43,279 +43,283 @@ /* FUNCTIONS *****************************************************************/ -VOID STATIC +VOID STATIC InsertAfterEntry(PLIST_ENTRY Previous, - PLIST_ENTRY Entry) + PLIST_ENTRY Entry) /* * FUNCTION: Insert a list entry after another entry in the list */ { Previous->Flink->Blink = Entry; - + Entry->Flink = Previous->Flink; Entry->Blink = Previous; - + Previous->Flink = Entry; } PMM_REGION STATIC MmSplitRegion(PMM_REGION InitialRegion, PVOID InitialBaseAddress, - PVOID StartAddress, ULONG Length, ULONG NewType, - ULONG NewProtect, PMADDRESS_SPACE AddressSpace, - PMM_ALTER_REGION_FUNC AlterFunc) + PVOID StartAddress, ULONG Length, ULONG NewType, + ULONG NewProtect, PMADDRESS_SPACE AddressSpace, + PMM_ALTER_REGION_FUNC AlterFunc) { - PMM_REGION NewRegion1; - PMM_REGION NewRegion2; - ULONG 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); - } + PMM_REGION NewRegion1; + PMM_REGION NewRegion2; + ULONG InternalLength; - /* Create the new region. */ - NewRegion1 = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION), - TAG_MM_REGION); - if (NewRegion1 == 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) + { ExFreePool(NewRegion2); 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); + } + 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)) - { + /* + * 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 - { + NewRegion2->Length = ((char*)InitialBaseAddress + InitialRegion->Length) - + ((char*)StartAddress + Length); + InsertAfterEntry(&NewRegion1->RegionListEntry, + &NewRegion2->RegionListEntry); + } + else + { ExFreePool(NewRegion2); - } + } - /* Either remove or shrink the initial region. */ - if (InitialBaseAddress == StartAddress) - { + /* Either remove or shrink the initial region. */ + if (InitialBaseAddress == StartAddress) + { RemoveEntryList(&InitialRegion->RegionListEntry); ExFreePool(InitialRegion); - } - else - { + } + else + { InitialRegion->Length = (char*)StartAddress - (char*)InitialBaseAddress; - } - - return(NewRegion1); + } + + return(NewRegion1); } NTSTATUS -MmAlterRegion(PMADDRESS_SPACE AddressSpace, PVOID BaseAddress, - PLIST_ENTRY RegionListHead, PVOID StartAddress, ULONG Length, - ULONG NewType, ULONG NewProtect, PMM_ALTER_REGION_FUNC AlterFunc) +MmAlterRegion(PMADDRESS_SPACE AddressSpace, PVOID BaseAddress, + PLIST_ENTRY RegionListHead, PVOID StartAddress, ULONG Length, + ULONG NewType, ULONG NewProtect, PMM_ALTER_REGION_FUNC AlterFunc) { - PMM_REGION InitialRegion; - PVOID InitialBaseAddress; - PMM_REGION NewRegion; - PLIST_ENTRY CurrentEntry; - PMM_REGION CurrentRegion = NULL; - PVOID CurrentBaseAddress; - ULONG RemainingLength; + PMM_REGION InitialRegion; + PVOID InitialBaseAddress; + PMM_REGION NewRegion; + PLIST_ENTRY CurrentEntry; + PMM_REGION CurrentRegion = NULL; + PVOID CurrentBaseAddress; + ULONG RemainingLength; - /* - * Find the first region containing part of the range of addresses to - * be altered. - */ - InitialRegion = MmFindRegion(BaseAddress, RegionListHead, StartAddress, - &InitialBaseAddress); - if (((char*)StartAddress + Length) > - ((char*)InitialBaseAddress + InitialRegion->Length)) - { - RemainingLength = ((char*)StartAddress + Length) - - ((char*)InitialBaseAddress + InitialRegion->Length); - } - else - { + /* + * Find the first region containing part of the range of addresses to + * be altered. + */ + InitialRegion = MmFindRegion(BaseAddress, RegionListHead, StartAddress, + &InitialBaseAddress); + if (((char*)StartAddress + Length) > + ((char*)InitialBaseAddress + InitialRegion->Length)) + { + RemainingLength = ((char*)StartAddress + Length) - + ((char*)InitialBaseAddress + InitialRegion->Length); + } + else + { RemainingLength = 0; - } - /* - * 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 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); - } - } - else - { + { + return(STATUS_NO_MEMORY); + } + } + else + { NewRegion = InitialRegion; - } - - /* - * 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) - { + } + + /* + * 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) + { if (CurrentRegion->Type != NewType && - CurrentRegion->Protect != NewProtect) - { - AlterFunc(AddressSpace, CurrentBaseAddress, CurrentRegion->Length, - CurrentRegion->Type, CurrentRegion->Protect, - NewType, NewProtect); - } + CurrentRegion->Protect != NewProtect) + { + AlterFunc(AddressSpace, CurrentBaseAddress, CurrentRegion->Length, + CurrentRegion->Type, CurrentRegion->Protect, + NewType, NewProtect); + } #if defined(__GNUC__) CurrentBaseAddress += CurrentRegion->Length; #else + { - char* pTemp = CurrentBaseAddress; - pTemp += CurrentRegion->Length; - CurrentBaseAddress = pTemp; + char* pTemp = CurrentBaseAddress; + pTemp += CurrentRegion->Length; + CurrentBaseAddress = pTemp; } #endif NewRegion->Length += CurrentRegion->Length; RemainingLength -= CurrentRegion->Length; - CurrentEntry = CurrentEntry->Flink; + CurrentEntry = CurrentEntry->Flink; RemoveEntryList(&CurrentRegion->RegionListEntry); ExFreePool(CurrentRegion); - CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, - RegionListEntry); - } + CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, + RegionListEntry); + } - /* - * Split any final region. - */ - if (RemainingLength > 0) - { - CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, - RegionListEntry); + /* + * Split any final region. + */ + if (RemainingLength > 0) + { + CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, + RegionListEntry); if (CurrentRegion->Type != NewType && - CurrentRegion->Protect != NewProtect) - { - AlterFunc(AddressSpace, CurrentBaseAddress, CurrentRegion->Length, - CurrentRegion->Type, CurrentRegion->Protect, - NewType, NewProtect); - } + CurrentRegion->Protect != NewProtect) + { + AlterFunc(AddressSpace, CurrentBaseAddress, CurrentRegion->Length, + 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) - { + /* + * 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); + CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, + RegionListEntry); if (CurrentRegion->Type == NewRegion->Type && - CurrentRegion->Protect == NewRegion->Protect) - { - NewRegion->Length += CurrentRegion->Length; - RemoveEntryList(&CurrentRegion->RegionListEntry); - ExFreePool(CurrentRegion); - } - } + CurrentRegion->Protect == NewRegion->Protect) + { + NewRegion->Length += CurrentRegion->Length; + RemoveEntryList(&CurrentRegion->RegionListEntry); + ExFreePool(CurrentRegion); + } + } - /* - * If the region before the new region has the same type then merge them. - */ - if (NewRegion->RegionListEntry.Blink != RegionListHead) - { + /* + * 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); + CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, + RegionListEntry); if (CurrentRegion->Type == NewRegion->Type && - CurrentRegion->Protect == NewRegion->Protect) - { - NewRegion->Length += CurrentRegion->Length; - RemoveEntryList(&CurrentRegion->RegionListEntry); - ExFreePool(CurrentRegion); - } - } + CurrentRegion->Protect == NewRegion->Protect) + { + NewRegion->Length += CurrentRegion->Length; + RemoveEntryList(&CurrentRegion->RegionListEntry); + ExFreePool(CurrentRegion); + } + } - return(STATUS_SUCCESS); + return(STATUS_SUCCESS); } VOID MmInitialiseRegion(PLIST_ENTRY RegionListHead, ULONG Length, ULONG Type, - ULONG Protect) + ULONG Protect) { - PMM_REGION Region; + PMM_REGION Region; - Region = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION), - TAG_MM_REGION); - Region->Type = Type; - Region->Protect = Protect; - Region->Length = Length; - InitializeListHead(RegionListHead); - InsertHeadList(RegionListHead, &Region->RegionListEntry); + Region = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION), + TAG_MM_REGION); + Region->Type = Type; + Region->Protect = Protect; + Region->Length = Length; + InitializeListHead(RegionListHead); + InsertHeadList(RegionListHead, &Region->RegionListEntry); } PMM_REGION MmFindRegion(PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID Address, - PVOID* RegionBaseAddress) + PVOID* RegionBaseAddress) { - PLIST_ENTRY current_entry; - PMM_REGION current; - PVOID StartAddress = BaseAddress; - - current_entry = RegionListHead->Flink; - while (current_entry != RegionListHead) - { + 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); - 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; #if defined(__GNUC__) + StartAddress += current->Length; #else + { - char* pTemp = StartAddress; - pTemp += current->Length; - StartAddress = pTemp; + char* pTemp = StartAddress; + pTemp += current->Length; + StartAddress = pTemp; } #endif - } - return(NULL); + + } + return(NULL); } diff --git a/reactos/ntoskrnl/mm/rmap.c b/reactos/ntoskrnl/mm/rmap.c index 9fe184c5151..a6d3d48d6df 100644 --- a/reactos/ntoskrnl/mm/rmap.c +++ b/reactos/ntoskrnl/mm/rmap.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: rmap.c,v 1.27 2004/03/05 11:31:59 hbirr Exp $ +/* $Id: rmap.c,v 1.28 2004/04/10 22:35:25 gdalsnes Exp $ * * COPYRIGHT: See COPYING in the top directory * PROJECT: ReactOS kernel @@ -40,10 +40,11 @@ typedef struct _MM_RMAP_ENTRY { - struct _MM_RMAP_ENTRY* Next; - PEPROCESS Process; - PVOID Address; -} MM_RMAP_ENTRY, *PMM_RMAP_ENTRY; + struct _MM_RMAP_ENTRY* Next; + PEPROCESS Process; + PVOID Address; +} +MM_RMAP_ENTRY, *PMM_RMAP_ENTRY; #define TAG_RMAP TAG('R', 'M', 'A', 'P') @@ -57,126 +58,100 @@ static NPAGED_LOOKASIDE_LIST RmapLookasideList; VOID INIT_FUNCTION MmInitializeRmapList(VOID) { - ExInitializeFastMutex(&RmapListLock); - ExInitializeNPagedLookasideList (&RmapLookasideList, - NULL, - NULL, - 0, - sizeof(MM_RMAP_ENTRY), - TAG_RMAP, - 50); + ExInitializeFastMutex(&RmapListLock); + ExInitializeNPagedLookasideList (&RmapLookasideList, + NULL, + NULL, + 0, + sizeof(MM_RMAP_ENTRY), + TAG_RMAP, + 50); } NTSTATUS MmWritePagePhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress) { - PMM_RMAP_ENTRY entry; - PMEMORY_AREA MemoryArea; - PMADDRESS_SPACE AddressSpace; - ULONG Type; - PVOID Address; - PEPROCESS Process; - PMM_PAGEOP PageOp; - ULONG Offset; - NTSTATUS Status = STATUS_SUCCESS; + PMM_RMAP_ENTRY entry; + PMEMORY_AREA MemoryArea; + PMADDRESS_SPACE AddressSpace; + ULONG Type; + PVOID Address; + PEPROCESS Process; + PMM_PAGEOP PageOp; + ULONG Offset; + NTSTATUS Status = STATUS_SUCCESS; - /* - * Check that the address still has a valid rmap; then reference the - * process so it isn't freed while we are working. - */ - ExAcquireFastMutex(&RmapListLock); - entry = MmGetRmapListHeadPage(PhysicalAddress); - if (entry == NULL) - { + /* + * Check that the address still has a valid rmap; then reference the + * process so it isn't freed while we are working. + */ + ExAcquireFastMutex(&RmapListLock); + entry = MmGetRmapListHeadPage(PhysicalAddress); + if (entry == NULL) + { ExReleaseFastMutex(&RmapListLock); return(STATUS_UNSUCCESSFUL); - } - Process = entry->Process; - Address = entry->Address; - if ((((ULONG)Address) & 0xFFF) != 0) - { + } + Process = entry->Process; + Address = entry->Address; + if ((((ULONG)Address) & 0xFFF) != 0) + { KEBUGCHECK(0); - } - if (Address < (PVOID)KERNEL_BASE) - { + } + if (Address < (PVOID)KERNEL_BASE) + { Status = ObReferenceObjectByPointer(Process, PROCESS_ALL_ACCESS, NULL, KernelMode); ExReleaseFastMutex(&RmapListLock); if (!NT_SUCCESS(Status)) - { - return Status; - } + { + return Status; + } AddressSpace = &Process->AddressSpace; - } - else - { + } + else + { ExReleaseFastMutex(&RmapListLock); AddressSpace = MmGetKernelAddressSpace(); - } + } - /* - * Lock the address space; then check that the address we are using - * still corresponds to a valid memory area (the page might have been - * freed or paged out after we read the rmap entry.) - */ - MmLockAddressSpace(AddressSpace); - MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, Address); - if (MemoryArea == NULL || MemoryArea->DeleteInProgress) - { + /* + * Lock the address space; then check that the address we are using + * still corresponds to a valid memory area (the page might have been + * freed or paged out after we read the rmap entry.) + */ + MmLockAddressSpace(AddressSpace); + MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, Address); + if (MemoryArea == NULL || MemoryArea->DeleteInProgress) + { MmUnlockAddressSpace(AddressSpace); if (Address < (PVOID)KERNEL_BASE) - { - ObDereferenceObject(Process); - } + { + ObDereferenceObject(Process); + } return(STATUS_UNSUCCESSFUL); - } + } - Type = MemoryArea->Type; - if (Type == MEMORY_AREA_SECTION_VIEW) - { + Type = MemoryArea->Type; + if (Type == MEMORY_AREA_SECTION_VIEW) + { Offset = (ULONG)((char*)Address - (ULONG)MemoryArea->BaseAddress); /* * Get or create a pageop */ - PageOp = MmGetPageOp(MemoryArea, 0, 0, - MemoryArea->Data.SectionData.Segment, - Offset, MM_PAGEOP_PAGEOUT, TRUE); + PageOp = MmGetPageOp(MemoryArea, 0, 0, + MemoryArea->Data.SectionData.Segment, + Offset, MM_PAGEOP_PAGEOUT, TRUE); if (PageOp == NULL) - { - MmUnlockAddressSpace(AddressSpace); - if (Address < (PVOID)KERNEL_BASE) - { - ObDereferenceObject(Process); - } - return(STATUS_UNSUCCESSFUL); - } - - /* - * Release locks now we have a page op. - */ - MmUnlockAddressSpace(AddressSpace); - - /* - * Do the actual page out work. - */ - Status = MmWritePageSectionView(AddressSpace, MemoryArea, - Address, PageOp); - } - else if (Type == MEMORY_AREA_VIRTUAL_MEMORY) - { - PageOp = MmGetPageOp(MemoryArea, Address < (PVOID)KERNEL_BASE ? Process->UniqueProcessId : 0, - Address, NULL, 0, MM_PAGEOP_PAGEOUT, TRUE); - - if (PageOp == NULL) - { - MmUnlockAddressSpace(AddressSpace); - if (Address < (PVOID)KERNEL_BASE) - { - ObDereferenceObject(Process); - } - return(STATUS_UNSUCCESSFUL); - } + { + MmUnlockAddressSpace(AddressSpace); + if (Address < (PVOID)KERNEL_BASE) + { + ObDereferenceObject(Process); + } + return(STATUS_UNSUCCESSFUL); + } /* * Release locks now we have a page op. @@ -186,95 +161,121 @@ MmWritePagePhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress) /* * Do the actual page out work. */ - Status = MmWritePageVirtualMemory(AddressSpace, MemoryArea, - Address, PageOp); - } - else - { + Status = MmWritePageSectionView(AddressSpace, MemoryArea, + Address, PageOp); + } + else if (Type == MEMORY_AREA_VIRTUAL_MEMORY) + { + PageOp = MmGetPageOp(MemoryArea, Address < (PVOID)KERNEL_BASE ? Process->UniqueProcessId : 0, + Address, NULL, 0, MM_PAGEOP_PAGEOUT, TRUE); + + if (PageOp == NULL) + { + MmUnlockAddressSpace(AddressSpace); + if (Address < (PVOID)KERNEL_BASE) + { + ObDereferenceObject(Process); + } + return(STATUS_UNSUCCESSFUL); + } + + /* + * Release locks now we have a page op. + */ + MmUnlockAddressSpace(AddressSpace); + + /* + * Do the actual page out work. + */ + Status = MmWritePageVirtualMemory(AddressSpace, MemoryArea, + Address, PageOp); + } + else + { KEBUGCHECK(0); - } - if (Address < (PVOID)KERNEL_BASE) - { + } + if (Address < (PVOID)KERNEL_BASE) + { ObDereferenceObject(Process); - } - return(Status); + } + return(Status); } NTSTATUS MmPageOutPhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress) { - PMM_RMAP_ENTRY entry; - PMEMORY_AREA MemoryArea; - PMADDRESS_SPACE AddressSpace; - ULONG Type; - PVOID Address; - PEPROCESS Process; - PMM_PAGEOP PageOp; - ULONG Offset; - NTSTATUS Status = STATUS_SUCCESS; + PMM_RMAP_ENTRY entry; + PMEMORY_AREA MemoryArea; + PMADDRESS_SPACE AddressSpace; + ULONG Type; + PVOID Address; + PEPROCESS Process; + PMM_PAGEOP PageOp; + ULONG Offset; + NTSTATUS Status = STATUS_SUCCESS; - ExAcquireFastMutex(&RmapListLock); - entry = MmGetRmapListHeadPage(PhysicalAddress); - if (entry == NULL || MmGetLockCountPage(PhysicalAddress) != 0) - { + ExAcquireFastMutex(&RmapListLock); + entry = MmGetRmapListHeadPage(PhysicalAddress); + if (entry == NULL || MmGetLockCountPage(PhysicalAddress) != 0) + { ExReleaseFastMutex(&RmapListLock); return(STATUS_UNSUCCESSFUL); - } - Process = entry->Process; - Address = entry->Address; - if ((((ULONG)Address) & 0xFFF) != 0) - { + } + Process = entry->Process; + Address = entry->Address; + if ((((ULONG)Address) & 0xFFF) != 0) + { KEBUGCHECK(0); - } + } - if (Address < (PVOID)KERNEL_BASE) - { + if (Address < (PVOID)KERNEL_BASE) + { Status = ObReferenceObjectByPointer(Process, PROCESS_ALL_ACCESS, NULL, KernelMode); ExReleaseFastMutex(&RmapListLock); if (!NT_SUCCESS(Status)) - { - return Status; - } + { + return Status; + } AddressSpace = &Process->AddressSpace; - } - else - { + } + else + { ExReleaseFastMutex(&RmapListLock); AddressSpace = MmGetKernelAddressSpace(); - } + } - MmLockAddressSpace(AddressSpace); - MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, Address); - if (MemoryArea == NULL || MemoryArea->DeleteInProgress) - { + MmLockAddressSpace(AddressSpace); + MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, Address); + if (MemoryArea == NULL || MemoryArea->DeleteInProgress) + { MmUnlockAddressSpace(AddressSpace); if (Address < (PVOID)KERNEL_BASE) - { - ObDereferenceObject(Process); - } + { + ObDereferenceObject(Process); + } return(STATUS_UNSUCCESSFUL); - } - Type = MemoryArea->Type; - if (Type == MEMORY_AREA_SECTION_VIEW) - { + } + Type = MemoryArea->Type; + if (Type == MEMORY_AREA_SECTION_VIEW) + { Offset = (ULONG)((char*)Address - (ULONG)MemoryArea->BaseAddress); /* * Get or create a pageop */ - PageOp = MmGetPageOp(MemoryArea, 0, 0, - MemoryArea->Data.SectionData.Segment, - Offset, MM_PAGEOP_PAGEOUT, TRUE); + PageOp = MmGetPageOp(MemoryArea, 0, 0, + MemoryArea->Data.SectionData.Segment, + Offset, MM_PAGEOP_PAGEOUT, TRUE); if (PageOp == NULL) - { - MmUnlockAddressSpace(AddressSpace); - if (Address < (PVOID)KERNEL_BASE) - { - ObDereferenceObject(Process); - } - return(STATUS_UNSUCCESSFUL); - } - + { + MmUnlockAddressSpace(AddressSpace); + if (Address < (PVOID)KERNEL_BASE) + { + ObDereferenceObject(Process); + } + return(STATUS_UNSUCCESSFUL); + } + /* * Release locks now we have a page op. */ @@ -283,22 +284,22 @@ MmPageOutPhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress) /* * Do the actual page out work. */ - Status = MmPageOutSectionView(AddressSpace, MemoryArea, - Address, PageOp); - } - else if (Type == MEMORY_AREA_VIRTUAL_MEMORY) - { + Status = MmPageOutSectionView(AddressSpace, MemoryArea, + Address, PageOp); + } + else if (Type == MEMORY_AREA_VIRTUAL_MEMORY) + { PageOp = MmGetPageOp(MemoryArea, Address < (PVOID)KERNEL_BASE ? Process->UniqueProcessId : 0, - Address, NULL, 0, MM_PAGEOP_PAGEOUT, TRUE); + Address, NULL, 0, MM_PAGEOP_PAGEOUT, TRUE); if (PageOp == NULL) - { - MmUnlockAddressSpace(AddressSpace); - if (Address < (PVOID)KERNEL_BASE) - { - ObDereferenceObject(Process); - } - return(STATUS_UNSUCCESSFUL); - } + { + MmUnlockAddressSpace(AddressSpace); + if (Address < (PVOID)KERNEL_BASE) + { + ObDereferenceObject(Process); + } + return(STATUS_UNSUCCESSFUL); + } /* * Release locks now we have a page op. @@ -308,177 +309,177 @@ MmPageOutPhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress) /* * Do the actual page out work. */ - Status = MmPageOutVirtualMemory(AddressSpace, MemoryArea, - Address, PageOp); - } - else - { + Status = MmPageOutVirtualMemory(AddressSpace, MemoryArea, + Address, PageOp); + } + else + { KEBUGCHECK(0); - } - if (Address < (PVOID)KERNEL_BASE) - { + } + if (Address < (PVOID)KERNEL_BASE) + { ObDereferenceObject(Process); - } - return(Status); + } + return(Status); } VOID MmSetCleanAllRmaps(PHYSICAL_ADDRESS PhysicalAddress) { - PMM_RMAP_ENTRY current_entry; + PMM_RMAP_ENTRY current_entry; - ExAcquireFastMutex(&RmapListLock); - current_entry = MmGetRmapListHeadPage(PhysicalAddress); - if (current_entry == NULL) - { + ExAcquireFastMutex(&RmapListLock); + current_entry = MmGetRmapListHeadPage(PhysicalAddress); + if (current_entry == NULL) + { DPRINT1("MmIsDirtyRmap: No rmaps.\n"); KEBUGCHECK(0); - } - while (current_entry != NULL) - { + } + while (current_entry != NULL) + { MmSetCleanPage(current_entry->Process, current_entry->Address); current_entry = current_entry->Next; - } - ExReleaseFastMutex(&RmapListLock); + } + ExReleaseFastMutex(&RmapListLock); } VOID MmSetDirtyAllRmaps(PHYSICAL_ADDRESS PhysicalAddress) { - PMM_RMAP_ENTRY current_entry; + PMM_RMAP_ENTRY current_entry; - ExAcquireFastMutex(&RmapListLock); - current_entry = MmGetRmapListHeadPage(PhysicalAddress); - if (current_entry == NULL) - { + ExAcquireFastMutex(&RmapListLock); + current_entry = MmGetRmapListHeadPage(PhysicalAddress); + if (current_entry == NULL) + { DPRINT1("MmIsDirtyRmap: No rmaps.\n"); KEBUGCHECK(0); - } - while (current_entry != NULL) - { + } + while (current_entry != NULL) + { MmSetDirtyPage(current_entry->Process, current_entry->Address); current_entry = current_entry->Next; - } - ExReleaseFastMutex(&RmapListLock); + } + ExReleaseFastMutex(&RmapListLock); } BOOL MmIsDirtyPageRmap(PHYSICAL_ADDRESS PhysicalAddress) { - PMM_RMAP_ENTRY current_entry; + PMM_RMAP_ENTRY current_entry; - ExAcquireFastMutex(&RmapListLock); - current_entry = MmGetRmapListHeadPage(PhysicalAddress); - if (current_entry == NULL) - { + ExAcquireFastMutex(&RmapListLock); + current_entry = MmGetRmapListHeadPage(PhysicalAddress); + if (current_entry == NULL) + { ExReleaseFastMutex(&RmapListLock); return(FALSE); - } - while (current_entry != NULL) - { + } + while (current_entry != NULL) + { if (MmIsDirtyPage(current_entry->Process, current_entry->Address)) - { - ExReleaseFastMutex(&RmapListLock); - return(TRUE); - } + { + ExReleaseFastMutex(&RmapListLock); + return(TRUE); + } current_entry = current_entry->Next; - } - ExReleaseFastMutex(&RmapListLock); - return(FALSE); + } + ExReleaseFastMutex(&RmapListLock); + return(FALSE); } VOID -MmInsertRmap(PHYSICAL_ADDRESS PhysicalAddress, PEPROCESS Process, - PVOID Address) +MmInsertRmap(PHYSICAL_ADDRESS PhysicalAddress, PEPROCESS Process, + PVOID Address) { - PMM_RMAP_ENTRY current_entry; - PMM_RMAP_ENTRY new_entry; + PMM_RMAP_ENTRY current_entry; + PMM_RMAP_ENTRY new_entry; - Address = (PVOID)PAGE_ROUND_DOWN(Address); + Address = (PVOID)PAGE_ROUND_DOWN(Address); - new_entry = ExAllocateFromNPagedLookasideList(&RmapLookasideList); - if (new_entry == NULL) - { + new_entry = ExAllocateFromNPagedLookasideList(&RmapLookasideList); + if (new_entry == NULL) + { KEBUGCHECK(0); - } - new_entry->Address = Address; - new_entry->Process = Process; + } + new_entry->Address = Address; + new_entry->Process = Process; - if (MmGetPhysicalAddressForProcess(Process, Address).QuadPart != - PhysicalAddress.QuadPart) - { + if (MmGetPhysicalAddressForProcess(Process, Address).QuadPart != + PhysicalAddress.QuadPart) + { DPRINT1("Insert rmap (%d, 0x%.8X) 0x%.8X which doesn't match physical " - "address 0x%.8X\n", Process->UniqueProcessId, Address, - MmGetPhysicalAddressForProcess(Process, Address).u.LowPart, - PhysicalAddress.u.LowPart); + "address 0x%.8X\n", Process->UniqueProcessId, Address, + MmGetPhysicalAddressForProcess(Process, Address).u.LowPart, + PhysicalAddress.u.LowPart); KEBUGCHECK(0); - } + } - ExAcquireFastMutex(&RmapListLock); - current_entry = MmGetRmapListHeadPage(PhysicalAddress); - new_entry->Next = current_entry; - MmSetRmapListHeadPage(PhysicalAddress, new_entry); - ExReleaseFastMutex(&RmapListLock); + ExAcquireFastMutex(&RmapListLock); + current_entry = MmGetRmapListHeadPage(PhysicalAddress); + new_entry->Next = current_entry; + MmSetRmapListHeadPage(PhysicalAddress, new_entry); + ExReleaseFastMutex(&RmapListLock); } VOID -MmDeleteAllRmaps(PHYSICAL_ADDRESS PhysicalAddress, PVOID Context, - VOID (*DeleteMapping)(PVOID Context, PEPROCESS Process, - PVOID Address)) +MmDeleteAllRmaps(PHYSICAL_ADDRESS PhysicalAddress, PVOID Context, + VOID (*DeleteMapping)(PVOID Context, PEPROCESS Process, + PVOID Address)) { - PMM_RMAP_ENTRY current_entry; - PMM_RMAP_ENTRY previous_entry; + PMM_RMAP_ENTRY current_entry; + PMM_RMAP_ENTRY previous_entry; - ExAcquireFastMutex(&RmapListLock); - current_entry = MmGetRmapListHeadPage(PhysicalAddress); - if (current_entry == NULL) - { + ExAcquireFastMutex(&RmapListLock); + current_entry = MmGetRmapListHeadPage(PhysicalAddress); + if (current_entry == NULL) + { DPRINT1("MmDeleteAllRmaps: No rmaps.\n"); KEBUGCHECK(0); - } - MmSetRmapListHeadPage(PhysicalAddress, NULL); - while (current_entry != NULL) - { + } + MmSetRmapListHeadPage(PhysicalAddress, NULL); + while (current_entry != NULL) + { previous_entry = current_entry; current_entry = current_entry->Next; if (DeleteMapping) - { - DeleteMapping(Context, previous_entry->Process, - previous_entry->Address); - } + { + DeleteMapping(Context, previous_entry->Process, + previous_entry->Address); + } ExFreeToNPagedLookasideList(&RmapLookasideList, previous_entry); - } - ExReleaseFastMutex(&RmapListLock); + } + ExReleaseFastMutex(&RmapListLock); } VOID -MmDeleteRmap(PHYSICAL_ADDRESS PhysicalAddress, PEPROCESS Process, - PVOID Address) +MmDeleteRmap(PHYSICAL_ADDRESS PhysicalAddress, 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(PhysicalAddress); - while (current_entry != NULL) - { - if (current_entry->Process == Process && - current_entry->Address == Address) - { - if (previous_entry == NULL) - { - MmSetRmapListHeadPage(PhysicalAddress, current_entry->Next); - } - else - { - previous_entry->Next = current_entry->Next; - } - ExReleaseFastMutex(&RmapListLock); - ExFreeToNPagedLookasideList(&RmapLookasideList, current_entry); - return; - } + ExAcquireFastMutex(&RmapListLock); + previous_entry = NULL; + current_entry = MmGetRmapListHeadPage(PhysicalAddress); + while (current_entry != NULL) + { + if (current_entry->Process == Process && + current_entry->Address == Address) + { + if (previous_entry == NULL) + { + MmSetRmapListHeadPage(PhysicalAddress, 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; - } - KEBUGCHECK(0); + } + KEBUGCHECK(0); } diff --git a/reactos/ntoskrnl/mm/section.c b/reactos/ntoskrnl/mm/section.c index 6f1a8fac688..6b8432f917b 100644 --- a/reactos/ntoskrnl/mm/section.c +++ b/reactos/ntoskrnl/mm/section.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: section.c,v 1.146 2004/03/05 11:31:59 hbirr Exp $ +/* $Id: section.c,v 1.147 2004/04/10 22:35:26 gdalsnes Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/mm/section.c @@ -49,22 +49,23 @@ typedef struct { - PSECTION_OBJECT Section; - PMM_SECTION_SEGMENT Segment; - ULONG Offset; - BOOLEAN WasDirty; - BOOLEAN Private; -} MM_SECTION_PAGEOUT_CONTEXT; + PSECTION_OBJECT Section; + PMM_SECTION_SEGMENT Segment; + ULONG Offset; + BOOLEAN WasDirty; + BOOLEAN Private; +} +MM_SECTION_PAGEOUT_CONTEXT; /* GLOBALS *******************************************************************/ POBJECT_TYPE EXPORTED MmSectionObjectType = NULL; 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}; + STANDARD_RIGHTS_READ | SECTION_MAP_READ | SECTION_QUERY, + STANDARD_RIGHTS_WRITE | SECTION_MAP_WRITE, + STANDARD_RIGHTS_EXECUTE | SECTION_MAP_EXECUTE, + SECTION_ALL_ACCESS}; #define TAG_MM_SECTION_SEGMENT TAG('M', 'M', 'S', 'S') #define TAG_SECTION_PAGE_TABLE TAG('M', 'S', 'P', 'T') @@ -89,13 +90,16 @@ static GENERIC_MAPPING MmpSectionMapping = { static NTSTATUS MmspWaitForPageOpCompletionEvent(PMM_PAGEOP PageOp) { - LARGE_INTEGER Timeout; + LARGE_INTEGER Timeout; #ifdef __GNUC__ /* TODO: Use other macro to check for suffix to use? */ - Timeout.QuadPart = -100000000LL; // 10 sec + + Timeout.QuadPart = -100000000LL; // 10 sec #else - Timeout.QuadPart = -100000000; // 10 sec + + Timeout.QuadPart = -100000000; // 10 sec #endif - return KeWaitForSingleObject(&PageOp->CompletionEvent, 0, KernelMode, FALSE, &Timeout); + + return KeWaitForSingleObject(&PageOp->CompletionEvent, 0, KernelMode, FALSE, &Timeout); } @@ -108,8 +112,8 @@ MmspWaitForPageOpCompletionEvent(PMM_PAGEOP PageOp) static void MmspCompleteAndReleasePageOp(PMM_PAGEOP PageOp) { - KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); - MmReleasePageOp(PageOp); + KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); + MmReleasePageOp(PageOp); } @@ -121,31 +125,31 @@ MmspCompleteAndReleasePageOp(PMM_PAGEOP PageOp) static NTSTATUS MmspWaitForFileLock(PFILE_OBJECT File) { - return KeWaitForSingleObject(&File->Lock, 0, KernelMode, FALSE, NULL); + return KeWaitForSingleObject(&File->Lock, 0, KernelMode, FALSE, NULL); } VOID MmFreePageTablesSectionSegment(PMM_SECTION_SEGMENT Segment) { - ULONG i; - if (Segment->Length > NR_SECTION_PAGE_TABLES * PAGE_SIZE) - { + ULONG i; + if (Segment->Length > NR_SECTION_PAGE_TABLES * PAGE_SIZE) + { for (i = 0; i < NR_SECTION_PAGE_TABLES; i++) - { - if (Segment->PageDirectory.PageTables[i] != NULL) - { - ExFreePool(Segment->PageDirectory.PageTables[i]); - } - } - } + { + if (Segment->PageDirectory.PageTables[i] != NULL) + { + ExFreePool(Segment->PageDirectory.PageTables[i]); + } + } + } } VOID MmFreeSectionSegments(PFILE_OBJECT FileObject) { - if (FileObject->SectionObjectPointer->ImageSectionObject != NULL) - { + if (FileObject->SectionObjectPointer->ImageSectionObject != NULL) + { PMM_IMAGE_SECTION_OBJECT ImageSectionObject; PMM_SECTION_SEGMENT SectionSegments; ULONG NrSegments; @@ -155,34 +159,34 @@ MmFreeSectionSegments(PFILE_OBJECT FileObject) NrSegments = ImageSectionObject->NrSegments; SectionSegments = ImageSectionObject->Segments; for (i = 0; i < NrSegments; i++) - { - if (SectionSegments[i].ReferenceCount != 0) - { - DPRINT1("Image segment %d still referenced (was %d)\n", i, - SectionSegments[i].ReferenceCount); - KEBUGCHECK(0); - } - MmFreePageTablesSectionSegment(&SectionSegments[i]); - } + { + if (SectionSegments[i].ReferenceCount != 0) + { + DPRINT1("Image segment %d still referenced (was %d)\n", i, + SectionSegments[i].ReferenceCount); + KEBUGCHECK(0); + } + MmFreePageTablesSectionSegment(&SectionSegments[i]); + } ExFreePool(ImageSectionObject); FileObject->SectionObjectPointer->ImageSectionObject = NULL; - } - if (FileObject->SectionObjectPointer->DataSectionObject != NULL) - { + } + if (FileObject->SectionObjectPointer->DataSectionObject != NULL) + { PMM_SECTION_SEGMENT Segment; Segment = (PMM_SECTION_SEGMENT)FileObject->SectionObjectPointer-> - DataSectionObject; + DataSectionObject; if (Segment->ReferenceCount != 0) - { - DPRINT1("Data segment still referenced\n"); - KEBUGCHECK(0); - } + { + DPRINT1("Data segment still referenced\n"); + KEBUGCHECK(0); + } MmFreePageTablesSectionSegment(Segment); ExFreePool(Segment); FileObject->SectionObjectPointer->DataSectionObject = NULL; - } + } } VOID @@ -199,35 +203,35 @@ MmUnlockSectionSegment(PMM_SECTION_SEGMENT Segment) VOID MmSetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment, - ULONG Offset, - ULONG Entry) + ULONG Offset, + ULONG Entry) { PSECTION_PAGE_TABLE Table; ULONG DirectoryOffset; ULONG TableOffset; if (Segment->Length <= NR_SECTION_PAGE_TABLES * PAGE_SIZE) - { - Table = (PSECTION_PAGE_TABLE)&Segment->PageDirectory; - } + { + Table = (PSECTION_PAGE_TABLE)&Segment->PageDirectory; + } else - { - DirectoryOffset = PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(Offset); - Table = Segment->PageDirectory.PageTables[DirectoryOffset]; - if (Table == NULL) + { + DirectoryOffset = PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(Offset); + Table = Segment->PageDirectory.PageTables[DirectoryOffset]; + if (Table == NULL) + { + Table = + Segment->PageDirectory.PageTables[DirectoryOffset] = + ExAllocatePoolWithTag(NonPagedPool, sizeof(SECTION_PAGE_TABLE), + TAG_SECTION_PAGE_TABLE); + if (Table == NULL) { - Table = - Segment->PageDirectory.PageTables[DirectoryOffset] = - ExAllocatePoolWithTag(NonPagedPool, sizeof(SECTION_PAGE_TABLE), - TAG_SECTION_PAGE_TABLE); - if (Table == NULL) - { - KEBUGCHECK(0); - } - memset(Table, 0, sizeof(SECTION_PAGE_TABLE)); - DPRINT("Table %x\n", Table); - } - } + KEBUGCHECK(0); + } + memset(Table, 0, sizeof(SECTION_PAGE_TABLE)); + DPRINT("Table %x\n", Table); + } + } TableOffset = PAGE_TO_SECTION_PAGE_TABLE_OFFSET(Offset); Table->Entry[TableOffset] = Entry; } @@ -235,7 +239,7 @@ MmSetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment, ULONG MmGetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment, - ULONG Offset) + ULONG Offset) { PSECTION_PAGE_TABLE Table; ULONG Entry; @@ -245,19 +249,19 @@ MmGetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment, DPRINT("MmGetPageEntrySection(Offset %x)\n", Offset); if (Segment->Length <= NR_SECTION_PAGE_TABLES * PAGE_SIZE) - { - Table = (PSECTION_PAGE_TABLE)&Segment->PageDirectory; - } + { + Table = (PSECTION_PAGE_TABLE)&Segment->PageDirectory; + } else - { - DirectoryOffset = PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(Offset); - Table = Segment->PageDirectory.PageTables[DirectoryOffset]; - DPRINT("Table %x\n", Table); - if (Table == NULL) - { - return(0); - } - } + { + DirectoryOffset = PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(Offset); + Table = Segment->PageDirectory.PageTables[DirectoryOffset]; + DPRINT("Table %x\n", Table); + if (Table == NULL) + { + return(0); + } + } TableOffset = PAGE_TO_SECTION_PAGE_TABLE_OFFSET(Offset); Entry = Table->Entry[TableOffset]; return(Entry); @@ -265,61 +269,61 @@ MmGetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment, VOID MmSharePageEntrySectionSegment(PMM_SECTION_SEGMENT Segment, - ULONG Offset) + ULONG Offset) { - ULONG Entry; + ULONG Entry; - Entry = MmGetPageEntrySectionSegment(Segment, Offset); - if (Entry == 0) - { + Entry = MmGetPageEntrySectionSegment(Segment, Offset); + if (Entry == 0) + { DPRINT1("Entry == 0 for MmSharePageEntrySectionSegment\n"); KEBUGCHECK(0); - } - if (SHARE_COUNT_FROM_SSE(Entry) == MAX_SHARE_COUNT) - { + } + if (SHARE_COUNT_FROM_SSE(Entry) == MAX_SHARE_COUNT) + { DPRINT1("Maximum share count reached\n"); KEBUGCHECK(0); - } - if (IS_SWAP_FROM_SSE(Entry)) - { + } + if (IS_SWAP_FROM_SSE(Entry)) + { KEBUGCHECK(0); - } - Entry = MAKE_SSE(PAGE_FROM_SSE(Entry), SHARE_COUNT_FROM_SSE(Entry) + 1); - MmSetPageEntrySectionSegment(Segment, Offset, Entry); + } + Entry = MAKE_SSE(PAGE_FROM_SSE(Entry), SHARE_COUNT_FROM_SSE(Entry) + 1); + MmSetPageEntrySectionSegment(Segment, Offset, Entry); } BOOLEAN MmUnsharePageEntrySectionSegment(PSECTION_OBJECT Section, - PMM_SECTION_SEGMENT Segment, - ULONG Offset, - BOOLEAN Dirty, - BOOLEAN PageOut) + PMM_SECTION_SEGMENT Segment, + ULONG Offset, + BOOLEAN Dirty, + BOOLEAN PageOut) { - ULONG Entry; - BOOLEAN IsDirectMapped = FALSE; + ULONG Entry; + BOOLEAN IsDirectMapped = FALSE; - Entry = MmGetPageEntrySectionSegment(Segment, Offset); - if (Entry == 0) - { + Entry = MmGetPageEntrySectionSegment(Segment, Offset); + if (Entry == 0) + { DPRINT1("Entry == 0 for MmUnsharePageEntrySectionSegment\n"); KEBUGCHECK(0); - } - if (SHARE_COUNT_FROM_SSE(Entry) == 0) - { + } + if (SHARE_COUNT_FROM_SSE(Entry) == 0) + { DPRINT1("Zero share count for unshare\n"); KEBUGCHECK(0); - } - if (IS_SWAP_FROM_SSE(Entry)) - { + } + if (IS_SWAP_FROM_SSE(Entry)) + { KEBUGCHECK(0); - } - 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) - { + } + 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; PBCB Bcb; SWAPENTRY SavedSwapEntry; @@ -334,154 +338,154 @@ MmUnsharePageEntrySectionSegment(PSECTION_OBJECT Section, Page.QuadPart = (LONGLONG)PAGE_FROM_SSE(Entry); FileObject = Section->FileObject; if (FileObject != NULL && - !(Segment->Characteristics & IMAGE_SECTION_CHAR_SHARED)) - { + !(Segment->Characteristics & IMAGE_SECTION_CHAR_SHARED)) + { - if ((FileOffset % PAGE_SIZE) == 0 && - (Offset + PAGE_SIZE <= Segment->RawLength || !IsImageSection)) - { - NTSTATUS Status; - Bcb = FileObject->SectionObjectPointer->SharedCacheMap; - IsDirectMapped = TRUE; - Status = CcRosUnmapCacheSegment(Bcb, FileOffset, Dirty); - if (!NT_SUCCESS(Status)) - { - DPRINT1("CcRosUnmapCacheSegment failed, status = %x\n", Status); - KEBUGCHECK(0); - } - } - } + if ((FileOffset % PAGE_SIZE) == 0 && + (Offset + PAGE_SIZE <= Segment->RawLength || !IsImageSection)) + { + NTSTATUS Status; + Bcb = FileObject->SectionObjectPointer->SharedCacheMap; + IsDirectMapped = TRUE; + Status = CcRosUnmapCacheSegment(Bcb, FileOffset, Dirty); + if (!NT_SUCCESS(Status)) + { + DPRINT1("CcRosUnmapCacheSegment failed, status = %x\n", Status); + KEBUGCHECK(0); + } + } + } SavedSwapEntry = MmGetSavedSwapEntryPage(Page); if (SavedSwapEntry == 0) - { - if (!PageOut && - ((Segment->Flags & MM_PAGEFILE_SEGMENT) || - (Segment->Characteristics & IMAGE_SECTION_CHAR_SHARED))) + { + if (!PageOut && + ((Segment->Flags & MM_PAGEFILE_SEGMENT) || + (Segment->Characteristics & IMAGE_SECTION_CHAR_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); + } + else + { + MmSetPageEntrySectionSegment(Segment, Offset, 0); + if (!IsDirectMapped) { - /* - * 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); - } - else - { - MmSetPageEntrySectionSegment(Segment, Offset, 0); - if (!IsDirectMapped) - { - MmReleasePageMemoryConsumer(MC_USER, Page); - } - } - } + MmReleasePageMemoryConsumer(MC_USER, Page); + } + } + } else - { - if ((Segment->Flags & MM_PAGEFILE_SEGMENT) || - (Segment->Characteristics & IMAGE_SECTION_CHAR_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; - PMDL Mdl; - Mdl = MmCreateMdl(NULL, NULL, PAGE_SIZE); - MmBuildMdlFromPages(Mdl, (PULONG)&Page); - Status = MmWriteToSwapPage(SavedSwapEntry, Mdl); - if (!NT_SUCCESS(Status)) - { - DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n", Status); - KEBUGCHECK(0); - } - } - MmSetPageEntrySectionSegment(Segment, Offset, MAKE_SWAP_SSE(SavedSwapEntry)); - MmSetSavedSwapEntryPage(Page, 0); - } - MmReleasePageMemoryConsumer(MC_USER, Page); - } - else - { - DPRINT1("Found a swapentry for a non private page in an image or data file sgment\n"); - KEBUGCHECK(0); - } - } - } - else - { + { + if ((Segment->Flags & MM_PAGEFILE_SEGMENT) || + (Segment->Characteristics & IMAGE_SECTION_CHAR_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; + PMDL Mdl; + Mdl = MmCreateMdl(NULL, NULL, PAGE_SIZE); + MmBuildMdlFromPages(Mdl, (PULONG)&Page); + Status = MmWriteToSwapPage(SavedSwapEntry, Mdl); + if (!NT_SUCCESS(Status)) + { + DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n", Status); + KEBUGCHECK(0); + } + } + MmSetPageEntrySectionSegment(Segment, Offset, MAKE_SWAP_SSE(SavedSwapEntry)); + MmSetSavedSwapEntryPage(Page, 0); + } + MmReleasePageMemoryConsumer(MC_USER, Page); + } + else + { + DPRINT1("Found a swapentry for a non private page in an image or data file sgment\n"); + KEBUGCHECK(0); + } + } + } + else + { MmSetPageEntrySectionSegment(Segment, Offset, Entry); - } - return(SHARE_COUNT_FROM_SSE(Entry) > 0); + } + return(SHARE_COUNT_FROM_SSE(Entry) > 0); } BOOL MiIsPageFromCache(PMEMORY_AREA MemoryArea, - ULONG SegOffset) + ULONG SegOffset) { - if (!(MemoryArea->Data.SectionData.Segment->Characteristics & IMAGE_SECTION_CHAR_SHARED)) - { + if (!(MemoryArea->Data.SectionData.Segment->Characteristics & IMAGE_SECTION_CHAR_SHARED)) + { PBCB Bcb; PCACHE_SEGMENT CacheSeg; Bcb = MemoryArea->Data.SectionData.Section->FileObject->SectionObjectPointer->SharedCacheMap; CacheSeg = CcRosLookupCacheSegment(Bcb, SegOffset + MemoryArea->Data.SectionData.Segment->FileOffset); if (CacheSeg) - { - CcRosReleaseCacheSegment(Bcb, CacheSeg, CacheSeg->Valid, FALSE, TRUE); - return TRUE; - } - } - return FALSE; + { + CcRosReleaseCacheSegment(Bcb, CacheSeg, CacheSeg->Valid, FALSE, TRUE); + return TRUE; + } + } + return FALSE; } NTSTATUS MiReadPage(PMEMORY_AREA MemoryArea, - ULONG SegOffset, - PHYSICAL_ADDRESS* Page) - /* - * FUNCTION: Read a page for a section backed memory area. - * PARAMETERS: - * MemoryArea - Memory area to read the page for. - * Offset - Offset of the page to read. - * Page - Variable that receives a page contains the read data. - */ + ULONG SegOffset, + PHYSICAL_ADDRESS* Page) +/* + * FUNCTION: Read a page for a section backed memory area. + * PARAMETERS: + * MemoryArea - Memory area to read the page for. + * Offset - Offset of the page to read. + * Page - Variable that receives a page contains the read data. + */ { - ULONG BaseOffset; - ULONG FileOffset; - PVOID BaseAddress; - BOOLEAN UptoDate; - PCACHE_SEGMENT CacheSeg; - PFILE_OBJECT FileObject; - NTSTATUS Status; - ULONG RawLength; - PBCB Bcb; - BOOLEAN IsImageSection; - ULONG Length; + ULONG BaseOffset; + ULONG FileOffset; + PVOID BaseAddress; + BOOLEAN UptoDate; + PCACHE_SEGMENT CacheSeg; + PFILE_OBJECT FileObject; + NTSTATUS Status; + ULONG RawLength; + PBCB Bcb; + BOOLEAN IsImageSection; + ULONG Length; - FileObject = MemoryArea->Data.SectionData.Section->FileObject; - Bcb = FileObject->SectionObjectPointer->SharedCacheMap; - RawLength = MemoryArea->Data.SectionData.Segment->RawLength; - FileOffset = SegOffset + MemoryArea->Data.SectionData.Segment->FileOffset; - IsImageSection = MemoryArea->Data.SectionData.Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE; + FileObject = MemoryArea->Data.SectionData.Section->FileObject; + Bcb = FileObject->SectionObjectPointer->SharedCacheMap; + RawLength = MemoryArea->Data.SectionData.Segment->RawLength; + FileOffset = SegOffset + MemoryArea->Data.SectionData.Segment->FileOffset; + IsImageSection = MemoryArea->Data.SectionData.Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE; - assert(Bcb); + assert(Bcb); - DPRINT("%S %x\n", FileObject->FileName.Buffer, FileOffset); + DPRINT("%S %x\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 cache segment. - */ - if ((FileOffset % PAGE_SIZE) == 0 && - (SegOffset + PAGE_SIZE <= RawLength || !IsImageSection) && - !(MemoryArea->Data.SectionData.Segment->Characteristics & IMAGE_SECTION_CHAR_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 cache segment. + */ + if ((FileOffset % PAGE_SIZE) == 0 && + (SegOffset + PAGE_SIZE <= RawLength || !IsImageSection) && + !(MemoryArea->Data.SectionData.Segment->Characteristics & IMAGE_SECTION_CHAR_SHARED)) + { /* * Get the related cache segment; we use a lower level interface than @@ -489,38 +493,38 @@ MiReadPage(PMEMORY_AREA MemoryArea, * alignment less than the file system block size. */ Status = CcRosGetCacheSegment(Bcb, - FileOffset, - &BaseOffset, - &BaseAddress, - &UptoDate, - &CacheSeg); + FileOffset, + &BaseOffset, + &BaseAddress, + &UptoDate, + &CacheSeg); if (!NT_SUCCESS(Status)) - { - return(Status); - } + { + return(Status); + } if (!UptoDate) - { - /* - * If the cache segment isn't up to date then call the file - * system to read in the data. - */ - Status = ReadCacheSegment(CacheSeg); - if (!NT_SUCCESS(Status)) - { - CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE); - return Status; - } - } + { + /* + * If the cache segment isn't up to date then call the file + * system to read in the data. + */ + Status = ReadCacheSegment(CacheSeg); + if (!NT_SUCCESS(Status)) + { + CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE); + return Status; + } + } /* * Retrieve the page from the cache segment that we actually want. */ (*Page) = MmGetPhysicalAddress((char*)BaseAddress + - FileOffset - BaseOffset); + FileOffset - BaseOffset); CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, TRUE); - } - else - { + } + else + { PVOID PageAddr; ULONG CacheSegOffset; /* @@ -529,32 +533,32 @@ MiReadPage(PMEMORY_AREA MemoryArea, */ Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, Page); if (!NT_SUCCESS(Status)) - { - return(Status); - } + { + return(Status); + } Status = CcRosGetCacheSegment(Bcb, - FileOffset, - &BaseOffset, - &BaseAddress, - &UptoDate, - &CacheSeg); + FileOffset, + &BaseOffset, + &BaseAddress, + &UptoDate, + &CacheSeg); if (!NT_SUCCESS(Status)) - { - return(Status); - } + { + return(Status); + } if (!UptoDate) - { - /* - * If the cache segment isn't up to date then call the file - * system to read in the data. - */ - Status = ReadCacheSegment(CacheSeg); - if (!NT_SUCCESS(Status)) - { - CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE); - return Status; - } - } + { + /* + * If the cache segment isn't up to date then call the file + * system to read in the data. + */ + Status = ReadCacheSegment(CacheSeg); + if (!NT_SUCCESS(Status)) + { + CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE); + return Status; + } + } PageAddr = ExAllocatePageWithPhysPage(*Page); CacheSegOffset = BaseOffset + CacheSeg->Bcb->CacheSegmentSize - FileOffset; Length = RawLength - SegOffset; @@ -568,53 +572,53 @@ MiReadPage(PMEMORY_AREA MemoryArea, } else { - memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, CacheSegOffset); + memcpy(PageAddr, (char*)BaseAddress + FileOffset - BaseOffset, CacheSegOffset); CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE); - Status = CcRosGetCacheSegment(Bcb, - FileOffset + CacheSegOffset, - &BaseOffset, - &BaseAddress, - &UptoDate, - &CacheSeg); + Status = CcRosGetCacheSegment(Bcb, + FileOffset + CacheSegOffset, + &BaseOffset, + &BaseAddress, + &UptoDate, + &CacheSeg); if (!NT_SUCCESS(Status)) - { - ExUnmapPage(PageAddr); - return(Status); - } + { + ExUnmapPage(PageAddr); + return(Status); + } if (!UptoDate) - { - /* - * If the cache segment isn't up to date then call the file - * system to read in the data. - */ - Status = ReadCacheSegment(CacheSeg); - if (!NT_SUCCESS(Status)) - { - CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE); - ExUnmapPage(PageAddr); - return Status; - } - } + { + /* + * If the cache segment isn't up to date then call the file + * system to read in the data. + */ + Status = ReadCacheSegment(CacheSeg); + if (!NT_SUCCESS(Status)) + { + CcRosReleaseCacheSegment(Bcb, CacheSeg, FALSE, FALSE, FALSE); + ExUnmapPage(PageAddr); + return Status; + } + } if (Length < PAGE_SIZE) - { - memcpy((char*)PageAddr + CacheSegOffset, BaseAddress, Length - CacheSegOffset); - } - else - { + { + memcpy((char*)PageAddr + CacheSegOffset, BaseAddress, Length - CacheSegOffset); + } + else + { memcpy((char*)PageAddr + CacheSegOffset, BaseAddress, PAGE_SIZE - CacheSegOffset); - } + } } CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE); ExUnmapPage(PageAddr); - } - return(STATUS_SUCCESS); + } + return(STATUS_SUCCESS); } NTSTATUS MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, - MEMORY_AREA* MemoryArea, - PVOID Address, - BOOLEAN Locked) + MEMORY_AREA* MemoryArea, + PVOID Address, + BOOLEAN Locked) { ULONG Offset; LARGE_INTEGER Page; @@ -635,13 +639,13 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, * that. */ if (MmIsPagePresent(AddressSpace->Process, Address)) - { - if (Locked) - { - MmLockPage(MmGetPhysicalAddressForProcess(AddressSpace->Process, Address)); - } - return(STATUS_SUCCESS); - } + { + if (Locked) + { + MmLockPage(MmGetPhysicalAddressForProcess(AddressSpace->Process, Address)); + } + return(STATUS_SUCCESS); + } PAddress = (ULONG)PAGE_ROUND_DOWN(((ULONG)Address)); Offset = PAddress - (ULONG)MemoryArea->BaseAddress; @@ -649,8 +653,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, Segment = MemoryArea->Data.SectionData.Segment; Section = MemoryArea->Data.SectionData.Section; Region = MmFindRegion(MemoryArea->BaseAddress, - &MemoryArea->Data.SectionData.RegionListHead, - Address, NULL); + &MemoryArea->Data.SectionData.RegionListHead, + Address, NULL); /* * Lock the segment */ @@ -660,311 +664,311 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, * Check if this page needs to be mapped COW */ if ((Segment->WriteCopy || MemoryArea->Data.SectionData.WriteCopyView) && - (Region->Protect == PAGE_READWRITE || - Region->Protect == PAGE_EXECUTE_READWRITE)) - { - Attributes = Region->Protect == PAGE_READWRITE ? PAGE_READONLY : PAGE_EXECUTE_READ; - } + (Region->Protect == PAGE_READWRITE || + Region->Protect == PAGE_EXECUTE_READWRITE)) + { + Attributes = Region->Protect == PAGE_READWRITE ? PAGE_READONLY : PAGE_EXECUTE_READ; + } else - { - Attributes = Region->Protect; - } + { + Attributes = Region->Protect; + } /* * Get or create a page operation descriptor */ PageOp = MmGetPageOp(MemoryArea, 0, 0, Segment, Offset, MM_PAGEOP_PAGEIN, FALSE); if (PageOp == NULL) - { - DPRINT1("MmGetPageOp failed\n"); - KEBUGCHECK(0); - } + { + DPRINT1("MmGetPageOp failed\n"); + KEBUGCHECK(0); + } /* * Check if someone else is already handling this fault, if so wait * for them */ if (PageOp->Thread != PsGetCurrentThread()) - { - MmUnlockSectionSegment(Segment); - MmUnlockAddressSpace(AddressSpace); - Status = MmspWaitForPageOpCompletionEvent(PageOp); - /* - * Check for various strange conditions - */ - if (Status != STATUS_SUCCESS) - { - DPRINT1("Failed to wait for page op, status = %x\n", Status); - KEBUGCHECK(0); - } - if (PageOp->Status == STATUS_PENDING) - { - DPRINT1("Woke for page op before completion\n"); - KEBUGCHECK(0); - } - MmLockAddressSpace(AddressSpace); - /* - * If this wasn't a pagein then restart the operation - */ - if (PageOp->OpType != MM_PAGEOP_PAGEIN) - { - MmspCompleteAndReleasePageOp(PageOp); - DPRINT("Address 0x%.8X\n", Address); - return(STATUS_MM_RESTART_OPERATION); - } + { + MmUnlockSectionSegment(Segment); + MmUnlockAddressSpace(AddressSpace); + Status = MmspWaitForPageOpCompletionEvent(PageOp); + /* + * Check for various strange conditions + */ + if (Status != STATUS_SUCCESS) + { + DPRINT1("Failed to wait for page op, status = %x\n", Status); + KEBUGCHECK(0); + } + if (PageOp->Status == STATUS_PENDING) + { + DPRINT1("Woke for page op before completion\n"); + KEBUGCHECK(0); + } + MmLockAddressSpace(AddressSpace); + /* + * If this wasn't a pagein then restart the operation + */ + if (PageOp->OpType != MM_PAGEOP_PAGEIN) + { + MmspCompleteAndReleasePageOp(PageOp); + DPRINT("Address 0x%.8X\n", Address); + return(STATUS_MM_RESTART_OPERATION); + } - /* - * If the thread handling this fault has failed then we don't retry - */ - if (!NT_SUCCESS(PageOp->Status)) - { - Status = PageOp->Status; - MmspCompleteAndReleasePageOp(PageOp); - DPRINT("Address 0x%.8X\n", Address); - return(Status); - } - MmLockSectionSegment(Segment); - /* - * If the completed fault was for another address space then set the - * page in this one. - */ - if (!MmIsPagePresent(AddressSpace->Process, Address)) - { - Entry = MmGetPageEntrySectionSegment(Segment, Offset); - HasSwapEntry = MmIsPageSwapEntry(AddressSpace->Process, (PVOID)PAddress); + /* + * If the thread handling this fault has failed then we don't retry + */ + if (!NT_SUCCESS(PageOp->Status)) + { + Status = PageOp->Status; + MmspCompleteAndReleasePageOp(PageOp); + DPRINT("Address 0x%.8X\n", Address); + return(Status); + } + MmLockSectionSegment(Segment); + /* + * If the completed fault was for another address space then set the + * page in this one. + */ + if (!MmIsPagePresent(AddressSpace->Process, Address)) + { + Entry = MmGetPageEntrySectionSegment(Segment, Offset); + HasSwapEntry = MmIsPageSwapEntry(AddressSpace->Process, (PVOID)PAddress); - if (PAGE_FROM_SSE(Entry) == 0 || HasSwapEntry) - { - /* - * The page was a private page in another or in our address space - */ - MmUnlockSectionSegment(Segment); - MmspCompleteAndReleasePageOp(PageOp); - return(STATUS_MM_RESTART_OPERATION); - } + if (PAGE_FROM_SSE(Entry) == 0 || HasSwapEntry) + { + /* + * The page was a private page in another or in our address space + */ + MmUnlockSectionSegment(Segment); + MmspCompleteAndReleasePageOp(PageOp); + return(STATUS_MM_RESTART_OPERATION); + } - Page.QuadPart = (LONGLONG)(PAGE_FROM_SSE(Entry)); + Page.QuadPart = (LONGLONG)(PAGE_FROM_SSE(Entry)); - MmSharePageEntrySectionSegment(Segment, Offset); + MmSharePageEntrySectionSegment(Segment, Offset); - Status = MmCreateVirtualMapping(MemoryArea->Process, - Address, - Attributes, - Page, - FALSE); - if (Status == STATUS_NO_MEMORY) - { - MmUnlockAddressSpace(AddressSpace); - Status = MmCreateVirtualMapping(MemoryArea->Process, - Address, - Attributes, - Page, - TRUE); - MmLockAddressSpace(AddressSpace); - } + Status = MmCreateVirtualMapping(MemoryArea->Process, + Address, + Attributes, + Page, + FALSE); + if (Status == STATUS_NO_MEMORY) + { + MmUnlockAddressSpace(AddressSpace); + Status = MmCreateVirtualMapping(MemoryArea->Process, + Address, + Attributes, + Page, + TRUE); + MmLockAddressSpace(AddressSpace); + } - if (!NT_SUCCESS(Status)) - { - DbgPrint("Unable to create virtual mapping\n"); - KEBUGCHECK(0); - } - MmInsertRmap(Page, MemoryArea->Process, (PVOID)PAddress); - } - if (Locked) - { - MmLockPage(Page); - } - MmUnlockSectionSegment(Segment); - PageOp->Status = STATUS_SUCCESS; - MmspCompleteAndReleasePageOp(PageOp); - DPRINT("Address 0x%.8X\n", Address); - return(STATUS_SUCCESS); - } + if (!NT_SUCCESS(Status)) + { + DbgPrint("Unable to create virtual mapping\n"); + KEBUGCHECK(0); + } + MmInsertRmap(Page, MemoryArea->Process, (PVOID)PAddress); + } + if (Locked) + { + MmLockPage(Page); + } + MmUnlockSectionSegment(Segment); + PageOp->Status = STATUS_SUCCESS; + MmspCompleteAndReleasePageOp(PageOp); + DPRINT("Address 0x%.8X\n", Address); + return(STATUS_SUCCESS); + } HasSwapEntry = MmIsPageSwapEntry(AddressSpace->Process, (PVOID)PAddress); if (HasSwapEntry) - { - /* - * Must be private page we have swapped out. - */ - SWAPENTRY SwapEntry; - PMDL Mdl; + { + /* + * Must be private page we have swapped out. + */ + SWAPENTRY SwapEntry; + PMDL Mdl; - /* - * Sanity check - */ - if (Segment->Flags & MM_PAGEFILE_SEGMENT) - { - DPRINT1("Found a swaped out private page in a pagefile section.\n"); - KEBUGCHECK(0); - } + /* + * Sanity check + */ + if (Segment->Flags & MM_PAGEFILE_SEGMENT) + { + DPRINT1("Found a swaped out private page in a pagefile section.\n"); + KEBUGCHECK(0); + } - MmUnlockSectionSegment(Segment); - MmDeletePageFileMapping(AddressSpace->Process, (PVOID)PAddress, &SwapEntry); + MmUnlockSectionSegment(Segment); + MmDeletePageFileMapping(AddressSpace->Process, (PVOID)PAddress, &SwapEntry); - MmUnlockAddressSpace(AddressSpace); - Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page); - if (!NT_SUCCESS(Status)) - { - KEBUGCHECK(0); - } + MmUnlockAddressSpace(AddressSpace); + Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page); + if (!NT_SUCCESS(Status)) + { + KEBUGCHECK(0); + } - Mdl = MmCreateMdl(NULL, NULL, PAGE_SIZE); - MmBuildMdlFromPages(Mdl, (PULONG)&Page); - Status = MmReadFromSwapPage(SwapEntry, Mdl); - if (!NT_SUCCESS(Status)) - { - DPRINT1("MmReadFromSwapPage failed, status = %x\n", Status); - KEBUGCHECK(0); - } - MmLockAddressSpace(AddressSpace); - Status = MmCreateVirtualMapping(AddressSpace->Process, - Address, - Region->Protect, - Page, - FALSE); - if (Status == STATUS_NO_MEMORY) - { - MmUnlockAddressSpace(AddressSpace); - Status = MmCreateVirtualMapping(AddressSpace->Process, - Address, - Region->Protect, - Page, - TRUE); - MmLockAddressSpace(AddressSpace); - } - if (!NT_SUCCESS(Status)) - { - DPRINT("MmCreateVirtualMapping failed, not out of memory\n"); - KEBUGCHECK(0); - return(Status); - } + Mdl = MmCreateMdl(NULL, NULL, PAGE_SIZE); + MmBuildMdlFromPages(Mdl, (PULONG)&Page); + Status = MmReadFromSwapPage(SwapEntry, Mdl); + if (!NT_SUCCESS(Status)) + { + DPRINT1("MmReadFromSwapPage failed, status = %x\n", Status); + KEBUGCHECK(0); + } + MmLockAddressSpace(AddressSpace); + Status = MmCreateVirtualMapping(AddressSpace->Process, + Address, + Region->Protect, + Page, + FALSE); + if (Status == STATUS_NO_MEMORY) + { + MmUnlockAddressSpace(AddressSpace); + Status = MmCreateVirtualMapping(AddressSpace->Process, + Address, + Region->Protect, + Page, + TRUE); + MmLockAddressSpace(AddressSpace); + } + if (!NT_SUCCESS(Status)) + { + DPRINT("MmCreateVirtualMapping failed, not out of memory\n"); + KEBUGCHECK(0); + 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, AddressSpace->Process, (PVOID)PAddress); + /* + * Add the page to the process's working set + */ + MmInsertRmap(Page, AddressSpace->Process, (PVOID)PAddress); - /* - * Finish the operation - */ - if (Locked) - { - MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address)); - } - PageOp->Status = STATUS_SUCCESS; - MmspCompleteAndReleasePageOp(PageOp); - DPRINT("Address 0x%.8X\n", Address); - return(STATUS_SUCCESS); - } + /* + * Finish the operation + */ + if (Locked) + { + MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address)); + } + PageOp->Status = STATUS_SUCCESS; + MmspCompleteAndReleasePageOp(PageOp); + DPRINT("Address 0x%.8X\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.QuadPart = Offset + MemoryArea->Data.SectionData.ViewOffset; - Status = MmCreateVirtualMapping(AddressSpace->Process, - Address, - Region->Protect, - Page, - FALSE); - if (Status == STATUS_NO_MEMORY) - { - MmUnlockAddressSpace(AddressSpace); - Status = MmCreateVirtualMapping(AddressSpace->Process, - Address, - Region->Protect, - Page, - TRUE); - MmLockAddressSpace(AddressSpace); - } - if (!NT_SUCCESS(Status)) - { - DPRINT("MmCreateVirtualMapping failed, not out of memory\n"); - KEBUGCHECK(0); - return(Status); - } - /* - * Don't add an rmap entry since the page mapped could be for - * anything. - */ - if (Locked) - { - MmLockPage(Page); - } + { + MmUnlockSectionSegment(Segment); + /* + * Just map the desired physical page + */ + Page.QuadPart = Offset + MemoryArea->Data.SectionData.ViewOffset; + Status = MmCreateVirtualMapping(AddressSpace->Process, + Address, + Region->Protect, + Page, + FALSE); + if (Status == STATUS_NO_MEMORY) + { + MmUnlockAddressSpace(AddressSpace); + Status = MmCreateVirtualMapping(AddressSpace->Process, + Address, + Region->Protect, + Page, + TRUE); + MmLockAddressSpace(AddressSpace); + } + if (!NT_SUCCESS(Status)) + { + DPRINT("MmCreateVirtualMapping failed, not out of memory\n"); + KEBUGCHECK(0); + return(Status); + } + /* + * Don't add an rmap entry since the page mapped could be for + * anything. + */ + if (Locked) + { + MmLockPage(Page); + } - /* - * Cleanup and release locks - */ - PageOp->Status = STATUS_SUCCESS; - MmspCompleteAndReleasePageOp(PageOp); - DPRINT("Address 0x%.8X\n", Address); - return(STATUS_SUCCESS); - } + /* + * Cleanup and release locks + */ + PageOp->Status = STATUS_SUCCESS; + MmspCompleteAndReleasePageOp(PageOp); + DPRINT("Address 0x%.8X\n", Address); + return(STATUS_SUCCESS); + } /* * Map anonymous memory for BSS sections */ if (Segment->Characteristics & IMAGE_SECTION_CHAR_BSS) - { - MmUnlockSectionSegment(Segment); - Status = MmRequestPageMemoryConsumer(MC_USER, FALSE, &Page); - if (!NT_SUCCESS(Status)) - { - MmUnlockAddressSpace(AddressSpace); - Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page); - MmLockAddressSpace(AddressSpace); - } - if (!NT_SUCCESS(Status)) - { - KEBUGCHECK(0); - } - Status = MmCreateVirtualMapping(AddressSpace->Process, - Address, - Region->Protect, - Page, - FALSE); - if (Status == STATUS_NO_MEMORY) - { - MmUnlockAddressSpace(AddressSpace); - Status = MmCreateVirtualMapping(AddressSpace->Process, - Address, - Region->Protect, - Page, - TRUE); - MmLockAddressSpace(AddressSpace); - } + { + MmUnlockSectionSegment(Segment); + Status = MmRequestPageMemoryConsumer(MC_USER, FALSE, &Page); + if (!NT_SUCCESS(Status)) + { + MmUnlockAddressSpace(AddressSpace); + Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page); + MmLockAddressSpace(AddressSpace); + } + if (!NT_SUCCESS(Status)) + { + KEBUGCHECK(0); + } + Status = MmCreateVirtualMapping(AddressSpace->Process, + Address, + Region->Protect, + Page, + FALSE); + if (Status == STATUS_NO_MEMORY) + { + MmUnlockAddressSpace(AddressSpace); + Status = MmCreateVirtualMapping(AddressSpace->Process, + Address, + Region->Protect, + Page, + TRUE); + MmLockAddressSpace(AddressSpace); + } - if (!NT_SUCCESS(Status)) - { - DPRINT("MmCreateVirtualMapping failed, not out of memory\n"); - KEBUGCHECK(0); - return(Status); - } - MmInsertRmap(Page, AddressSpace->Process, (PVOID)PAddress); - if (Locked) - { - MmLockPage(Page); - } + if (!NT_SUCCESS(Status)) + { + DPRINT("MmCreateVirtualMapping failed, not out of memory\n"); + KEBUGCHECK(0); + return(Status); + } + MmInsertRmap(Page, AddressSpace->Process, (PVOID)PAddress); + if (Locked) + { + MmLockPage(Page); + } - /* - * Cleanup and release locks - */ - PageOp->Status = STATUS_SUCCESS; - MmspCompleteAndReleasePageOp(PageOp); - DPRINT("Address 0x%.8X\n", Address); - return(STATUS_SUCCESS); - } + /* + * Cleanup and release locks + */ + PageOp->Status = STATUS_SUCCESS; + MmspCompleteAndReleasePageOp(PageOp); + DPRINT("Address 0x%.8X\n", Address); + return(STATUS_SUCCESS); + } /* * Get the entry corresponding to the offset within the section @@ -972,263 +976,263 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, Entry = MmGetPageEntrySectionSegment(Segment, Offset); if (Entry == 0) - { - /* - * 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 - */ - MmUnlockSectionSegment(Segment); - MmUnlockAddressSpace(AddressSpace); + /* + * Release all our locks and read in the page from disk + */ + MmUnlockSectionSegment(Segment); + MmUnlockAddressSpace(AddressSpace); - if ((Segment->Flags & MM_PAGEFILE_SEGMENT) || - (Offset >= PAGE_ROUND_UP(Segment->RawLength) && Section->AllocationAttributes & SEC_IMAGE)) - { - Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page); - if (!NT_SUCCESS(Status)) - { - DPRINT1("MmRequestPageMemoryConsumer failed (Status %x)\n", Status); - } - } - else + if ((Segment->Flags & MM_PAGEFILE_SEGMENT) || + (Offset >= PAGE_ROUND_UP(Segment->RawLength) && Section->AllocationAttributes & SEC_IMAGE)) + { + Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page); + if (!NT_SUCCESS(Status)) { - Status = MiReadPage(MemoryArea, Offset, &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); - PageOp->Status = Status; - MmspCompleteAndReleasePageOp(PageOp); - DPRINT("Address 0x%.8X\n", Address); - return(Status); - } - /* - * 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) - { - DbgPrint("Someone changed ppte entry while we slept\n"); - KEBUGCHECK(0); - } - - /* - * Mark the offset within the section as having valid, in-memory - * data - */ - Entry = MAKE_SSE(Page.u.LowPart, 1); - MmSetPageEntrySectionSegment(Segment, Offset, Entry); - MmUnlockSectionSegment(Segment); - - Status = MmCreateVirtualMapping(AddressSpace->Process, - Address, - Attributes, - Page, - FALSE); - if (Status == STATUS_NO_MEMORY) - { - MmUnlockAddressSpace(AddressSpace); - Status = MmCreateVirtualMapping(AddressSpace->Process, - Address, - Attributes, - Page, - TRUE); - MmLockAddressSpace(AddressSpace); + DPRINT1("MmRequestPageMemoryConsumer failed (Status %x)\n", Status); } - if (!NT_SUCCESS(Status)) + } + else + { + Status = MiReadPage(MemoryArea, Offset, &Page); + if (!NT_SUCCESS(Status)) { - DbgPrint("Unable to create virtual mapping\n"); - KEBUGCHECK(0); + DPRINT1("MiReadPage failed (Status %x)\n", Status); } - MmInsertRmap(Page, AddressSpace->Process, (PVOID)PAddress); + } + if (!NT_SUCCESS(Status)) + { + /* + * FIXME: What do we know in this case? + */ + /* + * Cleanup and release locks + */ + MmLockAddressSpace(AddressSpace); + PageOp->Status = Status; + MmspCompleteAndReleasePageOp(PageOp); + DPRINT("Address 0x%.8X\n", Address); + return(Status); + } + /* + * Relock the address space and segment + */ + MmLockAddressSpace(AddressSpace); + MmLockSectionSegment(Segment); - if (Locked) - { - MmLockPage(Page); - } - PageOp->Status = STATUS_SUCCESS; - MmspCompleteAndReleasePageOp(PageOp); - DPRINT("Address 0x%.8X\n", Address); - return(STATUS_SUCCESS); - } + /* + * 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) + { + DbgPrint("Someone changed ppte entry while we slept\n"); + KEBUGCHECK(0); + } + + /* + * Mark the offset within the section as having valid, in-memory + * data + */ + Entry = MAKE_SSE(Page.u.LowPart, 1); + MmSetPageEntrySectionSegment(Segment, Offset, Entry); + MmUnlockSectionSegment(Segment); + + Status = MmCreateVirtualMapping(AddressSpace->Process, + Address, + Attributes, + Page, + FALSE); + if (Status == STATUS_NO_MEMORY) + { + MmUnlockAddressSpace(AddressSpace); + Status = MmCreateVirtualMapping(AddressSpace->Process, + Address, + Attributes, + Page, + TRUE); + MmLockAddressSpace(AddressSpace); + } + if (!NT_SUCCESS(Status)) + { + DbgPrint("Unable to create virtual mapping\n"); + KEBUGCHECK(0); + } + MmInsertRmap(Page, AddressSpace->Process, (PVOID)PAddress); + + if (Locked) + { + MmLockPage(Page); + } + PageOp->Status = STATUS_SUCCESS; + MmspCompleteAndReleasePageOp(PageOp); + DPRINT("Address 0x%.8X\n", Address); + return(STATUS_SUCCESS); + } else if (IS_SWAP_FROM_SSE(Entry)) - { - SWAPENTRY SwapEntry; - PMDL Mdl; + { + SWAPENTRY SwapEntry; + PMDL Mdl; - 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); + MmUnlockAddressSpace(AddressSpace); - Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page); - if (!NT_SUCCESS(Status)) - { - KEBUGCHECK(0); - } + Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page); + if (!NT_SUCCESS(Status)) + { + KEBUGCHECK(0); + } - Mdl = MmCreateMdl(NULL, NULL, PAGE_SIZE); - MmBuildMdlFromPages(Mdl, (PULONG)&Page); - Status = MmReadFromSwapPage(SwapEntry, Mdl); - if (!NT_SUCCESS(Status)) - { - KEBUGCHECK(0); - } + Mdl = MmCreateMdl(NULL, NULL, PAGE_SIZE); + MmBuildMdlFromPages(Mdl, (PULONG)&Page); + Status = MmReadFromSwapPage(SwapEntry, Mdl); + if (!NT_SUCCESS(Status)) + { + KEBUGCHECK(0); + } - /* - * 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) - { - DbgPrint("Someone changed ppte entry while we slept\n"); - KEBUGCHECK(0); - } + /* + * 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) + { + DbgPrint("Someone changed ppte entry while we slept\n"); + KEBUGCHECK(0); + } - /* - * Mark the offset within the section as having valid, in-memory - * data - */ - Entry = MAKE_SSE(Page.u.LowPart, 1); - MmSetPageEntrySectionSegment(Segment, Offset, Entry); - MmUnlockSectionSegment(Segment); + /* + * Mark the offset within the section as having valid, in-memory + * data + */ + Entry = MAKE_SSE(Page.u.LowPart, 1); + MmSetPageEntrySectionSegment(Segment, Offset, Entry); + MmUnlockSectionSegment(Segment); - /* - * Save the swap entry. - */ - MmSetSavedSwapEntryPage(Page, SwapEntry); - Status = MmCreateVirtualMapping(AddressSpace->Process, - Address, - Region->Protect, - Page, - FALSE); - if (Status == STATUS_NO_MEMORY) - { - MmUnlockAddressSpace(AddressSpace); - Status = MmCreateVirtualMapping(AddressSpace->Process, - Address, - Region->Protect, - Page, - TRUE); - MmLockAddressSpace(AddressSpace); - } - if (!NT_SUCCESS(Status)) - { - DbgPrint("Unable to create virtual mapping\n"); - KEBUGCHECK(0); - } - MmInsertRmap(Page, AddressSpace->Process, (PVOID)PAddress); - if (Locked) - { - MmLockPage(Page); - } - PageOp->Status = STATUS_SUCCESS; - MmspCompleteAndReleasePageOp(PageOp); - DPRINT("Address 0x%.8X\n", Address); - return(STATUS_SUCCESS); - } + /* + * Save the swap entry. + */ + MmSetSavedSwapEntryPage(Page, SwapEntry); + Status = MmCreateVirtualMapping(AddressSpace->Process, + Address, + Region->Protect, + Page, + FALSE); + if (Status == STATUS_NO_MEMORY) + { + MmUnlockAddressSpace(AddressSpace); + Status = MmCreateVirtualMapping(AddressSpace->Process, + Address, + Region->Protect, + Page, + TRUE); + MmLockAddressSpace(AddressSpace); + } + if (!NT_SUCCESS(Status)) + { + DbgPrint("Unable to create virtual mapping\n"); + KEBUGCHECK(0); + } + MmInsertRmap(Page, AddressSpace->Process, (PVOID)PAddress); + if (Locked) + { + MmLockPage(Page); + } + PageOp->Status = STATUS_SUCCESS; + MmspCompleteAndReleasePageOp(PageOp); + DPRINT("Address 0x%.8X\n", Address); + return(STATUS_SUCCESS); + } else - { - /* - * If the section offset is already in-memory and valid then just - * take another reference to the page - */ + { + /* + * If the section offset is already in-memory and valid then just + * take another reference to the page + */ - Page.QuadPart = (LONGLONG)PAGE_FROM_SSE(Entry); + Page.QuadPart = (LONGLONG)PAGE_FROM_SSE(Entry); - MmSharePageEntrySectionSegment(Segment, Offset); - MmUnlockSectionSegment(Segment); + MmSharePageEntrySectionSegment(Segment, Offset); + MmUnlockSectionSegment(Segment); - Status = MmCreateVirtualMapping(AddressSpace->Process, - Address, - Attributes, - Page, - FALSE); - if (Status == STATUS_NO_MEMORY) - { - MmUnlockAddressSpace(AddressSpace); - Status = MmCreateVirtualMapping(AddressSpace->Process, - Address, - Attributes, - Page, - TRUE); - MmLockAddressSpace(AddressSpace); - } - if (!NT_SUCCESS(Status)) - { - DbgPrint("Unable to create virtual mapping\n"); - KEBUGCHECK(0); - } - MmInsertRmap(Page, AddressSpace->Process, (PVOID)PAddress); - if (Locked) - { - MmLockPage(Page); - } - PageOp->Status = STATUS_SUCCESS; - MmspCompleteAndReleasePageOp(PageOp); - DPRINT("Address 0x%.8X\n", Address); - return(STATUS_SUCCESS); - } + Status = MmCreateVirtualMapping(AddressSpace->Process, + Address, + Attributes, + Page, + FALSE); + if (Status == STATUS_NO_MEMORY) + { + MmUnlockAddressSpace(AddressSpace); + Status = MmCreateVirtualMapping(AddressSpace->Process, + Address, + Attributes, + Page, + TRUE); + MmLockAddressSpace(AddressSpace); + } + if (!NT_SUCCESS(Status)) + { + DbgPrint("Unable to create virtual mapping\n"); + KEBUGCHECK(0); + } + MmInsertRmap(Page, AddressSpace->Process, (PVOID)PAddress); + if (Locked) + { + MmLockPage(Page); + } + PageOp->Status = STATUS_SUCCESS; + MmspCompleteAndReleasePageOp(PageOp); + DPRINT("Address 0x%.8X\n", Address); + return(STATUS_SUCCESS); + } } NTSTATUS MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace, - MEMORY_AREA* MemoryArea, - PVOID Address, - BOOLEAN Locked) + MEMORY_AREA* MemoryArea, + PVOID Address, + BOOLEAN Locked) { - PMM_SECTION_SEGMENT Segment; - PSECTION_OBJECT Section; - PHYSICAL_ADDRESS OldPage; - PHYSICAL_ADDRESS NewPage; - PVOID NewAddress; - NTSTATUS Status; - ULONG PAddress; - ULONG Offset; - PMM_PAGEOP PageOp; - PMM_REGION Region; - ULONG Entry; + PMM_SECTION_SEGMENT Segment; + PSECTION_OBJECT Section; + PHYSICAL_ADDRESS OldPage; + PHYSICAL_ADDRESS NewPage; + PVOID NewAddress; + NTSTATUS Status; + ULONG PAddress; + ULONG Offset; + PMM_PAGEOP PageOp; + PMM_REGION Region; + ULONG Entry; - /* - * Check if the page has been paged out or has already been set readwrite - */ + /* + * Check if the page has been paged out or has already been set readwrite + */ if (!MmIsPagePresent(AddressSpace->Process, Address) || - MmGetPageProtect(AddressSpace->Process, Address) & PAGE_READWRITE) - { - DPRINT("Address 0x%.8X\n", Address); - return(STATUS_SUCCESS); - } + MmGetPageProtect(AddressSpace->Process, Address) & PAGE_READWRITE) + { + DPRINT("Address 0x%.8X\n", Address); + return(STATUS_SUCCESS); + } /* * Find the offset of the page @@ -1239,8 +1243,8 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace, Segment = MemoryArea->Data.SectionData.Segment; Section = MemoryArea->Data.SectionData.Section; Region = MmFindRegion(MemoryArea->BaseAddress, - &MemoryArea->Data.SectionData.RegionListHead, - Address, NULL); + &MemoryArea->Data.SectionData.RegionListHead, + Address, NULL); /* * Lock the segment */ @@ -1255,60 +1259,60 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace, * Check if we are doing COW */ if (!((Segment->WriteCopy || MemoryArea->Data.SectionData.WriteCopyView) && - (Region->Protect == PAGE_READWRITE || - Region->Protect == PAGE_EXECUTE_READWRITE))) - { - DPRINT("Address 0x%.8X\n", Address); - return(STATUS_UNSUCCESSFUL); - } + (Region->Protect == PAGE_READWRITE || + Region->Protect == PAGE_EXECUTE_READWRITE))) + { + DPRINT("Address 0x%.8X\n", Address); + return(STATUS_UNSUCCESSFUL); + } if (IS_SWAP_FROM_SSE(Entry) || - PAGE_FROM_SSE(Entry) != OldPage.u.LowPart) - { - /* This is a private page. We must only change the page protection. */ - MmSetPageProtect(AddressSpace->Process, (PVOID)PAddress, Region->Protect); - return(STATUS_SUCCESS); - } + PAGE_FROM_SSE(Entry) != OldPage.u.LowPart) + { + /* This is a private page. We must only change the page protection. */ + MmSetPageProtect(AddressSpace->Process, (PVOID)PAddress, Region->Protect); + return(STATUS_SUCCESS); + } /* * Get or create a pageop */ PageOp = MmGetPageOp(MemoryArea, 0, 0, Segment, Offset, - MM_PAGEOP_ACCESSFAULT, FALSE); + MM_PAGEOP_ACCESSFAULT, FALSE); if (PageOp == NULL) - { - DPRINT1("MmGetPageOp failed\n"); - KEBUGCHECK(0); - } + { + DPRINT1("MmGetPageOp failed\n"); + KEBUGCHECK(0); + } /* * Wait for any other operations to complete */ if (PageOp->Thread != PsGetCurrentThread()) - { - MmUnlockAddressSpace(AddressSpace); - Status = MmspWaitForPageOpCompletionEvent(PageOp); - /* - * Check for various strange conditions - */ - if (Status == STATUS_TIMEOUT) - { - DPRINT1("Failed to wait for page op, status = %x\n", Status); - KEBUGCHECK(0); - } - if (PageOp->Status == STATUS_PENDING) - { - DPRINT1("Woke for page op before completion\n"); - KEBUGCHECK(0); - } - /* - * Restart the operation - */ - MmLockAddressSpace(AddressSpace); - MmspCompleteAndReleasePageOp(PageOp); - DPRINT("Address 0x%.8X\n", Address); - return(STATUS_MM_RESTART_OPERATION); - } + { + MmUnlockAddressSpace(AddressSpace); + Status = MmspWaitForPageOpCompletionEvent(PageOp); + /* + * Check for various strange conditions + */ + if (Status == STATUS_TIMEOUT) + { + DPRINT1("Failed to wait for page op, status = %x\n", Status); + KEBUGCHECK(0); + } + if (PageOp->Status == STATUS_PENDING) + { + DPRINT1("Woke for page op before completion\n"); + KEBUGCHECK(0); + } + /* + * Restart the operation + */ + MmLockAddressSpace(AddressSpace); + MmspCompleteAndReleasePageOp(PageOp); + DPRINT("Address 0x%.8X\n", Address); + return(STATUS_MM_RESTART_OPERATION); + } /* * Release locks now we have the pageop @@ -1321,7 +1325,7 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace, Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &NewPage); if (!NT_SUCCESS(Status)) { - KEBUGCHECK(0); + KEBUGCHECK(0); } /* @@ -1342,37 +1346,37 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace, */ MmLockAddressSpace(AddressSpace); Status = MmCreateVirtualMapping(AddressSpace->Process, - Address, - Region->Protect, - NewPage, - FALSE); + Address, + Region->Protect, + NewPage, + FALSE); if (Status == STATUS_NO_MEMORY) - { - MmUnlockAddressSpace(AddressSpace); - Status = MmCreateVirtualMapping(AddressSpace->Process, - Address, - Region->Protect, - NewPage, - TRUE); - MmLockAddressSpace(AddressSpace); - } + { + MmUnlockAddressSpace(AddressSpace); + Status = MmCreateVirtualMapping(AddressSpace->Process, + Address, + Region->Protect, + NewPage, + TRUE); + MmLockAddressSpace(AddressSpace); + } if (!NT_SUCCESS(Status)) - { - DPRINT("MmCreateVirtualMapping failed, not out of memory\n"); - KEBUGCHECK(0); - return(Status); - } + { + DPRINT("MmCreateVirtualMapping failed, not out of memory\n"); + KEBUGCHECK(0); + return(Status); + } MmInsertRmap(NewPage, AddressSpace->Process, (PVOID)PAddress); if (!NT_SUCCESS(Status)) - { - DbgPrint("Unable to create virtual mapping\n"); - KEBUGCHECK(0); - } + { + DbgPrint("Unable to create virtual mapping\n"); + KEBUGCHECK(0); + } if (Locked) - { - MmLockPage(NewPage); - MmUnlockPage(OldPage); - } + { + MmLockPage(NewPage); + MmUnlockPage(OldPage); + } /* * Unshare the old page. @@ -1391,72 +1395,72 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace, VOID MmPageOutDeleteMapping(PVOID Context, PEPROCESS Process, PVOID Address) { - MM_SECTION_PAGEOUT_CONTEXT* PageOutContext; - BOOL WasDirty; - PHYSICAL_ADDRESS Page; + MM_SECTION_PAGEOUT_CONTEXT* PageOutContext; + BOOL WasDirty; + PHYSICAL_ADDRESS Page; - PageOutContext = (MM_SECTION_PAGEOUT_CONTEXT*)Context; - MmDeleteVirtualMapping(Process, - Address, - FALSE, - &WasDirty, - &Page); - if (WasDirty) - { + PageOutContext = (MM_SECTION_PAGEOUT_CONTEXT*)Context; + MmDeleteVirtualMapping(Process, + Address, + FALSE, + &WasDirty, + &Page); + if (WasDirty) + { PageOutContext->WasDirty = TRUE; - } - if (!PageOutContext->Private) - { + } + if (!PageOutContext->Private) + { MmUnsharePageEntrySectionSegment(PageOutContext->Section, - PageOutContext->Segment, - PageOutContext->Offset, - PageOutContext->WasDirty, - TRUE); - } - else - { + PageOutContext->Segment, + PageOutContext->Offset, + PageOutContext->WasDirty, + TRUE); + } + else + { MmReleasePageMemoryConsumer(MC_USER, Page); - } + } - DPRINT("PhysicalAddress %I64x, Address %x\n", Page, Address); + DPRINT("PhysicalAddress %I64x, Address %x\n", Page, Address); } NTSTATUS MmPageOutSectionView(PMADDRESS_SPACE AddressSpace, - MEMORY_AREA* MemoryArea, - PVOID Address, - PMM_PAGEOP PageOp) + MEMORY_AREA* MemoryArea, + PVOID Address, + PMM_PAGEOP PageOp) { - PHYSICAL_ADDRESS PhysicalAddress; - MM_SECTION_PAGEOUT_CONTEXT Context; - SWAPENTRY SwapEntry; - PMDL Mdl; - ULONG Entry; - ULONG FileOffset; - NTSTATUS Status; - PFILE_OBJECT FileObject; - PBCB Bcb = NULL; - BOOLEAN DirectMapped; - BOOLEAN IsImageSection; + PHYSICAL_ADDRESS PhysicalAddress; + MM_SECTION_PAGEOUT_CONTEXT Context; + SWAPENTRY SwapEntry; + PMDL Mdl; + ULONG Entry; + ULONG FileOffset; + NTSTATUS Status; + PFILE_OBJECT FileObject; + PBCB Bcb = NULL; + BOOLEAN DirectMapped; + BOOLEAN IsImageSection; - 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; + /* + * Get the segment and section. + */ + Context.Segment = MemoryArea->Data.SectionData.Segment; + Context.Section = MemoryArea->Data.SectionData.Section; - Context.Offset = (ULONG)((char*)Address - (ULONG)MemoryArea->BaseAddress); - FileOffset = Context.Offset + Context.Segment->FileOffset; + Context.Offset = (ULONG)((char*)Address - (ULONG)MemoryArea->BaseAddress); + FileOffset = Context.Offset + Context.Segment->FileOffset; - IsImageSection = Context.Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE; + IsImageSection = Context.Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE; - FileObject = Context.Section->FileObject; - DirectMapped = FALSE; - if (FileObject != NULL && - !(Context.Segment->Characteristics & IMAGE_SECTION_CHAR_SHARED)) - { + FileObject = Context.Section->FileObject; + DirectMapped = FALSE; + if (FileObject != NULL && + !(Context.Segment->Characteristics & IMAGE_SECTION_CHAR_SHARED)) + { Bcb = FileObject->SectionObjectPointer->SharedCacheMap; /* @@ -1465,346 +1469,346 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace, * then note this is a direct mapped page. */ if ((FileOffset % PAGE_SIZE) == 0 && - (Context.Offset + PAGE_SIZE <= Context.Segment->RawLength || !IsImageSection)) - { - DirectMapped = TRUE; - } - } + (Context.Offset + PAGE_SIZE <= Context.Segment->RawLength || !IsImageSection)) + { + DirectMapped = TRUE; + } + } - /* - * This should never happen since mappings of physical memory are never - * placed in the rmap lists. - */ - if (Context.Section->AllocationAttributes & SEC_PHYSICALMEMORY) - { + /* + * 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%X " - "process %d\n", Address, - AddressSpace->Process ? AddressSpace->Process->UniqueProcessId : 0); + "process %d\n", Address, + AddressSpace->Process ? AddressSpace->Process->UniqueProcessId : 0); KEBUGCHECK(0); - } + } - /* - * Get the section segment entry and the physical address. - */ - Entry = MmGetPageEntrySectionSegment(Context.Segment, Context.Offset); - if (!MmIsPagePresent(AddressSpace->Process, Address)) - { + /* + * Get the section segment entry and the physical address. + */ + Entry = MmGetPageEntrySectionSegment(Context.Segment, Context.Offset); + if (!MmIsPagePresent(AddressSpace->Process, Address)) + { DPRINT1("Trying to page out not-present page at (%d,0x%.8X).\n", - AddressSpace->Process ? AddressSpace->Process->UniqueProcessId : 0, Address); + AddressSpace->Process ? AddressSpace->Process->UniqueProcessId : 0, Address); KEBUGCHECK(0); - } - PhysicalAddress = - MmGetPhysicalAddressForProcess(AddressSpace->Process, Address); - SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress); + } + PhysicalAddress = + MmGetPhysicalAddressForProcess(AddressSpace->Process, Address); + SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress); - /* - * Prepare the context structure for the rmap delete call. - */ - Context.WasDirty = FALSE; - if (Context.Segment->Characteristics & IMAGE_SECTION_CHAR_BSS || - IS_SWAP_FROM_SSE(Entry) || - (LONGLONG)PAGE_FROM_SSE(Entry) != PhysicalAddress.QuadPart) - { + /* + * Prepare the context structure for the rmap delete call. + */ + Context.WasDirty = FALSE; + if (Context.Segment->Characteristics & IMAGE_SECTION_CHAR_BSS || + IS_SWAP_FROM_SSE(Entry) || + (LONGLONG)PAGE_FROM_SSE(Entry) != PhysicalAddress.QuadPart) + { Context.Private = TRUE; - } - else - { + } + else + { Context.Private = FALSE; - } + } - /* - * Take an additional reference to the page or the cache segment. - */ - if (DirectMapped && !Context.Private) - { + /* + * Take an additional reference to the page or the cache segment. + */ + if (DirectMapped && !Context.Private) + { if(!MiIsPageFromCache(MemoryArea, Context.Offset)) - { - DPRINT1("Direct mapped non private page is not associated with the cache.\n"); - KEBUGCHECK(0); - } - } - else - { + { + DPRINT1("Direct mapped non private page is not associated with the cache.\n"); + KEBUGCHECK(0); + } + } + else + { MmReferencePage(PhysicalAddress); - } + } - MmDeleteAllRmaps(PhysicalAddress, (PVOID)&Context, MmPageOutDeleteMapping); + MmDeleteAllRmaps(PhysicalAddress, (PVOID)&Context, MmPageOutDeleteMapping); - /* - * If this wasn't a private page then we should have reduced the entry to - * zero by deleting all the rmaps. - */ - if (!Context.Private && MmGetPageEntrySectionSegment(Context.Segment, Context.Offset) != 0) - { + /* + * If this wasn't a private page then we should have reduced the entry to + * zero by deleting all the rmaps. + */ + if (!Context.Private && MmGetPageEntrySectionSegment(Context.Segment, Context.Offset) != 0) + { if (!(Context.Segment->Flags & MM_PAGEFILE_SEGMENT) && - !(Context.Segment->Characteristics & IMAGE_SECTION_CHAR_SHARED)) - { - KEBUGCHECK(0); - } - } + !(Context.Segment->Characteristics & IMAGE_SECTION_CHAR_SHARED)) + { + KEBUGCHECK(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(PhysicalAddress); - if (Context.Segment->Flags & MM_PAGEFILE_SEGMENT) - { + /* + * 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(PhysicalAddress); + if (Context.Segment->Flags & MM_PAGEFILE_SEGMENT) + { if (Context.Private) - { - DPRINT1("Found a %s private page (address %x) in a pagefile segment.\n", - Context.WasDirty ? "dirty" : "clean", Address); - KEBUGCHECK(0); - } + { + DPRINT1("Found a %s private page (address %x) in a pagefile segment.\n", + Context.WasDirty ? "dirty" : "clean", Address); + KEBUGCHECK(0); + } if (!Context.WasDirty && SwapEntry != 0) - { - MmSetSavedSwapEntryPage(PhysicalAddress, 0); - MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, MAKE_SWAP_SSE(SwapEntry)); - MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress); - PageOp->Status = STATUS_SUCCESS; - MmspCompleteAndReleasePageOp(PageOp); - return(STATUS_SUCCESS); - } - } - else if (Context.Segment->Characteristics & IMAGE_SECTION_CHAR_SHARED) - { + { + MmSetSavedSwapEntryPage(PhysicalAddress, 0); + MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, MAKE_SWAP_SSE(SwapEntry)); + MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress); + PageOp->Status = STATUS_SUCCESS; + MmspCompleteAndReleasePageOp(PageOp); + return(STATUS_SUCCESS); + } + } + else if (Context.Segment->Characteristics & IMAGE_SECTION_CHAR_SHARED) + { if (Context.Private) - { - DPRINT1("Found a %s private page (address %x) in a shared section segment.\n", - Context.WasDirty ? "dirty" : "clean", Address); - KEBUGCHECK(0); - } + { + DPRINT1("Found a %s private page (address %x) in a shared section segment.\n", + Context.WasDirty ? "dirty" : "clean", Address); + KEBUGCHECK(0); + } if (!Context.WasDirty || SwapEntry != 0) - { - MmSetSavedSwapEntryPage(PhysicalAddress, 0); - if (SwapEntry != 0) - { - MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, MAKE_SWAP_SSE(SwapEntry)); - } - MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress); - PageOp->Status = STATUS_SUCCESS; - MmspCompleteAndReleasePageOp(PageOp); - return(STATUS_SUCCESS); - } - } - else if (!Context.Private && DirectMapped) - { + { + MmSetSavedSwapEntryPage(PhysicalAddress, 0); + if (SwapEntry != 0) + { + MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, MAKE_SWAP_SSE(SwapEntry)); + } + MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress); + PageOp->Status = STATUS_SUCCESS; + MmspCompleteAndReleasePageOp(PageOp); + return(STATUS_SUCCESS); + } + } + else if (!Context.Private && DirectMapped) + { if (SwapEntry != 0) - { - DPRINT1("Found a swapentry for a non private and direct mapped page (address %x)\n", - Address); - KEBUGCHECK(0); - } + { + DPRINT1("Found a swapentry for a non private and direct mapped page (address %x)\n", + Address); + KEBUGCHECK(0); + } Status = CcRosUnmapCacheSegment(Bcb, FileOffset, FALSE); if (!NT_SUCCESS(Status)) - { - DPRINT1("CCRosUnmapCacheSegment failed, status = %x\n", Status); - KEBUGCHECK(0); - } + { + DPRINT1("CCRosUnmapCacheSegment failed, status = %x\n", Status); + KEBUGCHECK(0); + } PageOp->Status = STATUS_SUCCESS; MmspCompleteAndReleasePageOp(PageOp); return(STATUS_SUCCESS); - } - else if (!Context.WasDirty && !DirectMapped && !Context.Private) - { + } + 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 %x)\n", - Address); - KEBUGCHECK(0); - } + { + DPRINT1("Found a swap entry for a non dirty, non private and not direct mapped page (address %x)\n", + Address); + KEBUGCHECK(0); + } MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress); PageOp->Status = STATUS_SUCCESS; MmspCompleteAndReleasePageOp(PageOp); return(STATUS_SUCCESS); - } - else if (!Context.WasDirty && Context.Private && SwapEntry != 0) - { + } + else if (!Context.WasDirty && Context.Private && SwapEntry != 0) + { MmSetSavedSwapEntryPage(PhysicalAddress, 0); Status = MmCreatePageFileMapping(AddressSpace->Process, - Address, - SwapEntry); + Address, + SwapEntry); if (!NT_SUCCESS(Status)) - { - KEBUGCHECK(0); - } + { + KEBUGCHECK(0); + } MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress); PageOp->Status = STATUS_SUCCESS; MmspCompleteAndReleasePageOp(PageOp); return(STATUS_SUCCESS); - } + } - /* - * If necessary, allocate an entry in the paging file for this page - */ - if (SwapEntry == 0) - { + /* + * If necessary, allocate an entry in the paging file for this page + */ + if (SwapEntry == 0) + { SwapEntry = MmAllocSwapPage(); if (SwapEntry == 0) - { - MmShowOutOfSpaceMessagePagingFile(); + { + MmShowOutOfSpaceMessagePagingFile(); - /* - * For private pages restore the old mappings. - */ - if (Context.Private) - { - Status = MmCreateVirtualMapping(MemoryArea->Process, - Address, - MemoryArea->Attributes, - PhysicalAddress, - FALSE); - MmSetDirtyPage(MemoryArea->Process, Address); - MmInsertRmap(PhysicalAddress, - MemoryArea->Process, - Address); - } - else - { - /* - * 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(MemoryArea->Process, - Address, - MemoryArea->Attributes, - PhysicalAddress, - FALSE); - MmSetDirtyPage(MemoryArea->Process, Address); - MmInsertRmap(PhysicalAddress, - MemoryArea->Process, - Address); - Entry = MAKE_SSE(PhysicalAddress.u.LowPart, 1); - MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry); - } - PageOp->Status = STATUS_UNSUCCESSFUL; - MmspCompleteAndReleasePageOp(PageOp); - return(STATUS_PAGEFILE_QUOTA); - } - } + /* + * For private pages restore the old mappings. + */ + if (Context.Private) + { + Status = MmCreateVirtualMapping(MemoryArea->Process, + Address, + MemoryArea->Attributes, + PhysicalAddress, + FALSE); + MmSetDirtyPage(MemoryArea->Process, Address); + MmInsertRmap(PhysicalAddress, + MemoryArea->Process, + Address); + } + else + { + /* + * 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(MemoryArea->Process, + Address, + MemoryArea->Attributes, + PhysicalAddress, + FALSE); + MmSetDirtyPage(MemoryArea->Process, Address); + MmInsertRmap(PhysicalAddress, + MemoryArea->Process, + Address); + Entry = MAKE_SSE(PhysicalAddress.u.LowPart, 1); + MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry); + } + PageOp->Status = STATUS_UNSUCCESSFUL; + MmspCompleteAndReleasePageOp(PageOp); + return(STATUS_PAGEFILE_QUOTA); + } + } - /* - * Write the page to the pagefile - */ - Mdl = MmCreateMdl(NULL, NULL, PAGE_SIZE); - MmBuildMdlFromPages(Mdl, (PULONG)&PhysicalAddress); - Status = MmWriteToSwapPage(SwapEntry, Mdl); - if (!NT_SUCCESS(Status)) - { + /* + * Write the page to the pagefile + */ + Mdl = MmCreateMdl(NULL, NULL, PAGE_SIZE); + MmBuildMdlFromPages(Mdl, (PULONG)&PhysicalAddress); + Status = MmWriteToSwapPage(SwapEntry, Mdl); + if (!NT_SUCCESS(Status)) + { DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n", - Status); + Status); /* * As above: undo our actions. * FIXME: Also free the swap page. */ if (Context.Private) - { - Status = MmCreateVirtualMapping(MemoryArea->Process, - Address, - MemoryArea->Attributes, - PhysicalAddress, - FALSE); - MmSetDirtyPage(MemoryArea->Process, Address); - MmInsertRmap(PhysicalAddress, - MemoryArea->Process, - Address); - } + { + Status = MmCreateVirtualMapping(MemoryArea->Process, + Address, + MemoryArea->Attributes, + PhysicalAddress, + FALSE); + MmSetDirtyPage(MemoryArea->Process, Address); + MmInsertRmap(PhysicalAddress, + MemoryArea->Process, + Address); + } else - { - Status = MmCreateVirtualMapping(MemoryArea->Process, - Address, - MemoryArea->Attributes, - PhysicalAddress, - FALSE); - MmSetDirtyPage(MemoryArea->Process, Address); - MmInsertRmap(PhysicalAddress, - MemoryArea->Process, - Address); - Entry = MAKE_SSE(PhysicalAddress.u.LowPart, 1); - MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry); - } + { + Status = MmCreateVirtualMapping(MemoryArea->Process, + Address, + MemoryArea->Attributes, + PhysicalAddress, + FALSE); + MmSetDirtyPage(MemoryArea->Process, Address); + MmInsertRmap(PhysicalAddress, + MemoryArea->Process, + Address); + Entry = MAKE_SSE(PhysicalAddress.u.LowPart, 1); + MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry); + } PageOp->Status = STATUS_UNSUCCESSFUL; MmspCompleteAndReleasePageOp(PageOp); return(STATUS_UNSUCCESSFUL); - } + } - /* - * Otherwise we have succeeded. - */ - DPRINT("MM: Wrote section page 0x%.8X to swap!\n", PhysicalAddress); - MmSetSavedSwapEntryPage(PhysicalAddress, 0); - if (Context.Segment->Flags & MM_PAGEFILE_SEGMENT || - Context.Segment->Characteristics & IMAGE_SECTION_CHAR_SHARED) - { + /* + * Otherwise we have succeeded. + */ + DPRINT("MM: Wrote section page 0x%.8X to swap!\n", PhysicalAddress); + MmSetSavedSwapEntryPage(PhysicalAddress, 0); + if (Context.Segment->Flags & MM_PAGEFILE_SEGMENT || + Context.Segment->Characteristics & IMAGE_SECTION_CHAR_SHARED) + { MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, MAKE_SWAP_SSE(SwapEntry)); - } - else - { + } + else + { MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress); - } + } - if (Context.Private) - { + if (Context.Private) + { Status = MmCreatePageFileMapping(MemoryArea->Process, - Address, - SwapEntry); + Address, + SwapEntry); if (!NT_SUCCESS(Status)) - { - KEBUGCHECK(0); - } - } - else - { + { + KEBUGCHECK(0); + } + } + else + { Entry = MAKE_SWAP_SSE(SwapEntry); MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry); - } + } - PageOp->Status = STATUS_SUCCESS; - MmspCompleteAndReleasePageOp(PageOp); - return(STATUS_SUCCESS); + PageOp->Status = STATUS_SUCCESS; + MmspCompleteAndReleasePageOp(PageOp); + return(STATUS_SUCCESS); } NTSTATUS MmWritePageSectionView(PMADDRESS_SPACE AddressSpace, - PMEMORY_AREA MemoryArea, - PVOID Address, - PMM_PAGEOP PageOp) + PMEMORY_AREA MemoryArea, + PVOID Address, + PMM_PAGEOP PageOp) { - ULONG Offset; - PSECTION_OBJECT Section; - PMM_SECTION_SEGMENT Segment; - PHYSICAL_ADDRESS PhysicalAddress; - SWAPENTRY SwapEntry; - PMDL Mdl; - ULONG Entry; - BOOLEAN Private; - NTSTATUS Status; - PFILE_OBJECT FileObject; - PBCB Bcb = NULL; - BOOLEAN DirectMapped; - BOOLEAN IsImageSection; + ULONG Offset; + PSECTION_OBJECT Section; + PMM_SECTION_SEGMENT Segment; + PHYSICAL_ADDRESS PhysicalAddress; + SWAPENTRY SwapEntry; + PMDL Mdl; + ULONG Entry; + BOOLEAN Private; + NTSTATUS Status; + PFILE_OBJECT FileObject; + PBCB Bcb = NULL; + BOOLEAN DirectMapped; + BOOLEAN IsImageSection; - Address = (PVOID)PAGE_ROUND_DOWN(Address); + Address = (PVOID)PAGE_ROUND_DOWN(Address); - Offset = (ULONG)((char*)Address - (ULONG)MemoryArea->BaseAddress); + Offset = (ULONG)((char*)Address - (ULONG)MemoryArea->BaseAddress); - /* - * 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->Characteristics & IMAGE_SECTION_CHAR_SHARED)) - { + FileObject = Section->FileObject; + DirectMapped = FALSE; + if (FileObject != NULL && + !(Segment->Characteristics & IMAGE_SECTION_CHAR_SHARED)) + { Bcb = FileObject->SectionObjectPointer->SharedCacheMap; /* @@ -1813,278 +1817,278 @@ MmWritePageSectionView(PMADDRESS_SPACE AddressSpace, * then note this is a direct mapped page. */ if ((Offset + MemoryArea->Data.SectionData.ViewOffset % PAGE_SIZE) == 0 && - (Offset + PAGE_SIZE <= Segment->RawLength || !IsImageSection)) - { - DirectMapped = TRUE; - } - } + (Offset + PAGE_SIZE <= Segment->RawLength || !IsImageSection)) + { + DirectMapped = TRUE; + } + } - /* - * This should never happen since mappings of physical memory are never - * placed in the rmap lists. - */ - if (Section->AllocationAttributes & SEC_PHYSICALMEMORY) - { + /* + * 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 %X " - "process %d\n", Address, - AddressSpace->Process ? AddressSpace->Process->UniqueProcessId : 0); + "process %d\n", Address, + AddressSpace->Process ? AddressSpace->Process->UniqueProcessId : 0); KEBUGCHECK(0); - } + } - /* - * Get the section segment entry and the physical address. - */ - Entry = MmGetPageEntrySectionSegment(Segment, Offset); - if (!MmIsPagePresent(AddressSpace->Process, Address)) - { + /* + * Get the section segment entry and the physical address. + */ + Entry = MmGetPageEntrySectionSegment(Segment, Offset); + if (!MmIsPagePresent(AddressSpace->Process, Address)) + { DPRINT1("Trying to page out not-present page at (%d,0x%.8X).\n", - AddressSpace->Process ? AddressSpace->Process->UniqueProcessId : 0, Address); + AddressSpace->Process ? AddressSpace->Process->UniqueProcessId : 0, Address); KEBUGCHECK(0); - } - PhysicalAddress = - MmGetPhysicalAddressForProcess(AddressSpace->Process, Address); - SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress); + } + PhysicalAddress = + MmGetPhysicalAddressForProcess(AddressSpace->Process, Address); + SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress); - /* - * Check for a private (COWed) page. - */ - if (Segment->Characteristics & IMAGE_SECTION_CHAR_BSS || - IS_SWAP_FROM_SSE(Entry) || - (LONGLONG)PAGE_FROM_SSE(Entry) != PhysicalAddress.QuadPart) - { + /* + * Check for a private (COWed) page. + */ + if (Segment->Characteristics & IMAGE_SECTION_CHAR_BSS || + IS_SWAP_FROM_SSE(Entry) || + (LONGLONG)PAGE_FROM_SSE(Entry) != PhysicalAddress.QuadPart) + { Private = TRUE; - } - else - { + } + else + { Private = FALSE; - } + } - /* - * Speculatively set all mappings of the page to clean. - */ - MmSetCleanAllRmaps(PhysicalAddress); + /* + * Speculatively set all mappings of the page to clean. + */ + MmSetCleanAllRmaps(PhysicalAddress); - /* - * 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) - { + /* + * 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) + { assert(SwapEntry == 0); CcRosMarkDirtyCacheSegment(Bcb, Offset + MemoryArea->Data.SectionData.ViewOffset); PageOp->Status = STATUS_SUCCESS; MmspCompleteAndReleasePageOp(PageOp); return(STATUS_SUCCESS); - } + } - /* - * If necessary, allocate an entry in the paging file for this page - */ - if (SwapEntry == 0) - { + /* + * If necessary, allocate an entry in the paging file for this page + */ + if (SwapEntry == 0) + { SwapEntry = MmAllocSwapPage(); if (SwapEntry == 0) - { - MmSetDirtyAllRmaps(PhysicalAddress); - PageOp->Status = STATUS_UNSUCCESSFUL; - MmspCompleteAndReleasePageOp(PageOp); - return(STATUS_PAGEFILE_QUOTA); - } + { + MmSetDirtyAllRmaps(PhysicalAddress); + PageOp->Status = STATUS_UNSUCCESSFUL; + MmspCompleteAndReleasePageOp(PageOp); + return(STATUS_PAGEFILE_QUOTA); + } MmSetSavedSwapEntryPage(PhysicalAddress, SwapEntry); - } + } - /* - * Write the page to the pagefile - */ - Mdl = MmCreateMdl(NULL, NULL, PAGE_SIZE); - MmBuildMdlFromPages(Mdl, (PULONG)&PhysicalAddress); - Status = MmWriteToSwapPage(SwapEntry, Mdl); - if (!NT_SUCCESS(Status)) - { + /* + * Write the page to the pagefile + */ + Mdl = MmCreateMdl(NULL, NULL, PAGE_SIZE); + MmBuildMdlFromPages(Mdl, (PULONG)&PhysicalAddress); + Status = MmWriteToSwapPage(SwapEntry, Mdl); + if (!NT_SUCCESS(Status)) + { DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n", - Status); + Status); MmSetDirtyAllRmaps(PhysicalAddress); PageOp->Status = STATUS_UNSUCCESSFUL; MmspCompleteAndReleasePageOp(PageOp); return(STATUS_UNSUCCESSFUL); - } + } - /* - * Otherwise we have succeeded. - */ - DPRINT("MM: Wrote section page 0x%.8X to swap!\n", PhysicalAddress); - PageOp->Status = STATUS_SUCCESS; - MmspCompleteAndReleasePageOp(PageOp); - return(STATUS_SUCCESS); + /* + * Otherwise we have succeeded. + */ + DPRINT("MM: Wrote section page 0x%.8X to swap!\n", PhysicalAddress); + PageOp->Status = STATUS_SUCCESS; + MmspCompleteAndReleasePageOp(PageOp); + return(STATUS_SUCCESS); } VOID STATIC MmAlterViewAttributes(PMADDRESS_SPACE AddressSpace, - PVOID BaseAddress, - ULONG RegionSize, - ULONG OldType, - ULONG OldProtect, - ULONG NewType, - ULONG NewProtect) + PVOID BaseAddress, + ULONG RegionSize, + ULONG OldType, + ULONG OldProtect, + ULONG NewType, + ULONG NewProtect) { - PMEMORY_AREA MemoryArea; - PMM_SECTION_SEGMENT Segment; - BOOL DoCOW = FALSE; - ULONG i; + PMEMORY_AREA MemoryArea; + PMM_SECTION_SEGMENT Segment; + BOOL DoCOW = FALSE; + ULONG i; - MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, BaseAddress); - Segment = MemoryArea->Data.SectionData.Segment; + MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, BaseAddress); + Segment = MemoryArea->Data.SectionData.Segment; - if ((Segment->WriteCopy || MemoryArea->Data.SectionData.WriteCopyView) && - (NewProtect == PAGE_READWRITE || NewProtect == PAGE_EXECUTE_READWRITE)) - { - DoCOW = TRUE; - } + if ((Segment->WriteCopy || MemoryArea->Data.SectionData.WriteCopyView) && + (NewProtect == PAGE_READWRITE || NewProtect == PAGE_EXECUTE_READWRITE)) + { + DoCOW = TRUE; + } - if (OldProtect != NewProtect) - { + if (OldProtect != NewProtect) + { for (i = 0; i < PAGE_ROUND_UP(RegionSize) / PAGE_SIZE; i++) - { - PVOID Address = (char*)BaseAddress + (i * PAGE_SIZE); - ULONG Protect = NewProtect; + { + PVOID Address = (char*)BaseAddress + (i * PAGE_SIZE); + ULONG Protect = NewProtect; - /* - * If we doing COW for this segment then check if the page is - * already private. - */ - if (DoCOW && MmIsPagePresent(AddressSpace->Process, Address)) - { - ULONG Offset; - ULONG Entry; - LARGE_INTEGER PhysicalAddress; + /* + * If we doing COW for this segment then check if the page is + * already private. + */ + if (DoCOW && MmIsPagePresent(AddressSpace->Process, Address)) + { + ULONG Offset; + ULONG Entry; + LARGE_INTEGER PhysicalAddress; - Offset = (ULONG)Address - (ULONG)MemoryArea->BaseAddress; - Entry = MmGetPageEntrySectionSegment(Segment, Offset); - PhysicalAddress = - MmGetPhysicalAddressForProcess(AddressSpace->Process, Address); + Offset = (ULONG)Address - (ULONG)MemoryArea->BaseAddress; + Entry = MmGetPageEntrySectionSegment(Segment, Offset); + PhysicalAddress = + MmGetPhysicalAddressForProcess(AddressSpace->Process, Address); - Protect = PAGE_READONLY; - if ((Segment->Characteristics & IMAGE_SECTION_CHAR_BSS || - IS_SWAP_FROM_SSE(Entry) || - (LONGLONG)PAGE_FROM_SSE(Entry) != PhysicalAddress.QuadPart)) - { - Protect = NewProtect; - } - } + Protect = PAGE_READONLY; + if ((Segment->Characteristics & IMAGE_SECTION_CHAR_BSS || + IS_SWAP_FROM_SSE(Entry) || + (LONGLONG)PAGE_FROM_SSE(Entry) != PhysicalAddress.QuadPart)) + { + Protect = NewProtect; + } + } - if (MmIsPagePresent(AddressSpace->Process, Address)) - { - MmSetPageProtect(AddressSpace->Process, BaseAddress, - Protect); - } - } - } + if (MmIsPagePresent(AddressSpace->Process, Address)) + { + MmSetPageProtect(AddressSpace->Process, BaseAddress, + Protect); + } + } + } } NTSTATUS MmProtectSectionView(PMADDRESS_SPACE AddressSpace, - PMEMORY_AREA MemoryArea, - PVOID BaseAddress, - ULONG Length, - ULONG Protect, - PULONG OldProtect) + PMEMORY_AREA MemoryArea, + PVOID BaseAddress, + ULONG Length, + ULONG Protect, + PULONG OldProtect) { - PMM_REGION Region; - NTSTATUS Status; + PMM_REGION Region; + NTSTATUS Status; - Length = - min(Length, (ULONG) ((char*)MemoryArea->BaseAddress + MemoryArea->Length - (char*)BaseAddress)); - Region = MmFindRegion(MemoryArea->BaseAddress, - &MemoryArea->Data.SectionData.RegionListHead, - BaseAddress, NULL); - *OldProtect = Region->Protect; - Status = MmAlterRegion(AddressSpace, MemoryArea->BaseAddress, - &MemoryArea->Data.SectionData.RegionListHead, - BaseAddress, Length, Region->Type, Protect, - MmAlterViewAttributes); + Length = + min(Length, (ULONG) ((char*)MemoryArea->BaseAddress + MemoryArea->Length - (char*)BaseAddress)); + Region = MmFindRegion(MemoryArea->BaseAddress, + &MemoryArea->Data.SectionData.RegionListHead, + BaseAddress, NULL); + *OldProtect = Region->Protect; + Status = MmAlterRegion(AddressSpace, MemoryArea->BaseAddress, + &MemoryArea->Data.SectionData.RegionListHead, + BaseAddress, Length, Region->Type, Protect, + MmAlterViewAttributes); - return(Status); + return(Status); } NTSTATUS STDCALL MmQuerySectionView(PMEMORY_AREA MemoryArea, - PVOID Address, - PMEMORY_BASIC_INFORMATION Info, - PULONG ResultLength) + PVOID Address, + PMEMORY_BASIC_INFORMATION Info, + PULONG ResultLength) { - PMM_REGION Region; - PVOID RegionBaseAddress; + PMM_REGION Region; + PVOID RegionBaseAddress; - Region = MmFindRegion(MemoryArea->BaseAddress, - &MemoryArea->Data.SectionData.RegionListHead, - Address, &RegionBaseAddress); - if (Region == NULL) - { + Region = MmFindRegion(MemoryArea->BaseAddress, + &MemoryArea->Data.SectionData.RegionListHead, + Address, &RegionBaseAddress); + if (Region == NULL) + { return STATUS_UNSUCCESSFUL; - } - Info->BaseAddress = (PVOID)PAGE_ROUND_DOWN(Address); - Info->AllocationBase = MemoryArea->BaseAddress; - Info->AllocationProtect = MemoryArea->Attributes; - Info->RegionSize = MemoryArea->Length; - Info->State = MEM_COMMIT; - Info->Protect = Region->Protect; - if (MemoryArea->Data.SectionData.Section->AllocationAttributes & SEC_IMAGE) - { + } + Info->BaseAddress = (PVOID)PAGE_ROUND_DOWN(Address); + Info->AllocationBase = MemoryArea->BaseAddress; + Info->AllocationProtect = MemoryArea->Attributes; + Info->RegionSize = MemoryArea->Length; + Info->State = MEM_COMMIT; + Info->Protect = Region->Protect; + if (MemoryArea->Data.SectionData.Section->AllocationAttributes & SEC_IMAGE) + { Info->Type = MEM_IMAGE; - } - else - { + } + else + { Info->Type = MEM_MAPPED; - } + } - return(STATUS_SUCCESS); + return(STATUS_SUCCESS); } VOID MmpFreePageFileSegment(PMM_SECTION_SEGMENT Segment) { - ULONG Length; - ULONG Offset; - ULONG Entry; - ULONG SavedSwapEntry; - PHYSICAL_ADDRESS Page; + ULONG Length; + ULONG Offset; + ULONG Entry; + ULONG SavedSwapEntry; + PHYSICAL_ADDRESS Page; - Page.u.HighPart = 0; + Page.u.HighPart = 0; - Length = PAGE_ROUND_UP(Segment->Length); - for (Offset = 0; Offset < Length; Offset += PAGE_SIZE) - { + Length = PAGE_ROUND_UP(Segment->Length); + for (Offset = 0; Offset < Length; Offset += PAGE_SIZE) + { Entry = MmGetPageEntrySectionSegment(Segment, Offset); if (Entry) - { - if (IS_SWAP_FROM_SSE(Entry)) + { + if (IS_SWAP_FROM_SSE(Entry)) + { + MmFreeSwapPage(SWAPENTRY_FROM_SSE(Entry)); + } + else + { + Page.u.LowPart = PAGE_FROM_SSE(Entry); + SavedSwapEntry = MmGetSavedSwapEntryPage(Page); + if (SavedSwapEntry != 0) { - MmFreeSwapPage(SWAPENTRY_FROM_SSE(Entry)); + MmSetSavedSwapEntryPage(Page, 0); + MmFreeSwapPage(SavedSwapEntry); } - else - { - Page.u.LowPart = PAGE_FROM_SSE(Entry); - SavedSwapEntry = MmGetSavedSwapEntryPage(Page); - if (SavedSwapEntry != 0) - { - MmSetSavedSwapEntryPage(Page, 0); - MmFreeSwapPage(SavedSwapEntry); - } - MmReleasePageMemoryConsumer(MC_USER, Page); - } - MmSetPageEntrySectionSegment(Segment, Offset, 0); - } - } + MmReleasePageMemoryConsumer(MC_USER, Page); + } + MmSetPageEntrySectionSegment(Segment, Offset, 0); + } + } } - + VOID STDCALL MmpDeleteSection(PVOID ObjectBody) { - PSECTION_OBJECT Section = (PSECTION_OBJECT)ObjectBody; + PSECTION_OBJECT Section = (PSECTION_OBJECT)ObjectBody; - DPRINT("MmpDeleteSection(ObjectBody %x)\n", ObjectBody); - if (Section->AllocationAttributes & SEC_IMAGE) - { + DPRINT("MmpDeleteSection(ObjectBody %x)\n", ObjectBody); + if (Section->AllocationAttributes & SEC_IMAGE) + { ULONG i; ULONG NrSegments; ULONG RefCount; @@ -2094,119 +2098,119 @@ MmpDeleteSection(PVOID ObjectBody) NrSegments = Section->ImageSection->NrSegments; for (i = 0; i < NrSegments; i++) - { - if (SectionSegments[i].Characteristics & IMAGE_SECTION_CHAR_SHARED) - { - MmLockSectionSegment(&SectionSegments[i]); - } - RefCount = InterlockedDecrement((LONG *)&SectionSegments[i].ReferenceCount); - if (SectionSegments[i].Characteristics & IMAGE_SECTION_CHAR_SHARED) - { - if (RefCount == 0) - { - MmpFreePageFileSegment(&SectionSegments[i]); - } - MmUnlockSectionSegment(&SectionSegments[i]); - } - } - } - else - { + { + if (SectionSegments[i].Characteristics & IMAGE_SECTION_CHAR_SHARED) + { + MmLockSectionSegment(&SectionSegments[i]); + } + RefCount = InterlockedDecrement((LONG *)&SectionSegments[i].ReferenceCount); + if (SectionSegments[i].Characteristics & IMAGE_SECTION_CHAR_SHARED) + { + if (RefCount == 0) + { + MmpFreePageFileSegment(&SectionSegments[i]); + } + MmUnlockSectionSegment(&SectionSegments[i]); + } + } + } + else + { if (Section->Segment->Flags & MM_PAGEFILE_SEGMENT) - { - MmpFreePageFileSegment(Section->Segment); - MmFreePageTablesSectionSegment(Section->Segment); - ExFreePool(Section->Segment); - Section->Segment = NULL; - } + { + MmpFreePageFileSegment(Section->Segment); + MmFreePageTablesSectionSegment(Section->Segment); + ExFreePool(Section->Segment); + Section->Segment = NULL; + } else - { - InterlockedDecrement((LONG *)&Section->Segment->ReferenceCount); - } - } - if (Section->FileObject != NULL) - { + { + InterlockedDecrement((LONG *)&Section->Segment->ReferenceCount); + } + } + if (Section->FileObject != NULL) + { CcRosDereferenceCache(Section->FileObject); ObDereferenceObject(Section->FileObject); Section->FileObject = NULL; - } + } } VOID STDCALL MmpCloseSection(PVOID ObjectBody, - ULONG HandleCount) + ULONG HandleCount) { DPRINT("MmpCloseSection(OB %x, HC %d) RC %d\n", - ObjectBody, HandleCount, ObGetObjectPointerCount(ObjectBody)); + ObjectBody, HandleCount, ObGetObjectPointerCount(ObjectBody)); } NTSTATUS STDCALL MmpCreateSection(PVOID ObjectBody, - PVOID Parent, - PWSTR RemainingPath, - POBJECT_ATTRIBUTES ObjectAttributes) + PVOID Parent, + PWSTR RemainingPath, + POBJECT_ATTRIBUTES ObjectAttributes) { DPRINT("MmpCreateSection(ObjectBody %x, Parent %x, RemainingPath %S)\n", - ObjectBody, Parent, RemainingPath); + ObjectBody, Parent, RemainingPath); if (RemainingPath == NULL) - { - return(STATUS_SUCCESS); - } + { + return(STATUS_SUCCESS); + } if (wcschr(RemainingPath+1, L'\\') != NULL) - { - return(STATUS_UNSUCCESSFUL); - } + { + return(STATUS_UNSUCCESSFUL); + } return(STATUS_SUCCESS); } NTSTATUS INIT_FUNCTION MmCreatePhysicalMemorySection(VOID) { - HANDLE PhysSectionH; - PSECTION_OBJECT PhysSection; - NTSTATUS Status; - OBJECT_ATTRIBUTES Obj; - UNICODE_STRING Name = ROS_STRING_INITIALIZER(L"\\Device\\PhysicalMemory"); - LARGE_INTEGER SectionSize; + HANDLE PhysSectionH; + PSECTION_OBJECT PhysSection; + NTSTATUS Status; + OBJECT_ATTRIBUTES Obj; + UNICODE_STRING Name = ROS_STRING_INITIALIZER(L"\\Device\\PhysicalMemory"); + LARGE_INTEGER SectionSize; - /* - * Create the section mapping physical memory - */ - SectionSize.QuadPart = 0xFFFFFFFF; - InitializeObjectAttributes(&Obj, - &Name, - 0, - NULL, - NULL); - Status = NtCreateSection(&PhysSectionH, - SECTION_ALL_ACCESS, - &Obj, - &SectionSize, - PAGE_EXECUTE_READWRITE, - 0, - NULL); - if (!NT_SUCCESS(Status)) - { + /* + * Create the section mapping physical memory + */ + SectionSize.QuadPart = 0xFFFFFFFF; + InitializeObjectAttributes(&Obj, + &Name, + 0, + NULL, + NULL); + Status = NtCreateSection(&PhysSectionH, + SECTION_ALL_ACCESS, + &Obj, + &SectionSize, + PAGE_EXECUTE_READWRITE, + 0, + NULL); + if (!NT_SUCCESS(Status)) + { DbgPrint("Failed to create PhysicalMemory section\n"); KEBUGCHECK(0); - } - Status = ObReferenceObjectByHandle(PhysSectionH, - SECTION_ALL_ACCESS, - NULL, - KernelMode, - (PVOID*)&PhysSection, - NULL); - if (!NT_SUCCESS(Status)) - { + } + Status = ObReferenceObjectByHandle(PhysSectionH, + SECTION_ALL_ACCESS, + NULL, + KernelMode, + (PVOID*)&PhysSection, + NULL); + if (!NT_SUCCESS(Status)) + { DbgPrint("Failed to reference PhysicalMemory section\n"); KEBUGCHECK(0); - } - PhysSection->AllocationAttributes |= SEC_PHYSICALMEMORY; - ObDereferenceObject((PVOID)PhysSection); + } + PhysSection->AllocationAttributes |= SEC_PHYSICALMEMORY; + ObDereferenceObject((PVOID)PhysSection); - return(STATUS_SUCCESS); + return(STATUS_SUCCESS); } NTSTATUS INIT_FUNCTION @@ -2247,241 +2251,241 @@ MmInitSectionImplementation(VOID) NTSTATUS MmCreatePageFileSection(PHANDLE SectionHandle, - ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes, - PLARGE_INTEGER UMaximumSize, - ULONG SectionPageProtection, - ULONG AllocationAttributes) - /* - * Create a section which is backed by the pagefile - */ + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes, + PLARGE_INTEGER UMaximumSize, + ULONG SectionPageProtection, + ULONG AllocationAttributes) +/* + * Create a section which is backed by the pagefile + */ { - LARGE_INTEGER MaximumSize; - PSECTION_OBJECT Section; - PMM_SECTION_SEGMENT Segment; - NTSTATUS Status; + LARGE_INTEGER MaximumSize; + PSECTION_OBJECT Section; + PMM_SECTION_SEGMENT Segment; + NTSTATUS Status; - if (UMaximumSize == NULL) - { + if (UMaximumSize == NULL) + { return(STATUS_UNSUCCESSFUL); - } - MaximumSize = *UMaximumSize; + } + MaximumSize = *UMaximumSize; - /* - * Check the protection - */ - if ((SectionPageProtection & PAGE_FLAGS_VALID_FROM_USER_MODE) != - SectionPageProtection) - { + /* + * Check the protection + */ + if ((SectionPageProtection & PAGE_FLAGS_VALID_FROM_USER_MODE) != + SectionPageProtection) + { return(STATUS_INVALID_PAGE_PROTECTION); - } + } - /* - * Create the section - */ - Status = ObCreateObject(ExGetPreviousMode(), - MmSectionObjectType, - ObjectAttributes, - ExGetPreviousMode(), - NULL, - sizeof(SECTION_OBJECT), - 0, - 0, - (PVOID*)&Section); - if (!NT_SUCCESS(Status)) - { + /* + * Create the section + */ + Status = ObCreateObject(ExGetPreviousMode(), + MmSectionObjectType, + ObjectAttributes, + ExGetPreviousMode(), + NULL, + sizeof(SECTION_OBJECT), + 0, + 0, + (PVOID*)&Section); + if (!NT_SUCCESS(Status)) + { return(Status); - } + } - Status = ObInsertObject ((PVOID)Section, - NULL, - DesiredAccess, - 0, - NULL, - SectionHandle); - if (!NT_SUCCESS(Status)) - { + Status = ObInsertObject ((PVOID)Section, + NULL, + DesiredAccess, + 0, + NULL, + SectionHandle); + if (!NT_SUCCESS(Status)) + { ObDereferenceObject(Section); return(Status); - } + } - /* - * Initialize it - */ - Section->SectionPageProtection = SectionPageProtection; - Section->AllocationAttributes = AllocationAttributes; - InitializeListHead(&Section->ViewListHead); - KeInitializeSpinLock(&Section->ViewListLock); - Section->FileObject = NULL; - Section->MaximumSize = MaximumSize; - Segment = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_SECTION_SEGMENT), - TAG_MM_SECTION_SEGMENT); - if (Segment == NULL) - { + /* + * Initialize it + */ + Section->SectionPageProtection = SectionPageProtection; + Section->AllocationAttributes = AllocationAttributes; + InitializeListHead(&Section->ViewListHead); + KeInitializeSpinLock(&Section->ViewListLock); + Section->FileObject = NULL; + Section->MaximumSize = MaximumSize; + Segment = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_SECTION_SEGMENT), + TAG_MM_SECTION_SEGMENT); + if (Segment == NULL) + { ZwClose(*SectionHandle); ObDereferenceObject(Section); return(STATUS_NO_MEMORY); - } - Section->Segment = Segment; - Segment->ReferenceCount = 1; - ExInitializeFastMutex(&Segment->Lock); - Segment->FileOffset = 0; - Segment->Protection = SectionPageProtection; - Segment->Attributes = AllocationAttributes; - Segment->RawLength = MaximumSize.u.LowPart; - Segment->Length = PAGE_ROUND_UP(MaximumSize.u.LowPart); - Segment->Flags = MM_PAGEFILE_SEGMENT; - Segment->WriteCopy = FALSE; - RtlZeroMemory(&Segment->PageDirectory, sizeof(SECTION_PAGE_DIRECTORY)); - Segment->VirtualAddress = 0; - Segment->Characteristics = 0; - ObDereferenceObject(Section); - return(STATUS_SUCCESS); + } + Section->Segment = Segment; + Segment->ReferenceCount = 1; + ExInitializeFastMutex(&Segment->Lock); + Segment->FileOffset = 0; + Segment->Protection = SectionPageProtection; + Segment->Attributes = AllocationAttributes; + Segment->RawLength = MaximumSize.u.LowPart; + Segment->Length = PAGE_ROUND_UP(MaximumSize.u.LowPart); + Segment->Flags = MM_PAGEFILE_SEGMENT; + Segment->WriteCopy = FALSE; + RtlZeroMemory(&Segment->PageDirectory, sizeof(SECTION_PAGE_DIRECTORY)); + Segment->VirtualAddress = 0; + Segment->Characteristics = 0; + ObDereferenceObject(Section); + return(STATUS_SUCCESS); } NTSTATUS MmCreateDataFileSection(PHANDLE SectionHandle, - ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes, - PLARGE_INTEGER UMaximumSize, - ULONG SectionPageProtection, - ULONG AllocationAttributes, - HANDLE FileHandle) - /* - * Create a section backed by a data file - */ + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes, + PLARGE_INTEGER UMaximumSize, + ULONG SectionPageProtection, + ULONG AllocationAttributes, + HANDLE FileHandle) +/* + * Create a section backed by a data file + */ { - PSECTION_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; + PSECTION_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; - /* - * Check the protection - */ - if ((SectionPageProtection & PAGE_FLAGS_VALID_FROM_USER_MODE) != - SectionPageProtection) - { + /* + * Check the protection + */ + if ((SectionPageProtection & PAGE_FLAGS_VALID_FROM_USER_MODE) != + SectionPageProtection) + { return(STATUS_INVALID_PAGE_PROTECTION); - } - /* - * Create the section - */ - Status = ObCreateObject(ExGetPreviousMode(), - MmSectionObjectType, - ObjectAttributes, - ExGetPreviousMode(), - NULL, - sizeof(SECTION_OBJECT), - 0, - 0, - (PVOID*)&Section); - if (!NT_SUCCESS(Status)) - { + } + /* + * Create the section + */ + Status = ObCreateObject(ExGetPreviousMode(), + MmSectionObjectType, + ObjectAttributes, + ExGetPreviousMode(), + NULL, + sizeof(SECTION_OBJECT), + 0, + 0, + (PVOID*)&Section); + if (!NT_SUCCESS(Status)) + { return(Status); - } + } - Status = ObInsertObject ((PVOID)Section, - NULL, - DesiredAccess, - 0, - NULL, - SectionHandle); - if (!NT_SUCCESS(Status)) - { + Status = ObInsertObject ((PVOID)Section, + NULL, + DesiredAccess, + 0, + NULL, + SectionHandle); + if (!NT_SUCCESS(Status)) + { ObDereferenceObject(Section); return(Status); - } + } - /* - * Initialize it - */ - Section->SectionPageProtection = SectionPageProtection; - Section->AllocationAttributes = AllocationAttributes; - InitializeListHead(&Section->ViewListHead); - KeInitializeSpinLock(&Section->ViewListLock); + /* + * Initialize it + */ + Section->SectionPageProtection = SectionPageProtection; + Section->AllocationAttributes = AllocationAttributes; + InitializeListHead(&Section->ViewListHead); + KeInitializeSpinLock(&Section->ViewListLock); - /* - * Check file access required - */ - if (SectionPageProtection & PAGE_READWRITE || - SectionPageProtection & PAGE_EXECUTE_READWRITE) - { + /* + * Check file access required + */ + if (SectionPageProtection & PAGE_READWRITE || + SectionPageProtection & PAGE_EXECUTE_READWRITE) + { FileAccess = FILE_READ_DATA | FILE_WRITE_DATA; - } - else - { + } + else + { FileAccess = FILE_READ_DATA; - } + } - /* - * Reference the file handle - */ - Status = ObReferenceObjectByHandle(FileHandle, - FileAccess, - IoFileObjectType, - UserMode, - (PVOID*)&FileObject, - NULL); - if (!NT_SUCCESS(Status)) - { + /* + * Reference the file handle + */ + Status = ObReferenceObjectByHandle(FileHandle, + FileAccess, + IoFileObjectType, + UserMode, + (PVOID*)&FileObject, + NULL); + if (!NT_SUCCESS(Status)) + { ZwClose(*SectionHandle); ObDereferenceObject(Section); return(Status); - } + } - /* - * We can't do memory mappings if the file system doesn't support the - * standard FCB - */ - if (!(FileObject->Flags & FO_FCB_IS_VALID)) - { + /* + * We can't do memory mappings if the file system doesn't support the + * standard FCB + */ + if (!(FileObject->Flags & FO_FCB_IS_VALID)) + { ZwClose(*SectionHandle); ObDereferenceObject(Section); ObDereferenceObject(FileObject); return(STATUS_INVALID_FILE_FOR_SECTION); - } + } - /* - * FIXME: Revise this once a locking order for file size changes is - * decided - */ - if (UMaximumSize != NULL) - { + /* + * FIXME: Revise this once a locking order for file size changes is + * decided + */ + if (UMaximumSize != NULL) + { MaximumSize = *UMaximumSize; - } - else - { + } + else + { MaximumSize = - ((PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)->FileSize; - } + ((PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)->FileSize; + } - if (MaximumSize.QuadPart > - ((PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)->FileSize.QuadPart) - { + if (MaximumSize.QuadPart > + ((PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)->FileSize.QuadPart) + { Status = NtSetInformationFile(FileHandle, - &Iosb, - &MaximumSize, - sizeof(LARGE_INTEGER), - FileAllocationInformation); + &Iosb, + &MaximumSize, + sizeof(LARGE_INTEGER), + FileAllocationInformation); if (!NT_SUCCESS(Status)) - { - ZwClose(*SectionHandle); - ObDereferenceObject(Section); - ObDereferenceObject(FileObject); - return(STATUS_SECTION_NOT_EXTENDED); - } - } + { + ZwClose(*SectionHandle); + ObDereferenceObject(Section); + ObDereferenceObject(FileObject); + return(STATUS_SECTION_NOT_EXTENDED); + } + } - if (FileObject->SectionObjectPointer == NULL || - FileObject->SectionObjectPointer->SharedCacheMap == NULL) - { + 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 @@ -2489,60 +2493,60 @@ MmCreateDataFileSection(PHANDLE SectionHandle, */ Offset.QuadPart = 0; Status = ZwReadFile(FileHandle, - NULL, - NULL, - NULL, - &Iosb, - &Buffer, - sizeof (Buffer), - &Offset, - 0); + NULL, + NULL, + NULL, + &Iosb, + &Buffer, + sizeof (Buffer), + &Offset, + 0); if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE)) - { - ZwClose(*SectionHandle); - ObDereferenceObject(Section); - ObDereferenceObject(FileObject); - return(Status); - } + { + ZwClose(*SectionHandle); + ObDereferenceObject(Section); + ObDereferenceObject(FileObject); + return(Status); + } if (FileObject->SectionObjectPointer == NULL || - FileObject->SectionObjectPointer->SharedCacheMap == NULL) - { - /* FIXME: handle this situation */ - ZwClose(*SectionHandle); - ObDereferenceObject(Section); - ObDereferenceObject(FileObject); - return STATUS_INVALID_PARAMETER; - } - } + FileObject->SectionObjectPointer->SharedCacheMap == NULL) + { + /* FIXME: handle this situation */ + ZwClose(*SectionHandle); + ObDereferenceObject(Section); + ObDereferenceObject(FileObject); + return STATUS_INVALID_PARAMETER; + } + } - /* - * Lock the file - */ - Status = MmspWaitForFileLock(FileObject); - if (Status != STATUS_SUCCESS) - { + /* + * Lock the file + */ + Status = MmspWaitForFileLock(FileObject); + if (Status != STATUS_SUCCESS) + { ZwClose(*SectionHandle); 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) - { + /* + * 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); + TAG_MM_SECTION_SEGMENT); if (Segment == NULL) - { - KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE); - ZwClose(*SectionHandle); - ObDereferenceObject(Section); - ObDereferenceObject(FileObject); - return(STATUS_NO_MEMORY); - } + { + KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE); + ZwClose(*SectionHandle); + ObDereferenceObject(Section); + ObDereferenceObject(FileObject); + return(STATUS_NO_MEMORY); + } Section->Segment = Segment; Segment->ReferenceCount = 1; ExInitializeFastMutex(&Segment->Lock); @@ -2559,456 +2563,456 @@ MmCreateDataFileSection(PHANDLE SectionHandle, Segment->Characteristics = 0; Segment->WriteCopy = FALSE; if (AllocationAttributes & SEC_RESERVE) - { - Segment->Length = Segment->RawLength = 0; - } + { + Segment->Length = Segment->RawLength = 0; + } else - { - Segment->RawLength = MaximumSize.u.LowPart; - Segment->Length = PAGE_ROUND_UP(Segment->RawLength); - } + { + Segment->RawLength = MaximumSize.u.LowPart; + Segment->Length = PAGE_ROUND_UP(Segment->RawLength); + } Segment->VirtualAddress = NULL; RtlZeroMemory(&Segment->PageDirectory, sizeof(SECTION_PAGE_DIRECTORY)); - } - else - { + } + 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; + (PMM_SECTION_SEGMENT)FileObject->SectionObjectPointer-> + DataSectionObject; Section->Segment = Segment; InterlockedIncrement((PLONG)&Segment->ReferenceCount); MmLockSectionSegment(Segment); if (MaximumSize.u.LowPart > Segment->RawLength && - !(AllocationAttributes & SEC_RESERVE)) - { - Segment->RawLength = MaximumSize.u.LowPart; - Segment->Length = PAGE_ROUND_UP(Segment->RawLength); - } - } - MmUnlockSectionSegment(Segment); - Section->FileObject = FileObject; - Section->MaximumSize = MaximumSize; - CcRosReferenceCache(FileObject); - KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE); - ObDereferenceObject(Section); - return(STATUS_SUCCESS); + !(AllocationAttributes & SEC_RESERVE)) + { + Segment->RawLength = MaximumSize.u.LowPart; + Segment->Length = PAGE_ROUND_UP(Segment->RawLength); + } + } + MmUnlockSectionSegment(Segment); + Section->FileObject = FileObject; + Section->MaximumSize = MaximumSize; + CcRosReferenceCache(FileObject); + KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE); + ObDereferenceObject(Section); + return(STATUS_SUCCESS); } static ULONG SectionCharacteristicsToProtect[16] = -{ - PAGE_NOACCESS, // 0 = NONE - PAGE_NOACCESS, // 1 = SHARED - PAGE_EXECUTE, // 2 = EXECUTABLE - PAGE_EXECUTE, // 3 = EXECUTABLE, SHARED - PAGE_READONLY, // 4 = READABLE - PAGE_READONLY, // 5 = READABLE, SHARED - PAGE_EXECUTE_READ, // 6 = READABLE, EXECUTABLE - PAGE_EXECUTE_READ, // 7 = READABLE, EXECUTABLE, SHARED - PAGE_READWRITE, // 8 = WRITABLE - PAGE_READWRITE, // 9 = WRITABLE, SHARED - PAGE_EXECUTE_READWRITE, // 10 = WRITABLE, EXECUTABLE - PAGE_EXECUTE_READWRITE, // 11 = WRITABLE, EXECUTABLE, SHARED - PAGE_READWRITE, // 12 = WRITABLE, READABLE - PAGE_READWRITE, // 13 = WRITABLE, READABLE, SHARED - PAGE_EXECUTE_READWRITE, // 14 = WRITABLE, READABLE, EXECUTABLE, - PAGE_EXECUTE_READWRITE, // 15 = WRITABLE, READABLE, EXECUTABLE, SHARED -}; + { + PAGE_NOACCESS, // 0 = NONE + PAGE_NOACCESS, // 1 = SHARED + PAGE_EXECUTE, // 2 = EXECUTABLE + PAGE_EXECUTE, // 3 = EXECUTABLE, SHARED + PAGE_READONLY, // 4 = READABLE + PAGE_READONLY, // 5 = READABLE, SHARED + PAGE_EXECUTE_READ, // 6 = READABLE, EXECUTABLE + PAGE_EXECUTE_READ, // 7 = READABLE, EXECUTABLE, SHARED + PAGE_READWRITE, // 8 = WRITABLE + PAGE_READWRITE, // 9 = WRITABLE, SHARED + PAGE_EXECUTE_READWRITE, // 10 = WRITABLE, EXECUTABLE + PAGE_EXECUTE_READWRITE, // 11 = WRITABLE, EXECUTABLE, SHARED + PAGE_READWRITE, // 12 = WRITABLE, READABLE + PAGE_READWRITE, // 13 = WRITABLE, READABLE, SHARED + PAGE_EXECUTE_READWRITE, // 14 = WRITABLE, READABLE, EXECUTABLE, + PAGE_EXECUTE_READWRITE, // 15 = WRITABLE, READABLE, EXECUTABLE, SHARED + }; NTSTATUS MmCreateImageSection(PHANDLE SectionHandle, - ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes, - PLARGE_INTEGER UMaximumSize, - ULONG SectionPageProtection, - ULONG AllocationAttributes, - HANDLE FileHandle) + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes, + PLARGE_INTEGER UMaximumSize, + ULONG SectionPageProtection, + ULONG AllocationAttributes, + HANDLE FileHandle) { - PSECTION_OBJECT Section; - NTSTATUS Status; - PFILE_OBJECT FileObject; - IMAGE_DOS_HEADER DosHeader; - IO_STATUS_BLOCK Iosb; - LARGE_INTEGER Offset; - IMAGE_NT_HEADERS PEHeader; - PMM_SECTION_SEGMENT SectionSegments; - ULONG NrSegments; - PMM_IMAGE_SECTION_OBJECT ImageSectionObject; - ULONG i; - ULONG Size; - ULONG Characteristics; - ULONG FileAccess = 0; - /* - * Check the protection - */ - if ((SectionPageProtection & PAGE_FLAGS_VALID_FROM_USER_MODE) != - SectionPageProtection) - { + PSECTION_OBJECT Section; + NTSTATUS Status; + PFILE_OBJECT FileObject; + IMAGE_DOS_HEADER DosHeader; + IO_STATUS_BLOCK Iosb; + LARGE_INTEGER Offset; + IMAGE_NT_HEADERS PEHeader; + PMM_SECTION_SEGMENT SectionSegments; + ULONG NrSegments; + PMM_IMAGE_SECTION_OBJECT ImageSectionObject; + ULONG i; + ULONG Size; + ULONG Characteristics; + ULONG FileAccess = 0; + /* + * Check the protection + */ + if ((SectionPageProtection & PAGE_FLAGS_VALID_FROM_USER_MODE) != + SectionPageProtection) + { return(STATUS_INVALID_PAGE_PROTECTION); - } + } - /* - * Specifying a maximum size is meaningless for an image section - */ - if (UMaximumSize != NULL) - { + /* + * Specifying a maximum size is meaningless for an image section + */ + if (UMaximumSize != NULL) + { return(STATUS_INVALID_PARAMETER_4); - } + } - /* - * Reference the file handle - */ - Status = ObReferenceObjectByHandle(FileHandle, - FileAccess, - IoFileObjectType, - UserMode, - (PVOID*)&FileObject, - NULL); - if (!NT_SUCCESS(Status)) - { + /* + * Reference the file handle + */ + Status = ObReferenceObjectByHandle(FileHandle, + FileAccess, + IoFileObjectType, + UserMode, + (PVOID*)&FileObject, + NULL); + if (!NT_SUCCESS(Status)) + { return Status; - } + } - /* - * 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); - if (!NT_SUCCESS(Status) || FileObject->SectionObjectPointer->ImageSectionObject == NULL) - { + if (!NT_SUCCESS(Status) || FileObject->SectionObjectPointer->ImageSectionObject == NULL) + { PIMAGE_SECTION_HEADER ImageSections; /* * Read the dos header and check the DOS signature */ Offset.QuadPart = 0; Status = ZwReadFile(FileHandle, - NULL, - NULL, - NULL, - &Iosb, - &DosHeader, - sizeof(DosHeader), - &Offset, - NULL); + NULL, + NULL, + NULL, + &Iosb, + &DosHeader, + sizeof(DosHeader), + &Offset, + NULL); if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(FileObject); - return(Status); - } + { + ObDereferenceObject(FileObject); + return(Status); + } /* * Check the DOS signature */ if (Iosb.Information != sizeof(DosHeader) || - DosHeader.e_magic != IMAGE_DOS_SIGNATURE) - { - ObDereferenceObject(FileObject); - return(STATUS_INVALID_IMAGE_FORMAT); - } + DosHeader.e_magic != IMAGE_DOS_SIGNATURE) + { + ObDereferenceObject(FileObject); + return(STATUS_INVALID_IMAGE_FORMAT); + } /* * Read the PE header */ Offset.QuadPart = DosHeader.e_lfanew; Status = ZwReadFile(FileHandle, - NULL, - NULL, - NULL, - &Iosb, - &PEHeader, - sizeof(PEHeader), - &Offset, - NULL); + NULL, + NULL, + NULL, + &Iosb, + &PEHeader, + sizeof(PEHeader), + &Offset, + NULL); if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(FileObject); - return(Status); - } + { + ObDereferenceObject(FileObject); + return(Status); + } /* * Check the signature */ if (Iosb.Information != sizeof(PEHeader) || - PEHeader.Signature != IMAGE_NT_SIGNATURE) - { - ObDereferenceObject(FileObject); - return(STATUS_INVALID_IMAGE_FORMAT); - } + PEHeader.Signature != IMAGE_NT_SIGNATURE) + { + ObDereferenceObject(FileObject); + return(STATUS_INVALID_IMAGE_FORMAT); + } /* * Read in the section headers */ Offset.QuadPart = DosHeader.e_lfanew + sizeof(PEHeader); ImageSections = ExAllocatePool(NonPagedPool, - PEHeader.FileHeader.NumberOfSections * - sizeof(IMAGE_SECTION_HEADER)); + PEHeader.FileHeader.NumberOfSections * + sizeof(IMAGE_SECTION_HEADER)); if (ImageSections == NULL) - { - ObDereferenceObject(FileObject); - return(STATUS_NO_MEMORY); - } + { + ObDereferenceObject(FileObject); + return(STATUS_NO_MEMORY); + } Status = ZwReadFile(FileHandle, - NULL, - NULL, - NULL, - &Iosb, - ImageSections, - PEHeader.FileHeader.NumberOfSections * - sizeof(IMAGE_SECTION_HEADER), - &Offset, - 0); + NULL, + NULL, + NULL, + &Iosb, + ImageSections, + PEHeader.FileHeader.NumberOfSections * + sizeof(IMAGE_SECTION_HEADER), + &Offset, + 0); if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(FileObject); - ExFreePool(ImageSections); - return(Status); - } + { + ObDereferenceObject(FileObject); + ExFreePool(ImageSections); + return(Status); + } if (Iosb.Information != (PEHeader.FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER))) - { - ObDereferenceObject(FileObject); - ExFreePool(ImageSections); - return(STATUS_INVALID_IMAGE_FORMAT); - } + { + ObDereferenceObject(FileObject); + ExFreePool(ImageSections); + return(STATUS_INVALID_IMAGE_FORMAT); + } - /* - * Create the section - */ - Status = ObCreateObject (ExGetPreviousMode(), - MmSectionObjectType, - ObjectAttributes, - ExGetPreviousMode(), - NULL, - sizeof(SECTION_OBJECT), - 0, - 0, - (PVOID*)&Section); - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(FileObject); - ExFreePool(ImageSections); - return(Status); - } - - Status = ObInsertObject ((PVOID)Section, - NULL, - DesiredAccess, - 0, - NULL, - SectionHandle); - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(Section); - ObDereferenceObject(FileObject); - ExFreePool(ImageSections); - return(Status); - } - - /* - * Initialize it - */ - Section->SectionPageProtection = SectionPageProtection; - Section->AllocationAttributes = AllocationAttributes; - InitializeListHead(&Section->ViewListHead); - KeInitializeSpinLock(&Section->ViewListLock); - - /* - * Check file access required - */ - if (SectionPageProtection & (PAGE_READWRITE|PAGE_EXECUTE_READWRITE)) - { - FileAccess = FILE_READ_DATA | FILE_WRITE_DATA; - } - else - { - FileAccess = FILE_READ_DATA; - } - - /* - * We can't do memory mappings if the file system doesn't support the - * standard FCB - */ - if (!(FileObject->Flags & FO_FCB_IS_VALID)) - { - ZwClose(*SectionHandle); - ObDereferenceObject(Section); - ObDereferenceObject(FileObject); - ExFreePool(ImageSections); - return(STATUS_INVALID_FILE_FOR_SECTION); - } - - /* - * Lock the file - */ - Status = MmspWaitForFileLock(FileObject); - if (Status != STATUS_SUCCESS) - { - ZwClose(*SectionHandle); - ObDereferenceObject(Section); - ObDereferenceObject(FileObject); - ExFreePool(ImageSections); - return(Status); - } - - /* - * allocate the section segments to describe the mapping - */ - NrSegments = PEHeader.FileHeader.NumberOfSections + 1; - Size = sizeof(MM_IMAGE_SECTION_OBJECT) + sizeof(MM_SECTION_SEGMENT) * NrSegments; - ImageSectionObject = ExAllocatePoolWithTag(NonPagedPool, Size, TAG_MM_SECTION_SEGMENT); - if (ImageSectionObject == NULL) - { - KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE); - ZwClose(*SectionHandle); - ObDereferenceObject(Section); - ObDereferenceObject(FileObject); - ExFreePool(ImageSections); - return(STATUS_NO_MEMORY); - } - Section->ImageSection = ImageSectionObject; - ImageSectionObject->NrSegments = NrSegments; - ImageSectionObject->ImageBase = (PVOID)PEHeader.OptionalHeader.ImageBase; - ImageSectionObject->EntryPoint = (PVOID)PEHeader.OptionalHeader.AddressOfEntryPoint; - ImageSectionObject->StackReserve = PEHeader.OptionalHeader.SizeOfStackReserve; - ImageSectionObject->StackCommit = PEHeader.OptionalHeader.SizeOfStackCommit; - ImageSectionObject->Subsystem = PEHeader.OptionalHeader.Subsystem; - ImageSectionObject->MinorSubsystemVersion = PEHeader.OptionalHeader.MinorSubsystemVersion; - ImageSectionObject->MajorSubsystemVersion = PEHeader.OptionalHeader.MajorSubsystemVersion; - ImageSectionObject->ImageCharacteristics = PEHeader.FileHeader.Characteristics; - ImageSectionObject->Machine = PEHeader.FileHeader.Machine; - ImageSectionObject->Executable = (PEHeader.OptionalHeader.SizeOfCode != 0); - - SectionSegments = ImageSectionObject->Segments; - SectionSegments[0].FileOffset = 0; - SectionSegments[0].Characteristics = IMAGE_SECTION_CHAR_DATA; - SectionSegments[0].Protection = PAGE_READONLY; - SectionSegments[0].RawLength = PAGE_SIZE; - SectionSegments[0].Length = PAGE_SIZE; - SectionSegments[0].Flags = 0; - SectionSegments[0].ReferenceCount = 1; - SectionSegments[0].VirtualAddress = 0; - SectionSegments[0].WriteCopy = TRUE; - SectionSegments[0].Attributes = 0; - ExInitializeFastMutex(&SectionSegments[0].Lock); - RtlZeroMemory(&SectionSegments[0].PageDirectory, sizeof(SECTION_PAGE_DIRECTORY)); - for (i = 1; i < NrSegments; i++) - { - SectionSegments[i].FileOffset = ImageSections[i-1].PointerToRawData; - SectionSegments[i].Characteristics = ImageSections[i-1].Characteristics; - - /* - * Set up the protection and write copy variables. - */ - Characteristics = ImageSections[i - 1].Characteristics; - if (Characteristics & (IMAGE_SECTION_CHAR_READABLE|IMAGE_SECTION_CHAR_WRITABLE|IMAGE_SECTION_CHAR_EXECUTABLE)) - { - SectionSegments[i].Protection = SectionCharacteristicsToProtect[Characteristics >> 28]; - SectionSegments[i].WriteCopy = !(Characteristics & IMAGE_SECTION_CHAR_SHARED); - } - else if (Characteristics & IMAGE_SECTION_CHAR_CODE) - { - SectionSegments[i].Protection = PAGE_EXECUTE_READ; - SectionSegments[i].WriteCopy = TRUE; - } - else if (Characteristics & IMAGE_SECTION_CHAR_DATA) - { - SectionSegments[i].Protection = PAGE_READWRITE; - SectionSegments[i].WriteCopy = TRUE; - } - else if (Characteristics & IMAGE_SECTION_CHAR_BSS) - { - SectionSegments[i].Protection = PAGE_READWRITE; - SectionSegments[i].WriteCopy = TRUE; - } - else - { - SectionSegments[i].Protection = PAGE_NOACCESS; - SectionSegments[i].WriteCopy = TRUE; - } - - /* - * Set up the attributes. - */ - if (Characteristics & IMAGE_SECTION_CHAR_CODE) - { - SectionSegments[i].Attributes = 0; - } - else if (Characteristics & IMAGE_SECTION_CHAR_DATA) - { - SectionSegments[i].Attributes = 0; - } - else if (Characteristics & IMAGE_SECTION_CHAR_BSS) - { - SectionSegments[i].Attributes = MM_SECTION_SEGMENT_BSS; - } - else - { - SectionSegments[i].Attributes = 0; - } - - SectionSegments[i].RawLength = ImageSections[i-1].SizeOfRawData; - SectionSegments[i].Length = ImageSections[i-1].Misc.VirtualSize; - SectionSegments[i].Flags = 0; - SectionSegments[i].ReferenceCount = 1; - SectionSegments[i].VirtualAddress = (PVOID)ImageSections[i-1].VirtualAddress; - ExInitializeFastMutex(&SectionSegments[i].Lock); - RtlZeroMemory(&SectionSegments[i].PageDirectory, sizeof(SECTION_PAGE_DIRECTORY)); - } - if (0 != InterlockedCompareExchange((PLONG)&FileObject->SectionObjectPointer->ImageSectionObject, - (LONG)ImageSectionObject, 0)) - { - /* - * An other thread has initialized the some image in the background - */ - ExFreePool(ImageSectionObject); - ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject; - Section->ImageSection = ImageSectionObject; - SectionSegments = ImageSectionObject->Segments; - - for (i = 0; i < NrSegments; i++) - { - InterlockedIncrement((LONG *)&SectionSegments[i].ReferenceCount); - } - } - ExFreePool(ImageSections); - } - else - { /* * Create the section */ Status = ObCreateObject (ExGetPreviousMode(), - MmSectionObjectType, - ObjectAttributes, - ExGetPreviousMode(), - NULL, - sizeof(SECTION_OBJECT), - 0, - 0, - (PVOID*)&Section); + MmSectionObjectType, + ObjectAttributes, + ExGetPreviousMode(), + NULL, + sizeof(SECTION_OBJECT), + 0, + 0, + (PVOID*)&Section); if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(FileObject); - return(Status); - } + { + ObDereferenceObject(FileObject); + ExFreePool(ImageSections); + return(Status); + } Status = ObInsertObject ((PVOID)Section, - NULL, - DesiredAccess, - 0, - NULL, - SectionHandle); + NULL, + DesiredAccess, + 0, + NULL, + SectionHandle); if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(Section); - ObDereferenceObject(FileObject); - return(Status); - } + { + ObDereferenceObject(Section); + ObDereferenceObject(FileObject); + ExFreePool(ImageSections); + return(Status); + } + + /* + * Initialize it + */ + Section->SectionPageProtection = SectionPageProtection; + Section->AllocationAttributes = AllocationAttributes; + InitializeListHead(&Section->ViewListHead); + KeInitializeSpinLock(&Section->ViewListLock); + + /* + * Check file access required + */ + if (SectionPageProtection & (PAGE_READWRITE|PAGE_EXECUTE_READWRITE)) + { + FileAccess = FILE_READ_DATA | FILE_WRITE_DATA; + } + else + { + FileAccess = FILE_READ_DATA; + } + + /* + * We can't do memory mappings if the file system doesn't support the + * standard FCB + */ + if (!(FileObject->Flags & FO_FCB_IS_VALID)) + { + ZwClose(*SectionHandle); + ObDereferenceObject(Section); + ObDereferenceObject(FileObject); + ExFreePool(ImageSections); + return(STATUS_INVALID_FILE_FOR_SECTION); + } + + /* + * Lock the file + */ + Status = MmspWaitForFileLock(FileObject); + if (Status != STATUS_SUCCESS) + { + ZwClose(*SectionHandle); + ObDereferenceObject(Section); + ObDereferenceObject(FileObject); + ExFreePool(ImageSections); + return(Status); + } + + /* + * allocate the section segments to describe the mapping + */ + NrSegments = PEHeader.FileHeader.NumberOfSections + 1; + Size = sizeof(MM_IMAGE_SECTION_OBJECT) + sizeof(MM_SECTION_SEGMENT) * NrSegments; + ImageSectionObject = ExAllocatePoolWithTag(NonPagedPool, Size, TAG_MM_SECTION_SEGMENT); + if (ImageSectionObject == NULL) + { + KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE); + ZwClose(*SectionHandle); + ObDereferenceObject(Section); + ObDereferenceObject(FileObject); + ExFreePool(ImageSections); + return(STATUS_NO_MEMORY); + } + Section->ImageSection = ImageSectionObject; + ImageSectionObject->NrSegments = NrSegments; + ImageSectionObject->ImageBase = (PVOID)PEHeader.OptionalHeader.ImageBase; + ImageSectionObject->EntryPoint = (PVOID)PEHeader.OptionalHeader.AddressOfEntryPoint; + ImageSectionObject->StackReserve = PEHeader.OptionalHeader.SizeOfStackReserve; + ImageSectionObject->StackCommit = PEHeader.OptionalHeader.SizeOfStackCommit; + ImageSectionObject->Subsystem = PEHeader.OptionalHeader.Subsystem; + ImageSectionObject->MinorSubsystemVersion = PEHeader.OptionalHeader.MinorSubsystemVersion; + ImageSectionObject->MajorSubsystemVersion = PEHeader.OptionalHeader.MajorSubsystemVersion; + ImageSectionObject->ImageCharacteristics = PEHeader.FileHeader.Characteristics; + ImageSectionObject->Machine = PEHeader.FileHeader.Machine; + ImageSectionObject->Executable = (PEHeader.OptionalHeader.SizeOfCode != 0); + + SectionSegments = ImageSectionObject->Segments; + SectionSegments[0].FileOffset = 0; + SectionSegments[0].Characteristics = IMAGE_SECTION_CHAR_DATA; + SectionSegments[0].Protection = PAGE_READONLY; + SectionSegments[0].RawLength = PAGE_SIZE; + SectionSegments[0].Length = PAGE_SIZE; + SectionSegments[0].Flags = 0; + SectionSegments[0].ReferenceCount = 1; + SectionSegments[0].VirtualAddress = 0; + SectionSegments[0].WriteCopy = TRUE; + SectionSegments[0].Attributes = 0; + ExInitializeFastMutex(&SectionSegments[0].Lock); + RtlZeroMemory(&SectionSegments[0].PageDirectory, sizeof(SECTION_PAGE_DIRECTORY)); + for (i = 1; i < NrSegments; i++) + { + SectionSegments[i].FileOffset = ImageSections[i-1].PointerToRawData; + SectionSegments[i].Characteristics = ImageSections[i-1].Characteristics; + + /* + * Set up the protection and write copy variables. + */ + Characteristics = ImageSections[i - 1].Characteristics; + if (Characteristics & (IMAGE_SECTION_CHAR_READABLE|IMAGE_SECTION_CHAR_WRITABLE|IMAGE_SECTION_CHAR_EXECUTABLE)) + { + SectionSegments[i].Protection = SectionCharacteristicsToProtect[Characteristics >> 28]; + SectionSegments[i].WriteCopy = !(Characteristics & IMAGE_SECTION_CHAR_SHARED); + } + else if (Characteristics & IMAGE_SECTION_CHAR_CODE) + { + SectionSegments[i].Protection = PAGE_EXECUTE_READ; + SectionSegments[i].WriteCopy = TRUE; + } + else if (Characteristics & IMAGE_SECTION_CHAR_DATA) + { + SectionSegments[i].Protection = PAGE_READWRITE; + SectionSegments[i].WriteCopy = TRUE; + } + else if (Characteristics & IMAGE_SECTION_CHAR_BSS) + { + SectionSegments[i].Protection = PAGE_READWRITE; + SectionSegments[i].WriteCopy = TRUE; + } + else + { + SectionSegments[i].Protection = PAGE_NOACCESS; + SectionSegments[i].WriteCopy = TRUE; + } + + /* + * Set up the attributes. + */ + if (Characteristics & IMAGE_SECTION_CHAR_CODE) + { + SectionSegments[i].Attributes = 0; + } + else if (Characteristics & IMAGE_SECTION_CHAR_DATA) + { + SectionSegments[i].Attributes = 0; + } + else if (Characteristics & IMAGE_SECTION_CHAR_BSS) + { + SectionSegments[i].Attributes = MM_SECTION_SEGMENT_BSS; + } + else + { + SectionSegments[i].Attributes = 0; + } + + SectionSegments[i].RawLength = ImageSections[i-1].SizeOfRawData; + SectionSegments[i].Length = ImageSections[i-1].Misc.VirtualSize; + SectionSegments[i].Flags = 0; + SectionSegments[i].ReferenceCount = 1; + SectionSegments[i].VirtualAddress = (PVOID)ImageSections[i-1].VirtualAddress; + ExInitializeFastMutex(&SectionSegments[i].Lock); + RtlZeroMemory(&SectionSegments[i].PageDirectory, sizeof(SECTION_PAGE_DIRECTORY)); + } + if (0 != InterlockedCompareExchange((PLONG)&FileObject->SectionObjectPointer->ImageSectionObject, + (LONG)ImageSectionObject, 0)) + { + /* + * An other thread has initialized the some image in the background + */ + ExFreePool(ImageSectionObject); + ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject; + Section->ImageSection = ImageSectionObject; + SectionSegments = ImageSectionObject->Segments; + + for (i = 0; i < NrSegments; i++) + { + InterlockedIncrement((LONG *)&SectionSegments[i].ReferenceCount); + } + } + ExFreePool(ImageSections); + } + else + { + /* + * Create the section + */ + Status = ObCreateObject (ExGetPreviousMode(), + MmSectionObjectType, + ObjectAttributes, + ExGetPreviousMode(), + NULL, + sizeof(SECTION_OBJECT), + 0, + 0, + (PVOID*)&Section); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(FileObject); + return(Status); + } + + Status = ObInsertObject ((PVOID)Section, + NULL, + DesiredAccess, + 0, + NULL, + SectionHandle); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(Section); + ObDereferenceObject(FileObject); + return(Status); + } /* * Initialize it @@ -3022,25 +3026,25 @@ MmCreateImageSection(PHANDLE SectionHandle, * Check file access required */ if (SectionPageProtection & (PAGE_READWRITE|PAGE_EXECUTE_READWRITE)) - { - FileAccess = FILE_READ_DATA | FILE_WRITE_DATA; - } + { + FileAccess = FILE_READ_DATA | FILE_WRITE_DATA; + } else - { - FileAccess = FILE_READ_DATA; - } + { + FileAccess = FILE_READ_DATA; + } /* * Lock the file */ Status = MmspWaitForFileLock(FileObject); if (Status != STATUS_SUCCESS) - { - ZwClose(*SectionHandle); - ObDereferenceObject(Section); - ObDereferenceObject(FileObject); - return(Status); - } + { + ZwClose(*SectionHandle); + ObDereferenceObject(Section); + ObDereferenceObject(FileObject); + return(Status); + } ImageSectionObject = FileObject->SectionObjectPointer->ImageSectionObject; Section->ImageSection = ImageSectionObject; @@ -3051,16 +3055,16 @@ MmCreateImageSection(PHANDLE SectionHandle, * Otherwise just reference all the section segments */ for (i = 0; i < NrSegments; i++) - { - InterlockedIncrement((LONG *)&SectionSegments[i].ReferenceCount); - } + { + InterlockedIncrement((LONG *)&SectionSegments[i].ReferenceCount); + } - } - Section->FileObject = FileObject; - CcRosReferenceCache(FileObject); - KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE); - ObDereferenceObject(Section); - return(STATUS_SUCCESS); + } + Section->FileObject = FileObject; + CcRosReferenceCache(FileObject); + KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE); + ObDereferenceObject(Section); + return(STATUS_SUCCESS); } /* @@ -3068,196 +3072,196 @@ MmCreateImageSection(PHANDLE SectionHandle, */ NTSTATUS STDCALL NtCreateSection (OUT PHANDLE SectionHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, - IN PLARGE_INTEGER MaximumSize OPTIONAL, - IN ULONG SectionPageProtection OPTIONAL, - IN ULONG AllocationAttributes, - IN HANDLE FileHandle OPTIONAL) + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN PLARGE_INTEGER MaximumSize OPTIONAL, + IN ULONG SectionPageProtection OPTIONAL, + IN ULONG AllocationAttributes, + IN HANDLE FileHandle OPTIONAL) { - if (AllocationAttributes & SEC_IMAGE) - { + if (AllocationAttributes & SEC_IMAGE) + { return(MmCreateImageSection(SectionHandle, - DesiredAccess, - ObjectAttributes, - MaximumSize, - SectionPageProtection, - AllocationAttributes, - FileHandle)); - } + DesiredAccess, + ObjectAttributes, + MaximumSize, + SectionPageProtection, + AllocationAttributes, + FileHandle)); + } - if (FileHandle != NULL) - { + if (FileHandle != NULL) + { return(MmCreateDataFileSection(SectionHandle, - DesiredAccess, - ObjectAttributes, - MaximumSize, - SectionPageProtection, - AllocationAttributes, - FileHandle)); - } + DesiredAccess, + ObjectAttributes, + MaximumSize, + SectionPageProtection, + AllocationAttributes, + FileHandle)); + } - return(MmCreatePageFileSection(SectionHandle, - DesiredAccess, - ObjectAttributes, - MaximumSize, - SectionPageProtection, - AllocationAttributes)); + return(MmCreatePageFileSection(SectionHandle, + DesiredAccess, + ObjectAttributes, + MaximumSize, + SectionPageProtection, + AllocationAttributes)); } /********************************************************************** * NAME - * NtOpenSection + * NtOpenSection * * DESCRIPTION * * ARGUMENTS - * SectionHandle + * SectionHandle * - * DesiredAccess + * DesiredAccess * - * ObjectAttributes + * ObjectAttributes * * RETURN VALUE * * REVISIONS */ NTSTATUS STDCALL -NtOpenSection(PHANDLE SectionHandle, - ACCESS_MASK DesiredAccess, - POBJECT_ATTRIBUTES ObjectAttributes) +NtOpenSection(PHANDLE SectionHandle, + ACCESS_MASK DesiredAccess, + POBJECT_ATTRIBUTES ObjectAttributes) { - NTSTATUS Status; + NTSTATUS Status; - *SectionHandle = 0; + *SectionHandle = 0; - Status = ObOpenObjectByName(ObjectAttributes, - MmSectionObjectType, - NULL, - UserMode, - DesiredAccess, - NULL, - SectionHandle); + Status = ObOpenObjectByName(ObjectAttributes, + MmSectionObjectType, + NULL, + UserMode, + DesiredAccess, + NULL, + SectionHandle); - return(Status); + return(Status); } NTSTATUS STATIC MmMapViewOfSegment(PEPROCESS Process, - PMADDRESS_SPACE AddressSpace, - PSECTION_OBJECT Section, - PMM_SECTION_SEGMENT Segment, - PVOID* BaseAddress, - ULONG ViewSize, - ULONG Protect, - ULONG ViewOffset, - BOOL TopDown) + PMADDRESS_SPACE AddressSpace, + PSECTION_OBJECT Section, + PMM_SECTION_SEGMENT Segment, + PVOID* BaseAddress, + ULONG ViewSize, + ULONG Protect, + ULONG ViewOffset, + BOOL TopDown) { - PMEMORY_AREA MArea; - NTSTATUS Status; - KIRQL oldIrql; - PHYSICAL_ADDRESS BoundaryAddressMultiple; + PMEMORY_AREA MArea; + NTSTATUS Status; + KIRQL oldIrql; + PHYSICAL_ADDRESS BoundaryAddressMultiple; - BoundaryAddressMultiple.QuadPart = 0; + BoundaryAddressMultiple.QuadPart = 0; - Status = MmCreateMemoryArea(Process, - AddressSpace, - MEMORY_AREA_SECTION_VIEW, - BaseAddress, - ViewSize, - Protect, - &MArea, - FALSE, - TopDown, - BoundaryAddressMultiple); - if (!NT_SUCCESS(Status)) - { + Status = MmCreateMemoryArea(Process, + AddressSpace, + MEMORY_AREA_SECTION_VIEW, + BaseAddress, + ViewSize, + Protect, + &MArea, + FALSE, + TopDown, + BoundaryAddressMultiple); + if (!NT_SUCCESS(Status)) + { DPRINT1("Mapping between 0x%.8X and 0x%.8X failed.\n", - (*BaseAddress), (char*)(*BaseAddress) + ViewSize); + (*BaseAddress), (char*)(*BaseAddress) + ViewSize); return(Status); - } + } - KeAcquireSpinLock(&Section->ViewListLock, &oldIrql); - InsertTailList(&Section->ViewListHead, - &MArea->Data.SectionData.ViewListEntry); - KeReleaseSpinLock(&Section->ViewListLock, oldIrql); + KeAcquireSpinLock(&Section->ViewListLock, &oldIrql); + InsertTailList(&Section->ViewListHead, + &MArea->Data.SectionData.ViewListEntry); + KeReleaseSpinLock(&Section->ViewListLock, oldIrql); - ObReferenceObjectByPointer((PVOID)Section, - SECTION_MAP_READ, - NULL, - ExGetPreviousMode()); - MArea->Data.SectionData.Segment = Segment; - MArea->Data.SectionData.Section = Section; - MArea->Data.SectionData.ViewOffset = ViewOffset; - MArea->Data.SectionData.WriteCopyView = FALSE; - MmInitialiseRegion(&MArea->Data.SectionData.RegionListHead, - ViewSize, 0, Protect); + ObReferenceObjectByPointer((PVOID)Section, + SECTION_MAP_READ, + NULL, + ExGetPreviousMode()); + MArea->Data.SectionData.Segment = Segment; + MArea->Data.SectionData.Section = Section; + MArea->Data.SectionData.ViewOffset = ViewOffset; + MArea->Data.SectionData.WriteCopyView = FALSE; + MmInitialiseRegion(&MArea->Data.SectionData.RegionListHead, + ViewSize, 0, Protect); - return(STATUS_SUCCESS); + return(STATUS_SUCCESS); } /********************************************************************** - * NAME EXPORTED - * NtMapViewOfSection + * NAME EXPORTED + * NtMapViewOfSection * * DESCRIPTION - * Maps a view of a section into the virtual address space of a - * process. + * Maps a view of a section into the virtual address space of a + * process. * * ARGUMENTS - * SectionHandle - * Handle of the section. + * SectionHandle + * Handle of the section. * - * ProcessHandle - * Handle of the process. + * ProcessHandle + * Handle of the process. * - * BaseAddress - * Desired base address (or NULL) on entry; - * Actual base address of the view on exit. + * BaseAddress + * Desired base address (or NULL) on entry; + * Actual base address of the view on exit. * - * ZeroBits - * Number of high order address bits that must be zero. + * ZeroBits + * Number of high order address bits that must be zero. * - * CommitSize - * Size in bytes of the initially committed section of - * the view. + * CommitSize + * Size in bytes of the initially committed section of + * the view. * - * SectionOffset - * Offset in bytes from the beginning of the section - * to the beginning of the view. + * SectionOffset + * Offset in bytes from the beginning of the section + * to the beginning of the view. * - * ViewSize - * Desired length of map (or zero to map all) on entry - * Actual length mapped on exit. + * ViewSize + * Desired length of map (or zero to map all) on entry + * Actual length mapped on exit. * - * InheritDisposition - * Specified how the view is to be shared with - * child processes. + * InheritDisposition + * Specified how the view is to be shared with + * child processes. * - * AllocateType - * Type of allocation for the pages. + * AllocateType + * Type of allocation for the pages. * - * Protect - * Protection for the committed region of the view. + * Protect + * Protection for the committed region of the view. * * RETURN VALUE - * Status. + * Status. * * @implemented */ NTSTATUS STDCALL NtMapViewOfSection(HANDLE SectionHandle, - HANDLE ProcessHandle, - PVOID* BaseAddress, - ULONG ZeroBits, - ULONG CommitSize, - PLARGE_INTEGER SectionOffset, - PULONG ViewSize, - SECTION_INHERIT InheritDisposition, - ULONG AllocationType, - ULONG Protect) + HANDLE ProcessHandle, + PVOID* BaseAddress, + ULONG ZeroBits, + ULONG CommitSize, + PLARGE_INTEGER SectionOffset, + PULONG ViewSize, + SECTION_INHERIT InheritDisposition, + ULONG AllocationType, + ULONG Protect) { PSECTION_OBJECT Section; PEPROCESS Process; @@ -3265,41 +3269,41 @@ NtMapViewOfSection(HANDLE SectionHandle, PMADDRESS_SPACE AddressSpace; Status = ObReferenceObjectByHandle(ProcessHandle, - PROCESS_VM_OPERATION, - PsProcessType, - UserMode, - (PVOID*)&Process, - NULL); + PROCESS_VM_OPERATION, + PsProcessType, + UserMode, + (PVOID*)&Process, + NULL); if (!NT_SUCCESS(Status)) - { - return(Status); - } + { + return(Status); + } AddressSpace = &Process->AddressSpace; Status = ObReferenceObjectByHandle(SectionHandle, - SECTION_MAP_READ, - MmSectionObjectType, - UserMode, - (PVOID*)&Section, - NULL); + SECTION_MAP_READ, + MmSectionObjectType, + UserMode, + (PVOID*)&Section, + NULL); if (!(NT_SUCCESS(Status))) - { - DPRINT("ObReference failed rc=%x\n",Status); - ObDereferenceObject(Process); - return(Status); - } + { + DPRINT("ObReference failed rc=%x\n",Status); + ObDereferenceObject(Process); + return(Status); + } Status = MmMapViewOfSection(Section, - Process, - BaseAddress, - ZeroBits, - CommitSize, - SectionOffset, - ViewSize, - InheritDisposition, - AllocationType, - Protect); + Process, + BaseAddress, + ZeroBits, + CommitSize, + SectionOffset, + ViewSize, + InheritDisposition, + AllocationType, + Protect); ObDereferenceObject(Section); ObDereferenceObject(Process); @@ -3309,115 +3313,115 @@ NtMapViewOfSection(HANDLE SectionHandle, VOID STATIC MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, - PHYSICAL_ADDRESS PhysAddr, SWAPENTRY SwapEntry, - BOOLEAN Dirty) + PHYSICAL_ADDRESS PhysAddr, SWAPENTRY SwapEntry, + BOOLEAN Dirty) { - PMEMORY_AREA MArea; - ULONG Entry; - PFILE_OBJECT FileObject; - PBCB Bcb; - ULONG Offset; - SWAPENTRY SavedSwapEntry; - PMM_PAGEOP PageOp; - NTSTATUS Status; - PSECTION_OBJECT Section; - PMM_SECTION_SEGMENT Segment; + PMEMORY_AREA MArea; + ULONG Entry; + PFILE_OBJECT FileObject; + PBCB Bcb; + ULONG Offset; + SWAPENTRY SavedSwapEntry; + PMM_PAGEOP PageOp; + NTSTATUS Status; + PSECTION_OBJECT Section; + PMM_SECTION_SEGMENT Segment; - MArea = (PMEMORY_AREA)Context; + MArea = (PMEMORY_AREA)Context; - Address = (PVOID)PAGE_ROUND_DOWN(Address); + Address = (PVOID)PAGE_ROUND_DOWN(Address); - Offset = ((ULONG)Address - (ULONG)MArea->BaseAddress); + Offset = ((ULONG)Address - (ULONG)MArea->BaseAddress); - Section = MArea->Data.SectionData.Section; - Segment = MArea->Data.SectionData.Segment; + Section = MArea->Data.SectionData.Section; + Segment = MArea->Data.SectionData.Segment; - PageOp = MmCheckForPageOp(MArea, 0, NULL, Segment, Offset); + PageOp = MmCheckForPageOp(MArea, 0, NULL, Segment, Offset); - while (PageOp) - { - MmUnlockSectionSegment(Segment); - MmUnlockAddressSpace(&MArea->Process->AddressSpace); + while (PageOp) + { + MmUnlockSectionSegment(Segment); + MmUnlockAddressSpace(&MArea->Process->AddressSpace); - Status = MmspWaitForPageOpCompletionEvent(PageOp); - if (Status != STATUS_SUCCESS) - { + Status = MmspWaitForPageOpCompletionEvent(PageOp); + if (Status != STATUS_SUCCESS) + { DPRINT1("Failed to wait for page op, status = %x\n", Status); - KEBUGCHECK(0); - } + KEBUGCHECK(0); + } - MmLockAddressSpace(&MArea->Process->AddressSpace); - MmLockSectionSegment(Segment); - MmspCompleteAndReleasePageOp(PageOp); - PageOp = MmCheckForPageOp(MArea, 0, NULL, Segment, Offset); - } + MmLockAddressSpace(&MArea->Process->AddressSpace); + MmLockSectionSegment(Segment); + MmspCompleteAndReleasePageOp(PageOp); + PageOp = MmCheckForPageOp(MArea, 0, NULL, Segment, Offset); + } - Entry = MmGetPageEntrySectionSegment(Segment, Offset); + 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) - { + /* + * For a dirty, datafile, non-private page mark it as dirty in the + * cache manager. + */ + if (Segment->Flags & MM_DATAFILE_SEGMENT) + { if (PhysAddr.QuadPart == PAGE_FROM_SSE(Entry) && Dirty) - { - FileObject = MemoryArea->Data.SectionData.Section->FileObject; - Bcb = FileObject->SectionObjectPointer->SharedCacheMap; - CcRosMarkDirtyCacheSegment(Bcb, Offset); - assert(SwapEntry == 0); - } - } + { + FileObject = MemoryArea->Data.SectionData.Section->FileObject; + Bcb = FileObject->SectionObjectPointer->SharedCacheMap; + CcRosMarkDirtyCacheSegment(Bcb, Offset); + assert(SwapEntry == 0); + } + } - if (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(0); - } + { + DPRINT1("Found a swap entry for a page in a pagefile section.\n"); + KEBUGCHECK(0); + } MmFreeSwapPage(SwapEntry); - } - else if (PhysAddr.QuadPart != 0) - { + } + else if (PhysAddr.QuadPart != 0) + { if (IS_SWAP_FROM_SSE(Entry) || - PhysAddr.QuadPart != (PAGE_FROM_SSE(Entry))) - { - /* - * Sanity check - */ - if (Segment->Flags & MM_PAGEFILE_SEGMENT) - { - DPRINT1("Found a private page in a pagefile section.\n"); - KEBUGCHECK(0); - } - /* - * Just dereference private pages - */ - SavedSwapEntry = MmGetSavedSwapEntryPage(PhysAddr); - if (SavedSwapEntry != 0) - { - MmFreeSwapPage(SavedSwapEntry); - MmSetSavedSwapEntryPage(PhysAddr, 0); - } - MmDeleteRmap(PhysAddr, MArea->Process, Address); - MmReleasePageMemoryConsumer(MC_USER, PhysAddr); - } + PhysAddr.QuadPart != (PAGE_FROM_SSE(Entry))) + { + /* + * Sanity check + */ + if (Segment->Flags & MM_PAGEFILE_SEGMENT) + { + DPRINT1("Found a private page in a pagefile section.\n"); + KEBUGCHECK(0); + } + /* + * Just dereference private pages + */ + SavedSwapEntry = MmGetSavedSwapEntryPage(PhysAddr); + if (SavedSwapEntry != 0) + { + MmFreeSwapPage(SavedSwapEntry); + MmSetSavedSwapEntryPage(PhysAddr, 0); + } + MmDeleteRmap(PhysAddr, MArea->Process, Address); + MmReleasePageMemoryConsumer(MC_USER, PhysAddr); + } else - { - MmDeleteRmap(PhysAddr, MArea->Process, Address); - MmUnsharePageEntrySectionSegment(Section, Segment, Offset, Dirty, FALSE); - } - } + { + MmDeleteRmap(PhysAddr, MArea->Process, Address); + MmUnsharePageEntrySectionSegment(Section, Segment, Offset, Dirty, FALSE); + } + } } NTSTATUS MmUnmapViewOfSegment(PMADDRESS_SPACE AddressSpace, - PVOID BaseAddress) + PVOID BaseAddress) { NTSTATUS Status; PMEMORY_AREA MemoryArea; @@ -3429,11 +3433,11 @@ MmUnmapViewOfSegment(PMADDRESS_SPACE AddressSpace, PLIST_ENTRY RegionListHead; MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, - BaseAddress); + BaseAddress); if (MemoryArea == NULL) - { - return(STATUS_UNSUCCESSFUL); - } + { + return(STATUS_UNSUCCESSFUL); + } MemoryArea->DeleteInProgress = TRUE; Section = MemoryArea->Data.SectionData.Section; @@ -3446,28 +3450,28 @@ MmUnmapViewOfSegment(PMADDRESS_SPACE AddressSpace, RegionListHead = &MemoryArea->Data.SectionData.RegionListHead; while (!IsListEmpty(RegionListHead)) - { - CurrentEntry = RemoveHeadList(RegionListHead); - CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, RegionListEntry); - ExFreePool(CurrentRegion); - } + { + CurrentEntry = RemoveHeadList(RegionListHead); + CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, RegionListEntry); + ExFreePool(CurrentRegion); + } if (Section->AllocationAttributes & SEC_PHYSICALMEMORY) - { - Status = MmFreeMemoryArea(AddressSpace, - BaseAddress, - 0, - NULL, - NULL); - } + { + Status = MmFreeMemoryArea(AddressSpace, + BaseAddress, + 0, + NULL, + NULL); + } else - { - Status = MmFreeMemoryArea(AddressSpace, - BaseAddress, - 0, - MmFreeSectionPage, - MemoryArea); - } + { + Status = MmFreeMemoryArea(AddressSpace, + BaseAddress, + 0, + MmFreeSectionPage, + MemoryArea); + } MmUnlockSectionSegment(Segment); ObDereferenceObject(Section); return(STATUS_SUCCESS); @@ -3478,116 +3482,116 @@ MmUnmapViewOfSegment(PMADDRESS_SPACE AddressSpace, */ NTSTATUS STDCALL MmUnmapViewOfSection(PEPROCESS Process, - PVOID BaseAddress) + PVOID BaseAddress) { - NTSTATUS Status; + NTSTATUS Status; PMEMORY_AREA MemoryArea; PMADDRESS_SPACE AddressSpace; PSECTION_OBJECT Section; DPRINT("Opening memory area Process %x BaseAddress %x\n", - Process, BaseAddress); + Process, BaseAddress); assert(Process); AddressSpace = &Process->AddressSpace; MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, - BaseAddress); + BaseAddress); if (MemoryArea == NULL) - { - return(STATUS_UNSUCCESSFUL); - } + { + return(STATUS_UNSUCCESSFUL); + } Section = MemoryArea->Data.SectionData.Section; if (Section->AllocationAttributes & SEC_IMAGE) - { - ULONG i; - ULONG NrSegments; - PMM_IMAGE_SECTION_OBJECT ImageSectionObject; - PMM_SECTION_SEGMENT SectionSegments; - PVOID ImageBaseAddress = 0; - PMM_SECTION_SEGMENT Segment; + { + ULONG i; + ULONG NrSegments; + PMM_IMAGE_SECTION_OBJECT ImageSectionObject; + PMM_SECTION_SEGMENT SectionSegments; + PVOID ImageBaseAddress = 0; + 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; - /* Search for the current segment within the section segments - * and calculate the image base address */ - for (i = 0; i < NrSegments; 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].Characteristics & IMAGE_SECTION_NOLOAD)) { - if (!(SectionSegments[i].Characteristics & IMAGE_SECTION_NOLOAD)) - { - if (Segment == &SectionSegments[i]) - { - ImageBaseAddress = (char*)BaseAddress - (ULONG_PTR)SectionSegments[i].VirtualAddress; - break; - } - } - } - if (i >= NrSegments) + if (Segment == &SectionSegments[i]) + { + ImageBaseAddress = (char*)BaseAddress - (ULONG_PTR)SectionSegments[i].VirtualAddress; + break; + } + } + } + if (i >= NrSegments) + { + KEBUGCHECK(0); + } + + for (i = 0; i < NrSegments; i++) + { + if (!(SectionSegments[i].Characteristics & IMAGE_SECTION_NOLOAD)) { - KEBUGCHECK(0); - } + PVOID SBaseAddress = (PVOID) + ((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].VirtualAddress); - for (i = 0; i < NrSegments; i++) - { - if (!(SectionSegments[i].Characteristics & IMAGE_SECTION_NOLOAD)) - { - PVOID SBaseAddress = (PVOID) - ((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].VirtualAddress); - - Status = MmUnmapViewOfSegment(AddressSpace, SBaseAddress); - } - } - } + Status = MmUnmapViewOfSegment(AddressSpace, SBaseAddress); + } + } + } else - { - Status = MmUnmapViewOfSegment(AddressSpace, BaseAddress); - } + { + Status = MmUnmapViewOfSegment(AddressSpace, BaseAddress); + } return(STATUS_SUCCESS); } /********************************************************************** - * NAME EXPORTED - * NtUnmapViewOfSection + * NAME EXPORTED + * NtUnmapViewOfSection * * DESCRIPTION * * ARGUMENTS - * ProcessHandle + * ProcessHandle * - * BaseAddress + * BaseAddress * * RETURN VALUE - * Status. + * Status. * * REVISIONS */ NTSTATUS STDCALL -NtUnmapViewOfSection (HANDLE ProcessHandle, - PVOID BaseAddress) +NtUnmapViewOfSection (HANDLE ProcessHandle, + PVOID BaseAddress) { - PEPROCESS Process; + PEPROCESS Process; NTSTATUS Status; DPRINT("NtUnmapViewOfSection(ProcessHandle %x, BaseAddress %x)\n", - ProcessHandle, BaseAddress); + ProcessHandle, BaseAddress); DPRINT("Referencing process\n"); Status = ObReferenceObjectByHandle(ProcessHandle, - PROCESS_VM_OPERATION, - PsProcessType, - UserMode, - (PVOID*)&Process, - NULL); + PROCESS_VM_OPERATION, + PsProcessType, + UserMode, + (PVOID*)&Process, + NULL); if (!NT_SUCCESS(Status)) - { - DPRINT("ObReferenceObjectByHandle failed (Status %x)\n", Status); - return(Status); - } + { + DPRINT("ObReferenceObjectByHandle failed (Status %x)\n", Status); + return(Status); + } MmLockAddressSpace(&Process->AddressSpace); Status = MmUnmapViewOfSection(Process, BaseAddress); @@ -3600,16 +3604,16 @@ NtUnmapViewOfSection (HANDLE ProcessHandle, NTSTATUS STDCALL -NtQuerySection (IN HANDLE SectionHandle, - IN CINT SectionInformationClass, - OUT PVOID SectionInformation, - IN ULONG Length, - OUT PULONG ResultLength) +NtQuerySection (IN HANDLE SectionHandle, + IN CINT SectionInformationClass, + OUT PVOID SectionInformation, + IN ULONG Length, + OUT PULONG ResultLength) /* * FUNCTION: Queries the information of a section object. * ARGUMENTS: * SectionHandle = Handle to the section link object - * SectionInformationClass = Index to a certain information structure + * SectionInformationClass = Index to a certain information structure * SectionInformation (OUT)= Caller supplies storage for resulting * information * Length = Size of the supplied storage @@ -3618,87 +3622,87 @@ NtQuerySection (IN HANDLE SectionHandle, * */ { - PSECTION_OBJECT Section; - NTSTATUS Status; + PSECTION_OBJECT Section; + NTSTATUS Status; - Status = ObReferenceObjectByHandle(SectionHandle, - SECTION_MAP_READ, - MmSectionObjectType, - UserMode, - (PVOID*)&Section, - NULL); - if (!(NT_SUCCESS(Status))) - { + Status = ObReferenceObjectByHandle(SectionHandle, + SECTION_MAP_READ, + MmSectionObjectType, + UserMode, + (PVOID*)&Section, + NULL); + if (!(NT_SUCCESS(Status))) + { return(Status); - } + } - switch (SectionInformationClass) - { - case SectionBasicInformation: - { - PSECTION_BASIC_INFORMATION Sbi; + switch (SectionInformationClass) + { + case SectionBasicInformation: + { + PSECTION_BASIC_INFORMATION Sbi; - if (Length != sizeof(SECTION_BASIC_INFORMATION)) - { - ObDereferenceObject(Section); - return(STATUS_INFO_LENGTH_MISMATCH); - } + if (Length != sizeof(SECTION_BASIC_INFORMATION)) + { + ObDereferenceObject(Section); + return(STATUS_INFO_LENGTH_MISMATCH); + } - Sbi = (PSECTION_BASIC_INFORMATION)SectionInformation; + Sbi = (PSECTION_BASIC_INFORMATION)SectionInformation; - Sbi->BaseAddress = 0; - Sbi->Attributes = 0; - Sbi->Size.QuadPart = 0; + Sbi->BaseAddress = 0; + Sbi->Attributes = 0; + Sbi->Size.QuadPart = 0; - *ResultLength = sizeof(SECTION_BASIC_INFORMATION); - Status = STATUS_SUCCESS; - break; - } + *ResultLength = sizeof(SECTION_BASIC_INFORMATION); + Status = STATUS_SUCCESS; + break; + } case SectionImageInformation: - { - PSECTION_IMAGE_INFORMATION Sii; + { + PSECTION_IMAGE_INFORMATION Sii; - if (Length != sizeof(SECTION_IMAGE_INFORMATION)) - { - ObDereferenceObject(Section); - return(STATUS_INFO_LENGTH_MISMATCH); - } + if (Length != sizeof(SECTION_IMAGE_INFORMATION)) + { + ObDereferenceObject(Section); + return(STATUS_INFO_LENGTH_MISMATCH); + } - Sii = (PSECTION_IMAGE_INFORMATION)SectionInformation; - memset(Sii, 0, sizeof(SECTION_IMAGE_INFORMATION)); - if (Section->AllocationAttributes & SEC_IMAGE) - { - PMM_IMAGE_SECTION_OBJECT ImageSectionObject; - ImageSectionObject = Section->ImageSection; + Sii = (PSECTION_IMAGE_INFORMATION)SectionInformation; + memset(Sii, 0, sizeof(SECTION_IMAGE_INFORMATION)); + if (Section->AllocationAttributes & SEC_IMAGE) + { + PMM_IMAGE_SECTION_OBJECT ImageSectionObject; + ImageSectionObject = Section->ImageSection; - Sii->EntryPoint = ImageSectionObject->EntryPoint; - Sii->StackReserve = ImageSectionObject->StackReserve; - Sii->StackCommit = ImageSectionObject->StackCommit; - Sii->Subsystem = ImageSectionObject->Subsystem; - Sii->MinorSubsystemVersion = (USHORT)ImageSectionObject->MinorSubsystemVersion; - Sii->MajorSubsystemVersion = (USHORT)ImageSectionObject->MajorSubsystemVersion; - Sii->Characteristics = ImageSectionObject->ImageCharacteristics; - Sii->ImageNumber = ImageSectionObject->Machine; - Sii->Executable = ImageSectionObject->Executable; - } - *ResultLength = sizeof(SECTION_IMAGE_INFORMATION); - Status = STATUS_SUCCESS; - break; - } + Sii->EntryPoint = ImageSectionObject->EntryPoint; + Sii->StackReserve = ImageSectionObject->StackReserve; + Sii->StackCommit = ImageSectionObject->StackCommit; + Sii->Subsystem = ImageSectionObject->Subsystem; + Sii->MinorSubsystemVersion = (USHORT)ImageSectionObject->MinorSubsystemVersion; + Sii->MajorSubsystemVersion = (USHORT)ImageSectionObject->MajorSubsystemVersion; + Sii->Characteristics = ImageSectionObject->ImageCharacteristics; + Sii->ImageNumber = ImageSectionObject->Machine; + Sii->Executable = ImageSectionObject->Executable; + } + *ResultLength = sizeof(SECTION_IMAGE_INFORMATION); + Status = STATUS_SUCCESS; + break; + } - default: - *ResultLength = 0; - Status = STATUS_INVALID_INFO_CLASS; - } - ObDereferenceObject(Section); - return(Status); + default: + *ResultLength = 0; + Status = STATUS_INVALID_INFO_CLASS; + } + ObDereferenceObject(Section); + return(Status); } NTSTATUS STDCALL -NtExtendSection(IN HANDLE SectionHandle, - IN ULONG NewMaximumSize) +NtExtendSection(IN HANDLE SectionHandle, + IN ULONG NewMaximumSize) { UNIMPLEMENTED; return(STATUS_NOT_IMPLEMENTED); @@ -3706,18 +3710,18 @@ NtExtendSection(IN HANDLE SectionHandle, /********************************************************************** - * NAME INTERNAL - * MmAllocateSection@4 + * NAME INTERNAL + * MmAllocateSection@4 * * DESCRIPTION * * ARGUMENTS - * Length + * Length * * RETURN VALUE * * NOTE - * Code taken from ntoskrnl/mm/special.c. + * Code taken from ntoskrnl/mm/special.c. * * REVISIONS */ @@ -3739,107 +3743,107 @@ MmAllocateSection (IN ULONG Length) Result = NULL; MmLockAddressSpace(AddressSpace); Status = MmCreateMemoryArea (NULL, - AddressSpace, - MEMORY_AREA_SYSTEM, - &Result, - Length, - 0, - &marea, - FALSE, - FALSE, - BoundaryAddressMultiple); + AddressSpace, + MEMORY_AREA_SYSTEM, + &Result, + Length, + 0, + &marea, + FALSE, + FALSE, + BoundaryAddressMultiple); MmUnlockAddressSpace(AddressSpace); if (!NT_SUCCESS(Status)) - { - return (NULL); - } + { + return (NULL); + } DPRINT("Result %p\n",Result); for (i = 0; i < PAGE_ROUND_UP(Length) / PAGE_SIZE; i++) - { - PHYSICAL_ADDRESS Page; + { + PHYSICAL_ADDRESS Page; - Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page); - if (!NT_SUCCESS(Status)) - { - DbgPrint("Unable to allocate page\n"); - KEBUGCHECK(0); - } - Status = MmCreateVirtualMapping (NULL, - ((char*)Result + (i * PAGE_SIZE)), - PAGE_READWRITE, - Page, - TRUE); - if (!NT_SUCCESS(Status)) - { - DbgPrint("Unable to create virtual mapping\n"); - KEBUGCHECK(0); - } - } + Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page); + if (!NT_SUCCESS(Status)) + { + DbgPrint("Unable to allocate page\n"); + KEBUGCHECK(0); + } + Status = MmCreateVirtualMapping (NULL, + ((char*)Result + (i * PAGE_SIZE)), + PAGE_READWRITE, + Page, + TRUE); + if (!NT_SUCCESS(Status)) + { + DbgPrint("Unable to create virtual mapping\n"); + KEBUGCHECK(0); + } + } return ((PVOID)Result); } /********************************************************************** - * NAME EXPORTED - * MmMapViewOfSection + * NAME EXPORTED + * MmMapViewOfSection * * DESCRIPTION - * Maps a view of a section into the virtual address space of a - * process. + * Maps a view of a section into the virtual address space of a + * process. * * ARGUMENTS - * Section - * Pointer to the section object. + * Section + * Pointer to the section object. * - * ProcessHandle - * Pointer to the process. + * ProcessHandle + * Pointer to the process. * - * BaseAddress - * Desired base address (or NULL) on entry; - * Actual base address of the view on exit. + * BaseAddress + * Desired base address (or NULL) on entry; + * Actual base address of the view on exit. * - * ZeroBits - * Number of high order address bits that must be zero. + * ZeroBits + * Number of high order address bits that must be zero. * - * CommitSize - * Size in bytes of the initially committed section of - * the view. + * CommitSize + * Size in bytes of the initially committed section of + * the view. * - * SectionOffset - * Offset in bytes from the beginning of the section - * to the beginning of the view. + * SectionOffset + * Offset in bytes from the beginning of the section + * to the beginning of the view. * - * ViewSize - * Desired length of map (or zero to map all) on entry - * Actual length mapped on exit. + * ViewSize + * Desired length of map (or zero to map all) on entry + * Actual length mapped on exit. * - * InheritDisposition - * Specified how the view is to be shared with - * child processes. + * InheritDisposition + * Specified how the view is to be shared with + * child processes. * - * AllocationType - * Type of allocation for the pages. + * AllocationType + * Type of allocation for the pages. * - * Protect - * Protection for the committed region of the view. + * Protect + * Protection for the committed region of the view. * * RETURN VALUE - * Status. + * Status. * * @implemented */ NTSTATUS STDCALL MmMapViewOfSection(IN PVOID SectionObject, - IN PEPROCESS Process, - IN OUT PVOID *BaseAddress, - IN ULONG ZeroBits, - IN ULONG CommitSize, - IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, - IN OUT PULONG ViewSize, - IN SECTION_INHERIT InheritDisposition, - IN ULONG AllocationType, - IN ULONG Protect) + IN PEPROCESS Process, + IN OUT PVOID *BaseAddress, + IN ULONG ZeroBits, + IN ULONG CommitSize, + IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, + IN OUT PULONG ViewSize, + IN SECTION_INHERIT InheritDisposition, + IN ULONG AllocationType, + IN ULONG Protect) { PSECTION_OBJECT Section; PMADDRESS_SPACE AddressSpace; @@ -3854,133 +3858,133 @@ MmMapViewOfSection(IN PVOID SectionObject, MmLockAddressSpace(AddressSpace); if (Section->AllocationAttributes & SEC_IMAGE) - { - ULONG i; - ULONG NrSegments; - PVOID ImageBase; - ULONG ImageSize; - PMM_IMAGE_SECTION_OBJECT ImageSectionObject; - PMM_SECTION_SEGMENT SectionSegments; + { + ULONG i; + ULONG NrSegments; + PVOID ImageBase; + ULONG 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 = *BaseAddress; - if (ImageBase == NULL) - { - ImageBase = ImageSectionObject->ImageBase; - } + ImageBase = *BaseAddress; + if (ImageBase == NULL) + { + ImageBase = ImageSectionObject->ImageBase; + } - ImageSize = 0; - for (i = 0; i < NrSegments; i++) - { - if (!(SectionSegments[i].Characteristics & IMAGE_SECTION_NOLOAD)) - { - ULONG MaxExtent; - MaxExtent = (ULONG)((char*)SectionSegments[i].VirtualAddress + - SectionSegments[i].Length); - ImageSize = max(ImageSize, MaxExtent); - } - } + ImageSize = 0; + for (i = 0; i < NrSegments; i++) + { + if (!(SectionSegments[i].Characteristics & IMAGE_SECTION_NOLOAD)) + { + ULONG MaxExtent; + MaxExtent = (ULONG)((char*)SectionSegments[i].VirtualAddress + + SectionSegments[i].Length); + ImageSize = max(ImageSize, MaxExtent); + } + } - /* Check there is enough space to map the section at that point. */ - if (MmOpenMemoryAreaByRegion(AddressSpace, ImageBase, - PAGE_ROUND_UP(ImageSize)) != NULL) - { - /* Fail if the user requested a fixed base address. */ - if ((*BaseAddress) != NULL) - { - MmUnlockAddressSpace(AddressSpace); - return(STATUS_UNSUCCESSFUL); - } - /* Otherwise find a gap to map the image. */ - ImageBase = MmFindGap(AddressSpace, PAGE_ROUND_UP(ImageSize), FALSE); - if (ImageBase == NULL) - { - MmUnlockAddressSpace(AddressSpace); - return(STATUS_UNSUCCESSFUL); - } - } + /* Check there is enough space to map the section at that point. */ + if (MmOpenMemoryAreaByRegion(AddressSpace, ImageBase, + PAGE_ROUND_UP(ImageSize)) != NULL) + { + /* Fail if the user requested a fixed base address. */ + if ((*BaseAddress) != NULL) + { + MmUnlockAddressSpace(AddressSpace); + return(STATUS_UNSUCCESSFUL); + } + /* Otherwise find a gap to map the image. */ + ImageBase = MmFindGap(AddressSpace, PAGE_ROUND_UP(ImageSize), FALSE); + if (ImageBase == NULL) + { + MmUnlockAddressSpace(AddressSpace); + return(STATUS_UNSUCCESSFUL); + } + } - for (i = 0; i < NrSegments; i++) - { - if (!(SectionSegments[i].Characteristics & IMAGE_SECTION_NOLOAD)) - { - PVOID SBaseAddress = (PVOID) - ((char*)ImageBase + (ULONG_PTR)SectionSegments[i].VirtualAddress); - MmLockSectionSegment(&SectionSegments[i]); - Status = MmMapViewOfSegment(Process, - AddressSpace, - Section, - &SectionSegments[i], - &SBaseAddress, - SectionSegments[i].Length, - SectionSegments[i].Protection, - (ULONG_PTR)SectionSegments[i].VirtualAddress, - FALSE); - MmUnlockSectionSegment(&SectionSegments[i]); - if (!NT_SUCCESS(Status)) - { - MmUnlockAddressSpace(AddressSpace); - return(Status); - } - } - } + for (i = 0; i < NrSegments; i++) + { + if (!(SectionSegments[i].Characteristics & IMAGE_SECTION_NOLOAD)) + { + PVOID SBaseAddress = (PVOID) + ((char*)ImageBase + (ULONG_PTR)SectionSegments[i].VirtualAddress); + MmLockSectionSegment(&SectionSegments[i]); + Status = MmMapViewOfSegment(Process, + AddressSpace, + Section, + &SectionSegments[i], + &SBaseAddress, + SectionSegments[i].Length, + SectionSegments[i].Protection, + (ULONG_PTR)SectionSegments[i].VirtualAddress, + FALSE); + MmUnlockSectionSegment(&SectionSegments[i]); + if (!NT_SUCCESS(Status)) + { + MmUnlockAddressSpace(AddressSpace); + return(Status); + } + } + } - *BaseAddress = ImageBase; - } + *BaseAddress = ImageBase; + } else - { - 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); - } + { + 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); + } - if (SectionOffset == NULL) - { - ViewOffset = 0; - } - else - { - ViewOffset = SectionOffset->u.LowPart; - } + if (SectionOffset == NULL) + { + ViewOffset = 0; + } + else + { + ViewOffset = SectionOffset->u.LowPart; + } - if ((ViewOffset % PAGE_SIZE) != 0) - { - MmUnlockAddressSpace(AddressSpace); - return(STATUS_MAPPED_ALIGNMENT); - } + if ((ViewOffset % PAGE_SIZE) != 0) + { + MmUnlockAddressSpace(AddressSpace); + return(STATUS_MAPPED_ALIGNMENT); + } - if ((*ViewSize) == 0) - { - (*ViewSize) = Section->MaximumSize.u.LowPart - ViewOffset; - } - else if (((*ViewSize)+ViewOffset) > Section->MaximumSize.u.LowPart) - { - (*ViewSize) = Section->MaximumSize.u.LowPart - ViewOffset; - } + if ((*ViewSize) == 0) + { + (*ViewSize) = Section->MaximumSize.u.LowPart - ViewOffset; + } + else if (((*ViewSize)+ViewOffset) > Section->MaximumSize.u.LowPart) + { + (*ViewSize) = Section->MaximumSize.u.LowPart - ViewOffset; + } - MmLockSectionSegment(Section->Segment); - Status = MmMapViewOfSegment(Process, - AddressSpace, - Section, - Section->Segment, - BaseAddress, - *ViewSize, - Protect, - ViewOffset, - (AllocationType & MEM_TOP_DOWN)); - MmUnlockSectionSegment(Section->Segment); - if (!NT_SUCCESS(Status)) - { - MmUnlockAddressSpace(AddressSpace); - return(Status); - } - } + MmLockSectionSegment(Section->Segment); + Status = MmMapViewOfSegment(Process, + AddressSpace, + Section, + Section->Segment, + BaseAddress, + *ViewSize, + Protect, + ViewOffset, + (AllocationType & MEM_TOP_DOWN)); + MmUnlockSectionSegment(Section->Segment); + if (!NT_SUCCESS(Status)) + { + MmUnlockAddressSpace(AddressSpace); + return(Status); + } + } MmUnlockAddressSpace(AddressSpace); @@ -3991,11 +3995,11 @@ MmMapViewOfSection(IN PVOID SectionObject, * @unimplemented */ BOOLEAN STDCALL -MmCanFileBeTruncated (IN PSECTION_OBJECT_POINTERS SectionObjectPointer, - IN PLARGE_INTEGER NewFileSize) +MmCanFileBeTruncated (IN PSECTION_OBJECT_POINTERS SectionObjectPointer, + IN PLARGE_INTEGER NewFileSize) { - UNIMPLEMENTED; - return (FALSE); + UNIMPLEMENTED; + return (FALSE); } @@ -4003,31 +4007,31 @@ MmCanFileBeTruncated (IN PSECTION_OBJECT_POINTERS SectionObjectPointer, * @unimplemented */ BOOLEAN STDCALL -MmDisableModifiedWriteOfSection (DWORD Unknown0) +MmDisableModifiedWriteOfSection (DWORD Unknown0) { - UNIMPLEMENTED; - return (FALSE); + UNIMPLEMENTED; + return (FALSE); } /* * @implemented */ BOOLEAN STDCALL -MmFlushImageSection (IN PSECTION_OBJECT_POINTERS SectionObjectPointer, - IN MMFLUSH_TYPE FlushType) +MmFlushImageSection (IN PSECTION_OBJECT_POINTERS SectionObjectPointer, + IN MMFLUSH_TYPE FlushType) { switch(FlushType) { case MmFlushForDelete: if (SectionObjectPointer->ImageSectionObject || - SectionObjectPointer->DataSectionObject) - { + SectionObjectPointer->DataSectionObject) + { return FALSE; - } - CcRosSetRemoveOnClose(SectionObjectPointer); + } + CcRosSetRemoveOnClose(SectionObjectPointer); return TRUE; case MmFlushForWrite: - break; + break; } return FALSE; } @@ -4036,11 +4040,11 @@ MmFlushImageSection (IN PSECTION_OBJECT_POINTERS SectionObjectPointer, * @unimplemented */ BOOLEAN STDCALL -MmForceSectionClosed (DWORD Unknown0, - DWORD Unknown1) +MmForceSectionClosed (DWORD Unknown0, + DWORD Unknown1) { - UNIMPLEMENTED; - return (FALSE); + UNIMPLEMENTED; + return (FALSE); } @@ -4048,48 +4052,48 @@ MmForceSectionClosed (DWORD Unknown0, * @implemented */ NTSTATUS STDCALL -MmMapViewInSystemSpace (IN PVOID SectionObject, - OUT PVOID * MappedBase, - IN OUT PULONG ViewSize) +MmMapViewInSystemSpace (IN PVOID SectionObject, + OUT PVOID * MappedBase, + IN OUT PULONG ViewSize) { - PSECTION_OBJECT Section; - PMADDRESS_SPACE AddressSpace; - NTSTATUS Status; + PSECTION_OBJECT Section; + PMADDRESS_SPACE AddressSpace; + NTSTATUS Status; - DPRINT("MmMapViewInSystemSpace() called\n"); + DPRINT("MmMapViewInSystemSpace() called\n"); - Section = (PSECTION_OBJECT)SectionObject; - AddressSpace = MmGetKernelAddressSpace(); + Section = (PSECTION_OBJECT)SectionObject; + AddressSpace = MmGetKernelAddressSpace(); - MmLockAddressSpace(AddressSpace); + MmLockAddressSpace(AddressSpace); - if ((*ViewSize) == 0) - { + if ((*ViewSize) == 0) + { (*ViewSize) = Section->MaximumSize.u.LowPart; - } - else if ((*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(NULL, - AddressSpace, - Section, - Section->Segment, - MappedBase, - *ViewSize, - PAGE_READWRITE, - 0, - FALSE); + Status = MmMapViewOfSegment(NULL, + AddressSpace, + Section, + Section->Segment, + MappedBase, + *ViewSize, + PAGE_READWRITE, + 0, + FALSE); - MmUnlockSectionSegment(Section->Segment); - MmUnlockAddressSpace(AddressSpace); + MmUnlockSectionSegment(Section->Segment); + MmUnlockAddressSpace(AddressSpace); - return Status; + return Status; } @@ -4097,18 +4101,18 @@ MmMapViewInSystemSpace (IN PVOID SectionObject, * @implemented */ NTSTATUS STDCALL -MmUnmapViewInSystemSpace (IN PVOID MappedBase) +MmUnmapViewInSystemSpace (IN PVOID MappedBase) { - PMADDRESS_SPACE AddressSpace; - NTSTATUS Status; + PMADDRESS_SPACE AddressSpace; + NTSTATUS Status; - DPRINT("MmUnmapViewInSystemSpace() called\n"); + DPRINT("MmUnmapViewInSystemSpace() called\n"); - AddressSpace = MmGetKernelAddressSpace(); + AddressSpace = MmGetKernelAddressSpace(); - Status = MmUnmapViewOfSegment(AddressSpace, MappedBase); + Status = MmUnmapViewOfSegment(AddressSpace, MappedBase); - return Status; + return Status; } @@ -4116,84 +4120,84 @@ MmUnmapViewInSystemSpace (IN PVOID MappedBase) * @unimplemented */ NTSTATUS STDCALL -MmSetBankedSection (DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, - DWORD Unknown4, - DWORD Unknown5) +MmSetBankedSection (DWORD Unknown0, + DWORD Unknown1, + DWORD Unknown2, + DWORD Unknown3, + DWORD Unknown4, + DWORD Unknown5) { - UNIMPLEMENTED; - return (STATUS_NOT_IMPLEMENTED); + UNIMPLEMENTED; + return (STATUS_NOT_IMPLEMENTED); } /********************************************************************** - * NAME EXPORTED - * MmCreateSection@ + * NAME EXPORTED + * MmCreateSection@ * * DESCRIPTION - * Creates a section object. + * Creates a section object. * * ARGUMENTS - * SectionObjiect (OUT) - * Caller supplied storage for the resulting pointer - * to a SECTION_OBJECT instance; + * SectionObjiect (OUT) + * Caller supplied storage for the resulting pointer + * to a SECTION_OBJECT instance; * - * DesiredAccess - * Specifies the desired access to the section can be a - * combination of: - * STANDARD_RIGHTS_REQUIRED | - * SECTION_QUERY | - * SECTION_MAP_WRITE | - * SECTION_MAP_READ | - * SECTION_MAP_EXECUTE + * DesiredAccess + * Specifies the desired access to the section can be a + * combination of: + * STANDARD_RIGHTS_REQUIRED | + * SECTION_QUERY | + * SECTION_MAP_WRITE | + * SECTION_MAP_READ | + * SECTION_MAP_EXECUTE * - * ObjectAttributes [OPTIONAL] - * Initialized attributes for the object can be used - * to create a named section; + * ObjectAttributes [OPTIONAL] + * Initialized attributes for the object can be used + * to create a named section; * - * MaximumSize - * Maximizes the size of the memory section. Must be - * non-NULL for a page-file backed section. - * If value specified for a mapped file and the file is - * not large enough, file will be extended. + * MaximumSize + * Maximizes the size of the memory section. Must be + * non-NULL for a page-file backed section. + * If value specified for a mapped file and the file is + * not large enough, file will be extended. * - * SectionPageProtection - * Can be a combination of: - * PAGE_READONLY | - * PAGE_READWRITE | - * PAGE_WRITEONLY | - * PAGE_WRITECOPY + * SectionPageProtection + * Can be a combination of: + * PAGE_READONLY | + * PAGE_READWRITE | + * PAGE_WRITEONLY | + * PAGE_WRITECOPY * - * AllocationAttributes - * Can be a combination of: - * SEC_IMAGE | - * SEC_RESERVE + * AllocationAttributes + * Can be a combination of: + * SEC_IMAGE | + * SEC_RESERVE * - * FileHandle - * Handle to a file to create a section mapped to a file - * instead of a memory backed section; + * FileHandle + * Handle to a file to create a section mapped to a file + * instead of a memory backed section; * - * File - * Unknown. + * File + * Unknown. * * RETURN VALUE - * Status. + * Status. * * @unimplemented */ NTSTATUS STDCALL -MmCreateSection (OUT PSECTION_OBJECT * SectionObject, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, - IN PLARGE_INTEGER MaximumSize, - IN ULONG SectionPageProtection, - IN ULONG AllocationAttributes, - IN HANDLE FileHandle OPTIONAL, - IN PFILE_OBJECT File OPTIONAL) +MmCreateSection (OUT PSECTION_OBJECT * SectionObject, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN PLARGE_INTEGER MaximumSize, + IN ULONG SectionPageProtection, + IN ULONG AllocationAttributes, + IN HANDLE FileHandle OPTIONAL, + IN PFILE_OBJECT File OPTIONAL) { - return (STATUS_NOT_IMPLEMENTED); + return (STATUS_NOT_IMPLEMENTED); } /* EOF */ diff --git a/reactos/ntoskrnl/mm/slab.c b/reactos/ntoskrnl/mm/slab.c index e34233df690..94b937bb7a5 100644 --- a/reactos/ntoskrnl/mm/slab.c +++ b/reactos/ntoskrnl/mm/slab.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: slab.c,v 1.11 2004/03/04 00:07:02 navaraf Exp $ +/* $Id: slab.c,v 1.12 2004/04/10 22:35:26 gdalsnes Exp $ * * COPYRIGHT: See COPYING in the top directory * PROJECT: ReactOS kernel @@ -44,27 +44,30 @@ struct _SLAB_CACHE_PAGE; typedef struct _SLAB_CACHE { - SLAB_CACHE_CONSTRUCTOR Constructor; - SLAB_CACHE_DESTRUCTOR Destructor; - ULONG BaseSize; - ULONG ObjectSize; - ULONG ObjectsPerPage; - LIST_ENTRY PageListHead; - struct _SLAB_CACHE_PAGE* FirstFreePage; - KSPIN_LOCK SlabLock; -} SLAB_CACHE, *PSLAB_CACHE; + SLAB_CACHE_CONSTRUCTOR Constructor; + SLAB_CACHE_DESTRUCTOR Destructor; + ULONG BaseSize; + ULONG ObjectSize; + ULONG ObjectsPerPage; + LIST_ENTRY PageListHead; + struct _SLAB_CACHE_PAGE* FirstFreePage; + KSPIN_LOCK SlabLock; +} +SLAB_CACHE, *PSLAB_CACHE; typedef struct _SLAB_CACHE_BUFCTL { - struct _SLAB_CACHE_BUFCTL* NextFree; -} SLAB_CACHE_BUFCTL, *PSLAB_CACHE_BUFCTL; + struct _SLAB_CACHE_BUFCTL* NextFree; +} +SLAB_CACHE_BUFCTL, *PSLAB_CACHE_BUFCTL; typedef struct _SLAB_CACHE_PAGE { - LIST_ENTRY PageListEntry; - PSLAB_CACHE_BUFCTL FirstFreeBuffer; - ULONG ReferenceCount; -} SLAB_CACHE_PAGE, *PSLAB_CACHE_PAGE; + LIST_ENTRY PageListEntry; + PSLAB_CACHE_BUFCTL FirstFreeBuffer; + ULONG ReferenceCount; +} +SLAB_CACHE_PAGE, *PSLAB_CACHE_PAGE; /* GLOBALS ******************************************************************/ @@ -72,252 +75,252 @@ typedef struct _SLAB_CACHE_PAGE PSLAB_CACHE ExCreateSlabCache(PUNICODE_STRING Name, ULONG Size, ULONG Align, - SLAB_CACHE_CONSTRUCTOR Constructor, - SLAB_CACHE_DESTRUCTOR Destructor) + SLAB_CACHE_CONSTRUCTOR Constructor, + SLAB_CACHE_DESTRUCTOR Destructor) { - PSLAB_CACHE Slab; - ULONG ObjectSize; - ULONG AlignSize; + PSLAB_CACHE Slab; + ULONG ObjectSize; + ULONG AlignSize; - Slab = ExAllocatePool(NonPagedPool, sizeof(SLAB_CACHE)); - if (Slab == NULL) - { + Slab = ExAllocatePool(NonPagedPool, sizeof(SLAB_CACHE)); + if (Slab == NULL) + { return(NULL); - } + } - Slab->Constructor = Constructor; - Slab->Destructor = Destructor; - Slab->BaseSize = Size; - ObjectSize = Size + sizeof(SLAB_CACHE_BUFCTL); - AlignSize = Align - (ObjectSize % Align); - Slab->ObjectSize = ObjectSize + AlignSize; - Slab->ObjectsPerPage = - (PAGE_SIZE - sizeof(SLAB_CACHE_PAGE)) / Slab->ObjectSize; - Slab->FirstFreePage = NULL; - InitializeListHead(&Slab->PageListHead); - KeInitializeSpinLock(&Slab->SlabLock); - - return(Slab); + Slab->Constructor = Constructor; + Slab->Destructor = Destructor; + Slab->BaseSize = Size; + ObjectSize = Size + sizeof(SLAB_CACHE_BUFCTL); + AlignSize = Align - (ObjectSize % Align); + Slab->ObjectSize = ObjectSize + AlignSize; + Slab->ObjectsPerPage = + (PAGE_SIZE - sizeof(SLAB_CACHE_PAGE)) / Slab->ObjectSize; + Slab->FirstFreePage = NULL; + InitializeListHead(&Slab->PageListHead); + KeInitializeSpinLock(&Slab->SlabLock); + + return(Slab); } PSLAB_CACHE_PAGE ExGrowSlabCache(PSLAB_CACHE Slab) { - PSLAB_CACHE_PAGE SlabPage; - PHYSICAL_ADDRESS PhysicalPage; - PVOID Page; - NTSTATUS Status; - ULONG i; - PSLAB_CACHE_BUFCTL BufCtl; - PVOID Object; - - Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &PhysicalPage); - if (!NT_SUCCESS(Status)) - { - return(NULL); - } + PSLAB_CACHE_PAGE SlabPage; + PHYSICAL_ADDRESS PhysicalPage; + PVOID Page; + NTSTATUS Status; + ULONG i; + PSLAB_CACHE_BUFCTL BufCtl; + PVOID Object; - Page = ExAllocatePageWithPhysPage(PhysicalPage); - if (Page == NULL) - { + Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &PhysicalPage); + if (!NT_SUCCESS(Status)) + { + return(NULL); + } + + Page = ExAllocatePageWithPhysPage(PhysicalPage); + if (Page == NULL) + { MmReleasePageMemoryConsumer(MC_NPPOOL, PhysicalPage); return(NULL); - } + } - SlabPage = (PSLAB_CACHE_PAGE)((char*)Page + PAGE_SIZE - sizeof(SLAB_CACHE_PAGE)); - SlabPage->ReferenceCount = 0; - SlabPage->FirstFreeBuffer = (PSLAB_CACHE_BUFCTL)Page; - for (i = 0; i < Slab->ObjectsPerPage; i++) - { + SlabPage = (PSLAB_CACHE_PAGE)((char*)Page + PAGE_SIZE - sizeof(SLAB_CACHE_PAGE)); + SlabPage->ReferenceCount = 0; + SlabPage->FirstFreeBuffer = (PSLAB_CACHE_BUFCTL)Page; + for (i = 0; i < Slab->ObjectsPerPage; i++) + { BufCtl = (PSLAB_CACHE_BUFCTL)((char*)Page + (i * Slab->ObjectSize)); Object = (PVOID)(BufCtl + 1); if (Slab->Constructor != NULL) - { - Slab->Constructor(Object, Slab->BaseSize); - } + { + Slab->Constructor(Object, Slab->BaseSize); + } if (i == (Slab->ObjectsPerPage - 1)) - { - BufCtl->NextFree = - (PSLAB_CACHE_BUFCTL)((char*)Page + ((i + 1) * Slab->ObjectSize)); - } + { + BufCtl->NextFree = + (PSLAB_CACHE_BUFCTL)((char*)Page + ((i + 1) * Slab->ObjectSize)); + } else - { - BufCtl->NextFree = NULL; - } - } + { + BufCtl->NextFree = NULL; + } + } - return(SlabPage); + return(SlabPage); } PVOID ExAllocateSlabCache(PSLAB_CACHE Slab, BOOLEAN MayWait) { - KIRQL oldIrql; - PSLAB_CACHE_PAGE Page; - PVOID Object; - BOOLEAN NewPage; + KIRQL oldIrql; + PSLAB_CACHE_PAGE Page; + PVOID Object; + BOOLEAN NewPage; - KeAcquireSpinLock(&Slab->SlabLock, &oldIrql); - - /* - * Check if there is a page with free objects - * present, if so allocate from it, if - * not grow the slab. - */ - if (Slab->FirstFreePage == NULL) - { + KeAcquireSpinLock(&Slab->SlabLock, &oldIrql); + + /* + * Check if there is a page with free objects + * present, if so allocate from it, if + * not grow the slab. + */ + if (Slab->FirstFreePage == NULL) + { KeReleaseSpinLock(&Slab->SlabLock, oldIrql); Page = ExGrowSlabCache(Slab); NewPage = TRUE; KeAcquireSpinLock(&Slab->SlabLock, &oldIrql); - } - else - { + } + else + { Page = Slab->FirstFreePage; NewPage = FALSE; - } - - /* - * We shouldn't have got a page without free buffers. - */ - if (Page->FirstFreeBuffer == NULL) - { + } + + /* + * We shouldn't have got a page without free buffers. + */ + if (Page->FirstFreeBuffer == NULL) + { DPRINT1("First free page had no free buffers.\n"); KEBUGCHECK(0); - } + } - /* - * Allocate the first free object from the page. - */ - Object = (PVOID)((char*)Page->FirstFreeBuffer + sizeof(SLAB_CACHE_BUFCTL)); - Page->FirstFreeBuffer = Page->FirstFreeBuffer->NextFree; - Page->ReferenceCount++; + /* + * Allocate the first free object from the page. + */ + Object = (PVOID)((char*)Page->FirstFreeBuffer + sizeof(SLAB_CACHE_BUFCTL)); + Page->FirstFreeBuffer = Page->FirstFreeBuffer->NextFree; + Page->ReferenceCount++; - /* - * If we just allocated all the objects from this page - * and it was the first free page then adjust the - * first free page pointer and move the page to the head - * of the list. - */ - if (Page->ReferenceCount == Slab->ObjectsPerPage && !NewPage) - { + /* + * If we just allocated all the objects from this page + * and it was the first free page then adjust the + * first free page pointer and move the page to the head + * of the list. + */ + if (Page->ReferenceCount == Slab->ObjectsPerPage && !NewPage) + { if (Page->PageListEntry.Flink == &Slab->PageListHead) - { - Slab->FirstFreePage = NULL; - } + { + Slab->FirstFreePage = NULL; + } else - { - PSLAB_CACHE_PAGE NextPage; - - NextPage = CONTAINING_RECORD(Page->PageListEntry.Flink, - SLAB_CACHE_PAGE, - PageListEntry); - Slab->FirstFreePage = NextPage; - } + { + PSLAB_CACHE_PAGE NextPage; + + NextPage = CONTAINING_RECORD(Page->PageListEntry.Flink, + SLAB_CACHE_PAGE, + PageListEntry); + Slab->FirstFreePage = NextPage; + } RemoveEntryList(&Page->PageListEntry); InsertHeadList(&Slab->PageListHead, &Page->PageListEntry); - } - /* - * Otherwise if we created a new page then add it to the end of - * the page list. - */ - else if (NewPage) - { + } + /* + * Otherwise if we created a new page then add it to the end of + * the page list. + */ + else if (NewPage) + { InsertTailList(&Slab->PageListHead, &Page->PageListEntry); if (Slab->FirstFreePage == NULL) - { - Slab->FirstFreePage = Page; - } - } - KeReleaseSpinLock(&Slab->SlabLock, oldIrql); - return(Object); + { + Slab->FirstFreePage = Page; + } + } + KeReleaseSpinLock(&Slab->SlabLock, oldIrql); + return(Object); } VOID ExFreeFromPageSlabCache(PSLAB_CACHE Slab, - PSLAB_CACHE_PAGE Page, - PVOID Object) + PSLAB_CACHE_PAGE Page, + PVOID Object) { - PSLAB_CACHE_BUFCTL BufCtl; + PSLAB_CACHE_BUFCTL BufCtl; - BufCtl = (PSLAB_CACHE_BUFCTL)((char*)Object - sizeof(SLAB_CACHE_BUFCTL)); - BufCtl->NextFree = Page->FirstFreeBuffer; - Page->FirstFreeBuffer = BufCtl; - Page->ReferenceCount--; + BufCtl = (PSLAB_CACHE_BUFCTL)((char*)Object - sizeof(SLAB_CACHE_BUFCTL)); + BufCtl->NextFree = Page->FirstFreeBuffer; + Page->FirstFreeBuffer = BufCtl; + Page->ReferenceCount--; } VOID ExFreeSlabCache(PSLAB_CACHE Slab, PVOID Object) { - KIRQL oldIrql; - PLIST_ENTRY current_entry; - PSLAB_CACHE_PAGE current; + KIRQL oldIrql; + PLIST_ENTRY current_entry; + PSLAB_CACHE_PAGE current; - KeAcquireSpinLock(&Slab->SlabLock, &oldIrql); - current_entry = Slab->PageListHead.Flink; - while (current_entry != &Slab->PageListHead) - { + KeAcquireSpinLock(&Slab->SlabLock, &oldIrql); + current_entry = Slab->PageListHead.Flink; + while (current_entry != &Slab->PageListHead) + { PVOID Base; current = CONTAINING_RECORD(current_entry, - SLAB_CACHE_PAGE, - PageListEntry); + SLAB_CACHE_PAGE, + PageListEntry); Base = (PVOID)((char*)current + sizeof(SLAB_CACHE_PAGE) - PAGE_SIZE); - if (Base >= Object && - ((char*)Base + PAGE_SIZE - sizeof(SLAB_CACHE_PAGE)) >= - ((char*)Object + Slab->ObjectSize)) - { - ExFreeFromPageSlabCache(Slab, current, Object); - /* - * If the page just become free then rearrange things. - */ - if (current->ReferenceCount == 0) - { - RemoveEntryList(¤t->PageListEntry); - InsertTailList(&Slab->PageListHead, ¤t->PageListEntry); - if (Slab->FirstFreePage == NULL) - { - Slab->FirstFreePage = current; - } - } - KeReleaseSpinLock(&Slab->SlabLock, oldIrql); - return; - } - } - DPRINT1("Tried to free object not in cache.\n"); - KEBUGCHECK(0); + if (Base >= Object && + ((char*)Base + PAGE_SIZE - sizeof(SLAB_CACHE_PAGE)) >= + ((char*)Object + Slab->ObjectSize)) + { + ExFreeFromPageSlabCache(Slab, current, Object); + /* + * If the page just become free then rearrange things. + */ + if (current->ReferenceCount == 0) + { + RemoveEntryList(¤t->PageListEntry); + InsertTailList(&Slab->PageListHead, ¤t->PageListEntry); + if (Slab->FirstFreePage == NULL) + { + Slab->FirstFreePage = current; + } + } + KeReleaseSpinLock(&Slab->SlabLock, oldIrql); + return; + } + } + DPRINT1("Tried to free object not in cache.\n"); + KEBUGCHECK(0); } VOID ExDestroySlabCache(PSLAB_CACHE Slab) { - PLIST_ENTRY current_entry; - PSLAB_CACHE_PAGE current; - ULONG i; - PVOID Object; + PLIST_ENTRY current_entry; + PSLAB_CACHE_PAGE current; + ULONG i; + PVOID Object; - current_entry = Slab->PageListHead.Flink; - while (current_entry != &Slab->PageListHead) - { + current_entry = Slab->PageListHead.Flink; + while (current_entry != &Slab->PageListHead) + { PVOID Base; PHYSICAL_ADDRESS PhysicalPage; current = CONTAINING_RECORD(current_entry, - SLAB_CACHE_PAGE, - PageListEntry); + SLAB_CACHE_PAGE, + PageListEntry); Base = (PVOID)((char*)current + sizeof(SLAB_CACHE_PAGE) - PAGE_SIZE); if (Slab->Destructor != NULL) - { - for (i = 0; i < Slab->ObjectsPerPage; i++) - { - Object = (char*)Base + (i * Slab->ObjectSize) + - sizeof(SLAB_CACHE_BUFCTL); - Slab->Destructor(Object, Slab->BaseSize); - } - } + { + for (i = 0; i < Slab->ObjectsPerPage; i++) + { + Object = (char*)Base + (i * Slab->ObjectSize) + + sizeof(SLAB_CACHE_BUFCTL); + Slab->Destructor(Object, Slab->BaseSize); + } + } PhysicalPage = MmGetPhysicalAddressForProcess(NULL, Base); ExUnmapPage(Base); MmReleasePageMemoryConsumer(MC_NPPOOL, PhysicalPage); - } - ExFreePool(Slab); + } + ExFreePool(Slab); } diff --git a/reactos/ntoskrnl/mm/virtual.c b/reactos/ntoskrnl/mm/virtual.c index 92d8f481295..b6c586d4b8e 100644 --- a/reactos/ntoskrnl/mm/virtual.c +++ b/reactos/ntoskrnl/mm/virtual.c @@ -16,14 +16,14 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: virtual.c,v 1.71 2003/12/14 17:44:02 hbirr Exp $ +/* $Id: virtual.c,v 1.72 2004/04/10 22:35:26 gdalsnes Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/mm/virtual.c * PURPOSE: Implementing operations on virtual memory. * PROGRAMMER: David Welch */ - + /* INCLUDE *****************************************************************/ #include @@ -39,11 +39,11 @@ /* FUNCTIONS *****************************************************************/ -NTSTATUS STDCALL -NtFlushVirtualMemory(IN HANDLE ProcessHandle, - IN PVOID BaseAddress, - IN ULONG NumberOfBytesToFlush, - OUT PULONG NumberOfBytesFlushed OPTIONAL) +NTSTATUS STDCALL +NtFlushVirtualMemory(IN HANDLE ProcessHandle, + IN PVOID BaseAddress, + IN ULONG NumberOfBytesToFlush, + OUT PULONG NumberOfBytesFlushed OPTIONAL) /* * FUNCTION: Flushes virtual memory to file * ARGUMENTS: @@ -55,152 +55,152 @@ NtFlushVirtualMemory(IN HANDLE ProcessHandle, * RETURNS: Status */ { - UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); + UNIMPLEMENTED; + return(STATUS_NOT_IMPLEMENTED); } -NTSTATUS STDCALL -NtLockVirtualMemory(HANDLE ProcessHandle, - PVOID BaseAddress, - ULONG NumberOfBytesToLock, - PULONG NumberOfBytesLocked) // ULONG LockOption? +NTSTATUS STDCALL +NtLockVirtualMemory(HANDLE ProcessHandle, + PVOID BaseAddress, + ULONG NumberOfBytesToLock, + PULONG NumberOfBytesLocked) // ULONG LockOption? { - // AG [08-20-03] : I have *no* idea if this is correct, I just used the - // other functions as a template and made a few intelligent guesses... + // AG [08-20-03] : I have *no* idea if this is correct, I just used the + // other functions as a template and made a few intelligent guesses... - NTSTATUS Status; - PMDL Mdl; - PEPROCESS Process; - - DPRINT("NtLockVirtualMemory(ProcessHandle %x, BaseAddress %x, " - "NumberOfBytesToLock %d), NumberOfBytesLocked %x\n",ProcessHandle,BaseAddress, - NumberOfBytesToLock, NumberOfBytesLocked); - - Status = ObReferenceObjectByHandle(ProcessHandle, - PROCESS_VM_WRITE, - NULL, - UserMode, - (PVOID*)(&Process), - NULL); - if (Status != STATUS_SUCCESS) - { + NTSTATUS Status; + PMDL Mdl; + PEPROCESS Process; + + DPRINT("NtLockVirtualMemory(ProcessHandle %x, BaseAddress %x, " + "NumberOfBytesToLock %d), NumberOfBytesLocked %x\n",ProcessHandle,BaseAddress, + NumberOfBytesToLock, NumberOfBytesLocked); + + Status = ObReferenceObjectByHandle(ProcessHandle, + PROCESS_VM_WRITE, + NULL, + UserMode, + (PVOID*)(&Process), + NULL); + if (Status != STATUS_SUCCESS) + { return(Status); - } - - Mdl = MmCreateMdl(NULL, - BaseAddress, - NumberOfBytesToLock); - MmProbeAndLockPages(Mdl, - UserMode, - IoWriteAccess); - - ExFreePool(Mdl); // Are we supposed to do this here? - - ObDereferenceObject(Process); - - *NumberOfBytesLocked = NumberOfBytesToLock; - return(STATUS_SUCCESS); + } + + Mdl = MmCreateMdl(NULL, + BaseAddress, + NumberOfBytesToLock); + MmProbeAndLockPages(Mdl, + UserMode, + IoWriteAccess); + + ExFreePool(Mdl); // Are we supposed to do this here? + + ObDereferenceObject(Process); + + *NumberOfBytesLocked = NumberOfBytesToLock; + return(STATUS_SUCCESS); } -NTSTATUS STDCALL +NTSTATUS STDCALL NtQueryVirtualMemory (IN HANDLE ProcessHandle, - IN PVOID Address, - IN CINT VirtualMemoryInformationClass, - OUT PVOID VirtualMemoryInformation, - IN ULONG Length, - OUT PULONG UnsafeResultLength) + IN PVOID Address, + IN CINT VirtualMemoryInformationClass, + OUT PVOID VirtualMemoryInformation, + IN ULONG Length, + OUT PULONG UnsafeResultLength) { NTSTATUS Status; PEPROCESS Process; MEMORY_AREA* MemoryArea; ULONG ResultLength = 0; PMADDRESS_SPACE AddressSpace; - + DPRINT("NtQueryVirtualMemory(ProcessHandle %x, Address %x, " "VirtualMemoryInformationClass %d, VirtualMemoryInformation %x, " "Length %lu ResultLength %x)\n",ProcessHandle,Address, VirtualMemoryInformationClass,VirtualMemoryInformation, Length,ResultLength); - + Status = ObReferenceObjectByHandle(ProcessHandle, - PROCESS_QUERY_INFORMATION, - NULL, - UserMode, - (PVOID*)(&Process), - NULL); - + PROCESS_QUERY_INFORMATION, + NULL, + UserMode, + (PVOID*)(&Process), + NULL); + if (!NT_SUCCESS(Status)) - { - DPRINT("NtQueryVirtualMemory() = %x\n",Status); - return(Status); - } - + { + DPRINT("NtQueryVirtualMemory() = %x\n",Status); + return(Status); + } + AddressSpace = &Process->AddressSpace; MmLockAddressSpace(AddressSpace); MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, - Address); + Address); switch(VirtualMemoryInformationClass) - { - case MemoryBasicInformation: - { - PMEMORY_BASIC_INFORMATION Info = - (PMEMORY_BASIC_INFORMATION)VirtualMemoryInformation; - - if (Length != sizeof(MEMORY_BASIC_INFORMATION)) - { - MmUnlockAddressSpace(AddressSpace); - ObDereferenceObject(Process); - return(STATUS_INFO_LENGTH_MISMATCH); - } - - if (MemoryArea == NULL) - { - Info->State = MEM_FREE; - Info->BaseAddress = (PVOID)PAGE_ROUND_DOWN(Address); - Status = STATUS_SUCCESS; - ResultLength = sizeof(MEMORY_BASIC_INFORMATION); - } - else if (MemoryArea->Type == MEMORY_AREA_VIRTUAL_MEMORY) - { - Status = MmQueryAnonMem(MemoryArea, Address, Info, - &ResultLength); - } - else if (MemoryArea->Type == MEMORY_AREA_SECTION_VIEW) - { - Status = MmQuerySectionView(MemoryArea, Address, Info, - &ResultLength); - } - else - { - Status = STATUS_UNSUCCESSFUL; - ResultLength = 0; - } - break; - } - - default: - { - Status = STATUS_INVALID_INFO_CLASS; - ResultLength = 0; - break; - } - } + { + case MemoryBasicInformation: + { + PMEMORY_BASIC_INFORMATION Info = + (PMEMORY_BASIC_INFORMATION)VirtualMemoryInformation; + + if (Length != sizeof(MEMORY_BASIC_INFORMATION)) + { + MmUnlockAddressSpace(AddressSpace); + ObDereferenceObject(Process); + return(STATUS_INFO_LENGTH_MISMATCH); + } + + if (MemoryArea == NULL) + { + Info->State = MEM_FREE; + Info->BaseAddress = (PVOID)PAGE_ROUND_DOWN(Address); + Status = STATUS_SUCCESS; + ResultLength = sizeof(MEMORY_BASIC_INFORMATION); + } + else if (MemoryArea->Type == MEMORY_AREA_VIRTUAL_MEMORY) + { + Status = MmQueryAnonMem(MemoryArea, Address, Info, + &ResultLength); + } + else if (MemoryArea->Type == MEMORY_AREA_SECTION_VIEW) + { + Status = MmQuerySectionView(MemoryArea, Address, Info, + &ResultLength); + } + else + { + Status = STATUS_UNSUCCESSFUL; + ResultLength = 0; + } + break; + } + + default: + { + Status = STATUS_INVALID_INFO_CLASS; + ResultLength = 0; + break; + } + } MmUnlockAddressSpace(AddressSpace); ObDereferenceObject(Process); if (UnsafeResultLength != NULL) - { - MmCopyToCaller(UnsafeResultLength, &ResultLength, sizeof(ULONG)); - } + { + MmCopyToCaller(UnsafeResultLength, &ResultLength, sizeof(ULONG)); + } return(Status); } NTSTATUS STDCALL -NtProtectVirtualMemory(IN HANDLE ProcessHandle, - IN PVOID BaseAddress, - IN ULONG NumberOfBytesToProtect, - IN ULONG NewAccessProtection, - OUT PULONG UnsafeOldAccessProtection) +NtProtectVirtualMemory(IN HANDLE ProcessHandle, + IN PVOID BaseAddress, + IN ULONG NumberOfBytesToProtect, + IN ULONG NewAccessProtection, + OUT PULONG UnsafeOldAccessProtection) { PMEMORY_AREA MemoryArea; PEPROCESS Process; @@ -209,210 +209,210 @@ NtProtectVirtualMemory(IN HANDLE ProcessHandle, ULONG OldAccessProtection; NumberOfBytesToProtect = - PAGE_ROUND_UP(BaseAddress + NumberOfBytesToProtect) - - PAGE_ROUND_DOWN(BaseAddress); + PAGE_ROUND_UP(BaseAddress + NumberOfBytesToProtect) - + PAGE_ROUND_DOWN(BaseAddress); BaseAddress = (PVOID)PAGE_ROUND_DOWN(BaseAddress); - + Status = ObReferenceObjectByHandle(ProcessHandle, - PROCESS_VM_OPERATION, - PsProcessType, - UserMode, - (PVOID*)(&Process), - NULL); + PROCESS_VM_OPERATION, + PsProcessType, + UserMode, + (PVOID*)(&Process), + NULL); if (Status != STATUS_SUCCESS) - { - DPRINT("NtProtectVirtualMemory() = %x\n",Status); - return(Status); - } + { + DPRINT("NtProtectVirtualMemory() = %x\n",Status); + return(Status); + } AddressSpace = &Process->AddressSpace; - + MmLockAddressSpace(AddressSpace); MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, - BaseAddress); + BaseAddress); if (MemoryArea == NULL) - { - MmUnlockAddressSpace(AddressSpace); - ObDereferenceObject(Process); - return(STATUS_UNSUCCESSFUL); - } - + { + MmUnlockAddressSpace(AddressSpace); + ObDereferenceObject(Process); + return(STATUS_UNSUCCESSFUL); + } + if (MemoryArea->Type == MEMORY_AREA_VIRTUAL_MEMORY) - { - Status = MmProtectAnonMem(AddressSpace, MemoryArea, BaseAddress, - NumberOfBytesToProtect, NewAccessProtection, - &OldAccessProtection); - } + { + Status = MmProtectAnonMem(AddressSpace, MemoryArea, BaseAddress, + NumberOfBytesToProtect, NewAccessProtection, + &OldAccessProtection); + } else if (MemoryArea->Type == MEMORY_AREA_SECTION_VIEW) - { - Status = MmProtectSectionView(AddressSpace, MemoryArea, BaseAddress, - NumberOfBytesToProtect, - NewAccessProtection, - &OldAccessProtection); - } - + { + Status = MmProtectSectionView(AddressSpace, MemoryArea, BaseAddress, + NumberOfBytesToProtect, + NewAccessProtection, + &OldAccessProtection); + } + MmUnlockAddressSpace(AddressSpace); ObDereferenceObject(Process); - MmCopyToCaller(UnsafeOldAccessProtection, &OldAccessProtection, - sizeof(ULONG)); + MmCopyToCaller(UnsafeOldAccessProtection, &OldAccessProtection, + sizeof(ULONG)); return(Status); } -NTSTATUS STDCALL -NtReadVirtualMemory(IN HANDLE ProcessHandle, - IN PVOID BaseAddress, - OUT PVOID Buffer, - IN ULONG NumberOfBytesToRead, - OUT PULONG NumberOfBytesRead) -{ - NTSTATUS Status; - PMDL Mdl; - PVOID SystemAddress; - PEPROCESS Process; - - DPRINT("NtReadVirtualMemory(ProcessHandle %x, BaseAddress %x, " - "Buffer %x, NumberOfBytesToRead %d)\n",ProcessHandle,BaseAddress, - Buffer,NumberOfBytesToRead); - - Status = ObReferenceObjectByHandle(ProcessHandle, - PROCESS_VM_WRITE, - NULL, - UserMode, - (PVOID*)(&Process), - NULL); - if (Status != STATUS_SUCCESS) - { - return(Status); - } - - Mdl = MmCreateMdl(NULL, - Buffer, - NumberOfBytesToRead); - MmProbeAndLockPages(Mdl, - UserMode, - IoWriteAccess); - - KeAttachProcess(Process); - - SystemAddress = MmGetSystemAddressForMdl(Mdl); - memcpy(SystemAddress, BaseAddress, NumberOfBytesToRead); - - KeDetachProcess(); - - if (Mdl->MappedSystemVa != NULL) - { - MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl); - } - MmUnlockPages(Mdl); - ExFreePool(Mdl); - - ObDereferenceObject(Process); - - *NumberOfBytesRead = NumberOfBytesToRead; - return(STATUS_SUCCESS); -} - -NTSTATUS STDCALL -NtUnlockVirtualMemory(HANDLE ProcessHandle, - PVOID BaseAddress, - ULONG NumberOfBytesToUnlock, - PULONG NumberOfBytesUnlocked OPTIONAL) -{ - // AG [08-20-03] : I have *no* idea if this is correct, I just used the - // other functions as a template and made a few intelligent guesses... - - NTSTATUS Status; - PMDL Mdl; - PEPROCESS Process; - - DPRINT("NtUnlockVirtualMemory(ProcessHandle %x, BaseAddress %x, " - "NumberOfBytesToUnlock %d), NumberOfBytesUnlocked %x\n",ProcessHandle,BaseAddress, - NumberOfBytesToUnlock, NumberOfBytesUnlocked); - - Status = ObReferenceObjectByHandle(ProcessHandle, - PROCESS_VM_WRITE, - NULL, - UserMode, - (PVOID*)(&Process), - NULL); - if (Status != STATUS_SUCCESS) - { - return(Status); - } - - Mdl = MmCreateMdl(NULL, - BaseAddress, - NumberOfBytesToUnlock); - - ObDereferenceObject(Process); - - if (Mdl->MappedSystemVa != NULL) - { - MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl); - } - MmUnlockPages(Mdl); - ExFreePool(Mdl); - - *NumberOfBytesUnlocked = NumberOfBytesToUnlock; - - return(STATUS_SUCCESS); -} - - -NTSTATUS STDCALL -NtWriteVirtualMemory(IN HANDLE ProcessHandle, - IN PVOID BaseAddress, - IN PVOID Buffer, - IN ULONG NumberOfBytesToWrite, - OUT PULONG NumberOfBytesWritten) +NTSTATUS STDCALL +NtReadVirtualMemory(IN HANDLE ProcessHandle, + IN PVOID BaseAddress, + OUT PVOID Buffer, + IN ULONG NumberOfBytesToRead, + OUT PULONG NumberOfBytesRead) { NTSTATUS Status; PMDL Mdl; PVOID SystemAddress; PEPROCESS Process; - - DPRINT("NtWriteVirtualMemory(ProcessHandle %x, BaseAddress %x, " - "Buffer %x, NumberOfBytesToWrite %d)\n",ProcessHandle,BaseAddress, - Buffer,NumberOfBytesToWrite); - + + DPRINT("NtReadVirtualMemory(ProcessHandle %x, BaseAddress %x, " + "Buffer %x, NumberOfBytesToRead %d)\n",ProcessHandle,BaseAddress, + Buffer,NumberOfBytesToRead); + Status = ObReferenceObjectByHandle(ProcessHandle, - PROCESS_VM_WRITE, - NULL, - UserMode, - (PVOID*)(&Process), - NULL); + PROCESS_VM_WRITE, + NULL, + UserMode, + (PVOID*)(&Process), + NULL); if (Status != STATUS_SUCCESS) - { - return(Status); - } - - Mdl = MmCreateMdl(NULL, - Buffer, - NumberOfBytesToWrite); + { + return(Status); + } + + Mdl = MmCreateMdl(NULL, + Buffer, + NumberOfBytesToRead); MmProbeAndLockPages(Mdl, - UserMode, - IoReadAccess); - + UserMode, + IoWriteAccess); + KeAttachProcess(Process); - + SystemAddress = MmGetSystemAddressForMdl(Mdl); - memcpy(BaseAddress, SystemAddress, NumberOfBytesToWrite); - + memcpy(SystemAddress, BaseAddress, NumberOfBytesToRead); + KeDetachProcess(); - + + if (Mdl->MappedSystemVa != NULL) + { + MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl); + } + MmUnlockPages(Mdl); + ExFreePool(Mdl); + + ObDereferenceObject(Process); + + *NumberOfBytesRead = NumberOfBytesToRead; + return(STATUS_SUCCESS); +} + +NTSTATUS STDCALL +NtUnlockVirtualMemory(HANDLE ProcessHandle, + PVOID BaseAddress, + ULONG NumberOfBytesToUnlock, + PULONG NumberOfBytesUnlocked OPTIONAL) +{ + // AG [08-20-03] : I have *no* idea if this is correct, I just used the + // other functions as a template and made a few intelligent guesses... + + NTSTATUS Status; + PMDL Mdl; + PEPROCESS Process; + + DPRINT("NtUnlockVirtualMemory(ProcessHandle %x, BaseAddress %x, " + "NumberOfBytesToUnlock %d), NumberOfBytesUnlocked %x\n",ProcessHandle,BaseAddress, + NumberOfBytesToUnlock, NumberOfBytesUnlocked); + + Status = ObReferenceObjectByHandle(ProcessHandle, + PROCESS_VM_WRITE, + NULL, + UserMode, + (PVOID*)(&Process), + NULL); + if (Status != STATUS_SUCCESS) + { + return(Status); + } + + Mdl = MmCreateMdl(NULL, + BaseAddress, + NumberOfBytesToUnlock); + ObDereferenceObject(Process); if (Mdl->MappedSystemVa != NULL) - { - MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl); - } + { + MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl); + } MmUnlockPages(Mdl); ExFreePool(Mdl); - + + *NumberOfBytesUnlocked = NumberOfBytesToUnlock; + + return(STATUS_SUCCESS); +} + + +NTSTATUS STDCALL +NtWriteVirtualMemory(IN HANDLE ProcessHandle, + IN PVOID BaseAddress, + IN PVOID Buffer, + IN ULONG NumberOfBytesToWrite, + OUT PULONG NumberOfBytesWritten) +{ + NTSTATUS Status; + PMDL Mdl; + PVOID SystemAddress; + PEPROCESS Process; + + DPRINT("NtWriteVirtualMemory(ProcessHandle %x, BaseAddress %x, " + "Buffer %x, NumberOfBytesToWrite %d)\n",ProcessHandle,BaseAddress, + Buffer,NumberOfBytesToWrite); + + Status = ObReferenceObjectByHandle(ProcessHandle, + PROCESS_VM_WRITE, + NULL, + UserMode, + (PVOID*)(&Process), + NULL); + if (Status != STATUS_SUCCESS) + { + return(Status); + } + + Mdl = MmCreateMdl(NULL, + Buffer, + NumberOfBytesToWrite); + MmProbeAndLockPages(Mdl, + UserMode, + IoReadAccess); + + KeAttachProcess(Process); + + SystemAddress = MmGetSystemAddressForMdl(Mdl); + memcpy(BaseAddress, SystemAddress, NumberOfBytesToWrite); + + KeDetachProcess(); + + ObDereferenceObject(Process); + + if (Mdl->MappedSystemVa != NULL) + { + MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl); + } + MmUnlockPages(Mdl); + ExFreePool(Mdl); + *NumberOfBytesWritten = NumberOfBytesToWrite; - + return(STATUS_SUCCESS); } @@ -424,15 +424,15 @@ MmSecureVirtualMemory (PVOID Address, SIZE_T Length, ULONG Mode) { - /* Only works for user space */ - if (MmHighestUserAddress < Address) - { + /* Only works for user space */ + if (MmHighestUserAddress < Address) + { return NULL; - } + } - UNIMPLEMENTED; + UNIMPLEMENTED; - return 0; + return 0; } @@ -442,12 +442,12 @@ MmSecureVirtualMemory (PVOID Address, VOID STDCALL MmUnsecureVirtualMemory(PVOID SecureMem) { - if (NULL == SecureMem) - { + if (NULL == SecureMem) + { return; - } + } - UNIMPLEMENTED; + UNIMPLEMENTED; } @@ -456,23 +456,23 @@ MmUnsecureVirtualMemory(PVOID SecureMem) */ VOID STDCALL ProbeForRead (IN PVOID Address, - IN ULONG Length, - IN ULONG Alignment) + IN ULONG Length, + IN ULONG Alignment) { - assert (Alignment ==1 || Alignment == 2 || Alignment == 4 || Alignment == 8); + assert (Alignment ==1 || Alignment == 2 || Alignment == 4 || Alignment == 8); - if (Length == 0) - return; + if (Length == 0) + return; - if (((ULONG_PTR)Address & (Alignment - 1)) != 0) - { + if (((ULONG_PTR)Address & (Alignment - 1)) != 0) + { ExRaiseStatus (STATUS_DATATYPE_MISALIGNMENT); - } - else if ((ULONG_PTR)Address + Length < (ULONG_PTR)Address || - (ULONG_PTR)Address + Length > (ULONG_PTR)MmUserProbeAddress) - { + } + else if ((ULONG_PTR)Address + Length < (ULONG_PTR)Address || + (ULONG_PTR)Address + Length > (ULONG_PTR)MmUserProbeAddress) + { ExRaiseStatus (STATUS_ACCESS_VIOLATION); - } + } } @@ -481,35 +481,35 @@ ProbeForRead (IN PVOID Address, */ VOID STDCALL ProbeForWrite (IN PVOID Address, - IN ULONG Length, - IN ULONG Alignment) + IN ULONG Length, + IN ULONG Alignment) { - PULONG Ptr; - ULONG x; - ULONG i; + PULONG Ptr; + ULONG x; + ULONG i; - assert (Alignment ==1 || Alignment == 2 || Alignment == 4 || Alignment == 8); + assert (Alignment ==1 || Alignment == 2 || Alignment == 4 || Alignment == 8); - if (Length == 0) - return; + if (Length == 0) + return; - if (((ULONG_PTR)Address & (Alignment - 1)) != 0) - { + if (((ULONG_PTR)Address & (Alignment - 1)) != 0) + { ExRaiseStatus (STATUS_DATATYPE_MISALIGNMENT); - } - else if ((ULONG_PTR)Address + Length < (ULONG_PTR)Address || - (ULONG_PTR)Address + Length > (ULONG_PTR)MmUserProbeAddress) - { + } + else if ((ULONG_PTR)Address + Length < (ULONG_PTR)Address || + (ULONG_PTR)Address + Length > (ULONG_PTR)MmUserProbeAddress) + { ExRaiseStatus (STATUS_ACCESS_VIOLATION); - } + } - /* Check for accessible pages */ - for (i = 0; i < Length; i += PAGE_SIZE) - { + /* Check for accessible pages */ + for (i = 0; i < Length; i += PAGE_SIZE) + { Ptr = (PULONG)(((ULONG_PTR)Address & ~(PAGE_SIZE - 1)) + i); x = *Ptr; *Ptr = x; - } + } } /* EOF */ diff --git a/reactos/ntoskrnl/mm/wset.c b/reactos/ntoskrnl/mm/wset.c index aff9a12d238..69477b025b7 100644 --- a/reactos/ntoskrnl/mm/wset.c +++ b/reactos/ntoskrnl/mm/wset.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: wset.c,v 1.17 2003/07/12 01:52:10 dwelch Exp $ +/* $Id: wset.c,v 1.18 2004/04/10 22:35:26 gdalsnes Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/mm/wset.c @@ -41,30 +41,30 @@ NTSTATUS MmTrimUserMemory(ULONG Target, ULONG Priority, PULONG NrFreedPages) { - PHYSICAL_ADDRESS CurrentPhysicalAddress; - PHYSICAL_ADDRESS NextPhysicalAddress; - NTSTATUS Status; + PHYSICAL_ADDRESS CurrentPhysicalAddress; + PHYSICAL_ADDRESS NextPhysicalAddress; + NTSTATUS Status; - (*NrFreedPages) = 0; + (*NrFreedPages) = 0; - CurrentPhysicalAddress = MmGetLRUFirstUserPage(); - while (CurrentPhysicalAddress.QuadPart != 0 && Target > 0) - { + CurrentPhysicalAddress = MmGetLRUFirstUserPage(); + while (CurrentPhysicalAddress.QuadPart != 0 && Target > 0) + { NextPhysicalAddress = MmGetLRUNextUserPage(CurrentPhysicalAddress); Status = MmPageOutPhysicalAddress(CurrentPhysicalAddress); if (NT_SUCCESS(Status)) - { - DPRINT("Succeeded\n"); - Target--; - (*NrFreedPages)++; - } + { + DPRINT("Succeeded\n"); + Target--; + (*NrFreedPages)++; + } else if (Status == STATUS_PAGEFILE_QUOTA) - { - MmSetLRULastPage(CurrentPhysicalAddress); - } + { + MmSetLRULastPage(CurrentPhysicalAddress); + } CurrentPhysicalAddress = NextPhysicalAddress; - } - return(STATUS_SUCCESS); + } + return(STATUS_SUCCESS); }