Leaked source code of windows server 2003
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.

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