A few minor changes.

This commit is contained in:
srs5694
2011-03-18 12:35:56 -04:00
parent 5a6085310b
commit 815fb65195
10 changed files with 65 additions and 37 deletions

View File

@@ -14,10 +14,10 @@ DEPEND= makedepend $(CXXFLAGS)
all: gdisk sgdisk fixparts all: gdisk sgdisk fixparts
gdisk: $(LIB_OBJS) gdisk.o gpttext.o gdisk: $(LIB_OBJS) gdisk.o gpttext.o
$(CXX) $(LIB_OBJS) gdisk.o gpttext.o $(LDFLAGS) -licui18n -licuio -luuid -o gdisk $(CXX) $(LIB_OBJS) gdisk.o gpttext.o $(LDFLAGS) -licuio -luuid -o gdisk
sgdisk: $(LIB_OBJS) sgdisk.o sgdisk: $(LIB_OBJS) sgdisk.o
$(CXX) $(LIB_OBJS) sgdisk.o $(LDFLAGS) -licui18n -licuio -luuid -lpopt -o sgdisk $(CXX) $(LIB_OBJS) sgdisk.o $(LDFLAGS) -licuio -luuid -lpopt -o sgdisk
fixparts: $(MBR_LIB_OBJS) fixparts.o fixparts: $(MBR_LIB_OBJS) fixparts.o
$(CXX) $(MBR_LIB_OBJS) fixparts.o $(LDFLAGS) -o fixparts $(CXX) $(MBR_LIB_OBJS) fixparts.o $(LDFLAGS) -o fixparts

View File

@@ -13,10 +13,10 @@ DEPEND= makedepend $(CFLAGS)
all: gdisk sgdisk fixparts all: gdisk sgdisk fixparts
gdisk: $(LIB_OBJS) gpttext.o gdisk.o gdisk: $(LIB_OBJS) gpttext.o gdisk.o
$(CXX) $(LIB_OBJS) gpttext.o gdisk.o -o gdisk $(CXX) $(LIB_OBJS) -L/usr/local/lib -licuuc -licuio -licudata gpttext.o gdisk.o -o gdisk
sgdisk: $(LIB_OBJS) sgdisk.o sgdisk: $(LIB_OBJS) sgdisk.o
$(CXX) $(LIB_OBJS) sgdisk.o -L/opt/local/lib -lpopt -o sgdisk $(CXX) $(LIB_OBJS) sgdisk.o -L/opt/local/lib -L/usr/local/lib -licudata -licuio -licuuc -lpopt -o sgdisk
fixparts: $(MBR_LIB_OBJS) fixparts.o fixparts: $(MBR_LIB_OBJS) fixparts.o
$(CXX) $(MBR_LIB_OBJS) fixparts.o $(LDFLAGS) -o fixparts $(CXX) $(MBR_LIB_OBJS) fixparts.o $(LDFLAGS) -o fixparts

3
NEWS
View File

@@ -1,6 +1,9 @@
0.7.1 (?/?/2011): 0.7.1 (?/?/2011):
----------------- -----------------
- Fixed bug that caused the protective MBR to not be written when
restoring a backup of the GPT data.
- Fixed bug that caused second protective MBR partition, when created - 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 as part of a hybrid MBR, to always be of type 0xEE, even when the
user specified something else. user specified something else.

View File

@@ -293,7 +293,7 @@ void ShowRecoveryCommands(void) {
// 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) {
GPTData secondDevice; GPTData secondDevice;
uint32_t pn, temp1, temp2; uint32_t temp1, temp2;
int goOn = 1; int goOn = 1;
string guidStr, device; string guidStr, device;
GUIDData aGUID; GUIDData aGUID;
@@ -311,17 +311,7 @@ void ExpertsMenu(string filename, GPTDataTextUI* theGPT) {
cout << "No partitions\n"; cout << "No partitions\n";
break; break;
case 'c': case 'C': case 'c': case 'C':
if (theGPT->GetPartRange(&temp1, &temp2) > 0) { theGPT->ChangeUniqueGuid();
pn = theGPT->GetPartNum();
cout << "Enter the partition's new unique GUID ('R' to randomize): ";
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 {
cout << "GUID is too short!\n";
} // if/else
} else cout << "No partitions\n";
break; break;
case 'd': case 'D': case 'd': case 'D':
cout << "Partitions will begin on " << theGPT->GetAlignment() cout << "Partitions will begin on " << theGPT->GetAlignment()

18
gpt.cc
View File

@@ -1140,6 +1140,7 @@ int GPTData::LoadGPTBackup(const string & filename) {
// Let the MBRData class load the saved MBR... // Let the MBRData class load the saved MBR...
protectiveMBR.ReadMBRData(&backupFile, 0); // 0 = don't check block size protectiveMBR.ReadMBRData(&backupFile, 0); // 0 = don't check block size
protectiveMBR.SetDisk(&myDisk);
LoadHeader(&mainHeader, backupFile, 1, &mainCrcOk); LoadHeader(&mainHeader, backupFile, 1, &mainCrcOk);
@@ -1580,6 +1581,7 @@ int GPTData::SetGPTSize(uint32_t numEntries) {
<< "partition table size of " << numEntries << "partition table size of " << numEntries
<< "; cannot resize. Perhaps sorting will help.\n"; << "; cannot resize. Perhaps sorting will help.\n";
allOK = 0; allOK = 0;
delete[] newParts;
} else { // go ahead with copy } else { // go ahead with copy
if (numEntries < numParts) if (numEntries < numParts)
copyNum = numEntries; copyNum = numEntries;
@@ -2101,12 +2103,17 @@ int GPTData::IsFree(uint64_t sector, uint32_t *partNum) {
return (isFree); return (isFree);
} // GPTData::IsFree() } // GPTData::IsFree()
// Returns 1 if partNum is unused. // Returns 1 if partNum is unused AND if it's a legal value.
int GPTData::IsFreePartNum(uint32_t partNum) { int GPTData::IsFreePartNum(uint32_t partNum) {
return ((partNum < numParts) && (partitions != NULL) && return ((partNum < numParts) && (partitions != NULL) &&
(!partitions[partNum].IsUsed())); (!partitions[partNum].IsUsed()));
} // GPTData::IsFreePartNum() } // GPTData::IsFreePartNum()
// Returns 1 if partNum is in use.
int GPTData::IsUsedPartNum(uint32_t partNum) {
return ((partNum < numParts) && (partitions != NULL) &&
(partitions[partNum].IsUsed()));
} // GPTData::IsUsedPartNum()
/*********************************************************** /***********************************************************
* * * *
@@ -2207,12 +2214,13 @@ bool GPTData::ValidPartNum (const uint32_t partNum) {
// functions. // functions.
const GPTPart & GPTData::operator[](uint32_t partNum) const { const GPTPart & GPTData::operator[](uint32_t partNum) const {
if (partNum >= numParts) { if (partNum >= numParts) {
cerr << "Partition number out of range: " << partNum << "\n"; cerr << "Partition number out of range (" << partNum << " requested, but only "
partNum = 0; << numParts << " available)\n";
if ((numParts == 0) || (partitions == NULL)) {
cerr << "No partitions defined in GPTData::operator[]; fatal error!\n";
exit(1); exit(1);
} // if } // if
if (partitions == NULL) {
cerr << "No partitions defined in GPTData::operator[]; fatal error!\n";
exit(1);
} // if } // if
return partitions[partNum]; return partitions[partNum];
} // operator[] } // operator[]

4
gpt.h
View File

@@ -65,7 +65,7 @@ class GPTData {
protected: protected:
struct GPTHeader mainHeader; struct GPTHeader mainHeader;
GPTPart *partitions; GPTPart *partitions;
uint32_t numParts; uint32_t numParts; // # of partitions the table can hold
struct GPTHeader secondHeader; struct GPTHeader secondHeader;
MBRData protectiveMBR; MBRData protectiveMBR;
string device; // device filename string device; // device filename
@@ -95,7 +95,6 @@ public:
GPTData(string deviceFilename); GPTData(string deviceFilename);
virtual ~GPTData(void); virtual ~GPTData(void);
GPTData & operator=(const GPTData & orig); GPTData & operator=(const GPTData & orig);
// bool operator<(const GPTData &other) const;
// Verify (or update) data integrity // Verify (or update) data integrity
int Verify(void); int Verify(void);
@@ -185,6 +184,7 @@ public:
uint64_t FindFreeBlocks(uint32_t *numSegments, uint64_t *largestSegment); uint64_t FindFreeBlocks(uint32_t *numSegments, uint64_t *largestSegment);
int IsFree(uint64_t sector, uint32_t *partNum = NULL); int IsFree(uint64_t sector, uint32_t *partNum = NULL);
int IsFreePartNum(uint32_t partNum); int IsFreePartNum(uint32_t partNum);
int IsUsedPartNum(uint32_t partNum);
// Change how functions work, or return information on same // Change how functions work, or return information on same
void SetAlignment(uint32_t n); void SetAlignment(uint32_t n);

View File

@@ -271,6 +271,27 @@ void GPTDataTextUI::ChangePartType(void) {
} // if/else } // if/else
} // GPTDataTextUI::ChangePartType() } // GPTDataTextUI::ChangePartType()
// Prompt user for a partition number, then change its unique
// GUID.
void GPTDataTextUI::ChangeUniqueGuid(void) {
int partNum;
uint32_t low, high;
string guidStr;
if (GetPartRange(&low, &high) > 0) {
partNum = GetPartNum();
cout << "Enter the partition's new unique GUID ('R' to randomize): ";
guidStr = ReadString();
if ((guidStr.length() >= 32) || (guidStr[0] == 'R') || (guidStr[0] == 'r')) {
SetPartitionGUID(partNum, (GUIDData) guidStr);
cout << "New GUID is " << partitions[partNum].GetUniqueGUID() << "\n";
} else {
cout << "GUID is too short!\n";
} // if/else
} else
cout << "No partitions\n";
} // GPTDataTextUI::ChangeUniqueGuid()
// Partition attributes seem to be rarely used, but I want a way to // Partition attributes seem to be rarely used, but I want a way to
// adjust them for completeness.... // adjust them for completeness....
void GPTDataTextUI::SetAttributes(uint32_t partNum) { void GPTDataTextUI::SetAttributes(uint32_t partNum) {

View File

@@ -45,6 +45,7 @@ class GPTDataTextUI : public GPTData {
void CreatePartition(void); void CreatePartition(void);
void DeletePartition(void); void DeletePartition(void);
void ChangePartType(void); void ChangePartType(void);
void ChangeUniqueGuid(void);
void SetAttributes(uint32_t partNum); void SetAttributes(uint32_t partNum);
int SwapPartitions(void); int SwapPartitions(void);
int DestroyGPTwPrompt(void); // Returns 1 if user proceeds int DestroyGPTwPrompt(void); // Returns 1 if user proceeds

View File

@@ -48,7 +48,7 @@ int main(int argc, char *argv[]) {
uint64_t startSector, endSector; uint64_t startSector, endSector;
uint64_t temp; // temporary variable; free to use in any case uint64_t temp; // temporary variable; free to use in any case
char *attributeOperation = NULL; char *attributeOperation = NULL;
char *device = NULL; char *device;
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, *outDevice = NULL; char *partGUID = NULL, *diskGUID = NULL, *outDevice = NULL;
@@ -440,17 +440,21 @@ int BuildMBR(GPTData & theGPT, char* argument, int isHybrid) {
if ((&theGPT != NULL) && (argument != NULL)) { if ((&theGPT != NULL) && (argument != NULL)) {
numParts = CountColons(argument) + 1; numParts = CountColons(argument) + 1;
cout << "numParts = " << numParts << "\n";
if (numParts <= (4 - isHybrid)) { if (numParts <= (4 - isHybrid)) {
newMBR.SetDisk(theGPT.GetDisk()); newMBR.SetDisk(theGPT.GetDisk());
for (i = 0; i < numParts; i++) { for (i = 0; i < numParts; i++) {
origPartNum = GetInt(argument, i + 1) - 1; origPartNum = GetInt(argument, i + 1) - 1;
if (theGPT.IsUsedPartNum(origPartNum)) {
newPart.SetInclusion(PRIMARY); newPart.SetInclusion(PRIMARY);
newPart.SetLocation(theGPT[origPartNum].GetFirstLBA(), newPart.SetLocation(theGPT[origPartNum].GetFirstLBA(),
theGPT[origPartNum].GetLengthLBA()); theGPT[origPartNum].GetLengthLBA());
newPart.SetStatus(0); newPart.SetStatus(0);
newPart.SetType((uint8_t)(theGPT[origPartNum].GetHexType() / 0x0100)); newPart.SetType((uint8_t)(theGPT[origPartNum].GetHexType() / 0x0100));
newMBR.AddPart(i + isHybrid, newPart); newMBR.AddPart(i + isHybrid, newPart);
} else {
cerr << "Partition " << origPartNum << " does not exist! Aborting operation!\n";
allOK = 0;
} // if/else
} // for } // for
if (isHybrid) { if (isHybrid) {
newPart.SetInclusion(PRIMARY); newPart.SetInclusion(PRIMARY);

View File

@@ -15,7 +15,6 @@
#include <fcntl.h> #include <fcntl.h>
#include <string.h> #include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unicode/ustdio.h>
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
@@ -110,7 +109,9 @@ uint64_t GetSectorNum(uint64_t low, uint64_t high, uint64_t def, uint64_t sSize,
// converts to sectors. For instance, with 512-byte sectors, "1K" converts // converts to sectors. For instance, with 512-byte sectors, "1K" converts
// to 2. If value includes a "+", adds low and subtracts 1; if SIValue // to 2. If value includes a "+", adds low and subtracts 1; if SIValue
// inclues a "-", subtracts from high. If IeeeValue is empty, returns def. // inclues a "-", subtracts from high. If IeeeValue is empty, returns def.
// Returns integral sector value. // Returns final sector value. In case inValue works out to something that
// is not in the range of low to high (inclusive), returns high + 1; the
// calling function is responsible for checking the validity of this value.
uint64_t IeeeToInt(string inValue, uint64_t sSize, uint64_t low, uint64_t high, uint64_t def) { uint64_t IeeeToInt(string inValue, uint64_t sSize, uint64_t low, uint64_t high, uint64_t def) {
uint64_t response = def, bytesPerUnit = 1, mult = 1, divide = 1; uint64_t response = def, bytesPerUnit = 1, mult = 1, divide = 1;
size_t foundAt = 0; size_t foundAt = 0;