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.

433 lines
12 KiB

  1. /*++
  2. Copyright (c) 1999 Intel Corporation
  3. Module Name:
  4. EfiDump.c
  5. Abstract:
  6. Dump out info about EFI structs
  7. Revision History
  8. --*/
  9. #include "shelle.h"
  10. #include "fat.h"
  11. typedef union {
  12. FAT_BOOT_SECTOR Fat;
  13. FAT_BOOT_SECTOR_EX Fat32;
  14. } EFI_FAT_BOOT_SECTOR;
  15. FAT_VOLUME_TYPE
  16. ValidBPB (
  17. IN EFI_FAT_BOOT_SECTOR *Bpb,
  18. IN UINTN BlockSize
  19. );
  20. VOID
  21. DumpBpb (
  22. IN FAT_VOLUME_TYPE FatType,
  23. IN EFI_FAT_BOOT_SECTOR *Bpb,
  24. IN UINTN BlockSize
  25. );
  26. typedef union {
  27. VOID *RawData;
  28. UINT8 *PtrMath;
  29. EFI_TABLE_HEADER *Hdr;
  30. EFI_PARTITION_HEADER *Partition;
  31. EFI_SYSTEM_TABLE *Sys;
  32. EFI_RUNTIME_SERVICES *RT;
  33. EFI_BOOT_SERVICES *BS;
  34. } EFI_TABLE_HEADER_PTR;
  35. VOID
  36. EFIFileAttributePrint (
  37. IN UINT64 Attrib
  38. );
  39. CHAR16 *
  40. EFIClassString (
  41. IN UINT32 Class
  42. );
  43. BOOLEAN
  44. IsValidEfiHeader (
  45. IN UINTN BlockSize,
  46. IN EFI_TABLE_HEADER_PTR Hdr
  47. );
  48. VOID
  49. EFITableHeaderPrint (
  50. IN VOID *Buffer,
  51. IN UINTN ByteSize,
  52. IN UINT64 BlockAddress,
  53. IN BOOLEAN IsBlkDevice
  54. );
  55. VOID
  56. DumpGenericHeader (
  57. IN EFI_TABLE_HEADER_PTR Tbl
  58. );
  59. VOID
  60. DumpPartition (
  61. IN EFI_TABLE_HEADER_PTR Tbl
  62. );
  63. VOID
  64. DumpFileHeader (
  65. IN EFI_TABLE_HEADER_PTR Tbl
  66. );
  67. VOID
  68. DumpSystemTable (
  69. IN EFI_TABLE_HEADER_PTR Tbl
  70. );
  71. UINT8 FatNumber[] = { 12, 16, 32, 0 };
  72. VOID
  73. EFIStructsPrint (
  74. IN VOID *Buffer,
  75. IN UINTN BlockSize,
  76. IN UINT64 BlockAddress,
  77. IN EFI_BLOCK_IO *BlkIo
  78. )
  79. {
  80. MASTER_BOOT_RECORD *Mbr;
  81. INTN i;
  82. BOOLEAN IsBlkDevice;
  83. FAT_VOLUME_TYPE FatType;
  84. Print (L"\n");
  85. Mbr = NULL;
  86. if (BlockAddress == 0 && BlkIo != NULL) {
  87. Mbr = (MASTER_BOOT_RECORD *)Buffer;
  88. if (ValidMBR (Mbr, BlkIo)) {
  89. Print (L" Valid MBR\n ---------\n");
  90. for (i=0; i<MAX_MBR_PARTITIONS; i++) {
  91. Print (L" Partition %d OS %02x Start 0x%08x Size 0x%08x\n",
  92. i,
  93. Mbr->Partition[i].OSIndicator,
  94. EXTRACT_UINT32(Mbr->Partition[i].StartingLBA),
  95. EXTRACT_UINT32(Mbr->Partition[i].SizeInLBA)
  96. );
  97. }
  98. } else if ((FatType = ValidBPB ((EFI_FAT_BOOT_SECTOR*) Buffer, BlockSize)) != FatUndefined) {
  99. DumpBpb (FatType, (EFI_FAT_BOOT_SECTOR*) Buffer, BlockSize);
  100. }
  101. }
  102. if (!Mbr) {
  103. IsBlkDevice = (BlkIo != NULL);
  104. EFITableHeaderPrint (Buffer, BlockSize, BlockAddress, IsBlkDevice);
  105. }
  106. }
  107. typedef
  108. VOID
  109. (*EFI_DUMP_HEADER) (
  110. IN EFI_TABLE_HEADER_PTR Tbl
  111. );
  112. typedef struct {
  113. UINT64 Signature;
  114. CHAR16 *String;
  115. EFI_DUMP_HEADER Func;
  116. } TABLE_HEADER_INFO;
  117. TABLE_HEADER_INFO TableHeader[] = {
  118. EFI_PARTITION_SIGNATURE, L"Partition", DumpPartition,
  119. EFI_SYSTEM_TABLE_SIGNATURE, L"System", DumpSystemTable,
  120. EFI_BOOT_SERVICES_SIGNATURE, L"Boot Services", DumpGenericHeader,
  121. EFI_RUNTIME_SERVICES_SIGNATURE, L"Runtime Services", DumpGenericHeader,
  122. 0x00, L"", DumpGenericHeader
  123. };
  124. VOID
  125. EFITableHeaderPrint (
  126. IN VOID *Buffer,
  127. IN UINTN ByteSize,
  128. IN UINT64 BlockAddress,
  129. IN BOOLEAN IsBlkDevice
  130. )
  131. {
  132. EFI_TABLE_HEADER_PTR Hdr;
  133. INTN i;
  134. Hdr.RawData = Buffer;
  135. if (IsValidEfiHeader (ByteSize, Hdr)) {
  136. for (i=0; TableHeader[i].Signature != 0x00; i++) {
  137. if (TableHeader[i].Signature == Hdr.Hdr->Signature) {
  138. Print (L" Valid EFI Header at %a %016lx\n ----------------------------------------%a\n",
  139. (IsBlkDevice ? "LBA":"Address"),
  140. BlockAddress,
  141. (IsBlkDevice ? "":"----")
  142. );
  143. Print (L" %H%s: Table Structure%N size %08x revision %08x\n", TableHeader[i].String, Hdr.Hdr->HeaderSize, Hdr.Hdr->Revision);
  144. TableHeader[i].Func (Hdr);
  145. return;
  146. }
  147. }
  148. /*
  149. * Dump the Generic Header, since we don't know the type
  150. */
  151. TableHeader[i].Func (Hdr);
  152. }
  153. }
  154. BOOLEAN
  155. IsValidEfiHeader (
  156. IN UINTN BlockSize,
  157. IN EFI_TABLE_HEADER_PTR Hdr
  158. )
  159. {
  160. if (Hdr.Hdr->HeaderSize == 0x00) {
  161. return FALSE;
  162. }
  163. if (Hdr.Hdr->HeaderSize > BlockSize) {
  164. return FALSE;
  165. }
  166. return TRUE;
  167. }
  168. VOID
  169. DumpGenericHeader (
  170. IN EFI_TABLE_HEADER_PTR Tbl
  171. )
  172. {
  173. Print (L" Header 0x%016lx Revision 0x%08x Size 0x%08x CRC 0x%08x\n",
  174. Tbl.Hdr->Signature,
  175. Tbl.Hdr->Revision,
  176. Tbl.Hdr->HeaderSize,
  177. Tbl.Hdr->CRC32
  178. );
  179. }
  180. VOID
  181. DumpPartition (
  182. IN EFI_TABLE_HEADER_PTR Tbl
  183. )
  184. {
  185. Print (L" LBA's 0x%016lx - 0x%016lx Unusable (0x%016lx)\n",
  186. Tbl.Partition->FirstUsableLba,
  187. Tbl.Partition->LastUsableLba,
  188. Tbl.Partition->UnusableSpace
  189. );
  190. Print (L" Free Space LBA 0x%016lx Root LBA 0x%016lx\n",
  191. Tbl.Partition->FreeSpace,
  192. Tbl.Partition->RootFile
  193. );
  194. Print (L" Block Size 0x%08x Dir Allocation Units 0x%08x\n",
  195. Tbl.Partition->BlockSize,
  196. Tbl.Partition->DirectoryAllocationNumber
  197. );
  198. }
  199. CHAR16 *
  200. EFIClassString (
  201. IN UINT32 Class
  202. )
  203. {
  204. switch (Class) {
  205. case EFI_FILE_CLASS_FREE_SPACE:
  206. return L"Free Space";
  207. case EFI_FILE_CLASS_EMPTY:
  208. return L"Empty";
  209. case EFI_FILE_CLASS_NORMAL:
  210. return L"Nornal";
  211. default:
  212. return L"Invalid";
  213. }
  214. }
  215. VOID
  216. DumpSystemTable (
  217. IN EFI_TABLE_HEADER_PTR Tbl
  218. )
  219. {
  220. EFI_STATUS Status;
  221. EFI_DEVICE_PATH *DevicePath;
  222. VOID *AcpiTable = NULL;
  223. VOID *SMBIOSTable = NULL;
  224. VOID *SalSystemTable = NULL;
  225. VOID *MpsTable = NULL;
  226. Print (L" ConIn (0x%08x) ConOut (0x%08x) StdErr (0x%08x)\n",
  227. Tbl.Sys->ConsoleInHandle,
  228. Tbl.Sys->ConsoleOutHandle,
  229. Tbl.Sys->StandardErrorHandle
  230. );
  231. Status = BS->HandleProtocol (Tbl.Sys->ConsoleInHandle, &DevicePathProtocol, (VOID*)&DevicePath);
  232. if (Status == EFI_SUCCESS && DevicePath) {
  233. Print (L" Console In on %s\n", DevicePathToStr (DevicePath));
  234. }
  235. Status = BS->HandleProtocol (Tbl.Sys->ConsoleOutHandle, &DevicePathProtocol, (VOID*)&DevicePath);
  236. if (Status == EFI_SUCCESS && DevicePath) {
  237. Print (L" Console Out on %s\n", DevicePathToStr (DevicePath));
  238. }
  239. Status = BS->HandleProtocol (Tbl.Sys->StandardErrorHandle, &DevicePathProtocol, (VOID*)&DevicePath);
  240. if (Status == EFI_SUCCESS && DevicePath) {
  241. Print (L" Std Error on %s\n", DevicePathToStr (DevicePath));
  242. }
  243. Print (L" Runtime Services 0x%016lx\n", (UINT64)Tbl.Sys->RuntimeServices);
  244. Print (L" Boot Services 0x%016lx\n", (UINT64)Tbl.Sys->BootServices);
  245. Status = LibGetSystemConfigurationTable(&SalSystemTableGuid, &SalSystemTable);
  246. if (!EFI_ERROR(Status)) {
  247. Print (L" SAL System Table 0x%016lx\n", (UINT64)SalSystemTable);
  248. }
  249. Status = LibGetSystemConfigurationTable(&AcpiTableGuid, &AcpiTable);
  250. if (!EFI_ERROR(Status)) {
  251. Print (L" ACPI Table 0x%016lx\n", (UINT64)AcpiTable);
  252. }
  253. Status = LibGetSystemConfigurationTable(&MpsTableGuid, &MpsTable);
  254. if (!EFI_ERROR(Status)) {
  255. Print (L" MPS Table 0x%016lx\n", (UINT64)MpsTable);
  256. }
  257. Status = LibGetSystemConfigurationTable(&SMBIOSTableGuid, &SMBIOSTable);
  258. if (!EFI_ERROR(Status)) {
  259. Print (L" SMBIOS Table 0x%016lx\n", (UINT64)SMBIOSTable);
  260. }
  261. }
  262. FAT_VOLUME_TYPE
  263. ValidBPB (
  264. IN EFI_FAT_BOOT_SECTOR *Bpb,
  265. IN UINTN BlockSize
  266. )
  267. {
  268. UINT32 BlockSize32;
  269. BOOLEAN IsFat;
  270. UINT32 RootSize;
  271. UINT32 RootLba;
  272. UINT32 FirstClusterLba;
  273. UINT32 MaxCluster;
  274. UINT32 Sectors;
  275. FAT_VOLUME_TYPE FatType;
  276. BlockSize32 = (UINT32)BlockSize;
  277. if (Bpb->Fat.SectorsPerFat == 0) {
  278. FatType = FAT32;
  279. } else {
  280. FatType = FatUndefined;
  281. }
  282. IsFat = TRUE;
  283. if (Bpb->Fat.Ia32Jump[0] != 0xe9 &&
  284. Bpb->Fat.Ia32Jump[0] != 0xeb &&
  285. Bpb->Fat.Ia32Jump[0] != 0x49) {
  286. IsFat = FALSE;
  287. }
  288. Sectors = (Bpb->Fat.Sectors == 0) ? Bpb->Fat.LargeSectors : Bpb->Fat.Sectors;
  289. if (Bpb->Fat.SectorSize != BlockSize32 ||
  290. Bpb->Fat.ReservedSectors == 0 ||
  291. Bpb->Fat.NoFats == 0 ||
  292. Sectors == 0 ) {
  293. IsFat = FALSE;
  294. }
  295. if (Bpb->Fat.SectorsPerCluster != 1 &&
  296. Bpb->Fat.SectorsPerCluster != 2 &&
  297. Bpb->Fat.SectorsPerCluster != 4 &&
  298. Bpb->Fat.SectorsPerCluster != 8 &&
  299. Bpb->Fat.SectorsPerCluster != 16 &&
  300. Bpb->Fat.SectorsPerCluster != 32 &&
  301. Bpb->Fat.SectorsPerCluster != 64 &&
  302. Bpb->Fat.SectorsPerCluster != 128) {
  303. IsFat = FALSE;
  304. }
  305. if (FatType == FAT32 && (Bpb->Fat32.LargeSectorsPerFat == 0 || Bpb->Fat32.FsVersion != 0)) {
  306. IsFat = FALSE;
  307. }
  308. if (Bpb->Fat.Media != 0xf0 &&
  309. Bpb->Fat.Media != 0xf8 &&
  310. Bpb->Fat.Media != 0xf9 &&
  311. Bpb->Fat.Media != 0xfb &&
  312. Bpb->Fat.Media != 0xfc &&
  313. Bpb->Fat.Media != 0xfd &&
  314. Bpb->Fat.Media != 0xfe &&
  315. Bpb->Fat.Media != 0xff &&
  316. /* FujitsuFMR */
  317. Bpb->Fat.Media != 0x00 &&
  318. Bpb->Fat.Media != 0x01 &&
  319. Bpb->Fat.Media != 0xfa) {
  320. IsFat = FALSE;
  321. }
  322. if (FatType != FAT32 && Bpb->Fat.RootEntries == 0) {
  323. IsFat = FALSE;
  324. }
  325. /* If this is fat32, refuse to mount mirror-disabled volumes */
  326. if (FatType == FAT32 && (Bpb->Fat32.ExtendedFlags & 0x80)) {
  327. IsFat = FALSE;
  328. }
  329. if (FatType != FAT32) {
  330. RootSize = Bpb->Fat.RootEntries * sizeof(FAT_DIRECTORY_ENTRY);
  331. RootLba = Bpb->Fat.NoFats * Bpb->Fat.SectorsPerFat + Bpb->Fat.ReservedSectors;
  332. FirstClusterLba = RootLba + (RootSize / Bpb->Fat.SectorSize);
  333. MaxCluster = (Bpb->Fat.Sectors - FirstClusterLba) / Bpb->Fat.SectorsPerCluster;
  334. FatType = (MaxCluster + 1) < 4087 ? FAT12 : FAT16;
  335. }
  336. return (IsFat ? FatType : FatUndefined);
  337. }
  338. VOID
  339. DumpBpb (
  340. IN FAT_VOLUME_TYPE FatType,
  341. IN EFI_FAT_BOOT_SECTOR *Bpb,
  342. IN UINTN BlockSize
  343. )
  344. {
  345. UINT32 Sectors;
  346. Sectors = (Bpb->Fat.Sectors == 0) ? Bpb->Fat.LargeSectors : Bpb->Fat.Sectors;
  347. Print (L"%HFat %d%N BPB ", FatNumber[FatType]);
  348. if (FatType == FAT32) {
  349. Print (L"FatLabel: '%.*a' SystemId: '%.*a' OemId: '%.*a'\n",
  350. sizeof(Bpb->Fat32.FatLabel), Bpb->Fat32.FatLabel,
  351. sizeof(Bpb->Fat32.SystemId), Bpb->Fat32.SystemId,
  352. sizeof(Bpb->Fat32.OemId), Bpb->Fat32.OemId
  353. );
  354. } else {
  355. Print (L"FatLabel: '%.*a' SystemId: '%.*a' OemId: '%.*a'\n",
  356. sizeof(Bpb->Fat.FatLabel), Bpb->Fat.FatLabel,
  357. sizeof(Bpb->Fat.SystemId), Bpb->Fat.SystemId,
  358. sizeof(Bpb->Fat.OemId), Bpb->Fat.OemId
  359. );
  360. }
  361. Print (L" SectorSize 0x%x SectorsPerCluster %d", Bpb->Fat.SectorSize, Bpb->Fat.SectorsPerCluster);
  362. Print (L" ReservedSectors %d # Fats %d\n Root Entries 0x%x Media 0x%x", Bpb->Fat.ReservedSectors, Bpb->Fat.NoFats, Bpb->Fat.RootEntries, Bpb->Fat.Media);
  363. if (FatType == FAT32) {
  364. Print (L" Sectors 0x%x SectorsPerFat 0x%x\n", Sectors, Bpb->Fat32.LargeSectorsPerFat);
  365. } else {
  366. Print (L" Sectors 0x%x SectorsPerFat 0x%x\n", Sectors, Bpb->Fat.SectorsPerFat);
  367. }
  368. Print (L" SectorsPerTrack 0x%x Heads %d\n", Bpb->Fat.SectorsPerTrack, Bpb->Fat.Heads);
  369. }