[EXT2] Upgrade to 0.69
[reactos.git] / boot / freeldr / freeldr / bootmgr.c
index 2295e50..e370c28 100644 (file)
  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+/* INCLUDES *******************************************************************/
+
 #include <freeldr.h>
+#include <debug.h>
+
+/* GLOBALS ********************************************************************/
+
+typedef
+VOID
+(*OS_LOADING_METHOD)(IN OperatingSystemItem* OperatingSystem,
+                     IN USHORT OperatingSystemVersion);
+
+struct
+{
+    CHAR BootType[80];
+    USHORT OperatingSystemVersion;
+    OS_LOADING_METHOD Load;
+} OSLoadingMethods[] =
+{
+    {"ReactOSSetup", 0                , LoadReactOSSetup     },
+
+#ifdef _M_IX86
+    {"BootSector"  , 0                , LoadAndBootBootSector},
+    {"Drive"       , 0                , LoadAndBootDrive     },
+    {"Partition"   , 0                , LoadAndBootPartition },
+
+    {"Linux"       , 0                , LoadAndBootLinux     },
 
-ARC_DISK_SIGNATURE reactos_arc_disk_info[32]; // ARC Disk Information
-unsigned long reactos_disk_count = 0;
-char reactos_arc_hardware_data[HW_MAX_ARC_HEAP_SIZE] = {0};
-char reactos_arc_strings[32][256];
+    {"Windows"     , 0                , LoadAndBootWindows   },
+    {"WindowsNT40" , _WIN32_WINNT_NT4 , LoadAndBootWindows   },
+#endif
+    {"Windows2003" , _WIN32_WINNT_WS03, LoadAndBootWindows   },
+};
+
+/* FUNCTIONS ******************************************************************/
 
-ULONG   GetDefaultOperatingSystem(OperatingSystemItem* OperatingSystemList, ULONG       OperatingSystemCount)
+VOID LoadOperatingSystem(IN OperatingSystemItem* OperatingSystem)
 {
-       CHAR    DefaultOSText[80];
-       PCSTR   DefaultOSName;
-       ULONG_PTR       SectionId;
-       ULONG   DefaultOS = 0;
-       ULONG   Idx;
-
-       if (!IniOpenSection("FreeLoader", &SectionId))
-       {
-               return 0;
-       }
-
-       DefaultOSName = CmdLineGetDefaultOS();
-       if (NULL == DefaultOSName)
-       {
-               if (IniReadSettingByName(SectionId, "DefaultOS", DefaultOSText, sizeof(DefaultOSText)))
-               {
-                       DefaultOSName = DefaultOSText;
-               }
-       }
-
-       if (NULL != DefaultOSName)
-       {
-               for (Idx=0; Idx<OperatingSystemCount; Idx++)
-               {
-                       if (_stricmp(DefaultOSName, OperatingSystemList[Idx].SystemPartition) == 0)
-                       {
-                               DefaultOS = Idx;
-                               break;
-                       }
-               }
-       }
-
-       return DefaultOS;
+    ULONG_PTR SectionId;
+    PCSTR SectionName = OperatingSystem->SystemPartition;
+    CHAR BootType[80];
+    ULONG i;
+
+    /* Try to open the operating system section in the .ini file */
+    if (IniOpenSection(SectionName, &SectionId))
+    {
+        /* Try to read the boot type */
+        IniReadSettingByName(SectionId, "BootType", BootType, sizeof(BootType));
+    }
+    else
+    {
+        BootType[0] = ANSI_NULL;
+    }
+
+    if (BootType[0] == ANSI_NULL && SectionName[0] != ANSI_NULL)
+    {
+        /* Try to infer the boot type value */
+#ifdef _M_IX86
+        ULONG FileId;
+        if (ArcOpen((PSTR)SectionName, OpenReadOnly, &FileId) == ESUCCESS)
+        {
+            ArcClose(FileId);
+            strcpy(BootType, "BootSector");
+        }
+        else
+#endif
+        {
+            strcpy(BootType, "Windows");
+        }
+    }
+
+    /* Install the drive mapper according to this section drive mappings */
+#if defined(_M_IX86) && !defined(_MSC_VER)
+    DriveMapMapDrivesInSection(SectionName);
+#endif
+
+    /* Loop through the OS loading method table and find a suitable OS to boot */
+    for (i = 0; i < sizeof(OSLoadingMethods) / sizeof(OSLoadingMethods[0]); ++i)
+    {
+        if (_stricmp(BootType, OSLoadingMethods[i].BootType) == 0)
+        {
+            OSLoadingMethods[i].Load(OperatingSystem,
+                                     OSLoadingMethods[i].OperatingSystemVersion);
+            return;
+        }
+    }
 }
 
-LONG GetTimeOut(VOID)
+ULONG GetDefaultOperatingSystem(OperatingSystemItem* OperatingSystemList, ULONG OperatingSystemCount)
 {
-       CHAR    TimeOutText[20];
-       LONG            TimeOut;
-       ULONG_PTR       SectionId;
-
-       TimeOut = CmdLineGetTimeOut();
-       if (0 <= TimeOut)
-       {
-               return TimeOut;
-       }
-
-       if (!IniOpenSection("FreeLoader", &SectionId))
-       {
-               return -1;
-       }
-
-       if (IniReadSettingByName(SectionId, "TimeOut", TimeOutText, sizeof(TimeOutText)))
-       {
-               TimeOut = atoi(TimeOutText);
-       }
-       else
-       {
-               TimeOut = -1;
-       }
-
-       return TimeOut;
+    CHAR      DefaultOSText[80];
+    PCSTR     DefaultOSName;
+    ULONG_PTR SectionId;
+    ULONG     DefaultOS = 0;
+    ULONG     Idx;
+
+    if (!IniOpenSection("FreeLoader", &SectionId))
+        return 0;
+
+    DefaultOSName = CmdLineGetDefaultOS();
+    if (DefaultOSName == NULL)
+    {
+        if (IniReadSettingByName(SectionId, "DefaultOS", DefaultOSText, sizeof(DefaultOSText)))
+        {
+            DefaultOSName = DefaultOSText;
+        }
+    }
+
+    if (DefaultOSName != NULL)
+    {
+        for (Idx = 0; Idx < OperatingSystemCount; Idx++)
+        {
+            if (_stricmp(DefaultOSName, OperatingSystemList[Idx].SystemPartition) == 0)
+            {
+                DefaultOS = Idx;
+                break;
+            }
+        }
+    }
+
+    return DefaultOS;
 }
 
-BOOLEAN MainBootMenuKeyPressFilter(ULONG KeyPress)
+LONG GetTimeOut(VOID)
 {
-       if (KeyPress == KEY_F8)
-       {
-               DoOptionsMenu();
+    CHAR    TimeOutText[20];
+    LONG        TimeOut;
+    ULONG_PTR    SectionId;
+
+    TimeOut = CmdLineGetTimeOut();
+    if (TimeOut >= 0)
+        return TimeOut;
 
-               return TRUE;
-       }
+    if (!IniOpenSection("FreeLoader", &SectionId))
+        return -1;
 
-       // We didn't handle the key
-       return FALSE;
+    if (IniReadSettingByName(SectionId, "TimeOut", TimeOutText, sizeof(TimeOutText)))
+        TimeOut = atoi(TimeOutText);
+    else
+        TimeOut = -1;
+
+    return TimeOut;
 }
 
-VOID RunLoader(VOID)
+BOOLEAN MainBootMenuKeyPressFilter(ULONG KeyPress)
 {
-       CHAR    SettingValue[80];
-       CHAR BootType[80];
-       ULONG_PTR       SectionId;
-       ULONG           OperatingSystemCount;
-       OperatingSystemItem*    OperatingSystemList;
-       PCSTR   *OperatingSystemDisplayNames;
-       PCSTR SectionName;
-       ULONG   i;
-       ULONG           DefaultOperatingSystem;
-       LONG            TimeOut;
-       ULONG           SelectedOperatingSystem;
-
-       // FIXME: if possible, only detect and register ARC devices...
-       if (!MachHwDetect())
-       {
-               UiMessageBoxCritical("Error when detecting hardware");
-               return;
-       }
+    if (KeyPress == KEY_F8)
+    {
+        DoOptionsMenu();
+        return TRUE;
+    }
+
+    /* We didn't handle the key */
+    return FALSE;
+}
 
-#ifdef _M_IX86
-       // Load additional SCSI driver (if any)
-       if (LoadBootDeviceDriver() != ESUCCESS)
-       {
-               UiMessageBoxCritical("Unable to load additional boot device driver");
-       }
-#endif
+VOID RunLoader(VOID)
+{
+    ULONG_PTR SectionId;
+    ULONG     OperatingSystemCount;
+    OperatingSystemItem* OperatingSystemList;
+    PCSTR*    OperatingSystemDisplayNames;
+    ULONG     DefaultOperatingSystem;
+    LONG      TimeOut;
+    ULONG     SelectedOperatingSystem;
+    ULONG     i;
+
+    if (!MachInitializeBootDevices())
+    {
+        UiMessageBoxCritical("Error when detecting hardware.");
+        return;
+    }
 
-       if (!IniFileInitialize())
-       {
-               UiMessageBoxCritical("Error initializing .ini file");
-               return;
-       }
-
-       if (!IniOpenSection("FreeLoader", &SectionId))
-       {
-               UiMessageBoxCritical("Section [FreeLoader] not found in freeldr.ini.");
-               return;
-       }
-       TimeOut = GetTimeOut();
-
-       if (!UiInitialize(TRUE))
-       {
-               UiMessageBoxCritical("Unable to initialize UI.");
-               return;
-       }
-
-       OperatingSystemList = InitOperatingSystemList(&OperatingSystemCount);
-       if (!OperatingSystemList)
-       {
-               UiMessageBox("Unable to read operating systems section in freeldr.ini.\nPress ENTER to reboot.");
-               goto reboot;
-       }
-
-       if (OperatingSystemCount == 0)
-       {
-               UiMessageBox("There were no operating systems listed in freeldr.ini.\nPress ENTER to reboot.");
-               goto reboot;
-       }
-
-       DefaultOperatingSystem = GetDefaultOperatingSystem(OperatingSystemList, OperatingSystemCount);
-
-       //
-       // Create list of display names
-       //
-       OperatingSystemDisplayNames = MmHeapAlloc(sizeof(PCSTR) * OperatingSystemCount);
-       if (!OperatingSystemDisplayNames)
-       {
-               goto reboot;
-       }
-       for (i = 0; i < OperatingSystemCount; i++)
-       {
-               OperatingSystemDisplayNames[i] = OperatingSystemList[i].LoadIdentifier;
-       }
-
-       //
-       // Find all the message box settings and run them
-       //
-       UiShowMessageBoxesInSection("FreeLoader");
-
-       for (;;)
-       {
-
-               // Redraw the backdrop
-               UiDrawBackdrop();
-
-               // Show the operating system list menu
-               if (!UiDisplayMenu("Please select the operating system to start:",
-                                  OperatingSystemDisplayNames,
-                                  OperatingSystemCount,
-                                  DefaultOperatingSystem,
-                                  TimeOut,
-                                  &SelectedOperatingSystem,
-                                  FALSE,
-                                  MainBootMenuKeyPressFilter))
-               {
-                       UiMessageBox("Press ENTER to reboot.");
-                       goto reboot;
-               }
-
-               TimeOut = -1;
-
-               // Try to open the operating system section in the .ini file
-               SettingValue[0] = ANSI_NULL;
-               SectionName = OperatingSystemList[SelectedOperatingSystem].SystemPartition;
-               if (IniOpenSection(SectionName, &SectionId))
-               {
-                       // Try to read the boot type
-                       IniReadSettingByName(SectionId, "BootType", BootType, sizeof(BootType));
-               }
-               else
-                       BootType[0] = ANSI_NULL;
-
-               if (BootType[0] == ANSI_NULL && SectionName[0] != ANSI_NULL)
-               {
-                       // Try to infere boot type value
 #ifdef _M_IX86
-                       ULONG FileId;
-                       if (ArcOpen((CHAR*)SectionName, OpenReadOnly, &FileId) == ESUCCESS)
-                       {
-                               ArcClose(FileId);
-                               strcpy(BootType, "BootSector");
-                       }
-                       else
-#endif
-                       {
-                               strcpy(BootType, "Windows");
-                       }
-               }
-
-               // Get OS setting value
-               IniOpenSection("Operating Systems", &SectionId);
-               IniReadSettingByName(SectionId, SectionName, SettingValue, sizeof(SettingValue));
-
-               // Install the drive mapper according to this sections drive mappings
-#if defined(_M_IX86) && !defined(_MSC_VER)
-               DriveMapMapDrivesInSection(SectionName);
-#endif
-
-#ifdef FREELDR_REACTOS_SETUP
-        // WinLdr-style boot
-        LoadReactOSSetup();
-#elif defined(_M_IX86)
-               if (_stricmp(BootType, "Windows") == 0)
-               {
-                       LoadAndBootWindows(SectionName, SettingValue, 0);
-               }
-               else if (_stricmp(BootType, "WindowsNT40") == 0)
-               {
-                       LoadAndBootWindows(SectionName, SettingValue, _WIN32_WINNT_NT4);
-               }
-               else if (_stricmp(BootType, "Windows2003") == 0)
-               {
-                       LoadAndBootWindows(SectionName, SettingValue, _WIN32_WINNT_WS03);
-               }
-               else if (_stricmp(BootType, "Linux") == 0)
-               {
-                       LoadAndBootLinux(SectionName, OperatingSystemDisplayNames[SelectedOperatingSystem]);
-               }
-               else if (_stricmp(BootType, "BootSector") == 0)
-               {
-                       LoadAndBootBootSector(SectionName);
-               }
-               else if (_stricmp(BootType, "Partition") == 0)
-               {
-                       LoadAndBootPartition(SectionName);
-               }
-               else if (_stricmp(BootType, "Drive") == 0)
-               {
-                       LoadAndBootDrive(SectionName);
-               }
-#else
-               LoadAndBootWindows(SectionName, SettingValue, _WIN32_WINNT_WS03);
+    /* Load additional SCSI driver (if any) */
+    if (LoadBootDeviceDriver() != ESUCCESS)
+    {
+        UiMessageBoxCritical("Unable to load additional boot device drivers.");
+    }
 #endif
-       }
 
-reboot:
-       UiUnInitialize("Rebooting...");
-       return;
+    if (!IniFileInitialize())
+    {
+        UiMessageBoxCritical("Error initializing .ini file.");
+        return;
+    }
+
+    /* Debugger main initialization */
+    DebugInit(TRUE);
+
+    if (!IniOpenSection("FreeLoader", &SectionId))
+    {
+        UiMessageBoxCritical("Section [FreeLoader] not found in freeldr.ini.");
+        return;
+    }
+
+    TimeOut = GetTimeOut();
+
+    /* UI main initialization */
+    if (!UiInitialize(TRUE))
+    {
+        UiMessageBoxCritical("Unable to initialize UI.");
+        return;
+    }
+
+    OperatingSystemList = InitOperatingSystemList(&OperatingSystemCount);
+    if (!OperatingSystemList)
+    {
+        UiMessageBox("Unable to read operating systems section in freeldr.ini.\nPress ENTER to reboot.");
+        goto Reboot;
+    }
+
+    if (OperatingSystemCount == 0)
+    {
+        UiMessageBox("There were no operating systems listed in freeldr.ini.\nPress ENTER to reboot.");
+        goto Reboot;
+    }
+
+    DefaultOperatingSystem = GetDefaultOperatingSystem(OperatingSystemList, OperatingSystemCount);
+
+    /* Create list of display names */
+    OperatingSystemDisplayNames = FrLdrTempAlloc(sizeof(PCSTR) * OperatingSystemCount, 'mNSO');
+    if (!OperatingSystemDisplayNames)
+        goto Reboot;
+
+    for (i = 0; i < OperatingSystemCount; i++)
+    {
+        OperatingSystemDisplayNames[i] = OperatingSystemList[i].LoadIdentifier;
+    }
+
+    /* Find all the message box settings and run them */
+    UiShowMessageBoxesInSection("FreeLoader");
+
+    for (;;)
+    {
+        /* Redraw the backdrop */
+        UiDrawBackdrop();
+
+        /* Show the operating system list menu */
+        if (!UiDisplayMenu("Please select the operating system to start:",
+                           "For troubleshooting and advanced startup options for "
+                               "ReactOS, press F8.",
+                           TRUE,
+                           OperatingSystemDisplayNames,
+                           OperatingSystemCount,
+                           DefaultOperatingSystem,
+                           TimeOut,
+                           &SelectedOperatingSystem,
+                           FALSE,
+                           MainBootMenuKeyPressFilter))
+        {
+            UiMessageBox("Press ENTER to reboot.");
+            goto Reboot;
+        }
+
+        TimeOut = -1;
+
+        /* Load the chosen operating system */
+        LoadOperatingSystem(&OperatingSystemList[SelectedOperatingSystem]);
+    }
+
+Reboot:
+    UiUnInitialize("Rebooting...");
+    return;
 }