1 /* INCLUDES ******************************************************************/
6 #include "bootvid/bootvid.h"
11 typedef struct tagBITMAPINFOHEADER
24 } BITMAPINFOHEADER
, *PBITMAPINFOHEADER
;
26 /* GLOBALS *******************************************************************/
28 KSPIN_LOCK BootDriverLock
;
30 INBV_DISPLAY_STATE InbvDisplayState
;
31 BOOLEAN InbvBootDriverInstalled
;
32 BOOLEAN InbvDisplayDebugStrings
;
33 INBV_DISPLAY_STRING_FILTER InbvDisplayFilter
;
34 ULONG ProgressBarLeft
, ProgressBarTop
;
35 BOOLEAN ShowProgressBar
;
36 INBV_PROGRESS_STATE InbvProgressState
;
37 INBV_RESET_DISPLAY_PARAMETERS InbvResetDisplayParameters
;
39 PUCHAR ResourceList
[64];
40 BOOLEAN SysThreadCreated
;
41 ROT_BAR_TYPE RotBarSelection
;
42 ULONG PltRotBarStatus
;
44 /* FUNCTIONS *****************************************************************/
48 FindBitmapResource(IN PLOADER_PARAMETER_BLOCK LoaderBlock
,
51 UNICODE_STRING UpString
= RTL_CONSTANT_STRING(L
"ntoskrnl.exe");
52 UNICODE_STRING MpString
= RTL_CONSTANT_STRING(L
"ntkrnlmp.exe");
53 PLIST_ENTRY NextEntry
, ListHead
;
54 PLDR_DATA_TABLE_ENTRY LdrEntry
;
55 PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry
;
56 LDR_RESOURCE_INFO ResourceInfo
;
61 /* Loop the driver list */
62 ListHead
= &LoaderBlock
->LoadOrderListHead
;
63 NextEntry
= ListHead
->Flink
;
64 while (NextEntry
!= ListHead
)
67 LdrEntry
= CONTAINING_RECORD(NextEntry
,
71 /* Check for a match */
72 if ((RtlEqualUnicodeString(&LdrEntry
->BaseDllName
, &UpString
, TRUE
)) ||
73 (RtlEqualUnicodeString(&LdrEntry
->BaseDllName
, &MpString
, TRUE
)))
80 /* Check if we found it */
81 if (NextEntry
!= ListHead
)
83 /* Try to find the resource */
84 ResourceInfo
.Type
= 2;
85 ResourceInfo
.Name
= ResourceId
;
86 ResourceInfo
.Language
= 0;
87 Status
= LdrFindResource_U(LdrEntry
->DllBase
,
91 if (NT_SUCCESS(Status
))
93 /* Access the resource */
94 Status
= LdrAccessResource(LdrEntry
->DllBase
,
98 if (!NT_SUCCESS(Status
)) Data
= NULL
;
102 /* Return the pointer */
108 InbvDriverInitialize(IN PLOADER_PARAMETER_BLOCK LoaderBlock
,
112 BOOLEAN CustomLogo
= FALSE
;
114 extern BOOLEAN ExpInTextModeSetup
;
116 /* Quit if we're already installed */
117 if (InbvBootDriverInstalled
) return TRUE
;
119 /* Initialize the lock and check the current display state */
120 KeInitializeSpinLock(&BootDriverLock
);
121 if (InbvDisplayState
== INBV_DISPLAY_STATE_OWNED
)
123 /* Check if we have a custom boot logo */
124 CommandLine
= _strupr(LoaderBlock
->LoadOptions
);
125 CustomLogo
= strstr(CommandLine
, "BOOTLOGO") ? TRUE
: FALSE
;
128 /* For SetupLDR, don't reset the BIOS Display -- FIXME! */
129 if (ExpInTextModeSetup
) CustomLogo
= TRUE
;
131 /* Initialize the video */
132 InbvBootDriverInstalled
= VidInitialize(!CustomLogo
);
133 if (InbvBootDriverInstalled
)
135 /* Find bitmap resources in the kernel */
136 ResourceCount
= Count
;
137 for (i
= 0; i
< Count
; i
++)
140 ResourceList
[i
] = FindBitmapResource(LoaderBlock
, i
);
143 /* Set the progress bar ranges */
144 InbvSetProgressBarSubset(0, 100);
147 /* Return install state */
148 return InbvBootDriverInstalled
;
153 InbvAcquireLock(VOID
)
155 /* Check if we're below dispatch level */
156 InbvOldIrql
= KeGetCurrentIrql();
157 if (InbvOldIrql
< DISPATCH_LEVEL
)
159 /* Raise IRQL to dispatch level */
160 InbvOldIrql
= KfRaiseIrql(DISPATCH_LEVEL
);
163 /* Acquire the lock */
164 KiAcquireSpinLock(&BootDriverLock
);
169 InbvReleaseLock(VOID
)
171 /* Release the driver lock */
172 KiReleaseSpinLock(&BootDriverLock
);
174 /* If we were below dispatch level, lower IRQL back */
175 if (InbvOldIrql
< DISPATCH_LEVEL
) KfLowerIrql(InbvOldIrql
);
180 InbvEnableBootDriver(IN BOOLEAN Enable
)
182 /* Check if we're installed */
183 if (InbvBootDriverInstalled
)
185 /* Check for lost state */
186 if (InbvDisplayState
>= INBV_DISPLAY_STATE_LOST
) return;
188 /* Acquire the lock */
191 /* Cleanup the screen if we own it */
192 if (InbvDisplayState
== INBV_DISPLAY_STATE_OWNED
) VidCleanUp();
194 /* Set the new display state */
195 InbvDisplayState
= Enable
? INBV_DISPLAY_STATE_OWNED
:
196 INBV_DISPLAY_STATE_DISABLED
;
198 /* Release the lock */
203 /* Set the new display state */
204 InbvDisplayState
= Enable
? INBV_DISPLAY_STATE_OWNED
:
205 INBV_DISPLAY_STATE_DISABLED
;
211 InbvAcquireDisplayOwnership(VOID
)
213 /* Check if we have a callback and we're just acquiring it now */
214 if ((InbvResetDisplayParameters
) &&
215 (InbvDisplayState
== INBV_DISPLAY_STATE_LOST
))
217 /* Call the callback */
218 InbvResetDisplayParameters(80, 50);
221 /* Acquire the display */
222 InbvDisplayState
= INBV_DISPLAY_STATE_OWNED
;
227 InbvSetDisplayOwnership(IN BOOLEAN DisplayOwned
)
229 /* Set the new display state */
230 InbvDisplayState
= DisplayOwned
? INBV_DISPLAY_STATE_OWNED
:
231 INBV_DISPLAY_STATE_LOST
;
236 InbvCheckDisplayOwnership(VOID
)
238 /* Return if we own it or not */
239 return InbvDisplayState
!= INBV_DISPLAY_STATE_LOST
;
244 InbvGetDisplayState(VOID
)
246 /* Return the actual state */
247 return InbvDisplayState
;
252 InbvDisplayString(IN PCHAR String
)
254 /* Make sure we own the display */
255 if (InbvDisplayState
== INBV_DISPLAY_STATE_OWNED
)
257 /* If we're not allowed, return success anyway */
258 if (!InbvDisplayDebugStrings
) return TRUE
;
260 /* Check if a filter is installed */
261 if (InbvDisplayFilter
) InbvDisplayFilter(&String
);
263 /* Acquire the lock */
266 /* Make sure we're installed and display the string */
267 if (InbvBootDriverInstalled
) VidDisplayString((PUCHAR
) String
);
269 /* Call Headless (We don't support headless for now)
270 HeadlessDispatch(DISPLAY_STRING); */
272 /* Release the lock */
279 /* We don't own it, fail */
285 InbvEnableDisplayString(IN BOOLEAN Enable
)
289 /* Get the old setting */
290 OldSetting
= InbvDisplayDebugStrings
;
293 InbvDisplayDebugStrings
= Enable
;
295 /* Return the old setting */
301 InbvInstallDisplayStringFilter(IN INBV_DISPLAY_STRING_FILTER Filter
)
303 /* Save the filter */
304 InbvDisplayFilter
= Filter
;
309 InbvIsBootDriverInstalled(VOID
)
311 /* Return driver state */
312 return InbvBootDriverInstalled
;
317 InbvNotifyDisplayOwnershipLost(IN INBV_RESET_DISPLAY_PARAMETERS Callback
)
319 /* Check if we're installed */
320 if (InbvBootDriverInstalled
)
322 /* Acquire the lock and cleanup if we own the screen */
324 if (InbvDisplayState
!= INBV_DISPLAY_STATE_LOST
) VidCleanUp();
326 /* Set the reset callback and display state */
327 InbvResetDisplayParameters
= Callback
;
328 InbvDisplayState
= INBV_DISPLAY_STATE_LOST
;
330 /* Release the lock */
335 /* Set the reset callback and display state */
336 InbvResetDisplayParameters
= Callback
;
337 InbvDisplayState
= INBV_DISPLAY_STATE_LOST
;
343 InbvResetDisplay(VOID
)
345 /* Check if we're installed and we own it */
346 if ((InbvBootDriverInstalled
) &&
347 (InbvDisplayState
== INBV_DISPLAY_STATE_OWNED
))
350 VidResetDisplay(TRUE
);
354 /* Nothing to reset */
360 InbvSetScrollRegion(IN ULONG Left
,
365 /* Just call bootvid */
366 VidSetScrollRegion(Left
, Top
, Width
, Height
);
371 InbvSetTextColor(IN ULONG Color
)
373 /* FIXME: Headless */
375 /* Update the text color */
376 VidSetTextColor(Color
);
381 InbvSolidColorFill(IN ULONG Left
,
387 /* Make sure we own it */
388 if (InbvDisplayState
== INBV_DISPLAY_STATE_OWNED
)
390 /* Acquire the lock */
393 /* Check if we're installed */
394 if (InbvBootDriverInstalled
)
397 VidSolidColorFill(Left
, Top
, Width
, Height
, (UCHAR
)Color
);
400 /* FIXME: Headless */
402 /* Release the lock */
409 InbvUpdateProgressBar(IN ULONG Progress
)
411 ULONG FillCount
, Left
= 0;
413 /* Make sure the progress bar is enabled, that we own and are installed */
414 if ((ShowProgressBar
) &&
415 (InbvBootDriverInstalled
) &&
416 (InbvDisplayState
== INBV_DISPLAY_STATE_OWNED
))
418 /* Calculate the fill count */
419 FillCount
= InbvProgressState
.Bias
* Progress
+ InbvProgressState
.Floor
;
423 /* Start fill loop */
426 /* Acquire the lock */
429 /* Fill the progress bar */
430 VidSolidColorFill(Left
+ ProgressBarLeft
,
432 Left
+ ProgressBarLeft
+ 7,
436 /* Release the lock */
439 /* Update the X position */
448 InbvBufferToScreenBlt(IN PUCHAR Buffer
,
455 /* Check if we're installed and we own it */
456 if ((InbvBootDriverInstalled
) &&
457 (InbvDisplayState
== INBV_DISPLAY_STATE_OWNED
))
460 VidBufferToScreenBlt(Buffer
, X
, Y
, Width
, Height
, Delta
);
466 InbvBitBlt(IN PUCHAR Buffer
,
470 /* Check if we're installed and we own it */
471 if ((InbvBootDriverInstalled
) &&
472 (InbvDisplayState
== INBV_DISPLAY_STATE_OWNED
))
474 /* Acquire the lock */
478 VidBitBlt(Buffer
, X
, Y
);
480 /* Release the lock */
487 InbvScreenToBufferBlt(IN PUCHAR Buffer
,
494 /* Check if we're installed and we own it */
495 if ((InbvBootDriverInstalled
) &&
496 (InbvDisplayState
== INBV_DISPLAY_STATE_OWNED
))
499 VidScreenToBufferBlt(Buffer
, X
, Y
, Width
, Height
, Delta
);
505 InbvSetProgressBarCoordinates(IN ULONG Left
,
508 /* Update the coordinates */
509 ProgressBarLeft
= Left
;
510 ProgressBarTop
= Top
;
512 /* Enable the progress bar */
513 ShowProgressBar
= TRUE
;
518 InbvSetProgressBarSubset(IN ULONG Floor
,
522 ASSERT(Floor
< Ceiling
);
523 ASSERT(Ceiling
<= 100);
525 /* Update the progress bar state */
526 InbvProgressState
.Floor
= Floor
* 100;
527 InbvProgressState
.Ceiling
= Ceiling
* 100;
528 InbvProgressState
.Bias
= (Ceiling
* 100) - Floor
;
533 InbvGetResourceAddress(IN ULONG ResourceNumber
)
535 /* Validate the resource number */
536 if (ResourceNumber
> ResourceCount
) return NULL
;
538 /* Return the address */
539 return ResourceList
[ResourceNumber
--];
544 NtDisplayString(IN PUNICODE_STRING DisplayString
)
546 OEM_STRING OemString
;
548 /* Convert the string to OEM and display it */
549 RtlUnicodeStringToOemString(&OemString
, DisplayString
, TRUE
);
550 InbvDisplayString(OemString
.Buffer
);
551 RtlFreeOemString(&OemString
);
554 return STATUS_SUCCESS
;
559 DisplayBootBitmap(IN BOOLEAN SosMode
)
561 PVOID Bitmap
, Header
;
562 ROT_BAR_TYPE TempRotBarSelection
= RB_UNSPECIFIED
;
564 /* Check if the system thread has already been created */
565 if (SysThreadCreated
)
567 /* Reset the progress bar */
573 /* Check if this is SOS mode */
574 ShowProgressBar
= FALSE
;
577 /* Check if this is a server OS */
578 if (SharedUserData
->NtProductType
== NtProductWinNt
)
580 /* It's not, set workstation settings */
581 InbvSetTextColor(15);
582 InbvSolidColorFill(0, 0, 639, 479, 7);
583 InbvSolidColorFill(0, 421, 639, 479, 1);
586 Bitmap
= InbvGetResourceAddress(6);
587 Header
= InbvGetResourceAddress(7);
591 /* Set server settings */
592 InbvSetTextColor(14);
593 InbvSolidColorFill(0, 0, 639, 479, 6);
594 InbvSolidColorFill(0, 421, 639, 479, 1);
597 Bitmap
= InbvGetResourceAddress(6);
598 Header
= InbvGetResourceAddress(15);
601 /* Set the scrolling region */
602 InbvSetScrollRegion(32, 80, 631, 400);
604 /* Make sure we have resources */
605 if ((Bitmap
) && (Header
))
607 /* BitBlt them on the screen */
608 InbvBitBlt(Header
, 0, 419);
609 InbvBitBlt(Bitmap
, 0, 0);
614 /* Is the boot driver installed? */
615 if (!InbvBootDriverInstalled
) return;
617 /* FIXME: TODO, display full-screen bitmap */
618 Bitmap
= InbvGetResourceAddress(5);
621 PBITMAPINFOHEADER BitmapInfoHeader
= (PBITMAPINFOHEADER
)Bitmap
;
624 Left
= (640 - BitmapInfoHeader
->biWidth
) / 2;
625 if (BitmapInfoHeader
->biHeight
< 0)
626 Top
= (480 + BitmapInfoHeader
->biHeight
) / 2;
628 Top
= (480 - BitmapInfoHeader
->biHeight
) / 2;
629 InbvBitBlt(Bitmap
, Left
, Top
);
633 /* Do we have a system thread? */
634 if (SysThreadCreated
)
636 /* We do, set the progress bar location */
638 RotBarSelection
= TempRotBarSelection
;
646 FinalizeBootLogo(VOID
)
648 /* Acquire lock and check the display state */
650 if (InbvGetDisplayState() == INBV_DISPLAY_STATE_OWNED
)
652 /* Clear the screen */
653 VidSolidColorFill(0, 0, 639, 479, 0);
656 /* Reset progress bar and lock */