KiSatisfyThreadWait

NTSTATUS __stdcall KiSatisfyThreadWait(
        _KPRCB *Prcb,
        _ETHREAD *Thread,
        UINT8 ExitScheduler,
        _KWAIT_BLOCK *WaitBlockList,
        UINT64 a5){
  volatile __int64 WaitStatus; 
  VOID *AbWaitObject; 
  _BYTE *v11; 
  _KWAIT_BLOCK *v12; 
  void *Object; 
  _LIST_ENTRY *Flink; 
  _LIST_ENTRY *Blink; 

  Thread->Tcb.WaitBlockFill6[68] = 2;
  KiReleaseThreadLockSafe((INT64)Thread);
  WaitStatus = Thread->Tcb.WaitStatus;
  AbWaitObject = Thread->Tcb.AbWaitObject;
  if( AbWaitObject )
  {
    Thread->Tcb.AbWaitObject = 0i64;
    v11 = KeAbPreAcquire(AbWaitObject, 0i64, 1ui64);
    if( v11 )
      v11[26] |= 1u;
  }
  if( (_DWORD)a5 )
  {
    v12 = &WaitBlockList[(unsigned __int8)a5];
    do
    {
      if( WaitBlockList->BlockState < 5u )
      {
        Object = WaitBlockList->Object;
        KiAcquireKobjectLockSafe(Object);
        if( WaitBlockList->BlockState == 4 )
        {
          Flink = WaitBlockList->WaitListEntry.Flink;
          if( (_KWAIT_BLOCK *)WaitBlockList->WaitListEntry.Flink->Blink != WaitBlockList
            || (Blink = WaitBlockList->WaitListEntry.Blink, (_KWAIT_BLOCK *)Blink->Flink != WaitBlockList) )
          {
            __fastfail(3u);
          }
          Blink->Flink = Flink;
          Flink->Blink = Blink;
        }
        _InterlockedAnd((volatile signed __int32 *)Object, 0xFFFFFF7F);
      }
      ++WaitBlockList;
    }
    while( WaitBlockList != v12 );
  }
  KiExitThreadWait(Prcb, &Thread->Tcb, ExitScheduler);
  return WaitStatus;
}

Referenced by:

KeWaitForMultipleObjects