https://git.reactos.org/?p=reactos.git;a=commitdiff;h=81943afb7b3603de981fa…
commit 81943afb7b3603de981fae80e994c8d8f29041df
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Fri Feb 18 04:38:52 2022 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Fri Feb 18 20:24:51 2022 +0100
[FREELDR:NTLDR] Slightly rework how KD transport DLLs are loaded.
A Kernel Debugger Transport DLL is always loaded for Windows XP+ :
either the standard KDCOM.DLL (by default), or an alternative
user-provided one via the /DEBUGPORT= option. If this alternative
does not exist or fails to be loaded, fall back to the standard
KDCOM.DLL.
If no KD dll is loaded, kernel loading would fail because of the
resulting unsatisfied KDCOM dll import (tested on Windows and ReactOS).
+ Normalize kernel, HAL and KD dll file names to lowercase (needed for
case-sensitive installations).
---
boot/freeldr/freeldr/ntldr/winldr.c | 78 +++++++++++++++++++++++++------------
1 file changed, 53 insertions(+), 25 deletions(-)
diff --git a/boot/freeldr/freeldr/ntldr/winldr.c b/boot/freeldr/freeldr/ntldr/winldr.c
index 3e7abaa51f4..317d59a35bd 100644
--- a/boot/freeldr/freeldr/ntldr/winldr.c
+++ b/boot/freeldr/freeldr/ntldr/winldr.c
@@ -575,7 +575,7 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion,
/* Retrieve the HAL file name */
Option += 4; OptionLength -= 4;
RtlStringCbCopyNA(HalFileName, sizeof(HalFileName), Option, OptionLength);
- _strupr(HalFileName);
+ _strlwr(HalFileName);
}
Option = NtLdrGetOptionEx(BootOptions, "KERNEL=", &OptionLength);
@@ -584,7 +584,7 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion,
/* Retrieve the KERNEL file name */
Option += 7; OptionLength -= 7;
RtlStringCbCopyNA(KernelFileName, sizeof(KernelFileName), Option, OptionLength);
- _strupr(KernelFileName);
+ _strlwr(KernelFileName);
}
TRACE("HAL file = '%s' ; Kernel file = '%s'\n",
HalFileName, KernelFileName);
@@ -633,50 +633,78 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion,
* the name "kdcom.dll". [...]"
*/
+ /*
+ * A Kernel Debugger Transport DLL is always loaded for Windows XP+ :
+ * either the standard KDCOM.DLL (by default): IsCustomKdDll == FALSE
+ * or an alternative user-provided one via the /DEBUGPORT= option:
+ * IsCustomKdDll == TRUE if it does not specify the default KDCOM.
+ */
+ BOOLEAN IsCustomKdDll = FALSE;
+
/* Check whether there is a DEBUGPORT option */
Option = NtLdrGetOptionEx(BootOptions, "DEBUGPORT=",
&OptionLength);
if (Option && (OptionLength > 10))
{
/* Move to the debug port name */
Option += 10; OptionLength -= 10;
- ASSERT(OptionLength > 0);
/*
* Parse the port name.
- * Format: /DEBUGPORT=COM[1-9]
+ * Format: /DEBUGPORT=COM[0-9]
* or: /DEBUGPORT=FILE:\Device\HarddiskX\PartitionY\debug.log
* or: /DEBUGPORT=FOO
* If we only have /DEBUGPORT= (i.e. without any port name),
- * defaults it to "COM".
+ * default to "COM".
*/
- RtlStringCbCopyA(KdDllName, sizeof(KdDllName), "KD");
- if (_strnicmp(Option, "COM", 3) == 0 && '0' <=
Option[3] && Option[3] <= '9')
+
+ /* Get the actual length of the debug port
+ * until the next whitespace or colon. */
+ OptionLength = (ULONG)strcspn(Option, " \t:");
+
+ if ((OptionLength == 0) ||
+ ( (OptionLength >= 3) && (_strnicmp(Option, "COM",
3) == 0) &&
+ ((OptionLength == 3) || ('0' <= Option[3] &&
Option[3] <= '9')) ))
{
- RtlStringCbCatNA(KdDllName, sizeof(KdDllName), Option, 3);
+ /* The standard KDCOM.DLL is used */
}
else
{
- /* Get the actual length of the debug port
- * until the next whitespace or colon. */
- OptionLength = (ULONG)strcspn(Option, " \t:");
- if (OptionLength == 0)
- RtlStringCbCatA(KdDllName, sizeof(KdDllName), "COM");
- else
- RtlStringCbCatNA(KdDllName, sizeof(KdDllName), Option,
OptionLength);
+ /* A custom KD DLL is used */
+ IsCustomKdDll = TRUE;
}
- RtlStringCbCatA(KdDllName, sizeof(KdDllName), ".DLL");
- _strupr(KdDllName);
+ }
+ if (!IsCustomKdDll)
+ {
+ Option = "COM"; OptionLength = 3;
+ }
- /*
- * Load the transport DLL. Override the base DLL name of the
- * loaded transport DLL to the default "KDCOM.DLL" name.
- */
- KdDllBase = LoadModule(LoaderBlock, DirPath, KdDllName,
- "kdcom.dll", LoaderSystemCode,
&KdDllDTE, 60);
- if (!KdDllBase)
+ RtlStringCbPrintfA(KdDllName, sizeof(KdDllName), "kd%.*s.dll",
+ OptionLength, Option);
+ _strlwr(KdDllName);
+
+ /* Load the KD DLL. Override its base DLL name to the default
"KDCOM.DLL". */
+ KdDllBase = LoadModule(LoaderBlock, DirPath, KdDllName,
+ "kdcom.dll", LoaderSystemCode, &KdDllDTE,
60);
+ if (!KdDllBase)
+ {
+ /* If we failed to load a custom KD DLL, fall back to the standard one */
+ if (IsCustomKdDll)
{
- /* The transport DLL being optional, just ignore the failure */
+ /* The custom KD DLL being optional, just ignore the failure */
WARN("LoadModule('%s') failed\n", KdDllName);
+
+ IsCustomKdDll = FALSE;
+ RtlStringCbCopyA(KdDllName, sizeof(KdDllName), "kdcom.dll");
+
+ KdDllBase = LoadModule(LoaderBlock, DirPath, KdDllName,
+ "kdcom.dll", LoaderSystemCode,
&KdDllDTE, 60);
+ }
+
+ if (!KdDllBase)
+ {
+ /* Ignore the failure; we will fail later when scanning the
+ * kernel import tables, if it really needs the KD DLL. */
+ ERR("LoadModule('%s') failed\n", KdDllName);
}
}
}