CmpCompleteUnloadKey
UINT8 __fastcall CmpCompleteUnloadKey(UINT64 a1, INT64 a2, _DWORD *a3){
ULONG_PTR v3;
__int64 v6;
int v7;
__int64 v8;
UINT64 v9;
UNICODE_STRING *v10;
UINT8 v11;
_ETHREAD *CurrentThread;
EVENT_DESCRIPTOR *v13;
int v14;
unsigned int v15;
EVENT_DESCRIPTOR *v16;
struct _PRIVILEGE_SET *v17;
unsigned int v18;
UINT64 v19;
UINT8 result;
unsigned int v21;
__int64 v22;
_QWORD *v23;
__int64 v24;
int v25;
unsigned int v26;
unsigned int v27;
__int64 v28;
unsigned int v29;
unsigned __int64 v30;
__int64 v31;
__int64 v32;
int v33[8];
__int16 v34;
int v35;
INT64 a1a[2];
EVENT_DESCRIPTOR EventDescriptor;
EVENT_DESCRIPTOR v38;
EVENT_DATA_DESCRIPTOR v39;
EVENT_DATA_DESCRIPTOR UserData[4];
v3 = *(_QWORD *)(a1 + 32);
*(_OWORD *)a1a = 0i64;
CmpInitializeDelayDerefContext(a1a);
v6 = 1i64;
v7 = *(_DWORD *)(v3 + 4152) & 0x20;
*(_DWORD *)(v3 + 4i64 * (_InterlockedExchangeAdd((volatile signed __int32 *)(v3 + 4276), 1u) & 0x7F) + 4280) = 6;
_InterlockedCompareExchange64((volatile signed __int64 *)(v3 + 2944), 1i64, 0i64);
v8 = *(_QWORD *)(v3 + 4192);
if( v8 )
{
v24 = *(_QWORD *)(v3 + 64);
v25 = *(_DWORD *)(v24 + 144);
if( *(_QWORD *)(v8 + 16) == v8 + 16 )
v26 = v25 & 0xFFFFFFFE;
else
v26 = v25 | 1;
*(_DWORD *)(v24 + 144) = v26;
HvMarkBaseBlockDirty((_HHIVE *)v3);
}
*(_DWORD *)(v3 + 160) |= 0x40u;
v9 = EtwpRegTraceHandle;
v34 = 0;
EventDescriptor = (EVENT_DESCRIPTOR)REGISTRY_PERF_EVENT_HIVE_UNLOAD_START;
if( EtwEventEnabled(EtwpRegTraceHandle, &EventDescriptor, (EVENT_DESCRIPTOR *)v6) )
{
v27 = 0;
if( *(_QWORD *)(v3 + 1840) )
{
UserData[0].Ptr = *(_QWORD *)(v3 + 1840);
v27 = 1;
UserData[0].Size = *(unsigned __int16 *)(v3 + 1832);
UserData[0].Reserved = 0;
}
v28 = v27;
v29 = v27 + 1;
UserData[v28].Ptr = (unsigned __int64)&v34;
*(_QWORD *)&UserData[v28].Size = 2i64;
v30 = *(_QWORD *)(v3 + 1856);
if( v30 )
{
v31 = v29++;
UserData[v31].Ptr = v30;
UserData[v31].Size = *(unsigned __int16 *)(v3 + 1848);
UserData[v31].Reserved = 0;
}
v32 = v29;
UserData[v32].Ptr = (unsigned __int64)&v34;
*(_QWORD *)&UserData[v32].Size = 2i64;
EtwWrite(v9, &EventDescriptor, 0i64, v29 + 1, UserData);
}
CmpRemoveHiveFromNamespace((_CMHIVE *)v3, (_CM_KEY_CONTROL_BLOCK *)a1);
*(_DWORD *)(v3 + 4i64 * (_InterlockedExchangeAdd((volatile signed __int32 *)(v3 + 4276), 1u) & 0x7F) + 4280) = 8;
if( v7 )
{
*(_DWORD *)(v3 + 4808) = 1;
CmpDecrementAppHiveUnloadCount();
}
CmpFlushNotifiesOnKeyBodyList(a1, 1i64, (INT64)a1a, 0);
CmpMarkKeyUnbacked((_CM_KEY_CONTROL_BLOCK *)a1);
CmpDiscardKcb(a1, (INT64)a1a);
LOBYTE(v10) = 1;
CmpCleanUpSubKeyInfo(*(UNICODE_STRING **)(*(_QWORD *)(a1 + 72) + 72i64), v10, v11);
CmpDrainDelayDerefContext((UINT64 **)a1a);
CmpUnlockRegistry();
*a3 &= ~2u;
if( (*a3 & 4) != 0 )
{
UNLOCK_HIVE_LOAD();
*a3 &= ~4u;
}
ZwDeleteValueKey(CmpHiveFileListHandle, (UNICODE_STRING *)(v3 + 1848));
CmpDestroySecurityCache(v3);
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
--*((_WORD *)CurrentThread + 242);
CmpUnJoinClassOfTrust(v3);
KeLeaveCriticalRegion();
if( (*(_DWORD *)(v3 + 160) & 0x400) != 0 )
{
v22 = *(_QWORD *)(v3 + 1616);
if( *(_QWORD *)(v22 + 8) != v3 + 1616 || (v23 = *(_QWORD **)(v3 + 1624), *v23 != v3 + 1616) )
__fastfail(3u);
*v23 = v22;
*(_QWORD *)(v22 + 8) = v23;
}
CmpVERemoveHiveFromSIDMappingTable(v3);
v14 = CmpFlushHive(v3, 44, v13);
if( v14 == -1073741811 )
v14 = 0;
v15 = *(_DWORD *)(v3 + 272) + 4096;
HvHiveCleanup(v3);
if( v14 >= 0 && (*(_DWORD *)(v3 + 160) & 0x8000) == 0 && (__int64)(*(_QWORD *)(v3 + 1792) - v15) > 0x100000 )
CmpDoFileSetSizeEx(v3, 0i64, v15, 0);
CmpCmdHiveClose(v3);
v17 = *(struct _PRIVILEGE_SET **)(v3 + 4832);
if( v17 )
CmpVolumeContextDecrementRefCount(v17);
if( v7 )
{
*(_DWORD *)(v3 + 4808) = 0;
_InterlockedOr(v33, 0);
if( *(_QWORD *)(v3 + 4816) )
ExfUnblockPushLock((_EX_PUSH_LOCK *)(v3 + 4816), 0i64);
}
v18 = 0;
if( *(_DWORD *)(v3 + 2912) )
{
do
{
KeSetEvent(*(PRKEVENT *)(*(_QWORD *)(v3 + 2920) + 8i64 * v18), 0);
HalPutDmaAdapter(*(PADAPTER_OBJECT *)(*(_QWORD *)(v3 + 2920) + 8i64 * v18));
v21 = *(_DWORD *)(v3 + 2912);
++v18;
}
while( v18 < v21 );
if( v21 )
ExFreePoolWithTag(*(PVOID *)(v3 + 2920), 0);
}
v19 = EtwpRegTraceHandle;
v35 = v14;
v38 = (EVENT_DESCRIPTOR)REGISTRY_PERF_EVENT_HIVE_UNLOAD_STOP;
result = EtwEventEnabled(EtwpRegTraceHandle, &v38, v16);
if( result )
{
*(_QWORD *)&v39.Size = 4i64;
v39.Ptr = (unsigned __int64)&v35;
return EtwWrite(v19, &v38, 0i64, 1ui64, &v39);
}
return result;
}Referenced by:
CmpLateUnloadHiveWorker
CmpPerformUnloadKey