-/* $Id$
- *
+/*
* Copyright (C) 2002-2005 ReactOS Team (and the authors from the programmers section)
*
* This program is free software; you can redistribute it and/or
NTSTATUS
NTAPI
-MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
+MmWritePageVirtualMemory(PMM_AVL_TABLE AddressSpace,
PMEMORY_AREA MemoryArea,
PVOID Address,
PMM_PAGEOP PageOp)
SWAPENTRY SwapEntry;
PFN_TYPE Page;
NTSTATUS Status;
+ PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
/*
* Check for paging out from a deleted virtual memory area.
return(STATUS_UNSUCCESSFUL);
}
- Page = MmGetPfnForProcess(AddressSpace->Process, Address);
+ Page = MmGetPfnForProcess(Process, Address);
/*
* Get that the page actually is dirty.
*/
- if (!MmIsDirtyPage(AddressSpace->Process, Address))
+ if (!MmIsDirtyPage(Process, Address))
{
PageOp->Status = STATUS_SUCCESS;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
/*
* Speculatively set the mapping to clean.
*/
- MmSetCleanPage(AddressSpace->Process, Address);
+ MmSetCleanPage(Process, Address);
/*
* If necessary, allocate an entry in the paging file for this page
SwapEntry = MmAllocSwapPage();
if (SwapEntry == 0)
{
- MmSetDirtyPage(AddressSpace->Process, Address);
+ MmSetDirtyPage(Process, Address);
PageOp->Status = STATUS_PAGEFILE_QUOTA_EXCEEDED;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
MmReleasePageOp(PageOp);
{
DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n",
Status);
- MmSetDirtyPage(AddressSpace->Process, Address);
+ MmSetDirtyPage(Process, Address);
PageOp->Status = STATUS_UNSUCCESSFUL;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
MmReleasePageOp(PageOp);
NTSTATUS
NTAPI
-MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
+MmPageOutVirtualMemory(PMM_AVL_TABLE AddressSpace,
PMEMORY_AREA MemoryArea,
PVOID Address,
PMM_PAGEOP PageOp)
BOOLEAN WasDirty;
SWAPENTRY SwapEntry;
NTSTATUS Status;
-
+ PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
+
DPRINT("MmPageOutVirtualMemory(Address 0x%.8X) PID %d\n",
- Address, AddressSpace->Process->UniqueProcessId);
+ Address, Process->UniqueProcessId);
/*
* Check for paging out from a deleted virtual memory area.
/*
* Disable the virtual mapping.
*/
- MmDisableVirtualMapping(AddressSpace->Process, Address,
+ MmDisableVirtualMapping(Process, Address,
&WasDirty, &Page);
if (Page == 0)
if (!WasDirty)
{
MmLockAddressSpace(AddressSpace);
- MmDeleteVirtualMapping(AddressSpace->Process, Address, FALSE, NULL, NULL);
+ MmDeleteVirtualMapping(Process, Address, FALSE, NULL, NULL);
MmDeleteAllRmaps(Page, NULL, NULL);
if ((SwapEntry = MmGetSavedSwapEntryPage(Page)) != 0)
{
- MmCreatePageFileMapping(AddressSpace->Process, Address, SwapEntry);
+ MmCreatePageFileMapping(Process, Address, SwapEntry);
MmSetSavedSwapEntryPage(Page, 0);
}
MmUnlockAddressSpace(AddressSpace);
if (SwapEntry == 0)
{
MmShowOutOfSpaceMessagePagingFile();
- MmEnableVirtualMapping(AddressSpace->Process, Address);
+ MmEnableVirtualMapping(Process, Address);
PageOp->Status = STATUS_UNSUCCESSFUL;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
MmReleasePageOp(PageOp);
{
DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n",
Status);
- MmEnableVirtualMapping(AddressSpace->Process, Address);
+ MmEnableVirtualMapping(Process, Address);
PageOp->Status = STATUS_UNSUCCESSFUL;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
MmReleasePageOp(PageOp);
*/
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);
+ MmDeleteVirtualMapping(Process, Address, FALSE, NULL, NULL);
+ MmCreatePageFileMapping(Process, Address, SwapEntry);
MmUnlockAddressSpace(AddressSpace);
MmDeleteAllRmaps(Page, NULL, NULL);
MmSetSavedSwapEntryPage(Page, 0);
NTSTATUS
NTAPI
-MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
+MmNotPresentFaultVirtualMemory(PMM_AVL_TABLE AddressSpace,
MEMORY_AREA* MemoryArea,
PVOID Address,
BOOLEAN Locked)
NTSTATUS Status;
PMM_REGION Region;
PMM_PAGEOP PageOp;
-
+ PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
+
/*
* There is a window between taking the page fault and locking the
* address space when another thread could load the page so we check
/*
* Get or create a page operation
*/
- PageOp = MmGetPageOp(MemoryArea, AddressSpace->Process->UniqueProcessId,
+ PageOp = MmGetPageOp(MemoryArea, Process->UniqueProcessId,
(PVOID)PAGE_ROUND_DOWN(Address), NULL, 0,
MM_PAGEOP_PAGEIN, FALSE);
if (PageOp == NULL)
{
SWAPENTRY SwapEntry;
- MmDeletePageFileMapping(AddressSpace->Process, Address, &SwapEntry);
+ MmDeletePageFileMapping(Process, Address, &SwapEntry);
Status = MmReadFromSwapPage(SwapEntry, Page);
if (!NT_SUCCESS(Status))
{
* Set the page. If we fail because we are out of memory then
* try again
*/
- Status = MmCreateVirtualMapping(AddressSpace->Process,
+ Status = MmCreateVirtualMapping(Process,
(PVOID)PAGE_ROUND_DOWN(Address),
Region->Protect,
&Page,
while (Status == STATUS_NO_MEMORY)
{
MmUnlockAddressSpace(AddressSpace);
- Status = MmCreateVirtualMapping(AddressSpace->Process,
+ Status = MmCreateVirtualMapping(Process,
Address,
Region->Protect,
&Page,
/*
* Add the page to the process's working set
*/
- MmInsertRmap(Page, AddressSpace->Process, (PVOID)PAGE_ROUND_DOWN(Address));
+ MmInsertRmap(Page, Process, (PVOID)PAGE_ROUND_DOWN(Address));
/*
* Finish the operation
}
VOID static
-MmModifyAttributes(PMADDRESS_SPACE AddressSpace,
+MmModifyAttributes(PMM_AVL_TABLE AddressSpace,
PVOID BaseAddress,
ULONG RegionSize,
ULONG OldType,
* FUNCTION: Modify the attributes of a memory region
*/
{
+ PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
+
/*
* If we are switching a previously committed region to reserved then
* free any allocated pages within the region
{
PFN_TYPE Page;
- if (MmIsPageSwapEntry(AddressSpace->Process,
+ if (MmIsPageSwapEntry(Process,
(char*)BaseAddress + (i * PAGE_SIZE)))
{
SWAPENTRY SwapEntry;
- MmDeletePageFileMapping(AddressSpace->Process,
+ MmDeletePageFileMapping(Process,
(char*)BaseAddress + (i * PAGE_SIZE),
&SwapEntry);
MmFreeSwapPage(SwapEntry);
}
else
{
- MmDeleteVirtualMapping(AddressSpace->Process,
+ MmDeleteVirtualMapping(Process,
(char*)BaseAddress + (i*PAGE_SIZE),
FALSE, NULL, &Page);
if (Page != 0)
MmFreeSwapPage(SavedSwapEntry);
MmSetSavedSwapEntryPage(Page, 0);
}
- MmDeleteRmap(Page, AddressSpace->Process,
+ MmDeleteRmap(Page, Process,
(char*)BaseAddress + (i * PAGE_SIZE));
MmReleasePageMemoryConsumer(MC_USER, Page);
}
for (i=0; i < PAGE_ROUND_UP(RegionSize)/PAGE_SIZE; i++)
{
- if (MmIsPagePresent(AddressSpace->Process,
+ if (MmIsPagePresent(Process,
(char*)BaseAddress + (i*PAGE_SIZE)))
{
- MmSetPageProtect(AddressSpace->Process,
+ MmSetPageProtect(Process,
(char*)BaseAddress + (i*PAGE_SIZE),
NewProtect);
}
NtAllocateVirtualMemory(IN HANDLE ProcessHandle,
IN OUT PVOID* UBaseAddress,
IN ULONG ZeroBits,
- IN OUT PULONG URegionSize,
+ IN OUT PSIZE_T URegionSize,
IN ULONG AllocationType,
IN ULONG Protect)
/*
* PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE, PAGE_GUARD,
* PAGE_NOACCESS
* RETURNS: Status
- * NOTES: Must run at IRQL PASSIVE_LEVEL? (or is APC_LEVEL cool too?)
- * MSDN states that ZwAllocateVirtualMemory IRQL must be PASSIVE_LEVEL,
- * but why wouldn't APC_LEVEL be valid (or is that only for the Zw* version
- * and Nt* can indeed run at APC_LEVEL?)
*/
{
PEPROCESS Process;
ULONG_PTR MemoryAreaLength;
ULONG Type;
NTSTATUS Status;
- PMADDRESS_SPACE AddressSpace;
+ PMM_AVL_TABLE AddressSpace;
PVOID BaseAddress;
ULONG RegionSize;
PVOID PBaseAddress;
PHYSICAL_ADDRESS BoundaryAddressMultiple;
KPROCESSOR_MODE PreviousMode;
- // TMN: Someone Pick one of these. Until it's clear which
- // level is allowed, I play it safe and check for <= APC_LEVEL
PAGED_CODE();
-// ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
DPRINT("NtAllocateVirtualMemory(*UBaseAddress %x, "
"ZeroBits %d, *URegionSize %x, AllocationType %x, Protect %x)\n",
* 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)
+ if ((ULONG_PTR)BaseAddress >= USER_SHARED_DATA)
{
DPRINT1("Virtual allocation base above User Space\n");
return STATUS_INVALID_PARAMETER_2;
DPRINT1("Region size is invalid (zero)\n");
return STATUS_INVALID_PARAMETER_4;
}
- if (((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (ULONG_PTR)BaseAddress) < RegionSize)
+ if ((USER_SHARED_DATA - (ULONG_PTR)BaseAddress) < RegionSize)
{
DPRINT1("Region size would overflow into kernel-memory\n");
return STATUS_INVALID_PARAMETER_4;
Type = (AllocationType & MEM_COMMIT) ? MEM_COMMIT : MEM_RESERVE;
DPRINT("Type %x\n", Type);
- AddressSpace = (PMADDRESS_SPACE)&Process->VadRoot;
+ AddressSpace = &Process->VadRoot;
MmLockAddressSpace(AddressSpace);
if (PBaseAddress != 0)
}
else if (MemoryAreaLength >= RegionSize)
{
- Status =
- MmAlterRegion(AddressSpace,
- MemoryArea->StartingAddress,
- &MemoryArea->Data.SectionData.RegionListHead,
- BaseAddress, RegionSize,
- Type, Protect, MmModifyAttributes);
+ /* Region list initialized? */
+ if (MemoryArea->Data.SectionData.RegionListHead.Flink)
+ {
+ Status =
+ MmAlterRegion(AddressSpace,
+ MemoryArea->StartingAddress,
+ &MemoryArea->Data.SectionData.RegionListHead,
+ BaseAddress, RegionSize,
+ Type, Protect, MmModifyAttributes);
+ }
+ else
+ {
+ Status = STATUS_ACCESS_VIOLATION;
+ }
+
MmUnlockAddressSpace(AddressSpace);
ObDereferenceObject(Process);
DPRINT("NtAllocateVirtualMemory() = %x\n",Status);
if (PageOp != NULL)
{
NTSTATUS Status;
- MmUnlockAddressSpace((PMADDRESS_SPACE)&Process->VadRoot);
+ MmUnlockAddressSpace(&Process->VadRoot);
Status = KeWaitForSingleObject(&PageOp->CompletionEvent,
0,
KernelMode,
DPRINT1("Failed to wait for page op\n");
KEBUGCHECK(0);
}
- MmLockAddressSpace((PMADDRESS_SPACE)&Process->VadRoot);
+ MmLockAddressSpace(&Process->VadRoot);
MmReleasePageOp(PageOp);
}
}
}
/* Actually free the memory area. */
- MmFreeMemoryArea((PMADDRESS_SPACE)&Process->VadRoot,
+ MmFreeMemoryArea(&Process->VadRoot,
MemoryArea,
MmFreeVirtualMemoryPage,
(PVOID)Process);
NTSTATUS STDCALL
NtFreeVirtualMemory(IN HANDLE ProcessHandle,
IN PVOID* PBaseAddress,
- IN PULONG PRegionSize,
+ IN PSIZE_T PRegionSize,
IN ULONG FreeType)
/*
* FUNCTION: Frees a range of virtual memory
MEMORY_AREA* MemoryArea;
NTSTATUS Status;
PEPROCESS Process;
- PMADDRESS_SPACE AddressSpace;
+ PMM_AVL_TABLE AddressSpace;
PVOID BaseAddress;
ULONG RegionSize;
return(Status);
}
- AddressSpace = (PMADDRESS_SPACE)&Process->VadRoot;
+ AddressSpace = &Process->VadRoot;
MmLockAddressSpace(AddressSpace);
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, BaseAddress);
NTSTATUS
NTAPI
-MmProtectAnonMem(PMADDRESS_SPACE AddressSpace,
+MmProtectAnonMem(PMM_AVL_TABLE AddressSpace,
PMEMORY_AREA MemoryArea,
PVOID BaseAddress,
ULONG Length,