Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

heapdbg.c File Reference

#include "ntrtlp.h"
#include "heap.h"
#include "heappriv.h"

Go to the source code of this file.

Functions

VOID RtlpUpdateHeapListIndex (USHORT OldIndex, USHORT NewIndex)
BOOLEAN RtlpValidateHeapHeaders (IN PHEAP Heap, IN BOOLEAN Recompute)
PVOID RtlDebugCreateHeap (IN ULONG Flags, IN PVOID HeapBase OPTIONAL, IN SIZE_T ReserveSize OPTIONAL, IN SIZE_T CommitSize OPTIONAL, IN PVOID Lock OPTIONAL, IN PRTL_HEAP_PARAMETERS Parameters)
BOOLEAN RtlpSerializeHeap (IN PVOID HeapHandle)
BOOLEAN RtlDebugDestroyHeap (IN PVOID HeapHandle)
PVOID RtlDebugAllocateHeap (IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
PVOID RtlDebugReAllocateHeap (IN PVOID HeapHandle, IN ULONG Flags, IN PVOID BaseAddress, IN SIZE_T Size)
BOOLEAN RtlDebugFreeHeap (IN PVOID HeapHandle, IN ULONG Flags, IN PVOID BaseAddress)
BOOLEAN RtlDebugGetUserInfoHeap (IN PVOID HeapHandle, IN ULONG Flags, IN PVOID BaseAddress, OUT PVOID *UserValue OPTIONAL, OUT PULONG UserFlags OPTIONAL)
BOOLEAN RtlDebugSetUserValueHeap (IN PVOID HeapHandle, IN ULONG Flags, IN PVOID BaseAddress, IN PVOID UserValue)
BOOLEAN RtlDebugSetUserFlagsHeap (IN PVOID HeapHandle, IN ULONG Flags, IN PVOID BaseAddress, IN ULONG UserFlagsReset, IN ULONG UserFlagsSet)
SIZE_T RtlDebugSizeHeap (IN PVOID HeapHandle, IN ULONG Flags, IN PVOID BaseAddress)
SIZE_T RtlDebugCompactHeap (IN PVOID HeapHandle, IN ULONG Flags)
NTSTATUS RtlDebugZeroHeap (IN PVOID HeapHandle, IN ULONG Flags)
NTSTATUS RtlDebugCreateTagHeap (IN PVOID HeapHandle, IN ULONG Flags, IN PWSTR TagPrefix OPTIONAL, IN PWSTR TagNames)
NTSYSAPI PWSTR NTAPI RtlDebugQueryTagHeap (IN PVOID HeapHandle, IN ULONG Flags, IN USHORT TagIndex, IN BOOLEAN ResetCounters, OUT PRTL_HEAP_TAG_INFO TagInfo OPTIONAL)
NTSTATUS RtlDebugUsageHeap (IN PVOID HeapHandle, IN ULONG Flags, IN OUT PRTL_HEAP_USAGE Usage)
BOOLEAN RtlDebugWalkHeap (IN PVOID HeapHandle, IN OUT PRTL_HEAP_WALK_ENTRY Entry)
BOOLEAN RtlpValidateHeapEntry (IN PHEAP Heap, IN PHEAP_ENTRY BusyBlock, IN PCHAR Reason)
BOOLEAN RtlpValidateHeapSegment (IN PHEAP Heap, IN PHEAP_SEGMENT Segment, IN UCHAR SegmentIndex, IN OUT PULONG CountOfFreeBlocks, IN OUT PSIZE_T TotalFreeSize, OUT PVOID *BadAddress, IN OUT PSIZE_T ComputedTagEntries, IN OUT PSIZE_T ComputedPseudoTagEntries)
BOOLEAN RtlpValidateHeap (IN PHEAP Heap, IN BOOLEAN AlwaysValidate)
VOID RtlpBreakPointHeap (IN PVOID BadAddress)

Variables

BOOLEAN RtlpValidateHeapHdrsEnable = FALSE
BOOLEAN RtlpValidateHeapTagsEnable
HEAP_STOP_ON_VALUES RtlpHeapStopOn
struct {
   ULONG   Offset
   LPSTR   Description
RtlpHeapHeaderFieldOffsets []
BOOLEAN RtlpHeapInvalidBreakPoint
PVOID RtlpHeapInvalidBadAddress


Function Documentation

PVOID RtlDebugAllocateHeap IN PVOID  HeapHandle,
IN ULONG  Flags,
IN SIZE_T  Size
 

Definition at line 444 of file heapdbg.c.

References _HEAP::AlignMask, _HEAP::AlignRound, _HEAP_STOP_ON_VALUES::AllocAddress, _HEAP_ENTRY_EXTRA::AllocatorBackTraceIndex, _HEAP_STOP_ON_VALUES::AllocTag, EXCEPTION_CONTINUE_SEARCH, EXCEPTION_EXECUTE_HANDLER, FALSE, _HEAP::Flags, _HEAP_ENTRY::Flags, _HEAP::ForceFlags, HEAP_CAPTURE_STACK_BACKTRACES, HEAP_ENTRY_EXTRA_PRESENT, HEAP_SKIP_VALIDATION_CHECKS, HEAP_VALIDATE_ALL_ENABLED, HeapDebugBreak, HeapDebugPrint, HeapHandle, _HEAP_STOP_ON_TAG::HeapIndex, IF_DEBUG_PAGE_HEAP_THEN_RETURN, IS_HEAP_TAGGING_ENABLED, _HEAP::LockVariable, _HEAP::MaximumAllocationSize, NULL, _HEAP::ProcessHeapsListIndex, RtlAcquireLockRoutine, RtlAllocateHeapSlowly(), RtlpCheckHeapSignature(), RtlpDebugPageHeapAllocate(), RtlpGetExtraStuffPointer(), RtlpGetTagName(), RtlpHeapStopOn, RtlpValidateHeap(), RtlpValidateHeapHeaders(), RtlReleaseLockRoutine, SET_LAST_STATUS, Size, _HEAP_ENTRY::SmallTagIndex, _HEAP_STOP_ON_TAG::TagIndex, _HEAP_ENTRY_EXTRA::TagIndex, TRUE, and USHORT.

Referenced by RtlAllocateHeapSlowly().

00452 : 00453 00454 Arguments: 00455 00456 Return Value: 00457 00458 --*/ 00459 00460 { 00461 PHEAP Heap = (PHEAP)HeapHandle; 00462 BOOLEAN LockAcquired = FALSE; 00463 PVOID ReturnValue = NULL; 00464 SIZE_T AllocationSize; 00465 USHORT TagIndex; 00466 PHEAP_ENTRY BusyBlock; 00467 PHEAP_ENTRY_EXTRA ExtraStuff; 00468 00469 IF_DEBUG_PAGE_HEAP_THEN_RETURN( HeapHandle, 00470 RtlpDebugPageHeapAllocate( HeapHandle, Flags, Size )); 00471 00472 try { 00473 00474 try { 00475 00476 // 00477 // Validate that HeapAddress points to a HEAP structure. 00478 // 00479 00480 if (!RtlpCheckHeapSignature( Heap, "RtlAllocateHeap" )) { 00481 00482 ReturnValue = NULL; 00483 leave; 00484 } 00485 00486 Flags |= Heap->ForceFlags | HEAP_SETTABLE_USER_VALUE | HEAP_SKIP_VALIDATION_CHECKS; 00487 00488 // 00489 // Verify that the size did not wrap or exceed the limit for this heap. 00490 // 00491 00492 AllocationSize = (((Size ? Size : 1) + Heap->AlignRound) & Heap->AlignMask) + 00493 sizeof( HEAP_ENTRY_EXTRA ); 00494 00495 if ((AllocationSize < Size) || (AllocationSize > Heap->MaximumAllocationSize)) { 00496 00497 HeapDebugPrint(( "Invalid allocation size - %lx (exceeded %x)\n", 00498 Size, 00499 Heap->MaximumAllocationSize )); 00500 00501 ReturnValue = NULL; 00502 leave; 00503 } 00504 00505 // 00506 // Lock the heap 00507 // 00508 00509 if (!(Flags & HEAP_NO_SERIALIZE)) { 00510 00511 RtlAcquireLockRoutine( Heap->LockVariable ); 00512 00513 LockAcquired = TRUE; 00514 00515 Flags |= HEAP_NO_SERIALIZE; 00516 } 00517 00518 RtlpValidateHeap( Heap, FALSE ); 00519 00520 ReturnValue = RtlAllocateHeapSlowly( HeapHandle, Flags, Size ); 00521 00522 RtlpValidateHeapHeaders( Heap, TRUE ); 00523 00524 if (ReturnValue != NULL) { 00525 00526 BusyBlock = (PHEAP_ENTRY)ReturnValue - 1; 00527 00528 if (BusyBlock->Flags & HEAP_ENTRY_EXTRA_PRESENT) { 00529 00530 ExtraStuff = RtlpGetExtraStuffPointer( BusyBlock ); 00531 00532 #if i386 00533 00534 if (Heap->Flags & HEAP_CAPTURE_STACK_BACKTRACES) { 00535 00536 ExtraStuff->AllocatorBackTraceIndex = (USHORT)RtlLogStackBackTrace(); 00537 00538 } else { 00539 00540 ExtraStuff->AllocatorBackTraceIndex = 0; 00541 } 00542 00543 #endif // i386 00544 00545 TagIndex = ExtraStuff->TagIndex; 00546 00547 } else { 00548 00549 TagIndex = BusyBlock->SmallTagIndex; 00550 } 00551 00552 if (Heap->Flags & HEAP_VALIDATE_ALL_ENABLED) { 00553 00554 RtlpValidateHeap( Heap, FALSE ); 00555 } 00556 } 00557 00558 if (ReturnValue != NULL) { 00559 00560 if ((ULONG_PTR)ReturnValue == RtlpHeapStopOn.AllocAddress) { 00561 00562 HeapDebugPrint(( "Just allocated block at %lx for 0x%x bytes\n", 00563 RtlpHeapStopOn.AllocAddress, 00564 Size )); 00565 00566 HeapDebugBreak( NULL ); 00567 00568 } else if ((IS_HEAP_TAGGING_ENABLED()) && 00569 (TagIndex != 0) && 00570 (TagIndex == RtlpHeapStopOn.AllocTag.TagIndex) && 00571 (Heap->ProcessHeapsListIndex == RtlpHeapStopOn.AllocTag.HeapIndex)) { 00572 00573 HeapDebugPrint(( "Just allocated block at %lx for 0x%x bytes with tag %ws\n", 00574 ReturnValue, 00575 Size, 00576 RtlpGetTagName( Heap, TagIndex ))); 00577 00578 HeapDebugBreak( NULL ); 00579 } 00580 } 00581 00582 } except( GetExceptionCode() == STATUS_NO_MEMORY ? EXCEPTION_CONTINUE_SEARCH : 00583 EXCEPTION_EXECUTE_HANDLER ) { 00584 00585 SET_LAST_STATUS( GetExceptionCode() ); 00586 00587 ReturnValue = NULL; 00588 } 00589 00590 } finally { 00591 00592 if (LockAcquired) { 00593 00594 RtlReleaseLockRoutine( Heap->LockVariable ); 00595 } 00596 } 00597 00598 return ReturnValue; 00599 }

SIZE_T RtlDebugCompactHeap IN PVOID  HeapHandle,
IN ULONG  Flags
 

Definition at line 1260 of file heapdbg.c.

References EXCEPTION_EXECUTE_HANDLER, FALSE, _HEAP::ForceFlags, HEAP_SKIP_VALIDATION_CHECKS, HeapHandle, IF_DEBUG_PAGE_HEAP_THEN_RETURN, _HEAP::LockVariable, RtlAcquireLockRoutine, RtlCompactHeap(), RtlpCheckHeapSignature(), RtlpDebugPageHeapCompact(), RtlpValidateHeap(), RtlpValidateHeapHeaders(), RtlReleaseLockRoutine, SET_LAST_STATUS, and TRUE.

Referenced by RtlCompactHeap().

01267 : 01268 01269 Arguments: 01270 01271 Return Value: 01272 01273 --*/ 01274 01275 { 01276 PHEAP Heap = (PHEAP)HeapHandle; 01277 BOOLEAN LockAcquired = FALSE; 01278 SIZE_T LargestFreeSize; 01279 01280 IF_DEBUG_PAGE_HEAP_THEN_RETURN( HeapHandle, 01281 RtlpDebugPageHeapCompact( HeapHandle, Flags )); 01282 01283 LargestFreeSize = 0; 01284 01285 try { 01286 01287 try { 01288 01289 // 01290 // Validate that HeapAddress points to a HEAP structure. 01291 // 01292 01293 if (!RtlpCheckHeapSignature( Heap, "RtlCompactHeap" )) { 01294 01295 LargestFreeSize = 0; 01296 leave; 01297 } 01298 01299 Flags |= Heap->ForceFlags | HEAP_SKIP_VALIDATION_CHECKS; 01300 01301 // 01302 // Lock the heap 01303 // 01304 01305 if (!(Flags & HEAP_NO_SERIALIZE)) { 01306 01307 RtlAcquireLockRoutine( Heap->LockVariable ); 01308 01309 LockAcquired = TRUE; 01310 01311 Flags |= HEAP_NO_SERIALIZE; 01312 } 01313 01314 RtlpValidateHeap( Heap, FALSE ); 01315 01316 LargestFreeSize = RtlCompactHeap( HeapHandle, Flags ); 01317 01318 RtlpValidateHeapHeaders( Heap, TRUE ); 01319 01320 } except( EXCEPTION_EXECUTE_HANDLER ) { 01321 01322 SET_LAST_STATUS( GetExceptionCode() ); 01323 } 01324 01325 } finally { 01326 01327 if (LockAcquired) { 01328 01329 RtlReleaseLockRoutine( Heap->LockVariable ); 01330 } 01331 } 01332 01333 return LargestFreeSize; 01334 }

PVOID RtlDebugCreateHeap IN ULONG  Flags,
IN PVOID HeapBase  OPTIONAL,
IN SIZE_T ReserveSize  OPTIONAL,
IN SIZE_T CommitSize  OPTIONAL,
IN PVOID Lock  OPTIONAL,
IN PRTL_HEAP_PARAMETERS  Parameters
 

Definition at line 204 of file heapdbg.c.

References _HEAP::AllocatorBackTraceIndex, _HEAP::Flags, HEAP_CAPTURE_STACK_BACKTRACES, HEAP_SKIP_VALIDATION_CHECKS, HeapDebugBreak, HeapDebugPrint, Lock, NT_SUCCESS, NtQueryVirtualMemory(), NTSTATUS(), NULL, RtlCreateHeap(), RtlpValidateHeapHeaders(), Status, TRUE, and USHORT.

Referenced by RtlCreateHeap().

00215 : 00216 00217 Arguments: 00218 00219 Return Value: 00220 00221 --*/ 00222 00223 { 00224 PHEAP Heap; 00225 NTSTATUS Status; 00226 MEMORY_BASIC_INFORMATION MemoryInformation; 00227 00228 if (ReserveSize <= sizeof( HEAP_ENTRY )) { 00229 00230 HeapDebugPrint(( "Invalid ReserveSize parameter - %lx\n", ReserveSize )); 00231 HeapDebugBreak( NULL ); 00232 00233 return NULL; 00234 } 00235 00236 if (ReserveSize < CommitSize) { 00237 00238 HeapDebugPrint(( "Invalid CommitSize parameter - %lx\n", CommitSize )); 00239 HeapDebugBreak( NULL ); 00240 00241 return NULL; 00242 } 00243 00244 if ((Flags & HEAP_NO_SERIALIZE) && ARGUMENT_PRESENT( Lock )) { 00245 00246 HeapDebugPrint(( "May not specify Lock parameter with HEAP_NO_SERIALIZE\n" )); 00247 HeapDebugBreak( NULL ); 00248 00249 return NULL; 00250 } 00251 00252 if (ARGUMENT_PRESENT( HeapBase )) { 00253 00254 Status = NtQueryVirtualMemory( NtCurrentProcess(), 00255 HeapBase, 00256 MemoryBasicInformation, 00257 &MemoryInformation, 00258 sizeof( MemoryInformation ), 00259 NULL ); 00260 00261 if (!NT_SUCCESS( Status )) { 00262 00263 HeapDebugPrint(( "Specified HeapBase (%lx) invalid, Status = %lx\n", 00264 HeapBase, 00265 Status )); 00266 00267 HeapDebugBreak( NULL ); 00268 00269 return NULL; 00270 } 00271 00272 if (MemoryInformation.BaseAddress != HeapBase) { 00273 00274 HeapDebugPrint(( "Specified HeapBase (%lx) != to BaseAddress (%lx)\n", 00275 HeapBase, 00276 MemoryInformation.BaseAddress )); 00277 00278 HeapDebugBreak( NULL ); 00279 00280 return NULL; 00281 } 00282 00283 if (MemoryInformation.State == MEM_FREE) { 00284 00285 HeapDebugPrint(( "Specified HeapBase (%lx) is free or not writable\n", 00286 MemoryInformation.BaseAddress )); 00287 00288 HeapDebugBreak( NULL ); 00289 00290 return NULL; 00291 } 00292 } 00293 00294 Heap = RtlCreateHeap( Flags | 00295 HEAP_SKIP_VALIDATION_CHECKS | 00296 HEAP_TAIL_CHECKING_ENABLED | 00297 HEAP_FREE_CHECKING_ENABLED, 00298 HeapBase, 00299 ReserveSize, 00300 CommitSize, 00301 Lock, 00302 Parameters ); 00303 00304 if (Heap != NULL) { 00305 00306 #if i386 00307 00308 if (Heap->Flags & HEAP_CAPTURE_STACK_BACKTRACES) { 00309 00310 Heap->AllocatorBackTraceIndex = (USHORT)RtlLogStackBackTrace(); 00311 } 00312 00313 #endif // i386 00314 00315 RtlpValidateHeapHeaders( Heap, TRUE ); 00316 } 00317 00318 return Heap; 00319 }

NTSTATUS RtlDebugCreateTagHeap IN PVOID  HeapHandle,
IN ULONG  Flags,
IN PWSTR TagPrefix  OPTIONAL,
IN PWSTR  TagNames
 

Definition at line 1421 of file heapdbg.c.

References EXCEPTION_EXECUTE_HANDLER, FALSE, _HEAP::ForceFlags, HEAP_SKIP_VALIDATION_CHECKS, HeapHandle, _HEAP::LockVariable, RtlAcquireLockRoutine, RtlCreateTagHeap(), RtlpCheckHeapSignature(), RtlpValidateHeap(), RtlpValidateHeapHeaders(), RtlReleaseLockRoutine, SET_LAST_STATUS, and TRUE.

Referenced by RtlCreateTagHeap().

01430 : 01431 01432 Arguments: 01433 01434 Return Value: 01435 01436 --*/ 01437 01438 { 01439 PHEAP Heap = (PHEAP)HeapHandle; 01440 BOOLEAN LockAcquired = FALSE; 01441 ULONG TagIndex; 01442 01443 TagIndex = 0; 01444 01445 try { 01446 01447 try { 01448 01449 // 01450 // Validate that HeapAddress points to a HEAP structure. 01451 // 01452 01453 if (RtlpCheckHeapSignature( Heap, "RtlCreateTagHeap" )) { 01454 01455 Flags |= Heap->ForceFlags | HEAP_SKIP_VALIDATION_CHECKS; 01456 01457 // 01458 // Lock the heap 01459 // 01460 01461 if (!(Flags & HEAP_NO_SERIALIZE)) { 01462 01463 RtlAcquireLockRoutine( Heap->LockVariable ); 01464 01465 LockAcquired = TRUE; 01466 01467 Flags |= HEAP_NO_SERIALIZE; 01468 } 01469 01470 if (RtlpValidateHeap( Heap, FALSE )) { 01471 01472 TagIndex = RtlCreateTagHeap( HeapHandle, Flags, TagPrefix, TagNames ); 01473 } 01474 01475 RtlpValidateHeapHeaders( Heap, TRUE ); 01476 } 01477 01478 } except( EXCEPTION_EXECUTE_HANDLER ) { 01479 01480 SET_LAST_STATUS( GetExceptionCode() ); 01481 } 01482 01483 } finally { 01484 01485 if (LockAcquired) { 01486 01487 RtlReleaseLockRoutine( Heap->LockVariable ); 01488 } 01489 } 01490 01491 return TagIndex; 01492 }

BOOLEAN RtlDebugDestroyHeap IN PVOID  HeapHandle  ) 
 

Definition at line 388 of file heapdbg.c.

References FALSE, _HEAP::HeaderValidateCopy, HeapDebugPrint, HeapHandle, n, NtFreeVirtualMemory(), NULL, RtlpCheckHeapSignature(), RtlpValidateHeap(), _HEAP::Signature, and TRUE.

Referenced by RtlDestroyHeap().

00394 : 00395 00396 Arguments: 00397 00398 Return Value: 00399 00400 --*/ 00401 00402 { 00403 PHEAP Heap = (PHEAP)HeapHandle; 00404 LIST_ENTRY ListEntry; 00405 SIZE_T n; 00406 00407 if (HeapHandle == NtCurrentPeb()->ProcessHeap) { 00408 00409 HeapDebugPrint(( "May not destroy the process heap at %x\n", HeapHandle )); 00410 00411 return FALSE; 00412 } 00413 00414 if (!RtlpCheckHeapSignature( Heap, "RtlDestroyHeap" )) { 00415 00416 return FALSE; 00417 } 00418 00419 if (!RtlpValidateHeap( Heap, FALSE )) { 00420 00421 return FALSE; 00422 } 00423 00424 // 00425 // Now mark the heap as invalid by zeroing the signature field. 00426 // 00427 00428 Heap->Signature = 0; 00429 00430 if (Heap->HeaderValidateCopy != NULL) { 00431 00432 n = 0; 00433 NtFreeVirtualMemory( NtCurrentProcess(), 00434 &Heap->HeaderValidateCopy, 00435 &n, 00436 MEM_RELEASE ); 00437 } 00438 00439 return TRUE; 00440 }

BOOLEAN RtlDebugFreeHeap IN PVOID  HeapHandle,
IN ULONG  Flags,
IN PVOID  BaseAddress
 

Definition at line 797 of file heapdbg.c.

References EXCEPTION_EXECUTE_HANDLER, FALSE, _HEAP_ENTRY::Flags, _HEAP::ForceFlags, _HEAP_STOP_ON_VALUES::FreeAddress, _HEAP_STOP_ON_VALUES::FreeTag, HEAP_ENTRY_EXTRA_PRESENT, HEAP_GRANULARITY_SHIFT, HEAP_SKIP_VALIDATION_CHECKS, _HEAP_STOP_ON_TAG::HeapAndTagIndex, HeapDebugBreak, HeapDebugPrint, HeapHandle, _HEAP_STOP_ON_TAG::HeapIndex, IF_DEBUG_PAGE_HEAP_THEN_RETURN, IS_HEAP_TAGGING_ENABLED, _HEAP::LockVariable, NULL, _HEAP::ProcessHeapsListIndex, RtlAcquireLockRoutine, RtlFreeHeapSlowly(), RtlpCheckHeapSignature(), RtlpDebugPageHeapFree(), RtlpGetExtraStuffPointer(), RtlpGetTagName(), RtlpHeapStopOn, RtlpValidateHeap(), RtlpValidateHeapEntry(), RtlpValidateHeapHeaders(), RtlReleaseLockRoutine, SET_LAST_STATUS, _HEAP_ENTRY::Size, Size, _HEAP_ENTRY::SmallTagIndex, _HEAP_STOP_ON_TAG::TagIndex, _HEAP_ENTRY_EXTRA::TagIndex, TRUE, and USHORT.

Referenced by RtlFreeHeapSlowly().

00805 : 00806 00807 Arguments: 00808 00809 Return Value: 00810 00811 --*/ 00812 00813 { 00814 PHEAP Heap = (PHEAP)HeapHandle; 00815 PHEAP_ENTRY BusyBlock; 00816 PHEAP_ENTRY_EXTRA ExtraStuff; 00817 SIZE_T Size; 00818 BOOLEAN Result = FALSE; 00819 BOOLEAN LockAcquired = FALSE; 00820 USHORT TagIndex; 00821 00822 IF_DEBUG_PAGE_HEAP_THEN_RETURN( HeapHandle, 00823 RtlpDebugPageHeapFree( HeapHandle, Flags, BaseAddress )); 00824 00825 try { 00826 00827 try { 00828 00829 // 00830 // Validate that HeapAddress points to a HEAP structure. 00831 // 00832 00833 if (!RtlpCheckHeapSignature( Heap, "RtlFreeHeap" )) { 00834 00835 Result = FALSE; 00836 leave; 00837 } 00838 00839 Flags |= Heap->ForceFlags | HEAP_SKIP_VALIDATION_CHECKS; 00840 00841 // 00842 // Lock the heap 00843 // 00844 00845 if (!(Flags & HEAP_NO_SERIALIZE)) { 00846 00847 RtlAcquireLockRoutine( Heap->LockVariable ); 00848 00849 LockAcquired = TRUE; 00850 00851 Flags |= HEAP_NO_SERIALIZE; 00852 } 00853 00854 RtlpValidateHeap( Heap, FALSE ); 00855 00856 BusyBlock = (PHEAP_ENTRY)BaseAddress - 1; 00857 Size = BusyBlock->Size << HEAP_GRANULARITY_SHIFT; 00858 00859 if (RtlpValidateHeapEntry( Heap, BusyBlock, "RtlFreeHeap" )) { 00860 00861 if ((ULONG_PTR)BaseAddress == RtlpHeapStopOn.FreeAddress) { 00862 00863 HeapDebugPrint(( "About to free block at %lx\n", 00864 RtlpHeapStopOn.FreeAddress )); 00865 00866 HeapDebugBreak( NULL ); 00867 00868 } else if ((IS_HEAP_TAGGING_ENABLED()) && (RtlpHeapStopOn.FreeTag.HeapAndTagIndex != 0)) { 00869 00870 if (BusyBlock->Flags & HEAP_ENTRY_EXTRA_PRESENT) { 00871 00872 ExtraStuff = RtlpGetExtraStuffPointer( BusyBlock ); 00873 00874 TagIndex = ExtraStuff->TagIndex; 00875 00876 } else { 00877 00878 TagIndex = BusyBlock->SmallTagIndex; 00879 } 00880 00881 if ((TagIndex != 0) && 00882 (TagIndex == RtlpHeapStopOn.FreeTag.TagIndex) && 00883 (Heap->ProcessHeapsListIndex == RtlpHeapStopOn.FreeTag.HeapIndex)) { 00884 00885 HeapDebugPrint(( "About to free block at %lx with tag %ws\n", 00886 BaseAddress, 00887 RtlpGetTagName( Heap, TagIndex ))); 00888 00889 HeapDebugBreak( NULL ); 00890 } 00891 } 00892 00893 Result = RtlFreeHeapSlowly( HeapHandle, Flags, BaseAddress ); 00894 00895 RtlpValidateHeapHeaders( Heap, TRUE ); 00896 RtlpValidateHeap( Heap, FALSE ); 00897 } 00898 00899 } except( EXCEPTION_EXECUTE_HANDLER ) { 00900 00901 SET_LAST_STATUS( GetExceptionCode() ); 00902 00903 Result = FALSE; 00904 } 00905 00906 } finally { 00907 00908 if (LockAcquired) { 00909 00910 RtlReleaseLockRoutine( Heap->LockVariable ); 00911 } 00912 } 00913 00914 return Result; 00915 }

BOOLEAN RtlDebugGetUserInfoHeap IN PVOID  HeapHandle,
IN ULONG  Flags,
IN PVOID  BaseAddress,
OUT PVOID *UserValue  OPTIONAL,
OUT PULONG UserFlags  OPTIONAL
 

Definition at line 919 of file heapdbg.c.

References EXCEPTION_EXECUTE_HANDLER, FALSE, _HEAP::ForceFlags, HEAP_SKIP_VALIDATION_CHECKS, HeapHandle, IF_DEBUG_PAGE_HEAP_THEN_RETURN, _HEAP::LockVariable, RtlAcquireLockRoutine, RtlGetUserInfoHeap(), RtlpCheckHeapSignature(), RtlpDebugPageHeapGetUserInfo(), RtlpValidateHeap(), RtlpValidateHeapEntry(), RtlReleaseLockRoutine, SET_LAST_STATUS, and TRUE.

Referenced by RtlGetUserInfoHeap().

00929 : 00930 00931 Arguments: 00932 00933 Return Value: 00934 00935 --*/ 00936 00937 { 00938 PHEAP Heap = (PHEAP)HeapHandle; 00939 PHEAP_ENTRY BusyBlock; 00940 BOOLEAN Result = FALSE; 00941 BOOLEAN LockAcquired = FALSE; 00942 00943 IF_DEBUG_PAGE_HEAP_THEN_RETURN( HeapHandle, 00944 RtlpDebugPageHeapGetUserInfo( HeapHandle, Flags, BaseAddress, UserValue, UserFlags )); 00945 00946 try { 00947 00948 try { 00949 00950 // 00951 // Validate that HeapAddress points to a HEAP structure. 00952 // 00953 00954 if (!RtlpCheckHeapSignature( Heap, "RtlGetUserInfoHeap" )) { 00955 00956 Result = FALSE; 00957 leave; 00958 } 00959 00960 Flags |= Heap->ForceFlags | HEAP_SKIP_VALIDATION_CHECKS; 00961 00962 // 00963 // Lock the heap 00964 // 00965 00966 if (!(Flags & HEAP_NO_SERIALIZE)) { 00967 00968 RtlAcquireLockRoutine( Heap->LockVariable ); 00969 00970 LockAcquired = TRUE; 00971 00972 Flags |= HEAP_NO_SERIALIZE; 00973 } 00974 00975 RtlpValidateHeap( Heap, FALSE ); 00976 00977 BusyBlock = (PHEAP_ENTRY)BaseAddress - 1; 00978 00979 if (RtlpValidateHeapEntry( Heap, BusyBlock, "RtlGetUserInfoHeap" )) { 00980 00981 Result = RtlGetUserInfoHeap( HeapHandle, Flags, BaseAddress, UserValue, UserFlags ); 00982 } 00983 00984 } except( EXCEPTION_EXECUTE_HANDLER ) { 00985 00986 SET_LAST_STATUS( GetExceptionCode() ); 00987 } 00988 00989 } finally { 00990 00991 if (LockAcquired) { 00992 00993 RtlReleaseLockRoutine( Heap->LockVariable ); 00994 } 00995 } 00996 00997 return Result; 00998 }

NTSYSAPI PWSTR NTAPI RtlDebugQueryTagHeap IN PVOID  HeapHandle,
IN ULONG  Flags,
IN USHORT  TagIndex,
IN BOOLEAN  ResetCounters,
OUT PRTL_HEAP_TAG_INFO TagInfo  OPTIONAL
 

Definition at line 1498 of file heapdbg.c.

References EXCEPTION_EXECUTE_HANDLER, FALSE, _HEAP::ForceFlags, HEAP_SKIP_VALIDATION_CHECKS, HeapHandle, _HEAP::LockVariable, NULL, RtlAcquireLockRoutine, RtlpCheckHeapSignature(), RtlpValidateHeap(), RtlQueryTagHeap(), RtlReleaseLockRoutine, SET_LAST_STATUS, and TRUE.

Referenced by RtlQueryTagHeap().

01508 : 01509 01510 Arguments: 01511 01512 Return Value: 01513 01514 --*/ 01515 01516 { 01517 PHEAP Heap = (PHEAP)HeapHandle; 01518 BOOLEAN LockAcquired = FALSE; 01519 PWSTR Result; 01520 01521 Result = NULL; 01522 01523 try { 01524 01525 try { 01526 01527 // 01528 // Validate that HeapAddress points to a HEAP structure. 01529 // 01530 01531 if (RtlpCheckHeapSignature( Heap, "RtlQueryTagHeap" )) { 01532 01533 Flags |= Heap->ForceFlags | HEAP_SKIP_VALIDATION_CHECKS; 01534 01535 // 01536 // Lock the heap 01537 // 01538 01539 if (!(Flags & HEAP_NO_SERIALIZE)) { 01540 01541 RtlAcquireLockRoutine( Heap->LockVariable ); 01542 01543 LockAcquired = TRUE; 01544 01545 Flags |= HEAP_NO_SERIALIZE; 01546 } 01547 01548 if (RtlpValidateHeap( Heap, FALSE )) { 01549 01550 Result = RtlQueryTagHeap( HeapHandle, Flags, TagIndex, ResetCounters, TagInfo ); 01551 } 01552 } 01553 01554 } except( EXCEPTION_EXECUTE_HANDLER ) { 01555 01556 SET_LAST_STATUS( GetExceptionCode() ); 01557 } 01558 01559 } finally { 01560 01561 if (LockAcquired) { 01562 01563 RtlReleaseLockRoutine( Heap->LockVariable ); 01564 } 01565 } 01566 01567 return Result; 01568 }

PVOID RtlDebugReAllocateHeap IN PVOID  HeapHandle,
IN ULONG  Flags,
IN PVOID  BaseAddress,
IN SIZE_T  Size
 

Definition at line 603 of file heapdbg.c.

References _HEAP::AlignMask, _HEAP::AlignRound, _HEAP_ENTRY_EXTRA::AllocatorBackTraceIndex, EXCEPTION_CONTINUE_SEARCH, EXCEPTION_EXECUTE_HANDLER, FALSE, _HEAP_ENTRY::Flags, _HEAP::Flags, _HEAP::ForceFlags, HEAP_CAPTURE_STACK_BACKTRACES, HEAP_ENTRY_EXTRA_PRESENT, HEAP_SKIP_VALIDATION_CHECKS, _HEAP_STOP_ON_TAG::HeapAndTagIndex, HeapDebugBreak, HeapDebugPrint, HeapHandle, _HEAP_STOP_ON_TAG::HeapIndex, IF_DEBUG_PAGE_HEAP_THEN_RETURN, IS_HEAP_TAGGING_ENABLED, _HEAP::LockVariable, _HEAP::MaximumAllocationSize, NULL, _HEAP::ProcessHeapsListIndex, _HEAP_STOP_ON_VALUES::ReAllocAddress, _HEAP_STOP_ON_VALUES::ReAllocTag, RtlAcquireLockRoutine, RtlpCheckHeapSignature(), RtlpDebugPageHeapReAllocate(), RtlpGetExtraStuffPointer(), RtlpGetTagName(), RtlpHeapStopOn, RtlpValidateHeap(), RtlpValidateHeapEntry(), RtlpValidateHeapHeaders(), RtlReAllocateHeap(), RtlReleaseLockRoutine, SET_LAST_STATUS, Size, _HEAP_ENTRY::SmallTagIndex, _HEAP_ENTRY_EXTRA::TagIndex, _HEAP_STOP_ON_TAG::TagIndex, TRUE, and USHORT.

Referenced by RtlReAllocateHeap().

00612 : 00613 00614 Arguments: 00615 00616 Return Value: 00617 00618 --*/ 00619 00620 { 00621 PHEAP Heap = (PHEAP)HeapHandle; 00622 SIZE_T AllocationSize; 00623 PHEAP_ENTRY BusyBlock; 00624 PHEAP_ENTRY_EXTRA ExtraStuff; 00625 BOOLEAN LockAcquired = FALSE; 00626 PVOID ReturnValue = NULL; 00627 USHORT TagIndex; 00628 00629 IF_DEBUG_PAGE_HEAP_THEN_RETURN( HeapHandle, 00630 RtlpDebugPageHeapReAllocate( HeapHandle, Flags, BaseAddress, Size )); 00631 00632 try { 00633 00634 try { 00635 00636 // 00637 // Validate that HeapAddress points to a HEAP structure. 00638 // 00639 00640 if (!RtlpCheckHeapSignature( Heap, "RtlReAllocateHeap" )) { 00641 00642 ReturnValue = NULL; 00643 leave; 00644 } 00645 00646 Flags |= Heap->ForceFlags | HEAP_SETTABLE_USER_VALUE | HEAP_SKIP_VALIDATION_CHECKS; 00647 00648 // 00649 // Verify that the size did not wrap or exceed the limit for this heap. 00650 // 00651 00652 AllocationSize = (((Size ? Size : 1) + Heap->AlignRound) & Heap->AlignMask) + 00653 sizeof( HEAP_ENTRY_EXTRA ); 00654 00655 if (AllocationSize < Size || AllocationSize > Heap->MaximumAllocationSize) { 00656 00657 HeapDebugPrint(( "Invalid allocation size - %lx (exceeded %x)\n", 00658 Size, 00659 Heap->MaximumAllocationSize )); 00660 00661 HeapDebugBreak( NULL ); 00662 00663 ReturnValue = NULL; 00664 leave; 00665 } 00666 00667 // 00668 // Lock the heap 00669 // 00670 00671 if (!(Flags & HEAP_NO_SERIALIZE)) { 00672 00673 RtlAcquireLockRoutine( Heap->LockVariable ); 00674 00675 LockAcquired = TRUE; 00676 00677 Flags |= HEAP_NO_SERIALIZE; 00678 } 00679 00680 RtlpValidateHeap( Heap, FALSE ); 00681 BusyBlock = (PHEAP_ENTRY)BaseAddress - 1; 00682 00683 if (RtlpValidateHeapEntry( Heap, BusyBlock, "RtlReAllocateHeap" )) { 00684 00685 if ((ULONG_PTR)BaseAddress == RtlpHeapStopOn.ReAllocAddress) { 00686 00687 HeapDebugPrint(( "About to reallocate block at %lx to 0x%x bytes\n", 00688 RtlpHeapStopOn.ReAllocAddress, 00689 Size )); 00690 00691 HeapDebugBreak( NULL ); 00692 00693 } else if (IS_HEAP_TAGGING_ENABLED() && RtlpHeapStopOn.ReAllocTag.HeapAndTagIndex != 0) { 00694 00695 if (BusyBlock->Flags & HEAP_ENTRY_EXTRA_PRESENT) { 00696 00697 ExtraStuff = RtlpGetExtraStuffPointer( BusyBlock ); 00698 TagIndex = ExtraStuff->TagIndex; 00699 00700 } else { 00701 00702 TagIndex = BusyBlock->SmallTagIndex; 00703 } 00704 00705 if ((TagIndex != 0) && 00706 (TagIndex == RtlpHeapStopOn.ReAllocTag.TagIndex) && 00707 (Heap->ProcessHeapsListIndex == RtlpHeapStopOn.ReAllocTag.HeapIndex)) { 00708 00709 HeapDebugPrint(( "About to rellocate block at %lx to 0x%x bytes with tag %ws\n", 00710 BaseAddress, 00711 Size, 00712 RtlpGetTagName( Heap, TagIndex ))); 00713 00714 HeapDebugBreak( NULL ); 00715 } 00716 } 00717 00718 ReturnValue = RtlReAllocateHeap( HeapHandle, Flags, BaseAddress, Size ); 00719 00720 if (ReturnValue != NULL) { 00721 00722 BusyBlock = (PHEAP_ENTRY)ReturnValue - 1; 00723 00724 if (BusyBlock->Flags & HEAP_ENTRY_EXTRA_PRESENT) { 00725 00726 ExtraStuff = RtlpGetExtraStuffPointer( BusyBlock ); 00727 00728 #if i386 00729 00730 if (Heap->Flags & HEAP_CAPTURE_STACK_BACKTRACES) { 00731 00732 ExtraStuff->AllocatorBackTraceIndex = (USHORT)RtlLogStackBackTrace(); 00733 00734 } else { 00735 00736 ExtraStuff->AllocatorBackTraceIndex = 0; 00737 } 00738 00739 #endif // i386 00740 00741 TagIndex = ExtraStuff->TagIndex; 00742 00743 } else { 00744 00745 TagIndex = BusyBlock->SmallTagIndex; 00746 } 00747 } 00748 00749 RtlpValidateHeapHeaders( Heap, TRUE ); 00750 RtlpValidateHeap( Heap, FALSE ); 00751 } 00752 00753 if (ReturnValue != NULL) { 00754 00755 if ((ULONG_PTR)ReturnValue == RtlpHeapStopOn.ReAllocAddress) { 00756 00757 HeapDebugPrint(( "Just reallocated block at %lx to 0x%x bytes\n", 00758 RtlpHeapStopOn.ReAllocAddress, 00759 Size )); 00760 00761 HeapDebugBreak( NULL ); 00762 00763 } else if ((IS_HEAP_TAGGING_ENABLED()) && 00764 (TagIndex == RtlpHeapStopOn.ReAllocTag.TagIndex) && 00765 (Heap->ProcessHeapsListIndex == RtlpHeapStopOn.ReAllocTag.HeapIndex)) { 00766 00767 HeapDebugPrint(( "Just reallocated block at %lx to 0x%x bytes with tag %ws\n", 00768 ReturnValue, 00769 Size, 00770 RtlpGetTagName( Heap, TagIndex ))); 00771 00772 HeapDebugBreak( NULL ); 00773 } 00774 } 00775 00776 } except( GetExceptionCode() == STATUS_NO_MEMORY ? EXCEPTION_CONTINUE_SEARCH : 00777 EXCEPTION_EXECUTE_HANDLER ) { 00778 00779 SET_LAST_STATUS( GetExceptionCode() ); 00780 00781 ReturnValue = NULL; 00782 } 00783 00784 } finally { 00785 00786 if (LockAcquired) { 00787 00788 RtlReleaseLockRoutine( Heap->LockVariable ); 00789 } 00790 } 00791 00792 return ReturnValue; 00793 }

BOOLEAN RtlDebugSetUserFlagsHeap IN PVOID  HeapHandle,
IN ULONG  Flags,
IN PVOID  BaseAddress,
IN ULONG  UserFlagsReset,
IN ULONG  UserFlagsSet
 

Definition at line 1086 of file heapdbg.c.

References EXCEPTION_EXECUTE_HANDLER, FALSE, _HEAP::ForceFlags, HEAP_SKIP_VALIDATION_CHECKS, HeapHandle, IF_DEBUG_PAGE_HEAP_THEN_RETURN, _HEAP::LockVariable, RtlAcquireLockRoutine, RtlpCheckHeapSignature(), RtlpDebugPageHeapSetUserFlags(), RtlpValidateHeap(), RtlpValidateHeapEntry(), RtlReleaseLockRoutine, RtlSetUserFlagsHeap(), SET_LAST_STATUS, and TRUE.

Referenced by RtlSetUserFlagsHeap().

01096 : 01097 01098 Arguments: 01099 01100 Return Value: 01101 01102 --*/ 01103 01104 { 01105 PHEAP Heap = (PHEAP)HeapHandle; 01106 PHEAP_ENTRY BusyBlock; 01107 BOOLEAN Result = FALSE; 01108 BOOLEAN LockAcquired = FALSE; 01109 01110 IF_DEBUG_PAGE_HEAP_THEN_RETURN( HeapHandle, 01111 RtlpDebugPageHeapSetUserFlags( HeapHandle, Flags, BaseAddress, UserFlagsReset, UserFlagsSet )); 01112 01113 if ((UserFlagsReset & ~HEAP_SETTABLE_USER_FLAGS) || 01114 (UserFlagsSet & ~HEAP_SETTABLE_USER_FLAGS)) { 01115 01116 return FALSE; 01117 } 01118 01119 try { 01120 01121 try { 01122 01123 // 01124 // Validate that HeapAddress points to a HEAP structure. 01125 // 01126 01127 if (!RtlpCheckHeapSignature( Heap, "RtlSetUserFlagsHeap" )) { 01128 01129 Result = FALSE; 01130 leave; 01131 } 01132 01133 Flags |= Heap->ForceFlags | HEAP_SKIP_VALIDATION_CHECKS; 01134 01135 // 01136 // Lock the heap 01137 // 01138 01139 if (!(Flags & HEAP_NO_SERIALIZE)) { 01140 01141 RtlAcquireLockRoutine( Heap->LockVariable ); 01142 01143 LockAcquired = TRUE; 01144 01145 Flags |= HEAP_NO_SERIALIZE; 01146 } 01147 01148 RtlpValidateHeap( Heap, FALSE ); 01149 01150 BusyBlock = (PHEAP_ENTRY)BaseAddress - 1; 01151 01152 if (RtlpValidateHeapEntry( Heap, BusyBlock, "RtlSetUserFlagsHeap" )) { 01153 01154 Result = RtlSetUserFlagsHeap( HeapHandle, Flags, BaseAddress, UserFlagsReset, UserFlagsSet ); 01155 01156 RtlpValidateHeap( Heap, FALSE ); 01157 } 01158 01159 } except( EXCEPTION_EXECUTE_HANDLER ) { 01160 01161 SET_LAST_STATUS( GetExceptionCode() ); 01162 } 01163 01164 } finally { 01165 01166 if (LockAcquired) { 01167 01168 RtlReleaseLockRoutine( Heap->LockVariable ); 01169 } 01170 } 01171 01172 return Result; 01173 }

BOOLEAN RtlDebugSetUserValueHeap IN PVOID  HeapHandle,
IN ULONG  Flags,
IN PVOID  BaseAddress,
IN PVOID  UserValue
 

Definition at line 1002 of file heapdbg.c.

References EXCEPTION_EXECUTE_HANDLER, FALSE, _HEAP::ForceFlags, HEAP_SKIP_VALIDATION_CHECKS, HeapHandle, IF_DEBUG_PAGE_HEAP_THEN_RETURN, _HEAP::LockVariable, RtlAcquireLockRoutine, RtlpCheckHeapSignature(), RtlpDebugPageHeapSetUserValue(), RtlpValidateHeap(), RtlpValidateHeapEntry(), RtlReleaseLockRoutine, RtlSetUserValueHeap(), SET_LAST_STATUS, and TRUE.

Referenced by RtlSetUserValueHeap().

01011 : 01012 01013 Arguments: 01014 01015 Return Value: 01016 01017 --*/ 01018 01019 { 01020 PHEAP Heap = (PHEAP)HeapHandle; 01021 PHEAP_ENTRY BusyBlock; 01022 BOOLEAN Result = FALSE; 01023 BOOLEAN LockAcquired = FALSE; 01024 01025 IF_DEBUG_PAGE_HEAP_THEN_RETURN( HeapHandle, 01026 RtlpDebugPageHeapSetUserValue( HeapHandle, Flags, BaseAddress, UserValue )); 01027 01028 try { 01029 01030 try { 01031 01032 // 01033 // Validate that HeapAddress points to a HEAP structure. 01034 // 01035 01036 if (!RtlpCheckHeapSignature( Heap, "RtlSetUserValueHeap" )) { 01037 01038 Result = FALSE; 01039 leave; 01040 } 01041 01042 Flags |= Heap->ForceFlags | HEAP_SKIP_VALIDATION_CHECKS; 01043 01044 // 01045 // Lock the heap 01046 // 01047 01048 if (!(Flags & HEAP_NO_SERIALIZE)) { 01049 01050 RtlAcquireLockRoutine( Heap->LockVariable ); 01051 01052 LockAcquired = TRUE; 01053 01054 Flags |= HEAP_NO_SERIALIZE; 01055 } 01056 01057 RtlpValidateHeap( Heap, FALSE ); 01058 01059 BusyBlock = (PHEAP_ENTRY)BaseAddress - 1; 01060 01061 if (RtlpValidateHeapEntry( Heap, BusyBlock, "RtlSetUserValueHeap" )) { 01062 01063 Result = RtlSetUserValueHeap( HeapHandle, Flags, BaseAddress, UserValue ); 01064 01065 RtlpValidateHeap( Heap, FALSE ); 01066 } 01067 01068 } except( EXCEPTION_EXECUTE_HANDLER ) { 01069 01070 SET_LAST_STATUS( GetExceptionCode() ); 01071 } 01072 01073 } finally { 01074 01075 if (LockAcquired) { 01076 01077 RtlReleaseLockRoutine( Heap->LockVariable ); 01078 } 01079 } 01080 01081 return Result; 01082 }

SIZE_T RtlDebugSizeHeap IN PVOID  HeapHandle,
IN ULONG  Flags,
IN PVOID  BaseAddress
 

Definition at line 1177 of file heapdbg.c.

References EXCEPTION_EXECUTE_HANDLER, FALSE, _HEAP::ForceFlags, HEAP_SKIP_VALIDATION_CHECKS, HeapHandle, IF_DEBUG_PAGE_HEAP_THEN_RETURN, _HEAP::LockVariable, RtlAcquireLockRoutine, RtlpCheckHeapSignature(), RtlpDebugPageHeapSize(), RtlpValidateHeap(), RtlpValidateHeapEntry(), RtlReleaseLockRoutine, RtlSizeHeap(), SET_LAST_STATUS, and TRUE.

Referenced by RtlSizeHeap().

01185 : 01186 01187 Arguments: 01188 01189 Return Value: 01190 01191 --*/ 01192 01193 { 01194 PHEAP Heap = (PHEAP)HeapHandle; 01195 PHEAP_ENTRY BusyBlock; 01196 BOOLEAN LockAcquired = FALSE; 01197 SIZE_T BusySize; 01198 01199 IF_DEBUG_PAGE_HEAP_THEN_RETURN( HeapHandle, 01200 RtlpDebugPageHeapSize( HeapHandle, Flags, BaseAddress )); 01201 01202 BusySize = 0xFFFFFFFF; 01203 01204 try { 01205 01206 try { 01207 01208 // 01209 // Validate that HeapAddress points to a HEAP structure. 01210 // 01211 01212 if (!RtlpCheckHeapSignature( Heap, "RtlSizeHeap" )) { 01213 01214 BusySize = FALSE; 01215 leave; 01216 } 01217 01218 Flags |= Heap->ForceFlags | HEAP_SKIP_VALIDATION_CHECKS; 01219 01220 // 01221 // Lock the heap 01222 // 01223 01224 if (!(Flags & HEAP_NO_SERIALIZE)) { 01225 01226 RtlAcquireLockRoutine( Heap->LockVariable ); 01227 01228 Flags |= HEAP_NO_SERIALIZE; 01229 01230 LockAcquired = TRUE; 01231 } 01232 01233 RtlpValidateHeap( Heap, FALSE ); 01234 01235 BusyBlock = (PHEAP_ENTRY)BaseAddress - 1; 01236 01237 if (RtlpValidateHeapEntry( Heap, BusyBlock, "RtlSizeHeap" )) { 01238 01239 BusySize = RtlSizeHeap( HeapHandle, Flags, BaseAddress ); 01240 } 01241 01242 } except( EXCEPTION_EXECUTE_HANDLER ) { 01243 01244 SET_LAST_STATUS( GetExceptionCode() ); 01245 } 01246 01247 } finally { 01248 01249 if (LockAcquired) { 01250 01251 RtlReleaseLockRoutine( Heap->LockVariable ); 01252 } 01253 } 01254 01255 return BusySize; 01256 }

NTSTATUS RtlDebugUsageHeap IN PVOID  HeapHandle,
IN ULONG  Flags,
IN OUT PRTL_HEAP_USAGE  Usage
 

Definition at line 1572 of file heapdbg.c.

References EXCEPTION_EXECUTE_HANDLER, FALSE, _HEAP::ForceFlags, HEAP_SKIP_VALIDATION_CHECKS, HeapHandle, IF_DEBUG_PAGE_HEAP_THEN_RETURN, _HEAP::LockVariable, NTSTATUS(), RtlAcquireLockRoutine, RtlpCheckHeapSignature(), RtlpDebugPageHeapUsage(), RtlpValidateHeap(), RtlReleaseLockRoutine, RtlUsageHeap(), Status, TRUE, and Usage().

Referenced by RtlUsageHeap().

01580 : 01581 01582 Arguments: 01583 01584 Return Value: 01585 01586 --*/ 01587 01588 { 01589 PHEAP Heap = (PHEAP)HeapHandle; 01590 NTSTATUS Status; 01591 BOOLEAN LockAcquired = FALSE; 01592 01593 IF_DEBUG_PAGE_HEAP_THEN_RETURN( HeapHandle, 01594 RtlpDebugPageHeapUsage( HeapHandle, Flags, Usage )); 01595 01596 Status = STATUS_SUCCESS; 01597 01598 try { 01599 01600 try { 01601 01602 // 01603 // Validate that HeapAddress points to a HEAP structure. 01604 // 01605 01606 if (!RtlpCheckHeapSignature( Heap, "RtlUsageHeap" )) { 01607 01608 Status = STATUS_INVALID_PARAMETER; 01609 leave; 01610 } 01611 01612 Flags |= Heap->ForceFlags | HEAP_SKIP_VALIDATION_CHECKS; 01613 01614 // 01615 // Lock the heap 01616 // 01617 01618 if (!(Flags & HEAP_NO_SERIALIZE)) { 01619 01620 RtlAcquireLockRoutine( Heap->LockVariable ); 01621 01622 LockAcquired = TRUE; 01623 01624 Flags |= HEAP_NO_SERIALIZE; 01625 } 01626 01627 if (!RtlpValidateHeap( Heap, FALSE )) { 01628 01629 Status = STATUS_INVALID_PARAMETER; 01630 01631 } else { 01632 01633 Status = RtlUsageHeap( HeapHandle, Flags, Usage ); 01634 } 01635 01636 } except( EXCEPTION_EXECUTE_HANDLER ) { 01637 01638 Status = GetExceptionCode(); 01639 } 01640 01641 } finally { 01642 01643 if (LockAcquired) { 01644 01645 RtlReleaseLockRoutine( Heap->LockVariable ); 01646 } 01647 } 01648 01649 return Status; 01650 }

BOOLEAN RtlDebugWalkHeap IN PVOID  HeapHandle,
IN OUT PRTL_HEAP_WALK_ENTRY  Entry
 

Definition at line 1654 of file heapdbg.c.

References EXCEPTION_EXECUTE_HANDLER, FALSE, HeapHandle, RtlpCheckHeapSignature(), RtlpValidateHeap(), and SET_LAST_STATUS.

Referenced by RtlWalkHeap().

01661 : 01662 01663 Arguments: 01664 01665 Return Value: 01666 01667 --*/ 01668 01669 { 01670 PHEAP Heap = (PHEAP)HeapHandle; 01671 BOOLEAN Result; 01672 01673 // 01674 // Assumed the caller has serialized via RtlLockHeap or their own locking mechanism. 01675 // 01676 01677 Result = FALSE; 01678 01679 try { 01680 01681 if (RtlpCheckHeapSignature( Heap, "RtlWalkHeap" )) { 01682 01683 Result = RtlpValidateHeap( Heap, FALSE ); 01684 } 01685 01686 } except( EXCEPTION_EXECUTE_HANDLER ) { 01687 01688 SET_LAST_STATUS( GetExceptionCode() ); 01689 } 01690 01691 return Result; 01692 }

NTSTATUS RtlDebugZeroHeap IN PVOID  HeapHandle,
IN ULONG  Flags
 

Definition at line 1338 of file heapdbg.c.

References EXCEPTION_EXECUTE_HANDLER, FALSE, _HEAP::ForceFlags, HEAP_SKIP_VALIDATION_CHECKS, HeapHandle, IF_DEBUG_PAGE_HEAP_THEN_RETURN, _HEAP::LockVariable, NTSTATUS(), RtlAcquireLockRoutine, RtlpCheckHeapSignature(), RtlpDebugPageHeapZero(), RtlpValidateHeap(), RtlReleaseLockRoutine, RtlZeroHeap(), Status, and TRUE.

Referenced by RtlZeroHeap().

01345 : 01346 01347 Arguments: 01348 01349 Return Value: 01350 01351 --*/ 01352 01353 { 01354 NTSTATUS Status; 01355 PHEAP Heap = (PHEAP)HeapHandle; 01356 BOOLEAN LockAcquired = FALSE; 01357 SIZE_T LargestFreeSize; 01358 01359 IF_DEBUG_PAGE_HEAP_THEN_RETURN( HeapHandle, 01360 RtlpDebugPageHeapZero( HeapHandle, Flags )); 01361 01362 Status = STATUS_SUCCESS; 01363 LargestFreeSize = 0; 01364 01365 try { 01366 01367 try { 01368 01369 // 01370 // Validate that HeapAddress points to a HEAP structure. 01371 // 01372 01373 if (!RtlpCheckHeapSignature( Heap, "RtlZeroHeap" )) { 01374 01375 Status = STATUS_INVALID_PARAMETER; 01376 leave; 01377 } 01378 01379 Flags |= Heap->ForceFlags | HEAP_SKIP_VALIDATION_CHECKS; 01380 01381 // 01382 // Lock the heap 01383 // 01384 01385 if (!(Flags & HEAP_NO_SERIALIZE)) { 01386 01387 RtlAcquireLockRoutine( Heap->LockVariable ); 01388 01389 LockAcquired = TRUE; 01390 01391 Flags |= HEAP_NO_SERIALIZE; 01392 } 01393 01394 if (!RtlpValidateHeap( Heap, FALSE )) { 01395 01396 Status = STATUS_INVALID_PARAMETER; 01397 01398 } else { 01399 01400 Status = RtlZeroHeap( HeapHandle, Flags ); 01401 } 01402 01403 } except( EXCEPTION_EXECUTE_HANDLER ) { 01404 01405 Status = GetExceptionCode(); 01406 } 01407 01408 } finally { 01409 01410 if (LockAcquired) { 01411 01412 RtlReleaseLockRoutine( Heap->LockVariable ); 01413 } 01414 } 01415 01416 return Status; 01417 }

VOID RtlpBreakPointHeap IN PVOID  BadAddress  ) 
 

Definition at line 2351 of file heapdbg.c.

References FALSE, RtlpHeapInvalidBadAddress, RtlpHeapInvalidBreakPoint, and TRUE.

02357 : 02358 02359 Arguments: 02360 02361 Return Value: 02362 02363 --*/ 02364 02365 { 02366 if (NtCurrentPeb()->BeingDebugged) { 02367 02368 *(BOOLEAN volatile *)&RtlpHeapInvalidBreakPoint = TRUE; 02369 02370 RtlpHeapInvalidBadAddress = BadAddress; 02371 02372 DbgBreakPoint(); 02373 02374 *(BOOLEAN volatile *)&RtlpHeapInvalidBreakPoint = FALSE; 02375 } 02376 } }

BOOLEAN RtlpSerializeHeap IN PVOID  HeapHandle  ) 
 

Definition at line 323 of file heapdbg.c.

References FALSE, _HEAP::Flags, _HEAP::ForceFlags, HeapHandle, IF_DEBUG_PAGE_HEAP_THEN_RETURN, Lock, _HEAP::LockVariable, NT_SUCCESS, NTSTATUS(), NULL, RtlAllocateHeap, RtlFreeHeap, RtlInitializeLockRoutine, RtlpCheckHeapSignature(), RtlpDebugPageHeapSerialize(), RtlpValidateHeapHeaders(), Status, and TRUE.

Referenced by LdrpInitializeTls().

00329 : 00330 00331 Arguments: 00332 00333 Return Value: 00334 00335 --*/ 00336 00337 { 00338 NTSTATUS Status; 00339 PHEAP Heap = (PHEAP)HeapHandle; 00340 PHEAP_LOCK Lock; 00341 00342 IF_DEBUG_PAGE_HEAP_THEN_RETURN( HeapHandle, 00343 RtlpDebugPageHeapSerialize( HeapHandle )); 00344 00345 // 00346 // Validate that HeapAddress points to a HEAP structure. 00347 // 00348 00349 if (!RtlpCheckHeapSignature( Heap, "RtlpSerializeHeap" )) { 00350 00351 return FALSE; 00352 } 00353 00354 // 00355 // Lock the heap. 00356 // 00357 00358 if (Heap->Flags & HEAP_NO_SERIALIZE) { 00359 00360 Lock = RtlAllocateHeap( HeapHandle, HEAP_NO_SERIALIZE, sizeof( *Lock ) ); 00361 00362 if ( Lock == NULL ) { 00363 00364 return FALSE; 00365 } 00366 00367 Status = RtlInitializeLockRoutine( Lock ); 00368 00369 if (!NT_SUCCESS( Status )) { 00370 00371 RtlFreeHeap( HeapHandle, HEAP_NO_SERIALIZE, Lock ); 00372 00373 return FALSE; 00374 } 00375 00376 Heap->LockVariable = Lock; 00377 Heap->Flags &= ~HEAP_NO_SERIALIZE; 00378 Heap->ForceFlags &= ~HEAP_NO_SERIALIZE; 00379 00380 RtlpValidateHeapHeaders( Heap, TRUE ); 00381 } 00382 00383 return TRUE; 00384 }

VOID RtlpUpdateHeapListIndex USHORT  OldIndex,
USHORT  NewIndex
 

Definition at line 76 of file heapdbg.c.

References _HEAP_STOP_ON_VALUES::AllocTag, _HEAP_STOP_ON_VALUES::FreeTag, _HEAP_STOP_ON_TAG::HeapIndex, _HEAP_STOP_ON_VALUES::ReAllocTag, and RtlpHeapStopOn.

Referenced by RtlpRemoveHeapFromProcessList().

00083 : 00084 00085 Arguments: 00086 00087 Return Value: 00088 00089 --*/ 00090 00091 { 00092 if (RtlpHeapStopOn.AllocTag.HeapIndex == OldIndex) { 00093 00094 RtlpHeapStopOn.AllocTag.HeapIndex = NewIndex; 00095 } 00096 00097 if (RtlpHeapStopOn.ReAllocTag.HeapIndex == OldIndex) { 00098 00099 RtlpHeapStopOn.ReAllocTag.HeapIndex = NewIndex; 00100 } 00101 00102 if (RtlpHeapStopOn.FreeTag.HeapIndex == OldIndex) { 00103 00104 RtlpHeapStopOn.FreeTag.HeapIndex = NewIndex; 00105 } 00106 00107 return; 00108 }

BOOLEAN RtlpValidateHeap IN PHEAP  Heap,
IN BOOLEAN  AlwaysValidate
 

Definition at line 2025 of file heapdbg.c.

References _HEAP_VIRTUAL_ALLOC_ENTRY::BusyBlock, _HEAP_VIRTUAL_ALLOC_ENTRY::CommitSize, exit, _HEAP_VIRTUAL_ALLOC_ENTRY::ExtraStuff, FALSE, _HEAP_ENTRY::Flags, HEAP_ENTRY_BUSY, HEAP_ENTRY_FILL_PATTERN, HEAP_GRANULARITY_SHIFT, HEAP_MAXIMUM_FREELISTS, HEAP_MAXIMUM_SEGMENTS, HEAP_NUMBER_OF_PSEUDO_TAG, HEAP_VALIDATE_ALL_ENABLED, HeapDebugBreak, HeapDebugPrint, NT_SUCCESS, NtAllocateVirtualMemory(), NtFreeVirtualMemory(), NTSTATUS(), NULL, RTL_PAGED_CODE, RtlpCheckBusyBlockTail(), RtlpValidateHeapHeaders(), RtlpValidateHeapSegment(), RtlpValidateHeapTagsEnable, Size, _HEAP_PSEUDO_TAG_ENTRY::Size, _HEAP_TAG_ENTRY::Size, Status, _HEAP_ENTRY_EXTRA::TagIndex, _HEAP_TAG_ENTRY::TagName, TRUE, and USHORT.

Referenced by RtlDebugAllocateHeap(), RtlDebugCompactHeap(), RtlDebugCreateTagHeap(), RtlDebugDestroyHeap(), RtlDebugFreeHeap(), RtlDebugGetUserInfoHeap(), RtlDebugQueryTagHeap(), RtlDebugReAllocateHeap(), RtlDebugSetUserFlagsHeap(), RtlDebugSetUserValueHeap(), RtlDebugSizeHeap(), RtlDebugUsageHeap(), RtlDebugWalkHeap(), RtlDebugZeroHeap(), and RtlValidateHeap().

02032 : 02033 02034 Arguments: 02035 02036 Return Value: 02037 02038 --*/ 02039 02040 { 02041 NTSTATUS Status; 02042 PHEAP_SEGMENT Segment; 02043 PLIST_ENTRY Head, Next; 02044 PHEAP_FREE_ENTRY FreeBlock; 02045 BOOLEAN EmptyFreeList; 02046 ULONG NumberOfFreeListEntries; 02047 ULONG CountOfFreeBlocks; 02048 SIZE_T TotalFreeSize; 02049 SIZE_T Size; 02050 USHORT PreviousSize; 02051 UCHAR SegmentIndex; 02052 PVOID BadAddress; 02053 PSIZE_T ComputedTagEntries = NULL; 02054 PSIZE_T ComputedPseudoTagEntries = NULL; 02055 PHEAP_VIRTUAL_ALLOC_ENTRY VirtualAllocBlock; 02056 USHORT TagIndex; 02057 02058 RTL_PAGED_CODE(); 02059 02060 BadAddress = Heap; 02061 02062 if (!RtlpValidateHeapHeaders( Heap, FALSE )) { 02063 02064 goto errorExit; 02065 } 02066 02067 if (!AlwaysValidate && !(Heap->Flags & HEAP_VALIDATE_ALL_ENABLED)) { 02068 02069 goto exit; 02070 } 02071 02072 NumberOfFreeListEntries = 0; 02073 Head = &Heap->FreeLists[ 0 ]; 02074 02075 for (Size = 0; Size < HEAP_MAXIMUM_FREELISTS; Size++) { 02076 02077 if (Size != 0) { 02078 02079 EmptyFreeList = (BOOLEAN)(IsListEmpty( Head )); 02080 BadAddress = &Heap->u.FreeListsInUseBytes[ Size / 8 ]; 02081 02082 if (Heap->u.FreeListsInUseBytes[ Size / 8 ] & (1 << (Size & 7)) ) { 02083 02084 if (EmptyFreeList) { 02085 02086 HeapDebugPrint(( "dedicated (%04x) free list empty but marked as non-empty\n", 02087 Size )); 02088 02089 goto errorExit; 02090 } 02091 02092 } else { 02093 02094 if (!EmptyFreeList) { 02095 02096 HeapDebugPrint(( "dedicated (%04x) free list non-empty but marked as empty\n", 02097 Size )); 02098 02099 goto errorExit; 02100 } 02101 } 02102 } 02103 02104 Next = Head->Flink; 02105 PreviousSize = 0; 02106 02107 while (Head != Next) { 02108 02109 FreeBlock = CONTAINING_RECORD( Next, HEAP_FREE_ENTRY, FreeList ); 02110 Next = Next->Flink; 02111 02112 BadAddress = FreeBlock; 02113 02114 if (FreeBlock->Flags & HEAP_ENTRY_BUSY) { 02115 02116 HeapDebugPrint(( "dedicated (%04x) free list element %lx is marked busy\n", 02117 Size, 02118 FreeBlock )); 02119 02120 goto errorExit; 02121 } 02122 02123 if ((Size != 0) && (FreeBlock->Size != Size)) { 02124 02125 HeapDebugPrint(( "Dedicated (%04x) free list element %lx is wrong size (%04x)\n", 02126 Size, 02127 FreeBlock, 02128 FreeBlock->Size )); 02129 02130 goto errorExit; 02131 02132 } else if ((Size == 0) && (FreeBlock->Size < HEAP_MAXIMUM_FREELISTS)) { 02133 02134 HeapDebugPrint(( "Non-Dedicated free list element %lx with too small size (%04x)\n", 02135 FreeBlock, 02136 FreeBlock->Size )); 02137 02138 goto errorExit; 02139 02140 } else if ((Size == 0) && (FreeBlock->Size < PreviousSize)) { 02141 02142 HeapDebugPrint(( "Non-Dedicated free list element %lx is out of order\n", 02143 FreeBlock )); 02144 02145 goto errorExit; 02146 02147 } else { 02148 02149 PreviousSize = FreeBlock->Size; 02150 } 02151 02152 NumberOfFreeListEntries++; 02153 } 02154 02155 Head++; 02156 } 02157 02158 Size = (HEAP_NUMBER_OF_PSEUDO_TAG + Heap->NextAvailableTagIndex + 1) * sizeof( SIZE_T ); 02159 02160 if ((RtlpValidateHeapTagsEnable) && (Heap->PseudoTagEntries != NULL)) { 02161 02162 Status = NtAllocateVirtualMemory( NtCurrentProcess(), 02163 &ComputedPseudoTagEntries, 02164 0, 02165 &Size, 02166 MEM_COMMIT, 02167 PAGE_READWRITE ); 02168 02169 if (NT_SUCCESS( Status )) { 02170 02171 ComputedTagEntries = ComputedPseudoTagEntries + HEAP_NUMBER_OF_PSEUDO_TAG; 02172 } 02173 } 02174 02175 Head = &Heap->VirtualAllocdBlocks; 02176 Next = Head->Flink; 02177 02178 while (Head != Next) { 02179 02180 VirtualAllocBlock = CONTAINING_RECORD( Next, HEAP_VIRTUAL_ALLOC_ENTRY, Entry ); 02181 02182 if (ComputedTagEntries != NULL) { 02183 02184 TagIndex = VirtualAllocBlock->ExtraStuff.TagIndex; 02185 02186 if (TagIndex != 0) { 02187 02188 if (TagIndex & HEAP_PSEUDO_TAG_FLAG) { 02189 02190 TagIndex &= ~HEAP_PSEUDO_TAG_FLAG; 02191 02192 if (TagIndex < HEAP_NUMBER_OF_PSEUDO_TAG) { 02193 02194 ComputedPseudoTagEntries[ TagIndex ] += 02195 VirtualAllocBlock->CommitSize >> HEAP_GRANULARITY_SHIFT; 02196 } 02197 02198 } else if (TagIndex & HEAP_GLOBAL_TAG) { 02199 02200 // 02201 // Ignore these since they are global across more than 02202 // one heap. 02203 // 02204 02205 } else if (TagIndex < Heap->NextAvailableTagIndex) { 02206 02207 ComputedTagEntries[ TagIndex ] += 02208 VirtualAllocBlock->CommitSize >> HEAP_GRANULARITY_SHIFT; 02209 } 02210 } 02211 } 02212 02213 if (VirtualAllocBlock->BusyBlock.Flags & HEAP_ENTRY_FILL_PATTERN) { 02214 02215 if (!RtlpCheckBusyBlockTail( &VirtualAllocBlock->BusyBlock )) { 02216 02217 return FALSE; 02218 } 02219 } 02220 02221 Next = Next->Flink; 02222 } 02223 02224 CountOfFreeBlocks = 0; 02225 TotalFreeSize = 0; 02226 02227 for (SegmentIndex=0; SegmentIndex<HEAP_MAXIMUM_SEGMENTS; SegmentIndex++) { 02228 02229 Segment = Heap->Segments[ SegmentIndex ]; 02230 02231 if (Segment) { 02232 02233 if (!RtlpValidateHeapSegment( Heap, 02234 Segment, 02235 SegmentIndex, 02236 &CountOfFreeBlocks, 02237 &TotalFreeSize, 02238 &BadAddress, 02239 ComputedTagEntries, 02240 ComputedPseudoTagEntries )) { 02241 02242 goto errorExit; 02243 } 02244 } 02245 } 02246 02247 BadAddress = Heap; 02248 02249 if (NumberOfFreeListEntries != CountOfFreeBlocks) { 02250 02251 HeapDebugPrint(( "Number of free blocks in arena (%ld) does not match number in the free lists (%ld)\n", 02252 CountOfFreeBlocks, 02253 NumberOfFreeListEntries )); 02254 02255 goto errorExit; 02256 } 02257 02258 if (Heap->TotalFreeSize != TotalFreeSize) { 02259 02260 HeapDebugPrint(( "Total size of free blocks in arena (%ld) does not match number total in heap header (%ld)\n", 02261 TotalFreeSize, 02262 Heap->TotalFreeSize )); 02263 02264 goto errorExit; 02265 } 02266 02267 if (ComputedPseudoTagEntries != NULL) { 02268 02269 PHEAP_PSEUDO_TAG_ENTRY PseudoTagEntries; 02270 PHEAP_TAG_ENTRY TagEntries; 02271 USHORT TagIndex; 02272 02273 PseudoTagEntries = Heap->PseudoTagEntries; 02274 02275 if (PseudoTagEntries != NULL) { 02276 02277 for (TagIndex=1; TagIndex<HEAP_NUMBER_OF_PSEUDO_TAG; TagIndex++) { 02278 02279 PseudoTagEntries += 1; 02280 02281 if (ComputedPseudoTagEntries[ TagIndex ] != PseudoTagEntries->Size) { 02282 02283 HeapDebugPrint(( "Pseudo Tag %04x size incorrect (%x != %x) %x\n", 02284 TagIndex, 02285 PseudoTagEntries->Size, 02286 ComputedPseudoTagEntries[ TagIndex ] 02287 &ComputedPseudoTagEntries[ TagIndex ] )); 02288 02289 goto errorExit; 02290 } 02291 } 02292 } 02293 02294 TagEntries = Heap->TagEntries; 02295 02296 if (TagEntries != NULL) { 02297 02298 for (TagIndex=1; TagIndex<Heap->NextAvailableTagIndex; TagIndex++) { 02299 02300 TagEntries += 1; 02301 02302 if (ComputedTagEntries[ TagIndex ] != TagEntries->Size) { 02303 02304 HeapDebugPrint(( "Tag %04x (%ws) size incorrect (%x != %x) %x\n", 02305 TagIndex, 02306 TagEntries->TagName, 02307 TagEntries->Size, 02308 ComputedTagEntries[ TagIndex ], 02309 &ComputedTagEntries[ TagIndex ] )); 02310 02311 goto errorExit; 02312 } 02313 } 02314 } 02315 02316 Size = 0; 02317 02318 NtFreeVirtualMemory( NtCurrentProcess(), 02319 &ComputedPseudoTagEntries, 02320 &Size, 02321 MEM_RELEASE ); 02322 } 02323 02324 exit: 02325 02326 return TRUE; 02327 02328 errorExit: 02329 02330 HeapDebugBreak( BadAddress ); 02331 02332 if (ComputedPseudoTagEntries != NULL) { 02333 02334 Size = 0; 02335 02336 NtFreeVirtualMemory( NtCurrentProcess(), 02337 &ComputedPseudoTagEntries, 02338 &Size, 02339 MEM_RELEASE ); 02340 } 02341 02342 return FALSE; 02343 02344 }

BOOLEAN RtlpValidateHeapEntry IN PHEAP  Heap,
IN PHEAP_ENTRY  BusyBlock,
IN PCHAR  Reason
 

Definition at line 1696 of file heapdbg.c.

References FALSE, _HEAP_SEGMENT::FirstEntry, HEAP_ENTRY_BUSY, HEAP_ENTRY_FILL_PATTERN, HEAP_ENTRY_VIRTUAL_ALLOC, HEAP_GRANULARITY, HEAP_MAXIMUM_SEGMENTS, HeapDebugBreak, HeapDebugPrint, _HEAP_SEGMENT::LastValidEntry, NULL, PAGE_SIZE, RtlpCheckBusyBlockTail(), and TRUE.

Referenced by RtlDebugFreeHeap(), RtlDebugGetUserInfoHeap(), RtlDebugReAllocateHeap(), RtlDebugSetUserFlagsHeap(), RtlDebugSetUserValueHeap(), RtlDebugSizeHeap(), and RtlValidateHeap().

01704 : 01705 01706 Arguments: 01707 01708 Return Value: 01709 01710 --*/ 01711 01712 { 01713 PHEAP_SEGMENT Segment; 01714 UCHAR SegmentIndex; 01715 BOOLEAN Result; 01716 01717 if ((BusyBlock == NULL) 01718 01719 || 01720 01721 ((ULONG_PTR)BusyBlock & (HEAP_GRANULARITY-1)) 01722 01723 || 01724 01725 ((BusyBlock->Flags & HEAP_ENTRY_VIRTUAL_ALLOC) && 01726 ((ULONG_PTR)BusyBlock & (PAGE_SIZE-1)) != FIELD_OFFSET( HEAP_VIRTUAL_ALLOC_ENTRY, BusyBlock )) 01727 01728 || 01729 01730 (!(BusyBlock->Flags & HEAP_ENTRY_VIRTUAL_ALLOC) && 01731 ((BusyBlock->SegmentIndex >= HEAP_MAXIMUM_SEGMENTS) || 01732 !(Segment = Heap->Segments[ BusyBlock->SegmentIndex ]) || 01733 (BusyBlock < Segment->FirstEntry) || 01734 (BusyBlock >= Segment->LastValidEntry))) 01735 01736 || 01737 01738 !(BusyBlock->Flags & HEAP_ENTRY_BUSY) 01739 01740 || 01741 01742 ((BusyBlock->Flags & HEAP_ENTRY_FILL_PATTERN) && !RtlpCheckBusyBlockTail( BusyBlock ))) { 01743 01744 InvalidBlock: 01745 01746 HeapDebugPrint(( "Invalid Address specified to %s( %lx, %lx )\n", 01747 Reason, 01748 Heap, 01749 BusyBlock + 1 )); 01750 01751 HeapDebugBreak( BusyBlock ); 01752 01753 return FALSE; 01754 01755 } else { 01756 01757 if (BusyBlock->Flags & HEAP_ENTRY_VIRTUAL_ALLOC) { 01758 01759 Result = TRUE; 01760 01761 } else { 01762 01763 for (SegmentIndex=0; SegmentIndex<HEAP_MAXIMUM_SEGMENTS; SegmentIndex++) { 01764 01765 Segment = Heap->Segments[ SegmentIndex ]; 01766 01767 if (Segment) { 01768 01769 if ((BusyBlock >= Segment->FirstEntry) && 01770 (BusyBlock < Segment->LastValidEntry)) { 01771 01772 Result = TRUE; 01773 break; 01774 } 01775 } 01776 } 01777 } 01778 01779 if (!Result) { 01780 01781 goto InvalidBlock; 01782 } 01783 01784 return TRUE; 01785 } 01786 }

BOOLEAN RtlpValidateHeapHeaders IN PHEAP  Heap,
IN BOOLEAN  Recompute
 

Definition at line 112 of file heapdbg.c.

References DbgPrint, Description, FALSE, HeapDebugPrint, n, NT_SUCCESS, NtAllocateVirtualMemory(), NTSTATUS(), NULL, RtlpHeapHeaderFieldOffsets, RtlpValidateHeapHdrsEnable, Status, and TRUE.

Referenced by RtlDebugAllocateHeap(), RtlDebugCompactHeap(), RtlDebugCreateHeap(), RtlDebugCreateTagHeap(), RtlDebugFreeHeap(), RtlDebugReAllocateHeap(), RtlpGrowBlockInPlace(), RtlpSerializeHeap(), and RtlpValidateHeap().

00119 : 00120 00121 Arguments: 00122 00123 Return Value: 00124 00125 --*/ 00126 00127 { 00128 ULONG i; 00129 SIZE_T n; 00130 SIZE_T nEqual; 00131 NTSTATUS Status; 00132 00133 if (!RtlpValidateHeapHdrsEnable) { 00134 00135 return TRUE; 00136 } 00137 00138 if (Heap->HeaderValidateCopy == NULL) { 00139 00140 n = Heap->HeaderValidateLength; 00141 00142 Status = NtAllocateVirtualMemory( NtCurrentProcess(), 00143 &Heap->HeaderValidateCopy, 00144 0, 00145 &n, 00146 MEM_COMMIT, 00147 PAGE_READWRITE ); 00148 00149 if (!NT_SUCCESS( Status )) { 00150 00151 return TRUE; 00152 } 00153 00154 Recompute = TRUE; 00155 } 00156 00157 n = Heap->HeaderValidateLength; 00158 00159 if (!Recompute) { 00160 00161 nEqual = RtlCompareMemory( Heap, 00162 Heap->HeaderValidateCopy, 00163 n ); 00164 00165 } else { 00166 00167 RtlMoveMemory( Heap->HeaderValidateCopy, 00168 Heap, 00169 n ); 00170 00171 nEqual = n; 00172 } 00173 00174 if (n != nEqual) { 00175 00176 HeapDebugPrint(( "Heap %x - headers modified (%x is %x instead of %x)\n", 00177 Heap, 00178 (PCHAR)Heap + nEqual, 00179 *(PULONG)((PCHAR)Heap + nEqual), 00180 *(PULONG)((PCHAR)Heap->HeaderValidateCopy + nEqual))); 00181 00182 for (i=0; RtlpHeapHeaderFieldOffsets[ i ].Description != NULL; i++) { 00183 00184 if ((nEqual >= RtlpHeapHeaderFieldOffsets[ i ].Offset) && 00185 (nEqual < RtlpHeapHeaderFieldOffsets[ i+1 ].Offset)) { 00186 00187 DbgPrint( " This is located in the %s field of the heap header.\n", 00188 RtlpHeapHeaderFieldOffsets[ i ].Description ); 00189 00190 break; 00191 } 00192 } 00193 00194 return FALSE; 00195 00196 } else { 00197 00198 return TRUE; 00199 } 00200 }

BOOLEAN RtlpValidateHeapSegment IN PHEAP  Heap,
IN PHEAP_SEGMENT  Segment,
IN UCHAR  SegmentIndex,
IN OUT PULONG  CountOfFreeBlocks,
IN OUT PSIZE_T  TotalFreeSize,
OUT PVOID *  BadAddress,
IN OUT PSIZE_T  ComputedTagEntries,
IN OUT PSIZE_T  ComputedPseudoTagEntries
 

Definition at line 1790 of file heapdbg.c.

References _HEAP_UNCOMMMTTED_RANGE::Address, FALSE, FREE_HEAP_FILL, HEAP_ENTRY_BUSY, HEAP_ENTRY_EXTRA_PRESENT, HEAP_ENTRY_FILL_PATTERN, HEAP_ENTRY_LAST_ENTRY, HEAP_GRANULARITY_SHIFT, HEAP_NUMBER_OF_PSEUDO_TAG, HeapDebugPrint, _HEAP_UNCOMMMTTED_RANGE::Next, NULL, PAGE_SIZE, RTL_PAGED_CODE, RtlCompareMemoryUlong(), RtlpCheckBusyBlockTail(), RtlpGetExtraStuffPointer(), _HEAP_UNCOMMMTTED_RANGE::Size, Size, _HEAP_ENTRY_EXTRA::TagIndex, TRUE, and USHORT.

Referenced by RtlpValidateHeap().

01803 : 01804 01805 Arguments: 01806 01807 Return Value: 01808 01809 --*/ 01810 01811 { 01812 PHEAP_ENTRY CurrentBlock, PreviousBlock; 01813 SIZE_T Size; 01814 USHORT PreviousSize, TagIndex; 01815 PHEAP_UNCOMMMTTED_RANGE UnCommittedRange; 01816 PHEAP_ENTRY_EXTRA ExtraStuff; 01817 ULONG NumberOfUnCommittedPages; 01818 ULONG NumberOfUnCommittedRanges; 01819 01820 RTL_PAGED_CODE(); 01821 01822 NumberOfUnCommittedPages = 0; 01823 NumberOfUnCommittedRanges = 0; 01824 01825 UnCommittedRange = Segment->UnCommittedRanges; 01826 01827 if (Segment->BaseAddress == Heap) { 01828 01829 CurrentBlock = &Heap->Entry; 01830 01831 } else { 01832 01833 CurrentBlock = &Segment->Entry; 01834 } 01835 01836 while (CurrentBlock < Segment->LastValidEntry) { 01837 01838 *BadAddress = CurrentBlock; 01839 01840 if ((UnCommittedRange != NULL) && 01841 ((ULONG_PTR)CurrentBlock >= UnCommittedRange->Address)) { 01842 01843 HeapDebugPrint(( "Heap entry %lx is beyond uncommited range [%x .. %x)\n", 01844 CurrentBlock, 01845 UnCommittedRange->Address, 01846 (PCHAR)UnCommittedRange->Address + UnCommittedRange->Size )); 01847 01848 return FALSE; 01849 } 01850 01851 PreviousSize = 0; 01852 01853 while (CurrentBlock < Segment->LastValidEntry) { 01854 01855 *BadAddress = CurrentBlock; 01856 01857 if (PreviousSize != CurrentBlock->PreviousSize) { 01858 01859 HeapDebugPrint(( "Heap entry %lx has incorrect PreviousSize field (%04x instead of %04x)\n", 01860 CurrentBlock, CurrentBlock->PreviousSize, PreviousSize )); 01861 01862 return FALSE; 01863 } 01864 01865 PreviousSize = CurrentBlock->Size; 01866 Size = (ULONG_PTR)CurrentBlock->Size << HEAP_GRANULARITY_SHIFT; 01867 01868 if (CurrentBlock->Flags & HEAP_ENTRY_BUSY) { 01869 01870 if (ComputedTagEntries != NULL) { 01871 01872 if (CurrentBlock->Flags & HEAP_ENTRY_EXTRA_PRESENT) { 01873 01874 ExtraStuff = RtlpGetExtraStuffPointer( CurrentBlock ); 01875 TagIndex = ExtraStuff->TagIndex; 01876 01877 } else { 01878 01879 TagIndex = CurrentBlock->SmallTagIndex; 01880 } 01881 01882 if (TagIndex != 0) { 01883 01884 if (TagIndex & HEAP_PSEUDO_TAG_FLAG) { 01885 01886 TagIndex &= ~HEAP_PSEUDO_TAG_FLAG; 01887 01888 if (TagIndex < HEAP_NUMBER_OF_PSEUDO_TAG) { 01889 01890 ComputedPseudoTagEntries[ TagIndex ] += CurrentBlock->Size; 01891 } 01892 01893 } else if (TagIndex & HEAP_GLOBAL_TAG) { 01894 01895 // 01896 // Ignore these since they are global across more than 01897 // one heap. 01898 // 01899 01900 } else if (TagIndex < Heap->NextAvailableTagIndex) { 01901 01902 ComputedTagEntries[ TagIndex ] += CurrentBlock->Size; 01903 } 01904 } 01905 } 01906 01907 if (CurrentBlock->Flags & HEAP_ENTRY_FILL_PATTERN) { 01908 01909 if (!RtlpCheckBusyBlockTail( CurrentBlock )) { 01910 01911 return FALSE; 01912 } 01913 } 01914 01915 } else { 01916 01917 *CountOfFreeBlocks += 1; 01918 *TotalFreeSize += CurrentBlock->Size; 01919 01920 if ((Heap->Flags & HEAP_FREE_CHECKING_ENABLED) && 01921 (CurrentBlock->Flags & HEAP_ENTRY_FILL_PATTERN)) { 01922 01923 SIZE_T cb, cbEqual; 01924 01925 cb = Size - sizeof( HEAP_FREE_ENTRY ); 01926 01927 if ((CurrentBlock->Flags & HEAP_ENTRY_EXTRA_PRESENT) && 01928 (cb > sizeof( HEAP_FREE_ENTRY_EXTRA ))) { 01929 01930 cb -= sizeof( HEAP_FREE_ENTRY_EXTRA ); 01931 } 01932 01933 cbEqual = RtlCompareMemoryUlong( (PCHAR)((PHEAP_FREE_ENTRY)CurrentBlock + 1), 01934 cb, 01935 FREE_HEAP_FILL ); 01936 01937 if (cbEqual != cb) { 01938 01939 HeapDebugPrint(( "Free Heap block %lx modified at %lx after it was freed\n", 01940 CurrentBlock, 01941 (PCHAR)(CurrentBlock + 1) + cbEqual )); 01942 01943 return FALSE; 01944 } 01945 } 01946 } 01947 01948 if (CurrentBlock->SegmentIndex != SegmentIndex) { 01949 01950 HeapDebugPrint(( "Heap block at %lx has incorrect segment index (%x)\n", 01951 CurrentBlock, 01952 SegmentIndex )); 01953 01954 return FALSE; 01955 } 01956 01957 if (CurrentBlock->Flags & HEAP_ENTRY_LAST_ENTRY) { 01958 01959 CurrentBlock = (PHEAP_ENTRY)((PCHAR)CurrentBlock + Size); 01960 01961 if (UnCommittedRange == NULL) { 01962 01963 if (CurrentBlock != Segment->LastValidEntry) { 01964 01965 HeapDebugPrint(( "Heap block at %lx is not last block in segment (%x)\n", 01966 CurrentBlock, 01967 Segment->LastValidEntry )); 01968 01969 return FALSE; 01970 } 01971 01972 } else if ((ULONG_PTR)CurrentBlock != UnCommittedRange->Address) { 01973 01974 HeapDebugPrint(( "Heap block at %lx does not match address of next uncommitted address (%x)\n", 01975 CurrentBlock, 01976 UnCommittedRange->Address )); 01977 01978 return FALSE; 01979 01980 } else { 01981 01982 NumberOfUnCommittedPages += (ULONG) (UnCommittedRange->Size / PAGE_SIZE); 01983 NumberOfUnCommittedRanges += 1; 01984 01985 CurrentBlock = (PHEAP_ENTRY) 01986 ((PCHAR)UnCommittedRange->Address + UnCommittedRange->Size); 01987 01988 UnCommittedRange = UnCommittedRange->Next; 01989 } 01990 01991 break; 01992 } 01993 01994 CurrentBlock = (PHEAP_ENTRY)((PCHAR)CurrentBlock + Size); 01995 } 01996 } 01997 01998 *BadAddress = Segment; 01999 02000 if (Segment->NumberOfUnCommittedPages != NumberOfUnCommittedPages) { 02001 02002 HeapDebugPrint(( "Heap Segment at %lx contains invalid NumberOfUnCommittedPages (%x != %x)\n", 02003 Segment, 02004 Segment->NumberOfUnCommittedPages, 02005 NumberOfUnCommittedPages )); 02006 02007 return FALSE; 02008 } 02009 02010 if (Segment->NumberOfUnCommittedRanges != NumberOfUnCommittedRanges) { 02011 02012 HeapDebugPrint(( "Heap Segment at %lx contains invalid NumberOfUnCommittedRanges (%x != %x)\n", 02013 Segment, 02014 Segment->NumberOfUnCommittedRanges, 02015 NumberOfUnCommittedRanges )); 02016 02017 return FALSE; 02018 } 02019 02020 return TRUE; 02021 }


Variable Documentation

LPSTR Description
 

Definition at line 34 of file heapdbg.c.

Referenced by CmpMatchAcpiCreatorIdRule(), CmpMatchAcpiCreatorRevisionRule(), CmpMatchAcpiOemIdRule(), CmpMatchAcpiOemRevisionRule(), CmpMatchAcpiOemTableIdRule(), CmpMatchAcpiRevisionRule(), CmpMatchDateRule(), CmpMatchDescription(), CmpMatchInstallRule(), CmpMatchMemoryRule(), CmpMatchNextMatchRule(), CmpMatchOemIdRule(), CmpMatchPModeRule(), CmpMatchPointerRule(), CmpMatchSearchRule(), and RtlpValidateHeapHeaders().

ULONG Offset
 

Definition at line 33 of file heapdbg.c.

Referenced by __C_specific_handler(), CParentInfo::AddEdge(), AlignTowardsDiskEnd(), AlignTowardsDiskStart(), AllocatePartitionStructure(), CcExtendVacbArray(), CcFlushCache(), CcPerformReadAhead(), CEdge::CEdge(), CmpFileRead(), CmpFileWrite(), CmpSaveKeyByFileCopy(), CEdgeCache::Create(), CreateHostInputOutputArray(), CreateOutputArray(), ExpEventPairInitialization(), FdGetExactOffset(), CParentInfo::FindCloseEdge(), FsRtlCopyWrite(), FsRtlIsDbcsInExpression(), FsRtlIsNameInExpressionPrivate(), FsRtlPrepareMdlWriteDev(), HvIsCellAllocated(), HvpBuildMap(), HvpBuildMapAndCopy(), HvpDoWriteHive(), HvpEnlistBinInMap(), HvpFindNextDirtyBlock(), HvpGetCellPaged(), HvpWriteLog(), HvRefreshHive(), IopWriteTriageDump(), IsUdfsVolume(), Ke386GetGdtEntryThread(), Ke386SetDescriptorProcess(), Ke386SetVdmInterruptHandler(), KeFlushIoBuffers(), KeIA32GetGdtEntryThread(), KePhase0MapIo(), KeSweepIcacheRange(), KiSweepIcacheRangeTarget(), LdrProcessRelocationBlock(), LdrRelocateImage(), main(), MaximumAlignment(), MiCheckForCrashDump(), MiReserveSystemPtes(), MiReserveSystemPtes2(), MiWaitForInPageComplete(), MiWriteComplete(), MmCopyToCachedPage(), MmFlushSection(), MmPurgeSection(), NewParsePrologueRegionPhase0(), NewParsePrologueRegionPhase1(), PspCreateLdt(), RestorePreservedRegisterFromGR(), RtlConvertSidToUnicodeString(), RtlNtStatusToDosErrorNoTeb(), RtlpValidateSDOffsetAndSize(), RtlpVirtualUnwind32(), RtlVirtualUnwind(), SetVacb(), UdfDvdReadStructure(), UdfDvdTransferKey(), UdfFindFileSetDescriptor(), UdfFindVolumeDescriptors(), UdfHighBit(), UdfLookupPsnOfExtent(), UdfMapMetadataView(), UdfRecognizeVolume(), UdfUpdateVcbPhase0(), VdmDispatchUnalignedIoToHandler(), and ZapSector().

const { ... } RtlpHeapHeaderFieldOffsets[]
 

Referenced by RtlpValidateHeapHeaders().

PVOID RtlpHeapInvalidBadAddress
 

Definition at line 2348 of file heapdbg.c.

Referenced by RtlpBreakPointHeap().

BOOLEAN RtlpHeapInvalidBreakPoint
 

Definition at line 2347 of file heapdbg.c.

Referenced by RtlpBreakPointHeap().

HEAP_STOP_ON_VALUES RtlpHeapStopOn
 

Definition at line 28 of file heapdbg.c.

Referenced by RtlDebugAllocateHeap(), RtlDebugFreeHeap(), RtlDebugReAllocateHeap(), and RtlpUpdateHeapListIndex().

BOOLEAN RtlpValidateHeapHdrsEnable = FALSE
 

Definition at line 25 of file heapdbg.c.

Referenced by RtlpValidateHeapHeaders().

BOOLEAN RtlpValidateHeapTagsEnable
 

Definition at line 26 of file heapdbg.c.

Referenced by RtlpValidateHeap().


Generated on Sat May 15 19:44:03 2004 for test by doxygen 1.3.7