ReactOS  0.4.14-dev-77-gd9e7c48
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 
18 VOID
19 NTAPI
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  /* Convert the context into Exception/Trap Frames */
32  KeContextToTrapFrame(&LocalContext,
33  ExceptionFrame,
34  TrapFrame,
35  LocalContext.ContextFlags,
36  UserMode);
37 }
38 
40 NTAPI
42  IN PKEXCEPTION_FRAME ExceptionFrame,
43  IN PKTRAP_FRAME TrapFrame)
44 {
48 
49  /* Raise to APC_LEVEL, only if needed */
51 
52  /* Set up SEH to validate the context */
53  _SEH2_TRY
54  {
55  /* Check the previous mode */
56  if (PreviousMode != KernelMode)
57  {
58  /* Validate from user-mode */
60  ExceptionFrame,
61  TrapFrame);
62  }
63  else
64  {
65  /* Convert the context into Exception/Trap Frames */
67  ExceptionFrame,
68  TrapFrame,
69  Context->ContextFlags,
70  KernelMode);
71  }
72  }
74  {
75  /* Save the exception code */
77  }
78  _SEH2_END;
79 
80  /* Lower the IRQL if needed */
82 
83  /* Return status */
84  return Status;
85 }
86 
88 NTAPI
91  IN PKEXCEPTION_FRAME ExceptionFrame,
92  IN PKTRAP_FRAME TrapFrame,
93  IN BOOLEAN SearchFrames)
94 {
96  CONTEXT LocalContext;
97  EXCEPTION_RECORD LocalExceptionRecord;
98  ULONG ParameterCount, Size;
99 
100  /* Check if we need to probe */
101  if (PreviousMode != KernelMode)
102  {
103  /* Set up SEH */
104  _SEH2_TRY
105  {
106  /* Probe the context */
107  ProbeForRead(Context, sizeof(CONTEXT), sizeof(ULONG));
108 
109  /* Probe the Exception Record */
110  ProbeForRead(ExceptionRecord,
111  FIELD_OFFSET(EXCEPTION_RECORD, NumberParameters) +
112  sizeof(ULONG),
113  sizeof(ULONG));
114 
115  /* Validate the maximum parameters */
116  if ((ParameterCount = ExceptionRecord->NumberParameters) >
118  {
119  /* Too large */
121  }
122 
123  /* Probe the entire parameters now*/
124  Size = (sizeof(EXCEPTION_RECORD) -
125  ((EXCEPTION_MAXIMUM_PARAMETERS - ParameterCount) * sizeof(ULONG)));
126  ProbeForRead(ExceptionRecord, Size, sizeof(ULONG));
127 
128  /* Now make copies in the stack */
129  RtlCopyMemory(&LocalContext, Context, sizeof(CONTEXT));
130  RtlCopyMemory(&LocalExceptionRecord, ExceptionRecord, Size);
131  Context = &LocalContext;
132  ExceptionRecord = &LocalExceptionRecord;
133 
134  /* Update the parameter count */
135  ExceptionRecord->NumberParameters = ParameterCount;
136  }
138  {
139  /* Don't fail silently */
140  DPRINT1("KiRaiseException: Failed to Probe\n");
141 
142  /* Return the exception code */
144  }
145  _SEH2_END;
146  }
147 
148  /* Convert the context record */
150  ExceptionFrame,
151  TrapFrame,
152  Context->ContextFlags,
153  PreviousMode);
154 
155  /* Dispatch the exception */
156  ExceptionRecord->ExceptionCode &= ~KI_EXCEPTION_INTERNAL;
157  KiDispatchException(ExceptionRecord,
158  ExceptionFrame,
159  TrapFrame,
160  PreviousMode,
161  SearchFrames);
162 
163  /* We are done */
164  return STATUS_SUCCESS;
165 }
166 
167 /* SYSTEM CALLS ***************************************************************/
168 
169 NTSTATUS
170 NTAPI
173  IN BOOLEAN FirstChance)
174 {
177  PKTRAP_FRAME TrapFrame;
178 
179  /* Get trap frame and link previous one*/
181  TrapFrame = Thread->TrapFrame;
182  Thread->TrapFrame = KiGetLinkedTrapFrame(TrapFrame);
183 
184  /* Set exception list */
185 #ifdef _M_IX86
186  KeGetPcr()->NtTib.ExceptionList = TrapFrame->ExceptionList;
187 #endif
188 
189  /* Raise the exception */
190  Status = KiRaiseException(ExceptionRecord,
191  Context,
192  NULL,
193  TrapFrame,
194  FirstChance);
195  if (NT_SUCCESS(Status))
196  {
197  /* It was handled, so exit restoring all state */
198  KiServiceExit2(TrapFrame);
199  }
200  else
201  {
202  /* Exit with error */
203  KiServiceExit(TrapFrame, Status);
204  }
205 
206  /* We don't actually make it here */
207  return Status;
208 }
209 
210 NTSTATUS
211 NTAPI
213  IN BOOLEAN TestAlert)
214 {
217  PKTRAP_FRAME TrapFrame;
218 
219  /* Get trap frame and link previous one*/
221  TrapFrame = Thread->TrapFrame;
222  Thread->TrapFrame = KiGetLinkedTrapFrame(TrapFrame);
223 
224  /* Continue from this point on */
225  Status = KiContinue(Context, NULL, TrapFrame);
226  if (NT_SUCCESS(Status))
227  {
228  /* Check if alert was requested */
229  if (TestAlert) KeTestAlertThread(Thread->PreviousMode);
230 
231  /* Exit to new trap frame */
232  KiServiceExit2(TrapFrame);
233  }
234  else
235  {
236  /* Exit with an error */
237  KiServiceExit(TrapFrame, Status);
238  }
239 
240  /* We don't actually make it here */
241  return Status;
242 }
243 
244 /* EOF */
VOID NTAPI KeContextToTrapFrame(PCONTEXT Context, PKEXCEPTION_FRAME ExeptionFrame, PKTRAP_FRAME TrapFrame, ULONG ContextFlags, KPROCESSOR_MODE PreviousMode)
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define IN
Definition: typedefs.h:38
NTSTATUS NTAPI KiContinue(IN PCONTEXT Context, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame)
Definition: except.c:41
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define KeGetPreviousMode()
Definition: ketypes.h:1107
LONG NTSTATUS
Definition: precomp.h:26
#define EXCEPTION_MAXIMUM_PARAMETERS
Definition: compat.h:194
#define KeGetPcr()
Definition: ke.h:25
_SEH2_TRY
Definition: create.c:4250
UCHAR KIRQL
Definition: env_spec_w32.h:591
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
NTSTATUS NTAPI NtContinue(IN PCONTEXT Context, IN BOOLEAN TestAlert)
Definition: except.c:212
struct _EXCEPTION_RECORD EXCEPTION_RECORD
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI NtRaiseException(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context, IN BOOLEAN FirstChance)
Definition: except.c:171
ULONG ContextFlags
Definition: compat.h:331
DECLSPEC_NORETURN VOID FASTCALL KiServiceExit(IN PKTRAP_FRAME TrapFrame, IN NTSTATUS Status)
Definition: traphdlr.c:150
VOID NTAPI KiContinuePreviousModeUser(IN PCONTEXT Context, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame)
Definition: except.c:20
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define KI_EXCEPTION_INTERNAL
Definition: ketypes.h:176
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
struct _EXCEPTION_REGISTRATION_RECORD FAR * ExceptionList
Definition: ketypes.h:260
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
NTSTATUS NTAPI KiRaiseException(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame, IN BOOLEAN SearchFrames)
Definition: except.c:89
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
Status
Definition: gdiplustypes.h:24
_SEH2_END
Definition: create.c:4424
#define KiGetLinkedTrapFrame(x)
Definition: ke.h:133
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define KiServiceExit2
Definition: ke.h:5
#define DPRINT1
Definition: precomp.h:8
BOOLEAN NTAPI KeTestAlertThread(IN KPROCESSOR_MODE AlertMode)
Definition: thrdobj.c:731
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:237
unsigned int ULONG
Definition: retypes.h:1
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
DWORD NumberParameters
Definition: compat.h:200
#define KeGetCurrentThread
Definition: hal.h:44
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define APC_LEVEL
Definition: env_spec_w32.h:695