KiWaitForAllObjects

VOID __fastcall KiWaitForAllObjects(
        UINT64 Count,
        VOID **Object,
        _KWAIT_REASON WaitReason,
        CHAR WaitMode,
        UINT8 Alertable,
        _LARGE_INTEGER *Timeout,
        _KWAIT_BLOCK *WaitBlockArray){
  _KWAIT_REASON v7; 
  unsigned int v9; 
  unsigned __int64 v10; 
  CHAR v11; 
  void *v12; 
  unsigned int v13; 
  VOID **v14; 
  PVOID *p_Objecta; 
  unsigned __int64 v16; 
  unsigned int v17; 
  _ETHREAD *CurrentThread; 
  char v19; 
  int v20; 
  struct _KPRCB *CurrentPrcb; 
  PVOID v22; 
  __int64 v23; 
  PVOID *v24; 
  char v25; 
  __int64 v26; 
  volatile unsigned __int8 *p_BlockState; 
  VOID **v28; 
  _BYTE *v29; 
  int v30; 
  _QWORD *v31; 
  __int64 *v32; 
  unsigned int v33; 
  __int64 *v34; 
  __int64 v35; 
  __int64 **v36; 
  unsigned __int64 v37; 
  unsigned int v38; 
  unsigned int v39; 
  __int64 v40; 
  unsigned __int8 CurrentIrql; 
  __int64 v42; 
  __int64 v43; 
  char v44; 
  _ETHREAD *v45; 
  unsigned int v46; 
  unsigned __int64 v47; 
  char v48; 
  _QWORD *v49; 
  _QWORD *v50; 
  __int64 v51; 
  __int64 v52; 
  unsigned __int64 v53; 
  unsigned __int8 v54; 
  _BYTE *v55; 
  char v56; 
  bool v57; 
  int v59; 
  __int64 v60; 
  unsigned int v61; 
  int v62; 
  int v63; 
  _KWAIT_REASON v64; 
  unsigned __int64 v65; 
  _KWAIT_BLOCK *v66; 
  PVOID Objecta; 
  INT64 result[64]; 
  v7 = WaitReason;
  v64 = WaitReason;
  v9 = Count;
  v61 = Count;
  v10 = 0i64;
  v66 = WaitBlockArray;
  v65 = 0i64;
  v11 = WaitMode;
  memset((INT64)result, 0i64);
  v12 = *Object;
  v13 = 1;
  v59 = 0;
  Objecta = v12;
  if( v9 > 1 )
  {
    v14 = Object + 1;
    p_Objecta = &Objecta;
    do
    {
      v16 = (unsigned __int64)*v14;
      v17 = v13;
      if( *p_Objecta > *v14 )
      {
        do
        {
          v42 = v17--;
          result[v42 - 1] = result[v17 - 1];
        }
        while( v17 && (unsigned __int64)*(&Objecta + v17 - 1) > v16 );
      }
      ++v13;
      ++p_Objecta;
      ++v14;
      result[v17 - 1] = v16;
    }
    while( v13 < v9 );
  }
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v19 = KiCheckWaitNext((__int64)CurrentThread, (__int64)Timeout, 0, &v65, &v59);
  v56 = v19;
LABEL_6:
  KiBeginThreadWait(CurrentThread, v11, v7, Alertable);
  if( !v20 )
  {
    CurrentPrcb = KeGetCurrentPrcb();
    v22 = Objecta;
    KiAcquireKobjectLockSafe(Objecta);
    if( v9 > 1 )
    {
      v23 = v9 - 1;
      v60 = v23;
      v24 = (PVOID *)result;
      do
      {
        if( *v24 != v22 )
        {
          v22 = *v24;
          KiAcquireKobjectLockSafe(*v24);
          v23 = v60;
        }
        ++v24;
        v60 = --v23;
      }
      while( v23 );
      v19 = v56;
    }
    if( v9 )
    {
      v25 = 0;
      v26 = v9;
      p_BlockState = &v66->BlockState;
      v28 = Object;
      do
      {
        v29 = *v28;
        *((_BYTE *)p_BlockState - 1) = 0;
        *p_BlockState = 4;
        *(_WORD *)(p_BlockState + 1) = 0;
        if( CurrentThread )
          *(_QWORD *)(p_BlockState + 7) = CurrentThread;
        *(_QWORD *)(p_BlockState + 15) = v29;
        p_BlockState += 48;
        if( (*(_BYTE *)*v28 & 0x7F) == 2 && (*((_BYTE *)*v28 + 48) & 2) != 0 )
          v10 |= 1i64 << v25;
        ++v25;
        ++v28;
        --v26;
      }
      while( v26 );
    }
    *((_QWORD *)CurrentThread + 25) = 0i64;
    v30 = 0;
    *((_QWORD *)CurrentThread + 122) = 0i64;
    while( 1 )
    {
      v31 = Object[v30];
      if( (*(_BYTE *)v31 & 0x7F) == 2 )
      {
        v44 = *((_BYTE *)CurrentPrcb + 12586);
        v45 = (_ETHREAD *)v31[5];
        if( CurrentThread == v45 && *((_BYTE *)v31 + 2) == v44 && *((_DWORD *)v31 + 1) == 0x80000000 )
        {
          KiUnlockKobjectArray(&Objecta, v9);
          KiFastExitThreadWait((__int64)CurrentPrcb, (__int64)CurrentThread, v19);
          RtlRaiseStatus(-1073741423);
        }
        if( *((int *)v31 + 1) <= 0 && (CurrentThread != v45 || *((_BYTE *)v31 + 2) != v44) )
        {
LABEL_23:
          if( v30 == v9 )
          {
            if( v9 )
            {
              v43 = v9;
              do
              {
                KiWaitSatisfyAny((__int64)*Object++, (__int64)CurrentThread, (__int64)CurrentPrcb);
                --v43;
              }
              while( v43 );
            }
            KiUnlockKobjectArray(&Objecta, v9);
            *((_QWORD *)CurrentThread + 122) = 0i64;
            KiFastExitThreadWait((__int64)CurrentPrcb, (__int64)CurrentThread, v19);
          }
          else if( KiCheckDueTimeExpired((__int64)CurrentThread, v59, v65) )
          {
            KiUnlockKobjectArray(&Objecta, v9);
            KiFastExitThreadWait((__int64)CurrentPrcb, (__int64)CurrentThread, v19);
          }
          else
          {
            v33 = 0;
            if( v9 )
            {
              v34 = v32;
              do
              {
                v35 = v34[4] + 8;
                v36 = *(__int64 ***)(v34[4] + 16);
                if( *v36 != (__int64 *)v35 )
                  __fastfail(3u);
                *v34 = v35;
                ++v33;
                v34[1] = (__int64)v36;
                *v36 = v34;
                *(_QWORD *)(v35 + 8) = v34;
                v34 += 6;
              }
              while( v33 < v9 );
            }
            KiUnlockKobjectArray(&Objecta, v9);
            *((_BYTE *)CurrentThread + 587) = v9;
            v37 = 0i64;
            if( v10 )
            {
              v46 = 0;
              do
              {
                _BitScanForward64(&v47, v10);
                v48 = v47;
                v62 = v47;
                _bittestandreset64((__int64 *)&v10, (unsigned int)v47);
                LODWORD(v49) = KeAbPreAcquire(Object[v47], 0i64, 0i64);
                v50 = v49;
                if( !v49 )
                  break;
                v37 |= 1i64 << v48;
                KeAbPreWait(v49);
                v51 = (unsigned __int128)(((__int64)v50 - v50[-2 * *((unsigned __int8 *)v50 + 24) + 100])
                                        * (__int128)0x2AAAAAAAAAAAAAABi64) >> 64;
                v52 = v46++;
                *((_BYTE *)&result[63] + v52) = (2 * ((v51 < 0) + (v51 >> 4))) | 1;
              }
              while( v10 );
              v9 = v61;
            }
            v38 = KiCommitThreadWait((__int64)CurrentThread, (__int64 *)v66, v59, v65, 0i64);
            v39 = v38;
            v57 = v38 <= 0x3F || v38 - 128 <= 0x3F;
            v40 = 0i64;
            *((_QWORD *)CurrentThread + 122) = 0i64;
            if( v37 )
            {
              do
              {
                _BitScanForward64(&v53, v37);
                v54 = *((_BYTE *)&result[63] + v40) >> 1;
                v63 = v53;
                v37 &= ~(1i64 << v53);
                v60 = (unsigned int)v53;
                v55 = (_BYTE *)(*((_QWORD *)KeGetCurrentThread() + 100) + 96i64 * v54);
                KeAbPreAcquire(Object[(unsigned int)v53], v55, 0i64);
                if( v57 )
                  v55[26] |= 1u;
                else
                  KeAbPostReleaseEx(Object[v60], v55);
                v40 = (unsigned int)(v40 + 1);
              }
              while( v37 );
              v9 = v61;
            }
            if( v39 == 256 )
            {
              v10 = 0i64;
              v19 = 0;
              v56 = 0;
              CurrentIrql = KeGetCurrentIrql();
              __writecr8(2ui64);
              v7 = v64;
              v11 = WaitMode;
              *((_BYTE *)CurrentThread + 390) = CurrentIrql;
              goto LABEL_6;
            }
          }
          return;
        }
      }
      else if( *((int *)v31 + 1) <= 0 )
      {
        goto LABEL_23;
      }
      if( ++v30 >= v9 )
        goto LABEL_23;
    }
  }
}

Referenced by:

KeWaitForMultipleObjects