The puzzle of the design decisions behind the React address space structure continues to be troubling (perhaps there was no design?). Every time a process address space is initialized,

the owner process is stored (which we now use to figure out the lowest address). Recall that NULL means kernel, anything else means per-process. This is great, except that after some
painfull header groking, one understands that the PMADDRESS_SPACE structure is actually *not* a separate structure, but embedded within PEPROCESS itself. It is a React-specific structure
(hence the attempts to get rid of it), that seems to have been "overloaded" on top of the VadRoot structure that Windows uses for user-mode memory allocations. To clarify, this structure
is actually embedded inside the process that owns it, except for the kernel address space, which is a global variable. So there's absolutely *no* point in saving a reference to the owner
process, since we'll always be embedded inside it (except for kernel address space).
This patch creates the MmGetAddressSpaceOwner macro which either returns NULL for kernel address space, or uses the CONTAINING_RECORD macro to return the owner (embedded) process. 


svn path=/trunk/; revision=34873
This commit is contained in:
ReactOS Portable Systems Group 2008-07-27 23:53:04 +00:00
parent 908aede2ef
commit 487609a995
5 changed files with 121 additions and 103 deletions

View file

@ -253,7 +253,6 @@ typedef struct _MEMORY_AREA
typedef struct _MADDRESS_SPACE typedef struct _MADDRESS_SPACE
{ {
PMEMORY_AREA MemoryAreaRoot; PMEMORY_AREA MemoryAreaRoot;
PEPROCESS Process;
PEX_PUSH_LOCK Lock; PEX_PUSH_LOCK Lock;
} MADDRESS_SPACE, *PMADDRESS_SPACE; } MADDRESS_SPACE, *PMADDRESS_SPACE;
@ -1588,6 +1587,14 @@ MmUnlockAddressSpace(PMADDRESS_SPACE AddressSpace)
KeLeaveCriticalRegion(); KeLeaveCriticalRegion();
} }
FORCEINLINE
PEPROCESS
MmGetAddressSpaceOwner(IN PMADDRESS_SPACE AddressSpace)
{
if (AddressSpace == &MmKernelAddressSpace) return NULL;
return CONTAINING_RECORD(AddressSpace, EPROCESS, VadRoot);
}
FORCEINLINE FORCEINLINE
PMADDRESS_SPACE PMADDRESS_SPACE
MmGetCurrentAddressSpace(VOID) MmGetCurrentAddressSpace(VOID)

View file

@ -55,6 +55,7 @@ MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
SWAPENTRY SwapEntry; SWAPENTRY SwapEntry;
PFN_TYPE Page; PFN_TYPE Page;
NTSTATUS Status; NTSTATUS Status;
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
/* /*
* Check for paging out from a deleted virtual memory area. * Check for paging out from a deleted virtual memory area.
@ -67,12 +68,12 @@ MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
return(STATUS_UNSUCCESSFUL); return(STATUS_UNSUCCESSFUL);
} }
Page = MmGetPfnForProcess(AddressSpace->Process, Address); Page = MmGetPfnForProcess(Process, Address);
/* /*
* Get that the page actually is dirty. * Get that the page actually is dirty.
*/ */
if (!MmIsDirtyPage(AddressSpace->Process, Address)) if (!MmIsDirtyPage(Process, Address))
{ {
PageOp->Status = STATUS_SUCCESS; PageOp->Status = STATUS_SUCCESS;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
@ -83,7 +84,7 @@ MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
/* /*
* Speculatively set the mapping to clean. * 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 * If necessary, allocate an entry in the paging file for this page
@ -94,7 +95,7 @@ MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
SwapEntry = MmAllocSwapPage(); SwapEntry = MmAllocSwapPage();
if (SwapEntry == 0) if (SwapEntry == 0)
{ {
MmSetDirtyPage(AddressSpace->Process, Address); MmSetDirtyPage(Process, Address);
PageOp->Status = STATUS_PAGEFILE_QUOTA_EXCEEDED; PageOp->Status = STATUS_PAGEFILE_QUOTA_EXCEEDED;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
MmReleasePageOp(PageOp); MmReleasePageOp(PageOp);
@ -110,7 +111,7 @@ MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
{ {
DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n", DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n",
Status); Status);
MmSetDirtyPage(AddressSpace->Process, Address); MmSetDirtyPage(Process, Address);
PageOp->Status = STATUS_UNSUCCESSFUL; PageOp->Status = STATUS_UNSUCCESSFUL;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
MmReleasePageOp(PageOp); MmReleasePageOp(PageOp);
@ -138,9 +139,10 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
BOOLEAN WasDirty; BOOLEAN WasDirty;
SWAPENTRY SwapEntry; SWAPENTRY SwapEntry;
NTSTATUS Status; NTSTATUS Status;
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
DPRINT("MmPageOutVirtualMemory(Address 0x%.8X) PID %d\n", DPRINT("MmPageOutVirtualMemory(Address 0x%.8X) PID %d\n",
Address, AddressSpace->Process->UniqueProcessId); Address, Process->UniqueProcessId);
/* /*
* Check for paging out from a deleted virtual memory area. * Check for paging out from a deleted virtual memory area.
@ -156,7 +158,7 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
/* /*
* Disable the virtual mapping. * Disable the virtual mapping.
*/ */
MmDisableVirtualMapping(AddressSpace->Process, Address, MmDisableVirtualMapping(Process, Address,
&WasDirty, &Page); &WasDirty, &Page);
if (Page == 0) if (Page == 0)
@ -170,11 +172,11 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
if (!WasDirty) if (!WasDirty)
{ {
MmLockAddressSpace(AddressSpace); MmLockAddressSpace(AddressSpace);
MmDeleteVirtualMapping(AddressSpace->Process, Address, FALSE, NULL, NULL); MmDeleteVirtualMapping(Process, Address, FALSE, NULL, NULL);
MmDeleteAllRmaps(Page, NULL, NULL); MmDeleteAllRmaps(Page, NULL, NULL);
if ((SwapEntry = MmGetSavedSwapEntryPage(Page)) != 0) if ((SwapEntry = MmGetSavedSwapEntryPage(Page)) != 0)
{ {
MmCreatePageFileMapping(AddressSpace->Process, Address, SwapEntry); MmCreatePageFileMapping(Process, Address, SwapEntry);
MmSetSavedSwapEntryPage(Page, 0); MmSetSavedSwapEntryPage(Page, 0);
} }
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
@ -195,7 +197,7 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
if (SwapEntry == 0) if (SwapEntry == 0)
{ {
MmShowOutOfSpaceMessagePagingFile(); MmShowOutOfSpaceMessagePagingFile();
MmEnableVirtualMapping(AddressSpace->Process, Address); MmEnableVirtualMapping(Process, Address);
PageOp->Status = STATUS_UNSUCCESSFUL; PageOp->Status = STATUS_UNSUCCESSFUL;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
MmReleasePageOp(PageOp); MmReleasePageOp(PageOp);
@ -211,7 +213,7 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
{ {
DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n", DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n",
Status); Status);
MmEnableVirtualMapping(AddressSpace->Process, Address); MmEnableVirtualMapping(Process, Address);
PageOp->Status = STATUS_UNSUCCESSFUL; PageOp->Status = STATUS_UNSUCCESSFUL;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
MmReleasePageOp(PageOp); MmReleasePageOp(PageOp);
@ -223,8 +225,8 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
*/ */
DPRINT("MM: Swapped out virtual memory page 0x%.8X!\n", Page << PAGE_SHIFT); DPRINT("MM: Swapped out virtual memory page 0x%.8X!\n", Page << PAGE_SHIFT);
MmLockAddressSpace(AddressSpace); MmLockAddressSpace(AddressSpace);
MmDeleteVirtualMapping(AddressSpace->Process, Address, FALSE, NULL, NULL); MmDeleteVirtualMapping(Process, Address, FALSE, NULL, NULL);
MmCreatePageFileMapping(AddressSpace->Process, Address, SwapEntry); MmCreatePageFileMapping(Process, Address, SwapEntry);
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
MmDeleteAllRmaps(Page, NULL, NULL); MmDeleteAllRmaps(Page, NULL, NULL);
MmSetSavedSwapEntryPage(Page, 0); MmSetSavedSwapEntryPage(Page, 0);
@ -255,7 +257,8 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
NTSTATUS Status; NTSTATUS Status;
PMM_REGION Region; PMM_REGION Region;
PMM_PAGEOP PageOp; PMM_PAGEOP PageOp;
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
/* /*
* There is a window between taking the page fault and locking the * There is a window between taking the page fault and locking the
* address space when another thread could load the page so we check * address space when another thread could load the page so we check
@ -292,7 +295,7 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
/* /*
* Get or create a page operation * Get or create a page operation
*/ */
PageOp = MmGetPageOp(MemoryArea, AddressSpace->Process->UniqueProcessId, PageOp = MmGetPageOp(MemoryArea, Process->UniqueProcessId,
(PVOID)PAGE_ROUND_DOWN(Address), NULL, 0, (PVOID)PAGE_ROUND_DOWN(Address), NULL, 0,
MM_PAGEOP_PAGEIN, FALSE); MM_PAGEOP_PAGEIN, FALSE);
if (PageOp == NULL) if (PageOp == NULL)
@ -380,7 +383,7 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
{ {
SWAPENTRY SwapEntry; SWAPENTRY SwapEntry;
MmDeletePageFileMapping(AddressSpace->Process, Address, &SwapEntry); MmDeletePageFileMapping(Process, Address, &SwapEntry);
Status = MmReadFromSwapPage(SwapEntry, Page); Status = MmReadFromSwapPage(SwapEntry, Page);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -393,7 +396,7 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
* Set the page. If we fail because we are out of memory then * Set the page. If we fail because we are out of memory then
* try again * try again
*/ */
Status = MmCreateVirtualMapping(AddressSpace->Process, Status = MmCreateVirtualMapping(Process,
(PVOID)PAGE_ROUND_DOWN(Address), (PVOID)PAGE_ROUND_DOWN(Address),
Region->Protect, Region->Protect,
&Page, &Page,
@ -401,7 +404,7 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
while (Status == STATUS_NO_MEMORY) while (Status == STATUS_NO_MEMORY)
{ {
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
Status = MmCreateVirtualMapping(AddressSpace->Process, Status = MmCreateVirtualMapping(Process,
Address, Address,
Region->Protect, Region->Protect,
&Page, &Page,
@ -418,7 +421,7 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
/* /*
* Add the page to the process's working set * 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 * Finish the operation
@ -445,6 +448,8 @@ MmModifyAttributes(PMADDRESS_SPACE AddressSpace,
* FUNCTION: Modify the attributes of a memory region * FUNCTION: Modify the attributes of a memory region
*/ */
{ {
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
/* /*
* If we are switching a previously committed region to reserved then * If we are switching a previously committed region to reserved then
* free any allocated pages within the region * free any allocated pages within the region
@ -457,19 +462,19 @@ MmModifyAttributes(PMADDRESS_SPACE AddressSpace,
{ {
PFN_TYPE Page; PFN_TYPE Page;
if (MmIsPageSwapEntry(AddressSpace->Process, if (MmIsPageSwapEntry(Process,
(char*)BaseAddress + (i * PAGE_SIZE))) (char*)BaseAddress + (i * PAGE_SIZE)))
{ {
SWAPENTRY SwapEntry; SWAPENTRY SwapEntry;
MmDeletePageFileMapping(AddressSpace->Process, MmDeletePageFileMapping(Process,
(char*)BaseAddress + (i * PAGE_SIZE), (char*)BaseAddress + (i * PAGE_SIZE),
&SwapEntry); &SwapEntry);
MmFreeSwapPage(SwapEntry); MmFreeSwapPage(SwapEntry);
} }
else else
{ {
MmDeleteVirtualMapping(AddressSpace->Process, MmDeleteVirtualMapping(Process,
(char*)BaseAddress + (i*PAGE_SIZE), (char*)BaseAddress + (i*PAGE_SIZE),
FALSE, NULL, &Page); FALSE, NULL, &Page);
if (Page != 0) if (Page != 0)
@ -481,7 +486,7 @@ MmModifyAttributes(PMADDRESS_SPACE AddressSpace,
MmFreeSwapPage(SavedSwapEntry); MmFreeSwapPage(SavedSwapEntry);
MmSetSavedSwapEntryPage(Page, 0); MmSetSavedSwapEntryPage(Page, 0);
} }
MmDeleteRmap(Page, AddressSpace->Process, MmDeleteRmap(Page, Process,
(char*)BaseAddress + (i * PAGE_SIZE)); (char*)BaseAddress + (i * PAGE_SIZE));
MmReleasePageMemoryConsumer(MC_USER, Page); MmReleasePageMemoryConsumer(MC_USER, Page);
} }
@ -500,10 +505,10 @@ MmModifyAttributes(PMADDRESS_SPACE AddressSpace,
for (i=0; i < PAGE_ROUND_UP(RegionSize)/PAGE_SIZE; i++) for (i=0; i < PAGE_ROUND_UP(RegionSize)/PAGE_SIZE; i++)
{ {
if (MmIsPagePresent(AddressSpace->Process, if (MmIsPagePresent(Process,
(char*)BaseAddress + (i*PAGE_SIZE))) (char*)BaseAddress + (i*PAGE_SIZE)))
{ {
MmSetPageProtect(AddressSpace->Process, MmSetPageProtect(Process,
(char*)BaseAddress + (i*PAGE_SIZE), (char*)BaseAddress + (i*PAGE_SIZE),
NewProtect); NewProtect);
} }

View file

@ -43,13 +43,11 @@ MmInitializeAddressSpace(PEPROCESS Process,
if (Process != NULL) if (Process != NULL)
{ {
AddressSpace->Process = Process;
AddressSpace->Lock = (PEX_PUSH_LOCK)&Process->AddressCreationLock; AddressSpace->Lock = (PEX_PUSH_LOCK)&Process->AddressCreationLock;
ExInitializePushLock((PULONG_PTR)AddressSpace->Lock); ExInitializePushLock((PULONG_PTR)AddressSpace->Lock);
} }
else else
{ {
AddressSpace->Process = NULL;
AddressSpace->Lock = (PEX_PUSH_LOCK)&PsGetCurrentProcess()->AddressCreationLock; AddressSpace->Lock = (PEX_PUSH_LOCK)&PsGetCurrentProcess()->AddressCreationLock;
ExInitializePushLock((PULONG_PTR)AddressSpace->Lock); ExInitializePushLock((PULONG_PTR)AddressSpace->Lock);
} }

View file

@ -470,8 +470,8 @@ MmFindGapBottomUp(
ULONG_PTR Length, ULONG_PTR Length,
ULONG_PTR Granularity) ULONG_PTR Granularity)
{ {
PVOID LowestAddress = AddressSpace->Process ? MM_LOWEST_USER_ADDRESS : MmSystemRangeStart; PVOID LowestAddress = MmGetAddressSpaceOwner(AddressSpace) ? MM_LOWEST_USER_ADDRESS : MmSystemRangeStart;
PVOID HighestAddress = AddressSpace->Process ? PVOID HighestAddress = MmGetAddressSpaceOwner(AddressSpace) ?
(PVOID)((ULONG_PTR)MmSystemRangeStart - 1) : (PVOID)MAXULONG_PTR; (PVOID)((ULONG_PTR)MmSystemRangeStart - 1) : (PVOID)MAXULONG_PTR;
PVOID AlignedAddress; PVOID AlignedAddress;
PMEMORY_AREA Node; PMEMORY_AREA Node;
@ -548,8 +548,8 @@ MmFindGapTopDown(
ULONG_PTR Length, ULONG_PTR Length,
ULONG_PTR Granularity) ULONG_PTR Granularity)
{ {
PVOID LowestAddress = AddressSpace->Process ? MM_LOWEST_USER_ADDRESS : MmSystemRangeStart; PVOID LowestAddress = MmGetAddressSpaceOwner(AddressSpace) ? MM_LOWEST_USER_ADDRESS : MmSystemRangeStart;
PVOID HighestAddress = AddressSpace->Process ? PVOID HighestAddress = MmGetAddressSpaceOwner(AddressSpace) ?
(PVOID)((ULONG_PTR)MmSystemRangeStart - 1) : (PVOID)MAXULONG_PTR; (PVOID)((ULONG_PTR)MmSystemRangeStart - 1) : (PVOID)MAXULONG_PTR;
PVOID AlignedAddress; PVOID AlignedAddress;
PMEMORY_AREA Node; PMEMORY_AREA Node;
@ -648,8 +648,8 @@ MmFindGapAtAddress(
{ {
PMEMORY_AREA Node = AddressSpace->MemoryAreaRoot; PMEMORY_AREA Node = AddressSpace->MemoryAreaRoot;
PMEMORY_AREA RightNeighbour = NULL; PMEMORY_AREA RightNeighbour = NULL;
PVOID LowestAddress = AddressSpace->Process ? MM_LOWEST_USER_ADDRESS : MmSystemRangeStart; PVOID LowestAddress = MmGetAddressSpaceOwner(AddressSpace) ? MM_LOWEST_USER_ADDRESS : MmSystemRangeStart;
PVOID HighestAddress = AddressSpace->Process ? PVOID HighestAddress = MmGetAddressSpaceOwner(AddressSpace) ?
(PVOID)((ULONG_PTR)MmSystemRangeStart - 1) : (PVOID)MAXULONG_PTR; (PVOID)((ULONG_PTR)MmSystemRangeStart - 1) : (PVOID)MAXULONG_PTR;
MmVerifyMemoryAreas(AddressSpace); MmVerifyMemoryAreas(AddressSpace);
@ -749,11 +749,12 @@ MmFreeMemoryArea(
ULONG_PTR Address; ULONG_PTR Address;
PVOID EndAddress; PVOID EndAddress;
PEPROCESS CurrentProcess = PsGetCurrentProcess(); PEPROCESS CurrentProcess = PsGetCurrentProcess();
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
if (AddressSpace->Process != NULL &&
AddressSpace->Process != CurrentProcess) if (Process != NULL &&
Process != CurrentProcess)
{ {
KeAttachProcess(&AddressSpace->Process->Pcb); KeAttachProcess(&Process->Pcb);
} }
EndAddress = MM_ROUND_UP(MemoryArea->EndingAddress, PAGE_SIZE); EndAddress = MM_ROUND_UP(MemoryArea->EndingAddress, PAGE_SIZE);
@ -771,13 +772,13 @@ MmFreeMemoryArea(
SWAPENTRY SwapEntry = 0; SWAPENTRY SwapEntry = 0;
PFN_TYPE Page = 0; PFN_TYPE Page = 0;
if (MmIsPageSwapEntry(AddressSpace->Process, (PVOID)Address)) if (MmIsPageSwapEntry(Process, (PVOID)Address))
{ {
MmDeletePageFileMapping(AddressSpace->Process, (PVOID)Address, &SwapEntry); MmDeletePageFileMapping(Process, (PVOID)Address, &SwapEntry);
} }
else else
{ {
MmDeleteVirtualMapping(AddressSpace->Process, (PVOID)Address, FALSE, &Dirty, &Page); MmDeleteVirtualMapping(Process, (PVOID)Address, FALSE, &Dirty, &Page);
} }
if (FreePage != NULL) if (FreePage != NULL)
{ {
@ -787,8 +788,8 @@ MmFreeMemoryArea(
} }
} }
if (AddressSpace->Process != NULL && if (Process != NULL &&
AddressSpace->Process != CurrentProcess) Process != CurrentProcess)
{ {
KeDetachProcess(); KeDetachProcess();
} }
@ -975,13 +976,13 @@ MmCreateMemoryArea(PMADDRESS_SPACE AddressSpace,
- (ULONG_PTR) MM_ROUND_DOWN(*BaseAddress, Granularity)); - (ULONG_PTR) MM_ROUND_DOWN(*BaseAddress, Granularity));
*BaseAddress = MM_ROUND_DOWN(*BaseAddress, Granularity); *BaseAddress = MM_ROUND_DOWN(*BaseAddress, Granularity);
if (!AddressSpace->Process && *BaseAddress < MmSystemRangeStart) if (!MmGetAddressSpaceOwner(AddressSpace) && *BaseAddress < MmSystemRangeStart)
{ {
CHECKPOINT; CHECKPOINT;
return STATUS_ACCESS_VIOLATION; return STATUS_ACCESS_VIOLATION;
} }
if (AddressSpace->Process && if (MmGetAddressSpaceOwner(AddressSpace) &&
(ULONG_PTR)(*BaseAddress) + tmpLength > (ULONG_PTR)MmSystemRangeStart) (ULONG_PTR)(*BaseAddress) + tmpLength > (ULONG_PTR)MmSystemRangeStart)
{ {
CHECKPOINT; CHECKPOINT;

View file

@ -724,17 +724,18 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
PMM_PAGEOP PageOp; PMM_PAGEOP PageOp;
PMM_REGION Region; PMM_REGION Region;
BOOLEAN HasSwapEntry; BOOLEAN HasSwapEntry;
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
/* /*
* There is a window between taking the page fault and locking the * There is a window between taking the page fault and locking the
* address space when another thread could load the page so we check * address space when another thread could load the page so we check
* that. * that.
*/ */
if (MmIsPagePresent(AddressSpace->Process, Address)) if (MmIsPagePresent(Process, Address))
{ {
if (Locked) if (Locked)
{ {
MmLockPage(MmGetPfnForProcess(AddressSpace->Process, Address)); MmLockPage(MmGetPfnForProcess(Process, Address));
} }
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
@ -825,10 +826,10 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
* If the completed fault was for another address space then set the * If the completed fault was for another address space then set the
* page in this one. * page in this one.
*/ */
if (!MmIsPagePresent(AddressSpace->Process, Address)) if (!MmIsPagePresent(Process, Address))
{ {
Entry = MmGetPageEntrySectionSegment(Segment, Offset); Entry = MmGetPageEntrySectionSegment(Segment, Offset);
HasSwapEntry = MmIsPageSwapEntry(AddressSpace->Process, (PVOID)PAddress); HasSwapEntry = MmIsPageSwapEntry(Process, (PVOID)PAddress);
if (PAGE_FROM_SSE(Entry) == 0 || HasSwapEntry) if (PAGE_FROM_SSE(Entry) == 0 || HasSwapEntry)
{ {
@ -847,7 +848,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
/* FIXME: Should we call MmCreateVirtualMappingUnsafe if /* FIXME: Should we call MmCreateVirtualMappingUnsafe if
* (Section->AllocationAttributes & SEC_PHYSICALMEMORY) is true? * (Section->AllocationAttributes & SEC_PHYSICALMEMORY) is true?
*/ */
Status = MmCreateVirtualMapping(AddressSpace->Process, Status = MmCreateVirtualMapping(Process,
Address, Address,
Attributes, Attributes,
&Page, &Page,
@ -857,7 +858,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
DPRINT1("Unable to create virtual mapping\n"); DPRINT1("Unable to create virtual mapping\n");
KEBUGCHECK(0); KEBUGCHECK(0);
} }
MmInsertRmap(Page, AddressSpace->Process, (PVOID)PAddress); MmInsertRmap(Page, Process, (PVOID)PAddress);
} }
if (Locked) if (Locked)
{ {
@ -870,7 +871,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
HasSwapEntry = MmIsPageSwapEntry(AddressSpace->Process, (PVOID)PAddress); HasSwapEntry = MmIsPageSwapEntry(Process, (PVOID)PAddress);
if (HasSwapEntry) if (HasSwapEntry)
{ {
/* /*
@ -888,7 +889,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
} }
MmUnlockSectionSegment(Segment); MmUnlockSectionSegment(Segment);
MmDeletePageFileMapping(AddressSpace->Process, (PVOID)PAddress, &SwapEntry); MmDeletePageFileMapping(Process, (PVOID)PAddress, &SwapEntry);
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page); Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
@ -904,7 +905,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
KEBUGCHECK(0); KEBUGCHECK(0);
} }
MmLockAddressSpace(AddressSpace); MmLockAddressSpace(AddressSpace);
Status = MmCreateVirtualMapping(AddressSpace->Process, Status = MmCreateVirtualMapping(Process,
Address, Address,
Region->Protect, Region->Protect,
&Page, &Page,
@ -924,7 +925,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
/* /*
* Add the page to the process's working set * Add the page to the process's working set
*/ */
MmInsertRmap(Page, AddressSpace->Process, (PVOID)PAddress); MmInsertRmap(Page, Process, (PVOID)PAddress);
/* /*
* Finish the operation * Finish the operation
@ -949,7 +950,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
* Just map the desired physical page * Just map the desired physical page
*/ */
Page = Offset >> PAGE_SHIFT; Page = Offset >> PAGE_SHIFT;
Status = MmCreateVirtualMappingUnsafe(AddressSpace->Process, Status = MmCreateVirtualMappingUnsafe(Process,
Address, Address,
Region->Protect, Region->Protect,
&Page, &Page,
@ -995,7 +996,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
{ {
KEBUGCHECK(0); KEBUGCHECK(0);
} }
Status = MmCreateVirtualMapping(AddressSpace->Process, Status = MmCreateVirtualMapping(Process,
Address, Address,
Region->Protect, Region->Protect,
&Page, &Page,
@ -1006,7 +1007,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
KEBUGCHECK(0); KEBUGCHECK(0);
return(Status); return(Status);
} }
MmInsertRmap(Page, AddressSpace->Process, (PVOID)PAddress); MmInsertRmap(Page, Process, (PVOID)PAddress);
if (Locked) if (Locked)
{ {
MmLockPage(Page); MmLockPage(Page);
@ -1095,7 +1096,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
MmSetPageEntrySectionSegment(Segment, Offset, Entry); MmSetPageEntrySectionSegment(Segment, Offset, Entry);
MmUnlockSectionSegment(Segment); MmUnlockSectionSegment(Segment);
Status = MmCreateVirtualMapping(AddressSpace->Process, Status = MmCreateVirtualMapping(Process,
Address, Address,
Attributes, Attributes,
&Page, &Page,
@ -1105,7 +1106,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
DPRINT1("Unable to create virtual mapping\n"); DPRINT1("Unable to create virtual mapping\n");
KEBUGCHECK(0); KEBUGCHECK(0);
} }
MmInsertRmap(Page, AddressSpace->Process, (PVOID)PAddress); MmInsertRmap(Page, Process, (PVOID)PAddress);
if (Locked) if (Locked)
{ {
@ -1170,7 +1171,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
* Save the swap entry. * Save the swap entry.
*/ */
MmSetSavedSwapEntryPage(Page, SwapEntry); MmSetSavedSwapEntryPage(Page, SwapEntry);
Status = MmCreateVirtualMapping(AddressSpace->Process, Status = MmCreateVirtualMapping(Process,
Address, Address,
Region->Protect, Region->Protect,
&Page, &Page,
@ -1180,7 +1181,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
DPRINT1("Unable to create virtual mapping\n"); DPRINT1("Unable to create virtual mapping\n");
KEBUGCHECK(0); KEBUGCHECK(0);
} }
MmInsertRmap(Page, AddressSpace->Process, (PVOID)PAddress); MmInsertRmap(Page, Process, (PVOID)PAddress);
if (Locked) if (Locked)
{ {
MmLockPage(Page); MmLockPage(Page);
@ -1202,7 +1203,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
MmSharePageEntrySectionSegment(Segment, Offset); MmSharePageEntrySectionSegment(Segment, Offset);
MmUnlockSectionSegment(Segment); MmUnlockSectionSegment(Segment);
Status = MmCreateVirtualMapping(AddressSpace->Process, Status = MmCreateVirtualMapping(Process,
Address, Address,
Attributes, Attributes,
&Page, &Page,
@ -1212,7 +1213,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
DPRINT1("Unable to create virtual mapping\n"); DPRINT1("Unable to create virtual mapping\n");
KEBUGCHECK(0); KEBUGCHECK(0);
} }
MmInsertRmap(Page, AddressSpace->Process, (PVOID)PAddress); MmInsertRmap(Page, Process, (PVOID)PAddress);
if (Locked) if (Locked)
{ {
MmLockPage(Page); MmLockPage(Page);
@ -1241,14 +1242,15 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
PMM_PAGEOP PageOp; PMM_PAGEOP PageOp;
PMM_REGION Region; PMM_REGION Region;
ULONG Entry; ULONG Entry;
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
DPRINT("MmAccessFaultSectionView(%x, %x, %x, %x)\n", AddressSpace, MemoryArea, Address, Locked); DPRINT("MmAccessFaultSectionView(%x, %x, %x, %x)\n", AddressSpace, MemoryArea, Address, Locked);
/* /*
* 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) || if (!MmIsPagePresent(Process, Address) ||
MmGetPageProtect(AddressSpace->Process, Address) & PAGE_READWRITE) MmGetPageProtect(Process, Address) & PAGE_READWRITE)
{ {
DPRINT("Address 0x%.8X\n", Address); DPRINT("Address 0x%.8X\n", Address);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
@ -1291,7 +1293,7 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
PFN_FROM_SSE(Entry) != OldPage) PFN_FROM_SSE(Entry) != OldPage)
{ {
/* This is a private page. We must only change the page protection. */ /* This is a private page. We must only change the page protection. */
MmSetPageProtect(AddressSpace->Process, PAddress, Region->Protect); MmSetPageProtect(Process, PAddress, Region->Protect);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
@ -1358,12 +1360,12 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
/* /*
* Delete the old entry. * Delete the old entry.
*/ */
MmDeleteVirtualMapping(AddressSpace->Process, Address, FALSE, NULL, NULL); MmDeleteVirtualMapping(Process, Address, FALSE, NULL, NULL);
/* /*
* Set the PTE to point to the new page * Set the PTE to point to the new page
*/ */
Status = MmCreateVirtualMapping(AddressSpace->Process, Status = MmCreateVirtualMapping(Process,
Address, Address,
Region->Protect, Region->Protect,
&NewPage, &NewPage,
@ -1388,8 +1390,8 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
/* /*
* Unshare the old page. * Unshare the old page.
*/ */
MmDeleteRmap(OldPage, AddressSpace->Process, PAddress); MmDeleteRmap(OldPage, Process, PAddress);
MmInsertRmap(NewPage, AddressSpace->Process, PAddress); MmInsertRmap(NewPage, Process, PAddress);
MmLockSectionSegment(Segment); MmLockSectionSegment(Segment);
MmUnsharePageEntrySectionSegment(Section, Segment, Offset, FALSE, FALSE); MmUnsharePageEntrySectionSegment(Section, Segment, Offset, FALSE, FALSE);
MmUnlockSectionSegment(Segment); MmUnlockSectionSegment(Segment);
@ -1462,7 +1464,8 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
PBCB Bcb = NULL; PBCB Bcb = NULL;
BOOLEAN DirectMapped; BOOLEAN DirectMapped;
BOOLEAN IsImageSection; BOOLEAN IsImageSection;
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
Address = (PVOID)PAGE_ROUND_DOWN(Address); Address = (PVOID)PAGE_ROUND_DOWN(Address);
/* /*
@ -1505,7 +1508,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
{ {
DPRINT1("Trying to page out from physical memory section address 0x%X " DPRINT1("Trying to page out from physical memory section address 0x%X "
"process %d\n", Address, "process %d\n", Address,
AddressSpace->Process ? AddressSpace->Process->UniqueProcessId : 0); Process ? Process->UniqueProcessId : 0);
KEBUGCHECK(0); KEBUGCHECK(0);
} }
@ -1513,13 +1516,13 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
* Get the section segment entry and the physical address. * Get the section segment entry and the physical address.
*/ */
Entry = MmGetPageEntrySectionSegment(Context.Segment, Context.Offset); Entry = MmGetPageEntrySectionSegment(Context.Segment, Context.Offset);
if (!MmIsPagePresent(AddressSpace->Process, Address)) if (!MmIsPagePresent(Process, Address))
{ {
DPRINT1("Trying to page out not-present page at (%d,0x%.8X).\n", DPRINT1("Trying to page out not-present page at (%d,0x%.8X).\n",
AddressSpace->Process ? AddressSpace->Process->UniqueProcessId : 0, Address); Process ? Process->UniqueProcessId : 0, Address);
KEBUGCHECK(0); KEBUGCHECK(0);
} }
Page = MmGetPfnForProcess(AddressSpace->Process, Address); Page = MmGetPfnForProcess(Process, Address);
SwapEntry = MmGetSavedSwapEntryPage(Page); SwapEntry = MmGetSavedSwapEntryPage(Page);
/* /*
@ -1650,7 +1653,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
{ {
MmSetSavedSwapEntryPage(Page, 0); MmSetSavedSwapEntryPage(Page, 0);
MmLockAddressSpace(AddressSpace); MmLockAddressSpace(AddressSpace);
Status = MmCreatePageFileMapping(AddressSpace->Process, Status = MmCreatePageFileMapping(Process,
Address, Address,
SwapEntry); SwapEntry);
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
@ -1679,14 +1682,14 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
*/ */
if (Context.Private) if (Context.Private)
{ {
Status = MmCreateVirtualMapping(AddressSpace->Process, Status = MmCreateVirtualMapping(Process,
Address, Address,
MemoryArea->Protect, MemoryArea->Protect,
&Page, &Page,
1); 1);
MmSetDirtyPage(AddressSpace->Process, Address); MmSetDirtyPage(Process, Address);
MmInsertRmap(Page, MmInsertRmap(Page,
AddressSpace->Process, Process,
Address); Address);
} }
else else
@ -1696,14 +1699,14 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
* set it back into the section segment entry so we don't loose * set it back into the section segment entry so we don't loose
* our copy. Otherwise it will be handled by the cache manager. * our copy. Otherwise it will be handled by the cache manager.
*/ */
Status = MmCreateVirtualMapping(AddressSpace->Process, Status = MmCreateVirtualMapping(Process,
Address, Address,
MemoryArea->Protect, MemoryArea->Protect,
&Page, &Page,
1); 1);
MmSetDirtyPage(AddressSpace->Process, Address); MmSetDirtyPage(Process, Address);
MmInsertRmap(Page, MmInsertRmap(Page,
AddressSpace->Process, Process,
Address); Address);
Entry = MAKE_SSE(Page << PAGE_SHIFT, 1); Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry); MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry);
@ -1730,26 +1733,26 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
MmLockAddressSpace(AddressSpace); MmLockAddressSpace(AddressSpace);
if (Context.Private) if (Context.Private)
{ {
Status = MmCreateVirtualMapping(AddressSpace->Process, Status = MmCreateVirtualMapping(Process,
Address, Address,
MemoryArea->Protect, MemoryArea->Protect,
&Page, &Page,
1); 1);
MmSetDirtyPage(AddressSpace->Process, Address); MmSetDirtyPage(Process, Address);
MmInsertRmap(Page, MmInsertRmap(Page,
AddressSpace->Process, Process,
Address); Address);
} }
else else
{ {
Status = MmCreateVirtualMapping(AddressSpace->Process, Status = MmCreateVirtualMapping(Process,
Address, Address,
MemoryArea->Protect, MemoryArea->Protect,
&Page, &Page,
1); 1);
MmSetDirtyPage(AddressSpace->Process, Address); MmSetDirtyPage(Process, Address);
MmInsertRmap(Page, MmInsertRmap(Page,
AddressSpace->Process, Process,
Address); Address);
Entry = MAKE_SSE(Page << PAGE_SHIFT, 1); Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry); MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry);
@ -1778,7 +1781,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
if (Context.Private) if (Context.Private)
{ {
MmLockAddressSpace(AddressSpace); MmLockAddressSpace(AddressSpace);
Status = MmCreatePageFileMapping(AddressSpace->Process, Status = MmCreatePageFileMapping(Process,
Address, Address,
SwapEntry); SwapEntry);
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
@ -1817,6 +1820,7 @@ MmWritePageSectionView(PMADDRESS_SPACE AddressSpace,
PBCB Bcb = NULL; PBCB Bcb = NULL;
BOOLEAN DirectMapped; BOOLEAN DirectMapped;
BOOLEAN IsImageSection; BOOLEAN IsImageSection;
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
Address = (PVOID)PAGE_ROUND_DOWN(Address); Address = (PVOID)PAGE_ROUND_DOWN(Address);
@ -1857,7 +1861,7 @@ MmWritePageSectionView(PMADDRESS_SPACE AddressSpace,
{ {
DPRINT1("Trying to write back page from physical memory mapped at %X " DPRINT1("Trying to write back page from physical memory mapped at %X "
"process %d\n", Address, "process %d\n", Address,
AddressSpace->Process ? AddressSpace->Process->UniqueProcessId : 0); Process ? Process->UniqueProcessId : 0);
KEBUGCHECK(0); KEBUGCHECK(0);
} }
@ -1865,13 +1869,13 @@ MmWritePageSectionView(PMADDRESS_SPACE AddressSpace,
* Get the section segment entry and the physical address. * Get the section segment entry and the physical address.
*/ */
Entry = MmGetPageEntrySectionSegment(Segment, Offset); Entry = MmGetPageEntrySectionSegment(Segment, Offset);
if (!MmIsPagePresent(AddressSpace->Process, Address)) if (!MmIsPagePresent(Process, Address))
{ {
DPRINT1("Trying to page out not-present page at (%d,0x%.8X).\n", DPRINT1("Trying to page out not-present page at (%d,0x%.8X).\n",
AddressSpace->Process ? AddressSpace->Process->UniqueProcessId : 0, Address); Process ? Process->UniqueProcessId : 0, Address);
KEBUGCHECK(0); KEBUGCHECK(0);
} }
Page = MmGetPfnForProcess(AddressSpace->Process, Address); Page = MmGetPfnForProcess(Process, Address);
SwapEntry = MmGetSavedSwapEntryPage(Page); SwapEntry = MmGetSavedSwapEntryPage(Page);
/* /*
@ -1958,6 +1962,7 @@ MmAlterViewAttributes(PMADDRESS_SPACE AddressSpace,
PMM_SECTION_SEGMENT Segment; PMM_SECTION_SEGMENT Segment;
BOOLEAN DoCOW = FALSE; BOOLEAN DoCOW = FALSE;
ULONG i; ULONG i;
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, BaseAddress); MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, BaseAddress);
Segment = MemoryArea->Data.SectionData.Segment; Segment = MemoryArea->Data.SectionData.Segment;
@ -1979,7 +1984,7 @@ MmAlterViewAttributes(PMADDRESS_SPACE AddressSpace,
* If we doing COW for this segment then check if the page is * If we doing COW for this segment then check if the page is
* already private. * already private.
*/ */
if (DoCOW && MmIsPagePresent(AddressSpace->Process, Address)) if (DoCOW && MmIsPagePresent(Process, Address))
{ {
ULONG Offset; ULONG Offset;
ULONG Entry; ULONG Entry;
@ -1988,7 +1993,7 @@ MmAlterViewAttributes(PMADDRESS_SPACE AddressSpace,
Offset = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress Offset = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
+ MemoryArea->Data.SectionData.ViewOffset; + MemoryArea->Data.SectionData.ViewOffset;
Entry = MmGetPageEntrySectionSegment(Segment, Offset); Entry = MmGetPageEntrySectionSegment(Segment, Offset);
Page = MmGetPfnForProcess(AddressSpace->Process, Address); Page = MmGetPfnForProcess(Process, Address);
Protect = PAGE_READONLY; Protect = PAGE_READONLY;
if (Segment->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA || if (Segment->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA ||
@ -1999,9 +2004,9 @@ MmAlterViewAttributes(PMADDRESS_SPACE AddressSpace,
} }
} }
if (MmIsPagePresent(AddressSpace->Process, Address)) if (MmIsPagePresent(Process, Address))
{ {
MmSetPageProtect(AddressSpace->Process, Address, MmSetPageProtect(Process, Address,
Protect); Protect);
} }
} }
@ -3836,8 +3841,10 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
PROS_SECTION_OBJECT Section; PROS_SECTION_OBJECT Section;
PMM_SECTION_SEGMENT Segment; PMM_SECTION_SEGMENT Segment;
PMADDRESS_SPACE AddressSpace; PMADDRESS_SPACE AddressSpace;
PEPROCESS Process;
AddressSpace = (PMADDRESS_SPACE)Context; AddressSpace = (PMADDRESS_SPACE)Context;
Process = MmGetAddressSpaceOwner(AddressSpace);
Address = (PVOID)PAGE_ROUND_DOWN(Address); Address = (PVOID)PAGE_ROUND_DOWN(Address);
@ -3918,12 +3925,12 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
MmFreeSwapPage(SavedSwapEntry); MmFreeSwapPage(SavedSwapEntry);
MmSetSavedSwapEntryPage(Page, 0); MmSetSavedSwapEntryPage(Page, 0);
} }
MmDeleteRmap(Page, AddressSpace->Process, Address); MmDeleteRmap(Page, Process, Address);
MmReleasePageMemoryConsumer(MC_USER, Page); MmReleasePageMemoryConsumer(MC_USER, Page);
} }
else else
{ {
MmDeleteRmap(Page, AddressSpace->Process, Address); MmDeleteRmap(Page, Process, Address);
MmUnsharePageEntrySectionSegment(Section, Segment, Offset, Dirty, FALSE); MmUnsharePageEntrySectionSegment(Section, Segment, Offset, Dirty, FALSE);
} }
} }