#ifndef _INTEL_PARTITION_MAP_H
#define _INTEL_PARTITION_MAP_H
#include <SupportDefs.h>
#include <driver_settings.h>
#include <disk_device_types.h>
#ifndef _USER_MODE
# include <util/kernel_cpp.h>
#else
# include <new>
#endif
struct partition_type {
uint8 type;
const char* name;
bool used;
};
static inline bool
is_empty_type(uint8 type)
{
return type == 0x00;
}
static inline bool
is_extended_type(uint8 type)
{
return type == 0x05 || type == 0x0f || type == 0x85;
}
void get_partition_type_string(uint8 type, char* buffer);
struct chs {
uint8 cylinder;
uint16 head_sector;
void SetUnused() { cylinder = 0xFF; head_sector = 0xFFFF; }
void Unset() { cylinder = 0; head_sector = 0; }
} _PACKED;
struct partition_descriptor {
uint8 active;
chs begin;
uint8 type;
chs end;
uint32 start;
uint32 size;
bool is_empty() const { return is_empty_type(type); }
bool is_extended() const { return is_extended_type(type); }
} _PACKED;
struct partition_table {
char code_area[440];
uint32 disk_id;
uint16 reserved;
partition_descriptor table[4];
uint16 signature;
void clear_code_area()
{
memset(code_area, 0, sizeof(code_area));
}
void fill_code_area(const uint8* code, size_t size)
{
memcpy(code_area, code, min_c(sizeof(code_area), size));
}
} _PACKED;
static const uint16 kPartitionTableSectorSignature = 0xaa55;
class Partition;
class PrimaryPartition;
class LogicalPartition;
class PartitionType {
public:
PartitionType();
bool SetType(uint8 type);
bool SetType(const char* typeName);
bool SetContentType(const char* contentType);
bool IsValid() const { return fValid; }
bool IsEmpty() const { return is_empty_type(fType); }
bool IsExtended() const { return is_extended_type(fType); }
uint8 Type() const { return fType; }
bool FindNext();
void GetTypeString(char* buffer) const
{ get_partition_type_string(fType, buffer); }
private:
uint8 fType;
bool fValid;
};
class Partition {
public:
Partition();
Partition(const partition_descriptor* descriptor,
off_t tableOffset, off_t baseOffset,
uint32 blockSize);
void SetTo(const partition_descriptor* descriptor,
off_t tableOffset, off_t baseOffset,
uint32 blockSize);
void SetTo(off_t offset, off_t size, uint8 type,
bool active, off_t tableOffset,
uint32 blockSize);
void Unset();
bool IsEmpty() const
{ return is_empty_type(fType); }
bool IsExtended() const
{ return is_extended_type(fType); }
off_t PartitionTableOffset() const
{ return fPartitionTableOffset; }
off_t Offset() const { return fOffset; }
off_t Size() const { return fSize; }
uint8 Type() const { return fType; }
bool Active() const { return fActive; }
uint32 BlockSize() const { return fBlockSize; }
void GetTypeString(char* buffer) const
{ get_partition_type_string(fType, buffer); }
void SetPartitionTableOffset(off_t offset)
{ fPartitionTableOffset = offset; }
void SetOffset(off_t offset)
{ fOffset = offset; }
void SetSize(off_t size)
{ fSize = size; }
void SetType(uint8 type)
{ fType = type; }
void SetActive(bool active)
{ fActive = active; }
void SetBlockSize(uint32 blockSize)
{ fBlockSize = blockSize; }
bool CheckLocation(off_t sessionSize) const;
bool FitSizeToSession(off_t sessionSize);
private:
off_t fPartitionTableOffset;
off_t fOffset;
off_t fSize;
uint32 fBlockSize;
uint8 fType;
bool fActive;
};
class PrimaryPartition : public Partition {
public:
PrimaryPartition();
void SetTo(const partition_descriptor* descriptor,
off_t tableOffset, uint32 blockSize);
void SetTo(off_t offset, off_t size, uint8 type,
bool active, uint32 blockSize);
void Unset();
status_t Assign(const PrimaryPartition& other);
int32 Index() const { return fIndex; }
void SetIndex(int32 index) { fIndex = index; }
void GetPartitionDescriptor(
partition_descriptor* descriptor) const;
int32 CountLogicalPartitions() const
{ return fLogicalPartitionCount; }
LogicalPartition* LogicalPartitionAt(int32 index) const;
void AddLogicalPartition(LogicalPartition* partition);
void RemoveLogicalPartition(
LogicalPartition* partition);
private:
LogicalPartition* fHead;
LogicalPartition* fTail;
int32 fLogicalPartitionCount;
int32 fIndex;
};
class LogicalPartition : public Partition {
public:
LogicalPartition();
LogicalPartition(
const partition_descriptor* descriptor,
off_t tableOffset,
PrimaryPartition* primary);
void SetTo(const partition_descriptor* descriptor,
off_t tableOffset,
PrimaryPartition* primary);
void SetTo(off_t offset, off_t size, uint8 type,
bool active, off_t tableOffset,
PrimaryPartition* primary);
void Unset();
void GetPartitionDescriptor(
partition_descriptor* descriptor,
bool inner = false) const;
void SetPrimaryPartition(PrimaryPartition* primary)
{ fPrimary = primary; }
PrimaryPartition* GetPrimaryPartition() const
{ return fPrimary; }
void SetNext(LogicalPartition* next)
{ fNext = next; }
LogicalPartition* Next() const
{ return fNext; }
void SetPrevious(LogicalPartition* previous)
{ fPrevious = previous; }
LogicalPartition* Previous() const
{ return fPrevious; }
private:
PrimaryPartition* fPrimary;
LogicalPartition* fNext;
LogicalPartition* fPrevious;
};
class PartitionMap {
public:
PartitionMap();
~PartitionMap();
void Unset();
status_t Assign(const PartitionMap& other);
PrimaryPartition* PrimaryPartitionAt(int32 index);
const PrimaryPartition* PrimaryPartitionAt(int32 index) const;
int32 IndexOfPrimaryPartition(
const PrimaryPartition* partition) const;
int32 CountNonEmptyPrimaryPartitions() const;
int32 ExtendedPartitionIndex() const;
int32 CountPartitions() const;
int32 CountNonEmptyPartitions() const;
Partition* PartitionAt(int32 index);
const Partition* PartitionAt(int32 index) const;
bool Check(off_t sessionSize) const;
const partition_type* GetNextSupportedPartitionType(uint32 cookie);
private:
PrimaryPartition fPrimaries[4];
};
#endif