33 8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
34 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
35 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
36 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
37 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
38 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
39 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
40 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
41 7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
42 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
43 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
44 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
45 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
46 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
47 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
48 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
64 if ((Bits >> 16) & 0xFF)
116 SIZE_T DeCommitFreeBlockThreshold;
156 Heap->Entry.SmallTagIndex =
LOBYTE(Heap->Entry.Size) ^
HIBYTE(Heap->Entry.Size) ^ Heap->Entry.Flags;
157 Heap->Entry.PreviousSize = 0;
158 Heap->Entry.SegmentOffset = 0;
159 Heap->Entry.UnusedBytes = 0;
176 Heap->SegmentReserve =
Parameters->SegmentReserve;
177 Heap->SegmentCommit =
Parameters->SegmentCommit;
178 Heap->DeCommitFreeBlockThreshold = DeCommitFreeBlockThreshold;
180 Heap->MaximumAllocationSize =
Parameters->MaximumAllocationSize;
181 Heap->CommitRoutine =
Parameters->CommitRoutine;
184 Heap->HeaderValidateCopy =
NULL;
185 Heap->HeaderValidateLength = (
USHORT)HeaderSize;
194 Heap->LockVariable =
Lock;
199 Heap->AlignMask = (
ULONG) ~15;
205 Heap->AlignRound = 2 *
sizeof(
HEAP_ENTRY) - 1;
218 (
PULONG)&Heap->FreeHints[DeCommitFreeBlockThreshold],
219 DeCommitFreeBlockThreshold);
221 RtlZeroMemory(&Heap->FreeHints[0],
sizeof(Heap->FreeHints[0]) * DeCommitFreeBlockThreshold);
245 ASSERT(FreeEntry->Size == BlockSize);
275 if (ListEntry ==
NULL)
291 if (PreviousEntry->Size >= BlockSize)
293 DPRINT(
"Inserting size %lu before %lu.\n", BlockSize, PreviousEntry->Size);
297 ListEntry = ListEntry->
Flink;
335 ASSERT(NextHintIndex != 0xFFFFFFFF);
336 if ((NextHintIndex == 0) || (NextHintIndex >
HintIndex))
367 DPRINT(
"RtlpInsertFreeBlock(%p %p %x)\n", Heap, FreeEntry, BlockSize);
373 LastEntry = FreeEntry;
374 Flags = FreeEntry->Flags;
375 PreviousSize = FreeEntry->PreviousSize;
376 SegmentOffset = FreeEntry->SegmentOffset;
391 FreeEntry->Flags = 0;
396 FreeEntry->Flags =
Flags;
400 FreeEntry->Size =
Size;
401 FreeEntry->PreviousSize = PreviousSize;
402 FreeEntry->SegmentOffset = SegmentOffset;
412 LastEntry = FreeEntry;
424 FreeEntry->PreviousSize = PreviousSize;
440 ASSERT(FreeEntry->Size != 0);
463 if ((
HintIndex != 0) && (NewHintEntry->Size != FreeEntry->Size))
466 ASSERT(NewHintEntry->Size > FreeEntry->Size);
472 if (NewHintEntry !=
NULL)
505 DPRINT1(
"Free heap block %p modified at %p after it was freed\n",
522 return VirtualEntry->
CommitSize - HeapEntry->Size;
551 (
PVOID *)&UcrSegment,
561 (
PVOID *)&UcrSegment,
571 (
PVOID *)&UcrSegment,
592 (
PVOID *)&UcrDescriptor,
617 return UcrDescriptor;
626 UcrDescriptor->
Size = 0;
644 Current =
Segment->UCRSegmentList.Flink;
645 while (Current != &
Segment->UCRSegmentList)
670 Current = Current->
Flink;
676 Segment->NumberOfUnCommittedRanges--;
681 Current = Current->
Flink;
687 if (!UcrDescriptor)
return;
698 Segment->NumberOfUnCommittedRanges++;
706 PVOID AddressRequested)
711 DPRINT(
"RtlpFindAndCommitPages(%p %p %Ix %p)\n", Heap,
Segment, *
Size, AddressRequested);
714 Current =
Segment->UCRSegmentList.Flink;
715 while (Current != &
Segment->UCRSegmentList)
721 (UcrDescriptor->
Address == AddressRequested || !AddressRequested))
746 DPRINT1(
"Committing page failed with status 0x%08X\n",
Status);
761 ASSERT(GuardEntry->Size == 1);
764 if (GuardEntry->PreviousSize == 1)
771 ASSERT(GuardEntry->Size == 1);
781 FreeEntry = GuardEntry;
786 DPRINT(
"Updating UcrDescriptor %p, new Address %p, size %lu\n",
787 UcrDescriptor, UcrDescriptor->
Address, UcrDescriptor->
Size);
790 if (UcrDescriptor->
Size == 0)
796 ASSERT((FreeEntry + FreeEntry->Size) == UcrDescriptor->
Address);
811 ASSERT(NextEntry->PreviousSize == 0);
812 ASSERT(NextEntry == FreeEntry + FreeEntry->Size);
813 NextEntry->PreviousSize = FreeEntry->Size;
820 Segment->NumberOfUnCommittedRanges--;
826 ASSERT(GuardEntry == FreeEntry + FreeEntry->Size);
828 GuardEntry->Size = 1;
829 GuardEntry->PreviousSize = FreeEntry->Size;
830 GuardEntry->SegmentOffset = FreeEntry->SegmentOffset;
831 DPRINT(
"Setting %p as UCR guard entry.\n", GuardEntry);
839 Current = Current->
Flink;
854 SIZE_T PrecedingSize, DecommitSize;
858 DPRINT(
"Decommitting %p %p %x\n", Heap, FreeEntry,
Size);
875 if (PrecedingSize == 0)
904 if (DecommitEnd <= DecommitBase)
911 DecommitSize = DecommitEnd - DecommitBase;
917 DPRINT1(
"HEAP: Failed to create UCR descriptor\n");
924 (
PVOID *)&DecommitBase,
927 ASSERT((DecommitBase + DecommitSize) == DecommitEnd);
944 GuardEntry->Size = 1;
946 GuardEntry->SegmentOffset = FreeEntry->SegmentOffset;
947 DPRINT(
"Setting %p as UCR guard entry.\n", GuardEntry);
951 switch (PrecedingSize)
955 GuardEntry->PreviousSize = 1;
957 GuardEntry->Size = 1;
959 GuardEntry->SegmentOffset = FreeEntry->SegmentOffset;
964 GuardEntry->PreviousSize = FreeEntry->PreviousSize;
968 GuardEntry->PreviousSize = PrecedingSize;
969 FreeEntry->Size = PrecedingSize;
970 FreeEntry->Flags &= ~HEAP_ENTRY_LAST_ENTRY;
991 NextFreeEntry->Flags = 0;
992 NextFreeEntry->PreviousSize = 0;
993 NextFreeEntry->SegmentOffset =
Segment->Entry.SegmentOffset;
994 NextFreeEntry->Size = (
USHORT)NextSize;
996 NextEntry->PreviousSize = NextSize;
1008 NextEntry->PreviousSize = 0;
1027 ASSERT(SegmentReserve >= SegmentCommit);
1030 DPRINT(
"RtlpInitializeHeapSegment(%p %p %x %x %lx %lx)\n", Heap,
Segment, SegmentIndex, SegmentFlags, SegmentReserve, SegmentCommit);
1038 Segment->Entry.PreviousSize = 0;
1039 Segment->Entry.SegmentOffset = SegmentIndex;
1040 Segment->Entry.UnusedBytes = 0;
1048 Segment->SegmentFlags = SegmentFlags;
1050 Heap->Segments[SegmentIndex] =
Segment;
1062 Segment->NumberOfUnCommittedRanges = 0;
1072 if (
Segment->NumberOfUnCommittedPages != 0)
1079 GuardEntry->Size = 1;
1081 GuardEntry->SegmentOffset = SegmentIndex;
1082 PreviousSize = GuardEntry -
Segment->FirstEntry;
1085 switch (PreviousSize)
1088 GuardEntry->PreviousSize = PreviousSize;
1092 GuardEntry->Size = 1;
1094 GuardEntry->SegmentOffset = SegmentIndex;
1095 DPRINT1(
"Setting %p as UCR guard entry.\n", GuardEntry);
1099 GuardEntry->PreviousSize =
Segment->Entry.Size;
1103 FreeEntry =
Segment->FirstEntry;
1104 FreeEntry->PreviousSize =
Segment->Entry.Size;
1105 FreeEntry->SegmentOffset = SegmentIndex;
1106 FreeEntry->Size = PreviousSize;
1107 FreeEntry->Flags = 0;
1111 GuardEntry->PreviousSize = FreeEntry->Size;
1118 FreeEntry =
Segment->FirstEntry;
1119 FreeEntry->PreviousSize =
Segment->Entry.Size;
1120 FreeEntry->SegmentOffset = SegmentIndex;
1130 if (
Segment->NumberOfUnCommittedPages != 0)
1157 DPRINT1(
"HEAP: Failed to release segment's memory with status 0x%08X\n",
Status);
1175 UCHAR SegmentOffset;
1181 if (CurrentEntry != FreeEntry &&
1185 ASSERT(FreeEntry->PreviousSize == CurrentEntry->Size);
1204 FreeEntry = CurrentEntry;
1205 *FreeSize = *FreeSize + CurrentEntry->Size;
1207 FreeEntry->Size = (
USHORT)(*FreeSize);
1216 SegmentOffset = FreeEntry->SegmentOffset;
1229 ASSERT(*FreeSize == NextEntry->PreviousSize);
1245 *FreeSize = *FreeSize + NextEntry->Size;
1247 FreeEntry->Size = (
USHORT)(*FreeSize);
1256 SegmentOffset = FreeEntry->SegmentOffset;
1276 DPRINT(
"RtlpExtendHeap(%p %x)\n", Heap,
Size);
1281 DPRINT(
"Pages %x, FreeSize %x. Going through segments...\n", Pages, FreeSize);
1293 Pages <= Segment->NumberOfUnCommittedPages)
1295 DPRINT(
"This segment is suitable\n");
1403 FreeEntry->Size >=
Size)
1436 ULONG HeapSegmentFlags = 0;
1444 if (Heap)
return Heap;
1450 DPRINT1(
"Enabling page heap failed\n");
1507 sizeof(SystemInformation),
1512 DPRINT1(
"Getting max usermode address failed with status 0x%08x\n",
Status);
1525 Parameters->VirtualMemoryThreshold > MaxBlockSize)
1527 Parameters->VirtualMemoryThreshold = MaxBlockSize;
1532 DPRINT1(
"WARNING: Ignoring DeCommitFreeBlockThreshold %lx, setting it to PAGE_SIZE.\n",
1581 CommittedAddress = Addr;
1600 DPRINT1(
"Querying amount of user supplied memory failed with status 0x%08X\n",
Status);
1612 CommittedAddress = Addr;
1644 UncommittedAddress = Addr;
1667 DPRINT1(
"Failed to reserve memory with status 0x%08x\n",
Status);
1672 CommittedAddress = Heap;
1673 UncommittedAddress = Heap;
1677 if (CommittedAddress == UncommittedAddress)
1718 DPRINT1(
"Failed to initialize heap segment (%x)\n",
Status);
1722 DPRINT(
"Created heap %p, CommitSize %x, ReserveSize %x\n", Heap,
CommitSize, TotalSize);
1759 if (!HeapPtr)
return NULL;
1780 Current = Current->
Flink;
1813 Current = Current->
Flink;
1847 UCHAR SegmentOffset;
1865 FreeFlags = FreeBlock->Flags;
1870 InUseEntry->Flags = EntryFlags;
1871 InUseEntry->SmallTagIndex = 0;
1874 FreeSize = InUseEntry->Size -
Index;
1889 InUseEntry->UnusedBytes +=
sizeof(
HEAP_ENTRY);
1897 SplitBlock->Flags = FreeFlags;
1898 SplitBlock->SegmentOffset = InUseEntry->SegmentOffset;
1899 SplitBlock->Size = (
USHORT)FreeSize;
1916 SplitBlock2->PreviousSize = (
USHORT)FreeSize;
1923 SplitBlock->Flags = SplitBlock2->Flags;
1929 FreeSize += SplitBlock2->Size;
1935 SplitBlock->Size = (
USHORT)FreeSize;
1961 SegmentOffset = SplitBlock->SegmentOffset;
2032 return InUseEntry + 1;
2054 DPRINT1(
"HEAP: Allocation failed!\n");
2089 if (
Size >= 0x80000000)
2092 DPRINT1(
"HEAP: Allocation failed!\n");
2098 DPRINT1(
"HEAP: RtlAllocateHeap is called with unsupported flags %x, ignoring\n",
Flags);
2137 if (Index <= Heap->VirtualMemoryThreshold)
2148 if (FreeEntry->Size <
Index)
2161 while (FreeEntry->Size <
Index)
2214 return InUseEntry + 1;
2223 (
PVOID *)&VirtualBlock,
2234 DPRINT1(
"HEAP: Allocation failed!\n");
2252 return VirtualBlock + 1;
2273 DPRINT1(
"HEAP: Allocation failed!\n");
2304 Heap = (
PHEAP)HeapPtr;
2323 DPRINT1(
"HEAP: Trying to free an invalid address %p!\n",
Ptr);
2331 DPRINT1(
"HEAP: Trying to free an invalid address %p!\n",
Ptr);
2356 (
PVOID *)&VirtualEntry,
2362 DPRINT1(
"HEAP: Failed releasing memory with Status 0x%08X. Heap %p, ptr %p, base address %p\n",
2370 BlockSize = HeapEntry->Size;
2417 UCHAR EntryFlags, RememberFlags;
2419 SIZE_T FreeSize, PrevSize, TailPart, AddedSize = 0;
2421 UCHAR SegmentOffset;
2424 if (
Index > Heap->VirtualMemoryThreshold)
2428 EntryFlags = InUseEntry->Flags;
2438 Heap->Segments[InUseEntry->SegmentOffset],
2443 if (!FreeEntry)
return FALSE;
2450 if (FreeSize + InUseEntry->Size <
Index)
2454 Heap->TotalFreeSize += FreeSize;
2459 RememberFlags = FreeEntry->Flags;
2462 FreeSize += InUseEntry->Size;
2472 FreeSize = InUseEntry->Size + FreeEntry->Size;
2476 RememberFlags = FreeEntry->Flags;
2480 Heap->TotalFreeSize -= FreeEntry->Size;
2483 PrevSize = (InUseEntry->Size <<
HEAP_ENTRY_SHIFT) - InUseEntry->UnusedBytes;
2501 *NewExtra = *OldExtra;
2520 (InUseEntry + InUseEntry->Size)->PreviousSize = InUseEntry->Size;
2524 SegmentOffset = InUseEntry->SegmentOffset;
2534 UnusedEntry->SegmentOffset = InUseEntry->SegmentOffset;
2539 SegmentOffset = UnusedEntry->SegmentOffset;
2543 UnusedEntry->Flags = RememberFlags;
2544 UnusedEntry->Size = (
USHORT)FreeSize;
2548 Heap->TotalFreeSize += FreeSize;
2558 UnusedEntry->Flags = RememberFlags & (~HEAP_ENTRY_LAST_ENTRY);
2559 UnusedEntry->Size = (
USHORT)FreeSize;
2562 FollowingEntry->PreviousSize = (
USHORT)FreeSize;
2566 Heap->TotalFreeSize += FreeSize;
2571 RememberFlags = FollowingEntry->Flags;
2575 Heap->TotalFreeSize -= FollowingEntry->Size;
2578 FreeSize += FollowingEntry->Size;
2579 UnusedEntry->Flags = RememberFlags;
2585 UnusedEntry->Size = (
USHORT)FreeSize;
2593 SegmentOffset = UnusedEntry->SegmentOffset;
2599 Heap->TotalFreeSize += FreeSize;
2618 TailPart = PrevSize & (
sizeof(
ULONG) - 1);
2621 if (TailPart) TailPart = 4 - TailPart;
2623 if (
Size > (PrevSize + TailPart))
2624 AddedSize = (
Size - (PrevSize + TailPart)) & ~(
sizeof(
ULONG) - 1);
2643 InUseEntry->Flags &= ~HEAP_ENTRY_SETTABLE_FLAGS;
2696 PVOID NewBaseAddress;
2702 SIZE_T RemainderBytes, ExtraSize;
2705 UCHAR SegmentOffset;
2722 if (
Size >= 0x80000000)
2781 OldIndex = InUseEntry->Size;
2790 if (
Index <= OldIndex)
2793 if (
Index + 1 == OldIndex)
2811 *NewExtra = *OldExtra;
2835 RemainderBytes = OldSize & (
sizeof(
ULONG) - 1);
2838 RemainderBytes = 4 - RemainderBytes;
2840 if (
Size > (OldSize + RemainderBytes))
2843 ExtraSize = (
Size - (OldSize + RemainderBytes)) & ~(
sizeof(
ULONG) - 1);
2865 if (
Index != OldIndex)
2868 FreeFlags = InUseEntry->Flags & ~HEAP_ENTRY_BUSY;
2882 (
PVOID *)&DecommitBase,
2888 DPRINT1(
"HEAP: Unable to release memory (pointer %p, size 0x%x), Status %08x\n", DecommitBase, DecommitSize,
Status);
2893 VirtualAllocBlock->
CommitSize -= DecommitSize;
2902 SplitBlock->Flags = FreeFlags;
2904 SplitBlock->SegmentOffset = InUseEntry->SegmentOffset;
2907 FreeSize = InUseEntry->Size -
Index;
2911 InUseEntry->Flags &= ~HEAP_ENTRY_LAST_ENTRY;
2916 SegmentOffset = SplitBlock->SegmentOffset;
2920 SplitBlock->Size = (
USHORT)FreeSize;
2934 SplitBlock->Size = (
USHORT)FreeSize;
2948 SplitBlock->Flags = SplitBlock2->Flags;
2955 FreeSize += SplitBlock2->Size;
2959 SplitBlock->Size = (
USHORT)FreeSize;
2968 SegmentOffset = SplitBlock->SegmentOffset;
2995 DPRINT1(
"Realloc in place failed, but it was the only option\n");
3001 Flags &= ~HEAP_TAG_MASK;
3007 Flags &= ~HEAP_SETTABLE_USER_FLAGS;
3021 else if (InUseEntry->SmallTagIndex)
3061 if (
Size > OldSize &&
3071 Ptr = NewBaseAddress;
3261 TailPart = (
PCHAR)(HeapEntry + 1) +
Size;
3270 DPRINT1(
"HEAP: Heap entry (size %x) %p tail is modified at %p\n",
Size, HeapEntry, TailPart +
Result);
3294 ULONG SegmentOffset;
3297 if (!HeapEntry)
goto invalid_entry;
3304 if (BigAllocation &&
3308 if (!BigAllocation && (HeapEntry->SegmentOffset >=
HEAP_SEGMENTS ||
3310 HeapEntry < Segment->FirstEntry ||
3311 HeapEntry >=
Segment->LastValidEntry))
3322 for (SegmentOffset = 0; SegmentOffset <
HEAP_SEGMENTS; SegmentOffset++)
3327 if ((HeapEntry >=
Segment->FirstEntry) &&
3328 (HeapEntry < Segment->LastValidEntry))
3340 DPRINT1(
"HEAP: Invalid heap entry %p in heap %p\n", HeapEntry, Heap);
3348 UCHAR SegmentOffset,
3358 ULONG UnCommittedPages;
3359 ULONG UnCommittedRanges;
3362 UnCommittedPages = 0;
3363 UnCommittedRanges = 0;
3368 UcrDescriptor =
NULL;
3372 UcrEntry =
Segment->UCRSegmentList.Flink;
3376 if (
Segment->BaseAddress == Heap)
3377 CurrentEntry = &Heap->Entry;
3379 CurrentEntry = &
Segment->Entry;
3381 while (CurrentEntry < Segment->LastValidEntry)
3383 if (UcrDescriptor &&
3386 DPRINT1(
"HEAP: Entry %p is not inside uncommited range [%p .. %p)\n",
3387 CurrentEntry, UcrDescriptor->
Address,
3395 while (CurrentEntry < Segment->LastValidEntry)
3397 if (PreviousSize != CurrentEntry->PreviousSize)
3399 DPRINT1(
"HEAP: Entry %p has incorrect PreviousSize %x instead of %x\n",
3400 CurrentEntry, CurrentEntry->PreviousSize, PreviousSize);
3405 PreviousSize = CurrentEntry->Size;
3425 *FreeEntriesCount = *FreeEntriesCount + 1;
3426 *TotalFreeSize += CurrentEntry->Size;
3445 DPRINT1(
"HEAP: Free heap block %p modified at %p after it was freed\n",
3454 if (CurrentEntry->SegmentOffset != SegmentOffset)
3456 DPRINT1(
"HEAP: Heap entry %p SegmentOffset is incorrect %x (should be %x)\n",
3457 CurrentEntry, SegmentOffset, CurrentEntry->SegmentOffset);
3469 if (CurrentEntry !=
Segment->LastValidEntry)
3471 DPRINT1(
"HEAP: Heap entry %p is not last block in segment (%p)\n",
3472 CurrentEntry,
Segment->LastValidEntry);
3476 else if (CurrentEntry != UcrDescriptor->
Address)
3478 DPRINT1(
"HEAP: Heap entry %p does not match next uncommitted address (%p)\n",
3479 CurrentEntry, UcrDescriptor->
Address);
3486 UnCommittedRanges++;
3491 UcrEntry = UcrEntry->
Flink;
3492 if (UcrEntry == &
Segment->UCRSegmentList)
3495 UcrDescriptor =
NULL;
3512 if (
Segment->NumberOfUnCommittedPages != UnCommittedPages)
3514 DPRINT1(
"HEAP: Segment %p NumberOfUnCommittedPages is invalid (%x != %x)\n",
3520 if (
Segment->NumberOfUnCommittedRanges != UnCommittedRanges)
3522 DPRINT1(
"HEAP: Segment %p NumberOfUnCommittedRanges is invalid (%x != %x)\n",
3535 UCHAR SegmentOffset;
3538 ULONG FreeBlocksCount, FreeListEntriesCount;
3550 FreeListEntriesCount = 0;
3552 NextEntry = ListHead->
Flink;
3554 while (NextEntry != ListHead)
3558 NextEntry = NextEntry->
Flink;
3560 if (NextEntry != ListHead)
3564 if (FreeEntry->Size > NextFreeEntry->Size)
3566 DPRINT1(
"Dedicated free entry %p of size %ld is not put in order.\n", FreeEntry, FreeEntry->Size);
3575 DPRINT1(
"No hint pointing to the non-dedicated list although there is a free entry %p of size %ld.\n",
3576 FreeEntry, FreeEntry->Size);
3580 DPRINT1(
"Hint bit 0 is not set although there is a free entry %p of size %ld.\n",
3581 FreeEntry, FreeEntry->Size);
3588 DPRINT1(
"No hint pointing to the dedicated list although there is a free entry %p of size %ld.\n",
3589 FreeEntry, FreeEntry->Size);
3593 DPRINT1(
"Hint bit 0 is not set although there is a free entry %p of size %ld.\n",
3594 FreeEntry, FreeEntry->Size);
3601 DPRINT1(
"HEAP: Free element %p is marked in-use\n", FreeEntry);
3606 FreeListEntriesCount++;
3618 DPRINT1(
"Hint bitmap bit at %u is not set, but there is a hint entry.\n",
HintIndex);
3625 DPRINT1(
"There is an entry %p of size %lu, smaller than the decommit threshold %lu in the non-dedicated free list hint.\n",
3633 DPRINT1(
"There is an entry %p of size %lu at the position %u in the free entry hint array.\n",
3643 if (PreviousFreeEntry->Size >= FreeEntry->Size)
3645 DPRINT1(
"Free entry hint %p of size %lu is larger than the entry before it %p, which is of size %lu.\n",
3646 FreeEntry, FreeEntry->Size, PreviousFreeEntry, PreviousFreeEntry->Size);
3653 DPRINT1(
"Hint bitmap bit at %u is set, but there is no hint entry.\n",
HintIndex);
3659 NextEntry = ListHead->
Flink;
3661 while (ListHead != NextEntry)
3672 NextEntry = NextEntry->
Flink;
3676 FreeBlocksCount = 0;
3679 for (SegmentOffset = 0; SegmentOffset <
HEAP_SEGMENTS; SegmentOffset++)
3698 if (FreeListEntriesCount != FreeBlocksCount)
3700 DPRINT1(
"HEAP: Free blocks count in arena (%lu) does not match free blocks number in the free lists (%lu)\n", FreeBlocksCount, FreeListEntriesCount);
3706 DPRINT1(
"HEAP: Total size of free blocks in arena (%Iu) does not equal to the one in heap header (%Iu)\n", TotalFreeSize, Heap->
TotalFreeSize);
3748 DPRINT1(
"HEAP: Signature %lx is invalid for heap %p\n", Heap->
Signature, Heap);
3919 HeapEntry->Flags &= ~(UserFlagsReset >> 4);
3920 HeapEntry->Flags |= (UserFlagsSet >> 4);
4076 if (HeapInformationLength <
sizeof(
ULONG))
4083 if (*(
PULONG)HeapInformation != 2)
4088 DPRINT1(
"RtlSetHeapInformation() needs to enable LFH\n");
4099 PVOID HeapInformation,
4100 SIZE_T HeapInformationLength,
4113 if (HeapInformationLength <
sizeof(
ULONG))
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
#define STATUS_INVALID_HANDLE
#define STATUS_NOT_IMPLEMENTED
#define RtlInitializeBitMap
#define NT_SUCCESS(StatCode)
NTSTATUS NTAPI RtlInitializeHeapLock(IN OUT PHEAP_LOCK *Lock)
NTSTATUS NTAPI RtlEnterHeapLock(IN OUT PHEAP_LOCK Lock, IN BOOLEAN Exclusive)
KPROCESSOR_MODE NTAPI RtlpGetMode(VOID)
VOID NTAPI RtlpSetHeapParameters(IN PRTL_HEAP_PARAMETERS Parameters)
NTSTATUS NTAPI RtlDeleteHeapLock(IN OUT PHEAP_LOCK Lock)
NTSTATUS NTAPI RtlLeaveHeapLock(IN OUT PHEAP_LOCK Lock)
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
#define RemoveEntryList(Entry)
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
#define IsListEmpty(ListHead)
#define RtlCompareMemory(s1, s2, l)
#define RemoveHeadList(ListHead)
#define InitializeListHead(ListHead)
#define ROUND_UP(n, align)
#define ROUND_DOWN(n, align)
IN PFCB IN PFILE_OBJECT FileObject IN ULONG AllocationSize
NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
_Must_inspect_result_ _In_ USAGE _In_ USHORT _In_ USAGE Usage
#define FLG_HEAP_DISABLE_COALESCING
#define FLG_USER_STACK_TRACE_DB
#define FLG_HEAP_ENABLE_FREE_CHECK
#define FLG_HEAP_VALIDATE_PARAMETERS
#define FLG_HEAP_ENABLE_TAIL_CHECK
#define FLG_HEAP_VALIDATE_ALL
#define RtlFillMemory(Dest, Length, Fill)
NTSYSAPI void WINAPI RtlSetLastWin32ErrorAndNtStatusFromNtStatus(NTSTATUS)
NTSYSAPI ULONG WINAPI RtlGetNtGlobalFlags(void)
#define EXCEPTION_EXECUTE_HANDLER
#define ARENA_FREE_FILLER
#define RtlFillMemoryUlong(dst, len, val)
NTSYSAPI NTSTATUS NTAPI ZwQueryVirtualMemory(_In_ HANDLE ProcessHandle, _In_ PVOID Address, _In_ MEMORY_INFORMATION_CLASS VirtualMemoryInformationClass, _Out_ PVOID VirtualMemoryInformation, _In_ SIZE_T Length, _Out_opt_ PSIZE_T ResultLength)
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T CommitSize
#define PAGE_ROUND_DOWN(x)
NTSYSAPI VOID NTAPI RtlRaiseException(_In_ PEXCEPTION_RECORD ExceptionRecord)
@ HeapCompatibilityInformation
#define HEAP_SKIP_VALIDATION_CHECKS
NTSTATUS(NTAPI * PHEAP_ENUMERATION_ROUTINE)(_In_ PVOID HeapHandle, _In_ PVOID UserParam)
#define HEAP_LOCK_USER_ALLOCATED
struct _HEAP_LOCK * PHEAP_LOCK
#define HEAP_VALIDATE_ALL_ENABLED
#define HEAP_CAPTURE_STACK_BACKTRACES
#define HEAP_VALIDATE_PARAMETERS_ENABLED
struct _HEAP_LOCK HEAP_LOCK
#define HEAP_FLAG_PAGE_ALLOCS
enum _HEAP_INFORMATION_CLASS HEAP_INFORMATION_CLASS
_In_ PMEMORY_AREA _In_ PVOID _In_ BOOLEAN Locked
#define HEAP_FREE_CHECKING_ENABLED
#define HEAP_DISABLE_COALESCE_ON_FREE
#define HEAP_GENERATE_EXCEPTIONS
#define HEAP_TAIL_CHECKING_ENABLED
#define NtCurrentProcess()
#define HEAP_SETTABLE_USER_VALUE
#define HEAP_SETTABLE_USER_FLAGS
#define HEAP_CREATE_ALIGN_16
#define HEAP_PSEUDO_TAG_FLAG
#define HEAP_CREATE_VALID_MASK
#define HEAP_REALLOC_IN_PLACE_ONLY
#define HEAP_CREATE_ENABLE_TRACING
#define HEAP_NO_SERIALIZE
#define RTL_BITS_OF(sizeOfArg)
BOOLEAN RtlpPageHeapEnabled
VOID NTAPI RtlpAddHeapToProcessList(struct _HEAP *Heap)
VOID NTAPI RtlpRemoveHeapFromProcessList(struct _HEAP *Heap)
#define ARENA_INUSE_FILLER
#define _SEH2_EXCEPT(...)
#define _SEH2_YIELD(__stmt)
HANDLE NTAPI RtlDestroyHeap(HANDLE HeapPtr)
PHEAP_FREE_ENTRY NTAPI RtlpCoalesceFreeBlocks(PHEAP Heap, PHEAP_FREE_ENTRY FreeEntry, PSIZE_T FreeSize, BOOLEAN Remove)
UCHAR FillPattern[HEAP_ENTRY_SIZE]
FORCEINLINE UCHAR RtlpFindLeastSetBit(ULONG Bits)
NTSTATUS NTAPI RtlpInitializeHeapSegment(IN OUT PHEAP Heap, OUT PHEAP_SEGMENT Segment, IN UCHAR SegmentIndex, IN ULONG SegmentFlags, IN SIZE_T SegmentReserve, IN SIZE_T SegmentCommit)
PHEAP_ENTRY NTAPI RtlpSplitEntry(PHEAP Heap, ULONG Flags, PHEAP_FREE_ENTRY FreeBlock, SIZE_T AllocationSize, SIZE_T Index, SIZE_T Size)
PHEAP_FREE_ENTRY NTAPI RtlpInsertFreeBlock(PHEAP Heap, PHEAP_FREE_ENTRY FreeEntry, SIZE_T BlockSize)
NTSTATUS NTAPI RtlSetHeapInformation(IN HANDLE HeapHandle OPTIONAL, IN HEAP_INFORMATION_CLASS HeapInformationClass, IN PVOID HeapInformation, IN SIZE_T HeapInformationLength)
NTSTATUS NTAPI RtlpInitializeHeap(OUT PHEAP Heap, IN ULONG Flags, IN PHEAP_LOCK Lock OPTIONAL, IN PRTL_HEAP_PARAMETERS Parameters)
static BOOLEAN RtlpIsLastCommittedEntry(PHEAP_ENTRY Entry)
BOOLEAN NTAPI RtlpValidateHeap(PHEAP Heap, BOOLEAN ForceValidation)
BOOLEAN NTAPI RtlGetUserInfoHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID BaseAddress, OUT PVOID *UserValue, OUT PULONG UserFlags)
NTSTATUS NTAPI RtlUsageHeap(IN HANDLE Heap, IN ULONG Flags, OUT PRTL_HEAP_USAGE Usage)
static PVOID RtlpAllocateNonDedicated(PHEAP Heap, ULONG Flags, SIZE_T Size, SIZE_T AllocationSize, SIZE_T Index, BOOLEAN HeapLocked)
ULONG NTAPI RtlMultipleFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN ULONG Count, OUT PVOID *Array)
BOOLEAN NTAPI RtlValidateHeap(HANDLE HeapPtr, ULONG Flags, PVOID Block)
PVOID NTAPI RtlReAllocateHeap(HANDLE HeapPtr, ULONG Flags, PVOID Ptr, SIZE_T Size)
NTSTATUS NTAPI RtlWalkHeap(IN HANDLE HeapHandle, IN PVOID HeapEntry)
BOOLEAN NTAPI RtlSetUserFlagsHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID BaseAddress, IN ULONG UserFlagsReset, IN ULONG UserFlagsSet)
static PHEAP_FREE_ENTRY RtlpExtendHeap(PHEAP Heap, SIZE_T Size)
BOOLEAN NTAPI RtlpCheckInUsePattern(PHEAP_ENTRY HeapEntry)
VOID NTAPI RtlpInsertUnCommittedPages(PHEAP_SEGMENT Segment, ULONG_PTR Address, SIZE_T Size)
PWSTR NTAPI RtlQueryTagHeap(IN PVOID HeapHandle, IN ULONG Flags, IN USHORT TagIndex, IN BOOLEAN ResetCounters, OUT PRTL_HEAP_TAG_INFO HeapTagInfo)
ULONG NTAPI RtlCreateTagHeap(_In_ HANDLE HeapHandle, _In_ ULONG Flags, _In_opt_ PWSTR TagName, _In_ PWSTR TagSubName)
static VOID RtlpDeCommitFreeBlock(PHEAP Heap, PHEAP_FREE_ENTRY FreeEntry, SIZE_T Size)
BOOLEAN NTAPI RtlpGrowBlockInPlace(IN PHEAP Heap, IN ULONG Flags, IN PHEAP_ENTRY InUseEntry, IN SIZE_T Size, IN SIZE_T Index)
HANDLE NTAPI RtlCreateHeap(ULONG Flags, PVOID Addr, SIZE_T TotalSize, SIZE_T CommitSize, PVOID Lock, PRTL_HEAP_PARAMETERS Parameters)
SIZE_T NTAPI RtlSizeHeap(HANDLE HeapPtr, ULONG Flags, PVOID Ptr)
BOOLEAN NTAPI RtlpValidateHeapHeaders(PHEAP Heap, BOOLEAN Recalculate)
PVOID NTAPI RtlProtectHeap(IN PVOID HeapHandle, IN BOOLEAN ReadOnly)
BOOLEAN NTAPI RtlValidateProcessHeaps(VOID)
VOID NTAPI RtlpInsertFreeBlockHelper(PHEAP Heap, PHEAP_FREE_ENTRY FreeEntry, SIZE_T BlockSize, BOOLEAN NoFill)
VOID NTAPI RtlpDestroyUnCommittedRange(PHEAP_SEGMENT Segment, PHEAP_UCR_DESCRIPTOR UcrDescriptor)
BOOLEAN NTAPI RtlSetUserValueHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID BaseAddress, IN PVOID UserValue)
BOOLEAN NTAPI RtlUnlockHeap(HANDLE HeapPtr)
PHEAP_UCR_DESCRIPTOR NTAPI RtlpCreateUnCommittedRange(PHEAP_SEGMENT Segment)
SIZE_T NTAPI RtlpGetSizeOfBigBlock(PHEAP_ENTRY HeapEntry)
ULONG NTAPI RtlExtendHeap(IN HANDLE Heap, IN ULONG Flags, IN PVOID P, IN SIZE_T Size)
PHEAP_FREE_ENTRY NTAPI RtlpCoalesceHeap(PHEAP Heap)
BOOLEAN NTAPI RtlpValidateHeapEntry(PHEAP Heap, PHEAP_ENTRY HeapEntry)
ULONG NTAPI RtlMultipleAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size, IN ULONG Count, OUT PVOID *Array)
NTSTATUS NTAPI RtlQueryProcessHeapInformation(IN struct _DEBUG_BUFFER *DebugBuffer)
PHEAP_ENTRY_EXTRA NTAPI RtlpGetExtraStuffPointer(PHEAP_ENTRY HeapEntry)
NTSTATUS NTAPI RtlQueryHeapInformation(HANDLE HeapHandle, HEAP_INFORMATION_CLASS HeapInformationClass, PVOID HeapInformation, SIZE_T HeapInformationLength, PSIZE_T ReturnLength OPTIONAL)
VOID NTAPI RtlpDestroyHeapSegment(PHEAP_SEGMENT Segment)
NTSTATUS NTAPI RtlEnumProcessHeaps(PHEAP_ENUMERATION_ROUTINE HeapEnumerationRoutine, PVOID lParam)
BOOLEAN NTAPI RtlpValidateHeapSegment(PHEAP Heap, PHEAP_SEGMENT Segment, UCHAR SegmentOffset, PULONG FreeEntriesCount, PSIZE_T TotalFreeSize, PSIZE_T TagEntries, PSIZE_T PseudoTagEntries)
BOOLEAN NTAPI RtlLockHeap(IN HANDLE HeapPtr)
static PHEAP_FREE_ENTRY RtlpFindAndCommitPages(PHEAP Heap, PHEAP_SEGMENT Segment, PSIZE_T Size, PVOID AddressRequested)
ULONG NTAPI RtlCompactHeap(HANDLE Heap, ULONG Flags)
static VOID RtlpRemoveFreeBlock(PHEAP Heap, PHEAP_FREE_ENTRY FreeEntry, BOOLEAN NoFill)
BOOLEAN NTAPI RtlZeroHeap(IN PVOID HeapHandle, IN ULONG Flags)
struct _HEAP_ENTRY_EXTRA HEAP_ENTRY_EXTRA
SIZE_T NTAPI RtlDebugSizeHeap(HANDLE HeapPtr, ULONG Flags, PVOID Ptr)
PVOID NTAPI RtlDebugAllocateHeap(PVOID HeapPtr, ULONG Flags, SIZE_T Size)
BOOLEAN NTAPI RtlDebugSetUserValueHeap(PVOID HeapHandle, ULONG Flags, PVOID BaseAddress, PVOID UserValue)
struct _HEAP_UCR_DESCRIPTOR HEAP_UCR_DESCRIPTOR
struct _HEAP_ENTRY * PHEAP_ENTRY
PVOID NTAPI RtlpPageHeapDestroy(HANDLE HeapPtr)
#define HEAP_ENTRY_EXTRA_PRESENT
#define HEAP_EXTRA_FLAGS_MASK
BOOLEAN NTAPI RtlpPageHeapLock(HANDLE HeapPtr)
struct _HEAP_VIRTUAL_ALLOC_ENTRY HEAP_VIRTUAL_ALLOC_ENTRY
struct _HEAP_FREE_ENTRY HEAP_FREE_ENTRY
struct _HEAP_ENTRY_EXTRA * PHEAP_ENTRY_EXTRA
FORCEINLINE BOOLEAN RtlpHeapIsSpecial(ULONG Flags)
BOOLEAN NTAPI RtlDebugFreeHeap(HANDLE HeapPtr, ULONG Flags, PVOID Ptr)
BOOLEAN NTAPI RtlDebugDestroyHeap(HANDLE HeapPtr)
HEAP_ENTRY_EXTRA HEAP_FREE_ENTRY_EXTRA
BOOLEAN NTAPI RtlDebugSetUserFlagsHeap(PVOID HeapHandle, ULONG Flags, PVOID BaseAddress, ULONG UserFlagsReset, ULONG UserFlagsSet)
NTSYSAPI HANDLE NTAPI RtlDebugCreateHeap(ULONG Flags, PVOID Addr, SIZE_T TotalSize, SIZE_T CommitSize, PVOID Lock, PRTL_HEAP_PARAMETERS Parameters)
#define HEAP_SEGMENT_SIGNATURE
PVOID NTAPI RtlDebugReAllocateHeap(HANDLE HeapPtr, ULONG Flags, PVOID Ptr, SIZE_T Size)
#define HEAP_MAX_BLOCK_SIZE
#define HEAP_USER_ALLOCATED
#define HEAP_ENTRY_SETTABLE_FLAGS
struct _HEAP_UCR_DESCRIPTOR * PHEAP_UCR_DESCRIPTOR
struct _HEAP_FREE_ENTRY * PHEAP_FREE_ENTRY
BOOLEAN NTAPI RtlDebugGetUserInfoHeap(PVOID HeapHandle, ULONG Flags, PVOID BaseAddress, PVOID *UserValue, PULONG UserFlags)
struct _HEAP_ENTRY HEAP_ENTRY
#define HEAP_ENTRY_LAST_ENTRY
BOOLEAN NTAPI RtlpPageHeapUnlock(HANDLE HeapPtr)
BOOLEAN NTAPI RtlpDebugPageHeapValidate(PVOID HeapPtr, ULONG Flags, PVOID Block)
#define HEAP_ENTRY_FILL_PATTERN
#define HEAP_ENTRY_VIRTUAL_ALLOC
HANDLE NTAPI RtlpPageHeapCreate(ULONG Flags, PVOID Addr, SIZE_T TotalSize, SIZE_T CommitSize, PVOID Lock, PRTL_HEAP_PARAMETERS Parameters)
#define STATUS_BUFFER_TOO_SMALL
PULONG MinorVersion OPTIONAL
base of all file and directory entries
struct _EXCEPTION_RECORD * ExceptionRecord
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
HEAP_ENTRY_EXTRA ExtraStuff
PRTL_HEAP_COMMIT_ROUTINE CommitRoutine
PLIST_ENTRY FreeHints[ANYSIZE_ARRAY]
RTL_BITMAP FreeHintBitmap
LIST_ENTRY VirtualAllocdBlocks
PHEAP_PSEUDO_TAG_ENTRY PseudoTagEntries
SIZE_T DeCommitFreeBlockThreshold
SIZE_T DeCommitTotalFreeThreshold
struct _HEAP_SEGMENT * Segments[HEAP_SEGMENTS]
struct _LIST_ENTRY * Blink
struct _LIST_ENTRY * Flink
#define FIELD_OFFSET(t, f)
#define RtlCopyMemory(Destination, Source, Length)
#define RtlZeroMemory(Destination, Length)
#define RtlMoveMemory(Destination, Source, Length)
#define CONTAINING_RECORD(address, type, field)
#define STATUS_INVALID_PARAMETER
#define STATUS_UNSUCCESSFUL
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
_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
_Must_inspect_result_ _In_ ULONG Flags
_In_ ULONG _In_ ULONG HintIndex
_In_opt_ PVOID _In_opt_ SIZE_T ReserveSize
_Must_inspect_result_ NTSYSAPI SIZE_T NTAPI RtlCompareMemoryUlong(_In_reads_bytes_(Length) PVOID Source, _In_ SIZE_T Length, _In_ ULONG Pattern)
_IRQL_requires_same_ _In_ CLONG ByteSize