#define NDEBUG
#include <debug.h>
-#if defined (ALLOC_PRAGMA)
-#pragma alloc_text(INIT, MmInitMemoryAreas)
-#endif
+MEMORY_AREA MiStaticMemoryAreas[MI_STATIC_MEMORY_AREAS];
+ULONG MiStaticMemoryAreaCount;
/* #define VALIDATE_MEMORY_AREAS */
}
#ifdef VALIDATE_MEMORY_AREAS
-static VOID MmVerifyMemoryAreas(PMM_AVL_TABLE AddressSpace)
+static VOID MmVerifyMemoryAreas(PMMSUPPORT AddressSpace)
{
PMEMORY_AREA Node;
ASSERT(AddressSpace != NULL);
/* Special case for empty tree. */
- if (AddressSpace->BalancedRoot.u1.Parent == NULL)
+ if (AddressSpace->WorkingSetExpansionLinks.Flink == NULL)
return;
/* Traverse the tree from left to right. */
- for (Node = MmIterateFirstNode(AddressSpace->BalancedRoot.u1.Parent);
+ for (Node = MmIterateFirstNode(AddressSpace->WorkingSetExpansionLinks.Flink);
Node != NULL;
Node = MmIterateNextNode(Node))
{
#define MmVerifyMemoryAreas(x)
#endif
-VOID STDCALL
-MmDumpMemoryAreas(PMM_AVL_TABLE AddressSpace)
+VOID NTAPI
+MmDumpMemoryAreas(PMMSUPPORT AddressSpace)
{
PMEMORY_AREA Node;
DbgPrint("MmDumpMemoryAreas()\n");
/* Special case for empty tree. */
- if (AddressSpace->BalancedRoot.u1.Parent == NULL)
+ if (AddressSpace->WorkingSetExpansionLinks.Flink == NULL)
return;
/* Traverse the tree from left to right. */
- for (Node = MmIterateFirstNode((PMEMORY_AREA)AddressSpace->BalancedRoot.u1.Parent);
+ for (Node = MmIterateFirstNode((PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink);
Node != NULL;
Node = MmIterateNextNode(Node))
{
DbgPrint("Finished MmDumpMemoryAreas()\n");
}
-PMEMORY_AREA STDCALL
+PMEMORY_AREA NTAPI
MmLocateMemoryAreaByAddress(
- PMM_AVL_TABLE AddressSpace,
+ PMMSUPPORT AddressSpace,
PVOID Address)
{
- PMEMORY_AREA Node = (PMEMORY_AREA)AddressSpace->BalancedRoot.u1.Parent;
+ PMEMORY_AREA Node = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink;
DPRINT("MmLocateMemoryAreaByAddress(AddressSpace %p, Address %p)\n",
AddressSpace, Address);
return NULL;
}
-PMEMORY_AREA STDCALL
+PMEMORY_AREA NTAPI
MmLocateMemoryAreaByRegion(
- PMM_AVL_TABLE AddressSpace,
+ PMMSUPPORT AddressSpace,
PVOID Address,
ULONG_PTR Length)
{
MmVerifyMemoryAreas(AddressSpace);
/* Special case for empty tree. */
- if (AddressSpace->BalancedRoot.u1.Parent == NULL)
+ if (AddressSpace->WorkingSetExpansionLinks.Flink == NULL)
return NULL;
/* Traverse the tree from left to right. */
- for (Node = MmIterateFirstNode((PMEMORY_AREA)AddressSpace->BalancedRoot.u1.Parent);
+ for (Node = MmIterateFirstNode((PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink);
Node != NULL;
Node = MmIterateNextNode(Node))
{
static VOID
MmCompressHelper(
- PMM_AVL_TABLE AddressSpace,
+ PMMSUPPORT AddressSpace,
ULONG Count)
{
PMEMORY_AREA Root = NULL;
- PMEMORY_AREA Red = (PMEMORY_AREA)AddressSpace->BalancedRoot.u1.Parent;
+ PMEMORY_AREA Red = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink;
PMEMORY_AREA Black = Red->LeftChild;
while (Count--)
if (Root)
Root->LeftChild = Black;
else
- AddressSpace->BalancedRoot.u1.Parent = (PVOID)Black;
+ AddressSpace->WorkingSetExpansionLinks.Flink = (PVOID)Black;
Black->Parent = Root;
Red->LeftChild = Black->RightChild;
if (Black->RightChild)
static VOID
MmRebalanceTree(
- PMM_AVL_TABLE AddressSpace)
+ PMMSUPPORT AddressSpace)
{
PMEMORY_AREA PreviousNode;
PMEMORY_AREA CurrentNode;
/* Transform the tree into Vine. */
PreviousNode = NULL;
- CurrentNode = (PMEMORY_AREA)AddressSpace->BalancedRoot.u1.Parent;
+ CurrentNode = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink;
while (CurrentNode != NULL)
{
if (CurrentNode->RightChild == NULL)
if (PreviousNode != NULL)
PreviousNode->LeftChild = TempNode;
else
- AddressSpace->BalancedRoot.u1.Parent = (PVOID)TempNode;
+ AddressSpace->WorkingSetExpansionLinks.Flink = (PVOID)TempNode;
TempNode->Parent = PreviousNode;
}
}
static VOID
MmInsertMemoryArea(
- PMM_AVL_TABLE AddressSpace,
+ PMMSUPPORT AddressSpace,
PMEMORY_AREA marea)
{
PMEMORY_AREA Node;
MmVerifyMemoryAreas(AddressSpace);
- if (AddressSpace->BalancedRoot.u1.Parent == NULL)
+ if (AddressSpace->WorkingSetExpansionLinks.Flink == NULL)
{
- AddressSpace->BalancedRoot.u1.Parent = (PVOID)marea;
+ AddressSpace->WorkingSetExpansionLinks.Flink = (PVOID)marea;
marea->LeftChild = marea->RightChild = marea->Parent = NULL;
return;
}
- Node = (PMEMORY_AREA)AddressSpace->BalancedRoot.u1.Parent;
+ Node = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink;
do
{
DPRINT("marea->EndingAddress: %p Node->StartingAddress: %p\n",
static PVOID
MmFindGapBottomUp(
- PMM_AVL_TABLE AddressSpace,
+ PMMSUPPORT AddressSpace,
ULONG_PTR Length,
ULONG_PTR Granularity)
{
AlignedAddress = MM_ROUND_UP(LowestAddress, Granularity);
/* Special case for empty tree. */
- if (AddressSpace->BalancedRoot.u1.Parent == NULL)
+ if (AddressSpace->WorkingSetExpansionLinks.Flink == NULL)
{
if ((ULONG_PTR)HighestAddress - (ULONG_PTR)AlignedAddress >= Length)
{
}
/* Go to the node with lowest address in the tree. */
- FirstNode = Node = MmIterateFirstNode((PMEMORY_AREA)AddressSpace->BalancedRoot.u1.Parent);
+ FirstNode = Node = MmIterateFirstNode((PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink);
/* Traverse the tree from left to right. */
PreviousNode = Node;
static PVOID
MmFindGapTopDown(
- PMM_AVL_TABLE AddressSpace,
+ PMMSUPPORT AddressSpace,
ULONG_PTR Length,
ULONG_PTR Granularity)
{
return NULL;
/* Special case for empty tree. */
- if (AddressSpace->BalancedRoot.u1.Parent == NULL)
+ if (AddressSpace->WorkingSetExpansionLinks.Flink == NULL)
{
if (AlignedAddress >= LowestAddress)
{
}
/* Go to the node with highest address in the tree. */
- Node = MmIterateLastNode((PMEMORY_AREA)AddressSpace->BalancedRoot.u1.Parent);
+ Node = MmIterateLastNode((PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink);
/* Check if there is enough space after the last memory area. */
if (Node->EndingAddress <= AlignedAddress)
}
-PVOID STDCALL
+PVOID NTAPI
MmFindGap(
- PMM_AVL_TABLE AddressSpace,
+ PMMSUPPORT AddressSpace,
ULONG_PTR Length,
ULONG_PTR Granularity,
BOOLEAN TopDown)
return MmFindGapBottomUp(AddressSpace, Length, Granularity);
}
-ULONG_PTR STDCALL
+ULONG_PTR NTAPI
MmFindGapAtAddress(
- PMM_AVL_TABLE AddressSpace,
+ PMMSUPPORT AddressSpace,
PVOID Address)
{
- PMEMORY_AREA Node = (PMEMORY_AREA)AddressSpace->BalancedRoot.u1.Parent;
+ PMEMORY_AREA Node = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink;
PMEMORY_AREA RightNeighbour = NULL;
PVOID LowestAddress = MmGetAddressSpaceOwner(AddressSpace) ? MM_LOWEST_USER_ADDRESS : MmSystemRangeStart;
PVOID HighestAddress = MmGetAddressSpaceOwner(AddressSpace) ?
}
}
-/**
- * @name MmInitMemoryAreas
- *
- * Initialize the memory area list implementation.
- */
-
-NTSTATUS
-INIT_FUNCTION
-NTAPI
-MmInitMemoryAreas(VOID)
-{
- DPRINT("MmInitMemoryAreas()\n");
- return(STATUS_SUCCESS);
-}
-
/**
* @name MmFreeMemoryArea
* @remarks Lock the address space before calling this function.
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
MmFreeMemoryArea(
- PMM_AVL_TABLE AddressSpace,
+ PMMSUPPORT AddressSpace,
PMEMORY_AREA MemoryArea,
PMM_FREE_PAGE_FUNC FreePage,
PVOID FreePageContext)
PMEMORY_AREA *ParentReplace;
ULONG_PTR Address;
PVOID EndAddress;
- PEPROCESS CurrentProcess = PsGetCurrentProcess();
- PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
-
- if (Process != NULL &&
- Process != CurrentProcess)
- {
- KeAttachProcess(&Process->Pcb);
- }
-
- EndAddress = MM_ROUND_UP(MemoryArea->EndingAddress, PAGE_SIZE);
- for (Address = (ULONG_PTR)MemoryArea->StartingAddress;
- Address < (ULONG_PTR)EndAddress;
- Address += PAGE_SIZE)
- {
- if (MemoryArea->Type == MEMORY_AREA_IO_MAPPING)
- {
- MmRawDeleteVirtualMapping((PVOID)Address);
- }
- else
- {
- BOOLEAN Dirty = FALSE;
- SWAPENTRY SwapEntry = 0;
- PFN_TYPE Page = 0;
-
- if (MmIsPageSwapEntry(Process, (PVOID)Address))
- {
- MmDeletePageFileMapping(Process, (PVOID)Address, &SwapEntry);
- }
- else
- {
- MmDeleteVirtualMapping(Process, (PVOID)Address, FALSE, &Dirty, &Page);
- }
- if (FreePage != NULL)
- {
- FreePage(FreePageContext, MemoryArea, (PVOID)Address,
- Page, SwapEntry, (BOOLEAN)Dirty);
- }
- }
- }
-
- if (Process != NULL &&
- Process != CurrentProcess)
+
+ if (MemoryArea->Type != MEMORY_AREA_OWNED_BY_ARM3)
{
- KeDetachProcess();
- }
+ PEPROCESS CurrentProcess = PsGetCurrentProcess();
+ PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
+
+ if (Process != NULL &&
+ Process != CurrentProcess)
+ {
+ KeAttachProcess(&Process->Pcb);
+ }
+
+ EndAddress = MM_ROUND_UP(MemoryArea->EndingAddress, PAGE_SIZE);
+ for (Address = (ULONG_PTR)MemoryArea->StartingAddress;
+ Address < (ULONG_PTR)EndAddress;
+ Address += PAGE_SIZE)
+ {
+ if (MemoryArea->Type == MEMORY_AREA_IO_MAPPING)
+ {
+ MmRawDeleteVirtualMapping((PVOID)Address);
+ }
+ else
+ {
+ BOOLEAN Dirty = FALSE;
+ SWAPENTRY SwapEntry = 0;
+ PFN_NUMBER Page = 0;
+
+ if (MmIsPageSwapEntry(Process, (PVOID)Address))
+ {
+ MmDeletePageFileMapping(Process, (PVOID)Address, &SwapEntry);
+ }
+ else
+ {
+ MmDeleteVirtualMapping(Process, (PVOID)Address, FALSE, &Dirty, &Page);
+ }
+ if (FreePage != NULL)
+ {
+ FreePage(FreePageContext, MemoryArea, (PVOID)Address,
+ Page, SwapEntry, (BOOLEAN)Dirty);
+ }
+ }
+ }
+
+ if (Process != NULL &&
+ Process != CurrentProcess)
+ {
+ KeDetachProcess();
+ }
+ }
/* Remove the tree item. */
{
ParentReplace = &MemoryArea->Parent->RightChild;
}
else
- ParentReplace = (PMEMORY_AREA*)&AddressSpace->BalancedRoot.u1.Parent;
+ ParentReplace = (PMEMORY_AREA*)&AddressSpace->WorkingSetExpansionLinks.Flink;
if (MemoryArea->RightChild == NULL)
{
* @remarks Lock the address space before calling this function.
*/
-NTSTATUS STDCALL
+NTSTATUS NTAPI
MmFreeMemoryAreaByPtr(
- PMM_AVL_TABLE AddressSpace,
+ PMMSUPPORT AddressSpace,
PVOID BaseAddress,
PMM_FREE_PAGE_FUNC FreePage,
PVOID FreePageContext)
BaseAddress);
if (MemoryArea == NULL)
{
- ASSERT(FALSE);
+ KeBugCheck(MEMORY_MANAGEMENT);
return(STATUS_UNSUCCESSFUL);
}
* @remarks Lock the address space before calling this function.
*/
-NTSTATUS STDCALL
-MmCreateMemoryArea(PMM_AVL_TABLE AddressSpace,
+NTSTATUS NTAPI
+MmCreateMemoryArea(PMMSUPPORT AddressSpace,
ULONG Type,
PVOID *BaseAddress,
ULONG_PTR Length,
return STATUS_CONFLICTING_ADDRESSES;
}
}
+
+ //
+ // Is this a static memory area?
+ //
+ if (Type & MEMORY_AREA_STATIC)
+ {
+ //
+ // Use the static array instead of the pool
+ //
+ ASSERT(MiStaticMemoryAreaCount < MI_STATIC_MEMORY_AREAS);
+ MemoryArea = &MiStaticMemoryAreas[MiStaticMemoryAreaCount++];
+ Type &= ~MEMORY_AREA_STATIC;
+ }
+ else
+ {
+ //
+ // Allocate the memory area from nonpaged pool
+ //
+ MemoryArea = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(MEMORY_AREA),
+ TAG_MAREA);
+ }
+
+ if (!MemoryArea) return STATUS_NO_MEMORY;
- MemoryArea = ExAllocatePoolWithTag(NonPagedPool, sizeof(MEMORY_AREA),
- TAG_MAREA);
RtlZeroMemory(MemoryArea, sizeof(MEMORY_AREA));
MemoryArea->Type = Type;
MemoryArea->StartingAddress = *BaseAddress;
for (i = 0; i < PAGE_ROUND_UP(Length) / PAGE_SIZE; i++)
{
- PFN_TYPE Page;
+ PFN_NUMBER Page;
Status = MmRequestPageMemoryConsumer(Consumer, TRUE, &Page);
if (!NT_SUCCESS(Status))
{
DPRINT1("Unable to allocate page\n");
- ASSERT(FALSE);
+ KeBugCheck(MEMORY_MANAGEMENT);
}
Status = MmCreateVirtualMapping (NULL,
(PVOID)((ULONG_PTR)BaseAddress + (i * PAGE_SIZE)),
if (!NT_SUCCESS(Status))
{
DPRINT1("Unable to create virtual mapping\n");
- ASSERT(FALSE);
+ KeBugCheck(MEMORY_MANAGEMENT);
}
}
}
-VOID STDCALL
+VOID NTAPI
MmReleaseMemoryAreaIfDecommitted(PEPROCESS Process,
- PMM_AVL_TABLE AddressSpace,
+ PMMSUPPORT AddressSpace,
PVOID BaseAddress)
{
PMEMORY_AREA MemoryArea;