Home | History | Annotate | Download | only in gptfdisk
      1 // fixparts
      2 // Program to fix certain types of damaged Master Boot Record (MBR) partition
      3 // tables
      4 //
      5 // Copyright 2011 by Roderick W. Smith
      6 //
      7 // This program is distributed under the terms of the GNU GPL, as described
      8 // in the COPYING file.
      9 //
     10 // Based on C++ classes originally created for GPT fdisk (gdisk and sgdisk)
     11 // programs
     12 
     13 #include <stdio.h>
     14 #include <string.h>
     15 #include <string>
     16 #include <iostream>
     17 #include <sstream>
     18 #include "basicmbr.h"
     19 #include "support.h"
     20 
     21 using namespace std;
     22 
     23 void DoMBR(BasicMBRData & mbrTable);
     24 
     25 int main(int argc, char* argv[]) {
     26    BasicMBRData mbrTable;
     27    string device;
     28 
     29    cout << "FixParts " << GPTFDISK_VERSION << "\n";
     30 
     31    switch (argc) {
     32       case 1:
     33          cout << "Type device filename, or press <Enter> to exit: ";
     34          device = ReadString();
     35          if (device.length() == 0)
     36             exit(0);
     37          break;
     38       case 2:
     39          device = argv[1];
     40          break;
     41       default:
     42          cerr << "Usage: " << argv[0] << " device_filename\n";
     43          exit(1);
     44    } // switch
     45 
     46    cout << "\nLoading MBR data from " << device << "\n";
     47    if (!mbrTable.ReadMBRData(device)) {
     48       cerr << "\nUnable to read MBR data from '" << device << "'! Exiting!\n\n";
     49       exit(1);
     50    } // if
     51 
     52    // This switch() statement weeds out disks with GPT signatures and non-MBR
     53    // disks so we don't accidentally damage them....
     54    switch(mbrTable.GetValidity()) {
     55       case hybrid: case gpt:
     56          cerr << "\nThis disk appears to be a GPT disk. Use GNU Parted or GPT fdisk on it!\n";
     57          cerr << "Exiting!\n\n";
     58          exit(1);
     59          break;
     60       case invalid:
     61          cerr << "\nCannot find valid MBR data on '" << device << "'! Exiting!\n\n";
     62          exit(1);
     63          break;
     64       case mbr:
     65          DoMBR(mbrTable);
     66          break;
     67       default:
     68          cerr << "\nCannot determine the validity of the disk on '" << device
     69               << "'! Exiting!\n\n";
     70          exit(1);
     71          break;
     72    } // switch()
     73    return 0;
     74 } // main()
     75 
     76 // Do the bulk of the processing on actual MBR disks. First checks for old
     77 // GPT data (note this is different from the earlier check; this one only
     78 // looks for the GPT signatures in the main and backup GPT area, not for
     79 // a protective partition in the MBR, which we know is NOT present, since
     80 // if it were, this function would NOT be called!) and offers to destroy
     81 // it, if found; then makes sure the partitions are in a consistent and
     82 // legal state; then presents the MBR menu and, if it returns a "1" value
     83 // (meaning the user opted to write changes), writes the table to disk.
     84 void DoMBR(BasicMBRData & mbrTable) {
     85    int doItAgain;
     86 
     87    if (mbrTable.CheckForGPT() > 0) {
     88       cout << "\nNOTICE: GPT signatures detected on the disk, but no 0xEE protective "
     89            << "partition!\nThe GPT signatures are probably left over from a previous "
     90            << "partition table.\nDo you want to delete them (if you answer 'Y', this "
     91            << "will happen\nimmediately)? ";
     92       if (GetYN() == 'Y') {
     93          cout << "Erasing GPT data!\n";
     94          if (mbrTable.BlankGPTData() != 1)
     95             cerr << "GPT signature erasure failed!\n";
     96       } // if
     97    } // if
     98 
     99    mbrTable.MakeItLegal();
    100    do {
    101       doItAgain = 0;
    102       if (mbrTable.DoMenu() > 0) {
    103          cout << "\nFinal checks complete. About to write MBR data. THIS WILL OVERWRITE "
    104               << "EXISTING\nPARTITIONS!!\n\nDo you want to proceed? ";
    105          if (GetYN() == 'Y') {
    106             mbrTable.WriteMBRData();
    107             mbrTable.DiskSync();
    108             doItAgain = 0;
    109          } else {
    110             doItAgain = 1;
    111          } // else
    112       } // if
    113    } while (doItAgain);
    114 } // DoMBR()
    115