/** @file
Reading/writing MBR/DBR.
  NOTE:
    If we write MBR to disk, we just update the MBR code and the partition table wouldn't be over written.
    If we process DBR, we will patch MBR to set first partition active if no active partition exists.

Copyright (c) 2006 - 2018, 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 <windows.h>
#include <stdio.h>
#include <string.h>
#include <Common/UefiBaseTypes.h>

#include "ParseInf.h"
#include "EfiUtilityMsgs.h"
#include "CommonLib.h"

//
// Utility Name
//
#define UTILITY_NAME  "GenBootSector"

//
// Utility version information
//
#define UTILITY_MAJOR_VERSION 0
#define UTILITY_MINOR_VERSION 2

#define MAX_DRIVE                             26
#define PARTITION_TABLE_OFFSET                0x1BE

#define SIZE_OF_PARTITION_ENTRY               0x10

#define PARTITION_ENTRY_STARTLBA_OFFSET       8

#define PARTITION_ENTRY_NUM                   4

INT
GetDrvNumOffset (
  IN VOID *BootSector
  );

typedef enum {
  PatchTypeUnknown,
  PatchTypeFloppy,
  PatchTypeIde,
  PatchTypeUsb,
  PatchTypeFileImage   // input and output are all file image, patching action is same as PatchTypeFloppy
} PATCH_TYPE;

typedef enum {
  PathUnknown,
  PathFile,
  PathFloppy,
  PathUsb,
  PathIde
} PATH_TYPE;

typedef enum {
  ErrorSuccess,
  ErrorFileCreate,
  ErrorFileReadWrite,
  ErrorNoMbr,
  ErrorFatType,
  ErrorPath,
} ERROR_STATUS;

CHAR *ErrorStatusDesc[] = {
  "Success",
  "Failed to create files",
  "Failed to read/write files",
  "No MBR exists",
  "Failed to detect Fat type",
  "Inavlid path"
};

typedef struct _DRIVE_TYPE_DESC {
  UINT  Type;
  CHAR  *Description;
} DRIVE_TYPE_DESC;

#define DRIVE_TYPE_ITEM(x) {x, #x}
DRIVE_TYPE_DESC DriveTypeDesc[] = {
  DRIVE_TYPE_ITEM (DRIVE_UNKNOWN),
  DRIVE_TYPE_ITEM (DRIVE_NO_ROOT_DIR),
  DRIVE_TYPE_ITEM (DRIVE_REMOVABLE),
  DRIVE_TYPE_ITEM (DRIVE_FIXED),
  DRIVE_TYPE_ITEM (DRIVE_REMOTE),
  DRIVE_TYPE_ITEM (DRIVE_CDROM),
  DRIVE_TYPE_ITEM (DRIVE_RAMDISK),
  (UINT) -1, NULL
};

typedef struct _DRIVE_INFO {
  CHAR              VolumeLetter;
  DRIVE_TYPE_DESC   *DriveType;
  UINT              DiskNumber;
} DRIVE_INFO;

typedef struct _PATH_INFO {
  CHAR             *Path;
  CHAR             PhysicalPath[260];
  PATH_TYPE        Type;
  BOOL             Input;
} PATH_INFO;

#define BOOT_SECTOR_LBA_OFFSET 0x1FA

#define IsLetter(x) (((x) >= 'a' && (x) <= 'z') || ((x) >= 'A' && (x) <= 'Z'))

BOOL
GetDriveInfo (
  CHAR       VolumeLetter,
  DRIVE_INFO *DriveInfo
  )
/*++
Routine Description:
  Get drive information including disk number and drive type,
  where disknumber is useful for reading/writing disk raw data.
  NOTE: Floppy disk doesn't have disk number but it doesn't matter because
        we can reading/writing floppy disk without disk number.

Arguments:
  VolumeLetter : volume letter, e.g.: C for C:, A for A:
  DriveInfo    : pointer to DRIVE_INFO structure receiving drive information.

Return:
  TRUE  : successful
  FALSE : failed
--*/
{
  HANDLE                  VolumeHandle;
  STORAGE_DEVICE_NUMBER   StorageDeviceNumber;
  DWORD                   BytesReturned;
  BOOL                    Success;
  UINT                    DriveType;
  UINT                    Index;

  CHAR RootPath[]         = "X:\\";       // "X:\"  -> for GetDriveType
  CHAR VolumeAccessPath[] = "\\\\.\\X:";  // "\\.\X:"  -> to open the volume

  RootPath[0] = VolumeAccessPath[4] = VolumeLetter;
  DriveType = GetDriveType(RootPath);
  if (DriveType != DRIVE_REMOVABLE && DriveType != DRIVE_FIXED) {
    return FALSE;
  }

  DriveInfo->VolumeLetter = VolumeLetter;
  VolumeHandle = CreateFile (
                   VolumeAccessPath,
                   0,
                   FILE_SHARE_READ | FILE_SHARE_WRITE,
                   NULL,
                   OPEN_EXISTING,
                   0,
                   NULL
                   );
  if (VolumeHandle == INVALID_HANDLE_VALUE) {
    fprintf (
      stderr,
      "error E0005: CreateFile failed: Volume = %s, LastError = 0x%lx\n",
      VolumeAccessPath,
      GetLastError ()
      );
    return FALSE;
  }

  //
  // Get Disk Number. It should fail when operating on floppy. That's ok
  //  because Disk Number is only needed when operating on Hard or USB disk.
  //
  // To direct write to disk:
  //   for USB and HD: use path = \\.\PHYSICALDRIVEx, where x is Disk Number
  //   for floppy:     use path = \\.\X:, where X can be A or B
  //
  Success = DeviceIoControl(
              VolumeHandle,
              IOCTL_STORAGE_GET_DEVICE_NUMBER,
              NULL,
              0,
              &StorageDeviceNumber,
              sizeof(StorageDeviceNumber),
              &BytesReturned,
              NULL
              );
  //
  // DeviceIoControl should fail if Volume is floppy or network drive.
  //
  if (!Success) {
    DriveInfo->DiskNumber = (UINT) -1;
  } else if (StorageDeviceNumber.DeviceType != FILE_DEVICE_DISK) {
    //
    // Only care about the disk.
    //
    CloseHandle(VolumeHandle);
    return FALSE;
  } else{
    DriveInfo->DiskNumber = StorageDeviceNumber.DeviceNumber;
  }
  CloseHandle(VolumeHandle);

  //
  // Fill in the type string
  //
  DriveInfo->DriveType = NULL;
  for (Index = 0; DriveTypeDesc[Index].Description != NULL; Index ++) {
    if (DriveType == DriveTypeDesc[Index].Type) {
      DriveInfo->DriveType = &DriveTypeDesc[Index];
      break;
    }
  }

  if (DriveInfo->DriveType == NULL) {
    //
    // Should have a type.
    //
    fprintf (stderr, "error E3005: Fatal Error!!!\n");
    return FALSE;
  }
  return TRUE;
}

VOID
ListDrive (
  VOID
  )
/*++
Routine Description:
  List every drive in current system and their information.

--*/
{
  UINT       Index;
  DRIVE_INFO DriveInfo;

  UINT Mask =  GetLogicalDrives();

  for (Index = 0; Index < MAX_DRIVE; Index++) {
    if (((Mask >> Index) & 0x1) == 1) {
      if (GetDriveInfo ('A' + (CHAR) Index, &DriveInfo)) {
        if (Index < 2) {
          // Floppy will occupy 'A' and 'B'
          fprintf (
            stdout,
            "%c: - Type: %s\n",
            DriveInfo.VolumeLetter,
            DriveInfo.DriveType->Description
            );
        } else {
          fprintf (
            stdout,
            "%c: - DiskNum: %u, Type: %s\n",
            DriveInfo.VolumeLetter,
            (unsigned) DriveInfo.DiskNumber,
            DriveInfo.DriveType->Description
            );
        }
      }
    }
  }

}

INT
GetBootSectorOffset (
  HANDLE     DiskHandle,
  PATH_INFO  *PathInfo
  )
/*++
Description:
  Get the offset of boot sector.
  For non-MBR disk, offset is just 0
  for disk with MBR, offset needs to be calculated by parsing MBR

  NOTE: if no one is active, we will patch MBR to select first partition as active.

Arguments:
  DiskHandle  : HANDLE of disk
  PathInfo    : PATH_INFO structure.
  WriteToDisk : TRUE indicates writing

Return:
  -1   : failed
  o.w. : Offset to boot sector
--*/
{
  BYTE    DiskPartition[0x200];
  DWORD   BytesReturn;
  DWORD   DbrOffset;
  DWORD   Index;
  BOOL    HasMbr;

  DbrOffset = 0;
  HasMbr    = FALSE;

  SetFilePointer(DiskHandle, 0, NULL, FILE_BEGIN);
  if (!ReadFile (DiskHandle, DiskPartition, 0x200, &BytesReturn, NULL)) {
    return -1;
  }

  //
  // Check Signature, Jmp, and Boot Indicator.
  // if all pass, we assume MBR found.
  //

  // Check Signature: 55AA
  if ((DiskPartition[0x1FE] == 0x55) && (DiskPartition[0x1FF] == 0xAA)) {
    // Check Jmp: (EB ?? 90) or (E9 ?? ??)
    if (((DiskPartition[0] != 0xEB) || (DiskPartition[2] != 0x90)) &&
        (DiskPartition[0] != 0xE9)) {
      // Check Boot Indicator: 0x00 or 0x80
      // Boot Indicator is the first byte of Partition Entry
      HasMbr = TRUE;
      for (Index = 0; Index < PARTITION_ENTRY_NUM; ++Index) {
        if ((DiskPartition[PARTITION_TABLE_OFFSET + Index * SIZE_OF_PARTITION_ENTRY] & 0x7F) != 0) {
          HasMbr = FALSE;
          break;
        }
      }
    }
  }

  if (HasMbr) {
    //
    // Skip MBR
    //
    for (Index = 0; Index < PARTITION_ENTRY_NUM; Index++) {
      //
      // Found Boot Indicator.
      //
      if (DiskPartition[PARTITION_TABLE_OFFSET + (Index * SIZE_OF_PARTITION_ENTRY)] == 0x80) {
        DbrOffset = *(DWORD *)&DiskPartition[PARTITION_TABLE_OFFSET + (Index * SIZE_OF_PARTITION_ENTRY) + PARTITION_ENTRY_STARTLBA_OFFSET];
        break;
      }
    }
    //
    // If no boot indicator, we manually select 1st partition, and patch MBR.
    //
    if (Index == PARTITION_ENTRY_NUM) {
      DbrOffset = *(DWORD *)&DiskPartition[PARTITION_TABLE_OFFSET + PARTITION_ENTRY_STARTLBA_OFFSET];
      if (!PathInfo->Input && (PathInfo->Type == PathUsb)) {
        SetFilePointer(DiskHandle, 0, NULL, FILE_BEGIN);
        DiskPartition[PARTITION_TABLE_OFFSET] = 0x80;
        WriteFile (DiskHandle, DiskPartition, 0x200, &BytesReturn, NULL);
      }
    }
  }

  return DbrOffset;
}

/**
 * Get window file handle for input/ouput disk/file.
 *
 * @param PathInfo
 * @param ProcessMbr
 * @param FileHandle
 *
 * @return ERROR_STATUS
 */
ERROR_STATUS
GetFileHandle (
  PATH_INFO  *PathInfo,
  BOOL       ProcessMbr,
  HANDLE     *FileHandle,
  DWORD      *DbrOffset
  )
{
  DWORD  OpenFlag;

  OpenFlag = OPEN_ALWAYS;
  if (PathInfo->Input || PathInfo->Type != PathFile) {
    OpenFlag = OPEN_EXISTING;
  }

  *FileHandle = CreateFile(
                   PathInfo->PhysicalPath,
                   GENERIC_READ | GENERIC_WRITE,
                   FILE_SHARE_READ,
                   NULL,
                   OpenFlag,
                   FILE_ATTRIBUTE_NORMAL,
                   NULL
                   );
  if (*FileHandle == INVALID_HANDLE_VALUE) {
    return ErrorFileCreate;
  }

  if ((PathInfo->Type == PathIde) || (PathInfo->Type == PathUsb)){
    *DbrOffset = GetBootSectorOffset (*FileHandle, PathInfo);
    if (!ProcessMbr) {
      //
      // 1. Process boot sector, set file pointer to the beginning of boot sector
      //
      SetFilePointer (*FileHandle, *DbrOffset * 0x200, NULL, FILE_BEGIN);
    } else if(*DbrOffset == 0) {
      //
      // If user want to process Mbr, but no Mbr exists, simply return FALSE
      //
      return ErrorNoMbr;
    } else {
      //
      // 2. Process MBR, set file pointer to 0
      //
      SetFilePointer (*FileHandle, 0, NULL, FILE_BEGIN);
    }
  }

  return ErrorSuccess;
}

/**
  Writing or reading boot sector or MBR according to the argument.

  @param InputInfo PATH_INFO instance for input path
  @param OutputInfo PATH_INFO instance for output path
  @param ProcessMbr TRUE is to process MBR, otherwise, processing boot sector

  @return ERROR_STATUS
 **/
ERROR_STATUS
ProcessBsOrMbr (
  PATH_INFO     *InputInfo,
  PATH_INFO     *OutputInfo,
  BOOL          ProcessMbr
  )
{
  BYTE              DiskPartition[0x200] = {0};
  BYTE              DiskPartitionBackup[0x200] = {0};
  DWORD             BytesReturn;
  INT               DrvNumOffset;
  HANDLE            InputHandle = INVALID_HANDLE_VALUE;
  HANDLE            OutputHandle = INVALID_HANDLE_VALUE;
  ERROR_STATUS      Status;
  DWORD             InputDbrOffset;
  DWORD             OutputDbrOffset;

  //
  // Create file Handle and move file Pointer is pointed to beginning of Mbr or Dbr
  //
  Status =  GetFileHandle(InputInfo, ProcessMbr, &InputHandle, &InputDbrOffset);
  if (Status != ErrorSuccess) {
    goto Done;
  }

  //
  // Create file Handle and move file Pointer is pointed to beginning of Mbr or Dbr
  //
  Status = GetFileHandle(OutputInfo, ProcessMbr, &OutputHandle, &OutputDbrOffset);
  if (Status != ErrorSuccess) {
    goto Done;
  }

  //
  // Read boot sector from source disk/file
  //
  if (!ReadFile (InputHandle, DiskPartition, 0x200, &BytesReturn, NULL)) {
    Status = ErrorFileReadWrite;
    goto Done;
  }

  if (InputInfo->Type == PathUsb) {
      // Manually set BS_DrvNum to 0x80 as window's format.exe has a bug which will clear this field discarding USB disk's MBR.
      // offset of BS_DrvNum is 0x24 for FAT12/16
      //                        0x40 for FAT32
      //
      DrvNumOffset = GetDrvNumOffset (DiskPartition);
      if (DrvNumOffset == -1) {
        Status = ErrorFatType;
        goto Done;
      }
      //
      // Some legacy BIOS require 0x80 discarding MBR.
      // Question left here: is it needed to check Mbr before set 0x80?
      //
      DiskPartition[DrvNumOffset] = ((InputDbrOffset > 0) ? 0x80 : 0);
  }

  if (InputInfo->Type == PathIde) {
      //
      // Patch LBAOffsetForBootSector
      //
      *(DWORD *)&DiskPartition [BOOT_SECTOR_LBA_OFFSET] = InputDbrOffset;
  }

  if (OutputInfo->Type != PathFile) {
    if (ProcessMbr) {
      //
      // Use original partition table
      //
      if (!ReadFile (OutputHandle, DiskPartitionBackup, 0x200, &BytesReturn, NULL)) {
        Status = ErrorFileReadWrite;
        goto Done;
      }
      memcpy (DiskPartition + 0x1BE, DiskPartitionBackup + 0x1BE, 0x40);
      SetFilePointer (OutputHandle, 0, NULL, FILE_BEGIN);

    }
  }

  //
  // Write boot sector to taget disk/file
  //
  if (!WriteFile (OutputHandle, DiskPartition, 0x200, &BytesReturn, NULL)) {
    Status = ErrorFileReadWrite;
    goto Done;
  }

Done:
  if (InputHandle != INVALID_HANDLE_VALUE) {
    CloseHandle (InputHandle);
  }
  if (OutputHandle != INVALID_HANDLE_VALUE) {
    CloseHandle (OutputHandle);
  }

  return Status;
}

void
Version (
  void
  )
/*++

Routine Description:

  Displays the standard utility information to SDTOUT

Arguments:

  None

Returns:

  None

--*/
{
  printf ("%s Version %d.%d %s\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
}

VOID
PrintUsage (
  void
  )
{
  printf ("Usage: GenBootSector [options] --cfg-file CFG_FILE\n\n\
Copyright (c) 2009 - 2018, Intel Corporation.  All rights reserved.\n\n\
  Utility to retrieve and update the boot sector or MBR.\n\n\
optional arguments:\n\
  -h, --help            Show this help message and exit\n\
  --version             Show program's version number and exit\n\
  -d [DEBUG], --debug [DEBUG]\n\
                        Output DEBUG statements, where DEBUG_LEVEL is 0 (min)\n\
                        - 9 (max)\n\
  -v, --verbose         Print informational statements\n\
  -q, --quiet           Returns the exit code, error messages will be\n\
                        displayed\n\
  -s, --silent          Returns only the exit code; informational and error\n\
                        messages are not displayed\n\
  -l, --list            List disk drives\n\
  -i INPUT_FILENAME, --input INPUT_FILENAME\n\
                        Input file name\n\
  -o OUTPUT_FILENAME, --output OUTPUT_FILENAME\n\
                        Output file name\n\
  -m, --mbr             Also process the MBR\n\
  --sfo                 Reserved for future use\n");

}

/**
  Get path information, including physical path for windows platform.

  @param PathInfo   Point to PATH_INFO structure.

  @return whether path is valid.
**/
ERROR_STATUS
GetPathInfo (
  PATH_INFO   *PathInfo
  )
{
  DRIVE_INFO  DriveInfo;
  CHAR        VolumeLetter;
  CHAR        DiskPathTemplate[]   = "\\\\.\\PHYSICALDRIVE%u";
  CHAR        FloppyPathTemplate[] = "\\\\.\\%c:";
  FILE        *f;

  //
  // If path is disk path
  //
  if (IsLetter(PathInfo->Path[0]) && (PathInfo->Path[1] == ':') && (PathInfo->Path[2] == '\0')) {
    VolumeLetter = PathInfo->Path[0];
    if ((VolumeLetter == 'A') || (VolumeLetter == 'a') ||
        (VolumeLetter == 'B') || (VolumeLetter == 'b')) {
      PathInfo->Type = PathFloppy;
      sprintf (PathInfo->PhysicalPath, FloppyPathTemplate, VolumeLetter);
      return ErrorSuccess;
    }

    if (!GetDriveInfo(VolumeLetter, &DriveInfo)) {
      fprintf (stderr, "ERROR: GetDriveInfo - 0x%lx\n", GetLastError ());
      return ErrorPath;
    }

    if (!PathInfo->Input && (DriveInfo.DriveType->Type == DRIVE_FIXED)) {
      fprintf (stderr, "ERROR: Could patch own IDE disk!\n");
      return ErrorPath;
    }

    sprintf(PathInfo->PhysicalPath, DiskPathTemplate, DriveInfo.DiskNumber);
    if (DriveInfo.DriveType->Type == DRIVE_REMOVABLE) {
      PathInfo->Type = PathUsb;
    } else if (DriveInfo.DriveType->Type == DRIVE_FIXED) {
      PathInfo->Type = PathIde;
    } else {
      fprintf (stderr, "ERROR, Invalid disk path - %s", PathInfo->Path);
      return ErrorPath;
    }

  return ErrorSuccess;
  }

  //
  // Check the path length
  //
  if (strlen (PathInfo->Path) >= (sizeof (PathInfo->PhysicalPath) / sizeof (PathInfo->PhysicalPath[0]))) {
    fprintf (stderr, "ERROR, Path is too long for - %s", PathInfo->Path);
    return ErrorPath;
  }

  PathInfo->Type = PathFile;
  if (PathInfo->Input) {
    //
    // If path is file path, check whether file is valid.
    //
    f = fopen (LongFilePath (PathInfo->Path), "r");
    if (f == NULL) {
      fprintf (stderr, "error E2003: File was not provided!\n");
      return ErrorPath;
    }
    fclose (f);
  }
  PathInfo->Type = PathFile;
  strncpy(
    PathInfo->PhysicalPath,
    PathInfo->Path,
    sizeof (PathInfo->PhysicalPath) / sizeof (PathInfo->PhysicalPath[0]) - 1
    );
  PathInfo->PhysicalPath[sizeof (PathInfo->PhysicalPath) / sizeof (PathInfo->PhysicalPath[0]) - 1] = 0;

  return ErrorSuccess;
}

INT
main (
  INT  argc,
  CHAR *argv[]
  )
{
  CHAR8         *AppName;
  INTN          Index;
  BOOLEAN       ProcessMbr;
  ERROR_STATUS  Status;
  EFI_STATUS    EfiStatus;
  PATH_INFO     InputPathInfo = {0};
  PATH_INFO     OutputPathInfo = {0};
  UINT64        LogLevel;

  SetUtilityName (UTILITY_NAME);

  AppName = *argv;
  argv ++;
  argc --;

  ProcessMbr    = FALSE;

  if (argc == 0) {
    PrintUsage();
    return 0;
  }

  //
  // Parse command line
  //
  for (Index = 0; Index < argc; Index ++) {
    if ((stricmp (argv[Index], "-l") == 0) || (stricmp (argv[Index], "--list") == 0)) {
      ListDrive ();
      return 0;
    }

    if ((stricmp (argv[Index], "-m") == 0) || (stricmp (argv[Index], "--mbr") == 0)) {
      ProcessMbr = TRUE;
      continue;
    }

    if ((stricmp (argv[Index], "-i") == 0) || (stricmp (argv[Index], "--input") == 0)) {
      InputPathInfo.Path  = argv[Index + 1];
      InputPathInfo.Input = TRUE;
      if (InputPathInfo.Path == NULL) {
        Error (NULL, 0, 1003, "Invalid option value", "Input file name can't be NULL");
        return 1;
      }
      if (InputPathInfo.Path[0] == '-') {
        Error (NULL, 0, 1003, "Invalid option value", "Input file is missing");
        return 1;
      }
      ++Index;
      continue;
    }

    if ((stricmp (argv[Index], "-o") == 0) || (stricmp (argv[Index], "--output") == 0)) {
      OutputPathInfo.Path  = argv[Index + 1];
      OutputPathInfo.Input = FALSE;
      if (OutputPathInfo.Path == NULL) {
        Error (NULL, 0, 1003, "Invalid option value", "Output file name can't be NULL");
        return 1;
      }
      if (OutputPathInfo.Path[0] == '-') {
        Error (NULL, 0, 1003, "Invalid option value", "Output file is missing");
        return 1;
      }
      ++Index;
      continue;
    }

    if ((stricmp (argv[Index], "-h") == 0) || (stricmp (argv[Index], "--help") == 0)) {
      PrintUsage ();
      return 0;
    }

    if (stricmp (argv[Index], "--version") == 0) {
      Version ();
      return 0;
    }

    if ((stricmp (argv[Index], "-v") == 0) || (stricmp (argv[Index], "--verbose") == 0)) {
      continue;
    }

    if ((stricmp (argv[Index], "-q") == 0) || (stricmp (argv[Index], "--quiet") == 0)) {
      continue;
    }

    if ((stricmp (argv[Index], "-d") == 0) || (stricmp (argv[Index], "--debug") == 0)) {
      EfiStatus = AsciiStringToUint64 (argv[Index + 1], FALSE, &LogLevel);
      if (EFI_ERROR (EfiStatus)) {
        Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[Index], argv[Index + 1]);
        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[Index + 1]);
      ++Index;
      continue;
    }

    //
    // Don't recognize the parameter.
    //
    Error (NULL, 0, 1000, "Unknown option", "%s", argv[Index]);
    return 1;
  }

  if (InputPathInfo.Path == NULL) {
    Error (NULL, 0, 1001, "Missing options", "Input file is missing");
    return 1;
  }

  if (OutputPathInfo.Path == NULL) {
    Error (NULL, 0, 1001, "Missing options", "Output file is missing");
    return 1;
  }

  if (GetPathInfo(&InputPathInfo) != ErrorSuccess) {
    Error (NULL, 0, 1003, "Invalid option value", "Input file can't be found.");
    return 1;
  }

  if (GetPathInfo(&OutputPathInfo) != ErrorSuccess) {
    Error (NULL, 0, 1003, "Invalid option value", "Output file can't be found.");
    return 1;
  }

  //
  // Process DBR (Patch or Read)
  //
  Status = ProcessBsOrMbr (&InputPathInfo, &OutputPathInfo, ProcessMbr);

  if (Status == ErrorSuccess) {
    fprintf (
      stdout,
      "%s %s: successful!\n",
      (OutputPathInfo.Type != PathFile) ? "Write" : "Read",
      ProcessMbr ? "MBR" : "DBR"
      );
    return 0;
  } else {
    fprintf (
      stderr,
      "%s: %s %s: failed - %s (LastError: 0x%lx)!\n",
      (Status == ErrorNoMbr) ? "WARNING" : "ERROR",
      (OutputPathInfo.Type != PathFile) ? "Write" : "Read",
      ProcessMbr ? "MBR" : "DBR",
      ErrorStatusDesc[Status],
      GetLastError ()
      );
    return 1;
  }
}
