1 #ifndef WINDOWS_HEAP_H
2 #define WINDOWS_HEAP_H
3 
4 #include <windows.h>
5 #include <winternl.h>
6 
7 /*
8 	Defines most of heap related structures on Windows (some still missing)
9 	Tested only on Windows 10 1809 x64
10 	TODO:
11 		Clean/organize this: Order and Style
12 		-Can this be useful in unix? does mdmp even have a heap? remote dbg session?
13 		x86 vs x64 Struct Differences:
14 			-Structs definetly unaligned, check pdb
15 			-Do something like the the linux_heap that includes itself but with another bitness
16 				-Define macros to prefix structs to W32 or W64
17 
18 		Some structs are different based on the Windows version (XP, Vista, 7, Server, 8, 8.1, 10)
19 		  and updates (Service Packs, Windows 10 Seasonal Updates)
20 			-Maybe use offsets instead of depending on structs
21 			-Create structs for each windows version (ie post-fix XP_SP2, 7, 10_1703)? (Oh god)
22 			-What about the parsing functions? Alter its behaviour depending on version or create
23 				one function for each version
24 */
25 #define EXTRA_FLAG			(1ULL << (sizeof (size_t) * 8 - 1))
26 
27 #define SHIFT 16
28 #define LFH_BLOCK			(1 << (SHIFT))
29 #define LARGE_BLOCK			(1 << (SHIFT + 1))
30 #define NT_BLOCK			(1 << (SHIFT + 2))
31 #define SEGMENT_HEAP_BLOCK	(1 << (SHIFT + 3))
32 #define VS_BLOCK			(1 << (SHIFT + 4))
33 #define BACKEND_BLOCK		(1 << (SHIFT + 5))
34 
35 typedef struct _HEAP_LOCAL_DATA *PHEAP_LOCAL_DATA;
36 typedef struct _HEAP_SUBSEGMENT *PHEAP_SUBSEGMENT;
37 typedef struct _LFH_HEAP *PLFH_HEAP;
38 typedef struct _HEAP *PHEAP;
39 
40 typedef struct _RTL_BALANCED_NODE *PRTL_BALANCED_NODE;
41 typedef struct _RTL_BALANCED_NODE {
42 	union {
43 		PRTL_BALANCED_NODE Children[2];
44 		struct {
45 			PRTL_BALANCED_NODE Left;
46 			PRTL_BALANCED_NODE Right;
47 		};
48 	};
49 	union {
50 		BYTE Red : 1;
51 		BYTE Balance : 2;
52 		WPARAM ParentValue;
53 	};
54 } RTL_BALANCED_NODE, *PRTL_BALANCED_NODE;
55 
56 typedef struct _RTL_RB_TREE {
57 	PRTL_BALANCED_NODE Root;
58 	union {
59 		BOOL Encoded : 1;
60 		PRTL_BALANCED_NODE Min;
61 	};
62 } RTL_RB_TREE, *PRTL_RB_TREE;
63 
64 typedef struct _HEAP_COUNTERS {
65 	WPARAM TotalMemoryReserved;
66 	WPARAM TotalMemoryCommitted;
67 	WPARAM TotalMemoryLargeUCR;
68 	WPARAM TotalSizeInVirtualBlocks;
69 	ULONG32 TotalSegments;
70 	ULONG32 TotalUCRs;
71 	ULONG32 CommittOps;
72 	ULONG32 DeCommitOps;
73 	ULONG32 LockAcquires;
74 	ULONG32 LockCollisions;
75 	ULONG32 CommitRate;
76 	ULONG32 DecommittRate;
77 	ULONG32 CommitFailures;
78 	ULONG32 InBlockCommitFailures;
79 	ULONG32 PollIntervalCounter;
80 	ULONG32 DecommitsSinceLastCheck;
81 	ULONG32 HeapPollInterval;
82 	ULONG32 AllocAndFreeOps;
83 	ULONG32 AllocationIndicesActive;
84 	ULONG32 InBlockDeccommits;
85 	WPARAM InBlockDeccomitSize;
86 	WPARAM HighWatermarkSize;
87 	WPARAM LastPolledSize;
88 } HEAP_COUNTERS, *PHEAP_COUNTERS;
89 
90 typedef struct _HEAP_BUCKET_COUNTERS {
91 	union {
92 		struct {
93 			ULONG TotalBlocks;
94 			ULONG SubSegmentCounts;
95 		};
96 		UINT64 Aggregate64;
97 	};
98 } HEAP_BUCKET_COUNTERS, *PHEAP_BUCKET_COUNTERS;
99 
100 typedef struct _INTERLOCK_SEQ { // Is this right? NO!
101 	union {
102 		WORD Depth;
103 		union {
104 			union {
105 				WORD Hint : 15;
106 				WORD Lock : 1;
107 			};
108 			WORD Hint16;
109 		};
110 		INT32 Exchg;
111 	};
112 } INTERLOCK_SEQ, *PINTERLOCK_SEQ;
113 
114 typedef struct _HEAP_UNPACKED_ENTRY {
115 #if defined(_M_X64)
116 	PVOID                       PreviousBlockPrivateData;
117 #endif
118 	union {
119 		struct {
120 			UINT16 Size;
121 			UINT8 Flags;
122 			UINT8 SmallTagIndex;
123 		};
124 #if defined(_M_X64)
125 		struct {
126 			ULONG32 SubSegmentCode;
127 			UINT16 PreviousSize;
128 			union {
129 				UINT8 SegmentOffset;
130 				UINT8 LFHFlags;
131 			};
132 			UINT8 UnusedBytes;
133 		};
134 		UINT64 CompactHeader;
135 #else
136 		ULONG32 SubSegmentCode;
137 #endif
138 	};
139 #if !defined(_M_X64)
140 	UINT16 PreviousSize;
141 	union {
142 		UINT8 SegmentOffset;
143 		UINT8 LFHFlags;
144 	};
145 	UINT8 UnusedBytes;
146 #endif
147 } HEAP_UNPACKED_ENTRY, *PHEAP_UNPACKED_ENTRY;
148 
149 typedef struct _HEAP_EXTENDED_ENTRY {
150 #if defined(_M_X64)
151 	PVOID Reserved;
152 #endif
153 	union {
154 		struct {
155 			UINT16 FunctionIndex;
156 			UINT16 ContextValue;
157 		};
158 		ULONG32 InterceptorValue;
159 	};
160 	UINT16 UnusedBytesLength;
161 	UINT8 EntryOffset;
162 	UINT8 ExtendedBlockSignature;
163 } HEAP_EXTENDED_ENTRY, *PHEAP_EXTENDED_ENTRY;
164 
165 typedef struct _HEAP_ENTRY {
166 	union {
167 		HEAP_UNPACKED_ENTRY UnpackedEntry;
168 		struct {
169 #if defined(_M_X64)
170 			PVOID PreviousBlockPrivateData;
171 			union {
172 				struct {
173 					UINT16 Size;
174 					UINT8 Flags;
175 					UINT8 SmallTagIndex;
176 				};
177 				struct {
178 					ULONG32 SubSegmentCode;
179 					UINT16 PreviousSize;
180 					union {
181 						UINT8 SegmentOffset;
182 						UINT8 LFHFlags;
183 					};
184 					UINT8 UnusedBytes;
185 				};
186 				UINT64 CompactHeader;
187 			};
188 #else
189 			UINT16 Size;
190 			UINT8 Flags;
191 			UINT8 SmallTagIndex;
192 #endif
193 		};
194 #if !defined(_M_X64)
195 		struct {
196 			ULONG32 SubSegmentCode;
197 			UINT16 PreviousSize;
198 			union {
199 				UINT8 SegmentOffset;
200 				UINT8 LFHFlags;
201 			};
202 			UINT8 UnusedBytes;
203 		};
204 #endif
205 		HEAP_EXTENDED_ENTRY ExtendedEntry;
206 		struct {
207 #if defined(_M_X64)
208 			PVOID Reserved;
209 			union {
210 				struct {
211 					UINT16 FunctionIndex;
212 					UINT16 ContextValue;
213 				};
214 				ULONG32 InterceptorValue;
215 			};
216 			UINT16 UnusedBytesLength;
217 			UINT8 EntryOffset;
218 			UINT8 ExtendedBlockSignature;
219 #else
220 			UINT16 FunctionIndex;
221 			UINT16 ContextValue;
222 #endif
223 		};
224 		struct {
225 #if defined(_M_X64)
226 			PVOID ReservedForAlignment;
227 			union {
228 				struct {
229 					ULONG32 Code1;
230 					union {
231 						struct {
232 							UINT16 Code2;
233 							UINT8 Code3;
234 							UINT8 Code4;
235 						};
236 						ULONG32 Code234;
237 					};
238 				};
239 				UINT64 AgregateCode;
240 			};
241 #else
242 			ULONG32 InterceptorValue;
243 			UINT16 UnusedBytesLength;
244 			UINT8 EntryOffset;
245 			UINT8 ExtendedBlockSignature;
246 #endif
247 		};
248 #if !defined(_M_X64)
249 		struct {
250 			ULONG32 Code1;
251 			union {
252 				struct {
253 					UINT16 Code2;
254 					UINT8 Code3;
255 					UINT8 Code4;
256 				};
257 				ULONG32 Code234;
258 			};
259 		};
260 		UINT64 AgregateCode;
261 #endif
262 	};
263 } HEAP_ENTRY, *PHEAP_ENTRY;
264 
265 typedef struct _HEAP_LOCK {
266 	union {
267 		RTL_CRITICAL_SECTION CriticalSection;
268 		PVOID /*(ERESOURCE)*/ Resource;
269 	} Lock;
270 } HEAP_LOCK, *PHEAP_LOCK;
271 
272 typedef struct _HEAP_TAG_ENTRY {
273 	ULONG32 Allocs;
274 	ULONG32 Frees;
275 	WPARAM Size;
276 	UINT16 TagIndex;
277 	UINT16 CreatorBackTraceIndex;
278 	WCHAR TagName[24];
279 #if defined(_M_X64)
280 	UINT8 _PADDING0_[4];
281 #endif
282 } HEAP_TAG_ENTRY, *PHEAP_TAG_ENTRY;
283 
284 typedef struct _HEAP_PSEUDO_TAG_ENTRY {
285 	ULONG32 Allocs;
286 	ULONG32 Frees;
287 	WPARAM Size;
288 } HEAP_PSEUDO_TAG_ENTRY, *PHEAP_PSEUDO_TAG_ENTRY;
289 
290 typedef struct _HEAP_TUNING_PARAMETERS {
291 	ULONG32 CommittThresholdShift;
292 #if defined(_M_X64)
293 	UINT8 _PADDING0_[4];
294 #endif
295 	WPARAM MaxPreCommittThreshold;
296 } HEAP_TUNING_PARAMETERS, *PHEAP_TUNING_PARAMETERS;
297 
298 typedef struct _RTL_HEAP_MEMORY_LIMIT_DATA {
299 	WPARAM CommitLimitBytes;
300 	WPARAM CommitLimitFailureCode;
301 	WPARAM MaxAllocationSizeBytes;
302 	WPARAM AllocationLimitFailureCode;
303 } RTL_HEAP_MEMORY_LIMIT_DATA, *PRTL_HEAP_MEMORY_LIMIT_DATA;
304 
305 typedef struct _RTL_HP_ENV_HANDLE {
306 	PVOID h[2];
307 } RTL_HP_ENV_HANDLE, *PRTL_HP_ENV_HANDLE;
308 
309 typedef struct _RTL_HP_SEG_ALLOC_POLICY {
310 	WPARAM MinLargePages;
311 	WPARAM MaxLargePages;
312 	UINT8 MinUtilization;
313 } RTL_HP_SEG_ALLOC_POLICY, *PRTL_HP_SEG_ALLOC_POLICY;
314 
315 typedef enum _RTLP_HP_LOCK_TYPE {
316 	HeapLockPaged,
317 	HeapLockNonPaged,
318 	HeapLockTypeMax
319 } RTLP_HP_LOCK_TYPE;
320 
321 typedef struct _HEAP_SUBALLOCATOR_CALLBACKS {
322 	PVOID Allocate;
323 	PVOID Free;
324 	PVOID Commit;
325 	PVOID Decommit;
326 	PVOID ExtendContext;
327 } HEAP_SUBALLOCATOR_CALLBACKS, *PHEAP_SUBALLOCATOR_CALLBACKS;
328 
329 typedef struct _RTL_HP_VS_CONFIG {
330 	struct {
331 		ULONG PageAlignLargeAllocs : 1;
332 		ULONG FullDecommit : 1;
333 	} Flags;
334 } RTL_HP_VS_CONFIG, *PRTL_HP_VS_CONFIG;
335 
336 typedef struct _HEAP_VS_SUBSEGMENT {
337 	LIST_ENTRY ListEntry;
338 	WPARAM CommitBitmap;
339 	WPARAM CommitLock;
340 	UINT16 Size;
341 	UINT16 Signature : 15;
342 	bool FullCommit : 1;
343 	WPARAM Spare;
344 } HEAP_VS_SUBSEGMENT, *PHEAP_VS_SUBSEGMENT;
345 
346 typedef struct _HEAP_VS_CONTEXT {
347 	RTL_SRWLOCK Lock;
348 	WPARAM /*RTLP_HP_LOCK_TYPE*/ LockType;
349 	RTL_RB_TREE FreeChunkTree;
350 	LIST_ENTRY SubsegmentList;
351 	WPARAM TotalCommittedUnits;
352 	WPARAM FreeCommittedUnits;
353 	WPARAM /*HEAP_VS_DELAY_FREE_CONTEXT*/ DelayFreeContext[8]; // 0x40 Bytes
354 	PVOID BackendCtx;
355 	HEAP_SUBALLOCATOR_CALLBACKS Callbacks;
356 	RTL_HP_VS_CONFIG Config;
357 	UINT Flags;
358 	WPARAM Padding;
359 } HEAP_VS_CONTEXT, *PHEAP_VS_CONTEXT;
360 
361 typedef struct _HEAP_VS_CHUNK_HEADER_SIZE {
362 	union {
363 		WPARAM HeaderBits;
364 		USHORT KeyUShort;
365 		ULONG KeyULong;
366 		struct {
367 			USHORT MemoryCost;
368 			USHORT UnsafeSize;
369 			USHORT UnsafePrevSize;
370 			UINT8 Allocated;
371 		};
372 	};
373 } HEAP_VS_CHUNK_HEADER_SIZE, *PHEAP_VS_CHUNK_HEADER_SIZE;
374 
375 typedef struct _HEAP_VS_CHUNK_HEADER {
376 	HEAP_VS_CHUNK_HEADER_SIZE Sizes;
377 	union {
378 		ULONG EncodedSegmentPageOffset : 8;
379 		ULONG UnusedBytes : 1;
380 		ULONG SkipDuringWalk : 1;
381 		ULONG Spare : 22;
382 		ULONG AllocatedChunkBits;
383 	};
384 } HEAP_VS_CHUNK_HEADER, *PHEAP_VS_CHUNK_HEADER;
385 
386 enum {
387 	PAGE_RANGE_FLAGS_LFH_SUBSEGMENT = 0x01,
388 	PAGE_RANGE_FLAGS_COMMITED		= 0x02,
389 	PAGE_RANGE_FLAGS_ALLOCATED		= 0x04,
390 	PAGE_RANGE_FLAGS_FIRST			= 0x08,
391 	PAGE_RANGE_FLAGS_VS_SUBSEGMENT	= 0x20 // LIES
392 };
393 
394 typedef struct _HEAP_PAGE_RANGE_DESCRIPTOR {
395 	union {
396 		RTL_BALANCED_NODE TreeNode;
397 		struct {
398 			ULONG TreeSignature;
399 			ULONG UnusedBytes;
400 		};
401 		union {
402 			bool ExtraPresent;
403 			UINT16 Spare0 : 15;
404 		};
405 	};
406 	UCHAR RangeFlags;
407 	UCHAR CommittedPageCount;
408 	USHORT Spare;
409 	union {
410 		//_HEAP_DESCRIPTOR_KEY Key;
411 		UCHAR Align[3];
412 	};
413 	union {
414 		UCHAR UnitOffset;
415 		UCHAR UnitSize;
416 	};
417 } HEAP_PAGE_RANGE_DESCRIPTOR, *PHEAP_PAGE_RANGE_DESCRIPTOR;
418 
419 typedef struct _HEAP_PAGE_SEGMENT {
420 	union {
421 		struct {
422 			LIST_ENTRY ListEntry;
423 			WPARAM Signature;
424 			PVOID SegmentCommitState;
425 			UCHAR UnusedWatermark;
426 		};
427 		HEAP_PAGE_RANGE_DESCRIPTOR DescArray[256];
428 	};
429 } HEAP_PAGE_SEGMENT, *PHEAP_PAGE_SEGMENT;
430 
431 typedef struct _RTL_HP_LFH_CONFIG {
432 	USHORT MaxBlockSize;
433 	BYTE WitholdPageCrossingBlocks : 1;
434 } RTL_HP_LFH_CONFIG, *PRTL_HP_LFH_CONFIG;
435 
436 typedef struct _HEAP_LFH_SUBSEGMENT_STAT {
437 	BYTE Index;
438 	BYTE Count;
439 } HEAP_LFH_SUBSEGMENT_STAT, *PHEAP_LFH_SUBSEGMENT_STAT;
440 
441 typedef struct _HEAP_LFH_SUBSEGMENT_STATS {
442 	union {
443 		HEAP_LFH_SUBSEGMENT_STAT Buckets[4];
444 		UINT64 Stats;
445 	};
446 } HEAP_LFH_SUBSEGMENT_STATS, *PHEAP_LFH_SUBSEGMENT_STATS;
447 
448 typedef struct _HEAP_LFH_SUBSEGMENT_OWNER {
449 	struct {
450 		BYTE IsBucket : 1;
451 		BYTE Spare0 : 7;
452 	};
453 	BYTE BucketIndex;
454 	union {
455 		BYTE SlotCount;
456 		BYTE SlotIndex;
457 	};
458 	BYTE Spare1;
459 	WPARAM AvailableSubsegmentCount;
460 	RTL_SRWLOCK Lock;
461 	LIST_ENTRY AvailableSubsegmentList;
462 	LIST_ENTRY FullSubsegmentList;
463 } HEAP_LFH_SUBSEGMENT_OWNER, *PHEAP_LFH_SUBSEGMENT_OWNER;
464 
465 typedef struct _HEAP_LFH_FAST_REF {
466 	union {
467 		PVOID Target;
468 		WPARAM Value;
469 		UINT16 RefCount : 12;
470 	};
471 } HEAP_LFH_FAST_REF, *PHEAP_LFH_FAST_REF;
472 
473 typedef struct _HEAP_LFH_AFFINITY_SLOT {
474 	HEAP_LFH_SUBSEGMENT_OWNER State;
475 	HEAP_LFH_FAST_REF ActiveSubsegment;
476 } HEAP_LFH_AFFINITY_SLOT, *PHEAP_LFH_AFFINITY_SLOT;
477 
478 typedef struct _HEAP_LFH_BUCKET {
479 	HEAP_LFH_SUBSEGMENT_OWNER State;
480 	WPARAM TotalBlockCount;
481 	WPARAM TotalSubsegmentCount;
482 	UINT ReciprocalBlockSize;
483 	UINT8 Shift;
484 	UINT8 ContentionCount;
485 	WPARAM AffinityMappingLock;
486 	PUINT8 ProcAffinityMapping;
487 	PHEAP_LFH_AFFINITY_SLOT *AffinitySlots;
488 } HEAP_LFH_BUCKET, *PHEAP_LFH_BUCKET;
489 
490 typedef struct _HEAP_LFH_CONTEXT {
491 	PVOID BackendCtx;
492 	HEAP_SUBALLOCATOR_CALLBACKS Callbacks;
493 	PUINT8 AffinityModArray;
494 	UINT8 MaxAffinity;
495 	UINT8 LockType;
496 	USHORT MemStatsOffset;
497 	RTL_HP_LFH_CONFIG Config;
498 	HEAP_LFH_SUBSEGMENT_STATS BucketStats;
499 	WPARAM SubsegmentCreationLock;
500 	WPARAM Padding[6];
501 	PHEAP_LFH_BUCKET Buckets[129];
502 } HEAP_LFH_CONTEXT, *PHEAP_LFH_CONTEXT;
503 
504 typedef struct _HEAP_LFH_SUBSEGMENT_ENCODED_OFFSETS {
505 	union {
506 		UINT32 EncodedData;
507 		struct {
508 			UINT16 BlockSize;
509 			UINT16 FirstBlockOffset;
510 		};
511 	};
512 } HEAP_LFH_SUBSEGMENT_ENCODED_OFFSETS, *PHEAP_LFH_SUBSEGMENT_ENCODED_OFFSETS;
513 
514 typedef struct _HEAP_LFH_SUBSEGMENT {
515 	LIST_ENTRY ListEntry;
516 	union {
517 		PHEAP_LFH_SUBSEGMENT_OWNER Owner;
518 		WPARAM /*HEAP_LFH_SUBSEGMENT_DELAY_FREE*/ DelayFree;
519 	};
520 	WPARAM CommitLock;
521 	union {
522 		struct {
523 			UINT16 FreeCount;
524 			UINT16 BlockCount;
525 		};
526 		union {
527 			SHORT InterlockedShort;
528 			LONG InterlockedLong;
529 		};
530 	};
531 	UINT16 FreeHint;
532 	BYTE Location;
533 	BYTE WitheldBlockCount;
534 	HEAP_LFH_SUBSEGMENT_ENCODED_OFFSETS BlockOffsets;
535 	BYTE CommitUnitShift;
536 	BYTE CommitUnitCount;
537 	UINT16 CommitStateOffset;
538 	WPARAM BlockBitmap[1];
539 } HEAP_LFH_SUBSEGMENT, *PHEAP_LFH_SUBSEGMENT;
540 
541 typedef struct _HEAP_LARGE_ALLOC_DATA {
542 	RTL_BALANCED_NODE TreeNode;
543 	union {
544 		WPARAM VirtualAddess;
545 		UINT16 UnusedBytes;
546 	};
547 	union {
548 		UINT64 BitMask;
549 		union {
550 			bool ExtraPresent : 1;
551 			bool GuardPageCount : 1;
552 			UINT8 GuardPageAlignment : 6;
553 			UINT8 Spare : 4;
554 			UINT64 AllocatedPages : 52;
555 		};
556 	};
557 } HEAP_LARGE_ALLOC_DATA, *PHEAP_LARGE_ALLOC_DATA;
558 
559 typedef struct _HEAP_OPPORTUNISTIC_LARGE_PAGE_STATS {
560 	WPARAM SmallPagesInUseWithinLarge;
561 	WPARAM OpportunisticLargePageCount;
562 } HEAP_OPPORTUNISTIC_LARGE_PAGE_STATS, *PHEAP_OPPORTUNISTIC_LARGE_PAGE_STATS;
563 
564 typedef struct _HEAP_RUNTIME_MEMORY_STATS {
565 	WPARAM TotalReservedPages;
566 	WPARAM TotalCommittedPages;
567 	WPARAM FreeCommittedPages;
568 	WPARAM LfhFreeCommittedPages;
569 	HEAP_OPPORTUNISTIC_LARGE_PAGE_STATS LargePageStats[2];
570 	RTL_HP_SEG_ALLOC_POLICY LargePageUtilizationPolicy;
571 } HEAP_RUNTIME_MEMORY_STATS, *PHEAP_RUNTIME_MEMORY_STATS;
572 
573 typedef struct _HEAP_SEG_CONTEXT {
574 	UINT64 SegmentMask;
575 	BYTE UnitShift;
576 	BYTE PagesPerUnitShift;
577 	BYTE FirstDescriptorIndex;
578 	BYTE CachedCommitSoftShift;
579 	BYTE CachedCommitHighShift;
580 	UINT16 Flags;
581 	UINT MaxAllocationSize;
582 	UINT16 OlpStatsOffset;
583 	UINT16 MemStatsOffset;
584 	PVOID LfhContext;
585 	PVOID VsContext;
586 	RTL_HP_ENV_HANDLE EnvHandle;
587 	PVOID Heap;
588 	WPARAM SegmentLock;
589 	LIST_ENTRY SegmentListHead;
590 	WPARAM SegmentCount;
591 	RTL_RB_TREE FreePageRanges;
592 	WPARAM FreeSegmentListLock;
593 	SINGLE_LIST_ENTRY FreeSegmentList[2];
594 	WPARAM Padding[7];
595 } HEAP_SEG_CONTEXT, *PHEAP_SEG_CONTEXT;
596 
597 typedef struct _SEGMENT_HEAP {
598 	RTL_HP_ENV_HANDLE EnvHandle;
599 	ULONG Signature;
600 	ULONG GlobalFlags;
601 	ULONG Interceptor;
602 	USHORT ProcessHeapListIndex;
603 	USHORT AllocatedFromMetadata : 1;
604 	union {
605 		RTL_HEAP_MEMORY_LIMIT_DATA CommitLimitData;
606 		struct {
607 			UINT64 ReservedMustBeZero1;
608 			PVOID UserContext;
609 			PVOID ReservedMustBeZero2;
610 			PVOID Spare;
611 		};
612 	};
613 	RTL_SRWLOCK LargeMetadataLock;
614 	RTL_RB_TREE LargeAllocMetadata; // Tree of HEAP_LARGE_ALLOC_DATA
615 	WPARAM LargeReservedPages;
616 	WPARAM LargeCommittedPages;
617 	RTL_RUN_ONCE StackTraceInitVar;
618 	WPARAM Padding[2];
619 	HEAP_RUNTIME_MEMORY_STATS MemStats;
620 	UINT16 GlobalLockCount;
621 	ULONG GlobalLockOwner;
622 	RTL_SRWLOCK ContextExtendLock;
623 	PUINT8 AllocatedBase;
624 	PUINT8 UncommittedBase;
625 	PUINT8 ReservedLimit;
626 	HEAP_SEG_CONTEXT SegContexts[2];
627 	HEAP_VS_CONTEXT VsContext;
628 	HEAP_LFH_CONTEXT LfhContext;
629 } SEGMENT_HEAP, *PSEGMENT_HEAP;
630 
631 typedef struct _HEAP_SEGMENT {
632 	HEAP_ENTRY Entry;
633 	ULONG32 SegmentSignature;
634 	ULONG32 SegmentFlags;
635 	LIST_ENTRY SegmentListEntry;
636 	PHEAP Heap;
637 	PVOID BaseAddress;
638 	ULONG32 NumberOfPages;
639 #if defined(_M_X64)
640 	UINT8 _PADDING0_[4];
641 #endif
642 	PHEAP_ENTRY FirstEntry;
643 	PHEAP_ENTRY LastValidEntry;
644 	ULONG32 NumberOfUnCommittedPages;
645 	ULONG32 NumberOfUnCommittedRanges;
646 	UINT16 SegmentAllocatorBackTraceIndex;
647 	UINT16 Reserved;
648 #if defined(_M_X64)
649 	UINT8 _PADDING1_[4];
650 #endif
651 	LIST_ENTRY UCRSegmentList;
652 } HEAP_SEGMENT, *PHEAP_SEGMENT;
653 
654 typedef struct _HEAP {
655 	union {
656 		HEAP_SEGMENT Segment;
657 		struct {
658 			HEAP_ENTRY Entry;
659 			ULONG32 SegmentSignature;
660 			ULONG32 SegmentFlags;
661 			LIST_ENTRY SegmentListEntry;
662 			PHEAP Heap;
663 			PVOID BaseAddress;
664 			ULONG32 NumberOfPages;
665 			PHEAP_ENTRY FirstEntry;
666 			PHEAP_ENTRY LastValidEntry;
667 			ULONG32 NumberOfUnCommittedPages;
668 			ULONG32 NumberOfUnCommittedRanges;
669 			UINT16 SegmentAllocatorBackTraceIndex;
670 			UINT16 Reserved;
671 			LIST_ENTRY UCRSegmentList;
672 		};
673 	};
674 	ULONG32 Flags;
675 	ULONG32 ForceFlags;
676 	ULONG32 CompatibilityFlags;
677 	ULONG32 EncodeFlagMask;
678 	HEAP_ENTRY Encoding;
679 	ULONG32 Interceptor;
680 	ULONG32 VirtualMemoryThreshold;
681 	ULONG32 Signature;
682 #if defined(_M_X64)
683 	UINT8 _PADDING0_[4];
684 #endif
685 	WPARAM SegmentReserve;
686 	WPARAM SegmentCommit;
687 	WPARAM DeCommitFreeBlockThreshold;
688 	WPARAM DeCommitTotalFreeThreshold;
689 	WPARAM TotalFreeSize;
690 	WPARAM MaximumAllocationSize;
691 	UINT16 ProcessHeapsListIndex;
692 	UINT16 HeaderValidateLength;
693 #if defined(_M_X64)
694 	UINT8 _PADDING1_[4];
695 #endif
696 	PVOID HeaderValidateCopy;
697 	UINT16 NextAvailableTagIndex;
698 	UINT16 MaximumTagIndex;
699 #if defined(_M_X64)
700 	UINT8 _PADDING2_[4];
701 #endif
702 	PHEAP_TAG_ENTRY TagEntries;
703 	LIST_ENTRY UCRList;
704 	WPARAM AlignRound;
705 	WPARAM AlignMask;
706 	LIST_ENTRY VirtualAllocdBlocks;
707 	LIST_ENTRY SegmentList;
708 	UINT16 AllocatorBackTraceIndex;
709 	UINT8 _PADDING03_[2];
710 	ULONG32 NonDedicatedListLength;
711 	PVOID BlocksIndex;
712 	PVOID UCRIndex;
713 	PHEAP_PSEUDO_TAG_ENTRY PseudoTagEntries;
714 	LIST_ENTRY FreeLists;
715 	PHEAP_LOCK LockVariable;
716 	LONG32 (WINAPI * CommitRoutine) (PVOID, PVOID *, WPARAM *);
717 	RTL_RUN_ONCE StackTraceInitVar;
718 	RTL_HEAP_MEMORY_LIMIT_DATA CommitLimitData;
719 	PVOID FrontEndHeap;
720 	UINT16 FrontHeapLockCount;
721 	UINT8 FrontEndHeapType;
722 	UINT8 RequestedFrontEndHeapType;
723 #if defined(_M_X64)
724 	UINT8 _PADDING4_[4];
725 #endif
726 	PUINT16 FrontEndHeapUsageData;
727 	UINT16 FrontEndHeapMaximumIndex;
728 #if defined(_M_X64)
729 	UINT8 FrontEndHeapStatusBitmap[129];
730 #else
731 	UINT8 FrontEndHeapStatusBitmap[257];
732 #endif
733 #if defined(_M_X64)
734 	UINT8 _PADDING5_[5];
735 #else
736 	UINT8 _PADDING1_[1];
737 #endif
738 	HEAP_COUNTERS Counters;
739 	HEAP_TUNING_PARAMETERS TuningParameters;
740 } HEAP, *PHEAP;
741 
742 typedef struct _HEAP_ENTRY_EXTRA {
743 	union {
744 		struct {
745 			UINT16 AllocatorBackTraceIndex;
746 			UINT16 TagIndex;
747 #if defined(_M_X64)
748 			UINT8 _PADDING0_[4];
749 #endif
750 			WPARAM Settable;
751 		};
752 #if defined(_M_X64)
753 		struct {
754 			UINT64 ZeroInit;
755 			UINT64 ZeroInit1;
756 		};
757 #else
758 		UINT64 ZeroInit;
759 #endif
760 	};
761 } HEAP_ENTRY_EXTRA, *PHEAP_ENTRY_EXTRA;
762 
763 typedef struct _HEAP_VIRTUAL_ALLOC_ENTRY {
764 	LIST_ENTRY Entry;
765 	HEAP_ENTRY_EXTRA ExtraStuff;
766 	WPARAM CommitSize;
767 	WPARAM ReserveSize;
768 	HEAP_ENTRY BusyBlock;
769 } HEAP_VIRTUAL_ALLOC_ENTRY, *PHEAP_VIRTUAL_ALLOC_ENTRY;
770 
771 typedef struct _LFH_BLOCK_ZONE {
772 	LIST_ENTRY ListEntry;
773 	LONG NextIndex;
774 	/*	// Win 7
775 	PVOID FreePointer;
776 	PVOID Limit;
777 	*/
778 } LFH_BLOCK_ZONE, *PLFH_BLOCK_ZONE;
779 
780 typedef struct _HEAP_USERDATA_OFFSETS {
781 	union {
782 		UINT32 StrideAndOffset;
783 		struct {
784 			UINT16 FirstAllocationOffset;
785 			UINT16 BlockStride;
786 		};
787 	};
788 } HEAP_USERDATA_OFFSETS, *PHEAP_USERDATA_OFFSETS;
789 
790 typedef struct _RTL_BITMAP_EX {
791 	WPARAM SizeOfBitMap;
792 	WPARAM *Buffer;
793 } RTL_BITMAP_EX, *PRTL_BITMAP_EX;
794 
795 typedef struct _HEAP_USERDATA_HEADER {
796 	union {
797 		SINGLE_LIST_ENTRY SFreeListEntry;
798 		PHEAP_SUBSEGMENT SubSegment;
799 	};
800 	PVOID Reserved;
801 	union {
802 		UINT32 SizeIndexAndPadding;
803 		struct {
804 			UCHAR SizeIndex;
805 			UCHAR GuardPagePresent;
806 			UINT16 PaddingBytes;
807 		};
808 	};
809 	ULONG Signature;
810 	HEAP_USERDATA_OFFSETS EncodedOffsets;
811 	RTL_BITMAP_EX BusyBitmap;
812 	WPARAM BitmapData;
813 } HEAP_USERDATA_HEADER, *PHEAP_USERDATA_HEADER;
814 
815 
816 typedef struct _HEAP_SUBSEGMENT *PHEAP_SUBSEGMENT;
817 typedef struct _HEAP_LOCAL_SEGMENT_INFO {
818 	PHEAP_LOCAL_DATA LocalData;
819 	PHEAP_SUBSEGMENT ActiveSubsegment;
820 	PHEAP_SUBSEGMENT CachedItems[16];
821 	SLIST_HEADER SListHeader;
822 	HEAP_BUCKET_COUNTERS Counters;
823 	ULONG LastOpSequence;
824 	UINT16 BucketIndex;
825 	UINT16 LastUsed;
826 	UINT16 NoThrashCount;
827 } HEAP_LOCAL_SEGMENT_INFO, *PHEAP_LOCAL_SEGMENT_INFO;
828 
829 typedef struct _HEAP_SUBSEGMENT {
830 	PHEAP_LOCAL_SEGMENT_INFO LocalInfo;
831 	PHEAP_USERDATA_HEADER UserBlocks;
832 	SLIST_HEADER DelayFreeList;
833 	INTERLOCK_SEQ AggregateExchg;
834 	union {
835 		struct {
836 			WORD BlockSize;
837 			WORD Flags;
838 			WORD BlockCount;
839 			UINT8 SizeIndex;
840 			UINT8 AffinityIndex;
841 		};
842 		ULONG Alignment[2];
843 	};
844 	ULONG Lock;
845 	SINGLE_LIST_ENTRY SFreeListEntry;
846 } HEAP_SUBSEGMENT, *PHEAP_SUBSEGMENT;
847 
848 typedef struct _HEAP_LFH_MEM_POLICIES {
849 	union {
850 		ULONG AllPolicies;
851 		union {
852 			UINT8 DisableAffinity : 1;
853 			UINT8 SlowSubsegmentGrowth : 1;
854 			ULONG Spare : 30;
855 		};
856 	};
857 } HEAP_LFH_MEM_POLICIES, *PHEAP_LFH_MEM_POLICIES;
858 
859 typedef struct _HEAP_LOCAL_DATA {
860 	SLIST_HEADER DeletedSubSegments;
861 	PLFH_BLOCK_ZONE CrtZone;
862 	PLFH_HEAP LowFragHeap;
863 	ULONG Sequence;
864 	//HEAP_LOCAL_SEGMENT_INFO SegmentInfo[128]; // Only on Win7
865 } HEAP_LOCAL_DATA, *PHEAP_LOCAL_DATA;
866 
867 typedef struct _HEAP_BUCKET {
868 	WORD BlockUnits;
869 	UINT8 SizeIndex;
870 	union {
871 		BYTE Flags;
872 		union {
873 			BYTE UseAffinity : 1;
874 			BYTE DebugFlags : 2;
875 		};
876 	};
877 } HEAP_BUCKET, *PHEAP_BUCKET;
878 
879 typedef struct _HEAP_BUCKET_RUN_INFO {
880 	union {
881 		struct {
882 			ULONG Bucket;
883 			ULONG RunLength;
884 		};
885 		UINT64 Aggregate64;
886 	};
887 } HEAP_BUCKET_RUN_INFO, *PHEAP_BUCKET_RUN_INFO;
888 
889 typedef struct _USER_MEMORY_CACHE_ENTRY {
890 	SLIST_HEADER UserBlocks;
891 	ULONG AvailableBlocks;
892 	ULONG MinimumDepth;
893 	ULONG CacheShiftThreshold;
894 	USHORT Allocations;
895 	USHORT Frees;
896 	USHORT CacheHits;
897 } USER_MEMORY_CACHE_ENTRY, *PUSER_MEMORY_CACHE_ENTRY;
898 
899 typedef struct _LFH_HEAP {
900 	RTL_SRWLOCK Lock;
901 	LIST_ENTRY SubSegmentZones;
902 	PVOID Heap;
903 	PVOID NextSegmentInfoArrayAddress;
904 	PVOID FirstUncommittedAddress;
905 	PVOID ReservedAddressLimit;
906 	ULONG SegmentCreate;
907 	ULONG SegmentDelete;
908 	ULONG MinimumCacheDepth;
909 	ULONG CacheShiftThreshold;
910 	WPARAM SizeInCache;
911 	HEAP_BUCKET_RUN_INFO RunInfo;
912 	USER_MEMORY_CACHE_ENTRY UserBlockCache[12];
913 	HEAP_LFH_MEM_POLICIES MemoryPolicies;
914 	HEAP_BUCKET Buckets[129];
915 	PHEAP_LOCAL_SEGMENT_INFO SegmentInfoArrays[129];
916 	PHEAP_LOCAL_SEGMENT_INFO AffinitizedInfoArrays[129];
917 	PSEGMENT_HEAP SegmentAllocator;
918 	HEAP_LOCAL_DATA LocalData[1];
919 } LFH_HEAP, *PLFH_HEAP;
920 
921 typedef struct _HeapBlockBasicInfo {
922 	WPARAM size;
923 	WPARAM flags;
924 	WPARAM extra;
925 	WPARAM address;
926 } HeapBlockBasicInfo, *PHeapBlockBasicInfo;
927 
928 typedef struct _HeapBlockExtraInfo { // think of extra stuff to put here
929 	WPARAM heap;
930 	WPARAM segment;
931 	WPARAM unusedBytes;
932 	USHORT granularity;
933 } HeapBlockExtraInfo, *PHeapBlockExtraInfo;
934 
935 typedef struct _HeapBlock {
936 	ULONG_PTR dwAddress;
937 	SIZE_T dwSize;
938 	DWORD dwFlags;
939 	SIZE_T index;
940 	PHeapBlockExtraInfo extraInfo;
941 } HeapBlock, *PHeapBlock;
942 
943 typedef struct _DEBUG_BUFFER {
944 	HANDLE SectionHandle;
945 	PVOID SectionBase;
946 	PVOID RemoteSectionBase;
947 	WPARAM SectionBaseDelta;
948 	HANDLE EventPairHandle;
949 	HANDLE RemoteEventPairHandle;
950 	HANDLE RemoteProcessId;
951 	HANDLE RemoteThreadHandle;
952 	ULONG InfoClassMask;
953 	SIZE_T SizeOfInfo;
954 	SIZE_T AllocatedSize;
955 	SIZE_T SectionSize;
956 	PVOID ModuleInformation;
957 	PVOID BackTraceInformation;
958 	PVOID HeapInformation;
959 	PVOID LockInformation;
960 	PVOID SpecificHeap;
961 	HANDLE RemoteProcessHandle;
962 	PVOID VerifierOptions;
963 	PVOID ProcessHeap;
964 	HANDLE CriticalSectionHandle;
965 	HANDLE CriticalSectionOwnerThread;
966 	PVOID Reserved[4];
967 } DEBUG_BUFFER, *PDEBUG_BUFFER;
968 
969 
970 typedef struct _DEBUG_HEAP_INFORMATION {
971 	PVOID Base;
972 	DWORD Flags;
973 	USHORT Granularity;
974 	USHORT CreatorBackTraceIndex;
975 	SIZE_T Allocated;
976 	SIZE_T Committed;
977 	DWORD TagCount;
978 	DWORD BlockCount;
979 	DWORD PseudoTagCount;
980 	DWORD PseudoTagGranularity;
981 	DWORD Reserved[5];
982 	PVOID Tags;
983 	PVOID Blocks;
984 } DEBUG_HEAP_INFORMATION, *PDEBUG_HEAP_INFORMATION;
985 
986 typedef struct _HeapInformation {
987 	DWORD count;
988 	DEBUG_HEAP_INFORMATION heaps[/* count */];
989 } HeapInformation, *PHeapInformation;
990 
991 PDEBUG_BUFFER (NTAPI *RtlCreateQueryDebugBuffer)(
992 	IN DWORD Size,
993 	IN BOOLEAN EventPair
994 );
995 
996 NTSTATUS (NTAPI *RtlQueryProcessDebugInformation)(
997 	IN DWORD ProcessId,
998 	IN DWORD DebugInfoClassMask,
999 	IN OUT PDEBUG_BUFFER DebugBuffer
1000 );
1001 
1002 NTSTATUS (NTAPI *RtlDestroyQueryDebugBuffer)(
1003 	IN PDEBUG_BUFFER DebugBuffer
1004 );
1005 
1006 __kernel_entry NTSTATUS (NTAPI *w32_NtQueryInformationProcess)(
1007   IN HANDLE           ProcessHandle,
1008   IN PROCESSINFOCLASS ProcessInformationClass,
1009   OUT PVOID           ProcessInformation,
1010   IN ULONG            ProcessInformationLength,
1011   OUT PULONG          ReturnLength
1012 );
1013 #endif