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