00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
#ifndef _RTL_HEAP_
00026
#define _RTL_HEAP_
00027
00028 #define HEAP_LARGE_TAG_MASK 0xFF000000
00029
00030 #define ROUND_UP_TO_POWER2( x, n ) (((ULONG_PTR)(x) + ((n)-1)) & ~((ULONG_PTR)(n)-1))
00031 #define ROUND_DOWN_TO_POWER2( x, n ) ((ULONG_PTR)(x) & ~((ULONG_PTR)(n)-1))
00032
00033 typedef struct _HEAP_ENTRY {
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 USHORT Size;
00046
00047
00048
00049
00050
00051
00052
00053 USHORT PreviousSize;
00054
00055
00056
00057
00058
00059
00060 UCHAR
SegmentIndex;
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 UCHAR
Flags;
00077
00078
00079
00080
00081
00082
00083
00084
00085 UCHAR
UnusedBytes;
00086
00087
00088
00089
00090
00091 UCHAR
SmallTagIndex;
00092
00093
#if defined(_WIN64)
00094
ULONGLONG
Reserved1;
00095
#endif
00096
00097 }
HEAP_ENTRY, *
PHEAP_ENTRY;
00098
00099
00100
00101
00102
00103
00104
00105 typedef struct _HEAP_ENTRY_EXTRA {
00106
union {
00107
struct {
00108
00109
00110
00111
00112
00113 USHORT AllocatorBackTraceIndex;
00114
00115
00116
00117
00118
00119
00120
00121 USHORT TagIndex;
00122
00123
00124
00125
00126
00127
00128 ULONG_PTR
Settable;
00129 };
00130
#if defined(_WIN64)
00131
struct {
00132 ULONGLONG ZeroInit;
00133 ULONGLONG ZeroInit1;
00134 };
00135
#else
00136 ULONGLONG
ZeroInit;
00137
#endif
00138
};
00139 }
HEAP_ENTRY_EXTRA, *
PHEAP_ENTRY_EXTRA;
00140
00141
00142
00143
00144
00145
00146
00147
00148 typedef struct _HEAP_FREE_ENTRY_EXTRA {
00149 USHORT TagIndex;
00150 USHORT FreeBackTraceIndex;
00151 }
HEAP_FREE_ENTRY_EXTRA, *
PHEAP_FREE_ENTRY_EXTRA;
00152
00153
00154
00155
00156
00157
00158
00159 typedef struct _HEAP_VIRTUAL_ALLOC_ENTRY {
00160 LIST_ENTRY
Entry;
00161 HEAP_ENTRY_EXTRA ExtraStuff;
00162 SIZE_T
CommitSize;
00163 SIZE_T
ReserveSize;
00164 HEAP_ENTRY BusyBlock;
00165 }
HEAP_VIRTUAL_ALLOC_ENTRY, *
PHEAP_VIRTUAL_ALLOC_ENTRY;
00166
00167 typedef struct _HEAP_FREE_ENTRY {
00168
00169
00170
00171
00172
00173
00174 USHORT Size;
00175
00176
00177
00178
00179
00180
00181
00182 USHORT PreviousSize;
00183
00184
00185
00186
00187
00188
00189 UCHAR
SegmentIndex;
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 UCHAR
Flags;
00201
00202
00203
00204
00205
00206
00207 UCHAR
Index;
00208 UCHAR
Mask;
00209
00210
00211
00212
00213
00214 LIST_ENTRY
FreeList;
00215
00216
#if defined(_WIN64)
00217
ULONGLONG
Reserved1;
00218
#endif
00219
00220 }
HEAP_FREE_ENTRY, *
PHEAP_FREE_ENTRY;
00221
00222
00223
00224 #define HEAP_GRANULARITY ((LONG) sizeof( HEAP_ENTRY ))
00225
#if defined(_WIN64)
00226
#define HEAP_GRANULARITY_SHIFT 4 // Log2( HEAP_GRANULARITY )
00227
#else
00228 #define HEAP_GRANULARITY_SHIFT 3 // Log2( HEAP_GRANULARITY )
00229
#endif
00230
00231 #define HEAP_MAXIMUM_BLOCK_SIZE (USHORT)(((0x10000 << HEAP_GRANULARITY_SHIFT) - PAGE_SIZE) >> HEAP_GRANULARITY_SHIFT)
00232
00233 #define HEAP_MAXIMUM_FREELISTS 128
00234 #define HEAP_MAXIMUM_SEGMENTS 64
00235
00236 #define HEAP_ENTRY_BUSY 0x01
00237 #define HEAP_ENTRY_EXTRA_PRESENT 0x02
00238 #define HEAP_ENTRY_FILL_PATTERN 0x04
00239 #define HEAP_ENTRY_VIRTUAL_ALLOC 0x08
00240 #define HEAP_ENTRY_LAST_ENTRY 0x10
00241 #define HEAP_ENTRY_SETTABLE_FLAG1 0x20
00242 #define HEAP_ENTRY_SETTABLE_FLAG2 0x40
00243 #define HEAP_ENTRY_SETTABLE_FLAG3 0x80
00244 #define HEAP_ENTRY_SETTABLE_FLAGS 0xE0
00245
00246
00247
00248
00249
00250
00251
00252 typedef struct _HEAP_UNCOMMMTTED_RANGE {
00253 struct _HEAP_UNCOMMMTTED_RANGE *
Next;
00254 ULONG_PTR
Address;
00255 SIZE_T
Size;
00256 ULONG
filler;
00257 }
HEAP_UNCOMMMTTED_RANGE, *
PHEAP_UNCOMMMTTED_RANGE;
00258
00259 typedef struct _HEAP_SEGMENT {
00260 HEAP_ENTRY Entry;
00261
00262 ULONG
Signature;
00263 ULONG
Flags;
00264 struct _HEAP *
Heap;
00265 SIZE_T
LargestUnCommittedRange;
00266
00267 PVOID
BaseAddress;
00268 ULONG
NumberOfPages;
00269 PHEAP_ENTRY FirstEntry;
00270 PHEAP_ENTRY LastValidEntry;
00271
00272 ULONG
NumberOfUnCommittedPages;
00273 ULONG
NumberOfUnCommittedRanges;
00274 PHEAP_UNCOMMMTTED_RANGE UnCommittedRanges;
00275 USHORT AllocatorBackTraceIndex;
00276 USHORT Reserved;
00277 PHEAP_ENTRY LastEntryInSegment;
00278 }
HEAP_SEGMENT, *
PHEAP_SEGMENT;
00279
00280 #define HEAP_SEGMENT_SIGNATURE 0xFFEEFFEE
00281 #define HEAP_SEGMENT_USER_ALLOCATED (ULONG)0x00000001
00282
00283
00284
00285
00286
00287 typedef struct _HEAP_LOCK {
00288
union {
00289 RTL_CRITICAL_SECTION
CriticalSection;
00290 ERESOURCE Resource;
00291 } Lock;
00292 }
HEAP_LOCK, *
PHEAP_LOCK;
00293
00294 typedef struct _HEAP_UCR_SEGMENT {
00295 struct _HEAP_UCR_SEGMENT *
Next;
00296 SIZE_T
ReservedSize;
00297 SIZE_T
CommittedSize;
00298 ULONG
filler;
00299 }
HEAP_UCR_SEGMENT, *
PHEAP_UCR_SEGMENT;
00300
00301
00302 typedef struct _HEAP_TAG_ENTRY {
00303 ULONG
Allocs;
00304 ULONG
Frees;
00305 SIZE_T
Size;
00306 USHORT TagIndex;
00307 USHORT CreatorBackTraceIndex;
00308 WCHAR
TagName[ 24 ];
00309 }
HEAP_TAG_ENTRY, *
PHEAP_TAG_ENTRY;
00310
00311 typedef struct _HEAP_PSEUDO_TAG_ENTRY {
00312 ULONG
Allocs;
00313 ULONG
Frees;
00314 SIZE_T
Size;
00315 }
HEAP_PSEUDO_TAG_ENTRY, *
PHEAP_PSEUDO_TAG_ENTRY;
00316
00317
00318 typedef struct _HEAP {
00319 HEAP_ENTRY Entry;
00320
00321 ULONG
Signature;
00322 ULONG
Flags;
00323 ULONG
ForceFlags;
00324 ULONG
VirtualMemoryThreshold;
00325
00326 SIZE_T
SegmentReserve;
00327 SIZE_T
SegmentCommit;
00328 SIZE_T
DeCommitFreeBlockThreshold;
00329 SIZE_T
DeCommitTotalFreeThreshold;
00330
00331 SIZE_T
TotalFreeSize;
00332 SIZE_T
MaximumAllocationSize;
00333 USHORT ProcessHeapsListIndex;
00334 USHORT HeaderValidateLength;
00335 PVOID
HeaderValidateCopy;
00336
00337 USHORT NextAvailableTagIndex;
00338 USHORT MaximumTagIndex;
00339 PHEAP_TAG_ENTRY TagEntries;
00340 PHEAP_UCR_SEGMENT UCRSegments;
00341 PHEAP_UNCOMMMTTED_RANGE UnusedUnCommittedRanges;
00342
00343
00344
00345
00346
00347
00348
00349
00350 ULONG
AlignRound;
00351 ULONG
AlignMask;
00352
00353 LIST_ENTRY
VirtualAllocdBlocks;
00354
00355 PHEAP_SEGMENT Segments[
HEAP_MAXIMUM_SEGMENTS ];
00356
00357
union {
00358 ULONG
FreeListsInUseUlong[
HEAP_MAXIMUM_FREELISTS / 32 ];
00359 UCHAR
FreeListsInUseBytes[
HEAP_MAXIMUM_FREELISTS / 8 ];
00360 } u;
00361
00362 USHORT FreeListsInUseTerminate;
00363 USHORT AllocatorBackTraceIndex;
00364 ULONG
Reserved1[2];
00365 PHEAP_PSEUDO_TAG_ENTRY PseudoTagEntries;
00366
00367 LIST_ENTRY
FreeLists[
HEAP_MAXIMUM_FREELISTS ];
00368
00369 PHEAP_LOCK LockVariable;
00370 PRTL_HEAP_COMMIT_ROUTINE
CommitRoutine;
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382 PVOID
Lookaside;
00383 ULONG
LookasideLockCount;
00384
00385 }
HEAP, *
PHEAP;
00386
00387 #define HEAP_SIGNATURE (ULONG)0xEEFFEEFF
00388 #define HEAP_LOCK_USER_ALLOCATED (ULONG)0x80000000
00389 #define HEAP_VALIDATE_PARAMETERS_ENABLED (ULONG)0x40000000
00390 #define HEAP_VALIDATE_ALL_ENABLED (ULONG)0x20000000
00391 #define HEAP_SKIP_VALIDATION_CHECKS (ULONG)0x10000000
00392 #define HEAP_CAPTURE_STACK_BACKTRACES (ULONG)0x08000000
00393
00394 #define CHECK_HEAP_TAIL_SIZE HEAP_GRANULARITY
00395 #define CHECK_HEAP_TAIL_FILL 0xAB
00396 #define FREE_HEAP_FILL 0xFEEEFEEE
00397 #define ALLOC_HEAP_FILL 0xBAADF00D
00398
00399 #define HEAP_MAXIMUM_SMALL_TAG 0xFF
00400 #define HEAP_SMALL_TAG_MASK (HEAP_MAXIMUM_SMALL_TAG << HEAP_TAG_SHIFT)
00401 #define HEAP_NEED_EXTRA_FLAGS ((HEAP_TAG_MASK ^ HEAP_SMALL_TAG_MASK) | \
00402
HEAP_CAPTURE_STACK_BACKTRACES | \
00403
HEAP_SETTABLE_USER_VALUE \
00404
)
00405 #define HEAP_NUMBER_OF_PSEUDO_TAG (HEAP_MAXIMUM_FREELISTS+1)
00406
00407
00408
#if (HEAP_ENTRY_SETTABLE_FLAG1 ^ \
00409
HEAP_ENTRY_SETTABLE_FLAG2 ^ \
00410
HEAP_ENTRY_SETTABLE_FLAG3 ^ \
00411
HEAP_ENTRY_SETTABLE_FLAGS \
00412
)
00413
#error Invalid HEAP_ENTRY_SETTABLE_FLAGS
00414
#endif
00415
00416
#if ((HEAP_ENTRY_BUSY ^ \
00417
HEAP_ENTRY_EXTRA_PRESENT ^ \
00418
HEAP_ENTRY_FILL_PATTERN ^ \
00419
HEAP_ENTRY_VIRTUAL_ALLOC ^ \
00420
HEAP_ENTRY_LAST_ENTRY ^ \
00421
HEAP_ENTRY_SETTABLE_FLAGS \
00422
) != \
00423
(HEAP_ENTRY_BUSY | \
00424
HEAP_ENTRY_EXTRA_PRESENT | \
00425
HEAP_ENTRY_FILL_PATTERN | \
00426
HEAP_ENTRY_VIRTUAL_ALLOC | \
00427
HEAP_ENTRY_LAST_ENTRY | \
00428
HEAP_ENTRY_SETTABLE_FLAGS \
00429
) \
00430
)
00431
#error Conflicting HEAP_ENTRY flags
00432
#endif
00433
00434
#if ((HEAP_SETTABLE_USER_FLAGS >> 4) ^ HEAP_ENTRY_SETTABLE_FLAGS)
00435
#error HEAP_SETTABLE_USER_FLAGS in ntrtl.h conflicts with HEAP_ENTRY_SETTABLE_FLAGS in heap.h
00436
#endif
00437
00438 typedef struct _HEAP_STOP_ON_TAG {
00439
union {
00440 ULONG
HeapAndTagIndex;
00441
struct {
00442 USHORT TagIndex;
00443 USHORT HeapIndex;
00444 };
00445 };
00446 }
HEAP_STOP_ON_TAG, *
PHEAP_STOP_ON_TAG;
00447
00448 typedef struct _HEAP_STOP_ON_VALUES {
00449 SIZE_T
AllocAddress;
00450 HEAP_STOP_ON_TAG AllocTag;
00451 SIZE_T
ReAllocAddress;
00452 HEAP_STOP_ON_TAG ReAllocTag;
00453 SIZE_T
FreeAddress;
00454 HEAP_STOP_ON_TAG FreeTag;
00455 }
HEAP_STOP_ON_VALUES, *
PHEAP_STOP_ON_VALUES;
00456
00457
#ifndef NTOS_KERNEL_RUNTIME
00458
00459 extern BOOLEAN
RtlpDebugHeap;
00460 extern BOOLEAN
RtlpValidateHeapHdrsEnable;
00461 extern BOOLEAN
RtlpValidateHeapTagsEnable;
00462 extern PHEAP RtlpGlobalTagHeap;
00463 extern HEAP_STOP_ON_VALUES RtlpHeapStopOn;
00464
00465 BOOLEAN
00466
RtlpHeapIsLocked(
00467 IN PVOID HeapHandle
00468 );
00469
00470
00471
00472
00473
00474
#include <heappage.h>
00475
00476
#endif // NTOS_KERNEL_RUNTIME
00477
00478
#endif // _RTL_HEAP_