1 /* 2 * Copyright 2003-2007, Ingo Weinhold, bonefish@cs.tu-berlin.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef _INTEL_PARTITION_MAP_H 6 #define _INTEL_PARTITION_MAP_H 7 8 /*! \file PartitionMap.h 9 \ingroup intel_module 10 \brief Definitions for "intel" style partitions and interface definitions 11 for related classes. 12 */ 13 14 // NOTE: <http://www.win.tue.nl/~aeb/partitions/partition_tables-2.html> 15 16 #include <SupportDefs.h> 17 #include <driver_settings.h> 18 19 #include <disk_device_types.h> 20 21 #ifndef _USER_MODE 22 # include <util/kernel_cpp.h> 23 #else 24 # include <new> 25 #endif 26 27 28 // partition_type 29 struct partition_type { 30 uint8 type; 31 const char* name; 32 bool used; 33 }; 34 35 36 // is_empty_type 37 static inline bool 38 is_empty_type(uint8 type) 39 { 40 return type == 0x00; 41 } 42 43 44 // is_extended_type 45 static inline bool 46 is_extended_type(uint8 type) 47 { 48 return type == 0x05 || type == 0x0f || type == 0x85; 49 } 50 51 52 void get_partition_type_string(uint8 type, char* buffer); 53 54 // chs 55 // NOTE: The CHS cannot express locations within larger disks (more than 8GB), 56 // and is therefore obsolete. 57 // However, some BIOSes still rely on it being 0 for unused partition, and some 58 // other value for valid records. Usually they are filled with 0xFF, which is 59 // an invalid CHS value, to notify the BIOS that LBA should be used instead. 60 struct chs { 61 uint8 cylinder; 62 uint16 head_sector; // head[15:10], sector[9:0] 63 void SetUnused() { cylinder = 0xFF; head_sector = 0xFFFF; } 64 void Unset() { cylinder = 0; head_sector = 0; } 65 } _PACKED; 66 67 // partition_descriptor 68 struct partition_descriptor { 69 uint8 active; 70 chs begin; // mostly ignored 71 uint8 type; // empty, filesystem or extended 72 chs end; // mostly ignored 73 uint32 start; // in sectors 74 uint32 size; // in sectors 75 76 bool is_empty() const { return is_empty_type(type); } 77 bool is_extended() const { return is_extended_type(type); } 78 } _PACKED; 79 80 // partition_table 81 struct partition_table { 82 char code_area[440]; 83 uint32 disk_id; 84 uint16 reserved; 85 partition_descriptor table[4]; 86 uint16 signature; 87 88 void clear_code_area() 89 { 90 memset(code_area, 0, sizeof(code_area)); 91 } 92 93 void fill_code_area(const uint8* code, size_t size) 94 { 95 memcpy(code_area, code, min_c(sizeof(code_area), size)); 96 } 97 } _PACKED; 98 99 static const uint16 kPartitionTableSectorSignature = 0xaa55; 100 101 class Partition; 102 class PrimaryPartition; 103 class LogicalPartition; 104 105 106 // PartitionType 107 /*! 108 \brief Class for validating partition types. 109 110 To this class we can set a partition type and then we can check whether 111 this type is valid, empty or if it represents an extended partition. 112 We can also retrieve the name of that partition type or find the next 113 supported type. 114 */ 115 class PartitionType { 116 public: 117 PartitionType(); 118 119 bool SetType(uint8 type); 120 bool SetType(const char* typeName); 121 bool SetContentType(const char* contentType); 122 123 bool IsValid() const { return fValid; } 124 bool IsEmpty() const { return is_empty_type(fType); } 125 bool IsExtended() const { return is_extended_type(fType); } 126 127 uint8 Type() const { return fType; } 128 bool FindNext(); 129 void GetTypeString(char* buffer) const 130 { get_partition_type_string(fType, buffer); } 131 private: 132 uint8 fType; 133 bool fValid; 134 }; 135 136 137 // Partition 138 class Partition { 139 public: 140 Partition(); 141 Partition(const partition_descriptor* descriptor, 142 off_t tableOffset, off_t baseOffset, 143 uint32 blockSize); 144 145 void SetTo(const partition_descriptor* descriptor, 146 off_t tableOffset, off_t baseOffset, 147 uint32 blockSize); 148 void SetTo(off_t offset, off_t size, uint8 type, 149 bool active, off_t tableOffset, 150 uint32 blockSize); 151 void Unset(); 152 153 bool IsEmpty() const 154 { return is_empty_type(fType); } 155 bool IsExtended() const 156 { return is_extended_type(fType); } 157 158 // NOTE: Both PartitionTableOffset() and Offset() are absolute with regards 159 // to the session (usually the disk). Ie, for all primary partitions, 160 // including the primary extended partition, the PartitionTableOffset() 161 // points to the MBR (0). 162 // For logical partitions, the PartitionTableOffset() is located within the 163 // primary extended partition, but again, the returned values are absolute 164 // with regards to the session. All values are expressed in bytes. 165 off_t PartitionTableOffset() const 166 { return fPartitionTableOffset; } 167 // offset of the partition table 168 off_t Offset() const { return fOffset; } 169 // start offset of the partition contents 170 off_t Size() const { return fSize; } 171 uint8 Type() const { return fType; } 172 bool Active() const { return fActive; } 173 uint32 BlockSize() const { return fBlockSize; } 174 void GetTypeString(char* buffer) const 175 { get_partition_type_string(fType, buffer); } 176 177 void SetPartitionTableOffset(off_t offset) 178 { fPartitionTableOffset = offset; } 179 void SetOffset(off_t offset) 180 { fOffset = offset; } 181 void SetSize(off_t size) 182 { fSize = size; } 183 void SetType(uint8 type) 184 { fType = type; } 185 void SetActive(bool active) 186 { fActive = active; } 187 void SetBlockSize(uint32 blockSize) 188 { fBlockSize = blockSize; } 189 190 bool CheckLocation(off_t sessionSize) const; 191 bool FitSizeToSession(off_t sessionSize); 192 193 private: 194 off_t fPartitionTableOffset; 195 off_t fOffset; 196 // relative to the start of the session 197 off_t fSize; 198 uint32 fBlockSize; 199 uint8 fType; 200 bool fActive; 201 }; 202 203 204 // PrimaryPartition 205 class PrimaryPartition : public Partition { 206 public: 207 PrimaryPartition(); 208 209 void SetTo(const partition_descriptor* descriptor, 210 off_t tableOffset, uint32 blockSize); 211 void SetTo(off_t offset, off_t size, uint8 type, 212 bool active, uint32 blockSize); 213 void Unset(); 214 215 status_t Assign(const PrimaryPartition& other); 216 217 int32 Index() const { return fIndex; } 218 void SetIndex(int32 index) { fIndex = index; } 219 void GetPartitionDescriptor( 220 partition_descriptor* descriptor) const; 221 222 // private 223 224 // only if extended 225 int32 CountLogicalPartitions() const 226 { return fLogicalPartitionCount; } 227 LogicalPartition* LogicalPartitionAt(int32 index) const; 228 void AddLogicalPartition(LogicalPartition* partition); 229 void RemoveLogicalPartition( 230 LogicalPartition* partition); 231 232 private: 233 LogicalPartition* fHead; 234 LogicalPartition* fTail; 235 int32 fLogicalPartitionCount; 236 int32 fIndex; 237 }; 238 239 240 // LogicalPartition 241 class LogicalPartition : public Partition { 242 public: 243 LogicalPartition(); 244 LogicalPartition( 245 const partition_descriptor* descriptor, 246 off_t tableOffset, 247 PrimaryPartition* primary); 248 249 void SetTo(const partition_descriptor* descriptor, 250 off_t tableOffset, 251 PrimaryPartition* primary); 252 void SetTo(off_t offset, off_t size, uint8 type, 253 bool active, off_t tableOffset, 254 PrimaryPartition* primary); 255 void Unset(); 256 void GetPartitionDescriptor( 257 partition_descriptor* descriptor, 258 bool inner = false) const; 259 260 261 void SetPrimaryPartition(PrimaryPartition* primary) 262 { fPrimary = primary; } 263 PrimaryPartition* GetPrimaryPartition() const 264 { return fPrimary; } 265 266 void SetNext(LogicalPartition* next) 267 { fNext = next; } 268 LogicalPartition* Next() const 269 { return fNext; } 270 271 void SetPrevious(LogicalPartition* previous) 272 { fPrevious = previous; } 273 LogicalPartition* Previous() const 274 { return fPrevious; } 275 276 private: 277 PrimaryPartition* fPrimary; 278 LogicalPartition* fNext; 279 LogicalPartition* fPrevious; 280 }; 281 282 283 // PartitionMap 284 class PartitionMap { 285 public: 286 PartitionMap(); 287 ~PartitionMap(); 288 289 void Unset(); 290 291 status_t Assign(const PartitionMap& other); 292 293 PrimaryPartition* PrimaryPartitionAt(int32 index); 294 const PrimaryPartition* PrimaryPartitionAt(int32 index) const; 295 int32 IndexOfPrimaryPartition( 296 const PrimaryPartition* partition) const; 297 int32 CountNonEmptyPrimaryPartitions() const; 298 299 int32 ExtendedPartitionIndex() const; 300 301 int32 CountPartitions() const; 302 int32 CountNonEmptyPartitions() const; 303 Partition* PartitionAt(int32 index); 304 const Partition* PartitionAt(int32 index) const; 305 306 bool Check(off_t sessionSize) const; 307 const partition_type* GetNextSupportedPartitionType(uint32 cookie); 308 309 private: 310 PrimaryPartition fPrimaries[4]; 311 }; 312 313 #endif // _INTEL_PARTITION_MAP_H 314