Alex Ionescu ionucu@videotron.ca - Remove ke/error.c and add its functions into ke/catch.c where they belong. - Create ex/error.c and move Executive functions present in ke/error.c to it. - Implement NtRaiseHardError and move it from ke/error.c to ex/error.c. - Increase Exceptions Dispatched count in dispatch code and comment code more throughly. Modified: trunk/reactos/ntoskrnl/Makefile Added: trunk/reactos/ntoskrnl/ex/error.c Modified: trunk/reactos/ntoskrnl/ke/catch.c Deleted: trunk/reactos/ntoskrnl/ke/error.c _____
Modified: trunk/reactos/ntoskrnl/Makefile --- trunk/reactos/ntoskrnl/Makefile 2005-03-12 21:08:29 UTC (rev 13981) +++ trunk/reactos/ntoskrnl/Makefile 2005-03-12 21:26:29 UTC (rev 13982) @@ -100,7 +100,6 @@
ke/critical.o \ ke/dpc.o \ ke/device.o \ - ke/error.o \ ke/event.o \ ke/kqueue.o \ ke/kthread.o \ @@ -237,6 +236,7 @@ OBJECTS_EX = \ ex/btree.o \ ex/callback.o \ + ex/error.o \ ex/event.o \ ex/evtpair.o \ ex/fmutex.o \ _____
Added: trunk/reactos/ntoskrnl/ex/error.c --- trunk/reactos/ntoskrnl/ex/error.c 2005-03-12 21:08:29 UTC (rev 13981) +++ trunk/reactos/ntoskrnl/ex/error.c 2005-03-12 21:26:29 UTC (rev 13982) @@ -0,0 +1,163 @@
+/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/ex/error.c + * PURPOSE: Error Functions and Status/Exception Dispatching/Raising + * + * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - Created File + */ + +/* INCLUDES *****************************************************************/ + +#include <ntoskrnl.h> +#define NDEBUG +#include <internal/debug.h> + +/* GLOBALS ****************************************************************/ + +BOOLEAN ExReadyForErrors = FALSE; +PEPORT ExpDefaultErrorPort = NULL; +PEPROCESS ExpDefaultErrorPortProcess = NULL; + +/* FUNCTIONS ****************************************************************/ + +/* + * @implemented + */ +VOID +STDCALL +ExRaiseAccessViolation(VOID) +{ + /* Raise the Right Status */ + ExRaiseStatus (STATUS_ACCESS_VIOLATION); +} + +/* + * @implemented + */ +VOID +STDCALL +ExRaiseDatatypeMisalignment (VOID) +{ + /* Raise the Right Status */ + ExRaiseStatus (STATUS_DATATYPE_MISALIGNMENT); +} + +/* + * @implemented + */ +VOID +STDCALL +ExRaiseStatus(IN NTSTATUS Status) +{ + EXCEPTION_RECORD ExceptionRecord; + + DPRINT("ExRaiseStatus(%x)\n", Status); + + /* Set up an Exception Record */ + ExceptionRecord.ExceptionRecord = NULL; + ExceptionRecord.NumberParameters = 0; + ExceptionRecord.ExceptionCode = Status; + ExceptionRecord.ExceptionFlags = 0; + + /* Call the Rtl Function */ + RtlRaiseException(&ExceptionRecord); +} + +/* + * @implemented + */ +VOID +STDCALL +ExRaiseException (PEXCEPTION_RECORD ExceptionRecord) +{ + /* Call the Rtl function */ + RtlRaiseException(ExceptionRecord); +} + +/* + * @implemented + */ +BOOLEAN +STDCALL +ExSystemExceptionFilter(VOID) +{ + return KeGetPreviousMode() != KernelMode ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; +} + +/* + * @unimplemented + */ +VOID +STDCALL +ExRaiseHardError(IN NTSTATUS ErrorStatus, + IN ULONG NumberOfParameters, + IN PUNICODE_STRING UnicodeStringParameterMask OPTIONAL, + IN PVOID *Parameters, + IN HARDERROR_RESPONSE_OPTION ResponseOption, + OUT PHARDERROR_RESPONSE Response) +{ + UNIMPLEMENTED; +} + +NTSTATUS +STDCALL +NtRaiseHardError(IN NTSTATUS ErrorStatus, + IN ULONG NumberOfParameters, + IN PUNICODE_STRING UnicodeStringParameterMask OPTIONAL, + IN PVOID *Parameters, + IN HARDERROR_RESPONSE_OPTION ResponseOption, + OUT PHARDERROR_RESPONSE Response) +{ + DPRINT1("Hard error %x\n", ErrorStatus); + + /* Call the Executive Function (WE SHOULD PUT SEH HERE/CAPTURE!) */ + ExRaiseHardError(ErrorStatus, + NumberOfParameters, + UnicodeStringParameterMask, + Parameters, + ResponseOption, + Response); + + /* Return Success */ + return STATUS_SUCCESS; +} + +NTSTATUS +STDCALL +NtSetDefaultHardErrorPort(IN HANDLE PortHandle) +{ + + KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + NTSTATUS Status = STATUS_UNSUCCESSFUL; + + /* Check if we have the Privilege */ + if(!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode)) { + + DPRINT1("NtSetDefaultHardErrorPort: Caller requires the SeTcbPrivilege privilege!\n"); + return STATUS_PRIVILEGE_NOT_HELD; + } + + /* Only called once during bootup, make sure we weren't called yet */ + if(!ExReadyForErrors) { + + Status = ObReferenceObjectByHandle(PortHandle, + 0, + LpcPortObjectType, + PreviousMode, + (PVOID*)&ExpDefaultErrorPort, + NULL); + + /* Check for Success */ + if(NT_SUCCESS(Status)) { + + /* Save the data */ + ExpDefaultErrorPortProcess = PsGetCurrentProcess(); + ExReadyForErrors = TRUE; + } + } + + return Status; +} + +/* EOF */ Property changes on: trunk/reactos/ntoskrnl/ex/error.c ___________________________________________________________________ Name: svn:keywords + author date id revision Name: svn:eol-style + native _____
Modified: trunk/reactos/ntoskrnl/ke/catch.c --- trunk/reactos/ntoskrnl/ke/catch.c 2005-03-12 21:08:29 UTC (rev 13981) +++ trunk/reactos/ntoskrnl/ke/catch.c 2005-03-12 21:26:29 UTC (rev 13982) @@ -1,5 +1,4 @@
-/* $Id$ - * +/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: ntoskrnl/ke/catch.c @@ -21,240 +20,211 @@ RtlpDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context);
+/* + * @unimplemented + */ VOID -KiDispatchException(PEXCEPTION_RECORD ExceptionRecord, - PCONTEXT Context, - PKTRAP_FRAME Tf, - KPROCESSOR_MODE PreviousMode, - BOOLEAN SearchFrames) +STDCALL +KiCoprocessorError(VOID) { - EXCEPTION_DISPOSITION Value; - CONTEXT TContext; - KD_CONTINUE_TYPE Action = kdHandleException; + UNIMPLEMENTED; +}
- DPRINT("KiDispatchException() called\n"); +/* + * @unimplemented + */ +VOID +STDCALL +KiUnexpectedInterrupt(VOID) +{ + UNIMPLEMENTED; +}
+VOID +KiDispatchException(PEXCEPTION_RECORD ExceptionRecord, + PCONTEXT Context, + PKTRAP_FRAME Tf, + KPROCESSOR_MODE PreviousMode, + BOOLEAN SearchFrames) +{ + EXCEPTION_DISPOSITION Value; + CONTEXT TContext; + KD_CONTINUE_TYPE Action = kdHandleException;
- /* PCR->KeExceptionDispatchCount++; */ + DPRINT("KiDispatchException() called\n");
- if (Context == NULL) - { - TContext.ContextFlags = CONTEXT_FULL; - if (PreviousMode == UserMode) - { - TContext.ContextFlags = TContext.ContextFlags | CONTEXT_DEBUGGER; - } + /* Increase number of Exception Dispatches */ + KeGetCurrentPrcb()->KeExceptionDispatchCount++; + + if (!Context) { + + /* Assume Full context */ + TContext.ContextFlags = CONTEXT_FULL; + + /* Check the mode */ + if (PreviousMode == UserMode) { + + /* Add Debugger Registers if this is User Mode */ + TContext.ContextFlags = TContext.ContextFlags | CONTEXT_DEBUGGER; + }
- KeTrapFrameToContext(Tf, &TContext); + /* Convert the Trapframe into a Context */ + KeTrapFrameToContext(Tf, &TContext);
- Context = &TContext; + /* Use local stack context */ + Context = &TContext; }
-#if 0 - if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) - { - Context->Eip--; +#if 0 /* FIXME: Isn't this right? With a break after? */ + if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) { + Context->Eip--; } #endif - - if (KdDebuggerEnabled && KdDebugState & KD_DEBUG_GDB) - { - Action = KdEnterDebuggerException (ExceptionRecord, Context, Tf); - }
- if (Action == kdContinue) - { - return; + /* Check if a Debugger is enabled */ + if (KdDebuggerEnabled && KdDebugState & KD_DEBUG_GDB) { + + /* Break into it */ + Action = KdEnterDebuggerException (ExceptionRecord, Context, Tf); } + + /* If the debugger said continue, then continue */ + if (Action == kdContinue) return; + + /* If the Debugger couldn't handle it... */ + if (Action != kdDoNotHandleException) { + + /* See what kind of Exception this is */ + if (PreviousMode == UserMode) { + + /* User mode exception, search the frames if we have to */ + if (SearchFrames) {
- if (Action != kdDoNotHandleException) - { - if (PreviousMode == UserMode) - { - if (SearchFrames) - { - PULONG Stack; - ULONG CDest; - char temp_space[12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)]; /* FIXME: HACKHACK */ - PULONG pNewUserStack = (PULONG)(Tf->Esp - (12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT))); - NTSTATUS StatusOfCopy; + PULONG Stack; + ULONG CDest; + char temp_space[12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)]; /* FIXME: HACKHACK */ + PULONG pNewUserStack = (PULONG)(Tf->Esp - (12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT))); + NTSTATUS StatusOfCopy;
#ifdef KDBG - Action = KdbEnterDebuggerException (ExceptionRecord, PreviousMode, - Context, Tf, TRUE); - if (Action == kdContinue) - { - return; - } + /* Enter KDB if available */ + Action = KdbEnterDebuggerException(ExceptionRecord, + PreviousMode, + Context, + Tf, + TRUE); + + /* Exit if we're continuing */ + if (Action == kdContinue) return; #endif
- /* FIXME: Forward exception to user mode debugger */ + /* FIXME: Forward exception to user mode debugger */
- /* FIXME: Check user mode stack for enough space */ - - /* - * Let usermode try and handle the exception - */ - Stack = (PULONG)temp_space; - CDest = 3 + (ROUND_UP(sizeof(EXCEPTION_RECORD), 4) / 4); - /* Return address */ - Stack[0] = 0; - /* Pointer to EXCEPTION_RECORD structure */ - Stack[1] = (ULONG)&pNewUserStack[3]; - /* Pointer to CONTEXT structure */ - Stack[2] = (ULONG)&pNewUserStack[CDest]; - memcpy(&Stack[3], ExceptionRecord, sizeof(EXCEPTION_RECORD)); - memcpy(&Stack[CDest], Context, sizeof(CONTEXT)); + /* FIXME: Check user mode stack for enough space */ + + /* Let usermode try and handle the exception. Setup Stack */ + Stack = (PULONG)temp_space; + CDest = 3 + (ROUND_UP(sizeof(EXCEPTION_RECORD), 4) / 4); + /* Return Address */ + Stack[0] = 0; + /* Pointer to EXCEPTION_RECORD structure */ + Stack[1] = (ULONG)&pNewUserStack[3]; + /* Pointer to CONTEXT structure */ + Stack[2] = (ULONG)&pNewUserStack[CDest]; + memcpy(&Stack[3], ExceptionRecord, sizeof(EXCEPTION_RECORD)); + memcpy(&Stack[CDest], Context, sizeof(CONTEXT)); + + /* Copy Stack */ + StatusOfCopy = MmCopyToCaller(pNewUserStack, + temp_space, + (12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT))); + + /* Check for success */ + if (NT_SUCCESS(StatusOfCopy)) { + + /* Set new Stack Pointer */ + Tf->Esp = (ULONG)pNewUserStack; + + } else { + + /* + * Now it really hit the ventilation device. Sorry, + * can do nothing but kill the sucker. + */ + ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode); + DPRINT1("User-mode stack was invalid. Terminating target thread\n"); + } + + /* Set EIP to the User-mode Dispathcer */ + Tf->Eip = (ULONG)LdrpGetSystemDllExceptionDispatcher(); + return; + }
- StatusOfCopy = MmCopyToCaller(pNewUserStack, - temp_space, - (12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT))); - if (NT_SUCCESS(StatusOfCopy)) - { - Tf->Esp = (ULONG)pNewUserStack; - } - else - { - /* Now it really hit the ventilation device. Sorry, - * can do nothing but kill the sucker. - */ - ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode); - DPRINT1("User-mode stack was invalid. Terminating target thread\n"); - } - Tf->Eip = (ULONG)LdrpGetSystemDllExceptionDispatcher(); - return; - } + /* FIXME: Forward the exception to the debugger */
- /* FIXME: Forward the exception to the debugger */ + /* FIXME: Forward the exception to the process exception port */
- /* FIXME: Forward the exception to the process exception port */ - + #ifdef KDBG - Action = KdbEnterDebuggerException (ExceptionRecord, PreviousMode, - Context, Tf, FALSE); - if (Action == kdContinue) - { - return; - } + /* Enter KDB if available */ + Action = KdbEnterDebuggerException(ExceptionRecord, + PreviousMode, + Context, + Tf, + FALSE); + + /* Exit if we're continuing */ + if (Action == kdContinue) return; #endif
- /* Terminate the offending thread */ - DPRINT1("Unhandled UserMode exception, terminating thread\n"); - ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode); - } - else - { - /* PreviousMode == KernelMode */ + /* Terminate the offending thread */ + DPRINT1("Unhandled UserMode exception, terminating thread\n"); + ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode); + + } else { + + /* This is Kernel Mode */ #ifdef KDBG - Action = KdbEnterDebuggerException (ExceptionRecord, PreviousMode, - Context, Tf, TRUE); - if (Action == kdContinue) - { - return; - } + /* Enter KDB if available */ + Action = KdbEnterDebuggerException(ExceptionRecord, + PreviousMode, + Context, + Tf, + TRUE); + + /* Exit if we're continuing */ + if (Action == kdContinue) return; #endif
- Value = RtlpDispatchException (ExceptionRecord, Context); - - DPRINT("RtlpDispatchException() returned with 0x%X\n", Value); - /* - * If RtlpDispatchException() does not handle the exception then - * bugcheck - */ - if (Value != ExceptionContinueExecution || - 0 != (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)) - { - DPRINT("ExceptionRecord->ExceptionAddress = 0x%x\n", - ExceptionRecord->ExceptionAddress ); + /* Dispatch the Exception */ + Value = RtlpDispatchException (ExceptionRecord, Context); + DPRINT("RtlpDispatchException() returned with 0x%X\n", Value); + + /* If RtlpDispatchException() did not handle the exception then bugcheck */ + if (Value != ExceptionContinueExecution || + 0 != (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)) { + + DPRINT("ExceptionRecord->ExceptionAddress = 0x%x\n", ExceptionRecord->ExceptionAddress); #ifdef KDBG - Action = KdbEnterDebuggerException (ExceptionRecord, PreviousMode, - Context, Tf, FALSE); - if (Action == kdContinue) - { - return; - } + /* Enter KDB if available */ + Action = KdbEnterDebuggerException(ExceptionRecord, + PreviousMode, + Context, + Tf, + FALSE); + + /* Exit if we're continuing */ + if (Action == kdContinue) return; #endif - KEBUGCHECKWITHTF(KMODE_EXCEPTION_NOT_HANDLED, 0, 0, 0, 0, Tf); - } - } + KEBUGCHECKWITHTF(KMODE_EXCEPTION_NOT_HANDLED, + ExceptionRecord->ExceptionCode, + (ULONG)ExceptionRecord->ExceptionAddress, + ExceptionRecord->ExceptionInformation[0], + ExceptionRecord->ExceptionInformation[1], + Tf); + } + } } }
-/* - * @implemented - */ -VOID STDCALL -ExRaiseAccessViolation (VOID) -{ - ExRaiseStatus (STATUS_ACCESS_VIOLATION); -} - -/* - * @implemented - */ -VOID STDCALL -ExRaiseDatatypeMisalignment (VOID) -{ - ExRaiseStatus (STATUS_DATATYPE_MISALIGNMENT); -} - -/* - * @implemented - */ -VOID STDCALL -ExRaiseStatus (IN NTSTATUS Status) -{ - EXCEPTION_RECORD ExceptionRecord; - - DPRINT("ExRaiseStatus(%x)\n", Status); - - ExceptionRecord.ExceptionRecord = NULL; - ExceptionRecord.NumberParameters = 0; - ExceptionRecord.ExceptionCode = Status; - ExceptionRecord.ExceptionFlags = 0; - - RtlRaiseException(&ExceptionRecord); -} - - - -/* - * @implemented - */ -VOID -STDCALL -ExRaiseException ( - PEXCEPTION_RECORD ExceptionRecord - ) -{ - RtlRaiseException(ExceptionRecord); -} - -/* - * @implemented - */ -BOOLEAN -STDCALL -ExSystemExceptionFilter(VOID) -{ - return KeGetPreviousMode() != KernelMode ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; -} - -/* - * @unimplemented - */ -VOID -STDCALL -ExRaiseHardError ( - IN NTSTATUS ErrorStatus, - IN ULONG NumberOfParameters, - IN PUNICODE_STRING UnicodeStringParameterMask OPTIONAL, - IN PVOID *Parameters, - IN HARDERROR_RESPONSE_OPTION ResponseOption, - OUT PHARDERROR_RESPONSE Response - ) -{ - UNIMPLEMENTED; -} - /* EOF */ _____
Deleted: trunk/reactos/ntoskrnl/ke/error.c --- trunk/reactos/ntoskrnl/ke/error.c 2005-03-12 21:08:29 UTC (rev 13981) +++ trunk/reactos/ntoskrnl/ke/error.c 2005-03-12 21:26:29 UTC (rev 13982) @@ -1,98 +0,0 @@
-/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/ke/error.c - * PURPOSE: Error reason setting/getting - * - * PROGRAMMERS: David Welch - */ - -/* INCLUDE *****************************************************************/ - -#include <ntoskrnl.h> -#include <internal/debug.h> - -/* FUNCTIONS ***************************************************************/ - -BOOLEAN ExReadyForErrors = FALSE; -PEPORT ExpDefaultErrorPort = NULL; -PEPROCESS ExpDefaultErrorPortProcess = NULL; - -/* - * @unimplemented - */ -VOID -STDCALL -KiCoprocessorError( - VOID -) -{ - UNIMPLEMENTED; -} - -/* - * @unimplemented - */ -VOID -STDCALL -KiUnexpectedInterrupt( - VOID -) -{ - UNIMPLEMENTED; -} - -NTSTATUS STDCALL -NtRaiseHardError(IN NTSTATUS ErrorStatus, - IN ULONG NumberOfParameters, - IN PUNICODE_STRING UnicodeStringParameterMask OPTIONAL, - IN PVOID *Parameters, - IN HARDERROR_RESPONSE_OPTION ResponseOption, - OUT PHARDERROR_RESPONSE Response) -{ - DPRINT1("Hard error %x\n", ErrorStatus); - return(STATUS_SUCCESS); -} - -NTSTATUS STDCALL -NtSetDefaultHardErrorPort(IN HANDLE PortHandle) -{ - KPROCESSOR_MODE PreviousMode; - NTSTATUS Status; - - PreviousMode = ExGetPreviousMode(); - - if(!SeSinglePrivilegeCheck(SeTcbPrivilege, - PreviousMode)) - { - DPRINT1("NtSetDefaultHardErrorPort: Caller requires the SeTcbPrivilege privilege!\n"); - return STATUS_PRIVILEGE_NOT_HELD; - } - - /* serialization shouldn't be required here as it usually is just called once - during startup */ - - if(!ExReadyForErrors) - { - Status = ObReferenceObjectByHandle(PortHandle, - 0, - LpcPortObjectType, - PreviousMode, - (PVOID*)&ExpDefaultErrorPort, - NULL); - if(NT_SUCCESS(Status)) - { - ExpDefaultErrorPortProcess = PsGetCurrentProcess(); - ExReadyForErrors = TRUE; - } - } - else - { - Status = STATUS_UNSUCCESSFUL; - } - - return Status; -} - -/* EOF */