* Removed SECTOR_SIZE in the read-only part of the intel partition scanner;

however, it's still used in the write part.
* Made the read-only code block size agnostic. Only tested with an Apple
  iPod so far, and it recognizes its partition fine now. Next test on real
  hardware.
* Cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30155 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-04-14 12:33:01 +00:00
parent b41bbb4a46
commit 199f33248d
8 changed files with 248 additions and 226 deletions
@@ -100,8 +100,7 @@ static const struct partition_type kPartitionContentTypes[] = {
}; };
// partition_type_string static const char*
static const char *
partition_type_string(uint8 type) partition_type_string(uint8 type)
{ {
int32 i; int32 i;
@@ -113,48 +112,51 @@ partition_type_string(uint8 type)
return NULL; return NULL;
} }
// get_partition_type_string
void void
get_partition_type_string(uint8 type, char *buffer) get_partition_type_string(uint8 type, char* buffer)
{ {
if (buffer) { if (buffer) {
if (const char *str = partition_type_string(type)) if (const char* typeString = partition_type_string(type))
strcpy(buffer, str); strcpy(buffer, typeString);
else else
sprintf(buffer, "Unrecognized Type 0x%x", type); sprintf(buffer, "Unrecognized Type 0x%x", type);
} }
} }
static int static int
cmp_partition_offset(const void *p1, const void *p2) cmp_partition_offset(const void* p1, const void* p2)
{ {
const Partition *partition1 = *(const Partition**)p1; const Partition* partition1 = *(const Partition**)p1;
const Partition *partition2 = *(const Partition**)p2; const Partition* partition2 = *(const Partition**)p2;
if (partition1->Offset() < partition2->Offset()) if (partition1->Offset() < partition2->Offset())
return -1; return -1;
else if (partition1->Offset() > partition2->Offset()) if (partition1->Offset() > partition2->Offset())
return 1; return 1;
return 0; return 0;
} }
static int static int
cmp_offset(const void *o1, const void *o2) cmp_offset(const void* o1, const void* o2)
{ {
off_t offset1 = *static_cast<const off_t*>(o1); off_t offset1 = *static_cast<const off_t*>(o1);
off_t offset2 = *static_cast<const off_t*>(o2); off_t offset2 = *static_cast<const off_t*>(o2);
if (offset1 < offset2) if (offset1 < offset2)
return -1; return -1;
else if (offset1 > offset2) if (offset1 > offset2)
return 1; return 1;
return 0; return 0;
} }
static bool static bool
is_inside_partitions(off_t location, const Partition **partitions, int32 count) is_inside_partitions(off_t location, const Partition** partitions, int32 count)
{ {
bool result = false; bool result = false;
if (count > 0) { if (count > 0) {
@@ -180,16 +182,15 @@ is_inside_partitions(off_t location, const Partition **partitions, int32 count)
// #pragma mark - PartitionType // #pragma mark - PartitionType
// constructor
PartitionType::PartitionType() PartitionType::PartitionType()
: fType(0), :
fValid(false) fType(0),
fValid(false)
{ {
} }
// SetType
/*! /*! \brief Sets the \a type via its ID.
\brief Sets the \a type via its ID.
\param type ID of the partition type, it is in the range [0..255]. \param type ID of the partition type, it is in the range [0..255].
*/ */
bool bool
@@ -200,9 +201,8 @@ PartitionType::SetType(uint8 type)
return fValid; return fValid;
} }
// SetType
/*! /*! \brief Sets the type via its string name.
\brief Sets the type via its string name.
\param typeName Name of the partition type. \param typeName Name of the partition type.
*/ */
bool bool
@@ -219,9 +219,8 @@ PartitionType::SetType(const char *typeName)
return fValid; return fValid;
} }
// SetContentType
/*! /*! \brief Converts content type to the partition type that fits best.
\brief Converts content type to the partition type that fits best.
\param content_type Name of the content type, it is standardized by system. \param content_type Name of the content type, it is standardized by system.
*/ */
bool bool
@@ -238,9 +237,8 @@ PartitionType::SetContentType(const char *contentType)
return fValid; return fValid;
} }
// FindNext
/*! /*! \brief Finds next supported partition.
\brief Finds next supported partition.
*/ */
bool bool
PartitionType::FindNext() PartitionType::FindNext()
@@ -257,28 +255,23 @@ PartitionType::FindNext()
} }
/*! /*! \fn bool PartitionType::IsValid() const
\fn bool PartitionType::IsValid() const
\brief Check whether the current type is valid. \brief Check whether the current type is valid.
*/ */
/*! /*! \fn bool PartitionType::IsEmpty() const
\fn bool PartitionType::IsEmpty() const
\brief Check whether the current type describes empty type. \brief Check whether the current type describes empty type.
*/ */
/*! /*! \fn bool PartitionType::IsExtended() const
\fn bool PartitionType::IsExtended() const
\brief Check whether the current type describes extended partition type. \brief Check whether the current type describes extended partition type.
*/ */
/*! /*! \fn uint8 PartitionType::Type() const
\fn uint8 PartitionType::Type() const
\brief Returns ID of the current type. \brief Returns ID of the current type.
*/ */
/*! /*! \fn void PartitionType::GetTypeString(char *buffer) const
\fn void PartitionType::GetTypeString(char *buffer) const
\brief Returns string name of the current type. \brief Returns string name of the current type.
\param buffer Buffer where the name is stored, has to be allocated with \param buffer Buffer where the name is stored, has to be allocated with
sufficient length. sufficient length.
@@ -288,7 +281,6 @@ PartitionType::FindNext()
// #pragma mark - Partition // #pragma mark - Partition
// constructor
Partition::Partition() Partition::Partition()
: :
fPartitionTableOffset(0), fPartitionTableOffset(0),
@@ -299,9 +291,9 @@ Partition::Partition()
{ {
} }
// constructor
Partition::Partition(const partition_descriptor* descriptor, off_t tableOffset, Partition::Partition(const partition_descriptor* descriptor, off_t tableOffset,
off_t baseOffset) off_t baseOffset, uint32 blockSize)
: :
fPartitionTableOffset(0), fPartitionTableOffset(0),
fOffset(0), fOffset(0),
@@ -309,40 +301,37 @@ Partition::Partition(const partition_descriptor* descriptor, off_t tableOffset,
fType(0), fType(0),
fActive(false) fActive(false)
{ {
SetTo(descriptor, tableOffset, baseOffset); SetTo(descriptor, tableOffset, baseOffset, blockSize);
} }
// SetTo
void void
Partition::SetTo(const partition_descriptor *descriptor, off_t tableOffset, Partition::SetTo(const partition_descriptor *descriptor, off_t tableOffset,
off_t baseOffset) off_t baseOffset, uint32 blockSize)
{ {
TRACE(("Partition::SetTo(): active: %x\n", descriptor->active)); TRACE(("Partition::SetTo(): active: %x\n", descriptor->active));
SetTo(baseOffset + (off_t)descriptor->start * SECTOR_SIZE, SetTo(baseOffset + (off_t)descriptor->start * blockSize,
(off_t)descriptor->size * SECTOR_SIZE, (off_t)descriptor->size * blockSize, descriptor->type,
descriptor->type, descriptor->active, tableOffset, blockSize);
descriptor->active,
tableOffset);
} }
// SetTo
void void
Partition::SetTo(off_t offset, off_t size, uint8 type, bool active, Partition::SetTo(off_t offset, off_t size, uint8 type, bool active,
off_t tableOffset) off_t tableOffset, uint32 blockSize)
{ {
fPartitionTableOffset = tableOffset; fPartitionTableOffset = tableOffset;
fOffset = offset; fOffset = offset;
fSize = size; fSize = size;
fType = type; fType = type;
fActive = active; fActive = active;
fBlockSize = blockSize;
if (fSize == 0) if (fSize == 0)
Unset(); Unset();
} }
// Unset
void void
Partition::Unset() Partition::Unset()
{ {
@@ -353,13 +342,13 @@ Partition::Unset()
fActive = false; fActive = false;
} }
// GetPartitionDescriptor
void void
Partition::GetPartitionDescriptor(partition_descriptor *descriptor, Partition::GetPartitionDescriptor(partition_descriptor *descriptor,
off_t baseOffset) const off_t baseOffset) const
{ {
descriptor->start = (fOffset - baseOffset) / SECTOR_SIZE; descriptor->start = (fOffset - baseOffset) / fBlockSize;
descriptor->size = fSize / SECTOR_SIZE; descriptor->size = fSize / fBlockSize;
descriptor->type = fType; descriptor->type = fType;
descriptor->active = fActive ? 0x80 : 0x00; descriptor->active = fActive ? 0x80 : 0x00;
descriptor->begin.Unset(); descriptor->begin.Unset();
@@ -385,17 +374,17 @@ Partition::CheckLocation(off_t sessionSize) const
{ {
// offsets and size must be block aligned, partition table and partition must // offsets and size must be block aligned, partition table and partition must
// lie within the session // lie within the session
if (fPartitionTableOffset % SECTOR_SIZE != 0) { if (fPartitionTableOffset % fBlockSize != 0) {
TRACE(("Partition::CheckLocation() - bad partition table offset: %lld " TRACE(("Partition::CheckLocation() - bad partition table offset: %lld "
"(session: %lld)\n", fPartitionTableOffset, sessionSize)); "(session: %lld)\n", fPartitionTableOffset, sessionSize));
return false; return false;
} }
if (fOffset % SECTOR_SIZE != 0) { if (fOffset % fBlockSize != 0) {
TRACE(("Partition::CheckLocation() - bad offset: %lld " TRACE(("Partition::CheckLocation() - bad offset: %lld "
"(session: %lld)\n", fOffset, sessionSize)); "(session: %lld)\n", fOffset, sessionSize));
return false; return false;
} }
if (fSize % SECTOR_SIZE != 0) { if (fSize % fBlockSize != 0) {
TRACE(("Partition::CheckLocation() - bad size: %lld " TRACE(("Partition::CheckLocation() - bad size: %lld "
"(session: %lld)\n", fSize, sessionSize)); "(session: %lld)\n", fSize, sessionSize));
return false; return false;
@@ -423,35 +412,33 @@ Partition::CheckLocation(off_t sessionSize) const
// #pragma mark - PrimaryPartition // #pragma mark - PrimaryPartition
// constructor
PrimaryPartition::PrimaryPartition() PrimaryPartition::PrimaryPartition()
: Partition(), : Partition(),
fHead(NULL), fHead(NULL),
fTail(NULL), fTail(NULL),
fLogicalPartitionCount(0) fLogicalPartitionCount(0)
{ {
} }
// SetTo
void void
PrimaryPartition::SetTo(const partition_descriptor* descriptor, PrimaryPartition::SetTo(const partition_descriptor* descriptor,
off_t tableOffset) off_t tableOffset, uint32 blockSize)
{ {
Unset(); Unset();
Partition::SetTo(descriptor, tableOffset, 0); Partition::SetTo(descriptor, tableOffset, 0, blockSize);
} }
// SetTo
void void
PrimaryPartition::SetTo(off_t offset, off_t size, uint8 type, bool active) PrimaryPartition::SetTo(off_t offset, off_t size, uint8 type, bool active,
uint32 blockSize)
{ {
Unset(); Unset();
Partition::SetTo(offset, size, type, active, 0); Partition::SetTo(offset, size, type, active, 0, blockSize);
} }
// Unset
void void
PrimaryPartition::Unset() PrimaryPartition::Unset()
{ {
@@ -466,13 +453,12 @@ PrimaryPartition::Unset()
} }
// Assign
status_t status_t
PrimaryPartition::Assign(const PrimaryPartition& other) PrimaryPartition::Assign(const PrimaryPartition& other)
{ {
partition_descriptor descriptor; partition_descriptor descriptor;
other.GetPartitionDescriptor(&descriptor, 0); other.GetPartitionDescriptor(&descriptor, 0);
SetTo(&descriptor, 0); SetTo(&descriptor, 0, other.BlockSize());
const LogicalPartition* otherLogical = other.fHead; const LogicalPartition* otherLogical = other.fHead;
while (otherLogical) { while (otherLogical) {
@@ -493,8 +479,7 @@ PrimaryPartition::Assign(const PrimaryPartition& other)
} }
// LogicalPartitionAt LogicalPartition*
LogicalPartition *
PrimaryPartition::LogicalPartitionAt(int32 index) const PrimaryPartition::LogicalPartitionAt(int32 index) const
{ {
LogicalPartition *partition = NULL; LogicalPartition *partition = NULL;
@@ -505,9 +490,9 @@ PrimaryPartition::LogicalPartitionAt(int32 index) const
return partition; return partition;
} }
// AddLogicalPartition
void void
PrimaryPartition::AddLogicalPartition(LogicalPartition *partition) PrimaryPartition::AddLogicalPartition(LogicalPartition* partition)
{ {
if (!partition) if (!partition)
return; return;
@@ -519,17 +504,19 @@ PrimaryPartition::AddLogicalPartition(LogicalPartition *partition)
fTail = partition; fTail = partition;
} else } else
fHead = fTail = partition; fHead = fTail = partition;
partition->SetNext(NULL); partition->SetNext(NULL);
fLogicalPartitionCount++; fLogicalPartitionCount++;
} }
// RemoveLogicalPartition
void void
PrimaryPartition::RemoveLogicalPartition(LogicalPartition *partition) PrimaryPartition::RemoveLogicalPartition(LogicalPartition* partition)
{ {
if (!partition || partition->GetPrimaryPartition() != this) if (!partition || partition->GetPrimaryPartition() != this)
return; return;
LogicalPartition *prev = partition->Previous(); LogicalPartition *prev = partition->Previous();
LogicalPartition *next = partition->Next(); LogicalPartition *next = partition->Next();
@@ -553,30 +540,29 @@ PrimaryPartition::RemoveLogicalPartition(LogicalPartition *partition)
// #pragma mark - LogicalPartition // #pragma mark - LogicalPartition
// constructor
LogicalPartition::LogicalPartition() LogicalPartition::LogicalPartition()
: Partition(), : Partition(),
fPrimary(NULL), fPrimary(NULL),
fNext(NULL), fNext(NULL),
fPrevious(NULL) fPrevious(NULL)
{ {
} }
// constructor
LogicalPartition::LogicalPartition(const partition_descriptor *descriptor, LogicalPartition::LogicalPartition(const partition_descriptor* descriptor,
off_t tableOffset, PrimaryPartition *primary) off_t tableOffset, PrimaryPartition* primary)
: Partition(), : Partition(),
fPrimary(NULL), fPrimary(NULL),
fNext(NULL), fNext(NULL),
fPrevious(NULL) fPrevious(NULL)
{ {
SetTo(descriptor, tableOffset, primary); SetTo(descriptor, tableOffset, primary);
} }
// SetTo
void void
LogicalPartition::SetTo(const partition_descriptor *descriptor, LogicalPartition::SetTo(const partition_descriptor* descriptor,
off_t tableOffset, PrimaryPartition *primary) off_t tableOffset, PrimaryPartition* primary)
{ {
Unset(); Unset();
if (descriptor && primary) { if (descriptor && primary) {
@@ -593,26 +579,26 @@ LogicalPartition::SetTo(const partition_descriptor *descriptor,
// baseOffset. // baseOffset.
off_t baseOffset = descriptor->is_extended() off_t baseOffset = descriptor->is_extended()
? primary->Offset() : tableOffset; ? primary->Offset() : tableOffset;
Partition::SetTo(descriptor, tableOffset, baseOffset); Partition::SetTo(descriptor, tableOffset, baseOffset,
primary->BlockSize());
fPrimary = primary; fPrimary = primary;
} }
} }
// SetTo
void void
LogicalPartition::SetTo(off_t offset, off_t size, uint8 type, bool active, LogicalPartition::SetTo(off_t offset, off_t size, uint8 type, bool active,
off_t tableOffset, PrimaryPartition *primary) off_t tableOffset, PrimaryPartition *primary)
{ {
Unset(); Unset();
if (primary) { if (primary) {
Partition::SetTo(offset, size, type, active, tableOffset); Partition::SetTo(offset, size, type, active, tableOffset,
primary->BlockSize());
fPrimary = primary; fPrimary = primary;
} }
} }
// Unset
void void
LogicalPartition::Unset() LogicalPartition::Unset()
{ {
@@ -626,7 +612,6 @@ LogicalPartition::Unset()
// #pragma mark - PartitionMap // #pragma mark - PartitionMap
// constructor
PartitionMap::PartitionMap() PartitionMap::PartitionMap()
{ {
for (int32 i = 0; i < 4; i++) for (int32 i = 0; i < 4; i++)
@@ -634,13 +619,11 @@ PartitionMap::PartitionMap()
} }
// destructor
PartitionMap::~PartitionMap() PartitionMap::~PartitionMap()
{ {
} }
// Unset
void void
PartitionMap::Unset() PartitionMap::Unset()
{ {
@@ -649,7 +632,6 @@ PartitionMap::Unset()
} }
// Assign
status_t status_t
PartitionMap::Assign(const PartitionMap& other) PartitionMap::Assign(const PartitionMap& other)
{ {
@@ -663,7 +645,6 @@ PartitionMap::Assign(const PartitionMap& other)
} }
// PrimaryPartitionAt
PrimaryPartition* PrimaryPartition*
PartitionMap::PrimaryPartitionAt(int32 index) PartitionMap::PrimaryPartitionAt(int32 index)
{ {
@@ -674,7 +655,6 @@ PartitionMap::PrimaryPartitionAt(int32 index)
} }
// PrimaryPartitionAt
const PrimaryPartition* const PrimaryPartition*
PartitionMap::PrimaryPartitionAt(int32 index) const PartitionMap::PrimaryPartitionAt(int32 index) const
{ {
@@ -685,7 +665,6 @@ PartitionMap::PrimaryPartitionAt(int32 index) const
} }
// CountNonEmptyPrimaryPartitions
int32 int32
PartitionMap::CountNonEmptyPrimaryPartitions() const PartitionMap::CountNonEmptyPrimaryPartitions() const
{ {
@@ -699,7 +678,6 @@ PartitionMap::CountNonEmptyPrimaryPartitions() const
} }
// ExtendedPartitionIndex
int32 int32
PartitionMap::ExtendedPartitionIndex() const PartitionMap::ExtendedPartitionIndex() const
{ {
@@ -712,7 +690,6 @@ PartitionMap::ExtendedPartitionIndex() const
} }
// CountPartitions
int32 int32
PartitionMap::CountPartitions() const PartitionMap::CountPartitions() const
{ {
@@ -723,7 +700,6 @@ PartitionMap::CountPartitions() const
} }
// CountNonEmptyPartitions
int32 int32
PartitionMap::CountNonEmptyPartitions() const PartitionMap::CountNonEmptyPartitions() const
{ {
@@ -737,7 +713,6 @@ PartitionMap::CountNonEmptyPartitions() const
} }
// PartitionAt
Partition* Partition*
PartitionMap::PartitionAt(int32 index) PartitionMap::PartitionAt(int32 index)
{ {
@@ -760,7 +735,6 @@ PartitionMap::PartitionAt(int32 index)
} }
// PartitionAt
const Partition* const Partition*
PartitionMap::PartitionAt(int32 index) const PartitionMap::PartitionAt(int32 index) const
{ {
@@ -768,7 +742,6 @@ PartitionMap::PartitionAt(int32 index) const
} }
// Check
bool bool
PartitionMap::Check(off_t sessionSize) const PartitionMap::Check(off_t sessionSize) const
{ {
@@ -26,10 +26,6 @@
#define INTEL_EXTENDED_PARTITION_NAME "Intel Extended Partition" #define INTEL_EXTENDED_PARTITION_NAME "Intel Extended Partition"
#define BFS_NAME "BFS Filesystem" #define BFS_NAME "BFS Filesystem"
enum {
SECTOR_SIZE = 512
};
// is_empty_type // is_empty_type
static inline bool static inline bool
@@ -128,141 +124,172 @@ private:
// Partition // Partition
class Partition { class Partition {
public: public:
Partition(); Partition();
Partition(const partition_descriptor *descriptor, off_t ptsOffset, Partition(const partition_descriptor* descriptor,
off_t baseOffset); off_t tableOffset, off_t baseOffset,
uint32 blockSize);
void SetTo(const partition_descriptor *descriptor, off_t ptsOffset, void SetTo(const partition_descriptor* descriptor,
off_t baseOffset); off_t tableOffset, off_t baseOffset,
void SetTo(off_t offset, off_t size, uint8 type, bool active, uint32 blockSize);
off_t ptsOffset); void SetTo(off_t offset, off_t size, uint8 type,
void Unset(); bool active, off_t tableOffset,
uint32 blockSize);
void Unset();
bool IsEmpty() const { return is_empty_type(fType); } bool IsEmpty() const
bool IsExtended() const { return is_extended_type(fType); } { return is_empty_type(fType); }
bool IsExtended() const
{ return is_extended_type(fType); }
// NOTE: Both PartitionTableOffset() and Offset() are absolute with regards to the // NOTE: Both PartitionTableOffset() and Offset() are absolute with regards
// session (usually the disk). Ie, for all primary partitions, including // to the session (usually the disk). Ie, for all primary partitions,
// the primary extended partition, the PartitionTableOffset() points to the MBR (0). // including the primary extended partition, the PartitionTableOffset()
// For logical partitions, the PartitionTableOffset() is located within the primary // points to the MBR (0).
// extended partition, but again, the returned values are absolute with // For logical partitions, the PartitionTableOffset() is located within the
// regards to the session. All values are expressed in bytes. // primary extended partition, but again, the returned values are absolute
off_t PartitionTableOffset() const { return fPartitionTableOffset; } // with regards to the session. All values are expressed in bytes.
// offset of the sector containing the descriptor for this partition off_t PartitionTableOffset() const
off_t Offset() const { return fOffset; } { return fPartitionTableOffset; }
// start offset of the partition contents // offset of the partition table
off_t Size() const { return fSize; } off_t Offset() const { return fOffset; }
uint8 Type() const { return fType; } // start offset of the partition contents
bool Active() const { return fActive; } off_t Size() const { return fSize; }
void GetTypeString(char *buffer) const uint8 Type() const { return fType; }
{ get_partition_type_string(fType, buffer); } bool Active() const { return fActive; }
void GetPartitionDescriptor(partition_descriptor *descriptor, uint32 BlockSize() const { return fBlockSize; }
off_t baseOffset) const; void GetTypeString(char *buffer) const
{ get_partition_type_string(fType, buffer); }
void GetPartitionDescriptor(
partition_descriptor* descriptor,
off_t baseOffset) const;
void SetPartitionTableOffset(off_t offset) { fPartitionTableOffset = offset; } void SetPartitionTableOffset(off_t offset)
void SetOffset(off_t offset) { fOffset = offset; } { fPartitionTableOffset = offset; }
void SetSize(off_t size) { fSize = size; } void SetOffset(off_t offset)
void SetType(uint8 type) { fType = type; } { fOffset = offset; }
void SetActive(bool active) { fActive = active; } void SetSize(off_t size)
{ fSize = size; }
void SetType(uint8 type)
{ fType = type; }
void SetActive(bool active)
{ fActive = active; }
bool CheckLocation(off_t sessionSize) const; bool CheckLocation(off_t sessionSize) const;
#ifdef _BOOT_MODE #ifdef _BOOT_MODE
void AdjustSize(off_t sessionSize); void AdjustSize(off_t sessionSize);
#endif #endif
private: private:
off_t fPartitionTableOffset; off_t fPartitionTableOffset;
off_t fOffset; // relative to the start of the session off_t fOffset;
off_t fSize; // relative to the start of the session
uint8 fType; off_t fSize;
bool fActive; uint32 fBlockSize;
uint8 fType;
bool fActive;
}; };
// PrimaryPartition // PrimaryPartition
class PrimaryPartition : public Partition { class PrimaryPartition : public Partition {
public: public:
PrimaryPartition(); PrimaryPartition();
void SetTo(const partition_descriptor *descriptor, off_t ptsOffset); void SetTo(const partition_descriptor* descriptor,
void SetTo(off_t offset, off_t size, uint8 type, bool active); off_t tableOffset, uint32 blockSize);
void Unset(); void SetTo(off_t offset, off_t size, uint8 type,
bool active, uint32 blockSize);
void Unset();
status_t Assign(const PrimaryPartition& other); status_t Assign(const PrimaryPartition& other);
int32 Index() const { return fIndex; } int32 Index() const { return fIndex; }
void SetIndex(int32 index) { fIndex = index; } void SetIndex(int32 index) { fIndex = index; }
// private // private
// only if extended // only if extended
int32 CountLogicalPartitions() const { return fLogicalPartitionCount; } int32 CountLogicalPartitions() const
LogicalPartition *LogicalPartitionAt(int32 index) const; { return fLogicalPartitionCount; }
void AddLogicalPartition(LogicalPartition *partition); LogicalPartition* LogicalPartitionAt(int32 index) const;
void RemoveLogicalPartition(LogicalPartition *partition); void AddLogicalPartition(LogicalPartition* partition);
void RemoveLogicalPartition(
LogicalPartition* partition);
private: private:
LogicalPartition *fHead; LogicalPartition* fHead;
LogicalPartition *fTail; LogicalPartition* fTail;
int32 fLogicalPartitionCount; int32 fLogicalPartitionCount;
int32 fIndex; int32 fIndex;
}; };
// LogicalPartition // LogicalPartition
class LogicalPartition : public Partition { class LogicalPartition : public Partition {
public: public:
LogicalPartition(); LogicalPartition();
LogicalPartition(const partition_descriptor *descriptor, off_t ptsOffset, LogicalPartition(
PrimaryPartition *primary); const partition_descriptor* descriptor,
off_t tableOffset,
PrimaryPartition *primary);
void SetTo(const partition_descriptor *descriptor, off_t ptsOffset, void SetTo(const partition_descriptor* descriptor,
PrimaryPartition *primary); off_t tableOffset,
void SetTo(off_t offset, off_t size, uint8 type, bool active, PrimaryPartition* primary);
off_t ptsOffset, PrimaryPartition *primary); void SetTo(off_t offset, off_t size, uint8 type,
void Unset(); bool active, off_t tableOffset,
PrimaryPartition* primary);
void Unset();
void SetPrimaryPartition(PrimaryPartition *primary) { fPrimary = primary; } void SetPrimaryPartition(PrimaryPartition* primary)
PrimaryPartition *GetPrimaryPartition() const { return fPrimary; } { fPrimary = primary; }
PrimaryPartition* GetPrimaryPartition() const
{ return fPrimary; }
void SetNext(LogicalPartition *next) { fNext = next; } void SetNext(LogicalPartition* next)
LogicalPartition *Next() const { return fNext; } { fNext = next; }
LogicalPartition* Next() const
{ return fNext; }
void SetPrevious(LogicalPartition *previous) { fPrevious = previous; } void SetPrevious(LogicalPartition* previous)
LogicalPartition *Previous() const { return fPrevious; } { fPrevious = previous; }
LogicalPartition* Previous() const
{ return fPrevious; }
private: private:
PrimaryPartition *fPrimary; PrimaryPartition* fPrimary;
LogicalPartition *fNext; LogicalPartition* fNext;
LogicalPartition *fPrevious; LogicalPartition* fPrevious;
}; };
// PartitionMap // PartitionMap
class PartitionMap { class PartitionMap {
public: public:
PartitionMap(); PartitionMap();
~PartitionMap(); ~PartitionMap();
void Unset(); void Unset();
status_t Assign(const PartitionMap& other); status_t Assign(const PartitionMap& other);
PrimaryPartition *PrimaryPartitionAt(int32 index); PrimaryPartition* PrimaryPartitionAt(int32 index);
const PrimaryPartition *PrimaryPartitionAt(int32 index) const; const PrimaryPartition* PrimaryPartitionAt(int32 index) const;
int32 IndexOfPrimaryPartition(const PrimaryPartition* partition) const; int32 IndexOfPrimaryPartition(
int32 CountNonEmptyPrimaryPartitions() const; const PrimaryPartition* partition) const;
int32 CountNonEmptyPrimaryPartitions() const;
int32 ExtendedPartitionIndex() const; int32 ExtendedPartitionIndex() const;
int32 CountPartitions() const; int32 CountPartitions() const;
int32 CountNonEmptyPartitions() const; int32 CountNonEmptyPartitions() const;
Partition *PartitionAt(int32 index); Partition* PartitionAt(int32 index);
const Partition *PartitionAt(int32 index) const; const Partition* PartitionAt(int32 index) const;
bool Check(off_t sessionSize) const; bool Check(off_t sessionSize) const;
private: private:
PrimaryPartition fPrimaries[4]; PrimaryPartition fPrimaries[4];
}; };
#endif // _INTEL_PARTITION_MAP_H #endif // _INTEL_PARTITION_MAP_H
@@ -41,9 +41,10 @@ static const int32 kMaxLogicalPartitionCount = 128;
// constructor // constructor
PartitionMapParser::PartitionMapParser(int deviceFD, off_t sessionOffset, PartitionMapParser::PartitionMapParser(int deviceFD, off_t sessionOffset,
off_t sessionSize) off_t sessionSize, uint32 blockSize)
: :
fDeviceFD(deviceFD), fDeviceFD(deviceFD),
fBlockSize(blockSize),
fSessionOffset(sessionOffset), fSessionOffset(sessionOffset),
fSessionSize(sessionSize), fSessionSize(sessionSize),
fPartitionTable(NULL), fPartitionTable(NULL),
@@ -105,9 +106,9 @@ PartitionMapParser::_ParsePrimary(const partition_table* table)
// examine the table // examine the table
for (int32 i = 0; i < 4; i++) { for (int32 i = 0; i < 4; i++) {
const partition_descriptor *descriptor = &table->table[i]; const partition_descriptor* descriptor = &table->table[i];
PrimaryPartition *partition = fMap->PrimaryPartitionAt(i); PrimaryPartition* partition = fMap->PrimaryPartitionAt(i);
partition->SetTo(descriptor, 0); partition->SetTo(descriptor, 0, fBlockSize);
#ifdef _BOOT_MODE #ifdef _BOOT_MODE
// work-around potential BIOS problems // work-around potential BIOS problems
@@ -28,7 +28,8 @@ struct partition_table;
class PartitionMapParser { class PartitionMapParser {
public: public:
PartitionMapParser(int deviceFD, PartitionMapParser(int deviceFD,
off_t sessionOffset, off_t sessionSize); off_t sessionOffset, off_t sessionSize,
uint32 blockSize);
~PartitionMapParser(); ~PartitionMapParser();
status_t Parse(const uint8* block, PartitionMap* map); status_t Parse(const uint8* block, PartitionMap* map);
@@ -45,6 +46,7 @@ private:
private: private:
int fDeviceFD; int fDeviceFD;
uint32 fBlockSize;
off_t fSessionOffset; off_t fSessionOffset;
off_t fSessionSize; off_t fSessionSize;
partition_table* fPartitionTable; // while parsing partition_table* fPartitionTable; // while parsing
@@ -34,6 +34,10 @@ using std::nothrow;
#endif #endif
// TODO: get rid of this - there is no such thing as a fixed sector size!
static const uint32 SECTOR_SIZE = 512;
// constructor // constructor
/*! \brief Creates the writer. /*! \brief Creates the writer.
@@ -1,5 +1,5 @@
/* /*
* Copyright 2003-2008, Haiku, Inc. All Rights Reserved. * Copyright 2003-2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -132,7 +132,7 @@ pm_identify_partition(int fd, partition_data *partition, void **cookie)
return -1; return -1;
// read the partition structure // read the partition structure
PartitionMapParser parser(fd, 0, partition->size); PartitionMapParser parser(fd, 0, partition->size, partition->block_size);
status_t error = parser.Parse(NULL, map); status_t error = parser.Parse(NULL, map);
if (error != B_OK) { if (error != B_OK) {
// cleanup, if not detected // cleanup, if not detected
@@ -173,6 +173,7 @@ pm_identify_partition(int fd, partition_data *partition, void **cookie)
return -1; return -1;
} }
// pm_scan_partition // pm_scan_partition
static status_t static status_t
pm_scan_partition(int fd, partition_data *partition, void *cookie) pm_scan_partition(int fd, partition_data *partition, void *cookie)
@@ -192,7 +193,6 @@ pm_scan_partition(int fd, partition_data *partition, void *cookie)
partition->content_size = partition->size; partition->content_size = partition->size;
// (no content_name and content_parameters) // (no content_name and content_parameters)
// (content_type is set by the system) // (content_type is set by the system)
partition->block_size = SECTOR_SIZE;
partition->content_cookie = map; partition->content_cookie = map;
// children // children
@@ -202,7 +202,7 @@ pm_scan_partition(int fd, partition_data *partition, void *cookie)
PrimaryPartition *primary = map->PrimaryPartitionAt(i); PrimaryPartition *primary = map->PrimaryPartitionAt(i);
if (!primary->IsEmpty()) { if (!primary->IsEmpty()) {
partition_data *child = create_child_partition(partition->id, partition_data *child = create_child_partition(partition->id,
index, -1); index, -1);
index++; index++;
if (!child) { if (!child) {
// something went wrong // something went wrong
@@ -212,7 +212,8 @@ pm_scan_partition(int fd, partition_data *partition, void *cookie)
child->offset = partition->offset + primary->Offset(); child->offset = partition->offset + primary->Offset();
child->size = primary->Size(); child->size = primary->Size();
child->block_size = SECTOR_SIZE; child->block_size = partition->block_size;
// (no name) // (no name)
char type[B_FILE_NAME_LENGTH]; char type[B_FILE_NAME_LENGTH];
primary->GetTypeString(type); primary->GetTypeString(type);
@@ -220,7 +221,7 @@ pm_scan_partition(int fd, partition_data *partition, void *cookie)
// parameters // parameters
char buffer[128]; char buffer[128];
sprintf(buffer, "type = %u ; active = %d", primary->Type(), sprintf(buffer, "type = %u ; active = %d", primary->Type(),
primary->Active()); primary->Active());
child->parameters = strdup(buffer); child->parameters = strdup(buffer);
child->cookie = primary; child->cookie = primary;
// check for allocation problems // check for allocation problems
@@ -245,6 +246,7 @@ pm_scan_partition(int fd, partition_data *partition, void *cookie)
return error; return error;
} }
// pm_free_identify_partition_cookie // pm_free_identify_partition_cookie
static void static void
pm_free_identify_partition_cookie(partition_data */*partition*/, void *cookie) pm_free_identify_partition_cookie(partition_data */*partition*/, void *cookie)
@@ -256,6 +258,7 @@ pm_free_identify_partition_cookie(partition_data */*partition*/, void *cookie)
} }
} }
// pm_free_partition_cookie // pm_free_partition_cookie
static void static void
pm_free_partition_cookie(partition_data *partition) pm_free_partition_cookie(partition_data *partition)
@@ -266,6 +269,7 @@ pm_free_partition_cookie(partition_data *partition)
partition->cookie = NULL; partition->cookie = NULL;
} }
// pm_free_partition_content_cookie // pm_free_partition_content_cookie
static void static void
pm_free_partition_content_cookie(partition_data *partition) pm_free_partition_content_cookie(partition_data *partition)
@@ -276,6 +280,7 @@ pm_free_partition_content_cookie(partition_data *partition)
} }
} }
// #pragma mark - Intel Extended Partition Module // #pragma mark - Intel Extended Partition Module
@@ -292,6 +297,7 @@ ep_std_ops(int32 op, ...)
return B_ERROR; return B_ERROR;
} }
// ep_identify_partition // ep_identify_partition
static float static float
ep_identify_partition(int fd, partition_data *partition, void **cookie) ep_identify_partition(int fd, partition_data *partition, void **cookie)
@@ -319,6 +325,7 @@ ep_identify_partition(int fd, partition_data *partition, void **cookie)
return 0.95; return 0.95;
} }
// ep_scan_partition // ep_scan_partition
static status_t static status_t
ep_scan_partition(int fd, partition_data *partition, void *cookie) ep_scan_partition(int fd, partition_data *partition, void *cookie)
@@ -340,7 +347,6 @@ ep_scan_partition(int fd, partition_data *partition, void *cookie)
partition->content_size = partition->size; partition->content_size = partition->size;
// (no content_name and content_parameters) // (no content_name and content_parameters)
// (content_type is set by the system) // (content_type is set by the system)
partition->block_size = SECTOR_SIZE;
partition->content_cookie = primary; partition->content_cookie = primary;
// children // children
@@ -348,8 +354,7 @@ ep_scan_partition(int fd, partition_data *partition, void *cookie)
int32 index = 0; int32 index = 0;
for (int32 i = 0; i < primary->CountLogicalPartitions(); i++) { for (int32 i = 0; i < primary->CountLogicalPartitions(); i++) {
LogicalPartition *logical = primary->LogicalPartitionAt(i); LogicalPartition *logical = primary->LogicalPartitionAt(i);
partition_data *child = create_child_partition(partition->id, partition_data *child = create_child_partition(partition->id, index, -1);
index, -1);
index++; index++;
if (!child) { if (!child) {
// something went wrong // something went wrong
@@ -360,7 +365,8 @@ ep_scan_partition(int fd, partition_data *partition, void *cookie)
} }
child->offset = parent->offset + logical->Offset(); child->offset = parent->offset + logical->Offset();
child->size = logical->Size(); child->size = logical->Size();
child->block_size = SECTOR_SIZE; child->block_size = partition->block_size;
// (no name) // (no name)
char type[B_FILE_NAME_LENGTH]; char type[B_FILE_NAME_LENGTH];
logical->GetTypeString(type); logical->GetTypeString(type);
@@ -380,6 +386,7 @@ ep_scan_partition(int fd, partition_data *partition, void *cookie)
break; break;
} }
} }
// cleanup on error // cleanup on error
if (error != B_OK) { if (error != B_OK) {
partition->content_cookie = NULL; partition->content_cookie = NULL;
@@ -391,6 +398,7 @@ ep_scan_partition(int fd, partition_data *partition, void *cookie)
return error; return error;
} }
// ep_free_identify_partition_cookie // ep_free_identify_partition_cookie
static void static void
ep_free_identify_partition_cookie(partition_data *partition, void *cookie) ep_free_identify_partition_cookie(partition_data *partition, void *cookie)
@@ -398,6 +406,7 @@ ep_free_identify_partition_cookie(partition_data *partition, void *cookie)
// nothing to do // nothing to do
} }
// ep_free_partition_cookie // ep_free_partition_cookie
static void static void
ep_free_partition_cookie(partition_data *partition) ep_free_partition_cookie(partition_data *partition)
@@ -407,6 +416,7 @@ ep_free_partition_cookie(partition_data *partition)
partition->cookie = NULL; partition->cookie = NULL;
} }
// ep_free_partition_content_cookie // ep_free_partition_content_cookie
static void static void
ep_free_partition_content_cookie(partition_data *partition) ep_free_partition_content_cookie(partition_data *partition)
@@ -32,6 +32,9 @@
//#define TRACE(x) ; //#define TRACE(x) ;
#define TRACE(x) dprintf x #define TRACE(x) dprintf x
// TODO: get rid of this - there is no such thing as a fixed sector size!
static const uint32 SECTOR_SIZE = 512;
// Maximal size of move buffer (in sectors). // Maximal size of move buffer (in sectors).
static const int32 MAX_MOVE_BUFFER = 2 * 1024 * 4; static const int32 MAX_MOVE_BUFFER = 2 * 1024 * 4;
@@ -382,7 +382,8 @@ main(int argc, const char *const *argv)
} }
// parse the partition map // parse the partition map
PartitionMapParser parser(baseFD, 0, deviceSize); // TODO: block size!
PartitionMapParser parser(baseFD, 0, deviceSize, 512);
PartitionMap map; PartitionMap map;
error = parser.Parse(NULL, &map); error = parser.Parse(NULL, &map);
if (error != B_OK) { if (error != B_OK) {
@@ -464,7 +465,8 @@ main(int argc, const char *const *argv)
* geometry.cylinders * 512; * geometry.cylinders * 512;
// parse the partition map // parse the partition map
PartitionMapParser parser(baseFD, 0, deviceSize); // TODO: block size!
PartitionMapParser parser(baseFD, 0, deviceSize, 512);
PartitionMap map; PartitionMap map;
error = parser.Parse(NULL, &map); error = parser.Parse(NULL, &map);
if (error != B_OK) { if (error != B_OK) {
@@ -536,7 +538,7 @@ main(int argc, const char *const *argv)
deviceSize = blockSize * blockCount; deviceSize = blockSize * blockCount;
// parse the partition map // parse the partition map
PartitionMapParser parser(baseFD, 0, deviceSize); PartitionMapParser parser(baseFD, 0, deviceSize, blockSize);
PartitionMap map; PartitionMap map;
error = parser.Parse(NULL, &map); error = parser.Parse(NULL, &map);
if (error != B_OK) { if (error != B_OK) {