VfDeadlockAcquireResource
VOID __fastcall VfDeadlockAcquireResource(
VOID *Resource,
_VI_DEADLOCK_RESOURCE_TYPE Type,
_KTHREAD *Thread,
UINT64 TryAcquire,
VOID *Caller){
UINT64 v6;
_VI_DEADLOCK_RESOURCE_TYPE v8;
void *v9;
_VI_DEADLOCK_THREAD *v10;
VOID *v11;
void *v12;
VOID *v13;
UINT16 v14;
unsigned int v15;
volatile unsigned __int64 TickCountQuad;
_VI_DEADLOCK_THREAD *v17;
void *v18;
int v19;
_VI_DEADLOCK_RESOURCE *v20;
void *v21;
_VI_DEADLOCK_RESOURCE *v22;
UINT64 v23;
INT64 CurrentSpinNode;
_VI_DEADLOCK_THREAD *ThreadOwner;
unsigned __int16 v26;
INT64 v27;
__int64 v28;
_QWORD *p_Blink;
__int64 v30;
int v31;
_QWORD *v32;
_QWORD *v33;
_LIST_ENTRY *p_ResourceList;
_LIST_ENTRY *Flink;
INT64 v36;
_QWORD *v37;
int v38;
_QWORD *v39;
__int64 v40;
_LIST_ENTRY *v41;
_LIST_ENTRY *v42;
_LIST_ENTRY *v43;
_OWORD *v44;
__int64 v45;
UINT8 OldIrql;
VOID *ReservedThread;
PVOID ReservedResource;
unsigned int v49;
PVOID Entry;
int v51;
PVOID v52;
int v53;
PVOID v54;
PVOID ResourceToFree;
VOID *v56;
PVOID BackTrace[2];
__int128 v58;
__int128 v59;
__int128 v60;
v6 = Type;
v49 = TryAcquire;
v56 = Caller;
memset((INT64)BackTrace, 0i64);
v51 = 0;
v9 = 0i64;
ResourceToFree = 0i64;
Entry = 0i64;
if( (_DWORD)v6 == 8
&& (!VfWin32kDllBase
|| VfWin32kDllBase > (unsigned __int64)Caller
|| VfWin32kDllBase + (unsigned __int64)(unsigned int)VfWin32kSizeOfImage <= (unsigned __int64)Caller)
|| !(unsigned int)ViDeadlockCanProceed(Resource, v8)
|| (unsigned int)ViIsThreadInsidePagingCodePaths()
|| *((_DWORD *)ViDeadlockGlobals + 8196)
|| *((int *)ViDeadlockGlobals + 8282) > 1024 )
{
return;
}
v52 = 0i64;
v10 = 0i64;
v53 = ViDeadlockResourceTypeInfo[v6];
LODWORD(v11) = ViDeadlockAllocate(3);
ReservedThread = v11;
LODWORD(v12) = ViDeadlockAllocate(2);
v54 = v12;
LODWORD(v13) = ViDeadlockAllocate(1);
ReservedResource = v13;
v14 = RtlCaptureStackBackTrace(2ui64, 8ui64, BackTrace, 0i64);
v15 = v14;
if( !v14 )
{
BackTrace[0] = Caller;
v15 = 1;
}
if( v15 < 8 )
BackTrace[v15] = 0i64;
OldIrql = ViRaiseIrqlToDpcLevel();
ViDeadlockDetectionLock(1ui64);
TickCountQuad = KUSER_SHARED_DATA.TickCountQuad;
if( !ViDeadlockDetectionEnabled || (v52 = v54, v54 = 0i64, !v52) )
{
LABEL_50:
v18 = ReservedResource;
goto LABEL_51;
}
v10 = ViDeadlockSearchThread((_KTHREAD *)Thread);
if( !v10 )
{
v17 = ViDeadlockAddThread((_KTHREAD *)Thread, ReservedThread);
ReservedThread = 0i64;
v10 = v17;
if( !v17 )
{
v18 = ReservedResource;
v19 = 0;
goto LABEL_53;
}
LODWORD(v9) = 1;
}
if( (_DWORD)v6 != 8 )
{
v20 = ViDeadlockSearchResource(Resource, &Entry);
v21 = 0i64;
v22 = v20;
if( !v20 )
{
v18 = ReservedResource;
if( !(unsigned int)ViDeadlockAddResource(
Resource,
(_VI_DEADLOCK_RESOURCE_TYPE)v6,
ReservedResource,
BackTrace,
&ResourceToFree,
&Entry) )
{
if( (_DWORD)v9 )
{
v19 = 1;
ViDeadlockRemoveThread(v10, 0i64);
goto LABEL_52;
}
LABEL_51:
v19 = 0;
goto LABEL_52;
}
ReservedResource = 0i64;
v22 = ViDeadlockSearchResource(Resource, &Entry);
v21 = 0i64;
}
v23 = v22->Type;
if( (_DWORD)v23 != (_DWORD)v6 )
{
if( ((unsigned int)(v6 - 3) > 1 || (unsigned int)(v23 - 3) > 1)
&& ((_DWORD)v23 != 7 || (unsigned int)(v6 - 5) > 1) )
{
ViDeadlockPreprocessOptions(
&byte_140C12D88,
"Acquiring lock 0x%p using mismatched API for this lock type.",
0x1008ui64,
(UINT64)Resource,
v23,
v6);
VfReportIssueWithOptions(0xC4ui64, 0x1008ui64, (UINT64)Resource, v22->Type, v6, &byte_140C12D88);
goto LABEL_35;
}
v22->Type = v6;
}
if( (unsigned int)(v6 - 5) <= 1 )
CurrentSpinNode = (INT64)v10->CurrentSpinNode;
else
CurrentSpinNode = (INT64)v10->CurrentOtherNode;
ThreadOwner = v22->ThreadOwner;
if( ThreadOwner && ThreadOwner != v10 )
*((_WORD *)v22 + 3) = 0;
v26 = *((_WORD *)v22 + 3) + 1;
v22->ThreadOwner = v10;
*((_WORD *)v22 + 3) = v26;
if( CurrentSpinNode )
{
if( v26 > 1u )
{
if( (v53 & 1) != 0 )
goto LABEL_20;
ViDeadlockPreprocessOptions(
&dword_140C12D8C,
"Lock 0x%p doesn't support recursive acquire.",
0x1000ui64,
(UINT64)Resource,
(UINT64)v22,
(UINT64)v10);
VfReportIssueWithOptions(0xC4ui64, 0x1000ui64, (UINT64)Resource, (UINT64)v22, (UINT64)v10, &dword_140C12D8C);
LABEL_35:
v18 = ReservedResource;
v19 = 0;
goto LABEL_52;
}
v27 = v49;
v28 = *(_QWORD *)(CurrentSpinNode + 8);
if( v28 != CurrentSpinNode + 8 )
{
while( 1 )
{
p_Blink = (_QWORD *)(v28 - 24);
if( (unsigned int)ViDeadlockSimilarNode((INT64)Resource, v27, v28 - 24) )
break;
if( v28 == v30 )
goto LABEL_47;
}
ViDeadlockCheckDuplicatesAmongChildren(CurrentSpinNode, (INT64)p_Blink, (INT64 **)&Entry);
goto LABEL_85;
}
LABEL_47:
if( *((_WORD *)v22 + 2) )
{
if( !(_DWORD)v27 )
{
v31 = ViDeadlockAnalyze(Resource, (_VI_DEADLOCK_NODE *)CurrentSpinNode, 1ui64, 0i64, v56);
v21 = 0i64;
if( v31 )
goto LABEL_50;
}
}
}
else
{
p_ResourceList = &v22->ResourceList;
Flink = v22->ResourceList.Flink;
if( Flink != &v22->ResourceList )
{
v36 = v49;
while( 1 )
{
p_Blink = &Flink[-3].Blink;
Flink = Flink->Flink;
if( (void *)*p_Blink == v21 )
{
if( (unsigned int)ViDeadlockSimilarNode((INT64)Resource, v36, (INT64)p_Blink) )
break;
}
if( Flink == p_ResourceList )
goto LABEL_76;
}
ViDeadlockCheckDuplicatesAmongRoots((INT64)p_Blink, (INT64 **)&Entry);
goto LABEL_85;
}
LABEL_76:
v51 = 1;
}
p_Blink = v52;
v52 = v21;
p_Blink[9] = 0i64;
p_Blink[8] = v21;
v37 = p_Blink + 3;
p_Blink[10] = v21;
p_Blink[18] = v21;
*p_Blink = CurrentSpinNode;
p_Blink[7] = v22;
v38 = *((_DWORD *)ViDeadlockGlobals + 8201);
p_Blink[2] = p_Blink + 1;
p_Blink[1] = p_Blink + 1;
p_Blink[4] = p_Blink + 3;
p_Blink[3] = p_Blink + 3;
*((_DWORD *)p_Blink + 18) = 2 * (v49 & 1 | (4 * v38));
if( v51 == (_DWORD)v21 )
{
v39 = (_QWORD *)(CurrentSpinNode + 8);
v40 = *(_QWORD *)(CurrentSpinNode + 8);
if( *(_QWORD *)(v40 + 8) != CurrentSpinNode + 8 )
goto LABEL_81;
*v37 = v40;
p_Blink[4] = v39;
*(_QWORD *)(v40 + 8) = v37;
*v39 = v37;
ViDeadlockUpdateChildrenCount((_VI_DEADLOCK_NODE *)CurrentSpinNode, 1i64);
}
v41 = &v22->ResourceList;
v42 = v22->ResourceList.Flink;
v43 = (_LIST_ENTRY *)(p_Blink + 5);
if( v42->Blink == &v22->ResourceList )
{
v43->Flink = v42;
p_Blink[6] = v41;
v42->Blink = v43;
v41->Flink = v43;
++*((_WORD *)v22 + 2);
if( (unsigned __int16)*((_DWORD *)v22 + 1) > 0xFFF0u )
ViDeadlockState |= 0x20u;
LABEL_85:
if( p_Blink )
{
*((_DWORD *)p_Blink + 18) |= 1u;
p_Blink[8] = v10;
if( (unsigned int)(v6 - 5) <= 1 )
v10->CurrentSpinNode = (_VI_DEADLOCK_NODE *)p_Blink;
else
v10->CurrentOtherNode = (_VI_DEADLOCK_NODE *)p_Blink;
++v10->NodeCount;
v44 = (_OWORD *)*p_Blink;
if( *p_Blink )
{
*((_OWORD *)p_Blink + 9) = v44[5];
*((_OWORD *)p_Blink + 10) = v44[6];
*((_OWORD *)p_Blink + 11) = v44[7];
*((_OWORD *)p_Blink + 12) = v44[8];
}
v45 = p_Blink[7];
*((_OWORD *)p_Blink + 5) = *(_OWORD *)BackTrace;
*((_OWORD *)p_Blink + 6) = v58;
*((_OWORD *)p_Blink + 7) = v59;
*((_OWORD *)p_Blink + 8) = v60;
*(_OWORD *)(v45 + 120) = *((_OWORD *)p_Blink + 5);
*(_OWORD *)(v45 + 136) = *((_OWORD *)p_Blink + 6);
*(_OWORD *)(v45 + 152) = *((_OWORD *)p_Blink + 7);
*(_OWORD *)(v45 + 168) = *((_OWORD *)p_Blink + 8);
}
goto LABEL_20;
}
LABEL_81:
__fastfail(3u);
}
v10->ThreadUsesEresources = 1;
LABEL_20:
v18 = ReservedResource;
v19 = 0;
LABEL_52:
v9 = ReservedThread;
LABEL_53:
if( (signed __int64)(KUSER_SHARED_DATA.TickCountQuad - TickCountQuad) > *(_QWORD *)ViDeadlockGlobals )
*(_QWORD *)ViDeadlockGlobals = KUSER_SHARED_DATA.TickCountQuad - TickCountQuad;
ViDeadlockDetectionUnlock(1ui64);
ViLowerIrql(OldIrql);
v32 = Entry;
if( Entry )
{
do
{
v33 = (_QWORD *)*v32;
ViDeadlockFree(v32, 2);
v32 = v33;
}
while( v33 );
}
if( ResourceToFree )
ViDeadlockFree(ResourceToFree, 1);
if( v19 )
ViDeadlockFree(v10, 3);
if( v52 )
ViDeadlockFree(v52, 2);
if( v18 )
ViDeadlockFree(v18, 1);
if( v54 )
ViDeadlockFree(v54, 2);
if( v9 )
ViDeadlockFree(v9, 3);
}Referenced by:
VerifierExAcquireFastMutex
VerifierExAcquireFastMutexUnsafe
VerifierExAcquireResourceExclusiveLite
VerifierExAcquireResourceSharedLite
VerifierExAcquireSharedStarveExclusive
VerifierExAcquireSharedWaitForExclusive
VerifierExEnterCriticalRegionAndAcquireResourceExclusive
VerifierExEnterCriticalRegionAndAcquireResourceShared
VerifierExEnterPriorityRegionAndAcquireResourceExclusive
VerifierExEnterPriorityRegionAndAcquireResourceShared
VerifierExTryToAcquireFastMutex
VerifierKeAcquireInStackQueuedSpinLock
VerifierKeAcquireInStackQueuedSpinLockAtDpcLevel
VerifierKeAcquireInStackQueuedSpinLockForDpc
VerifierKeAcquireInStackQueuedSpinLockRaiseToSynch
VerifierKeAcquireSpinLockAtDpcLevel
VerifierKeAcquireSpinLockRaiseToDpc
VerifierKeInitializeMutant
VerifierKeTryToAcquireSpinLockAtDpcLevel
ViKeObjectAcquired