00039                    :
00040 
00041     This routine 
is called whenever a exception 
is dispatched and 
the kernel
00042     debugger 
is active.
00043 
00044 Arguments:
00045 
00046     TrapFrame - Supplies a pointer to a trap frame that describes 
the
00047         trap.
00048 
00049     ExceptionFrame - Supplies a pointer to a exception frame that describes
00050         
the trap.
00051 
00052     ExceptionRecord - Supplies a pointer to an exception record that
00053         describes 
the exception.
00054 
00055     ContextRecord - Supplies 
the context at 
the time of 
the exception.
00056 
00057     PreviousMode - Supplies 
the previous processor mode.
00058 
00059     SecondChance - Supplies a 
boolean value that determines whether 
this is
00060         
the second chance (TRUE) that the exception has been raised.
00061 
00062 Return Value:
00063 
00064     A value of TRUE is returned if the exception is handled. Otherwise a
00065     value of FALSE is returned.
00066 
00067 --*/
00068 
00069 {
00070 
00071     BOOLEAN Completion;
00072     BOOLEAN Enable;
00073     BOOLEAN UnloadSymbols = 
FALSE;
00074     STRING Input;
00075     ULONGLONG OldFir;
00076     STRING Output;
00077     PKPRCB Prcb;
00078 
00079     
00080     
00081     
00082 
00083     
00084     
00085     
00086     
00087 
00088     
if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
00089         (ExceptionRecord->ExceptionInformation[0] >= DEBUG_PRINT_BREAKPOINT)){
00090 
00091         
00092         
00093         
00094 
00095         
switch (ExceptionRecord->ExceptionInformation[0]) {
00096 
00097             
00098             
00099             
00100             
00101             
00102             
00103             
00104             
00105 
00106         
case DEBUG_PRINT_BREAKPOINT:
00107 
00108             ContextRecord->Fir += 4;
00109             Output.Buffer = (PCHAR)ContextRecord->IntA0;
00110             Output.Length = (
USHORT)ContextRecord->IntA1;
00111 
00112             
KdLogDbgPrint(&Output);
00113 
00114             
if (
KdDebuggerNotPresent == 
FALSE) {
00115 
00116                 Enable = 
KdEnterDebugger(TrapFrame, ExceptionFrame);
00117                 
if (
KdpPrintString(&Output)) {
00118                     ContextRecord->IntV0 = (ULONG)STATUS_BREAKPOINT;
00119                 } 
else {
00120                     ContextRecord->IntV0 = (ULONG)STATUS_SUCCESS;
00121                 }
00122                 
KdExitDebugger(Enable);
00123 
00124             } 
else {
00125                 ContextRecord->IntV0 = (ULONG)STATUS_DEVICE_NOT_CONNECTED;
00126             }
00127 
00128             
return TRUE;
00129 
00130 
00131             
00132             
00133             
00134             
00135             
00136             
00137 
00138         
case BREAKIN_BREAKPOINT:
00139 
00140             ContextRecord->Fir += 4;
00141             
break;
00142 
00143             
00144             
00145             
00146             
00147             
00148             
00149             
00150             
00151 
00152         
case DEBUG_PROMPT_BREAKPOINT:
00153 
00154             ContextRecord->Fir += 4;
00155             Output.Buffer = (PCHAR)ContextRecord->IntA0;
00156             Output.Length = (
USHORT)ContextRecord->IntA1;
00157             Input.Buffer = (PCHAR)ContextRecord->IntA2;
00158             Input.MaximumLength = (
USHORT)ContextRecord->IntA3;
00159 
00160             
KdLogDbgPrint(&Output);
00161 
00162             Enable = 
KdEnterDebugger(TrapFrame, ExceptionFrame);
00163 
00164             
KdpPromptString(&Output, &Input);
00165 
00166             ContextRecord->IntV0 = Input.Length;
00167 
00168             
KdExitDebugger(Enable);
00169             
return TRUE;
00170 
00171             
00172             
00173             
00174             
00175             
00176             
00177             
00178             
00179             
00180 
00181         
case DEBUG_UNLOAD_SYMBOLS_BREAKPOINT:
00182 
00183             UnloadSymbols = 
TRUE;
00184 
00185             
00186             
00187             
00188 
00189         
case DEBUG_LOAD_SYMBOLS_BREAKPOINT:
00190 
00191             Enable = 
KdEnterDebugger(TrapFrame, ExceptionFrame);
00192             Prcb = 
KeGetCurrentPrcb();
00193             OldFir = ContextRecord->Fir;
00194             RtlCopyMemory(&Prcb->ProcessorState.ContextFrame,
00195                           ContextRecord,
00196                           
sizeof(CONTEXT));
00197 
00198             
if (
KdDebuggerNotPresent == 
FALSE) {
00199 
00200                 
KdpReportLoadSymbolsStateChange((PSTRING)ContextRecord->IntA0,
00201                                                 (
PKD_SYMBOLS_INFO) ContextRecord->IntA1,
00202                                                 UnloadSymbols,
00203                                                 &Prcb->ProcessorState.ContextFrame);
00204 
00205             }
00206 
00207             RtlCopyMemory(ContextRecord,
00208                           &Prcb->ProcessorState.ContextFrame,
00209                           
sizeof(CONTEXT));
00210 
00211             
KdExitDebugger(Enable);
00212 
00213             
00214             
00215             
00216             
00217 
00218             
if (ContextRecord->Fir == OldFir) {
00219                 ContextRecord->Fir += 4;
00220             }
00221 
00222             
return TRUE;
00223 
00224             
00225             
00226             
00227 
00228         
default:
00229 
00230             
break;
00231         }
00232     }
00233 
00234     
00235     
00236     
00237 
00238     Enable = 
KdEnterDebugger(TrapFrame, ExceptionFrame);
00239     Prcb = 
KeGetCurrentPrcb();
00240 
00241     RtlCopyMemory(&Prcb->ProcessorState.ContextFrame,
00242                     ContextRecord,
00243                     sizeof (CONTEXT));
00244 
00245     Completion = 
KdpReportExceptionStateChange(ExceptionRecord,
00246                                                &Prcb->ProcessorState.ContextFrame,
00247                                                SecondChance);
00248 
00249     RtlCopyMemory(ContextRecord,
00250                   &Prcb->ProcessorState.ContextFrame,
00251                   
sizeof(CONTEXT));
00252 
00253     
KdExitDebugger(Enable);
00254 
00255     
KdpControlCPressed = 
FALSE;
00256 
00257     
00258     
00259     
00260     
00261     
00262 
00263     
if( SecondChance ){
00264         
return Completion;
00265     } 
else {
00266         
return TRUE;
00267     }
00268 }