1cf200d32Sopenharmony_ci/* gpt.h -- GPT and data structure definitions, types, and 2cf200d32Sopenharmony_ci functions */ 3cf200d32Sopenharmony_ci 4cf200d32Sopenharmony_ci/* This program is copyright (c) 2009-2022 by Roderick W. Smith. It is distributed 5cf200d32Sopenharmony_ci under the terms of the GNU GPL version 2, as detailed in the COPYING file. */ 6cf200d32Sopenharmony_ci 7cf200d32Sopenharmony_ci#ifndef __GPTSTRUCTS 8cf200d32Sopenharmony_ci#define __GPTSTRUCTS 9cf200d32Sopenharmony_ci 10cf200d32Sopenharmony_ci#include <stdint.h> 11cf200d32Sopenharmony_ci#include <sys/types.h> 12cf200d32Sopenharmony_ci#include "gptpart.h" 13cf200d32Sopenharmony_ci#include "support.h" 14cf200d32Sopenharmony_ci#include "mbr.h" 15cf200d32Sopenharmony_ci#include "bsd.h" 16cf200d32Sopenharmony_ci#include "gptpart.h" 17cf200d32Sopenharmony_ci 18cf200d32Sopenharmony_ci// Default values for sector alignment 19cf200d32Sopenharmony_ci#define DEFAULT_ALIGNMENT 2048 20cf200d32Sopenharmony_ci#define MAX_ALIGNMENT 65536 21cf200d32Sopenharmony_ci#define MIN_AF_ALIGNMENT 8 22cf200d32Sopenharmony_ci 23cf200d32Sopenharmony_ci// Below constant corresponds to a ~279GiB (300GB) disk, since the 24cf200d32Sopenharmony_ci// smallest Advanced Format drive I know of is 320GB in size 25cf200d32Sopenharmony_ci#define SMALLEST_ADVANCED_FORMAT UINT64_C(585937500) 26cf200d32Sopenharmony_ci 27cf200d32Sopenharmony_ci/**************************************** 28cf200d32Sopenharmony_ci * * 29cf200d32Sopenharmony_ci * GPTData class and related structures * 30cf200d32Sopenharmony_ci * * 31cf200d32Sopenharmony_ci ****************************************/ 32cf200d32Sopenharmony_ci 33cf200d32Sopenharmony_ci// Validity state of GPT data 34cf200d32Sopenharmony_cienum GPTValidity {gpt_valid, gpt_corrupt, gpt_invalid}; 35cf200d32Sopenharmony_ci 36cf200d32Sopenharmony_ci// Which set of partition data to use 37cf200d32Sopenharmony_cienum WhichToUse {use_gpt, use_mbr, use_bsd, use_new, use_abort}; 38cf200d32Sopenharmony_ci 39cf200d32Sopenharmony_ci// Header (first 512 bytes) of GPT table 40cf200d32Sopenharmony_ci#pragma pack(1) 41cf200d32Sopenharmony_cistruct GPTHeader { 42cf200d32Sopenharmony_ci uint64_t signature; 43cf200d32Sopenharmony_ci uint32_t revision; 44cf200d32Sopenharmony_ci uint32_t headerSize; 45cf200d32Sopenharmony_ci uint32_t headerCRC; 46cf200d32Sopenharmony_ci uint32_t reserved; 47cf200d32Sopenharmony_ci uint64_t currentLBA; 48cf200d32Sopenharmony_ci uint64_t backupLBA; 49cf200d32Sopenharmony_ci uint64_t firstUsableLBA; 50cf200d32Sopenharmony_ci uint64_t lastUsableLBA; 51cf200d32Sopenharmony_ci GUIDData diskGUID; 52cf200d32Sopenharmony_ci uint64_t partitionEntriesLBA; 53cf200d32Sopenharmony_ci uint32_t numParts; 54cf200d32Sopenharmony_ci uint32_t sizeOfPartitionEntries; 55cf200d32Sopenharmony_ci uint32_t partitionEntriesCRC; 56cf200d32Sopenharmony_ci unsigned char reserved2[GPT_RESERVED]; 57cf200d32Sopenharmony_ci}; // struct GPTHeader 58cf200d32Sopenharmony_ci#pragma pack () 59cf200d32Sopenharmony_ci 60cf200d32Sopenharmony_ci// Data in GPT format 61cf200d32Sopenharmony_ciclass GPTData { 62cf200d32Sopenharmony_ciprotected: 63cf200d32Sopenharmony_ci struct GPTHeader mainHeader; 64cf200d32Sopenharmony_ci GPTPart *partitions; 65cf200d32Sopenharmony_ci uint32_t numParts; // # of partitions the table can hold 66cf200d32Sopenharmony_ci struct GPTHeader secondHeader; 67cf200d32Sopenharmony_ci MBRData protectiveMBR; 68cf200d32Sopenharmony_ci std::string device; // device filename 69cf200d32Sopenharmony_ci DiskIO myDisk; 70cf200d32Sopenharmony_ci uint32_t blockSize; // device logical block size 71cf200d32Sopenharmony_ci uint32_t physBlockSize; // device physical block size (or 0 if it can't be determined) 72cf200d32Sopenharmony_ci uint64_t diskSize; // size of device, in logical blocks 73cf200d32Sopenharmony_ci GPTValidity state; // is GPT valid? 74cf200d32Sopenharmony_ci int justLooking; // Set to 1 if program launched with "-l" or if read-only 75cf200d32Sopenharmony_ci int mainCrcOk; 76cf200d32Sopenharmony_ci int secondCrcOk; 77cf200d32Sopenharmony_ci int mainPartsCrcOk; 78cf200d32Sopenharmony_ci int secondPartsCrcOk; 79cf200d32Sopenharmony_ci int apmFound; // set to 1 if APM detected 80cf200d32Sopenharmony_ci int bsdFound; // set to 1 if BSD disklabel detected in MBR 81cf200d32Sopenharmony_ci uint32_t sectorAlignment; // Start partitions at multiples of sectorAlignment 82cf200d32Sopenharmony_ci int beQuiet; 83cf200d32Sopenharmony_ci WhichToUse whichWasUsed; 84cf200d32Sopenharmony_ci 85cf200d32Sopenharmony_ci int LoadHeader(struct GPTHeader *header, DiskIO & disk, uint64_t sector, int *crcOk); 86cf200d32Sopenharmony_ci int LoadPartitionTable(const struct GPTHeader & header, DiskIO & disk, uint64_t sector = 0); 87cf200d32Sopenharmony_ci int CheckTable(struct GPTHeader *header); 88cf200d32Sopenharmony_ci int SaveHeader(struct GPTHeader *header, DiskIO & disk, uint64_t sector); 89cf200d32Sopenharmony_ci int SavePartitionTable(DiskIO & disk, uint64_t sector); 90cf200d32Sopenharmony_cipublic: 91cf200d32Sopenharmony_ci // Basic necessary functions.... 92cf200d32Sopenharmony_ci GPTData(void); 93cf200d32Sopenharmony_ci GPTData(const GPTData &); 94cf200d32Sopenharmony_ci GPTData(std::string deviceFilename); 95cf200d32Sopenharmony_ci virtual ~GPTData(void); 96cf200d32Sopenharmony_ci GPTData & operator=(const GPTData & orig); 97cf200d32Sopenharmony_ci 98cf200d32Sopenharmony_ci // Verify (or update) data integrity 99cf200d32Sopenharmony_ci int Verify(void); 100cf200d32Sopenharmony_ci int CheckGPTSize(void); 101cf200d32Sopenharmony_ci int CheckHeaderValidity(void); 102cf200d32Sopenharmony_ci int CheckHeaderCRC(struct GPTHeader* header, int warn = 0); 103cf200d32Sopenharmony_ci void RecomputeCRCs(void); 104cf200d32Sopenharmony_ci void RebuildMainHeader(void); 105cf200d32Sopenharmony_ci void RebuildSecondHeader(void); 106cf200d32Sopenharmony_ci int VerifyMBR(void) {return protectiveMBR.FindOverlaps();} 107cf200d32Sopenharmony_ci int FindHybridMismatches(void); 108cf200d32Sopenharmony_ci int FindOverlaps(void); 109cf200d32Sopenharmony_ci int FindInsanePartitions(void); 110cf200d32Sopenharmony_ci 111cf200d32Sopenharmony_ci // Load or save data from/to disk 112cf200d32Sopenharmony_ci int SetDisk(const std::string & deviceFilename); 113cf200d32Sopenharmony_ci DiskIO* GetDisk(void) {return &myDisk;} 114cf200d32Sopenharmony_ci int LoadMBR(const std::string & f) {return protectiveMBR.ReadMBRData(f);} 115cf200d32Sopenharmony_ci int WriteProtectiveMBR(void) {return protectiveMBR.WriteMBRData(&myDisk);} 116cf200d32Sopenharmony_ci void PartitionScan(void); 117cf200d32Sopenharmony_ci int LoadPartitions(const std::string & deviceFilename); 118cf200d32Sopenharmony_ci int ForceLoadGPTData(void); 119cf200d32Sopenharmony_ci int LoadMainTable(void); 120cf200d32Sopenharmony_ci int LoadSecondTableAsMain(void); 121cf200d32Sopenharmony_ci int SaveGPTData(int quiet = 0); 122cf200d32Sopenharmony_ci int SaveGPTBackup(const std::string & filename); 123cf200d32Sopenharmony_ci int LoadGPTBackup(const std::string & filename); 124cf200d32Sopenharmony_ci int SaveMBR(void); 125cf200d32Sopenharmony_ci int DestroyGPT(void); 126cf200d32Sopenharmony_ci int DestroyMBR(void); 127cf200d32Sopenharmony_ci 128cf200d32Sopenharmony_ci // Display data.... 129cf200d32Sopenharmony_ci void ShowAPMState(void); 130cf200d32Sopenharmony_ci void ShowGPTState(void); 131cf200d32Sopenharmony_ci void DisplayGPTData(void); 132cf200d32Sopenharmony_ci void DisplayMBRData(void) {protectiveMBR.DisplayMBRData();} 133cf200d32Sopenharmony_ci void ShowPartDetails(uint32_t partNum); 134cf200d32Sopenharmony_ci 135cf200d32Sopenharmony_ci // Convert between GPT and other formats 136cf200d32Sopenharmony_ci virtual WhichToUse UseWhichPartitions(void); 137cf200d32Sopenharmony_ci void XFormPartitions(void); 138cf200d32Sopenharmony_ci int XFormDisklabel(uint32_t partNum); 139cf200d32Sopenharmony_ci int XFormDisklabel(BSDData* disklabel); 140cf200d32Sopenharmony_ci int OnePartToMBR(uint32_t gptPart, int mbrPart); // add one partition to MBR. Returns 1 if successful 141cf200d32Sopenharmony_ci 142cf200d32Sopenharmony_ci // Adjust GPT structures WITHOUT user interaction... 143cf200d32Sopenharmony_ci int SetGPTSize(uint32_t numEntries, int fillGPTSectors = 1); 144cf200d32Sopenharmony_ci int MoveMainTable(uint64_t pteSector); 145cf200d32Sopenharmony_ci int MoveSecondTable(uint64_t pteSector); 146cf200d32Sopenharmony_ci void BlankPartitions(void); 147cf200d32Sopenharmony_ci int DeletePartition(uint32_t partNum); 148cf200d32Sopenharmony_ci uint32_t CreatePartition(uint32_t partNum, uint64_t startSector, uint64_t endSector); 149cf200d32Sopenharmony_ci void SortGPT(void); 150cf200d32Sopenharmony_ci int SwapPartitions(uint32_t partNum1, uint32_t partNum2); 151cf200d32Sopenharmony_ci int ClearGPTData(void); 152cf200d32Sopenharmony_ci void MoveSecondHeaderToEnd(); 153cf200d32Sopenharmony_ci int SetName(uint32_t partNum, const UnicodeString & theName); 154cf200d32Sopenharmony_ci void SetDiskGUID(GUIDData newGUID); 155cf200d32Sopenharmony_ci int SetPartitionGUID(uint32_t pn, GUIDData theGUID); 156cf200d32Sopenharmony_ci void RandomizeGUIDs(void); 157cf200d32Sopenharmony_ci int ChangePartType(uint32_t pn, PartType theGUID); 158cf200d32Sopenharmony_ci void MakeProtectiveMBR(void) {protectiveMBR.MakeProtectiveMBR();} 159cf200d32Sopenharmony_ci void RecomputeCHS(void); 160cf200d32Sopenharmony_ci int Align(uint64_t* sector); 161cf200d32Sopenharmony_ci void SetProtectiveMBR(BasicMBRData & newMBR) {protectiveMBR = newMBR;} 162cf200d32Sopenharmony_ci 163cf200d32Sopenharmony_ci // Return data about the GPT structures.... 164cf200d32Sopenharmony_ci WhichToUse GetState(void) {return whichWasUsed;} 165cf200d32Sopenharmony_ci int GetPartRange(uint32_t* low, uint32_t* high); 166cf200d32Sopenharmony_ci int FindFirstFreePart(void); 167cf200d32Sopenharmony_ci uint32_t GetNumParts(void) {return mainHeader.numParts;} 168cf200d32Sopenharmony_ci uint64_t GetTableSizeInSectors(void) {return (((numParts * GPT_SIZE) / blockSize) + 169cf200d32Sopenharmony_ci (((numParts * GPT_SIZE) % blockSize) != 0)); } 170cf200d32Sopenharmony_ci uint64_t GetMainHeaderLBA(void) {return mainHeader.currentLBA;} 171cf200d32Sopenharmony_ci uint64_t GetSecondHeaderLBA(void) {return secondHeader.currentLBA;} 172cf200d32Sopenharmony_ci uint64_t GetMainPartsLBA(void) {return mainHeader.partitionEntriesLBA;} 173cf200d32Sopenharmony_ci uint64_t GetSecondPartsLBA(void) {return secondHeader.partitionEntriesLBA;} 174cf200d32Sopenharmony_ci uint64_t GetFirstUsableLBA(void) {return mainHeader.firstUsableLBA;} 175cf200d32Sopenharmony_ci uint64_t GetLastUsableLBA(void) {return mainHeader.lastUsableLBA;} 176cf200d32Sopenharmony_ci uint32_t CountParts(void); 177cf200d32Sopenharmony_ci bool ValidPartNum (const uint32_t partNum); 178cf200d32Sopenharmony_ci const GPTPart & operator[](uint32_t partNum) const; 179cf200d32Sopenharmony_ci const GUIDData & GetDiskGUID(void) const; 180cf200d32Sopenharmony_ci uint32_t GetBlockSize(void) {return blockSize;} 181cf200d32Sopenharmony_ci 182cf200d32Sopenharmony_ci // Find information about free space 183cf200d32Sopenharmony_ci uint64_t FindFirstAvailable(uint64_t start = 0); 184cf200d32Sopenharmony_ci uint64_t FindFirstUsedLBA(void); 185cf200d32Sopenharmony_ci uint64_t FindLastUsedLBA(void); 186cf200d32Sopenharmony_ci uint64_t FindFirstInLargest(void); 187cf200d32Sopenharmony_ci uint64_t FindLastAvailable(); 188cf200d32Sopenharmony_ci uint64_t FindLastInFree(uint64_t start, bool align = false); 189cf200d32Sopenharmony_ci uint64_t FindFreeBlocks(uint32_t *numSegments, uint64_t *largestSegment); 190cf200d32Sopenharmony_ci int IsFree(uint64_t sector, uint32_t *partNum = NULL); 191cf200d32Sopenharmony_ci int IsFreePartNum(uint32_t partNum); 192cf200d32Sopenharmony_ci int IsUsedPartNum(uint32_t partNum); 193cf200d32Sopenharmony_ci 194cf200d32Sopenharmony_ci // Change how functions work, or return information on same 195cf200d32Sopenharmony_ci void SetAlignment(uint32_t n); 196cf200d32Sopenharmony_ci uint32_t ComputeAlignment(void); // Set alignment based on current partitions 197cf200d32Sopenharmony_ci uint32_t GetAlignment(void) {return sectorAlignment;} 198cf200d32Sopenharmony_ci void JustLooking(int i = 1) {justLooking = i;} 199cf200d32Sopenharmony_ci void BeQuiet(int i = 1) {beQuiet = i;} 200cf200d32Sopenharmony_ci WhichToUse WhichWasUsed(void) {return whichWasUsed;} 201cf200d32Sopenharmony_ci 202cf200d32Sopenharmony_ci // Endianness functions 203cf200d32Sopenharmony_ci void ReverseHeaderBytes(struct GPTHeader* header); 204cf200d32Sopenharmony_ci void ReversePartitionBytes(); // for endianness 205cf200d32Sopenharmony_ci 206cf200d32Sopenharmony_ci // Attributes functions 207cf200d32Sopenharmony_ci int ManageAttributes(int partNum, const std::string & command, const std::string & bits); 208cf200d32Sopenharmony_ci void ShowAttributes(const uint32_t partNum); 209cf200d32Sopenharmony_ci void GetAttribute(const uint32_t partNum, const std::string& attributeBits); 210cf200d32Sopenharmony_ci 211cf200d32Sopenharmony_ci}; // class GPTData 212cf200d32Sopenharmony_ci 213cf200d32Sopenharmony_ci// Function prototypes.... 214cf200d32Sopenharmony_ciint SizesOK(void); 215cf200d32Sopenharmony_ci 216cf200d32Sopenharmony_ci#endif 217