Author: jgardou
Date: Sat Nov 12 19:26:26 2011
New Revision: 54366
URL:
http://svn.reactos.org/svn/reactos?rev=54366&view=rev
Log:
(FORMATTING)
- get back this good ol' 4-space indentation
Modified:
trunk/reactos/ntoskrnl/mm/anonmem.c
Modified: trunk/reactos/ntoskrnl/mm/anonmem.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/anonmem.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/anonmem.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/anonmem.c [iso-8859-1] Sat Nov 12 19:26:26 2011
@@ -51,164 +51,164 @@
NTSTATUS
NTAPI
MmPageOutVirtualMemory(PMMSUPPORT AddressSpace,
- PMEMORY_AREA MemoryArea,
- PVOID Address,
- PMM_PAGEOP PageOp)
+ PMEMORY_AREA MemoryArea,
+ PVOID Address,
+ PMM_PAGEOP PageOp)
{
- PFN_NUMBER Page;
- BOOLEAN WasDirty;
- SWAPENTRY SwapEntry;
- NTSTATUS Status;
- PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
+ PFN_NUMBER Page;
+ BOOLEAN WasDirty;
+ SWAPENTRY SwapEntry;
+ NTSTATUS Status;
+ PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
- DPRINT("MmPageOutVirtualMemory(Address 0x%.8X) PID %d\n",
- Address, Process->UniqueProcessId);
-
- /*
+ DPRINT("MmPageOutVirtualMemory(Address 0x%.8X) PID %d\n",
+ Address, 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);
- }
-
- /*
+ if (MemoryArea->DeleteInProgress)
+ {
+ PageOp->Status = STATUS_UNSUCCESSFUL;
+ KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
+ MmReleasePageOp(PageOp);
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ /*
* Disable the virtual mapping.
*/
- MmDisableVirtualMapping(Process, Address,
- &WasDirty, &Page);
-
- if (Page == 0)
- {
- KeBugCheck(MEMORY_MANAGEMENT);
- }
-
- /*
+ MmDisableVirtualMapping(Process, Address,
+ &WasDirty, &Page);
+
+ if (Page == 0)
+ {
+ KeBugCheck(MEMORY_MANAGEMENT);
+ }
+
+ /*
* Paging out non-dirty data is easy.
*/
- if (!WasDirty)
- {
- MmLockAddressSpace(AddressSpace);
- MmDeleteVirtualMapping(Process, Address, FALSE, NULL, NULL);
- MmDeleteAllRmaps(Page, NULL, NULL);
- if ((SwapEntry = MmGetSavedSwapEntryPage(Page)) != 0)
- {
- MmCreatePageFileMapping(Process, Address, SwapEntry);
- MmSetSavedSwapEntryPage(Page, 0);
- }
- MmUnlockAddressSpace(AddressSpace);
- MmReleasePageMemoryConsumer(MC_USER, Page);
- PageOp->Status = STATUS_SUCCESS;
- KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
- MmReleasePageOp(PageOp);
- return(STATUS_SUCCESS);
- }
-
- /*
+ if (!WasDirty)
+ {
+ MmLockAddressSpace(AddressSpace);
+ MmDeleteVirtualMapping(Process, Address, FALSE, NULL, NULL);
+ MmDeleteAllRmaps(Page, NULL, NULL);
+ if ((SwapEntry = MmGetSavedSwapEntryPage(Page)) != 0)
+ {
+ MmCreatePageFileMapping(Process, Address, SwapEntry);
+ MmSetSavedSwapEntryPage(Page, 0);
+ }
+ MmUnlockAddressSpace(AddressSpace);
+ MmReleasePageMemoryConsumer(MC_USER, Page);
+ 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(Page);
- if (SwapEntry == 0)
- {
- SwapEntry = MmAllocSwapPage();
- if (SwapEntry == 0)
- {
- MmShowOutOfSpaceMessagePagingFile();
- MmEnableVirtualMapping(Process, Address);
- PageOp->Status = STATUS_UNSUCCESSFUL;
- KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
- MmReleasePageOp(PageOp);
- return(STATUS_PAGEFILE_QUOTA);
- }
- }
-
- /*
+ SwapEntry = MmGetSavedSwapEntryPage(Page);
+ if (SwapEntry == 0)
+ {
+ SwapEntry = MmAllocSwapPage();
+ if (SwapEntry == 0)
+ {
+ MmShowOutOfSpaceMessagePagingFile();
+ MmEnableVirtualMapping(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
*/
- Status = MmWriteToSwapPage(SwapEntry, Page);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n",
- Status);
- MmEnableVirtualMapping(Process, Address);
- PageOp->Status = STATUS_UNSUCCESSFUL;
- KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
- MmReleasePageOp(PageOp);
- return(STATUS_UNSUCCESSFUL);
- }
-
- /*
+ Status = MmWriteToSwapPage(SwapEntry, Page);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n",
+ Status);
+ MmEnableVirtualMapping(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
*/
- DPRINT("MM: Swapped out virtual memory page 0x%.8X!\n", Page <<
PAGE_SHIFT);
- MmLockAddressSpace(AddressSpace);
- MmDeleteVirtualMapping(Process, Address, FALSE, NULL, NULL);
- MmCreatePageFileMapping(Process, Address, SwapEntry);
- MmUnlockAddressSpace(AddressSpace);
- MmDeleteAllRmaps(Page, NULL, NULL);
- MmSetSavedSwapEntryPage(Page, 0);
- MmReleasePageMemoryConsumer(MC_USER, Page);
- PageOp->Status = STATUS_SUCCESS;
- KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
- MmReleasePageOp(PageOp);
- return(STATUS_SUCCESS);
+ DPRINT("MM: Swapped out virtual memory page 0x%.8X!\n", Page <<
PAGE_SHIFT);
+ MmLockAddressSpace(AddressSpace);
+ MmDeleteVirtualMapping(Process, Address, FALSE, NULL, NULL);
+ MmCreatePageFileMapping(Process, Address, SwapEntry);
+ MmUnlockAddressSpace(AddressSpace);
+ MmDeleteAllRmaps(Page, NULL, NULL);
+ MmSetSavedSwapEntryPage(Page, 0);
+ MmReleasePageMemoryConsumer(MC_USER, Page);
+ PageOp->Status = STATUS_SUCCESS;
+ KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
+ MmReleasePageOp(PageOp);
+ return(STATUS_SUCCESS);
}
NTSTATUS
NTAPI
MmNotPresentFaultVirtualMemory(PMMSUPPORT AddressSpace,
- MEMORY_AREA* MemoryArea,
- PVOID Address)
+ MEMORY_AREA* MemoryArea,
+ PVOID Address)
/*
- * FUNCTION: Move data into memory to satisfy a page not present fault
- * ARGUMENTS:
- * AddressSpace = Address space within which the fault occurred
- * MemoryArea = The memory area within which the fault occurred
- * Address = The absolute address of fault
- * RETURNS: Status
- * NOTES: This function is called with the address space lock held.
- */
+* FUNCTION: Move data into memory to satisfy a page not present fault
+* ARGUMENTS:
+* AddressSpace = Address space within which the fault occurred
+* MemoryArea = The memory area within which the fault occurred
+* Address = The absolute address of fault
+* RETURNS: Status
+* NOTES: This function is called with the address space lock held.
+*/
{
- PFN_NUMBER Page;
- NTSTATUS Status;
- PMM_REGION Region;
- PMM_PAGEOP PageOp;
- PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
+ PFN_NUMBER Page;
+ NTSTATUS Status;
+ PMM_REGION Region;
+ PMM_PAGEOP PageOp;
+ PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
- /*
+ /*
* 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))
- {
- return(STATUS_SUCCESS);
- }
-
- /*
+ if (MmIsPagePresent(NULL, Address))
+ {
+ return(STATUS_SUCCESS);
+ }
+
+ /*
* Check for the virtual memory area being deleted.
*/
- if (MemoryArea->DeleteInProgress)
- {
- return(STATUS_UNSUCCESSFUL);
- }
-
- /*
+ if (MemoryArea->DeleteInProgress)
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ /*
* Get the segment corresponding to the virtual address
*/
- Region = MmFindRegion(MemoryArea->StartingAddress,
- &MemoryArea->Data.VirtualMemoryData.RegionListHead,
- Address, NULL);
-
- if (Region->Type == MEM_RESERVE || Region->Protect == PAGE_NOACCESS)
- {
- return(STATUS_ACCESS_VIOLATION);
- }
-
- /*
+ Region = MmFindRegion(MemoryArea->StartingAddress,
+ &MemoryArea->Data.VirtualMemoryData.RegionListHead,
+ Address, NULL);
+
+ if (Region->Type == MEM_RESERVE || Region->Protect == PAGE_NOACCESS)
+ {
+ return(STATUS_ACCESS_VIOLATION);
+ }
+
+ /*
* FIXME
*/
if (Region->Protect & PAGE_GUARD)
@@ -216,230 +216,230 @@
return(STATUS_GUARD_PAGE_VIOLATION);
}
- /*
+ /*
* Get or create a page operation
*/
- PageOp = MmGetPageOp(MemoryArea, Process->UniqueProcessId,
- (PVOID)PAGE_ROUND_DOWN(Address), NULL, 0,
- MM_PAGEOP_PAGEIN, FALSE);
- if (PageOp == NULL)
- {
- DPRINT1("MmGetPageOp failed");
- KeBugCheck(MEMORY_MANAGEMENT);
- }
-
- /*
+ PageOp = MmGetPageOp(MemoryArea, Process->UniqueProcessId,
+ (PVOID)PAGE_ROUND_DOWN(Address), NULL, 0,
+ MM_PAGEOP_PAGEIN, FALSE);
+ if (PageOp == NULL)
+ {
+ DPRINT1("MmGetPageOp failed");
+ KeBugCheck(MEMORY_MANAGEMENT);
+ }
+
+ /*
* 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(MEMORY_MANAGEMENT);
- }
- if (PageOp->Status == STATUS_PENDING)
- {
- DPRINT1("Woke for page op before completion\n");
- KeBugCheck(MEMORY_MANAGEMENT);
- }
- /*
- * 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);
- KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
- MmReleasePageOp(PageOp);
- return(STATUS_SUCCESS);
- }
-
- /*
+ 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(MEMORY_MANAGEMENT);
+ }
+ if (PageOp->Status == STATUS_PENDING)
+ {
+ DPRINT1("Woke for page op before completion\n");
+ KeBugCheck(MEMORY_MANAGEMENT);
+ }
+ /*
+ * 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);
+ KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
+ MmReleasePageOp(PageOp);
+ return(STATUS_SUCCESS);
+ }
+
+ /*
* Try to allocate a page
*/
- MI_SET_USAGE(MI_USAGE_VAD);
- MI_SET_PROCESS2(Process->ImageFileName);
- Status = MmRequestPageMemoryConsumer(MC_USER, FALSE, &Page);
- if (Status == STATUS_NO_MEMORY)
- {
- MmUnlockAddressSpace(AddressSpace);
- Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
- MmLockAddressSpace(AddressSpace);
- }
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("MmRequestPageMemoryConsumer failed, status = %x\n", Status);
- KeBugCheck(MEMORY_MANAGEMENT);
- }
-
- /*
+ MI_SET_USAGE(MI_USAGE_VAD);
+ MI_SET_PROCESS2(Process->ImageFileName);
+ Status = MmRequestPageMemoryConsumer(MC_USER, FALSE, &Page);
+ if (Status == STATUS_NO_MEMORY)
+ {
+ MmUnlockAddressSpace(AddressSpace);
+ Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
+ MmLockAddressSpace(AddressSpace);
+ }
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("MmRequestPageMemoryConsumer failed, status = %x\n", Status);
+ KeBugCheck(MEMORY_MANAGEMENT);
+ }
+
+ /*
* Handle swapped out pages.
*/
- if (MmIsPageSwapEntry(NULL, Address))
- {
- SWAPENTRY SwapEntry;
-
- MmDeletePageFileMapping(Process, Address, &SwapEntry);
- Status = MmReadFromSwapPage(SwapEntry, Page);
- if (!NT_SUCCESS(Status))
- {
- KeBugCheck(MEMORY_MANAGEMENT);
- }
- MmSetSavedSwapEntryPage(Page, SwapEntry);
- }
-
- /*
+ if (MmIsPageSwapEntry(NULL, Address))
+ {
+ SWAPENTRY SwapEntry;
+
+ MmDeletePageFileMapping(Process, Address, &SwapEntry);
+ Status = MmReadFromSwapPage(SwapEntry, Page);
+ if (!NT_SUCCESS(Status))
+ {
+ KeBugCheck(MEMORY_MANAGEMENT);
+ }
+ MmSetSavedSwapEntryPage(Page, SwapEntry);
+ }
+
+ /*
* Set the page. If we fail because we are out of memory then
* try again
*/
- Status = MmCreateVirtualMapping(Process,
- (PVOID)PAGE_ROUND_DOWN(Address),
- Region->Protect,
- &Page,
- 1);
- while (Status == STATUS_NO_MEMORY)
- {
- MmUnlockAddressSpace(AddressSpace);
- Status = MmCreateVirtualMapping(Process,
- Address,
- Region->Protect,
- &Page,
- 1);
- MmLockAddressSpace(AddressSpace);
- }
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("MmCreateVirtualMapping failed, not out of memory\n");
- KeBugCheck(MEMORY_MANAGEMENT);
- return(Status);
- }
-
- /*
+ Status = MmCreateVirtualMapping(Process,
+ (PVOID)PAGE_ROUND_DOWN(Address),
+ Region->Protect,
+ &Page,
+ 1);
+ while (Status == STATUS_NO_MEMORY)
+ {
+ MmUnlockAddressSpace(AddressSpace);
+ Status = MmCreateVirtualMapping(Process,
+ Address,
+ Region->Protect,
+ &Page,
+ 1);
+ MmLockAddressSpace(AddressSpace);
+ }
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("MmCreateVirtualMapping failed, not out of memory\n");
+ KeBugCheck(MEMORY_MANAGEMENT);
+ return(Status);
+ }
+
+ /*
* Add the page to the process's working set
*/
- MmInsertRmap(Page, Process, (PVOID)PAGE_ROUND_DOWN(Address));
-
- /*
+ MmInsertRmap(Page, Process, (PVOID)PAGE_ROUND_DOWN(Address));
+
+ /*
* Finish the operation
*/
- PageOp->Status = STATUS_SUCCESS;
- KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
- MmReleasePageOp(PageOp);
- return(STATUS_SUCCESS);
+ PageOp->Status = STATUS_SUCCESS;
+ KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
+ MmReleasePageOp(PageOp);
+ return(STATUS_SUCCESS);
}
static VOID
MmModifyAttributes(PMMSUPPORT AddressSpace,
- PVOID BaseAddress,
- SIZE_T RegionSize,
- ULONG OldType,
- ULONG OldProtect,
- ULONG NewType,
- ULONG NewProtect)
+ PVOID BaseAddress,
+ SIZE_T RegionSize,
+ ULONG OldType,
+ ULONG OldProtect,
+ ULONG NewType,
+ ULONG NewProtect)
/*
- * FUNCTION: Modify the attributes of a memory region
- */
+* FUNCTION: Modify the attributes of a memory region
+*/
{
- PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
+ PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
- /*
+ /*
* 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++)
- {
- PFN_NUMBER Page;
-
- if (MmIsPageSwapEntry(Process,
- (char*)BaseAddress + (i * PAGE_SIZE)))
- {
- SWAPENTRY SwapEntry;
-
- MmDeletePageFileMapping(Process,
- (char*)BaseAddress + (i * PAGE_SIZE),
- &SwapEntry);
- MmFreeSwapPage(SwapEntry);
- }
- else
- {
- MmDeleteVirtualMapping(Process,
- (char*)BaseAddress + (i*PAGE_SIZE),
- FALSE, NULL, &Page);
- if (Page != 0)
+ if (NewType == MEM_RESERVE && OldType == MEM_COMMIT)
+ {
+ ULONG i;
+
+ for (i=0; i < PAGE_ROUND_UP(RegionSize)/PAGE_SIZE; i++)
+ {
+ PFN_NUMBER Page;
+
+ if (MmIsPageSwapEntry(Process,
+ (char*)BaseAddress + (i * PAGE_SIZE)))
{
- SWAPENTRY SavedSwapEntry;
- SavedSwapEntry = MmGetSavedSwapEntryPage(Page);
- if (SavedSwapEntry != 0)
- {
- MmFreeSwapPage(SavedSwapEntry);
- MmSetSavedSwapEntryPage(Page, 0);
- }
- MmDeleteRmap(Page, Process,
- (char*)BaseAddress + (i * PAGE_SIZE));
- MmReleasePageMemoryConsumer(MC_USER, Page);
+ SWAPENTRY SwapEntry;
+
+ MmDeletePageFileMapping(Process,
+ (char*)BaseAddress + (i * PAGE_SIZE),
+ &SwapEntry);
+ MmFreeSwapPage(SwapEntry);
}
- }
- }
- }
-
- /*
+ else
+ {
+ MmDeleteVirtualMapping(Process,
+ (char*)BaseAddress + (i*PAGE_SIZE),
+ FALSE, NULL, &Page);
+ if (Page != 0)
+ {
+ SWAPENTRY SavedSwapEntry;
+ SavedSwapEntry = MmGetSavedSwapEntryPage(Page);
+ if (SavedSwapEntry != 0)
+ {
+ MmFreeSwapPage(SavedSwapEntry);
+ MmSetSavedSwapEntryPage(Page, 0);
+ }
+ MmDeleteRmap(Page, Process,
+ (char*)BaseAddress + (i * PAGE_SIZE));
+ MmReleasePageMemoryConsumer(MC_USER, Page);
+ }
+ }
+ }
+ }
+
+ /*
* 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(Process,
- (char*)BaseAddress + (i*PAGE_SIZE)))
- {
- MmSetPageProtect(Process,
- (char*)BaseAddress + (i*PAGE_SIZE),
- NewProtect);
- }
- }
- }
+ if (NewType == MEM_COMMIT && OldType == MEM_COMMIT &&
+ OldProtect != NewProtect)
+ {
+ ULONG i;
+
+ for (i=0; i < PAGE_ROUND_UP(RegionSize)/PAGE_SIZE; i++)
+ {
+ if (MmIsPagePresent(Process,
+ (char*)BaseAddress + (i*PAGE_SIZE)))
+ {
+ MmSetPageProtect(Process,
+ (char*)BaseAddress + (i*PAGE_SIZE),
+ NewProtect);
+ }
+ }
+ }
}
NTSTATUS NTAPI
MiProtectVirtualMemory(IN PEPROCESS Process,
- IN OUT PVOID *BaseAddress,
- IN OUT PSIZE_T NumberOfBytesToProtect,
- IN ULONG NewAccessProtection,
- OUT PULONG OldAccessProtection OPTIONAL)
+ IN OUT PVOID *BaseAddress,
+ IN OUT PSIZE_T NumberOfBytesToProtect,
+ IN ULONG NewAccessProtection,
+ OUT PULONG OldAccessProtection OPTIONAL)
{
PMEMORY_AREA MemoryArea;
PMMSUPPORT AddressSpace;
@@ -462,20 +462,20 @@
}
if (OldAccessProtection == NULL)
- OldAccessProtection = &OldAccessProtection_;
+ OldAccessProtection = &OldAccessProtection_;
if (MemoryArea->Type == MEMORY_AREA_VIRTUAL_MEMORY)
{
Status = MmProtectAnonMem(AddressSpace, MemoryArea, *BaseAddress,
- *NumberOfBytesToProtect, NewAccessProtection,
- OldAccessProtection);
+ *NumberOfBytesToProtect, NewAccessProtection,
+ OldAccessProtection);
}
else if (MemoryArea->Type == MEMORY_AREA_SECTION_VIEW)
{
Status = MmProtectSectionView(AddressSpace, MemoryArea, *BaseAddress,
- *NumberOfBytesToProtect,
- NewAccessProtection,
- OldAccessProtection);
+ *NumberOfBytesToProtect,
+ NewAccessProtection,
+ OldAccessProtection);
}
else
{
@@ -489,28 +489,28 @@
}
/*
- * @implemented
- */
+* @implemented
+*/
NTSTATUS
NTAPI
NtAllocateVirtualMemory(IN HANDLE ProcessHandle,
- IN OUT PVOID* UBaseAddress,
- IN ULONG_PTR ZeroBits,
- IN OUT PSIZE_T URegionSize,
- IN ULONG AllocationType,
- IN ULONG Protect)
+ IN OUT PVOID* UBaseAddress,
+ IN ULONG_PTR ZeroBits,
+ IN OUT PSIZE_T URegionSize,
+ IN ULONG AllocationType,
+ IN ULONG Protect)
{
- PEPROCESS Process;
- MEMORY_AREA* MemoryArea;
- ULONG_PTR MemoryAreaLength;
- ULONG Type;
- NTSTATUS Status;
- PMMSUPPORT AddressSpace;
- PVOID BaseAddress;
- ULONG RegionSize;
- PVOID PBaseAddress;
- ULONG_PTR PRegionSize;
- PHYSICAL_ADDRESS BoundaryAddressMultiple;
+ PEPROCESS Process;
+ MEMORY_AREA* MemoryArea;
+ ULONG_PTR MemoryAreaLength;
+ ULONG Type;
+ NTSTATUS Status;
+ PMMSUPPORT AddressSpace;
+ PVOID BaseAddress;
+ ULONG RegionSize;
+ PVOID PBaseAddress;
+ ULONG_PTR PRegionSize;
+ PHYSICAL_ADDRESS BoundaryAddressMultiple;
PEPROCESS CurrentProcess = PsGetCurrentProcess();
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
KAPC_STATE ApcState;
@@ -528,7 +528,7 @@
/* Check for valid Allocation Types */
if ((AllocationType & ~(MEM_COMMIT | MEM_RESERVE | MEM_RESET | MEM_PHYSICAL |
- MEM_TOP_DOWN | MEM_WRITE_WATCH)))
+ MEM_TOP_DOWN | MEM_WRITE_WATCH)))
{
DPRINT1("Invalid Allocation Type\n");
return STATUS_INVALID_PARAMETER_5;
@@ -659,11 +659,11 @@
{
/* Reference the handle for correct permissions */
Status = ObReferenceObjectByHandle(ProcessHandle,
- PROCESS_VM_OPERATION,
- PsProcessType,
- PreviousMode,
- (PVOID*)&Process,
- NULL);
+ PROCESS_VM_OPERATION,
+ PsProcessType,
+ PreviousMode,
+ (PVOID*)&Process,
+ NULL);
if (!NT_SUCCESS(Status)) return Status;
/* Check if not running in the current process */
@@ -688,297 +688,297 @@
}
}
- BaseAddress = (PVOID)PAGE_ROUND_DOWN(PBaseAddress);
- RegionSize = PAGE_ROUND_UP((ULONG_PTR)PBaseAddress + PRegionSize) -
- PAGE_ROUND_DOWN(PBaseAddress);
-
-
- /*
+ BaseAddress = (PVOID)PAGE_ROUND_DOWN(PBaseAddress);
+ RegionSize = PAGE_ROUND_UP((ULONG_PTR)PBaseAddress + PRegionSize) -
+ PAGE_ROUND_DOWN(PBaseAddress);
+
+
+ /*
* Copy on Write is reserved for system use. This case is a certain failure
* but there may be other cases...needs more testing
*/
- if ((!BaseAddress || (AllocationType & MEM_RESERVE)) &&
- (Protect & (PAGE_WRITECOPY | PAGE_EXECUTE_WRITECOPY)))
- {
- DPRINT1("Copy on write is not supported by VirtualAlloc\n");
- return STATUS_INVALID_PAGE_PROTECTION;
- }
-
- Type = (AllocationType & MEM_COMMIT) ? MEM_COMMIT : MEM_RESERVE;
- DPRINT("Type %x\n", Type);
-
- AddressSpace = &Process->Vm;
- MmLockAddressSpace(AddressSpace);
-
- if (PBaseAddress != 0)
- {
- MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, BaseAddress);
-
- if (MemoryArea != NULL)
- {
- MemoryAreaLength = (ULONG_PTR)MemoryArea->EndingAddress -
- (ULONG_PTR)MemoryArea->StartingAddress;
-
- if (((ULONG_PTR)BaseAddress + RegionSize) >
(ULONG_PTR)MemoryArea->EndingAddress)
- {
- DPRINT("BaseAddress + RegionSize %x is larger than MemoryArea's
EndingAddress %x\n",
- (ULONG_PTR)BaseAddress + RegionSize, MemoryArea->EndingAddress);
-
- MmUnlockAddressSpace(AddressSpace);
- if (Attached) KeUnstackDetachProcess(&ApcState);
- if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process);
- return STATUS_MEMORY_NOT_ALLOCATED;
- }
-
- if (AllocationType == MEM_RESET)
- {
- if (MmIsPagePresent(Process, BaseAddress))
+ if ((!BaseAddress || (AllocationType & MEM_RESERVE)) &&
+ (Protect & (PAGE_WRITECOPY | PAGE_EXECUTE_WRITECOPY)))
+ {
+ DPRINT1("Copy on write is not supported by VirtualAlloc\n");
+ return STATUS_INVALID_PAGE_PROTECTION;
+ }
+
+ Type = (AllocationType & MEM_COMMIT) ? MEM_COMMIT : MEM_RESERVE;
+ DPRINT("Type %x\n", Type);
+
+ AddressSpace = &Process->Vm;
+ MmLockAddressSpace(AddressSpace);
+
+ if (PBaseAddress != 0)
+ {
+ MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, BaseAddress);
+
+ if (MemoryArea != NULL)
+ {
+ MemoryAreaLength = (ULONG_PTR)MemoryArea->EndingAddress -
+ (ULONG_PTR)MemoryArea->StartingAddress;
+
+ if (((ULONG_PTR)BaseAddress + RegionSize) >
(ULONG_PTR)MemoryArea->EndingAddress)
{
- /* FIXME: mark pages as not modified */
+ DPRINT("BaseAddress + RegionSize %x is larger than MemoryArea's
EndingAddress %x\n",
+ (ULONG_PTR)BaseAddress + RegionSize, MemoryArea->EndingAddress);
+
+ MmUnlockAddressSpace(AddressSpace);
+ if (Attached) KeUnstackDetachProcess(&ApcState);
+ if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process);
+ return STATUS_MEMORY_NOT_ALLOCATED;
+ }
+
+ if (AllocationType == MEM_RESET)
+ {
+ if (MmIsPagePresent(Process, BaseAddress))
+ {
+ /* FIXME: mark pages as not modified */
+ }
+ else
+ {
+ /* FIXME: if pages are in paging file discard them and bring in pages
of zeros */
+ }
+
+ MmUnlockAddressSpace(AddressSpace);
+ if (Attached) KeUnstackDetachProcess(&ApcState);
+ if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process);
+
+ /* MEM_RESET does not modify any attributes of region */
+ return STATUS_SUCCESS;
+ }
+
+ if (MemoryArea->Type == MEMORY_AREA_VIRTUAL_MEMORY &&
+ MemoryAreaLength >= RegionSize)
+ {
+ Status =
+ MmAlterRegion(AddressSpace,
+ MemoryArea->StartingAddress,
+ &MemoryArea->Data.VirtualMemoryData.RegionListHead,
+ BaseAddress, RegionSize,
+ Type, Protect, MmModifyAttributes);
+ MmUnlockAddressSpace(AddressSpace);
+ if (Attached) KeUnstackDetachProcess(&ApcState);
+ if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process);
+ DPRINT("NtAllocateVirtualMemory() = %x\n",Status);
+
+ /* Give the caller rounded BaseAddress and area length */
+ if (NT_SUCCESS(Status))
+ {
+ *UBaseAddress = BaseAddress;
+ *URegionSize = RegionSize;
+ DPRINT("*UBaseAddress %x *URegionSize %x\n", BaseAddress,
RegionSize);
+ }
+
+ return(Status);
+ }
+ else if (MemoryAreaLength >= RegionSize)
+ {
+ /* Region list initialized? */
+ if (MemoryArea->Data.SectionData.RegionListHead.Flink)
+ {
+ Status =
+ MmAlterRegion(AddressSpace,
+ MemoryArea->StartingAddress,
+ &MemoryArea->Data.SectionData.RegionListHead,
+ BaseAddress, RegionSize,
+ Type, Protect, MmModifyAttributes);
+ }
+ else
+ {
+ Status = STATUS_ACCESS_VIOLATION;
+ }
+
+ MmUnlockAddressSpace(AddressSpace);
+ if (Attached) KeUnstackDetachProcess(&ApcState);
+ if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process);
+ DPRINT("NtAllocateVirtualMemory() = %x\n",Status);
+
+ /* Give the caller rounded BaseAddress and area length */
+ if (NT_SUCCESS(Status))
+ {
+ *UBaseAddress = BaseAddress;
+ *URegionSize = RegionSize;
+ DPRINT("*UBaseAddress %x *URegionSize %x\n", BaseAddress,
RegionSize);
+ }
+
+ return(Status);
}
else
{
- /* FIXME: if pages are in paging file discard them and bring in pages of
zeros */
+ MmUnlockAddressSpace(AddressSpace);
+ if (Attached) KeUnstackDetachProcess(&ApcState);
+ if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process);
+ return(STATUS_UNSUCCESSFUL);
}
-
- MmUnlockAddressSpace(AddressSpace);
- if (Attached) KeUnstackDetachProcess(&ApcState);
- if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process);
-
- /* MEM_RESET does not modify any attributes of region */
- return STATUS_SUCCESS;
- }
-
- if (MemoryArea->Type == MEMORY_AREA_VIRTUAL_MEMORY &&
- MemoryAreaLength >= RegionSize)
- {
- Status =
- MmAlterRegion(AddressSpace,
- MemoryArea->StartingAddress,
- &MemoryArea->Data.VirtualMemoryData.RegionListHead,
- BaseAddress, RegionSize,
- Type, Protect, MmModifyAttributes);
- MmUnlockAddressSpace(AddressSpace);
- if (Attached) KeUnstackDetachProcess(&ApcState);
- if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process);
- DPRINT("NtAllocateVirtualMemory() = %x\n",Status);
-
- /* Give the caller rounded BaseAddress and area length */
- if (NT_SUCCESS(Status))
- {
- *UBaseAddress = BaseAddress;
- *URegionSize = RegionSize;
- DPRINT("*UBaseAddress %x *URegionSize %x\n", BaseAddress,
RegionSize);
- }
-
- return(Status);
- }
- else if (MemoryAreaLength >= RegionSize)
- {
- /* Region list initialized? */
- if (MemoryArea->Data.SectionData.RegionListHead.Flink)
- {
- Status =
- MmAlterRegion(AddressSpace,
- MemoryArea->StartingAddress,
- &MemoryArea->Data.SectionData.RegionListHead,
- BaseAddress, RegionSize,
- Type, Protect, MmModifyAttributes);
- }
- else
- {
- Status = STATUS_ACCESS_VIOLATION;
- }
-
- MmUnlockAddressSpace(AddressSpace);
- if (Attached) KeUnstackDetachProcess(&ApcState);
- if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process);
- DPRINT("NtAllocateVirtualMemory() = %x\n",Status);
-
- /* Give the caller rounded BaseAddress and area length */
- if (NT_SUCCESS(Status))
- {
- *UBaseAddress = BaseAddress;
- *URegionSize = RegionSize;
- DPRINT("*UBaseAddress %x *URegionSize %x\n", BaseAddress,
RegionSize);
- }
-
- return(Status);
- }
- else
- {
- MmUnlockAddressSpace(AddressSpace);
- if (Attached) KeUnstackDetachProcess(&ApcState);
- if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process);
- return(STATUS_UNSUCCESSFUL);
- }
- }
- }
-
- Status = MmCreateMemoryArea(AddressSpace,
- MEMORY_AREA_VIRTUAL_MEMORY,
- &BaseAddress,
- RegionSize,
- Protect,
- &MemoryArea,
- PBaseAddress != 0,
- AllocationType & MEM_TOP_DOWN,
- BoundaryAddressMultiple);
- if (!NT_SUCCESS(Status))
- {
- MmUnlockAddressSpace(AddressSpace);
- if (Attached) KeUnstackDetachProcess(&ApcState);
- if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process);
- DPRINT("NtAllocateVirtualMemory() = %x\n",Status);
- return(Status);
- }
-
- MemoryAreaLength = (ULONG_PTR)MemoryArea->EndingAddress -
- (ULONG_PTR)MemoryArea->StartingAddress;
-
- MmInitializeRegion(&MemoryArea->Data.VirtualMemoryData.RegionListHead,
- MemoryAreaLength, Type, Protect);
-
- if ((AllocationType & MEM_COMMIT) &&
- (Protect & (PAGE_READWRITE | PAGE_EXECUTE_READWRITE)))
- {
- const ULONG nPages = PAGE_ROUND_UP(MemoryAreaLength) >> PAGE_SHIFT;
- MmReserveSwapPages(nPages);
- }
-
- MmUnlockAddressSpace(AddressSpace);
- if (Attached) KeUnstackDetachProcess(&ApcState);
- if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process);
-
- *UBaseAddress = BaseAddress;
- *URegionSize = MemoryAreaLength;
- DPRINT("*UBaseAddress %x *URegionSize %x\n", BaseAddress, RegionSize);
-
- return(STATUS_SUCCESS);
+ }
+ }
+
+ Status = MmCreateMemoryArea(AddressSpace,
+ MEMORY_AREA_VIRTUAL_MEMORY,
+ &BaseAddress,
+ RegionSize,
+ Protect,
+ &MemoryArea,
+ PBaseAddress != 0,
+ AllocationType & MEM_TOP_DOWN,
+ BoundaryAddressMultiple);
+ if (!NT_SUCCESS(Status))
+ {
+ MmUnlockAddressSpace(AddressSpace);
+ if (Attached) KeUnstackDetachProcess(&ApcState);
+ if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process);
+ DPRINT("NtAllocateVirtualMemory() = %x\n",Status);
+ return(Status);
+ }
+
+ MemoryAreaLength = (ULONG_PTR)MemoryArea->EndingAddress -
+ (ULONG_PTR)MemoryArea->StartingAddress;
+
+ MmInitializeRegion(&MemoryArea->Data.VirtualMemoryData.RegionListHead,
+ MemoryAreaLength, Type, Protect);
+
+ if ((AllocationType & MEM_COMMIT) &&
+ (Protect & (PAGE_READWRITE | PAGE_EXECUTE_READWRITE)))
+ {
+ const ULONG nPages = PAGE_ROUND_UP(MemoryAreaLength) >> PAGE_SHIFT;
+ MmReserveSwapPages(nPages);
+ }
+
+ MmUnlockAddressSpace(AddressSpace);
+ if (Attached) KeUnstackDetachProcess(&ApcState);
+ if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process);
+
+ *UBaseAddress = BaseAddress;
+ *URegionSize = MemoryAreaLength;
+ DPRINT("*UBaseAddress %x *URegionSize %x\n", BaseAddress, RegionSize);
+
+ return(STATUS_SUCCESS);
}
static VOID
MmFreeVirtualMemoryPage(PVOID Context,
- MEMORY_AREA* MemoryArea,
- PVOID Address,
- PFN_NUMBER Page,
- SWAPENTRY SwapEntry,
- BOOLEAN Dirty)
+ MEMORY_AREA* MemoryArea,
+ PVOID Address,
+ PFN_NUMBER Page,
+ SWAPENTRY SwapEntry,
+ BOOLEAN Dirty)
{
- PEPROCESS Process = (PEPROCESS)Context;
-
- if (Page != 0)
- {
- SWAPENTRY SavedSwapEntry;
- SavedSwapEntry = MmGetSavedSwapEntryPage(Page);
- if (SavedSwapEntry != 0)
- {
- MmFreeSwapPage(SavedSwapEntry);
- MmSetSavedSwapEntryPage(Page, 0);
- }
- MmDeleteRmap(Page, Process, Address);
- MmReleasePageMemoryConsumer(MC_USER, Page);
- }
- else if (SwapEntry != 0)
- {
- MmFreeSwapPage(SwapEntry);
- }
+ PEPROCESS Process = (PEPROCESS)Context;
+
+ if (Page != 0)
+ {
+ SWAPENTRY SavedSwapEntry;
+ SavedSwapEntry = MmGetSavedSwapEntryPage(Page);
+ if (SavedSwapEntry != 0)
+ {
+ MmFreeSwapPage(SavedSwapEntry);
+ MmSetSavedSwapEntryPage(Page, 0);
+ }
+ MmDeleteRmap(Page, Process, Address);
+ MmReleasePageMemoryConsumer(MC_USER, Page);
+ }
+ else if (SwapEntry != 0)
+ {
+ MmFreeSwapPage(SwapEntry);
+ }
}
VOID
NTAPI
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;
+
+ 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)
- {
- ULONG_PTR MemoryAreaLength = (ULONG_PTR)MemoryArea->EndingAddress -
- (ULONG_PTR)MemoryArea->StartingAddress;
- const ULONG nPages = PAGE_ROUND_UP(MemoryAreaLength) >> PAGE_SHIFT;
-
- for (i = 0; i < nPages && MemoryArea->PageOpCount != 0; ++i)
- {
- PMM_PAGEOP PageOp;
- PageOp = MmCheckForPageOp(MemoryArea, Process->UniqueProcessId,
- (PVOID)((ULONG_PTR)MemoryArea->StartingAddress + (i
* PAGE_SIZE)),
- NULL, 0);
- if (PageOp != NULL)
- {
- NTSTATUS Status;
- MmUnlockAddressSpace(&Process->Vm);
- Status = KeWaitForSingleObject(&PageOp->CompletionEvent,
- 0,
- KernelMode,
- FALSE,
- NULL);
- if (Status != STATUS_SUCCESS)
+ if (MemoryArea->PageOpCount > 0)
+ {
+ ULONG_PTR MemoryAreaLength = (ULONG_PTR)MemoryArea->EndingAddress -
+ (ULONG_PTR)MemoryArea->StartingAddress;
+ const ULONG nPages = PAGE_ROUND_UP(MemoryAreaLength) >> PAGE_SHIFT;
+
+ for (i = 0; i < nPages && MemoryArea->PageOpCount != 0; ++i)
+ {
+ PMM_PAGEOP PageOp;
+ PageOp = MmCheckForPageOp(MemoryArea, Process->UniqueProcessId,
+ (PVOID)((ULONG_PTR)MemoryArea->StartingAddress + (i * PAGE_SIZE)),
+ NULL, 0);
+ if (PageOp != NULL)
{
- DPRINT1("Failed to wait for page op\n");
- KeBugCheck(MEMORY_MANAGEMENT);
+ NTSTATUS Status;
+ MmUnlockAddressSpace(&Process->Vm);
+ Status = KeWaitForSingleObject(&PageOp->CompletionEvent,
+ 0,
+ KernelMode,
+ FALSE,
+ NULL);
+ if (Status != STATUS_SUCCESS)
+ {
+ DPRINT1("Failed to wait for page op\n");
+ KeBugCheck(MEMORY_MANAGEMENT);
+ }
+ MmLockAddressSpace(&Process->Vm);
+ MmReleasePageOp(PageOp);
}
- MmLockAddressSpace(&Process->Vm);
- 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->Vm,
- MemoryArea,
- MmFreeVirtualMemoryPage,
- (PVOID)Process);
+ }
+ }
+
+ /* 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->Vm,
+ MemoryArea,
+ MmFreeVirtualMemoryPage,
+ (PVOID)Process);
}
/*
- * @implemented
- */
+* @implemented
+*/
NTSTATUS NTAPI
NtFreeVirtualMemory(IN HANDLE ProcessHandle,
- IN PVOID* UBaseAddress,
- IN PSIZE_T URegionSize,
- IN ULONG FreeType)
+ IN PVOID* UBaseAddress,
+ IN PSIZE_T URegionSize,
+ IN ULONG FreeType)
/*
- * FUNCTION: Frees a range of virtual memory
- * ARGUMENTS:
- * ProcessHandle = Points to the process that allocated the virtual
- * memory
- * BaseAddress = Points to the memory address, rounded down to a
- * multiple of the pagesize
- * RegionSize = Limits the range to free, rounded up to a multiple of
- * the paging size
- * FreeType = Can be one of the values: MEM_DECOMMIT, or MEM_RELEASE
- * RETURNS: Status
- */
+* FUNCTION: Frees a range of virtual memory
+* ARGUMENTS:
+* ProcessHandle = Points to the process that allocated the virtual
+* memory
+* BaseAddress = Points to the memory address, rounded down to a
+* multiple of the pagesize
+* RegionSize = Limits the range to free, rounded up to a multiple of
+* the paging size
+* FreeType = Can be one of the values: MEM_DECOMMIT, or MEM_RELEASE
+* RETURNS: Status
+*/
{
- MEMORY_AREA* MemoryArea;
- NTSTATUS Status;
- PEPROCESS Process;
- PMMSUPPORT AddressSpace;
- PVOID BaseAddress, PBaseAddress;
- SIZE_T RegionSize, PRegionSize;
+ MEMORY_AREA* MemoryArea;
+ NTSTATUS Status;
+ PEPROCESS Process;
+ PMMSUPPORT AddressSpace;
+ PVOID BaseAddress, PBaseAddress;
+ SIZE_T RegionSize, PRegionSize;
PEPROCESS CurrentProcess = PsGetCurrentProcess();
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
KAPC_STATE ApcState;
@@ -991,15 +991,15 @@
DPRINT1("Invalid FreeType\n");
return STATUS_INVALID_PARAMETER_4;
}
-
+
/* Check if no flag was used, or if both flags were used */
if (!((FreeType & (MEM_DECOMMIT | MEM_RELEASE))) ||
- ((FreeType & (MEM_DECOMMIT | MEM_RELEASE)) == (MEM_DECOMMIT |
MEM_RELEASE)))
+ ((FreeType & (MEM_DECOMMIT | MEM_RELEASE)) == (MEM_DECOMMIT |
MEM_RELEASE)))
{
DPRINT1("Invalid FreeType combination\n");
return STATUS_INVALID_PARAMETER_4;
}
-
+
/* Enter SEH */
_SEH2_TRY
{
@@ -1010,7 +1010,7 @@
ProbeForWritePointer(UBaseAddress);
ProbeForWriteUlong(URegionSize);
}
-
+
/* Capture their values */
PBaseAddress = *UBaseAddress;
PRegionSize = *URegionSize;
@@ -1021,180 +1021,180 @@
_SEH2_YIELD(return _SEH2_GetExceptionCode());
}
_SEH2_END;
-
+
/* Make sure the allocation isn't past the user area */
if (PBaseAddress >= MM_HIGHEST_USER_ADDRESS)
{
DPRINT1("Virtual free base above User Space\n");
return STATUS_INVALID_PARAMETER_2;
}
-
- /* Make sure the allocation wouldn't overflow past the user area */
- if (((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (ULONG_PTR)PBaseAddress) < PRegionSize)
- {
- DPRINT1("Region size would overflow into kernel-memory\n");
- return STATUS_INVALID_PARAMETER_3;
- }
-
- /* Check if this is for the current process */
- if (ProcessHandle == NtCurrentProcess())
- {
- /* We already have the current process, no need to go through Ob */
- Process = CurrentProcess;
- }
- else
- {
- /* Reference the handle for correct permissions */
- Status = ObReferenceObjectByHandle(ProcessHandle,
- PROCESS_VM_OPERATION,
- PsProcessType,
- PreviousMode,
- (PVOID*)&Process,
- NULL);
- if (!NT_SUCCESS(Status)) return Status;
-
- /* Check if not running in the current process */
- if (CurrentProcess != Process)
- {
- /* Attach to it */
- KeStackAttachProcess(&Process->Pcb, &ApcState);
- Attached = TRUE;
- }
- }
-
- BaseAddress = (PVOID)PAGE_ROUND_DOWN((PBaseAddress));
- RegionSize = PAGE_ROUND_UP((ULONG_PTR)(PBaseAddress) + (PRegionSize)) -
- PAGE_ROUND_DOWN((PBaseAddress));
-
- AddressSpace = &Process->Vm;
-
- MmLockAddressSpace(AddressSpace);
- MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, BaseAddress);
- if (MemoryArea == NULL)
- {
- Status = STATUS_UNSUCCESSFUL;
- goto unlock_deref_and_return;
- }
-
- switch (FreeType)
- {
- case MEM_RELEASE:
- /* We can only free a memory area in one step. */
- if (MemoryArea->StartingAddress != BaseAddress ||
- MemoryArea->Type != MEMORY_AREA_VIRTUAL_MEMORY)
- {
+
+ /* Make sure the allocation wouldn't overflow past the user area */
+ if (((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (ULONG_PTR)PBaseAddress) < PRegionSize)
+ {
+ DPRINT1("Region size would overflow into kernel-memory\n");
+ return STATUS_INVALID_PARAMETER_3;
+ }
+
+ /* Check if this is for the current process */
+ if (ProcessHandle == NtCurrentProcess())
+ {
+ /* We already have the current process, no need to go through Ob */
+ Process = CurrentProcess;
+ }
+ else
+ {
+ /* Reference the handle for correct permissions */
+ Status = ObReferenceObjectByHandle(ProcessHandle,
+ PROCESS_VM_OPERATION,
+ PsProcessType,
+ PreviousMode,
+ (PVOID*)&Process,
+ NULL);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Check if not running in the current process */
+ if (CurrentProcess != Process)
+ {
+ /* Attach to it */
+ KeStackAttachProcess(&Process->Pcb, &ApcState);
+ Attached = TRUE;
+ }
+ }
+
+ BaseAddress = (PVOID)PAGE_ROUND_DOWN((PBaseAddress));
+ RegionSize = PAGE_ROUND_UP((ULONG_PTR)(PBaseAddress) + (PRegionSize)) -
+ PAGE_ROUND_DOWN((PBaseAddress));
+
+ AddressSpace = &Process->Vm;
+
+ MmLockAddressSpace(AddressSpace);
+ MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, BaseAddress);
+ if (MemoryArea == NULL)
+ {
+ Status = STATUS_UNSUCCESSFUL;
+ goto unlock_deref_and_return;
+ }
+
+ switch (FreeType)
+ {
+ case MEM_RELEASE:
+ /* We can only free a memory area in one step. */
+ if (MemoryArea->StartingAddress != BaseAddress ||
+ MemoryArea->Type != MEMORY_AREA_VIRTUAL_MEMORY)
+ {
Status = STATUS_UNSUCCESSFUL;
goto unlock_deref_and_return;
- }
-
- MmFreeVirtualMemory(Process, MemoryArea);
- Status = STATUS_SUCCESS;
- goto unlock_deref_and_return;
-
- case MEM_DECOMMIT:
- Status =
- MmAlterRegion(AddressSpace,
- MemoryArea->StartingAddress,
- (MemoryArea->Type == MEMORY_AREA_SECTION_VIEW) ?
- &MemoryArea->Data.SectionData.RegionListHead :
- &MemoryArea->Data.VirtualMemoryData.RegionListHead,
- BaseAddress,
- RegionSize,
- MEM_RESERVE,
- PAGE_NOACCESS,
- MmModifyAttributes);
- goto unlock_deref_and_return;
- }
-
- Status = STATUS_NOT_IMPLEMENTED;
-
-unlock_deref_and_return:
-
- MmUnlockAddressSpace(AddressSpace);
- if (Attached) KeUnstackDetachProcess(&ApcState);
- if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process);
-
- return(Status);
+ }
+
+ MmFreeVirtualMemory(Process, MemoryArea);
+ Status = STATUS_SUCCESS;
+ goto unlock_deref_and_return;
+
+ case MEM_DECOMMIT:
+ Status =
+ MmAlterRegion(AddressSpace,
+ MemoryArea->StartingAddress,
+ (MemoryArea->Type == MEMORY_AREA_SECTION_VIEW) ?
+ &MemoryArea->Data.SectionData.RegionListHead :
+ &MemoryArea->Data.VirtualMemoryData.RegionListHead,
+ BaseAddress,
+ RegionSize,
+ MEM_RESERVE,
+ PAGE_NOACCESS,
+ MmModifyAttributes);
+ goto unlock_deref_and_return;
+ }
+
+ Status = STATUS_NOT_IMPLEMENTED;
+
+ unlock_deref_and_return:
+
+ MmUnlockAddressSpace(AddressSpace);
+ if (Attached) KeUnstackDetachProcess(&ApcState);
+ if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process);
+
+ return(Status);
}
NTSTATUS
NTAPI
MmProtectAnonMem(PMMSUPPORT AddressSpace,
- PMEMORY_AREA MemoryArea,
- PVOID BaseAddress,
- SIZE_T Length,
- ULONG Protect,
- PULONG OldProtect)
+ PMEMORY_AREA MemoryArea,
+ PVOID BaseAddress,
+ SIZE_T Length,
+ ULONG Protect,
+ PULONG OldProtect)
{
- PMM_REGION Region;
- NTSTATUS Status = STATUS_SUCCESS;
- ULONG_PTR LengthCount = 0;
-
- /* Search all Regions in MemoryArea up to Length */
- /* Every Region up to Length must be committed for success */
- for (;;)
- {
- Region = MmFindRegion(MemoryArea->StartingAddress,
- &MemoryArea->Data.VirtualMemoryData.RegionListHead,
- (PVOID)((ULONG_PTR)BaseAddress + LengthCount), NULL);
-
- /* If a Region was found and it is committed */
- if ((Region) && (Region->Type == MEM_COMMIT))
- {
- LengthCount += Region->Length;
- if (Length <= LengthCount) break;
- continue;
- }
- /* If Region was found and it is not commited */
- else if (Region)
- {
- Status = STATUS_NOT_COMMITTED;
- break;
- }
- /* If no Region was found at all */
- else if (LengthCount == 0)
- {
- Status = STATUS_INVALID_ADDRESS;
- break;
- }
- }
-
- if (NT_SUCCESS(Status))
- {
- *OldProtect = Region->Protect;
- Status = MmAlterRegion(AddressSpace, MemoryArea->StartingAddress,
- &MemoryArea->Data.VirtualMemoryData.RegionListHead,
- BaseAddress, Length, Region->Type, Protect,
- MmModifyAttributes);
- }
-
- return (Status);
+ PMM_REGION Region;
+ NTSTATUS Status = STATUS_SUCCESS;
+ ULONG_PTR LengthCount = 0;
+
+ /* Search all Regions in MemoryArea up to Length */
+ /* Every Region up to Length must be committed for success */
+ for (;;)
+ {
+ Region = MmFindRegion(MemoryArea->StartingAddress,
+ &MemoryArea->Data.VirtualMemoryData.RegionListHead,
+ (PVOID)((ULONG_PTR)BaseAddress + LengthCount), NULL);
+
+ /* If a Region was found and it is committed */
+ if ((Region) && (Region->Type == MEM_COMMIT))
+ {
+ LengthCount += Region->Length;
+ if (Length <= LengthCount) break;
+ continue;
+ }
+ /* If Region was found and it is not commited */
+ else if (Region)
+ {
+ Status = STATUS_NOT_COMMITTED;
+ break;
+ }
+ /* If no Region was found at all */
+ else if (LengthCount == 0)
+ {
+ Status = STATUS_INVALID_ADDRESS;
+ break;
+ }
+ }
+
+ if (NT_SUCCESS(Status))
+ {
+ *OldProtect = Region->Protect;
+ Status = MmAlterRegion(AddressSpace, MemoryArea->StartingAddress,
+ &MemoryArea->Data.VirtualMemoryData.RegionListHead,
+ BaseAddress, Length, Region->Type, Protect,
+ MmModifyAttributes);
+ }
+
+ return (Status);
}
NTSTATUS NTAPI
MmQueryAnonMem(PMEMORY_AREA MemoryArea,
- PVOID Address,
- PMEMORY_BASIC_INFORMATION Info,
- PSIZE_T ResultLength)
+ PVOID Address,
+ PMEMORY_BASIC_INFORMATION Info,
+ PSIZE_T ResultLength)
{
- PMM_REGION Region;
- PVOID RegionBase = NULL;
-
- Info->BaseAddress = (PVOID)PAGE_ROUND_DOWN(Address);
-
- Region = MmFindRegion(MemoryArea->StartingAddress,
- &MemoryArea->Data.VirtualMemoryData.RegionListHead,
- Address, &RegionBase);
- Info->BaseAddress = RegionBase;
- Info->AllocationBase = MemoryArea->StartingAddress;
- Info->AllocationProtect = MemoryArea->Protect;
- Info->RegionSize = Region->Length;
- Info->State = Region->Type;
- Info->Protect = Region->Protect;
- Info->Type = MEM_PRIVATE;
-
- *ResultLength = sizeof(MEMORY_BASIC_INFORMATION);
- return(STATUS_SUCCESS);
+ PMM_REGION Region;
+ PVOID RegionBase = NULL;
+
+ Info->BaseAddress = (PVOID)PAGE_ROUND_DOWN(Address);
+
+ Region = MmFindRegion(MemoryArea->StartingAddress,
+ &MemoryArea->Data.VirtualMemoryData.RegionListHead,
+ Address, &RegionBase);
+ Info->BaseAddress = RegionBase;
+ Info->AllocationBase = MemoryArea->StartingAddress;
+ Info->AllocationProtect = MemoryArea->Protect;
+ Info->RegionSize = Region->Length;
+ Info->State = Region->Type;
+ Info->Protect = Region->Protect;
+ Info->Type = MEM_PRIVATE;
+
+ *ResultLength = sizeof(MEMORY_BASIC_INFORMATION);
+ return(STATUS_SUCCESS);
}
/* EOF */