* Copyright 2007, Ingo Weinhold, bonefish@users.sf.net.
* Distributed under the terms of the MIT License.
*/
#include "PartitionDelegate.h"
#include <stdio.h>
#include <DiskSystemAddOn.h>
#include <DiskSystemAddOnManager.h>
#undef TRACE
#ifdef TRACE_PARTITION_DELEGATE
# define TRACE(x...) printf(x)
#else
# define TRACE(x...) do {} while (false)
#endif
BPartition::Delegate::Delegate(BPartition* partition)
:
fPartition(partition),
fMutablePartition(this),
fDiskSystem(NULL),
fPartitionHandle(NULL)
{
}
BPartition::Delegate::~Delegate()
{
}
BMutablePartition*
BPartition::Delegate::MutablePartition()
{
return &fMutablePartition;
}
const BMutablePartition*
BPartition::Delegate::MutablePartition() const
{
return &fMutablePartition;
}
status_t
BPartition::Delegate::InitHierarchy(
const user_partition_data* partitionData, Delegate* parent)
{
return fMutablePartition.Init(partitionData,
parent ? &parent->fMutablePartition : NULL);
}
status_t
BPartition::Delegate::InitAfterHierarchy()
{
TRACE("%p->BPartition::Delegate::InitAfterHierarchy()\n", this);
if (!fMutablePartition.ContentType()) {
TRACE(" no content type\n");
return B_OK;
}
DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default();
BDiskSystemAddOn* addOn = manager->GetAddOn(
fMutablePartition.ContentType());
if (!addOn) {
TRACE(" add-on for disk system \"%s\" not found\n",
fMutablePartition.ContentType());
return B_OK;
}
BPartitionHandle* handle;
status_t error = addOn->CreatePartitionHandle(&fMutablePartition, &handle);
if (error != B_OK) {
TRACE(" failed to create partition handle for partition %ld, disk "
"system: \"%s\": %s\n",
Partition()->ID(), addOn->Name(), strerror(error));
manager->PutAddOn(addOn);
return error;
}
fDiskSystem = addOn;
fPartitionHandle = handle;
return B_OK;
}
const user_partition_data*
BPartition::Delegate::PartitionData() const
{
return fMutablePartition.PartitionData();
}
BPartition::Delegate*
BPartition::Delegate::ChildAt(int32 index) const
{
BMutablePartition* child = fMutablePartition.ChildAt(index);
return child ? child->GetDelegate() : NULL;
}
int32
BPartition::Delegate::CountChildren() const
{
return fMutablePartition.CountChildren();
}
bool
BPartition::Delegate::IsModified() const
{
return fMutablePartition.ChangeFlags() != 0;
}
uint32
BPartition::Delegate::SupportedOperations(uint32 mask)
{
if (!fPartitionHandle)
return 0;
return fPartitionHandle->SupportedOperations(mask);
}
uint32
BPartition::Delegate::SupportedChildOperations(Delegate* child,
uint32 mask)
{
if (!fPartitionHandle)
return 0;
return fPartitionHandle->SupportedChildOperations(child->MutablePartition(),
mask);
}
status_t
BPartition::Delegate::Defragment()
{
return B_BAD_VALUE;
}
status_t
BPartition::Delegate::Repair(bool checkOnly)
{
if (fPartitionHandle == NULL)
return B_NO_INIT;
return fPartitionHandle->Repair(checkOnly);
}
status_t
BPartition::Delegate::ValidateResize(off_t* size) const
{
if (!fPartitionHandle)
return B_NO_INIT;
return fPartitionHandle->ValidateResize(size);
}
status_t
BPartition::Delegate::ValidateResizeChild(Delegate* child, off_t* size) const
{
if (!fPartitionHandle || !child)
return B_NO_INIT;
return fPartitionHandle->ValidateResizeChild(&child->fMutablePartition,
size);
}
status_t
BPartition::Delegate::Resize(off_t size)
{
if (!fPartitionHandle)
return B_NO_INIT;
return fPartitionHandle->Resize(size);
}
status_t
BPartition::Delegate::ResizeChild(Delegate* child, off_t size)
{
if (!fPartitionHandle || !child)
return B_NO_INIT;
return fPartitionHandle->ResizeChild(&child->fMutablePartition, size);
}
status_t
BPartition::Delegate::ValidateMove(off_t* offset) const
{
if (!fPartitionHandle)
return B_NO_INIT;
return fPartitionHandle->ValidateMove(offset);
}
status_t
BPartition::Delegate::ValidateMoveChild(Delegate* child, off_t* offset) const
{
if (!fPartitionHandle || !child)
return B_NO_INIT;
return fPartitionHandle->ValidateMoveChild(&child->fMutablePartition,
offset);
}
status_t
BPartition::Delegate::Move(off_t offset)
{
if (!fPartitionHandle)
return B_NO_INIT;
return fPartitionHandle->Move(offset);
}
status_t
BPartition::Delegate::MoveChild(Delegate* child, off_t offset)
{
if (!fPartitionHandle || !child)
return B_NO_INIT;
return fPartitionHandle->MoveChild(&child->fMutablePartition, offset);
}
status_t
BPartition::Delegate::ValidateSetContentName(BString* name) const
{
if (!fPartitionHandle)
return B_NO_INIT;
return fPartitionHandle->ValidateSetContentName(name);
}
status_t
BPartition::Delegate::ValidateSetName(Delegate* child, BString* name) const
{
if (!fPartitionHandle || !child)
return B_NO_INIT;
return fPartitionHandle->ValidateSetName(&child->fMutablePartition, name);
}
status_t
BPartition::Delegate::SetContentName(const char* name)
{
if (!fPartitionHandle)
return B_NO_INIT;
return fPartitionHandle->SetContentName(name);
}
status_t
BPartition::Delegate::SetName(Delegate* child, const char* name)
{
if (!fPartitionHandle || !child)
return B_NO_INIT;
return fPartitionHandle->SetName(&child->fMutablePartition, name);
}
status_t
BPartition::Delegate::ValidateSetType(Delegate* child, const char* type) const
{
if (!fPartitionHandle || !child)
return B_NO_INIT;
return fPartitionHandle->ValidateSetType(&child->fMutablePartition, type);
}
status_t
BPartition::Delegate::SetType(Delegate* child, const char* type)
{
if (!fPartitionHandle || !child)
return B_NO_INIT;
return fPartitionHandle->SetType(&child->fMutablePartition, type);
}
status_t
BPartition::Delegate::SetContentParameters(const char* parameters)
{
if (!fPartitionHandle)
return B_NO_INIT;
return fPartitionHandle->SetContentParameters(parameters);
}
status_t
BPartition::Delegate::SetParameters(Delegate* child, const char* parameters)
{
if (!fPartitionHandle || !child)
return B_NO_INIT;
return fPartitionHandle->SetParameters(&child->fMutablePartition,
parameters);
}
status_t
BPartition::Delegate::GetNextSupportedChildType(Delegate* child,
int32* cookie, BString* type) const
{
TRACE("%p->BPartition::Delegate::GetNextSupportedChildType(child: %p, "
"cookie: %ld)\n", this, child, *cookie);
if (!fPartitionHandle) {
TRACE(" no partition handle!\n");
return B_NO_INIT;
}
return fPartitionHandle->GetNextSupportedType(
child ? &child->fMutablePartition : NULL, cookie, type);
}
bool
BPartition::Delegate::IsSubSystem(Delegate* child,
const char* diskSystem) const
{
DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default();
BDiskSystemAddOn* addOn = manager->GetAddOn(diskSystem);
if (!addOn)
return false;
bool result = addOn->IsSubSystemFor(&child->fMutablePartition);
manager->PutAddOn(addOn);
return result;
}
bool
BPartition::Delegate::CanInitialize(const char* diskSystem) const
{
DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default();
BDiskSystemAddOn* addOn = manager->GetAddOn(diskSystem);
if (!addOn)
return false;
bool result = addOn->CanInitialize(&fMutablePartition);
manager->PutAddOn(addOn);
return result;
}
status_t
BPartition::Delegate::ValidateInitialize(const char* diskSystem,
BString* name, const char* parameters)
{
DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default();
BDiskSystemAddOn* addOn = manager->GetAddOn(diskSystem);
if (!addOn)
return B_ENTRY_NOT_FOUND;
status_t result = addOn->ValidateInitialize(&fMutablePartition,
name, parameters);
manager->PutAddOn(addOn);
return result;
}
status_t
BPartition::Delegate::Initialize(const char* diskSystem,
const char* name, const char* parameters)
{
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);
if (result == B_OK) {
_FreeHandle();
fDiskSystem = addOn;
fPartitionHandle = handle;
} else {
manager->PutAddOn(addOn);
}
return result;
}
status_t
BPartition::Delegate::Uninitialize()
{
if (fPartitionHandle) {
_FreeHandle();
fMutablePartition.UninitializeContents();
}
return B_OK;
}
status_t
BPartition::Delegate::GetPartitioningInfo(BPartitioningInfo* info)
{
if (!fPartitionHandle)
return B_NO_INIT;
return fPartitionHandle->GetPartitioningInfo(info);
}
status_t
BPartition::Delegate::GetParameterEditor(B_PARAMETER_EDITOR_TYPE type,
BPartitionParameterEditor** editor) const
{
if (!fPartitionHandle)
return B_NO_INIT;
return fPartitionHandle->GetParameterEditor(type, editor);
}
status_t
BPartition::Delegate::ValidateCreateChild(off_t* start, off_t* size,
const char* type, BString* name, const char* parameters) const
{
if (!fPartitionHandle)
return B_NO_INIT;
return fPartitionHandle->ValidateCreateChild(start, size, type, name,
parameters);
}
status_t
BPartition::Delegate::CreateChild(off_t start, off_t size, const char* type,
const char* name, const char* parameters, BPartition** child)
{
if (!fPartitionHandle)
return B_NO_INIT;
BMutablePartition* mutableChild;
status_t error = fPartitionHandle->CreateChild(start, size, type, name,
parameters, &mutableChild);
if (error != B_OK)
return error;
if (child)
*child = mutableChild->GetDelegate()->Partition();
return B_OK;
}
status_t
BPartition::Delegate::DeleteChild(Delegate* child)
{
if (!fPartitionHandle || !child)
return B_NO_INIT;
return fPartitionHandle->DeleteChild(&child->fMutablePartition);
}
void
BPartition::Delegate::_FreeHandle()
{
if (fPartitionHandle) {
delete fPartitionHandle;
fPartitionHandle = NULL;
DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default();
manager->PutAddOn(fDiskSystem);
fDiskSystem = NULL;
}
}