1 /* 2 * Copyright 2002-2009 Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT license. 4 * 5 * Authors: 6 * Erik Jaesler <ejakowatz@users.sourceforge.net> 7 * Ithamar R. Adema <ithamar@unet.nl> 8 * Stephan Aßmus <superstippi@gmx.de> 9 */ 10 11 #include "MainWindow.h" 12 #include "DiskView.h" 13 #include "InitParamsPanel.h" 14 #include "PartitionList.h" 15 #include "Support.h" 16 #include "tracker_private.h" 17 18 #include <stdio.h> 19 #include <string.h> 20 21 #include <Alert.h> 22 #include <Application.h> 23 #include <ColumnListView.h> 24 #include <ColumnTypes.h> 25 #include <DiskDevice.h> 26 #include <DiskDeviceVisitor.h> 27 #include <DiskSystem.h> 28 #include <MenuItem.h> 29 #include <MenuBar.h> 30 #include <Menu.h> 31 #include <Path.h> 32 #include <Partition.h> 33 #include <PartitioningInfo.h> 34 #include <Roster.h> 35 #include <Screen.h> 36 #include <Volume.h> 37 #include <VolumeRoster.h> 38 39 40 class ListPopulatorVisitor : public BDiskDeviceVisitor { 41 public: 42 ListPopulatorVisitor(PartitionListView* list, int32& diskCount, 43 SpaceIDMap& spaceIDMap) 44 : 45 fPartitionList(list), 46 fDiskCount(diskCount), 47 fSpaceIDMap(spaceIDMap) 48 { 49 fDiskCount = 0; 50 fSpaceIDMap.Clear(); 51 // start with an empty list 52 int32 rows = fPartitionList->CountRows(); 53 for (int32 i = rows - 1; i >= 0; i--) { 54 BRow* row = fPartitionList->RowAt(i); 55 fPartitionList->RemoveRow(row); 56 delete row; 57 } 58 } 59 60 virtual bool Visit(BDiskDevice* device) 61 { 62 fDiskCount++; 63 // if we don't prepare the device for modifications, 64 // we cannot get information about available empty 65 // regions on the device or child partitions 66 device->PrepareModifications(); 67 _AddPartition(device); 68 return false; // Don't stop yet! 69 } 70 71 virtual bool Visit(BPartition* partition, int32 level) 72 { 73 _AddPartition(partition); 74 return false; // Don't stop yet! 75 } 76 77 private: 78 void _AddPartition(BPartition* partition) const 79 { 80 // add the partition itself 81 fPartitionList->AddPartition(partition); 82 83 // add any available space on it 84 BPartitioningInfo info; 85 status_t ret = partition->GetPartitioningInfo(&info); 86 if (ret >= B_OK) { 87 partition_id parentID = partition->ID(); 88 off_t offset; 89 off_t size; 90 for (int32 i = 0; 91 info.GetPartitionableSpaceAt(i, &offset, &size) >= B_OK; 92 i++) { 93 // TODO: remove again once Disk Device API is fixed 94 if (!is_valid_partitionable_space(size)) 95 continue; 96 // 97 partition_id id = fSpaceIDMap.SpaceIDFor(parentID, offset); 98 fPartitionList->AddSpace(parentID, id, offset, size); 99 } 100 } 101 } 102 103 PartitionListView* fPartitionList; 104 int32& fDiskCount; 105 SpaceIDMap& fSpaceIDMap; 106 BDiskDevice* fLastPreparedDevice; 107 }; 108 109 110 class MountAllVisitor : public BDiskDeviceVisitor { 111 public: 112 MountAllVisitor() 113 { 114 } 115 116 virtual bool Visit(BDiskDevice* device) 117 { 118 return false; // Don't stop yet! 119 } 120 121 virtual bool Visit(BPartition* partition, int32 level) 122 { 123 partition->Mount(); 124 return false; // Don't stop yet! 125 } 126 127 private: 128 PartitionListView* fPartitionList; 129 }; 130 131 132 enum { 133 MSG_MOUNT_ALL = 'mnta', 134 MSG_MOUNT = 'mnts', 135 MSG_UNMOUNT = 'unmt', 136 MSG_FORMAT = 'frmt', 137 MSG_CREATE = 'crtp', 138 MSG_INITIALIZE = 'init', 139 MSG_DELETE = 'delt', 140 MSG_EJECT = 'ejct', 141 MSG_SURFACE_TEST = 'sfct', 142 MSG_RESCAN = 'rscn', 143 144 MSG_PARTITION_ROW_SELECTED = 'prsl', 145 }; 146 147 148 // #pragma mark - 149 150 151 MainWindow::MainWindow(BRect frame) 152 : BWindow(frame, "DriveSetup", B_DOCUMENT_WINDOW, 153 B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE), 154 fCurrentDisk(NULL), 155 fCurrentPartitionID(-1), 156 fSpaceIDMap() 157 { 158 BMenuBar* menuBar = new BMenuBar(Bounds(), "root menu"); 159 160 // create all the menu items 161 fFormatMI = new BMenuItem("Format (not implemented)", 162 new BMessage(MSG_FORMAT)); 163 fEjectMI = new BMenuItem("Eject", new BMessage(MSG_EJECT), 'E'); 164 fSurfaceTestMI = new BMenuItem("Surface Test (not implemented)", 165 new BMessage(MSG_SURFACE_TEST)); 166 fRescanMI = new BMenuItem("Rescan", new BMessage(MSG_RESCAN)); 167 168 fDeleteMI = new BMenuItem("Delete (not implemented)", 169 new BMessage(MSG_DELETE)); 170 fDeleteMI->SetEnabled(false); 171 172 fMountMI = new BMenuItem("Mount", new BMessage(MSG_MOUNT), 'M'); 173 fUnmountMI = new BMenuItem("Unmount", new BMessage(MSG_UNMOUNT), 'U'); 174 fMountAllMI = new BMenuItem("Mount All", 175 new BMessage(MSG_MOUNT_ALL), 'M', B_SHIFT_KEY); 176 177 // Disk menu 178 fDiskMenu = new BMenu("Disk"); 179 fDiskMenu->AddItem(fFormatMI); 180 fDiskMenu->AddItem(fEjectMI); 181 fDiskMenu->AddItem(fSurfaceTestMI); 182 183 fDiskMenu->AddSeparatorItem(); 184 185 fDiskMenu->AddItem(fRescanMI); 186 menuBar->AddItem(fDiskMenu); 187 188 // Parition menu 189 fPartitionMenu = new BMenu("Partition"); 190 fCreateMenu = new BMenu("Create (not implemented)"); 191 fPartitionMenu->AddItem(fCreateMenu); 192 193 fInitMenu = new BMenu("Initialize"); 194 fPartitionMenu->AddItem(fInitMenu); 195 196 fPartitionMenu->AddItem(fDeleteMI); 197 198 fPartitionMenu->AddSeparatorItem(); 199 200 fPartitionMenu->AddItem(fMountMI); 201 fPartitionMenu->AddItem(fUnmountMI); 202 203 fPartitionMenu->AddSeparatorItem(); 204 205 fPartitionMenu->AddItem(fMountAllMI); 206 menuBar->AddItem(fPartitionMenu); 207 208 AddChild(menuBar); 209 210 // add DiskView 211 BRect r(Bounds()); 212 r.top = menuBar->Frame().bottom + 1; 213 r.bottom = floorf(r.top + r.Height() * 0.33); 214 fDiskView = new DiskView(r, B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP, 215 fSpaceIDMap); 216 AddChild(fDiskView); 217 218 // add PartitionListView 219 r.top = r.bottom + 2; 220 r.bottom = Bounds().bottom; 221 r.InsetBy(-1, -1); 222 fListView = new PartitionListView(r, B_FOLLOW_ALL); 223 AddChild(fListView); 224 225 // configure PartitionListView 226 fListView->SetSelectionMessage(new BMessage(MSG_PARTITION_ROW_SELECTED)); 227 fListView->SetTarget(this); 228 229 BDiskDeviceRoster().StartWatching(this); 230 231 // populate the Initialiaze menu with the available file systems 232 _ScanFileSystems(); 233 234 // visit all disks in the system and show their contents 235 _ScanDrives(); 236 237 if (!be_roster->IsRunning(kDeskbarSignature)) 238 SetFlags(Flags() | B_NOT_MINIMIZABLE); 239 } 240 241 242 MainWindow::~MainWindow() 243 { 244 BDiskDeviceRoster().StopWatching(this); 245 delete fCurrentDisk; 246 } 247 248 249 void 250 MainWindow::MessageReceived(BMessage* message) 251 { 252 switch (message->what) { 253 case MSG_MOUNT_ALL: 254 _MountAll(); 255 break; 256 case MSG_MOUNT: 257 _Mount(fCurrentDisk, fCurrentPartitionID); 258 break; 259 case MSG_UNMOUNT: 260 _Unmount(fCurrentDisk, fCurrentPartitionID); 261 break; 262 263 case MSG_FORMAT: 264 printf("MSG_FORMAT\n"); 265 break; 266 267 case MSG_CREATE: 268 printf("MSG_CREATE\n"); 269 break; 270 271 case MSG_INITIALIZE: { 272 BString diskSystemName; 273 if (message->FindString("format", &diskSystemName) != B_OK) 274 break; 275 _Initialize(fCurrentDisk, fCurrentPartitionID, diskSystemName); 276 break; 277 } 278 279 case MSG_DELETE: 280 printf("MSG_DELETE\n"); 281 break; 282 283 case MSG_EJECT: 284 // TODO: completely untested, especially interesting 285 // if partition list behaves when partitions disappear 286 if (fCurrentDisk) { 287 // TODO: only if no partitions are mounted anymore? 288 fCurrentDisk->Eject(true); 289 _ScanDrives(); 290 } 291 break; 292 case MSG_SURFACE_TEST: 293 printf("MSG_SURFACE_TEST\n"); 294 break; 295 296 // TODO: this could probably be done better! 297 case B_DEVICE_UPDATE: 298 case MSG_RESCAN: 299 _ScanDrives(); 300 break; 301 302 case MSG_PARTITION_ROW_SELECTED: 303 // selection of partitions via list view 304 _AdaptToSelectedPartition(); 305 break; 306 case MSG_SELECTED_PARTITION_ID: { 307 // selection of partitions via disk view 308 partition_id id; 309 if (message->FindInt32("partition_id", &id) == B_OK) { 310 if (BRow* row = fListView->FindRow(id)) { 311 fListView->DeselectAll(); 312 fListView->AddToSelection(row); 313 _AdaptToSelectedPartition(); 314 } 315 } 316 break; 317 } 318 319 default: 320 BWindow::MessageReceived(message); 321 break; 322 } 323 } 324 325 326 bool 327 MainWindow::QuitRequested() 328 { 329 // TODO: ask about any unsaved changes 330 be_app->PostMessage(B_QUIT_REQUESTED); 331 Hide(); 332 return false; 333 } 334 335 336 // #pragma mark - 337 338 339 status_t 340 MainWindow::StoreSettings(BMessage* archive) const 341 { 342 if (archive->ReplaceRect("window frame", Frame()) < B_OK) 343 archive->AddRect("window frame", Frame()); 344 345 BMessage columnSettings; 346 fListView->SaveState(&columnSettings); 347 if (archive->ReplaceMessage("column settings", &columnSettings) < B_OK) 348 archive->AddMessage("column settings", &columnSettings); 349 350 return B_OK; 351 } 352 353 354 status_t 355 MainWindow::RestoreSettings(BMessage* archive) 356 { 357 BRect frame; 358 if (archive->FindRect("window frame", &frame) == B_OK) { 359 BScreen screen(this); 360 if (frame.Intersects(screen.Frame())) { 361 MoveTo(frame.LeftTop()); 362 ResizeTo(frame.Width(), frame.Height()); 363 } 364 } 365 366 BMessage columnSettings; 367 if (archive->FindMessage("column settings", &columnSettings) == B_OK) 368 fListView->LoadState(&columnSettings); 369 370 return B_OK; 371 } 372 373 374 // #pragma mark - 375 376 377 void 378 MainWindow::_ScanDrives() 379 { 380 fSpaceIDMap.Clear(); 381 int32 diskCount = 0; 382 ListPopulatorVisitor driveVisitor(fListView, diskCount, fSpaceIDMap); 383 fDDRoster.VisitEachPartition(&driveVisitor); 384 fDiskView->SetDiskCount(diskCount); 385 386 // restore selection 387 PartitionListRow* previousSelection 388 = fListView->FindRow(fCurrentPartitionID); 389 if (previousSelection) { 390 fListView->AddToSelection(previousSelection); 391 _EnabledDisableMenuItems(fCurrentDisk, fCurrentPartitionID, 392 previousSelection->ParentID()); 393 fDiskView->ForceUpdate(); 394 } else { 395 _EnabledDisableMenuItems(NULL, -1, -1); 396 } 397 } 398 399 400 void 401 MainWindow::_ScanFileSystems() 402 { 403 while (BMenuItem* item = fInitMenu->RemoveItem(0L)) 404 delete item; 405 406 BDiskSystem diskSystem; 407 fDDRoster.RewindDiskSystems(); 408 while (fDDRoster.GetNextDiskSystem(&diskSystem) == B_OK) { 409 if (diskSystem.IsFileSystem() && diskSystem.SupportsInitializing()) { 410 BMessage* message = new BMessage(MSG_INITIALIZE); 411 message->AddString("format", diskSystem.PrettyName()); 412 BString label = diskSystem.PrettyName(); 413 label << B_UTF8_ELLIPSIS; 414 fInitMenu->AddItem(new BMenuItem(label.String(), message)); 415 } 416 } 417 } 418 419 420 // #pragma mark - 421 422 423 void 424 MainWindow::_AdaptToSelectedPartition() 425 { 426 partition_id diskID = -1; 427 partition_id partitionID = -1; 428 partition_id parentID = -1; 429 430 BRow* _selectedRow = fListView->CurrentSelection(); 431 if (_selectedRow) { 432 // go up to top level row 433 BRow* _topLevelRow = _selectedRow; 434 BRow* parent = NULL; 435 while (fListView->FindParent(_topLevelRow, &parent, NULL)) 436 _topLevelRow = parent; 437 438 PartitionListRow* topLevelRow 439 = dynamic_cast<PartitionListRow*>(_topLevelRow); 440 PartitionListRow* selectedRow 441 = dynamic_cast<PartitionListRow*>(_selectedRow); 442 443 if (topLevelRow) 444 diskID = topLevelRow->ID(); 445 if (selectedRow) { 446 partitionID = selectedRow->ID(); 447 parentID = selectedRow->ParentID(); 448 } 449 } 450 451 _SetToDiskAndPartition(diskID, partitionID, parentID); 452 } 453 454 455 void 456 MainWindow::_SetToDiskAndPartition(partition_id disk, partition_id partition, 457 partition_id parent) 458 { 459 BDiskDevice* oldDisk = NULL; 460 if (!fCurrentDisk || fCurrentDisk->ID() != disk) { 461 oldDisk = fCurrentDisk; 462 fCurrentDisk = NULL; 463 if (disk >= 0) { 464 BDiskDevice* newDisk = new BDiskDevice(); 465 status_t ret = newDisk->SetTo(disk); 466 if (ret < B_OK) { 467 printf("error switching disks: %s\n", strerror(ret)); 468 delete newDisk; 469 } else 470 fCurrentDisk = newDisk; 471 } 472 } 473 474 fCurrentPartitionID = partition; 475 476 fDiskView->SetDisk(fCurrentDisk, fCurrentPartitionID); 477 _EnabledDisableMenuItems(fCurrentDisk, fCurrentPartitionID, parent); 478 479 delete oldDisk; 480 } 481 482 483 void 484 MainWindow::_EnabledDisableMenuItems(BDiskDevice* disk, 485 partition_id selectedPartition, partition_id parentID) 486 { 487 // clean out Create menu 488 while (BMenuItem* item = fCreateMenu->RemoveItem(0L)) 489 delete item; 490 491 if (!disk) { 492 fFormatMI->SetEnabled(false); 493 fEjectMI->SetEnabled(false); 494 fSurfaceTestMI->SetEnabled(false); 495 496 fPartitionMenu->SetEnabled(false); 497 } else { 498 // fFormatMI->SetEnabled(true); 499 fFormatMI->SetEnabled(false); 500 fEjectMI->SetEnabled(disk->IsRemovableMedia()); 501 // fSurfaceTestMI->SetEnabled(true); 502 fSurfaceTestMI->SetEnabled(false); 503 504 // Create menu and items 505 fPartitionMenu->SetEnabled(true); 506 507 BPartition* parentPartition = NULL; 508 if (selectedPartition <= -2) 509 parentPartition = disk->FindDescendant(parentID); 510 511 if (parentPartition) { 512 bool prepared = disk->PrepareModifications() == B_OK; 513 fCreateMenu->SetEnabled(true); 514 BString supportedChildType; 515 int32 cookie = 0; 516 status_t ret; 517 while ((ret = parentPartition->GetNextSupportedChildType(&cookie, 518 &supportedChildType)) == B_OK) { 519 BMessage* message = new BMessage(MSG_CREATE); 520 message->AddInt32("parent id", parentID); 521 message->AddInt32("space id", selectedPartition); 522 message->AddString("type", supportedChildType); 523 BMenuItem* item = new BMenuItem(supportedChildType.String(), 524 message); 525 fCreateMenu->AddItem(item); 526 } 527 if (fCreateMenu->CountItems() == 0) 528 fprintf(stderr, "Failed to get supported child types: %s\n", 529 strerror(ret)); 530 if (prepared) 531 disk->CancelModifications(); 532 } else { 533 fCreateMenu->SetEnabled(false); 534 } 535 536 // Mount items 537 BPartition* partition = disk->FindDescendant(selectedPartition); 538 if (partition) { 539 fInitMenu->SetEnabled(!partition->IsMounted()); 540 // fDeleteMI->SetEnabled(!partition->IsMounted()); 541 fDeleteMI->SetEnabled(false); 542 fMountMI->SetEnabled(!partition->IsMounted()); 543 544 bool unMountable = false; 545 if (partition->IsMounted()) { 546 // see if this partition is the boot volume 547 BVolume volume; 548 BVolume bootVolume; 549 if (BVolumeRoster().GetBootVolume(&bootVolume) == B_OK 550 && partition->GetVolume(&volume) == B_OK) { 551 unMountable = volume != bootVolume; 552 } else 553 unMountable = true; 554 } 555 fUnmountMI->SetEnabled(unMountable); 556 } else { 557 fInitMenu->SetEnabled(false); 558 fDeleteMI->SetEnabled(false); 559 fMountMI->SetEnabled(false); 560 fUnmountMI->SetEnabled(false); 561 } 562 fMountAllMI->SetEnabled(true); 563 } 564 } 565 566 567 void 568 MainWindow::_DisplayPartitionError(BString _message, 569 const BPartition* partition, status_t error) const 570 { 571 char message[1024]; 572 573 if (partition && _message.FindFirst("%s") >= 0) { 574 BString name; 575 name << " \"" << partition->ContentName() << "\""; 576 sprintf(message, _message.String(), name.String()); 577 } else { 578 _message.ReplaceAll("%s", ""); 579 sprintf(message, _message.String()); 580 } 581 582 if (error < B_OK) { 583 BString helper = message; 584 sprintf(message, "%s\n\nError: %s", helper.String(), strerror(error)); 585 } 586 587 BAlert* alert = new BAlert("error", message, "Ok", NULL, NULL, 588 B_WIDTH_FROM_WIDEST, error < B_OK ? B_STOP_ALERT : B_INFO_ALERT); 589 alert->Go(NULL); 590 } 591 592 593 // #pragma mark - 594 595 596 void 597 MainWindow::_Mount(BDiskDevice* disk, partition_id selectedPartition) 598 { 599 if (!disk || selectedPartition < 0) { 600 _DisplayPartitionError("You need to select a partition " 601 "entry from the list."); 602 return; 603 } 604 605 BPartition* partition = disk->FindDescendant(selectedPartition); 606 if (!partition) { 607 _DisplayPartitionError("Unable to find the selected partition by id."); 608 return; 609 } 610 611 if (!partition->IsMounted()) { 612 status_t ret = partition->Mount(); 613 if (ret < B_OK) { 614 _DisplayPartitionError("Could not mount partition %s.", 615 partition, ret); 616 } else { 617 // successful mount, adapt to the changes 618 _ScanDrives(); 619 } 620 } else { 621 _DisplayPartitionError("The partition %s is already mounted.", 622 partition); 623 } 624 } 625 626 627 void 628 MainWindow::_Unmount(BDiskDevice* disk, partition_id selectedPartition) 629 { 630 if (!disk || selectedPartition < 0) { 631 _DisplayPartitionError("You need to select a partition " 632 "entry from the list."); 633 return; 634 } 635 636 BPartition* partition = disk->FindDescendant(selectedPartition); 637 if (!partition) { 638 _DisplayPartitionError("Unable to find the selected partition by id."); 639 return; 640 } 641 642 if (partition->IsMounted()) { 643 BPath path; 644 partition->GetMountPoint(&path); 645 status_t ret = partition->Unmount(); 646 if (ret < B_OK) { 647 _DisplayPartitionError("Could not unmount partition %s.", 648 partition, ret); 649 } else { 650 if (dev_for_path(path.Path()) == dev_for_path("/")) 651 rmdir(path.Path()); 652 // successful unmount, adapt to the changes 653 _ScanDrives(); 654 } 655 } else { 656 _DisplayPartitionError("The partition %s is already unmounted.", 657 partition); 658 } 659 } 660 661 662 void 663 MainWindow::_MountAll() 664 { 665 MountAllVisitor visitor; 666 fDDRoster.VisitEachPartition(&visitor); 667 } 668 669 670 // #pragma mark - 671 672 673 class ModificationPreparer { 674 public: 675 ModificationPreparer(BDiskDevice* disk) 676 : 677 fDisk(disk), 678 fModificationStatus(fDisk->PrepareModifications()) 679 { 680 } 681 ~ModificationPreparer() 682 { 683 if (fModificationStatus == B_OK) 684 fDisk->CancelModifications(); 685 } 686 status_t ModificationStatus() const 687 { 688 return fModificationStatus; 689 } 690 status_t CommitModifications() 691 { 692 status_t ret = fDisk->CommitModifications(); 693 if (ret == B_OK) 694 fModificationStatus = B_ERROR; 695 return ret; 696 } 697 698 private: 699 BDiskDevice* fDisk; 700 status_t fModificationStatus; 701 }; 702 703 704 void 705 MainWindow::_Initialize(BDiskDevice* disk, partition_id selectedPartition, 706 const BString& diskSystemName) 707 { 708 if (!disk || selectedPartition < 0) { 709 _DisplayPartitionError("You need to select a partition " 710 "entry from the list."); 711 return; 712 } 713 714 if (disk->IsReadOnly()) { 715 _DisplayPartitionError("The selected disk is read-only."); 716 return; 717 } 718 719 BPartition* partition = disk->FindDescendant(selectedPartition); 720 if (!partition) { 721 _DisplayPartitionError("Unable to find the selected partition by id."); 722 return; 723 } 724 725 if (partition->IsMounted()) { 726 _DisplayPartitionError("The partition %s is currently mounted."); 727 // TODO: option to unmount and continue on success to unmount 728 return; 729 } 730 731 BString message("Are you sure you want to initialize the partition "); 732 message << "\"" << partition->ContentName(); 733 message << "\"? After entering the initialization parameters, "; 734 message << "you can abort this operation right before writing "; 735 message << "changes back to the disk."; 736 BAlert* alert = new BAlert("first notice", message.String(), 737 "Continue", "Cancel", NULL, B_WIDTH_FROM_WIDEST, B_WARNING_ALERT); 738 int32 choice = alert->Go(); 739 740 if (choice == 1) 741 return; 742 743 BDiskSystem diskSystem; 744 fDDRoster.RewindDiskSystems(); 745 bool found = false; 746 while (fDDRoster.GetNextDiskSystem(&diskSystem) == B_OK) { 747 if (diskSystem.IsFileSystem() && diskSystem.SupportsInitializing()) { 748 if (diskSystemName == diskSystem.PrettyName()) { 749 found = true; 750 break; 751 } 752 } 753 } 754 755 if (!found) { 756 BString message("Disk system \""); 757 message << diskSystemName << "\" not found!"; 758 _DisplayPartitionError(message); 759 return; 760 } 761 762 763 // allow BFS only, since our parameter string 764 // construction only handles BFS at the moment 765 if (diskSystemName != "Be File System") { 766 _DisplayPartitionError("Don't know how to construct parameters " 767 "for this file system."); 768 return; 769 } 770 771 ModificationPreparer modificationPreparer(disk); 772 status_t ret = modificationPreparer.ModificationStatus(); 773 if (ret != B_OK) { 774 _DisplayPartitionError("There was an error preparing the " 775 "disk for modifications.", NULL, ret); 776 return; 777 } 778 779 // TODO: use partition initialization editor 780 // (partition->GetInitializationParameterEditor()) 781 782 BString name = partition->ContentName(); 783 if (name.Length() == 0) 784 name = "Haiku"; 785 BString parameters; 786 InitParamsPanel* panel = new InitParamsPanel(this); 787 if (panel->Go(name, parameters) == GO_CANCELED) 788 return; 789 790 bool supportsName = diskSystem.SupportsContentName(); 791 BString validatedName(name); 792 ret = partition->ValidateInitialize(diskSystem.PrettyName(), 793 supportsName ? &validatedName : NULL, parameters.String()); 794 if (ret != B_OK) { 795 _DisplayPartitionError("Validation of the given initialization " 796 "parameters failed.", partition, ret); 797 return; 798 } 799 800 BString previousName = partition->ContentName(); 801 802 ret = partition->Initialize(diskSystem.PrettyName(), 803 supportsName ? name.String() : NULL, parameters.String()); 804 if (ret != B_OK) { 805 _DisplayPartitionError("Initialization of the partition %s " 806 "failed. (Nothing has been written to disk.)", partition, ret); 807 return; 808 } 809 810 // everything looks fine, we are ready to actually write the changes 811 // to disk 812 813 message = "Are you sure you want to write the changes back to " 814 "disk now?\n\n"; 815 message << "All data on the partition \"" << previousName; 816 message << "\" will be irrevertably lost if you do so!"; 817 alert = new BAlert("final notice", message.String(), 818 "Write Changes", "Cancel", NULL, B_WIDTH_FROM_WIDEST, B_WARNING_ALERT); 819 choice = alert->Go(); 820 821 if (choice == 1) 822 return; 823 824 // commit 825 ret = modificationPreparer.CommitModifications(); 826 827 // The partition pointer is toast now! Use the partition id to 828 // retrieve it again. 829 partition = disk->FindDescendant(selectedPartition); 830 831 if (ret == B_OK) { 832 _DisplayPartitionError("The partition %s has been successfully " 833 "initialized.\n", partition); 834 } else { 835 _DisplayPartitionError("Failed to initialize the partition " 836 "%s!\n", partition, ret); 837 } 838 839 _ScanDrives(); 840 } 841 842