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 // 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 419 status_t 420 BPartition::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 440 status_t 441 BPartition::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 470 status_t 471 BPartition::Delegate::Uninitialize() 472 { 473 if (fPartitionHandle) { 474 _FreeHandle(); 475 476 fMutablePartition.UninitializeContents(); 477 } 478 479 return B_OK; 480 } 481 482 483 // GetPartitioningInfo 484 status_t 485 BPartition::Delegate::GetPartitioningInfo(BPartitioningInfo* info) 486 { 487 if (!fPartitionHandle) 488 return B_NO_INIT; 489 490 return fPartitionHandle->GetPartitioningInfo(info); 491 } 492 493 494 // GetParameterEditor 495 status_t 496 BPartition::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 507 status_t 508 BPartition::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 520 status_t 521 BPartition::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 541 status_t 542 BPartition::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 552 void 553 BPartition::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