CmpCreateKeyControlBlock
INT64 __fastcall CmpCreateKeyControlBlock(
_CMHIVE *Hive,
UINT64 Cell,
_CM_KEY_CONTROL_BLOCK *ParentKcb,
_CM_KEY_CONTROL_BLOCK *NextLayerKcb,
UINT64 ControlFlags,
_UNICODE_STRING *KeyName,
_CM_COMPONENT_HASH ComponentHash,
_CM_PATH_HASH PathHash,
_CM_KEY_CONTROL_BLOCK **ResultKcb){
ULONG_PTR v9;
int v11;
int v12;
unsigned int Hash;
_UNICODE_STRING *v15;
_CM_KEY_CONTROL_BLOCK *KcbInHashEntryByName;
_CM_KEY_CONTROL_BLOCK *v17;
PSLIST_ENTRY KeyControlBlock;
UINT8 *v19;
UINT64 v20;
struct _SLIST_ENTRY *v21;
_QWORD *v22;
_CM_NAME_CONTROL_BLOCK *NameControlBlock;
__int64 v24;
INT64 v25;
__int64 v26;
int v27;
_BYTE *v28;
unsigned int v29;
char v30;
__int64 v31;
__int64 v32;
bool v33;
int v34;
unsigned int v35;
unsigned __int64 v36;
INT64 result;
__int64 v38;
int LayerLink;
unsigned int *v40;
void *v41;
__int64 v42[2];
unsigned int v43;
ULONG_PTR BugCheckParameter2;
BugCheckParameter2 = (ULONG_PTR)NextLayerKcb;
v42[0] = 0i64;
v9 = (ULONG_PTR)NextLayerKcb;
v11 = *((_DWORD *)Hive + 40);
v12 = Cell;
LODWORD(v42[0]) = -1;
if( (v11 & 0x20) != 0 && *((struct _KTHREAD **)Hive + 526) != KeGetCurrentThread() )
return 3221225524i64;
Hash = PathHash.Hash;
v15 = KeyName;
KcbInHashEntryByName = (_CM_KEY_CONTROL_BLOCK *)CmpFindKcbInHashEntryByName(
(INT64)Hive,
PathHash.Hash,
(INT64)ParentKcb,
KeyName);
v17 = KcbInHashEntryByName;
if( KcbInHashEntryByName )
{
CmpReferenceKeyControlBlockLockNotHeld(KcbInHashEntryByName);
result = 0i64;
*ResultKcb = v17;
return result;
}
if( v15->Length + 2 + (unsigned int)CmpKeyFullNameLength((INT64)ParentKcb) > 0xFFFF )
return 3221225485i64;
KeyControlBlock = CmpAllocateKeyControlBlock();
v20 = (UINT64)KeyControlBlock;
if( !KeyControlBlock )
return 3221225626i64;
v21 = KeyControlBlock + 1;
v22 = &KeyControlBlock[7].Next + 1;
v22[1] = v22;
*v22 = v22;
*(_QWORD *)(v20 + 136) = 0i64;
*(_QWORD *)(v20 + 144) = 0i64;
*(_QWORD *)(v20 + 152) = 0i64;
*(_QWORD *)(v20 + 160) = 0i64;
*(_QWORD *)(v20 + 48) = 0i64;
*(_QWORD *)v20 = 1i64;
*(_QWORD *)(v20 + 32) = Hive;
*(_DWORD *)(v20 + 40) = v12;
*(_DWORD *)(v20 + 16) = Hash;
*(_QWORD *)(v20 + 216) = v20 + 208;
*(_QWORD *)(v20 + 208) = v20 + 208;
*(_QWORD *)(v20 + 240) = 0i64;
*(_DWORD *)(v20 + 248) = 0;
*(_QWORD *)(v20 + 256) = 0i64;
*(_DWORD *)(v20 + 264) = 0;
*(_QWORD *)(v20 + 272) = 0i64;
*(_DWORD *)(v20 + 280) = 0;
*(_QWORD *)(v20 + 288) = 0i64;
*(_QWORD *)(v20 + 232) = v20 + 224;
*(_QWORD *)(v20 + 224) = v20 + 224;
*(_DWORD *)(v20 + 284) = -1;
NameControlBlock = CmpGetNameControlBlock(v15, &ComponentHash, v19);
*(_QWORD *)(v20 + 80) = NameControlBlock;
if( !NameControlBlock )
{
LayerLink = -1073741670;
goto LABEL_44;
}
v24 = *(unsigned int *)(v20 + 40);
if( (_DWORD)v24 != -1 )
{
v25 = (*(__int64(__fastcall **)(_QWORD, __int64, __int64 *))(*(_QWORD *)(v20 + 32) + 8i64))(
*(_QWORD *)(v20 + 32),
v24,
v42);
if( CmpKeyNodeNeedsAccessBitUpdate(*(_QWORD *)(v20 + 32), v25) )
{
(*(void(__fastcall **)(__int64, __int64 *))(v26 + 16))(v26, v42);
ExAcquirePushLockSharedEx(*(_QWORD *)(v20 + 32) + 72i64, 0i64);
v25 = (*(__int64(__fastcall **)(_QWORD, _QWORD, __int64 *))(*(_QWORD *)(v20 + 32) + 8i64))(
*(_QWORD *)(v20 + 32),
*(unsigned int *)(v20 + 40),
v42);
CmpUpdateKeyNodeAccessBits(*(_QWORD *)(v20 + 32), v25, *(unsigned int *)(v20 + 40));
v38 = *(_QWORD *)(v20 + 32);
if( _InterlockedCompareExchange64((volatile signed __int64 *)(v38 + 72), 0i64, 17i64) != 17 )
ExfReleasePushLockShared((INT64 *)(v38 + 72));
KeAbPostRelease((PVOID)(v38 + 72));
}
*(_BYTE *)(v20 + 65) = *(_BYTE *)(v25 + 13) & 3;
v27 = *(_DWORD *)(v25 + 36);
*(_DWORD *)(v20 + 100) = *(_DWORD *)(v25 + 40);
*(_DWORD *)(v20 + 96) = v27;
*(_WORD *)(v20 + 186) = *(_WORD *)(v25 + 2);
*(_DWORD *)(v20 + 112) = *(_DWORD *)(v25 + 20) + *(_DWORD *)(v25 + 24);
*(_QWORD *)(v20 + 168) = *(_QWORD *)(v25 + 4);
*(_WORD *)(v20 + 176) = *(_WORD *)(v25 + 52);
*(_WORD *)(v20 + 178) = *(_WORD *)(v25 + 60);
*(_DWORD *)(v20 + 180) = *(_DWORD *)(v25 + 64);
*(_DWORD *)(v20 + 184) ^= (*(_DWORD *)(v20 + 184) ^ *(unsigned __int16 *)(v25 + 54)) & 0xF;
*(_DWORD *)(v20 + 184) ^= ((unsigned __int8)*(_DWORD *)(v20 + 184) ^ (unsigned __int8)*(_WORD *)(v25 + 54)) & 0xF0;
*(_BYTE *)(v20 + 185) = *(_BYTE *)(v25 + 55);
LODWORD(v28) = KeAbPreAcquire((PVOID)(v20 + 48), 0i64, 1ui64);
if( _interlockedbittestandset64((volatile signed __int32 *)(v20 + 48), 0i64) )
{
if( v28 )
KeAbPostReleaseEx((PVOID)(v20 + 48), v28);
}
else
{
if( v28 )
v28[26] |= 1u;
*(_QWORD *)(v20 + 56) = KeGetCurrentThread();
}
v29 = *(_DWORD *)(v25 + 44);
v43 = 0;
v30 = 1;
if( v29 == -1 )
{
*(_QWORD *)(v20 + 88) = 0i64;
LABEL_16:
CmpUnlockKcb(v20);
(*(void(__fastcall **)(_QWORD, __int64 *))(*(_QWORD *)(v20 + 32) + 16i64))(*(_QWORD *)(v20 + 32), v42);
v9 = BugCheckParameter2;
goto LABEL_17;
}
v31 = *(_QWORD *)(v20 + 32);
ExAcquirePushLockSharedEx(v31 + 1776, 0i64);
if( CmpFindSecurityCellCacheIndex(v31, v29, &v43) )
{
v32 = *(_QWORD *)(*(_QWORD *)(v31 + 1880) + 16i64 * v43 + 8);
}
else
{
v30 = 0;
v32 = 0i64;
}
*(_QWORD *)(v20 + 88) = v32;
ExReleasePushLockEx(v31 + 1776, 0i64);
if( v30 )
goto LABEL_16;
CmpUnlockKcb(v20);
LayerLink = -1073741670;
(*((void(__fastcall **)(_CMHIVE *, __int64 *))Hive + 2))(Hive, v42);
LABEL_44:
v40 = *(unsigned int **)(v20 + 80);
if( v40 )
CmpDereferenceNameControlBlockWithLock(v40);
if( *(_QWORD *)(v20 + 72) )
CmpDereferenceKeyControlBlockUnsafe((volatile INT64 *)ParentKcb);
v41 = *(void **)(v20 + 192);
if( v41 )
ExFreePoolWithTag(v41, 0);
*(_DWORD *)(v20 + 8) |= 0x80000u;
CmpFreeKeyControlBlock((_CM_KEY_CONTROL_BLOCK *)v20);
return(unsigned int)LayerLink;
}
if( ((ParentKcb->LayerSemantics - 1) & 0xFD) == 0 )
*(_BYTE *)(v20 + 65) = 1;
if( (ControlFlags & 1) != 0 )
*(_WORD *)(v20 + 186) |= 4u;
LABEL_17:
if( ParentKcb )
{
CmpReferenceKeyControlBlockUnsafe((volatile INT64 *)ParentKcb);
v33 = (*(_DWORD *)(v20 + 184) & 0x40000) == 0;
*(_QWORD *)(v20 + 72) = ParentKcb;
v34 = *((_DWORD *)ParentKcb + 2);
if( v33 )
v35 = *(_DWORD *)(v20 + 8) ^ (*(_DWORD *)(v20 + 8) ^ (v34 + 0x200000)) & 0x7FE00000;
else
v35 = *(_DWORD *)(v20 + 8) ^ (*(_DWORD *)(v20 + 8) ^ v34) & 0x7FE00000;
}
else
{
v35 = *(_DWORD *)(v20 + 8) & 0x801FFFFF | 0x200000;
}
*(_DWORD *)(v20 + 8) = v35;
if( v9 )
{
CmpLockKcbExclusive(v9);
CmpTryToLockKcbExclusive(v20);
LayerLink = CmpCreateLayerLink(v9);
CmpUnlockKcb(v20);
CmpUnlockKcb(v9);
if( LayerLink < 0 )
goto LABEL_44;
}
v36 = *(_QWORD *)(*(_QWORD *)(v20 + 32) + 1640i64)
+ 24
* ((unsigned int)(*(_DWORD *)(*(_QWORD *)(v20 + 32) + 1648i64) - 1) & ((unsigned int)(101027
* (LODWORD(v21->Next) ^ (LODWORD(v21->Next) >> 9))) ^ ((unsigned __int64)(unsigned int)(101027 * (LODWORD(v21->Next) ^ (LODWORD(v21->Next) >> 9))) >> 9)));
*(_QWORD *)(v20 + 24) = *(_QWORD *)(v36 + 16);
*(_QWORD *)(v36 + 16) = v21;
if( *((_BYTE *)Hive + 2936) == 1 )
*(_WORD *)(v20 + 8) |= 0x20u;
if( *(BOOLEAN **)((char *)&NlsMbCodePageTag + 7) )
CmpEtwDumpKcb((_CM_KEY_CONTROL_BLOCK *)v20, 0x16u);
*ResultKcb = (_CM_KEY_CONTROL_BLOCK *)v20;
return 0i64;
}Referenced by:
CmRenameKey
CmpCreateRegistryRoot
CmpDoParseKey
CmpWalkOneLevel