srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 1 | // gdisk.cc |
| 2 | // Program modelled after Linux fdisk, but it manipulates GPT partitions |
| 3 | // rather than MBR partitions. |
| 4 | // |
srs5694 | e4ac11e | 2009-08-31 10:13:04 -0400 | [diff] [blame] | 5 | // by Rod Smith, project began February 2009 |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 6 | |
srs5694 | 1e09372 | 2010-01-05 00:14:19 -0500 | [diff] [blame] | 7 | /* This program is copyright (c) 2009, 2010 by Roderick W. Smith. It is distributed |
srs5694 | 221e087 | 2009-08-29 15:00:31 -0400 | [diff] [blame] | 8 | under the terms of the GNU GPL version 2, as detailed in the COPYING file. */ |
| 9 | |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 10 | //#include <iostream> |
| 11 | #include <stdio.h> |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 12 | #include <getopt.h> |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 13 | #include <string.h> |
| 14 | #include <string> |
| 15 | #include <iostream> |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 16 | #include "mbr.h" |
| 17 | #include "gpt.h" |
| 18 | #include "support.h" |
| 19 | |
| 20 | // Function prototypes.... |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 21 | void MainMenu(string filename, struct GPTData* theGPT); |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 22 | void ShowCommands(void); |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 23 | void ExpertsMenu(string filename, struct GPTData* theGPT); |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 24 | void ShowExpertCommands(void); |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 25 | void RecoveryMenu(string filename, struct GPTData* theGPT); |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 26 | void ShowRecoveryCommands(void); |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 27 | |
| 28 | int main(int argc, char* argv[]) { |
| 29 | GPTData theGPT; |
| 30 | int doMore = 1; |
| 31 | char* device = NULL; |
| 32 | |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 33 | cout << "GPT fdisk (gdisk) version " << GPTFDISK_VERSION << "\n\n"; |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 34 | |
| 35 | if (argc == 2) { // basic usage |
| 36 | if (SizesOK()) { |
| 37 | doMore = theGPT.LoadPartitions(argv[1]); |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 38 | if (doMore) { |
| 39 | MainMenu(argv[1], &theGPT); |
| 40 | } // if (doMore) |
| 41 | } // if (SizesOK()) |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 42 | } else if (argc == 3) { // usage with "-l" option |
| 43 | if (SizesOK()) { |
| 44 | if (strcmp(argv[1], "-l") == 0) { |
| 45 | device = argv[2]; |
| 46 | } else if (strcmp(argv[2], "-l") == 0) { |
| 47 | device = argv[1]; |
| 48 | } else { // 3 arguments, but none is "-l" |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 49 | cerr << "Usage: " << argv[0] << " [-l] device_file\n"; |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 50 | } // if/elseif/else |
| 51 | if (device != NULL) { |
srs5694 | 5d58fe0 | 2010-01-03 20:57:08 -0500 | [diff] [blame] | 52 | theGPT.JustLooking(); |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 53 | doMore = theGPT.LoadPartitions((string) device); |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 54 | if (doMore) theGPT.DisplayGPTData(); |
| 55 | } // if |
| 56 | } // if |
| 57 | } else { |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 58 | cerr << "Usage: " << argv[0] << " [-l] device_file\n"; |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 59 | } // if/else |
| 60 | } // main |
| 61 | |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 62 | // Accept a command and execute it. Returns only when the user |
| 63 | // wants to exit (such as after a 'w' or 'q' command). |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 64 | void MainMenu(string filename, struct GPTData* theGPT) { |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 65 | char command, line[255], buFile[255]; |
srs5694 | 5d58fe0 | 2010-01-03 20:57:08 -0500 | [diff] [blame] | 66 | char* junk; |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 67 | int goOn = 1; |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 68 | PartTypes typeHelper; |
| 69 | uint32_t temp1, temp2; |
| 70 | |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 71 | do { |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 72 | cout << "\nCommand (? for help): "; |
srs5694 | 5d58fe0 | 2010-01-03 20:57:08 -0500 | [diff] [blame] | 73 | junk = fgets(line, 255, stdin); |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 74 | sscanf(line, "%c", &command); |
| 75 | switch (command) { |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 76 | case '\n': |
| 77 | break; |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 78 | case 'b': case 'B': |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 79 | cout << "Enter backup filename to save: "; |
srs5694 | 5d58fe0 | 2010-01-03 20:57:08 -0500 | [diff] [blame] | 80 | junk = fgets(line, 255, stdin); |
| 81 | sscanf(line, "%s", (char*) &buFile); |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 82 | theGPT->SaveGPTBackup(buFile); |
| 83 | break; |
| 84 | case 'c': case 'C': |
| 85 | if (theGPT->GetPartRange(&temp1, &temp2) > 0) |
| 86 | theGPT->SetName(theGPT->GetPartNum()); |
| 87 | else |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 88 | cout << "No partitions\n"; |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 89 | break; |
| 90 | case 'd': case 'D': |
| 91 | theGPT->DeletePartition(); |
| 92 | break; |
| 93 | case 'i': case 'I': |
| 94 | theGPT->ShowDetails(); |
| 95 | break; |
| 96 | case 'l': case 'L': |
| 97 | typeHelper.ShowTypes(); |
| 98 | break; |
| 99 | case 'n': case 'N': |
| 100 | theGPT->CreatePartition(); |
| 101 | break; |
| 102 | case 'o': case 'O': |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 103 | cout << "This option deletes all partitions and creates a new protective MBR.\n" |
| 104 | << "Proceed? "; |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 105 | if (GetYN() == 'Y') { |
| 106 | theGPT->ClearGPTData(); |
| 107 | theGPT->MakeProtectiveMBR(); |
| 108 | } // if |
| 109 | break; |
| 110 | case 'p': case 'P': |
| 111 | theGPT->DisplayGPTData(); |
| 112 | break; |
| 113 | case 'q': case 'Q': |
| 114 | goOn = 0; |
| 115 | break; |
| 116 | case 'r': case 'R': |
| 117 | RecoveryMenu(filename, theGPT); |
| 118 | goOn = 0; |
| 119 | break; |
| 120 | case 's': case 'S': |
| 121 | theGPT->SortGPT(); |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 122 | cout << "You may need to edit /etc/fstab and/or your boot loader configuration!\n"; |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 123 | break; |
| 124 | case 't': case 'T': |
| 125 | theGPT->ChangePartType(); |
| 126 | break; |
| 127 | case 'v': case 'V': |
srs5694 | 546a9c7 | 2010-01-26 16:00:26 -0500 | [diff] [blame] | 128 | theGPT->Verify(); |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 129 | break; |
| 130 | case 'w': case 'W': |
| 131 | if (theGPT->SaveGPTData() == 1) |
| 132 | goOn = 0; |
| 133 | break; |
| 134 | case 'x': case 'X': |
| 135 | ExpertsMenu(filename, theGPT); |
| 136 | goOn = 0; |
| 137 | break; |
| 138 | default: |
| 139 | ShowCommands(); |
| 140 | break; |
| 141 | } // switch |
| 142 | } while (goOn); |
| 143 | } // MainMenu() |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 144 | |
| 145 | void ShowCommands(void) { |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 146 | cout << "b\tback up GPT data to a file\n"; |
| 147 | cout << "c\tchange a partition's name\n"; |
| 148 | cout << "d\tdelete a partition\n"; |
| 149 | cout << "i\tshow detailed information on a partition\n"; |
| 150 | cout << "l\tlist known partition types\n"; |
| 151 | cout << "n\tadd a new partition\n"; |
| 152 | cout << "o\tcreate a new empty GUID partition table (GPT)\n"; |
| 153 | cout << "p\tprint the partition table\n"; |
| 154 | cout << "q\tquit without saving changes\n"; |
| 155 | cout << "r\trecovery and transformation options (experts only)\n"; |
| 156 | cout << "s\tsort partitions\n"; |
| 157 | cout << "t\tchange a partition's type code\n"; |
| 158 | cout << "v\tverify disk\n"; |
| 159 | cout << "w\twrite table to disk and exit\n"; |
| 160 | cout << "x\textra functionality (experts only)\n"; |
| 161 | cout << "?\tprint this menu\n"; |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 162 | } // ShowCommands() |
| 163 | |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 164 | // Accept a recovery & transformation menu command. Returns only when the user |
| 165 | // issues an exit command, such as 'w' or 'q'. |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 166 | void RecoveryMenu(string filename, struct GPTData* theGPT) { |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 167 | char command, line[255], buFile[255]; |
srs5694 | 5d58fe0 | 2010-01-03 20:57:08 -0500 | [diff] [blame] | 168 | char* junk; |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 169 | PartTypes typeHelper; |
| 170 | uint32_t temp1; |
| 171 | int goOn = 1; |
| 172 | |
| 173 | do { |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 174 | cout << "\nRecovery/transformation command (? for help): "; |
srs5694 | 5d58fe0 | 2010-01-03 20:57:08 -0500 | [diff] [blame] | 175 | junk = fgets(line, 255, stdin); |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 176 | sscanf(line, "%c", &command); |
| 177 | switch (command) { |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 178 | case '\n': |
| 179 | break; |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 180 | case 'b': case 'B': |
| 181 | theGPT->RebuildMainHeader(); |
| 182 | break; |
| 183 | case 'c': case 'C': |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 184 | cout << "Warning! This will probably do weird things if you've converted an MBR to\n" |
| 185 | << "GPT form and haven't yet saved the GPT! Proceed? "; |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 186 | if (GetYN() == 'Y') |
| 187 | theGPT->LoadSecondTableAsMain(); |
| 188 | break; |
| 189 | case 'd': case 'D': |
| 190 | theGPT->RebuildSecondHeader(); |
| 191 | break; |
| 192 | case 'e': case 'E': |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 193 | cout << "Warning! This will probably do weird things if you've converted an MBR to\n" |
| 194 | << "GPT form and haven't yet saved the GPT! Proceed? "; |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 195 | if (GetYN() == 'Y') |
| 196 | theGPT->LoadMainTable(); |
| 197 | break; |
| 198 | case 'f': case 'F': |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 199 | cout << "Warning! This will destroy the currently defined partitions! Proceed? "; |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 200 | if (GetYN() == 'Y') { |
| 201 | if (theGPT->LoadMBR(filename) == 1) { // successful load |
| 202 | theGPT->XFormPartitions(); |
| 203 | } else { |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 204 | cout << "Problem loading MBR! GPT is untouched; regenerating protective MBR!\n"; |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 205 | theGPT->MakeProtectiveMBR(); |
| 206 | } // if/else |
| 207 | } // if |
| 208 | break; |
| 209 | case 'g': case 'G': |
| 210 | temp1 = theGPT->XFormToMBR(); |
| 211 | if (temp1 > 0) { |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 212 | cout << "Converted " << temp1 << " partitions. Finalize and exit? "; |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 213 | if (GetYN() == 'Y') { |
| 214 | if (theGPT->DestroyGPT(0) > 0) |
| 215 | goOn = 0; |
| 216 | } else { |
| 217 | theGPT->MakeProtectiveMBR(); |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 218 | cout << "Note: New protective MBR created.\n"; |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 219 | } // if/else |
| 220 | } // if |
| 221 | break; |
| 222 | case 'h': case 'H': |
| 223 | theGPT->MakeHybrid(); |
| 224 | break; |
| 225 | case 'i': case 'I': |
| 226 | theGPT->ShowDetails(); |
| 227 | break; |
| 228 | case 'l': case 'L': |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 229 | cout << "Enter backup filename to load: "; |
srs5694 | 5d58fe0 | 2010-01-03 20:57:08 -0500 | [diff] [blame] | 230 | junk = fgets(line, 255, stdin); |
| 231 | sscanf(line, "%s", (char*) &buFile); |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 232 | theGPT->LoadGPTBackup(buFile); |
| 233 | break; |
| 234 | case 'm': case 'M': |
| 235 | MainMenu(filename, theGPT); |
| 236 | goOn = 0; |
| 237 | break; |
| 238 | case 'o': case 'O': |
| 239 | theGPT->DisplayMBRData(); |
| 240 | break; |
| 241 | case 'p': case 'P': |
| 242 | theGPT->DisplayGPTData(); |
| 243 | break; |
| 244 | case 'q': case 'Q': |
| 245 | goOn = 0; |
| 246 | break; |
| 247 | case 't': case 'T': |
| 248 | theGPT->XFormDisklabel(); |
| 249 | break; |
| 250 | case 'v': case 'V': |
| 251 | theGPT->Verify(); |
| 252 | break; |
| 253 | case 'w': case 'W': |
| 254 | if (theGPT->SaveGPTData() == 1) { |
| 255 | goOn = 0; |
| 256 | } // if |
| 257 | break; |
| 258 | case 'x': case 'X': |
| 259 | ExpertsMenu(filename, theGPT); |
| 260 | goOn = 0; |
| 261 | break; |
| 262 | default: |
| 263 | ShowRecoveryCommands(); |
| 264 | break; |
| 265 | } // switch |
| 266 | } while (goOn); |
| 267 | } // RecoveryMenu() |
| 268 | |
| 269 | void ShowRecoveryCommands(void) { |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 270 | cout << "b\tuse backup GPT header (rebuilding main)\n"; |
| 271 | cout << "c\tload backup partition table from disk (rebuilding main)\n"; |
| 272 | cout << "d\tuse main GPT header (rebuilding backup)\n"; |
| 273 | cout << "e\tload main partition table from disk (rebuilding backup)\n"; |
| 274 | cout << "f\tload MBR and build fresh GPT from it\n"; |
| 275 | cout << "g\tconvert GPT into MBR and exit\n"; |
| 276 | cout << "h\tmake hybrid MBR\n"; |
| 277 | cout << "i\tshow detailed information on a partition\n"; |
| 278 | cout << "l\tload partition data from a backup file\n"; |
| 279 | cout << "m\treturn to main menu\n"; |
| 280 | cout << "o\tprint protective MBR data\n"; |
| 281 | cout << "p\tprint the partition table\n"; |
| 282 | cout << "q\tquit without saving changes\n"; |
| 283 | cout << "t\ttransform BSD disklabel partition\n"; |
| 284 | cout << "v\tverify disk\n"; |
| 285 | cout << "w\twrite table to disk and exit\n"; |
| 286 | cout << "x\textra functionality (experts only)\n"; |
| 287 | cout << "?\tprint this menu\n"; |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 288 | } // ShowRecoveryCommands() |
| 289 | |
| 290 | // Accept an experts' menu command. Returns only after the user |
| 291 | // selects an exit command, such as 'w' or 'q'. |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 292 | void ExpertsMenu(string filename, struct GPTData* theGPT) { |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 293 | char command, line[255]; |
srs5694 | 5d58fe0 | 2010-01-03 20:57:08 -0500 | [diff] [blame] | 294 | char* junk; |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 295 | PartTypes typeHelper; |
| 296 | uint32_t pn; |
| 297 | uint32_t temp1, temp2; |
| 298 | int goOn = 1; |
| 299 | |
| 300 | do { |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 301 | cout << "\nExpert command (? for help): "; |
srs5694 | 5d58fe0 | 2010-01-03 20:57:08 -0500 | [diff] [blame] | 302 | junk = fgets(line, 255, stdin); |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 303 | sscanf(line, "%c", &command); |
| 304 | switch (command) { |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 305 | case '\n': |
| 306 | break; |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 307 | case 'a': case 'A': |
| 308 | if (theGPT->GetPartRange(&temp1, &temp2) > 0) |
| 309 | theGPT->SetAttributes(theGPT->GetPartNum()); |
| 310 | else |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 311 | cout << "No partitions\n"; |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 312 | break; |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 313 | case 'c': case 'C': |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 314 | if (theGPT->GetPartRange(&temp1, &temp2) > 0) { |
| 315 | pn = theGPT->GetPartNum(); |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 316 | cout << "Enter the partition's new unique GUID:\n"; |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 317 | theGPT->SetPartitionGUID(pn, GetGUID()); |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 318 | } else cout << "No partitions\n"; |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 319 | break; |
srs5694 | 1d1448a | 2009-12-31 21:20:19 -0500 | [diff] [blame] | 320 | case 'd': case 'D': |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 321 | cout << "Partitions will begin on " << theGPT->GetAlignment() |
| 322 | << "-sector boundaries.\n"; |
srs5694 | 1d1448a | 2009-12-31 21:20:19 -0500 | [diff] [blame] | 323 | break; |
srs5694 | 8bb7876 | 2009-11-24 15:43:49 -0500 | [diff] [blame] | 324 | case 'e': case 'E': |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 325 | cout << "Relocating backup data structures to the end of the disk\n"; |
srs5694 | 247657a | 2009-11-26 18:36:12 -0500 | [diff] [blame] | 326 | theGPT->MoveSecondHeaderToEnd(); |
srs5694 | 8bb7876 | 2009-11-24 15:43:49 -0500 | [diff] [blame] | 327 | break; |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 328 | case 'g': case 'G': |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 329 | cout << "Enter the disk's unique GUID:\n"; |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 330 | theGPT->SetDiskGUID(GetGUID()); |
| 331 | break; |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 332 | case 'i': case 'I': |
| 333 | theGPT->ShowDetails(); |
| 334 | break; |
srs5694 | 1d1448a | 2009-12-31 21:20:19 -0500 | [diff] [blame] | 335 | case 'l': case 'L': |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 336 | temp1 = GetNumber(1, 128, 8, (string) |
| 337 | "Enter the sector alignment value (1-128, default = 8): "); |
srs5694 | 1d1448a | 2009-12-31 21:20:19 -0500 | [diff] [blame] | 338 | theGPT->SetAlignment(temp1); |
| 339 | break; |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 340 | case 'm': case 'M': |
| 341 | MainMenu(filename, theGPT); |
| 342 | goOn = 0; |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 343 | break; |
| 344 | case 'n': case 'N': |
| 345 | theGPT->MakeProtectiveMBR(); |
| 346 | break; |
| 347 | case 'o': case 'O': |
| 348 | theGPT->DisplayMBRData(); |
| 349 | break; |
| 350 | case 'p': case 'P': |
| 351 | theGPT->DisplayGPTData(); |
| 352 | break; |
| 353 | case 'q': case 'Q': |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 354 | goOn = 0; |
| 355 | break; |
| 356 | case 'r': case 'R': |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 357 | RecoveryMenu(filename, theGPT); |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 358 | goOn = 0; |
| 359 | break; |
| 360 | case 's': case 'S': |
| 361 | theGPT->ResizePartitionTable(); |
| 362 | break; |
| 363 | case 'v': case 'V': |
| 364 | theGPT->Verify(); |
| 365 | break; |
| 366 | case 'w': case 'W': |
| 367 | if (theGPT->SaveGPTData() == 1) { |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 368 | goOn = 0; |
| 369 | } // if |
| 370 | break; |
srs5694 | c0ca8f8 | 2009-08-20 21:35:25 -0400 | [diff] [blame] | 371 | case 'z': case 'Z': |
| 372 | if (theGPT->DestroyGPT() == 1) { |
srs5694 | 978041c | 2009-09-21 20:51:47 -0400 | [diff] [blame] | 373 | goOn = 0; |
srs5694 | c0ca8f8 | 2009-08-20 21:35:25 -0400 | [diff] [blame] | 374 | } |
| 375 | break; |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 376 | default: |
| 377 | ShowExpertCommands(); |
| 378 | break; |
| 379 | } // switch |
| 380 | } while (goOn); |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 381 | } // ExpertsMenu() |
| 382 | |
| 383 | void ShowExpertCommands(void) { |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame^] | 384 | cout << "a\tset attributes\n"; |
| 385 | cout << "c\tchange partition GUID\n"; |
| 386 | cout << "d\tdisplay the sector alignment value\n"; |
| 387 | cout << "e\trelocate backup data structures to the end of the disk\n"; |
| 388 | cout << "g\tchange disk GUID\n"; |
| 389 | cout << "i\tshow detailed information on a partition\n"; |
| 390 | cout << "l\tset the sector alignment value\n"; |
| 391 | cout << "m\treturn to main menu\n"; |
| 392 | cout << "n\tcreate a new protective MBR\n"; |
| 393 | cout << "o\tprint protective MBR data\n"; |
| 394 | cout << "p\tprint the partition table\n"; |
| 395 | cout << "q\tquit without saving changes\n"; |
| 396 | cout << "r\trecovery and transformation options (experts only)\n"; |
| 397 | cout << "s\tresize partition table\n"; |
| 398 | cout << "v\tverify disk\n"; |
| 399 | cout << "w\twrite table to disk and exit\n"; |
| 400 | cout << "z\tzap (destroy) GPT data structures and exit\n"; |
| 401 | cout << "?\tprint this menu\n"; |
srs5694 | e7b4ff9 | 2009-08-18 13:16:10 -0400 | [diff] [blame] | 402 | } // ShowExpertCommands() |