#include <debug.h>
#include "bootvid/bootvid.h"
-//
-// Bitmap Header
-//
-typedef struct tagBITMAPINFOHEADER
-{
- ULONG biSize;
- LONG biWidth;
- LONG biHeight;
- USHORT biPlanes;
- USHORT biBitCount;
- ULONG biCompression;
- ULONG biSizeImage;
- LONG biXPelsPerMeter;
- LONG biYPelsPerMeter;
- ULONG biClrUsed;
- ULONG biClrImportant;
-} BITMAPINFOHEADER, *PBITMAPINFOHEADER;
-
/* GLOBALS *******************************************************************/
KSPIN_LOCK BootDriverLock;
BOOLEAN SysThreadCreated;
ROT_BAR_TYPE RotBarSelection;
ULONG PltRotBarStatus;
+BT_PROGRESS_INDICATOR InbvProgressIndicator = {0, 25, 0};
/* FUNCTIONS *****************************************************************/
PVOID
NTAPI
+INIT_FUNCTION
FindBitmapResource(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
IN ULONG ResourceId)
{
PLDR_DATA_TABLE_ENTRY LdrEntry;
PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry;
LDR_RESOURCE_INFO ResourceInfo;
- ULONG Size;
NTSTATUS Status;
PVOID Data = NULL;
if (NextEntry != ListHead)
{
/* Try to find the resource */
- ResourceInfo.Type = 2;
+ ResourceInfo.Type = 2; //RT_BITMAP;
ResourceInfo.Name = ResourceId;
ResourceInfo.Language = 0;
Status = LdrFindResource_U(LdrEntry->DllBase,
if (NT_SUCCESS(Status))
{
/* Access the resource */
+ ULONG Size = 0;
Status = LdrAccessResource(LdrEntry->DllBase,
ResourceDataEntry,
&Data,
&Size);
+ if ((Data) && (ResourceId < 3))
+ {
+ KiBugCheckData[4] ^= RtlComputeCrc32(0, Data, Size);
+ }
if (!NT_SUCCESS(Status)) Data = NULL;
}
}
BOOLEAN
NTAPI
+INIT_FUNCTION
InbvDriverInitialize(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
IN ULONG Count)
{
PCHAR CommandLine;
BOOLEAN CustomLogo = FALSE;
ULONG i;
- extern BOOLEAN ExpInTextModeSetup;
/* Quit if we're already installed */
if (InbvBootDriverInstalled) return TRUE;
CustomLogo = strstr(CommandLine, "BOOTLOGO") ? TRUE: FALSE;
}
- /* For SetupLDR, don't reset the BIOS Display -- FIXME! */
- if (ExpInTextModeSetup) CustomLogo = TRUE;
-
/* Initialize the video */
- InbvBootDriverInstalled = VidInitialize(!CustomLogo);
+ InbvBootDriverInstalled = VidInitialize(FALSE);
if (InbvBootDriverInstalled)
{
+ /* Now reset the display, but only if there's a custom boot logo */
+ VidResetDisplay(CustomLogo);
+
/* Find bitmap resources in the kernel */
- ResourceCount = Count;
- for (i = 0; i < Count; i++)
+ ResourceCount = min(IDB_CLUSTER_SERVER, Count);
+ for (i = 1; i <= Count; i++)
{
/* Do the lookup */
ResourceList[i] = FindBitmapResource(LoaderBlock, i);
NTAPI
InbvAcquireLock(VOID)
{
- /* Check if we're below dispatch level */
- InbvOldIrql = KeGetCurrentIrql();
- if (InbvOldIrql < DISPATCH_LEVEL)
+ KIRQL OldIrql;
+
+ /* Check if we're at dispatch level or lower */
+ OldIrql = KeGetCurrentIrql();
+ if (OldIrql <= DISPATCH_LEVEL)
{
+ /* Loop until the lock is free */
+ while (!KeTestSpinLock(&BootDriverLock));
+
/* Raise IRQL to dispatch level */
- KeRaiseIrql(DISPATCH_LEVEL, &InbvOldIrql);
+ KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
}
/* Acquire the lock */
KiAcquireSpinLock(&BootDriverLock);
+ InbvOldIrql = OldIrql;
}
VOID
NTAPI
InbvReleaseLock(VOID)
{
+ KIRQL OldIrql;
+
+ /* Capture the old IRQL */
+ OldIrql = InbvOldIrql;
+
/* Release the driver lock */
KiReleaseSpinLock(&BootDriverLock);
- /* If we were below dispatch level, lower IRQL back */
- if (InbvOldIrql < DISPATCH_LEVEL) KeLowerIrql(InbvOldIrql);
+ /* If we were at dispatch level or lower, restore the old IRQL */
+ if (InbvOldIrql <= DISPATCH_LEVEL) KeLowerIrql(OldIrql);
}
VOID
NTAPI
+INIT_FUNCTION
InbvEnableBootDriver(IN BOOLEAN Enable)
{
/* Check if we're installed */
/* Make sure we're installed and display the string */
if (InbvBootDriverInstalled) VidDisplayString((PUCHAR) String);
- /* Call Headless (We don't support headless for now)
- HeadlessDispatch(DISPLAY_STRING); */
+ /* Print the string on the EMS port */
+ HeadlessDispatch(
+ HeadlessCmdPutString,
+ String,
+ strlen(String) + sizeof(ANSI_NULL),
+ NULL,
+ NULL);
/* Release the lock */
InbvReleaseLock();
VOID
NTAPI
+INIT_FUNCTION
InbvUpdateProgressBar(IN ULONG Progress)
{
- ULONG FillCount, Left = 0;
+ ULONG FillCount, BoundedProgress;
/* Make sure the progress bar is enabled, that we own and are installed */
if ((ShowProgressBar) &&
(InbvBootDriverInstalled) &&
(InbvDisplayState == INBV_DISPLAY_STATE_OWNED))
{
- /* Calculate the fill count */
- FillCount = InbvProgressState.Bias * Progress + InbvProgressState.Floor;
- FillCount *= 18;
- FillCount /= 10000;
+ /* Compute fill count */
+ BoundedProgress = (InbvProgressState.Floor / 100) + Progress;
+ FillCount = 121 * (InbvProgressState.Bias * BoundedProgress) / 1000000;
- /* Start fill loop */
- while (FillCount)
- {
- /* Acquire the lock */
- InbvAcquireLock();
-
- /* Fill the progress bar */
- VidSolidColorFill(Left + ProgressBarLeft,
- ProgressBarTop,
- Left + ProgressBarLeft + 7,
- ProgressBarTop + 7,
- 11);
-
- /* Release the lock */
- InbvReleaseLock();
-
- /* Update the X position */
- Left += 9;
- FillCount--;
- }
+ /* Acquire the lock */
+ InbvAcquireLock();
+
+ /* Fill the progress bar */
+ VidSolidColorFill(ProgressBarLeft,
+ ProgressBarTop,
+ ProgressBarLeft + FillCount,
+ ProgressBarTop + 12,
+ 15);
+
+ /* Release the lock */
+ InbvReleaseLock();
}
}
InbvProgressState.Bias = (Ceiling * 100) - Floor;
}
+VOID
+NTAPI
+INIT_FUNCTION
+InbvIndicateProgress(VOID)
+{
+ ULONG Percentage;
+
+ /* Increase progress */
+ InbvProgressIndicator.Count++;
+
+ /* Compute new percentage */
+ Percentage = min(100 * InbvProgressIndicator.Count /
+ InbvProgressIndicator.Expected,
+ 99);
+ if (Percentage != InbvProgressIndicator.Percentage)
+ {
+ /* Percentage has moved, update the progress bar */
+ InbvProgressIndicator.Percentage = Percentage;
+ InbvUpdateProgressBar(Percentage);
+ }
+}
+
PUCHAR
NTAPI
InbvGetResourceAddress(IN ULONG ResourceNumber)
VOID
NTAPI
+INIT_FUNCTION
DisplayBootBitmap(IN BOOLEAN SosMode)
{
- PVOID Bitmap, Header;
+ PVOID Header, Band, Text, Screen;
ROT_BAR_TYPE TempRotBarSelection = RB_UNSPECIFIED;
-
+ UCHAR Buffer[64];
+
/* Check if the system thread has already been created */
if (SysThreadCreated)
{
/* Reset the progress bar */
InbvAcquireLock();
- RotBarSelection = 0;
+ RotBarSelection = RB_UNSPECIFIED;
InbvReleaseLock();
}
InbvSetTextColor(15);
InbvSolidColorFill(0, 0, 639, 479, 7);
InbvSolidColorFill(0, 421, 639, 479, 1);
-
+
/* Get resources */
- Bitmap = InbvGetResourceAddress(6);
- Header = InbvGetResourceAddress(7);
+ Header = InbvGetResourceAddress(IDB_LOGO_HEADER);
+ Band = InbvGetResourceAddress(IDB_LOGO_BAND);
}
else
{
InbvSolidColorFill(0, 421, 639, 479, 1);
/* Get resources */
- Bitmap = InbvGetResourceAddress(6);
- Header = InbvGetResourceAddress(15);
+ 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 ((Bitmap) && (Header))
+ if ((Header) && (Band))
{
/* BitBlt them on the screen */
- InbvBitBlt(Header, 0, 419);
- InbvBitBlt(Bitmap, 0, 0);
+ InbvBitBlt(Band, 0, 419);
+ InbvBitBlt(Header, 0, 0);
}
}
else
{
/* Is the boot driver installed? */
+ Text = NULL;
if (!InbvBootDriverInstalled) return;
- /* FIXME: TODO, display full-screen bitmap */
- Bitmap = InbvGetResourceAddress(5);
- if (Bitmap)
+ /* Load the standard boot screen */
+ Screen = InbvGetResourceAddress(IDB_BOOT_LOGO);
+ if (SharedUserData->NtProductType == NtProductWinNt)
{
- PBITMAPINFOHEADER BitmapInfoHeader = (PBITMAPINFOHEADER)Bitmap;
- ULONG Top, Left;
-
- Left = (640 - BitmapInfoHeader->biWidth) / 2;
- if (BitmapInfoHeader->biHeight < 0)
- Top = (480 + BitmapInfoHeader->biHeight) / 2;
+ /* 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
- Top = (480 - BitmapInfoHeader->biHeight) / 2;
- InbvBitBlt(Bitmap, Left, Top);
+ {
+ /* 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;
+
+ /* Blit the background */
+ InbvBitBlt(Screen, 0, 0);
+
+ /* Set progress bar coordinates and display it */
+ InbvSetProgressBarCoordinates(257, 352);
+
+ /* 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;
+ }
+ }
+
+ /* Draw the SKU text if it exits */
+ if (Text) InbvBitBlt(Text, 180, 121);
+
+ /* Draw the progress bar bit */
+// if (Bar) InbvBitBlt(Bar, 0, 0);
}
/* Do we have a system thread? */
VOID
NTAPI
+INIT_FUNCTION
FinalizeBootLogo(VOID)
{
/* Acquire lock and check the display state */