Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/kernel32/tests/heap.c | 161 +++++++++++++++++++++++++++++++++++-- 1 file changed, 154 insertions(+), 7 deletions(-)
diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c index 9921eaaf090..07d4409a5cd 100644 --- a/dlls/kernel32/tests/heap.c +++ b/dlls/kernel32/tests/heap.c @@ -240,6 +240,17 @@ static void test_HeapCreate(void) }
+struct mem_entry +{ + UINT_PTR flags; + void *ptr; +}; + +static struct mem_entry *mem_entry_from_HANDLE( HLOCAL handle ) +{ + return CONTAINING_RECORD( handle, struct mem_entry, ptr ); +} + static void test_GlobalAlloc(void) { static const UINT flags_tests[] = @@ -257,11 +268,12 @@ static void test_GlobalAlloc(void) static const SIZE_T buffer_size = ARRAY_SIZE(zero_buffer); const HGLOBAL invalid_mem = LongToHandle( 0xdeadbee0 + sizeof(void *) ); void *const invalid_ptr = LongToHandle( 0xdeadbee0 ); + struct mem_entry *entry; HGLOBAL globals[0x10000]; + SIZE_T size, alloc_size; HGLOBAL mem, tmp_mem; BYTE *ptr, *tmp_ptr; UINT i, flags; - SIZE_T size; BOOL ret;
mem = GlobalFree( 0 ); @@ -319,6 +331,135 @@ static void test_GlobalAlloc(void) size = GlobalSize( mem ); ok( size == 0, "GlobalSize returned %Iu\n", size );
+ mem = GlobalAlloc( GMEM_MOVEABLE | GMEM_DISCARDABLE, 0 ); + ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); + entry = mem_entry_from_HANDLE( mem ); + size = GlobalSize( mem ); + ok( size == 0, "GlobalSize returned %Iu\n", size ); + ret = HeapValidate( GetProcessHeap(), 0, entry ); + ok( !ret, "HeapValidate succeeded\n" ); + todo_wine + ok( entry->flags == 0xf, "got unexpected flags %#Ix\n", entry->flags ); + ok( !entry->ptr, "got unexpected ptr %p\n", entry->ptr ); + mem = GlobalFree( mem ); + ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() ); + + mem = GlobalAlloc( GMEM_MOVEABLE, 0 ); + ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); + entry = mem_entry_from_HANDLE( mem ); + size = GlobalSize( mem ); + ok( size == 0, "GlobalSize returned %Iu\n", size ); + ret = HeapValidate( GetProcessHeap(), 0, entry ); + ok( !ret, "HeapValidate succeeded\n" ); + todo_wine + ok( entry->flags == 0xb, "got unexpected flags %#Ix\n", entry->flags ); + ok( !entry->ptr, "got unexpected ptr %p\n", entry->ptr ); + mem = GlobalFree( mem ); + ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() ); + + for (alloc_size = 1; alloc_size < 0x10000000; alloc_size <<= 1) + { + winetest_push_context( "size %#Ix", alloc_size ); + + mem = GlobalAlloc( GMEM_FIXED, alloc_size ); + ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); + ok( !((UINT_PTR)mem & sizeof(void *)), "got unexpected ptr align\n" ); + ok( !((UINT_PTR)mem & (sizeof(void *) - 1)), "got unexpected ptr align\n" ); + ret = HeapValidate( GetProcessHeap(), 0, mem ); + ok( ret, "HeapValidate failed, error %lu\n", GetLastError() ); + tmp_mem = GlobalFree( mem ); + ok( !tmp_mem, "GlobalFree failed, error %lu\n", GetLastError() ); + + mem = GlobalAlloc( GMEM_MOVEABLE, alloc_size ); + ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); + todo_wine + ok( ((UINT_PTR)mem & sizeof(void *)), "got unexpected entry align\n" ); + todo_wine + ok( !((UINT_PTR)mem & (sizeof(void *) - 1)), "got unexpected entry align\n" ); + + entry = mem_entry_from_HANDLE( mem ); + ret = HeapValidate( GetProcessHeap(), 0, entry ); + ok( !ret, "HeapValidate succeeded\n" ); + ret = HeapValidate( GetProcessHeap(), 0, entry->ptr ); + todo_wine + ok( ret, "HeapValidate failed, error %lu\n", GetLastError() ); + size = HeapSize( GetProcessHeap(), 0, entry->ptr ); + todo_wine + ok( size == alloc_size, "HeapSize returned %Iu\n", size ); + + ptr = GlobalLock( mem ); + ok( !!ptr, "GlobalLock failed, error %lu\n", GetLastError() ); + ok( ptr != mem, "got unexpected ptr %p\n", ptr ); + ok( ptr == entry->ptr, "got unexpected ptr %p\n", ptr ); + ok( !((UINT_PTR)ptr & sizeof(void *)), "got unexpected ptr align\n" ); + ok( !((UINT_PTR)ptr & (sizeof(void *) - 1)), "got unexpected ptr align\n" ); + for (i = 1; i < 0xff; ++i) + { + todo_wine + ok( entry->flags == ((i<<16)|3), "got unexpected flags %#Ix\n", entry->flags ); + ptr = GlobalLock( mem ); + ok( !!ptr, "GlobalLock failed, error %lu\n", GetLastError() ); + } + ptr = GlobalLock( mem ); + ok( !!ptr, "GlobalLock failed, error %lu\n", GetLastError() ); + todo_wine + ok( entry->flags == 0xff0003, "got unexpected flags %#Ix\n", entry->flags ); + for (i = 1; i < 0xff; ++i) + { + ret = GlobalUnlock( mem ); + ok( ret, "GlobalUnlock failed, error %lu\n", GetLastError() ); + } + ret = GlobalUnlock( mem ); + ok( !ret, "GlobalUnlock succeeded, error %lu\n", GetLastError() ); + todo_wine + ok( entry->flags == 0x3, "got unexpected flags %#Ix\n", entry->flags ); + + tmp_mem = GlobalFree( mem ); + ok( !tmp_mem, "GlobalFree failed, error %lu\n", GetLastError() ); + ok( !!entry->flags, "got unexpected flags %#Ix\n", entry->flags ); + todo_wine_if(sizeof(void *) == 4) + ok( !((UINT_PTR)entry->flags & sizeof(void *)), "got unexpected ptr align\n" ); + todo_wine_if(sizeof(void *) == 4) + ok( !((UINT_PTR)entry->flags & (sizeof(void *) - 1)), "got unexpected ptr align\n" ); + todo_wine + ok( !entry->ptr, "got unexpected ptr %p\n", entry->ptr ); + + mem = GlobalAlloc( GMEM_MOVEABLE | GMEM_DISCARDABLE, 0 ); + ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); + entry = mem_entry_from_HANDLE( mem ); + todo_wine + ok( entry->flags == 0xf, "got unexpected flags %#Ix\n", entry->flags ); + ok( !entry->ptr, "got unexpected ptr %p\n", entry->ptr ); + flags = GlobalFlags( mem ); + ok( flags == (GMEM_DISCARDED | GMEM_DISCARDABLE), "GlobalFlags returned %#x, error %lu\n", flags, GetLastError() ); + mem = GlobalFree( mem ); + ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() ); + + mem = GlobalAlloc( GMEM_MOVEABLE | GMEM_DISCARDABLE, 1 ); + ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); + entry = mem_entry_from_HANDLE( mem ); + todo_wine + ok( entry->flags == 0x7, "got unexpected flags %#Ix\n", entry->flags ); + ok( !!entry->ptr, "got unexpected ptr %p\n", entry->ptr ); + flags = GlobalFlags( mem ); + ok( flags == GMEM_DISCARDABLE, "GlobalFlags returned %#x, error %lu\n", flags, GetLastError() ); + mem = GlobalFree( mem ); + ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() ); + + mem = GlobalAlloc( GMEM_MOVEABLE | GMEM_DISCARDABLE | GMEM_DDESHARE, 1 ); + ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); + entry = mem_entry_from_HANDLE( mem ); + todo_wine + ok( entry->flags == 0x8007, "got unexpected flags %#Ix\n", entry->flags ); + ok( !!entry->ptr, "got unexpected ptr %p\n", entry->ptr ); + flags = GlobalFlags( mem ); + ok( flags == (GMEM_DISCARDABLE | GMEM_DDESHARE), "GlobalFlags returned %#x, error %lu\n", flags, GetLastError() ); + mem = GlobalFree( mem ); + ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() ); + + winetest_pop_context(); + } + mem = GlobalAlloc( GMEM_MOVEABLE, 256 ); ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); ptr = GlobalLock( mem ); @@ -477,9 +618,11 @@ static void test_GlobalAlloc(void) SetLastError( 0xdeadbeef ); tmp_mem = GlobalReAlloc( mem, 10, 0 ); todo_wine - ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); + ok( !tmp_mem || broken( tmp_mem == mem ) /* w1064v1507 / w1064v1607 */, + "GlobalReAlloc succeeded\n" ); todo_wine - ok( GetLastError() == ERROR_NOT_ENOUGH_MEMORY, "got error %lu\n", GetLastError() ); + ok( GetLastError() == ERROR_NOT_ENOUGH_MEMORY || broken( GetLastError() == 0xdeadbeef ) /* w1064v1507 / w1064v1607 */, + "got error %lu\n", GetLastError() ); if (tmp_mem) mem = tmp_mem; tmp_mem = GlobalReAlloc( mem, 1024 * 1024, GMEM_MODIFY ); todo_wine @@ -497,7 +640,8 @@ static void test_GlobalAlloc(void) tmp_mem = GlobalReAlloc( mem, 11, GMEM_MOVEABLE ); ok( !!tmp_mem, "GlobalReAlloc failed, error %lu\n", GetLastError() ); todo_wine - ok( tmp_mem != mem, "GlobalReAlloc didn't relocate memory\n" ); + ok( tmp_mem != mem || broken( tmp_mem == mem ) /* w1064v1507 / w1064v1607 */, + "GlobalReAlloc didn't relocate memory\n" ); ptr = GlobalLock( tmp_mem ); ok( !!ptr, "GlobalLock failed, error %lu\n", GetLastError() ); ok( ptr == tmp_mem, "got ptr %p, expected %p\n", ptr, tmp_mem ); @@ -821,9 +965,11 @@ static void test_LocalAlloc(void) SetLastError( 0xdeadbeef ); tmp_mem = LocalReAlloc( mem, 10, 0 ); todo_wine - ok( !tmp_mem, "LocalReAlloc succeeded\n" ); + ok( !tmp_mem || broken( tmp_mem == mem ) /* w1064v1507 / w1064v1607 */, + "LocalReAlloc succeeded\n" ); todo_wine - ok( GetLastError() == ERROR_NOT_ENOUGH_MEMORY, "got error %lu\n", GetLastError() ); + ok( GetLastError() == ERROR_NOT_ENOUGH_MEMORY || broken( GetLastError() == 0xdeadbeef ) /* w1064v1507 / w1064v1607 */, + "got error %lu\n", GetLastError() ); if (tmp_mem) mem = tmp_mem; tmp_mem = LocalReAlloc( mem, 1024 * 1024, LMEM_MODIFY ); todo_wine @@ -841,7 +987,8 @@ static void test_LocalAlloc(void) tmp_mem = LocalReAlloc( mem, 11, LMEM_MOVEABLE ); ok( !!tmp_mem, "LocalReAlloc failed, error %lu\n", GetLastError() ); todo_wine - ok( tmp_mem != mem, "LocalReAlloc didn't relocate memory\n" ); + ok( tmp_mem != mem || broken( tmp_mem == mem ) /* w1064v1507 / w1064v1607 */, + "LocalReAlloc didn't relocate memory\n" ); ptr = LocalLock( tmp_mem ); ok( !!ptr, "LocalLock failed, error %lu\n", GetLastError() ); ok( ptr == tmp_mem, "got ptr %p, expected %p\n", ptr, tmp_mem );