CmpCreateKeyControlBlock
__int64 __fastcall CmpCreateKeyControlBlock(
_CMHIVE *Hive,
unsigned int Cell,
_CM_KEY_CONTROL_BLOCK *ParentKcb,
_CM_KEY_CONTROL_BLOCK *NextLayerKcb,
unsigned int ControlFlags,
_UNICODE_STRING *KeyName,
_CM_COMPONENT_HASH ComponentHash,
_CM_PATH_HASH PathHash,
_CM_KEY_CONTROL_BLOCK **ResultKcb){
_CM_KEY_CONTROL_BLOCK *v9;
unsigned int HiveFlags;
unsigned int Hash;
_UNICODE_STRING *v15;
_CM_KEY_CONTROL_BLOCK *KcbInHashEntryByName;
_CM_KEY_CONTROL_BLOCK *v17;
PSLIST_ENTRY KeyControlBlock;
UINT8 *v19;
UINT64 v20;
_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;
CMHIVE *v31;
_CM_KEY_SECURITY_CACHE *CachedSecurity;
bool v33;
__int32 bf_8;
unsigned int v35;
unsigned __int64 v36;
__int64 result;
_EX_PUSH_LOCK *v38;
int LayerLink;
CM_NAME_CONTROL_BLOCK *v40;
void *v41;
__int64 v42[2];
UINT64 Index;
PVOID BugCheckParameter2;
BugCheckParameter2 = NextLayerKcb;
v42[0] = 0i64;
v9 = NextLayerKcb;
HiveFlags = Hive->Hive.HiveFlags;
LODWORD(v42[0]) = -1;
if( (HiveFlags & 0x20) != 0 && (struct _KTHREAD *)Hive->CreatorOwner != KeGetCurrentThread() )
return 3221225524i64;
Hash = PathHash.Hash;
v15 = KeyName;
KcbInHashEntryByName = CmpFindKcbInHashEntryByName(Hive, PathHash, ParentKcb, KeyName);
v17 = KcbInHashEntryByName;
if( KcbInHashEntryByName )
{
CmpReferenceKeyControlBlockLockNotHeld(KcbInHashEntryByName);
result = 0i64;
*ResultKcb = v17;
return result;
}
if( v15->Length + 2 + (unsigned int)CmpKeyFullNameLength(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) = Cell;
*(_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((_EX_PUSH_LOCK *)(*(_QWORD *)(v20 + 32) + 72i64), 0i64);
v25 = (*(__int64(__fastcall **)(_QWORD, _QWORD, __int64 *))(*(_QWORD *)(v20 + 32) + 8i64))(
*(_QWORD *)(v20 + 32),
*(unsigned int *)(v20 + 40),
v42);
CmpUpdateKeyNodeAccessBits(*(_HHIVE **)(v20 + 32), (_CM_KEY_NODE *)v25, *(unsigned int *)(v20 + 40));
v38 = *(_EX_PUSH_LOCK **)(v20 + 32);
if( _InterlockedCompareExchange64(&v38[9]._bf_0, 0i64, 17i64) != 17 )
ExfReleasePushLockShared(v38 + 9);
KeAbPostRelease(&v38[9]);
}
*(_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);
v28 = KeAbPreAcquire((VOID *)(v20 + 48), 0i64, 1ui64);
if( _interlockedbittestandset64((volatile signed __int32 *)(v20 + 48), 0i64) )
{
if( v28 )
KeAbPostReleaseEx((VOID *)(v20 + 48), v28);
}
else
{
if( v28 )
v28[26] |= 1u;
*(_QWORD *)(v20 + 56) = KeGetCurrentThread();
}
v29 = *(_DWORD *)(v25 + 44);
LODWORD(Index) = 0;
v30 = 1;
if( v29 == -1 )
{
*(_QWORD *)(v20 + 88) = 0i64;
LABEL_16:
CmpUnlockKcb((_CM_KEY_CONTROL_BLOCK *)v20);
(*(void(__fastcall **)(_QWORD, __int64 *))(*(_QWORD *)(v20 + 32) + 16i64))(*(_QWORD *)(v20 + 32), v42);
v9 = (_CM_KEY_CONTROL_BLOCK *)BugCheckParameter2;
goto LABEL_17;
}
v31 = *(CMHIVE **)(v20 + 32);
ExAcquirePushLockSharedEx(&v31->SecurityLock, 0i64);
if( CmpFindSecurityCellCacheIndex(v31, v29, &Index) )
{
CachedSecurity = v31->SecurityCache[(unsigned int)Index].CachedSecurity;
}
else
{
v30 = 0;
CachedSecurity = 0i64;
}
*(_QWORD *)(v20 + 88) = CachedSecurity;
ExReleasePushLockEx((_DWORD)v31 + 1776, 0);
if( v30 )
goto LABEL_16;
CmpUnlockKcb((_CM_KEY_CONTROL_BLOCK *)v20);
LayerLink = -1073741670;
Hive->Hive.ReleaseCellRoutine((_HHIVE *)Hive, (_HV_GET_CELL_CONTEXT *)v42);
LABEL_44:
v40 = *(CM_NAME_CONTROL_BLOCK **)(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(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;
bf_8 = ParentKcb->_bf_8;
if( v33 )
v35 = *(_DWORD *)(v20 + 8) ^ (*(_DWORD *)(v20 + 8) ^ (bf_8 + 0x200000)) & 0x7FE00000;
else
v35 = *(_DWORD *)(v20 + 8) ^ (*(_DWORD *)(v20 + 8) ^ bf_8) & 0x7FE00000;
}
else
{
v35 = *(_DWORD *)(v20 + 8) & 0x801FFFFF | 0x200000;
}
*(_DWORD *)(v20 + 8) = v35;
if( v9 )
{
CmpLockKcbExclusive((INT64)v9);
CmpTryToLockKcbExclusive((_CM_KEY_CONTROL_BLOCK *)v20);
LayerLink = CmpCreateLayerLink(v9);
CmpUnlockKcb((_CM_KEY_CONTROL_BLOCK *)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( Hive->Frozen == 1 )
*(_WORD *)(v20 + 8) |= 0x20u;
if( *(BOOLEAN **)((char *)&NlsMbCodePageTag + 7) )
CmpEtwDumpKcb(v20, 22);
*ResultKcb = (_CM_KEY_CONTROL_BLOCK *)v20;
return 0i64;
}Referenced by:
CmRenameKey
CmpCreateRegistryRoot
CmpDoParseKey
CmpWalkOneLevel