ReactOS  0.4.14-dev-1036-g3c5b10f
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_FREELISTS   128
 
#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
 

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))
 
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 27 of file heap.h.

◆ ARENA_INUSE_FILLER

#define ARENA_INUSE_FILLER   0xBAADF00D

Definition at line 26 of file heap.h.

◆ HEAP_ENTRY_BUSY

#define HEAP_ENTRY_BUSY   0x01

Definition at line 41 of file heap.h.

◆ HEAP_ENTRY_EXTRA_PRESENT

#define HEAP_ENTRY_EXTRA_PRESENT   0x02

Definition at line 42 of file heap.h.

◆ HEAP_ENTRY_FILL_PATTERN

#define HEAP_ENTRY_FILL_PATTERN   0x04

Definition at line 43 of file heap.h.

◆ HEAP_ENTRY_LAST_ENTRY

#define HEAP_ENTRY_LAST_ENTRY   0x10

Definition at line 45 of file heap.h.

◆ HEAP_ENTRY_SETTABLE_FLAG1

#define HEAP_ENTRY_SETTABLE_FLAG1   0x20

Definition at line 46 of file heap.h.

◆ HEAP_ENTRY_SETTABLE_FLAG2

#define HEAP_ENTRY_SETTABLE_FLAG2   0x40

Definition at line 47 of file heap.h.

◆ HEAP_ENTRY_SETTABLE_FLAG3

#define HEAP_ENTRY_SETTABLE_FLAG3   0x80

Definition at line 48 of file heap.h.

◆ HEAP_ENTRY_SETTABLE_FLAGS

Definition at line 49 of file heap.h.

◆ HEAP_ENTRY_SHIFT

#define HEAP_ENTRY_SHIFT   3

Definition at line 22 of file heap.h.

◆ HEAP_ENTRY_SIZE

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

Definition at line 18 of file heap.h.

◆ HEAP_ENTRY_VIRTUAL_ALLOC

#define HEAP_ENTRY_VIRTUAL_ALLOC   0x08

Definition at line 44 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 36 of file heap.h.

◆ HEAP_FREELISTS

#define HEAP_FREELISTS   128

Definition at line 15 of file heap.h.

◆ HEAP_GLOBAL_TAG

#define HEAP_GLOBAL_TAG   0x0800

Definition at line 31 of file heap.h.

◆ HEAP_MAX_BLOCK_SIZE

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

Definition at line 24 of file heap.h.

◆ HEAP_PSEUDO_TAG_FLAG

#define HEAP_PSEUDO_TAG_FLAG   0x8000

Definition at line 32 of file heap.h.

◆ HEAP_SEGMENT_SIGNATURE

#define HEAP_SEGMENT_SIGNATURE   0xffeeffee

Definition at line 53 of file heap.h.

◆ HEAP_SEGMENTS

#define HEAP_SEGMENTS   64

Definition at line 16 of file heap.h.

◆ HEAP_SIGNATURE

#define HEAP_SIGNATURE   0xeefeeff

Definition at line 52 of file heap.h.

◆ HEAP_TAG_MASK

#define HEAP_TAG_MASK   (HEAP_MAXIMUM_TAG << HEAP_TAG_SHIFT)

Definition at line 33 of file heap.h.

◆ HEAP_TAGS_MASK

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

Definition at line 34 of file heap.h.

◆ HEAP_TAIL_FILL

#define HEAP_TAIL_FILL   0xab

Definition at line 28 of file heap.h.

◆ HEAP_USER_ALLOCATED

#define HEAP_USER_ALLOCATED   0x1

Definition at line 56 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 319 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 319 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/2]

C_ASSERT ( sizeof(HEAP_ENTRY = =8)

◆ C_ASSERT() [2/2]

C_ASSERT ( (1<< HEAP_ENTRY_SHIFT = =sizeof(HEAP_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 TRUE
Definition: types.h:120
#define HEAP_NO_SERIALIZE
Definition: nt_native.h:1692
NTSTATUS NTAPI RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
Definition: libsupp.c:108
SIZE_T MaximumAllocationSize
Definition: heap.h:237
ULONG Signature
Definition: heap.h:231
BOOLEAN NTAPI RtlpValidateHeap(PHEAP Heap, BOOLEAN ForceValidation)
Definition: heap.c:3397
#define HEAP_SETTABLE_USER_VALUE
Definition: nt_native.h:1704
BOOLEAN NTAPI RtlpValidateHeapHeaders(PHEAP Heap, BOOLEAN Recalculate)
Definition: heap.c:3144
#define HEAP_SKIP_VALIDATION_CHECKS
Definition: rtltypes.h:165
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
ULONG_PTR AlignMask
Definition: heap.h:247
PHEAP_LOCK LockVariable
Definition: heap.h:263
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
_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
#define HEAP_VALIDATE_ALL_ENABLED
Definition: rtltypes.h:166
#define HEAP_FLAG_PAGE_ALLOCS
Definition: rtltypes.h:160
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
PVOID NTAPI RtlpPageHeapAllocate(IN PVOID HeapPtr, IN ULONG Flags, IN SIZE_T Size)
Definition: heappage.c:1697
ULONG_PTR SIZE_T
Definition: typedefs.h:79
ULONG_PTR AlignRound
Definition: heap.h:246
ULONG Flags
Definition: heap.h:223
#define HEAP_SIGNATURE
Definition: heap.h:52
struct _HEAP_ENTRY_EXTRA HEAP_ENTRY_EXTRA
#define DPRINT1
Definition: precomp.h:8
struct _HEAP * PHEAP
ULONG ForceFlags
Definition: heap.h:224
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 }
#define TRUE
Definition: types.h:120
#define HEAP_NO_SERIALIZE
Definition: nt_native.h:1692
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:3144
#define HEAP_SKIP_VALIDATION_CHECKS
Definition: rtltypes.h:165
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
smooth NULL
Definition: ftsmooth.c:416
#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)
#define MEM_FREE
Definition: nt_native.h:1317
#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:18
_In_ PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
Definition: iotypes.h:872
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)
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment IN PNDIS_RW_LOCK Lock
Definition: CrNtStubs.h:75
Status
Definition: gdiplustypes.h:24
_In_opt_ PVOID _In_opt_ SIZE_T ReserveSize
Definition: rtlfuncs.h:2169
#define DPRINT1
Definition: precomp.h:8
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:231
PVOID HeaderValidateCopy
Definition: heap.h:240
BOOLEAN NTAPI RtlpValidateHeap(PHEAP Heap, BOOLEAN ForceValidation)
Definition: heap.c:3397
#define NtCurrentProcess()
Definition: nt_native.h:1657
PPEB NTAPI RtlGetCurrentPeb(VOID)
Definition: libsupp.c:63
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
ULONG_PTR SIZE_T
Definition: typedefs.h:79
PVOID ProcessHeap
Definition: ntddk_ex.h:249
#define HEAP_SIGNATURE
Definition: heap.h:52
#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 TRUE
Definition: types.h:120
#define HEAP_NO_SERIALIZE
Definition: nt_native.h:1692
NTSTATUS NTAPI RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
Definition: libsupp.c:108
BOOLEAN NTAPI RtlpValidateHeapEntry(PHEAP Heap, PHEAP_ENTRY HeapEntry)
Definition: heap.c:3153
_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:231
BOOLEAN NTAPI RtlpValidateHeap(PHEAP Heap, BOOLEAN ForceValidation)
Definition: heap.c:3397
BOOLEAN NTAPI RtlpValidateHeapHeaders(PHEAP Heap, BOOLEAN Recalculate)
Definition: heap.c:3144
#define HEAP_SKIP_VALIDATION_CHECKS
Definition: rtltypes.h:165
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
PHEAP_LOCK LockVariable
Definition: heap.h:263
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
#define HEAP_FLAG_PAGE_ALLOCS
Definition: rtltypes.h:160
Definition: heap.h:136
#define HEAP_SIGNATURE
Definition: heap.h:52
#define DPRINT1
Definition: precomp.h:8
struct _HEAP * PHEAP
ULONG ForceFlags
Definition: heap.h:224
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 TRUE
Definition: types.h:120
#define HEAP_NO_SERIALIZE
Definition: nt_native.h:1692
NTSTATUS NTAPI RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
Definition: libsupp.c:108
BOOLEAN NTAPI RtlpValidateHeapEntry(PHEAP Heap, PHEAP_ENTRY HeapEntry)
Definition: heap.c:3153
ULONG Signature
Definition: heap.h:231
BOOLEAN NTAPI RtlpValidateHeap(PHEAP Heap, BOOLEAN ForceValidation)
Definition: heap.c:3397
#define HEAP_SKIP_VALIDATION_CHECKS
Definition: rtltypes.h:165
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
PHEAP_LOCK LockVariable
Definition: heap.h:263
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:3781
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
#define HEAP_FLAG_PAGE_ALLOCS
Definition: rtltypes.h:160
Definition: heap.h:136
#define HEAP_SIGNATURE
Definition: heap.h:52
#define DPRINT1
Definition: precomp.h:8
struct _HEAP * PHEAP
ULONG ForceFlags
Definition: heap.h:224
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 TRUE
Definition: types.h:120
#define HEAP_NO_SERIALIZE
Definition: nt_native.h:1692
NTSTATUS NTAPI RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
Definition: libsupp.c:108
BOOLEAN NTAPI RtlpValidateHeapEntry(PHEAP Heap, PHEAP_ENTRY HeapEntry)
Definition: heap.c:3153
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
SIZE_T MaximumAllocationSize
Definition: heap.h:237
ULONG Signature
Definition: heap.h:231
BOOLEAN NTAPI RtlpValidateHeap(PHEAP Heap, BOOLEAN ForceValidation)
Definition: heap.c:3397
#define HEAP_SETTABLE_USER_VALUE
Definition: nt_native.h:1704
BOOLEAN NTAPI RtlpValidateHeapHeaders(PHEAP Heap, BOOLEAN Recalculate)
Definition: heap.c:3144
#define HEAP_SKIP_VALIDATION_CHECKS
Definition: rtltypes.h:165
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
ULONG_PTR AlignMask
Definition: heap.h:247
PHEAP_LOCK LockVariable
Definition: heap.h:263
unsigned char BOOLEAN
struct _HEAP_ENTRY * PHEAP_ENTRY
smooth NULL
Definition: ftsmooth.c:416
_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 RtlpPageHeapReAllocate(HANDLE HeapPtr, ULONG Flags, PVOID Ptr, SIZE_T Size)
Definition: heappage.c:1954
#define HEAP_FLAG_PAGE_ALLOCS
Definition: rtltypes.h:160
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
ULONG_PTR SIZE_T
Definition: typedefs.h:79
ULONG_PTR AlignRound
Definition: heap.h:246
Definition: heap.h:136
#define HEAP_SIGNATURE
Definition: heap.h:52
struct _HEAP_ENTRY_EXTRA HEAP_ENTRY_EXTRA
#define DPRINT1
Definition: precomp.h:8
struct _HEAP * PHEAP
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T)
Definition: heap.c:2561
ULONG ForceFlags
Definition: heap.h:224
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 TRUE
Definition: types.h:120
#define HEAP_NO_SERIALIZE
Definition: nt_native.h:1692
NTSTATUS NTAPI RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
Definition: libsupp.c:108
BOOLEAN NTAPI RtlpValidateHeapEntry(PHEAP Heap, PHEAP_ENTRY HeapEntry)
Definition: heap.c:3153
ULONG Signature
Definition: heap.h:231
BOOLEAN NTAPI RtlpValidateHeap(PHEAP Heap, BOOLEAN ForceValidation)
Definition: heap.c:3397
#define HEAP_SKIP_VALIDATION_CHECKS
Definition: rtltypes.h:165
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
PHEAP_LOCK LockVariable
Definition: heap.h:263
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
#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:3726
Definition: heap.h:136
BOOLEAN NTAPI RtlpPageHeapSetUserFlags(PVOID HeapHandle, ULONG Flags, PVOID BaseAddress, ULONG UserFlagsReset, ULONG UserFlagsSet)
Definition: heappage.c:2207
#define HEAP_SIGNATURE
Definition: heap.h:52
#define DPRINT1
Definition: precomp.h:8
struct _HEAP * PHEAP
ULONG ForceFlags
Definition: heap.h:224
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 TRUE
Definition: types.h:120
#define HEAP_NO_SERIALIZE
Definition: nt_native.h:1692
NTSTATUS NTAPI RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
Definition: libsupp.c:108
BOOLEAN NTAPI RtlpValidateHeapEntry(PHEAP Heap, PHEAP_ENTRY HeapEntry)
Definition: heap.c:3153
ULONG Signature
Definition: heap.h:231
BOOLEAN NTAPI RtlpValidateHeap(PHEAP Heap, BOOLEAN ForceValidation)
Definition: heap.c:3397
#define HEAP_SKIP_VALIDATION_CHECKS
Definition: rtltypes.h:165
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
BOOLEAN NTAPI RtlSetUserValueHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID BaseAddress, IN PVOID UserValue)
Definition: heap.c:3664
PHEAP_LOCK LockVariable
Definition: heap.h:263
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
#define HEAP_FLAG_PAGE_ALLOCS
Definition: rtltypes.h:160
Definition: heap.h:136
#define HEAP_SIGNATURE
Definition: heap.h:52
#define DPRINT1
Definition: precomp.h:8
struct _HEAP * PHEAP
ULONG ForceFlags
Definition: heap.h:224
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 TRUE
Definition: types.h:120
#define HEAP_NO_SERIALIZE
Definition: nt_native.h:1692
NTSTATUS NTAPI RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
Definition: libsupp.c:108
BOOLEAN NTAPI RtlpValidateHeapEntry(PHEAP Heap, PHEAP_ENTRY HeapEntry)
Definition: heap.c:3153
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
ULONG Signature
Definition: heap.h:231
BOOLEAN NTAPI RtlpValidateHeap(PHEAP Heap, BOOLEAN ForceValidation)
Definition: heap.c:3397
#define HEAP_SKIP_VALIDATION_CHECKS
Definition: rtltypes.h:165
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
PHEAP_LOCK LockVariable
Definition: heap.h:263
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
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:79
Definition: heap.h:136
#define HEAP_SIGNATURE
Definition: heap.h:52
#define DPRINT1
Definition: precomp.h:8
struct _HEAP * PHEAP
ULONG ForceFlags
Definition: heap.h:224
Definition: heap.c:51

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
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)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
ULONG NumberOfHeaps
Definition: ntddk_ex.h:286
PVOID * ProcessHeaps
Definition: ntddk_ex.h:288
ULONG MaximumNumberOfHeaps
Definition: ntddk_ex.h:287
PPEB NTAPI RtlGetCurrentPeb(VOID)
Definition: libsupp.c:63
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned short USHORT
Definition: pedump.c:61
USHORT ProcessHeapsListIndex
Definition: heap.h:238

◆ RtlpCoalesceFreeBlocks()

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

Definition at line 980 of file heap.c.

984 {
985  PHEAP_FREE_ENTRY CurrentEntry, NextEntry;
986 
987  /* Get the previous entry */
988  CurrentEntry = (PHEAP_FREE_ENTRY)((PHEAP_ENTRY)FreeEntry - FreeEntry->PreviousSize);
989 
990  /* Check it */
991  if (CurrentEntry != FreeEntry &&
992  !(CurrentEntry->Flags & HEAP_ENTRY_BUSY) &&
993  (*FreeSize + CurrentEntry->Size) <= HEAP_MAX_BLOCK_SIZE)
994  {
995  ASSERT(FreeEntry->PreviousSize == CurrentEntry->Size);
996 
997  /* Remove it if asked for */
998  if (Remove)
999  {
1000  RtlpRemoveFreeBlock(Heap, FreeEntry, FALSE, FALSE);
1001  Heap->TotalFreeSize -= FreeEntry->Size;
1002 
1003  /* Remove it only once! */
1004  Remove = FALSE;
1005  }
1006 
1007  /* Remove previous entry too */
1008  RtlpRemoveFreeBlock(Heap, CurrentEntry, FALSE, FALSE);
1009 
1010  /* Copy flags */
1011  CurrentEntry->Flags = FreeEntry->Flags & HEAP_ENTRY_LAST_ENTRY;
1012 
1013  /* Advance FreeEntry and update sizes */
1014  FreeEntry = CurrentEntry;
1015  *FreeSize = *FreeSize + CurrentEntry->Size;
1016  Heap->TotalFreeSize -= CurrentEntry->Size;
1017  FreeEntry->Size = (USHORT)(*FreeSize);
1018 
1019  /* Also update previous size if needed */
1020  if (!(FreeEntry->Flags & HEAP_ENTRY_LAST_ENTRY))
1021  {
1022  ((PHEAP_ENTRY)FreeEntry + *FreeSize)->PreviousSize = (USHORT)(*FreeSize);
1023  }
1024  }
1025 
1026  /* Check the next block if it exists */
1027  if (!(FreeEntry->Flags & HEAP_ENTRY_LAST_ENTRY))
1028  {
1029  NextEntry = (PHEAP_FREE_ENTRY)((PHEAP_ENTRY)FreeEntry + *FreeSize);
1030 
1031  if (!(NextEntry->Flags & HEAP_ENTRY_BUSY) &&
1032  NextEntry->Size + *FreeSize <= HEAP_MAX_BLOCK_SIZE)
1033  {
1034  ASSERT(*FreeSize == NextEntry->PreviousSize);
1035 
1036  /* Remove it if asked for */
1037  if (Remove)
1038  {
1039  RtlpRemoveFreeBlock(Heap, FreeEntry, FALSE, FALSE);
1040  Heap->TotalFreeSize -= FreeEntry->Size;
1041  }
1042 
1043  /* Copy flags */
1044  FreeEntry->Flags = NextEntry->Flags & HEAP_ENTRY_LAST_ENTRY;
1045 
1046  /* Remove next entry now */
1047  RtlpRemoveFreeBlock(Heap, NextEntry, FALSE, FALSE);
1048 
1049  /* Update sizes */
1050  *FreeSize = *FreeSize + NextEntry->Size;
1051  Heap->TotalFreeSize -= NextEntry->Size;
1052  FreeEntry->Size = (USHORT)(*FreeSize);
1053 
1054  /* Also update previous size if needed */
1055  if (!(FreeEntry->Flags & HEAP_ENTRY_LAST_ENTRY))
1056  {
1057  ((PHEAP_ENTRY)FreeEntry + *FreeSize)->PreviousSize = (USHORT)(*FreeSize);
1058  }
1059  }
1060  }
1061  return FreeEntry;
1062 }
SIZE_T TotalFreeSize
Definition: heap.h:236
#define HEAP_MAX_BLOCK_SIZE
Definition: heap.h:24
Definition: heap.h:130
struct _HEAP_ENTRY * PHEAP_ENTRY
#define HEAP_ENTRY_BUSY
Definition: heap.h:41
_In_ BOOLEAN Remove
Definition: psfuncs.h:110
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID NTAPI RtlpRemoveFreeBlock(PHEAP Heap, PHEAP_FREE_ENTRY FreeEntry, BOOLEAN Dedicated, BOOLEAN NoFill)
Definition: heap.c:382
struct _HEAP_FREE_ENTRY * PHEAP_FREE_ENTRY
Definition: heap.h:136
unsigned short USHORT
Definition: pedump.c:61
#define HEAP_ENTRY_LAST_ENTRY
Definition: heap.h:45

Referenced by RtlFreeHeap(), 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
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
PDPH_HEAP_BLOCK NTAPI RtlpDphFindBusyMemory(PDPH_HEAP_ROOT DphRoot, PVOID pUserMem)
Definition: heappage.c:934
ULONG HeapFlags
Definition: heappage.c:64
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
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 RtlValidateHeap().

◆ RtlpGetExtraStuffPointer()

PHEAP_ENTRY_EXTRA NTAPI RtlpGetExtraStuffPointer ( PHEAP_ENTRY  HeapEntry)

Definition at line 2526 of file heap.c.

2527 {
2528  PHEAP_VIRTUAL_ALLOC_ENTRY VirtualEntry;
2529 
2530  /* Check if it's a big block */
2531  if (HeapEntry->Flags & HEAP_ENTRY_VIRTUAL_ALLOC)
2532  {
2533  VirtualEntry = CONTAINING_RECORD(HeapEntry, HEAP_VIRTUAL_ALLOC_ENTRY, BusyBlock);
2534 
2535  /* Return a pointer to the extra stuff*/
2536  return &VirtualEntry->ExtraStuff;
2537  }
2538  else
2539  {
2540  /* This is a usual entry, which means extra stuff follows this block */
2541  return (PHEAP_ENTRY_EXTRA)(HeapEntry + HeapEntry->Size - 1);
2542  }
2543 }
Definition: heap.h:321
#define HEAP_ENTRY_VIRTUAL_ALLOC
Definition: heap.h:44
Definition: heap.h:305
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:324

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

◆ RtlpHeapIsSpecial()

FORCEINLINE BOOLEAN RtlpHeapIsSpecial ( ULONG  Flags)

Definition at line 60 of file heap.h.

61 {
63 
69  {
70  /* This is a special heap */
71  return TRUE;
72  }
73 
74  /* No need for a special treatment */
75  return FALSE;
76 }
#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
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define HEAP_VALIDATE_PARAMETERS_ENABLED
Definition: rtltypes.h:167
#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 TRUE
Definition: types.h:120
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
#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
NTSTATUS NTAPI RtlpDphSetProtectionBeforeUse(PDPH_HEAP_ROOT DphRoot, PUCHAR VirtualBlock, ULONG UserSize)
Definition: heappage.c:951
#define POINTER_REMOVE_BIAS(ptr)
Definition: heappage.c:179
void DbgBreakPoint()
Definition: mach.c:553
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
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
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
PDPH_HEAP_BLOCK NTAPI RtlpDphAllocateNode(PDPH_HEAP_ROOT DphRoot)
Definition: heappage.c:988
void * PVOID
Definition: retypes.h:9
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
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#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
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#define DPH_DEBUG_INTERNAL_VALIDATE
Definition: heappage.c:146
Status
Definition: gdiplustypes.h:24
ULONG_PTR SIZE_T
Definition: typedefs.h:79
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:246
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#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 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
#define TRUE
Definition: types.h:120
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
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:2374
#define DPH_RESERVE_SIZE
Definition: heappage.c:133
PVOID NormalHeap
Definition: heappage.c:99
#define InsertTailList(ListHead, Entry)
HANDLE UniqueProcess
Definition: compat.h:482
#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:64
PHEAP_LOCK HeapCritSect
Definition: heappage.c:65
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
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
ULONG HeapFlags
Definition: heappage.c:64
ULONG ExtraFlags
Definition: heappage.c:97
#define PAGE_NOACCESS
Definition: nt_native.h:1302
smooth NULL
Definition: ftsmooth.c:416
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
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1163
#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
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
PUCHAR pVirtualBlock
Definition: heappage.c:49
_In_ PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
Definition: iotypes.h:872
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:105
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
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment IN PNDIS_RW_LOCK Lock
Definition: CrNtStubs.h:75
#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
Status
Definition: gdiplustypes.h:24
ULONG Signature
Definition: heappage.c:63
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
ULONG Flags
Definition: heap.h:223
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define PAGE_READONLY
Definition: compat.h:127
#define DPRINT1
Definition: precomp.h:8
BOOLEAN RtlpDphPageHeapListInitialized
Definition: heappage.c:113
unsigned int ULONG
Definition: retypes.h:1
struct _HEAP * PHEAP
ULONG ForceFlags
Definition: heap.h:224
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
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2374
PHEAP_LOCK RtlpDphPageHeapListLock
Definition: heappage.c:115
#define TRUE
Definition: types.h:120
NTSTATUS NTAPI RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
Definition: libsupp.c:108
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
PVOID NormalHeap
Definition: heappage.c:99
HANDLE UniqueProcess
Definition: compat.h:482
void DbgBreakPoint()
Definition: mach.c:553
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
union node Node
Definition: types.h:1255
ULONG HeapFlags
Definition: heappage.c:64
ULONG ExtraFlags
Definition: heappage.c:97
smooth NULL
Definition: ftsmooth.c:416
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
_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 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
void DbgBreakPoint()
Definition: mach.c:553
struct TraceInfo Info
#define DPH_FILL_END_STAMP_2
Definition: heappage.c:158
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
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
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
smooth NULL
Definition: ftsmooth.c:416
struct _DPH_BLOCK_INFORMATION * PDPH_BLOCK_INFORMATION
VOID NTAPI RtlpDphPlaceOnFreeList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:465
#define DPH_FILL_START_STAMP_2
Definition: heappage.c:156
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
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 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
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
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
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
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
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
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#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
#define POINTER_REMOVE_BIAS(ptr)
Definition: heappage.c:179
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define POINTER_ADD_BIAS(ptr)
Definition: heappage.c:180
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
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
void * PVOID
Definition: retypes.h:9
VOID NTAPI RtlpDphPlaceOnFreeList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
Definition: heappage.c:465
#define HEAP_SETTABLE_USER_FLAGS
Definition: nt_native.h:1708
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
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
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#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:79
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:246
#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
ULONG RtlpDphDebugOptions
Definition: heappage.c:184
#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
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
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
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
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
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
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
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
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
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
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
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
ULONG_PTR SIZE_T
Definition: typedefs.h:79
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
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)
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
smooth NULL
Definition: ftsmooth.c:416
ULONG NumberOfHeaps
Definition: ntddk_ex.h:286
PVOID * ProcessHeaps
Definition: ntddk_ex.h:288
PPEB NTAPI RtlGetCurrentPeb(VOID)
Definition: libsupp.c:63
USHORT ProcessHeapsListIndex
Definition: heap.h:238
unsigned int ULONG
Definition: retypes.h:1
Definition: heap.c:51

◆ RtlpValidateHeap()

BOOLEAN NTAPI RtlpValidateHeap ( PHEAP  Heap,
BOOLEAN  ForceValidation 
)

Definition at line 3397 of file heap.c.

3399 {
3401  BOOLEAN EmptyList;
3402  UCHAR SegmentOffset;
3403  SIZE_T Size, TotalFreeSize;
3404  ULONG PreviousSize;
3405  PHEAP_VIRTUAL_ALLOC_ENTRY VirtualAllocBlock;
3406  PLIST_ENTRY ListHead, NextEntry;
3407  PHEAP_FREE_ENTRY FreeEntry;
3408  ULONG FreeBlocksCount, FreeListEntriesCount;
3409 
3410  /* Check headers */
3411  if (!RtlpValidateHeapHeaders(Heap, FALSE))
3412  return FALSE;
3413 
3414  /* Skip validation if it's not needed */
3415  if (!ForceValidation && !(Heap->Flags & HEAP_VALIDATE_ALL_ENABLED))
3416  return TRUE;
3417 
3418  /* Check free lists bitmaps */
3419  FreeListEntriesCount = 0;
3420  ListHead = &Heap->FreeLists[0];
3421 
3422  for (Size = 0; Size < HEAP_FREELISTS; Size++)
3423  {
3424  if (Size)
3425  {
3426  /* This is a dedicated list. Check if it's empty */
3427  EmptyList = IsListEmpty(ListHead);
3428 
3429  if (Heap->u.FreeListsInUseBytes[Size >> 3] & (1 << (Size & 7)))
3430  {
3431  if (EmptyList)
3432  {
3433  DPRINT1("HEAP: Empty %x-free list marked as non-empty\n", Size);
3434  return FALSE;
3435  }
3436  }
3437  else
3438  {
3439  if (!EmptyList)
3440  {
3441  DPRINT1("HEAP: Non-empty %x-free list marked as empty\n", Size);
3442  return FALSE;
3443  }
3444  }
3445  }
3446 
3447  /* Now check this list entries */
3448  NextEntry = ListHead->Flink;
3449  PreviousSize = 0;
3450 
3451  while (ListHead != NextEntry)
3452  {
3453  FreeEntry = CONTAINING_RECORD(NextEntry, HEAP_FREE_ENTRY, FreeList);
3454  NextEntry = NextEntry->Flink;
3455 
3456  /* If there is an in-use entry in a free list - that's quite a big problem */
3457  if (FreeEntry->Flags & HEAP_ENTRY_BUSY)
3458  {
3459  DPRINT1("HEAP: %Ix-dedicated list free element %p is marked in-use\n", Size, FreeEntry);
3460  return FALSE;
3461  }
3462 
3463  /* Check sizes according to that specific list's size */
3464  if ((Size == 0) && (FreeEntry->Size < HEAP_FREELISTS))
3465  {
3466  DPRINT1("HEAP: Non dedicated list free element %p has size %x which would fit a dedicated list\n", FreeEntry, FreeEntry->Size);
3467  return FALSE;
3468  }
3469  else if (Size && (FreeEntry->Size != Size))
3470  {
3471  DPRINT1("HEAP: %Ix-dedicated list free element %p has incorrect size %x\n", Size, FreeEntry, FreeEntry->Size);
3472  return FALSE;
3473  }
3474  else if ((Size == 0) && (FreeEntry->Size < PreviousSize))
3475  {
3476  DPRINT1("HEAP: Non dedicated list free element %p is not put in order\n", FreeEntry);
3477  return FALSE;
3478  }
3479 
3480  /* Remember previous size*/
3481  PreviousSize = FreeEntry->Size;
3482 
3483  /* Add up to the total amount of free entries */
3484  FreeListEntriesCount++;
3485  }
3486 
3487  /* Go to the head of the next free list */
3488  ListHead++;
3489  }
3490 
3491  /* Check big allocations */
3492  ListHead = &Heap->VirtualAllocdBlocks;
3493  NextEntry = ListHead->Flink;
3494 
3495  while (ListHead != NextEntry)
3496  {
3497  VirtualAllocBlock = CONTAINING_RECORD(NextEntry, HEAP_VIRTUAL_ALLOC_ENTRY, Entry);
3498 
3499  /* We can only check the fill pattern */
3500  if (VirtualAllocBlock->BusyBlock.Flags & HEAP_ENTRY_FILL_PATTERN)
3501  {
3502  if (!RtlpCheckInUsePattern(&VirtualAllocBlock->BusyBlock))
3503  return FALSE;
3504  }
3505 
3506  NextEntry = NextEntry->Flink;
3507  }
3508 
3509  /* Check all segments */
3510  FreeBlocksCount = 0;
3511  TotalFreeSize = 0;
3512 
3513  for (SegmentOffset = 0; SegmentOffset < HEAP_SEGMENTS; SegmentOffset++)
3514  {
3515  Segment = Heap->Segments[SegmentOffset];
3516 
3517  /* Go to the next one if there is no segment */
3518  if (!Segment) continue;
3519 
3520  if (!RtlpValidateHeapSegment(Heap,
3521  Segment,
3522  SegmentOffset,
3523  &FreeBlocksCount,
3524  &TotalFreeSize,
3525  NULL,
3526  NULL))
3527  {
3528  return FALSE;
3529  }
3530  }
3531 
3532  if (FreeListEntriesCount != FreeBlocksCount)
3533  {
3534  DPRINT1("HEAP: Free blocks count in arena (%lu) does not match free blocks number in the free lists (%lu)\n", FreeBlocksCount, FreeListEntriesCount);
3535  return FALSE;
3536  }
3537 
3538  if (Heap->TotalFreeSize != TotalFreeSize)
3539  {
3540  DPRINT1("HEAP: Total size of free blocks in arena (%Iu) does not equal to the one in heap header (%Iu)\n", TotalFreeSize, Heap->TotalFreeSize);
3541  return FALSE;
3542  }
3543 
3544  return TRUE;
3545 }
Definition: heap.h:321
#define TRUE
Definition: types.h:120
UCHAR FreeListsInUseBytes[HEAP_FREELISTS/(sizeof(UCHAR) *8)]
Definition: heap.h:261
SIZE_T TotalFreeSize
Definition: heap.h:236
#define HEAP_SEGMENTS
Definition: heap.h:16
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
BOOLEAN NTAPI RtlpValidateHeapHeaders(PHEAP Heap, BOOLEAN Recalculate)
Definition: heap.c:3144
struct _HEAP_SEGMENT * Segments[HEAP_SEGMENTS]
Definition: heap.h:250
Definition: heap.h:130
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define HEAP_ENTRY_BUSY
Definition: heap.h:41
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:893
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
#define HEAP_VALIDATE_ALL_ENABLED
Definition: rtltypes.h:166
LIST_ENTRY VirtualAllocdBlocks
Definition: heap.h:248
#define HEAP_FREELISTS
Definition: heap.h:15
unsigned char UCHAR
Definition: xmlstorage.h:181
MmuFreePage * FreeList
Definition: mmuobject.c:60
BOOLEAN NTAPI RtlpCheckInUsePattern(PHEAP_ENTRY HeapEntry)
Definition: heap.c:3114
Definition: typedefs.h:118
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#define HEAP_ENTRY_FILL_PATTERN
Definition: heap.h:43
ULONG_PTR SIZE_T
Definition: typedefs.h:79
ULONG Flags
Definition: heap.h:223
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
HEAP_ENTRY BusyBlock
Definition: heap.h:327
BOOLEAN NTAPI RtlpValidateHeapSegment(PHEAP Heap, PHEAP_SEGMENT Segment, UCHAR SegmentOffset, PULONG FreeEntriesCount, PSIZE_T TotalFreeSize, PSIZE_T TagEntries, PSIZE_T PseudoTagEntries)
Definition: heap.c:3210
union _HEAP::@4025 u
base of all file and directory entries
Definition: entries.h:82
LIST_ENTRY FreeLists[HEAP_FREELISTS]
Definition: heap.h:256

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

◆ RtlpValidateHeapEntry()

BOOLEAN NTAPI RtlpValidateHeapEntry ( PHEAP  Heap,
PHEAP_ENTRY  HeapEntry 
)

Definition at line 3153 of file heap.c.

3156 {
3157  BOOLEAN BigAllocation, EntryFound = FALSE;
3159  ULONG SegmentOffset;
3160 
3161  /* Perform various consistency checks of this entry */
3162  if (!HeapEntry) goto invalid_entry;
3163  if ((ULONG_PTR)HeapEntry & (HEAP_ENTRY_SIZE - 1)) goto invalid_entry;
3164  if (!(HeapEntry->Flags & HEAP_ENTRY_BUSY)) goto invalid_entry;
3165 
3166  BigAllocation = HeapEntry->Flags & HEAP_ENTRY_VIRTUAL_ALLOC;
3167  Segment = Heap->Segments[HeapEntry->SegmentOffset];
3168 
3169  if (BigAllocation &&
3170  (((ULONG_PTR)HeapEntry & (PAGE_SIZE - 1)) != FIELD_OFFSET(HEAP_VIRTUAL_ALLOC_ENTRY, BusyBlock)))
3171  goto invalid_entry;
3172 
3173  if (!BigAllocation && (HeapEntry->SegmentOffset >= HEAP_SEGMENTS ||
3174  !Segment ||
3175  HeapEntry < Segment->FirstEntry ||
3176  HeapEntry >= Segment->LastValidEntry))
3177  goto invalid_entry;
3178 
3179  if ((HeapEntry->Flags & HEAP_ENTRY_FILL_PATTERN) &&
3180  !RtlpCheckInUsePattern(HeapEntry))
3181  goto invalid_entry;
3182 
3183  /* Checks are done, if this is a virtual entry, that's all */
3184  if (HeapEntry->Flags & HEAP_ENTRY_VIRTUAL_ALLOC) return TRUE;
3185 
3186  /* Go through segments and check if this entry fits into any of them */
3187  for (SegmentOffset = 0; SegmentOffset < HEAP_SEGMENTS; SegmentOffset++)
3188  {
3189  Segment = Heap->Segments[SegmentOffset];
3190  if (!Segment) continue;
3191 
3192  if ((HeapEntry >= Segment->FirstEntry) &&
3193  (HeapEntry < Segment->LastValidEntry))
3194  {
3195  /* Got it */
3196  EntryFound = TRUE;
3197  break;
3198  }
3199  }
3200 
3201  /* Return our result of finding entry in the segments */
3202  return EntryFound;
3203 
3204 invalid_entry:
3205  DPRINT1("HEAP: Invalid heap entry %p in heap %p\n", HeapEntry, Heap);
3206  return FALSE;
3207 }
Definition: heap.h:321
#define TRUE
Definition: types.h:120
#define HEAP_ENTRY_VIRTUAL_ALLOC
Definition: heap.h:44
#define HEAP_SEGMENTS
Definition: heap.h:16
uint32_t ULONG_PTR
Definition: typedefs.h:64
struct _HEAP_SEGMENT * Segments[HEAP_SEGMENTS]
Definition: heap.h:250
unsigned char BOOLEAN
#define HEAP_ENTRY_BUSY
Definition: heap.h:41
_Inout_ PVOID Segment
Definition: exfuncs.h:893
#define HEAP_ENTRY_SIZE
Definition: heap.h:18
BOOLEAN NTAPI RtlpCheckInUsePattern(PHEAP_ENTRY HeapEntry)
Definition: heap.c:3114
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define HEAP_ENTRY_FILL_PATTERN
Definition: heap.h:43
#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 3144 of file heap.c.

3147 {
3148  // We skip header validation for now
3149  return TRUE;
3150 }
#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