diff --git a/headers/private/storage/PartitioningInfo.h b/headers/private/storage/PartitioningInfo.h index d55468ec8a..9b9ac43360 100644 --- a/headers/private/storage/PartitioningInfo.h +++ b/headers/private/storage/PartitioningInfo.h @@ -6,18 +6,31 @@ #ifndef _PARTITIONING_INFO_H #define _PARTITIONING_INFO_H -#include +#include + +struct partitionable_space_data; class BPartitioningInfo { public: + BPartitioningInfo(); + virtual ~BPartitioningInfo(); + + void Unset(); + + partition_id PartitionID() const; + status_t GetPartitionableSpaceAt(int32 index, off_t *offset, off_t *size) const; int32 CountPartitionableSpaces() const; private: - off_t *fOffsets; - off_t *fSizes; - int32 fCount; + status_t _SetTo(partition_id partition); + + friend class BPartition; + + partition_id fPartitionID; + partitionable_space_data *fSpaces; + int32 fCount; }; #endif // _PARTITIONING_INFO_H diff --git a/src/kits/storage/Partition.cpp b/src/kits/storage/Partition.cpp index c97b7bc67f..bd4656d345 100644 --- a/src/kits/storage/Partition.cpp +++ b/src/kits/storage/Partition.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include "ddm_userland_interface.h" @@ -375,8 +376,9 @@ BPartition::FindDescendant(partition_id id) const status_t BPartition::GetPartitioningInfo(BPartitioningInfo *info) const { - // not implemented - return B_ERROR; + if (!info || !fPartitionData || !_IsShadow()) + return B_BAD_VALUE; + return info->_SetTo(_ShadowID()); } // VisitEachChild diff --git a/src/kits/storage/PartitioningInfo.cpp b/src/kits/storage/PartitioningInfo.cpp index 61d16e1fc7..ac7e2ec98d 100644 --- a/src/kits/storage/PartitioningInfo.cpp +++ b/src/kits/storage/PartitioningInfo.cpp @@ -3,4 +3,93 @@ // by the OpenBeOS license. //--------------------------------------------------------------------- +#include + +#include #include + +using namespace std; + +// constructor +BPartitioningInfo::BPartitioningInfo() + : fPartitionID(-1), + fSpaces(NULL), + fCount(0) +{ +} + +// destructor +BPartitioningInfo::~BPartitioningInfo() +{ + Unset(); +} + +// Unset +void +BPartitioningInfo::Unset() +{ + delete[] fSpaces; + fPartitionID = -1; + fSpaces = NULL; + fCount = 0; +} + +// PartitionID +partition_id +BPartitioningInfo::PartitionID() const +{ + return fPartitionID; +} + +// GetPartitionableSpaceAt +status_t +BPartitioningInfo::GetPartitionableSpaceAt(int32 index, off_t *offset, + off_t *size) const +{ + if (!fSpaces || !offset || !size || index < 0 || index >= fCount) + return B_BAD_VALUE; + *offset = fSpaces[index].offset; + *size = fSpaces[index].size; + return B_OK; +} + +// CountPartitionableSpaces +int32 +BPartitioningInfo::CountPartitionableSpaces() const +{ + return fCount; +} + +// _SetTo +status_t +BPartitioningInfo::_SetTo(partition_id partition) +{ + Unset(); + status_t error = B_OK; + partitionable_space_data *buffer = NULL; + int32 count = 0; + int32 actualCount = 0; + do { + error = _kern_get_partitionable_spaces(partition, buffer, + count, &actualCount); + if (error == B_BUFFER_OVERFLOW) { + // buffer to small re-allocate it + if (buffer) + delete[] buffer; + buffer = new(nothrow) partitionable_space_data[actualCount]; + if (buffer) + count = actualCount; + else + error = B_NO_MEMORY; + } + } while (error == B_BUFFER_OVERFLOW); + // set data / cleanup on failure + if (error == B_OK) { + fPartitionID = partition; + fSpaces = buffer; + fCount = actualCount; + } else if (buffer) + delete[] buffer; + return error; +} +