[FREELDR] Diverse enhancements.
[reactos.git] / boot / freeldr / freeldr / options.c
index 5b64b46..ac30225 100644 (file)
  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+/* INCLUDES *******************************************************************/
+
 #include <freeldr.h>
+#include <debug.h>
+
+/* GLOBALS ********************************************************************/
 
-PCSTR  OptionsMenuList[] =
+PCSTR OptionsMenuList[] =
 {
-       "Safe Mode",
-       "Safe Mode with Networking",
-       "Safe Mode with Command Prompt",
+    "Safe Mode",
+    "Safe Mode with Networking",
+    "Safe Mode with Command Prompt",
 
-       "SEPARATOR",
+    NULL,
 
-       "Enable Boot Logging",
-       "Enable VGA Mode",
-       "Last Known Good Configuration",
-       "Directory Services Restore Mode",
-       "Debugging Mode",
+    "Enable Boot Logging",
+    "Enable VGA Mode",
+    "Last Known Good Configuration",
+    "Directory Services Restore Mode",
+    "Debugging Mode",
+    "FreeLdr debugging",
 
-       "SEPARATOR",
+    NULL,
 
+    "Start ReactOS normally",
+#ifdef HAS_OPTION_MENU_EDIT_CMDLINE
+    "Edit Boot Command Line (F10)",
+#endif
 #ifdef HAS_OPTION_MENU_CUSTOM_BOOT
-       "Custom Boot",
+    "Custom Boot",
 #endif
 #ifdef HAS_OPTION_MENU_REBOOT
-       "Reboot",
+    "Reboot",
 #endif
 };
 
-enum OptionMenuItems
-{
-       SAFE_MODE = 0,
-       SAFE_MODE_WITH_NETWORKING = 1,
-       SAFE_MODE_WITH_COMMAND_PROMPT = 2,
+const
+PCSTR FrldrDbgMsg = "Enable FreeLdr debug channels\n"
+                    "Acceptable syntax: [level1]#channel1[,[level2]#channel2]\n"
+                    "level can be one of: trace,warn,fixme,err\n"
+                    "  if the level is omitted all levels\n"
+                    "  are enabled for the specified channel\n"
+                    "# can be either + or -\n"
+                    "channel can be one of the following:\n"
+                    "  all,warning,memory,filesystem,inifile,ui,disk,cache,registry,\n"
+                    "  reactos,linux,hwdetect,windows,peloader,scsiport,heap\n"
+                    "Examples:\n"
+                    "  trace+windows,trace+reactos\n"
+                    "  +hwdetect,err-disk\n"
+                    "  +peloader\n"
+                    "NOTE: all letters must be lowercase, no spaces allowed.";
 
-       SEPARATOR1 = 3,
-
-       ENABLE_BOOT_LOGGING = 4,
-       ENABLE_VGA_MODE = 5,
-       LAST_KNOWN_GOOD_CONFIGURATION = 6,
-       DIRECTORY_SERVICES_RESTORE_MODE = 7,
-       DEBUGGING_MODE = 8,
+/* The boot options are mutually exclusive */
+enum BootOption
+{
+    NO_OPTION = 0,
 
-       SEPARATOR2 = 9,
+    SAFE_MODE,
+    SAFE_MODE_WITH_NETWORKING,
+    SAFE_MODE_WITH_COMMAND_PROMPT,
 
-#ifdef HAS_OPTION_MENU_CUSTOM_BOOT
-       CUSTOM_BOOT = 10,
-#endif
-#ifdef HAS_OPTION_MENU_REBOOT
-       REBOOT = 11,
-#endif
+    LAST_KNOWN_GOOD_CONFIGURATION,
+    DIRECTORY_SERVICES_RESTORE_MODE,
 };
 
-ULONG          OptionsMenuItemCount = sizeof(OptionsMenuList) / sizeof(OptionsMenuList[0]);
+static enum BootOption BootOptionChoice = NO_OPTION;
+static BOOLEAN BootLogging = FALSE;
+static BOOLEAN VgaMode = FALSE;
+static BOOLEAN DebuggingMode = FALSE;
 
-BOOLEAN SafeMode = FALSE;
-BOOLEAN SafeModeWithNetworking = FALSE;
-BOOLEAN SafeModeWithCommandPrompt = FALSE;
-BOOLEAN BootLogging = FALSE;
-BOOLEAN VgaMode = FALSE;
-BOOLEAN LastKnownGoodConfiguration = FALSE;
-BOOLEAN DirectoryServicesRepairMode = FALSE;
-BOOLEAN DebuggingMode = FALSE;
+/* FUNCTIONS ******************************************************************/
 
-VOID DoOptionsMenu(VOID)
+VOID DoOptionsMenu(IN OperatingSystemItem* OperatingSystem)
 {
-       ULONG           SelectedMenuItem;
-
-       if (!UiDisplayMenu(OptionsMenuList, OptionsMenuItemCount, 0, -1, &SelectedMenuItem, TRUE, NULL))
-       {
-               // The user pressed ESC
-               return;
-       }
-
-       // Clear the backdrop
-       UiDrawBackdrop();
-
-       switch (SelectedMenuItem)
-       {
-       case SAFE_MODE:
-               SafeMode = TRUE;
-               BootLogging = TRUE;
-               break;
-       case SAFE_MODE_WITH_NETWORKING:
-               SafeModeWithNetworking = TRUE;
-               BootLogging = TRUE;
-               break;
-       case SAFE_MODE_WITH_COMMAND_PROMPT:
-               SafeModeWithCommandPrompt = TRUE;
-               BootLogging = TRUE;
-               break;
-       //case SEPARATOR1:
-       //      break;
-       case ENABLE_BOOT_LOGGING:
-               BootLogging = TRUE;
-               break;
-       case ENABLE_VGA_MODE:
-               VgaMode = TRUE;
-               break;
-       case LAST_KNOWN_GOOD_CONFIGURATION:
-               LastKnownGoodConfiguration = TRUE;
-               break;
-       case DIRECTORY_SERVICES_RESTORE_MODE:
-               DirectoryServicesRepairMode = TRUE;
-               break;
-       case DEBUGGING_MODE:
-               DebuggingMode = TRUE;
-               break;
-       //case SEPARATOR2:
-       //      break;
+    ULONG SelectedMenuItem;
+    CHAR  DebugChannelString[100];
+
+    if (!UiDisplayMenu("Select an option:", NULL,
+                       TRUE,
+                       OptionsMenuList,
+                       sizeof(OptionsMenuList) / sizeof(OptionsMenuList[0]),
+                       11, // Use "Start ReactOS normally" as default; see the switch below.
+                       -1,
+                       &SelectedMenuItem,
+                       TRUE,
+                       NULL, NULL))
+    {
+        /* The user pressed ESC */
+        return;
+    }
+
+    /* Clear the backdrop */
+    UiDrawBackdrop();
+
+    switch (SelectedMenuItem)
+    {
+        case 0: // Safe Mode
+            BootOptionChoice = SAFE_MODE;
+            BootLogging = TRUE;
+            break;
+        case 1: // Safe Mode with Networking
+            BootOptionChoice = SAFE_MODE_WITH_NETWORKING;
+            BootLogging = TRUE;
+            break;
+        case 2: // Safe Mode with Command Prompt
+            BootOptionChoice = SAFE_MODE_WITH_COMMAND_PROMPT;
+            BootLogging = TRUE;
+            break;
+        // case 3: // Separator
+        //     break;
+        case 4: // Enable Boot Logging
+            BootLogging = TRUE;
+            break;
+        case 5: // Enable VGA Mode
+            VgaMode = TRUE;
+            break;
+        case 6: // Last Known Good Configuration
+            BootOptionChoice = LAST_KNOWN_GOOD_CONFIGURATION;
+            break;
+        case 7: // Directory Services Restore Mode
+            BootOptionChoice = DIRECTORY_SERVICES_RESTORE_MODE;
+            break;
+        case 8: // Debugging Mode
+            DebuggingMode = TRUE;
+            break;
+        case 9: // FreeLdr debugging
+            DebugChannelString[0] = 0;
+            if (UiEditBox(FrldrDbgMsg,
+                          DebugChannelString,
+                          sizeof(DebugChannelString) / sizeof(DebugChannelString[0])))
+            {
+                DbgParseDebugChannels(DebugChannelString);
+            }
+            break;
+        // case 10: // Separator
+        //     break;
+        case 11: // Start ReactOS normally
+            // Reset all the parameters to their default values.
+            BootOptionChoice = NO_OPTION;
+            BootLogging = FALSE;
+            VgaMode = FALSE;
+            DebuggingMode = FALSE;
+            break;
+#ifdef HAS_OPTION_MENU_EDIT_CMDLINE
+        case 12: // Edit command line
+            EditOperatingSystemEntry(OperatingSystem);
+            break;
+#endif
 #ifdef HAS_OPTION_MENU_CUSTOM_BOOT
-       case CUSTOM_BOOT:
-               OptionMenuCustomBoot();
-               break;
+        case 13: // Custom Boot
+            OptionMenuCustomBoot();
+            break;
 #endif
 #ifdef HAS_OPTION_MENU_REBOOT
-       case REBOOT:
-               OptionMenuReboot();
-               break;
+        case 14: // Reboot
+            OptionMenuReboot();
+            break;
 #endif
-       }
+    }
+}
+
+VOID DisplayBootTimeOptions(VOID)
+{
+    CHAR BootOptions[260] = "";
+
+    switch (BootOptionChoice)
+    {
+        case SAFE_MODE:
+            strcat(BootOptions, OptionsMenuList[0]);
+            break;
+
+        case SAFE_MODE_WITH_NETWORKING:
+            strcat(BootOptions, OptionsMenuList[1]);
+            break;
+
+        case SAFE_MODE_WITH_COMMAND_PROMPT:
+            strcat(BootOptions, OptionsMenuList[2]);
+            break;
+
+        case LAST_KNOWN_GOOD_CONFIGURATION:
+            strcat(BootOptions, OptionsMenuList[6]);
+            break;
+
+        case DIRECTORY_SERVICES_RESTORE_MODE:
+            strcat(BootOptions, OptionsMenuList[7]);
+            break;
+
+        default:
+            break;
+    }
+
+    if (BootLogging)
+    {
+        if ( (BootOptionChoice != SAFE_MODE) &&
+             (BootOptionChoice != SAFE_MODE_WITH_NETWORKING) &&
+             (BootOptionChoice != SAFE_MODE_WITH_COMMAND_PROMPT) )
+        {
+            if (BootOptionChoice != NO_OPTION)
+            {
+                strcat(BootOptions, ", ");
+            }
+            strcat(BootOptions, OptionsMenuList[4]);
+        }
+    }
+
+    if (VgaMode)
+    {
+        if ((BootOptionChoice != NO_OPTION) ||
+             BootLogging)
+        {
+            strcat(BootOptions, ", ");
+        }
+        strcat(BootOptions, OptionsMenuList[5]);
+    }
+
+    if (DebuggingMode)
+    {
+        if ((BootOptionChoice != NO_OPTION) ||
+             BootLogging || VgaMode)
+        {
+            strcat(BootOptions, ", ");
+        }
+        strcat(BootOptions, OptionsMenuList[8]);
+    }
+
+    /* Display the chosen boot options */
+    UiDrawText(0,
+               UiScreenHeight - 2,
+               BootOptions,
+               ATTR(COLOR_LIGHTBLUE, UiMenuBgColor));
 }
 
 VOID AppendBootTimeOptions(PCHAR BootOptions)
 {
-       if (SafeMode)
-               strcat(BootOptions, " /SAFEBOOT:MINIMAL /SOS"); //FIXME: NOGUIBOOT should also be specified
+    switch (BootOptionChoice)
+    {
+        case SAFE_MODE:
+            strcat(BootOptions, " /SAFEBOOT:MINIMAL /SOS /NOGUIBOOT");
+            break;
+
+        case SAFE_MODE_WITH_NETWORKING:
+            strcat(BootOptions, " /SAFEBOOT:NETWORK /SOS /NOGUIBOOT");
+            break;
 
-       if (SafeModeWithNetworking)
-               strcat(BootOptions, " /SAFEBOOT:NETWORK /SOS"); //FIXME: NOGUIBOOT should also be specified
+        case SAFE_MODE_WITH_COMMAND_PROMPT:
+            strcat(BootOptions, " /SAFEBOOT:MINIMAL(ALTERNATESHELL) /SOS /NOGUIBOOT");
+            break;
 
-       if (SafeModeWithCommandPrompt)
-               strcat(BootOptions, " /SAFEBOOT:MINIMAL(ALTERNATESHELL) /SOS"); //FIXME: NOGUIBOOT should also be specified
+        case LAST_KNOWN_GOOD_CONFIGURATION:
+            DbgPrint("Last known good configuration is not supported yet!\n");
+            break;
 
-       if (BootLogging)
-               strcat(BootOptions, " /BOOTLOG");
+        case DIRECTORY_SERVICES_RESTORE_MODE:
+            strcat(BootOptions, " /SAFEBOOT:DSREPAIR /SOS");
+            break;
 
-       if (VgaMode)
-               strcat(BootOptions, " /BASEVIDEO");
+        default:
+            break;
+    }
 
-       if (LastKnownGoodConfiguration)
-               DbgPrint("Last known good configuration is not supported yet!\n");
+    if (BootLogging)
+        strcat(BootOptions, " /BOOTLOG");
 
-       if (DirectoryServicesRepairMode)
-               strcat(BootOptions, " /SAFEBOOT:DSREPAIR /SOS");
+    if (VgaMode)
+        strcat(BootOptions, " /BASEVIDEO");
 
-       if (DebuggingMode)
-               strcat(BootOptions, " /DEBUG");
+    if (DebuggingMode)
+        strcat(BootOptions, " /DEBUG");
 }