HvFreeHivePartial

INT64 __fastcall HvFreeHivePartial(UINT64 P2, UINT64 a2, INT64 a3){
  unsigned int v3; 
  unsigned int v4; 
  __int64 v5; 
  unsigned int v7; 
  INT64 result; 
  int v9; 
  unsigned int v10; 
  _BYTE *CellMap; 
  _BYTE *v12; 
  _QWORD *FreeBin; 
  void *v14; 
  _QWORD *v15; 
  __int64 v16; 
  _QWORD *v17; 
  __int64 v18; 
  UINT64 v19; 
  INT64 v20; 
  unsigned int v21; 
  UINT64 v22; 
  unsigned int v23; 
  unsigned int v24; 
  int v25; 
  void *BugCheckParameter4; 
  unsigned int v27; 
  v3 = a3;
  v4 = a2;
  v5 = 632i64 * (int)a3;
  v7 = a2;
  result = *(unsigned int *)(v5 + P2 + 272);
  v27 = result;
  if( (_DWORD)a2 != (_DWORD)result )
  {
    v9 = (_DWORD)a3 << 31;
    do
    {
      v10 = v7 + v9;
      CellMap = (_BYTE *)HvpGetCellMap(P2, v7 + v9);
      v12 = CellMap;
      if( !CellMap )
        KeBugCheckEx(0x51u, 1ui64, P2, v10, 0x165ui64);
      FreeBin = (_QWORD *)HvpMapEntryGetFreeBin(CellMap);
      v15 = FreeBin;
      if( FreeBin )
      {
        v16 = *FreeBin;
        if( *(_QWORD **)(*FreeBin + 8i64) != FreeBin || (v17 = (_QWORD *)FreeBin[1], (_QWORD *)*v17 != v15) )
          __fastfail(3u);
        *v17 = v16;
        *(_QWORD *)(v16 + 8) = v17;
        (*(void(__fastcall **)(_QWORD *, __int64))(P2 + 32))(v15, 24i64);
      }
      v18 = *((_QWORD *)v12 + 1);
      v19 = *((unsigned int *)v12 + 4);
      if( (v18 & 8) != 0 )
        HvpFreeBin((_HHIVE *)P2, v19, (HSTORAGE_TYPE)(v18 & 0xFFFFFFF0), v14, BugCheckParameter4);
      else
        CmpReleaseGlobalQuota(v19);
      v7 += *((_DWORD *)v12 + 4);
      do
      {
        v20 = HvpGetCellMap(P2, v10);
        if( !v20 )
          KeBugCheckEx(0x51u, 1ui64, P2, v10, 0x19Eui64);
        v10 += 4096;
        *(_OWORD *)v20 = 0i64;
        *(_QWORD *)(v20 + 16) = 0i64;
      }
      while( v10 - v9 < v7 );
    }
    while( v7 < v27 );
    if( v4 )
      v21 = (v4 - 1) >> 21;
    else
      v21 = -1;
    HvpFreeMap(P2, *(_QWORD *)(v5 + P2 + 280), v21 + 1, (unsigned int)((*(_DWORD *)(v5 + P2 + 272) >> 12) - 1) >> 9);
    if( !v3 )
    {
      CmpUpdateSystemHiveHysteresis(P2, v4 & 0x7FFFFFFF, *(unsigned int *)(v5 + P2 + 272));
      if( (*(_DWORD *)(P2 + 160) & 0x20000) != 0 )
        HvpViewMapShrinkStorage(P2 + 216, v4 & 0x7FFFFFFF);
    }
    v22 = v4 & 0x7FFFFFFF;
    *(_DWORD *)(v5 + P2 + 272) = v22;
    if( !v3 )
    {
      v23 = v4 >> 9;
      v24 = *(_DWORD *)(P2 + 88) - v23;
      RtlClearBits((RTL_BITMAP *)(P2 + 88), v23, v24);
      RtlClearBits((RTL_BITMAP *)(P2 + 112), v23, v24);
      *(_QWORD *)(P2 + 96) = *(_QWORD *)(P2 + 96);
      *(_DWORD *)(P2 + 88) = v23;
      *(_QWORD *)(P2 + 120) = *(_QWORD *)(P2 + 120);
      *(_DWORD *)(P2 + 112) = v23;
      v25 = *(_DWORD *)(P2 + 104);
      *(_DWORD *)(P2 + 104) = RtlNumberOfSetBits((PRTL_BITMAP)(P2 + 88));
      *(_DWORD *)(P2 + 128) = RtlNumberOfSetBits((PRTL_BITMAP)(P2 + 112));
      _InterlockedExchangeAdd(&CmpDirtySectorCount, *(_DWORD *)(P2 + 104) - v25);
      v22 = *(unsigned int *)(v5 + P2 + 272);
    }
    return HvpAdjustHiveFreeDisplay(P2, v22, v3);
  }
  return result;
}

Referenced by:

HvpPerformLogFileRecovery
HvpTruncateBins