Rémi Bernon : ntdll: Fix main heap struct layout and flags members.

Alexandre Julliard julliard at winehq.org
Tue Apr 19 16:20:14 CDT 2022


Module: wine
Branch: master
Commit: 43fe980818d93e8f407eb6447aaf7eb4381c3cee
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=43fe980818d93e8f407eb6447aaf7eb4381c3cee

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Tue Apr 19 19:33:32 2022 +0200

ntdll: Fix main heap struct layout and flags members.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/kernel32/tests/heap.c |  3 --
 dlls/ntdll/heap.c          | 72 +++++++++++++++++++++++++++-------------------
 2 files changed, 43 insertions(+), 32 deletions(-)

diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c
index e1cda94f78c..104eced3bf4 100644
--- a/dlls/kernel32/tests/heap.c
+++ b/dlls/kernel32/tests/heap.c
@@ -1974,9 +1974,7 @@ static void test_heap_layout( HANDLE handle, DWORD global_flag, DWORD heap_flags
     if (global_flag & FLG_HEAP_ENABLE_TAGGING) heap_flags |= HEAP_SHARED;
     if (!(global_flag & FLG_HEAP_PAGE_ALLOCS)) force_flags &= ~(HEAP_GROWABLE|HEAP_PRIVATE);
 
-    todo_wine_if( force_flags & (HEAP_PRIVATE|HEAP_NO_SERIALIZE) )
     ok( heap->force_flags == force_flags, "got force_flags %#x\n", heap->force_flags );
-    todo_wine_if( heap_flags & (HEAP_VALIDATE_ALL|HEAP_VALIDATE_PARAMS|HEAP_SHARED|HEAP_PRIVATE) )
     ok( heap->flags == heap_flags, "got flags %#x\n", heap->flags );
 
     if (heap->flags & HEAP_PAGE_ALLOCS)
@@ -1990,7 +1988,6 @@ static void test_heap_layout( HANDLE handle, DWORD global_flag, DWORD heap_flags
     }
     else
     {
-        todo_wine
         ok( heap->ffeeffee == 0xffeeffee, "got ffeeffee %#x\n", heap->ffeeffee );
         ok( heap->auto_flags == (heap_flags & HEAP_GROWABLE) || !heap->auto_flags,
             "got auto_flags %#x\n", heap->auto_flags );
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c
index 01364016271..298c39f24ff 100644
--- a/dlls/ntdll/heap.c
+++ b/dlls/ntdll/heap.c
@@ -142,17 +142,17 @@ typedef struct tagSUBHEAP
 #define SUBHEAP_MAGIC    ((DWORD)('S' | ('U'<<8) | ('B'<<16) | ('H'<<24)))
 
 typedef struct tagHEAP
-{
-    DWORD_PTR        unknown1[2];
-    DWORD            unknown2[2];
-    DWORD_PTR        unknown3[4];
-    DWORD            unknown4;
-    DWORD_PTR        unknown5[2];
-    DWORD            unknown6[3];
-    DWORD_PTR        unknown7[2];
-    /* For Vista through 10, 'flags' is at offset 0x40 (x86) / 0x70 (x64) */
-    DWORD            flags;         /* Heap flags */
-    DWORD            force_flags;   /* Forced heap flags for debugging */
+{                                  /* win32/win64 */
+    DWORD_PTR        unknown1[2];   /* 0000/0000 */
+    DWORD            ffeeffee;      /* 0008/0010 */
+    DWORD            auto_flags;    /* 000c/0014 */
+    DWORD_PTR        unknown2[7];   /* 0010/0018 */
+    DWORD            unknown3[2];   /* 002c/0050 */
+    DWORD_PTR        unknown4[3];   /* 0034/0058 */
+    DWORD            flags;         /* 0040/0070 */
+    DWORD            force_flags;   /* 0044/0074 */
+    /* end of the Windows 10 compatible struct layout */
+
     BOOL             shared;        /* System shared heap */
     SUBHEAP          subheap;       /* First sub-heap */
     struct list      entry;         /* Entry in process heap list */
@@ -173,6 +173,7 @@ typedef struct tagHEAP
 #define MAX_FREE_PENDING     1024    /* max number of free requests to delay */
 
 /* some undocumented flags (names are made up) */
+#define HEAP_PRIVATE          0x00001000
 #define HEAP_PAGE_ALLOCS      0x01000000
 #define HEAP_VALIDATE         0x10000000
 #define HEAP_VALIDATE_ALL     0x20000000
@@ -922,7 +923,9 @@ static SUBHEAP *HEAP_CreateSubHeap( HEAP *heap, LPVOID address, DWORD flags,
         /* If this is a primary subheap, initialize main heap */
 
         heap = address;
-        heap->flags         = flags;
+        heap->ffeeffee      = 0xffeeffee;
+        heap->auto_flags    = (flags & HEAP_GROWABLE);
+        heap->flags         = (flags & ~HEAP_SHARED);
         heap->shared        = (flags & HEAP_SHARED) != 0;
         heap->magic         = HEAP_MAGIC;
         heap->grow_size     = max( HEAP_DEF_SIZE, totalSize );
@@ -1438,6 +1441,25 @@ static BOOL validate_block_pointer( HEAP *heap, SUBHEAP **ret_subheap, const ARE
     return ret;
 }
 
+static DWORD heap_flags_from_global_flag( DWORD flag )
+{
+    DWORD ret = 0;
+
+    if (flag & FLG_HEAP_ENABLE_TAIL_CHECK)
+        ret |= HEAP_TAIL_CHECKING_ENABLED;
+    if (flag & FLG_HEAP_ENABLE_FREE_CHECK)
+        ret |= HEAP_FREE_CHECKING_ENABLED;
+    if (flag & FLG_HEAP_VALIDATE_PARAMETERS)
+        ret |= HEAP_VALIDATE_PARAMS | HEAP_TAIL_CHECKING_ENABLED | HEAP_FREE_CHECKING_ENABLED;
+    if (flag & FLG_HEAP_VALIDATE_ALL)
+        ret |= HEAP_VALIDATE_ALL | HEAP_TAIL_CHECKING_ENABLED | HEAP_FREE_CHECKING_ENABLED;
+    if (flag & FLG_HEAP_DISABLE_COALESCING)
+        ret |= HEAP_DISABLE_COALESCE_ON_FREE;
+    if (flag & FLG_HEAP_PAGE_ALLOCS)
+        ret |= HEAP_PAGE_ALLOCS;
+
+    return ret;
+}
 
 /***********************************************************************
  *           heap_set_debug_flags
@@ -1446,27 +1468,21 @@ static void heap_set_debug_flags( HANDLE handle )
 {
     HEAP *heap = HEAP_GetPtr( handle );
     ULONG global_flags = RtlGetNtGlobalFlags();
-    ULONG flags = 0;
+    DWORD flags, force_flags;
 
     if (TRACE_ON(heap)) global_flags |= FLG_HEAP_VALIDATE_ALL;
     if (WARN_ON(heap)) global_flags |= FLG_HEAP_VALIDATE_PARAMETERS;
 
-    if (global_flags & FLG_HEAP_ENABLE_TAIL_CHECK) flags |= HEAP_TAIL_CHECKING_ENABLED;
-    if (global_flags & FLG_HEAP_ENABLE_FREE_CHECK) flags |= HEAP_FREE_CHECKING_ENABLED;
-    if (global_flags & FLG_HEAP_DISABLE_COALESCING) flags |= HEAP_DISABLE_COALESCE_ON_FREE;
-    if (global_flags & FLG_HEAP_PAGE_ALLOCS) flags |= HEAP_PAGE_ALLOCS | HEAP_GROWABLE;
+    flags = heap_flags_from_global_flag( global_flags );
+    force_flags = (heap->flags | flags) & ~(HEAP_SHARED|HEAP_DISABLE_COALESCE_ON_FREE);
 
-    if (global_flags & FLG_HEAP_VALIDATE_PARAMETERS)
-        flags |= HEAP_VALIDATE | HEAP_VALIDATE_PARAMS |
-                 HEAP_TAIL_CHECKING_ENABLED | HEAP_FREE_CHECKING_ENABLED;
-    if (global_flags & FLG_HEAP_VALIDATE_ALL)
-        flags |= HEAP_VALIDATE | HEAP_VALIDATE_ALL |
-                 HEAP_TAIL_CHECKING_ENABLED | HEAP_FREE_CHECKING_ENABLED;
+    if (global_flags & FLG_HEAP_ENABLE_TAGGING) flags |= HEAP_SHARED;
+    if (!(global_flags & FLG_HEAP_PAGE_ALLOCS)) force_flags &= ~(HEAP_GROWABLE|HEAP_PRIVATE);
 
     if (RUNNING_ON_VALGRIND) flags = 0; /* no sense in validating since Valgrind catches accesses */
 
     heap->flags |= flags;
-    heap->force_flags |= flags & ~(HEAP_VALIDATE | HEAP_DISABLE_COALESCE_ON_FREE);
+    heap->force_flags |= force_flags;
 
     if (flags & (HEAP_FREE_CHECKING_ENABLED | HEAP_TAIL_CHECKING_ENABLED))  /* fix existing blocks */
     {
@@ -1541,11 +1557,9 @@ HANDLE WINAPI RtlCreateHeap( ULONG flags, PVOID addr, SIZE_T totalSize, SIZE_T c
 
     /* Allocate the heap block */
 
-    if (!totalSize)
-    {
-        totalSize = HEAP_DEF_SIZE;
-        flags |= HEAP_GROWABLE;
-    }
+    if (processHeap) flags |= HEAP_PRIVATE;
+    if (!processHeap || !totalSize || (flags & HEAP_SHARED)) flags |= HEAP_GROWABLE;
+    if (!totalSize) totalSize = HEAP_DEF_SIZE;
 
     if (!(subheap = HEAP_CreateSubHeap( NULL, addr, flags, commitSize, totalSize ))) return 0;
 




More information about the wine-cvs mailing list