Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- 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;