ReactOS  0.4.15-dev-3173-g40ee59d
heap.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _HEAP_COMMON_ENTRY
 
struct  _HEAP_FREE_ENTRY
 
struct  _HEAP_ENTRY
 
struct  _HEAP_TAG_ENTRY
 
struct  _HEAP_PSEUDO_TAG_ENTRY
 
struct  _HEAP_COUNTERS
 
struct  _HEAP_TUNING_PARAMETERS
 
struct  _HEAP_LIST_LOOKUP
 
struct  _HEAP
 
struct  _HEAP_SEGMENT
 
struct  _HEAP_UCR_DESCRIPTOR
 
struct  _HEAP_UCR_SEGMENT
 
struct  _HEAP_ENTRY_EXTRA
 
struct  _HEAP_VIRTUAL_ALLOC_ENTRY
 

Macros

#define HEAP_SEGMENTS   64
 
#define HEAP_ENTRY_SIZE   ((ULONG)sizeof(HEAP_ENTRY))
 
#define HEAP_ENTRY_SHIFT   3
 
#define HEAP_MAX_BLOCK_SIZE   ((0x80000 - PAGE_SIZE) >> HEAP_ENTRY_SHIFT)
 
#define ARENA_INUSE_FILLER   0xBAADF00D
 
#define ARENA_FREE_FILLER   0xFEEEFEEE
 
#define HEAP_TAIL_FILL   0xab
 
#define HEAP_GLOBAL_TAG   0x0800
 
#define HEAP_PSEUDO_TAG_FLAG   0x8000
 
#define HEAP_TAG_MASK   (HEAP_MAXIMUM_TAG << HEAP_TAG_SHIFT)
 
#define HEAP_TAGS_MASK   (HEAP_TAG_MASK ^ (0xFF << HEAP_TAG_SHIFT))
 
#define HEAP_EXTRA_FLAGS_MASK
 
#define HEAP_ENTRY_BUSY   0x01
 
#define HEAP_ENTRY_EXTRA_PRESENT   0x02
 
#define HEAP_ENTRY_FILL_PATTERN   0x04
 
#define HEAP_ENTRY_VIRTUAL_ALLOC   0x08
 
#define HEAP_ENTRY_LAST_ENTRY   0x10
 
#define HEAP_ENTRY_SETTABLE_FLAG1   0x20
 
#define HEAP_ENTRY_SETTABLE_FLAG2   0x40
 
#define HEAP_ENTRY_SETTABLE_FLAG3   0x80
 
#define HEAP_ENTRY_SETTABLE_FLAGS   (HEAP_ENTRY_SETTABLE_FLAG1 | HEAP_ENTRY_SETTABLE_FLAG2 | HEAP_ENTRY_SETTABLE_FLAG3)
 
#define HEAP_SIGNATURE   0xeefeeff
 
#define HEAP_SEGMENT_SIGNATURE   0xffeeffee
 
#define HEAP_USER_ALLOCATED   0x1
 
#define HEAP_SEGMENT_MEMBERS
 

Typedefs

typedef struct _HEAP_FREE_ENTRY HEAP_FREE_ENTRY
 
typedef struct _HEAP_FREE_ENTRYPHEAP_FREE_ENTRY
 
typedef struct _HEAP_ENTRY HEAP_ENTRY
 
typedef struct _HEAP_ENTRYPHEAP_ENTRY
 
typedef struct _HEAP_TAG_ENTRY HEAP_TAG_ENTRY
 
typedef struct _HEAP_TAG_ENTRYPHEAP_TAG_ENTRY
 
typedef struct _HEAP_PSEUDO_TAG_ENTRY HEAP_PSEUDO_TAG_ENTRY
 
typedef struct _HEAP_PSEUDO_TAG_ENTRYPHEAP_PSEUDO_TAG_ENTRY
 
typedef struct _HEAP_COUNTERS HEAP_COUNTERS
 
typedef struct _HEAP_COUNTERSPHEAP_COUNTERS
 
typedef struct _HEAP_TUNING_PARAMETERS HEAP_TUNING_PARAMETERS
 
typedef struct _HEAP_TUNING_PARAMETERSPHEAP_TUNING_PARAMETERS
 
typedef struct _HEAP_LIST_LOOKUP HEAP_LIST_LOOKUP
 
typedef struct _HEAP_LIST_LOOKUPPHEAP_LIST_LOOKUP
 
typedef struct _HEAP HEAP
 
typedef struct _HEAPPHEAP
 
typedef struct _HEAP_SEGMENT HEAP_SEGMENT
 
typedef struct _HEAP_SEGMENTPHEAP_SEGMENT
 
typedef struct _HEAP_UCR_DESCRIPTOR HEAP_UCR_DESCRIPTOR
 
typedef struct _HEAP_UCR_DESCRIPTORPHEAP_UCR_DESCRIPTOR
 
typedef struct _HEAP_UCR_SEGMENT HEAP_UCR_SEGMENT
 
typedef struct _HEAP_UCR_SEGMENTPHEAP_UCR_SEGMENT
 
typedef struct _HEAP_ENTRY_EXTRA HEAP_ENTRY_EXTRA
 
typedef struct _HEAP_ENTRY_EXTRAPHEAP_ENTRY_EXTRA
 
typedef HEAP_ENTRY_EXTRA HEAP_FREE_ENTRY_EXTRA
 
typedef HEAP_ENTRY_EXTRAPHEAP_FREE_ENTRY_EXTRA
 
typedef struct _HEAP_VIRTUAL_ALLOC_ENTRY HEAP_VIRTUAL_ALLOC_ENTRY
 
typedef struct _HEAP_VIRTUAL_ALLOC_ENTRYPHEAP_VIRTUAL_ALLOC_ENTRY
 

Functions

FORCEINLINE BOOLEAN RtlpHeapIsSpecial (ULONG Flags)
 
 C_ASSERT (sizeof(HEAP_ENTRY)==8)
 
 C_ASSERT ((1<< HEAP_ENTRY_SHIFT)==sizeof(HEAP_ENTRY))
 
 C_ASSERT ((2<< HEAP_ENTRY_SHIFT)==sizeof(HEAP_FREE_ENTRY))
 
PHEAP_FREE_ENTRY NTAPI RtlpCoalesceFreeBlocks (PHEAP Heap, PHEAP_FREE_ENTRY FreeEntry, PSIZE_T FreeSize, BOOLEAN Remove)
 
PHEAP_ENTRY_EXTRA NTAPI 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)
 
HANDLE NTAPI RtlDebugCreateHeap (ULONG Flags, PVOID Addr, SIZE_T TotalSize, SIZE_T CommitSize, PVOID Lock, PRTL_HEAP_PARAMETERS Parameters)
 
BOOLEAN NTAPI RtlDebugDestroyHeap (HANDLE HeapPtr)
 
PVOID NTAPI RtlDebugAllocateHeap (PVOID HeapPtr, ULONG Flags, SIZE_T Size)
 
PVOID NTAPI RtlDebugReAllocateHeap (HANDLE HeapPtr, ULONG Flags, PVOID Ptr, SIZE_T Size)
 
BOOLEAN NTAPI RtlDebugFreeHeap (HANDLE HeapPtr, ULONG Flags, PVOID Ptr)
 
BOOLEAN NTAPI RtlDebugGetUserInfoHeap (PVOID HeapHandle, ULONG Flags, PVOID BaseAddress, PVOID *UserValue, PULONG UserFlags)
 
BOOLEAN NTAPI RtlDebugSetUserValueHeap (PVOID HeapHandle, ULONG Flags, PVOID BaseAddress, PVOID UserValue)
 
BOOLEAN NTAPI RtlDebugSetUserFlagsHeap (PVOID HeapHandle, ULONG Flags, PVOID BaseAddress, ULONG UserFlagsReset, ULONG UserFlagsSet)
 
SIZE_T NTAPI RtlDebugSizeHeap (HANDLE HeapPtr, ULONG Flags, PVOID Ptr)
 
HANDLE NTAPI RtlpPageHeapCreate (ULONG Flags, PVOID Addr, SIZE_T TotalSize, SIZE_T CommitSize, PVOID Lock, PRTL_HEAP_PARAMETERS Parameters)
 
PVOID NTAPI RtlpPageHeapDestroy (HANDLE HeapPtr)
 
PVOID NTAPI RtlpPageHeapAllocate (IN PVOID HeapPtr, IN ULONG Flags, IN SIZE_T Size)
 
BOOLEAN NTAPI RtlpPageHeapFree (HANDLE HeapPtr, ULONG Flags, PVOID Ptr)
 
PVOID NTAPI RtlpPageHeapReAllocate (HANDLE HeapPtr, ULONG Flags, PVOID Ptr, SIZE_T Size)
 
BOOLEAN NTAPI RtlpPageHeapLock (HANDLE HeapPtr)
 
BOOLEAN NTAPI RtlpPageHeapUnlock (HANDLE HeapPtr)
 
BOOLEAN NTAPI RtlpPageHeapGetUserInfo (PVOID HeapHandle, ULONG Flags, PVOID BaseAddress, PVOID *UserValue, PULONG UserFlags)
 
BOOLEAN NTAPI RtlpPageHeapSetUserValue (PVOID HeapHandle, ULONG Flags, PVOID BaseAddress, PVOID UserValue)
 
BOOLEAN NTAPI RtlpPageHeapSetUserFlags (PVOID HeapHandle, ULONG Flags, PVOID BaseAddress, ULONG UserFlagsReset, ULONG UserFlagsSet)
 
BOOLEAN NTAPI RtlpDebugPageHeapValidate (PVOID HeapPtr, ULONG Flags, PVOID Block)
 
SIZE_T NTAPI RtlpPageHeapSize (HANDLE HeapPtr, ULONG Flags, PVOID Ptr)
 
VOID NTAPI RtlpAddHeapToProcessList (PHEAP Heap)
 
VOID NTAPI RtlpRemoveHeapFromProcessList (PHEAP Heap)
 
VOID NTAPI RtlInitializeHeapManager (VOID)
 

Variables

RTL_CRITICAL_SECTION RtlpProcessHeapsListLock
 
BOOLEAN RtlpPageHeapEnabled
 

Macro Definition Documentation

◆ ARENA_FREE_FILLER

#define ARENA_FREE_FILLER   0xFEEEFEEE

Definition at line 26 of file heap.h.

◆ ARENA_INUSE_FILLER

#define ARENA_INUSE_FILLER   0xBAADF00D

Definition at line 25 of file heap.h.

◆ HEAP_ENTRY_BUSY

#define HEAP_ENTRY_BUSY   0x01

Definition at line 40 of file heap.h.

◆ HEAP_ENTRY_EXTRA_PRESENT

#define HEAP_ENTRY_EXTRA_PRESENT   0x02

Definition at line 41 of file heap.h.

◆ HEAP_ENTRY_FILL_PATTERN

#define HEAP_ENTRY_FILL_PATTERN   0x04

Definition at line 42 of file heap.h.

◆ HEAP_ENTRY_LAST_ENTRY

#define HEAP_ENTRY_LAST_ENTRY   0x10

Definition at line 44 of file heap.h.

◆ HEAP_ENTRY_SETTABLE_FLAG1

#define HEAP_ENTRY_SETTABLE_FLAG1   0x20

Definition at line 45 of file heap.h.

◆ HEAP_ENTRY_SETTABLE_FLAG2

#define HEAP_ENTRY_SETTABLE_FLAG2   0x40

Definition at line 46 of file heap.h.

◆ HEAP_ENTRY_SETTABLE_FLAG3

#define HEAP_ENTRY_SETTABLE_FLAG3   0x80

Definition at line 47 of file heap.h.

◆ HEAP_ENTRY_SETTABLE_FLAGS

Definition at line 48 of file heap.h.

◆ HEAP_ENTRY_SHIFT

#define HEAP_ENTRY_SHIFT   3

Definition at line 21 of file heap.h.

◆ HEAP_ENTRY_SIZE

#define HEAP_ENTRY_SIZE   ((ULONG)sizeof(HEAP_ENTRY))

Definition at line 17 of file heap.h.

◆ HEAP_ENTRY_VIRTUAL_ALLOC

#define HEAP_ENTRY_VIRTUAL_ALLOC   0x08

Definition at line 43 of file heap.h.

◆ HEAP_EXTRA_FLAGS_MASK

#define HEAP_EXTRA_FLAGS_MASK
Value:
HEAP_SETTABLE_USER_VALUE | \
HEAP_TAGS_MASK)
#define HEAP_CAPTURE_STACK_BACKTRACES
Definition: rtltypes.h:164

Definition at line 35 of file heap.h.

◆ HEAP_GLOBAL_TAG

#define HEAP_GLOBAL_TAG   0x0800

Definition at line 30 of file heap.h.

◆ HEAP_MAX_BLOCK_SIZE

#define HEAP_MAX_BLOCK_SIZE   ((0x80000 - PAGE_SIZE) >> HEAP_ENTRY_SHIFT)

Definition at line 23 of file heap.h.

◆ HEAP_PSEUDO_TAG_FLAG

#define HEAP_PSEUDO_TAG_FLAG   0x8000

Definition at line 31 of file heap.h.

◆ HEAP_SEGMENT_MEMBERS

#define HEAP_SEGMENT_MEMBERS
Value:
ULONG SegmentSignature; \
ULONG SegmentFlags; \
LIST_ENTRY SegmentListEntry; \
struct _HEAP *Heap; \
PVOID BaseAddress; \
ULONG NumberOfPages; \
PHEAP_ENTRY FirstEntry; \
PHEAP_ENTRY LastValidEntry; \
ULONG NumberOfUnCommittedPages; \
ULONG NumberOfUnCommittedRanges; \
USHORT SegmentAllocatorBackTraceIndex; \
USHORT Reserved; \
LIST_ENTRY UCRSegmentList
struct _Entry Entry
Definition: kefuncs.h:627
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
Definition: heap.h:135
Definition: heap.c:51

Definition at line 206 of file heap.h.

◆ HEAP_SEGMENT_SIGNATURE

#define HEAP_SEGMENT_SIGNATURE   0xffeeffee

Definition at line 52 of file heap.h.

◆ HEAP_SEGMENTS

#define HEAP_SEGMENTS   64

Definition at line 15 of file heap.h.

◆ HEAP_SIGNATURE

#define HEAP_SIGNATURE   0xeefeeff

Definition at line 51 of file heap.h.

◆ HEAP_TAG_MASK

#define HEAP_TAG_MASK   (HEAP_MAXIMUM_TAG << HEAP_TAG_SHIFT)

Definition at line 32 of file heap.h.

◆ HEAP_TAGS_MASK

#define HEAP_TAGS_MASK   (HEAP_TAG_MASK ^ (0xFF << HEAP_TAG_SHIFT))

Definition at line 33 of file heap.h.

◆ HEAP_TAIL_FILL

#define HEAP_TAIL_FILL   0xab

Definition at line 27 of file heap.h.

◆ HEAP_USER_ALLOCATED

#define HEAP_USER_ALLOCATED   0x1

Definition at line 55 of file heap.h.

Typedef Documentation

◆ HEAP

typedef struct _HEAP HEAP

◆ HEAP_COUNTERS

◆ HEAP_ENTRY

◆ HEAP_ENTRY_EXTRA

◆ HEAP_FREE_ENTRY

◆ HEAP_FREE_ENTRY_EXTRA

Definition at line 305 of file heap.h.

◆ HEAP_LIST_LOOKUP

◆ HEAP_PSEUDO_TAG_ENTRY

◆ HEAP_SEGMENT

◆ HEAP_TAG_ENTRY

◆ HEAP_TUNING_PARAMETERS

◆ HEAP_UCR_DESCRIPTOR

◆ HEAP_UCR_SEGMENT

◆ HEAP_VIRTUAL_ALLOC_ENTRY

◆ PHEAP

typedef struct _HEAP * PHEAP

◆ PHEAP_COUNTERS

◆ PHEAP_ENTRY

◆ PHEAP_ENTRY_EXTRA

◆ PHEAP_FREE_ENTRY

◆ PHEAP_FREE_ENTRY_EXTRA

Definition at line 305 of file heap.h.

◆ PHEAP_LIST_LOOKUP

◆ PHEAP_PSEUDO_TAG_ENTRY

◆ PHEAP_SEGMENT

◆ PHEAP_TAG_ENTRY

◆ PHEAP_TUNING_PARAMETERS

◆ PHEAP_UCR_DESCRIPTOR

◆ PHEAP_UCR_SEGMENT

◆ PHEAP_VIRTUAL_ALLOC_ENTRY

Function Documentation

◆ C_ASSERT() [1/3]

C_ASSERT ( sizeof(HEAP_ENTRY = =8)

◆ C_ASSERT() [2/3]

C_ASSERT ( (1<< HEAP_ENTRY_SHIFT = =sizeof(HEAP_ENTRY))

◆ C_ASSERT() [3/3]

C_ASSERT ( (2<< HEAP_ENTRY_SHIFT = =sizeof(HEAP_FREE_ENTRY))

◆ RtlDebugAllocateHeap()

PVOID NTAPI RtlDebugAllocateHeap ( PVOID  HeapPtr,
ULONG  Flags,
SIZE_T  Size 
)

Definition at line 130 of file heapdbg.c.

133 {
134  PHEAP Heap = (PHEAP)HeapPtr;
135  SIZE_T AllocSize = 1;
136  BOOLEAN HeapLocked = FALSE;
137  PVOID Result;
138 
139  if (Heap->ForceFlags & HEAP_FLAG_PAGE_ALLOCS)
140  return RtlpPageHeapAllocate(HeapPtr, Flags, Size);
141 
142  if (Heap->Signature != HEAP_SIGNATURE)
143  {
144  DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature);
145  return NULL;
146  }
147 
148  /* Add settable user value flag */
150 
151  /* Calculate size */
152  if (Size) AllocSize = Size;
153  AllocSize = ((AllocSize + Heap->AlignRound) & Heap->AlignMask) + sizeof(HEAP_ENTRY_EXTRA);
154 
155  /* Check if size didn't exceed max one */
156  if (AllocSize < Size ||
157  AllocSize > Heap->MaximumAllocationSize)
158  {
159  DPRINT1("HEAP: Too big allocation size %x (max allowed %x)\n", Size, Heap->MaximumAllocationSize);
160  return NULL;
161  }
162 
163  /* Lock the heap ourselves */
164  if (!(Flags & HEAP_NO_SERIALIZE))
165  {
167  HeapLocked = TRUE;
168 
169  /* Add no serialize flag so that the main routine won't try to acquire the lock again */
171  }
172 
173  /* Validate the heap if necessary */
174  RtlpValidateHeap(Heap, FALSE);
175 
176  /* Call main routine to do the stuff */
177  Result = RtlAllocateHeap(HeapPtr, Flags, Size);
178 
179  /* Validate heap headers */
181 
182  if (Result)
183  {
184  if (Heap->Flags & HEAP_VALIDATE_ALL_ENABLED)
185  RtlpValidateHeap(Heap, FALSE);
186  }
187 
188  /* Release the lock */
189  if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
190 
191  return Result;
192 }
#define HEAP_NO_SERIALIZE
Definition: nt_native.h:1692
NTSTATUS NTAPI RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
Definition: libsupp.c:108
#define TRUE
Definition: types.h:120
SIZE_T MaximumAllocationSize
Definition: heap.h:240
ULONG Signature
Definition: heap.h:234
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
BOOLEAN NTAPI RtlpValidateHeap(PHEAP Heap, BOOLEAN ForceValidation)
Definition: heap.c:3513
#define HEAP_SETTABLE_USER_VALUE
Definition: nt_native.h:1704
BOOLEAN NTAPI RtlpValidateHeapHeaders(PHEAP Heap, BOOLEAN Recalculate)
Definition: heap.c:3260
#define HEAP_SKIP_VALIDATION_CHECKS
Definition: rtltypes.h:165
ULONG_PTR AlignMask
Definition: heap.h:250
#define FALSE
Definition: types.h:117
PHEAP_LOCK LockVariable
Definition: heap.h:260
unsigned char BOOLEAN
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
NTSTATUS NTAPI RtlLeaveHeapLock(IN OUT PHEAP_LOCK Lock)
Definition: libsupp.c:133
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define HEAP_VALIDATE_ALL_ENABLED
Definition: rtltypes.h:166
#define HEAP_FLAG_PAGE_ALLOCS
Definition: rtltypes.h:160
PVOID NTAPI RtlpPageHeapAllocate(IN PVOID HeapPtr, IN ULONG Flags, IN SIZE_T Size)
Definition: heappage.c:1697
ULONG_PTR SIZE_T
Definition: typedefs.h:80
ULONG_PTR AlignRound
Definition: heap.h:249
ULONG Flags
Definition: heap.h:226
#define HEAP_SIGNATURE
Definition: heap.h:51
struct _HEAP_ENTRY_EXTRA HEAP_ENTRY_EXTRA
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
struct _HEAP * PHEAP
ULONG ForceFlags
Definition: heap.h:227
Definition: heap.c:51

Referenced by RtlAllocateHeap().

◆ RtlDebugCreateHeap()

HANDLE NTAPI RtlDebugCreateHeap ( ULONG  Flags,
PVOID  Addr,
SIZE_T  TotalSize,
SIZE_T  CommitSize,
PVOID  Lock,
PRTL_HEAP_PARAMETERS  Parameters 
)

Definition at line 20 of file heapdbg.c.

26 {
27  MEMORY_BASIC_INFORMATION MemoryInfo;
29  PHEAP Heap;
30 
31  /* Validate parameters */
33  {
34  DPRINT1("HEAP: Incorrect ReserveSize %x\n", ReserveSize);
35  return NULL;
36  }
37 
38  if (ReserveSize < CommitSize)
39  {
40  DPRINT1("HEAP: Incorrect CommitSize %x\n", CommitSize);
41  return NULL;
42  }
43 
44  if (Flags & HEAP_NO_SERIALIZE && Lock)
45  {
46  DPRINT1("HEAP: Can't specify Lock routine and have HEAP_NO_SERIALIZE flag set\n");
47  return NULL;
48  }
49 
50  /* If the address is specified, check it's virtual memory */
51  if (Addr)
52  {
54  Addr,
56  &MemoryInfo,
57  sizeof(MemoryInfo),
58  NULL);
59 
60  if (!NT_SUCCESS(Status))
61  {
62  DPRINT1("HEAP: Specified heap base address %p is invalid, Status 0x%08X\n", Addr, Status);
63  return NULL;
64  }
65 
66  if (MemoryInfo.BaseAddress != Addr)
67  {
68  DPRINT1("HEAP: Specified heap base address %p is not really a base one %p\n", Addr, MemoryInfo.BaseAddress);
69  return NULL;
70  }
71 
72  if (MemoryInfo.State == MEM_FREE)
73  {
74  DPRINT1("HEAP: Specified heap base address %p is free\n", Addr);
75  return NULL;
76  }
77  }
78 
79  /* All validation performed, now call the real routine with skip validation check flag */
83 
85  if (!Heap) return NULL;
86 
87  // FIXME: Capture stack backtrace
88 
90 
91  return Heap;
92 }
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:863
#define HEAP_NO_SERIALIZE
Definition: nt_native.h:1692
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
#define HEAP_TAIL_CHECKING_ENABLED
Definition: nt_native.h:1697
BOOLEAN NTAPI RtlpValidateHeapHeaders(PHEAP Heap, BOOLEAN Recalculate)
Definition: heap.c:3260
#define HEAP_SKIP_VALIDATION_CHECKS
Definition: rtltypes.h:165
#define HEAP_FREE_CHECKING_ENABLED
Definition: nt_native.h:1698
#define NtCurrentProcess()
Definition: nt_native.h:1657
NTSYSAPI NTSTATUS NTAPI ZwQueryVirtualMemory(_In_ HANDLE ProcessHandle, _In_ PVOID Address, _In_ MEMORY_INFORMATION_CLASS VirtualMemoryInformationClass, _Out_ PVOID VirtualMemoryInformation, _In_ SIZE_T Length, _Out_opt_ PSIZE_T ResultLength)
Status
Definition: gdiplustypes.h:24
#define MEM_FREE
Definition: nt_native.h:1317
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T CommitSize
Definition: mmfuncs.h:404
#define HEAP_ENTRY_SIZE
Definition: heap.h:17
NTSYSAPI PVOID NTAPI RtlCreateHeap(IN ULONG Flags, IN PVOID HeapBase OPTIONAL, IN ULONG ReserveSize OPTIONAL, IN ULONG CommitSize OPTIONAL, IN PVOID Lock OPTIONAL, IN PRTL_HEAP_PARAMETERS Parameters OPTIONAL)
#define NULL
Definition: types.h:112
_In_opt_ PVOID _In_opt_ SIZE_T ReserveSize
Definition: rtlfuncs.h:2167
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
Definition: heap.c:51

Referenced by RtlCreateHeap().

◆ RtlDebugDestroyHeap()

BOOLEAN NTAPI RtlDebugDestroyHeap ( HANDLE  HeapPtr)

Definition at line 95 of file heapdbg.c.

96 {
97  SIZE_T Size = 0;
98  PHEAP Heap = (PHEAP)HeapPtr;
99 
100  if (Heap == RtlGetCurrentPeb()->ProcessHeap)
101  {
102  DPRINT1("HEAP: It's forbidden delete process heap!");
103  return FALSE;
104  }
105 
106  if (Heap->Signature != HEAP_SIGNATURE)
107  {
108  DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature);
109  return FALSE;
110  }
111 
112  if (!RtlpValidateHeap(Heap, FALSE)) return FALSE;
113 
114  /* Make heap invalid by zeroing its signature */
115  Heap->Signature = 0;
116 
117  /* Free validate headers copy if it was existing */
118  if (Heap->HeaderValidateCopy)
119  {
120  ZwFreeVirtualMemory(NtCurrentProcess(),
121  &Heap->HeaderValidateCopy,
122  &Size,
123  MEM_RELEASE);
124  }
125 
126  return TRUE;
127 }
#define TRUE
Definition: types.h:120
ULONG Signature
Definition: heap.h:234
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
PVOID HeaderValidateCopy
Definition: heap.h:243
BOOLEAN NTAPI RtlpValidateHeap(PHEAP Heap, BOOLEAN ForceValidation)
Definition: heap.c:3513
#define FALSE
Definition: types.h:117
#define NtCurrentProcess()
Definition: nt_native.h:1657
PPEB NTAPI RtlGetCurrentPeb(VOID)
Definition: libsupp.c:63
ULONG_PTR SIZE_T
Definition: typedefs.h:80
PVOID ProcessHeap
Definition: ntddk_ex.h:249
#define HEAP_SIGNATURE
Definition: heap.h:51
#define DPRINT1
Definition: precomp.h:8
#define MEM_RELEASE
Definition: nt_native.h:1316
struct _HEAP * PHEAP
Definition: heap.c:51

Referenced by RtlDestroyHeap().

◆ RtlDebugFreeHeap()

BOOLEAN NTAPI RtlDebugFreeHeap ( HANDLE  HeapPtr,
ULONG  Flags,
PVOID  Ptr 
)

Definition at line 267 of file heapdbg.c.

270 {
271  PHEAP Heap = (PHEAP)HeapPtr;
272  BOOLEAN HeapLocked = FALSE;
273  PHEAP_ENTRY HeapEntry;
274  BOOLEAN Result = FALSE;
275 
276  if (Heap->ForceFlags & HEAP_FLAG_PAGE_ALLOCS)
277  return RtlpPageHeapFree(HeapPtr, Flags, Ptr);
278 
279  if (Heap->Signature != HEAP_SIGNATURE)
280  {
281  DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature);
282  return FALSE;
283  }
284 
285  /* Add skip validation flag */
287 
288  /* Lock the heap ourselves */
289  if (!(Flags & HEAP_NO_SERIALIZE))
290  {
292  HeapLocked = TRUE;
293 
294  /* Add no serialize flag so that the main routine won't try to acquire the lock again */
296  }
297 
298  /* Validate the heap if necessary */
299  RtlpValidateHeap(Heap, FALSE);
300 
301  /* Get the existing heap entry */
302  HeapEntry = (PHEAP_ENTRY)Ptr - 1;
303 
304  /* Validate it */
305  if (RtlpValidateHeapEntry(Heap, HeapEntry))
306  {
307  /* If it succeeded - call the main routine */
308  Result = RtlFreeHeap(HeapPtr, Flags, Ptr);
309 
310  /* Validate heap headers and then heap itself */
312  RtlpValidateHeap(Heap, FALSE);
313  }
314 
315  /* Release the lock */
316  if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
317 
318  return Result;
319 }
#define HEAP_NO_SERIALIZE
Definition: nt_native.h:1692
NTSTATUS NTAPI RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
Definition: libsupp.c:108
#define TRUE
Definition: types.h:120
BOOLEAN NTAPI RtlpValidateHeapEntry(PHEAP Heap, PHEAP_ENTRY HeapEntry)
Definition: heap.c:3269
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
ULONG Signature
Definition: heap.h:234
BOOLEAN NTAPI RtlpValidateHeap(PHEAP Heap, BOOLEAN ForceValidation)
Definition: heap.c:3513
BOOLEAN NTAPI RtlpValidateHeapHeaders(PHEAP Heap, BOOLEAN Recalculate)
Definition: heap.c:3260
#define HEAP_SKIP_VALIDATION_CHECKS
Definition: rtltypes.h:165
#define FALSE
Definition: types.h:117
PHEAP_LOCK LockVariable
Definition: heap.h:260
unsigned char BOOLEAN
struct _HEAP_ENTRY * PHEAP_ENTRY
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
NTSTATUS NTAPI RtlLeaveHeapLock(IN OUT PHEAP_LOCK Lock)
Definition: libsupp.c:133
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define HEAP_FLAG_PAGE_ALLOCS
Definition: rtltypes.h:160
Definition: heap.h:135
#define HEAP_SIGNATURE
Definition: heap.h:51
#define DPRINT1
Definition: precomp.h:8
struct _HEAP * PHEAP
ULONG ForceFlags
Definition: heap.h:227
BOOLEAN NTAPI RtlpPageHeapFree(HANDLE HeapPtr, ULONG Flags, PVOID Ptr)
Definition: heappage.c:1862
Definition: heap.c:51

Referenced by RtlFreeHeap().

◆ RtlDebugGetUserInfoHeap()

BOOLEAN NTAPI RtlDebugGetUserInfoHeap ( PVOID  HeapHandle,
ULONG  Flags,
PVOID  BaseAddress,
PVOID UserValue,
PULONG  UserFlags 
)

Definition at line 322 of file heapdbg.c.

327 {
328  PHEAP Heap = (PHEAP)HeapHandle;
329  BOOLEAN HeapLocked = FALSE;
330  PHEAP_ENTRY HeapEntry;
331  BOOLEAN Result = FALSE;
332 
333  if (Heap->ForceFlags & HEAP_FLAG_PAGE_ALLOCS)
334  return RtlpPageHeapGetUserInfo(HeapHandle, Flags, BaseAddress, UserValue, UserFlags);
335 
336  if (Heap->Signature != HEAP_SIGNATURE)
337  {
338  DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature);
339  return FALSE;
340  }
341 
342  /* Add skip validation flag */
344 
345  /* Lock the heap ourselves */
346  if (!(Flags & HEAP_NO_SERIALIZE))
347  {
349  HeapLocked = TRUE;
350 
351  /* Add no serialize flag so that the main routine won't try to acquire the lock again */
353  }
354 
355  /* Validate the heap if necessary */
356  RtlpValidateHeap(Heap, FALSE);
357 
358  /* Get the existing heap entry */
359  HeapEntry = (PHEAP_ENTRY)BaseAddress - 1;
360 
361  /* Validate it */
362  if (RtlpValidateHeapEntry(Heap, HeapEntry))
363  {
364  /* If it succeeded - call the main routine */
365  Result = RtlGetUserInfoHeap(HeapHandle, Flags, BaseAddress, UserValue, UserFlags);
366  }
367 
368  /* Release the lock */
369  if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
370 
371  return Result;
372 }
#define HEAP_NO_SERIALIZE
Definition: nt_native.h:1692
NTSTATUS NTAPI RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
Definition: libsupp.c:108
#define TRUE
Definition: types.h:120
BOOLEAN NTAPI RtlpValidateHeapEntry(PHEAP Heap, PHEAP_ENTRY HeapEntry)
Definition: heap.c:3269
ULONG Signature
Definition: heap.h:234
BOOLEAN NTAPI RtlpValidateHeap(PHEAP Heap, BOOLEAN ForceValidation)
Definition: heap.c:3513
#define HEAP_SKIP_VALIDATION_CHECKS
Definition: rtltypes.h:165
#define FALSE
Definition: types.h:117
PHEAP_LOCK LockVariable
Definition: heap.h:260
unsigned char BOOLEAN
struct _HEAP_ENTRY * PHEAP_ENTRY
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
BOOLEAN NTAPI RtlGetUserInfoHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID BaseAddress, OUT PVOID *UserValue, OUT PULONG UserFlags)
Definition: heap.c:3928
NTSTATUS NTAPI RtlLeaveHeapLock(IN OUT PHEAP_LOCK Lock)
Definition: libsupp.c:133
BOOLEAN NTAPI RtlpPageHeapGetUserInfo(PVOID HeapHandle, ULONG Flags, PVOID BaseAddress, PVOID *UserValue, PULONG UserFlags)
Definition: heappage.c:2124
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define HEAP_FLAG_PAGE_ALLOCS
Definition: rtltypes.h:160
Definition: heap.h:135
#define HEAP_SIGNATURE
Definition: heap.h:51
#define DPRINT1
Definition: precomp.h:8
struct _HEAP * PHEAP
ULONG ForceFlags
Definition: heap.h:227
Definition: heap.c:51

Referenced by RtlGetUserInfoHeap().

◆ RtlDebugReAllocateHeap()

PVOID NTAPI RtlDebugReAllocateHeap ( HANDLE  HeapPtr,
ULONG  Flags,
PVOID  Ptr,
SIZE_T  Size 
)

Definition at line 195 of file heapdbg.c.

199 {
200  PHEAP Heap = (PHEAP)HeapPtr;
201  SIZE_T AllocSize = 1;
202  BOOLEAN HeapLocked = FALSE;
203  PVOID Result = NULL;
204  PHEAP_ENTRY HeapEntry;
205 
206  if (Heap->ForceFlags & HEAP_FLAG_PAGE_ALLOCS)
207  return RtlpPageHeapReAllocate(HeapPtr, Flags, Ptr, Size);
208 
209  if (Heap->Signature != HEAP_SIGNATURE)
210  {
211  DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature);
212  return NULL;
213  }
214 
215  /* Add settable user value flag */
217 
218  /* Calculate size */
219  if (Size) AllocSize = Size;
220  AllocSize = ((AllocSize + Heap->AlignRound) & Heap->AlignMask) + sizeof(HEAP_ENTRY_EXTRA);
221 
222  /* Check if size didn't exceed max one */
223  if (AllocSize < Size ||
224  AllocSize > Heap->MaximumAllocationSize)
225  {
226  DPRINT1("HEAP: Too big allocation size %x (max allowed %x)\n", Size, Heap->MaximumAllocationSize);
227  return NULL;
228  }
229 
230  /* Lock the heap ourselves */
231  if (!(Flags & HEAP_NO_SERIALIZE))
232  {
234  HeapLocked = TRUE;
235 
236  /* Add no serialize flag so that the main routine won't try to acquire the lock again */
238  }
239 
240  /* Validate the heap if necessary */
241  RtlpValidateHeap(Heap, FALSE);
242 
243  /* Get the existing heap entry */
244  HeapEntry = (PHEAP_ENTRY)Ptr - 1;
245 
246  /* Validate it */
247  if (RtlpValidateHeapEntry(Heap, HeapEntry))
248  {
249  /* Call main routine to do the stuff */
250  Result = RtlReAllocateHeap(HeapPtr, Flags, Ptr, Size);
251 
252  if (Result)
253  {
254  /* Validate heap headers and then heap itself */
256  RtlpValidateHeap(Heap, FALSE);
257  }
258  }
259 
260  /* Release the lock */
261  if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
262 
263  return Result;
264 }
#define HEAP_NO_SERIALIZE
Definition: nt_native.h:1692
NTSTATUS NTAPI RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
Definition: libsupp.c:108
#define TRUE
Definition: types.h:120
BOOLEAN NTAPI RtlpValidateHeapEntry(PHEAP Heap, PHEAP_ENTRY HeapEntry)
Definition: heap.c:3269
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
SIZE_T MaximumAllocationSize
Definition: heap.h:240
ULONG Signature
Definition: heap.h:234
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
BOOLEAN NTAPI RtlpValidateHeap(PHEAP Heap, BOOLEAN ForceValidation)
Definition: heap.c:3513
#define HEAP_SETTABLE_USER_VALUE
Definition: nt_native.h:1704
BOOLEAN NTAPI RtlpValidateHeapHeaders(PHEAP Heap, BOOLEAN Recalculate)
Definition: heap.c:3260
#define HEAP_SKIP_VALIDATION_CHECKS
Definition: rtltypes.h:165
ULONG_PTR AlignMask
Definition: heap.h:250
#define FALSE
Definition: types.h:117
PHEAP_LOCK LockVariable
Definition: heap.h:260
unsigned char BOOLEAN
struct _HEAP_ENTRY * PHEAP_ENTRY
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
NTSTATUS NTAPI RtlLeaveHeapLock(IN OUT PHEAP_LOCK Lock)
Definition: libsupp.c:133
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
PVOID NTAPI RtlpPageHeapReAllocate(HANDLE HeapPtr, ULONG Flags, PVOID Ptr, SIZE_T Size)
Definition: heappage.c:1954
#define HEAP_FLAG_PAGE_ALLOCS
Definition: rtltypes.h:160
ULONG_PTR SIZE_T
Definition: typedefs.h:80
ULONG_PTR AlignRound
Definition: heap.h:249
Definition: heap.h:135
#define HEAP_SIGNATURE
Definition: heap.h:51
struct _HEAP_ENTRY_EXTRA HEAP_ENTRY_EXTRA
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
struct _HEAP * PHEAP
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T)
Definition: heap.c:2667
ULONG ForceFlags
Definition: heap.h:227
Definition: heap.c:51

Referenced by RtlReAllocateHeap().

◆ RtlDebugSetUserFlagsHeap()

BOOLEAN NTAPI RtlDebugSetUserFlagsHeap ( PVOID  HeapHandle,
ULONG  Flags,
PVOID  BaseAddress,
ULONG  UserFlagsReset,
ULONG  UserFlagsSet 
)

Definition at line 431 of file heapdbg.c.

436 {
437  PHEAP Heap = (PHEAP)HeapHandle;
438  BOOLEAN HeapLocked = FALSE;
439  PHEAP_ENTRY HeapEntry;
440  BOOLEAN Result = FALSE;
441 
442  if (Heap->ForceFlags & HEAP_FLAG_PAGE_ALLOCS)
443  return RtlpPageHeapSetUserFlags(HeapHandle, Flags, BaseAddress, UserFlagsReset, UserFlagsSet);
444 
445  /* Check if this heap allows flags to be set at all */
446  if (UserFlagsSet & ~HEAP_SETTABLE_USER_FLAGS ||
447  UserFlagsReset & ~HEAP_SETTABLE_USER_FLAGS)
448  {
449  return FALSE;
450  }
451 
452  if (Heap->Signature != HEAP_SIGNATURE)
453  {
454  DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature);
455  return FALSE;
456  }
457 
458  /* Add skip validation flag */
460 
461  /* Lock the heap ourselves */
462  if (!(Flags & HEAP_NO_SERIALIZE))
463  {
465  HeapLocked = TRUE;
466 
467  /* Add no serialize flag so that the main routine won't try to acquire the lock again */
469  }
470 
471  /* Validate the heap if necessary */
472  RtlpValidateHeap(Heap, FALSE);
473 
474  /* Get the existing heap entry */
475  HeapEntry = (PHEAP_ENTRY)BaseAddress - 1;
476 
477  /* Validate it */
478  if (RtlpValidateHeapEntry(Heap, HeapEntry))
479  {
480  /* If it succeeded - call the main routine */
481  Result = RtlSetUserFlagsHeap(HeapHandle, Flags, BaseAddress, UserFlagsReset, UserFlagsSet);
482 
483  /* Validate the heap */
484  RtlpValidateHeap(Heap, FALSE);
485  }
486 
487  /* Release the lock */
488  if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
489 
490  return Result;
491 }
#define HEAP_NO_SERIALIZE
Definition: nt_native.h:1692
NTSTATUS NTAPI RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
Definition: libsupp.c:108
#define TRUE
Definition: types.h:120
BOOLEAN NTAPI RtlpValidateHeapEntry(PHEAP Heap, PHEAP_ENTRY HeapEntry)
Definition: heap.c:3269
ULONG Signature
Definition: heap.h:234
BOOLEAN NTAPI RtlpValidateHeap(PHEAP Heap, BOOLEAN ForceValidation)
Definition: heap.c:3513
#define HEAP_SKIP_VALIDATION_CHECKS
Definition: rtltypes.h:165
#define FALSE
Definition: types.h:117
PHEAP_LOCK LockVariable
Definition: heap.h:260
unsigned char BOOLEAN
struct _HEAP_ENTRY * PHEAP_ENTRY
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
NTSTATUS NTAPI RtlLeaveHeapLock(IN OUT PHEAP_LOCK Lock)
Definition: libsupp.c:133
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define HEAP_SETTABLE_USER_FLAGS
Definition: nt_native.h:1708
#define HEAP_FLAG_PAGE_ALLOCS
Definition: rtltypes.h:160
BOOLEAN NTAPI RtlSetUserFlagsHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID BaseAddress, IN ULONG UserFlagsReset, IN ULONG UserFlagsSet)
Definition: heap.c:3873
Definition: heap.h:135
BOOLEAN NTAPI RtlpPageHeapSetUserFlags(PVOID HeapHandle, ULONG Flags, PVOID BaseAddress, ULONG UserFlagsReset, ULONG UserFlagsSet)
Definition: heappage.c:2207
#define HEAP_SIGNATURE
Definition: heap.h:51
#define DPRINT1
Definition: precomp.h:8
struct _HEAP * PHEAP
ULONG ForceFlags
Definition: heap.h:227
Definition: heap.c:51

Referenced by RtlSetUserFlagsHeap().

◆ RtlDebugSetUserValueHeap()

BOOLEAN NTAPI RtlDebugSetUserValueHeap ( PVOID  HeapHandle,
ULONG  Flags,
PVOID  BaseAddress,
PVOID  UserValue 
)

Definition at line 375 of file heapdbg.c.

379 {
380  PHEAP Heap = (PHEAP)HeapHandle;
381  BOOLEAN HeapLocked = FALSE;
382  PHEAP_ENTRY HeapEntry;
383  BOOLEAN Result = FALSE;
384 
385  if (Heap->ForceFlags & HEAP_FLAG_PAGE_ALLOCS)
386  return RtlpPageHeapSetUserValue(HeapHandle, Flags, BaseAddress, UserValue);
387 
388  if (Heap->Signature != HEAP_SIGNATURE)
389  {
390  DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature);
391  return FALSE;
392  }
393 
394  /* Add skip validation flag */
396 
397  /* Lock the heap ourselves */
398  if (!(Flags & HEAP_NO_SERIALIZE))
399  {
401  HeapLocked = TRUE;
402 
403  /* Add no serialize flag so that the main routine won't try to acquire the lock again */
405  }
406 
407  /* Validate the heap if necessary */
408  RtlpValidateHeap(Heap, FALSE);
409 
410  /* Get the existing heap entry */
411  HeapEntry = (PHEAP_ENTRY)BaseAddress - 1;
412 
413  /* Validate it */
414  if (RtlpValidateHeapEntry(Heap, HeapEntry))
415  {
416  /* If it succeeded - call the main routine */
417  Result = RtlSetUserValueHeap(HeapHandle, Flags, BaseAddress, UserValue);
418 
419  /* Validate the heap */
420  RtlpValidateHeap(Heap, FALSE);
421  }
422 
423  /* Release the lock */
424  if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
425 
426  return Result;
427 }
#define HEAP_NO_SERIALIZE
Definition: nt_native.h:1692
NTSTATUS NTAPI RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
Definition: libsupp.c:108
#define TRUE
Definition: types.h:120
BOOLEAN NTAPI RtlpValidateHeapEntry(PHEAP Heap, PHEAP_ENTRY HeapEntry)
Definition: heap.c:3269
ULONG Signature
Definition: heap.h:234
BOOLEAN NTAPI RtlpValidateHeap(PHEAP Heap, BOOLEAN ForceValidation)
Definition: heap.c:3513
#define HEAP_SKIP_VALIDATION_CHECKS
Definition: rtltypes.h:165
BOOLEAN NTAPI RtlSetUserValueHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID BaseAddress, IN PVOID UserValue)
Definition: heap.c:3811
#define FALSE
Definition: types.h:117
PHEAP_LOCK LockVariable
Definition: heap.h:260
unsigned char BOOLEAN
struct _HEAP_ENTRY * PHEAP_ENTRY
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
BOOLEAN NTAPI RtlpPageHeapSetUserValue(PVOID HeapHandle, ULONG Flags, PVOID BaseAddress, PVOID UserValue)
Definition: heappage.c:2166
NTSTATUS NTAPI RtlLeaveHeapLock(IN OUT PHEAP_LOCK Lock)
Definition: libsupp.c:133
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define HEAP_FLAG_PAGE_ALLOCS
Definition: rtltypes.h:160
Definition: heap.h:135
#define HEAP_SIGNATURE
Definition: heap.h:51
#define DPRINT1
Definition: precomp.h:8
struct _HEAP * PHEAP
ULONG ForceFlags
Definition: heap.h:227
Definition: heap.c:51

Referenced by RtlSetUserValueHeap().

◆ RtlDebugSizeHeap()

SIZE_T NTAPI RtlDebugSizeHeap ( HANDLE  HeapPtr,
ULONG  Flags,
PVOID  Ptr 
)

Definition at line 494 of file heapdbg.c.

497 {
498  PHEAP Heap = (PHEAP)HeapPtr;
499  BOOLEAN HeapLocked = FALSE;
500  PHEAP_ENTRY HeapEntry;
501  SIZE_T Result = ~(SIZE_T)0;
502 
503  if (Heap->ForceFlags & HEAP_FLAG_PAGE_ALLOCS)
504  return RtlpPageHeapSize(HeapPtr, Flags, Ptr);
505 
506  /* Check heap signature */
507  if (Heap->Signature != HEAP_SIGNATURE)
508  {
509  DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature);
510  return FALSE;
511  }
512 
513  /* Add skip validation flag */
515 
516  /* Lock the heap ourselves */
517  if (!(Flags & HEAP_NO_SERIALIZE))
518  {
520  HeapLocked = TRUE;
521 
522  /* Add no serialize flag so that the main routine won't try to acquire the lock again */
524  }
525 
526  /* Validate the heap if necessary */
527  RtlpValidateHeap(Heap, FALSE);
528 
529  /* Get the existing heap entry */
530  HeapEntry = (PHEAP_ENTRY)Ptr - 1;
531 
532  /* Validate it */
533  if (RtlpValidateHeapEntry(Heap, HeapEntry))
534  {
535  /* If it succeeded - call the main routine */
536  Result = RtlSizeHeap(HeapPtr, Flags, Ptr);
537  }
538 
539  /* Release the lock */
540  if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
541 
542  return Result;
543 }
#define HEAP_NO_SERIALIZE
Definition: nt_native.h:1692
NTSTATUS NTAPI RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
Definition: libsupp.c:108
#define TRUE
Definition: types.h:120
BOOLEAN NTAPI RtlpValidateHeapEntry(PHEAP Heap, PHEAP_ENTRY HeapEntry)
Definition: heap.c:3269
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
ULONG Signature
Definition: heap.h:234
BOOLEAN NTAPI RtlpValidateHeap(PHEAP Heap, BOOLEAN ForceValidation)
Definition: heap.c:3513
#define HEAP_SKIP_VALIDATION_CHECKS
Definition: rtltypes.h:165
#define FALSE
Definition: types.h:117
PHEAP_LOCK LockVariable
Definition: heap.h:260
unsigned char BOOLEAN
struct _HEAP_ENTRY * PHEAP_ENTRY
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
NTSTATUS NTAPI RtlLeaveHeapLock(IN OUT PHEAP_LOCK Lock)
Definition: libsupp.c:133
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
NTSYSAPI SIZE_T NTAPI RtlSizeHeap(_In_ PVOID HeapHandle, _In_ ULONG Flags, _In_ PVOID MemoryPointer)
#define HEAP_FLAG_PAGE_ALLOCS
Definition: rtltypes.h:160
SIZE_T NTAPI RtlpPageHeapSize(HANDLE HeapPtr, ULONG Flags, PVOID Ptr)
Definition: heappage.c:2249
ULONG_PTR SIZE_T
Definition: typedefs.h:80
Definition: heap.h:135
#define HEAP_SIGNATURE
Definition: heap.h:51
#define DPRINT1
Definition: precomp.h:8
struct _HEAP * PHEAP
ULONG ForceFlags
Definition: heap.h:227
Definition: heap.c:51

Referenced by RtlSizeHeap().

◆ RtlInitializeHeapManager()

VOID NTAPI RtlInitializeHeapManager ( VOID  )

Definition at line 250 of file libsupp.c.

251 {
252 }

◆ RtlpAddHeapToProcessList()

VOID NTAPI RtlpAddHeapToProcessList ( PHEAP  Heap)

Definition at line 23 of file heapuser.c.

24 {
25  PPEB Peb;
26 
27  /* Get PEB */
29 
30  /* Acquire the lock */
32 
33  //_SEH2_TRY {
34  /* Check if max number of heaps reached */
36  {
37  // TODO: Handle this case
38  ASSERT(FALSE);
39  }
40 
41  /* Add the heap to the process heaps */
43  Peb->NumberOfHeaps++;
45  // } _SEH2_FINALLY {
46 
47  /* Release the lock */
49 
50  // } _SEH2_END
51 }
PPEB Peb
Definition: dllmain.c:27
RTL_CRITICAL_SECTION RtlpProcessHeapsListLock
Definition: heapuser.c:17
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define FALSE
Definition: types.h:117
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
ULONG NumberOfHeaps
Definition: ntddk_ex.h:286
#define ASSERT(a)
Definition: mode.c:44
PVOID * ProcessHeaps
Definition: ntddk_ex.h:288
ULONG MaximumNumberOfHeaps
Definition: ntddk_ex.h:287
PPEB NTAPI RtlGetCurrentPeb(VOID)
Definition: libsupp.c:63
unsigned short USHORT
Definition: pedump.c:61
USHORT ProcessHeapsListIndex
Definition: heap.h:241

◆ RtlpCoalesceFreeBlocks()

PHEAP_FREE_ENTRY NTAPI RtlpCoalesceFreeBlocks ( PHEAP  Heap,
PHEAP_FREE_ENTRY  FreeEntry,
PSIZE_T  FreeSize,
BOOLEAN  Remove 
)

Definition at line 1150 of file heap.c.

1154 {
1155  PHEAP_FREE_ENTRY CurrentEntry, NextEntry;
1156  UCHAR SegmentOffset;
1157 
1158  /* Get the previous entry */
1159  CurrentEntry = (PHEAP_FREE_ENTRY)((PHEAP_ENTRY)FreeEntry - FreeEntry->PreviousSize);
1160 
1161  /* Check it */
1162  if (CurrentEntry != FreeEntry &&
1163  !(CurrentEntry->Flags & HEAP_ENTRY_BUSY) &&
1164  (*FreeSize + CurrentEntry->Size) <= HEAP_MAX_BLOCK_SIZE)
1165  {
1166  ASSERT(FreeEntry->PreviousSize == CurrentEntry->Size);
1167 
1168  /* Remove it if asked for */
1169  if (Remove)
1170  {
1171  RtlpRemoveFreeBlock(Heap, FreeEntry, FALSE);
1172  Heap->TotalFreeSize -= FreeEntry->Size;
1173 
1174  /* Remove it only once! */
1175  Remove = FALSE;
1176  }
1177 
1178  /* Remove previous entry too */
1179  RtlpRemoveFreeBlock(Heap, CurrentEntry, FALSE);
1180 
1181  /* Copy flags */
1182  CurrentEntry->Flags = FreeEntry->Flags & HEAP_ENTRY_LAST_ENTRY;
1183 
1184  /* Advance FreeEntry and update sizes */
1185  FreeEntry = CurrentEntry;
1186  *FreeSize = *FreeSize + CurrentEntry->Size;
1187  Heap->TotalFreeSize -= CurrentEntry->Size;
1188  FreeEntry->Size = (USHORT)(*FreeSize);
1189 
1190  /* Also update previous size if needed */
1191  if (!(FreeEntry->Flags & HEAP_ENTRY_LAST_ENTRY))
1192  {
1193  ((PHEAP_ENTRY)FreeEntry + *FreeSize)->PreviousSize = (USHORT)(*FreeSize);
1194  }
1195  else
1196  {
1197  SegmentOffset = FreeEntry->SegmentOffset;
1198  ASSERT(SegmentOffset < HEAP_SEGMENTS);
1199  }
1200  }
1201 
1202  /* Check the next block if it exists */
1203  if (!(FreeEntry->Flags & HEAP_ENTRY_LAST_ENTRY))
1204  {
1205  NextEntry = (PHEAP_FREE_ENTRY)((PHEAP_ENTRY)FreeEntry + *FreeSize);
1206 
1207  if (!(NextEntry->Flags & HEAP_ENTRY_BUSY) &&
1208  NextEntry->Size + *FreeSize <= HEAP_MAX_BLOCK_SIZE)
1209  {
1210  ASSERT(*FreeSize == NextEntry->PreviousSize);
1211 
1212  /* Remove it if asked for */
1213  if (Remove)
1214  {
1215  RtlpRemoveFreeBlock(Heap, FreeEntry, FALSE);
1216  Heap->TotalFreeSize -= FreeEntry->Size;
1217  }
1218 
1219  /* Copy flags */
1220  FreeEntry->Flags = NextEntry->Flags & HEAP_ENTRY_LAST_ENTRY;
1221 
1222  /* Remove next entry now */
1223  RtlpRemoveFreeBlock(Heap, NextEntry, FALSE);
1224 
1225  /* Update sizes */
1226  *FreeSize = *FreeSize + NextEntry->Size;
1227  Heap->TotalFreeSize -= NextEntry->Size;
1228  FreeEntry->Size = (USHORT)(*FreeSize);
1229 
1230  /* Also update previous size if needed */
1231  if (!(FreeEntry->Flags & HEAP_ENTRY_LAST_ENTRY))
1232  {
1233  ((PHEAP_ENTRY)FreeEntry + *FreeSize)->PreviousSize = (USHORT)(*FreeSize);
1234  }
1235  else
1236  {
1237  SegmentOffset = FreeEntry->SegmentOffset;
1238  ASSERT(SegmentOffset < HEAP_SEGMENTS);
1239  }
1240  }
1241  }
1242  return FreeEntry;
1243 }
SIZE_T TotalFreeSize
Definition: heap.h:239
#define HEAP_SEGMENTS
Definition: heap.h:15
static VOID RtlpRemoveFreeBlock(PHEAP Heap, PHEAP_FREE_ENTRY FreeEntry, BOOLEAN NoFill)
Definition: heap.c:422
#define HEAP_MAX_BLOCK_SIZE
Definition: heap.h:23
#define FALSE
Definition: types.h:117
Definition: heap.h:129
struct _HEAP_ENTRY * PHEAP_ENTRY
#define HEAP_ENTRY_BUSY
Definition: heap.h:40
_In_ BOOLEAN Remove
Definition: psfuncs.h:110
#define ASSERT(a)
Definition: mode.c:44
unsigned char UCHAR
Definition: xmlstorage.h:181
struct _HEAP_FREE_ENTRY * PHEAP_FREE_ENTRY
Definition: heap.h:135
unsigned short USHORT
Definition: pedump.c:61
#define HEAP_ENTRY_LAST_ENTRY
Definition: heap.h:44

Referenced by RtlFreeHeap(), RtlpDeCommitFreeBlock(), RtlpExtendHeap(), and RtlpGrowBlockInPlace().

◆ RtlpDebugPageHeapValidate()

BOOLEAN NTAPI RtlpDebugPageHeapValidate ( PVOID  HeapPtr,
ULONG  Flags,
PVOID  Block 
)

Definition at line 2290 of file heappage.c.

2293 {
2294  PDPH_HEAP_ROOT DphRoot;
2296  BOOLEAN Valid = FALSE;
2297 
2298  /* Get a pointer to the heap root */
2299  DphRoot = RtlpDphPointerFromHandle(HeapHandle);
2300  if (!DphRoot) return -1;
2301 
2302  /* Add heap flags */
2303  Flags |= DphRoot->HeapFlags;
2304 
2305  /* Acquire the heap lock */
2306  RtlpDphPreProcessing(DphRoot, Flags);
2307 
2308  /* Find busy memory */
2309  if (BaseAddress)
2311 
2312  if (!Node)
2313  {
2314  /* This block was not found in page heap, or the request is to validate all normal heap */
2315  Valid = RtlpDphNormalHeapValidate(DphRoot, Flags, BaseAddress);
2316  }
2317 
2318  /* Leave the heap lock */
2319  RtlpDphPostProcessing(DphRoot);
2320 
2321  /* Return result of a normal heap validation */
2322  if (BaseAddress && !Node)
2323  return Valid;
2324 
2325  /* Otherwise return our own result */
2326  if (!BaseAddress || Node) Valid = TRUE;
2327 
2328  return Valid;
2329 }
#define TRUE
Definition: types.h:120
VOID NTAPI RtlpDphPostProcessing(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:279
BOOLEAN NTAPI RtlpDphNormalHeapValidate(PDPH_HEAP_ROOT DphRoot, ULONG Flags, PVOID BaseAddress)
Definition: heappage.c:2333
#define FALSE
Definition: types.h:117
PDPH_HEAP_BLOCK NTAPI RtlpDphFindBusyMemory(PDPH_HEAP_ROOT DphRoot, PVOID pUserMem)
Definition: heappage.c:934
ULONG HeapFlags
Definition: heappage.c:64
unsigned char BOOLEAN
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
PVOID NTAPI RtlpDphPointerFromHandle(PVOID Handle)
Definition: heappage.c:218
VOID NTAPI RtlpDphPreProcessing(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
Definition: heappage.c:271
#define NULL
Definition: types.h:112
Definition: dlist.c:348

Referenced by RtlValidateHeap().

◆ RtlpGetExtraStuffPointer()

PHEAP_ENTRY_EXTRA NTAPI RtlpGetExtraStuffPointer ( PHEAP_ENTRY  HeapEntry)

Definition at line 2632 of file heap.c.

2633 {
2634  PHEAP_VIRTUAL_ALLOC_ENTRY VirtualEntry;
2635 
2636  /* Check if it's a big block */
2637  if (HeapEntry->Flags & HEAP_ENTRY_VIRTUAL_ALLOC)
2638  {
2639  VirtualEntry = CONTAINING_RECORD(HeapEntry, HEAP_VIRTUAL_ALLOC_ENTRY, BusyBlock);
2640 
2641  /* Return a pointer to the extra stuff*/
2642  return &VirtualEntry->ExtraStuff;
2643  }
2644  else
2645  {
2646  /* This is a usual entry, which means extra stuff follows this block */
2647  return (PHEAP_ENTRY_EXTRA)(HeapEntry + HeapEntry->Size - 1);
2648  }
2649 }
Definition: heap.h:307
#define HEAP_ENTRY_VIRTUAL_ALLOC
Definition: heap.h:43
Definition: heap.h:291
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
HEAP_ENTRY_EXTRA ExtraStuff
Definition: heap.h:310

Referenced by RtlAllocateHeap(), RtlGetUserInfoHeap(), RtlpAllocateNonDedicated(), RtlReAllocateHeap(), and RtlSetUserValueHeap().

◆ RtlpHeapIsSpecial()

FORCEINLINE BOOLEAN RtlpHeapIsSpecial ( ULONG  Flags)

Definition at line 59 of file heap.h.

60 {
62 
68  {
69  /* This is a special heap */
70  return TRUE;
71  }
72 
73  /* No need for a special treatment */
74  return FALSE;
75 }
#define TRUE
Definition: types.h:120
#define HEAP_CREATE_ENABLE_TRACING
Definition: nt_native.h:1702
#define HEAP_SKIP_VALIDATION_CHECKS
Definition: rtltypes.h:165
#define FALSE
Definition: types.h:117
#define HEAP_VALIDATE_PARAMETERS_ENABLED
Definition: rtltypes.h:167
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define HEAP_VALIDATE_ALL_ENABLED
Definition: rtltypes.h:166
#define HEAP_FLAG_PAGE_ALLOCS
Definition: rtltypes.h:160
#define HEAP_CAPTURE_STACK_BACKTRACES
Definition: rtltypes.h:164

Referenced by RtlAllocateHeap(), RtlCreateHeap(), RtlDestroyHeap(), RtlFreeHeap(), RtlGetUserInfoHeap(), RtlReAllocateHeap(), RtlSetUserFlagsHeap(), RtlSetUserValueHeap(), and RtlSizeHeap().

◆ RtlpPageHeapAllocate()

PVOID NTAPI RtlpPageHeapAllocate ( IN PVOID  HeapPtr,
IN ULONG  Flags,
IN SIZE_T  Size 
)

Definition at line 1697 of file heappage.c.

1700 {
1701  PDPH_HEAP_ROOT DphRoot;
1702  PDPH_HEAP_BLOCK AvailableNode, BusyNode;
1703  BOOLEAN Biased = FALSE;
1704  ULONG AllocateSize, AccessSize;
1705  NTSTATUS Status;
1706  SIZE_T UserActualSize;
1707  PVOID Ptr;
1708 
1709  /* Check requested size */
1710  if (Size > 0x7FF00000)
1711  {
1712  DPRINT1("extreme size request\n");
1713 
1714  /* Generate an exception if needed */
1716 
1717  return NULL;
1718  }
1719 
1720  /* Unbias the pointer if necessary */
1721  if (IS_BIASED_POINTER(HeapPtr))
1722  {
1723  HeapPtr = (PVOID)POINTER_REMOVE_BIAS(HeapPtr);
1724  Biased = TRUE;
1725  }
1726 
1727  /* Get a pointer to the heap root */
1728  DphRoot = RtlpDphPointerFromHandle(HeapPtr);
1729  if (!DphRoot) return NULL;
1730 
1731  /* Acquire the heap lock */
1732  RtlpDphPreProcessing(DphRoot, Flags);
1733 
1734  /* Perform internal validation if specified by flags */
1736  {
1738  }
1739 
1740  /* Add heap flags */
1741  Flags |= DphRoot->HeapFlags;
1742 
1743  if (!Biased && !RtlpDphShouldAllocateInPageHeap(DphRoot, Size))
1744  {
1745  /* Perform allocation from a normal heap */
1746  ASSERT(FALSE);
1747  }
1748 
1749  /* Perform heap integrity check if specified by flags */
1751  {
1752  RtlpDphVerifyIntegrity(DphRoot);
1753  }
1754 
1755  /* Calculate sizes */
1756  AccessSize = ROUND_UP(Size + sizeof(DPH_BLOCK_INFORMATION), PAGE_SIZE);
1757  AllocateSize = AccessSize + PAGE_SIZE;
1758 
1759  // FIXME: Move RtlpDphAllocateNode(DphRoot) to this place
1760  AvailableNode = RtlpDphFindAvailableMemory(DphRoot, AllocateSize, TRUE);
1761  if (!AvailableNode)
1762  {
1763  DPRINT1("Page heap: Unable to allocate virtual memory\n");
1764  DbgBreakPoint();
1765 
1766  /* Release the lock */
1767  RtlpDphPostProcessing(DphRoot);
1768 
1769  return NULL;
1770  }
1771  ASSERT(AvailableNode->nVirtualBlockSize >= AllocateSize);
1772 
1773  /* Set protection */
1775  AvailableNode->pVirtualBlock,
1776  AccessSize);
1777  if (!NT_SUCCESS(Status))
1778  {
1779  ASSERT(FALSE);
1780  }
1781 
1782  /* Save available node pointer */
1783  Ptr = AvailableNode->pVirtualBlock;
1784 
1785  /* Check node's size */
1786  if (AvailableNode->nVirtualBlockSize > AllocateSize)
1787  {
1788  /* The block contains too much free space, reduce it */
1789  AvailableNode->pVirtualBlock += AllocateSize;
1790  AvailableNode->nVirtualBlockSize -= AllocateSize;
1791  DphRoot->nAvailableAllocationBytesCommitted -= AllocateSize;
1792 
1793  /* Allocate a new node which will be our busy node */
1794  BusyNode = RtlpDphAllocateNode(DphRoot);
1795  ASSERT(BusyNode != NULL);
1796  BusyNode->pVirtualBlock = Ptr;
1797  BusyNode->nVirtualBlockSize = AllocateSize;
1798  }
1799  else
1800  {
1801  /* The block's size fits exactly */
1802  RtlpDphRemoveFromAvailableList(DphRoot, AvailableNode);
1803  BusyNode = AvailableNode;
1804  }
1805 
1806  /* Calculate actual user size */
1807  if (DphRoot->HeapFlags & HEAP_NO_ALIGNMENT)
1808  UserActualSize = Size;
1809  else
1810  UserActualSize = ROUND_UP(Size, 8);
1811 
1812  /* Set up the block */
1813  BusyNode->nVirtualAccessSize = AccessSize;
1814  BusyNode->nUserActualSize = UserActualSize;
1815  BusyNode->nUserRequestedSize = Size;
1816 
1817  if (DphRoot->ExtraFlags & DPH_EXTRA_CHECK_UNDERRUN)
1818  BusyNode->pUserAllocation = BusyNode->pVirtualBlock + PAGE_SIZE;
1819  else
1820  BusyNode->pUserAllocation = BusyNode->pVirtualBlock + BusyNode->nVirtualAccessSize - UserActualSize;
1821 
1822  BusyNode->UserValue = NULL;
1824 
1825  // FIXME: Don't forget about stack traces if such flag was set
1826  BusyNode->StackTrace = NULL;
1827 
1828  /* Place it on busy list */
1829  RtlpDphPlaceOnBusyList(DphRoot, BusyNode);
1830 
1831  /* Zero or patter-fill memory depending on flags */
1832  if (Flags & HEAP_ZERO_MEMORY)
1833  RtlZeroMemory(BusyNode->pUserAllocation, Size);
1834  else
1836 
1837  /* Write DPH info */
1838  if (!(DphRoot->ExtraFlags & DPH_EXTRA_CHECK_UNDERRUN))
1839  {
1841  BusyNode->pUserAllocation,
1842  Size,
1843  AccessSize);
1844  }
1845 
1846  /* Finally allocation is done, perform validation again if required */
1848  {
1850  }
1851 
1852  /* Release the lock */
1853  RtlpDphPostProcessing(DphRoot);
1854 
1855  DPRINT("Allocated user block pointer: %p\n", BusyNode->pUserAllocation);
1856 
1857  /* Return pointer to user allocation */
1858  return BusyNode->pUserAllocation;
1859 }
#define DPH_FILL_INFIX
Definition: heappage.c:160
PVOID UserValue
Definition: heappage.c:54
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
#define TRUE
Definition: types.h:120
#define IS_BIASED_POINTER(ptr)
Definition: heappage.c:178
ULONG UserFlags
Definition: heappage.c:55
BOOLEAN NTAPI RtlpDphShouldAllocateInPageHeap(PDPH_HEAP_ROOT DphRoot, SIZE_T Size)
Definition: heappage.c:1463
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI RtlpDphPostProcessing(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:279
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
NTSTATUS NTAPI RtlpDphSetProtectionBeforeUse(PDPH_HEAP_ROOT DphRoot, PUCHAR VirtualBlock, ULONG UserSize)
Definition: heappage.c:951
#define POINTER_REMOVE_BIAS(ptr)
Definition: heappage.c:179
#define FALSE
Definition: types.h:117
VOID NTAPI DbgBreakPoint(VOID)
SIZE_T nUserActualSize
Definition: heappage.c:53
ULONG HeapFlags
Definition: heappage.c:64
ULONG ExtraFlags
Definition: heappage.c:97
unsigned char BOOLEAN
SIZE_T nVirtualAccessSize
Definition: heappage.c:51
PDPH_HEAP_BLOCK NTAPI RtlpDphAllocateNode(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:988
void * PVOID
Definition: retypes.h:9
Status
Definition: gdiplustypes.h:24
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define ASSERT(a)
Definition: mode.c:44
PUCHAR pUserAllocation
Definition: heappage.c:48
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
#define HEAP_SETTABLE_USER_FLAGS
Definition: nt_native.h:1708
#define HEAP_NO_ALIGNMENT
Definition: rtltypes.h:163
PRTL_TRACE_BLOCK StackTrace
Definition: heappage.c:56
PUCHAR pVirtualBlock
Definition: heappage.c:49
#define DPH_EXTRA_CHECK_UNDERRUN
Definition: heappage.c:151
VOID NTAPI RtlpDphInternalValidatePageHeap(PDPH_HEAP_ROOT DphRoot, PVOID Address, ULONG Value)
Definition: heappage.c:1288
BOOLEAN NTAPI RtlpDphWritePageHeapBlockInformation(PDPH_HEAP_ROOT DphRoot, PVOID UserAllocation, SIZE_T Size, SIZE_T UserSize)
Definition: heappage.c:415
VOID NTAPI RtlpDphPlaceOnBusyList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK DphNode)
Definition: heappage.c:441
SIZE_T nVirtualBlockSize
Definition: heappage.c:50
#define PAGE_SIZE
Definition: env_spec_w32.h:49
SIZE_T nUserRequestedSize
Definition: heappage.c:52
#define DPH_DEBUG_INTERNAL_VALIDATE
Definition: heappage.c:146
ULONG_PTR SIZE_T
Definition: typedefs.h:80
PDPH_HEAP_BLOCK NTAPI RtlpDphFindAvailableMemory(PDPH_HEAP_ROOT DphRoot, SIZE_T Size, BOOLEAN Grow)
Definition: heappage.c:878
PVOID NTAPI RtlpDphPointerFromHandle(PVOID Handle)
Definition: heappage.c:218
VOID NTAPI RtlpDphPreProcessing(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
Definition: heappage.c:271
VOID NTAPI RtlpDphRaiseException(NTSTATUS Status)
Definition: heappage.c:202
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define NULL
Definition: types.h:112
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define DPRINT1
Definition: precomp.h:8
VOID NTAPI RtlpDphRemoveFromAvailableList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:559
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
ULONG RtlpDphDebugOptions
Definition: heappage.c:184
#define DPRINT
Definition: sndvol32.h:71
#define HEAP_GENERATE_EXCEPTIONS
Definition: nt_native.h:1694
VOID NTAPI RtlpDphVerifyIntegrity(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:1294
SIZE_T nAvailableAllocationBytesCommitted
Definition: heappage.c:85

Referenced by RtlDebugAllocateHeap(), and RtlpPageHeapReAllocate().

◆ RtlpPageHeapCreate()

HANDLE NTAPI RtlpPageHeapCreate ( ULONG  Flags,
PVOID  Addr,
SIZE_T  TotalSize,
SIZE_T  CommitSize,
PVOID  Lock,
PRTL_HEAP_PARAMETERS  Parameters 
)

Definition at line 1472 of file heappage.c.

1478 {
1479  PVOID Base = NULL;
1480  PHEAP HeapPtr;
1481  PDPH_HEAP_ROOT DphRoot;
1482  PDPH_HEAP_BLOCK DphNode;
1483  ULONG MemSize;
1484  NTSTATUS Status;
1485  LARGE_INTEGER PerfCounter;
1486 
1487  /* Check for a DPH bypass flag */
1488  if ((ULONG_PTR)Parameters == -1) return NULL;
1489 
1490  /* Make sure no user-allocated stuff was provided */
1491  if (Addr || Lock) return NULL;
1492 
1493  /* Allocate minimum amount of virtual memory */
1494  MemSize = DPH_RESERVE_SIZE;
1496  if (!NT_SUCCESS(Status))
1497  {
1498  ASSERT(FALSE);
1499  return NULL;
1500  }
1501 
1502  /* Set protection */
1504  if (!NT_SUCCESS(Status))
1505  {
1506  //RtlpDphFreeVm(Base, 0, 0, 0);
1507  ASSERT(FALSE);
1508  return NULL;
1509  }
1510 
1511  /* Start preparing the 1st page. Fill it with the default filler */
1513 
1514  /* Set flags in the "HEAP" structure */
1515  HeapPtr = (PHEAP)Base;
1516  HeapPtr->Flags = Flags | HEAP_FLAG_PAGE_ALLOCS;
1517  HeapPtr->ForceFlags = Flags | HEAP_FLAG_PAGE_ALLOCS;
1518 
1519  /* Set 1st page to read only now */
1521  if (!NT_SUCCESS(Status))
1522  {
1523  ASSERT(FALSE);
1524  return NULL;
1525  }
1526 
1527  /* 2nd page is the real DPH root block */
1528  DphRoot = (PDPH_HEAP_ROOT)((PCHAR)Base + PAGE_SIZE);
1529 
1530  /* Initialize the DPH root */
1531  DphRoot->Signature = DPH_SIGNATURE;
1532  DphRoot->HeapFlags = Flags;
1533  DphRoot->HeapCritSect = (PHEAP_LOCK)((PCHAR)DphRoot + DPH_POOL_SIZE);
1534  DphRoot->ExtraFlags = RtlpDphGlobalFlags;
1535 
1536  ZwQueryPerformanceCounter(&PerfCounter, NULL);
1537  DphRoot->Seed = PerfCounter.LowPart;
1538 
1541 
1542  /* Create a normal heap for this paged heap */
1543  DphRoot->NormalHeap = RtlCreateHeap(Flags, NULL, TotalSize, CommitSize, NULL, (PRTL_HEAP_PARAMETERS)-1);
1544  if (!DphRoot->NormalHeap)
1545  {
1546  ASSERT(FALSE);
1547  return NULL;
1548  }
1549 
1550  /* 3rd page: a pool for DPH allocations */
1551  RtlpDphAddNewPool(DphRoot, NULL, DphRoot + 1, DPH_POOL_SIZE - sizeof(DPH_HEAP_ROOT), FALSE);
1552 
1553  /* Allocate internal heap blocks. For the root */
1554  DphNode = RtlpDphAllocateNode(DphRoot);
1555  ASSERT(DphNode != NULL);
1556  DphNode->pVirtualBlock = (PUCHAR)DphRoot;
1557  DphNode->nVirtualBlockSize = DPH_POOL_SIZE;
1558  RtlpDphPlaceOnPoolList(DphRoot, DphNode);
1559 
1560  /* For the memory we allocated as a whole */
1561  DphNode = RtlpDphAllocateNode(DphRoot);
1562  ASSERT(DphNode != NULL);
1563  DphNode->pVirtualBlock = Base;
1564  DphNode->nVirtualBlockSize = MemSize;
1565  RtlpDphPlaceOnVirtualList(DphRoot, DphNode);
1566 
1567  /* For the remaining part */
1568  DphNode = RtlpDphAllocateNode(DphRoot);
1569  ASSERT(DphNode != NULL);
1570  DphNode->pVirtualBlock = (PUCHAR)Base + 2*PAGE_SIZE + DPH_POOL_SIZE;
1571  DphNode->nVirtualBlockSize = MemSize - (2*PAGE_SIZE + DPH_POOL_SIZE);
1572  RtlpDphCoalesceNodeIntoAvailable(DphRoot, DphNode);
1573 
1574  //DphRoot->CreateStackTrace = RtlpDphLogStackTrace(1);
1575 
1576  /* Initialize AVL-based busy nodes table */
1581  NULL);
1582 
1583  /* Initialize per-process startup info */
1585 
1586  /* Acquire the heap list lock */
1588 
1589  /* Insert this heap to the tail of the global list */
1591 
1592  /* Note we increased the size of the list */
1594 
1595  /* Release the heap list lock */
1597 
1599  {
1600  DPRINT1("Page heap: process 0x%p created heap @ %p (%p, flags 0x%X)\n",
1602  DphRoot->NormalHeap, DphRoot->ExtraFlags);
1603  }
1604 
1605  /* Perform internal validation if required */
1608 
1609  return (PUCHAR)DphRoot - PAGE_SIZE;
1610 }
#define DPH_DEBUG_VERBOSE
Definition: heappage.c:147
signed char * PCHAR
Definition: retypes.h:7
NTSYSAPI NTSTATUS NTAPI ZwQueryPerformanceCounter(_Out_ PLARGE_INTEGER Counter, _Out_opt_ PLARGE_INTEGER Frequency)
NTSTATUS NTAPI RtlpDphProcessStartupInitialization(VOID)
Definition: heappage.c:1431
LIST_ENTRY AvailableAllocationHead
Definition: heappage.c:83
struct _DPH_HEAP_ROOT * PDPH_HEAP_ROOT
PHEAP_LOCK RtlpDphPageHeapListLock
Definition: heappage.c:115
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:863
NTSTATUS NTAPI RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
Definition: libsupp.c:108
VOID NTAPI RtlpDphPlaceOnVirtualList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:505
#define TRUE
Definition: types.h:120
VOID NTAPI RtlpDphAddNewPool(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK NodeBlock, PVOID Virtual, SIZE_T Size, BOOLEAN PlaceOnPool)
Definition: heappage.c:799
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI RtlpDphProtectVm(PVOID Base, SIZE_T Size, ULONG Protection)
Definition: heappage.c:391
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2386
#define DPH_RESERVE_SIZE
Definition: heappage.c:133
PVOID NormalHeap
Definition: heappage.c:99
#define InsertTailList(ListHead, Entry)
HANDLE UniqueProcess
Definition: compat.h:684
#define MEM_COMMIT
Definition: nt_native.h:1313
ULONG RtlpDphGlobalFlags
Definition: heappage.c:107
LIST_ENTRY RtlpDphPageHeapList
Definition: heappage.c:112
struct _HEAP_LOCK * PHEAP_LOCK
uint32_t ULONG_PTR
Definition: typedefs.h:65
PHEAP_LOCK HeapCritSect
Definition: heappage.c:65
PVOID NTAPI RtlpDphAllocateNodeForTable(IN PRTL_AVL_TABLE Table, IN CLONG ByteSize)
Definition: heappage.c:1176
VOID NTAPI RtlpDphCoalesceNodeIntoAvailable(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:654
#define FALSE
Definition: types.h:117
ULONG HeapFlags
Definition: heappage.c:64
ULONG ExtraFlags
Definition: heappage.c:97
#define PAGE_NOACCESS
Definition: nt_native.h:1302
PDPH_HEAP_BLOCK NTAPI RtlpDphAllocateNode(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:988
ULONG RtlpDphPageHeapListLength
Definition: heappage.c:116
VOID NTAPI RtlpDphPlaceOnPoolList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:485
VOID NTAPI RtlpDphFreeNodeForTable(IN PRTL_AVL_TABLE Table, IN PVOID Buffer)
Definition: heappage.c:1197
NTSTATUS NTAPI RtlLeaveHeapLock(IN OUT PHEAP_LOCK Lock)
Definition: libsupp.c:133
#define RtlFillMemoryUlong(dst, len, val)
Definition: mkhive.h:55
#define DPH_FILL
Definition: heappage.c:154
#define DPH_POOL_SIZE
Definition: heappage.c:134
Status
Definition: gdiplustypes.h:24
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1163
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T CommitSize
Definition: mmfuncs.h:404
NTSTATUS NTAPI RtlInitializeHeapLock(IN OUT PHEAP_LOCK *Lock)
Definition: libsupp.c:126
PUCHAR pVirtualBlock
Definition: heappage.c:49
VOID NTAPI RtlpDphInternalValidatePageHeap(PDPH_HEAP_ROOT DphRoot, PVOID Address, ULONG Value)
Definition: heappage.c:1288
NTSTATUS NTAPI RtlpDphAllocateVm(PVOID *Base, SIZE_T Size, ULONG Type, ULONG Protection)
Definition: heappage.c:316
SIZE_T nVirtualBlockSize
Definition: heappage.c:50
ULONG LowPart
Definition: typedefs.h:106
VOID NTAPI RtlInitializeGenericTableAvl(IN OUT PRTL_AVL_TABLE Table, IN PRTL_AVL_COMPARE_ROUTINE CompareRoutine, IN PRTL_AVL_ALLOCATE_ROUTINE AllocateRoutine, IN PRTL_AVL_FREE_ROUTINE FreeRoutine, IN PVOID TableContext)
Definition: avltable.c:26
NTSYSAPI PVOID NTAPI RtlCreateHeap(IN ULONG Flags, IN PVOID HeapBase OPTIONAL, IN ULONG ReserveSize OPTIONAL, IN ULONG CommitSize OPTIONAL, IN PVOID Lock OPTIONAL, IN PRTL_HEAP_PARAMETERS Parameters OPTIONAL)
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define HEAP_FLAG_PAGE_ALLOCS
Definition: rtltypes.h:160
#define DPH_DEBUG_INTERNAL_VALIDATE
Definition: heappage.c:146
LIST_ENTRY NextHeap
Definition: heappage.c:96
ULONG Seed
Definition: heappage.c:98
ULONG Signature
Definition: heappage.c:63
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
ULONG Flags
Definition: heap.h:226
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define NULL
Definition: types.h:112
#define PAGE_READONLY
Definition: compat.h:138
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
BOOLEAN RtlpDphPageHeapListInitialized
Definition: heappage.c:113
unsigned int ULONG
Definition: retypes.h:1
struct _HEAP * PHEAP
ULONG ForceFlags
Definition: heap.h:227
ULONG RtlpDphDebugOptions
Definition: heappage.c:184
RTL_AVL_TABLE BusyNodesTable
Definition: heappage.c:73
RTL_GENERIC_COMPARE_RESULTS NTAPI RtlpDphCompareNodeForTable(IN PRTL_AVL_TABLE Table, IN PVOID FirstStruct, IN PVOID SecondStruct)
Definition: heappage.c:1157
#define DPH_SIGNATURE
Definition: heappage.c:175
Definition: heap.c:51
#define PAGE_READWRITE
Definition: nt_native.h:1304

Referenced by RtlCreateHeap().

◆ RtlpPageHeapDestroy()

PVOID NTAPI RtlpPageHeapDestroy ( HANDLE  HeapPtr)

Definition at line 1613 of file heappage.c.

1614 {
1615  PDPH_HEAP_ROOT DphRoot;
1616  PVOID Ptr;
1617  PDPH_HEAP_BLOCK Node, Next;
1618  PHEAP NormalHeap;
1619  ULONG Value;
1620 
1621  /* Check if it's not a process heap */
1622  if (HeapPtr == RtlGetProcessHeap())
1623  {
1624  DbgBreakPoint();
1625  return NULL;
1626  }
1627 
1628  /* Get pointer to the heap root */
1629  DphRoot = RtlpDphPointerFromHandle(HeapPtr);
1630  if (!DphRoot) return NULL;
1631 
1632  RtlpDphPreProcessing(DphRoot, DphRoot->HeapFlags);
1633 
1634  /* Get the pointer to the normal heap */
1635  NormalHeap = DphRoot->NormalHeap;
1636 
1637  /* Free the delayed-free blocks */
1638  RtlpDphFreeDelayedBlocksFromHeap(DphRoot, NormalHeap);
1639 
1640  /* Go through the busy blocks */
1642 
1643  while (Ptr)
1644  {
1645  Node = CONTAINING_RECORD(Ptr, DPH_HEAP_BLOCK, pUserAllocation);
1646  if (!(DphRoot->ExtraFlags & DPH_EXTRA_CHECK_UNDERRUN))
1647  {
1648  if (!RtlpDphIsPageHeapBlock(DphRoot, Node->pUserAllocation, &Value, TRUE))
1649  {
1650  RtlpDphReportCorruptedBlock(DphRoot, 3, Node->pUserAllocation, Value);
1651  }
1652  }
1653 
1654  /* FIXME: Call AV notification */
1655  //AVrfInternalHeapFreeNotification();
1656 
1657  /* Go to the next node */
1659  }
1660 
1661  /* Acquire the global heap list lock */
1663 
1664  /* Remove the entry and decrement the global counter */
1665  RemoveEntryList(&DphRoot->NextHeap);
1667 
1668  /* Release the global heap list lock */
1670 
1671  /* Leave and delete this heap's critical section */
1672  RtlLeaveHeapLock(DphRoot->HeapCritSect);
1673  RtlDeleteHeapLock(DphRoot->HeapCritSect);
1674 
1675  /* Now go through all virtual list nodes and release the VM */
1676  Node = DphRoot->pVirtualStorageListHead;
1677  while (Node)
1678  {
1679  Next = Node->pNextAlloc;
1680  /* Release the memory without checking result */
1681  RtlpDphFreeVm(Node->pVirtualBlock, 0, MEM_RELEASE);
1682  Node = Next;
1683  }
1684 
1685  /* Destroy the normal heap */
1686  RtlDestroyHeap(NormalHeap);
1687 
1688  /* Report success */
1690  DPRINT1("Page heap: process 0x%p destroyed heap @ %p (%p)\n",
1691  NtCurrentTeb()->ClientId.UniqueProcess, HeapPtr, NormalHeap);
1692 
1693  return NULL;
1694 }
#define DPH_DEBUG_VERBOSE
Definition: heappage.c:147
PHEAP_LOCK RtlpDphPageHeapListLock
Definition: heappage.c:115
NTSTATUS NTAPI RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
Definition: libsupp.c:108
#define TRUE
Definition: types.h:120
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
PVOID NormalHeap
Definition: heappage.c:99
HANDLE UniqueProcess
Definition: compat.h:684
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
PHEAP_LOCK HeapCritSect
Definition: heappage.c:65
PDPH_HEAP_BLOCK pVirtualStorageListHead
Definition: heappage.c:68
#define FALSE
Definition: types.h:117
VOID NTAPI DbgBreakPoint(VOID)
union node Node
Definition: types.h:1255
ULONG HeapFlags
Definition: heappage.c:64
ULONG ExtraFlags
Definition: heappage.c:97
NTSYSAPI PVOID NTAPI RtlDestroyHeap(IN PVOID HeapHandle)
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
ULONG RtlpDphPageHeapListLength
Definition: heappage.c:116
NTSTATUS NTAPI RtlLeaveHeapLock(IN OUT PHEAP_LOCK Lock)
Definition: libsupp.c:133
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1163
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlEnumerateGenericTableAvl(_In_ PRTL_AVL_TABLE Table, _In_ BOOLEAN Restart)
VOID NTAPI RtlpDphFreeDelayedBlocksFromHeap(PDPH_HEAP_ROOT DphRoot, PHEAP NormalHeap)
Definition: heappage.c:1228
VOID NTAPI RtlpDphReportCorruptedBlock(PDPH_HEAP_ROOT DphRoot, ULONG Reserved, PVOID Block, ULONG ValidationInfo)
Definition: heappage.c:1300
#define DPH_EXTRA_CHECK_UNDERRUN
Definition: heappage.c:151
LIST_ENTRY NextHeap
Definition: heappage.c:96
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
PVOID NTAPI RtlpDphPointerFromHandle(PVOID Handle)
Definition: heappage.c:218
VOID NTAPI RtlpDphPreProcessing(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
Definition: heappage.c:271
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
NTSTATUS NTAPI RtlpDphFreeVm(PVOID Base, SIZE_T Size, ULONG Type)
Definition: heappage.c:355
#define MEM_RELEASE
Definition: nt_native.h:1316
BOOLEAN NTAPI RtlpDphIsPageHeapBlock(PDPH_HEAP_ROOT DphRoot, PVOID Block, PULONG ValidationInformation, BOOLEAN CheckFillers)
Definition: heappage.c:1356
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS NTAPI RtlDeleteHeapLock(IN OUT PHEAP_LOCK Lock)
Definition: libsupp.c:101
ULONG RtlpDphDebugOptions
Definition: heappage.c:184
RTL_AVL_TABLE BusyNodesTable
Definition: heappage.c:73
Definition: heap.c:51
Definition: dlist.c:348

Referenced by RtlDestroyHeap().

◆ RtlpPageHeapFree()

BOOLEAN NTAPI RtlpPageHeapFree ( HANDLE  HeapPtr,
ULONG  Flags,
PVOID  Ptr 
)

Definition at line 1862 of file heappage.c.

1865 {
1866  PDPH_HEAP_ROOT DphRoot;
1868  ULONG ValidationInfo;
1870 
1871  /* Check for a NULL pointer freeing */
1872  if (!Ptr)
1873  {
1875  {
1876  DPRINT1("Page heap: freeing a null pointer\n");
1877  DbgBreakPoint();
1878  }
1879  return TRUE;
1880  }
1881 
1882  /* Get a pointer to the heap root */
1883  DphRoot = RtlpDphPointerFromHandle(HeapPtr);
1884  if (!DphRoot) return FALSE;
1885 
1886  /* Acquire the heap lock */
1887  RtlpDphPreProcessing(DphRoot, Flags);
1888 
1889  /* Perform internal validation if specified by flags */
1892 
1893  /* Add heap flags */
1894  Flags |= DphRoot->HeapFlags;
1895 
1896  /* Find busy memory */
1897  Node = RtlpDphFindBusyMemory(DphRoot, Ptr);
1898 
1899  if (!Node)
1900  {
1901  /* This block was not found in page heap, try a normal heap instead */
1902  //RtlpDphNormalHeapFree();
1903  ASSERT(FALSE);
1904  }
1905 
1906  if (!(DphRoot->ExtraFlags & DPH_EXTRA_CHECK_UNDERRUN))
1907  {
1908  /* Check and report corrupted block */
1909  if (!RtlpDphIsPageHeapBlock(DphRoot, Ptr, &ValidationInfo, TRUE))
1910  {
1911  RtlpDphReportCorruptedBlock(DphRoot, 1, Ptr, ValidationInfo);
1912  }
1913 
1914  // FIXME: Should go inside RtlpDphSetProtectionAfterUse
1915  if (Node->nVirtualAccessSize != 0)
1916  {
1917  /* Set stamps */
1918  Info = (PDPH_BLOCK_INFORMATION)Node->pUserAllocation - 1;
1919  Info->StartStamp = DPH_FILL_START_STAMP_2;
1920  Info->EndStamp = DPH_FILL_END_STAMP_2;
1921 
1922  RtlpDphProtectVm(Node->pVirtualBlock, Node->nVirtualAccessSize, PAGE_NOACCESS);
1923  }
1924  }
1925  else
1926  {
1927  // FIXME: Should go inside RtlpDphSetProtectionAfterUse
1928  if (Node->nVirtualAccessSize != 0)
1929  RtlpDphProtectVm(Node->pVirtualBlock + PAGE_SIZE, Node->nVirtualAccessSize, PAGE_NOACCESS);
1930  }
1931 
1932  /* Set new protection */
1933  //RtlpDphSetProtectionAfterUse(DphRoot, Node);
1934 
1935  /* Remove it from the list of busy nodes */
1936  RtlpDphRemoveFromBusyList(DphRoot, Node);
1937 
1938  /* And put it into the list of free nodes */
1939  RtlpDphPlaceOnFreeList(DphRoot, Node);
1940 
1941  //if (DphRoot->ExtraFlags & DPH_EXTRA_LOG_STACK_TRACES)
1942  // Node->StackTrace = RtlpDphLogStackTrace(3);
1943  //else
1944  Node->StackTrace = NULL;
1945 
1946  /* Leave the heap lock */
1947  RtlpDphPostProcessing(DphRoot);
1948 
1949  /* Return success */
1950  return TRUE;
1951 }
#define TRUE
Definition: types.h:120
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
VOID NTAPI RtlpDphPostProcessing(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:279
NTSTATUS NTAPI RtlpDphProtectVm(PVOID Base, SIZE_T Size, ULONG Protection)
Definition: heappage.c:391
#define DPH_FILL_END_STAMP_2
Definition: heappage.c:158
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:683
#define FALSE
Definition: types.h:117
VOID NTAPI RtlpDphRemoveFromBusyList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:612
VOID NTAPI DbgBreakPoint(VOID)
PDPH_HEAP_BLOCK NTAPI RtlpDphFindBusyMemory(PDPH_HEAP_ROOT DphRoot, PVOID pUserMem)
Definition: heappage.c:934
union node Node
Definition: types.h:1255
ULONG HeapFlags
Definition: heappage.c:64
ULONG ExtraFlags
Definition: heappage.c:97
#define PAGE_NOACCESS
Definition: nt_native.h:1302
struct _DPH_BLOCK_INFORMATION * PDPH_BLOCK_INFORMATION
VOID NTAPI RtlpDphPlaceOnFreeList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:465
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define ASSERT(a)
Definition: mode.c:44
#define DPH_FILL_START_STAMP_2
Definition: heappage.c:156
VOID NTAPI RtlpDphReportCorruptedBlock(PDPH_HEAP_ROOT DphRoot, ULONG Reserved, PVOID Block, ULONG ValidationInfo)
Definition: heappage.c:1300
#define DPH_EXTRA_CHECK_UNDERRUN
Definition: heappage.c:151
VOID NTAPI RtlpDphInternalValidatePageHeap(PDPH_HEAP_ROOT DphRoot, PVOID Address, ULONG Value)
Definition: heappage.c:1288
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define DPH_DEBUG_INTERNAL_VALIDATE
Definition: heappage.c:146
#define DPH_BREAK_ON_NULL_FREE
Definition: heappage.c:143
PVOID NTAPI RtlpDphPointerFromHandle(PVOID Handle)
Definition: heappage.c:218
VOID NTAPI RtlpDphPreProcessing(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
Definition: heappage.c:271
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
ULONG RtlpDphBreakOptions
Definition: heappage.c:183
BOOLEAN NTAPI RtlpDphIsPageHeapBlock(PDPH_HEAP_ROOT DphRoot, PVOID Block, PULONG ValidationInformation, BOOLEAN CheckFillers)
Definition: heappage.c:1356
unsigned int ULONG
Definition: retypes.h:1
ULONG RtlpDphDebugOptions
Definition: heappage.c:184
Definition: dlist.c:348

Referenced by RtlDebugFreeHeap().

◆ RtlpPageHeapGetUserInfo()

BOOLEAN NTAPI RtlpPageHeapGetUserInfo ( PVOID  HeapHandle,
ULONG  Flags,
PVOID  BaseAddress,
PVOID UserValue,
PULONG  UserFlags 
)

Definition at line 2124 of file heappage.c.

2129 {
2130  PDPH_HEAP_ROOT DphRoot;
2132 
2133  /* Get a pointer to the heap root */
2134  DphRoot = RtlpDphPointerFromHandle(HeapHandle);
2135  if (!DphRoot) return FALSE;
2136 
2137  /* Add heap flags */
2138  Flags |= DphRoot->HeapFlags;
2139 
2140  /* Acquire the heap lock */
2141  RtlpDphPreProcessing(DphRoot, Flags);
2142 
2143  /* Find busy memory */
2145 
2146  if (!Node)
2147  {
2148  /* This block was not found in page heap, try a normal heap instead */
2149  //RtlpDphNormalHeapGetUserInfo();
2150  ASSERT(FALSE);
2151  return FALSE;
2152  }
2153 
2154  /* Get user values and flags and store them in user provided pointers */
2155  if (UserValue) *UserValue = Node->UserValue;
2156  if (UserFlags) *UserFlags = Node->UserFlags;
2157 
2158  /* Leave the heap lock */
2159  RtlpDphPostProcessing(DphRoot);
2160 
2161  /* Return success */
2162  return TRUE;
2163 }
#define TRUE
Definition: types.h:120
VOID NTAPI RtlpDphPostProcessing(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:279
#define FALSE
Definition: types.h:117
PDPH_HEAP_BLOCK NTAPI RtlpDphFindBusyMemory(PDPH_HEAP_ROOT DphRoot, PVOID pUserMem)
Definition: heappage.c:934
union node Node
Definition: types.h:1255
ULONG HeapFlags
Definition: heappage.c:64
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define ASSERT(a)
Definition: mode.c:44
PVOID NTAPI RtlpDphPointerFromHandle(PVOID Handle)
Definition: heappage.c:218
VOID NTAPI RtlpDphPreProcessing(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
Definition: heappage.c:271
Definition: dlist.c:348

Referenced by RtlDebugGetUserInfoHeap().

◆ RtlpPageHeapLock()

BOOLEAN NTAPI RtlpPageHeapLock ( HANDLE  HeapPtr)

Definition at line 2354 of file heappage.c.

2355 {
2356  PDPH_HEAP_ROOT DphRoot;
2357 
2358  /* Get pointer to the heap root */
2359  DphRoot = RtlpDphPointerFromHandle(HeapPtr);
2360  if (!DphRoot) return FALSE;
2361 
2362  RtlpDphEnterCriticalSection(DphRoot, DphRoot->HeapFlags);
2363  return TRUE;
2364 }
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
ULONG HeapFlags
Definition: heappage.c:64
VOID NTAPI RtlpDphEnterCriticalSection(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
Definition: heappage.c:235
PVOID NTAPI RtlpDphPointerFromHandle(PVOID Handle)
Definition: heappage.c:218

Referenced by RtlLockHeap().

◆ RtlpPageHeapReAllocate()

PVOID NTAPI RtlpPageHeapReAllocate ( HANDLE  HeapPtr,
ULONG  Flags,
PVOID  Ptr,
SIZE_T  Size 
)

Definition at line 1954 of file heappage.c.

1958 {
1959  PDPH_HEAP_ROOT DphRoot;
1960  PDPH_HEAP_BLOCK Node = NULL, AllocatedNode;
1961  BOOLEAN Biased = FALSE, UseNormalHeap = FALSE, OldBlockPageHeap = TRUE;
1962  ULONG ValidationInfo;
1963  SIZE_T DataSize;
1964  PVOID NewAlloc = NULL;
1965 
1966  /* Check requested size */
1967  if (Size > 0x7FF00000)
1968  {
1969  DPRINT1("extreme size request\n");
1970 
1971  /* Generate an exception if needed */
1973 
1974  return NULL;
1975  }
1976 
1977  /* Unbias the pointer if necessary */
1978  if (IS_BIASED_POINTER(HeapPtr))
1979  {
1980  HeapPtr = (PVOID)POINTER_REMOVE_BIAS(HeapPtr);
1981  Biased = TRUE;
1982  }
1983 
1984  /* Get a pointer to the heap root */
1985  DphRoot = RtlpDphPointerFromHandle(HeapPtr);
1986  if (!DphRoot) return NULL;
1987 
1988  /* Acquire the heap lock */
1989  RtlpDphPreProcessing(DphRoot, Flags);
1990 
1991  /* Perform internal validation if specified by flags */
1993  {
1995  }
1996 
1997  /* Add heap flags */
1998  Flags |= DphRoot->HeapFlags;
1999 
2000  /* Exit with NULL right away if inplace is specified */
2002  {
2003  /* Release the lock */
2004  RtlpDphPostProcessing(DphRoot);
2005 
2006  /* Generate an exception if needed */
2008 
2009  return NULL;
2010  }
2011 
2012  /* Try to get node of the allocated block */
2013  AllocatedNode = RtlpDphFindBusyMemory(DphRoot, Ptr);
2014 
2015  if (!AllocatedNode)
2016  {
2017  /* This block was not found in page heap, try a normal heap instead */
2018  //RtlpDphNormalHeapFree();
2019  ASSERT(FALSE);
2020  OldBlockPageHeap = FALSE;
2021  }
2022 
2023  /* Check the block */
2024  if (!(DphRoot->ExtraFlags & DPH_EXTRA_CHECK_UNDERRUN))
2025  {
2026  if (!RtlpDphIsPageHeapBlock(DphRoot, AllocatedNode->pUserAllocation, &ValidationInfo, TRUE))
2027  {
2028  RtlpDphReportCorruptedBlock(DphRoot, 3, AllocatedNode->pUserAllocation, ValidationInfo);
2029  }
2030  }
2031 
2032  /* Remove old one from the busy list */
2033  RtlpDphRemoveFromBusyList(DphRoot, AllocatedNode);
2034 
2035  if (!Biased && !RtlpDphShouldAllocateInPageHeap(DphRoot, Size))
2036  {
2037  // FIXME: Use normal heap
2038  ASSERT(FALSE);
2039  UseNormalHeap = TRUE;
2040  }
2041  else
2042  {
2043  /* Now do a trick: bias the pointer and call our allocate routine */
2044  NewAlloc = RtlpPageHeapAllocate((PVOID)POINTER_ADD_BIAS(HeapPtr), Flags, Size);
2045  }
2046 
2047  if (!NewAlloc)
2048  {
2049  /* New allocation failed, put the block back (if it was found in page heap) */
2050  RtlpDphPlaceOnBusyList(DphRoot, AllocatedNode);
2051 
2052  /* Release the lock */
2053  RtlpDphPostProcessing(DphRoot);
2054 
2055  /* Perform validation again if required */
2057  {
2059  }
2060 
2061  /* Generate an exception if needed */
2063 
2064  return NULL;
2065  }
2066 
2067  /* Copy contents of the old block */
2068  if (AllocatedNode->nUserRequestedSize > Size)
2069  DataSize = Size;
2070  else
2071  DataSize = AllocatedNode->nUserRequestedSize;
2072 
2073  if (DataSize != 0) RtlCopyMemory(NewAlloc, Ptr, DataSize);
2074 
2075  /* Copy user flags and values */
2076  if (!UseNormalHeap)
2077  {
2078  /* Get the node of the new block */
2079  Node = RtlpDphFindBusyMemory(DphRoot, NewAlloc);
2080  ASSERT(Node != NULL);
2081 
2082  /* Set its values/flags */
2083  Node->UserValue = AllocatedNode->UserValue;
2085  Node->UserFlags = Flags & HEAP_SETTABLE_USER_FLAGS;
2086  else
2087  Node->UserFlags = AllocatedNode->UserFlags;
2088  }
2089 
2090  if (!OldBlockPageHeap)
2091  {
2092  /* Weird scenario, investigate */
2093  ASSERT(FALSE);
2094  }
2095 
2096  /* Mark the old block as no access */
2097  if (AllocatedNode->nVirtualAccessSize != 0)
2098  {
2099  RtlpDphProtectVm(AllocatedNode->pVirtualBlock, AllocatedNode->nVirtualAccessSize, PAGE_NOACCESS);
2100  }
2101 
2102  /* And place it on the free list */
2103  RtlpDphPlaceOnFreeList(DphRoot, AllocatedNode);
2104 
2105  // FIXME: Capture stack traces if needed
2106  AllocatedNode->StackTrace = NULL;
2107 
2108  /* Finally allocation is done, perform validation again if required */
2110  {
2112  }
2113 
2114  /* Release the lock */
2115  RtlpDphPostProcessing(DphRoot);
2116 
2117  DPRINT("Allocated new user block pointer: %p\n", NewAlloc);
2118 
2119  /* Return pointer to user allocation */
2120  return NewAlloc;
2121 }
#define TRUE
Definition: types.h:120
#define IS_BIASED_POINTER(ptr)
Definition: heappage.c:178
BOOLEAN NTAPI RtlpDphShouldAllocateInPageHeap(PDPH_HEAP_ROOT DphRoot, SIZE_T Size)
Definition: heappage.c:1463
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
VOID NTAPI RtlpDphPostProcessing(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:279
NTSTATUS NTAPI RtlpDphProtectVm(PVOID Base, SIZE_T Size, ULONG Protection)
Definition: heappage.c:391
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
#define POINTER_REMOVE_BIAS(ptr)
Definition: heappage.c:179
#define POINTER_ADD_BIAS(ptr)
Definition: heappage.c:180
#define FALSE
Definition: types.h:117
VOID NTAPI RtlpDphRemoveFromBusyList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:612
PDPH_HEAP_BLOCK NTAPI RtlpDphFindBusyMemory(PDPH_HEAP_ROOT DphRoot, PVOID pUserMem)
Definition: heappage.c:934
ULONG HeapFlags
Definition: heappage.c:64
ULONG ExtraFlags
Definition: heappage.c:97
#define PAGE_NOACCESS
Definition: nt_native.h:1302
unsigned char BOOLEAN
void * PVOID
Definition: retypes.h:9
VOID NTAPI RtlpDphPlaceOnFreeList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:465
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define ASSERT(a)
Definition: mode.c:44
#define HEAP_SETTABLE_USER_FLAGS
Definition: nt_native.h:1708
VOID NTAPI RtlpDphReportCorruptedBlock(PDPH_HEAP_ROOT DphRoot, ULONG Reserved, PVOID Block, ULONG ValidationInfo)
Definition: heappage.c:1300
#define DPH_EXTRA_CHECK_UNDERRUN
Definition: heappage.c:151
VOID NTAPI RtlpDphInternalValidatePageHeap(PDPH_HEAP_ROOT DphRoot, PVOID Address, ULONG Value)
Definition: heappage.c:1288
VOID NTAPI RtlpDphPlaceOnBusyList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK DphNode)
Definition: heappage.c:441
#define DPH_DEBUG_INTERNAL_VALIDATE
Definition: heappage.c:146
PVOID NTAPI RtlpPageHeapAllocate(IN PVOID HeapPtr, IN ULONG Flags, IN SIZE_T Size)
Definition: heappage.c:1697
ULONG_PTR SIZE_T
Definition: typedefs.h:80
PVOID NTAPI RtlpDphPointerFromHandle(PVOID Handle)
Definition: heappage.c:218
VOID NTAPI RtlpDphPreProcessing(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
Definition: heappage.c:271
VOID NTAPI RtlpDphRaiseException(NTSTATUS Status)
Definition: heappage.c:202
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
BOOLEAN NTAPI RtlpDphIsPageHeapBlock(PDPH_HEAP_ROOT DphRoot, PVOID Block, PULONG ValidationInformation, BOOLEAN CheckFillers)
Definition: heappage.c:1356
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
ULONG RtlpDphDebugOptions
Definition: heappage.c:184
#define DPRINT
Definition: sndvol32.h:71
#define HEAP_GENERATE_EXCEPTIONS
Definition: nt_native.h:1694
#define HEAP_REALLOC_IN_PLACE_ONLY
Definition: nt_native.h:1696
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4751
Definition: dlist.c:348

Referenced by RtlDebugReAllocateHeap().

◆ RtlpPageHeapSetUserFlags()

BOOLEAN NTAPI RtlpPageHeapSetUserFlags ( PVOID  HeapHandle,
ULONG  Flags,
PVOID  BaseAddress,
ULONG  UserFlagsReset,
ULONG  UserFlagsSet 
)

Definition at line 2207 of file heappage.c.

2212 {
2213  PDPH_HEAP_ROOT DphRoot;
2215 
2216  /* Get a pointer to the heap root */
2217  DphRoot = RtlpDphPointerFromHandle(HeapHandle);
2218  if (!DphRoot) return FALSE;
2219 
2220  /* Add heap flags */
2221  Flags |= DphRoot->HeapFlags;
2222 
2223  /* Acquire the heap lock */
2224  RtlpDphPreProcessing(DphRoot, Flags);
2225 
2226  /* Find busy memory */
2228 
2229  if (!Node)
2230  {
2231  /* This block was not found in page heap, try a normal heap instead */
2232  //RtlpDphNormalHeapSetUserFlags();
2233  ASSERT(FALSE);
2234  return FALSE;
2235  }
2236 
2237  /* Get user values and flags and store them in user provided pointers */
2238  Node->UserFlags &= ~(UserFlagsReset);
2239  Node->UserFlags |= UserFlagsSet;
2240 
2241  /* Leave the heap lock */
2242  RtlpDphPostProcessing(DphRoot);
2243 
2244  /* Return success */
2245  return TRUE;
2246 }
#define TRUE
Definition: types.h:120
VOID NTAPI RtlpDphPostProcessing(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:279
#define FALSE
Definition: types.h:117
PDPH_HEAP_BLOCK NTAPI RtlpDphFindBusyMemory(PDPH_HEAP_ROOT DphRoot, PVOID pUserMem)
Definition: heappage.c:934
union node Node
Definition: types.h:1255
ULONG HeapFlags
Definition: heappage.c:64
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define ASSERT(a)
Definition: mode.c:44
PVOID NTAPI RtlpDphPointerFromHandle(PVOID Handle)
Definition: heappage.c:218
VOID NTAPI RtlpDphPreProcessing(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
Definition: heappage.c:271
Definition: dlist.c:348

Referenced by RtlDebugSetUserFlagsHeap().

◆ RtlpPageHeapSetUserValue()

BOOLEAN NTAPI RtlpPageHeapSetUserValue ( PVOID  HeapHandle,
ULONG  Flags,
PVOID  BaseAddress,
PVOID  UserValue 
)

Definition at line 2166 of file heappage.c.

2170 {
2171  PDPH_HEAP_ROOT DphRoot;
2173 
2174  /* Get a pointer to the heap root */
2175  DphRoot = RtlpDphPointerFromHandle(HeapHandle);
2176  if (!DphRoot) return FALSE;
2177 
2178  /* Add heap flags */
2179  Flags |= DphRoot->HeapFlags;
2180 
2181  /* Acquire the heap lock */
2182  RtlpDphPreProcessing(DphRoot, Flags);
2183 
2184  /* Find busy memory */
2186 
2187  if (!Node)
2188  {
2189  /* This block was not found in page heap, try a normal heap instead */
2190  //RtlpDphNormalHeapSetUserValue();
2191  ASSERT(FALSE);
2192  return FALSE;
2193  }
2194 
2195  /* Get user values and flags and store them in user provided pointers */
2196  Node->UserValue = UserValue;
2197 
2198  /* Leave the heap lock */
2199  RtlpDphPostProcessing(DphRoot);
2200 
2201  /* Return success */
2202  return TRUE;
2203 }
#define TRUE
Definition: types.h:120
VOID NTAPI RtlpDphPostProcessing(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:279
#define FALSE
Definition: types.h:117
PDPH_HEAP_BLOCK NTAPI RtlpDphFindBusyMemory(PDPH_HEAP_ROOT DphRoot, PVOID pUserMem)
Definition: heappage.c:934
union node Node
Definition: types.h:1255
ULONG HeapFlags
Definition: heappage.c:64
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define ASSERT(a)
Definition: mode.c:44
PVOID NTAPI RtlpDphPointerFromHandle(PVOID Handle)
Definition: heappage.c:218
VOID NTAPI RtlpDphPreProcessing(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
Definition: heappage.c:271
Definition: dlist.c:348

Referenced by RtlDebugSetUserValueHeap().

◆ RtlpPageHeapSize()

SIZE_T NTAPI RtlpPageHeapSize ( HANDLE  HeapPtr,
ULONG  Flags,
PVOID  Ptr 
)

Definition at line 2249 of file heappage.c.

2252 {
2253  PDPH_HEAP_ROOT DphRoot;
2255  SIZE_T Size;
2256 
2257  /* Get a pointer to the heap root */
2258  DphRoot = RtlpDphPointerFromHandle(HeapHandle);
2259  if (!DphRoot) return -1;
2260 
2261  /* Add heap flags */
2262  Flags |= DphRoot->HeapFlags;
2263 
2264  /* Acquire the heap lock */
2265  RtlpDphPreProcessing(DphRoot, Flags);
2266 
2267  /* Find busy memory */
2269 
2270  if (!Node)
2271  {
2272  /* This block was not found in page heap, try a normal heap instead */
2273  //RtlpDphNormalHeapSize();
2274  ASSERT(FALSE);
2275  return -1;
2276  }
2277 
2278  /* Get heap block size */
2279  Size = Node->nUserRequestedSize;
2280 
2281  /* Leave the heap lock */
2282  RtlpDphPostProcessing(DphRoot);
2283 
2284  /* Return user requested size */
2285  return Size;
2286 }
VOID NTAPI RtlpDphPostProcessing(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:279
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
#define FALSE
Definition: types.h:117
PDPH_HEAP_BLOCK NTAPI RtlpDphFindBusyMemory(PDPH_HEAP_ROOT DphRoot, PVOID pUserMem)
Definition: heappage.c:934
union node Node
Definition: types.h:1255
ULONG HeapFlags
Definition: heappage.c:64
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define ASSERT(a)
Definition: mode.c:44
ULONG_PTR SIZE_T
Definition: typedefs.h:80
PVOID NTAPI RtlpDphPointerFromHandle(PVOID Handle)
Definition: heappage.c:218
VOID NTAPI RtlpDphPreProcessing(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
Definition: heappage.c:271
Definition: dlist.c:348

Referenced by RtlDebugSizeHeap().

◆ RtlpPageHeapUnlock()

BOOLEAN NTAPI RtlpPageHeapUnlock ( HANDLE  HeapPtr)

Definition at line 2368 of file heappage.c.

2369 {
2370  PDPH_HEAP_ROOT DphRoot;
2371 
2372  /* Get pointer to the heap root */
2373  DphRoot = RtlpDphPointerFromHandle(HeapPtr);
2374  if (!DphRoot) return FALSE;
2375 
2376  RtlpDphLeaveCriticalSection(DphRoot);
2377  return TRUE;
2378 }
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
VOID NTAPI RtlpDphLeaveCriticalSection(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:263
PVOID NTAPI RtlpDphPointerFromHandle(PVOID Handle)
Definition: heappage.c:218

Referenced by RtlUnlockHeap().

◆ RtlpRemoveHeapFromProcessList()

VOID NTAPI RtlpRemoveHeapFromProcessList ( PHEAP  Heap)

Definition at line 56 of file heapuser.c.

57 {
58  PPEB Peb;
59  PHEAP *Current, *Next;
60  ULONG Count;
61 
62  /* Get PEB */
64 
65  /* Acquire the lock */
67 
68  /* Check if we don't need anything to do */
69  if ((Heap->ProcessHeapsListIndex == 0) ||
71  (Peb->NumberOfHeaps == 0))
72  {
73  /* Release the lock */
75 
76  return;
77  }
78 
79  /* The process actually has more than one heap.
80  Use classic, lernt from university times algorithm for removing an entry
81  from a static array */
82 
83  Current = (PHEAP *)&Peb->ProcessHeaps[Heap->ProcessHeapsListIndex - 1];
84  Next = Current + 1;
85 
86  /* How many items we need to shift to the left */
88 
89  /* Move them all in a loop */
90  while (--Count)
91  {
92  /* Copy it and advance next pointer */
93  *Current = *Next;
94 
95  /* Update its index */
96  (*Current)->ProcessHeapsListIndex -= 1;
97 
98  /* Advance pointers */
99  Current++;
100  Next++;
101  }
102 
103  /* Decrease total number of heaps */
104  Peb->NumberOfHeaps--;
105 
106  /* Zero last unused item */
108  Heap->ProcessHeapsListIndex = 0;
109 
110  /* Release the lock */
112 }
PPEB Peb
Definition: dllmain.c:27
RTL_CRITICAL_SECTION RtlpProcessHeapsListLock
Definition: heapuser.c:17
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
ULONG NumberOfHeaps
Definition: ntddk_ex.h:286
int Count
Definition: noreturn.cpp:7
PVOID * ProcessHeaps
Definition: ntddk_ex.h:288
PPEB NTAPI RtlGetCurrentPeb(VOID)
Definition: libsupp.c:63
USHORT ProcessHeapsListIndex
Definition: heap.h:241
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
Definition: heap.c:51

◆ RtlpValidateHeap()

BOOLEAN NTAPI RtlpValidateHeap ( PHEAP  Heap,
BOOLEAN  ForceValidation 
)

Definition at line 3513 of file heap.c.

3515 {
3516  UCHAR SegmentOffset;
3517  SIZE_T TotalFreeSize;
3518  PLIST_ENTRY ListHead, NextEntry;
3519  ULONG FreeBlocksCount, FreeListEntriesCount;
3520  ULONG HintIndex;
3521 
3522  /* Check headers */
3523  if (!RtlpValidateHeapHeaders(Heap, FALSE))
3524  return FALSE;
3525 
3526  /* Skip validation if it's not needed */
3527  if (!ForceValidation && !(Heap->Flags & HEAP_VALIDATE_ALL_ENABLED))
3528  return TRUE;
3529 
3530  /* Check free list */
3531  FreeListEntriesCount = 0;
3532  ListHead = &Heap->FreeLists;
3533  NextEntry = ListHead->Flink;
3534 
3535  while (NextEntry != ListHead)
3536  {
3537  PHEAP_FREE_ENTRY FreeEntry = CONTAINING_RECORD(NextEntry, HEAP_FREE_ENTRY, FreeList);
3538 
3539  NextEntry = NextEntry->Flink;
3540 
3541  if (NextEntry != ListHead)
3542  {
3543  PHEAP_FREE_ENTRY NextFreeEntry = CONTAINING_RECORD(NextEntry, HEAP_FREE_ENTRY, FreeList);
3544  /* Free entries must be sorted */
3545  if (FreeEntry->Size > NextFreeEntry->Size)
3546  {
3547  DPRINT1("Dedicated free entry %p of size %ld is not put in order.\n", FreeEntry, FreeEntry->Size);
3548  }
3549  }
3550 
3551  /* Check that the hint is there */
3552  if (FreeEntry->Size > Heap->DeCommitFreeBlockThreshold)
3553  {
3554  if (Heap->FreeHints[0] == NULL)
3555  {
3556  DPRINT1("No hint pointing to the non-dedicated list although there is a free entry %p of size %ld.\n",
3557  FreeEntry, FreeEntry->Size);
3558  }
3559  if (!RtlTestBit(&Heap->FreeHintBitmap, 0))
3560  {
3561  DPRINT1("Hint bit 0 is not set although there is a free entry %p of size %ld.\n",
3562  FreeEntry, FreeEntry->Size);
3563  }
3564  }
3565  else
3566  {
3567  if (Heap->FreeHints[FreeEntry->Size - 1] == NULL)
3568  {
3569  DPRINT1("No hint pointing to the dedicated list although there is a free entry %p of size %ld.\n",
3570  FreeEntry, FreeEntry->Size);
3571  }
3572  if (!RtlTestBit(&Heap->FreeHintBitmap, FreeEntry->Size - 1))
3573  {
3574  DPRINT1("Hint bit 0 is not set although there is a free entry %p of size %ld.\n",
3575  FreeEntry, FreeEntry->Size);
3576  }
3577  }
3578 
3579  /* If there is an in-use entry in a free list - that's quite a big problem */
3580  if (FreeEntry->Flags & HEAP_ENTRY_BUSY)
3581  {
3582  DPRINT1("HEAP: Free element %p is marked in-use\n", FreeEntry);
3583  return FALSE;
3584  }
3585 
3586  /* Add up to the total amount of free entries */
3587  FreeListEntriesCount++;
3588  }
3589 
3590  /* Check free list hints */
3592  {
3593  if (Heap->FreeHints[HintIndex] != NULL)
3594  {
3595  PHEAP_FREE_ENTRY FreeEntry = CONTAINING_RECORD(Heap->FreeHints[HintIndex], HEAP_FREE_ENTRY, FreeList);
3596 
3597  if (!RtlTestBit(&Heap->FreeHintBitmap, HintIndex))
3598  {
3599  DPRINT1("Hint bitmap bit at %u is not set, but there is a hint entry.\n", HintIndex);
3600  }
3601 
3602  if (HintIndex == 0)
3603  {
3604  if (FreeEntry->Size <= Heap->DeCommitFreeBlockThreshold)
3605  {
3606  DPRINT1("There is an entry %p of size %lu, smaller than the decommit threshold %lu in the non-dedicated free list hint.\n",
3607  FreeEntry, FreeEntry->Size, Heap->DeCommitFreeBlockThreshold);
3608  }
3609  }
3610  else
3611  {
3612  if (HintIndex != FreeEntry->Size - 1)
3613  {
3614  DPRINT1("There is an entry %p of size %lu at the position %u in the free entry hint array.\n",
3615  FreeEntry, FreeEntry->Size, HintIndex);
3616  }
3617 
3618  if (FreeEntry->FreeList.Blink != &Heap->FreeLists)
3619  {
3620  /* The entry right before the hint must be smaller. */
3621  PHEAP_FREE_ENTRY PreviousFreeEntry = CONTAINING_RECORD(FreeEntry->FreeList.Blink,
3623  FreeList);
3624  if (PreviousFreeEntry->Size >= FreeEntry->Size)
3625  {
3626  DPRINT1("Free entry hint %p of size %lu is larger than the entry before it %p, which is of size %lu.\n",
3627  FreeEntry, FreeEntry->Size, PreviousFreeEntry, PreviousFreeEntry->Size);
3628  }
3629  }
3630  }
3631  }
3632  else if (RtlTestBit(&Heap->FreeHintBitmap, HintIndex))
3633  {
3634  DPRINT1("Hint bitmap bit at %u is set, but there is no hint entry.\n", HintIndex);
3635  }
3636  }
3637 
3638  /* Check big allocations */
3639  ListHead = &Heap->VirtualAllocdBlocks;
3640  NextEntry = ListHead->Flink;
3641 
3642  while (ListHead != NextEntry)
3643  {
3645 
3646  /* We can only check the fill pattern */
3647  if (VirtualAllocBlock->BusyBlock.Flags & HEAP_ENTRY_FILL_PATTERN)
3648  {
3649  if (!RtlpCheckInUsePattern(&VirtualAllocBlock->BusyBlock))
3650  return FALSE;
3651  }
3652 
3653  NextEntry = NextEntry->Flink;
3654  }
3655 
3656  /* Check all segments */
3657  FreeBlocksCount = 0;
3658  TotalFreeSize = 0;
3659 
3660  for (SegmentOffset = 0; SegmentOffset < HEAP_SEGMENTS; SegmentOffset++)
3661  {
3662  PHEAP_SEGMENT Segment = Heap->Segments[SegmentOffset];
3663 
3664  /* Go to the next one if there is no segment */
3665  if (!Segment) continue;
3666 
3667  if (!RtlpValidateHeapSegment(Heap,
3668  Segment,
3669  SegmentOffset,
3670  &FreeBlocksCount,
3671  &TotalFreeSize,
3672  NULL,
3673  NULL))
3674  {
3675  return FALSE;
3676  }
3677  }
3678 
3679  if (FreeListEntriesCount != FreeBlocksCount)
3680  {
3681  DPRINT1("HEAP: Free blocks count in arena (%lu) does not match free blocks number in the free lists (%lu)\n", FreeBlocksCount, FreeListEntriesCount);
3682  return FALSE;
3683  }
3684 
3685  if (Heap->TotalFreeSize != TotalFreeSize)
3686  {
3687  DPRINT1("HEAP: Total size of free blocks in arena (%Iu) does not equal to the one in heap header (%Iu)\n", TotalFreeSize, Heap->TotalFreeSize);
3688  return FALSE;
3689  }
3690 
3691  return TRUE;
3692 }
Definition: heap.h:307
SIZE_T TotalFreeSize
Definition: heap.h:239
#define HEAP_SEGMENTS
Definition: heap.h:15
#define TRUE
Definition: types.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
LIST_ENTRY FreeLists
Definition: heap.h:259
LIST_ENTRY FreeList
Definition: heap.h:131
BOOLEAN NTAPI RtlpValidateHeapHeaders(PHEAP Heap, BOOLEAN Recalculate)
Definition: heap.c:3260
_In_ ULONG _In_ ULONG HintIndex
Definition: rtlfuncs.h:609
struct _HEAP_SEGMENT * Segments[HEAP_SEGMENTS]
Definition: heap.h:253
#define FALSE
Definition: types.h:117
PLIST_ENTRY FreeHints[ANYSIZE_ARRAY]
Definition: heap.h:268
Definition: heap.h:129
RTL_BITMAP FreeHintBitmap
Definition: heap.h:267
#define HEAP_ENTRY_BUSY
Definition: heap.h:40
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define HEAP_VALIDATE_ALL_ENABLED
Definition: rtltypes.h:166
LIST_ENTRY VirtualAllocdBlocks
Definition: heap.h:251
_Must_inspect_result_ NTSYSAPI BOOLEAN NTAPI RtlTestBit(_In_ PRTL_BITMAP BitMapHeader, _In_range_(<, BitMapHeader->SizeOfBitMap) ULONG BitNumber)
Definition: bitmap.c:434
unsigned char UCHAR
Definition: xmlstorage.h:181
BOOLEAN NTAPI RtlpCheckInUsePattern(PHEAP_ENTRY HeapEntry)
Definition: heap.c:3230
Definition: typedefs.h:119
#define HEAP_ENTRY_FILL_PATTERN
Definition: heap.h:42
ULONG_PTR SIZE_T
Definition: typedefs.h:80
ULONG Flags
Definition: heap.h:226
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
SIZE_T DeCommitFreeBlockThreshold
Definition: heap.h:237
unsigned int ULONG
Definition: retypes.h:1
HEAP_ENTRY BusyBlock
Definition: heap.h:313
BOOLEAN NTAPI RtlpValidateHeapSegment(PHEAP Heap, PHEAP_SEGMENT Segment, UCHAR SegmentOffset, PULONG FreeEntriesCount, PSIZE_T TotalFreeSize, PSIZE_T TagEntries, PSIZE_T PseudoTagEntries)
Definition: heap.c:3326
base of all file and directory entries
Definition: entries.h:82

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

◆ RtlpValidateHeapEntry()

BOOLEAN NTAPI RtlpValidateHeapEntry ( PHEAP  Heap,
PHEAP_ENTRY  HeapEntry 
)

Definition at line 3269 of file heap.c.

3272 {
3273  BOOLEAN BigAllocation, EntryFound = FALSE;
3275  ULONG SegmentOffset;
3276 
3277  /* Perform various consistency checks of this entry */
3278  if (!HeapEntry) goto invalid_entry;
3279  if ((ULONG_PTR)HeapEntry & (HEAP_ENTRY_SIZE - 1)) goto invalid_entry;
3280  if (!(HeapEntry->Flags & HEAP_ENTRY_BUSY)) goto invalid_entry;
3281 
3282  BigAllocation = HeapEntry->Flags & HEAP_ENTRY_VIRTUAL_ALLOC;
3283  Segment = Heap->Segments[HeapEntry->SegmentOffset];
3284 
3285  if (BigAllocation &&
3286  (((ULONG_PTR)HeapEntry & (PAGE_SIZE - 1)) != FIELD_OFFSET(HEAP_VIRTUAL_ALLOC_ENTRY, BusyBlock)))
3287  goto invalid_entry;
3288 
3289  if (!BigAllocation && (HeapEntry->SegmentOffset >= HEAP_SEGMENTS ||
3290  !Segment ||
3291  HeapEntry < Segment->FirstEntry ||
3292  HeapEntry >= Segment->LastValidEntry))
3293  goto invalid_entry;
3294 
3295  if ((HeapEntry->Flags & HEAP_ENTRY_FILL_PATTERN) &&
3296  !RtlpCheckInUsePattern(HeapEntry))
3297  goto invalid_entry;
3298 
3299  /* Checks are done, if this is a virtual entry, that's all */
3300  if (HeapEntry->Flags & HEAP_ENTRY_VIRTUAL_ALLOC) return TRUE;
3301 
3302  /* Go through segments and check if this entry fits into any of them */
3303  for (SegmentOffset = 0; SegmentOffset < HEAP_SEGMENTS; SegmentOffset++)
3304  {
3305  Segment = Heap->Segments[SegmentOffset];
3306  if (!Segment) continue;
3307 
3308  if ((HeapEntry >= Segment->FirstEntry) &&
3309  (HeapEntry < Segment->LastValidEntry))
3310  {
3311  /* Got it */
3312  EntryFound = TRUE;
3313  break;
3314  }
3315  }
3316 
3317  /* Return our result of finding entry in the segments */
3318  return EntryFound;
3319 
3320 invalid_entry:
3321  DPRINT1("HEAP: Invalid heap entry %p in heap %p\n", HeapEntry, Heap);
3322  return FALSE;
3323 }
Definition: heap.h:307
#define HEAP_ENTRY_VIRTUAL_ALLOC
Definition: heap.h:43
#define HEAP_SEGMENTS
Definition: heap.h:15
#define TRUE
Definition: types.h:120
uint32_t ULONG_PTR
Definition: typedefs.h:65
struct _HEAP_SEGMENT * Segments[HEAP_SEGMENTS]
Definition: heap.h:253
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
#define HEAP_ENTRY_BUSY
Definition: heap.h:40
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
#define HEAP_ENTRY_SIZE
Definition: heap.h:17
BOOLEAN NTAPI RtlpCheckInUsePattern(PHEAP_ENTRY HeapEntry)
Definition: heap.c:3230
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define HEAP_ENTRY_FILL_PATTERN
Definition: heap.h:42
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1

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

◆ RtlpValidateHeapHeaders()

BOOLEAN NTAPI RtlpValidateHeapHeaders ( PHEAP  Heap,
BOOLEAN  Recalculate 
)

Definition at line 3260 of file heap.c.

3263 {
3264  // We skip header validation for now
3265  return TRUE;
3266 }
#define TRUE
Definition: types.h:120

Referenced by RtlDebugAllocateHeap(), RtlDebugCreateHeap(), RtlDebugFreeHeap(), RtlDebugReAllocateHeap(), and RtlpValidateHeap().

Variable Documentation

◆ RtlpPageHeapEnabled

BOOLEAN RtlpPageHeapEnabled

Definition at line 106 of file heappage.c.

◆ RtlpProcessHeapsListLock

RTL_CRITICAL_SECTION RtlpProcessHeapsListLock