mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 14:53:40 +00:00
[FREELDR/WINLDR]: Rework LoadModule() so that we can load custom kernels & hals via the /KERNEL= and /HAL= boot option switches.
svn path=/trunk/; revision=74725
This commit is contained in:
parent
c6fc31e430
commit
c1d754ee9f
1 changed files with 89 additions and 34 deletions
|
@ -96,7 +96,7 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||||
/* Construct SystemRoot and ArcBoot from SystemPath */
|
/* Construct SystemRoot and ArcBoot from SystemPath */
|
||||||
PathSeparator = strstr(BootPath, "\\") - BootPath;
|
PathSeparator = strstr(BootPath, "\\") - BootPath;
|
||||||
strncpy(ArcBoot, BootPath, PathSeparator);
|
strncpy(ArcBoot, BootPath, PathSeparator);
|
||||||
ArcBoot[PathSeparator] = 0;
|
ArcBoot[PathSeparator] = ANSI_NULL;
|
||||||
|
|
||||||
TRACE("ArcBoot: %s\n", ArcBoot);
|
TRACE("ArcBoot: %s\n", ArcBoot);
|
||||||
TRACE("SystemRoot: %s\n", SystemRoot);
|
TRACE("SystemRoot: %s\n", SystemRoot);
|
||||||
|
@ -249,7 +249,7 @@ WinLdrLoadDeviceDriver(PLIST_ENTRY LoadOrderListHead,
|
||||||
{
|
{
|
||||||
// There is no directory in the path
|
// There is no directory in the path
|
||||||
strcpy(DllName, DriverPath);
|
strcpy(DllName, DriverPath);
|
||||||
DriverPath[0] = 0;
|
DriverPath[0] = ANSI_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("DriverPath: %s, DllName: %s, LPB\n", DriverPath, DllName);
|
TRACE("DriverPath: %s, DllName: %s, LPB\n", DriverPath, DllName);
|
||||||
|
@ -426,13 +426,13 @@ WinLdrDetectVersion(VOID)
|
||||||
static
|
static
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
LoadModule(
|
LoadModule(
|
||||||
PLOADER_PARAMETER_BLOCK LoaderBlock,
|
IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||||
PCCH Path,
|
IN PCCH Path,
|
||||||
PCCH File,
|
IN PCCH File,
|
||||||
TYPE_OF_MEMORY MemoryType,
|
IN PCCH ImportName, // BaseDllName
|
||||||
PLDR_DATA_TABLE_ENTRY *Dte,
|
IN TYPE_OF_MEMORY MemoryType,
|
||||||
BOOLEAN IsKdTransportDll,
|
OUT PLDR_DATA_TABLE_ENTRY *Dte,
|
||||||
ULONG Percentage)
|
IN ULONG Percentage)
|
||||||
{
|
{
|
||||||
BOOLEAN Success;
|
BOOLEAN Success;
|
||||||
CHAR FullFileName[MAX_PATH];
|
CHAR FullFileName[MAX_PATH];
|
||||||
|
@ -444,7 +444,6 @@ LoadModule(
|
||||||
UiDrawProgressBarCenter(Percentage, 100, ProgressString);
|
UiDrawProgressBarCenter(Percentage, 100, ProgressString);
|
||||||
|
|
||||||
strcpy(FullFileName, Path);
|
strcpy(FullFileName, Path);
|
||||||
strcat(FullFileName, "SYSTEM32\\");
|
|
||||||
strcat(FullFileName, File);
|
strcat(FullFileName, File);
|
||||||
|
|
||||||
Success = WinLdrLoadImage(FullFileName, MemoryType, &BaseAddress);
|
Success = WinLdrLoadImage(FullFileName, MemoryType, &BaseAddress);
|
||||||
|
@ -455,15 +454,13 @@ LoadModule(
|
||||||
}
|
}
|
||||||
TRACE("%s loaded successfully at %p\n", File, BaseAddress);
|
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
|
* Cheat about the base DLL name if we are loading
|
||||||
* the Kernel Debugger Transport DLL, to make the
|
* the Kernel Debugger Transport DLL, to make the
|
||||||
* PE loader happy.
|
* PE loader happy.
|
||||||
*/
|
*/
|
||||||
Success = WinLdrAllocateDataTableEntry(&LoaderBlock->LoadOrderListHead,
|
Success = WinLdrAllocateDataTableEntry(&LoaderBlock->LoadOrderListHead,
|
||||||
(IsKdTransportDll ? "KDCOM.DLL" : File),
|
ImportName,
|
||||||
FullFileName,
|
FullFileName,
|
||||||
BaseAddress,
|
BaseAddress,
|
||||||
Dte);
|
Dte);
|
||||||
|
@ -475,22 +472,82 @@ static
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
LoadWindowsCore(IN USHORT OperatingSystemVersion,
|
LoadWindowsCore(IN USHORT OperatingSystemVersion,
|
||||||
IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||||||
IN LPCSTR BootOptions,
|
IN PCSTR BootOptions,
|
||||||
IN LPCSTR BootPath,
|
IN PCSTR BootPath,
|
||||||
IN OUT PLDR_DATA_TABLE_ENTRY* KernelDTE)
|
IN OUT PLDR_DATA_TABLE_ENTRY* KernelDTE)
|
||||||
{
|
{
|
||||||
BOOLEAN Success;
|
BOOLEAN Success;
|
||||||
|
PCSTR Options;
|
||||||
CHAR DirPath[MAX_PATH];
|
CHAR DirPath[MAX_PATH];
|
||||||
|
CHAR KernelFileName[MAX_PATH];
|
||||||
|
CHAR HalFileName[MAX_PATH];
|
||||||
CHAR KdTransportDllName[MAX_PATH];
|
CHAR KdTransportDllName[MAX_PATH];
|
||||||
PLDR_DATA_TABLE_ENTRY HalDTE, KdComDTE = NULL;
|
PLDR_DATA_TABLE_ENTRY HalDTE, KdComDTE = NULL;
|
||||||
|
|
||||||
if (!KernelDTE) return FALSE;
|
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 */
|
/* Load the Kernel */
|
||||||
LoadModule(LoaderBlock, BootPath, "NTOSKRNL.EXE", LoaderSystemCode, KernelDTE, FALSE, 30);
|
LoadModule(LoaderBlock, DirPath, KernelFileName, "NTOSKRNL.EXE", LoaderSystemCode, KernelDTE, 30);
|
||||||
|
|
||||||
/* Load the HAL */
|
/* 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 */
|
/* Load the Kernel Debugger Transport DLL */
|
||||||
if (OperatingSystemVersion > _WIN32_WINNT_WIN2K)
|
if (OperatingSystemVersion > _WIN32_WINNT_WIN2K)
|
||||||
|
@ -525,27 +582,28 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion,
|
||||||
* "...foo /DEBUGPORT= bar..."
|
* "...foo /DEBUGPORT= bar..."
|
||||||
* (in that case, we default the port to COM).
|
* (in that case, we default the port to COM).
|
||||||
*/
|
*/
|
||||||
while (BootOptions)
|
Options = BootOptions;
|
||||||
|
while (Options)
|
||||||
{
|
{
|
||||||
/* Skip possible initial whitespace */
|
/* Skip possible initial whitespace */
|
||||||
BootOptions += strspn(BootOptions, " \t");
|
Options += strspn(Options, " \t");
|
||||||
|
|
||||||
/* Check whether a new commutator starts and it is the DEBUGPORT one */
|
/* 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 */
|
/* Search for another whitespace */
|
||||||
BootOptions = strpbrk(BootOptions, " \t");
|
Options = strpbrk(Options, " \t");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* We found the DEBUGPORT commutator. Move to the port name. */
|
/* We found the DEBUGPORT commutator. Move to the port name. */
|
||||||
BootOptions += 10;
|
Options += 10;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BootOptions)
|
if (Options)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* We have found the DEBUGPORT commutator. Parse the port name.
|
* 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".
|
* If we only have /DEBUGPORT= (i.e. without any port name), defaults it to "COM".
|
||||||
*/
|
*/
|
||||||
strcpy(KdTransportDllName, "KD");
|
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
|
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)
|
if (i == 0)
|
||||||
strcat(KdTransportDllName, "COM");
|
strcat(KdTransportDllName, "COM");
|
||||||
else
|
else
|
||||||
strncat(KdTransportDllName, BootOptions, i);
|
strncat(KdTransportDllName, Options, i);
|
||||||
}
|
}
|
||||||
strcat(KdTransportDllName, ".DLL");
|
strcat(KdTransportDllName, ".DLL");
|
||||||
_strupr(KdTransportDllName);
|
_strupr(KdTransportDllName);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Load the transport DLL. Specify it to LoadModule so that it can
|
* Load the transport DLL. Override the base DLL name of the
|
||||||
* change the base DLL name of the loaded transport DLL to the default
|
* loaded transport DLL to the default "KDCOM.DLL" name.
|
||||||
* "KDCOM.DLL" name, to make the PE loader happy.
|
|
||||||
*/
|
*/
|
||||||
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 */
|
/* 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, *KernelDTE);
|
||||||
Success &= WinLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath, HalDTE);
|
Success &= WinLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath, HalDTE);
|
||||||
if (KdComDTE)
|
if (KdComDTE)
|
||||||
|
@ -691,7 +746,7 @@ LoadAndBootWindows(IN OperatingSystemItem* OperatingSystem,
|
||||||
/* Allocate and minimalist-initialize LPB */
|
/* Allocate and minimalist-initialize LPB */
|
||||||
AllocateAndInitLPB(&LoaderBlock);
|
AllocateAndInitLPB(&LoaderBlock);
|
||||||
|
|
||||||
/* Load Hive */
|
/* Load the system hive */
|
||||||
UiDrawBackdrop();
|
UiDrawBackdrop();
|
||||||
UiDrawProgressBarCenter(15, 100, "Loading system hive...");
|
UiDrawProgressBarCenter(15, 100, "Loading system hive...");
|
||||||
Success = WinLdrInitSystemHive(LoaderBlock, BootPath);
|
Success = WinLdrInitSystemHive(LoaderBlock, BootPath);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue