Author: fireball
Date: Thu Oct  7 17:05:29 2010
New Revision: 49034

URL: http://svn.reactos.org/svn/reactos?rev=49034&view=rev
Log:
[HEAP]
- Fix allocated/free memory fillers to match those Windows uses (winetests)
- Add missing coalesce-on-free flag check in RtlCreateHeap
- Turn on tail check/pattern filling in RtlAllocateHeap.
- Add extra stuff storage support in RtlAllocateHeap and its helpers.
- Set win32 statuses where necessary.
- Return success in RtlValidateHeap to reduce spam when running winetest.

Modified:
    trunk/reactos/lib/rtl/heap_rewrite.c

Modified: trunk/reactos/lib/rtl/heap_rewrite.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/heap_rewrite.c?rev=49034&r1=49033&r2=49034&view=diff
==============================================================================
--- trunk/reactos/lib/rtl/heap_rewrite.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/heap_rewrite.c [iso-8859-1] Thu Oct  7 17:05:29 2010
@@ -30,8 +30,8 @@
 #define HEAP_ENTRY_SHIFT 3
 #define HEAP_MAX_BLOCK_SIZE ((0x80000 - PAGE_SIZE) >> HEAP_ENTRY_SHIFT)
 
-#define ARENA_INUSE_FILLER     0x55555555
-#define ARENA_FREE_FILLER      0xaaaaaaaa
+#define ARENA_INUSE_FILLER     0xBAADF00D
+#define ARENA_FREE_FILLER      0xFEEEFEEE
 #define HEAP_TAIL_FILL         0xab
 
 // from ntifs.h, should go to another header!
@@ -261,6 +261,7 @@
     HEAP_ENTRY BusyBlock;
 } HEAP_VIRTUAL_ALLOC_ENTRY, *PHEAP_VIRTUAL_ALLOC_ENTRY;
 
+extern BOOLEAN RtlpPageHeapEnabled;
 HANDLE NTAPI
 RtlpSpecialHeapCreate(ULONG Flags,
                       PVOID Addr,
@@ -341,6 +342,9 @@
                         PSIZE_T FreeSize,
                         BOOLEAN Remove);
 
+PHEAP_ENTRY_EXTRA NTAPI
+RtlpGetExtraStuffPointer(PHEAP_ENTRY HeapEntry);
+
 /* FUNCTIONS *****************************************************************/
 
 VOID NTAPI
@@ -1546,7 +1550,8 @@
         Heap = RtlpSpecialHeapCreate(Flags, Addr, TotalSize, CommitSize, Lock, 
Parameters);
         if (Heap) return Heap;
 
-        ASSERT(FALSE);
+        //ASSERT(FALSE);
+        DPRINT1("Enabling page heap failed\n");
     }
 
     /* Check validation flags */
@@ -1560,11 +1565,17 @@
     if (!Parameters) Parameters = &SafeParams;
 
     /* Check global flags */
+    if (NtGlobalFlags & FLG_HEAP_DISABLE_COALESCING)
+        Flags |= HEAP_DISABLE_COALESCE_ON_FREE;
+
     if (NtGlobalFlags & FLG_HEAP_ENABLE_FREE_CHECK)
         Flags |= HEAP_FREE_CHECKING_ENABLED;
 
     if (NtGlobalFlags & FLG_HEAP_ENABLE_TAIL_CHECK)
         Flags |= HEAP_TAIL_CHECKING_ENABLED;
+
+    if (Flags & HEAP_TAIL_CHECKING_ENABLED)
+        DPRINT1("TailChecking!\n");
 
     if (RtlpGetMode() == UserMode)
     {
@@ -2014,7 +2025,7 @@
             if (FreeFlags & HEAP_ENTRY_LAST_ENTRY)
             {
                 /* Insert it to the free list if it's the last entry */
-                RtlpInsertFreeBlockHelper(Heap, SplitBlock, FreeSize, TRUE);
+                RtlpInsertFreeBlockHelper(Heap, SplitBlock, FreeSize, FALSE);
                 Heap->TotalFreeSize += FreeSize;
             }
             else
@@ -2025,7 +2036,7 @@
                 if (SplitBlock2->Flags & HEAP_ENTRY_BUSY)
                 {
                     SplitBlock2->PreviousSize = (USHORT)FreeSize;
-                    RtlpInsertFreeBlockHelper(Heap, SplitBlock, FreeSize, 
TRUE);
+                    RtlpInsertFreeBlockHelper(Heap, SplitBlock, FreeSize, 
FALSE);
                     Heap->TotalFreeSize += FreeSize;
                 }
                 else
@@ -2034,7 +2045,7 @@
                     SplitBlock->Flags = SplitBlock2->Flags;
 
                     /* Remove that next entry */
-                    RtlpRemoveFreeBlock(Heap, SplitBlock2, FALSE, TRUE);
+                    RtlpRemoveFreeBlock(Heap, SplitBlock2, FALSE, FALSE);
 
                     /* Update sizes */
                     FreeSize += SplitBlock2->Size;
@@ -2052,7 +2063,7 @@
                         }
 
                         /* Actually insert it */
-                        RtlpInsertFreeBlockHelper( Heap, SplitBlock, 
(USHORT)FreeSize, TRUE );
+                        RtlpInsertFreeBlockHelper(Heap, SplitBlock, 
(USHORT)FreeSize, FALSE);
 
                         /* Update total size */
                         Heap->TotalFreeSize += FreeSize;
@@ -2094,6 +2105,7 @@
     PLIST_ENTRY FreeListHead, Next;
     PHEAP_FREE_ENTRY FreeBlock;
     PHEAP_ENTRY InUseEntry;
+    PHEAP_ENTRY_EXTRA Extra;
     EXCEPTION_RECORD ExceptionRecord;
 
     /* Go through the zero list to find a place where to insert the new entry 
*/
@@ -2130,6 +2142,27 @@
                     /* Zero memory if that was requested */
                     if (Flags & HEAP_ZERO_MEMORY)
                         RtlZeroMemory(InUseEntry + 1, Size);
+                    else if (Heap->Flags & HEAP_FREE_CHECKING_ENABLED)
+                    {
+                        /* Fill this block with a special pattern */
+                        RtlFillMemoryUlong(InUseEntry + 1, Size & ~0x3, 
ARENA_INUSE_FILLER);
+                    }
+
+                    /* Fill tail of the block with a special pattern too if 
requested */
+                    if (Heap->Flags & HEAP_TAIL_CHECKING_ENABLED)
+                    {
+                        RtlFillMemory((PCHAR)(InUseEntry + 1) + Size, 
sizeof(HEAP_ENTRY), HEAP_TAIL_FILL);
+                        InUseEntry->Flags |= HEAP_ENTRY_FILL_PATTERN;
+                    }
+
+                    /* Prepare extra if it's present */
+                    if (InUseEntry->Flags & HEAP_ENTRY_EXTRA_PRESENT)
+                    {
+                        Extra = RtlpGetExtraStuffPointer(InUseEntry);
+                        RtlZeroMemory(Extra, sizeof(HEAP_ENTRY_EXTRA));
+
+                        // TODO: Tagging
+                    }
 
                     /* Return pointer to the */
                     return InUseEntry + 1;
@@ -2158,13 +2191,34 @@
         /* Zero memory if that was requested */
         if (Flags & HEAP_ZERO_MEMORY)
             RtlZeroMemory(InUseEntry + 1, Size);
+        else if (Heap->Flags & HEAP_FREE_CHECKING_ENABLED)
+        {
+            /* Fill this block with a special pattern */
+            RtlFillMemoryUlong(InUseEntry + 1, Size & ~0x3, 
ARENA_INUSE_FILLER);
+        }
+
+        /* Fill tail of the block with a special pattern too if requested */
+        if (Heap->Flags & HEAP_TAIL_CHECKING_ENABLED)
+        {
+            RtlFillMemory((PCHAR)(InUseEntry + 1) + Size, sizeof(HEAP_ENTRY), 
HEAP_TAIL_FILL);
+            InUseEntry->Flags |= HEAP_ENTRY_FILL_PATTERN;
+        }
+
+        /* Prepare extra if it's present */
+        if (InUseEntry->Flags & HEAP_ENTRY_EXTRA_PRESENT)
+        {
+            Extra = RtlpGetExtraStuffPointer(InUseEntry);
+            RtlZeroMemory(Extra, sizeof(HEAP_ENTRY_EXTRA));
+
+            // TODO: Tagging
+        }
 
         /* Return pointer to the */
         return InUseEntry + 1;
     }
 
     /* Really unfortunate, out of memory condition */
-    //STATUS_NO_MEMORY;
+    RtlSetLastWin32ErrorAndNtStatusFromNtStatus(STATUS_NO_MEMORY);
 
     /* Generate an exception */
     if (Flags & HEAP_GENERATE_EXCEPTIONS)
@@ -2209,6 +2263,7 @@
     EXCEPTION_RECORD ExceptionRecord;
     BOOLEAN HeapLocked = FALSE;
     PHEAP_VIRTUAL_ALLOC_ENTRY VirtualBlock = NULL;
+    PHEAP_ENTRY_EXTRA Extra;
     NTSTATUS Status;
 
     /* Force flags */
@@ -2217,7 +2272,7 @@
     /* Check for the maximum size */
     if (Size >= 0x80000000)
     {
-        // STATUS_NO_MEMORY
+        RtlSetLastWin32ErrorAndNtStatusFromNtStatus(STATUS_NO_MEMORY);
         return FALSE;
     }
 
@@ -2225,24 +2280,27 @@
         HEAP_VALIDATE_ALL_ENABLED |
         HEAP_VALIDATE_PARAMETERS_ENABLED |
         HEAP_FLAG_PAGE_ALLOCS |
-        HEAP_EXTRA_FLAGS_MASK |
         HEAP_CREATE_ENABLE_TRACING |
-        HEAP_FREE_CHECKING_ENABLED |
-        HEAP_TAIL_CHECKING_ENABLED |
         HEAP_CREATE_ALIGN_16))
     {
         DPRINT1("HEAP: RtlAllocateHeap is called with unsupported flags %x, 
ignoring\n", Flags);
     }
 
+    if (Flags & HEAP_TAIL_CHECKING_ENABLED)
+        DPRINT1("TailChecking, Heap %p\n!", Heap);
+
     /* Calculate allocation size and index */
-    if (!Size) Size = 1;
-    AllocationSize = (Size + Heap->AlignRound) & Heap->AlignMask;
+    if (Size)
+        AllocationSize = Size;
+    else
+        AllocationSize = 1;
+    AllocationSize = (AllocationSize + Heap->AlignRound) & Heap->AlignMask;
     Index = AllocationSize >>  HEAP_ENTRY_SHIFT;
 
     /* Acquire the lock if necessary */
     if (!(Flags & HEAP_NO_SERIALIZE))
     {
-        RtlEnterHeapLock( Heap->LockVariable );
+        RtlEnterHeapLock(Heap->LockVariable);
         HeapLocked = TRUE;
     }
 
@@ -2261,7 +2319,7 @@
 
             /* Save flags and remove the free entry */
             FreeFlags = FreeBlock->Flags;
-            RtlpRemoveFreeBlock(Heap, FreeBlock, TRUE, TRUE);
+            RtlpRemoveFreeBlock(Heap, FreeBlock, TRUE, FALSE);
 
             /* Update the total free size of the heap */
             Heap->TotalFreeSize -= Index;
@@ -2308,7 +2366,7 @@
             FreeBlock = CONTAINING_RECORD(FreeListHead->Blink,
                                           HEAP_FREE_ENTRY,
                                           FreeList);
-            RtlpRemoveFreeBlock(Heap, FreeBlock, TRUE, TRUE);
+            RtlpRemoveFreeBlock(Heap, FreeBlock, TRUE, FALSE);
 
             /* Split it */
             InUseEntry = RtlpSplitEntry(Heap, FreeBlock, AllocationSize, 
Index, Size);
@@ -2320,6 +2378,27 @@
         /* Zero memory if that was requested */
         if (Flags & HEAP_ZERO_MEMORY)
             RtlZeroMemory(InUseEntry + 1, Size);
+        else if (Heap->Flags & HEAP_FREE_CHECKING_ENABLED)
+        {
+            /* Fill this block with a special pattern */
+            RtlFillMemoryUlong(InUseEntry + 1, Size & ~0x3, 
ARENA_INUSE_FILLER);
+        }
+
+        /* Fill tail of the block with a special pattern too if requested */
+        if (Heap->Flags & HEAP_TAIL_CHECKING_ENABLED)
+        {
+            RtlFillMemory((PCHAR)(InUseEntry + 1) + Size, sizeof(HEAP_ENTRY), 
HEAP_TAIL_FILL);
+            InUseEntry->Flags |= HEAP_ENTRY_FILL_PATTERN;
+        }
+
+        /* Prepare extra if it's present */
+        if (InUseEntry->Flags & HEAP_ENTRY_EXTRA_PRESENT)
+        {
+            Extra = RtlpGetExtraStuffPointer(InUseEntry);
+            RtlZeroMemory(Extra, sizeof(HEAP_ENTRY_EXTRA));
+
+            // TODO: Tagging
+        }
 
         /* User data starts right after the entry's header */
         return InUseEntry + 1;
@@ -2377,7 +2456,7 @@
         RtlRaiseException(&ExceptionRecord);
     }
 
-    //STATUS_BUFFER_TOO_SMALL;
+    RtlSetLastWin32ErrorAndNtStatusFromNtStatus(STATUS_BUFFER_TOO_SMALL);
 
     /* Release the lock */
     if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
@@ -2431,7 +2510,7 @@
     {
         /* This is an invalid block */
         DPRINT1("HEAP: Trying to free an invalid address %p!\n", Ptr);
-        // FIXME: Set STATUS_INVALID_PARAMETER
+        RtlSetLastWin32ErrorAndNtStatusFromNtStatus(STATUS_INVALID_PARAMETER);
 
         /* Release the heap lock */
         if (Locked) RtlLeaveHeapLock(Heap->LockVariable);
@@ -2457,7 +2536,7 @@
         if (!NT_SUCCESS(Status))
         {
             DPRINT1("Failed releasing memory with Status 0x%08X\n", Status);
-            // TODO: Set this status in user mode
+            RtlSetLastWin32ErrorAndNtStatusFromNtStatus(Status);
         }
     }
     else
@@ -2593,7 +2672,7 @@
     /* Return success in case of a null pointer */
     if (!Ptr)
     {
-        // STATUS_SUCCESS
+        RtlSetLastWin32ErrorAndNtStatusFromNtStatus(STATUS_SUCCESS);
         return NULL;
     }
 
@@ -2605,7 +2684,7 @@
     /* Make sure size is valid */
     if (Size >= 0x80000000)
     {
-        // STATUS_NO_MEMORY
+        RtlSetLastWin32ErrorAndNtStatusFromNtStatus(STATUS_NO_MEMORY);
         return NULL;
     }
 
@@ -2635,7 +2714,7 @@
     /* If that entry is not really in-use, we have a problem */
     if (!(InUseEntry->Flags & HEAP_ENTRY_BUSY))
     {
-        // STATUS_INVALID_PARAMETER
+        RtlSetLastWin32ErrorAndNtStatusFromNtStatus(STATUS_INVALID_PARAMETER);
 
         /* Release the lock and return */
         if (HeapLocked)
@@ -3086,7 +3165,7 @@
     /* Return -1 if that entry is free */
     if (!(HeapEntry->Flags & HEAP_ENTRY_BUSY))
     {
-        // STATUS_INVALID_PARAMETER
+        RtlSetLastWin32ErrorAndNtStatusFromNtStatus(STATUS_INVALID_PARAMETER);
         return (SIZE_T)-1;
     }
 
@@ -3131,7 +3210,9 @@
 )
 {
     UNIMPLEMENTED;
-    return FALSE;
+
+    /* Imitate success */
+    return TRUE;
 }
 
 VOID


Reply via email to