diff --git a/gpt.cc b/gpt.cc
new file mode 100644
index 0000000..83bf046
--- /dev/null
+++ b/gpt.cc
@@ -0,0 +1,1660 @@
+/* gpt.cc -- Functions for loading, saving, and manipulating legacy MBR and GPT partition
+   data. */
+
+/* By Rod Smith, January to February, 2009 */
+
+#define __STDC_LIMIT_MACROS
+#define __STDC_CONSTANT_MACROS
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <string.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include "crc32.h"
+#include "gpt.h"
+#include "support.h"
+#include "parttypes.h"
+#include "attributes.h"
+
+using namespace std;
+
+/****************************************
+ *                                      *
+ * GPTData class and related structures *
+ *                                      *
+ ****************************************/
+
+GPTData::GPTData(void) {
+   blockSize = SECTOR_SIZE; // set a default
+   diskSize = 0;
+   partitions = NULL;
+   state = gpt_valid;
+   strcpy(device, "");
+   mainCrcOk = 0;
+   secondCrcOk = 0;
+   mainPartsCrcOk = 0;
+   secondPartsCrcOk = 0;
+   srand((unsigned int) time(NULL));
+   SetGPTSize(NUM_GPT_ENTRIES);
+} // GPTData default constructor
+
+// The following constructor loads GPT data from a device file
+GPTData::GPTData(char* filename) {
+   blockSize = SECTOR_SIZE; // set a default
+   diskSize = 0;
+   partitions = NULL;
+   state = gpt_invalid;
+   strcpy(device, "");
+   mainCrcOk = 0;
+   secondCrcOk = 0;
+   mainPartsCrcOk = 0;
+   secondPartsCrcOk = 0;
+   srand((unsigned int) time(NULL));
+   LoadPartitions(filename);
+} // GPTData(char* filename) constructor
+
+GPTData::~GPTData(void) {
+   free(partitions);
+} // GPTData destructor
+
+// Resizes GPT to specified number of entries. Creates a new table if
+// necessary, copies data if it already exists.
+int GPTData::SetGPTSize(uint32_t numEntries) {
+   struct GPTPartition* newParts;
+   struct GPTPartition* trash;
+   uint32_t i, high, copyNum;
+   int allOK = 1;
+
+   // First, adjust numEntries upward, if necessary, to get a number
+   // that fills the allocated sectors
+   i = blockSize / GPT_SIZE;
+   if ((numEntries % i) != 0) {
+      printf("Adjusting GPT size from %lu ", (unsigned long) numEntries);
+      numEntries = ((numEntries / i) + 1) * i;
+      printf("to %lu to fill the sector\n", (unsigned long) numEntries);
+   } // if
+
+   newParts = (struct GPTPartition*) calloc(numEntries, sizeof (struct GPTPartition));
+   if (newParts != NULL) {
+      if (partitions != NULL) { // existing partitions; copy them over
+         GetPartRange(&i, &high);
+         if (numEntries < (high + 1)) { // Highest entry too high for new #
+            printf("The highest-numbered partition is %lu, which is greater than the requested\n"
+                   "partition table size of %d; cannot resize. Perhaps sorting will help.\n",
+                   (unsigned long) (high + 1), numEntries);
+            allOK = 0;
+         } else { // go ahead with copy
+            if (numEntries < mainHeader.numParts)
+               copyNum = numEntries;
+            else
+               copyNum = mainHeader.numParts;
+            for (i = 0; i < copyNum; i++) {
+               newParts[i] = partitions[i];
+            } // for
+            trash = partitions;
+            partitions = newParts;
+            free(trash);
+         } // if
+      } else { // No existing partition table; just create it
+         partitions = newParts;
+      } // if/else existing partitions
+      mainHeader.numParts = numEntries;
+      secondHeader.numParts = numEntries;
+      mainHeader.firstUsableLBA = ((numEntries * GPT_SIZE) / blockSize) + 2 ;
+      secondHeader.firstUsableLBA = mainHeader.firstUsableLBA;
+      mainHeader.lastUsableLBA = diskSize - mainHeader.firstUsableLBA;
+      secondHeader.lastUsableLBA = mainHeader.lastUsableLBA;
+      secondHeader.partitionEntriesLBA = secondHeader.lastUsableLBA + UINT64_C(1);
+      if (diskSize > 0)
+         CheckGPTSize();
+   } else { // Bad memory allocation
+      fprintf(stderr, "Error allocating memory for partition table!\n");
+      allOK = 0;
+   } // if/else
+   return (allOK);
+} // GPTData::SetGPTSize()
+
+// Checks to see if the GPT tables overrun existing partitions; if they
+// do, issues a warning but takes no action. Returns 1 if all is OK, 0
+// if problems were detected.
+int GPTData::CheckGPTSize(void) {
+   uint64_t overlap, firstUsedBlock, lastUsedBlock;
+   uint32_t i;
+   int allOK = 1;
+
+   // first, locate the first & last used blocks
+   firstUsedBlock = UINT64_MAX;
+   lastUsedBlock = 0;
+   for (i = 0; i < mainHeader.numParts; i++) {
+      if ((partitions[i].firstLBA < firstUsedBlock) &&
+          (partitions[i].firstLBA != 0))
+         firstUsedBlock = partitions[i].firstLBA;
+      if (partitions[i].lastLBA > lastUsedBlock)
+         lastUsedBlock = partitions[i].lastLBA;
+   } // for
+
+   // If the disk size is 0 (the default), then it means that various
+   // variables aren't yet set, so the below tests will be useless;
+   // therefore we should skip everything
+   if (diskSize != 0) {
+      if (mainHeader.firstUsableLBA > firstUsedBlock) {
+         overlap = mainHeader.firstUsableLBA - firstUsedBlock;
+         printf("Warning! Main partition table overlaps the first partition by %lu\n"
+                "blocks! Try reducing the partition table size by %lu entries.\n",
+                (unsigned long) overlap, (unsigned long) (overlap * 4));
+         printf("(Use the 's' item on the experts' menu.)\n");
+         allOK = 0;
+      } // Problem at start of disk
+      if (mainHeader.lastUsableLBA < lastUsedBlock) {
+         overlap = lastUsedBlock - mainHeader.lastUsableLBA;
+         printf("Warning! Secondary partition table overlaps the last partition by %lu\n"
+                "blocks! Try reducing the partition table size by %lu entries.\n",
+                (unsigned long) overlap, (unsigned long) (overlap * 4));
+         printf("(Use the 's' item on the experts' menu.)\n");
+         allOK = 0;
+      } // Problem at end of disk
+   } // if (diskSize != 0)
+   return allOK;
+} // GPTData::CheckGPTSize()
+
+// Read GPT data from a disk.
+int GPTData::LoadPartitions(char* deviceFilename) {
+   int fd, err;
+   int allOK = 1, i;
+   uint64_t firstBlock, lastBlock;
+
+   if ((fd = open(deviceFilename, O_RDONLY)) != -1) {
+      // store disk information....
+      diskSize = disksize(fd, &err);
+      blockSize = (uint32_t) GetBlockSize(fd);
+      strcpy(device, deviceFilename);
+
+      // Read the MBR
+      protectiveMBR.ReadMBRData(fd);
+
+      // Load the GPT data, whether or not it's valid
+      ForceLoadGPTData(fd);
+
+      switch (UseWhichPartitions()) {
+         case use_mbr:
+//            printf("In LoadPartitions(), using MBR\n");
+            XFormPartitions(&protectiveMBR);
+            break;
+         case use_gpt:
+            break;
+         case use_new:
+//            printf("In LoadPartitions(), making new\n");
+            ClearGPTData();
+            protectiveMBR.MakeProtectiveMBR();
+            break;
+      } // switch
+
+      // Now find the first and last sectors used by partitions...
+      if (allOK) {
+         firstBlock = mainHeader.backupLBA; // start high
+	 lastBlock = 0; // start low
+         for (i = 0; i < mainHeader.numParts; i++) {
+	    if ((partitions[i].firstLBA < firstBlock) &&
+                (partitions[i].firstLBA > 0))
+	       firstBlock = partitions[i].firstLBA;
+            if (partitions[i].lastLBA > lastBlock)
+               lastBlock = partitions[i].lastLBA;
+	 } // for
+      } // if
+      CheckGPTSize();
+   } else {
+      allOK = 0;
+      fprintf(stderr, "Problem opening %s for reading!\n",
+              deviceFilename);
+   } // if/else
+   return (allOK);
+} // GPTData::LoadPartitions()
+
+// Loads the GPT, as much as possible. Returns 1 if this seems to have
+// succeeded, 0 if there are obvious problems....
+int GPTData::ForceLoadGPTData(int fd) {
+   int allOK = 1, validHeaders;
+   off_t seekTo;
+   char* storage;
+   uint32_t newCRC, sizeOfParts;
+
+   // Seek to and read the main GPT header
+   lseek64(fd, 512, SEEK_SET);
+   read(fd, &mainHeader, 512); // read main GPT header
+   mainCrcOk = CheckHeaderCRC(&mainHeader);
+
+   // Load backup header, check its CRC, and store the results of
+   // the check for future reference
+   seekTo = (diskSize * blockSize) - UINT64_C(512);
+   if (lseek64(fd, seekTo, SEEK_SET) != (off_t) -1) {
+      read(fd, &secondHeader, 512); // read secondary GPT header
+      secondCrcOk = CheckHeaderCRC(&secondHeader);
+   } else {
+      allOK = 0;
+      state = gpt_invalid;
+      fprintf(stderr, "Unable to seek to secondary GPT at sector %llu!\n",
+              diskSize - (UINT64_C(1)));
+   } // if/else lseek
+
+   // Return valid headers code: 0 = both headers bad; 1 = main header
+   // good, backup bad; 2 = backup header good, main header bad;
+   // 3 = both headers good. Note these codes refer to valid GPT
+   // signatures and version numbers; more subtle problems will elude
+   // this check!
+   validHeaders = CheckHeaderValidity();
+
+   // Read partitions (from primary array)
+   if (validHeaders > 0) { // if at least one header is OK....
+      // GPT appears to be valid....
+      state = gpt_valid;
+
+      // We're calling the GPT valid, but there's a possibility that one
+      // of the two headers is corrupt. If so, use the one that seems to
+      // be in better shape to regenerate the bad one
+      if (validHeaders == 2) { // valid backup header, invalid main header
+         printf("Caution: invalid main GPT header, but valid backup; regenerating main header\n"
+                "from backup!\n");
+         RebuildMainHeader();
+         mainCrcOk = secondCrcOk; // Since copied, use CRC validity of backup
+      } else if (validHeaders == 1) { // valid main header, invalid backup
+         printf("Caution: invalid backup GPT header, but valid main header; regenerating\n"
+                "backup header from main header.\n");
+         RebuildSecondHeader();
+         secondCrcOk = mainCrcOk; // Since regenerated, use CRC validity of main
+      } // if/else/if
+
+      // Load the main partition table, including storing results of its
+      // CRC check
+      if (LoadMainTable() == 0)
+         allOK = 0;
+
+      // Load backup 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
+      seekTo = secondHeader.partitionEntriesLBA * (off_t) blockSize;
+      if ((lseek64(fd, seekTo, SEEK_SET) != (off_t) -1) && (secondCrcOk)) {
+         sizeOfParts = secondHeader.numParts * secondHeader.sizeOfPartitionEntries;
+         storage = (char*) malloc(sizeOfParts);
+         read(fd, storage, sizeOfParts);
+         newCRC = chksum_crc32((unsigned char*) storage,  sizeOfParts);
+         free(storage);
+         secondPartsCrcOk = (newCRC == secondHeader.partitionEntriesCRC);
+      } // if
+
+      // Check for valid CRCs and warn if there are problems
+      if ((mainCrcOk == 0) || (secondCrcOk == 0) || (mainPartsCrcOk == 0) ||
+          (secondPartsCrcOk == 0)) {
+         printf("Warning! One or more CRCs don't match. You should repair the disk!\n");
+	 state = gpt_corrupt;
+      } // if
+   } else {
+      state = gpt_invalid;
+   } // if/else
+   return allOK;
+} // GPTData::ForceLoadGPTData()
+
+// Loads the partition tables pointed to by the main GPT header. The
+// main GPT header in memory MUST be valid for this call to do anything
+// sensible!
+int GPTData::LoadMainTable(void) {
+   int fd, retval = 0;
+   uint32_t newCRC, sizeOfParts;
+
+   if ((fd = open(device, O_RDONLY)) != -1) {
+      // Set internal data structures for number of partitions on the disk
+      SetGPTSize(mainHeader.numParts);
+
+      // Load main partition table, and record whether its CRC
+      // matches the stored value
+      lseek64(fd, mainHeader.partitionEntriesLBA * blockSize, SEEK_SET);
+      sizeOfParts = mainHeader.numParts * mainHeader.sizeOfPartitionEntries;
+      read(fd, partitions, sizeOfParts);
+      newCRC = chksum_crc32((unsigned char*) partitions, sizeOfParts);
+      mainPartsCrcOk = (newCRC == mainHeader.partitionEntriesCRC);
+      retval = 1;
+   } // if
+   return retval;
+} // GPTData::LoadMainTable()
+
+// Examines the MBR & GPT data, and perhaps asks the user questions, to
+// determine which set of data to use: the MBR (use_mbr), the GPT (use_gpt),
+// or create a new set of partitions (use_new)
+WhichToUse GPTData::UseWhichPartitions(void) {
+   WhichToUse which = use_new;
+   MBRValidity mbrState;
+   int answer;
+
+   mbrState = protectiveMBR.GetValidity();
+
+   if ((state == gpt_invalid) && (mbrState == mbr)) {
+      printf("\n\a***************************************************************\n"
+                    "Found invalid GPT and valid MBR; converting MBR to GPT format.\n"
+             "THIS OPERATON IS POTENTIALLY DESTRUCTIVE! Exit by typing 'q' if\n"
+             "you don't want to convert your MBR partitions to GPT format!\n"
+             "***************************************************************\n\n");
+      which = use_mbr;
+   } // if
+   if ((state == gpt_valid) && (mbrState == gpt)) {
+      printf("Found valid GPT with protective MBR; using GPT.\n");
+      which = use_gpt;
+   } // if
+   if ((state == gpt_valid) && (mbrState == invalid)) {
+      printf("\aFound valid GPT with corrupt MBR; using GPT and will create new\nprotective MBR on save.\n");
+      which = use_gpt;
+      protectiveMBR.MakeProtectiveMBR();
+   } // if
+   if ((state == gpt_valid) && (mbrState == mbr)) {
+      printf("Found valid MBR and GPT. Which do you want to use?\n");
+      answer = GetNumber(1, 3, 2, (char*) " 1 - MBR\n 2 - GPT\n 3 - Create blank GPT\n\nYour answer: ");
+      if (answer == 1) {
+         which = use_mbr;
+      } else if (answer == 2) {
+         which = use_gpt;
+	 protectiveMBR.MakeProtectiveMBR();
+         printf("Using GPT and creating fresh protective MBR.\n");
+      } else which = use_new;
+   } // if
+
+   // Nasty decisions here -- GPT is present, but corrupt (bad CRCs or other
+   // problems)
+   if (state == gpt_corrupt) {
+      if (mbrState == mbr) {
+         printf("Found valid MBR and corrupt GPT. Which do you want to use? (Using the\n"
+                "GPT MAY permit recovery of GPT data.)\n");
+         answer = GetNumber(1, 3, 2, (char*) " 1 - MBR\n 2 - GPT\n 3 - Create blank GPT\n\nYour answer: ");
+         if (answer == 1) {
+            which = use_mbr;
+//            protectiveMBR.MakeProtectiveMBR();
+         } else if (answer == 2) {
+            which = use_gpt;
+         } else which = use_new;
+      } else if (mbrState == invalid) {
+         printf("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, (char*) " 1 - GPT\n 2 - Create blank GPT\n\nYour answer: ");
+         if (answer == 1) {
+            which = use_gpt;
+         } else which = use_new;
+      } else {
+         printf("\a\a****************************************************************************\n"
+                "Caution: Found protective or hybrid MBR and corrupt GPT. Using GPT, but disk\n"
+                "verification and recovery are STRONGLY recommended.\n"
+                "****************************************************************************\n");
+      } // if
+   } // if
+
+   if (which == use_new)
+      printf("Creating new GPT entries.\n");
+
+   return which;
+} // UseWhichPartitions()
+
+void GPTData::ResizePartitionTable(void) {
+   int newSize;
+   char prompt[255];
+   uint32_t curLow, curHigh;
+
+   printf("Current partition table size is %lu.\n",
+          (unsigned long) mainHeader.numParts);
+   GetPartRange(&curLow, &curHigh);
+   curHigh++; // since GetPartRange() returns numbers starting from 0...
+   // There's no point in having fewer than four partitions....
+   if (curHigh < 4)
+      curHigh = 4;
+   sprintf(prompt, "Enter new size (%d up, default %d): ", (int) curHigh,
+           (int) NUM_GPT_ENTRIES);
+   newSize = GetNumber(4, 65535, 128, prompt);
+   if (newSize < 128) {
+      printf("Caution: The partition table size should officially be 16KB or larger,\n"
+             "which works out to 128 entries. In practice, smaller tables seem to\n"
+	     "work with most OSes, but this practice is risky. I'm proceeding with\n"
+             "the resize, but you may want to reconsider this action and undo it.\n\n");
+   } // if
+   SetGPTSize(newSize);
+} // GPTData::ResizePartitionTable()
+
+// Find the low and high used partition numbers (numbered from 0).
+// Return value is the number of partitions found. Note that the
+// *low and *high values are both set to 0 when no partitions
+// are found, as well as when a single partition in the first
+// position exists. Thus, the return value is the only way to
+// tell when no partitions exist.
+int GPTData::GetPartRange(uint32_t *low, uint32_t *high) {
+   uint32_t i;
+   int numFound = 0;
+
+   *low = mainHeader.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 (partitions[i].firstLBA != 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;
+            numFound++;
+         } // if
+      } // for
+   } // if
+
+   // 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))
+      *low = 0;
+   return numFound;
+} // GPTData::GetPartRange()
+
+// Display the basic GPT data
+void GPTData::DisplayGPTData(void) {
+   int i, j;
+   char sizeInSI[255]; // String to hold size of disk in SI units
+   char tempStr[255];
+   uint64_t temp, totalFree;
+
+   BytesToSI(diskSize * blockSize, sizeInSI);
+   printf("Disk %s: %lu sectors, %s\n", device,
+          (unsigned long) diskSize, sizeInSI);
+   printf("Disk identifier (GUID): %s\n", GUIDToStr(mainHeader.diskGUID, tempStr));
+   printf("Partition table holds up to %lu entries\n", (unsigned long) mainHeader.numParts);
+   printf("First usable sector is %lu, last usable sector is %lu\n",
+          (unsigned long) mainHeader.firstUsableLBA,
+          (unsigned long) mainHeader.lastUsableLBA);
+   totalFree = FindFreeBlocks(&i, &temp);
+   printf("Total free space is %llu sectors (%s)\n", totalFree,
+          BytesToSI(totalFree * (uint64_t) blockSize, sizeInSI));
+   printf("\nNumber  Start (block)     End (block)  Size        Code  Name\n");
+   for (i = 0; i < mainHeader.numParts; i++) {
+      if (partitions[i].firstLBA != 0) {
+         BytesToSI(blockSize * (partitions[i].lastLBA - partitions[i].firstLBA + 1),
+                   sizeInSI);
+         printf("%4d  %14lu  %14lu  ", i + 1, (unsigned long) partitions[i].firstLBA,
+                (unsigned long) partitions[i].lastLBA);
+         printf(" %-10s  %04X  ", sizeInSI,
+                typeHelper.GUIDToID(partitions[i].partitionType));
+         j = 0;
+         while ((partitions[i].name[j] != '\0') && (j < 44)) {
+            printf("%c", partitions[i].name[j]);
+	    j += 2;
+         } // while
+         printf("\n");
+      } // if
+   } // for
+} // GPTData::DisplayGPTData()
+
+// Get partition number from user and then call ShowPartDetails(partNum)
+// to show its detailed information
+void GPTData::ShowDetails(void) {
+   int partNum;
+   uint32_t low, high;
+
+   if (GetPartRange(&low, &high) > 0) {
+      partNum = GetPartNum();
+      ShowPartDetails(partNum);
+   } else {
+      printf("No partitions\n");
+   } // if/else
+} // GPTData::ShowDetails()
+
+// Show detailed information on the specified partition
+void GPTData::ShowPartDetails(uint32_t partNum) {
+   char temp[255];
+   int i;
+   uint64_t size;
+
+   if (partitions[partNum].firstLBA != 0) {
+      printf("Partition GUID code: %s ", GUIDToStr(partitions[partNum].partitionType, temp));
+      printf("(%s)\n", typeHelper.GUIDToName(partitions[partNum].partitionType, temp));
+      printf("Partition unique GUID: %s\n", GUIDToStr(partitions[partNum].uniqueGUID, temp));
+
+      printf("First sector: %llu (at %s)\n", (unsigned long long) 
+             partitions[partNum].firstLBA,
+	     BytesToSI(partitions[partNum].firstLBA * blockSize, temp));
+      printf("Last sector: %llu (at %s)\n", (unsigned long long) 
+             partitions[partNum].lastLBA,
+	     BytesToSI(partitions[partNum].lastLBA * blockSize, temp));
+      size = (partitions[partNum].lastLBA - partitions[partNum].firstLBA + 1);
+      printf("Partition size: %llu sectprs (%s)\n", (unsigned long long)
+             size, BytesToSI(size * ((uint64_t) blockSize), temp));
+      printf("Attribute flags: %016llx\n", (unsigned long long)
+             partitions[partNum].attributes);
+      printf("Partition name: ");
+      i = 0;
+      while ((partitions[partNum].name[i] != '\0') && (i < NAME_SIZE)) {
+         printf("%c", partitions[partNum].name[i]);
+	 i += 2;
+      } // while
+      printf("\n");
+   } else {
+      printf("Partition #%d does not exist.", (int) (partNum + 1));
+   } // if
+} // GPTData::ShowPartDetails()
+
+// Interactively create a partition
+void GPTData::CreatePartition(void) {
+   uint64_t firstBlock, lastBlock, sector;
+   char prompt[255];
+   int partNum, firstFreePart = 0;
+
+   // Find first free partition...
+   while (partitions[firstFreePart].firstLBA != 0) {
+      firstFreePart++;
+   } // while
+
+   if (((firstBlock = FindFirstAvailable()) != 0) &&
+       (firstFreePart < mainHeader.numParts)) {
+      lastBlock = FindLastAvailable(firstBlock);
+
+      // Get partition number....
+      do {
+         sprintf(prompt, "Partition number (%d-%d, default %d): ", firstFreePart + 1,
+                 mainHeader.numParts, firstFreePart + 1);
+         partNum = GetNumber(firstFreePart + 1, mainHeader.numParts,
+                             firstFreePart + 1, prompt) - 1;
+	 if (partitions[partNum].firstLBA != 0)
+	    printf("partition %d is in use.\n", partNum + 1);
+      } while (partitions[partNum].firstLBA != 0);
+
+      // Get first block for new partition...
+      sprintf(prompt, "First sector (%llu-%llu, default = %llu): ", firstBlock,
+              lastBlock, firstBlock);
+      do {
+	 sector = GetNumber(firstBlock, lastBlock, firstBlock, prompt);
+      } while (IsFree(sector) == 0);
+      firstBlock = sector;
+
+      // Get last block for new partitions...
+      lastBlock = FindLastInFree(firstBlock);
+      sprintf(prompt, "Last sector or +size or +sizeM or +sizeK (%llu-%llu, default = %d): ",
+              firstBlock, lastBlock, lastBlock);
+      do {
+         sector = GetLastSector(firstBlock, lastBlock, prompt);
+      } while (IsFree(sector) == 0);
+      lastBlock = sector;
+
+      partitions[partNum].firstLBA = firstBlock;
+      partitions[partNum].lastLBA = lastBlock;
+
+      // rand() is only 32 bits on 32-bit systems, so multiply together to
+      // fill a 64-bit value.
+      partitions[partNum].uniqueGUID.data1 = (uint64_t) rand() * (uint64_t) rand();
+      partitions[partNum].uniqueGUID.data2 = (uint64_t) rand() * (uint64_t) rand();
+      ChangeGPTType(&partitions[partNum]);
+   } else {
+      printf("No free sectors available\n");
+   } // if/else
+} // GPTData::CreatePartition()
+
+// Interactively delete a partition (duh!)
+void GPTData::DeletePartition(void) {
+   int partNum;
+   uint32_t low, high;
+   char prompt[255];
+
+   if (GetPartRange(&low, &high) > 0) {
+      sprintf(prompt, "Partition number (%d-%d): ", low + 1, high + 1);
+      partNum = GetNumber(low + 1, high + 1, low, prompt);
+      BlankPartition(&partitions[partNum - 1]);
+   } else {
+      printf("No partitions\n");
+   } // if/else
+} // GPTData::DeletePartition
+
+// Find the first available block after the starting point; returns 0 if
+// there are no available blocks left
+uint64_t GPTData::FindFirstAvailable(uint64_t start) {
+   uint64_t first;
+   uint32_t i;
+   int firstMoved = 0;
+
+   // Begin from the specified starting point or from the first usable
+   // LBA, whichever is greater...
+   if (start < mainHeader.firstUsableLBA)
+      first = mainHeader.firstUsableLBA;
+   else
+      first = start;
+
+   // ...now search through all partitions; if first is within an
+   // existing partition, move it to the next sector after that
+   // partition and repeat. If first was moved, set firstMoved
+   // flag; repeat until firstMoved is not set, so as to catch
+   // cases where partitions are out of sequential order....
+   do {
+      firstMoved = 0;
+      for (i = 0; i < mainHeader.numParts; i++) {
+         if ((first >= partitions[i].firstLBA) &&
+             (first <= partitions[i].lastLBA)) { // in existing part.
+            first = partitions[i].lastLBA + 1;
+            firstMoved = 1;
+          } // if
+      } // for
+   } while (firstMoved == 1);
+   if (first > mainHeader.lastUsableLBA)
+      first = 0;
+   return (first);
+} // GPTData::FindFirstAvailable()
+
+// Find the last available block on the disk at or after the start
+// block. Returns 0 if there are no available partitions after
+// (or including) start.
+uint64_t GPTData::FindLastAvailable(uint64_t start) {
+   uint64_t last;
+   uint32_t i;
+   int lastMoved = 0;
+
+   // Start by assuming the last usable LBA is available....
+   last = mainHeader.lastUsableLBA;
+
+   // ...now, similar to algorithm in FindFirstAvailable(), search
+   // through all partitions, moving last when it's in an existing
+   // partition. Set the lastMoved flag so we repeat to catch cases
+   // where partitions are out of logical order.
+   do {
+      lastMoved = 0;
+      for (i = 0; i < mainHeader.numParts; i++) {
+         if ((last >= partitions[i].firstLBA) &&
+             (last <= partitions[i].lastLBA)) { // in existing part.
+            last = partitions[i].firstLBA - 1;
+            lastMoved = 1;
+         } // if
+      } // for
+   } while (lastMoved == 1);
+   if (last < mainHeader.firstUsableLBA)
+      last = 0;
+   return (last);
+} // GPTData::FindLastAvailable()
+
+// Find the last available block in the free space pointed to by start.
+uint64_t GPTData::FindLastInFree(uint64_t start) {
+   uint64_t nearestStart;
+   uint32_t i;
+
+   nearestStart = mainHeader.lastUsableLBA;
+   for (i = 0; i < mainHeader.numParts; i++) {
+      if ((nearestStart > partitions[i].firstLBA) &&
+          (partitions[i].firstLBA > start)) {
+         nearestStart = partitions[i].firstLBA - 1;
+      } // if
+   } // for
+   return (nearestStart);
+} // GPTData::FindLastInFree()
+
+// Returns 1 if sector is unallocated, 0 if it's allocated to a partition
+int GPTData::IsFree(uint64_t sector) {
+   int isFree = 1;
+   uint32_t i;
+
+   for (i = 0; i < mainHeader.numParts; i++) {
+      if ((sector >= partitions[i].firstLBA) &&
+          (sector <= partitions[i].lastLBA)) {
+         isFree = 0;
+      } // if
+   } // for
+   if ((sector < mainHeader.firstUsableLBA) || 
+       (sector > mainHeader.lastUsableLBA)) {
+      isFree = 0;
+   } // if
+   return (isFree);
+} // GPTData::IsFree()
+
+int GPTData::XFormPartitions(MBRData* origParts) {
+   int i, j;
+   int numToConvert;
+   uint8_t origType;
+
+   // Clear out old data & prepare basics....
+   ClearGPTData();
+
+   // Convert the smaller of the # of GPT or MBR partitions
+   if (mainHeader.numParts > (NUM_LOGICALS + 4))
+      numToConvert = NUM_LOGICALS + 4;
+   else
+      numToConvert = mainHeader.numParts;
+
+//   printf("In XFormPartitions(), numToConvert = %d\n", numToConvert);
+
+   for (i = 0; i < numToConvert; i++) {
+      origType = origParts->GetType(i);
+//      printf("Converting partition of type 0x%02X\n", (int) origType);
+
+      // don't convert extended partitions or null (non-existent) partitions
+      if ((origType != 0x05) && (origType != 0x0f) && (origType != 0x00)) {
+         partitions[i].firstLBA = (uint64_t) origParts->GetFirstSector(i);
+         partitions[i].lastLBA = partitions[i].firstLBA + (uint64_t)
+                                 origParts->GetLength(i) - 1;
+         partitions[i].partitionType = typeHelper.IDToGUID(((uint16_t) origType) * 0x0100);
+
+         // Create random unique GUIDs for the partitions
+         // rand() is only 32 bits, so multiply together to fill a 64-bit value
+	 partitions[i].uniqueGUID.data1 = (uint64_t) rand() * (uint64_t) rand();
+	 partitions[i].uniqueGUID.data2 = (uint64_t) rand() * (uint64_t) rand();
+	 partitions[i].attributes = 0;
+	 for (j = 0; j < NAME_SIZE; j++)
+            partitions[i].name[j] = '\0';
+      } // if
+   } // for
+
+   // Convert MBR into protective MBR
+   protectiveMBR.MakeProtectiveMBR();
+
+   // Record that all original CRCs were OK so as not to raise flags
+   // when doing a disk verification
+   mainCrcOk = secondCrcOk = mainPartsCrcOk = secondPartsCrcOk = 1;
+
+   return (1);
+} // XFormPartitions()
+
+// Sort the GPT entries, eliminating gaps and making for a logical
+// ordering. Relies on QuickSortGPT() for the bulk of the work
+void GPTData::SortGPT(void) {
+   int i, lastPart = 0;
+   struct GPTPartition temp;
+
+   // First, find the last partition with data, so as not to
+   // spend needless time sorting empty entries....
+   for (i = 0; i < GPT_SIZE; i++) {
+      if (partitions[i].firstLBA > 0)
+         lastPart = i;
+   } // for
+
+   // Now swap empties with the last partitions, to simplify the logic
+   // in the Quicksort function....
+   i = 0;
+   while (i < lastPart) {
+      if (partitions[i].firstLBA == 0) {
+         temp = partitions[i];
+	 partitions[i] = partitions[lastPart];
+	 partitions[lastPart] = temp;
+	 lastPart--;
+      } // if
+      i++;
+   } // while
+
+   // Now call the recursive quick sort routine to do the real work....
+   QuickSortGPT(partitions, 0, lastPart);
+} // GPTData::SortGPT()
+
+// Recursive quick sort algorithm for GPT partitions. Note that if there
+// are any empties in the specified range, they'll be sorted to the
+// start, resulting in a sorted set of partitions that begins with
+// partition 2, 3, or higher.
+void QuickSortGPT(struct GPTPartition* partitions, int start, int finish) {
+   uint64_t starterValue; // starting location of median partition
+   int left, right;
+   struct GPTPartition temp;
+
+   left = start;
+   right = finish;
+   starterValue = partitions[(start + finish) / 2].firstLBA;
+   do {
+      while (partitions[left].firstLBA < starterValue)
+         left++;
+      while (partitions[right].firstLBA > starterValue)
+         right--;
+      if (left <= right) {
+         temp = partitions[left];
+	 partitions[left] = partitions[right];
+	 partitions[right] = temp;
+	 left++;
+	 right--;
+      } // if
+   } while (left <= right);
+   if (start < right) QuickSortGPT(partitions, start, right);
+   if (finish > left) QuickSortGPT(partitions, left, finish);
+} // QuickSortGPT()
+
+// Blank (delete) a single partition
+void BlankPartition(struct GPTPartition* partition) {
+   int j;
+
+   partition->uniqueGUID.data1 = 0;
+   partition->uniqueGUID.data2 = 0;
+   partition->partitionType.data1 = 0;
+   partition->partitionType.data2 = 0;
+   partition->firstLBA = 0;
+   partition->lastLBA = 0;
+   partition->attributes = 0;
+   for (j = 0; j < NAME_SIZE; j++)
+      partition->name[j] = '\0';
+} // BlankPartition
+
+// Blank the partition array
+void GPTData::BlankPartitions(void) {
+   uint32_t i;
+
+   for (i = 0; i < mainHeader.numParts; i++) {
+      BlankPartition(&partitions[i]);
+   } // for
+} // GPTData::BlankPartitions()
+
+// Set up data structures for entirely new set of partitions on the
+// specified device. Returns 1 if OK, 0 if there were problems.
+int GPTData::ClearGPTData(void) {
+   int goOn, i;
+
+   // Set up the partition table....
+   free(partitions);
+   partitions = NULL;
+   SetGPTSize(NUM_GPT_ENTRIES);
+
+   // Now initialize a bunch of stuff that's static....
+   mainHeader.signature = GPT_SIGNATURE;
+   mainHeader.revision = 0x00010000;
+   mainHeader.headerSize = (uint32_t) HEADER_SIZE;
+   mainHeader.reserved = 0;
+   mainHeader.currentLBA = UINT64_C(1);
+   mainHeader.partitionEntriesLBA = (uint64_t) 2;
+   mainHeader.sizeOfPartitionEntries = GPT_SIZE;
+   for (i = 0; i < GPT_RESERVED; i++) {
+      mainHeader.reserved2[i] = '\0';
+   } // for
+
+   // Now some semi-static items (computed based on end of disk)
+   mainHeader.backupLBA = diskSize - UINT64_C(1);
+   mainHeader.lastUsableLBA = diskSize - mainHeader.firstUsableLBA;
+
+   // Set a unique GUID for the disk, based on random numbers
+   // rand() is only 32 bits, so multiply together to fill a 64-bit value
+   mainHeader.diskGUID.data1 = (uint64_t) rand() * (uint64_t) rand();
+   mainHeader.diskGUID.data2 = (uint64_t) rand() * (uint64_t) rand();
+
+   // Copy main header to backup header
+   RebuildSecondHeader();
+
+   // Blank out the partitions array....
+   BlankPartitions();
+   return (goOn);
+} // GPTData::ClearGPTData()
+
+// Returns 1 if the two partitions overlap, 0 if they don't
+int TheyOverlap(struct GPTPartition* first, struct GPTPartition* second) {
+   int theyDo = 0;
+
+   // Don't bother checking unless these are defined (both start and end points
+   // are 0 for undefined partitions, so just check the start points)
+   if ((first->firstLBA != 0) && (second->firstLBA != 0)) {
+      if ((first->firstLBA < second->lastLBA) && (first->lastLBA >= second->firstLBA))
+         theyDo = 1;
+      if ((second->firstLBA < first->lastLBA) && (second->lastLBA >= first->firstLBA))
+         theyDo = 1;
+   } // if
+   return (theyDo);
+} // Overlap()
+
+// Change the type code on the specified partition.
+// Note: The GPT CRCs must be recomputed after calling this function!
+void ChangeGPTType(struct GPTPartition* part) {
+   char typeName[255], line[255];
+   uint16_t typeNum = 0xFFFF;
+   PartTypes typeHelper;
+   GUIDData newType;
+
+   printf("Current type is '%s'\n", typeHelper.GUIDToName(part->partitionType, typeName));
+   while ((!typeHelper.Valid(typeNum)) && (typeNum != 0)) {
+      printf("Hex code (L to show codes, 0 to enter raw code): ");
+      fgets(line, 255, stdin);
+      sscanf(line, "%x", &typeNum);
+      if (line[0] == 'L')
+         typeHelper.ShowTypes();
+   } // while
+   if (typeNum != 0) // user entered a code, so convert it
+      newType = typeHelper.IDToGUID(typeNum);
+   else // user wants to enter the GUID directly, so do that
+      newType = GetGUID();
+   part->partitionType = newType;
+   printf("Changed system type of partition to '%s'\n",
+          typeHelper.GUIDToName(part->partitionType, typeName));
+} // ChangeGPTType()
+
+// Prompt user for a partition number, then change its type code
+// using ChangeGPTType(struct GPTPartition*) function.
+void GPTData::ChangePartType(void) {
+   int partNum;
+   uint32_t low, high;
+
+   if (GetPartRange(&low, &high) > 0) {
+      partNum = GetPartNum();
+      ChangeGPTType(&partitions[partNum]);
+   } else {
+      printf("No partitions\n");
+   } // if/else
+} // GPTData::ChangePartType()
+
+// Prompts user for partition number and returns the result.
+uint32_t GPTData::GetPartNum(void) {
+   uint32_t partNum;
+   uint32_t low, high;
+   char prompt[255];
+
+   if (GetPartRange(&low, &high) > 0) {
+      sprintf(prompt, "Partition number (%d-%d): ", low + 1, high + 1);
+      partNum = GetNumber(low + 1, high + 1, low, prompt);
+   } else partNum = 1;
+   return (partNum - 1);
+} // GPTData::GetPartNum()
+
+// Prompt user for attributes to change on the specified partition
+// and change them.
+void GPTData::SetAttributes(uint32_t partNum) {
+   Attributes theAttr;
+
+   theAttr.SetAttributes(partitions[partNum].attributes);
+   theAttr.DisplayAttributes();
+   theAttr.ChangeAttributes();
+   partitions[partNum].attributes = theAttr.GetAttributes();
+} // GPTData::SetAttributes()
+
+// Set the name for a partition to theName, or prompt for a name if
+// theName is a NULL pointer. Note that theName is a standard C-style
+// string, although the GUID partition definition requires a UTF-16LE
+// string. This function creates a simple-minded copy for this.
+void GPTData::SetName(uint32_t partNum, char* theName) {
+   char newName[NAME_SIZE]; // New name
+   int i;
+
+   // Blank out new name string, just to be on the safe side....
+   for (i = 0; i < NAME_SIZE; i++)
+      newName[i] = '\0';
+
+   if (theName == NULL) { // No name specified, so get one from the user
+      printf("Enter name: ");
+      fgets(newName, NAME_SIZE / 2, stdin);
+
+      // Input is likely to include a newline, so remove it....
+      i = strlen(newName);
+      if (newName[i - 1] == '\n')
+         newName[i - 1] = '\0';
+   } else {
+      strcpy(newName, theName);
+   } // if
+
+   // Copy the C-style ASCII string from newName into a form that the GPT
+   // table will accept....
+   for (i = 0; i < NAME_SIZE; i++) {
+      if ((i % 2) == 0) {
+         partitions[partNum].name[i] = newName[(i / 2)];
+      } else {
+         partitions[partNum].name[i] = '\0';
+      } // if/else
+   } // for
+} // GPTData::SetName()
+
+// Set the disk GUID to the specified value. Note that the header CRCs must
+// be recomputed after calling this function.
+void GPTData::SetDiskGUID(GUIDData newGUID) {
+   mainHeader.diskGUID = newGUID;
+   secondHeader.diskGUID = newGUID;
+} // SetDiskGUID()
+
+// Set the unique GUID of the specified partition. Returns 1 on
+// successful completion, 0 if there were problems (invalid
+// partition number).
+int GPTData::SetPartitionGUID(uint32_t pn, GUIDData theGUID) {
+   int retval = 0;
+
+   if (pn < mainHeader.numParts) {
+      if (partitions[pn].firstLBA != UINT64_C(0)) {
+	 partitions[pn].uniqueGUID = theGUID;
+         retval = 1;
+      } // if
+   } // if
+   return retval;
+} // GPTData::SetPartitionGUID()
+
+// Check the validity of the GPT header. Returns 1 if the main header
+// is valid, 2 if the backup header is valid, 3 if both are valid, and
+// 0 if neither is valid. Note that this function just checks the GPT
+// signature and revision numbers, not CRCs or other data.
+int GPTData::CheckHeaderValidity(void) {
+   int valid = 3;
+
+   if (mainHeader.signature != GPT_SIGNATURE) {
+      valid -= 1;
+      printf("Main GPT signature invalid; read 0x%016llX, should be\n0x%016llX\n",
+             (unsigned long long) mainHeader.signature, (unsigned long long) GPT_SIGNATURE);
+   } else if ((mainHeader.revision != 0x00010000) && valid) {
+      valid -= 1;
+      printf("Unsupported GPT version in main header; read 0x%08lX, should be\n0x%08lX\n",
+             (unsigned long) mainHeader.revision, UINT32_C(0x00010000));
+   } // if/else/if
+
+   if (secondHeader.signature != GPT_SIGNATURE) {
+      valid -= 2;
+      printf("Secondary GPT signature invalid; read 0x%016llX, should be\n0x%016llX\n",
+             (unsigned long long) secondHeader.signature, (unsigned long long) GPT_SIGNATURE);
+   } else if ((secondHeader.revision != 0x00010000) && valid) {
+      valid -= 2;
+      printf("Unsupported GPT version in backup header; read 0x%08lX, should be\n0x%08lX\n",
+             (unsigned long) mainHeader.revision, UINT32_C(0x00010000));
+   } // if/else/if
+
+   return valid;
+} // GPTData::CheckHeaderValidity()
+
+// Check the header CRC to see if it's OK...
+int GPTData::CheckHeaderCRC(struct GPTHeader* header) {
+   uint32_t oldCRC, newCRC;
+
+   // Back up old header and then blank it, since it must be 0 for
+   // computation to be valid
+   oldCRC = header->headerCRC;
+   header->headerCRC = UINT32_C(0);
+
+   // Initialize CRC functions...
+   chksum_crc32gentab();
+
+   // Compute CRC, restore original, and return result of comparison
+   newCRC = chksum_crc32((unsigned char*) header, HEADER_SIZE);
+   mainHeader.headerCRC = oldCRC;
+   return (oldCRC == newCRC);
+} // GPTData::CheckHeaderCRC()
+
+// Recompute all the CRCs. Must be called before saving if any changes
+// have been made.
+void GPTData::RecomputeCRCs(void) {
+   uint32_t crc;
+
+   // Initialize CRC functions...
+   chksum_crc32gentab();
+
+   // Compute CRC of partition tables & store in main and secondary headers
+   crc = chksum_crc32((unsigned char*) partitions, mainHeader.numParts * GPT_SIZE);
+   mainHeader.partitionEntriesCRC = crc;
+   secondHeader.partitionEntriesCRC = crc;
+
+   // Zero out GPT tables' own CRCs (required for correct computation)
+   mainHeader.headerCRC = 0;
+   secondHeader.headerCRC = 0;
+
+   // Compute & store CRCs of main & secondary headers...
+   crc = chksum_crc32((unsigned char*) &mainHeader, HEADER_SIZE);
+   mainHeader.headerCRC = crc;
+   crc = chksum_crc32((unsigned char*) &secondHeader, HEADER_SIZE);
+   secondHeader.headerCRC = crc;
+} // GPTData::RecomputeCRCs()
+
+// Perform detailed verification, reporting on any problems found, but
+// do *NOT* recover from these problems. Returns the total number of
+// problems identified.
+int GPTData::Verify(void) {
+   int problems = 0, numSegments, i, j;
+   uint64_t totalFree, largestSegment;
+   char tempStr[255], siTotal[255], siLargest[255];
+
+   // First, check for CRC errors in the GPT data....
+   if (!mainCrcOk) {
+      problems++;
+      printf("\nProblem: The CRC for the main GPT header is invalid. The main GPT header may\n"
+             "be corrupt. Consider loading the backup GPT header to rebuild the main GPT\n"
+             "header\n");
+   } // if
+   if (!mainPartsCrcOk) {
+      problems++;
+      printf("\nProblem: The CRC for the main partition table is invalid. This table may be\n"
+             "corrupt. Consider loading the backup partition table.\n");
+   } // if
+   if (!secondCrcOk) {
+      problems++;
+      printf("\nProblem: The CRC for the backup GPT header is invalid. The backup GPT header\n"
+             "may be corrupt. Consider using the main GPT header to rebuild the backup GPT\n"
+             "header.\n");
+   } // if
+   if (!secondPartsCrcOk) {
+      problems++;
+      printf("\nCaution: The CRC for the backup partition table is invalid. This table may\n"
+             "be corrupt. This program will automatically create a new backup partition\n"
+             "table when you save your partitions.\n");
+   } // if
+
+   // Now check that critical main and backup GPT entries match
+   if (mainHeader.currentLBA != secondHeader.backupLBA) {
+      problems++;
+      printf("\nProblem: main GPT header's current LBA pointer (%llu) doesn't\n"
+             "match the backup GPT header's LBA pointer(%llu)\n",
+             (unsigned long long) mainHeader.currentLBA,
+	     (unsigned long long) secondHeader.backupLBA);
+   } // if
+   if (mainHeader.backupLBA != secondHeader.currentLBA) {
+      problems++;
+      printf("\nProblem: main GPT header's backup LBA pointer (%llu) doesn't\n"
+             "match the backup GPT header's current LBA pointer (%llu)\n",
+             (unsigned long long) mainHeader.backupLBA,
+	     (unsigned long long) secondHeader.currentLBA);
+   } // if
+   if (mainHeader.firstUsableLBA != secondHeader.firstUsableLBA) {
+      problems++;
+      printf("\nProblem: main GPT header's first usable LBA pointer (%llu) doesn't\n"
+             "match the backup GPT header's first usable LBA pointer (%llu)\n",
+             (unsigned long long) mainHeader.firstUsableLBA,
+	     (unsigned long long) secondHeader.firstUsableLBA);
+   } // if
+   if (mainHeader.lastUsableLBA != secondHeader.lastUsableLBA) {
+      problems++;
+      printf("\nProblem: main GPT header's last usable LBA pointer (%llu) doesn't\n"
+             "match the backup GPT header's last usable LBA pointer (%llu)\n",
+             (unsigned long long) mainHeader.lastUsableLBA,
+	     (unsigned long long) secondHeader.lastUsableLBA);
+   } // if
+   if ((mainHeader.diskGUID.data1 != secondHeader.diskGUID.data1) ||
+       (mainHeader.diskGUID.data2 != secondHeader.diskGUID.data2)) {
+      problems++;
+      printf("\nProblem: main header's disk GUID (%s) doesn't\n",
+             GUIDToStr(mainHeader.diskGUID, tempStr));
+      printf("match the backup GPT header's disk GUID (%s)\n",
+             GUIDToStr(secondHeader.diskGUID, tempStr));
+   } // if
+   if (mainHeader.numParts != secondHeader.numParts) {
+      problems++;
+      printf("\nProblem: main GPT header's number of partitions (%lu) doesn't\n"
+             "match the backup GPT header's number of partitions (%lu)\n",
+	     (unsigned long) mainHeader.numParts,
+             (unsigned long) secondHeader.numParts);
+   } // if
+   if (mainHeader.sizeOfPartitionEntries != secondHeader.sizeOfPartitionEntries) {
+      problems++;
+      printf("\nProblem: main GPT header's size of partition entries (%lu) doesn't\n"
+             "match the backup GPT header's size of partition entries (%lu)\n",
+	     (unsigned long) mainHeader.sizeOfPartitionEntries,
+	     (unsigned long) secondHeader.sizeOfPartitionEntries);
+   } // if
+
+   // Now check for a few other miscellaneous problems...
+   // Check that the disk size will hold the data...
+   if (mainHeader.backupLBA > diskSize) {
+      problems++;
+      printf("\nProblem: Disk is too small to hold all the data!\n");
+      printf("(Disk size is %llu sectors, needs to be %llu sectors.)\n",
+             (unsigned long long) diskSize,
+             (unsigned long long) mainHeader.backupLBA);
+   } // if
+
+   // Check for overlapping partitions....
+   for (i = 1; i < mainHeader.numParts; i++) {
+      for (j = 0; j < i; j++) {
+         if (TheyOverlap(&partitions[i], &partitions[j])) {
+            problems++;
+            printf("\nProblem: partitions %d and %d overlap:\n", i + 1, j + 1);
+            printf("  Partition %d: %llu to %llu\n", i, 
+                   (unsigned long long) partitions[i].firstLBA,
+                   (unsigned long long) partitions[i].lastLBA);
+            printf("  Partition %d: %llu to %llu\n", j,
+                   (unsigned long long) partitions[j].firstLBA,
+                   (unsigned long long) partitions[j].lastLBA);
+	 } // if
+      } // for j...
+   } // for i...
+
+   // Now compute available space, but only if no problems found, since
+   // problems could affect the results
+   if (problems == 0) {
+      totalFree = FindFreeBlocks(&numSegments, &largestSegment);
+      BytesToSI(totalFree * (uint64_t) blockSize, siTotal);
+      BytesToSI(largestSegment * (uint64_t) blockSize, siLargest);
+      printf("No problems found. %llu free sectors (%s) available in %u\n"
+             "segments, the largest of which is %llu sectors (%s) in size\n",
+             (unsigned long long) totalFree,
+             siTotal, numSegments, (unsigned long long) largestSegment,
+	     siLargest);
+   } else {
+      printf("\nIdentified %d problems!\n", problems);
+   } // if/else
+
+   return (problems);
+} // GPTData::Verify()
+
+// Rebuild the main GPT header, using the secondary header as a model.
+// Typically called when the main header has been found to be corrupt.
+void GPTData::RebuildMainHeader(void) {
+   int i;
+
+   mainHeader.signature = GPT_SIGNATURE;
+   mainHeader.revision = secondHeader.revision;
+   mainHeader.headerSize = HEADER_SIZE;
+   mainHeader.headerCRC = UINT32_C(0);
+   mainHeader.reserved = secondHeader.reserved;
+   mainHeader.currentLBA = secondHeader.backupLBA;
+   mainHeader.backupLBA = secondHeader.currentLBA;
+   mainHeader.firstUsableLBA = secondHeader.firstUsableLBA;
+   mainHeader.lastUsableLBA = secondHeader.lastUsableLBA;
+   mainHeader.diskGUID.data1 = secondHeader.diskGUID.data1;
+   mainHeader.diskGUID.data2 = secondHeader.diskGUID.data2;
+   mainHeader.partitionEntriesLBA = UINT64_C(2);
+   mainHeader.numParts = secondHeader.numParts;
+   mainHeader.sizeOfPartitionEntries = secondHeader.sizeOfPartitionEntries;
+   mainHeader.partitionEntriesCRC = secondHeader.partitionEntriesCRC;
+   for (i = 0 ; i < GPT_RESERVED; i++)
+      mainHeader.reserved2[i] = secondHeader.reserved2[i];
+} // GPTData::RebuildMainHeader()
+
+// Rebuild the secondary GPT header, using the main header as a model.
+void GPTData::RebuildSecondHeader(void) {
+   int i;
+
+   secondHeader.signature = GPT_SIGNATURE;
+   secondHeader.revision = mainHeader.revision;
+   secondHeader.headerSize = HEADER_SIZE;
+   secondHeader.headerCRC = UINT32_C(0);
+   secondHeader.reserved = mainHeader.reserved;
+   secondHeader.currentLBA = mainHeader.backupLBA;
+   secondHeader.backupLBA = mainHeader.currentLBA;
+   secondHeader.firstUsableLBA = mainHeader.firstUsableLBA;
+   secondHeader.lastUsableLBA = mainHeader.lastUsableLBA;
+   secondHeader.diskGUID.data1 = mainHeader.diskGUID.data1;
+   secondHeader.diskGUID.data2 = mainHeader.diskGUID.data2;
+   secondHeader.partitionEntriesLBA = secondHeader.lastUsableLBA + UINT64_C(1);
+   secondHeader.numParts = mainHeader.numParts;
+   secondHeader.sizeOfPartitionEntries = mainHeader.sizeOfPartitionEntries;
+   secondHeader.partitionEntriesCRC = mainHeader.partitionEntriesCRC;
+   for (i = 0 ; i < GPT_RESERVED; i++)
+      secondHeader.reserved2[i] = mainHeader.reserved2[i];
+} // RebuildSecondHeader()
+
+// Load the second (backup) partition table as the primary partition
+// table. Used in repair functions
+void GPTData::LoadSecondTableAsMain(void) {
+   int fd;
+   off_t seekTo;
+   uint32_t sizeOfParts, newCRC;
+
+   if ((fd = open(device, O_RDONLY)) != -1) {
+      seekTo = secondHeader.partitionEntriesLBA * (off_t) blockSize;
+      if (lseek64(fd, seekTo, SEEK_SET) != (off_t) -1) {
+         SetGPTSize(secondHeader.numParts);
+         sizeOfParts = secondHeader.numParts * secondHeader.sizeOfPartitionEntries;
+         read(fd, partitions, sizeOfParts);
+         newCRC = chksum_crc32((unsigned char*) partitions, sizeOfParts);
+         secondPartsCrcOk = (newCRC == secondHeader.partitionEntriesCRC);
+	 mainPartsCrcOk = secondPartsCrcOk;
+         if (!secondPartsCrcOk) {
+            printf("Error! After loading backup partitions, the CRC still doesn't check out!\n");
+         } // if
+      } else {
+         printf("Error! Couldn't seek to backup partition table!\n");
+      } // if/else
+   } else {
+      printf("Error! Couldn't open device %s when recovering backup partition table!\n");
+   } // if/else
+} // GPTData::LoadSecondTableAsMain()
+
+// Finds the total number of free blocks, the number of segments in which
+// they reside, and the size of the largest of those segments
+uint64_t GPTData::FindFreeBlocks(int *numSegments, uint64_t *largestSegment) {
+   uint64_t start = UINT64_C(0); // starting point for each search
+   uint64_t totalFound = UINT64_C(0); // running total
+   uint64_t firstBlock; // first block in a segment
+   uint64_t lastBlock; // last block in a segment
+   uint64_t segmentSize; // size of segment in blocks
+   int num = 0;
+
+   *largestSegment = UINT64_C(0);
+   do {
+      firstBlock = FindFirstAvailable(start);
+      if (firstBlock != UINT64_C(0)) { // something's free...
+         lastBlock = FindLastInFree(firstBlock);
+         segmentSize = lastBlock - firstBlock + UINT64_C(1);
+	 if (segmentSize > *largestSegment) {
+            *largestSegment = segmentSize;
+	 } // if
+         totalFound += segmentSize;
+	 num++;
+	 start = lastBlock + 1;
+      } // if
+   } while (firstBlock != 0);
+   *numSegments = num;
+   return totalFound;
+} // GPTData::FindFreeBlocks()
+
+/*
+// Create a hybrid MBR -- an ugly, funky thing that helps GPT work with
+// OSes that don't understand GPT.
+void GPTData::MakeHybrid(void) {
+   uint32_t partNums[3];
+   char line[255];
+   int numParts, i, j, typeCode, bootable;
+   uint64_t length;
+
+   // First, rebuild the protective MBR...
+   protectiveMBR.MakeProtectiveMBR();
+
+   // Now get the numbers of up to three partitions to add to the
+   // hybrid MBR....
+   printf("Type from one to three partition numbers to be added to the hybrid MBR, in\n"
+          "sequence: ");
+   fgets(line, 255, stdin);
+   numParts = sscanf(line, "%d %d %d", &partNums[0], &partNums[1], &partNums[2]);
+   for (i = 0; i < numParts; i++) {
+      j = partNums[i] - 1;
+      printf("Creating entry for partition #%d\n", j + 1);
+      if ((j >= 0) && (j < mainHeader.numParts)) {
+         if (partitions[j].lastLBA < UINT32_MAX) {
+            printf("Enter an MBR hex code (suggested %02X): ",
+                   typeHelper.GUIDToID(partitions[j].partitionType) / 256);
+            fgets(line, 255, stdin);
+	    sscanf(line, "%x", &typeCode);
+	    printf("Set the bootable flag? ");
+	    bootable = (GetYN() == 'Y');
+            length = partitions[j].lastLBA - partitions[j].firstLBA + UINT64_C(1);
+            protectiveMBR.MakePart(i + 1, (uint32_t) partitions[j].firstLBA,
+                    (uint32_t) length, typeCode, bootable);
+         } else { // partition out of range
+            printf("Partition %d ends beyond the 2TiB limit of MBR partitions; omitting it.\n",
+                   j + 1);
+         } // if/else
+      } else {
+         printf("Partition %d is out of range; omitting it.\n", j + 1);
+      } // if/else
+   } // for
+} // GPTData::MakeHybrid()
+*/
+
+// Writes GPT (and protective MBR) to disk. Returns 1 on successful
+// write, 0 if there was a problem.
+int GPTData::SaveGPTData(void) {
+   int allOK = 1, i, j;
+   char answer, line[256];
+   int fd;
+   uint64_t secondTable;
+   off_t offset;
+
+   if (strlen(device) == 0) {
+      printf("Device not defined.\n");
+   } // if
+
+   // First do some final sanity checks....
+   // Is there enough space to hold the GPT headers and partition tables,
+   // given the partition sizes?
+   if (CheckGPTSize() == 0) {
+      allOK = 0;
+   } // if
+
+   // Check that disk is really big enough to handle this...
+   if (mainHeader.backupLBA > diskSize) {
+      fprintf(stderr, "Error! Disk is too small -- either the original MBR is corrupt or you're\n");
+      fprintf(stderr, "working from an MBR copied to a file! Aborting!\n");
+      printf("(Disk size is %ld sectors, needs to be %ld sectors.)\n", diskSize,
+             mainHeader.backupLBA);
+      allOK = 0;
+   } // if
+
+   // Check for overlapping partitions....
+   for (i = 1; i < mainHeader.numParts; i++) {
+      for (j = 0; j < i; j++) {
+         if (TheyOverlap(&partitions[i], &partitions[j])) {
+            fprintf(stderr, "\Error: partitions %d and %d overlap:\n", i + 1, j + 1);
+            fprintf(stderr, "  Partition %d: %llu to %llu\n", i, 
+                   (unsigned long long) partitions[i].firstLBA,
+                   (unsigned long long) partitions[i].lastLBA);
+            fprintf(stderr, "  Partition %d: %llu to %llu\n", j,
+                   (unsigned long long) partitions[j].firstLBA,
+                   (unsigned long long) partitions[j].lastLBA);
+            fprintf(stderr, "Aborting write operation!\n");
+	    allOK = 0;
+	 } // if
+      } // for j...
+   } // for i...
+
+   RecomputeCRCs();
+
+   if (allOK) {
+      printf("\nFinal checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING\n");
+      printf("MBR PARTITIONS!! THIS PROGRAM IS BETA QUALITY AT BEST. IF YOU LOSE ALL YOUR\n");
+      printf("DATA, YOU HAVE ONLY YOURSELF TO BLAME IF YOU ANSWER 'Y' BELOW!\n\n");
+      printf("Do you want to proceed, possibly destroying your data? (Y/N) ");
+      fgets(line, 255, stdin);
+      sscanf(line, "%c", &answer);
+      if ((answer == 'Y') || (answer == 'y')) {
+         printf("OK; writing new GPT partition table.\n");
+      } else {
+         allOK = 0;
+      } // if/else
+   } // if
+
+   // Do it!
+   if (allOK) {
+      fd = open(device, O_WRONLY); // try to open the device; may fail....
+#ifdef __APPLE__
+      // MacOS X requires a shared lock under some circumstances....
+      if (fd < 0) {
+         fd = open(device, O_WRONLY|O_SHLOCK);
+      } // if
+#endif
+      if (fd != -1) {
+         // First, write the protective MBR...
+	 protectiveMBR.WriteMBRData(fd);
+
+         // Now write the main GPT header...
+         if (allOK)
+            if (write(fd, &mainHeader, 512) == -1)
+              allOK = 0;
+
+         // Now write the main partition tables...
+	 if (allOK) {
+	    if (write(fd, partitions, GPT_SIZE * mainHeader.numParts) == -1)
+               allOK = 0;
+         } // if
+
+         // Now seek to near the end to write the secondary GPT....
+	 if (allOK) {
+            secondTable = secondHeader.partitionEntriesLBA;
+            offset = (off_t) secondTable * (off_t) (blockSize);
+            if (lseek64(fd, offset, SEEK_SET) == (off_t) - 1) {
+               allOK = 0;
+               printf("Unable to seek to end of disk!\n");
+            } // if
+         } // if
+
+         // Now write the secondary partition tables....
+	 if (allOK)
+            if (write(fd, partitions, GPT_SIZE * mainHeader.numParts) == -1)
+               allOK = 0;
+
+         // Now write the secondary GPT header...
+	 if (allOK)
+            if (write(fd, &secondHeader, 512) == -1)
+	       allOK = 0;
+
+         // re-read the partition table
+         if (allOK) {
+            sync();
+#ifdef __APPLE__
+	    printf("Warning: The kernel may continue to use old or deleted partitions.\n"
+	           "You should reboot or remove the drive.\n");
+	    /* don't know if this helps
+	     * it definitely will get things on disk though:
+	     * http://topiks.org/mac-os-x/0321278542/ch12lev1sec8.html */
+	    i = ioctl(fd, DKIOCSYNCHRONIZECACHE);
+#else
+	    sleep(2);
+            i = ioctl(fd, BLKRRPART);
+            if (i)
+               printf("Warning: The kernel is still using the old partition table.\n"
+                      "The new table will be used at the next reboot.\n");
+#endif
+         } // if
+
+         if (allOK) { // writes completed OK
+	    printf("The operation has completed successfully.\n");
+         } else {
+	    printf("Warning! An error was reported when writing the partition table! This error\n");
+	    printf("MIGHT be harmless, but you may have trashed the disk! Use parted and, if\n");
+	    printf("necessary, restore your original partition table.\n");
+         } // if/else
+	 close(fd);
+      } else {
+         fprintf(stderr, "Unable to open device %s for writing! Errno is %d! Aborting!\n", device, errno);
+	 allOK = 0;
+      } // if/else
+   } else {
+      printf("Aborting write of new partition table.\n");
+   } // if
+
+   return (allOK);
+} // GPTData::SaveGPTData()
+
+// Save GPT data to a backup file. This function does much less error
+// checking than SaveGPTData(). It can therefore preserve many types of
+// corruption for later analysis; however, it preserves only the MBR,
+// the main GPT header, the backup GPT header, and the main partition
+// table; it discards the backup partition table, since it should be
+// identical to the main partition table on healthy disks.
+int GPTData::SaveGPTBackup(char* filename) {
+   int fd, allOK = 1;;
+
+   if ((fd = open(filename, O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH)) != -1) {
+      // First, write the protective MBR...
+      protectiveMBR.WriteMBRData(fd);
+
+      // Now write the main GPT header...
+      if (allOK)
+         if (write(fd, &mainHeader, 512) == -1)
+            allOK = 0;
+
+      // Now write the secondary GPT header...
+      if (allOK)
+         if (write(fd, &secondHeader, 512) == -1)
+	    allOK = 0;
+
+      // Now write the main partition tables...
+      if (allOK) {
+         if (write(fd, partitions, GPT_SIZE * mainHeader.numParts) == -1)
+            allOK = 0;
+      } // if
+
+      if (allOK) { // writes completed OK
+         printf("The operation has completed successfully.\n");
+      } else {
+         printf("Warning! An error was reported when writing the backup file.\n");
+         printf("It may not be useable!\n");
+      } // if/else
+      close(fd);
+   } else {
+      fprintf(stderr, "Unable to open file %s for writing! Aborting!\n", filename);
+      allOK = 0;
+   } // if/else
+   return allOK;
+} // GPTData::SaveGPTBackup()
+
+// Load GPT data from a backup file created by SaveGPTBackup(). This function
+// does minimal error checking. It returns 1 if it completed successfully,
+// 0 if there was a problem. In the latter case, it creates a new empty
+// set of partitions.
+int GPTData::LoadGPTBackup(char* filename) {
+   int fd, allOK = 1, val;
+   uint32_t numParts, sizeOfEntries, sizeOfParts, newCRC;
+
+   if ((fd = open(filename, O_RDONLY)) != -1) {
+      // Let the MBRData class load the saved MBR...
+      protectiveMBR.ReadMBRData(fd);
+
+      // Load the main GPT header, check its vaility, and set the GPT
+      // size based on the data
+      read(fd, &mainHeader, 512);
+      mainCrcOk = CheckHeaderCRC(&mainHeader);
+
+      // Load the backup GPT header in much the same way as the main
+      // GPT header....
+      read(fd, &secondHeader, 512);
+      secondCrcOk = CheckHeaderCRC(&secondHeader);
+
+      // Return valid headers code: 0 = both headers bad; 1 = main header
+      // good, backup bad; 2 = backup header good, main header bad;
+      // 3 = both headers good. Note these codes refer to valid GPT
+      // signatures and version numbers; more subtle problems will elude
+      // this check!
+      if ((val = CheckHeaderValidity()) > 0) {
+         if (val == 2) { // only backup header seems to be good
+            numParts = secondHeader.numParts;
+	    sizeOfEntries = secondHeader.sizeOfPartitionEntries;
+         } else { // main header is OK
+            numParts = mainHeader.numParts;
+            sizeOfEntries = mainHeader.sizeOfPartitionEntries;
+         } // if/else
+
+         SetGPTSize(numParts);
+
+         // If current disk size doesn't match that of backup....
+         if (secondHeader.currentLBA != diskSize - UINT64_C(1)) {
+            printf("Warning! Current disk size doesn't match that of the backup!\n"
+	           "Adjusting sizes to match, but subsequent problems are possible!\n");
+            secondHeader.currentLBA = mainHeader.backupLBA = diskSize - UINT64_C(1);
+            mainHeader.lastUsableLBA = diskSize - mainHeader.firstUsableLBA;
+            secondHeader.lastUsableLBA = mainHeader.lastUsableLBA;
+            secondHeader.partitionEntriesLBA = secondHeader.lastUsableLBA + UINT64_C(1);
+         } // if
+
+         // Load main partition table, and record whether its CRC
+         // matches the stored value
+         sizeOfParts = numParts * sizeOfEntries;
+         read(fd, partitions, sizeOfParts);
+
+         newCRC = chksum_crc32((unsigned char*) partitions, sizeOfParts);
+         mainPartsCrcOk = (newCRC == mainHeader.partitionEntriesCRC);
+         secondPartsCrcOk = (newCRC == secondHeader.partitionEntriesCRC);
+      } else {
+         allOK = 0;
+      } // if/else
+   } else {
+      allOK = 0;
+      fprintf(stderr, "Unable to open file %s for reading! Aborting!\n", filename);
+   } // if/else
+
+   // Something went badly wrong, so blank out partitions
+   if (allOK == 0) {
+      ClearGPTData();
+      protectiveMBR.MakeProtectiveMBR();
+   } // if
+   return allOK;
+} // GPTData::LoadGPTBackup()
+
+// Check to be sure that data type sizes are correct. The basic types (uint*_t) should
+// never fail these tests, but the struct types may fail depending on compile options.
+// Specifically, the -fpack-struct option to gcc may be required to ensure proper structure
+// sizes.
+int SizesOK(void) {
+   int allOK = 1;
+   union {
+      uint32_t num;
+      unsigned char uc[sizeof(uint32_t)];
+   } endian;
+
+   if (sizeof(uint8_t) != 1) {
+      fprintf(stderr, "uint8_t is %d bytes, should be 1 byte; aborting!\n", sizeof(uint8_t));
+      allOK = 0;
+   } // if
+   if (sizeof(uint16_t) != 2) {
+      fprintf(stderr, "uint16_t is %d bytes, should be 2 bytes; aborting!\n", sizeof(uint16_t));
+      allOK = 0;
+   } // if
+   if (sizeof(uint32_t) != 4) {
+      fprintf(stderr, "uint32_t is %d bytes, should be 4 bytes; aborting!\n", sizeof(uint32_t));
+      allOK = 0;
+   } // if
+   if (sizeof(uint64_t) != 8) {
+      fprintf(stderr, "uint64_t is %d bytes, should be 8 bytes; aborting!\n", sizeof(uint64_t));
+      allOK = 0;
+   } // if
+   if (sizeof(struct MBRRecord) != 16) {
+      fprintf(stderr, "MBRRecord is %d bytes, should be 16 bytes; aborting!\n", sizeof(uint32_t));
+      allOK = 0;
+   } // if
+   if (sizeof(struct EBRRecord) != 512) {
+      fprintf(stderr, "EBRRecord is %d bytes, should be 512 bytes; aborting!\n", sizeof(uint32_t));
+      allOK = 0;
+   } // if
+   if (sizeof(struct GPTHeader) != 512) {
+      fprintf(stderr, "GPTHeader is %d bytes, should be 512 bytes; aborting!\n", sizeof(uint32_t));
+      allOK = 0;
+   } // if
+   // Determine endianness; set allOK = 0 if running on big-endian hardware
+   endian.num = 1;
+   if (endian.uc[0] != (unsigned char) 1) {
+      fprintf(stderr, "Running on big-endian hardware, but this program only works on little-endian\n"
+                      "systems; aborting!\n");
+      allOK = 0;
+   } // if
+   return (allOK);
+} // SizesOK()
+
