Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/ntdll/heap.c | 82 +++++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 38 deletions(-)
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c index b84fa8dd42c..020176347e8 100644 --- a/dlls/ntdll/heap.c +++ b/dlls/ntdll/heap.c @@ -811,35 +811,41 @@ static BOOL validate_block_pointer( HEAP *heap, SUBHEAP **ret_subheap, const ARE return ret; }
-static BOOL heap_validate( HEAP *heapPtr, DWORD flags, LPCVOID block, BOOL quiet ) +static BOOL heap_validate_ptr( HEAP *heap, DWORD flags, const void *ptr, BOOL quiet ) { + const ARENA_INUSE *arena = (const ARENA_INUSE *)ptr - 1; + const ARENA_LARGE *large_arena; SUBHEAP *subheap; BOOL ret = FALSE; - const ARENA_LARGE *large_arena;
- heap_lock( heapPtr, flags ); + heap_lock( heap, flags );
- if (block) /* only check this single memory block */ + if (!(subheap = find_subheap( heap, arena )) || + ((const char *)arena < (char *)subheap->base + subheap->headerSize)) { - const ARENA_INUSE *arena = (const ARENA_INUSE *)block - 1; - - if (!(subheap = find_subheap( heapPtr, arena )) || - ((const char *)arena < (char *)subheap->base + subheap->headerSize)) + if (!(large_arena = find_large_block( heap, ptr ))) { - if (!(large_arena = find_large_block( heapPtr, block ))) - { - if (quiet == NOISY) - ERR("Heap %p: block %p is not inside heap\n", heapPtr, block ); - else if (WARN_ON(heap)) - WARN("Heap %p: block %p is not inside heap\n", heapPtr, block ); - } - else ret = validate_large_arena( heapPtr, large_arena, quiet ); + if (quiet == NOISY) ERR("heap %p, ptr %p is not inside heap\n", heap, ptr ); + else if (WARN_ON(heap)) WARN("heap %p, ptr %p is not inside heap\n", heap, ptr ); } - else ret = validate_used_block( subheap, arena, quiet ); - goto done; + else ret = validate_large_arena( heap, large_arena, quiet ); } + else ret = validate_used_block( subheap, arena, quiet );
- LIST_FOR_EACH_ENTRY( subheap, &heapPtr->subheap_list, SUBHEAP, entry ) + heap_unlock( heap, flags ); + + return ret; +} + +static BOOL heap_validate( HEAP *heap, DWORD flags, BOOL quiet ) +{ + const ARENA_LARGE *large_arena; + SUBHEAP *subheap; + BOOL ret = FALSE; + + heap_lock( heap, flags ); + + LIST_FOR_EACH_ENTRY( subheap, &heap->subheap_list, SUBHEAP, entry ) { char *ptr = (char *)subheap->base + subheap->headerSize; while (ptr < (char *)subheap->base + subheap->size) @@ -857,13 +863,14 @@ static BOOL heap_validate( HEAP *heapPtr, DWORD flags, LPCVOID block, BOOL quiet } }
- LIST_FOR_EACH_ENTRY( large_arena, &heapPtr->large_list, ARENA_LARGE, entry ) - if (!validate_large_arena( heapPtr, large_arena, quiet )) goto done; + LIST_FOR_EACH_ENTRY( large_arena, &heap->large_list, ARENA_LARGE, entry ) + if (!validate_large_arena( heap, large_arena, quiet )) goto done;
ret = TRUE;
done: - heap_unlock( heapPtr, flags ); + heap_unlock( heap, flags ); + return ret; }
@@ -883,7 +890,7 @@ static HEAP *HEAP_GetPtr( ERR("Invalid heap %p!\n", heap ); return NULL; } - if ((heapPtr->flags & HEAP_VALIDATE_ALL) && !heap_validate( heapPtr, 0, NULL, NOISY )) + if ((heapPtr->flags & HEAP_VALIDATE_ALL) && !heap_validate( heapPtr, 0, NOISY )) { if (TRACE_ON(heap)) { @@ -2013,23 +2020,22 @@ SIZE_T WINAPI RtlSizeHeap( HANDLE heap, ULONG flags, const void *ptr )
/*********************************************************************** * RtlValidateHeap (NTDLL.@) - * - * Determine if a block is a valid allocation from a heap. - * - * PARAMS - * heap [I] Heap that block was allocated from - * flags [I] HEAP_ flags from "winnt.h" - * ptr [I] Block to check - * - * RETURNS - * Success: TRUE. The block was allocated from heap. - * Failure: FALSE, if heap is invalid or ptr was not allocated from it. */ -BOOLEAN WINAPI RtlValidateHeap( HANDLE heap, ULONG flags, LPCVOID ptr ) +BOOLEAN WINAPI RtlValidateHeap( HANDLE heap, ULONG flags, const void *ptr ) { - HEAP *heapPtr = HEAP_GetPtr( heap ); - if (!heapPtr) return FALSE; - return heap_validate( heapPtr, flags, ptr, QUIET ); + HEAP *heapPtr; + BOOLEAN ret; + + if (!(heapPtr = HEAP_GetPtr( heap ))) + ret = FALSE; + else + { + if (ptr) ret = heap_validate_ptr( heapPtr, flags, ptr, QUIET ); + else ret = heap_validate( heapPtr, flags, QUIET ); + } + + TRACE( "heap %p, flags %#x, ptr %p, return %u\n", heapPtr, flags, ptr, ret ); + return ret; }