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