diff --git a/reactos/boot/freeldr/freeldr/bootmgr.c b/reactos/boot/freeldr/freeldr/bootmgr.c index 56a0e610645..9f0bd324bff 100644 --- a/reactos/boot/freeldr/freeldr/bootmgr.c +++ b/reactos/boot/freeldr/freeldr/bootmgr.c @@ -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); } diff --git a/reactos/boot/freeldr/freeldr/include/winldr.h b/reactos/boot/freeldr/freeldr/include/winldr.h index 883d51232a8..8fc5ef8ee3d 100644 --- a/reactos/boot/freeldr/freeldr/include/winldr.h +++ b/reactos/boot/freeldr/freeldr/include/winldr.h @@ -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 */ diff --git a/reactos/boot/freeldr/freeldr/oslist.c b/reactos/boot/freeldr/freeldr/oslist.c index d21a17531d6..d10debd817b 100644 --- a/reactos/boot/freeldr/freeldr/oslist.c +++ b/reactos/boot/freeldr/freeldr/oslist.c @@ -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; diff --git a/reactos/boot/freeldr/freeldr/windows/winldr.c b/reactos/boot/freeldr/freeldr/windows/winldr.c index 9bda7c4dde7..c1c5b15a68d 100644 --- a/reactos/boot/freeldr/freeldr/windows/winldr.c +++ b/reactos/boot/freeldr/freeldr/windows/winldr.c @@ -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); diff --git a/reactos/boot/freeldr/freeldr/windows/wlregistry.c b/reactos/boot/freeldr/freeldr/windows/wlregistry.c index d64f76ddda3..1080ee2cd06 100644 --- a/reactos/boot/freeldr/freeldr/windows/wlregistry.c +++ b/reactos/boot/freeldr/freeldr/windows/wlregistry.c @@ -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);