ReactOS 0.4.15-dev-8102-g108db8f
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
20extern 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_)
58PKDBG_PRESERVICEHOOK KeWin32PreServiceHook = NULL;
59PKDBG_POSTSERVICEHOOK KeWin32PostServiceHook = NULL;
60#endif
61#if DBG
62BOOLEAN StopChecking = FALSE;
63#endif
64
65
66/* TRAP EXIT CODE *************************************************************/
67
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
80{
81 /* Check if the V8086 flag is on */
82 return ((TrapFrame->EFlags & EFLAGS_V86_MASK) != 0);
83}
84
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
95VOID
96KiCommonExit(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
124VOID
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 */
145}
146
148VOID
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);
179 }
180 }
181
182 /* Exit to kernel mode */
183 KiSystemCallReturn(TrapFrame);
184}
185
187VOID
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 */
211}
212
213
214/* TRAP HANDLERS **************************************************************/
215
217VOID
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. Fix EIP in case its a break breakpoint (sic) */
232 0,
233 TrapFrame->Eip - (Parameter1 == BREAKPOINT_BREAK),
234 3,
235 Parameter1,
236 Parameter2,
237 Parameter3,
238 TrapFrame);
239}
240
242VOID
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 */
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 */
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 */
322 Error &= ~Mask;
323
324 /* Check for 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 */
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 */
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
405VOID
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
425VOID
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
458VOID
461{
462 PKTSS Tss, NmiTss;
465 PKGDTENTRY TssGdt;
466 KTRAP_FRAME TrapFrame;
468
469 /*
470 * In some sort of strange recursion case, we might end up here with the IF
471 * flag incorrectly on the interrupt frame -- during a normal NMI this would
472 * normally already be set.
473 *
474 * For sanity's sake, make sure interrupts are disabled for sure.
475 * NMIs will already be since the CPU does it for us.
476 */
477 _disable();
478
479 /* Get the current TSS, thread, and process */
480 Tss = KeGetPcr()->TSS;
481 Thread = ((PKIPCR)KeGetPcr())->PrcbData.CurrentThread;
482 Process = Thread->ApcState.Process;
483
484 /* Save data usually not present in the TSS */
485 Tss->CR3 = Process->DirectoryTableBase[0];
486 Tss->IoMapBase = Process->IopmOffset;
487 Tss->LDT = Process->LdtDescriptor.LimitLow ? KGDT_LDT : 0;
488
489 /* Now get the base address of the NMI TSS */
490 TssGdt = &((PKIPCR)KeGetPcr())->GDT[KGDT_NMI_TSS / sizeof(KGDTENTRY)];
491 NmiTss = (PKTSS)(ULONG_PTR)(TssGdt->BaseLow |
492 TssGdt->HighWord.Bytes.BaseMid << 16 |
493 TssGdt->HighWord.Bytes.BaseHi << 24);
494
495 /*
496 * Switch to it and activate it, masking off the nested flag.
497 *
498 * Note that in reality, we are already on the NMI TSS -- we just
499 * need to update the PCR to reflect this.
500 */
501 KeGetPcr()->TSS = NmiTss;
503 TssGdt->HighWord.Bits.Dpl = 0;
504 TssGdt->HighWord.Bits.Pres = 1;
505 TssGdt->HighWord.Bits.Type = I386_TSS;
506
507 /*
508 * Now build the trap frame based on the original TSS.
509 *
510 * The CPU does a hardware "Context switch" / task switch of sorts
511 * and so it takes care of saving our context in the normal TSS.
512 *
513 * We just have to go get the values...
514 */
515 RtlZeroMemory(&TrapFrame, sizeof(KTRAP_FRAME));
516 TrapFrame.HardwareSegSs = Tss->Ss0;
517 TrapFrame.HardwareEsp = Tss->Esp0;
518 TrapFrame.EFlags = Tss->EFlags;
519 TrapFrame.SegCs = Tss->Cs;
520 TrapFrame.Eip = Tss->Eip;
521 TrapFrame.Ebp = Tss->Ebp;
522 TrapFrame.Ebx = Tss->Ebx;
523 TrapFrame.Esi = Tss->Esi;
524 TrapFrame.Edi = Tss->Edi;
525 TrapFrame.SegFs = Tss->Fs;
526 TrapFrame.ExceptionList = KeGetPcr()->NtTib.ExceptionList;
527 TrapFrame.PreviousPreviousMode = (ULONG)-1;
528 TrapFrame.Eax = Tss->Eax;
529 TrapFrame.Ecx = Tss->Ecx;
530 TrapFrame.Edx = Tss->Edx;
531 TrapFrame.SegDs = Tss->Ds;
532 TrapFrame.SegEs = Tss->Es;
533 TrapFrame.SegGs = Tss->Gs;
534 TrapFrame.DbgEip = Tss->Eip;
535 TrapFrame.DbgEbp = Tss->Ebp;
536
537 /* Store the trap frame in the KPRCB */
538 KiSaveProcessorState(&TrapFrame, NULL);
539
540 /* Call any registered NMI handlers and see if they handled it or not */
541 if (!KiHandleNmi())
542 {
543 /*
544 * They did not, so call the platform HAL routine to bugcheck the system
545 *
546 * Make sure the HAL believes it's running at HIGH IRQL... we can't use
547 * the normal APIs here as playing with the IRQL could change the system
548 * state.
549 */
550 OldIrql = KeGetPcr()->Irql;
551 KeGetPcr()->Irql = HIGH_LEVEL;
553 KeGetPcr()->Irql = OldIrql;
554 }
555
556 /*
557 * Although the CPU disabled NMIs, we just did a BIOS call, which could've
558 * totally changed things.
559 *
560 * We have to make sure we're still in our original NMI -- a nested NMI
561 * will point back to the NMI TSS, and in that case we're hosed.
562 */
563 if (KeGetPcr()->TSS->Backlink == KGDT_NMI_TSS)
564 {
565 /* Unhandled: crash the system */
567 }
568
569 /* Restore original TSS */
570 KeGetPcr()->TSS = Tss;
571
572 /* Set it back to busy */
573 TssGdt->HighWord.Bits.Dpl = 0;
574 TssGdt->HighWord.Bits.Pres = 1;
575 TssGdt->HighWord.Bits.Type = I386_ACTIVE_TSS;
576
577 /* Restore nested flag */
579
580 /* Handled, return from interrupt */
581}
582
584VOID
587{
588 /* Save trap frame */
589 KiEnterTrap(TrapFrame);
590
591 /* Continue with the common handler */
592 KiDebugHandler(TrapFrame, BREAKPOINT_BREAK, 0, 0);
593}
594
596VOID
599{
600 /* Save trap frame */
601 KiEnterTrap(TrapFrame);
602
603 /* Check for VDM trap */
604 ASSERT(KiVdmTrap(TrapFrame) == FALSE);
605
606 /* Enable interrupts */
607 _enable();
608
609 /* Dispatch the exception */
611 TrapFrame->Eip - 1,
612 TrapFrame);
613}
614
616VOID
619{
620 /* Save trap frame */
621 KiEnterTrap(TrapFrame);
622
623 /* Check for VDM trap */
624 ASSERT(KiVdmTrap(TrapFrame) == FALSE);
625
626 /* Check for kernel-mode fault */
627 if (!KiUserTrap(TrapFrame)) KiSystemFatalException(EXCEPTION_BOUND_CHECK, TrapFrame);
628
629 /* Enable interrupts */
630 _enable();
631
632 /* Dispatch the exception */
634 TrapFrame->Eip,
635 TrapFrame);
636}
637
639VOID
642{
644 ULONG i;
646
647 /* Check for V86 GPF */
648 if (__builtin_expect(KiV86Trap(TrapFrame), 1))
649 {
650 /* Enter V86 trap */
651 KiEnterV86Trap(TrapFrame);
652
653 /* Must be a VDM process */
654 if (__builtin_expect(!PsGetCurrentProcess()->VdmObjects, 0))
655 {
656 /* Enable interrupts */
657 _enable();
658
659 /* Setup illegal instruction fault */
661 TrapFrame->Eip,
662 TrapFrame);
663 }
664
665 /* Go to APC level */
667 _enable();
668
669 /* Check for BOP */
670 if (!VdmDispatchBop(TrapFrame))
671 {
672 /* Should only happen in VDM mode */
674 }
675
676 /* Bring IRQL back */
678 _disable();
679
680 /* Do a quick V86 exit if possible */
681 KiExitV86Trap(TrapFrame);
682 }
683
684 /* Save trap frame */
685 KiEnterTrap(TrapFrame);
686
687 /* Enable interrupts */
688 Instruction = (PUCHAR)TrapFrame->Eip;
689 _enable();
690
691 /* Check for user trap */
692 if (KiUserTrap(TrapFrame))
693 {
694 /* FIXME: Use SEH */
695
696 /* Scan next 4 opcodes */
697 for (i = 0; i < 4; i++)
698 {
699 /* Check for LOCK instruction */
700 if (Instruction[i] == 0xF0)
701 {
702 /* Send invalid lock sequence exception */
704 TrapFrame->Eip,
705 TrapFrame);
706 }
707 }
708
709 /* FIXME: SEH ends here */
710 }
711
712 /* Kernel-mode or user-mode fault (but not LOCK) */
714 TrapFrame->Eip,
715 TrapFrame);
716
717}
718
720VOID
723{
724 PKTHREAD Thread, NpxThread;
725 PFX_SAVE_AREA SaveArea, NpxSaveArea;
726 ULONG Cr0;
727
728 /* Save trap frame */
729 KiEnterTrap(TrapFrame);
730
731 /* Try to handle NPX delay load */
732 for (;;)
733 {
734 /* Get the current thread */
736
737 /* Get the NPX frame */
738 SaveArea = KiGetThreadNpxArea(Thread);
739
740 /* Check if emulation is enabled */
741 if (SaveArea->Cr0NpxState & CR0_EM)
742 {
743 /* Not implemented */
745 }
746
747 /* Save CR0 and check NPX state */
748 Cr0 = __readcr0();
749 if (Thread->NpxState != NPX_STATE_LOADED)
750 {
751 /* Update CR0 */
752 Cr0 &= ~(CR0_MP | CR0_EM | CR0_TS);
753 __writecr0(Cr0);
754
755 /* Get the NPX thread */
756 NpxThread = KeGetCurrentPrcb()->NpxThread;
757 if (NpxThread)
758 {
759 /* Get the NPX frame */
760 NpxSaveArea = KiGetThreadNpxArea(NpxThread);
761
762 /* Save FPU state */
763 Ke386SaveFpuState(NpxSaveArea);
764
765 /* Update NPX state */
766 NpxThread->NpxState = NPX_STATE_NOT_LOADED;
767 }
768
769 /* Load FPU state */
770 Ke386LoadFpuState(SaveArea);
771
772 /* Update NPX state */
773 Thread->NpxState = NPX_STATE_LOADED;
774 KeGetCurrentPrcb()->NpxThread = Thread;
775
776 /* Enable interrupts */
777 _enable();
778
779 /* Check if CR0 needs to be reloaded due to context switch */
780 if (!SaveArea->Cr0NpxState) KiEoiHelper(TrapFrame);
781
782 /* Otherwise, we need to reload CR0, disable interrupts */
783 _disable();
784
785 /* Reload CR0 */
786 Cr0 = __readcr0();
787 Cr0 |= SaveArea->Cr0NpxState;
788 __writecr0(Cr0);
789
790 /* Now restore interrupts and check for TS */
791 _enable();
792 if (Cr0 & CR0_TS) KiEoiHelper(TrapFrame);
793
794 /* We're still here -- clear TS and try again */
796 _disable();
797 }
798 else
799 {
800 /* This is an actual fault, not a lack of FPU state */
801 break;
802 }
803 }
804
805 /* TS should not be set */
806 if (Cr0 & CR0_TS)
807 {
808 /*
809 * If it's incorrectly set, then maybe the state is actually still valid
810 * but we could have lost track of that due to a BIOS call.
811 * Make sure MP is still set, which should verify the theory.
812 */
813 if (Cr0 & CR0_MP)
814 {
815 /* Indeed, the state is actually still valid, so clear TS */
817 KiEoiHelper(TrapFrame);
818 }
819
820 /* Otherwise, something strange is going on */
821 KeBugCheckWithTf(TRAP_CAUSE_UNKNOWN, 2, Cr0, 0, 0, TrapFrame);
822 }
823
824 /* It's not a delayed load, so process this trap as an NPX fault */
825 KiNpxHandler(TrapFrame, Thread, SaveArea);
826}
827
829VOID
832{
833 PKTSS Tss, DfTss;
836 PKGDTENTRY TssGdt;
837
838 /* For sanity's sake, make sure interrupts are disabled */
839 _disable();
840
841 /* Get the current TSS, thread, and process */
842 Tss = KeGetPcr()->TSS;
843 Thread = ((PKIPCR)KeGetPcr())->PrcbData.CurrentThread;
844 Process = Thread->ApcState.Process;
845
846 /* Save data usually not present in the TSS */
847 Tss->CR3 = Process->DirectoryTableBase[0];
848 Tss->IoMapBase = Process->IopmOffset;
849 Tss->LDT = Process->LdtDescriptor.LimitLow ? KGDT_LDT : 0;
850
851 /* Now get the base address of the double-fault TSS */
852 TssGdt = &((PKIPCR)KeGetPcr())->GDT[KGDT_DF_TSS / sizeof(KGDTENTRY)];
853 DfTss = (PKTSS)(ULONG_PTR)(TssGdt->BaseLow |
854 TssGdt->HighWord.Bytes.BaseMid << 16 |
855 TssGdt->HighWord.Bytes.BaseHi << 24);
856
857 /*
858 * Switch to it and activate it, masking off the nested flag.
859 *
860 * Note that in reality, we are already on the double-fault TSS
861 * -- we just need to update the PCR to reflect this.
862 */
863 KeGetPcr()->TSS = DfTss;
865 TssGdt->HighWord.Bits.Dpl = 0;
866 TssGdt->HighWord.Bits.Pres = 1;
867 // TssGdt->HighWord.Bits.Type &= ~0x2; /* I386_ACTIVE_TSS --> I386_TSS */
868 TssGdt->HighWord.Bits.Type = I386_TSS; // Busy bit cleared in the TSS selector.
869
870 /* Bugcheck the system */
871 KeBugCheckWithTf(UNEXPECTED_KERNEL_MODE_TRAP,
873 (ULONG_PTR)Tss,
874 0,
875 0,
876 NULL);
877}
878
880VOID
883{
884 /* Save trap frame */
885 KiEnterTrap(TrapFrame);
886
887 /* Enable interrupts and kill the system */
888 _enable();
890}
891
893VOID
896{
897 /* Save trap frame */
898 KiEnterTrap(TrapFrame);
899
900 /* Check for VDM trap */
901 ASSERT(KiVdmTrap(TrapFrame) == FALSE);
902
903 /* Kill the system */
905}
906
908VOID
911{
912 /* Save trap frame */
913 KiEnterTrap(TrapFrame);
914
915 /* FIXME: Kill the system */
918}
919
921VOID
924{
925 /* Save trap frame */
926 KiEnterTrap(TrapFrame);
927
928 /* FIXME: Kill the system */
931}
932
933/* DECLSPEC_NORETURN VOID FASTCALL KiTrap0DHandler(IN PKTRAP_FRAME); */
935
937VOID
940{
941 ULONG i, j, Iopl;
942 BOOLEAN Privileged = FALSE;
943 PUCHAR Instructions;
944 UCHAR Instruction = 0;
946
947 /* Check for V86 GPF */
948 if (__builtin_expect(KiV86Trap(TrapFrame), 1))
949 {
950 /* Enter V86 trap */
951 KiEnterV86Trap(TrapFrame);
952
953 /* Must be a VDM process */
954 if (__builtin_expect(!PsGetCurrentProcess()->VdmObjects, 0))
955 {
956 /* Enable interrupts */
957 _enable();
958
959 /* Setup illegal instruction fault */
961 TrapFrame->Eip,
962 TrapFrame);
963 }
964
965 /* Go to APC level */
967 _enable();
968
969 /* Handle the V86 opcode */
970 if (__builtin_expect(Ki386HandleOpcodeV86(TrapFrame) == 0xFF, 0))
971 {
972 /* Should only happen in VDM mode */
974 }
975
976 /* Bring IRQL back */
978 _disable();
979
980 /* Do a quick V86 exit if possible */
981 KiExitV86Trap(TrapFrame);
982 }
983
984 /* Save trap frame */
985 KiEnterTrap(TrapFrame);
986
987 /* Check for user-mode GPF */
988 if (KiUserTrap(TrapFrame))
989 {
990 /* Should not be VDM */
991 ASSERT(KiVdmTrap(TrapFrame) == FALSE);
992
993 /* Enable interrupts and check error code */
994 _enable();
995 if (!TrapFrame->ErrCode)
996 {
997 /* FIXME: Use SEH */
998 Instructions = (PUCHAR)TrapFrame->Eip;
999
1000 /* Scan next 15 bytes */
1001 for (i = 0; i < 15; i++)
1002 {
1003 /* Skip prefix instructions */
1004 for (j = 0; j < sizeof(KiTrapPrefixTable); j++)
1005 {
1006 /* Is this a prefix instruction? */
1007 if (Instructions[i] == KiTrapPrefixTable[j])
1008 {
1009 /* Stop looking */
1010 break;
1011 }
1012 }
1013
1014 /* Is this NOT any prefix instruction? */
1015 if (j == sizeof(KiTrapPrefixTable))
1016 {
1017 /* We can go ahead and handle the fault now */
1018 Instruction = Instructions[i];
1019 break;
1020 }
1021 }
1022
1023 /* If all we found was prefixes, then this instruction is too long */
1024 if (i == 15)
1025 {
1026 /* Setup illegal instruction fault */
1028 TrapFrame->Eip,
1029 TrapFrame);
1030 }
1031
1032 /* Check for privileged instructions */
1033 DPRINT("Instruction (%lu) at fault: %lx %lx %lx %lx\n",
1034 i,
1035 Instructions[i],
1036 Instructions[i + 1],
1037 Instructions[i + 2],
1038 Instructions[i + 3]);
1039 if (Instruction == 0xF4) // HLT
1040 {
1041 /* HLT is privileged */
1042 Privileged = TRUE;
1043 }
1044 else if (Instruction == 0x0F)
1045 {
1046 /* Test if it's any of the privileged two-byte opcodes */
1047 if (((Instructions[i + 1] == 0x00) && // LLDT or LTR
1048 (((Instructions[i + 2] & 0x38) == 0x10) || // LLDT
1049 (Instructions[i + 2] == 0x18))) || // LTR
1050 ((Instructions[i + 1] == 0x01) && // LGDT or LIDT or LMSW
1051 (((Instructions[i + 2] & 0x38) == 0x10) || // LGDT
1052 (Instructions[i + 2] == 0x18) || // LIDT
1053 (Instructions[i + 2] == 0x30))) || // LMSW
1054 (Instructions[i + 1] == 0x08) || // INVD
1055 (Instructions[i + 1] == 0x09) || // WBINVD
1056 (Instructions[i + 1] == 0x35) || // SYSEXIT
1057 (Instructions[i + 1] == 0x21) || // MOV DR, XXX
1058 (Instructions[i + 1] == 0x06) || // CLTS
1059 (Instructions[i + 1] == 0x20) || // MOV CR, XXX
1060 (Instructions[i + 1] == 0x22) || // MOV XXX, CR
1061 (Instructions[i + 1] == 0x23) || // MOV YYY, DR
1062 (Instructions[i + 1] == 0x30) || // WRMSR
1063 (Instructions[i + 1] == 0x33)) // RDPMC
1064 // INVLPG, INVLPGA, SYSRET
1065 {
1066 /* These are all privileged */
1067 Privileged = TRUE;
1068 }
1069 }
1070 else
1071 {
1072 /* Get the IOPL and compare with the RPL mask */
1073 Iopl = (TrapFrame->EFlags & EFLAGS_IOPL) >> 12;
1074 if ((TrapFrame->SegCs & RPL_MASK) > Iopl)
1075 {
1076 /* I/O privilege error -- check for known instructions */
1077 if ((Instruction == 0xFA) || (Instruction == 0xFB)) // CLI or STI
1078 {
1079 /* These are privileged */
1080 Privileged = TRUE;
1081 }
1082 else
1083 {
1084 /* Last hope: an IN/OUT instruction */
1085 for (j = 0; j < sizeof(KiTrapIoTable); j++)
1086 {
1087 /* Is this an I/O instruction? */
1088 if (Instruction == KiTrapIoTable[j])
1089 {
1090 /* Then it's privileged */
1091 Privileged = TRUE;
1092 break;
1093 }
1094 }
1095 }
1096 }
1097 }
1098
1099 /* So now... was the instruction privileged or not? */
1100 if (Privileged)
1101 {
1102 /* Whew! We have a privileged instruction, so dispatch the fault */
1104 TrapFrame->Eip,
1105 TrapFrame);
1106 }
1107 }
1108
1109 /* If we got here, send an access violation */
1111 TrapFrame->Eip,
1112 0,
1113 0xFFFFFFFF,
1114 TrapFrame);
1115 }
1116
1117 /*
1118 * Check for a fault during checking of the user instruction.
1119 *
1120 * Note that the SEH handler will catch invalid EIP, but we could be dealing
1121 * with an invalid CS, which will generate another GPF instead.
1122 *
1123 */
1124 if ((PVOID)TrapFrame->Eip >= (PVOID)KiTrap0DHandler &&
1125 (PVOID)TrapFrame->Eip < (PVOID)KiTrap0EHandler)
1126 {
1127 /* Not implemented */
1129 }
1130
1131 /*
1132 * NOTE: The ASM trap exit code would restore segment registers by doing
1133 * a POP <SEG>, which could cause an invalid segment if someone had messed
1134 * with the segment values.
1135 *
1136 * Another case is a bogus SS, which would hit a GPF when doing the iret.
1137 * This could only be done through a buggy or malicious driver, or perhaps
1138 * the kernel debugger.
1139 *
1140 * The kernel normally restores the "true" segment if this happens.
1141 *
1142 * However, since we're restoring in C, not ASM, we can't detect
1143 * POP <SEG> since the actual instructions will be different.
1144 *
1145 * A better technique would be to check the EIP and somehow edit the
1146 * trap frame before restarting the instruction -- but we would need to
1147 * know the extract instruction that was used first.
1148 *
1149 * We could force a special instrinsic to use stack instructions, or write
1150 * a simple instruction length checker.
1151 *
1152 * Nevertheless, this is a lot of work for the purpose of avoiding a crash
1153 * when the user is purposedly trying to create one from kernel-mode, so
1154 * we should probably table this for now since it's not a "real" issue.
1155 */
1156
1157 /*
1158 * NOTE2: Another scenario is the IRET during a V8086 restore (BIOS Call)
1159 * which will cause a GPF since the trap frame is a total mess (on purpose)
1160 * as built in KiEnterV86Mode.
1161 *
1162 * The idea is to scan for IRET, scan for the known EIP address, validate CS
1163 * and then manually issue a jump to the V8086 return EIP.
1164 */
1165 Instructions = (PUCHAR)TrapFrame->Eip;
1166 if (Instructions[0] == 0xCF)
1167 {
1168 /*
1169 * Some evil shit is going on here -- this is not the SS:ESP you're
1170 * looking for! Instead, this is actually CS:EIP you're looking at!
1171 * Why? Because part of the trap frame actually corresponds to the IRET
1172 * stack during the trap exit!
1173 */
1174 if ((TrapFrame->HardwareEsp == (ULONG)Ki386BiosCallReturnAddress) &&
1175 (TrapFrame->HardwareSegSs == (KGDT_R0_CODE | RPL_MASK)))
1176 {
1177 /* Exit the V86 trap! */
1178 Ki386BiosCallReturnAddress(TrapFrame);
1179 }
1180 else
1181 {
1182 /* Otherwise, this is another kind of IRET fault */
1184 }
1185 }
1186
1187 /* So since we're not dealing with the above case, check for RDMSR/WRMSR */
1188 if ((Instructions[0] == 0xF) && // 2-byte opcode
1189 ((Instructions[1] == 0x32) || // RDMSR
1190 (Instructions[1] == 0x30))) // WRMSR
1191 {
1192 /* Unknown CPU MSR, so raise an access violation */
1194 TrapFrame->Eip,
1195 TrapFrame);
1196 }
1197
1198 /* Check for lazy segment load */
1199 if (TrapFrame->SegDs != (KGDT_R3_DATA | RPL_MASK))
1200 {
1201 /* Fix it */
1202 TrapFrame->SegDs = (KGDT_R3_DATA | RPL_MASK);
1203 }
1204 else if (TrapFrame->SegEs != (KGDT_R3_DATA | RPL_MASK))
1205 {
1206 /* Fix it */
1207 TrapFrame->SegEs = (KGDT_R3_DATA | RPL_MASK);
1208 }
1209 else
1210 {
1211 /* Whatever it is, we can't handle it */
1213 }
1214
1215 /* Return to where we came from */
1216 KiTrapReturn(TrapFrame);
1217}
1218
1219BOOLEAN
1222{
1223 /* Explanation: An S-List fault can occur due to a race condition between 2
1224 threads simultaneously trying to pop an element from the S-List. After
1225 thread 1 has read the pointer to the top element on the S-List it is
1226 preempted and thread 2 calls InterlockedPopEntrySlist on the same S-List,
1227 removing the top element and freeing it's memory. After that thread 1
1228 resumes and tries to read the address of the Next pointer from the top
1229 element, which it assumes will be the next top element.
1230 But since that memory has been freed, we get a page fault. To handle this
1231 race condition, we let thread 1 repeat the operation.
1232 We do NOT invoke the page fault handler in this case, since we do not
1233 want to trigger any side effects, like paging or a guard page fault.
1234
1235 Sequence of operations:
1236
1237 Thread 1 : mov eax, [ebp] <= eax now points to the first element
1238 Thread 1 : mov edx, [ebp + 4] <= edx is loaded with Depth and Sequence
1239 *** preempted ***
1240 Thread 2 : calls InterlockedPopEntrySlist, changing the top element
1241 Thread 2 : frees the memory of the element that was popped
1242 *** preempted ***
1243 Thread 1 : checks if eax is NULL
1244 Thread 1 : InterlockedPopEntrySListFault: mov ebx, [eax] <= faults
1245
1246 To be sure that we are dealing with exactly the case described above, we
1247 check whether the ListHeader has changed. If Thread 2 only popped one
1248 entry, the Next field in the S-List-header has changed.
1249 If after thread 1 has faulted, thread 2 allocates a new element, by
1250 chance getting the same address as the previously freed element and
1251 pushes it on the list again, we will see the same top element, but the
1252 Sequence member of the S-List header has changed. Therefore we check
1253 both fields to make sure we catch any concurrent modification of the
1254 S-List-header.
1255 */
1256 if ((TrapFrame->Eip == (ULONG_PTR)ExpInterlockedPopEntrySListFault) ||
1257 (TrapFrame->Eip == (ULONG_PTR)KeUserPopEntrySListFault))
1258 {
1259 ULARGE_INTEGER SListHeader;
1260 PVOID ResumeAddress;
1261
1262 /* Sanity check that the assembly is correct:
1263 This must be mov ebx, [eax]
1264 Followed by cmpxchg8b [ebp] */
1265 ASSERT((((UCHAR*)TrapFrame->Eip)[0] == 0x8B) &&
1266 (((UCHAR*)TrapFrame->Eip)[1] == 0x18) &&
1267 (((UCHAR*)TrapFrame->Eip)[2] == 0x0F) &&
1268 (((UCHAR*)TrapFrame->Eip)[3] == 0xC7) &&
1269 (((UCHAR*)TrapFrame->Eip)[4] == 0x4D) &&
1270 (((UCHAR*)TrapFrame->Eip)[5] == 0x00));
1271
1272 /* Check if this is a user fault */
1273 if (TrapFrame->Eip == (ULONG_PTR)KeUserPopEntrySListFault)
1274 {
1275 /* EBP points to the S-List-header. Copy it inside SEH, to protect
1276 against a bogus pointer from user mode */
1277 _SEH2_TRY
1278 {
1279 ProbeForRead((PVOID)TrapFrame->Ebp,
1280 sizeof(ULARGE_INTEGER),
1282 SListHeader = *(PULARGE_INTEGER)TrapFrame->Ebp;
1283 }
1285 {
1286 /* The S-List pointer is not valid! */
1287 return FALSE;
1288 }
1289 _SEH2_END;
1290 ResumeAddress = KeUserPopEntrySListResume;
1291 }
1292 else
1293 {
1294 SListHeader = *(PULARGE_INTEGER)TrapFrame->Ebp;
1295 ResumeAddress = ExpInterlockedPopEntrySListResume;
1296 }
1297
1298 /* Check if either the Next pointer or the Sequence member in the
1299 S-List-header has changed. If any of these has changed, we restart
1300 the operation. Otherwise we only have a bogus pointer and let the
1301 page fault handler deal with it. */
1302 if ((SListHeader.LowPart != TrapFrame->Eax) ||
1303 (SListHeader.HighPart != TrapFrame->Edx))
1304 {
1305 DPRINT1("*** Got an S-List-Fault ***\n");
1306 KeGetCurrentThread()->SListFaultCount++;
1307
1308 /* Restart the operation */
1309 TrapFrame->Eip = (ULONG_PTR)ResumeAddress;
1310
1311 return TRUE;
1312 }
1313 }
1314
1315 return FALSE;
1316}
1317
1319VOID
1322{
1324 ULONG_PTR Cr2;
1326
1327 /* Save trap frame */
1328 KiEnterTrap(TrapFrame);
1329
1330 /* Check if this is the base frame */
1332 if (KeGetTrapFrame(Thread) != TrapFrame)
1333 {
1334 /* It isn't, check if this is a second nested frame */
1335 if (((ULONG_PTR)KeGetTrapFrame(Thread) - (ULONG_PTR)TrapFrame) <=
1336 FIELD_OFFSET(KTRAP_FRAME, EFlags))
1337 {
1338 /* The stack is somewhere in between frames, we need to fix it */
1340 }
1341 }
1342
1343 /* Save CR2 */
1344 Cr2 = __readcr2();
1345
1346 /* Enable interrupts */
1347 _enable();
1348
1349 /* Check if we came in with interrupts disabled */
1350 if (!(TrapFrame->EFlags & EFLAGS_INTERRUPT_MASK))
1351 {
1352 /* This is completely illegal, bugcheck the system */
1353 KeBugCheckWithTf(IRQL_NOT_LESS_OR_EQUAL,
1354 Cr2,
1355 (ULONG_PTR)-1,
1356 TrapFrame->ErrCode,
1357 TrapFrame->Eip,
1358 TrapFrame);
1359 }
1360
1361 /* Check for S-List fault */
1362 if (KiCheckForSListFault(TrapFrame))
1363 {
1364 /* Continue execution */
1365 KiEoiHelper(TrapFrame);
1366 }
1367
1368 /* Call the access fault handler */
1369 Status = MmAccessFault(TrapFrame->ErrCode,
1370 (PVOID)Cr2,
1371 KiUserTrap(TrapFrame),
1372 TrapFrame);
1373 if (NT_SUCCESS(Status))
1374 {
1375 /* Check whether the kernel debugger has owed breakpoints to be inserted */
1377 /* We succeeded, return */
1378 KiEoiHelper(TrapFrame);
1379 }
1380
1381 /* Check for syscall fault */
1382#if 0
1383 if ((TrapFrame->Eip == (ULONG_PTR)CopyParams) ||
1384 (TrapFrame->Eip == (ULONG_PTR)ReadBatch))
1385 {
1386 /* Not yet implemented */
1388 }
1389#endif
1390
1391 /* Check for VDM trap */
1392 if (KiVdmTrap(TrapFrame))
1393 {
1394 DPRINT1("VDM PAGE FAULT at %lx:%lx for address %lx\n",
1395 TrapFrame->SegCs, TrapFrame->Eip, Cr2);
1396 if (VdmDispatchPageFault(TrapFrame))
1397 {
1398 /* Return and end VDM execution */
1399 DPRINT1("VDM page fault with status 0x%lx resolved\n", Status);
1400 KiEoiHelper(TrapFrame);
1401 }
1402 DPRINT1("VDM page fault with status 0x%lx NOT resolved\n", Status);
1403 }
1404
1405 /* Either kernel or user trap (non VDM) so dispatch exception */
1407 {
1408 /* This status code is repurposed so we can recognize it later */
1410 TrapFrame->Eip,
1411 MI_IS_WRITE_ACCESS(TrapFrame->ErrCode),
1412 Cr2,
1413 TrapFrame);
1414 }
1415 else if ((Status == STATUS_GUARD_PAGE_VIOLATION) ||
1417 {
1418 /* These faults only have two parameters */
1420 TrapFrame->Eip,
1421 MI_IS_WRITE_ACCESS(TrapFrame->ErrCode),
1422 Cr2,
1423 TrapFrame);
1424 }
1425
1426 /* Only other choice is an in-page error, with 3 parameters */
1428 0,
1429 TrapFrame->Eip,
1430 3,
1431 MI_IS_WRITE_ACCESS(TrapFrame->ErrCode),
1432 Cr2,
1433 Status,
1434 TrapFrame);
1435}
1436
1438VOID
1441{
1442 /* Save trap frame */
1443 KiEnterTrap(TrapFrame);
1444
1445 /* FIXME: Kill the system */
1448}
1449
1451VOID
1454{
1456 PFX_SAVE_AREA SaveArea;
1457
1458 /* Save trap frame */
1459 KiEnterTrap(TrapFrame);
1460
1461 /* Check if this is the NPX thrad */
1463 SaveArea = KiGetThreadNpxArea(Thread);
1464 if (Thread != KeGetCurrentPrcb()->NpxThread)
1465 {
1466 /* It isn't, enable interrupts and set delayed error */
1467 _enable();
1468 SaveArea->Cr0NpxState |= CR0_TS;
1469
1470 /* End trap */
1471 KiEoiHelper(TrapFrame);
1472 }
1473
1474 /* Otherwise, proceed with NPX fault handling */
1475 KiNpxHandler(TrapFrame, Thread, SaveArea);
1476}
1477
1479VOID
1482{
1483 /* Save trap frame */
1484 KiEnterTrap(TrapFrame);
1485
1486 /* Enable interrupts and kill the system */
1487 _enable();
1489}
1490
1492VOID
1495{
1497 PFX_SAVE_AREA SaveArea;
1498 ULONG Cr0, MxCsrMask, Error;
1499
1500 /* Save trap frame */
1501 KiEnterTrap(TrapFrame);
1502
1503 /* Check if this is the NPX thrad */
1505 if (Thread != KeGetCurrentPrcb()->NpxThread)
1506 {
1507 /* It isn't, kill the system */
1508 KeBugCheckWithTf(TRAP_CAUSE_UNKNOWN, 13, (ULONG_PTR)Thread, 0, 0, TrapFrame);
1509 }
1510
1511 /* Get the NPX frame */
1512 SaveArea = KiGetThreadNpxArea(Thread);
1513
1514 /* Check for VDM trap */
1515 ASSERT(KiVdmTrap(TrapFrame) == FALSE);
1516
1517 /* Check for user trap */
1518 if (!KiUserTrap(TrapFrame))
1519 {
1520 /* Kernel should not fault on XMMI */
1521 KeBugCheckWithTf(TRAP_CAUSE_UNKNOWN, 13, 0, 0, 2, TrapFrame);
1522 }
1523
1524 /* Update CR0 */
1525 Cr0 = __readcr0();
1526 Cr0 &= ~(CR0_MP | CR0_EM | CR0_TS);
1527 __writecr0(Cr0);
1528
1529 /* Save FPU state */
1530 Ke386SaveFpuState(SaveArea);
1531
1532 /* Mark CR0 state dirty */
1533 Cr0 |= NPX_STATE_NOT_LOADED;
1534 Cr0 |= SaveArea->Cr0NpxState;
1535 __writecr0(Cr0);
1536
1537 /* Update NPX state */
1538 Thread->NpxState = NPX_STATE_NOT_LOADED;
1539 KeGetCurrentPrcb()->NpxThread = NULL;
1540
1541 /* Clear the TS bit and re-enable interrupts */
1542 SaveArea->Cr0NpxState &= ~CR0_TS;
1543 _enable();
1544
1545 /* Now look at MxCsr to get the mask of errors we should care about */
1546 MxCsrMask = ~((USHORT)SaveArea->U.FxArea.MXCsr >> 7);
1547
1548 /* Get legal exceptions that software should handle */
1550 FSW_DENORMAL |
1552 FSW_OVERFLOW |
1555 Error &= MxCsrMask;
1556
1557 /* Now handle any of those legal errors */
1559 FSW_DENORMAL |
1561 FSW_OVERFLOW |
1564 {
1565 /* By issuing an exception */
1567 TrapFrame->Eip,
1568 0,
1569 TrapFrame);
1570 }
1571
1572 /* Unknown XMMI fault */
1573 KeBugCheckWithTf(TRAP_CAUSE_UNKNOWN, 13, 0, 0, 1, TrapFrame);
1574}
1575
1576/* SOFTWARE SERVICES **********************************************************/
1577
1578VOID
1581{
1582 /* Save trap frame */
1583 KiEnterTrap(TrapFrame);
1584
1585 /* Decrement EIP to point to the INT29 instruction (2 bytes, not 1 like INT3) */
1586 TrapFrame->Eip -= 2;
1587
1588 /* Check if this is a user trap */
1589 if (KiUserTrap(TrapFrame))
1590 {
1591 /* Dispatch exception to user mode */
1594 TrapFrame->Eip,
1595 1,
1596 TrapFrame->Ecx,
1597 0,
1598 0,
1599 TrapFrame);
1600 }
1601 else
1602 {
1603 EXCEPTION_RECORD ExceptionRecord;
1604
1605 /* Bugcheck the system */
1607 ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
1608 ExceptionRecord.ExceptionRecord = NULL;
1609 ExceptionRecord.ExceptionAddress = (PVOID)TrapFrame->Eip;
1610 ExceptionRecord.NumberParameters = 1;
1611 ExceptionRecord.ExceptionInformation[0] = TrapFrame->Ecx;
1612
1613 KeBugCheckWithTf(KERNEL_SECURITY_CHECK_FAILURE,
1614 TrapFrame->Ecx,
1615 (ULONG_PTR)TrapFrame,
1616 (ULONG_PTR)&ExceptionRecord,
1617 0,
1618 TrapFrame);
1619 }
1620}
1621
1622VOID
1625{
1626 /* Save trap frame */
1627 KiEnterTrap(TrapFrame);
1628
1629 /*
1630 * Just fail the request
1631 */
1632 DbgPrint("INT 0x2A attempted, returning 0 tick count\n");
1633 TrapFrame->Eax = 0;
1634
1635 /* Exit the trap */
1636 KiEoiHelper(TrapFrame);
1637}
1638
1639VOID
1642{
1645
1646 /* Save the SEH chain, NtCallbackReturn will restore this */
1647 TrapFrame->ExceptionList = KeGetPcr()->NtTib.ExceptionList;
1648
1649 /* Set thread fields */
1651 Thread->TrapFrame = TrapFrame;
1652 Thread->PreviousMode = KiUserTrap(TrapFrame);
1653 ASSERT(Thread->PreviousMode != KernelMode);
1654
1655 /* Pass the register parameters to NtCallbackReturn.
1656 Result pointer is in ecx, result length in edx, status in eax */
1657 Status = NtCallbackReturn((PVOID)TrapFrame->Ecx,
1658 TrapFrame->Edx,
1659 TrapFrame->Eax);
1660
1661 /* If we got here, something went wrong. Return an error to the caller */
1662 KiServiceExit(TrapFrame, Status);
1663}
1664
1666VOID
1669{
1670 /* Save trap frame */
1671 KiEnterTrap(TrapFrame);
1672
1673 /* Decrement EIP to point to the INT2C instruction (2 bytes, not 1 like INT3) */
1674 TrapFrame->Eip -= 2;
1675
1676 /* Dispatch the exception */
1678 TrapFrame->Eip,
1679 TrapFrame);
1680}
1681
1683VOID
1686{
1687 /* Save trap frame */
1688 KiEnterTrap(TrapFrame);
1689
1690 /* Increment EIP to skip the INT3 instruction */
1691 TrapFrame->Eip++;
1692
1693 /* Continue with the common handler */
1694 KiDebugHandler(TrapFrame, TrapFrame->Eax, TrapFrame->Ecx, TrapFrame->Edx);
1695}
1696
1697
1699VOID
1700KiDbgPreServiceHook(ULONG SystemCallNumber, PULONG_PTR Arguments)
1701{
1702#if DBG && !defined(_WINKD_)
1703 if (SystemCallNumber >= 0x1000 && KeWin32PreServiceHook)
1704 KeWin32PreServiceHook(SystemCallNumber, Arguments);
1705#endif
1706}
1707
1711{
1712#if DBG && !defined(_WINKD_)
1713 if (SystemCallNumber >= 0x1000 && KeWin32PostServiceHook)
1714 return KeWin32PostServiceHook(SystemCallNumber, Result);
1715#endif
1716 return Result;
1717}
1718
1720VOID
1723 IN PVOID Arguments)
1724{
1726 PKSERVICE_TABLE_DESCRIPTOR DescriptorTable;
1727 ULONG Id, Offset, StackBytes;
1729 PVOID Handler;
1730 ULONG SystemCallNumber = TrapFrame->Eax;
1731
1732 /* Get the current thread */
1734
1735 /* Set debug header */
1736 KiFillTrapFrameDebug(TrapFrame);
1737
1738 /* Chain trap frames */
1739 TrapFrame->Edx = (ULONG_PTR)Thread->TrapFrame;
1740
1741 /* No error code */
1742 TrapFrame->ErrCode = 0;
1743
1744 /* Save previous mode */
1745 TrapFrame->PreviousPreviousMode = Thread->PreviousMode;
1746
1747 /* Save the SEH chain and terminate it for now */
1748 TrapFrame->ExceptionList = KeGetPcr()->NtTib.ExceptionList;
1749 KeGetPcr()->NtTib.ExceptionList = EXCEPTION_CHAIN_END;
1750
1751 /* Default to debugging disabled */
1752 TrapFrame->Dr7 = 0;
1753
1754 /* Check if the frame was from user mode */
1755 if (KiUserTrap(TrapFrame))
1756 {
1757 /* Check for active debugging */
1758 if (KeGetCurrentThread()->Header.DebugActive & 0xFF)
1759 {
1760 /* Handle debug registers */
1762 }
1763 }
1764
1765 /* Set thread fields */
1766 Thread->TrapFrame = TrapFrame;
1767 Thread->PreviousMode = KiUserTrap(TrapFrame);
1768
1769 /* Enable interrupts */
1770 _enable();
1771
1772 /* Decode the system call number */
1773 Offset = (SystemCallNumber >> SERVICE_TABLE_SHIFT) & SERVICE_TABLE_MASK;
1774 Id = SystemCallNumber & SERVICE_NUMBER_MASK;
1775
1776 /* Get descriptor table */
1777 DescriptorTable = (PVOID)((ULONG_PTR)Thread->ServiceTable + Offset);
1778
1779 /* Validate the system call number */
1780 if (__builtin_expect(Id >= DescriptorTable->Limit, 0))
1781 {
1782 /* Check if this is a GUI call */
1783 if (!(Offset & SERVICE_TABLE_TEST))
1784 {
1785 /* Fail the call */
1787 goto ExitCall;
1788 }
1789
1790 /* Convert us to a GUI thread -- must wrap in ASM to get new EBP */
1792
1793 /* Reload trap frame and descriptor table pointer from new stack */
1794 TrapFrame = *(volatile PVOID*)&Thread->TrapFrame;
1795 DescriptorTable = (PVOID)(*(volatile ULONG_PTR*)&Thread->ServiceTable + Offset);
1796
1797 if (!NT_SUCCESS(Status))
1798 {
1799 /* Set the last error and fail */
1800 goto ExitCall;
1801 }
1802
1803 /* Validate the system call number again */
1804 if (Id >= DescriptorTable->Limit)
1805 {
1806 /* Fail the call */
1808 goto ExitCall;
1809 }
1810 }
1811
1812 /* Check if this is a GUI call */
1813 if (__builtin_expect(Offset & SERVICE_TABLE_TEST, 0))
1814 {
1815 /* Get the batch count and flush if necessary */
1816 if (NtCurrentTeb()->GdiBatchCount) KeGdiFlushUserBatch();
1817 }
1818
1819 /* Increase system call count */
1820 KeGetCurrentPrcb()->KeSystemCalls++;
1821
1822 /* FIXME: Increase individual counts on debug systems */
1823 //KiIncreaseSystemCallCount(DescriptorTable, Id);
1824
1825 /* Get stack bytes */
1826 StackBytes = DescriptorTable->Number[Id];
1827
1828 /* Probe caller stack */
1829 if (__builtin_expect((Arguments < (PVOID)MmUserProbeAddress) && !(KiUserTrap(TrapFrame)), 0))
1830 {
1831 /* Access violation */
1833 }
1834
1835 /* Call pre-service debug hook */
1836 KiDbgPreServiceHook(SystemCallNumber, Arguments);
1837
1838 /* Get the handler and make the system call */
1839 Handler = (PVOID)DescriptorTable->Base[Id];
1840 Status = KiSystemCallTrampoline(Handler, Arguments, StackBytes);
1841
1842 /* Call post-service debug hook */
1843 Status = KiDbgPostServiceHook(SystemCallNumber, Status);
1844
1845 /* Make sure we're exiting correctly */
1846 KiExitSystemCallDebugChecks(Id, TrapFrame);
1847
1848 /* Restore the old trap frame */
1849ExitCall:
1850 Thread->TrapFrame = (PKTRAP_FRAME)TrapFrame->Edx;
1851
1852 /* Exit from system call */
1853 KiServiceExit(TrapFrame, Status);
1854}
1855
1856VOID
1859{
1861}
1862
1863/*
1864 * @implemented
1865 */
1866VOID
1867NTAPI
1869{
1870 /* We should never see this call happening */
1871 KeBugCheck(MISMATCHED_HAL);
1872}
1873
1874/* EOF */
DWORD Id
unsigned char BOOLEAN
#define EFLAGS_INTERRUPT_MASK
Definition: SystemCall.c:11
#define EFLAGS_TF
Definition: SystemCall.c:10
#define __cdecl
Definition: accygwin.h:79
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx 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:672
NTSTATUS NTAPI NtCallbackReturn(_In_ PVOID Result, _In_ ULONG ResultLength, _In_ NTSTATUS CallbackStatus)
Definition: usercall.c:329
@ Instruction
Definition: asmpp.cpp:82
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
BOOL Error
Definition: chkdsk.c:66
#define UNIMPLEMENTED
Definition: debug.h:118
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1430
Definition: Header.h:9
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ULONG_PTR
Definition: config.h:101
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define HIGH_LEVEL
Definition: env_spec_w32.h:703
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
unsigned int Mask
Definition: fpcontrol.c:82
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum 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 const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum 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 const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define DbgPrint
Definition: hal.h:12
#define KeGetCurrentThread
Definition: hal.h:55
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
void __cdecl _disable(void)
Definition: intrin_arm.h:365
void __cdecl _enable(void)
Definition: intrin_arm.h:373
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1669
__INTRIN_INLINE unsigned long __readcr0(void)
Definition: intrin_x86.h:1804
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1674
__INTRIN_INLINE unsigned long __readcr2(void)
Definition: intrin_x86.h:1811
__INTRIN_INLINE void __writecr0(unsigned int Data)
Definition: intrin_x86.h:1789
#define NtCurrentTeb
VOID NTAPI KdSetOwedBreakpoints(VOID)
Definition: kdbreak.c:105
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define for
Definition: utility.h:88
struct _ULARGE_INTEGER * PULARGE_INTEGER
Definition: drive.c:28
#define KernelMode
Definition: asm.h:34
#define CR0_MP
Definition: asm.h:246
#define CR0_EM
Definition: asm.h:247
#define CR0_TS
Definition: asm.h:248
#define FSW_STACK_FAULT
Definition: ketypes.h:236
#define FSW_DENORMAL
Definition: ketypes.h:231
#define FSW_ZERO_DIVIDE
Definition: ketypes.h:232
#define EFLAGS_NESTED_TASK
Definition: ketypes.h:190
#define EFLAGS_V86_MASK
Definition: ketypes.h:193
#define FSW_PRECISION
Definition: ketypes.h:235
#define I386_TSS
Definition: ketypes.h:121
#define FSW_OVERFLOW
Definition: ketypes.h:233
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1161
#define PKTSS
Definition: ketypes.h:1007
#define FSW_INVALID_OPERATION
Definition: ketypes.h:230
struct _KIPCR * PKIPCR
#define I386_ACTIVE_TSS
Definition: ketypes.h:122
struct _KTRAP_FRAME * PKTRAP_FRAME
#define RPL_MASK
Definition: ketypes.h:130
#define EFLAGS_IOPL
Definition: ketypes.h:189
#define FSW_UNDERFLOW
Definition: ketypes.h:234
#define EXCEPTION_INVALID_TSS
Definition: asm.h:627
#define EXCEPTION_DOUBLE_FAULT
Definition: asm.h:625
#define EXCEPTION_BOUND_CHECK
Definition: asm.h:622
#define EXCEPTION_NPX_OVERRUN
Definition: asm.h:626
#define NPX_STATE_NOT_LOADED
Definition: asm.h:265
#define EXCEPTION_RESERVED_TRAP
Definition: asm.h:631
#define EXCEPTION_ALIGNMENT_CHECK
Definition: asm.h:633
#define EXCEPTION_SEGMENT_NOT_PRESENT
Definition: asm.h:628
#define DR7_RESERVED_MASK
Definition: asm.h:515
#define EXCEPTION_NMI
Definition: asm.h:620
#define NPX_STATE_LOADED
Definition: asm.h:266
#define EXCEPTION_STACK_FAULT
Definition: asm.h:629
#define EXCEPTION_GP_FAULT
Definition: asm.h:630
#define KGDT_R3_DATA
Definition: ketypes.h:126
#define KGDT_NMI_TSS
Definition: ketypes.h:133
#define KeGetPcr()
Definition: ketypes.h:81
#define KGDT_LDT
Definition: ketypes.h:131
#define KGDT_DF_TSS
Definition: ketypes.h:132
#define KGDT_R0_CODE
Definition: ketypes.h:123
#define BREAKPOINT_BREAK
Definition: kdtypes.h:50
#define SERVICE_TABLE_SHIFT
Definition: ketypes.h:71
#define SERVICE_TABLE_MASK
Definition: ketypes.h:78
#define KI_EXCEPTION_ACCESS_VIOLATION
Definition: ketypes.h:144
#define SERVICE_NUMBER_MASK
Definition: ketypes.h:83
#define SERVICE_TABLE_TEST
Definition: ketypes.h:90
#define EXCEPTION_CHAIN_END
Definition: rtltypes.h:63
VOID NTAPI HalHandleNMI(IN PVOID NmiInfo)
Definition: nmi.c:27
#define FASTCALL
Definition: nt_native.h:50
#define UNREACHABLE
#define TYPE_ALIGNMENT(t)
Definition: ntbasedef.h:117
#define DECLSPEC_NORETURN
Definition: ntbasedef.h:176
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define FRAME_EDITED
Definition: ke.h:68
ULONG KeI386FxsrPresent
Definition: cpu.c:33
FORCEINLINE BOOLEAN KiUserTrap(IN PKTRAP_FRAME TrapFrame)
Definition: ke.h:364
#define KeGetTrapFrame(Thread)
Definition: ke.h:208
#define MI_IS_WRITE_ACCESS(FaultCode)
Definition: mm.h:122
#define KiServiceExit2
Definition: ke.h:5
BOOLEAN NTAPI VdmDispatchPageFault(_In_ PKTRAP_FRAME TrapFrame)
Definition: vdmexec.c:367
BOOLEAN NTAPI VdmDispatchBop(IN PKTRAP_FRAME TrapFrame)
Definition: vdmexec.c:313
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:829
VOID NTAPI ExpInterlockedPopEntrySListResume(VOID)
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:1055
BOOLEAN FASTCALL Ki386HandleOpcodeV86(IN PKTRAP_FRAME TrapFrame)
Definition: v86vdm.c:456
VOID __cdecl ReadBatch(VOID)
FORCEINLINE DECLSPEC_NORETURN VOID KiDispatchException0Args(IN NTSTATUS Code, IN ULONG_PTR Address, IN PKTRAP_FRAME TrapFrame)
Definition: ke.h:800
VOID __cdecl CopyParams(VOID)
NTSTATUS NTAPI KiSystemCallTrampoline(_In_ PVOID Handler, _In_ PVOID Arguments, _In_ ULONG StackBytes)
FORCEINLINE DECLSPEC_NORETURN VOID KiDispatchException1Args(IN NTSTATUS Code, IN ULONG_PTR Address, IN ULONG P1, IN PKTRAP_FRAME TrapFrame)
Definition: ke.h:814
FORCEINLINE PFX_SAVE_AREA KiGetThreadNpxArea(IN PKTHREAD Thread)
Definition: ke.h:737
NTSTATUS NTAPI KiConvertToGuiThread(VOID)
VOID FASTCALL Ki386BiosCallReturnAddress(IN PKTRAP_FRAME TrapFrame)
FORCEINLINE VOID KiCheckForApcDelivery(IN PKTRAP_FRAME TrapFrame)
Definition: ke.h:854
VOID NTAPI ExpInterlockedPopEntrySListFault(VOID)
DECLSPEC_NORETURN VOID NTAPI KeBugCheckWithTf(ULONG BugCheckCode, ULONG_PTR BugCheckParameter1, ULONG_PTR BugCheckParameter2, ULONG_PTR BugCheckParameter3, ULONG_PTR BugCheckParameter4, PKTRAP_FRAME Tf)
VOID NTAPI KiSaveProcessorState(_In_ PKTRAP_FRAME TrapFrame, _In_ PKEXCEPTION_FRAME ExceptionFrame)
Definition: cpu.c:617
BOOLEAN NTAPI KiHandleNmi(VOID)
Definition: bug.c:1165
PGDI_BATCHFLUSH_ROUTINE KeGdiFlushUserBatch
Definition: win32.c:20
DECLSPEC_NORETURN VOID FASTCALL KiSystemFatalException(IN ULONG ExceptionCode, IN PKTRAP_FRAME TrapFrame)
Definition: except.c:422
NTSTATUS NTAPI MmAccessFault(IN ULONG FaultCode, IN PVOID Address, IN KPROCESSOR_MODE Mode, IN PVOID TrapInformation)
Definition: mmfault.c:209
ULONG MmUserProbeAddress
Definition: init.c:50
#define STATUS_FLOAT_UNDERFLOW
Definition: ntstatus.h:383
#define STATUS_ILLEGAL_INSTRUCTION
Definition: ntstatus.h:266
#define STATUS_FLOAT_OVERFLOW
Definition: ntstatus.h:381
#define STATUS_FLOAT_STACK_CHECK
Definition: ntstatus.h:382
#define STATUS_ARRAY_BOUNDS_EXCEEDED
Definition: ntstatus.h:376
#define STATUS_ASSERTION_FAILURE
Definition: ntstatus.h:960
#define STATUS_STACK_OVERFLOW
Definition: ntstatus.h:489
#define STATUS_SINGLE_STEP
Definition: ntstatus.h:185
#define STATUS_FLOAT_DIVIDE_BY_ZERO
Definition: ntstatus.h:378
#define STATUS_PRIVILEGED_INSTRUCTION
Definition: ntstatus.h:386
#define STATUS_BREAKPOINT
Definition: ntstatus.h:184
#define STATUS_FLOAT_MULTIPLE_TRAPS
Definition: ntstatus.h:808
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define STATUS_INVALID_SYSTEM_SERVICE
Definition: ntstatus.h:265
#define STATUS_FLOAT_INVALID_OPERATION
Definition: ntstatus.h:380
#define STATUS_IN_PAGE_ERROR
Definition: ntstatus.h:243
#define STATUS_FLOAT_INEXACT_RESULT
Definition: ntstatus.h:379
#define STATUS_STACK_BUFFER_OVERRUN
Definition: ntstatus.h:946
#define STATUS_GUARD_PAGE_VIOLATION
Definition: ntstatus.h:182
#define STATUS_INTEGER_OVERFLOW
Definition: ntstatus.h:385
#define STATUS_INTEGER_DIVIDE_BY_ZERO
Definition: ntstatus.h:384
#define STATUS_INVALID_LOCK_SEQUENCE
Definition: ntstatus.h:267
unsigned short USHORT
Definition: pedump.c:61
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define UNIMPLEMENTED_FATAL(...)
Definition: debug.h:244
#define DPRINT
Definition: sndvol32.h:73
struct _EXCEPTION_RECORD * ExceptionRecord
Definition: compat.h:210
DWORD ExceptionCode
Definition: compat.h:208
DWORD NumberParameters
Definition: compat.h:212
DWORD ExceptionFlags
Definition: compat.h:209
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:213
PVOID ExceptionAddress
Definition: compat.h:211
ULONG MXCsr
Definition: ketypes.h:489
ULONG Cr0NpxState
Definition: ketypes.h:505
FXSAVE_FORMAT FxArea
Definition: ketypes.h:502
union _FX_SAVE_AREA::@2458 U
struct _KGDTENTRY::@2451::@2453 Bits
struct _KGDTENTRY::@2451::@2452 Bytes
USHORT BaseLow
Definition: ketypes.h:390
union _KGDTENTRY::@2451 HighWord
ULONG64 NpxState
Definition: ketypes.h:2068
ULONG DbgEip
Definition: ketypes.h:296
ULONG HardwareSegSs
Definition: ketypes.h:325
ULONG Edi
Definition: ketypes.h:316
ULONG DbgEbp
Definition: ketypes.h:295
ULONG EFlags
Definition: ketypes.h:469
ULONG Ebp
Definition: ketypes.h:319
ULONG Ebx
Definition: ketypes.h:318
ULONG PreviousPreviousMode
Definition: ketypes.h:313
ULONG HardwareEsp
Definition: ketypes.h:324
ULONG Ecx
Definition: ketypes.h:311
ULONG Eip
Definition: ketypes.h:321
USHORT SegCs
Definition: ketypes.h:465
USHORT SegEs
Definition: ketypes.h:450
struct _EXCEPTION_REGISTRATION_RECORD FAR * ExceptionList
Definition: ketypes.h:314
USHORT SegFs
Definition: ketypes.h:451
USHORT SegGs
Definition: ketypes.h:452
ULONG Eax
Definition: ketypes.h:312
USHORT SegDs
Definition: ketypes.h:449
ULONG Esi
Definition: ketypes.h:317
ULONG Edx
Definition: ketypes.h:310
Definition: ketypes.h:844
USHORT Fs
Definition: ketypes.h:870
USHORT LDT
Definition: ketypes.h:874
USHORT Ds
Definition: ketypes.h:868
ULONG Eax
Definition: ketypes.h:854
ULONG Ecx
Definition: ketypes.h:855
ULONG Esi
Definition: ketypes.h:860
ULONG Ebp
Definition: ketypes.h:859
ULONG Edx
Definition: ketypes.h:856
USHORT Gs
Definition: ketypes.h:872
ULONG Eip
Definition: ketypes.h:852
USHORT Cs
Definition: ketypes.h:864
ULONG Ebx
Definition: ketypes.h:857
USHORT IoMapBase
Definition: ketypes.h:877
ULONG Edi
Definition: ketypes.h:861
ULONG Esp0
Definition: ketypes.h:847
ULONG CR3
Definition: ketypes.h:851
USHORT Ss0
Definition: ketypes.h:848
USHORT Es
Definition: ketypes.h:862
ULONG EFlags
Definition: ketypes.h:853
$ULONG LowPart
Definition: ntbasedef.h:569
$ULONG HighPart
Definition: ntbasedef.h:570
#define EXCEPTION_NONCONTINUABLE
Definition: stubs.h:23
DECLSPEC_NORETURN VOID FASTCALL KiTrapReturnNoSegmentsRet8(IN PKTRAP_FRAME TrapFrame)
FORCEINLINE VOID KiEnterV86Trap(IN PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:345
FORCEINLINE VOID KiHandleDebugRegistersOnTrapEntry(IN PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:251
FORCEINLINE DECLSPEC_NORETURN VOID KiExitV86Trap(IN PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:299
DECLSPEC_NORETURN VOID FASTCALL KiTrapReturn(IN PKTRAP_FRAME TrapFrame)
#define KiFillTrapFrameDebug(x)
Definition: trap_x.h:184
FORCEINLINE VOID KiHandleDebugRegistersOnTrapExit(PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:278
DECLSPEC_NORETURN VOID FASTCALL KiSystemCallTrapReturn(IN PKTRAP_FRAME TrapFrame)
FORCEINLINE VOID KiEnterTrap(IN PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:402
DECLSPEC_NORETURN VOID FASTCALL KiEditedTrapReturn(IN PKTRAP_FRAME TrapFrame)
VOID(FASTCALL * PFAST_SYSTEM_CALL_EXIT)(IN PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:240
DECLSPEC_NORETURN VOID FASTCALL KiTrapReturnNoSegments(IN PKTRAP_FRAME TrapFrame)
#define KiExitTrapDebugChecks(x, y)
Definition: trap_x.h:183
DECLSPEC_NORETURN VOID FASTCALL KiSystemCallReturn(IN PKTRAP_FRAME TrapFrame)
FORCEINLINE VOID KiExitSystemCallDebugChecks(IN ULONG SystemCall, IN PKTRAP_FRAME TrapFrame)
Definition: trap_x.h:189
UCHAR KiTrapPrefixTable[]
Definition: traphdlr.c:25
DECLSPEC_NORETURN VOID FASTCALL KiTrap0BHandler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:910
PVOID KeUserPopEntrySListResume
Definition: psmgr.c:19
DECLSPEC_NORETURN VOID FASTCALL KiRaiseAssertionHandler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:1668
DECLSPEC_NORETURN VOID FASTCALL KiTrap00Handler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:407
VOID FASTCALL KiRaiseSecurityCheckFailureHandler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:1580
DECLSPEC_NORETURN VOID FASTCALL KiNpxHandler(IN PKTRAP_FRAME TrapFrame, IN PKTHREAD Thread, IN PFX_SAVE_AREA SaveArea)
Definition: traphdlr.c:244
DECLSPEC_NORETURN VOID FASTCALL KiTrap0EHandler(IN PKTRAP_FRAME)
Definition: traphdlr.c:1321
VOID FASTCALL KiCheckForSListAddress(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:1858
DECLSPEC_NORETURN VOID FASTCALL KiTrap10Handler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:1453
VOID __cdecl KiFastCallEntryWithSingleStep(VOID)
VOID FASTCALL KiCallbackReturnHandler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:1641
DECLSPEC_NORETURN VOID FASTCALL KiTrap0CHandler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:923
VOID FASTCALL Ke386LoadFpuState(IN PFX_SAVE_AREA SaveArea)
DECLSPEC_NORETURN VOID __cdecl KiTrap08Handler(VOID)
Definition: traphdlr.c:831
DECLSPEC_NORETURN VOID FASTCALL KiTrap0FHandler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:1440
VOID FASTCALL KiGetTickCountHandler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:1624
DECLSPEC_NORETURN VOID FASTCALL KiTrap13Handler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:1494
DECLSPEC_NORETURN VOID FASTCALL KiTrap0AHandler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:895
DECLSPEC_NORETURN VOID FASTCALL KiTrap06Handler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:641
DECLSPEC_NORETURN VOID FASTCALL KiTrap09Handler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:882
FORCEINLINE BOOLEAN KiIsFrameEdited(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:87
DECLSPEC_NORETURN VOID FASTCALL KiDebugServiceHandler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:1685
PVOID KeUserPopEntrySListFault
Definition: psmgr.c:18
FORCEINLINE ULONG_PTR KiDbgPostServiceHook(ULONG SystemCallNumber, ULONG_PTR Result)
Definition: traphdlr.c:1710
PVOID FrRestore
DECLSPEC_NORETURN VOID FASTCALL KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:126
UCHAR KiTrapIoTable[]
Definition: traphdlr.c:40
VOID __cdecl KiFastCallEntry(VOID)
DECLSPEC_NORETURN VOID FASTCALL KiTrap0DHandler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:939
DECLSPEC_NORETURN VOID FASTCALL KiTrap05Handler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:618
PFAST_SYSTEM_CALL_EXIT KiFastCallExitHandler
Definition: traphdlr.c:56
DECLSPEC_NORETURN VOID FASTCALL KiTrap11Handler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:1481
DECLSPEC_NORETURN VOID FASTCALL KiTrap07Handler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:722
DECLSPEC_NORETURN VOID FASTCALL KiSystemServiceHandler(IN PKTRAP_FRAME TrapFrame, IN PVOID Arguments)
Definition: traphdlr.c:1722
VOID NTAPI Kei386EoiHelper(VOID)
Definition: traphdlr.c:1868
FORCEINLINE VOID KiDbgPreServiceHook(ULONG SystemCallNumber, PULONG_PTR Arguments)
Definition: traphdlr.c:1700
FORCEINLINE BOOLEAN KiV86Trap(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:79
BOOLEAN FASTCALL KiCheckForSListFault(PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:1221
FORCEINLINE BOOLEAN KiVdmTrap(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:70
VOID __cdecl KiTrap02Handler(VOID)
Definition: traphdlr.c:460
DECLSPEC_NORETURN VOID FASTCALL KiTrap03Handler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:586
DECLSPEC_NORETURN VOID FASTCALL KiTrap01Handler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:427
DECLSPEC_NORETURN VOID FASTCALL KiTrap04Handler(IN PKTRAP_FRAME TrapFrame)
Definition: traphdlr.c:598
DECLSPEC_NORETURN VOID FASTCALL KiServiceExit(IN PKTRAP_FRAME TrapFrame, IN NTSTATUS Status)
Definition: traphdlr.c:150
DECLSPEC_NORETURN VOID FASTCALL KiDebugHandler(IN PKTRAP_FRAME TrapFrame, IN ULONG Parameter1, IN ULONG Parameter2, IN ULONG Parameter3)
Definition: traphdlr.c:219
FORCEINLINE VOID KiCommonExit(IN PKTRAP_FRAME TrapFrame, BOOLEAN SkipPreviousMode)
Definition: traphdlr.c:96
uint32_t * PULONG_PTR
Definition: typedefs.h:65
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
char CCHAR
Definition: typedefs.h:51
#define FORCEINLINE
Definition: wdftypes.h:67
_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:409
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
#define PsGetCurrentProcess
Definition: psfuncs.h:17
unsigned char UCHAR
Definition: xmlstorage.h:181