CmpWalkOneLevel
__int64 __fastcall CmpWalkOneLevel(
__int64 a1,
__int64 a2,
__int64 *a3,
__int64 a4,
__int64 a5,
__int64 a6,
int a7,
ULONG_PTR a8,
__int64 a9,
char a10,
__int64 a11){
__int64 v11;
ULONG_PTR v14;
INT16 v15;
__int16 v16;
__int64 v17;
ULONG_PTR v18;
UINT64 v19;
signed __int32 v20;
signed __int32 v21;
__int16 v22;
__int16 i;
__int64 v24;
__int64 v25;
__int64 v26;
_KPROCESS *v27;
__int16 v28;
_CM_KEY_CONTROL_BLOCK *v29;
__int64 KeyCell;
__int64 v31;
_HHIVE *KeyHive;
__int64 v33;
INT64 v34;
int v35;
__int64 v36;
unsigned int v37;
__int64 v38;
__int16 v39;
__int16 v40;
__int64 v41;
bool v42;
__int16 v43;
__int64 v44;
__int64 v45;
__int64 v46;
UINT64 v47;
_CM_KEY_INDEX *v49;
int v50;
__int16 v51;
UINT16 *v52;
__int64 v53;
UINT16 v54;
unsigned __int16 v55;
int v56;
volatile INT64 *v57;
int v58;
__int16 v59;
__int16 v60;
int v61;
__int64 v62;
LIST_ENTRY *v63;
int v64;
INT64 KcbAtLayerHeight;
_CMHIVE *v66;
void *KcbInHashEntryByName;
INT64 v68;
INT64 v69;
INT64 v70;
UINT64 v71;
UINT64 v72;
_HHIVE *v73;
UINT *BugCheckParameter4;
__int16 v75;
int SubKeyInLeafWithStatus;
__int16 v77;
__int16 v78;
UINT Index;
ULONG_PTR v80;
int v81[2];
__int64 v82;
_CM_KEY_CONTROL_BLOCK *ParentKcb;
int v84;
int v85;
INT64 v86;
int v87;
__int64 v88;
_CM_KEY_CONTROL_BLOCK *ResultKcb;
LIST_ENTRY *ListIterator;
__m128i v91;
v11 = a1;
v82 = 0i64;
v14 = 0i64;
v15 = *(_WORD *)(a1 + 66) - 1;
ResultKcb = 0i64;
LODWORD(v82) = -1;
v75 = -1;
v80 = 0i64;
if( v15 >= 0 )
{
do
{
KcbAtLayerHeight = CmpGetKcbAtLayerHeight(a2, v15);
CmpLockHashEntryShared(*(_QWORD *)(KcbAtLayerHeight + 32), (unsigned int)a8);
v66 = *(_CMHIVE **)(KcbAtLayerHeight + 32);
KcbInHashEntryByName = (void *)CmpFindKcbInHashEntryByName(
(INT64)v66,
(unsigned int)a8,
KcbAtLayerHeight,
(const UNICODE_STRING *)a6);
v80 = (ULONG_PTR)KcbInHashEntryByName;
if( KcbInHashEntryByName )
{
v14 = (ULONG_PTR)KcbInHashEntryByName;
CmpReferenceKeyControlBlockLockNotHeld(KcbInHashEntryByName);
CmpUnlockHashEntry(*(_CMHIVE **)(KcbAtLayerHeight + 32), (_CM_PATH_HASH)a8);
CmpPopulateKcbStack(a4, v14);
v16 = *(_WORD *)(v14 + 66) + 1;
goto LABEL_3;
}
CmpUnlockHashEntry(v66, (_CM_PATH_HASH)a8);
--v15;
}
while( v15 >= 0 );
v14 = v80;
}
v16 = 0;
*(_WORD *)(a4 + 2) = -1;
LABEL_3:
v78 = v16;
if( v16 <= *(__int16 *)(v11 + 66) )
{
do
{
if( v16 >= 2 )
v17 = *(_QWORD *)(*(_QWORD *)(a2 + 24) + 8i64 * v16 - 16);
else
v17 = *(_QWORD *)(a2 + 8i64 * v16 + 8);
v18 = *(_QWORD *)(v17 + 32);
v19 = *(_QWORD *)(v18 + 1640)
+ 24
* (((101027 * ((unsigned int)a8 ^ ((unsigned int)a8 >> 9))) ^ ((unsigned __int64)(101027
* ((unsigned int)a8 ^ ((unsigned int)a8 >> 9))) >> 9)) & (unsigned int)(*(_DWORD *)(v18 + 1648) - 1));
ExAcquirePushLockExclusiveEx(v19, 0i64);
*(_QWORD *)(v19 + 8) = KeGetCurrentThread();
_m_prefetchw((const void *)(v18 + 4272));
v20 = *(_DWORD *)(v18 + 4272);
if( !v20 )
LABEL_136:
KeBugCheckEx(0x51u, 0x17ui64, v18, 0xCui64, (unsigned int)a8);
while( 1 )
{
v21 = v20;
v20 = _InterlockedCompareExchange((volatile signed __int32 *)(v18 + 4272), v20 + 1, v20);
if( v21 == v20 )
break;
if( !v20 )
goto LABEL_136;
}
v75 = v16++;
}
while( v16 <= *(__int16 *)(v11 + 66) );
v14 = v80;
}
v22 = *(_WORD *)(a2 + 2);
for( i = 0; i <= v22; ++i )
{
if( i >= 2 )
v24 = *(_QWORD *)(*(_QWORD *)(a2 + 24) + 8i64 * i - 16);
else
v24 = *(_QWORD *)(a2 + 8i64 * i + 8);
ExAcquirePushLockSharedEx(v24 + 48, 0i64);
_InterlockedIncrement((volatile signed __int32 *)(v24 + 56));
v22 = *(_WORD *)(a2 + 2);
}
ListIterator = 0i64;
if( v22 < 0 )
goto LABEL_121;
while( 1 )
{
if( v22 >= 2 )
v25 = *(_QWORD *)(*(_QWORD *)(a2 + 24) + 8i64 * v22 - 16);
else
v25 = *(_QWORD *)(a2 + 8i64 * v22 + 8);
if( *(_WORD *)(v25 + 66) && *(_BYTE *)(v25 + 65) == 1 )
goto LABEL_121;
if( *(_DWORD *)(v25 + 40) != -1 )
break;
if( --v22 < 0 )
goto LABEL_121;
}
if( a9 )
{
LODWORD(v62) = CmListGetNextElement((LIST_ENTRY *)(*(_QWORD *)(a2 + 8) + 208i64), &ListIterator, 32i64);
if( v62 )
{
do
{
v64 = *(_DWORD *)(v62 + 68);
if( v64 == 2 || v64 == 11 )
break;
LODWORD(v62) = CmListGetNextElement(v63 + 13, &ListIterator, 32i64);
}
while( v62 );
if( CmEqualTrans(*(_QWORD *)(v62 + 56), a9) )
{
LABEL_121:
v68 = 328192i64;
LABEL_122:
v35 = -1073741772;
SubKeyInLeafWithStatus = -1073741772;
v69 = 3221225524i64;
goto LABEL_123;
}
}
}
v26 = *(_QWORD *)(v11 + 240);
if( v26 && !CmEqualTrans(a9, v26) )
{
v68 = 328448i64;
goto LABEL_122;
}
if( (*(_DWORD *)(v11 + 184) & 0x20000) != 0 )
{
v68 = 328704i64;
goto LABEL_122;
}
if( (*(_DWORD *)(a11 + 160) & 1) == 0 )
{
v27 = (_EPROCESS *)*(&CmpRegistryProcess + 1);
if( !*(&CmpRegistryProcess + 1) )
v27 = (_EPROCESS *)*((_QWORD *)KeGetCurrentThread() + 23);
KiStackAttachProcess((_KPROCESS *)v27, 0i64, (_KAPC_STATE *)(a11 + 168));
*(_DWORD *)(a11 + 160) |= 1u;
}
if( v14 )
v28 = *(_WORD *)(v14 + 66) + 1;
else
v28 = 0;
v77 = v28;
if( v28 > *(__int16 *)(v11 + 66) )
{
LABEL_98:
v80 = 0i64;
SubKeyInLeafWithStatus = 0;
v60 = v75 - 1;
if( !a10 )
v60 = v75;
v39 = v60;
*(_BYTE *)a5 = a10 != 0;
*a3 = v14;
v35 = 0;
goto LABEL_46;
}
while( 2 )
{
if( v28 >= 2 )
v29 = *(_CM_KEY_CONTROL_BLOCK **)(*(_QWORD *)(a2 + 24) + 8i64 * v28 - 16);
else
v29 = *(_CM_KEY_CONTROL_BLOCK **)(a2 + 8i64 * v28 + 8);
KeyCell = v29->KeyHash.KeyCell;
ParentKcb = v29;
if( (_DWORD)KeyCell == -1 )
{
v37 = -1;
goto LABEL_41;
}
v31 = (__int64)v29->KeyHash.KeyHive->GetCellRoutine(v29->KeyHash.KeyHive, KeyCell, (_HV_GET_CELL_CONTEXT *)&v82);
KeyHive = v29->KeyHash.KeyHive;
v33 = v31;
v88 = v31;
if( (KeyHive->HiveFlags & 0x8001) == 0 && (*(_BYTE *)(v31 + 12) & (unsigned __int8)CmpAccessBitForPhase) == 0 )
{
KeyHive->ReleaseCellRoutine(KeyHive, (_HV_GET_CELL_CONTEXT *)&v82);
ExAcquirePushLockSharedEx((UINT64)&v29->KeyHash.KeyHive->FlusherLock, 0i64);
v70 = (INT64)v29->KeyHash.KeyHive->GetCellRoutine(
v29->KeyHash.KeyHive,
v29->KeyHash.KeyCell,
(_HV_GET_CELL_CONTEXT *)&v82);
v71 = v29->KeyHash.KeyCell;
v72 = (UINT64)v29->KeyHash.KeyHive;
v33 = v70;
v88 = v70;
CmpUpdateKeyNodeAccessBits(v72, v70, v71);
v73 = v29->KeyHash.KeyHive;
if( _InterlockedCompareExchange64((volatile signed __int64 *)&v73->FlusherLock, 0i64, 17i64) != 17 )
ExfReleasePushLockShared((INT64 *)&v73->FlusherLock);
KeAbPostRelease(&v73->FlusherLock);
}
v34 = (INT64)v29->KeyHash.KeyHive;
v81[1] = 0;
v86 = v34;
v85 = -1;
v35 = -1073741772;
v36 = 0i64;
v84 = 0;
SubKeyInLeafWithStatus = -1073741772;
v81[0] = -1;
Index = 0;
v87 = 0;
if( !*(_DWORD *)(v34 + 208) )
goto LABEL_38;
while( !*(_DWORD *)(v33 + 4 * v36 + 20) )
{
LABEL_36:
v36 = (unsigned int)(v84 + 1);
v84 = v36;
if( (unsigned int)v36 >= *(_DWORD *)(v34 + 208) )
goto LABEL_37;
}
v49 = (_CM_KEY_INDEX *)(*(__int64(__fastcall **)(INT64, _QWORD, int *))(v34 + 8))(
v34,
*(unsigned int *)(v33 + 4 * v36 + 28),
v81);
if( !v49 )
goto LABEL_145;
if( v49->Signature == 26994 )
{
BugCheckParameter4 = &Index;
if( CmpFindSubKeyInRoot((PVOID)v34, v49) < 0 )
{
v35 = -1073741670;
goto LABEL_85;
}
(*(void(__fastcall **)(INT64, int *))(v34 + 16))(v34, v81);
if( Index == -1 )
goto LABEL_80;
v49 = (_CM_KEY_INDEX *)(*(__int64(__fastcall **)(INT64, _QWORD, int *))(v34 + 8))(v34, Index, v81);
if( !v49 )
{
LABEL_145:
v35 = -1073741670;
SubKeyInLeafWithStatus = -1073741670;
goto LABEL_37;
}
}
if( v49->Signature != 26732 )
{
SubKeyInLeafWithStatus = CmpFindSubKeyInLeafWithStatus(
(_HHIVE *)v34,
v49,
(const _UNICODE_STRING *)a6,
0i64,
&Index);
v35 = SubKeyInLeafWithStatus;
if( (int)(SubKeyInLeafWithStatus + 0x80000000) >= 0 && SubKeyInLeafWithStatus != -1073741772 )
goto LABEL_86;
v56 = Index;
LABEL_83:
if( v56 != -1 )
{
v85 = v56;
v35 = 0;
goto LABEL_85;
}
goto LABEL_79;
}
v50 = 0;
v51 = _mm_cvtsi128_si32(*(__m128i *)a6);
v91 = *(__m128i *)a6;
if( v51 )
{
v52 = (UINT16 *)v91.m128i_i64[1];
v53 = (unsigned __int16)(((unsigned __int16)(v51 - 1) >> 1) + 1);
do
{
v54 = *v52;
if( *v52 >= 0x61u )
{
if( v54 > 0x7Au )
v54 = NLS_UPCASE(v54);
else
v54 -= 32;
}
++v52;
v50 = v54 + 37 * v50;
--v53;
}
while( v53 );
v91.m128i_i64[1] = (__int64)v52;
}
v55 = 0;
Index = -1;
if( !v49->Count )
{
LABEL_78:
v34 = v86;
v35 = -1073741772;
SubKeyInLeafWithStatus = -1073741772;
LABEL_79:
(*(void(__fastcall **)(INT64, int *))(v34 + 16))(v34, v81);
LABEL_80:
v33 = v88;
goto LABEL_36;
}
while( 1 )
{
if( v50 != *(_DWORD *)&v49[v55 + 1].Signature )
goto LABEL_77;
v61 = CmpDoCompareKeyName(v86, (const UNICODE_STRING *)a6, 0i64, v49[v55].List[0]);
if( v61 == 2 )
break;
if( !v61 )
{
v56 = v49[v55].List[0];
v34 = v86;
v35 = 0;
SubKeyInLeafWithStatus = 0;
Index = v56;
goto LABEL_83;
}
LABEL_77:
if( ++v55 >= v49->Count )
goto LABEL_78;
}
v34 = v86;
v35 = -1073741670;
LABEL_85:
SubKeyInLeafWithStatus = v35;
LABEL_86:
(*(void(__fastcall **)(INT64, int *))(v34 + 16))(v34, v81);
LABEL_37:
v11 = a1;
LABEL_38:
ParentKcb->KeyHash.KeyHive->ReleaseCellRoutine(ParentKcb->KeyHash.KeyHive, (_HV_GET_CELL_CONTEXT *)&v82);
if( v35 == -1073741772 )
{
v37 = -1;
goto LABEL_40;
}
if( v35 < 0 )
{
CmpRecordParseFailure(a11, 328960i64, (unsigned int)v35);
goto LABEL_45;
}
v37 = v85;
if( v85 != -1 )
{
v29 = ParentKcb;
goto LABEL_90;
}
LABEL_40:
v29 = ParentKcb;
LABEL_41:
if( *(_WORD *)(v11 + 66) || a10 )
{
LABEL_90:
v57 = (volatile INT64 *)v80;
LODWORD(BugCheckParameter4) = 0;
v58 = CmpCreateKeyControlBlock(
(_CMHIVE *)v29->KeyHash.KeyHive,
v37,
v29,
(_CM_KEY_CONTROL_BLOCK *)v80,
(UINT64)BugCheckParameter4,
(_UNICODE_STRING *)a6,
(_CM_COMPONENT_HASH)a7,
(_CM_PATH_HASH)a8,
&ResultKcb);
SubKeyInLeafWithStatus = v58;
v35 = v58;
if( v58 >= 0 )
{
if( v57 )
CmpDereferenceKeyControlBlockUnsafe(v57);
v14 = (ULONG_PTR)ResultKcb;
ResultKcb = 0i64;
v80 = v14;
++*(_WORD *)(a4 + 2);
if( v77 >= 2 )
*(_QWORD *)(*(_QWORD *)(a4 + 24) + 8i64 * v77 - 16) = v14;
else
*(_QWORD *)(a4 + 8i64 * v77 + 8) = v14;
v59 = *(_WORD *)(v11 + 66);
if( v77 != v59 )
{
CmpUnlockHashEntry((_CMHIVE *)ParentKcb->KeyHash.KeyHive, (_CM_PATH_HASH)a8);
++v78;
v59 = *(_WORD *)(v11 + 66);
}
v28 = v77 + 1;
v77 = v28;
if( v28 > v59 )
goto LABEL_98;
continue;
}
v69 = (unsigned int)v58;
v68 = 329472i64;
LABEL_123:
CmpRecordParseFailure(a11, v68, v69);
goto LABEL_45;
}
break;
}
v35 = -1073741772;
SubKeyInLeafWithStatus = -1073741772;
v38 = *(unsigned __int8 *)(a11 + 258);
if( (unsigned __int8)v38 < 4u )
{
*(_DWORD *)(a11 + 8 * v38 + 260) = -1073741772;
*(_DWORD *)(a11 + 8i64 * (unsigned __int8)(*(_BYTE *)(a11 + 258))++ + 264) = 329216;
}
LABEL_45:
v39 = v75;
LABEL_46:
v40 = 0;
if( *(__int16 *)(a2 + 2) >= 0 )
{
do
{
if( v40 >= 2 )
v41 = *(_QWORD *)(*(_QWORD *)(a2 + 24) + 8i64 * v40 - 16);
else
v41 = *(_QWORD *)(a2 + 8i64 * v40 + 8);
v42 = (*(_DWORD *)(v41 + 8) & 0x80000) != 0;
if( *(struct _KTHREAD **)(v41 + 56) == KeGetCurrentThread() )
*(_QWORD *)(v41 + 56) = 0i64;
else
_InterlockedDecrement((volatile signed __int32 *)(v41 + 56));
ExReleasePushLockEx(v41 + 48, 0i64);
if( v42 && (*(_DWORD *)(v41 + 8) & 0x80000) != 0 )
CmpFreeKeyControlBlock((_CM_KEY_CONTROL_BLOCK *)v41);
++v40;
}
while( v40 <= *(__int16 *)(a2 + 2) );
v35 = SubKeyInLeafWithStatus;
}
v43 = v78;
if( v78 <= v39 )
{
v44 = 8i64 * v78 - 16;
do
{
if( v43 >= 2 )
v45 = *(_QWORD *)(v44 + *(_QWORD *)(a2 + 24));
else
v45 = *(_QWORD *)(v44 + a2 + 24);
v46 = *(_QWORD *)(v45 + 32);
v47 = *(_QWORD *)(v46 + 1640)
+ 24
* (((101027 * ((unsigned int)a8 ^ ((unsigned int)a8 >> 9))) ^ ((unsigned __int64)(101027
* ((unsigned int)a8 ^ ((unsigned int)a8 >> 9))) >> 9)) & (unsigned int)(*(_DWORD *)(v46 + 1648) - 1));
*(_QWORD *)(v47 + 8) = 0i64;
ExReleasePushLockEx(v47, 0i64);
if( _InterlockedExchangeAdd((volatile signed __int32 *)(v46 + 4272), 0xFFFFFFFF) == 1 )
CmpDeleteHive((PVOID)v46);
++v43;
v44 += 8i64;
}
while( v43 <= v39 );
v35 = SubKeyInLeafWithStatus;
}
if( v80 )
CmpDereferenceKeyControlBlock(v80);
return(unsigned int)v35;
}Referenced by:
CmpDoBuildVirtualStack
CmpDoParseKey