* 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:
@@ -100,8 +100,7 @@ static const struct partition_type kPartitionContentTypes[] = {
|
||||
};
|
||||
|
||||
|
||||
// partition_type_string
|
||||
static const char *
|
||||
static const char*
|
||||
partition_type_string(uint8 type)
|
||||
{
|
||||
int32 i;
|
||||
@@ -113,48 +112,51 @@ partition_type_string(uint8 type)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// get_partition_type_string
|
||||
|
||||
void
|
||||
get_partition_type_string(uint8 type, char *buffer)
|
||||
get_partition_type_string(uint8 type, char* buffer)
|
||||
{
|
||||
if (buffer) {
|
||||
if (const char *str = partition_type_string(type))
|
||||
strcpy(buffer, str);
|
||||
if (const char* typeString = partition_type_string(type))
|
||||
strcpy(buffer, typeString);
|
||||
else
|
||||
sprintf(buffer, "Unrecognized Type 0x%x", type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
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 *partition2 = *(const Partition**)p2;
|
||||
const Partition* partition1 = *(const Partition**)p1;
|
||||
const Partition* partition2 = *(const Partition**)p2;
|
||||
|
||||
if (partition1->Offset() < partition2->Offset())
|
||||
return -1;
|
||||
else if (partition1->Offset() > partition2->Offset())
|
||||
if (partition1->Offset() > partition2->Offset())
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
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 offset2 = *static_cast<const off_t*>(o2);
|
||||
|
||||
if (offset1 < offset2)
|
||||
return -1;
|
||||
else if (offset1 > offset2)
|
||||
if (offset1 > offset2)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
if (count > 0) {
|
||||
@@ -180,16 +182,15 @@ is_inside_partitions(off_t location, const Partition **partitions, int32 count)
|
||||
// #pragma mark - PartitionType
|
||||
|
||||
|
||||
// constructor
|
||||
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].
|
||||
*/
|
||||
bool
|
||||
@@ -200,9 +201,8 @@ PartitionType::SetType(uint8 type)
|
||||
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.
|
||||
*/
|
||||
bool
|
||||
@@ -219,9 +219,8 @@ PartitionType::SetType(const char *typeName)
|
||||
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.
|
||||
*/
|
||||
bool
|
||||
@@ -238,9 +237,8 @@ PartitionType::SetContentType(const char *contentType)
|
||||
return fValid;
|
||||
}
|
||||
|
||||
// FindNext
|
||||
/*!
|
||||
\brief Finds next supported partition.
|
||||
|
||||
/*! \brief Finds next supported partition.
|
||||
*/
|
||||
bool
|
||||
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.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool PartitionType::IsEmpty() const
|
||||
/*! \fn bool PartitionType::IsEmpty() const
|
||||
\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.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn uint8 PartitionType::Type() const
|
||||
/*! \fn uint8 PartitionType::Type() const
|
||||
\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.
|
||||
\param buffer Buffer where the name is stored, has to be allocated with
|
||||
sufficient length.
|
||||
@@ -288,7 +281,6 @@ PartitionType::FindNext()
|
||||
// #pragma mark - Partition
|
||||
|
||||
|
||||
// constructor
|
||||
Partition::Partition()
|
||||
:
|
||||
fPartitionTableOffset(0),
|
||||
@@ -299,9 +291,9 @@ Partition::Partition()
|
||||
{
|
||||
}
|
||||
|
||||
// constructor
|
||||
|
||||
Partition::Partition(const partition_descriptor* descriptor, off_t tableOffset,
|
||||
off_t baseOffset)
|
||||
off_t baseOffset, uint32 blockSize)
|
||||
:
|
||||
fPartitionTableOffset(0),
|
||||
fOffset(0),
|
||||
@@ -309,40 +301,37 @@ Partition::Partition(const partition_descriptor* descriptor, off_t tableOffset,
|
||||
fType(0),
|
||||
fActive(false)
|
||||
{
|
||||
SetTo(descriptor, tableOffset, baseOffset);
|
||||
SetTo(descriptor, tableOffset, baseOffset, blockSize);
|
||||
}
|
||||
|
||||
// SetTo
|
||||
|
||||
void
|
||||
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));
|
||||
SetTo(baseOffset + (off_t)descriptor->start * SECTOR_SIZE,
|
||||
(off_t)descriptor->size * SECTOR_SIZE,
|
||||
descriptor->type,
|
||||
descriptor->active,
|
||||
tableOffset);
|
||||
SetTo(baseOffset + (off_t)descriptor->start * blockSize,
|
||||
(off_t)descriptor->size * blockSize, descriptor->type,
|
||||
descriptor->active, tableOffset, blockSize);
|
||||
}
|
||||
|
||||
|
||||
// SetTo
|
||||
void
|
||||
Partition::SetTo(off_t offset, off_t size, uint8 type, bool active,
|
||||
off_t tableOffset)
|
||||
off_t tableOffset, uint32 blockSize)
|
||||
{
|
||||
fPartitionTableOffset = tableOffset;
|
||||
fOffset = offset;
|
||||
fSize = size;
|
||||
fType = type;
|
||||
fActive = active;
|
||||
fBlockSize = blockSize;
|
||||
|
||||
if (fSize == 0)
|
||||
Unset();
|
||||
}
|
||||
|
||||
|
||||
// Unset
|
||||
void
|
||||
Partition::Unset()
|
||||
{
|
||||
@@ -353,13 +342,13 @@ Partition::Unset()
|
||||
fActive = false;
|
||||
}
|
||||
|
||||
// GetPartitionDescriptor
|
||||
|
||||
void
|
||||
Partition::GetPartitionDescriptor(partition_descriptor *descriptor,
|
||||
off_t baseOffset) const
|
||||
off_t baseOffset) const
|
||||
{
|
||||
descriptor->start = (fOffset - baseOffset) / SECTOR_SIZE;
|
||||
descriptor->size = fSize / SECTOR_SIZE;
|
||||
descriptor->start = (fOffset - baseOffset) / fBlockSize;
|
||||
descriptor->size = fSize / fBlockSize;
|
||||
descriptor->type = fType;
|
||||
descriptor->active = fActive ? 0x80 : 0x00;
|
||||
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
|
||||
// lie within the session
|
||||
if (fPartitionTableOffset % SECTOR_SIZE != 0) {
|
||||
if (fPartitionTableOffset % fBlockSize != 0) {
|
||||
TRACE(("Partition::CheckLocation() - bad partition table offset: %lld "
|
||||
"(session: %lld)\n", fPartitionTableOffset, sessionSize));
|
||||
return false;
|
||||
}
|
||||
if (fOffset % SECTOR_SIZE != 0) {
|
||||
if (fOffset % fBlockSize != 0) {
|
||||
TRACE(("Partition::CheckLocation() - bad offset: %lld "
|
||||
"(session: %lld)\n", fOffset, sessionSize));
|
||||
return false;
|
||||
}
|
||||
if (fSize % SECTOR_SIZE != 0) {
|
||||
if (fSize % fBlockSize != 0) {
|
||||
TRACE(("Partition::CheckLocation() - bad size: %lld "
|
||||
"(session: %lld)\n", fSize, sessionSize));
|
||||
return false;
|
||||
@@ -423,35 +412,33 @@ Partition::CheckLocation(off_t sessionSize) const
|
||||
// #pragma mark - PrimaryPartition
|
||||
|
||||
|
||||
// constructor
|
||||
PrimaryPartition::PrimaryPartition()
|
||||
: Partition(),
|
||||
fHead(NULL),
|
||||
fTail(NULL),
|
||||
fLogicalPartitionCount(0)
|
||||
fHead(NULL),
|
||||
fTail(NULL),
|
||||
fLogicalPartitionCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
// SetTo
|
||||
|
||||
void
|
||||
PrimaryPartition::SetTo(const partition_descriptor* descriptor,
|
||||
off_t tableOffset)
|
||||
off_t tableOffset, uint32 blockSize)
|
||||
{
|
||||
Unset();
|
||||
Partition::SetTo(descriptor, tableOffset, 0);
|
||||
Partition::SetTo(descriptor, tableOffset, 0, blockSize);
|
||||
}
|
||||
|
||||
|
||||
// SetTo
|
||||
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();
|
||||
Partition::SetTo(offset, size, type, active, 0);
|
||||
Partition::SetTo(offset, size, type, active, 0, blockSize);
|
||||
}
|
||||
|
||||
|
||||
// Unset
|
||||
void
|
||||
PrimaryPartition::Unset()
|
||||
{
|
||||
@@ -466,13 +453,12 @@ PrimaryPartition::Unset()
|
||||
}
|
||||
|
||||
|
||||
// Assign
|
||||
status_t
|
||||
PrimaryPartition::Assign(const PrimaryPartition& other)
|
||||
{
|
||||
partition_descriptor descriptor;
|
||||
other.GetPartitionDescriptor(&descriptor, 0);
|
||||
SetTo(&descriptor, 0);
|
||||
SetTo(&descriptor, 0, other.BlockSize());
|
||||
|
||||
const LogicalPartition* otherLogical = other.fHead;
|
||||
while (otherLogical) {
|
||||
@@ -493,8 +479,7 @@ PrimaryPartition::Assign(const PrimaryPartition& other)
|
||||
}
|
||||
|
||||
|
||||
// LogicalPartitionAt
|
||||
LogicalPartition *
|
||||
LogicalPartition*
|
||||
PrimaryPartition::LogicalPartitionAt(int32 index) const
|
||||
{
|
||||
LogicalPartition *partition = NULL;
|
||||
@@ -505,9 +490,9 @@ PrimaryPartition::LogicalPartitionAt(int32 index) const
|
||||
return partition;
|
||||
}
|
||||
|
||||
// AddLogicalPartition
|
||||
|
||||
void
|
||||
PrimaryPartition::AddLogicalPartition(LogicalPartition *partition)
|
||||
PrimaryPartition::AddLogicalPartition(LogicalPartition* partition)
|
||||
{
|
||||
if (!partition)
|
||||
return;
|
||||
@@ -519,17 +504,19 @@ PrimaryPartition::AddLogicalPartition(LogicalPartition *partition)
|
||||
fTail = partition;
|
||||
} else
|
||||
fHead = fTail = partition;
|
||||
|
||||
partition->SetNext(NULL);
|
||||
|
||||
fLogicalPartitionCount++;
|
||||
}
|
||||
|
||||
// RemoveLogicalPartition
|
||||
|
||||
void
|
||||
PrimaryPartition::RemoveLogicalPartition(LogicalPartition *partition)
|
||||
PrimaryPartition::RemoveLogicalPartition(LogicalPartition* partition)
|
||||
{
|
||||
if (!partition || partition->GetPrimaryPartition() != this)
|
||||
return;
|
||||
|
||||
LogicalPartition *prev = partition->Previous();
|
||||
LogicalPartition *next = partition->Next();
|
||||
|
||||
@@ -553,30 +540,29 @@ PrimaryPartition::RemoveLogicalPartition(LogicalPartition *partition)
|
||||
// #pragma mark - LogicalPartition
|
||||
|
||||
|
||||
// constructor
|
||||
LogicalPartition::LogicalPartition()
|
||||
: Partition(),
|
||||
fPrimary(NULL),
|
||||
fNext(NULL),
|
||||
fPrevious(NULL)
|
||||
fPrimary(NULL),
|
||||
fNext(NULL),
|
||||
fPrevious(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
// constructor
|
||||
LogicalPartition::LogicalPartition(const partition_descriptor *descriptor,
|
||||
off_t tableOffset, PrimaryPartition *primary)
|
||||
|
||||
LogicalPartition::LogicalPartition(const partition_descriptor* descriptor,
|
||||
off_t tableOffset, PrimaryPartition* primary)
|
||||
: Partition(),
|
||||
fPrimary(NULL),
|
||||
fNext(NULL),
|
||||
fPrevious(NULL)
|
||||
fPrimary(NULL),
|
||||
fNext(NULL),
|
||||
fPrevious(NULL)
|
||||
{
|
||||
SetTo(descriptor, tableOffset, primary);
|
||||
}
|
||||
|
||||
// SetTo
|
||||
|
||||
void
|
||||
LogicalPartition::SetTo(const partition_descriptor *descriptor,
|
||||
off_t tableOffset, PrimaryPartition *primary)
|
||||
LogicalPartition::SetTo(const partition_descriptor* descriptor,
|
||||
off_t tableOffset, PrimaryPartition* primary)
|
||||
{
|
||||
Unset();
|
||||
if (descriptor && primary) {
|
||||
@@ -593,26 +579,26 @@ LogicalPartition::SetTo(const partition_descriptor *descriptor,
|
||||
// baseOffset.
|
||||
off_t baseOffset = descriptor->is_extended()
|
||||
? primary->Offset() : tableOffset;
|
||||
Partition::SetTo(descriptor, tableOffset, baseOffset);
|
||||
Partition::SetTo(descriptor, tableOffset, baseOffset,
|
||||
primary->BlockSize());
|
||||
fPrimary = primary;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// SetTo
|
||||
void
|
||||
LogicalPartition::SetTo(off_t offset, off_t size, uint8 type, bool active,
|
||||
off_t tableOffset, PrimaryPartition *primary)
|
||||
{
|
||||
Unset();
|
||||
if (primary) {
|
||||
Partition::SetTo(offset, size, type, active, tableOffset);
|
||||
Partition::SetTo(offset, size, type, active, tableOffset,
|
||||
primary->BlockSize());
|
||||
fPrimary = primary;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Unset
|
||||
void
|
||||
LogicalPartition::Unset()
|
||||
{
|
||||
@@ -626,7 +612,6 @@ LogicalPartition::Unset()
|
||||
// #pragma mark - PartitionMap
|
||||
|
||||
|
||||
// constructor
|
||||
PartitionMap::PartitionMap()
|
||||
{
|
||||
for (int32 i = 0; i < 4; i++)
|
||||
@@ -634,13 +619,11 @@ PartitionMap::PartitionMap()
|
||||
}
|
||||
|
||||
|
||||
// destructor
|
||||
PartitionMap::~PartitionMap()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// Unset
|
||||
void
|
||||
PartitionMap::Unset()
|
||||
{
|
||||
@@ -649,7 +632,6 @@ PartitionMap::Unset()
|
||||
}
|
||||
|
||||
|
||||
// Assign
|
||||
status_t
|
||||
PartitionMap::Assign(const PartitionMap& other)
|
||||
{
|
||||
@@ -663,7 +645,6 @@ PartitionMap::Assign(const PartitionMap& other)
|
||||
}
|
||||
|
||||
|
||||
// PrimaryPartitionAt
|
||||
PrimaryPartition*
|
||||
PartitionMap::PrimaryPartitionAt(int32 index)
|
||||
{
|
||||
@@ -674,7 +655,6 @@ PartitionMap::PrimaryPartitionAt(int32 index)
|
||||
}
|
||||
|
||||
|
||||
// PrimaryPartitionAt
|
||||
const PrimaryPartition*
|
||||
PartitionMap::PrimaryPartitionAt(int32 index) const
|
||||
{
|
||||
@@ -685,7 +665,6 @@ PartitionMap::PrimaryPartitionAt(int32 index) const
|
||||
}
|
||||
|
||||
|
||||
// CountNonEmptyPrimaryPartitions
|
||||
int32
|
||||
PartitionMap::CountNonEmptyPrimaryPartitions() const
|
||||
{
|
||||
@@ -699,7 +678,6 @@ PartitionMap::CountNonEmptyPrimaryPartitions() const
|
||||
}
|
||||
|
||||
|
||||
// ExtendedPartitionIndex
|
||||
int32
|
||||
PartitionMap::ExtendedPartitionIndex() const
|
||||
{
|
||||
@@ -712,7 +690,6 @@ PartitionMap::ExtendedPartitionIndex() const
|
||||
}
|
||||
|
||||
|
||||
// CountPartitions
|
||||
int32
|
||||
PartitionMap::CountPartitions() const
|
||||
{
|
||||
@@ -723,7 +700,6 @@ PartitionMap::CountPartitions() const
|
||||
}
|
||||
|
||||
|
||||
// CountNonEmptyPartitions
|
||||
int32
|
||||
PartitionMap::CountNonEmptyPartitions() const
|
||||
{
|
||||
@@ -737,7 +713,6 @@ PartitionMap::CountNonEmptyPartitions() const
|
||||
}
|
||||
|
||||
|
||||
// PartitionAt
|
||||
Partition*
|
||||
PartitionMap::PartitionAt(int32 index)
|
||||
{
|
||||
@@ -760,7 +735,6 @@ PartitionMap::PartitionAt(int32 index)
|
||||
}
|
||||
|
||||
|
||||
// PartitionAt
|
||||
const Partition*
|
||||
PartitionMap::PartitionAt(int32 index) const
|
||||
{
|
||||
@@ -768,7 +742,6 @@ PartitionMap::PartitionAt(int32 index) const
|
||||
}
|
||||
|
||||
|
||||
// Check
|
||||
bool
|
||||
PartitionMap::Check(off_t sessionSize) const
|
||||
{
|
||||
|
||||
@@ -26,10 +26,6 @@
|
||||
#define INTEL_EXTENDED_PARTITION_NAME "Intel Extended Partition"
|
||||
#define BFS_NAME "BFS Filesystem"
|
||||
|
||||
enum {
|
||||
SECTOR_SIZE = 512
|
||||
};
|
||||
|
||||
|
||||
// is_empty_type
|
||||
static inline bool
|
||||
@@ -128,141 +124,172 @@ private:
|
||||
// Partition
|
||||
class Partition {
|
||||
public:
|
||||
Partition();
|
||||
Partition(const partition_descriptor *descriptor, off_t ptsOffset,
|
||||
off_t baseOffset);
|
||||
Partition();
|
||||
Partition(const partition_descriptor* descriptor,
|
||||
off_t tableOffset, off_t baseOffset,
|
||||
uint32 blockSize);
|
||||
|
||||
void SetTo(const partition_descriptor *descriptor, off_t ptsOffset,
|
||||
off_t baseOffset);
|
||||
void SetTo(off_t offset, off_t size, uint8 type, bool active,
|
||||
off_t ptsOffset);
|
||||
void Unset();
|
||||
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); }
|
||||
bool IsEmpty() const
|
||||
{ return is_empty_type(fType); }
|
||||
bool IsExtended() const
|
||||
{ return is_extended_type(fType); }
|
||||
|
||||
// NOTE: Both PartitionTableOffset() and Offset() are absolute with regards to the
|
||||
// session (usually the disk). Ie, for all primary partitions, including
|
||||
// the primary extended partition, the PartitionTableOffset() points to the MBR (0).
|
||||
// For logical partitions, the PartitionTableOffset() is located within the primary
|
||||
// extended partition, but again, the returned values are absolute with
|
||||
// regards to the session. All values are expressed in bytes.
|
||||
off_t PartitionTableOffset() const { return fPartitionTableOffset; }
|
||||
// offset of the sector containing the descriptor for this partition
|
||||
off_t Offset() const { return fOffset; }
|
||||
// start offset of the partition contents
|
||||
off_t Size() const { return fSize; }
|
||||
uint8 Type() const { return fType; }
|
||||
bool Active() const { return fActive; }
|
||||
void GetTypeString(char *buffer) const
|
||||
{ get_partition_type_string(fType, buffer); }
|
||||
void GetPartitionDescriptor(partition_descriptor *descriptor,
|
||||
off_t baseOffset) const;
|
||||
// NOTE: Both PartitionTableOffset() and Offset() are absolute with regards
|
||||
// to the session (usually the disk). Ie, for all primary partitions,
|
||||
// including the primary extended partition, the PartitionTableOffset()
|
||||
// points to the MBR (0).
|
||||
// For logical partitions, the PartitionTableOffset() is located within the
|
||||
// primary extended partition, but again, the returned values are absolute
|
||||
// with regards to the session. All values are expressed in bytes.
|
||||
off_t PartitionTableOffset() const
|
||||
{ return fPartitionTableOffset; }
|
||||
// offset of the partition table
|
||||
off_t Offset() const { return fOffset; }
|
||||
// start offset of the partition contents
|
||||
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 GetPartitionDescriptor(
|
||||
partition_descriptor* descriptor,
|
||||
off_t baseOffset) const;
|
||||
|
||||
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 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; }
|
||||
|
||||
bool CheckLocation(off_t sessionSize) const;
|
||||
bool CheckLocation(off_t sessionSize) const;
|
||||
#ifdef _BOOT_MODE
|
||||
void AdjustSize(off_t sessionSize);
|
||||
void AdjustSize(off_t sessionSize);
|
||||
#endif
|
||||
|
||||
private:
|
||||
off_t fPartitionTableOffset;
|
||||
off_t fOffset; // relative to the start of the session
|
||||
off_t fSize;
|
||||
uint8 fType;
|
||||
bool fActive;
|
||||
off_t fPartitionTableOffset;
|
||||
off_t fOffset;
|
||||
// relative to the start of the session
|
||||
off_t fSize;
|
||||
uint32 fBlockSize;
|
||||
uint8 fType;
|
||||
bool fActive;
|
||||
};
|
||||
|
||||
|
||||
// PrimaryPartition
|
||||
class PrimaryPartition : public Partition {
|
||||
public:
|
||||
PrimaryPartition();
|
||||
PrimaryPartition();
|
||||
|
||||
void SetTo(const partition_descriptor *descriptor, off_t ptsOffset);
|
||||
void SetTo(off_t offset, off_t size, uint8 type, bool active);
|
||||
void Unset();
|
||||
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);
|
||||
status_t Assign(const PrimaryPartition& other);
|
||||
|
||||
int32 Index() const { return fIndex; }
|
||||
void SetIndex(int32 index) { fIndex = index; }
|
||||
// private
|
||||
int32 Index() const { return fIndex; }
|
||||
void SetIndex(int32 index) { fIndex = index; }
|
||||
// private
|
||||
|
||||
// only if extended
|
||||
int32 CountLogicalPartitions() const { return fLogicalPartitionCount; }
|
||||
LogicalPartition *LogicalPartitionAt(int32 index) const;
|
||||
void AddLogicalPartition(LogicalPartition *partition);
|
||||
void RemoveLogicalPartition(LogicalPartition *partition);
|
||||
// only if extended
|
||||
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;
|
||||
LogicalPartition* fHead;
|
||||
LogicalPartition* fTail;
|
||||
int32 fLogicalPartitionCount;
|
||||
int32 fIndex;
|
||||
};
|
||||
|
||||
|
||||
// LogicalPartition
|
||||
class LogicalPartition : public Partition {
|
||||
public:
|
||||
LogicalPartition();
|
||||
LogicalPartition(const partition_descriptor *descriptor, off_t ptsOffset,
|
||||
PrimaryPartition *primary);
|
||||
LogicalPartition();
|
||||
LogicalPartition(
|
||||
const partition_descriptor* descriptor,
|
||||
off_t tableOffset,
|
||||
PrimaryPartition *primary);
|
||||
|
||||
void SetTo(const partition_descriptor *descriptor, off_t ptsOffset,
|
||||
PrimaryPartition *primary);
|
||||
void SetTo(off_t offset, off_t size, uint8 type, bool active,
|
||||
off_t ptsOffset, PrimaryPartition *primary);
|
||||
void Unset();
|
||||
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 SetPrimaryPartition(PrimaryPartition *primary) { fPrimary = primary; }
|
||||
PrimaryPartition *GetPrimaryPartition() const { return fPrimary; }
|
||||
void SetPrimaryPartition(PrimaryPartition* primary)
|
||||
{ fPrimary = primary; }
|
||||
PrimaryPartition* GetPrimaryPartition() const
|
||||
{ return fPrimary; }
|
||||
|
||||
void SetNext(LogicalPartition *next) { fNext = next; }
|
||||
LogicalPartition *Next() const { return fNext; }
|
||||
void SetNext(LogicalPartition* next)
|
||||
{ fNext = next; }
|
||||
LogicalPartition* Next() const
|
||||
{ return fNext; }
|
||||
|
||||
void SetPrevious(LogicalPartition *previous) { fPrevious = previous; }
|
||||
LogicalPartition *Previous() const { return fPrevious; }
|
||||
void SetPrevious(LogicalPartition* previous)
|
||||
{ fPrevious = previous; }
|
||||
LogicalPartition* Previous() const
|
||||
{ return fPrevious; }
|
||||
|
||||
private:
|
||||
PrimaryPartition *fPrimary;
|
||||
LogicalPartition *fNext;
|
||||
LogicalPartition *fPrevious;
|
||||
PrimaryPartition* fPrimary;
|
||||
LogicalPartition* fNext;
|
||||
LogicalPartition* fPrevious;
|
||||
};
|
||||
|
||||
|
||||
// PartitionMap
|
||||
class PartitionMap {
|
||||
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);
|
||||
const PrimaryPartition *PrimaryPartitionAt(int32 index) const;
|
||||
int32 IndexOfPrimaryPartition(const PrimaryPartition* partition) const;
|
||||
int32 CountNonEmptyPrimaryPartitions() const;
|
||||
PrimaryPartition* PrimaryPartitionAt(int32 index);
|
||||
const PrimaryPartition* PrimaryPartitionAt(int32 index) const;
|
||||
int32 IndexOfPrimaryPartition(
|
||||
const PrimaryPartition* partition) const;
|
||||
int32 CountNonEmptyPrimaryPartitions() const;
|
||||
|
||||
int32 ExtendedPartitionIndex() const;
|
||||
int32 ExtendedPartitionIndex() const;
|
||||
|
||||
int32 CountPartitions() const;
|
||||
int32 CountNonEmptyPartitions() const;
|
||||
Partition *PartitionAt(int32 index);
|
||||
const Partition *PartitionAt(int32 index) const;
|
||||
int32 CountPartitions() const;
|
||||
int32 CountNonEmptyPartitions() const;
|
||||
Partition* PartitionAt(int32 index);
|
||||
const Partition* PartitionAt(int32 index) const;
|
||||
|
||||
bool Check(off_t sessionSize) const;
|
||||
bool Check(off_t sessionSize) const;
|
||||
|
||||
private:
|
||||
PrimaryPartition fPrimaries[4];
|
||||
PrimaryPartition fPrimaries[4];
|
||||
};
|
||||
|
||||
#endif // _INTEL_PARTITION_MAP_H
|
||||
|
||||
@@ -41,9 +41,10 @@ static const int32 kMaxLogicalPartitionCount = 128;
|
||||
|
||||
// constructor
|
||||
PartitionMapParser::PartitionMapParser(int deviceFD, off_t sessionOffset,
|
||||
off_t sessionSize)
|
||||
off_t sessionSize, uint32 blockSize)
|
||||
:
|
||||
fDeviceFD(deviceFD),
|
||||
fBlockSize(blockSize),
|
||||
fSessionOffset(sessionOffset),
|
||||
fSessionSize(sessionSize),
|
||||
fPartitionTable(NULL),
|
||||
@@ -105,9 +106,9 @@ PartitionMapParser::_ParsePrimary(const partition_table* table)
|
||||
|
||||
// examine the table
|
||||
for (int32 i = 0; i < 4; i++) {
|
||||
const partition_descriptor *descriptor = &table->table[i];
|
||||
PrimaryPartition *partition = fMap->PrimaryPartitionAt(i);
|
||||
partition->SetTo(descriptor, 0);
|
||||
const partition_descriptor* descriptor = &table->table[i];
|
||||
PrimaryPartition* partition = fMap->PrimaryPartitionAt(i);
|
||||
partition->SetTo(descriptor, 0, fBlockSize);
|
||||
|
||||
#ifdef _BOOT_MODE
|
||||
// work-around potential BIOS problems
|
||||
|
||||
@@ -28,7 +28,8 @@ struct partition_table;
|
||||
class PartitionMapParser {
|
||||
public:
|
||||
PartitionMapParser(int deviceFD,
|
||||
off_t sessionOffset, off_t sessionSize);
|
||||
off_t sessionOffset, off_t sessionSize,
|
||||
uint32 blockSize);
|
||||
~PartitionMapParser();
|
||||
|
||||
status_t Parse(const uint8* block, PartitionMap* map);
|
||||
@@ -45,6 +46,7 @@ private:
|
||||
|
||||
private:
|
||||
int fDeviceFD;
|
||||
uint32 fBlockSize;
|
||||
off_t fSessionOffset;
|
||||
off_t fSessionSize;
|
||||
partition_table* fPartitionTable; // while parsing
|
||||
|
||||
@@ -34,6 +34,10 @@ using std::nothrow;
|
||||
#endif
|
||||
|
||||
|
||||
// TODO: get rid of this - there is no such thing as a fixed sector size!
|
||||
static const uint32 SECTOR_SIZE = 512;
|
||||
|
||||
|
||||
// constructor
|
||||
/*! \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.
|
||||
*
|
||||
* Authors:
|
||||
@@ -132,7 +132,7 @@ pm_identify_partition(int fd, partition_data *partition, void **cookie)
|
||||
return -1;
|
||||
|
||||
// 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);
|
||||
if (error != B_OK) {
|
||||
// cleanup, if not detected
|
||||
@@ -173,6 +173,7 @@ pm_identify_partition(int fd, partition_data *partition, void **cookie)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// pm_scan_partition
|
||||
static status_t
|
||||
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;
|
||||
// (no content_name and content_parameters)
|
||||
// (content_type is set by the system)
|
||||
partition->block_size = SECTOR_SIZE;
|
||||
|
||||
partition->content_cookie = map;
|
||||
// children
|
||||
@@ -202,7 +202,7 @@ pm_scan_partition(int fd, partition_data *partition, void *cookie)
|
||||
PrimaryPartition *primary = map->PrimaryPartitionAt(i);
|
||||
if (!primary->IsEmpty()) {
|
||||
partition_data *child = create_child_partition(partition->id,
|
||||
index, -1);
|
||||
index, -1);
|
||||
index++;
|
||||
if (!child) {
|
||||
// something went wrong
|
||||
@@ -212,7 +212,8 @@ pm_scan_partition(int fd, partition_data *partition, void *cookie)
|
||||
|
||||
child->offset = partition->offset + primary->Offset();
|
||||
child->size = primary->Size();
|
||||
child->block_size = SECTOR_SIZE;
|
||||
child->block_size = partition->block_size;
|
||||
|
||||
// (no name)
|
||||
char type[B_FILE_NAME_LENGTH];
|
||||
primary->GetTypeString(type);
|
||||
@@ -220,7 +221,7 @@ pm_scan_partition(int fd, partition_data *partition, void *cookie)
|
||||
// parameters
|
||||
char buffer[128];
|
||||
sprintf(buffer, "type = %u ; active = %d", primary->Type(),
|
||||
primary->Active());
|
||||
primary->Active());
|
||||
child->parameters = strdup(buffer);
|
||||
child->cookie = primary;
|
||||
// check for allocation problems
|
||||
@@ -245,6 +246,7 @@ pm_scan_partition(int fd, partition_data *partition, void *cookie)
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
// pm_free_identify_partition_cookie
|
||||
static void
|
||||
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
|
||||
static void
|
||||
pm_free_partition_cookie(partition_data *partition)
|
||||
@@ -266,6 +269,7 @@ pm_free_partition_cookie(partition_data *partition)
|
||||
partition->cookie = NULL;
|
||||
}
|
||||
|
||||
|
||||
// pm_free_partition_content_cookie
|
||||
static void
|
||||
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
|
||||
|
||||
|
||||
@@ -292,6 +297,7 @@ ep_std_ops(int32 op, ...)
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
// ep_identify_partition
|
||||
static float
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
// ep_scan_partition
|
||||
static status_t
|
||||
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;
|
||||
// (no content_name and content_parameters)
|
||||
// (content_type is set by the system)
|
||||
partition->block_size = SECTOR_SIZE;
|
||||
|
||||
partition->content_cookie = primary;
|
||||
// children
|
||||
@@ -348,8 +354,7 @@ ep_scan_partition(int fd, partition_data *partition, void *cookie)
|
||||
int32 index = 0;
|
||||
for (int32 i = 0; i < primary->CountLogicalPartitions(); i++) {
|
||||
LogicalPartition *logical = primary->LogicalPartitionAt(i);
|
||||
partition_data *child = create_child_partition(partition->id,
|
||||
index, -1);
|
||||
partition_data *child = create_child_partition(partition->id, index, -1);
|
||||
index++;
|
||||
if (!child) {
|
||||
// something went wrong
|
||||
@@ -360,7 +365,8 @@ ep_scan_partition(int fd, partition_data *partition, void *cookie)
|
||||
}
|
||||
child->offset = parent->offset + logical->Offset();
|
||||
child->size = logical->Size();
|
||||
child->block_size = SECTOR_SIZE;
|
||||
child->block_size = partition->block_size;
|
||||
|
||||
// (no name)
|
||||
char type[B_FILE_NAME_LENGTH];
|
||||
logical->GetTypeString(type);
|
||||
@@ -380,6 +386,7 @@ ep_scan_partition(int fd, partition_data *partition, void *cookie)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// cleanup on error
|
||||
if (error != B_OK) {
|
||||
partition->content_cookie = NULL;
|
||||
@@ -391,6 +398,7 @@ ep_scan_partition(int fd, partition_data *partition, void *cookie)
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
// ep_free_identify_partition_cookie
|
||||
static void
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
// ep_free_partition_cookie
|
||||
static void
|
||||
ep_free_partition_cookie(partition_data *partition)
|
||||
@@ -407,6 +416,7 @@ ep_free_partition_cookie(partition_data *partition)
|
||||
partition->cookie = NULL;
|
||||
}
|
||||
|
||||
|
||||
// ep_free_partition_content_cookie
|
||||
static void
|
||||
ep_free_partition_content_cookie(partition_data *partition)
|
||||
|
||||
@@ -32,6 +32,9 @@
|
||||
//#define TRACE(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).
|
||||
static const int32 MAX_MOVE_BUFFER = 2 * 1024 * 4;
|
||||
|
||||
|
||||
@@ -382,7 +382,8 @@ main(int argc, const char *const *argv)
|
||||
}
|
||||
|
||||
// parse the partition map
|
||||
PartitionMapParser parser(baseFD, 0, deviceSize);
|
||||
// TODO: block size!
|
||||
PartitionMapParser parser(baseFD, 0, deviceSize, 512);
|
||||
PartitionMap map;
|
||||
error = parser.Parse(NULL, &map);
|
||||
if (error != B_OK) {
|
||||
@@ -464,7 +465,8 @@ main(int argc, const char *const *argv)
|
||||
* geometry.cylinders * 512;
|
||||
|
||||
// parse the partition map
|
||||
PartitionMapParser parser(baseFD, 0, deviceSize);
|
||||
// TODO: block size!
|
||||
PartitionMapParser parser(baseFD, 0, deviceSize, 512);
|
||||
PartitionMap map;
|
||||
error = parser.Parse(NULL, &map);
|
||||
if (error != B_OK) {
|
||||
@@ -501,13 +503,13 @@ main(int argc, const char *const *argv)
|
||||
// chop off the trailing number
|
||||
int fileNameLen = strlen(fileName);
|
||||
int baseNameLen = fileNameLen - 2;
|
||||
|
||||
|
||||
// get base device name and partition index
|
||||
char baseDeviceName[B_PATH_NAME_LENGTH];
|
||||
int partitionIndex = atoi(fileName + baseNameLen + 1);
|
||||
memcpy(baseDeviceName, fileName, baseNameLen);
|
||||
baseDeviceName[baseNameLen] = '\0';
|
||||
|
||||
|
||||
// open base device
|
||||
int baseFD = open(baseDeviceName, O_RDONLY);
|
||||
if (baseFD < 0) {
|
||||
@@ -515,7 +517,7 @@ main(int argc, const char *const *argv)
|
||||
baseDeviceName, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
// get device size
|
||||
int64 blockSize;
|
||||
int64 blockCount;
|
||||
@@ -534,9 +536,9 @@ main(int argc, const char *const *argv)
|
||||
}
|
||||
|
||||
deviceSize = blockSize * blockCount;
|
||||
|
||||
|
||||
// parse the partition map
|
||||
PartitionMapParser parser(baseFD, 0, deviceSize);
|
||||
PartitionMapParser parser(baseFD, 0, deviceSize, blockSize);
|
||||
PartitionMap map;
|
||||
error = parser.Parse(NULL, &map);
|
||||
if (error != B_OK) {
|
||||
@@ -545,9 +547,9 @@ main(int argc, const char *const *argv)
|
||||
strerror(error));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
close(baseFD);
|
||||
|
||||
|
||||
// check the partition we are supposed to write at
|
||||
Partition *partition = map.PartitionAt(partitionIndex - 1);
|
||||
if (!partition || partition->IsEmpty()) {
|
||||
@@ -555,7 +557,7 @@ main(int argc, const char *const *argv)
|
||||
partitionIndex);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
if (partition->IsExtended()) {
|
||||
fprintf(stderr, "Error: Partition %d is an extended "
|
||||
"partition.\n", partitionIndex);
|
||||
|
||||
Reference in New Issue
Block a user