ReactOS 0.4.15-dev-8058-ga7cbb60
except.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: ntoskrnl/ke/except.c
5 * PURPOSE: Platform independent exception handling
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 * Alex Ionescu (alex.ionescu@reactos.org)
8 */
9
10/* INCLUDES ******************************************************************/
11
12#include <ntoskrnl.h>
13#define NDEBUG
14#include <debug.h>
15
16/* FUNCTIONS *****************************************************************/
17
18VOID
22 _Out_ PKEXCEPTION_FRAME ExceptionFrame,
23 _Out_ PKTRAP_FRAME TrapFrame)
24{
25 CONTEXT LocalContext;
26
27 /* We'll have to make a copy and probe it */
28 ProbeForRead(Context, sizeof(CONTEXT), sizeof(ULONG));
29 RtlCopyMemory(&LocalContext, Context, sizeof(CONTEXT));
30 Context = &LocalContext;
31
32 /* Convert the context into Exception/Trap Frames */
33 KeContextToTrapFrame(&LocalContext,
34 ExceptionFrame,
35 TrapFrame,
36 LocalContext.ContextFlags,
37 UserMode);
38}
39
43 IN PKEXCEPTION_FRAME ExceptionFrame,
44 IN PKTRAP_FRAME TrapFrame)
45{
49
50 /* Raise to APC_LEVEL, only if needed */
52
53 /* Set up SEH to validate the context */
55 {
56 /* Check the previous mode */
58 {
59 /* Validate from user-mode */
61 ExceptionFrame,
62 TrapFrame);
63 }
64 else
65 {
66 /* Convert the context into Exception/Trap Frames */
68 ExceptionFrame,
69 TrapFrame,
70 Context->ContextFlags,
72 }
73 }
75 {
76 /* Save the exception code */
78 }
80
81 /* Lower the IRQL if needed */
83
84 /* Return status */
85 return Status;
86}
87
91 _In_ PEXCEPTION_RECORD ExceptionRecord,
93 _Out_ PKEXCEPTION_FRAME ExceptionFrame,
94 _Out_ PKTRAP_FRAME TrapFrame,
95 _In_ BOOLEAN SearchFrames)
96{
98 CONTEXT LocalContext;
99 EXCEPTION_RECORD LocalExceptionRecord;
100 ULONG ParameterCount, Size;
101
102 /* Check if we need to probe */
104 {
105 /* Set up SEH */
107 {
108 /* Probe the context */
109 ProbeForRead(Context, sizeof(CONTEXT), sizeof(ULONG));
110
111 /* Probe the Exception Record */
112 ProbeForRead(ExceptionRecord,
113 FIELD_OFFSET(EXCEPTION_RECORD, NumberParameters) +
114 sizeof(ULONG),
115 sizeof(ULONG));
116
117 /* Validate the maximum parameters */
118 if ((ParameterCount = ExceptionRecord->NumberParameters) >
120 {
121 /* Too large */
123 }
124
125 /* Probe the entire parameters now*/
126 Size = (sizeof(EXCEPTION_RECORD) -
127 ((EXCEPTION_MAXIMUM_PARAMETERS - ParameterCount) * sizeof(ULONG)));
128 ProbeForRead(ExceptionRecord, Size, sizeof(ULONG));
129
130 /* Now make copies in the stack */
131 RtlCopyMemory(&LocalContext, Context, sizeof(CONTEXT));
132 RtlCopyMemory(&LocalExceptionRecord, ExceptionRecord, Size);
133 Context = &LocalContext;
134 ExceptionRecord = &LocalExceptionRecord;
135
136 /* Update the parameter count */
137 ExceptionRecord->NumberParameters = ParameterCount;
138 }
140 {
141 /* Don't fail silently */
142 DPRINT1("KiRaiseException: Failed to Probe\n");
143
144 /* Return the exception code */
146 }
147 _SEH2_END;
148 }
149
150 /* Convert the context record */
152 ExceptionFrame,
153 TrapFrame,
154 Context->ContextFlags,
156
157 /* Dispatch the exception */
158 ExceptionRecord->ExceptionCode &= ~KI_EXCEPTION_INTERNAL;
159 KiDispatchException(ExceptionRecord,
160 ExceptionFrame,
161 TrapFrame,
163 SearchFrames);
164
165 /* We are done */
166 return STATUS_SUCCESS;
167}
168
169/* SYSTEM CALLS ***************************************************************/
170
172NTAPI
174 _In_ PEXCEPTION_RECORD ExceptionRecord,
176 _In_ BOOLEAN FirstChance)
177{
180 PKTRAP_FRAME TrapFrame;
181#ifdef _M_IX86
182 PKEXCEPTION_FRAME ExceptionFrame = NULL;
183#else
184 KEXCEPTION_FRAME LocalExceptionFrame;
185 PKEXCEPTION_FRAME ExceptionFrame = &LocalExceptionFrame;
186#endif
187
188 /* Get trap frame and link previous one */
190 TrapFrame = Thread->TrapFrame;
191 Thread->TrapFrame = KiGetLinkedTrapFrame(TrapFrame);
192
193 /* Set exception list */
194#ifdef _M_IX86
195 KeGetPcr()->NtTib.ExceptionList = TrapFrame->ExceptionList;
196#endif
197
198 /* Raise the exception */
199 Status = KiRaiseException(ExceptionRecord,
200 Context,
201 ExceptionFrame,
202 TrapFrame,
203 FirstChance);
204 if (!NT_SUCCESS(Status))
205 {
206 DPRINT1("KiRaiseException failed. Status = 0x%lx\n", Status);
207 return Status;
208 }
209
210 /* It was handled, so exit restoring all state */
211 KiExceptionExit(TrapFrame, ExceptionFrame);
212}
213
215NTAPI
218 _In_ BOOLEAN TestAlert)
219{
222 PKTRAP_FRAME TrapFrame;
223#ifdef _M_IX86
224 PKEXCEPTION_FRAME ExceptionFrame = NULL;
225#else
226 KEXCEPTION_FRAME LocalExceptionFrame;
227 PKEXCEPTION_FRAME ExceptionFrame = &LocalExceptionFrame;
228#endif
229
230 /* Get trap frame and link previous one*/
232 TrapFrame = Thread->TrapFrame;
233 Thread->TrapFrame = KiGetLinkedTrapFrame(TrapFrame);
234
235 /* Continue from this point on */
236 Status = KiContinue(Context, ExceptionFrame, TrapFrame);
237 if (!NT_SUCCESS(Status))
238 {
239 DPRINT1("KiContinue failed. Status = 0x%lx\n", Status);
240 return Status;
241 }
242
243 /* Check if alert was requested */
244 if (TestAlert)
245 {
246 KeTestAlertThread(Thread->PreviousMode);
247 }
248
249 /* Exit to new context */
250 KiExceptionExit(TrapFrame, ExceptionFrame);
251}
252
253/* EOF */
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define EXCEPTION_MAXIMUM_PARAMETERS
Definition: compat.h:206
struct _EXCEPTION_RECORD EXCEPTION_RECORD
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
Status
Definition: gdiplustypes.h:25
#define KeGetCurrentThread
Definition: hal.h:55
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
#define KernelMode
Definition: asm.h:34
#define UserMode
Definition: asm.h:35
#define KeGetPreviousMode()
Definition: ketypes.h:1115
#define KeGetPcr()
Definition: ketypes.h:81
DECLSPEC_NORETURN VOID KiExceptionExit(_In_ PKTRAP_FRAME TrapFrame, _In_ PKEXCEPTION_FRAME ExceptionFrame)
Definition: ke.h:689
#define KiGetLinkedTrapFrame(x)
Definition: ke.h:177
BOOLEAN NTAPI KeTestAlertThread(IN KPROCESSOR_MODE AlertMode)
Definition: thrdobj.c:722
VOID NTAPI KeContextToTrapFrame(PCONTEXT Context, PKEXCEPTION_FRAME ExeptionFrame, PKTRAP_FRAME TrapFrame, ULONG ContextFlags, KPROCESSOR_MODE PreviousMode)
VOID NTAPI KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN FirstChance)
Definition: except.c:248
VOID NTAPI KiContinuePreviousModeUser(_In_ PCONTEXT Context, _Out_ PKEXCEPTION_FRAME ExceptionFrame, _Out_ PKTRAP_FRAME TrapFrame)
Definition: except.c:20
NTSTATUS NTAPI KiRaiseException(_In_ PEXCEPTION_RECORD ExceptionRecord, _In_ PCONTEXT Context, _Out_ PKEXCEPTION_FRAME ExceptionFrame, _Out_ PKTRAP_FRAME TrapFrame, _In_ BOOLEAN SearchFrames)
Definition: except.c:90
NTSTATUS NTAPI NtRaiseException(_In_ PEXCEPTION_RECORD ExceptionRecord, _In_ PCONTEXT Context, _In_ BOOLEAN FirstChance)
Definition: except.c:173
NTSTATUS NTAPI KiContinue(IN PCONTEXT Context, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame)
Definition: except.c:42
NTSTATUS NTAPI NtContinue(_In_ PCONTEXT Context, _In_ BOOLEAN TestAlert)
Definition: except.c:216
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
#define STATUS_SUCCESS
Definition: shellext.h:65
ULONG ContextFlags
Definition: nt_native.h:1426
DWORD NumberParameters
Definition: compat.h:212
struct _EXCEPTION_REGISTRATION_RECORD FAR * ExceptionList
Definition: ketypes.h:314
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103