https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f6a13d452cbeaddeee0b7…
commit f6a13d452cbeaddeee0b75f74934d57c7b6a7939
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Fri Jan 7 15:39:25 2022 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sun Feb 6 23:53:41 2022 +0100
[FREELDR:NTLDR] Implement support for the SOS option.
CORE-9023, CORE-18033
- Reset the UI to a minimal one in SOS mode.
- In SOS mode, a trace of loaded files is displayed on the screen,
instead of the usual progress bar.
- Add a callback to the PE loader to notify when imported DLLs are
loaded for a main image. This allows getting an accurate SOS trace.
---
boot/freeldr/freeldr/include/peloader.h | 8 +++
boot/freeldr/freeldr/lib/peloader.c | 10 +++-
boot/freeldr/freeldr/ntldr/arch/i386/winldr.c | 4 +-
boot/freeldr/freeldr/ntldr/setupldr.c | 8 ++-
boot/freeldr/freeldr/ntldr/winldr.c | 83 ++++++++++++++++++++-------
boot/freeldr/freeldr/ntldr/winldr.h | 22 +++++++
boot/freeldr/freeldr/ntldr/wlregistry.c | 15 ++++-
7 files changed, 123 insertions(+), 27 deletions(-)
diff --git a/boot/freeldr/freeldr/include/peloader.h
b/boot/freeldr/freeldr/include/peloader.h
index a582f760c29..63ffa80471a 100644
--- a/boot/freeldr/freeldr/include/peloader.h
+++ b/boot/freeldr/freeldr/include/peloader.h
@@ -18,6 +18,14 @@
#pragma once
+/* Optional user-provided callback used by the PE loader
+ * when it loads DLLs imported by a main image. */
+typedef VOID
+(NTAPI *PELDR_IMPORTDLL_LOAD_CALLBACK)(
+ _In_ PCSTR FileName);
+
+extern PELDR_IMPORTDLL_LOAD_CALLBACK PeLdrImportDllLoadCallback;
+
BOOLEAN
PeLdrLoadImage(
IN PCHAR FileName,
diff --git a/boot/freeldr/freeldr/lib/peloader.c b/boot/freeldr/freeldr/lib/peloader.c
index 935c0ee8212..b768aa9dea8 100644
--- a/boot/freeldr/freeldr/lib/peloader.c
+++ b/boot/freeldr/freeldr/lib/peloader.c
@@ -23,6 +23,11 @@
#include <debug.h>
DBG_DEFAULT_CHANNEL(PELOADER);
+/* GLOBALS *******************************************************************/
+
+PELDR_IMPORTDLL_LOAD_CALLBACK PeLdrImportDllLoadCallback = NULL;
+
+
/* PRIVATE FUNCTIONS *********************************************************/
/* DllName - physical, UnicodeString->Buffer - virtual */
@@ -356,6 +361,9 @@ PeLdrpLoadAndScanReferencedDll(
TRACE("Loading referenced DLL: %s\n", FullDllName);
+ if (PeLdrImportDllLoadCallback)
+ PeLdrImportDllLoadCallback(FullDllName);
+
/* Load the image */
Success = PeLdrLoadImage(FullDllName, LoaderBootDriver, &BasePA);
if (!Success)
@@ -722,7 +730,7 @@ PeLdrLoadImage(
LARGE_INTEGER Position;
ULONG i, BytesRead;
- TRACE("PeLdrLoadImage(%s, %ld, *)\n", FileName, MemoryType);
+ TRACE("PeLdrLoadImage(%s, %ld)\n", FileName, MemoryType);
/* Open the image file */
Status = ArcOpen((PSTR)FileName, OpenReadOnly, &FileId);
diff --git a/boot/freeldr/freeldr/ntldr/arch/i386/winldr.c
b/boot/freeldr/freeldr/ntldr/arch/i386/winldr.c
index 759a72f108c..e28778b553f 100644
--- a/boot/freeldr/freeldr/ntldr/arch/i386/winldr.c
+++ b/boot/freeldr/freeldr/ntldr/arch/i386/winldr.c
@@ -254,7 +254,7 @@ static
VOID
MempAllocatePTE(ULONG Entry, PHARDWARE_PTE *PhysicalPT, PHARDWARE_PTE *KernelPT)
{
- //Print(L"Creating PDE Entry %X\n", Entry);
+ //TRACE("Creating PDE Entry %X\n", Entry);
// Identity mapping
*PhysicalPT =
(PHARDWARE_PTE)&PhysicalPageTablesBuffer[PhysicalPageTables*MM_PAGE_SIZE];
@@ -297,7 +297,7 @@ MempSetupPaging(IN PFN_NUMBER StartPage,
// We cannot map this as it requires more than 1 PDE
// and in fact it's not possible at all ;)
//
- //Print(L"skipping...\n");
+ //TRACE("skipping...\n");
return TRUE;
}
diff --git a/boot/freeldr/freeldr/ntldr/setupldr.c
b/boot/freeldr/freeldr/ntldr/setupldr.c
index 89fde95d4b9..2deaf6ce5ba 100644
--- a/boot/freeldr/freeldr/ntldr/setupldr.c
+++ b/boot/freeldr/freeldr/ntldr/setupldr.c
@@ -490,6 +490,7 @@ LoadReactOSSetup(
return EINVAL;
}
+ /* Let the user know we started loading */
UiDrawBackdrop();
UiDrawStatusText("Setup is loading...");
UiDrawProgressBarCenter(1, 100, "Loading ReactOS Setup...");
@@ -726,6 +727,11 @@ LoadReactOSSetup(
TRACE("BootOptions: '%s'\n", BootOptions);
+ /* Handle the SOS option */
+ SosEnabled = !!NtLdrGetOption(BootOptions, "SOS");
+ if (SosEnabled)
+ UiResetForSOS();
+
/* Allocate and minimally-initialize the Loader Parameter Block */
AllocateAndInitLPB(_WIN32_WINNT_WS03, &LoaderBlock);
@@ -737,7 +743,7 @@ LoadReactOSSetup(
SetupBlock->Flags = SETUPLDR_TEXT_MODE;
/* Load the "setupreg.hiv" setup system hive */
- UiDrawProgressBarCenter(15, 100, "Loading setup system hive...");
+ if (!SosEnabled) UiDrawProgressBarCenter(15, 100, "Loading setup system
hive...");
Success = WinLdrInitSystemHive(LoaderBlock, BootPath, TRUE);
TRACE("Setup SYSTEM hive %s\n", (Success ? "loaded" : "not
loaded"));
/* Bail out if failure */
diff --git a/boot/freeldr/freeldr/ntldr/winldr.c b/boot/freeldr/freeldr/ntldr/winldr.c
index b485835fcb4..3a21d2fe01a 100644
--- a/boot/freeldr/freeldr/ntldr/winldr.c
+++ b/boot/freeldr/freeldr/ntldr/winldr.c
@@ -39,6 +39,38 @@ BOOLEAN NoexecuteEnabled = FALSE;
// debug stuff
VOID DumpMemoryAllocMap(VOID);
+/* PE loader import-DLL loading callback */
+static VOID
+NTAPI
+NtLdrImportDllLoadCallback(
+ _In_ PCSTR FileName)
+{
+ NtLdrOutputLoadMsg(FileName, NULL);
+}
+
+VOID
+NtLdrOutputLoadMsg(
+ _In_ PCSTR FileName,
+ _In_opt_ PCSTR Description)
+{
+ if (SosEnabled)
+ {
+ printf(" %s\n", FileName);
+ TRACE("Loading: %s\n", FileName);
+ }
+ else
+ {
+ /* Inform the user we load a file */
+ CHAR ProgressString[256];
+
+ RtlStringCbPrintfA(ProgressString, sizeof(ProgressString),
+ "Loading %s...",
+ (Description ? Description : FileName));
+ // UiDrawProgressBarCenter(1, 100, ProgressString);
+ UiDrawStatusText(ProgressString);
+ }
+}
+
// Init "phase 0"
VOID
AllocateAndInitLPB(
@@ -288,6 +320,8 @@ WinLdrLoadDeviceDriver(PLIST_ENTRY LoadOrderListHead,
// It's not loaded, we have to load it
RtlStringCbPrintfA(FullPath, sizeof(FullPath), "%s%wZ", BootPath,
FilePath);
+
+ NtLdrOutputLoadMsg(FullPath, NULL);
Success = PeLdrLoadImage(FullPath, LoaderBootDriver, &DriverBase);
if (!Success)
return FALSE;
@@ -379,16 +413,10 @@ WinLdrLoadModule(PCSTR ModuleName,
ARC_STATUS Status;
ULONG BytesRead;
- //CHAR ProgressString[256];
-
- /* Inform user we are loading files */
- //RtlStringCbPrintfA(ProgressString, sizeof(ProgressString), "Loading
%s...", FileName);
- //UiDrawProgressBarCenter(1, 100, ProgressString);
-
- TRACE("Loading module %s\n", ModuleName);
*Size = 0;
/* Open the image file */
+ NtLdrOutputLoadMsg(ModuleName, NULL);
Status = ArcOpen((PSTR)ModuleName, OpenReadOnly, &FileId);
if (Status != ESUCCESS)
{
@@ -467,11 +495,12 @@ LoadModule(
PVOID BaseAddress = NULL;
RtlStringCbPrintfA(ProgressString, sizeof(ProgressString), "Loading %s...",
File);
- UiDrawProgressBarCenter(Percentage, 100, ProgressString);
+ if (!SosEnabled) UiDrawProgressBarCenter(Percentage, 100, ProgressString);
RtlStringCbCopyA(FullFileName, sizeof(FullFileName), Path);
RtlStringCbCatA(FullFileName, sizeof(FullFileName), File);
+ NtLdrOutputLoadMsg(FullFileName, NULL);
Success = PeLdrLoadImage(FullFileName, MemoryType, &BaseAddress);
if (!Success)
{
@@ -620,12 +649,6 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion,
FIXME("LoadWindowsCore: 3GB - TRUE (not implemented)\n");
VirtualBias = TRUE;
}
- if (NtLdrGetOption(BootOptions, "SOS"))
- {
- /* We found the SOS option. */
- FIXME("LoadWindowsCore: SOS - TRUE (not implemented)\n");
- SosEnabled = TRUE;
- }
if (OperatingSystemVersion > _WIN32_WINNT_NT4)
{
@@ -813,7 +836,9 @@ LoadAndBootWindows(
return EINVAL;
}
+ /* Let the user know we started loading */
UiDrawBackdrop();
+ UiDrawStatusText("Loading...");
UiDrawProgressBarCenter(1, 100, "Loading NT...");
/* Retrieve the system path */
@@ -909,14 +934,16 @@ LoadAndBootWindows(
}
}
- /* Let user know we started loading */
- //UiDrawStatusText("Loading...");
+ /* Handle the SOS option */
+ SosEnabled = !!NtLdrGetOption(BootOptions, "SOS");
+ if (SosEnabled)
+ UiResetForSOS();
/* Allocate and minimally-initialize the Loader Parameter Block */
AllocateAndInitLPB(OperatingSystemVersion, &LoaderBlock);
/* Load the system hive */
- UiDrawProgressBarCenter(15, 100, "Loading system hive...");
+ if (!SosEnabled) UiDrawProgressBarCenter(15, 100, "Loading system
hive...");
Success = WinLdrInitSystemHive(LoaderBlock, BootPath, FALSE);
TRACE("SYSTEM hive %s\n", (Success ? "loaded" : "not
loaded"));
/* Bail out if failure */
@@ -974,9 +1001,13 @@ LoadAndBootWindowsCommon(
SystemRoot = strstr(BootPath, "\\");
/* Detect hardware */
- UiDrawProgressBarCenter(20, 100, "Detecting hardware...");
+ if (!SosEnabled) UiDrawProgressBarCenter(20, 100, "Detecting
hardware...");
LoaderBlock->ConfigurationRoot = MachHwDetect();
+ /* Initialize the PE loader import-DLL callback, so that we can obtain
+ * feedback (for example during SOS) on the PE images that get loaded. */
+ PeLdrImportDllLoadCallback = NtLdrImportDllLoadCallback;
+
/* Load the operating system core: the Kernel, the HAL and the Kernel Debugger
Transport DLL */
Success = LoadWindowsCore(OperatingSystemVersion,
LoaderBlock,
@@ -985,17 +1016,27 @@ LoadAndBootWindowsCommon(
&KernelDTE);
if (!Success)
{
+ /* Reset the PE loader import-DLL callback */
+ PeLdrImportDllLoadCallback = NULL;
+
UiMessageBox("Error loading NTOS core.");
return ENOEXEC;
}
+ /* Cleanup INI file */
+ IniCleanup();
+
+/****
+ **** WE HAVE NOW REACHED THE POINT OF NO RETURN !!
+ ****/
+
/* Load boot drivers */
- UiDrawProgressBarCenter(100, 100, "Loading boot drivers...");
+ if (!SosEnabled) UiDrawProgressBarCenter(100, 100, "Loading boot
drivers...");
Success = WinLdrLoadBootDrivers(LoaderBlock, BootPath);
TRACE("Boot drivers loading %s\n", Success ? "successful" :
"failed");
- /* Cleanup ini file */
- IniCleanup();
+ /* Reset the PE loader import-DLL callback */
+ PeLdrImportDllLoadCallback = NULL;
/* Initialize Phase 1 - no drivers loading anymore */
WinLdrInitializePhase1(LoaderBlock,
diff --git a/boot/freeldr/freeldr/ntldr/winldr.h b/boot/freeldr/freeldr/ntldr/winldr.h
index c89010e3e1a..03cc68f88c7 100644
--- a/boot/freeldr/freeldr/ntldr/winldr.h
+++ b/boot/freeldr/freeldr/ntldr/winldr.h
@@ -73,6 +73,28 @@ VOID ConvertConfigToVA(PCONFIGURATION_COMPONENT_DATA Start);
// winldr.c
+extern BOOLEAN SosEnabled;
+
+FORCEINLINE
+VOID
+UiResetForSOS(VOID)
+{
+#ifdef _M_ARM
+ /* Re-initialize the UI */
+ UiInitialize(TRUE);
+#else
+ /* Reset the UI and switch to MiniTui */
+ UiVtbl.UnInitialize();
+ UiVtbl = MiniTuiVtbl;
+ UiVtbl.Initialize();
+#endif
+}
+
+VOID
+NtLdrOutputLoadMsg(
+ _In_ PCSTR FileName,
+ _In_opt_ PCSTR Description);
+
PVOID WinLdrLoadModule(PCSTR ModuleName, PULONG Size,
TYPE_OF_MEMORY MemoryType);
diff --git a/boot/freeldr/freeldr/ntldr/wlregistry.c
b/boot/freeldr/freeldr/ntldr/wlregistry.c
index 83bbda92f84..4f82fb82b97 100644
--- a/boot/freeldr/freeldr/ntldr/wlregistry.c
+++ b/boot/freeldr/freeldr/ntldr/wlregistry.c
@@ -50,6 +50,7 @@ WinLdrLoadSystemHive(
RtlStringCbCopyA(FullHiveName, sizeof(FullHiveName), DirectoryPath);
RtlStringCbCatA(FullHiveName, sizeof(FullHiveName), HiveName);
+ NtLdrOutputLoadMsg(FullHiveName, NULL);
Status = ArcOpen(FullHiveName, OpenReadOnly, &FileId);
if (Status != ESUCCESS)
{
@@ -330,6 +331,8 @@ WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
/* Open file with ANSI and store its size */
RtlStringCbCopyA(FileName, sizeof(FileName), DirectoryPath);
RtlStringCbCatA(FileName, sizeof(FileName), AnsiFileName);
+
+ NtLdrOutputLoadMsg(FileName, NULL);
Status = ArcOpen(FileName, OpenReadOnly, &FileId);
if (Status != ESUCCESS)
{
@@ -351,9 +354,10 @@ WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
}
else
{
- //Print(L"Loading %s...\n", Filename);
RtlStringCbCopyA(FileName, sizeof(FileName), DirectoryPath);
RtlStringCbCatA(FileName, sizeof(FileName), OemFileName);
+
+ NtLdrOutputLoadMsg(FileName, NULL);
Status = ArcOpen(FileName, OpenReadOnly, &FileId);
if (Status != ESUCCESS)
{
@@ -370,9 +374,10 @@ WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
TRACE("OemFileSize: %d\n", OemFileSize);
/* And finally open the language codepage file and store its length */
- //Print(L"Loading %s...\n", Filename);
RtlStringCbCopyA(FileName, sizeof(FileName), DirectoryPath);
RtlStringCbCatA(FileName, sizeof(FileName), LanguageFileName);
+
+ NtLdrOutputLoadMsg(FileName, NULL);
Status = ArcOpen(FileName, OpenReadOnly, &FileId);
if (Status != ESUCCESS)
{
@@ -415,6 +420,8 @@ WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
/* Now actually read the data into memory, starting with Ansi file */
RtlStringCbCopyA(FileName, sizeof(FileName), DirectoryPath);
RtlStringCbCatA(FileName, sizeof(FileName), AnsiFileName);
+
+ NtLdrOutputLoadMsg(FileName, NULL);
Status = ArcOpen(FileName, OpenReadOnly, &FileId);
if (Status != ESUCCESS)
{
@@ -435,6 +442,8 @@ WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
{
RtlStringCbCopyA(FileName, sizeof(FileName), DirectoryPath);
RtlStringCbCatA(FileName, sizeof(FileName), OemFileName);
+
+ NtLdrOutputLoadMsg(FileName, NULL);
Status = ArcOpen(FileName, OpenReadOnly, &FileId);
if (Status != ESUCCESS)
{
@@ -454,6 +463,8 @@ WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
/* Finally the language file */
RtlStringCbCopyA(FileName, sizeof(FileName), DirectoryPath);
RtlStringCbCatA(FileName, sizeof(FileName), LanguageFileName);
+
+ NtLdrOutputLoadMsg(FileName, NULL);
Status = ArcOpen(FileName, OpenReadOnly, &FileId);
if (Status != ESUCCESS)
{