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