KeWakeWaitChain

VOID __fastcall KeWakeWaitChain(const WCHAR *MultiSz, const WCHAR *String, UINT8 IgnoreCase){
  _QWORD *v3; 
  unsigned int v4; 
  struct _KPRCB *CurrentPrcb; 
  _QWORD *v6; 
  _QWORD *v7; 
  _KWAIT_BLOCK *v8; 
  _KWAIT_BLOCK *v9; 
  _LIST_ENTRY *Flink; 
  _KWAIT_BLOCK *v11; 
  _LIST_ENTRY *Blink; 
  unsigned __int8 WaitType; 
  bool v14; 
  CHAR v15; 
  _ADJUST_REASON v16; 
  _KQUEUE *NotificationQueue; 
  _LIST_ENTRY *p_WaitListHead; 
  struct _KPRCB *v19; 
  __int64 v20; 
  int SignalState; 
  _LIST_ENTRY *v22; 
  _KWAIT_BLOCK *v23; 
  volatile signed __int32 *v24; 
  _QWORD *v25; 
  _QWORD *v26; 
  UINT8 OldIrql; 
  int v30; 
  v3 = *(_QWORD **)MultiSz;
  v30 = 0;
  v4 = (unsigned int)String;
  v26 = *(_QWORD **)MultiSz;
  if( *(_QWORD *)MultiSz )
  {
    OldIrql = KeGetCurrentIrql();
    __writecr8(2ui64);
    CurrentPrcb = KeGetCurrentPrcb();
    v6 = v3;
    do
    {
      v7 = v6;
      v25 = (_QWORD *)*v6;
      v24 = (volatile signed __int32 *)(v6 + 3);
      KiAcquireKobjectLockSafe(v6 + 3);
      v8 = (_KWAIT_BLOCK *)(v7 + 4);
      *((_DWORD *)v7 + 7) = 1;
      v9 = (_KWAIT_BLOCK *)v7[4];
      while( v9 != v8 )
      {
        Flink = v9->WaitListEntry.Flink;
        v11 = v9;
        v9 = (_KWAIT_BLOCK *)Flink;
        v23 = (_KWAIT_BLOCK *)Flink;
        Blink = v11->WaitListEntry.Blink;
        if( (_KWAIT_BLOCK *)Flink->Blink != v11 || (_KWAIT_BLOCK *)Blink->Flink != v11 )
LABEL_6:
          __fastfail(3u);
        Blink->Flink = Flink;
        Flink->Blink = Blink;
        WaitType = v11->WaitType;
        if( WaitType == 1 )
        {
          if( KiTryUnwaitThread(CurrentPrcb, v11, v11->WaitKey, 0i64) )
          {
            v14 = (*((_DWORD *)v7 + 7))-- == 1;
            if( v14 )
              break;
          }
        }
        else if( WaitType == 2 )
        {
          v11->BlockState = 5;
          NotificationQueue = v11->NotificationQueue;
          v11->WaitListEntry.Flink = 0i64;
          p_WaitListHead = &NotificationQueue->Header.WaitListHead;
          KeGetCurrentIrql();
          __writecr8(2ui64);
          v19 = KeGetCurrentPrcb();
          v20 = *((_QWORD *)v19 + 1);
          KiAcquireKobjectLockSafe(NotificationQueue);
          if( p_WaitListHead->Flink == p_WaitListHead
            || NotificationQueue->CurrentCount >= NotificationQueue->MaximumCount
            || *(_KQUEUE **)(v20 + 232) == NotificationQueue && *(_BYTE *)(v20 + 643) == 15
            || !KiWakeQueueWaiter(v19, NotificationQueue, (INT64)v11) )
          {
            SignalState = NotificationQueue->Header.SignalState;
            NotificationQueue->Header.SignalState = SignalState + 1;
            v22 = NotificationQueue->EntryListHead.Blink;
            if( v22->Flink != &NotificationQueue->EntryListHead )
              goto LABEL_6;
            v11->WaitListEntry.Flink = &NotificationQueue->EntryListHead;
            v11->WaitListEntry.Blink = v22;
            v22->Flink = &v11->WaitListEntry;
            NotificationQueue->EntryListHead.Blink = &v11->WaitListEntry;
            if( !SignalState && p_WaitListHead->Flink != p_WaitListHead )
              KiWakeOtherQueueWaiters(v19, NotificationQueue);
          }
          _InterlockedAnd(&NotificationQueue->Header.Lock, 0xFFFFFF7F);
          v14 = (*((_DWORD *)v7 + 7))-- == 1;
          if( v14 )
            break;
          v9 = v23;
        }
        else
        {
          KiTryUnwaitThread(CurrentPrcb, v11, 256i64, 0i64);
        }
        v8 = (_KWAIT_BLOCK *)(v7 + 4);
      }
      _InterlockedAnd(v24, 0xFFFFFF7F);
      v6 = v25;
      ++v30;
    }
    while( v25 != v26 );
    if( (IgnoreCase & 1) != 0 && (v15 = KiRemoveBoostThread(CurrentPrcb, *((_KTHREAD **)CurrentPrcb + 1)), v4) )
    {
      v16 = AdjustBoost;
      if( v15 > (char)v4 )
        v4 = v15;
    }
    else
    {
      v16 = AdjustUnwait;
    }
    if( (IgnoreCase & 2) != 0 && v16 == AdjustUnwait )
      v4 = 1;
    KiExitDispatcher(CurrentPrcb, 0i64, v16, v4, OldIrql);
    *(_QWORD *)MultiSz = 0i64;
  }
}

Referenced by:

ExpConvertExclusiveToSharedLite
ExpConvertFastResourceExclusiveToShared
ExpReleaseDisownedFastResourceExclusive
ExpReleaseDisownedFastResourceShared
ExpReleaseFastResourceExclusive
ExpReleaseFastResourceShared
VrpRelinquishDiffHiveEntryTransitionOwner