mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
[HEAP]
- 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:
parent
6fa23913f1
commit
7f8660190b
3 changed files with 504 additions and 39 deletions
|
@ -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
|
||||||
|
|
|
@ -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))
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue