Tentative support for duplicating one disk's partition table on another
disk.
This commit is contained in:
6
NEWS
6
NEWS
@@ -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):
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
|||||||
19
gdisk.cc
19
gdisk.cc
@@ -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
11
gpt.cc
@@ -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
4
gpt.h
@@ -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);
|
||||||
|
|||||||
11
sgdisk.cc
11
sgdisk.cc
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user