- Implement parameters validation ("DebugHeap") in all used RTL heap APIs. Winetests failures down to 4.

svn path=/trunk/; revision=49154
This commit is contained in:
Aleksey Bragin 2010-10-15 13:16:48 +00:00
parent 6fa23913f1
commit 7f8660190b
3 changed files with 504 additions and 39 deletions

View file

@ -322,6 +322,15 @@ RtlpCoalesceFreeBlocks (PHEAP Heap,
PHEAP_ENTRY_EXTRA NTAPI PHEAP_ENTRY_EXTRA NTAPI
RtlpGetExtraStuffPointer(PHEAP_ENTRY HeapEntry); RtlpGetExtraStuffPointer(PHEAP_ENTRY HeapEntry);
BOOLEAN NTAPI
RtlpValidateHeap(PHEAP Heap, BOOLEAN ForceValidation);
BOOLEAN NTAPI
RtlpValidateHeapEntry(PHEAP Heap, PHEAP_ENTRY HeapEntry);
BOOLEAN NTAPI
RtlpValidateHeapHeaders(PHEAP Heap, BOOLEAN Recalculate);
/* heapdbg.c */ /* heapdbg.c */
HANDLE NTAPI HANDLE NTAPI
RtlDebugCreateHeap(ULONG Flags, RtlDebugCreateHeap(ULONG Flags,
@ -331,7 +340,7 @@ RtlDebugCreateHeap(ULONG Flags,
PVOID Lock, PVOID Lock,
PRTL_HEAP_PARAMETERS Parameters); PRTL_HEAP_PARAMETERS Parameters);
HANDLE NTAPI BOOLEAN NTAPI
RtlDebugDestroyHeap(HANDLE HeapPtr); RtlDebugDestroyHeap(HANDLE HeapPtr);
PVOID NTAPI PVOID NTAPI

View file

@ -1476,23 +1476,9 @@ RtlCreateHeap(ULONG Flags,
TotalSize = ROUND_UP(CommitSize, 16 * PAGE_SIZE); TotalSize = ROUND_UP(CommitSize, 16 * PAGE_SIZE);
} }
if (RtlpGetMode() == UserMode) /* Call special heap */
{ if (RtlpHeapIsSpecial(Flags))
/* TODO: Here should be a call to special "Debug" heap, which does parameters validation, return RtlDebugCreateHeap(Flags, Addr, TotalSize, CommitSize, Lock, Parameters);
however we're just going to simulate setting correct flags here */
if (Flags & (HEAP_VALIDATE_ALL_ENABLED |
HEAP_VALIDATE_PARAMETERS_ENABLED |
HEAP_CAPTURE_STACK_BACKTRACES |
HEAP_FLAG_PAGE_ALLOCS |
HEAP_CREATE_ENABLE_TRACING) &&
!(Flags & HEAP_SKIP_VALIDATION_CHECKS))
{
// RtlDebugCreateHeap(Flags, Addr, TotalSize, CommitSize, Lock, Parameters);
Flags |= HEAP_SKIP_VALIDATION_CHECKS |
HEAP_TAIL_CHECKING_ENABLED |
HEAP_FREE_CHECKING_ENABLED;
}
}
/* Calculate header size */ /* Calculate header size */
HeaderSize = sizeof(HEAP); HeaderSize = sizeof(HEAP);
@ -1736,7 +1722,11 @@ RtlDestroyHeap(HANDLE HeapPtr) /* [in] Handle of heap */
if (!HeapPtr) return NULL; if (!HeapPtr) return NULL;
// TODO: Check for special heap /* Call special heap */
if (RtlpHeapIsSpecial(Heap->Flags))
{
if (!RtlDebugDestroyHeap(Heap)) return HeapPtr;
}
/* Check for a process heap */ /* Check for a process heap */
if (RtlpGetMode() == UserMode && if (RtlpGetMode() == UserMode &&
@ -2103,6 +2093,10 @@ RtlAllocateHeap(IN PVOID HeapPtr,
/* Force flags */ /* Force flags */
Flags |= Heap->ForceFlags; Flags |= Heap->ForceFlags;
/* Call special heap */
if (RtlpHeapIsSpecial(Flags))
return RtlDebugAllocateHeap(Heap, Flags, Size);
/* Check for the maximum size */ /* Check for the maximum size */
if (Size >= 0x80000000) if (Size >= 0x80000000)
{ {
@ -2111,14 +2105,10 @@ RtlAllocateHeap(IN PVOID HeapPtr,
return NULL; return NULL;
} }
if (Flags & ( if (Flags & (HEAP_CREATE_ENABLE_TRACING |
HEAP_VALIDATE_ALL_ENABLED | HEAP_CREATE_ALIGN_16))
HEAP_VALIDATE_PARAMETERS_ENABLED |
HEAP_FLAG_PAGE_ALLOCS |
HEAP_CREATE_ENABLE_TRACING |
HEAP_CREATE_ALIGN_16))
{ {
DPRINT("HEAP: RtlAllocateHeap is called with unsupported flags %x, ignoring\n", Flags); DPRINT1("HEAP: RtlAllocateHeap is called with unsupported flags %x, ignoring\n", Flags);
} }
//DPRINT("RtlAllocateHeap(%p %x %x)\n", Heap, Flags, Size); //DPRINT("RtlAllocateHeap(%p %x %x)\n", Heap, Flags, Size);
@ -2329,6 +2319,10 @@ BOOLEAN NTAPI RtlFreeHeap(
Heap = (PHEAP)HeapPtr; Heap = (PHEAP)HeapPtr;
Flags |= Heap->ForceFlags; Flags |= Heap->ForceFlags;
/* Call special heap */
if (RtlpHeapIsSpecial(Flags))
return RtlDebugFreeHeap(Heap, Flags, Ptr);
/* Lock if necessary */ /* Lock if necessary */
if (!(Flags & HEAP_NO_SERIALIZE)) if (!(Flags & HEAP_NO_SERIALIZE))
{ {
@ -2733,7 +2727,9 @@ RtlReAllocateHeap(HANDLE HeapPtr,
/* Force heap flags */ /* Force heap flags */
Flags |= Heap->ForceFlags; Flags |= Heap->ForceFlags;
// Check for special heap /* Call special heap */
if (RtlpHeapIsSpecial(Flags))
return RtlDebugReAllocateHeap(Heap, Flags, Ptr, Size);
/* Make sure size is valid */ /* Make sure size is valid */
if (Size >= 0x80000000) if (Size >= 0x80000000)
@ -3222,7 +3218,9 @@ RtlSizeHeap(
/* Force flags */ /* Force flags */
Flags |= Heap->Flags; Flags |= Heap->Flags;
// FIXME Special heap /* Call special heap */
if (RtlpHeapIsSpecial(Flags))
return RtlDebugSizeHeap(Heap, Flags, Ptr);
/* Get the heap entry pointer */ /* Get the heap entry pointer */
HeapEntry = (PHEAP_ENTRY)Ptr - 1; HeapEntry = (PHEAP_ENTRY)Ptr - 1;
@ -3825,6 +3823,10 @@ RtlSetUserValueHeap(IN PVOID HeapHandle,
/* Force flags */ /* Force flags */
Flags |= Heap->Flags; Flags |= Heap->Flags;
/* Call special heap */
if (RtlpHeapIsSpecial(Flags))
return RtlDebugSetUserValueHeap(Heap, Flags, BaseAddress, UserValue);
/* Lock if it's lockable */ /* Lock if it's lockable */
if (!(Heap->Flags & HEAP_NO_SERIALIZE)) if (!(Heap->Flags & HEAP_NO_SERIALIZE))
{ {
@ -3880,6 +3882,10 @@ RtlSetUserFlagsHeap(IN PVOID HeapHandle,
/* Force flags */ /* Force flags */
Flags |= Heap->Flags; Flags |= Heap->Flags;
/* Call special heap */
if (RtlpHeapIsSpecial(Flags))
return RtlDebugSetUserFlagsHeap(Heap, Flags, BaseAddress, UserFlagsReset, UserFlagsSet);
/* Lock if it's lockable */ /* Lock if it's lockable */
if (!(Heap->Flags & HEAP_NO_SERIALIZE)) if (!(Heap->Flags & HEAP_NO_SERIALIZE))
{ {
@ -3932,6 +3938,10 @@ RtlGetUserInfoHeap(IN PVOID HeapHandle,
/* Force flags */ /* Force flags */
Flags |= Heap->Flags; Flags |= Heap->Flags;
/* Call special heap */
if (RtlpHeapIsSpecial(Flags))
return RtlDebugGetUserInfoHeap(Heap, Flags, BaseAddress, UserValue, UserFlags);
/* Lock if it's lockable */ /* Lock if it's lockable */
if (!(Heap->Flags & HEAP_NO_SERIALIZE)) if (!(Heap->Flags & HEAP_NO_SERIALIZE))
{ {

View file

@ -25,18 +25,111 @@ WCHAR RtlpPageHeapTargetDlls[512];
HANDLE NTAPI HANDLE NTAPI
RtlDebugCreateHeap(ULONG Flags, RtlDebugCreateHeap(ULONG Flags,
PVOID Addr, PVOID Addr,
SIZE_T TotalSize, SIZE_T ReserveSize,
SIZE_T CommitSize, SIZE_T CommitSize,
PVOID Lock, PVOID Lock,
PRTL_HEAP_PARAMETERS Parameters) PRTL_HEAP_PARAMETERS Parameters)
{ {
return NULL; MEMORY_BASIC_INFORMATION MemoryInfo;
NTSTATUS Status;
PHEAP Heap;
/* Validate parameters */
if (ReserveSize <= HEAP_ENTRY_SIZE)
{
DPRINT1("HEAP: Incorrect ReserveSize %x\n", ReserveSize);
return NULL;
}
if (ReserveSize < CommitSize)
{
DPRINT1("HEAP: Incorrect CommitSize %x\n", CommitSize);
return NULL;
}
if (Flags & HEAP_NO_SERIALIZE && Lock)
{
DPRINT1("HEAP: Can't specify Lock routine and have HEAP_NO_SERIALIZE flag set\n");
return NULL;
}
/* If the address is specified, check it's virtual memory */
if (Addr)
{
Status = ZwQueryVirtualMemory(NtCurrentProcess(),
Addr,
MemoryBasicInformation,
&MemoryInfo,
sizeof(MemoryInfo),
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("HEAP: Specified heap base address %p is invalid, Status 0x%08X\n", Addr, Status);
return NULL;
}
if (MemoryInfo.BaseAddress != Addr)
{
DPRINT1("HEAP: Specified heap base address %p is not really a base one %p\n", Addr, MemoryInfo.BaseAddress);
return NULL;
}
if (MemoryInfo.State == MEM_FREE)
{
DPRINT1("HEAP: Specified heap base address %p is free\n", Addr);
return NULL;
}
}
/* All validation performed, now call the real routine with skip validation check flag */
Flags |= HEAP_SKIP_VALIDATION_CHECKS |
HEAP_TAIL_CHECKING_ENABLED |
HEAP_FREE_CHECKING_ENABLED;
Heap = RtlCreateHeap(Flags, Addr, ReserveSize, CommitSize, Lock, Parameters);
if (!Heap) return NULL;
// FIXME: Capture stack backtrace
RtlpValidateHeapHeaders(Heap, TRUE);
return Heap;
} }
HANDLE NTAPI BOOLEAN NTAPI
RtlDebugDestroyHeap(HANDLE HeapPtr) RtlDebugDestroyHeap(HANDLE HeapPtr)
{ {
return NULL; SIZE_T Size;
PHEAP Heap = (PHEAP)HeapPtr;
if (Heap == RtlGetCurrentPeb()->ProcessHeap)
{
DPRINT1("HEAP: It's forbidden delete process heap!");
return FALSE;
}
if (Heap->Signature != HEAP_SIGNATURE)
{
DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature);
return FALSE;
}
if (!RtlpValidateHeap(Heap, FALSE)) return FALSE;
/* Make heap invalid by zeroing its signature */
Heap->Signature = 0;
/* Free validate headers copy if it was existing */
if (Heap->HeaderValidateCopy)
{
ZwFreeVirtualMemory(NtCurrentProcess(),
&Heap->HeaderValidateCopy,
&Size,
MEM_RELEASE);
}
return TRUE;
} }
PVOID NTAPI PVOID NTAPI
@ -44,7 +137,64 @@ RtlDebugAllocateHeap(PVOID HeapPtr,
ULONG Flags, ULONG Flags,
SIZE_T Size) SIZE_T Size)
{ {
return NULL; PHEAP Heap = (PHEAP)HeapPtr;
SIZE_T AllocSize = 1;
BOOLEAN HeapLocked = FALSE;
PVOID Result;
//if (Heap->ForceFlags & HEAP_FLAG_PAGE_ALLOCS)
//return RtlpPageHeapAllocateHeap(HeapPtr, Flags, Size);
if (Heap->Signature != HEAP_SIGNATURE)
{
DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature);
return NULL;
}
/* Add settable user value flag */
Flags |= Heap->ForceFlags | HEAP_SETTABLE_USER_VALUE | HEAP_SKIP_VALIDATION_CHECKS;
/* Calculate size */
if (Size) AllocSize = Size;
AllocSize = ((AllocSize + Heap->AlignRound) & Heap->AlignMask) + sizeof(HEAP_ENTRY_EXTRA);
/* Check if size didn't exceed max one */
if (AllocSize < Size ||
AllocSize > Heap->MaximumAllocationSize)
{
DPRINT1("HEAP: Too big allocation size %x (max allowed %x)\n", Size, Heap->MaximumAllocationSize);
return NULL;
}
/* Lock the heap ourselves */
if (!(Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
HeapLocked = TRUE;
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
Flags |= HEAP_NO_SERIALIZE;
}
/* Validate the heap if necessary */
RtlpValidateHeap(Heap, FALSE);
/* Call main routine to do the stuff */
Result = RtlAllocateHeap(HeapPtr, Flags, Size);
/* Validate heap headers */
RtlpValidateHeapHeaders(Heap, TRUE);
if (Result)
{
if (Heap->Flags & HEAP_VALIDATE_ALL_ENABLED)
RtlpValidateHeap(Heap, FALSE);
}
/* Release the lock */
if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
return Result;
} }
PVOID NTAPI PVOID NTAPI
@ -53,7 +203,70 @@ RtlDebugReAllocateHeap(HANDLE HeapPtr,
PVOID Ptr, PVOID Ptr,
SIZE_T Size) SIZE_T Size)
{ {
return NULL; PHEAP Heap = (PHEAP)HeapPtr;
SIZE_T AllocSize = 1;
BOOLEAN HeapLocked = FALSE;
PVOID Result = NULL;
PHEAP_ENTRY HeapEntry;
//if (Heap->ForceFlags & HEAP_FLAG_PAGE_ALLOCS)
//return RtlpPageHeapReAllocateHeap(HeapPtr, Flags, Size);
if (Heap->Signature != HEAP_SIGNATURE)
{
DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature);
return NULL;
}
/* Add settable user value flag */
Flags |= Heap->ForceFlags | HEAP_SETTABLE_USER_VALUE | HEAP_SKIP_VALIDATION_CHECKS;
/* Calculate size */
if (Size) AllocSize = Size;
AllocSize = ((AllocSize + Heap->AlignRound) & Heap->AlignMask) + sizeof(HEAP_ENTRY_EXTRA);
/* Check if size didn't exceed max one */
if (AllocSize < Size ||
AllocSize > Heap->MaximumAllocationSize)
{
DPRINT1("HEAP: Too big allocation size %x (max allowed %x)\n", Size, Heap->MaximumAllocationSize);
return NULL;
}
/* Lock the heap ourselves */
if (!(Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
HeapLocked = TRUE;
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
Flags |= HEAP_NO_SERIALIZE;
}
/* Validate the heap if necessary */
RtlpValidateHeap(Heap, FALSE);
/* Get the existing heap entry */
HeapEntry = (PHEAP_ENTRY)Ptr - 1;
/* Validate it */
if (RtlpValidateHeapEntry(Heap, HeapEntry))
{
/* Call main routine to do the stuff */
Result = RtlReAllocateHeap(HeapPtr, Flags, Ptr, Size);
if (Result)
{
/* Validate heap headers and then heap itself */
RtlpValidateHeapHeaders(Heap, TRUE);
RtlpValidateHeap(Heap, FALSE);
}
}
/* Release the lock */
if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
return Result;
} }
BOOLEAN NTAPI BOOLEAN NTAPI
@ -61,7 +274,54 @@ RtlDebugFreeHeap(HANDLE HeapPtr,
ULONG Flags, ULONG Flags,
PVOID Ptr) PVOID Ptr)
{ {
return FALSE; PHEAP Heap = (PHEAP)HeapPtr;
BOOLEAN HeapLocked = FALSE;
PHEAP_ENTRY HeapEntry;
BOOLEAN Result = FALSE;
//if (Heap->ForceFlags & HEAP_FLAG_PAGE_ALLOCS)
//return RtlpPageHeapFreeHeap(HeapPtr, Flags, Size);
if (Heap->Signature != HEAP_SIGNATURE)
{
DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature);
return FALSE;
}
/* Add skip validation flag */
Flags |= Heap->ForceFlags | HEAP_SKIP_VALIDATION_CHECKS;
/* Lock the heap ourselves */
if (!(Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
HeapLocked = TRUE;
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
Flags |= HEAP_NO_SERIALIZE;
}
/* Validate the heap if necessary */
RtlpValidateHeap(Heap, FALSE);
/* Get the existing heap entry */
HeapEntry = (PHEAP_ENTRY)Ptr - 1;
/* Validate it */
if (RtlpValidateHeapEntry(Heap, HeapEntry))
{
/* If it succeeded - call the main routine */
Result = RtlFreeHeap(HeapPtr, Flags, Ptr);
/* Validate heap headers and then heap itself */
RtlpValidateHeapHeaders(Heap, TRUE);
RtlpValidateHeap(Heap, FALSE);
}
/* Release the lock */
if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
return Result;
} }
BOOLEAN NTAPI BOOLEAN NTAPI
@ -71,7 +331,50 @@ RtlDebugGetUserInfoHeap(PVOID HeapHandle,
PVOID *UserValue, PVOID *UserValue,
PULONG UserFlags) PULONG UserFlags)
{ {
return FALSE; PHEAP Heap = (PHEAP)HeapHandle;
BOOLEAN HeapLocked = FALSE;
PHEAP_ENTRY HeapEntry;
BOOLEAN Result = FALSE;
//if (Heap->ForceFlags & HEAP_FLAG_PAGE_ALLOCS)
//return RtlpPageHeapGetUserInfoHeap(HeapPtr, Flags, Size);
if (Heap->Signature != HEAP_SIGNATURE)
{
DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature);
return FALSE;
}
/* Add skip validation flag */
Flags |= Heap->ForceFlags | HEAP_SKIP_VALIDATION_CHECKS;
/* Lock the heap ourselves */
if (!(Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
HeapLocked = TRUE;
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
Flags |= HEAP_NO_SERIALIZE;
}
/* Validate the heap if necessary */
RtlpValidateHeap(Heap, FALSE);
/* Get the existing heap entry */
HeapEntry = (PHEAP_ENTRY)BaseAddress - 1;
/* Validate it */
if (RtlpValidateHeapEntry(Heap, HeapEntry))
{
/* If it succeeded - call the main routine */
Result = RtlGetUserInfoHeap(HeapHandle, Flags, BaseAddress, UserValue, UserFlags);
}
/* Release the lock */
if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
return Result;
} }
BOOLEAN NTAPI BOOLEAN NTAPI
@ -80,7 +383,53 @@ RtlDebugSetUserValueHeap(PVOID HeapHandle,
PVOID BaseAddress, PVOID BaseAddress,
PVOID UserValue) PVOID UserValue)
{ {
return FALSE; PHEAP Heap = (PHEAP)HeapHandle;
BOOLEAN HeapLocked = FALSE;
PHEAP_ENTRY HeapEntry;
BOOLEAN Result = FALSE;
//if (Heap->ForceFlags & HEAP_FLAG_PAGE_ALLOCS)
//return RtlpPageHeapSetUserValueHeap(HeapPtr, Flags, Size);
if (Heap->Signature != HEAP_SIGNATURE)
{
DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature);
return FALSE;
}
/* Add skip validation flag */
Flags |= Heap->ForceFlags | HEAP_SKIP_VALIDATION_CHECKS;
/* Lock the heap ourselves */
if (!(Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
HeapLocked = TRUE;
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
Flags |= HEAP_NO_SERIALIZE;
}
/* Validate the heap if necessary */
RtlpValidateHeap(Heap, FALSE);
/* Get the existing heap entry */
HeapEntry = (PHEAP_ENTRY)BaseAddress - 1;
/* Validate it */
if (RtlpValidateHeapEntry(Heap, HeapEntry))
{
/* If it succeeded - call the main routine */
Result = RtlSetUserValueHeap(HeapHandle, Flags, BaseAddress, UserValue);
/* Validate the heap */
RtlpValidateHeap(Heap, FALSE);
}
/* Release the lock */
if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
return Result;
} }
BOOLEAN BOOLEAN
@ -91,7 +440,60 @@ RtlDebugSetUserFlagsHeap(PVOID HeapHandle,
ULONG UserFlagsReset, ULONG UserFlagsReset,
ULONG UserFlagsSet) ULONG UserFlagsSet)
{ {
return FALSE; PHEAP Heap = (PHEAP)HeapHandle;
BOOLEAN HeapLocked = FALSE;
PHEAP_ENTRY HeapEntry;
BOOLEAN Result = FALSE;
//if (Heap->ForceFlags & HEAP_FLAG_PAGE_ALLOCS)
//return RtlPageHeapSetUserFlagsHeap(HeapPtr, Flags, BaseAddress, UserFlagsReset, UserFlagsSet);
/* Check if this heap allows flags to be set at all */
if (UserFlagsSet & ~HEAP_SETTABLE_USER_FLAGS ||
UserFlagsReset & ~HEAP_SETTABLE_USER_FLAGS)
{
return FALSE;
}
if (Heap->Signature != HEAP_SIGNATURE)
{
DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature);
return FALSE;
}
/* Add skip validation flag */
Flags |= Heap->ForceFlags | HEAP_SKIP_VALIDATION_CHECKS;
/* Lock the heap ourselves */
if (!(Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
HeapLocked = TRUE;
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
Flags |= HEAP_NO_SERIALIZE;
}
/* Validate the heap if necessary */
RtlpValidateHeap(Heap, FALSE);
/* Get the existing heap entry */
HeapEntry = (PHEAP_ENTRY)BaseAddress - 1;
/* Validate it */
if (RtlpValidateHeapEntry(Heap, HeapEntry))
{
/* If it succeeded - call the main routine */
Result = RtlSetUserFlagsHeap(HeapHandle, Flags, BaseAddress, UserFlagsReset, UserFlagsSet);
/* Validate the heap */
RtlpValidateHeap(Heap, FALSE);
}
/* Release the lock */
if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
return Result;
} }
SIZE_T NTAPI SIZE_T NTAPI
@ -99,7 +501,51 @@ RtlDebugSizeHeap(HANDLE HeapPtr,
ULONG Flags, ULONG Flags,
PVOID Ptr) PVOID Ptr)
{ {
return 0; PHEAP Heap = (PHEAP)HeapPtr;
BOOLEAN HeapLocked = FALSE;
PHEAP_ENTRY HeapEntry;
SIZE_T Result = ~(SIZE_T)0;
//if (Heap->ForceFlags & HEAP_FLAG_PAGE_ALLOCS)
//return RtlPageHeapSizeHeap(HeapPtr, Flags, Ptr);
/* Check heap signature */
if (Heap->Signature != HEAP_SIGNATURE)
{
DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature);
return FALSE;
}
/* Add skip validation flag */
Flags |= Heap->ForceFlags | HEAP_SKIP_VALIDATION_CHECKS;
/* Lock the heap ourselves */
if (!(Flags & HEAP_NO_SERIALIZE))
{
RtlEnterHeapLock(Heap->LockVariable);
HeapLocked = TRUE;
/* Add no serialize flag so that the main routine won't try to acquire the lock again */
Flags |= HEAP_NO_SERIALIZE;
}
/* Validate the heap if necessary */
RtlpValidateHeap(Heap, FALSE);
/* Get the existing heap entry */
HeapEntry = (PHEAP_ENTRY)Ptr - 1;
/* Validate it */
if (RtlpValidateHeapEntry(Heap, HeapEntry))
{
/* If it succeeded - call the main routine */
Result = RtlSizeHeap(HeapPtr, Flags, Ptr);
}
/* Release the lock */
if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
return Result;
} }