-/*\r
- * PROJECT: ReactOS Kernel\r
- * LICENSE: GPL - See COPYING in the top level directory\r
- * FILE: ntoskrnl/ke/except.c\r
- * PURPOSE: Platform independent exception handling\r
- * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)\r
- */\r
-\r
-/* INCLUDES ******************************************************************/\r
-\r
-#include <ntoskrnl.h>\r
-#define NDEBUG\r
-#include <internal/debug.h>\r
-\r
-/* FUNCTIONS *****************************************************************/\r
-\r
-VOID\r
-NTAPI\r
-KiContinuePreviousModeUser(IN PCONTEXT Context,\r
- IN PKEXCEPTION_FRAME ExceptionFrame,\r
- IN PKTRAP_FRAME TrapFrame)\r
-{\r
- CONTEXT LocalContext;\r
-\r
- /* We'll have to make a copy and probe it */\r
- ProbeForRead(Context, sizeof(CONTEXT), sizeof(ULONG));\r
- RtlMoveMemory(&LocalContext, Context, sizeof(CONTEXT));\r
- Context = &LocalContext;\r
-\r
- /* Convert the context into Exception/Trap Frames */\r
- KeContextToTrapFrame(&LocalContext,\r
- ExceptionFrame,\r
- TrapFrame,\r
- LocalContext.ContextFlags,\r
- UserMode);\r
-}\r
-\r
-NTSTATUS\r
-NTAPI\r
-KiContinue(IN PCONTEXT Context,\r
- IN PKEXCEPTION_FRAME ExceptionFrame,\r
- IN PKTRAP_FRAME TrapFrame)\r
-{\r
- NTSTATUS Status = STATUS_SUCCESS;\r
- KIRQL OldIrql = APC_LEVEL;\r
- KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();\r
-\r
- /* Raise to APC_LEVEL, only if needed */\r
- if (KeGetCurrentIrql() < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);\r
-\r
- /* Set up SEH to validate the context */\r
- _SEH_TRY\r
- {\r
- /* Check the previous mode */\r
- if (PreviousMode != KernelMode)\r
- {\r
- /* Validate from user-mode */\r
- KiContinuePreviousModeUser(Context,\r
- ExceptionFrame,\r
- TrapFrame);\r
- }\r
- else\r
- {\r
- /* Convert the context into Exception/Trap Frames */\r
- KeContextToTrapFrame(Context,\r
- ExceptionFrame,\r
- TrapFrame,\r
- Context->ContextFlags,\r
- KernelMode);\r
- }\r
- }\r
- _SEH_HANDLE\r
- {\r
- /* Save the exception code */\r
- Status = _SEH_GetExceptionCode();\r
- }\r
- _SEH_END;\r
-\r
- /* Lower the IRQL if needed */\r
- if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);\r
-\r
- /* Return status */\r
- return Status;\r
-}\r
-\r
-NTSTATUS\r
-NTAPI\r
-KiRaiseException(IN PEXCEPTION_RECORD ExceptionRecord,\r
- IN PCONTEXT Context,\r
- IN PKEXCEPTION_FRAME ExceptionFrame,\r
- IN PKTRAP_FRAME TrapFrame,\r
- IN BOOLEAN SearchFrames)\r
-{\r
- KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();\r
- CONTEXT LocalContext;\r
- EXCEPTION_RECORD LocalExceptionRecord;\r
- ULONG ParameterCount, Size;\r
- NTSTATUS Status = STATUS_SUCCESS;\r
-\r
- /* Set up SEH */\r
- _SEH_TRY\r
- {\r
- /* Check the previous mode */\r
- if (PreviousMode != KernelMode)\r
- {\r
-#if 0\r
- /* Probe the context */\r
- ProbeForRead(Context, sizeof(CONTEXT), sizeof(ULONG));\r
-\r
- /* Probe the Exception Record */\r
- ProbeForRead(ExceptionRecord,\r
- FIELD_OFFSET(EXCEPTION_RECORD, NumberParameters) +\r
- sizeof(ULONG),\r
- sizeof(ULONG));\r
-#endif\r
- /* Validate the maximum parameters */\r
- if ((ParameterCount = ExceptionRecord->NumberParameters) >\r
- EXCEPTION_MAXIMUM_PARAMETERS)\r
- {\r
- /* Too large */\r
- Status = STATUS_INVALID_PARAMETER;\r
- _SEH_LEAVE;\r
- }\r
-\r
- /* Probe the entire parameters now*/\r
- Size = (sizeof(EXCEPTION_RECORD) - \r
- ((EXCEPTION_MAXIMUM_PARAMETERS - ParameterCount) * sizeof(ULONG)));\r
- ProbeForRead(ExceptionRecord, Size, sizeof(ULONG));\r
-\r
- /* Now make copies in the stack */\r
- RtlMoveMemory(&LocalContext, Context, sizeof(CONTEXT));\r
- RtlMoveMemory(&LocalExceptionRecord, ExceptionRecord, Size);\r
- Context = &LocalContext;\r
- ExceptionRecord = &LocalExceptionRecord;\r
-\r
- /* Update the parameter count */\r
- ExceptionRecord->NumberParameters = ParameterCount;\r
- }\r
- }\r
- _SEH_HANDLE\r
- {\r
- /* Get the exception code */\r
- Status = _SEH_GetExceptionCode();\r
- }\r
- _SEH_END;\r
-\r
- /* Make sure we didn't crash in SEH */\r
- if (NT_SUCCESS(Status))\r
- {\r
- /* Convert the context record */\r
- KeContextToTrapFrame(Context,\r
- ExceptionFrame,\r
- TrapFrame,\r
- Context->ContextFlags,\r
- PreviousMode);\r
-\r
- /* Dispatch the exception */\r
- KiDispatchException(ExceptionRecord,\r
- ExceptionFrame,\r
- TrapFrame,\r
- PreviousMode,\r
- SearchFrames);\r
- }\r
-\r
- /* Return the status */\r
- return Status;\r
-}\r
-\r
-/* EOF */\r
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/ke/except.c
+ * PURPOSE: Platform independent exception handling
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+VOID
+NTAPI
+KiContinuePreviousModeUser(IN PCONTEXT Context,
+ IN PKEXCEPTION_FRAME ExceptionFrame,
+ IN PKTRAP_FRAME TrapFrame)
+{
+ CONTEXT LocalContext;
+
+ /* We'll have to make a copy and probe it */
+ ProbeForRead(Context, sizeof(CONTEXT), sizeof(ULONG));
+ RtlCopyMemory(&LocalContext, Context, sizeof(CONTEXT));
+ Context = &LocalContext;
+
+ /* Convert the context into Exception/Trap Frames */
+ KeContextToTrapFrame(&LocalContext,
+ ExceptionFrame,
+ TrapFrame,
+ LocalContext.ContextFlags,
+ UserMode);
+}
+
+NTSTATUS
+NTAPI
+KiContinue(IN PCONTEXT Context,
+ IN PKEXCEPTION_FRAME ExceptionFrame,
+ IN PKTRAP_FRAME TrapFrame)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ KIRQL OldIrql = APC_LEVEL;
+ KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
+
+ /* Raise to APC_LEVEL, only if needed */
+ if (KeGetCurrentIrql() < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
+
+ /* Set up SEH to validate the context */
+ _SEH2_TRY
+ {
+ /* Check the previous mode */
+ if (PreviousMode != KernelMode)
+ {
+ /* Validate from user-mode */
+ KiContinuePreviousModeUser(Context,
+ ExceptionFrame,
+ TrapFrame);
+ }
+ else
+ {
+ /* Convert the context into Exception/Trap Frames */
+ KeContextToTrapFrame(Context,
+ ExceptionFrame,
+ TrapFrame,
+ Context->ContextFlags,
+ KernelMode);
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Save the exception code */
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ /* Lower the IRQL if needed */
+ if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);
+
+ /* Return status */
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+KiRaiseException(IN PEXCEPTION_RECORD ExceptionRecord,
+ IN PCONTEXT Context,
+ IN PKEXCEPTION_FRAME ExceptionFrame,
+ IN PKTRAP_FRAME TrapFrame,
+ IN BOOLEAN SearchFrames)
+{
+ KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
+ CONTEXT LocalContext;
+ EXCEPTION_RECORD LocalExceptionRecord;
+ ULONG ParameterCount, Size;
+
+ /* Check if we need to probe */
+ if (PreviousMode != KernelMode)
+ {
+ /* Set up SEH */
+ _SEH2_TRY
+ {
+ /* Probe the context */
+ ProbeForRead(Context, sizeof(CONTEXT), sizeof(ULONG));
+
+ /* Probe the Exception Record */
+ ProbeForRead(ExceptionRecord,
+ FIELD_OFFSET(EXCEPTION_RECORD, NumberParameters) +
+ sizeof(ULONG),
+ sizeof(ULONG));
+
+ /* Validate the maximum parameters */
+ if ((ParameterCount = ExceptionRecord->NumberParameters) >
+ EXCEPTION_MAXIMUM_PARAMETERS)
+ {
+ /* Too large */
+ _SEH2_YIELD(return STATUS_INVALID_PARAMETER);
+ }
+
+ /* Probe the entire parameters now*/
+ Size = (sizeof(EXCEPTION_RECORD) -
+ ((EXCEPTION_MAXIMUM_PARAMETERS - ParameterCount) * sizeof(ULONG)));
+ ProbeForRead(ExceptionRecord, Size, sizeof(ULONG));
+
+ /* Now make copies in the stack */
+ RtlCopyMemory(&LocalContext, Context, sizeof(CONTEXT));
+ RtlCopyMemory(&LocalExceptionRecord, ExceptionRecord, Size);
+ Context = &LocalContext;
+ ExceptionRecord = &LocalExceptionRecord;
+
+ /* Update the parameter count */
+ ExceptionRecord->NumberParameters = ParameterCount;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Don't fail silently */
+ DPRINT1("KiRaiseException: Failed to Probe\n");
+ DbgBreakPoint();
+
+ /* Return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+ }
+
+ /* Convert the context record */
+ KeContextToTrapFrame(Context,
+ ExceptionFrame,
+ TrapFrame,
+ Context->ContextFlags,
+ PreviousMode);
+
+ /* Dispatch the exception */
+ ExceptionRecord->ExceptionCode &= ~KI_EXCEPTION_INTERNAL;
+ KiDispatchException(ExceptionRecord,
+ ExceptionFrame,
+ TrapFrame,
+ PreviousMode,
+ SearchFrames);
+
+ /* We are done */
+ return STATUS_SUCCESS;
+}
+
+/* EOF */