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 | 71 +++++++++++++++----------------------- 2 files changed, 30 insertions(+), 43 deletions(-)
diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c index 92e90b56deb..45a22adcf2e 100644 --- a/dlls/kernel32/tests/heap.c +++ b/dlls/kernel32/tests/heap.c @@ -229,6 +229,8 @@ static void test_HeapCreate(void)
/* test some border cases */
+ ret = HeapFree( NULL, 0, NULL ); + ok( ret, "HeapFree failed, error %lu\n", GetLastError() ); ret = HeapFree( heap, 0, NULL ); ok( ret, "HeapFree failed, error %lu\n", GetLastError() ); #if 0 /* crashes */ diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c index f3dd6ab6c67..1a4d5b1a2bb 100644 --- a/dlls/ntdll/heap.c +++ b/dlls/ntdll/heap.c @@ -1725,60 +1725,45 @@ void *WINAPI DECLSPEC_HOTPATCH RtlAllocateHeap( HANDLE heap, ULONG flags, SIZE_T }
-/*********************************************************************** - * RtlFreeHeap (NTDLL.@) - * - * Free a memory block allocated with RtlAllocateHeap(). - * - * PARAMS - * heap [I] Heap that block was allocated from - * flags [I] HEAP_ flags from "winnt.h" - * ptr [I] Block to free - * - * RETURNS - * Success: TRUE, if ptr is NULL or was freed successfully. - * Failure: FALSE. - */ -BOOLEAN WINAPI DECLSPEC_HOTPATCH RtlFreeHeap( HANDLE heap, ULONG flags, void *ptr ) +static NTSTATUS heap_free( HEAP *heap, void *ptr ) { - ARENA_INUSE *pInUse; + ARENA_INUSE *block; SUBHEAP *subheap; - HEAP *heapPtr;
- /* Validate the parameters */ + /* Inform valgrind we are trying to free memory, so it can throw up an error message */ + notify_free( ptr );
- if (!ptr) return TRUE; /* freeing a NULL ptr isn't an error in Win2k */ + block = (ARENA_INUSE *)ptr - 1; + if (!validate_block_pointer( heap, &subheap, block )) return STATUS_INVALID_PARAMETER;
- heapPtr = HEAP_GetPtr( heap ); - if (!heapPtr) - { - RtlSetLastWin32ErrorAndNtStatusFromNtStatus( STATUS_INVALID_HANDLE ); - return FALSE; - } + if (!subheap) free_large_block( heap, ptr ); + else HEAP_MakeInUseBlockFree( subheap, block );
- heap_lock( heapPtr, flags ); + return STATUS_SUCCESS; +}
- /* Inform valgrind we are trying to free memory, so it can throw up an error message */ - notify_free( ptr ); +/*********************************************************************** + * RtlFreeHeap (NTDLL.@) + */ +BOOLEAN WINAPI DECLSPEC_HOTPATCH RtlFreeHeap( HANDLE heap, ULONG flags, void *ptr ) +{ + NTSTATUS status; + HEAP *heapPtr;
- /* Some sanity checks */ - pInUse = (ARENA_INUSE *)ptr - 1; - if (!validate_block_pointer( heapPtr, &subheap, pInUse )) goto error; + if (!ptr) return TRUE;
- if (!subheap) - free_large_block( heapPtr, ptr ); + if (!(heapPtr = HEAP_GetPtr( heap ))) + status = STATUS_INVALID_PARAMETER; else - HEAP_MakeInUseBlockFree( subheap, pInUse ); - - heap_unlock( heapPtr, flags ); - TRACE("(%p,%08x,%p): returning TRUE\n", heap, flags, ptr ); - return TRUE; + { + heap_lock( heapPtr, flags ); + status = heap_free( heapPtr, ptr ); + heap_unlock( heapPtr, flags ); + }
-error: - heap_unlock( heapPtr, flags ); - RtlSetLastWin32ErrorAndNtStatusFromNtStatus( STATUS_INVALID_PARAMETER ); - TRACE("(%p,%08x,%p): returning FALSE\n", heap, flags, ptr ); - return FALSE; + TRACE( "heap %p, flags %#x, ptr %p, return %u, status %#x.\n", heap, flags, ptr, !status, status ); + heap_set_status( heapPtr, flags, status ); + return !status; }