-/* $Id$
- *
+/*
* Copyright (C) 2002-2005 ReactOS Team (and the authors from the programmers section)
*
* This program is free software; you can redistribute it and/or
* PURPOSE: Implementing anonymous memory.
*
* PROGRAMMERS: David Welch
- * Hartmut Birr
* Casper Hornstrup
* KJK::Hyperion
* Ge van Geldorp
* Eric Kohl
* Royce Mitchell III
- * Aleksey Bragin
+ * Aleksey Bragin
* Jason Filby
* Art Yerkes
* Gunnar Andre' Dalsnes
* Filip Navara
* Thomas Weidenmueller
* Alex Ionescu
- * Trevor McCort
+ * Trevor McCort
* Steven Edwards
*/
/* FUNCTIONS *****************************************************************/
NTSTATUS
-MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
+NTAPI
+MmWritePageVirtualMemory(PMM_AVL_TABLE AddressSpace,
PMEMORY_AREA MemoryArea,
PVOID Address,
PMM_PAGEOP PageOp)
SWAPENTRY SwapEntry;
PFN_TYPE Page;
NTSTATUS Status;
+ PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
/*
* Check for paging out from a deleted virtual memory area.
return(STATUS_UNSUCCESSFUL);
}
- Page = MmGetPfnForProcess(AddressSpace->Process, Address);
+ Page = MmGetPfnForProcess(Process, Address);
/*
* Get that the page actually is dirty.
*/
- if (!MmIsDirtyPage(AddressSpace->Process, Address))
+ if (!MmIsDirtyPage(Process, Address))
{
PageOp->Status = STATUS_SUCCESS;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
/*
* Speculatively set the mapping to clean.
*/
- MmSetCleanPage(AddressSpace->Process, Address);
+ MmSetCleanPage(Process, Address);
/*
* If necessary, allocate an entry in the paging file for this page
SwapEntry = MmAllocSwapPage();
if (SwapEntry == 0)
{
- MmSetDirtyPage(AddressSpace->Process, Address);
+ MmSetDirtyPage(Process, Address);
PageOp->Status = STATUS_PAGEFILE_QUOTA_EXCEEDED;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
MmReleasePageOp(PageOp);
{
DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n",
Status);
- MmSetDirtyPage(AddressSpace->Process, Address);
+ MmSetDirtyPage(Process, Address);
PageOp->Status = STATUS_UNSUCCESSFUL;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
MmReleasePageOp(PageOp);
}
NTSTATUS
-MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
+NTAPI
+MmPageOutVirtualMemory(PMM_AVL_TABLE AddressSpace,
PMEMORY_AREA MemoryArea,
PVOID Address,
PMM_PAGEOP PageOp)
{
PFN_TYPE Page;
- BOOL WasDirty;
+ BOOLEAN WasDirty;
SWAPENTRY SwapEntry;
NTSTATUS Status;
-
+ PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
+
DPRINT("MmPageOutVirtualMemory(Address 0x%.8X) PID %d\n",
- Address, MemoryArea->Process->UniqueProcessId);
+ Address, Process->UniqueProcessId);
/*
* Check for paging out from a deleted virtual memory area.
/*
* Disable the virtual mapping.
*/
- MmDisableVirtualMapping(AddressSpace->Process, Address,
+ MmDisableVirtualMapping(Process, Address,
&WasDirty, &Page);
if (Page == 0)
*/
if (!WasDirty)
{
- MmDeleteVirtualMapping(AddressSpace->Process, Address, FALSE, NULL, NULL);
+ MmLockAddressSpace(AddressSpace);
+ MmDeleteVirtualMapping(Process, Address, FALSE, NULL, NULL);
MmDeleteAllRmaps(Page, NULL, NULL);
if ((SwapEntry = MmGetSavedSwapEntryPage(Page)) != 0)
{
- MmCreatePageFileMapping(AddressSpace->Process, Address, SwapEntry);
+ MmCreatePageFileMapping(Process, Address, SwapEntry);
MmSetSavedSwapEntryPage(Page, 0);
}
+ MmUnlockAddressSpace(AddressSpace);
MmReleasePageMemoryConsumer(MC_USER, Page);
PageOp->Status = STATUS_SUCCESS;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
if (SwapEntry == 0)
{
MmShowOutOfSpaceMessagePagingFile();
- MmEnableVirtualMapping(AddressSpace->Process, Address);
+ MmEnableVirtualMapping(Process, Address);
PageOp->Status = STATUS_UNSUCCESSFUL;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
MmReleasePageOp(PageOp);
{
DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n",
Status);
- MmEnableVirtualMapping(AddressSpace->Process, Address);
+ MmEnableVirtualMapping(Process, Address);
PageOp->Status = STATUS_UNSUCCESSFUL;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
MmReleasePageOp(PageOp);
* Otherwise we have succeeded, free the page
*/
DPRINT("MM: Swapped out virtual memory page 0x%.8X!\n", Page << PAGE_SHIFT);
- MmDeleteVirtualMapping(AddressSpace->Process, Address, FALSE, NULL, NULL);
- MmCreatePageFileMapping(AddressSpace->Process, Address, SwapEntry);
+ 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);
}
NTSTATUS
-MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
+NTAPI
+MmNotPresentFaultVirtualMemory(PMM_AVL_TABLE AddressSpace,
MEMORY_AREA* MemoryArea,
PVOID Address,
BOOLEAN Locked)
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
/*
* Get or create a page operation
*/
- PageOp = MmGetPageOp(MemoryArea, AddressSpace->Process->UniqueProcessId,
+ PageOp = MmGetPageOp(MemoryArea, Process->UniqueProcessId,
(PVOID)PAGE_ROUND_DOWN(Address), NULL, 0,
MM_PAGEOP_PAGEIN, FALSE);
if (PageOp == NULL)
{
SWAPENTRY SwapEntry;
- MmDeletePageFileMapping(AddressSpace->Process, Address, &SwapEntry);
+ MmDeletePageFileMapping(Process, Address, &SwapEntry);
Status = MmReadFromSwapPage(SwapEntry, Page);
if (!NT_SUCCESS(Status))
{
* Set the page. If we fail because we are out of memory then
* try again
*/
- Status = MmCreateVirtualMapping(AddressSpace->Process,
+ Status = MmCreateVirtualMapping(Process,
(PVOID)PAGE_ROUND_DOWN(Address),
Region->Protect,
&Page,
while (Status == STATUS_NO_MEMORY)
{
MmUnlockAddressSpace(AddressSpace);
- Status = MmCreateVirtualMapping(AddressSpace->Process,
+ Status = MmCreateVirtualMapping(Process,
Address,
Region->Protect,
&Page,
/*
* Add the page to the process's working set
*/
- MmInsertRmap(Page, AddressSpace->Process, (PVOID)PAGE_ROUND_DOWN(Address));
+ MmInsertRmap(Page, Process, (PVOID)PAGE_ROUND_DOWN(Address));
/*
* Finish the operation
return(STATUS_SUCCESS);
}
-VOID STATIC
-MmModifyAttributes(PMADDRESS_SPACE AddressSpace,
+VOID static
+MmModifyAttributes(PMM_AVL_TABLE AddressSpace,
PVOID BaseAddress,
ULONG RegionSize,
ULONG OldType,
* FUNCTION: Modify the attributes of a memory region
*/
{
+ PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
+
/*
* If we are switching a previously committed region to reserved then
* free any allocated pages within the region
{
PFN_TYPE Page;
- if (MmIsPageSwapEntry(AddressSpace->Process,
+ if (MmIsPageSwapEntry(Process,
(char*)BaseAddress + (i * PAGE_SIZE)))
{
SWAPENTRY SwapEntry;
- MmDeletePageFileMapping(AddressSpace->Process,
+ MmDeletePageFileMapping(Process,
(char*)BaseAddress + (i * PAGE_SIZE),
&SwapEntry);
MmFreeSwapPage(SwapEntry);
}
else
{
- MmDeleteVirtualMapping(AddressSpace->Process,
+ MmDeleteVirtualMapping(Process,
(char*)BaseAddress + (i*PAGE_SIZE),
FALSE, NULL, &Page);
if (Page != 0)
MmFreeSwapPage(SavedSwapEntry);
MmSetSavedSwapEntryPage(Page, 0);
}
- MmDeleteRmap(Page, AddressSpace->Process,
+ MmDeleteRmap(Page, Process,
(char*)BaseAddress + (i * PAGE_SIZE));
MmReleasePageMemoryConsumer(MC_USER, Page);
}
for (i=0; i < PAGE_ROUND_UP(RegionSize)/PAGE_SIZE; i++)
{
- if (MmIsPagePresent(AddressSpace->Process,
+ if (MmIsPagePresent(Process,
(char*)BaseAddress + (i*PAGE_SIZE)))
{
- MmSetPageProtect(AddressSpace->Process,
+ MmSetPageProtect(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 PSIZE_T URegionSize,
+ IN ULONG AllocationType,
+ IN ULONG Protect)
/*
* FUNCTION: Allocates a block of virtual memory in the process address space
* ARGUMENTS:
ULONG_PTR MemoryAreaLength;
ULONG Type;
NTSTATUS Status;
- PMADDRESS_SPACE AddressSpace;
+ PMM_AVL_TABLE AddressSpace;
PVOID BaseAddress;
ULONG RegionSize;
PVOID PBaseAddress;
ULONG PRegionSize;
PHYSICAL_ADDRESS BoundaryAddressMultiple;
+ KPROCESSOR_MODE PreviousMode;
+
+ PAGED_CODE();
DPRINT("NtAllocateVirtualMemory(*UBaseAddress %x, "
"ZeroBits %d, *URegionSize %x, AllocationType %x, Protect %x)\n",
*UBaseAddress,ZeroBits,*URegionSize,AllocationType,
Protect);
- /*
- * Check the validity of the parameters
- */
+ /* Check for valid protection flags */
if ((Protect & PAGE_FLAGS_VALID_FROM_USER_MODE) != Protect)
{
- return(STATUS_INVALID_PAGE_PROTECTION);
+ DPRINT1("Invalid page protection\n");
+ return STATUS_INVALID_PAGE_PROTECTION;
+ }
+
+ /* Check for valid Zero bits */
+ if (ZeroBits > 21)
+ {
+ DPRINT1("Too many zero bits\n");
+ return STATUS_INVALID_PARAMETER_3;
+ }
+
+ /* Check for valid Allocation Types */
+ if ((AllocationType & ~(MEM_COMMIT | MEM_RESERVE | MEM_RESET | MEM_PHYSICAL |
+ MEM_TOP_DOWN | MEM_WRITE_WATCH)))
+ {
+ DPRINT1("Invalid Allocation Type\n");
+ return STATUS_INVALID_PARAMETER_5;
+ }
+
+ /* Check for at least one of these Allocation Types to be set */
+ if (!(AllocationType & (MEM_COMMIT | MEM_RESERVE | MEM_RESET)))
+ {
+ DPRINT1("No memory allocation base type\n");
+ return STATUS_INVALID_PARAMETER_5;
+ }
+
+ /* MEM_RESET is an exclusive flag, make sure that is valid too */
+ if ((AllocationType & MEM_RESET) && (AllocationType != MEM_RESET))
+ {
+ DPRINT1("Invalid use of MEM_RESET\n");
+ return STATUS_INVALID_PARAMETER_5;
+ }
+
+ /* MEM_WRITE_WATCH can only be used if MEM_RESERVE is also used */
+ if ((AllocationType & MEM_WRITE_WATCH) && !(AllocationType & MEM_RESERVE))
+ {
+ DPRINT1("MEM_WRITE_WATCH used without MEM_RESERVE\n");
+ return STATUS_INVALID_PARAMETER_5;
}
- if ((AllocationType & (MEM_COMMIT | MEM_RESERVE)) == 0)
+
+ /* MEM_PHYSICAL can only be used with MEM_RESERVE, and can only be R/W */
+ if (AllocationType & MEM_PHYSICAL)
{
- return(STATUS_INVALID_PARAMETER);
+ /* First check for MEM_RESERVE exclusivity */
+ if (AllocationType != (MEM_RESERVE | MEM_PHYSICAL))
+ {
+ DPRINT1("MEM_PHYSICAL used with other flags then MEM_RESERVE or"
+ "MEM_RESERVE was not present at all\n");
+ return STATUS_INVALID_PARAMETER_5;
+ }
+
+ /* Then make sure PAGE_READWRITE is used */
+ if (Protect != PAGE_READWRITE)
+ {
+ DPRINT1("MEM_PHYSICAL used without PAGE_READWRITE\n");
+ return STATUS_INVALID_PAGE_PROTECTION;
+ }
}
- PBaseAddress = *UBaseAddress;
- PRegionSize = *URegionSize;
+ PreviousMode = KeGetPreviousMode();
+
+ _SEH_TRY
+ {
+ if (PreviousMode != KernelMode)
+ {
+ ProbeForWritePointer(UBaseAddress);
+ ProbeForWriteUlong(URegionSize);
+ }
+ PBaseAddress = *UBaseAddress;
+ PRegionSize = *URegionSize;
+ }
+ _SEH_HANDLE
+ {
+ /* Get the exception code */
+ Status = _SEH_GetExceptionCode();
+ _SEH_YIELD(return Status);
+ }
+ _SEH_END;
+
BoundaryAddressMultiple.QuadPart = 0;
BaseAddress = (PVOID)PAGE_ROUND_DOWN(PBaseAddress);
- RegionSize = PAGE_ROUND_UP(PBaseAddress + PRegionSize) -
+ RegionSize = PAGE_ROUND_UP((ULONG_PTR)PBaseAddress + PRegionSize) -
PAGE_ROUND_DOWN(PBaseAddress);
+ /*
+ * We've captured and calculated the data, now do more checks
+ * Yes, MmCreateMemoryArea does similar checks, but they don't return
+ * the right status codes that a caller of this routine would expect.
+ */
+ if ((ULONG_PTR)BaseAddress >= USER_SHARED_DATA)
+ {
+ DPRINT1("Virtual allocation base above User Space\n");
+ return STATUS_INVALID_PARAMETER_2;
+ }
+ if (!RegionSize)
+ {
+ DPRINT1("Region size is invalid (zero)\n");
+ return STATUS_INVALID_PARAMETER_4;
+ }
+ if ((USER_SHARED_DATA - (ULONG_PTR)BaseAddress) < RegionSize)
+ {
+ DPRINT1("Region size would overflow into kernel-memory\n");
+ return STATUS_INVALID_PARAMETER_4;
+ }
+
+ /*
+ * 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;
+ }
+
+
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_VM_OPERATION,
- NULL,
- UserMode,
+ PsProcessType,
+ PreviousMode,
(PVOID*)(&Process),
NULL);
if (!NT_SUCCESS(Status))
Type = (AllocationType & MEM_COMMIT) ? MEM_COMMIT : MEM_RESERVE;
DPRINT("Type %x\n", Type);
- AddressSpace = &Process->AddressSpace;
+ AddressSpace = &Process->VadRoot;
MmLockAddressSpace(AddressSpace);
if (PBaseAddress != 0)
}
else if (MemoryAreaLength >= RegionSize)
{
- Status =
- MmAlterRegion(AddressSpace,
- MemoryArea->StartingAddress,
- &MemoryArea->Data.SectionData.RegionListHead,
- BaseAddress, RegionSize,
- Type, Protect, MmModifyAttributes);
+ /* 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);
ObDereferenceObject(Process);
DPRINT("NtAllocateVirtualMemory() = %x\n",Status);
}
}
- Status = MmCreateMemoryArea(Process,
- AddressSpace,
+ Status = MmCreateMemoryArea(AddressSpace,
MEMORY_AREA_VIRTUAL_MEMORY,
&BaseAddress,
RegionSize,
Protect,
&MemoryArea,
PBaseAddress != 0,
- (AllocationType & MEM_TOP_DOWN) == MEM_TOP_DOWN,
+ AllocationType & MEM_TOP_DOWN,
BoundaryAddressMultiple);
if (!NT_SUCCESS(Status))
{
MemoryAreaLength = (ULONG_PTR)MemoryArea->EndingAddress -
(ULONG_PTR)MemoryArea->StartingAddress;
- MmInitialiseRegion(&MemoryArea->Data.VirtualMemoryData.RegionListHead,
+ MmInitializeRegion(&MemoryArea->Data.VirtualMemoryData.RegionListHead,
MemoryAreaLength, Type, Protect);
if ((AllocationType & MEM_COMMIT) &&
- ((Protect & PAGE_READWRITE) ||
- (Protect & PAGE_EXECUTE_READWRITE)))
+ (Protect & (PAGE_READWRITE | PAGE_EXECUTE_READWRITE)))
{
- MmReserveSwapPages(MemoryAreaLength);
+ const ULONG nPages = PAGE_ROUND_UP(MemoryAreaLength) >> PAGE_SHIFT;
+ MmReserveSwapPages(nPages);
}
*UBaseAddress = BaseAddress;
return(STATUS_SUCCESS);
}
-VOID STATIC
+VOID static
MmFreeVirtualMemoryPage(PVOID Context,
MEMORY_AREA* MemoryArea,
PVOID Address,
}
VOID
+NTAPI
MmFreeVirtualMemory(PEPROCESS Process,
PMEMORY_AREA MemoryArea)
{
{
ULONG_PTR MemoryAreaLength = (ULONG_PTR)MemoryArea->EndingAddress -
(ULONG_PTR)MemoryArea->StartingAddress;
+ const ULONG nPages = PAGE_ROUND_UP(MemoryAreaLength) >> PAGE_SHIFT;
- /* FiN TODO: Optimize loop counter! */
- for (i = 0; i < PAGE_ROUND_UP(MemoryAreaLength) / PAGE_SIZE; i++)
+ for (i = 0; i < nPages && MemoryArea->PageOpCount != 0; ++i)
{
PMM_PAGEOP PageOp;
-
- if (MemoryArea->PageOpCount == 0)
- {
- break;
- }
-
PageOp = MmCheckForPageOp(MemoryArea, Process->UniqueProcessId,
(PVOID)((ULONG_PTR)MemoryArea->StartingAddress + (i * PAGE_SIZE)),
NULL, 0);
if (PageOp != NULL)
{
NTSTATUS Status;
- MmUnlockAddressSpace(&Process->AddressSpace);
+ MmUnlockAddressSpace(&Process->VadRoot);
Status = KeWaitForSingleObject(&PageOp->CompletionEvent,
0,
KernelMode,
DPRINT1("Failed to wait for page op\n");
KEBUGCHECK(0);
}
- MmLockAddressSpace(&Process->AddressSpace);
+ MmLockAddressSpace(&Process->VadRoot);
MmReleasePageOp(PageOp);
}
}
}
/* Actually free the memory area. */
- MmFreeMemoryArea(&Process->AddressSpace,
+ MmFreeMemoryArea(&Process->VadRoot,
MemoryArea,
MmFreeVirtualMemoryPage,
(PVOID)Process);
NTSTATUS STDCALL
NtFreeVirtualMemory(IN HANDLE ProcessHandle,
IN PVOID* PBaseAddress,
- IN PULONG PRegionSize,
+ IN PSIZE_T PRegionSize,
IN ULONG FreeType)
/*
* FUNCTION: Frees a range of virtual memory
MEMORY_AREA* MemoryArea;
NTSTATUS Status;
PEPROCESS Process;
- PMADDRESS_SPACE AddressSpace;
+ PMM_AVL_TABLE AddressSpace;
PVOID BaseAddress;
ULONG RegionSize;
*PRegionSize,FreeType);
BaseAddress = (PVOID)PAGE_ROUND_DOWN((*PBaseAddress));
- RegionSize = PAGE_ROUND_UP((*PBaseAddress) + (*PRegionSize)) -
+ RegionSize = PAGE_ROUND_UP((ULONG_PTR)(*PBaseAddress) + (*PRegionSize)) -
PAGE_ROUND_DOWN((*PBaseAddress));
Status = ObReferenceObjectByHandle(ProcessHandle,
return(Status);
}
- AddressSpace = &Process->AddressSpace;
+ AddressSpace = &Process->VadRoot;
MmLockAddressSpace(AddressSpace);
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, BaseAddress);
if (MemoryArea == NULL)
{
- MmUnlockAddressSpace(AddressSpace);
- ObDereferenceObject(Process);
- return(STATUS_UNSUCCESSFUL);
+ Status = STATUS_UNSUCCESSFUL;
+ goto unlock_deref_and_return;
}
switch (FreeType)
if (MemoryArea->StartingAddress != BaseAddress ||
MemoryArea->Type != MEMORY_AREA_VIRTUAL_MEMORY)
{
- MmUnlockAddressSpace(AddressSpace);
- ObDereferenceObject(Process);
- return(STATUS_UNSUCCESSFUL);
+ Status = STATUS_UNSUCCESSFUL;
+ goto unlock_deref_and_return;
}
+
MmFreeVirtualMemory(Process, MemoryArea);
- MmUnlockAddressSpace(AddressSpace);
- ObDereferenceObject(Process);
- return(STATUS_SUCCESS);
+ Status = STATUS_SUCCESS;
+ goto unlock_deref_and_return;
case MEM_DECOMMIT:
Status =
MEM_RESERVE,
PAGE_NOACCESS,
MmModifyAttributes);
- MmUnlockAddressSpace(AddressSpace);
- ObDereferenceObject(Process);
- return(Status);
+ goto unlock_deref_and_return;
}
+
+ Status = STATUS_NOT_IMPLEMENTED;
+
+unlock_deref_and_return:
+
MmUnlockAddressSpace(AddressSpace);
ObDereferenceObject(Process);
- return(STATUS_NOT_IMPLEMENTED);
+
+ return(Status);
}
NTSTATUS
-MmProtectAnonMem(PMADDRESS_SPACE AddressSpace,
+NTAPI
+MmProtectAnonMem(PMM_AVL_TABLE AddressSpace,
PMEMORY_AREA MemoryArea,
PVOID BaseAddress,
ULONG Length,
PULONG ResultLength)
{
PMM_REGION Region;
- PVOID RegionBase;
+ PVOID RegionBase = NULL;
Info->BaseAddress = (PVOID)PAGE_ROUND_DOWN(Address);
Address, &RegionBase);
Info->BaseAddress = RegionBase;
Info->AllocationBase = MemoryArea->StartingAddress;
- Info->AllocationProtect = MemoryArea->Attributes;
- Info->RegionSize = (char*)RegionBase + Region->Length - (char*)Info->BaseAddress;
+ Info->AllocationProtect = MemoryArea->Protect;
+ Info->RegionSize = Region->Length;
Info->State = Region->Type;
Info->Protect = Region->Protect;
Info->Type = MEM_PRIVATE;