Author: sginsberg
Date: Mon Sep 28 09:01:11 2015
New Revision: 69393
URL:
http://svn.reactos.org/svn/reactos?rev=69393&view=rev
Log:
[NTOS] Fix the Ob wait system calls to only catch the exceptions that are expected to be
raised by the Ke wait functions (and not potentially silently catching *any* exception and
corrupting everything in the process). Also fixup some code logic. SEH Mega Fixup 1/???
Modified:
trunk/reactos/ntoskrnl/ob/obwait.c
Modified: trunk/reactos/ntoskrnl/ob/obwait.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/obwait.c?rev=6…
==============================================================================
--- trunk/reactos/ntoskrnl/ob/obwait.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ob/obwait.c [iso-8859-1] Mon Sep 28 09:01:11 2015
@@ -49,12 +49,12 @@
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;
@@ -65,31 +65,26 @@
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;
- }
-
- /* Enter SEH */
- _SEH2_TRY
- {
- /* Check if the call came from user mode */
- if (PreviousMode != KernelMode)
+ return STATUS_INVALID_PARAMETER_3;
+ }
+
+ /* Enter SEH for user mode */
+ PreviousMode = ExGetPreviousMode();
+ if (PreviousMode != KernelMode)
+ {
+ /* Enter SEH */
+ _SEH2_TRY
{
/* Check if we have a timeout */
if (TimeOut)
@@ -103,24 +98,30 @@
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)
+ {
+ /* Return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+ }
+ else
+ {
+ /* This is kernel mode, no need to wrap in SEH */
RtlCopyMemory(Handles,
HandleArray,
ObjectCount * sizeof(HANDLE));
}
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- /* Return the exception code */
- Status = _SEH2_GetExceptionCode();
- _SEH2_YIELD(goto Quickie);
- }
- _SEH2_END;
/* Check if we can use the internal Wait Array */
if (ObjectCount > THREAD_WAIT_OBJECTS)
@@ -133,12 +134,22 @@
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 */
@@ -240,7 +251,7 @@
} 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 */
@@ -257,7 +268,9 @@
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();
@@ -358,11 +371,12 @@
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 */
@@ -410,7 +424,9 @@
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();
@@ -459,7 +475,7 @@
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;
@@ -467,6 +483,7 @@
NTSTATUS Status;
/* Check if we came with a timeout from user mode */
+ PreviousMode = ExGetPreviousMode();
if ((TimeOut) && (PreviousMode != KernelMode))
{
/* Enter SEH for probing */
@@ -542,7 +559,10 @@
/* 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();
@@ -566,7 +586,9 @@
/* 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();
@@ -592,7 +614,9 @@
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();