ExpReleaseResourceSharedForThreadLite

NTSTATUS __stdcall ExpReleaseResourceSharedForThreadLite(PVOID BugCheckParameter1, PVOID BugCheckParameter2){
  _KSPIN_LOCK_QUEUE *v2; 
  _KSPIN_LOCK_QUEUE *v3; 
  __int64 v4; 
  unsigned int v6; 
  PVOID v7; 
  unsigned int *v8; 
  unsigned int v9; 
  unsigned __int64 v10; 
  unsigned int v11; 
  __int64 v12; 
  int v13; 
  int v14; 
  bool v15; 
  unsigned int v16; 
  _KSPIN_LOCK_QUEUE *v17; 
  _ADJUST_REASON v18; 
  NTSTATUS result; 
  char v20; 
  unsigned int *v21; 
  unsigned __int64 v22; 
  __int64 v23; 
  unsigned int *v24; 
  unsigned __int64 v25; 
  char *v26; 
  char *v27; 
  __int64 *v28; 
  __int64 v29; 
  __int64 **v30; 
  struct _KPRCB *CurrentPrcb; 
  _QWORD *v32; 
  _QWORD *v33; 
  _KWAIT_BLOCK *v34; 
  _LIST_ENTRY *Flink; 
  _KWAIT_BLOCK *v36; 
  _KWAIT_BLOCK **Blink; 
  int v38; 
  _KSPIN_LOCK_QUEUE *Next; 
  unsigned __int8 WaitType; 
  char v41; 
  __int64 **v42; 
  __int64 v43; 
  _QWORD *v44; 
  _ETHREAD *v45; 
  char v46; 
  int v47; 
  _ETHREAD **QuantumTarget; 
  _ETHREAD *Object; 
  _QWORD *v50; 
  _KWAIT_BLOCK *Entry; 
  __int64 v52; 
  _QWORD *v53; 
  _KPRCB *Prcb; 
  _ETHREAD *CurrentThread; 
  _KWAIT_BLOCK *v56; 
  UINT8 OldIrql; 
  UINT64 SpinCount; 
  UINT64 ContentionCount; 
  _QWORD *v60; 

  v3 = v2;
  v4 = 0i64;
  v60 = 0i64;
  if( ((unsigned __int8)BugCheckParameter2 & 3) != 0 )
    v6 = 0;
  else
    v6 = *((unsigned __int8 *)BugCheckParameter2 + 649);
  v7 = (PVOID)*((_QWORD *)BugCheckParameter1 + 6);
  v8 = (unsigned int *)((char *)BugCheckParameter1 + 48);
  if( v7 != BugCheckParameter2 )
  {
    v21 = (unsigned int *)((char *)BugCheckParameter1 + 48);
    v22 = v7 != 0i64;
    if( v7 )
      v21 = 0i64;
    if( !v6
      || (v23 = *((_QWORD *)BugCheckParameter1 + 2)) == 0
      || v6 >= *(_DWORD *)(v23 + 8)
      || (v8 = (unsigned int *)(v23 + 16i64 * v6), *(PVOID *)v8 != BugCheckParameter2) )
    {
      v24 = (unsigned int *)*((_QWORD *)BugCheckParameter1 + 2);
      v25 = *((unsigned int *)BugCheckParameter1 + 16) + (unsigned __int64)*((unsigned int *)BugCheckParameter1 + 18);
      if( !v24 || (v8 = v24 + 4, v22 >= v25) )
LABEL_87:
        KeBugCheckEx(0xE3u, BugCheckParameter1, BugCheckParameter2, v24, (PVOID)2);
      while( 1 )
      {
        v26 = (char *)v21;
        v27 = (char *)v21;
        if( *(PVOID *)v8 == BugCheckParameter2 )
          break;
        if( *(_QWORD *)v8 )
        {
          if( ++v22 == v25 )
            goto LABEL_87;
        }
        else
        {
          v21 = v8;
          if( v27 )
            v21 = (unsigned int *)v26;
        }
        v8 += 4;
        if( v8 == &v24[4 * v24[2]] )
          goto LABEL_87;
      }
      v4 = (__int64)v60;
      KeGetCurrentThread()->SchedulerApc.SpareByte0 = ((char *)v8 - (char *)v24) >> 4;
    }
  }
  v9 = v8[2] & 7 | (8 * (v8[2] >> 3) - 8);
  v8[2] = v9;
  if( v9 >= 8 )
  {
    _m_prefetchw(v3);
    Next = v3->Next;
    if( !v3->Next )
    {
      if( v3 == (_KSPIN_LOCK_QUEUE *)_InterlockedCompareExchange64(
                                        (volatile signed __int64 *)v3->Lock,
                                        0i64,
                                        (signed __int64)v3) )
      {
LABEL_60:
        result = KiIrqlFlags;
        __writecr8(LOBYTE(v3[1].Next));
        goto LABEL_28;
      }
      Next = KxWaitForLockChainValid(v3);
    }
    v3->Next = 0i64;
    _InterlockedXor64((volatile signed __int64 *)&Next->Lock, 1ui64);
    goto LABEL_60;
  }
  v10 = *(_QWORD *)v8;
  if( (v9 & 2) != 0 )
  {
    v10 &= 0xFFFFFFFFFFFFFFFCui64;
  }
  else if( (v10 & 3) != 0 )
  {
    goto LABEL_14;
  }
  if( v10 )
  {
    if( (v9 & 1) != 0 )
    {
      PsBoostThreadIoEx((_ETHREAD *)v10, 1u, 0, 0i64);
      v8[2] &= ~1u;
      v11 = v8[2];
    }
    else
    {
      LOBYTE(v11) = v9;
    }
    if( (v11 & 4) != 0 )
    {
      _InterlockedDecrement((volatile signed __int32 *)(v10 + 1364));
      v8[2] &= ~4u;
      v11 = v8[2];
      v4 = (__int64)v60;
    }
    if( (v11 & 2) != 0 )
    {
      ObDereferenceObjectDeferDelete(v10);
      v8[2] &= ~2u;
    }
  }
LABEL_14:
  *(_QWORD *)v8 = 0i64;
  v12 = 0i64;
  LODWORD(ContentionCount) = *((_DWORD *)BugCheckParameter1 + 17);
  v52 = 0i64;
  if( *((_DWORD *)BugCheckParameter1 + 16) > 1u )
  {
LABEL_17:
    v14 = 0;
    goto LABEL_18;
  }
  v13 = *((_DWORD *)BugCheckParameter1 + 19);
  if( v13 )
  {
    v28 = (__int64 *)*((_QWORD *)BugCheckParameter1 + 5);
    if( !v28 )
    {
LABEL_52:
      v52 = v12;
      *((_DWORD *)BugCheckParameter1 + 19) = v13 - 1;
      v14 = 1;
      *((_WORD *)BugCheckParameter1 + 13) |= 0x80u;
      goto LABEL_18;
    }
    if( (__int64 *)*v28 == v28 )
    {
      *((_QWORD *)BugCheckParameter1 + 5) = 0i64;
    }
    else
    {
      *((_QWORD *)BugCheckParameter1 + 5) = *v28;
      v29 = *v28;
      v30 = (__int64 **)v28[1];
      if( *(__int64 **)(*v28 + 8) != v28 || *v30 != v28 )
        goto LABEL_57;
      *v30 = (__int64 *)v29;
      *(_QWORD *)(v29 + 8) = v30;
    }
    v12 = v28[2];
    if( !v4 )
    {
      v28[1] = (__int64)v28;
      *v28 = (__int64)v28;
LABEL_51:
      v13 = *((_DWORD *)BugCheckParameter1 + 19);
      v60 = v28;
      goto LABEL_52;
    }
    v42 = *(__int64 ***)(v4 + 8);
    if( *v42 == (__int64 *)v4 )
    {
      *v28 = v4;
      v28[1] = (__int64)v42;
      *v42 = v28;
      *(_QWORD *)(v4 + 8) = v28;
      goto LABEL_51;
    }
LABEL_57:
    __fastfail(3u);
  }
  if( !*((_DWORD *)BugCheckParameter1 + 18) )
    goto LABEL_17;
  v43 = *((_QWORD *)BugCheckParameter1 + 4);
  *((_QWORD *)BugCheckParameter1 + 4) = 0i64;
  v14 = *((_DWORD *)BugCheckParameter1 + 18);
  *((_DWORD *)BugCheckParameter1 + 18) = 0;
  v60 = (_QWORD *)v43;
LABEL_18:
  v15 = v14 - 1 + *((_DWORD *)BugCheckParameter1 + 16) == 0;
  *((_DWORD *)BugCheckParameter1 + 16) += v14 - 1;
  if( v15 )
    *((_WORD *)BugCheckParameter1 + 12) = 0;
  if( !*((_DWORD *)BugCheckParameter1 + 19) && !*((_DWORD *)BugCheckParameter1 + 18) )
    *((_WORD *)BugCheckParameter1 + 13) &= 0xF9u;
  v16 = *((unsigned __int8 *)BugCheckParameter1 + 27);
  if( v12 )
  {
    v38 = *((_DWORD *)BugCheckParameter1 + 14) & 7;
    *((_QWORD *)BugCheckParameter1 + 6) = v12;
    *((_DWORD *)BugCheckParameter1 + 14) = v38 | 8;
  }
  _m_prefetchw(v3);
  v17 = v3->Next;
  if( v3->Next )
    goto LABEL_43;
  if( v3 != (_KSPIN_LOCK_QUEUE *)_InterlockedCompareExchange64(
                                    (volatile signed __int64 *)v3->Lock,
                                    0i64,
                                    (signed __int64)v3) )
  {
    v17 = KxWaitForLockChainValid(v3);
LABEL_43:
    v3->Next = 0i64;
    _InterlockedXor64((volatile signed __int64 *)&v17->Lock, 1ui64);
  }
  __writecr8(LOBYTE(v3[1].Next));
  v18 = AdjustUnwait;
  result = v52 != 0;
  v20 = 2 * result + 1;
  if( !v60 )
    goto LABEL_28;
  OldIrql = KeGetCurrentIrql();
  __writecr8(2ui64);
  CurrentPrcb = KeGetCurrentPrcb();
  v32 = v60;
  do
  {
    v33 = v32;
    LODWORD(SpinCount) = 0;
    v32 = (_QWORD *)*v32;
    v50 = v32;
    if( _interlockedbittestandset((volatile signed __int32 *)v33 + 6, 7u) )
    {
      do
      {
        do
          KeYieldProcessorEx(&SpinCount);
        while( (*((_DWORD *)v33 + 6) & 0x80u) != 0 );
      }
      while( _interlockedbittestandset((volatile signed __int32 *)v33 + 6, 7u) );
      v32 = v50;
    }
    *((_DWORD *)v33 + 7) = 1;
    v34 = (_KWAIT_BLOCK *)v33[4];
    if( v34 != (_KWAIT_BLOCK *)(v33 + 4) )
    {
      while( 1 )
      {
        Flink = v34->WaitListEntry.Flink;
        v36 = v34;
        Entry = v34;
        Blink = (_KWAIT_BLOCK **)v34->WaitListEntry.Blink;
        v56 = (_KWAIT_BLOCK *)Flink;
        if( (_KWAIT_BLOCK *)Flink->Blink != v36 || *Blink != v36 )
          goto LABEL_57;
        *Blink = (_KWAIT_BLOCK *)Flink;
        Flink->Blink = (_LIST_ENTRY *)Blink;
        WaitType = v36->WaitType;
        if( WaitType == 1 )
        {
          if( KiTryUnwaitThread(CurrentPrcb, v36, v36->WaitKey, 0i64) )
          {
            v15 = (*((_DWORD *)v33 + 7))-- == 1;
            if( v15 )
            {
LABEL_67:
              v32 = v50;
              break;
            }
          }
        }
        else
        {
          if( WaitType == 2 )
          {
            v36->BlockState = 5;
            Object = v36->Thread;
            v53 = &Object->Tcb.gap0[8];
            v36->WaitListEntry.Flink = 0i64;
            KeGetCurrentIrql();
            __writecr8(2ui64);
            Prcb = KeGetCurrentPrcb();
            CurrentThread = Prcb->CurrentThread;
            KiAcquireKobjectLockSafe(Object);
            v44 = v53;
            v45 = Object;
            if( (_QWORD *)*v44 == v44
              || LODWORD(Object->Tcb.InitialStack) >= HIDWORD(Object->Tcb.InitialStack)
              || (_ETHREAD *)CurrentThread->Tcb.Queue == Object && CurrentThread->Tcb.WaitReason == 15 )
            {
LABEL_98:
              v47 = *(_DWORD *)&v45->Tcb.gap0[4];
              *(_DWORD *)&v45->Tcb.gap0[4] = v47 + 1;
              QuantumTarget = (_ETHREAD **)v45->Tcb.QuantumTarget;
              if( *QuantumTarget != (_ETHREAD *)&v45->Tcb.SListFaultAddress )
                goto LABEL_57;
              Entry->WaitListEntry.Flink = (_LIST_ENTRY *)&v45->Tcb.SListFaultAddress;
              Entry->WaitListEntry.Blink = (_LIST_ENTRY *)QuantumTarget;
              *QuantumTarget = (_ETHREAD *)Entry;
              v45->Tcb.QuantumTarget = (unsigned __int64)Entry;
              if( !v47 && (_QWORD *)*v44 != v44 )
              {
                KiWakeOtherQueueWaiters(Prcb, (_KQUEUE *)v45);
                v45 = Object;
              }
            }
            else
            {
              KiWakeQueueWaiter(Prcb, (_KQUEUE *)Object, (INT64)Entry);
              v45 = Object;
              if( !v46 )
              {
                v44 = &Object->Tcb.gap0[8];
                goto LABEL_98;
              }
            }
            _InterlockedAnd((volatile signed __int32 *)v45, 0xFFFFFF7F);
            v15 = (*((_DWORD *)v33 + 7))-- == 1;
            if( v15 )
              goto LABEL_67;
            goto LABEL_105;
          }
          KiTryUnwaitThread(CurrentPrcb, v36, 256i64, 0i64);
        }
LABEL_105:
        v34 = v56;
        if( v56 == (_KWAIT_BLOCK *)(v33 + 4) )
          goto LABEL_67;
      }
    }
    _InterlockedAnd((volatile signed __int32 *)v33 + 6, 0xFFFFFF7F);
  }
  while( v32 != v60 );
  KiRemoveBoostThread(CurrentPrcb, CurrentPrcb->CurrentThread);
  if( v16 )
  {
    v18 = AdjustBoost;
    if( v41 > (char)v16 )
      v16 = v41;
  }
  if( (v20 & 2) != 0 && v18 == AdjustUnwait )
    v16 = 1;
  KiExitDispatcher(CurrentPrcb, 0i64, v18, v16, OldIrql);
LABEL_28:
  __incgsdword(0x8670u);
  return result;
}

Referenced by:

ExReleaseResourceAndLeaveCriticalRegion
ExReleaseResourceForThreadLite
ExReleaseResourceLite