Misc. updates and bug fixes
diff --git a/gpt.cc b/gpt.cc
index 867c3ff..e5c9852 100644
--- a/gpt.cc
+++ b/gpt.cc
@@ -18,6 +18,7 @@
 #include <time.h>
 #include <sys/stat.h>
 #include <errno.h>
+#include <iostream>
 #include "crc32.h"
 #include "gpt.h"
 #include "bsd.h"
@@ -40,7 +41,7 @@
    diskSize = 0;
    partitions = NULL;
    state = gpt_valid;
-   strcpy(device, "");
+   device = "";
    justLooking = 0;
    mainCrcOk = 0;
    secondCrcOk = 0;
@@ -57,12 +58,12 @@
 } // GPTData default constructor
 
 // The following constructor loads GPT data from a device file
-GPTData::GPTData(char* filename) {
+GPTData::GPTData(string filename) {
    blockSize = SECTOR_SIZE; // set a default
    diskSize = 0;
    partitions = NULL;
    state = gpt_invalid;
-   strcpy(device, "");
+   device = "";
    justLooking = 0;
    mainCrcOk = 0;
    secondCrcOk = 0;
@@ -77,7 +78,7 @@
    mainHeader.numParts = 0;
    if (!LoadPartitions(filename))
       exit(2);
-} // GPTData(char* filename) constructor
+} // GPTData(string filename) constructor
 
 // Destructor
 GPTData::~GPTData(void) {
@@ -102,116 +103,109 @@
    // 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 ('b' on the recovery & transformation menu). This report may be a false\n"
-             "alarm if you've already corrected other problems.\n");
+      cout << "\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 ('b' on the recovery & transformation menu). This report may be a false\n"
+           << "alarm if you've already corrected other problems.\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 ('c' on the recovery &\n"
-             "transformation menu). This report may be a false alarm if you've already\n"
-             "corrected other problems.\n");
+      cout << "\nProblem: The CRC for the main partition table is invalid. This table may be\n"
+           << "corrupt. Consider loading the backup partition table ('c' on the recovery &\n"
+           << "transformation menu). This report may be a false alarm if you've already\n"
+           << "corrected other problems.\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 ('d' on the recovery & transformation menu). This report may be a false\n"
-            "alarm if you've already corrected other problems.\n");
+      cout << "\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 ('d' on the recovery & transformation menu). This report may be a false\n"
+           << "alarm if you've already corrected other problems.\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");
+      cout << "\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 the main and backup headers both point to themselves....
    if (mainHeader.currentLBA != 1) {
       problems++;
-      printf("\nProblem: The main header's self-pointer doesn't point to itself. This problem\n"
-             "is being automatically corrected, but it may be a symptom of more serious\n"
-             "problems. Think carefully before saving changes with 'w' or using this disk.\n");
+      cout << "\nProblem: The main header's self-pointer doesn't point to itself. This problem\n"
+           << "is being automatically corrected, but it may be a symptom of more serious\n"
+           << "problems. Think carefully before saving changes with 'w' or using this disk.\n";
       mainHeader.currentLBA = 1;
    } // if
    if (secondHeader.currentLBA != (diskSize - UINT64_C(1))) {
       problems++;
-      printf("\nProblem: The secondary header's self-pointer indicates that it doesn't reside\n"
-             "at the end of the disk. If you've added a disk to a RAID array, use the 'e'\n"
-             "option on the experts' menu to adjust the secondary header's and partition\n"
-             "table's locations.\n");
+      cout << "\nProblem: The secondary header's self-pointer indicates that it doesn't reside\n"
+           << "at the end of the disk. If you've added a disk to a RAID array, use the 'e'\n"
+           << "option on the experts' menu to adjust the secondary header's and partition\n"
+           << "table's locations.\n";
    } // if
 
    // Now check that critical main and backup GPT entries match each other
    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);
+      cout << "\nProblem: main GPT header's current LBA pointer (" << mainHeader.currentLBA
+           << ") doesn't\nmatch the backup GPT header's alternate LBA pointer("
+           << secondHeader.backupLBA << ").\n";
    } // 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"
-             "The 'e' option on the experts' menu may fix this problem.\n",
-             (unsigned long long) mainHeader.backupLBA,
-             (unsigned long long) secondHeader.currentLBA);
+      cout << "\nProblem: main GPT header's backup LBA pointer (" << mainHeader.backupLBA
+           << ") doesn't\nmatch the backup GPT header's current LBA pointer ("
+           << secondHeader.currentLBA << ").\n"
+           << "The 'e' option on the experts' menu may fix this problem.\n";
    } // 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);
+      cout << "\nProblem: main GPT header's first usable LBA pointer (" << mainHeader.firstUsableLBA
+           << ") doesn't\nmatch the backup GPT header's first usable LBA pointer ("
+           << secondHeader.firstUsableLBA << ")\n";
    } // 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);
-      printf("The 'e' option on the experts' menu can probably fix this problem.\n");
+      cout << "\nProblem: main GPT header's last usable LBA pointer (" << mainHeader.lastUsableLBA
+           << ") doesn't\nmatch the backup GPT header's last usable LBA pointer ("
+           << secondHeader.lastUsableLBA << ")\n"
+           << "The 'e' option on the experts' menu can probably fix this problem.\n";
    } // 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));
-      printf("You should use the 'b' or 'd' option on the recovery & transformation menu to\n"
-             "select one or the other header.\n");
+      cout << "\nProblem: main header's disk GUID (" << GUIDToStr(mainHeader.diskGUID)
+           << ") doesn't\nmatch the backup GPT header's disk GUID ("
+           << GUIDToStr(secondHeader.diskGUID) << ")\n"
+           << "You should use the 'b' or 'd' option on the recovery & transformation menu to\n"
+           << "select one or the other header.\n";
    } // 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);
-      printf("Resizing the partition table ('s' on the experts' menu) may help.\n");
+      cout << "\nProblem: main GPT header's number of partitions (" << mainHeader.numParts
+           << ") doesn't\nmatch the backup GPT header's number of partitions ("
+           << secondHeader.numParts << ")\n"
+           << "Resizing the partition table ('s' on the experts' menu) may help.\n";
    } // 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);
-      printf("You should use the 'b' or 'd' option on the recovery & transformation menu to\n"
-            "select one or the other header.\n");
+      cout << "\nProblem: main GPT header's size of partition entries ("
+           << mainHeader.sizeOfPartitionEntries << ") doesn't\n"
+           << "match the backup GPT header's size of partition entries ("
+           << secondHeader.sizeOfPartitionEntries << ")\n"
+           << "You should use the 'b' or 'd' option on the recovery & transformation menu to\n"
+           << "select one or the other header.\n";
    } // 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);
-      printf("The 'e' option on the experts' menu may fix this problem.\n");
+      cout << "\nProblem: Disk is too small to hold all the data!\n"
+           << "(Disk size is " << diskSize << " sectors, needs to be "
+           << mainHeader.backupLBA << " sectors.)\n"
+           << "The 'e' option on the experts' menu may fix this problem.\n";
    } // if
 
    // Check for overlapping partitions....
@@ -227,9 +221,9 @@
    // Format and similar disks)....
    for (i = 0; i < mainHeader.numParts; i++) {
       if ((partitions[i].GetFirstLBA() % sectorAlignment) != 0) {
-         printf("\nCaution: Partition %d doesn't begin on a %d-sector boundary. This may\n"
-                "result in degraded performance on some modern (2010 and later) hard disks.\n",
-                i + 1, sectorAlignment);
+         cout << "\nCaution: Partition " << i + 1 << " doesn't begin on a "
+              << sectorAlignment << "-sector boundary. This may\nresult "
+              << "in degraded performance on some modern (2009 and later) hard disks.\n";
       } // if
    } // for
 
@@ -237,14 +231,15 @@
    // 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 ", (unsigned long long) totalFree);
-      printf("(%s) available in %u\n", siTotal, numSegments);
-      printf("segments, the largest of which is %llu sectors ", (unsigned long long) largestSegment);
-      printf("(%s) in size\n", siLargest);
+      strcpy(siTotal, BytesToSI(totalFree * (uint64_t) blockSize).c_str());
+      strcpy(siLargest, BytesToSI(largestSegment * (uint64_t) blockSize).c_str());
+      cout << "No problems found. " << totalFree << " free sectors ("
+           << BytesToSI(totalFree * (uint64_t) blockSize) << ") available in "
+           << numSegments << "\nsegments, the largest of which is "
+           << largestSegment << " (" << BytesToSI(largestSegment * (uint64_t) blockSize)
+           << ") in size\n";
    } else {
-      printf("\nIdentified %d problems!\n", problems);
+      cout << "\nIdentified %d problems!\n", problems;
    } // if/else
 
    return (problems);
@@ -275,27 +270,25 @@
    if (diskSize != 0) {
       if (mainHeader.firstUsableLBA > firstUsedBlock) {
          overlap = mainHeader.firstUsableLBA - firstUsedBlock;
-         printf("Warning! Main partition table overlaps the first partition by %lu blocks!\n",
-                (unsigned long) overlap);
+         cout << "Warning! Main partition table overlaps the first partition by "
+              << overlap << " blocks!\n";
          if (firstUsedBlock > 2) {
-            printf("Try reducing the partition table size by %lu entries.\n",
-                   (unsigned long) (overlap * 4));
-            printf("(Use the 's' item on the experts' menu.)\n");
+            cout << "Try reducing the partition table size by " << overlap * 4
+                 << " entries.\n(Use the 's' item on the experts' menu.)\n";
          } else {
-            printf("You will need to delete this partition or resize it in another utility.\n");
+            cout << "You will need to delete this partition or resize it in another utility.\n";
          } // if/else
          numProbs++;
       } // Problem at start of disk
       if (mainHeader.lastUsableLBA < lastUsedBlock) {
          overlap = lastUsedBlock - mainHeader.lastUsableLBA;
-         printf("Warning! Secondary partition table overlaps the last partition by %lu blocks!\n",
-                (unsigned long) overlap);
+         cout << "Warning! Secondary partition table overlaps the last partition by "
+              << overlap << " blocks!\n";
          if (lastUsedBlock > (diskSize - 2)) {
-            printf("You will need to delete this partition or resize it in another utility.\n");
+            cout << "You will need to delete this partition or resize it in another utility.\n";
          } else {
-            printf("Try reducing the partition table size by %lu entries.\n",
-                   (unsigned long) (overlap * 4));
-            printf("(Use the 's' item on the experts' menu.)\n");
+            cout << "Try reducing the partition table size by " << overlap * 4
+                 << " entries.\n(Use the 's' item on the experts' menu.)\n";
          } // if/else
          numProbs++;
       } // Problem at end of disk
@@ -310,24 +303,31 @@
 int GPTData::CheckHeaderValidity(void) {
    int valid = 3;
 
+   cout.setf(ios::uppercase);
+   cout.fill('0');
+
+   // Note: failed GPT signature checks produce no error message because
+   // a message is displayed in the ReversePartitionBytes() function
    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, (unsigned long) UINT32_C(0x00010000));
+      cout << "Unsupported GPT version in main header; read 0x";
+      cout.width(8);
+      cout << hex << mainHeader.revision << ", should be\n0x";
+      cout.width(8);
+      cout << UINT32_C(0x00010000) << dec << "\n";
    } // 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, (unsigned long) UINT32_C(0x00010000));
+      cout << "Unsupported GPT version in backup header; read 0x";
+      cout.width(8);
+      cout << hex << secondHeader.revision << ", should be\n0x";
+      cout.width(8);
+      cout << UINT32_C(0x00010000) << dec << "\n";
    } // if/else/if
 
    // If MBR bad, check for an Apple disk signature
@@ -336,8 +336,9 @@
         (mainHeader.signature << 32) == APM_SIGNATURE2)) {
       apmFound = 1; // Will display warning message later
    } // if
+   cout.fill(' ');
 
-        return valid;
+   return valid;
 } // GPTData::CheckHeaderValidity()
 
 // Check the header CRC to see if it's OK...
@@ -474,10 +475,15 @@
          } while ((!found) && (j < mainHeader.numParts));
          if (!found) {
             numFound++;
-            printf("\nWarning! Mismatched GPT and MBR partitions! MBR partition "
-                   "%d, of type 0x%02X,\nhas no corresponding GPT partition! "
-                   "You may continue, but this condition\nmight cause data loss"
-                   " in the future!\a\n", i + 1, protectiveMBR.GetType(i));
+            cout << "\nWarning! Mismatched GPT and MBR partition! MBR partition "
+                 << i + 1 << ", of type 0x";
+            cout.fill('0');
+            cout.setf(ios::uppercase);
+            cout.width(2);
+            cout << hex << (int) protectiveMBR.GetType(i) << ",\n"
+                 << "has no corresponding GPT partition! You may continue, but this condition\n"
+                 << "might cause data loss in the future!\a\n" << dec;
+            cout.fill(' ');
          } // if
       } // if
    } // for
@@ -493,13 +499,11 @@
       for (j = 0; j < i; j++) {
          if (partitions[i].DoTheyOverlap(&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].GetFirstLBA(),
-                    (unsigned long long) partitions[i].GetLastLBA());
-            printf("  Partition %d: %llu to %llu\n", j,
-                   (unsigned long long) partitions[j].GetFirstLBA(),
-                    (unsigned long long) partitions[j].GetLastLBA());
+            cout << "\nProblem: partitions " << i + 1 << " and " << j + 1 << " overlap:\n";
+            cout << "  Partition " << i + 1 << ": " << partitions[i].GetFirstLBA()
+                 << " to " << partitions[i].GetLastLBA() << "\n";
+            cout << "  Partition " << j + 1 << ": " << partitions[j].GetFirstLBA()
+                 << " to " << partitions[j].GetLastLBA() << "\n";
          } // if
       } // for j...
    } // for i...
@@ -527,44 +531,44 @@
    ForceLoadGPTData();
 
    if (!beQuiet) {
-      printf("Partition table scan:\n");
+      cout << "Partition table scan:\n";
       protectiveMBR.ShowState();
       bsdDisklabel.ShowState();
       ShowAPMState(); // Show whether there's an Apple Partition Map present
       ShowGPTState(); // Show GPT status
-      printf("\n");
+      cout << "\n";
    } // if
 
    if (apmFound) {
-      printf("\n*******************************************************************\n");
-      printf("This disk appears to contain an Apple-format (APM) partition table!\n");
+      cout << "\n*******************************************************************\n"
+           << "This disk appears to contain an Apple-format (APM) partition table!\n";
       if (!justLooking) {
-         printf("It will be destroyed if you continue!\n");
+         cout << "It will be destroyed if you continue!\n";
       } // if
-      printf("*******************************************************************\n\n\a");
+      cout << "*******************************************************************\n\n\a";
    } // if
 } // GPTData::PartitionScan()
 
 // Read GPT data from a disk.
-int GPTData::LoadPartitions(char* deviceFilename) {
-   int fd, err;
+int GPTData::LoadPartitions(string deviceFilename) {
+   int err;
    int allOK = 1, i;
    uint64_t firstBlock, lastBlock;
    BSDData bsdDisklabel;
+   MBRValidity mbrState;
 
    // First, do a test to see if writing will be possible later....
-   fd = myDisk.OpenForWrite(deviceFilename);
-   if ((fd == -1) && (!justLooking)) {
-      printf("\aNOTE: Write test failed with error number %d. It will be "
-             "impossible to save\nchanges to this disk's partition table!\n",
-             errno);
+   err = myDisk.OpenForWrite(deviceFilename);
+   if ((err == 0) && (!justLooking)) {
+      cout << "\aNOTE: Write test failed with error number " << errno
+           << ". It will be impossible to save\nchanges to this disk's partition table!\n";
 #ifdef __FreeBSD__
-      printf("You may be able to enable writes by exiting this program, typing\n"
-             "'sysctl kern.geom.debugflags=16' at a shell prompt, and re-running this\n"
-             "program.\n");
+      cout << "You may be able to enable writes by exiting this program, typing\n"
+           << "'sysctl kern.geom.debugflags=16' at a shell prompt, and re-running this\n"
+           << "program.\n";
 #endif
-      printf("\n");
-      justLooking = 1;
+      cout << "\n";
+//      justLooking = 1;
    } // if
    myDisk.Close();
 
@@ -574,7 +578,7 @@
       diskSize = myDisk.DiskSize(&err);
       blockSize = (uint32_t) myDisk.GetBlockSize();
       sectorAlignment = myDisk.FindAlignment();
-      strcpy(device, deviceFilename);
+      device = deviceFilename;
       PartitionScan(); // Check for partition types, load GPT, & print summary
 
       whichWasUsed = UseWhichPartitions();
@@ -590,6 +594,9 @@
             XFormDisklabel(&bsdDisklabel, 0);
             break;
          case use_gpt:
+            mbrState = protectiveMBR.GetValidity();
+            if ((mbrState == invalid) || (mbrState == mbr))
+               protectiveMBR.MakeProtectiveMBR();
             break;
          case use_new:
             ClearGPTData();
@@ -597,7 +604,7 @@
             break;
          case use_abort:
             allOK = 0;
-            printf("Aborting because of invalid partition data!\n");
+            cerr << "Aborting because of invalid partition data!\n";
             break;
       } // switch
 
@@ -616,10 +623,10 @@
       } // if
    } else {
       allOK = 0;
-      fprintf(stderr, "Problem opening %s for reading! Error is %d\n",
-              deviceFilename, errno);
+      cerr << "Problem opening " << deviceFilename << " for reading! Error is "
+           << errno << "\n";
       if (errno == EACCES) { // User is probably not running as root
-         fprintf(stderr, "You must run this program as root or use sudo!\n");
+         cerr << "You must run this program as root or use sudo!\n";
       } // if
    } // if/else
    return (allOK);
@@ -630,13 +637,13 @@
 int GPTData::ForceLoadGPTData(void) {
    int allOK = 1, validHeaders;
    off_t seekTo;
-   char* storage;
+   uint8_t* storage;
    uint32_t newCRC, sizeOfParts;
 
    // Seek to and read the main GPT header
    if (myDisk.Seek(1)) {
       if (myDisk.Read(&mainHeader, 512) != 512) { // read main GPT header
-         fprintf(stderr, "Warning! Error %d reading main GPT header!\n", errno);
+         cerr << "Warning! Error " << errno << " reading main GPT header!\n";
       } // if read not OK
    } else allOK = 0; // if/else seek OK
    mainCrcOk = CheckHeaderCRC(&mainHeader);
@@ -653,10 +660,10 @@
          seekTo = mainHeader.backupLBA;
       } else {
          seekTo = diskSize - UINT64_C(1);
-         printf("Warning! Disk size is smaller than the main header indicates! Loading\n"
-                "secondary header from the last sector of the disk! You should use 'v' to\n"
-                "verify disk integrity, and perhaps options on the experts' menu to repair\n"
-                "the disk.\n");
+         cout << "Warning! Disk size is smaller than the main header indicates! Loading\n"
+              << "secondary header from the last sector of the disk! You should use 'v' to\n"
+              << "verify disk integrity, and perhaps options on the experts' menu to repair\n"
+              << "the disk.\n";
       } // else
    } else {
       seekTo = diskSize - UINT64_C(1);
@@ -664,7 +671,7 @@
 
    if (myDisk.Seek(seekTo)) {
       if (myDisk.Read(&secondHeader, 512) != 512) { // read secondary GPT header
-         fprintf(stderr, "Warning! Error %d reading secondary GPT header!\n", errno);
+         cerr << "Warning! Error " << errno << " reading secondary GPT header!\n";
       } // if
       secondCrcOk = CheckHeaderCRC(&secondHeader);
       if (IsLittleEndian() == 0) // big-endian system; adjust header byte order....
@@ -672,8 +679,8 @@
    } else {
       allOK = 0;
       state = gpt_invalid;
-      fprintf(stderr, "Unable to seek to secondary GPT header at sector %llu!\n",
-              (unsigned long long) (diskSize - (UINT64_C(1))));
+      cerr << "Unable to seek to secondary GPT header at sector "
+           << (diskSize - (UINT64_C(1))) << "!\n";
    } // if/else lseek
 
    // Return valid headers code: 0 = both headers bad; 1 = main header
@@ -692,14 +699,14 @@
       // 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 == 1) { // valid main header, invalid backup header
-         fprintf(stderr, "\aCaution: invalid backup GPT header, but valid main header; regenerating\n"
-                 "backup header from main header.\n\n");
+         cerr << "\aCaution: invalid backup GPT header, but valid main header; regenerating\n"
+              << "backup header from main header.\n\n";
          RebuildSecondHeader();
          state = gpt_corrupt;
          secondCrcOk = mainCrcOk; // Since regenerated, use CRC validity of main
       } else if (validHeaders == 2) { // valid backup header, invalid main header
-         fprintf(stderr, "\aCaution: invalid main GPT header, but valid backup; regenerating main header\n"
-                 "from backup!\n\n");
+         cerr << "\aCaution: invalid main GPT header, but valid backup; regenerating main header\n"
+              << "from backup!\n\n";
          RebuildMainHeader();
          state = gpt_corrupt;
          mainCrcOk = secondCrcOk; // Since copied, use CRC validity of backup
@@ -714,11 +721,11 @@
       } else { // bad main header CRC and backup header CRC is OK
          state = gpt_corrupt;
          if (LoadSecondTableAsMain()) {
-            fprintf(stderr, "\aWarning: Invalid CRC on main header data; loaded backup partition table.\n");
+            cerr << "\aWarning: Invalid CRC on main header data; loaded backup partition table.\n";
          } else { // backup table bad, bad main header CRC, but try main table in desperation....
             if (LoadMainTable() == 0) {
                allOK = 0;
-               fprintf(stderr, "\a\aWarning! Unable to load either main or backup partition table!\n");
+               cerr << "\a\aWarning! Unable to load either main or backup partition table!\n";
             } // if
          } // if/else (LoadSecondTableAsMain())
       } // if/else (load partition table)
@@ -729,9 +736,9 @@
       seekTo = secondHeader.partitionEntriesLBA;
       if ((myDisk.Seek(seekTo)) && (secondCrcOk)) {
          sizeOfParts = secondHeader.numParts * secondHeader.sizeOfPartitionEntries;
-         storage = (char*) malloc(sizeOfParts);
+         storage = (uint8_t*) malloc(sizeOfParts);
          if (myDisk.Read(storage, sizeOfParts) != sizeOfParts) {
-            fprintf(stderr, "Warning! Error %d reading backup partition table!\n", errno);
+            cerr << "Warning! Error " << errno << " reading backup partition table!\n";
          } // if
          newCRC = chksum_crc32((unsigned char*) storage,  sizeOfParts);
          free(storage);
@@ -742,14 +749,14 @@
       if (secondPartsCrcOk && secondCrcOk && !mainPartsCrcOk) {
          state = gpt_corrupt;
          allOK = allOK && LoadSecondTableAsMain();
-         fprintf(stderr, "\aWarning! Main partition table CRC mismatch! Loaded backup "
-                         "partition table\ninstead of main partition table!\n\n");
+         cerr << "\aWarning! Main partition table CRC mismatch! Loaded backup "
+              << "partition table\ninstead of main partition table!\n\n";
       } // 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\n");
+         cerr << "Warning! One or more CRCs don't match. You should repair the disk!\n\n";
          state = gpt_corrupt;
       } // if
    } else {
@@ -776,7 +783,7 @@
          retval = 0;
       sizeOfParts = mainHeader.numParts * mainHeader.sizeOfPartitionEntries;
       if (myDisk.Read(partitions, sizeOfParts) != sizeOfParts) {
-         fprintf(stderr, "Warning! Error %d when loading the main partition table!\n", errno);
+         cerr << "Warning! Error " << errno << " when loading the main partition table!\n";
          retval = 0;
       } // if
       newCRC = chksum_crc32((unsigned char*) partitions, sizeOfParts);
@@ -803,7 +810,7 @@
          SetGPTSize(secondHeader.numParts);
          sizeOfParts = secondHeader.numParts * secondHeader.sizeOfPartitionEntries;
          if (myDisk.Read(partitions, sizeOfParts) != sizeOfParts) {
-            fprintf(stderr, "Warning! Read error %d! Misbehavior now likely!\n", errno);
+            cerr << "Warning! Read error " << errno << "! Misbehavior now likely!\n";
             retval = 0;
          } // if
          newCRC = chksum_crc32((unsigned char*) partitions, sizeOfParts);
@@ -812,13 +819,14 @@
          if (IsLittleEndian() == 0)
             ReversePartitionBytes();
          if (!secondPartsCrcOk) {
-            printf("Error! After loading backup partitions, the CRC still doesn't check out!\n");
+            cout << "Caution! After loading backup partitions, the CRC still doesn't check out!\n";
          } // if
       } else {
-         printf("Error! Couldn't seek to backup partition table!\n", retval);
+         cerr << "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", device);
+      cerr << "Error! Couldn't open device " << device
+           << " when recovering backup partition table!\n";
       retval = 0;
    } // if/else
    return retval;
@@ -833,15 +841,15 @@
    uint32_t numParts;
    off_t offset;
 
-   if (strlen(device) == 0) {
-      printf("Device not defined.\n");
+   if (device == "") {
+      cerr << "Device not defined.\n";
    } // if
 
    // First do some final sanity checks....
 
    // This test should only fail on read-only disks....
    if (justLooking) {
-      printf("The justLooking flag is set. This probably means you can't write to the disk.\n");
+      cout << "The justLooking flag is set. This probably means you can't write to the disk.\n";
       allOK = 0;
    } // if
 
@@ -853,29 +861,28 @@
 
    // Check that disk is really big enough to handle this...
    if (mainHeader.backupLBA > diskSize) {
-      fprintf(stderr, "Error! Disk is too small! The 'e' option on the experts' menu might fix the\n"
-              "problem (or it might not). Aborting!\n");
-      printf("(Disk size is %llu sectors, needs to be %llu sectors.)\n",
-             (unsigned long long) diskSize, (unsigned long long) mainHeader.backupLBA);
+      cerr << "Error! Disk is too small! The 'e' option on the experts' menu might fix the\n"
+           << "problem (or it might not). Aborting!\n(Disk size is "
+           << diskSize << " sectors, needs to be " << mainHeader.backupLBA << " sectors.)\n";
       allOK = 0;
    } // if
    // Check that second header is properly placed. Warn and ask if this should
    // be corrected if the test fails....
    if ((mainHeader.backupLBA < (diskSize - UINT64_C(1))) && (quiet == 0)) {
-      printf("Warning! Secondary header is placed too early on the disk! Do you want to\n"
-             "correct this problem? ");
+      cout << "Warning! Secondary header is placed too early on the disk! Do you want to\n"
+           << "correct this problem? ";
       if (GetYN() == 'Y') {
          MoveSecondHeaderToEnd();
-         printf("Have moved second header and partition table to correct location.\n");
+         cout << "Have moved second header and partition table to correct location.\n";
       } else {
-         printf("Have not corrected the problem. Strange problems may occur in the future!\n");
+         cout << "Have not corrected the problem. Strange problems may occur in the future!\n";
       } // if correction requested
    } // if
 
    // Check for overlapping partitions....
    if (FindOverlaps() > 0) {
       allOK = 0;
-      fprintf(stderr, "Aborting write operation!\n");
+      cerr << "Aborting write operation!\n";
    } // if
 
    // Check for mismatched MBR and GPT data, but let it pass if found
@@ -896,12 +903,11 @@
    RecomputeCRCs();
 
    if ((allOK) && (!quiet)) {
-      printf("\nFinal checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING\n");
-      printf("MBR PARTITIONS!!\n\n");
-      printf("Do you want to proceed, possibly destroying your data? ");
+      cout << "\nFinal checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING\n"
+           << "PARTITIONS!!\n\nDo you want to proceed, possibly destroying your data? ";
       answer = GetYN();
       if (answer == 'Y') {
-         printf("OK; writing new GUID partition table (GPT).\n");
+         cout << "OK; writing new GUID partition table (GPT).\n";
       } else {
          allOK = 0;
       } // if/else
@@ -933,8 +939,8 @@
             offset = (off_t) secondTable;
             if (myDisk.Seek(offset) != 1) {
                allOK = 0;
-               printf("Unable to seek to end of disk! Perhaps the 'e' option on the experts' menu\n"
-                      "will resolve this problem.\n");
+               cerr << "Unable to seek to end of disk! Perhaps the 'e' option on the experts' menu\n"
+                    << "will resolve this problem.\n";
             } // if
          } // if
 
@@ -959,20 +965,20 @@
          } // if
 
          if (allOK) { // writes completed OK
-            printf("The operation has completed successfully.\n");
+            cout << "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");
+            cerr << "Warning! An error was reported when writing the partition table! This error\n"
+                 << "MIGHT be harmless, but you may have trashed the disk! Use parted and, if\n"
+                 << "necessary, restore your original partition table.\n";
          } // if/else
          myDisk.Close();
       } else {
-         fprintf(stderr, "Unable to open device %s for writing! Errno is %d! Aborting write!\n",
-                 device, errno);
+         cerr << "Unable to open device " << device << " for writing! Errno is "
+              << errno << "! Aborting write!\n";
          allOK = 0;
       } // if/else
    } else {
-      printf("Aborting write of new partition table.\n");
+      cout << "Aborting write of new partition table.\n";
    } // if
 
    if (IsLittleEndian() == 0) {
@@ -992,7 +998,7 @@
 // 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 GPTData::SaveGPTBackup(string filename) {
    int fd, allOK = 1;
    uint32_t numParts;
    DiskIO backupFile;
@@ -1036,10 +1042,10 @@
       } // if
 
       if (allOK) { // writes completed OK
-         printf("The operation has completed successfully.\n");
+         cout << "The operation has completed successfully.\n";
       } else {
-         printf("Warning! An error was reported when writing the backup file.\n");
-         printf("It may not be usable!\n");
+         cerr << "Warning! An error was reported when writing the backup file.\n"
+              << "It may not be usable!\n";
       } // if/else
       backupFile.Close();
 
@@ -1050,7 +1056,7 @@
          ReversePartitionBytes();
       } // if
    } else {
-      fprintf(stderr, "Unable to open file %s for writing! Aborting!\n", filename);
+      cerr << "Unable to open file " << filename << " for writing! Aborting!\n";
       allOK = 0;
    } // if/else
    return allOK;
@@ -1060,7 +1066,7 @@
 // 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 GPTData::LoadGPTBackup(string filename) {
    int fd, allOK = 1, val;
    uint32_t numParts, sizeOfEntries, sizeOfParts, newCRC;
    int littleEndian = 1;
@@ -1077,7 +1083,7 @@
       // Load the main GPT header, check its vaility, and set the GPT
       // size based on the data
       if (backupFile.Read(&mainHeader, 512) != 512) {
-         fprintf(stderr, "Warning! Read error %d; strange behavior now likely!\n", errno);
+         cerr << "Warning! Read error " << errno << "; strange behavior now likely!\n";
       } // if
       mainCrcOk = CheckHeaderCRC(&mainHeader);
 
@@ -1089,7 +1095,7 @@
       // Load the backup GPT header in much the same way as the main
       // GPT header....
       if (backupFile.Read(&secondHeader, 512) != 512) {
-         fprintf(stderr, "Warning! Read error %d; strange behavior now likely!\n", errno);
+         cerr << "Warning! Read error " << errno << "; strange behavior now likely!\n";
       } // if
       secondCrcOk = CheckHeaderCRC(&secondHeader);
 
@@ -1116,8 +1122,8 @@
 
          // 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");
+            cout << "Warning! Current disk size doesn't match that of the backup!\n"
+                 << "Adjusting sizes to match, but subsequent problems are possible!\n";
             MoveSecondHeaderToEnd();
          } // if
 
@@ -1125,7 +1131,7 @@
          // matches the stored value
          sizeOfParts = numParts * sizeOfEntries;
          if (backupFile.Read(partitions, sizeOfParts) != sizeOfParts) {
-            fprintf(stderr, "Warning! Read error %d; strange behavior now likely!\n", errno);
+            cerr << "Warning! Read error " << errno << "; strange behavior now likely!\n";
          } // if
 
          newCRC = chksum_crc32((unsigned char*) partitions, sizeOfParts);
@@ -1141,7 +1147,7 @@
       } // if/else
    } else {
       allOK = 0;
-      fprintf(stderr, "Unable to open file %s for reading! Aborting!\n", filename);
+      cerr << "Unable to open file " << filename << " for reading! Aborting!\n";
    } // if/else
 
    // Something went badly wrong, so blank out partitions
@@ -1155,25 +1161,25 @@
 // Tell user whether Apple Partition Map (APM) was discovered....
 void GPTData::ShowAPMState(void) {
    if (apmFound)
-      printf("  APM: present\n");
+      cout << "  APM: present\n";
    else
-      printf("  APM: not present\n");
+      cout << "  APM: not present\n";
 } // GPTData::ShowAPMState()
 
 // Tell user about the state of the GPT data....
 void GPTData::ShowGPTState(void) {
    switch (state) {
       case gpt_invalid:
-         printf("  GPT: not present\n");
+         cout << "  GPT: not present\n";
          break;
       case gpt_valid:
-         printf("  GPT: present\n");
+         cout << "  GPT: present\n";
          break;
       case gpt_corrupt:
-         printf("  GPT: damaged\n");
+         cout << "  GPT: damaged\n";
          break;
       default:
-         printf("\a  GPT: unknown -- bug!\n");
+         cout << "\a  GPT: unknown -- bug!\n";
          break;
    } // switch
 } // GPTData::ShowGPTState()
@@ -1181,24 +1187,20 @@
 // Display the basic GPT data
 void GPTData::DisplayGPTData(void) {
    int i;
-   char sizeInSI[255]; // String to hold size of disk in SI units
-   char tempStr[255];
+//   char tempStr[255];
    uint64_t temp, totalFree;
 
-   BytesToSI(diskSize * blockSize, sizeInSI);
-   printf("Disk %s: %llu sectors, ", device,
-          (unsigned long long) diskSize);
-   printf("%s\n", sizeInSI);
-   printf("Logical sector size: %d bytes\n", blockSize);
-   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 %llu, last usable sector is %llu\n",
-          (unsigned long long) mainHeader.firstUsableLBA,
-          (unsigned long long) mainHeader.lastUsableLBA);
+   cout << "Disk " << device << ": " << diskSize << " sectors, "
+        << BytesToSI(diskSize * blockSize) << "\n";
+   cout << "Logical sector size: " << blockSize << " bytes\n";
+   cout << "Disk identifier (GUID): " << GUIDToStr(mainHeader.diskGUID) << "\n";
+   cout << "Partition table holds up to " << mainHeader.numParts << " entries\n";
+   cout << "First usable sector is " << mainHeader.firstUsableLBA
+        << ", last usable sector is " << mainHeader.lastUsableLBA << "\n";
    totalFree = FindFreeBlocks(&i, &temp);
-   printf("Total free space is %llu sectors ", (unsigned long long) totalFree);
-   printf("(%s)\n", BytesToSI(totalFree * (uint64_t) blockSize, sizeInSI));
-   printf("\nNumber  Start (sector)    End (sector)  Size       Code  Name\n");
+   cout << "Total free space is " << totalFree << " sectors ("
+        << BytesToSI(totalFree * (uint64_t) blockSize) << ")\n";
+   cout << "\nNumber  Start (sector)    End (sector)  Size       Code  Name\n";
    for (i = 0; i < mainHeader.numParts; i++) {
       partitions[i].ShowSummary(i, blockSize);
    } // for
@@ -1214,7 +1216,7 @@
       partNum = GetPartNum();
       ShowPartDetails(partNum);
    } else {
-      printf("No partitions\n");
+      cout << "No partitions\n";
    } // if/else
 } // GPTData::ShowDetails()
 
@@ -1223,7 +1225,7 @@
    if (partitions[partNum].GetFirstLBA() != 0) {
       partitions[partNum].ShowDetails(blockSize);
    } else {
-      printf("Partition #%d does not exist.", (int) (partNum + 1));
+      cout << "Partition #" << partNum + 1 << " does not exist.";
    } // if
 } // GPTData::ShowPartDetails()
 
@@ -1253,8 +1255,7 @@
    char prompt[255];
    uint32_t curLow, curHigh;
 
-   printf("Current partition table size is %lu.\n",
-          (unsigned long) mainHeader.numParts);
+   cout << "Current partition table size is " << mainHeader.numParts << ".\n";
    GetPartRange(&curLow, &curHigh);
    curHigh++; // since GetPartRange() returns numbers starting from 0...
    // There's no point in having fewer than four partitions....
@@ -1264,10 +1265,10 @@
            (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");
+      cout << "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()
@@ -1295,7 +1296,7 @@
          partNum = GetNumber(firstFreePart + 1, mainHeader.numParts,
                              firstFreePart + 1, prompt) - 1;
          if (partitions[partNum].GetFirstLBA() != 0)
-            printf("partition %d is in use.\n", partNum + 1);
+            cout << "partition " << partNum + 1 << " is in use.\n";
       } while (partitions[partNum].GetFirstLBA() != 0);
 
       // Get first block for new partition...
@@ -1320,9 +1321,9 @@
 
       firstFreePart = CreatePartition(partNum, firstBlock, lastBlock);
       partitions[partNum].ChangeType();
-      partitions[partNum].SetName((unsigned char*) partitions[partNum].GetNameType().c_str());
+      partitions[partNum].SetName(partitions[partNum].GetNameType());
    } else {
-      printf("No free sectors available\n");
+      cout << "No free sectors available\n";
    } // if/else
 } // GPTData::CreatePartition()
 
@@ -1337,7 +1338,7 @@
       partNum = GetNumber(low + 1, high + 1, low, prompt);
       DeletePartition(partNum - 1);
    } else {
-      printf("No partitions\n");
+      cout << "No partitions\n";
    } // if/else
 } // GPTData::DeletePartition()
 
@@ -1351,7 +1352,7 @@
       partNum = GetPartNum();
       partitions[partNum].ChangeType();
    } else {
-      printf("No partitions\n");
+      cout << "No partitions\n";
    } // if/else
 } // GPTData::ChangePartType()
 
@@ -1374,52 +1375,45 @@
 // MBR.
 int GPTData::DestroyGPT(int prompt) {
    int fd, i, sum, tableSize;
-   char blankSector[512], goOn = 'Y', blank = 'N';
-   char* emptyTable;
+   uint8_t blankSector[512], goOn = 'Y', blank = 'N';
+   uint8_t* emptyTable;
 
    for (i = 0; i < 512; i++) {
-      blankSector[i] = '\0';
+      blankSector[i] = 0;
    } // for
 
    if (((apmFound) || (bsdFound)) && (prompt > 0)) {
-      printf("WARNING: APM or BSD disklabel structures detected! This operation could\n"
-             "damage any APM or BSD partitions on this disk!\n");
+      cout << "WARNING: APM or BSD disklabel structures detected! This operation could\n"
+           << "damage any APM or BSD partitions on this disk!\n";
    } // if APM or BSD
    if (prompt > 0) {
-      printf("\a\aAbout to wipe out GPT on %s. Proceed? ", device);
+      cout << "\a\aAbout to wipe out GPT on " << device << ". Proceed? ";
       goOn = GetYN();
    } // if
    if (goOn == 'Y') {
-/*      OpenForWrite(device);
-#ifdef __APPLE__
-      // MacOS X requires a shared lock under some circumstances....
-      if (fd < 0) {
-         fd = open(device, O_WRONLY|O_SHLOCK);
-      } // if
-#endif */
       if (myDisk.OpenForWrite(device)) {
          myDisk.Seek(mainHeader.currentLBA); // seek to GPT header
          if (myDisk.Write(blankSector, 512) != 512) { // blank it out
-            fprintf(stderr, "Warning! GPT main header not overwritten! Error is %d\n", errno);
+            cerr << "Warning! GPT main header not overwritten! Error is " << errno << "\n";
          } // if
          myDisk.Seek(mainHeader.partitionEntriesLBA); // seek to partition table
          tableSize = mainHeader.numParts * mainHeader.sizeOfPartitionEntries;
-         emptyTable = (char*) malloc(tableSize);
+         emptyTable = (uint8_t*) malloc(tableSize);
          for (i = 0; i < tableSize; i++)
-            emptyTable[i] = (char) 0;
+            emptyTable[i] = 0;
          sum = myDisk.Write(emptyTable, tableSize);
          if (sum != tableSize)
-            fprintf(stderr, "Warning! GPT main partition table not overwritten! Error is %d\n", errno);
+            cerr << "Warning! GPT main partition table not overwritten! Error is " << errno << "\n";
          myDisk.Seek(secondHeader.partitionEntriesLBA); // seek to partition table
          sum = myDisk.Write(emptyTable, tableSize);
          if (sum != tableSize)
-            fprintf(stderr, "Warning! GPT backup partition table not overwritten! Error is %d\n", errno);
+            cerr << "Warning! GPT backup partition table not overwritten! Error is " << errno << "\n";
          myDisk.Seek(secondHeader.currentLBA); // seek to GPT header
          if (myDisk.Write(blankSector, 512) != 512) { // blank it out
-            fprintf(stderr, "Warning! GPT backup header not overwritten! Error is %d\n", errno);
+            cerr << "Warning! GPT backup header not overwritten! Error is " << errno << "\n";
          } // if
          if (prompt > 0) {
-            printf("Blank out MBR? ");
+            cout << "Blank out MBR? ";
             blank = GetYN();
          } // if
          // Note on below: Touch the MBR only if the user wants it completely
@@ -1430,18 +1424,18 @@
          if ((blank == 'Y') || (prompt < 0)) {
             myDisk.Seek(0);
             if (myDisk.Write(blankSector, 512) != 512) { // blank it out
-               fprintf(stderr, "Warning! MBR not overwritten! Error is %d!\n", errno);
+               cerr << "Warning! MBR not overwritten! Error is " << errno << "!\n";
             } // if
          } else {
-            printf("MBR is unchanged. You may need to delete an EFI GPT (0xEE) partition\n"
-                   "with fdisk or another tool.\n");
+            cout << "MBR is unchanged. You may need to delete an EFI GPT (0xEE) partition\n"
+                 << "with fdisk or another tool.\n";
          } // if/else
          myDisk.DiskSync();
          myDisk.Close();
-         printf("GPT data structures destroyed! You may now partition the disk using fdisk or\n"
-               "other utilities. Program will now terminate.\n");
+         cout << "GPT data structures destroyed! You may now partition the disk using fdisk or\n"
+              << "other utilities. Program will now terminate.\n";
       } else {
-         printf("Problem opening %s for writing! Program will now terminate.\n", device);
+         cerr << "Problem opening " << device << " for writing! Program will now terminate.\n";
       } // if/else (fd != -1)
    } // if (goOn == 'Y')
    return (goOn == 'Y');
@@ -1465,54 +1459,55 @@
    mbrState = protectiveMBR.GetValidity();
 
    if ((state == gpt_invalid) && ((mbrState == mbr) || (mbrState == hybrid))) {
-      printf("\n***************************************************************\n"
-             "Found invalid GPT and valid MBR; converting MBR to GPT format.\n");
+      cout << "\n***************************************************************\n"
+           << "Found invalid GPT and valid MBR; converting MBR to GPT format.\n";
       if (!justLooking) {
-         printf("\aTHIS OPERATON IS POTENTIALLY DESTRUCTIVE! Exit by typing 'q' if\n"
-               "you don't want to convert your MBR partitions to GPT format!\n");
+         cout << "\aTHIS OPERATON IS POTENTIALLY DESTRUCTIVE! Exit by typing 'q' if\n"
+              << "you don't want to convert your MBR partitions to GPT format!\n";
       } // if
-      printf("***************************************************************\n\n");
+      cout << "***************************************************************\n\n";
       which = use_mbr;
    } // if
 
    if ((state == gpt_invalid) && bsdFound) {
-      printf("\n**********************************************************************\n"
-            "Found invalid GPT and valid BSD disklabel; converting BSD disklabel\n"
-            "to GPT format.");
+      cout << "\n**********************************************************************\n"
+           << "Found invalid GPT and valid BSD disklabel; converting BSD disklabel\n"
+           << "to GPT format.";
       if (!justLooking) {
-      printf("\a THIS OPERATON IS POTENTIALLY DESTRUCTIVE! Your first\n"
-            "BSD partition will likely be unusable. Exit by typing 'q' if you don't\n"
-            "want to convert your BSD partitions to GPT format!");
+      cout << "\a THIS OPERATON IS POTENTIALLY DESTRUCTIVE! Your first\n"
+           << "BSD partition will likely be unusable. Exit by typing 'q' if you don't\n"
+           << "want to convert your BSD partitions to GPT format!";
       } // if
-      printf("\n**********************************************************************\n\n");
+      cout << "\n**********************************************************************\n\n";
       which = use_bsd;
    } // if
 
    if ((state == gpt_valid) && (mbrState == gpt)) {
       which = use_gpt;
       if (!beQuiet)
-         printf("Found valid GPT with protective MBR; using GPT.\n");
+         cout << "Found valid GPT with protective MBR; using GPT.\n";
    } // if
    if ((state == gpt_valid) && (mbrState == hybrid)) {
       which = use_gpt;
       if (!beQuiet)
-         printf("Found valid GPT with hybrid MBR; using GPT.\n");
+         cout << "Found valid GPT with hybrid MBR; using GPT.\n";
    } // 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");
+      cout << "\aFound valid GPT with corrupt MBR; using GPT and will create new\n"
+           << "protective MBR on save.\n";
       which = use_gpt;
       protectiveMBR.MakeProtectiveMBR();
    } // if
    if ((state == gpt_valid) && (mbrState == mbr)) {
       if (!beQuiet) {
-         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: ");
+         cout << "Found valid MBR and GPT. Which do you want to use?\n";
+         answer = GetNumber(1, 3, 2, " 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");
+            cout << "Using GPT and creating fresh protective MBR.\n";
          } else which = use_new;
       } else which = use_abort;
    } // if
@@ -1524,34 +1519,33 @@
          which = use_abort;
       } else {
          if ((mbrState == mbr) || (mbrState == hybrid)) {
-            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: ");
+            cout << "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, " 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: ");
+            cout << "Found invalid MBR and corrupt GPT. What do you want to do? (Using the\n"
+                 << "GPT MAY permit recovery of GPT data.)\n";
+            answer = GetNumber(1, 2, 1, " 1 - GPT\n 2 - Create blank GPT\n\nYour answer: ");
             if (answer == 1) {
                which = use_gpt;
             } else which = use_new;
          } else { // corrupt GPT, MBR indicates it's a GPT disk....
-            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");
+            cout << "\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";
             which = use_gpt;
          } // if/else/else
       } // else (beQuiet)
    } // if (corrupt GPT)
 
    if (which == use_new)
-      printf("Creating new GPT entries.\n");
+      cout << "Creating new GPT entries.\n";
 
    return which;
 } // UseWhichPartitions()
@@ -1611,30 +1605,30 @@
       // Now see if the specified partition has a BSD type code....
       hexCode = partitions[partNum].GetHexType();
       if ((hexCode != 0xa500) && (hexCode != 0xa900)) {
-         printf("Specified partition doesn't have a disklabel partition type "
-               "code.\nContinue anyway?");
+         cout << "Specified partition doesn't have a disklabel partition type "
+              << "code.\nContinue anyway? ";
          goOn = (GetYN() == 'Y');
       } // if
 
       // If all is OK, read the disklabel and convert it.
       if (goOn) {
-         goOn = disklabel.ReadBSDData(device, partitions[partNum].GetFirstLBA(),
+         goOn = disklabel.ReadBSDData(&myDisk, partitions[partNum].GetFirstLBA(),
                                       partitions[partNum].GetLastLBA());
          if ((goOn) && (disklabel.IsDisklabel())) {
             numDone = XFormDisklabel(&disklabel, startPart);
             if (numDone == 1)
-               printf("Converted %d BSD partition.\n", numDone);
+               cout << "Converted " << numDone << " BSD partition.\n";
             else
-               printf("Converted %d BSD partitions.\n", numDone);
+               cout << "Converted " << numDone << " BSD partitions.\n";
          } else {
-            printf("Unable to convert partitions! Unrecognized BSD disklabel.\n");
+            cout << "Unable to convert partitions! Unrecognized BSD disklabel.\n";
          } // if/else
       } // if
       if (numDone > 0) { // converted partitions; delete carrier
          partitions[partNum].BlankPartition();
       } // if
    } else {
-      printf("No partitions\n");
+      cout << "No partitions\n";
    } // if/else
    return numDone;
 } // GPTData::XFormDisklable(int i)
@@ -1667,42 +1661,48 @@
    char line[255];
    char* junk;
 
+   cout.setf(ios::uppercase);
+   cout.fill('0');
+
    if ((mbrPart < 0) || (mbrPart > 3)) {
-      printf("MBR partition %d is out of range; omitting it.\n", mbrPart + 1);
+      cout << "MBR partition " << mbrPart + 1 << " is out of range; omitting it.\n";
       allOK = 0;
    } // if
    if (gptPart >= mainHeader.numParts) {
-      printf("GPT partition %d is out of range; omitting it.\n", gptPart + 1);
+      cout << "GPT partition " << gptPart + 1 << " is out of range; omitting it.\n";
       allOK = 0;
    } // if
    if (allOK && (partitions[gptPart].GetLastLBA() == UINT64_C(0))) {
-      printf("GPT partition %d is undefined; omitting it.\n", gptPart + 1);
+      cout << "GPT partition " << gptPart + 1 << " is undefined; omitting it.\n";
       allOK = 0;
    } // if
    if (allOK && (partitions[gptPart].GetFirstLBA() <= UINT32_MAX) &&
        (partitions[gptPart].GetLengthLBA() <= UINT32_MAX)) {
       if (partitions[gptPart].GetLastLBA() > UINT32_MAX) {
-         printf("Caution: Partition end point past 32-bit pointer boundary;"
-                " some OSes may\nreact strangely.\n");
+         cout << "Caution: Partition end point past 32-bit pointer boundary;"
+              << " some OSes may\nreact strangely.\n";
       } // if partition ends past 32-bit (usually 2TiB) boundary
       do {
-         printf("Enter an MBR hex code (default %02X): ",
-                  typeHelper.GUIDToID(partitions[gptPart].GetType()) / 256);
+         cout << "Enter an MBR hex code (default " << hex;
+         cout.width(2);
+         cout << typeHelper.GUIDToID(partitions[gptPart].GetType()) / 256 << "): ";
          junk = fgets(line, 255, stdin);
-         sscanf(line, "%x", &typeCode);
          if (line[0] == '\n')
             typeCode = partitions[gptPart].GetHexType() / 256;
+         else
+            sscanf(line, "%x", &typeCode);
       } while ((typeCode <= 0) || (typeCode > 255));
-      printf("Set the bootable flag? ");
+      cout << "Set the bootable flag? ";
       bootable = (GetYN() == 'Y');
       length = partitions[gptPart].GetLengthLBA();
       protectiveMBR.MakePart(mbrPart, (uint32_t) partitions[gptPart].GetFirstLBA(),
                              (uint32_t) length, typeCode, bootable);
    } else { // partition out of range
-      printf("Partition %d begins beyond the 32-bit pointer limit of MBR "
-             "partitions, or is\n too big; omitting it.\n", gptPart + 1);
+      cout << "Partition " << gptPart + 1 << " begins beyond the 32-bit pointer limit of MBR "
+           << "partitions, or is\n too big; omitting it.\n";
       allOK = 0;
    } // if/else
+   cout.fill(' ');
    return allOK;
 } // GPTData::OnePartToMBR()
 
@@ -1720,15 +1720,15 @@
    // Get the numbers of up to four partitions to add to the
    // hybrid MBR....
    numParts = CountParts();
-   printf("Counted %d partitions.\n", numParts);
+   cout << "Counted " << numParts << " partitions.\n";
 
    // Prepare the MBR for conversion (empty it of existing partitions).
    protectiveMBR.EmptyMBR(0);
    protectiveMBR.SetDiskSize(diskSize);
 
    if (numParts > 4) { // Over four partitions; engage in triage
-      printf("Type from one to four GPT partition numbers, separated by spaces, to be\n"
-            "used in the MBR, in sequence: ");
+      cout << "Type from one to four GPT partition numbers, separated by spaces, to be\n"
+           << "used in the MBR, in sequence: ";
       junk = fgets(line, 255, stdin);
       numParts = sscanf(line, "%d %d %d %d", &partNums[0], &partNums[1],
                         &partNums[2], &partNums[3]);
@@ -1743,10 +1743,10 @@
 
    for (i = 0; i < numParts; i++) {
       j = partNums[i] - 1;
-      printf("\nCreating entry for partition #%d\n", j + 1);
+      cout << "\nCreating entry for partition #" << j + 1 << "\n";
       numConverted += OnePartToMBR(j, i);
    } // for
-   printf("MBR writing returned %d\n", protectiveMBR.WriteMBRData(&myDisk));
+   cout << "MBR writing returned " << protectiveMBR.WriteMBRData(&myDisk) << "\n";
    return numConverted;
 } // GPTData::XFormToMBR()
 
@@ -1760,14 +1760,14 @@
    char fillItUp = 'M'; // fill extra partition entries? (Yes/No/Maybe)
    char eeFirst = 'Y'; // Whether EFI GPT (0xEE) partition comes first in table
 
-   printf("\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 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";
 
    // Now get the numbers of up to three partitions to add to the
    // hybrid MBR....
-   printf("Type from one to three GPT partition numbers, separated by spaces, to be\n"
-         "added to the hybrid MBR, in sequence: ");
+   cout << "Type from one to three GPT partition numbers, separated by spaces, to be\n"
+        << "added to the hybrid MBR, in sequence: ";
    junk = fgets(line, 255, stdin);
    numParts = sscanf(line, "%d %d %d", &partNums[0], &partNums[1], &partNums[2]);
 
@@ -1776,13 +1776,13 @@
       // alone....
       protectiveMBR.EmptyMBR(0);
       protectiveMBR.SetDiskSize(diskSize);
-      printf("Place EFI GPT (0xEE) partition first in MBR (good for GRUB)? ");
+      cout << "Place EFI GPT (0xEE) partition first in MBR (good for GRUB)? ";
       eeFirst = GetYN();
    } // if
 
    for (i = 0; i < numParts; i++) {
       j = partNums[i] - 1;
-      printf("\nCreating entry for partition #%d\n", j + 1);
+      cout << "\nCreating entry for partition #" << j + 1 << "\n";
       if (eeFirst == 'Y')
          mbrNum = i + 1;
       else
@@ -1811,13 +1811,13 @@
       for (i = 0; i < 4; i++) {
          if (protectiveMBR.GetType(i) == 0x00) { // unused entry....
             if (fillItUp == 'M') {
-               printf("\nUnused partition space(s) found. Use one to protect more partitions? ");
+               cout << "\nUnused partition space(s) found. Use one to protect more partitions? ";
                fillItUp = GetYN();
                typeCode = 0x00; // use this to flag a need to get type code
             } // if
             if (fillItUp == 'Y') {
                while ((typeCode <= 0) || (typeCode > 255)) {
-                  printf("Enter an MBR hex code (EE is EFI GPT, but may confuse MacOS): ");
+                  cout << "Enter an MBR hex code (EE is EFI GPT, but may confuse MacOS): ";
                   // Comment on above: Mac OS treats disks with more than one
                   // 0xEE MBR partition as MBR disks, not as GPT disks.
                   junk = fgets(line, 255, stdin);
@@ -1852,9 +1852,9 @@
    // that fills the allocated sectors
    i = blockSize / GPT_SIZE;
    if ((numEntries % i) != 0) {
-      printf("Adjusting GPT size from %lu ", (unsigned long) numEntries);
+      cout << "Adjusting GPT size from " << numEntries << " to ";
       numEntries = ((numEntries / i) + 1) * i;
-      printf("to %lu to fill the sector\n", (unsigned long) numEntries);
+      cout << numEntries << " to fill the sector\n";
    } // if
 
    // Do the work only if the # of partitions is changing. Along with being
@@ -1869,9 +1869,10 @@
          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);
+               cout << "The highest-numbered partition is " << high + 1
+                    << ", which is greater than the requested\n"
+                    << "partition table size of " << numEntries
+                    << "; cannot resize. Perhaps sorting will help.\n";
                allOK = 0;
             } else { // go ahead with copy
                if (numEntries < mainHeader.numParts)
@@ -1896,7 +1897,7 @@
          if (diskSize > 0)
             CheckGPTSize();
       } else { // Bad memory allocation
-         fprintf(stderr, "Error allocating memory for partition table!\n");
+         cerr << "Error allocating memory for partition table!\n";
          allOK = 0;
       } // if/else
    } // if/else
@@ -1930,7 +1931,7 @@
       // Now delete the GPT partition
       partitions[partNum].BlankPartition();
    } else {
-      fprintf(stderr, "Partition number %d out of range!\n", partNum + 1);
+      cerr << "Partition number " << partNum + 1 << " out of range!\n";
       retval = 0;
    } // if/else
    return retval;
@@ -2001,7 +2002,8 @@
    int goOn = 1, i;
 
    // Set up the partition table....
-   free(partitions);
+   if (partitions != NULL)
+      free(partitions);
    partitions = NULL;
    SetGPTSize(NUM_GPT_ENTRIES);
 
@@ -2051,11 +2053,12 @@
    secondHeader.partitionEntriesLBA = secondHeader.lastUsableLBA + UINT64_C(1);
 } // GPTData::FixSecondHeaderLocation()
 
-int GPTData::SetName(uint32_t partNum, char* theName) {
+int GPTData::SetName(uint32_t partNum, string theName) {
    int retval = 1;
-   if (!IsFreePartNum(partNum))
-      partitions[partNum].SetName((unsigned char*) theName);
-   else retval = 0;
+
+   if (!IsFreePartNum(partNum)) {
+      partitions[partNum].SetName(theName);
+   } else retval = 0;
 
    return retval;
 } // GPTData::SetName
@@ -2117,7 +2120,6 @@
       // Check to see that every sector between the earlier one and the
       // requested one is clear, and that it's not too early....
       if (earlier >= mainHeader.firstUsableLBA) {
-//         printf("earlier is %llu, first usable is %llu\n", earlier, mainHeader.firstUsableLBA);
          sectorOK = 1;
          testSector = earlier;
          do {
@@ -2125,7 +2127,6 @@
          } while ((sectorOK == 1) && (testSector < *sector));
          if (sectorOK == 1) {
             *sector = earlier;
-//            printf("Moved sector earlier.\n");
          } // if
       } // if firstUsableLBA check
 
@@ -2138,22 +2139,21 @@
          } while ((sectorOK == 1) && (testSector > *sector));
          if (sectorOK == 1) {
             *sector = later;
-//            printf("Moved sector later\n");
          } // if
       } // if
 
       // If sector was changed successfully, inform the user of this fact.
       // Otherwise, notify the user that it couldn't be done....
       if (sectorOK == 1) {
-         printf("Information: Moved requested sector from %llu to %llu for\n"
-                "alignment purposes.\n",
-                (unsigned long long) original, (unsigned long long) *sector);
+         cout << "Information: Moved requested sector from " << original << " to "
+              << *sector << " for\nalignment purposes.\n";
          if (!beQuiet)
-            printf("Use 'l' on the experts' menu to adjust alignment\n");
+            cout << "Use 'l' on the experts' menu to adjust alignment\n";
       } else {
-         printf("Information: Sector not aligned on %d-sector boundary and could not be moved.\n"
-                "If you're using a Western Digital Advanced Format or similar disk with\n"
-                "underlying 4096-byte sectors, performance may suffer.\n", sectorAlignment);
+         cout << "Information: Sector not aligned on " << sectorAlignment
+              << "-sector boundary and could not be moved.\n"
+              << "If you're using a Western Digital Advanced Format or similar disk with\n"
+              << "underlying 4096-byte sectors, performance may suffer.\n";
          retval = 0;
       } // if/else
    } // if
@@ -2408,8 +2408,8 @@
    // if the function is called out of order. Unfortunately, it'll also
    // mismatch if there's data corruption.
    if ((mainHeader.signature != GPT_SIGNATURE) && (IsLittleEndian() == 0)) {
-      printf("GPT signature mismatch in GPTData::ReversePartitionBytes(). This indicates\n"
-            "data corruption or a misplaced call to this function.\n");
+      cerr << "GPT signature mismatch in GPTData::ReversePartitionBytes(). This indicates\n"
+           << "data corruption or a misplaced call to this function.\n";
    } // if signature mismatch....
    for (i = 0; i < mainHeader.numParts; i++) {
       partitions[i].ReversePartBytes();
@@ -2430,42 +2430,41 @@
    int allOK = 1;
 
    if (sizeof(uint8_t) != 1) {
-      fprintf(stderr, "uint8_t is %lu bytes, should be 1 byte; aborting!\n", sizeof(uint8_t));
+      cerr << "uint8_t is " << sizeof(uint8_t) << " bytes, should be 1 byte; aborting!\n";
       allOK = 0;
    } // if
    if (sizeof(uint16_t) != 2) {
-      fprintf(stderr, "uint16_t is %lu bytes, should be 2 bytes; aborting!\n", sizeof(uint16_t));
+      cerr << "uint16_t is " << sizeof(uint16_t) << " bytes, should be 2 bytes; aborting!\n";
       allOK = 0;
    } // if
    if (sizeof(uint32_t) != 4) {
-      fprintf(stderr, "uint32_t is %lu bytes, should be 4 bytes; aborting!\n", sizeof(uint32_t));
+      cerr << "uint32_t is " << sizeof(uint32_t) << " bytes, should be 4 bytes; aborting!\n";
       allOK = 0;
    } // if
    if (sizeof(uint64_t) != 8) {
-      fprintf(stderr, "uint64_t is %lu bytes, should be 8 bytes; aborting!\n", sizeof(uint64_t));
+      cerr << "uint64_t is " << sizeof(uint64_t) << " bytes, should be 8 bytes; aborting!\n";
       allOK = 0;
    } // if
    if (sizeof(struct MBRRecord) != 16) {
-      fprintf(stderr, "MBRRecord is %lu bytes, should be 16 bytes; aborting!\n", sizeof(MBRRecord));
+      cerr << "MBRRecord is " << sizeof(MBRRecord) << " bytes, should be 16 bytes; aborting!\n";
       allOK = 0;
    } // if
    if (sizeof(struct TempMBR) != 512) {
-      fprintf(stderr, "TempMBR is %lu bytes, should be 512 bytes; aborting!\n", sizeof(TempMBR));
+      cerr << "TempMBR is " <<  sizeof(TempMBR) << " bytes, should be 512 bytes; aborting!\n";
       allOK = 0;
    } // if
    if (sizeof(struct GPTHeader) != 512) {
-      fprintf(stderr, "GPTHeader is %lu bytes, should be 512 bytes; aborting!\n", sizeof(GPTHeader));
+      cerr << "GPTHeader is " << sizeof(GPTHeader) << " bytes, should be 512 bytes; aborting!\n";
       allOK = 0;
    } // if
    if (sizeof(GPTPart) != 128) {
-      fprintf(stderr, "GPTPart is %lu bytes, should be 128 bytes; aborting!\n", sizeof(GPTPart));
+      cerr << "GPTPart is " << sizeof(GPTPart) << " bytes, should be 128 bytes; aborting!\n";
       allOK = 0;
    } // if
-// Determine endianness; set allOK = 0 if running on big-endian hardware
+   // Determine endianness; warn user if running on big-endian (PowerPC, etc.) hardware
    if (IsLittleEndian() == 0) {
-      fprintf(stderr, "\aRunning on big-endian hardware. Big-endian support is new and poorly"
-            " tested!\nBeware!\n");
-      // allOK = 0;
+      cerr << "\aRunning on big-endian hardware. Big-endian support is new and poorly"
+            " tested!\n";
    } // if
    return (allOK);
 } // SizesOK()