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