HvpAddBin

UINT64 __stdcall HvpAddBin(_HHIVE *Hive, UINT64 NewSize, HSTORAGE_TYPE Type){
  __int64 v3; 
  int v4; 
  unsigned int v5; 
  unsigned int v7; 
  __int64 v8; 
  _LIST_ENTRY *p_FreeBins; 
  _LIST_ENTRY *i; 
  unsigned int Length; 
  unsigned int v12; 
  unsigned int v13; 
  INT8 v14; 
  unsigned int HiveFlags; 
  __int64 SectionEndFileOffset; 
  signed __int64 v17; 
  int v18; 
  char v19; 
  INT64 v20; 
  int v21; 
  _DWORD *v22; 
  INT64 v23; 
  int v24; 
  CHAR v25; 
  unsigned int Flink; 
  char v28; 
  _LIST_ENTRY *v29; 
  _LIST_ENTRY *Blink; 
  int v31; 
  __int64 v32; 
  INT64 CellMap; 
  unsigned int v34; 
  unsigned int v35; 
  _QWORD *v36; 
  __int64 v37; 
  char v38; 
  int v39; 
  _DWORD *v40; 
  _DWORD *v41; 
  INT64 *v42; 
  _LIST_ENTRY *v43; 
  INT64 v44; 
  INT64 v45; 
  void *v46; 
  unsigned int DirtyCount; 
  unsigned int v48; 
  unsigned int *Buffer; 
  _LIST_ENTRY *v50; 
  void *BugCheckParameter4; 
  char v52; 
  unsigned int j; 
  size_t Size; 
  INT64 a4; 
  INT64 result; 
  INT64 v57; 
  unsigned __int64 v58; 
  _LIST_ENTRY *v59; 
  CHAR v60; 
  char v61; 
  char v62; 
  CHAR v63; 
  v3 = Type;
  v4 = -1;
  Size = 0i64;
  j = -1;
  v5 = (NewSize + 4127) & 0xFFFFF000;
  v52 = 0;
  a4 = 0i64;
  v57 = 0i64;
  v7 = 0;
  result = 0i64;
  v62 = 0;
  v61 = 0;
  if( v5 <= 0x3000 && v5 - (unsigned __int64)(unsigned int)NewSize - 32 < 0xE00 )
    v5 += 4096;
  v8 = Type;
  p_FreeBins = &Hive->Storage[v3].FreeBins;
  v58 = 632 * v3;
  v59 = p_FreeBins;
  for( i = p_FreeBins->Flink; ; i = i->Flink )
  {
    if( i == p_FreeBins )
    {
      i = 0i64;
      goto LABEL_7;
    }
    Flink = (unsigned int)i[1].Flink;
    if( Flink >= v5 && Flink + HIDWORD(i[1].Flink) <= Hive->Storage[v8].Length )
      break;
  }
  v7 = (unsigned int)i[1].Flink;
LABEL_7:
  if( i )
  {
    v29 = i->Flink;
    if( i->Flink->Blink != i )
      goto LABEL_93;
    Blink = i->Blink;
    if( Blink->Flink != i )
      goto LABEL_93;
    Blink->Flink = v29;
    v29->Blink = Blink;
    v31 = (_DWORD)v3 << 31;
    if( HvpMarkDirty((INT64)Hive, (unsigned int)(v31 + HIDWORD(i[1].Flink)), LODWORD(i[1].Flink)) )
    {
      v32 = 0i64;
      v4 = v31 + HIDWORD(i[1].Flink);
      for( j = v4; (unsigned int)v32 < v7; *v36 = v37 )
      {
        CellMap = HvpGetCellMap((INT64)Hive, (unsigned int)(v32 + v4));
        v36 = (_QWORD *)CellMap;
        if( !CellMap )
          KeBugCheckEx(0x51u, 1ui64, (ULONG_PTR)Hive, v35, 0x267ui64);
        *(_QWORD *)(CellMap + 8) &= ~2ui64;
        v37 = v34;
        v32 = v34 + 4096;
      }
    }
LABEL_55:
    if( !i )
      return j;
    if( v4 != -1 )
    {
      ((void(__fastcall *)(_LIST_ENTRY *, __int64, __int64))Hive->Free)(i, 24i64, v32);
      return j;
    }
    v50 = p_FreeBins->Flink;
    if( p_FreeBins->Flink->Blink == p_FreeBins )
    {
      i->Flink = v50;
      i->Blink = p_FreeBins;
      v50->Blink = i;
      p_FreeBins->Flink = i;
      return j;
    }
LABEL_93:
    __fastfail(3u);
  }
  Length = Hive->Storage[v8].Length;
  v12 = Length;
  v13 = Length + v5;
  if( !(_DWORD)v3 && v5 <= 0x40000 && (((Length + 4096) ^ (v13 + 4095)) & 0xFFFC0000) != 0 )
  {
    v12 = ((Length + 266239) & 0xFFFC0000) - 4096;
    LODWORD(Size) = v12 - Length;
    v13 = v12 + v5;
  }
  if( v13 < Length
    || !CmpCanGrowHive((INT64)Hive, v13)
    || HvpExpandMap((INT8 *)Hive, (INT8 *)(unsigned int)v3, Length) < 0 )
  {
    return j;
  }
  Hive->Storage[v58 / 0x278].Length = v13;
  if( (int)HvpAdjustHiveFreeDisplay((INT64)Hive, v13, (unsigned int)v3) < 0 )
  {
LABEL_77:
    HvpShrinkMap((INT64)Hive, (unsigned int)v3, v13, Length);
    Hive->Storage[v58 / 0x278].Length = Length;
    if( v52 )
    {
      Hive->DirtyVector.Buffer = Hive->DirtyVector.Buffer;
      Hive->DirtyVector.SizeOfBitMap = Length >> 9;
      DirtyCount = Hive->DirtyCount;
      v48 = RtlNumberOfSetBits(&Hive->DirtyVector);
      Hive->DirtyCount = v48;
      _InterlockedExchangeAdd(&CmpDirtySectorCount, v48 - DirtyCount);
      Buffer = Hive->UnreconciledVector.Buffer;
      Hive->UnreconciledVector.SizeOfBitMap = Length >> 9;
      Hive->UnreconciledVector.Buffer = Buffer;
      Hive->UnreconciledCount = RtlNumberOfSetBits(&Hive->UnreconciledVector);
    }
    if( v61 )
      HvpViewMapShrinkStorage((UINT64)&Hive->ViewMap, Length);
    if( a4 && !v62 )
      HvpFreeBin(Hive, v12 - Length, (HSTORAGE_TYPE)a4, v46, BugCheckParameter4);
    if( v57 )
      Hive->Free((void *)v57, 24u);
    if( result && !v62 )
      HvpFreeBin(Hive, v13 - v12, (HSTORAGE_TYPE)result, v46, BugCheckParameter4);
    if( !HIDWORD(Size) )
      return j;
    CmpReleaseGlobalQuota(HIDWORD(Size));
    p_FreeBins = v59;
    v4 = -1;
    goto LABEL_55;
  }
  v60 = 1;
  v63 = 1;
  if( (_DWORD)v3 )
    goto LABEL_31;
  HiveFlags = Hive->HiveFlags;
  if( (HiveFlags & 1) == 0 )
  {
    if( (int)HvpGrowDirtyVectors((INT64)Hive, v13) < 0 )
      goto LABEL_76;
    HiveFlags = Hive->HiveFlags;
    v52 = 1;
  }
  if( (HiveFlags & 0x8001) == 0 )
  {
    if( (int)CmpDoFileSetSizeEx((INT64)Hive, 0i64, v13 + 4096, 1) < 0 )
      goto LABEL_76;
    if( (Hive[2].Storage[1].FreeDisplay[6].RealVectorSize & 0x800) != 0
      && !HIDWORD(Hive[2].Storage[1].FreeDisplay[10].Display.Buffer) )
    {
      HIDWORD(Hive[2].Storage[1].FreeDisplay[10].Display.Buffer) = Length;
    }
  }
  v60 = 1;
  v63 = 1;
  if( (Hive->HiveFlags & 0x20000) == 0 )
    goto LABEL_31;
  if( (Hive->ViewMap.Flags & 1) != 0 )
    SectionEndFileOffset = Hive->ViewMap.SectionEndFileOffset;
  else
    SectionEndFileOffset = 0x7FFFFFFFFFFFFFFFi64;
  v17 = SectionEndFileOffset & 0xFFFFFFFFFFFFF000ui64;
  v60 = 1;
  v14 = 0;
  v63 = 1;
  if( v17 >= 2147479552 )
    LODWORD(v17) = 2147479552;
  if( v13 > (int)v17 - 4096 )
  {
LABEL_31:
    v19 = 0;
  }
  else
  {
    HvpViewMapExtendStorage((INT64)&Hive->ViewMap, v13);
    if( v18 < 0 )
      goto LABEL_76;
    v19 = 1;
    v60 = 0;
    v62 = 1;
    v63 = 0;
  }
  if( (_DWORD)Size )
  {
    if( v19 )
    {
      v61 = v19;
      CmpClaimGlobalQuota((unsigned int)Size, v14);
      if( !v38 )
        goto LABEL_76;
      v61 = v62;
      HIDWORD(Size) = Size;
      if( (int)HvpViewMapPromoteRangeToMapping((UINT64)&Hive->ViewMap, Length, (unsigned int)Size, &a4) < 0 )
        goto LABEL_76;
      v61 = v62;
      v39 = HvpViewMapCOWAndUnsealRange((INT64)&Hive->ViewMap, Length, (unsigned int)Size);
    }
    else
    {
      v61 = 0;
      if( (int)HvpAllocateBin((INT64)Hive, (unsigned int)Size, (unsigned int)v3, 0x30324D43ui64, &a4) < 0 )
        goto LABEL_76;
      v61 = 0;
      v39 = HvpProtectBin(v45, (unsigned int)Size, (VOID *)a4, 1);
    }
    if( v39 < 0 )
      goto LABEL_76;
    memset(a4, 0i64);
    v40 = (_DWORD *)a4;
    *(_DWORD *)(a4 + 28) = 0;
    v40[1] = Length & 0x7FFFFFFF;
    v40[2] = Size;
    v40[8] = Size - 32;
    *v40 = 1852400232;
    v41 = Hive->Allocate(24i64, 0i64, 825380163i64);
    v19 = v62;
    v14 = (char)v41;
    v61 = v62;
    v57 = (INT64)v41;
    if( !v41 )
      goto LABEL_76;
    v41[4] = Size;
    v41[5] = Length;
  }
  if( !v19 )
  {
    v61 = 0;
    if( (int)HvpAllocateBin((INT64)Hive, v5, (unsigned int)v3, 0x36314D43ui64, &result) >= 0 )
    {
      v61 = 0;
      v21 = HvpProtectBin(v20, v5, (VOID *)result, 1);
      goto LABEL_36;
    }
LABEL_76:
    HvpAdjustHiveFreeDisplay((INT64)Hive, Length, (unsigned int)v3);
    goto LABEL_77;
  }
  v61 = v19;
  CmpClaimGlobalQuota(v5, v14);
  if( !v28 )
    goto LABEL_76;
  HIDWORD(Size) += v5;
  v61 = v62;
  if( (int)HvpViewMapPromoteRangeToMapping((UINT64)&Hive->ViewMap, v12, v5, &result) < 0 )
    goto LABEL_76;
  v61 = v62;
  v21 = HvpViewMapCOWAndUnsealRange((INT64)&Hive->ViewMap, v12, v5);
LABEL_36:
  if( v21 < 0 )
    goto LABEL_76;
  memset(result, 0i64);
  v22 = (_DWORD *)result;
  v23 = a4;
  *(_DWORD *)(result + 28) = 0;
  v22[1] = v12 & 0x7FFFFFFF;
  v22[8] = v5 - 32;
  v24 = (_DWORD)v3 << 31;
  *v22 = 1852400232;
  v22[2] = v5;
  if( v23 )
  {
    HvpPointMapEntriesToBuffer((UINT64)Hive, v23, v12 - Length, v24 + Length, v60, v57);
    v42 = (INT64 *)v59;
    v43 = v59->Flink;
    if( v59->Flink->Blink != v59 )
      goto LABEL_93;
    v44 = v57;
    *(_QWORD *)v57 = v43;
    *(_QWORD *)(v44 + 8) = v42;
    v43->Blink = (_LIST_ENTRY *)v44;
    v22 = (_DWORD *)result;
    *v42 = v44;
    v24 = (_DWORD)v3 << 31;
    v25 = v60;
  }
  else
  {
    v25 = v63;
  }
  v12 += v24;
  HvpPointMapEntriesToBuffer((UINT64)Hive, (INT64)v22, v5, v12, v25, 0i64);
  if( !(_DWORD)v3 )
  {
    if( (Hive->HiveFlags & 1) != 0 || (v61 = v62, HvpMarkDirty((INT64)Hive, Length, v13 - Length)) )
    {
      CmpUpdateSystemHiveHysteresis((INT64)Hive, v13, Length);
      HvpSetRangeProtection(Hive, Length, v13 - Length, 4ui64);
      return v12;
    }
    goto LABEL_76;
  }
  return v12;
}

Referenced by:

HvpDoAllocateCell