CmpDereferenceKeyControlBlockWithLock
VOID __fastcall CmpDereferenceKeyControlBlockWithLock(ULONG_PTR BugCheckParameter2, INT64 a2, CHAR a3){
__int64 v5;
signed __int64 v7;
int v8;
bool v9;
bool v10;
__int64 v11;
_ETHREAD *CurrentThread;
v5 = *(_QWORD *)(BugCheckParameter2 + 32);
v7 = _InterlockedDecrement64((volatile signed __int64 *)BugCheckParameter2);
if( v7 == 2 )
{
if( (*(_DWORD *)(BugCheckParameter2 + 184) & 0x40000) == 0 || *(_BYTE *)(v5 + 2936) != 1 )
return;
CmpDoQueueLateUnloadWorker(v5);
}
if( !v7 )
{
if( (*(_DWORD *)(BugCheckParameter2 + 184) & 0x40000) != 0 )
{
v11 = *(_QWORD *)(BugCheckParameter2 + 32);
CmpCleanUpKcbCacheWithLock((_CM_KEY_CONTROL_BLOCK *)BugCheckParameter2, a2);
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
*(_DWORD *)(v11 + 160) |= 0x80u;
*(_QWORD *)(v11 + 4216) = CurrentThread;
*(_DWORD *)(v11 + 4i64 * (_InterlockedExchangeAdd((volatile signed __int32 *)(v11 + 4276), 1u) & 0x7F) + 4280) = 31;
if( (*(_DWORD *)(v11 + 160) & 0x20) == 0
&& _InterlockedExchangeAdd((volatile signed __int32 *)(v11 + 4272), 0xFFFFFFFF) == 1 )
{
CmpDeleteHive((PVOID)v11);
}
}
else
{
v8 = *(_DWORD *)(BugCheckParameter2 + 8);
v9 = 0;
v10 = 0;
if( (v8 & 0x20000) == 0 )
v9 = a3 == 0;
if( (v8 & 0x20) == 0 )
v10 = v9;
if( CmpHoldLazyFlush
&& (*(_WORD *)(BugCheckParameter2 + 186) & 0x10) == 0
&& (*(_BYTE *)(BugCheckParameter2 + 8) & 8) == 0 )
{
v10 = 0;
}
if( v10 )
{
CmpAddToDelayedClose(BugCheckParameter2);
}
else
{
CmpCleanUpKcbCacheWithLock((_CM_KEY_CONTROL_BLOCK *)BugCheckParameter2, a2);
if( *(struct _KTHREAD **)(BugCheckParameter2 + 56) != KeGetCurrentThread()
&& (*(_DWORD *)(BugCheckParameter2 + 8) & 0x80000) != 0 )
{
CmpFreeKeyControlBlock((_CM_KEY_CONTROL_BLOCK *)BugCheckParameter2);
}
}
}
}
}Referenced by:
CmRenameKey
CmpCleanupDiscardReplacePost
CmpCommitDiscardReplacePost
CmpCommitRenameKeyUoW
CmpDrainDelayDerefContext
CmpEnumerateAllHigherLayerKcbs
CmpLightWeightCommitRenameKeyUoW
CmpLightWeightPrepareRenameKeyUoW
CmpUnfreezeHive