- Add STATUS_SUCCESS to asm.h and make use of it.
[reactos.git] / reactos / ntoskrnl / kd64 / kdinit.c
index f62e612..e5c487c 100644 (file)
@@ -72,15 +72,20 @@ NTAPI
 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;
-    ULONG i, j, Length;
+    ULONG i, j, Length, DebugOptionLength;
     CHAR NameBuffer[256];
     PWCHAR Name;
 
+#if defined(__GNUC__)
+    /* Make gcc happy */
+    BlockEnable = FALSE;
+#endif
+
     /* Check if this is Phase 1 */
     if (BootPhase)
     {
@@ -166,10 +171,87 @@ KdInitSystem(IN ULONG BootPhase,
                 /* Enable KD */
                 EnableKd = TRUE;
 
-                /* Check if there was additional data */
+                /* Check if there are any options */
                 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
     {
-        /* 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 */
@@ -226,6 +308,20 @@ KdInitSystem(IN ULONG BootPhase,
         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)
         {