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.

1763 lines
41 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. blload.c
  5. Abstract:
  6. This module provides common code for loading things like drivers, NLS files, registry.
  7. Used by both the osloader and the setupldr.
  8. Author:
  9. John Vert (jvert) 8-Oct-1993
  10. Environment:
  11. ARC environment
  12. Revision History:
  13. --*/
  14. #include "bldr.h"
  15. #include "stdio.h"
  16. #include "stdlib.h"
  17. #include "vmode.h"
  18. #ifdef EFI
  19. #include "bootefi.h"
  20. #endif
  21. //
  22. // progress bar message ids
  23. //
  24. // HIBER_UI_BAR_ELEMENT 0x00002CF9L
  25. // BLDR_UI_BAR_BACKGROUND 0x00002CFAL
  26. //
  27. ULONG BlProgBarFrontMsgID = 0x00002CF9L;
  28. ULONG BlProgBarBackMsgID = 0x00002CFAL;
  29. //
  30. // number of files loaded (for progress bar)
  31. //
  32. int BlNumFilesLoaded = 0;
  33. int BlNumProgressBarFilesLoaded = 0;
  34. //
  35. // maximum number of files to load (for progress bar)
  36. //
  37. int BlMaxFilesToLoad = 80;
  38. int BlProgressBarFilesToLoad = 0;
  39. #if defined(_X86_)
  40. ULONG BlProgressBarShowTimeOut = 3;
  41. #else
  42. ULONG BlProgressBarShowTimeOut = 0;
  43. #endif
  44. //
  45. // The progress bar width (in characters)
  46. //
  47. #define PROGRESS_BAR_WIDTH 80
  48. //
  49. // The progress bar characters
  50. //
  51. #define DEFAULT_FRONT_CHAR 0xDB // block cursor
  52. #define DEFAULT_BACK_CHAR ' '
  53. USHORT BlFrontChar = DEFAULT_FRONT_CHAR;
  54. USHORT BlBackChar = DEFAULT_BACK_CHAR;
  55. //
  56. // defines whether to draw the progress bar or not
  57. //
  58. #if DBG
  59. BOOLEAN BlOutputDots=FALSE;
  60. //BOOLEAN BlOutputDots=TRUE;
  61. #else
  62. BOOLEAN BlOutputDots=TRUE;
  63. #endif
  64. //
  65. // To show the progress bar or not
  66. //
  67. BOOLEAN BlShowProgressBar = FALSE;
  68. ULONG BlStartTime = 0L;
  69. ARC_STATUS
  70. BlLoadSystemHiveLog(
  71. IN ULONG DeviceId,
  72. IN PCHAR DeviceName,
  73. IN PCHAR DirectoryPath,
  74. IN PCHAR HiveName,
  75. OUT PULONG_PTR LogData
  76. )
  77. /*++
  78. Routine Description:
  79. Loads the registry log file for the system hive from <BootDirectory>\config\system.LOG.
  80. Allocates a memory descriptor to hold the hive image, reads the hive
  81. image into this descriptor,
  82. Arguments:
  83. DeviceId - Supplies the file id of the device the system tree is on.
  84. DeviceName - Supplies the name of the device the system tree is on.
  85. DirectoryPath - Supplies a pointer to the zero-terminated directory path
  86. of the root of the NT tree.
  87. HiveName - Supplies the name of the system hive ("SYSTEM.LOG")
  88. LogData - flat image of the log file
  89. LogLength - length of the data in LogData
  90. Return Value:
  91. TRUE - system hive successfully loaded.
  92. FALSE - system hive could not be loaded.
  93. --*/
  94. {
  95. CHAR RegistryName[256];
  96. ULONG FileId;
  97. ARC_STATUS Status;
  98. FILE_INFORMATION FileInformation;
  99. ULONG FileSize;
  100. ULONG ActualBase;
  101. ULONG_PTR LocalPointer;
  102. LARGE_INTEGER SeekValue;
  103. ULONG Count;
  104. PCHAR FailReason;
  105. //
  106. // Create the full filename for the SYSTEM hive.
  107. //
  108. strcpy(&RegistryName[0], DirectoryPath);
  109. strcat(&RegistryName[0], HiveName);
  110. BlOutputLoadMessage(DeviceName, &RegistryName[0], NULL);
  111. Status = BlOpen(DeviceId, &RegistryName[0], ArcOpenReadOnly, &FileId);
  112. if (Status != ESUCCESS) {
  113. FailReason = "BlOpen";
  114. goto HiveLoadFailed;
  115. }
  116. BlUpdateBootStatus();
  117. //
  118. // Determine the length of the registry file
  119. //
  120. Status = BlGetFileInformation(FileId, &FileInformation);
  121. if (Status != ESUCCESS) {
  122. BlClose(FileId);
  123. FailReason = "BlGetFileInformation";
  124. goto HiveLoadFailed;
  125. }
  126. FileSize = FileInformation.EndingAddress.LowPart;
  127. if (FileSize == 0) {
  128. Status = EINVAL;
  129. BlClose(FileId);
  130. FailReason = "FileSize == 0";
  131. goto HiveLoadFailed;
  132. }
  133. //
  134. // Round up to a page boundary, allocate a memory descriptor, fill in the
  135. // registry fields in the loader parameter block, and read the registry
  136. // data into memory.
  137. //
  138. Status = BlAllocateDescriptor(LoaderRegistryData,
  139. 0x0,
  140. (FileSize + PAGE_SIZE - 1) >> PAGE_SHIFT,
  141. &ActualBase);
  142. if (Status != ESUCCESS) {
  143. BlClose(FileId);
  144. FailReason = "BlAllocateDescriptor";
  145. goto HiveLoadFailed;
  146. }
  147. *LogData = LocalPointer = KSEG0_BASE | (ActualBase << PAGE_SHIFT);
  148. //
  149. // Read the SYSTEM hive into the allocated memory.
  150. //
  151. SeekValue.QuadPart = 0;
  152. Status = BlSeek(FileId, &SeekValue, SeekAbsolute);
  153. if (Status != ESUCCESS) {
  154. BlClose(FileId);
  155. FailReason = "BlSeek";
  156. BlFreeDescriptor(ActualBase);
  157. goto HiveLoadFailed;
  158. }
  159. Status = BlRead(FileId, (PVOID)LocalPointer, FileSize, &Count);
  160. BlClose(FileId);
  161. if (Status != ESUCCESS) {
  162. FailReason = "BlRead";
  163. BlFreeDescriptor(ActualBase);
  164. goto HiveLoadFailed;
  165. }
  166. HiveLoadFailed:
  167. return Status;
  168. }
  169. ARC_STATUS
  170. BlLoadSystemHive(
  171. IN ULONG DeviceId,
  172. IN PCHAR DeviceName,
  173. IN PCHAR DirectoryPath,
  174. IN PCHAR HiveName
  175. )
  176. /*++
  177. Routine Description:
  178. Loads the registry SYSTEM hive from <BootDirectory>\config\system.
  179. Allocates a memory descriptor to hold the hive image, reads the hive
  180. image into this descriptor, and updates the registry pointers in the
  181. LoaderBlock.
  182. Arguments:
  183. DeviceId - Supplies the file id of the device the system tree is on.
  184. DeviceName - Supplies the name of the device the system tree is on.
  185. DirectoryPath - Supplies a pointer to the zero-terminated directory path
  186. of the root of the NT tree.
  187. HiveName - Supplies the name of the system hive ("SYSTEM" or "SYSTEM.ALT")
  188. Return Value:
  189. TRUE - system hive successfully loaded.
  190. FALSE - system hive could not be loaded.
  191. --*/
  192. {
  193. CHAR RegistryName[256];
  194. ULONG FileId;
  195. ARC_STATUS Status;
  196. FILE_INFORMATION FileInformation;
  197. ULONG FileSize;
  198. ULONG ActualBase;
  199. ULONG_PTR LocalPointer;
  200. LARGE_INTEGER SeekValue;
  201. ULONG Count;
  202. PCHAR FailReason;
  203. //
  204. // Create the full filename for the SYSTEM hive.
  205. //
  206. strcpy(&RegistryName[0], DirectoryPath);
  207. strcat(&RegistryName[0], HiveName);
  208. BlOutputLoadMessage(DeviceName, &RegistryName[0], NULL);
  209. Status = BlOpen(DeviceId, &RegistryName[0], ArcOpenReadOnly, &FileId);
  210. if (Status != ESUCCESS) {
  211. FailReason = "BlOpen";
  212. goto HiveLoadFailed;
  213. }
  214. BlUpdateBootStatus();
  215. //
  216. // Determine the length of the registry file
  217. //
  218. Status = BlGetFileInformation(FileId, &FileInformation);
  219. if (Status != ESUCCESS) {
  220. BlClose(FileId);
  221. FailReason = "BlGetFileInformation";
  222. goto HiveLoadFailed;
  223. }
  224. FileSize = FileInformation.EndingAddress.LowPart;
  225. if (FileSize == 0) {
  226. Status = EINVAL;
  227. BlClose(FileId);
  228. FailReason = "FileSize == 0";
  229. goto HiveLoadFailed;
  230. }
  231. //
  232. // Round up to a page boundary, allocate a memory descriptor, fill in the
  233. // registry fields in the loader parameter block, and read the registry
  234. // data into memory.
  235. //
  236. Status = BlAllocateDescriptor(LoaderRegistryData,
  237. 0x0,
  238. (FileSize + PAGE_SIZE - 1) >> PAGE_SHIFT,
  239. &ActualBase);
  240. if (Status != ESUCCESS) {
  241. BlClose(FileId);
  242. FailReason = "BlAllocateDescriptor";
  243. goto HiveLoadFailed;
  244. }
  245. LocalPointer = KSEG0_BASE | (ActualBase << PAGE_SHIFT);
  246. BlLoaderBlock->RegistryLength = FileSize;
  247. BlLoaderBlock->RegistryBase = (PVOID)(LocalPointer + BlVirtualBias);
  248. //
  249. // Read the SYSTEM hive into the allocated memory.
  250. //
  251. SeekValue.QuadPart = 0;
  252. Status = BlSeek(FileId, &SeekValue, SeekAbsolute);
  253. if (Status != ESUCCESS) {
  254. BlClose(FileId);
  255. FailReason = "BlSeek";
  256. goto HiveLoadFailed;
  257. }
  258. Status = BlRead(FileId, (PVOID)LocalPointer, FileSize, &Count);
  259. BlClose(FileId);
  260. if (Status != ESUCCESS) {
  261. FailReason = "BlRead";
  262. goto HiveLoadFailed;
  263. }
  264. HiveLoadFailed:
  265. return Status;
  266. }
  267. ARC_STATUS
  268. BlLoadNLSData(
  269. IN ULONG DeviceId,
  270. IN PCHAR DeviceName,
  271. IN PCHAR DirectoryPath,
  272. IN PUNICODE_STRING AnsiCodepage,
  273. IN PUNICODE_STRING OemCodepage,
  274. IN PUNICODE_STRING LanguageTable,
  275. OUT PCHAR BadFileName
  276. )
  277. /*++
  278. Routine Description:
  279. This routine loads all the NLS data files into one contiguous block of
  280. memory.
  281. Arguments:
  282. DeviceId - Supplies the file id of the device the system tree is on.
  283. DeviceName - Supplies the name of the device the system tree is on.
  284. DirectoryPath - Supplies a pointer to the zero-terminated path
  285. of the directory containing the NLS files.
  286. AnsiCodePage - Supplies the filename of the ANSI codepage data file.
  287. OemCodePage - Supplies the filename of the OEM codepage data file.
  288. LanguageTable - Supplies the filename of the Unicode language case table.
  289. BadFileName - Returns the filename of the NLS file that was missing
  290. or invalid. This will not be filled in if ESUCCESS is returned.
  291. Return Value:
  292. ESUCCESS is returned if the NLS data was successfully loaded.
  293. Otherwise, an unsuccessful status is returned.
  294. --*/
  295. {
  296. CHAR Filename[129];
  297. ULONG AnsiFileId;
  298. ULONG OemFileId;
  299. ULONG LanguageFileId;
  300. ARC_STATUS Status;
  301. FILE_INFORMATION FileInformation;
  302. ULONG AnsiFileSize;
  303. ULONG OemFileSize;
  304. ULONG LanguageFileSize;
  305. ULONG TotalSize;
  306. ULONG ActualBase;
  307. ULONG_PTR LocalPointer;
  308. LARGE_INTEGER SeekValue;
  309. ULONG Count;
  310. BOOLEAN OemIsSameAsAnsi = FALSE;
  311. //
  312. // Under the Japanese version of NT, ANSI code page and OEM codepage
  313. // is same. In this case, we share the same data to save and memory.
  314. //
  315. if ( (AnsiCodepage->Length == OemCodepage->Length) &&
  316. (_wcsnicmp(AnsiCodepage->Buffer,
  317. OemCodepage->Buffer,
  318. AnsiCodepage->Length) == 0)) {
  319. OemIsSameAsAnsi = TRUE;
  320. }
  321. //
  322. // Open the ANSI data file
  323. //
  324. sprintf(Filename, "%s%wZ", DirectoryPath,AnsiCodepage);
  325. BlOutputLoadMessage(DeviceName, Filename, NULL);
  326. Status = BlOpen(DeviceId, Filename, ArcOpenReadOnly, &AnsiFileId);
  327. if (Status != ESUCCESS) {
  328. goto NlsLoadFailed;
  329. }
  330. BlUpdateBootStatus();
  331. Status = BlGetFileInformation(AnsiFileId, &FileInformation);
  332. BlClose(AnsiFileId);
  333. if (Status != ESUCCESS) {
  334. goto NlsLoadFailed;
  335. }
  336. AnsiFileSize = FileInformation.EndingAddress.LowPart;
  337. //
  338. // Open the OEM data file
  339. //
  340. if (OemIsSameAsAnsi) {
  341. OemFileSize = 0;
  342. } else {
  343. sprintf(Filename, "%s%wZ", DirectoryPath, OemCodepage);
  344. BlOutputLoadMessage(DeviceName, Filename, NULL);
  345. Status = BlOpen(DeviceId, Filename, ArcOpenReadOnly, &OemFileId);
  346. if (Status != ESUCCESS) {
  347. goto NlsLoadFailed;
  348. }
  349. BlUpdateBootStatus();
  350. Status = BlGetFileInformation(OemFileId, &FileInformation);
  351. BlClose(OemFileId);
  352. if (Status != ESUCCESS) {
  353. goto NlsLoadFailed;
  354. }
  355. OemFileSize = FileInformation.EndingAddress.LowPart;
  356. }
  357. //
  358. // Open the language codepage file
  359. //
  360. sprintf(Filename, "%s%wZ", DirectoryPath,LanguageTable);
  361. BlOutputLoadMessage(DeviceName, Filename, NULL);
  362. Status = BlOpen(DeviceId, Filename, ArcOpenReadOnly, &LanguageFileId);
  363. if (Status != ESUCCESS) {
  364. goto NlsLoadFailed;
  365. }
  366. BlUpdateBootStatus();
  367. Status = BlGetFileInformation(LanguageFileId, &FileInformation);
  368. BlClose(LanguageFileId);
  369. if (Status != ESUCCESS) {
  370. goto NlsLoadFailed;
  371. }
  372. LanguageFileSize = FileInformation.EndingAddress.LowPart;
  373. //
  374. // Calculate the total size of the descriptor needed. We want each
  375. // data file to start on a page boundary, so round up each size to
  376. // page granularity.
  377. //
  378. TotalSize = (ULONG)(ROUND_TO_PAGES(AnsiFileSize) +
  379. (OemIsSameAsAnsi ? 0 : ROUND_TO_PAGES(OemFileSize)) +
  380. ROUND_TO_PAGES(LanguageFileSize));
  381. Status = BlAllocateDescriptor(LoaderNlsData,
  382. 0x0,
  383. TotalSize >> PAGE_SHIFT,
  384. &ActualBase);
  385. if (Status != ESUCCESS) {
  386. goto NlsLoadFailed;
  387. }
  388. LocalPointer = KSEG0_BASE | (ActualBase << PAGE_SHIFT);
  389. //
  390. // Read NLS data into memory.
  391. //
  392. // Open and read the ANSI file.
  393. //
  394. sprintf(Filename, "%s%wZ", DirectoryPath, AnsiCodepage);
  395. Status = BlOpen(DeviceId, Filename, ArcOpenReadOnly, &AnsiFileId);
  396. if (Status != ESUCCESS) {
  397. goto NlsLoadFailed;
  398. }
  399. SeekValue.QuadPart = 0;
  400. Status = BlSeek(AnsiFileId, &SeekValue, SeekAbsolute);
  401. if (Status != ESUCCESS) {
  402. goto NlsLoadFailed;
  403. }
  404. Status = BlRead(AnsiFileId,
  405. (PVOID)LocalPointer,
  406. AnsiFileSize,
  407. &Count);
  408. if (Status != ESUCCESS) {
  409. goto NlsLoadFailed;
  410. }
  411. BlLoaderBlock->NlsData->AnsiCodePageData = (PVOID)(LocalPointer + BlVirtualBias);
  412. LocalPointer += ROUND_TO_PAGES(AnsiFileSize);
  413. BlClose(AnsiFileId);
  414. //
  415. // If the OEM file is the same as the ANSI file, then define the OEM file as
  416. // the ANSI file. Otherwise, open and read the OEM file.
  417. //
  418. if(OemIsSameAsAnsi) {
  419. BlLoaderBlock->NlsData->OemCodePageData = BlLoaderBlock->NlsData->AnsiCodePageData;
  420. } else {
  421. sprintf(Filename, "%s%wZ", DirectoryPath, OemCodepage);
  422. Status = BlOpen(DeviceId, Filename, ArcOpenReadOnly, &OemFileId);
  423. if (Status != ESUCCESS) {
  424. goto NlsLoadFailed;
  425. }
  426. SeekValue.QuadPart = 0;
  427. Status = BlSeek(OemFileId, &SeekValue, SeekAbsolute);
  428. if (Status != ESUCCESS) {
  429. goto NlsLoadFailed;
  430. }
  431. Status = BlRead(OemFileId,
  432. (PVOID)LocalPointer,
  433. OemFileSize,
  434. &Count);
  435. if (Status != ESUCCESS) {
  436. goto NlsLoadFailed;
  437. }
  438. BlLoaderBlock->NlsData->OemCodePageData = (PVOID)(LocalPointer + BlVirtualBias);
  439. LocalPointer += ROUND_TO_PAGES(OemFileSize);
  440. BlClose(OemFileId);
  441. }
  442. //
  443. // Open and read Language file.
  444. //
  445. sprintf(Filename, "%s%wZ", DirectoryPath,LanguageTable);
  446. Status = BlOpen(DeviceId, Filename, ArcOpenReadOnly, &LanguageFileId);
  447. if (Status != ESUCCESS) {
  448. goto NlsLoadFailed;
  449. }
  450. SeekValue.QuadPart = 0;
  451. Status = BlSeek(LanguageFileId, &SeekValue, SeekAbsolute);
  452. if (Status != ESUCCESS) {
  453. goto NlsLoadFailed;
  454. }
  455. Status = BlRead(LanguageFileId,
  456. (PVOID)LocalPointer,
  457. LanguageFileSize,
  458. &Count);
  459. if (Status != ESUCCESS) {
  460. goto NlsLoadFailed;
  461. }
  462. BlLoaderBlock->NlsData->UnicodeCaseTableData = (PVOID)(LocalPointer + BlVirtualBias);
  463. BlClose(LanguageFileId);
  464. return(ESUCCESS);
  465. NlsLoadFailed:
  466. strcpy(BadFileName, Filename);
  467. return(Status);
  468. }
  469. ARC_STATUS
  470. BlLoadOemHalFont(
  471. IN ULONG DeviceId,
  472. IN PCHAR DeviceName,
  473. IN PCHAR DirectoryPath,
  474. IN PUNICODE_STRING OemHalFont,
  475. OUT PCHAR BadFileName
  476. )
  477. /*++
  478. Routine Description:
  479. This routine loads the OEM font file for use the HAL display string
  480. function.
  481. Arguments:
  482. DeviceId - Supplies the file id of the device the system tree is on.
  483. DeviceName - Supplies the name of the device the system tree is on.
  484. DirectoryPath - Supplies a pointer to the directory path of the root
  485. of the NT tree.
  486. Fontfile - Supplies the filename of the OEM font file.
  487. BadFileName - Returns the filename of the OEM font file that was missing
  488. or invalid.
  489. Return Value:
  490. ESUCCESS is returned if the OEM font was successfully loaded. Otherwise,
  491. an unsuccessful status is returned and the bad file name is filled.
  492. --*/
  493. {
  494. PVOID FileBuffer;
  495. ULONG Count;
  496. PIMAGE_DOS_HEADER DosHeader;
  497. ULONG FileId;
  498. FILE_INFORMATION FileInformation;
  499. CHAR Filename[129];
  500. ULONG FileSize;
  501. ARC_STATUS Status;
  502. POEM_FONT_FILE_HEADER FontHeader;
  503. PIMAGE_OS2_HEADER Os2Header;
  504. ULONG ScaleFactor;
  505. RESOURCE_TYPE_INFORMATION UNALIGNED *TableAddress;
  506. RESOURCE_TYPE_INFORMATION UNALIGNED *TableEnd;
  507. RESOURCE_NAME_INFORMATION UNALIGNED *TableName;
  508. //
  509. // Open the OEM font file.
  510. //
  511. BlLoaderBlock->OemFontFile = NULL;
  512. sprintf(&Filename[0], "%s%wZ", DirectoryPath, OemHalFont);
  513. BlOutputLoadMessage(DeviceName, &Filename[0], NULL);
  514. Status = BlOpen(DeviceId, &Filename[0], ArcOpenReadOnly, &FileId);
  515. if (Status != ESUCCESS) {
  516. goto OemLoadExit1;
  517. }
  518. BlUpdateBootStatus();
  519. //
  520. // Get the size of the font file and allocate a buffer from the heap
  521. // to hold the font file. Typically this file is about 4kb in length.
  522. //
  523. Status = BlGetFileInformation(FileId, &FileInformation);
  524. if (Status != ESUCCESS) {
  525. goto OemLoadExit;
  526. }
  527. FileSize = FileInformation.EndingAddress.LowPart;
  528. FileBuffer = BlAllocateHeap(FileSize + BlDcacheFillSize - 1);
  529. if (FileBuffer == NULL) {
  530. Status = ENOMEM;
  531. goto OemLoadExit;
  532. }
  533. //
  534. // Round the file buffer address up to a cache line boundary and read
  535. // the file into memory.
  536. //
  537. FileBuffer = (PVOID)((ULONG_PTR)FileBuffer + BlDcacheFillSize - 1);
  538. FileBuffer = (PVOID)((ULONG_PTR)FileBuffer & ~((ULONG_PTR)BlDcacheFillSize - 1));
  539. Status = BlRead(FileId,
  540. FileBuffer,
  541. FileSize,
  542. &Count);
  543. if (Status != ESUCCESS) {
  544. goto OemLoadExit;
  545. }
  546. //
  547. // Attempt to recognize the file as either a .fon or .fnt file.
  548. //
  549. // Check if the file has a DOS header or a font file header. If the
  550. // file has a font file header, then it is a .fnt file. Otherwise,
  551. // it must be checked for an OS/2 executable with a font resource.
  552. //
  553. Status = EBADF;
  554. DosHeader = (PIMAGE_DOS_HEADER)FileBuffer;
  555. if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
  556. //
  557. // Check if the file has a font file header.
  558. //
  559. FontHeader = (POEM_FONT_FILE_HEADER)FileBuffer;
  560. if ((FontHeader->Version != OEM_FONT_VERSION) ||
  561. (FontHeader->Type != OEM_FONT_TYPE) ||
  562. (FontHeader->Italic != OEM_FONT_ITALIC) ||
  563. (FontHeader->Underline != OEM_FONT_UNDERLINE) ||
  564. (FontHeader->StrikeOut != OEM_FONT_STRIKEOUT) ||
  565. (FontHeader->CharacterSet != OEM_FONT_CHARACTER_SET) ||
  566. (FontHeader->Family != OEM_FONT_FAMILY) ||
  567. (FontHeader->PixelWidth > 32)) {
  568. goto OemLoadExit;
  569. } else {
  570. BlLoaderBlock->OemFontFile = (PVOID)FontHeader;
  571. Status = ESUCCESS;
  572. goto OemLoadExit;
  573. }
  574. }
  575. //
  576. // Check if the file has an OS/2 header.
  577. //
  578. if ((FileSize < sizeof(IMAGE_DOS_HEADER)) || (FileSize < (ULONG)DosHeader->e_lfanew)) {
  579. goto OemLoadExit;
  580. }
  581. Os2Header = (PIMAGE_OS2_HEADER)((PUCHAR)DosHeader + DosHeader->e_lfanew);
  582. if (Os2Header->ne_magic != IMAGE_OS2_SIGNATURE) {
  583. goto OemLoadExit;
  584. }
  585. //
  586. // Check if the resource table exists.
  587. //
  588. if ((Os2Header->ne_restab - Os2Header->ne_rsrctab) == 0) {
  589. goto OemLoadExit;
  590. }
  591. //
  592. // Compute address of resource table and search the table for a font
  593. // resource.
  594. //
  595. TableAddress =
  596. (PRESOURCE_TYPE_INFORMATION)((PUCHAR)Os2Header + Os2Header->ne_rsrctab);
  597. TableEnd =
  598. (PRESOURCE_TYPE_INFORMATION)((PUCHAR)Os2Header + Os2Header->ne_restab);
  599. ScaleFactor = *((SHORT UNALIGNED *)TableAddress)++;
  600. while ((TableAddress < TableEnd) &&
  601. (TableAddress->Ident != 0) &&
  602. (TableAddress->Ident != FONT_RESOURCE)) {
  603. TableAddress =
  604. (PRESOURCE_TYPE_INFORMATION)((PUCHAR)(TableAddress + 1) +
  605. (TableAddress->Number * sizeof(RESOURCE_NAME_INFORMATION)));
  606. }
  607. if ((TableAddress >= TableEnd) || (TableAddress->Ident != FONT_RESOURCE)) {
  608. goto OemLoadExit;
  609. }
  610. //
  611. // Compute address of resource name information and check if the resource
  612. // is within the file.
  613. //
  614. TableName = (PRESOURCE_NAME_INFORMATION)(TableAddress + 1);
  615. if (FileSize < ((TableName->Offset << ScaleFactor) + sizeof(OEM_FONT_FILE_HEADER))) {
  616. goto OemLoadExit;
  617. }
  618. //
  619. // Compute the address of the font file header and check if the header
  620. // contains correct information.
  621. //
  622. FontHeader = (POEM_FONT_FILE_HEADER)((PCHAR)FileBuffer +
  623. (TableName->Offset << ScaleFactor));
  624. if ((FontHeader->Version != OEM_FONT_VERSION) ||
  625. (FontHeader->Type != OEM_FONT_TYPE) ||
  626. (FontHeader->Italic != OEM_FONT_ITALIC) ||
  627. (FontHeader->Underline != OEM_FONT_UNDERLINE) ||
  628. (FontHeader->StrikeOut != OEM_FONT_STRIKEOUT) ||
  629. (FontHeader->CharacterSet != OEM_FONT_CHARACTER_SET) ||
  630. (FontHeader->PixelWidth > 32)) {
  631. goto OemLoadExit;
  632. } else {
  633. BlLoaderBlock->OemFontFile = (PVOID)FontHeader;
  634. Status = ESUCCESS;
  635. goto OemLoadExit;
  636. }
  637. //
  638. // Exit loading of the OEM font file.
  639. //
  640. OemLoadExit:
  641. BlClose(FileId);
  642. OemLoadExit1:
  643. strcpy(BadFileName,&Filename[0]);
  644. return(Status);
  645. }
  646. ARC_STATUS
  647. BlLoadDeviceDriver(
  648. IN PPATH_SET PathSet,
  649. IN PCHAR DriverName,
  650. IN PTCHAR DriverDescription OPTIONAL,
  651. IN ULONG DriverFlags,
  652. OUT PKLDR_DATA_TABLE_ENTRY *DriverDataTableEntry
  653. )
  654. /*++
  655. Routine Description:
  656. This routine loads the specified device driver and resolves all DLL
  657. references if the driver is not already loaded.
  658. Arguments:
  659. PathSet - Describes all the various locations the driver could be present
  660. at.
  661. DriverName - Supplies a pointer to a zero terminated device driver
  662. name string.
  663. DriverDescription - Supplies an optional pointer to a zero terminated string
  664. to be displayed when loading the driver. If NULL, DriverName is used.
  665. DriverFlags - Supplies the driver flags that are to be set in the
  666. generated data table entry.
  667. DriverDataTableEntry - Receives a pointer to the data table entry
  668. created for the newly-loaded driver.
  669. Return Value:
  670. ESUCCESS is returned if the specified driver is successfully loaded
  671. or it is already loaded. Otherwise, and unsuccessful status is
  672. returned.
  673. --*/
  674. {
  675. CHAR DllName[256];
  676. CHAR FullName[256];
  677. PVOID Base;
  678. ARC_STATUS Status;
  679. ULONG Index;
  680. PPATH_SOURCE PathSource;
  681. //
  682. // Generate the DLL name for the device driver.
  683. //
  684. strcpy(&DllName[0], DriverName);
  685. //
  686. // If the specified device driver is not already loaded, then load it.
  687. //
  688. if (BlCheckForLoadedDll(&DllName[0], DriverDataTableEntry) == FALSE) {
  689. //
  690. // Start walking our list of DevicePaths. If the list is
  691. // empty (bad caller!) we fail with ENOENT.
  692. //
  693. Status = ENOENT;
  694. for(Index=0; Index < PathSet->PathCount; Index++) {
  695. PathSource = &PathSet->Source[Index];
  696. //
  697. // Generate the full path name of device driver.
  698. //
  699. strcpy(&FullName[0], PathSource->DirectoryPath);
  700. strcat(&FullName[0], PathSet->PathOffset);
  701. strcat(&FullName[0], DriverName);
  702. //
  703. // Try to load it.
  704. //
  705. Status = BlLoadImage(PathSource->DeviceId,
  706. LoaderBootDriver,
  707. &FullName[0],
  708. TARGET_IMAGE,
  709. &Base);
  710. if (Status == ESUCCESS) {
  711. //
  712. // Print out the driver that loaded.
  713. //
  714. BlOutputLoadMessage((PCHAR) PathSource->DeviceName,
  715. &FullName[0],
  716. DriverDescription);
  717. break;
  718. }
  719. }
  720. if (Status != ESUCCESS) {
  721. return Status;
  722. }
  723. BlUpdateBootStatus();
  724. //
  725. // Generate a data table entry for the driver, then clear the entry
  726. // processed flag. The I/O initialization code calls each DLL in the
  727. // loaded module list that does not have its entry processed flag set.
  728. //
  729. // ISSUE - 2000/29/03 - ADRIAO: Existant namespace polution
  730. // Instead of passing in DllName here, we should be passing in
  731. // AliasName\PathOffset\DriverName.
  732. //
  733. Status = BlAllocateDataTableEntry(&DllName[0],
  734. DriverName,
  735. Base,
  736. DriverDataTableEntry);
  737. if (Status != ESUCCESS) {
  738. return Status;
  739. }
  740. //
  741. // Set the flag LDRP_DRIVER_DEPENDENT_DLL so that BlScanImportDescriptorTable
  742. // will set the flag in the data table entries for the dlls that it creates.
  743. //
  744. (*DriverDataTableEntry)->Flags |= DriverFlags|LDRP_DRIVER_DEPENDENT_DLL;
  745. //
  746. // Scan the import table and load all the referenced DLLs.
  747. //
  748. // ISSUE - 2000/29/03 - ADRIAO: LDR memory
  749. // This should probably be LoaderBootDriver. Per MikeG we are
  750. // leaving this alone for now.
  751. //
  752. Status = BlScanImportDescriptorTable(PathSet,
  753. *DriverDataTableEntry,
  754. LoaderHalCode);
  755. if (Status != ESUCCESS) {
  756. //
  757. // Remove the driver from the load order list.
  758. //
  759. RemoveEntryList(&(*DriverDataTableEntry)->InLoadOrderLinks);
  760. return Status;
  761. }
  762. //
  763. // Clear the flag here. This way we don't call DllInitialize for drivers.
  764. //
  765. (*DriverDataTableEntry)->Flags &= ~LDRP_DRIVER_DEPENDENT_DLL;
  766. }
  767. return ESUCCESS;
  768. }
  769. VOID
  770. BlUpdateBootStatus(
  771. VOID
  772. )
  773. /*++
  774. Routine Description:
  775. Updates the boot status (like updating progress bar currently).
  776. Generally gets called after important files are loaded.
  777. Arguments:
  778. None
  779. Return Value:
  780. None
  781. --*/
  782. {
  783. BlNumFilesLoaded++;
  784. if (BlShowProgressBar)
  785. BlNumProgressBarFilesLoaded++;
  786. BlRedrawProgressBar();
  787. }
  788. VOID
  789. BlRedrawProgressBar(
  790. VOID
  791. )
  792. /*++
  793. Routine Description:
  794. Redraws the progress bar (with the last percentage)
  795. Arguments:
  796. None
  797. Return Value:
  798. None
  799. --*/
  800. {
  801. if (!BlShowProgressBar) {
  802. ULONG EndTime = ArcGetRelativeTime();
  803. if ((BlProgressBarShowTimeOut == 0) ||
  804. ((EndTime - BlStartTime) > BlProgressBarShowTimeOut)) {
  805. BlShowProgressBar = TRUE;
  806. BlNumProgressBarFilesLoaded = 1;
  807. BlProgressBarFilesToLoad = BlMaxFilesToLoad - BlNumFilesLoaded;
  808. }
  809. }
  810. if (BlShowProgressBar && (BlProgressBarFilesToLoad>0)) {
  811. BlUpdateProgressBar((BlNumProgressBarFilesLoaded * 100) / BlProgressBarFilesToLoad);
  812. }
  813. }
  814. VOID
  815. BlUpdateTxtProgressBar(
  816. ULONG fPercentage
  817. )
  818. /*++
  819. Routine Description:
  820. Draws the progress bar with the specified percentage value
  821. Arguments:
  822. fPercentage : percentage the progress bar needs to show
  823. (Note : should have a value between 0 & 100 inclusive)
  824. Return Value:
  825. None
  826. --*/
  827. {
  828. ULONG lCount = 0;
  829. TCHAR szMsg[PROGRESS_BAR_WIDTH * 2 + 2] = {0};
  830. int iNumChars = 0;
  831. int iNumBackChars = 0;
  832. _TUCHAR szBarBackStr[PROGRESS_BAR_WIDTH * 2 + 2] = {0};
  833. _TUCHAR szPrgBar[PROGRESS_BAR_WIDTH * 4 + 2] = {0};
  834. _PTUCHAR szBarBack = 0;
  835. static ULONG uRow = 0;
  836. static ULONG uCol = 0;
  837. static ULONG uBarWidth = PROGRESS_BAR_WIDTH;
  838. if (BlShowProgressBar && BlOutputDots) {
  839. // fix percentage value (if needed)
  840. if (fPercentage > 100)
  841. fPercentage = 100;
  842. // select the row where to display the progress bar
  843. if (uRow == 0)
  844. uRow = ScreenHeight - 2;
  845. // fix the start column
  846. if (uCol == 0) {
  847. if (PROGRESS_BAR_WIDTH >= ScreenWidth) {
  848. uCol = 1;
  849. uBarWidth = ScreenWidth;
  850. } else {
  851. uCol = (ScreenWidth - PROGRESS_BAR_WIDTH) / 2;
  852. uBarWidth = PROGRESS_BAR_WIDTH;
  853. }
  854. }
  855. iNumChars = (fPercentage * uBarWidth) / 100;
  856. iNumBackChars = uBarWidth - iNumChars;
  857. if (iNumChars) {
  858. #ifdef EFI
  859. PTCHAR pMsg = szMsg;
  860. ULONG uNumChars = iNumChars;
  861. while (uNumChars--) {
  862. *pMsg++ = BlFrontChar;
  863. }
  864. #else
  865. //
  866. // copy appropriately based on single / double byte character
  867. // each dbcs character takes two single char space on screen
  868. //
  869. if (BlFrontChar & 0xFF00) {
  870. USHORT *pMsg = (USHORT *)szMsg;
  871. ULONG uNumChars = (iNumChars + 1) / 2;
  872. while(uNumChars--)
  873. *pMsg++ = BlFrontChar;
  874. } else {
  875. memset( szMsg, BlFrontChar, min(iNumChars, sizeof(szMsg) - 1));
  876. }
  877. #endif
  878. }
  879. if (iNumBackChars && BlBackChar) {
  880. #ifdef EFI
  881. PTCHAR pMsg = szBarBackStr;
  882. ULONG uNumChars = iNumBackChars;
  883. while (uNumChars--) {
  884. *pMsg++ = BlBackChar;
  885. }
  886. #else
  887. //
  888. // copy appropriately based on single / double byte character
  889. // each dbcs character takes two single char space on screen
  890. //
  891. if (BlBackChar & 0xFF00) {
  892. USHORT *pMsg = (USHORT *)szBarBackStr;
  893. ULONG uNumChars = iNumBackChars / 2;
  894. while(uNumChars--)
  895. *pMsg++ = BlBackChar;
  896. } else {
  897. memset(szBarBackStr, BlBackChar,
  898. min(sizeof(szBarBackStr) - 1, iNumBackChars));
  899. }
  900. #endif
  901. }
  902. _tcscat(szPrgBar, szMsg);
  903. _tcscat(szPrgBar, szBarBackStr);
  904. #if 0
  905. {
  906. TCHAR szDbg[512] = { 0 };
  907. _stprintf(szDbg, TEXT("(%x, %x)=[%d,%d],%x\n%s\n%s\n%s"),
  908. BlFrontChar, BlBackChar, iNumChars, iNumBackChars, fPercentage,
  909. szMsg, szBarBackStr, szPrgBar);
  910. BlPositionCursor(1,1);
  911. ArcWrite(BlConsoleOutDeviceId,
  912. szDbg,
  913. _tcslen(szDbg)*sizeof(TCHAR),
  914. &lCount);
  915. }
  916. #endif
  917. // print out the progress bar
  918. BlPositionCursor(uCol, uRow);
  919. ArcWrite(BlConsoleOutDeviceId,
  920. szPrgBar,
  921. _tcslen(szPrgBar)*sizeof(TCHAR),
  922. &lCount);
  923. }
  924. }
  925. VOID
  926. BlUpdateProgressBar(
  927. ULONG fPercentage
  928. )
  929. {
  930. if (DisplayLogoOnBoot) {
  931. BlUpdateGfxProgressBar(fPercentage);
  932. } else {
  933. BlUpdateTxtProgressBar(fPercentage);
  934. }
  935. }
  936. VOID
  937. BlOutputStartupMsgStr(
  938. PCTSTR MsgStr
  939. )
  940. /*++
  941. Routine Description:
  942. Clears the screen and displays the startup message at the specified
  943. coordinates of screen
  944. Arguments:
  945. MsgStr - the message that needs to be displayed
  946. Return Value:
  947. None
  948. --*/
  949. {
  950. ULONG lCount = 0;
  951. ULONG uX = 0, uY = 0;
  952. if (!DisplayLogoOnBoot && BlOutputDots && MsgStr) {
  953. BlClearScreen();
  954. BlSetInverseMode(FALSE);
  955. // center the message
  956. uX = ScreenHeight - 3;
  957. uY = (ScreenWidth / 2) - (_tcslen(MsgStr) / 2);
  958. if (uY > ScreenWidth)
  959. uY = 1;
  960. // print out the message
  961. BlPositionCursor(uY, uX);
  962. ArcWrite(BlConsoleOutDeviceId,
  963. (PVOID)MsgStr,
  964. _tcslen(MsgStr) * sizeof(TCHAR),
  965. &lCount);
  966. BlRedrawProgressBar();
  967. }
  968. }
  969. VOID
  970. BlOutputStartupMsg(
  971. ULONG uMsgID
  972. )
  973. /*++
  974. Routine Description:
  975. Clears the screen and displays the startup message at the specified
  976. coordinates of screen
  977. Arguments:
  978. uMsgID - inidicates the message ID that needs to be displayed
  979. Return Value:
  980. None
  981. --*/
  982. {
  983. if (!DisplayLogoOnBoot && BlOutputDots) {
  984. //
  985. // Proceed only if no logo is displayed.
  986. //
  987. BlOutputStartupMsgStr(BlFindMessage(uMsgID));
  988. }
  989. }
  990. VOID
  991. BlOutputTrailerMsgStr(
  992. PCTSTR MsgStr
  993. )
  994. /*++
  995. Routine Description:
  996. Displays a trailer message at the bottom of the screen
  997. Arguments:
  998. uMsgID - inidicates the message ID that needs to be displayed
  999. Return Value:
  1000. None
  1001. --*/
  1002. {
  1003. ULONG lCount = 0;
  1004. TCHAR szText[256] = {0};
  1005. if (!DisplayLogoOnBoot && BlOutputDots && MsgStr) {
  1006. ASSERT( _tcslen(MsgStr) < 256 );
  1007. BlPositionCursor(1, ScreenHeight);
  1008. _tcscpy(szText, MsgStr);
  1009. lCount = (ULONG)_tcslen(szText);
  1010. if ((lCount > 2) && szText[lCount-2] == TEXT('\r') && szText[lCount-1] == TEXT('\n')) {
  1011. szText[lCount-2] = TEXT('\0');
  1012. lCount -= 2;
  1013. }
  1014. ArcWrite(BlConsoleOutDeviceId,
  1015. szText,
  1016. lCount*sizeof(TCHAR),
  1017. &lCount);
  1018. }
  1019. }
  1020. VOID
  1021. BlOutputTrailerMsg(
  1022. ULONG uMsgID
  1023. )
  1024. /*++
  1025. Routine Description:
  1026. Displays a trailer message at the bottom of the screen
  1027. Arguments:
  1028. uMsgID - inidicates the message ID that needs to be displayed
  1029. Return Value:
  1030. None
  1031. --*/
  1032. {
  1033. BlOutputTrailerMsgStr(BlFindMessage(uMsgID));
  1034. }
  1035. VOID
  1036. BlSetProgBarCharacteristics(
  1037. IN ULONG FrontCharMsgID,
  1038. IN ULONG BackCharMsgID
  1039. )
  1040. /*++
  1041. Routine Description:
  1042. Sets the characteristics for progress bar
  1043. Arguments:
  1044. IN ULONG FrontCharMsgID : Progress bar foreground character
  1045. IN ULONG BackCharMsgID : Progress bar background character
  1046. Return Value:
  1047. None
  1048. --*/
  1049. {
  1050. #ifdef EFI
  1051. BlFrontChar = GetGraphicsChar( GraphicsCharFullBlock );
  1052. BlBackChar = GetGraphicsChar( GraphicsCharLightShade );
  1053. #else
  1054. _PTUCHAR szBar = 0;
  1055. BlProgBarFrontMsgID = FrontCharMsgID;
  1056. BlProgBarBackMsgID = BackCharMsgID;
  1057. // fetch the bar character from resource file
  1058. szBar = BlFindMessage(BlProgBarFrontMsgID);
  1059. if (szBar) {
  1060. ULONG len = _tcslen(szBar);
  1061. if ((len == 1) ||
  1062. ((len > 2) && (szBar[1] == TEXT('\r')) && (szBar[2] == TEXT('\n')))) {
  1063. BlFrontChar = szBar[0];
  1064. } else {
  1065. BlFrontChar = *(USHORT *)szBar;
  1066. }
  1067. }
  1068. // fetch the progress bar background character
  1069. szBar = BlFindMessage(BlProgBarBackMsgID);
  1070. if (szBar) {
  1071. ULONG len = _tcslen(szBar);
  1072. if ((len == 1) ||
  1073. ((len > 2) && (szBar[1] == TEXT('\r')) && (szBar[2] == TEXT('\n')))) {
  1074. BlBackChar = szBar[0];
  1075. } else {
  1076. BlBackChar = *(USHORT *)szBar;
  1077. }
  1078. }
  1079. //
  1080. // make both the progess bar characters double byte characters
  1081. // if one of them is double byte character
  1082. //
  1083. if (BlFrontChar & 0xFF00) {
  1084. if (!(BlBackChar & 0xFF00))
  1085. BlBackChar = BlBackChar | (BlBackChar << 8);
  1086. } else {
  1087. if (BlBackChar & 0xFF00)
  1088. BlFrontChar = BlFrontChar | (BlFrontChar << 8);
  1089. }
  1090. #endif
  1091. }
  1092. ARC_STATUS
  1093. BlLoadFileImage(
  1094. IN ULONG DeviceId,
  1095. IN PCHAR DeviceName,
  1096. IN PCHAR Directory,
  1097. IN PUNICODE_STRING FileName,
  1098. IN TYPE_OF_MEMORY MemoryType,
  1099. OUT PVOID *Image,
  1100. OUT PULONG ImageSize,
  1101. OUT PCHAR BadFileName
  1102. )
  1103. /*++
  1104. Routine Description:
  1105. This routine loads the specified device driver and resolves all DLL
  1106. references if the driver is not already loaded.
  1107. Arguments:
  1108. DeviceId - Supplies the file id of the device on which the specified
  1109. device driver is loaded from.
  1110. DeviceName - Supplies the name of the device the system tree is on.
  1111. Directory - Supplies a pointer to the directory path of the root
  1112. of the NT tree.
  1113. FileName - Name of the file to be loaded.
  1114. Image - Receives pointer to the buffer containing the file image in memory.
  1115. ImageSize - Receives the size of file image in memory.
  1116. BadFileName - Returns the filename of the OEM font file that was missing
  1117. or invalid.
  1118. Return Value:
  1119. ESUCCESS is returned if the specified file is successfully loaded.
  1120. Otherwise unsuccessful status is returned.
  1121. --*/
  1122. {
  1123. CHAR infName[256];
  1124. ARC_STATUS status;
  1125. ULONG fileId;
  1126. FILE_INFORMATION fileInfo;
  1127. ULONG size;
  1128. ULONG pageCount;
  1129. ULONG actualBase;
  1130. PCHAR buffer;
  1131. ULONG sizeRead;
  1132. *Image = NULL;
  1133. *ImageSize = 0;
  1134. //
  1135. // Get the fully qualified name for the file being loaded.
  1136. //
  1137. sprintf(&infName[0], "%s%wZ", Directory, FileName);
  1138. //
  1139. // Display the name of file being loaded.
  1140. //
  1141. BlOutputLoadMessage(DeviceName, infName, NULL);
  1142. //
  1143. // Open the file.
  1144. //
  1145. status = BlOpen(DeviceId, infName, ArcOpenReadOnly, &fileId);
  1146. if (status == ESUCCESS) {
  1147. BlUpdateBootStatus();
  1148. //
  1149. // Find out size of INF file.
  1150. //
  1151. status = BlGetFileInformation(fileId, &fileInfo);
  1152. if (status == ESUCCESS) {
  1153. size = fileInfo.EndingAddress.LowPart;
  1154. //
  1155. // Allocate a descriptor large enough to hold the entire file.
  1156. // On x86 this has an unfortunate tendency to slam txtsetup.sif
  1157. // into a free block at 1MB, which means the kernel can't be
  1158. // loaded (it's linked for 0x100000 without relocations).
  1159. // On x86 this has an unfortunate tendency to slam txtsetup.sif
  1160. // into a free block at 1MB, which means the kernel can't be
  1161. // loaded (it's linked for 0x100000 without relocations).
  1162. //
  1163. // (tedm) we're also seeing a similar problem on alphas now
  1164. // because txtsetup.sif has grown too large, so this code has been
  1165. // made non-conditional.
  1166. //
  1167. pageCount = (ULONG)(ROUND_TO_PAGES(size) >> PAGE_SHIFT);
  1168. status = BlAllocateDescriptor( MemoryType, // Descriptor gets reclaimed by MM.
  1169. 0,
  1170. pageCount,
  1171. &actualBase);
  1172. if (status == ESUCCESS) {
  1173. buffer = (PCHAR)(KSEG0_BASE | (actualBase << PAGE_SHIFT));
  1174. //
  1175. // Read the file in.
  1176. //
  1177. status = BlRead(fileId, buffer, size, &sizeRead);
  1178. if (status == ESUCCESS) {
  1179. //
  1180. // If the file was successfully read, return the
  1181. // desired parameters.
  1182. //
  1183. if (Image) {
  1184. *Image = buffer;
  1185. }
  1186. if (ImageSize) {
  1187. *ImageSize = sizeRead;
  1188. }
  1189. }
  1190. else {
  1191. //
  1192. // No need to release the memory as it will get reclaimed by MM anyway.
  1193. //
  1194. }
  1195. }
  1196. }
  1197. //
  1198. // Close the file handle.
  1199. //
  1200. BlClose(fileId);
  1201. }
  1202. //
  1203. // If there was any error, return the name of the file
  1204. // we failed to load.
  1205. //
  1206. if (status != ESUCCESS)
  1207. {
  1208. strcpy(BadFileName, &infName[0]);
  1209. }
  1210. return(status);
  1211. }
  1212. VOID
  1213. BlClearScreen(
  1214. VOID
  1215. )
  1216. /*++
  1217. Routine Description:
  1218. Clears the screen.
  1219. Arguments:
  1220. None
  1221. Return Value:
  1222. None.
  1223. --*/
  1224. {
  1225. #ifdef EFI
  1226. BlEfiClearDisplay();
  1227. #else
  1228. TCHAR Buffer[16];
  1229. ULONG Count;
  1230. _stprintf(Buffer, ASCI_CSI_OUT TEXT("2J"));
  1231. ArcWrite(BlConsoleOutDeviceId,
  1232. Buffer,
  1233. _tcslen(Buffer) *sizeof(TCHAR),
  1234. &Count);
  1235. #endif
  1236. }
  1237. VOID
  1238. BlClearToEndOfScreen(
  1239. VOID
  1240. )
  1241. {
  1242. #ifdef EFI
  1243. BlEfiClearToEndOfDisplay();
  1244. #else
  1245. TCHAR Buffer[16];
  1246. ULONG Count;
  1247. _stprintf(Buffer, ASCI_CSI_OUT TEXT("J"));
  1248. ArcWrite(BlConsoleOutDeviceId,
  1249. Buffer,
  1250. _tcslen(Buffer)*sizeof(TCHAR),
  1251. &Count);
  1252. #endif
  1253. }
  1254. VOID
  1255. BlClearToEndOfLine(
  1256. VOID
  1257. )
  1258. {
  1259. #ifdef EFI
  1260. BlEfiClearToEndOfLine();
  1261. #else
  1262. TCHAR Buffer[16];
  1263. ULONG Count;
  1264. if (!DisplayLogoOnBoot) {
  1265. _stprintf(Buffer, ASCI_CSI_OUT TEXT("K"));
  1266. ArcWrite(BlConsoleOutDeviceId,
  1267. Buffer,
  1268. _tcslen(Buffer)*sizeof(TCHAR),
  1269. &Count);
  1270. }
  1271. #endif
  1272. }
  1273. VOID
  1274. BlPositionCursor(
  1275. IN ULONG Column,
  1276. IN ULONG Row
  1277. )
  1278. /*++
  1279. Routine Description:
  1280. Sets the position of the cursor on the screen.
  1281. Arguments:
  1282. Column - supplies new Column for the cursor position.
  1283. Row - supplies new Row for the cursor position.
  1284. Return Value:
  1285. None.
  1286. --*/
  1287. {
  1288. #ifdef EFI
  1289. BlEfiPositionCursor( Column-1, Row-1 );
  1290. #else
  1291. TCHAR Buffer[16];
  1292. ULONG Count;
  1293. _stprintf(Buffer, ASCI_CSI_OUT TEXT("%d;%dH"), Row, Column);
  1294. ArcWrite(BlConsoleOutDeviceId,
  1295. Buffer,
  1296. _tcslen(Buffer)*sizeof(TCHAR),
  1297. &Count);
  1298. #endif
  1299. }
  1300. VOID
  1301. BlSetInverseMode(
  1302. IN BOOLEAN InverseOn
  1303. )
  1304. /*++
  1305. Routine Description:
  1306. Sets inverse console output mode on or off.
  1307. Arguments:
  1308. InverseOn - supplies whether inverse mode should be turned on (TRUE)
  1309. or off (FALSE)
  1310. Return Value:
  1311. None.
  1312. --*/
  1313. {
  1314. #ifdef EFI
  1315. BlEfiSetInverseMode( InverseOn );
  1316. #else
  1317. TCHAR Buffer[16];
  1318. ULONG Count;
  1319. _stprintf(Buffer, ASCI_CSI_OUT TEXT("%dm"), InverseOn ? SGR_INVERSE : SGR_NORMAL);
  1320. ArcWrite(BlConsoleOutDeviceId,
  1321. Buffer,
  1322. _tcslen(Buffer)*sizeof(TCHAR),
  1323. &Count);
  1324. #endif
  1325. }