From 815fb65195106b8afe1b8dfec5dae605dbd7ccbe Mon Sep 17 00:00:00 2001 From: srs5694 Date: Fri, 18 Mar 2011 12:35:56 -0400 Subject: [PATCH] A few minor changes. --- Makefile | 4 ++-- Makefile.mac | 6 +++--- NEWS | 3 +++ gdisk.cc | 14 ++------------ gpt.cc | 22 +++++++++++++++------- gpt.h | 6 +++--- gpttext.cc | 21 +++++++++++++++++++++ gpttext.h | 1 + sgdisk.cc | 20 ++++++++++++-------- support.cc | 5 +++-- 10 files changed, 65 insertions(+), 37 deletions(-) diff --git a/Makefile b/Makefile index 7f04243..06c576f 100644 --- a/Makefile +++ b/Makefile @@ -14,10 +14,10 @@ DEPEND= makedepend $(CXXFLAGS) all: gdisk sgdisk fixparts 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 - $(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 $(CXX) $(MBR_LIB_OBJS) fixparts.o $(LDFLAGS) -o fixparts diff --git a/Makefile.mac b/Makefile.mac index c9fe488..3793624 100644 --- a/Makefile.mac +++ b/Makefile.mac @@ -12,11 +12,11 @@ DEPEND= makedepend $(CFLAGS) all: gdisk sgdisk fixparts -gdisk: $(LIB_OBJS) gpttext.o gdisk.o - $(CXX) $(LIB_OBJS) gpttext.o gdisk.o -o gdisk +gdisk: $(LIB_OBJS) gpttext.o gdisk.o + $(CXX) $(LIB_OBJS) -L/usr/local/lib -licuuc -licuio -licudata gpttext.o gdisk.o -o gdisk 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 $(CXX) $(MBR_LIB_OBJS) fixparts.o $(LDFLAGS) -o fixparts diff --git a/NEWS b/NEWS index 5827153..678b913 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,9 @@ 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 as part of a hybrid MBR, to always be of type 0xEE, even when the user specified something else. diff --git a/gdisk.cc b/gdisk.cc index 35f7e9d..22de86b 100644 --- a/gdisk.cc +++ b/gdisk.cc @@ -293,7 +293,7 @@ void ShowRecoveryCommands(void) { // selects an exit command, such as 'w' or 'q'. void ExpertsMenu(string filename, GPTDataTextUI* theGPT) { GPTData secondDevice; - uint32_t pn, temp1, temp2; + uint32_t temp1, temp2; int goOn = 1; string guidStr, device; GUIDData aGUID; @@ -311,17 +311,7 @@ void ExpertsMenu(string filename, GPTDataTextUI* theGPT) { cout << "No partitions\n"; break; case 'c': case 'C': - if (theGPT->GetPartRange(&temp1, &temp2) > 0) { - 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"; + theGPT->ChangeUniqueGuid(); break; case 'd': case 'D': cout << "Partitions will begin on " << theGPT->GetAlignment() diff --git a/gpt.cc b/gpt.cc index bf99c6a..ea0a0a3 100644 --- a/gpt.cc +++ b/gpt.cc @@ -1140,6 +1140,7 @@ int GPTData::LoadGPTBackup(const string & filename) { // Let the MBRData class load the saved MBR... protectiveMBR.ReadMBRData(&backupFile, 0); // 0 = don't check block size + protectiveMBR.SetDisk(&myDisk); LoadHeader(&mainHeader, backupFile, 1, &mainCrcOk); @@ -1580,6 +1581,7 @@ int GPTData::SetGPTSize(uint32_t numEntries) { << "partition table size of " << numEntries << "; cannot resize. Perhaps sorting will help.\n"; allOK = 0; + delete[] newParts; } else { // go ahead with copy if (numEntries < numParts) copyNum = numEntries; @@ -2101,12 +2103,17 @@ int GPTData::IsFree(uint64_t sector, uint32_t *partNum) { return (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) { return ((partNum < numParts) && (partitions != NULL) && (!partitions[partNum].IsUsed())); } // 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. const GPTPart & GPTData::operator[](uint32_t partNum) const { if (partNum >= numParts) { - cerr << "Partition number out of range: " << partNum << "\n"; - partNum = 0; - if ((numParts == 0) || (partitions == NULL)) { - cerr << "No partitions defined in GPTData::operator[]; fatal error!\n"; - exit(1); - } // if + cerr << "Partition number out of range (" << partNum << " requested, but only " + << numParts << " available)\n"; + exit(1); + } // if + if (partitions == NULL) { + cerr << "No partitions defined in GPTData::operator[]; fatal error!\n"; + exit(1); } // if return partitions[partNum]; } // operator[] diff --git a/gpt.h b/gpt.h index eb91bb3..41fa3d1 100644 --- a/gpt.h +++ b/gpt.h @@ -65,7 +65,7 @@ class GPTData { protected: struct GPTHeader mainHeader; GPTPart *partitions; - uint32_t numParts; + uint32_t numParts; // # of partitions the table can hold struct GPTHeader secondHeader; MBRData protectiveMBR; string device; // device filename @@ -95,7 +95,6 @@ public: GPTData(string deviceFilename); virtual ~GPTData(void); GPTData & operator=(const GPTData & orig); -// bool operator<(const GPTData &other) const; // Verify (or update) data integrity int Verify(void); @@ -185,7 +184,8 @@ public: uint64_t FindFreeBlocks(uint32_t *numSegments, uint64_t *largestSegment); int IsFree(uint64_t sector, uint32_t *partNum = NULL); int IsFreePartNum(uint32_t partNum); - + int IsUsedPartNum(uint32_t partNum); + // Change how functions work, or return information on same void SetAlignment(uint32_t n); uint32_t ComputeAlignment(void); // Set alignment based on current partitions diff --git a/gpttext.cc b/gpttext.cc index ff63be9..0b02672 100644 --- a/gpttext.cc +++ b/gpttext.cc @@ -271,6 +271,27 @@ void GPTDataTextUI::ChangePartType(void) { } // if/else } // 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 // adjust them for completeness.... void GPTDataTextUI::SetAttributes(uint32_t partNum) { diff --git a/gpttext.h b/gpttext.h index cb8f1e0..33b7486 100644 --- a/gpttext.h +++ b/gpttext.h @@ -45,6 +45,7 @@ class GPTDataTextUI : public GPTData { void CreatePartition(void); void DeletePartition(void); void ChangePartType(void); + void ChangeUniqueGuid(void); void SetAttributes(uint32_t partNum); int SwapPartitions(void); int DestroyGPTwPrompt(void); // Returns 1 if user proceeds diff --git a/sgdisk.cc b/sgdisk.cc index 802e49b..83cb663 100644 --- a/sgdisk.cc +++ b/sgdisk.cc @@ -48,7 +48,7 @@ int main(int argc, char *argv[]) { uint64_t startSector, endSector; uint64_t temp; // temporary variable; free to use in any case char *attributeOperation = NULL; - char *device = NULL; + char *device; char *newPartInfo = NULL, *typeCode = NULL, *partName = NULL; char *backupFile = NULL, *twoParts = NULL, *hybrids = NULL, *mbrParts; char *partGUID = NULL, *diskGUID = NULL, *outDevice = NULL; @@ -440,17 +440,21 @@ int BuildMBR(GPTData & theGPT, char* argument, int isHybrid) { if ((&theGPT != NULL) && (argument != NULL)) { numParts = CountColons(argument) + 1; - cout << "numParts = " << numParts << "\n"; if (numParts <= (4 - isHybrid)) { newMBR.SetDisk(theGPT.GetDisk()); for (i = 0; i < numParts; i++) { origPartNum = GetInt(argument, i + 1) - 1; - newPart.SetInclusion(PRIMARY); - newPart.SetLocation(theGPT[origPartNum].GetFirstLBA(), - theGPT[origPartNum].GetLengthLBA()); - newPart.SetStatus(0); - newPart.SetType((uint8_t)(theGPT[origPartNum].GetHexType() / 0x0100)); - newMBR.AddPart(i + isHybrid, newPart); + if (theGPT.IsUsedPartNum(origPartNum)) { + newPart.SetInclusion(PRIMARY); + newPart.SetLocation(theGPT[origPartNum].GetFirstLBA(), + theGPT[origPartNum].GetLengthLBA()); + newPart.SetStatus(0); + newPart.SetType((uint8_t)(theGPT[origPartNum].GetHexType() / 0x0100)); + newMBR.AddPart(i + isHybrid, newPart); + } else { + cerr << "Partition " << origPartNum << " does not exist! Aborting operation!\n"; + allOK = 0; + } // if/else } // for if (isHybrid) { newPart.SetInclusion(PRIMARY); diff --git a/support.cc b/support.cc index 4e7c874..00c0e12 100644 --- a/support.cc +++ b/support.cc @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -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 // to 2. If value includes a "+", adds low and subtracts 1; if SIValue // 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 response = def, bytesPerUnit = 1, mult = 1, divide = 1; size_t foundAt = 0;