VOID NTAPI MmDeleteVirtualMapping( PEPROCESS Process, PVOID Address, BOOLEAN FreePage, BOOLEAN* WasDirty, PPFN_NUMBER Page) { PFN_NUMBER Pfn; PMMPTE Pte; MMPTE OldPte; Pte = MiGetPteForProcess(Process, Address, FALSE); if (Pte) { /* Atomically set the entry to zero and get the old value. */ OldPte.u.Long = InterlockedExchange64((LONG64*)&Pte->u.Long, 0); if (OldPte.u.Hard.Valid) { Pfn = OldPte.u.Hard.PageFrameNumber; //if (FreePage) //MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn); } else Pfn = 0; } else { OldPte.u.Long = 0; Pfn = 0; } /* Return information to the caller */ if (WasDirty) *WasDirty = (BOOLEAN)OldPte.u.Hard.Dirty;; if (Page) *Page = Pfn; MiFlushTlb(Pte, Address); }
VOID NTAPI MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect) { PMMPTE Pte; MMPTE NewPte; Pte = MiGetPteForProcess(Process, Address, FALSE); ASSERT(Pte != NULL); NewPte = *Pte; MiSetPteProtection(&NewPte, flProtect); InterlockedExchangePte(Pte, NewPte); MiFlushTlb(Pte, Address); }
VOID NTAPI MmSetDirtyPage(PEPROCESS Process, PVOID Address) { PMMPTE Pte; Pte = MiGetPteForProcess(Process, Address, FALSE); if (!Pte) { KeBugCheckEx(MEMORY_MANAGEMENT, 0x1234, (ULONG64)Address, 0, 0); } /* Ckear the dirty bit */ if (InterlockedBitTestAndSet64((PVOID)Pte, 6)) { if (!MiIsHyperspaceAddress(Pte)) __invlpg(Address); } MiFlushTlb(Pte, Address); }