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