Esempio n. 1
0
static
VOID
MmDeletePageTablePfn(PFN_NUMBER PageFrameNumber, ULONG Level)
{
    PMMPTE PageTable;
    KIRQL OldIrql;
    PMMPFN PfnEntry;
    ULONG i, NumberEntries;

    /* Check if this is a page table */
    if (Level > 0)
    {
        NumberEntries = (Level == 4) ? MiAddressToPxi(MmHighestUserAddress)+1 : 512;

        /* Map the page table in hyperspace */
        PageTable = (PMMPTE)MmCreateHyperspaceMapping(PageFrameNumber);

        /* Loop all page table entries */
        for (i = 0; i < NumberEntries; i++)
        {
            /* Check if the entry is valid */
            if (PageTable[i].u.Hard.Valid)
            {
                /* Recursively free the page that backs it */
                MmDeletePageTablePfn(PageTable[i].u.Hard.PageFrameNumber, Level - 1);
            }
        }

        /* Delete the hyperspace mapping */
        MmDeleteHyperspaceMapping(PageTable);
    }

    /* Check if this is a legacy allocation */
    PfnEntry = MiGetPfnEntry(PageFrameNumber);
    if (MI_IS_ROS_PFN(PfnEntry))
    {
        /* Free it using the legacy API */
        MmReleasePageMemoryConsumer(MC_SYSTEM, PageFrameNumber);
    }
    else
    {
        OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);

        /* Free it using the ARM3 API */
        MI_SET_PFN_DELETED(PfnEntry);
        MiDecrementShareCount(PfnEntry, PageFrameNumber);

        KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
    }
}
Esempio n. 2
0
NTSTATUS
NTAPI
_MiWriteBackPage
(PFILE_OBJECT FileObject,
 PLARGE_INTEGER FileOffset,
 ULONG Length,
 PFN_NUMBER Page,
 const char *File,
 int Line)
{
	NTSTATUS Status;
	PVOID Hyperspace;
	IO_STATUS_BLOCK Iosb;
	KIRQL OldIrql;
	PVOID PageBuffer = ExAllocatePool(NonPagedPool, PAGE_SIZE);

	if (!PageBuffer) return STATUS_NO_MEMORY;

	KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
	Hyperspace = MmCreateHyperspaceMapping(Page);
	RtlCopyMemory(PageBuffer, Hyperspace, PAGE_SIZE);
	MmDeleteHyperspaceMapping(Hyperspace);
	KeLowerIrql(OldIrql);

	DPRINT1("MiWriteBackPage(%wZ,%08x%08x,%s:%d)\n", &FileObject->FileName, FileOffset->u.HighPart, FileOffset->u.LowPart, File, Line);
	Status = MiSimpleWrite
		(FileObject,
		 FileOffset,
		 PageBuffer,
		 Length,
		 &Iosb);

	ExFreePool(PageBuffer);

	if (!NT_SUCCESS(Status))
	{
		DPRINT1("MiSimpleWrite failed (%x)\n", Status);
	}

	return Status;
}