- wdm.h: Define ALLOC_PRAGMA and ALLOC_DATA_PRAGMA for MSVC.
[reactos.git] / reactos / ntoskrnl / mm / marea.c
index 4361aed..7ac02d8 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
  * Copyright (C) 1998-2005 ReactOS Team (and the authors from the programmers section)
  *
  * This program is free software; you can redistribute it and/or
  *                  Eric Kohl
  *                  Philip Susi
  *                  Casper Hornstrup
- *                  Hartmut Birr
  *                  Eric Kohl
  *                  Ge van Geldorp
  *                  Royce Mitchell III
- *                  Aleksey Bragin 
+ *                  Aleksey Bragin
  *                  Jason Filby
  *                  Thomas Weidenmueller
  *                  Gunnar Andre' Dalsnes
 
 #include <ntoskrnl.h>
 #define NDEBUG
-#include <internal/debug.h>
+#include <debug.h>
+
+MEMORY_AREA MiStaticMemoryAreas[MI_STATIC_MEMORY_AREAS];
+ULONG MiStaticMemoryAreaCount;
 
 /* #define VALIDATE_MEMORY_AREAS */
 
@@ -105,7 +106,7 @@ static PMEMORY_AREA MmIterateNextNode(PMEMORY_AREA Node)
 }
 
 /**
- * @name MmIterateFirstNode
+ * @name MmIterateLastNode
  *
  * @param Node
  *        Head node of the MEMORY_AREA tree.
@@ -123,7 +124,7 @@ static PMEMORY_AREA MmIterateLastNode(PMEMORY_AREA Node)
 }
 
 /**
- * @name MmIterateNextNode
+ * @name MmIteratePreviousNode
  *
  * @param Node
  *        Current node in the tree.
@@ -158,25 +159,24 @@ static PMEMORY_AREA MmIteratePrevNode(PMEMORY_AREA Node)
 }
 
 #ifdef VALIDATE_MEMORY_AREAS
-static VOID MmVerifyMemoryAreas(PMADDRESS_SPACE AddressSpace)
+static VOID MmVerifyMemoryAreas(PMMSUPPORT AddressSpace)
 {
    PMEMORY_AREA Node;
 
    ASSERT(AddressSpace != NULL);
 
    /* Special case for empty tree. */
-   if (AddressSpace->MemoryAreaRoot == NULL)
+   if (AddressSpace->WorkingSetExpansionLinks.Flink == NULL)
       return;
 
    /* Traverse the tree from left to right. */
-   for (Node = MmIterateFirstNode(AddressSpace->MemoryAreaRoot);
+   for (Node = MmIterateFirstNode(AddressSpace->WorkingSetExpansionLinks.Flink);
         Node != NULL;
         Node = MmIterateNextNode(Node))
    {
       /* FiN: The starting address can be NULL if someone explicitely asks
        * for NULL address. */
-      ASSERT(Node->StartingAddress >= AddressSpace->LowestAddress ||
-             Node->StartingAddress == NULL);
+      ASSERT(Node->StartingAddress == NULL);
       ASSERT(Node->EndingAddress >= Node->StartingAddress);
    }
 }
@@ -184,36 +184,36 @@ static VOID MmVerifyMemoryAreas(PMADDRESS_SPACE AddressSpace)
 #define MmVerifyMemoryAreas(x)
 #endif
 
-VOID STDCALL
-MmDumpMemoryAreas(PMADDRESS_SPACE AddressSpace)
+VOID NTAPI
+MmDumpMemoryAreas(PMMSUPPORT AddressSpace)
 {
    PMEMORY_AREA Node;
 
    DbgPrint("MmDumpMemoryAreas()\n");
 
    /* Special case for empty tree. */
-   if (AddressSpace->MemoryAreaRoot == NULL)
+   if (AddressSpace->WorkingSetExpansionLinks.Flink == NULL)
       return;
 
    /* Traverse the tree from left to right. */
-   for (Node = MmIterateFirstNode(AddressSpace->MemoryAreaRoot);
+   for (Node = MmIterateFirstNode((PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink);
         Node != NULL;
         Node = MmIterateNextNode(Node))
    {
-      DbgPrint("Start %p End %p Attributes %x\n",
+      DbgPrint("Start %p End %p Protect %x Flags %x\n",
                Node->StartingAddress, Node->EndingAddress,
-               Node->Attributes);
+               Node->Protect, Node->Flags);
    }
 
    DbgPrint("Finished MmDumpMemoryAreas()\n");
 }
 
-PMEMORY_AREA STDCALL
+PMEMORY_AREA NTAPI
 MmLocateMemoryAreaByAddress(
-   PMADDRESS_SPACE AddressSpace,
+   PMMSUPPORT AddressSpace,
    PVOID Address)
 {
-   PMEMORY_AREA Node = AddressSpace->MemoryAreaRoot;
+   PMEMORY_AREA Node = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink;
 
    DPRINT("MmLocateMemoryAreaByAddress(AddressSpace %p, Address %p)\n",
            AddressSpace, Address);
@@ -238,9 +238,9 @@ MmLocateMemoryAreaByAddress(
    return NULL;
 }
 
-PMEMORY_AREA STDCALL
+PMEMORY_AREA NTAPI
 MmLocateMemoryAreaByRegion(
-   PMADDRESS_SPACE AddressSpace,
+   PMMSUPPORT AddressSpace,
    PVOID Address,
    ULONG_PTR Length)
 {
@@ -250,11 +250,11 @@ MmLocateMemoryAreaByRegion(
    MmVerifyMemoryAreas(AddressSpace);
 
    /* Special case for empty tree. */
-   if (AddressSpace->MemoryAreaRoot == NULL)
+   if (AddressSpace->WorkingSetExpansionLinks.Flink == NULL)
       return NULL;
 
    /* Traverse the tree from left to right. */
-   for (Node = MmIterateFirstNode(AddressSpace->MemoryAreaRoot);
+   for (Node = MmIterateFirstNode((PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink);
         Node != NULL;
         Node = MmIterateNextNode(Node))
    {
@@ -301,11 +301,11 @@ MmLocateMemoryAreaByRegion(
 
 static VOID
 MmCompressHelper(
-   PMADDRESS_SPACE AddressSpace,
+   PMMSUPPORT AddressSpace,
    ULONG Count)
 {
    PMEMORY_AREA Root = NULL;
-   PMEMORY_AREA Red = AddressSpace->MemoryAreaRoot;
+   PMEMORY_AREA Red = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink;
    PMEMORY_AREA Black = Red->LeftChild;
 
    while (Count--)
@@ -313,7 +313,7 @@ MmCompressHelper(
       if (Root)
          Root->LeftChild = Black;
       else
-         AddressSpace->MemoryAreaRoot = Black;
+         AddressSpace->WorkingSetExpansionLinks.Flink = (PVOID)Black;
       Black->Parent = Root;
       Red->LeftChild = Black->RightChild;
       if (Black->RightChild)
@@ -340,7 +340,7 @@ MmCompressHelper(
 
 static VOID
 MmRebalanceTree(
-   PMADDRESS_SPACE AddressSpace)
+   PMMSUPPORT AddressSpace)
 {
    PMEMORY_AREA PreviousNode;
    PMEMORY_AREA CurrentNode;
@@ -353,7 +353,7 @@ MmRebalanceTree(
    /* Transform the tree into Vine. */
 
    PreviousNode = NULL;
-   CurrentNode = AddressSpace->MemoryAreaRoot;
+   CurrentNode = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink;
    while (CurrentNode != NULL)
    {
       if (CurrentNode->RightChild == NULL)
@@ -378,7 +378,7 @@ MmRebalanceTree(
          if (PreviousNode != NULL)
             PreviousNode->LeftChild = TempNode;
          else
-            AddressSpace->MemoryAreaRoot = TempNode;
+            AddressSpace->WorkingSetExpansionLinks.Flink = (PVOID)TempNode;
          TempNode->Parent = PreviousNode;
       }
    }
@@ -409,7 +409,7 @@ MmRebalanceTree(
 
 static VOID
 MmInsertMemoryArea(
-   PMADDRESS_SPACE AddressSpace,
+   PMMSUPPORT AddressSpace,
    PMEMORY_AREA marea)
 {
    PMEMORY_AREA Node;
@@ -418,14 +418,14 @@ MmInsertMemoryArea(
 
    MmVerifyMemoryAreas(AddressSpace);
 
-   if (AddressSpace->MemoryAreaRoot == NULL)
+   if (AddressSpace->WorkingSetExpansionLinks.Flink == NULL)
    {
-      AddressSpace->MemoryAreaRoot = marea;
+      AddressSpace->WorkingSetExpansionLinks.Flink = (PVOID)marea;
       marea->LeftChild = marea->RightChild = marea->Parent = NULL;
       return;
    }
 
-   Node = AddressSpace->MemoryAreaRoot;
+   Node = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink;
    do
    {
       DPRINT("marea->EndingAddress: %p Node->StartingAddress: %p\n",
@@ -465,11 +465,12 @@ MmInsertMemoryArea(
 
 static PVOID
 MmFindGapBottomUp(
-   PMADDRESS_SPACE AddressSpace,
+   PMMSUPPORT AddressSpace,
    ULONG_PTR Length,
    ULONG_PTR Granularity)
 {
-   PVOID HighestAddress = AddressSpace->LowestAddress < MmSystemRangeStart ?
+   PVOID LowestAddress  = MmGetAddressSpaceOwner(AddressSpace) ? MM_LOWEST_USER_ADDRESS : MmSystemRangeStart;
+   PVOID HighestAddress = MmGetAddressSpaceOwner(AddressSpace) ?
                           (PVOID)((ULONG_PTR)MmSystemRangeStart - 1) : (PVOID)MAXULONG_PTR;
    PVOID AlignedAddress;
    PMEMORY_AREA Node;
@@ -479,12 +480,12 @@ MmFindGapBottomUp(
    MmVerifyMemoryAreas(AddressSpace);
 
    DPRINT("LowestAddress: %p HighestAddress: %p\n",
-          AddressSpace->LowestAddress, HighestAddress);
+          LowestAddress, HighestAddress);
 
-   AlignedAddress = MM_ROUND_UP(AddressSpace->LowestAddress, Granularity);
+   AlignedAddress = MM_ROUND_UP(LowestAddress, Granularity);
 
    /* Special case for empty tree. */
-   if (AddressSpace->MemoryAreaRoot == NULL)
+   if (AddressSpace->WorkingSetExpansionLinks.Flink == NULL)
    {
       if ((ULONG_PTR)HighestAddress - (ULONG_PTR)AlignedAddress >= Length)
       {
@@ -496,7 +497,7 @@ MmFindGapBottomUp(
    }
 
    /* Go to the node with lowest address in the tree. */
-   FirstNode = Node = MmIterateFirstNode(AddressSpace->MemoryAreaRoot);
+   FirstNode = Node = MmIterateFirstNode((PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink);
 
    /* Traverse the tree from left to right. */
    PreviousNode = Node;
@@ -527,7 +528,7 @@ MmFindGapBottomUp(
    }
 
    /* Check if there is enough space before the first memory area. */
-   AlignedAddress = MM_ROUND_UP(AddressSpace->LowestAddress, Granularity);
+   AlignedAddress = MM_ROUND_UP(LowestAddress, Granularity);
    if (FirstNode->StartingAddress > AlignedAddress &&
        (ULONG_PTR)FirstNode->StartingAddress - (ULONG_PTR)AlignedAddress >= Length)
    {
@@ -542,11 +543,12 @@ MmFindGapBottomUp(
 
 static PVOID
 MmFindGapTopDown(
-   PMADDRESS_SPACE AddressSpace,
+   PMMSUPPORT AddressSpace,
    ULONG_PTR Length,
    ULONG_PTR Granularity)
 {
-   PVOID HighestAddress = AddressSpace->LowestAddress < MmSystemRangeStart ?
+   PVOID LowestAddress  = MmGetAddressSpaceOwner(AddressSpace) ? MM_LOWEST_USER_ADDRESS : MmSystemRangeStart;
+   PVOID HighestAddress = MmGetAddressSpaceOwner(AddressSpace) ?
                           (PVOID)((ULONG_PTR)MmSystemRangeStart - 1) : (PVOID)MAXULONG_PTR;
    PVOID AlignedAddress;
    PMEMORY_AREA Node;
@@ -555,7 +557,7 @@ MmFindGapTopDown(
    MmVerifyMemoryAreas(AddressSpace);
 
    DPRINT("LowestAddress: %p HighestAddress: %p\n",
-          AddressSpace->LowestAddress, HighestAddress);
+          LowestAddress, HighestAddress);
 
    AlignedAddress = MM_ROUND_DOWN((ULONG_PTR)HighestAddress - Length + 1, Granularity);
 
@@ -564,9 +566,9 @@ MmFindGapTopDown(
       return NULL;
 
    /* Special case for empty tree. */
-   if (AddressSpace->MemoryAreaRoot == NULL)
+   if (AddressSpace->WorkingSetExpansionLinks.Flink == NULL)
    {
-      if (AlignedAddress >= (PVOID)AddressSpace->LowestAddress)
+      if (AlignedAddress >= LowestAddress)
       {
          DPRINT("MmFindGapTopDown: %p\n", AlignedAddress);
          return AlignedAddress;
@@ -576,7 +578,7 @@ MmFindGapTopDown(
    }
 
    /* Go to the node with highest address in the tree. */
-   Node = MmIterateLastNode(AddressSpace->MemoryAreaRoot);
+   Node = MmIterateLastNode((PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink);
 
    /* Check if there is enough space after the last memory area. */
    if (Node->EndingAddress <= AlignedAddress)
@@ -614,7 +616,7 @@ MmFindGapTopDown(
    if (AlignedAddress > PreviousNode->StartingAddress)
       return NULL;
 
-   if (AlignedAddress >= (PVOID)AddressSpace->LowestAddress)
+   if (AlignedAddress >= LowestAddress)
    {
       DPRINT("MmFindGapTopDown: %p\n", AlignedAddress);
       return AlignedAddress;
@@ -625,9 +627,9 @@ MmFindGapTopDown(
 }
 
 
-PVOID STDCALL
+PVOID NTAPI
 MmFindGap(
-   PMADDRESS_SPACE AddressSpace,
+   PMMSUPPORT AddressSpace,
    ULONG_PTR Length,
    ULONG_PTR Granularity,
    BOOLEAN TopDown)
@@ -638,21 +640,22 @@ MmFindGap(
    return MmFindGapBottomUp(AddressSpace, Length, Granularity);
 }
 
-ULONG_PTR STDCALL
+ULONG_PTR NTAPI
 MmFindGapAtAddress(
-   PMADDRESS_SPACE AddressSpace,
+   PMMSUPPORT AddressSpace,
    PVOID Address)
 {
-   PMEMORY_AREA Node = AddressSpace->MemoryAreaRoot;
+   PMEMORY_AREA Node = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink;
    PMEMORY_AREA RightNeighbour = NULL;
-   PVOID HighestAddress = AddressSpace->LowestAddress < MmSystemRangeStart ?
+   PVOID LowestAddress  = MmGetAddressSpaceOwner(AddressSpace) ? MM_LOWEST_USER_ADDRESS : MmSystemRangeStart;
+   PVOID HighestAddress = MmGetAddressSpaceOwner(AddressSpace) ?
                           (PVOID)((ULONG_PTR)MmSystemRangeStart - 1) : (PVOID)MAXULONG_PTR;
 
    MmVerifyMemoryAreas(AddressSpace);
 
    Address = MM_ROUND_DOWN(Address, PAGE_SIZE);
 
-   if (AddressSpace->LowestAddress < MmSystemRangeStart)
+   if (LowestAddress < MmSystemRangeStart)
    {
       if (Address >= MmSystemRangeStart)
       {
@@ -661,7 +664,7 @@ MmFindGapAtAddress(
    }
    else
    {
-      if (Address < AddressSpace->LowestAddress)
+      if (Address < LowestAddress)
       {
          return 0;
       }
@@ -699,21 +702,6 @@ MmFindGapAtAddress(
    }
 }
 
-/**
- * @name MmInitMemoryAreas
- *
- * Initialize the memory area list implementation.
- */
-
-NTSTATUS
-INIT_FUNCTION
-NTAPI
-MmInitMemoryAreas(VOID)
-{
-   DPRINT("MmInitMemoryAreas()\n",0);
-   return(STATUS_SUCCESS);
-}
-
 
 /**
  * @name MmFreeMemoryArea
@@ -734,9 +722,9 @@ MmInitMemoryAreas(VOID)
  * @remarks Lock the address space before calling this function.
  */
 
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 MmFreeMemoryArea(
-   PMADDRESS_SPACE AddressSpace,
+   PMMSUPPORT AddressSpace,
    PMEMORY_AREA MemoryArea,
    PMM_FREE_PAGE_FUNC FreePage,
    PVOID FreePageContext)
@@ -745,11 +733,12 @@ MmFreeMemoryArea(
    ULONG_PTR Address;
    PVOID EndAddress;
    PEPROCESS CurrentProcess = PsGetCurrentProcess();
-
-   if (AddressSpace->Process != NULL &&
-       AddressSpace->Process != CurrentProcess)
+   PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
+    
+   if (Process != NULL &&
+       Process != CurrentProcess)
    {
-      KeAttachProcess(&AddressSpace->Process->Pcb);
+      KeAttachProcess(&Process->Pcb);
    }
 
    EndAddress = MM_ROUND_UP(MemoryArea->EndingAddress, PAGE_SIZE);
@@ -763,17 +752,17 @@ MmFreeMemoryArea(
       }
       else
       {
-         BOOL Dirty = FALSE;
+         BOOLEAN Dirty = FALSE;
          SWAPENTRY SwapEntry = 0;
          PFN_TYPE Page = 0;
 
-         if (MmIsPageSwapEntry(AddressSpace->Process, (PVOID)Address))
+         if (MmIsPageSwapEntry(Process, (PVOID)Address))
          {
-            MmDeletePageFileMapping(AddressSpace->Process, (PVOID)Address, &SwapEntry);
+            MmDeletePageFileMapping(Process, (PVOID)Address, &SwapEntry);
          }
          else
          {
-            MmDeleteVirtualMapping(AddressSpace->Process, (PVOID)Address, FALSE, &Dirty, &Page);
+            MmDeleteVirtualMapping(Process, (PVOID)Address, FALSE, &Dirty, &Page);
          }
          if (FreePage != NULL)
          {
@@ -783,8 +772,8 @@ MmFreeMemoryArea(
       }
    }
 
-   if (AddressSpace->Process != NULL &&
-       AddressSpace->Process != CurrentProcess)
+   if (Process != NULL &&
+       Process != CurrentProcess)
    {
       KeDetachProcess();
    }
@@ -799,7 +788,7 @@ MmFreeMemoryArea(
             ParentReplace = &MemoryArea->Parent->RightChild;
       }
       else
-         ParentReplace = &AddressSpace->MemoryAreaRoot;
+         ParentReplace = (PMEMORY_AREA*)&AddressSpace->WorkingSetExpansionLinks.Flink;
 
       if (MemoryArea->RightChild == NULL)
       {
@@ -875,9 +864,9 @@ MmFreeMemoryArea(
  * @remarks Lock the address space before calling this function.
  */
 
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 MmFreeMemoryAreaByPtr(
-   PMADDRESS_SPACE AddressSpace,
+   PMMSUPPORT AddressSpace,
    PVOID BaseAddress,
    PMM_FREE_PAGE_FUNC FreePage,
    PVOID FreePageContext)
@@ -894,7 +883,7 @@ MmFreeMemoryAreaByPtr(
                                             BaseAddress);
    if (MemoryArea == NULL)
    {
-      KEBUGCHECK(0);
+      KeBugCheck(MEMORY_MANAGEMENT);
       return(STATUS_UNSUCCESSFUL);
    }
 
@@ -927,16 +916,15 @@ MmFreeMemoryAreaByPtr(
  * @remarks Lock the address space before calling this function.
  */
 
-NTSTATUS STDCALL
-MmCreateMemoryArea(PEPROCESS Process,
-                   PMADDRESS_SPACE AddressSpace,
+NTSTATUS NTAPI
+MmCreateMemoryArea(PMMSUPPORT AddressSpace,
                    ULONG Type,
                    PVOID *BaseAddress,
                    ULONG_PTR Length,
-                   ULONG Attributes,
+                   ULONG Protect,
                    PMEMORY_AREA *Result,
                    BOOLEAN FixedAddress,
-                   BOOLEAN TopDown,
+                   ULONG AllocationFlags,
                    PHYSICAL_ADDRESS BoundaryAddressMultiple)
 {
    PVOID EndAddress;
@@ -945,9 +933,9 @@ MmCreateMemoryArea(PEPROCESS Process,
    PMEMORY_AREA MemoryArea;
 
    DPRINT("MmCreateMemoryArea(Type %d, BaseAddress %p, "
-          "*BaseAddress %p, Length %p, Attributes %x, TopDown: %x, "
+          "*BaseAddress %p, Length %p, AllocationFlags %x, "
           "FixedAddress %x, Result %p)\n",
-          Type, BaseAddress, *BaseAddress, Length, Attributes, TopDown,
+          Type, BaseAddress, *BaseAddress, Length, AllocationFlags,
           FixedAddress, Result);
 
    MmVerifyMemoryAreas(AddressSpace);
@@ -959,7 +947,7 @@ MmCreateMemoryArea(PEPROCESS Process,
       *BaseAddress = MmFindGap(AddressSpace,
                                tmpLength,
                                Granularity,
-                               TopDown != 0);
+                               (AllocationFlags & MEM_TOP_DOWN) == MEM_TOP_DOWN);
       if ((*BaseAddress) == 0)
       {
          DPRINT("No suitable gap\n");
@@ -972,17 +960,14 @@ MmCreateMemoryArea(PEPROCESS Process,
                          - (ULONG_PTR) MM_ROUND_DOWN(*BaseAddress, Granularity));
       *BaseAddress = MM_ROUND_DOWN(*BaseAddress, Granularity);
 
-      if (AddressSpace->LowestAddress == MmSystemRangeStart &&
-          *BaseAddress < MmSystemRangeStart)
+      if (!MmGetAddressSpaceOwner(AddressSpace) && *BaseAddress < MmSystemRangeStart)
       {
-         CHECKPOINT;
          return STATUS_ACCESS_VIOLATION;
       }
 
-      if (AddressSpace->LowestAddress < MmSystemRangeStart &&
+      if (MmGetAddressSpaceOwner(AddressSpace) &&
           (ULONG_PTR)(*BaseAddress) + tmpLength > (ULONG_PTR)MmSystemRangeStart)
       {
-         CHECKPOINT;
          return STATUS_ACCESS_VIOLATION;
       }
 
@@ -1000,15 +985,35 @@ MmCreateMemoryArea(PEPROCESS Process,
          return STATUS_CONFLICTING_ADDRESSES;
       }
    }
-
-   MemoryArea = ExAllocatePoolWithTag(NonPagedPool, sizeof(MEMORY_AREA),
-                                      TAG_MAREA);
+    
+    //
+    // 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++];
+    }
+    else
+    {
+        //
+        // Allocate the memory area from nonpaged pool
+        //
+        MemoryArea = ExAllocatePoolWithTag(NonPagedPool,
+                                           sizeof(MEMORY_AREA),
+                                           TAG_MAREA);
+    }
+    
    RtlZeroMemory(MemoryArea, sizeof(MEMORY_AREA));
    MemoryArea->Type = Type;
    MemoryArea->StartingAddress = *BaseAddress;
    MemoryArea->EndingAddress = (PVOID)((ULONG_PTR)*BaseAddress + tmpLength);
-   MemoryArea->Attributes = Attributes;
-   MemoryArea->LockCount = 0;
+   MemoryArea->Protect = Protect;
+   MemoryArea->Flags = AllocationFlags;
+   //MemoryArea->LockCount = 0;
    MemoryArea->PageOpCount = 0;
    MemoryArea->DeleteInProgress = FALSE;
 
@@ -1020,10 +1025,42 @@ MmCreateMemoryArea(PEPROCESS Process,
    return STATUS_SUCCESS;
 }
 
+VOID NTAPI
+MmMapMemoryArea(PVOID BaseAddress,
+                ULONG Length,
+                ULONG Consumer,
+                ULONG Protection)
+{
+   ULONG i;
+   NTSTATUS Status;
+
+   for (i = 0; i < PAGE_ROUND_UP(Length) / PAGE_SIZE; i++)
+   {
+      PFN_TYPE Page;
+
+      Status = MmRequestPageMemoryConsumer(Consumer, TRUE, &Page);
+      if (!NT_SUCCESS(Status))
+      {
+         DPRINT1("Unable to allocate page\n");
+         KeBugCheck(MEMORY_MANAGEMENT);
+      }
+      Status = MmCreateVirtualMapping (NULL,
+                                       (PVOID)((ULONG_PTR)BaseAddress + (i * PAGE_SIZE)),
+                                       Protection,
+                                       &Page,
+                                       1);
+      if (!NT_SUCCESS(Status))
+      {
+         DPRINT1("Unable to create virtual mapping\n");
+         KeBugCheck(MEMORY_MANAGEMENT);
+      }
+   }
+}
+
 
-VOID STDCALL
+VOID NTAPI
 MmReleaseMemoryAreaIfDecommitted(PEPROCESS Process,
-                                 PMADDRESS_SPACE AddressSpace,
+                                 PMMSUPPORT AddressSpace,
                                  PVOID BaseAddress)
 {
    PMEMORY_AREA MemoryArea;