| // 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() |