- Add STATUS_SUCCESS to asm.h and make use of it.
authorStefan Ginsberg <stefanginsberg@gmail.com>
Sat, 17 Oct 2009 14:31:38 +0000 (14:31 +0000)
committerStefan Ginsberg <stefanginsberg@gmail.com>
Sat, 17 Oct 2009 14:31:38 +0000 (14:31 +0000)
- Implement Bus and I/O space read and write support.
- Implement support for AUTOENABLE, DISABLE and NOUMEX subparameters to /debug. Add the missing string scan and set and respect the related globals properly. Add support for disabling the debugger and suspending breakpoints.
- Add and implement KdIsThisAKdTrap to determine if the kernel debugger can't ignore a particular trap -- returns true for software breakpoints and debug service calls (DbgPrint for example). Called from KiDispatchException to determine whether to override NOUMEX (otherwise, DbgPrint and friends will kill user mode applications). Stub this for KDBG as it implements its own scheme for ignoring user mode.
- KiDispatchException: Clean up some goto and support NOUMEX. Also don't check if KiDebugRoutine is NULL -- it will never be.
- KdEnableDebuggerWithLock should initialize the debugger even if KdDisableCount is 0 (but only if called internally) as this means that the debugger was never initialized in the first place. Required for AUTOENABLE and for enabling the debugger during a bugcheck. Add the globals to kdbg too but don't set or respect them there as kdbg does not support it.
- Enable KdEnableDebugger and implement KdDisableDebugger for KD as KdDisableDebuggerWithLock is now implemented.
- Only build kdmemsup.c if KDBG is defined.

svn path=/trunk/; revision=43530

15 files changed:
reactos/include/ndk/i386/asm.h
reactos/ntoskrnl/include/internal/kd.h
reactos/ntoskrnl/include/internal/kd64.h
reactos/ntoskrnl/kd/kdmain.c
reactos/ntoskrnl/kd64/amd64/kdsup.c
reactos/ntoskrnl/kd64/arm/kdsup.c
reactos/ntoskrnl/kd64/i386/kdsup.c
reactos/ntoskrnl/kd64/kdapi.c
reactos/ntoskrnl/kd64/kdbreak.c
reactos/ntoskrnl/kd64/kddata.c
reactos/ntoskrnl/kd64/kdinit.c
reactos/ntoskrnl/kd64/kdtrap.c
reactos/ntoskrnl/ke/i386/exp.c
reactos/ntoskrnl/ke/i386/trap.s
reactos/ntoskrnl/ntoskrnl-generic.rbuild

index de4182c..5970108 100644 (file)
@@ -527,6 +527,7 @@ Author:
 // NTSTATUS, Bugcheck Codes and Debug Codes
 //
 #ifdef __ASM__
 // NTSTATUS, Bugcheck Codes and Debug Codes
 //
 #ifdef __ASM__
+#define STATUS_SUCCESS                          0x00000000
 #define STATUS_ACCESS_VIOLATION                 0xC0000005
 #define STATUS_IN_PAGE_ERROR                    0xC0000006
 #define STATUS_GUARD_PAGE_VIOLATION             0x80000001
 #define STATUS_ACCESS_VIOLATION                 0xC0000005
 #define STATUS_IN_PAGE_ERROR                    0xC0000006
 #define STATUS_GUARD_PAGE_VIOLATION             0x80000001
index c9bfec9..d42ffb3 100644 (file)
@@ -22,6 +22,7 @@ extern BOOLEAN _KdDebuggerEnabled;
 extern BOOLEAN _KdDebuggerNotPresent;
 extern BOOLEAN KdBreakAfterSymbolLoad;
 extern BOOLEAN KdPitchDebugger;
 extern BOOLEAN _KdDebuggerNotPresent;
 extern BOOLEAN KdBreakAfterSymbolLoad;
 extern BOOLEAN KdPitchDebugger;
+extern BOOLEAN KdIgnoreUmExceptions;
 
 BOOLEAN
 NTAPI
 
 BOOLEAN
 NTAPI
@@ -133,6 +134,14 @@ KD_CONTINUE_TYPE
     PKTRAP_FRAME TrapFrame
 );
 
     PKTRAP_FRAME TrapFrame
 );
 
+BOOLEAN
+NTAPI
+KdIsThisAKdTrap(
+    IN PEXCEPTION_RECORD ExceptionRecord,
+    IN PCONTEXT Context,
+    IN KPROCESSOR_MODE PreviousMode
+);
+
 /* INIT ROUTINES *************************************************************/
 
 BOOLEAN
 /* INIT ROUTINES *************************************************************/
 
 BOOLEAN
index 213c832..5961bd4 100644 (file)
@@ -71,6 +71,17 @@ KdUpdateDataBlock(
     VOID
 );
 
     VOID
 );
 
+//
+// Determines if the kernel debugger must handle a particular trap
+//
+BOOLEAN
+NTAPI
+KdIsThisAKdTrap(
+    IN PEXCEPTION_RECORD ExceptionRecord,
+    IN PCONTEXT Context,
+    IN KPROCESSOR_MODE PreviousMode
+);
+
 //
 // Multi-Processor Switch Support
 //
 //
 // Multi-Processor Switch Support
 //
@@ -147,7 +158,7 @@ KdpPollBreakInWithPortLock(
 );
 
 //
 );
 
 //
-// Debugger Enable, Enter and Exit
+// Debugger Enter, Exit, Enable and Disable
 //
 BOOLEAN
 NTAPI
 //
 BOOLEAN
 NTAPI
@@ -168,6 +179,12 @@ KdEnableDebuggerWithLock(
     IN BOOLEAN NeedLock
 );
 
     IN BOOLEAN NeedLock
 );
 
+NTSTATUS
+NTAPI
+KdDisableDebuggerWithLock(
+    IN BOOLEAN NeedLock
+);
+
 //
 // Debug Event Handlers
 //
 //
 // Debug Event Handlers
 //
@@ -242,10 +259,10 @@ KdpReportExceptionStateChange(
 //
 // Breakpoint Support
 //
 //
 // Breakpoint Support
 //
-VOID
+ULONG
 NTAPI
 NTAPI
-KdpRestoreAllBreakpoints(
-    VOID
+KdpAddBreakpoint(
+    IN PVOID Address
 );
 
 BOOLEAN
 );
 
 BOOLEAN
@@ -261,10 +278,22 @@ KdpDeleteBreakpointRange(
     IN PVOID Limit
 );
 
     IN PVOID Limit
 );
 
-ULONG
+VOID
 NTAPI
 NTAPI
-KdpAddBreakpoint(
-    IN PVOID Address
+KdpSuspendBreakPoint(
+    IN ULONG BpEntry
+);
+
+VOID
+NTAPI
+KdpRestoreAllBreakpoints(
+    VOID
+);
+
+VOID
+NTAPI
+KdpSuspendAllBreakPoints(
+    VOID
 );
 
 //
 );
 
 //
@@ -323,8 +352,8 @@ KdpSysReadBusData(
     IN ULONG BusDataType,
     IN ULONG BusNumber,
     IN ULONG SlotNumber,
     IN ULONG BusDataType,
     IN ULONG BusNumber,
     IN ULONG SlotNumber,
-    IN PVOID Buffer,
     IN ULONG Offset,
     IN ULONG Offset,
+    IN PVOID Buffer,
     IN ULONG Length,
     OUT PULONG ActualLength
 );
     IN ULONG Length,
     OUT PULONG ActualLength
 );
@@ -335,8 +364,8 @@ KdpSysWriteBusData(
     IN ULONG BusDataType,
     IN ULONG BusNumber,
     IN ULONG SlotNumber,
     IN ULONG BusDataType,
     IN ULONG BusNumber,
     IN ULONG SlotNumber,
-    IN PVOID Buffer,
     IN ULONG Offset,
     IN ULONG Offset,
+    IN PVOID Buffer,
     IN ULONG Length,
     OUT PULONG ActualLength
 );
     IN ULONG Length,
     OUT PULONG ActualLength
 );
@@ -428,6 +457,8 @@ extern BOOLEAN KdPitchDebugger;
 extern BOOLEAN _KdDebuggerNotPresent;
 extern BOOLEAN _KdDebuggerEnabled;
 extern BOOLEAN KdAutoEnableOnEvent;
 extern BOOLEAN _KdDebuggerNotPresent;
 extern BOOLEAN _KdDebuggerEnabled;
 extern BOOLEAN KdAutoEnableOnEvent;
+extern BOOLEAN KdBlockEnable;
+extern BOOLEAN KdIgnoreUmExceptions;
 extern BOOLEAN KdPreviouslyEnabled;
 extern BOOLEAN KdpDebuggerStructuresInitialized;
 extern BOOLEAN KdEnteredDebugger;
 extern BOOLEAN KdPreviouslyEnabled;
 extern BOOLEAN KdpDebuggerStructuresInitialized;
 extern BOOLEAN KdEnteredDebugger;
index c7f0186..8e6324a 100644 (file)
@@ -18,8 +18,9 @@ BOOLEAN KdEnteredDebugger = FALSE;
 BOOLEAN KdDebuggerNotPresent = TRUE;
 BOOLEAN KiEnableTimerWatchdog = FALSE;
 BOOLEAN KdBreakAfterSymbolLoad = FALSE;
 BOOLEAN KdDebuggerNotPresent = TRUE;
 BOOLEAN KiEnableTimerWatchdog = FALSE;
 BOOLEAN KdBreakAfterSymbolLoad = FALSE;
-BOOLEAN KdpBreakPending;
+BOOLEAN KdpBreakPending = FALSE;
 BOOLEAN KdPitchDebugger = TRUE;
 BOOLEAN KdPitchDebugger = TRUE;
+BOOLEAN KdIgnoreUmExceptions = FALSE;
 VOID NTAPI PspDumpThreads(BOOLEAN SystemThreads);
 
 typedef struct
 VOID NTAPI PspDumpThreads(BOOLEAN SystemThreads);
 
 typedef struct
@@ -200,6 +201,16 @@ KdpCallGdb(IN PKTRAP_FRAME TrapFrame,
     return TRUE;
 }
 
     return TRUE;
 }
 
+BOOLEAN
+NTAPI
+KdIsThisAKdTrap(IN PEXCEPTION_RECORD ExceptionRecord,
+                IN PCONTEXT Context,
+                IN KPROCESSOR_MODE PreviousMode)
+{
+    /* KDBG has its own mechanism for ignoring user mode exceptions */
+    return FALSE;
+}
+
 /* PUBLIC FUNCTIONS *********************************************************/
 
 /*
 /* PUBLIC FUNCTIONS *********************************************************/
 
 /*
index 06c08c5..f31a4e8 100644 (file)
@@ -68,8 +68,8 @@ NTAPI
 KdpSysReadBusData(IN ULONG BusDataType,
                   IN ULONG BusNumber,
                   IN ULONG SlotNumber,
 KdpSysReadBusData(IN ULONG BusDataType,
                   IN ULONG BusNumber,
                   IN ULONG SlotNumber,
-                  IN PVOID Buffer,
                   IN ULONG Offset,
                   IN ULONG Offset,
+                  IN PVOID Buffer,
                   IN ULONG Length,
                   OUT PULONG ActualLength)
 {
                   IN ULONG Length,
                   OUT PULONG ActualLength)
 {
@@ -83,8 +83,8 @@ NTAPI
 KdpSysWriteBusData(IN ULONG BusDataType,
                    IN ULONG BusNumber,
                    IN ULONG SlotNumber,
 KdpSysWriteBusData(IN ULONG BusDataType,
                    IN ULONG BusNumber,
                    IN ULONG SlotNumber,
-                   IN PVOID Buffer,
                    IN ULONG Offset,
                    IN ULONG Offset,
+                   IN PVOID Buffer,
                    IN ULONG Length,
                    OUT PULONG ActualLength)
 {
                    IN ULONG Length,
                    OUT PULONG ActualLength)
 {
index 3c4dc94..9ba9045 100644 (file)
@@ -68,8 +68,8 @@ NTAPI
 KdpSysReadBusData(IN ULONG BusDataType,
                   IN ULONG BusNumber,
                   IN ULONG SlotNumber,
 KdpSysReadBusData(IN ULONG BusDataType,
                   IN ULONG BusNumber,
                   IN ULONG SlotNumber,
-                  IN PVOID Buffer,
                   IN ULONG Offset,
                   IN ULONG Offset,
+                  IN PVOID Buffer,
                   IN ULONG Length,
                   OUT PULONG ActualLength)
 {
                   IN ULONG Length,
                   OUT PULONG ActualLength)
 {
@@ -83,8 +83,8 @@ NTAPI
 KdpSysWriteBusData(IN ULONG BusDataType,
                    IN ULONG BusNumber,
                    IN ULONG SlotNumber,
 KdpSysWriteBusData(IN ULONG BusDataType,
                    IN ULONG BusNumber,
                    IN ULONG SlotNumber,
-                   IN PVOID Buffer,
                    IN ULONG Offset,
                    IN ULONG Offset,
+                   IN PVOID Buffer,
                    IN ULONG Length,
                    OUT PULONG ActualLength)
 {
                    IN ULONG Length,
                    OUT PULONG ActualLength)
 {
index 5aa9854..5777388 100644 (file)
@@ -12,9 +12,6 @@
 #define NDEBUG
 #include <debug.h>
 
 #define NDEBUG
 #include <debug.h>
 
-#undef UNIMPLEMENTED
-#define UNIMPLEMENTED KdpDprintf("%s is unimplemented\n", __FUNCTION__)
-
 /* FUNCTIONS *****************************************************************/
 
 VOID
 /* FUNCTIONS *****************************************************************/
 
 VOID
@@ -148,14 +145,21 @@ NTAPI
 KdpSysReadBusData(IN ULONG BusDataType,
                   IN ULONG BusNumber,
                   IN ULONG SlotNumber,
 KdpSysReadBusData(IN ULONG BusDataType,
                   IN ULONG BusNumber,
                   IN ULONG SlotNumber,
-                  IN PVOID Buffer,
                   IN ULONG Offset,
                   IN ULONG Offset,
+                  IN PVOID Buffer,
                   IN ULONG Length,
                   OUT PULONG ActualLength)
 {
                   IN ULONG Length,
                   OUT PULONG ActualLength)
 {
-    UNIMPLEMENTED;
-    while (TRUE);
-    return STATUS_UNSUCCESSFUL;
+    /* Just forward to HAL */
+    *ActualLength = HalGetBusDataByOffset(BusDataType,
+                                          BusNumber,
+                                          SlotNumber,
+                                          Buffer,
+                                          Offset,
+                                          Length);
+
+    /* Return status */
+    return (*ActualLength != 0) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
 }
 
 NTSTATUS
 }
 
 NTSTATUS
@@ -163,14 +167,21 @@ NTAPI
 KdpSysWriteBusData(IN ULONG BusDataType,
                    IN ULONG BusNumber,
                    IN ULONG SlotNumber,
 KdpSysWriteBusData(IN ULONG BusDataType,
                    IN ULONG BusNumber,
                    IN ULONG SlotNumber,
-                   IN PVOID Buffer,
                    IN ULONG Offset,
                    IN ULONG Offset,
+                   IN PVOID Buffer,
                    IN ULONG Length,
                    OUT PULONG ActualLength)
 {
                    IN ULONG Length,
                    OUT PULONG ActualLength)
 {
-    UNIMPLEMENTED;
-    while (TRUE);
-    return STATUS_UNSUCCESSFUL;
+    /* Just forward to HAL */
+    *ActualLength = HalSetBusDataByOffset(BusDataType,
+                                          BusNumber,
+                                          SlotNumber,
+                                          Buffer,
+                                          Offset,
+                                          Length);
+
+    /* Return status */
+    return (*ActualLength != 0) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
 }
 
 NTSTATUS
 }
 
 NTSTATUS
@@ -185,7 +196,7 @@ KdpSysReadControlSpace(IN ULONG Processor,
     ULONG RealLength;
 
     /* Make sure that this is a valid request */
     ULONG RealLength;
 
     /* Make sure that this is a valid request */
-    if (((ULONG)BaseAddress < sizeof(KPROCESSOR_STATE)) &&
+    if ((BaseAddress < sizeof(KPROCESSOR_STATE)) &&
         (Processor < KeNumberProcessors))
     {
         /* Get the actual length */
         (Processor < KeNumberProcessors))
     {
         /* Get the actual length */
@@ -223,7 +234,7 @@ KdpSysWriteControlSpace(IN ULONG Processor,
     PVOID ControlStart;
 
     /* Make sure that this is a valid request */
     PVOID ControlStart;
 
     /* Make sure that this is a valid request */
-    if ((((ULONG)BaseAddress + Length) <= sizeof(KPROCESSOR_STATE)) &&
+    if (((BaseAddress + Length) <= sizeof(KPROCESSOR_STATE)) &&
         (Processor < KeNumberProcessors))
     {
         /* Set the proper address */
         (Processor < KeNumberProcessors))
     {
         /* Set the proper address */
@@ -256,9 +267,75 @@ KdpSysReadIoSpace(IN ULONG InterfaceType,
                   IN ULONG DataSize,
                   OUT PULONG ActualDataSize)
 {
                   IN ULONG DataSize,
                   OUT PULONG ActualDataSize)
 {
-    UNIMPLEMENTED;
-    while (TRUE);
-    return STATUS_UNSUCCESSFUL;
+    NTSTATUS Status;
+
+    /* Verify parameters */
+    if ((InterfaceType != Isa) ||
+        (BusNumber != 0) ||
+        (AddressSpace != 1))
+    {
+        /* Fail, we don't support this */
+        *ActualDataSize = 0;
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    /* Check the size */
+    switch (DataSize)
+    {
+        case sizeof(UCHAR):
+
+            /* Read 1 byte */
+            *(PUCHAR)DataValue =
+                READ_PORT_UCHAR((PUCHAR)(ULONG_PTR)IoAddress);
+            *ActualDataSize = sizeof(UCHAR);
+            Status = STATUS_SUCCESS;
+            break;
+
+        case sizeof(USHORT):
+
+            /* Make sure the address is aligned */
+            if ((IoAddress & (sizeof(USHORT) - 1)) != 0)
+            {
+                /* It isn't, bail out */
+                *ActualDataSize = 0;
+                Status = STATUS_DATATYPE_MISALIGNMENT;
+                break;
+            }
+
+            /* Read 2 bytes */
+            *(PUSHORT)DataValue =
+                READ_PORT_USHORT((PUSHORT)(ULONG_PTR)IoAddress);
+            *ActualDataSize = sizeof(USHORT);
+            Status = STATUS_SUCCESS;
+            break;
+
+        case sizeof(ULONG):
+
+            /* Make sure the address is aligned */
+            if ((IoAddress & (sizeof(ULONG) - 1)) != 0)
+            {
+                /* It isn't, bail out */
+                *ActualDataSize = 0;
+                Status = STATUS_DATATYPE_MISALIGNMENT;
+                break;
+            }
+
+            /* Read 4 bytes */
+            *(PULONG)DataValue =
+                READ_PORT_ULONG((PULONG)(ULONG_PTR)IoAddress);
+            *ActualDataSize = sizeof(ULONG);
+            Status = STATUS_SUCCESS;
+            break;
+
+        default:
+
+            /* Invalid size, fail */
+            *ActualDataSize = 0;
+            Status = STATUS_INVALID_PARAMETER;
+    }
+
+    /* Return status */
+    return Status;
 }
 
 NTSTATUS
 }
 
 NTSTATUS
@@ -271,16 +348,81 @@ KdpSysWriteIoSpace(IN ULONG InterfaceType,
                    IN ULONG DataSize,
                    OUT PULONG ActualDataSize)
 {
                    IN ULONG DataSize,
                    OUT PULONG ActualDataSize)
 {
-    UNIMPLEMENTED;
-    while (TRUE);
-    return STATUS_UNSUCCESSFUL;
+    NTSTATUS Status;
+
+    /* Verify parameters */
+    if ((InterfaceType != Isa) ||
+        (BusNumber != 0) ||
+        (AddressSpace != 1))
+    {
+        /* Fail, we don't support this */
+        *ActualDataSize = 0;
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    /* Check the size */
+    switch (DataSize)
+    {
+        case sizeof(UCHAR):
+
+            /* Write 1 byte */
+            WRITE_PORT_UCHAR((PUCHAR)(ULONG_PTR)IoAddress,
+                             *(PUCHAR)DataValue);
+            *ActualDataSize = sizeof(UCHAR);
+            Status = STATUS_SUCCESS;
+            break;
+
+        case sizeof(USHORT):
+
+            /* Make sure the address is aligned */
+            if ((IoAddress & (sizeof(USHORT) - 1)) != 0)
+            {
+                /* It isn't, bail out */
+                *ActualDataSize = 0;
+                Status = STATUS_DATATYPE_MISALIGNMENT;
+                break;
+            }
+
+            /* Write 2 bytes */
+            WRITE_PORT_USHORT((PUSHORT)(ULONG_PTR)IoAddress,
+                             *(PUSHORT)DataValue);
+            *ActualDataSize = sizeof(USHORT);
+            Status = STATUS_SUCCESS;
+            break;
+
+        case sizeof(ULONG):
+
+            /* Make sure the address is aligned */
+            if ((IoAddress & (sizeof(ULONG) - 1)) != 0)
+            {
+                /* It isn't, bail out */
+                *ActualDataSize = 0;
+                Status = STATUS_DATATYPE_MISALIGNMENT;
+                break;
+            }
+
+            /* Write 4 bytes */
+            WRITE_PORT_ULONG((PULONG)(ULONG_PTR)IoAddress,
+                             *(PULONG)DataValue);
+            *ActualDataSize = sizeof(ULONG);
+            Status = STATUS_SUCCESS;
+            break;
+
+        default:
+
+            /* Invalid size, fail */
+            *ActualDataSize = 0;
+            Status = STATUS_INVALID_PARAMETER;
+    }
+
+    /* Return status */
+    return Status;
 }
 
 NTSTATUS
 NTAPI
 KdpSysCheckLowMemory(IN ULONG Flags)
 {
 }
 
 NTSTATUS
 NTAPI
 KdpSysCheckLowMemory(IN ULONG Flags)
 {
-    UNIMPLEMENTED;
-    while (TRUE);
+    /* Stubbed as we don't support PAE */
     return STATUS_UNSUCCESSFUL;
 }
     return STATUS_UNSUCCESSFUL;
 }
index c899f2b..a68e43b 100644 (file)
@@ -602,7 +602,7 @@ KdpGetContext(IN PDBGKD_MANIPULATE_STATE64 State,
         else
         {
             /* SMP not yet handled */
         else
         {
             /* SMP not yet handled */
-            KdpDprintf("SMP UNHANDLED\n");
+            KdpDprintf("KdpGetContext: SMP UNHANDLED\n");
             ControlStart = NULL;
             while (TRUE);
         }
             ControlStart = NULL;
             while (TRUE);
         }
@@ -653,7 +653,7 @@ KdpSetContext(IN PDBGKD_MANIPULATE_STATE64 State,
         else
         {
             /* SMP not yet handled */
         else
         {
             /* SMP not yet handled */
-            KdpDprintf("SMP UNHANDLED\n");
+            KdpDprintf("KdpSetContext: SMP UNHANDLED\n");
             ControlStart = NULL;
             while (TRUE);
         }
             ControlStart = NULL;
             while (TRUE);
         }
@@ -770,8 +770,8 @@ KdpGetBusData(IN PDBGKD_MANIPULATE_STATE64 State,
     State->ReturnStatus = KdpSysReadBusData(GetBusData->BusDataType,
                                             GetBusData->BusNumber,
                                             GetBusData->SlotNumber,
     State->ReturnStatus = KdpSysReadBusData(GetBusData->BusDataType,
                                             GetBusData->BusNumber,
                                             GetBusData->SlotNumber,
-                                            Data->Buffer,
                                             GetBusData->Offset,
                                             GetBusData->Offset,
+                                            Data->Buffer,
                                             Length,
                                             &Length);
 
                                             Length,
                                             &Length);
 
@@ -803,8 +803,8 @@ KdpSetBusData(IN PDBGKD_MANIPULATE_STATE64 State,
     State->ReturnStatus = KdpSysWriteBusData(SetBusData->BusDataType,
                                              SetBusData->BusNumber,
                                              SetBusData->SlotNumber,
     State->ReturnStatus = KdpSysWriteBusData(SetBusData->BusDataType,
                                              SetBusData->BusNumber,
                                              SetBusData->SlotNumber,
-                                             Data->Buffer,
                                              SetBusData->Offset,
                                              SetBusData->Offset,
+                                             Data->Buffer,
                                              SetBusData->Length,
                                              &Length);
 
                                              SetBusData->Length,
                                              &Length);
 
@@ -1476,6 +1476,22 @@ KdpQueryPerformanceCounter(IN PKTRAP_FRAME TrapFrame)
     return KeQueryPerformanceCounter(NULL);
 }
 
     return KeQueryPerformanceCounter(NULL);
 }
 
+NTSTATUS
+NTAPI
+KdpAllowDisable(VOID)
+{
+    /* Check if we are on MP */
+    if (KeNumberProcessors > 1)
+    {
+        /* TODO */
+        KdpDprintf("KdpAllowDisable: SMP UNHANDLED\n");
+        while (TRUE);
+    }
+
+    /* Allow disable */
+    return STATUS_SUCCESS;
+}
+
 BOOLEAN
 NTAPI
 KdEnterDebugger(IN PKTRAP_FRAME TrapFrame,
 BOOLEAN
 NTAPI
 KdEnterDebugger(IN PKTRAP_FRAME TrapFrame,
@@ -1575,6 +1591,13 @@ KdEnableDebuggerWithLock(IN BOOLEAN NeedLock)
     OldIrql = PASSIVE_LEVEL;
 #endif
 
     OldIrql = PASSIVE_LEVEL;
 #endif
 
+    /* Check if enabling the debugger is blocked */
+    if (KdBlockEnable)
+    {
+        /* It is, fail the enable */
+        return STATUS_ACCESS_DENIED;
+    }
+
     /* Check if we need to acquire the lock */
     if (NeedLock)
     {
     /* Check if we need to acquire the lock */
     if (NeedLock)
     {
@@ -1592,10 +1615,21 @@ KdEnableDebuggerWithLock(IN BOOLEAN NeedLock)
             /* Do the unlock */
             KeLowerIrql(OldIrql);
             KdpPortUnlock();
             /* Do the unlock */
             KeLowerIrql(OldIrql);
             KdpPortUnlock();
-        }
 
 
-        /* Fail: We're already enabled */
-        return STATUS_INVALID_PARAMETER;
+            /* Fail: We're already enabled */
+            return STATUS_INVALID_PARAMETER;
+        }
+        else
+        {
+            /*
+             * This can only happen if we are called from a bugcheck
+             * and were never initialized, so initialize the debugger now.
+             */
+            KdInitSystem(0, NULL);
+
+            /* Return success since we initialized */
+            return STATUS_SUCCESS;
+        }
     }
 
     /* Decrease the disable count */
     }
 
     /* Decrease the disable count */
@@ -1622,6 +1656,98 @@ KdEnableDebuggerWithLock(IN BOOLEAN NeedLock)
     return STATUS_SUCCESS;
 }
 
     return STATUS_SUCCESS;
 }
 
+NTSTATUS
+NTAPI
+KdDisableDebuggerWithLock(IN BOOLEAN NeedLock)
+{
+    KIRQL OldIrql;
+    NTSTATUS Status;
+
+#if defined(__GNUC__)
+    /* Make gcc happy */
+    OldIrql = PASSIVE_LEVEL;
+#endif
+
+    /*
+     * If enabling the debugger is blocked
+     * then there is nothing to disable (duh)
+     */
+    if (KdBlockEnable)
+    {
+        /* Fail */
+        return STATUS_ACCESS_DENIED;
+    }
+
+    /* Check if we need to acquire the lock */
+    if (NeedLock)
+    {
+        /* Lock the port */
+        KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
+        KdpPortLock();
+    }
+
+    /* Check if we're not disabled */
+    if (!KdDisableCount)
+    {
+        /* Check if the debugger was never actually initialized */
+        if (!(KdDebuggerEnabled) && !(KdPitchDebugger))
+        {
+            /* It wasn't, so don't re-enable it later */
+            KdPreviouslyEnabled = FALSE;
+        }
+        else
+        {
+            /* It was, so we will re-enable it later */
+            KdPreviouslyEnabled = TRUE;
+        }
+
+        /* Check if we were called from the exported API and are enabled */
+        if ((NeedLock) && (KdPreviouslyEnabled))
+        {
+            /* Check if it is safe to disable the debugger */
+            Status = KdpAllowDisable();
+            if (!NT_SUCCESS(Status))
+            {
+                /* Release the lock and fail */
+                KeLowerIrql(OldIrql);
+                KdpPortUnlock();
+                return Status;
+            }
+        }
+
+        /* Only disable the debugger if it is enabled */
+        if (KdDebuggerEnabled)
+        {
+            /*
+             * Disable the debugger; suspend breakpoints
+             * and reset the debug stub
+             */
+            KdpSuspendAllBreakPoints();
+            KiDebugRoutine = KdpStub;
+
+            /* We are disabled now */
+            KdDebuggerEnabled = FALSE;
+#undef KdDebuggerEnabled
+            SharedUserData->KdDebuggerEnabled = FALSE;
+#define KdDebuggerEnabled _KdDebuggerEnabled
+        }
+     }
+
+    /* Increment the disable count */
+    KdDisableCount++;
+
+    /* Check if we had locked the port before */
+    if (NeedLock)
+    {
+        /* Yes, now unlock it */
+        KeLowerIrql(OldIrql);
+        KdpPortUnlock();
+    }
+
+    /* We're done */
+    return STATUS_SUCCESS;
+}
+
 /* PUBLIC FUNCTIONS **********************************************************/
 
 /*
 /* PUBLIC FUNCTIONS **********************************************************/
 
 /*
@@ -1632,11 +1758,20 @@ NTAPI
 KdEnableDebugger(VOID)
 {
     /* Use the internal routine */
 KdEnableDebugger(VOID)
 {
     /* Use the internal routine */
-    KdpDprintf("KdEnableDebugger called\n");
-    while (TRUE);
     return KdEnableDebuggerWithLock(TRUE);
 }
 
     return KdEnableDebuggerWithLock(TRUE);
 }
 
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+KdDisableDebugger(VOID)
+{
+    /* Use the internal routine */
+    return KdDisableDebuggerWithLock(TRUE);
+}
+
 /*
  * @unimplemented
  */
 /*
  * @unimplemented
  */
@@ -1681,17 +1816,6 @@ KdPowerTransition(IN DEVICE_POWER_STATE NewState)
     return STATUS_SUCCESS;
 }
 
     return STATUS_SUCCESS;
 }
 
-/*
- * @unimplemented
- */
-NTSTATUS
-NTAPI
-KdDisableDebugger(VOID)
-{
-    /* HACK */
-    return STATUS_SUCCESS;
-}
-
 /*
  * @unimplemented
  */
 /*
  * @unimplemented
  */
@@ -1721,4 +1845,3 @@ NtSetDebugFilterState(ULONG ComponentId,
     /* HACK */
     return STATUS_SUCCESS;
 }
     /* HACK */
     return STATUS_SUCCESS;
 }
-
index 8cf6253..2583623 100644 (file)
@@ -183,7 +183,7 @@ KdpRestoreAllBreakpoints(VOID)
     BreakpointsSuspended = FALSE;
 
     /* Loop the breakpoints */
     BreakpointsSuspended = FALSE;
 
     /* Loop the breakpoints */
-    for (BpIndex = 0; BpIndex < KD_BREAKPOINT_MAX; BpIndex++ )
+    for (BpIndex = 0; BpIndex < KD_BREAKPOINT_MAX; BpIndex++)
     {
         /* Check if they are valid, suspended breakpoints */
         if ((KdpBreakpointTable[BpIndex].Flags & KdpBreakpointActive) &&
     {
         /* Check if they are valid, suspended breakpoints */
         if ((KdpBreakpointTable[BpIndex].Flags & KdpBreakpointActive) &&
@@ -195,3 +195,36 @@ KdpRestoreAllBreakpoints(VOID)
         }
     }
 }
         }
     }
 }
+
+VOID
+NTAPI
+KdpSuspendBreakPoint(IN ULONG BpEntry)
+{
+    ULONG BpIndex = BpEntry - 1;
+
+    /* Check if this is a valid, unsuspended breakpoint */
+    if ((KdpBreakpointTable[BpIndex].Flags & KdpBreakpointActive) &&
+        !(KdpBreakpointTable[BpIndex].Flags & KdpBreakpointSuspended))
+    {
+        /* Suspend it */
+        KdpBreakpointTable[BpIndex].Flags |= KdpBreakpointSuspended;
+        KdpLowWriteContent(BpIndex);
+    }
+}
+
+VOID
+NTAPI
+KdpSuspendAllBreakPoints(VOID)
+{
+    ULONG BpEntry;
+
+    /* Breakpoints are suspended */
+    BreakpointsSuspended = TRUE;
+
+    /* Loop every breakpoint */
+    for (BpEntry = 1; BpEntry <= KD_BREAKPOINT_MAX; BpEntry++)
+    {
+        /* Suspend it */
+        KdpSuspendBreakPoint(BpEntry);
+    }
+}
index 577b5e7..9af857a 100644 (file)
@@ -68,6 +68,8 @@ BOOLEAN KdPitchDebugger;
 BOOLEAN _KdDebuggerNotPresent;
 BOOLEAN _KdDebuggerEnabled;
 BOOLEAN KdAutoEnableOnEvent;
 BOOLEAN _KdDebuggerNotPresent;
 BOOLEAN _KdDebuggerEnabled;
 BOOLEAN KdAutoEnableOnEvent;
+BOOLEAN KdBlockEnable;
+BOOLEAN KdIgnoreUmExceptions;
 BOOLEAN KdPreviouslyEnabled;
 BOOLEAN KdpDebuggerStructuresInitialized;
 BOOLEAN KdEnteredDebugger;
 BOOLEAN KdPreviouslyEnabled;
 BOOLEAN KdpDebuggerStructuresInitialized;
 BOOLEAN KdEnteredDebugger;
@@ -83,6 +85,9 @@ BOOLEAN KdpOweBreakpoint;
 BOOLEAN BreakpointsSuspended;
 ULONG KdpNumInternalBreakpoints;
 
 BOOLEAN BreakpointsSuspended;
 ULONG KdpNumInternalBreakpoints;
 
+//
+// Symbol Data
+//
 ULONG KdpCurrentSymbolStart, KdpCurrentSymbolEnd;
 
 //
 ULONG KdpCurrentSymbolStart, KdpCurrentSymbolEnd;
 
 //
index f62e612..e5c487c 100644 (file)
@@ -72,15 +72,20 @@ NTAPI
 KdInitSystem(IN ULONG BootPhase,
              IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 {
 KdInitSystem(IN ULONG BootPhase,
              IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 {
-    BOOLEAN EnableKd;
-    LPSTR CommandLine, DebugLine;
+    BOOLEAN EnableKd, DisableKdAfterInit = FALSE, BlockEnable;
+    LPSTR CommandLine, DebugLine, DebugOptionStart, DebugOptionEnd;
     ANSI_STRING ImageName;
     PLDR_DATA_TABLE_ENTRY LdrEntry;
     PLIST_ENTRY NextEntry;
     ANSI_STRING ImageName;
     PLDR_DATA_TABLE_ENTRY LdrEntry;
     PLIST_ENTRY NextEntry;
-    ULONG i, j, Length;
+    ULONG i, j, Length, DebugOptionLength;
     CHAR NameBuffer[256];
     PWCHAR Name;
 
     CHAR NameBuffer[256];
     PWCHAR Name;
 
+#if defined(__GNUC__)
+    /* Make gcc happy */
+    BlockEnable = FALSE;
+#endif
+
     /* Check if this is Phase 1 */
     if (BootPhase)
     {
     /* Check if this is Phase 1 */
     if (BootPhase)
     {
@@ -166,10 +171,87 @@ KdInitSystem(IN ULONG BootPhase,
                 /* Enable KD */
                 EnableKd = TRUE;
 
                 /* Enable KD */
                 EnableKd = TRUE;
 
-                /* Check if there was additional data */
+                /* Check if there are any options */
                 if (DebugLine[5] == '=')
                 {
                 if (DebugLine[5] == '=')
                 {
-                    /* FIXME: Check for NOUMEX, DISABLE, AUTOENABLE */
+                    /* Save pointers */
+                    DebugOptionStart = DebugOptionEnd = &DebugLine[6];
+
+                    /* Scan the string for debug options */
+                    for (;;)
+                    {
+                        /* Loop until we reach the end of the string */
+                        while (*DebugOptionEnd != ANSI_NULL)
+                        {
+                            /* Check if this is a comma, a space or a tab */
+                            if ((*DebugOptionEnd == ',') ||
+                                (*DebugOptionEnd == ' ') ||
+                                (*DebugOptionEnd == '  '))
+                            {
+                                /*
+                                 * We reached the end of the option or
+                                 * the end of the string, break out
+                                 */
+                                break;
+                            }
+                            else
+                            {
+                                /* Move on to the next character */
+                                DebugOptionEnd++;
+                            }
+                        }
+
+                        /* Calculate the length of the current option */
+                        DebugOptionLength = ((ULONG_PTR)DebugOptionEnd -
+                                             (ULONG_PTR)DebugOptionStart);
+
+                       /*
+                        * Break out if we reached the last option
+                        * or if there were no options at all
+                        */
+                       if (!DebugOptionLength) break;
+
+                        /* Now check which option this is */
+                        if ((DebugOptionLength == 10) &&
+                            !(strncmp(DebugOptionStart, "AUTOENABLE", 10)))
+                        {
+                            /*
+                             * Disable the debugger, but
+                             * allow it to be reenabled 
+                             */
+                            DisableKdAfterInit = TRUE;
+                            BlockEnable = FALSE;
+                            KdAutoEnableOnEvent = TRUE;
+                        }
+                        else if ((DebugOptionLength == 7) &&
+                                 !(strncmp(DebugOptionStart, "DISABLE", 7)))
+                        {
+                            /* Disable the debugger */
+                            DisableKdAfterInit = TRUE;
+                            BlockEnable = TRUE;
+                            KdAutoEnableOnEvent = FALSE;
+                        }
+                        else if ((DebugOptionLength == 6) &&
+                                 !(strncmp(DebugOptionStart, "NOUMEX", 6)))
+                        {
+                            /* Ignore user mode exceptions */
+                            KdIgnoreUmExceptions = TRUE;
+                        }
+
+                        /*
+                         * If there are more options then 
+                         * the next character should be a comma
+                         */
+                        if (*DebugOptionEnd != ',')
+                        {
+                            /* It isn't, break out  */
+                            break;
+                        }
+
+                        /* Move on to the next option */
+                        DebugOptionEnd++;
+                        DebugOptionStart = DebugOptionEnd;
+                    }
                 }
             }
         }
                 }
             }
         }
@@ -182,7 +264,7 @@ KdInitSystem(IN ULONG BootPhase,
     }
     else
     {
     }
     else
     {
-        /* Called from a bugcheck...Save the Kernel Base */
+        /* Called from a bugcheck or a re-enable. Save the Kernel Base */
         KdVersionBlock.KernBase = (ULONG64)(LONG_PTR)PsNtosImageBase;
 
         /* Unconditionally enable KD */
         KdVersionBlock.KernBase = (ULONG64)(LONG_PTR)PsNtosImageBase;
 
         /* Unconditionally enable KD */
@@ -226,6 +308,20 @@ KdInitSystem(IN ULONG BootPhase,
         SharedUserData->KdDebuggerEnabled = TRUE;
 #define KdDebuggerEnabled _KdDebuggerEnabled
 
         SharedUserData->KdDebuggerEnabled = TRUE;
 #define KdDebuggerEnabled _KdDebuggerEnabled
 
+        /* Check if the debugger should be disabled initially */
+        if (DisableKdAfterInit)
+        {
+            /* Disable it */
+            KdDisableDebuggerWithLock(FALSE);
+
+            /*
+             * Save the enable block state and return initialized
+             * (the debugger is active but disabled).
+             */
+            KdBlockEnable = BlockEnable;
+            return TRUE;
+        }
+
         /* Check if we have a loader block */
         if (LoaderBlock)
         {
         /* Check if we have a loader block */
         if (LoaderBlock)
         {
index 99f779d..409b2e9 100644 (file)
@@ -289,3 +289,24 @@ KdpStub(IN PKTRAP_FRAME TrapFrame,
         return FALSE;
     }
 }
         return FALSE;
     }
 }
+
+BOOLEAN
+NTAPI
+KdIsThisAKdTrap(IN PEXCEPTION_RECORD ExceptionRecord,
+                IN PCONTEXT Context,
+                IN KPROCESSOR_MODE PreviousMode)
+{
+    /* Check if this is a breakpoint or a valid debug service */
+    if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
+        (ExceptionRecord->NumberParameters > 0) &&
+        (ExceptionRecord->ExceptionInformation[0] != BREAKPOINT_BREAK))
+    {
+        /* Then we have to handle it */
+        return TRUE;
+    }
+    else
+    {
+        /* We don't have to handle it */
+        return FALSE;
+    }
+}
index 6ee3c74..bd0df7a 100644 (file)
@@ -928,11 +928,19 @@ KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
         /* User mode exception, was it first-chance? */
         if (FirstChance)
         {
         /* User mode exception, was it first-chance? */
         if (FirstChance)
         {
-            /* Make sure a debugger is present, and ignore user-mode if requested */
-            if ((KiDebugRoutine) &&
-                (!(PsGetCurrentProcess()->DebugPort)))
+            /* 
+             * Break into the kernel debugger unless a user mode debugger
+             * is present or user mode exceptions are ignored, unless this is
+             * a breakpoint or a debug service in which case we have to
+             * handle it.
+             */
+            if ((!(PsGetCurrentProcess()->DebugPort) &&
+                 !(KdIgnoreUmExceptions)) ||
+                 (KdIsThisAKdTrap(ExceptionRecord,
+                                  &Context,
+                                  PreviousMode)))
             {
             {
-                /* Call the debugger */
+                /* Call the kernel debugger */
                 if (KiDebugRoutine(TrapFrame,
                                    ExceptionFrame,
                                    ExceptionRecord,
                 if (KiDebugRoutine(TrapFrame,
                                    ExceptionFrame,
                                    ExceptionRecord,
@@ -946,7 +954,7 @@ KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
             }
 
             /* Forward exception to user mode debugger */
             }
 
             /* Forward exception to user mode debugger */
-            if (DbgkForwardException(ExceptionRecord, TRUE, FALSE)) goto Exit;
+            if (DbgkForwardException(ExceptionRecord, TRUE, FALSE)) return;
 
             /* Set up the user-stack */
 DispatchToUser:
 
             /* Set up the user-stack */
 DispatchToUser:
@@ -1032,12 +1040,12 @@ DispatchToUser:
         if (DbgkForwardException(ExceptionRecord, TRUE, TRUE))
         {
             /* Handled, get out */
         if (DbgkForwardException(ExceptionRecord, TRUE, TRUE))
         {
             /* Handled, get out */
-            goto Exit;
+            return;
         }
         else if (DbgkForwardException(ExceptionRecord, FALSE, TRUE))
         {
             /* Handled, get out */
         }
         else if (DbgkForwardException(ExceptionRecord, FALSE, TRUE))
         {
             /* Handled, get out */
-            goto Exit;
+            return;
         }
 
         /* 3rd strike, kill the process */
         }
 
         /* 3rd strike, kill the process */
@@ -1061,7 +1069,6 @@ Handled:
                          TrapFrame,
                          Context.ContextFlags,
                          PreviousMode);
                          TrapFrame,
                          Context.ContextFlags,
                          PreviousMode);
-Exit:
     return;
 }
 
     return;
 }
 
index e46dfea..190855f 100644 (file)
@@ -781,7 +781,7 @@ _KiTrap3:
     TRAP_PROLOG kit3_a, kit3_t
 
     /* Set status code */
     TRAP_PROLOG kit3_a, kit3_t
 
     /* Set status code */
-    mov eax, 0 //STATUS_SUCCESS
+    mov eax, STATUS_SUCCESS
 
     /* Check for V86 */
 PrepareInt3:
 
     /* Check for V86 */
 PrepareInt3:
index 69871e2..5ff09a5 100644 (file)
                        <file>pnproot.c</file>
                </directory>
        </directory>
                        <file>pnproot.c</file>
                </directory>
        </directory>
-       <directory name="kd">
-               <if property="ARCH" value="i386">
-                       <directory name="i386">
-                               <file>kdmemsup.c</file>
-                       </directory>
-               </if>
-       </directory>
+       <if property="KDBG" value="1">
+               <directory name="kd">
+                       <if property="ARCH" value="i386">
+                               <directory name="i386">
+                                       <file>kdmemsup.c</file>
+                               </directory>
+                       </if>
+               </directory>
+       </if>
        <if property="_WINKD_" value="0">
                <directory name="kdbg">
                        <if property="ARCH" value="i386">
        <if property="_WINKD_" value="0">
                <directory name="kdbg">
                        <if property="ARCH" value="i386">