X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=EdkCompatibilityPkg%2FSample%2FTools%2FSource%2FBootsectImage%2Fbootsectimage.c;fp=EdkCompatibilityPkg%2FSample%2FTools%2FSource%2FBootsectImage%2Fbootsectimage.c;h=d71a03df0ba92cf862061b42cca904c359917349;hp=0000000000000000000000000000000000000000;hb=3eb9473ea9a949badfe06ae61d2d3fcfa53651c7;hpb=30d4a0c7ec19938196b1308006b990e0945150da diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/bootsectimage.c b/EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/bootsectimage.c new file mode 100644 index 0000000000..d71a03df0b --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Tools/Source/BootsectImage/bootsectimage.c @@ -0,0 +1,881 @@ +/*++ + +Copyright 2006 - 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + bootsectimage.c + +Abstract: + Patch the BPB information in boot sector image file. + Patch the MBR code in MBR image file. + +--*/ + + +#include +#include +#include "fat.h" +#include "mbr.h" +#include "EfiUtilityMsgs.h" + +#define DEBUG_WARN 0x1 +#define DEBUG_ERROR 0x2 +int WriteToFile ( + void *BootSector, + char *FileName + ) +/*++ +Routine Description: + Write 512 bytes boot sector to file. + +Arguments: + BootSector - point to a buffer containing 512 bytes boot sector to write + FileName - file to write to + +Return: + int - number of bytes wrote, + 512 indicates write successful + 0 indicates write failure +--*/ +{ + FILE *FileHandle; + int result; + + FileHandle = fopen (FileName, "r+b"); + if (FileHandle == NULL) { + DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "Open file: %s", FileName); + return 0; + } + fseek (FileHandle, 0, SEEK_SET); + + result = fwrite (BootSector, 1, 512, FileHandle); + if (result != 512) { + DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "Write file: %s", FileName); + result = 0; + } + + fclose (FileHandle); + return result; +} + +int ReadFromFile ( + void *BootSector, + char *FileName + ) +/*++ +Routine Description: + Read first 512 bytes from file. + +Arguments: + BootSector - point to a buffer receiving the first 512 bytes data from file + FileName - file to read from + +Return: + int - number of bytes read, + 512 indicates read successful + 0 indicates read failure +--*/ +{ + FILE *FileHandle; + int result; + + FileHandle = fopen (FileName, "rb"); + if (FileHandle == NULL) { + DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "Open file: %s", FileName); + return 0; + } + + result = fread (BootSector, 1, 512, FileHandle); + if (result != 512) { + DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "Read file: %s", FileName); + result = 0; + } + + fclose (FileHandle); + return result; +} + +char * +FatTypeToString ( + IN FAT_TYPE FatType + ) +/*++ +Routine Description: + Convert enum type of FatType to string +--*/ +{ + switch (FatType) { + case FatTypeFat12: + return "FAT12"; + case FatTypeFat16: + return "FAT16"; + case FatTypeFat32: + return "FAT32"; + default: + break; + } + return "FAT Unknown"; +} + +FAT_TYPE +GetFatType ( + IN FAT_BPB_STRUCT *FatBpb + ) +/*++ +Routine Description: + Determine the FAT type according to BIOS Paramater Block (BPB) data + +Arguments: + FatBpb - BIOS Parameter Block (BPB) data, 512 Bytes + +Return: + FatTypeUnknown - Cannot determine the FAT type + FatTypeFat12 - FAT12 + FatTypeFat16 - FAT16 + FatTypeFat32 - FAT32 +--*/ +{ + FAT_TYPE FatType; + UINTN RootDirSectors; + UINTN FATSz; + UINTN TotSec; + UINTN DataSec; + UINTN CountOfClusters; + CHAR8 FilSysType[9]; + + FatType = FatTypeUnknown; + + // + // Simple check + // + if (FatBpb->Fat12_16.Signature != FAT_BS_SIGNATURE) { + DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: Signature Invalid - %04x, expected - %04x", + FatBpb->Fat12_16.Signature, FAT_BS_SIGNATURE); + return FatTypeUnknown; + } + + // + // Check according to FAT spec + // + if ((FatBpb->Fat12_16.BS_jmpBoot[0] != FAT_BS_JMP1) && + (FatBpb->Fat12_16.BS_jmpBoot[0] != FAT_BS_JMP2)) { + DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BS_jmpBoot - %02x, expected - %02x or %02x", + FatBpb->Fat12_16.BS_jmpBoot[0], FAT_BS_JMP1, FAT_BS_JMP2); + return FatTypeUnknown; + } + + if ((FatBpb->Fat12_16.BPB_BytsPerSec != 512) && + (FatBpb->Fat12_16.BPB_BytsPerSec != 1024) && + (FatBpb->Fat12_16.BPB_BytsPerSec != 2048) && + (FatBpb->Fat12_16.BPB_BytsPerSec != 4096)) { + DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_BytsPerSec - %04x, expected - %04x, %04x, %04x, or %04x", + FatBpb->Fat12_16.BPB_BytsPerSec, 512, 1024, 2048, 4096); + return FatTypeUnknown; + } + if (FatBpb->Fat12_16.BPB_BytsPerSec != 512) { + DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT: BPB_BytsPerSec - %04x, expected - %04x", + FatBpb->Fat12_16.BPB_BytsPerSec, 512); + } + if ((FatBpb->Fat12_16.BPB_SecPerClus != 1) && + (FatBpb->Fat12_16.BPB_SecPerClus != 2) && + (FatBpb->Fat12_16.BPB_SecPerClus != 4) && + (FatBpb->Fat12_16.BPB_SecPerClus != 8) && + (FatBpb->Fat12_16.BPB_SecPerClus != 16) && + (FatBpb->Fat12_16.BPB_SecPerClus != 32) && + (FatBpb->Fat12_16.BPB_SecPerClus != 64) && + (FatBpb->Fat12_16.BPB_SecPerClus != 128)) { + DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_SecPerClus - %02x, expected - %02x, %02x, %02x, %02x, %02x, %02x, %02x, or %02x", + FatBpb->Fat12_16.BPB_BytsPerSec, 1, 2, 4, 8, 16, 32, 64, 128); + return FatTypeUnknown; + } + if (FatBpb->Fat12_16.BPB_BytsPerSec * FatBpb->Fat12_16.BPB_SecPerClus > 32 * 1024) { + DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_BytsPerSec * BPB_SecPerClus - %08x, expected <= %08x", + FatBpb->Fat12_16.BPB_BytsPerSec * FatBpb->Fat12_16.BPB_SecPerClus, 32 * 1024); + return FatTypeUnknown; + } + if (FatBpb->Fat12_16.BPB_RsvdSecCnt == 0) { + DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_RsvdSecCnt - %04x, expected - Non-Zero", + FatBpb->Fat12_16.BPB_RsvdSecCnt); + return FatTypeUnknown; + } + if (FatBpb->Fat12_16.BPB_NumFATs != 2) { + DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT: BPB_NumFATs - %02x, expected - %02x", + FatBpb->Fat12_16.BPB_NumFATs, 2); + } + if ((FatBpb->Fat12_16.BPB_Media != 0xF0) && + (FatBpb->Fat12_16.BPB_Media != 0xF8) && + (FatBpb->Fat12_16.BPB_Media != 0xF9) && + (FatBpb->Fat12_16.BPB_Media != 0xFA) && + (FatBpb->Fat12_16.BPB_Media != 0xFB) && + (FatBpb->Fat12_16.BPB_Media != 0xFC) && + (FatBpb->Fat12_16.BPB_Media != 0xFD) && + (FatBpb->Fat12_16.BPB_Media != 0xFE) && + (FatBpb->Fat12_16.BPB_Media != 0xFF)) { + DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_Media - %02x, expected - %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, or %02x", + FatBpb->Fat12_16.BPB_Media, 0xF0, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF); + return FatTypeUnknown; + } + + // + // Algo in FAT spec + // + RootDirSectors = ((FatBpb->Fat12_16.BPB_RootEntCnt * sizeof(FAT_DIRECTORY_ENTRY)) + + (FatBpb->Fat12_16.BPB_BytsPerSec - 1)) / + FatBpb->Fat12_16.BPB_BytsPerSec; + + if (FatBpb->Fat12_16.BPB_FATSz16 != 0) { + FATSz = FatBpb->Fat12_16.BPB_FATSz16; + } else { + FATSz = FatBpb->Fat32.BPB_FATSz32; + } + if (FATSz == 0) { + DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_FATSz16, BPB_FATSz32 - 0, expected - Non-Zero"); + return FatTypeUnknown; + } + + if (FatBpb->Fat12_16.BPB_TotSec16 != 0) { + TotSec = FatBpb->Fat12_16.BPB_TotSec16; + } else { + TotSec = FatBpb->Fat12_16.BPB_TotSec32; + } + if (TotSec == 0) { + DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT: BPB_TotSec16, BPB_TotSec32 - 0, expected - Non-Zero"); + return FatTypeUnknown; + } + + DataSec = TotSec - ( + FatBpb->Fat12_16.BPB_RsvdSecCnt + + FatBpb->Fat12_16.BPB_NumFATs * FATSz + + RootDirSectors + ); + + CountOfClusters = DataSec / FatBpb->Fat12_16.BPB_SecPerClus; + + if (CountOfClusters < FAT_MAX_FAT12_CLUSTER) { + FatType = FatTypeFat12; + } else if (CountOfClusters < FAT_MAX_FAT16_CLUSTER) { + FatType = FatTypeFat16; + } else { + FatType = FatTypeFat32; + } + // + // Check according to FAT spec + // + if (((FatType == FatTypeFat12) || (FatType == FatTypeFat16)) && + (FatBpb->Fat12_16.BPB_RsvdSecCnt != 1)) { + DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT12_16: BPB_RsvdSecCnt - %04x, expected - %04x", + FatBpb->Fat12_16.BPB_RsvdSecCnt, 1); + } + if ((FatType == FatTypeFat32) && + (FatBpb->Fat12_16.BPB_RsvdSecCnt != 32)) { + DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT32: BPB_RsvdSecCnt - %04x, expected - %04x", + FatBpb->Fat12_16.BPB_RsvdSecCnt, 32); + } + if ((FatType == FatTypeFat16) && + (FatBpb->Fat12_16.BPB_RootEntCnt != 512)) { + printf ("WARNING: FAT16: BPB_RootEntCnt - %04x, expected - %04x\n", + FatBpb->Fat12_16.BPB_RootEntCnt, 512); + } + if ((FatType == FatTypeFat32) && + (FatBpb->Fat12_16.BPB_RootEntCnt != 0)) { + DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BPB_RootEntCnt - %04x, expected - %04x", + FatBpb->Fat12_16.BPB_RootEntCnt, 0); + return FatTypeUnknown; + } + if ((FatType == FatTypeFat32) && + (FatBpb->Fat12_16.BPB_TotSec16 != 0)) { + DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BPB_TotSec16 - %04x, expected - %04x", + FatBpb->Fat12_16.BPB_TotSec16, 0); + return FatTypeUnknown; + } + if ((FatType == FatTypeFat32) && + (FatBpb->Fat12_16.BPB_FATSz16 != 0)) { + DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BPB_FATSz16 - %04x, expected - %04x", + FatBpb->Fat12_16.BPB_FATSz16, 0); + return FatTypeUnknown; + } + if ((FatType == FatTypeFat32) && + (FatBpb->Fat12_16.BPB_TotSec32 == 0)) { + DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BPB_TotSec32 - %04x, expected - Non-Zero", + FatBpb->Fat12_16.BPB_TotSec32); + return FatTypeUnknown; + } + if ((FatType == FatTypeFat32) && + (FatBpb->Fat32.BPB_FATSz32 == 0)) { + DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BPB_FATSz32 - %08x, expected - Non-Zero", + FatBpb->Fat32.BPB_FATSz32); + return FatTypeUnknown; + } + if ((FatType == FatTypeFat32) && + (FatBpb->Fat32.BPB_FSVer != 0)) { + DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT32: BPB_FSVer - %08x, expected - %04x", + FatBpb->Fat32.BPB_FSVer, 0); + } + if ((FatType == FatTypeFat32) && + (FatBpb->Fat32.BPB_RootClus != 2)) { + DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT32: BPB_RootClus - %08x, expected - %04x", + FatBpb->Fat32.BPB_RootClus, 2); + } + if ((FatType == FatTypeFat32) && + (FatBpb->Fat32.BPB_FSInfo != 1)) { + DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT32: BPB_FSInfo - %08x, expected - %04x", + FatBpb->Fat32.BPB_FSInfo, 1); + } + if ((FatType == FatTypeFat32) && + (FatBpb->Fat32.BPB_BkBootSec != 6)) { + DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT32: BPB_BkBootSec - %08x, expected - %04x", + FatBpb->Fat32.BPB_BkBootSec, 6); + } + if ((FatType == FatTypeFat32) && + ((*(UINT32 *)FatBpb->Fat32.BPB_Reserved != 0) || + (*((UINT32 *)FatBpb->Fat32.BPB_Reserved + 1) != 0) || + (*((UINT32 *)FatBpb->Fat32.BPB_Reserved + 2) != 0))) { + DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BPB_Reserved - %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x, expected - 0", + FatBpb->Fat32.BPB_Reserved[0], + FatBpb->Fat32.BPB_Reserved[1], + FatBpb->Fat32.BPB_Reserved[2], + FatBpb->Fat32.BPB_Reserved[3], + FatBpb->Fat32.BPB_Reserved[4], + FatBpb->Fat32.BPB_Reserved[5], + FatBpb->Fat32.BPB_Reserved[6], + FatBpb->Fat32.BPB_Reserved[7], + FatBpb->Fat32.BPB_Reserved[8], + FatBpb->Fat32.BPB_Reserved[9], + FatBpb->Fat32.BPB_Reserved[10], + FatBpb->Fat32.BPB_Reserved[11]); + return FatTypeUnknown; + } + if (((FatType == FatTypeFat12) || (FatType == FatTypeFat16)) && + (FatBpb->Fat12_16.BS_Reserved1 != 0)) { + DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT12_16: BS_Reserved1 - %02x, expected - 0\n", + FatBpb->Fat12_16.BS_Reserved1); + return FatTypeUnknown; + } + if ((FatType == FatTypeFat32) && + (FatBpb->Fat32.BS_Reserved1 != 0)) { + DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BS_Reserved1 - %02x, expected - 0\n", + FatBpb->Fat32.BS_Reserved1); + return FatTypeUnknown; + } + if (((FatType == FatTypeFat12) || (FatType == FatTypeFat16)) && + (FatBpb->Fat12_16.BS_BootSig != FAT_BS_BOOTSIG)) { + DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT12_16: BS_BootSig - %02x, expected - %02x\n", + FatBpb->Fat12_16.BS_BootSig, FAT_BS_BOOTSIG); + return FatTypeUnknown; + } + if ((FatType == FatTypeFat32) && + (FatBpb->Fat32.BS_BootSig != FAT_BS_BOOTSIG)) { + DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT32: BS_BootSig - %02x, expected - %02x\n", + FatBpb->Fat32.BS_BootSig, FAT_BS_BOOTSIG); + return FatTypeUnknown; + } + + if ((FatType == FatTypeFat12) || (FatType == FatTypeFat16)) { + memcpy (FilSysType, FatBpb->Fat12_16.BS_FilSysType, 8); + FilSysType[8] = 0; + if ((FatType == FatTypeFat12) && + (strcmp (FilSysType, FAT12_FILSYSTYPE) != 0) && + (strcmp (FilSysType, FAT_FILSYSTYPE) != 0)) { + DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT12: BS_FilSysType - %s, expected - %s, or %s\n", + FilSysType, FAT12_FILSYSTYPE, FAT_FILSYSTYPE); + } + if ((FatType == FatTypeFat16) && + (strcmp (FilSysType, FAT16_FILSYSTYPE) != 0) && + (strcmp (FilSysType, FAT_FILSYSTYPE) != 0)) { + DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT16: BS_FilSysType - %s, expected - %s, or %s\n", + FilSysType, FAT16_FILSYSTYPE, FAT_FILSYSTYPE); + } + } + if (FatType == FatTypeFat32) { + memcpy (FilSysType, FatBpb->Fat32.BS_FilSysType, 8); + FilSysType[8] = 0; + if (strcmp (FilSysType, FAT32_FILSYSTYPE) != 0) { + DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT32: BS_FilSysType - %s, expected - %s\n", + FilSysType, FAT32_FILSYSTYPE); + } + } + + // + // pass all check, get FAT type + // + return FatType; +} + + +void +ParseBootSector ( + char *FileName + ) +{ + FAT_BPB_STRUCT FatBpb; + FAT_TYPE FatType; + + if (ReadFromFile ((void *)&FatBpb, FileName) == 0) { + return ; + } + + FatType = GetFatType (&FatBpb); + if (FatType <= FatTypeUnknown || FatType >= FatTypeMax) { + printf ("ERROR: Unknown Fat Type!\n"); + return; + } + + printf ("\nBoot Sector %s:\n", FatTypeToString (FatType)); + printf ("\n"); + printf (" Offset Title Data\n"); + printf ("==================================================================\n"); + printf (" 0 JMP instruction %02x %02x %02x\n", + FatBpb.Fat12_16.BS_jmpBoot[0], + FatBpb.Fat12_16.BS_jmpBoot[1], + FatBpb.Fat12_16.BS_jmpBoot[2]); + printf (" 3 OEM %c%c%c%c%c%c%c%c\n", + FatBpb.Fat12_16.BS_OEMName[0], + FatBpb.Fat12_16.BS_OEMName[1], + FatBpb.Fat12_16.BS_OEMName[2], + FatBpb.Fat12_16.BS_OEMName[3], + FatBpb.Fat12_16.BS_OEMName[4], + FatBpb.Fat12_16.BS_OEMName[5], + FatBpb.Fat12_16.BS_OEMName[6], + FatBpb.Fat12_16.BS_OEMName[7]); + printf ("\n"); + printf ("BIOS Parameter Block\n"); + printf (" B Bytes per sector %04x\n", FatBpb.Fat12_16.BPB_BytsPerSec); + printf (" D Sectors per cluster %02x\n", FatBpb.Fat12_16.BPB_SecPerClus); + printf (" E Reserved sectors %04x\n", FatBpb.Fat12_16.BPB_RsvdSecCnt); + printf (" 10 Number of FATs %02x\n", FatBpb.Fat12_16.BPB_NumFATs); + printf (" 11 Root entries %04x\n", FatBpb.Fat12_16.BPB_RootEntCnt); + printf (" 13 Sectors (under 32MB) %04x\n", FatBpb.Fat12_16.BPB_TotSec16); + printf (" 15 Media descriptor %02x\n", FatBpb.Fat12_16.BPB_Media); + printf (" 16 Sectors per FAT (small vol.) %04x\n", FatBpb.Fat12_16.BPB_FATSz16); + printf (" 18 Sectors per track %04x\n", FatBpb.Fat12_16.BPB_SecPerTrk); + printf (" 1A Heads %04x\n", FatBpb.Fat12_16.BPB_NumHeads); + printf (" 1C Hidden sectors %08x\n", FatBpb.Fat12_16.BPB_HiddSec); + printf (" 20 Sectors (over 32MB) %08x\n", FatBpb.Fat12_16.BPB_TotSec32); + printf ("\n"); + if (FatType != FatTypeFat32) { + printf (" 24 BIOS drive %02x\n", FatBpb.Fat12_16.BS_DrvNum); + printf (" 25 (Unused) %02x\n", FatBpb.Fat12_16.BS_Reserved1); + printf (" 26 Ext. boot signature %02x\n", FatBpb.Fat12_16.BS_BootSig); + printf (" 27 Volume serial number %08x\n", FatBpb.Fat12_16.BS_VolID); + printf (" 2B Volume lable %c%c%c%c%c%c%c%c%c%c%c\n", + FatBpb.Fat12_16.BS_VolLab[0], + FatBpb.Fat12_16.BS_VolLab[1], + FatBpb.Fat12_16.BS_VolLab[2], + FatBpb.Fat12_16.BS_VolLab[3], + FatBpb.Fat12_16.BS_VolLab[4], + FatBpb.Fat12_16.BS_VolLab[5], + FatBpb.Fat12_16.BS_VolLab[6], + FatBpb.Fat12_16.BS_VolLab[7], + FatBpb.Fat12_16.BS_VolLab[8], + FatBpb.Fat12_16.BS_VolLab[9], + FatBpb.Fat12_16.BS_VolLab[10]); + printf (" 36 File system %c%c%c%c%c%c%c%c\n", + FatBpb.Fat12_16.BS_FilSysType[0], + FatBpb.Fat12_16.BS_FilSysType[1], + FatBpb.Fat12_16.BS_FilSysType[2], + FatBpb.Fat12_16.BS_FilSysType[3], + FatBpb.Fat12_16.BS_FilSysType[4], + FatBpb.Fat12_16.BS_FilSysType[5], + FatBpb.Fat12_16.BS_FilSysType[6], + FatBpb.Fat12_16.BS_FilSysType[7]); + printf ("\n"); + } else { + printf ("FAT32 Section\n"); + printf (" 24 Sectors per FAT (large vol.) %08x\n", FatBpb.Fat32.BPB_FATSz32); + printf (" 28 Flags %04x\n", FatBpb.Fat32.BPB_ExtFlags); + printf (" 2A Version %04x\n", FatBpb.Fat32.BPB_FSVer); + printf (" 2C Root dir 1st cluster %08x\n", FatBpb.Fat32.BPB_RootClus); + printf (" 30 FSInfo sector %04x\n", FatBpb.Fat32.BPB_FSInfo); + printf (" 32 Backup boot sector %04x\n", FatBpb.Fat32.BPB_BkBootSec); + printf (" 34 (Reserved) %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", + FatBpb.Fat32.BPB_Reserved[0], + FatBpb.Fat32.BPB_Reserved[1], + FatBpb.Fat32.BPB_Reserved[2], + FatBpb.Fat32.BPB_Reserved[3], + FatBpb.Fat32.BPB_Reserved[4], + FatBpb.Fat32.BPB_Reserved[5], + FatBpb.Fat32.BPB_Reserved[6], + FatBpb.Fat32.BPB_Reserved[7], + FatBpb.Fat32.BPB_Reserved[8], + FatBpb.Fat32.BPB_Reserved[9], + FatBpb.Fat32.BPB_Reserved[10], + FatBpb.Fat32.BPB_Reserved[11]); + printf ("\n"); + printf (" 40 BIOS drive %02x\n", FatBpb.Fat32.BS_DrvNum); + printf (" 41 (Unused) %02x\n", FatBpb.Fat32.BS_Reserved1); + printf (" 42 Ext. boot signature %02x\n", FatBpb.Fat32.BS_BootSig); + printf (" 43 Volume serial number %08x\n", FatBpb.Fat32.BS_VolID); + printf (" 47 Volume lable %c%c%c%c%c%c%c%c%c%c%c\n", + FatBpb.Fat32.BS_VolLab[0], + FatBpb.Fat32.BS_VolLab[1], + FatBpb.Fat32.BS_VolLab[2], + FatBpb.Fat32.BS_VolLab[3], + FatBpb.Fat32.BS_VolLab[4], + FatBpb.Fat32.BS_VolLab[5], + FatBpb.Fat32.BS_VolLab[6], + FatBpb.Fat32.BS_VolLab[7], + FatBpb.Fat32.BS_VolLab[8], + FatBpb.Fat32.BS_VolLab[9], + FatBpb.Fat32.BS_VolLab[10]); + printf (" 52 File system %c%c%c%c%c%c%c%c\n", + FatBpb.Fat32.BS_FilSysType[0], + FatBpb.Fat32.BS_FilSysType[1], + FatBpb.Fat32.BS_FilSysType[2], + FatBpb.Fat32.BS_FilSysType[3], + FatBpb.Fat32.BS_FilSysType[4], + FatBpb.Fat32.BS_FilSysType[5], + FatBpb.Fat32.BS_FilSysType[6], + FatBpb.Fat32.BS_FilSysType[7]); + printf ("\n"); + } + printf (" 1FE Signature %04x\n", FatBpb.Fat12_16.Signature); + printf ("\n"); + + + return ; +} + +void +PatchBootSector ( + char *DestFileName, + char *SourceFileName, + BOOL ForcePatch + ) +/*++ +Routine Description: + Patch destination file according to the information from source file. + Only patch BPB data but leave boot code un-touched. + +Arguments: + DestFileName - Destination file to patch + SourceFileName - Source file where patch from +--*/ +{ + FAT_BPB_STRUCT DestFatBpb; + FAT_BPB_STRUCT SourceFatBpb; + FAT_TYPE DestFatType; + FAT_TYPE SourceFatType; + CHAR8 VolLab[11]; + CHAR8 FilSysType[8]; + + if (ReadFromFile ((void *)&DestFatBpb, DestFileName) == 0) { + return ; + } + if (ReadFromFile ((void *)&SourceFatBpb, SourceFileName) == 0) { + return ; + } + + DestFatType = GetFatType (&DestFatBpb); + SourceFatType = GetFatType (&SourceFatBpb); + + if (DestFatType != SourceFatType) { + // + // FAT type mismatch + // + if (ForcePatch) { + DebugMsg (NULL, 0, DEBUG_WARN, NULL, "FAT type mismatch: Dest - %s, Source - %s", + FatTypeToString(DestFatType), FatTypeToString(SourceFatType)); + } else { + DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "FAT type mismatch: Dest - %s, Source - %s", + FatTypeToString(DestFatType), FatTypeToString(SourceFatType)); + return ; + } + } + + if (SourceFatType <= FatTypeUnknown || SourceFatType >= FatTypeMax) { + DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "Unknown Fat Type!\n"); + return; + } + + // + // Copy BPB/boot data (excluding BS_jmpBoot, BS_OEMName, BootCode and Signature) from SourceFatBpb to DestFatBpb + // + printf ("Patching %s BPB: ", FatTypeToString (SourceFatType)); + if (SourceFatType != FatTypeFat32) { + memcpy ( + &DestFatBpb.Fat12_16.BPB_BytsPerSec, + &SourceFatBpb.Fat12_16.BPB_BytsPerSec, + ((UINTN)&DestFatBpb.Fat12_16.Reserved - (UINTN)&DestFatBpb.Fat12_16.BPB_BytsPerSec) + ); + } else { + memcpy ( + &DestFatBpb.Fat32.BPB_BytsPerSec, + &SourceFatBpb.Fat32.BPB_BytsPerSec, + ((UINTN)&DestFatBpb.Fat32.Reserved - (UINTN)&DestFatBpb.Fat32.BPB_BytsPerSec) + ); + } + + // + // Set BS_VolLab and BS_FilSysType of DestFatBpb + // + // BS_VolLab BS_FilSysType + // FAT12: EFI FAT12 FAT12 + // FAT16: EFI FAT16 FAT16 + // FAT32: EFI FAT32 FAT32 + // + if (SourceFatType == FatTypeFat32) { + memcpy (VolLab, "EFI FAT32 ", sizeof(VolLab)); + memcpy (FilSysType, FAT32_FILSYSTYPE, sizeof(FilSysType)); + } else if (SourceFatType == FatTypeFat16) { + memcpy (VolLab, "EFI FAT16 ", sizeof(VolLab)); + memcpy (FilSysType, FAT16_FILSYSTYPE, sizeof(FilSysType)); + } else { + memcpy (VolLab, "EFI FAT12 ", sizeof(VolLab)); + memcpy (FilSysType, FAT12_FILSYSTYPE, sizeof(FilSysType)); + } + if (SourceFatType != FatTypeFat32) { + memcpy (DestFatBpb.Fat12_16.BS_VolLab, VolLab, sizeof(VolLab)); + memcpy (DestFatBpb.Fat12_16.BS_FilSysType, FilSysType, sizeof(FilSysType)); + } else { + memcpy (DestFatBpb.Fat32.BS_VolLab, VolLab, sizeof(VolLab)); + memcpy (DestFatBpb.Fat32.BS_FilSysType, FilSysType, sizeof(FilSysType)); + } + + // + // Set Signature of DestFatBpb to 55AA + // + DestFatBpb.Fat12_16.Signature = FAT_BS_SIGNATURE; + + // + // Write DestFatBpb + // + if (WriteToFile ((void *)&DestFatBpb, DestFileName)) { + printf ("successfully!\n"); + } else { + printf ("failed!\n"); + } + + return ; +} + +void +ParseMbr ( + char *FileName + ) +{ + MASTER_BOOT_RECORD Mbr; + + if (ReadFromFile ((void *)&Mbr, FileName) == 0) { + return ; + } + + printf ("\nMaster Boot Record:\n"); + printf ("\n"); + printf (" Offset Title Value\n"); + printf ("==================================================================\n"); + printf (" 0 Master bootstrap loader code (not list)\n"); + printf (" 1B8 Windows disk signature %08x\n", Mbr.UniqueMbrSignature); + printf ("\n"); + printf ("Partition Table Entry #1\n"); + printf (" 1BE 80 = active partition %02x\n", Mbr.PartitionRecord[0].BootIndicator); + printf (" 1BF Start head %02x\n", Mbr.PartitionRecord[0].StartHead); + printf (" 1C0 Start sector %02x\n", Mbr.PartitionRecord[0].StartSector); + printf (" 1C1 Start cylinder %02x\n", Mbr.PartitionRecord[0].StartTrack); + printf (" 1C2 Partition type indicator %02x\n", Mbr.PartitionRecord[0].OSType); + printf (" 1C3 End head %02x\n", Mbr.PartitionRecord[0].EndHead); + printf (" 1C4 End sector %02x\n", Mbr.PartitionRecord[0].EndSector); + printf (" 1C5 End cylinder %02x\n", Mbr.PartitionRecord[0].EndTrack); + printf (" 1C6 Sectors preceding partition %08x\n", Mbr.PartitionRecord[0].StartingLBA); + printf (" 1CA Sectors in partition %08x\n", Mbr.PartitionRecord[0].SizeInLBA); + printf ("\n"); + printf ("Partition Table Entry #2\n"); + printf (" 1CE 80 = active partition %02x\n", Mbr.PartitionRecord[1].BootIndicator); + printf (" 1CF Start head %02x\n", Mbr.PartitionRecord[1].StartHead); + printf (" 1D0 Start sector %02x\n", Mbr.PartitionRecord[1].StartSector); + printf (" 1D1 Start cylinder %02x\n", Mbr.PartitionRecord[1].StartTrack); + printf (" 1D2 Partition type indicator %02x\n", Mbr.PartitionRecord[1].OSType); + printf (" 1D3 End head %02x\n", Mbr.PartitionRecord[1].EndHead); + printf (" 1D4 End sector %02x\n", Mbr.PartitionRecord[1].EndSector); + printf (" 1D5 End cylinder %02x\n", Mbr.PartitionRecord[1].EndTrack); + printf (" 1D6 Sectors preceding partition %08x\n", Mbr.PartitionRecord[1].StartingLBA); + printf (" 1DA Sectors in partition %08x\n", Mbr.PartitionRecord[1].SizeInLBA); + printf ("\n"); + printf ("Partition Table Entry #3\n"); + printf (" 1DE 80 = active partition %02x\n", Mbr.PartitionRecord[2].BootIndicator); + printf (" 1DF Start head %02x\n", Mbr.PartitionRecord[2].StartHead); + printf (" 1E0 Start sector %02x\n", Mbr.PartitionRecord[2].StartSector); + printf (" 1E1 Start cylinder %02x\n", Mbr.PartitionRecord[2].StartTrack); + printf (" 1E2 Partition type indicator %02x\n", Mbr.PartitionRecord[2].OSType); + printf (" 1E3 End head %02x\n", Mbr.PartitionRecord[2].EndHead); + printf (" 1E4 End sector %02x\n", Mbr.PartitionRecord[2].EndSector); + printf (" 1E5 End cylinder %02x\n", Mbr.PartitionRecord[2].EndTrack); + printf (" 1E6 Sectors preceding partition %08x\n", Mbr.PartitionRecord[2].StartingLBA); + printf (" 1EA Sectors in partition %08x\n", Mbr.PartitionRecord[2].SizeInLBA); + printf ("\n"); + printf ("Partition Table Entry #4\n"); + printf (" 1EE 80 = active partition %02x\n", Mbr.PartitionRecord[3].BootIndicator); + printf (" 1EF Start head %02x\n", Mbr.PartitionRecord[3].StartHead); + printf (" 1F0 Start sector %02x\n", Mbr.PartitionRecord[3].StartSector); + printf (" 1F1 Start cylinder %02x\n", Mbr.PartitionRecord[3].StartTrack); + printf (" 1F2 Partition type indicator %02x\n", Mbr.PartitionRecord[3].OSType); + printf (" 1F3 End head %02x\n", Mbr.PartitionRecord[3].EndHead); + printf (" 1F4 End sector %02x\n", Mbr.PartitionRecord[3].EndSector); + printf (" 1F5 End cylinder %02x\n", Mbr.PartitionRecord[3].EndTrack); + printf (" 1F6 Sectors preceding partition %08x\n", Mbr.PartitionRecord[3].StartingLBA); + printf (" 1FA Sectors in partition %08x\n", Mbr.PartitionRecord[3].SizeInLBA); + printf ("\n"); + printf (" 1FE Signature %04x\n", Mbr.Signature); + printf ("\n"); + + return ; +} + +void +PatchMbr ( + char *DestFileName, + char *SourceFileName + ) +{ + MASTER_BOOT_RECORD DestMbr; + MASTER_BOOT_RECORD SourceMbr; + + if (ReadFromFile ((void *)&DestMbr, DestFileName) == 0) { + return ; + } + if (ReadFromFile ((void *)&SourceMbr, SourceFileName) == 0) { + return ; + } + + if (SourceMbr.Signature != MBR_SIGNATURE) { + printf ("ERROR: Invalid MBR!\n"); + return; + } + + printf ("Patching MBR:\n"); + memcpy ( + &DestMbr.PartitionRecord[0], + &SourceMbr.PartitionRecord[0], + sizeof(DestMbr.PartitionRecord) + ); + + DestMbr.Signature = MBR_SIGNATURE; + + + if (WriteToFile ((void *)&DestMbr, DestFileName)) { + printf ("\tsuccessfully!\n"); + } + + return ; +} + +void +PrintUsage ( + void + ) +{ + printf ( + "Usage:\n" + "bootsectimage [-m] [-v] -p SrcImage\n" + "bootsectimage [-m] [-v] [-f] -g SrcImage DstImage\n" + "where\n" + " -p: parse SrcImage\n" + " -g: get info from SrcImage, and patch to DstImage\n" + " -f: force patch even FAT type of SrcImage and DstImage mismatch\n" + " -m: process MBR instead of boot sector\n" + " -v: verbose\n" + ); +} + +int +main ( + int argc, + char *argv[] + ) +{ + char *SrcImage; + char *DstImage; + BOOL ForcePatch; // -f + BOOL ProcessMbr; // -m + BOOL DoParse; // -p SrcImage or -g SrcImage DstImage + BOOL Verbose; // -v + + SrcImage = DstImage = NULL; + ForcePatch = FALSE; + ProcessMbr = FALSE; + DoParse = TRUE; + Verbose = FALSE; + + SetUtilityName ("bootsectimage"); + + argc--; argv++; + + if (argc == 0) { + PrintUsage (); + return -1; + } + + while (argc != 0) { + if (strcmp (*argv, "-f") == 0) { + ForcePatch = TRUE; + } else if (strcmp (*argv, "-p") == 0) { + DoParse = TRUE; + argc--; argv++; + if (argc < 1) { + PrintUsage (); + return -1; + } + SrcImage = *argv; + } else if (strcmp (*argv, "-g") == 0) { + DoParse = FALSE; + argc--; argv++; + if (argc < 2) { + PrintUsage (); + return -1; + } + SrcImage = *argv; + argc--; argv++; + DstImage = *argv; + } else if (strcmp (*argv, "-m") == 0) { + ProcessMbr = TRUE; + } else if (strcmp (*argv, "-v") == 0) { + Verbose = TRUE; + } else { + PrintUsage (); + return -1; + } + + argc--; argv++; + } + + if (ForcePatch && DoParse) { + printf ("Cannot apply force(-f) to parse(-p)!\n"); + PrintUsage (); + return -1; + } + if (ForcePatch && !DoParse && ProcessMbr) { + printf ("Cannot apply force(-f) to processing MBR (-g -m)!\n"); + PrintUsage (); + return -1; + } + + if (Verbose) { + SetDebugMsgMask (DEBUG_WARN | DEBUG_ERROR); + } else { + SetDebugMsgMask (0); + } + + if (DoParse) { + if (ProcessMbr) { + ParseMbr (SrcImage); + } else { + ParseBootSector (SrcImage); + } + } else { + if (ProcessMbr) { + PatchMbr (DstImage, SrcImage); + } else { + PatchBootSector (DstImage, SrcImage, ForcePatch); + } + } + + return 0; +} +