- Removed the hole pool allocation, because it needs to much memory and ros will not boot.  
- Allocate short blocks in one page.  
- Split the used and free header. It makes it easier to implement a red zone check.
Modified: trunk/reactos/ntoskrnl/mm/npool.c

Modified: trunk/reactos/ntoskrnl/mm/npool.c
--- trunk/reactos/ntoskrnl/mm/npool.c	2005-08-11 20:23:13 UTC (rev 17305)
+++ trunk/reactos/ntoskrnl/mm/npool.c	2005-08-11 20:29:08 UTC (rev 17306)
@@ -8,6 +8,7 @@
  * PROGRAMMERS:     David Welch (welch@cwcom.net)
  *                  Iwan Fatahi (i_fatahi@hotmail.com)
  *                  Robert Bergkvist (fragdance@hotmail.com)
+ *                  Hartmut Birr
  */
 
 /* INCLUDES ****************************************************************/
@@ -54,38 +55,33 @@
 /*
  * fields present at the start of a block (this is for internal use only)
  */
-typedef struct _BLOCK_HDR
+typedef struct _HDR
 {
-   ULONG Magic;
-   ULONG Size;
-   struct _BLOCK_HDR* previous;
-   union
-   {
-      struct
-      {
-         LIST_ENTRY ListEntry;
-         ULONG Tag;
-         PVOID Caller;
-         LIST_ENTRY TagListEntry;
-         BOOLEAN Dumped;
-      }
-      Used;
-      struct
-      {
-         NODE Node;
-      }
-      Free;
-   };
-}
-BLOCK_HDR;
+    ULONG Magic;
+    ULONG Size;
+    struct _HDR* previous;
+} HDR, *PHDR;
 
-#define BLOCK_HDR_SIZE ROUND_UP(sizeof(BLOCK_HDR), MM_POOL_ALIGNMENT)
+typedef struct _HDR_USED
+{
+    HDR hdr;
+    LIST_ENTRY ListEntry;
+    ULONG Tag;
+    PVOID Caller;
+    LIST_ENTRY TagListEntry;
+    BOOLEAN Dumped;
+} HDR_USED, *PHDR_USED;
 
-PVOID STDCALL
-ExAllocateWholePageBlock(ULONG Size);
-VOID STDCALL
-ExFreeWholePageBlock(PVOID Addr);
+typedef struct _HDR_FREE
+{
+    HDR hdr;
+    NODE Node;
+} HDR_FREE, *PHDR_FREE;
 
+#define HDR_FREE_SIZE ROUND_UP(sizeof(HDR_FREE), MM_POOL_ALIGNMENT)
+#define HDR_USED_SIZE ROUND_UP(sizeof(HDR_USED), MM_POOL_ALIGNMENT)
+
+
 /* GLOBALS *****************************************************************/
 
 extern PVOID MiNonPagedPoolStart;
@@ -103,7 +99,6 @@
 
 static LIST_ENTRY AddressListHead;
 
-#ifndef WHOLE_PAGE_ALLOCATIONS
 /*
  * Count of free blocks
  */
@@ -113,7 +108,6 @@
  * Count of used blocks
  */
 static ULONG EiNrUsedBlocks = 0;
-#endif
 
 /*
  * Lock that protects the non-paged pool data structures
@@ -147,29 +141,23 @@
 static LIST_ENTRY tag_hash_table[TAG_HASH_TABLE_SIZE];
 #endif /* TAG_STATISTICS_TRACKING */
 
-#ifdef WHOLE_PAGE_ALLOCATIONS
-static RTL_BITMAP NonPagedPoolAllocMap;
-static ULONG NonPagedPoolAllocMapHint;
-static ULONG MiCurrentNonPagedPoolLength = 0;
-#else
 static PULONG MiNonPagedPoolAllocMap;
 static ULONG MiNonPagedPoolNrOfPages;
-#endif /* WHOLE_PAGE_ALLOCATIONS */
 
 /* avl helper functions ****************************************************/
 
 void DumpFreeBlockNode(PNODE p)
 {
    static int count = 0;
-   BLOCK_HDR* blk;
+   HDR_FREE* blk;
 
    count++;
 
    if (p)
    {
       DumpFreeBlockNode(p->link[0]);
-      blk = CONTAINING_RECORD(p, BLOCK_HDR, Free.Node);
-      DbgPrint("%08x %8d (%d)\n", blk, blk->Size, count);
+      blk = CONTAINING_RECORD(p, HDR_FREE, Node);
+      DbgPrint("%08x %8d (%d)\n", blk, blk->hdr.Size, count);
       DumpFreeBlockNode(p->link[1]);
    }
 
@@ -178,17 +166,17 @@
 void DumpFreeBlockTree(void)
 {
    DbgPrint("--- Begin tree ------------------\n");
-   DbgPrint("%08x\n", CONTAINING_RECORD(FreeBlockListRoot, BLOCK_HDR, Free.Node));
+   DbgPrint("%08x\n", CONTAINING_RECORD(FreeBlockListRoot, HDR_FREE, Node));
    DumpFreeBlockNode(FreeBlockListRoot);
    DbgPrint("--- End tree --------------------\n");
 }
 
 int compare_node(PNODE p1, PNODE p2)
 {
-   BLOCK_HDR* blk1 = CONTAINING_RECORD(p1, BLOCK_HDR, Free.Node);
-   BLOCK_HDR* blk2 = CONTAINING_RECORD(p2, BLOCK_HDR, Free.Node);
+   HDR_FREE* blk1 = CONTAINING_RECORD(p1, HDR_FREE, Node);
+   HDR_FREE* blk2 = CONTAINING_RECORD(p2, HDR_FREE, Node);
 
-   if (blk1->Size == blk2->Size)
+   if (blk1->hdr.Size == blk2->hdr.Size)
    {
       if (blk1 < blk2)
       {
@@ -201,11 +189,11 @@
    }
    else
    {
-      if (blk1->Size < blk2->Size)
+      if (blk1->hdr.Size < blk2->hdr.Size)
       {
          return -1;
       }
-      if (blk1->Size > blk2->Size)
+      if (blk1->hdr.Size > blk2->hdr.Size)
       {
          return 1;
       }
@@ -216,14 +204,14 @@
 
 int compare_value(PVOID value, PNODE p)
 {
-   BLOCK_HDR* blk = CONTAINING_RECORD(p, BLOCK_HDR, Free.Node);
+   HDR_FREE* blk = CONTAINING_RECORD(p, HDR_FREE, Node);
    ULONG v = *(PULONG)value;
 
-   if (v < blk->Size)
+   if (v < blk->hdr.Size)
    {
       return -1;
    }
-   if (v > blk->Size)
+   if (v > blk->hdr.Size)
    {
       return 1;
    }
@@ -730,39 +718,38 @@
 
 #ifdef TAG_STATISTICS_TRACKING
 VOID
-MiRemoveFromTagHashTable(BLOCK_HDR* block)
+MiRemoveFromTagHashTable(HDR_USED* block)
 /*
  * Remove a block from the tag hash table
  */
 {
-   if (block->Used.Tag == 0)
+   if (block->Tag == 0)
    {
       return;
    }
-
-   RemoveEntryList(&block->Used.TagListEntry);
+   RemoveEntryList(&block->TagListEntry);
 }
 
 VOID
-MiAddToTagHashTable(BLOCK_HDR* block)
+MiAddToTagHashTable(HDR_USED* block)
 /*
  * Add a block to the tag hash table
  */
 {
    ULONG hash;
 
-   if (block->Used.Tag == 0)
+   if (block->Tag == 0)
    {
       return;
    }
 
-   hash = block->Used.Tag % TAG_HASH_TABLE_SIZE;
+   hash = block->Tag % TAG_HASH_TABLE_SIZE;
 
-   InsertHeadList(&tag_hash_table[hash], &block->Used.TagListEntry);
+   InsertHeadList(&tag_hash_table[hash], &block->TagListEntry);
 }
 #endif /* TAG_STATISTICS_TRACKING */
 
-#if defined(TAG_STATISTICS_TRACKING) && !defined(WHOLE_PAGE_ALLOCATIONS)
+#if defined(TAG_STATISTICS_TRACKING)
 VOID STATIC
 MiDumpTagStats(ULONG CurrentTag, ULONG CurrentNrBlocks, ULONG CurrentSize)
 {
@@ -786,14 +773,14 @@
                CurrentSize / CurrentNrBlocks);
    }
 }
-#endif /* defined(TAG_STATISTICS_TRACKING) && !defined(WHOLE_PAGE_ALLOCATIONS); */
+#endif /* defined(TAG_STATISTICS_TRACKING) */
 
 VOID
 MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly)
 {
-#if defined(TAG_STATISTICS_TRACKING) && !defined(WHOLE_PAGE_ALLOCATIONS)
+#if defined(TAG_STATISTICS_TRACKING)
    ULONG i;
-   BLOCK_HDR* current;
+   HDR_USED* current;
    ULONG CurrentTag;
    ULONG CurrentNrBlocks = 0;
    ULONG CurrentSize = 0;
@@ -817,25 +804,25 @@
          current_entry = tag_hash_table[i].Flink;
          while (current_entry != &tag_hash_table[i])
          {
-            current = CONTAINING_RECORD(current_entry, BLOCK_HDR, Used.TagListEntry);
+            current = CONTAINING_RECORD(current_entry, HDR_USED, TagListEntry);
             current_entry = current_entry->Flink;
             if (CurrentTag == 0)
             {
-               CurrentTag = current->Used.Tag;
+               CurrentTag = current->Tag;
                CurrentNrBlocks = 0;
                CurrentSize = 0;
             }
-            if (current->Used.Tag == CurrentTag)
+            if (current->Tag == CurrentTag)
             {
-               RemoveEntryList(&current->Used.TagListEntry);
-               InsertHeadList(&tmpListHead, &current->Used.TagListEntry);
-               if (!NewOnly || !current->Used.Dumped)
+               RemoveEntryList(&current->TagListEntry);
+               InsertHeadList(&tmpListHead, &current->TagListEntry);
+               if (!NewOnly || !current->Dumped)
                {
                   CurrentNrBlocks++;
                   TotalBlocks++;
-                  CurrentSize += current->Size;
-                  TotalSize += current->Size;
-                  current->Used.Dumped = TRUE;
+                  CurrentSize += current->hdr.Size;
+                  TotalSize += current->hdr.Size;
+                  current->Dumped = TRUE;
                }
             }
          }
@@ -866,14 +853,14 @@
    DbgPrint("Freeblocks %d TotalFreeSize %d AverageFreeSize %d\n",
             EiNrFreeBlocks, Size, EiNrFreeBlocks ? Size / EiNrFreeBlocks : 0);
    DbgPrint("***************** Dump Complete ***************\n");
-#endif /* defined(TAG_STATISTICS_TRACKING) && !defined(WHOLE_PAGE_ALLOCATIONS) */
+#endif /* defined(TAG_STATISTICS_TRACKING) */
 }
 
 VOID
 MiDebugDumpNonPagedPool(BOOLEAN NewOnly)
 {
-#if defined(POOL_DEBUG_APIS) && !defined(WHOLE_PAGE_ALLOCATIONS)
-   BLOCK_HDR* current;
+#if defined(POOL_DEBUG_APIS)
+   HDR_USED* current;
    PLIST_ENTRY current_entry;
    KIRQL oldIrql;
 
@@ -883,45 +870,43 @@
    current_entry = UsedBlockListHead.Flink;
    while (current_entry != &UsedBlockListHead)
    {
-      current = CONTAINING_RECORD(current_entry, BLOCK_HDR, Used.ListEntry);
-      if (!NewOnly || !current->Used.Dumped)
+      current = CONTAINING_RECORD(current_entry, HDR_USED, ListEntry);
+      if (!NewOnly || !current->Dumped)
       {
          CHAR c1, c2, c3, c4;
 
-         c1 = (CHAR)((current->Used.Tag >> 24) & 0xFF);
-         c2 = (CHAR)((current->Used.Tag >> 16) & 0xFF);
-         c3 = (CHAR)((current->Used.Tag >> 8) & 0xFF);
-         c4 = (CHAR)(current->Used.Tag & 0xFF);
+         c1 = (CHAR)((current->Tag >> 24) & 0xFF);
+         c2 = (CHAR)((current->Tag >> 16) & 0xFF);
+         c3 = (CHAR)((current->Tag >> 8) & 0xFF);
+         c4 = (CHAR)(current->Tag & 0xFF);
 
          if (isprint(c1) && isprint(c2) && isprint(c3) && isprint(c4))
          {
             DbgPrint("Size 0x%x Tag 0x%x (%c%c%c%c) Allocator 0x%x\n",
-                     current->Size, current->Used.Tag, c4, c3, c2, c1,
-                     current->Used.Caller);
+                     current->hdr.Size, current->Tag, c4, c3, c2, c1,
+                     current->Caller);
          }
          else
          {
             DbgPrint("Size 0x%x Tag 0x%x Allocator 0x%x\n",
-                     current->Size, current->Used.Tag, current->Used.Caller);
+                     current->hdr.Size, current->Tag, current->Caller);
          }
-         current->Used.Dumped = TRUE;
+         current->Dumped = TRUE;
       }
       current_entry = current_entry->Flink;
    }
    DbgPrint("***************** Dump Complete ***************\n");
    KeReleaseSpinLock(&MmNpoolLock, oldIrql);
-#endif /* not WHOLE_PAGE_ALLOCATIONS */
+#endif 
 }
 
-#ifndef WHOLE_PAGE_ALLOCATIONS
-
 #ifdef ENABLE_VALIDATE_POOL
 static void validate_free_list(void)
 /*
  * FUNCTION: Validate the integrity of the list of free blocks
  */
 {
-   BLOCK_HDR* current;
+   HDR_FREE* current;
    unsigned int blocks_seen=0;
    PNODE p;
 
@@ -931,10 +916,10 @@
    {
       PVOID base_addr;
 
-      current = CONTAINING_RECORD(p, BLOCK_HDR, Free.Node);
+      current = CONTAINING_RECORD(p, HDR_FREE, Node);
       base_addr = (PVOID)current;
 
-      if (current->Magic != BLOCK_HDR_FREE_MAGIC)
+      if (current->hdr.Magic != BLOCK_HDR_FREE_MAGIC)
       {
          DbgPrint("Bad block magic (probable pool corruption) at %x\n",
                   current);
@@ -942,12 +927,12 @@
       }
 
       if (base_addr < MiNonPagedPoolStart ||
-            base_addr + BLOCK_HDR_SIZE + current->Size > MiNonPagedPoolStart + MiNonPagedPoolLength)
+            (ULONG_PTR)base_addr + current->hdr.Size > (ULONG_PTR)MiNonPagedPoolStart + MiNonPagedPoolLength)
       {
          DbgPrint("Block %x found outside pool area\n",current);
-         DbgPrint("Size %d\n",current->Size);
+         DbgPrint("Size %d\n",current->hdr.Size);
          DbgPrint("Limits are %x %x\n",MiNonPagedPoolStart,
-                  MiNonPagedPoolStart+MiNonPagedPoolLength);
+                  (ULONG_PTR)MiNonPagedPoolStart+MiNonPagedPoolLength);
          KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0);
       }
       blocks_seen++;
@@ -965,7 +950,7 @@
  * FUNCTION: Validate the integrity of the list of used blocks
  */
 {
-   BLOCK_HDR* current;
+   HDR_USED* current;
    PLIST_ENTRY current_entry;
    unsigned int blocks_seen=0;
 
@@ -974,23 +959,23 @@
    {
       PVOID base_addr;
 
-      current = CONTAINING_RECORD(current_entry, BLOCK_HDR, Used.ListEntry);
+      current = CONTAINING_RECORD(current_entry, HDR_USED, ListEntry);
       base_addr = (PVOID)current;
 
-      if (current->Magic != BLOCK_HDR_USED_MAGIC)
+      if (current->hdr.Magic != BLOCK_HDR_USED_MAGIC)
       {
          DbgPrint("Bad block magic (probable pool corruption) at %x\n",
                   current);
          KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0);
       }
       if (base_addr < MiNonPagedPoolStart ||
-            (base_addr+BLOCK_HDR_SIZE+current->Size) >
-            MiNonPagedPoolStart+MiNonPagedPoolLength)
+            ((ULONG_PTR)base_addr+current->hdr.Size) >
+            (ULONG_PTR)MiNonPagedPoolStart+MiNonPagedPoolLength)
       {
          DbgPrint("Block %x found outside pool area\n",current);
-         DbgPrint("Size %d\n",current->Size);
+         DbgPrint("Size %d\n",current->hdr.Size);
          DbgPrint("Limits are %x %x\n",MiNonPagedPoolStart,
-                  MiNonPagedPoolStart+MiNonPagedPoolLength);
+                  (ULONG_PTR)MiNonPagedPoolStart+MiNonPagedPoolLength);
          KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0);
       }
       blocks_seen++;
@@ -999,13 +984,13 @@
          DbgPrint("Too many blocks on used list\n");
          KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0);
       }
-      if (current->Used.ListEntry.Flink != &UsedBlockListHead &&
-            current->Used.ListEntry.Flink->Blink != &current->Used.ListEntry)
+      if (current->ListEntry.Flink != &UsedBlockListHead &&
+            current->ListEntry.Flink->Blink != &current->ListEntry)
       {
          DbgPrint("%s:%d:Break in list (current %x next %x "
                   "current->next->previous %x)\n",
-                  __FILE__,__LINE__,current, current->Used.ListEntry.Flink,
-                  current->Used.ListEntry.Flink->Blink);
+                  __FILE__,__LINE__,current, current->ListEntry.Flink,
+                  current->ListEntry.Flink->Blink);
          KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0);
       }
 
@@ -1013,7 +998,7 @@
    }
 }
 
-static void check_duplicates(BLOCK_HDR* blk)
+static void check_duplicates(HDR* blk)
 /*
  * FUNCTION: Check a block has no duplicates
  * ARGUMENTS:
@@ -1021,33 +1006,32 @@
  * NOTE: Bug checks if duplicates are found
  */
 {
-   char* base = (char*)blk;
-   char* last = ((char*)blk) + BLOCK_HDR_SIZE + blk->Size;
-   BLOCK_HDR* current;
+   ULONG_PTR base = (ULONG_PTR)blk;
+   ULONG_PTR last = (ULONG_PTR)blk + blk->Size;
    PLIST_ENTRY current_entry;
    PNODE p;
+   HDR_FREE* free;
+   HDR_USED* used;
 
    p = avl_get_first(FreeBlockListRoot);
 
    while (p)
    {
-      current = CONTAINING_RECORD(p, BLOCK_HDR, Free.Node);
-
-      if (current->Magic != BLOCK_HDR_FREE_MAGIC)
+      free = CONTAINING_RECORD(p, HDR_FREE, Node);
+      if (free->hdr.Magic != BLOCK_HDR_FREE_MAGIC)
       {
          DbgPrint("Bad block magic (probable pool corruption) at %x\n",
-                  current);
+                  free);
          KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0);
       }
 
-      if ( (char*)current > base && (char*)current < last )
+      if ( (ULONG_PTR)free > base && (ULONG_PTR)free < last )
       {
          DbgPrint("intersecting blocks on list\n");
          KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0);
       }
-      if  ( (char*)current < base &&
-            ((char*)current + current->Size + BLOCK_HDR_SIZE)
-            > base )
+      if  ( (ULONG_PTR)free < base &&
+            ((ULONG_PTR)free + free->hdr.Size) > base )
       {
          DbgPrint("intersecting blocks on list\n");
          KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0);
@@ -1058,16 +1042,15 @@
    current_entry = UsedBlockListHead.Flink;
    while (current_entry != &UsedBlockListHead)
    {
-      current = CONTAINING_RECORD(current_entry, BLOCK_HDR, Used.ListEntry);
+      used = CONTAINING_RECORD(current_entry, HDR_USED, ListEntry);
 
-      if ( (char*)current > base && (char*)current < last )
+      if ( (ULONG_PTR)used > base && (ULONG_PTR)used < last )
       {
          DbgPrint("intersecting blocks on list\n");
          KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0);
       }
-      if  ( (char*)current < base &&
-            ((char*)current + current->Size + BLOCK_HDR_SIZE)
-            > base )
+      if  ( (ULONG_PTR)current < base &&
+            ((ULONG_PTR)current + current->hdr.Size) > base )
       {
          DbgPrint("intersecting blocks on list\n");
          KEBUGCHECK(/*KBUG_POOL_FREE_LIST_CORRUPT*/0);
@@ -1083,7 +1066,8 @@
  * FUNCTION: Checks the integrity of the kernel memory heap
  */
 {
-   BLOCK_HDR* current;
+   HDR_FREE* free;
+   HDR_USED* used;
    PLIST_ENTRY current_entry;
    PNODE p;
 
@@ -1093,15 +1077,15 @@
    p = avl_get_first(FreeBlockListRoot);
    while (p)
    {
-      current = CONTAINING_RECORD(p, BLOCK_HDR, Free.Node);
-      check_duplicates(current);
+      freet = CONTAINING_RECORD(p, HDR_FREE, Node);
+      check_duplicates(&free->hdr);
       p = avl_get_next(FreeBlockListRoot, p);
    }
    current_entry = UsedBlockListHead.Flink;
    while (current_entry != &UsedBlockListHead)
    {
-      current = CONTAINING_RECORD(current_entry, BLOCK_HDR, Used.ListEntry);
-      check_duplicates(current);
+      used = CONTAINING_RECORD(current_entry, HDR_USED, ListEntry);
+      check_duplicates(&used->hdr);
       current_entry = current_entry->Flink;
    }
 }
@@ -1109,14 +1093,13 @@
 
 #if 0
 STATIC VOID
-free_pages(BLOCK_HDR* blk)
+free_pages(HDR_FREE* blk)
 {
    ULONG start;
    ULONG end;
-   ULONG i;
 
-   start = (ULONG)blk;
-   end = (ULONG)blk + BLOCK_HDR_SIZE + blk->Size;
+   start = (ULONG_PTR)blk;
+   end = (ULONG_PTR)blk + blk->hdr.Size;
 
    /*
     * If the block doesn't contain a whole page then there is nothing to do
@@ -1128,20 +1111,20 @@
 }
 #endif
 
-static void remove_from_used_list(BLOCK_HDR* current)
+static void remove_from_used_list(HDR_USED* current)
 {
-   RemoveEntryList(&current->Used.ListEntry);
-   EiUsedNonPagedPool -= current->Size;
+   RemoveEntryList(&current->ListEntry);
+   EiUsedNonPagedPool -= current->hdr.Size;
    EiNrUsedBlocks--;
 }
 
-static void remove_from_free_list(BLOCK_HDR* current)
+static void remove_from_free_list(HDR_FREE* current)
 {
-   DPRINT("remove_from_free_list %d\n", current->Size);
+   DPRINT("remove_from_free_list %d\n", current->hdr.Size);
 
-   avl_remove(&FreeBlockListRoot, &current->Free.Node, compare_node);
+   avl_remove(&FreeBlockListRoot, &current->Node, compare_node);
 
-   EiFreeNonPagedPool -= current->Size;
+   EiFreeNonPagedPool -= current->hdr.Size;
    EiNrFreeBlocks--;
    DPRINT("remove_from_free_list done\n");
 #ifdef DUMP_AVL
@@ -1151,49 +1134,48 @@
 }
 
 static void
-add_to_free_list(BLOCK_HDR* blk)
+add_to_free_list(HDR_FREE* blk)
 /*
  * FUNCTION: add the block to the free list (internal)
  */
 {
-   BLOCK_HDR* current;
+   HDR_FREE* current;
    BOOL UpdatePrevPtr = FALSE;
 
-   DPRINT("add_to_free_list (%d)\n", blk->Size);
+   DPRINT("add_to_free_list (%d)\n", blk->hdr.Size);
 
    EiNrFreeBlocks++;
 
-   current = blk->previous;
-   if (current && current->Magic == BLOCK_HDR_FREE_MAGIC)
+   current = (HDR_FREE*)blk->hdr.previous;
+   if (current && current->hdr.Magic == BLOCK_HDR_FREE_MAGIC)
    {
       remove_from_free_list(current);
-      current->Size = current->Size + BLOCK_HDR_SIZE + blk->Size;
-      current->Magic = BLOCK_HDR_USED_MAGIC;
-      memset(blk, 0xcc, BLOCK_HDR_SIZE);
+      current->hdr.Size = current->hdr.Size + blk->hdr.Size;
+      current->hdr.Magic = BLOCK_HDR_USED_MAGIC;
+      memset(blk, 0xcc, HDR_USED_SIZE);
       blk = current;
       UpdatePrevPtr = TRUE;
    }
 
-   current = (BLOCK_HDR*)((char*)blk + BLOCK_HDR_SIZE + blk->Size);
+   current = (HDR_FREE*)((ULONG_PTR)blk + blk->hdr.Size);
    if ((char*)current < (char*)MiNonPagedPoolStart + MiNonPagedPoolLength &&
-         current->Magic == BLOCK_HDR_FREE_MAGIC)
+         current->hdr.Magic == BLOCK_HDR_FREE_MAGIC)
    {
       remove_from_free_list(current);
-      blk->Size += BLOCK_HDR_SIZE + current->Size;
-      memset(current, 0xcc, BLOCK_HDR_SIZE);
+      blk->hdr.Size += current->hdr.Size;
+      memset(current, 0xcc, HDR_FREE_SIZE);
       UpdatePrevPtr = TRUE;
-      current = (BLOCK_HDR*)((char*)blk + BLOCK_HDR_SIZE + blk->Size);
+      current = (HDR_FREE*)((ULONG_PTR)blk + blk->hdr.Size);
    }
    if (UpdatePrevPtr &&
          (char*)current < (char*)MiNonPagedPoolStart + MiNonPagedPoolLength)
    {
-      current->previous = blk;
+      current->hdr.previous = &blk->hdr;
    }
-   DPRINT("%d\n", blk->Size);
-   blk->Magic = BLOCK_HDR_FREE_MAGIC;
-   EiFreeNonPagedPool += blk->Size;
-   avl_insert(&FreeBlockListRoot, &blk->Free.Node, compare_node);
-
+   DPRINT("%d\n", blk->hdr.Size);
+   blk->hdr.Magic = BLOCK_HDR_FREE_MAGIC;
+   EiFreeNonPagedPool += blk->hdr.Size;
+   avl_insert(&FreeBlockListRoot, &blk->Node, compare_node);
    DPRINT("add_to_free_list done\n");
 #ifdef DUMP_AVL
 
@@ -1201,40 +1183,26 @@
 #endif
 }
 
-static void add_to_used_list(BLOCK_HDR* blk)
+static void add_to_used_list(HDR_USED* blk)
 /*
  * FUNCTION: add the block to the used list (internal)
  */
 {
-   InsertHeadList(&UsedBlockListHead, &blk->Used.ListEntry);
-   EiUsedNonPagedPool += blk->Size;
+   InsertHeadList(&UsedBlockListHead, &blk->ListEntry);
+   EiUsedNonPagedPool += blk->hdr.Size;
    EiNrUsedBlocks++;
 }
 
-inline static void* block_to_address(BLOCK_HDR* blk)
-/*
- * FUNCTION: Translate a block header address to the corresponding block
- * address (internal)
- */
-{
-   return ( (void *) ((char*)blk + BLOCK_HDR_SIZE));
-}
 
-inline static BLOCK_HDR* address_to_block(void* addr)
-{
-   return (BLOCK_HDR *)
-          ( ((char*)addr) - BLOCK_HDR_SIZE );
-}
-
 static BOOLEAN
-grow_block(BLOCK_HDR* blk, PVOID end)
+grow_block(HDR_FREE* blk, PVOID end)
 {
    NTSTATUS Status;
    PFN_TYPE Page[32];
    ULONG_PTR StartIndex, EndIndex;
    ULONG i, j, k;
 
-   StartIndex = (ULONG_PTR)(PAGE_ROUND_UP((ULONG_PTR)blk + BLOCK_HDR_SIZE - (ULONG_PTR)MiNonPagedPoolStart)) / PAGE_SIZE;
+   StartIndex = (ULONG_PTR)(PAGE_ROUND_UP((ULONG_PTR)blk + HDR_FREE_SIZE - (ULONG_PTR)MiNonPagedPoolStart)) / PAGE_SIZE;
    EndIndex = ((ULONG_PTR)PAGE_ROUND_UP(end) - (ULONG_PTR)MiNonPagedPoolStart) / PAGE_SIZE;
 
 
@@ -1285,72 +1253,86 @@
    return TRUE;
 }
 
-static BLOCK_HDR* get_block(unsigned int size, unsigned long alignment)
+static HDR_USED* get_block(unsigned int size, unsigned long alignment)
 {
-   BLOCK_HDR *blk, *current, *previous = NULL, *next = NULL, *best = NULL;
+   HDR_FREE *blk, *current, *previous = NULL, *next = NULL, *best = NULL;
    ULONG previous_size = 0, current_size, next_size = 0, new_size;
    PVOID end;
-   PVOID addr, aligned_addr;
+   PVOID addr, aligned_addr, best_aligned_addr;
    PNODE p;
 
    DPRINT("get_block %d\n", size);
 
-   if (alignment == 0)
+   p = avl_find_equal_or_greater(FreeBlockListRoot, size + HDR_USED_SIZE, compare_value);
+   while (p)
    {
-      p = avl_find_equal_or_greater(FreeBlockListRoot, size, compare_value);
-      if (p)
+      current = CONTAINING_RECORD(p, HDR_FREE, Node);
+      addr = (PVOID)((ULONG_PTR)current + HDR_USED_SIZE);
+      /* calculate first aligned address available within this block */
+      aligned_addr = alignment > 0 ? MM_ROUND_UP(addr, alignment) : addr;
+      if (size < PAGE_SIZE)
       {
-         best = CONTAINING_RECORD(p, BLOCK_HDR, Free.Node);
-         addr = block_to_address(best);
+         /* check that the block is in one page */
+         if (PAGE_ROUND_DOWN(aligned_addr) != PAGE_ROUND_DOWN((ULONG_PTR)aligned_addr + size - 1))
+         {
+            aligned_addr = (PVOID)PAGE_ROUND_UP(aligned_addr);
+         }
       }
-   }
-   else
-   {
-      p = avl_find_equal_or_greater(FreeBlockListRoot, size, compare_value);
-
-      while(p)
+      DPRINT("%x %x\n", addr, aligned_addr);
+      if (aligned_addr != addr)
       {
-         current = CONTAINING_RECORD(p, BLOCK_HDR, Free.Node);
-         addr = block_to_address(current);
-         /* calculate first aligned address available within this block */
-         aligned_addr = MM_ROUND_UP(addr, alignment);
-         /* check to see if this address is already aligned */
-         if (addr == aligned_addr)
+         while((ULONG_PTR)aligned_addr - (ULONG_PTR)addr < HDR_FREE_SIZE)
          {
-            if (current->Size >= size &&
-                  (best == NULL || current->Size < best->Size))
+            if (alignment == 0)
             {
-               best = current;
+               aligned_addr = (PVOID)((ULONG_PTR)current + HDR_USED_SIZE + HDR_FREE_SIZE);
             }
-         }
-         else
-         {
-            /* make sure there's enough room to make a free block by the space skipped
-             * from alignment. If not, calculate forward to the next alignment
-             * and see if we allocate there...
-             */
-            new_size = (ULONG_PTR)aligned_addr - (ULONG_PTR)addr + size;
-            if ((ULONG_PTR)aligned_addr - (ULONG_PTR)addr < BLOCK_HDR_SIZE)
+            else
             {
-               /* not enough room for a free block header, add some more bytes */
-               aligned_addr = MM_ROUND_UP(block_to_address((BLOCK_HDR*)((char*)current + BLOCK_HDR_SIZE)), alignment);
-               new_size = (ULONG_PTR)aligned_addr - (ULONG_PTR)addr + size;
+               aligned_addr = MM_ROUND_UP((PVOID)((ULONG_PTR)current + HDR_USED_SIZE + HDR_FREE_SIZE), alignment);
             }
-            if (current->Size >= new_size &&
-                  (best == NULL || current->Size < best->Size))
+            if (size < PAGE_SIZE)
             {
-               best = current;
+               /* check that the block is in one page */
+               if (PAGE_ROUND_DOWN(aligned_addr) != PAGE_ROUND_DOWN((ULONG_PTR)aligned_addr + size - 1))
+               {
+                  aligned_addr = (PVOID)PAGE_ROUND_UP(aligned_addr);
+               }
             }
          }
-         if (best && current->Size >= size + alignment + 2 * BLOCK_HDR_SIZE)
+      }
+      DPRINT("%x %x\n", addr, aligned_addr);
+      new_size = (ULONG_PTR)aligned_addr - (ULONG_PTR)addr + size;
+      if (current->hdr.Size >= new_size + HDR_USED_SIZE &&
+          (best == NULL || current->hdr.Size < best->hdr.Size))
+      {
+         best = current;
+         best_aligned_addr = aligned_addr;
+         if (new_size <= size + 2 * HDR_FREE_SIZE)
          {
-            break;
+             break;
          }
-         p = avl_get_next(FreeBlockListRoot, p);
-
       }
-   }
-
+      
+      if (best)
+      {
+         if (size < PAGE_SIZE)
+         {
+            if (current->hdr.Size >= 2 * PAGE_SIZE + HDR_FREE_SIZE)
+            {
+                break;
+            }
+         }
+         else
+         {
+            if (current->hdr.Size >= size + alignment + HDR_FREE_SIZE)
+            {
+                break;
+            }
+         }
+      }
+      p = avl_get_next(FreeBlockListRoot, p);
+   }         
    /*
     * We didn't find anything suitable at all.
     */
@@ -1359,40 +1341,31 @@
       return NULL;
    }
 
-   current = best;
-   current_size = current->Size;
+   DPRINT(":: blk %x blk->hdr.Size %d (%d) Size %d\n", best, best->hdr.Size, best->hdr.Size - HDR_USED_SIZE, size);
 
-   if (alignment > 0)
+   current = best;
+   current_size = current->hdr.Size - HDR_USED_SIZE;
+   addr = (PVOID)((ULONG_PTR)current + HDR_USED_SIZE);
+   if (addr != best_aligned_addr)
    {
-      addr = block_to_address(current);
-      aligned_addr = MM_ROUND_UP(addr, alignment);
-      if (addr != aligned_addr)
-      {
-         blk = address_to_block(aligned_addr);
-         if ((char*)blk < (char*)current + BLOCK_HDR_SIZE)
-         {
-            aligned_addr = MM_ROUND_UP(block_to_address((BLOCK_HDR*)((char*)current + BLOCK_HDR_SIZE)), alignment);
-            blk = address_to_block(aligned_addr);
-         }
-         /*
-          * if size-aligned, break off the preceding bytes into their own block...
-          */
-         previous = current;
-         previous_size = (ULONG_PTR)blk - (ULONG_PTR)previous - BLOCK_HDR_SIZE;
-         current = blk;
-         current_size -= ((ULONG_PTR)current - (ULONG_PTR)previous);
-      }
+      blk = (HDR_FREE*)((ULONG_PTR)best_aligned_addr - HDR_USED_SIZE);
+      /*
+       * if size-aligned, break off the preceding bytes into their own block...
+       */
+      previous = current;
+      previous_size = (ULONG_PTR)blk - (ULONG_PTR)previous - HDR_FREE_SIZE;
+      current = blk;
+      current_size -= ((ULONG_PTR)current - (ULONG_PTR)previous);
    }
+   end = (PVOID)((ULONG_PTR)current + HDR_USED_SIZE + size);
 
-   end = (char*)current + BLOCK_HDR_SIZE + size;
-
-   if (current_size >= size + BLOCK_HDR_SIZE + MM_POOL_ALIGNMENT)
+   if (current_size >= size + HDR_FREE_SIZE + MM_POOL_ALIGNMENT)
    {
       /* create a new free block after our block, if the memory size is >= 4 byte for this block */
-      next = (BLOCK_HDR*)((ULONG_PTR)current + size + BLOCK_HDR_SIZE);
-      next_size = current_size - size - BLOCK_HDR_SIZE;
+      next = (HDR_FREE*)((ULONG_PTR)current + size + HDR_USED_SIZE);
+      next_size = current_size - size - HDR_FREE_SIZE;
       current_size = size;
-      end = (char*)next + BLOCK_HDR_SIZE;
+      end = (PVOID)((ULONG_PTR)next + HDR_FREE_SIZE);
    }
 
    if (previous)
@@ -1403,17 +1376,17 @@
          add_to_free_list(previous);
          return NULL;
       }
-      memset(current, 0, BLOCK_HDR_SIZE);
-      current->Size = current_size;
-      current->Magic = BLOCK_HDR_USED_MAGIC;
-      current->previous = previous;
-      previous->Size = previous_size;
+      memset(current, 0, HDR_USED_SIZE);
+      current->hdr.Size = current_size + HDR_USED_SIZE;
+      current->hdr.Magic = BLOCK_HDR_USED_MAGIC;
+      current->hdr.previous = &previous->hdr;
+      previous->hdr.Size = previous_size + HDR_FREE_SIZE;
       if (next == NULL)
       {
-         blk = (BLOCK_HDR*)((char*)current + BLOCK_HDR_SIZE + current->Size);
-         if ((char*)blk < (char*)MiNonPagedPoolStart + MiNonPagedPoolLength)
+         blk = (HDR_FREE*)((ULONG_PTR)current + current->hdr.Size);
+         if ((ULONG_PTR)blk < (ULONG_PTR)MiNonPagedPoolStart + MiNonPagedPoolLength)
          {
-            blk->previous = current;
+            blk->hdr.previous = &current->hdr;
          }
       }
 
@@ -1428,56 +1401,55 @@
          add_to_free_list(current);
          return NULL;
       }
-
-      current->Magic = BLOCK_HDR_USED_MAGIC;
+      current->hdr.Magic = BLOCK_HDR_USED_MAGIC;
       if (next)
       {
-         current->Size = current_size;
+         current->hdr.Size = current_size + HDR_USED_SIZE;
       }
    }
 
    if (next)
    {
-      memset(next, 0, BLOCK_HDR_SIZE);
-
-      next->Size = next_size;
-      next->Magic = BLOCK_HDR_FREE_MAGIC;
-      next->previous = current;
-      blk = (BLOCK_HDR*)((char*)next + BLOCK_HDR_SIZE + next->Size);
-      if ((char*)blk < (char*)MiNonPagedPoolStart + MiNonPagedPoolLength)
+      memset(next, 0, HDR_FREE_SIZE);
+      next->hdr.Size = next_size + HDR_FREE_SIZE;
+      next->hdr.Magic = BLOCK_HDR_FREE_MAGIC;
+      next->hdr.previous = &current->hdr;
+      blk = (HDR_FREE*)((ULONG_PTR)next + next->hdr.Size);
+      if ((ULONG_PTR)blk < (ULONG_PTR)MiNonPagedPoolStart + MiNonPagedPoolLength)
       {
-         blk->previous = next;
+         blk->hdr.previous = &next->hdr;
       }
       add_to_free_list(next);
    }
 
-   add_to_used_list(current);
+   add_to_used_list((HDR_USED*)current);
    VALIDATE_POOL;
-   return current;
+
+   if (size < PAGE_SIZE)
+   {
+       addr = (PVOID)((ULONG_PTR)current + HDR_USED_SIZE);
+       if (PAGE_ROUND_DOWN(addr) != PAGE_ROUND_DOWN((PVOID)((ULONG_PTR)addr + size - 1)))
+       {
+           DPRINT1("%x %x\n", addr, (ULONG_PTR)addr + size);
+       }
+       ASSERT (PAGE_ROUND_DOWN(addr) == PAGE_ROUND_DOWN((PVOID)((ULONG_PTR)addr + size - 1)));
+   }
+   if (alignment)
+   {
+       addr = (PVOID)((ULONG_PTR)current + HDR_USED_SIZE);
+       ASSERT(MM_ROUND_UP(addr, alignment) == addr);
+   }
+   return (HDR_USED*)current;
 }
 
-#endif /* not WHOLE_PAGE_ALLOCATIONS */
-
 ULONG STDCALL
 ExRosQueryNonPagedPoolTag ( PVOID Addr )
 {
-#ifdef WHOLE_PAGE_ALLOCATIONS /* WHOLE_PAGE_ALLOCATIONS */
-
-   UNIMPLEMENTED;
-   return 0;
-
-#else /* not WHOLE_PAGE_ALLOCATIONS */
-
-   BLOCK_HDR* blk=address_to_block(Addr);
-
-   if (blk->Magic != BLOCK_HDR_USED_MAGIC)
+   HDR_USED* blk=(HDR_USED*)((ULONG_PTR)Addr - HDR_USED_SIZE);
+   if (blk->hdr.Magic != BLOCK_HDR_USED_MAGIC)
       KEBUGCHECK(0);
-   if (blk->Magic == BLOCK_HDR_FREE_MAGIC)
-      KEBUGCHECK(0);
 
-   return blk->Used.Tag;
[truncated at 1000 lines; 391 more skipped]