Version 0.6.13: GPT-to-MBR conversion bug fixes.
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 @@
 %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 @@
 // 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 @@
          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 @@
    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 @@
    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 @@
    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 @@
             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 @@
    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 @@
          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 @@
 // 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 @@
    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 @@
    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 @@
 // 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 @@
 // 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 @@
    RemoveDuplicates();
 
    if (!IsLegal()) {
+      cout << "Isn't legal!\n";
       // Start by eliminating or converting excessive extended partitions...
       while (GetNumExtended() > 1)
          TrimSmallestExtended();
@@ -514,11 +522,14 @@
    // 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 @@
             // 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;