RtlpFreeHeapInternal

NTSTATUS __fastcall RtlpFreeHeapInternal(
        VOID *HeapHandle,
        VOID *BaseAddress,
        INT64 Flags,
        UINT64 *UserSize,
        UINT16 *Tag,
        VOID *a6,
        INT64 a7,
        INT64 a8){
  NTSTATUS v8; 
  int v9; 
  NTSTATUS v12; 
  NTSTATUS v13; 
  _HEAP_ENTRY *v15; 
  VOID *v16; 
  _HEAP_FAILURE_TYPE v17; 
  unsigned int SubSegmentCode; 
  int v19; 
  unsigned __int16 Size; 
  unsigned int v21; 
  unsigned __int16 v22; 
  __int64 v23; 
  int v24; 
  int v25; 
  int v26; 
  int v27; 
  int v28; 
  INT64 a5; 

  a5 = (INT64)UserSize;
  v8 = 0;
  v9 = Flags;
  if( *((_DWORD *)HeapHandle + 4) == -857879331 )
  {
    LODWORD(a5) = 0;
    v12 = RtlpHpConvertFlagsToSegmentFlags((unsigned int)Flags);
    RtlpHpVsContextFree(
      (INT64 *)HeapHandle + 8,
      0i64,
      BaseAddress,
      *((_DWORD *)HeapHandle + 5) | (unsigned int)v12,
      (INT64)&a5);
    return v13;
  }
  if( (*((_DWORD *)HeapHandle + 30) & 1) != 0 )
  {
    v15 = RtlpProbeUserBufferSafe((_HEAP *)HeapHandle, BaseAddress);
  }
  else
  {
    if( ((unsigned __int8)BaseAddress & 0xF) != 0 )
    {
      v16 = BaseAddress;
      v17 = heap_failure_invalid_argument;
    }
    else
    {
      v15 = (_HEAP_ENTRY *)((char *)BaseAddress - 16);
      _m_prefetchw((char *)BaseAddress - 16);
      if( *((char *)BaseAddress - 1) == 5 )
        v15 -= v15->UnpackedEntry.SegmentOffset;
      if( (v15->UnpackedEntry.UnusedBytes & 0x3F) != 0 )
        goto LABEL_13;
      v16 = v15;
      v17 = heap_failure_block_not_busy;
    }
    RtlpLogHeapFailure(v17, HeapHandle, v16, 0i64, 0i64);
    v15 = 0i64;
  }
LABEL_13:
  if( !v15 )
    return v8;
  if( *((char *)BaseAddress - 1) != 5 )
    return(unsigned __int8)RtlpFreeHeap((_HEAP *)HeapHandle, v9 | 2u, v15, UserSize);
  if( !*((_DWORD *)HeapHandle + 31) )
    goto LABEL_21;
  v26 = v15->UnpackedEntry.SubSegmentCode ^ *((_DWORD *)HeapHandle + 34);
  if( HIBYTE(v26) != ((unsigned __int8)v26 ^ (unsigned __int8)(BYTE1(v26) ^ BYTE2(v26))) )
  {
LABEL_34:
    RtlpLogHeapFailure(heap_failure_entry_corruption, HeapHandle, v15, BaseAddress, 0i64);
    return v8;
  }
  if( *((_DWORD *)HeapHandle + 31) )
  {
    SubSegmentCode = v15->UnpackedEntry.SubSegmentCode;
    v19 = *((_DWORD *)HeapHandle + 31);
    LOWORD(v27) = SubSegmentCode;
    if( (v19 & SubSegmentCode) != 0 )
      v27 = *((_DWORD *)HeapHandle + 34) ^ SubSegmentCode;
    Size = v27;
  }
  else
  {
LABEL_21:
    Size = v15->UnpackedEntry.Size;
    v19 = 0;
  }
  if( v15->UnpackedEntry.UnusedBytes == 4 )
  {
    if( v19 )
    {
      v21 = v15->UnpackedEntry.SubSegmentCode;
      LOWORD(v28) = v21;
      if( (v21 & *((_DWORD *)HeapHandle + 31)) != 0 )
        v28 = *((_DWORD *)HeapHandle + 34) ^ v21;
      v22 = v28;
    }
    else
    {
      v22 = v15->UnpackedEntry.Size;
    }
    v23 = (__int64)v15[-1].UnpackedEntry.PreviousBlockPrivateData + Size - v22;
  }
  else
  {
    v23 = 16i64 * Size;
  }
  if( (char *)v15 + v23 < BaseAddress )
    goto LABEL_34;
  v24 = *((_DWORD *)BaseAddress - 2);
  if( (v9 & 0x3C000102) != 0 )
    return(unsigned __int8)RtlpFreeHeap((_HEAP *)HeapHandle, v9 | 2u, v15, UserSize);
  UserSize = *((char *)BaseAddress - 1) == 5 ? (UINT64 *)((char *)BaseAddress
                                                        - 16 * (unsigned __int8)*((char *)BaseAddress - 2)) : 0i64;
  v25 = v24 && (_WORD)v24 == 1 ? ((__int64(__fastcall *)(VOID *, VOID *, __int64, UINT64 *))RtlpInterceptorRoutines.QuadPart)(
                                   HeapHandle,
                                   BaseAddress,
                                   3i64,
                                   UserSize) : -1073741823;
  if( v25 >= 0 )
    return(unsigned __int8)RtlpFreeHeap((_HEAP *)HeapHandle, v9 | 2u, v15, UserSize);
  return v8;
}

Referenced by:

RtlpHpFreeWithExceptionProtection