1/* 2 * Copyright 2007, Ingo Weinhold, bonefish@users.sf.net. 3 * Distributed under the terms of the MIT License. 4 */ 5 6#include "PartitionDelegate.h" 7 8#include <stdio.h> 9 10#include <DiskSystemAddOn.h> 11#include <DiskSystemAddOnManager.h> 12 13//#define TRACE_PARTITION_DELEGATE 14#undef TRACE 15#ifdef TRACE_PARTITION_DELEGATE 16# define TRACE(x...) printf(x) 17#else 18# define TRACE(x...) do {} while (false) 19#endif 20 21 22// constructor 23BPartition::Delegate::Delegate(BPartition* partition) 24 : 25 fPartition(partition), 26 fMutablePartition(this), 27 fDiskSystem(NULL), 28 fPartitionHandle(NULL) 29{ 30} 31 32 33// destructor 34BPartition::Delegate::~Delegate() 35{ 36} 37 38 39// MutablePartition 40BMutablePartition* 41BPartition::Delegate::MutablePartition() 42{ 43 return &fMutablePartition; 44} 45 46 47// MutablePartition 48const BMutablePartition* 49BPartition::Delegate::MutablePartition() const 50{ 51 return &fMutablePartition; 52} 53 54 55// InitHierarchy 56status_t 57BPartition::Delegate::InitHierarchy( 58 const user_partition_data* partitionData, Delegate* parent) 59{ 60 return fMutablePartition.Init(partitionData, 61 parent ? &parent->fMutablePartition : NULL); 62} 63 64 65// InitAfterHierarchy 66status_t 67BPartition::Delegate::InitAfterHierarchy() 68{ 69 TRACE("%p->BPartition::Delegate::InitAfterHierarchy()\n", this); 70 71 if (!fMutablePartition.ContentType()) { 72 TRACE(" no content type\n"); 73 return B_OK; 74 } 75 76 // init disk system and handle 77 DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default(); 78 BDiskSystemAddOn* addOn = manager->GetAddOn( 79 fMutablePartition.ContentType()); 80 if (!addOn) { 81 TRACE(" add-on for disk system \"%s\" not found\n", 82 fMutablePartition.ContentType()); 83 return B_OK; 84 } 85 86 BPartitionHandle* handle; 87 status_t error = addOn->CreatePartitionHandle(&fMutablePartition, &handle); 88 if (error != B_OK) { 89 TRACE(" failed to create partition handle for partition %ld, disk " 90 "system: \"%s\": %s\n", 91 Partition()->ID(), addOn->Name(), strerror(error)); 92 manager->PutAddOn(addOn); 93 return error; 94 } 95 96 // everything went fine -- keep the disk system add-on reference and the 97 // handle 98 fDiskSystem = addOn; 99 fPartitionHandle = handle; 100 101 return B_OK; 102} 103 104 105// PartitionData 106const user_partition_data* 107BPartition::Delegate::PartitionData() const 108{ 109 return fMutablePartition.PartitionData(); 110} 111 112 113// ChildAt 114BPartition::Delegate* 115BPartition::Delegate::ChildAt(int32 index) const 116{ 117 BMutablePartition* child = fMutablePartition.ChildAt(index); 118 return child ? child->GetDelegate() : NULL; 119} 120 121 122// CountChildren 123int32 124BPartition::Delegate::CountChildren() const 125{ 126 return fMutablePartition.CountChildren(); 127} 128 129 130// IsModified 131bool 132BPartition::Delegate::IsModified() const 133{ 134 return fMutablePartition.ChangeFlags() != 0; 135} 136 137 138// SupportedOperations 139uint32 140BPartition::Delegate::SupportedOperations(uint32 mask) 141{ 142 if (!fPartitionHandle) 143 return 0; 144 145 return fPartitionHandle->SupportedOperations(mask); 146} 147 148 149// SupportedChildOperations 150uint32 151BPartition::Delegate::SupportedChildOperations(Delegate* child, 152 uint32 mask) 153{ 154 if (!fPartitionHandle) 155 return 0; 156 157 return fPartitionHandle->SupportedChildOperations(child->MutablePartition(), 158 mask); 159} 160 161 162// Defragment 163status_t 164BPartition::Delegate::Defragment() 165{ 166// TODO: Implement! 167 return B_BAD_VALUE; 168} 169 170 171// Repair 172status_t 173BPartition::Delegate::Repair(bool checkOnly) 174{ 175 if (fPartitionHandle == NULL) 176 return B_NO_INIT; 177 178 return fPartitionHandle->Repair(checkOnly); 179} 180 181 182// ValidateResize 183status_t 184BPartition::Delegate::ValidateResize(off_t* size) const 185{ 186 if (!fPartitionHandle) 187 return B_NO_INIT; 188 189 return fPartitionHandle->ValidateResize(size); 190} 191 192 193// ValidateResizeChild 194status_t 195BPartition::Delegate::ValidateResizeChild(Delegate* child, off_t* size) const 196{ 197 if (!fPartitionHandle || !child) 198 return B_NO_INIT; 199 200 return fPartitionHandle->ValidateResizeChild(&child->fMutablePartition, 201 size); 202} 203 204 205// Resize 206status_t 207BPartition::Delegate::Resize(off_t size) 208{ 209 if (!fPartitionHandle) 210 return B_NO_INIT; 211 212 return fPartitionHandle->Resize(size); 213} 214 215 216// ResizeChild 217status_t 218BPartition::Delegate::ResizeChild(Delegate* child, off_t size) 219{ 220 if (!fPartitionHandle || !child) 221 return B_NO_INIT; 222 223 return fPartitionHandle->ResizeChild(&child->fMutablePartition, size); 224} 225 226 227// ValidateMove 228status_t 229BPartition::Delegate::ValidateMove(off_t* offset) const 230{ 231 if (!fPartitionHandle) 232 return B_NO_INIT; 233 234 return fPartitionHandle->ValidateMove(offset); 235} 236 237 238// ValidateMoveChild 239status_t 240BPartition::Delegate::ValidateMoveChild(Delegate* child, off_t* offset) const 241{ 242 if (!fPartitionHandle || !child) 243 return B_NO_INIT; 244 245 return fPartitionHandle->ValidateMoveChild(&child->fMutablePartition, 246 offset); 247} 248 249 250// Move 251status_t 252BPartition::Delegate::Move(off_t offset) 253{ 254 if (!fPartitionHandle) 255 return B_NO_INIT; 256 257 return fPartitionHandle->Move(offset); 258} 259 260 261// MoveChild 262status_t 263BPartition::Delegate::MoveChild(Delegate* child, off_t offset) 264{ 265 if (!fPartitionHandle || !child) 266 return B_NO_INIT; 267 268 return fPartitionHandle->MoveChild(&child->fMutablePartition, offset); 269} 270 271 272// ValidateSetContentName 273status_t 274BPartition::Delegate::ValidateSetContentName(BString* name) const 275{ 276 if (!fPartitionHandle) 277 return B_NO_INIT; 278 279 return fPartitionHandle->ValidateSetContentName(name); 280} 281 282 283// ValidateSetName 284status_t 285BPartition::Delegate::ValidateSetName(Delegate* child, BString* name) const 286{ 287 if (!fPartitionHandle || !child) 288 return B_NO_INIT; 289 290 return fPartitionHandle->ValidateSetName(&child->fMutablePartition, name); 291} 292 293 294// SetContentName 295status_t 296BPartition::Delegate::SetContentName(const char* name) 297{ 298 if (!fPartitionHandle) 299 return B_NO_INIT; 300 301 return fPartitionHandle->SetContentName(name); 302} 303 304 305// SetName 306status_t 307BPartition::Delegate::SetName(Delegate* child, const char* name) 308{ 309 if (!fPartitionHandle || !child) 310 return B_NO_INIT; 311 312 return fPartitionHandle->SetName(&child->fMutablePartition, name); 313} 314 315 316// ValidateSetType 317status_t 318BPartition::Delegate::ValidateSetType(Delegate* child, const char* type) const 319{ 320 if (!fPartitionHandle || !child) 321 return B_NO_INIT; 322 323 return fPartitionHandle->ValidateSetType(&child->fMutablePartition, type); 324} 325 326 327// SetType 328status_t 329BPartition::Delegate::SetType(Delegate* child, const char* type) 330{ 331 if (!fPartitionHandle || !child) 332 return B_NO_INIT; 333 334 return fPartitionHandle->SetType(&child->fMutablePartition, type); 335} 336 337 338// SetContentParameters 339status_t 340BPartition::Delegate::SetContentParameters(const char* parameters) 341{ 342 if (!fPartitionHandle) 343 return B_NO_INIT; 344 345 return fPartitionHandle->SetContentParameters(parameters); 346} 347 348 349// SetParameters 350status_t 351BPartition::Delegate::SetParameters(Delegate* child, const char* parameters) 352{ 353 if (!fPartitionHandle || !child) 354 return B_NO_INIT; 355 356 return fPartitionHandle->SetParameters(&child->fMutablePartition, 357 parameters); 358} 359 360 361// GetNextSupportedChildType 362status_t 363BPartition::Delegate::GetNextSupportedChildType(Delegate* child, 364 int32* cookie, BString* type) const 365{ 366 TRACE("%p->BPartition::Delegate::GetNextSupportedChildType(child: %p, " 367 "cookie: %ld)\n", this, child, *cookie); 368 369 if (!fPartitionHandle) { 370 TRACE(" no partition handle!\n"); 371 return B_NO_INIT; 372 } 373 374 return fPartitionHandle->GetNextSupportedType( 375 child ? &child->fMutablePartition : NULL, cookie, type); 376} 377 378 379// IsSubSystem 380bool 381BPartition::Delegate::IsSubSystem(Delegate* child, 382 const char* diskSystem) const 383{ 384 // get the disk system add-on 385 DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default(); 386 BDiskSystemAddOn* addOn = manager->GetAddOn(diskSystem); 387 if (!addOn) 388 return false; 389 390 bool result = addOn->IsSubSystemFor(&child->fMutablePartition); 391 392 // put the add-on 393 manager->PutAddOn(addOn); 394 395 return result; 396} 397 398 399// CanInitialize 400bool 401BPartition::Delegate::CanInitialize(const char* diskSystem) const 402{ 403 // get the disk system add-on 404 DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default(); 405 BDiskSystemAddOn* addOn = manager->GetAddOn(diskSystem); 406 if (!addOn) 407 return false; 408 409 bool result = addOn->CanInitialize(&fMutablePartition); 410 411 // put the add-on 412 manager->PutAddOn(addOn); 413 414 return result; 415} 416 417 418// ValidateInitialize 419status_t 420BPartition::Delegate::ValidateInitialize(const char* diskSystem, 421 BString* name, const char* parameters) 422{ 423 // get the disk system add-on 424 DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default(); 425 BDiskSystemAddOn* addOn = manager->GetAddOn(diskSystem); 426 if (!addOn) 427 return B_ENTRY_NOT_FOUND; 428 429 status_t result = addOn->ValidateInitialize(&fMutablePartition, 430 name, parameters); 431 432 // put the add-on 433 manager->PutAddOn(addOn); 434 435 return result; 436} 437 438 439// Initialize 440status_t 441BPartition::Delegate::Initialize(const char* diskSystem, 442 const char* name, const char* parameters) 443{ 444 // get the disk system add-on 445 DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default(); 446 BDiskSystemAddOn* addOn = manager->GetAddOn(diskSystem); 447 if (!addOn) 448 return B_ENTRY_NOT_FOUND; 449 450 BPartitionHandle* handle; 451 status_t result = addOn->Initialize(&fMutablePartition, name, parameters, 452 &handle); 453 454 // keep the add-on or put it on error 455 if (result == B_OK) { 456 // TODO: This won't suffice. If this partition had children, we have 457 // to delete them before the new disk system plays with it. 458 _FreeHandle(); 459 fDiskSystem = addOn; 460 fPartitionHandle = handle; 461 } else { 462 manager->PutAddOn(addOn); 463 } 464 465 return result; 466} 467 468 469// Uninitialize 470status_t 471BPartition::Delegate::Uninitialize() 472{ 473 if (fPartitionHandle) { 474 _FreeHandle(); 475 476 fMutablePartition.UninitializeContents(); 477 } 478 479 return B_OK; 480} 481 482 483// GetPartitioningInfo 484status_t 485BPartition::Delegate::GetPartitioningInfo(BPartitioningInfo* info) 486{ 487 if (!fPartitionHandle) 488 return B_NO_INIT; 489 490 return fPartitionHandle->GetPartitioningInfo(info); 491} 492 493 494// GetParameterEditor 495status_t 496BPartition::Delegate::GetParameterEditor(B_PARAMETER_EDITOR_TYPE type, 497 BPartitionParameterEditor** editor) const 498{ 499 if (!fPartitionHandle) 500 return B_NO_INIT; 501 502 return fPartitionHandle->GetParameterEditor(type, editor); 503} 504 505 506// ValidateCreateChild 507status_t 508BPartition::Delegate::ValidateCreateChild(off_t* start, off_t* size, 509 const char* type, BString* name, const char* parameters) const 510{ 511 if (!fPartitionHandle) 512 return B_NO_INIT; 513 514 return fPartitionHandle->ValidateCreateChild(start, size, type, name, 515 parameters); 516} 517 518 519// CreateChild 520status_t 521BPartition::Delegate::CreateChild(off_t start, off_t size, const char* type, 522 const char* name, const char* parameters, BPartition** child) 523{ 524 if (!fPartitionHandle) 525 return B_NO_INIT; 526 527 BMutablePartition* mutableChild; 528 status_t error = fPartitionHandle->CreateChild(start, size, type, name, 529 parameters, &mutableChild); 530 if (error != B_OK) 531 return error; 532 533 if (child) 534 *child = mutableChild->GetDelegate()->Partition(); 535 536 return B_OK; 537} 538 539 540// DeleteChild 541status_t 542BPartition::Delegate::DeleteChild(Delegate* child) 543{ 544 if (!fPartitionHandle || !child) 545 return B_NO_INIT; 546 547 return fPartitionHandle->DeleteChild(&child->fMutablePartition); 548} 549 550 551// _FreeHandle 552void 553BPartition::Delegate::_FreeHandle() 554{ 555 if (fPartitionHandle) { 556 delete fPartitionHandle; 557 fPartitionHandle = NULL; 558 559 DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default(); 560 manager->PutAddOn(fDiskSystem); 561 fDiskSystem = NULL; 562 } 563} 564