[freeldr/WINLDR] Simplify freeldr.ini syntax for common cases

- If boot type is not specified, autodetect bootsector and Windows types
- Try to automatically detect version of loaded Windows
- Accept boot options after name of OS
- Separate loading and scanning of system hive
As a result, lines like "multi(0)disk(0)rdisk(0)partition(1)\WINNT="Windows NT4" /DEBUG /BREAK" work

svn path=/trunk/; revision=43875
This commit is contained in:
Hervé Poussineau 2009-10-31 15:09:03 +00:00
parent e65de6eda6
commit 370e856450
5 changed files with 113 additions and 72 deletions

View file

@ -22,6 +22,7 @@
VOID RunLoader(VOID)
{
CHAR SettingValue[80];
CHAR BootType[80];
ULONG_PTR SectionId;
ULONG OperatingSystemCount;
PCSTR *OperatingSystemSectionNames;
@ -98,53 +99,49 @@ VOID RunLoader(VOID)
if (IniOpenSection(SectionName, &SectionId))
{
// Try to read the boot type
IniReadSettingByName(SectionId, "BootType", SettingValue, sizeof(SettingValue));
IniReadSettingByName(SectionId, "BootType", BootType, sizeof(BootType));
}
else
BootType[0] = ANSI_NULL;
if (SettingValue[0] == ANSI_NULL && SectionName[0] != ANSI_NULL)
if (BootType[0] == ANSI_NULL && SectionName[0] != ANSI_NULL)
{
// Try to infere boot type value
#ifdef __i386__
CHAR LastChar;
LastChar = SectionName[strlen(SectionName) - 1];
if (LastChar == '\\' ||
(strstr(SectionName, ")partition(") != NULL &&
strstr(SectionName, ")partition(0)") == NULL))
ULONG FileId;
if (ArcOpen((CHAR*)SectionName, OpenReadOnly, &FileId) == ESUCCESS)
{
strcpy(SettingValue, "Partition");
}
else if (LastChar == ')' || LastChar == ':')
{
strcpy(SettingValue, "Drive");
}
else if (TRUE)
{
strcpy(SettingValue, "BootSector");
ArcClose(FileId);
strcpy(BootType, "BootSector");
}
else
#endif
{
strcpy(SettingValue, "Windows2003");
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
#ifdef __i386__
DriveMapMapDrivesInSection(SectionName);
#endif
if (_stricmp(SettingValue, "ReactOS") == 0)
if (_stricmp(BootType, "ReactOS") == 0)
{
LoadAndBootReactOS(SectionName);
}
#ifdef FREELDR_REACTOS_SETUP
else if (_stricmp(SettingValue, "ReactOSSetup") == 0)
else if (_stricmp(BootType, "ReactOSSetup") == 0)
{
// In future we could pass the selected OS details through this
// to have different install methods, etc.
LoadReactOSSetup();
}
#ifdef __i386__
else if (_stricmp(SettingValue, "ReactOSSetup2") == 0)
else if (_stricmp(BootType, "ReactOSSetup2") == 0)
{
// WinLdr-style boot
LoadReactOSSetup2();
@ -152,27 +149,31 @@ VOID RunLoader(VOID)
#endif
#endif
#ifdef __i386__
else if (_stricmp(BootType, "Windows") == 0)
{
LoadAndBootWindows(SectionName, SettingValue, 0);
}
else if (_stricmp(SettingValue, "WindowsNT40") == 0)
{
LoadAndBootWindows(SectionName, _WIN32_WINNT_NT4);
LoadAndBootWindows(BootType, SettingValue, _WIN32_WINNT_NT4);
}
else if (_stricmp(SettingValue, "Windows2003") == 0)
{
LoadAndBootWindows(SectionName, _WIN32_WINNT_WS03);
LoadAndBootWindows(BootType, SettingValue, _WIN32_WINNT_WS03);
}
else if (_stricmp(SettingValue, "Linux") == 0)
{
LoadAndBootLinux(SectionName, OperatingSystemDisplayNames[SelectedOperatingSystem]);
LoadAndBootLinux(BootType, OperatingSystemDisplayNames[SelectedOperatingSystem]);
}
else if (_stricmp(SettingValue, "BootSector") == 0)
{
LoadAndBootBootSector(SectionName);
}
else if (_stricmp(SettingValue, "Partition") == 0)
else if (_stricmp(BootType, "Partition") == 0)
{
LoadAndBootPartition(SectionName);
}
else if (_stricmp(SettingValue, "Drive") == 0)
else if (_stricmp(BootType, "Drive") == 0)
{
LoadAndBootDrive(SectionName);
}

View file

@ -27,7 +27,9 @@
// ReactOS Loading Functions
//
///////////////////////////////////////////////////////////////////////////////////////
VOID LoadAndBootWindows(PCSTR OperatingSystemName, USHORT OperatingSystemVersion);
VOID LoadAndBootWindows(PCSTR OperatingSystemName,
PSTR SettingsValue,
USHORT OperatingSystemVersion);
/* Entry-point to kernel */
typedef VOID (NTAPI *KERNEL_ENTRY_POINT) (PLOADER_PARAMETER_BLOCK LoaderBlock);
@ -77,8 +79,11 @@ WinLdrTurnOnPaging(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
PVOID GdtIdt);
// wlregistry.c
BOOLEAN WinLdrLoadAndScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
IN LPCSTR DirectoryPath);
BOOLEAN WinLdrInitSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
IN LPCSTR DirectoryPath);
BOOLEAN WinLdrScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
IN LPCSTR DirectoryPath);
/* FIXME: Should be moved to NDK, and respective ACPI header files */

View file

@ -169,29 +169,28 @@ AllocateListMemoryFailed:
BOOLEAN RemoveQuotes(PCHAR QuotedString)
{
CHAR TempString[200];
PCHAR p;
PSTR Start;
//
// If this string is not quoted then return FALSE
// Skip spaces up to "
//
if ((QuotedString[0] != '\"') && (QuotedString[strlen(QuotedString)-1] != '\"'))
{
return FALSE;
}
p = QuotedString;
while (*p == ' ' || *p == '"')
p++;
Start = p;
if (QuotedString[0] == '\"')
{
strcpy(TempString, (QuotedString + 1));
}
else
{
strcpy(TempString, QuotedString);
}
if (TempString[strlen(TempString)-1] == '\"')
{
TempString[strlen(TempString)-1] = '\0';
}
//
// Go up to next "
//
while (*p != '"' && *p != ANSI_NULL)
p++;
*p = ANSI_NULL;
//
// Copy result
//
strcpy(TempString, Start);
strcpy(QuotedString, TempString);
return TRUE;

View file

@ -383,11 +383,34 @@ PVOID WinLdrLoadModule(PCSTR ModuleName, ULONG *Size,
}
VOID
LoadAndBootWindows(PCSTR OperatingSystemName, USHORT OperatingSystemVersion)
USHORT
WinLdrDetectVersion()
{
CHAR MsgBuffer[256];
CHAR FullPath[MAX_PATH], SystemRoot[MAX_PATH], BootPath[MAX_PATH];
LONG rc;
FRLDRHKEY hKey;
rc = RegOpenKey(
NULL,
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server",
&hKey);
if (rc != ERROR_SUCCESS)
{
// Key doesn't exist; assume NT 4.0
return _WIN32_WINNT_NT4;
}
// We may here want to read the value of ProductVersion
return _WIN32_WINNT_WS03;
}
VOID
LoadAndBootWindows(PCSTR OperatingSystemName,
PSTR SettingsValue,
USHORT OperatingSystemVersion)
{
BOOLEAN HasSection;
char FullPath[MAX_PATH], SystemRoot[MAX_PATH], BootPath[MAX_PATH];
CHAR FileName[MAX_PATH];
CHAR BootOptions[256];
PCHAR File;
@ -403,27 +426,18 @@ LoadAndBootWindows(PCSTR OperatingSystemName, USHORT OperatingSystemVersion)
ULONG PcrBasePage=0;
ULONG TssBasePage=0;
//sprintf(MsgBuffer,"Booting Microsoft(R) Windows(R) OS version '%04x' is not implemented yet", OperatingSystemVersion);
//UiMessageBox(MsgBuffer);
// Open the operating system section
// specified in the .ini file
if (!IniOpenSection(OperatingSystemName, &SectionId))
{
sprintf(MsgBuffer,"Operating System section '%s' not found in freeldr.ini", OperatingSystemName);
UiMessageBox(MsgBuffer);
return;
}
HasSection = IniOpenSection(OperatingSystemName, &SectionId);
UiDrawBackdrop();
UiDrawStatusText("Detecting Hardware...");
UiDrawProgressBarCenter(1, 100, "Loading Windows...");
/* Make sure the system path is set in the .ini file */
if (!IniReadSettingByName(SectionId, "SystemPath", FullPath, sizeof(FullPath)))
/* Read the system path is set in the .ini file */
if (!HasSection || !IniReadSettingByName(SectionId, "SystemPath", FullPath, sizeof(FullPath)))
{
UiMessageBox("System path not specified for selected operating system.");
return;
strcpy(FullPath, OperatingSystemName);
}
/* Special case for LiveCD */
@ -440,10 +454,16 @@ LoadAndBootWindows(PCSTR OperatingSystemName, USHORT OperatingSystemVersion)
strcat(SystemRoot, "\\");
/* Read booting options */
if (!IniReadSettingByName(SectionId, "Options", BootOptions, sizeof(BootOptions)))
if (!HasSection || !IniReadSettingByName(SectionId, "Options", BootOptions, sizeof(BootOptions)))
{
/* Nothing read, make the string empty */
strcpy(BootOptions, "");
/* Get options after the title */
const CHAR*p = SettingsValue;
while (*p == ' ' || *p == '"')
p++;
while (*p != '\0' && *p != '"')
p++;
strcpy(BootOptions, p);
DPRINTM(DPRINT_WINDOWS,"BootOptions: '%s'\n", BootOptions);
}
//
@ -486,6 +506,13 @@ LoadAndBootWindows(PCSTR OperatingSystemName, USHORT OperatingSystemVersion)
UseRealHeap = TRUE;
LoaderBlock->ConfigurationRoot = MachHwDetect();
/* Load Hive */
Status = WinLdrInitSystemHive(LoaderBlock, BootPath);
DPRINTM(DPRINT_WINDOWS, "SYSTEM hive loaded with status %d\n", Status);
if (OperatingSystemVersion == 0)
OperatingSystemVersion = WinLdrDetectVersion();
/* Load kernel */
strcpy(FileName, BootPath);
strcat(FileName, "SYSTEM32\\NTOSKRNL.EXE");
@ -526,9 +553,9 @@ LoadAndBootWindows(PCSTR OperatingSystemName, USHORT OperatingSystemVersion)
if (KdComDTE)
WinLdrScanImportDescriptorTable(LoaderBlock, FileName, KdComDTE);
/* Load Hive, and then NLS data, OEM font, and prepare boot drivers list */
Status = WinLdrLoadAndScanSystemHive(LoaderBlock, BootPath);
DPRINTM(DPRINT_WINDOWS, "SYSTEM hive loaded and scanned with status %d\n", Status);
/* Load NLS data, OEM font, and prepare boot drivers list */
Status = WinLdrScanSystemHive(LoaderBlock, BootPath);
DPRINTM(DPRINT_WINDOWS, "SYSTEM hive scanned with status %d\n", Status);
/* Load boot drivers */
Status = WinLdrLoadBootDrivers(LoaderBlock, BootPath);

View file

@ -124,11 +124,10 @@ WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
return TRUE;
}
BOOLEAN WinLdrLoadAndScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
IN LPCSTR DirectoryPath)
BOOLEAN WinLdrInitSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
IN LPCSTR DirectoryPath)
{
CHAR SearchPath[1024];
CHAR AnsiName[256], OemName[256], LangName[256];
BOOLEAN Status;
// There is a simple logic here: try to load usual hive (system), if it
@ -161,6 +160,16 @@ BOOLEAN WinLdrLoadAndScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
return FALSE;
}
return TRUE;
}
BOOLEAN WinLdrScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
IN LPCSTR DirectoryPath)
{
CHAR SearchPath[1024];
CHAR AnsiName[256], OemName[256], LangName[256];
BOOLEAN Status;
// Scan registry and prepare boot drivers list
WinLdrScanRegistry(LoaderBlock, DirectoryPath);