IN SECTION_INHERIT InheritDisposition,
IN ULONG AllocationType,
IN ULONG Protect);
-
+
//
// PeFmtCreateSection depends on the following:
//
NTAPI
MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
MEMORY_AREA* MemoryArea,
- PVOID Address,
- BOOLEAN Locked)
+ PVOID Address)
{
ULONG Offset;
PFN_NUMBER Page;
NTSTATUS Status;
- PVOID PAddress;
PROS_SECTION_OBJECT Section;
PMM_SECTION_SEGMENT Segment;
ULONG_PTR Entry;
{
return(STATUS_SUCCESS);
}
+
+ /*
+ * Check for the virtual memory area being deleted.
+ */
+ if (MemoryArea->DeleteInProgress)
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
- PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
- Offset = (ULONG)((ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress
+ Address = MM_ROUND_DOWN(Address, PAGE_SIZE);
+ Offset = (ULONG)((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
+ MemoryArea->Data.SectionData.ViewOffset);
Segment = MemoryArea->Data.SectionData.Segment;
if (!MmIsPagePresent(Process, Address))
{
Entry = MmGetPageEntrySectionSegment(Segment, Offset);
- HasSwapEntry = MmIsPageSwapEntry(Process, (PVOID)PAddress);
+ HasSwapEntry = MmIsPageSwapEntry(Process, (PVOID)Address);
if (PAGE_FROM_SSE(Entry) == 0 || HasSwapEntry)
{
DPRINT1("Unable to create virtual mapping\n");
KeBugCheck(MEMORY_MANAGEMENT);
}
- MmInsertRmap(Page, Process, (PVOID)PAddress);
+ MmInsertRmap(Page, Process, Address);
}
MmUnlockSectionSegment(Segment);
PageOp->Status = STATUS_SUCCESS;
return(STATUS_SUCCESS);
}
- HasSwapEntry = MmIsPageSwapEntry(Process, (PVOID)PAddress);
+ HasSwapEntry = MmIsPageSwapEntry(Process, Address);
if (HasSwapEntry)
{
/*
}
MmUnlockSectionSegment(Segment);
- MmDeletePageFileMapping(Process, (PVOID)PAddress, &SwapEntry);
+ MmDeletePageFileMapping(Process, Address, &SwapEntry);
MmUnlockAddressSpace(AddressSpace);
MI_SET_USAGE(MI_USAGE_SECTION);
/*
* Add the page to the process's working set
*/
- MmInsertRmap(Page, Process, (PVOID)PAddress);
-
+ MmInsertRmap(Page, Process, Address);
/*
* Finish the operation
*/
KeBugCheck(MEMORY_MANAGEMENT);
return(Status);
}
- MmInsertRmap(Page, Process, (PVOID)PAddress);
+ MmInsertRmap(Page, Process, Address);
/*
* Cleanup and release locks
{
DPRINT1("MmRequestPageMemoryConsumer failed (Status %x)\n", Status);
}
-
+
}
else
{
DPRINT1("Unable to create virtual mapping\n");
KeBugCheck(MEMORY_MANAGEMENT);
}
- MmInsertRmap(Page, Process, (PVOID)PAddress);
+ MmInsertRmap(Page, Process, Address);
PageOp->Status = STATUS_SUCCESS;
MmspCompleteAndReleasePageOp(PageOp);
DPRINT1("Unable to create virtual mapping\n");
KeBugCheck(MEMORY_MANAGEMENT);
}
- MmInsertRmap(Page, Process, (PVOID)PAddress);
+ MmInsertRmap(Page, Process, Address);
PageOp->Status = STATUS_SUCCESS;
MmspCompleteAndReleasePageOp(PageOp);
DPRINT("Address 0x%.8X\n", Address);
DPRINT1("Unable to create virtual mapping\n");
KeBugCheck(MEMORY_MANAGEMENT);
}
- MmInsertRmap(Page, Process, (PVOID)PAddress);
+ MmInsertRmap(Page, Process, Address);
PageOp->Status = STATUS_SUCCESS;
MmspCompleteAndReleasePageOp(PageOp);
DPRINT("Address 0x%.8X\n", Address);
NTAPI
MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
MEMORY_AREA* MemoryArea,
- PVOID Address,
- BOOLEAN Locked)
+ PVOID Address)
{
PMM_SECTION_SEGMENT Segment;
PROS_SECTION_OBJECT Section;
PFN_NUMBER OldPage;
PFN_NUMBER NewPage;
NTSTATUS Status;
- PVOID PAddress;
ULONG Offset;
PMM_PAGEOP PageOp;
PMM_REGION Region;
ULONG Entry;
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
-
- DPRINT("MmAccessFaultSectionView(%x, %x, %x, %x)\n", AddressSpace, MemoryArea, Address, Locked);
+
+ DPRINT("MmAccessFaultSectionView(%x, %x, %x, %x)\n", AddressSpace, MemoryArea, Address);
/*
- * Check if the page has been paged out or has already been set readwrite
+ * Check if the page has already been set readwrite
*/
- if (!MmIsPagePresent(Process, Address) ||
- MmGetPageProtect(Process, Address) & PAGE_READWRITE)
+ if (MmGetPageProtect(Process, Address) & PAGE_READWRITE)
{
DPRINT("Address 0x%.8X\n", Address);
return(STATUS_SUCCESS);
/*
* Find the offset of the page
*/
- PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
- Offset = (ULONG)((ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress
+ Address = MM_ROUND_DOWN(Address, PAGE_SIZE);
+ Offset = (ULONG)((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
+ MemoryArea->Data.SectionData.ViewOffset);
Segment = MemoryArea->Data.SectionData.Segment;
*/
MmLockSectionSegment(Segment);
- OldPage = MmGetPfnForProcess(NULL, Address);
+ OldPage = MmGetPfnForProcess(Process, Address);
Entry = MmGetPageEntrySectionSegment(Segment, Offset);
MmUnlockSectionSegment(Segment);
PFN_FROM_SSE(Entry) != OldPage)
{
/* This is a private page. We must only change the page protection. */
- MmSetPageProtect(Process, PAddress, Region->Protect);
+ MmSetPageProtect(Process, Address, Region->Protect);
return(STATUS_SUCCESS);
}
/*
* Copy the old page
*/
- MiCopyFromUserPage(NewPage, PAddress);
+ MiCopyFromUserPage(NewPage, Address);
MmLockAddressSpace(AddressSpace);
/*
/*
* Unshare the old page.
*/
- MmDeleteRmap(OldPage, Process, PAddress);
- MmInsertRmap(NewPage, Process, PAddress);
+ MmDeleteRmap(OldPage, Process, Address);
+ MmInsertRmap(NewPage, Process, Address);
MmLockSectionSegment(Segment);
MmUnsharePageEntrySectionSegment(Section, Segment, Offset, FALSE, FALSE);
MmUnlockSectionSegment(Segment);
Page = MmGetPfnForProcess(Process, Address);
SwapEntry = MmGetSavedSwapEntryPage(Page);
+ /*
+ * Check the reference count to ensure this page can be paged out
+ */
+ if (MmGetReferenceCountPage(Page) != 1)
+ {
+ DPRINT1("Cannot page out locked section page: 0x%p (RefCount: %d)\n",
+ Page, MmGetReferenceCountPage(Page));
+ PageOp->Status = STATUS_UNSUCCESSFUL;
+ MmspCompleteAndReleasePageOp(PageOp);
+ return STATUS_UNSUCCESSFUL;
+ }
+
/*
* Prepare the context structure for the rmap delete call.
*/
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, BaseAddress);
+ ASSERT(MemoryArea);
Segment = MemoryArea->Data.SectionData.Segment;
if ((Segment->WriteCopy) &&
ImageSectionObject->ImageSize = (ULONG)ImageSize;
+ /* Check for an illegal base address */
+ if ((ImageBase + ImageSize) > (ULONG_PTR)MmHighestUserAddress)
+ {
+ ImageBase = PAGE_ROUND_DOWN((ULONG_PTR)MmHighestUserAddress - ImageSize);
+ }
+
/* Check there is enough space to map the section at that point. */
if (MmLocateMemoryAreaByRegion(AddressSpace, (PVOID)ImageBase,
PAGE_ROUND_UP(ImageSize)) != NULL)
DPRINT("MmUnmapViewInSystemSpace() called\n");
AddressSpace = MmGetKernelAddressSpace();
+
+ MmLockAddressSpace(AddressSpace);
Status = MmUnmapViewOfSegment(AddressSpace, MappedBase);
+
+ MmUnlockAddressSpace(AddressSpace);
return Status;
}