RtlpInitializeHeapSegment
NTSTATUS __fastcall RtlpInitializeHeapSegment(
_HEAP *Heap,
_HEAP_SEGMENT *Segment,
UINT64 SizeOfMetadata,
UINT8 SegmentIndex,
UINT64 Flags,
VOID *BaseAddress,
VOID *UnCommittedAddress,
VOID *CommitLimitAddress){
_BYTE *v8;
signed __int64 Blink;
signed __int64 v12;
_HEAP_UCR_DESCRIPTOR *v13;
unsigned int v14;
_HEAP_FREE_ENTRY *v15;
__int64 v16;
INT64 v17;
__int64 v18;
__int64 v19;
_HEAP *v20;
unsigned __int64 v21;
_LIST_ENTRY *p_SegmentList;
_LIST_ENTRY *p_SegmentListEntry;
UINT64 AllocationType;
UINT64 Protect;
UINT64 RegionSize[2];
v8 = CommitLimitAddress;
RegionSize[0] = 0i64;
Blink = (_BYTE *)CommitLimitAddress - (_BYTE *)BaseAddress;
if( (unsigned __int64)((_BYTE *)CommitLimitAddress - (_BYTE *)BaseAddress) > 0xFFFFF000 )
goto LABEL_10;
v12 = SizeOfMetadata + 15;
v13 = (_HEAP_UCR_DESCRIPTOR *)UnCommittedAddress;
Blink /= 4096i64;
v12 &= 0xFFFFFFFFFFFFFFF0ui64;
v14 = Blink;
v15 = (_HEAP_FREE_ENTRY *)((char *)Segment + v12);
v16 = v12 >> 4;
if( &v15[2].FreeList >= UnCommittedAddress )
{
if( &v15[2].FreeList < CommitLimitAddress )
{
v17 = Heap->Counters.TotalMemoryCommitted - Heap->Counters.InBlockDeccomitSize;
RegionSize[0] = ((char *)v15 - (_BYTE *)UnCommittedAddress + 4111) & 0xFFFFFFFFFFFFF000ui64;
LODWORD(Blink) = RtlpHpHeapCheckCommitLimit((VOID *)RegionSize[0], v17, Heap, (INT8 *)&Heap->CommitLimitData);
if( (_DWORD)Blink )
{
LODWORD(Protect) = 4;
LODWORD(AllocationType) = 4096;
LODWORD(Blink) = ZwAllocateVirtualMemory(
(VOID *)0xFFFFFFFFFFFFFFFFi64,
&UnCommittedAddress,
0i64,
RegionSize,
AllocationType,
Protect);
if( (int)Blink >= 0 )
{
v13 = (_HEAP_UCR_DESCRIPTOR *)((char *)UnCommittedAddress + RegionSize[0]);
UnCommittedAddress = (char *)UnCommittedAddress + RegionSize[0];
goto LABEL_7;
}
}
++Heap->Counters.CommitFailures;
}
LABEL_10:
LOBYTE(Blink) = 0;
return Blink;
}
LABEL_7:
Segment->Entry.UnpackedEntry.Size = v16;
Segment->Entry.ExtendedEntry.ContextValue = 1;
Segment->Entry.UnpackedEntry.UnusedBytes = 1;
Segment->Entry.UnpackedEntry.PreviousSize = Heap->Encoding.UnpackedEntry.PreviousSize;
v18 = (v8 - (_BYTE *)v13) / 4096;
Segment->Heap = Heap;
Segment->SegmentFlags = Flags;
v19 = v14 << 12;
Segment->LastValidEntry = (_HEAP_ENTRY *)((char *)BaseAddress + v19);
Segment->SegmentSignature = -1114130;
Segment->BaseAddress = BaseAddress;
Segment->FirstEntry = &v15->HeapEntry;
Segment->NumberOfPages = v14;
Segment->NumberOfUnCommittedPages = 0;
Heap->Counters.TotalMemoryCommitted += v19;
Heap->Counters.TotalMemoryReserved += v19;
Segment->UCRSegmentList.Blink = &Segment->UCRSegmentList;
Segment->UCRSegmentList.Flink = &Segment->UCRSegmentList;
Segment->Entry.UnpackedEntry.SegmentOffset = Segment->Heap != (_HEAP *)Segment;
v15->HeapEntry.UnpackedEntry.PreviousSize = Segment->Entry.UnpackedEntry.Size ^ Heap->Encoding.UnpackedEntry.PreviousSize;
v20 = Segment->Heap;
if( v20 == (_HEAP *)Segment )
{
LOBYTE(v21) = 0;
}
else
{
v21 = ((unsigned __int64)((char *)v15 - (char *)Segment) >> 16) + 1;
if( v21 >= 0xFE )
{
RtlpLogHeapFailure(heap_failure_entry_corruption, v20, v15, Segment, 0i64);
v13 = (_HEAP_UCR_DESCRIPTOR *)UnCommittedAddress;
}
}
v15->HeapEntry.UnpackedEntry.SegmentOffset = v21;
RtlpCreateUCREntry(Heap, Segment, v13 - 1, (unsigned int)((_DWORD)v18 << 12), v15, RegionSize);
if( Heap->EncodeFlagMask )
{
Segment->Entry.UnpackedEntry.SmallTagIndex = LOBYTE(Segment->Entry.Code1) ^ BYTE1(Segment->Entry.AgregateCode) ^ Segment->Entry.UnpackedEntry.Flags;
Segment->Entry.UnpackedEntry.SubSegmentCode ^= Heap->Encoding.UnpackedEntry.SubSegmentCode;
}
if( RegionSize[0] )
RtlpInsertFreeBlock(Heap, v15, RegionSize[0]);
p_SegmentList = &Heap->SegmentList;
p_SegmentListEntry = &Segment->SegmentListEntry;
Blink = (signed __int64)Heap->SegmentList.Blink;
if( *(_HEAP **)Blink == (_HEAP *)&Heap->SegmentList )
{
p_SegmentListEntry->Flink = p_SegmentList;
p_SegmentListEntry->Blink = (_LIST_ENTRY *)Blink;
*(_QWORD *)Blink = p_SegmentListEntry;
Heap->SegmentList.Blink = p_SegmentListEntry;
}
else
{
RtlpLogHeapFailure(heap_failure_freelists_corruption, 0i64, p_SegmentList, 0i64, *(VOID **)Blink);
}
++Heap->Counters.TotalSegments;
LOBYTE(Blink) = 1;
return Blink;
}Referenced by:
RtlCreateHeap
RtlpExtendHeap