ReactOS  r76032
usercall.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: ntoskrnl/ke/i386/usercall.c
5  * PURPOSE: User-mode Callout Mechanisms (APC and Win32K Callbacks)
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  * Timo Kreuzer (timo.kreuzer@reactos.org)
8  */
9 
10 /* INCLUDES ******************************************************************/
11 
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <debug.h>
15 
17 
18 /* PRIVATE FUNCTIONS *********************************************************/
19 
20 /*++
21  * @name KiInitializeUserApc
22  *
23  * Prepares the Context for a User-Mode APC called through NTDLL.DLL
24  *
25  * @param Reserved
26  * Pointer to the Exception Frame on non-i386 builds.
27  *
28  * @param TrapFrame
29  * Pointer to the Trap Frame.
30  *
31  * @param NormalRoutine
32  * Pointer to the NormalRoutine to call.
33  *
34  * @param NormalContext
35  * Pointer to the context to send to the Normal Routine.
36  *
37  * @param SystemArgument[1-2]
38  * Pointer to a set of two parameters that contain untyped data.
39  *
40  * @return None.
41  *
42  * @remarks None.
43  *
44  *--*/
45 VOID
46 NTAPI
48  IN PKTRAP_FRAME TrapFrame,
49  IN PKNORMAL_ROUTINE NormalRoutine,
50  IN PVOID NormalContext,
53 {
55  ULONG_PTR Stack, AlignedEsp;
56  ULONG ContextLength;
57  EXCEPTION_RECORD SehExceptRecord;
58 
59  /* Don't deliver APCs in V86 mode */
60  if (TrapFrame->EFlags & EFLAGS_V86_MASK) return;
61 
62  /* Save the full context */
64  KeTrapFrameToContext(TrapFrame, ExceptionFrame, &Context);
65 
66  /* Protect with SEH */
67  _SEH2_TRY
68  {
69  /* Sanity check */
70  ASSERT(KiUserTrap(TrapFrame));
71 
72  /* Get the aligned size */
73  AlignedEsp = Context.Esp & ~3;
74  ContextLength = CONTEXT_ALIGNED_SIZE + (4 * sizeof(ULONG_PTR));
75  Stack = ((AlignedEsp - 8) & ~3) - ContextLength;
76 
77  /* Probe the stack */
78  ProbeForWrite((PVOID)Stack, AlignedEsp - Stack, 1);
79  ASSERT(!(Stack & 3));
80 
81  /* Copy data into it */
82  RtlCopyMemory((PVOID)(Stack + (4 * sizeof(ULONG_PTR))),
83  &Context,
84  sizeof(CONTEXT));
85 
86  /* Run at APC dispatcher */
87  TrapFrame->Eip = (ULONG)KeUserApcDispatcher;
88  TrapFrame->HardwareEsp = Stack;
89 
90  /* Setup Ring 3 state */
91  TrapFrame->SegCs = Ke386SanitizeSeg(KGDT_R3_CODE, UserMode);
92  TrapFrame->HardwareSegSs = Ke386SanitizeSeg(KGDT_R3_DATA, UserMode);
93  TrapFrame->SegDs = Ke386SanitizeSeg(KGDT_R3_DATA, UserMode);
94  TrapFrame->SegEs = Ke386SanitizeSeg(KGDT_R3_DATA, UserMode);
95  TrapFrame->SegFs = Ke386SanitizeSeg(KGDT_R3_TEB, UserMode);
96  TrapFrame->SegGs = 0;
97  TrapFrame->ErrCode = 0;
98 
99  /* Sanitize EFLAGS */
100  TrapFrame->EFlags = Ke386SanitizeFlags(Context.EFlags, UserMode);
101 
102  /* Check if thread has IOPL and force it enabled if so */
103  if (KeGetCurrentThread()->Iopl) TrapFrame->EFlags |= EFLAGS_IOPL;
104 
105  /* Setup the stack */
106  *(PULONG_PTR)(Stack + 0 * sizeof(ULONG_PTR)) = (ULONG_PTR)NormalRoutine;
107  *(PULONG_PTR)(Stack + 1 * sizeof(ULONG_PTR)) = (ULONG_PTR)NormalContext;
108  *(PULONG_PTR)(Stack + 2 * sizeof(ULONG_PTR)) = (ULONG_PTR)SystemArgument1;
109  *(PULONG_PTR)(Stack + 3 * sizeof(ULONG_PTR)) = (ULONG_PTR)SystemArgument2;
110  }
112  {
113  /* Dispatch the exception */
114  SehExceptRecord.ExceptionAddress = (PVOID)TrapFrame->Eip;
115  KiDispatchException(&SehExceptRecord,
116  ExceptionFrame,
117  TrapFrame,
118  UserMode,
119  TRUE);
120  }
121  _SEH2_END;
122 }
123 
124 /* PUBLIC FUNCTIONS **********************************************************/
125 
126 /*
127  * @implemented
128  */
129 NTSTATUS
130 NTAPI
132  IN PVOID Argument,
133  IN ULONG ArgumentLength,
134  OUT PVOID *Result,
136 {
137  ULONG_PTR NewStack, OldStack;
138  PULONG UserEsp;
140  PEXCEPTION_REGISTRATION_RECORD ExceptionList;
141  PTEB Teb;
142  ULONG GdiBatchCount = 0;
143  ASSERT(KeGetCurrentThread()->ApcState.KernelApcInProgress == FALSE);
145 
146  /* Get the current user-mode stack */
147  UserEsp = KiGetUserModeStackAddress();
148  OldStack = *UserEsp;
149 
150  /* Enter a SEH Block */
151  _SEH2_TRY
152  {
153  /* Calculate and align the stack size */
154  NewStack = (OldStack - ArgumentLength) & ~3;
155 
156  /* Make sure it's writable */
157  ProbeForWrite((PVOID)(NewStack - 6 * sizeof(ULONG_PTR)),
158  ArgumentLength + 6 * sizeof(ULONG_PTR),
159  sizeof(CHAR));
160 
161  /* Copy the buffer into the stack */
162  RtlCopyMemory((PVOID)NewStack, Argument, ArgumentLength);
163 
164  /* Write the arguments */
165  NewStack -= 24;
166  *(PULONG)NewStack = 0;
167  *(PULONG)(NewStack + 4) = RoutineIndex;
168  *(PULONG)(NewStack + 8) = (NewStack + 24);
169  *(PULONG)(NewStack + 12) = ArgumentLength;
170 
171  /* Save the exception list */
172  Teb = KeGetCurrentThread()->Teb;
173  ExceptionList = Teb->NtTib.ExceptionList;
174 
175  /* Jump to user mode */
176  *UserEsp = NewStack;
177  CallbackStatus = KiCallUserMode(Result, ResultLength);
178  if (CallbackStatus != STATUS_CALLBACK_POP_STACK)
179  {
180  /* Only restore the exception list if we didn't crash in ring 3 */
181  Teb->NtTib.ExceptionList = ExceptionList;
182  }
183  else
184  {
185  /* Otherwise, pop the stack */
186  OldStack = *UserEsp;
187  }
188 
189  /* Read the GDI Batch count */
190  GdiBatchCount = Teb->GdiBatchCount;
191  }
193  {
194  /* Get the SEH exception */
196  }
197  _SEH2_END;
198 
199  /* Check if we have GDI Batch operations */
200  if (GdiBatchCount)
201  {
202  *UserEsp -= 256;
204  }
205 
206  /* Restore stack and return */
207  *UserEsp = OldStack;
208  return CallbackStatus;
209 }
210 
211 
212 /*
213  * Stack layout for KiUserModeCallout:
214  * ----------------------------------
215  * KCALLOUT_FRAME.ResultLength <= 2nd Parameter to KiCallUserMode
216  * KCALLOUT_FRAME.Result <= 1st Parameter to KiCallUserMode
217  * KCALLOUT_FRAME.ReturnAddress <= Return address of KiCallUserMode
218  * KCALLOUT_FRAME.Ebp \
219  * KCALLOUT_FRAME.Ebx | = non-volatile registers, pushed
220  * KCALLOUT_FRAME.Esi | by KiCallUserMode
221  * KCALLOUT_FRAME.Edi /
222  * KCALLOUT_FRAME.CallbackStack
223  * KCALLOUT_FRAME.TrapFrame
224  * KCALLOUT_FRAME.InitialStack <= CalloutFrame points here
225  * ----------------------------------
226  * ~~ optional alignment ~~
227  * ----------------------------------
228  * FX_SAVE_AREA
229  * ----------------------------------
230  * KTRAP_FRAME
231  * ----------------------------------
232  * ~~ begin of stack frame for KiUserModeCallout ~~
233  *
234  */
235 
236 NTSTATUS
237 FASTCALL
239 {
240  PKTHREAD CurrentThread;
241  PKTRAP_FRAME TrapFrame, CallbackTrapFrame;
242  PFX_SAVE_AREA FxSaveArea, OldFxSaveArea;
243  PKPCR Pcr;
244  PKTSS Tss;
245  ULONG_PTR InitialStack;
247 
248  /* Get the current thread */
249  CurrentThread = KeGetCurrentThread();
250 
251 #if DBG
252  /* Check if we are at pasive level */
254  {
255  /* We're not, bugcheck */
256  KeBugCheckEx(IRQL_GT_ZERO_AT_SYSTEM_SERVICE,
257  0,
259  0,
260  0);
261  }
262 
263  /* Check if we are attached or APCs are disabled */
264  if ((CurrentThread->ApcStateIndex != OriginalApcEnvironment) ||
265  (CurrentThread->CombinedApcDisable > 0))
266  {
267  KeBugCheckEx(APC_INDEX_MISMATCH,
268  0,
269  CurrentThread->ApcStateIndex,
270  CurrentThread->CombinedApcDisable,
271  0);
272  }
273 #endif
274 
275  /* Align stack on a 16-byte boundary */
276  InitialStack = ALIGN_DOWN_BY(CalloutFrame, 16);
277 
278  /* Check if we have enough space on the stack */
279  if ((InitialStack - KERNEL_STACK_SIZE) < CurrentThread->StackLimit)
280  {
281  /* We don't, we'll have to grow our stack */
282  Status = MmGrowKernelStack((PVOID)InitialStack);
283 
284  /* Quit if we failed */
285  if (!NT_SUCCESS(Status)) return Status;
286  }
287 
288  /* Save the current callback stack and initial stack */
289  CalloutFrame->CallbackStack = (ULONG_PTR)CurrentThread->CallbackStack;
290  CalloutFrame->InitialStack = (ULONG_PTR)CurrentThread->InitialStack;
291 
292  /* Get and save the trap frame */
293  TrapFrame = CurrentThread->TrapFrame;
294  CalloutFrame->TrapFrame = (ULONG_PTR)TrapFrame;
295 
296  /* Set the new callback stack */
297  CurrentThread->CallbackStack = CalloutFrame;
298 
299  /* Set destination and origin NPX Areas */
300  OldFxSaveArea = (PVOID)(CalloutFrame->InitialStack - sizeof(FX_SAVE_AREA));
301  FxSaveArea = (PVOID)(InitialStack - sizeof(FX_SAVE_AREA));
302 
303  /* Disable interrupts so we can fill the NPX State */
304  _disable();
305 
306  /* Now copy the NPX State */
307  FxSaveArea->U.FnArea.ControlWord = OldFxSaveArea->U.FnArea.ControlWord;
308  FxSaveArea->U.FnArea.StatusWord = OldFxSaveArea->U.FnArea.StatusWord;
309  FxSaveArea->U.FnArea.TagWord = OldFxSaveArea->U.FnArea.TagWord;
310  FxSaveArea->U.FnArea.DataSelector = OldFxSaveArea->U.FnArea.DataSelector;
311  FxSaveArea->Cr0NpxState = OldFxSaveArea->Cr0NpxState;
312 
313  /* Set the stack address */
314  CurrentThread->InitialStack = (PVOID)InitialStack;
315 
316  /* Locate the trap frame on the callback stack */
317  CallbackTrapFrame = (PVOID)((ULONG_PTR)FxSaveArea - sizeof(KTRAP_FRAME));
318 
319  /* Copy the trap frame to the new location */
320  *CallbackTrapFrame = *TrapFrame;
321 
322  /* Get PCR */
323  Pcr = KeGetPcr();
324 
325  /* Update the exception list */
326  CallbackTrapFrame->ExceptionList = Pcr->NtTib.ExceptionList;
327 
328  /* Get TSS */
329  Tss = Pcr->TSS;
330 
331  /* Check for V86 mode */
332  if (CallbackTrapFrame->EFlags & EFLAGS_V86_MASK)
333  {
334  /* Set new stack address in TSS (full trap frame) */
335  Tss->Esp0 = (ULONG_PTR)(CallbackTrapFrame + 1);
336  }
337  else
338  {
339  /* Set new stack address in TSS (non-V86 trap frame) */
340  Tss->Esp0 = (ULONG_PTR)&CallbackTrapFrame->V86Es;
341  }
342 
343  /* Set user-mode dispatcher address as EIP */
344  CallbackTrapFrame->Eip = (ULONG_PTR)KeUserCallbackDispatcher;
345 
346  /* Bring interrupts back */
347  _enable();
348 
349  /* Exit to user-mode */
350  KiServiceExit(CallbackTrapFrame, 0);
351 }
352 
353 /*++
354  * @name NtCallbackReturn
355  *
356  * The NtCallbackReturn routine returns to kernel mode after a user-mode
357  * callback was done through KeUserModeCallback. It uses the callback frame
358  * which was setup in order to return the information, restores the stack,
359  * and resumes execution where it was left off.
360  *
361  * @param Result
362  * Pointer to a caller-allocated buffer where the return data
363  * from the user-mode function is located.
364  *
365  * @param ResultLength
366  * Size of the Output Buffer described above.
367  *
368  * @param CallbackStatus
369  * Status code of the callback operation.
370  *
371  * @return Status code of the callback operation.
372  *
373  * @remark This call MUST be paired with KeUserModeCallback.
374  *
375  *--*/
376 NTSTATUS
377 NTAPI
379  _In_ PVOID Result,
382 {
383  PKTHREAD CurrentThread;
384  PKCALLOUT_FRAME CalloutFrame;
385  PKTRAP_FRAME CallbackTrapFrame, TrapFrame;
386  PFX_SAVE_AREA FxSaveArea, CbFxSaveArea;
387  ULONG Size;
388  PKPCR Pcr;
389  PKTSS Tss;
390 
391  /* Get the current thread and make sure we have a callback stack */
392  CurrentThread = KeGetCurrentThread();
393  CalloutFrame = CurrentThread->CallbackStack;
394  if (CalloutFrame == NULL)
395  {
397  }
398 
399  /* Get the trap frame */
400  CallbackTrapFrame = CurrentThread->TrapFrame;
401 
402  /* Restore the exception list */
403  Pcr = KeGetPcr();
404  Pcr->NtTib.ExceptionList = CallbackTrapFrame->ExceptionList;
405 
406  /* Store the results in the callback stack */
407  *((PVOID*)CalloutFrame->Result) = Result;
408  *((ULONG*)CalloutFrame->ResultLength) = ResultLength;
409 
410  /* Disable interrupts for NPX save and stack switch */
411  _disable();
412 
413  /* Set desination and origin NPX Frames */
414  CbFxSaveArea = (PVOID)((ULONG)CurrentThread->InitialStack - sizeof(FX_SAVE_AREA));
415  FxSaveArea = (PVOID)(CalloutFrame->InitialStack - sizeof(FX_SAVE_AREA));
416 
417  /* Now copy back NPX State */
418  FxSaveArea->U.FnArea.ControlWord = CbFxSaveArea->U.FnArea.ControlWord;
419  FxSaveArea->U.FnArea.StatusWord = CbFxSaveArea->U.FnArea.StatusWord;
420  FxSaveArea->U.FnArea.TagWord = CbFxSaveArea->U.FnArea.TagWord;
421  FxSaveArea->U.FnArea.DataSelector = CbFxSaveArea->U.FnArea.DataSelector;
422  FxSaveArea->Cr0NpxState = CbFxSaveArea->Cr0NpxState;
423 
424  /* Get the previous trap frame */
425  TrapFrame = (PKTRAP_FRAME)CalloutFrame->TrapFrame;
426 
427  /* Check if we failed in user mode */
428  if (CallbackStatus == STATUS_CALLBACK_POP_STACK)
429  {
430  /* Check if we came from v86 mode */
431  if (CallbackTrapFrame->EFlags & EFLAGS_V86_MASK)
432  {
433  Size = sizeof(KTRAP_FRAME) - FIELD_OFFSET(KTRAP_FRAME, SegFs);
434  }
435  else
436  {
437  Size = FIELD_OFFSET(KTRAP_FRAME, V86Es) - FIELD_OFFSET(KTRAP_FRAME, SegFs);
438  }
439 
440  /* Copy back part of the trap frame */
441  RtlCopyMemory(&TrapFrame->SegFs, &CallbackTrapFrame->SegFs, Size);
442  }
443 
444  /* Clear DR7 */
445  TrapFrame->Dr7 = 0;
446 
447  /* Check if debugging was active */
448  if (CurrentThread->Header.DebugActive & 0xFF)
449  {
450  /* Copy debug registers data from it */
451  TrapFrame->Dr0 = CallbackTrapFrame->Dr0;
452  TrapFrame->Dr1 = CallbackTrapFrame->Dr1;
453  TrapFrame->Dr2 = CallbackTrapFrame->Dr2;
454  TrapFrame->Dr3 = CallbackTrapFrame->Dr3;
455  TrapFrame->Dr6 = CallbackTrapFrame->Dr6;
456  TrapFrame->Dr7 = CallbackTrapFrame->Dr7;
457  }
458 
459  /* Get TSS */
460  Tss = Pcr->TSS;
461 
462  /* Check for V86 mode */
463  if (TrapFrame->EFlags & EFLAGS_V86_MASK)
464  {
465  /* Set new stack address in TSS (full trap frame) */
466  Tss->Esp0 = (ULONG_PTR)(TrapFrame + 1);
467  }
468  else
469  {
470  /* Set new stack address in TSS (non-V86 trap frame) */
471  Tss->Esp0 = (ULONG_PTR)&TrapFrame->V86Es;
472  }
473 
474  /* Get the initial stack and restore it */
475  CurrentThread->InitialStack = (PVOID)CalloutFrame->InitialStack;
476 
477  /* Restore the trap frame and the previous callback stack */
478  CurrentThread->TrapFrame = TrapFrame;
479  CurrentThread->CallbackStack = (PVOID)CalloutFrame->CallbackStack;
480 
481  /* Bring interrupts back */
482  _enable();
483 
484  /* Now switch back to the old stack */
485  KiCallbackReturn(&CalloutFrame->Edi, CallbackStatus);
486 }
487 
488 
489 /* EOF */
DWORD *typedef PVOID
Definition: winlogon.h:52
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
ULONG DataSelector
Definition: ketypes.h:419
ULONG Esp
Definition: nt_native.h:1479
ULONG V86Es
Definition: ketypes.h:270
PVOID KeUserApcDispatcher
Definition: ke.h:130
NTSTATUS NTAPI NtCallbackReturn(_In_ PVOID Result, _In_ ULONG ResultLength, _In_ NTSTATUS CallbackStatus)
Definition: usercall.c:331
ULONG CombinedApcDisable
Definition: ketypes.h:1054
#define STATUS_CALLBACK_POP_STACK
Definition: ntstatus.h:947
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
ULONG TagWord
Definition: ketypes.h:415
char CHAR
Definition: xmlstorage.h:175
FORCEINLINE ULONG Ke386SanitizeFlags(IN ULONG Eflags, IN KPROCESSOR_MODE Mode)
Definition: ke.h:610
void __cdecl _enable(void)
Definition: intrin_arm.h:373
#define KeGetPreviousMode()
Definition: ketypes.h:1081
USHORT SegFs
Definition: ketypes.h:366
PVOID CallbackStack
Definition: ketypes.h:1186
PKTRAP_FRAME TrapFrame
Definition: ketypes.h:1181
ULONG64 TrapFrame
Definition: ketypes.h:944
NTSTATUS NTAPI KeUserModeCallback(IN ULONG RoutineIndex, IN PVOID Argument, IN ULONG ArgumentLength, OUT PVOID *Result, OUT PULONG ResultLength)
Definition: usercall.c:309
Definition: ke.h:280
#define CONTEXT_FULL
Definition: compat.h:270
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
#define FASTCALL
Definition: nt_native.h:50
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define KeGetPcr()
Definition: ke.h:25
PVOID ExceptionAddress
Definition: compat.h:199
#define EFLAGS_V86_MASK
Definition: ketypes.h:129
ULONG_PTR StackLimit
Definition: ketypes.h:938
uint32_t ULONG_PTR
Definition: typedefs.h:63
struct _KTRAP_FRAME KTRAP_FRAME
PVOID KeUserCallbackDispatcher
Definition: ke.h:131
union _FX_SAVE_AREA::@2175 U
UINT64 Dr2
Definition: ketypes.h:344
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
VOID NTAPI KiDispatchException(PEXCEPTION_RECORD ExceptionRecord, PKEXCEPTION_FRAME ExceptionFrame, PKTRAP_FRAME Tf, KPROCESSOR_MODE PreviousMode, BOOLEAN SearchFrames)
#define _SEH2_END
Definition: pseh2_64.h:7
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:557
Definition: ketypes.h:787
ULONG Cr0NpxState
Definition: ketypes.h:449
#define KGDT_R3_DATA
Definition: ketypes.h:77
ULONG EFlags
Definition: nt_native.h:1478
VOID NTAPI KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN OUT PCONTEXT Context)
Definition: context.c:146
NTSTATUS NTAPI MmGrowKernelStack(IN PVOID StackPointer)
Definition: procsup.c:461
ULONG ContextFlags
Definition: compat.h:331
UINTN Size
Definition: acefiex.h:555
DECLSPEC_NORETURN VOID FASTCALL KiServiceExit(IN PKTRAP_FRAME TrapFrame, IN NTSTATUS Status)
Definition: traphdlr.c:150
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:660
PGDI_BATCHFLUSH_ROUTINE KeGdiFlushUserBatch
Definition: win32.c:20
struct _FX_SAVE_AREA FX_SAVE_AREA
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
if(!(yy_init))
Definition: macro.lex.yy.c:704
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
VOID NTAPI KiInitializeUserApc(IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame, IN PKNORMAL_ROUTINE NormalRoutine, IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: usercall.c:266
#define CONTEXT_ALIGNED_SIZE
Definition: asm.h:362
struct _EXCEPTION_REGISTRATION_RECORD * ExceptionList
Definition: compat.h:371
UINT64 Dr6
Definition: ketypes.h:346
#define KGDT_R3_TEB
Definition: ketypes.h:80
VOID(NTAPI * PKNORMAL_ROUTINE)(IN PVOID NormalContext OPTIONAL, IN PVOID SystemArgument1 OPTIONAL, IN PVOID SystemArgument2 OPTIONAL)
Definition: ketypes.h:632
struct _EXCEPTION_REGISTRATION_RECORD FAR * ExceptionList
Definition: ketypes.h:258
#define KERNEL_STACK_SIZE
UINT64 Dr3
Definition: ketypes.h:345
ULONG ControlWord
Definition: ketypes.h:413
_In_ FLT_PREOP_CALLBACK_STATUS CallbackStatus
Definition: fltkernel.h:1020
UINT64 Dr1
Definition: ketypes.h:343
#define EFLAGS_IOPL
Definition: cpu.c:17
ULONG GdiBatchCount
Definition: compat.h:536
NT_TIB NtTib
Definition: ke.h:284
BOOLEAN DebugActive
Definition: ketypes.h:766
DECLSPEC_NORETURN VOID FASTCALL KiCallbackReturn(IN PVOID Stack, IN NTSTATUS Status)
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
ULONG Eip
Definition: ketypes.h:265
UINT64 Dr0
Definition: ketypes.h:342
FORCEINLINE PULONG KiGetUserModeStackAddress(void)
Definition: ke.h:887
FORCEINLINE ULONG Ke386SanitizeSeg(IN ULONG Cs, IN KPROCESSOR_MODE Mode)
Definition: ke.h:593
Status
Definition: gdiplustypes.h:24
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:660
#define ALIGN_DOWN_BY(size, align)
#define _In_
Definition: no_sal2.h:204
ULONG StatusWord
Definition: ketypes.h:414
#define STATUS_NO_CALLBACK_ACTIVE
Definition: ntstatus.h:712
struct _KTSS * TSS
Definition: ke.h:54
Definition: compat.h:484
LONG NTSTATUS
Definition: DriverTester.h:11
ULONG Esp0
Definition: ketypes.h:791
#define _SEH2_TRY
Definition: pseh2_64.h:5
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1411
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS(NTAPI * PGDI_BATCHFLUSH_ROUTINE)(VOID)
Definition: pstypes.h:547
FNSAVE_FORMAT FnArea
Definition: ketypes.h:445
DISPATCHER_HEADER Header
Definition: ketypes.h:927
#define KGDT_R3_CODE
Definition: ketypes.h:76
#define OUT
Definition: typedefs.h:39
void __cdecl _disable(void)
Definition: intrin_arm.h:365
struct tagContext Context
Definition: acpixf.h:1014
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
uint32_t * PULONG_PTR
Definition: typedefs.h:63
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
UCHAR ApcStateIndex
Definition: ketypes.h:1198
struct _KTRAP_FRAME * PKTRAP_FRAME
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
UINT64 Dr7
Definition: ketypes.h:347
#define KeGetCurrentThread
Definition: hal.h:44
PVOID InitialStack
Definition: ketypes.h:937
NTSTATUS NTAPI KiCallUserMode(IN PVOID *OutputBuffer, IN PULONG OutputLength)
Definition: usercall.c:321
NT_TIB NtTib
Definition: ntddk_ex.h:336
NTSTATUS FASTCALL KiUserModeCallout(PKCALLOUT_FRAME CalloutFrame)
Definition: usercall.c:238
ULONG EFlags
Definition: ketypes.h:384
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:90
#define CONTEXT_DEBUG_REGISTERS
Definition: compat.h:268
BOOLEAN FORCEINLINE KiUserTrap(IN PKTRAP_FRAME TrapFrame)
Definition: ke.h:281