+BOOLEAN
+NTAPI
+KdpEnterDebuggerException(IN PKTRAP_FRAME TrapFrame,
+ IN PKEXCEPTION_FRAME ExceptionFrame,
+ IN PEXCEPTION_RECORD ExceptionRecord,
+ IN PCONTEXT Context,
+ IN KPROCESSOR_MODE PreviousMode,
+ IN BOOLEAN SecondChance)
+{
+ KD_CONTINUE_TYPE Return = kdHandleException;
+ ULONG ExceptionCommand = ExceptionRecord->ExceptionInformation[0];
+
+ /* Check if this was a breakpoint due to DbgPrint or Load/UnloadSymbols */
+ if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
+ (ExceptionRecord->NumberParameters > 0) &&
+ ((ExceptionCommand == BREAKPOINT_LOAD_SYMBOLS) ||
+ (ExceptionCommand == BREAKPOINT_UNLOAD_SYMBOLS) ||
+ (ExceptionCommand == BREAKPOINT_COMMAND_STRING) ||
+ (ExceptionCommand == BREAKPOINT_PRINT) ||
+ (ExceptionCommand == BREAKPOINT_PROMPT)))
+ {
+ /* Check if this is a debug print */
+ if (ExceptionCommand == BREAKPOINT_PRINT)
+ {
+ /* Print the string */
+ KdpServiceDispatcher(BREAKPOINT_PRINT,
+ (PVOID)ExceptionRecord->ExceptionInformation[1],
+ ExceptionRecord->ExceptionInformation[2]);
+
+ /* Return success */
+ KeSetContextReturnRegister(Context, STATUS_SUCCESS);
+ }
+#ifdef KDBG
+ else if (ExceptionCommand == BREAKPOINT_LOAD_SYMBOLS)
+ {
+ PLDR_DATA_TABLE_ENTRY LdrEntry;
+
+ /* Load symbols. Currently implemented only for KDBG! */
+ if(KdbpSymFindModule(((PKD_SYMBOLS_INFO)ExceptionRecord->ExceptionInformation[2])->BaseOfDll, NULL, -1, &LdrEntry))
+ KdbSymProcessSymbols(LdrEntry);
+ }
+ else if (ExceptionCommand == BREAKPOINT_PROMPT)
+ {
+ ULONG ReturnValue;
+ LPSTR OutString;
+ USHORT OutStringLength;
+
+ /* Get the response string and length */
+ OutString = (LPSTR)Context->Ebx;
+ OutStringLength = (USHORT)Context->Edi;
+
+ /* Call KDBG */
+ ReturnValue = KdpPrompt((LPSTR)ExceptionRecord->
+ ExceptionInformation[1],
+ (USHORT)ExceptionRecord->
+ ExceptionInformation[2],
+ OutString,
+ OutStringLength);
+
+ /* Return the number of characters that we received */
+ Context->Eax = ReturnValue;
+ }
+#endif
+
+ /* This we can handle: simply bump the Program Counter */
+ KeSetContextPc(Context, KeGetContextPc(Context) + KD_BREAKPOINT_SIZE);
+ return TRUE;
+ }
+
+#ifdef KDBG
+ /* Check if this is an assertion failure */
+ if (ExceptionRecord->ExceptionCode == STATUS_ASSERTION_FAILURE)
+ {
+ /* Warn about it */
+ DbgPrint("\n!!! Assertion Failure at Address 0x%p !!!\n\n",
+ (PVOID)Context->Eip);
+
+ /* Bump EIP to the instruction following the int 2C and return */
+ Context->Eip += 2;
+ return TRUE;
+ }
+#endif
+
+ /* Get out of here if the Debugger isn't connected */
+ if (KdDebuggerNotPresent) return FALSE;
+
+#ifdef KDBG
+ /* Call KDBG if available */
+ Return = KdbEnterDebuggerException(ExceptionRecord,
+ PreviousMode,
+ Context,
+ TrapFrame,
+ !SecondChance);
+#else /* not KDBG */
+ if (WrapperInitRoutine)
+ {
+ /* Call GDB */
+ Return = WrapperTable.KdpExceptionRoutine(ExceptionRecord,
+ Context,
+ TrapFrame);
+ }
+#endif /* not KDBG */
+
+ /* Debugger didn't handle it, please handle! */
+ if (Return == kdHandleException) return FALSE;
+
+ /* Debugger handled it */
+ return TRUE;
+}
+
+BOOLEAN
+NTAPI
+KdpCallGdb(IN PKTRAP_FRAME TrapFrame,
+ IN PEXCEPTION_RECORD ExceptionRecord,
+ IN PCONTEXT Context)