From f022f9092b4cc64d6beed6de7303f943f5e27f68 Mon Sep 17 00:00:00 2001 From: Stefan Ginsberg Date: Mon, 24 Aug 2009 19:58:15 +0000 Subject: [PATCH] - Use _SEH2_YIELD when returning from an exception instead of returning outside the SEH block. Avoids unnecessary status checks for the most common case (no exception). Move the cleanup code into the handler too in favor of the no-exception case. Futhermore, don't call ExSystemExceptionFilter when we know we are called from user mode. Finally, only enter SEH if we need to do any probing. - Re-enable user mode probes in KiRaiseException; they do not seem to be an issue anymore -- booting and running the ntdll exception Winetest didn't reveal any issue. Put a breakpoint there in case this code is ever hit (unlikely). svn path=/trunk/; revision=42923 --- reactos/lib/rtl/debug.c | 9 ++--- reactos/ntoskrnl/config/ntapi.c | 57 +++++++++-------------------- reactos/ntoskrnl/dbgk/dbgkobj.c | 29 +++++++-------- reactos/ntoskrnl/ke/except.c | 26 ++++++------- reactos/ntoskrnl/ke/i386/exp.c | 6 +-- reactos/ntoskrnl/ke/i386/usercall.c | 5 +-- reactos/ntoskrnl/ke/wait.c | 9 ++--- reactos/ntoskrnl/lpc/reply.c | 10 ++--- reactos/ntoskrnl/lpc/send.c | 11 ++---- reactos/ntoskrnl/po/power.c | 2 +- reactos/ntoskrnl/vdm/vdmmain.c | 14 +++---- 11 files changed, 68 insertions(+), 110 deletions(-) diff --git a/reactos/lib/rtl/debug.c b/reactos/lib/rtl/debug.c index c491a46906b..f34adefc46b 100644 --- a/reactos/lib/rtl/debug.c +++ b/reactos/lib/rtl/debug.c @@ -54,7 +54,7 @@ vDbgPrintExWithPrefixInternal(IN LPCSTR Prefix, IN va_list ap, IN BOOLEAN HandleBreakpoint) { - NTSTATUS Status = STATUS_SUCCESS; + NTSTATUS Status; ANSI_STRING DebugString; CHAR Buffer[512]; ULONG Length, PrefixLength; @@ -65,11 +65,11 @@ vDbgPrintExWithPrefixInternal(IN LPCSTR Prefix, !(NtQueryDebugFilterState(ComponentId, Level))) { /* This message is masked */ - return Status; + return STATUS_SUCCESS; } /* For user mode, don't recursively DbgPrint */ - if (RtlpSetInDbgPrint(TRUE)) return Status; + if (RtlpSetInDbgPrint(TRUE)) return STATUS_SUCCESS; /* Guard against incorrect pointers */ _SEH2_TRY @@ -91,10 +91,9 @@ vDbgPrintExWithPrefixInternal(IN LPCSTR Prefix, { /* Fail */ Length = PrefixLength = 0; - Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; - if (!NT_SUCCESS(Status)) return Status; /* Check if we went past the buffer */ if (Length == -1U) diff --git a/reactos/ntoskrnl/config/ntapi.c b/reactos/ntoskrnl/config/ntapi.c index 20176b30125..0d622696cef 100644 --- a/reactos/ntoskrnl/config/ntapi.c +++ b/reactos/ntoskrnl/config/ntapi.c @@ -27,7 +27,7 @@ NtCreateKey(OUT PHANDLE KeyHandle, IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL) { - NTSTATUS Status = STATUS_SUCCESS; + NTSTATUS Status; KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); CM_PARSE_CONTEXT ParseContext = {0}; HANDLE Handle; @@ -63,11 +63,10 @@ NtCreateKey(OUT PHANDLE KeyHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Get the error code */ - Status = _SEH2_GetExceptionCode(); + /* Return the exception code */ + _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; - if(!NT_SUCCESS(Status)) return Status; } else { @@ -113,7 +112,7 @@ NtOpenKey(OUT PHANDLE KeyHandle, { CM_PARSE_CONTEXT ParseContext = {0}; HANDLE Handle; - NTSTATUS Status = STATUS_SUCCESS; + NTSTATUS Status; KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); PAGED_CODE(); DPRINT("NtOpenKey(OB 0x%wZ)\n", ObjectAttributes->ObjectName); @@ -135,11 +134,10 @@ NtOpenKey(OUT PHANDLE KeyHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Get the status */ - Status = _SEH2_GetExceptionCode(); + /* Return the exception code */ + _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; - if(!NT_SUCCESS(Status)) return Status; } /* Just let the object manager handle this */ @@ -267,17 +265,12 @@ NtEnumerateKey(IN HANDLE KeyHandle, sizeof(ULONG)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; - - if (!NT_SUCCESS(Status)) { /* Dereference and return status */ ObDereferenceObject(KeyObject); - return Status; + _SEH2_YIELD(return _SEH2_GetExceptionCode()); } + _SEH2_END; } /* Setup the callback */ @@ -356,17 +349,12 @@ NtEnumerateValueKey(IN HANDLE KeyHandle, sizeof(ULONG)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; - - if (!NT_SUCCESS(Status)) { /* Dereference and return status */ ObDereferenceObject(KeyObject); - return Status; + _SEH2_YIELD(return _SEH2_GetExceptionCode()); } + _SEH2_END; } /* Setup the callback */ @@ -475,17 +463,12 @@ NtQueryKey(IN HANDLE KeyHandle, sizeof(ULONG)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; - - if (!NT_SUCCESS(Status)) { /* Dereference and return status */ ObDereferenceObject(KeyObject); - return Status; + _SEH2_YIELD(return _SEH2_GetExceptionCode()); } + _SEH2_END; } /* Setup the callback */ @@ -555,17 +538,12 @@ NtQueryValueKey(IN HANDLE KeyHandle, sizeof(ULONG)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; - - if (!NT_SUCCESS(Status)) { /* Dereference and return status */ ObDereferenceObject(KeyObject); - return Status; + _SEH2_YIELD(return _SEH2_GetExceptionCode()); } + _SEH2_END; } /* Make sure the name is aligned properly */ @@ -1131,7 +1109,7 @@ NtUnloadKey2(IN POBJECT_ATTRIBUTES TargetKey, IN ULONG Flags) { #if 0 - NTSTATUS Status = STATUS_SUCCESS; + NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING ObjectName; CM_PARSE_CONTEXT ParseContext = {0}; @@ -1175,11 +1153,10 @@ NtUnloadKey2(IN POBJECT_ATTRIBUTES TargetKey, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Get the error code */ - Status = _SEH2_GetExceptionCode(); + /* Return the exception code */ + _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; - if(!NT_SUCCESS(Status)) return Status; } else { diff --git a/reactos/ntoskrnl/dbgk/dbgkobj.c b/reactos/ntoskrnl/dbgk/dbgkobj.c index c59ad79ba82..6b509a05fcd 100644 --- a/reactos/ntoskrnl/dbgk/dbgkobj.c +++ b/reactos/ntoskrnl/dbgk/dbgkobj.c @@ -1517,7 +1517,7 @@ NtCreateDebugObject(OUT PHANDLE DebugHandle, KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); PDEBUG_OBJECT DebugObject; HANDLE hDebug; - NTSTATUS Status = STATUS_SUCCESS; + NTSTATUS Status; PAGED_CODE(); /* Check if we were called from user mode*/ @@ -1531,10 +1531,9 @@ NtCreateDebugObject(OUT PHANDLE DebugHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Get exception error */ - Status = _SEH2_GetExceptionCode(); + /* Return the exception code */ + _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; - if (!NT_SUCCESS(Status)) return Status; } /* Check for invalid flags */ @@ -1610,7 +1609,7 @@ NtDebugContinue(IN HANDLE DebugHandle, { KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); PDEBUG_OBJECT DebugObject; - NTSTATUS Status = STATUS_SUCCESS; + NTSTATUS Status; PDEBUG_EVENT DebugEvent = NULL, DebugEventToWake = NULL; PLIST_ENTRY ListHead, NextEntry; BOOLEAN NeedsWake = FALSE; @@ -1632,10 +1631,9 @@ NtDebugContinue(IN HANDLE DebugHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Get exception error */ - Status = _SEH2_GetExceptionCode(); + /* Return the exception code */ + _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; - if (!NT_SUCCESS(Status)) return Status; } /* Make sure that the status is valid */ @@ -1869,7 +1867,7 @@ NtSetInformationDebugObject(IN HANDLE DebugHandle, { PDEBUG_OBJECT DebugObject; KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); - NTSTATUS Status = STATUS_SUCCESS; + NTSTATUS Status; PDEBUG_OBJECT_KILL_PROCESS_ON_EXIT_INFORMATION DebugInfo = DebugInformation; PAGED_CODE(); @@ -1881,6 +1879,7 @@ NtSetInformationDebugObject(IN HANDLE DebugHandle, DebugInformation, DebugInformationLength, PreviousMode); + if (!NT_SUCCESS(Status)) return Status; /* Check if the caller wanted the return length */ if (ReturnLength) @@ -1894,12 +1893,11 @@ NtSetInformationDebugObject(IN HANDLE DebugHandle, } _SEH2_EXCEPT(ExSystemExceptionFilter()) { - /* Get SEH Exception code */ - Status = _SEH2_GetExceptionCode(); + /* Return the exception code */ + _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; } - if (!NT_SUCCESS(Status)) return Status; /* Open the Object */ Status = ObReferenceObjectByHandle(DebugHandle, @@ -1955,7 +1953,7 @@ NtWaitForDebugEvent(IN HANDLE DebugHandle, LARGE_INTEGER NewTime; PDEBUG_OBJECT DebugObject; DBGUI_WAIT_STATE_CHANGE WaitStateChange; - NTSTATUS Status = STATUS_SUCCESS; + NTSTATUS Status; PDEBUG_EVENT DebugEvent = NULL, DebugEvent2; PLIST_ENTRY ListHead, NextEntry, NextEntry2; PAGED_CODE(); @@ -1987,11 +1985,10 @@ NtWaitForDebugEvent(IN HANDLE DebugHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Get the exception code */ - Status = _SEH2_GetExceptionCode(); + /* Return the exception code */ + _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; - if (!NT_SUCCESS(Status)) return Status; } else { diff --git a/reactos/ntoskrnl/ke/except.c b/reactos/ntoskrnl/ke/except.c index 8cb8d96b03c..fd4ba952eda 100644 --- a/reactos/ntoskrnl/ke/except.c +++ b/reactos/ntoskrnl/ke/except.c @@ -97,13 +97,12 @@ KiRaiseException(IN PEXCEPTION_RECORD ExceptionRecord, ULONG ParameterCount, Size; NTSTATUS Status = STATUS_SUCCESS; - /* Set up SEH */ - _SEH2_TRY + /* Check if we need to probe */ + if (PreviousMode != KernelMode) { - /* Check the previous mode */ - if (PreviousMode != KernelMode) + /* Set up SEH */ + _SEH2_TRY { -#if 0 /* Probe the context */ ProbeForRead(Context, sizeof(CONTEXT), sizeof(ULONG)); @@ -112,7 +111,7 @@ KiRaiseException(IN PEXCEPTION_RECORD ExceptionRecord, FIELD_OFFSET(EXCEPTION_RECORD, NumberParameters) + sizeof(ULONG), sizeof(ULONG)); -#endif + /* Validate the maximum parameters */ if ((ParameterCount = ExceptionRecord->NumberParameters) > EXCEPTION_MAXIMUM_PARAMETERS) @@ -136,14 +135,15 @@ KiRaiseException(IN PEXCEPTION_RECORD ExceptionRecord, /* Update the parameter count */ ExceptionRecord->NumberParameters = ParameterCount; } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + DbgBreakPoint(); + + /* Return the exception code */ + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - /* Get the exception code */ - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; - if (!NT_SUCCESS(Status)) return Status; /* Convert the context record */ KeContextToTrapFrame(Context, diff --git a/reactos/ntoskrnl/ke/i386/exp.c b/reactos/ntoskrnl/ke/i386/exp.c index 4424a3d6416..6ee3c74c088 100644 --- a/reactos/ntoskrnl/ke/i386/exp.c +++ b/reactos/ntoskrnl/ke/i386/exp.c @@ -1072,7 +1072,6 @@ NTSTATUS NTAPI KeRaiseUserException(IN NTSTATUS ExceptionCode) { - NTSTATUS Status = STATUS_SUCCESS; ULONG OldEip; PTEB Teb = KeGetCurrentThread()->Teb; PKTRAP_FRAME TrapFrame = KeGetCurrentThread()->TrapFrame; @@ -1085,11 +1084,10 @@ KeRaiseUserException(IN NTSTATUS ExceptionCode) } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Save exception code */ - Status = ExceptionCode; + /* Return the exception code */ + _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; - if (!NT_SUCCESS(Status)) return Status; /* Get the old EIP */ OldEip = TrapFrame->Eip; diff --git a/reactos/ntoskrnl/ke/i386/usercall.c b/reactos/ntoskrnl/ke/i386/usercall.c index 11acfaf3766..a07a0550e01 100644 --- a/reactos/ntoskrnl/ke/i386/usercall.c +++ b/reactos/ntoskrnl/ke/i386/usercall.c @@ -135,7 +135,7 @@ KeUserModeCallback(IN ULONG RoutineIndex, { ULONG_PTR NewStack, OldStack; PULONG UserEsp; - NTSTATUS CallbackStatus = STATUS_SUCCESS; + NTSTATUS CallbackStatus; PEXCEPTION_REGISTRATION_RECORD ExceptionList; PTEB Teb; ULONG GdiBatchCount = 0; @@ -192,10 +192,9 @@ KeUserModeCallback(IN ULONG RoutineIndex, _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { /* Get the SEH exception */ - CallbackStatus = _SEH2_GetExceptionCode(); + _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; - if (!NT_SUCCESS(CallbackStatus)) return CallbackStatus; /* Check if we have GDI Batch operations */ if (GdiBatchCount) diff --git a/reactos/ntoskrnl/ke/wait.c b/reactos/ntoskrnl/ke/wait.c index 83d9c691fbb..2e9c1c884a9 100644 --- a/reactos/ntoskrnl/ke/wait.c +++ b/reactos/ntoskrnl/ke/wait.c @@ -849,10 +849,10 @@ NtDelayExecution(IN BOOLEAN Alertable, { KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); LARGE_INTEGER SafeInterval; - NTSTATUS Status = STATUS_SUCCESS; + NTSTATUS Status; /* Check the previous mode */ - if(PreviousMode != KernelMode) + if (PreviousMode != KernelMode) { /* Enter SEH for probing */ _SEH2_TRY @@ -863,11 +863,10 @@ NtDelayExecution(IN BOOLEAN Alertable, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Get SEH exception */ - Status = _SEH2_GetExceptionCode(); + /* Return the exception code */ + _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; - if (!NT_SUCCESS(Status)) return Status; } /* Call the Kernel Function */ diff --git a/reactos/ntoskrnl/lpc/reply.c b/reactos/ntoskrnl/lpc/reply.c index af8f57378ef..0233ea10cc3 100644 --- a/reactos/ntoskrnl/lpc/reply.c +++ b/reactos/ntoskrnl/lpc/reply.c @@ -160,7 +160,7 @@ NtReplyWaitReceivePortEx(IN HANDLE PortHandle, { PLPCP_PORT_OBJECT Port, ReceivePort, ConnectionPort = NULL; KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(), WaitMode = PreviousMode; - NTSTATUS Status = STATUS_SUCCESS; + NTSTATUS Status; PLPCP_MESSAGE Message; PETHREAD Thread = PsGetCurrentThread(), WakeupThread; PLPCP_CONNECTION_MESSAGE ConnectMessage; @@ -200,14 +200,10 @@ NtReplyWaitReceivePortEx(IN HANDLE PortHandle, _SEH2_EXCEPT(ExSystemExceptionFilter()) { DPRINT1("SEH crash [1]\n"); - DbgBreakPoint(); - Status = _SEH2_GetExceptionCode(); + DbgBreakPoint(); + _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; - - /* Bail out if pointer was invalid */ - if (!NT_SUCCESS(Status)) - return Status; } else { diff --git a/reactos/ntoskrnl/lpc/send.c b/reactos/ntoskrnl/lpc/send.c index 6b4ee12c698..dad5a35c865 100644 --- a/reactos/ntoskrnl/lpc/send.c +++ b/reactos/ntoskrnl/lpc/send.c @@ -544,6 +544,7 @@ NtRequestWaitReplyPort(IN HANDLE PortHandle, /* No callback, just copy the message */ _SEH2_TRY { + /* Copy it */ LpcpMoveMessage(&Message->Request, LpcRequest, LpcRequest + 1, @@ -552,16 +553,12 @@ NtRequestWaitReplyPort(IN HANDLE PortHandle, } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; - - if (!NT_SUCCESS(Status)) - { + /* Fail */ LpcpFreeToPortZone(Message, 0); ObDereferenceObject(Port); - return Status; + _SEH2_YIELD(return _SEH2_GetExceptionCode()); } + _SEH2_END; /* Acquire the LPC lock */ KeAcquireGuardedMutex(&LpcpLock); diff --git a/reactos/ntoskrnl/po/power.c b/reactos/ntoskrnl/po/power.c index dbf72a94382..0d5d10d23b9 100644 --- a/reactos/ntoskrnl/po/power.c +++ b/reactos/ntoskrnl/po/power.c @@ -609,7 +609,7 @@ NtSetThreadExecutionState(IN EXECUTION_STATE esFlags, /* Check if the pointer is valid */ ProbeForWriteUlong(PreviousFlags); } - _SEH2_EXCEPT(ExSystemExceptionFilter()) + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { /* It isn't -- fail */ _SEH2_YIELD(return _SEH2_GetExceptionCode()); diff --git a/reactos/ntoskrnl/vdm/vdmmain.c b/reactos/ntoskrnl/vdm/vdmmain.c index 228753e4229..3dcf145a45b 100644 --- a/reactos/ntoskrnl/vdm/vdmmain.c +++ b/reactos/ntoskrnl/vdm/vdmmain.c @@ -120,25 +120,21 @@ VdmpInitialize(PVOID ControlData) return Status; } - /* Now, copy the first physical page into the first virtual page */ + /* Enter SEH */ _SEH2_TRY { + /* Copy the first physical page into the first virtual page */ RtlMoveMemory(NullAddress, BaseAddress, ViewSize); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* Get the status */ - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; - - if (!NT_SUCCESS(Status)) - { + /* Fail */ DPRINT1("Couldn't copy first page (%x)\n", Status); ZwClose(PhysMemHandle); ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress); - return Status; + _SEH2_YIELD(return _SEH2_GetExceptionCode()); } + _SEH2_END; /* Close physical memory section handle */ ZwClose(PhysMemHandle); -- 2.17.1