00323 :
00324
00325 This function
is called to dispatch an exception to
the proper mode and
00326 to cause
the exception dispatcher to be called.
00327
00328 If
the exception
is a data misalignment,
the previous mode
is user,
this
00329
is the first chance
for handling
the exception, and
the current thread
00330 has enabled automatic alignment fixup, then an attempt
is made to emulate
00331
the unaligned reference. Data misalignment exceptions are never emulated
00332
for kernel mode.
00333
00334 If
the exception
is a floating exception (N.B. the pseudo status
00335 STATUS_FLOAT_STACK_CHECK is used to signify
this and is converted to the
00336 proper code by the floating emulation routine), then an attempt
is made
00337 to emulate
the floating operation
if it is not implemented.
00338
00339 If
the exception
is neither a data misalignment nor a floating point
00340 exception and
the the previous mode
is kernel, then
the exception
00341 dispatcher
is called directly to process
the exception. Otherwise
the
00342 exception record, exception frame, and trap frame contents are copied
00343 to
the user mode stack. The contents of
the exception frame and trap
00344 are then modified such that when
control is returned, execution will
00345 commense in user mode in a routine which will call
the exception
00346 dispatcher.
00347
00348 Arguments:
00349
00350 ExceptionRecord - Supplies a pointer to an exception record.
00351
00352 ExceptionFrame - Supplies a pointer to an exception frame.
00353
00354 TrapFrame - Supplies a pointer to a trap frame.
00355
00356 PreviousMode - Supplies
the previous processor mode.
00357
00358 FirstChance - Supplies a
boolean variable that specifies whether
this
00359
is the first (TRUE) or second (FALSE) time that this exception has
00360 been processed.
00361
00362 Return Value:
00363
00364 None.
00365
00366 --*/
00367
00368 {
00369
00370 CONTEXT ContextFrame;
00371 PULONG Destination;
00372 EXCEPTION_RECORD ExceptionRecord1;
00373 ULONG
Index;
00374 LONG Length;
00375 PULONGLONG Source;
00376 BOOLEAN UserApcPending;
00377 ULONG UserStack1;
00378 ULONG UserStack2;
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
if ((ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION) &&
00392 (((ULONG)ExceptionRecord->ExceptionAddress & 0xffc) == 0xffc) &&
00393 (PreviousMode !=
KernelMode) &&
00394 (
KiEmulateReference(ExceptionRecord, ExceptionFrame, TrapFrame) !=
FALSE)) {
00395
KeGetCurrentPrcb()->KeAlignmentFixupCount += 1;
00396
goto Handled2;
00397 }
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
if (ExceptionRecord->ExceptionCode == (
DATA_BUS_ERROR | 0xdfff0000)) {
00411
00412
00413
00414
00415
00416
00417
00418
00419
if ((ExceptionRecord->ExceptionInformation[1] < 0x80000000) &&
00420 (((ULONG)ExceptionRecord->ExceptionAddress & 0xffc) == 0xffc) &&
00421 (PreviousMode !=
KernelMode)) {
00422
if (
KiEmulateReference(ExceptionRecord, ExceptionFrame, TrapFrame) !=
FALSE) {
00423
KeGetCurrentPrcb()->KeAlignmentFixupCount += 1;
00424
goto Handled2;
00425 }
00426 }
00427
00428
KiDataBusError(ExceptionRecord, ExceptionFrame, TrapFrame);
00429
goto Handled2;
00430 }
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
if (ExceptionRecord->ExceptionCode == (
INSTRUCTION_BUS_ERROR | 0xdfff0000)) {
00444
KiInstructionBusError(ExceptionRecord, ExceptionFrame, TrapFrame);
00445
goto Handled2;
00446 }
00447
00448
00449
00450
00451
00452
00453
00454
if ((ExceptionRecord->ExceptionCode == STATUS_DATATYPE_MISALIGNMENT) &&
00455 (FirstChance !=
FALSE) &&
00456 ((
KeGetCurrentThread()->AutoAlignment !=
FALSE) ||
00457 (
KeGetCurrentThread()->ApcState.Process->AutoAlignment !=
FALSE) ||
00458 (((ExceptionRecord->ExceptionInformation[1] & 0x7fff0000) == 0x7fff0000) &&
00459 (PreviousMode !=
KernelMode))) &&
00460 (
KiEmulateReference(ExceptionRecord, ExceptionFrame, TrapFrame) !=
FALSE)) {
00461
KeGetCurrentPrcb()->KeAlignmentFixupCount += 1;
00462
goto Handled2;
00463 }
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
if ((ExceptionRecord->ExceptionCode == STATUS_FLOAT_STACK_CHECK) &&
00477 (
KiEmulateFloating(ExceptionRecord, ExceptionFrame, TrapFrame) !=
FALSE)) {
00478 TrapFrame->Fsr = SANITIZE_FSR(TrapFrame->Fsr, PreviousMode);
00479
goto Handled2;
00480 }
00481
00482
00483
00484
00485
00486
00487
00488
if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) {
00489
if (ExceptionRecord->ExceptionInformation[0] ==
DIVIDE_BREAKPOINT) {
00490 ExceptionRecord->ExceptionCode = STATUS_INTEGER_DIVIDE_BY_ZERO;
00491
00492 }
else if ((ExceptionRecord->ExceptionInformation[0] ==
MULTIPLY_BREAKPOINT) ||
00493 (ExceptionRecord->ExceptionInformation[0] ==
OVERFLOW_BREAKPOINT)) {
00494 ExceptionRecord->ExceptionCode = STATUS_INTEGER_OVERFLOW;
00495
00496 }
else if (ExceptionRecord->ExceptionInformation[0] ==
KDDEBUG_BREAKPOINT) {
00497 TrapFrame->Fir += 4;
00498 }
00499 }
00500
00501
00502
00503
00504
00505
00506 ContextFrame.ContextFlags =
CONTEXT_FULL;
00507
KeContextFromKframes(TrapFrame, ExceptionFrame, &ContextFrame);
00508
KeGetCurrentPrcb()->KeExceptionDispatchCount += 1;
00509
00510
00511
00512
00513
00514
if (PreviousMode ==
KernelMode) {
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
if (FirstChance !=
FALSE) {
00534
00535
00536
00537
00538
00539
00540
00541
if ((
KiDebugRoutine !=
NULL) &&
00542 (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
00543 (
KdIsThisAKdTrap(ExceptionRecord,
00544 &ContextFrame,
00545 KernelMode) !=
FALSE)) {
00546
00547
if (((
KiDebugRoutine) (TrapFrame,
00548 ExceptionFrame,
00549 ExceptionRecord,
00550 &ContextFrame,
00551
KernelMode,
00552
FALSE)) !=
FALSE) {
00553
00554
goto Handled1;
00555 }
00556 }
00557
00558
00559
00560
00561
00562
if (
RtlDispatchException(ExceptionRecord, &ContextFrame) !=
FALSE) {
00563
goto Handled1;
00564 }
00565 }
00566
00567
00568
00569
00570
00571
if (
KiDebugRoutine !=
NULL) {
00572
if (((
KiDebugRoutine) (TrapFrame,
00573 ExceptionFrame,
00574 ExceptionRecord,
00575 &ContextFrame,
00576 PreviousMode,
00577
TRUE)) !=
FALSE) {
00578
goto Handled1;
00579 }
00580 }
00581
00582
KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,
00583 ExceptionRecord->ExceptionCode,
00584 (ULONG)ExceptionRecord->ExceptionAddress,
00585 ExceptionRecord->ExceptionInformation[0],
00586 ExceptionRecord->ExceptionInformation[1]);
00587
00588 }
else {
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
if (FirstChance !=
FALSE) {
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
if ((
KiDebugRoutine !=
NULL) &&
00627 (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
00628 (
KdIsThisAKdTrap(ExceptionRecord,
00629 &ContextFrame,
00630 UserMode) !=
FALSE) &&
00631 ((
PsGetCurrentProcess()->DebugPort ==
NULL) ||
00632 ((
PsGetCurrentProcess()->DebugPort !=
NULL) &&
00633 (ExceptionRecord->ExceptionInformation[0] !=
00634
KERNEL_BREAKPOINT_INSTRUCTION)))) {
00635
00636
if (((
KiDebugRoutine) (TrapFrame,
00637 ExceptionFrame,
00638 ExceptionRecord,
00639 &ContextFrame,
00640
UserMode,
00641
FALSE)) !=
FALSE) {
00642
00643
goto Handled1;
00644 }
00645 }
00646
00647
00648
00649
00650
00651
if (
DbgkForwardException(ExceptionRecord, TRUE, FALSE)) {
00652 TrapFrame->Fsr = SANITIZE_FSR(TrapFrame->Fsr, UserMode);
00653
goto Handled2;
00654 }
00655
00656
00657
00658
00659
00660
00661
00662 repeat:
00663
try {
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675 Destination = &ContextFrame.IntZero;
00676 Source = &ContextFrame.XIntZero;
00677
for (
Index = 0;
Index < 32;
Index += 1) {
00678 *Destination++ = (ULONG)*Source++;
00679 }
00680
00681
00682
00683
00684
00685
00686 Length = (
sizeof(EXCEPTION_RECORD) + 7) & (~7);
00687 UserStack1 = (ULONG)(ContextFrame.XIntSp & (~7)) - Length;
00688
00689
00690
00691
00692
00693
00694
ProbeForWrite((PCHAR)UserStack1, Length,
sizeof(QUAD));
00695 RtlMoveMemory((PVOID)UserStack1, ExceptionRecord, Length);
00696
00697
00698
00699
00700
00701
00702 Length =
sizeof(CONTEXT);
00703 UserStack2 = UserStack1 - Length;
00704
00705
00706
00707
00708
00709
00710
ProbeForWrite((PCHAR)UserStack2, Length,
sizeof(QUAD));
00711 RtlMoveMemory((PVOID)UserStack2, &ContextFrame,
sizeof(CONTEXT));
00712
00713
00714
00715
00716
00717
00718 TrapFrame->XIntSp = (LONG)UserStack2;
00719 TrapFrame->XIntS8 = (LONG)UserStack2;
00720 TrapFrame->XIntS0 = (LONG)UserStack1;
00721 TrapFrame->XIntS1 = (LONG)UserStack2;
00722
00723
00724
00725
00726
00727
00728 TrapFrame->Fsr = SANITIZE_FSR(ContextFrame.Fsr, UserMode);
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738 TrapFrame->Fir =
KeUserExceptionDispatcher;
00739
return;
00740
00741
00742
00743
00744
00745
00746 } except (
KiCopyInformation(&ExceptionRecord1,
00747 (GetExceptionInformation())->ExceptionRecord)) {
00748
00749
00750
00751
00752
00753
00754
00755
00756
if (ExceptionRecord1.ExceptionCode == STATUS_STACK_OVERFLOW) {
00757 ExceptionRecord1.ExceptionAddress = ExceptionRecord->ExceptionAddress;
00758 RtlMoveMemory((PVOID)ExceptionRecord,
00759 &ExceptionRecord1,
sizeof(EXCEPTION_RECORD));
00760
goto repeat;
00761 }
00762 }
00763 }
00764
00765
00766
00767
00768
00769 UserApcPending =
KeGetCurrentThread()->ApcState.UserApcPending;
00770
if (
DbgkForwardException(ExceptionRecord, TRUE, TRUE)) {
00771 TrapFrame->Fsr = SANITIZE_FSR(TrapFrame->Fsr, UserMode);
00772
goto Handled2;
00773
00774 }
else if (
DbgkForwardException(ExceptionRecord, FALSE, TRUE)) {
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
if ((UserApcPending ==
FALSE) &&
00785 (
KeGetCurrentThread()->ApcState.UserApcPending !=
FALSE)) {
00786 TrapFrame->Fir = (ULONG)USPCR;
00787 }
00788
00789 TrapFrame->Fsr = SANITIZE_FSR(TrapFrame->Fsr, UserMode);
00790
goto Handled2;
00791
00792 }
else {
00793 ZwTerminateProcess(NtCurrentProcess(), ExceptionRecord->ExceptionCode);
00794
KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,
00795 ExceptionRecord->ExceptionCode,
00796 (ULONG)ExceptionRecord->ExceptionAddress,
00797 ExceptionRecord->ExceptionInformation[0],
00798 ExceptionRecord->ExceptionInformation[1]);
00799 }
00800 }
00801
00802
00803
00804
00805
00806
00807 Handled1:
00808
KeContextToKframes(TrapFrame, ExceptionFrame, &ContextFrame,
00809 ContextFrame.ContextFlags, PreviousMode);
00810
00811
00812
00813
00814
00815
00816
00817
00818 Handled2:
00819
return;
00820 }