00240                    :
00241 
00242     This function 
is called to dispatch an exception to 
the proper mode and
00243     to cause 
the exception dispatcher to be called.
00244 
00245     If 
the exception 
is a data misalignment, 
this is the first chance 
for
00246     handling 
the exception, and 
the current thread has enabled automatic
00247     alignment fixup, then an attempt 
is made to emulate 
the unaligned
00248     reference.
00249 
00250     If 
the exception 
is a floating exception (N.B. the pseudo status
00251     STATUS_FLOAT_STACK_CHECK is used to signify 
this and is converted to the
00252     proper code by examiningg the main status field of the floating point 
00253     status 
register).
00254 
00255     If 
the exception 
is neither a data misalignment nor a floating point
00256     exception and 
the the previous mode 
is kernel, then 
the exception
00257     dispatcher 
is called directly to process 
the exception. Otherwise 
the
00258     exception record, exception frame, and trap frame contents are copied
00259     to 
the user mode stack. The contents of 
the exception frame and trap
00260     are then modified such that when 
control is returned, execution will
00261     commense in user mode in a routine which will call 
the exception
00262     dispatcher.
00263 
00264 Arguments:
00265 
00266     ExceptionRecord - Supplies a pointer to an exception record.
00267 
00268     ExceptionFrame - Supplies a pointer to an exception frame.
00269 
00270     TrapFrame - Supplies a pointer to a trap frame.
00271 
00272     PreviousMode - Supplies 
the previous processor mode.
00273 
00274     FirstChance - Supplies a 
boolean variable that specifies whether 
this
00275         
is the first (TRUE) or second (FALSE) time that this exception has
00276         been processed.
00277 
00278 Return Value:
00279 
00280     None.
00281 
00282 --*/
00283 
00284 {
00285 
00286     CONTEXT ContextFrame;
00287     EXCEPTION_RECORD ExceptionRecord1;
00288     PPLABEL_DESCRIPTOR Plabel;
00289     BOOLEAN UserApcPending;
00290 
00291     
00292     
00293     
00294     
00295     
00296     
00297 
00298 
#if DBG
00299 
    if (KiBreakOnAlignmentFault != 
FALSE) {
00300 
00301         
if (ExceptionRecord->ExceptionCode == STATUS_DATATYPE_MISALIGNMENT) {
00302 
00303             
DbgPrint(
"KI: Alignment fault exr = %p Pc = %p Address = %p\n",
00304                      ExceptionRecord,
00305                      ExceptionRecord->ExceptionAddress,
00306                      ExceptionRecord->ExceptionInformation[2]);
00307 
00308             DbgBreakPoint();
00309         }
00310     }
00311 
#endif
00312 
00313     
if ((ExceptionRecord->ExceptionCode == STATUS_DATATYPE_MISALIGNMENT) &&
00314         (FirstChance != 
FALSE)) {
00315 
00316 
#if DBG
00317 
00318         
00319         
00320         
00321 
00322         
if (PreviousMode == 
KernelMode) {
00323             KiKernelFixupCount += 1;
00324             
if ((KiKernelFixupCount & KiKernelFixupMask) == 0) {
00325                 
DbgPrint(
"KI: Kernel Fixup: Pid=0x%.3lx, Pc=%.16p, Address=%.16p ... Total=%ld\n",
00326                          
PsGetCurrentProcess()->UniqueProcessId,
00327                          ExceptionRecord->ExceptionAddress,
00328                          ExceptionRecord->ExceptionInformation[1],
00329                          KiKernelFixupCount);
00330             }
00331 
00332         } 
else {
00333             KiUserFixupCount += 1;
00334             
if ((KiUserFixupCount & KiUserFixupMask) == 0) {
00335                 
DbgPrint(
"KI: User  Fixup: Pid=0x%.3lx, Pc=%.16p, Address=%.16p ... Total=%ld\n",
00336                          
PsGetCurrentProcess()->UniqueProcessId,
00337                          ExceptionRecord->ExceptionAddress,
00338                          ExceptionRecord->ExceptionInformation[1],
00339                          KiUserFixupCount);
00340             }
00341         }
00342 
00343 
#endif
00344 
00345         
00346         
00347         
00348         
00349         
00350         
00351         
00352         
00353         
00354 
00355         
if ( (
KiEnableAlignmentFaultExceptions == 0) ||
00356 
00357              ((
KeGetCurrentThread()->AutoAlignment != 
FALSE) ||
00358               (
KeGetCurrentThread()->ApcState.Process->AutoAlignment != 
FALSE)) ||
00359 
00360              (((
PsGetCurrentProcess()->DebugPort == 
NULL) || (PreviousMode == 
KernelMode)) &&
00361               (
KiEnableAlignmentFaultExceptions == 2)) ) {
00362 
00363             
if (
KiEmulateReference(ExceptionRecord,
00364                                    ExceptionFrame,
00365                                    TrapFrame) != 
FALSE) 
00366             {
00367                 
KeGetCurrentPrcb()->KeAlignmentFixupCount += 1;
00368                 
goto Handled2;
00369             }
00370         }
00371     }
00372 
00373     
00374     
00375     
00376 
00377     
00378     
00379     
00380     
00381     
00382 
00383     
if ((ExceptionRecord->ExceptionCode == STATUS_FLOAT_MULTIPLE_FAULTS) ||
00384         (ExceptionRecord->ExceptionCode == STATUS_FLOAT_MULTIPLE_TRAPS)) {
00385 
00386         
if (
KiEmulateFloat(ExceptionRecord, ExceptionFrame, TrapFrame)) {
00387 
00388             
00389             
00390             
00391 
00392             
return;
00393         }
00394     }
00395 
00396     
00397     
00398     
00399     
00400 
00401     ContextFrame.ContextFlags = 
CONTEXT_FULL;
00402     
KeContextFromKframes(TrapFrame, ExceptionFrame, &ContextFrame);
00403     
KeGetCurrentPrcb()->KeExceptionDispatchCount += 1;
00404 
00405     
00406     
00407     
00408 
00409     
if (PreviousMode == 
KernelMode) {
00410 
00411         
00412         
00413         
00414         
00415         
00416         
00417         
00418         
00419         
00420         
00421         
00422         
00423         
00424         
00425         
00426         
00427 
00428         
if (FirstChance != 
FALSE) {
00429 
00430             
00431             
00432             
00433             
00434             
00435             
00436             
00437 
00438             
RtlpCaptureRnats(&ContextFrame);
00439             TrapFrame->RsRNAT = ContextFrame.RsRNAT;
00440 
00441             
00442             
00443             
00444             
00445             
00446 
00447             
if ((
KiDebugRoutine != 
NULL) &&
00448                (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
00449                (
KdIsThisAKdTrap(ExceptionRecord,
00450                                 &ContextFrame,
00451                                 KernelMode) != 
FALSE)) {
00452 
00453                 
if (((
KiDebugRoutine) (TrapFrame,
00454                                        ExceptionFrame,
00455                                        ExceptionRecord,
00456                                        &ContextFrame,
00457                                        
KernelMode,
00458                                        
FALSE)) != 
FALSE) {
00459 
00460                     
goto Handled1;
00461                 }
00462             }
00463 
00464             
if (
RtlDispatchException(ExceptionRecord, &ContextFrame) != 
FALSE) {
00465                 
goto Handled1;
00466             }
00467         }
00468 
00469         
00470         
00471         
00472 
00473         
if (
KiDebugRoutine != 
NULL) {
00474             
if (((
KiDebugRoutine) (TrapFrame,
00475                                    ExceptionFrame,
00476                                    ExceptionRecord,
00477                                    &ContextFrame,
00478                                    PreviousMode,
00479                                    
TRUE)) != 
FALSE) {
00480                 
goto Handled1;
00481             }
00482         }
00483 
00484         
KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,
00485                      ExceptionRecord->ExceptionCode,
00486                      (ULONG_PTR)ExceptionRecord->ExceptionAddress,
00487                      ExceptionRecord->ExceptionInformation[0],
00488                      ExceptionRecord->ExceptionInformation[1]);
00489 
00490     } 
else {
00491 
00492         
00493         
00494         
00495         
00496         
00497         
00498         
00499         
00500         
00501         
00502         
00503         
00504         
00505         
00506         
00507         
00508         
00509         
00510         
00511         
00512         
00513         
00514         
00515         
00516         
00517 
00518         
if (FirstChance != 
FALSE) {
00519 
00520             
00521             
00522             
00523             
00524             
00525             
00526             
00527 
00528             
if ((
KiDebugRoutine != 
NULL) &&
00529                 (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
00530                 (
KdIsThisAKdTrap(ExceptionRecord,
00531                                  &ContextFrame,
00532                                  UserMode) != 
FALSE) &&
00533                 ((
PsGetCurrentProcess()->DebugPort == 
NULL) ||
00534                 ((
PsGetCurrentProcess()->DebugPort != 
NULL) &&
00535                 (ExceptionRecord->ExceptionInformation[0] !=
00536                                             DEBUG_STOP_BREAKPOINT)))) {
00537 
00538                 
if (((
KiDebugRoutine) (TrapFrame,
00539                                        ExceptionFrame,
00540                                        ExceptionRecord,
00541                                        &ContextFrame,
00542                                        
UserMode,
00543                                        
FALSE)) != 
FALSE) {
00544 
00545                     
goto Handled1;
00546                 }
00547             }
00548 
00549             
00550             
00551             
00552 
00553             
if (
DbgkForwardException(ExceptionRecord, TRUE, FALSE)) {
00554                 TrapFrame->StFPSR = SANITIZE_FSR(TrapFrame->StFPSR, UserMode);
00555                 
goto Handled2;
00556             }
00557 
00558             
00559             
00560             
00561             
00562             
00563             
00564             
00565             
00566             
00567             
00568             
00569             
00570             
00571             
00572             
00573             
00574             
00575             
00576             
00577             
00578             
00579             
00580             
00581             
00582             
00583             
00584             
00585             
00586             
00587             
00588             
00589             
00590             
00591             
00592 
00593         repeat:
00594             
try {
00595 
00596                 
00597                 
00598                 
00599                 
00600 
00601                 ULONG Length = (STACK_SCRATCH_AREA + 15 +
00602                                 
sizeof(EXCEPTION_REGISTRATION_RECORD) +
00603                                 
sizeof(EXCEPTION_RECORD) + 
sizeof(CONTEXT)) & ~(15);
00604                 ULONGLONG UserStack = (ContextFrame.IntSp & (~15)) - Length;
00605                 ULONGLONG ContextSlot = UserStack + STACK_SCRATCH_AREA;
00606                 ULONGLONG ExceptSlot = ContextSlot + 
sizeof(CONTEXT);
00607                 PULONGLONG PUserStack = (PULONGLONG) UserStack;
00608                 
00609                 
00610                 
00611                 
00612                 
00613 
00614                 
ProbeForWrite((PCHAR)UserStack, Length, 
sizeof(QUAD));
00615                 RtlMoveMemory((PVOID)ContextSlot, &ContextFrame, 
00616                               
sizeof(CONTEXT));
00617                 RtlMoveMemory((PVOID)ExceptSlot, ExceptionRecord, 
00618                               
sizeof(EXCEPTION_RECORD));
00619 
00620                 
00621                 
00622                 
00623                 
00624                 
00625                 
00626                 
00627                 
00628                 
00629 
00630                 TrapFrame->RsPFS = TrapFrame->StIFS;
00631                 TrapFrame->StIFS &= 0xffffffc000000000;
00632                 TrapFrame->StIPSR &= ~((0x3i64 << PSR_RI) | (0x1i64 << PSR_IS));
00633                 TrapFrame->IntSp = UserStack;
00634                 TrapFrame->IntNats = 0;
00635 
00636                 ExceptionFrame->IntS0 = ExceptSlot;
00637                 ExceptionFrame->IntS1 = ContextSlot;
00638                 ExceptionFrame->IntNats = 0;
00639 
00640                 
00641                 
00642                 
00643                 
00644                 
00645                 
00646                 
00647 
00648                 Plabel = (PPLABEL_DESCRIPTOR)
KeUserExceptionDispatcher;
00649                 TrapFrame->StIIP = Plabel->EntryPoint;
00650                 TrapFrame->IntGp = Plabel->GlobalPointer;
00651 
00652                 
return;
00653 
00654             
00655             
00656             
00657             
00658 
00659             } except (
KiCopyInformation(&ExceptionRecord1,
00660                                (GetExceptionInformation())->ExceptionRecord)) {
00661 
00662                 
00663                 
00664                 
00665                 
00666                 
00667                 
00668 
00669                 
if (ExceptionRecord1.ExceptionCode == STATUS_STACK_OVERFLOW) {
00670                     ExceptionRecord1.ExceptionAddress = ExceptionRecord->ExceptionAddress;
00671                     RtlMoveMemory((PVOID)ExceptionRecord,
00672                                   &ExceptionRecord1, 
sizeof(EXCEPTION_RECORD));
00673                     
goto repeat;
00674                 }
00675             }
00676         }
00677 
00678         
00679         
00680         
00681 
00682         UserApcPending = 
KeGetCurrentThread()->ApcState.UserApcPending;
00683         
if (
DbgkForwardException(ExceptionRecord, TRUE, TRUE)) {
00684             TrapFrame->StFPSR = SANITIZE_FSR(TrapFrame->StFPSR, UserMode);
00685             
goto Handled2;
00686 
00687         } 
else if (
DbgkForwardException(ExceptionRecord, FALSE, TRUE)) {
00688             TrapFrame->StFPSR = SANITIZE_FSR(TrapFrame->StFPSR, UserMode);
00689             
goto Handled2;
00690 
00691         } 
else {
00692             ZwTerminateProcess(NtCurrentProcess(), ExceptionRecord->ExceptionCode);
00693             
KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,
00694                          ExceptionRecord->ExceptionCode,
00695                          (ULONG_PTR)ExceptionRecord->ExceptionAddress,
00696                          ExceptionRecord->ExceptionInformation[0],
00697                          ExceptionRecord->ExceptionInformation[1]);
00698         }
00699     }
00700 
00701     
00702     
00703     
00704     
00705 
00706 Handled1:
00707     
KeContextToKframes(TrapFrame, ExceptionFrame, &ContextFrame,
00708                        ContextFrame.ContextFlags, PreviousMode);
00709 
00710     
00711     
00712     
00713     
00714     
00715     
00716 
00717 Handled2:
00718     
return;
00719 }