00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <ntoskrnl.h>
00012 #define NDEBUG
00013 #include <debug.h>
00014
00015
00016
00017 UCHAR KiTrapPrefixTable[] =
00018 {
00019 0xF2,
00020 0xF3,
00021 0x67,
00022 0xF0,
00023 0x66,
00024 0x2E,
00025 0x3E,
00026 0x26,
00027 0x64,
00028 0x65,
00029 0x36,
00030 };
00031
00032 UCHAR KiTrapIoTable[] =
00033 {
00034 0xE4,
00035 0xE5,
00036 0xEC,
00037 0xED,
00038 0x6C,
00039 0x6D,
00040 0xE6,
00041 0xE7,
00042 0xEE,
00043 0xEF,
00044 0x6E,
00045 0x6F,
00046 };
00047
00048 PFAST_SYSTEM_CALL_EXIT KiFastCallExitHandler;
00049 #if DBG && !defined(_WINKD_)
00050 PKDBG_PRESERVICEHOOK KeWin32PreServiceHook = NULL;
00051 PKDBG_POSTSERVICEHOOK KeWin32PostServiceHook = NULL;
00052 #endif
00053 #if TRAP_DEBUG
00054 BOOLEAN StopChecking = FALSE;
00055 #endif
00056
00057
00058
00059
00060 BOOLEAN
00061 FORCEINLINE
00062 KiVdmTrap(IN PKTRAP_FRAME TrapFrame)
00063 {
00064
00065 return ((TrapFrame->EFlags & EFLAGS_V86_MASK) ||
00066 ((KiUserTrap(TrapFrame)) && (PsGetCurrentProcess()->VdmObjects)));
00067 }
00068
00069 BOOLEAN
00070 FORCEINLINE
00071 KiV86Trap(IN PKTRAP_FRAME TrapFrame)
00072 {
00073
00074 return ((TrapFrame->EFlags & EFLAGS_V86_MASK) != 0);
00075 }
00076
00077 BOOLEAN
00078 FORCEINLINE
00079 KiIsFrameEdited(IN PKTRAP_FRAME TrapFrame)
00080 {
00081
00082
00083 return ((TrapFrame->SegCs & FRAME_EDITED) == 0);
00084 }
00085
00086 VOID
00087 FORCEINLINE
00088 KiCommonExit(IN PKTRAP_FRAME TrapFrame, BOOLEAN SkipPreviousMode)
00089 {
00090
00091 _disable();
00092
00093
00094 KiCheckForApcDelivery(TrapFrame);
00095
00096
00097 KeGetPcr()->NtTib.ExceptionList = TrapFrame->ExceptionList;
00098
00099
00100 if (__builtin_expect(TrapFrame->Dr7 & ~DR7_RESERVED_MASK, 0))
00101 {
00102
00103 if ((TrapFrame->SegCs & MODE_MASK) ||
00104 (TrapFrame->EFlags & EFLAGS_V86_MASK))
00105 {
00106
00107 KiHandleDebugRegistersOnTrapExit(TrapFrame);
00108 }
00109 }
00110
00111
00112 KiExitTrapDebugChecks(TrapFrame, SkipPreviousMode);
00113 }
00114
00115 DECLSPEC_NORETURN
00116 VOID
00117 FASTCALL
00118 KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
00119 {
00120
00121 KiCommonExit(TrapFrame, TRUE);
00122
00123
00124 if (TrapFrame->EFlags & EFLAGS_V86_MASK) KiTrapReturnNoSegments(TrapFrame);
00125
00126
00127 if (TrapFrame->SegCs & MODE_MASK) KiTrapReturn(TrapFrame);
00128
00129
00130 if (KiIsFrameEdited(TrapFrame)) KiEditedTrapReturn(TrapFrame);
00131
00132
00133 KiTrapReturnNoSegments(TrapFrame);
00134 }
00135
00136 DECLSPEC_NORETURN
00137 VOID
00138 FASTCALL
00139 KiServiceExit(IN PKTRAP_FRAME TrapFrame,
00140 IN NTSTATUS Status)
00141 {
00142 ASSERT((TrapFrame->EFlags & EFLAGS_V86_MASK) == 0);
00143 ASSERT(!KiIsFrameEdited(TrapFrame));
00144
00145
00146 TrapFrame->Eax = Status;
00147
00148
00149 KiCommonExit(TrapFrame, FALSE);
00150
00151
00152 KeGetCurrentThread()->PreviousMode = (CCHAR)TrapFrame->PreviousPreviousMode;
00153
00154
00155 if (TrapFrame->SegCs & MODE_MASK)
00156 {
00157
00158 if (TrapFrame->EFlags & EFLAGS_TF)
00159 {
00160
00161 KiSystemCallTrapReturn(TrapFrame);
00162 }
00163 else
00164 {
00165
00166 KiFastCallExitHandler(TrapFrame);
00167 }
00168 }
00169
00170
00171 KiSystemCallReturn(TrapFrame);
00172 }
00173
00174 DECLSPEC_NORETURN
00175 VOID
00176 FASTCALL
00177 KiServiceExit2(IN PKTRAP_FRAME TrapFrame)
00178 {
00179
00180 KiCommonExit(TrapFrame, FALSE);
00181
00182
00183 KeGetCurrentThread()->PreviousMode = (CCHAR)TrapFrame->PreviousPreviousMode;
00184
00185
00186 if (TrapFrame->EFlags & EFLAGS_V86_MASK) KiTrapReturnNoSegments(TrapFrame);
00187
00188
00189 if (TrapFrame->SegCs & MODE_MASK) KiTrapReturn(TrapFrame);
00190
00191
00192 if (KiIsFrameEdited(TrapFrame)) KiEditedTrapReturn(TrapFrame);
00193
00194
00195 KiTrapReturnNoSegments(TrapFrame);
00196 }
00197
00198
00199
00200
00201 DECLSPEC_NORETURN
00202 VOID
00203 FASTCALL
00204 KiDebugHandler(IN PKTRAP_FRAME TrapFrame,
00205 IN ULONG Parameter1,
00206 IN ULONG Parameter2,
00207 IN ULONG Parameter3)
00208 {
00209
00210 ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
00211
00212
00213 if (KiUserTrap(TrapFrame)) _enable();
00214
00215
00216 KiDispatchExceptionFromTrapFrame(STATUS_BREAKPOINT,
00217 TrapFrame->Eip - 1,
00218 3,
00219 Parameter1,
00220 Parameter2,
00221 Parameter3,
00222 TrapFrame);
00223 }
00224
00225 DECLSPEC_NORETURN
00226 VOID
00227 FASTCALL
00228 KiNpxHandler(IN PKTRAP_FRAME TrapFrame,
00229 IN PKTHREAD Thread,
00230 IN PFX_SAVE_AREA SaveArea)
00231 {
00232 ULONG Cr0, Mask, Error, ErrorOffset, DataOffset;
00233
00234
00235 ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
00236
00237
00238 if (!KiUserTrap(TrapFrame))
00239 {
00240
00241 SaveArea->Cr0NpxState |= CR0_TS;
00242
00243
00244
00245 {
00246
00247
00248
00249 }
00250 }
00251
00252
00253
00254 {
00255
00256 Cr0 = __readcr0();
00257 Cr0 &= ~(CR0_MP | CR0_EM | CR0_TS);
00258 __writecr0(Cr0);
00259
00260
00261 Ke386SaveFpuState(SaveArea);
00262
00263
00264 Cr0 |= NPX_STATE_NOT_LOADED;
00265 Cr0 |= SaveArea->Cr0NpxState;
00266 __writecr0(Cr0);
00267
00268
00269 Thread->NpxState = NPX_STATE_NOT_LOADED;
00270 KeGetCurrentPrcb()->NpxThread = NULL;
00271 }
00272
00273
00274 SaveArea->Cr0NpxState &= ~CR0_TS;
00275 _enable();
00276
00277
00278 if (KeI386FxsrPresent)
00279 {
00280
00281 Mask = SaveArea->U.FxArea.ControlWord;
00282 Error = SaveArea->U.FxArea.StatusWord;
00283
00284
00285 ErrorOffset = SaveArea->U.FxArea.ErrorOffset;
00286 DataOffset = SaveArea->U.FxArea.DataOffset;
00287 }
00288 else
00289 {
00290
00291 Mask = SaveArea->U.FnArea.ControlWord;
00292 Error = SaveArea->U.FnArea.StatusWord;
00293
00294
00295 ErrorOffset = SaveArea->U.FnArea.ErrorOffset;
00296 DataOffset = SaveArea->U.FnArea.DataOffset;
00297 }
00298
00299
00300
00301
00302 Mask &= (FSW_INVALID_OPERATION |
00303 FSW_DENORMAL |
00304 FSW_ZERO_DIVIDE |
00305 FSW_OVERFLOW |
00306 FSW_UNDERFLOW |
00307 FSW_PRECISION);
00308 Error &= ~Mask;
00309
00310
00311 if (Error & FSW_INVALID_OPERATION)
00312 {
00313
00314
00315
00316 if (Error & FSW_STACK_FAULT)
00317 {
00318
00319 KiDispatchException2Args(STATUS_FLOAT_STACK_CHECK,
00320 ErrorOffset,
00321 0,
00322 DataOffset,
00323 TrapFrame);
00324 }
00325
00326
00327 KiDispatchException1Args(STATUS_FLOAT_INVALID_OPERATION,
00328 ErrorOffset,
00329 0,
00330 TrapFrame);
00331 }
00332
00333
00334 if (Error & FSW_ZERO_DIVIDE)
00335 {
00336
00337 KiDispatchException1Args(STATUS_FLOAT_DIVIDE_BY_ZERO,
00338 ErrorOffset,
00339 0,
00340 TrapFrame);
00341 }
00342
00343
00344 if (Error & FSW_DENORMAL)
00345 {
00346
00347 KiDispatchException1Args(STATUS_FLOAT_INVALID_OPERATION,
00348 ErrorOffset,
00349 0,
00350 TrapFrame);
00351 }
00352
00353
00354 if (Error & FSW_OVERFLOW)
00355 {
00356
00357 KiDispatchException1Args(STATUS_FLOAT_OVERFLOW,
00358 ErrorOffset,
00359 0,
00360 TrapFrame);
00361 }
00362
00363
00364 if (Error & FSW_UNDERFLOW)
00365 {
00366
00367 KiDispatchException1Args(STATUS_FLOAT_UNDERFLOW,
00368 ErrorOffset,
00369 0,
00370 TrapFrame);
00371 }
00372
00373
00374 if (Error & FSW_PRECISION)
00375 {
00376
00377 KiDispatchException1Args(STATUS_FLOAT_INEXACT_RESULT,
00378 ErrorOffset,
00379 0,
00380 TrapFrame);
00381 }
00382
00383
00384 KeBugCheckWithTf(TRAP_CAUSE_UNKNOWN, 1, Error, 0, 0, TrapFrame);
00385 }
00386
00387 DECLSPEC_NORETURN
00388 VOID
00389 FASTCALL
00390 KiTrap00Handler(IN PKTRAP_FRAME TrapFrame)
00391 {
00392
00393 KiEnterTrap(TrapFrame);
00394
00395
00396 ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
00397
00398
00399 _enable();
00400
00401
00402 KiDispatchException0Args(STATUS_INTEGER_DIVIDE_BY_ZERO,
00403 TrapFrame->Eip,
00404 TrapFrame);
00405 }
00406
00407 DECLSPEC_NORETURN
00408 VOID
00409 FASTCALL
00410 KiTrap01Handler(IN PKTRAP_FRAME TrapFrame)
00411 {
00412
00413 KiEnterTrap(TrapFrame);
00414
00415
00416 ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
00417
00418
00419 if (KiUserTrap(TrapFrame)) _enable();
00420
00421
00422 TrapFrame->EFlags &= ~EFLAGS_TF;
00423 KiDispatchException0Args(STATUS_SINGLE_STEP,
00424 TrapFrame->Eip,
00425 TrapFrame);
00426 }
00427
00428 DECLSPEC_NORETURN
00429 VOID
00430 __cdecl
00431 KiTrap02(VOID)
00432 {
00433 PKTSS Tss, NmiTss;
00434 PKTHREAD Thread;
00435 PKPROCESS Process;
00436 PKGDTENTRY TssGdt;
00437 KTRAP_FRAME TrapFrame;
00438 KIRQL OldIrql;
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448 _disable();
00449
00450
00451
00452
00453 Tss = PCR->TSS;
00454 Thread = ((PKIPCR)PCR)->PrcbData.CurrentThread;
00455 Process = Thread->ApcState.Process;
00456
00457
00458
00459
00460 Tss->CR3 = Process->DirectoryTableBase[0];
00461 Tss->IoMapBase = Process->IopmOffset;
00462 Tss->LDT = Process->LdtDescriptor.LimitLow ? KGDT_LDT : 0;
00463
00464
00465
00466
00467 TssGdt = &((PKIPCR)KeGetPcr())->GDT[KGDT_NMI_TSS / sizeof(KGDTENTRY)];
00468 NmiTss = (PKTSS)(ULONG_PTR)(TssGdt->BaseLow |
00469 TssGdt->HighWord.Bytes.BaseMid << 16 |
00470 TssGdt->HighWord.Bytes.BaseHi << 24);
00471
00472
00473
00474
00475
00476
00477
00478 PCR->TSS = NmiTss;
00479 __writeeflags(__readeflags() &~ EFLAGS_NESTED_TASK);
00480 TssGdt->HighWord.Bits.Dpl = 0;
00481 TssGdt->HighWord.Bits.Pres = 1;
00482 TssGdt->HighWord.Bits.Type = I386_TSS;
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 RtlZeroMemory(&TrapFrame, sizeof(KTRAP_FRAME));
00493 TrapFrame.HardwareSegSs = Tss->Ss0;
00494 TrapFrame.HardwareEsp = Tss->Esp0;
00495 TrapFrame.EFlags = Tss->EFlags;
00496 TrapFrame.SegCs = Tss->Cs;
00497 TrapFrame.Eip = Tss->Eip;
00498 TrapFrame.Ebp = Tss->Ebp;
00499 TrapFrame.Ebx = Tss->Ebx;
00500 TrapFrame.Esi = Tss->Esi;
00501 TrapFrame.Edi = Tss->Edi;
00502 TrapFrame.SegFs = Tss->Fs;
00503 TrapFrame.ExceptionList = PCR->NtTib.ExceptionList;
00504 TrapFrame.PreviousPreviousMode = -1;
00505 TrapFrame.Eax = Tss->Eax;
00506 TrapFrame.Ecx = Tss->Ecx;
00507 TrapFrame.Edx = Tss->Edx;
00508 TrapFrame.SegDs = Tss->Ds;
00509 TrapFrame.SegEs = Tss->Es;
00510 TrapFrame.SegGs = Tss->Gs;
00511 TrapFrame.DbgEip = Tss->Eip;
00512 TrapFrame.DbgEbp = Tss->Ebp;
00513
00514
00515
00516
00517 KiSaveProcessorState(&TrapFrame, NULL);
00518
00519
00520
00521
00522 if (!KiHandleNmi())
00523 {
00524
00525
00526
00527
00528
00529
00530
00531 OldIrql = PCR->Irql;
00532 PCR->Irql = HIGH_LEVEL;
00533 HalHandleNMI(NULL);
00534 PCR->Irql = OldIrql;
00535 }
00536
00537
00538
00539
00540
00541
00542
00543
00544 if (PCR->TSS->Backlink != KGDT_NMI_TSS)
00545 {
00546
00547
00548
00549 PCR->TSS = Tss;
00550
00551
00552
00553
00554 TssGdt->HighWord.Bits.Dpl = 0;
00555 TssGdt->HighWord.Bits.Pres = 1;
00556 TssGdt->HighWord.Bits.Type = I386_ACTIVE_TSS;
00557
00558
00559
00560
00561 __writeeflags(__readeflags() | EFLAGS_NESTED_TASK);
00562
00563
00564
00565
00566 KiIret();
00567 }
00568
00569
00570
00571
00572 KiSystemFatalException(EXCEPTION_NMI, NULL);
00573 }
00574
00575 DECLSPEC_NORETURN
00576 VOID
00577 FASTCALL
00578 KiTrap03Handler(IN PKTRAP_FRAME TrapFrame)
00579 {
00580
00581 KiEnterTrap(TrapFrame);
00582
00583
00584 KiDebugHandler(TrapFrame, BREAKPOINT_BREAK, 0, 0);
00585 }
00586
00587 DECLSPEC_NORETURN
00588 VOID
00589 FASTCALL
00590 KiTrap04Handler(IN PKTRAP_FRAME TrapFrame)
00591 {
00592
00593 KiEnterTrap(TrapFrame);
00594
00595
00596 ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
00597
00598
00599 _enable();
00600
00601
00602 KiDispatchException0Args(STATUS_INTEGER_OVERFLOW,
00603 TrapFrame->Eip - 1,
00604 TrapFrame);
00605 }
00606
00607 DECLSPEC_NORETURN
00608 VOID
00609 FASTCALL
00610 KiTrap05Handler(IN PKTRAP_FRAME TrapFrame)
00611 {
00612
00613 KiEnterTrap(TrapFrame);
00614
00615
00616 ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
00617
00618
00619 if (!KiUserTrap(TrapFrame)) KiSystemFatalException(EXCEPTION_BOUND_CHECK, TrapFrame);
00620
00621
00622 _enable();
00623
00624
00625 KiDispatchException0Args(STATUS_ARRAY_BOUNDS_EXCEEDED,
00626 TrapFrame->Eip,
00627 TrapFrame);
00628 }
00629
00630 DECLSPEC_NORETURN
00631 VOID
00632 FASTCALL
00633 KiTrap06Handler(IN PKTRAP_FRAME TrapFrame)
00634 {
00635 PUCHAR Instruction;
00636 ULONG i;
00637 KIRQL OldIrql;
00638
00639
00640 if (__builtin_expect(KiV86Trap(TrapFrame), 1))
00641 {
00642
00643 KiEnterV86Trap(TrapFrame);
00644
00645
00646 if (__builtin_expect(!PsGetCurrentProcess()->VdmObjects, 0))
00647 {
00648
00649 _enable();
00650
00651
00652 KiDispatchException0Args(STATUS_ILLEGAL_INSTRUCTION,
00653 TrapFrame->Eip,
00654 TrapFrame);
00655 }
00656
00657
00658 OldIrql = KfRaiseIrql(APC_LEVEL);
00659 _enable();
00660
00661
00662 if (!VdmDispatchBop(TrapFrame))
00663 {
00664
00665 UNIMPLEMENTED_FATAL();
00666 }
00667
00668
00669 KfLowerIrql(OldIrql);
00670 _disable();
00671
00672
00673 KiExitV86Trap(TrapFrame);
00674 }
00675
00676
00677 KiEnterTrap(TrapFrame);
00678
00679
00680 Instruction = (PUCHAR)TrapFrame->Eip;
00681 _enable();
00682
00683
00684 if (KiUserTrap(TrapFrame))
00685 {
00686
00687
00688
00689 for (i = 0; i < 4; i++)
00690 {
00691
00692 if (Instruction[i] == 0xF0)
00693 {
00694
00695 KiDispatchException0Args(STATUS_INVALID_LOCK_SEQUENCE,
00696 TrapFrame->Eip,
00697 TrapFrame);
00698 }
00699 }
00700
00701
00702 }
00703
00704
00705 KiDispatchException0Args(STATUS_ILLEGAL_INSTRUCTION,
00706 TrapFrame->Eip,
00707 TrapFrame);
00708
00709 }
00710
00711 DECLSPEC_NORETURN
00712 VOID
00713 FASTCALL
00714 KiTrap07Handler(IN PKTRAP_FRAME TrapFrame)
00715 {
00716 PKTHREAD Thread, NpxThread;
00717 PFX_SAVE_AREA SaveArea, NpxSaveArea;
00718 ULONG Cr0;
00719
00720
00721 KiEnterTrap(TrapFrame);
00722
00723
00724 while (TRUE)
00725 {
00726
00727 Thread = KeGetCurrentThread();
00728
00729
00730 SaveArea = KiGetThreadNpxArea(Thread);
00731
00732
00733 if (SaveArea->Cr0NpxState & CR0_EM)
00734 {
00735
00736 UNIMPLEMENTED_FATAL();
00737 }
00738
00739
00740 Cr0 = __readcr0();
00741 if (Thread->NpxState != NPX_STATE_LOADED)
00742 {
00743
00744 Cr0 &= ~(CR0_MP | CR0_EM | CR0_TS);
00745 __writecr0(Cr0);
00746
00747
00748 NpxThread = KeGetCurrentPrcb()->NpxThread;
00749 if (NpxThread)
00750 {
00751
00752 NpxSaveArea = KiGetThreadNpxArea(NpxThread);
00753
00754
00755 DPRINT("FIXME: Save FPU state: %p\n", NpxSaveArea);
00756
00757
00758
00759 NpxThread->NpxState = NPX_STATE_NOT_LOADED;
00760 }
00761
00762
00763
00764
00765
00766 Thread->NpxState = NPX_STATE_LOADED;
00767 KeGetCurrentPrcb()->NpxThread = Thread;
00768
00769
00770 _enable();
00771
00772
00773 if (!SaveArea->Cr0NpxState) KiEoiHelper(TrapFrame);
00774
00775
00776 _disable();
00777
00778
00779 Cr0 = __readcr0();
00780 Cr0 |= SaveArea->Cr0NpxState;
00781 __writecr0(Cr0);
00782
00783
00784 _enable();
00785 if (Cr0 & CR0_TS) KiEoiHelper(TrapFrame);
00786
00787
00788 __writecr0(__readcr0() &~ CR0_TS);
00789 _disable();
00790 }
00791 else
00792 {
00793
00794 break;
00795 }
00796 }
00797
00798
00799 if (Cr0 & CR0_TS)
00800 {
00801
00802
00803
00804
00805
00806 if (Cr0 & CR0_MP)
00807 {
00808
00809 __writecr0(__readcr0() &~ CR0_TS);
00810 KiEoiHelper(TrapFrame);
00811 }
00812
00813
00814 KeBugCheckWithTf(TRAP_CAUSE_UNKNOWN, 2, Cr0, 0, 0, TrapFrame);
00815 }
00816
00817
00818 KiNpxHandler(TrapFrame, Thread, SaveArea);
00819 }
00820
00821 DECLSPEC_NORETURN
00822 VOID
00823 FASTCALL
00824 KiTrap08Handler(IN PKTRAP_FRAME TrapFrame)
00825 {
00826
00827 KiSystemFatalException(EXCEPTION_DOUBLE_FAULT, TrapFrame);
00828 }
00829
00830 DECLSPEC_NORETURN
00831 VOID
00832 FASTCALL
00833 KiTrap09Handler(IN PKTRAP_FRAME TrapFrame)
00834 {
00835
00836 KiEnterTrap(TrapFrame);
00837
00838
00839 _enable();
00840 KiSystemFatalException(EXCEPTION_NPX_OVERRUN, TrapFrame);
00841 }
00842
00843 DECLSPEC_NORETURN
00844 VOID
00845 FASTCALL
00846 KiTrap0AHandler(IN PKTRAP_FRAME TrapFrame)
00847 {
00848
00849 KiEnterTrap(TrapFrame);
00850
00851
00852 ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
00853
00854
00855 KiSystemFatalException(EXCEPTION_INVALID_TSS, TrapFrame);
00856 }
00857
00858 DECLSPEC_NORETURN
00859 VOID
00860 FASTCALL
00861 KiTrap0BHandler(IN PKTRAP_FRAME TrapFrame)
00862 {
00863
00864 KiEnterTrap(TrapFrame);
00865
00866
00867 UNIMPLEMENTED;
00868 KiSystemFatalException(EXCEPTION_SEGMENT_NOT_PRESENT, TrapFrame);
00869 }
00870
00871 DECLSPEC_NORETURN
00872 VOID
00873 FASTCALL
00874 KiTrap0CHandler(IN PKTRAP_FRAME TrapFrame)
00875 {
00876
00877 KiEnterTrap(TrapFrame);
00878
00879
00880 UNIMPLEMENTED;
00881 KiSystemFatalException(EXCEPTION_STACK_FAULT, TrapFrame);
00882 }
00883
00884 DECLSPEC_NORETURN
00885 VOID
00886 FASTCALL
00887 KiTrap0DHandler(IN PKTRAP_FRAME TrapFrame)
00888 {
00889 ULONG i, j, Iopl;
00890 BOOLEAN Privileged = FALSE;
00891 PUCHAR Instructions;
00892 UCHAR Instruction = 0;
00893 KIRQL OldIrql;
00894
00895
00896 if (__builtin_expect(KiV86Trap(TrapFrame), 1))
00897 {
00898
00899 KiEnterV86Trap(TrapFrame);
00900
00901
00902 if (__builtin_expect(!PsGetCurrentProcess()->VdmObjects, 0))
00903 {
00904
00905 _enable();
00906
00907
00908 KiDispatchException0Args(STATUS_ILLEGAL_INSTRUCTION,
00909 TrapFrame->Eip,
00910 TrapFrame);
00911 }
00912
00913
00914 OldIrql = KfRaiseIrql(APC_LEVEL);
00915 _enable();
00916
00917
00918 if (__builtin_expect(Ki386HandleOpcodeV86(TrapFrame) == 0xFF, 0))
00919 {
00920
00921 UNIMPLEMENTED_FATAL();
00922 }
00923
00924
00925 KfLowerIrql(OldIrql);
00926 _disable();
00927
00928
00929 KiExitV86Trap(TrapFrame);
00930 }
00931
00932
00933 KiEnterTrap(TrapFrame);
00934
00935
00936 if (KiUserTrap(TrapFrame))
00937 {
00938
00939 ASSERT(KiVdmTrap(TrapFrame) == FALSE);
00940
00941
00942 _enable();
00943 if (!TrapFrame->ErrCode)
00944 {
00945
00946 Instructions = (PUCHAR)TrapFrame->Eip;
00947
00948
00949 for (i = 0; i < 15; i++)
00950 {
00951
00952 for (j = 0; j < sizeof(KiTrapPrefixTable); j++)
00953 {
00954
00955 if (Instructions[i] == KiTrapPrefixTable[j])
00956 {
00957
00958 break;
00959 }
00960 }
00961
00962
00963 if (j == sizeof(KiTrapPrefixTable))
00964 {
00965
00966 Instruction = Instructions[i];
00967 break;
00968 }
00969 }
00970
00971
00972 if (i == 15)
00973 {
00974
00975 KiDispatchException0Args(STATUS_ILLEGAL_INSTRUCTION,
00976 TrapFrame->Eip,
00977 TrapFrame);
00978 }
00979
00980
00981 DPRINT("Instruction (%d) at fault: %lx %lx %lx %lx\n",
00982 i,
00983 Instructions[i],
00984 Instructions[i + 1],
00985 Instructions[i + 2],
00986 Instructions[i + 3]);
00987 if (Instruction == 0xF4)
00988 {
00989
00990 Privileged = TRUE;
00991 }
00992 else if (Instruction == 0x0F)
00993 {
00994
00995 if (((Instructions[i + 1] == 0x00) &&
00996 (((Instructions[i + 2] & 0x38) == 0x10) ||
00997 (Instructions[i + 2] == 0x18))) ||
00998 ((Instructions[i + 1] == 0x01) &&
00999 (((Instructions[i + 2] & 0x38) == 0x10) ||
01000 (Instructions[i + 2] == 0x18) ||
01001 (Instructions[i + 2] == 0x30))) ||
01002 (Instructions[i + 1] == 0x08) ||
01003 (Instructions[i + 1] == 0x09) ||
01004 (Instructions[i + 1] == 0x35) ||
01005 (Instructions[i + 1] == 0x21) ||
01006 (Instructions[i + 1] == 0x06) ||
01007 (Instructions[i + 1] == 0x20) ||
01008 (Instructions[i + 1] == 0x22) ||
01009 (Instructions[i + 1] == 0x23) ||
01010 (Instructions[i + 1] == 0x30) ||
01011 (Instructions[i + 1] == 0x33))
01012
01013 {
01014
01015 Privileged = TRUE;
01016 }
01017 }
01018 else
01019 {
01020
01021 Iopl = (TrapFrame->EFlags & EFLAGS_IOPL) >> 12;
01022 if ((TrapFrame->SegCs & RPL_MASK) > Iopl)
01023 {
01024
01025 if ((Instruction == 0xFA) || (Instruction == 0xFB))
01026 {
01027
01028 Privileged = TRUE;
01029 }
01030 else
01031 {
01032
01033 for (j = 0; j < sizeof(KiTrapIoTable); j++)
01034 {
01035
01036 if (Instruction == KiTrapIoTable[j])
01037 {
01038
01039 Privileged = TRUE;
01040 break;
01041 }
01042 }
01043 }
01044 }
01045 }
01046
01047
01048 if (Privileged)
01049 {
01050
01051 KiDispatchException0Args(STATUS_PRIVILEGED_INSTRUCTION,
01052 TrapFrame->Eip,
01053 TrapFrame);
01054 }
01055 }
01056
01057
01058 KiDispatchException2Args(STATUS_ACCESS_VIOLATION,
01059 TrapFrame->Eip,
01060 0,
01061 0xFFFFFFFF,
01062 TrapFrame);
01063 }
01064
01065
01066
01067
01068
01069
01070
01071
01072 if (((PVOID)TrapFrame->Eip >= (PVOID)KiTrap0DHandler) &&
01073 ((PVOID)TrapFrame->Eip < (PVOID)KiTrap0DHandler))
01074 {
01075
01076 UNIMPLEMENTED_FATAL();
01077 }
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113 Instructions = (PUCHAR)TrapFrame->Eip;
01114 if (Instructions[0] == 0xCF)
01115 {
01116
01117
01118
01119
01120
01121
01122 if ((TrapFrame->HardwareEsp == (ULONG)Ki386BiosCallReturnAddress) &&
01123 (TrapFrame->HardwareSegSs == (KGDT_R0_CODE | RPL_MASK)))
01124 {
01125
01126 Ki386BiosCallReturnAddress(TrapFrame);
01127 }
01128 else
01129 {
01130
01131 UNIMPLEMENTED_FATAL();
01132 }
01133 }
01134
01135
01136 if ((Instructions[0] == 0xF) &&
01137 ((Instructions[1] == 0x32) ||
01138 (Instructions[1] == 0x30)))
01139 {
01140
01141 KiDispatchException0Args(STATUS_ACCESS_VIOLATION,
01142 TrapFrame->Eip,
01143 TrapFrame);
01144 }
01145
01146
01147 if (TrapFrame->SegDs != (KGDT_R3_DATA | RPL_MASK))
01148 {
01149
01150 TrapFrame->SegDs = (KGDT_R3_DATA | RPL_MASK);
01151 }
01152 else if (TrapFrame->SegEs != (KGDT_R3_DATA | RPL_MASK))
01153 {
01154
01155 TrapFrame->SegEs = (KGDT_R3_DATA | RPL_MASK);
01156 }
01157 else
01158 {
01159
01160 KiSystemFatalException(EXCEPTION_GP_FAULT, TrapFrame);
01161 }
01162
01163
01164 KiTrapReturn(TrapFrame);
01165 }
01166
01167 DECLSPEC_NORETURN
01168 VOID
01169 FASTCALL
01170 KiTrap0EHandler(IN PKTRAP_FRAME TrapFrame)
01171 {
01172 PKTHREAD Thread;
01173 ULONG_PTR Cr2;
01174 NTSTATUS Status;
01175
01176
01177 KiEnterTrap(TrapFrame);
01178
01179
01180 Thread = KeGetCurrentThread();
01181 if (KeGetTrapFrame(Thread) != TrapFrame)
01182 {
01183
01184 if (((ULONG_PTR)KeGetTrapFrame(Thread) - (ULONG_PTR)TrapFrame) <=
01185 FIELD_OFFSET(KTRAP_FRAME, EFlags))
01186 {
01187
01188 UNIMPLEMENTED_FATAL();
01189 }
01190 }
01191
01192
01193 Cr2 = __readcr2();
01194
01195
01196 _enable();
01197
01198
01199 if (!(TrapFrame->EFlags & EFLAGS_INTERRUPT_MASK))
01200 {
01201
01202 KeBugCheckWithTf(IRQL_NOT_LESS_OR_EQUAL,
01203 Cr2,
01204 -1,
01205 TrapFrame->ErrCode & 2 ? TRUE : FALSE,
01206 TrapFrame->Eip,
01207 TrapFrame);
01208 }
01209
01210
01211 if (TrapFrame->Eip == (ULONG_PTR)ExpInterlockedPopEntrySListFault)
01212 {
01213 PSLIST_HEADER SListHeader;
01214
01215
01216
01217
01218 ASSERT((((UCHAR*)TrapFrame->Eip)[0] == 0x8B) &&
01219 (((UCHAR*)TrapFrame->Eip)[1] == 0x18) &&
01220 (((UCHAR*)TrapFrame->Eip)[2] == 0x0F) &&
01221 (((UCHAR*)TrapFrame->Eip)[3] == 0xC7) &&
01222 (((UCHAR*)TrapFrame->Eip)[4] == 0x4D) &&
01223 (((UCHAR*)TrapFrame->Eip)[5] == 0x00));
01224
01225
01226 SListHeader = (PSLIST_HEADER)TrapFrame->Ebp;
01227
01228
01229 if (SListHeader->Next.Next != (PSLIST_ENTRY)TrapFrame->Eax)
01230 {
01231
01232 TrapFrame->Eip = (ULONG_PTR)ExpInterlockedPopEntrySListResume;
01233
01234
01235 KiEoiHelper(TrapFrame);
01236 }
01237 }
01238
01239
01240 Status = MmAccessFault(TrapFrame->ErrCode & 1,
01241 (PVOID)Cr2,
01242 TrapFrame->SegCs & MODE_MASK,
01243 TrapFrame);
01244 if (NT_SUCCESS(Status)) KiEoiHelper(TrapFrame);
01245
01246
01247 #if 0
01248 if ((TrapFrame->Eip == (ULONG_PTR)CopyParams) ||
01249 (TrapFrame->Eip == (ULONG_PTR)ReadBatch))
01250 {
01251
01252 UNIMPLEMENTED_FATAL();
01253 }
01254 #endif
01255
01256 ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
01257
01258
01259 if (Status == STATUS_ACCESS_VIOLATION)
01260 {
01261
01262 KiDispatchException2Args(KI_EXCEPTION_ACCESS_VIOLATION,
01263 TrapFrame->Eip,
01264 TrapFrame->ErrCode & 2 ? TRUE : FALSE,
01265 Cr2,
01266 TrapFrame);
01267 }
01268 else if ((Status == STATUS_GUARD_PAGE_VIOLATION) ||
01269 (Status == STATUS_STACK_OVERFLOW))
01270 {
01271
01272 KiDispatchException2Args(Status,
01273 TrapFrame->Eip,
01274 TrapFrame->ErrCode & 2 ? TRUE : FALSE,
01275 Cr2,
01276 TrapFrame);
01277 }
01278
01279
01280 KiDispatchExceptionFromTrapFrame(STATUS_IN_PAGE_ERROR,
01281 TrapFrame->Eip,
01282 3,
01283 TrapFrame->ErrCode & 2 ? TRUE : FALSE,
01284 Cr2,
01285 Status,
01286 TrapFrame);
01287 }
01288
01289 DECLSPEC_NORETURN
01290 VOID
01291 FASTCALL
01292 KiTrap0FHandler(IN PKTRAP_FRAME TrapFrame)
01293 {
01294
01295 KiEnterTrap(TrapFrame);
01296
01297
01298 UNIMPLEMENTED;
01299 KiSystemFatalException(EXCEPTION_RESERVED_TRAP, TrapFrame);
01300 }
01301
01302 DECLSPEC_NORETURN
01303 VOID
01304 FASTCALL
01305 KiTrap10Handler(IN PKTRAP_FRAME TrapFrame)
01306 {
01307 PKTHREAD Thread;
01308 PFX_SAVE_AREA SaveArea;
01309
01310
01311 KiEnterTrap(TrapFrame);
01312
01313
01314 Thread = KeGetCurrentThread();
01315 SaveArea = KiGetThreadNpxArea(Thread);
01316 if (Thread != KeGetCurrentPrcb()->NpxThread)
01317 {
01318
01319 _enable();
01320 SaveArea->Cr0NpxState |= CR0_TS;
01321
01322
01323 KiEoiHelper(TrapFrame);
01324 }
01325
01326
01327 KiNpxHandler(TrapFrame, Thread, SaveArea);
01328 }
01329
01330 DECLSPEC_NORETURN
01331 VOID
01332 FASTCALL
01333 KiTrap11Handler(IN PKTRAP_FRAME TrapFrame)
01334 {
01335
01336 KiEnterTrap(TrapFrame);
01337
01338
01339 _enable();
01340 KiSystemFatalException(EXCEPTION_ALIGNMENT_CHECK, TrapFrame);
01341 }
01342
01343 DECLSPEC_NORETURN
01344 VOID
01345 FASTCALL
01346 KiTrap13Handler(IN PKTRAP_FRAME TrapFrame)
01347 {
01348 PKTHREAD Thread;
01349 PFX_SAVE_AREA SaveArea;
01350 ULONG Cr0, MxCsrMask, Error;
01351
01352
01353 KiEnterTrap(TrapFrame);
01354
01355
01356 Thread = KeGetCurrentThread();
01357 if (Thread != KeGetCurrentPrcb()->NpxThread)
01358 {
01359
01360 KeBugCheckWithTf(TRAP_CAUSE_UNKNOWN, 13, (ULONG_PTR)Thread, 0, 0, TrapFrame);
01361 }
01362
01363
01364 SaveArea = KiGetThreadNpxArea(Thread);
01365
01366
01367 ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
01368
01369
01370 if (!KiUserTrap(TrapFrame))
01371 {
01372
01373 KeBugCheckWithTf(TRAP_CAUSE_UNKNOWN, 13, 0, 0, 2, TrapFrame);
01374 }
01375
01376
01377 Cr0 = __readcr0();
01378 Cr0 &= ~(CR0_MP | CR0_EM | CR0_TS);
01379 __writecr0(Cr0);
01380
01381
01382 Ke386SaveFpuState(SaveArea);
01383
01384
01385 Cr0 |= NPX_STATE_NOT_LOADED;
01386 Cr0 |= SaveArea->Cr0NpxState;
01387 __writecr0(Cr0);
01388
01389
01390 Thread->NpxState = NPX_STATE_NOT_LOADED;
01391 KeGetCurrentPrcb()->NpxThread = NULL;
01392
01393
01394 SaveArea->Cr0NpxState &= ~CR0_TS;
01395 _enable();
01396
01397
01398 MxCsrMask = ~((USHORT)SaveArea->U.FxArea.MXCsr >> 7);
01399
01400
01401 Error = (USHORT)SaveArea->U.FxArea.MXCsr & (FSW_INVALID_OPERATION |
01402 FSW_DENORMAL |
01403 FSW_ZERO_DIVIDE |
01404 FSW_OVERFLOW |
01405 FSW_UNDERFLOW |
01406 FSW_PRECISION);
01407 Error &= MxCsrMask;
01408
01409
01410 if (Error & (FSW_INVALID_OPERATION |
01411 FSW_DENORMAL |
01412 FSW_ZERO_DIVIDE |
01413 FSW_OVERFLOW |
01414 FSW_UNDERFLOW |
01415 FSW_PRECISION))
01416 {
01417
01418 KiDispatchException1Args(STATUS_FLOAT_MULTIPLE_TRAPS,
01419 TrapFrame->Eip,
01420 0,
01421 TrapFrame);
01422 }
01423
01424
01425 KeBugCheckWithTf(TRAP_CAUSE_UNKNOWN, 13, 0, 0, 1, TrapFrame);
01426 }
01427
01428
01429
01430 VOID
01431 FASTCALL
01432 KiGetTickCountHandler(IN PKTRAP_FRAME TrapFrame)
01433 {
01434 UNIMPLEMENTED_DBGBREAK();
01435 }
01436
01437 VOID
01438 FASTCALL
01439 KiCallbackReturnHandler(IN PKTRAP_FRAME TrapFrame)
01440 {
01441 UNIMPLEMENTED_DBGBREAK();
01442 }
01443
01444 DECLSPEC_NORETURN
01445 VOID
01446 FASTCALL
01447 KiRaiseAssertionHandler(IN PKTRAP_FRAME TrapFrame)
01448 {
01449
01450 KiEnterTrap(TrapFrame);
01451
01452
01453 TrapFrame->Eip -= 2;
01454
01455
01456 KiDispatchException0Args(STATUS_ASSERTION_FAILURE,
01457 TrapFrame->Eip,
01458 TrapFrame);
01459 }
01460
01461 DECLSPEC_NORETURN
01462 VOID
01463 FASTCALL
01464 KiDebugServiceHandler(IN PKTRAP_FRAME TrapFrame)
01465 {
01466
01467 KiEnterTrap(TrapFrame);
01468
01469
01470 TrapFrame->Eip++;
01471
01472
01473 KiDebugHandler(TrapFrame, TrapFrame->Eax, TrapFrame->Ecx, TrapFrame->Edx);
01474 }
01475
01476
01477 FORCEINLINE
01478 VOID
01479 KiDbgPreServiceHook(ULONG SystemCallNumber, PULONG_PTR Arguments)
01480 {
01481 #if DBG && !defined(_WINKD_)
01482 if (SystemCallNumber >= 0x1000 && KeWin32PreServiceHook)
01483 KeWin32PreServiceHook(SystemCallNumber, Arguments);
01484 #endif
01485 }
01486
01487 FORCEINLINE
01488 ULONG_PTR
01489 KiDbgPostServiceHook(ULONG SystemCallNumber, ULONG_PTR Result)
01490 {
01491 #if DBG && !defined(_WINKD_)
01492 if (SystemCallNumber >= 0x1000 && KeWin32PostServiceHook)
01493 return KeWin32PostServiceHook(SystemCallNumber, Result);
01494 #endif
01495 return Result;
01496 }
01497
01498 DECLSPEC_NORETURN
01499 VOID
01500 FORCEINLINE
01501 KiSystemCall(IN PKTRAP_FRAME TrapFrame,
01502 IN PVOID Arguments)
01503 {
01504 PKTHREAD Thread;
01505 PKSERVICE_TABLE_DESCRIPTOR DescriptorTable;
01506 ULONG Id, Offset, StackBytes, Result;
01507 PVOID Handler;
01508 ULONG SystemCallNumber = TrapFrame->Eax;
01509
01510
01511 Thread = KeGetCurrentThread();
01512
01513
01514 KiFillTrapFrameDebug(TrapFrame);
01515
01516
01517 TrapFrame->Edx = (ULONG_PTR)Thread->TrapFrame;
01518
01519
01520 TrapFrame->ErrCode = 0;
01521
01522
01523 TrapFrame->PreviousPreviousMode = Thread->PreviousMode;
01524
01525
01526 TrapFrame->ExceptionList = KeGetPcr()->NtTib.ExceptionList;
01527 KeGetPcr()->NtTib.ExceptionList = EXCEPTION_CHAIN_END;
01528
01529
01530 TrapFrame->Dr7 = 0;
01531
01532
01533 if (TrapFrame->SegCs & MODE_MASK)
01534 {
01535
01536 if (KeGetCurrentThread()->Header.DebugActive & 0xFF)
01537 {
01538
01539 KiHandleDebugRegistersOnTrapEntry(TrapFrame);
01540 }
01541 }
01542
01543
01544 Thread->TrapFrame = TrapFrame;
01545 Thread->PreviousMode = KiUserTrap(TrapFrame);
01546
01547
01548 _enable();
01549
01550
01551 Offset = (SystemCallNumber >> SERVICE_TABLE_SHIFT) & SERVICE_TABLE_MASK;
01552 Id = SystemCallNumber & SERVICE_NUMBER_MASK;
01553
01554
01555 DescriptorTable = (PVOID)((ULONG_PTR)Thread->ServiceTable + Offset);
01556
01557
01558 if (__builtin_expect(Id >= DescriptorTable->Limit, 0))
01559 {
01560
01561 if (!(Offset & SERVICE_TABLE_TEST))
01562 {
01563
01564 Result = STATUS_INVALID_SYSTEM_SERVICE;
01565 goto ExitCall;
01566 }
01567
01568
01569 Result = KiConvertToGuiThread();
01570
01571
01572 TrapFrame = *(volatile PVOID*)&Thread->TrapFrame;
01573 DescriptorTable = (PVOID)(*(volatile ULONG_PTR*)&Thread->ServiceTable + Offset);
01574
01575 if (!NT_SUCCESS(Result))
01576 {
01577
01578
01579 goto ExitCall;
01580 }
01581
01582
01583 if (Id >= DescriptorTable->Limit)
01584 {
01585
01586 Result = STATUS_INVALID_SYSTEM_SERVICE;
01587 goto ExitCall;
01588 }
01589 }
01590
01591
01592 if (__builtin_expect(Offset & SERVICE_TABLE_TEST, 0))
01593 {
01594
01595 if (NtCurrentTeb()->GdiBatchCount) KeGdiFlushUserBatch();
01596 }
01597
01598
01599 KeGetCurrentPrcb()->KeSystemCalls++;
01600
01601
01602
01603
01604
01605 StackBytes = DescriptorTable->Number[Id];
01606
01607
01608 if (__builtin_expect((Arguments < (PVOID)MmUserProbeAddress) && !(KiUserTrap(TrapFrame)), 0))
01609 {
01610
01611 UNIMPLEMENTED_FATAL();
01612 }
01613
01614
01615 KiDbgPreServiceHook(SystemCallNumber, Arguments);
01616
01617
01618 Handler = (PVOID)DescriptorTable->Base[Id];
01619 Result = KiSystemCallTrampoline(Handler, Arguments, StackBytes);
01620
01621
01622 Result = KiDbgPostServiceHook(SystemCallNumber, Result);
01623
01624
01625 KiExitSystemCallDebugChecks(Id, TrapFrame);
01626
01627
01628 ExitCall:
01629 Thread->TrapFrame = (PKTRAP_FRAME)TrapFrame->Edx;
01630
01631
01632 KiServiceExit(TrapFrame, Result);
01633 }
01634
01635 DECLSPEC_NORETURN
01636 VOID
01637 FASTCALL
01638 KiSystemServiceHandler(IN PKTRAP_FRAME TrapFrame,
01639 IN PVOID Arguments)
01640 {
01641
01642 KiSystemCall(TrapFrame, Arguments);
01643 }
01644
01645 DECLSPEC_NORETURN
01646 VOID
01647 FASTCALL
01648 KiFastCallEntryHandler(IN PKTRAP_FRAME TrapFrame,
01649 IN PVOID Arguments)
01650 {
01651
01652 TrapFrame->HardwareSegSs = KGDT_R3_DATA | RPL_MASK;
01653 TrapFrame->HardwareEsp = (ULONG_PTR)Arguments;
01654 TrapFrame->EFlags = __readeflags() | EFLAGS_INTERRUPT_MASK;
01655 TrapFrame->SegCs = KGDT_R3_CODE | RPL_MASK;
01656 TrapFrame->Eip = SharedUserData->SystemCallReturn;
01657 TrapFrame->SegFs = KGDT_R3_TEB | RPL_MASK;
01658 __writeeflags(0x2);
01659
01660
01661 Arguments = (PVOID)(TrapFrame->HardwareEsp + 8);
01662
01663
01664 KiSystemCall(TrapFrame, Arguments);
01665 }
01666
01667
01668
01669
01670 VOID
01671 NTAPI
01672 Kei386EoiHelper(VOID)
01673 {
01674
01675 ERROR_FATAL("Mismatched NT/HAL version");
01676 }
01677
01678