NTSTATUS
KeWaitForMultipleObjects (
IN ULONG Count,
IN PVOID Object[],
IN WAIT_TYPE WaitType,
IN KWAIT_REASON WaitReason,
IN KPROCESSOR_MODE WaitMode,
IN BOOLEAN Alertable,
IN PLARGE_INTEGER Timeout OPTIONAL,
IN PKWAIT_BLOCK WaitBlockArray OPTIONAL
)
{
。。。。。。
Index = 0;
if (WaitType == WaitAny) {
do {
//
// Test if wait can be satisfied immediately.
//
Objectx = (PKMUTANT)Object[Index];
ASSERT(Objectx->Header.Type != QueueObject);
//
// If the object is a mutant object and the mutant object
// has been recursively acquired MINLONG times, then raise
// an exception. Otherwise if the signal state of the mutant
// object is greater than zero, or the current thread is
// the owner of the mutant object, then satisfy the wait.
//
if (Objectx->Header.Type == MutantObject) {
if ((Objectx->Header.SignalState > 0) ||
(Thread == Objectx->OwnerThread)) {
if (Objectx->Header.SignalState != MINLONG) {
KiWaitSatisfyMutant(Objectx, Thread);
WaitStatus = (NTSTATUS)(Index | Thread->WaitStatus);
goto NoWait;
} else {
KiUnlockDispatcherDatabase(Thread->WaitIrql);
ExRaiseStatus(STATUS_MUTANT_LIMIT_EXCEEDED);
}
}
//
// If the signal state is greater than zero, then satisfy
// the wait.
//
} else if (Objectx->Header.SignalState > 0) {
KiWaitSatisfyOther(Objectx);
WaitStatus = (NTSTATUS)(Index);
goto NoWait;
}
Index += 1;
} while(Index < Count);
NoWait:
KiUnlockDispatcherDatabaseFromSynchLevel();
//
// Adjust the thread quantum, exit the scheduler, and return the wait
// completion status.
//
KiAdjustQuantumThread(Thread);
return WaitStatus;
}