The LFH being automatically enabled after several allocations of the same sizes are done, its reallocation strategy differs from non-LFH blocks and was messing with the tests. I previously removed the HEAP_REALLOC_IN_PLACE_ONLY flag from LocalReAlloc, based on the test results, but the outcome is different when a non-LFH block size is used.
This adds more tests and restores the flag to fix the regression.
From: Rémi Bernon rbernon@codeweavers.com
Making the GlobalReAlloc tests more sensible, as they fail to reallocate when the block was allocated with the LFH and the new size wouldn't.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54012 --- dlls/kernel32/tests/heap.c | 286 +++++++++++++++++-------------------- 1 file changed, 131 insertions(+), 155 deletions(-)
diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c index 3350f0853ab..0ac209577af 100644 --- a/dlls/kernel32/tests/heap.c +++ b/dlls/kernel32/tests/heap.c @@ -1296,11 +1296,11 @@ 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 ); + SIZE_T size, alloc_size, small_size = 0x20; HANDLE heap = GetProcessHeap(); PROCESS_HEAP_ENTRY walk_entry; struct mem_entry *entry; HGLOBAL globals[0x10000]; - SIZE_T size, alloc_size; HGLOBAL mem, tmp_mem; BYTE *ptr, *tmp_ptr; ULONG tmp_flags; @@ -1352,6 +1352,10 @@ static void test_GlobalAlloc(void) ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() ); }
+ /* make sure LFH is enabled for some small block size */ + for (i = 0; i < 0x12; i++) globals[i] = pGlobalAlloc( GMEM_FIXED, small_size ); + for (i = 0; i < 0x12; i++) pGlobalFree( globals[i] ); + mem = GlobalAlloc( GMEM_MOVEABLE, 0 ); ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); mem = GlobalReAlloc( mem, 10, GMEM_MOVEABLE ); @@ -1666,36 +1670,33 @@ static void test_GlobalAlloc(void) }
/* GMEM_FIXED block doesn't allow resize, though it succeeds with GMEM_MODIFY */ - mem = GlobalAlloc( GMEM_FIXED, 10 ); + mem = GlobalAlloc( GMEM_FIXED, small_size ); ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); - tmp_mem = GlobalReAlloc( mem, 9, GMEM_MODIFY ); + tmp_mem = GlobalReAlloc( mem, small_size - 1, GMEM_MODIFY ); ok( !!tmp_mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); ok( tmp_mem == mem, "got ptr %p, expected %p\n", tmp_mem, mem ); size = GlobalSize( mem ); - ok( size == 10, "GlobalSize returned %Iu\n", size ); + ok( size == small_size, "GlobalSize returned %Iu\n", size ); SetLastError( 0xdeadbeef ); - tmp_mem = GlobalReAlloc( mem, 10, 0 ); - ok( !tmp_mem || broken( tmp_mem == mem ) /* w1064v1507 / w1064v1607 */, - "GlobalReAlloc succeeded\n" ); - ok( GetLastError() == ERROR_NOT_ENOUGH_MEMORY || broken( GetLastError() == 0xdeadbeef ) /* w1064v1507 / w1064v1607 */, - "got error %lu\n", GetLastError() ); + tmp_mem = GlobalReAlloc( mem, small_size, 0 ); + ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); + ok( GetLastError() == ERROR_NOT_ENOUGH_MEMORY, "got error %lu\n", GetLastError() ); if (tmp_mem) mem = tmp_mem; tmp_mem = GlobalReAlloc( mem, 1024 * 1024, GMEM_MODIFY ); ok( !!tmp_mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); ok( tmp_mem == mem, "got ptr %p, expected %p\n", tmp_mem, mem ); size = GlobalSize( mem ); - ok( size == 10, "GlobalSize returned %Iu\n", size ); + ok( size == small_size, "GlobalSize returned %Iu\n", size ); mem = GlobalFree( mem ); ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() );
/* GMEM_FIXED block can be relocated with GMEM_MOVEABLE */ - mem = GlobalAlloc( GMEM_FIXED, 10 ); + mem = GlobalAlloc( GMEM_FIXED, small_size ); ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); - tmp_mem = GlobalReAlloc( mem, 11, GMEM_MOVEABLE ); + tmp_mem = GlobalReAlloc( mem, small_size + 1, GMEM_MOVEABLE ); ok( !!tmp_mem, "GlobalReAlloc failed, error %lu\n", GetLastError() ); todo_wine - ok( tmp_mem != mem || broken( tmp_mem == mem ) /* w1064v1507 / w1064v1607 */, - "GlobalReAlloc didn't relocate memory\n" ); + ok( tmp_mem != mem, "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 ); @@ -1714,7 +1715,7 @@ static void test_GlobalAlloc(void)
winetest_push_context( "flags %#x", flags );
- mem = pGlobalAlloc( GMEM_FIXED, 10 ); + mem = pGlobalAlloc( GMEM_FIXED, small_size ); ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); ok( !is_mem_entry( mem ), "unexpected moveable %p\n", mem );
@@ -1738,13 +1739,13 @@ static void test_GlobalAlloc(void)
size = GlobalSize( mem ); if (flags == GMEM_MOVEABLE) ok( size == 512, "GlobalSize returned %Iu\n", size ); - else ok( size == 10, "GlobalSize returned %Iu\n", size ); + else ok( size == small_size, "GlobalSize returned %Iu\n", size );
mem = GlobalFree( mem ); ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() );
- mem = pGlobalAlloc( GMEM_FIXED, 12 ); + mem = pGlobalAlloc( GMEM_FIXED, small_size ); ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); ok( !is_mem_entry( mem ), "unexpected moveable %p\n", mem );
@@ -1753,7 +1754,7 @@ static void test_GlobalAlloc(void) { ok( !is_mem_entry( tmp_mem ), "unexpected moveable %p\n", tmp_mem ); if (flags == GMEM_MODIFY) ok( tmp_mem == mem, "GlobalReAlloc returned %p\n", tmp_mem ); - else if (flags != GMEM_MOVEABLE) ok( !tmp_mem || broken( tmp_mem == mem ) /* w8 */, "GlobalReAlloc succeeded\n" ); + else if (flags != GMEM_MOVEABLE) ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); else todo_wine ok( tmp_mem != mem, "GlobalReAlloc returned %p\n", tmp_mem ); } else @@ -1768,14 +1769,13 @@ static void test_GlobalAlloc(void)
size = GlobalSize( mem ); if (flags == GMEM_MOVEABLE) ok( size == 10, "GlobalSize returned %Iu\n", size ); - else if (flags) ok( size == 12, "GlobalSize returned %Iu\n", size ); - else ok( size == 12 || broken( size == 10 ) /* w8 */, "GlobalSize returned %Iu\n", size ); + else ok( size == small_size, "GlobalSize returned %Iu\n", size );
mem = GlobalFree( mem ); ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() );
- mem = pGlobalAlloc( GMEM_FIXED, 12 ); + mem = pGlobalAlloc( GMEM_FIXED, small_size ); ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); ok( !is_mem_entry( mem ), "unexpected moveable %p\n", mem );
@@ -1784,7 +1784,7 @@ static void test_GlobalAlloc(void) { ok( !is_mem_entry( tmp_mem ), "unexpected moveable %p\n", tmp_mem ); if (flags == GMEM_MODIFY) ok( tmp_mem == mem, "GlobalReAlloc returned %p\n", tmp_mem ); - else if (flags != GMEM_MOVEABLE) ok( !tmp_mem || broken( tmp_mem == mem ) /* w8 */, "GlobalReAlloc succeeded\n" ); + else if (flags != GMEM_MOVEABLE) ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); else todo_wine ok( tmp_mem != mem, "GlobalReAlloc returned %p\n", tmp_mem ); } else @@ -1799,14 +1799,13 @@ static void test_GlobalAlloc(void)
size = GlobalSize( mem ); if (flags == GMEM_MOVEABLE) ok( size == 0 || broken( size == 1 ) /* w7 */, "GlobalSize returned %Iu\n", size ); - else if (flags) ok( size == 12, "GlobalSize returned %Iu\n", size ); - else ok( size == 12 || broken( size == 0 ) /* w8 */, "GlobalSize returned %Iu\n", size ); + else ok( size == small_size, "GlobalSize returned %Iu\n", size );
mem = GlobalFree( mem ); ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() );
- mem = pGlobalAlloc( GMEM_MOVEABLE, 10 ); + mem = pGlobalAlloc( GMEM_MOVEABLE, small_size ); ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); ok( is_mem_entry( mem ), "unexpected moveable %p\n", mem ); ptr = GlobalLock( mem ); @@ -1814,22 +1813,19 @@ static void test_GlobalAlloc(void) expect_entry = *mem_entry_from_HANDLE( mem );
tmp_mem = GlobalReAlloc( mem, 512, flags ); - if (!(flags & GMEM_MODIFY) && ((flags & GMEM_DISCARDABLE) || !(flags & GMEM_MOVEABLE))) - ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); - else - ok( tmp_mem == mem, "GlobalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + if (flags & GMEM_MODIFY) ok( tmp_mem == mem, "GlobalReAlloc returned %p\n", tmp_mem ); + else if (flags & GMEM_DISCARDABLE) ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); + else if (flags & GMEM_MOVEABLE) ok( tmp_mem == mem, "GlobalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + else ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); entry = *mem_entry_from_HANDLE( mem ); if ((flags & GMEM_DISCARDABLE) && (flags & GMEM_MODIFY)) expect_entry.flags |= 4; - if (flags == GMEM_MOVEABLE) - ok( entry.ptr != expect_entry.ptr, "got unexpected ptr %p\n", entry.ptr ); - else - ok( entry.ptr == expect_entry.ptr, "got ptr %p\n", entry.ptr ); + if (flags == GMEM_MOVEABLE) ok( entry.ptr != expect_entry.ptr, "got unexpected ptr %p\n", entry.ptr ); + else ok( entry.ptr == expect_entry.ptr, "got ptr %p\n", entry.ptr ); ok( entry.flags == expect_entry.flags, "got flags %#Ix was %#Ix\n", entry.flags, expect_entry.flags ); + size = GlobalSize( mem ); - if (flags == GMEM_MOVEABLE) - ok( size == 512, "GlobalSize returned %Iu\n", size ); - else - ok( size == 10, "GlobalSize returned %Iu\n", size ); + if (flags == GMEM_MOVEABLE) ok( size == 512, "GlobalSize returned %Iu\n", size ); + else ok( size == small_size, "GlobalSize returned %Iu\n", size );
ret = GlobalUnlock( mem ); ok( !ret, "GlobalUnlock succeeded\n" ); @@ -1837,7 +1833,7 @@ static void test_GlobalAlloc(void) ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() );
- mem = pGlobalAlloc( GMEM_MOVEABLE, 12 ); + mem = pGlobalAlloc( GMEM_MOVEABLE, small_size ); ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); ok( is_mem_entry( mem ), "unexpected moveable %p\n", mem ); ptr = GlobalLock( mem ); @@ -1845,19 +1841,17 @@ static void test_GlobalAlloc(void) expect_entry = *mem_entry_from_HANDLE( mem );
tmp_mem = GlobalReAlloc( mem, 10, flags ); - if (!(flags & GMEM_MODIFY) && (flags & GMEM_DISCARDABLE)) - ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); - else - ok( tmp_mem == mem, "GlobalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + if (flags & GMEM_MODIFY) ok( tmp_mem == mem, "GlobalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + else if (flags & GMEM_DISCARDABLE) ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); + else ok( tmp_mem == mem, "GlobalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); entry = *mem_entry_from_HANDLE( mem ); if ((flags & GMEM_DISCARDABLE) && (flags & GMEM_MODIFY)) expect_entry.flags |= 4; ok( entry.ptr == expect_entry.ptr, "got ptr %p was %p\n", entry.ptr, expect_entry.ptr ); ok( entry.flags == expect_entry.flags, "got flags %#Ix was %#Ix\n", entry.flags, expect_entry.flags ); + size = GlobalSize( mem ); - if ((flags & GMEM_DISCARDABLE) || (flags & GMEM_MODIFY)) - ok( size == 12, "GlobalSize returned %Iu\n", size ); - else - ok( size == 10, "GlobalSize returned %Iu\n", size ); + if (flags & (GMEM_DISCARDABLE | GMEM_MODIFY)) ok( size == small_size, "GlobalSize returned %Iu\n", size ); + else ok( size == 10, "GlobalSize returned %Iu\n", size );
ret = GlobalUnlock( mem ); ok( !ret, "GlobalUnlock succeeded\n" ); @@ -1865,7 +1859,7 @@ static void test_GlobalAlloc(void) ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() );
- mem = pGlobalAlloc( GMEM_MOVEABLE, 12 ); + mem = pGlobalAlloc( GMEM_MOVEABLE, small_size ); ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); ok( is_mem_entry( mem ), "unexpected moveable %p\n", mem ); ptr = GlobalLock( mem ); @@ -1873,16 +1867,15 @@ static void test_GlobalAlloc(void) expect_entry = *mem_entry_from_HANDLE( mem );
tmp_mem = GlobalReAlloc( mem, 0, flags ); - if (flags & GMEM_MODIFY) - ok( tmp_mem == mem, "GlobalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); - else - ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); + if (flags & GMEM_MODIFY) ok( tmp_mem == mem, "GlobalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + else ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); entry = *mem_entry_from_HANDLE( mem ); if ((flags & GMEM_DISCARDABLE) && (flags & GMEM_MODIFY)) expect_entry.flags |= 4; ok( entry.ptr == expect_entry.ptr, "got ptr %p was %p\n", entry.ptr, expect_entry.ptr ); ok( entry.flags == expect_entry.flags, "got flags %#Ix was %#Ix\n", entry.flags, expect_entry.flags ); + size = GlobalSize( mem ); - ok( size == 12, "GlobalSize returned %Iu\n", size ); + ok( size == small_size, "GlobalSize returned %Iu\n", size );
ret = GlobalUnlock( mem ); ok( !ret, "GlobalUnlock succeeded\n" ); @@ -1890,69 +1883,61 @@ static void test_GlobalAlloc(void) ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() );
- mem = pGlobalAlloc( GMEM_MOVEABLE, 10 ); + mem = pGlobalAlloc( GMEM_MOVEABLE, small_size ); ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); ok( is_mem_entry( mem ), "unexpected moveable %p\n", mem ); expect_entry = *mem_entry_from_HANDLE( mem );
tmp_mem = GlobalReAlloc( mem, 512, flags ); - if (!(flags & GMEM_MODIFY) && (flags & GMEM_DISCARDABLE)) - ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); - else - ok( tmp_mem == mem, "GlobalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + if (flags & GMEM_MODIFY) ok( tmp_mem == mem, "GlobalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + else if (flags & GMEM_DISCARDABLE) ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); + else ok( tmp_mem == mem, "GlobalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); entry = *mem_entry_from_HANDLE( mem ); if ((flags & GMEM_DISCARDABLE) && (flags & GMEM_MODIFY)) expect_entry.flags |= 4; - if ((flags & GMEM_DISCARDABLE) || (flags & GMEM_MODIFY)) - ok( entry.ptr == expect_entry.ptr, "got ptr %p\n", entry.ptr ); - else - ok( entry.ptr != expect_entry.ptr, "got unexpected ptr %p\n", entry.ptr ); + if (flags & (GMEM_DISCARDABLE | GMEM_MODIFY)) ok( entry.ptr == expect_entry.ptr, "got ptr %p\n", entry.ptr ); + else ok( entry.ptr != expect_entry.ptr, "got unexpected ptr %p\n", entry.ptr ); ok( entry.flags == expect_entry.flags, "got flags %#Ix was %#Ix\n", entry.flags, expect_entry.flags ); + size = GlobalSize( mem ); - if ((flags & GMEM_DISCARDABLE) || (flags & GMEM_MODIFY)) - ok( size == 10, "GlobalSize returned %Iu\n", size ); - else - ok( size == 512, "GlobalSize returned %Iu\n", size ); + if (flags & (GMEM_DISCARDABLE | GMEM_MODIFY)) ok( size == small_size, "GlobalSize returned %Iu\n", size ); + else ok( size == 512, "GlobalSize returned %Iu\n", size );
mem = GlobalFree( mem ); ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() );
- mem = pGlobalAlloc( GMEM_MOVEABLE, 12 ); + mem = pGlobalAlloc( GMEM_MOVEABLE, small_size ); ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); ok( is_mem_entry( mem ), "unexpected moveable %p\n", mem ); expect_entry = *mem_entry_from_HANDLE( mem );
tmp_mem = GlobalReAlloc( mem, 10, flags ); - if (!(flags & GMEM_MODIFY) && (flags & GMEM_DISCARDABLE)) - ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); - else - ok( tmp_mem == mem, "GlobalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + if (flags & GMEM_MODIFY) ok( tmp_mem == mem, "GlobalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + else if (flags & GMEM_DISCARDABLE) ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); + else ok( tmp_mem == mem, "GlobalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); entry = *mem_entry_from_HANDLE( mem ); if ((flags & GMEM_DISCARDABLE) && (flags & GMEM_MODIFY)) expect_entry.flags |= 4; ok( entry.ptr == expect_entry.ptr, "got ptr %p was %p\n", entry.ptr, expect_entry.ptr ); ok( entry.flags == expect_entry.flags, "got flags %#Ix was %#Ix\n", entry.flags, expect_entry.flags ); + size = GlobalSize( mem ); - if ((flags & GMEM_DISCARDABLE) || (flags & GMEM_MODIFY)) - ok( size == 12, "GlobalSize returned %Iu\n", size ); - else - ok( size == 10, "GlobalSize returned %Iu\n", size ); + if (flags & (GMEM_DISCARDABLE | GMEM_MODIFY)) ok( size == small_size, "GlobalSize returned %Iu\n", size ); + else ok( size == 10, "GlobalSize returned %Iu\n", size );
mem = GlobalFree( mem ); ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() );
- mem = pGlobalAlloc( GMEM_MOVEABLE, 12 ); + mem = pGlobalAlloc( GMEM_MOVEABLE, small_size ); ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); ok( is_mem_entry( mem ), "unexpected moveable %p\n", mem ); expect_entry = *mem_entry_from_HANDLE( mem );
tmp_mem = GlobalReAlloc( mem, 0, flags ); - if (flags == GMEM_FIXED) - ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); - else if (!(flags & GMEM_MODIFY) && (flags & GMEM_DISCARDABLE)) - ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); - else - ok( tmp_mem == mem, "GlobalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + if (flags & GMEM_MODIFY) ok( tmp_mem == mem, "GlobalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + else if (flags == GMEM_FIXED) ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); + else if (flags & GMEM_DISCARDABLE) ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); + else ok( tmp_mem == mem, "GlobalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); entry = *mem_entry_from_HANDLE( mem ); if (flags == GMEM_MOVEABLE) { @@ -1962,9 +1947,10 @@ static void test_GlobalAlloc(void) else if ((flags & GMEM_DISCARDABLE) && (flags & GMEM_MODIFY)) expect_entry.flags |= 4; ok( entry.ptr == expect_entry.ptr, "got ptr %p was %p\n", entry.ptr, expect_entry.ptr ); ok( entry.flags == expect_entry.flags, "got flags %#Ix was %#Ix\n", entry.flags, expect_entry.flags ); + size = GlobalSize( mem ); if (flags == GMEM_MOVEABLE) ok( size == 0, "GlobalSize returned %Iu\n", size ); - else ok( size == 12, "GlobalSize returned %Iu\n", size ); + else ok( size == small_size, "GlobalSize returned %Iu\n", size );
mem = GlobalFree( mem ); ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() ); @@ -2133,12 +2119,12 @@ static void test_LocalAlloc(void) static const SIZE_T buffer_size = ARRAY_SIZE(zero_buffer); const HLOCAL invalid_mem = LongToHandle( 0xdeadbee0 + sizeof(void *) ); void *const invalid_ptr = LongToHandle( 0xdeadbee0 ); + SIZE_T size, small_size = 0x20; HLOCAL locals[0x10000]; HLOCAL mem, tmp_mem; BYTE *ptr, *tmp_ptr; ULONG tmp_flags; UINT i, flags; - SIZE_T size; BOOL ret;
mem = LocalFree( 0 ); @@ -2173,6 +2159,10 @@ static void test_LocalAlloc(void) ok( !mem, "LocalFree failed, error %lu\n", GetLastError() ); }
+ /* make sure LFH is enabled for some small block size */ + for (i = 0; i < 0x12; i++) locals[i] = pLocalAlloc( LMEM_FIXED, small_size ); + for (i = 0; i < 0x12; i++) LocalFree( locals[i] ); + mem = LocalAlloc( LMEM_MOVEABLE, 0 ); ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); mem = LocalReAlloc( mem, 10, LMEM_MOVEABLE ); @@ -2329,36 +2319,33 @@ static void test_LocalAlloc(void) ok( GetLastError() == ERROR_NOACCESS, "got error %lu\n", GetLastError() );
/* LMEM_FIXED block doesn't allow resize, though it succeeds with LMEM_MODIFY */ - mem = LocalAlloc( LMEM_FIXED, 10 ); + mem = LocalAlloc( LMEM_FIXED, small_size ); ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); - tmp_mem = LocalReAlloc( mem, 9, LMEM_MODIFY ); + tmp_mem = LocalReAlloc( mem, small_size - 1, LMEM_MODIFY ); ok( !!tmp_mem, "LocalAlloc failed, error %lu\n", GetLastError() ); ok( tmp_mem == mem, "got ptr %p, expected %p\n", tmp_mem, mem ); size = LocalSize( mem ); - ok( size == 10, "LocalSize returned %Iu\n", size ); + ok( size == small_size, "LocalSize returned %Iu\n", size ); SetLastError( 0xdeadbeef ); - tmp_mem = LocalReAlloc( mem, 10, 0 ); - ok( !tmp_mem || broken( tmp_mem == mem ) /* w1064v1507 / w1064v1607 */, - "LocalReAlloc succeeded\n" ); - ok( GetLastError() == ERROR_NOT_ENOUGH_MEMORY || broken( GetLastError() == 0xdeadbeef ) /* w1064v1507 / w1064v1607 */, - "got error %lu\n", GetLastError() ); + tmp_mem = LocalReAlloc( mem, small_size, 0 ); + ok( !tmp_mem, "LocalReAlloc succeeded\n" ); + ok( GetLastError() == ERROR_NOT_ENOUGH_MEMORY, "got error %lu\n", GetLastError() ); if (tmp_mem) mem = tmp_mem; tmp_mem = LocalReAlloc( mem, 1024 * 1024, LMEM_MODIFY ); ok( !!tmp_mem, "LocalAlloc failed, error %lu\n", GetLastError() ); ok( tmp_mem == mem, "got ptr %p, expected %p\n", tmp_mem, mem ); size = LocalSize( mem ); - ok( size == 10, "LocalSize returned %Iu\n", size ); + ok( size == small_size, "LocalSize returned %Iu\n", size ); mem = LocalFree( mem ); ok( !mem, "LocalFree failed, error %lu\n", GetLastError() );
/* LMEM_FIXED block can be relocated with LMEM_MOVEABLE */ - mem = LocalAlloc( LMEM_FIXED, 10 ); + mem = LocalAlloc( LMEM_FIXED, small_size ); ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); - tmp_mem = LocalReAlloc( mem, 11, LMEM_MOVEABLE ); + tmp_mem = LocalReAlloc( mem, small_size + 1, LMEM_MOVEABLE ); ok( !!tmp_mem, "LocalReAlloc failed, error %lu\n", GetLastError() ); todo_wine - ok( tmp_mem != mem || broken( tmp_mem == mem ) /* w1064v1507 / w1064v1607 */, - "LocalReAlloc didn't relocate memory\n" ); + ok( tmp_mem != mem, "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 ); @@ -2375,7 +2362,7 @@ static void test_LocalAlloc(void)
winetest_push_context( "flags %#x", flags );
- mem = pLocalAlloc( LMEM_FIXED, 10 ); + mem = pLocalAlloc( LMEM_FIXED, small_size ); ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); ok( !is_mem_entry( mem ), "unexpected moveable %p\n", mem );
@@ -2388,13 +2375,13 @@ static void test_LocalAlloc(void)
size = LocalSize( mem ); if (flags == LMEM_MOVEABLE) ok( size == 512, "LocalSize returned %Iu\n", size ); - else ok( size == 10, "LocalSize returned %Iu\n", size ); + else ok( size == small_size, "LocalSize returned %Iu\n", size );
mem = LocalFree( mem ); ok( !mem, "LocalFree failed, error %lu\n", GetLastError() );
- mem = pLocalAlloc( LMEM_FIXED, 12 ); + mem = pLocalAlloc( LMEM_FIXED, small_size ); ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); ok( !is_mem_entry( mem ), "unexpected moveable %p\n", mem );
@@ -2407,14 +2394,13 @@ static void test_LocalAlloc(void)
size = LocalSize( mem ); if (flags == LMEM_MOVEABLE) ok( size == 10, "LocalSize returned %Iu\n", size ); - else if (flags) ok( size == 12, "LocalSize returned %Iu\n", size ); - else ok( size == 12, "LocalSize returned %Iu\n", size ); + else ok( size == small_size, "LocalSize returned %Iu\n", size );
mem = LocalFree( mem ); ok( !mem, "LocalFree failed, error %lu\n", GetLastError() );
- mem = pLocalAlloc( LMEM_FIXED, 12 ); + mem = pLocalAlloc( LMEM_FIXED, small_size ); ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); ok( !is_mem_entry( mem ), "unexpected moveable %p\n", mem );
@@ -2427,14 +2413,13 @@ static void test_LocalAlloc(void)
size = LocalSize( mem ); if (flags == LMEM_MOVEABLE) ok( size == 0 || broken( size == 1 ) /* w7 */, "LocalSize returned %Iu\n", size ); - else if (flags) ok( size == 12, "LocalSize returned %Iu\n", size ); - else ok( size == 12, "LocalSize returned %Iu\n", size ); + else ok( size == small_size, "LocalSize returned %Iu\n", size );
mem = LocalFree( mem ); ok( !mem, "LocalFree failed, error %lu\n", GetLastError() );
- mem = pLocalAlloc( LMEM_MOVEABLE, 10 ); + mem = pLocalAlloc( LMEM_MOVEABLE, small_size ); ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); ok( is_mem_entry( mem ), "unexpected moveable %p\n", mem ); ptr = LocalLock( mem ); @@ -2442,18 +2427,19 @@ static void test_LocalAlloc(void) expect_entry = *mem_entry_from_HANDLE( mem );
tmp_mem = LocalReAlloc( mem, 512, flags ); - if (!(flags & LMEM_MODIFY) && ((flags & LMEM_DISCARDABLE) || !(flags & LMEM_MOVEABLE))) - ok( !tmp_mem, "LocalReAlloc succeeded\n" ); - else - ok( tmp_mem == mem, "LocalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + if (flags & LMEM_MODIFY) ok( tmp_mem == mem, "LocalReAlloc returned %p\n", tmp_mem ); + else if (flags & LMEM_DISCARDABLE) ok( !tmp_mem, "LocalReAlloc succeeded\n" ); + else if (flags & LMEM_MOVEABLE) ok( tmp_mem == mem, "LocalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + else ok( !tmp_mem, "LocalReAlloc succeeded\n" ); entry = *mem_entry_from_HANDLE( mem ); if ((flags & LMEM_DISCARDABLE) && (flags & LMEM_MODIFY)) expect_entry.flags |= 4; if (flags == LMEM_MOVEABLE) ok( entry.ptr != expect_entry.ptr, "got unexpected ptr %p\n", entry.ptr ); else ok( entry.ptr == expect_entry.ptr, "got ptr %p\n", entry.ptr ); ok( entry.flags == expect_entry.flags, "got flags %#Ix was %#Ix\n", entry.flags, expect_entry.flags ); + size = LocalSize( mem ); if (flags == LMEM_MOVEABLE) ok( size == 512, "LocalSize returned %Iu\n", size ); - else ok( size == 10, "LocalSize returned %Iu\n", size ); + else ok( size == small_size, "LocalSize returned %Iu\n", size );
ret = LocalUnlock( mem ); ok( !ret, "LocalUnlock succeeded\n" ); @@ -2461,7 +2447,7 @@ static void test_LocalAlloc(void) ok( !mem, "LocalFree failed, error %lu\n", GetLastError() );
- mem = pLocalAlloc( LMEM_MOVEABLE, 12 ); + mem = pLocalAlloc( LMEM_MOVEABLE, small_size ); ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); ok( is_mem_entry( mem ), "unexpected moveable %p\n", mem ); ptr = LocalLock( mem ); @@ -2469,19 +2455,17 @@ static void test_LocalAlloc(void) expect_entry = *mem_entry_from_HANDLE( mem );
tmp_mem = LocalReAlloc( mem, 10, flags ); - if (!(flags & LMEM_MODIFY) && (flags & LMEM_DISCARDABLE)) - ok( !tmp_mem, "LocalReAlloc succeeded\n" ); - else - ok( tmp_mem == mem, "LocalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + if (flags & LMEM_MODIFY) ok( tmp_mem == mem, "LocalReAlloc returned %p\n", tmp_mem ); + else if (flags & LMEM_DISCARDABLE) ok( !tmp_mem, "LocalReAlloc succeeded\n" ); + else ok( tmp_mem == mem, "LocalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); entry = *mem_entry_from_HANDLE( mem ); if ((flags & LMEM_DISCARDABLE) && (flags & LMEM_MODIFY)) expect_entry.flags |= 4; ok( entry.ptr == expect_entry.ptr, "got ptr %p was %p\n", entry.ptr, expect_entry.ptr ); ok( entry.flags == expect_entry.flags, "got flags %#Ix was %#Ix\n", entry.flags, expect_entry.flags ); + size = LocalSize( mem ); - if ((flags & LMEM_DISCARDABLE) || (flags & LMEM_MODIFY)) - ok( size == 12, "LocalSize returned %Iu\n", size ); - else - ok( size == 10, "LocalSize returned %Iu\n", size ); + if (flags & (LMEM_DISCARDABLE | LMEM_MODIFY)) ok( size == small_size, "LocalSize returned %Iu\n", size ); + else ok( size == 10, "LocalSize returned %Iu\n", size );
ret = LocalUnlock( mem ); ok( !ret, "LocalUnlock succeeded\n" ); @@ -2489,7 +2473,7 @@ static void test_LocalAlloc(void) ok( !mem, "LocalFree failed, error %lu\n", GetLastError() );
- mem = pLocalAlloc( LMEM_MOVEABLE, 12 ); + mem = pLocalAlloc( LMEM_MOVEABLE, small_size ); ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); ok( is_mem_entry( mem ), "unexpected moveable %p\n", mem ); ptr = LocalLock( mem ); @@ -2497,16 +2481,15 @@ static void test_LocalAlloc(void) expect_entry = *mem_entry_from_HANDLE( mem );
tmp_mem = LocalReAlloc( mem, 0, flags ); - if (flags & LMEM_MODIFY) - ok( tmp_mem == mem, "LocalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); - else - ok( !tmp_mem, "LocalReAlloc succeeded\n" ); + if (flags & LMEM_MODIFY) ok( tmp_mem == mem, "LocalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + else ok( !tmp_mem, "LocalReAlloc succeeded\n" ); entry = *mem_entry_from_HANDLE( mem ); if ((flags & LMEM_DISCARDABLE) && (flags & LMEM_MODIFY)) expect_entry.flags |= 4; ok( entry.ptr == expect_entry.ptr, "got ptr %p was %p\n", entry.ptr, expect_entry.ptr ); ok( entry.flags == expect_entry.flags, "got flags %#Ix was %#Ix\n", entry.flags, expect_entry.flags ); + size = LocalSize( mem ); - ok( size == 12, "LocalSize returned %Iu\n", size ); + ok( size == small_size, "LocalSize returned %Iu\n", size );
ret = LocalUnlock( mem ); ok( !ret, "LocalUnlock succeeded\n" ); @@ -2514,69 +2497,61 @@ static void test_LocalAlloc(void) ok( !mem, "LocalFree failed, error %lu\n", GetLastError() );
- mem = pLocalAlloc( LMEM_MOVEABLE, 10 ); + mem = pLocalAlloc( LMEM_MOVEABLE, small_size ); ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); ok( is_mem_entry( mem ), "unexpected moveable %p\n", mem ); expect_entry = *mem_entry_from_HANDLE( mem );
tmp_mem = LocalReAlloc( mem, 512, flags ); - if (!(flags & LMEM_MODIFY) && (flags & LMEM_DISCARDABLE)) - ok( !tmp_mem, "LocalReAlloc succeeded\n" ); - else - ok( tmp_mem == mem, "LocalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + if (flags & LMEM_MODIFY) ok( tmp_mem == mem, "LocalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + else if (flags & LMEM_DISCARDABLE) ok( !tmp_mem, "LocalReAlloc succeeded\n" ); + else ok( tmp_mem == mem, "LocalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); entry = *mem_entry_from_HANDLE( mem ); if ((flags & LMEM_DISCARDABLE) && (flags & LMEM_MODIFY)) expect_entry.flags |= 4; - if ((flags & LMEM_DISCARDABLE) || (flags & LMEM_MODIFY)) - ok( entry.ptr == expect_entry.ptr, "got ptr %p\n", entry.ptr ); - else - ok( entry.ptr != expect_entry.ptr, "got unexpected ptr %p\n", entry.ptr ); + if (flags & (LMEM_DISCARDABLE | LMEM_MODIFY)) ok( entry.ptr == expect_entry.ptr, "got ptr %p\n", entry.ptr ); + else ok( entry.ptr != expect_entry.ptr, "got unexpected ptr %p\n", entry.ptr ); ok( entry.flags == expect_entry.flags, "got flags %#Ix was %#Ix\n", entry.flags, expect_entry.flags ); + size = LocalSize( mem ); - if ((flags & LMEM_DISCARDABLE) || (flags & LMEM_MODIFY)) - ok( size == 10, "LocalSize returned %Iu\n", size ); - else - ok( size == 512, "LocalSize returned %Iu\n", size ); + if (flags & (LMEM_DISCARDABLE | LMEM_MODIFY)) ok( size == small_size, "LocalSize returned %Iu\n", size ); + else ok( size == 512, "LocalSize returned %Iu\n", size );
mem = LocalFree( mem ); ok( !mem, "LocalFree failed, error %lu\n", GetLastError() );
- mem = pLocalAlloc( LMEM_MOVEABLE, 12 ); + mem = pLocalAlloc( LMEM_MOVEABLE, small_size ); ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); ok( is_mem_entry( mem ), "unexpected moveable %p\n", mem ); expect_entry = *mem_entry_from_HANDLE( mem );
tmp_mem = LocalReAlloc( mem, 10, flags ); - if (!(flags & LMEM_MODIFY) && (flags & LMEM_DISCARDABLE)) - ok( !tmp_mem, "LocalReAlloc succeeded\n" ); - else - ok( tmp_mem == mem, "LocalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + if (flags & LMEM_MODIFY) ok( tmp_mem == mem, "LocalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + else if (flags & LMEM_DISCARDABLE) ok( !tmp_mem, "LocalReAlloc succeeded\n" ); + else ok( tmp_mem == mem, "LocalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); entry = *mem_entry_from_HANDLE( mem ); if ((flags & LMEM_DISCARDABLE) && (flags & LMEM_MODIFY)) expect_entry.flags |= 4; ok( entry.ptr == expect_entry.ptr, "got ptr %p was %p\n", entry.ptr, expect_entry.ptr ); ok( entry.flags == expect_entry.flags, "got flags %#Ix was %#Ix\n", entry.flags, expect_entry.flags ); + size = LocalSize( mem ); - if ((flags & LMEM_DISCARDABLE) || (flags & LMEM_MODIFY)) - ok( size == 12, "LocalSize returned %Iu\n", size ); - else - ok( size == 10, "LocalSize returned %Iu\n", size ); + if (flags & (LMEM_DISCARDABLE | LMEM_MODIFY)) ok( size == small_size, "LocalSize returned %Iu\n", size ); + else ok( size == 10, "LocalSize returned %Iu\n", size );
mem = LocalFree( mem ); ok( !mem, "LocalFree failed, error %lu\n", GetLastError() );
- mem = pLocalAlloc( LMEM_MOVEABLE, 12 ); + mem = pLocalAlloc( LMEM_MOVEABLE, small_size ); ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); ok( is_mem_entry( mem ), "unexpected moveable %p\n", mem ); expect_entry = *mem_entry_from_HANDLE( mem );
tmp_mem = LocalReAlloc( mem, 0, flags ); - if (flags == LMEM_FIXED) - ok( !tmp_mem, "LocalReAlloc succeeded\n" ); - else if (!(flags & LMEM_MODIFY) && (flags & LMEM_DISCARDABLE)) - ok( !tmp_mem, "LocalReAlloc succeeded\n" ); - else - ok( tmp_mem == mem, "LocalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + if (flags & LMEM_MODIFY) ok( tmp_mem == mem, "LocalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + else if (flags == LMEM_FIXED) ok( !tmp_mem, "LocalReAlloc succeeded\n" ); + else if (flags & LMEM_DISCARDABLE) ok( !tmp_mem, "LocalReAlloc succeeded\n" ); + else ok( tmp_mem == mem, "LocalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); entry = *mem_entry_from_HANDLE( mem ); if (flags == LMEM_MOVEABLE) { @@ -2586,9 +2561,10 @@ static void test_LocalAlloc(void) else if ((flags & LMEM_DISCARDABLE) && (flags & LMEM_MODIFY)) expect_entry.flags |= 4; ok( entry.ptr == expect_entry.ptr, "got ptr %p was %p\n", entry.ptr, expect_entry.ptr ); ok( entry.flags == expect_entry.flags, "got flags %#Ix was %#Ix\n", entry.flags, expect_entry.flags ); + size = LocalSize( mem ); if (flags == LMEM_MOVEABLE) ok( size == 0, "LocalSize returned %Iu\n", size ); - else ok( size == 12, "LocalSize returned %Iu\n", size ); + else ok( size == small_size, "LocalSize returned %Iu\n", size );
mem = LocalFree( mem ); ok( !mem, "LocalFree failed, error %lu\n", GetLastError() );
From: Rémi Bernon rbernon@codeweavers.com
In place reallocation is possible, although it depends on the underlying heap strategy. The LFH heap usually fails as it doesn't blocks to grow or shrink out of their size class. Larger block (LFH is limited to 16K blocks), more often allow in-place reallocation, and some native DLLs depend on this.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53996 --- dlls/kernel32/tests/heap.c | 284 ++++++++++++++++++++++++++++++++++++- 1 file changed, 282 insertions(+), 2 deletions(-)
diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c index 0ac209577af..654ba88738d 100644 --- a/dlls/kernel32/tests/heap.c +++ b/dlls/kernel32/tests/heap.c @@ -1295,8 +1295,8 @@ static void test_GlobalAlloc(void) static const char zero_buffer[100000] = {0}; static const SIZE_T buffer_size = ARRAY_SIZE(zero_buffer); const HGLOBAL invalid_mem = LongToHandle( 0xdeadbee0 + sizeof(void *) ); + SIZE_T size, alloc_size, small_size = 12, nolfh_size = 0x20000; void *const invalid_ptr = LongToHandle( 0xdeadbee0 ); - SIZE_T size, alloc_size, small_size = 0x20; HANDLE heap = GetProcessHeap(); PROCESS_HEAP_ENTRY walk_entry; struct mem_entry *entry; @@ -1745,6 +1745,35 @@ static void test_GlobalAlloc(void) ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() );
+ mem = pGlobalAlloc( GMEM_FIXED, nolfh_size ); + ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); + ok( !is_mem_entry( mem ), "unexpected moveable %p\n", mem ); + + tmp_mem = GlobalReAlloc( mem, nolfh_size + 512, flags ); + if (!expect_convert) + { + ok( !is_mem_entry( tmp_mem ), "unexpected moveable %p\n", tmp_mem ); + if (flags & GMEM_DISCARDABLE) ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); + else todo_wine_if(!flags) ok( tmp_mem == mem, "GlobalReAlloc returned %p\n", tmp_mem ); + } + else + { + ok( is_mem_entry( tmp_mem ), "unexpected moveable %p\n", tmp_mem ); + entry = *mem_entry_from_HANDLE( tmp_mem ); + todo_wine ok( entry.ptr != mem, "got ptr %p was %p\n", entry.ptr, mem ); + if (flags & GMEM_DISCARDABLE) ok( (entry.flags & 0x7fff) == 0x7, "got flags %#Ix\n", entry.flags ); + else ok( (entry.flags & 0x7fff) == 0x3, "got flags %#Ix\n", entry.flags ); + } + if (tmp_mem) mem = tmp_mem; + + size = GlobalSize( mem ); + if (flags & (GMEM_MODIFY | GMEM_DISCARDABLE)) ok( size == nolfh_size, "GlobalSize returned %Iu\n", size ); + else todo_wine_if(!flags) ok( size == nolfh_size + 512, "GlobalSize returned %Iu\n", size ); + + mem = GlobalFree( mem ); + ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() ); + + mem = pGlobalAlloc( GMEM_FIXED, small_size ); ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); ok( !is_mem_entry( mem ), "unexpected moveable %p\n", mem ); @@ -1775,6 +1804,35 @@ static void test_GlobalAlloc(void) ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() );
+ mem = pGlobalAlloc( GMEM_FIXED, nolfh_size ); + ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); + ok( !is_mem_entry( mem ), "unexpected moveable %p\n", mem ); + + tmp_mem = GlobalReAlloc( mem, 10, flags ); + if (!expect_convert) + { + ok( !is_mem_entry( tmp_mem ), "unexpected moveable %p\n", tmp_mem ); + if (flags & GMEM_DISCARDABLE) ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); + else todo_wine_if(!flags) ok( tmp_mem == mem, "GlobalReAlloc returned %p\n", tmp_mem ); + } + else + { + ok( is_mem_entry( tmp_mem ), "unexpected moveable %p\n", tmp_mem ); + entry = *mem_entry_from_HANDLE( tmp_mem ); + ok( entry.ptr != ptr, "got ptr %p was %p\n", entry.ptr, ptr ); + if (flags & GMEM_DISCARDABLE) ok( (entry.flags & 0x7fff) == 0x7, "got flags %#Ix\n", entry.flags ); + else ok( (entry.flags & 0x7fff) == 0x3, "got flags %#Ix\n", entry.flags ); + } + if (tmp_mem) mem = tmp_mem; + + size = GlobalSize( mem ); + if (flags & (GMEM_MODIFY | GMEM_DISCARDABLE)) ok( size == nolfh_size, "GlobalSize returned %Iu\n", size ); + else todo_wine_if(!flags) ok( size == 10, "GlobalSize returned %Iu\n", size ); + + mem = GlobalFree( mem ); + ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() ); + + mem = pGlobalAlloc( GMEM_FIXED, small_size ); ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); ok( !is_mem_entry( mem ), "unexpected moveable %p\n", mem ); @@ -1805,6 +1863,35 @@ static void test_GlobalAlloc(void) ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() );
+ mem = pGlobalAlloc( GMEM_FIXED, nolfh_size ); + ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); + ok( !is_mem_entry( mem ), "unexpected moveable %p\n", mem ); + + tmp_mem = GlobalReAlloc( mem, 0, flags ); + if (!expect_convert) + { + ok( !is_mem_entry( tmp_mem ), "unexpected moveable %p\n", tmp_mem ); + if (flags & GMEM_DISCARDABLE) ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); + else todo_wine_if(!flags) ok( tmp_mem == mem, "GlobalReAlloc returned %p\n", tmp_mem ); + } + else + { + ok( is_mem_entry( tmp_mem ), "unexpected moveable %p\n", tmp_mem ); + entry = *mem_entry_from_HANDLE( tmp_mem ); + ok( entry.ptr != ptr, "got ptr %p was %p\n", entry.ptr, ptr ); + if (flags & GMEM_DISCARDABLE) ok( (entry.flags & 0x7fff) == 0x7, "got flags %#Ix\n", entry.flags ); + else ok( (entry.flags & 0x7fff) == 0x3, "got flags %#Ix\n", entry.flags ); + } + if (tmp_mem) mem = tmp_mem; + + size = GlobalSize( mem ); + if (flags & (GMEM_MODIFY | GMEM_DISCARDABLE)) ok( size == nolfh_size, "GlobalSize returned %Iu\n", size ); + else todo_wine_if(!flags) ok( size == 0 || broken( size == 1 ) /* w7 */, "GlobalSize returned %Iu\n", size ); + + mem = GlobalFree( mem ); + ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() ); + + mem = pGlobalAlloc( GMEM_MOVEABLE, small_size ); ok( !!mem, "GlobalAlloc failed, error %lu\n", GetLastError() ); ok( is_mem_entry( mem ), "unexpected moveable %p\n", mem ); @@ -2119,7 +2206,7 @@ static void test_LocalAlloc(void) static const SIZE_T buffer_size = ARRAY_SIZE(zero_buffer); const HLOCAL invalid_mem = LongToHandle( 0xdeadbee0 + sizeof(void *) ); void *const invalid_ptr = LongToHandle( 0xdeadbee0 ); - SIZE_T size, small_size = 0x20; + SIZE_T size, small_size = 12, nolfh_size = 0x20000; HLOCAL locals[0x10000]; HLOCAL mem, tmp_mem; BYTE *ptr, *tmp_ptr; @@ -2381,6 +2468,21 @@ static void test_LocalAlloc(void) ok( !mem, "LocalFree failed, error %lu\n", GetLastError() );
+ mem = pLocalAlloc( LMEM_FIXED, nolfh_size ); + ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); + ok( !is_mem_entry( mem ), "unexpected moveable %p\n", mem ); + tmp_mem = LocalReAlloc( mem, nolfh_size + 512, flags ); + ok( !is_mem_entry( tmp_mem ), "unexpected moveable %p\n", tmp_mem ); + if (flags & LMEM_MODIFY) ok( tmp_mem == mem, "LocalReAlloc returned %p\n", tmp_mem ); + else if (flags & LMEM_DISCARDABLE) ok( !tmp_mem, "LocalReAlloc succeeded\n" ); + else todo_wine_if(!flags) ok( tmp_mem == mem, "LocalReAlloc returned %p\n", tmp_mem ); + size = LocalSize( mem ); + if (flags & (LMEM_DISCARDABLE | LMEM_MODIFY)) ok( size == nolfh_size, "LocalSize returned %Iu\n", size ); + else todo_wine_if(!flags) ok( size == nolfh_size + 512, "LocalSize returned %Iu\n", size ); + mem = LocalFree( mem ); + ok( !mem, "LocalFree failed, error %lu\n", GetLastError() ); + + mem = pLocalAlloc( LMEM_FIXED, small_size ); ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); ok( !is_mem_entry( mem ), "unexpected moveable %p\n", mem ); @@ -2400,6 +2502,21 @@ static void test_LocalAlloc(void) ok( !mem, "LocalFree failed, error %lu\n", GetLastError() );
+ mem = pLocalAlloc( LMEM_FIXED, nolfh_size ); + ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); + ok( !is_mem_entry( mem ), "unexpected moveable %p\n", mem ); + tmp_mem = LocalReAlloc( mem, 10, flags ); + ok( !is_mem_entry( tmp_mem ), "unexpected moveable %p\n", tmp_mem ); + if (flags & LMEM_MODIFY) ok( tmp_mem == mem, "LocalReAlloc returned %p\n", tmp_mem ); + else if (flags & LMEM_DISCARDABLE) ok( !tmp_mem, "LocalReAlloc succeeded\n" ); + else todo_wine_if(!flags) ok( tmp_mem == mem, "LocalReAlloc returned %p\n", tmp_mem ); + size = LocalSize( mem ); + if (flags & (LMEM_DISCARDABLE | LMEM_MODIFY)) ok( size == nolfh_size, "LocalSize returned %Iu\n", size ); + else todo_wine_if(!flags) ok( size == 10, "LocalSize returned %Iu\n", size ); + mem = LocalFree( mem ); + ok( !mem, "LocalFree failed, error %lu\n", GetLastError() ); + + mem = pLocalAlloc( LMEM_FIXED, small_size ); ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); ok( !is_mem_entry( mem ), "unexpected moveable %p\n", mem ); @@ -2419,6 +2536,21 @@ static void test_LocalAlloc(void) ok( !mem, "LocalFree failed, error %lu\n", GetLastError() );
+ mem = pLocalAlloc( LMEM_FIXED, nolfh_size ); + ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); + ok( !is_mem_entry( mem ), "unexpected moveable %p\n", mem ); + tmp_mem = LocalReAlloc( mem, 0, flags ); + ok( !is_mem_entry( tmp_mem ), "unexpected moveable %p\n", tmp_mem ); + if (flags & LMEM_MODIFY) ok( tmp_mem == mem, "LocalReAlloc returned %p\n", tmp_mem ); + else if (flags & LMEM_DISCARDABLE) ok( !tmp_mem, "LocalReAlloc succeeded\n" ); + else todo_wine_if(!flags) ok( tmp_mem == mem, "LocalReAlloc returned %p\n", tmp_mem ); + size = LocalSize( mem ); + if (flags & (LMEM_DISCARDABLE | LMEM_MODIFY)) ok( size == nolfh_size, "LocalSize returned %Iu\n", size ); + else todo_wine_if(!flags) ok( size == 0 || broken( size == 1 ) /* w7 */, "LocalSize returned %Iu\n", size ); + mem = LocalFree( mem ); + ok( !mem, "LocalFree failed, error %lu\n", GetLastError() ); + + mem = pLocalAlloc( LMEM_MOVEABLE, small_size ); ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); ok( is_mem_entry( mem ), "unexpected moveable %p\n", mem ); @@ -2447,6 +2579,32 @@ static void test_LocalAlloc(void) ok( !mem, "LocalFree failed, error %lu\n", GetLastError() );
+ mem = pLocalAlloc( LMEM_MOVEABLE, nolfh_size ); + ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); + ok( is_mem_entry( mem ), "unexpected moveable %p\n", mem ); + ptr = LocalLock( mem ); + ok( !!ptr, "LocalLock failed, error %lu\n", GetLastError() ); + expect_entry = *mem_entry_from_HANDLE( mem ); + + tmp_mem = LocalReAlloc( mem, nolfh_size + 512, flags ); + if (flags & LMEM_MODIFY) ok( tmp_mem == mem, "LocalReAlloc returned %p\n", tmp_mem ); + else if (flags & LMEM_DISCARDABLE) ok( !tmp_mem, "LocalReAlloc succeeded\n" ); + else ok( tmp_mem == mem, "LocalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + entry = *mem_entry_from_HANDLE( mem ); + if ((flags & LMEM_DISCARDABLE) && (flags & LMEM_MODIFY)) expect_entry.flags |= 4; + ok( entry.ptr == expect_entry.ptr, "got ptr %p\n", entry.ptr ); + ok( entry.flags == expect_entry.flags, "got flags %#Ix was %#Ix\n", entry.flags, expect_entry.flags ); + + size = LocalSize( mem ); + if (flags & (LMEM_DISCARDABLE | LMEM_MODIFY)) ok( size == nolfh_size, "LocalSize returned %Iu\n", size ); + else ok( size == nolfh_size + 512, "LocalSize returned %Iu\n", size ); + + ret = LocalUnlock( mem ); + ok( !ret, "LocalUnlock succeeded\n" ); + mem = LocalFree( mem ); + ok( !mem, "LocalFree failed, error %lu\n", GetLastError() ); + + mem = pLocalAlloc( LMEM_MOVEABLE, small_size ); ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); ok( is_mem_entry( mem ), "unexpected moveable %p\n", mem ); @@ -2473,6 +2631,32 @@ static void test_LocalAlloc(void) ok( !mem, "LocalFree failed, error %lu\n", GetLastError() );
+ mem = pLocalAlloc( LMEM_MOVEABLE, nolfh_size ); + ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); + ok( is_mem_entry( mem ), "unexpected moveable %p\n", mem ); + ptr = LocalLock( mem ); + ok( !!ptr, "LocalLock failed, error %lu\n", GetLastError() ); + expect_entry = *mem_entry_from_HANDLE( mem ); + + tmp_mem = LocalReAlloc( mem, 10, flags ); + if (flags & LMEM_MODIFY) ok( tmp_mem == mem, "LocalReAlloc returned %p\n", tmp_mem ); + else if (flags & LMEM_DISCARDABLE) ok( !tmp_mem, "LocalReAlloc succeeded\n" ); + else ok( tmp_mem == mem, "LocalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + entry = *mem_entry_from_HANDLE( mem ); + if ((flags & LMEM_DISCARDABLE) && (flags & LMEM_MODIFY)) expect_entry.flags |= 4; + ok( entry.ptr == expect_entry.ptr, "got ptr %p was %p\n", entry.ptr, expect_entry.ptr ); + ok( entry.flags == expect_entry.flags, "got flags %#Ix was %#Ix\n", entry.flags, expect_entry.flags ); + + size = LocalSize( mem ); + if (flags & (LMEM_DISCARDABLE | LMEM_MODIFY)) ok( size == nolfh_size, "LocalSize returned %Iu\n", size ); + else ok( size == 10, "LocalSize returned %Iu\n", size ); + + ret = LocalUnlock( mem ); + ok( !ret, "LocalUnlock succeeded\n" ); + mem = LocalFree( mem ); + ok( !mem, "LocalFree failed, error %lu\n", GetLastError() ); + + mem = pLocalAlloc( LMEM_MOVEABLE, small_size ); ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); ok( is_mem_entry( mem ), "unexpected moveable %p\n", mem ); @@ -2497,6 +2681,30 @@ static void test_LocalAlloc(void) ok( !mem, "LocalFree failed, error %lu\n", GetLastError() );
+ mem = pLocalAlloc( LMEM_MOVEABLE, nolfh_size ); + ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); + ok( is_mem_entry( mem ), "unexpected moveable %p\n", mem ); + ptr = LocalLock( mem ); + ok( !!ptr, "LocalLock failed, error %lu\n", GetLastError() ); + expect_entry = *mem_entry_from_HANDLE( mem ); + + tmp_mem = LocalReAlloc( mem, 0, flags ); + if (flags & LMEM_MODIFY) ok( tmp_mem == mem, "LocalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + else ok( !tmp_mem, "LocalReAlloc succeeded\n" ); + entry = *mem_entry_from_HANDLE( mem ); + if ((flags & LMEM_DISCARDABLE) && (flags & LMEM_MODIFY)) expect_entry.flags |= 4; + ok( entry.ptr == expect_entry.ptr, "got ptr %p was %p\n", entry.ptr, expect_entry.ptr ); + ok( entry.flags == expect_entry.flags, "got flags %#Ix was %#Ix\n", entry.flags, expect_entry.flags ); + + size = LocalSize( mem ); + ok( size == nolfh_size, "LocalSize returned %Iu\n", size ); + + ret = LocalUnlock( mem ); + ok( !ret, "LocalUnlock succeeded\n" ); + mem = LocalFree( mem ); + ok( !mem, "LocalFree failed, error %lu\n", GetLastError() ); + + mem = pLocalAlloc( LMEM_MOVEABLE, small_size ); ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); ok( is_mem_entry( mem ), "unexpected moveable %p\n", mem ); @@ -2520,6 +2728,28 @@ static void test_LocalAlloc(void) ok( !mem, "LocalFree failed, error %lu\n", GetLastError() );
+ mem = pLocalAlloc( LMEM_MOVEABLE, nolfh_size ); + ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); + ok( is_mem_entry( mem ), "unexpected moveable %p\n", mem ); + expect_entry = *mem_entry_from_HANDLE( mem ); + + tmp_mem = LocalReAlloc( mem, nolfh_size + 512, flags ); + if (flags & LMEM_MODIFY) ok( tmp_mem == mem, "LocalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + else if (flags & LMEM_DISCARDABLE) ok( !tmp_mem, "LocalReAlloc succeeded\n" ); + else ok( tmp_mem == mem, "LocalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + entry = *mem_entry_from_HANDLE( mem ); + if ((flags & LMEM_DISCARDABLE) && (flags & LMEM_MODIFY)) expect_entry.flags |= 4; + ok( entry.ptr == expect_entry.ptr, "got unexpected ptr %p\n", entry.ptr ); + ok( entry.flags == expect_entry.flags, "got flags %#Ix was %#Ix\n", entry.flags, expect_entry.flags ); + + size = LocalSize( mem ); + if (flags & (LMEM_DISCARDABLE | LMEM_MODIFY)) ok( size == nolfh_size, "LocalSize returned %Iu\n", size ); + else ok( size == nolfh_size + 512, "LocalSize returned %Iu\n", size ); + + mem = LocalFree( mem ); + ok( !mem, "LocalFree failed, error %lu\n", GetLastError() ); + + mem = pLocalAlloc( LMEM_MOVEABLE, small_size ); ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); ok( is_mem_entry( mem ), "unexpected moveable %p\n", mem ); @@ -2542,6 +2772,28 @@ static void test_LocalAlloc(void) ok( !mem, "LocalFree failed, error %lu\n", GetLastError() );
+ mem = pLocalAlloc( LMEM_MOVEABLE, nolfh_size ); + ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); + ok( is_mem_entry( mem ), "unexpected moveable %p\n", mem ); + expect_entry = *mem_entry_from_HANDLE( mem ); + + tmp_mem = LocalReAlloc( mem, 10, flags ); + if (flags & LMEM_MODIFY) ok( tmp_mem == mem, "LocalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + else if (flags & LMEM_DISCARDABLE) ok( !tmp_mem, "LocalReAlloc succeeded\n" ); + else ok( tmp_mem == mem, "LocalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + entry = *mem_entry_from_HANDLE( mem ); + if ((flags & LMEM_DISCARDABLE) && (flags & LMEM_MODIFY)) expect_entry.flags |= 4; + ok( entry.ptr == expect_entry.ptr, "got ptr %p was %p\n", entry.ptr, expect_entry.ptr ); + ok( entry.flags == expect_entry.flags, "got flags %#Ix was %#Ix\n", entry.flags, expect_entry.flags ); + + size = LocalSize( mem ); + if (flags & (LMEM_DISCARDABLE | LMEM_MODIFY)) ok( size == nolfh_size, "LocalSize returned %Iu\n", size ); + else ok( size == 10, "LocalSize returned %Iu\n", size ); + + mem = LocalFree( mem ); + ok( !mem, "LocalFree failed, error %lu\n", GetLastError() ); + + mem = pLocalAlloc( LMEM_MOVEABLE, small_size ); ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); ok( is_mem_entry( mem ), "unexpected moveable %p\n", mem ); @@ -2569,6 +2821,34 @@ static void test_LocalAlloc(void) mem = LocalFree( mem ); ok( !mem, "LocalFree failed, error %lu\n", GetLastError() );
+ + mem = pLocalAlloc( LMEM_MOVEABLE, nolfh_size ); + ok( !!mem, "LocalAlloc failed, error %lu\n", GetLastError() ); + ok( is_mem_entry( mem ), "unexpected moveable %p\n", mem ); + expect_entry = *mem_entry_from_HANDLE( mem ); + + tmp_mem = LocalReAlloc( mem, 0, flags ); + if (flags & LMEM_MODIFY) ok( tmp_mem == mem, "LocalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + else if (flags == LMEM_FIXED) ok( !tmp_mem, "LocalReAlloc succeeded\n" ); + else if (flags & LMEM_DISCARDABLE) ok( !tmp_mem, "LocalReAlloc succeeded\n" ); + else ok( tmp_mem == mem, "LocalReAlloc returned %p, error %lu\n", tmp_mem, GetLastError() ); + entry = *mem_entry_from_HANDLE( mem ); + if (flags == LMEM_MOVEABLE) + { + expect_entry.flags |= 8; + expect_entry.ptr = NULL; + } + else if ((flags & LMEM_DISCARDABLE) && (flags & LMEM_MODIFY)) expect_entry.flags |= 4; + ok( entry.ptr == expect_entry.ptr, "got ptr %p was %p\n", entry.ptr, expect_entry.ptr ); + ok( entry.flags == expect_entry.flags, "got flags %#Ix was %#Ix\n", entry.flags, expect_entry.flags ); + + size = LocalSize( mem ); + if (flags == LMEM_MOVEABLE) ok( size == 0, "LocalSize returned %Iu\n", size ); + else ok( size == nolfh_size, "LocalSize returned %Iu\n", size ); + + mem = LocalFree( mem ); + ok( !mem, "LocalFree failed, error %lu\n", GetLastError() ); + winetest_pop_context(); }
From: Rémi Bernon rbernon@codeweavers.com
This effectively reverts 2be9b0ff4a61f3738eb2c05a7f196a60a95d40c6, which incorrectly removed the flag, when the reallocation failures the tests showed were coming from an underlying LFH in-place reallocation failure.
Thus, it restores todo_wine where appropriate while removing other todos for sizes outside of the LFH block size range.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53996 --- dlls/kernel32/tests/heap.c | 44 +++++++++++++++++++++----------------- dlls/kernelbase/memory.c | 4 ++-- 2 files changed, 26 insertions(+), 22 deletions(-)
diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c index 654ba88738d..a81cb1b7a15 100644 --- a/dlls/kernel32/tests/heap.c +++ b/dlls/kernel32/tests/heap.c @@ -1679,7 +1679,9 @@ static void test_GlobalAlloc(void) ok( size == small_size, "GlobalSize returned %Iu\n", size ); SetLastError( 0xdeadbeef ); tmp_mem = GlobalReAlloc( mem, small_size, 0 ); + todo_wine ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); + todo_wine ok( GetLastError() == ERROR_NOT_ENOUGH_MEMORY, "got error %lu\n", GetLastError() ); if (tmp_mem) mem = tmp_mem; tmp_mem = GlobalReAlloc( mem, 1024 * 1024, GMEM_MODIFY ); @@ -1754,7 +1756,7 @@ static void test_GlobalAlloc(void) { ok( !is_mem_entry( tmp_mem ), "unexpected moveable %p\n", tmp_mem ); if (flags & GMEM_DISCARDABLE) ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); - else todo_wine_if(!flags) ok( tmp_mem == mem, "GlobalReAlloc returned %p\n", tmp_mem ); + else ok( tmp_mem == mem, "GlobalReAlloc returned %p\n", tmp_mem ); } else { @@ -1768,7 +1770,7 @@ static void test_GlobalAlloc(void)
size = GlobalSize( mem ); if (flags & (GMEM_MODIFY | GMEM_DISCARDABLE)) ok( size == nolfh_size, "GlobalSize returned %Iu\n", size ); - else todo_wine_if(!flags) ok( size == nolfh_size + 512, "GlobalSize returned %Iu\n", size ); + else ok( size == nolfh_size + 512, "GlobalSize returned %Iu\n", size );
mem = GlobalFree( mem ); ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() ); @@ -1783,7 +1785,7 @@ static void test_GlobalAlloc(void) { ok( !is_mem_entry( tmp_mem ), "unexpected moveable %p\n", tmp_mem ); if (flags == GMEM_MODIFY) ok( tmp_mem == mem, "GlobalReAlloc returned %p\n", tmp_mem ); - else if (flags != GMEM_MOVEABLE) ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); + else if (flags != GMEM_MOVEABLE) todo_wine_if(!flags) ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); else todo_wine ok( tmp_mem != mem, "GlobalReAlloc returned %p\n", tmp_mem ); } else @@ -1798,7 +1800,7 @@ static void test_GlobalAlloc(void)
size = GlobalSize( mem ); if (flags == GMEM_MOVEABLE) ok( size == 10, "GlobalSize returned %Iu\n", size ); - else ok( size == small_size, "GlobalSize returned %Iu\n", size ); + else todo_wine_if(!flags) ok( size == small_size, "GlobalSize returned %Iu\n", size );
mem = GlobalFree( mem ); ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() ); @@ -1813,7 +1815,7 @@ static void test_GlobalAlloc(void) { ok( !is_mem_entry( tmp_mem ), "unexpected moveable %p\n", tmp_mem ); if (flags & GMEM_DISCARDABLE) ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); - else todo_wine_if(!flags) ok( tmp_mem == mem, "GlobalReAlloc returned %p\n", tmp_mem ); + else ok( tmp_mem == mem, "GlobalReAlloc returned %p\n", tmp_mem ); } else { @@ -1827,7 +1829,7 @@ static void test_GlobalAlloc(void)
size = GlobalSize( mem ); if (flags & (GMEM_MODIFY | GMEM_DISCARDABLE)) ok( size == nolfh_size, "GlobalSize returned %Iu\n", size ); - else todo_wine_if(!flags) ok( size == 10, "GlobalSize returned %Iu\n", size ); + else ok( size == 10, "GlobalSize returned %Iu\n", size );
mem = GlobalFree( mem ); ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() ); @@ -1842,7 +1844,7 @@ static void test_GlobalAlloc(void) { ok( !is_mem_entry( tmp_mem ), "unexpected moveable %p\n", tmp_mem ); if (flags == GMEM_MODIFY) ok( tmp_mem == mem, "GlobalReAlloc returned %p\n", tmp_mem ); - else if (flags != GMEM_MOVEABLE) ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); + else if (flags != GMEM_MOVEABLE) todo_wine_if(!flags) ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); else todo_wine ok( tmp_mem != mem, "GlobalReAlloc returned %p\n", tmp_mem ); } else @@ -1857,7 +1859,7 @@ static void test_GlobalAlloc(void)
size = GlobalSize( mem ); if (flags == GMEM_MOVEABLE) ok( size == 0 || broken( size == 1 ) /* w7 */, "GlobalSize returned %Iu\n", size ); - else ok( size == small_size, "GlobalSize returned %Iu\n", size ); + else todo_wine_if(!flags) ok( size == small_size, "GlobalSize returned %Iu\n", size );
mem = GlobalFree( mem ); ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() ); @@ -1872,7 +1874,7 @@ static void test_GlobalAlloc(void) { ok( !is_mem_entry( tmp_mem ), "unexpected moveable %p\n", tmp_mem ); if (flags & GMEM_DISCARDABLE) ok( !tmp_mem, "GlobalReAlloc succeeded\n" ); - else todo_wine_if(!flags) ok( tmp_mem == mem, "GlobalReAlloc returned %p\n", tmp_mem ); + else ok( tmp_mem == mem, "GlobalReAlloc returned %p\n", tmp_mem ); } else { @@ -1886,7 +1888,7 @@ static void test_GlobalAlloc(void)
size = GlobalSize( mem ); if (flags & (GMEM_MODIFY | GMEM_DISCARDABLE)) ok( size == nolfh_size, "GlobalSize returned %Iu\n", size ); - else todo_wine_if(!flags) ok( size == 0 || broken( size == 1 ) /* w7 */, "GlobalSize returned %Iu\n", size ); + else ok( size == 0 || broken( size == 1 ) /* w7 */, "GlobalSize returned %Iu\n", size );
mem = GlobalFree( mem ); ok( !mem, "GlobalFree failed, error %lu\n", GetLastError() ); @@ -2415,7 +2417,9 @@ static void test_LocalAlloc(void) ok( size == small_size, "LocalSize returned %Iu\n", size ); SetLastError( 0xdeadbeef ); tmp_mem = LocalReAlloc( mem, small_size, 0 ); + todo_wine ok( !tmp_mem, "LocalReAlloc succeeded\n" ); + todo_wine ok( GetLastError() == ERROR_NOT_ENOUGH_MEMORY, "got error %lu\n", GetLastError() ); if (tmp_mem) mem = tmp_mem; tmp_mem = LocalReAlloc( mem, 1024 * 1024, LMEM_MODIFY ); @@ -2475,10 +2479,10 @@ static void test_LocalAlloc(void) ok( !is_mem_entry( tmp_mem ), "unexpected moveable %p\n", tmp_mem ); if (flags & LMEM_MODIFY) ok( tmp_mem == mem, "LocalReAlloc returned %p\n", tmp_mem ); else if (flags & LMEM_DISCARDABLE) ok( !tmp_mem, "LocalReAlloc succeeded\n" ); - else todo_wine_if(!flags) ok( tmp_mem == mem, "LocalReAlloc returned %p\n", tmp_mem ); + else ok( tmp_mem == mem, "LocalReAlloc returned %p\n", tmp_mem ); size = LocalSize( mem ); if (flags & (LMEM_DISCARDABLE | LMEM_MODIFY)) ok( size == nolfh_size, "LocalSize returned %Iu\n", size ); - else todo_wine_if(!flags) ok( size == nolfh_size + 512, "LocalSize returned %Iu\n", size ); + else ok( size == nolfh_size + 512, "LocalSize returned %Iu\n", size ); mem = LocalFree( mem ); ok( !mem, "LocalFree failed, error %lu\n", GetLastError() );
@@ -2490,13 +2494,13 @@ static void test_LocalAlloc(void) tmp_mem = LocalReAlloc( mem, 10, flags ); ok( !is_mem_entry( tmp_mem ), "unexpected moveable %p\n", tmp_mem ); if (flags & LMEM_MODIFY) ok( tmp_mem == mem, "LocalReAlloc returned %p\n", tmp_mem ); - else if (flags != LMEM_MOVEABLE) ok( !tmp_mem, "LocalReAlloc succeeded\n" ); + else if (flags != LMEM_MOVEABLE) todo_wine_if(!flags) ok( !tmp_mem, "LocalReAlloc succeeded\n" ); else todo_wine ok( tmp_mem != mem, "LocalReAlloc returned %p\n", tmp_mem ); if (tmp_mem) mem = tmp_mem;
size = LocalSize( mem ); if (flags == LMEM_MOVEABLE) ok( size == 10, "LocalSize returned %Iu\n", size ); - else ok( size == small_size, "LocalSize returned %Iu\n", size ); + else todo_wine_if(!flags) ok( size == small_size, "LocalSize returned %Iu\n", size );
mem = LocalFree( mem ); ok( !mem, "LocalFree failed, error %lu\n", GetLastError() ); @@ -2509,10 +2513,10 @@ static void test_LocalAlloc(void) ok( !is_mem_entry( tmp_mem ), "unexpected moveable %p\n", tmp_mem ); if (flags & LMEM_MODIFY) ok( tmp_mem == mem, "LocalReAlloc returned %p\n", tmp_mem ); else if (flags & LMEM_DISCARDABLE) ok( !tmp_mem, "LocalReAlloc succeeded\n" ); - else todo_wine_if(!flags) ok( tmp_mem == mem, "LocalReAlloc returned %p\n", tmp_mem ); + else ok( tmp_mem == mem, "LocalReAlloc returned %p\n", tmp_mem ); size = LocalSize( mem ); if (flags & (LMEM_DISCARDABLE | LMEM_MODIFY)) ok( size == nolfh_size, "LocalSize returned %Iu\n", size ); - else todo_wine_if(!flags) ok( size == 10, "LocalSize returned %Iu\n", size ); + else ok( size == 10, "LocalSize returned %Iu\n", size ); mem = LocalFree( mem ); ok( !mem, "LocalFree failed, error %lu\n", GetLastError() );
@@ -2524,13 +2528,13 @@ static void test_LocalAlloc(void) tmp_mem = LocalReAlloc( mem, 0, flags ); ok( !is_mem_entry( tmp_mem ), "unexpected moveable %p\n", tmp_mem ); if (flags & LMEM_MODIFY) ok( tmp_mem == mem, "LocalReAlloc returned %p\n", tmp_mem ); - else if (flags != LMEM_MOVEABLE) ok( !tmp_mem, "LocalReAlloc succeeded\n" ); + else if (flags != LMEM_MOVEABLE) todo_wine_if(!flags) ok( !tmp_mem, "LocalReAlloc succeeded\n" ); else todo_wine ok( tmp_mem != mem, "LocalReAlloc returned %p\n", tmp_mem ); if (tmp_mem) mem = tmp_mem;
size = LocalSize( mem ); if (flags == LMEM_MOVEABLE) ok( size == 0 || broken( size == 1 ) /* w7 */, "LocalSize returned %Iu\n", size ); - else ok( size == small_size, "LocalSize returned %Iu\n", size ); + else todo_wine_if(!flags) ok( size == small_size, "LocalSize returned %Iu\n", size );
mem = LocalFree( mem ); ok( !mem, "LocalFree failed, error %lu\n", GetLastError() ); @@ -2543,10 +2547,10 @@ static void test_LocalAlloc(void) ok( !is_mem_entry( tmp_mem ), "unexpected moveable %p\n", tmp_mem ); if (flags & LMEM_MODIFY) ok( tmp_mem == mem, "LocalReAlloc returned %p\n", tmp_mem ); else if (flags & LMEM_DISCARDABLE) ok( !tmp_mem, "LocalReAlloc succeeded\n" ); - else todo_wine_if(!flags) ok( tmp_mem == mem, "LocalReAlloc returned %p\n", tmp_mem ); + else ok( tmp_mem == mem, "LocalReAlloc returned %p\n", tmp_mem ); size = LocalSize( mem ); if (flags & (LMEM_DISCARDABLE | LMEM_MODIFY)) ok( size == nolfh_size, "LocalSize returned %Iu\n", size ); - else todo_wine_if(!flags) ok( size == 0 || broken( size == 1 ) /* w7 */, "LocalSize returned %Iu\n", size ); + else ok( size == 0 || broken( size == 1 ) /* w7 */, "LocalSize returned %Iu\n", size ); mem = LocalFree( mem ); ok( !mem, "LocalFree failed, error %lu\n", GetLastError() );
diff --git a/dlls/kernelbase/memory.c b/dlls/kernelbase/memory.c index df7c07c2700..4bcd4a639f6 100644 --- a/dlls/kernelbase/memory.c +++ b/dlls/kernelbase/memory.c @@ -991,13 +991,13 @@ HLOCAL WINAPI DECLSPEC_HOTPATCH LocalReAlloc( HLOCAL handle, SIZE_T size, UINT f { if (flags & LMEM_MODIFY) ret = handle; else if (flags & LMEM_DISCARDABLE) SetLastError( ERROR_INVALID_PARAMETER ); - else if (flags & LMEM_MOVEABLE) + else { + if (!(flags & LMEM_MOVEABLE)) heap_flags |= HEAP_REALLOC_IN_PLACE_ONLY; ret = HeapReAlloc( heap, heap_flags, ptr, size ); if (ret) RtlSetUserValueHeap( heap, heap_flags, ret, ret ); else SetLastError( ERROR_NOT_ENOUGH_MEMORY ); } - else SetLastError( ERROR_NOT_ENOUGH_MEMORY ); } else if ((mem = unsafe_mem_from_HLOCAL( handle ))) {