diff --git a/reactos/boot/freeldr/freeldr/ntldr/winldr.c b/reactos/boot/freeldr/freeldr/ntldr/winldr.c index a49a687eff5..3ecda6be923 100644 --- a/reactos/boot/freeldr/freeldr/ntldr/winldr.c +++ b/reactos/boot/freeldr/freeldr/ntldr/winldr.c @@ -96,7 +96,7 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock, /* Construct SystemRoot and ArcBoot from SystemPath */ PathSeparator = strstr(BootPath, "\\") - BootPath; strncpy(ArcBoot, BootPath, PathSeparator); - ArcBoot[PathSeparator] = 0; + ArcBoot[PathSeparator] = ANSI_NULL; TRACE("ArcBoot: %s\n", ArcBoot); TRACE("SystemRoot: %s\n", SystemRoot); @@ -249,7 +249,7 @@ WinLdrLoadDeviceDriver(PLIST_ENTRY LoadOrderListHead, { // There is no directory in the path strcpy(DllName, DriverPath); - DriverPath[0] = 0; + DriverPath[0] = ANSI_NULL; } TRACE("DriverPath: %s, DllName: %s, LPB\n", DriverPath, DllName); @@ -426,13 +426,13 @@ WinLdrDetectVersion(VOID) static BOOLEAN LoadModule( - PLOADER_PARAMETER_BLOCK LoaderBlock, - PCCH Path, - PCCH File, - TYPE_OF_MEMORY MemoryType, - PLDR_DATA_TABLE_ENTRY *Dte, - BOOLEAN IsKdTransportDll, - ULONG Percentage) + IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, + IN PCCH Path, + IN PCCH File, + IN PCCH ImportName, // BaseDllName + IN TYPE_OF_MEMORY MemoryType, + OUT PLDR_DATA_TABLE_ENTRY *Dte, + IN ULONG Percentage) { BOOLEAN Success; CHAR FullFileName[MAX_PATH]; @@ -444,7 +444,6 @@ LoadModule( UiDrawProgressBarCenter(Percentage, 100, ProgressString); strcpy(FullFileName, Path); - strcat(FullFileName, "SYSTEM32\\"); strcat(FullFileName, File); Success = WinLdrLoadImage(FullFileName, MemoryType, &BaseAddress); @@ -455,15 +454,13 @@ LoadModule( } TRACE("%s loaded successfully at %p\n", File, BaseAddress); - strcpy(FullFileName, "WINDOWS\\SYSTEM32\\"); - strcat(FullFileName, File); /* * Cheat about the base DLL name if we are loading * the Kernel Debugger Transport DLL, to make the * PE loader happy. */ Success = WinLdrAllocateDataTableEntry(&LoaderBlock->LoadOrderListHead, - (IsKdTransportDll ? "KDCOM.DLL" : File), + ImportName, FullFileName, BaseAddress, Dte); @@ -475,22 +472,82 @@ static BOOLEAN LoadWindowsCore(IN USHORT OperatingSystemVersion, IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock, - IN LPCSTR BootOptions, - IN LPCSTR BootPath, + IN PCSTR BootOptions, + IN PCSTR BootPath, IN OUT PLDR_DATA_TABLE_ENTRY* KernelDTE) { BOOLEAN Success; + PCSTR Options; CHAR DirPath[MAX_PATH]; + CHAR KernelFileName[MAX_PATH]; + CHAR HalFileName[MAX_PATH]; CHAR KdTransportDllName[MAX_PATH]; PLDR_DATA_TABLE_ENTRY HalDTE, KdComDTE = NULL; if (!KernelDTE) return FALSE; + /* Initialize SystemRoot\System32 path */ + strcpy(DirPath, BootPath); + strcat(DirPath, "SYSTEM32\\"); + + // + // TODO: Parse also the separate INI values "Kernel=" and "Hal=" + // + + /* Default KERNEL and HAL file names */ + strcpy(KernelFileName, "NTOSKRNL.EXE"); + strcpy(HalFileName , "HAL.DLL"); + + /* Find any /KERNEL= or /HAL= switch in the boot options */ + Options = BootOptions; + while (Options) + { + /* Skip possible initial whitespace */ + Options += strspn(Options, " \t"); + + /* Check whether a new commutator starts and it is either KERNEL or HAL */ + if (*Options != '/' || (++Options, + !(_strnicmp(Options, "KERNEL=", 7) == 0 || + _strnicmp(Options, "HAL=", 4) == 0)) ) + { + /* Search for another whitespace */ + Options = strpbrk(Options, " \t"); + continue; + } + else + { + size_t i = strcspn(Options, " \t"); /* Skip whitespace */ + if (i == 0) + { + /* Use the default values */ + break; + } + + /* We have found either KERNEL or HAL commutator */ + if (_strnicmp(Options, "KERNEL=", 7) == 0) + { + Options += 7; i -= 7; + strncpy(KernelFileName, Options, i); + KernelFileName[i] = ANSI_NULL; + _strupr(KernelFileName); + } + else if (_strnicmp(Options, "HAL=", 4) == 0) + { + Options += 4; i -= 4; + strncpy(HalFileName, Options, i); + HalFileName[i] = ANSI_NULL; + _strupr(HalFileName); + } + } + } + + TRACE("Kernel file = '%s' ; HAL file = '%s'\n", KernelFileName, HalFileName); + /* Load the Kernel */ - LoadModule(LoaderBlock, BootPath, "NTOSKRNL.EXE", LoaderSystemCode, KernelDTE, FALSE, 30); + LoadModule(LoaderBlock, DirPath, KernelFileName, "NTOSKRNL.EXE", LoaderSystemCode, KernelDTE, 30); /* Load the HAL */ - LoadModule(LoaderBlock, BootPath, "HAL.DLL", LoaderHalCode, &HalDTE, FALSE, 45); + LoadModule(LoaderBlock, DirPath, HalFileName, "HAL.DLL", LoaderHalCode, &HalDTE, 45); /* Load the Kernel Debugger Transport DLL */ if (OperatingSystemVersion > _WIN32_WINNT_WIN2K) @@ -525,27 +582,28 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion, * "...foo /DEBUGPORT= bar..." * (in that case, we default the port to COM). */ - while (BootOptions) + Options = BootOptions; + while (Options) { /* Skip possible initial whitespace */ - BootOptions += strspn(BootOptions, " \t"); + Options += strspn(Options, " \t"); /* Check whether a new commutator starts and it is the DEBUGPORT one */ - if (*BootOptions != '/' || _strnicmp(++BootOptions, "DEBUGPORT=", 10) != 0) + if (*Options != '/' || _strnicmp(++Options, "DEBUGPORT=", 10) != 0) { /* Search for another whitespace */ - BootOptions = strpbrk(BootOptions, " \t"); + Options = strpbrk(Options, " \t"); continue; } else { /* We found the DEBUGPORT commutator. Move to the port name. */ - BootOptions += 10; + Options += 10; break; } } - if (BootOptions) + if (Options) { /* * We have found the DEBUGPORT commutator. Parse the port name. @@ -553,33 +611,30 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion, * If we only have /DEBUGPORT= (i.e. without any port name), defaults it to "COM". */ strcpy(KdTransportDllName, "KD"); - if (_strnicmp(BootOptions, "COM", 3) == 0 && '0' <= BootOptions[3] && BootOptions[3] <= '9') + if (_strnicmp(Options, "COM", 3) == 0 && '0' <= Options[3] && Options[3] <= '9') { - strncat(KdTransportDllName, BootOptions, 3); + strncat(KdTransportDllName, Options, 3); } else { - size_t i = strcspn(BootOptions, " \t:"); /* Skip valid separators: whitespace or colon */ + size_t i = strcspn(Options, " \t:"); /* Skip valid separators: whitespace or colon */ if (i == 0) strcat(KdTransportDllName, "COM"); else - strncat(KdTransportDllName, BootOptions, i); + strncat(KdTransportDllName, Options, i); } strcat(KdTransportDllName, ".DLL"); _strupr(KdTransportDllName); /* - * Load the transport DLL. Specify it to LoadModule so that it can - * change the base DLL name of the loaded transport DLL to the default - * "KDCOM.DLL" name, to make the PE loader happy. + * Load the transport DLL. Override the base DLL name of the + * loaded transport DLL to the default "KDCOM.DLL" name. */ - LoadModule(LoaderBlock, BootPath, KdTransportDllName, LoaderSystemCode, &KdComDTE, TRUE, 60); + LoadModule(LoaderBlock, DirPath, KdTransportDllName, "KDCOM.DLL", LoaderSystemCode, &KdComDTE, 60); } } /* Load all referenced DLLs for Kernel, HAL and Kernel Debugger Transport DLL */ - strcpy(DirPath, BootPath); - strcat(DirPath, "system32\\"); Success = WinLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath, *KernelDTE); Success &= WinLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath, HalDTE); if (KdComDTE) @@ -691,7 +746,7 @@ LoadAndBootWindows(IN OperatingSystemItem* OperatingSystem, /* Allocate and minimalist-initialize LPB */ AllocateAndInitLPB(&LoaderBlock); - /* Load Hive */ + /* Load the system hive */ UiDrawBackdrop(); UiDrawProgressBarCenter(15, 100, "Loading system hive..."); Success = WinLdrInitSystemHive(LoaderBlock, BootPath);