RtlpDeCommitFreeBlock

VOID __stdcall RtlpDeCommitFreeBlock(_HEAP *Heap, _HEAP_FREE_ENTRY *FreeBlock, UINT64 FreeSize){
  char v3; 
  char v4; 
  _HEAP_FREE_ENTRY *v5; 
  _HEAP *v6; 
  char v7; 
  unsigned __int64 v8; 
  _HEAP_UCR_DESCRIPTOR *v9; 
  _HEAP_FREE_ENTRY *v10; 
  _HEAP_SEGMENT *p_Segment; 
  UINT64 v12; 
  UINT64 v13; 
  UINT64 v14; 
  unsigned __int64 v15; 
  _LIST_ENTRY *i; 
  _LIST_ENTRY *v17; 
  _HEAP_FREE_ENTRY *v18; 
  INT64 v19; 
  __int64 v20; 
  __int64 v21; 
  INT64 v22; 
  _HEAP_UCR_DESCRIPTOR *v23; 
  _HEAP *v24; 
  bool v25; 
  _HEAP_UCR_DESCRIPTOR *v26; 
  unsigned __int64 v27; 
  UINT64 v28; 
  unsigned __int64 v29; 
  char *v30; 
  UINT64 v31; 
  bool v32; 
  INT64 v33; 
  _HEAP *v34; 
  _LIST_ENTRY *v35; 
  __int64 v36; 
  __int64 v37; 
  unsigned __int64 v38; 
  UINT64 v39; 
  char *v40; 
  UINT64 v41; 
  INT64 v42; 
  _HEAP *v43; 
  INT64 v44; 
  _HEAP_FREE_ENTRY *LastKnownEntry; 
  UINT64 *v46; 
  VOID *BaseAddress; 
  __int64 v48; 
  UINT64 Size; 
  _HEAP_UCR_DESCRIPTOR *UCRBlock; 
  __int64 v51[2]; 
  UINT64 RegionSize; 
  UINT64 FreeSizea; 
  char v54; 

  v54 = v3;
  FreeSizea = FreeSize;
  v4 = 0;
  v25 = (int(__fastcall *)(void *, void **, unsigned __int64 *))RtlpHeapKey == Heap->CommitRoutine;
  v5 = FreeBlock;
  v6 = Heap;
  v51[0] = 0i64;
  v48 = 0i64;
  v7 = 0;
  v54 = 0;
  if( !v25 || FreeSize < Heap->DeCommitFreeBlockThreshold )
    goto LABEL_80;
  v8 = FreeSize + Heap->TotalFreeSize;
  if( v8 < Heap->DeCommitTotalFreeThreshold
    || v8 < Heap->Counters.TotalMemoryCommitted >> (LOBYTE(Heap->TuningParameters.CommittThresholdShift) + 4) )
  {
LABEL_79:
    Heap = v6;
LABEL_80:
    RtlpInsertFreeBlock(Heap, FreeBlock, FreeSize);
    return;
  }
  v10 = RtlpCoalesceFreeBlocks(Heap, FreeBlock, &FreeSizea, (UINT64 *)v8, (UINT64 *)LastKnownEntry, v46);
  if( v5->HeapEntry.UnpackedEntry.SegmentOffset )
  {
    v9 = (_HEAP_UCR_DESCRIPTOR *)((unsigned __int64)v5->HeapEntry.UnpackedEntry.SegmentOffset << 16);
    p_Segment = (_HEAP_SEGMENT *)(((unsigned __int64)v5 & 0xFFFFFFFFFFFF0000ui64) - (_QWORD)v9 + 0x10000);
  }
  else
  {
    p_Segment = &v6->Segment;
  }
  v12 = FreeSizea;
  v13 = (UINT64)v10 + 16 * FreeSizea;
  if( *(_BYTE *)(v13 + 15) == 3 )
  {
    RtlpRemoveUCRBlock(v9);
    v14 = *(_QWORD *)(v13 + 56);
    v48 = *(_QWORD *)(v13 + 48);
    Size = v14;
    --p_Segment->NumberOfUnCommittedRanges;
    p_Segment->NumberOfUnCommittedPages -= *(_QWORD *)(v13 + 56) >> 12;
    v6->Counters.TotalMemoryCommitted += *(_QWORD *)(v13 + 56);
    --v6->Counters.TotalUCRs;
    v15 = *(_QWORD *)(v13 + 56);
    if( v15 >= 0xFF000 )
    {
      v6->Counters.TotalMemoryLargeUCR -= v15;
      v15 = *(_QWORD *)(v13 + 56);
    }
    v54 = 1;
    v12 += (v15 >> 4) + 64;
    v7 = 1;
    FreeSizea = v12;
  }
  else
  {
    Size = 0i64;
  }
  if( v6->Encoding.UnpackedEntry.PreviousSize != v10->HeapEntry.UnpackedEntry.PreviousSize )
  {
    v35 = (_LIST_ENTRY *)(((unsigned __int64)&v10[129].FreeList.Blink + 7) & 0xFFFFFFFFFFFFF000ui64);
    BaseAddress = v35;
    if( v35 == &v10[2].FreeList )
    {
      v35 += 256;
      BaseAddress = v35;
    }
    if( v7 )
    {
      v36 = 16 * v12;
      v37 = (__int64)v10 + 16 * v12;
    }
    else
    {
      v36 = 16 * v12;
      v37 = (__int64)&v10[-1] + 16 * v12;
    }
    v38 = v37 & 0xFFFFFFFFFFFFF000ui64;
    if( v38 < (unsigned __int64)v35 )
    {
      if( RtlpHeapErrorHandlerThreshold >= 1 && v54 )
      {
        DbgPrint("(!TrailingUCR)");
        RtlpHeapHandleError(v44);
      }
      goto LABEL_29;
    }
    v39 = v38 - (_QWORD)v35;
    RegionSize = v39;
    if( *(_BYTE *)(v13 + 15) != 3 && (!v39 || v39 < v6->DeCommitFreeBlockThreshold) )
    {
LABEL_29:
      FreeSize = v12;
LABEL_30:
      FreeBlock = v10;
      goto LABEL_79;
    }
    if( !v39
      || (++v6->Counters.DeCommitOps,
          ZwFreeVirtualMemory((VOID *)0xFFFFFFFFFFFFFFFFi64, &BaseAddress, &RegionSize, 0x4000ui64) >= 0) )
    {
      if( !v54 )
      {
        v40 = (char *)BaseAddress + RegionSize;
        *(_WORD *)((char *)BaseAddress + RegionSize + 12) = v6->Encoding.UnpackedEntry.PreviousSize;
        if( (char *)v10 + v36 == (char *)BaseAddress + RegionSize )
        {
          if( v6->EncodeFlagMask )
          {
            v40[11] = v40[8] ^ v40[9] ^ v40[10];
            *((_DWORD *)v40 + 2) ^= v6->Encoding.UnpackedEntry.SubSegmentCode;
          }
        }
        else
        {
          v40[15] = 0;
          v40[10] = 0;
          v41 = ((unsigned __int64)v10 + v36 - RegionSize - (_QWORD)BaseAddress) >> 4;
          v32 = RtlpHeapErrorHandlerThreshold < 1;
          *((_WORD *)v40 + 4) = v41;
          if( !v32 && (unsigned __int16)v41 <= 1u )
          {
            DbgPrint("(LONG)FreeEntry->Size > 1");
            RtlpHeapHandleError(v42);
          }
          v40[11] = 0;
          v43 = p_Segment->Heap;
          if( v43 != (_HEAP *)p_Segment )
          {
            if( ((unsigned __int64)(v40 - (char *)p_Segment) >> 16) + 1 >= 0xFE )
            {
              RtlpLogHeapFailure(heap_failure_entry_corruption, v43, v40, p_Segment, 0i64);
              LOWORD(v41) = *((_WORD *)v40 + 4);
            }
            v4 = ((unsigned int)((_DWORD)v40 - (_DWORD)p_Segment) >> 16) + 1;
          }
          v40[14] = v4;
          RtlpInsertFreeBlock(v6, (_HEAP_FREE_ENTRY *)v40, (unsigned __int16)v41);
        }
      }
      RtlpCreateUCREntry(v6, p_Segment, (_HEAP_UCR_DESCRIPTOR *)BaseAddress - 1, RegionSize, v10, (UINT64 *)v51);
      FreeSize = v51[0];
      goto LABEL_30;
    }
    RtlpUpdateHeapRates(v6, 3ui64);
    v25 = v54 == 0;
LABEL_33:
    if( !v25 )
    {
      RtlpCreateUCREntry(v24, p_Segment, (_HEAP_UCR_DESCRIPTOR *)(v48 - 48), Size, v10, &FreeSizea);
      v12 = FreeSizea;
    }
    goto LABEL_29;
  }
  BaseAddress = v10;
  for( i = p_Segment->UCRSegmentList.Flink; &p_Segment->UCRSegmentList != i; i = i->Flink )
  {
    v17 = i - 1;
    v18 = (_HEAP_FREE_ENTRY *)((char *)i[1].Flink + (unsigned __int64)i[1].Blink);
    UCRBlock = (_HEAP_UCR_DESCRIPTOR *)&i[-1];
    if( v18 == v10 )
      goto LABEL_19;
  }
  v17 = 0i64;
  UCRBlock = 0i64;
LABEL_19:
  if( RtlpHeapErrorHandlerThreshold >= 1 && !v17 )
  {
    DbgPrint("(UCRBlock != NULL)");
    RtlpHeapHandleError(v19);
  }
  v20 = 16 * v12;
  if( v7 )
  {
    v21 = (__int64)v10 + v20;
    v51[0] = (__int64)v10 + v20;
  }
  else
  {
    v51[0] = (__int64)v10 + v20;
    v21 = (__int64)&v10[-1] + v20;
  }
  RegionSize = (v21 & 0xFFFFFFFFFFFFF000ui64) - (_QWORD)v10;
  if( !RegionSize )
  {
    if( RtlpHeapErrorHandlerThreshold >= 1 )
    {
      if( v7 )
      {
        DbgPrint("(!TrailingUCR)");
        RtlpHeapHandleError(v22);
      }
    }
    goto LABEL_29;
  }
  if( ZwFreeVirtualMemory((VOID *)0xFFFFFFFFFFFFFFFFi64, &BaseAddress, &RegionSize, 0x4000ui64) < 0 )
  {
    RtlpUpdateHeapRates(v6, 3ui64);
    v25 = v7 == 0;
    goto LABEL_33;
  }
  v26 = UCRBlock;
  ++v6->Counters.DeCommitOps;
  v27 = v26->Size;
  if( v27 >= 0xFF000 )
    v6->Counters.TotalMemoryLargeUCR -= v27;
  RtlpRemoveUCRBlock(v23);
  v26->Size += RegionSize;
  RtlpInsertUCRBlock(v6, v26);
  p_Segment->NumberOfUnCommittedPages += RegionSize >> 12;
  v28 = RegionSize;
  v6->Counters.TotalMemoryCommitted -= RegionSize;
  v29 = v26->Size;
  if( v29 >= 0xFF000 )
    v6->Counters.TotalMemoryLargeUCR += v29;
  if( !v7 )
  {
    v30 = (char *)BaseAddress + v28;
    *(_WORD *)((char *)BaseAddress + v28 + 12) = v6->Encoding.UnpackedEntry.PreviousSize;
    if( (VOID *)v51[0] != (char *)BaseAddress + RegionSize )
    {
      v30[15] = 0;
      v30[10] = 0;
      v31 = (v20 - RegionSize) >> 4;
      v32 = RtlpHeapErrorHandlerThreshold < 1;
      *((_WORD *)v30 + 4) = v31;
      if( !v32 && (unsigned __int16)v31 <= 1u )
      {
        DbgPrint("((LONG)FreeEntry->Size > 1)");
        RtlpHeapHandleError(v33);
      }
      v30[11] = 0;
      v34 = p_Segment->Heap;
      if( v34 != (_HEAP *)p_Segment )
      {
        if( ((unsigned __int64)(v30 - (char *)p_Segment) >> 16) + 1 >= 0xFE )
        {
          RtlpLogHeapFailure(heap_failure_entry_corruption, v34, v30, p_Segment, 0i64);
          LOWORD(v31) = *((_WORD *)v30 + 4);
        }
        v4 = ((unsigned int)((_DWORD)v30 - (_DWORD)p_Segment) >> 16) + 1;
      }
      v30[14] = v4;
      FreeBlock = (_HEAP_FREE_ENTRY *)v30;
      FreeSize = (unsigned __int16)v31;
      goto LABEL_79;
    }
    if( v6->EncodeFlagMask )
    {
      v30[11] = v30[8] ^ v30[9] ^ v30[10];
      *((_DWORD *)v30 + 2) ^= v6->Encoding.UnpackedEntry.SubSegmentCode;
    }
  }
}

Referenced by:

RtlpFreeHeap