Example #1
0
	void _InitializePartition()
	{
		if (!fPrepared) {
			if (fDevice->IsReadOnly())
				printf("Device is read-only!\n");
			else
				printf("Sorry, not prepared for modifications!\n");
			return;
		}

		// get the partition
		int32 partitionIndex;
		BPartition* partition = NULL;
		if (!_SelectPartition("partition index [-1 to abort]: ", partition,
				partitionIndex)) {
			return;
		}

		printf("\nselected partition:\n\n");
		print_partition_table_header();
		print_partition(partition, 0, partitionIndex);

		// get available disk systems
		BObjectList<BDiskSystem> diskSystems(20, true);
		BDiskDeviceRoster roster;
		{
			BDiskSystem diskSystem;
			while (roster.GetNextDiskSystem(&diskSystem) == B_OK) {
				if (partition->CanInitialize(diskSystem.PrettyName()))
					diskSystems.AddItem(new BDiskSystem(diskSystem));
			}
		}

		if (diskSystems.IsEmpty()) {
			printf("There are no disk systems, that can initialize this "
				"partition.\n");
			return;
		}

		// print the available disk systems
		printf("\ndisk systems that can initialize the selected partition:\n");
		for (int32 i = 0; BDiskSystem* diskSystem = diskSystems.ItemAt(i); i++)
			printf("%2ld  %s\n", i, diskSystem->PrettyName());

		printf("\n");

		// get the disk system
		int64 diskSystemIndex;
		if (!_ReadNumber("disk system index [-1 to abort]: ", 0,
				diskSystems.CountItems() - 1, -1, "invalid index",
				diskSystemIndex)) {
			return;
		}
		BDiskSystem* diskSystem = diskSystems.ItemAt(diskSystemIndex);

		bool supportsName = diskSystem->SupportsContentName();
		BString name;
		BString parameters;
		while (true) {
			// let the user enter name and parameters
			if (supportsName && !_ReadLine("partition name: ", name)
				|| !_ReadLine("partition parameters: ", parameters)) {
				return;
			}

			// validate parameters
			BString validatedName(name);
			if (partition->ValidateInitialize(diskSystem->PrettyName(),
					supportsName ? &validatedName : NULL, parameters.String())
					!= B_OK) {
				printf("Validation of the given values failed. Sorry, can't "
					"continue.\n");
				return;
			}

			// did the disk system change the name?
			if (!supportsName || name == validatedName) {
				printf("Everything looks dandy.\n");
			} else {
				printf("The disk system adjusted the file name to \"%s\".\n",
					validatedName.String());
				name = validatedName;
			}

			// let the user decide whether to continue, change parameters, or
			// abort
			bool changeParameters = false;
			while (true) {
				BString line;
				_ReadLine("[c]ontinue, change [p]arameters, or [a]bort? ", line);
				if (line == "a")
					return;
				if (line == "p") {
					changeParameters = true;
					break;
				}
				if (line == "c")
					break;

				printf("invalid input\n");
			}

			if (!changeParameters)
				break;
		}

		// initialize
		status_t error = partition->Initialize(diskSystem->PrettyName(),
			supportsName ? name.String() : NULL, parameters.String());
		if (error != B_OK)
			printf("Initialization failed: %s\n", strerror(error));
	}
Example #2
0
void
MainWindow::_Initialize(BDiskDevice* disk, partition_id selectedPartition,
	const BString& diskSystemName)
{
	if (!disk || selectedPartition < 0) {
		_DisplayPartitionError(B_TRANSLATE("You need to select a partition "
			"entry from the list."));
		return;
	}

	if (disk->IsReadOnly()) {
		_DisplayPartitionError(B_TRANSLATE("The selected disk is read-only."));
		return;
	}

	BPartition* partition = disk->FindDescendant(selectedPartition);
	if (!partition) {
		_DisplayPartitionError(B_TRANSLATE("Unable to find the selected "
			"partition by ID."));
		return;
	}

	if (partition->IsMounted()) {
		_DisplayPartitionError(
			B_TRANSLATE("The partition %s is currently mounted."));
		// TODO: option to unmount and continue on success to unmount
		return;
	}

	BDiskSystem diskSystem;
	fDDRoster.RewindDiskSystems();
	bool found = false;
	while (fDDRoster.GetNextDiskSystem(&diskSystem) == B_OK) {
		if (diskSystem.SupportsInitializing()) {
			if (diskSystemName == diskSystem.PrettyName()) {
				found = true;
				break;
			}
		}
	}

	char message[512];

	if (!found) {
		snprintf(message, sizeof(message), B_TRANSLATE("Disk system \"%s\"\" "
			"not found!"));
		_DisplayPartitionError(message);
		return;
	}

	if (diskSystem.IsFileSystem()) {
		if (disk->ID() == selectedPartition) {
			snprintf(message, sizeof(message), B_TRANSLATE("Are you sure you "
				"want to format a raw disk? (most people initialize the disk "
				"with a partitioning system first) You will be asked "
				"again before changes are written to the disk."));
		} else if (partition->ContentName()
			&& strlen(partition->ContentName()) > 0) {
			snprintf(message, sizeof(message), B_TRANSLATE("Are you sure you "
				"want to format the partition \"%s\"? You will be asked "
				"again before changes are written to the disk."),
				partition->ContentName());
		} else {
			snprintf(message, sizeof(message), B_TRANSLATE("Are you sure you "
				"want to format the partition? You will be asked again "
				"before changes are written to the disk."));
		}
	} else {
		snprintf(message, sizeof(message), B_TRANSLATE("Are you sure you "
			"want to initialize the selected disk? All data will be lost. "
			"You will be asked again before changes are written to the "
			"disk.\n"));
	}
	BAlert* alert = new BAlert("first notice", message,
		B_TRANSLATE("Continue"), B_TRANSLATE("Cancel"), NULL,
		B_WIDTH_FROM_WIDEST, B_WARNING_ALERT);
	int32 choice = alert->Go();

	if (choice == 1)
		return;

	ModificationPreparer modificationPreparer(disk);
	status_t ret = modificationPreparer.ModificationStatus();
	if (ret != B_OK) {
		_DisplayPartitionError(B_TRANSLATE("There was an error preparing the "
			"disk for modifications."), NULL, ret);
		return;
	}

	BString name;
	BString parameters;

	// TODO: diskSystem.IsFileSystem() seems like a better fit here?
	if (diskSystemName == "Be File System") {
		InitParamsPanel* panel = new InitParamsPanel(this, diskSystemName,
			partition);
		if (panel->Go(name, parameters) == GO_CANCELED)
			return;
	} else if (diskSystemName == "Intel Partition Map") {
		// TODO: parameters?
	} else if (diskSystemName == "Intel Extended Partition") {
		// TODO: parameters?
	}

	bool supportsName = diskSystem.SupportsContentName();
	BString validatedName(name);
	ret = partition->ValidateInitialize(diskSystem.PrettyName(),
		supportsName ? &validatedName : NULL, parameters.String());
	if (ret != B_OK) {
		_DisplayPartitionError(B_TRANSLATE("Validation of the given "
			"initialization parameters failed."), partition, ret);
		return;
	}

	BString previousName = partition->ContentName();

	ret = partition->Initialize(diskSystem.PrettyName(),
		supportsName ? validatedName.String() : NULL, parameters.String());
	if (ret != B_OK) {
		_DisplayPartitionError(B_TRANSLATE("Initialization of the partition "
			"%s failed. (Nothing has been written to disk.)"), partition, ret);
		return;
	}

	// everything looks fine, we are ready to actually write the changes
	// to disk

	// Warn the user one more time...
	if (previousName.Length() > 0) {
		if (partition->IsDevice()) {
			snprintf(message, sizeof(message), B_TRANSLATE("Are you sure you "
				"want to write the changes back to disk now?\n\n"
				"All data on the disk %s will be irretrievably lost if you "
				"do so!"), previousName.String());
		} else {
			snprintf(message, sizeof(message), B_TRANSLATE("Are you sure you "
				"want to write the changes back to disk now?\n\n"
				"All data on the partition %s will be irretrievably lost if you "
				"do so!"), previousName.String());
		}
	} else {
		if (partition->IsDevice()) {
			snprintf(message, sizeof(message), B_TRANSLATE("Are you sure you "
				"want to write the changes back to disk now?\n\n"
				"All data on the selected disk will be irretrievably lost if "
				"you do so!"));
		} else {
			snprintf(message, sizeof(message), B_TRANSLATE("Are you sure you "
				"want to write the changes back to disk now?\n\n"
				"All data on the selected partition will be irretrievably lost "
				"if you do so!"));
		}
	}
	alert = new BAlert("final notice", message,
		B_TRANSLATE("Write changes"), B_TRANSLATE("Cancel"), NULL,
		B_WIDTH_FROM_WIDEST, B_WARNING_ALERT);
	choice = alert->Go();

	if (choice == 1)
		return;

	// commit
	ret = modificationPreparer.CommitModifications();

	// The partition pointer is toast now! Use the partition ID to
	// retrieve it again.
	partition = disk->FindDescendant(selectedPartition);

	if (ret == B_OK) {
		if (diskSystem.IsFileSystem()) {
			_DisplayPartitionError(B_TRANSLATE("The partition %s has been "
				"successfully formatted.\n"), partition);
		} else {
			_DisplayPartitionError(B_TRANSLATE("The disk has been "
				"successfully initialized.\n"), partition);
		}
	} else {
		if (diskSystem.IsFileSystem()) {
			_DisplayPartitionError(B_TRANSLATE("Failed to format the "
				"partition %s!\n"), partition, ret);
		} else {
			_DisplayPartitionError(B_TRANSLATE("Failed to initialize the "
				"disk %s!\n"), partition, ret);
		}
	}

	_ScanDrives();
}
Example #3
0
/*static*/ bool
AutoMounter::_SuggestMountFlags(const BPartition* partition, uint32* _flags)
{
	uint32 mountFlags = 0;

	bool askReadOnly = true;
	bool isBFS = false;

	if (partition->ContentType() != NULL
		&& strcmp(partition->ContentType(), kPartitionTypeBFS) == 0) {
#if 0
		askReadOnly = false;
#endif
		isBFS = true;
	}

	BDiskSystem diskSystem;
	status_t status = partition->GetDiskSystem(&diskSystem);
	if (status == B_OK && !diskSystem.SupportsWriting())
		askReadOnly = false;

	if (partition->IsReadOnly())
		askReadOnly = false;

	if (askReadOnly) {
		// Suggest to the user to mount read-only until Haiku is more mature.
		BString string;
		if (partition->ContentName() != NULL) {
			char buffer[512];
			snprintf(buffer, sizeof(buffer),
				B_TRANSLATE("Mounting volume '%s'\n\n"),
				partition->ContentName());
			string << buffer;
		} else
			string << B_TRANSLATE("Mounting volume <unnamed volume>\n\n");

		// TODO: Use distro name instead of "Haiku"...
		if (!isBFS) {
			string << B_TRANSLATE("The file system on this volume is not the "
				"Haiku file system. It is strongly suggested to mount it in "
				"read-only mode. This will prevent unintentional data loss "
				"because of errors in Haiku.");
		} else {
			string << B_TRANSLATE("It is suggested to mount all additional "
				"Haiku volumes in read-only mode. This will prevent "
				"unintentional data loss because of errors in Haiku.");
		}

		BAlert* alert = new BAlert(B_TRANSLATE("Mount warning"),
			string.String(), B_TRANSLATE("Mount read/write"),
			B_TRANSLATE("Cancel"), B_TRANSLATE("Mount read-only"),
			B_WIDTH_FROM_WIDEST, B_WARNING_ALERT);
		alert->SetShortcut(1, B_ESCAPE);
		int32 choice = alert->Go();
		switch (choice) {
			case 0:
				break;
			case 1:
				return false;
			case 2:
				mountFlags |= B_MOUNT_READ_ONLY;
				break;
		}
	}

	*_flags = mountFlags;
	return true;
}
Example #4
0
void
MainWindow::_UpdateMenus(BDiskDevice* disk,
	partition_id selectedPartition, partition_id parentID)
{
	while (BMenuItem* item = fFormatMenu->RemoveItem(0L))
		delete item;
	while (BMenuItem* item = fDiskInitMenu->RemoveItem(0L))
		delete item;

	fCreateMI->SetEnabled(false);
	fUnmountMI->SetEnabled(false);
	fDiskInitMenu->SetEnabled(false);
	fFormatMenu->SetEnabled(false);

	if (!disk) {
		fWipeMI->SetEnabled(false);
		fEjectMI->SetEnabled(false);
		fSurfaceTestMI->SetEnabled(false);
	} else {
//		fWipeMI->SetEnabled(true);
		fWipeMI->SetEnabled(false);
		fEjectMI->SetEnabled(disk->IsRemovableMedia());
//		fSurfaceTestMI->SetEnabled(true);
		fSurfaceTestMI->SetEnabled(false);

		// Create menu and items
		BPartition* parentPartition = NULL;
		if (selectedPartition <= -2) {
			// a partitionable space item is selected
			parentPartition = disk->FindDescendant(parentID);
		}

		if (parentPartition && parentPartition->ContainsPartitioningSystem())
			fCreateMI->SetEnabled(true);

		bool prepared = disk->PrepareModifications() == B_OK;
		fFormatMenu->SetEnabled(prepared);
		fDeleteMI->SetEnabled(prepared);

		BPartition* partition = disk->FindDescendant(selectedPartition);

		BDiskSystem diskSystem;
		fDDRoster.RewindDiskSystems();
		while (fDDRoster.GetNextDiskSystem(&diskSystem) == B_OK) {
			if (!diskSystem.SupportsInitializing())
				continue;

			BMessage* message = new BMessage(MSG_INITIALIZE);
			message->AddInt32("parent id", parentID);
			message->AddString("disk system", diskSystem.PrettyName());

			BString label = diskSystem.PrettyName();
			label << B_UTF8_ELLIPSIS;
			BMenuItem* item = new BMenuItem(label.String(), message);

			// TODO: Very unintuitive that we have to use PrettyName (vs Name)
			item->SetEnabled(partition != NULL
				&& partition->CanInitialize(diskSystem.PrettyName()));

			if (disk->ID() == selectedPartition
				&& !diskSystem.IsFileSystem()) {
				// Disk is selected, and DiskSystem is a partition map
				fDiskInitMenu->AddItem(item);
			} else if (diskSystem.IsFileSystem()) {
				// Otherwise a filesystem
				fFormatMenu->AddItem(item);
			}
		}

		// Mount items
		if (partition) {
			fFormatMenu->SetEnabled(!partition->IsMounted()
				&& !partition->IsReadOnly()
				&& partition->Device()->HasMedia()
				&& fFormatMenu->CountItems() > 0);

			fDiskInitMenu->SetEnabled(!partition->IsMounted()
				&& !partition->IsReadOnly()
				&& partition->Device()->HasMedia()
				&& partition->IsDevice()
				&& fDiskInitMenu->CountItems() > 0);

			fDeleteMI->SetEnabled(!partition->IsMounted()
				&& !partition->IsDevice());

			fMountMI->SetEnabled(!partition->IsMounted());

			bool unMountable = false;
			if (partition->IsMounted()) {
				// see if this partition is the boot volume
				BVolume volume;
				BVolume bootVolume;
				if (BVolumeRoster().GetBootVolume(&bootVolume) == B_OK
					&& partition->GetVolume(&volume) == B_OK) {
					unMountable = volume != bootVolume;
				} else
					unMountable = true;
			}
			fUnmountMI->SetEnabled(unMountable);
		} else {
			fDeleteMI->SetEnabled(false);
			fMountMI->SetEnabled(false);
			fFormatMenu->SetEnabled(false);
			fDiskInitMenu->SetEnabled(false);
		}

		if (prepared)
			disk->CancelModifications();

		fMountAllMI->SetEnabled(true);
	}
	if (selectedPartition < 0) {
		fDeleteMI->SetEnabled(false);
		fMountMI->SetEnabled(false);
	}
}