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