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