mirror of
https://github.com/reactos/reactos.git
synced 2026-06-05 03:02:59 +08:00
[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.
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user