summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS12
-rw-r--r--current.spec8
-rw-r--r--gdisk.82
-rw-r--r--gpt.cc13
-rw-r--r--gpt.h4
-rw-r--r--gpttext.cc42
-rw-r--r--guid.cc24
-rw-r--r--guid.h2
-rw-r--r--mbr.cc10
-rw-r--r--mbr.h2
-rw-r--r--partnotes.cc25
-rw-r--r--sgdisk.82
-rw-r--r--sgdisk.cc2
13 files changed, 89 insertions, 59 deletions
diff --git a/NEWS b/NEWS
index f941e24..a734b09 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,15 @@
+0.6.13 (10/12/2010):
+--------------------
+
+- Added notification about nonexistent partitions to hybrid MBR creation
+ in gdisk.
+
+- Fixed bug in GPT-to-MBR conversion that could sometimes enable creation
+ of an extended partition that overlaps a preceding partition.
+
+- Fixed bug in GPT-to-MBR conversion that prevented creation of an MBR
+ table with logical partitions if there were four or fewer partitions.
+
0.6.12 (10/7/2010):
-------------------
diff --git a/current.spec b/current.spec
index 650c167..caa1a84 100644
--- a/current.spec
+++ b/current.spec
@@ -1,11 +1,11 @@
Summary: An fdisk-like partitioning tool for GPT disks
Name: gdisk
-Version: 0.6.12
+Version: 0.6.13
Release: 1%{?dist}
License: GPLv2
URL: http://www.rodsbooks.com/gdisk
Group: Applications/System
-Source: http://www.rodsbooks.com/gdisk/gdisk-0.6.12.tgz
+Source: http://www.rodsbooks.com/gdisk/gdisk-0.6.13.tgz
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
%description
@@ -40,5 +40,5 @@ rm -rf $RPM_BUILD_ROOT
%doc %{_mandir}/man8*
%changelog
-* Thu Oct 7 2010 R Smith <rodsmith@rodsbooks.com> - 0.6.12
-- Created spec file for 0.6.12 release
+* Tue Oct 12 2010 R Smith <rodsmith@rodsbooks.com> - 0.6.13
+- Created spec file for 0.6.13 release
diff --git a/gdisk.8 b/gdisk.8
index 7409f68..fdb7277 100644
--- a/gdisk.8
+++ b/gdisk.8
@@ -1,6 +1,6 @@
.\" Copyright 2010 Roderick W. Smith (rodsmith@rodsbooks.com)
.\" May be distributed under the GNU General Public License
-.TH "GDISK" "8" "0.6.12" "Roderick W. Smith" "GPT fdisk Manual"
+.TH "GDISK" "8" "0.6.13" "Roderick W. Smith" "GPT fdisk Manual"
.SH "NAME"
gdisk \- Interactive GUID partition table (GPT) manipulator
.SH "SYNOPSIS"
diff --git a/gpt.cc b/gpt.cc
index 3c9b843..2a2df8f 100644
--- a/gpt.cc
+++ b/gpt.cc
@@ -1504,15 +1504,16 @@ int GPTData::OnePartToMBR(uint32_t gptPart, int mbrPart) {
// is 0, a default entry is used, based on the GPT partition type code.
// Returns the number of partitions converted, NOT counting EFI GPT
// protective partitions or extended partitions.
-int GPTData::PartsToMBR(PartNotes & notes) {
+int GPTData::PartsToMBR(PartNotes * notes) {
int mbrNum = 0, numConverted = 0;
struct PartInfo convInfo;
protectiveMBR.EmptyMBR(0);
protectiveMBR.SetDiskSize(diskSize);
- notes.MakeItLegal();
- notes.Rewind();
- while (notes.GetNextInfo(&convInfo) >= 0) {
+ if (!notes->IsLegal())
+ notes->MakeItLegal();
+ notes->Rewind();
+ while (notes->GetNextInfo(&convInfo) >= 0) {
if ((convInfo.gptPartNum >= 0) && (convInfo.type == PRIMARY)) {
numConverted += OnePartToMBR((uint32_t) convInfo.gptPartNum, mbrNum);
if (convInfo.hexCode != 0)
@@ -1525,9 +1526,9 @@ int GPTData::PartsToMBR(PartNotes & notes) {
mbrNum++;
} // for
// Now go through and set sizes for MBR_EFI_GPT partitions....
- notes.Rewind();
+ notes->Rewind();
mbrNum = 0;
- while (notes.GetNextInfo(&convInfo) >= 0) {
+ while (notes->GetNextInfo(&convInfo) >= 0) {
if ((convInfo.gptPartNum >= 0) && (convInfo.type == PRIMARY))
mbrNum++;
if (convInfo.gptPartNum == MBR_EFI_GPT) {
diff --git a/gpt.h b/gpt.h
index 9820cae..e92b8b1 100644
--- a/gpt.h
+++ b/gpt.h
@@ -16,7 +16,7 @@
#ifndef __GPTSTRUCTS
#define __GPTSTRUCTS
-#define GPTFDISK_VERSION "0.6.12"
+#define GPTFDISK_VERSION "0.6.13"
// Constants used by GPTData::PartsToMBR(). MBR_EMPTY must be the lowest-
// numbered value to refer to partition numbers. (Most will be 0 or positive,
@@ -145,7 +145,7 @@ public:
virtual int XFormDisklabel(uint32_t partNum);
int XFormDisklabel(BSDData* disklabel);
int OnePartToMBR(uint32_t gptPart, int mbrPart); // add one partition to MBR. Returns 1 if successful
- int PartsToMBR(PartNotes & notes);
+ int PartsToMBR(PartNotes * notes);
// Adjust GPT structures WITHOUT user interaction...
int SetGPTSize(uint32_t numEntries);
diff --git a/gpttext.cc b/gpttext.cc
index 69c2a6c..0bc0ae2 100644
--- a/gpttext.cc
+++ b/gpttext.cc
@@ -360,9 +360,9 @@ void GPTDataTextUI::MakeHybrid(void) {
PartNotes notes;
char eeFirst = 'Y'; // Whether EFI GPT (0xEE) partition comes first in table
- cout << "\nWARNING! Hybrid MBRs are flaky and potentially dangerous! If you decide not\n"
- << "to use one, just hit the Enter key at the below prompt and your MBR\n"
- << "partition table will be untouched.\n\n\a";
+ cout << "\nWARNING! Hybrid MBRs are flaky and dangerous! If you decide not to use one,\n"
+ << "just hit the Enter key at the below prompt and your MBR partition table will\n"
+ << "be untouched.\n\n\a";
// Now get the numbers of up to three partitions to add to the
// hybrid MBR....
@@ -379,19 +379,24 @@ void GPTDataTextUI::MakeHybrid(void) {
for (i = 0; i < numPartsToCvt; i++) {
newNote = new struct PartInfo;
j = newNote->gptPartNum = partNums[i] - 1;
- mbrNum = i + (eeFirst == 'Y');
- cout << "\nCreating entry for GPT partition #" << j + 1
- << " (MBR partition #" << mbrNum + 1 << ")\n";
- newNote->hexCode = GetMBRTypeCode(partitions[j].GetHexType() / 256);
- newNote->firstLBA = partitions[j].GetFirstLBA();
- newNote->lastLBA = partitions[j].GetLastLBA();
- newNote->type = PRIMARY;
- cout << "Set the bootable flag? ";
- if (GetYN() == 'Y')
- newNote->active = 1;
- else
- newNote->active = 0;
- notes.AddToEnd(newNote);
+ if (partitions[j].IsUsed()) {
+ mbrNum = i + (eeFirst == 'Y');
+ cout << "\nCreating entry for GPT partition #" << j + 1
+ << " (MBR partition #" << mbrNum + 1 << ")\n";
+ newNote->hexCode = GetMBRTypeCode(partitions[j].GetHexType() / 256);
+ newNote->firstLBA = partitions[j].GetFirstLBA();
+ newNote->lastLBA = partitions[j].GetLastLBA();
+ newNote->type = PRIMARY;
+ cout << "Set the bootable flag? ";
+ if (GetYN() == 'Y')
+ newNote->active = 1;
+ else
+ newNote->active = 0;
+ notes.AddToEnd(newNote);
+ } else {
+ delete newNote;
+ cerr << "\nGPT partition #" << j + 1 << " does not exist; skipping.\n";
+ } // if/else
} // for
if (numPartsToCvt > 0) { // User opted to create a hybrid MBR....
@@ -436,7 +441,7 @@ void GPTDataTextUI::MakeHybrid(void) {
notes.AddToEnd(newNote);
} // if (GetYN() == 'Y')
} // if unused entry
- PartsToMBR(notes);
+ PartsToMBR(&notes);
if (bootable > 0)
protectiveMBR.SetPartBootable(bootable);
} // if (numPartsToCvt > 0)
@@ -533,10 +538,11 @@ int GPTDataTextUI::XFormToMBR(void) {
for (i = 0; i < numParts; i++)
tempGptParts[i] = partitions[i];
+ notes.MakeItLegal();
numToConvert = AssignPrimaryOrLogical(notes);
if (numToConvert > 0) {
- numReallyConverted = PartsToMBR(notes);
+ numReallyConverted = PartsToMBR(&notes);
if (numReallyConverted != numToConvert) {
cerr << "Error converting partitions to MBR; tried to convert "
<< numToConvert << " partitions,\nbut converted " << numReallyConverted
diff --git a/guid.cc b/guid.cc
index 8e4d7dd..7b4b378 100644
--- a/guid.cc
+++ b/guid.cc
@@ -92,24 +92,24 @@ GUIDData & GUIDData::operator=(const string & orig) {
uuidData[0] = StrToHex(copy, 6);
} // if
if (len >= segStart[2]) {
- uuidData[5] = StrToHex(copy, segStart[1]);
- uuidData[4] = StrToHex(copy, segStart[1] + 2);
+ uuidData[5] = StrToHex(copy, (unsigned int) segStart[1]);
+ uuidData[4] = StrToHex(copy, (unsigned int) segStart[1] + 2);
} // if
if (len >= segStart[3]) {
- uuidData[7] = StrToHex(copy, segStart[2]);
- uuidData[6] = StrToHex(copy, segStart[2] + 2);
+ uuidData[7] = StrToHex(copy, (unsigned int) segStart[2]);
+ uuidData[6] = StrToHex(copy, (unsigned int) segStart[2] + 2);
} // if
if (len >= segStart[4]) {
- uuidData[8] = StrToHex(copy, segStart[3]);
- uuidData[9] = StrToHex(copy, segStart[3] + 2);
+ uuidData[8] = StrToHex(copy, (unsigned int) segStart[3]);
+ uuidData[9] = StrToHex(copy, (unsigned int) segStart[3] + 2);
} // if
if (len >= segStart[5]) {
- uuidData[10] = StrToHex(copy, segStart[4]);
- uuidData[11] = StrToHex(copy, segStart[4] + 2);
- uuidData[12] = StrToHex(copy, segStart[4] + 4);
- uuidData[13] = StrToHex(copy, segStart[4] + 6);
- uuidData[14] = StrToHex(copy, segStart[4] + 8);
- uuidData[15] = StrToHex(copy, segStart[4] + 10);
+ uuidData[10] = StrToHex(copy, (unsigned int) segStart[4]);
+ uuidData[11] = StrToHex(copy, (unsigned int) segStart[4] + 2);
+ uuidData[12] = StrToHex(copy, (unsigned int) segStart[4] + 4);
+ uuidData[13] = StrToHex(copy, (unsigned int) segStart[4] + 6);
+ uuidData[14] = StrToHex(copy, (unsigned int) segStart[4] + 8);
+ uuidData[15] = StrToHex(copy, (unsigned int) segStart[4] + 10);
} // if
} // if/else randomize/set value
diff --git a/guid.h b/guid.h
index d22ec86..224302c 100644
--- a/guid.h
+++ b/guid.h
@@ -22,7 +22,7 @@
#ifdef _WIN32
typedef unsigned char my_uuid_t[16];
#else
-#include <uuid/uuid.h>
+#include </usr/include/uuid/uuid.h>
typedef uuid_t my_uuid_t;
#endif
diff --git a/mbr.cc b/mbr.cc
index 782fd81..1d840cc 100644
--- a/mbr.cc
+++ b/mbr.cc
@@ -830,14 +830,14 @@ void MBRData::RecomputeCHS(int partNum) {
// entries are written to disk; that is left for the WriteMBRData()
// function.
// Returns number of converted partitions
-int MBRData::CreateLogicals(PartNotes& notes) {
+int MBRData::CreateLogicals(PartNotes * notes) {
uint64_t extEndLBA = 0, extStartLBA = UINT64_MAX;
int i = 4, numLogicals = 0;
struct PartInfo aPart;
// Find bounds of the extended partition....
- notes.Rewind();
- while (notes.GetNextInfo(&aPart) >= 0) {
+ notes->Rewind();
+ while (notes->GetNextInfo(&aPart) >= 0) {
if (aPart.type == LOGICAL) {
if (extStartLBA > aPart.firstLBA)
extStartLBA = aPart.firstLBA;
@@ -849,9 +849,9 @@ int MBRData::CreateLogicals(PartNotes& notes) {
extStartLBA--;
if ((extStartLBA < UINT32_MAX) && ((extEndLBA - extStartLBA + 1) < UINT32_MAX)) {
- notes.Rewind();
+ notes->Rewind();
i = 4;
- while ((notes.GetNextInfo(&aPart) >= 0) && (i < MAX_MBR_PARTS)) {
+ while ((notes->GetNextInfo(&aPart) >= 0) && (i < MAX_MBR_PARTS)) {
if (aPart.type == LOGICAL) {
partitions[i].partitionType = aPart.hexCode;
partitions[i].firstLBA = (uint32_t) (aPart.firstLBA - extStartLBA);
diff --git a/mbr.h b/mbr.h
index b434ac0..85b1841 100644
--- a/mbr.h
+++ b/mbr.h
@@ -126,7 +126,7 @@ public:
int DeleteByLocation(uint64_t start64, uint64_t length64);
void OptimizeEESize(void);
void RecomputeCHS(int partNum);
- int CreateLogicals(PartNotes& notes);
+ int CreateLogicals(PartNotes * notes);
// Functions to find information on free space....
uint32_t FindFirstAvailable(uint32_t start = 1);
diff --git a/partnotes.cc b/partnotes.cc
index bbb38f3..70196f7 100644
--- a/partnotes.cc
+++ b/partnotes.cc
@@ -437,11 +437,18 @@ int PartNotes::IsSorted(void) {
// Returns 1 if the set as a whole makes a legal MBR partition table
// (possibly with logicals), 0 if not
int PartNotes::IsLegal(void) {
- int p, e;
+ int p, e, legalLogicals = 1;
+ struct PartInfo *theNote;
p = GetNumPrimary();
e = GetNumExtended();
- return (((p+e) <= 4) && (e <= 1));
+ theNote = notes;
+ while (theNote != NULL) {
+ if ((!theNote->spaceBefore) && (theNote->type == LOGICAL))
+ legalLogicals = 0;
+ theNote = theNote->next;
+ } // while
+ return (((p+e) <= 4) && (e <= 1) && legalLogicals);
} // PartNotes::IsLegal()
/*************************************************************************
@@ -475,7 +482,7 @@ void PartNotes::RemoveDuplicates(void) {
// of included partitions. Also removes duplicates.
// Returns 1 if successful, 0 if not (if missing notes list, say)
int PartNotes::MakeItLegal(void) {
- struct PartInfo *theNote, *lastPrimary;
+ struct PartInfo *theNote, *lastPrimary, *firstPart;
if (notes == NULL)
return 0;
@@ -483,6 +490,7 @@ int PartNotes::MakeItLegal(void) {
RemoveDuplicates();
if (!IsLegal()) {
+ cout << "Isn't legal!\n";
// Start by eliminating or converting excessive extended partitions...
while (GetNumExtended() > 1)
TrimSmallestExtended();
@@ -514,11 +522,14 @@ int PartNotes::MakeItLegal(void) {
// Try to make the first partition a primary...
if ((GetNumExtended() + GetNumPrimary()) < 4) {
theNote = notes;
- do {
+ firstPart = notes;
+ while ((theNote != NULL) && (firstPart != NULL)) {
+ if ((theNote->firstLBA < firstPart->firstLBA) && (theNote->type != WILL_NOT_CONVERT))
+ firstPart = theNote;
theNote = theNote->next;
- } while ((theNote != NULL) && (theNote->type != WILL_NOT_CONVERT));
- if ((theNote != NULL) && (theNote->type == LOGICAL))
- theNote->type = PRIMARY;
+ };
+ if (firstPart->spaceBefore)
+ firstPart->type = PRIMARY;
} // if
return IsLegal();
diff --git a/sgdisk.8 b/sgdisk.8
index 2a9560e..4b75053 100644
--- a/sgdisk.8
+++ b/sgdisk.8
@@ -1,6 +1,6 @@
.\" Copyright 2010 Roderick W. Smith (rodsmith@rodsbooks.com)
.\" May be distributed under the GNU General Public License
-.TH "SGDISK" "8" "0.6.12" "Roderick W. Smith" "GPT fdisk Manual"
+.TH "SGDISK" "8" "0.6.13" "Roderick W. Smith" "GPT fdisk Manual"
.SH "NAME"
sgdisk \- Command\-line GUID partition table (GPT) manipulator for Linux and Unix
.SH "SYNOPSIS"
diff --git a/sgdisk.cc b/sgdisk.cc
index b0959a5..fc56202 100644
--- a/sgdisk.cc
+++ b/sgdisk.cc
@@ -439,7 +439,7 @@ int BuildMBR(GPTData & theGPT, char* argument, int isHybrid) {
// newNote firstLBA and lastLBA are computed later...
notes.AddToStart(newNote);
} // if
- if (theGPT.PartsToMBR(notes) != numParts)
+ if (theGPT.PartsToMBR(&notes) != numParts)
allOK = 0;
} else allOK = 0;
} else allOK = 0;