summaryrefslogtreecommitdiff
path: root/mbr.h
blob: 0cd4d2a916b8631250d72e8881968dcf002ac177 (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
/* mbr.h -- MBR 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 <sys/ioctl.h>
#include "gptpart.h"

#ifndef __MBRSTRUCTS
#define __MBRSTRUCTS

#define MBR_SIGNATURE UINT16_C(0xAA55)
#define MAX_HEADS 255        /* numbered 0 - 254 */
#define MAX_SECSPERTRACK 63  /* numbered 1 - 63 */
#define MAX_CYLINDERS 1024   /* numbered 0 - 1023 */

// Maximum number of MBR partitions
#define MAX_MBR_PARTS 128

using namespace std;

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

// Data for a single MBR partition record
// Note that firstSector and lastSector are in CHS addressing, which
// splits the bits up in a weird way.
#pragma pack(1)
struct MBRRecord {
   uint8_t status;
   uint8_t firstSector[3];
   uint8_t partitionType;
   uint8_t lastSector[3];
   uint32_t firstLBA;
   uint32_t lengthLBA;
}; // struct MBRRecord

// A 512-byte data structure into which the MBR can be loaded in one
// go, for the benefit of FreeBSD which seems to flake out when loading
// from block devices in multiples other than the block size.
// Also used when loading logical partitions.
#pragma pack(1)
struct TempMBR {
   uint8_t code[440];
   uint32_t diskSignature;
   uint16_t nulls;
   struct MBRRecord partitions[4];
   uint16_t MBRSignature;
}; // struct TempMBR

// Possible states of the MBR
enum MBRValidity {invalid, gpt, hybrid, mbr};

// Full data in tweaked MBR format
class MBRData {
protected:
   uint8_t code[440];
   uint32_t diskSignature;
   uint16_t nulls;
   // MAX_MBR_PARTS defaults to 128. This array holds both the primary and
   // the logical partitions, to simplify data retrieval for GPT conversions.
   struct MBRRecord partitions[MAX_MBR_PARTS];
   uint16_t MBRSignature;

   // Above are basic MBR data; now add more stuff....
   uint32_t blockSize; // block size (usually 512)
   uint64_t diskSize; // size in blocks
   uint64_t numHeads; // number of heads, in CHS scheme
   uint64_t numSecspTrack; // number of sectors per track, in CHS scheme
   char device[256];
   MBRValidity state;
   struct MBRRecord* GetPartition(int i); // Return primary or logical partition
public:
   MBRData(void);
   MBRData(char* deviceFilename);
   ~MBRData(void);

   // File I/O functions...
   int ReadMBRData(char* deviceFilename);
   void ReadMBRData(int fd, int checkBlockSize = 1);
   // ReadLogicalPart() returns last partition # read to logicals[] array,
   // or -1 if there was a problem....
   int ReadLogicalPart(int fd, uint32_t extendedStart, uint32_t diskOffset,
                       int partNum);
   int WriteMBRData(void);
   void WriteMBRData(int fd);
   int WriteMBRData(char* deviceFilename);

   // Display data for user...
   void DisplayMBRData(void);
   void ShowState(void);

   // Functions that set or get disk metadata (size, CHS geometry, etc.)
   void SetDiskSize(uint64_t ds) {diskSize = ds;}
   MBRValidity GetValidity(void) {return state;}
   void SetHybrid(void) {state = hybrid;} // Set hybrid flag
   void SetCHSGeom(uint32_t h, uint32_t s);
   int LBAtoCHS(uint64_t lba, uint8_t * chs); // Convert LBA to CHS

   // Functions to create, delete, or change partitions
   // Pass EmptyMBR 1 to clear the boot loader code, 0 to leave it intact
   void EmptyMBR(int clearBootloader = 1);
   void MakeProtectiveMBR(int clearBoot = 0);
   void MakePart(int num, uint32_t startLBA, uint32_t lengthLBA, int type = 0x07,
                 int bootable = 0);
   int MakeBiggestPart(int i, int type); // Make partition filling most space
   void DeletePartition(int i);
   int DeleteByLocation(uint64_t start64, uint64_t length64);
   void OptimizeEESize(void);

   // Functions to find information on free space....
   uint32_t FindFirstAvailable(uint32_t start = 1);
   uint32_t FindLastInFree(uint32_t start);
   uint32_t FindFirstInFree(uint32_t start);
   int IsFree(uint32_t sector);

   // Functions to extract data on specific partitions....
   uint8_t GetStatus(int i);
   uint8_t GetType(int i);
   uint32_t GetFirstSector(int i);
   uint32_t GetLength(int i);
   GPTPart AsGPT(int i);
}; // struct MBRData

#endif