mirror of
https://github.com/reactos/reactos.git
synced 2025-06-20 07:36:05 +00:00
[NTOS] Implement MiIsPageTablePresent as a replacement for the abused MiQueryPageTableReferences
This commit is contained in:
parent
678923bf4b
commit
6a2eeaa5ae
2 changed files with 77 additions and 52 deletions
|
@ -2549,57 +2549,13 @@ USHORT
|
||||||
MiQueryPageTableReferences(IN PVOID Address)
|
MiQueryPageTableReferences(IN PVOID Address)
|
||||||
{
|
{
|
||||||
PMMPDE PointerPde;
|
PMMPDE PointerPde;
|
||||||
PMMPPE PointerPpe;
|
|
||||||
#if _MI_PAGING_LEVELS == 4
|
|
||||||
PMMPXE PointerPxe;
|
|
||||||
#endif
|
|
||||||
PMMPFN Pfn;
|
PMMPFN Pfn;
|
||||||
|
|
||||||
/* Make sure we're locked */
|
/* Make sure we're locked */
|
||||||
ASSERT((PsGetCurrentThread()->OwnsProcessWorkingSetExclusive) || (PsGetCurrentThread()->OwnsProcessWorkingSetShared));
|
ASSERT((PsGetCurrentThread()->OwnsProcessWorkingSetExclusive) || (PsGetCurrentThread()->OwnsProcessWorkingSetShared));
|
||||||
|
|
||||||
/* Check if PXE or PPE have references first. */
|
|
||||||
#if _MI_PAGING_LEVELS == 4
|
|
||||||
PointerPxe = MiAddressToPxe(Address);
|
|
||||||
if ((PointerPxe->u.Hard.Valid == 1) || (PointerPxe->u.Soft.Transition == 1))
|
|
||||||
{
|
|
||||||
Pfn = MiGetPfnEntry(PFN_FROM_PXE(PointerPxe));
|
|
||||||
if (Pfn->OriginalPte.u.Soft.UsedPageTableEntries == 0)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if (PointerPxe->u.Soft.UsedPageTableEntries == 0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PointerPxe->u.Hard.Valid == 0)
|
|
||||||
{
|
|
||||||
MiMakeSystemAddressValid(MiPteToAddress(PointerPxe), PsGetCurrentProcess());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PointerPpe = MiAddressToPpe(Address);
|
|
||||||
if ((PointerPpe->u.Hard.Valid == 1) || (PointerPpe->u.Soft.Transition == 1))
|
|
||||||
{
|
|
||||||
Pfn = MiGetPfnEntry(PFN_FROM_PPE(PointerPpe));
|
|
||||||
if (Pfn->OriginalPte.u.Soft.UsedPageTableEntries == 0)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if (PointerPpe->u.Soft.UsedPageTableEntries == 0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PointerPpe->u.Hard.Valid == 0)
|
|
||||||
{
|
|
||||||
MiMakeSystemAddressValid(MiPteToAddress(PointerPpe), PsGetCurrentProcess());
|
|
||||||
}
|
|
||||||
|
|
||||||
PointerPde = MiAddressToPde(Address);
|
PointerPde = MiAddressToPde(Address);
|
||||||
if ((PointerPde->u.Hard.Valid == 0) && (PointerPde->u.Soft.Transition == 0))
|
ASSERT(PointerPde->u.Hard.Valid);
|
||||||
{
|
|
||||||
return PointerPde->u.Soft.UsedPageTableEntries;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This lies on the PFN */
|
/* This lies on the PFN */
|
||||||
Pfn = MiGetPfnEntry(PFN_FROM_PDE(PointerPde));
|
Pfn = MiGetPfnEntry(PFN_FROM_PDE(PointerPde));
|
||||||
|
|
|
@ -114,6 +114,75 @@ NTAPI
|
||||||
MiFillSystemPageDirectory(IN PVOID Base,
|
MiFillSystemPageDirectory(IN PVOID Base,
|
||||||
IN SIZE_T NumberOfBytes);
|
IN SIZE_T NumberOfBytes);
|
||||||
|
|
||||||
|
static
|
||||||
|
BOOLEAN
|
||||||
|
MiIsPageTablePresent(PVOID Address)
|
||||||
|
{
|
||||||
|
#if _MI_PAGING_LEVELS == 2
|
||||||
|
return MiQueryPageTableReferences(Address) != 0;
|
||||||
|
#else
|
||||||
|
PMMPDE PointerPde;
|
||||||
|
PMMPPE PointerPpe;
|
||||||
|
#if _MI_PAGING_LEVELS == 4
|
||||||
|
PMMPXE PointerPxe;
|
||||||
|
#endif
|
||||||
|
PMMPFN Pfn;
|
||||||
|
|
||||||
|
/* Make sure we're locked */
|
||||||
|
ASSERT((PsGetCurrentThread()->OwnsProcessWorkingSetExclusive) || (PsGetCurrentThread()->OwnsProcessWorkingSetShared));
|
||||||
|
|
||||||
|
/* Must not hold the PFN lock! */
|
||||||
|
ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
|
||||||
|
|
||||||
|
/* Check if PXE or PPE have references first. */
|
||||||
|
#if _MI_PAGING_LEVELS == 4
|
||||||
|
PointerPxe = MiAddressToPxe(Address);
|
||||||
|
if ((PointerPxe->u.Hard.Valid == 1) || (PointerPxe->u.Soft.Transition == 1))
|
||||||
|
{
|
||||||
|
Pfn = MiGetPfnEntry(PFN_FROM_PXE(PointerPxe));
|
||||||
|
if (Pfn->OriginalPte.u.Soft.UsedPageTableEntries == 0)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else if (PointerPxe->u.Soft.UsedPageTableEntries == 0)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PointerPxe->u.Hard.Valid == 0)
|
||||||
|
{
|
||||||
|
MiMakeSystemAddressValid(MiPteToAddress(PointerPxe), PsGetCurrentProcess());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
PointerPpe = MiAddressToPpe(Address);
|
||||||
|
if ((PointerPpe->u.Hard.Valid == 1) || (PointerPpe->u.Soft.Transition == 1))
|
||||||
|
{
|
||||||
|
Pfn = MiGetPfnEntry(PFN_FROM_PPE(PointerPpe));
|
||||||
|
if (Pfn->OriginalPte.u.Soft.UsedPageTableEntries == 0)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else if (PointerPpe->u.Soft.UsedPageTableEntries == 0)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PointerPpe->u.Hard.Valid == 0)
|
||||||
|
{
|
||||||
|
MiMakeSystemAddressValid(MiPteToAddress(PointerPpe), PsGetCurrentProcess());
|
||||||
|
}
|
||||||
|
|
||||||
|
PointerPde = MiAddressToPde(Address);
|
||||||
|
if ((PointerPde->u.Hard.Valid == 0) && (PointerPde->u.Soft.Transition == 0))
|
||||||
|
{
|
||||||
|
return PointerPde->u.Soft.UsedPageTableEntries != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This lies on the PFN */
|
||||||
|
Pfn = MiGetPfnEntry(PFN_FROM_PDE(PointerPde));
|
||||||
|
return Pfn->OriginalPte.u.Soft.UsedPageTableEntries != 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
PFN_NUMBER
|
PFN_NUMBER
|
||||||
NTAPI
|
NTAPI
|
||||||
MmGetPfnForProcess(PEPROCESS Process,
|
MmGetPfnForProcess(PEPROCESS Process,
|
||||||
|
@ -132,7 +201,7 @@ MmGetPfnForProcess(PEPROCESS Process,
|
||||||
/* Lock for reading */
|
/* Lock for reading */
|
||||||
MiLockProcessWorkingSetShared(Process, PsGetCurrentThread());
|
MiLockProcessWorkingSetShared(Process, PsGetCurrentThread());
|
||||||
|
|
||||||
if (MiQueryPageTableReferences(Address) == 0)
|
if (!MiIsPageTablePresent(Address))
|
||||||
{
|
{
|
||||||
MiUnlockProcessWorkingSetShared(Process, PsGetCurrentThread());
|
MiUnlockProcessWorkingSetShared(Process, PsGetCurrentThread());
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -201,7 +270,7 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address,
|
||||||
MiLockProcessWorkingSetUnsafe(Process, PsGetCurrentThread());
|
MiLockProcessWorkingSetUnsafe(Process, PsGetCurrentThread());
|
||||||
|
|
||||||
/* No PDE --> No page */
|
/* No PDE --> No page */
|
||||||
if (MiQueryPageTableReferences(Address) == 0)
|
if (!MiIsPageTablePresent(Address))
|
||||||
{
|
{
|
||||||
MiUnlockProcessWorkingSetUnsafe(Process, PsGetCurrentThread());
|
MiUnlockProcessWorkingSetUnsafe(Process, PsGetCurrentThread());
|
||||||
if (WasDirty)
|
if (WasDirty)
|
||||||
|
@ -332,7 +401,7 @@ MmIsPagePresent(PEPROCESS Process, PVOID Address)
|
||||||
|
|
||||||
MiLockProcessWorkingSetShared(Process, PsGetCurrentThread());
|
MiLockProcessWorkingSetShared(Process, PsGetCurrentThread());
|
||||||
|
|
||||||
if (MiQueryPageTableReferences(Address) == 0)
|
if (!MiIsPageTablePresent(Address))
|
||||||
{
|
{
|
||||||
/* It can't be present if there is no PDE */
|
/* It can't be present if there is no PDE */
|
||||||
MiUnlockProcessWorkingSetShared(Process, PsGetCurrentThread());
|
MiUnlockProcessWorkingSetShared(Process, PsGetCurrentThread());
|
||||||
|
@ -375,7 +444,7 @@ MmIsDisabledPage(PEPROCESS Process, PVOID Address)
|
||||||
|
|
||||||
MiLockProcessWorkingSetShared(Process, PsGetCurrentThread());
|
MiLockProcessWorkingSetShared(Process, PsGetCurrentThread());
|
||||||
|
|
||||||
if (MiQueryPageTableReferences(Address) == 0)
|
if (!MiIsPageTablePresent(Address))
|
||||||
{
|
{
|
||||||
/* It can't be disabled if there is no PDE */
|
/* It can't be disabled if there is no PDE */
|
||||||
MiUnlockProcessWorkingSetShared(Process, PsGetCurrentThread());
|
MiUnlockProcessWorkingSetShared(Process, PsGetCurrentThread());
|
||||||
|
@ -415,7 +484,7 @@ MmIsPageSwapEntry(PEPROCESS Process, PVOID Address)
|
||||||
|
|
||||||
MiLockProcessWorkingSetShared(Process, PsGetCurrentThread());
|
MiLockProcessWorkingSetShared(Process, PsGetCurrentThread());
|
||||||
|
|
||||||
if (MiQueryPageTableReferences(Address) == 0)
|
if (!MiIsPageTablePresent(Address))
|
||||||
{
|
{
|
||||||
/* There can't be a swap entry if there is no PDE */
|
/* There can't be a swap entry if there is no PDE */
|
||||||
MiUnlockProcessWorkingSetShared(Process, PsGetCurrentThread());
|
MiUnlockProcessWorkingSetShared(Process, PsGetCurrentThread());
|
||||||
|
@ -451,7 +520,7 @@ MmGetPageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY* SwapEntry)
|
||||||
|
|
||||||
MiLockProcessWorkingSetShared(Process, PsGetCurrentThread());
|
MiLockProcessWorkingSetShared(Process, PsGetCurrentThread());
|
||||||
|
|
||||||
if (MiQueryPageTableReferences(Address) == 0)
|
if (!MiIsPageTablePresent(Address))
|
||||||
{
|
{
|
||||||
/* There can't be a swap entry if there is no PDE */
|
/* There can't be a swap entry if there is no PDE */
|
||||||
MiUnlockProcessWorkingSetShared(Process, PsGetCurrentThread());
|
MiUnlockProcessWorkingSetShared(Process, PsGetCurrentThread());
|
||||||
|
@ -638,7 +707,7 @@ MmGetPageProtect(PEPROCESS Process, PVOID Address)
|
||||||
|
|
||||||
MiLockProcessWorkingSetShared(Process, PsGetCurrentThread());
|
MiLockProcessWorkingSetShared(Process, PsGetCurrentThread());
|
||||||
|
|
||||||
if (MiQueryPageTableReferences(Address) == 0)
|
if (!MiIsPageTablePresent(Address))
|
||||||
{
|
{
|
||||||
/* It can't be present if there is no PDE */
|
/* It can't be present if there is no PDE */
|
||||||
MiUnlockProcessWorkingSetShared(Process, PsGetCurrentThread());
|
MiUnlockProcessWorkingSetShared(Process, PsGetCurrentThread());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue