Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Liming Gao <liming.gao@intel.com> Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com>
		
			
				
	
	
		
			956 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			956 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
| 
 | |
| Abstract:
 | |
|   Patch the BPB information in boot sector image file.
 | |
|   Patch the MBR code in MBR image file.
 | |
| 
 | |
| Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
 | |
| 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.             
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include <stdio.h>
 | |
| #include <string.h>
 | |
| #include "fat.h"
 | |
| #include "mbr.h"
 | |
| #include "EfiUtilityMsgs.h"
 | |
| #include "ParseInf.h"
 | |
| 
 | |
| #define DEBUG_WARN  0x1
 | |
| #define DEBUG_ERROR 0x2
 | |
| 
 | |
| //
 | |
| // Utility Name
 | |
| //
 | |
| #define UTILITY_NAME  "BootSectImage"
 | |
| 
 | |
| //
 | |
| // Utility version information
 | |
| //
 | |
| #define UTILITY_MAJOR_VERSION 1
 | |
| #define UTILITY_MINOR_VERSION 0
 | |
| 
 | |
| void
 | |
| Version (
 | |
|   void
 | |
|   )
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
| 
 | |
|   Displays the standard utility information to SDTOUT
 | |
| 
 | |
| Arguments:
 | |
| 
 | |
|   None
 | |
| 
 | |
| Returns:
 | |
| 
 | |
|   None
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   printf ("%s Version %d.%d Build %s\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
 | |
| }
 | |
| 
 | |
| void
 | |
| Usage (
 | |
|   void
 | |
|   )
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
| 
 | |
|   GC_TODO: Add function description
 | |
| 
 | |
| Arguments:
 | |
| 
 | |
| 
 | |
| Returns:
 | |
| 
 | |
|   GC_TODO: add return values
 | |
| 
 | |
| --*/
 | |
| {
 | |
|   Version();
 | |
|   printf ("Copyright (c) 1999-2016 Intel Corporation. All rights reserved.\n");
 | |
|   printf ("\n  The BootSectImage tool prints information or patch destination file by source\n");
 | |
|   printf ("  file for BIOS Parameter Block (BPB) or Master Boot Record (MBR).\n");
 | |
|   printf ("\nUsage: \n\
 | |
|    BootSectImage\n\
 | |
|      [-f, --force force patch even if the FAT type of SrcImage and DstImage mismatch]\n\
 | |
|      [-m, --mbr process MBR instead of boot sector]\n\
 | |
|      [-p, --parse parse SrcImageFile]\n\
 | |
|      [-o, --output DstImage]\n\
 | |
|      [-g, --patch patch DstImage using data from SrcImageFile]\n\
 | |
|      [-v, --verbose]\n\
 | |
|      [--version]\n\
 | |
|      [-q, --quiet disable all messages except fatal errors]\n\
 | |
|      [-d, --debug[#]\n\
 | |
|      [-h, --help]\n\
 | |
|      [SrcImageFile]\n");
 | |
| }
 | |
| 
 | |
| 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 (LongFilePath (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 (LongFilePath (FileName), "rb");
 | |
|   if (FileHandle == NULL) {
 | |
|     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E0001: Error opening file: %s", FileName);
 | |
|     return 0;
 | |
|   }
 | |
| 
 | |
|   result = fread (BootSector, 1, 512, FileHandle);
 | |
|   if (result != 512) {
 | |
|     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E0004: Error reading 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, "ERROR: E3003: 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, "ERROR: E3003: 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, "ERROR: E3003: 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, "ERROR: E3003: 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, "ERROR: E3003: 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, "ERROR: E3003: 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, "ERROR: E3003: FAT - BPB_RsvdSecCnt - %04x, expected: Non-Zero Value",
 | |
|         FatBpb->Fat12_16.BPB_RsvdSecCnt);
 | |
|     return FatTypeUnknown;
 | |
|   }
 | |
|   if (FatBpb->Fat12_16.BPB_NumFATs != 2) {
 | |
|     DebugMsg (NULL, 0, DEBUG_WARN, NULL, "ERROR: E3003: 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, "ERROR: E3003: 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, "ERROR: E3003: FAT - BPB_FATSz16, BPB_FATSz32 - 0, expected: Non-Zero Value");
 | |
|     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, "ERROR: E3003: FAT - BPB_TotSec16, BPB_TotSec32 - 0, expected: Non-Zero Value");
 | |
|     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, "ERROR: E3003: 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, "ERROR: E3003: 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, "ERROR: E3003: 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, "ERROR: E3003: 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, "ERROR: E3003: 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, "ERROR: E3003: FAT32 - BPB_TotSec32 - %04x, expected: Non-Zero",
 | |
|         (unsigned) FatBpb->Fat12_16.BPB_TotSec32);
 | |
|     return FatTypeUnknown;
 | |
|   }
 | |
|   if ((FatType == FatTypeFat32) &&
 | |
|       (FatBpb->Fat32.BPB_FATSz32 == 0)) {
 | |
|     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3003: FAT32 - BPB_FATSz32 - %08x, expected: Non-Zero",
 | |
|         (unsigned) FatBpb->Fat32.BPB_FATSz32);
 | |
|     return FatTypeUnknown;
 | |
|   }
 | |
|   if ((FatType == FatTypeFat32) &&
 | |
|       (FatBpb->Fat32.BPB_FSVer != 0)) {
 | |
|     DebugMsg (NULL, 0, DEBUG_WARN, NULL, "ERROR: E3003: 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, "ERROR: E3003: FAT32 - BPB_RootClus - %08x, expected: %04x",
 | |
|         (unsigned) FatBpb->Fat32.BPB_RootClus, 2);
 | |
|   }
 | |
|   if ((FatType == FatTypeFat32) &&
 | |
|       (FatBpb->Fat32.BPB_FSInfo != 1)) {
 | |
|     DebugMsg (NULL, 0, DEBUG_WARN, NULL, "ERROR: E3003: 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, "ERROR: E3003: 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, "ERROR: E3003: 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, "ERROR: E3003: 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, "ERROR: E3003: 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, "ERROR: E3003: 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, "ERROR: E3003: 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, "ERROR: E3003: 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, "ERROR: E3003: 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, "ERROR: E3003: 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: E3002: 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", (unsigned) FatBpb.Fat12_16.BPB_HiddSec);
 | |
|   printf ("  20     Sectors (over 32MB)          %08x\n", (unsigned) 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", (unsigned) 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", (unsigned) 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", (unsigned) 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", (unsigned) 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,
 | |
|   BOOLEAN 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, "ERROR: E3004: FAT type mismatch: Source - %s, Dest - %s", 
 | |
|         FatTypeToString(SourceFatType), FatTypeToString(DestFatType));
 | |
|     } else {
 | |
|       DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3004: FAT type mismatch: Source - %s, Dest - %s", 
 | |
|         FatTypeToString(SourceFatType), FatTypeToString(DestFatType));
 | |
|       return ;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (SourceFatType <= FatTypeUnknown || SourceFatType >= FatTypeMax) {
 | |
|     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3002: 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 ("successful!\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", (unsigned) 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", (unsigned) Mbr.PartitionRecord[0].StartingLBA);
 | |
|   printf ("  1CA    Sectors in partition         %08x\n", (unsigned) 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", (unsigned) Mbr.PartitionRecord[1].StartingLBA);
 | |
|   printf ("  1DA    Sectors in partition         %08x\n", (unsigned) 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", (unsigned) Mbr.PartitionRecord[2].StartingLBA);
 | |
|   printf ("  1EA    Sectors in partition         %08x\n", (unsigned) 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", (unsigned) Mbr.PartitionRecord[3].StartingLBA);
 | |
|   printf ("  1FA    Sectors in partition         %08x\n", (unsigned) 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: E3000: 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 ("\tsuccessful!\n");
 | |
|   }
 | |
| 
 | |
|   return ;
 | |
| }
 | |
| 
 | |
| 
 | |
| int
 | |
| main (
 | |
|   int argc,
 | |
|   char *argv[]
 | |
|   )
 | |
| {
 | |
|   char *SrcImage;
 | |
|   char *DstImage;
 | |
|   BOOLEAN ForcePatch;    // -f
 | |
|   BOOLEAN ProcessMbr;    // -m
 | |
|   BOOLEAN DoParse;       // -p SrcImage or -g SrcImage DstImage
 | |
|   BOOLEAN Verbose;       // -v
 | |
|   UINT64  LogLevel;
 | |
|   EFI_STATUS EfiStatus;
 | |
| 
 | |
|   SrcImage = DstImage = NULL;
 | |
|   ForcePatch = FALSE;
 | |
|   ProcessMbr = FALSE;
 | |
|   DoParse    = TRUE;
 | |
|   Verbose    = FALSE;
 | |
| 
 | |
|   SetUtilityName ("bootsectimage");
 | |
| 
 | |
|   argc--; argv++;
 | |
| 
 | |
|   if (argc == 0) {
 | |
|     Usage ();
 | |
|     return -1;
 | |
|   }
 | |
| 
 | |
|   while (argc != 0) {
 | |
|     if (strcmp (*argv, "-f") == 0 || strcmp (*argv, "--force") == 0) {
 | |
|       ForcePatch = TRUE;
 | |
|     } else if (strcmp (*argv, "-p") == 0 || strcmp (*argv, "--parse") == 0) {
 | |
|       DoParse    = TRUE;
 | |
|       argc--; argv++;
 | |
|       if (argc < 1) {
 | |
|         Usage ();
 | |
|         return -1;
 | |
|       }
 | |
|       SrcImage   = *argv;
 | |
|     } else if (strcmp (*argv, "-g") == 0 || strcmp (*argv, "--patch") == 0) {
 | |
|       DoParse    = FALSE;
 | |
|       argc--; argv++;
 | |
|       if (argc < 2) {
 | |
|         Usage ();
 | |
|         return -1;
 | |
|       }
 | |
|       SrcImage   = *argv;
 | |
|       argc--; argv++;
 | |
|       DstImage   = *argv;
 | |
|     } else if (strcmp (*argv, "-m") == 0 || strcmp (*argv, "--mbr") == 0) {
 | |
|       ProcessMbr = TRUE;
 | |
|     } else if (strcmp (*argv, "-v") == 0 || strcmp (*argv, "--verbose") == 0) {
 | |
|       Verbose    = TRUE;
 | |
|     } else if (strcmp (*argv, "--version") == 0) {
 | |
|       Version();
 | |
|       return 0;
 | |
|     } else if ((stricmp (*argv, "-d") == 0) || (stricmp (*argv, "--debug") == 0)) {
 | |
|       argc--; argv++;
 | |
|       if (argc < 1) {
 | |
|         Usage ();
 | |
|         return -1;
 | |
|       }
 | |
|       EfiStatus = AsciiStringToUint64 (*argv, FALSE, &LogLevel);
 | |
|       if (EFI_ERROR (EfiStatus)) {
 | |
|         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", "--debug", *argv);
 | |
|         return 1;
 | |
|       }
 | |
|       if (LogLevel > 9) {
 | |
|         Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, currnt input level is %d", (int) LogLevel);
 | |
|         return 1;
 | |
|       }
 | |
|       SetPrintLevel (LogLevel);
 | |
|       DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", *argv);
 | |
|     } else {
 | |
|       Usage ();
 | |
|       return -1;
 | |
|     }
 | |
| 
 | |
|     argc--; argv++;
 | |
|   }
 | |
| 
 | |
|   if (ForcePatch && DoParse) {
 | |
|     printf ("ERROR: E1002: Conflicting options: -f, -p. Cannot apply force(-f) to parse(-p)!\n");
 | |
|     Usage ();
 | |
|     return -1;
 | |
|   }
 | |
|   if (ForcePatch && !DoParse && ProcessMbr) {
 | |
|     printf ("ERROR: E1002: Conflicting options: -f, -g -m. Cannot apply force(-f) to processing MBR (-g -m)!\n");
 | |
|     Usage ();
 | |
|     return -1;
 | |
|   }
 | |
| 
 | |
|   if (Verbose) {
 | |
|     SetPrintLevel (VERBOSE_LOG_LEVEL);
 | |
|   } else {
 | |
|     SetPrintLevel (KEY_LOG_LEVEL);
 | |
|   }
 | |
| 
 | |
|   if (DoParse) {
 | |
|     if (ProcessMbr) {
 | |
|       ParseMbr (SrcImage);
 | |
|     } else {
 | |
|       ParseBootSector (SrcImage);
 | |
|     }
 | |
|   } else {
 | |
|     if (ProcessMbr) {
 | |
|       PatchMbr (DstImage, SrcImage);
 | |
|     } else {
 | |
|       PatchBootSector (DstImage, SrcImage, ForcePatch);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return 0;
 | |
| }
 | |
| 
 |