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