Home | History | Annotate | Download | only in BootSectImage
      1 /** @file
      2 
      3 Abstract:
      4   Patch the BPB information in boot sector image file.
      5   Patch the MBR code in MBR image file.
      6 
      7 Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
      8 This program and the accompanying materials
      9 are licensed and made available under the terms and conditions of the BSD License
     10 which accompanies this distribution.  The full text of the license may be found at
     11 http://opensource.org/licenses/bsd-license.php
     12 
     13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     15 
     16 **/
     17 
     18 #include <stdio.h>
     19 #include <string.h>
     20 #include "fat.h"
     21 #include "mbr.h"
     22 #include "EfiUtilityMsgs.h"
     23 #include "ParseInf.h"
     24 
     25 #define DEBUG_WARN  0x1
     26 #define DEBUG_ERROR 0x2
     27 
     28 //
     29 // Utility Name
     30 //
     31 #define UTILITY_NAME  "BootSectImage"
     32 
     33 //
     34 // Utility version information
     35 //
     36 #define UTILITY_MAJOR_VERSION 0
     37 #define UTILITY_MINOR_VERSION 1
     38 
     39 void
     40 Version (
     41   void
     42   )
     43 /*++
     44 
     45 Routine Description:
     46 
     47   Displays the standard utility information to SDTOUT
     48 
     49 Arguments:
     50 
     51   None
     52 
     53 Returns:
     54 
     55   None
     56 
     57 --*/
     58 {
     59   printf ("%s Version %d.%d %s\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
     60   printf ("Copyright (c) 1999-2014 Intel Corporation. All rights reserved.\n");
     61   printf ("\n  The BootSectImage tool prints information or patch destination file by source\n");
     62   printf ("  file for BIOS Parameter Block (BPB) or Master Boot Record (MBR).\n");
     63 }
     64 
     65 void
     66 Usage (
     67   void
     68   )
     69 /*++
     70 
     71 Routine Description:
     72 
     73   GC_TODO: Add function description
     74 
     75 Arguments:
     76 
     77 
     78 Returns:
     79 
     80   GC_TODO: add return values
     81 
     82 --*/
     83 {
     84   Version();
     85   printf ("\nUsage: \n\
     86    BootSectImage\n\
     87      [-f, --force force patch even if the FAT type of SrcImage and DstImage mismatch]\n\
     88      [-m, --mbr process MBR instead of boot sector]\n\
     89      [-p, --parse parse SrcImageFile]\n\
     90      [-o, --output DstImage]\n\
     91      [-g, --patch patch DstImage using data from SrcImageFile]\n\
     92      [-v, --verbose]\n\
     93      [--version]\n\
     94      [-q, --quiet disable all messages except fatal errors]\n\
     95      [-d, --debug[#]\n\
     96      [-h, --help]\n\
     97      [SrcImageFile]\n");
     98 }
     99 
    100 int WriteToFile (
    101   void *BootSector,
    102   char *FileName
    103   )
    104 /*++
    105 Routine Description:
    106   Write 512 bytes boot sector to file.
    107 
    108 Arguments:
    109   BootSector - point to a buffer containing 512 bytes boot sector to write
    110   FileName   - file to write to
    111 
    112 Return:
    113   int        - number of bytes wrote,
    114                  512 indicates write successful
    115                  0 indicates write failure
    116 --*/
    117 {
    118   FILE *FileHandle;
    119   int  result;
    120 
    121   FileHandle = fopen (LongFilePath (FileName), "r+b");
    122   if (FileHandle == NULL) {
    123     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "Open file: %s", FileName);
    124     return 0;
    125   }
    126   fseek (FileHandle, 0, SEEK_SET);
    127 
    128   result = fwrite (BootSector, 1, 512, FileHandle);
    129   if (result != 512) {
    130     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "Write file: %s", FileName);
    131     result = 0;
    132   }
    133 
    134   fclose (FileHandle);
    135   return result;
    136 }
    137 
    138 int ReadFromFile (
    139   void *BootSector,
    140   char *FileName
    141   )
    142 /*++
    143 Routine Description:
    144   Read first 512 bytes from file.
    145 
    146 Arguments:
    147   BootSector - point to a buffer receiving the first 512 bytes data from file
    148   FileName   - file to read from
    149 
    150 Return:
    151   int        - number of bytes read,
    152                  512 indicates read successful
    153                  0 indicates read failure
    154 --*/
    155 {
    156   FILE *FileHandle;
    157   int  result;
    158 
    159   FileHandle = fopen (LongFilePath (FileName), "rb");
    160   if (FileHandle == NULL) {
    161     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E0001: Error opening file: %s", FileName);
    162     return 0;
    163   }
    164 
    165   result = fread (BootSector, 1, 512, FileHandle);
    166   if (result != 512) {
    167     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E0004: Error reading file: %s", FileName);
    168     result = 0;
    169   }
    170 
    171   fclose (FileHandle);
    172   return result;
    173 }
    174 
    175 char *
    176 FatTypeToString (
    177   IN FAT_TYPE        FatType
    178   )
    179 /*++
    180 Routine Description:
    181   Convert enum type of FatType to string
    182 --*/
    183 {
    184   switch (FatType) {
    185   case FatTypeFat12:
    186     return "FAT12";
    187   case FatTypeFat16:
    188     return "FAT16";
    189   case FatTypeFat32:
    190     return "FAT32";
    191   default:
    192     break;
    193   }
    194   return "FAT Unknown";
    195 }
    196 
    197 FAT_TYPE
    198 GetFatType (
    199   IN FAT_BPB_STRUCT  *FatBpb
    200   )
    201 /*++
    202 Routine Description:
    203   Determine the FAT type according to BIOS Paramater Block (BPB) data
    204 
    205 Arguments:
    206   FatBpb - BIOS Parameter Block (BPB) data, 512 Bytes
    207 
    208 Return:
    209   FatTypeUnknown - Cannot determine the FAT type
    210   FatTypeFat12   - FAT12
    211   FatTypeFat16   - FAT16
    212   FatTypeFat32   - FAT32
    213 --*/
    214 {
    215   FAT_TYPE FatType;
    216   UINTN    RootDirSectors;
    217   UINTN    FATSz;
    218   UINTN    TotSec;
    219   UINTN    DataSec;
    220   UINTN    CountOfClusters;
    221   CHAR8    FilSysType[9];
    222 
    223   FatType = FatTypeUnknown;
    224 
    225   //
    226   // Simple check
    227   //
    228   if (FatBpb->Fat12_16.Signature != FAT_BS_SIGNATURE) {
    229     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3003: FAT - Signature Invalid - %04x, expected: %04x",
    230         FatBpb->Fat12_16.Signature, FAT_BS_SIGNATURE);
    231     return FatTypeUnknown;
    232   }
    233 
    234   //
    235   // Check according to FAT spec
    236   //
    237   if ((FatBpb->Fat12_16.BS_jmpBoot[0] != FAT_BS_JMP1) &&
    238       (FatBpb->Fat12_16.BS_jmpBoot[0] != FAT_BS_JMP2)) {
    239     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3003: FAT - BS_jmpBoot - %02x, expected: %02x or %02x",
    240         FatBpb->Fat12_16.BS_jmpBoot[0], FAT_BS_JMP1, FAT_BS_JMP2);
    241     return FatTypeUnknown;
    242   }
    243 
    244   if ((FatBpb->Fat12_16.BPB_BytsPerSec != 512) &&
    245       (FatBpb->Fat12_16.BPB_BytsPerSec != 1024) &&
    246       (FatBpb->Fat12_16.BPB_BytsPerSec != 2048) &&
    247       (FatBpb->Fat12_16.BPB_BytsPerSec != 4096)) {
    248     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3003: FAT - BPB_BytsPerSec - %04x, expected: %04x, %04x, %04x, or %04x",
    249         FatBpb->Fat12_16.BPB_BytsPerSec, 512, 1024, 2048, 4096);
    250     return FatTypeUnknown;
    251   }
    252   if (FatBpb->Fat12_16.BPB_BytsPerSec != 512) {
    253     DebugMsg (NULL, 0, DEBUG_WARN, NULL, "ERROR: E3003: FAT - BPB_BytsPerSec - %04x, expected: %04x",
    254         FatBpb->Fat12_16.BPB_BytsPerSec, 512);
    255   }
    256   if ((FatBpb->Fat12_16.BPB_SecPerClus != 1) &&
    257       (FatBpb->Fat12_16.BPB_SecPerClus != 2) &&
    258       (FatBpb->Fat12_16.BPB_SecPerClus != 4) &&
    259       (FatBpb->Fat12_16.BPB_SecPerClus != 8) &&
    260       (FatBpb->Fat12_16.BPB_SecPerClus != 16) &&
    261       (FatBpb->Fat12_16.BPB_SecPerClus != 32) &&
    262       (FatBpb->Fat12_16.BPB_SecPerClus != 64) &&
    263       (FatBpb->Fat12_16.BPB_SecPerClus != 128)) {
    264     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3003: FAT - BPB_SecPerClus - %02x, expected: %02x, %02x, %02x, %02x, %02x, %02x, %02x, or %02x",
    265         FatBpb->Fat12_16.BPB_BytsPerSec, 1, 2, 4, 8, 16, 32, 64, 128);
    266     return FatTypeUnknown;
    267   }
    268   if (FatBpb->Fat12_16.BPB_BytsPerSec * FatBpb->Fat12_16.BPB_SecPerClus > 32 * 1024) {
    269     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3003: FAT - BPB_BytsPerSec * BPB_SecPerClus - %08x, expected: <= %08x",
    270         FatBpb->Fat12_16.BPB_BytsPerSec * FatBpb->Fat12_16.BPB_SecPerClus, 32 * 1024);
    271     return FatTypeUnknown;
    272   }
    273   if (FatBpb->Fat12_16.BPB_RsvdSecCnt == 0) {
    274     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3003: FAT - BPB_RsvdSecCnt - %04x, expected: Non-Zero Value",
    275         FatBpb->Fat12_16.BPB_RsvdSecCnt);
    276     return FatTypeUnknown;
    277   }
    278   if (FatBpb->Fat12_16.BPB_NumFATs != 2) {
    279     DebugMsg (NULL, 0, DEBUG_WARN, NULL, "ERROR: E3003: FAT - BPB_NumFATs - %02x, expected: %02x",
    280         FatBpb->Fat12_16.BPB_NumFATs, 2);
    281   }
    282   if ((FatBpb->Fat12_16.BPB_Media != 0xF0) &&
    283       (FatBpb->Fat12_16.BPB_Media != 0xF8) &&
    284       (FatBpb->Fat12_16.BPB_Media != 0xF9) &&
    285       (FatBpb->Fat12_16.BPB_Media != 0xFA) &&
    286       (FatBpb->Fat12_16.BPB_Media != 0xFB) &&
    287       (FatBpb->Fat12_16.BPB_Media != 0xFC) &&
    288       (FatBpb->Fat12_16.BPB_Media != 0xFD) &&
    289       (FatBpb->Fat12_16.BPB_Media != 0xFE) &&
    290       (FatBpb->Fat12_16.BPB_Media != 0xFF)) {
    291     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3003: FAT - BPB_Media - %02x, expected: %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, or %02x",
    292         FatBpb->Fat12_16.BPB_Media, 0xF0, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF);
    293     return FatTypeUnknown;
    294   }
    295 
    296   //
    297   // Algo in FAT spec
    298   //
    299   RootDirSectors = ((FatBpb->Fat12_16.BPB_RootEntCnt * sizeof(FAT_DIRECTORY_ENTRY)) +
    300                     (FatBpb->Fat12_16.BPB_BytsPerSec - 1)) /
    301                    FatBpb->Fat12_16.BPB_BytsPerSec;
    302 
    303   if (FatBpb->Fat12_16.BPB_FATSz16 != 0) {
    304     FATSz = FatBpb->Fat12_16.BPB_FATSz16;
    305   } else {
    306     FATSz = FatBpb->Fat32.BPB_FATSz32;
    307   }
    308   if (FATSz == 0) {
    309     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3003: FAT - BPB_FATSz16, BPB_FATSz32 - 0, expected: Non-Zero Value");
    310     return FatTypeUnknown;
    311   }
    312 
    313   if (FatBpb->Fat12_16.BPB_TotSec16 != 0) {
    314     TotSec = FatBpb->Fat12_16.BPB_TotSec16;
    315   } else {
    316     TotSec = FatBpb->Fat12_16.BPB_TotSec32;
    317   }
    318   if (TotSec == 0) {
    319     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3003: FAT - BPB_TotSec16, BPB_TotSec32 - 0, expected: Non-Zero Value");
    320     return FatTypeUnknown;
    321   }
    322 
    323   DataSec = TotSec - (
    324                       FatBpb->Fat12_16.BPB_RsvdSecCnt +
    325                       FatBpb->Fat12_16.BPB_NumFATs * FATSz +
    326                       RootDirSectors
    327                      );
    328 
    329   CountOfClusters = DataSec / FatBpb->Fat12_16.BPB_SecPerClus;
    330 
    331   if (CountOfClusters < FAT_MAX_FAT12_CLUSTER) {
    332     FatType = FatTypeFat12;
    333   } else if (CountOfClusters < FAT_MAX_FAT16_CLUSTER) {
    334     FatType = FatTypeFat16;
    335   } else {
    336     FatType = FatTypeFat32;
    337   }
    338   //
    339   // Check according to FAT spec
    340   //
    341   if (((FatType == FatTypeFat12) || (FatType == FatTypeFat16)) &&
    342        (FatBpb->Fat12_16.BPB_RsvdSecCnt != 1)) {
    343     DebugMsg (NULL, 0, DEBUG_WARN, NULL, "ERROR: E3003: FAT12_16 - BPB_RsvdSecCnt - %04x, expected: %04x",
    344         FatBpb->Fat12_16.BPB_RsvdSecCnt, 1);
    345   }
    346   if ((FatType == FatTypeFat32) &&
    347        (FatBpb->Fat12_16.BPB_RsvdSecCnt != 32)) {
    348     DebugMsg (NULL, 0, DEBUG_WARN, NULL, "ERROR: E3003: FAT32 - BPB_RsvdSecCnt - %04x, expected: %04x",
    349         FatBpb->Fat12_16.BPB_RsvdSecCnt, 32);
    350   }
    351   if ((FatType == FatTypeFat16) &&
    352       (FatBpb->Fat12_16.BPB_RootEntCnt != 512)) {
    353     printf ("WARNING: FAT16: BPB_RootEntCnt - %04x, expected - %04x\n",
    354         FatBpb->Fat12_16.BPB_RootEntCnt, 512);
    355   }
    356   if ((FatType == FatTypeFat32) &&
    357       (FatBpb->Fat12_16.BPB_RootEntCnt != 0)) {
    358     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3003: FAT32 - BPB_RootEntCnt - %04x, expected: %04x",
    359         FatBpb->Fat12_16.BPB_RootEntCnt, 0);
    360     return FatTypeUnknown;
    361   }
    362   if ((FatType == FatTypeFat32) &&
    363       (FatBpb->Fat12_16.BPB_TotSec16 != 0)) {
    364     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3003: FAT32 - BPB_TotSec16 - %04x, expected: %04x",
    365         FatBpb->Fat12_16.BPB_TotSec16, 0);
    366     return FatTypeUnknown;
    367   }
    368   if ((FatType == FatTypeFat32) &&
    369       (FatBpb->Fat12_16.BPB_FATSz16 != 0)) {
    370     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3003: FAT32 - BPB_FATSz16 - %04x, expected: %04x",
    371         FatBpb->Fat12_16.BPB_FATSz16, 0);
    372     return FatTypeUnknown;
    373   }
    374   if ((FatType == FatTypeFat32) &&
    375       (FatBpb->Fat12_16.BPB_TotSec32 == 0)) {
    376     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3003: FAT32 - BPB_TotSec32 - %04x, expected: Non-Zero",
    377         (unsigned) FatBpb->Fat12_16.BPB_TotSec32);
    378     return FatTypeUnknown;
    379   }
    380   if ((FatType == FatTypeFat32) &&
    381       (FatBpb->Fat32.BPB_FATSz32 == 0)) {
    382     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3003: FAT32 - BPB_FATSz32 - %08x, expected: Non-Zero",
    383         (unsigned) FatBpb->Fat32.BPB_FATSz32);
    384     return FatTypeUnknown;
    385   }
    386   if ((FatType == FatTypeFat32) &&
    387       (FatBpb->Fat32.BPB_FSVer != 0)) {
    388     DebugMsg (NULL, 0, DEBUG_WARN, NULL, "ERROR: E3003: FAT32 - BPB_FSVer - %08x, expected: %04x",
    389         FatBpb->Fat32.BPB_FSVer, 0);
    390   }
    391   if ((FatType == FatTypeFat32) &&
    392       (FatBpb->Fat32.BPB_RootClus != 2)) {
    393     DebugMsg (NULL, 0, DEBUG_WARN, NULL, "ERROR: E3003: FAT32 - BPB_RootClus - %08x, expected: %04x",
    394         (unsigned) FatBpb->Fat32.BPB_RootClus, 2);
    395   }
    396   if ((FatType == FatTypeFat32) &&
    397       (FatBpb->Fat32.BPB_FSInfo != 1)) {
    398     DebugMsg (NULL, 0, DEBUG_WARN, NULL, "ERROR: E3003: FAT32 - BPB_FSInfo - %08x, expected: %04x",
    399         FatBpb->Fat32.BPB_FSInfo, 1);
    400   }
    401   if ((FatType == FatTypeFat32) &&
    402       (FatBpb->Fat32.BPB_BkBootSec != 6)) {
    403     DebugMsg (NULL, 0, DEBUG_WARN, NULL, "ERROR: E3003: FAT32 - BPB_BkBootSec - %08x, expected: %04x",
    404         FatBpb->Fat32.BPB_BkBootSec, 6);
    405   }
    406   if ((FatType == FatTypeFat32) &&
    407       ((*(UINT32 *)FatBpb->Fat32.BPB_Reserved != 0) ||
    408        (*((UINT32 *)FatBpb->Fat32.BPB_Reserved + 1) != 0) ||
    409        (*((UINT32 *)FatBpb->Fat32.BPB_Reserved + 2) != 0))) {
    410     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",
    411         FatBpb->Fat32.BPB_Reserved[0],
    412         FatBpb->Fat32.BPB_Reserved[1],
    413         FatBpb->Fat32.BPB_Reserved[2],
    414         FatBpb->Fat32.BPB_Reserved[3],
    415         FatBpb->Fat32.BPB_Reserved[4],
    416         FatBpb->Fat32.BPB_Reserved[5],
    417         FatBpb->Fat32.BPB_Reserved[6],
    418         FatBpb->Fat32.BPB_Reserved[7],
    419         FatBpb->Fat32.BPB_Reserved[8],
    420         FatBpb->Fat32.BPB_Reserved[9],
    421         FatBpb->Fat32.BPB_Reserved[10],
    422         FatBpb->Fat32.BPB_Reserved[11]);
    423     return FatTypeUnknown;
    424   }
    425   if (((FatType == FatTypeFat12) || (FatType == FatTypeFat16)) &&
    426        (FatBpb->Fat12_16.BS_Reserved1 != 0)) {
    427     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3003: FAT12_16 - BS_Reserved1 - %02x, expected: 0\n",
    428         FatBpb->Fat12_16.BS_Reserved1);
    429     return FatTypeUnknown;
    430   }
    431   if ((FatType == FatTypeFat32) &&
    432       (FatBpb->Fat32.BS_Reserved1 != 0)) {
    433     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3003: FAT32 - BS_Reserved1 - %02x, expected: 0\n",
    434         FatBpb->Fat32.BS_Reserved1);
    435     return FatTypeUnknown;
    436   }
    437   if (((FatType == FatTypeFat12) || (FatType == FatTypeFat16)) &&
    438        (FatBpb->Fat12_16.BS_BootSig != FAT_BS_BOOTSIG)) {
    439     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3003: FAT12_16 - BS_BootSig - %02x, expected: %02x\n",
    440         FatBpb->Fat12_16.BS_BootSig, FAT_BS_BOOTSIG);
    441     return FatTypeUnknown;
    442   }
    443   if ((FatType == FatTypeFat32) &&
    444       (FatBpb->Fat32.BS_BootSig != FAT_BS_BOOTSIG)) {
    445     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3003: FAT32 - BS_BootSig - %02x, expected: %02x\n",
    446         FatBpb->Fat32.BS_BootSig, FAT_BS_BOOTSIG);
    447     return FatTypeUnknown;
    448   }
    449 
    450   if ((FatType == FatTypeFat12) || (FatType == FatTypeFat16)) {
    451     memcpy (FilSysType, FatBpb->Fat12_16.BS_FilSysType, 8);
    452     FilSysType[8] = 0;
    453     if ((FatType == FatTypeFat12) &&
    454         (strcmp (FilSysType, FAT12_FILSYSTYPE) != 0) &&
    455         (strcmp (FilSysType, FAT_FILSYSTYPE) != 0)) {
    456       DebugMsg (NULL, 0, DEBUG_WARN, NULL, "ERROR: E3003: FAT12 - BS_FilSysType - %s, expected: %s, or %s\n",
    457           FilSysType, FAT12_FILSYSTYPE, FAT_FILSYSTYPE);
    458     }
    459     if ((FatType == FatTypeFat16) &&
    460         (strcmp (FilSysType, FAT16_FILSYSTYPE) != 0) &&
    461         (strcmp (FilSysType, FAT_FILSYSTYPE) != 0)) {
    462       DebugMsg (NULL, 0, DEBUG_WARN, NULL, "ERROR: E3003: FAT16 - BS_FilSysType - %s, expected: %s, or %s\n",
    463           FilSysType, FAT16_FILSYSTYPE, FAT_FILSYSTYPE);
    464     }
    465   }
    466   if (FatType == FatTypeFat32) {
    467     memcpy (FilSysType, FatBpb->Fat32.BS_FilSysType, 8);
    468     FilSysType[8] = 0;
    469     if (strcmp (FilSysType, FAT32_FILSYSTYPE) != 0) {
    470       DebugMsg (NULL, 0, DEBUG_WARN, NULL, "ERROR: E3003: FAT32 - BS_FilSysType - %s, expected: %s\n",
    471           FilSysType, FAT32_FILSYSTYPE);
    472     }
    473   }
    474 
    475   //
    476   // pass all check, get FAT type
    477   //
    478   return FatType;
    479 }
    480 
    481 
    482 void
    483 ParseBootSector (
    484   char *FileName
    485   )
    486 {
    487   FAT_BPB_STRUCT  FatBpb;
    488   FAT_TYPE        FatType;
    489 
    490   if (ReadFromFile ((void *)&FatBpb, FileName) == 0) {
    491     return ;
    492   }
    493 
    494   FatType = GetFatType (&FatBpb);
    495   if (FatType <= FatTypeUnknown || FatType >= FatTypeMax) {
    496     printf ("ERROR: E3002: Unknown FAT Type!\n");
    497     return;
    498   }
    499 
    500   printf ("\nBoot Sector %s:\n", FatTypeToString (FatType));
    501   printf ("\n");
    502   printf ("  Offset Title                        Data\n");
    503   printf ("==================================================================\n");
    504   printf ("  0      JMP instruction              %02x %02x %02x\n",
    505                                                  FatBpb.Fat12_16.BS_jmpBoot[0],
    506                                                  FatBpb.Fat12_16.BS_jmpBoot[1],
    507                                                  FatBpb.Fat12_16.BS_jmpBoot[2]);
    508   printf ("  3      OEM                          %c%c%c%c%c%c%c%c\n",
    509                                                  FatBpb.Fat12_16.BS_OEMName[0],
    510                                                  FatBpb.Fat12_16.BS_OEMName[1],
    511                                                  FatBpb.Fat12_16.BS_OEMName[2],
    512                                                  FatBpb.Fat12_16.BS_OEMName[3],
    513                                                  FatBpb.Fat12_16.BS_OEMName[4],
    514                                                  FatBpb.Fat12_16.BS_OEMName[5],
    515                                                  FatBpb.Fat12_16.BS_OEMName[6],
    516                                                  FatBpb.Fat12_16.BS_OEMName[7]);
    517   printf ("\n");
    518   printf ("BIOS Parameter Block\n");
    519   printf ("  B      Bytes per sector             %04x\n", FatBpb.Fat12_16.BPB_BytsPerSec);
    520   printf ("  D      Sectors per cluster          %02x\n", FatBpb.Fat12_16.BPB_SecPerClus);
    521   printf ("  E      Reserved sectors             %04x\n", FatBpb.Fat12_16.BPB_RsvdSecCnt);
    522   printf ("  10     Number of FATs               %02x\n", FatBpb.Fat12_16.BPB_NumFATs);
    523   printf ("  11     Root entries                 %04x\n", FatBpb.Fat12_16.BPB_RootEntCnt);
    524   printf ("  13     Sectors (under 32MB)         %04x\n", FatBpb.Fat12_16.BPB_TotSec16);
    525   printf ("  15     Media descriptor             %02x\n", FatBpb.Fat12_16.BPB_Media);
    526   printf ("  16     Sectors per FAT (small vol.) %04x\n", FatBpb.Fat12_16.BPB_FATSz16);
    527   printf ("  18     Sectors per track            %04x\n", FatBpb.Fat12_16.BPB_SecPerTrk);
    528   printf ("  1A     Heads                        %04x\n", FatBpb.Fat12_16.BPB_NumHeads);
    529   printf ("  1C     Hidden sectors               %08x\n", (unsigned) FatBpb.Fat12_16.BPB_HiddSec);
    530   printf ("  20     Sectors (over 32MB)          %08x\n", (unsigned) FatBpb.Fat12_16.BPB_TotSec32);
    531   printf ("\n");
    532   if (FatType != FatTypeFat32) {
    533     printf ("  24     BIOS drive                   %02x\n", FatBpb.Fat12_16.BS_DrvNum);
    534     printf ("  25     (Unused)                     %02x\n", FatBpb.Fat12_16.BS_Reserved1);
    535     printf ("  26     Ext. boot signature          %02x\n", FatBpb.Fat12_16.BS_BootSig);
    536     printf ("  27     Volume serial number         %08x\n", (unsigned) FatBpb.Fat12_16.BS_VolID);
    537     printf ("  2B     Volume lable                 %c%c%c%c%c%c%c%c%c%c%c\n",
    538                                                    FatBpb.Fat12_16.BS_VolLab[0],
    539                                                    FatBpb.Fat12_16.BS_VolLab[1],
    540                                                    FatBpb.Fat12_16.BS_VolLab[2],
    541                                                    FatBpb.Fat12_16.BS_VolLab[3],
    542                                                    FatBpb.Fat12_16.BS_VolLab[4],
    543                                                    FatBpb.Fat12_16.BS_VolLab[5],
    544                                                    FatBpb.Fat12_16.BS_VolLab[6],
    545                                                    FatBpb.Fat12_16.BS_VolLab[7],
    546                                                    FatBpb.Fat12_16.BS_VolLab[8],
    547                                                    FatBpb.Fat12_16.BS_VolLab[9],
    548                                                    FatBpb.Fat12_16.BS_VolLab[10]);
    549     printf ("  36     File system                  %c%c%c%c%c%c%c%c\n",
    550                                                    FatBpb.Fat12_16.BS_FilSysType[0],
    551                                                    FatBpb.Fat12_16.BS_FilSysType[1],
    552                                                    FatBpb.Fat12_16.BS_FilSysType[2],
    553                                                    FatBpb.Fat12_16.BS_FilSysType[3],
    554                                                    FatBpb.Fat12_16.BS_FilSysType[4],
    555                                                    FatBpb.Fat12_16.BS_FilSysType[5],
    556                                                    FatBpb.Fat12_16.BS_FilSysType[6],
    557                                                    FatBpb.Fat12_16.BS_FilSysType[7]);
    558     printf ("\n");
    559   } else {
    560     printf ("FAT32 Section\n");
    561     printf ("  24     Sectors per FAT (large vol.) %08x\n", (unsigned) FatBpb.Fat32.BPB_FATSz32);
    562     printf ("  28     Flags                        %04x\n", FatBpb.Fat32.BPB_ExtFlags);
    563     printf ("  2A     Version                      %04x\n", FatBpb.Fat32.BPB_FSVer);
    564     printf ("  2C     Root dir 1st cluster         %08x\n", (unsigned) FatBpb.Fat32.BPB_RootClus);
    565     printf ("  30     FSInfo sector                %04x\n", FatBpb.Fat32.BPB_FSInfo);
    566     printf ("  32     Backup boot sector           %04x\n", FatBpb.Fat32.BPB_BkBootSec);
    567     printf ("  34     (Reserved)                   %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
    568                                                    FatBpb.Fat32.BPB_Reserved[0],
    569                                                    FatBpb.Fat32.BPB_Reserved[1],
    570                                                    FatBpb.Fat32.BPB_Reserved[2],
    571                                                    FatBpb.Fat32.BPB_Reserved[3],
    572                                                    FatBpb.Fat32.BPB_Reserved[4],
    573                                                    FatBpb.Fat32.BPB_Reserved[5],
    574                                                    FatBpb.Fat32.BPB_Reserved[6],
    575                                                    FatBpb.Fat32.BPB_Reserved[7],
    576                                                    FatBpb.Fat32.BPB_Reserved[8],
    577                                                    FatBpb.Fat32.BPB_Reserved[9],
    578                                                    FatBpb.Fat32.BPB_Reserved[10],
    579                                                    FatBpb.Fat32.BPB_Reserved[11]);
    580     printf ("\n");
    581     printf ("  40     BIOS drive                   %02x\n", FatBpb.Fat32.BS_DrvNum);
    582     printf ("  41     (Unused)                     %02x\n", FatBpb.Fat32.BS_Reserved1);
    583     printf ("  42     Ext. boot signature          %02x\n", FatBpb.Fat32.BS_BootSig);
    584     printf ("  43     Volume serial number         %08x\n", (unsigned) FatBpb.Fat32.BS_VolID);
    585     printf ("  47     Volume lable                 %c%c%c%c%c%c%c%c%c%c%c\n",
    586                                                    FatBpb.Fat32.BS_VolLab[0],
    587                                                    FatBpb.Fat32.BS_VolLab[1],
    588                                                    FatBpb.Fat32.BS_VolLab[2],
    589                                                    FatBpb.Fat32.BS_VolLab[3],
    590                                                    FatBpb.Fat32.BS_VolLab[4],
    591                                                    FatBpb.Fat32.BS_VolLab[5],
    592                                                    FatBpb.Fat32.BS_VolLab[6],
    593                                                    FatBpb.Fat32.BS_VolLab[7],
    594                                                    FatBpb.Fat32.BS_VolLab[8],
    595                                                    FatBpb.Fat32.BS_VolLab[9],
    596                                                    FatBpb.Fat32.BS_VolLab[10]);
    597     printf ("  52     File system                  %c%c%c%c%c%c%c%c\n",
    598                                                    FatBpb.Fat32.BS_FilSysType[0],
    599                                                    FatBpb.Fat32.BS_FilSysType[1],
    600                                                    FatBpb.Fat32.BS_FilSysType[2],
    601                                                    FatBpb.Fat32.BS_FilSysType[3],
    602                                                    FatBpb.Fat32.BS_FilSysType[4],
    603                                                    FatBpb.Fat32.BS_FilSysType[5],
    604                                                    FatBpb.Fat32.BS_FilSysType[6],
    605                                                    FatBpb.Fat32.BS_FilSysType[7]);
    606     printf ("\n");
    607   }
    608   printf ("  1FE    Signature                    %04x\n", FatBpb.Fat12_16.Signature);
    609   printf ("\n");
    610 
    611 
    612   return ;
    613 }
    614 
    615 void
    616 PatchBootSector (
    617   char *DestFileName,
    618   char *SourceFileName,
    619   BOOLEAN ForcePatch
    620   )
    621 /*++
    622 Routine Description:
    623   Patch destination file according to the information from source file.
    624   Only patch BPB data but leave boot code un-touched.
    625 
    626 Arguments:
    627   DestFileName   - Destination file to patch
    628   SourceFileName - Source file where patch from
    629 --*/
    630 {
    631   FAT_BPB_STRUCT  DestFatBpb;
    632   FAT_BPB_STRUCT  SourceFatBpb;
    633   FAT_TYPE        DestFatType;
    634   FAT_TYPE        SourceFatType;
    635   CHAR8           VolLab[11];
    636   CHAR8           FilSysType[8];
    637 
    638   if (ReadFromFile ((void *)&DestFatBpb, DestFileName) == 0) {
    639     return ;
    640   }
    641   if (ReadFromFile ((void *)&SourceFatBpb, SourceFileName) == 0) {
    642     return ;
    643   }
    644 
    645   DestFatType = GetFatType (&DestFatBpb);
    646   SourceFatType = GetFatType (&SourceFatBpb);
    647 
    648   if (DestFatType != SourceFatType) {
    649     //
    650     // FAT type mismatch
    651     //
    652     if (ForcePatch) {
    653       DebugMsg (NULL, 0, DEBUG_WARN, NULL, "ERROR: E3004: FAT type mismatch: Source - %s, Dest - %s",
    654         FatTypeToString(SourceFatType), FatTypeToString(DestFatType));
    655     } else {
    656       DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3004: FAT type mismatch: Source - %s, Dest - %s",
    657         FatTypeToString(SourceFatType), FatTypeToString(DestFatType));
    658       return ;
    659     }
    660   }
    661 
    662   if (SourceFatType <= FatTypeUnknown || SourceFatType >= FatTypeMax) {
    663     DebugMsg (NULL, 0, DEBUG_ERROR, NULL, "ERROR: E3002: Unknown FAT Type!\n");
    664     return;
    665   }
    666 
    667   //
    668   // Copy BPB/boot data (excluding BS_jmpBoot, BS_OEMName, BootCode and Signature) from SourceFatBpb to DestFatBpb
    669   //
    670   printf ("Patching %s BPB: ", FatTypeToString (SourceFatType));
    671   if (SourceFatType != FatTypeFat32) {
    672     memcpy (
    673       &DestFatBpb.Fat12_16.BPB_BytsPerSec,
    674       &SourceFatBpb.Fat12_16.BPB_BytsPerSec,
    675       ((UINTN)&DestFatBpb.Fat12_16.Reserved - (UINTN)&DestFatBpb.Fat12_16.BPB_BytsPerSec)
    676       );
    677   } else {
    678     memcpy (
    679       &DestFatBpb.Fat32.BPB_BytsPerSec,
    680       &SourceFatBpb.Fat32.BPB_BytsPerSec,
    681       ((UINTN)&DestFatBpb.Fat32.Reserved - (UINTN)&DestFatBpb.Fat32.BPB_BytsPerSec)
    682       );
    683   }
    684 
    685   //
    686   // Set BS_VolLab and BS_FilSysType of DestFatBpb
    687   //
    688   //        BS_VolLab     BS_FilSysType
    689   // FAT12: EFI FAT12     FAT12
    690   // FAT16: EFI FAT16     FAT16
    691   // FAT32: EFI FAT32     FAT32
    692   //
    693   if (SourceFatType == FatTypeFat32) {
    694     memcpy (VolLab, "EFI FAT32  ", sizeof(VolLab));
    695     memcpy (FilSysType, FAT32_FILSYSTYPE, sizeof(FilSysType));
    696   } else if (SourceFatType == FatTypeFat16) {
    697     memcpy (VolLab, "EFI FAT16  ", sizeof(VolLab));
    698     memcpy (FilSysType, FAT16_FILSYSTYPE, sizeof(FilSysType));
    699   } else {
    700     memcpy (VolLab, "EFI FAT12  ", sizeof(VolLab));
    701     memcpy (FilSysType, FAT12_FILSYSTYPE, sizeof(FilSysType));
    702   }
    703   if (SourceFatType != FatTypeFat32) {
    704     memcpy (DestFatBpb.Fat12_16.BS_VolLab, VolLab, sizeof(VolLab));
    705     memcpy (DestFatBpb.Fat12_16.BS_FilSysType, FilSysType, sizeof(FilSysType));
    706   } else {
    707     memcpy (DestFatBpb.Fat32.BS_VolLab, VolLab, sizeof(VolLab));
    708     memcpy (DestFatBpb.Fat32.BS_FilSysType, FilSysType, sizeof(FilSysType));
    709   }
    710 
    711   //
    712   // Set Signature of DestFatBpb to 55AA
    713   //
    714   DestFatBpb.Fat12_16.Signature = FAT_BS_SIGNATURE;
    715 
    716   //
    717   // Write DestFatBpb
    718   //
    719   if (WriteToFile ((void *)&DestFatBpb, DestFileName)) {
    720     printf ("successful!\n");
    721   } else {
    722     printf ("failed!\n");
    723   }
    724 
    725   return ;
    726 }
    727 
    728 void
    729 ParseMbr (
    730   char *FileName
    731   )
    732 {
    733   MASTER_BOOT_RECORD  Mbr;
    734 
    735   if (ReadFromFile ((void *)&Mbr, FileName) == 0) {
    736     return ;
    737   }
    738 
    739   printf ("\nMaster Boot Record:\n");
    740   printf ("\n");
    741   printf ("  Offset Title                        Value\n");
    742   printf ("==================================================================\n");
    743   printf ("  0      Master bootstrap loader code (not list)\n");
    744   printf ("  1B8    Windows disk signature       %08x\n", (unsigned) Mbr.UniqueMbrSignature);
    745   printf ("\n");
    746   printf ("Partition Table Entry #1\n");
    747   printf ("  1BE    80 = active partition        %02x\n", Mbr.PartitionRecord[0].BootIndicator);
    748   printf ("  1BF    Start head                   %02x\n", Mbr.PartitionRecord[0].StartHead);
    749   printf ("  1C0    Start sector                 %02x\n", Mbr.PartitionRecord[0].StartSector);
    750   printf ("  1C1    Start cylinder               %02x\n", Mbr.PartitionRecord[0].StartTrack);
    751   printf ("  1C2    Partition type indicator     %02x\n", Mbr.PartitionRecord[0].OSType);
    752   printf ("  1C3    End head                     %02x\n", Mbr.PartitionRecord[0].EndHead);
    753   printf ("  1C4    End sector                   %02x\n", Mbr.PartitionRecord[0].EndSector);
    754   printf ("  1C5    End cylinder                 %02x\n", Mbr.PartitionRecord[0].EndTrack);
    755   printf ("  1C6    Sectors preceding partition  %08x\n", (unsigned) Mbr.PartitionRecord[0].StartingLBA);
    756   printf ("  1CA    Sectors in partition         %08x\n", (unsigned) Mbr.PartitionRecord[0].SizeInLBA);
    757   printf ("\n");
    758   printf ("Partition Table Entry #2\n");
    759   printf ("  1CE    80 = active partition        %02x\n", Mbr.PartitionRecord[1].BootIndicator);
    760   printf ("  1CF    Start head                   %02x\n", Mbr.PartitionRecord[1].StartHead);
    761   printf ("  1D0    Start sector                 %02x\n", Mbr.PartitionRecord[1].StartSector);
    762   printf ("  1D1    Start cylinder               %02x\n", Mbr.PartitionRecord[1].StartTrack);
    763   printf ("  1D2    Partition type indicator     %02x\n", Mbr.PartitionRecord[1].OSType);
    764   printf ("  1D3    End head                     %02x\n", Mbr.PartitionRecord[1].EndHead);
    765   printf ("  1D4    End sector                   %02x\n", Mbr.PartitionRecord[1].EndSector);
    766   printf ("  1D5    End cylinder                 %02x\n", Mbr.PartitionRecord[1].EndTrack);
    767   printf ("  1D6    Sectors preceding partition  %08x\n", (unsigned) Mbr.PartitionRecord[1].StartingLBA);
    768   printf ("  1DA    Sectors in partition         %08x\n", (unsigned) Mbr.PartitionRecord[1].SizeInLBA);
    769   printf ("\n");
    770   printf ("Partition Table Entry #3\n");
    771   printf ("  1DE    80 = active partition        %02x\n", Mbr.PartitionRecord[2].BootIndicator);
    772   printf ("  1DF    Start head                   %02x\n", Mbr.PartitionRecord[2].StartHead);
    773   printf ("  1E0    Start sector                 %02x\n", Mbr.PartitionRecord[2].StartSector);
    774   printf ("  1E1    Start cylinder               %02x\n", Mbr.PartitionRecord[2].StartTrack);
    775   printf ("  1E2    Partition type indicator     %02x\n", Mbr.PartitionRecord[2].OSType);
    776   printf ("  1E3    End head                     %02x\n", Mbr.PartitionRecord[2].EndHead);
    777   printf ("  1E4    End sector                   %02x\n", Mbr.PartitionRecord[2].EndSector);
    778   printf ("  1E5    End cylinder                 %02x\n", Mbr.PartitionRecord[2].EndTrack);
    779   printf ("  1E6    Sectors preceding partition  %08x\n", (unsigned) Mbr.PartitionRecord[2].StartingLBA);
    780   printf ("  1EA    Sectors in partition         %08x\n", (unsigned) Mbr.PartitionRecord[2].SizeInLBA);
    781   printf ("\n");
    782   printf ("Partition Table Entry #4\n");
    783   printf ("  1EE    80 = active partition        %02x\n", Mbr.PartitionRecord[3].BootIndicator);
    784   printf ("  1EF    Start head                   %02x\n", Mbr.PartitionRecord[3].StartHead);
    785   printf ("  1F0    Start sector                 %02x\n", Mbr.PartitionRecord[3].StartSector);
    786   printf ("  1F1    Start cylinder               %02x\n", Mbr.PartitionRecord[3].StartTrack);
    787   printf ("  1F2    Partition type indicator     %02x\n", Mbr.PartitionRecord[3].OSType);
    788   printf ("  1F3    End head                     %02x\n", Mbr.PartitionRecord[3].EndHead);
    789   printf ("  1F4    End sector                   %02x\n", Mbr.PartitionRecord[3].EndSector);
    790   printf ("  1F5    End cylinder                 %02x\n", Mbr.PartitionRecord[3].EndTrack);
    791   printf ("  1F6    Sectors preceding partition  %08x\n", (unsigned) Mbr.PartitionRecord[3].StartingLBA);
    792   printf ("  1FA    Sectors in partition         %08x\n", (unsigned) Mbr.PartitionRecord[3].SizeInLBA);
    793   printf ("\n");
    794   printf ("  1FE    Signature                    %04x\n", Mbr.Signature);
    795   printf ("\n");
    796 
    797   return ;
    798 }
    799 
    800 void
    801 PatchMbr (
    802   char *DestFileName,
    803   char *SourceFileName
    804   )
    805 {
    806   MASTER_BOOT_RECORD  DestMbr;
    807   MASTER_BOOT_RECORD  SourceMbr;
    808 
    809   if (ReadFromFile ((void *)&DestMbr, DestFileName) == 0) {
    810     return ;
    811   }
    812   if (ReadFromFile ((void *)&SourceMbr, SourceFileName) == 0) {
    813     return ;
    814   }
    815 
    816   if (SourceMbr.Signature != MBR_SIGNATURE) {
    817     printf ("ERROR: E3000: Invalid MBR!\n");
    818     return;
    819   }
    820 
    821   printf ("Patching MBR:\n");
    822   memcpy (
    823     &DestMbr.PartitionRecord[0],
    824     &SourceMbr.PartitionRecord[0],
    825     sizeof(DestMbr.PartitionRecord)
    826     );
    827 
    828   DestMbr.Signature = MBR_SIGNATURE;
    829 
    830 
    831   if (WriteToFile ((void *)&DestMbr, DestFileName)) {
    832     printf ("\tsuccessful!\n");
    833   }
    834 
    835   return ;
    836 }
    837 
    838 
    839 int
    840 main (
    841   int argc,
    842   char *argv[]
    843   )
    844 {
    845   char *SrcImage;
    846   char *DstImage;
    847   BOOLEAN ForcePatch;    // -f
    848   BOOLEAN ProcessMbr;    // -m
    849   BOOLEAN DoParse;       // -p SrcImage or -g SrcImage DstImage
    850   BOOLEAN Verbose;       // -v
    851   UINT64  LogLevel;
    852   EFI_STATUS EfiStatus;
    853 
    854   SrcImage = DstImage = NULL;
    855   ForcePatch = FALSE;
    856   ProcessMbr = FALSE;
    857   DoParse    = TRUE;
    858   Verbose    = FALSE;
    859 
    860   SetUtilityName ("bootsectimage");
    861 
    862   argc--; argv++;
    863 
    864   if (argc == 0) {
    865     Usage ();
    866     return -1;
    867   }
    868 
    869   while (argc != 0) {
    870     if (strcmp (*argv, "-f") == 0 || strcmp (*argv, "--force") == 0) {
    871       ForcePatch = TRUE;
    872     } else if (strcmp (*argv, "-p") == 0 || strcmp (*argv, "--parse") == 0) {
    873       DoParse    = TRUE;
    874       argc--; argv++;
    875       if (argc < 1) {
    876         Usage ();
    877         return -1;
    878       }
    879       SrcImage   = *argv;
    880     } else if (strcmp (*argv, "-g") == 0 || strcmp (*argv, "--patch") == 0) {
    881       DoParse    = FALSE;
    882       argc--; argv++;
    883       if (argc < 2) {
    884         Usage ();
    885         return -1;
    886       }
    887       SrcImage   = *argv;
    888       argc--; argv++;
    889       DstImage   = *argv;
    890     } else if (strcmp (*argv, "-m") == 0 || strcmp (*argv, "--mbr") == 0) {
    891       ProcessMbr = TRUE;
    892     } else if (strcmp (*argv, "-v") == 0 || strcmp (*argv, "--verbose") == 0) {
    893       Verbose    = TRUE;
    894     } else if (strcmp (*argv, "--version") == 0) {
    895       Version();
    896       return 0;
    897     } else if ((stricmp (*argv, "-d") == 0) || (stricmp (*argv, "--debug") == 0)) {
    898       argc--; argv++;
    899       if (argc < 1) {
    900         Usage ();
    901         return -1;
    902       }
    903       EfiStatus = AsciiStringToUint64 (*argv, FALSE, &LogLevel);
    904       if (EFI_ERROR (EfiStatus)) {
    905         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", "--debug", *argv);
    906         return 1;
    907       }
    908       if (LogLevel > 9) {
    909         Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, currnt input level is %d", (int) LogLevel);
    910         return 1;
    911       }
    912       SetPrintLevel (LogLevel);
    913       DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", *argv);
    914     } else {
    915       Usage ();
    916       return -1;
    917     }
    918 
    919     argc--; argv++;
    920   }
    921 
    922   if (ForcePatch && DoParse) {
    923     printf ("ERROR: E1002: Conflicting options: -f, -p. Cannot apply force(-f) to parse(-p)!\n");
    924     Usage ();
    925     return -1;
    926   }
    927   if (ForcePatch && !DoParse && ProcessMbr) {
    928     printf ("ERROR: E1002: Conflicting options: -f, -g -m. Cannot apply force(-f) to processing MBR (-g -m)!\n");
    929     Usage ();
    930     return -1;
    931   }
    932 
    933   if (Verbose) {
    934     SetPrintLevel (VERBOSE_LOG_LEVEL);
    935   } else {
    936     SetPrintLevel (KEY_LOG_LEVEL);
    937   }
    938 
    939   if (DoParse) {
    940     if (ProcessMbr) {
    941       ParseMbr (SrcImage);
    942     } else {
    943       ParseBootSector (SrcImage);
    944     }
    945   } else {
    946     if (ProcessMbr) {
    947       PatchMbr (DstImage, SrcImage);
    948     } else {
    949       PatchBootSector (DstImage, SrcImage, ForcePatch);
    950     }
    951   }
    952 
    953   return 0;
    954 }
    955 
    956