[FREELDR]

- Use a list of possible operating system method loading to load ReactOS / ROS-Setup / Windows / Linux or booting from a disk / partition ..., instead of using a (huge) if () else if () ... instruction.
- Modify the corresponding functions to take into account for this new functionality.
- Allow having a live + boot cd if needed, in a elegant way.

svn path=/trunk/; revision=57899
This commit is contained in:
Hermès Bélusca-Maïto 2012-12-13 00:46:55 +00:00
parent 5b900194af
commit d4129a2e07
9 changed files with 206 additions and 145 deletions

View file

@ -40,8 +40,8 @@ VOID OptionMenuCustomBoot(VOID)
"ReactOS",
"Linux"
};
ULONG CustomBootMenuCount = sizeof(CustomBootMenuList) / sizeof(CustomBootMenuList[0]);
ULONG SelectedMenuItem;
ULONG CustomBootMenuCount = sizeof(CustomBootMenuList) / sizeof(CustomBootMenuList[0]);
ULONG SelectedMenuItem;
if (!UiDisplayMenu("Please choose a boot method:",
CustomBootMenuList,
@ -74,10 +74,11 @@ VOID OptionMenuCustomBoot(VOID)
VOID OptionMenuCustomBootDisk(VOID)
{
CHAR SectionName[100];
CHAR BootDriveString[20];
ULONG SectionId;
ULONG_PTR SectionId;
CHAR SectionName[100];
CHAR BootDriveString[20];
TIMEINFO* TimeInfo;
OperatingSystemItem OperatingSystem;
RtlZeroMemory(SectionName, sizeof(SectionName));
RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
@ -111,16 +112,21 @@ VOID OptionMenuCustomBootDisk(VOID)
UiMessageBox(CustomBootPrompt);
LoadAndBootDrive(SectionName);
OperatingSystem.SystemPartition = SectionName;
OperatingSystem.LoadIdentifier = NULL;
OperatingSystem.OsLoadOptions = NULL;
LoadAndBootDrive(&OperatingSystem, 0);
}
VOID OptionMenuCustomBootPartition(VOID)
{
CHAR SectionName[100];
CHAR BootDriveString[20];
CHAR BootPartitionString[20];
ULONG SectionId;
ULONG_PTR SectionId;
CHAR SectionName[100];
CHAR BootDriveString[20];
CHAR BootPartitionString[20];
TIMEINFO* TimeInfo;
OperatingSystemItem OperatingSystem;
RtlZeroMemory(SectionName, sizeof(SectionName));
RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
@ -166,17 +172,22 @@ VOID OptionMenuCustomBootPartition(VOID)
UiMessageBox(CustomBootPrompt);
LoadAndBootPartition(SectionName);
OperatingSystem.SystemPartition = SectionName;
OperatingSystem.LoadIdentifier = NULL;
OperatingSystem.OsLoadOptions = NULL;
LoadAndBootPartition(&OperatingSystem, 0);
}
VOID OptionMenuCustomBootBootSectorFile(VOID)
{
CHAR SectionName[100];
CHAR BootDriveString[20];
CHAR BootPartitionString[20];
CHAR BootSectorFileString[200];
ULONG SectionId;
ULONG_PTR SectionId;
CHAR SectionName[100];
CHAR BootDriveString[20];
CHAR BootPartitionString[20];
CHAR BootSectorFileString[200];
TIMEINFO* TimeInfo;
OperatingSystemItem OperatingSystem;
RtlZeroMemory(SectionName, sizeof(SectionName));
RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
@ -234,19 +245,24 @@ VOID OptionMenuCustomBootBootSectorFile(VOID)
UiMessageBox(CustomBootPrompt);
LoadAndBootBootSector(SectionName);
OperatingSystem.SystemPartition = SectionName;
OperatingSystem.LoadIdentifier = NULL;
OperatingSystem.OsLoadOptions = NULL;
LoadAndBootBootSector(&OperatingSystem, 0);
}
VOID OptionMenuCustomBootLinux(VOID)
{
CHAR SectionName[100];
CHAR BootDriveString[20];
CHAR BootPartitionString[20];
CHAR LinuxKernelString[200];
CHAR LinuxInitrdString[200];
CHAR LinuxCommandLineString[200];
ULONG SectionId;
ULONG_PTR SectionId;
CHAR SectionName[100];
CHAR BootDriveString[20];
CHAR BootPartitionString[20];
CHAR LinuxKernelString[200];
CHAR LinuxInitrdString[200];
CHAR LinuxCommandLineString[200];
TIMEINFO* TimeInfo;
OperatingSystemItem OperatingSystem;
RtlZeroMemory(SectionName, sizeof(SectionName));
RtlZeroMemory(BootDriveString, sizeof(BootDriveString));
@ -331,7 +347,11 @@ VOID OptionMenuCustomBootLinux(VOID)
UiMessageBox(CustomBootPrompt);
LoadAndBootLinux(SectionName, "Custom Linux Setup");
OperatingSystem.SystemPartition = SectionName;
OperatingSystem.LoadIdentifier = "Custom Linux Setup";
OperatingSystem.OsLoadOptions = NULL;
LoadAndBootLinux(&OperatingSystem, 0);
}
VOID OptionMenuReboot(VOID)

View file

@ -19,21 +19,24 @@
#include <freeldr.h>
VOID LoadAndBootBootSector(PCSTR OperatingSystemName)
VOID
LoadAndBootBootSector(IN OperatingSystemItem* OperatingSystem,
IN USHORT OperatingSystemVersion)
{
PFILE FilePointer;
CHAR SettingName[80];
ULONG SectionId;
ULONG_PTR SectionId;
PCSTR SectionName = OperatingSystem->SystemPartition;
CHAR FileName[260];
PFILE FilePointer;
ULONG BytesRead;
CHAR SettingName[80];
// Find all the message box settings and run them
UiShowMessageBoxesInSection(OperatingSystemName);
UiShowMessageBoxesInSection(SectionName);
// Try to open the operating system section in the .ini file
if (!IniOpenSection(OperatingSystemName, &SectionId))
if (!IniOpenSection(SectionName, &SectionId))
{
sprintf(SettingName, "Section [%s] not found in freeldr.ini.\n", OperatingSystemName);
sprintf(SettingName, "Section [%s] not found in freeldr.ini.\n", SectionName);
UiMessageBox(SettingName);
return;
}
@ -79,22 +82,25 @@ VOID LoadAndBootBootSector(PCSTR OperatingSystemName)
ChainLoadBiosBootSectorCode();
}
VOID LoadAndBootPartition(PCSTR OperatingSystemName)
VOID
LoadAndBootPartition(IN OperatingSystemItem* OperatingSystem,
IN USHORT OperatingSystemVersion)
{
ULONG_PTR SectionId;
PCSTR SectionName = OperatingSystem->SystemPartition;
CHAR SettingName[80];
CHAR SettingValue[80];
ULONG SectionId;
PARTITION_TABLE_ENTRY PartitionTableEntry;
UCHAR DriveNumber;
ULONG PartitionNumber;
// Find all the message box settings and run them
UiShowMessageBoxesInSection(OperatingSystemName);
UiShowMessageBoxesInSection(SectionName);
// Try to open the operating system section in the .ini file
if (!IniOpenSection(OperatingSystemName, &SectionId))
if (!IniOpenSection(SectionName, &SectionId))
{
sprintf(SettingName, "Section [%s] not found in freeldr.ini.\n", OperatingSystemName);
sprintf(SettingName, "Section [%s] not found in freeldr.ini.\n", SectionName);
UiMessageBox(SettingName);
return;
}
@ -151,20 +157,23 @@ VOID LoadAndBootPartition(PCSTR OperatingSystemName)
ChainLoadBiosBootSectorCode();
}
VOID LoadAndBootDrive(PCSTR OperatingSystemName)
VOID
LoadAndBootDrive(IN OperatingSystemItem* OperatingSystem,
IN USHORT OperatingSystemVersion)
{
ULONG_PTR SectionId;
PCSTR SectionName = OperatingSystem->SystemPartition;
CHAR SettingName[80];
CHAR SettingValue[80];
ULONG SectionId;
UCHAR DriveNumber;
// Find all the message box settings and run them
UiShowMessageBoxesInSection(OperatingSystemName);
UiShowMessageBoxesInSection(SectionName);
// Try to open the operating system section in the .ini file
if (!IniOpenSection(OperatingSystemName, &SectionId))
if (!IniOpenSection(SectionName, &SectionId))
{
sprintf(SettingName, "Section [%s] not found in freeldr.ini.\n", OperatingSystemName);
sprintf(SettingName, "Section [%s] not found in freeldr.ini.\n", SectionName);
UiMessageBox(SettingName);
return;
}

View file

@ -24,7 +24,90 @@ ULONG reactos_disk_count = 0;
CHAR reactos_arc_hardware_data[HW_MAX_ARC_HEAP_SIZE] = {0};
CHAR reactos_arc_strings[32][256];
ULONG GetDefaultOperatingSystem(OperatingSystemItem* OperatingSystemList, ULONG OperatingSystemCount)
typedef
VOID
(*OS_LOADING_METHOD)(IN OperatingSystemItem* OperatingSystem,
IN USHORT OperatingSystemVersion);
struct
{
CHAR BootType[80];
USHORT OperatingSystemVersion;
OS_LOADING_METHOD Load;
} OSLoadingMethods[] =
{
#ifdef FREELDR_REACTOS_SETUP
{"ReactOSSetup", 0 , LoadReactOSSetup },
#endif
#ifdef _M_IX86
{"BootSector" , 0 , LoadAndBootBootSector},
{"Drive" , 0 , LoadAndBootDrive },
{"Partition" , 0 , LoadAndBootPartition },
{"Linux" , 0 , LoadAndBootLinux },
{"Windows" , 0 , LoadAndBootWindows },
{"WindowsNT40" , _WIN32_WINNT_NT4 , LoadAndBootWindows },
#endif
{"Windows2003" , _WIN32_WINNT_WS03, LoadAndBootWindows },
// {"Not found" , 0 , NULL }
};
VOID LoadOperatingSystem(IN OperatingSystemItem* OperatingSystem)
{
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 infere 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;
}
}
}
ULONG GetDefaultOperatingSystem(OperatingSystemItem* OperatingSystemList, ULONG OperatingSystemCount)
{
CHAR DefaultOSText[80];
PCSTR DefaultOSName;
@ -105,17 +188,14 @@ BOOLEAN MainBootMenuKeyPressFilter(ULONG KeyPress)
VOID RunLoader(VOID)
{
CHAR SettingValue[80];
CHAR BootType[80];
ULONG_PTR SectionId;
ULONG OperatingSystemCount;
OperatingSystemItem* OperatingSystemList;
PCSTR *OperatingSystemDisplayNames;
PCSTR SectionName;
ULONG i;
PCSTR* OperatingSystemDisplayNames;
ULONG DefaultOperatingSystem;
LONG TimeOut;
ULONG SelectedOperatingSystem;
ULONG i;
// FIXME: if possible, only detect and register ARC devices...
if (!MachHwDetect())
@ -206,78 +286,8 @@ VOID RunLoader(VOID)
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);
#endif
// Load the chosen operating system
LoadOperatingSystem(&OperatingSystemList[SelectedOperatingSystem]);
}
reboot:

View file

@ -19,6 +19,12 @@
#pragma once
VOID LoadAndBootBootSector(PCSTR OperatingSystemName);
VOID LoadAndBootPartition(PCSTR OperatingSystemName);
VOID LoadAndBootDrive(PCSTR OperatingSystemName);
VOID
LoadAndBootBootSector(IN OperatingSystemItem* OperatingSystem,
IN USHORT OperatingSystemVersion);
VOID
LoadAndBootPartition(IN OperatingSystemItem* OperatingSystem,
IN USHORT OperatingSystemVersion);
VOID
LoadAndBootDrive(IN OperatingSystemItem* OperatingSystem,
IN USHORT OperatingSystemVersion);

View file

@ -18,6 +18,7 @@
*/
#include <fs.h>
#include <oslist.h>
#ifndef __LINUX_H
#define __LINUX_H
@ -129,7 +130,9 @@ typedef struct
VOID BootNewLinuxKernel(VOID); // Implemented in linux.S
VOID BootOldLinuxKernel(ULONG KernelSize); // Implemented in linux.S
VOID LoadAndBootLinux(PCSTR OperatingSystemName, PCSTR Description);
VOID
LoadAndBootLinux(IN OperatingSystemItem* OperatingSystem,
IN USHORT OperatingSystemVersion);
BOOLEAN LinuxParseIniSection(PCSTR OperatingSystemName);
BOOLEAN LinuxReadBootSector(PFILE LinuxKernelFile);

View file

@ -80,9 +80,8 @@ extern PLOADER_SYSTEM_BLOCK WinLdrSystemBlock;
// ReactOS Loading Functions
//
///////////////////////////////////////////////////////////////////////////////////////
VOID LoadAndBootWindows(PCSTR OperatingSystemName,
PSTR SettingsValue,
USHORT OperatingSystemVersion);
VOID LoadAndBootWindows(IN OperatingSystemItem* OperatingSystem,
IN USHORT OperatingSystemVersion);
// conversion.c
PVOID VaToPa(PVOID Va);
@ -179,7 +178,9 @@ LoadAndBootWindowsCommon(
LPCSTR BootPath,
BOOLEAN Setup);
VOID LoadReactOSSetup(VOID);
VOID
LoadReactOSSetup(IN OperatingSystemItem* OperatingSystem,
IN USHORT OperatingSystemVersion);
VOID
WinLdrSetupMachineDependent(PLOADER_PARAMETER_BLOCK LoaderBlock);

View file

@ -72,8 +72,12 @@ BOOLEAN RemoveQuotes(PCHAR QuotedString)
return TRUE;
}
VOID LoadAndBootLinux(PCSTR OperatingSystemName, PCSTR Description)
VOID
LoadAndBootLinux(IN OperatingSystemItem* OperatingSystem,
IN USHORT OperatingSystemVersion)
{
PCSTR SectionName = OperatingSystem->SystemPartition;
PCSTR Description = OperatingSystem->LoadIdentifier;
PFILE LinuxKernel = 0;
PFILE LinuxInitrdFile = 0;
CHAR TempString[260];
@ -93,7 +97,7 @@ VOID LoadAndBootLinux(PCSTR OperatingSystemName, PCSTR Description)
UiDrawProgressBarCenter(0, 100, LinuxBootDescription);
// Parse the .ini file section
if (!LinuxParseIniSection(OperatingSystemName))
if (!LinuxParseIniSection(SectionName))
{
goto LinuxBootFailed;
}
@ -235,18 +239,18 @@ LinuxBootFailed:
LinuxCommandLineSize = 0;
}
BOOLEAN LinuxParseIniSection(PCSTR OperatingSystemName)
BOOLEAN LinuxParseIniSection(PCSTR SectionName)
{
CHAR SettingName[260];
ULONG SectionId;
ULONG_PTR SectionId;
CHAR SettingName[260];
// Find all the message box settings and run them
UiShowMessageBoxesInSection(OperatingSystemName);
UiShowMessageBoxesInSection(SectionName);
// Try to open the operating system section in the .ini file
if (!IniOpenSection(OperatingSystemName, &SectionId))
if (!IniOpenSection(SectionName, &SectionId))
{
sprintf(SettingName, "Section [%s] not found in freeldr.ini.\n", OperatingSystemName);
sprintf(SettingName, "Section [%s] not found in freeldr.ini.\n", SectionName);
UiMessageBox(SettingName);
return FALSE;
}

View file

@ -133,7 +133,9 @@ SetupLdrScanBootDrivers(PLIST_ENTRY BootDriverListHead, HINF InfHandle, LPCSTR S
} while (InfFindNextLine(&InfContext, &InfContext));
}
VOID LoadReactOSSetup(VOID)
VOID
LoadReactOSSetup(IN OperatingSystemItem* OperatingSystem,
IN USHORT OperatingSystemVersion)
{
CHAR FileName[512];
CHAR BootPath[512];

View file

@ -456,22 +456,28 @@ LoadModule(
}
VOID
LoadAndBootWindows(PCSTR OperatingSystemName,
PSTR SettingsValue,
USHORT OperatingSystemVersion)
LoadAndBootWindows(IN OperatingSystemItem* OperatingSystem,
IN USHORT OperatingSystemVersion)
{
ULONG_PTR SectionId;
PCSTR SectionName = OperatingSystem->SystemPartition;
CHAR SettingsValue[80];
BOOLEAN HasSection;
char BootPath[MAX_PATH];
CHAR BootPath[MAX_PATH];
CHAR FileName[MAX_PATH];
CHAR BootOptions[256];
PCHAR File;
BOOLEAN Status;
ULONG_PTR SectionId;
PLOADER_PARAMETER_BLOCK LoaderBlock;
// Get OS setting value
SettingsValue[0] = ANSI_NULL;
IniOpenSection("Operating Systems", &SectionId);
IniReadSettingByName(SectionId, SectionName, SettingsValue, sizeof(SettingsValue));
// Open the operating system section
// specified in the .ini file
HasSection = IniOpenSection(OperatingSystemName, &SectionId);
HasSection = IniOpenSection(SectionName, &SectionId);
UiDrawBackdrop();
UiDrawProgressBarCenter(1, 100, "Loading NT...");
@ -480,7 +486,7 @@ LoadAndBootWindows(PCSTR OperatingSystemName,
if (!HasSection ||
!IniReadSettingByName(SectionId, "SystemPath", BootPath, sizeof(BootPath)))
{
strcpy(BootPath, OperatingSystemName);
strcpy(BootPath, SectionName);
}
/* Special case for LiveCD */
@ -499,7 +505,7 @@ LoadAndBootWindows(PCSTR OperatingSystemName,
if (!HasSection || !IniReadSettingByName(SectionId, "Options", BootOptions, sizeof(BootOptions)))
{
/* Get options after the title */
const CHAR*p = SettingsValue;
PCSTR p = SettingsValue;
while (*p == ' ' || *p == '"')
p++;
while (*p != '\0' && *p != '"')