From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/kernel32/tests/heap.c | 2 -- dlls/ntdll/heap.c | 29 +++++++++++++++++++++++++---- 2 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c index 4221fd39c0f..339921b83c3 100644 --- a/dlls/kernel32/tests/heap.c +++ b/dlls/kernel32/tests/heap.c @@ -2320,7 +2320,6 @@ static void test_block_layout( HANDLE heap, DWORD global_flags, DWORD heap_flags tmp_flags = 0; ret = pRtlGetUserInfoHeap( heap, 0, ptr0, (void **)&tmp_ptr, &tmp_flags ); ok( ret, "RtlGetUserInfoHeap failed, error %lu\n", GetLastError() ); - todo_wine ok( tmp_ptr == (void *)0xdeadbeef, "got ptr %p\n", tmp_ptr ); todo_wine ok( tmp_flags == 0xa00 || broken(tmp_flags == 0xc00) /* w1064v1507 */, @@ -2335,7 +2334,6 @@ static void test_block_layout( HANDLE heap, DWORD global_flags, DWORD heap_flags tmp_flags = 0; ret = pRtlGetUserInfoHeap( heap, 0, ptr0, (void **)&tmp_ptr, &tmp_flags ); ok( ret, "RtlGetUserInfoHeap failed, error %lu\n", GetLastError() ); - todo_wine ok( tmp_ptr == (void *)0xdeadbee0, "got ptr %p\n", tmp_ptr ); todo_wine ok( tmp_flags == 0xa00 || broken(tmp_flags == 0xc00) /* w1064v1507 */, diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c index 64d4f6644af..8ebd561dd1c 100644 --- a/dlls/ntdll/heap.c +++ b/dlls/ntdll/heap.c @@ -1996,12 +1996,33 @@ NTSTATUS WINAPI RtlSetHeapInformation( HANDLE heap, HEAP_INFORMATION_CLASS info_ /*********************************************************************** * RtlGetUserInfoHeap (NTDLL.@) */ -BOOLEAN WINAPI RtlGetUserInfoHeap( HANDLE heap, ULONG flags, void *ptr, void **user_value, ULONG *user_flags ) +BOOLEAN WINAPI RtlGetUserInfoHeap( HANDLE handle, ULONG flags, void *ptr, void **user_value, ULONG *user_flags ) { - FIXME( "heap %p, flags %#x, ptr %p, user_value %p, user_flags %p semi-stub!\n", - heap, flags, ptr, user_value, user_flags ); - *user_value = NULL; + ARENA_LARGE *large = (ARENA_LARGE *)ptr - 1; + struct block *block; + SUBHEAP *subheap; + HEAP *heap; + char *tmp; + + 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 = HEAP_GetPtr( handle ))) return TRUE; + + heap_lock( heap, flags ); + if ((block = unsafe_block_from_ptr( heap, ptr, &subheap )) && !subheap) + *user_value = large->user_value; + else if (block) + { + 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_value = *(void **)tmp; + } + heap_unlock( heap, flags ); + return TRUE; }