blob: 1e838a6fb001e9d2b9026b906729a9ec40e34f73 [file] [log] [blame]
srs5694e7b4ff92009-08-18 13:16:10 -04001/* mbr.h -- MBR data structure definitions, types, and functions */
2
srs5694221e0872009-08-29 15:00:31 -04003/* This program is copyright (c) 2009 by Roderick W. Smith. It is distributed
4 under the terms of the GNU GPL version 2, as detailed in the COPYING file. */
5
srs5694e7b4ff92009-08-18 13:16:10 -04006#include <stdint.h>
7#include <sys/types.h>
srs5694221e0872009-08-29 15:00:31 -04008#include "gptpart.h"
srs569455d92612010-03-07 22:16:07 -05009#include "partnotes.h"
srs5694546a9c72010-01-26 16:00:26 -050010#include "diskio.h"
srs5694e7b4ff92009-08-18 13:16:10 -040011
12#ifndef __MBRSTRUCTS
13#define __MBRSTRUCTS
14
15#define MBR_SIGNATURE UINT16_C(0xAA55)
srs5694978041c2009-09-21 20:51:47 -040016#define MAX_HEADS 255 /* numbered 0 - 254 */
17#define MAX_SECSPERTRACK 63 /* numbered 1 - 63 */
18#define MAX_CYLINDERS 1024 /* numbered 0 - 1023 */
srs5694e7b4ff92009-08-18 13:16:10 -040019
srs5694978041c2009-09-21 20:51:47 -040020// Maximum number of MBR partitions
21#define MAX_MBR_PARTS 128
srs5694e7b4ff92009-08-18 13:16:10 -040022
23using namespace std;
24
srs569455d92612010-03-07 22:16:07 -050025class PartNotes;
26
srs5694e7b4ff92009-08-18 13:16:10 -040027/****************************************
28 * *
29 * MBRData class and related structures *
30 * *
31 ****************************************/
32
33// Data for a single MBR partition record
34// Note that firstSector and lastSector are in CHS addressing, which
35// splits the bits up in a weird way.
srs569455d92612010-03-07 22:16:07 -050036// On read or write of MBR entries, firstLBA is an absolute disk sector.
37// On read of logical entries, it's relative to the EBR record for that
38// partition. When writing EBR records, it's relative to the extended
39// partition's start.
srs5694ba00fed2010-01-12 18:18:36 -050040#pragma pack(1)
srs5694e7b4ff92009-08-18 13:16:10 -040041struct MBRRecord {
42 uint8_t status;
43 uint8_t firstSector[3];
44 uint8_t partitionType;
45 uint8_t lastSector[3];
srs569455d92612010-03-07 22:16:07 -050046 uint32_t firstLBA; // see above
srs5694e7b4ff92009-08-18 13:16:10 -040047 uint32_t lengthLBA;
48}; // struct MBRRecord
49
srs5694978041c2009-09-21 20:51:47 -040050// A 512-byte data structure into which the MBR can be loaded in one
srs5694546a9c72010-01-26 16:00:26 -050051// go. Also used when loading logical partitions.
srs5694ba00fed2010-01-12 18:18:36 -050052#pragma pack(1)
srs5694221e0872009-08-29 15:00:31 -040053struct TempMBR {
54 uint8_t code[440];
55 uint32_t diskSignature;
56 uint16_t nulls;
57 struct MBRRecord partitions[4];
58 uint16_t MBRSignature;
59}; // struct TempMBR
60
srs5694e7b4ff92009-08-18 13:16:10 -040061// Possible states of the MBR
62enum MBRValidity {invalid, gpt, hybrid, mbr};
63
64// Full data in tweaked MBR format
65class MBRData {
66protected:
67 uint8_t code[440];
68 uint32_t diskSignature;
69 uint16_t nulls;
srs5694978041c2009-09-21 20:51:47 -040070 // MAX_MBR_PARTS defaults to 128. This array holds both the primary and
71 // the logical partitions, to simplify data retrieval for GPT conversions.
72 struct MBRRecord partitions[MAX_MBR_PARTS];
srs5694e7b4ff92009-08-18 13:16:10 -040073 uint16_t MBRSignature;
74
75 // Above are basic MBR data; now add more stuff....
76 uint32_t blockSize; // block size (usually 512)
77 uint64_t diskSize; // size in blocks
srs5694978041c2009-09-21 20:51:47 -040078 uint64_t numHeads; // number of heads, in CHS scheme
79 uint64_t numSecspTrack; // number of sectors per track, in CHS scheme
srs5694546a9c72010-01-26 16:00:26 -050080 DiskIO* myDisk;
srs56946699b012010-02-04 00:55:30 -050081 int canDeleteMyDisk;
srs5694fed16d02010-01-27 23:03:40 -050082 string device;
srs5694e7b4ff92009-08-18 13:16:10 -040083 MBRValidity state;
84 struct MBRRecord* GetPartition(int i); // Return primary or logical partition
85public:
86 MBRData(void);
srs5694fed16d02010-01-27 23:03:40 -050087 MBRData(string deviceFilename);
srs5694e7b4ff92009-08-18 13:16:10 -040088 ~MBRData(void);
srs5694978041c2009-09-21 20:51:47 -040089
90 // File I/O functions...
srs56940a697312010-01-28 21:10:52 -050091 int ReadMBRData(const string & deviceFilename);
srs5694546a9c72010-01-26 16:00:26 -050092 void ReadMBRData(DiskIO * theDisk, int checkBlockSize = 1);
srs5694ba00fed2010-01-12 18:18:36 -050093 // ReadLogicalPart() returns last partition # read to logicals[] array,
94 // or -1 if there was a problem....
srs5694546a9c72010-01-26 16:00:26 -050095 int ReadLogicalPart(uint32_t extendedStart, uint32_t diskOffset,
srs5694978041c2009-09-21 20:51:47 -040096 int partNum);
srs5694e7b4ff92009-08-18 13:16:10 -040097 int WriteMBRData(void);
srs5694546a9c72010-01-26 16:00:26 -050098 int WriteMBRData(DiskIO *theDisk);
srs56940a697312010-01-28 21:10:52 -050099 int WriteMBRData(const string & deviceFilename);
srs569455d92612010-03-07 22:16:07 -0500100 int WriteMBRData(struct TempMBR & mbr, DiskIO *theDisk, uint64_t sector);
101 void SetDisk(DiskIO *theDisk) {myDisk = theDisk; canDeleteMyDisk = 0;}
srs5694978041c2009-09-21 20:51:47 -0400102
103 // Display data for user...
srs569455d92612010-03-07 22:16:07 -0500104 void DisplayMBRData(int maxParts = 4);
srs5694e7b4ff92009-08-18 13:16:10 -0400105 void ShowState(void);
srs5694978041c2009-09-21 20:51:47 -0400106
107 // Functions that set or get disk metadata (size, CHS geometry, etc.)
108 void SetDiskSize(uint64_t ds) {diskSize = ds;}
109 MBRValidity GetValidity(void) {return state;}
110 void SetHybrid(void) {state = hybrid;} // Set hybrid flag
111 void SetCHSGeom(uint32_t h, uint32_t s);
112 int LBAtoCHS(uint64_t lba, uint8_t * chs); // Convert LBA to CHS
113
114 // Functions to create, delete, or change partitions
115 // Pass EmptyMBR 1 to clear the boot loader code, 0 to leave it intact
116 void EmptyMBR(int clearBootloader = 1);
srs569408bb0da2010-02-19 17:19:55 -0500117 void EmptyBootloader(void);
srs5694978041c2009-09-21 20:51:47 -0400118 void MakeProtectiveMBR(int clearBoot = 0);
srs5694e7b4ff92009-08-18 13:16:10 -0400119 void MakePart(int num, uint32_t startLBA, uint32_t lengthLBA, int type = 0x07,
120 int bootable = 0);
srs569408bb0da2010-02-19 17:19:55 -0500121 int SetPartType(int num, int type);
122 int SetPartBootable(int num, int bootable = 1);
srs5694c0ca8f82009-08-20 21:35:25 -0400123 int MakeBiggestPart(int i, int type); // Make partition filling most space
srs5694e35eb1b2009-09-14 00:29:34 -0400124 void DeletePartition(int i);
srs5694e4ac11e2009-08-31 10:13:04 -0400125 int DeleteByLocation(uint64_t start64, uint64_t length64);
126 void OptimizeEESize(void);
srs569455d92612010-03-07 22:16:07 -0500127 int CreateLogicals(PartNotes& notes);
srs5694c0ca8f82009-08-20 21:35:25 -0400128
129 // Functions to find information on free space....
130 uint32_t FindFirstAvailable(uint32_t start = 1);
131 uint32_t FindLastInFree(uint32_t start);
srs5694e4ac11e2009-08-31 10:13:04 -0400132 uint32_t FindFirstInFree(uint32_t start);
133 int IsFree(uint32_t sector);
srs5694e7b4ff92009-08-18 13:16:10 -0400134
135 // Functions to extract data on specific partitions....
136 uint8_t GetStatus(int i);
137 uint8_t GetType(int i);
138 uint32_t GetFirstSector(int i);
139 uint32_t GetLength(int i);
srs5694221e0872009-08-29 15:00:31 -0400140 GPTPart AsGPT(int i);
srs5694e7b4ff92009-08-18 13:16:10 -0400141}; // struct MBRData
142
143#endif