Author: hpoussin Date: Sat Oct 31 16:09:03 2009 New Revision: 43875
URL: http://svn.reactos.org/svn/reactos?rev=43875&view=rev Log: [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
Modified: trunk/reactos/boot/freeldr/freeldr/bootmgr.c trunk/reactos/boot/freeldr/freeldr/include/winldr.h trunk/reactos/boot/freeldr/freeldr/oslist.c trunk/reactos/boot/freeldr/freeldr/windows/winldr.c trunk/reactos/boot/freeldr/freeldr/windows/wlregistry.c
Modified: trunk/reactos/boot/freeldr/freeldr/bootmgr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/bootmg... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/bootmgr.c [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/bootmgr.c [iso-8859-1] Sat Oct 31 16:09:03 2009 @@ -22,6 +22,7 @@ VOID RunLoader(VOID) { CHAR SettingValue[80]; + CHAR BootType[80]; ULONG_PTR SectionId; ULONG OperatingSystemCount; PCSTR *OperatingSystemSectionNames; @@ -98,53 +99,49 @@ if (IniOpenSection(SectionName, &SectionId)) { // Try to read the boot type - IniReadSettingByName(SectionId, "BootType", SettingValue, sizeof(SettingValue)); - } - - if (SettingValue[0] == ANSI_NULL && SectionName[0] != ANSI_NULL) + 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 __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 @@ #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); }
Modified: trunk/reactos/boot/freeldr/freeldr/include/winldr.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/includ... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/include/winldr.h [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/include/winldr.h [iso-8859-1] Sat Oct 31 16:09:03 2009 @@ -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 @@ 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 */
Modified: trunk/reactos/boot/freeldr/freeldr/oslist.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/oslist... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/oslist.c [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/oslist.c [iso-8859-1] Sat Oct 31 16:09:03 2009 @@ -169,29 +169,28 @@ 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); - } + // + // Go up to next " + // + while (*p != '"' && *p != ANSI_NULL) + p++; + *p = ANSI_NULL;
- if (TempString[strlen(TempString)-1] == '"') - { - TempString[strlen(TempString)-1] = '\0'; - } - + // + // Copy result + // + strcpy(TempString, Start); strcpy(QuotedString, TempString);
return TRUE;
Modified: trunk/reactos/boot/freeldr/freeldr/windows/winldr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/window... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/windows/winldr.c [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/windows/winldr.c [iso-8859-1] Sat Oct 31 16:09:03 2009 @@ -383,11 +383,34 @@ }
+USHORT +WinLdrDetectVersion() +{ + 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, USHORT OperatingSystemVersion) -{ - CHAR MsgBuffer[256]; - CHAR FullPath[MAX_PATH], SystemRoot[MAX_PATH], BootPath[MAX_PATH]; +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 @@ 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))) - { - UiMessageBox("System path not specified for selected operating system."); - return; + /* Read the system path is set in the .ini file */ + if (!HasSection || !IniReadSettingByName(SectionId, "SystemPath", FullPath, sizeof(FullPath))) + { + strcpy(FullPath, OperatingSystemName); }
/* Special case for LiveCD */ @@ -440,10 +454,16 @@ strcat(SystemRoot, "\");
/* Read booting options */ - if (!IniReadSettingByName(SectionId, "Options", BootOptions, sizeof(BootOptions))) - { - /* Nothing read, make the string empty */ - strcpy(BootOptions, ""); + if (!HasSection || !IniReadSettingByName(SectionId, "Options", BootOptions, sizeof(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); }
// @@ -485,6 +505,13 @@ /* Detect hardware */ 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); @@ -526,9 +553,9 @@ 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);
Modified: trunk/reactos/boot/freeldr/freeldr/windows/wlregistry.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/window... ============================================================================== --- trunk/reactos/boot/freeldr/freeldr/windows/wlregistry.c [iso-8859-1] (original) +++ trunk/reactos/boot/freeldr/freeldr/windows/wlregistry.c [iso-8859-1] Sat Oct 31 16:09:03 2009 @@ -124,42 +124,51 @@ 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]; + BOOLEAN Status; + + // There is a simple logic here: try to load usual hive (system), if it + // fails, then give system.alt a try, and finally try a system.sav + + // FIXME: For now we only try system + strcpy(SearchPath, DirectoryPath); + strcat(SearchPath, "SYSTEM32\CONFIG\"); + Status = WinLdrLoadSystemHive(LoaderBlock, SearchPath, "SYSTEM"); + + // Fail if failed... + if (!Status) + return FALSE; + + // Initialize in-memory registry + RegInitializeRegistry(); + + // Import what was loaded + Status = RegImportBinaryHive((PCHAR)VaToPa(LoaderBlock->RegistryBase), LoaderBlock->RegistryLength); + if (!Status) + { + UiMessageBox("Importing binary hive failed!"); + return FALSE; + } + + // Initialize the 'CurrentControlSet' link + if (RegInitCurrentControlSet(FALSE) != ERROR_SUCCESS) + { + UiMessageBox("Initializing CurrentControlSet link failed!"); + 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; - - // There is a simple logic here: try to load usual hive (system), if it - // fails, then give system.alt a try, and finally try a system.sav - - // FIXME: For now we only try system - strcpy(SearchPath, DirectoryPath); - strcat(SearchPath, "SYSTEM32\CONFIG\"); - Status = WinLdrLoadSystemHive(LoaderBlock, SearchPath, "SYSTEM"); - - // Fail if failed... - if (!Status) - return FALSE; - - // Initialize in-memory registry - RegInitializeRegistry(); - - // Import what was loaded - Status = RegImportBinaryHive((PCHAR)VaToPa(LoaderBlock->RegistryBase), LoaderBlock->RegistryLength); - if (!Status) - { - UiMessageBox("Importing binary hive failed!"); - return FALSE; - } - - // Initialize the 'CurrentControlSet' link - if (RegInitCurrentControlSet(FALSE) != ERROR_SUCCESS) - { - UiMessageBox("Initializing CurrentControlSet link failed!"); - return FALSE; - }
// Scan registry and prepare boot drivers list WinLdrScanRegistry(LoaderBlock, DirectoryPath);