HvSnapshotHiveToOffsetArray

NTSTATUS __stdcall HvSnapshotHiveToOffsetArray(_HHIVE *Hive, INT64 *a2, UINT8 **a3, UINT64 *a4){
  unsigned int v4; 
  unsigned int Length; 
  _HMAP_ENTRY *CellMap; 
  int v11; 
  int v12; 
  unsigned int v13; 
  unsigned int v14; 
  __int64 v15; 
  size_t v16; 
  VOID **PoolWithTag; 
  NTSTATUS v18; 
  unsigned int v19; 
  VOID **v20; 
  UINT8 *v21; 
  unsigned int v22; 
  _HBASE_BLOCK *v23; 
  int v24; 
  size_t *v25; 
  __int64 v26; 
  unsigned int v27; 
  unsigned int v28; 
  unsigned int v29; 
  int i; 
  unsigned int v31; 
  VOID **v32; 
  __int64 v33; 
  __int64 v34; 
  size_t v35; 
  size_t v36; 
  _HMAP_ENTRY *v37; 
  int v38; 
  size_t v39; 
  __int64 v40; 
  UINT8 *v41; 
  size_t *v43; 
  _HBASE_BLOCK *Src; 
  int Srca; 
  unsigned int v46; 
  __int64 v47; 
  int v48; 

  *a3 = 0i64;
  v4 = 0;
  *(_DWORD *)a2 = 0;
  Length = Hive->Storage[0].Length;
  Src = Hive->BaseBlock;
  if( Length )
  {
    while( 1 )
    {
      CellMap = HvpGetCellMap(Hive, v4);
      if( *(_DWORD *)(CellMap->PermanentBinAddress & 0xFFFFFFFFFFFFFFF0ui64) != 1852400232 )
        break;
      if( *(_DWORD *)((CellMap->PermanentBinAddress & 0xFFFFFFFFFFFFFFF0ui64) + 4) != v11 )
        break;
      v12 = *(_DWORD *)((CellMap->PermanentBinAddress & 0xFFFFFFFFFFFFFFF0ui64) + 8);
      v4 = v12 + v11;
      if( v4 > Length || (v12 & 0xFFF) != 0 )
        break;
      if( v4 >= Length )
        goto LABEL_7;
    }
    v18 = -1073741492;
    goto LABEL_35;
  }
LABEL_7:
  v13 = Length + 4096;
  v14 = (Length + 4096) >> 20;
  v15 = v14 + 1;
  if( ((Length + 4096) & 0xFFFFF) == 0 )
    v15 = v14;
  v16 = 24 * v15;
  PoolWithTag = ExAllocatePoolWithTag(1ui64, 24 * v15, 538987843i64);
  *a3 = (UINT8 *)PoolWithTag;
  if( PoolWithTag )
  {
    memset(PoolWithTag, 0i64, v16);
    *(_DWORD *)a4 = v13;
    v19 = 0x100000;
    if( v13 < 0x100000 )
      v19 = Length + 4096;
    v20 = ExAllocatePoolWithTag(1ui64, v19, 538987843i64);
    v21 = *a3;
    *((_QWORD *)*a3 + 1) = v20;
    if( v20 )
    {
      *(_DWORD *)v21 = 0;
      v22 = 4096;
      *((_DWORD *)v21 + 4) = v19;
      memmove(v20, Src, 0x1000u);
      v23 = (_HBASE_BLOCK *)*((_QWORD *)v21 + 1);
      v23->Sequence2 = v23->Sequence1;
      v23->Length = Length;
      v24 = HvpHeaderCheckSum(v23);
      v25 = 0i64;
      *(_DWORD *)(v26 + 508) = v24;
      v27 = Hive->Storage[0].Length;
      v28 = 0;
      v29 = 0;
      v46 = 0;
      Srca = 4096;
      *(_DWORD *)a2 = 1;
      v43 = 0i64;
      if( !v27 )
        return 0;
      for( i = 1; ; i = v48 )
      {
        v48 = i;
        if( v22 == v19 )
        {
          v31 = v27 - v28;
          v19 = 0x100000;
          if( v31 < 0x100000 )
            v19 = v31;
          v32 = ExAllocatePoolWithTag(1ui64, v19, 538987843i64);
          v33 = *(unsigned int *)a2;
          v21 = *a3;
          v34 = 3 * v33;
          *(_QWORD *)&(*a3)[24 * v33 + 8] = v32;
          if( !v32 )
            goto LABEL_10;
          i = v33 + 1;
          v25 = v43;
          v22 = 0;
          *(_DWORD *)&v21[8 * v34] = Srca;
          *(_DWORD *)&v21[8 * v34 + 16] = v19;
          v48 = i;
          *(_DWORD *)a2 = i;
        }
        if( v29 )
          break;
        v37 = HvpGetCellMap(Hive, v28);
        if( !v37 )
        {
          v18 = -1073741275;
          goto LABEL_35;
        }
        v43 = (size_t *)(v37->PermanentBinAddress & 0xFFFFFFFFFFFFFFF0ui64);
        v39 = v43[2];
        v29 = v19 - v22 < v39 ? v39 - (v19 - v22) : 0;
        if( v39 > v19 - v22 )
          v39 = v19 - v22;
        v47 = v39;
        memmove(
          (VOID *)(*(_QWORD *)&v21[24 * (v38 - 1) + 8] + v22),
          (const VOID *)(v37->PermanentBinAddress & 0xFFFFFFFFFFFFFFF0ui64),
          v39);
        v40 = v47;
        Srca += v47;
        v28 += v47;
        v22 += v47;
        v46 = v28;
        if( !v29 )
          goto LABEL_26;
        v25 = (size_t *)((char *)v43 + v40);
        v43 = (size_t *)((char *)v43 + v40);
LABEL_27:
        v27 = Hive->Storage[0].Length;
        if( v28 >= v27 )
          return 0;
      }
      v35 = v29;
      if( v29 > v19 )
        v35 = v19;
      v36 = v35;
      memmove(*(VOID **)&v21[24 * (i - 1) + 8], v25, v35);
      v46 += v36;
      v29 -= v36;
      v22 += v36;
      Srca += v36;
      v28 = v46;
LABEL_26:
      v25 = v43;
      goto LABEL_27;
    }
  }
LABEL_10:
  v18 = -1073741801;
LABEL_35:
  v41 = *a3;
  if( *a3 )
  {
    if( *(_DWORD *)a2 )
    {
      do
        ExFreePoolWithTag(*(PVOID *)&(*a3)[24 * --*(_DWORD *)a2 + 8], 0);
      while( *(_DWORD *)a2 );
      v41 = *a3;
    }
    ExFreePoolWithTag(v41, 0);
    *(_DWORD *)a2 = 0;
  }
  return v18;
}

Referenced by:

CmDumpKey
CmpFlushBackupHive