CmRestoreKey

__int64 __fastcall CmRestoreKey(_QWORD *a1, void *a2, int a3, KPROCESSOR_MODE a4){
  char v4; 
  __int64 v8; 
  UINT64 v9; 
  UINT64 v10; 
  int Hive; 
  char v12; 
  int HiveVolatile; 
  unsigned int v14; 
  __int64 v15; 
  unsigned int v16; 
  __int64 v17; 
  unsigned int v18; 
  unsigned int v19; 
  unsigned int v20; 
  UINT64 v21; 
  UINT8 *v22; 
  INT64 v23; 
  __int64 v24; 
  void(__fastcall *v25)(UINT64, INT64 *); 
  char v26; 
  INT64 v27; 
  INT64 v28; 
  INT64 v29; 
  int v30; 
  INT64 v31; 
  unsigned int v32; 
  bool v33; 
  unsigned int v34; 
  __int64 v35; 
  __int64 v36; 
  int *v37; 
  __int64 v38; 
  unsigned int v39; 
  void(__fastcall *v40)(UINT64, int *); 
  _WORD *v41; 
  unsigned int v42; 
  int *v43; 
  _WORD *v44; 
  CHAR v45; 
  __int64 v46; 
  unsigned int v47; 
  __int64 v48; 
  _DWORD *v49; 
  _DWORD *v50; 
  __int64 v51; 
  unsigned int v52; 
  __int64 v53; 
  __int64 v54; 
  __int64 v55; 
  __int64 v56; 
  int v57; 
  int v58; 
  UNICODE_STRING *v59; 
  UINT8 v60; 
  __int64 v61; 
  unsigned int v62; 
  INT64 a5; 
  CHAR a6; 
  INT64 a6a; 
  INT64 a7; 
  UINT64 Flags; 
  char v70; 
  unsigned int a2a; 
  unsigned int a2_4; 
  int a1a; 
  __int64 v74; 
  unsigned int v75; 
  int v76[2]; 
  int v77[2]; 
  PVOID P; 
  INT64 v79; 
  int v80[2]; 
  UINT64 v81[2]; 
  unsigned int NodeCell; 
  unsigned int NodeCell_4; 
  INT64 v84; 
  unsigned int v85; 
  unsigned int v86; 
  int v87[2]; 
  int v88[2]; 
  INT64 a4a[2]; 
  LIST_ENTRY v90; 
  _WORD *v91; 
  INT64 v92[5]; 
  INT64 result[54]; 
  v75 = a3;
  v4 = 0;
  v91 = 0i64;
  v88[1] = 0;
  v79 = 0i64;
  v88[0] = -1;
  v84 = 0xFFFFFFFFi64;
  v76[0] = -1;
  v77[0] = -1;
  v80[0] = -1;
  v8 = 0i64;
  v76[1] = 0;
  v77[1] = 0;
  P = 0i64;
  v80[1] = 0;
  memset(v92, 0, 32);
  v90 = 0i64;
  memset((INT64)result, 0i64);
  a1a = 0;
  *(_OWORD *)a4a = 0i64;
  *(_OWORD *)v81 = 0i64;
  CmpInitializeDelayDerefContext(a4a);
  v9 = a1[1];
  v10 = *(_QWORD *)(v9 + 32);
  if( (*(_DWORD *)(v10 + 160) & 0x100000) != 0 )
  {
    Hive = -1073741790;
    goto LABEL_119;
  }
  CmpTraceHiveRestoreStart(a2, (unsigned int)a3);
  if( (a3 & 0xFFFFFFFD) != 0 && (a3 & 2) != 0 || a1[7] || a1[8] )
  {
    Hive = -1073741811;
    goto LABEL_119;
  }
  v12 = 1;
  if( (v75 & 1) != 0 )
  {
    HiveVolatile = CmpLoadHiveVolatile((__int64)a1, a2);
LABEL_8:
    Hive = HiveVolatile;
    goto LABEL_119;
  }
  if( (v75 & 2) != 0 )
  {
    HiveVolatile = CmpRefreshHive((__int64)a1);
    goto LABEL_8;
  }
  v90.Blink = &v90;
  v92[0] = (INT64)a2;
  v90.Flink = &v90;
  LODWORD(Flags) = 17825793;
  memset(&v92[1], 0, 24);
  Hive = CmpCreateHive(
           (INT64)&P,
           2ui64,
           0x8000ui64,
           0i64,
           0i64,
           (INT64)v92,
           0i64,
           Flags,
           0i64,
           0i64,
           0i64,
           (INT64)result);
  if( Hive < 0 )
    goto LABEL_119;
  CmpLockRegistryFreezeAware(0);
  v4 = 1;
  CmpLockKcbShared((_CM_KEY_CONTROL_BLOCK *)v9);
  v14 = *(_DWORD *)(v9 + 40);
  a2a = v14;
  if( *(_WORD *)(v9 + 66) )
  {
    CmpLogUnsupportedOperation(17i64);
    Hive = -1073741822;
LABEL_117:
    CmpUnlockKcb(v9);
    goto LABEL_119;
  }
  if( CmpIsKeyDeletedForKeyBody((__int64)a1, 0i64) )
  {
    Hive = -1073741535;
    goto LABEL_117;
  }
  if( *(_BYTE *)(v9 + 65) == 1 || v10 == CmpMasterHive )
  {
    Hive = -1073741790;
    goto LABEL_117;
  }
  if( *(_BYTE *)(v10 + 2936) == 1 )
  {
    Hive = -1073741431;
    goto LABEL_117;
  }
  HvLockHiveFlusherShared(v10);
  v70 = 1;
  v15 = (*(__int64(__fastcall **)(UINT64, _QWORD, int *))(v10 + 8))(v10, v14, v76);
  v74 = v15;
  v8 = v15;
  if( !v15
    || ((*(_BYTE *)(v15 + 2) & 4) == 0 ? (v16 = *(_DWORD *)(v15 + 16)) : (v16 = -1),
        LODWORD(a7) = v14 >> 31,
        NodeCell = v16,
        v17 = *((_QWORD *)P + 8),
        v85 = v14 >> 31,
        v18 = CmpCopyKeyPartial((UINT64)P, *(unsigned int *)(v17 + 36), v10, v16, 6, a6, a7),
        NodeCell_4 = v18,
        v18 == -1) )
  {
    Hive = -1073741670;
    goto LABEL_115;
  }
  v19 = HvReallocateCell(v10, v18, (unsigned int)*(unsigned __int16 *)(v8 + 72) + 76, 1, &v79, &v84);
  a2_4 = v19;
  v20 = v19;
  if( v19 == -1 )
  {
    Hive = -1073741670;
    goto LABEL_112;
  }
  v21 = *(unsigned __int16 *)(v8 + 72);
  v22 = (UINT8 *)(v8 + 76);
  v23 = v79;
  NodeCell_4 = v19;
  memmove((UINT8 *)(v79 + 76), v22, v21);
  v24 = v74;
  *(_WORD *)(v23 + 72) = *(_WORD *)(v74 + 72);
  if( (*(_BYTE *)(v24 + 2) & 0x20) != 0 )
    *(_WORD *)(v23 + 2) |= 0x20u;
  else
    *(_WORD *)(v79 + 2) &= ~0x20u;
  LODWORD(a6a) = 0;
  if( !CmpCopySyncTree((UINT64)P, *(unsigned int *)(*((_QWORD *)P + 8) + 36i64), v10, v20, 2, a6a) )
  {
    v8 = v74;
    Hive = -1073741670;
LABEL_112:
    v62 = NodeCell_4;
    if( CmpDeleteTree(v10, NodeCell_4) )
      CmpFreeKeyByCell((_HHIVE *)v10, v62, 0);
    v12 = v70;
    if( !v70 )
    {
LABEL_116:
      if( !v12 )
        goto LABEL_119;
      goto LABEL_117;
    }
LABEL_115:
    HvUnlockHiveFlusherShared(v10);
    goto LABEL_116;
  }
  HvUnlockHiveFlusherShared(v10);
  v70 = 0;
  CmpUnlockKcb(v9);
  CmpUnlockRegistry();
  (*(void(__fastcall **)(UINT64, int *))(v10 + 16))(v10, v76);
  v25 = *(void(__fastcall **)(UINT64, INT64 *))(v10 + 16);
  v74 = 0i64;
  v8 = 0i64;
  v25(v10, &v84);
  v79 = 0i64;
  CmpLockRegistryFreezeAware(1u);
  while( 1 )
  {
    v26 = 0;
    if( (CmpShutdownRundown & 1) != 0 )
    {
LABEL_110:
      Hive = -1073741431;
      goto LABEL_111;
    }
    if( CmpIsKeyDeletedForKeyBody((__int64)a1, 0i64) )
      goto LABEL_60;
    if( a2a != *(_DWORD *)(v9 + 40) )
    {
      Hive = -1073741444;
      goto LABEL_111;
    }
    if( (*(_DWORD *)(v9 + 8) & 0x40000) != 0 )
    {
      Hive = -1073740763;
      goto LABEL_111;
    }
    if( *(_BYTE *)(v10 + 2936) == 1 )
      goto LABEL_110;
    if( NodeCell != -1 )
    {
      Hive = CmpCheckKeyAccess((_HHIVE *)v10, NodeCell, a4, 4ui64);
      if( Hive < 0 )
        goto LABEL_111;
    }
    Hive = CmpCheckKeyAccess((_HHIVE *)v10, a2a, a4, 0x10000ui64);
    if( Hive < 0 )
      goto LABEL_111;
    Hive = CmpTryAcquireKcbIXLocks(v9, 1, v27, v81);
    if( Hive == -1073741267 )
    {
      CmpLogTransactionAbortedForRollbackPacket(v9, 7i64, v81, v29);
      CmpUnlockRegistry();
      Hive = CmpAbortRollbackPacket((INT64)v81);
      if( Hive >= 0 )
        goto LABEL_45;
      CmpLockRegistryFreezeAware(1u);
LABEL_111:
      v4 = 1;
      goto LABEL_112;
    }
    if( Hive < 0 )
      goto LABEL_111;
    LOBYTE(v28) = a4;
    LODWORD(a5) = 2;
    Hive = CmpDoAccessCheckOnSubtree(v10, a2a, v28, 0x10000i64, a5);
    if( Hive < 0 )
      goto LABEL_111;
    if( (v75 & 8) == 0 )
      break;
    Hive = CmpPrepareToInvalidateAllHigherLayerKcbs(v9, 0, (INT64)v81);
    if( Hive == -1073741267 )
    {
      v26 = 1;
    }
    else if( Hive < 0 )
    {
      goto LABEL_111;
    }
    v30 = CmpPrepareForSubtreeInvalidation(v9, (INT64)v81);
    Hive = v30;
    if( v30 != -1073741267 )
    {
      if( v30 < 0 )
        goto LABEL_111;
      if( !v26 )
      {
        CmpInvalidateAllHigherLayerKcbs(v9, 0, 1i64, (INT64)a4a);
        CmpInvalidateSubtree(v9, 1i64, (INT64)a4a, 0i64);
        CmpDrainDelayDerefContext((UINT64 **)a4a);
        goto LABEL_62;
      }
    }
    CmpLogTransactionAbortedForRollbackPacket(v9, 7i64, v81, v31);
    CmpUnlockRegistry();
    v4 = 0;
    Hive = CmpAbortRollbackPacket((INT64)v81);
    if( Hive < 0 )
    {
      CmpLockRegistryFreezeAware(1u);
      goto LABEL_112;
    }
LABEL_45:
    CmpCleanupRollbackPacket((INT64)v81);
    *(_OWORD *)v81 = 0i64;
    CmpRetryBackOff(&a1a);
    CmpLockRegistryFreezeAware(1u);
  }
  CmpEnumerateAllHigherLayerKcbs(
    v9,
    (unsigned int(__fastcall *)(ULONG_PTR, __int64))CmpCleanUpHigherLayerKcbCachesPreCallback,
    (unsigned int(__fastcall *)(ULONG_PTR, __int64, __int64))CmpCleanUpHigherLayerKcbCachesPostCallback,
    0i64,
    0i64,
    1,
    1);
  if( CmpDoesKeyHaveOpenSubkeys(v9) || *(_QWORD *)v9 != 1i64 )
  {
LABEL_60:
    Hive = -1073741535;
    goto LABEL_111;
  }
LABEL_62:
  v32 = a2_4;
  if( !HvMarkCellDirty(v10, a2_4, 0) )
  {
    Hive = -1073741443;
    goto LABEL_111;
  }
  v79 = (*(__int64(__fastcall **)(UINT64, _QWORD, INT64 *))(v10 + 8))(v10, a2a, &v84);
  if( !v79 )
  {
LABEL_65:
    Hive = -1073741670;
    goto LABEL_111;
  }
  v33 = (*(_BYTE *)(v79 + 2) & 4) == 0;
  v34 = *(_DWORD *)(v79 + 16);
  v75 = v34;
  if( v33 )
  {
    v8 = 0i64;
    if( !HvMarkCellDirty(v10, v34, 0) )
    {
      Hive = -1073741443;
      goto LABEL_111;
    }
    v38 = (*(__int64(__fastcall **)(UINT64, _QWORD, int *))(v10 + 8))(v10, v34, v77);
    if( !v38 )
      goto LABEL_65;
    v39 = *(_DWORD *)(v38 + 4i64 * v85 + 28);
    v40 = *(void(__fastcall **)(UINT64, int *))(v10 + 16);
    v86 = v39;
    v40(v10, v77);
    v41 = (_WORD *)(*(__int64(__fastcall **)(UINT64, _QWORD, int *))(v10 + 8))(v10, v39, v88);
    v91 = v41;
    if( !v41 )
    {
LABEL_68:
      Hive = -1073741670;
      v8 = 0i64;
      goto LABEL_111;
    }
    if( *v41 == 26994 )
    {
      v42 = (unsigned __int16)v41[1];
      v43 = (int *)(v41 + 2);
    }
    else
    {
      v42 = 1;
      v43 = (int *)&v86;
    }
    a1a = 0;
    if( v42 )
    {
      while( 1 )
      {
        v44 = (_WORD *)(*(__int64(__fastcall **)(UINT64, _QWORD, int *))(v10 + 8))(v10, (unsigned int)*v43, v80);
        if( !v44 )
          break;
        v45 = HvMarkCellDirty(v10, (unsigned int)*v43, 0);
        v46 = 0i64;
        if( !v45 )
        {
          (*(void(__fastcall **)(UINT64, int *, _QWORD))(v10 + 16))(v10, v80, 0i64);
          v8 = v74;
          Hive = -1073741443;
          goto LABEL_111;
        }
        v47 = (unsigned __int16)v44[1];
        v48 = 0i64;
        if( ((*v44 - 26220) & 0xFDFF) != 0 )
        {
          if( v44[1] )
          {
            v46 = a2a;
            v49 = v44 + 2;
            while( *v49 != a2a )
            {
              v48 = (unsigned int)(v48 + 1);
              ++v49;
              if( (unsigned int)v48 >= v47 )
                goto LABEL_92;
            }
            v32 = a2_4;
            *(_DWORD *)&v44[2 * v48 + 2] = a2_4;
LABEL_104:
            (*(void(__fastcall **)(UINT64, int *))(v10 + 16))(v10, v80);
            goto LABEL_94;
          }
        }
        else if( v44[1] )
        {
          v46 = a2a;
          v50 = v44 + 2;
          while( *v50 != a2a )
          {
            v48 = (unsigned int)(v48 + 1);
            v50 += 2;
            if( (unsigned int)v48 >= v47 )
              goto LABEL_92;
          }
          v32 = a2_4;
          *(_DWORD *)&v44[4 * v48 + 2] = a2_4;
          goto LABEL_104;
        }
LABEL_92:
        (*(void(__fastcall **)(UINT64, int *, __int64))(v10 + 16))(v10, v80, v46);
        ++v43;
        if( ++a1a >= v42 )
          goto LABEL_93;
      }
      Hive = -1073741670;
      v8 = 0i64;
      goto LABEL_111;
    }
LABEL_93:
    v32 = a2_4;
LABEL_94:
    v51 = (*(__int64(__fastcall **)(UINT64, _QWORD, int *))(v10 + 8))(v10, v75, v77);
    v52 = *(unsigned __int16 *)((*(__int64(__fastcall **)(UINT64, _QWORD, int *))(v10 + 8))(v10, v32, v76) + 74);
    if( *(_DWORD *)(v51 + 56) < v52 )
      *(_DWORD *)(v51 + 56) = v52;
    (*(void(__fastcall **)(UINT64, int *))(v10 + 16))(v10, v76);
    v37 = v77;
  }
  else
  {
    v35 = (*(__int64(__fastcall **)(INT64, _QWORD, int *))(CmpMasterHive + 8))(CmpMasterHive, v34, v77);
    if( !v35 )
      goto LABEL_68;
    *(_DWORD *)(v35 + 28) = a2_4;
    (*(void(__fastcall **)(INT64, int *))(CmpMasterHive + 16))(CmpMasterHive, v77);
    v36 = (*(__int64(__fastcall **)(UINT64, _QWORD, int *))(v10 + 8))(v10, a2_4, v76);
    v8 = v36;
    if( !v36 )
    {
LABEL_70:
      Hive = -1073741670;
      goto LABEL_111;
    }
    *(_DWORD *)(v36 + 16) = v34;
    v37 = v76;
    *(_DWORD *)(*(_QWORD *)(v10 + 64) + 36i64) = a2_4;
  }
  (*(void(__fastcall **)(UINT64, int *))(v10 + 16))(v10, v37);
  *(_DWORD *)(v9 + 40) = v32;
  CmpCleanUpKcbCachedSymlink(v9, (INT64)a4a);
  v53 = *(_QWORD *)(v9 + 32);
  v87[0] = -1;
  v54 = *(unsigned int *)(v9 + 40);
  v87[1] = 0;
  v55 = (*(__int64(__fastcall **)(__int64, __int64, int *))(v53 + 8))(v53, v54, v87);
  v8 = 0i64;
  v56 = v55;
  if( !v55 )
    goto LABEL_70;
  v57 = *(_DWORD *)(v55 + 40);
  v58 = *(_DWORD *)(v55 + 36);
  *(_DWORD *)(v9 + 100) = v57;
  *(_DWORD *)(v9 + 96) = v58;
  *(_WORD *)(v9 + 186) = *(_WORD *)(v56 + 2);
  CmpAssignSecurityToKcb(v9, *(unsigned int *)(v56 + 44), 0i64, 0, 0);
  LOBYTE(v59) = 1;
  CmpCleanUpSubKeyInfo((UNICODE_STRING *)v9, v59, v60);
  ++*(_QWORD *)(v9 + 304);
  *(_QWORD *)(v9 + 168) = *(_QWORD *)(v56 + 4);
  *(_WORD *)(v9 + 176) = *(_WORD *)(v56 + 52);
  *(_WORD *)(v9 + 178) = *(_WORD *)(v56 + 60);
  *(_DWORD *)(v9 + 180) = *(_DWORD *)(v56 + 64);
  *(_DWORD *)(v9 + 184) ^= (*(_DWORD *)(v9 + 184) ^ *(unsigned __int16 *)(v56 + 54)) & 0xF;
  *(_DWORD *)(v9 + 184) ^= ((unsigned __int8)*(_DWORD *)(v9 + 184) ^ (unsigned __int8)*(_WORD *)(v56 + 54)) & 0xF0;
  v61 = *(_QWORD *)(v9 + 32);
  *(_BYTE *)(v9 + 185) = *(_BYTE *)(v56 + 55);
  (*(void(__fastcall **)(__int64, int *))(v61 + 16))(v61, v87);
  *(_WORD *)(v9 + 8) = 64;
  if( CmpDeleteTree(v10, a2a) )
    CmpFreeKeyByCell((_HHIVE *)v10, a2a, 0);
  CmpReportNotify(v9, 0i64, 1i64, &v90);
  if( !CmpProfileLoaded )
  {
    CmpGlobalQuotaAllowed = CmpGlobalQuota;
    CmpProfileLoaded = 1;
  }
  CmpDrainDelayDerefContext((UINT64 **)a4a);
  CmpUnlockRegistry();
  v4 = 0;
  CmpDestroyHive(P);
  P = 0i64;
  CmpSignalDeferredPosts(&v90);
LABEL_119:
  CmpDrainDelayDerefContext((UINT64 **)a4a);
  if( v4 )
    CmpUnlockRegistry();
  if( P )
  {
    CmpDestroyHive(P);
    P = 0i64;
  }
  if( v91 )
    (*(void(__fastcall **)(UINT64, int *))(v10 + 16))(v10, v88);
  if( v8 )
    (*(void(__fastcall **)(UINT64, int *))(v10 + 16))(v10, v76);
  if( v79 )
    (*(void(__fastcall **)(UINT64, INT64 *))(v10 + 16))(v10, &v84);
  CmpCleanupRollbackPacket((INT64)v81);
  CmpTraceHiveRestoreStop((unsigned int)Hive);
  return(unsigned int)Hive;
}

Referenced by:

NtRestoreKey