Ejemplo n.º 1
0
NTSTATUS
NTAPI
_MmSetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment,
                              PLARGE_INTEGER Offset,
                              ULONG_PTR Entry,
                              const char *file,
                              int line)
{
    ULONG_PTR PageIndex, OldEntry;
    PCACHE_SECTION_PAGE_TABLE PageTable;

    ASSERT(Segment->Locked);
    ASSERT(!IS_SWAP_FROM_SSE(Entry) || !IS_DIRTY_SSE(Entry));

    if (Entry && !IS_SWAP_FROM_SSE(Entry))
        MmGetRmapListHeadPage(PFN_FROM_SSE(Entry));

    PageTable = MiSectionPageTableGetOrAllocate(&Segment->PageTable, Offset);

    if (!PageTable) return STATUS_NO_MEMORY;

    ASSERT(MiSectionPageTableGet(&Segment->PageTable, Offset));

    PageTable->Segment = Segment;
    PageIndex = (ULONG_PTR)((Offset->QuadPart - PageTable->FileOffset.QuadPart) / PAGE_SIZE);
    OldEntry = PageTable->PageEntries[PageIndex];

    DPRINT("MiSetPageEntrySectionSegment(%p,%08x%08x,%x=>%x)\n",
            Segment,
            Offset->u.HighPart,
            Offset->u.LowPart,
            OldEntry,
            Entry);

    if (PFN_FROM_SSE(Entry) == PFN_FROM_SSE(OldEntry)) {
        /* Nothing */
    } else if (Entry && !IS_SWAP_FROM_SSE(Entry)) {
        ASSERT(!OldEntry || IS_SWAP_FROM_SSE(OldEntry));
        MmSetSectionAssociation(PFN_FROM_SSE(Entry), Segment, Offset);
    } else if (OldEntry && !IS_SWAP_FROM_SSE(OldEntry)) {
        ASSERT(!Entry || IS_SWAP_FROM_SSE(Entry));
        MmDeleteSectionAssociation(PFN_FROM_SSE(OldEntry));
    } else if (IS_SWAP_FROM_SSE(Entry)) {
        ASSERT(!IS_SWAP_FROM_SSE(OldEntry) ||
               SWAPENTRY_FROM_SSE(OldEntry) == MM_WAIT_ENTRY);
        if (OldEntry && SWAPENTRY_FROM_SSE(OldEntry) != MM_WAIT_ENTRY)
            MmDeleteSectionAssociation(PFN_FROM_SSE(OldEntry));
    } else if (IS_SWAP_FROM_SSE(OldEntry)) {
        ASSERT(!IS_SWAP_FROM_SSE(Entry));
        if (Entry)
            MmSetSectionAssociation(PFN_FROM_SSE(OldEntry), Segment, Offset);
    } else {
        /* We should not be replacing a page like this */
        ASSERT(FALSE);
    }
    PageTable->PageEntries[PageIndex] = Entry;
    return STATUS_SUCCESS;
}
Ejemplo n.º 2
0
/*

MmWithdrawSectionPage removes a page entry from the section segment, replacing
it with a wait entry.  The caller must replace the wait entry with a 0, when
any required writing is done.  The wait entry must remain until the page is
written to protect against cases where a fault brings a stale copy of the page
back before writing is complete.

*/
PFN_NUMBER
NTAPI
MmWithdrawSectionPage(PMM_SECTION_SEGMENT Segment,
                      PLARGE_INTEGER FileOffset,
                      BOOLEAN *Dirty)
{
    ULONG_PTR Entry;

    DPRINT("MmWithdrawSectionPage(%p,%08x%08x,%p)\n",
           Segment,
           FileOffset->HighPart,
           FileOffset->LowPart,
           Dirty);

    MmLockSectionSegment(Segment);
    Entry = MmGetPageEntrySectionSegment(Segment, FileOffset);

    *Dirty = !!IS_DIRTY_SSE(Entry);

    DPRINT("Withdraw %x (%x) of %wZ\n",
           FileOffset->LowPart,
           Entry,
           Segment->FileObject ? &Segment->FileObject->FileName : NULL);

    if (!Entry)
    {
        DPRINT("Stoeled!\n");
        MmUnlockSectionSegment(Segment);
        return 0;
    }
    else if (MM_IS_WAIT_PTE(Entry))
    {
        DPRINT("WAIT\n");
        MmUnlockSectionSegment(Segment);
        return MM_WAIT_ENTRY;
    }
    else if (Entry && !IS_SWAP_FROM_SSE(Entry))
    {
        DPRINT("Page %x\n", PFN_FROM_SSE(Entry));

        *Dirty |= (Entry & 2);

        MmSetPageEntrySectionSegment(Segment,
                                     FileOffset,
                                     MAKE_SWAP_SSE(MM_WAIT_ENTRY));

        MmUnlockSectionSegment(Segment);
        return PFN_FROM_SSE(Entry);
    }
    else
    {
        DPRINT1("SWAP ENTRY?! (%p:%08x%08x)\n",
                Segment,
                FileOffset->HighPart,
                FileOffset->LowPart);

        ASSERT(FALSE);
        MmUnlockSectionSegment(Segment);
        return 0;
    }
}