CmRestoreKey
__int64 __fastcall CmRestoreKey(_QWORD *a1, __int64 a2, int a3, char 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;
size_t v21;
const VOID *v22;
_WORD *v23;
__int64 v24;
void(__fastcall *v25)(UINT64, _HV_GET_CELL_CONTEXT *);
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;
UINT8 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;
__int64 v59;
unsigned int v60;
VOID **CellAddress;
CHAR CellAddressContext;
_HV_GET_CELL_CONTEXT *CellAddressContexta;
INT64 a7;
UINT64 Flags;
char v68;
unsigned int CellIndex;
unsigned int CellIndex_4;
int v71;
__int64 v72;
unsigned int v73;
int v74[2];
int v75[2];
PVOID P;
VOID *v77;
int v78[2];
INT64 v79[2];
unsigned int NodeCell;
unsigned int NodeCell_4;
_HV_GET_CELL_CONTEXT v82;
unsigned int v83;
unsigned int v84;
int v85[2];
int v86[2];
INT64 a2a[2];
_LIST_ENTRY DeferredPostAsync;
_WORD *v89;
INT64 a6[5];
INT64 a12[54];
v73 = a3;
v4 = 0;
v89 = 0i64;
v86[1] = 0;
v77 = 0i64;
v86[0] = -1;
v82.Cell = -1;
v74[0] = -1;
v75[0] = -1;
v78[0] = -1;
v8 = 0i64;
*(_DWORD *)&v82.BinContext._bf_0 = 0;
v74[1] = 0;
v75[1] = 0;
P = 0i64;
v78[1] = 0;
memset(a6, 0, 32);
DeferredPostAsync = 0i64;
memset(a12, 0i64, sizeof(a12));
v71 = 0;
*(_OWORD *)a2a = 0i64;
*(_OWORD *)v79 = 0i64;
CmpInitializeDelayDerefContext(a2a);
v9 = a1[1];
v10 = *(_QWORD *)(v9 + 32);
if( (*(_DWORD *)(v10 + 160) & 0x100000) != 0 )
{
Hive = -1073741790;
goto LABEL_119;
}
CmpTraceHiveRestoreStart((PVOID)a2, (unsigned int)a3);
if( (a3 & 0xFFFFFFFD) != 0 && (a3 & 2) != 0 || a1[7] || a1[8] )
{
Hive = -1073741811;
goto LABEL_119;
}
v12 = 1;
if( (v73 & 1) != 0 )
{
HiveVolatile = CmpLoadHiveVolatile((_CM_KEY_BODY *)a1, (PVOID)a2);
LABEL_8:
Hive = HiveVolatile;
goto LABEL_119;
}
if( (v73 & 2) != 0 )
{
HiveVolatile = CmpRefreshHive((__int64)a1);
goto LABEL_8;
}
DeferredPostAsync.Blink = &DeferredPostAsync;
a6[0] = a2;
DeferredPostAsync.Flink = &DeferredPostAsync;
LODWORD(Flags) = 17825793;
memset(&a6[1], 0, 24);
Hive = CmpCreateHive((INT64)&P, 2ui64, 0x8000ui64, 0i64, 0i64, (INT64)a6, 0i64, Flags, 0i64, 0i64, 0i64, (INT64)a12);
if( Hive < 0 )
goto LABEL_119;
CmpLockRegistryFreezeAware(0);
v4 = 1;
CmpLockKcbShared((_CM_KEY_CONTROL_BLOCK *)v9);
v14 = *(_DWORD *)(v9 + 40);
CellIndex = v14;
if( *(_WORD *)(v9 + 66) )
{
CmpLogUnsupportedOperation(17);
Hive = -1073741822;
LABEL_117:
CmpUnlockKcb((_CM_KEY_CONTROL_BLOCK *)v9);
goto LABEL_119;
}
if( CmpIsKeyDeletedForKeyBody((CM_KEY_BODY *)a1, 0i64) )
{
Hive = -1073741535;
goto LABEL_117;
}
if( *(_BYTE *)(v9 + 65) == 1 || v10 == *(_QWORD *)&CmpMasterHive )
{
Hive = -1073741790;
goto LABEL_117;
}
if( *(_BYTE *)(v10 + 2936) == 1 )
{
Hive = -1073741431;
goto LABEL_117;
}
HvLockHiveFlusherShared(v10);
v68 = 1;
v15 = (*(__int64(__fastcall **)(UINT64, _QWORD, int *))(v10 + 8))(v10, v14, v74);
v72 = 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),
v83 = v14 >> 31,
v18 = CmpCopyKeyPartial((UINT64)P, *(unsigned int *)(v17 + 36), v10, v16, 6, CellAddressContext, a7),
NodeCell_4 = v18,
v18 == -1) )
{
Hive = -1073741670;
goto LABEL_115;
}
v19 = HvReallocateCell((PVOID)v10, (PVOID)v18, (unsigned int)*(unsigned __int16 *)(v8 + 72) + 76, 1u, &v77, &v82);
CellIndex_4 = v19;
v20 = v19;
if( v19 == -1 )
{
Hive = -1073741670;
goto LABEL_112;
}
v21 = *(unsigned __int16 *)(v8 + 72);
v22 = (const VOID *)(v8 + 76);
v23 = v77;
NodeCell_4 = v19;
memmove((char *)v77 + 76, v22, v21);
v24 = v72;
v23[36] = *(_WORD *)(v72 + 72);
if( (*(_BYTE *)(v24 + 2) & 0x20) != 0 )
v23[1] |= 0x20u;
else
*((_WORD *)v77 + 1) &= ~0x20u;
LODWORD(CellAddressContexta) = 0;
if( !CmpCopySyncTree(
(UINT64)P,
*(unsigned int *)(*((_QWORD *)P + 8) + 36i64),
v10,
v20,
2,
(INT64)CellAddressContexta) )
{
v8 = v72;
Hive = -1073741670;
LABEL_112:
v60 = NodeCell_4;
if( CmpDeleteTree(v10, NodeCell_4) )
CmpFreeKeyByCell(v10, v60, 0);
v12 = v68;
if( !v68 )
{
LABEL_116:
if( !v12 )
goto LABEL_119;
goto LABEL_117;
}
LABEL_115:
HvUnlockHiveFlusherShared(v10);
goto LABEL_116;
}
HvUnlockHiveFlusherShared(v10);
v68 = 0;
CmpUnlockKcb((_CM_KEY_CONTROL_BLOCK *)v9);
CmpUnlockRegistry();
(*(void(__fastcall **)(UINT64, int *))(v10 + 16))(v10, v74);
v25 = *(void(__fastcall **)(UINT64, _HV_GET_CELL_CONTEXT *))(v10 + 16);
v72 = 0i64;
v8 = 0i64;
v25(v10, &v82);
v77 = 0i64;
CmpLockRegistryFreezeAware(1u);
while( 1 )
{
v26 = 0;
if( (*(&CmpDummyThreadEvent + 1056) & 1) != 0 )
{
LABEL_110:
Hive = -1073741431;
goto LABEL_111;
}
if( CmpIsKeyDeletedForKeyBody((CM_KEY_BODY *)a1, 0i64) )
goto LABEL_60;
if( CellIndex != *(_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, CellIndex, a4, 0x10000ui64);
if( Hive < 0 )
goto LABEL_111;
Hive = CmpTryAcquireKcbIXLocks(v9, 1, v27, (UINT64 *)v79);
if( Hive == -1073741267 )
{
CmpLogTransactionAbortedForRollbackPacket(v9, 7, (unsigned int *)v79, v29);
CmpUnlockRegistry();
Hive = CmpAbortRollbackPacket((INT64)v79);
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(CellAddress) = 2;
Hive = CmpDoAccessCheckOnSubtree(v10, CellIndex, v28, 0x10000i64, (INT64)CellAddress);
if( Hive < 0 )
goto LABEL_111;
if( (v73 & 8) == 0 )
break;
Hive = CmpPrepareToInvalidateAllHigherLayerKcbs(v9, 0, (__int64)v79);
if( Hive == -1073741267 )
{
v26 = 1;
}
else if( Hive < 0 )
{
goto LABEL_111;
}
v30 = CmpPrepareForSubtreeInvalidation(v9, (__int64)v79);
Hive = v30;
if( v30 != -1073741267 )
{
if( v30 < 0 )
goto LABEL_111;
if( !v26 )
{
CmpInvalidateAllHigherLayerKcbs(v9, 0, 1i64, (INT64)a2a);
CmpInvalidateSubtree(v9, 1i64, (INT64)a2a, 0i64);
CmpDrainDelayDerefContext((UINT64 **)a2a);
goto LABEL_62;
}
}
CmpLogTransactionAbortedForRollbackPacket(v9, 7, (unsigned int *)v79, v31);
CmpUnlockRegistry();
v4 = 0;
Hive = CmpAbortRollbackPacket((INT64)v79);
if( Hive < 0 )
{
CmpLockRegistryFreezeAware(1u);
goto LABEL_112;
}
LABEL_45:
CmpCleanupRollbackPacket((INT64)v79);
*(_OWORD *)v79 = 0i64;
CmpRetryBackOff(&v71);
CmpLockRegistryFreezeAware(1u);
}
CmpEnumerateAllHigherLayerKcbs(
v9,
(unsigned int(__fastcall *)(void *, __int64))CmpCleanUpHigherLayerKcbCachesPreCallback,
(unsigned int(__fastcall *)(void *, __int64, __int64))CmpCleanUpHigherLayerKcbCachesPostCallback,
0i64,
0i64,
1,
1);
if( CmpDoesKeyHaveOpenSubkeys(v9) || *(_QWORD *)v9 != 1i64 )
{
LABEL_60:
Hive = -1073741535;
goto LABEL_111;
}
LABEL_62:
v32 = CellIndex_4;
if( !HvMarkCellDirty((PVOID)v10, (PVOID)CellIndex_4, 0) )
{
Hive = -1073741443;
goto LABEL_111;
}
v77 = (VOID *)(*(__int64(__fastcall **)(UINT64, _QWORD, _HV_GET_CELL_CONTEXT *))(v10 + 8))(v10, CellIndex, &v82);
if( !v77 )
{
LABEL_65:
Hive = -1073741670;
goto LABEL_111;
}
v33 = (*((_BYTE *)v77 + 2) & 4) == 0;
v34 = *((_DWORD *)v77 + 4);
v73 = v34;
if( v33 )
{
v8 = 0i64;
if( !HvMarkCellDirty((PVOID)v10, (PVOID)v34, 0) )
{
Hive = -1073741443;
goto LABEL_111;
}
v38 = (*(__int64(__fastcall **)(UINT64, _QWORD, int *))(v10 + 8))(v10, v34, v75);
if( !v38 )
goto LABEL_65;
v39 = *(_DWORD *)(v38 + 4i64 * v83 + 28);
v40 = *(void(__fastcall **)(UINT64, int *))(v10 + 16);
v84 = v39;
v40(v10, v75);
v41 = (_WORD *)(*(__int64(__fastcall **)(UINT64, _QWORD, int *))(v10 + 8))(v10, v39, v86);
v89 = 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 *)&v84;
}
v71 = 0;
if( v42 )
{
while( 1 )
{
v44 = (_WORD *)(*(__int64(__fastcall **)(UINT64, _QWORD, int *))(v10 + 8))(v10, (unsigned int)*v43, v78);
if( !v44 )
break;
v45 = HvMarkCellDirty((PVOID)v10, (PVOID)(unsigned int)*v43, 0);
v46 = 0i64;
if( !v45 )
{
(*(void(__fastcall **)(UINT64, int *, _QWORD))(v10 + 16))(v10, v78, 0i64);
v8 = v72;
Hive = -1073741443;
goto LABEL_111;
}
v47 = (unsigned __int16)v44[1];
v48 = 0i64;
if( ((*v44 - 26220) & 0xFDFF) != 0 )
{
if( v44[1] )
{
v46 = CellIndex;
v49 = v44 + 2;
while( *v49 != CellIndex )
{
v48 = (unsigned int)(v48 + 1);
++v49;
if( (unsigned int)v48 >= v47 )
goto LABEL_92;
}
v32 = CellIndex_4;
*(_DWORD *)&v44[2 * v48 + 2] = CellIndex_4;
LABEL_104:
(*(void(__fastcall **)(UINT64, int *))(v10 + 16))(v10, v78);
goto LABEL_94;
}
}
else if( v44[1] )
{
v46 = CellIndex;
v50 = v44 + 2;
while( *v50 != CellIndex )
{
v48 = (unsigned int)(v48 + 1);
v50 += 2;
if( (unsigned int)v48 >= v47 )
goto LABEL_92;
}
v32 = CellIndex_4;
*(_DWORD *)&v44[4 * v48 + 2] = CellIndex_4;
goto LABEL_104;
}
LABEL_92:
(*(void(__fastcall **)(UINT64, int *, __int64))(v10 + 16))(v10, v78, v46);
++v43;
if( ++v71 >= v42 )
goto LABEL_93;
}
Hive = -1073741670;
v8 = 0i64;
goto LABEL_111;
}
LABEL_93:
v32 = CellIndex_4;
LABEL_94:
v51 = (*(__int64(__fastcall **)(UINT64, _QWORD, int *))(v10 + 8))(v10, v73, v75);
v52 = *(unsigned __int16 *)((*(__int64(__fastcall **)(UINT64, _QWORD, int *))(v10 + 8))(v10, v32, v74) + 74);
if( *(_DWORD *)(v51 + 56) < v52 )
*(_DWORD *)(v51 + 56) = v52;
(*(void(__fastcall **)(UINT64, int *))(v10 + 16))(v10, v74);
v37 = v75;
}
else
{
v35 = (*(__int64(__fastcall **)(_QWORD, _QWORD, int *))(*(_QWORD *)&CmpMasterHive + 8i64))(
*(_QWORD *)&CmpMasterHive,
v34,
v75);
if( !v35 )
goto LABEL_68;
*(_DWORD *)(v35 + 28) = CellIndex_4;
(*(void(__fastcall **)(_QWORD, int *))(*(_QWORD *)&CmpMasterHive + 16i64))(*(_QWORD *)&CmpMasterHive, v75);
v36 = (*(__int64(__fastcall **)(UINT64, _QWORD, int *))(v10 + 8))(v10, CellIndex_4, v74);
v8 = v36;
if( !v36 )
{
LABEL_70:
Hive = -1073741670;
goto LABEL_111;
}
*(_DWORD *)(v36 + 16) = v34;
v37 = v74;
*(_DWORD *)(*(_QWORD *)(v10 + 64) + 36i64) = CellIndex_4;
}
(*(void(__fastcall **)(UINT64, int *))(v10 + 16))(v10, v37);
*(_DWORD *)(v9 + 40) = v32;
CmpCleanUpKcbCachedSymlink(v9, (INT64)a2a);
v53 = *(_QWORD *)(v9 + 32);
v85[0] = -1;
v54 = *(unsigned int *)(v9 + 40);
v85[1] = 0;
v55 = (*(__int64(__fastcall **)(__int64, __int64, int *))(v53 + 8))(v53, v54, v85);
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);
CmpCleanUpSubKeyInfo(v9, 1);
++*(_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;
v59 = *(_QWORD *)(v9 + 32);
*(_BYTE *)(v9 + 185) = *(_BYTE *)(v56 + 55);
(*(void(__fastcall **)(__int64, int *))(v59 + 16))(v59, v85);
*(_WORD *)(v9 + 8) = 64;
if( CmpDeleteTree(v10, CellIndex) )
CmpFreeKeyByCell(v10, CellIndex, 0);
CmpReportNotify(v9, 0i64, 1i64, (_LOOKASIDE_LIST_EX *)&DeferredPostAsync);
if( !CmpProfileLoaded )
{
CmpGlobalQuotaAllowed = CmpGlobalQuota;
CmpProfileLoaded = 1;
}
CmpDrainDelayDerefContext((UINT64 **)a2a);
CmpUnlockRegistry();
v4 = 0;
CmpDestroyHive(P);
P = 0i64;
CmpSignalDeferredPosts(&DeferredPostAsync);
LABEL_119:
CmpDrainDelayDerefContext((UINT64 **)a2a);
if( v4 )
CmpUnlockRegistry();
if( P )
{
CmpDestroyHive(P);
P = 0i64;
}
if( v89 )
(*(void(__fastcall **)(UINT64, int *))(v10 + 16))(v10, v86);
if( v8 )
(*(void(__fastcall **)(UINT64, int *))(v10 + 16))(v10, v74);
if( v77 )
(*(void(__fastcall **)(UINT64, _HV_GET_CELL_CONTEXT *))(v10 + 16))(v10, &v82);
CmpCleanupRollbackPacket((INT64)v79);
CmpTraceHiveRestoreStop((unsigned int)Hive);
return(unsigned int)Hive;
}Referenced by:
NtRestoreKey