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