ReactOS 0.4.16-dev-980-g00983aa
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)
 
NTSYSAPI 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:
#define HEAP_CAPTURE_STACK_BACKTRACES
Definition: rtltypes.h:164
#define HEAP_SETTABLE_USER_VALUE
Definition: nt_native.h:1704
#define HEAP_TAGS_MASK
Definition: heap.h:33

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; \
ULONG NumberOfPages; \
PHEAP_ENTRY FirstEntry; \
PHEAP_ENTRY LastValidEntry; \
ULONG NumberOfUnCommittedPages; \
ULONG NumberOfUnCommittedRanges; \
USHORT SegmentAllocatorBackTraceIndex; \
LIST_ENTRY UCRSegmentList
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
unsigned short USHORT
Definition: pedump.c:61
base of all file and directory entries
Definition: entries.h:83
Definition: heap.h:136
Definition: heap.c:52
Definition: typedefs.h:120
uint32_t ULONG
Definition: typedefs.h:59
_Reserved_ PVOID Reserved
Definition: winddi.h:3974

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 ( (1<< HEAP_ENTRY_SHIFT = =sizeof(HEAP_ENTRY))

◆ C_ASSERT() [2/3]

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

◆ C_ASSERT() [3/3]

C_ASSERT ( sizeof(HEAP_ENTRY = =8)

◆ 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;
138
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 {
185 RtlpValidateHeap(Heap, FALSE);
186 }
187
188 /* Release the lock */
189 if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
190
191 return Result;
192}
unsigned char BOOLEAN
#define DPRINT1
Definition: precomp.h:8
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
struct _HEAP * PHEAP
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
NTSTATUS NTAPI RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
Definition: libsupp.c:110
NTSTATUS NTAPI RtlLeaveHeapLock(IN OUT PHEAP_LOCK Lock)
Definition: libsupp.c:135
#define HEAP_SKIP_VALIDATION_CHECKS
Definition: rtltypes.h:165
#define HEAP_VALIDATE_ALL_ENABLED
Definition: rtltypes.h:166
#define HEAP_FLAG_PAGE_ALLOCS
Definition: rtltypes.h:160
#define HEAP_NO_SERIALIZE
Definition: nt_native.h:1692
BOOLEAN NTAPI RtlpValidateHeap(PHEAP Heap, BOOLEAN ForceValidation)
Definition: heap.c:3532
BOOLEAN NTAPI RtlpValidateHeapHeaders(PHEAP Heap, BOOLEAN Recalculate)
Definition: heap.c:3279
struct _HEAP_ENTRY_EXTRA HEAP_ENTRY_EXTRA
#define HEAP_SIGNATURE
Definition: heap.h:51
PVOID NTAPI RtlpPageHeapAllocate(IN PVOID HeapPtr, IN ULONG Flags, IN SIZE_T Size)
Definition: heappage.c:1766
ULONG Flags
Definition: heap.h:226
ULONG_PTR AlignRound
Definition: heap.h:249
ULONG ForceFlags
Definition: heap.h:227
ULONG_PTR AlignMask
Definition: heap.h:250
ULONG Signature
Definition: heap.h:234
SIZE_T MaximumAllocationSize
Definition: heap.h:240
PHEAP_LOCK LockVariable
Definition: heap.h:260
ULONG_PTR SIZE_T
Definition: typedefs.h:80
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_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:409
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by RtlAllocateHeap().

◆ RtlDebugCreateHeap()

NTSYSAPI 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
39 {
40 DPRINT1("HEAP: Incorrect CommitSize %x\n", CommitSize);
41 return NULL;
42 }
43
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}
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
Status
Definition: gdiplustypes.h:25
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)
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T CommitSize
Definition: mmfuncs.h:406
@ MemoryBasicInformation
Definition: mmtypes.h:183
#define MEM_FREE
Definition: nt_native.h:1317
#define HEAP_FREE_CHECKING_ENABLED
Definition: nt_native.h:1698
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 HEAP_TAIL_CHECKING_ENABLED
Definition: nt_native.h:1697
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define HEAP_ENTRY_SIZE
Definition: heap.h:17
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:869
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127
_In_opt_ PVOID _In_opt_ SIZE_T ReserveSize
Definition: rtlfuncs.h:2185

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,
124 }
125
126 return TRUE;
127}
NTSYSAPI PEB *WINAPI RtlGetCurrentPeb(void)
Definition: libsupp.c:65
#define MEM_RELEASE
Definition: nt_native.h:1316
PVOID HeaderValidateCopy
Definition: heap.h:243
PVOID ProcessHeap
Definition: ntddk_ex.h:249

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;
275
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}
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
BOOLEAN NTAPI RtlpValidateHeapEntry(PHEAP Heap, PHEAP_ENTRY HeapEntry)
Definition: heap.c:3288
struct _HEAP_ENTRY * PHEAP_ENTRY
BOOLEAN NTAPI RtlpPageHeapFree(HANDLE HeapPtr, ULONG Flags, PVOID Ptr)
Definition: heappage.c:1931

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;
332
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}
BOOLEAN NTAPI RtlGetUserInfoHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID BaseAddress, OUT PVOID *UserValue, OUT PULONG UserFlags)
Definition: heap.c:3934
BOOLEAN NTAPI RtlpPageHeapGetUserInfo(PVOID HeapHandle, ULONG Flags, PVOID BaseAddress, PVOID *UserValue, PULONG UserFlags)
Definition: heappage.c:2193

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
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}
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T)
Definition: heap.c:2686
PVOID NTAPI RtlpPageHeapReAllocate(HANDLE HeapPtr, ULONG Flags, PVOID Ptr, SIZE_T Size)
Definition: heappage.c:2023

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;
441
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_SETTABLE_USER_FLAGS
Definition: nt_native.h:1708
BOOLEAN NTAPI RtlSetUserFlagsHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID BaseAddress, IN ULONG UserFlagsReset, IN ULONG UserFlagsSet)
Definition: heap.c:3879
BOOLEAN NTAPI RtlpPageHeapSetUserFlags(PVOID HeapHandle, ULONG Flags, PVOID BaseAddress, ULONG UserFlagsReset, ULONG UserFlagsSet)
Definition: heappage.c:2276

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;
384
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}
BOOLEAN NTAPI RtlSetUserValueHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID BaseAddress, IN PVOID UserValue)
Definition: heap.c:3817
BOOLEAN NTAPI RtlpPageHeapSetUserValue(PVOID HeapHandle, ULONG Flags, PVOID BaseAddress, PVOID UserValue)
Definition: heappage.c:2235

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
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}
NTSYSAPI SIZE_T NTAPI RtlSizeHeap(_In_ PVOID HeapHandle, _In_ ULONG Flags, _In_ PVOID MemoryPointer)
SIZE_T NTAPI RtlpPageHeapSize(HANDLE HeapPtr, ULONG Flags, PVOID Ptr)
Definition: heappage.c:2318

Referenced by RtlSizeHeap().

◆ RtlInitializeHeapManager()

VOID NTAPI RtlInitializeHeapManager ( VOID  )

Definition at line 243 of file libsupp.c.

244{
245}

◆ 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
39 }
40
41 /* Add the heap to the process heaps */
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
#define ASSERT(a)
Definition: mode.c:44
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
USHORT ProcessHeapsListIndex
Definition: heap.h:241
ULONG MaximumNumberOfHeaps
Definition: ntddk_ex.h:287
PVOID * ProcessHeaps
Definition: ntddk_ex.h:288
ULONG NumberOfHeaps
Definition: ntddk_ex.h:286

◆ RtlpCoalesceFreeBlocks()

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

Definition at line 1169 of file heap.c.

1173{
1174 PHEAP_FREE_ENTRY CurrentEntry, NextEntry;
1175 UCHAR SegmentOffset;
1176
1177 /* Get the previous entry */
1178 CurrentEntry = (PHEAP_FREE_ENTRY)((PHEAP_ENTRY)FreeEntry - FreeEntry->PreviousSize);
1179
1180 /* Check it */
1181 if (CurrentEntry != FreeEntry &&
1182 !(CurrentEntry->Flags & HEAP_ENTRY_BUSY) &&
1183 (*FreeSize + CurrentEntry->Size) <= HEAP_MAX_BLOCK_SIZE)
1184 {
1185 ASSERT(FreeEntry->PreviousSize == CurrentEntry->Size);
1186
1187 /* Remove it if asked for */
1188 if (Remove)
1189 {
1190 RtlpRemoveFreeBlock(Heap, FreeEntry, FALSE);
1191 Heap->TotalFreeSize -= FreeEntry->Size;
1192
1193 /* Remove it only once! */
1194 Remove = FALSE;
1195 }
1196
1197 /* Remove previous entry too */
1198 RtlpRemoveFreeBlock(Heap, CurrentEntry, FALSE);
1199
1200 /* Copy flags */
1201 CurrentEntry->Flags = FreeEntry->Flags & HEAP_ENTRY_LAST_ENTRY;
1202
1203 /* Advance FreeEntry and update sizes */
1204 FreeEntry = CurrentEntry;
1205 *FreeSize = *FreeSize + CurrentEntry->Size;
1206 Heap->TotalFreeSize -= CurrentEntry->Size;
1207 FreeEntry->Size = (USHORT)(*FreeSize);
1208
1209 /* Also update previous size if needed */
1210 if (!(FreeEntry->Flags & HEAP_ENTRY_LAST_ENTRY))
1211 {
1212 ((PHEAP_ENTRY)FreeEntry + *FreeSize)->PreviousSize = (USHORT)(*FreeSize);
1213 }
1214 else
1215 {
1216 SegmentOffset = FreeEntry->SegmentOffset;
1217 ASSERT(SegmentOffset < HEAP_SEGMENTS);
1218 }
1219 }
1220
1221 /* Check the next block if it exists */
1222 if (!(FreeEntry->Flags & HEAP_ENTRY_LAST_ENTRY))
1223 {
1224 NextEntry = (PHEAP_FREE_ENTRY)((PHEAP_ENTRY)FreeEntry + *FreeSize);
1225
1226 if (!(NextEntry->Flags & HEAP_ENTRY_BUSY) &&
1227 NextEntry->Size + *FreeSize <= HEAP_MAX_BLOCK_SIZE)
1228 {
1229 ASSERT(*FreeSize == NextEntry->PreviousSize);
1230
1231 /* Remove it if asked for */
1232 if (Remove)
1233 {
1234 RtlpRemoveFreeBlock(Heap, FreeEntry, FALSE);
1235 Heap->TotalFreeSize -= FreeEntry->Size;
1236 }
1237
1238 /* Copy flags */
1239 FreeEntry->Flags = NextEntry->Flags & HEAP_ENTRY_LAST_ENTRY;
1240
1241 /* Remove next entry now */
1242 RtlpRemoveFreeBlock(Heap, NextEntry, FALSE);
1243
1244 /* Update sizes */
1245 *FreeSize = *FreeSize + NextEntry->Size;
1246 Heap->TotalFreeSize -= NextEntry->Size;
1247 FreeEntry->Size = (USHORT)(*FreeSize);
1248
1249 /* Also update previous size if needed */
1250 if (!(FreeEntry->Flags & HEAP_ENTRY_LAST_ENTRY))
1251 {
1252 ((PHEAP_ENTRY)FreeEntry + *FreeSize)->PreviousSize = (USHORT)(*FreeSize);
1253 }
1254 else
1255 {
1256 SegmentOffset = FreeEntry->SegmentOffset;
1257 ASSERT(SegmentOffset < HEAP_SEGMENTS);
1258 }
1259 }
1260 }
1261 return FreeEntry;
1262}
static VOID RtlpRemoveFreeBlock(PHEAP Heap, PHEAP_FREE_ENTRY FreeEntry, BOOLEAN NoFill)
Definition: heap.c:431
#define HEAP_MAX_BLOCK_SIZE
Definition: heap.h:23
struct _HEAP_FREE_ENTRY * PHEAP_FREE_ENTRY
#define HEAP_ENTRY_LAST_ENTRY
Definition: heap.h:44
#define HEAP_SEGMENTS
Definition: heap.h:15
#define HEAP_ENTRY_BUSY
Definition: heap.h:40
Definition: heap.h:130
SIZE_T TotalFreeSize
Definition: heap.h:239
_In_ BOOLEAN Remove
Definition: psfuncs.h:110
unsigned char UCHAR
Definition: xmlstorage.h:181

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

◆ RtlpDebugPageHeapValidate()

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

Definition at line 2359 of file heappage.c.

2362{
2363 PDPH_HEAP_ROOT DphRoot;
2365 BOOLEAN Valid = FALSE;
2366
2367 /* Get a pointer to the heap root */
2368 DphRoot = RtlpDphPointerFromHandle(HeapHandle);
2369 if (!DphRoot) return -1;
2370
2371 /* Add heap flags */
2372 Flags |= DphRoot->HeapFlags;
2373
2374 /* Acquire the heap lock */
2375 RtlpDphPreProcessing(DphRoot, Flags);
2376
2377 /* Find busy memory */
2378 if (BaseAddress)
2380
2381 if (!Node)
2382 {
2383 /* This block was not found in page heap, or the request is to validate all normal heap */
2384 Valid = RtlpDphNormalHeapValidate(DphRoot, Flags, BaseAddress);
2385 }
2386
2387 /* Leave the heap lock */
2388 RtlpDphPostProcessing(DphRoot);
2389
2390 /* Return result of a normal heap validation */
2391 if (BaseAddress && !Node)
2392 return Valid;
2393
2394 /* Otherwise return our own result */
2395 if (!BaseAddress || Node) Valid = TRUE;
2396
2397 return Valid;
2398}
VOID NTAPI RtlpDphPreProcessing(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
Definition: heappage.c:301
PVOID NTAPI RtlpDphPointerFromHandle(PVOID Handle)
Definition: heappage.c:227
VOID NTAPI RtlpDphPostProcessing(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:309
BOOLEAN NTAPI RtlpDphNormalHeapValidate(PDPH_HEAP_ROOT DphRoot, ULONG Flags, PVOID BaseAddress)
Definition: heappage.c:2402
PDPH_HEAP_BLOCK NTAPI RtlpDphFindBusyMemory(PDPH_HEAP_ROOT DphRoot, PVOID pUserMem)
Definition: heappage.c:964
ULONG HeapFlags
Definition: heappage.c:65
Definition: dlist.c:348

Referenced by RtlValidateHeap().

◆ RtlpGetExtraStuffPointer()

PHEAP_ENTRY_EXTRA NTAPI RtlpGetExtraStuffPointer ( PHEAP_ENTRY  HeapEntry)

Definition at line 2651 of file heap.c.

2652{
2653 PHEAP_VIRTUAL_ALLOC_ENTRY VirtualEntry;
2654
2655 /* Check if it's a big block */
2656 if (HeapEntry->Flags & HEAP_ENTRY_VIRTUAL_ALLOC)
2657 {
2658 VirtualEntry = CONTAINING_RECORD(HeapEntry, HEAP_VIRTUAL_ALLOC_ENTRY, BusyBlock);
2659
2660 /* Return a pointer to the extra stuff*/
2661 return &VirtualEntry->ExtraStuff;
2662 }
2663 else
2664 {
2665 /* This is a usual entry, which means extra stuff follows this block */
2666 return (PHEAP_ENTRY_EXTRA)(HeapEntry + HeapEntry->Size - 1);
2667 }
2668}
#define HEAP_ENTRY_VIRTUAL_ALLOC
Definition: heap.h:43
Definition: heap.h:292
Definition: heap.h:308
HEAP_ENTRY_EXTRA ExtraStuff
Definition: heap.h:310
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

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 HEAP_VALIDATE_PARAMETERS_ENABLED
Definition: rtltypes.h:167
#define HEAP_CREATE_ENABLE_TRACING
Definition: nt_native.h:1702

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 1766 of file heappage.c.

1769{
1770 PDPH_HEAP_ROOT DphRoot;
1771 PDPH_HEAP_BLOCK AvailableNode, BusyNode;
1772 BOOLEAN Biased = FALSE;
1773 ULONG AllocateSize, AccessSize;
1775 SIZE_T UserActualSize;
1776 PVOID Ptr;
1777
1778 /* Check requested size */
1779 if (Size > 0x7FF00000)
1780 {
1781 DPRINT1("extreme size request\n");
1782
1783 /* Generate an exception if needed */
1785
1786 return NULL;
1787 }
1788
1789 /* Unbias the pointer if necessary */
1790 if (IS_BIASED_POINTER(HeapPtr))
1791 {
1792 HeapPtr = (PVOID)POINTER_REMOVE_BIAS(HeapPtr);
1793 Biased = TRUE;
1794 }
1795
1796 /* Get a pointer to the heap root */
1797 DphRoot = RtlpDphPointerFromHandle(HeapPtr);
1798 if (!DphRoot) return NULL;
1799
1800 /* Acquire the heap lock */
1801 RtlpDphPreProcessing(DphRoot, Flags);
1802
1803 /* Perform internal validation if specified by flags */
1805 {
1807 }
1808
1809 /* Add heap flags */
1810 Flags |= DphRoot->HeapFlags;
1811
1812 if (!Biased && !RtlpDphShouldAllocateInPageHeap(DphRoot, Size))
1813 {
1814 /* Perform allocation from a normal heap */
1815 ASSERT(FALSE);
1816 }
1817
1818 /* Perform heap integrity check if specified by flags */
1820 {
1821 RtlpDphVerifyIntegrity(DphRoot);
1822 }
1823
1824 /* Calculate sizes */
1825 AccessSize = ROUND_UP(Size + sizeof(DPH_BLOCK_INFORMATION), PAGE_SIZE);
1826 AllocateSize = AccessSize + PAGE_SIZE;
1827
1828 // FIXME: Move RtlpDphAllocateNode(DphRoot) to this place
1829 AvailableNode = RtlpDphFindAvailableMemory(DphRoot, AllocateSize, TRUE);
1830 if (!AvailableNode)
1831 {
1832 DPRINT1("Page heap: Unable to allocate virtual memory\n");
1833 DbgBreakPoint();
1834
1835 /* Release the lock */
1836 RtlpDphPostProcessing(DphRoot);
1837
1838 return NULL;
1839 }
1840 ASSERT(AvailableNode->nVirtualBlockSize >= AllocateSize);
1841
1842 /* Set protection */
1844 AvailableNode->pVirtualBlock,
1845 AccessSize);
1846 if (!NT_SUCCESS(Status))
1847 {
1848 ASSERT(FALSE);
1849 }
1850
1851 /* Save available node pointer */
1852 Ptr = AvailableNode->pVirtualBlock;
1853
1854 /* Check node's size */
1855 if (AvailableNode->nVirtualBlockSize > AllocateSize)
1856 {
1857 /* The block contains too much free space, reduce it */
1858 AvailableNode->pVirtualBlock += AllocateSize;
1859 AvailableNode->nVirtualBlockSize -= AllocateSize;
1860 DphRoot->nAvailableAllocationBytesCommitted -= AllocateSize;
1861
1862 /* Allocate a new node which will be our busy node */
1863 BusyNode = RtlpDphAllocateNode(DphRoot);
1864 ASSERT(BusyNode != NULL);
1865 BusyNode->pVirtualBlock = Ptr;
1866 BusyNode->nVirtualBlockSize = AllocateSize;
1867 }
1868 else
1869 {
1870 /* The block's size fits exactly */
1871 RtlpDphRemoveFromAvailableList(DphRoot, AvailableNode);
1872 BusyNode = AvailableNode;
1873 }
1874
1875 /* Calculate actual user size */
1876 if (DphRoot->HeapFlags & HEAP_NO_ALIGNMENT)
1877 UserActualSize = Size;
1878 else
1879 UserActualSize = ROUND_UP(Size, 8);
1880
1881 /* Set up the block */
1882 BusyNode->nVirtualAccessSize = AccessSize;
1883 BusyNode->nUserActualSize = UserActualSize;
1884 BusyNode->nUserRequestedSize = Size;
1885
1886 if (DphRoot->ExtraFlags & DPH_EXTRA_CHECK_UNDERRUN)
1887 BusyNode->pUserAllocation = BusyNode->pVirtualBlock + PAGE_SIZE;
1888 else
1889 BusyNode->pUserAllocation = BusyNode->pVirtualBlock + BusyNode->nVirtualAccessSize - UserActualSize;
1890
1891 BusyNode->UserValue = NULL;
1893
1894 // FIXME: Don't forget about stack traces if such flag was set
1895 BusyNode->StackTrace = NULL;
1896
1897 /* Place it on busy list */
1898 RtlpDphPlaceOnBusyList(DphRoot, BusyNode);
1899
1900 /* Zero or patter-fill memory depending on flags */
1901 if (Flags & HEAP_ZERO_MEMORY)
1903 else
1905
1906 /* Write DPH info */
1907 if (!(DphRoot->ExtraFlags & DPH_EXTRA_CHECK_UNDERRUN))
1908 {
1910 BusyNode->pUserAllocation,
1911 Size,
1912 AccessSize);
1913 }
1914
1915 /* Finally allocation is done, perform validation again if required */
1917 {
1919 }
1920
1921 /* Release the lock */
1922 RtlpDphPostProcessing(DphRoot);
1923
1924 DPRINT("Allocated user block pointer: %p\n", BusyNode->pUserAllocation);
1925
1926 /* Return pointer to user allocation */
1927 return BusyNode->pUserAllocation;
1928}
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
BOOLEAN NTAPI RtlpDphWritePageHeapBlockInformation(PDPH_HEAP_ROOT DphRoot, PVOID UserAllocation, SIZE_T Size, SIZE_T UserSize)
Definition: heappage.c:445
BOOLEAN NTAPI RtlpDphShouldAllocateInPageHeap(PDPH_HEAP_ROOT DphRoot, SIZE_T Size)
Definition: heappage.c:1528
VOID NTAPI RtlpDphVerifyIntegrity(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:1324
#define IS_BIASED_POINTER(ptr)
Definition: heappage.c:179
VOID NTAPI RtlpDphRemoveFromAvailableList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:589
VOID NTAPI RtlpDphPlaceOnBusyList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK DphNode)
Definition: heappage.c:471
#define DPH_EXTRA_CHECK_UNDERRUN
Definition: heappage.c:152
#define POINTER_REMOVE_BIAS(ptr)
Definition: heappage.c:180
PDPH_HEAP_BLOCK NTAPI RtlpDphAllocateNode(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:1018
#define DPH_FILL_INFIX
Definition: heappage.c:161
VOID NTAPI RtlpDphInternalValidatePageHeap(PDPH_HEAP_ROOT DphRoot, PVOID Address, ULONG Value)
Definition: heappage.c:1318
NTSTATUS NTAPI RtlpDphSetProtectionBeforeUse(PDPH_HEAP_ROOT DphRoot, PUCHAR VirtualBlock, ULONG UserSize)
Definition: heappage.c:981
#define DPH_DEBUG_INTERNAL_VALIDATE
Definition: heappage.c:147
VOID NTAPI RtlpDphRaiseException(NTSTATUS Status)
Definition: heappage.c:211
PDPH_HEAP_BLOCK NTAPI RtlpDphFindAvailableMemory(PDPH_HEAP_ROOT DphRoot, SIZE_T Size, BOOLEAN Grow)
Definition: heappage.c:908
ULONG RtlpDphDebugOptions
Definition: heappage.c:185
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:599
NTSYSAPI void WINAPI DbgBreakPoint(void)
#define HEAP_NO_ALIGNMENT
Definition: rtltypes.h:163
#define HEAP_GENERATE_EXCEPTIONS
Definition: nt_native.h:1694
#define DPRINT
Definition: sndvol32.h:73
SIZE_T nUserActualSize
Definition: heappage.c:54
PUCHAR pVirtualBlock
Definition: heappage.c:50
ULONG UserFlags
Definition: heappage.c:56
PUCHAR pUserAllocation
Definition: heappage.c:49
SIZE_T nVirtualAccessSize
Definition: heappage.c:52
SIZE_T nUserRequestedSize
Definition: heappage.c:53
PRTL_TRACE_BLOCK StackTrace
Definition: heappage.c:57
SIZE_T nVirtualBlockSize
Definition: heappage.c:51
PVOID UserValue
Definition: heappage.c:55
ULONG ExtraFlags
Definition: heappage.c:98
SIZE_T nAvailableAllocationBytesCommitted
Definition: heappage.c:86
void * PVOID
Definition: typedefs.h:50
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

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 1537 of file heappage.c.

1543{
1544 PVOID Base = NULL;
1545 PHEAP HeapPtr;
1546 PDPH_HEAP_ROOT DphRoot;
1547 PDPH_HEAP_BLOCK DphNode;
1548 ULONG MemSize;
1550 LARGE_INTEGER PerfCounter;
1551
1552 /* Check for a DPH bypass flag */
1553 if ((ULONG_PTR)Parameters == -1) return NULL;
1554
1555 /* Make sure no user-allocated stuff was provided */
1556 if (Addr || Lock) return NULL;
1557
1558 /* Allocate minimum amount of virtual memory */
1559 MemSize = DPH_RESERVE_SIZE;
1561 if (!NT_SUCCESS(Status))
1562 {
1563 ASSERT(FALSE);
1564 return NULL;
1565 }
1566
1567 /* Set protection */
1569 if (!NT_SUCCESS(Status))
1570 {
1571 //RtlpDphFreeVm(Base, 0, 0, 0);
1572 ASSERT(FALSE);
1573 return NULL;
1574 }
1575
1576 /* Start preparing the 1st page. Fill it with the default filler */
1578
1579 /* Set flags in the "HEAP" structure */
1580 HeapPtr = (PHEAP)Base;
1581 HeapPtr->Flags = Flags | HEAP_FLAG_PAGE_ALLOCS;
1583
1584 /* Set 1st page to read only now */
1586 if (!NT_SUCCESS(Status))
1587 {
1588 ASSERT(FALSE);
1589 return NULL;
1590 }
1591
1592 /* 2nd page is the real DPH root block */
1593 DphRoot = (PDPH_HEAP_ROOT)((PCHAR)Base + PAGE_SIZE);
1594
1595 /* Initialize the DPH root */
1596 DphRoot->Signature = DPH_SIGNATURE;
1597 DphRoot->HeapFlags = Flags;
1598 DphRoot->HeapCritSect = (PHEAP_LOCK)((PCHAR)DphRoot + DPH_POOL_SIZE);
1599 DphRoot->ExtraFlags = RtlpDphGlobalFlags;
1600
1601 ZwQueryPerformanceCounter(&PerfCounter, NULL);
1602 DphRoot->Seed = PerfCounter.LowPart;
1603
1606
1607 /* Create a normal heap for this paged heap */
1608 DphRoot->NormalHeap = RtlCreateHeap(Flags, NULL, TotalSize, CommitSize, NULL, (PRTL_HEAP_PARAMETERS)-1);
1609 if (!DphRoot->NormalHeap)
1610 {
1611 ASSERT(FALSE);
1612 return NULL;
1613 }
1614
1615 /* 3rd page: a pool for DPH allocations */
1616 RtlpDphAddNewPool(DphRoot, NULL, DphRoot + 1, DPH_POOL_SIZE - sizeof(DPH_HEAP_ROOT), FALSE);
1617
1618 /* Allocate internal heap blocks. For the root */
1619 DphNode = RtlpDphAllocateNode(DphRoot);
1620 ASSERT(DphNode != NULL);
1621 DphNode->pVirtualBlock = (PUCHAR)DphRoot;
1623 RtlpDphPlaceOnPoolList(DphRoot, DphNode);
1624
1625 /* For the memory we allocated as a whole */
1626 DphNode = RtlpDphAllocateNode(DphRoot);
1627 ASSERT(DphNode != NULL);
1628 DphNode->pVirtualBlock = Base;
1629 DphNode->nVirtualBlockSize = MemSize;
1630 RtlpDphPlaceOnVirtualList(DphRoot, DphNode);
1631
1632 /* For the remaining part */
1633 DphNode = RtlpDphAllocateNode(DphRoot);
1634 ASSERT(DphNode != NULL);
1636 DphNode->nVirtualBlockSize = MemSize - (2*PAGE_SIZE + DPH_POOL_SIZE);
1637 RtlpDphCoalesceNodeIntoAvailable(DphRoot, DphNode);
1638
1639 //DphRoot->CreateStackTrace = RtlpDphLogStackTrace(1);
1640
1641 /* Initialize AVL-based busy nodes table */
1646 NULL);
1647
1648 /* Initialize per-process startup info */
1650
1651 /* Acquire the heap list lock */
1653
1654 /* Insert this heap to the tail of the global list */
1656
1657 /* Note we increased the size of the list */
1659
1660 /* Release the heap list lock */
1662
1664 {
1665 DPRINT1("Page heap: process 0x%p created heap @ %p (%p, flags 0x%X)\n",
1667 DphRoot->NormalHeap, DphRoot->ExtraFlags);
1668 }
1669
1670 /* Perform internal validation if required */
1673
1674 return (PUCHAR)DphRoot - PAGE_SIZE;
1675}
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
NTSTATUS NTAPI RtlInitializeHeapLock(IN OUT PHEAP_LOCK *Lock)
Definition: libsupp.c:128
#define PAGE_READONLY
Definition: compat.h:138
#define InsertTailList(ListHead, Entry)
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
VOID NTAPI RtlpDphPlaceOnPoolList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:515
PHEAP_LOCK RtlpDphPageHeapListLock
Definition: heappage.c:116
ULONG RtlpDphGlobalFlags
Definition: heappage.c:108
LIST_ENTRY RtlpDphPageHeapList
Definition: heappage.c:113
VOID NTAPI RtlpDphFreeNodeForTable(IN PRTL_AVL_TABLE Table, IN PVOID Buffer)
Definition: heappage.c:1227
NTSTATUS NTAPI RtlpDphProtectVm(PVOID Base, SIZE_T Size, ULONG Protection)
Definition: heappage.c:421
BOOLEAN RtlpDphPageHeapListInitialized
Definition: heappage.c:114
#define DPH_RESERVE_SIZE
Definition: heappage.c:134
VOID NTAPI RtlpDphAddNewPool(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK NodeBlock, PVOID Virtual, SIZE_T Size, BOOLEAN PlaceOnPool)
Definition: heappage.c:829
VOID NTAPI RtlpDphCoalesceNodeIntoAvailable(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:684
#define DPH_FILL
Definition: heappage.c:155
ULONG RtlpDphPageHeapListLength
Definition: heappage.c:117
PVOID NTAPI RtlpDphAllocateNodeForTable(IN PRTL_AVL_TABLE Table, IN CLONG ByteSize)
Definition: heappage.c:1206
NTSTATUS NTAPI RtlpDphProcessStartupInitialization(VOID)
Definition: heappage.c:1496
#define DPH_DEBUG_VERBOSE
Definition: heappage.c:148
struct _DPH_HEAP_ROOT * PDPH_HEAP_ROOT
RTL_GENERIC_COMPARE_RESULTS NTAPI RtlpDphCompareNodeForTable(IN PRTL_AVL_TABLE Table, IN PVOID FirstStruct, IN PVOID SecondStruct)
Definition: heappage.c:1187
#define DPH_POOL_SIZE
Definition: heappage.c:135
#define DPH_SIGNATURE
Definition: heappage.c:176
NTSTATUS NTAPI RtlpDphAllocateVm(PVOID *Base, SIZE_T Size, ULONG Type, ULONG Protection)
Definition: heappage.c:346
VOID NTAPI RtlpDphPlaceOnVirtualList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:535
#define NtCurrentTeb
#define RtlFillMemoryUlong(dst, len, val)
Definition: mkhive.h:55
NTSYSAPI NTSTATUS NTAPI ZwQueryPerformanceCounter(_Out_ PLARGE_INTEGER Counter, _Out_opt_ PLARGE_INTEGER Frequency)
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2478
struct _HEAP_LOCK * PHEAP_LOCK
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define MEM_COMMIT
Definition: nt_native.h:1313
#define PAGE_NOACCESS
Definition: nt_native.h:1302
HANDLE UniqueProcess
Definition: compat.h:825
PHEAP_LOCK HeapCritSect
Definition: heappage.c:66
ULONG Seed
Definition: heappage.c:99
LIST_ENTRY NextHeap
Definition: heappage.c:97
LIST_ENTRY AvailableAllocationHead
Definition: heappage.c:84
ULONG Signature
Definition: heappage.c:64
PVOID NormalHeap
Definition: heappage.c:100
RTL_AVL_TABLE BusyNodesTable
Definition: heappage.c:74
uint32_t ULONG_PTR
Definition: typedefs.h:65
unsigned char * PUCHAR
Definition: typedefs.h:53
char * PCHAR
Definition: typedefs.h:51
ULONG LowPart
Definition: typedefs.h:106
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1151

◆ RtlpPageHeapDestroy()

PVOID NTAPI RtlpPageHeapDestroy ( HANDLE  HeapPtr)

Definition at line 1678 of file heappage.c.

1679{
1680 PDPH_HEAP_ROOT DphRoot;
1681 PVOID Ptr;
1683 PHEAP NormalHeap;
1684 ULONG Value;
1685
1686 /* Check if it's not a process heap */
1687 if (HeapPtr == RtlGetProcessHeap())
1688 {
1690 "attempt to destroy process heap",
1691 HeapPtr, "Heap handle",
1692 0, "",
1693 0, "",
1694 0, "");
1695 return NULL;
1696 }
1697
1698 /* Get pointer to the heap root */
1699 DphRoot = RtlpDphPointerFromHandle(HeapPtr);
1700 if (!DphRoot) return NULL;
1701
1702 RtlpDphPreProcessing(DphRoot, DphRoot->HeapFlags);
1703
1704 /* Get the pointer to the normal heap */
1705 NormalHeap = DphRoot->NormalHeap;
1706
1707 /* Free the delayed-free blocks */
1708 RtlpDphFreeDelayedBlocksFromHeap(DphRoot, NormalHeap);
1709
1710 /* Go through the busy blocks */
1712
1713 while (Ptr)
1714 {
1715 Node = CONTAINING_RECORD(Ptr, DPH_HEAP_BLOCK, pUserAllocation);
1716 if (!(DphRoot->ExtraFlags & DPH_EXTRA_CHECK_UNDERRUN))
1717 {
1718 if (!RtlpDphIsPageHeapBlock(DphRoot, Node->pUserAllocation, &Value, TRUE))
1719 {
1720 RtlpDphReportCorruptedBlock(DphRoot, 3, Node->pUserAllocation, Value);
1721 }
1722 }
1723
1724 AVrfInternalHeapFreeNotification(Node->pUserAllocation, Node->nUserRequestedSize);
1725
1726 /* Go to the next node */
1728 }
1729
1730 /* Acquire the global heap list lock */
1732
1733 /* Remove the entry and decrement the global counter */
1734 RemoveEntryList(&DphRoot->NextHeap);
1736
1737 /* Release the global heap list lock */
1739
1740 /* Leave and delete this heap's critical section */
1743
1744 /* Now go through all virtual list nodes and release the VM */
1745 Node = DphRoot->pVirtualStorageListHead;
1746 while (Node)
1747 {
1748 Next = Node->pNextAlloc;
1749 /* Release the memory without checking result */
1750 RtlpDphFreeVm(Node->pVirtualBlock, 0, MEM_RELEASE);
1751 Node = Next;
1752 }
1753
1754 /* Destroy the normal heap */
1755 RtlDestroyHeap(NormalHeap);
1756
1757 /* Report success */
1759 DPRINT1("Page heap: process 0x%p destroyed heap @ %p (%p)\n",
1760 NtCurrentTeb()->ClientId.UniqueProcess, HeapPtr, NormalHeap);
1761
1762 return NULL;
1763}
NTSTATUS NTAPI RtlDeleteHeapLock(IN OUT PHEAP_LOCK Lock)
Definition: libsupp.c:103
union node Node
Definition: types.h:1255
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
NTSTATUS NTAPI RtlpDphFreeVm(PVOID Base, SIZE_T Size, ULONG Type)
Definition: heappage.c:385
VOID NTAPI AVrfInternalHeapFreeNotification(PVOID AllocationBase, SIZE_T AllocationSize)
Definition: verifier.c:364
BOOLEAN NTAPI RtlpDphIsPageHeapBlock(PDPH_HEAP_ROOT DphRoot, PVOID Block, PULONG ValidationInformation, BOOLEAN CheckFillers)
Definition: heappage.c:1421
VOID NTAPI RtlpDphFreeDelayedBlocksFromHeap(PDPH_HEAP_ROOT DphRoot, PHEAP NormalHeap)
Definition: heappage.c:1258
VOID NTAPI RtlpDphReportCorruptedBlock(_In_ PDPH_HEAP_ROOT DphRoot, _In_ ULONG Reserved, _In_ PVOID Block, _In_ ULONG ValidationInfo)
Definition: heappage.c:1330
NTSYSAPI PVOID NTAPI RtlDestroyHeap(IN PVOID HeapHandle)
STDMETHOD() Next(THIS_ ULONG celt, IAssociationElement *pElement, ULONG *pceltFetched) PURE
PDPH_HEAP_BLOCK pVirtualStorageListHead
Definition: heappage.c:69
#define VERIFIER_STOP(Code, Msg, Val1, Desc1, Val2, Desc2, Val3, Desc3, Val4, Desc4)
Definition: verifier.h:171
#define APPLICATION_VERIFIER_DESTROY_PROCESS_HEAP
Definition: verifier.h:102
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlEnumerateGenericTableAvl(_In_ PRTL_AVL_TABLE Table, _In_ BOOLEAN Restart)

◆ RtlpPageHeapFree()

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

Definition at line 1931 of file heappage.c.

1934{
1935 PDPH_HEAP_ROOT DphRoot;
1937 ULONG ValidationInfo;
1939
1940 /* Check for a NULL pointer freeing */
1941 if (!Ptr)
1942 {
1944 {
1945 DPRINT1("Page heap: freeing a null pointer\n");
1946 DbgBreakPoint();
1947 }
1948 return TRUE;
1949 }
1950
1951 /* Get a pointer to the heap root */
1952 DphRoot = RtlpDphPointerFromHandle(HeapPtr);
1953 if (!DphRoot) return FALSE;
1954
1955 /* Acquire the heap lock */
1956 RtlpDphPreProcessing(DphRoot, Flags);
1957
1958 /* Perform internal validation if specified by flags */
1961
1962 /* Add heap flags */
1963 Flags |= DphRoot->HeapFlags;
1964
1965 /* Find busy memory */
1966 Node = RtlpDphFindBusyMemory(DphRoot, Ptr);
1967
1968 if (!Node)
1969 {
1970 /* This block was not found in page heap, try a normal heap instead */
1971 //RtlpDphNormalHeapFree();
1972 ASSERT(FALSE);
1973 }
1974
1975 if (!(DphRoot->ExtraFlags & DPH_EXTRA_CHECK_UNDERRUN))
1976 {
1977 /* Check and report corrupted block */
1978 if (!RtlpDphIsPageHeapBlock(DphRoot, Ptr, &ValidationInfo, TRUE))
1979 {
1980 RtlpDphReportCorruptedBlock(DphRoot, 1, Ptr, ValidationInfo);
1981 }
1982
1983 // FIXME: Should go inside RtlpDphSetProtectionAfterUse
1984 if (Node->nVirtualAccessSize != 0)
1985 {
1986 /* Set stamps */
1987 Info = (PDPH_BLOCK_INFORMATION)Node->pUserAllocation - 1;
1988 Info->StartStamp = DPH_FILL_START_STAMP_2;
1989 Info->EndStamp = DPH_FILL_END_STAMP_2;
1990
1991 RtlpDphProtectVm(Node->pVirtualBlock, Node->nVirtualAccessSize, PAGE_NOACCESS);
1992 }
1993 }
1994 else
1995 {
1996 // FIXME: Should go inside RtlpDphSetProtectionAfterUse
1997 if (Node->nVirtualAccessSize != 0)
1998 RtlpDphProtectVm(Node->pVirtualBlock + PAGE_SIZE, Node->nVirtualAccessSize, PAGE_NOACCESS);
1999 }
2000
2001 /* Set new protection */
2002 //RtlpDphSetProtectionAfterUse(DphRoot, Node);
2003
2004 /* Remove it from the list of busy nodes */
2006
2007 /* And put it into the list of free nodes */
2008 RtlpDphPlaceOnFreeList(DphRoot, Node);
2009
2010 //if (DphRoot->ExtraFlags & DPH_EXTRA_LOG_STACK_TRACES)
2011 // Node->StackTrace = RtlpDphLogStackTrace(3);
2012 //else
2013 Node->StackTrace = NULL;
2014
2015 /* Leave the heap lock */
2016 RtlpDphPostProcessing(DphRoot);
2017
2018 /* Return success */
2019 return TRUE;
2020}
#define DPH_FILL_START_STAMP_2
Definition: heappage.c:157
struct _DPH_BLOCK_INFORMATION * PDPH_BLOCK_INFORMATION
VOID NTAPI RtlpDphPlaceOnFreeList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:495
VOID NTAPI RtlpDphRemoveFromBusyList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:642
ULONG RtlpDphBreakOptions
Definition: heappage.c:184
#define DPH_BREAK_ON_NULL_FREE
Definition: heappage.c:144
#define DPH_FILL_END_STAMP_2
Definition: heappage.c:159
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690

Referenced by RtlDebugFreeHeap().

◆ RtlpPageHeapGetUserInfo()

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

Definition at line 2193 of file heappage.c.

2198{
2199 PDPH_HEAP_ROOT DphRoot;
2201
2202 /* Get a pointer to the heap root */
2203 DphRoot = RtlpDphPointerFromHandle(HeapHandle);
2204 if (!DphRoot) return FALSE;
2205
2206 /* Add heap flags */
2207 Flags |= DphRoot->HeapFlags;
2208
2209 /* Acquire the heap lock */
2210 RtlpDphPreProcessing(DphRoot, Flags);
2211
2212 /* Find busy memory */
2214
2215 if (!Node)
2216 {
2217 /* This block was not found in page heap, try a normal heap instead */
2218 //RtlpDphNormalHeapGetUserInfo();
2219 ASSERT(FALSE);
2220 return FALSE;
2221 }
2222
2223 /* Get user values and flags and store them in user provided pointers */
2224 if (UserValue) *UserValue = Node->UserValue;
2225 if (UserFlags) *UserFlags = Node->UserFlags;
2226
2227 /* Leave the heap lock */
2228 RtlpDphPostProcessing(DphRoot);
2229
2230 /* Return success */
2231 return TRUE;
2232}

Referenced by RtlDebugGetUserInfoHeap().

◆ RtlpPageHeapLock()

BOOLEAN NTAPI RtlpPageHeapLock ( HANDLE  HeapPtr)

Definition at line 2423 of file heappage.c.

2424{
2425 PDPH_HEAP_ROOT DphRoot;
2426
2427 /* Get pointer to the heap root */
2428 DphRoot = RtlpDphPointerFromHandle(HeapPtr);
2429 if (!DphRoot) return FALSE;
2430
2431 RtlpDphEnterCriticalSection(DphRoot, DphRoot->HeapFlags);
2432 return TRUE;
2433}
VOID NTAPI RtlpDphEnterCriticalSection(PDPH_HEAP_ROOT DphRoot, ULONG Flags)
Definition: heappage.c:265

Referenced by RtlLockHeap().

◆ RtlpPageHeapReAllocate()

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

Definition at line 2023 of file heappage.c.

2027{
2028 PDPH_HEAP_ROOT DphRoot;
2029 PDPH_HEAP_BLOCK Node = NULL, AllocatedNode;
2030 BOOLEAN Biased = FALSE, UseNormalHeap = FALSE, OldBlockPageHeap = TRUE;
2031 ULONG ValidationInfo;
2033 PVOID NewAlloc = NULL;
2034
2035 /* Check requested size */
2036 if (Size > 0x7FF00000)
2037 {
2038 DPRINT1("extreme size request\n");
2039
2040 /* Generate an exception if needed */
2042
2043 return NULL;
2044 }
2045
2046 /* Unbias the pointer if necessary */
2047 if (IS_BIASED_POINTER(HeapPtr))
2048 {
2049 HeapPtr = (PVOID)POINTER_REMOVE_BIAS(HeapPtr);
2050 Biased = TRUE;
2051 }
2052
2053 /* Get a pointer to the heap root */
2054 DphRoot = RtlpDphPointerFromHandle(HeapPtr);
2055 if (!DphRoot) return NULL;
2056
2057 /* Acquire the heap lock */
2058 RtlpDphPreProcessing(DphRoot, Flags);
2059
2060 /* Perform internal validation if specified by flags */
2062 {
2064 }
2065
2066 /* Add heap flags */
2067 Flags |= DphRoot->HeapFlags;
2068
2069 /* Exit with NULL right away if inplace is specified */
2071 {
2072 /* Release the lock */
2073 RtlpDphPostProcessing(DphRoot);
2074
2075 /* Generate an exception if needed */
2077
2078 return NULL;
2079 }
2080
2081 /* Try to get node of the allocated block */
2082 AllocatedNode = RtlpDphFindBusyMemory(DphRoot, Ptr);
2083
2084 if (!AllocatedNode)
2085 {
2086 /* This block was not found in page heap, try a normal heap instead */
2087 //RtlpDphNormalHeapFree();
2088 ASSERT(FALSE);
2089 OldBlockPageHeap = FALSE;
2090 }
2091
2092 /* Check the block */
2093 if (!(DphRoot->ExtraFlags & DPH_EXTRA_CHECK_UNDERRUN))
2094 {
2095 if (!RtlpDphIsPageHeapBlock(DphRoot, AllocatedNode->pUserAllocation, &ValidationInfo, TRUE))
2096 {
2097 RtlpDphReportCorruptedBlock(DphRoot, 3, AllocatedNode->pUserAllocation, ValidationInfo);
2098 }
2099 }
2100
2101 /* Remove old one from the busy list */
2102 RtlpDphRemoveFromBusyList(DphRoot, AllocatedNode);
2103
2104 if (!Biased && !RtlpDphShouldAllocateInPageHeap(DphRoot, Size))
2105 {
2106 // FIXME: Use normal heap
2107 ASSERT(FALSE);
2108 UseNormalHeap = TRUE;
2109 }
2110 else
2111 {
2112 /* Now do a trick: bias the pointer and call our allocate routine */
2113 NewAlloc = RtlpPageHeapAllocate((PVOID)POINTER_ADD_BIAS(HeapPtr), Flags, Size);
2114 }
2115
2116 if (!NewAlloc)
2117 {
2118 /* New allocation failed, put the block back (if it was found in page heap) */
2119 RtlpDphPlaceOnBusyList(DphRoot, AllocatedNode);
2120
2121 /* Release the lock */
2122 RtlpDphPostProcessing(DphRoot);
2123
2124 /* Perform validation again if required */
2126 {
2128 }
2129
2130 /* Generate an exception if needed */
2132
2133 return NULL;
2134 }
2135
2136 /* Copy contents of the old block */
2137 if (AllocatedNode->nUserRequestedSize > Size)
2138 DataSize = Size;
2139 else
2140 DataSize = AllocatedNode->nUserRequestedSize;
2141
2142 if (DataSize != 0) RtlCopyMemory(NewAlloc, Ptr, DataSize);
2143
2144 /* Copy user flags and values */
2145 if (!UseNormalHeap)
2146 {
2147 /* Get the node of the new block */
2148 Node = RtlpDphFindBusyMemory(DphRoot, NewAlloc);
2149 ASSERT(Node != NULL);
2150
2151 /* Set its values/flags */
2152 Node->UserValue = AllocatedNode->UserValue;
2154 Node->UserFlags = Flags & HEAP_SETTABLE_USER_FLAGS;
2155 else
2156 Node->UserFlags = AllocatedNode->UserFlags;
2157 }
2158
2159 if (!OldBlockPageHeap)
2160 {
2161 /* Weird scenario, investigate */
2162 ASSERT(FALSE);
2163 }
2164
2165 /* Mark the old block as no access */
2166 if (AllocatedNode->nVirtualAccessSize != 0)
2167 {
2168 RtlpDphProtectVm(AllocatedNode->pVirtualBlock, AllocatedNode->nVirtualAccessSize, PAGE_NOACCESS);
2169 }
2170
2171 /* And place it on the free list */
2172 RtlpDphPlaceOnFreeList(DphRoot, AllocatedNode);
2173
2174 // FIXME: Capture stack traces if needed
2175 AllocatedNode->StackTrace = NULL;
2176
2177 /* Finally allocation is done, perform validation again if required */
2179 {
2181 }
2182
2183 /* Release the lock */
2184 RtlpDphPostProcessing(DphRoot);
2185
2186 DPRINT("Allocated new user block pointer: %p\n", NewAlloc);
2187
2188 /* Return pointer to user allocation */
2189 return NewAlloc;
2190}
#define POINTER_ADD_BIAS(ptr)
Definition: heappage.c:181
PVOID NTAPI RtlpPageHeapAllocate(IN PVOID HeapPtr, IN ULONG Flags, IN SIZE_T Size)
Definition: heappage.c:1766
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4755
#define HEAP_REALLOC_IN_PLACE_ONLY
Definition: nt_native.h:1696
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

Referenced by RtlDebugReAllocateHeap().

◆ RtlpPageHeapSetUserFlags()

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

Definition at line 2276 of file heappage.c.

2281{
2282 PDPH_HEAP_ROOT DphRoot;
2284
2285 /* Get a pointer to the heap root */
2286 DphRoot = RtlpDphPointerFromHandle(HeapHandle);
2287 if (!DphRoot) return FALSE;
2288
2289 /* Add heap flags */
2290 Flags |= DphRoot->HeapFlags;
2291
2292 /* Acquire the heap lock */
2293 RtlpDphPreProcessing(DphRoot, Flags);
2294
2295 /* Find busy memory */
2297
2298 if (!Node)
2299 {
2300 /* This block was not found in page heap, try a normal heap instead */
2301 //RtlpDphNormalHeapSetUserFlags();
2302 ASSERT(FALSE);
2303 return FALSE;
2304 }
2305
2306 /* Get user values and flags and store them in user provided pointers */
2307 Node->UserFlags &= ~(UserFlagsReset);
2308 Node->UserFlags |= UserFlagsSet;
2309
2310 /* Leave the heap lock */
2311 RtlpDphPostProcessing(DphRoot);
2312
2313 /* Return success */
2314 return TRUE;
2315}

Referenced by RtlDebugSetUserFlagsHeap().

◆ RtlpPageHeapSetUserValue()

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

Definition at line 2235 of file heappage.c.

2239{
2240 PDPH_HEAP_ROOT DphRoot;
2242
2243 /* Get a pointer to the heap root */
2244 DphRoot = RtlpDphPointerFromHandle(HeapHandle);
2245 if (!DphRoot) return FALSE;
2246
2247 /* Add heap flags */
2248 Flags |= DphRoot->HeapFlags;
2249
2250 /* Acquire the heap lock */
2251 RtlpDphPreProcessing(DphRoot, Flags);
2252
2253 /* Find busy memory */
2255
2256 if (!Node)
2257 {
2258 /* This block was not found in page heap, try a normal heap instead */
2259 //RtlpDphNormalHeapSetUserValue();
2260 ASSERT(FALSE);
2261 return FALSE;
2262 }
2263
2264 /* Get user values and flags and store them in user provided pointers */
2265 Node->UserValue = UserValue;
2266
2267 /* Leave the heap lock */
2268 RtlpDphPostProcessing(DphRoot);
2269
2270 /* Return success */
2271 return TRUE;
2272}

Referenced by RtlDebugSetUserValueHeap().

◆ RtlpPageHeapSize()

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

Definition at line 2318 of file heappage.c.

2321{
2322 PDPH_HEAP_ROOT DphRoot;
2324 SIZE_T Size;
2325
2326 /* Get a pointer to the heap root */
2327 DphRoot = RtlpDphPointerFromHandle(HeapHandle);
2328 if (!DphRoot) return -1;
2329
2330 /* Add heap flags */
2331 Flags |= DphRoot->HeapFlags;
2332
2333 /* Acquire the heap lock */
2334 RtlpDphPreProcessing(DphRoot, Flags);
2335
2336 /* Find busy memory */
2338
2339 if (!Node)
2340 {
2341 /* This block was not found in page heap, try a normal heap instead */
2342 //RtlpDphNormalHeapSize();
2343 ASSERT(FALSE);
2344 return -1;
2345 }
2346
2347 /* Get heap block size */
2348 Size = Node->nUserRequestedSize;
2349
2350 /* Leave the heap lock */
2351 RtlpDphPostProcessing(DphRoot);
2352
2353 /* Return user requested size */
2354 return Size;
2355}

Referenced by RtlDebugSizeHeap().

◆ RtlpPageHeapUnlock()

BOOLEAN NTAPI RtlpPageHeapUnlock ( HANDLE  HeapPtr)

Definition at line 2437 of file heappage.c.

2438{
2439 PDPH_HEAP_ROOT DphRoot;
2440
2441 /* Get pointer to the heap root */
2442 DphRoot = RtlpDphPointerFromHandle(HeapPtr);
2443 if (!DphRoot) return FALSE;
2444
2446 return TRUE;
2447}
VOID NTAPI RtlpDphLeaveCriticalSection(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:293

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;
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 */
105
106 /* Zero last unused item */
108 Heap->ProcessHeapsListIndex = 0;
109
110 /* Release the lock */
112}
int Count
Definition: noreturn.cpp:7

◆ RtlpValidateHeap()

BOOLEAN NTAPI RtlpValidateHeap ( PHEAP  Heap,
BOOLEAN  ForceValidation 
)

Definition at line 3532 of file heap.c.

3534{
3535 UCHAR SegmentOffset;
3536 SIZE_T TotalFreeSize;
3537 PLIST_ENTRY ListHead, NextEntry;
3538 ULONG FreeBlocksCount, FreeListEntriesCount;
3540
3541 /* Check headers */
3542 if (!RtlpValidateHeapHeaders(Heap, FALSE))
3543 return FALSE;
3544
3545 /* Skip validation if it's not needed */
3546 if (!ForceValidation && !(Heap->Flags & HEAP_VALIDATE_ALL_ENABLED))
3547 return TRUE;
3548
3549 /* Check free list */
3550 FreeListEntriesCount = 0;
3551 ListHead = &Heap->FreeLists;
3552 NextEntry = ListHead->Flink;
3553
3554 while (NextEntry != ListHead)
3555 {
3557
3558 NextEntry = NextEntry->Flink;
3559
3560 if (NextEntry != ListHead)
3561 {
3562 PHEAP_FREE_ENTRY NextFreeEntry = CONTAINING_RECORD(NextEntry, HEAP_FREE_ENTRY, FreeList);
3563 /* Free entries must be sorted */
3564 if (FreeEntry->Size > NextFreeEntry->Size)
3565 {
3566 DPRINT1("Dedicated free entry %p of size %ld is not put in order.\n", FreeEntry, FreeEntry->Size);
3567 }
3568 }
3569
3570 /* Check that the hint is there */
3571 if (FreeEntry->Size > Heap->DeCommitFreeBlockThreshold)
3572 {
3573 if (Heap->FreeHints[0] == NULL)
3574 {
3575 DPRINT1("No hint pointing to the non-dedicated list although there is a free entry %p of size %ld.\n",
3576 FreeEntry, FreeEntry->Size);
3577 }
3578 if (!RtlTestBit(&Heap->FreeHintBitmap, 0))
3579 {
3580 DPRINT1("Hint bit 0 is not set although there is a free entry %p of size %ld.\n",
3581 FreeEntry, FreeEntry->Size);
3582 }
3583 }
3584 else
3585 {
3586 if (Heap->FreeHints[FreeEntry->Size - 1] == NULL)
3587 {
3588 DPRINT1("No hint pointing to the dedicated list although there is a free entry %p of size %ld.\n",
3589 FreeEntry, FreeEntry->Size);
3590 }
3591 if (!RtlTestBit(&Heap->FreeHintBitmap, FreeEntry->Size - 1))
3592 {
3593 DPRINT1("Hint bit 0 is not set although there is a free entry %p of size %ld.\n",
3594 FreeEntry, FreeEntry->Size);
3595 }
3596 }
3597
3598 /* If there is an in-use entry in a free list - that's quite a big problem */
3599 if (FreeEntry->Flags & HEAP_ENTRY_BUSY)
3600 {
3601 DPRINT1("HEAP: Free element %p is marked in-use\n", FreeEntry);
3602 return FALSE;
3603 }
3604
3605 /* Add up to the total amount of free entries */
3606 FreeListEntriesCount++;
3607 }
3608
3609 /* Check free list hints */
3611 {
3612 if (Heap->FreeHints[HintIndex] != NULL)
3613 {
3615
3616 if (!RtlTestBit(&Heap->FreeHintBitmap, HintIndex))
3617 {
3618 DPRINT1("Hint bitmap bit at %u is not set, but there is a hint entry.\n", HintIndex);
3619 }
3620
3621 if (HintIndex == 0)
3622 {
3623 if (FreeEntry->Size <= Heap->DeCommitFreeBlockThreshold)
3624 {
3625 DPRINT1("There is an entry %p of size %lu, smaller than the decommit threshold %lu in the non-dedicated free list hint.\n",
3626 FreeEntry, FreeEntry->Size, Heap->DeCommitFreeBlockThreshold);
3627 }
3628 }
3629 else
3630 {
3631 if (HintIndex != FreeEntry->Size - 1)
3632 {
3633 DPRINT1("There is an entry %p of size %lu at the position %u in the free entry hint array.\n",
3634 FreeEntry, FreeEntry->Size, HintIndex);
3635 }
3636
3637 if (FreeEntry->FreeList.Blink != &Heap->FreeLists)
3638 {
3639 /* The entry right before the hint must be smaller. */
3640 PHEAP_FREE_ENTRY PreviousFreeEntry = CONTAINING_RECORD(FreeEntry->FreeList.Blink,
3642 FreeList);
3643 if (PreviousFreeEntry->Size >= FreeEntry->Size)
3644 {
3645 DPRINT1("Free entry hint %p of size %lu is larger than the entry before it %p, which is of size %lu.\n",
3646 FreeEntry, FreeEntry->Size, PreviousFreeEntry, PreviousFreeEntry->Size);
3647 }
3648 }
3649 }
3650 }
3651 else if (RtlTestBit(&Heap->FreeHintBitmap, HintIndex))
3652 {
3653 DPRINT1("Hint bitmap bit at %u is set, but there is no hint entry.\n", HintIndex);
3654 }
3655 }
3656
3657 /* Check big allocations */
3658 ListHead = &Heap->VirtualAllocdBlocks;
3659 NextEntry = ListHead->Flink;
3660
3661 while (ListHead != NextEntry)
3662 {
3664
3665 /* We can only check the fill pattern */
3666 if (VirtualAllocBlock->BusyBlock.Flags & HEAP_ENTRY_FILL_PATTERN)
3667 {
3668 if (!RtlpCheckInUsePattern(&VirtualAllocBlock->BusyBlock))
3669 return FALSE;
3670 }
3671
3672 NextEntry = NextEntry->Flink;
3673 }
3674
3675 /* Check all segments */
3676 FreeBlocksCount = 0;
3677 TotalFreeSize = 0;
3678
3679 for (SegmentOffset = 0; SegmentOffset < HEAP_SEGMENTS; SegmentOffset++)
3680 {
3681 PHEAP_SEGMENT Segment = Heap->Segments[SegmentOffset];
3682
3683 /* Go to the next one if there is no segment */
3684 if (!Segment) continue;
3685
3686 if (!RtlpValidateHeapSegment(Heap,
3687 Segment,
3688 SegmentOffset,
3689 &FreeBlocksCount,
3690 &TotalFreeSize,
3691 NULL,
3692 NULL))
3693 {
3694 return FALSE;
3695 }
3696 }
3697
3698 if (FreeListEntriesCount != FreeBlocksCount)
3699 {
3700 DPRINT1("HEAP: Free blocks count in arena (%lu) does not match free blocks number in the free lists (%lu)\n", FreeBlocksCount, FreeListEntriesCount);
3701 return FALSE;
3702 }
3703
3704 if (Heap->TotalFreeSize != TotalFreeSize)
3705 {
3706 DPRINT1("HEAP: Total size of free blocks in arena (%Iu) does not equal to the one in heap header (%Iu)\n", TotalFreeSize, Heap->TotalFreeSize);
3707 return FALSE;
3708 }
3709
3710 return TRUE;
3711}
void FreeList(LOCATIONITEM *pItems)
Definition: CSearchBar.cpp:95
#define RtlTestBit
Definition: dbgbitmap.h:347
BOOLEAN NTAPI RtlpCheckInUsePattern(PHEAP_ENTRY HeapEntry)
Definition: heap.c:3249
BOOLEAN NTAPI RtlpValidateHeapSegment(PHEAP Heap, PHEAP_SEGMENT Segment, UCHAR SegmentOffset, PULONG FreeEntriesCount, PSIZE_T TotalFreeSize, PSIZE_T TagEntries, PSIZE_T PseudoTagEntries)
Definition: heap.c:3345
#define HEAP_ENTRY_FILL_PATTERN
Definition: heap.h:42
LIST_ENTRY FreeList
Definition: heap.h:132
HEAP_ENTRY BusyBlock
Definition: heap.h:313
PLIST_ENTRY FreeHints[ANYSIZE_ARRAY]
Definition: heap.h:268
RTL_BITMAP FreeHintBitmap
Definition: heap.h:267
LIST_ENTRY VirtualAllocdBlocks
Definition: heap.h:251
LIST_ENTRY FreeLists
Definition: heap.h:259
SIZE_T DeCommitFreeBlockThreshold
Definition: heap.h:237
struct _HEAP_SEGMENT * Segments[HEAP_SEGMENTS]
Definition: heap.h:253
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
_In_ ULONG _In_ ULONG HintIndex
Definition: rtlfuncs.h:613

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

◆ RtlpValidateHeapEntry()

BOOLEAN NTAPI RtlpValidateHeapEntry ( PHEAP  Heap,
PHEAP_ENTRY  HeapEntry 
)

Definition at line 3288 of file heap.c.

3291{
3292 BOOLEAN BigAllocation, EntryFound = FALSE;
3294 ULONG SegmentOffset;
3295
3296 /* Perform various consistency checks of this entry */
3297 if (!HeapEntry) goto invalid_entry;
3298 if ((ULONG_PTR)HeapEntry & (HEAP_ENTRY_SIZE - 1)) goto invalid_entry;
3299 if (!(HeapEntry->Flags & HEAP_ENTRY_BUSY)) goto invalid_entry;
3300
3301 BigAllocation = HeapEntry->Flags & HEAP_ENTRY_VIRTUAL_ALLOC;
3302 Segment = Heap->Segments[HeapEntry->SegmentOffset];
3303
3304 if (BigAllocation &&
3305 (((ULONG_PTR)HeapEntry & (PAGE_SIZE - 1)) != FIELD_OFFSET(HEAP_VIRTUAL_ALLOC_ENTRY, BusyBlock)))
3306 goto invalid_entry;
3307
3308 if (!BigAllocation && (HeapEntry->SegmentOffset >= HEAP_SEGMENTS ||
3309 !Segment ||
3310 HeapEntry < Segment->FirstEntry ||
3311 HeapEntry >= Segment->LastValidEntry))
3312 goto invalid_entry;
3313
3314 if ((HeapEntry->Flags & HEAP_ENTRY_FILL_PATTERN) &&
3315 !RtlpCheckInUsePattern(HeapEntry))
3316 goto invalid_entry;
3317
3318 /* Checks are done, if this is a virtual entry, that's all */
3319 if (HeapEntry->Flags & HEAP_ENTRY_VIRTUAL_ALLOC) return TRUE;
3320
3321 /* Go through segments and check if this entry fits into any of them */
3322 for (SegmentOffset = 0; SegmentOffset < HEAP_SEGMENTS; SegmentOffset++)
3323 {
3324 Segment = Heap->Segments[SegmentOffset];
3325 if (!Segment) continue;
3326
3327 if ((HeapEntry >= Segment->FirstEntry) &&
3328 (HeapEntry < Segment->LastValidEntry))
3329 {
3330 /* Got it */
3331 EntryFound = TRUE;
3332 break;
3333 }
3334 }
3335
3336 /* Return our result of finding entry in the segments */
3337 return EntryFound;
3338
3339invalid_entry:
3340 DPRINT1("HEAP: Invalid heap entry %p in heap %p\n", HeapEntry, Heap);
3341 return FALSE;
3342}
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255

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

◆ RtlpValidateHeapHeaders()

BOOLEAN NTAPI RtlpValidateHeapHeaders ( PHEAP  Heap,
BOOLEAN  Recalculate 
)

Definition at line 3279 of file heap.c.

3282{
3283 // We skip header validation for now
3284 return TRUE;
3285}

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

Variable Documentation

◆ RtlpPageHeapEnabled

BOOLEAN RtlpPageHeapEnabled
extern

Definition at line 107 of file heappage.c.

◆ RtlpProcessHeapsListLock

RTL_CRITICAL_SECTION RtlpProcessHeapsListLock
extern