diff --git a/headers/private/storage/DiskSystemAddOn.h b/headers/private/storage/DiskSystemAddOn.h index 8391636eb0..8a7d7e310c 100644 --- a/headers/private/storage/DiskSystemAddOn.h +++ b/headers/private/storage/DiskSystemAddOn.h @@ -9,6 +9,7 @@ #include +class BDiskDeviceParameterEditor; class BList; class BMutablePartition; class BPartitionHandle; @@ -28,8 +29,13 @@ public: BMutablePartition* partition, BPartitionHandle** handle) = 0; - virtual bool CanInitialize(BMutablePartition* partition); - virtual bool ValidateInitialize(BMutablePartition* partition, + virtual bool CanInitialize( + const BMutablePartition* partition); + virtual status_t GetInitializationParameterEditor( + const BMutablePartition* partition, + BDiskDeviceParameterEditor** editor); + virtual bool ValidateInitialize( + const BMutablePartition* partition, BString* name, const char* parameters); virtual status_t Initialize(BMutablePartition* partition, const char* name, const char* parameters, @@ -50,14 +56,16 @@ public: virtual uint32 SupportedOperations(uint32 mask); virtual uint32 SupportedChildOperations( - BMutablePartition* child, uint32 mask); + const BMutablePartition* child, + uint32 mask); virtual bool SupportsInitializingChild( - BMutablePartition* child, + const BMutablePartition* child, const char* diskSystem); - virtual bool IsSubSystemFor(BMutablePartition* child); + virtual bool IsSubSystemFor(const BMutablePartition* child); - virtual status_t GetNextSupportedType(BMutablePartition* child, + virtual status_t GetNextSupportedType( + const BMutablePartition* child, int32* cookie, BString* type); // child can be NULL virtual status_t GetTypeForContentType(const char* contentType, @@ -66,47 +74,60 @@ public: virtual status_t GetPartitioningInfo(BPartitioningInfo* info); + virtual status_t Defragment(); virtual status_t Repair(bool checkOnly); - // TODO: How is this supposed to work? virtual bool ValidateResize(off_t* size); - virtual bool ValidateResizeChild(BMutablePartition* child, + virtual bool ValidateResizeChild( + const BMutablePartition* child, off_t* size); virtual status_t Resize(off_t size); virtual status_t ResizeChild(BMutablePartition* child, off_t size); virtual bool ValidateMove(off_t* offset); - virtual bool ValidateMoveChild(BMutablePartition* child, + virtual bool ValidateMoveChild( + const BMutablePartition* child, off_t* offset); virtual status_t Move(off_t offset); virtual status_t MoveChild(BMutablePartition* child, off_t offset); virtual bool ValidateSetContentName(BString* name); - virtual bool ValidateSetName(BMutablePartition* child, + virtual bool ValidateSetName(const BMutablePartition* child, BString* name); virtual status_t SetContentName(const char* name); virtual status_t SetName(BMutablePartition* child, const char* name); - virtual bool ValidateSetType(BMutablePartition* child, + virtual bool ValidateSetType(const BMutablePartition* child, const char* type); virtual status_t SetType(BMutablePartition* child, const char* type); + virtual status_t GetContentParameterEditor( + BDiskDeviceParameterEditor** editor); + virtual status_t GetParameterEditor( + const BMutablePartition* child, + BDiskDeviceParameterEditor** editor); virtual bool ValidateSetContentParameters( const char* parameters); - virtual bool ValidateSetParameters(BMutablePartition* child, + virtual bool ValidateSetParameters( + const BMutablePartition* child, const char* parameters); virtual status_t SetContentParameters(const char* parameters); virtual status_t SetParameters(BMutablePartition* child, const char* parameters); + virtual status_t GetChildCreationParameterEditor( + const char* type, + BDiskDeviceParameterEditor** editor); virtual bool ValidateCreateChild(off_t* offset, off_t* size, const char* type, const char* parameters); - virtual status_t CreateChild(BMutablePartition* child); + virtual status_t CreateChild(off_t offset, off_t size, + const char* type, const char* parameters, + BMutablePartition** child); virtual status_t DeleteChild(BMutablePartition* child); diff --git a/headers/private/storage/MutablePartition.h b/headers/private/storage/MutablePartition.h new file mode 100644 index 0000000000..01341697b5 --- /dev/null +++ b/headers/private/storage/MutablePartition.h @@ -0,0 +1,88 @@ +/* + * Copyright 2007, Ingo Weinhold, bonefish@users.sf.net. + * Distributed under the terms of the MIT License. + */ +#ifndef _MUTABLE_PARTITION_H +#define _MUTABLE_PARTITION_H + +#include +#include + + +struct user_partition_data; + + +class BMutablePartition { +public: + off_t Offset() const; + void SetOffset(off_t offset); + + off_t Size() const; + void SetSize(off_t size); + + off_t ContentSize() const; + void SetContentSize(off_t size); + + off_t BlockSize() const; + void SetBlockSize(off_t blockSize); + + uint32 Status() const; + + uint32 Flags() const; + void SetFlags(uint32 flags); + + dev_t Volume() const; + + int32 Index() const; + + const char* Name() const; + status_t SetName(const char* name); + + const char* ContentName() const; + status_t SetContentName(const char* name); + + const char* Type() const; + status_t SetType(const char* type) const; + + const char* ContentType() const; + status_t SetContentType(const char* type) const; + + const char* Parameters() const; + status_t SetParameters(const char* parameters); + + const char* ContentParameters() const; + status_t SetContentParameters(const char* parameters); + + status_t CreateChild(int32 index, + BMutablePartition** child); + status_t DeleteChild(int32 index); + + BMutablePartition* ChildAt(int32 index) const; + int32 CountChildren() const; + + // for the partitioning system managing the parent + void* ChildCookie() const; + void SetChildCookie(void* cookie); + +private: + BMutablePartition( + BPartition::MutableDelegate* delegate); + ~BMutablePartition(); + + status_t Init(const user_partition_data* partitionData); + + const user_partition_data* PartitionData() const; + +private: + friend class BPartition::MutableDelegate; + + BPartition::MutableDelegate* GetDelegate() const; + + BPartition::MutableDelegate* fDelegate; + user_partition_data* fData; + BList fChildren; + void* fChildCookie; +}; + + +#endif // _MUTABLE_PARTITION_H diff --git a/headers/private/storage/Partition.h b/headers/private/storage/Partition.h index 705f831d21..04374ed76f 100644 --- a/headers/private/storage/Partition.h +++ b/headers/private/storage/Partition.h @@ -140,6 +140,10 @@ public: status_t DeleteChild(int32 index); private: + class Delegate; + class ImmutableDelegate; + class MutableDelegate; + BPartition(); BPartition(const BPartition &); virtual ~BPartition(); diff --git a/src/kits/storage/DiskSystemAddOn.cpp b/src/kits/storage/DiskSystemAddOn.cpp index 6726d23e49..98be5aeef1 100644 --- a/src/kits/storage/DiskSystemAddOn.cpp +++ b/src/kits/storage/DiskSystemAddOn.cpp @@ -43,15 +43,24 @@ BDiskSystemAddOn::Flags() const // CanInitialize bool -BDiskSystemAddOn::CanInitialize(BMutablePartition* partition) +BDiskSystemAddOn::CanInitialize(const BMutablePartition* partition) { return false; } +// GetInitializationParameterEditor +status_t +BDiskSystemAddOn::GetInitializationParameterEditor( + const BMutablePartition* partition, BDiskDeviceParameterEditor** editor) +{ + return B_NOT_SUPPORTED; +} + + // ValidateInitialize bool -BDiskSystemAddOn::ValidateInitialize(BMutablePartition* partition, +BDiskSystemAddOn::ValidateInitialize(const BMutablePartition* partition, BString* name, const char* parameters) { return false; @@ -101,7 +110,7 @@ BPartitionHandle::SupportedOperations(uint32 mask) // SupportedChildOperations uint32 -BPartitionHandle::SupportedChildOperations(BMutablePartition* child, +BPartitionHandle::SupportedChildOperations(const BMutablePartition* child, uint32 mask) { return 0; @@ -110,7 +119,7 @@ BPartitionHandle::SupportedChildOperations(BMutablePartition* child, // SupportsInitializingChild bool -BPartitionHandle::SupportsInitializingChild(BMutablePartition* child, +BPartitionHandle::SupportsInitializingChild(const BMutablePartition* child, const char* diskSystem) { return false; @@ -119,7 +128,7 @@ BPartitionHandle::SupportsInitializingChild(BMutablePartition* child, // IsSubSystemFor bool -BPartitionHandle::IsSubSystemFor(BMutablePartition* child) +BPartitionHandle::IsSubSystemFor(const BMutablePartition* child) { return false; } @@ -127,8 +136,8 @@ BPartitionHandle::IsSubSystemFor(BMutablePartition* child) // GetNextSupportedType status_t -BPartitionHandle::GetNextSupportedType(BMutablePartition* child, int32* cookie, - BString* type) +BPartitionHandle::GetNextSupportedType(const BMutablePartition* child, + int32* cookie, BString* type) { return B_ENTRY_NOT_FOUND; } @@ -150,6 +159,14 @@ BPartitionHandle::GetPartitioningInfo(BPartitioningInfo* info) } +// Defragment +status_t +BPartitionHandle::Defragment() +{ + return B_NOT_SUPPORTED; +} + + // Repair status_t BPartitionHandle::Repair(bool checkOnly) @@ -168,7 +185,8 @@ BPartitionHandle::ValidateResize(off_t* size) // ValidateResizeChild bool -BPartitionHandle::ValidateResizeChild(BMutablePartition* child, off_t* size) +BPartitionHandle::ValidateResizeChild(const BMutablePartition* child, + off_t* size) { return false; } @@ -202,7 +220,8 @@ BPartitionHandle::ValidateMove(off_t* offset) // ValidateMoveChild bool -BPartitionHandle::ValidateMoveChild(BMutablePartition* child, off_t* offset) +BPartitionHandle::ValidateMoveChild(const BMutablePartition* child, + off_t* offset) { return false; } @@ -236,7 +255,8 @@ BPartitionHandle::ValidateSetContentName(BString* name) // ValidateSetName bool -BPartitionHandle::ValidateSetName(BMutablePartition* child, BString* name) +BPartitionHandle::ValidateSetName(const BMutablePartition* child, + BString* name) { return false; } @@ -260,7 +280,8 @@ BPartitionHandle::SetName(BMutablePartition* child, const char* name) // ValidateSetType bool -BPartitionHandle::ValidateSetType(BMutablePartition* child, const char* type) +BPartitionHandle::ValidateSetType(const BMutablePartition* child, + const char* type) { return false; } @@ -274,6 +295,23 @@ BPartitionHandle::SetType(BMutablePartition* child, const char* type) } +// GetContentParameterEditor +status_t +BPartitionHandle::GetContentParameterEditor(BDiskDeviceParameterEditor** editor) +{ + return B_NOT_SUPPORTED; +} + + +// GetParameterEditor +status_t +BPartitionHandle::GetParameterEditor(const BMutablePartition* child, + BDiskDeviceParameterEditor** editor) +{ + return B_NOT_SUPPORTED; +} + + // ValidateSetContentParameters bool BPartitionHandle::ValidateSetContentParameters(const char* parameters) @@ -284,7 +322,7 @@ BPartitionHandle::ValidateSetContentParameters(const char* parameters) // ValidateSetParameters bool -BPartitionHandle::ValidateSetParameters(BMutablePartition* child, +BPartitionHandle::ValidateSetParameters(const BMutablePartition* child, const char* parameters) { return false; @@ -308,6 +346,15 @@ BPartitionHandle::SetParameters(BMutablePartition* child, } +// GetChildCreationParameterEditor +status_t +BPartitionHandle::GetChildCreationParameterEditor(const char* type, + BDiskDeviceParameterEditor** editor) +{ + return B_NOT_SUPPORTED; +} + + // ValidateCreateChild bool BPartitionHandle::ValidateCreateChild(off_t* offset, off_t* size, @@ -319,7 +366,8 @@ BPartitionHandle::ValidateCreateChild(off_t* offset, off_t* size, // CreateChild status_t -BPartitionHandle::CreateChild(BMutablePartition* child) +BPartitionHandle::CreateChild(off_t offset, off_t size, const char* type, + const char* parameters, BMutablePartition** child) { return B_NOT_SUPPORTED; } diff --git a/src/kits/storage/DiskSystemAddOnManager.cpp b/src/kits/storage/DiskSystemAddOnManager.cpp new file mode 100644 index 0000000000..07d3e8fa03 --- /dev/null +++ b/src/kits/storage/DiskSystemAddOnManager.cpp @@ -0,0 +1,175 @@ +/* + * Copyright 2007, Ingo Weinhold, bonefish@users.sf.net. + * Distributed under the terms of the MIT License. + */ + +#include "DiskSystemAddOnManager.h" + +#include + +#include +#include + +#include + + +// sManager +DiskSystemAddOnManager* DiskSystemAddOnManager::sManager = NULL; + + +// AddOnImage +struct DiskSystemAddOnManager::AddOnImage { + image_id image; + int32 refCount; +}; + + +// AddOn +struct DiskSystemAddOnManager::AddOn { + AddOnImage* image; + BDiskSystemAddOn* addOn; + int32 refCount; +}; + + +// Default +DiskSystemAddOnManager* +DiskSystemAddOnManager::Default() +{ + if (!sManager) { + DiskSystemAddOnManager* manager = new DiskSystemAddOnManager(); + + BPrivate::gInitializationLock.Lock(); + + // set manager, if no one beat us to it + if (!sManager) { + sManager = manager; + manager = NULL; + } + + BPrivate::gInitializationLock.Unlock(); + + // delete the object we created, if someone else was quicker + delete manager; + } + + return sManager; +} + + +// Lock +bool +DiskSystemAddOnManager::Lock() +{ + return fLock.Lock(); +} + + +// Unlock +void +DiskSystemAddOnManager::Unlock() +{ + fLock.Unlock(); +} + + +// LoadDiskSystems +void +DiskSystemAddOnManager::LoadDiskSystems() +{ + AutoLocker _(fLock); + + if (++fLoadCount > 1) + return; + + // TODO: Load the add-ons ... +} + + +// UnloadDiskSystems +void +DiskSystemAddOnManager::UnloadDiskSystems() +{ + AutoLocker _(fLock); + + if (--fLoadCount == 0) + return; + + // TODO: Unload the add-ons ... +} + + +// CountAddOns +int32 +DiskSystemAddOnManager::CountAddOns() const +{ + return fAddOns.CountItems(); +} + + +// AddOnAt +BDiskSystemAddOn* +DiskSystemAddOnManager::AddOnAt(int32 index) const +{ + AddOn* addOn = _AddOnAt(index); + return addOn ? addOn->addOn : NULL; +} + + +// GetAddOn +BDiskSystemAddOn* +DiskSystemAddOnManager::GetAddOn(const char* name) +{ + if (!name) + return NULL; + + AutoLocker _(fLock); + + for (int32 i = 0; AddOn* addOn = _AddOnAt(i); i++) { + if (strcmp(addOn->addOn->Name(), name) == 0) { + addOn->refCount++; + return addOn->addOn; + } + } + + return NULL; +} + + +// PutAddOn +void +DiskSystemAddOnManager::PutAddOn(BDiskSystemAddOn* _addOn) +{ + if (!_addOn) + return; + + AutoLocker _(fLock); + + for (int32 i = 0; AddOn* addOn = _AddOnAt(i); i++) { + if (_addOn == addOn->addOn) { + if (addOn->refCount == 0) + debugger("DiskSystemAddOnManager: unbalanced PutAddOn()"); + else + addOn->refCount--; + return; + } + } +} + + +// constructor +DiskSystemAddOnManager::DiskSystemAddOnManager() + : fLock("disk system add-ons manager"), + fAddOns(), + fLoadCount(0) +{ +} + + +// _AddOnAt +DiskSystemAddOnManager::AddOn* +DiskSystemAddOnManager::_AddOnAt(int32 index) const +{ + return (AddOn*)fAddOns.ItemAt(index); +} + diff --git a/src/kits/storage/DiskSystemAddOnManager.h b/src/kits/storage/DiskSystemAddOnManager.h new file mode 100644 index 0000000000..a75ef0e25e --- /dev/null +++ b/src/kits/storage/DiskSystemAddOnManager.h @@ -0,0 +1,58 @@ +/* + * Copyright 2007, Ingo Weinhold, bonefish@users.sf.net. + * Distributed under the terms of the MIT License. + */ +#ifndef _DISK_SYSTEM_ADD_ON_MANAGER_H +#define _DISK_SYSTEM_ADD_ON_MANAGER_H + +#include +#include + + +class BDiskSystemAddOn; + + +namespace BPrivate { + + +class DiskSystemAddOnManager { +public: + static DiskSystemAddOnManager* Default(); + + bool Lock(); + void Unlock(); + + // load/unload all disk system add-ons + void LoadDiskSystems(); + void UnloadDiskSystems(); + + // manager must be locked + int32 CountAddOns() const; + BDiskSystemAddOn* AddOnAt(int32 index) const; + + // manager will be locked + BDiskSystemAddOn* GetAddOn(const char* name); + void PutAddOn(BDiskSystemAddOn* addOn); + +private: + struct AddOnImage; + struct AddOn; + + DiskSystemAddOnManager(); + + AddOn* _AddOnAt(int32 index) const; + +private: + mutable BLocker fLock; + BList fAddOns; + int32 fLoadCount; + + static DiskSystemAddOnManager* sManager; +}; + + +} // namespace BPrivate + +using BPrivate::DiskSystemAddOnManager; + +#endif // _DISK_SYSTEM_ADD_ON_MANAGER_H diff --git a/src/kits/storage/Jamfile b/src/kits/storage/Jamfile index a392d8bb1e..81a639a5b1 100644 --- a/src/kits/storage/Jamfile +++ b/src/kits/storage/Jamfile @@ -79,7 +79,10 @@ MergeObject storage_kit.o : DiskDeviceVisitor.cpp DiskSystem.cpp DiskSystemAddOn.cpp + DiskSystemAddOnManager.cpp + MutablePartition.cpp Partition.cpp + PartitionDelegate.cpp PartitioningInfo.cpp ; diff --git a/src/kits/storage/MutablePartition.cpp b/src/kits/storage/MutablePartition.cpp new file mode 100644 index 0000000000..e9350852e7 --- /dev/null +++ b/src/kits/storage/MutablePartition.cpp @@ -0,0 +1,372 @@ +/* + * Copyright 2007, Ingo Weinhold, bonefish@users.sf.net. + * Distributed under the terms of the MIT License. + */ + +#include + +#include +#include + +#include + +#include + + +using std::nothrow; + + +// set_string +static status_t +set_string(char*& location, const char* newString) +{ + char* string = NULL; + if (newString) { + string = strdup(newString); + if (!string) + return B_NO_MEMORY; + } + + free(location); + location = string; + + return B_OK; +} + + +#define SET_STRING_RETURN_ON_ERROR(location, string) \ +{ \ + status_t error = set_string(location, string); \ + if (error != B_OK) \ + return error; \ +} + + +// Offset +off_t +BMutablePartition::Offset() const +{ + return fData->offset; +} + + +// SetOffset +void +BMutablePartition::SetOffset(off_t offset) +{ + fData->offset = offset; +} + + +// Size +off_t +BMutablePartition::Size() const +{ + return fData->size; +} + + +// SetSize +void +BMutablePartition::SetSize(off_t size) +{ + fData->size = size; +} + + +// ContentSize +off_t +BMutablePartition::ContentSize() const +{ + return fData->content_size; +} + + +// SetContentSize +void +BMutablePartition::SetContentSize(off_t size) +{ + fData->content_size = size; +} + + +// BlockSize +off_t +BMutablePartition::BlockSize() const +{ + return fData->block_size; +} + + +// SetBlockSize +void +BMutablePartition::SetBlockSize(off_t blockSize) +{ + fData->block_size = blockSize; +} + + +// Status +uint32 +BMutablePartition::Status() const +{ + return fData->status; +} + + +// Flags +uint32 +BMutablePartition::Flags() const +{ + return fData->flags; +} + + +// SetFlags +void +BMutablePartition::SetFlags(uint32 flags) +{ + fData->flags = flags; +} + + +// Volume +dev_t +BMutablePartition::Volume() const +{ + return fData->volume; +} + + +// Index +int32 +BMutablePartition::Index() const +{ + return fData->index; +} + + +// Name +const char* +BMutablePartition::Name() const +{ + return fData->name; +} + + +// SetName +status_t +BMutablePartition::SetName(const char* name) +{ + return set_string(fData->name, name); +} + + +// ContentName +const char* +BMutablePartition::ContentName() const +{ + return fData->content_name; +} + + +// SetContentName +status_t +BMutablePartition::SetContentName(const char* name) +{ + return set_string(fData->content_name, name); +} + + +// Type +const char* +BMutablePartition::Type() const +{ + return fData->type; +} + + +// SetType +status_t +BMutablePartition::SetType(const char* type) const +{ + return set_string(fData->type, type); +} + + +// ContentType +const char* +BMutablePartition::ContentType() const +{ + return fData->content_type; +} + + +// SetContentType +status_t +BMutablePartition::SetContentType(const char* type) const +{ + return set_string(fData->content_type, type); +} + + +// Parameters +const char* +BMutablePartition::Parameters() const +{ + return fData->parameters; +} + + +// SetParameters +status_t +BMutablePartition::SetParameters(const char* parameters) +{ + return set_string(fData->parameters, parameters); +} + + +// ContentParameters +const char* +BMutablePartition::ContentParameters() const +{ + return fData->content_parameters; +} + + +// SetContentParameters +status_t +BMutablePartition::SetContentParameters(const char* parameters) +{ + return set_string(fData->content_parameters, parameters); +} + + +// CreateChild +status_t +BMutablePartition::CreateChild(int32 index, BMutablePartition** child) +{ + // TODO: ... + return B_ERROR; +} + + +// DeleteChild +status_t +BMutablePartition::DeleteChild(int32 index) +{ + // TODO: ... + return B_ERROR; +} + + +// ChildAt +BMutablePartition* +BMutablePartition::ChildAt(int32 index) const +{ + return (BMutablePartition*)fChildren.ItemAt(index); +} + + +// CountChildren +int32 +BMutablePartition::CountChildren() const +{ + return fChildren.CountItems(); +} + + +// ChildCookie +void* +BMutablePartition::ChildCookie() const +{ + return fChildCookie; +} + + +// SetChildCookie +void +BMutablePartition::SetChildCookie(void* cookie) +{ + fChildCookie = cookie; +} + + +// constructor +BMutablePartition::BMutablePartition(BPartition::MutableDelegate* delegate) + : fDelegate(delegate), + fData(NULL), + fChildCookie(NULL) +{ +} + + +// Init +status_t +BMutablePartition::Init(const user_partition_data* partitionData) +{ + // allocate data structure + fData = new(nothrow) user_partition_data; + if (!fData) + return B_NO_MEMORY; + + memset(fData, 0, sizeof(user_partition_data)); + + // copy the flat data + fData->id = partitionData->id; + fData->offset = partitionData->offset; + fData->size = partitionData->size; + fData->content_size = partitionData->content_size; + fData->block_size = partitionData->block_size; + fData->status = partitionData->status; + fData->flags = partitionData->flags; + fData->volume = partitionData->volume; + fData->index = partitionData->index; + fData->change_counter = partitionData->change_counter; + fData->disk_system = partitionData->disk_system; + + // copy the strings + SET_STRING_RETURN_ON_ERROR(fData->name, partitionData->name); + SET_STRING_RETURN_ON_ERROR(fData->content_name, + partitionData->content_name); + SET_STRING_RETURN_ON_ERROR(fData->type, partitionData->type); + SET_STRING_RETURN_ON_ERROR(fData->content_type, + partitionData->content_type); + SET_STRING_RETURN_ON_ERROR(fData->parameters, partitionData->parameters); + SET_STRING_RETURN_ON_ERROR(fData->content_parameters, + partitionData->content_parameters); + + return B_OK; +} + + +// destructor +BMutablePartition::~BMutablePartition() +{ + if (fData) { + free(fData->name); + free(fData->content_name); + free(fData->type); + free(fData->content_type); + free(fData->parameters); + free(fData->content_parameters); + delete fData; + } +} + + +// PartitionData +const user_partition_data* +BMutablePartition::PartitionData() const +{ + return fData; +} + + +// GetDelegate +BPartition::MutableDelegate* +BMutablePartition::GetDelegate() const +{ + return fDelegate; +} + diff --git a/src/kits/storage/PartitionDelegate.cpp b/src/kits/storage/PartitionDelegate.cpp new file mode 100644 index 0000000000..abcf8cde78 --- /dev/null +++ b/src/kits/storage/PartitionDelegate.cpp @@ -0,0 +1,572 @@ +/* + * Copyright 2007, Ingo Weinhold, bonefish@users.sf.net. + * Distributed under the terms of the MIT License. + */ + +#include "PartitionDelegate.h" + +#include + +#include "DiskSystemAddOnManager.h" + + +// #pragma mark - Delegate + + +// constructor +BPartition::Delegate::Delegate(BPartition* partition) + : fPartition(partition) +{ +} + + +// destructor +BPartition::Delegate::~Delegate() +{ +} + + +// #pragma mark - MutableDelegate + + +// constructor +BPartition::MutableDelegate::MutableDelegate(BPartition* partition) + : Delegate(partition), + fMutablePartition(this), + fDiskSystem(NULL), + fPartitionHandle(NULL) +{ +} + + +// destructor +BPartition::MutableDelegate::~MutableDelegate() +{ +} + + +// MutablePartition +BMutablePartition* +BPartition::MutableDelegate::MutablePartition() +{ + return &fMutablePartition; +} + + +// MutablePartition +const BMutablePartition* +BPartition::MutableDelegate::MutablePartition() const +{ + return &fMutablePartition; +} + + +// Init +status_t +BPartition::MutableDelegate::Init(const user_partition_data* partitionData) +{ + status_t error = fMutablePartition.Init(partitionData); + if (error != B_OK) + return error; + + if (!fMutablePartition.ContentType()) + return B_OK; + + // init disk system and handle + DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default(); + BDiskSystemAddOn* addOn = manager->GetAddOn( + fMutablePartition.ContentType()); + if (!addOn) + return B_ENTRY_NOT_FOUND; + + BPartitionHandle* handle; + error = addOn->CreatePartitionHandle(&fMutablePartition, &handle); + if (error != B_OK) { + manager->PutAddOn(addOn); + return error; + } + + // everything went fine --keep the disk system add-on reference and the + // handle + fDiskSystem = addOn; + fPartitionHandle = handle; + + return B_OK; +} + + +// PartitionData +const user_partition_data* +BPartition::MutableDelegate::PartitionData() const +{ + return fMutablePartition.PartitionData(); +} + + +// ChildAt +BPartition::Delegate* +BPartition::MutableDelegate::ChildAt(int32 index) const +{ + BMutablePartition* child = fMutablePartition.ChildAt(index); + return child ? child->GetDelegate() : NULL; +} + + +// CountChildren +int32 +BPartition::MutableDelegate::CountChildren() const +{ + return fMutablePartition.CountChildren(); +} + + +// SupportedOperations +uint32 +BPartition::MutableDelegate::SupportedOperations(uint32 mask) +{ + if (!fPartitionHandle) + return 0; + + return fPartitionHandle->SupportedOperations(mask); +} + + +// SupportedChildOperations +uint32 +BPartition::MutableDelegate::SupportedChildOperations(Delegate* child, + uint32 mask) +{ + if (!fPartitionHandle) + return 0; + + return fPartitionHandle->SupportedChildOperations( + ((MutableDelegate*)child)->MutablePartition(), mask); +} + + +// Defragment +status_t +BPartition::MutableDelegate::Defragment() +{ +// TODO: Implement! + return B_BAD_VALUE; +} + + +// Repair +status_t +BPartition::MutableDelegate::Repair(bool checkOnly) +{ +// TODO: Implement! + return B_BAD_VALUE; +} + + +// ValidateResize +status_t +BPartition::MutableDelegate::ValidateResize(off_t* size) const +{ + if (!fPartitionHandle) + return B_NO_INIT; + + return fPartitionHandle->ValidateResize(size) ? B_OK : B_BAD_VALUE; +} + + +// ValidateResizeChild +status_t +BPartition::MutableDelegate::ValidateResizeChild(Delegate* _child, + off_t* size) const +{ + MutableDelegate* child = dynamic_cast(_child); + + if (!fPartitionHandle || !child) + return B_NO_INIT; + + return fPartitionHandle->ValidateResizeChild(&child->fMutablePartition, + size) ? B_OK : B_BAD_VALUE; +} + + +// Resize +status_t +BPartition::MutableDelegate::Resize(off_t size) +{ + if (!fPartitionHandle) + return B_NO_INIT; + + return fPartitionHandle->Resize(size); +} + + +// ResizeChild +status_t +BPartition::MutableDelegate::ResizeChild(Delegate* _child, off_t size) +{ + MutableDelegate* child = dynamic_cast(_child); + + if (!fPartitionHandle || !child) + return B_NO_INIT; + + return fPartitionHandle->ResizeChild(&child->fMutablePartition, size); +} + + +// ValidateMove +status_t +BPartition::MutableDelegate::ValidateMove(off_t* offset) const +{ + if (!fPartitionHandle) + return B_NO_INIT; + + return fPartitionHandle->ValidateMove(offset) ? B_OK : B_BAD_VALUE; +} + + +// ValidateMoveChild +status_t +BPartition::MutableDelegate::ValidateMoveChild(Delegate* _child, + off_t* offset) const +{ + MutableDelegate* child = dynamic_cast(_child); + + if (!fPartitionHandle || !child) + return B_NO_INIT; + + return fPartitionHandle->ValidateMoveChild(&child->fMutablePartition, + offset) ? B_OK : B_BAD_VALUE; +} + + +// Move +status_t +BPartition::MutableDelegate::Move(off_t offset) +{ + if (!fPartitionHandle) + return B_NO_INIT; + + return fPartitionHandle->Move(offset); +} + + +// MoveChild +status_t +BPartition::MutableDelegate::MoveChild(Delegate* _child, off_t offset) +{ + MutableDelegate* child = dynamic_cast(_child); + + if (!fPartitionHandle || !child) + return B_NO_INIT; + + return fPartitionHandle->MoveChild(&child->fMutablePartition, offset); +} + + +// ValidateSetContentName +status_t +BPartition::MutableDelegate::ValidateSetContentName(BString* name) const +{ + if (!fPartitionHandle) + return B_NO_INIT; + + return fPartitionHandle->ValidateSetContentName(name) ? B_OK : B_BAD_VALUE; +} + + +// ValidateSetName +status_t +BPartition::MutableDelegate::ValidateSetName(Delegate* _child, + BString* name) const +{ + MutableDelegate* child = dynamic_cast(_child); + + if (!fPartitionHandle || !child) + return B_NO_INIT; + + return fPartitionHandle->ValidateSetName(&child->fMutablePartition, name) + ? B_OK : B_BAD_VALUE; +} + + +// SetContentName +status_t +BPartition::MutableDelegate::SetContentName(const char* name) +{ + if (!fPartitionHandle) + return B_NO_INIT; + + return fPartitionHandle->SetContentName(name); +} + + +// SetName +status_t +BPartition::MutableDelegate::SetName(Delegate* _child, const char* name) +{ + MutableDelegate* child = dynamic_cast(_child); + + if (!fPartitionHandle || !child) + return B_NO_INIT; + + return fPartitionHandle->SetName(&child->fMutablePartition, name); +} + + +// ValidateSetType +status_t +BPartition::MutableDelegate::ValidateSetType(Delegate* _child, + const char* type) const +{ + MutableDelegate* child = dynamic_cast(_child); + + if (!fPartitionHandle || !child) + return B_NO_INIT; + + return fPartitionHandle->ValidateSetType(&child->fMutablePartition, type) + ? B_OK : B_BAD_VALUE; +} + + +// SetType +status_t +BPartition::MutableDelegate::SetType(Delegate* _child, const char* type) +{ + MutableDelegate* child = dynamic_cast(_child); + + if (!fPartitionHandle || !child) + return B_NO_INIT; + + return fPartitionHandle->SetType(&child->fMutablePartition, type); +} + + +// GetContentParameterEditor +status_t +BPartition::MutableDelegate::GetContentParameterEditor( + BDiskDeviceParameterEditor** editor) const +{ + if (!fPartitionHandle) + return B_NO_INIT; + + return fPartitionHandle->GetContentParameterEditor(editor); +} + + +// GetParameterEditor +status_t +BPartition::MutableDelegate::GetParameterEditor(Delegate* _child, + BDiskDeviceParameterEditor** editor) const +{ + MutableDelegate* child = dynamic_cast(_child); + + if (!fPartitionHandle || !child) + return B_NO_INIT; + + return fPartitionHandle->GetParameterEditor(&child->fMutablePartition, + editor); +} + + +// SetContentParameters +status_t +BPartition::MutableDelegate::SetContentParameters(const char* parameters) +{ + if (!fPartitionHandle) + return B_NO_INIT; + + return fPartitionHandle->SetContentParameters(parameters); +} + + +// SetParameters +status_t +BPartition::MutableDelegate::SetParameters(Delegate* _child, + const char* parameters) +{ + MutableDelegate* child = dynamic_cast(_child); + + if (!fPartitionHandle || !child) + return B_NO_INIT; + + return fPartitionHandle->SetParameters(&child->fMutablePartition, + parameters); +} + + +// CanInitialize +bool +BPartition::MutableDelegate::CanInitialize(const char* diskSystem) const +{ + // get the disk system add-on + DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default(); + BDiskSystemAddOn* addOn = manager->GetAddOn(diskSystem); + if (!addOn) + return false; + + bool result = addOn->CanInitialize(&fMutablePartition); + + // put the add-on + manager->PutAddOn(addOn); + + return result; +} + + +// GetInitializationParameterEditor +status_t +BPartition::MutableDelegate::GetInitializationParameterEditor( + const char* diskSystem, BDiskDeviceParameterEditor** editor) const +{ + // get the disk system add-on + DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default(); + BDiskSystemAddOn* addOn = manager->GetAddOn(diskSystem); + if (!addOn) + return B_ENTRY_NOT_FOUND; + + status_t result = addOn->GetInitializationParameterEditor( + &fMutablePartition, editor); + + // put the add-on + manager->PutAddOn(addOn); + + return result; +} + + +// ValidateInitialize +status_t +BPartition::MutableDelegate::ValidateInitialize(const char* diskSystem, + BString* name, const char* parameters) +{ + // get the disk system add-on + DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default(); + BDiskSystemAddOn* addOn = manager->GetAddOn(diskSystem); + if (!addOn) + return B_ENTRY_NOT_FOUND; + + bool result = addOn->ValidateInitialize(&fMutablePartition, + name, parameters); + + // put the add-on + manager->PutAddOn(addOn); + + return result ? B_OK : B_BAD_VALUE; +} + + +// Initialize +status_t +BPartition::MutableDelegate::Initialize(const char* diskSystem, + const char* name, const char* parameters) +{ + // get the disk system add-on + DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default(); + BDiskSystemAddOn* addOn = manager->GetAddOn(diskSystem); + if (!addOn) + return B_ENTRY_NOT_FOUND; + + BPartitionHandle* handle; + status_t result = addOn->Initialize(&fMutablePartition, name, parameters, + &handle); + + // keep the add-on or put it on error + if (result == B_OK) { + // TODO: This won't suffice. If this partition had children, we have + // to delete them before the new disk system plays with it. + _FreeHandle(); + fDiskSystem = addOn; + fPartitionHandle = handle; + } else { + manager->PutAddOn(addOn); + } + + return result; +} + + +// Uninitialize +status_t +BPartition::MutableDelegate::Uninitialize() +{ + if (fPartitionHandle) { + _FreeHandle(); + + // TODO: Uninitialize fMutablePartition! + } + + return B_OK; +} + + +// GetChildCreationParameterEditor +status_t +BPartition::MutableDelegate::GetChildCreationParameterEditor(const char* type, + BDiskDeviceParameterEditor** editor) const +{ + if (!fPartitionHandle) + return B_NO_INIT; + + return fPartitionHandle->GetChildCreationParameterEditor(type, editor); +} + + +// ValidateCreateChild +status_t +BPartition::MutableDelegate::ValidateCreateChild(off_t* start, off_t* size, + const char* type, const char* parameters) const +{ + if (!fPartitionHandle) + return B_NO_INIT; + + return fPartitionHandle->ValidateCreateChild(start, size, type, parameters) + ? B_OK : B_BAD_VALUE; +} + + +// CreateChild +status_t +BPartition::MutableDelegate::CreateChild(off_t start, off_t size, + const char* type, const char* parameters, BPartition** child) +{ + if (!fPartitionHandle) + return B_NO_INIT; + + BMutablePartition* mutableChild; + status_t error = fPartitionHandle->CreateChild(start, size, type, + parameters, &mutableChild); + if (error != B_OK) + return error; + + if (child) + *child = mutableChild->GetDelegate()->Partition(); + + return B_OK; +} + + +// DeleteChild +status_t +BPartition::MutableDelegate::DeleteChild(Delegate* _child) +{ + MutableDelegate* child = dynamic_cast(_child); + + if (!fPartitionHandle || !child) + return B_NO_INIT; + + return fPartitionHandle->DeleteChild(&child->fMutablePartition); +} + + +// _FreeHandle +void +BPartition::MutableDelegate::_FreeHandle() +{ + if (fPartitionHandle) { + delete fPartitionHandle; + fPartitionHandle = NULL; + + DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default(); + manager->PutAddOn(fDiskSystem); + fDiskSystem = NULL; + } +} diff --git a/src/kits/storage/PartitionDelegate.h b/src/kits/storage/PartitionDelegate.h new file mode 100644 index 0000000000..6e6f5c09d4 --- /dev/null +++ b/src/kits/storage/PartitionDelegate.h @@ -0,0 +1,197 @@ +/* + * Copyright 2007, Ingo Weinhold, bonefish@users.sf.net. + * Distributed under the terms of the MIT License. + */ +#ifndef _PARTITION_DELEGATE_H +#define _PARTITION_DELEGATE_H + +#include +#include + + +class BDiskSystemAddOn; +class BPartitionHandle; + + +class BPartition::Delegate { +public: + Delegate(BPartition* partition); + virtual ~Delegate(); + + virtual status_t Init(const user_partition_data* partitionData) + = 0; + + BPartition* Partition() const { return fPartition; } + + virtual const user_partition_data* PartitionData() const = 0; + + virtual Delegate* ChildAt(int32 index) const = 0; + virtual int32 CountChildren() const = 0; + + virtual uint32 SupportedOperations(uint32 mask) = 0; + virtual uint32 SupportedChildOperations(Delegate* child, + uint32 mask) = 0; + + // Self Modification + + virtual status_t Defragment() = 0; + virtual status_t Repair(bool checkOnly) = 0; + + virtual status_t ValidateResize(off_t* size) const = 0; + virtual status_t ValidateResizeChild(Delegate* child, + off_t* size) const = 0; + virtual status_t Resize(off_t size) = 0; + virtual status_t ResizeChild(Delegate* child, off_t size) = 0; + + virtual status_t ValidateMove(off_t* offset) const = 0; + virtual status_t ValidateMoveChild(Delegate* child, + off_t* offset) const = 0; + virtual status_t Move(off_t offset) = 0; + virtual status_t MoveChild(Delegate* child, off_t offset) = 0; + + virtual status_t ValidateSetContentName(BString* name) const = 0; + virtual status_t ValidateSetName(Delegate* child, + BString* name) const = 0; + virtual status_t SetContentName(const char* name) = 0; + virtual status_t SetName(Delegate* child, const char* name) = 0; + + virtual status_t ValidateSetType(Delegate* child, + const char* type) const = 0; + virtual status_t SetType(Delegate* child, const char* type) = 0; + + virtual status_t GetContentParameterEditor( + BDiskDeviceParameterEditor** editor) + const = 0; + virtual status_t GetParameterEditor(Delegate* child, + BDiskDeviceParameterEditor** editor) + const = 0; + virtual status_t SetContentParameters( + const char* parameters) = 0; + virtual status_t SetParameters(Delegate* child, + const char* parameters) = 0; + + virtual bool CanInitialize(const char* diskSystem) const = 0; + virtual status_t GetInitializationParameterEditor( + const char* system, + BDiskDeviceParameterEditor** editor) + const = 0; + virtual status_t ValidateInitialize(const char* diskSystem, + BString* name, const char* parameters) = 0; + virtual status_t Initialize(const char* diskSystem, + const char* name, + const char* parameters) = 0; + virtual status_t Uninitialize() = 0; + + // Modification of child partitions + + virtual status_t GetChildCreationParameterEditor( + const char* system, + BDiskDeviceParameterEditor** editor) + const = 0; + virtual status_t ValidateCreateChild(off_t* start, off_t* size, + const char* type, + const char* parameters) const = 0; + virtual status_t CreateChild(off_t start, off_t size, + const char* type, const char* parameters, + BPartition** child) = 0; + + virtual status_t DeleteChild(Delegate* child) = 0; + + +protected: + BPartition* fPartition; +}; + + +class BPartition::MutableDelegate : BPartition::Delegate { +public: + MutableDelegate(BPartition* partition); + virtual ~MutableDelegate(); + + BMutablePartition* MutablePartition(); + const BMutablePartition* MutablePartition() const; + + virtual status_t Init(const user_partition_data* partitionData); + + virtual const user_partition_data* PartitionData() const; + + virtual Delegate* ChildAt(int32 index) const; + virtual int32 CountChildren() const; + + virtual uint32 SupportedOperations(uint32 mask); + virtual uint32 SupportedChildOperations(Delegate* child, + uint32 mask); + + // Self Modification + + virtual status_t Defragment(); + virtual status_t Repair(bool checkOnly); + + virtual status_t ValidateResize(off_t* size) const = 0; + virtual status_t ValidateResizeChild(Delegate* child, + off_t* size) const = 0; + virtual status_t Resize(off_t size) = 0; + virtual status_t ResizeChild(Delegate* child, off_t size) = 0; + + virtual status_t ValidateMove(off_t* offset) const = 0; + virtual status_t ValidateMoveChild(Delegate* child, + off_t* offset) const = 0; + virtual status_t Move(off_t offset) = 0; + virtual status_t MoveChild(Delegate* child, off_t offset) = 0; + + virtual status_t ValidateSetContentName(BString* name) const; + virtual status_t ValidateSetName(Delegate* child, + BString* name) const; + virtual status_t SetContentName(const char* name); + virtual status_t SetName(Delegate* child, const char* name); + + virtual status_t ValidateSetType(Delegate* child, + const char* type) const; + virtual status_t SetType(Delegate* child, const char* type); + + virtual status_t GetContentParameterEditor( + BDiskDeviceParameterEditor** editor) const; + virtual status_t GetParameterEditor(Delegate* child, + BDiskDeviceParameterEditor** editor) const; + virtual status_t SetContentParameters(const char* parameters); + virtual status_t SetParameters(Delegate* child, + const char* parameters); + + virtual bool CanInitialize(const char* diskSystem) const; + virtual status_t GetInitializationParameterEditor( + const char* system, + BDiskDeviceParameterEditor** editor) const; + virtual status_t ValidateInitialize(const char* diskSystem, + BString* name, const char* parameters); + virtual status_t Initialize(const char* diskSystem, + const char* name, + const char* parameters); + virtual status_t Uninitialize(); + + // Modification of child partitions + + virtual status_t GetChildCreationParameterEditor( + const char* system, + BDiskDeviceParameterEditor** editor) const; + virtual status_t ValidateCreateChild(off_t* start, off_t* size, + const char* type, + const char* parameters) const; + virtual status_t CreateChild(off_t start, off_t size, + const char* type, const char* parameters, + BPartition** child); + + virtual status_t DeleteChild(Delegate* child); + +private: + void _FreeHandle(); + +private: +// friend class BMutablePartition; + + BMutablePartition fMutablePartition; + BDiskSystemAddOn* fDiskSystem; + BPartitionHandle* fPartitionHandle; +}; + + +#endif // _PARTITION_DELEGATE_H