IN BOOLEAN Alertable,
IN PLARGE_INTEGER TimeOut OPTIONAL)
{
- PKWAIT_BLOCK WaitBlockArray = NULL;
+ PKWAIT_BLOCK WaitBlockArray;
HANDLE Handles[MAXIMUM_WAIT_OBJECTS], KernelHandle;
PVOID Objects[MAXIMUM_WAIT_OBJECTS];
PVOID WaitObjects[MAXIMUM_WAIT_OBJECTS];
- ULONG i = 0, ReferencedObjects = 0, j;
- KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+ ULONG i, ReferencedObjects, j;
+ KPROCESSOR_MODE PreviousMode;
LARGE_INTEGER SafeTimeOut;
BOOLEAN LockInUse;
PHANDLE_TABLE_ENTRY HandleEntry;
NTSTATUS Status;
PAGED_CODE();
- /* Enter a critical region since we'll play with handles */
- LockInUse = TRUE;
- KeEnterCriticalRegion();
-
/* Check for valid Object Count */
if ((ObjectCount > MAXIMUM_WAIT_OBJECTS) || !(ObjectCount))
{
/* Fail */
- Status = STATUS_INVALID_PARAMETER_1;
- goto Quickie;
+ return STATUS_INVALID_PARAMETER_1;
}
/* Check for valid Wait Type */
if ((WaitType != WaitAll) && (WaitType != WaitAny))
{
/* Fail */
- Status = STATUS_INVALID_PARAMETER_3;
- goto Quickie;
+ return STATUS_INVALID_PARAMETER_3;
}
/* Enter SEH */
+ PreviousMode = ExGetPreviousMode();
_SEH2_TRY
{
- /* Check if the call came from user mode */
+ /* Probe for user mode */
if (PreviousMode != KernelMode)
{
/* Check if we have a timeout */
TimeOut = &SafeTimeOut;
}
- /* Probe all the handles */
+ /* Probe all the handles */
ProbeForRead(HandleArray,
ObjectCount * sizeof(HANDLE),
sizeof(HANDLE));
}
- /*
- * Make a copy so we don't have to guard with SEH later and keep
- * track of what objects we referenced if dereferencing pointers
- * suddenly fails
- */
+ /*
+ * Make a copy so we don't have to guard with SEH later and keep
+ * track of what objects we referenced if dereferencing pointers
+ * suddenly fails
+ */
RtlCopyMemory(Handles,
HandleArray,
ObjectCount * sizeof(HANDLE));
}
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) //ExSystemExceptionFilter()
{
+ /* Cover up for kernel mode */
+ if (PreviousMode == KernelMode)
+ {
+ /* But don't fail silently */
+ DbgPrint("Mon dieu! Covering up for BAD driver passing invalid pointer (0x%p)! Hon hon hon!\n", HandleArray);
+ }
+
/* Return the exception code */
- Status = _SEH2_GetExceptionCode();
- _SEH2_YIELD(goto Quickie);
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
}
_SEH2_END;
if (!WaitBlockArray)
{
/* Fail */
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto Quickie;
+ return STATUS_INSUFFICIENT_RESOURCES;
}
}
+ else
+ {
+ /* No need for the array */
+ WaitBlockArray = NULL;
+ }
+
+ /* Enter a critical region since we'll play with handles */
+ LockInUse = TRUE;
+ KeEnterCriticalRegion();
/* Start the loop */
+ i = 0;
+ ReferencedObjects = 0;
do
{
/* Use the right Executive Handle */
{
/* Fail, handle is invalid */
Status = STATUS_INVALID_HANDLE;
- DPRINT1("Invalid handle passed to NtWaitForMultipleObjects\n");
+ DPRINT1("Invalid handle %p passed to NtWaitForMultipleObjects\n", Handles[i]);
goto Quickie;
}
} while (i < ObjectCount);
}
- /* Now we can finally wait. Use SEH since it can raise an exception */
+ /* Now we can finally wait. Always use SEH since it can raise an exception */
_SEH2_TRY
{
/* We're done playing with handles */
TimeOut,
WaitBlockArray);
}
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ _SEH2_EXCEPT((_SEH2_GetExceptionCode() == STATUS_MUTANT_LIMIT_EXCEEDED) ?
+ EXCEPTION_EXECUTE_HANDLER :
+ EXCEPTION_CONTINUE_SEARCH)
{
/* Get the exception code */
Status = _SEH2_GetExceptionCode();
IN PLARGE_INTEGER TimeOut OPTIONAL)
{
PVOID Object, WaitableObject;
- KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+ KPROCESSOR_MODE PreviousMode;
LARGE_INTEGER SafeTimeOut;
NTSTATUS Status;
/* Check if we came with a timeout from user mode */
+ PreviousMode = ExGetPreviousMode();
if ((TimeOut) && (PreviousMode != KernelMode))
{
/* Enter SEH for proving */
Alertable,
TimeOut);
}
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ _SEH2_EXCEPT((_SEH2_GetExceptionCode() == STATUS_MUTANT_LIMIT_EXCEEDED) ?
+ EXCEPTION_EXECUTE_HANDLER :
+ EXCEPTION_CONTINUE_SEARCH)
{
/* Get the exception code */
Status = _SEH2_GetExceptionCode();
IN BOOLEAN Alertable,
IN PLARGE_INTEGER TimeOut OPTIONAL)
{
- KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+ KPROCESSOR_MODE PreviousMode;
POBJECT_TYPE Type;
PVOID SignalObj, WaitObj, WaitableObject;
LARGE_INTEGER SafeTimeOut;
NTSTATUS Status;
/* Check if we came with a timeout from user mode */
+ PreviousMode = ExGetPreviousMode();
if ((TimeOut) && (PreviousMode != KernelMode))
{
/* Enter SEH for probing */
/* Release the mutant */
KeReleaseMutant(SignalObj, MUTANT_INCREMENT, FALSE, TRUE);
}
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ _SEH2_EXCEPT(((_SEH2_GetExceptionCode() == STATUS_ABANDONED) ||
+ (_SEH2_GetExceptionCode() == STATUS_MUTANT_NOT_OWNED)) ?
+ EXCEPTION_EXECUTE_HANDLER :
+ EXCEPTION_CONTINUE_SEARCH)
{
/* Get the exception code */
Status = _SEH2_GetExceptionCode();
/* Release the semaphore */
KeReleaseSemaphore(SignalObj, SEMAPHORE_INCREMENT, 1, TRUE);
}
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ _SEH2_EXCEPT((_SEH2_GetExceptionCode() == STATUS_SEMAPHORE_LIMIT_EXCEEDED) ?
+ EXCEPTION_EXECUTE_HANDLER :
+ EXCEPTION_CONTINUE_SEARCH)
{
/* Get the exception code */
Status = _SEH2_GetExceptionCode();
Alertable,
TimeOut);
}
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ _SEH2_EXCEPT((_SEH2_GetExceptionCode() == STATUS_MUTANT_LIMIT_EXCEEDED) ?
+ EXCEPTION_EXECUTE_HANDLER :
+ EXCEPTION_CONTINUE_SEARCH)
{
/* Get the exception code */
Status = _SEH2_GetExceptionCode();