[CALC] Fix input bug when display is in error. (#5988)
[reactos.git] / ntoskrnl / inbv / inbv.c
index a99677c..006f96a 100644 (file)
+/*
+ * PROJECT:     ReactOS Kernel
+ * LICENSE:     BSD - See COPYING.ARM in the top level directory
+ * PURPOSE:     Boot Video Driver support
+ * COPYRIGHT:   Copyright 2007 Alex Ionescu (alex.ionescu@reactos.org)
+ *              Copyright 2010 Aleksey Bragin (aleksey@reactos.org)
+ *              Copyright 2015-2022 Hermès Bélusca-Maïto
+ */
+
 /* INCLUDES ******************************************************************/
 
 #include <ntoskrnl.h>
-#define NDEBUG
-#include <debug.h>
-#include "bootvid/bootvid.h"
+#include "inbv/logo.h"
 
 /* GLOBALS *******************************************************************/
 
-KSPIN_LOCK BootDriverLock;
-KIRQL InbvOldIrql;
-INBV_DISPLAY_STATE InbvDisplayState;
-BOOLEAN InbvBootDriverInstalled = FALSE;
-BOOLEAN InbvDisplayDebugStrings = FALSE;
-INBV_DISPLAY_STRING_FILTER InbvDisplayFilter;
-ULONG ProgressBarLeft, ProgressBarTop;
-BOOLEAN ShowProgressBar = FALSE;
-INBV_PROGRESS_STATE InbvProgressState;
-INBV_RESET_DISPLAY_PARAMETERS InbvResetDisplayParameters;
-ULONG ResourceCount;
-PUCHAR ResourceList[64];
-BOOLEAN SysThreadCreated = FALSE;
-ROT_BAR_TYPE RotBarSelection;
-ULONG PltRotBarStatus;
-BT_PROGRESS_INDICATOR InbvProgressIndicator = {0, 25, 0};
-
-/* FADING FUNCTION ***********************************************************/
-
-/** From include/psdk/wingdi.h **/
-typedef struct tagRGBQUAD
-{
-    UCHAR    rgbBlue;
-    UCHAR    rgbGreen;
-    UCHAR    rgbRed;
-    UCHAR    rgbReserved;
-} RGBQUAD,*LPRGBQUAD;
-/*******************************/
-
-static RGBQUAD _MainPalette[16];
-
-#define PALETTE_FADE_STEPS  15
-#define PALETTE_FADE_TIME   20 * 10000 /* 20ms */
-
-/** From bootvid/precomp.h **/
-//
-// Bitmap Header
-//
-typedef struct tagBITMAPINFOHEADER
+/*
+ * Enable this define if you want Inbv to use coloured headless mode.
+ */
+// #define INBV_HEADLESS_COLORS
+
+typedef struct _INBV_PROGRESS_STATE
 {
-    ULONG biSize;
-    LONG biWidth;
-    LONG biHeight;
-    USHORT biPlanes;
-    USHORT biBitCount;
-    ULONG biCompression;
-    ULONG biSizeImage;
-    LONG biXPelsPerMeter;
-    LONG biYPelsPerMeter;
-    ULONG biClrUsed;
-    ULONG biClrImportant;
-} BITMAPINFOHEADER, *PBITMAPINFOHEADER;
-/****************************/
-
-//
-// Needed prototypes
-//
-VOID NTAPI InbvAcquireLock(VOID);
-VOID NTAPI InbvReleaseLock(VOID);
-
-static VOID
-NTAPI
-BootImageFadeIn(VOID)
+    ULONG Floor;
+    ULONG Ceiling;
+    ULONG Bias;
+} INBV_PROGRESS_STATE;
+
+typedef struct _BT_PROGRESS_INDICATOR
 {
-    UCHAR PaletteBitmapBuffer[sizeof(BITMAPINFOHEADER) + sizeof(_MainPalette)];
-    PBITMAPINFOHEADER PaletteBitmap = (PBITMAPINFOHEADER)PaletteBitmapBuffer;
-    LPRGBQUAD Palette = (LPRGBQUAD)(PaletteBitmapBuffer + sizeof(BITMAPINFOHEADER));
+    ULONG Count;
+    ULONG Expected;
+    ULONG Percentage;
+} BT_PROGRESS_INDICATOR, *PBT_PROGRESS_INDICATOR;
 
-    ULONG Iteration, Index, ClrUsed;
-    LARGE_INTEGER Interval;
+static KSPIN_LOCK BootDriverLock;
+static KIRQL InbvOldIrql;
+static INBV_DISPLAY_STATE InbvDisplayState = INBV_DISPLAY_STATE_DISABLED;
+BOOLEAN InbvBootDriverInstalled = FALSE;
+static INBV_RESET_DISPLAY_PARAMETERS InbvResetDisplayParameters = NULL;
 
-    Interval.QuadPart = -PALETTE_FADE_TIME;
+static BOOLEAN InbvDisplayDebugStrings = FALSE;
+static INBV_DISPLAY_STRING_FILTER InbvDisplayFilter = NULL;
 
-    /* Check if we're installed and we own it */
-    if ((InbvBootDriverInstalled) &&
-        (InbvDisplayState == INBV_DISPLAY_STATE_OWNED))
-    {
-        /* Acquire the lock */
-        InbvAcquireLock();
+ULONG ProgressBarLeft = 0, ProgressBarTop = 0;
+BOOLEAN ShowProgressBar = FALSE;
+static INBV_PROGRESS_STATE InbvProgressState;
+static BT_PROGRESS_INDICATOR InbvProgressIndicator = {0, 25, 0};
 
-        /*
-         * Build a bitmap containing the fade in palette. The palette entries
-         * are then processed in a loop and set using VidBitBlt function.
-         */
-        ClrUsed = sizeof(_MainPalette) / sizeof(_MainPalette[0]);
-        RtlZeroMemory(PaletteBitmap, sizeof(BITMAPINFOHEADER));
-        PaletteBitmap->biSize = sizeof(BITMAPINFOHEADER);
-        PaletteBitmap->biBitCount = 4;
-        PaletteBitmap->biClrUsed = ClrUsed;
-
-        /*
-         * Main animation loop.
-         */
-        for (Iteration = 0; Iteration <= PALETTE_FADE_STEPS; ++Iteration)
-        {
-            for (Index = 0; Index < ClrUsed; Index++)
-            {
-                Palette[Index].rgbRed = (UCHAR)
-                    (_MainPalette[Index].rgbRed * Iteration / PALETTE_FADE_STEPS);
-                Palette[Index].rgbGreen = (UCHAR)
-                    (_MainPalette[Index].rgbGreen * Iteration / PALETTE_FADE_STEPS);
-                Palette[Index].rgbBlue = (UCHAR)
-                    (_MainPalette[Index].rgbBlue * Iteration / PALETTE_FADE_STEPS);
-            }
+static ULONG ResourceCount = 0;
+static PUCHAR ResourceList[1 + IDB_MAX_RESOURCES]; // First entry == NULL, followed by 'ResourceCount' entries.
 
-            VidBitBlt(PaletteBitmapBuffer, 0, 0);
 
-            /* Wait for a bit. */
-            KeDelayExecutionThread(KernelMode, FALSE, &Interval);
-        }
+/*
+ * Headless terminal text colors
+ */
 
-        /* Release the lock */
-        InbvReleaseLock();
+#ifdef INBV_HEADLESS_COLORS
+
+// Conversion table CGA to ANSI color index
+static const UCHAR CGA_TO_ANSI_COLOR_TABLE[16] =
+{
+    0,  // Black
+    4,  // Blue
+    2,  // Green
+    6,  // Cyan
+    1,  // Red
+    5,  // Magenta
+    3,  // Brown/Yellow
+    7,  // Grey/White
+
+    60, // Bright Black
+    64, // Bright Blue
+    62, // Bright Green
+    66, // Bright Cyan
+    61, // Bright Red
+    65, // Bright Magenta
+    63, // Bright Yellow
+    67  // Bright Grey (White)
+};
+
+#define CGA_TO_ANSI_COLOR(CgaColor) \
+    CGA_TO_ANSI_COLOR_TABLE[CgaColor & 0x0F]
+
+#endif
+
+// Default colors: text in white, background in black
+static ULONG InbvTerminalTextColor = 37;
+static ULONG InbvTerminalBkgdColor = 40;
 
-        /* Wait for a bit. */
-        KeDelayExecutionThread(KernelMode, FALSE, &Interval);
-    }
-}
 
 /* FUNCTIONS *****************************************************************/
 
+CODE_SEG("INIT")
+static
 PVOID
-NTAPI
-INIT_FUNCTION
-FindBitmapResource(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
-                   IN ULONG ResourceId)
+FindBitmapResource(
+    _In_ PLOADER_PARAMETER_BLOCK LoaderBlock,
+    _In_ ULONG ResourceId)
 {
     UNICODE_STRING UpString = RTL_CONSTANT_STRING(L"ntoskrnl.exe");
     UNICODE_STRING MpString = RTL_CONSTANT_STRING(L"ntkrnlmp.exe");
@@ -145,8 +109,9 @@ FindBitmapResource(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
 
     /* Loop the driver list */
     ListHead = &LoaderBlock->LoadOrderListHead;
-    NextEntry = ListHead->Flink;
-    while (NextEntry != ListHead)
+    for (NextEntry = ListHead->Flink;
+         NextEntry != ListHead;
+         NextEntry = NextEntry->Flink)
     {
         /* Get the entry */
         LdrEntry = CONTAINING_RECORD(NextEntry,
@@ -154,8 +119,8 @@ FindBitmapResource(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
                                      InLoadOrderLinks);
 
         /* Check for a match */
-        if ((RtlEqualUnicodeString(&LdrEntry->BaseDllName, &UpString, TRUE)) ||
-            (RtlEqualUnicodeString(&LdrEntry->BaseDllName, &MpString, TRUE)))
+        if (RtlEqualUnicodeString(&LdrEntry->BaseDllName, &UpString, TRUE) ||
+            RtlEqualUnicodeString(&LdrEntry->BaseDllName, &MpString, TRUE))
         {
             /* Break out */
             break;
@@ -166,7 +131,7 @@ FindBitmapResource(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
     if (NextEntry != ListHead)
     {
         /* Try to find the resource */
-        ResourceInfo.Type = 2; //RT_BITMAP;
+        ResourceInfo.Type = 2; // RT_BITMAP;
         ResourceInfo.Name = ResourceId;
         ResourceInfo.Language = 0;
         Status = LdrFindResource_U(LdrEntry->DllBase,
@@ -193,14 +158,27 @@ FindBitmapResource(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
     return Data;
 }
 
+PUCHAR
+NTAPI
+InbvGetResourceAddress(
+    _In_ ULONG ResourceNumber)
+{
+    /* Validate the resource number */
+    if (ResourceNumber > ResourceCount) return NULL;
+
+    /* Return the address */
+    return ResourceList[ResourceNumber];
+}
+
+CODE_SEG("INIT")
 BOOLEAN
 NTAPI
-INIT_FUNCTION
-InbvDriverInitialize(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
-                     IN ULONG Count)
+InbvDriverInitialize(
+    _In_ PLOADER_PARAMETER_BLOCK LoaderBlock,
+    _In_ ULONG Count)
 {
     PCHAR CommandLine;
-    BOOLEAN CustomLogo = FALSE;
+    BOOLEAN ResetMode = FALSE; // By default do not reset the video mode
     ULONG i;
 
     /* Quit if we're already installed */
@@ -210,21 +188,18 @@ InbvDriverInitialize(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
     KeInitializeSpinLock(&BootDriverLock);
     if (InbvDisplayState == INBV_DISPLAY_STATE_OWNED)
     {
-        /* Check if we have a custom boot logo */
-        CommandLine = _strupr(LoaderBlock->LoadOptions);
-        CustomLogo = strstr(CommandLine, "BOOTLOGO") ? TRUE: FALSE;
+        /* Reset the video mode in case we do not have a custom boot logo */
+        CommandLine = (LoaderBlock->LoadOptions ? _strupr(LoaderBlock->LoadOptions) : NULL);
+        ResetMode   = (CommandLine == NULL) || (strstr(CommandLine, "BOOTLOGO") == NULL);
     }
 
     /* Initialize the video */
-    InbvBootDriverInstalled = VidInitialize(FALSE);
+    InbvBootDriverInstalled = VidInitialize(ResetMode);
     if (InbvBootDriverInstalled)
     {
-        /* Now reset the display, but only if there's a custom boot logo */
-        VidResetDisplay(CustomLogo);
-
         /* Find bitmap resources in the kernel */
-        ResourceCount = min(IDB_CLUSTER_SERVER, Count);
-        for (i = 1; i <= Count; i++)
+        ResourceCount = min(Count, RTL_NUMBER_OF(ResourceList) - 1);
+        for (i = 1; i <= ResourceCount; i++)
         {
             /* Do the lookup */
             ResourceList[i] = FindBitmapResource(LoaderBlock, i);
@@ -232,6 +207,8 @@ InbvDriverInitialize(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
 
         /* Set the progress bar ranges */
         InbvSetProgressBarSubset(0, 100);
+
+        // BootAnimInitialize(LoaderBlock, Count);
     }
 
     /* Return install state */
@@ -278,8 +255,8 @@ InbvReleaseLock(VOID)
 
 VOID
 NTAPI
-INIT_FUNCTION
-InbvEnableBootDriver(IN BOOLEAN Enable)
+InbvEnableBootDriver(
+    _In_ BOOLEAN Enable)
 {
     /* Check if we're installed */
     if (InbvBootDriverInstalled)
@@ -294,7 +271,7 @@ InbvEnableBootDriver(IN BOOLEAN Enable)
         if (InbvDisplayState == INBV_DISPLAY_STATE_OWNED) VidCleanUp();
 
         /* Set the new display state */
-        InbvDisplayState = Enable ? INBV_DISPLAY_STATE_OWNED:
+        InbvDisplayState = Enable ? INBV_DISPLAY_STATE_OWNED :
                                     INBV_DISPLAY_STATE_DISABLED;
 
         /* Release the lock */
@@ -303,7 +280,7 @@ InbvEnableBootDriver(IN BOOLEAN Enable)
     else
     {
         /* Set the new display state */
-        InbvDisplayState = Enable ? INBV_DISPLAY_STATE_OWNED:
+        InbvDisplayState = Enable ? INBV_DISPLAY_STATE_OWNED :
                                     INBV_DISPLAY_STATE_DISABLED;
     }
 }
@@ -326,10 +303,11 @@ InbvAcquireDisplayOwnership(VOID)
 
 VOID
 NTAPI
-InbvSetDisplayOwnership(IN BOOLEAN DisplayOwned)
+InbvSetDisplayOwnership(
+    _In_ BOOLEAN DisplayOwned)
 {
     /* Set the new display state */
-    InbvDisplayState = DisplayOwned ? INBV_DISPLAY_STATE_OWNED:
+    InbvDisplayState = DisplayOwned ? INBV_DISPLAY_STATE_OWNED :
                                       INBV_DISPLAY_STATE_LOST;
 }
 
@@ -351,7 +329,8 @@ InbvGetDisplayState(VOID)
 
 BOOLEAN
 NTAPI
-InbvDisplayString(IN PCHAR String)
+InbvDisplayString(
+    _In_ PCHAR String)
 {
     /* Make sure we own the display */
     if (InbvDisplayState == INBV_DISPLAY_STATE_OWNED)
@@ -366,7 +345,7 @@ InbvDisplayString(IN PCHAR String)
         InbvAcquireLock();
 
         /* Make sure we're installed and display the string */
-        if (InbvBootDriverInstalled) VidDisplayString((PUCHAR) String);
+        if (InbvBootDriverInstalled) VidDisplayString((PUCHAR)String);
 
         /* Print the string on the EMS port */
         HeadlessDispatch(HeadlessCmdPutString,
@@ -388,7 +367,8 @@ InbvDisplayString(IN PCHAR String)
 
 BOOLEAN
 NTAPI
-InbvEnableDisplayString(IN BOOLEAN Enable)
+InbvEnableDisplayString(
+    _In_ BOOLEAN Enable)
 {
     BOOLEAN OldSetting;
 
@@ -404,10 +384,11 @@ InbvEnableDisplayString(IN BOOLEAN Enable)
 
 VOID
 NTAPI
-InbvInstallDisplayStringFilter(IN INBV_DISPLAY_STRING_FILTER Filter)
+InbvInstallDisplayStringFilter(
+    _In_ INBV_DISPLAY_STRING_FILTER DisplayFilter)
 {
     /* Save the filter */
-    InbvDisplayFilter = Filter;
+    InbvDisplayFilter = DisplayFilter;
 }
 
 BOOLEAN
@@ -420,7 +401,8 @@ InbvIsBootDriverInstalled(VOID)
 
 VOID
 NTAPI
-InbvNotifyDisplayOwnershipLost(IN INBV_RESET_DISPLAY_PARAMETERS Callback)
+InbvNotifyDisplayOwnershipLost(
+    _In_ INBV_RESET_DISPLAY_PARAMETERS Callback)
 {
     /* Check if we're installed */
     if (InbvBootDriverInstalled)
@@ -449,7 +431,7 @@ NTAPI
 InbvResetDisplay(VOID)
 {
     /* Check if we're installed and we own it */
-    if ((InbvBootDriverInstalled) &&
+    if (InbvBootDriverInstalled &&
         (InbvDisplayState == INBV_DISPLAY_STATE_OWNED))
     {
         /* Do the reset */
@@ -463,20 +445,36 @@ InbvResetDisplay(VOID)
 
 VOID
 NTAPI
-InbvSetScrollRegion(IN ULONG Left,
-                    IN ULONG Top,
-                    IN ULONG Width,
-                    IN ULONG Height)
+InbvSetScrollRegion(
+    _In_ ULONG Left,
+    _In_ ULONG Top,
+    _In_ ULONG Right,
+    _In_ ULONG Bottom)
 {
     /* Just call bootvid */
-    VidSetScrollRegion(Left, Top, Width, Height);
+    VidSetScrollRegion(Left, Top, Right, Bottom);
 }
 
 VOID
 NTAPI
-InbvSetTextColor(IN ULONG Color)
+InbvSetTextColor(
+    _In_ ULONG Color)
 {
-    /* FIXME: Headless */
+    HEADLESS_CMD_SET_COLOR HeadlessSetColor;
+
+    /* Set color for EMS port */
+#ifdef INBV_HEADLESS_COLORS
+    InbvTerminalTextColor = 30 + CGA_TO_ANSI_COLOR(Color);
+#else
+    InbvTerminalTextColor = 37;
+#endif
+    HeadlessSetColor.TextColor = InbvTerminalTextColor;
+    HeadlessSetColor.BkgdColor = InbvTerminalBkgdColor;
+    HeadlessDispatch(HeadlessCmdSetColor,
+                     &HeadlessSetColor,
+                     sizeof(HeadlessSetColor),
+                     NULL,
+                     NULL);
 
     /* Update the text color */
     VidSetTextColor(Color);
@@ -484,12 +482,15 @@ InbvSetTextColor(IN ULONG Color)
 
 VOID
 NTAPI
-InbvSolidColorFill(IN ULONG Left,
-                   IN ULONG Top,
-                   IN ULONG Width,
-                   IN ULONG Height,
-                   IN ULONG Color)
+InbvSolidColorFill(
+    _In_ ULONG Left,
+    _In_ ULONG Top,
+    _In_ ULONG Right,
+    _In_ ULONG Bottom,
+    _In_ ULONG Color)
 {
+    HEADLESS_CMD_SET_COLOR HeadlessSetColor;
+
     /* Make sure we own it */
     if (InbvDisplayState == INBV_DISPLAY_STATE_OWNED)
     {
@@ -500,10 +501,25 @@ InbvSolidColorFill(IN ULONG Left,
         if (InbvBootDriverInstalled)
         {
             /* Call bootvid */
-            VidSolidColorFill(Left, Top, Width, Height, (UCHAR)Color);
+            VidSolidColorFill(Left, Top, Right, Bottom, (UCHAR)Color);
         }
 
-        /* FIXME: Headless */
+        /* Set color for EMS port and clear display */
+#ifdef INBV_HEADLESS_COLORS
+        InbvTerminalBkgdColor = 40 + CGA_TO_ANSI_COLOR(Color);
+#else
+        InbvTerminalBkgdColor = 40;
+#endif
+        HeadlessSetColor.TextColor = InbvTerminalTextColor;
+        HeadlessSetColor.BkgdColor = InbvTerminalBkgdColor;
+        HeadlessDispatch(HeadlessCmdSetColor,
+                         &HeadlessSetColor,
+                         sizeof(HeadlessSetColor),
+                         NULL,
+                         NULL);
+        HeadlessDispatch(HeadlessCmdClearDisplay,
+                         NULL, 0,
+                         NULL, NULL);
 
         /* Release the lock */
         InbvReleaseLock();
@@ -512,29 +528,20 @@ InbvSolidColorFill(IN ULONG Left,
 
 VOID
 NTAPI
-INIT_FUNCTION
-InbvUpdateProgressBar(IN ULONG Progress)
+InbvBitBlt(
+    _In_ PUCHAR Buffer,
+    _In_ ULONG X,
+    _In_ ULONG Y)
 {
-    ULONG FillCount, BoundedProgress;
-
-    /* Make sure the progress bar is enabled, that we own and are installed */
-    if ((ShowProgressBar) &&
-        (InbvBootDriverInstalled) &&
+    /* Check if we're installed and we own it */
+    if (InbvBootDriverInstalled &&
         (InbvDisplayState == INBV_DISPLAY_STATE_OWNED))
     {
-        /* Compute fill count */
-        BoundedProgress = (InbvProgressState.Floor / 100) + Progress;
-        FillCount = 121 * (InbvProgressState.Bias * BoundedProgress) / 1000000;
-
         /* Acquire the lock */
         InbvAcquireLock();
 
-        /* Fill the progress bar */
-        VidSolidColorFill(ProgressBarLeft,
-                          ProgressBarTop,
-                          ProgressBarLeft + FillCount,
-                          ProgressBarTop + 12,
-                          15);
+        /* Do the blit */
+        VidBitBlt(Buffer, X, Y);
 
         /* Release the lock */
         InbvReleaseLock();
@@ -543,15 +550,16 @@ InbvUpdateProgressBar(IN ULONG Progress)
 
 VOID
 NTAPI
-InbvBufferToScreenBlt(IN PUCHAR Buffer,
-                      IN ULONG X,
-                      IN ULONG Y,
-                      IN ULONG Width,
-                      IN ULONG Height,
-                      IN ULONG Delta)
+InbvBufferToScreenBlt(
+    _In_ PUCHAR Buffer,
+    _In_ ULONG X,
+    _In_ ULONG Y,
+    _In_ ULONG Width,
+    _In_ ULONG Height,
+    _In_ ULONG Delta)
 {
     /* Check if we're installed and we own it */
-    if ((InbvBootDriverInstalled) &&
+    if (InbvBootDriverInstalled &&
         (InbvDisplayState == INBV_DISPLAY_STATE_OWNED))
     {
         /* Do the blit */
@@ -561,36 +569,16 @@ InbvBufferToScreenBlt(IN PUCHAR Buffer,
 
 VOID
 NTAPI
-InbvBitBlt(IN PUCHAR Buffer,
-           IN ULONG X,
-           IN ULONG Y)
+InbvScreenToBufferBlt(
+    _Out_ PUCHAR Buffer,
+    _In_ ULONG X,
+    _In_ ULONG Y,
+    _In_ ULONG Width,
+    _In_ ULONG Height,
+    _In_ ULONG Delta)
 {
     /* Check if we're installed and we own it */
-    if ((InbvBootDriverInstalled) &&
-        (InbvDisplayState == INBV_DISPLAY_STATE_OWNED))
-    {
-        /* Acquire the lock */
-        InbvAcquireLock();
-
-        /* Do the blit */
-        VidBitBlt(Buffer, X, Y);
-
-        /* Release the lock */
-        InbvReleaseLock();
-    }
-}
-
-VOID
-NTAPI
-InbvScreenToBufferBlt(IN PUCHAR Buffer,
-                      IN ULONG X,
-                      IN ULONG Y,
-                      IN ULONG Width,
-                      IN ULONG Height,
-                      IN ULONG Delta)
-{
-    /* Check if we're installed and we own it */
-    if ((InbvBootDriverInstalled) &&
+    if (InbvBootDriverInstalled &&
         (InbvDisplayState == INBV_DISPLAY_STATE_OWNED))
     {
         /* Do the blit */
@@ -598,37 +586,43 @@ InbvScreenToBufferBlt(IN PUCHAR Buffer,
     }
 }
 
+/**
+ * @brief
+ * Sets the screen coordinates of the loading progress bar and enable it.
+ *
+ * @param[in]   Left
+ * @param[in]   Top
+ * The left/top coordinates.
+ *
+ * @return None.
+ **/
 VOID
 NTAPI
-InbvSetProgressBarCoordinates(IN ULONG Left,
-                              IN ULONG Top)
+InbvSetProgressBarCoordinates(
+    _In_ ULONG Left,
+    _In_ ULONG Top)
 {
     /* Update the coordinates */
     ProgressBarLeft = Left;
-    ProgressBarTop = Top;
+    ProgressBarTop  = Top;
 
     /* Enable the progress bar */
     ShowProgressBar = TRUE;
 }
 
+/**
+ * @brief
+ * Gives some progress feedback, without specifying any explicit number
+ * of progress steps or percentage.
+ * The corresponding percentage is derived from the progress indicator's
+ * current count, capped to the number of expected calls to be made to
+ * this function (default: 25, see @b InbvProgressIndicator.Expected).
+ *
+ * @return None.
+ **/
+CODE_SEG("INIT")
 VOID
 NTAPI
-InbvSetProgressBarSubset(IN ULONG Floor,
-                         IN ULONG Ceiling)
-{
-    /* Sanity checks */
-    ASSERT(Floor < Ceiling);
-    ASSERT(Ceiling <= 100);
-
-    /* Update the progress bar state */
-    InbvProgressState.Floor = Floor * 100;
-    InbvProgressState.Ceiling = Ceiling * 100;
-    InbvProgressState.Bias = (Ceiling * 100) - Floor;
-}
-
-VOID
-NTAPI
-INIT_FUNCTION
 InbvIndicateProgress(VOID)
 {
     ULONG Percentage;
@@ -636,243 +630,148 @@ InbvIndicateProgress(VOID)
     /* Increase progress */
     InbvProgressIndicator.Count++;
 
-    /* Compute new percentage */
-    Percentage = min(100 * InbvProgressIndicator.Count /
-                           InbvProgressIndicator.Expected,
-                     99);
+    /* Compute the new percentage - Don't go over 100% */
+    Percentage = 100 * InbvProgressIndicator.Count /
+                       InbvProgressIndicator.Expected;
+    Percentage = min(Percentage, 99);
+
     if (Percentage != InbvProgressIndicator.Percentage)
     {
-        /* Percentage has moved, update the progress bar */
+        /* Percentage has changed, update the progress bar */
         InbvProgressIndicator.Percentage = Percentage;
         InbvUpdateProgressBar(Percentage);
     }
 }
 
-PUCHAR
+/**
+ * @brief
+ * Specifies a progress percentage sub-range.
+ * Further calls to InbvIndicateProgress() or InbvUpdateProgressBar()
+ * will update the progress percentage relative to this sub-range.
+ * In particular, the percentage provided to InbvUpdateProgressBar()
+ * is relative to this sub-range.
+ *
+ * @param[in]   Floor
+ * The lower bound percentage of the sub-range (default: 0).
+ *
+ * @param[in]   Ceiling
+ * The upper bound percentage of the sub-range (default: 100).
+ *
+ * @return None.
+ **/
+VOID
 NTAPI
-InbvGetResourceAddress(IN ULONG ResourceNumber)
+InbvSetProgressBarSubset(
+    _In_ ULONG Floor,
+    _In_ ULONG Ceiling)
 {
-    /* Validate the resource number */
-    if (ResourceNumber > ResourceCount) return NULL;
+    /* Sanity checks */
+    ASSERT(Floor < Ceiling);
+    ASSERT(Ceiling <= 100);
 
-    /* Return the address */
-    return ResourceList[ResourceNumber--];
+    /* Update the progress bar state */
+    InbvProgressState.Floor = Floor * 100;
+    InbvProgressState.Ceiling = Ceiling * 100;
+    InbvProgressState.Bias = Ceiling - Floor;
 }
 
-NTSTATUS
+/**
+ * @brief
+ * Updates the progress bar percentage, relative to the current
+ * percentage sub-range previously set by InbvSetProgressBarSubset().
+ *
+ * @param[in]   Percentage
+ * The progress percentage, relative to the current sub-range.
+ *
+ * @return None.
+ **/
+VOID
 NTAPI
-NtDisplayString(IN PUNICODE_STRING DisplayString)
+InbvUpdateProgressBar(
+    _In_ ULONG Percentage)
 {
-    OEM_STRING OemString;
+    ULONG TotalProgress;
 
-    /* Convert the string to OEM and display it */
-    RtlUnicodeStringToOemString(&OemString, DisplayString, TRUE);
-    InbvDisplayString(OemString.Buffer);
-    RtlFreeOemString(&OemString);
+    /* Make sure the progress bar is enabled, that we own and are installed */
+    if (ShowProgressBar &&
+        InbvBootDriverInstalled &&
+        (InbvDisplayState == INBV_DISPLAY_STATE_OWNED))
+    {
+        /* Compute the total progress and tick the progress bar */
+        TotalProgress = InbvProgressState.Floor + (Percentage * InbvProgressState.Bias);
+        // TotalProgress /= (100 * 100);
 
-    /* Return success */
-    return STATUS_SUCCESS;
+        BootAnimTickProgressBar(TotalProgress);
+    }
 }
 
-VOID
+NTSTATUS
 NTAPI
-INIT_FUNCTION
-DisplayBootBitmap(IN BOOLEAN TextMode)
+NtDisplayString(IN PUNICODE_STRING DisplayString)
 {
-    PBITMAPINFOHEADER BitmapInfoHeader;
-    LPRGBQUAD Palette;
+    NTSTATUS Status;
+    UNICODE_STRING CapturedString;
+    OEM_STRING OemString;
+    ULONG OemLength;
+    KPROCESSOR_MODE PreviousMode;
 
-    PVOID Header, Band, Text, Screen;
-    ROT_BAR_TYPE TempRotBarSelection = RB_UNSPECIFIED;
+    PAGED_CODE();
 
-#ifdef CORE_6781_resolved
-    UCHAR Buffer[64];
-#endif
+    PreviousMode = ExGetPreviousMode();
+
+    /* We require the TCB privilege */
+    if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
+        return STATUS_PRIVILEGE_NOT_HELD;
 
-    /* Check if the system thread has already been created */
-    if (SysThreadCreated)
+    /* Capture the string */
+    Status = ProbeAndCaptureUnicodeString(&CapturedString, PreviousMode, DisplayString);
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    /* Do not display the string if it is empty */
+    if (CapturedString.Length == 0 || CapturedString.Buffer == NULL)
     {
-        /* Reset the progress bar */
-        InbvAcquireLock();
-        RotBarSelection = RB_UNSPECIFIED;
-        InbvReleaseLock();
+        Status = STATUS_SUCCESS;
+        goto Quit;
     }
 
-    /* Check if this is text mode */
-    ShowProgressBar = FALSE;
-    if (TextMode)
+    /*
+     * Convert the string since INBV understands only ANSI/OEM. Allocate the
+     * string buffer in non-paged pool because INBV passes it down to BOOTVID.
+     * We cannot perform the allocation using RtlUnicodeStringToOemString()
+     * since its allocator uses PagedPool.
+     */
+    OemLength = RtlUnicodeStringToOemSize(&CapturedString);
+    if (OemLength > MAXUSHORT)
     {
-        /* Check if this is a server OS */
-        if (SharedUserData->NtProductType == NtProductWinNt)
-        {
-            /* It's not, set workstation settings */
-            InbvSetTextColor(15);
-            InbvSolidColorFill(0, 0, 639, 479, 7);
-            InbvSolidColorFill(0, 421, 639, 479, 1);
-
-            /* Get resources */
-            Header = InbvGetResourceAddress(IDB_LOGO_HEADER);
-            Band = InbvGetResourceAddress(IDB_LOGO_BAND);
-        }
-        else
-        {
-            /* Set server settings */
-            InbvSetTextColor(14);
-            InbvSolidColorFill(0, 0, 639, 479, 6);
-            InbvSolidColorFill(0, 421, 639, 479, 1);
-
-            /* Get resources */
-            Header = InbvGetResourceAddress(IDB_SERVER_HEADER);
-            Band = InbvGetResourceAddress(IDB_SERVER_BAND);
-        }
-
-        /* Set the scrolling region */
-        InbvSetScrollRegion(32, 80, 631, 400);
-
-        /* Make sure we have resources */
-        if ((Header) && (Band))
-        {
-            /* BitBlt them on the screen */
-            InbvBitBlt(Band, 0, 419);
-            InbvBitBlt(Header, 0, 0);
-        }
+        Status = STATUS_BUFFER_OVERFLOW;
+        goto Quit;
     }
-    else
+    RtlInitEmptyAnsiString((PANSI_STRING)&OemString, NULL, (USHORT)OemLength);
+    OemString.Buffer = ExAllocatePoolWithTag(NonPagedPool, OemLength, TAG_OSTR);
+    if (OemString.Buffer == NULL)
     {
-        /* Is the boot driver installed? */
-        Text = NULL;
-        if (!InbvBootDriverInstalled) return;
-
-        /* Load the standard boot screen */
-        Screen = InbvGetResourceAddress(IDB_BOOT_LOGO);
-        if (SharedUserData->NtProductType == NtProductWinNt)
-        {
-            /* Workstation product, display appropriate status bar color */
-            InbvGetResourceAddress(IDB_BAR_PRO);
-        }
-        else
-        {
-            /* Display correct branding based on server suite */
-            if (ExVerifySuite(StorageServer))
-            {
-                /* Storage Server Edition */
-                Text = InbvGetResourceAddress(IDB_STORAGE_SERVER);
-            }
-            else if (ExVerifySuite(ComputeServer))
-            {
-                /* Compute Cluster Edition */
-                Text = InbvGetResourceAddress(IDB_CLUSTER_SERVER);
-            }
-            else
-            {
-                /* Normal edition */
-                Text = InbvGetResourceAddress(IDB_SERVER_LOGO);
-            }
-
-            /* Server product, display appropriate status bar color */
-            InbvGetResourceAddress(IDB_BAR_SERVER);
-        }
-
-        /* Make sure we had a logo */
-        if (Screen)
-        {
-            /* Choose progress bar */
-            TempRotBarSelection = RB_SQUARE_CELLS;
-
-            /*
-             * Save the main image palette and replace it with black palette, so
-             * we can do fade in effect later.
-             */
-            BitmapInfoHeader = (PBITMAPINFOHEADER)Screen;
-            Palette = (LPRGBQUAD)((PUCHAR)Screen + BitmapInfoHeader->biSize);
-            RtlCopyMemory(_MainPalette, Palette, sizeof(_MainPalette));
-            RtlZeroMemory(Palette, sizeof(_MainPalette));
-
-            /* Blit the background */
-            InbvBitBlt(Screen, 0, 0);
-
-            /* Set progress bar coordinates and display it */
-            InbvSetProgressBarCoordinates(257, 352);
-
-            /* Display the boot logo and fade it in */
-            BootImageFadeIn();
-
-#ifdef CORE_6781_resolved
-            /* Check for non-workstation products */
-            if (SharedUserData->NtProductType != NtProductWinNt)
-            {
-                /* Overwrite part of the logo for a server product */
-                InbvScreenToBufferBlt(Buffer, 413, 237, 7, 7, 8);
-                InbvSolidColorFill(418, 230, 454, 256, 0);
-                InbvBufferToScreenBlt(Buffer, 413, 237, 7, 7, 8);
-
-                /* In setup mode, you haven't selected a SKU yet */
-                if (ExpInTextModeSetup) Text = NULL;
-            }
-#endif
-        }
-
-#ifdef CORE_6781_resolved
-        /* Draw the SKU text if it exits */
-        if (Text) InbvBitBlt(Text, 180, 121);
-#endif
-
-        /* Draw the progress bar bit */
-//      if (Bar) InbvBitBlt(Bar, 0, 0);
-
-        /* Set filter which will draw text display if needed */
-        InbvInstallDisplayStringFilter(DisplayFilter);
+        Status = STATUS_NO_MEMORY;
+        goto Quit;
     }
-
-    /* Do we have a system thread? */
-    if (SysThreadCreated)
+    Status = RtlUnicodeStringToOemString(&OemString, &CapturedString, FALSE);
+    if (!NT_SUCCESS(Status))
     {
-        /* We do, set the progress bar location */
-        InbvAcquireLock();
-        RotBarSelection = TempRotBarSelection;
-        //InbvRotBarInit();
-        InbvReleaseLock();
+        ExFreePoolWithTag(OemString.Buffer, TAG_OSTR);
+        goto Quit;
     }
-}
-
-VOID
-NTAPI
-INIT_FUNCTION
-DisplayFilter(PCHAR *String)
-{
-    /* Windows hack to skip first dots */
-    static BOOLEAN DotHack = TRUE;
 
-    /* If "." is given set *String to empty string */
-    if(DotHack && strcmp(*String, ".") == 0)
-        *String = "";
-
-    if(**String)
-    {
-        /* Remove the filter */
-        InbvInstallDisplayStringFilter(NULL);
+    /* Display the string */
+    InbvDisplayString(OemString.Buffer);
 
-        DotHack = FALSE;
+    /* Free the string buffer */
+    ExFreePoolWithTag(OemString.Buffer, TAG_OSTR);
 
-        /* Draw text screen */
-        DisplayBootBitmap(TRUE);
-    }
-}
+    Status = STATUS_SUCCESS;
 
-VOID
-NTAPI
-INIT_FUNCTION
-FinalizeBootLogo(VOID)
-{
-    /* Acquire lock and check the display state */
-    InbvAcquireLock();
-    if (InbvGetDisplayState() == INBV_DISPLAY_STATE_OWNED)
-    {
-        /* Clear the screen */
-        VidSolidColorFill(0, 0, 639, 479, 0);
-    }
+Quit:
+    /* Free the captured string */
+    ReleaseCapturedUnicodeString(&CapturedString, PreviousMode);
 
-    /* Reset progress bar and lock */
-    PltRotBarStatus = 3;
-    InbvReleaseLock();
+    return Status;
 }