https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c322610f6e1a407f3bf2c2a915ab2526b6b9f91d

commit c322610f6e1a407f3bf2c2a915ab2526b6b9f91d
Author:     Hermès Bélusca-Maïto <[email protected]>
AuthorDate: Mon Feb 14 02:28:53 2022 +0100
Commit:     Hermès Bélusca-Maïto <[email protected]>
CommitDate: Mon Feb 21 02:53:54 2022 +0100

    [FREELDR] Improve progress bar support, adapted from Inbv.
    
    - Improve accuracy/progression smoothness when loading drivers.
    - Allow changing text and percentage independently.
---
 boot/freeldr/freeldr/disk/ramdisk.c       |  18 +--
 boot/freeldr/freeldr/include/ui.h         |  95 +++++++++++++--
 boot/freeldr/freeldr/include/ui/minitui.h |  16 ++-
 boot/freeldr/freeldr/include/ui/noui.h    |  19 ++-
 boot/freeldr/freeldr/include/ui/tui.h     |  22 +---
 boot/freeldr/freeldr/linuxboot.c          |   6 +-
 boot/freeldr/freeldr/ntldr/setupldr.c     |   4 +-
 boot/freeldr/freeldr/ntldr/winldr.c       |  27 +++--
 boot/freeldr/freeldr/ntldr/winldr.h       |   2 +
 boot/freeldr/freeldr/ui/directui.c        |  31 -----
 boot/freeldr/freeldr/ui/minitui.c         | 133 ++++++++++++--------
 boot/freeldr/freeldr/ui/noui.c            |  23 +++-
 boot/freeldr/freeldr/ui/tui.c             | 135 +++++++++++++++------
 boot/freeldr/freeldr/ui/ui.c              | 195 ++++++++++++++++++++++++------
 14 files changed, 500 insertions(+), 226 deletions(-)

diff --git a/boot/freeldr/freeldr/disk/ramdisk.c 
b/boot/freeldr/freeldr/disk/ramdisk.c
index 58f8a37d528..6306cad88be 100644
--- a/boot/freeldr/freeldr/disk/ramdisk.c
+++ b/boot/freeldr/freeldr/disk/ramdisk.c
@@ -111,13 +111,12 @@ RamDiskLoadVirtualFile(
     ULONG RamFileId;
     ULONG ChunkSize, Count;
     ULONGLONG TotalRead;
-    PCHAR MsgBuffer = "Loading RamDisk...";
     ULONG PercentPerChunk, Percent;
     FILEINFORMATION Information;
     LARGE_INTEGER Position;
 
     /* Display progress */
-    UiDrawProgressBarCenter(1, 100, MsgBuffer);
+    UiDrawProgressBarCenter("Loading RamDisk...");
 
     /* Try opening the Ramdisk file */
     Status = FsOpenFile(FileName, DefaultPath, OpenReadOnly, &RamFileId);
@@ -135,8 +134,8 @@ RamDiskLoadVirtualFile(
     /* FIXME: For now, limit RAM disks to 4GB */
     if (Information.EndingAddress.HighPart != 0)
     {
-        UiMessageBox("RAM disk too big.");
         ArcClose(RamFileId);
+        UiMessageBox("RAM disk too big.");
         return ENOMEM;
     }
     RamDiskFileSize = Information.EndingAddress.QuadPart;
@@ -145,20 +144,22 @@ RamDiskLoadVirtualFile(
     /* Allocate memory for it */
     ChunkSize = 8 * 1024 * 1024;
     if (RamDiskFileSize < ChunkSize)
-        Percent = PercentPerChunk = 0;
+        PercentPerChunk = 0;
     else
-        Percent = PercentPerChunk = 100 / (RamDiskFileSize / ChunkSize);
+        PercentPerChunk = 100 * ChunkSize / RamDiskFileSize;
     RamDiskBase = MmAllocateMemoryWithType(RamDiskFileSize, LoaderXIPRom);
     if (!RamDiskBase)
     {
-        UiMessageBox("Failed to allocate memory for RAM disk.");
+        RamDiskFileSize = 0;
         ArcClose(RamFileId);
+        UiMessageBox("Failed to allocate memory for RAM disk.");
         return ENOMEM;
     }
 
     /*
      * Read it in chunks
      */
+    Percent = 0;
     for (TotalRead = 0; TotalRead < RamDiskFileSize; TotalRead += ChunkSize)
     {
         /* Check if we're at the last chunk */
@@ -168,8 +169,8 @@ RamDiskLoadVirtualFile(
             ChunkSize = (ULONG)(RamDiskFileSize - TotalRead);
         }
 
-        /* Draw progress */
-        UiDrawProgressBarCenter(Percent, 100, MsgBuffer);
+        /* Update progress */
+        UiUpdateProgressBar(Percent, NULL);
         Percent += PercentPerChunk;
 
         /* Copy the contents */
@@ -194,6 +195,7 @@ RamDiskLoadVirtualFile(
             return ((Status != ESUCCESS) ? Status : EIO);
         }
     }
+    UiUpdateProgressBar(100, NULL);
 
     ArcClose(RamFileId);
 
diff --git a/boot/freeldr/freeldr/include/ui.h 
b/boot/freeldr/freeldr/include/ui.h
index 4308b95c0f4..938192e19b8 100644
--- a/boot/freeldr/freeldr/include/ui.h
+++ b/boot/freeldr/freeldr/include/ui.h
@@ -95,12 +95,74 @@ VOID    UiInfoBox(PCSTR MessageText);                       
     // Displays a i
 VOID    UiMessageBox(PCSTR Format, ...);                        // Displays a 
message box on the screen with an ok button
 VOID    UiMessageBoxCritical(PCSTR MessageText);                // Displays a 
message box on the screen with an ok button using no system resources
 
+
+/* Loading Progress-Bar Functions ********************************************/
+
+/*
+ * Loading progress bar, based on the one from NTOS Inbv.
+ * Supports progress within sub-ranges, used when loading
+ * with an unknown number of steps.
+ */
+typedef struct _UI_PROGRESS_BAR
+{
+    // UI_PROGRESS_STATE
+    struct
+    {
+        ULONG Floor;
+        // ULONG Ceiling;
+        ULONG Bias;
+    } State;
+
+    // BT_PROGRESS_INDICATOR
+    struct
+    {
+        ULONG Count;
+        ULONG Expected;
+        ULONG Percentage;
+    } Indicator;
+
+    ULONG Left;
+    ULONG Top;
+    ULONG Right;
+    ULONG Bottom;
+    // ULONG Width; // == Right - Left + 1;
+    BOOLEAN Show;
+} UI_PROGRESS_BAR, *PUI_PROGRESS_BAR;
+
+extern UI_PROGRESS_BAR UiProgressBar;
+
+VOID
+UiInitProgressBar(
+    _In_ ULONG Left,
+    _In_ ULONG Top,
+    _In_ ULONG Right,
+    _In_ ULONG Bottom,
+    _In_ PCSTR ProgressText);
+
+/* Indicate loading progress without any specific number of steps */
+VOID
+UiIndicateProgress(VOID);
+
+/* Set a progress loading percentage range */
+VOID
+UiSetProgressBarSubset(
+    _In_ ULONG Floor,
+    _In_ ULONG Ceiling);
+
+/* Update the loading progress percentage within a selected range */
+VOID
+UiUpdateProgressBar(
+    _In_ ULONG Percentage,
+    _In_opt_ PCSTR ProgressText);
+
+VOID
+UiSetProgressBarText(
+    _In_ PCSTR ProgressText);
+
 /* Draws the progress bar showing nPos percent filled */
 VOID
 UiDrawProgressBarCenter(
-    _In_ ULONG Position,
-    _In_ ULONG Range,
-    _Inout_z_ PSTR ProgressText);
+    _In_ PCSTR ProgressText);
 
 /* Draws the progress bar showing nPos percent filled */
 VOID
@@ -109,9 +171,8 @@ UiDrawProgressBar(
     _In_ ULONG Top,
     _In_ ULONG Right,
     _In_ ULONG Bottom,
-    _In_ ULONG Position,
-    _In_ ULONG Range,
-    _Inout_z_ PSTR ProgressText);
+    _In_ PCSTR ProgressText);
+
 
 // Displays all the message boxes in a given section.
 VOID
@@ -123,14 +184,11 @@ UiShowMessageBoxesInArgv(
     IN ULONG Argc,
     IN PCHAR Argv[]);
 
-VOID    UiEscapeString(PCHAR String);                            // Processes 
a string and changes all occurrences of "\n" to '\n'
 BOOLEAN    UiEditBox(PCSTR MessageText, PCHAR EditTextBuffer, ULONG Length);
 
 UCHAR    UiTextToColor(PCSTR ColorText);                        // Converts 
the text color into it's equivalent color value
 UCHAR    UiTextToFillStyle(PCSTR FillStyleText);                // Converts 
the text fill into it's equivalent fill value
 
-VOID    UiTruncateStringEllipsis(PCHAR StringText, ULONG MaxChars);    // 
Truncates a string to MaxChars by adding an ellipsis on the end '...'
-
 VOID    UiFadeInBackdrop(VOID);                                    // Draws 
the backdrop and fades the screen in
 VOID    UiFadeOut(VOID);                                        // Fades the 
screen out
 
@@ -200,8 +258,23 @@ typedef struct tagUIVTBL
     VOID (*UpdateDateTime)(VOID);
     VOID (*MessageBox)(PCSTR MessageText);
     VOID (*MessageBoxCritical)(PCSTR MessageText);
-    VOID (*DrawProgressBarCenter)(ULONG Position, ULONG Range, PCHAR 
ProgressText);
-    VOID (*DrawProgressBar)(ULONG Left, ULONG Top, ULONG Right, ULONG Bottom, 
ULONG Position, ULONG Range, PCHAR ProgressText);
+
+    VOID (*DrawProgressBarCenter)(
+        _In_ PCSTR ProgressText);
+
+    VOID (*DrawProgressBar)(
+        _In_ ULONG Left,
+        _In_ ULONG Top,
+        _In_ ULONG Right,
+        _In_ ULONG Bottom,
+        _In_ PCSTR ProgressText);
+
+    VOID (*SetProgressBarText)(
+        _In_ PCSTR ProgressText);
+
+    VOID (*TickProgressBar)(
+        _In_ ULONG SubPercentTimes100);
+
     BOOLEAN (*EditBox)(PCSTR MessageText, PCHAR EditTextBuffer, ULONG Length);
     UCHAR (*TextToColor)(PCSTR ColorText);
     UCHAR (*TextToFillStyle)(PCSTR FillStyleText);
diff --git a/boot/freeldr/freeldr/include/ui/minitui.h 
b/boot/freeldr/freeldr/include/ui/minitui.h
index 4a710cd8b6f..6db89b41cc0 100644
--- a/boot/freeldr/freeldr/include/ui/minitui.h
+++ b/boot/freeldr/freeldr/include/ui/minitui.h
@@ -13,12 +13,18 @@
 VOID MiniTuiDrawBackdrop(VOID);
 VOID MiniTuiDrawStatusText(PCSTR StatusText);
 
+VOID
+MiniTuiSetProgressBarText(
+    _In_ PCSTR ProgressText);
+
+VOID
+MiniTuiTickProgressBar(
+    _In_ ULONG SubPercentTimes100);
+
 /* Draws the progress bar showing nPos percent filled */
 VOID
 MiniTuiDrawProgressBarCenter(
-    _In_ ULONG Position,
-    _In_ ULONG Range,
-    _Inout_z_ PSTR ProgressText);
+    _In_ PCSTR ProgressText);
 
 /* Draws the progress bar showing nPos percent filled */
 VOID
@@ -27,9 +33,7 @@ MiniTuiDrawProgressBar(
     _In_ ULONG Top,
     _In_ ULONG Right,
     _In_ ULONG Bottom,
-    _In_ ULONG Position,
-    _In_ ULONG Range,
-    _Inout_z_ PSTR ProgressText);
+    _In_ PCSTR ProgressText);
 
 /* Menu Functions ************************************************************/
 
diff --git a/boot/freeldr/freeldr/include/ui/noui.h 
b/boot/freeldr/freeldr/include/ui/noui.h
index dca5db172e0..72eca1a9298 100644
--- a/boot/freeldr/freeldr/include/ui/noui.h
+++ b/boot/freeldr/freeldr/include/ui/noui.h
@@ -50,12 +50,20 @@ VOID NoUiUpdateDateTime(VOID);
 VOID NoUiMessageBox(PCSTR MessageText);
 VOID NoUiMessageBoxCritical(PCSTR MessageText);
 
+/* Loading Progress-Bar Functions ********************************************/
+
+VOID
+NoUiSetProgressBarText(
+    _In_ PCSTR ProgressText);
+
+VOID
+NoUiTickProgressBar(
+    _In_ ULONG SubPercentTimes100);
+
 /* Draws the progress bar showing nPos percent filled */
 VOID
 NoUiDrawProgressBarCenter(
-    _In_ ULONG Position,
-    _In_ ULONG Range,
-    _Inout_z_ PSTR ProgressText);
+    _In_ PCSTR ProgressText);
 
 /* Draws the progress bar showing nPos percent filled */
 VOID
@@ -64,9 +72,8 @@ NoUiDrawProgressBar(
     _In_ ULONG Top,
     _In_ ULONG Right,
     _In_ ULONG Bottom,
-    _In_ ULONG Position,
-    _In_ ULONG Range,
-    _Inout_z_ PSTR ProgressText);
+    _In_ PCSTR ProgressText);
+
 
 BOOLEAN NoUiEditBox(PCSTR MessageText, PCHAR EditTextBuffer, ULONG Length);
 UCHAR NoUiTextToColor(PCSTR ColorText);
diff --git a/boot/freeldr/freeldr/include/ui/tui.h 
b/boot/freeldr/freeldr/include/ui/tui.h
index 27918f47bd7..b952a06822d 100644
--- a/boot/freeldr/freeldr/include/ui/tui.h
+++ b/boot/freeldr/freeldr/include/ui/tui.h
@@ -25,6 +25,10 @@ INT
 TuiPrintf(
     _In_ PCSTR Format, ...);
 
+VOID
+TuiTruncateStringEllipsis(
+    _Inout_z_ PSTR StringText,
+    _In_ ULONG MaxChars);
 
 #define TUI_TITLE_BOX_CHAR_HEIGHT    5
 
@@ -72,24 +76,6 @@ VOID    TuiRestoreScreen(PUCHAR Buffer);                     
   // Restores the
 VOID    TuiMessageBox(PCSTR MessageText);                        // Displays a 
message box on the screen with an ok button
 VOID    TuiMessageBoxCritical(PCSTR MessageText);                // Displays a 
message box on the screen with an ok button using no system resources
 
-/* Draws the progress bar showing nPos percent filled */
-VOID
-TuiDrawProgressBarCenter(
-    _In_ ULONG Position,
-    _In_ ULONG Range,
-    _Inout_z_ PSTR ProgressText);
-
-/* Draws the progress bar showing nPos percent filled */
-VOID
-TuiDrawProgressBar(
-    _In_ ULONG Left,
-    _In_ ULONG Top,
-    _In_ ULONG Right,
-    _In_ ULONG Bottom,
-    _In_ ULONG Position,
-    _In_ ULONG Range,
-    _Inout_z_ PSTR ProgressText);
-
 BOOLEAN    TuiEditBox(PCSTR MessageText, PCHAR EditTextBuffer, ULONG Length);
 UCHAR    TuiTextToColor(PCSTR ColorText);                        // Converts 
the text color into it's equivalent color value
 UCHAR    TuiTextToFillStyle(PCSTR FillStyleText);                // Converts 
the text fill into it's equivalent fill value
diff --git a/boot/freeldr/freeldr/linuxboot.c b/boot/freeldr/freeldr/linuxboot.c
index fae1f8da6a2..5375aafe796 100644
--- a/boot/freeldr/freeldr/linuxboot.c
+++ b/boot/freeldr/freeldr/linuxboot.c
@@ -107,7 +107,7 @@ LoadAndBootLinux(
 
     UiDrawBackdrop();
     UiDrawStatusText(LinuxBootDescription);
-    UiDrawProgressBarCenter(0, 100, LinuxBootDescription);
+    UiDrawProgressBarCenter(LinuxBootDescription);
 
     /* Find all the message box settings and run them */
     UiShowMessageBoxesInArgv(Argc, Argv);
@@ -445,7 +445,7 @@ static BOOLEAN LinuxReadKernel(ULONG LinuxKernelFile)
         BytesLoaded += LINUX_READ_CHUNK_SIZE;
         LoadAddress = (PVOID)((ULONG_PTR)LoadAddress + LINUX_READ_CHUNK_SIZE);
 
-        UiDrawProgressBarCenter(BytesLoaded, LinuxKernelSize + 
LinuxInitrdSize, LinuxBootDescription);
+        UiUpdateProgressBar(BytesLoaded * 100 / (LinuxKernelSize + 
LinuxInitrdSize), NULL);
     }
 
     return TRUE;
@@ -540,7 +540,7 @@ static BOOLEAN LinuxReadInitrd(ULONG LinuxInitrdFile)
         BytesLoaded += LINUX_READ_CHUNK_SIZE;
         LinuxInitrdLoadAddress = (PVOID)((ULONG_PTR)LinuxInitrdLoadAddress + 
LINUX_READ_CHUNK_SIZE);
 
-        UiDrawProgressBarCenter(BytesLoaded + LinuxKernelSize, LinuxInitrdSize 
+ LinuxKernelSize, LinuxBootDescription);
+        UiUpdateProgressBar((BytesLoaded + LinuxKernelSize) * 100 / 
(LinuxInitrdSize + LinuxKernelSize), NULL);
     }
 
     return TRUE;
diff --git a/boot/freeldr/freeldr/ntldr/setupldr.c 
b/boot/freeldr/freeldr/ntldr/setupldr.c
index 2deaf6ce5ba..f7a330be2fd 100644
--- a/boot/freeldr/freeldr/ntldr/setupldr.c
+++ b/boot/freeldr/freeldr/ntldr/setupldr.c
@@ -493,7 +493,7 @@ LoadReactOSSetup(
     /* Let the user know we started loading */
     UiDrawBackdrop();
     UiDrawStatusText("Setup is loading...");
-    UiDrawProgressBarCenter(1, 100, "Loading ReactOS Setup...");
+    UiDrawProgressBarCenter("Loading ReactOS Setup...");
 
     /* Retrieve the system path */
     *BootPath = ANSI_NULL;
@@ -743,7 +743,7 @@ LoadReactOSSetup(
     SetupBlock->Flags = SETUPLDR_TEXT_MODE;
 
     /* Load the "setupreg.hiv" setup system hive */
-    if (!SosEnabled) UiDrawProgressBarCenter(15, 100, "Loading setup system 
hive...");
+    UiUpdateProgressBar(15, "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 317d59a35bd..5b06bef6e0f 100644
--- a/boot/freeldr/freeldr/ntldr/winldr.c
+++ b/boot/freeldr/freeldr/ntldr/winldr.c
@@ -66,7 +66,8 @@ NtLdrOutputLoadMsg(
         RtlStringCbPrintfA(ProgressString, sizeof(ProgressString),
                            "Loading %s...",
                            (Description ? Description : FileName));
-        // UiDrawProgressBarCenter(1, 100, ProgressString);
+        // UiSetProgressBarText(ProgressString);
+        // UiIndicateProgress();
         UiDrawStatusText(ProgressString);
     }
 }
@@ -379,12 +380,12 @@ WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,
         // Paths are relative (FIXME: Are they always relative?)
 
         // 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
@@ -503,7 +504,7 @@ LoadModule(
     PVOID BaseAddress;
 
     RtlStringCbPrintfA(ProgressString, sizeof(ProgressString), "Loading 
%s...", File);
-    if (!SosEnabled) UiDrawProgressBarCenter(Percentage, 100, ProgressString);
+    UiUpdateProgressBar(Percentage, ProgressString);
 
     RtlStringCbCopyA(FullFileName, sizeof(FullFileName), Path);
     RtlStringCbCatA(FullFileName, sizeof(FullFileName), File);
@@ -609,7 +610,7 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion,
 
     /* Load the HAL */
     HalBase = LoadModule(LoaderBlock, DirPath, HalFileName,
-                         "hal.dll", LoaderHalCode, &HalDTE, 45);
+                         "hal.dll", LoaderHalCode, &HalDTE, 35);
     if (!HalBase)
     {
         ERR("LoadModule('%s') failed\n", HalFileName);
@@ -684,7 +685,7 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion,
 
         /* Load the KD DLL. Override its base DLL name to the default 
"KDCOM.DLL". */
         KdDllBase = LoadModule(LoaderBlock, DirPath, KdDllName,
-                               "kdcom.dll", LoaderSystemCode, &KdDllDTE, 60);
+                               "kdcom.dll", LoaderSystemCode, &KdDllDTE, 40);
         if (!KdDllBase)
         {
             /* If we failed to load a custom KD DLL, fall back to the standard 
one */
@@ -697,7 +698,7 @@ LoadWindowsCore(IN USHORT OperatingSystemVersion,
                 RtlStringCbCopyA(KdDllName, sizeof(KdDllName), "kdcom.dll");
 
                 KdDllBase = LoadModule(LoaderBlock, DirPath, KdDllName,
-                                       "kdcom.dll", LoaderSystemCode, 
&KdDllDTE, 60);
+                                       "kdcom.dll", LoaderSystemCode, 
&KdDllDTE, 40);
             }
 
             if (!KdDllBase)
@@ -939,7 +940,7 @@ LoadAndBootWindows(
     /* Let the user know we started loading */
     UiDrawBackdrop();
     UiDrawStatusText("Loading...");
-    UiDrawProgressBarCenter(1, 100, "Loading NT...");
+    UiDrawProgressBarCenter("Loading NT...");
 
     /* Retrieve the system path */
     *BootPath = ANSI_NULL;
@@ -1043,7 +1044,7 @@ LoadAndBootWindows(
     AllocateAndInitLPB(OperatingSystemVersion, &LoaderBlock);
 
     /* Load the system hive */
-    if (!SosEnabled) 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 */
@@ -1101,7 +1102,7 @@ LoadAndBootWindowsCommon(
     SystemRoot = strstr(BootPath, "\\");
 
     /* Detect hardware */
-    if (!SosEnabled) UiDrawProgressBarCenter(20, 100, "Detecting hardware...");
+    UiUpdateProgressBar(20, "Detecting hardware...");
     LoaderBlock->ConfigurationRoot = MachHwDetect();
 
     /* Initialize the PE loader import-DLL callback, so that we can obtain
@@ -1130,11 +1131,15 @@ LoadAndBootWindowsCommon(
  **** WE HAVE NOW REACHED THE POINT OF NO RETURN !!
  ****/
 
+    UiSetProgressBarSubset(40, 90); // NTOS goes from 25 to 75%
+
     /* Load boot drivers */
-    if (!SosEnabled) UiDrawProgressBarCenter(100, 100, "Loading boot 
drivers...");
+    UiSetProgressBarText("Loading boot drivers...");
     Success = WinLdrLoadBootDrivers(LoaderBlock, BootPath);
     TRACE("Boot drivers loading %s\n", Success ? "successful" : "failed");
 
+    UiSetProgressBarSubset(0, 100);
+
     /* Reset the PE loader import-DLL callback */
     PeLdrImportDllLoadCallback = NULL;
 
@@ -1145,6 +1150,8 @@ LoadAndBootWindowsCommon(
                            BootPath,
                            OperatingSystemVersion);
 
+    UiUpdateProgressBar(100, NULL);
+
     /* Save entry-point pointer and Loader block VAs */
     KiSystemStartup = (KERNEL_ENTRY_POINT)KernelDTE->EntryPoint;
     LoaderBlockVA = PaToVa(LoaderBlock);
diff --git a/boot/freeldr/freeldr/ntldr/winldr.h 
b/boot/freeldr/freeldr/ntldr/winldr.h
index 03cc68f88c7..38598e29f85 100644
--- a/boot/freeldr/freeldr/ntldr/winldr.h
+++ b/boot/freeldr/freeldr/ntldr/winldr.h
@@ -88,6 +88,8 @@ UiResetForSOS(VOID)
     UiVtbl = MiniTuiVtbl;
     UiVtbl.Initialize();
 #endif
+    /* Disable the progress bar */
+    UiProgressBar.Show = FALSE;
 }
 
 VOID
diff --git a/boot/freeldr/freeldr/ui/directui.c 
b/boot/freeldr/freeldr/ui/directui.c
index dbd2ed41902..68d67777190 100644
--- a/boot/freeldr/freeldr/ui/directui.c
+++ b/boot/freeldr/freeldr/ui/directui.c
@@ -111,28 +111,6 @@ UiMessageBoxCritical(IN PCSTR MessageText)
     TuiPrintf(MessageText);
 }
 
-VOID
-UiDrawProgressBarCenter(
-    _In_ ULONG Position,
-    _In_ ULONG Range,
-    _Inout_z_ PSTR ProgressText)
-{
-    MiniTuiDrawProgressBarCenter(Position, Range, ProgressText);
-}
-
-VOID
-UiDrawProgressBar(
-    _In_ ULONG Left,
-    _In_ ULONG Top,
-    _In_ ULONG Right,
-    _In_ ULONG Bottom,
-    _In_ ULONG Position,
-    _In_ ULONG Range,
-    _Inout_z_ PSTR ProgressText)
-{
-    MiniTuiDrawProgressBar(Left, Top, Right, Bottom, Position, Range, 
ProgressText);
-}
-
 VOID
 UiShowMessageBoxesInSection(
     IN ULONG_PTR SectionId)
@@ -148,15 +126,6 @@ UiShowMessageBoxesInArgv(
     return;
 }
 
-VOID
-UiTruncateStringEllipsis(IN PCHAR StringText,
-                         IN ULONG MaxChars)
-{
-    /* If it's too large, just add some ellipsis past the maximum */
-    if (strlen(StringText) > MaxChars)
-        strcpy(&StringText[MaxChars - 3], "...");
-}
-
 VOID
 UiDrawMenu(
     _In_ PUI_MENU_INFO MenuInfo)
diff --git a/boot/freeldr/freeldr/ui/minitui.c 
b/boot/freeldr/freeldr/ui/minitui.c
index 373605a8b1b..ae2ae004fa3 100644
--- a/boot/freeldr/freeldr/ui/minitui.c
+++ b/boot/freeldr/freeldr/ui/minitui.c
@@ -31,11 +31,85 @@ VOID MiniTuiDrawStatusText(PCSTR StatusText)
 
 #endif // _M_ARM
 
+/*static*/ VOID
+MiniTuiSetProgressBarText(
+    _In_ PCSTR ProgressText)
+{
+    ULONG ProgressBarWidth;
+    CHAR ProgressString[256];
+
+    /* Make sure the progress bar is enabled */
+    ASSERT(UiProgressBar.Show);
+
+    /* Calculate the width of the bar proper */
+    ProgressBarWidth = UiProgressBar.Right - UiProgressBar.Left + 1;
+
+    /* First make sure the progress bar text fits */
+    RtlStringCbCopyA(ProgressString, sizeof(ProgressString), ProgressText);
+    TuiTruncateStringEllipsis(ProgressString, ProgressBarWidth);
+
+    /* Clear the text area */
+    TuiFillArea(UiProgressBar.Left, UiProgressBar.Top,
+                UiProgressBar.Right,
+#ifdef NTLDR_PROGRESSBAR
+                UiProgressBar.Bottom - 1,
+#else // BTMGR_PROGRESSBAR
+                UiProgressBar.Bottom - 2, // One empty line between text and 
bar.
+#endif
+                ' ', ATTR(UiTextColor, UiMenuBgColor));
+
+    /* Draw the "Loading..." text */
+    TuiDrawCenteredText(UiProgressBar.Left, UiProgressBar.Top,
+                        UiProgressBar.Right,
+#ifdef NTLDR_PROGRESSBAR
+                        UiProgressBar.Bottom - 1,
+#else // BTMGR_PROGRESSBAR
+                        UiProgressBar.Bottom - 2, // One empty line between 
text and bar.
+#endif
+                        ProgressString, ATTR(UiTextColor, UiMenuBgColor));
+}
+
+/*static*/ VOID
+MiniTuiTickProgressBar(
+    _In_ ULONG SubPercentTimes100)
+{
+    ULONG ProgressBarWidth;
+    ULONG FillCount;
+
+    /* Make sure the progress bar is enabled */
+    ASSERT(UiProgressBar.Show);
+
+    ASSERT(SubPercentTimes100 <= (100 * 100));
+
+    /* Calculate the width of the bar proper */
+    ProgressBarWidth = UiProgressBar.Right - UiProgressBar.Left + 1;
+
+    /* Compute fill count */
+    // FillCount = (ProgressBarWidth * Position) / Range;
+    FillCount = ProgressBarWidth * SubPercentTimes100 / (100 * 100);
+
+    /* Fill the progress bar */
+    /* Draw the percent complete -- Use the fill character */
+    if (FillCount > 0)
+    {
+        TuiFillArea(UiProgressBar.Left, UiProgressBar.Bottom,
+                    UiProgressBar.Left + FillCount - 1, UiProgressBar.Bottom,
+                    '\xDB', ATTR(UiTextColor, UiMenuBgColor));
+    }
+    /* Fill the remaining with blanks */
+    TuiFillArea(UiProgressBar.Left + FillCount, UiProgressBar.Bottom,
+                UiProgressBar.Right, UiProgressBar.Bottom,
+                ' ', ATTR(UiTextColor, UiMenuBgColor));
+
+#ifndef _M_ARM
+    TuiUpdateDateTime();
+    VideoCopyOffScreenBufferToVRAM();
+#endif
+}
+
 VOID
 MiniTuiDrawProgressBarCenter(
-    _In_ ULONG Position,
-    _In_ ULONG Range,
-    _Inout_z_ PSTR ProgressText)
+    _In_ PCSTR ProgressText)
 {
     ULONG Left, Top, Right, Bottom, Width, Height;
 
@@ -55,7 +129,7 @@ MiniTuiDrawProgressBarCenter(
     Bottom = Top + Height - 1;
 
     /* Draw the progress bar */
-    MiniTuiDrawProgressBar(Left, Top, Right, Bottom, Position, Range, 
ProgressText);
+    MiniTuiDrawProgressBar(Left, Top, Right, Bottom, ProgressText);
 }
 
 VOID
@@ -64,54 +138,9 @@ MiniTuiDrawProgressBar(
     _In_ ULONG Top,
     _In_ ULONG Right,
     _In_ ULONG Bottom,
-    _In_ ULONG Position,
-    _In_ ULONG Range,
-    _Inout_z_ PSTR ProgressText)
+    _In_ PCSTR ProgressText)
 {
-    ULONG ProgressBarWidth, i;
-
-    /* Calculate the width of the bar proper */
-    ProgressBarWidth = Right - Left + 1;
-
-    /* Clip the position */
-    if (Position > Range)
-        Position = Range;
-
-    /* First make sure the progress bar text fits */
-    UiTruncateStringEllipsis(ProgressText, ProgressBarWidth);
-
-    /* Clear the text area */
-    TuiFillArea(Left, Top, Right,
-#ifdef NTLDR_PROGRESSBAR
-                Bottom - 1,
-#else // BTMGR_PROGRESSBAR
-                Bottom - 2, // One empty line between text and bar.
-#endif
-                ' ', ATTR(UiTextColor, UiMenuBgColor));
-
-    /* Draw the "Loading..." text */
-    TuiDrawCenteredText(Left, Top, Right,
-#ifdef NTLDR_PROGRESSBAR
-                        Bottom - 1,
-#else // BTMGR_PROGRESSBAR
-                        Bottom - 2, // One empty line between text and bar.
-#endif
-                        ProgressText, ATTR(UiTextColor, UiMenuBgColor));
-
-    /* Draw the percent complete -- Use the fill character */
-    for (i = 0; i < (Position * ProgressBarWidth) / Range; i++)
-    {
-        TuiDrawText(Left + i, Bottom,
-                    "\xDB", ATTR(UiTextColor, UiMenuBgColor));
-    }
-    /* Fill the remaining with blanks */
-    TuiFillArea(Left + i, Bottom, Right, Bottom,
-                ' ', ATTR(UiTextColor, UiMenuBgColor));
-
-#ifndef _M_ARM
-    TuiUpdateDateTime();
-    VideoCopyOffScreenBufferToVRAM();
-#endif
+    UiInitProgressBar(Left, Top, Right, Bottom, ProgressText);
 }
 
 VOID
@@ -192,6 +221,8 @@ const UIVTBL MiniTuiVtbl =
     TuiMessageBoxCritical,
     MiniTuiDrawProgressBarCenter,
     MiniTuiDrawProgressBar,
+    MiniTuiSetProgressBarText,
+    MiniTuiTickProgressBar,
     TuiEditBox,
     TuiTextToColor,
     TuiTextToFillStyle,
diff --git a/boot/freeldr/freeldr/ui/noui.c b/boot/freeldr/freeldr/ui/noui.c
index 5e083dd8be0..5bc33d70e69 100644
--- a/boot/freeldr/freeldr/ui/noui.c
+++ b/boot/freeldr/freeldr/ui/noui.c
@@ -100,11 +100,23 @@ VOID NoUiMessageBoxCritical(PCSTR MessageText)
     MachConsGetCh();
 }
 
+/* Loading Progress-Bar Functions ********************************************/
+
+VOID
+NoUiSetProgressBarText(
+    _In_ PCSTR ProgressText)
+{
+}
+
+VOID
+NoUiTickProgressBar(
+    _In_ ULONG SubPercentTimes100)
+{
+}
+
 VOID
 NoUiDrawProgressBarCenter(
-    _In_ ULONG Position,
-    _In_ ULONG Range,
-    _Inout_z_ PSTR ProgressText)
+    _In_ PCSTR ProgressText)
 {
 }
 
@@ -114,12 +126,11 @@ NoUiDrawProgressBar(
     _In_ ULONG Top,
     _In_ ULONG Right,
     _In_ ULONG Bottom,
-    _In_ ULONG Position,
-    _In_ ULONG Range,
-    _Inout_z_ PSTR ProgressText)
+    _In_ PCSTR ProgressText)
 {
 }
 
+
 BOOLEAN NoUiEditBox(PCSTR MessageText, PCHAR EditTextBuffer, ULONG Length)
 {
     return FALSE;
diff --git a/boot/freeldr/freeldr/ui/tui.c b/boot/freeldr/freeldr/ui/tui.c
index bcf510ed7c8..3950f93df2d 100644
--- a/boot/freeldr/freeldr/ui/tui.c
+++ b/boot/freeldr/freeldr/ui/tui.c
@@ -53,6 +53,16 @@ TuiPrintf(
     return Length;
 }
 
+VOID
+TuiTruncateStringEllipsis(
+    _Inout_z_ PSTR StringText,
+    _In_ ULONG MaxChars)
+{
+    /* If it's too large, just add some ellipsis past the maximum */
+    if (strlen(StringText) > MaxChars)
+        strcpy(&StringText[MaxChars - 3], "...");
+}
+
 /*
  * DrawText()
  * Displays a string on a single screen line.
@@ -690,11 +700,83 @@ VOID TuiMessageBoxCritical(PCSTR MessageText)
     }
 }
 
-VOID
+static VOID
+TuiSetProgressBarText(
+    _In_ PCSTR ProgressText)
+{
+    ULONG ProgressBarWidth;
+    CHAR ProgressString[256];
+
+    /* Make sure the progress bar is enabled */
+    ASSERT(UiProgressBar.Show);
+
+    /* Calculate the width of the bar proper */
+    ProgressBarWidth = UiProgressBar.Right - UiProgressBar.Left + 1;
+
+    /* First make sure the progress bar text fits */
+    RtlStringCbCopyA(ProgressString, sizeof(ProgressString), ProgressText);
+    TuiTruncateStringEllipsis(ProgressString, ProgressBarWidth);
+
+    /* Clear the text area */
+    TuiFillArea(UiProgressBar.Left, UiProgressBar.Top,
+                UiProgressBar.Right, UiProgressBar.Bottom - 1,
+                ' ', ATTR(UiTextColor, UiMenuBgColor));
+
+    /* Draw the "Loading..." text */
+    TuiDrawCenteredText(UiProgressBar.Left, UiProgressBar.Top,
+                        UiProgressBar.Right, UiProgressBar.Bottom - 1,
+                        ProgressString, ATTR(UiTextColor, UiMenuBgColor));
+}
+
+static VOID
+TuiTickProgressBar(
+    _In_ ULONG SubPercentTimes100)
+{
+    ULONG ProgressBarWidth;
+    ULONG FillCount;
+
+    /* Make sure the progress bar is enabled */
+    ASSERT(UiProgressBar.Show);
+
+    ASSERT(SubPercentTimes100 <= (100 * 100));
+
+    /* Calculate the width of the bar proper */
+    ProgressBarWidth = UiProgressBar.Right - UiProgressBar.Left + 1;
+
+    /* Compute fill count */
+    // FillCount = (ProgressBarWidth * Position) / Range;
+    FillCount = ProgressBarWidth * SubPercentTimes100 / (100 * 100);
+
+    /* Fill the progress bar */
+    /* Draw the percent complete -- Use the fill character */
+    if (FillCount > 0)
+    {
+        TuiFillArea(UiProgressBar.Left, UiProgressBar.Bottom,
+                    UiProgressBar.Left + FillCount - 1, UiProgressBar.Bottom,
+                    '\xDB', ATTR(UiTextColor, UiMenuBgColor));
+    }
+    /* Fill the remaining with shadow blanks */
+    TuiFillArea(UiProgressBar.Left + FillCount, UiProgressBar.Bottom,
+                UiProgressBar.Right, UiProgressBar.Bottom,
+                '\xB2', ATTR(UiTextColor, UiMenuBgColor));
+
+#ifndef _M_ARM
+    TuiUpdateDateTime();
+    VideoCopyOffScreenBufferToVRAM();
+#endif
+}
+
+static VOID
+TuiDrawProgressBar(
+    _In_ ULONG Left,
+    _In_ ULONG Top,
+    _In_ ULONG Right,
+    _In_ ULONG Bottom,
+    _In_ PCSTR ProgressText);
+
+static VOID
 TuiDrawProgressBarCenter(
-    _In_ ULONG Position,
-    _In_ ULONG Range,
-    _Inout_z_ PSTR ProgressText)
+    _In_ PCSTR ProgressText)
 {
     ULONG Left, Top, Right, Bottom, Width, Height;
 
@@ -713,23 +795,21 @@ TuiDrawProgressBarCenter(
     Bottom += 1;
 
     /* Draw the progress bar */
-    TuiDrawProgressBar(Left, Top, Right, Bottom, Position, Range, 
ProgressText);
+    TuiDrawProgressBar(Left, Top, Right, Bottom, ProgressText);
 }
 
-VOID
+static VOID
 TuiDrawProgressBar(
     _In_ ULONG Left,
     _In_ ULONG Top,
     _In_ ULONG Right,
     _In_ ULONG Bottom,
-    _In_ ULONG Position,
-    _In_ ULONG Range,
-    _Inout_z_ PSTR ProgressText)
+    _In_ PCSTR ProgressText)
 {
-    ULONG ProgressBarWidth, i;
-
     /* Draw the box */
-    TuiDrawBox(Left, Top, Right, Bottom, VERT, HORZ, TRUE, TRUE, 
ATTR(UiMenuFgColor, UiMenuBgColor));
+    TuiDrawBox(Left, Top, Right, Bottom,
+               VERT, HORZ, TRUE, TRUE,
+               ATTR(UiMenuFgColor, UiMenuBgColor));
 
     /* Exclude the box margins */
     Left += 2;
@@ -737,34 +817,7 @@ TuiDrawProgressBar(
     Top += 1;
     Bottom -= 1;
 
-    /* Calculate the width of the bar proper */
-    ProgressBarWidth = Right - Left + 1;
-
-    /* Clip the position */
-    if (Position > Range)
-        Position = Range;
-
-    /* First make sure the progress bar text fits */
-    UiTruncateStringEllipsis(ProgressText, ProgressBarWidth);
-
-    /* Draw the "Loading..." text */
-    TuiDrawCenteredText(Left, Top, Right, Bottom - 1,
-                        ProgressText, ATTR(UiTextColor, UiMenuBgColor));
-
-    /* Draw the percent complete -- Use the fill character */
-    for (i = 0; i < (Position * ProgressBarWidth) / Range; i++)
-    {
-        TuiDrawText(Left + i, Bottom,
-                    "\xDB", ATTR(UiTextColor, UiMenuBgColor));
-    }
-    /* Fill the remaining with shadow blanks */
-    TuiFillArea(Left + i, Bottom, Right, Bottom,
-                '\xB2', ATTR(UiTextColor, UiMenuBgColor));
-
-#ifndef _M_ARM
-    TuiUpdateDateTime();
-    VideoCopyOffScreenBufferToVRAM();
-#endif
+    UiInitProgressBar(Left, Top, Right, Bottom, ProgressText);
 }
 
 UCHAR TuiTextToColor(PCSTR ColorText)
@@ -1135,6 +1188,8 @@ const UIVTBL TuiVtbl =
     TuiMessageBoxCritical,
     TuiDrawProgressBarCenter,
     TuiDrawProgressBar,
+    TuiSetProgressBarText,
+    TuiTickProgressBar,
     TuiEditBox,
     TuiTextToColor,
     TuiTextToFillStyle,
diff --git a/boot/freeldr/freeldr/ui/ui.c b/boot/freeldr/freeldr/ui/ui.c
index b2a08f27c9f..7d13d81ef16 100644
--- a/boot/freeldr/freeldr/ui/ui.c
+++ b/boot/freeldr/freeldr/ui/ui.c
@@ -16,13 +16,14 @@
  *  with this program; if not, write to the Free Software Foundation, Inc.,
  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
-#ifndef _M_ARM
 
 #include <freeldr.h>
 
 #include <debug.h>
 DBG_DEFAULT_CHANNEL(UI);
 
+#ifndef _M_ARM
+
 #define TAG_UI_TEXT 'xTiU'
 
 ULONG UiScreenWidth;    // Screen Width
@@ -55,6 +56,17 @@ CHAR    UiTimeText[260] = "[Time Remaining: ] ";
 
 const CHAR UiMonthNames[12][15] = { "January ", "February ", "March ", "April 
", "May ", "June ", "July ", "August ", "September ", "October ", "November ", 
"December " };
 
+#endif // _M_ARM
+
+/*
+ * Loading progress bar, based on the NTOS Inbv one.
+ * Supports progress within sub-ranges, used when loading
+ * with an unknown number of steps.
+ */
+UI_PROGRESS_BAR UiProgressBar = {{0}};
+
+#ifndef _M_ARM
+
 UIVTBL UiVtbl =
 {
     NoUiInitialize,
@@ -72,6 +84,8 @@ UIVTBL UiVtbl =
     NoUiMessageBoxCritical,
     NoUiDrawProgressBarCenter,
     NoUiDrawProgressBar,
+    NoUiSetProgressBarText,
+    NoUiTickProgressBar,
     NoUiEditBox,
     NoUiTextToColor,
     NoUiTextToFillStyle,
@@ -369,13 +383,128 @@ UCHAR UiTextToFillStyle(PCSTR FillStyleText)
     return UiVtbl.TextToFillStyle(FillStyleText);
 }
 
+#endif // _M_ARM
+
+VOID
+UiInitProgressBar(
+    _In_ ULONG Left,
+    _In_ ULONG Top,
+    _In_ ULONG Right,
+    _In_ ULONG Bottom,
+    _In_ PCSTR ProgressText)
+{
+    /* Progress bar area */
+    UiProgressBar.Left = Left;
+    UiProgressBar.Top  = Top;
+    UiProgressBar.Right  = Right;
+    UiProgressBar.Bottom = Bottom;
+    // UiProgressBar.Width = Right - Left + 1;
+
+    /* Set the progress bar ranges */
+    UiSetProgressBarSubset(0, 100);
+    UiProgressBar.Indicator.Count = 0;
+    UiProgressBar.Indicator.Expected = 25;
+    UiProgressBar.Indicator.Percentage = 0;
+
+    /* Enable the progress bar */
+    UiProgressBar.Show = TRUE;
+
+    /* Initial drawing: set the "Loading..." text and the original position */
+#ifndef _M_ARM
+    UiVtbl.SetProgressBarText(ProgressText);
+    UiVtbl.TickProgressBar(0);
+#else
+    MiniTuiSetProgressBarText(ProgressText);
+    MiniTuiTickProgressBar(0);
+#endif
+}
+
+VOID
+UiIndicateProgress(VOID)
+{
+    ULONG Percentage;
+
+    /* Increase progress */
+    UiProgressBar.Indicator.Count++;
+
+    /* Compute the new percentage - Don't go over 100% */
+    Percentage = 100 * UiProgressBar.Indicator.Count /
+                       UiProgressBar.Indicator.Expected;
+    Percentage = min(Percentage, 99);
+
+    if (Percentage != UiProgressBar.Indicator.Percentage)
+    {
+        /* Percentage has changed, update the progress bar */
+        UiProgressBar.Indicator.Percentage = Percentage;
+        UiUpdateProgressBar(Percentage, NULL);
+    }
+}
+
+VOID
+UiSetProgressBarSubset(
+    _In_ ULONG Floor,
+    _In_ ULONG Ceiling)
+{
+    /* Sanity checks */
+    ASSERT(Floor < Ceiling);
+    ASSERT(Ceiling <= 100);
+
+    /* Update the progress bar state */
+    UiProgressBar.State.Floor = Floor * 100;
+    // UiProgressBar.State.Ceiling = Ceiling * 100;
+    UiProgressBar.State.Bias = Ceiling - Floor;
+}
+
+VOID
+UiUpdateProgressBar(
+    _In_ ULONG Percentage,
+    _In_opt_ PCSTR ProgressText)
+{
+    ULONG TotalProgress;
+
+    /* Make sure the progress bar is enabled */
+    if (!UiProgressBar.Show)
+        return;
+
+    /* Set the progress text if specified */
+    if (ProgressText)
+        UiSetProgressBarText(ProgressText);
+
+    /* Compute the total progress and tick the progress bar */
+    TotalProgress = UiProgressBar.State.Floor + (Percentage * 
UiProgressBar.State.Bias);
+    // TotalProgress /= (100 * 100);
+
+#ifndef _M_ARM
+    UiVtbl.TickProgressBar(TotalProgress);
+#else
+    MiniTuiTickProgressBar(TotalProgress);
+#endif
+}
+
+VOID
+UiSetProgressBarText(
+    _In_ PCSTR ProgressText)
+{
+    /* Make sure the progress bar is enabled */
+    if (!UiProgressBar.Show)
+        return;
+
+#ifndef _M_ARM
+    UiVtbl.SetProgressBarText(ProgressText);
+#else
+    MiniTuiSetProgressBarText(ProgressText);
+#endif
+}
+
 VOID
 UiDrawProgressBarCenter(
-    _In_ ULONG Position,
-    _In_ ULONG Range,
-    _Inout_z_ PSTR ProgressText)
+    _In_ PCSTR ProgressText)
 {
-    UiVtbl.DrawProgressBarCenter(Position, Range, ProgressText);
+#ifndef _M_ARM
+    UiVtbl.DrawProgressBarCenter(ProgressText);
+#else
+    MiniTuiDrawProgressBarCenter(ProgressText);
+#endif
 }
 
 VOID
@@ -384,11 +513,34 @@ UiDrawProgressBar(
     _In_ ULONG Top,
     _In_ ULONG Right,
     _In_ ULONG Bottom,
-    _In_ ULONG Position,
-    _In_ ULONG Range,
-    _Inout_z_ PSTR ProgressText)
+    _In_ PCSTR ProgressText)
 {
-    UiVtbl.DrawProgressBar(Left, Top, Right, Bottom, Position, Range, 
ProgressText);
+#ifndef _M_ARM
+    UiVtbl.DrawProgressBar(Left, Top, Right, Bottom, ProgressText);
+#else
+    MiniTuiDrawProgressBar(Left, Top, Right, Bottom, ProgressText);
+#endif
+}
+
+#ifndef _M_ARM
+
+static VOID
+UiEscapeString(PCHAR String)
+{
+    ULONG    Idx;
+
+    for (Idx=0; Idx<strlen(String); Idx++)
+    {
+        // Escape the new line characters
+        if (String[Idx] == '\\' && String[Idx+1] == 'n')
+        {
+            // Escape the character
+            String[Idx] = '\n';
+
+            // Move the rest of the string up
+            strcpy(&String[Idx+1], &String[Idx+2]);
+        }
+    }
 }
 
 VOID
@@ -472,31 +624,6 @@ UiShowMessageBoxesInArgv(
     }
 }
 
-VOID UiEscapeString(PCHAR String)
-{
-    ULONG    Idx;
-
-    for (Idx=0; Idx<strlen(String); Idx++)
-    {
-        // Escape the new line characters
-        if (String[Idx] == '\\' && String[Idx+1] == 'n')
-        {
-            // Escape the character
-            String[Idx] = '\n';
-
-            // Move the rest of the string up
-            strcpy(&String[Idx+1], &String[Idx+2]);
-        }
-    }
-}
-
-VOID UiTruncateStringEllipsis(PCHAR StringText, ULONG MaxChars)
-{
-    /* If it's too large, just add some ellipsis past the maximum */
-    if (strlen(StringText) > MaxChars)
-        strcpy(&StringText[MaxChars - 3], "...");
-}
-
 BOOLEAN
 UiDisplayMenu(
     IN PCSTR MenuHeader,

Reply via email to