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 23 BPartition::Delegate::Delegate(BPartition* partition) 24 : 25 fPartition(partition), 26 fMutablePartition(this), 27 fDiskSystem(NULL), 28 fPartitionHandle(NULL) 29 { 30 } 31 32 33 // destructor 34 BPartition::Delegate::~Delegate() 35 { 36 } 37 38 39 // MutablePartition 40 BMutablePartition* 41 BPartition::Delegate::MutablePartition() 42 { 43 return &fMutablePartition; 44 } 45 46 47 // MutablePartition 48 const BMutablePartition* 49 BPartition::Delegate::MutablePartition() const 50 { 51 return &fMutablePartition; 52 } 53 54 55 // InitHierarchy 56 status_t 57 BPartition::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 66 status_t 67 BPartition::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 106 const user_partition_data* 107 BPartition::Delegate::PartitionData() const 108 { 109 return fMutablePartition.PartitionData(); 110 } 111 112 113 // ChildAt 114 BPartition::Delegate* 115 BPartition::Delegate::ChildAt(int32 index) const 116 { 117 BMutablePartition* child = fMutablePartition.ChildAt(index); 118 return child ? child->GetDelegate() : NULL; 119 } 120 121 122 // CountChildren 123 int32 124 BPartition::Delegate::CountChildren() const 125 { 126 return fMutablePartition.CountChildren(); 127 } 128 129 130 // IsModified 131 bool 132 BPartition::Delegate::IsModified() const 133 { 134 return fMutablePartition.ChangeFlags() != 0; 135 } 136 137 138 // SupportedOperations 139 uint32 140 BPartition::Delegate::SupportedOperations(uint32 mask) 141 { 142 if (!fPartitionHandle) 143 return 0; 144 145 return fPartitionHandle->SupportedOperations(mask); 146 } 147 148 149 // SupportedChildOperations 150 uint32 151 BPartition::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 163 status_t 164 BPartition::Delegate::Defragment() 165 { 166 // TODO: Implement! 167 return B_BAD_VALUE; 168 } 169 170 171 // Repair 172 status_t 173 BPartition::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 183 status_t 184 BPartition::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 194 status_t 195 BPartition::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 206 status_t 207 BPartition::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 217 status_t 218 BPartition::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 228 status_t 229 BPartition::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 239 status_t 240 BPartition::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 251 status_t 252 BPartition::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 262 status_t 263 BPartition::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 273 status_t 274 BPartition::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 284 status_t 285 BPartition::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 295 status_t 296 BPartition::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 306 status_t 307 BPartition::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 317 status_t 318 BPartition::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 328 status_t 329 BPartition::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 339 status_t 340 BPartition::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 350 status_t 351 BPartition::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 362 status_t 363 BPartition::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 380 bool 381 BPartition::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 400 bool 401 BPartition::Delegate::CanInitialize(const char* diskSystem) const 402 { 403 // HACK TO HELP BLANK PARTITION'S BECOME INITIALIZED. 404 if (diskSystem == NULL) 405 return true; 406 if (strlen(diskSystem) < 1) 407 return true; 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->CanInitialize(&fMutablePartition); 416 417 // put the add-on 418 manager->PutAddOn(addOn); 419 420 return result; 421 } 422 423 424 // ValidateInitialize 425 status_t 426 BPartition::Delegate::ValidateInitialize(const char* diskSystem, 427 BString* name, const char* parameters) 428 { 429 // get the disk system add-on 430 DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default(); 431 BDiskSystemAddOn* addOn = manager->GetAddOn(diskSystem); 432 if (!addOn) 433 return B_ENTRY_NOT_FOUND; 434 435 status_t result = addOn->ValidateInitialize(&fMutablePartition, 436 name, parameters); 437 438 // put the add-on 439 manager->PutAddOn(addOn); 440 441 return result; 442 } 443 444 445 // Initialize 446 status_t 447 BPartition::Delegate::Initialize(const char* diskSystem, 448 const char* name, const char* parameters) 449 { 450 // get the disk system add-on 451 DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default(); 452 BDiskSystemAddOn* addOn = manager->GetAddOn(diskSystem); 453 if (!addOn) 454 return B_ENTRY_NOT_FOUND; 455 456 BPartitionHandle* handle; 457 status_t result = addOn->Initialize(&fMutablePartition, name, parameters, 458 &handle); 459 460 // keep the add-on or put it on error 461 if (result == B_OK) { 462 // TODO: This won't suffice. If this partition had children, we have 463 // to delete them before the new disk system plays with it. 464 _FreeHandle(); 465 fDiskSystem = addOn; 466 fPartitionHandle = handle; 467 } else { 468 manager->PutAddOn(addOn); 469 } 470 471 return result; 472 } 473 474 475 // Uninitialize 476 status_t 477 BPartition::Delegate::Uninitialize() 478 { 479 if (fPartitionHandle) { 480 _FreeHandle(); 481 482 fMutablePartition.UninitializeContents(); 483 } 484 485 return B_OK; 486 } 487 488 489 // GetPartitioningInfo 490 status_t 491 BPartition::Delegate::GetPartitioningInfo(BPartitioningInfo* info) 492 { 493 if (!fPartitionHandle) 494 return B_NO_INIT; 495 496 return fPartitionHandle->GetPartitioningInfo(info); 497 } 498 499 500 // GetParameterEditor 501 status_t 502 BPartition::Delegate::GetParameterEditor(B_PARAMETER_EDITOR_TYPE type, 503 BPartitionParameterEditor** editor) const 504 { 505 if (!fPartitionHandle) 506 return B_NO_INIT; 507 508 return fPartitionHandle->GetParameterEditor(type, editor); 509 } 510 511 512 // ValidateCreateChild 513 status_t 514 BPartition::Delegate::ValidateCreateChild(off_t* start, off_t* size, 515 const char* type, BString* name, const char* parameters) const 516 { 517 if (!fPartitionHandle) 518 return B_NO_INIT; 519 520 return fPartitionHandle->ValidateCreateChild(start, size, type, name, 521 parameters); 522 } 523 524 525 // CreateChild 526 status_t 527 BPartition::Delegate::CreateChild(off_t start, off_t size, const char* type, 528 const char* name, const char* parameters, BPartition** child) 529 { 530 if (!fPartitionHandle) 531 return B_NO_INIT; 532 533 BMutablePartition* mutableChild; 534 status_t error = fPartitionHandle->CreateChild(start, size, type, name, 535 parameters, &mutableChild); 536 if (error != B_OK) 537 return error; 538 539 if (child) 540 *child = mutableChild->GetDelegate()->Partition(); 541 542 return B_OK; 543 } 544 545 546 // DeleteChild 547 status_t 548 BPartition::Delegate::DeleteChild(Delegate* child) 549 { 550 if (!fPartitionHandle || !child) 551 return B_NO_INIT; 552 553 return fPartitionHandle->DeleteChild(&child->fMutablePartition); 554 } 555 556 557 // _FreeHandle 558 void 559 BPartition::Delegate::_FreeHandle() 560 { 561 if (fPartitionHandle) { 562 delete fPartitionHandle; 563 fPartitionHandle = NULL; 564 565 DiskSystemAddOnManager* manager = DiskSystemAddOnManager::Default(); 566 manager->PutAddOn(fDiskSystem); 567 fDiskSystem = NULL; 568 } 569 } 570