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