windows-nt/Source/XPSP1/NT/base/efiutil/sdk/shell/debug/efidump.c

434 lines
12 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1999 Intel Corporation
Module Name:
EfiDump.c
Abstract:
Dump out info about EFI structs
Revision History
--*/
#include "shelle.h"
#include "fat.h"
typedef union {
FAT_BOOT_SECTOR Fat;
FAT_BOOT_SECTOR_EX Fat32;
} EFI_FAT_BOOT_SECTOR;
FAT_VOLUME_TYPE
ValidBPB (
IN EFI_FAT_BOOT_SECTOR *Bpb,
IN UINTN BlockSize
);
VOID
DumpBpb (
IN FAT_VOLUME_TYPE FatType,
IN EFI_FAT_BOOT_SECTOR *Bpb,
IN UINTN BlockSize
);
typedef union {
VOID *RawData;
UINT8 *PtrMath;
EFI_TABLE_HEADER *Hdr;
EFI_PARTITION_HEADER *Partition;
EFI_SYSTEM_TABLE *Sys;
EFI_RUNTIME_SERVICES *RT;
EFI_BOOT_SERVICES *BS;
} EFI_TABLE_HEADER_PTR;
VOID
EFIFileAttributePrint (
IN UINT64 Attrib
);
CHAR16 *
EFIClassString (
IN UINT32 Class
);
BOOLEAN
IsValidEfiHeader (
IN UINTN BlockSize,
IN EFI_TABLE_HEADER_PTR Hdr
);
VOID
EFITableHeaderPrint (
IN VOID *Buffer,
IN UINTN ByteSize,
IN UINT64 BlockAddress,
IN BOOLEAN IsBlkDevice
);
VOID
DumpGenericHeader (
IN EFI_TABLE_HEADER_PTR Tbl
);
VOID
DumpPartition (
IN EFI_TABLE_HEADER_PTR Tbl
);
VOID
DumpFileHeader (
IN EFI_TABLE_HEADER_PTR Tbl
);
VOID
DumpSystemTable (
IN EFI_TABLE_HEADER_PTR Tbl
);
UINT8 FatNumber[] = { 12, 16, 32, 0 };
VOID
EFIStructsPrint (
IN VOID *Buffer,
IN UINTN BlockSize,
IN UINT64 BlockAddress,
IN EFI_BLOCK_IO *BlkIo
)
{
MASTER_BOOT_RECORD *Mbr;
INTN i;
BOOLEAN IsBlkDevice;
FAT_VOLUME_TYPE FatType;
Print (L"\n");
Mbr = NULL;
if (BlockAddress == 0 && BlkIo != NULL) {
Mbr = (MASTER_BOOT_RECORD *)Buffer;
if (ValidMBR (Mbr, BlkIo)) {
Print (L" Valid MBR\n ---------\n");
for (i=0; i<MAX_MBR_PARTITIONS; i++) {
Print (L" Partition %d OS %02x Start 0x%08x Size 0x%08x\n",
i,
Mbr->Partition[i].OSIndicator,
EXTRACT_UINT32(Mbr->Partition[i].StartingLBA),
EXTRACT_UINT32(Mbr->Partition[i].SizeInLBA)
);
}
} else if ((FatType = ValidBPB ((EFI_FAT_BOOT_SECTOR*) Buffer, BlockSize)) != FatUndefined) {
DumpBpb (FatType, (EFI_FAT_BOOT_SECTOR*) Buffer, BlockSize);
}
}
if (!Mbr) {
IsBlkDevice = (BlkIo != NULL);
EFITableHeaderPrint (Buffer, BlockSize, BlockAddress, IsBlkDevice);
}
}
typedef
VOID
(*EFI_DUMP_HEADER) (
IN EFI_TABLE_HEADER_PTR Tbl
);
typedef struct {
UINT64 Signature;
CHAR16 *String;
EFI_DUMP_HEADER Func;
} TABLE_HEADER_INFO;
TABLE_HEADER_INFO TableHeader[] = {
EFI_PARTITION_SIGNATURE, L"Partition", DumpPartition,
EFI_SYSTEM_TABLE_SIGNATURE, L"System", DumpSystemTable,
EFI_BOOT_SERVICES_SIGNATURE, L"Boot Services", DumpGenericHeader,
EFI_RUNTIME_SERVICES_SIGNATURE, L"Runtime Services", DumpGenericHeader,
0x00, L"", DumpGenericHeader
};
VOID
EFITableHeaderPrint (
IN VOID *Buffer,
IN UINTN ByteSize,
IN UINT64 BlockAddress,
IN BOOLEAN IsBlkDevice
)
{
EFI_TABLE_HEADER_PTR Hdr;
INTN i;
Hdr.RawData = Buffer;
if (IsValidEfiHeader (ByteSize, Hdr)) {
for (i=0; TableHeader[i].Signature != 0x00; i++) {
if (TableHeader[i].Signature == Hdr.Hdr->Signature) {
Print (L" Valid EFI Header at %a %016lx\n ----------------------------------------%a\n",
(IsBlkDevice ? "LBA":"Address"),
BlockAddress,
(IsBlkDevice ? "":"----")
);
Print (L" %H%s: Table Structure%N size %08x revision %08x\n", TableHeader[i].String, Hdr.Hdr->HeaderSize, Hdr.Hdr->Revision);
TableHeader[i].Func (Hdr);
return;
}
}
/*
* Dump the Generic Header, since we don't know the type
*/
TableHeader[i].Func (Hdr);
}
}
BOOLEAN
IsValidEfiHeader (
IN UINTN BlockSize,
IN EFI_TABLE_HEADER_PTR Hdr
)
{
if (Hdr.Hdr->HeaderSize == 0x00) {
return FALSE;
}
if (Hdr.Hdr->HeaderSize > BlockSize) {
return FALSE;
}
return TRUE;
}
VOID
DumpGenericHeader (
IN EFI_TABLE_HEADER_PTR Tbl
)
{
Print (L" Header 0x%016lx Revision 0x%08x Size 0x%08x CRC 0x%08x\n",
Tbl.Hdr->Signature,
Tbl.Hdr->Revision,
Tbl.Hdr->HeaderSize,
Tbl.Hdr->CRC32
);
}
VOID
DumpPartition (
IN EFI_TABLE_HEADER_PTR Tbl
)
{
Print (L" LBA's 0x%016lx - 0x%016lx Unusable (0x%016lx)\n",
Tbl.Partition->FirstUsableLba,
Tbl.Partition->LastUsableLba,
Tbl.Partition->UnusableSpace
);
Print (L" Free Space LBA 0x%016lx Root LBA 0x%016lx\n",
Tbl.Partition->FreeSpace,
Tbl.Partition->RootFile
);
Print (L" Block Size 0x%08x Dir Allocation Units 0x%08x\n",
Tbl.Partition->BlockSize,
Tbl.Partition->DirectoryAllocationNumber
);
}
CHAR16 *
EFIClassString (
IN UINT32 Class
)
{
switch (Class) {
case EFI_FILE_CLASS_FREE_SPACE:
return L"Free Space";
case EFI_FILE_CLASS_EMPTY:
return L"Empty";
case EFI_FILE_CLASS_NORMAL:
return L"Nornal";
default:
return L"Invalid";
}
}
VOID
DumpSystemTable (
IN EFI_TABLE_HEADER_PTR Tbl
)
{
EFI_STATUS Status;
EFI_DEVICE_PATH *DevicePath;
VOID *AcpiTable = NULL;
VOID *SMBIOSTable = NULL;
VOID *SalSystemTable = NULL;
VOID *MpsTable = NULL;
Print (L" ConIn (0x%08x) ConOut (0x%08x) StdErr (0x%08x)\n",
Tbl.Sys->ConsoleInHandle,
Tbl.Sys->ConsoleOutHandle,
Tbl.Sys->StandardErrorHandle
);
Status = BS->HandleProtocol (Tbl.Sys->ConsoleInHandle, &DevicePathProtocol, (VOID*)&DevicePath);
if (Status == EFI_SUCCESS && DevicePath) {
Print (L" Console In on %s\n", DevicePathToStr (DevicePath));
}
Status = BS->HandleProtocol (Tbl.Sys->ConsoleOutHandle, &DevicePathProtocol, (VOID*)&DevicePath);
if (Status == EFI_SUCCESS && DevicePath) {
Print (L" Console Out on %s\n", DevicePathToStr (DevicePath));
}
Status = BS->HandleProtocol (Tbl.Sys->StandardErrorHandle, &DevicePathProtocol, (VOID*)&DevicePath);
if (Status == EFI_SUCCESS && DevicePath) {
Print (L" Std Error on %s\n", DevicePathToStr (DevicePath));
}
Print (L" Runtime Services 0x%016lx\n", (UINT64)Tbl.Sys->RuntimeServices);
Print (L" Boot Services 0x%016lx\n", (UINT64)Tbl.Sys->BootServices);
Status = LibGetSystemConfigurationTable(&SalSystemTableGuid, &SalSystemTable);
if (!EFI_ERROR(Status)) {
Print (L" SAL System Table 0x%016lx\n", (UINT64)SalSystemTable);
}
Status = LibGetSystemConfigurationTable(&AcpiTableGuid, &AcpiTable);
if (!EFI_ERROR(Status)) {
Print (L" ACPI Table 0x%016lx\n", (UINT64)AcpiTable);
}
Status = LibGetSystemConfigurationTable(&MpsTableGuid, &MpsTable);
if (!EFI_ERROR(Status)) {
Print (L" MPS Table 0x%016lx\n", (UINT64)MpsTable);
}
Status = LibGetSystemConfigurationTable(&SMBIOSTableGuid, &SMBIOSTable);
if (!EFI_ERROR(Status)) {
Print (L" SMBIOS Table 0x%016lx\n", (UINT64)SMBIOSTable);
}
}
FAT_VOLUME_TYPE
ValidBPB (
IN EFI_FAT_BOOT_SECTOR *Bpb,
IN UINTN BlockSize
)
{
UINT32 BlockSize32;
BOOLEAN IsFat;
UINT32 RootSize;
UINT32 RootLba;
UINT32 FirstClusterLba;
UINT32 MaxCluster;
UINT32 Sectors;
FAT_VOLUME_TYPE FatType;
BlockSize32 = (UINT32)BlockSize;
if (Bpb->Fat.SectorsPerFat == 0) {
FatType = FAT32;
} else {
FatType = FatUndefined;
}
IsFat = TRUE;
if (Bpb->Fat.Ia32Jump[0] != 0xe9 &&
Bpb->Fat.Ia32Jump[0] != 0xeb &&
Bpb->Fat.Ia32Jump[0] != 0x49) {
IsFat = FALSE;
}
Sectors = (Bpb->Fat.Sectors == 0) ? Bpb->Fat.LargeSectors : Bpb->Fat.Sectors;
if (Bpb->Fat.SectorSize != BlockSize32 ||
Bpb->Fat.ReservedSectors == 0 ||
Bpb->Fat.NoFats == 0 ||
Sectors == 0 ) {
IsFat = FALSE;
}
if (Bpb->Fat.SectorsPerCluster != 1 &&
Bpb->Fat.SectorsPerCluster != 2 &&
Bpb->Fat.SectorsPerCluster != 4 &&
Bpb->Fat.SectorsPerCluster != 8 &&
Bpb->Fat.SectorsPerCluster != 16 &&
Bpb->Fat.SectorsPerCluster != 32 &&
Bpb->Fat.SectorsPerCluster != 64 &&
Bpb->Fat.SectorsPerCluster != 128) {
IsFat = FALSE;
}
if (FatType == FAT32 && (Bpb->Fat32.LargeSectorsPerFat == 0 || Bpb->Fat32.FsVersion != 0)) {
IsFat = FALSE;
}
if (Bpb->Fat.Media != 0xf0 &&
Bpb->Fat.Media != 0xf8 &&
Bpb->Fat.Media != 0xf9 &&
Bpb->Fat.Media != 0xfb &&
Bpb->Fat.Media != 0xfc &&
Bpb->Fat.Media != 0xfd &&
Bpb->Fat.Media != 0xfe &&
Bpb->Fat.Media != 0xff &&
/* FujitsuFMR */
Bpb->Fat.Media != 0x00 &&
Bpb->Fat.Media != 0x01 &&
Bpb->Fat.Media != 0xfa) {
IsFat = FALSE;
}
if (FatType != FAT32 && Bpb->Fat.RootEntries == 0) {
IsFat = FALSE;
}
/* If this is fat32, refuse to mount mirror-disabled volumes */
if (FatType == FAT32 && (Bpb->Fat32.ExtendedFlags & 0x80)) {
IsFat = FALSE;
}
if (FatType != FAT32) {
RootSize = Bpb->Fat.RootEntries * sizeof(FAT_DIRECTORY_ENTRY);
RootLba = Bpb->Fat.NoFats * Bpb->Fat.SectorsPerFat + Bpb->Fat.ReservedSectors;
FirstClusterLba = RootLba + (RootSize / Bpb->Fat.SectorSize);
MaxCluster = (Bpb->Fat.Sectors - FirstClusterLba) / Bpb->Fat.SectorsPerCluster;
FatType = (MaxCluster + 1) < 4087 ? FAT12 : FAT16;
}
return (IsFat ? FatType : FatUndefined);
}
VOID
DumpBpb (
IN FAT_VOLUME_TYPE FatType,
IN EFI_FAT_BOOT_SECTOR *Bpb,
IN UINTN BlockSize
)
{
UINT32 Sectors;
Sectors = (Bpb->Fat.Sectors == 0) ? Bpb->Fat.LargeSectors : Bpb->Fat.Sectors;
Print (L"%HFat %d%N BPB ", FatNumber[FatType]);
if (FatType == FAT32) {
Print (L"FatLabel: '%.*a' SystemId: '%.*a' OemId: '%.*a'\n",
sizeof(Bpb->Fat32.FatLabel), Bpb->Fat32.FatLabel,
sizeof(Bpb->Fat32.SystemId), Bpb->Fat32.SystemId,
sizeof(Bpb->Fat32.OemId), Bpb->Fat32.OemId
);
} else {
Print (L"FatLabel: '%.*a' SystemId: '%.*a' OemId: '%.*a'\n",
sizeof(Bpb->Fat.FatLabel), Bpb->Fat.FatLabel,
sizeof(Bpb->Fat.SystemId), Bpb->Fat.SystemId,
sizeof(Bpb->Fat.OemId), Bpb->Fat.OemId
);
}
Print (L" SectorSize 0x%x SectorsPerCluster %d", Bpb->Fat.SectorSize, Bpb->Fat.SectorsPerCluster);
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);
if (FatType == FAT32) {
Print (L" Sectors 0x%x SectorsPerFat 0x%x\n", Sectors, Bpb->Fat32.LargeSectorsPerFat);
} else {
Print (L" Sectors 0x%x SectorsPerFat 0x%x\n", Sectors, Bpb->Fat.SectorsPerFat);
}
Print (L" SectorsPerTrack 0x%x Heads %d\n", Bpb->Fat.SectorsPerTrack, Bpb->Fat.Heads);
}