/* basicmbr.cc -- Functions for loading, saving, and manipulating legacy MBR partition
   data. */

/* Initial coding by Rod Smith, January to February, 2009 */

/* This program is copyright (c) 2009-2011 by Roderick W. Smith. It is distributed
  under the terms of the GNU GPL version 2, as detailed in the COPYING file. */

#define __STDC_LIMIT_MACROS
#define __STDC_CONSTANT_MACROS

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <fcntl.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>
#include <errno.h>
#include <iostream>
#include <algorithm>
#include "mbr.h"
#include "support.h"

using namespace std;

/****************************************
 *                                      *
 * MBRData class and related structures *
 *                                      *
 ****************************************/

BasicMBRData::BasicMBRData(void) {
   blockSize = SECTOR_SIZE;
   diskSize = 0;
   device = "";
   state = invalid;
   numHeads = MAX_HEADS;
   numSecspTrack = MAX_SECSPERTRACK;
   myDisk = NULL;
   canDeleteMyDisk = 0;
   EmptyMBR();
} // BasicMBRData default constructor

BasicMBRData::BasicMBRData(string filename) {
   blockSize = SECTOR_SIZE;
   diskSize = 0;
   device = filename;
   state = invalid;
   numHeads = MAX_HEADS;
   numSecspTrack = MAX_SECSPERTRACK;
   myDisk = NULL;
   canDeleteMyDisk = 0;

   // Try to read the specified partition table, but if it fails....
   if (!ReadMBRData(filename)) {
      EmptyMBR();
      device = "";
   } // if
} // BasicMBRData(string filename) constructor

// Free space used by myDisk only if that's OK -- sometimes it will be
// copied from an outside source, in which case that source should handle
// it!
BasicMBRData::~BasicMBRData(void) {
   if (canDeleteMyDisk)
      delete myDisk;
} // BasicMBRData destructor

// Assignment operator -- copy entire set of MBR data.
BasicMBRData & BasicMBRData::operator=(const BasicMBRData & orig) {
   int i;

   memcpy(code, orig.code, 440);
   diskSignature = orig.diskSignature;
   nulls = orig.nulls;
   MBRSignature = orig.MBRSignature;
   blockSize = orig.blockSize;
   diskSize = orig.diskSize;
   numHeads = orig.numHeads;
   numSecspTrack = orig.numSecspTrack;
   canDeleteMyDisk = orig.canDeleteMyDisk;
   device = orig.device;
   state = orig.state;

   myDisk = new DiskIO;
   if (myDisk == NULL) {
      cerr << "Unable to allocate memory in BasicMBRData::operator=()! Terminating!\n";
      exit(1);
   } // if
   if (orig.myDisk != NULL)
      myDisk->OpenForRead(orig.myDisk->GetName());

   for (i = 0; i < MAX_MBR_PARTS; i++) {
      partitions[i] = orig.partitions[i];
   } // for
   return *this;
} // BasicMBRData::operator=()

/**********************
 *                    *
 * Disk I/O functions *
 *                    *
 **********************/

// Read data from MBR. Returns 1 if read was successful (even if the
// data isn't a valid MBR), 0 if the read failed.
int BasicMBRData::ReadMBRData(const string & deviceFilename) {
   int allOK = 1;

   if (myDisk == NULL) {
      myDisk = new DiskIO;
      if (myDisk == NULL) {
         cerr << "Unable to allocate memory in BasicMBRData::ReadMBRData()! Terminating!\n";
         exit(1);
      } // if
      canDeleteMyDisk = 1;
   } // if
   if (myDisk->OpenForRead(deviceFilename)) {
      allOK = ReadMBRData(myDisk);
   } else {
      allOK = 0;
   } // if

   if (allOK)
      device = deviceFilename;

   return allOK;
} // BasicMBRData::ReadMBRData(const string & deviceFilename)

// Read data from MBR. If checkBlockSize == 1 (the default), the block
// size is checked; otherwise it's set to the default (512 bytes).
// Note that any extended partition(s) present will be omitted from
// in the partitions[] array; these partitions must be re-created when
// the partition table is saved in MBR format.
int BasicMBRData::ReadMBRData(DiskIO * theDisk, int checkBlockSize) {
   int allOK = 1, i, logicalNum = 0;
   int err = 1;
   TempMBR tempMBR;

   if ((myDisk != NULL) && (myDisk != theDisk) && (canDeleteMyDisk)) {
      delete myDisk;
      canDeleteMyDisk = 0;
   } // if

   myDisk = theDisk;

   // Empty existing MBR data, including the logical partitions...
   EmptyMBR(0);

   if (myDisk->Seek(0))
     if (myDisk->Read(&tempMBR, 512))
        err = 0;
   if (err) {
      cerr << "Problem reading disk in BasicMBRData::ReadMBRData()!\n";
   } else {
      for (i = 0; i < 440; i++)
         code[i] = tempMBR.code[i];
      diskSignature = tempMBR.diskSignature;
      nulls = tempMBR.nulls;
      for (i = 0; i < 4; i++) {
         partitions[i] = tempMBR.partitions[i];
         if (partitions[i].GetLengthLBA() > 0)
            partitions[i].SetInclusion(PRIMARY);
      } // for i... (reading all four partitions)
      MBRSignature = tempMBR.MBRSignature;
      ReadCHSGeom();

      // Reverse the byte order, if necessary
      if (IsLittleEndian() == 0) {
         ReverseBytes(&diskSignature, 4);
         ReverseBytes(&nulls, 2);
         ReverseBytes(&MBRSignature, 2);
         for (i = 0; i < 4; i++) {
            partitions[i].ReverseByteOrder();
         } // for
      } // if

      if (MBRSignature != MBR_SIGNATURE) {
         allOK = 0;
         state = invalid;
      } // if

      // Find disk size
      diskSize = myDisk->DiskSize(&err);

      // Find block size
      if (checkBlockSize) {
         blockSize = myDisk->GetBlockSize();
      } // if (checkBlockSize)

      // Load logical partition data, if any is found....
      if (allOK) {
         for (i = 0; i < 4; i++) {
            if ((partitions[i].GetType() == 0x05) || (partitions[i].GetType() == 0x0f)
                || (partitions[i].GetType() == 0x85)) {
               // Found it, so call a recursive algorithm to load everything from them....
               logicalNum = ReadLogicalPart(partitions[i].GetStartLBA(), UINT32_C(0), 4);
               if ((logicalNum < 0) || (logicalNum >= MAX_MBR_PARTS)) {
                  allOK = 0;
                  cerr << "Error reading logical partitions! List may be truncated!\n";
               } // if maxLogicals valid
               DeletePartition(i);
            } // if primary partition is extended
         } // for primary partition loop
         if (allOK) { // Loaded logicals OK
            state = mbr;
         } else {
            state = invalid;
         } // if
      } // if

      // Check to see if it's in GPT format....
      if (allOK) {
         for (i = 0; i < 4; i++) {
            if (partitions[i].GetType() == UINT8_C(0xEE)) {
               state = gpt;
            } // if
         } // for
      } // if

      // If there's an EFI GPT partition, look for other partition types,
      // to flag as hybrid
      if (state == gpt) {
         for (i = 0 ; i < 4; i++) {
            if ((partitions[i].GetType() != UINT8_C(0xEE)) &&
                (partitions[i].GetType() != UINT8_C(0x00)))
               state = hybrid;
            if (logicalNum > 0)
               cerr << "Warning! MBR Logical partitions found on a hybrid MBR disk! This is an\n"
                    << "EXTREMELY dangerous configuration!\n\a";
         } // for
      } // if (hybrid detection code)
   } // no initial error
   return allOK;
} // BasicMBRData::ReadMBRData(DiskIO * theDisk, int checkBlockSize)

// This is a recursive function to read all the logical partitions, following the
// logical partition linked list from the disk and storing the basic data in the
// partitions[] array. Returns last index to partitions[] used, or -1 if there was
// a problem.
// Parameters:
// extendedStart = LBA of the start of the extended partition
// diskOffset = LBA offset WITHIN the extended partition of the one to be read
// partNum = location in partitions[] array to store retrieved data
int BasicMBRData::ReadLogicalPart(uint64_t extendedStart, uint64_t diskOffset, int partNum) {
   struct TempMBR ebr;
   uint8_t ebrType;
   uint64_t offset;

   // Check for a valid partition number. Note that partitions MAY be read into
   // the area normally used by primary partitions, although the only calling
   // functions as of GPT fdisk version 0.7.0 don't do so.
   if ((partNum < MAX_MBR_PARTS) && (partNum >= 0)) {
      offset = (uint64_t) (extendedStart + diskOffset);
      if (myDisk->Seek(offset) == 0) { // seek to EBR record
         cerr << "Unable to seek to " << offset << "! Aborting!\n";
         partNum = -1;
      }
      if (myDisk->Read(&ebr, 512) != 512) { // Load the data....
         cerr << "Error seeking to or reading logical partition data from " << offset
              << "!\nAborting!\n";
         partNum = -1;
      } else if (IsLittleEndian() != 1) { // Reverse byte ordering of some data....
         ReverseBytes(&ebr.MBRSignature, 2);
         ReverseBytes(&ebr.partitions[0].firstLBA, 4);
         ReverseBytes(&ebr.partitions[0].lengthLBA, 4);
         ReverseBytes(&ebr.partitions[1].firstLBA, 4);
         ReverseBytes(&ebr.partitions[1].lengthLBA, 4);
      } // if/else/if

      if (ebr.MBRSignature != MBR_SIGNATURE) {
         partNum = -1;
         cerr << "MBR signature in logical partition invalid; read 0x";
         cerr.fill('0');
         cerr.width(4);
         cerr.setf(ios::uppercase);
         cerr << hex << ebr.MBRSignature << ", but should be 0x";
         cerr.width(4);
         cerr << MBR_SIGNATURE << dec << "\n";
         cerr.fill(' ');
      } // if

      // Sometimes an EBR points directly to another EBR, rather than defining
      // a logical partition and then pointing to another EBR. Thus, we recurse
      // directly if this is detected, else extract partition data and then
      // recurse on the second entry in the EBR...
      ebrType = ebr.partitions[0].partitionType;
      if ((ebrType == 0x05) || (ebrType == 0x0f) || (ebrType == 0x85)) {
         partNum = ReadLogicalPart(extendedStart, ebr.partitions[0].firstLBA, partNum);
      } else {
         // Copy over the basic data....
         partitions[partNum] = ebr.partitions[0];
         // Adjust the start LBA, since it's encoded strangely....
         partitions[partNum].SetStartLBA(ebr.partitions[0].firstLBA + diskOffset + extendedStart);
         partitions[partNum].SetInclusion(LOGICAL);

         // Find the next partition (if there is one) and recurse....
         if ((ebr.partitions[1].firstLBA != UINT32_C(0)) && (partNum >= 4) &&
            (partNum < (MAX_MBR_PARTS - 1))) {
            partNum = ReadLogicalPart(extendedStart, ebr.partitions[1].firstLBA,
                                      partNum + 1);
         } else {
            partNum++;
         } // if another partition
      } // if/else
   } // Not enough space for all the logicals (or previous error encountered)
   return (partNum);
} // BasicMBRData::ReadLogicalPart()

// Write the MBR data to the default defined device. This writes both the
// MBR itself and any defined logical partitions, provided there's an
// MBR extended partition.
int BasicMBRData::WriteMBRData(void) {
   int allOK = 1;

   if (myDisk != NULL) {
      if (myDisk->OpenForWrite() != 0) {
         allOK = WriteMBRData(myDisk);
         cout << "Done writing data!\n";
      } else {
         allOK = 0;
      } // if/else
      myDisk->Close();
   } else allOK = 0;
   return allOK;
} // BasicMBRData::WriteMBRData(void)

// Save the MBR data to a file. This writes both the
// MBR itself and any defined logical partitions.
int BasicMBRData::WriteMBRData(DiskIO *theDisk) {
   int i, j, partNum, next, allOK = 1, moreLogicals = 0;
   uint64_t extFirstLBA = 0;
   uint64_t writeEbrTo; // 64-bit because we support extended in 2-4TiB range
   TempMBR tempMBR;

   allOK = CreateExtended();
   if (allOK) {
      // First write the main MBR data structure....
      memcpy(tempMBR.code, code, 440);
      tempMBR.diskSignature = diskSignature;
      tempMBR.nulls = nulls;
      tempMBR.MBRSignature = MBRSignature;
      for (i = 0; i < 4; i++) {
         partitions[i].StoreInStruct(&tempMBR.partitions[i]);
         if (partitions[i].GetType() == 0x0f) {
            extFirstLBA = partitions[i].GetStartLBA();
            moreLogicals = 1;
         } // if
      } // for i...
   } // if
   allOK = allOK && WriteMBRData(tempMBR, theDisk, 0);

   // Set up tempMBR with some constant data for logical partitions...
   tempMBR.diskSignature = 0;
   for (i = 2; i < 4; i++) {
      tempMBR.partitions[i].firstLBA = tempMBR.partitions[i].lengthLBA = 0;
      tempMBR.partitions[i].partitionType = 0x00;
      for (j = 0; j < 3; j++) {
         tempMBR.partitions[i].firstSector[j] = 0;
         tempMBR.partitions[i].lastSector[j] = 0;
      } // for j
   } // for i

   partNum = FindNextInUse(4);
   writeEbrTo = (uint64_t) extFirstLBA;
   // Write logicals...
   while (allOK && moreLogicals && (partNum < MAX_MBR_PARTS)) {
      partitions[partNum].StoreInStruct(&tempMBR.partitions[0]);
      tempMBR.partitions[0].firstLBA = 1;
      // tempMBR.partitions[1] points to next EBR or terminates EBR linked list...
      next = FindNextInUse(partNum + 1);
      if ((next < MAX_MBR_PARTS) && (next > 0) && (partitions[next].GetStartLBA() > 0)) {
         tempMBR.partitions[1].partitionType = 0x0f;
         tempMBR.partitions[1].firstLBA = (uint32_t) (partitions[next].GetStartLBA() - extFirstLBA - 1);
         tempMBR.partitions[1].lengthLBA = (uint32_t) (partitions[next].GetLengthLBA() + 1);
         LBAtoCHS((uint64_t) tempMBR.partitions[1].firstLBA,
                  (uint8_t *) &tempMBR.partitions[1].firstSector);
         LBAtoCHS(tempMBR.partitions[1].lengthLBA - extFirstLBA,
                  (uint8_t *) &tempMBR.partitions[1].lastSector);
      } else {
         tempMBR.partitions[1].partitionType = 0x00;
         tempMBR.partitions[1].firstLBA = 0;
         tempMBR.partitions[1].lengthLBA = 0;
         moreLogicals = 0;
      } // if/else
      allOK = WriteMBRData(tempMBR, theDisk, writeEbrTo);
      writeEbrTo = (uint64_t) tempMBR.partitions[1].firstLBA + (uint64_t) extFirstLBA;
      partNum = next;
   } // while
   DeleteExtendedParts();
   return allOK;
} // BasicMBRData::WriteMBRData(DiskIO *theDisk)

int BasicMBRData::WriteMBRData(const string & deviceFilename) {
   device = deviceFilename;
   return WriteMBRData();
} // BasicMBRData::WriteMBRData(const string & deviceFilename)

// Write a single MBR record to the specified sector. Used by the like-named
// function to write both the MBR and multiple EBR (for logical partition)
// records.
// Returns 1 on success, 0 on failure
int BasicMBRData::WriteMBRData(struct TempMBR & mbr, DiskIO *theDisk, uint64_t sector) {
   int i, allOK;

   // Reverse the byte order, if necessary
   if (IsLittleEndian() == 0) {
      ReverseBytes(&mbr.diskSignature, 4);
      ReverseBytes(&mbr.nulls, 2);
      ReverseBytes(&mbr.MBRSignature, 2);
      for (i = 0; i < 4; i++) {
         ReverseBytes(&mbr.partitions[i].firstLBA, 4);
         ReverseBytes(&mbr.partitions[i].lengthLBA, 4);
      } // for
   } // if

   // Now write the data structure...
   allOK = theDisk->OpenForWrite();
   if (allOK && theDisk->Seek(sector)) {
      if (theDisk->Write(&mbr, 512) != 512) {
         allOK = 0;
         cerr << "Error " << errno << " when saving MBR!\n";
      } // if
   } else {
      allOK = 0;
      cerr << "Error " << errno << " when seeking to MBR to write it!\n";
   } // if/else
   theDisk->Close();

   // Reverse the byte order back, if necessary
   if (IsLittleEndian() == 0) {
      ReverseBytes(&mbr.diskSignature, 4);
      ReverseBytes(&mbr.nulls, 2);
      ReverseBytes(&mbr.MBRSignature, 2);
      for (i = 0; i < 4; i++) {
         ReverseBytes(&mbr.partitions[i].firstLBA, 4);
         ReverseBytes(&mbr.partitions[i].lengthLBA, 4);
      } // for
   }// if
   return allOK;
} // BasicMBRData::WriteMBRData(uint64_t sector)

// Set a new disk device; used in copying one disk's partition
// table to another disk.
void BasicMBRData::SetDisk(DiskIO *theDisk) {
   int err;

   myDisk = theDisk;
   diskSize = theDisk->DiskSize(&err);
   canDeleteMyDisk = 0;
   ReadCHSGeom();
} // BasicMBRData::SetDisk()

/********************************************
 *                                          *
 * Functions that display data for the user *
 *                                          *
 ********************************************/

// Show the MBR data to the user, up to the specified maximum number
// of partitions....
void BasicMBRData::DisplayMBRData(void) {
   int i;

   cout << "\nDisk size is " << diskSize << " sectors ("
        << BytesToIeee(diskSize, blockSize) << ")\n";
   cout << "MBR disk identifier: 0x";
   cout.width(8);
   cout.fill('0');
   cout.setf(ios::uppercase);
   cout << hex << diskSignature << dec << "\n";
   cout << "MBR partitions:\n\n";
   if ((state == gpt) || (state == hybrid)) {
      cout << "Number  Boot  Start Sector   End Sector   Status      Code\n";
   } else {
      cout << "                                                   Can Be   Can Be\n";
      cout << "Number  Boot  Start Sector   End Sector   Status   Logical  Primary   Code\n";
      UpdateCanBeLogical();
   } // 
   for (i = 0; i < MAX_MBR_PARTS; i++) {
      if (partitions[i].GetLengthLBA() != 0) {
         cout.fill(' ');
         cout.width(4);
         cout << i + 1 << "      ";
         partitions[i].ShowData((state == gpt) || (state == hybrid));
      } // if
      cout.fill(' ');
   } // for
} // BasicMBRData::DisplayMBRData()

// Displays the state, as a word, on stdout. Used for debugging & to
// tell the user about the MBR state when the program launches....
void BasicMBRData::ShowState(void) {
   switch (state) {
      case invalid:
         cout << "  MBR: not present\n";
         break;
      case gpt:
         cout << "  MBR: protective\n";
         break;
      case hybrid:
         cout << "  MBR: hybrid\n";
         break;
      case mbr:
         cout << "  MBR: MBR only\n";
         break;
      default:
         cout << "\a  MBR: unknown -- bug!\n";
         break;
   } // switch
} // BasicMBRData::ShowState()

/************************
 *                      *
 * GPT Checks and fixes *
 *                      *
 ************************/

// Perform a very rudimentary check for GPT data on the disk; searches for
// the GPT signature in the main and backup metadata areas.
// Returns 0 if GPT data not found, 1 if main data only is found, 2 if
// backup only is found, 3 if both main and backup data are found, and
// -1 if a disk error occurred.
int BasicMBRData::CheckForGPT(void) {
   int retval = 0, err;
   char signature1[9], signature2[9];

   if (myDisk != NULL) {
      if (myDisk->OpenForRead() != 0) {
         if (myDisk->Seek(1)) {
            myDisk->Read(signature1, 8);
            signature1[8] = '\0';
         } else retval = -1;
         if (myDisk->Seek(myDisk->DiskSize(&err) - 1)) {
            myDisk->Read(signature2, 8);
            signature2[8] = '\0';
         } else retval = -1;
         if ((retval >= 0) && (strcmp(signature1, "EFI PART") == 0))
            retval += 1;
         if ((retval >= 0) && (strcmp(signature2, "EFI PART") == 0))
            retval += 2;
      } else {
         retval = -1;
      } // if/else
      myDisk->Close();
   } else retval = -1;
   return retval;
} // BasicMBRData::CheckForGPT()

// Blanks the 2nd (sector #1, numbered from 0) and last sectors of the disk,
// but only if GPT data are verified on the disk, and only for the sector(s)
// with GPT signatures.
// Returns 1 if operation completes successfully, 0 if not (returns 1 if
// no GPT data are found on the disk).
int BasicMBRData::BlankGPTData(void) {
   int allOK = 1, err;
   uint8_t blank[512];

   memset(blank, 0, 512);
   switch (CheckForGPT()) {
      case -1:
         allOK = 0;
         break;
      case 0:
         break;
      case 1:
         if ((myDisk != NULL) && (myDisk->OpenForWrite())) {
            if (!((myDisk->Seek(1)) && (myDisk->Write(blank, 512) == 512)))
               allOK = 0;
            myDisk->Close();
         } else allOK = 0;
         break;
      case 2:
         if ((myDisk != NULL) && (myDisk->OpenForWrite())) {
            if (!((myDisk->Seek(myDisk->DiskSize(&err) - 1)) &&
               (myDisk->Write(blank, 512) == 512)))
               allOK = 0;
            myDisk->Close();
         } else allOK = 0;
         break;
      case 3:
         if ((myDisk != NULL) && (myDisk->OpenForWrite())) {
            if (!((myDisk->Seek(1)) && (myDisk->Write(blank, 512) == 512)))
               allOK = 0;
            if (!((myDisk->Seek(myDisk->DiskSize(&err) - 1)) &&
                (myDisk->Write(blank, 512) == 512)))
                allOK = 0;
            myDisk->Close();
         } else allOK = 0;
         break;
      default:
         break;
   } // switch()
   return allOK;
} // BasicMBRData::BlankGPTData

/*********************************************************************
 *                                                                   *
 * Functions that set or get disk metadata (CHS geometry, disk size, *
 * etc.)                                                             *
 *                                                                   *
 *********************************************************************/

// Read the CHS geometry using OS calls, or if that fails, set to
// the most common value for big disks (255 heads, 63 sectors per
// track, & however many cylinders that computes to).
void BasicMBRData::ReadCHSGeom(void) {
   numHeads = myDisk->GetNumHeads();
   numSecspTrack = myDisk->GetNumSecsPerTrack();
   partitions[0].SetGeometry(numHeads, numSecspTrack, diskSize, blockSize);
} // BasicMBRData::ReadCHSGeom()

// 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 BasicMBRData::GetPartRange(uint32_t *low, uint32_t *high) {
   uint32_t i;
   int numFound = 0;

   *low = MAX_MBR_PARTS + 1; // code for "not found"
   *high = 0;
   for (i = 0; i < MAX_MBR_PARTS; i++) {
      if (partitions[i].GetStartLBA() != UINT32_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 == (MAX_MBR_PARTS + 1))
            *low = i;
         numFound++;
      } // if
   } // for

   // 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 == (MAX_MBR_PARTS + 1))
      *low = 0;
   return numFound;
} // GPTData::GetPartRange()

// Converts 64-bit LBA value to MBR-style CHS value. Returns 1 if conversion
// was within the range that can be expressed by CHS (including 0, for an
// empty partition), 0 if the value is outside that range, and -1 if chs is
// invalid.
int BasicMBRData::LBAtoCHS(uint64_t lba, uint8_t * chs) {
   uint64_t cylinder, head, sector; // all numbered from 0
   uint64_t remainder;
   int retval = 1;
   int done = 0;

   if (chs != NULL) {
      // Special case: In case of 0 LBA value, zero out CHS values....
      if (lba == 0) {
         chs[0] = chs[1] = chs[2] = UINT8_C(0);
         done = 1;
      } // if
      // If LBA value is too large for CHS, max out CHS values....
      if ((!done) && (lba >= (numHeads * numSecspTrack * MAX_CYLINDERS))) {
         chs[0] = 254;
         chs[1] = chs[2] = 255;
         done = 1;
         retval = 0;
      } // if
      // If neither of the above applies, compute CHS values....
      if (!done) {
         cylinder = lba / (uint64_t) (numHeads * numSecspTrack);
         remainder = lba - (cylinder * numHeads * numSecspTrack);
         head = remainder / numSecspTrack;
         remainder -= head * numSecspTrack;
         sector = remainder;
         if (head < numHeads)
            chs[0] = (uint8_t) head;
         else
            retval = 0;
         if (sector < numSecspTrack) {
            chs[1] = (uint8_t) ((sector + 1) + (cylinder >> 8) * 64);
            chs[2] = (uint8_t) (cylinder & UINT64_C(0xFF));
         } else {
            retval = 0;
         } // if/else
      } // if value is expressible and non-0
   } else { // Invalid (NULL) chs pointer
      retval = -1;
   } // if CHS pointer valid
   return (retval);
} // BasicMBRData::LBAtoCHS()

// Look for overlapping partitions.
// Returns the number of problems found
int BasicMBRData::FindOverlaps(void) {
   int i, j, numProbs = 0, numEE = 0;

   for (i = 0; i < MAX_MBR_PARTS; i++) {
      for (j = i + 1; j < MAX_MBR_PARTS; j++) {
         if ((partitions[i].GetInclusion() != NONE) &&
             (partitions[i].DoTheyOverlap(partitions[j]))) {
            numProbs++;
            cout << "\nProblem: MBR partitions " << i + 1 << " and " << j + 1
                 << " overlap!\n";
         } // if
      } // for (j...)
      if (partitions[i].GetType() == 0xEE) {
         numEE++;
         if (partitions[i].GetStartLBA() != 1)
            cout << "\nWarning: 0xEE partition doesn't start on sector 1. This can cause "
                 << "problems\nin some OSes.\n";
      } // if
   } // for (i...)
   if (numEE > 1)
      cout << "\nCaution: More than one 0xEE MBR partition found. This can cause problems\n"
           << "in some OSes.\n";

   return numProbs;
} // BasicMBRData::FindOverlaps()

// Returns the number of primary partitions, including the extended partition
// required to hold any logical partitions found.
int BasicMBRData::NumPrimaries(void) {
   int i, numPrimaries = 0, logicalsFound = 0;

   for (i = 0; i < MAX_MBR_PARTS; i++) {
      if (partitions[i].GetLengthLBA() > 0) {
         if (partitions[i].GetInclusion() == PRIMARY)
            numPrimaries++;
         if (partitions[i].GetInclusion() == LOGICAL)
            logicalsFound = 1;
      } // if
   } // for
   return (numPrimaries + logicalsFound);
} // BasicMBRData::NumPrimaries()

// Returns the number of logical partitions.
int BasicMBRData::NumLogicals(void) {
   int i, numLogicals = 0;

   for (i = 0; i < MAX_MBR_PARTS; i++) {
      if (partitions[i].GetInclusion() == LOGICAL)
         numLogicals++;
   } // for
   return numLogicals;
} // BasicMBRData::NumLogicals()

// Returns the number of partitions (primaries plus logicals), NOT including
// the extended partition required to house the logicals.
int BasicMBRData::CountParts(void) {
   int i, num = 0;

   for (i = 0; i < MAX_MBR_PARTS; i++) {
      if ((partitions[i].GetInclusion() == LOGICAL) ||
          (partitions[i].GetInclusion() == PRIMARY))
         num++;
   } // for
   return num;
} // BasicMBRData::CountParts()

// Updates the canBeLogical and canBePrimary flags for all the partitions.
void BasicMBRData::UpdateCanBeLogical(void) {
   int i, j, sectorBefore, numPrimaries, numLogicals, usedAsEBR;
   uint64_t firstLogical, lastLogical, lStart, pStart;

   numPrimaries = NumPrimaries();
   numLogicals = NumLogicals();
   firstLogical = FirstLogicalLBA() - 1;
   lastLogical = LastLogicalLBA();
   for (i = 0; i < MAX_MBR_PARTS; i++) {
      usedAsEBR = (SectorUsedAs(partitions[i].GetLastLBA()) == EBR);
      if (usedAsEBR) {
         partitions[i].SetCanBeLogical(0);
         partitions[i].SetCanBePrimary(0);
      } else if (partitions[i].GetLengthLBA() > 0) {
         // First determine if it can be logical....
         sectorBefore = SectorUsedAs(partitions[i].GetStartLBA() - 1);
         lStart = partitions[i].GetStartLBA(); // start of potential logical part.
         if ((lastLogical > 0) &&
             ((sectorBefore == EBR) || (sectorBefore == NONE))) {
            // Assume it can be logical, then search for primaries that make it
            // not work and, if found, flag appropriately.
            partitions[i].SetCanBeLogical(1);
            for (j = 0; j < MAX_MBR_PARTS; j++) {
               if ((i != j) && (partitions[j].GetInclusion() == PRIMARY)) {
                  pStart = partitions[j].GetStartLBA();
                  if (((pStart < lStart) && (firstLogical < pStart)) ||
                      ((pStart > lStart) && (firstLogical > pStart))) {
                     partitions[i].SetCanBeLogical(0);
                  } // if/else
               } // if
            } // for
         } else {
            if ((sectorBefore != EBR) && (sectorBefore != NONE))
               partitions[i].SetCanBeLogical(0);
            else
               partitions[i].SetCanBeLogical(lastLogical == 0); // can be logical only if no logicals already
         } // if/else
         // Now determine if it can be primary. Start by assuming it can be...
         partitions[i].SetCanBePrimary(1);
         if ((numPrimaries >= 4) && (partitions[i].GetInclusion() != PRIMARY)) {
            partitions[i].SetCanBePrimary(0);
            if ((partitions[i].GetInclusion() == LOGICAL) && (numLogicals == 1) &&
                (numPrimaries == 4))
               partitions[i].SetCanBePrimary(1);
         } // if
         if ((partitions[i].GetStartLBA() > (firstLogical + 1)) &&
             (partitions[i].GetLastLBA() < lastLogical))
            partitions[i].SetCanBePrimary(0);
      } // else if
   } // for
} // BasicMBRData::UpdateCanBeLogical()

// Returns the first sector occupied by any logical partition. Note that
// this does NOT include the logical partition's EBR! Returns UINT32_MAX
// if there are no logical partitions defined.
uint64_t BasicMBRData::FirstLogicalLBA(void) {
   int i;
   uint64_t firstFound = UINT32_MAX;

   for (i = 0; i < MAX_MBR_PARTS; i++) {
      if ((partitions[i].GetInclusion() == LOGICAL) &&
          (partitions[i].GetStartLBA() < firstFound)) {
         firstFound = partitions[i].GetStartLBA();
      } // if
   } // for
   return firstFound;
} // BasicMBRData::FirstLogicalLBA()

// Returns the last sector occupied by any logical partition, or 0 if
// there are no logical partitions defined.
uint64_t BasicMBRData::LastLogicalLBA(void) {
   int i;
   uint64_t lastFound = 0;

   for (i = 0; i < MAX_MBR_PARTS; i++) {
      if ((partitions[i].GetInclusion() == LOGICAL) &&
          (partitions[i].GetLastLBA() > lastFound))
         lastFound = partitions[i].GetLastLBA();
   } // for
   return lastFound;
} // BasicMBRData::LastLogicalLBA()

// Returns 1 if logical partitions are contiguous (have no primaries
// in their midst), or 0 if one or more primaries exist between
// logicals.
int BasicMBRData::AreLogicalsContiguous(void) {
   int allOK = 1, i = 0;
   uint64_t firstLogical, lastLogical;

   firstLogical = FirstLogicalLBA() - 1; // subtract 1 for EBR
   lastLogical = LastLogicalLBA();
   if (lastLogical > 0) {
      do {
         if ((partitions[i].GetInclusion() == PRIMARY) &&
             (partitions[i].GetStartLBA() >= firstLogical) &&
             (partitions[i].GetStartLBA() <= lastLogical)) {
            allOK = 0;
         } // if
         i++;
      } while ((i < MAX_MBR_PARTS) && allOK);
   } // if
   return allOK;
} // BasicMBRData::AreLogicalsContiguous()

// Returns 1 if all partitions fit on the disk, given its size; 0 if any
// partition is too big.
int BasicMBRData::DoTheyFit(void) {
   int i, allOK = 1;

   for (i = 0; i < MAX_MBR_PARTS; i++) {
      if ((partitions[i].GetStartLBA() > diskSize) || (partitions[i].GetLastLBA() > diskSize)) {
         allOK = 0;
      } // if
   } // for
   return allOK;
} // BasicMBRData::DoTheyFit(void)

// Returns 1 if there's at least one free sector immediately preceding
// all partitions flagged as logical; 0 if any logical partition lacks
// this space.
int BasicMBRData::SpaceBeforeAllLogicals(void) {
   int i = 0, allOK = 1;

   do {
      if ((partitions[i].GetStartLBA() > 0) && (partitions[i].GetInclusion() == LOGICAL)) {
         allOK = allOK && (SectorUsedAs(partitions[i].GetStartLBA() - 1) == EBR);
      } // if
      i++;
   } while (allOK && (i < MAX_MBR_PARTS));
   return allOK;
} // BasicMBRData::SpaceBeforeAllLogicals()

// Returns 1 if the partitions describe a legal layout -- all logicals
// are contiguous and have at least one preceding empty partitions,
// the number of primaries is under 4 (or under 3 if there are any
// logicals), there are no overlapping partitions, etc.
// Does NOT assume that primaries are numbered 1-4; uses the
// IsItPrimary() function of the MBRPart class to determine
// primary status. Also does NOT consider partition order; there
// can be gaps and it will still be considered legal.
int BasicMBRData::IsLegal(void) {
   int allOK = 1;

   allOK = (FindOverlaps() == 0);
   allOK = (allOK && (NumPrimaries() <= 4));
   allOK = (allOK && AreLogicalsContiguous());
   allOK = (allOK && DoTheyFit());
   allOK = (allOK && SpaceBeforeAllLogicals());
   return allOK;
} // BasicMBRData::IsLegal()

// Finds the next in-use partition, starting with start (will return start
// if it's in use). Returns -1 if no subsequent partition is in use.
int BasicMBRData::FindNextInUse(int start) {
   if (start >= MAX_MBR_PARTS)
      start = -1;
   while ((start < MAX_MBR_PARTS) && (start >= 0) && (partitions[start].GetInclusion() == NONE))
      start++;
   if ((start < 0) || (start >= MAX_MBR_PARTS))
      start = -1;
   return start;
} // BasicMBRData::FindFirstLogical();

/*****************************************************
 *                                                   *
 * Functions to create, delete, or change partitions *
 *                                                   *
 *****************************************************/

// Empty all data. Meant mainly for calling by constructors, but it's also
// used by the hybrid MBR functions in the GPTData class.
void BasicMBRData::EmptyMBR(int clearBootloader) {
   int i;

   // Zero out the boot loader section, the disk signature, and the
   // 2-byte nulls area only if requested to do so. (This is the
   // default.)
   if (clearBootloader == 1) {
      EmptyBootloader();
   } // if

   // Blank out the partitions
   for (i = 0; i < MAX_MBR_PARTS; i++) {
      partitions[i].Empty();
   } // for
   MBRSignature = MBR_SIGNATURE;
   state = mbr;
} // BasicMBRData::EmptyMBR()

// Blank out the boot loader area. Done with the initial MBR-to-GPT
// conversion, since MBR boot loaders don't understand GPT, and so
// need to be replaced....
void BasicMBRData::EmptyBootloader(void) {
   int i;

   for (i = 0; i < 440; i++)
      code[i] = 0;
   nulls = 0;
} // BasicMBRData::EmptyBootloader

// Create a partition of the specified number based on the passed
// partition. This function does *NO* error checking, so it's possible
// to seriously screw up a partition table using this function!
// Note: This function should NOT be used to create the 0xEE partition
// in a conventional GPT configuration, since that partition has
// specific size requirements that this function won't handle. It may
// be used for creating the 0xEE partition(s) in a hybrid MBR, though,
// since those toss the rulebook away anyhow....
void BasicMBRData::AddPart(int num, const MBRPart& newPart) {
   partitions[num] = newPart;
} // BasicMBRData::AddPart()

// Create a partition of the specified number, starting LBA, and
// length. This function does almost no error checking, so it's possible
// to seriously screw up a partition table using this function!
// Note: This function should NOT be used to create the 0xEE partition
// in a conventional GPT configuration, since that partition has
// specific size requirements that this function won't handle. It may
// be used for creating the 0xEE partition(s) in a hybrid MBR, though,
// since those toss the rulebook away anyhow....
void BasicMBRData::MakePart(int num, uint64_t start, uint64_t length, int type, int bootable) {
   if ((num >= 0) && (num < MAX_MBR_PARTS) && (start <= UINT32_MAX) && (length <= UINT32_MAX)) {
      partitions[num].Empty();
      partitions[num].SetType(type);
      partitions[num].SetLocation(start, length);
      if (num < 4)
         partitions[num].SetInclusion(PRIMARY);
      else
         partitions[num].SetInclusion(LOGICAL);
      SetPartBootable(num, bootable);
   } // if valid partition number & size
} // BasicMBRData::MakePart()

// Set the partition's type code.
// Returns 1 if successful, 0 if not (invalid partition number)
int BasicMBRData::SetPartType(int num, int type) {
   int allOK = 1;

   if ((num >= 0) && (num < MAX_MBR_PARTS)) {
      if (partitions[num].GetLengthLBA() != UINT32_C(0)) {
         allOK = partitions[num].SetType(type);
      } else allOK = 0;
   } else allOK = 0;
   return allOK;
} // BasicMBRData::SetPartType()

// Set (or remove) the partition's bootable flag. Setting it is the
// default; pass 0 as bootable to remove the flag.
// Returns 1 if successful, 0 if not (invalid partition number)
int BasicMBRData::SetPartBootable(int num, int bootable) {
   int allOK = 1;

   if ((num >= 0) && (num < MAX_MBR_PARTS)) {
      if (partitions[num].GetLengthLBA() != UINT32_C(0)) {
         if (bootable == 0)
            partitions[num].SetStatus(UINT8_C(0x00));
         else
            partitions[num].SetStatus(UINT8_C(0x80));
      } else allOK = 0;
   } else allOK = 0;
   return allOK;
} // BasicMBRData::SetPartBootable()

// Create a partition that fills the most available space. Returns
// 1 if partition was created, 0 otherwise. Intended for use in
// creating hybrid MBRs.
int BasicMBRData::MakeBiggestPart(int i, int type) {
   uint64_t start = UINT64_C(1); // starting point for each search
   uint64_t firstBlock; // first block in a segment
   uint64_t lastBlock; // last block in a segment
   uint64_t segmentSize; // size of segment in blocks
   uint64_t selectedSegment = UINT64_C(0); // location of largest segment
   uint64_t selectedSize = UINT64_C(0); // size of largest segment in blocks
   int found = 0;

   do {
      firstBlock = FindFirstAvailable(start);
      if (firstBlock > UINT64_C(0)) { // something's free...
         lastBlock = FindLastInFree(firstBlock);
         segmentSize = lastBlock - firstBlock + UINT64_C(1);
         if (segmentSize > selectedSize) {
            selectedSize = segmentSize;
            selectedSegment = firstBlock;
         } // if
         start = lastBlock + 1;
      } // if
   } while (firstBlock != 0);
   if ((selectedSize > UINT64_C(0)) && (selectedSize < diskSize)) {
      found = 1;
      MakePart(i, selectedSegment, selectedSize, type, 0);
   } else {
      found = 0;
   } // if/else
   return found;
} // BasicMBRData::MakeBiggestPart(int i)

// Delete partition #i
void BasicMBRData::DeletePartition(int i) {
   partitions[i].Empty();
} // BasicMBRData::DeletePartition()

// Set the inclusion status (PRIMARY, LOGICAL, or NONE) with some sanity
// checks to ensure the table remains legal.
// Returns 1 on success, 0 on failure.
int BasicMBRData::SetInclusionwChecks(int num, int inclStatus) {
   int allOK = 1, origValue;

   if (IsLegal()) {
      if ((inclStatus == PRIMARY) || (inclStatus == LOGICAL) || (inclStatus == NONE)) {
         origValue = partitions[num].GetInclusion();
         partitions[num].SetInclusion(inclStatus);
         if (!IsLegal()) {
            partitions[num].SetInclusion(origValue);
            cerr << "Specified change is not legal! Aborting change!\n";
         } // if
      } else {
         cerr << "Invalid partition inclusion code in BasicMBRData::SetInclusionwChecks()!\n";
      } // if/else
   } else {
      cerr << "Partition table is not currently in a valid state. Aborting change!\n";
      allOK = 0;
   } // if/else
   return allOK;
} // BasicMBRData::SetInclusionwChecks()

// Recomputes the CHS values for the specified partition and adjusts the value.
// Note that this will create a technically incorrect CHS value for EFI GPT (0xEE)
// protective partitions, but this is required by some buggy BIOSes, so I'm
// providing a function to do this deliberately at the user's command.
// This function does nothing if the partition's length is 0.
void BasicMBRData::RecomputeCHS(int partNum) {
   partitions[partNum].RecomputeCHS();
} // BasicMBRData::RecomputeCHS()

// Sorts the partitions starting with partition #start. This function
// does NOT pay attention to primary/logical assignment, which is
// critical when writing the partitions.
void BasicMBRData::SortMBR(int start) {
   if ((start < MAX_MBR_PARTS) && (start >= 0))
      sort(partitions + start, partitions + MAX_MBR_PARTS);
} // BasicMBRData::SortMBR()

// Delete any partitions that are too big to fit on the disk
// or that are too big for MBR (32-bit limits).
// This deletes the partitions by setting values to 0, not just
// by setting them as being omitted.
// Returns the number of partitions deleted in this way.
int BasicMBRData::DeleteOversizedParts() {
   int num = 0, i;

   for (i = 0; i < MAX_MBR_PARTS; i++) {
      if ((partitions[i].GetStartLBA() > diskSize) || (partitions[i].GetLastLBA() > diskSize) ||
          (partitions[i].GetStartLBA() > UINT32_MAX) || (partitions[i].GetLengthLBA() > UINT32_MAX)) {
         cerr << "\aWarning: Deleting oversized partition #" << i + 1 << "! Start = "
              << partitions[i].GetStartLBA() << ", length = " << partitions[i].GetLengthLBA() << "\n";
         partitions[i].Empty();
         num++;
      } // if
   } // for
   return num;
} // BasicMBRData::DeleteOversizedParts()

// Search for and delete extended partitions.
// Returns the number of partitions deleted.
int BasicMBRData::DeleteExtendedParts() {
   int i, numDeleted = 0;
   uint8_t type;

   for (i = 0; i < MAX_MBR_PARTS; i++) {
      type = partitions[i].GetType();
      if (((type == 0x05) || (type == 0x0f) || (type == (0x85))) &&
          (partitions[i].GetLengthLBA() > 0)) {
         partitions[i].Empty();
         numDeleted++;
      } // if
   } // for
   return numDeleted;
} // BasicMBRData::DeleteExtendedParts()

// Finds any overlapping partitions and omits the smaller of the two.
void BasicMBRData::OmitOverlaps() {
   int i, j;

   for (i = 0; i < MAX_MBR_PARTS; i++) {
      for (j = i + 1; j < MAX_MBR_PARTS; j++) {
         if ((partitions[i].GetInclusion() != NONE) &&
             partitions[i].DoTheyOverlap(partitions[j])) {
            if (partitions[i].GetLengthLBA() < partitions[j].GetLengthLBA())
               partitions[i].SetInclusion(NONE);
            else
               partitions[j].SetInclusion(NONE);
         } // if
      } // for (j...)
   } // for (i...)
} // BasicMBRData::OmitOverlaps()

// Convert as many partitions into logicals as possible, except for
// the first partition, if possible.
void BasicMBRData::MaximizeLogicals() {
   int earliestPart = 0, earliestPartWas = NONE, i;

   for (i = MAX_MBR_PARTS - 1; i >= 0; i--) {
      UpdateCanBeLogical();
      earliestPart = i;
      if (partitions[i].CanBeLogical()) {
         partitions[i].SetInclusion(LOGICAL);
      } else if (partitions[i].CanBePrimary()) {
         partitions[i].SetInclusion(PRIMARY);
      } else {
         partitions[i].SetInclusion(NONE);
      } // if/elseif/else
   } // for
   // If we have spare primaries, convert back the earliest partition to
   // its original state....
   if ((NumPrimaries() < 4) && (partitions[earliestPart].GetInclusion() == LOGICAL))
      partitions[earliestPart].SetInclusion(earliestPartWas);
} // BasicMBRData::MaximizeLogicals()

// Add primaries up to the maximum allowed, from the omitted category.
void BasicMBRData::MaximizePrimaries() {
   int num, i = 0;

   num = NumPrimaries();
   while ((num < 4) && (i < MAX_MBR_PARTS)) {
      if ((partitions[i].GetInclusion() == NONE) && (partitions[i].CanBePrimary())) {
         partitions[i].SetInclusion(PRIMARY);
         num++;
         UpdateCanBeLogical();
      } // if
      i++;
   } // while
} // BasicMBRData::MaximizePrimaries()

// Remove primary partitions in excess of 4, starting with the later ones,
// in terms of the array location....
void BasicMBRData::TrimPrimaries(void) {
   int numToDelete, i = MAX_MBR_PARTS;

   numToDelete = NumPrimaries() - 4;
   while ((numToDelete > 0) && (i >= 0)) {
      if (partitions[i].GetInclusion() == PRIMARY) {
         partitions[i].SetInclusion(NONE);
         numToDelete--;
      } // if
      i--;
   } // while (numToDelete > 0)
} // BasicMBRData::TrimPrimaries()

// Locates primary partitions located between logical partitions and
// either converts the primaries into logicals (if possible) or omits
// them.
void BasicMBRData::MakeLogicalsContiguous(void) {
   uint64_t firstLogicalLBA, lastLogicalLBA;
   int i;

   firstLogicalLBA = FirstLogicalLBA();
   lastLogicalLBA = LastLogicalLBA();
   for (i = 0; i < MAX_MBR_PARTS; i++) {
      if ((partitions[i].GetInclusion() == PRIMARY) &&
          (partitions[i].GetStartLBA() >= firstLogicalLBA) &&
          (partitions[i].GetLastLBA() <= lastLogicalLBA)) {
         if (SectorUsedAs(partitions[i].GetStartLBA() - 1) == NONE)
            partitions[i].SetInclusion(LOGICAL);
         else
            partitions[i].SetInclusion(NONE);
      } // if
   } // for
} // BasicMBRData::MakeLogicalsContiguous()

// If MBR data aren't legal, adjust primary/logical assignments and,
// if necessary, drop partitions, to make the data legal.
void BasicMBRData::MakeItLegal(void) {
   if (!IsLegal()) {
      DeleteOversizedParts();
      MaximizeLogicals();
      MaximizePrimaries();
      if (!AreLogicalsContiguous())
         MakeLogicalsContiguous();
      if (NumPrimaries() > 4)
         TrimPrimaries();
      OmitOverlaps();
   } // if
} // BasicMBRData::MakeItLegal()

// Removes logical partitions and deactivated partitions from first four
// entries (primary space).
// Returns the number of partitions moved.
int BasicMBRData::RemoveLogicalsFromFirstFour(void) {
   int i, j = 4, numMoved = 0, swapped = 0;
   MBRPart temp;

   for (i = 0; i < 4; i++) {
      if ((partitions[i].GetInclusion() != PRIMARY) && (partitions[i].GetLengthLBA() > 0)) {
         j = 4;
         swapped = 0;
         do {
            if ((partitions[j].GetInclusion() == NONE) && (partitions[j].GetLengthLBA() == 0)) {
               temp = partitions[j];
               partitions[j] = partitions[i];
               partitions[i] = temp;
               swapped = 1;
               numMoved++;
            } // if
            j++;
         } while ((j < MAX_MBR_PARTS) && !swapped);
         if (j >= MAX_MBR_PARTS)
            cerr << "Warning! Too many partitions in BasicMBRData::RemoveLogicalsFromFirstFour()!\n";
      } // if
   } // for i...
   return numMoved;
} // BasicMBRData::RemoveLogicalsFromFirstFour()

// Move all primaries into the first four partition spaces
// Returns the number of partitions moved.
int BasicMBRData::MovePrimariesToFirstFour(void) {
   int i, j = 0, numMoved = 0, swapped = 0;
   MBRPart temp;

   for (i = 4; i < MAX_MBR_PARTS; i++) {
      if (partitions[i].GetInclusion() == PRIMARY) {
         j = 0;
         swapped = 0;
         do {
            if (partitions[j].GetInclusion() != PRIMARY) {
               temp = partitions[j];
               partitions[j] = partitions[i];
               partitions[i] = temp;
               swapped = 1;
               numMoved++;
            } // if
            j++;
         } while ((j < 4) && !swapped);
      } // if
   } // for
   return numMoved;
} // BasicMBRData::MovePrimariesToFirstFour()

// Create an extended partition, if necessary, to hold the logical partitions.
// This function also sorts the primaries into the first four positions of
// the table.
// Returns 1 on success, 0 on failure.
int BasicMBRData::CreateExtended(void) {
   int allOK = 1, i = 0, swapped = 0;
   MBRPart temp;

   if (IsLegal()) {
      // Move logicals out of primary space...
      RemoveLogicalsFromFirstFour();
      // Move primaries out of logical space...
      MovePrimariesToFirstFour();

      // Create the extended partition
      if (NumLogicals() > 0) {
         SortMBR(4); // sort starting from 4 -- that is, logicals only
         temp.Empty();
         temp.SetStartLBA(FirstLogicalLBA() - 1);
         temp.SetLengthLBA(LastLogicalLBA() - FirstLogicalLBA() + 2);
         temp.SetType(0x0f, 1);
         temp.SetInclusion(PRIMARY);
         do {
            if ((partitions[i].GetInclusion() == NONE) || (partitions[i].GetLengthLBA() == 0)) {
               partitions[i] = temp;
               swapped = 1;
            } // if
            i++;
         } while ((i < 4) && !swapped);
         if (!swapped) {
            cerr << "Could not create extended partition; no room in primary table!\n";
            allOK = 0;
         } // if
      } // if (NumLogicals() > 0)
   } else allOK = 0;
   // Do a final check for EFI GPT (0xEE) partitions & flag as a problem if found
   // along with an extended partition
   for (i = 0; i < MAX_MBR_PARTS; i++)
      if (swapped && partitions[i].GetType() == 0xEE)
         allOK = 0;
   return allOK;
} // BasicMBRData::CreateExtended()

/****************************************
 *                                      *
 * Functions to find data on free space *
 *                                      *
 ****************************************/

// Finds the first free space on the disk from start onward; returns 0
// if none available....
uint64_t BasicMBRData::FindFirstAvailable(uint64_t start) {
   uint64_t first;
   uint64_t i;
   int firstMoved;

   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 < 4; i++) {
         // Check if it's in the existing partition
         if ((first >= partitions[i].GetStartLBA()) &&
             (first < (partitions[i].GetStartLBA() + partitions[i].GetLengthLBA()))) {
            first = partitions[i].GetStartLBA() + partitions[i].GetLengthLBA();
            firstMoved = 1;
         } // if
      } // for
   } while (firstMoved == 1);
   if ((first >= diskSize) || (first > UINT32_MAX))
      first = 0;
   return (first);
} // BasicMBRData::FindFirstAvailable()

// Finds the last free sector on the disk from start forward.
uint64_t BasicMBRData::FindLastInFree(uint64_t start) {
   uint64_t nearestStart;
   uint64_t i;

   if ((diskSize <= UINT32_MAX) && (diskSize > 0))
      nearestStart = diskSize - 1;
   else
      nearestStart = UINT32_MAX - 1;

   for (i = 0; i < 4; i++) {
      if ((nearestStart > partitions[i].GetStartLBA()) &&
          (partitions[i].GetStartLBA() > start)) {
         nearestStart = partitions[i].GetStartLBA() - 1;
      } // if
   } // for
   return (nearestStart);
} // BasicMBRData::FindLastInFree()

// Finds the first free sector on the disk from start backward.
uint64_t BasicMBRData::FindFirstInFree(uint64_t start) {
   uint64_t bestLastLBA, thisLastLBA;
   int i;

   bestLastLBA = 1;
   for (i = 0; i < 4; i++) {
      thisLastLBA = partitions[i].GetLastLBA() + 1;
      if (thisLastLBA > 0)
         thisLastLBA--;
      if ((thisLastLBA > bestLastLBA) && (thisLastLBA < start))
         bestLastLBA = thisLastLBA + 1;
   } // for
   return (bestLastLBA);
} // BasicMBRData::FindFirstInFree()

// Returns NONE (unused), PRIMARY, LOGICAL, EBR (for EBR or MBR), or INVALID
int BasicMBRData::SectorUsedAs(uint64_t sector, int topPartNum) {
   int i = 0, usedAs = NONE;

   do {
      if ((partitions[i].GetStartLBA() <= sector) && (partitions[i].GetLastLBA() >= sector))
         usedAs = partitions[i].GetInclusion();
      if ((partitions[i].GetStartLBA() == (sector + 1)) && (partitions[i].GetInclusion() == LOGICAL))
         usedAs = EBR;
      if (sector == 0)
         usedAs = EBR;
      if (sector >= diskSize)
         usedAs = INVALID;
      i++;
   } while ((i < topPartNum) && (usedAs == NONE));
   return usedAs;
} // BasicMBRData::SectorUsedAs()

/******************************************************
 *                                                    *
 * Functions that extract data on specific partitions *
 *                                                    *
 ******************************************************/

uint8_t BasicMBRData::GetStatus(int i) {
   MBRPart* thePart;
   uint8_t retval;

   thePart = GetPartition(i);
   if (thePart != NULL)
      retval = thePart->GetStatus();
   else
      retval = UINT8_C(0);
   return retval;
} // BasicMBRData::GetStatus()

uint8_t BasicMBRData::GetType(int i) {
   MBRPart* thePart;
   uint8_t retval;

   thePart = GetPartition(i);
   if (thePart != NULL)
      retval = thePart->GetType();
   else
      retval = UINT8_C(0);
   return retval;
} // BasicMBRData::GetType()

uint64_t BasicMBRData::GetFirstSector(int i) {
   MBRPart* thePart;
   uint64_t retval;

   thePart = GetPartition(i);
   if (thePart != NULL) {
      retval = thePart->GetStartLBA();
   } else
      retval = UINT32_C(0);
      return retval;
} // BasicMBRData::GetFirstSector()

uint64_t BasicMBRData::GetLength(int i) {
   MBRPart* thePart;
   uint64_t retval;

   thePart = GetPartition(i);
   if (thePart != NULL) {
      retval = thePart->GetLengthLBA();
   } else
      retval = UINT64_C(0);
      return retval;
} // BasicMBRData::GetLength()

/***********************
 *                     *
 * Protected functions *
 *                     *
 ***********************/

// Return a pointer to a primary or logical partition, or NULL if
// the partition is out of range....
MBRPart* BasicMBRData::GetPartition(int i) {
   MBRPart* thePart = NULL;

   if ((i >= 0) && (i < MAX_MBR_PARTS))
      thePart = &partitions[i];
   return thePart;
} // GetPartition()

/*******************************************
 *                                         *
 * Functions that involve user interaction *
 *                                         *
 *******************************************/

// Present the MBR operations menu. Note that the 'w' option does not
// immediately write data; that's handled by the calling function.
// Returns the number of partitions defined on exit, or -1 if the
// user selected the 'q' option. (Thus, the caller should save data
// if the return value is >0, or possibly >=0 depending on intentions.)
int BasicMBRData::DoMenu(const string& prompt) {
   int goOn = 1, quitting = 0, retval, num, haveShownInfo = 0;
   unsigned int hexCode;
   string tempStr;

   do {
      cout << prompt;
      switch (ReadString()[0]) {
         case '\0':
            break;
         case 'a': case 'A':
            num = GetNumber(1, MAX_MBR_PARTS, 1, "Toggle active flag for partition: ") - 1;
            if (partitions[num].GetInclusion() != NONE)
               partitions[num].SetStatus(partitions[num].GetStatus() ^ 0x80);
            break;
         case 'c': case 'C':
            for (num = 0; num < MAX_MBR_PARTS; num++)
               RecomputeCHS(num);
            break;
         case 'l': case 'L':
            num = GetNumber(1, MAX_MBR_PARTS, 1, "Partition to set as logical: ") - 1;
            SetInclusionwChecks(num, LOGICAL);
            break;
         case 'o': case 'O':
            num = GetNumber(1, MAX_MBR_PARTS, 1, "Partition to omit: ") - 1;
            SetInclusionwChecks(num, NONE);
            break;
         case 'p': case 'P':
            if (!haveShownInfo) {
               cout << "\n** NOTE: Partition numbers do NOT indicate final primary/logical "
                    << "status,\n** unlike in most MBR partitioning tools!\n\a";
               cout << "\n** Extended partitions are not displayed, but will be generated "
                    << "as required.\n";
               haveShownInfo = 1;
            } // if
            DisplayMBRData();
            break;
         case 'q': case 'Q':
            cout << "This will abandon your changes. Are you sure? ";
            if (GetYN() == 'Y') {
               goOn = 0;
               quitting = 1;
            } // if
            break;
         case 'r': case 'R':
            num = GetNumber(1, MAX_MBR_PARTS, 1, "Partition to set as primary: ") - 1;
            SetInclusionwChecks(num, PRIMARY);
            break;
         case 's': case 'S':
            SortMBR();
            break;
         case 't': case 'T':
            num = GetNumber(1, MAX_MBR_PARTS, 1, "Partition to change type code: ") - 1;
            hexCode = 0x00;
            if (partitions[num].GetLengthLBA() > 0) {
               while ((hexCode <= 0) || (hexCode > 255)) {
                  cout << "Enter an MBR hex code: ";
                  tempStr = ReadString();
                  if (IsHex(tempStr))
                     sscanf(tempStr.c_str(), "%x", &hexCode);
               } // while
               partitions[num].SetType(hexCode);
            } // if
            break;
         case 'w': case 'W':
            goOn = 0;
            break;
         default:
            ShowCommands();
            break;
      } // switch
   } while (goOn);
   if (quitting)
      retval = -1;
   else
      retval = CountParts();
   return (retval);
} // BasicMBRData::DoMenu()

void BasicMBRData::ShowCommands(void) {
   cout << "a\ttoggle the active/boot flag\n";
   cout << "c\trecompute all CHS values\n";
   cout << "l\tset partition as logical\n";
   cout << "o\tomit partition\n";
   cout << "p\tprint the MBR partition table\n";
   cout << "q\tquit without saving changes\n";
   cout << "r\tset partition as primary\n";
   cout << "s\tsort MBR partitions\n";
   cout << "t\tchange partition type code\n";
   cout << "w\twrite the MBR partition table to disk and exit\n";
} // BasicMBRData::ShowCommands()
