-NTSTATUS
-NTAPI
-MmWritePageVirtualMemory(PMMSUPPORT AddressSpace,
- PMEMORY_AREA MemoryArea,
- PVOID Address,
- PMM_PAGEOP PageOp)
-{
- SWAPENTRY SwapEntry;
- PFN_NUMBER Page;
- NTSTATUS Status;
- PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
-
- /*
- * 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);
- }
-
- Page = MmGetPfnForProcess(Process, Address);
-
- /*
- * Get that the page actually is dirty.
- */
- if (!MmIsDirtyPage(Process, Address))
- {
- PageOp->Status = STATUS_SUCCESS;
- KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
- MmReleasePageOp(PageOp);
- return(STATUS_SUCCESS);
- }
-
- /*
- * Speculatively set the mapping to clean.
- */
- MmSetCleanPage(Process, Address);
-
- /*
- * If necessary, allocate an entry in the paging file for this page
- */
- SwapEntry = MmGetSavedSwapEntryPage(Page);
- if (SwapEntry == 0)
- {
- SwapEntry = MmAllocSwapPage();
- if (SwapEntry == 0)
- {
- MmSetDirtyPage(Process, Address);
- PageOp->Status = STATUS_PAGEFILE_QUOTA_EXCEEDED;
- KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
- MmReleasePageOp(PageOp);
- return(STATUS_PAGEFILE_QUOTA_EXCEEDED);
- }
- }
-
- /*
- * Write the page to the pagefile
- */
- Status = MmWriteToSwapPage(SwapEntry, Page);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n",
- Status);
- MmSetDirtyPage(Process, Address);
- PageOp->Status = STATUS_UNSUCCESSFUL;
- KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
- MmReleasePageOp(PageOp);
- return(STATUS_UNSUCCESSFUL);
- }
-
- /*
- * Otherwise we have succeeded.
- */
- MmSetSavedSwapEntryPage(Page, SwapEntry);
- PageOp->Status = STATUS_SUCCESS;
- KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
- MmReleasePageOp(PageOp);
- return(STATUS_SUCCESS);
-}
-