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

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

#ifndef __GPTSTRUCTS
#define __GPTSTRUCTS

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

// 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)

/****************************************
 *                                      *
 * 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;
   std::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(std::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 std::string & deviceFilename);
   int SetDisk(const DiskIO & disk);
   DiskIO* GetDisk(void) {return &myDisk;}
   int LoadMBR(const std::string & f) {return protectiveMBR.ReadMBRData(f);}
   int WriteProtectiveMBR(void) {return protectiveMBR.WriteMBRData(&myDisk);}
   void PartitionScan(void);
   int LoadPartitions(const std::string & deviceFilename);
   int ForceLoadGPTData(void);
   int LoadMainTable(void);
   int LoadSecondTableAsMain(void);
   int SaveGPTData(int quiet = 0);
   int SaveGPTBackup(const std::string & filename);
   int LoadGPTBackup(const std::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, bool align = false);
   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 std::string & command, const std::string & bits);
   void ShowAttributes(const uint32_t partNum);
   void GetAttribute(const uint32_t partNum, const std::string& attributeBits);

}; // class GPTData

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

#endif
