[SHELL32] Remove 2 redundant initializations
[reactos.git] / boot / freeldr / freeldr / ntldr / winldr.c
index 4ad35a2..4b4d462 100644 (file)
@@ -8,7 +8,9 @@
 #include <freeldr.h>
 #include <ndk/ldrtypes.h>
 #include "winldr.h"
+#include "ntldropts.h"
 #include "registry.h"
+#include <internal/cmboot.h>
 
 #include <debug.h>
 DBG_DEFAULT_CHANNEL(WINDOWS);
@@ -22,20 +24,66 @@ extern BOOLEAN AcpiPresent;
 
 extern HEADLESS_LOADER_BLOCK LoaderRedirectionInformation;
 extern BOOLEAN WinLdrTerminalConnected;
-extern void WinLdrSetupEms(IN PCHAR BootOptions);
+extern VOID WinLdrSetupEms(IN PCSTR BootOptions);
 
 PLOADER_SYSTEM_BLOCK WinLdrSystemBlock;
+/**/PCWSTR BootFileSystem = NULL;/**/
+
+BOOLEAN VirtualBias = FALSE;
+BOOLEAN SosEnabled = FALSE;
+BOOLEAN SafeBoot = FALSE;
+BOOLEAN BootLogo = FALSE;
+#ifdef _M_IX86
+BOOLEAN PaeModeOn = FALSE;
+#endif
+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));
+        // UiSetProgressBarText(ProgressString);
+        // UiIndicateProgress();
+        UiDrawStatusText(ProgressString);
+    }
+}
+
 // Init "phase 0"
 VOID
-AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock)
+AllocateAndInitLPB(
+    IN USHORT VersionToBoot,
+    OUT PLOADER_PARAMETER_BLOCK* OutLoaderBlock)
 {
     PLOADER_PARAMETER_BLOCK LoaderBlock;
+    PLOADER_PARAMETER_EXTENSION Extension;
 
-    /* Allocate and zero-init the LPB */
+    /* Allocate and zero-init the Loader Parameter Block */
     WinLdrSystemBlock = MmAllocateMemoryWithType(sizeof(LOADER_SYSTEM_BLOCK),
                                                  LoaderSystemBlock);
     if (WinLdrSystemBlock == NULL)
@@ -49,6 +97,13 @@ AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock)
     LoaderBlock = &WinLdrSystemBlock->LoaderBlock;
     LoaderBlock->NlsData = &WinLdrSystemBlock->NlsDataBlock;
 
+    /* Initialize the Loader Block Extension */
+    Extension = &WinLdrSystemBlock->Extension;
+    LoaderBlock->Extension = Extension;
+    Extension->Size = sizeof(LOADER_PARAMETER_EXTENSION);
+    Extension->MajorVersion = (VersionToBoot & 0xFF00) >> 8;
+    Extension->MinorVersion = (VersionToBoot & 0xFF);
+
     /* Init three critical lists, used right away */
     InitializeListHead(&LoaderBlock->LoadOrderListHead);
     InitializeListHead(&LoaderBlock->MemoryDescriptorListHead);
@@ -99,16 +154,16 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
 // SetupBlock->ArcSetupDeviceName must be the path to the setup **SOURCE**,
 // and not the setup boot path. Indeed they may differ!!
 //
-    /* If we have a setup block, adjust also its ARC path */
     if (LoaderBlock->SetupLdrBlock)
     {
         PSETUP_LOADER_BLOCK SetupBlock = LoaderBlock->SetupLdrBlock;
 
-        /* Matches ArcBoot path */
+        /* Adjust the ARC path in the setup block - Matches ArcBoot path */
         SetupBlock->ArcSetupDeviceName = WinLdrSystemBlock->ArcBootDeviceName;
         SetupBlock->ArcSetupDeviceName = PaToVa(SetupBlock->ArcSetupDeviceName);
 
-        /* Note: LoaderBlock->SetupLdrBlock is PaToVa'ed at the end of this function */
+        /* Convert the setup block pointer */
+        LoaderBlock->SetupLdrBlock = PaToVa(LoaderBlock->SetupLdrBlock);
     }
 
     /* Fill ARC HalDevice, it matches ArcBoot path */
@@ -150,6 +205,12 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
 
         /* Allocate the ARC structure */
         ArcDiskSig = FrLdrHeapAlloc(sizeof(ARC_DISK_SIGNATURE_EX), 'giSD');
+        if (!ArcDiskSig)
+        {
+            ERR("Failed to allocate ARC structure! Ignoring remaining ARC disks. (i = %lu, DiskCount = %lu)\n",
+                i, reactos_disk_count);
+            break;
+        }
 
         /* Copy the data over */
         RtlCopyMemory(ArcDiskSig, &reactos_arc_disk_info[i], sizeof(ARC_DISK_SIGNATURE_EX));
@@ -162,7 +223,7 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
                        &ArcDiskSig->DiskSignature.ListEntry);
     }
 
-    /* Convert all list's to Virtual address */
+    /* Convert all lists to Virtual address */
 
     /* Convert the ArcDisks list to virtual address */
     List_PaToVa(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);
@@ -181,11 +242,9 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
     /* Convert list of boot drivers */
     List_PaToVa(&LoaderBlock->BootDriverListHead);
 
-    /* Initialize Extension now */
-    Extension = &WinLdrSystemBlock->Extension;
-    Extension->Size = sizeof(LOADER_PARAMETER_EXTENSION);
-    Extension->MajorVersion = (VersionToBoot & 0xFF00) >> 8;
-    Extension->MinorVersion = VersionToBoot & 0xFF;
+    Extension = LoaderBlock->Extension;
+
+    /* FIXME! HACK value for docking profile */
     Extension->Profile.Status = 2;
 
     /* Check if FreeLdr detected a ACPI table */
@@ -196,6 +255,15 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
         // FIXME: Extension->AcpiTableSize;
     }
 
+    if (VersionToBoot >= _WIN32_WINNT_VISTA)
+    {
+        Extension->BootViaWinload = 1;
+        Extension->LoaderPerformanceData = PaToVa(&WinLdrSystemBlock->LoaderPerformanceData);
+
+        InitializeListHead(&Extension->BootApplicationPersistentData);
+        List_PaToVa(&Extension->BootApplicationPersistentData);
+    }
+
 #ifdef _M_IX86
     /* Set headless block pointer */
     if (WinLdrTerminalConnected)
@@ -214,11 +282,8 @@ WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
                                                     &Extension->DrvDBSize,
                                                     LoaderRegistryData));
 
-    /* Convert extension and setup block pointers */
-    LoaderBlock->Extension = PaToVa(Extension);
-
-    if (LoaderBlock->SetupLdrBlock)
-        LoaderBlock->SetupLdrBlock = PaToVa(LoaderBlock->SetupLdrBlock);
+    /* Convert the extension block pointer */
+    LoaderBlock->Extension = PaToVa(LoaderBlock->Extension);
 
     TRACE("WinLdrInitializePhase1() completed\n");
 }
@@ -267,18 +332,28 @@ 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)
+    {
+        ERR("PeLdrLoadImage('%s') failed\n", DllName);
         return FALSE;
+    }
 
     // Allocate a DTE for it
     Success = PeLdrAllocateDataTableEntry(LoadOrderListHead, DllName, DllName, DriverBase, DriverDTE);
     if (!Success)
     {
-        ERR("PeLdrAllocateDataTableEntry() failed\n");
+        /* Cleanup and bail out */
+        ERR("PeLdrAllocateDataTableEntry('%s') failed\n", DllName);
+        MmFreeMemory(DriverBase);
         return FALSE;
     }
 
+    /* Init security cookie */
+    PeLdrInitSecurityCookie(*DriverDTE);
+
     // Modify any flags, if needed
     (*DriverDTE)->Flags |= Flags;
 
@@ -287,7 +362,10 @@ WinLdrLoadDeviceDriver(PLIST_ENTRY LoadOrderListHead,
     Success = PeLdrScanImportDescriptorTable(LoadOrderListHead, FullPath, *DriverDTE);
     if (!Success)
     {
-        ERR("PeLdrScanImportDescriptorTable() failed for %s\n", FullPath);
+        /* Cleanup and bail out */
+        ERR("PeLdrScanImportDescriptorTable('%s') failed\n", FullPath);
+        PeLdrFreeDataTableEntry(*DriverDTE);
+        MmFreeMemory(DriverBase);
         return FALSE;
     }
 
@@ -299,48 +377,57 @@ WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,
                       PCSTR BootPath)
 {
     PLIST_ENTRY NextBd;
+    PBOOT_DRIVER_NODE DriverNode;
     PBOOT_DRIVER_LIST_ENTRY BootDriver;
     BOOLEAN Success;
     BOOLEAN ret = TRUE;
 
-    // Walk through the boot drivers list
+    /* Walk through the boot drivers list */
     NextBd = LoaderBlock->BootDriverListHead.Flink;
-
     while (NextBd != &LoaderBlock->BootDriverListHead)
     {
-        BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, Link);
+        DriverNode = CONTAINING_RECORD(NextBd,
+                                       BOOT_DRIVER_NODE,
+                                       ListEntry.Link);
+        BootDriver = &DriverNode->ListEntry;
 
-        TRACE("BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,
-            BootDriver->LdrEntry, &BootDriver->RegistryPath);
+        /* Get the next list entry as we may remove the current one on failure */
+        NextBd = BootDriver->Link.Flink;
+
+        TRACE("BootDriver %wZ DTE %08X RegPath: %wZ\n",
+              &BootDriver->FilePath, BootDriver->LdrEntry,
+              &BootDriver->RegistryPath);
 
         // Paths are relative (FIXME: Are they always relative?)
 
-        // Load it
+        /* Load it */
+        UiIndicateProgress();
         Success = WinLdrLoadDeviceDriver(&LoaderBlock->LoadOrderListHead,
                                          BootPath,
                                          &BootDriver->FilePath,
                                          0,
                                          &BootDriver->LdrEntry);
-
         if (Success)
         {
-            // Convert the RegistryPath and DTE addresses to VA since we are not going to use it anymore
+            /* Convert the addresses to VA since we are not going to use them anymore */
             BootDriver->RegistryPath.Buffer = PaToVa(BootDriver->RegistryPath.Buffer);
             BootDriver->FilePath.Buffer = PaToVa(BootDriver->FilePath.Buffer);
             BootDriver->LdrEntry = PaToVa(BootDriver->LdrEntry);
+
+            if (DriverNode->Group.Buffer)
+                DriverNode->Group.Buffer = PaToVa(DriverNode->Group.Buffer);
+            DriverNode->Name.Buffer = PaToVa(DriverNode->Name.Buffer);
         }
         else
         {
-            // Loading failed - cry loudly
-            ERR("Can't load boot driver '%wZ'!\n", &BootDriver->FilePath);
-            UiMessageBox("Can't load boot driver '%wZ'!", &BootDriver->FilePath);
+            /* Loading failed: cry loudly */
+            ERR("Cannot load boot driver '%wZ'!\n", &BootDriver->FilePath);
+            UiMessageBox("Cannot load boot driver '%wZ'!", &BootDriver->FilePath);
             ret = FALSE;
 
-            // Remove it from the list and try to continue
-            RemoveEntryList(NextBd);
+            /* Remove it from the list and try to continue */
+            RemoveEntryList(&BootDriver->Link);
         }
-
-        NextBd = BootDriver->Link.Flink;
     }
 
     return ret;
@@ -358,17 +445,10 @@ WinLdrLoadModule(PCSTR ModuleName,
     ARC_STATUS Status;
     ULONG BytesRead;
 
-    //CHAR ProgressString[256];
-
-    /* Inform user we are loading files */
-    //UiDrawBackdrop();
-    //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)
     {
@@ -377,7 +457,7 @@ WinLdrLoadModule(PCSTR ModuleName,
         return NULL;
     }
 
-    /* Get this file's size */
+    /* Retrieve its size */
     Status = ArcGetFileInformation(FileId, &FileInfo);
     if (Status != ESUCCESS)
     {
@@ -391,11 +471,12 @@ WinLdrLoadModule(PCSTR ModuleName,
     PhysicalBase = MmAllocateMemoryWithType(FileSize, MemoryType);
     if (PhysicalBase == NULL)
     {
+        ERR("Could not allocate memory for '%s'\n", ModuleName);
         ArcClose(FileId);
         return NULL;
     }
 
-    /* Load whole file */
+    /* Load the whole file */
     Status = ArcRead(FileId, PhysicalBase, FileSize, &BytesRead);
     ArcClose(FileId);
     if (Status != ESUCCESS)
@@ -415,21 +496,20 @@ WinLdrDetectVersion(VOID)
     LONG rc;
     HKEY hKey;
 
-    rc = RegOpenKey(NULL,
-                    L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server",
-                    &hKey);
+    rc = RegOpenKey(CurrentControlSetKey, L"Control\\Terminal Server", &hKey);
     if (rc != ERROR_SUCCESS)
     {
         /* Key doesn't exist; assume NT 4.0 */
         return _WIN32_WINNT_NT4;
     }
+    RegCloseKey(hKey);
 
     /* We may here want to read the value of ProductVersion */
     return _WIN32_WINNT_WS03;
 }
 
 static
-BOOLEAN
+PVOID
 LoadModule(
     IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
     IN PCCH Path,
@@ -442,36 +522,96 @@ LoadModule(
     BOOLEAN Success;
     CHAR FullFileName[MAX_PATH];
     CHAR ProgressString[256];
-    PVOID BaseAddress = NULL;
+    PVOID BaseAddress;
 
-    UiDrawBackdrop();
     RtlStringCbPrintfA(ProgressString, sizeof(ProgressString), "Loading %s...", File);
-    UiDrawProgressBarCenter(Percentage, 100, ProgressString);
+    UiUpdateProgressBar(Percentage, ProgressString);
 
     RtlStringCbCopyA(FullFileName, sizeof(FullFileName), Path);
     RtlStringCbCatA(FullFileName, sizeof(FullFileName), File);
 
+    NtLdrOutputLoadMsg(FullFileName, NULL);
     Success = PeLdrLoadImage(FullFileName, MemoryType, &BaseAddress);
     if (!Success)
     {
-        TRACE("Loading %s failed\n", File);
-        return FALSE;
+        ERR("PeLdrLoadImage('%s') failed\n", File);
+        return NULL;
     }
     TRACE("%s loaded successfully at %p\n", File, BaseAddress);
 
-    /*
-     * Cheat about the base DLL name if we are loading
-     * the Kernel Debugger Transport DLL, to make the
-     * PE loader happy.
-     */
     Success = PeLdrAllocateDataTableEntry(&LoaderBlock->LoadOrderListHead,
                                           ImportName,
                                           FullFileName,
                                           BaseAddress,
                                           Dte);
+    if (!Success)
+    {
+        /* Cleanup and bail out */
+        ERR("PeLdrAllocateDataTableEntry('%s') failed\n", FullFileName);
+        MmFreeMemory(BaseAddress);
+        return NULL;
+    }
 
-    return Success;
+    /* Init security cookie */
+    PeLdrInitSecurityCookie(*Dte);
+
+    return BaseAddress;
+}
+
+#ifdef _M_IX86
+static
+BOOLEAN
+WinLdrIsPaeSupported(
+    _In_ USHORT OperatingSystemVersion,
+    _In_ PLOADER_PARAMETER_BLOCK LoaderBlock,
+    _In_ PCSTR BootOptions,
+    _In_ PCSTR HalFileName,
+    _Inout_updates_bytes_(KernelFileNameSize) _Always_(_Post_z_)
+         PSTR KernelFileName,
+    _In_ SIZE_T KernelFileNameSize)
+{
+    BOOLEAN PaeEnabled = FALSE;
+    BOOLEAN PaeDisabled = FALSE;
+    BOOLEAN Result;
+
+    if ((OperatingSystemVersion > _WIN32_WINNT_NT4) &&
+        NtLdrGetOption(BootOptions, "PAE"))
+    {
+        /* We found the PAE option */
+        PaeEnabled = TRUE;
+    }
+
+    Result = PaeEnabled;
+
+    if ((OperatingSystemVersion > _WIN32_WINNT_WIN2K) &&
+        NtLdrGetOption(BootOptions, "NOPAE"))
+    {
+        PaeDisabled = TRUE;
+    }
+
+    if (SafeBoot)
+        PaeDisabled = TRUE;
+
+    TRACE("PaeEnabled %X, PaeDisabled %X\n", PaeEnabled, PaeDisabled);
+
+    if (PaeDisabled)
+        Result = FALSE;
+
+    /* Enable PAE if DEP is enabled */
+    if (NoExecuteEnabled)
+        Result = TRUE;
+
+    // TODO: checks for CPU support, hotplug memory support ... other tests
+    // TODO: select kernel name ("ntkrnlpa.exe" or "ntoskrnl.exe"), or,
+    // if KernelFileName is a user-specified kernel file, check whether it
+    // has, if PAE needs to be enabled, the IMAGE_FILE_LARGE_ADDRESS_AWARE
+    // Characteristics bit set, and that the HAL image has a similar support.
+
+    if (Result) UNIMPLEMENTED;
+
+    return Result;
 }
+#endif /* _M_IX86 */
 
 static
 BOOLEAN
@@ -482,12 +622,14 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion,
                 IN OUT PLDR_DATA_TABLE_ENTRY* KernelDTE)
 {
     BOOLEAN Success;
-    PCSTR Options;
+    PCSTR Option;
+    ULONG OptionLength;
+    PVOID KernelBase, HalBase, KdDllBase = NULL;
+    PLDR_DATA_TABLE_ENTRY HalDTE, KdDllDTE = NULL;
     CHAR DirPath[MAX_PATH];
     CHAR HalFileName[MAX_PATH];
     CHAR KernelFileName[MAX_PATH];
-    CHAR KdTransportDllName[MAX_PATH];
-    PLDR_DATA_TABLE_ENTRY HalDTE, KdComDTE = NULL;
+    CHAR KdDllName[MAX_PATH];
 
     if (!KernelDTE) return FALSE;
 
@@ -495,64 +637,147 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion,
     RtlStringCbCopyA(DirPath, sizeof(DirPath), BootPath);
     RtlStringCbCatA(DirPath, sizeof(DirPath), "system32\\");
 
+    /* Parse the boot options */
+    TRACE("LoadWindowsCore: BootOptions '%s'\n", BootOptions);
+
+#ifdef _M_IX86
+    if (NtLdrGetOption(BootOptions, "3GB"))
+    {
+        /* We found the 3GB option. */
+        FIXME("LoadWindowsCore: 3GB - TRUE (not implemented)\n");
+        VirtualBias = TRUE;
+    }
+    // TODO: "USERVA=" for XP/2k3
+#endif
+
+    if ((OperatingSystemVersion > _WIN32_WINNT_NT4) &&
+        (NtLdrGetOption(BootOptions, "SAFEBOOT") ||
+         NtLdrGetOption(BootOptions, "SAFEBOOT:")))
+    {
+        /* We found the SAFEBOOT option. */
+        FIXME("LoadWindowsCore: SAFEBOOT - TRUE (not implemented)\n");
+        SafeBoot = TRUE;
+    }
+
+    if ((OperatingSystemVersion > _WIN32_WINNT_WIN2K) &&
+        NtLdrGetOption(BootOptions, "BOOTLOGO"))
+    {
+        /* We found the BOOTLOGO option. */
+        FIXME("LoadWindowsCore: BOOTLOGO - TRUE (not implemented)\n");
+        BootLogo = TRUE;
+    }
+
+    /* Check the (NO)EXECUTE options */
+    if ((OperatingSystemVersion > _WIN32_WINNT_WIN2K) &&
+        !LoaderBlock->SetupLdrBlock)
+    {
+        /* Disable NX by default on x86, otherwise enable it */
+#ifdef _M_IX86
+        NoExecuteEnabled = FALSE;
+#else
+        NoExecuteEnabled = TRUE;
+#endif
+
+#ifdef _M_IX86
+        /* Check the options in decreasing order of precedence */
+        if (NtLdrGetOption(BootOptions, "NOEXECUTE=OPTIN")  ||
+            NtLdrGetOption(BootOptions, "NOEXECUTE=OPTOUT") ||
+            NtLdrGetOption(BootOptions, "NOEXECUTE=ALWAYSON"))
+        {
+            NoExecuteEnabled = TRUE;
+        }
+        else if (NtLdrGetOption(BootOptions, "NOEXECUTE=ALWAYSOFF"))
+            NoExecuteEnabled = FALSE;
+        else
+#else
+        /* Only the following two options really apply for x64 and other platforms */
+#endif
+        if (NtLdrGetOption(BootOptions, "NOEXECUTE"))
+            NoExecuteEnabled = TRUE;
+        else if (NtLdrGetOption(BootOptions, "EXECUTE"))
+            NoExecuteEnabled = FALSE;
+
+#ifdef _M_IX86
+        /* Disable DEP in SafeBoot mode for x86 only */
+        if (SafeBoot)
+            NoExecuteEnabled = FALSE;
+#endif
+    }
+    TRACE("NoExecuteEnabled %X\n", NoExecuteEnabled);
+
     /*
-     * Default HAL and KERNEL file names.
+     * Select the HAL and KERNEL file names.
+     * Check for any "/HAL=" or "/KERNEL=" override option.
+     *
      * See the following links to know how the file names are actually chosen:
      * https://www.geoffchappell.com/notes/windows/boot/bcd/osloader/detecthal.htm
      * https://www.geoffchappell.com/notes/windows/boot/bcd/osloader/hal.htm
      * https://www.geoffchappell.com/notes/windows/boot/bcd/osloader/kernel.htm
      */
+    /* Default HAL and KERNEL file names */
     RtlStringCbCopyA(HalFileName   , sizeof(HalFileName)   , "hal.dll");
     RtlStringCbCopyA(KernelFileName, sizeof(KernelFileName), "ntoskrnl.exe");
 
-    /* Find any "/HAL=" or "/KERNEL=" switch in the boot options */
-    Options = BootOptions;
-    while (Options)
+    Option = NtLdrGetOptionEx(BootOptions, "HAL=", &OptionLength);
+    if (Option && (OptionLength > 4))
     {
-        /* Skip possible initial whitespace */
-        Options += strspn(Options, " \t");
-
-        /* Check whether a new option starts and it is either HAL or KERNEL */
-        if (*Options != '/' || (++Options,
-            !(_strnicmp(Options, "HAL=",    4) == 0 ||
-              _strnicmp(Options, "KERNEL=", 7) == 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;
-            }
+        /* Retrieve the HAL file name */
+        Option += 4; OptionLength -= 4;
+        RtlStringCbCopyNA(HalFileName, sizeof(HalFileName), Option, OptionLength);
+        _strlwr(HalFileName);
+    }
 
-            /* We have found either HAL or KERNEL options */
-            if (_strnicmp(Options, "HAL=", 4) == 0)
-            {
-                Options += 4; i -= 4;
-                RtlStringCbCopyNA(HalFileName, sizeof(HalFileName), Options, i);
-                _strupr(HalFileName);
-            }
-            else if (_strnicmp(Options, "KERNEL=", 7) == 0)
-            {
-                Options += 7; i -= 7;
-                RtlStringCbCopyNA(KernelFileName, sizeof(KernelFileName), Options, i);
-                _strupr(KernelFileName);
-            }
-        }
+    Option = NtLdrGetOptionEx(BootOptions, "KERNEL=", &OptionLength);
+    if (Option && (OptionLength > 7))
+    {
+        /* Retrieve the KERNEL file name */
+        Option += 7; OptionLength -= 7;
+        RtlStringCbCopyNA(KernelFileName, sizeof(KernelFileName), Option, OptionLength);
+        _strlwr(KernelFileName);
     }
 
+#ifdef _M_IX86
+    /* Check for PAE support and select the adequate kernel image */
+    PaeModeOn = WinLdrIsPaeSupported(OperatingSystemVersion,
+                                     LoaderBlock,
+                                     BootOptions,
+                                     HalFileName,
+                                     KernelFileName,
+                                     sizeof(KernelFileName));
+    if (PaeModeOn) FIXME("WinLdrIsPaeSupported: PaeModeOn\n");
+#endif
+
     TRACE("HAL file = '%s' ; Kernel file = '%s'\n", HalFileName, KernelFileName);
 
+    /*
+     * Load the core NT files: Kernel, HAL and KD transport DLL.
+     * Cheat about their base DLL name so as to satisfy the imports/exports,
+     * even if the corresponding underlying files do not have the same names
+     * -- this happens e.g. with UP vs. MP kernel, standard vs. ACPI hal, or
+     * different KD transport DLLs.
+     */
+
     /* Load the Kernel */
-    LoadModule(LoaderBlock, DirPath, KernelFileName, "ntoskrnl.exe", LoaderSystemCode, KernelDTE, 30);
+    KernelBase = LoadModule(LoaderBlock, DirPath, KernelFileName,
+                            "ntoskrnl.exe", LoaderSystemCode, KernelDTE, 30);
+    if (!KernelBase)
+    {
+        ERR("LoadModule('%s') failed\n", KernelFileName);
+        UiMessageBox("Could not load %s", KernelFileName);
+        return FALSE;
+    }
 
     /* Load the HAL */
-    LoadModule(LoaderBlock, DirPath, HalFileName, "hal.dll", LoaderHalCode, &HalDTE, 45);
+    HalBase = LoadModule(LoaderBlock, DirPath, HalFileName,
+                         "hal.dll", LoaderHalCode, &HalDTE, 35);
+    if (!HalBase)
+    {
+        ERR("LoadModule('%s') failed\n", HalFileName);
+        UiMessageBox("Could not load %s", HalFileName);
+        PeLdrFreeDataTableEntry(*KernelDTE);
+        MmFreeMemory(KernelBase);
+        return FALSE;
+    }
 
     /* Load the Kernel Debugger Transport DLL */
     if (OperatingSystemVersion > _WIN32_WINNT_WIN2K)
@@ -569,87 +794,184 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion,
          */
 
         /*
-         * This loop replaces a dumb call to strstr(..., "DEBUGPORT=").
-         * Indeed I want it to be case-insensitive to allow "debugport="
-         * or "DeBuGpOrT=" or... , and I don't want it to match malformed
-         * command-line options, such as:
-         *
-         * "...foo DEBUGPORT=xxx bar..."
-         * "...foo/DEBUGPORT=xxx bar..."
-         * "...foo/DEBUGPORT=bar..."
-         *
-         * i.e. the "DEBUGPORT=" switch must start with a slash and be separated
-         * from the rest by whitespace, unless it begins the command-line, e.g.:
-         *
-         * "/DEBUGPORT=COM1 foo...bar..."
-         * "...foo /DEBUGPORT=USB bar..."
-         * or:
-         * "...foo /DEBUGPORT= bar..."
-         * (in that case, we default the port to COM).
+         * 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.
          */
-        Options = BootOptions;
-        while (Options)
+        BOOLEAN IsCustomKdDll = FALSE;
+
+        /* Check whether there is a DEBUGPORT option */
+        Option = NtLdrGetOptionEx(BootOptions, "DEBUGPORT=", &OptionLength);
+        if (Option && (OptionLength > 10))
         {
-            /* Skip possible initial whitespace */
-            Options += strspn(Options, " \t");
+            /* Move to the debug port name */
+            Option += 10; OptionLength -= 10;
+
+            /*
+             * Parse the port name.
+             * 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),
+             * default to "COM".
+             */
 
-            /* Check whether a new option starts and it is the DEBUGPORT one */
-            if (*Options != '/' || _strnicmp(++Options, "DEBUGPORT=", 10) != 0)
+            /* 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')) ))
             {
-                /* Search for another whitespace */
-                Options = strpbrk(Options, " \t");
-                continue;
+                /* The standard KDCOM.DLL is used */
             }
             else
             {
-                /* We found the DEBUGPORT option. Move to the port name. */
-                Options += 10;
-                break;
+                /* A custom KD DLL is used */
+                IsCustomKdDll = TRUE;
             }
         }
+        if (!IsCustomKdDll)
+        {
+            Option = "COM"; OptionLength = 3;
+        }
+
+        RtlStringCbPrintfA(KdDllName, sizeof(KdDllName), "kd%.*s.dll",
+                           OptionLength, Option);
+        _strlwr(KdDllName);
 
-        if (Options)
+        /* Load the KD DLL. Override its base DLL name to the default "KDCOM.DLL". */
+        KdDllBase = LoadModule(LoaderBlock, DirPath, KdDllName,
+                               "kdcom.dll", LoaderSystemCode, &KdDllDTE, 40);
+        if (!KdDllBase)
         {
-            /*
-             * We have found the DEBUGPORT option. Parse the port name.
-             * Format: /DEBUGPORT=COM1 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".
-             */
-            RtlStringCbCopyA(KdTransportDllName, sizeof(KdTransportDllName), "KD");
-            if (_strnicmp(Options, "COM", 3) == 0 && '0' <= Options[3] && Options[3] <= '9')
+            /* If we failed to load a custom KD DLL, fall back to the standard one */
+            if (IsCustomKdDll)
             {
-                RtlStringCbCatNA(KdTransportDllName, sizeof(KdTransportDllName), Options, 3);
+                /* 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, 40);
             }
-            else
+
+            if (!KdDllBase)
             {
-                size_t i = strcspn(Options, " \t:"); /* Skip valid separators: whitespace or colon */
-                if (i == 0)
-                    RtlStringCbCatA(KdTransportDllName, sizeof(KdTransportDllName), "COM");
-                else
-                    RtlStringCbCatNA(KdTransportDllName, sizeof(KdTransportDllName), Options, i);
+                /* 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);
             }
-            RtlStringCbCatA(KdTransportDllName, sizeof(KdTransportDllName), ".DLL");
-            _strupr(KdTransportDllName);
-
-            /*
-             * Load the transport DLL. Override the base DLL name of the
-             * loaded transport DLL to the default "KDCOM.DLL" name.
-             */
-            LoadModule(LoaderBlock, DirPath, KdTransportDllName, "kdcom.dll", LoaderSystemCode, &KdComDTE, 60);
         }
     }
 
     /* Load all referenced DLLs for Kernel, HAL and Kernel Debugger Transport DLL */
-    Success  = PeLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath, *KernelDTE);
-    Success &= PeLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath, HalDTE);
-    if (KdComDTE)
+    Success = PeLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath, *KernelDTE);
+    if (!Success)
     {
-        Success &= PeLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath, KdComDTE);
+        UiMessageBox("Could not load %s", KernelFileName);
+        goto Quit;
+    }
+    Success = PeLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath, HalDTE);
+    if (!Success)
+    {
+        UiMessageBox("Could not load %s", HalFileName);
+        goto Quit;
+    }
+    if (KdDllDTE)
+    {
+        Success = PeLdrScanImportDescriptorTable(&LoaderBlock->LoadOrderListHead, DirPath, KdDllDTE);
+        if (!Success)
+        {
+            UiMessageBox("Could not load %s", KdDllName);
+            goto Quit;
+        }
+    }
+
+Quit:
+    if (!Success)
+    {
+        /* Cleanup and bail out */
+        if (KdDllDTE)
+            PeLdrFreeDataTableEntry(KdDllDTE);
+        if (KdDllBase) // Optional
+            MmFreeMemory(KdDllBase);
+
+        PeLdrFreeDataTableEntry(HalDTE);
+        MmFreeMemory(HalBase);
+
+        PeLdrFreeDataTableEntry(*KernelDTE);
+        MmFreeMemory(KernelBase);
     }
 
     return Success;
 }
 
+static
+BOOLEAN
+WinLdrInitErrataInf(
+    IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
+    IN USHORT OperatingSystemVersion,
+    IN PCSTR SystemRoot)
+{
+    LONG rc;
+    HKEY hKey;
+    ULONG BufferSize;
+    ULONG FileSize;
+    PVOID PhysicalBase;
+    WCHAR szFileName[80];
+    CHAR ErrataFilePath[MAX_PATH];
+
+    /* Open either the 'BiosInfo' (Windows <= 2003) or the 'Errata' (Vista+) key */
+    if (OperatingSystemVersion >= _WIN32_WINNT_VISTA)
+    {
+        rc = RegOpenKey(CurrentControlSetKey, L"Control\\Errata", &hKey);
+    }
+    else // (OperatingSystemVersion <= _WIN32_WINNT_WS03)
+    {
+        rc = RegOpenKey(CurrentControlSetKey, L"Control\\BiosInfo", &hKey);
+    }
+    if (rc != ERROR_SUCCESS)
+    {
+        WARN("Could not open the BiosInfo/Errata registry key (Error %u)\n", (int)rc);
+        return FALSE;
+    }
+
+    /* Retrieve the INF file name value */
+    BufferSize = sizeof(szFileName);
+    rc = RegQueryValue(hKey, L"InfName", NULL, (PUCHAR)szFileName, &BufferSize);
+    if (rc != ERROR_SUCCESS)
+    {
+        WARN("Could not retrieve the InfName value (Error %u)\n", (int)rc);
+        RegCloseKey(hKey);
+        return FALSE;
+    }
+
+    // TODO: "SystemBiosDate"
+
+    RegCloseKey(hKey);
+
+    RtlStringCbPrintfA(ErrataFilePath, sizeof(ErrataFilePath), "%s%s%S",
+                       SystemRoot, "inf\\", szFileName);
+
+    /* Load the INF file */
+    PhysicalBase = WinLdrLoadModule(ErrataFilePath, &FileSize, LoaderRegistryData);
+    if (!PhysicalBase)
+    {
+        WARN("Could not load '%s'\n", ErrataFilePath);
+        return FALSE;
+    }
+
+    LoaderBlock->Extension->EmInfFileImage = PaToVa(PhysicalBase);
+    LoaderBlock->Extension->EmInfFileSize  = FileSize;
+
+    return TRUE;
+}
+
 ARC_STATUS
 LoadAndBootWindows(
     IN ULONG Argc,
@@ -659,13 +981,14 @@ LoadAndBootWindows(
     ARC_STATUS Status;
     PCSTR ArgValue;
     PCSTR SystemPartition;
-    PCHAR File;
+    PCSTR FileName;
+    ULONG FileNameLength;
     BOOLEAN Success;
     USHORT OperatingSystemVersion;
     PLOADER_PARAMETER_BLOCK LoaderBlock;
-    CHAR  BootPath[MAX_PATH];
-    CHAR  FileName[MAX_PATH];
-    CHAR  BootOptions[256];
+    CHAR BootPath[MAX_PATH];
+    CHAR FilePath[MAX_PATH];
+    CHAR BootOptions[256];
 
     /* Retrieve the (mandatory) boot type */
     ArgValue = GetArgumentValue(Argc, Argv, "BootType");
@@ -685,6 +1008,10 @@ LoadAndBootWindows(
     {
         OperatingSystemVersion = _WIN32_WINNT_NT4;
     }
+    else if (_stricmp(ArgValue, "WindowsVista") == 0)
+    {
+        OperatingSystemVersion = _WIN32_WINNT_VISTA;
+    }
     else
     {
         ERR("Unknown 'BootType' value '%s', aborting!\n", ArgValue);
@@ -699,8 +1026,10 @@ LoadAndBootWindows(
         return EINVAL;
     }
 
+    /* Let the user know we started loading */
     UiDrawBackdrop();
-    UiDrawProgressBarCenter(1, 100, "Loading NT...");
+    UiDrawStatusText("Loading...");
+    UiDrawProgressBarCenter("Loading NT...");
 
     /* Retrieve the system path */
     *BootPath = ANSI_NULL;
@@ -717,17 +1046,17 @@ LoadAndBootWindows(
     if (strrchr(BootPath, ')') == NULL)
     {
         /* Temporarily save the boot path */
-        RtlStringCbCopyA(FileName, sizeof(FileName), BootPath);
+        RtlStringCbCopyA(FilePath, sizeof(FilePath), BootPath);
 
         /* This is not a full path: prepend the SystemPartition */
         RtlStringCbCopyA(BootPath, sizeof(BootPath), SystemPartition);
 
         /* Append a path separator if needed */
-        if (*FileName != '\\' && *FileName != '/')
+        if (*FilePath != '\\' && *FilePath != '/')
             RtlStringCbCatA(BootPath, sizeof(BootPath), "\\");
 
         /* Append the remaining path */
-        RtlStringCbCatA(BootPath, sizeof(BootPath), FileName);
+        RtlStringCbCatA(BootPath, sizeof(BootPath), FilePath);
     }
 
     /* Append a path separator if needed */
@@ -746,12 +1075,12 @@ LoadAndBootWindows(
     AppendBootTimeOptions(BootOptions);
 
     /*
-     * Set "/HAL=" and "/KERNEL=" options if needed.
+     * Set the "/HAL=" and "/KERNEL=" options if needed.
      * If already present on the standard "Options=" option line, they take
      * precedence over those passed via the separate "Hal=" and "Kernel="
      * options.
      */
-    if (strstr(BootOptions, "/HAL=") != 0)
+    if (!NtLdrGetOption(BootOptions, "HAL="))
     {
         /*
          * Not found in the options, try to retrieve the
@@ -764,7 +1093,7 @@ LoadAndBootWindows(
             RtlStringCbCatA(BootOptions, sizeof(BootOptions), ArgValue);
         }
     }
-    if (strstr(BootOptions, "/KERNEL=") != 0)
+    if (!NtLdrGetOption(BootOptions, "KERNEL="))
     {
         /*
          * Not found in the options, try to retrieve the
@@ -780,40 +1109,43 @@ LoadAndBootWindows(
 
     TRACE("BootOptions: '%s'\n", BootOptions);
 
-    /* Check if a ramdisk file was given */
-    File = strstr(BootOptions, "/RDPATH=");
-    if (File)
+    /* Check if a RAM disk file was given */
+    FileName = NtLdrGetOptionEx(BootOptions, "RDPATH=", &FileNameLength);
+    if (FileName && (FileNameLength > 7))
     {
-        /* Copy the file name and everything else after it */
-        RtlStringCbCopyA(FileName, sizeof(FileName), File + 8);
-
-        /* Null-terminate */
-        *strstr(FileName, " ") = ANSI_NULL;
-
-        /* Load the ramdisk */
-        Status = RamDiskLoadVirtualFile(FileName, SystemPartition);
+        /* Load the RAM disk */
+        Status = RamDiskInitialize(FALSE, BootOptions, SystemPartition);
         if (Status != ESUCCESS)
         {
-            UiMessageBox("Failed to load RAM disk file %s", FileName);
+            FileName += 7; FileNameLength -= 7;
+            UiMessageBox("Failed to load RAM disk file '%.*s'",
+                         FileNameLength, FileName);
             return Status;
         }
     }
 
-    /* Let user know we started loading */
-    //UiDrawStatusText("Loading...");
+    /* Handle the SOS option */
+    SosEnabled = !!NtLdrGetOption(BootOptions, "SOS");
+    if (SosEnabled)
+        UiResetForSOS();
 
-    /* Allocate and minimalist-initialize LPB */
-    AllocateAndInitLPB(&LoaderBlock);
+    /* Allocate and minimally-initialize the Loader Parameter Block */
+    AllocateAndInitLPB(OperatingSystemVersion, &LoaderBlock);
 
     /* Load the system hive */
-    UiDrawBackdrop();
-    UiDrawProgressBarCenter(15, 100, "Loading system hive...");
+    UiUpdateProgressBar(15, "Loading system hive...");
     Success = WinLdrInitSystemHive(LoaderBlock, BootPath, FALSE);
     TRACE("SYSTEM hive %s\n", (Success ? "loaded" : "not loaded"));
     /* Bail out if failure */
     if (!Success)
         return ENOEXEC;
 
+    /* Fixup the version number using data from the registry */
+    if (OperatingSystemVersion == 0)
+        OperatingSystemVersion = WinLdrDetectVersion();
+    LoaderBlock->Extension->MajorVersion = (OperatingSystemVersion & 0xFF00) >> 8;
+    LoaderBlock->Extension->MinorVersion = (OperatingSystemVersion & 0xFF);
+
     /* Load NLS data, OEM font, and prepare boot drivers list */
     Success = WinLdrScanSystemHive(LoaderBlock, BootPath);
     TRACE("SYSTEM hive %s\n", (Success ? "scanned" : "not scanned"));
@@ -821,21 +1153,24 @@ LoadAndBootWindows(
     if (!Success)
         return ENOEXEC;
 
+    /* Load the Firmware Errata file */
+    Success = WinLdrInitErrataInf(LoaderBlock, OperatingSystemVersion, BootPath);
+    TRACE("Firmware Errata file %s\n", (Success ? "loaded" : "not loaded"));
+    /* Not necessarily fatal if not found - carry on going */
+
     /* Finish loading */
     return LoadAndBootWindowsCommon(OperatingSystemVersion,
                                     LoaderBlock,
                                     BootOptions,
-                                    BootPath,
-                                    FALSE);
+                                    BootPath);
 }
 
 ARC_STATUS
 LoadAndBootWindowsCommon(
-    USHORT OperatingSystemVersion,
-    PLOADER_PARAMETER_BLOCK LoaderBlock,
-    PCSTR BootOptions,
-    PCSTR BootPath,
-    BOOLEAN Setup)
+    IN USHORT OperatingSystemVersion,
+    IN PLOADER_PARAMETER_BLOCK LoaderBlock,
+    IN PCSTR BootOptions,
+    IN PCSTR BootPath)
 {
     PLOADER_PARAMETER_BLOCK LoaderBlockVA;
     BOOLEAN Success;
@@ -845,21 +1180,23 @@ LoadAndBootWindowsCommon(
 
     TRACE("LoadAndBootWindowsCommon()\n");
 
+    ASSERT(OperatingSystemVersion != 0);
+
 #ifdef _M_IX86
     /* Setup redirection support */
-    WinLdrSetupEms((PCHAR)BootOptions);
+    WinLdrSetupEms(BootOptions);
 #endif
 
     /* Convert BootPath to SystemRoot */
     SystemRoot = strstr(BootPath, "\\");
 
     /* Detect hardware */
-    UiDrawBackdrop();
-    UiDrawProgressBarCenter(20, 100, "Detecting hardware...");
-    LoaderBlock->ConfigurationRoot = MachHwDetect();
+    UiUpdateProgressBar(20, "Detecting hardware...");
+    LoaderBlock->ConfigurationRoot = MachHwDetect(BootOptions);
 
-    if (OperatingSystemVersion == 0)
-        OperatingSystemVersion = WinLdrDetectVersion();
+    /* 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,
@@ -869,18 +1206,31 @@ 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 !!
+ ****/
+
+    UiSetProgressBarSubset(40, 90); // NTOS goes from 25 to 75%
+
     /* Load boot drivers */
-    UiDrawBackdrop();
-    UiDrawProgressBarCenter(100, 100, "Loading boot drivers...");
+    UiSetProgressBarText("Loading boot drivers...");
     Success = WinLdrLoadBootDrivers(LoaderBlock, BootPath);
     TRACE("Boot drivers loading %s\n", Success ? "successful" : "failed");
 
-    /* Cleanup ini file */
-    IniCleanup();
+    UiSetProgressBarSubset(0, 100);
+
+    /* Reset the PE loader import-DLL callback */
+    PeLdrImportDllLoadCallback = NULL;
 
     /* Initialize Phase 1 - no drivers loading anymore */
     WinLdrInitializePhase1(LoaderBlock,
@@ -889,6 +1239,8 @@ LoadAndBootWindowsCommon(
                            BootPath,
                            OperatingSystemVersion);
 
+    UiUpdateProgressBar(100, NULL);
+
     /* Save entry-point pointer and Loader block VAs */
     KiSystemStartup = (KERNEL_ENTRY_POINT)KernelDTE->EntryPoint;
     LoaderBlockVA = PaToVa(LoaderBlock);
@@ -906,7 +1258,7 @@ LoadAndBootWindowsCommon(
     WinLdrSetupMemoryLayout(LoaderBlock);
 
     /* Set processor context */
-    WinLdrSetProcessorContext();
+    WinLdrSetProcessorContext(OperatingSystemVersion);
 
     /* Save final value of LoaderPagesSpanned */
     LoaderBlock->Extension->LoaderPagesSpanned = LoaderPagesSpanned;
@@ -925,7 +1277,8 @@ LoadAndBootWindowsCommon(
 
     /* Pass control */
     (*KiSystemStartup)(LoaderBlockVA);
-    return ESUCCESS;
+
+    UNREACHABLE; // return ESUCCESS;
 }
 
 VOID