Skip to content

Commit

Permalink
Preliminary UTF-16LE support for GPT descriptions
Browse files Browse the repository at this point in the history
  • Loading branch information
srs5694 committed Mar 17, 2011
1 parent c2f6e0c commit 5a60853
Show file tree
Hide file tree
Showing 18 changed files with 282 additions and 605 deletions.
402 changes: 2 additions & 400 deletions Makefile

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
0.7.1 (?/?/2011):
-----------------

- Fixed bug that caused second protective MBR partition, when created
as part of a hybrid MBR, to always be of type 0xEE, even when the
user specified something else.

- Integrated a number of code cleanups contributed by Florian Zumbiehl.

0.7.0 (3/11/2011):
Expand Down
4 changes: 4 additions & 0 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ used.) In addition, note these requirements:
called uuid-dev or something similar to get the headers. On FreeBSD, the
e2fsprogs-libuuid port must be installed.

* The ICU library (http://site.icu-project.org) is required on all
platforms. This library is normally installed in Linux, but you may need
to install the development headers (libicu-dev or something similar).

* The sgdisk program also requires the popt library and its development
files (headers). Most Linux distributions install popt by default, but
you may need to install a package called popt-dev, popt-devel, or
Expand Down
12 changes: 3 additions & 9 deletions basicmbr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1544,15 +1544,13 @@ MBRPart* BasicMBRData::GetPartition(int i) {
// user selected the 'q' option. (Thus, the caller should save data
// if the return value is >0, or possibly >=0 depending on intentions.)
int BasicMBRData::DoMenu(const string& prompt) {
char line[255];
int goOn = 1, quitting = 0, retval, num, haveShownInfo = 0;
unsigned int hexCode = 0x00;

do {
cout << prompt;
ReadCString(line, sizeof(line));
switch (*line) {
case '\n':
switch (ReadString()[0]) {
case '\0':
break;
case 'a': case 'A':
num = GetNumber(1, MAX_MBR_PARTS, 1, "Toggle active flag for partition: ") - 1;
Expand Down Expand Up @@ -1598,13 +1596,9 @@ int BasicMBRData::DoMenu(const string& prompt) {
case 't': case 'T':
num = GetNumber(1, MAX_MBR_PARTS, 1, "Partition to change type code: ") - 1;
if (partitions[num].GetLengthLBA() > 0) {
hexCode = 0;
while ((hexCode <= 0) || (hexCode > 255)) {
cout << "Enter an MBR hex code: ";
ReadCString(line, sizeof(line));
sscanf(line, "%x", &hexCode);
if (line[0] == '\n')
hexCode = 0x00;
hexCode = StrToHex(ReadString(), 0);
} // while
partitions[num].SetType(hexCode);
} // if
Expand Down
79 changes: 38 additions & 41 deletions fixparts.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,18 @@ using namespace std;

int main(int argc, char* argv[]) {
BasicMBRData mbrTable;
char *device = NULL;
int i, doItAgain;
string device;
int doItAgain;

switch (argc) {
case 1:
cout << "Type device filename, or press <Enter> to exit: ";
device = new char[255];
ReadCString(device, 255);
i = strlen(device);
if (i && device[i - 1] == '\n')
device[i - 1] = '\0';
device = ReadString();
if (device.length() == 0)
exit(0);
break;
case 2:
device = new char[strlen(argv[1]) + 1];
strcpy(device, argv[1]);
device = argv[1];
break;
default:
cerr << "Usage: " << argv[0] << " device_filename\n";
Expand All @@ -45,39 +42,39 @@ int main(int argc, char* argv[]) {

cout << "FixParts " << GPTFDISK_VERSION << "\n";
cout << "\nLoading MBR data from " << device << "\n";
mbrTable.ReadMBRData(device);
if (mbrTable.CheckForGPT() > 0) {
if ((mbrTable.GetValidity() == hybrid) || (mbrTable.GetValidity() == 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);
} else {
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/else
} // if
mbrTable.MakeItLegal();
do {
doItAgain = 0;
if (mbrTable.DoMenu() > 0) {
cout << "\nFinal checks complete. About to write MBR data. THIS WILL OVERWRITE EXISTING\n"
<< "PARTITIONS!!\n\nDo you want to proceed? ";
if (GetYN() == 'Y') {
mbrTable.WriteMBRData();
mbrTable.DiskSync();
doItAgain = 0;
if (mbrTable.ReadMBRData(device)) {
if (mbrTable.CheckForGPT() > 0) {
if ((mbrTable.GetValidity() == hybrid) || (mbrTable.GetValidity() == 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);
} else {
doItAgain = 1;
} // else
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/else
} // if
} while (doItAgain);
delete[] device;
mbrTable.MakeItLegal();
do {
doItAgain = 0;
if (mbrTable.DoMenu() > 0) {
cout << "\nFinal checks complete. About to write MBR data. THIS WILL OVERWRITE EXISTING\n"
<< "PARTITIONS!!\n\nDo you want to proceed? ";
if (GetYN() == 'Y') {
mbrTable.WriteMBRData();
mbrTable.DiskSync();
doItAgain = 0;
} else {
doItAgain = 1;
} // else
} // if
} while (doItAgain);
} // if read OK
return 0;
} // main()
73 changes: 28 additions & 45 deletions gdisk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ void WinWarning(void);

int main(int argc, char* argv[]) {
GPTDataTextUI theGPT;
size_t i;
char *device = NULL;
string device = "";
UnicodeString uString;

cout << "GPT fdisk (gdisk) version " << GPTFDISK_VERSION << "\n\n";

Expand All @@ -40,14 +40,12 @@ int main(int argc, char* argv[]) {
case 1:
WinWarning();
cout << "Type device filename, or press <Enter> to exit: ";
device = new char[255];
ReadCString(device, 255);
i = strlen(device);
if (i && device[i - 1] == '\n')
device[i - 1] = '\0';
if (*device && theGPT.LoadPartitions(device))
device = ReadString();
if (device.length() == 0)
exit(0);
else if (theGPT.LoadPartitions(device)) {
MainMenu(device, &theGPT);
delete[] device;
} // if/elseif
break;
case 2: // basic usage
WinWarning();
Expand All @@ -56,15 +54,15 @@ int main(int argc, char* argv[]) {
break;
case 3: // usage with "-l" option
if (strcmp(argv[1], "-l") == 0) {
device = argv[2];
device = (string) argv[2];
} else if (strcmp(argv[2], "-l") == 0) {
device = argv[1];
device = (string) argv[1];
} else { // 3 arguments, but none is "-l"
cerr << "Usage: " << argv[0] << " [-l] device_file\n";
} // if/elseif/else
if (device != NULL) {
if (device != "") {
theGPT.JustLooking();
if (theGPT.LoadPartitions((string) device))
if (theGPT.LoadPartitions(device))
theGPT.DisplayGPTData();
} // if
break;
Expand All @@ -77,22 +75,18 @@ int main(int argc, char* argv[]) {
// Accept a command and execute it. Returns only when the user
// wants to exit (such as after a 'w' or 'q' command).
void MainMenu(string filename, GPTDataTextUI* theGPT) {
char line[255], buFile[255];
int goOn = 1;
PartType typeHelper;
uint32_t temp1, temp2;

do {
cout << "\nCommand (? for help): ";
ReadCString(line, sizeof(line));
switch (*line) {
case '\n':
switch (ReadString()[0]) {
case '\0':
break;
case 'b': case 'B':
cout << "Enter backup filename to save: ";
ReadCString(line, sizeof(line));
sscanf(line, "%s", buFile);
theGPT->SaveGPTBackup(buFile);
theGPT->SaveGPTBackup(ReadString());
break;
case 'c': case 'C':
if (theGPT->GetPartRange(&temp1, &temp2) > 0)
Expand Down Expand Up @@ -177,15 +171,13 @@ void ShowCommands(void) {
// Accept a recovery & transformation menu command. Returns only when the user
// issues an exit command, such as 'w' or 'q'.
void RecoveryMenu(string filename, GPTDataTextUI* theGPT) {
char line[255], buFile[255];
uint32_t numParts;
int goOn = 1, temp1;

do {
cout << "\nRecovery/transformation command (? for help): ";
ReadCString(line, sizeof(line));
switch (*line) {
case '\n':
switch (ReadString()[0]) {
case '\0':
break;
case 'b': case 'B':
theGPT->RebuildMainHeader();
Expand Down Expand Up @@ -239,9 +231,7 @@ void RecoveryMenu(string filename, GPTDataTextUI* theGPT) {
break;
case 'l': case 'L':
cout << "Enter backup filename to load: ";
ReadCString(line, sizeof(line));
sscanf(line, "%s", buFile);
theGPT->LoadGPTBackup(buFile);
theGPT->LoadGPTBackup(ReadString());
break;
case 'm': case 'M':
MainMenu(filename, theGPT);
Expand Down Expand Up @@ -303,19 +293,16 @@ void ShowRecoveryCommands(void) {
// selects an exit command, such as 'w' or 'q'.
void ExpertsMenu(string filename, GPTDataTextUI* theGPT) {
GPTData secondDevice;
char line[255], *device;
uint32_t pn, temp1, temp2;
int goOn = 1;
size_t i;
char guidStr[255];
string guidStr, device;
GUIDData aGUID;
ostringstream prompt;

do {
cout << "\nExpert command (? for help): ";
ReadCString(line, sizeof(line));
switch (*line) {
case '\n':
switch (ReadString()[0]) {
case '\0':
break;
case 'a': case 'A':
if (theGPT->GetPartRange(&temp1, &temp2) > 0)
Expand All @@ -327,8 +314,8 @@ void ExpertsMenu(string filename, GPTDataTextUI* theGPT) {
if (theGPT->GetPartRange(&temp1, &temp2) > 0) {
pn = theGPT->GetPartNum();
cout << "Enter the partition's new unique GUID ('R' to randomize): ";
ReadCString(guidStr, sizeof(guidStr));
if ((strlen(guidStr) >= 33) || (guidStr[0] == 'R') || (guidStr[0] == 'r')) {
guidStr = ReadString();
if ((guidStr.length() >= 32) || (guidStr[0] == 'R') || (guidStr[0] == 'r')) {
theGPT->SetPartitionGUID(pn, (GUIDData) guidStr);
cout << "New GUID is " << theGPT->operator[](pn).GetUniqueGUID() << "\n";
} else {
Expand All @@ -349,12 +336,13 @@ void ExpertsMenu(string filename, GPTDataTextUI* theGPT) {
break;
case 'g': case 'G':
cout << "Enter the disk's unique GUID ('R' to randomize): ";
ReadCString(guidStr, sizeof(guidStr));
if ((strlen(guidStr) >= 33) || (guidStr[0] == 'R') || (guidStr[0] == 'r')) {
guidStr = ReadString();
if ((guidStr.length() >= 32) || (guidStr[0] == 'R') || (guidStr[0] == 'r')) {
theGPT->SetDiskGUID((GUIDData) guidStr);
cout << "The new disk GUID is " << theGPT->GetDiskGUID() << "\n";
} else
} else {
cout << "GUID is too short!\n";
} // if/else
break;
case 'h': case 'H':
theGPT->RecomputeCHS();
Expand Down Expand Up @@ -397,17 +385,12 @@ void ExpertsMenu(string filename, GPTDataTextUI* theGPT) {
break;
case 'u': case 'U':
cout << "Type device filename, or press <Enter> to exit: ";
device = new char[255];
ReadCString(device, 255);
i = strlen(device);
if (i && device[i - 1] == '\n')
device[i - 1] = '\0';
if (*device) {
device = ReadString();
if (device.length() > 0) {
secondDevice = *theGPT;
secondDevice.SetDisk(device);
secondDevice.SaveGPTData(0);
} // if
delete[] device;
break;
case 'v': case 'V':
theGPT->Verify();
Expand Down
10 changes: 5 additions & 5 deletions gpt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1028,7 +1028,7 @@ int GPTData::SaveGPTData(int quiet) {

myDisk.Close();
} else {
cerr << "Unable to open device " << myDisk.GetName() << " for writing! Errno is "
cerr << "Unable to open device '" << myDisk.GetName() << "' for writing! Errno is "
<< errno << "! Aborting write!\n";
allOK = 0;
} // if/else
Expand Down Expand Up @@ -1078,7 +1078,7 @@ int GPTData::SaveGPTBackup(const string & filename) {
} // if/else
backupFile.Close();
} else {
cerr << "Unable to open file " << filename << " for writing! Aborting!\n";
cerr << "Unable to open file '" << filename << "' for writing! Aborting!\n";
allOK = 0;
} // if/else
return allOK;
Expand Down Expand Up @@ -1190,7 +1190,7 @@ int GPTData::LoadGPTBackup(const string & filename) {
} // if
} else {
allOK = 0;
cerr << "Unable to open file " << filename << " for reading! Aborting!\n";
cerr << "Unable to open file '" << filename << "' for reading! Aborting!\n";
} // if/else

return allOK;
Expand Down Expand Up @@ -1253,7 +1253,7 @@ int GPTData::DestroyGPT(void) {
<< "other utilities.\n";
delete[] emptyTable;
} else {
cerr << "Problem opening " << device << " for writing! Program will now terminate.\n";
cerr << "Problem opening '" << device << "' for writing! Program will now terminate.\n";
} // if/else (fd != -1)
return (allOK);
} // GPTDataTextUI::DestroyGPT()
Expand Down Expand Up @@ -1766,7 +1766,7 @@ void GPTData::MoveSecondHeaderToEnd() {
secondHeader.partitionEntriesLBA = secondHeader.lastUsableLBA + UINT64_C(1);
} // GPTData::FixSecondHeaderLocation()

int GPTData::SetName(uint32_t partNum, const string & theName) {
int GPTData::SetName(uint32_t partNum, const UnicodeString & theName) {
int retval = 1;

if (!IsFreePartNum(partNum)) {
Expand Down
2 changes: 1 addition & 1 deletion gpt.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ class GPTData {
int SwapPartitions(uint32_t partNum1, uint32_t partNum2);
int ClearGPTData(void);
void MoveSecondHeaderToEnd();
int SetName(uint32_t partNum, const string & theName = "");
int SetName(uint32_t partNum, const UnicodeString & theName = "");
void SetDiskGUID(GUIDData newGUID);
int SetPartitionGUID(uint32_t pn, GUIDData theGUID);
void RandomizeGUIDs(void);
Expand Down
Loading

0 comments on commit 5a60853

Please sign in to comment.