ExpReleaseResourceExclusiveForThreadLite

NTSTATUS __stdcall ExpReleaseResourceExclusiveForThreadLite(PVOID BugCheckParameter1, PVOID BugCheckParameter2){
  _KSPIN_LOCK_QUEUE *v2; 
  signed __int64 v3; 
  unsigned int v5; 
  int v6; 
  signed __int64 v7; 
  __int64 v8; 
  int v9; 
  int v10; 
  unsigned int v11; 
  _KSPIN_LOCK_QUEUE *v12; 
  _ADJUST_REASON v13; 
  NTSTATUS result; 
  char v15; 
  _KSPIN_LOCK_QUEUE *Next; 
  _KPRCB *CurrentPrcb; 
  volatile signed __int32 *v18; 
  _KWAIT_BLOCK *v19; 
  _LIST_ENTRY *Flink; 
  _KWAIT_BLOCK *v21; 
  _KWAIT_BLOCK **Blink; 
  unsigned __int8 WaitType; 
  bool v24; 
  CHAR v25; 
  volatile signed __int32 *v26; 
  int v27; 
  volatile signed __int32 *v28; 
  int v29; 
  __int64 v30; 
  volatile signed __int32 **v31; 
  volatile signed __int32 *v32; 
  _LIST_ENTRY *v33; 
  _KQUEUE *v34; 
  UINT8 v35; 
  int SignalState; 
  _LIST_ENTRY *v37; 
  _KQUEUE *Object; 
  volatile signed __int32 *v39; 
  volatile signed __int32 *v40; 
  _KPRCB *Prcb; 
  _KWAIT_BLOCK *Entry; 
  volatile signed __int32 *v43; 
  __int64 v44; 
  _LIST_ENTRY *p_WaitListHead; 
  _KPRCB *v46; 
  __int64 v47; 
  _KWAIT_BLOCK *v48; 
  UINT8 CurrentIrql; 
  UINT64 SpinCount; 
  unsigned int v51; 
  v3 = (signed __int64)v2;
  if( ((*((_BYTE *)BugCheckParameter1 + 26) & 1) != 0 || ExpResourceEnforceOwnerTransfer)
    && *((PVOID *)BugCheckParameter1 + 6) != BugCheckParameter2 )
  {
    KeBugCheckEx(
      0xE3u,
      (ULONG_PTR)BugCheckParameter1,
      (ULONG_PTR)BugCheckParameter2,
      *((_QWORD *)BugCheckParameter1 + 2),
      1ui64);
  }
  v5 = *((_DWORD *)BugCheckParameter1 + 14) & 7 | (8 * (*((_DWORD *)BugCheckParameter1 + 14) >> 3) - 8);
  *((_DWORD *)BugCheckParameter1 + 14) = v5;
  if( v5 >> 3 )
  {
    _m_prefetchw(v2);
    Next = v2->Next;
    if( !v2->Next )
    {
      if( v2 == (_KSPIN_LOCK_QUEUE *)_InterlockedCompareExchange64(
                                        (volatile signed __int64 *)v2->Lock,
                                        0i64,
                                        (signed __int64)v2) )
      {
LABEL_28:
        result = KiIrqlFlags;
        __writecr8(*(unsigned __int8 *)(v3 + 16));
        goto LABEL_25;
      }
      Next = KxWaitForLockChainValid(v2);
    }
    *(_QWORD *)v3 = 0i64;
    _InterlockedXor64((volatile signed __int64 *)&Next->Lock, 1ui64);
    goto LABEL_28;
  }
  v6 = *((_DWORD *)BugCheckParameter1 + 14);
  v7 = *((_QWORD *)BugCheckParameter1 + 6);
  if( (v6 & 2) != 0 )
  {
    v7 &= 0xFFFFFFFFFFFFFFFCui64;
  }
  else if( (v7 & 3) != 0 )
  {
    goto LABEL_13;
  }
  if( v7 )
  {
    if( (v6 & 1) != 0 )
    {
      PsBoostThreadIoEx(v7, 1, 0, 0i64);
      *((_DWORD *)BugCheckParameter1 + 14) &= ~1u;
      v6 = *((_DWORD *)BugCheckParameter1 + 14);
    }
    if( (v6 & 4) != 0 )
    {
      _InterlockedDecrement((volatile signed __int32 *)(v7 + 1364));
      *((_DWORD *)BugCheckParameter1 + 14) &= ~4u;
      v6 = *((_DWORD *)BugCheckParameter1 + 14);
    }
    if( (v6 & 2) != 0 )
    {
      ObDereferenceObjectDeferDelete((PVOID)v7);
      *((_DWORD *)BugCheckParameter1 + 14) &= ~2u;
    }
  }
LABEL_13:
  v8 = 0i64;
  *((_QWORD *)BugCheckParameter1 + 6) = 0i64;
  v44 = 0i64;
  if( *((_DWORD *)BugCheckParameter1 + 18) )
  {
    v26 = (volatile signed __int32 *)*((_QWORD *)BugCheckParameter1 + 4);
    *((_QWORD *)BugCheckParameter1 + 4) = 0i64;
    v27 = *((_DWORD *)BugCheckParameter1 + 18);
    v40 = v26;
    *((_WORD *)BugCheckParameter1 + 13) &= ~0x80u;
    *((_DWORD *)BugCheckParameter1 + 18) = 0;
    if( !v27 )
      goto LABEL_16;
LABEL_45:
    v10 = v27 + *((_DWORD *)BugCheckParameter1 + 16) - 1;
    goto LABEL_17;
  }
  v9 = *((_DWORD *)BugCheckParameter1 + 19);
  v40 = 0i64;
  if( v9 )
  {
    v28 = (volatile signed __int32 *)*((_QWORD *)BugCheckParameter1 + 5);
    if( v28 )
    {
      if( *(volatile signed __int32 **)v28 == v28 )
      {
        *((_QWORD *)BugCheckParameter1 + 5) = 0i64;
      }
      else
      {
        *((_QWORD *)BugCheckParameter1 + 5) = *(_QWORD *)v28;
        v30 = *(_QWORD *)v28;
        v31 = (volatile signed __int32 **)*((_QWORD *)v28 + 1);
        if( *(volatile signed __int32 **)(*(_QWORD *)v28 + 8i64) != v28 || *v31 != v28 )
LABEL_33:
          __fastfail(3u);
        *v31 = (volatile signed __int32 *)v30;
        *(_QWORD *)(v30 + 8) = v31;
      }
      v8 = *((_QWORD *)v28 + 2);
      *((_QWORD *)v28 + 1) = v28;
      *(_QWORD *)v28 = v28;
      v9 = *((_DWORD *)BugCheckParameter1 + 19);
      v40 = v28;
    }
    v44 = v8;
    *((_DWORD *)BugCheckParameter1 + 19) = v9 - 1;
    v27 = 1;
    goto LABEL_45;
  }
  *((_WORD *)BugCheckParameter1 + 13) &= ~0x80u;
LABEL_16:
  *((_WORD *)BugCheckParameter1 + 12) = 0;
  v10 = 0;
LABEL_17:
  *((_DWORD *)BugCheckParameter1 + 16) = v10;
  if( !*((_DWORD *)BugCheckParameter1 + 19) && !*((_DWORD *)BugCheckParameter1 + 18) )
    *((_WORD *)BugCheckParameter1 + 13) &= 0xF9u;
  v11 = *((unsigned __int8 *)BugCheckParameter1 + 27);
  v51 = v11;
  if( v8 )
  {
    v29 = *((_DWORD *)BugCheckParameter1 + 14) & 7;
    *((_QWORD *)BugCheckParameter1 + 6) = v8;
    *((_DWORD *)BugCheckParameter1 + 14) = v29 | 8;
  }
  _m_prefetchw((const void *)v3);
  v12 = *(_KSPIN_LOCK_QUEUE **)v3;
  if( *(_QWORD *)v3 )
    goto LABEL_59;
  if( v3 != _InterlockedCompareExchange64(*(volatile signed __int64 **)(v3 + 8), 0i64, v3) )
  {
    v12 = KxWaitForLockChainValid((_KSPIN_LOCK_QUEUE *)v3);
LABEL_59:
    *(_QWORD *)v3 = 0i64;
    _InterlockedXor64((volatile signed __int64 *)&v12->Lock, 1ui64);
  }
  __writecr8(*(unsigned __int8 *)(v3 + 16));
  v13 = AdjustUnwait;
  result = v44 != 0;
  v15 = 2 * result + 1;
  if( !v40 )
    goto LABEL_25;
  CurrentIrql = KeGetCurrentIrql();
  __writecr8(2ui64);
  CurrentPrcb = KeGetCurrentPrcb();
  v18 = v40;
  v43 = v40;
  for( Prcb = CurrentPrcb; ; CurrentPrcb = Prcb )
  {
    LODWORD(SpinCount) = 0;
    v39 = v18;
    v43 = *(volatile signed __int32 **)v43;
    if( _interlockedbittestandset(v18 + 6, 7u) )
    {
      v32 = v18;
      do
      {
        do
          KeYieldProcessorEx(&SpinCount);
        while( (*((_DWORD *)v32 + 6) & 0x80u) != 0 );
      }
      while( _interlockedbittestandset(v32 + 6, 7u) );
      v11 = v51;
      v18 = v39;
      CurrentPrcb = Prcb;
    }
    *((_DWORD *)v18 + 7) = 1;
    v19 = (_KWAIT_BLOCK *)*((_QWORD *)v18 + 4);
    if( v19 != (_KWAIT_BLOCK *)(v18 + 8) )
    {
      while( 1 )
      {
        Flink = v19->WaitListEntry.Flink;
        v21 = v19;
        Blink = (_KWAIT_BLOCK **)v19->WaitListEntry.Blink;
        Entry = v21;
        v48 = (_KWAIT_BLOCK *)Flink;
        if( (_KWAIT_BLOCK *)Flink->Blink != v21 || *Blink != v21 )
          goto LABEL_33;
        *Blink = (_KWAIT_BLOCK *)Flink;
        Flink->Blink = (_LIST_ENTRY *)Blink;
        WaitType = v21->WaitType;
        if( WaitType != 1 )
          break;
        v24 = KiTryUnwaitThread(CurrentPrcb, v21, v21->WaitKey, 0i64) == 0;
        v18 = v39;
        if( !v24 )
        {
          v24 = (*((_DWORD *)v39 + 7))-- == 1;
          if( v24 )
            goto LABEL_38;
        }
LABEL_66:
        v19 = v48;
        CurrentPrcb = Prcb;
        if( v48 == (_KWAIT_BLOCK *)(v18 + 8) )
          goto LABEL_38;
      }
      if( WaitType != 2 )
      {
        KiTryUnwaitThread(CurrentPrcb, v21, 256i64, 0i64);
        v18 = v39;
        goto LABEL_66;
      }
      v21->BlockState = 5;
      Object = v21->NotificationQueue;
      p_WaitListHead = &Object->Header.WaitListHead;
      v21->WaitListEntry.Flink = 0i64;
      KeGetCurrentIrql();
      __writecr8(2ui64);
      v46 = KeGetCurrentPrcb();
      v47 = *((_QWORD *)v46 + 1);
      KiAcquireKobjectLockSafe(Object);
      v33 = p_WaitListHead;
      v34 = Object;
      if( v33->Flink != v33
        && Object->CurrentCount < Object->MaximumCount
        && (*(_KQUEUE **)(v47 + 232) != Object || *(_BYTE *)(v47 + 643) != 15) )
      {
        v35 = KiWakeQueueWaiter(v46, Object, (INT64)Entry);
        v34 = Object;
        if( v35 )
          goto LABEL_82;
        v33 = &Object->Header.WaitListHead;
      }
      SignalState = v34->Header.SignalState;
      v34->Header.SignalState = SignalState + 1;
      v37 = v34->EntryListHead.Blink;
      if( v37->Flink != &v34->EntryListHead )
        goto LABEL_33;
      Entry->WaitListEntry.Flink = &v34->EntryListHead;
      Entry->WaitListEntry.Blink = v37;
      v37->Flink = &Entry->WaitListEntry;
      v34->EntryListHead.Blink = &Entry->WaitListEntry;
      if( !SignalState && v33->Flink != v33 )
      {
        KiWakeOtherQueueWaiters(v46, v34);
        v34 = Object;
      }
LABEL_82:
      _InterlockedAnd(&v34->Header.Lock, 0xFFFFFF7F);
      v18 = v39;
      v24 = (*((_DWORD *)v39 + 7))-- == 1;
      if( v24 )
        goto LABEL_38;
      goto LABEL_66;
    }
LABEL_38:
    _InterlockedAnd(v18 + 6, 0xFFFFFF7F);
    v18 = v43;
    if( v43 == v40 )
      break;
  }
  v25 = KiRemoveBoostThread(Prcb, *((_KTHREAD **)Prcb + 1));
  if( v11 )
  {
    v13 = AdjustBoost;
    if( v25 > (char)v11 )
      v11 = v25;
  }
  if( (v15 & 2) != 0 && v13 == AdjustUnwait )
    v11 = 1;
  KiExitDispatcher(Prcb, 0i64, v13, v11, CurrentIrql);
LABEL_25:
  __incgsdword(0x866Cu);
  return result;
}

Referenced by:

CcUnpinFileDataEx
ExReleaseResourceAndLeaveCriticalRegion
ExReleaseResourceForThreadLite
ExReleaseResourceLite