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
);
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
);
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
)
102 /* Probe the context */
103 ProbeForRead(Context
, sizeof(CONTEXT
), sizeof(ULONG
));
105 /* Probe the Exception Record */
106 ProbeForRead(ExceptionRecord
,
107 FIELD_OFFSET(EXCEPTION_RECORD
, NumberParameters
) +
111 /* Validate the maximum parameters */
112 if ((ParameterCount
= ExceptionRecord
->NumberParameters
) >
113 EXCEPTION_MAXIMUM_PARAMETERS
)
116 return STATUS_INVALID_PARAMETER
;
119 /* Probe the entire parameters now*/
120 Size
= (sizeof(EXCEPTION_RECORD
) -
121 ((EXCEPTION_MAXIMUM_PARAMETERS
- ParameterCount
) * sizeof(ULONG
)));
122 ProbeForRead(ExceptionRecord
, Size
, sizeof(ULONG
));
124 /* Now make copies in the stack */
125 RtlMoveMemory(&LocalContext
, Context
, sizeof(CONTEXT
));
126 RtlMoveMemory(&LocalExceptionRecord
, ExceptionRecord
, Size
);
127 Context
= &LocalContext
;
128 ExceptionRecord
= &LocalExceptionRecord
;
130 /* Update the parameter count */
131 ExceptionRecord
->NumberParameters
= ParameterCount
;
136 Status
= _SEH_GetExceptionCode();
140 if (NT_SUCCESS(Status
))
142 /* Convert the context record */
143 KeContextToTrapFrame(Context
, ExceptionFrame
, TrapFrame
);
145 /* Dispatch the exception */
146 KiDispatchException(ExceptionRecord
,
153 /* Return the status */