summaryrefslogtreecommitdiff
path: root/mbr.h
blob: b434ac0e674dd8c23af9fdb0e4052de2a9c63e2a (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
/* 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 "gptpart.h"
#include "partnotes.h"
#include "diskio.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;

class PartNotes;

/****************************************
 *                                      *
 * 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.
// On read or write of MBR entries, firstLBA is an absolute disk sector.
// On read of logical entries, it's relative to the EBR record for that
// partition. When writing EBR records, it's relative to the extended
// partition's start.
#pragma pack(1)
struct MBRRecord {
   uint8_t status;
   uint8_t firstSector[3];
   uint8_t partitionType;
   uint8_t lastSector[3];
   uint32_t firstLBA; // see above
   uint32_t lengthLBA;
}; // struct MBRRecord

// A 512-byte data structure into which the MBR can be loaded in one
// go. 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
   DiskIO* myDisk;
   int canDeleteMyDisk;
   string device;
   MBRValidity state;
   struct MBRRecord* GetPartition(int i); // Return primary or logical partition
public:
   MBRData(void);
   MBRData(string deviceFilename);
   ~MBRData(void);

   // File I/O functions...
   int ReadMBRData(const string & deviceFilename);
   int ReadMBRData(DiskIO * theDisk, int checkBlockSize = 1);
   // ReadLogicalPart() returns last partition # read to logicals[] array,
   // or -1 if there was a problem....
   int ReadLogicalPart(uint32_t extendedStart, uint32_t diskOffset,
                       int partNum);
   int WriteMBRData(void);
   int WriteMBRData(DiskIO *theDisk);
   int WriteMBRData(const string & deviceFilename);
   int WriteMBRData(struct TempMBR & mbr, DiskIO *theDisk, uint64_t sector);
   void SetDisk(DiskIO *theDisk) {myDisk = theDisk; canDeleteMyDisk = 0;}

   // Display data for user...
   void DisplayMBRData(int maxParts = 4);
   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
   int Verify(void);

   // 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 EmptyBootloader(void);
   void MakeProtectiveMBR(int clearBoot = 0);
   void MakePart(int num, uint32_t startLBA, uint32_t lengthLBA, int type = 0x07,
                 int bootable = 0);
   int SetPartType(int num, int type);
   int SetPartBootable(int num, int bootable = 1);
   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);
   void RecomputeCHS(int partNum);
   int CreateLogicals(PartNotes& notes);

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