diff options
-rw-r--r-- | NEWS | 12 | ||||
-rw-r--r-- | current.spec | 8 | ||||
-rw-r--r-- | gdisk.8 | 2 | ||||
-rw-r--r-- | gpt.cc | 13 | ||||
-rw-r--r-- | gpt.h | 4 | ||||
-rw-r--r-- | gpttext.cc | 42 | ||||
-rw-r--r-- | guid.cc | 24 | ||||
-rw-r--r-- | guid.h | 2 | ||||
-rw-r--r-- | mbr.cc | 10 | ||||
-rw-r--r-- | mbr.h | 2 | ||||
-rw-r--r-- | partnotes.cc | 25 | ||||
-rw-r--r-- | sgdisk.8 | 2 | ||||
-rw-r--r-- | sgdisk.cc | 2 |
13 files changed, 89 insertions, 59 deletions
@@ -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 @@ -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" @@ -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) { @@ -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); @@ -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(¬es); 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(¬es); if (numReallyConverted != numToConvert) { cerr << "Error converting partitions to MBR; tried to convert " << numToConvert << " partitions,\nbut converted " << numReallyConverted @@ -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 @@ -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 @@ -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); @@ -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(); @@ -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" @@ -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(¬es) != numParts) allOK = 0; } else allOK = 0; } else allOK = 0; |