HvHiveCleanup

VOID **__fastcall HvHiveCleanup(INT64 a1){
  unsigned int v1; 
  int v3; 
  unsigned int v4; 
  __int64 v5; 
  unsigned int v6; 
  unsigned int i; 
  _HMAP_ENTRY *CellMap; 
  _HMAP_ENTRY *v9; 
  _QWORD *FreeBin; 
  unsigned __int64 PermanentBinAddress; 
  VOID *v12; 
  _QWORD *v13; 
  unsigned int MemAlloc; 
  _HMAP_DIRECTORY *v15; 
  __int64 v16; 
  void *v17; 
  void *v18; 
  __int64 v20; 
  _QWORD *v21; 
  VOID *v22; 

  *(_DWORD *)(a1 + 160) &= ~1u;
  v1 = 0;
  v3 = *(_DWORD *)(a1 + 160) & 0x10;
  v4 = 0;
  do
  {
    v5 = 632i64 * v1;
    if( *(_QWORD *)(v5 + a1 + 280) )
    {
      v6 = v4 + *(_DWORD *)(v5 + a1 + 272);
      if( v6 != v4 )
      {
        for( i = v4; i < v6; i += v9->MemAlloc )
        {
          CellMap = HvpGetCellMap((_HHIVE *)a1, i);
          v9 = CellMap;
          if( !CellMap->PermanentBinAddress )
            break;
          FreeBin = (_QWORD *)HvpMapEntryGetFreeBin(CellMap);
          v13 = FreeBin;
          if( FreeBin )
          {
            v20 = *FreeBin;
            if( *(_QWORD **)(*FreeBin + 8i64) != FreeBin || (v21 = (_QWORD *)FreeBin[1], (_QWORD *)*v21 != v13) )
              __fastfail(3u);
            *v21 = v20;
            *(_QWORD *)(v20 + 8) = v21;
            (*(void(__fastcall **)(_QWORD *, __int64))(a1 + 32))(v13, 24i64);
            PermanentBinAddress = v9->PermanentBinAddress;
          }
          MemAlloc = v9->MemAlloc;
          if( (PermanentBinAddress & 8) != 0 )
            HvpFreeBin((_HHIVE *)a1, MemAlloc, (VOID *)(PermanentBinAddress & 0xFFFFFFFFFFFFFFF0ui64), v12, v22);
          else
            CmpReleaseGlobalQuota(MemAlloc);
        }
        v15 = *(_HMAP_DIRECTORY **)(v5 + a1 + 280);
        HvpFreeMap((_HHIVE *)a1, v15, 0i64, (unsigned int)((*(_DWORD *)(v5 + a1 + 272) >> 12) - 1) >> 9);
        if( v15 != (_HMAP_DIRECTORY *)(v5 + a1 + 288) )
        {
          CmpReleaseGlobalQuota(0x2000u);
          ExFreePoolWithTag(v15, 0);
        }
        *(_QWORD *)(v5 + a1 + 280) = 0i64;
        *(_DWORD *)(v5 + a1 + 272) = 0;
      }
    }
    ++v1;
    v4 += 0x80000000;
  }
  while( v1 < 2 );
  if( v3 && _InterlockedExchangeAdd(&CmpPreloadedHivesCount, 0xFFFFFFFF) == 1 )
    CmpFreeBootRegistry();
  v16 = *(_QWORD *)(a1 + 64);
  if( v16 )
  {
    (*(void(__fastcall **)(__int64, _QWORD))(a1 + 32))(v16, *(unsigned int *)(a1 + 132));
    *(_QWORD *)(a1 + 64) = 0i64;
  }
  v17 = *(void **)(a1 + 96);
  if( v17 )
  {
    CmpReleaseGlobalQuota(*(_DWORD *)(a1 + 108));
    ExFreePoolWithTag(v17, 0);
    *(_QWORD *)(a1 + 96) = 0i64;
  }
  v18 = *(void **)(a1 + 120);
  if( v18 )
  {
    CmpReleaseGlobalQuota(*(_DWORD *)(a1 + 108));
    ExFreePoolWithTag(v18, 0);
    *(_QWORD *)(a1 + 120) = 0i64;
  }
  HvpViewMapCleanup(a1 + 216);
  return HvpFreeHiveFreeDisplay(a1);
}

Referenced by:

CmShutdownSystem
CmpCompleteUnloadKey
CmpDestroyHive