// fixparts
// Program to fix certain types of damaged Master Boot Record (MBR) partition
// tables
//
// Copyright 2011 by Roderick W. Smith
//
// This program is distributed under the terms of the GNU GPL, as described
// in the COPYING file.
//
// Based on C++ classes originally created for GPT fdisk (gdisk and sgdisk)
// programs
#include <stdio.h>
#include <string.h>
#include <string>
#include <iostream>
#include <sstream>
#include "basicmbr.h"
#include "support.h"
using namespace std;
void DoMBR(BasicMBRData & mbrTable);
int main(int argc, char* argv[]) {
BasicMBRData mbrTable;
string device;
cout << "FixParts " << GPTFDISK_VERSION << "\n";
switch (argc) {
case 1:
cout << "Type device filename, or press <Enter> to exit: ";
device = ReadString();
if (device.length() == 0)
exit(0);
break;
case 2:
device = argv[1];
break;
default:
cerr << "Usage: " << argv[0] << " device_filename\n";
exit(1);
} // switch
cout << "\nLoading MBR data from " << device << "\n";
if (!mbrTable.ReadMBRData(device)) {
cerr << "\nUnable to read MBR data from '" << device << "'! Exiting!\n\n";
exit(1);
} // if
// This switch() statement weeds out disks with GPT signatures and non-MBR
// disks so we don't accidentally damage them....
switch(mbrTable.GetValidity()) {
case hybrid: case gpt:
cerr << "\nThis disk appears to be a GPT disk. Use GNU Parted or GPT fdisk on it!\n";
cerr << "Exiting!\n\n";
exit(1);
break;
case invalid:
cerr << "\nCannot find valid MBR data on '" << device << "'! Exiting!\n\n";
exit(1);
break;
case mbr:
DoMBR(mbrTable);
break;
default:
cerr << "\nCannot determine the validity of the disk on '" << device
<< "'! Exiting!\n\n";
exit(1);
break;
} // switch()
return 0;
} // main()
// Do the bulk of the processing on actual MBR disks. First checks for old
// GPT data (note this is different from the earlier check; this one only
// looks for the GPT signatures in the main and backup GPT area, not for
// a protective partition in the MBR, which we know is NOT present, since
// if it were, this function would NOT be called!) and offers to destroy
// it, if found; then makes sure the partitions are in a consistent and
// legal state; then presents the MBR menu and, if it returns a "1" value
// (meaning the user opted to write changes), writes the table to disk.
void DoMBR(BasicMBRData & mbrTable) {
int doItAgain;
if (mbrTable.CheckForGPT() > 0) {
cout << "\nNOTICE: GPT signatures detected on the disk, but no 0xEE protective "
<< "partition!\nThe GPT signatures are probably left over from a previous "
<< "partition table.\nDo you want to delete them (if you answer 'Y', this "
<< "will happen\nimmediately)? ";
if (GetYN() == 'Y') {
cout << "Erasing GPT data!\n";
if (mbrTable.BlankGPTData() != 1)
cerr << "GPT signature erasure failed!\n";
} // if
} // if
mbrTable.MakeItLegal();
do {
doItAgain = 0;
if (mbrTable.DoMenu() > 0) {
cout << "\nFinal checks complete. About to write MBR data. THIS WILL OVERWRITE "
<< "EXISTING\nPARTITIONS!!\n\nDo you want to proceed? ";
if (GetYN() == 'Y') {
mbrTable.WriteMBRData();
mbrTable.DiskSync();
doItAgain = 0;
} else {
doItAgain = 1;
} // else
} // if
} while (doItAgain);
} // DoMBR()