Author: fireball
Date: Wed Oct  6 09:19:24 2010
New Revision: 49010

URL: http://svn.reactos.org/svn/reactos?rev=49010&view=rev
Log:
[RTL/HEAP]
- Implement missing parts of a virtual block allocations support.
- Minor fixes to handling extra stuff in heap blocks.
- Wine's heap regression tests now run through the end without crashing and 
show 277 failures.

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=49010&r1=49009&r2=49010&view=diff
==============================================================================
--- trunk/reactos/lib/rtl/heap_rewrite.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/heap_rewrite.c [iso-8859-1] Wed Oct  6 09:19:24 2010
@@ -2404,7 +2404,9 @@
     PHEAP_ENTRY HeapEntry;
     USHORT TagIndex = 0;
     SIZE_T BlockSize;
+    PHEAP_VIRTUAL_ALLOC_ENTRY VirtualEntry;
     BOOLEAN Locked = FALSE;
+    NTSTATUS Status;
 
     /* Freeing NULL pointer is a legal operation */
     if (!Ptr) return TRUE;
@@ -2440,7 +2442,24 @@
     if (HeapEntry->Flags & HEAP_ENTRY_VIRTUAL_ALLOC)
     {
         /* Big allocation */
-        ASSERT(FALSE);
+        VirtualEntry = CONTAINING_RECORD(HeapEntry, HEAP_VIRTUAL_ALLOC_ENTRY, 
BusyBlock);
+
+        /* Remove it from the list */
+        RemoveEntryList(&VirtualEntry->Entry);
+
+        // TODO: Tagging
+
+        BlockSize = 0;
+        Status = ZwFreeVirtualMemory(NtCurrentProcess(),
+                                     (PVOID *)&VirtualEntry,
+                                     &BlockSize,
+                                     MEM_RELEASE);
+
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("Failed releasing memory with Status 0x%08X\n", Status);
+            // TODO: Set this status in user mode
+        }
     }
     else
     {
@@ -2514,6 +2533,26 @@
 {
     /* We always fail growing in place now */
     return FALSE;
+}
+
+PHEAP_ENTRY_EXTRA NTAPI
+RtlpGetExtraStuffPointer(PHEAP_ENTRY HeapEntry)
+{
+    PHEAP_VIRTUAL_ALLOC_ENTRY VirtualEntry;
+
+    /* Check if it's a big block */
+    if (HeapEntry->Flags & HEAP_ENTRY_VIRTUAL_ALLOC)
+    {
+        VirtualEntry = CONTAINING_RECORD(HeapEntry, HEAP_VIRTUAL_ALLOC_ENTRY, 
BusyBlock);
+
+        /* Return a pointer to the extra stuff*/
+        return &VirtualEntry->ExtraStuff;
+    }
+    else
+    {
+        /* This is a usual entry, which means extra stuff follows this block */
+        return (PHEAP_ENTRY_EXTRA)(HeapEntry + HeapEntry->Size - 1);
+    }
 }
 
 
@@ -2870,12 +2909,11 @@
                     /* Process extra stuff if it exists */
                     if (NewInUseEntry->Flags & HEAP_ENTRY_EXTRA_PRESENT)
                     {
-                        UNIMPLEMENTED;
-                        NewExtra = 
NULL;//RtlpGetExtraStuffPointer(NewInUseEntry);
+                        NewExtra = RtlpGetExtraStuffPointer(NewInUseEntry);
 
                         if (InUseEntry->Flags & HEAP_ENTRY_EXTRA_PRESENT)
                         {
-                            OldExtra = 
NULL;//RtlpGetExtraStuffPointer(InUseEntry);
+                            OldExtra = RtlpGetExtraStuffPointer(InUseEntry);
                             NewExtra->Settable = OldExtra->Settable;
                         }
                         else
@@ -3031,6 +3069,13 @@
     PHEAP_ENTRY HeapEntry;
     SIZE_T EntrySize;
 
+    // FIXME This is a hack around missing SEH support!
+    if (!Heap)
+    {
+        RtlSetLastWin32ErrorAndNtStatusFromNtStatus(STATUS_INVALID_HANDLE);
+        return (SIZE_T)-1;
+    }
+
     /* Force flags */
     Flags |= Heap->Flags;
 
@@ -3049,10 +3094,7 @@
     /* Get size of this block depending if it's a usual or a big one */
     if (HeapEntry->Flags & HEAP_ENTRY_VIRTUAL_ALLOC)
     {
-        // FIXME implement
-        UNIMPLEMENTED;
-        ASSERT(FALSE);
-        EntrySize = 0;
+        EntrySize = RtlpGetSizeOfBigBlock(HeapEntry);
     }
     else
     {


Reply via email to