https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f6a13d452cbeaddeee0b75...
commit f6a13d452cbeaddeee0b75f74934d57c7b6a7939 Author: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org AuthorDate: Fri Jan 7 15:39:25 2022 +0100 Commit: Hermès Bélusca-Maïto hermes.belusca-maito@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) {