CmSaveKey
NTSTATUS __stdcall CmSaveKey(CM_KEY_BODY *KeyBody, PVOID FileHandle, UINT64 HiveVersion){
char v3;
char v5;
char v6;
UINT8 v7;
__int64 KeyHive;
_CMHIVE *v9;
NTSTATUS started;
_GUID *v11;
_CM_KEY_CONTROL_BLOCK *KeyControlBlock;
INT64 v13;
unsigned int v14;
INT64 EntryAtLayerHeight;
UINT64 v16;
INT64 v18;
UINT64 v19;
INT64 a6;
char v21;
char a4[15];
INT64 v23[2];
__int128 v24;
PVOID v25;
CM_KEY_BODY *KeyBodya;
INT16 a3[40];
UUID HiveTmUuid;
UUID Uuid;
v25 = FileHandle;
*(_DWORD *)&a4[7] = HiveVersion;
KeyBodya = KeyBody;
a4[0] = v3;
Uuid = 0i64;
HiveTmUuid = 0i64;
memset(a3, 0i64, sizeof(a3));
*(_OWORD *)v23 = 0i64;
WORD1(v23[0]) = -1;
v24 = 0i64;
CmpInitializeKeyNodeStack((INT64)a3);
*(_DWORD *)&a4[3] = -1;
v5 = 0;
v21 = 0;
v6 = 0;
v7 = 0;
KeyHive = 0i64;
v9 = 0i64;
started = CmpUuidCreate(&Uuid);
if( started >= 0 )
{
started = CmpUuidCreate(&HiveTmUuid);
if( started >= 0 )
{
v9 = CmpCreateTemporaryHive(&Uuid, &HiveTmUuid, v11);
if( !v9 )
{
started = -1073741670;
goto LABEL_15;
}
CmpLockRegistry();
KeyControlBlock = KeyBody->KeyControlBlock;
v5 = 1;
started = CmpStartKcbStackForTopLayerKcb((INT64)v23, (INT64)KeyControlBlock);
if( started < 0 )
goto LABEL_15;
CmpLockKcbStackShared((INT64)v23);
v6 = 1;
if( KeyControlBlock->KeyHash.KeyHive == *(_HHIVE **)&CmpMasterHive )
{
started = -1073741790;
goto LABEL_15;
}
CmpTraceHiveSaveStart(KeyControlBlock);
v21 = 1;
started = CmpPerformKeyBodyDeletionCheck(KeyBodya, 0i64);
if( started >= 0 )
{
started = CmpStartKeyNodeStack((INT64)a3, KeyControlBlock->LayerHeight + 1);
if( started >= 0 )
{
CmpLockKcbStackFlusherLocksExclusive((INT64)v23);
CmpPopulateKeyNodeStackFromKcbStack((__int64)a3, (__int64)v23);
LOBYTE(v13) = a4[0];
LODWORD(a6) = 3;
LODWORD(v18) = 131097;
started = CmpDoAccessCheckOnLayeredSubtree(0i64, 0i64, a3, v13, v18, a6);
if( started < 0 )
{
LABEL_32:
CmpUnlockKcbStackFlusherLocksExclusive((INT64)v23);
goto LABEL_15;
}
KeyHive = (__int64)KeyControlBlock->KeyHash.KeyHive;
if( (*(_DWORD *)(KeyHive + 160) & 2) != 0 && *(_DWORD *)(KeyHive + 104) && *(_QWORD *)(KeyHive + 1536) )
{
if( KeyControlBlock->LayerHeight )
{
CmpLogUnsupportedOperation(25);
started = -1073741822;
goto LABEL_32;
}
v7 = ExAcquireRundownProtection((_EX_RUNDOWN_REF *)(KeyHive + 1632));
if( !v7 )
{
started = -1073741444;
goto LABEL_32;
}
CmpUnlockKcbStackFlusherLocksExclusive((INT64)v23);
CmpUnlockKcbStack((INT64)v23);
v6 = 0;
CmpUnlockRegistry();
v5 = 0;
started = CmpSaveKeyByFileCopy(KeyHive, (__int64)v25);
if( started >= 0 )
CmpTraceHiveSaveFileCopied();
}
else
{
v14 = *(_DWORD *)&a4[7];
v9->Hive.BaseBlock->Minor = *(_DWORD *)&a4[7];
v9->Hive.Version = v14;
LODWORD(v19) = 0;
started = CmpCopyMergeOfLayeredKeyNode(a3, (UINT64)v9, 0xFFFFFFFFui64, 1, v19, (UINT64 *)&a4[3]);
if( started < 0 )
goto LABEL_32;
CmpTraceHiveSaveTreeCopied();
v9->Hive.BaseBlock->RootCell = *(_DWORD *)&a4[3];
EntryAtLayerHeight = CmpKeyNodeStackGetEntryAtLayerHeight((INT64)a3, a3[0]);
CmpKeyNodeStackEntryPopulate(EntryAtLayerHeight, (INT64)v9, v16);
started = CmpFullPromoteHiveRootFromKeyNodeStack(a3);
if( started < 0 )
goto LABEL_32;
started = CmpPromoteSubtree(0i64, a3);
if( started < 0 )
goto LABEL_32;
CmpUnlockKcbStackFlusherLocksExclusive((INT64)v23);
CmpCleanupKeyNodeStack((INT64)a3);
CmpInitializeKeyNodeStack((INT64)a3);
CmpUnlockKcbStack((INT64)v23);
v6 = 0;
CmpUnlockRegistry();
v9->FileHandles[2] = v25;
v5 = 0;
started = HvWriteExternal(&v9->Hive);
if( started >= 0 )
started = 0;
}
}
}
}
}
LABEL_15:
CmpCleanupKeyNodeStack((INT64)a3);
if( v6 )
CmpUnlockKcbStack((INT64)v23);
if( v5 )
CmpUnlockRegistry();
if( v7 )
ExReleaseRundownProtection((_EX_RUNDOWN_REF *)(KeyHive + 1632));
CmpCleanupKcbStack((INT64)v23);
if( v9 )
{
v9->FileHandles[2] = 0i64;
CmpDestroyHive(v9);
}
if( v21 )
CmpTraceHiveSaveStop((unsigned int)started);
return started;
}Referenced by:
CmDumpKey
NtSaveKeyEx