2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel
4 * FILE: ntoskrnl/ke/exception.c
5 * PURPOSE: Platform independent exception handling
6 * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
9 /* INCLUDES *****************************************************************/
13 #include <internal/debug.h>
15 /* FUNCTIONS ****************************************************************/
19 KiContinuePreviousModeUser(IN PCONTEXT Context
,
20 IN PKEXCEPTION_FRAME ExceptionFrame
,
21 IN PKTRAP_FRAME TrapFrame
)
25 /* We'll have to make a copy and probe it */
26 ProbeForRead(Context
, sizeof(CONTEXT
), sizeof(ULONG
));
27 RtlMoveMemory(&LocalContext
, Context
, sizeof(CONTEXT
));
28 Context
= &LocalContext
;
30 /* Convert the context into Exception/Trap Frames */
31 KeContextToTrapFrame(&LocalContext
, ExceptionFrame
, TrapFrame
, UserMode
);
36 KiContinue(IN PCONTEXT Context
,
37 IN PKEXCEPTION_FRAME ExceptionFrame
,
38 IN PKTRAP_FRAME TrapFrame
)
40 NTSTATUS Status
= STATUS_SUCCESS
;
41 KIRQL OldIrql
= APC_LEVEL
;
42 KPROCESSOR_MODE PreviousMode
= KeGetPreviousMode();
44 /* Raise to APC_LEVEL, only if needed */
45 if (KeGetCurrentIrql() < APC_LEVEL
)
47 /* Raise to APC_LEVEL */
48 KeRaiseIrql(APC_LEVEL
, &OldIrql
);
51 /* Set up SEH to validate the context */
54 /* Check the previous mode */
55 if (PreviousMode
!= KernelMode
)
57 /* Validate from user-mode */
58 KiContinuePreviousModeUser(Context
,
64 /* Convert the context into Exception/Trap Frames */
65 KeContextToTrapFrame(Context
, ExceptionFrame
, TrapFrame
, KernelMode
);
70 Status
= _SEH_GetExceptionCode();
74 /* Lower the IRQL if needed */
75 if (OldIrql
< APC_LEVEL
) KeLowerIrql(OldIrql
);
83 KiRaiseException(PEXCEPTION_RECORD ExceptionRecord
,
85 PKEXCEPTION_FRAME ExceptionFrame
,
86 PKTRAP_FRAME TrapFrame
,
89 KPROCESSOR_MODE PreviousMode
= KeGetPreviousMode();
91 EXCEPTION_RECORD LocalExceptionRecord
;
92 ULONG ParameterCount
, Size
;
93 NTSTATUS Status
= STATUS_SUCCESS
;
94 DPRINT1("KiRaiseException\n");
99 /* Check the previous mode */
100 if (PreviousMode
!= KernelMode
)
103 /* Probe the context */
104 ProbeForRead(Context
, sizeof(CONTEXT
), sizeof(ULONG
));
106 /* Probe the Exception Record */
107 ProbeForRead(ExceptionRecord
,
108 FIELD_OFFSET(EXCEPTION_RECORD
, NumberParameters
) +
112 /* Validate the maximum parameters */
113 if ((ParameterCount
= ExceptionRecord
->NumberParameters
) >
114 EXCEPTION_MAXIMUM_PARAMETERS
)
117 Status
= STATUS_INVALID_PARAMETER
;
121 /* Probe the entire parameters now*/
122 Size
= (sizeof(EXCEPTION_RECORD
) -
123 ((EXCEPTION_MAXIMUM_PARAMETERS
- ParameterCount
) * sizeof(ULONG
)));
124 ProbeForRead(ExceptionRecord
, Size
, sizeof(ULONG
));
126 /* Now make copies in the stack */
127 RtlMoveMemory(&LocalContext
, Context
, sizeof(CONTEXT
));
128 RtlMoveMemory(&LocalExceptionRecord
, ExceptionRecord
, Size
);
129 Context
= &LocalContext
;
130 ExceptionRecord
= &LocalExceptionRecord
;
132 /* Update the parameter count */
133 ExceptionRecord
->NumberParameters
= ParameterCount
;
138 Status
= _SEH_GetExceptionCode();
142 if (NT_SUCCESS(Status
))
144 /* Convert the context record */
145 KeContextToTrapFrame(Context
, ExceptionFrame
, TrapFrame
, PreviousMode
);
147 /* Dispatch the exception */
148 KiDispatchException(ExceptionRecord
,
155 /* Return the status */