summaryrefslogtreecommitdiff
path: root/gpt.h
blob: 24786488c4ca980356c0da23eb352e9d2be1241a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/* gpt.h -- GPT and data structure definitions, types, and
   functions */

/* This program is copyright (c) 2009 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

#define GPTFDISK_VERSION "0.6.4-pre1"

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

// Data in GPT format
class GPTData {
protected:
   struct GPTHeader mainHeader;
   GPTPart *partitions;
   struct GPTHeader secondHeader;
   MBRData protectiveMBR;
   string device; // device filename
   DiskIO myDisk;
   uint32_t blockSize; // device block size
   uint64_t diskSize; // size of device, in 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
   int sectorAlignment; // Start & end 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(string deviceFilename);
   ~GPTData(void);

   // Verify (or update) data integrity
   int Verify(void);
   int CheckGPTSize(void);
   int CheckHeaderValidity(void);
   int CheckHeaderCRC(struct GPTHeader* header);
   void RecomputeCRCs(void);
   void RebuildMainHeader(void);
   void RebuildSecondHeader(void);
   int FindHybridMismatches(void);
   int FindOverlaps(void);

   // Load or save data from/to disk
   int LoadMBR(const string & f) {return protectiveMBR.ReadMBRData(f);}
   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);

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

   // Request information from the user (& possibly do something with it)
   uint32_t GetPartNum(void);
   void ResizePartitionTable(void);
   void CreatePartition(void);
   void DeletePartition(void);
   void ChangePartType(void);
   void SetAttributes(uint32_t partNum);
   int DestroyGPT(int prompt = 1); // Returns 1 if user proceeds

   // Convert between GPT and other formats (may require user interaction)
   WhichToUse UseWhichPartitions(void);
   int XFormPartitions(void);
   int XFormDisklabel(int OnGptPart = -1);
   int XFormDisklabel(BSDData* disklabel, uint32_t startPart);
   int OnePartToMBR(uint32_t gptPart, int mbrPart); // add one partition to MBR. Returns 1 if successful
   int XFormToMBR(void); // convert GPT to MBR, wiping GPT afterwards. Returns 1 if successful
   void MakeHybrid(void);

   // Adjust GPT structures WITHOUT user interaction...
   int SetGPTSize(uint32_t numEntries);
   void BlankPartitions(void);
   int DeletePartition(uint32_t partNum);
   uint32_t CreatePartition(uint32_t partNum, uint64_t startSector, uint64_t endSector);
   void SortGPT(void);
   int ClearGPTData(void);
   void MoveSecondHeaderToEnd();
   int SetName(uint32_t partNum, const string & theName = "");
   void SetDiskGUID(GUIDData newGUID);
   int SetPartitionGUID(uint32_t pn, GUIDData theGUID);
   int ChangePartType(uint32_t pn, uint16_t hexCode);
   void MakeProtectiveMBR(void) {protectiveMBR.MakeProtectiveMBR();}
   int Align(uint64_t* sector);

   // Return data about the GPT structures....
   int GetPartRange(uint32_t* low, uint32_t* high);
   uint32_t GetNumParts(void) {return mainHeader.numParts;}
   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;}
   uint32_t CountParts(void);

   // Find information about free space
   uint64_t FindFirstAvailable(uint64_t start = 0);
   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);
   int IsFreePartNum(uint32_t partNum);

   // Change how functions work, or return information on same
   void SetAlignment(int n) {sectorAlignment = n;}
   int 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
}; // class GPTData

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

#endif