From cf9f185901f5f0718e6e59e3ad3545f4b497e622 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 13 Sep 2016 20:48:08 +0900 Subject: [PATCH] kernel32: GMEM_FIXED blocks cannot be 0 size. Signed-off-by: Alexandre Julliard --- dlls/kernel32/heap.c | 16 +++++++++++----- dlls/kernel32/tests/heap.c | 13 +++++++++++++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/dlls/kernel32/heap.c b/dlls/kernel32/heap.c index fffd0e4e7ce..49cb027d2ec 100644 --- a/dlls/kernel32/heap.c +++ b/dlls/kernel32/heap.c @@ -362,7 +362,7 @@ HGLOBAL WINAPI GlobalAlloc( if((flags & GMEM_MOVEABLE)==0) /* POINTER */ { - palloc=HeapAlloc(GetProcessHeap(), hpflags, size); + palloc = HeapAlloc( GetProcessHeap(), hpflags, max( 1, size )); TRACE( "(flags=%04x) returning %p\n", flags, palloc ); return palloc; } @@ -961,10 +961,16 @@ SIZE_T WINAPI GlobalCompact( DWORD minfree ) * Windows memory management does not provide a separate local heap * and global heap. */ -HLOCAL WINAPI LocalAlloc( - UINT flags, /* [in] Allocation attributes */ - SIZE_T size /* [in] Number of bytes to allocate */ -) { +HLOCAL WINAPI LocalAlloc( UINT flags, SIZE_T size ) +{ + /* LocalAlloc allows a 0-size fixed block, but GlobalAlloc doesn't */ + if (!(flags & LMEM_MOVEABLE)) + { + DWORD heap_flags = (flags & LMEM_ZEROINIT) ? HEAP_ZERO_MEMORY : 0; + void *ret = HeapAlloc( GetProcessHeap(), heap_flags, size ); + TRACE( "(flags=%04x) returning %p\n", flags, ret ); + return ret; + } return GlobalAlloc( flags, size ); } diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c index b656dc226e6..2f7edc823c0 100644 --- a/dlls/kernel32/tests/heap.c +++ b/dlls/kernel32/tests/heap.c @@ -306,6 +306,12 @@ static void test_heap(void) "Expected ERROR_INVALID_HANDLE or ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); } + gbl = GlobalAlloc( GMEM_FIXED, 0 ); + SetLastError(0xdeadbeef); + size = GlobalSize( gbl ); + ok( size == 1, "wrong size %lu\n", size ); + GlobalFree( gbl ); + /* ####################################### */ /* Local*() functions */ gbl = LocalAlloc(LMEM_MOVEABLE, 0); @@ -438,6 +444,13 @@ static void test_heap(void) broken(GetLastError() == 0xdeadbeef) /* win9x */, "got %d\n", GetLastError()); LocalFree(gbl); + gbl = LocalAlloc( LMEM_FIXED, 0 ); + SetLastError(0xdeadbeef); + size = LocalSize( gbl ); + ok( !size || broken(size == 1), /* vistau64 */ + "wrong size %lu\n", size ); + LocalFree( gbl ); + /* trying to lock empty memory should give an error */ gbl = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,0); ok(gbl != NULL, "returned NULL\n"); -- 2.11.4.GIT