From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53741 --- dlls/kernel32/tests/heap.c | 9 --------- dlls/ntdll/heap.c | 12 +++++++++--- 2 files changed, 9 insertions(+), 12 deletions(-)
diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c index 51a36f12030..4afc4a9f3dc 100644 --- a/dlls/kernel32/tests/heap.c +++ b/dlls/kernel32/tests/heap.c @@ -1409,7 +1409,6 @@ static void test_GlobalAlloc(void) ret = pRtlGetUserInfoHeap( GetProcessHeap(), 0, entry->ptr, (void **)&tmp_mem, &tmp_flags ); ok( ret, "RtlGetUserInfoHeap failed, error %lu\n", GetLastError() ); ok( tmp_mem == mem, "got user ptr %p\n", tmp_mem ); - todo_wine ok( tmp_flags == 0x200, "got user flags %#lx\n", tmp_flags );
ret = pRtlSetUserValueHeap( GetProcessHeap(), 0, entry->ptr, invalid_mem ); @@ -1786,15 +1785,12 @@ static void test_GlobalAlloc(void) ok( !!ptr, "HeapAlloc failed, error %lu\n", GetLastError() ); SetLastError( 0xdeadbeef ); tmp_mem = GlobalHandle( ptr ); - todo_wine_if( sizeof(void *) == 8 ) ok( !!tmp_mem, "GlobalHandle failed, error %lu\n", GetLastError() ); - todo_wine ok( tmp_mem == ptr, "GlobalHandle returned unexpected handle\n" ); tmp_ptr = (void *)0xdeadbeef; tmp_flags = 0xdeadbeef; ret = pRtlGetUserInfoHeap( GetProcessHeap(), 0, ptr, (void **)&tmp_ptr, &tmp_flags ); ok( ret, "RtlGetUserInfoHeap failed, error %lu\n", GetLastError() ); - todo_wine ok( tmp_ptr == (void *)0xdeadbeef, "got user value %p\n", tmp_ptr ); ok( tmp_flags == 0, "got user flags %#lx\n", tmp_flags ); ret = HeapFree( GetProcessHeap(), 0, ptr ); @@ -2137,15 +2133,12 @@ static void test_LocalAlloc(void) ok( !!ptr, "HeapAlloc failed, error %lu\n", GetLastError() ); SetLastError( 0xdeadbeef ); tmp_mem = LocalHandle( ptr ); - todo_wine_if( sizeof(void *) == 8 ) ok( !!tmp_mem, "LocalHandle failed, error %lu\n", GetLastError() ); - todo_wine ok( tmp_mem == ptr, "LocalHandle returned unexpected handle\n" ); tmp_ptr = (void *)0xdeadbeef; tmp_flags = 0xdeadbeef; ret = pRtlGetUserInfoHeap( GetProcessHeap(), 0, ptr, (void **)&tmp_ptr, &tmp_flags ); ok( ret, "RtlGetUserInfoHeap failed, error %lu\n", GetLastError() ); - todo_wine ok( tmp_ptr == (void *)0xdeadbeef, "got user value %p\n", tmp_ptr ); ok( tmp_flags == 0, "got user flags %#lx\n", tmp_flags ); ret = HeapFree( GetProcessHeap(), 0, ptr ); @@ -2312,7 +2305,6 @@ static void test_block_layout( HANDLE heap, DWORD global_flags, DWORD heap_flags ret = pRtlGetUserInfoHeap( heap, 0, ptr0, (void **)&tmp_ptr, &tmp_flags ); ok( ret, "RtlGetUserInfoHeap failed, error %lu\n", GetLastError() ); ok( tmp_ptr == NULL, "got ptr %p\n", tmp_ptr ); - todo_wine ok( tmp_flags == 0xc00, "got flags %#lx\n", tmp_flags );
tmp_ptr = (void *)0xdeadbeef; @@ -2320,7 +2312,6 @@ static void test_block_layout( HANDLE heap, DWORD global_flags, DWORD heap_flags ret = pRtlGetUserInfoHeap( heap, 0, ptr1, (void **)&tmp_ptr, &tmp_flags ); ok( ret, "RtlGetUserInfoHeap failed, error %lu\n", GetLastError() ); ok( tmp_ptr == NULL, "got ptr %p\n", tmp_ptr ); - todo_wine ok( tmp_flags == 0x200, "got flags %#lx\n", tmp_flags );
ret = pRtlSetUserValueHeap( heap, 0, ptr0, (void *)0xdeadbeef ); diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c index e0af0e72925..617f3705dcd 100644 --- a/dlls/ntdll/heap.c +++ b/dlls/ntdll/heap.c @@ -96,6 +96,7 @@ C_ASSERT( sizeof(struct block) == 8 ); #define BLOCK_FLAG_USER_MASK 0x000000f0
#define BLOCK_USER_FLAGS( heap_flags ) (((heap_flags) >> 4) & BLOCK_FLAG_USER_MASK) +#define HEAP_USER_FLAGS( block_flags ) (((block_flags) & BLOCK_FLAG_USER_MASK) << 4)
/* entry to link free blocks in free lists */
@@ -2016,21 +2017,26 @@ BOOLEAN WINAPI RtlGetUserInfoHeap( HANDLE handle, ULONG flags, void *ptr, void * TRACE( "handle %p, flags %#x, ptr %p, user_value %p, user_flags %p semi-stub!\n", handle, flags, ptr, user_value, user_flags );
- *user_value = 0; *user_flags = 0;
if (!(heap = unsafe_heap_from_handle( handle ))) return TRUE;
heap_lock( heap, flags ); - if ((block = unsafe_block_from_ptr( heap, ptr, &subheap )) && !subheap) + if (!(block = unsafe_block_from_ptr( heap, ptr, &subheap ))) + WARN( "Failed to find block %p in heap %p\n", ptr, handle ); + else if (!(*user_flags = HEAP_USER_FLAGS(block_get_flags( block )))) + WARN( "Block %p wasn't allocated with user info\n", ptr ); + else if (!subheap) { const ARENA_LARGE *large = CONTAINING_RECORD( block, ARENA_LARGE, block ); + *user_flags = *user_flags & ~HEAP_ADD_USER_INFO; *user_value = large->user_value; } - else if (block) + else { tmp = (char *)block + block_get_size( block ) - block->tail_size + sizeof(void *); if ((heap_get_flags( heap, flags ) & HEAP_TAIL_CHECKING_ENABLED) || RUNNING_ON_VALGRIND) tmp += ALIGNMENT; + *user_flags = *user_flags & ~HEAP_ADD_USER_INFO; *user_value = *(void **)tmp; } heap_unlock( heap, flags );