[NTOSKRNL]
[reactos.git] / reactos / ntoskrnl / inbv / inbv.c
1 /* INCLUDES ******************************************************************/
2
3 #include <ntoskrnl.h>
4 #define NDEBUG
5 #include <debug.h>
6 #include "bootvid/bootvid.h"
7
8 /* GLOBALS *******************************************************************/
9
10 KSPIN_LOCK BootDriverLock;
11 KIRQL InbvOldIrql;
12 INBV_DISPLAY_STATE InbvDisplayState;
13 BOOLEAN InbvBootDriverInstalled = FALSE;
14 BOOLEAN InbvDisplayDebugStrings = FALSE;
15 INBV_DISPLAY_STRING_FILTER InbvDisplayFilter;
16 ULONG ProgressBarLeft, ProgressBarTop;
17 BOOLEAN ShowProgressBar = FALSE;
18 INBV_PROGRESS_STATE InbvProgressState;
19 INBV_RESET_DISPLAY_PARAMETERS InbvResetDisplayParameters;
20 ULONG ResourceCount;
21 PUCHAR ResourceList[64];
22 BOOLEAN SysThreadCreated = FALSE;
23 ROT_BAR_TYPE RotBarSelection;
24 ULONG PltRotBarStatus;
25 BT_PROGRESS_INDICATOR InbvProgressIndicator = {0, 25, 0};
26
27 /* FADING FUNCTION ***********************************************************/
28
29 /** From include/psdk/wingdi.h **/
30 typedef struct tagRGBQUAD
31 {
32 UCHAR rgbBlue;
33 UCHAR rgbGreen;
34 UCHAR rgbRed;
35 UCHAR rgbReserved;
36 } RGBQUAD,*LPRGBQUAD;
37 /*******************************/
38
39 static RGBQUAD _MainPalette[16];
40
41 #define PALETTE_FADE_STEPS 15
42 #define PALETTE_FADE_TIME 20 * 10000 /* 20ms */
43
44 /** From bootvid/precomp.h **/
45 //
46 // Bitmap Header
47 //
48 typedef struct tagBITMAPINFOHEADER
49 {
50 ULONG biSize;
51 LONG biWidth;
52 LONG biHeight;
53 USHORT biPlanes;
54 USHORT biBitCount;
55 ULONG biCompression;
56 ULONG biSizeImage;
57 LONG biXPelsPerMeter;
58 LONG biYPelsPerMeter;
59 ULONG biClrUsed;
60 ULONG biClrImportant;
61 } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
62 /****************************/
63
64 static VOID
65 NTAPI
66 BootImageFadeProc(VOID)
67 {
68 UCHAR PaletteBitmapBuffer[sizeof(BITMAPINFOHEADER) + sizeof(_MainPalette)];
69 PBITMAPINFOHEADER PaletteBitmap = (PBITMAPINFOHEADER)PaletteBitmapBuffer;
70 LPRGBQUAD Palette = (LPRGBQUAD)(PaletteBitmapBuffer + sizeof(BITMAPINFOHEADER));
71
72 ULONG Iteration, Index, ClrUsed;
73 LARGE_INTEGER Interval;
74
75 Interval.QuadPart = -PALETTE_FADE_TIME;
76
77 /*
78 * Build a bitmap containing the fade in palette. The palette entries
79 * are then processed in a loop and set using VidBitBlt function.
80 */
81 ClrUsed = sizeof(_MainPalette) / sizeof(_MainPalette[0]);
82 RtlZeroMemory(PaletteBitmap, sizeof(BITMAPINFOHEADER));
83 PaletteBitmap->biSize = sizeof(BITMAPINFOHEADER);
84 PaletteBitmap->biBitCount = 4;
85 PaletteBitmap->biClrUsed = ClrUsed;
86
87 /*
88 * Main animation loop.
89 */
90 for (Iteration = 0; Iteration <= PALETTE_FADE_STEPS; ++Iteration)
91 {
92 for (Index = 0; Index < ClrUsed; Index++)
93 {
94 Palette[Index].rgbRed =
95 _MainPalette[Index].rgbRed * Iteration / PALETTE_FADE_STEPS;
96 Palette[Index].rgbGreen =
97 _MainPalette[Index].rgbGreen * Iteration / PALETTE_FADE_STEPS;
98 Palette[Index].rgbBlue =
99 _MainPalette[Index].rgbBlue * Iteration / PALETTE_FADE_STEPS;
100 }
101
102 VidBitBlt(PaletteBitmapBuffer, 0, 0);
103
104 /* Wait for a bit. */
105 KeDelayExecutionThread(KernelMode, FALSE, &Interval);
106 }
107
108 /* Wait for a bit. */
109 KeDelayExecutionThread(KernelMode, FALSE, &Interval);
110 }
111
112
113 /* FUNCTIONS *****************************************************************/
114
115 PVOID
116 NTAPI
117 INIT_FUNCTION
118 FindBitmapResource(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
119 IN ULONG ResourceId)
120 {
121 UNICODE_STRING UpString = RTL_CONSTANT_STRING(L"ntoskrnl.exe");
122 UNICODE_STRING MpString = RTL_CONSTANT_STRING(L"ntkrnlmp.exe");
123 PLIST_ENTRY NextEntry, ListHead;
124 PLDR_DATA_TABLE_ENTRY LdrEntry;
125 PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry;
126 LDR_RESOURCE_INFO ResourceInfo;
127 NTSTATUS Status;
128 PVOID Data = NULL;
129
130 /* Loop the driver list */
131 ListHead = &LoaderBlock->LoadOrderListHead;
132 NextEntry = ListHead->Flink;
133 while (NextEntry != ListHead)
134 {
135 /* Get the entry */
136 LdrEntry = CONTAINING_RECORD(NextEntry,
137 LDR_DATA_TABLE_ENTRY,
138 InLoadOrderLinks);
139
140 /* Check for a match */
141 if ((RtlEqualUnicodeString(&LdrEntry->BaseDllName, &UpString, TRUE)) ||
142 (RtlEqualUnicodeString(&LdrEntry->BaseDllName, &MpString, TRUE)))
143 {
144 /* Break out */
145 break;
146 }
147 }
148
149 /* Check if we found it */
150 if (NextEntry != ListHead)
151 {
152 /* Try to find the resource */
153 ResourceInfo.Type = 2; //RT_BITMAP;
154 ResourceInfo.Name = ResourceId;
155 ResourceInfo.Language = 0;
156 Status = LdrFindResource_U(LdrEntry->DllBase,
157 &ResourceInfo,
158 RESOURCE_DATA_LEVEL,
159 &ResourceDataEntry);
160 if (NT_SUCCESS(Status))
161 {
162 /* Access the resource */
163 ULONG Size = 0;
164 Status = LdrAccessResource(LdrEntry->DllBase,
165 ResourceDataEntry,
166 &Data,
167 &Size);
168 if ((Data) && (ResourceId < 3))
169 {
170 KiBugCheckData[4] ^= RtlComputeCrc32(0, Data, Size);
171 }
172 if (!NT_SUCCESS(Status)) Data = NULL;
173 }
174 }
175
176 /* Return the pointer */
177 return Data;
178 }
179
180 BOOLEAN
181 NTAPI
182 INIT_FUNCTION
183 InbvDriverInitialize(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
184 IN ULONG Count)
185 {
186 PCHAR CommandLine;
187 BOOLEAN CustomLogo = FALSE;
188 ULONG i;
189
190 /* Quit if we're already installed */
191 if (InbvBootDriverInstalled) return TRUE;
192
193 /* Initialize the lock and check the current display state */
194 KeInitializeSpinLock(&BootDriverLock);
195 if (InbvDisplayState == INBV_DISPLAY_STATE_OWNED)
196 {
197 /* Check if we have a custom boot logo */
198 CommandLine = _strupr(LoaderBlock->LoadOptions);
199 CustomLogo = strstr(CommandLine, "BOOTLOGO") ? TRUE: FALSE;
200 }
201
202 /* Initialize the video */
203 InbvBootDriverInstalled = VidInitialize(FALSE);
204 if (InbvBootDriverInstalled)
205 {
206 /* Now reset the display, but only if there's a custom boot logo */
207 VidResetDisplay(CustomLogo);
208
209 /* Find bitmap resources in the kernel */
210 ResourceCount = min(IDB_CLUSTER_SERVER, Count);
211 for (i = 1; i <= Count; i++)
212 {
213 /* Do the lookup */
214 ResourceList[i] = FindBitmapResource(LoaderBlock, i);
215 }
216
217 /* Set the progress bar ranges */
218 InbvSetProgressBarSubset(0, 100);
219 }
220
221 /* Return install state */
222 return InbvBootDriverInstalled;
223 }
224
225 VOID
226 NTAPI
227 InbvAcquireLock(VOID)
228 {
229 KIRQL OldIrql;
230
231 /* Check if we're at dispatch level or lower */
232 OldIrql = KeGetCurrentIrql();
233 if (OldIrql <= DISPATCH_LEVEL)
234 {
235 /* Loop until the lock is free */
236 while (!KeTestSpinLock(&BootDriverLock));
237
238 /* Raise IRQL to dispatch level */
239 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
240 }
241
242 /* Acquire the lock */
243 KiAcquireSpinLock(&BootDriverLock);
244 InbvOldIrql = OldIrql;
245 }
246
247 VOID
248 NTAPI
249 InbvReleaseLock(VOID)
250 {
251 KIRQL OldIrql;
252
253 /* Capture the old IRQL */
254 OldIrql = InbvOldIrql;
255
256 /* Release the driver lock */
257 KiReleaseSpinLock(&BootDriverLock);
258
259 /* If we were at dispatch level or lower, restore the old IRQL */
260 if (InbvOldIrql <= DISPATCH_LEVEL) KeLowerIrql(OldIrql);
261 }
262
263 VOID
264 NTAPI
265 INIT_FUNCTION
266 InbvEnableBootDriver(IN BOOLEAN Enable)
267 {
268 /* Check if we're installed */
269 if (InbvBootDriverInstalled)
270 {
271 /* Check for lost state */
272 if (InbvDisplayState >= INBV_DISPLAY_STATE_LOST) return;
273
274 /* Acquire the lock */
275 InbvAcquireLock();
276
277 /* Cleanup the screen if we own it */
278 if (InbvDisplayState == INBV_DISPLAY_STATE_OWNED) VidCleanUp();
279
280 /* Set the new display state */
281 InbvDisplayState = Enable ? INBV_DISPLAY_STATE_OWNED:
282 INBV_DISPLAY_STATE_DISABLED;
283
284 /* Release the lock */
285 InbvReleaseLock();
286 }
287 else
288 {
289 /* Set the new display state */
290 InbvDisplayState = Enable ? INBV_DISPLAY_STATE_OWNED:
291 INBV_DISPLAY_STATE_DISABLED;
292 }
293 }
294
295 VOID
296 NTAPI
297 InbvAcquireDisplayOwnership(VOID)
298 {
299 /* Check if we have a callback and we're just acquiring it now */
300 if ((InbvResetDisplayParameters) &&
301 (InbvDisplayState == INBV_DISPLAY_STATE_LOST))
302 {
303 /* Call the callback */
304 InbvResetDisplayParameters(80, 50);
305 }
306
307 /* Acquire the display */
308 InbvDisplayState = INBV_DISPLAY_STATE_OWNED;
309 }
310
311 VOID
312 NTAPI
313 InbvSetDisplayOwnership(IN BOOLEAN DisplayOwned)
314 {
315 /* Set the new display state */
316 InbvDisplayState = DisplayOwned ? INBV_DISPLAY_STATE_OWNED:
317 INBV_DISPLAY_STATE_LOST;
318 }
319
320 BOOLEAN
321 NTAPI
322 InbvCheckDisplayOwnership(VOID)
323 {
324 /* Return if we own it or not */
325 return InbvDisplayState != INBV_DISPLAY_STATE_LOST;
326 }
327
328 INBV_DISPLAY_STATE
329 NTAPI
330 InbvGetDisplayState(VOID)
331 {
332 /* Return the actual state */
333 return InbvDisplayState;
334 }
335
336 BOOLEAN
337 NTAPI
338 InbvDisplayString(IN PCHAR String)
339 {
340 /* Make sure we own the display */
341 if (InbvDisplayState == INBV_DISPLAY_STATE_OWNED)
342 {
343 /* If we're not allowed, return success anyway */
344 if (!InbvDisplayDebugStrings) return TRUE;
345
346 /* Check if a filter is installed */
347 if (InbvDisplayFilter) InbvDisplayFilter(&String);
348
349 /* Acquire the lock */
350 InbvAcquireLock();
351
352 /* Make sure we're installed and display the string */
353 if (InbvBootDriverInstalled) VidDisplayString((PUCHAR) String);
354
355 /* Print the string on the EMS port */
356 HeadlessDispatch(HeadlessCmdPutString,
357 String,
358 strlen(String) + sizeof(ANSI_NULL),
359 NULL,
360 NULL);
361
362 /* Release the lock */
363 InbvReleaseLock();
364
365 /* All done */
366 return TRUE;
367 }
368
369 /* We don't own it, fail */
370 return FALSE;
371 }
372
373 BOOLEAN
374 NTAPI
375 InbvEnableDisplayString(IN BOOLEAN Enable)
376 {
377 BOOLEAN OldSetting;
378
379 /* Get the old setting */
380 OldSetting = InbvDisplayDebugStrings;
381
382 /* Update it */
383 InbvDisplayDebugStrings = Enable;
384
385 /* Return the old setting */
386 return OldSetting;
387 }
388
389 VOID
390 NTAPI
391 InbvInstallDisplayStringFilter(IN INBV_DISPLAY_STRING_FILTER Filter)
392 {
393 /* Save the filter */
394 InbvDisplayFilter = Filter;
395 }
396
397 BOOLEAN
398 NTAPI
399 InbvIsBootDriverInstalled(VOID)
400 {
401 /* Return driver state */
402 return InbvBootDriverInstalled;
403 }
404
405 VOID
406 NTAPI
407 InbvNotifyDisplayOwnershipLost(IN INBV_RESET_DISPLAY_PARAMETERS Callback)
408 {
409 /* Check if we're installed */
410 if (InbvBootDriverInstalled)
411 {
412 /* Acquire the lock and cleanup if we own the screen */
413 InbvAcquireLock();
414 if (InbvDisplayState != INBV_DISPLAY_STATE_LOST) VidCleanUp();
415
416 /* Set the reset callback and display state */
417 InbvResetDisplayParameters = Callback;
418 InbvDisplayState = INBV_DISPLAY_STATE_LOST;
419
420 /* Release the lock */
421 InbvReleaseLock();
422 }
423 else
424 {
425 /* Set the reset callback and display state */
426 InbvResetDisplayParameters = Callback;
427 InbvDisplayState = INBV_DISPLAY_STATE_LOST;
428 }
429 }
430
431 BOOLEAN
432 NTAPI
433 InbvResetDisplay(VOID)
434 {
435 /* Check if we're installed and we own it */
436 if ((InbvBootDriverInstalled) &&
437 (InbvDisplayState == INBV_DISPLAY_STATE_OWNED))
438 {
439 /* Do the reset */
440 VidResetDisplay(TRUE);
441 return TRUE;
442 }
443
444 /* Nothing to reset */
445 return FALSE;
446 }
447
448 VOID
449 NTAPI
450 InbvSetScrollRegion(IN ULONG Left,
451 IN ULONG Top,
452 IN ULONG Width,
453 IN ULONG Height)
454 {
455 /* Just call bootvid */
456 VidSetScrollRegion(Left, Top, Width, Height);
457 }
458
459 VOID
460 NTAPI
461 InbvSetTextColor(IN ULONG Color)
462 {
463 /* FIXME: Headless */
464
465 /* Update the text color */
466 VidSetTextColor(Color);
467 }
468
469 VOID
470 NTAPI
471 InbvSolidColorFill(IN ULONG Left,
472 IN ULONG Top,
473 IN ULONG Width,
474 IN ULONG Height,
475 IN ULONG Color)
476 {
477 /* Make sure we own it */
478 if (InbvDisplayState == INBV_DISPLAY_STATE_OWNED)
479 {
480 /* Acquire the lock */
481 InbvAcquireLock();
482
483 /* Check if we're installed */
484 if (InbvBootDriverInstalled)
485 {
486 /* Call bootvid */
487 VidSolidColorFill(Left, Top, Width, Height, (UCHAR)Color);
488 }
489
490 /* FIXME: Headless */
491
492 /* Release the lock */
493 InbvReleaseLock();
494 }
495 }
496
497 VOID
498 NTAPI
499 INIT_FUNCTION
500 InbvUpdateProgressBar(IN ULONG Progress)
501 {
502 ULONG FillCount, BoundedProgress;
503
504 /* Make sure the progress bar is enabled, that we own and are installed */
505 if ((ShowProgressBar) &&
506 (InbvBootDriverInstalled) &&
507 (InbvDisplayState == INBV_DISPLAY_STATE_OWNED))
508 {
509 /* Compute fill count */
510 BoundedProgress = (InbvProgressState.Floor / 100) + Progress;
511 FillCount = 121 * (InbvProgressState.Bias * BoundedProgress) / 1000000;
512
513 /* Acquire the lock */
514 InbvAcquireLock();
515
516 /* Fill the progress bar */
517 VidSolidColorFill(ProgressBarLeft,
518 ProgressBarTop,
519 ProgressBarLeft + FillCount,
520 ProgressBarTop + 12,
521 15);
522
523 /* Release the lock */
524 InbvReleaseLock();
525 }
526 }
527
528 VOID
529 NTAPI
530 InbvBufferToScreenBlt(IN PUCHAR Buffer,
531 IN ULONG X,
532 IN ULONG Y,
533 IN ULONG Width,
534 IN ULONG Height,
535 IN ULONG Delta)
536 {
537 /* Check if we're installed and we own it */
538 if ((InbvBootDriverInstalled) &&
539 (InbvDisplayState == INBV_DISPLAY_STATE_OWNED))
540 {
541 /* Do the blit */
542 VidBufferToScreenBlt(Buffer, X, Y, Width, Height, Delta);
543 }
544 }
545
546 VOID
547 NTAPI
548 InbvBitBlt(IN PUCHAR Buffer,
549 IN ULONG X,
550 IN ULONG Y)
551 {
552 /* Check if we're installed and we own it */
553 if ((InbvBootDriverInstalled) &&
554 (InbvDisplayState == INBV_DISPLAY_STATE_OWNED))
555 {
556 /* Acquire the lock */
557 InbvAcquireLock();
558
559 /* Do the blit */
560 VidBitBlt(Buffer, X, Y);
561
562 /* Release the lock */
563 InbvReleaseLock();
564 }
565 }
566
567 VOID
568 NTAPI
569 InbvScreenToBufferBlt(IN PUCHAR Buffer,
570 IN ULONG X,
571 IN ULONG Y,
572 IN ULONG Width,
573 IN ULONG Height,
574 IN ULONG Delta)
575 {
576 /* Check if we're installed and we own it */
577 if ((InbvBootDriverInstalled) &&
578 (InbvDisplayState == INBV_DISPLAY_STATE_OWNED))
579 {
580 /* Do the blit */
581 VidScreenToBufferBlt(Buffer, X, Y, Width, Height, Delta);
582 }
583 }
584
585 VOID
586 NTAPI
587 InbvSetProgressBarCoordinates(IN ULONG Left,
588 IN ULONG Top)
589 {
590 /* Update the coordinates */
591 ProgressBarLeft = Left;
592 ProgressBarTop = Top;
593
594 /* Enable the progress bar */
595 ShowProgressBar = TRUE;
596 }
597
598 VOID
599 NTAPI
600 InbvSetProgressBarSubset(IN ULONG Floor,
601 IN ULONG Ceiling)
602 {
603 /* Sanity checks */
604 ASSERT(Floor < Ceiling);
605 ASSERT(Ceiling <= 100);
606
607 /* Update the progress bar state */
608 InbvProgressState.Floor = Floor * 100;
609 InbvProgressState.Ceiling = Ceiling * 100;
610 InbvProgressState.Bias = (Ceiling * 100) - Floor;
611 }
612
613 VOID
614 NTAPI
615 INIT_FUNCTION
616 InbvIndicateProgress(VOID)
617 {
618 ULONG Percentage;
619
620 /* Increase progress */
621 InbvProgressIndicator.Count++;
622
623 /* Compute new percentage */
624 Percentage = min(100 * InbvProgressIndicator.Count /
625 InbvProgressIndicator.Expected,
626 99);
627 if (Percentage != InbvProgressIndicator.Percentage)
628 {
629 /* Percentage has moved, update the progress bar */
630 InbvProgressIndicator.Percentage = Percentage;
631 InbvUpdateProgressBar(Percentage);
632 }
633 }
634
635 PUCHAR
636 NTAPI
637 InbvGetResourceAddress(IN ULONG ResourceNumber)
638 {
639 /* Validate the resource number */
640 if (ResourceNumber > ResourceCount) return NULL;
641
642 /* Return the address */
643 return ResourceList[ResourceNumber--];
644 }
645
646 NTSTATUS
647 NTAPI
648 NtDisplayString(IN PUNICODE_STRING DisplayString)
649 {
650 OEM_STRING OemString;
651
652 /* Convert the string to OEM and display it */
653 RtlUnicodeStringToOemString(&OemString, DisplayString, TRUE);
654 InbvDisplayString(OemString.Buffer);
655 RtlFreeOemString(&OemString);
656
657 /* Return success */
658 return STATUS_SUCCESS;
659 }
660
661 VOID
662 NTAPI
663 INIT_FUNCTION
664 DisplayBootBitmap(IN BOOLEAN TextMode)
665 {
666 PBITMAPINFOHEADER BitmapInfoHeader;
667 LPRGBQUAD Palette;
668
669 PVOID Header, Band, Text, Screen;
670 ROT_BAR_TYPE TempRotBarSelection = RB_UNSPECIFIED;
671 // UCHAR Buffer[64];
672
673 /* Check if the system thread has already been created */
674 if (SysThreadCreated)
675 {
676 /* Reset the progress bar */
677 InbvAcquireLock();
678 RotBarSelection = RB_UNSPECIFIED;
679 InbvReleaseLock();
680 }
681
682 /* Check if this is text mode */
683 ShowProgressBar = FALSE;
684 if (TextMode)
685 {
686 /* Check if this is a server OS */
687 if (SharedUserData->NtProductType == NtProductWinNt)
688 {
689 /* It's not, set workstation settings */
690 InbvSetTextColor(15);
691 InbvSolidColorFill(0, 0, 639, 479, 7);
692 InbvSolidColorFill(0, 421, 639, 479, 1);
693
694 /* Get resources */
695 Header = InbvGetResourceAddress(IDB_LOGO_HEADER);
696 Band = InbvGetResourceAddress(IDB_LOGO_BAND);
697 }
698 else
699 {
700 /* Set server settings */
701 InbvSetTextColor(14);
702 InbvSolidColorFill(0, 0, 639, 479, 6);
703 InbvSolidColorFill(0, 421, 639, 479, 1);
704
705 /* Get resources */
706 Header = InbvGetResourceAddress(IDB_SERVER_HEADER);
707 Band = InbvGetResourceAddress(IDB_SERVER_BAND);
708 }
709
710 /* Set the scrolling region */
711 InbvSetScrollRegion(32, 80, 631, 400);
712
713 /* Make sure we have resources */
714 if ((Header) && (Band))
715 {
716 /* BitBlt them on the screen */
717 InbvBitBlt(Band, 0, 419);
718 InbvBitBlt(Header, 0, 0);
719 }
720 }
721 else
722 {
723 /* Is the boot driver installed? */
724 Text = NULL;
725 if (!InbvBootDriverInstalled) return;
726
727 /* Load the standard boot screen */
728 Screen = InbvGetResourceAddress(IDB_BOOT_LOGO);
729 if (SharedUserData->NtProductType == NtProductWinNt)
730 {
731 /* Workstation product, display appropriate status bar color */
732 InbvGetResourceAddress(IDB_BAR_PRO);
733 }
734 else
735 {
736 /* Display correct branding based on server suite */
737 if (ExVerifySuite(StorageServer))
738 {
739 /* Storage Server Edition */
740 Text = InbvGetResourceAddress(IDB_STORAGE_SERVER);
741 }
742 else if (ExVerifySuite(ComputeServer))
743 {
744 /* Compute Cluster Edition */
745 Text = InbvGetResourceAddress(IDB_CLUSTER_SERVER);
746 }
747 else
748 {
749 /* Normal edition */
750 Text = InbvGetResourceAddress(IDB_SERVER_LOGO);
751 }
752
753 /* Server product, display appropriate status bar color */
754 InbvGetResourceAddress(IDB_BAR_SERVER);
755 }
756
757 /* Make sure we had a logo */
758 if (Screen)
759 {
760 /* Choose progress bar */
761 TempRotBarSelection = RB_SQUARE_CELLS;
762
763 /*
764 * Save the main image palette and replace it with black palette, so
765 * we can do fade in effect later.
766 */
767 BitmapInfoHeader = (PBITMAPINFOHEADER)Screen;
768 Palette = (LPRGBQUAD)((PUCHAR)Screen + BitmapInfoHeader->biSize);
769 RtlCopyMemory(_MainPalette, Palette, sizeof(_MainPalette));
770 RtlZeroMemory(Palette, sizeof(_MainPalette));
771
772 /* Blit the background */
773 InbvBitBlt(Screen, 0, 0);
774
775 /* Set progress bar coordinates and display it */
776 InbvSetProgressBarCoordinates(257, 352);
777
778 /* Display the boot logo and fade it in */
779 BootImageFadeProc();
780
781 #if 0
782 /* Check for non-workstation products */
783 if (SharedUserData->NtProductType != NtProductWinNt)
784 {
785 /* Overwrite part of the logo for a server product */
786 InbvScreenToBufferBlt(Buffer, 413, 237, 7, 7, 8);
787 InbvSolidColorFill(418, 230, 454, 256, 0);
788 InbvBufferToScreenBlt(Buffer, 413, 237, 7, 7, 8);
789
790 /* In setup mode, you haven't selected a SKU yet */
791 if (ExpInTextModeSetup) Text = NULL;
792 }
793 #endif
794 }
795
796 /* Draw the SKU text if it exits */
797 // if (Text) InbvBitBlt(Text, 180, 121);
798
799 /* Draw the progress bar bit */
800 // if (Bar) InbvBitBlt(Bar, 0, 0);
801
802 /* Set filter which will draw text display if needed */
803 InbvInstallDisplayStringFilter(DisplayFilter);
804 }
805
806 /* Do we have a system thread? */
807 if (SysThreadCreated)
808 {
809 /* We do, set the progress bar location */
810 InbvAcquireLock();
811 RotBarSelection = TempRotBarSelection;
812 //InbvRotBarInit();
813 InbvReleaseLock();
814 }
815 }
816
817 VOID
818 NTAPI
819 INIT_FUNCTION
820 DisplayFilter(PCHAR *String)
821 {
822 /* Windows hack to skip first dots */
823 static BOOLEAN DotHack = TRUE;
824
825 /* If "." is given set *String to empty string */
826 if(DotHack && strcmp(*String, ".") == 0)
827 *String = "";
828
829 if(**String)
830 {
831 /* Remove the filter */
832 InbvInstallDisplayStringFilter(NULL);
833
834 DotHack = FALSE;
835
836 /* Draw text screen */
837 DisplayBootBitmap(TRUE);
838 }
839 }
840
841 VOID
842 NTAPI
843 INIT_FUNCTION
844 FinalizeBootLogo(VOID)
845 {
846 /* Acquire lock and check the display state */
847 InbvAcquireLock();
848 if (InbvGetDisplayState() == INBV_DISPLAY_STATE_OWNED)
849 {
850 /* Clear the screen */
851 VidSolidColorFill(0, 0, 639, 479, 0);
852 }
853
854 /* Reset progress bar and lock */
855 PltRotBarStatus = 3;
856 InbvReleaseLock();
857 }