Tentative support for duplicating one disk's partition table on another

disk.
This commit is contained in:
srs5694
2010-07-06 15:39:51 -04:00
parent 61768bccde
commit f9312b0ca9
5 changed files with 40 additions and 11 deletions

6
NEWS
View File

@@ -1,3 +1,9 @@
0.6.10 (??/??/2010):
--------------------
- Added ability to save partition table from one device to another
(gdisk: 'u' on experts' menu; sgdisk: -R or --replicate option)
0.6.9 (7/4/2010): 0.6.9 (7/4/2010):
------------------ ------------------

View File

@@ -314,10 +314,10 @@ void ShowRecoveryCommands(void) {
// Accept an experts' menu command. Returns only after the user // Accept an experts' menu command. Returns only after the user
// selects an exit command, such as 'w' or 'q'. // selects an exit command, such as 'w' or 'q'.
void ExpertsMenu(string filename, GPTDataTextUI* theGPT) { void ExpertsMenu(string filename, GPTDataTextUI* theGPT) {
char command, line[255]; char command, line[255], *device;
char* junk; char* junk;
uint32_t pn, temp1, temp2; uint32_t pn, temp1, temp2;
int goOn = 1; int goOn = 1, i;
GUIDData aGUID; GUIDData aGUID;
ostringstream prompt; ostringstream prompt;
@@ -395,6 +395,20 @@ void ExpertsMenu(string filename, GPTDataTextUI* theGPT) {
case 't': case 'T': case 't': case 'T':
theGPT->SwapPartitions(); theGPT->SwapPartitions();
break; break;
case 'u': case 'U':
cout << "Type device filename, or press <Enter> to exit: ";
device = new char[255];
junk = fgets(device, 255, stdin);
if (device[0] != '\n') {
i = strlen(device);
if (i > 0)
if (device[i - 1] == '\n')
device[i - 1] = '\0';
} // if
if (strlen(device) > 0)
theGPT->SaveGPTData(0, device);
delete[] device;
break;
case 'v': case 'V': case 'v': case 'V':
theGPT->Verify(); theGPT->Verify();
break; break;
@@ -432,6 +446,7 @@ void ShowExpertCommands(void) {
cout << "r\trecovery and transformation options (experts only)\n"; cout << "r\trecovery and transformation options (experts only)\n";
cout << "s\tresize partition table\n"; cout << "s\tresize partition table\n";
cout << "t\ttranspose two partition table entries\n"; cout << "t\ttranspose two partition table entries\n";
cout << "u\tReplicate partition table on new device\n";
cout << "v\tverify disk\n"; cout << "v\tverify disk\n";
cout << "w\twrite table to disk and exit\n"; cout << "w\twrite table to disk and exit\n";
cout << "z\tzap (destroy) GPT data structures and exit\n"; cout << "z\tzap (destroy) GPT data structures and exit\n";

11
gpt.cc
View File

@@ -869,13 +869,16 @@ int GPTData::CheckTable(struct GPTHeader *header) {
// Writes GPT (and protective MBR) to disk. Returns 1 on successful // Writes GPT (and protective MBR) to disk. Returns 1 on successful
// write, 0 if there was a problem. // write, 0 if there was a problem.
int GPTData::SaveGPTData(int quiet) { int GPTData::SaveGPTData(int quiet, string filename) {
int allOK = 1, littleEndian; int allOK = 1, littleEndian;
char answer; char answer;
if (filename == "")
filename = device;
littleEndian = IsLittleEndian(); littleEndian = IsLittleEndian();
if (device == "") { if (filename == "") {
cerr << "Device not defined.\n"; cerr << "Device not defined.\n";
} // if } // if
@@ -938,7 +941,7 @@ int GPTData::SaveGPTData(int quiet) {
// Do it! // Do it!
if (allOK) { if (allOK) {
if (myDisk.OpenForWrite(device)) { if (myDisk.OpenForWrite(filename)) {
// As per UEFI specs, write the secondary table and GPT first.... // As per UEFI specs, write the secondary table and GPT first....
allOK = SavePartitionTable(myDisk, secondHeader.partitionEntriesLBA); allOK = SavePartitionTable(myDisk, secondHeader.partitionEntriesLBA);
if (!allOK) if (!allOK)
@@ -971,7 +974,7 @@ int GPTData::SaveGPTData(int quiet) {
myDisk.Close(); myDisk.Close();
} else { } else {
cerr << "Unable to open device " << device << " for writing! Errno is " cerr << "Unable to open device " << filename << " for writing! Errno is "
<< errno << "! Aborting write!\n"; << errno << "! Aborting write!\n";
allOK = 0; allOK = 0;
} // if/else } // if/else

4
gpt.h
View File

@@ -16,7 +16,7 @@
#ifndef __GPTSTRUCTS #ifndef __GPTSTRUCTS
#define __GPTSTRUCTS #define __GPTSTRUCTS
#define GPTFDISK_VERSION "0.6.9" #define GPTFDISK_VERSION "0.6.10-pre1"
// Constants used by GPTData::PartsToMBR(). MBR_EMPTY must be the lowest- // Constants used by GPTData::PartsToMBR(). MBR_EMPTY must be the lowest-
// numbered value to refer to partition numbers. (Most will be 0 or positive, // numbered value to refer to partition numbers. (Most will be 0 or positive,
@@ -125,7 +125,7 @@ public:
int ForceLoadGPTData(void); int ForceLoadGPTData(void);
int LoadMainTable(void); int LoadMainTable(void);
int LoadSecondTableAsMain(void); int LoadSecondTableAsMain(void);
int SaveGPTData(int quiet = 0); int SaveGPTData(int quiet = 0, string filename = "");
int SaveGPTBackup(const string & filename); int SaveGPTBackup(const string & filename);
int LoadGPTBackup(const string & filename); int LoadGPTBackup(const string & filename);
int SaveMBR(void); int SaveMBR(void);

View File

@@ -42,7 +42,7 @@ int main(int argc, char *argv[]) {
char *device = NULL; char *device = NULL;
char *newPartInfo = NULL, *typeCode = NULL, *partName = NULL; char *newPartInfo = NULL, *typeCode = NULL, *partName = NULL;
char *backupFile = NULL, *twoParts = NULL, *hybrids = NULL, *mbrParts; char *backupFile = NULL, *twoParts = NULL, *hybrids = NULL, *mbrParts;
char *partGUID = NULL, *diskGUID = NULL; char *partGUID = NULL, *diskGUID = NULL, *outDevice = NULL;
PartType typeHelper; PartType typeHelper;
poptContext poptCon; poptContext poptCon;
@@ -70,6 +70,7 @@ int main(int argc, char *argv[]) {
{"print", 'p', POPT_ARG_NONE, NULL, 'p', "print partition table", ""}, {"print", 'p', POPT_ARG_NONE, NULL, 'p', "print partition table", ""},
{"pretend", 'P', POPT_ARG_NONE, NULL, 'P', "make changes in memory, but don't write them", ""}, {"pretend", 'P', POPT_ARG_NONE, NULL, 'P', "make changes in memory, but don't write them", ""},
{"transpose", 'r', POPT_ARG_STRING, &twoParts, 'r', "transpose two partitions", "partnum:partnum"}, {"transpose", 'r', POPT_ARG_STRING, &twoParts, 'r', "transpose two partitions", "partnum:partnum"},
{"replicate", 'R', POPT_ARG_STRING, &outDevice, 'R', "replicate partition table", "device_filename"},
{"sort", 's', POPT_ARG_NONE, NULL, 's', "sort partition table entries", ""}, {"sort", 's', POPT_ARG_NONE, NULL, 's', "sort partition table entries", ""},
{"resize-table", 'S', POPT_ARG_INT, &tableSize, 'S', "resize partition table", "numparts"}, {"resize-table", 'S', POPT_ARG_INT, &tableSize, 'S', "resize partition table", "numparts"},
{"typecode", 't', POPT_ARG_STRING, &typeCode, 't', "change partition type code", "partnum:hexcode"}, {"typecode", 't', POPT_ARG_STRING, &typeCode, 't', "change partition type code", "partnum:hexcode"},
@@ -143,6 +144,11 @@ int main(int argc, char *argv[]) {
} // if/else } // if/else
free(partName); free(partName);
break; break;
case 'C':
theGPT.JustLooking(0);
theGPT.RecomputeCHS();
saveData = 1;
break;
case 'd': case 'd':
theGPT.JustLooking(0); theGPT.JustLooking(0);
if (theGPT.DeletePartition(deletePartNum - 1) == 0) { if (theGPT.DeletePartition(deletePartNum - 1) == 0) {
@@ -256,8 +262,7 @@ int main(int argc, char *argv[]) {
break; break;
case 'R': case 'R':
theGPT.JustLooking(0); theGPT.JustLooking(0);
theGPT.RecomputeCHS(); theGPT.SaveGPTData(1, outDevice);
saveData = 1;
break; break;
case 's': case 's':
theGPT.JustLooking(0); theGPT.JustLooking(0);