Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
if (Entry == 0)
{
/*
* If the entry is zero, then we need to load the page.
*/
if ((Offset.QuadPart >= (LONGLONG)PAGE_ROUND_UP(Segment->RawLength.QuadPart)) && (MemoryArea->VadNode.u.VadFlags.VadType == VadImageMap))
{
/* We are beyond the data which is on file. Just get a new page. */
MI_SET_USAGE(MI_USAGE_SECTION);
if (Process) MI_SET_PROCESS2(Process->ImageFileName);
if (!Process) MI_SET_PROCESS2("Kernel Section");
Status = MmRequestPageMemoryConsumer(MC_USER, FALSE, &Page);
if (!NT_SUCCESS(Status))
{
MmUnlockSectionSegment(Segment);
return STATUS_NO_MEMORY;
}
MmSetPageEntrySectionSegment(Segment, &Offset, MAKE_SSE(Page << PAGE_SHIFT, 1));
MmUnlockSectionSegment(Segment);
Status = MmCreateVirtualMapping(Process, PAddress, Attributes, Page);
if (!NT_SUCCESS(Status))
{
DPRINT1("Unable to create virtual mapping\n");
KeBugCheck(MEMORY_MANAGEMENT);
}
ASSERT(MmIsPagePresent(Process, PAddress));
if (Process)
MmInsertRmap(Page, Process, Address);
DPRINT("Address 0x%p\n", Address);
return STATUS_SUCCESS;
}
MmUnlockSectionSegment(Segment);
MmUnlockAddressSpace(AddressSpace);
/* The data must be paged in. Lock the file, so that the VDL doesn't get updated behind us. */
FsRtlAcquireFileExclusive(Segment->FileObject);
PFSRTL_COMMON_FCB_HEADER FcbHeader = Segment->FileObject->FsContext;
Status = MmMakeSegmentResident(Segment, Offset.QuadPart, PAGE_SIZE, &FcbHeader->ValidDataLength, FALSE);
FsRtlReleaseFile(Segment->FileObject);
/* Lock address space again */
MmLockAddressSpace(AddressSpace);
if (!NT_SUCCESS(Status))
{
if (Status == STATUS_NO_MEMORY)
{
return Status;
}
/* Damn */
DPRINT1("Failed to page data in!\n");
return STATUS_IN_PAGE_ERROR;
}
/* Everything went fine. Restart the operation */
return STATUS_MM_RESTART_OPERATION;
}
/* We already have a page on this section offset. Map it into the process address space. */
Page = PFN_FROM_SSE(Entry);
Status = MmCreateVirtualMapping(Process,
PAddress,
Attributes,
Page);
if (!NT_SUCCESS(Status))
{
DPRINT1("Unable to create virtual mapping\n");
KeBugCheck(MEMORY_MANAGEMENT);
}
if (Process)
MmInsertRmap(Page, Process, Address);
/* Take a reference on it */
MmSharePageEntrySectionSegment(Segment, &Offset);
MmUnlockSectionSegment(Segment);
DPRINT("Address 0x%p\n", Address);
return STATUS_SUCCESS;