summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG9
-rw-r--r--Makefile6
-rw-r--r--current.spec2
-rw-r--r--gdisk.cc1
-rw-r--r--gpt.cc125
-rw-r--r--gpt.h3
-rw-r--r--gpttext.cc41
-rw-r--r--sgdisk.cc2
8 files changed, 96 insertions, 93 deletions
diff --git a/CHANGELOG b/CHANGELOG
index fe1da76..fccc838 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,12 @@
+0.6.7 (?/?/2010):
+-----------------
+
+- Fixed bug that caused segfault on some invalid disks
+
+- Fixed bug that caused incorrect partition numbers to be displayed for
+ some verify problems.
+
+
0.6.6 (3/21/2010):
-----------------
diff --git a/Makefile b/Makefile
index 5b488ed..49be23a 100644
--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,7 @@ LIB_NAMES=crc32 support guid partnotes gptpart mbr gpt bsd parttypes attributes
LIB_SRCS=$(NAMES:=.cc)
LIB_OBJS=$(LIB_NAMES:=.o)
LIB_HEADERS=$(LIB_NAMES:=.h)
-DEPEND= makedepend $(CFLAGS)
+DEPEND= makedepend $(CXXFLAGS)
all: gdisk sgdisk
@@ -17,9 +17,6 @@ gdisk: $(LIB_OBJS) gdisk.o gpttext.o
sgdisk: $(LIB_OBJS) sgdisk.o
$(CXX) $(LIB_OBJS) sgdisk.o -L/opt/local/lib -L/usr/local/lib $(LDFLAGS) -luuid -lpopt -o sgdisk
-testguid: $(LIB_OBJS) testguid.o
- $(CXX) $(LIB_OBJS) testguid.o -o testguid
-
lint: #no pre-reqs
lint $(SRCS)
@@ -31,5 +28,6 @@ depend: $(SRCS)
$(DEPEND) $(SRCS)
$(OBJS):
+ $(CRITICAL_CXX_FLAGS)
# DO NOT DELETE
diff --git a/current.spec b/current.spec
index f610336..373769b 100644
--- a/current.spec
+++ b/current.spec
@@ -19,7 +19,7 @@ and the ability to convert MBR disks to GPT format.
%setup -q
%build
-make CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_CXX_FLAGS -D_FILE_OFFSET_BITS=64 -O2"
+CFLAGS="$RPM_OPT_FLAGS" "$RPM_OPT_CXX_FLAGS" make
%install
rm -rf $RPM_BUILD_ROOT
diff --git a/gdisk.cc b/gdisk.cc
index a3e4bb9..b372ebb 100644
--- a/gdisk.cc
+++ b/gdisk.cc
@@ -13,6 +13,7 @@
#include <string>
#include <iostream>
#include <sstream>
+#include <locale>
#include "mbr.h"
#include "gpttext.h"
#include "support.h"
diff --git a/gpt.cc b/gpt.cc
index 9b1faf6..12aece1 100644
--- a/gpt.cc
+++ b/gpt.cc
@@ -55,6 +55,7 @@ GPTData::GPTData(void) {
whichWasUsed = use_new;
srand((unsigned int) time(NULL));
mainHeader.numParts = 0;
+ numParts = 0;
SetGPTSize(NUM_GPT_ENTRIES);
} // GPTData default constructor
@@ -77,6 +78,7 @@ GPTData::GPTData(string filename) {
whichWasUsed = use_new;
srand((unsigned int) time(NULL));
mainHeader.numParts = 0;
+ numParts = 0;
if (!LoadPartitions(filename))
exit(2);
} // GPTData(string filename) constructor
@@ -222,7 +224,7 @@ int GPTData::Verify(void) {
// Check that partitions are aligned on proper boundaries (for WD Advanced
// Format and similar disks)....
- for (i = 0; i < mainHeader.numParts; i++) {
+ for (i = 0; i < numParts; i++) {
if ((partitions[i].GetFirstLBA() % sectorAlignment) != 0) {
cout << "\nCaution: Partition " << i + 1 << " doesn't begin on a "
<< sectorAlignment << "-sector boundary. This may\nresult "
@@ -238,7 +240,7 @@ int GPTData::Verify(void) {
<< BytesToSI(totalFree * (uint64_t) blockSize) << ") available in "
<< numSegments << "\nsegments, the largest of which is "
<< largestSegment << " (" << BytesToSI(largestSegment * (uint64_t) blockSize)
- << ") in size\n";
+ << ") in size.\n";
} else {
cout << "\nIdentified " << problems << " problems!\n";
} // if/else
@@ -257,7 +259,7 @@ int GPTData::CheckGPTSize(void) {
// first, locate the first & last used blocks
firstUsedBlock = UINT64_MAX;
lastUsedBlock = 0;
- for (i = 0; i < mainHeader.numParts; i++) {
+ for (i = 0; i < numParts; i++) {
if ((partitions[i].GetFirstLBA() < firstUsedBlock) &&
(partitions[i].GetFirstLBA() != 0))
firstUsedBlock = partitions[i].GetFirstLBA();
@@ -372,14 +374,13 @@ int GPTData::CheckHeaderCRC(struct GPTHeader* header) {
// been made. Must be called on platform-ordered data (this function reverses
// byte order and then undoes that reversal.)
void GPTData::RecomputeCRCs(void) {
- uint32_t crc, hSize, trueNumParts;
+ uint32_t crc, hSize;
int littleEndian = 1;
// Initialize CRC functions...
chksum_crc32gentab();
// Save some key data from header before reversing byte order....
- trueNumParts = mainHeader.numParts;
hSize = mainHeader.headerSize;
if ((littleEndian = IsLittleEndian()) == 0) {
@@ -389,7 +390,7 @@ void GPTData::RecomputeCRCs(void) {
} // if
// Compute CRC of partition tables & store in main and secondary headers
- crc = chksum_crc32((unsigned char*) partitions, trueNumParts * GPT_SIZE);
+ crc = chksum_crc32((unsigned char*) partitions, numParts * GPT_SIZE);
mainHeader.partitionEntriesCRC = crc;
secondHeader.partitionEntriesCRC = crc;
if (littleEndian == 0) {
@@ -440,6 +441,7 @@ void GPTData::RebuildMainHeader(void) {
for (i = 0 ; i < GPT_RESERVED; i++)
mainHeader.reserved2[i] = secondHeader.reserved2[i];
mainCrcOk = secondCrcOk;
+ SetGPTSize(mainHeader.numParts);
} // GPTData::RebuildMainHeader()
// Rebuild the secondary GPT header, using the main header as a model.
@@ -463,6 +465,7 @@ void GPTData::RebuildSecondHeader(void) {
for (i = 0 ; i < GPT_RESERVED; i++)
secondHeader.reserved2[i] = mainHeader.reserved2[i];
secondCrcOk = mainCrcOk;
+ SetGPTSize(secondHeader.numParts);
} // GPTData::RebuildSecondHeader()
// Search for hybrid MBR entries that have no corresponding GPT partition.
@@ -483,7 +486,7 @@ int GPTData::FindHybridMismatches(void) {
(partitions[j].GetLastLBA() == mbrLast))
found = 1;
j++;
- } while ((!found) && (j < mainHeader.numParts));
+ } while ((!found) && (j < numParts));
if (!found) {
numFound++;
cout << "\nWarning! Mismatched GPT and MBR partition! MBR partition "
@@ -507,7 +510,7 @@ int GPTData::FindOverlaps(void) {
int problems = 0;
uint32_t i, j;
- for (i = 1; i < mainHeader.numParts; i++) {
+ for (i = 1; i < numParts; i++) {
for (j = 0; j < i; j++) {
if (partitions[i].DoTheyOverlap(partitions[j])) {
problems++;
@@ -530,14 +533,14 @@ int GPTData::FindInsanePartitions(void) {
uint32_t i;
int problems = 0;
- for (i = 0; i < mainHeader.numParts; i++) {
+ for (i = 0; i < numParts; i++) {
if (partitions[i].GetFirstLBA() > partitions[i].GetLastLBA()) {
problems++;
- cout << "\nProblem: partition " << i << " ends before it begins.\n";
+ cout << "\nProblem: partition " << i + 1 << " ends before it begins.\n";
} // if
if (partitions[i].GetLastLBA() >= diskSize) {
problems++;
- cout << "\nProblem: partition " << i << " is too big for the disk.\n";
+ cout << "\nProblem: partition " << i + 1<< " is too big for the disk.\n";
} // if
} // for
return problems;
@@ -782,7 +785,7 @@ int GPTData::LoadHeader(struct GPTHeader *header, DiskIO & disk, uint64_t sector
ReverseHeaderBytes(&tempHeader);
} // if
- if (allOK && (mainHeader.numParts != tempHeader.numParts) && *crcOk) {
+ if (allOK && (numParts != tempHeader.numParts) && *crcOk) {
allOK = SetGPTSize(tempHeader.numParts);
}
@@ -839,14 +842,14 @@ int GPTData::CheckTable(struct GPTHeader *header) {
uint8_t *storage;
int newCrcOk = 0;
- // Load backup partition table into temporary storage to check
+ // Load partition table into temporary storage to check
// its CRC and store the results, then discard this temporary
// storage, since we don't use it in any but recovery operations
if (myDisk.Seek(header->partitionEntriesLBA)) {
- sizeOfParts = secondHeader.numParts * secondHeader.sizeOfPartitionEntries;
+ sizeOfParts = header->numParts * header->sizeOfPartitionEntries;
storage = new uint8_t[sizeOfParts];
if (myDisk.Read(storage, sizeOfParts) != (int) sizeOfParts) {
- cerr << "Warning! Error " << errno << " reading backup partition table!\n";
+ cerr << "Warning! Error " << errno << " reading partition table for CRC check!\n";
} else {
newCRC = chksum_crc32((unsigned char*) storage, sizeOfParts);
newCrcOk = (newCRC == header->partitionEntriesCRC);
@@ -1048,7 +1051,7 @@ int GPTData::SavePartitionTable(DiskIO & disk, uint64_t sector) {
if (disk.Seek(sector)) {
if (!littleEndian)
ReversePartitionBytes();
- if (disk.Write(partitions, mainHeader.sizeOfPartitionEntries * mainHeader.numParts) == -1)
+ if (disk.Write(partitions, mainHeader.sizeOfPartitionEntries * numParts) == -1)
allOK = 0;
if (!littleEndian)
ReversePartitionBytes();
@@ -1062,7 +1065,7 @@ int GPTData::SavePartitionTable(DiskIO & disk, uint64_t sector) {
// set of partitions.
int GPTData::LoadGPTBackup(const string & filename) {
int allOK = 1, val, err;
- uint32_t numParts, sizeOfEntries;
+ uint32_t sizeOfEntries;
int littleEndian = 1, shortBackup = 0;
DiskIO backupFile;
@@ -1095,14 +1098,16 @@ int GPTData::LoadGPTBackup(const string & filename) {
// this check!
if ((val = CheckHeaderValidity()) > 0) {
if (val == 2) { // only backup header seems to be good
- numParts = secondHeader.numParts;
+ SetGPTSize(secondHeader.numParts);
+// numParts = secondHeader.numParts;
sizeOfEntries = secondHeader.sizeOfPartitionEntries;
} else { // main header is OK
- numParts = mainHeader.numParts;
+ SetGPTSize(mainHeader.numParts);
+// numParts = mainHeader.numParts;
sizeOfEntries = mainHeader.sizeOfPartitionEntries;
} // if/else
- SetGPTSize(numParts);
+// SetGPTSize(numParts);
if (secondHeader.currentLBA != diskSize - UINT64_C(1)) {
cout << "Warning! Current disk size doesn't match that of the backup!\n"
@@ -1155,7 +1160,7 @@ int GPTData::DestroyGPT(void) {
} // if
if (!myDisk.Seek(mainHeader.partitionEntriesLBA))
allOK = 0;
- tableSize = mainHeader.numParts * mainHeader.sizeOfPartitionEntries;
+ tableSize = numParts * mainHeader.sizeOfPartitionEntries;
emptyTable = new uint8_t[tableSize];
for (i = 0; i < tableSize; i++)
emptyTable[i] = 0;
@@ -1250,7 +1255,7 @@ void GPTData::DisplayGPTData(void) {
<< BytesToSI(diskSize * blockSize) << "\n";
cout << "Logical sector size: " << blockSize << " bytes\n";
cout << "Disk identifier (GUID): " << mainHeader.diskGUID.AsString() << "\n";
- cout << "Partition table holds up to " << mainHeader.numParts << " entries\n";
+ cout << "Partition table holds up to " << numParts << " entries\n";
cout << "First usable sector is " << mainHeader.firstUsableLBA
<< ", last usable sector is " << mainHeader.lastUsableLBA << "\n";
totalFree = FindFreeBlocks(&i, &temp);
@@ -1258,7 +1263,7 @@ void GPTData::DisplayGPTData(void) {
cout << "Total free space is " << totalFree << " sectors ("
<< BytesToSI(totalFree * (uint64_t) blockSize) << ")\n";
cout << "\nNumber Start (sector) End (sector) Size Code Name\n";
- for (i = 0; i < mainHeader.numParts; i++) {
+ for (i = 0; i < numParts; i++) {
partitions[i].ShowSummary(i, blockSize);
} // for
} // GPTData::DisplayGPTData()
@@ -1294,7 +1299,7 @@ WhichToUse GPTData::UseWhichPartitions(void) {
cout << "\n***************************************************************\n"
<< "Found invalid GPT and valid MBR; converting MBR to GPT format.\n";
if (!justLooking) {
- cout << "\aTHIS OPERATON IS POTENTIALLY DESTRUCTIVE! Exit by typing 'q' if\n"
+ cout << "\aTHIS OPERATION IS POTENTIALLY DESTRUCTIVE! Exit by typing 'q' if\n"
<< "you don't want to convert your MBR partitions to GPT format!\n";
} // if
cout << "***************************************************************\n\n";
@@ -1306,7 +1311,7 @@ WhichToUse GPTData::UseWhichPartitions(void) {
<< "Found invalid GPT and valid BSD disklabel; converting BSD disklabel\n"
<< "to GPT format.";
if ((!justLooking) && (!beQuiet)) {
- cout << "\a THIS OPERATON IS POTENTIALLY DESTRUCTIVE! Your first\n"
+ cout << "\a THIS OPERATION IS POTENTIALLY DESTRUCTIVE! Your first\n"
<< "BSD partition will likely be unusable. Exit by typing 'q' if you don't\n"
<< "want to convert your BSD partitions to GPT format!";
} // if
@@ -1361,10 +1366,10 @@ void GPTData::XFormPartitions(void) {
protectiveMBR.EmptyBootloader();
// Convert the smaller of the # of GPT or MBR partitions
- if (mainHeader.numParts > (MAX_MBR_PARTS))
+ if (numParts > MAX_MBR_PARTS)
numToConvert = MAX_MBR_PARTS;
else
- numToConvert = mainHeader.numParts;
+ numToConvert = numParts;
for (i = 0; i < numToConvert; i++) {
origType = protectiveMBR.GetType(i);
@@ -1456,7 +1461,7 @@ int GPTData::OnePartToMBR(uint32_t gptPart, int mbrPart) {
cout << "MBR partition " << mbrPart + 1 << " is out of range; omitting it.\n";
allOK = 0;
} // if
- if (gptPart >= mainHeader.numParts) {
+ if (gptPart >= numParts) {
cout << "GPT partition " << gptPart + 1 << " is out of range; omitting it.\n";
allOK = 0;
} // if
@@ -1555,8 +1560,7 @@ int GPTData::SetGPTSize(uint32_t numEntries) {
// partition table, which causes problems when loading data from a RAID
// array that's been expanded because this function is called when loading
// data.
- if (((numEntries != mainHeader.numParts) || (numEntries != secondHeader.numParts)
- || (partitions == NULL)) && (numEntries > 0)) {
+ if (((numEntries != numParts) || (partitions == NULL)) && (numEntries > 0)) {
newParts = new GPTPart [numEntries * sizeof (GPTPart)];
if (newParts != NULL) {
if (partitions != NULL) { // existing partitions; copy them over
@@ -1568,10 +1572,10 @@ int GPTData::SetGPTSize(uint32_t numEntries) {
<< "; cannot resize. Perhaps sorting will help.\n";
allOK = 0;
} else { // go ahead with copy
- if (numEntries < mainHeader.numParts)
+ if (numEntries < numParts)
copyNum = numEntries;
else
- copyNum = mainHeader.numParts;
+ copyNum = numParts;
for (i = 0; i < copyNum; i++) {
newParts[i] = partitions[i];
} // for
@@ -1582,8 +1586,7 @@ int GPTData::SetGPTSize(uint32_t numEntries) {
} else { // No existing partition table; just create it
partitions = newParts;
} // if/else existing partitions
- mainHeader.numParts = numEntries;
- secondHeader.numParts = numEntries;
+ numParts = numEntries;
mainHeader.firstUsableLBA = ((numEntries * GPT_SIZE) / blockSize) + 2 ;
secondHeader.firstUsableLBA = mainHeader.firstUsableLBA;
MoveSecondHeaderToEnd();
@@ -1594,6 +1597,8 @@ int GPTData::SetGPTSize(uint32_t numEntries) {
allOK = 0;
} // if/else
} // if/else
+ mainHeader.numParts = numParts;
+ secondHeader.numParts = numParts;
return (allOK);
} // GPTData::SetGPTSize()
@@ -1601,7 +1606,7 @@ int GPTData::SetGPTSize(uint32_t numEntries) {
void GPTData::BlankPartitions(void) {
uint32_t i;
- for (i = 0; i < mainHeader.numParts; i++) {
+ for (i = 0; i < numParts; i++) {
partitions[i].BlankPartition();
} // for
} // GPTData::BlankPartitions()
@@ -1611,10 +1616,10 @@ void GPTData::BlankPartitions(void) {
// range, 0 if it was out of range.
int GPTData::DeletePartition(uint32_t partNum) {
uint64_t startSector, length;
- uint32_t low, high, numParts, retval = 1;;
+ uint32_t low, high, numUsedParts, retval = 1;;
- numParts = GetPartRange(&low, &high);
- if ((numParts > 0) && (partNum >= low) && (partNum <= high)) {
+ numUsedParts = GetPartRange(&low, &high);
+ if ((numUsedParts > 0) && (partNum >= low) && (partNum <= high)) {
// In case there's a protective MBR, look for & delete matching
// MBR partition....
startSector = partitions[partNum].GetFirstLBA();
@@ -1712,7 +1717,7 @@ int GPTData::SwapPartitions(uint32_t partNum1, uint32_t partNum2) {
GPTPart temp;
int allOK = 1;
- if ((partNum1 < mainHeader.numParts) && (partNum2 < mainHeader.numParts)) {
+ if ((partNum1 < numParts) && (partNum2 < numParts)) {
if (partNum1 != partNum2) {
temp = partitions[partNum1];
partitions[partNum1] = partitions[partNum2];
@@ -1805,7 +1810,7 @@ void GPTData::SetDiskGUID(GUIDData newGUID) {
int GPTData::SetPartitionGUID(uint32_t pn, GUIDData theGUID) {
int retval = 0;
- if (pn < mainHeader.numParts) {
+ if (pn < numParts) {
if (partitions[pn].GetFirstLBA() != UINT64_C(0)) {
partitions[pn].SetUniqueGUID(theGUID);
retval = 1;
@@ -1908,14 +1913,14 @@ int GPTData::GetPartRange(uint32_t *low, uint32_t *high) {
uint32_t i;
int numFound = 0;
- *low = mainHeader.numParts + 1; // code for "not found"
+ *low = numParts + 1; // code for "not found"
*high = 0;
- if (mainHeader.numParts > 0) { // only try if partition table exists...
- for (i = 0; i < mainHeader.numParts; i++) {
+ if (numParts > 0) { // only try if partition table exists...
+ for (i = 0; i < numParts; i++) {
if (partitions[i].GetFirstLBA() != UINT64_C(0)) { // it exists
*high = i; // since we're counting up, set the high value
// Set the low value only if it's not yet found...
- if (*low == (mainHeader.numParts + 1)) *low = i;
+ if (*low == (numParts + 1)) *low = i;
numFound++;
} // if
} // for
@@ -1923,7 +1928,7 @@ int GPTData::GetPartRange(uint32_t *low, uint32_t *high) {
// Above will leave *low pointing to its "not found" value if no partitions
// are defined, so reset to 0 if this is the case....
- if (*low == (mainHeader.numParts + 1))
+ if (*low == (numParts + 1))
*low = 0;
return numFound;
} // GPTData::GetPartRange()
@@ -1934,9 +1939,9 @@ int GPTData::FindFirstFreePart(void) {
int i = 0;
if (partitions != NULL) {
- while ((partitions[i].IsUsed()) && (i < (int) mainHeader.numParts))
+ while ((partitions[i].IsUsed()) && (i < (int) numParts))
i++;
- if (i >= (int) mainHeader.numParts)
+ if (i >= (int) numParts)
i = -1;
} else i = -1;
return i;
@@ -1946,7 +1951,7 @@ int GPTData::FindFirstFreePart(void) {
uint32_t GPTData::CountParts(void) {
uint32_t i, counted = 0;
- for (i = 0; i < mainHeader.numParts; i++) {
+ for (i = 0; i < numParts; i++) {
if (partitions[i].IsUsed())
counted++;
} // for
@@ -1980,7 +1985,7 @@ uint64_t GPTData::FindFirstAvailable(uint64_t start) {
// cases where partitions are out of sequential order....
do {
firstMoved = 0;
- for (i = 0; i < mainHeader.numParts; i++) {
+ for (i = 0; i < numParts; i++) {
if ((first >= partitions[i].GetFirstLBA()) &&
(first <= partitions[i].GetLastLBA())) { // in existing part.
first = partitions[i].GetLastLBA() + 1;
@@ -2030,7 +2035,7 @@ uint64_t GPTData::FindLastAvailable(void) {
// where partitions are out of logical order.
do {
lastMoved = 0;
- for (i = 0; i < mainHeader.numParts; i++) {
+ for (i = 0; i < numParts; i++) {
if ((last >= partitions[i].GetFirstLBA()) &&
(last <= partitions[i].GetLastLBA())) { // in existing part.
last = partitions[i].GetFirstLBA() - 1;
@@ -2049,7 +2054,7 @@ uint64_t GPTData::FindLastInFree(uint64_t start) {
uint32_t i;
nearestStart = mainHeader.lastUsableLBA;
- for (i = 0; i < mainHeader.numParts; i++) {
+ for (i = 0; i < numParts; i++) {
if ((nearestStart > partitions[i].GetFirstLBA()) &&
(partitions[i].GetFirstLBA() > start)) {
nearestStart = partitions[i].GetFirstLBA() - 1;
@@ -2094,7 +2099,7 @@ int GPTData::IsFree(uint64_t sector, uint32_t *partNum) {
int isFree = 1;
uint32_t i;
- for (i = 0; i < mainHeader.numParts; i++) {
+ for (i = 0; i < numParts; i++) {
if ((sector >= partitions[i].GetFirstLBA()) &&
(sector <= partitions[i].GetLastLBA())) {
isFree = 0;
@@ -2115,7 +2120,7 @@ int GPTData::IsFree(uint64_t sector, uint32_t *partNum) {
int GPTData::IsFreePartNum(uint32_t partNum) {
int retval = 1;
- if ((partNum < mainHeader.numParts) && (partitions != NULL)) {
+ if ((partNum < numParts) && (partitions != NULL)) {
if (partitions[partNum].IsUsed()) {
retval = 0;
} // if partition is in use
@@ -2157,7 +2162,7 @@ uint32_t GPTData::ComputeAlignment(void) {
uint64_t align = DEFAULT_ALIGNMENT;
exponent = (uint32_t) log2(DEFAULT_ALIGNMENT);
- for (i = 0; i < mainHeader.numParts; i++) {
+ for (i = 0; i < numParts; i++) {
if (partitions[i].IsUsed()) {
found = 0;
while (!found) {
@@ -2199,19 +2204,11 @@ void GPTData::ReverseHeaderBytes(struct GPTHeader* header) {
ReverseBytes(header->reserved2, GPT_RESERVED);
} // GPTData::ReverseHeaderBytes()
-// IMPORTANT NOTE: This function requires non-reversed mainHeader
-// structure!
+// Reverse byte order for all partitions.
void GPTData::ReversePartitionBytes() {
uint32_t i;
- // Check GPT signature on big-endian systems; this will mismatch
- // if the function is called out of order. Unfortunately, it'll also
- // mismatch if there's data corruption.
- if ((mainHeader.signature != GPT_SIGNATURE) && (IsLittleEndian() == 0)) {
- cerr << "GPT signature mismatch in GPTData::ReversePartitionBytes(). This indicates\n"
- << "data corruption or a misplaced call to this function.\n";
- } // if signature mismatch....
- for (i = 0; i < mainHeader.numParts; i++) {
+ for (i = 0; i < numParts; i++) {
partitions[i].ReversePartBytes();
} // for
} // GPTData::ReversePartitionBytes()
diff --git a/gpt.h b/gpt.h
index cae0339..751229c 100644
--- a/gpt.h
+++ b/gpt.h
@@ -16,7 +16,7 @@
#ifndef __GPTSTRUCTS
#define __GPTSTRUCTS
-#define GPTFDISK_VERSION "0.6.6"
+#define GPTFDISK_VERSION "0.6.7-pre1"
// Constants used by GPTData::PartsToMBR(). MBR_EMPTY must be the lowest-
// numbered value to refer to partition numbers. (Most will be 0 or positive,
@@ -75,6 +75,7 @@ class GPTData {
protected:
struct GPTHeader mainHeader;
GPTPart *partitions;
+ uint32_t numParts;
struct GPTHeader secondHeader;
MBRData protectiveMBR;
string device; // device filename
diff --git a/gpttext.cc b/gpttext.cc
index 46e6eea..3000308 100644
--- a/gpttext.cc
+++ b/gpttext.cc
@@ -97,7 +97,7 @@ WhichToUse GPTDataTextUI::UseWhichPartitions(void) {
} else if (mbrState == invalid) {
cout << "Found invalid MBR and corrupt GPT. What do you want to do? (Using the\n"
<< "GPT MAY permit recovery of GPT data.)\n";
- answer = GetNumber(1, 2, 1, " 1 - GPT\n 2 - Create blank GPT\n\nYour answer: ");
+ answer = GetNumber(1, 2, 1, " 1 - Use current GPT\n 2 - Create blank GPT\n\nYour answer: ");
if (answer == 1) {
which = use_gpt;
} else which = use_new;
@@ -160,7 +160,7 @@ void GPTDataTextUI::ResizePartitionTable(void) {
ostringstream prompt;
uint32_t curLow, curHigh;
- cout << "Current partition table size is " << mainHeader.numParts << ".\n";
+ cout << "Current partition table size is " << numParts << ".\n";
GetPartRange(&curLow, &curHigh);
curHigh++; // since GetPartRange() returns numbers starting from 0...
// There's no point in having fewer than four partitions....
@@ -190,15 +190,15 @@ void GPTDataTextUI::CreatePartition(void) {
} // while
if (((firstBlock = FindFirstAvailable()) != 0) &&
- (firstFreePart < mainHeader.numParts)) {
+ (firstFreePart < numParts)) {
lastBlock = FindLastAvailable();
firstInLargest = FindFirstInLargest();
// Get partition number....
do {
- prompt1 << "Partition number (" << firstFreePart + 1 << "-" << mainHeader.numParts
+ prompt1 << "Partition number (" << firstFreePart + 1 << "-" << numParts
<< ", default " << firstFreePart + 1 << "): ";
- partNum = GetNumber(firstFreePart + 1, mainHeader.numParts,
+ partNum = GetNumber(firstFreePart + 1, numParts,
firstFreePart + 1, prompt1.str()) - 1;
if (partitions[partNum].GetFirstLBA() != 0)
cout << "partition " << partNum + 1 << " is in use.\n";
@@ -283,11 +283,11 @@ int GPTDataTextUI::SwapPartitions(void) {
if (GetPartRange(&low, &high) > 0) {
partNum1 = GetPartNum();
- if (high >= mainHeader.numParts - 1)
+ if (high >= numParts - 1)
high = 0;
- prompt << "New partition number (1-" << mainHeader.numParts
+ prompt << "New partition number (1-" << numParts
<< ", default " << high + 2 << "): ";
- partNum2 = GetNumber(1, mainHeader.numParts, high + 2, prompt.str()) - 1;
+ partNum2 = GetNumber(1, numParts, high + 2, prompt.str()) - 1;
didIt = GPTData::SwapPartitions(partNum1, partNum2);
} else {
cout << "No partitions\n";
@@ -344,7 +344,7 @@ void GPTDataTextUI::MakeHybrid(void) {
uint32_t partNums[3];
char line[255];
char* junk;
- int numParts, i, j, mbrNum, bootable = 0;
+ int numPartsToCvt, i, j, mbrNum, bootable = 0;
unsigned int hexCode = 0;
struct PartInfo *newNote;
PartNotes notes;
@@ -359,14 +359,14 @@ void GPTDataTextUI::MakeHybrid(void) {
cout << "Type from one to three GPT partition numbers, separated by spaces, to be\n"
<< "added to the hybrid MBR, in sequence: ";
junk = fgets(line, 255, stdin);
- numParts = sscanf(line, "%d %d %d", &partNums[0], &partNums[1], &partNums[2]);
+ numPartsToCvt = sscanf(line, "%d %d %d", &partNums[0], &partNums[1], &partNums[2]);
- if (numParts > 0) {
+ if (numPartsToCvt > 0) {
cout << "Place EFI GPT (0xEE) partition first in MBR (good for GRUB)? ";
eeFirst = GetYN();
} // if
- for (i = 0; i < numParts; i++) {
+ for (i = 0; i < numPartsToCvt; i++) {
newNote = new struct PartInfo;
j = newNote->gptPartNum = partNums[i] - 1;
mbrNum = i + (eeFirst == 'Y');
@@ -384,7 +384,7 @@ void GPTDataTextUI::MakeHybrid(void) {
notes.AddToEnd(newNote);
} // for
- if (numParts > 0) { // User opted to create a hybrid MBR....
+ if (numPartsToCvt > 0) { // User opted to create a hybrid MBR....
// Create EFI protective partition that covers the start of the disk.
// If this location (covering the main GPT data structures) is omitted,
// Linux won't find any partitions on the disk.
@@ -428,7 +428,7 @@ void GPTDataTextUI::MakeHybrid(void) {
PartsToMBR(notes);
if (bootable > 0)
protectiveMBR.SetPartBootable(bootable);
- } // if (numParts > 0)
+ } // if (numPartsToCvt > 0)
} // GPTDataTextUI::MakeHybrid()
// Assign GPT partitions to primary or logical status for conversion. The
@@ -454,8 +454,7 @@ int GPTDataTextUI::AssignPrimaryOrLogical(PartNotes & notes) {
// Takes notes on existing partitions: Create an initial assignment as
// primary or logical, set default MBR types, and then make it legal
// (drop partitions as required to fit in the MBR and as logicals).
- allOK = (notes.PassPartitions(partitions, this, mainHeader.numParts, blockSize) ==
- (int) mainHeader.numParts);
+ allOK = (notes.PassPartitions(partitions, this, numParts, blockSize) == (int) numParts);
for (i = 0; i < countedParts; i++)
notes.SetMbrHexType(i, partitions[i].GetHexType() / 255);
notes.MakeItLegal();
@@ -510,7 +509,7 @@ int GPTDataTextUI::AssignPrimaryOrLogical(PartNotes & notes) {
// is over 0, the calling function should call DestroyGPT() to destroy
// the GPT data, call SaveMBR() to save the MBR, and then exit.
int GPTDataTextUI::XFormToMBR(void) {
- int numParts, numToConvert, numReallyConverted = 0;
+ int numToConvert, numReallyConverted = 0;
int origNumParts;
PartNotes notes;
GPTPart *tempGptParts;
@@ -518,13 +517,11 @@ int GPTDataTextUI::XFormToMBR(void) {
// Back up partition array, since we'll be sorting it and we want to
// be able to restore it in case the user aborts....
- origNumParts = mainHeader.numParts;
- tempGptParts = new GPTPart[mainHeader.numParts];
- for (i = 0; i < mainHeader.numParts; i++)
+ origNumParts = numParts;
+ tempGptParts = new GPTPart[numParts];
+ for (i = 0; i < numParts; i++)
tempGptParts[i] = partitions[i];
- numParts = CountParts();
-
numToConvert = AssignPrimaryOrLogical(notes);
if (numToConvert > 0) {
diff --git a/sgdisk.cc b/sgdisk.cc
index ab6f7b2..99fa8ac 100644
--- a/sgdisk.cc
+++ b/sgdisk.cc
@@ -129,7 +129,7 @@ int main(int argc, char *argv[]) {
if (theGPT.SetName(partNum, GetString(partName, 2))) {
saveData = 1;
} else {
- cerr << "Unable set set partition " << partNum + 1
+ cerr << "Unable to set partition " << partNum + 1
<< "'s name to '" << GetString(partName, 2) << "'!\n";
neverSaveData = 1;
} // if/else