* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/catch.c
* PURPOSE: Exception handling
- *
+ *
* PROGRAMMERS: Anich Gregor
* David Welch (welch@mcmail.com)
* Casper S. Hornstrup (chorns@users.sourceforge.net)
/* Increase number of Exception Dispatches */
KeGetCurrentPrcb()->KeExceptionDispatchCount++;
- if (!Context)
+ if (!Context)
{
/* Assume Full context */
TContext.ContextFlags = CONTEXT_FULL;
-
+
/* Check the mode */
- if (PreviousMode == UserMode)
+ if (PreviousMode != KernelMode)
{
/* Add Debugger Registers if this is User Mode */
TContext.ContextFlags = TContext.ContextFlags | CONTEXT_DEBUGGER;
}
-
+
/* Convert the Trapframe into a Context */
KeTrapFrameToContext(Tf, &TContext);
}
/* Break into Debugger */
- Action = KdpEnterDebuggerException(ExceptionRecord,
- PreviousMode,
- Context,
- Tf,
+ Action = KdpEnterDebuggerException(ExceptionRecord,
+ PreviousMode,
+ Context,
+ Tf,
TRUE,
TRUE);
/* If the debugger said continue, then continue */
if (Action == kdContinue) return;
-
+
/* If the Debugger couldn't handle it... */
- if (Action != kdDoNotHandleException)
- {
+ if (Action != kdDoNotHandleException)
+ {
/* See what kind of Exception this is */
- if (PreviousMode == UserMode)
- {
+ if (PreviousMode != KernelMode)
+ {
/* User mode exception, search the frames if we have to */
- if (SearchFrames)
+ 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;
+ NTSTATUS Status = STATUS_SUCCESS;
/* Enter Debugger if available */
- Action = KdpEnterDebuggerException(ExceptionRecord,
+ Action = KdpEnterDebuggerException(ExceptionRecord,
PreviousMode,
- Context,
- Tf,
+ Context,
+ Tf,
TRUE,
FALSE);
/* FIXME: Forward exception to user mode debugger */
/* 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);
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)));
-
+ _SEH_TRY
+ {
+ ProbeForWrite(pNewUserStack,
+ 12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT),
+ 1);
+ RtlCopyMemory(pNewUserStack,
+ temp_space,
+ 12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT));
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
/* Check for success */
- if (NT_SUCCESS(StatusOfCopy))
+ if (NT_SUCCESS(Status))
{
/* Set new Stack Pointer */
Tf->Esp = (ULONG)pNewUserStack;
- }
- else
- {
+ }
+ else
+ {
/*
* Now it really hit the ventilation device. Sorry,
* can do nothing but kill the sucker.
DPRINT1("User-mode stack was invalid. Terminating target thread\n");
}
/* Set EIP to the User-mode Dispathcer */
- Tf->Eip = (ULONG)LdrpGetSystemDllExceptionDispatcher();
+ Tf->Eip = (ULONG)KeUserExceptionDispatcher;
return;
}
/* FIXME: Forward the exception to the process exception port */
/* Enter KDB if available */
- Action = KdpEnterDebuggerException(ExceptionRecord,
+ Action = KdpEnterDebuggerException(ExceptionRecord,
PreviousMode,
- Context,
- Tf,
+ Context,
+ Tf,
FALSE,
FALSE);
/* Terminate the offending thread */
DPRINT1("Unhandled UserMode exception, terminating thread\n");
ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode);
- }
- else
+ }
+ else
{
- /* This is Kernel Mode */
+ /* This is Kernel Mode */
/* Enter KDB if available */
- Action = KdpEnterDebuggerException(ExceptionRecord,
+ Action = KdpEnterDebuggerException(ExceptionRecord,
PreviousMode,
- Context,
- Tf,
+ Context,
+ Tf,
TRUE,
FALSE);
/* 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))
+ 0 != (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE))
{
- DPRINT("ExceptionRecord->ExceptionAddress = 0x%x\n", ExceptionRecord->ExceptionAddress);
+ DPRINT("ExceptionRecord->ExceptionAddress = 0x%p\n", ExceptionRecord->ExceptionAddress);
/* Enter KDB if available */
- Action = KdpEnterDebuggerException(ExceptionRecord,
+ Action = KdpEnterDebuggerException(ExceptionRecord,
PreviousMode,
- Context,
- Tf,
+ Context,
+ Tf,
FALSE,
FALSE);
/* Exit if we're continuing */
if (Action == kdContinue) return;
- KEBUGCHECKWITHTF(KMODE_EXCEPTION_NOT_HANDLED,
- ExceptionRecord->ExceptionCode,
+ KEBUGCHECKWITHTF(KMODE_EXCEPTION_NOT_HANDLED,
+ ExceptionRecord->ExceptionCode,
(ULONG)ExceptionRecord->ExceptionAddress,
ExceptionRecord->ExceptionInformation[0],
ExceptionRecord->ExceptionInformation[1],