* 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(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;
}