Commit bba4fa0f authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

ntdll: Check block user flags in RtlGetUserInfoHeap.

parent 0f6e9084
......@@ -1411,7 +1411,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 );
......@@ -1568,7 +1567,6 @@ static void test_GlobalAlloc(void)
SetLastError( 0xdeadbeef );
tmp_mem = GlobalHandle( mem );
ok( !tmp_mem, "GlobalHandle succeeded\n" );
todo_wine
ok( GetLastError() == ERROR_INVALID_HANDLE, "got error %lu\n", GetLastError() );
}
......@@ -1603,13 +1601,10 @@ static void test_GlobalAlloc(void)
SetLastError( 0xdeadbeef );
tmp_mem = GlobalHandle( invalid_mem );
ok( !tmp_mem, "GlobalHandle succeeded\n" );
todo_wine
ok( GetLastError() == ERROR_INVALID_HANDLE, "got error %lu\n", GetLastError() );
SetLastError( 0xdeadbeef );
ret = pRtlGetUserInfoHeap( GetProcessHeap(), 0, invalid_mem, (void **)&tmp_ptr, &tmp_flags );
todo_wine
ok( !ret, "RtlGetUserInfoHeap failed, error %lu\n", GetLastError() );
todo_wine
ok( GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError() );
}
......@@ -1647,7 +1642,6 @@ static void test_GlobalAlloc(void)
SetLastError( 0xdeadbeef );
tmp_mem = GlobalHandle( invalid_ptr );
ok( !tmp_mem, "GlobalHandle succeeded\n" );
todo_wine
ok( GetLastError() == ERROR_INVALID_HANDLE, "got error %lu\n", GetLastError() );
if (0) /* crashes */
{
......@@ -1819,13 +1813,11 @@ static void test_GlobalAlloc(void)
SetLastError( 0xdeadbeef );
tmp_mem = GlobalHandle( ptr );
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 );
......@@ -1971,7 +1963,6 @@ static void test_LocalAlloc(void)
SetLastError( 0xdeadbeef );
tmp_mem = LocalHandle( mem );
ok( !tmp_mem, "LocalHandle succeeded\n" );
todo_wine
ok( GetLastError() == ERROR_INVALID_HANDLE, "got error %lu\n", GetLastError() );
}
......@@ -2005,7 +1996,6 @@ static void test_LocalAlloc(void)
SetLastError( 0xdeadbeef );
tmp_mem = LocalHandle( invalid_mem );
ok( !tmp_mem, "LocalHandle succeeded\n" );
todo_wine
ok( GetLastError() == ERROR_INVALID_HANDLE, "got error %lu\n", GetLastError() );
}
......@@ -2186,13 +2176,11 @@ static void test_LocalAlloc(void)
SetLastError( 0xdeadbeef );
tmp_mem = LocalHandle( ptr );
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 );
......@@ -2359,7 +2347,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;
......@@ -2367,7 +2354,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 );
......
......@@ -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 */
......@@ -2008,6 +2009,7 @@ NTSTATUS WINAPI RtlSetHeapInformation( HANDLE handle, HEAP_INFORMATION_CLASS inf
*/
BOOLEAN WINAPI RtlGetUserInfoHeap( HANDLE handle, ULONG flags, void *ptr, void **user_value, ULONG *user_flags )
{
NTSTATUS status = STATUS_SUCCESS;
struct block *block;
struct heap *heap;
SUBHEAP *subheap;
......@@ -2016,26 +2018,36 @@ 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 );
status = STATUS_INVALID_PARAMETER;
*user_value = 0;
}
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 );
return TRUE;
heap_set_status( heap, flags, status );
return !status;
}
/***********************************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment