ReactOS  r76032
traphdlr.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/i386/traphdlr.c
5  * PURPOSE: Kernel Trap Handlers
6  * PROGRAMMERS: ReactOS Portable Systems Group
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14 
17 
20 extern PVOID FrRestore;
22 
23 /* GLOBALS ********************************************************************/
24 
26 {
27  0xF2, /* REP */
28  0xF3, /* REP INS/OUTS */
29  0x67, /* ADDR */
30  0xF0, /* LOCK */
31  0x66, /* OP */
32  0x2E, /* SEG */
33  0x3E, /* DS */
34  0x26, /* ES */
35  0x64, /* FS */
36  0x65, /* GS */
37  0x36, /* SS */
38 };
39 
41 {
42  0xE4, /* IN */
43  0xE5, /* IN */
44  0xEC, /* IN */
45  0xED, /* IN */
46  0x6C, /* INS */
47  0x6D, /* INS */
48  0xE6, /* OUT */
49  0xE7, /* OUT */
50  0xEE, /* OUT */
51  0xEF, /* OUT */
52  0x6E, /* OUTS */
53  0x6F, /* OUTS */
54 };
55 
57 #if DBG && defined(_M_IX86) && !defined(_WINKD_)
58 PKDBG_PRESERVICEHOOK KeWin32PreServiceHook = NULL;
59 PKDBG_POSTSERVICEHOOK KeWin32PostServiceHook = NULL;
60 #endif
61 #if DBG
62 BOOLEAN StopChecking = FALSE;
63 #endif
64 
65 
66 /* TRAP EXIT CODE *************************************************************/
67 
69 BOOLEAN
71 {
72  /* Either the V8086 flag is on, or this is user-mode with a VDM */
73  return ((TrapFrame->EFlags & EFLAGS_V86_MASK) ||
74  ((KiUserTrap(TrapFrame)) && (PsGetCurrentProcess()->VdmObjects)));
75 }
76 
78 BOOLEAN
80 {
81  /* Check if the V8086 flag is on */
82  return ((TrapFrame->EFlags & EFLAGS_V86_MASK) != 0);
83 }
84 
86 BOOLEAN
88 {
89  /* An edited frame changes esp. It is marked by clearing the bits
90  defined by FRAME_EDITED in the SegCs field of the trap frame */
91  return ((TrapFrame->SegCs & FRAME_EDITED) == 0);
92 }
93 
95 VOID
96 KiCommonExit(IN PKTRAP_FRAME TrapFrame, BOOLEAN SkipPreviousMode)
97 {
98  /* Disable interrupts until we return */
99  _disable();
100 
101  /* Check for APC delivery */
102  KiCheckForApcDelivery(TrapFrame);
103 
104  /* Restore the SEH handler chain */
105  KeGetPcr()->NtTib.ExceptionList = TrapFrame->ExceptionList;
106 
107  /* Check if there are active debug registers */
108  if (__builtin_expect(TrapFrame->Dr7 & ~DR7_RESERVED_MASK, 0))
109  {
110  /* Check if the frame was from user mode or v86 mode */
111  if (KiUserTrap(TrapFrame) ||
112  (TrapFrame->EFlags & EFLAGS_V86_MASK))
113  {
114  /* Handle debug registers */
116  }
117  }
118 
119  /* Debugging checks */
120  KiExitTrapDebugChecks(TrapFrame, SkipPreviousMode);
121 }
122 
124 VOID
125 FASTCALL
127 {
128  /* Common trap exit code */
129  KiCommonExit(TrapFrame, TRUE);
130 
131  /* Check if this was a V8086 trap */
132  if (TrapFrame->EFlags & EFLAGS_V86_MASK) KiTrapReturnNoSegments(TrapFrame);
133 
134  /* Check for user mode exit */
135  if (KiUserTrap(TrapFrame)) KiTrapReturn(TrapFrame);
136 
137  /* Check for edited frame */
138  if (KiIsFrameEdited(TrapFrame)) KiEditedTrapReturn(TrapFrame);
139 
140  /* Check if we have single stepping enabled */
141  if (TrapFrame->EFlags & EFLAGS_TF) KiTrapReturnNoSegments(TrapFrame);
142 
143  /* Exit the trap to kernel mode */
144  KiTrapReturnNoSegmentsRet8(TrapFrame);
145 }
146 
148 VOID
149 FASTCALL
152 {
153  ASSERT((TrapFrame->EFlags & EFLAGS_V86_MASK) == 0);
154  ASSERT(!KiIsFrameEdited(TrapFrame));
155 
156  /* Copy the status into EAX */
157  TrapFrame->Eax = Status;
158 
159  /* Common trap exit code */
160  KiCommonExit(TrapFrame, FALSE);
161 
162  /* Restore previous mode */
163  KeGetCurrentThread()->PreviousMode = (CCHAR)TrapFrame->PreviousPreviousMode;
164 
165  /* Check for user mode exit */
166  if (KiUserTrap(TrapFrame))
167  {
168  /* Check if we were single stepping */
169  if (TrapFrame->EFlags & EFLAGS_TF)
170  {
171  /* Must use the IRET handler */
172  KiSystemCallTrapReturn(TrapFrame);
173  }
174  else
175  {
176  /* We can use the sysexit handler */
177  KiFastCallExitHandler(TrapFrame);
178  UNREACHABLE;
179  }
180  }
181 
182  /* Exit to kernel mode */
183  KiSystemCallReturn(TrapFrame);
184 }
185 
187 VOID
188 FASTCALL
190 {
191  /* Common trap exit code */
192  KiCommonExit(TrapFrame, FALSE);
193 
194  /* Restore previous mode */
195  KeGetCurrentThread()->PreviousMode = (CCHAR)TrapFrame->PreviousPreviousMode;
196 
197  /* Check if this was a V8086 trap */
198  if (TrapFrame->EFlags & EFLAGS_V86_MASK) KiTrapReturnNoSegments(TrapFrame);
199 
200  /* Check for user mode exit */
201  if (KiUserTrap(TrapFrame)) KiTrapReturn(TrapFrame);
202 
203  /* Check for edited frame */
204  if (KiIsFrameEdited(TrapFrame)) KiEditedTrapReturn(TrapFrame);
205 
206  /* Check if we have single stepping enabled */
207  if (TrapFrame->EFlags & EFLAGS_TF) KiTrapReturnNoSegments(TrapFrame);
208 
209  /* Exit the trap to kernel mode */
210  KiTrapReturnNoSegmentsRet8(TrapFrame);
211 }
212 
213 
214 /* TRAP HANDLERS **************************************************************/
215 
217 VOID
218 FASTCALL
220  IN ULONG Parameter1,
221  IN ULONG Parameter2,
222  IN ULONG Parameter3)
223 {
224  /* Check for VDM trap */
225  ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
226 
227  /* Enable interrupts if the trap came from user-mode */
228  if (KiUserTrap(TrapFrame)) _enable();
229 
230  /* Dispatch the exception */
232  0,
233  TrapFrame->Eip - 1,
234  3,
235  Parameter1,
236  Parameter2,
237  Parameter3,
238  TrapFrame);
239 }
240 
242 VOID
243 FASTCALL
246  IN PFX_SAVE_AREA SaveArea)
247 {
248  ULONG Cr0, Mask, Error, ErrorOffset, DataOffset;
249 
250  /* Check for VDM trap */
251  ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
252 
253  /* Check for kernel trap */
254  if (!KiUserTrap(TrapFrame))
255  {
256  /* Kernel might've tripped a delayed error */
257  SaveArea->Cr0NpxState |= CR0_TS;
258 
259  /* Only valid if it happened during a restore */
260  if ((PVOID)TrapFrame->Eip == FrRestore)
261  {
262  /* It did, so just skip the instruction */
263  TrapFrame->Eip += 3; /* Size of FRSTOR instruction */
264  KiEoiHelper(TrapFrame);
265  }
266  }
267 
268  /* User or kernel trap -- check if we need to unload the current state */
269  if (Thread->NpxState == NPX_STATE_LOADED)
270  {
271  /* Update CR0 */
272  Cr0 = __readcr0();
273  Cr0 &= ~(CR0_MP | CR0_EM | CR0_TS);
274  __writecr0(Cr0);
275 
276  /* Save FPU state */
277  Ke386SaveFpuState(SaveArea);
278 
279  /* Mark CR0 state dirty */
280  Cr0 |= NPX_STATE_NOT_LOADED;
281  Cr0 |= SaveArea->Cr0NpxState;
282  __writecr0(Cr0);
283 
284  /* Update NPX state */
285  Thread->NpxState = NPX_STATE_NOT_LOADED;
286  KeGetCurrentPrcb()->NpxThread = NULL;
287  }
288 
289  /* Clear the TS bit and re-enable interrupts */
290  SaveArea->Cr0NpxState &= ~CR0_TS;
291  _enable();
292 
293  /* Check if we should get the FN or FX error */
294  if (KeI386FxsrPresent)
295  {
296  /* Get it from FX */
297  Mask = SaveArea->U.FxArea.ControlWord;
298  Error = SaveArea->U.FxArea.StatusWord;
299 
300  /* Get the FPU exception address too */
301  ErrorOffset = SaveArea->U.FxArea.ErrorOffset;
302  DataOffset = SaveArea->U.FxArea.DataOffset;
303  }
304  else
305  {
306  /* Get it from FN */
307  Mask = SaveArea->U.FnArea.ControlWord;
308  Error = SaveArea->U.FnArea.StatusWord;
309 
310  /* Get the FPU exception address too */
311  ErrorOffset = SaveArea->U.FnArea.ErrorOffset;
312  DataOffset = SaveArea->U.FnArea.DataOffset;
313  }
314 
315  /* Get legal exceptions that software should handle */
316  Mask &= (FSW_INVALID_OPERATION |
317  FSW_DENORMAL |
319  FSW_OVERFLOW |
320  FSW_UNDERFLOW |
321  FSW_PRECISION);
322  Error &= ~Mask;
323 
324  /* Check for invalid operation */
325  if (Error & FSW_INVALID_OPERATION)
326  {
327  /*
328  * Now check if this is actually a Stack Fault. This is needed because
329  * on x86 the Invalid Operation error is set for Stack Check faults as well.
330  */
331  if (Error & FSW_STACK_FAULT)
332  {
333  /* Issue stack check fault */
335  ErrorOffset,
336  0,
337  DataOffset,
338  TrapFrame);
339  }
340  else
341  {
342  /* This is an invalid operation fault after all, so raise that instead */
344  ErrorOffset,
345  0,
346  TrapFrame);
347  }
348  }
349 
350  /* Check for divide by zero */
351  if (Error & FSW_ZERO_DIVIDE)
352  {
353  /* Issue fault */
355  ErrorOffset,
356  0,
357  TrapFrame);
358  }
359 
360  /* Check for denormal */
361  if (Error & FSW_DENORMAL)
362  {
363  /* Issue fault */
365  ErrorOffset,
366  0,
367  TrapFrame);
368  }
369 
370  /* Check for overflow */
371  if (Error & FSW_OVERFLOW)
372  {
373  /* Issue fault */
375  ErrorOffset,
376  0,
377  TrapFrame);
378  }
379 
380  /* Check for underflow */
381  if (Error & FSW_UNDERFLOW)
382  {
383  /* Issue fault */
385  ErrorOffset,
386  0,
387  TrapFrame);
388  }
389 
390  /* Check for precision fault */
391  if (Error & FSW_PRECISION)
392  {
393  /* Issue fault */
395  ErrorOffset,
396  0,
397  TrapFrame);
398  }
399 
400  /* Unknown FPU fault */
401  KeBugCheckWithTf(TRAP_CAUSE_UNKNOWN, 1, Error, 0, 0, TrapFrame);
402 }
403 
405 VOID
406 FASTCALL
408 {
409  /* Save trap frame */
410  KiEnterTrap(TrapFrame);
411 
412  /* Check for VDM trap */
413  ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
414 
415  /* Enable interrupts */
416  _enable();
417 
418  /* Dispatch the exception */
420  TrapFrame->Eip,
421  TrapFrame);
422 }
423 
425 VOID
426 FASTCALL
428 {
429  /* Save trap frame */
430  KiEnterTrap(TrapFrame);
431 
432  /* Check for VDM trap */
433  ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
434 
435  /* Check if this was a single step after sysenter */
436  if (TrapFrame->Eip == (ULONG)KiFastCallEntry)
437  {
438  /* Disable single stepping */
439  TrapFrame->EFlags &= ~EFLAGS_TF;
440 
441  /* Re-enter at the alternative sysenter entry point */
442  TrapFrame->Eip = (ULONG)KiFastCallEntryWithSingleStep;
443 
444  /* End this trap */
445  KiEoiHelper(TrapFrame);
446  }
447 
448  /* Enable interrupts if the trap came from user-mode */
449  if (KiUserTrap(TrapFrame)) _enable();
450 
451  /* Mask out trap flag and dispatch the exception */
452  TrapFrame->EFlags &= ~EFLAGS_TF;
454  TrapFrame->Eip,
455  TrapFrame);
456 }
457 
459 VOID
460 __cdecl
462 {
463  PKTSS Tss, NmiTss;
466  PKGDTENTRY TssGdt;
467  KTRAP_FRAME TrapFrame;
468  KIRQL OldIrql;
469 
470  //
471  // In some sort of strange recursion case, we might end up here with the IF
472  // flag incorrectly on the interrupt frame -- during a normal NMI this would
473  // normally already be set.
474  //
475  // For sanity's sake, make sure interrupts are disabled for sure.
476  // NMIs will already be since the CPU does it for us.
477  //
478  _disable();
479 
480  //
481  // Get the current TSS, thread, and process
482  //
483  Tss = PCR->TSS;
484  Thread = ((PKIPCR)PCR)->PrcbData.CurrentThread;
485  Process = Thread->ApcState.Process;
486 
487  //
488  // Save data usually not in the TSS
489  //
490  Tss->CR3 = Process->DirectoryTableBase[0];
491  Tss->IoMapBase = Process->IopmOffset;
492  Tss->LDT = Process->LdtDescriptor.LimitLow ? KGDT_LDT : 0;
493 
494  //
495  // Now get the base address of the NMI TSS
496  //
497  TssGdt = &((PKIPCR)KeGetPcr())->GDT[KGDT_NMI_TSS / sizeof(KGDTENTRY)];
498  NmiTss = (PKTSS)(ULONG_PTR)(TssGdt->BaseLow |
499  TssGdt->HighWord.Bytes.BaseMid << 16 |
500  TssGdt->HighWord.Bytes.BaseHi << 24);
501 
502  //
503  // Switch to it and activate it, masking off the nested flag
504  //
505  // Note that in reality, we are already on the NMI tss -- we just need to
506  // update the PCR to reflect this
507  //
508  PCR->TSS = NmiTss;
510  TssGdt->HighWord.Bits.Dpl = 0;
511  TssGdt->HighWord.Bits.Pres = 1;
512  TssGdt->HighWord.Bits.Type = I386_TSS;
513 
514  //
515  // Now build the trap frame based on the original TSS
516  //
517  // The CPU does a hardware "Context switch" / task switch of sorts and so it
518  // takes care of saving our context in the normal TSS.
519  //
520  // We just have to go get the values...
521  //
522  RtlZeroMemory(&TrapFrame, sizeof(KTRAP_FRAME));
523  TrapFrame.HardwareSegSs = Tss->Ss0;
524  TrapFrame.HardwareEsp = Tss->Esp0;
525  TrapFrame.EFlags = Tss->EFlags;
526  TrapFrame.SegCs = Tss->Cs;
527  TrapFrame.Eip = Tss->Eip;
528  TrapFrame.Ebp = Tss->Ebp;
529  TrapFrame.Ebx = Tss->Ebx;
530  TrapFrame.Esi = Tss->Esi;
531  TrapFrame.Edi = Tss->Edi;
532  TrapFrame.SegFs = Tss->Fs;
533  TrapFrame.ExceptionList = PCR->NtTib.ExceptionList;
534  TrapFrame.PreviousPreviousMode = (ULONG)-1;
535  TrapFrame.Eax = Tss->Eax;
536  TrapFrame.Ecx = Tss->Ecx;
537  TrapFrame.Edx = Tss->Edx;
538  TrapFrame.SegDs = Tss->Ds;
539  TrapFrame.SegEs = Tss->Es;
540  TrapFrame.SegGs = Tss->Gs;
541  TrapFrame.DbgEip = Tss->Eip;
542  TrapFrame.DbgEbp = Tss->Ebp;
543 
544  //
545  // Store the trap frame in the KPRCB
546  //
547  KiSaveProcessorState(&TrapFrame, NULL);
548 
549  //
550  // Call any registered NMI handlers and see if they handled it or not
551  //
552  if (!KiHandleNmi())
553  {
554  //
555  // They did not, so call the platform HAL routine to bugcheck the system
556  //
557  // Make sure the HAL believes it's running at HIGH IRQL... we can't use
558  // the normal APIs here as playing with the IRQL could change the system
559  // state
560  //
561  OldIrql = PCR->Irql;
562  PCR->Irql = HIGH_LEVEL;
564  PCR->Irql = OldIrql;
565  }
566 
567  //
568  // Although the CPU disabled NMIs, we just did a BIOS Call, which could've
569  // totally changed things.
570  //
571  // We have to make sure we're still in our original NMI -- a nested NMI
572  // will point back to the NMI TSS, and in that case we're hosed.
573  //
574  if (PCR->TSS->Backlink != KGDT_NMI_TSS)
575  {
576  //
577  // Restore original TSS
578  //
579  PCR->TSS = Tss;
580 
581  //
582  // Set it back to busy
583  //
584  TssGdt->HighWord.Bits.Dpl = 0;
585  TssGdt->HighWord.Bits.Pres = 1;
586  TssGdt->HighWord.Bits.Type = I386_ACTIVE_TSS;
587 
588  //
589  // Restore nested flag
590  //
592 
593  //
594  // Handled, return from interrupt
595  //
596  KiIret();
597  }
598 
599  //
600  // Unhandled: crash the system
601  //
603 }
604 
606 VOID
607 FASTCALL
609 {
610  /* Save trap frame */
611  KiEnterTrap(TrapFrame);
612 
613  /* Continue with the common handler */
614  KiDebugHandler(TrapFrame, BREAKPOINT_BREAK, 0, 0);
615 }
616 
618 VOID
619 FASTCALL
621 {
622  /* Save trap frame */
623  KiEnterTrap(TrapFrame);
624 
625  /* Check for VDM trap */
626  ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
627 
628  /* Enable interrupts */
629  _enable();
630 
631  /* Dispatch the exception */
633  TrapFrame->Eip - 1,
634  TrapFrame);
635 }
636 
638 VOID
639 FASTCALL
641 {
642  /* Save trap frame */
643  KiEnterTrap(TrapFrame);
644 
645  /* Check for VDM trap */
646  ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
647 
648  /* Check for kernel-mode fault */
649  if (!KiUserTrap(TrapFrame)) KiSystemFatalException(EXCEPTION_BOUND_CHECK, TrapFrame);
650 
651  /* Enable interrupts */
652  _enable();
653 
654  /* Dispatch the exception */
656  TrapFrame->Eip,
657  TrapFrame);
658 }
659 
661 VOID
662 FASTCALL
664 {
665  PUCHAR Instruction;
666  ULONG i;
667  KIRQL OldIrql;
668 
669  /* Check for V86 GPF */
670  if (__builtin_expect(KiV86Trap(TrapFrame), 1))
671  {
672  /* Enter V86 trap */
673  KiEnterV86Trap(TrapFrame);
674 
675  /* Must be a VDM process */
676  if (__builtin_expect(!PsGetCurrentProcess()->VdmObjects, 0))
677  {
678  /* Enable interrupts */
679  _enable();
680 
681  /* Setup illegal instruction fault */
683  TrapFrame->Eip,
684  TrapFrame);
685  }
686 
687  /* Go to APC level */
688  KeRaiseIrql(APC_LEVEL, &OldIrql);
689  _enable();
690 
691  /* Check for BOP */
692  if (!VdmDispatchBop(TrapFrame))
693  {
694  /* Should only happen in VDM mode */
696  }
697 
698  /* Bring IRQL back */
699  KeLowerIrql(OldIrql);
700  _disable();
701 
702  /* Do a quick V86 exit if possible */
703  KiExitV86Trap(TrapFrame);
704  }
705 
706  /* Save trap frame */
707  KiEnterTrap(TrapFrame);
708 
709  /* Enable interrupts */
710  Instruction = (PUCHAR)TrapFrame->Eip;
711  _enable();
712 
713  /* Check for user trap */
714  if (KiUserTrap(TrapFrame))
715  {
716  /* FIXME: Use SEH */
717 
718  /* Scan next 4 opcodes */
719  for (i = 0; i < 4; i++)
720  {
721  /* Check for LOCK instruction */
722  if (Instruction[i] == 0xF0)
723  {
724  /* Send invalid lock sequence exception */
726  TrapFrame->Eip,
727  TrapFrame);
728  }
729  }
730 
731  /* FIXME: SEH ends here */
732  }
733 
734  /* Kernel-mode or user-mode fault (but not LOCK) */
736  TrapFrame->Eip,
737  TrapFrame);
738 
739 }
740 
742 VOID
743 FASTCALL
745 {
746  PKTHREAD Thread, NpxThread;
747  PFX_SAVE_AREA SaveArea, NpxSaveArea;
748  ULONG Cr0;
749 
750  /* Save trap frame */
751  KiEnterTrap(TrapFrame);
752 
753  /* Try to handle NPX delay load */
754  for (;;)
755  {
756  /* Get the current thread */
757  Thread = KeGetCurrentThread();
758 
759  /* Get the NPX frame */
760  SaveArea = KiGetThreadNpxArea(Thread);
761 
762  /* Check if emulation is enabled */
763  if (SaveArea->Cr0NpxState & CR0_EM)
764  {
765  /* Not implemented */
767  }
768 
769  /* Save CR0 and check NPX state */
770  Cr0 = __readcr0();
771  if (Thread->NpxState != NPX_STATE_LOADED)
772  {
773  /* Update CR0 */
774  Cr0 &= ~(CR0_MP | CR0_EM | CR0_TS);
775  __writecr0(Cr0);
776 
777  /* Get the NPX thread */
778  NpxThread = KeGetCurrentPrcb()->NpxThread;
779  if (NpxThread)
780  {
781  /* Get the NPX frame */
782  NpxSaveArea = KiGetThreadNpxArea(NpxThread);
783 
784  /* Save FPU state */
785  Ke386SaveFpuState(NpxSaveArea);
786 
787  /* Update NPX state */
788  NpxThread->NpxState = NPX_STATE_NOT_LOADED;
789  }
790 
791  /* Load FPU state */
792  Ke386LoadFpuState(SaveArea);
793 
794  /* Update NPX state */
795  Thread->NpxState = NPX_STATE_LOADED;
796  KeGetCurrentPrcb()->NpxThread = Thread;
797 
798  /* Enable interrupts */
799  _enable();
800 
801  /* Check if CR0 needs to be reloaded due to context switch */
802  if (!SaveArea->Cr0NpxState) KiEoiHelper(TrapFrame);
803 
804  /* Otherwise, we need to reload CR0, disable interrupts */
805  _disable();
806 
807  /* Reload CR0 */
808  Cr0 = __readcr0();
809  Cr0 |= SaveArea->Cr0NpxState;
810  __writecr0(Cr0);
811 
812  /* Now restore interrupts and check for TS */
813  _enable();
814  if (Cr0 & CR0_TS) KiEoiHelper(TrapFrame);
815 
816  /* We're still here -- clear TS and try again */
817  __writecr0(__readcr0() &~ CR0_TS);
818  _disable();
819  }
820  else
821  {
822  /* This is an actual fault, not a lack of FPU state */
823  break;
824  }
825  }
826 
827  /* TS should not be set */
828  if (Cr0 & CR0_TS)
829  {
830  /*
831  * If it's incorrectly set, then maybe the state is actually still valid
832  * but we could have lost track of that due to a BIOS call.
833  * Make sure MP is still set, which should verify the theory.
834  */
835  if (Cr0 & CR0_MP)
836  {
837  /* Indeed, the state is actually still valid, so clear TS */
838  __writecr0(__readcr0() &~ CR0_TS);
839  KiEoiHelper(TrapFrame);
840  }
841 
842  /* Otherwise, something strange is going on */
843  KeBugCheckWithTf(TRAP_CAUSE_UNKNOWN, 2, Cr0, 0, 0, TrapFrame);
844  }
845 
846  /* It's not a delayed load, so process this trap as an NPX fault */
847  KiNpxHandler(TrapFrame, Thread, SaveArea);
848 }
849 
851 VOID
852 FASTCALL
854 {
855  /* FIXME: Not handled */
857 }
858 
860 VOID
861 FASTCALL
863 {
864  /* Save trap frame */
865  KiEnterTrap(TrapFrame);
866 
867  /* Enable interrupts and kill the system */
868  _enable();
870 }
871 
873 VOID
874 FASTCALL
876 {
877  /* Save trap frame */
878  KiEnterTrap(TrapFrame);
879 
880  /* Check for VDM trap */
881  ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
882 
883  /* Kill the system */
885 }
886 
888 VOID
889 FASTCALL
891 {
892  /* Save trap frame */
893  KiEnterTrap(TrapFrame);
894 
895  /* FIXME: Kill the system */
898 }
899 
901 VOID
902 FASTCALL
904 {
905  /* Save trap frame */
906  KiEnterTrap(TrapFrame);
907 
908  /* FIXME: Kill the system */
911 }
912 
914 VOID
915 FASTCALL
917 {
918  ULONG i, j, Iopl;
919  BOOLEAN Privileged = FALSE;
920  PUCHAR Instructions;
921  UCHAR Instruction = 0;
922  KIRQL OldIrql;
923 
924  /* Check for V86 GPF */
925  if (__builtin_expect(KiV86Trap(TrapFrame), 1))
926  {
927  /* Enter V86 trap */
928  KiEnterV86Trap(TrapFrame);
929 
930  /* Must be a VDM process */
931  if (__builtin_expect(!PsGetCurrentProcess()->VdmObjects, 0))
932  {
933  /* Enable interrupts */
934  _enable();
935 
936  /* Setup illegal instruction fault */
938  TrapFrame->Eip,
939  TrapFrame);
940  }
941 
942  /* Go to APC level */
943  KeRaiseIrql(APC_LEVEL, &OldIrql);
944  _enable();
945 
946  /* Handle the V86 opcode */
947  if (__builtin_expect(Ki386HandleOpcodeV86(TrapFrame) == 0xFF, 0))
948  {
949  /* Should only happen in VDM mode */
951  }
952 
953  /* Bring IRQL back */
954  KeLowerIrql(OldIrql);
955  _disable();
956 
957  /* Do a quick V86 exit if possible */
958  KiExitV86Trap(TrapFrame);
959  }
960 
961  /* Save trap frame */
962  KiEnterTrap(TrapFrame);
963 
964  /* Check for user-mode GPF */
965  if (KiUserTrap(TrapFrame))
966  {
967  /* Should not be VDM */
968  ASSERT(KiVdmTrap(TrapFrame) == FALSE);
969 
970  /* Enable interrupts and check error code */
971  _enable();
972  if (!TrapFrame->ErrCode)
973  {
974  /* FIXME: Use SEH */
975  Instructions = (PUCHAR)TrapFrame->Eip;
976 
977  /* Scan next 15 bytes */
978  for (i = 0; i < 15; i++)
979  {
980  /* Skip prefix instructions */
981  for (j = 0; j < sizeof(KiTrapPrefixTable); j++)
982  {
983  /* Is this a prefix instruction? */
984  if (Instructions[i] == KiTrapPrefixTable[j])
985  {
986  /* Stop looking */
987  break;
988  }
989  }
990 
991  /* Is this NOT any prefix instruction? */
992  if (j == sizeof(KiTrapPrefixTable))
993  {
994  /* We can go ahead and handle the fault now */
995  Instruction = Instructions[i];
996  break;
997  }
998  }
999 
1000  /* If all we found was prefixes, then this instruction is too long */
1001  if (i == 15)
1002  {
1003  /* Setup illegal instruction fault */
1005  TrapFrame->Eip,
1006  TrapFrame);
1007  }
1008 
1009  /* Check for privileged instructions */
1010  DPRINT("Instruction (%lu) at fault: %lx %lx %lx %lx\n",
1011  i,
1012  Instructions[i],
1013  Instructions[i + 1],
1014  Instructions[i + 2],
1015  Instructions[i + 3]);
1016  if (Instruction == 0xF4) // HLT
1017  {
1018  /* HLT is privileged */
1019  Privileged = TRUE;
1020  }
1021  else if (Instruction == 0x0F)
1022  {
1023  /* Test if it's any of the privileged two-byte opcodes */
1024  if (((Instructions[i + 1] == 0x00) && // LLDT or LTR
1025  (((Instructions[i + 2] & 0x38) == 0x10) || // LLDT
1026  (Instructions[i + 2] == 0x18))) || // LTR
1027  ((Instructions[i + 1] == 0x01) && // LGDT or LIDT or LMSW
1028  (((Instructions[i + 2] & 0x38) == 0x10) || // LGDT
1029  (Instructions[i + 2] == 0x18) || // LIDT
1030  (Instructions[i + 2] == 0x30))) || // LMSW
1031  (Instructions[i + 1] == 0x08) || // INVD
1032  (Instructions[i + 1] == 0x09) || // WBINVD
1033  (Instructions[i + 1] == 0x35) || // SYSEXIT
1034  (Instructions[i + 1] == 0x21) || // MOV DR, XXX
1035  (Instructions[i + 1] == 0x06) || // CLTS
1036  (Instructions[i + 1] == 0x20) || // MOV CR, XXX
1037  (Instructions[i + 1] == 0x22) || // MOV XXX, CR
1038  (Instructions[i + 1] == 0x23) || // MOV YYY, DR
1039  (Instructions[i + 1] == 0x30) || // WRMSR
1040  (Instructions[i + 1] == 0x33)) // RDPMC
1041  // INVLPG, INVLPGA, SYSRET
1042  {
1043  /* These are all privileged */
1044  Privileged = TRUE;
1045  }
1046  }
1047  else
1048  {
1049  /* Get the IOPL and compare with the RPL mask */
1050  Iopl = (TrapFrame->EFlags & EFLAGS_IOPL) >> 12;
1051  if ((TrapFrame->SegCs & RPL_MASK) > Iopl)
1052  {
1053  /* I/O privilege error -- check for known instructions */
1054  if ((Instruction == 0xFA) || (Instruction == 0xFB)) // CLI or STI
1055  {
1056  /* These are privileged */
1057  Privileged = TRUE;
1058  }
1059  else
1060  {
1061  /* Last hope: an IN/OUT instruction */
1062  for (j = 0; j < sizeof(KiTrapIoTable); j++)
1063  {
1064  /* Is this an I/O instruction? */
1065  if (Instruction == KiTrapIoTable[j])
1066  {
1067  /* Then it's privileged */
1068  Privileged = TRUE;
1069  break;
1070  }
1071  }
1072  }
1073  }
1074  }
1075 
1076  /* So now... was the instruction privileged or not? */
1077  if (Privileged)
1078  {
1079  /* Whew! We have a privileged instruction, so dispatch the fault */
1081  TrapFrame->Eip,
1082  TrapFrame);
1083  }
1084  }
1085 
1086  /* If we got here, send an access violation */
1088  TrapFrame->Eip,
1089  0,
1090  0xFFFFFFFF,
1091  TrapFrame);
1092  }
1093 
1094  /*
1095  * Check for a fault during checking of the user instruction.
1096  *
1097  * Note that the SEH handler will catch invalid EIP, but we could be dealing
1098  * with an invalid CS, which will generate another GPF instead.
1099  *
1100  */
1101  if (((PVOID)TrapFrame->Eip >= (PVOID)KiTrap0DHandler) &&
1102  ((PVOID)TrapFrame->Eip < (PVOID)KiTrap0DHandler))
1103  {
1104  /* Not implemented */
1106  }
1107 
1108  /*
1109  * NOTE: The ASM trap exit code would restore segment registers by doing
1110  * a POP <SEG>, which could cause an invalid segment if someone had messed
1111  * with the segment values.
1112  *
1113  * Another case is a bogus SS, which would hit a GPF when doing the iret.
1114  * This could only be done through a buggy or malicious driver, or perhaps
1115  * the kernel debugger.
1116  *
1117  * The kernel normally restores the "true" segment if this happens.
1118  *
1119  * However, since we're restoring in C, not ASM, we can't detect
1120  * POP <SEG> since the actual instructions will be different.
1121  *
1122  * A better technique would be to check the EIP and somehow edit the
1123  * trap frame before restarting the instruction -- but we would need to
1124  * know the extract instruction that was used first.
1125  *
1126  * We could force a special instrinsic to use stack instructions, or write
1127  * a simple instruction length checker.
1128  *
1129  * Nevertheless, this is a lot of work for the purpose of avoiding a crash
1130  * when the user is purposedly trying to create one from kernel-mode, so
1131  * we should probably table this for now since it's not a "real" issue.
1132  */
1133 
1134  /*
1135  * NOTE2: Another scenario is the IRET during a V8086 restore (BIOS Call)
1136  * which will cause a GPF since the trap frame is a total mess (on purpose)
1137  * as built in KiEnterV86Mode.
1138  *
1139  * The idea is to scan for IRET, scan for the known EIP adress, validate CS
1140  * and then manually issue a jump to the V8086 return EIP.
1141  */
1142  Instructions = (PUCHAR)TrapFrame->Eip;
1143  if (Instructions[0] == 0xCF)
1144  {
1145  /*
1146  * Some evil shit is going on here -- this is not the SS:ESP you're
1147  * looking for! Instead, this is actually CS:EIP you're looking at!
1148  * Why? Because part of the trap frame actually corresponds to the IRET
1149  * stack during the trap exit!
1150  */
1151  if ((TrapFrame->HardwareEsp == (ULONG)Ki386BiosCallReturnAddress) &&
1152  (TrapFrame->HardwareSegSs == (KGDT_R0_CODE | RPL_MASK)))
1153  {
1154  /* Exit the V86 trap! */
1155  Ki386BiosCallReturnAddress(TrapFrame);
1156  }
1157  else
1158  {
1159  /* Otherwise, this is another kind of IRET fault */
1161  }
1162  }
1163 
1164  /* So since we're not dealing with the above case, check for RDMSR/WRMSR */
1165  if ((Instructions[0] == 0xF) && // 2-byte opcode
1166  ((Instructions[1] == 0x32) || // RDMSR
1167  (Instructions[1] == 0x30))) // WRMSR
1168  {
1169  /* Unknown CPU MSR, so raise an access violation */
1171  TrapFrame->Eip,
1172  TrapFrame);
1173  }
1174 
1175  /* Check for lazy segment load */
1176  if (TrapFrame->SegDs != (KGDT_R3_DATA | RPL_MASK))
1177  {
1178  /* Fix it */
1179  TrapFrame->SegDs = (KGDT_R3_DATA | RPL_MASK);
1180  }
1181  else if (TrapFrame->SegEs != (KGDT_R3_DATA | RPL_MASK))
1182  {
1183  /* Fix it */
1184  TrapFrame->SegEs = (KGDT_R3_DATA | RPL_MASK);
1185  }
1186  else
1187  {
1188  /* Whatever it is, we can't handle it */
1190  }
1191 
1192  /* Return to where we came from */
1193  KiTrapReturn(TrapFrame);
1194 }
1195 
1197 VOID
1198 FASTCALL
1200 {
1201  PKTHREAD Thread;
1202  BOOLEAN Present;
1203  BOOLEAN StoreInstruction;
1204  ULONG_PTR Cr2;
1205  NTSTATUS Status;
1206 
1207  /* Save trap frame */
1208  KiEnterTrap(TrapFrame);
1209 
1210  /* Check if this is the base frame */
1211  Thread = KeGetCurrentThread();
1212  if (KeGetTrapFrame(Thread) != TrapFrame)
1213  {
1214  /* It isn't, check if this is a second nested frame */
1215  if (((ULONG_PTR)KeGetTrapFrame(Thread) - (ULONG_PTR)TrapFrame) <=
1216  FIELD_OFFSET(KTRAP_FRAME, EFlags))
1217  {
1218  /* The stack is somewhere in between frames, we need to fix it */
1220  }
1221  }
1222 
1223  /* Save CR2 */
1224  Cr2 = __readcr2();
1225 
1226  /* Enable interrupts */
1227  _enable();
1228 
1229  /* Interpret the error code */
1230  Present = (TrapFrame->ErrCode & 1) != 0;
1231  StoreInstruction = (TrapFrame->ErrCode & 2) != 0;
1232 
1233  /* Check if we came in with interrupts disabled */
1234  if (!(TrapFrame->EFlags & EFLAGS_INTERRUPT_MASK))
1235  {
1236  /* This is completely illegal, bugcheck the system */
1237  KeBugCheckWithTf(IRQL_NOT_LESS_OR_EQUAL,
1238  Cr2,
1239  (ULONG_PTR)-1,
1240  StoreInstruction,
1241  TrapFrame->Eip,
1242  TrapFrame);
1243  }
1244 
1245  /* Check for S-List fault
1246 
1247  Explanation: An S-List fault can occur due to a race condition between 2
1248  threads simultaneously trying to pop an element from the S-List. After
1249  thread 1 has read the pointer to the top element on the S-List it is
1250  preempted and thread 2 calls InterlockedPopEntrySlist on the same S-List,
1251  removing the top element and freeing it's memory. After that thread 1
1252  resumes and tries to read the address of the Next pointer from the top
1253  element, which it assumes will be the next top element.
1254  But since that memory has been freed, we get a page fault. To handle this
1255  race condition, we let thread 1 repeat the operation.
1256  We do NOT invoke the page fault handler in this case, since we do not
1257  want to trigger any side effects, like paging or a guard page fault.
1258 
1259  Sequence of operations:
1260 
1261  Thread 1 : mov eax, [ebp] <= eax now points to the first element
1262  Thread 1 : mov edx, [ebp + 4] <= edx is loaded with Depth and Sequence
1263  *** preempted ***
1264  Thread 2 : calls InterlockedPopEntrySlist, changing the top element
1265  Thread 2 : frees the memory of the element that was popped
1266  *** preempted ***
1267  Thread 1 : checks if eax is NULL
1268  Thread 1 : InterlockedPopEntrySListFault: mov ebx, [eax] <= faults
1269 
1270  To be sure that we are dealing with exactly the case described above, we
1271  check whether the ListHeader has changed. If Thread 2 only popped one
1272  entry, the Next field in the S-List-header has changed.
1273  If after thread 1 has faulted, thread 2 allocates a new element, by
1274  chance getting the same address as the previously freed element and
1275  pushes it on the list again, we will see the same top element, but the
1276  Sequence member of the S-List header has changed. Therefore we check
1277  both fields to make sure we catch any concurrent modification of the
1278  S-List-header.
1279  */
1280  if ((TrapFrame->Eip == (ULONG_PTR)ExpInterlockedPopEntrySListFault) ||
1281  (TrapFrame->Eip == (ULONG_PTR)KeUserPopEntrySListFault))
1282  {
1283  ULARGE_INTEGER SListHeader;
1284  PVOID ResumeAddress;
1285 
1286  /* Sanity check that the assembly is correct:
1287  This must be mov ebx, [eax]
1288  Followed by cmpxchg8b [ebp] */
1289  ASSERT((((UCHAR*)TrapFrame->Eip)[0] == 0x8B) &&
1290  (((UCHAR*)TrapFrame->Eip)[1] == 0x18) &&
1291  (((UCHAR*)TrapFrame->Eip)[2] == 0x0F) &&
1292  (((UCHAR*)TrapFrame->Eip)[3] == 0xC7) &&
1293  (((UCHAR*)TrapFrame->Eip)[4] == 0x4D) &&
1294  (((UCHAR*)TrapFrame->Eip)[5] == 0x00));
1295 
1296  /* Check if this is a user fault */
1297  if (TrapFrame->Eip == (ULONG_PTR)KeUserPopEntrySListFault)
1298  {
1299  /* EBP points to the S-List-header. Copy it inside SEH, to protect
1300  against a bogus pointer from user mode */
1301  _SEH2_TRY
1302  {
1303  ProbeForRead((PVOID)TrapFrame->Ebp,
1304  sizeof(ULARGE_INTEGER),
1306  SListHeader = *(PULARGE_INTEGER)TrapFrame->Ebp;
1307  }
1309  {
1310  /* The S-List pointer is not valid! */
1311  goto NotSListFault;
1312  }
1313  _SEH2_END;
1314  ResumeAddress = KeUserPopEntrySListResume;
1315  }
1316  else
1317  {
1318  SListHeader = *(PULARGE_INTEGER)TrapFrame->Ebp;
1319  ResumeAddress = ExpInterlockedPopEntrySListResume;
1320  }
1321 
1322  /* Check if either the Next pointer or the Sequence member in the
1323  S-List-header has changed. If any of these has changed, we restart
1324  the operation. Otherwise we only have a bogus pointer and let the
1325  page fault handler deal with it. */
1326  if ((SListHeader.LowPart != TrapFrame->Eax) ||
1327  (SListHeader.HighPart != TrapFrame->Edx))
1328  {
1329  DPRINT1("*** Got an S-List-Fault ***\n");
1330  KeGetCurrentThread()->SListFaultCount++;
1331 
1332  /* Restart the operation */
1333  TrapFrame->Eip = (ULONG_PTR)ResumeAddress;
1334 
1335  /* Continue execution */
1336  KiEoiHelper(TrapFrame);
1337  }
1338  }
1339 NotSListFault:
1340 
1341  /* Call the access fault handler */
1342  Status = MmAccessFault(Present,
1343  (PVOID)Cr2,
1344  KiUserTrap(TrapFrame),
1345  TrapFrame);
1346  if (NT_SUCCESS(Status))
1347  {
1348 #ifdef _WINKD_
1349  /* Check whether the kernel debugger has owed breakpoints to be inserted */
1351 #endif
1352  /* We succeeded, return */
1353  KiEoiHelper(TrapFrame);
1354  }
1355 
1356  /* Check for syscall fault */
1357 #if 0
1358  if ((TrapFrame->Eip == (ULONG_PTR)CopyParams) ||
1359  (TrapFrame->Eip == (ULONG_PTR)ReadBatch))
1360  {
1361  /* Not yet implemented */
1363  }
1364 #endif
1365 
1366  /* Check for VDM trap */
1367  if (KiVdmTrap(TrapFrame))
1368  {
1369  DPRINT1("VDM PAGE FAULT at %lx:%lx for address %lx\n",
1370  TrapFrame->SegCs, TrapFrame->Eip, Cr2);
1371  if (VdmDispatchPageFault(TrapFrame))
1372  {
1373  /* Return and end VDM execution */
1374  DPRINT1("VDM page fault with status 0x%lx resolved\n", Status);
1375  KiEoiHelper(TrapFrame);
1376  }
1377  DPRINT1("VDM page fault with status 0x%lx NOT resolved\n", Status);
1378  }
1379 
1380  /* Either kernel or user trap (non VDM) so dispatch exception */
1381  if (Status == STATUS_ACCESS_VIOLATION)
1382  {
1383  /* This status code is repurposed so we can recognize it later */
1385  TrapFrame->Eip,
1386  StoreInstruction,
1387  Cr2,
1388  TrapFrame);
1389  }
1390  else if ((Status == STATUS_GUARD_PAGE_VIOLATION) ||
1391  (Status == STATUS_STACK_OVERFLOW))
1392  {
1393  /* These faults only have two parameters */
1394  KiDispatchException2Args(Status,
1395  TrapFrame->Eip,
1396  StoreInstruction,
1397  Cr2,
1398  TrapFrame);
1399  }
1400 
1401  /* Only other choice is an in-page error, with 3 parameters */
1403  0,
1404  TrapFrame->Eip,
1405  3,
1406  StoreInstruction,
1407  Cr2,
1408  Status,
1409  TrapFrame);
1410 }
1411 
1413 VOID
1414 FASTCALL
1416 {
1417  /* Save trap frame */
1418  KiEnterTrap(TrapFrame);
1419 
1420  /* FIXME: Kill the system */
1421  UNIMPLEMENTED;
1423 }
1424 
1426 VOID
1427 FASTCALL
1429 {
1430  PKTHREAD Thread;
1431  PFX_SAVE_AREA SaveArea;
1432 
1433  /* Save trap frame */
1434  KiEnterTrap(TrapFrame);
1435 
1436  /* Check if this is the NPX thrad */
1437  Thread = KeGetCurrentThread();
1438  SaveArea = KiGetThreadNpxArea(Thread);
1439  if (Thread != KeGetCurrentPrcb()->NpxThread)
1440  {
1441  /* It isn't, enable interrupts and set delayed error */
1442  _enable();
1443  SaveArea->Cr0NpxState |= CR0_TS;
1444 
1445  /* End trap */
1446  KiEoiHelper(TrapFrame);
1447  }
1448 
1449  /* Otherwise, proceed with NPX fault handling */
1450  KiNpxHandler(TrapFrame, Thread, SaveArea);
1451 }
1452 
1454 VOID
1455 FASTCALL
1457 {
1458  /* Save trap frame */
1459  KiEnterTrap(TrapFrame);
1460 
1461  /* Enable interrupts and kill the system */
1462  _enable();
1464 }
1465 
1467 VOID
1468 FASTCALL
1470 {
1471  PKTHREAD Thread;
1472  PFX_SAVE_AREA SaveArea;
1473  ULONG Cr0, MxCsrMask, Error;
1474 
1475  /* Save trap frame */
1476  KiEnterTrap(TrapFrame);
1477 
1478  /* Check if this is the NPX thrad */
1479  Thread = KeGetCurrentThread();
1480  if (Thread != KeGetCurrentPrcb()->NpxThread)
1481  {
1482  /* It isn't, kill the system */
1483  KeBugCheckWithTf(TRAP_CAUSE_UNKNOWN, 13, (ULONG_PTR)Thread, 0, 0, TrapFrame);
1484  }
1485 
1486  /* Get the NPX frame */
1487  SaveArea = KiGetThreadNpxArea(Thread);
1488 
1489  /* Check for VDM trap */
1490  ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
1491 
1492  /* Check for user trap */
1493  if (!KiUserTrap(TrapFrame))
1494  {
1495  /* Kernel should not fault on XMMI */
1496  KeBugCheckWithTf(TRAP_CAUSE_UNKNOWN, 13, 0, 0, 2, TrapFrame);
1497  }
1498 
1499  /* Update CR0 */
1500  Cr0 = __readcr0();
1501  Cr0 &= ~(CR0_MP | CR0_EM | CR0_TS);
1502  __writecr0(Cr0);
1503 
1504  /* Save FPU state */
1505  Ke386SaveFpuState(SaveArea);
1506 
1507  /* Mark CR0 state dirty */
1508  Cr0 |= NPX_STATE_NOT_LOADED;
1509  Cr0 |= SaveArea->Cr0NpxState;
1510  __writecr0(Cr0);
1511 
1512  /* Update NPX state */
1513  Thread->NpxState = NPX_STATE_NOT_LOADED;
1514  KeGetCurrentPrcb()->NpxThread = NULL;
1515 
1516  /* Clear the TS bit and re-enable interrupts */
1517  SaveArea->Cr0NpxState &= ~CR0_TS;
1518  _enable();
1519 
1520  /* Now look at MxCsr to get the mask of errors we should care about */
1521  MxCsrMask = ~((USHORT)SaveArea->U.FxArea.MXCsr >> 7);
1522 
1523  /* Get legal exceptions that software should handle */
1524  Error = (USHORT)SaveArea->U.FxArea.MXCsr & (FSW_INVALID_OPERATION |
1525  FSW_DENORMAL |
1526  FSW_ZERO_DIVIDE |
1527  FSW_OVERFLOW |
1528  FSW_UNDERFLOW |
1529  FSW_PRECISION);
1530  Error &= MxCsrMask;
1531 
1532  /* Now handle any of those legal errors */
1533  if (Error & (FSW_INVALID_OPERATION |
1534  FSW_DENORMAL |
1535  FSW_ZERO_DIVIDE |
1536  FSW_OVERFLOW |
1537  FSW_UNDERFLOW |
1538  FSW_PRECISION))
1539  {
1540  /* By issuing an exception */
1542  TrapFrame->Eip,
1543  0,
1544  TrapFrame);
1545  }
1546 
1547  /* Unknown XMMI fault */
1548  KeBugCheckWithTf(TRAP_CAUSE_UNKNOWN, 13, 0, 0, 1, TrapFrame);
1549 }
1550 
1551 /* SOFTWARE SERVICES **********************************************************/
1552 
1553 VOID
1554 FASTCALL
1556 {
1557  /* Save trap frame */
1558  KiEnterTrap(TrapFrame);
1559 
1560  /* Decrement EIP to point to the INT29 instruction (2 bytes, not 1 like INT3) */
1561  TrapFrame->Eip -= 2;
1562 
1563  /* Check if this is a user trap */
1564  if (KiUserTrap(TrapFrame))
1565  {
1566  /* Dispatch exception to user mode */
1569  TrapFrame->Eip,
1570  1,
1571  TrapFrame->Ecx,
1572  0,
1573  0,
1574  TrapFrame);
1575  }
1576  else
1577  {
1578  EXCEPTION_RECORD ExceptionRecord;
1579 
1580  /* Bugcheck the system */
1581  ExceptionRecord.ExceptionCode = STATUS_STACK_BUFFER_OVERRUN;
1582  ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
1583  ExceptionRecord.ExceptionRecord = NULL;
1584  ExceptionRecord.ExceptionAddress = (PVOID)TrapFrame->Eip;
1585  ExceptionRecord.NumberParameters = 1;
1586  ExceptionRecord.ExceptionInformation[0] = TrapFrame->Ecx;
1587 
1588  KeBugCheckWithTf(KERNEL_SECURITY_CHECK_FAILURE,
1589  TrapFrame->Ecx,
1590  (ULONG_PTR)TrapFrame,
1591  (ULONG_PTR)&ExceptionRecord,
1592  0,
1593  TrapFrame);
1594  }
1595 }
1596 
1597 VOID
1598 FASTCALL
1600 {
1601  /* Save trap frame */
1602  KiEnterTrap(TrapFrame);
1603 
1604  /*
1605  * Just fail the request
1606  */
1607  DbgPrint("INT 0x2A attempted, returning 0 tick count\n");
1608  TrapFrame->Eax = 0;
1609 
1610  /* Exit the trap */
1611  KiEoiHelper(TrapFrame);
1612 }
1613 
1614 VOID
1615 FASTCALL
1617 {
1618  PKTHREAD Thread;
1619  NTSTATUS Status;
1620 
1621  /* Save the SEH chain, NtCallbackReturn will restore this */
1622  TrapFrame->ExceptionList = KeGetPcr()->NtTib.ExceptionList;
1623 
1624  /* Set thread fields */
1625  Thread = KeGetCurrentThread();
1626  Thread->TrapFrame = TrapFrame;
1627  Thread->PreviousMode = KiUserTrap(TrapFrame);
1628  ASSERT(Thread->PreviousMode != KernelMode);
1629 
1630  /* Pass the register parameters to NtCallbackReturn.
1631  Result pointer is in ecx, result length in edx, status in eax */
1632  Status = NtCallbackReturn((PVOID)TrapFrame->Ecx,
1633  TrapFrame->Edx,
1634  TrapFrame->Eax);
1635 
1636  /* If we got here, something went wrong. Return an error to the caller */
1637  KiServiceExit(TrapFrame, Status);
1638 }
1639 
1641 VOID
1642 FASTCALL
1644 {
1645  /* Save trap frame */
1646  KiEnterTrap(TrapFrame);
1647 
1648  /* Decrement EIP to point to the INT2C instruction (2 bytes, not 1 like INT3) */
1649  TrapFrame->Eip -= 2;
1650 
1651  /* Dispatch the exception */
1653  TrapFrame->Eip,
1654  TrapFrame);
1655 }
1656 
1658 VOID
1659 FASTCALL
1661 {
1662  /* Save trap frame */
1663  KiEnterTrap(TrapFrame);
1664 
1665  /* Increment EIP to skip the INT3 instruction */
1666  TrapFrame->Eip++;
1667 
1668  /* Continue with the common handler */
1669  KiDebugHandler(TrapFrame, TrapFrame->Eax, TrapFrame->Ecx, TrapFrame->Edx);
1670 }
1671 
1672 
1674 VOID
1675 KiDbgPreServiceHook(ULONG SystemCallNumber, PULONG_PTR Arguments)
1676 {
1677 #if DBG && !defined(_WINKD_)
1678  if (SystemCallNumber >= 0x1000 && KeWin32PreServiceHook)
1679  KeWin32PreServiceHook(SystemCallNumber, Arguments);
1680 #endif
1681 }
1682 
1684 ULONG_PTR
1686 {
1687 #if DBG && !defined(_WINKD_)
1688  if (SystemCallNumber >= 0x1000 && KeWin32PostServiceHook)
1689  return KeWin32PostServiceHook(SystemCallNumber, Result);
1690 #endif
1691  return Result;
1692 }
1693 
1695 VOID
1696 FASTCALL
1698  IN PVOID Arguments)
1699 {
1700  PKTHREAD Thread;
1701  PKSERVICE_TABLE_DESCRIPTOR DescriptorTable;
1702  ULONG Id, Offset, StackBytes;
1703  NTSTATUS Status;
1704  PVOID Handler;
1705  ULONG SystemCallNumber = TrapFrame->Eax;
1706 
1707  /* Get the current thread */
1708  Thread = KeGetCurrentThread();
1709 
1710  /* Set debug header */
1711  KiFillTrapFrameDebug(TrapFrame);
1712 
1713  /* Chain trap frames */
1714  TrapFrame->Edx = (ULONG_PTR)Thread->TrapFrame;
1715 
1716  /* No error code */
1717  TrapFrame->ErrCode = 0;
1718 
1719  /* Save previous mode */
1720  TrapFrame->PreviousPreviousMode = Thread->PreviousMode;
1721 
1722  /* Save the SEH chain and terminate it for now */
1723  TrapFrame->ExceptionList = KeGetPcr()->NtTib.ExceptionList;
1724  KeGetPcr()->NtTib.ExceptionList = EXCEPTION_CHAIN_END;
1725 
1726  /* Default to debugging disabled */
1727  TrapFrame->Dr7 = 0;
1728 
1729  /* Check if the frame was from user mode */
1730  if (KiUserTrap(TrapFrame))
1731  {
1732  /* Check for active debugging */
1733  if (KeGetCurrentThread()->Header.DebugActive & 0xFF)
1734  {
1735  /* Handle debug registers */
1737  }
1738  }
1739 
1740  /* Set thread fields */
1741  Thread->TrapFrame = TrapFrame;
1742  Thread->PreviousMode = KiUserTrap(TrapFrame);
1743 
1744  /* Enable interrupts */
1745  _enable();
1746 
1747  /* Decode the system call number */
1748  Offset = (SystemCallNumber >> SERVICE_TABLE_SHIFT) & SERVICE_TABLE_MASK;
1749  Id = SystemCallNumber & SERVICE_NUMBER_MASK;
1750 
1751  /* Get descriptor table */
1752  DescriptorTable = (PVOID)((ULONG_PTR)Thread->ServiceTable + Offset);
1753 
1754  /* Validate the system call number */
1755  if (__builtin_expect(Id >= DescriptorTable->Limit, 0))
1756  {
1757  /* Check if this is a GUI call */
1758  if (!(Offset & SERVICE_TABLE_TEST))
1759  {
1760  /* Fail the call */
1762  goto ExitCall;
1763  }
1764 
1765  /* Convert us to a GUI thread -- must wrap in ASM to get new EBP */
1766  Status = KiConvertToGuiThread();
1767 
1768  /* Reload trap frame and descriptor table pointer from new stack */
1769  TrapFrame = *(volatile PVOID*)&Thread->TrapFrame;
1770  DescriptorTable = (PVOID)(*(volatile ULONG_PTR*)&Thread->ServiceTable + Offset);
1771 
1772  if (!NT_SUCCESS(Status))
1773  {
1774  /* Set the last error and fail */
1775  goto ExitCall;
1776  }
1777 
1778  /* Validate the system call number again */
1779  if (Id >= DescriptorTable->Limit)
1780  {
1781  /* Fail the call */
1783  goto ExitCall;
1784  }
1785  }
1786 
1787  /* Check if this is a GUI call */
1788  if (__builtin_expect(Offset & SERVICE_TABLE_TEST, 0))
1789  {
1790  /* Get the batch count and flush if necessary */
1791  if (NtCurrentTeb()->GdiBatchCount) KeGdiFlushUserBatch();
1792  }
1793 
1794  /* Increase system call count */
1795  KeGetCurrentPrcb()->KeSystemCalls++;
1796 
1797  /* FIXME: Increase individual counts on debug systems */
1798  //KiIncreaseSystemCallCount(DescriptorTable, Id);
1799 
1800  /* Get stack bytes */
1801  StackBytes = DescriptorTable->Number[Id];
1802 
1803  /* Probe caller stack */
1804  if (__builtin_expect((Arguments < (PVOID)MmUserProbeAddress) && !(KiUserTrap(TrapFrame)), 0))
1805  {
1806  /* Access violation */
1808  }
1809 
1810  /* Call pre-service debug hook */
1811  KiDbgPreServiceHook(SystemCallNumber, Arguments);
1812 
1813  /* Get the handler and make the system call */
1814  Handler = (PVOID)DescriptorTable->Base[Id];
1815  Status = KiSystemCallTrampoline(Handler, Arguments, StackBytes);
1816 
1817  /* Call post-service debug hook */
1818  Status = KiDbgPostServiceHook(SystemCallNumber, Status);
1819 
1820  /* Make sure we're exiting correctly */
1821  KiExitSystemCallDebugChecks(Id, TrapFrame);
1822 
1823  /* Restore the old trap frame */
1824 ExitCall:
1825  Thread->TrapFrame = (PKTRAP_FRAME)TrapFrame->Edx;
1826 
1827  /* Exit from system call */
1828  KiServiceExit(TrapFrame, Status);
1829 }
1830 
1831 VOID
1832 FASTCALL
1834 {
1835  UNIMPLEMENTED;
1836 }
1837 
1838 /*
1839  * @implemented
1840  */
1841 VOID
1842 NTAPI
1844 {
1845  /* We should never see this call happening */
1846  KeBugCheck(MISMATCHED_HAL);
1847 }
1848 
1849 /* EOF */
VOID NTAPI ExpInterlockedPopEntrySListResume(VOID)
ULONG MmUserProbeAddress
Definition: init.c:50
#define CR0_MP
Definition: asm.h:246
DWORD *typedef PVOID
Definition: winlogon.h:52
DECLSPEC_NORETURN VOID __cdecl KiTrap02(VOID)
Definition: traphdlr.c:461
#define FSW_PRECISION
Definition: ketypes.h:170
FORCEINLINE VOID KiEnterV86Trap(IN PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:350
#define IN
Definition: typedefs.h:38
DECLSPEC_NORETURN VOID FASTCALL KiTrap08Handler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:853
#define SERVICE_TABLE_SHIFT
Definition: ketypes.h:71
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define TRUE
Definition: types.h:120
#define TYPE_ALIGNMENT(t)
Definition: ntbasedef.h:117
#define EXCEPTION_NPX_OVERRUN
Definition: asm.h:620
#define STATUS_ILLEGAL_INSTRUCTION
Definition: ntstatus.h:252
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
DECLSPEC_NORETURN VOID FASTCALL KiTrapReturnNoSegmentsRet8(IN PKTRAP_FRAME TrapFrame)
DECLSPEC_NORETURN VOID FASTCALL KiTrapReturnNoSegments(IN PKTRAP_FRAME TrapFrame)
__INTRIN_INLINE unsigned long __readcr2(void)
Definition: intrin_x86.h:1594
DECLSPEC_NORETURN VOID FASTCALL KiTrap0CHandler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:903
FORCEINLINE DECLSPEC_NORETURN VOID KiDispatchException2Args(IN NTSTATUS Code, IN ULONG_PTR Address, IN ULONG P1, IN ULONG P2, IN PKTRAP_FRAME TrapFrame)
Definition: ke.h:674
ULONG_PTR DirectoryTableBase
Definition: ketypes.h:1383
#define __cdecl
Definition: accygwin.h:79
#define I386_ACTIVE_TSS
Definition: ketypes.h:61
USHORT Fs
Definition: ketypes.h:814
#define DbgPrint
Definition: loader.c:26
VOID(FASTCALL * PFAST_SYSTEM_CALL_EXIT)(IN PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:245
FORCEINLINE BOOLEAN KiIsFrameEdited(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:87
DECLSPEC_NORETURN VOID FASTCALL KiTrapReturn(IN PKTRAP_FRAME TrapFrame)
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
USHORT BaseLow
Definition: ketypes.h:334
ULONG CR3
Definition: ketypes.h:795
DECLSPEC_NORETURN VOID FASTCALL KiTrap10Handler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:1428
PVOID ServiceTable
Definition: ketypes.h:1102
VOID __cdecl KiFastCallEntryWithSingleStep(VOID)
#define SERVICE_TABLE_MASK
Definition: ketypes.h:78
unsigned char * PUCHAR
Definition: retypes.h:3
ULONG MXCsr
Definition: ketypes.h:433
USHORT IopmOffset
Definition: ketypes.h:1392
void __cdecl _enable(void)
Definition: intrin_arm.h:373
DECLSPEC_NORETURN VOID FASTCALL KiTrap09Handler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:862
DECLSPEC_NORETURN VOID FASTCALL KiTrap0EHandler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:1199
DECLSPEC_NORETURN VOID FASTCALL KiTrap01Handler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:427
BOOLEAN FASTCALL Ki386HandleOpcodeV86(IN PKTRAP_FRAME TrapFrame)
Definition: v86vdm.c:454
PVOID KeUserPopEntrySListFault
Definition: psmgr.c:18
#define STATUS_SINGLE_STEP
Definition: ntstatus.h:173
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1054
#define DR7_RESERVED_MASK
Definition: asm.h:511
USHORT SegFs
Definition: ketypes.h:366
struct _KIPCR * PKIPCR
FORCEINLINE VOID KiCommonExit(IN PKTRAP_FRAME TrapFrame, BOOLEAN SkipPreviousMode)
Definition: traphdlr.c:96
FORCEINLINE VOID KiHandleDebugRegistersOnTrapEntry(IN PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:256
#define CR0_TS
Definition: asm.h:248
#define STATUS_GUARD_PAGE_VIOLATION
Definition: ntstatus.h:170
USHORT Cs
Definition: ketypes.h:808
#define EXCEPTION_NONCONTINUABLE
Definition: rtltypes.h:150
USHORT Es
Definition: ketypes.h:806
#define KGDT_R0_CODE
Definition: ketypes.h:74
DECLSPEC_NORETURN VOID NTAPI KiDispatchExceptionFromTrapFrame(IN NTSTATUS Code, IN ULONG Flags, IN ULONG_PTR Address, IN ULONG ParameterCount, IN ULONG_PTR Parameter1, IN ULONG_PTR Parameter2, IN ULONG_PTR Parameter3, IN PKTRAP_FRAME TrapFrame)
Definition: exp.c:1100
$ULONG LowPart
Definition: ntbasedef.h:568
PKTRAP_FRAME TrapFrame
Definition: ketypes.h:1181
ULONG HardwareSegSs
Definition: ketypes.h:269
_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 STATUS_FLOAT_DIVIDE_BY_ZERO
Definition: ntstatus.h:364
ULONG Esi
Definition: ketypes.h:261
#define STATUS_FLOAT_INEXACT_RESULT
Definition: ntstatus.h:365
#define SERVICE_NUMBER_MASK
Definition: ketypes.h:83
#define FASTCALL
Definition: nt_native.h:50
DECLSPEC_NORETURN VOID FASTCALL KiTrap0DHandler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:916
#define NPX_STATE_NOT_LOADED
Definition: asm.h:262
#define DECLSPEC_NORETURN
Definition: ntbasedef.h:168
VOID NTAPI HalHandleNMI(IN PVOID NmiInfo)
Definition: misc.c:53
DECLSPEC_NORETURN VOID FASTCALL KiTrap00Handler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:407
#define KeGetPcr()
Definition: ke.h:25
ULONG KeI386FxsrPresent
Definition: cpu.c:31
USHORT LDT
Definition: ketypes.h:818
PVOID ExceptionAddress
Definition: compat.h:199
ULONG Edi
Definition: ketypes.h:260
#define EFLAGS_V86_MASK
Definition: ketypes.h:129
DECLSPEC_NORETURN VOID FASTCALL KiTrap13Handler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:1469
DWORD Id
#define STATUS_FLOAT_STACK_CHECK
Definition: ntstatus.h:368
struct _KGDTENTRY::@2168::@2170 Bits
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define STATUS_FLOAT_UNDERFLOW
Definition: ntstatus.h:369
VOID FASTCALL KiGetTickCountHandler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:1599
DECLSPEC_NORETURN VOID FASTCALL KiSystemCallReturn(IN PKTRAP_FRAME TrapFrame)
DWORD ExceptionCode
Definition: compat.h:196
VOID NTAPI KdSetOwedBreakpoints(VOID)
Definition: kdbreak.c:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
USHORT Ds
Definition: ketypes.h:812
#define KGDT_NMI_TSS
Definition: ketypes.h:83
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define KGDT_LDT
Definition: ketypes.h:81
union _FX_SAVE_AREA::@2175 U
ULONG Edx
Definition: ketypes.h:800
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1456
ULONG Eax
Definition: ketypes.h:256
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define STATUS_FLOAT_OVERFLOW
Definition: ntstatus.h:367
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
USHORT SegGs
Definition: ketypes.h:367
#define FALSE
Definition: types.h:117
Definition: Header.h:8
#define EFLAGS_NESTED_TASK
Definition: ketypes.h:128
#define STATUS_INTEGER_OVERFLOW
Definition: ntstatus.h:371
#define PCR
Definition: ke.h:8
DECLSPEC_NORETURN VOID FASTCALL KiDebugHandler(IN PKTRAP_FRAME TrapFrame, IN ULONG Parameter1, IN ULONG Parameter2, IN ULONG Parameter3)
Definition: traphdlr.c:219
#define STATUS_STACK_BUFFER_OVERRUN
Definition: ntstatus.h:932
KAPC_STATE ApcState
Definition: ketypes.h:969
#define _SEH2_END
Definition: pseh2_64.h:7
USHORT SegEs
Definition: ketypes.h:365
#define STATUS_INTEGER_DIVIDE_BY_ZERO
Definition: ntstatus.h:370
FORCEINLINE DECLSPEC_NORETURN VOID KiExitV86Trap(IN PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:304
DECLSPEC_NORETURN VOID NTAPI KeBugCheckWithTf(ULONG BugCheckCode, ULONG_PTR BugCheckParameter1, ULONG_PTR BugCheckParameter2, ULONG_PTR BugCheckParameter3, ULONG_PTR BugCheckParameter4, PKTRAP_FRAME Tf)
#define PsGetCurrentProcess
Definition: psfuncs.h:17
union _KGDTENTRY::@2168 HighWord
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define RPL_MASK
Definition: ketypes.h:69
NTSTATUS NTAPI KiConvertToGuiThread(VOID)
DECLSPEC_NORETURN VOID FASTCALL KiDebugServiceHandler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:1660
smooth NULL
Definition: ftsmooth.c:557
__INTRIN_INLINE void __writecr0(unsigned int Data)
Definition: intrin_x86.h:1567
#define STATUS_BREAKPOINT
Definition: ntstatus.h:172
ULONG DbgEbp
Definition: ketypes.h:239
USHORT SegCs
Definition: ketypes.h:380
#define FORCEINLINE
Definition: ntbasedef.h:213
Definition: ketypes.h:787
#define SERVICE_TABLE_TEST
Definition: ketypes.h:90
void DPRINT(...)
Definition: polytest.cpp:61
ULONG Cr0NpxState
Definition: ketypes.h:449
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1469
#define KGDT_R3_DATA
Definition: ketypes.h:77
#define EXCEPTION_BOUND_CHECK
Definition: asm.h:616
#define FSW_OVERFLOW
Definition: ketypes.h:168
DECLSPEC_NORETURN VOID FASTCALL KiTrap0AHandler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:875
struct _ULARGE_INTEGER * PULARGE_INTEGER
Definition: drive.c:28
VOID __cdecl CopyParams(VOID)
VOID NTAPI ExpInterlockedPopEntrySListFault(VOID)
UCHAR PreviousMode
Definition: ketypes.h:1216
DECLSPEC_NORETURN VOID FASTCALL KiRaiseAssertionHandler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:1643
Definition: utils.h:160
PFAST_SYSTEM_CALL_EXIT KiFastCallExitHandler
Definition: traphdlr.c:56
FORCEINLINE PFX_SAVE_AREA KiGetThreadNpxArea(IN PKTHREAD Thread)
Definition: ke.h:582
FORCEINLINE VOID KiCheckForApcDelivery(IN PKTRAP_FRAME TrapFrame)
Definition: ke.h:759
#define STATUS_ASSERTION_FAILURE
Definition: ntstatus.h:946
ULONG Ebx
Definition: ketypes.h:801
unsigned char BOOLEAN
$ULONG HighPart
Definition: ntbasedef.h:569
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:201
struct _KGDTENTRY::@2168::@2169 Bytes
if(!(yy_init))
Definition: macro.lex.yy.c:704
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
USHORT Ss0
Definition: ketypes.h:792
ULONG Eip
Definition: ketypes.h:796
char CCHAR
Definition: typedefs.h:50
ULONG Ecx
Definition: ketypes.h:799
ULONG HardwareEsp
Definition: ketypes.h:268
#define for
Definition: utility.h:88
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
DECLSPEC_NORETURN VOID FASTCALL KiTrap03Handler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:608
BOOL Error
Definition: chkdsk.c:63
DECLSPEC_NORETURN VOID FASTCALL KiSystemFatalException(IN ULONG ExceptionCode, IN PKTRAP_FRAME TrapFrame)
Definition: except.c:402
FORCEINLINE BOOLEAN KiV86Trap(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:79
FORCEINLINE VOID KiDbgPreServiceHook(ULONG SystemCallNumber, PULONG_PTR Arguments)
Definition: traphdlr.c:1675
struct _EXCEPTION_REGISTRATION_RECORD FAR * ExceptionList
Definition: ketypes.h:258
#define KiFillTrapFrameDebug(x)
Definition: trap_x.h:189
USHORT IoMapBase
Definition: ketypes.h:821
ULONG EFlags
Definition: ketypes.h:797
DECLSPEC_NORETURN VOID FASTCALL KiTrap11Handler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:1456
#define EXCEPTION_RESERVED_TRAP
Definition: asm.h:625
#define PKTSS
Definition: ketypes.h:921
FORCEINLINE DECLSPEC_NORETURN VOID KiIret(VOID)
Definition: ke.h:834
#define EXCEPTION_INVALID_TSS
Definition: asm.h:621
unsigned char UCHAR
Definition: xmlstorage.h:181
#define EXCEPTION_SEGMENT_NOT_PRESENT
Definition: asm.h:622
#define EXCEPTION_NMI
Definition: asm.h:614
#define FSW_STACK_FAULT
Definition: ketypes.h:171
#define EFLAGS_IOPL
Definition: cpu.c:17
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
NTSTATUS NTAPI MmAccessFault(IN BOOLEAN StoreInstruction, IN PVOID Address, IN KPROCESSOR_MODE Mode, IN PVOID TrapInformation)
Definition: mmfault.c:204
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1451
VOID FASTCALL Ki386BiosCallReturnAddress(IN PKTRAP_FRAME TrapFrame)
DECLSPEC_NORETURN VOID FASTCALL KiTrap0BHandler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:890
#define FSW_INVALID_OPERATION
Definition: ketypes.h:165
FORCEINLINE BOOLEAN KiVdmTrap(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:70
DECLSPEC_NORETURN VOID FASTCALL KiTrap04Handler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:620
USHORT SegDs
Definition: ketypes.h:364
#define STATUS_PRIVILEGED_INSTRUCTION
Definition: ntstatus.h:372
DECLSPEC_NORETURN VOID FASTCALL KiTrap07Handler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:744
__INTRIN_INLINE unsigned long __readcr0(void)
Definition: intrin_x86.h:1587
DECLSPEC_NORETURN VOID FASTCALL KiTrap0FHandler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:1415
#define EFLAGS_TF
Definition: ketypes.h:125
#define STATUS_FLOAT_MULTIPLE_TRAPS
Definition: ntstatus.h:794
UCHAR NpxState
Definition: ketypes.h:998
ULONG Ecx
Definition: ketypes.h:255
ULONG Eip
Definition: ketypes.h:265
ULONG Eax
Definition: ketypes.h:798
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER Handler
Definition: acpixf.h:658
Status
Definition: gdiplustypes.h:24
VOID FASTCALL KiCheckForSListAddress(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:1833
struct _EXCEPTION_RECORD * ExceptionRecord
Definition: compat.h:198
ULONG PreviousPreviousMode
Definition: ketypes.h:257
PVOID FrRestore
VOID __cdecl ReadBatch(VOID)
FORCEINLINE DECLSPEC_NORETURN VOID KiDispatchException0Args(IN NTSTATUS Code, IN ULONG_PTR Address, IN PKTRAP_FRAME TrapFrame)
Definition: ke.h:645
#define HIGH_LEVEL
Definition: env_spec_w32.h:703
ULONG DbgEip
Definition: ketypes.h:240
VOID FASTCALL KiRaiseSecurityCheckFailureHandler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:1555
UCHAR KiTrapIoTable[]
Definition: traphdlr.c:40
LONG NTSTATUS
Definition: DriverTester.h:11
ULONG Ebx
Definition: ketypes.h:262
#define EXCEPTION_CHAIN_END
Definition: rtltypes.h:63
FORCEINLINE DECLSPEC_NORETURN VOID KiDispatchException1Args(IN NTSTATUS Code, IN ULONG_PTR Address, IN ULONG P1, IN PKTRAP_FRAME TrapFrame)
Definition: ke.h:659
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
ULONG Esp0
Definition: ketypes.h:791
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
#define EXCEPTION_STACK_FAULT
Definition: asm.h:623
unsigned short USHORT
Definition: pedump.c:61
BOOLEAN NTAPI VdmDispatchPageFault(_In_ PKTRAP_FRAME TrapFrame)
Definition: vdmexec.c:367
ULONG Edi
Definition: ketypes.h:805
ULONG Ebp
Definition: ketypes.h:803
#define FSW_UNDERFLOW
Definition: ketypes.h:169
PGDI_BATCHFLUSH_ROUTINE KeGdiFlushUserBatch
Definition: win32.c:20
#define _SEH2_TRY
Definition: pseh2_64.h:5
DECLSPEC_NORETURN VOID FASTCALL KiTrap06Handler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:663
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
BOOLEAN NTAPI KiHandleNmi(VOID)
Definition: bug.c:1206
#define KiExitTrapDebugChecks(x, y)
Definition: trap_x.h:188
#define EXCEPTION_ALIGNMENT_CHECK
Definition: asm.h:627
VOID NTAPI KiSaveProcessorState(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame)
Definition: cpu.c:1143
#define STATUS_STACK_OVERFLOW
Definition: ntstatus.h:475
FORCEINLINE VOID KiExitSystemCallDebugChecks(IN ULONG SystemCall, IN PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:194
BOOLEAN NTAPI VdmDispatchBop(IN PKTRAP_FRAME TrapFrame)
Definition: vdmexec.c:313
#define I386_TSS
Definition: ketypes.h:60
#define DPRINT1
Definition: precomp.h:8
#define UNIMPLEMENTED_FATAL(...)
Definition: debug.h:243
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
FORCEINLINE VOID KiHandleDebugRegistersOnTrapExit(PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:283
#define FSW_ZERO_DIVIDE
Definition: ketypes.h:167
VOID NTAPI Kei386EoiHelper(VOID)
Definition: traphdlr.c:1843
ULONG Esi
Definition: ketypes.h:804
FORCEINLINE VOID KiEnterTrap(IN PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:399
void __cdecl _disable(void)
Definition: intrin_arm.h:365
#define EXCEPTION_GP_FAULT
Definition: asm.h:624
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_INVALID_SYSTEM_SERVICE
Definition: ntstatus.h:251
#define UNIMPLEMENTED
Definition: debug.h:114
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
DWORD ExceptionFlags
Definition: compat.h:197
uint32_t * PULONG_PTR
Definition: typedefs.h:63
#define NPX_STATE_LOADED
Definition: asm.h:263
PVOID KeUserPopEntrySListResume
Definition: psmgr.c:19
#define __builtin_expect(x, y)
Definition: compiler.h:178
DECLSPEC_NORETURN VOID FASTCALL KiServiceExit(IN PKTRAP_FRAME TrapFrame, IN NTSTATUS Status)
Definition: traphdlr.c:150
#define FRAME_EDITED
Definition: ke.h:40
DECLSPEC_NORETURN VOID FASTCALL KiServiceExit2(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:189
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
struct _KTRAP_FRAME * PKTRAP_FRAME
#define STATUS_IN_PAGE_ERROR
Definition: ntstatus.h:229
DECLSPEC_NORETURN VOID FASTCALL KiNpxHandler(IN PKTRAP_FRAME TrapFrame, IN PKTHREAD Thread, IN PFX_SAVE_AREA SaveArea)
Definition: traphdlr.c:244
#define STATUS_FLOAT_INVALID_OPERATION
Definition: ntstatus.h:366
DWORD NumberParameters
Definition: compat.h:200
#define KeGetCurrentThread
Definition: hal.h:44
UCHAR KiTrapPrefixTable[]
Definition: traphdlr.c:25
USHORT Gs
Definition: ketypes.h:816
VOID __cdecl KiFastCallEntry(VOID)
#define EXCEPTION_DOUBLE_FAULT
Definition: asm.h:619
VOID FASTCALL Ke386LoadFpuState(IN PFX_SAVE_AREA SaveArea)
FXSAVE_FORMAT FxArea
Definition: ketypes.h:446
FORCEINLINE ULONG_PTR KiDbgPostServiceHook(ULONG SystemCallNumber, ULONG_PTR Result)
Definition: traphdlr.c:1685
VOID FASTCALL KiCallbackReturnHandler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:1616
#define STATUS_ARRAY_BOUNDS_EXCEEDED
Definition: ntstatus.h:362
#define KeGetTrapFrame(Thread)
Definition: ke.h:121
#define APC_LEVEL
Definition: env_spec_w32.h:695
DECLSPEC_NORETURN VOID FASTCALL KiTrap05Handler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:640
ULONG ErrCode
Definition: ketypes.h:264
ULONG EFlags
Definition: ketypes.h:384
#define KI_EXCEPTION_ACCESS_VIOLATION
Definition: ketypes.h:177
ULONG Edx
Definition: ketypes.h:254
ULONG Ebp
Definition: ketypes.h:263
#define FSW_DENORMAL
Definition: ketypes.h:166
#define BREAKPOINT_BREAK
Definition: kdtypes.h:50
#define CR0_EM
Definition: asm.h:247
#define STATUS_INVALID_LOCK_SEQUENCE
Definition: ntstatus.h:253
BOOLEAN FORCEINLINE KiUserTrap(IN PKTRAP_FRAME TrapFrame)
Definition: ke.h:281
DECLSPEC_NORETURN VOID FASTCALL KiSystemServiceHandler(IN PKTRAP_FRAME TrapFrame, IN PVOID Arguments)
Definition: traphdlr.c:1697
DECLSPEC_NORETURN VOID FASTCALL KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:126
DECLSPEC_NORETURN VOID FASTCALL KiSystemCallTrapReturn(IN PKTRAP_FRAME TrapFrame)
DECLSPEC_NORETURN VOID FASTCALL KiEditedTrapReturn(IN PKTRAP_FRAME TrapFrame)
NTSYSAPI NTSTATUS NTAPI NtCallbackReturn(IN PVOID Result OPTIONAL, IN ULONG ResultLength, IN NTSTATUS Status)
Definition: stubs.c:413
#define EFLAGS_INTERRUPT_MASK
Definition: ketypes.h:126