/* FUNCTIONS *****************************************************************/
NTSTATUS
+NTAPI
MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
PMEMORY_AREA MemoryArea,
PVOID Address,
}
NTSTATUS
+NTAPI
MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
PMEMORY_AREA MemoryArea,
PVOID Address,
*/
if (!WasDirty)
{
+ MmLockAddressSpace(AddressSpace);
MmDeleteVirtualMapping(AddressSpace->Process, Address, FALSE, NULL, NULL);
MmDeleteAllRmaps(Page, NULL, NULL);
if ((SwapEntry = MmGetSavedSwapEntryPage(Page)) != 0)
MmCreatePageFileMapping(AddressSpace->Process, Address, SwapEntry);
MmSetSavedSwapEntryPage(Page, 0);
}
+ MmUnlockAddressSpace(AddressSpace);
MmReleasePageMemoryConsumer(MC_USER, Page);
PageOp->Status = STATUS_SUCCESS;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
* Otherwise we have succeeded, free the page
*/
DPRINT("MM: Swapped out virtual memory page 0x%.8X!\n", Page << PAGE_SHIFT);
+ MmLockAddressSpace(AddressSpace);
MmDeleteVirtualMapping(AddressSpace->Process, Address, FALSE, NULL, NULL);
MmCreatePageFileMapping(AddressSpace->Process, Address, SwapEntry);
+ MmUnlockAddressSpace(AddressSpace);
MmDeleteAllRmaps(Page, NULL, NULL);
MmSetSavedSwapEntryPage(Page, 0);
MmReleasePageMemoryConsumer(MC_USER, Page);
}
NTSTATUS
+NTAPI
MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
MEMORY_AREA* MemoryArea,
PVOID Address,
*UBaseAddress,ZeroBits,*URegionSize,AllocationType,
Protect);
- /*
- * Check the validity of the parameters
- */
+ /* Check for valid protection flags */
if ((Protect & PAGE_FLAGS_VALID_FROM_USER_MODE) != Protect)
{
- return(STATUS_INVALID_PAGE_PROTECTION);
+ DPRINT1("Invalid page protection\n");
+ return STATUS_INVALID_PAGE_PROTECTION;
+ }
+
+ /* Check for valid Zero bits */
+ if (ZeroBits > 21)
+ {
+ DPRINT1("Too many zero bits\n");
+ return STATUS_INVALID_PARAMETER_3;
+ }
+
+ /* Check for valid Allocation Types */
+ if ((AllocationType &~ (MEM_COMMIT | MEM_RESERVE | MEM_RESET | MEM_PHYSICAL |
+ MEM_TOP_DOWN | MEM_WRITE_WATCH)))
+ {
+ DPRINT1("Invalid Allocation Type\n");
+ return STATUS_INVALID_PARAMETER_5;
+ }
+
+ /* Check for at least one of these Allocation Types to be set */
+ if (!(AllocationType & (MEM_COMMIT | MEM_RESERVE | MEM_RESET)))
+ {
+ DPRINT1("No memory allocation base type\n");
+ return STATUS_INVALID_PARAMETER_5;
}
- if ((AllocationType & (MEM_COMMIT | MEM_RESERVE)) == 0)
+
+ /* MEM_RESET is an exclusive flag, make sure that is valid too */
+ if ((AllocationType & MEM_RESET) && (AllocationType != MEM_RESET))
{
- return(STATUS_INVALID_PARAMETER);
+ DPRINT1("MEM_RESET used illegaly\n");
+ return STATUS_INVALID_PARAMETER_5;
+ }
+
+ /* MEM_WRITE_WATCH can only be used if MEM_RESERVE is also used */
+ if ((AllocationType & MEM_WRITE_WATCH) && !(AllocationType & MEM_RESERVE))
+ {
+ DPRINT1("MEM_WRITE_WATCH used without MEM_RESERVE\n");
+ return STATUS_INVALID_PARAMETER_5;
+ }
+
+ /* MEM_PHYSICAL can only be used with MEM_RESERVE, and can only be R/W */
+ if (AllocationType & MEM_PHYSICAL)
+ {
+ /* First check for MEM_RESERVE exclusivity */
+ if (AllocationType != (MEM_RESERVE | MEM_PHYSICAL))
+ {
+ DPRINT1("MEM_PHYSICAL used with other flags then MEM_RESERVE or"
+ "MEM_RESERVE was not present at all\n");
+ return STATUS_INVALID_PARAMETER_5;
+ }
+
+ /* Then make sure PAGE_READWRITE is used */
+ if (Protect != PAGE_READWRITE)
+ {
+ DPRINT1("MEM_PHYSICAL used without PAGE_READWRITE\n");
+ return STATUS_INVALID_PAGE_PROTECTION;
+ }
}
PBaseAddress = *UBaseAddress;
RegionSize = PAGE_ROUND_UP(PBaseAddress + PRegionSize) -
PAGE_ROUND_DOWN(PBaseAddress);
+ /*
+ * We've captured and calculated the data, now do more checks
+ * Yes, MmCreateMemoryArea does similar checks, but they don't return
+ * the right status codes that a caller of this routine would expect.
+ */
+ if (BaseAddress >= MM_HIGHEST_USER_ADDRESS)
+ {
+ DPRINT1("Virtual allocation above User Space\n");
+ return STATUS_INVALID_PARAMETER_2;
+ }
+ if (!RegionSize)
+ {
+ DPRINT1("Region size is invalid\n");
+ return STATUS_INVALID_PARAMETER_4;
+ }
+ if (((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (ULONG_PTR)BaseAddress) < RegionSize)
+ {
+ DPRINT1("Region size would overflow into kernel-memory\n");
+ return STATUS_INVALID_PARAMETER_4;
+ }
+
+ /*
+ * Copy on Write is reserved for system use. This case is a certain failure
+ * but there may be other cases...needs more testing
+ */
+ if ((!BaseAddress || (AllocationType & MEM_RESERVE)) &&
+ ((Protect & PAGE_WRITECOPY) || (Protect & PAGE_EXECUTE_WRITECOPY)))
+ {
+ DPRINT1("Copy on write is not supported by VirtualAlloc\n");
+ return STATUS_INVALID_PAGE_PROTECTION;
+ }
+
+
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_VM_OPERATION,
NULL,
}
VOID
+NTAPI
MmFreeVirtualMemory(PEPROCESS Process,
PMEMORY_AREA MemoryArea)
{
}
NTSTATUS
+NTAPI
MmProtectAnonMem(PMADDRESS_SPACE AddressSpace,
PMEMORY_AREA MemoryArea,
PVOID BaseAddress,
Info->BaseAddress = RegionBase;
Info->AllocationBase = MemoryArea->StartingAddress;
Info->AllocationProtect = MemoryArea->Attributes;
- Info->RegionSize = (char*)RegionBase + Region->Length - (char*)Info->BaseAddress;
+ Info->RegionSize = Region->Length;
Info->State = Region->Type;
Info->Protect = Region->Protect;
Info->Type = MEM_PRIVATE;