1 /* INCLUDES ******************************************************************/
6 #include "bootvid/bootvid.h"
8 /* GLOBALS *******************************************************************/
11 * Enable this define if you want Inbv to use coloured headless mode.
13 // #define INBV_HEADLESS_COLORS
16 * ReactOS uses the same boot screen for all the products.
17 * Also it doesn't use a parallel system thread for the
18 * rotating "progress" bar.
22 * Enable this define when ReactOS will have different SKUs
23 * (Workstation, Server, Storage Server, Cluster Server, etc...).
25 // #define REACTOS_SKUS
28 * Enable this define when Inbv will support rotating progress bar.
30 #define INBV_ROTBAR_IMPLEMENTED
32 static KSPIN_LOCK BootDriverLock
;
33 static KIRQL InbvOldIrql
;
34 static INBV_DISPLAY_STATE InbvDisplayState
= INBV_DISPLAY_STATE_DISABLED
;
35 BOOLEAN InbvBootDriverInstalled
= FALSE
;
36 static BOOLEAN InbvDisplayDebugStrings
= FALSE
;
37 static INBV_DISPLAY_STRING_FILTER InbvDisplayFilter
= NULL
;
38 static ULONG ProgressBarLeft
= 0, ProgressBarTop
= 0;
39 static BOOLEAN ShowProgressBar
= FALSE
;
40 static INBV_PROGRESS_STATE InbvProgressState
;
41 static BT_PROGRESS_INDICATOR InbvProgressIndicator
= {0, 25, 0};
42 static INBV_RESET_DISPLAY_PARAMETERS InbvResetDisplayParameters
= NULL
;
43 static ULONG ResourceCount
= 0;
44 static PUCHAR ResourceList
[1 + IDB_MAX_RESOURCE
]; // First entry == NULL, followed by 'ResourceCount' entries.
46 #ifdef INBV_ROTBAR_IMPLEMENTED
48 * Change this to modify progress bar behaviour
50 #define ROT_BAR_DEFAULT_MODE RB_PROGRESS_BAR
51 static BOOLEAN RotBarThreadActive
= FALSE
;
52 static ROT_BAR_TYPE RotBarSelection
;
53 static ULONG PltRotBarStatus
;
54 static PVOID RotBarThread
= NULL
;
55 static UCHAR RotBarBuffer
[24 * 9];
56 static UCHAR RotLineBuffer
[640 * 6];
61 * Headless terminal text colors
64 #ifdef INBV_HEADLESS_COLORS
66 // Conversion table CGA to ANSI color index
67 static const UCHAR CGA_TO_ANSI_COLOR_TABLE
[16] =
85 67 // Bright Grey (White)
88 #define CGA_TO_ANSI_COLOR(CgaColor) \
89 CGA_TO_ANSI_COLOR_TABLE[CgaColor & 0x0F]
93 // Default colors: text in white, background in black
94 static ULONG InbvTerminalTextColor
= 37;
95 static ULONG InbvTerminalBkgdColor
= 40;
98 /* FADING FUNCTION ***********************************************************/
100 /** From include/psdk/wingdi.h **/
101 typedef struct tagRGBQUAD
107 } RGBQUAD
,*LPRGBQUAD
;
108 /*******************************/
110 static RGBQUAD MainPalette
[16];
112 #define PALETTE_FADE_STEPS 15
113 #define PALETTE_FADE_TIME 20 * 1000 /* 20ms */
115 /** From bootvid/precomp.h **/
119 typedef struct tagBITMAPINFOHEADER
128 LONG biXPelsPerMeter
;
129 LONG biYPelsPerMeter
;
131 ULONG biClrImportant
;
132 } BITMAPINFOHEADER
, *PBITMAPINFOHEADER
;
133 /****************************/
138 VOID NTAPI
InbvAcquireLock(VOID
);
139 VOID NTAPI
InbvReleaseLock(VOID
);
144 UCHAR PaletteBitmapBuffer
[sizeof(BITMAPINFOHEADER
) + sizeof(MainPalette
)];
145 PBITMAPINFOHEADER PaletteBitmap
= (PBITMAPINFOHEADER
)PaletteBitmapBuffer
;
146 LPRGBQUAD Palette
= (LPRGBQUAD
)(PaletteBitmapBuffer
+ sizeof(BITMAPINFOHEADER
));
148 ULONG Iteration
, Index
, ClrUsed
;
150 /* Check if we're installed and we own it */
151 if (InbvBootDriverInstalled
&&
152 (InbvDisplayState
== INBV_DISPLAY_STATE_OWNED
))
154 /* Acquire the lock */
158 * Build a bitmap containing the fade in palette. The palette entries
159 * are then processed in a loop and set using VidBitBlt function.
161 ClrUsed
= RTL_NUMBER_OF(MainPalette
);
162 RtlZeroMemory(PaletteBitmap
, sizeof(BITMAPINFOHEADER
));
163 PaletteBitmap
->biSize
= sizeof(BITMAPINFOHEADER
);
164 PaletteBitmap
->biBitCount
= 4;
165 PaletteBitmap
->biClrUsed
= ClrUsed
;
168 * Main animation loop.
170 for (Iteration
= 0; Iteration
<= PALETTE_FADE_STEPS
; ++Iteration
)
172 for (Index
= 0; Index
< ClrUsed
; Index
++)
174 Palette
[Index
].rgbRed
= (UCHAR
)
175 (MainPalette
[Index
].rgbRed
* Iteration
/ PALETTE_FADE_STEPS
);
176 Palette
[Index
].rgbGreen
= (UCHAR
)
177 (MainPalette
[Index
].rgbGreen
* Iteration
/ PALETTE_FADE_STEPS
);
178 Palette
[Index
].rgbBlue
= (UCHAR
)
179 (MainPalette
[Index
].rgbBlue
* Iteration
/ PALETTE_FADE_STEPS
);
182 VidBitBlt(PaletteBitmapBuffer
, 0, 0);
185 KeStallExecutionProcessor(PALETTE_FADE_TIME
);
188 /* Release the lock */
192 KeStallExecutionProcessor(PALETTE_FADE_TIME
);
196 /* FUNCTIONS *****************************************************************/
201 FindBitmapResource(IN PLOADER_PARAMETER_BLOCK LoaderBlock
,
204 UNICODE_STRING UpString
= RTL_CONSTANT_STRING(L
"ntoskrnl.exe");
205 UNICODE_STRING MpString
= RTL_CONSTANT_STRING(L
"ntkrnlmp.exe");
206 PLIST_ENTRY NextEntry
, ListHead
;
207 PLDR_DATA_TABLE_ENTRY LdrEntry
;
208 PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry
;
209 LDR_RESOURCE_INFO ResourceInfo
;
213 /* Loop the driver list */
214 ListHead
= &LoaderBlock
->LoadOrderListHead
;
215 NextEntry
= ListHead
->Flink
;
216 while (NextEntry
!= ListHead
)
219 LdrEntry
= CONTAINING_RECORD(NextEntry
,
220 LDR_DATA_TABLE_ENTRY
,
223 /* Check for a match */
224 if (RtlEqualUnicodeString(&LdrEntry
->BaseDllName
, &UpString
, TRUE
) ||
225 RtlEqualUnicodeString(&LdrEntry
->BaseDllName
, &MpString
, TRUE
))
232 /* Check if we found it */
233 if (NextEntry
!= ListHead
)
235 /* Try to find the resource */
236 ResourceInfo
.Type
= 2; // RT_BITMAP;
237 ResourceInfo
.Name
= ResourceId
;
238 ResourceInfo
.Language
= 0;
239 Status
= LdrFindResource_U(LdrEntry
->DllBase
,
243 if (NT_SUCCESS(Status
))
245 /* Access the resource */
247 Status
= LdrAccessResource(LdrEntry
->DllBase
,
251 if ((Data
) && (ResourceId
< 3))
253 KiBugCheckData
[4] ^= RtlComputeCrc32(0, Data
, Size
);
255 if (!NT_SUCCESS(Status
)) Data
= NULL
;
259 /* Return the pointer */
266 InbvDriverInitialize(IN PLOADER_PARAMETER_BLOCK LoaderBlock
,
270 BOOLEAN ResetMode
= FALSE
; // By default do not reset the video mode
273 /* Quit if we're already installed */
274 if (InbvBootDriverInstalled
) return TRUE
;
276 /* Initialize the lock and check the current display state */
277 KeInitializeSpinLock(&BootDriverLock
);
278 if (InbvDisplayState
== INBV_DISPLAY_STATE_OWNED
)
280 /* Reset the video mode in case we do not have a custom boot logo */
281 CommandLine
= (LoaderBlock
->LoadOptions
? _strupr(LoaderBlock
->LoadOptions
) : NULL
);
282 ResetMode
= (CommandLine
== NULL
) || (strstr(CommandLine
, "BOOTLOGO") == NULL
);
285 /* Initialize the video */
286 InbvBootDriverInstalled
= VidInitialize(ResetMode
);
287 if (InbvBootDriverInstalled
)
289 /* Find bitmap resources in the kernel */
290 ResourceCount
= min(Count
, RTL_NUMBER_OF(ResourceList
) - 1);
291 for (i
= 1; i
<= ResourceCount
; i
++)
294 ResourceList
[i
] = FindBitmapResource(LoaderBlock
, i
);
297 /* Set the progress bar ranges */
298 InbvSetProgressBarSubset(0, 100);
301 /* Return install state */
302 return InbvBootDriverInstalled
;
307 InbvAcquireLock(VOID
)
311 /* Check if we're at dispatch level or lower */
312 OldIrql
= KeGetCurrentIrql();
313 if (OldIrql
<= DISPATCH_LEVEL
)
315 /* Loop until the lock is free */
316 while (!KeTestSpinLock(&BootDriverLock
));
318 /* Raise IRQL to dispatch level */
319 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
322 /* Acquire the lock */
323 KiAcquireSpinLock(&BootDriverLock
);
324 InbvOldIrql
= OldIrql
;
329 InbvReleaseLock(VOID
)
333 /* Capture the old IRQL */
334 OldIrql
= InbvOldIrql
;
336 /* Release the driver lock */
337 KiReleaseSpinLock(&BootDriverLock
);
339 /* If we were at dispatch level or lower, restore the old IRQL */
340 if (InbvOldIrql
<= DISPATCH_LEVEL
) KeLowerIrql(OldIrql
);
346 InbvEnableBootDriver(IN BOOLEAN Enable
)
348 /* Check if we're installed */
349 if (InbvBootDriverInstalled
)
351 /* Check for lost state */
352 if (InbvDisplayState
>= INBV_DISPLAY_STATE_LOST
) return;
354 /* Acquire the lock */
357 /* Cleanup the screen if we own it */
358 if (InbvDisplayState
== INBV_DISPLAY_STATE_OWNED
) VidCleanUp();
360 /* Set the new display state */
361 InbvDisplayState
= Enable
? INBV_DISPLAY_STATE_OWNED
:
362 INBV_DISPLAY_STATE_DISABLED
;
364 /* Release the lock */
369 /* Set the new display state */
370 InbvDisplayState
= Enable
? INBV_DISPLAY_STATE_OWNED
:
371 INBV_DISPLAY_STATE_DISABLED
;
377 InbvAcquireDisplayOwnership(VOID
)
379 /* Check if we have a callback and we're just acquiring it now */
380 if ((InbvResetDisplayParameters
) &&
381 (InbvDisplayState
== INBV_DISPLAY_STATE_LOST
))
383 /* Call the callback */
384 InbvResetDisplayParameters(80, 50);
387 /* Acquire the display */
388 InbvDisplayState
= INBV_DISPLAY_STATE_OWNED
;
393 InbvSetDisplayOwnership(IN BOOLEAN DisplayOwned
)
395 /* Set the new display state */
396 InbvDisplayState
= DisplayOwned
? INBV_DISPLAY_STATE_OWNED
:
397 INBV_DISPLAY_STATE_LOST
;
402 InbvCheckDisplayOwnership(VOID
)
404 /* Return if we own it or not */
405 return InbvDisplayState
!= INBV_DISPLAY_STATE_LOST
;
410 InbvGetDisplayState(VOID
)
412 /* Return the actual state */
413 return InbvDisplayState
;
418 InbvDisplayString(IN PCHAR String
)
420 /* Make sure we own the display */
421 if (InbvDisplayState
== INBV_DISPLAY_STATE_OWNED
)
423 /* If we're not allowed, return success anyway */
424 if (!InbvDisplayDebugStrings
) return TRUE
;
426 /* Check if a filter is installed */
427 if (InbvDisplayFilter
) InbvDisplayFilter(&String
);
429 /* Acquire the lock */
432 /* Make sure we're installed and display the string */
433 if (InbvBootDriverInstalled
) VidDisplayString((PUCHAR
)String
);
435 /* Print the string on the EMS port */
436 HeadlessDispatch(HeadlessCmdPutString
,
438 strlen(String
) + sizeof(ANSI_NULL
),
442 /* Release the lock */
449 /* We don't own it, fail */
455 InbvEnableDisplayString(IN BOOLEAN Enable
)
459 /* Get the old setting */
460 OldSetting
= InbvDisplayDebugStrings
;
463 InbvDisplayDebugStrings
= Enable
;
465 /* Return the old setting */
471 InbvInstallDisplayStringFilter(IN INBV_DISPLAY_STRING_FILTER Filter
)
473 /* Save the filter */
474 InbvDisplayFilter
= Filter
;
479 InbvIsBootDriverInstalled(VOID
)
481 /* Return driver state */
482 return InbvBootDriverInstalled
;
487 InbvNotifyDisplayOwnershipLost(IN INBV_RESET_DISPLAY_PARAMETERS Callback
)
489 /* Check if we're installed */
490 if (InbvBootDriverInstalled
)
492 /* Acquire the lock and cleanup if we own the screen */
494 if (InbvDisplayState
!= INBV_DISPLAY_STATE_LOST
) VidCleanUp();
496 /* Set the reset callback and display state */
497 InbvResetDisplayParameters
= Callback
;
498 InbvDisplayState
= INBV_DISPLAY_STATE_LOST
;
500 /* Release the lock */
505 /* Set the reset callback and display state */
506 InbvResetDisplayParameters
= Callback
;
507 InbvDisplayState
= INBV_DISPLAY_STATE_LOST
;
513 InbvResetDisplay(VOID
)
515 /* Check if we're installed and we own it */
516 if (InbvBootDriverInstalled
&&
517 (InbvDisplayState
== INBV_DISPLAY_STATE_OWNED
))
520 VidResetDisplay(TRUE
);
524 /* Nothing to reset */
530 InbvSetScrollRegion(IN ULONG Left
,
535 /* Just call bootvid */
536 VidSetScrollRegion(Left
, Top
, Right
, Bottom
);
541 InbvSetTextColor(IN ULONG Color
)
543 HEADLESS_CMD_SET_COLOR HeadlessSetColor
;
545 /* Set color for EMS port */
546 #ifdef INBV_HEADLESS_COLORS
547 InbvTerminalTextColor
= 30 + CGA_TO_ANSI_COLOR(Color
);
549 InbvTerminalTextColor
= 37;
551 HeadlessSetColor
.TextColor
= InbvTerminalTextColor
;
552 HeadlessSetColor
.BkgdColor
= InbvTerminalBkgdColor
;
553 HeadlessDispatch(HeadlessCmdSetColor
,
555 sizeof(HeadlessSetColor
),
559 /* Update the text color */
560 VidSetTextColor(Color
);
565 InbvSolidColorFill(IN ULONG Left
,
571 HEADLESS_CMD_SET_COLOR HeadlessSetColor
;
573 /* Make sure we own it */
574 if (InbvDisplayState
== INBV_DISPLAY_STATE_OWNED
)
576 /* Acquire the lock */
579 /* Check if we're installed */
580 if (InbvBootDriverInstalled
)
583 VidSolidColorFill(Left
, Top
, Right
, Bottom
, (UCHAR
)Color
);
586 /* Set color for EMS port and clear display */
587 #ifdef INBV_HEADLESS_COLORS
588 InbvTerminalBkgdColor
= 40 + CGA_TO_ANSI_COLOR(Color
);
590 InbvTerminalBkgdColor
= 40;
592 HeadlessSetColor
.TextColor
= InbvTerminalTextColor
;
593 HeadlessSetColor
.BkgdColor
= InbvTerminalBkgdColor
;
594 HeadlessDispatch(HeadlessCmdSetColor
,
596 sizeof(HeadlessSetColor
),
599 HeadlessDispatch(HeadlessCmdClearDisplay
,
603 /* Release the lock */
611 InbvUpdateProgressBar(IN ULONG Progress
)
613 ULONG FillCount
, BoundedProgress
;
615 /* Make sure the progress bar is enabled, that we own and are installed */
616 if (ShowProgressBar
&&
617 InbvBootDriverInstalled
&&
618 (InbvDisplayState
== INBV_DISPLAY_STATE_OWNED
))
620 /* Compute fill count */
621 BoundedProgress
= (InbvProgressState
.Floor
/ 100) + Progress
;
622 FillCount
= 121 * (InbvProgressState
.Bias
* BoundedProgress
) / 1000000;
624 /* Acquire the lock */
627 /* Fill the progress bar */
628 VidSolidColorFill(ProgressBarLeft
,
630 ProgressBarLeft
+ FillCount
,
634 /* Release the lock */
641 InbvBufferToScreenBlt(IN PUCHAR Buffer
,
648 /* Check if we're installed and we own it */
649 if (InbvBootDriverInstalled
&&
650 (InbvDisplayState
== INBV_DISPLAY_STATE_OWNED
))
653 VidBufferToScreenBlt(Buffer
, X
, Y
, Width
, Height
, Delta
);
659 InbvBitBlt(IN PUCHAR Buffer
,
663 /* Check if we're installed and we own it */
664 if (InbvBootDriverInstalled
&&
665 (InbvDisplayState
== INBV_DISPLAY_STATE_OWNED
))
667 /* Acquire the lock */
671 VidBitBlt(Buffer
, X
, Y
);
673 /* Release the lock */
680 InbvScreenToBufferBlt(IN PUCHAR Buffer
,
687 /* Check if we're installed and we own it */
688 if (InbvBootDriverInstalled
&&
689 (InbvDisplayState
== INBV_DISPLAY_STATE_OWNED
))
692 VidScreenToBufferBlt(Buffer
, X
, Y
, Width
, Height
, Delta
);
698 InbvSetProgressBarCoordinates(IN ULONG Left
,
701 /* Update the coordinates */
702 ProgressBarLeft
= Left
;
703 ProgressBarTop
= Top
;
705 /* Enable the progress bar */
706 ShowProgressBar
= TRUE
;
711 InbvSetProgressBarSubset(IN ULONG Floor
,
715 ASSERT(Floor
< Ceiling
);
716 ASSERT(Ceiling
<= 100);
718 /* Update the progress bar state */
719 InbvProgressState
.Floor
= Floor
* 100;
720 InbvProgressState
.Ceiling
= Ceiling
* 100;
721 InbvProgressState
.Bias
= (Ceiling
* 100) - Floor
;
727 InbvIndicateProgress(VOID
)
731 /* Increase progress */
732 InbvProgressIndicator
.Count
++;
734 /* Compute new percentage */
735 Percentage
= min(100 * InbvProgressIndicator
.Count
/
736 InbvProgressIndicator
.Expected
,
738 if (Percentage
!= InbvProgressIndicator
.Percentage
)
740 /* Percentage has moved, update the progress bar */
741 InbvProgressIndicator
.Percentage
= Percentage
;
742 InbvUpdateProgressBar(Percentage
);
748 InbvGetResourceAddress(IN ULONG ResourceNumber
)
750 /* Validate the resource number */
751 if (ResourceNumber
> ResourceCount
) return NULL
;
753 /* Return the address */
754 return ResourceList
[ResourceNumber
];
759 NtDisplayString(IN PUNICODE_STRING DisplayString
)
761 OEM_STRING OemString
;
763 /* Convert the string to OEM and display it */
764 RtlUnicodeStringToOemString(&OemString
, DisplayString
, TRUE
);
765 InbvDisplayString(OemString
.Buffer
);
766 RtlFreeOemString(&OemString
);
769 return STATUS_SUCCESS
;
772 #ifdef INBV_ROTBAR_IMPLEMENTED
779 ULONG X
, Y
, Index
, Total
= 18;
783 if (RotBarSelection
== RB_SQUARE_CELLS
)
785 Delay
.QuadPart
= -800000; // 0.08 sec
790 Delay
.QuadPart
= -600000; // 0.06 sec
793 X
= ProgressBarLeft
+ 2;
794 Y
= ProgressBarTop
+ 2;
797 while (InbvDisplayState
== INBV_DISPLAY_STATE_OWNED
&& PltRotBarStatus
!= 3)
801 if (RotBarSelection
== RB_SQUARE_CELLS
)
805 /* Fill previous bar position */
806 VidSolidColorFill(X
+ ((Index
- 3) * 8), Y
, (X
+ ((Index
- 3) * 8)) + 8 - 1, Y
+ 9 - 1, 0);
808 if (Index
< Total
- 1)
810 /* Draw the progress bar bit */
813 /* Appearing from the left */
814 VidBufferToScreenBlt(RotBarBuffer
+ 8 * (2 - Index
) / 2, X
, Y
, 22 - 8 * (2 - Index
), 9, 24);
816 else if (Index
>= Total
- 3)
818 /* Hiding to the right */
819 VidBufferToScreenBlt(RotBarBuffer
, X
+ ((Index
- 2) * 8), Y
, 22 - 8 * (4 - (Total
- Index
)), 9, 24);
823 VidBufferToScreenBlt(RotBarBuffer
, X
+ ((Index
- 2) * 8), Y
, 22, 9, 24);
826 Index
= (Index
+ 1) % Total
;
828 else if (RotBarSelection
== RB_PROGRESS_BAR
)
831 VidBufferToScreenBlt(RotLineBuffer
, Index
, 474, 640 - Index
, 6, 640);
835 VidBufferToScreenBlt(RotLineBuffer
+ (640 - Index
) / 2, 0, 474, Index
- 2, 6, 640);
837 Index
= (Index
+ 32) % 640;
843 KeDelayExecutionThread(KernelMode
, FALSE
, &Delay
);
845 PsTerminateSystemThread(STATUS_SUCCESS
);
854 HANDLE ThreadHandle
= NULL
;
856 if (!InbvBootDriverInstalled
|| RotBarSelection
== RB_UNSPECIFIED
)
862 Status
= PsCreateSystemThread(&ThreadHandle
,
870 if (NT_SUCCESS(Status
))
872 Status
= ObReferenceObjectByHandle(ThreadHandle
,
878 if (NT_SUCCESS(Status
))
880 KeSetPriorityThread(RotBarThread
, HIGH_PRIORITY
);
881 RotBarThreadActive
= TRUE
;
883 ObCloseHandle(ThreadHandle
, KernelMode
);
894 RotBarThreadActive
= FALSE
;
902 KeWaitForSingleObject(RotBarThread
,
907 ObDereferenceObject(RotBarThread
);
909 RotBarThreadActive
= FALSE
;
916 DisplayBootBitmap(IN BOOLEAN TextMode
)
918 PVOID Header
= NULL
, Footer
= NULL
, Screen
= NULL
;
920 #ifdef INBV_ROTBAR_IMPLEMENTED
921 UCHAR Buffer
[24 * 9];
922 PVOID Bar
= NULL
, LineBmp
= NULL
;
923 ROT_BAR_TYPE TempRotBarSelection
= RB_UNSPECIFIED
;
931 #ifdef INBV_ROTBAR_IMPLEMENTED
932 /* Check if the system thread has already been created */
933 if (RotBarThreadActive
)
935 /* Reset the progress bar */
940 ShowProgressBar
= FALSE
;
942 /* Check if this is text mode */
945 /* Check the type of the OS: workstation or server */
946 if (SharedUserData
->NtProductType
== NtProductWinNt
)
948 /* Workstation; set colors */
949 InbvSetTextColor(15);
950 InbvSolidColorFill(0, 0, 639, 479, 7);
951 InbvSolidColorFill(0, 421, 639, 479, 1);
954 Header
= InbvGetResourceAddress(IDB_WKSTA_HEADER
);
955 Footer
= InbvGetResourceAddress(IDB_WKSTA_FOOTER
);
959 /* Server; set colors */
960 InbvSetTextColor(14);
961 InbvSolidColorFill(0, 0, 639, 479, 6);
962 InbvSolidColorFill(0, 421, 639, 479, 1);
965 Header
= InbvGetResourceAddress(IDB_SERVER_HEADER
);
966 Footer
= InbvGetResourceAddress(IDB_SERVER_FOOTER
);
969 /* Set the scrolling region */
970 InbvSetScrollRegion(32, 80, 631, 400);
972 /* Make sure we have resources */
973 if (Header
&& Footer
)
975 /* BitBlt them on the screen */
976 InbvBitBlt(Footer
, 0, 419);
977 InbvBitBlt(Header
, 0, 0);
982 /* Is the boot driver installed? */
983 if (!InbvBootDriverInstalled
) return;
985 /* Load the standard boot screen */
986 Screen
= InbvGetResourceAddress(IDB_BOOT_SCREEN
);
990 if (SharedUserData
->NtProductType
== NtProductWinNt
)
992 #ifdef INBV_ROTBAR_IMPLEMENTED
993 /* Workstation product, use appropriate status bar color */
994 Bar
= InbvGetResourceAddress(IDB_BAR_WKSTA
);
999 /* Display correct branding based on server suite */
1000 if (ExVerifySuite(StorageServer
))
1002 /* Storage Server Edition */
1003 Text
= InbvGetResourceAddress(IDB_STORAGE_SERVER
);
1005 else if (ExVerifySuite(ComputeServer
))
1007 /* Compute Cluster Edition */
1008 Text
= InbvGetResourceAddress(IDB_CLUSTER_SERVER
);
1012 /* Normal edition */
1013 Text
= InbvGetResourceAddress(IDB_SERVER_LOGO
);
1016 #ifdef INBV_ROTBAR_IMPLEMENTED
1017 /* Server product, use appropriate status bar color */
1018 Bar
= InbvGetResourceAddress(IDB_BAR_SERVER
);
1022 /* Use default status bar */
1023 Bar
= InbvGetResourceAddress(IDB_BAR_WKSTA
);
1026 /* Make sure we have a logo */
1029 PBITMAPINFOHEADER BitmapInfoHeader
;
1033 * Save the main image palette and replace it with black palette,
1034 * so that we can do fade in effect later.
1036 BitmapInfoHeader
= (PBITMAPINFOHEADER
)Screen
;
1037 Palette
= (LPRGBQUAD
)((PUCHAR
)Screen
+ BitmapInfoHeader
->biSize
);
1038 RtlCopyMemory(MainPalette
, Palette
, sizeof(MainPalette
));
1039 RtlZeroMemory(Palette
, sizeof(MainPalette
));
1041 /* Blit the background */
1042 InbvBitBlt(Screen
, 0, 0);
1044 #ifdef INBV_ROTBAR_IMPLEMENTED
1045 /* Choose progress bar */
1046 TempRotBarSelection
= ROT_BAR_DEFAULT_MODE
;
1049 /* Set progress bar coordinates and display it */
1050 InbvSetProgressBarCoordinates(259, 352);
1053 /* Check for non-workstation products */
1054 if (SharedUserData
->NtProductType
!= NtProductWinNt
)
1056 /* Overwrite part of the logo for a server product */
1057 InbvScreenToBufferBlt(Buffer
, 413, 237, 7, 7, 8);
1058 InbvSolidColorFill(418, 230, 454, 256, 0);
1059 InbvBufferToScreenBlt(Buffer
, 413, 237, 7, 7, 8);
1061 /* In setup mode, you haven't selected a SKU yet */
1062 if (ExpInTextModeSetup
) Text
= NULL
;
1068 /* Draw the SKU text if it exits */
1069 if (Text
) InbvBitBlt(Text
, 180, 121);
1072 #ifdef INBV_ROTBAR_IMPLEMENTED
1075 /* Save previous screen pixels to buffer */
1076 InbvScreenToBufferBlt(Buffer
, 0, 0, 22, 9, 24);
1077 /* Draw the progress bar bit */
1078 InbvBitBlt(Bar
, 0, 0);
1079 /* Store it in global buffer */
1080 InbvScreenToBufferBlt(RotBarBuffer
, 0, 0, 22, 9, 24);
1081 /* Restore screen pixels */
1082 InbvBufferToScreenBlt(Buffer
, 0, 0, 22, 9, 24);
1085 LineBmp
= InbvGetResourceAddress(IDB_ROTATING_LINE
);
1086 if (LineBmp
&& TempRotBarSelection
== RB_PROGRESS_BAR
)
1089 InbvBitBlt(LineBmp
, 0, 474);
1090 /* Store it in global buffer */
1091 InbvScreenToBufferBlt(RotLineBuffer
, 0, 474, 640, 6, 640);
1095 /* Display the boot logo and fade it in */
1098 #ifdef INBV_ROTBAR_IMPLEMENTED
1099 if (TempRotBarSelection
!= RB_PROGRESS_BAR
)
1101 /* Hide simple progress bar if not used */
1102 ShowProgressBar
= FALSE
;
1105 /* Do we have a system thread? */
1106 if (!RotBarThreadActive
)
1108 /* We don't, initialize the progress bar */
1109 RotBarSelection
= TempRotBarSelection
;
1113 /* Start rotating bar */
1115 PltRotBarStatus
= 1;
1118 if (TempRotBarSelection
!= RB_UNSPECIFIED
)
1120 Delay
.QuadPart
= -3000000; // 0.3 sec
1121 KeDelayExecutionThread(KernelMode
, FALSE
, &Delay
);
1125 /* Set filter which will draw text display if needed */
1126 InbvInstallDisplayStringFilter(DisplayFilter
);
1133 DisplayFilter(PCHAR
*String
)
1135 /* Windows hack to skip first dots */
1136 static BOOLEAN DotHack
= TRUE
;
1138 /* If "." is given set *String to empty string */
1139 if(DotHack
&& strcmp(*String
, ".") == 0)
1144 /* Remove the filter */
1145 InbvInstallDisplayStringFilter(NULL
);
1149 /* Draw text screen */
1150 DisplayBootBitmap(TRUE
);
1157 FinalizeBootLogo(VOID
)
1159 #ifdef INBV_ROTBAR_IMPLEMENTED
1160 /* Reset rotation bar */
1163 /* Acquire lock and check the display state */
1165 if (InbvGetDisplayState() == INBV_DISPLAY_STATE_OWNED
)
1167 /* Clear the screen */
1168 VidSolidColorFill(0, 0, 639, 479, 0);