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