ReactOS 0.4.15-dev-7961-gdcf9eb0
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
21 IN PKEXCEPTION_FRAME ExceptionFrame,
22 IN PKTRAP_FRAME TrapFrame)
23{
24 CONTEXT LocalContext;
25
26 /* We'll have to make a copy and probe it */
27 ProbeForRead(Context, sizeof(CONTEXT), sizeof(ULONG));
28 RtlCopyMemory(&LocalContext, Context, sizeof(CONTEXT));
29 Context = &LocalContext;
30
31#ifdef _M_AMD64
32 KiSetTrapContext(TrapFrame, &LocalContext, UserMode);
33#else
34 /* Convert the context into Exception/Trap Frames */
35 KeContextToTrapFrame(&LocalContext,
36 ExceptionFrame,
37 TrapFrame,
38 LocalContext.ContextFlags,
39 UserMode);
40#endif
41}
42
46 IN PKEXCEPTION_FRAME ExceptionFrame,
47 IN PKTRAP_FRAME TrapFrame)
48{
52
53 /* Raise to APC_LEVEL, only if needed */
55
56 /* Set up SEH to validate the context */
58 {
59 /* Check the previous mode */
61 {
62 /* Validate from user-mode */
64 ExceptionFrame,
65 TrapFrame);
66 }
67 else
68 {
69#ifdef _M_AMD64
71#else
72 /* Convert the context into Exception/Trap Frames */
74 ExceptionFrame,
75 TrapFrame,
76 Context->ContextFlags,
78#endif
79 }
80 }
82 {
83 /* Save the exception code */
85 }
87
88 /* Lower the IRQL if needed */
90
91 /* Return status */
92 return Status;
93}
94
99 IN PKEXCEPTION_FRAME ExceptionFrame,
100 IN PKTRAP_FRAME TrapFrame,
101 IN BOOLEAN SearchFrames)
102{
104 CONTEXT LocalContext;
105 EXCEPTION_RECORD LocalExceptionRecord;
106 ULONG ParameterCount, Size;
107
108 /* Check if we need to probe */
110 {
111 /* Set up SEH */
113 {
114 /* Probe the context */
115 ProbeForRead(Context, sizeof(CONTEXT), sizeof(ULONG));
116
117 /* Probe the Exception Record */
118 ProbeForRead(ExceptionRecord,
119 FIELD_OFFSET(EXCEPTION_RECORD, NumberParameters) +
120 sizeof(ULONG),
121 sizeof(ULONG));
122
123 /* Validate the maximum parameters */
124 if ((ParameterCount = ExceptionRecord->NumberParameters) >
126 {
127 /* Too large */
129 }
130
131 /* Probe the entire parameters now*/
132 Size = (sizeof(EXCEPTION_RECORD) -
133 ((EXCEPTION_MAXIMUM_PARAMETERS - ParameterCount) * sizeof(ULONG)));
134 ProbeForRead(ExceptionRecord, Size, sizeof(ULONG));
135
136 /* Now make copies in the stack */
137 RtlCopyMemory(&LocalContext, Context, sizeof(CONTEXT));
138 RtlCopyMemory(&LocalExceptionRecord, ExceptionRecord, Size);
139 Context = &LocalContext;
140 ExceptionRecord = &LocalExceptionRecord;
141
142 /* Update the parameter count */
143 ExceptionRecord->NumberParameters = ParameterCount;
144 }
146 {
147 /* Don't fail silently */
148 DPRINT1("KiRaiseException: Failed to Probe\n");
149
150 /* Return the exception code */
152 }
153 _SEH2_END;
154 }
155
156 /* Convert the context record */
158 ExceptionFrame,
159 TrapFrame,
160 Context->ContextFlags,
162
163 /* Dispatch the exception */
164 ExceptionRecord->ExceptionCode &= ~KI_EXCEPTION_INTERNAL;
165 KiDispatchException(ExceptionRecord,
166 ExceptionFrame,
167 TrapFrame,
169 SearchFrames);
170
171 /* We are done */
172 return STATUS_SUCCESS;
173}
174
175/* SYSTEM CALLS ***************************************************************/
176
178NTAPI
181 IN BOOLEAN FirstChance)
182{
185 PKTRAP_FRAME TrapFrame;
186
187 /* Get trap frame and link previous one*/
189 TrapFrame = Thread->TrapFrame;
190 Thread->TrapFrame = KiGetLinkedTrapFrame(TrapFrame);
191
192 /* Set exception list */
193#ifdef _M_IX86
194 KeGetPcr()->NtTib.ExceptionList = TrapFrame->ExceptionList;
195#endif
196
197 /* Raise the exception */
198 Status = KiRaiseException(ExceptionRecord,
199 Context,
200 NULL,
201 TrapFrame,
202 FirstChance);
203 if (NT_SUCCESS(Status))
204 {
205 /* It was handled, so exit restoring all state */
206 KiServiceExit2(TrapFrame);
207 }
208 else
209 {
210 /* Exit with error */
211 KiServiceExit(TrapFrame, Status);
212 }
213
214 /* We don't actually make it here */
215 return Status;
216}
217
219NTAPI
221 IN BOOLEAN TestAlert)
222{
225 PKTRAP_FRAME TrapFrame;
226
227 /* Get trap frame and link previous one*/
229 TrapFrame = Thread->TrapFrame;
230 Thread->TrapFrame = KiGetLinkedTrapFrame(TrapFrame);
231
232 /* Continue from this point on */
233 Status = KiContinue(Context, NULL, TrapFrame);
234 if (NT_SUCCESS(Status))
235 {
236 /* Check if alert was requested */
237 if (TestAlert) KeTestAlertThread(Thread->PreviousMode);
238
239 /* Exit to new trap frame */
240 KiServiceExit2(TrapFrame);
241 }
242 else
243 {
244 /* Exit with an error */
245 KiServiceExit(TrapFrame, Status);
246 }
247
248 /* We don't actually make it here */
249 return Status;
250}
251
252/* 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 KernelMode
Definition: asm.h:34
#define UserMode
Definition: asm.h:35
#define KeGetPreviousMode()
Definition: ketypes.h:1115
#define KeGetPcr()
Definition: ketypes.h:81
VOID KiSetTrapContext(_Out_ PKTRAP_FRAME TrapFrame, _In_ PCONTEXT Context, _In_ KPROCESSOR_MODE RequestorMode)
#define KiGetLinkedTrapFrame(x)
Definition: ke.h:177
#define KiServiceExit2
Definition: ke.h:5
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)
DECLSPEC_NORETURN VOID FASTCALL KiServiceExit(IN PKTRAP_FRAME TrapFrame, IN NTSTATUS Status)
Definition: traphdlr.c:150
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, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame)
Definition: except.c:20
NTSTATUS NTAPI NtContinue(IN PCONTEXT Context, IN BOOLEAN TestAlert)
Definition: except.c:220
NTSTATUS NTAPI KiRaiseException(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame, IN BOOLEAN SearchFrames)
Definition: except.c:97
NTSTATUS NTAPI NtRaiseException(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context, IN BOOLEAN FirstChance)
Definition: except.c:179
NTSTATUS NTAPI KiContinue(IN PCONTEXT Context, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame)
Definition: except.c:45
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
#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