/* gpt.h -- GPT and data structure definitions, types, and
   functions */

/* 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. */

#include <stdint.h>
#include <sys/types.h>
#include "gptpart.h"
#include "support.h"
#include "mbr.h"
#include "bsd.h"
#include "gptpart.h"

#ifndef __GPTSTRUCTS
#define __GPTSTRUCTS

// Default values for sector alignment
#define DEFAULT_ALIGNMENT 2048
#define MAX_ALIGNMENT 65536
#define MIN_AF_ALIGNMENT 8

// Below constant corresponds to a ~279GiB (300GB) disk, since the
// smallest Advanced Format drive I know of is 320GB in size
#define SMALLEST_ADVANCED_FORMAT UINT64_C(585937500)

using namespace std;

/****************************************
 *                                      *
 * GPTData class and related structures *
 *                                      *
 ****************************************/

// Validity state of GPT data
enum GPTValidity {gpt_valid, gpt_corrupt, gpt_invalid};

// Which set of partition data to use
enum WhichToUse {use_gpt, use_mbr, use_bsd, use_new, use_abort};

// Header (first 512 bytes) of GPT table
#pragma pack(1)
struct GPTHeader {
   uint64_t signature;
   uint32_t revision;
   uint32_t headerSize;
   uint32_t headerCRC;
   uint32_t reserved;
   uint64_t currentLBA;
   uint64_t backupLBA;
   uint64_t firstUsableLBA;
   uint64_t lastUsableLBA;
   GUIDData diskGUID;
   uint64_t partitionEntriesLBA;
   uint32_t numParts;
   uint32_t sizeOfPartitionEntries;
   uint32_t partitionEntriesCRC;
   unsigned char reserved2[GPT_RESERVED];
}; // struct GPTHeader
#pragma pack ()

// Data in GPT format
class GPTData {
protected:
   struct GPTHeader mainHeader;
   GPTPart *partitions;
   uint32_t numParts; // # of partitions the table can hold
   struct GPTHeader secondHeader;
   MBRData protectiveMBR;
   string device; // device filename
   DiskIO myDisk;
   uint32_t blockSize; // device logical block size
   uint32_t physBlockSize; // device physical block size (or 0 if it can't be determined)
   uint64_t diskSize; // size of device, in logical blocks
   GPTValidity state; // is GPT valid?
   int justLooking; // Set to 1 if program launched with "-l" or if read-only
   int mainCrcOk;
   int secondCrcOk;
   int mainPartsCrcOk;
   int secondPartsCrcOk;
   int apmFound; // set to 1 if APM detected
   int bsdFound; // set to 1 if BSD disklabel detected in MBR
   uint32_t sectorAlignment; // Start partitions at multiples of sectorAlignment
   int beQuiet;
   WhichToUse whichWasUsed;

   int LoadHeader(struct GPTHeader *header, DiskIO & disk, uint64_t sector, int *crcOk);
   int LoadPartitionTable(const struct GPTHeader & header, DiskIO & disk, uint64_t sector = 0);
   int CheckTable(struct GPTHeader *header);
   int SaveHeader(struct GPTHeader *header, DiskIO & disk, uint64_t sector);
   int SavePartitionTable(DiskIO & disk, uint64_t sector);
public:
   // Basic necessary functions....
   GPTData(void);
   GPTData(const GPTData &);
   GPTData(string deviceFilename);
   virtual ~GPTData(void);
   GPTData & operator=(const GPTData & orig);

   // Verify (or update) data integrity
   int Verify(void);
   int CheckGPTSize(void);
   int CheckHeaderValidity(void);
   int CheckHeaderCRC(struct GPTHeader* header, int warn = 0);
   void RecomputeCRCs(void);
   void RebuildMainHeader(void);
   void RebuildSecondHeader(void);
   int VerifyMBR(void) {return protectiveMBR.FindOverlaps();}
   int FindHybridMismatches(void);
   int FindOverlaps(void);
   int FindInsanePartitions(void);

   // Load or save data from/to disk
   int SetDisk(const string & deviceFilename);
   int SetDisk(const DiskIO & disk);
   DiskIO* GetDisk(void) {return &myDisk;}
   int LoadMBR(const string & f) {return protectiveMBR.ReadMBRData(f);}
   int WriteProtectiveMBR(void) {return protectiveMBR.WriteMBRData(&myDisk);}
   void PartitionScan(void);
   int LoadPartitions(const string & deviceFilename);
   int ForceLoadGPTData(void);
   int LoadMainTable(void);
   int LoadSecondTableAsMain(void);
   int SaveGPTData(int quiet = 0);
   int SaveGPTBackup(const string & filename);
   int LoadGPTBackup(const string & filename);
   int SaveMBR(void);
   int DestroyGPT(void);
   int DestroyMBR(void);

   // Display data....
   void ShowAPMState(void);
   void ShowGPTState(void);
   void DisplayGPTData(void);
   void DisplayMBRData(void) {protectiveMBR.DisplayMBRData();}
   void ShowPartDetails(uint32_t partNum);

   // Convert between GPT and other formats
   virtual WhichToUse UseWhichPartitions(void);
   void XFormPartitions(void);
   int XFormDisklabel(uint32_t partNum);
   int XFormDisklabel(BSDData* disklabel);
   int OnePartToMBR(uint32_t gptPart, int mbrPart); // add one partition to MBR. Returns 1 if successful

   // Adjust GPT structures WITHOUT user interaction...
   int SetGPTSize(uint32_t numEntries, int fillGPTSectors = 1);
   int MoveMainTable(uint64_t pteSector);
   void BlankPartitions(void);
   int DeletePartition(uint32_t partNum);
   uint32_t CreatePartition(uint32_t partNum, uint64_t startSector, uint64_t endSector);
   void SortGPT(void);
   int SwapPartitions(uint32_t partNum1, uint32_t partNum2);
   int ClearGPTData(void);
   void MoveSecondHeaderToEnd();
   int SetName(uint32_t partNum, const UnicodeString & theName);
   void SetDiskGUID(GUIDData newGUID);
   int SetPartitionGUID(uint32_t pn, GUIDData theGUID);
   void RandomizeGUIDs(void);
   int ChangePartType(uint32_t pn, PartType theGUID);
   void MakeProtectiveMBR(void) {protectiveMBR.MakeProtectiveMBR();}
   void RecomputeCHS(void);
   int Align(uint64_t* sector);
   void SetProtectiveMBR(BasicMBRData & newMBR) {protectiveMBR = newMBR;}
   
   // Return data about the GPT structures....
   WhichToUse GetState(void) {return whichWasUsed;}
   int GetPartRange(uint32_t* low, uint32_t* high);
   int FindFirstFreePart(void);
   uint32_t GetNumParts(void) {return mainHeader.numParts;}
   uint64_t GetTableSizeInSectors(void) {return (((numParts * GPT_SIZE) / blockSize) +
                                                 (((numParts * GPT_SIZE) % blockSize) != 0)); }
   uint64_t GetMainHeaderLBA(void) {return mainHeader.currentLBA;}
   uint64_t GetSecondHeaderLBA(void) {return secondHeader.currentLBA;}
   uint64_t GetMainPartsLBA(void) {return mainHeader.partitionEntriesLBA;}
   uint64_t GetSecondPartsLBA(void) {return secondHeader.partitionEntriesLBA;}
   uint64_t GetFirstUsableLBA(void) {return mainHeader.firstUsableLBA;}
   uint64_t GetLastUsableLBA(void) {return mainHeader.lastUsableLBA;}
   uint32_t CountParts(void);
   bool ValidPartNum (const uint32_t partNum);
   const GPTPart & operator[](uint32_t partNum) const;
   const GUIDData & GetDiskGUID(void) const;
   uint32_t GetBlockSize(void) {return blockSize;}

   // Find information about free space
   uint64_t FindFirstAvailable(uint64_t start = 0);
   uint64_t FindFirstUsedLBA(void);
   uint64_t FindFirstInLargest(void);
   uint64_t FindLastAvailable();
   uint64_t FindLastInFree(uint64_t start);
   uint64_t FindFreeBlocks(uint32_t *numSegments, uint64_t *largestSegment);
   int IsFree(uint64_t sector, uint32_t *partNum = NULL);
   int IsFreePartNum(uint32_t partNum);
   int IsUsedPartNum(uint32_t partNum);

   // Change how functions work, or return information on same
   void SetAlignment(uint32_t n);
   uint32_t ComputeAlignment(void); // Set alignment based on current partitions
   uint32_t GetAlignment(void) {return sectorAlignment;}
   void JustLooking(int i = 1) {justLooking = i;}
   void BeQuiet(int i = 1) {beQuiet = i;}
   WhichToUse WhichWasUsed(void) {return whichWasUsed;}

   // Endianness functions
   void ReverseHeaderBytes(struct GPTHeader* header);
   void ReversePartitionBytes(); // for endianness

   // Attributes functions
   int ManageAttributes(int partNum, const string & command, const string & bits);
   void ShowAttributes(const uint32_t partNum);
   void GetAttribute(const uint32_t partNum, const string& attributeBits);

}; // class GPTData

// Function prototypes....
int SizesOK(void);

#endif
