Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1135 lines
22 KiB

  1. /*++
  2. Copyright (c) 1990-1998 Microsoft Corporation
  3. Module Name:
  4. bootvid.c
  5. Abstract:
  6. This file implements the interface between the kernel, and the
  7. graphical boot driver.
  8. Author:
  9. Erick Smith (ericks) Feb. 3, 1998
  10. Environment:
  11. kernel mode
  12. Revision History:
  13. --*/
  14. #include "ntos.h"
  15. #include "ntimage.h"
  16. #include <zwapi.h>
  17. #include <ntdddisk.h>
  18. #include <setupblk.h>
  19. #include <fsrtl.h>
  20. #include <ntverp.h>
  21. #include "stdlib.h"
  22. #include "stdio.h"
  23. #include <string.h>
  24. #include <safeboot.h>
  25. #include <inbv.h>
  26. #include <bootvid.h>
  27. #include <hdlsblk.h>
  28. #include <hdlsterm.h>
  29. #include "anim.h"
  30. ULONG InbvTerminalBkgdColor = HEADLESS_TERM_DEFAULT_BKGD_COLOR;
  31. ULONG InbvTerminalTextColor = HEADLESS_TERM_DEFAULT_TEXT_COLOR;
  32. PUCHAR
  33. FindBitmapResource(
  34. IN PLOADER_PARAMETER_BLOCK LoaderBlock,
  35. IN ULONG_PTR ResourceIdentifier
  36. );
  37. #if defined(ALLOC_PRAGMA)
  38. #pragma alloc_text(INIT,InbvIndicateProgress)
  39. #pragma alloc_text(INIT,InbvDriverInitialize)
  40. #pragma alloc_text(INIT,FindBitmapResource)
  41. #endif
  42. //
  43. // System global variable
  44. //
  45. BOOLEAN InbvBootDriverInstalled = FALSE;
  46. BOOLEAN InbvDisplayDebugStrings = FALSE;
  47. INBV_DISPLAY_STATE InbvDisplayState = INBV_DISPLAY_STATE_OWNED;
  48. KSPIN_LOCK BootDriverLock;
  49. KIRQL InbvOldIrql;
  50. INBV_RESET_DISPLAY_PARAMETERS InbvResetDisplayParameters = NULL;
  51. INBV_DISPLAY_STRING_FILTER InbvDisplayFilter = NULL;
  52. #define MAX_RESOURCES 15
  53. ULONG ResourceCount = 0;
  54. PUCHAR ResourceList[MAX_RESOURCES];
  55. ULONG ProgressBarLeft;
  56. ULONG ProgressBarTop;
  57. BOOLEAN ShowProgressBar = TRUE;
  58. struct _InbvProgressState {
  59. ULONG Floor;
  60. ULONG Ceiling;
  61. ULONG Bias;
  62. } InbvProgressState;
  63. #ifdef ALLOC_DATA_PRAGMA
  64. #pragma data_seg("INITDATA")
  65. #endif
  66. struct _BT_PROGRESS_INDICATOR {
  67. ULONG Count;
  68. ULONG Expected;
  69. ULONG Percentage;
  70. } InbvProgressIndicator = { 0, 25, 0 };
  71. #ifdef ALLOC_DATA_PRAGMA
  72. #pragma data_seg()
  73. #endif
  74. VOID
  75. InbvAcquireLock(
  76. VOID
  77. )
  78. /*++
  79. Routine Description:
  80. This is an internal function used to grab the boot driver lock. This
  81. ensures that only one thread will enter the driver code at a time.
  82. Notes:
  83. You must call ReleaseLock for each call to AcquireLock.
  84. --*/
  85. {
  86. KIRQL Irql;
  87. KIRQL LocalIrql;
  88. LocalIrql = KeGetCurrentIrql();
  89. if (LocalIrql <= DISPATCH_LEVEL) {
  90. while (!KeTestSpinLock(&BootDriverLock))
  91. ;
  92. KeRaiseIrql(DISPATCH_LEVEL, &Irql);
  93. LocalIrql = Irql;
  94. }
  95. KiAcquireSpinLock(&BootDriverLock);
  96. InbvOldIrql = LocalIrql;
  97. }
  98. VOID
  99. InbvReleaseLock(
  100. VOID
  101. )
  102. /*++
  103. Routine Description:
  104. This routine releases the boot driver lock.
  105. --*/
  106. {
  107. KIRQL OldIrql = InbvOldIrql;
  108. KiReleaseSpinLock(&BootDriverLock);
  109. if (OldIrql <= DISPATCH_LEVEL) {
  110. KeLowerIrql(OldIrql);
  111. }
  112. }
  113. BOOLEAN
  114. InbvTestLock(
  115. VOID
  116. )
  117. /*++
  118. Routine Description:
  119. This routine allows you to try to acquire the display lock. If it
  120. can't get the lock right away, it returns failure.
  121. Returns:
  122. TRUE - If you aqcuired the lock.
  123. FALSE - If another thread is currently using the boot driver.
  124. Notes:
  125. You must call InbvReleaseLock if this function returns TRUE!
  126. --*/
  127. {
  128. KIRQL Irql;
  129. if (KeTryToAcquireSpinLock(&BootDriverLock, &Irql)) {
  130. InbvOldIrql = Irql;
  131. return TRUE;
  132. } else {
  133. return FALSE;
  134. }
  135. }
  136. VOID
  137. InbvEnableBootDriver(
  138. BOOLEAN bEnable
  139. )
  140. /*++
  141. Routine Description:
  142. This routine allows the kernel to control whether Inbv
  143. calls make it through to the boot driver, and when they don't.
  144. Arguments:
  145. bEnable - If TRUE, we will allow Inbv calls to display,
  146. otherwise we will not.
  147. --*/
  148. {
  149. if (InbvBootDriverInstalled) {
  150. if (InbvDisplayState < INBV_DISPLAY_STATE_LOST) {
  151. //
  152. // We can only wait for our lock, and execute our clean up code
  153. // if the driver is installed.
  154. //
  155. InbvAcquireLock();
  156. if (InbvDisplayState == INBV_DISPLAY_STATE_OWNED) {
  157. VidCleanUp();
  158. }
  159. InbvDisplayState = (bEnable ? INBV_DISPLAY_STATE_OWNED : INBV_DISPLAY_STATE_DISABLED);
  160. InbvReleaseLock();
  161. }
  162. } else {
  163. //
  164. // This allow us to set display state before boot driver starts.
  165. //
  166. InbvDisplayState = (bEnable ? INBV_DISPLAY_STATE_OWNED : INBV_DISPLAY_STATE_DISABLED);
  167. }
  168. }
  169. BOOLEAN
  170. InbvEnableDisplayString(
  171. BOOLEAN bEnable
  172. )
  173. /*++
  174. Routine Description:
  175. This routine allows the kernel to control when HalDisplayString
  176. calls make it through to the boot driver, and when they don't.
  177. Arguments:
  178. bEnable - If TRUE, we will allow HalDisplayString calls to display,
  179. otherwise we will not.
  180. Returns:
  181. TRUE - If display string were currently being dumped.
  182. FALSE - otherwise.
  183. --*/
  184. {
  185. BOOLEAN PrevValue = InbvDisplayDebugStrings;
  186. InbvDisplayDebugStrings = bEnable;
  187. return PrevValue;
  188. }
  189. BOOLEAN
  190. InbvIsBootDriverInstalled(
  191. VOID
  192. )
  193. /*++
  194. Routine Description:
  195. This routine allows a component to determine if the gui boot
  196. driver is in use.
  197. --*/
  198. {
  199. return InbvBootDriverInstalled;
  200. }
  201. BOOLEAN
  202. InbvResetDisplay(
  203. )
  204. /*++
  205. Routine Description:
  206. This routine will reset the display from text mode to a
  207. supported graphics mode.
  208. Notes:
  209. This routine expects the display to be in text mode when called.
  210. --*/
  211. {
  212. if (InbvBootDriverInstalled && (InbvDisplayState == INBV_DISPLAY_STATE_OWNED)) {
  213. VidResetDisplay(TRUE);
  214. return TRUE;
  215. } else {
  216. return FALSE;
  217. }
  218. }
  219. VOID
  220. InbvScreenToBufferBlt(
  221. PUCHAR Buffer,
  222. ULONG x,
  223. ULONG y,
  224. ULONG width,
  225. ULONG height,
  226. ULONG lDelta
  227. )
  228. /*++
  229. Routine Description:
  230. This routine allows for copying portions of video memory into system
  231. memory.
  232. Arguments:
  233. Buffer - Location in which to place the video image.
  234. x, y - X and Y coordinates of top-left corner of image.
  235. width, height - The width and height of the image in pixels.
  236. lDelta - width of the buffer in bytes
  237. Notes:
  238. This routine does not automatically acquire the device lock, so
  239. the caller must call InbvAquireLock or InbvTestLock to acquire
  240. the device lock.
  241. --*/
  242. {
  243. if (InbvBootDriverInstalled && (InbvDisplayState == INBV_DISPLAY_STATE_OWNED)) {
  244. VidScreenToBufferBlt(Buffer, x, y, width, height, lDelta);
  245. }
  246. }
  247. VOID
  248. InbvBufferToScreenBlt(
  249. PUCHAR Buffer,
  250. ULONG x,
  251. ULONG y,
  252. ULONG width,
  253. ULONG height,
  254. ULONG lDelta
  255. )
  256. /*++
  257. Routine Description:
  258. This routine allows for copying previously saved portions of video
  259. memory back to the screen.
  260. Arguments:
  261. Buffer - Location in which to place the video image.
  262. x, y - X and Y coordinates of top-left corner of image.
  263. width, height - The width and height of the image in pixels.
  264. lDelta - width of the buffer in bytes
  265. Notes:
  266. This routine does not automatically acquire the device lock, so
  267. the caller must call InbvAquireLock or InbvTestLock to acquire
  268. the device lock.
  269. --*/
  270. {
  271. if (InbvBootDriverInstalled && (InbvDisplayState == INBV_DISPLAY_STATE_OWNED)) {
  272. VidBufferToScreenBlt(Buffer, x, y, width, height, lDelta);
  273. }
  274. }
  275. VOID
  276. InbvBitBlt(
  277. PUCHAR Buffer,
  278. ULONG x,
  279. ULONG y
  280. )
  281. /*++
  282. Routine Description:
  283. This routine blts the bitmap described in 'Buffer' to the location
  284. x and y on the screen.
  285. Arguments:
  286. Buffer - points to a bitmap (in the same format as stored on disk).
  287. x, y - the upper left corner at which the bitmap will be drawn.
  288. --*/
  289. {
  290. if (InbvBootDriverInstalled && (InbvDisplayState == INBV_DISPLAY_STATE_OWNED)) {
  291. InbvAcquireLock();
  292. VidBitBlt(Buffer, x, y);
  293. InbvReleaseLock();
  294. }
  295. }
  296. VOID
  297. InbvSolidColorFill(
  298. ULONG x1,
  299. ULONG y1,
  300. ULONG x2,
  301. ULONG y2,
  302. ULONG color
  303. )
  304. /*++
  305. Routine Description:
  306. This routine fills a rectangular portion of the screen with a
  307. given color.
  308. --*/
  309. {
  310. ULONG x, y;
  311. HEADLESS_CMD_SET_COLOR HeadlessCmd;
  312. if (InbvBootDriverInstalled && (InbvDisplayState == INBV_DISPLAY_STATE_OWNED)) {
  313. InbvAcquireLock();
  314. VidSolidColorFill(x1, y1, x2, y2, color);
  315. //
  316. // Now fill in the area on the terminal
  317. //
  318. //
  319. // Color comes in as the palette index to the standard windows VGA palette.
  320. // Convert it.
  321. //
  322. switch (color) {
  323. case 0:
  324. InbvTerminalBkgdColor = 40;
  325. break;
  326. case 4:
  327. InbvTerminalBkgdColor = 44;
  328. break;
  329. default:
  330. //
  331. // Guess
  332. //
  333. InbvTerminalBkgdColor = color + 40;
  334. }
  335. HeadlessCmd.FgColor = InbvTerminalTextColor;
  336. HeadlessCmd.BkgColor = InbvTerminalBkgdColor;
  337. HeadlessDispatch(HeadlessCmdSetColor,
  338. &HeadlessCmd,
  339. sizeof(HEADLESS_CMD_SET_COLOR),
  340. NULL,
  341. NULL
  342. );
  343. //
  344. // All block fills come in as if on VGA (640x480). The terminal is only 24x80
  345. // so just assume it is full screen reset for now. This works because the only
  346. // thing enables terminal output is KeBugCheckEx(), which does a full screen fill.
  347. //
  348. HeadlessDispatch(HeadlessCmdClearDisplay, NULL, 0, NULL, NULL);
  349. InbvReleaseLock();
  350. }
  351. }
  352. ULONG
  353. InbvSetTextColor(
  354. ULONG Color
  355. )
  356. /*++
  357. Routine Description:
  358. Sets the text color used when dislaying text.
  359. Arguments:
  360. Color - the new text color.
  361. Returns:
  362. The previous text color.
  363. --*/
  364. {
  365. HEADLESS_CMD_SET_COLOR HeadlessCmd;
  366. //
  367. // Color comes in as the palette index to the standard windows VGA palette.
  368. // Convert it.
  369. //
  370. switch (Color) {
  371. case 0:
  372. InbvTerminalBkgdColor = 40;
  373. break;
  374. case 4:
  375. InbvTerminalTextColor = 44;
  376. break;
  377. default:
  378. //
  379. // Guess
  380. //
  381. InbvTerminalTextColor = Color + 40;
  382. }
  383. HeadlessCmd.FgColor = InbvTerminalTextColor;
  384. HeadlessCmd.BkgColor = InbvTerminalBkgdColor;
  385. HeadlessDispatch(HeadlessCmdSetColor,
  386. &HeadlessCmd,
  387. sizeof(HEADLESS_CMD_SET_COLOR),
  388. NULL,
  389. NULL
  390. );
  391. return VidSetTextColor(Color);
  392. }
  393. VOID
  394. InbvInstallDisplayStringFilter(
  395. INBV_DISPLAY_STRING_FILTER DisplayFilter
  396. )
  397. /*++
  398. --*/
  399. {
  400. InbvDisplayFilter = DisplayFilter;
  401. }
  402. BOOLEAN
  403. InbvDisplayString(
  404. PUCHAR Str
  405. )
  406. /*++
  407. Routine Description:
  408. This routine displays a string on the screen.
  409. Arguments:
  410. Str - The string to be displayed.
  411. --*/
  412. {
  413. PUCHAR *String = &Str;
  414. if (InbvBootDriverInstalled && (InbvDisplayState == INBV_DISPLAY_STATE_OWNED)) {
  415. if (InbvDisplayDebugStrings) {
  416. if (InbvDisplayFilter) {
  417. InbvDisplayFilter(String);
  418. }
  419. InbvAcquireLock();
  420. VidDisplayString(*String);
  421. //
  422. // Since the command structure is exactly a string, we can do this. The
  423. // ASSERT() will catch if this ever changes. If it does change, then
  424. // we will need to allocate a structure, or have one pre-allocated, for
  425. // filling in and copying over the string.
  426. //
  427. ASSERT(FIELD_OFFSET(HEADLESS_CMD_PUT_STRING, String) == 0);
  428. HeadlessDispatch(HeadlessCmdPutString,
  429. *String,
  430. strlen(*String) + sizeof('\0'),
  431. NULL,
  432. NULL
  433. );
  434. InbvReleaseLock();
  435. }
  436. return TRUE;
  437. } else {
  438. return FALSE;
  439. }
  440. }
  441. #define PROGRESS_BAR_TICK_WIDTH 9
  442. #define PROGRESS_BAR_TICK_HEIGHT 8
  443. #define PROGRESS_BAR_TICKS 18
  444. #define PROGRESS_BAR_COLOR 11
  445. VOID
  446. InbvSetProgressBarCoordinates(
  447. ULONG x,
  448. ULONG y
  449. )
  450. /*++
  451. Routine Description:
  452. This routine sets the upper left coordinate of the progress bar.
  453. Arguments:
  454. x, y - upper left coordinate of progress bar.
  455. --*/
  456. {
  457. ProgressBarLeft = x;
  458. ProgressBarTop = y;
  459. ShowProgressBar = TRUE;
  460. }
  461. VOID
  462. InbvUpdateProgressBar(
  463. ULONG Percentage
  464. )
  465. /*++
  466. Routine Description:
  467. This routine is called by the system during startup to update
  468. the status bar displayed on the gui boot screen.
  469. --*/
  470. {
  471. int i, Ticks;
  472. if (ShowProgressBar && InbvBootDriverInstalled && (InbvDisplayState == INBV_DISPLAY_STATE_OWNED)) {
  473. //
  474. // Draw the ticks for the current percentage
  475. //
  476. //
  477. // The following calculations are biased by 100 do that
  478. // InbvProgressState.Bias can be expressed as an integer fraction.
  479. //
  480. Ticks = Percentage * InbvProgressState.Bias;
  481. Ticks += InbvProgressState.Floor;
  482. Ticks *= PROGRESS_BAR_TICKS;
  483. Ticks /= 10000;
  484. for (i=0; i<Ticks; i++) {
  485. InbvAcquireLock();
  486. VidSolidColorFill(ProgressBarLeft + (i * PROGRESS_BAR_TICK_WIDTH),
  487. ProgressBarTop,
  488. ProgressBarLeft + ((i + 1) * PROGRESS_BAR_TICK_WIDTH) - 2,
  489. ProgressBarTop + PROGRESS_BAR_TICK_HEIGHT - 1,
  490. PROGRESS_BAR_COLOR);
  491. InbvReleaseLock();
  492. }
  493. }
  494. }
  495. VOID
  496. InbvSetProgressBarSubset(
  497. ULONG Floor,
  498. ULONG Ceiling
  499. )
  500. /*++
  501. Routine Description:
  502. Sets floor and ceiling for subsequent calls to InbvUpdateProgressBar.
  503. While a floor and ceiling are in effect, a caller's 100% is a
  504. percentage of this range. If floor and ceiling are zero, the
  505. entire range is used.
  506. Arguments:
  507. Floor Lower limit of the subset.
  508. Ceiling Upper limit of the subset.
  509. Return Value:
  510. None.
  511. --*/
  512. {
  513. ASSERT(Floor < Ceiling);
  514. ASSERT(Ceiling <= 100);
  515. InbvProgressState.Floor = Floor * 100;
  516. InbvProgressState.Ceiling = Ceiling * 100;
  517. InbvProgressState.Bias = (Ceiling - Floor);
  518. }
  519. VOID
  520. InbvIndicateProgress(
  521. VOID
  522. )
  523. /*++
  524. Routine Description:
  525. This routine is called to indicate that progress is being
  526. made. The number of calls is counted and compared to the
  527. expected number of calls, the boot progress bar is updated
  528. apropriately.
  529. Arguments:
  530. None.
  531. Return Value:
  532. None.
  533. --*/
  534. {
  535. ULONG Percentage;
  536. InbvProgressIndicator.Count++;
  537. //
  538. // Calculate how far along we think we are.
  539. //
  540. Percentage = (InbvProgressIndicator.Count * 100) /
  541. InbvProgressIndicator.Expected;
  542. //
  543. // The Expected number of calls can vary from boot to boot
  544. // but should remain relatively constant. Allow for the
  545. // possibility we were called more than we expected to be.
  546. // (The progress bar simply stalls at this point).
  547. //
  548. if (Percentage > 99) {
  549. Percentage = 99;
  550. }
  551. //
  552. // See if the progress bar should be updated.
  553. //
  554. if (Percentage != InbvProgressIndicator.Percentage) {
  555. InbvProgressIndicator.Percentage = Percentage;
  556. InbvUpdateProgressBar(Percentage);
  557. }
  558. }
  559. PUCHAR
  560. FindBitmapResource(
  561. IN PLOADER_PARAMETER_BLOCK LoaderBlock,
  562. IN ULONG_PTR ResourceIdentifier
  563. )
  564. /*++
  565. Routine Description:
  566. Gets a pointer to the bitmap image compiled into this binary,
  567. if one exists.
  568. Arguments:
  569. LoaderBlock - Used in obtaining the bitmap resource
  570. ResourceIdentifier - Identifier for the resource to return the address for
  571. Return Value:
  572. Pointer to bitmap resource, if successful. NULL otherwise.
  573. --*/
  574. {
  575. NTSTATUS Status;
  576. PLIST_ENTRY Entry;
  577. PKLDR_DATA_TABLE_ENTRY DataTableEntry;
  578. ULONG_PTR ResourceIdPath[3];
  579. PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry;
  580. PUCHAR Bitmap;
  581. UNICODE_STRING KernelString1;
  582. UNICODE_STRING KernelString2;
  583. RtlInitUnicodeString(&KernelString1, L"NTOSKRNL.EXE");
  584. RtlInitUnicodeString(&KernelString2, L"NTKRNLMP.EXE");
  585. //
  586. // Find our loader block entry
  587. //
  588. Entry = LoaderBlock->LoadOrderListHead.Flink;
  589. while (Entry != &LoaderBlock->LoadOrderListHead) {
  590. //
  591. // Get the address of the data table entry for this component.
  592. //
  593. DataTableEntry = CONTAINING_RECORD(Entry,
  594. KLDR_DATA_TABLE_ENTRY,
  595. InLoadOrderLinks);
  596. //
  597. // Case-insensitive comparison with "NTOSKRNL.EXE" and "NTKRNLMP.EXE"
  598. //
  599. if (RtlEqualUnicodeString(&DataTableEntry->BaseDllName,
  600. &KernelString1,
  601. TRUE) == TRUE) {
  602. break;
  603. }
  604. if (RtlEqualUnicodeString(&DataTableEntry->BaseDllName,
  605. &KernelString2,
  606. TRUE) == TRUE) {
  607. break;
  608. }
  609. Entry = Entry->Flink;
  610. }
  611. //
  612. // If we couldn't find ntoskrnl in the loader list, give up
  613. //
  614. if (Entry == &LoaderBlock->LoadOrderListHead) {
  615. return NULL;
  616. }
  617. ResourceIdPath[0] = 2; // RT_BITMAP = 2
  618. ResourceIdPath[1] = ResourceIdentifier;
  619. ResourceIdPath[2] = 0; // ??
  620. Status = LdrFindResource_U( DataTableEntry->DllBase,
  621. ResourceIdPath,
  622. 3,
  623. (VOID *) &ResourceDataEntry );
  624. if (!NT_SUCCESS(Status)) {
  625. return NULL;
  626. }
  627. Status = LdrAccessResource( DataTableEntry->DllBase,
  628. ResourceDataEntry,
  629. &Bitmap,
  630. NULL );
  631. if (!NT_SUCCESS(Status)) {
  632. return NULL;
  633. }
  634. return Bitmap;
  635. }
  636. PUCHAR
  637. InbvGetResourceAddress(
  638. IN ULONG ResourceNumber
  639. )
  640. /*++
  641. Routine Description:
  642. This routine returns the cached resources address for a given
  643. resource.
  644. --*/
  645. {
  646. if (ResourceNumber <= ResourceCount) {
  647. return ResourceList[ResourceNumber-1];
  648. } else {
  649. return NULL;
  650. }
  651. }
  652. BOOLEAN
  653. InbvDriverInitialize(
  654. IN PLOADER_PARAMETER_BLOCK LoaderBlock,
  655. ULONG Count
  656. )
  657. /*++
  658. Routine Description:
  659. This routine will call into the graphical boot driver and give the
  660. driver a chance to initialize. At this point, the boot driver
  661. should determine whether it can run on the hardware in the machine.
  662. --*/
  663. {
  664. ULONG i;
  665. ULONG_PTR p;
  666. PCHAR Options;
  667. BOOLEAN DispModeChange = FALSE;
  668. //
  669. // Only do this once.
  670. //
  671. if (InbvBootDriverInstalled == TRUE) {
  672. return TRUE;
  673. }
  674. KeInitializeSpinLock(&BootDriverLock);
  675. if (InbvDisplayState == INBV_DISPLAY_STATE_OWNED) {
  676. Options = LoaderBlock->LoadOptions ? _strupr(LoaderBlock->LoadOptions) : NULL;
  677. if (Options) {
  678. DispModeChange = (BOOLEAN)(strstr(Options, "BOOTLOGO") == NULL);
  679. } else {
  680. DispModeChange = TRUE;
  681. }
  682. }
  683. InbvBootDriverInstalled = VidInitialize(DispModeChange);
  684. if (InbvBootDriverInstalled == FALSE) {
  685. return FALSE;
  686. }
  687. ResourceCount = Count;
  688. for (i=1; i<=Count; i++) {
  689. p = (ULONG_PTR) i;
  690. ResourceList[i-1] = FindBitmapResource(LoaderBlock, p);
  691. }
  692. //
  693. // Set prograss bar to full range.
  694. //
  695. InbvSetProgressBarSubset(0, 100);
  696. return InbvBootDriverInstalled;
  697. }
  698. VOID
  699. InbvNotifyDisplayOwnershipLost(
  700. INBV_RESET_DISPLAY_PARAMETERS ResetDisplayParameters
  701. )
  702. /*++
  703. Routine Description:
  704. This routine is called by the hal when the hal looses
  705. display ownership. At this point win32k.sys has taken
  706. over.
  707. --*/
  708. {
  709. if (InbvBootDriverInstalled) {
  710. //
  711. // We can only wait for our lock, and execute our clean up code
  712. // if the driver is installed and we still own the display.
  713. //
  714. InbvAcquireLock();
  715. if (InbvDisplayState != INBV_DISPLAY_STATE_LOST) {
  716. VidCleanUp();
  717. }
  718. InbvDisplayState = INBV_DISPLAY_STATE_LOST;
  719. InbvResetDisplayParameters = ResetDisplayParameters;
  720. InbvReleaseLock();
  721. } else {
  722. InbvDisplayState = INBV_DISPLAY_STATE_LOST;
  723. InbvResetDisplayParameters = ResetDisplayParameters;
  724. }
  725. }
  726. VOID
  727. InbvAcquireDisplayOwnership(
  728. VOID
  729. )
  730. /*++
  731. Routine Description:
  732. Allows the kernel to reaquire ownership of the display.
  733. --*/
  734. {
  735. if (InbvResetDisplayParameters && (InbvDisplayState == INBV_DISPLAY_STATE_LOST)) {
  736. InbvResetDisplayParameters(80,50);
  737. }
  738. InbvDisplayState = INBV_DISPLAY_STATE_OWNED;
  739. }
  740. VOID
  741. InbvSetDisplayOwnership(
  742. BOOLEAN DisplayOwned
  743. )
  744. /*++
  745. Routine Description:
  746. This routine allows the kernel to set a display state. This is useful
  747. after a hibernate. At this point win32k will reacquire display ownership
  748. but will not tell us.
  749. Arguments:
  750. Whether the display is owned or not.
  751. --*/
  752. {
  753. if (DisplayOwned) {
  754. InbvDisplayState = INBV_DISPLAY_STATE_OWNED;
  755. } else {
  756. InbvDisplayState = INBV_DISPLAY_STATE_LOST;
  757. }
  758. }
  759. BOOLEAN
  760. InbvCheckDisplayOwnership(
  761. VOID
  762. )
  763. /*++
  764. Routine Description:
  765. Indicates whether the Hal owns the display.
  766. --*/
  767. {
  768. return (InbvDisplayState != INBV_DISPLAY_STATE_LOST);
  769. }
  770. INBV_DISPLAY_STATE
  771. InbvGetDisplayState(
  772. VOID
  773. )
  774. /*++
  775. Routine Description:
  776. Indicates whether the Hal owns the display.
  777. --*/
  778. {
  779. return InbvDisplayState;
  780. }
  781. VOID
  782. InbvSetScrollRegion(
  783. ULONG x1,
  784. ULONG y1,
  785. ULONG x2,
  786. ULONG y2
  787. )
  788. /*++
  789. Routine Description:
  790. Control what portions of the screen are used for text.
  791. Arguments:
  792. Lines - number of lines of text.
  793. --*/
  794. {
  795. VidSetScrollRegion(x1, y1, x2, y2);
  796. }