Exemple #1
0
NTSTATUS
NTAPI
MiSwapInPage(PMMSUPPORT AddressSpace,
             PMEMORY_AREA MemoryArea,
             PMM_REQUIRED_RESOURCES Resources)
{
    NTSTATUS Status;

    Status = MmRequestPageMemoryConsumer(Resources->Consumer,
                                         TRUE,
                                         &Resources->Page[Resources->Offset]);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("MmRequestPageMemoryConsumer failed, status = %x\n", Status);
        return Status;
    }

    Status = MmReadFromSwapPage(Resources->SwapEntry,
                                Resources->Page[Resources->Offset]);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("MmReadFromSwapPage failed, status = %x\n", Status);
        return Status;
    }

    MmSetSavedSwapEntryPage(Resources->Page[Resources->Offset],
                            Resources->SwapEntry);

    DPRINT1("MiSwapInPage(%x,%x)\n",
            Resources->Page[Resources->Offset],
            Resources->SwapEntry);

    return Status;
}
Exemple #2
0
/*

Blocking function to acquire zeroed pages from the balancer.

Upon entry:

Required->Amount: Number of pages to acquire
Required->Consumer: consumer to charge the page to

Upon return:

Required->Pages[0..Amount]: Allocated pages.

The function fails unless all requested pages can be allocated.

 */
NTSTATUS
NTAPI
MiGetOnePage(PMMSUPPORT AddressSpace,
             PMEMORY_AREA MemoryArea,
             PMM_REQUIRED_RESOURCES Required)
{
    ULONG i;
    NTSTATUS Status = STATUS_SUCCESS;

    for (i = 0; i < Required->Amount; i++)
    {
        DPRINTC("MiGetOnePage(%s:%d)\n", Required->File, Required->Line);
        Status = MmRequestPageMemoryConsumer(Required->Consumer,
                                             TRUE,
                                             &Required->Page[i]);
        if (!NT_SUCCESS(Status))
        {
            while (i > 0)
            {
                MmReleasePageMemoryConsumer(Required->Consumer,
                                            Required->Page[i-1]);
                i--;
            }
            return Status;
        }
    }

    return Status;
}
Exemple #3
0
PMMPTE
NTAPI
MiGetPageTableForProcess(IN PEPROCESS Process,
                         IN PVOID Address,
                         IN BOOLEAN Create)
{
    //ULONG PdeOffset;
    PMMPTE PointerPte;
    PMMPDE_HARDWARE PointerPde;
    MMPDE_HARDWARE TempPde;
    MMPTE TempPte;
    NTSTATUS Status;
    PFN_NUMBER Pfn;

    //
    // Check if this is a user-mode, non-kernel or non-current address
    //
    if ((Address < MmSystemRangeStart) &&
        (Process) &&
        (Process != PsGetCurrentProcess()))
    {
        //
        // FIXME-USER: No user-mode memory support
        //
        ASSERT(FALSE);
    }

    //
    // Get our templates
    //
    TempPde = MiArmTemplatePde;
    TempPte = MiArmTemplatePte;

    //
    // Get the PDE
    //
    PointerPde = MiGetPdeAddress(Address);
    if (PointerPde->u.Hard.Coarse.Valid)
    {
        //
        // Invalid PDE, is this a kernel address?
        //
        if (Address >= MmSystemRangeStart)
        {
            //
            // Does it exist in the kernel page directory?
            //
            //PdeOffset = MiGetPdeOffset(Address);
            //if (MmGlobalKernelPageDirectory[PdeOffset] == 0)
            {
                //
                // It doesn't. Is this a create operation? If not, fail
                //
                if (Create == FALSE) return NULL;
            kernelHack:
                DPRINT1("Must create a page for: %p PDE: %p\n", // Offset: %lx!\n",
                        Address, PointerPde);//, PdeOffset);

                //
                // Allocate a non paged pool page for the PDE
                //
                Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
                if (!NT_SUCCESS(Status)) return NULL;

                //
                // Setup the PFN
                //
                TempPde.u.Hard.Coarse.PageFrameNumber = (Pfn << PAGE_SHIFT) >> CPT_SHIFT;

                //
                // Write the PDE
                //
                ASSERT(PointerPde->u.Hard.Coarse.Valid == 0);
                ASSERT(TempPde.u.Hard.Coarse.Valid == 1);
                *PointerPde = TempPde;

                //
                // Save it
                //
                //MmGlobalKernelPageDirectory[PdeOffset] = TempPde.u.Hard.AsUlong;
                //DPRINT1("KPD: %p PDEADDR: %p\n", &MmGlobalKernelPageDirectory[PdeOffset], MiGetPdeAddress(Address));

                //
                // FIXFIX: Double check with Felix tomorrow
                //
/////
                //
                // Get the PTE for this 1MB region
                //
                PointerPte = MiGetPteAddress(MiGetPteAddress(Address));
                DPRINT1("PointerPte: %p\n", PointerPte);

                //
                // Write the PFN of the PDE
                //
                TempPte.u.Hard.PageFrameNumber = Pfn;

                //
                // Write the PTE
                //
                ASSERT(PointerPte->u.Hard.Valid == 0);
                ASSERT(TempPte.u.Hard.Valid == 1);
                *PointerPte = TempPte;
/////
            }

            //
            // Now set the actual PDE
            //
            //PointerPde = (PMMPTE)&MmGlobalKernelPageDirectory[PdeOffset];
        }
        else
        {
            //
            // Is this a create operation? If not, fail
            //
            if (Create == FALSE) return NULL;
Exemple #4
0
NTSTATUS
NTAPI
MiReadFilePage(PMMSUPPORT AddressSpace,
               PMEMORY_AREA MemoryArea,
               PMM_REQUIRED_RESOURCES RequiredResources)
{
    PFILE_OBJECT FileObject = RequiredResources->Context;
    PPFN_NUMBER Page = &RequiredResources->Page[RequiredResources->Offset];
    PLARGE_INTEGER FileOffset = &RequiredResources->FileOffset;
    NTSTATUS Status;
    PVOID PageBuf = NULL;
    KEVENT Event;
    IO_STATUS_BLOCK IOSB;
    UCHAR MdlBase[sizeof(MDL) + sizeof(ULONG)];
    PMDL Mdl = (PMDL)MdlBase;
    KIRQL OldIrql;

    DPRINTC("Pulling page %I64x from %wZ to %Ix\n",
            FileOffset->QuadPart,
            &FileObject->FileName,
            *Page);

    Status = MmRequestPageMemoryConsumer(RequiredResources->Consumer,
                                         TRUE,
                                         Page);

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

    MmInitializeMdl(Mdl, NULL, PAGE_SIZE);
    MmBuildMdlFromPages(Mdl, Page);
    Mdl->MdlFlags |= MDL_PAGES_LOCKED;

    KeInitializeEvent(&Event, NotificationEvent, FALSE);
    Status = IoPageRead(FileObject, Mdl, FileOffset, &Event, &IOSB);
    if (Status == STATUS_PENDING)
    {
        KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
        Status = IOSB.Status;
    }
    if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
    {
        MmUnmapLockedPages (Mdl->MappedSystemVa, Mdl);
    }

    PageBuf = MiMapPageInHyperSpace(PsGetCurrentProcess(), *Page, &OldIrql);
    if (!PageBuf)
    {
        MmReleasePageMemoryConsumer(RequiredResources->Consumer, *Page);
        return STATUS_NO_MEMORY;
    }

    RtlZeroMemory((PCHAR)PageBuf+RequiredResources->Amount,
                  PAGE_SIZE-RequiredResources->Amount);

    MiUnmapPageInHyperSpace(PsGetCurrentProcess(), PageBuf, OldIrql);

    DPRINT("Read Status %x (Page %x)\n", Status, *Page);

    if (!NT_SUCCESS(Status))
    {
        MmReleasePageMemoryConsumer(RequiredResources->Consumer, *Page);
        DPRINT("Status: %x\n", Status);
        return Status;
    }

    return STATUS_SUCCESS;
}