NTSTATUS NTAPI MiWriteFilePage(PMMSUPPORT AddressSpace, PMEMORY_AREA MemoryArea, PMM_REQUIRED_RESOURCES Required) { DPRINT1("MiWriteFilePage(%x,%x)\n", Required->Page[Required->Offset], Required->FileOffset.LowPart); return MiWriteBackPage(Required->Context, &Required->FileOffset, PAGE_SIZE, Required->Page[Required->Offset]); }
NTSTATUS NTAPI MmFinalizeSectionPageOut(PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER FileOffset, PFN_NUMBER Page, BOOLEAN Dirty) { NTSTATUS Status = STATUS_SUCCESS; BOOLEAN WriteZero = FALSE, WritePage = FALSE; SWAPENTRY Swap = MmGetSavedSwapEntryPage(Page); /* Bail early if the reference count isn't where we need it */ if (MmGetReferenceCountPage(Page) != 1) { DPRINT1("Cannot page out locked page %x with ref count %lu\n", Page, MmGetReferenceCountPage(Page)); return STATUS_UNSUCCESSFUL; } MmLockSectionSegment(Segment); (void)InterlockedIncrementUL(&Segment->ReferenceCount); if (Dirty) { DPRINT("Finalize (dirty) Segment %p Page %x\n", Segment, Page); DPRINT("Segment->FileObject %p\n", Segment->FileObject); DPRINT("Segment->Flags %x\n", Segment->Flags); WriteZero = TRUE; WritePage = TRUE; } else { WriteZero = TRUE; } DPRINT("Status %x\n", Status); MmUnlockSectionSegment(Segment); if (WritePage) { DPRINT("MiWriteBackPage(Segment %p FileObject %p Offset %x)\n", Segment, Segment->FileObject, FileOffset->LowPart); Status = MiWriteBackPage(Segment->FileObject, FileOffset, PAGE_SIZE, Page); } MmLockSectionSegment(Segment); if (WriteZero && NT_SUCCESS(Status)) { DPRINT("Setting page entry in segment %p:%x to swap %x\n", Segment, FileOffset->LowPart, Swap); MmSetPageEntrySectionSegment(Segment, FileOffset, Swap ? MAKE_SWAP_SSE(Swap) : 0); } else { DPRINT("Setting page entry in segment %p:%x to page %x\n", Segment, FileOffset->LowPart, Page); MmSetPageEntrySectionSegment(Segment, FileOffset, Page ? (Dirty ? DIRTY_SSE(MAKE_PFN_SSE(Page)) : MAKE_PFN_SSE(Page)) : 0); } if (NT_SUCCESS(Status)) { DPRINT("Removing page %x for real\n", Page); MmSetSavedSwapEntryPage(Page, 0); MmReleasePageMemoryConsumer(MC_CACHE, Page); } MmUnlockSectionSegment(Segment); if (InterlockedDecrementUL(&Segment->ReferenceCount) == 0) { MmFinalizeSegment(Segment); } /* Note: Writing may evict the segment... Nothing is guaranteed from here down */ MiSetPageEvent(Segment, FileOffset->LowPart); DPRINT("Status %x\n", Status); return Status; }