VfDeadlockAcquireResource
VOID __fastcall VfDeadlockAcquireResource(VOID *Resource, INT64 a2, _ETHREAD *a3, UINT64 a4, INT64 a5){
UINT64 Param4;
_VI_DEADLOCK_RESOURCE_TYPE v8;
VOID *v9;
_VI_DEADLOCK_THREAD *v10;
UINT16 v11;
unsigned int v12;
volatile unsigned __int64 TickCountQuad;
_VI_DEADLOCK_THREAD *v14;
VOID *v15;
int v16;
_VI_DEADLOCK_RESOURCE *v17;
_VI_DEADLOCK_THREAD *v18;
_VI_DEADLOCK_RESOURCE *v19;
UINT64 Type;
_VI_DEADLOCK_NODE *CurrentSpinNode;
_VI_DEADLOCK_THREAD *ThreadOwner;
unsigned __int16 v23;
UINT64 v24;
_LIST_ENTRY *Flink;
_VI_DEADLOCK_NODE *p_Blink;
_LIST_ENTRY *v27;
int v28;
_QWORD *v29;
_QWORD *v30;
_LIST_ENTRY *p_ResourceList;
_LIST_ENTRY *v32;
UINT64 v33;
_LIST_ENTRY *p_SiblingsList;
int v35;
_LIST_ENTRY *p_ChildrenList;
_LIST_ENTRY *v37;
_LIST_ENTRY *v38;
_LIST_ENTRY *v39;
$40597CAD8088CB40007EECA86A191ECD *v40;
_VI_DEADLOCK_NODE *Parent;
_VI_DEADLOCK_RESOURCE *Root;
UINT64 a7;
VOID *ReservedThread;
VOID *ReservedResource;
unsigned int TryNode;
VOID *NodesToFree;
int v48;
VOID *v49;
int v50;
VOID *v51;
VOID *Object;
VOID *Caller;
VOID *BackTrace[8];
Param4 = (int)a2;
TryNode = a4;
Caller = (VOID *)a5;
memset(BackTrace, 0i64, sizeof(BackTrace));
v48 = 0;
v9 = 0i64;
LODWORD(a7) = 0;
Object = 0i64;
NodesToFree = 0i64;
if( (_DWORD)Param4 == 8
&& (!VfWin32kDllBase
|| VfWin32kDllBase > (unsigned __int64)a5
|| VfWin32kDllBase + (unsigned __int64)(unsigned int)VfWin32kSizeOfImage <= a5)
|| !(unsigned int)ViDeadlockCanProceed(Resource, v8)
|| (unsigned int)ViIsThreadInsidePagingCodePaths()
|| *((_DWORD *)ViDeadlockGlobals + 8196)
|| *((int *)ViDeadlockGlobals + 8282) > 1024 )
{
return;
}
v49 = 0i64;
v10 = 0i64;
v50 = ViDeadlockResourceTypeInfo[Param4];
ReservedThread = ViDeadlockAllocate(ViDeadlockThread);
v51 = ViDeadlockAllocate(ViDeadlockNode);
ReservedResource = ViDeadlockAllocate(ViDeadlockResource);
v11 = RtlCaptureStackBackTrace(2ui64, 8ui64, BackTrace, 0i64);
v12 = v11;
if( !v11 )
{
BackTrace[0] = (VOID *)a5;
v12 = 1;
}
if( v12 < 8 )
BackTrace[v12] = 0i64;
BYTE4(a7) = ViRaiseIrqlToDpcLevel();
ViDeadlockDetectionLock(1ui64);
TickCountQuad = KUSER_SHARED_DATA.TickCountQuad;
if( !ViDeadlockDetectionEnabled || (v49 = v51, v51 = 0i64, !v49) )
{
LABEL_50:
v15 = ReservedResource;
goto LABEL_51;
}
v10 = ViDeadlockSearchThread(&a3->Tcb);
if( !v10 )
{
v14 = ViDeadlockAddThread(&a3->Tcb, ReservedThread);
ReservedThread = 0i64;
v10 = v14;
if( !v14 )
{
v15 = ReservedResource;
v16 = 0;
goto LABEL_53;
}
LODWORD(v9) = 1;
}
if( (_DWORD)Param4 != 8 )
{
v17 = ViDeadlockSearchResource(Resource, &NodesToFree);
v18 = 0i64;
v19 = v17;
if( !v17 )
{
v15 = ReservedResource;
if( !(unsigned int)ViDeadlockAddResource(
Resource,
(_VI_DEADLOCK_RESOURCE_TYPE)Param4,
ReservedResource,
BackTrace,
&Object,
&NodesToFree) )
{
if( (_DWORD)v9 )
{
v16 = 1;
ViDeadlockRemoveThread(v10, 0i64);
goto LABEL_52;
}
LABEL_51:
v16 = 0;
goto LABEL_52;
}
ReservedResource = 0i64;
v19 = ViDeadlockSearchResource(Resource, &NodesToFree);
v18 = 0i64;
}
Type = v19->Type;
if( (_DWORD)Type != (_DWORD)Param4 )
{
if( ((unsigned int)(Param4 - 3) > 1 || (unsigned int)(Type - 3) > 1)
&& ((_DWORD)Type != 7 || (unsigned int)(Param4 - 5) > 1) )
{
ViDeadlockPreprocessOptions(
(UINT64 *)((char *)&qword_140C12D84 + 4),
(CHAR *)"Acquiring lock 0x%p using mismatched API for this lock type.",
0x1008ui64,
(UINT64)Resource,
Type,
Param4,
a7);
VfReportIssueWithOptions(
0xC4ui64,
0x1008u,
(ULONG_PTR)Resource,
v19->Type,
Param4,
(UINT64 *)((char *)&qword_140C12D84 + 4));
goto LABEL_35;
}
v19->Type = Param4;
}
if( (unsigned int)(Param4 - 5) <= 1 )
CurrentSpinNode = v10->CurrentSpinNode;
else
CurrentSpinNode = v10->CurrentOtherNode;
ThreadOwner = v19->ThreadOwner;
if( ThreadOwner && ThreadOwner != v10 )
*((_WORD *)v19 + 3) = 0;
v23 = *((_WORD *)v19 + 3) + 1;
v19->ThreadOwner = v10;
*((_WORD *)v19 + 3) = v23;
if( CurrentSpinNode )
{
if( v23 > 1u )
{
if( (v50 & 1) != 0 )
goto LABEL_20;
ViDeadlockPreprocessOptions(
&unk_140C12D8C,
(CHAR *)"Lock 0x%p doesn't support recursive acquire.",
0x1000ui64,
(UINT64)Resource,
(UINT64)v19,
(UINT64)v10,
a7);
VfReportIssueWithOptions(0xC4ui64, 0x1000u, (ULONG_PTR)Resource, (ULONG_PTR)v19, (ULONG_PTR)v10, &unk_140C12D8C);
LABEL_35:
v15 = ReservedResource;
v16 = a7;
goto LABEL_52;
}
v24 = TryNode;
Flink = CurrentSpinNode->ChildrenList.Flink;
if( Flink != &CurrentSpinNode->ChildrenList )
{
while( 1 )
{
p_Blink = (_VI_DEADLOCK_NODE *)&Flink[-2].Blink;
if( (unsigned int)ViDeadlockSimilarNode(Resource, v24, (_VI_DEADLOCK_NODE *)&Flink[-2].Blink) )
break;
if( Flink == v27 )
goto LABEL_47;
}
ViDeadlockCheckDuplicatesAmongChildren((INT64)CurrentSpinNode, (INT64)p_Blink, (INT64 **)&NodesToFree);
goto LABEL_85;
}
LABEL_47:
if( *((_WORD *)v19 + 2) )
{
if( !(_DWORD)v24 )
{
v28 = ViDeadlockAnalyze(Resource, CurrentSpinNode, 1ui64, 0i64, Caller);
v18 = 0i64;
if( v28 )
goto LABEL_50;
}
}
}
else
{
p_ResourceList = &v19->ResourceList;
v32 = v19->ResourceList.Flink;
if( v32 != &v19->ResourceList )
{
v33 = TryNode;
while( 1 )
{
p_Blink = (_VI_DEADLOCK_NODE *)&v32[-3].Blink;
v32 = v32->Flink;
if( (_VI_DEADLOCK_THREAD *)p_Blink->Parent == v18 )
{
if( (unsigned int)ViDeadlockSimilarNode(Resource, v33, p_Blink) )
break;
}
if( v32 == p_ResourceList )
goto LABEL_76;
}
ViDeadlockCheckDuplicatesAmongRoots((INT64)p_Blink, (INT64 **)&NodesToFree);
goto LABEL_85;
}
LABEL_76:
v48 = 1;
}
p_Blink = (_VI_DEADLOCK_NODE *)v49;
v49 = v18;
*(_QWORD *)&p_Blink->u1.0 = 0i64;
p_Blink->ThreadEntry = v18;
p_SiblingsList = &p_Blink->SiblingsList;
p_Blink->StackTrace[0] = v18;
p_Blink->ParentStackTrace[0] = v18;
p_Blink->Parent = CurrentSpinNode;
p_Blink->Root = v19;
v35 = *((_DWORD *)ViDeadlockGlobals + 8201);
p_Blink->ChildrenList.Blink = &p_Blink->ChildrenList;
p_Blink->ChildrenList.Flink = &p_Blink->ChildrenList;
p_Blink->SiblingsList.Blink = &p_Blink->SiblingsList;
p_Blink->SiblingsList.Flink = &p_Blink->SiblingsList;
p_Blink->u1.Whole = 2 * (TryNode & 1 | (4 * v35));
if( v48 == (_DWORD)v18 )
{
p_ChildrenList = &CurrentSpinNode->ChildrenList;
v37 = CurrentSpinNode->ChildrenList.Flink;
if( v37->Blink != &CurrentSpinNode->ChildrenList )
goto LABEL_81;
p_SiblingsList->Flink = v37;
p_Blink->SiblingsList.Blink = p_ChildrenList;
v37->Blink = p_SiblingsList;
p_ChildrenList->Flink = p_SiblingsList;
ViDeadlockUpdateChildrenCount(CurrentSpinNode, 1i64);
}
v38 = &v19->ResourceList;
v39 = v19->ResourceList.Flink;
v40 = &p_Blink->40;
if( v39->Blink == &v19->ResourceList )
{
v40->ResourceList.Flink = v39;
p_Blink->ResourceList.Blink = v38;
v39->Blink = &v40->ResourceList;
v38->Flink = &v40->ResourceList;
++*((_WORD *)v19 + 2);
if( (unsigned __int16)*((_DWORD *)v19 + 1) > 0xFFF0u )
ViDeadlockState |= 0x20u;
LABEL_85:
if( p_Blink )
{
p_Blink->u1.Whole |= 1u;
p_Blink->ThreadEntry = v10;
if( (unsigned int)(Param4 - 5) <= 1 )
v10->CurrentSpinNode = p_Blink;
else
v10->CurrentOtherNode = p_Blink;
++v10->NodeCount;
Parent = p_Blink->Parent;
if( p_Blink->Parent )
{
*(_OWORD *)p_Blink->ParentStackTrace = *(_OWORD *)Parent->StackTrace;
*(_OWORD *)&p_Blink->ParentStackTrace[2] = *(_OWORD *)&Parent->StackTrace[2];
*(_OWORD *)&p_Blink->ParentStackTrace[4] = *(_OWORD *)&Parent->StackTrace[4];
*(_OWORD *)&p_Blink->ParentStackTrace[6] = *(_OWORD *)&Parent->StackTrace[6];
}
Root = p_Blink->Root;
*(_OWORD *)p_Blink->StackTrace = *(_OWORD *)BackTrace;
*(_OWORD *)&p_Blink->StackTrace[2] = *(_OWORD *)&BackTrace[2];
*(_OWORD *)&p_Blink->StackTrace[4] = *(_OWORD *)&BackTrace[4];
*(_OWORD *)&p_Blink->StackTrace[6] = *(_OWORD *)&BackTrace[6];
*(_OWORD *)Root->LastAcquireTrace = *(_OWORD *)p_Blink->StackTrace;
*(_OWORD *)&Root->LastAcquireTrace[2] = *(_OWORD *)&p_Blink->StackTrace[2];
*(_OWORD *)&Root->LastAcquireTrace[4] = *(_OWORD *)&p_Blink->StackTrace[4];
*(_OWORD *)&Root->LastAcquireTrace[6] = *(_OWORD *)&p_Blink->StackTrace[6];
}
goto LABEL_20;
}
LABEL_81:
__fastfail(3u);
}
v10->ThreadUsesEresources = 1;
LABEL_20:
v15 = ReservedResource;
v16 = 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(BYTE4(a7));
v29 = NodesToFree;
if( NodesToFree )
{
do
{
v30 = (_QWORD *)*v29;
ViDeadlockFree(v29, ViDeadlockNode);
v29 = v30;
}
while( v30 );
}
if( Object )
ViDeadlockFree(Object, ViDeadlockResource);
if( v16 )
ViDeadlockFree(v10, ViDeadlockThread);
if( v49 )
ViDeadlockFree(v49, ViDeadlockNode);
if( v15 )
ViDeadlockFree(v15, ViDeadlockResource);
if( v51 )
ViDeadlockFree(v51, ViDeadlockNode);
if( v9 )
ViDeadlockFree(v9, ViDeadlockThread);
}Referenced by:
VerifierExAcquireFastMutex
VerifierExAcquireFastMutexUnsafe
VerifierExAcquireResourceExclusiveLite
VerifierExAcquireResourceSharedLite
VerifierExAcquireSharedStarveExclusive
VerifierExAcquireSharedWaitForExclusive
VerifierExEnterCriticalRegionAndAcquireResourceExclusive
VerifierExEnterCriticalRegionAndAcquireResourceShared
VerifierExEnterPriorityRegionAndAcquireResourceExclusive
VerifierExEnterPriorityRegionAndAcquireResourceShared
VerifierExTryToAcquireFastMutex
VerifierKeAcquireInStackQueuedSpinLock
VerifierKeAcquireInStackQueuedSpinLockAtDpcLevel
VerifierKeAcquireInStackQueuedSpinLockForDpc
VerifierKeAcquireInStackQueuedSpinLockRaiseToSynch
VerifierKeAcquireSpinLockAtDpcLevel
VerifierKeAcquireSpinLockRaiseToDpc
VerifierKeInitializeMutant
VerifierKeTryToAcquireSpinLockAtDpcLevel
ViKeObjectAcquired