diff --git a/src/add-ons/disk_systems/intel/PartitionMapAddOn.cpp b/src/add-ons/disk_systems/intel/PartitionMapAddOn.cpp index 913bf3c38c..e14375743c 100644 --- a/src/add-ons/disk_systems/intel/PartitionMapAddOn.cpp +++ b/src/add-ons/disk_systems/intel/PartitionMapAddOn.cpp @@ -236,7 +236,6 @@ PartitionMapHandle::SupportedChildOperations(const BMutablePartition* child, { return B_DISK_SYSTEM_SUPPORTS_RESIZING_CHILD | B_DISK_SYSTEM_SUPPORTS_MOVING_CHILD - | B_DISK_SYSTEM_SUPPORTS_SETTING_TYPE | B_DISK_SYSTEM_SUPPORTS_SETTING_PARAMETERS | B_DISK_SYSTEM_SUPPORTS_DELETING_CHILD; } @@ -295,6 +294,44 @@ PartitionMapHandle::GetPartitioningInfo(BPartitioningInfo* info) } +status_t +PartitionMapHandle::ValidateSetParameters(const BMutablePartition* child, + const char* parameters) +{ + if (child == NULL || parameters == NULL) + return B_NO_INIT; + + void* handle = parse_driver_settings_string(parameters); + if (handle == NULL) + return B_BAD_DATA; + + delete_driver_settings(handle); + + return B_OK; +} + + +status_t +PartitionMapHandle::SetParameters(BMutablePartition* child, + const char* parameters) +{ + void* handle = parse_driver_settings_string(parameters); + if (handle == NULL) + return B_BAD_DATA; + + bool active = get_driver_boolean_parameter(handle, "active", false, true); + delete_driver_settings(handle); + + // Update our local state + PrimaryPartition* partition = (PrimaryPartition*)child->ChildCookie(); + partition->SetActive(active); + + // Forward the request to the BMutablePartition so it can be committed to + // disk + return child->SetParameters(parameters); +} + + status_t PartitionMapHandle::GetParameterEditor(B_PARAMETER_EDITOR_TYPE type, BPartitionParameterEditor** editor) diff --git a/src/add-ons/disk_systems/intel/PartitionMapAddOn.h b/src/add-ons/disk_systems/intel/PartitionMapAddOn.h index 343f3cd227..6f6b90ca67 100644 --- a/src/add-ons/disk_systems/intel/PartitionMapAddOn.h +++ b/src/add-ons/disk_systems/intel/PartitionMapAddOn.h @@ -49,6 +49,13 @@ public: virtual status_t GetPartitioningInfo(BPartitioningInfo* info); + virtual status_t ValidateSetParameters( + const BMutablePartition* child, + const char* parameters); + virtual status_t SetParameters( + BMutablePartition* child, + const char* parameters); + virtual status_t GetParameterEditor( B_PARAMETER_EDITOR_TYPE type, BPartitionParameterEditor** editor); @@ -59,7 +66,7 @@ public: const char* type, const char* name, const char* parameters, BMutablePartition** child); - virtual status_t DeleteChild(BMutablePartition* child); + virtual status_t DeleteChild(BMutablePartition* child); private: PartitionMap fPartitionMap; diff --git a/src/add-ons/disk_systems/intel/PrimaryParameterEditor.cpp b/src/add-ons/disk_systems/intel/PrimaryParameterEditor.cpp index 0d89a9cfbf..2ccbac627b 100644 --- a/src/add-ons/disk_systems/intel/PrimaryParameterEditor.cpp +++ b/src/add-ons/disk_systems/intel/PrimaryParameterEditor.cpp @@ -44,10 +44,15 @@ status_t PrimaryPartitionEditor::ParameterChanged(const char* name, const BVariant& variant) { - if (!strcmp(name, "type")) { + if (strcmp(name, "type") == 0) { fActiveCheckBox->SetEnabled(strcmp(variant.ToString(), kPartitionTypeIntelExtended) != 0); + fActiveCheckBox->SetValue(false); } + + if (strcmp(name, "active") == 0) + fActiveCheckBox->SetValue(variant.ToBool()); + return B_OK; } diff --git a/src/add-ons/kernel/partitioning_systems/intel/intel.cpp b/src/add-ons/kernel/partitioning_systems/intel/intel.cpp index 6591c4b9c8..f53aaffdd7 100644 --- a/src/add-ons/kernel/partitioning_systems/intel/intel.cpp +++ b/src/add-ons/kernel/partitioning_systems/intel/intel.cpp @@ -494,8 +494,8 @@ static partition_module_info intel_partition_map_module = NULL, // set_name NULL, // set_content_name pm_set_type, // set_type - NULL, // set_parameters - NULL, // set_content_parameters + pm_set_parameters, // set_parameters + pm_set_parameters, // set_content_parameters pm_initialize, // initialize pm_uninitialize, // uninitialize pm_create_child, // create_child diff --git a/src/add-ons/kernel/partitioning_systems/intel/write_support.cpp b/src/add-ons/kernel/partitioning_systems/intel/write_support.cpp index b9d2bb0794..dda012f76d 100644 --- a/src/add-ons/kernel/partitioning_systems/intel/write_support.cpp +++ b/src/add-ons/kernel/partitioning_systems/intel/write_support.cpp @@ -1249,6 +1249,80 @@ pm_set_type(int fd, partition_id partitionID, const char* type, disk_job_id job) } +// pm_set_parameters +status_t +pm_set_parameters(int fd, partition_id partitionID, const char* parameters, + disk_job_id job) +{ + TRACE(("intel: pm_set_parameters\n")); + + if (fd < 0) + return B_BAD_VALUE; + + // Nothing to do if there are no parameters provided + if (parameters == NULL) + return B_OK; + + PartitionWriteLocker locker(partitionID); + if (!locker.IsLocked()) + return B_ERROR; + + // get parent partition, child and partition map structure + partition_data* partition = get_parent_partition(partitionID); + partition_data* child = get_partition(partitionID); + if (partition == NULL || child == NULL) + return B_BAD_VALUE; + PartitionMap* map = (PartitionMap*)partition->content_cookie; + PrimaryPartition* primary = (PrimaryPartition*)child->cookie; + if (map ==NULL || primary == NULL) + return B_BAD_VALUE; + + // check parameters + void* handle = parse_driver_settings_string(parameters); + if (handle == NULL) + return B_ERROR; + + bool active = get_driver_boolean_parameter(handle, "active", false, true); + delete_driver_settings(handle); + + // if the old type is the same, there is nothing to do + if (primary->Active() == active) { + TRACE(("intel: pm_set_parameters: no changes required.\n")); + return B_OK; + } + + update_disk_device_job_progress(job, 0.0); + + // set the active flags to false for other partitions + if (active) { + for (int i = 0; i < 4; i++) { + PrimaryPartition* partition = map->PrimaryPartitionAt(i); + partition->SetActive(false); + } + } + + bool oldActive = primary->Active(); + primary->SetActive(active); + + // TODO: The partition is not supposed to be locked at this point! + PartitionMapWriter writer(fd, primary->BlockSize()); + // TODO: disk size? + status_t error = writer.WriteMBR(map, false); + if (error != B_OK) { + TRACE(("intel: pm_set_parameters: Failed to rewrite MBR: %s\n", + strerror(error))); + // something went wrong - putting into previous state + primary->SetType(oldActive); + return error; + } + + // all changes applied + update_disk_device_job_progress(job, 1.0); + partition_modified(partitionID); + return B_OK; +} + + // pm_initialize status_t pm_initialize(int fd, partition_id partitionID, const char* name, diff --git a/src/add-ons/kernel/partitioning_systems/intel/write_support.h b/src/add-ons/kernel/partitioning_systems/intel/write_support.h index 5d63ab6344..0764ade570 100644 --- a/src/add-ons/kernel/partitioning_systems/intel/write_support.h +++ b/src/add-ons/kernel/partitioning_systems/intel/write_support.h @@ -46,6 +46,8 @@ status_t pm_move_child(int fd, partition_id partitionID, partition_id childID, off_t offset, disk_job_id job); status_t pm_set_type(int fd, partition_id partitionID, const char* type, disk_job_id job); +status_t pm_set_parameters(int fd, partition_id partitionID, + const char* parameters, disk_job_id job); status_t pm_initialize(int fd, partition_id partitionID, const char* name, const char* parameters, off_t partitionSize, disk_job_id job); status_t pm_uninitialize(int fd, partition_id partitionID, diff --git a/src/apps/drivesetup/ChangeParametersPanel.cpp b/src/apps/drivesetup/ChangeParametersPanel.cpp index 978177802a..58cd2790e6 100644 --- a/src/apps/drivesetup/ChangeParametersPanel.cpp +++ b/src/apps/drivesetup/ChangeParametersPanel.cpp @@ -109,24 +109,28 @@ ChangeParametersPanel::Go(BString& name, BString& type, BString& parameters, void -ChangeParametersPanel::CreateChangeControls(BPartition* parent) +ChangeParametersPanel::CreateChangeControls(BPartition* partition) { fNameTextControl = new BTextControl("Name Control", - B_TRANSLATE("Partition name:"), "", NULL); - fSupportsName = parent->SupportsChildName(); + B_TRANSLATE("Partition name:"), partition->Name(), NULL); + fSupportsName = partition->CanSetName(); fTypePopUpMenu = new BPopUpMenu("Partition Type"); int32 cookie = 0; BString supportedType; - while (parent->GetNextSupportedChildType(&cookie, &supportedType) == B_OK) { - BMessage* message = new BMessage(MSG_PARTITION_TYPE); - message->AddString("type", supportedType); - BMenuItem* item = new BMenuItem(supportedType, message); - fTypePopUpMenu->AddItem(item); + BPartition* parent = partition->Parent(); + if (parent != NULL) { + while (parent->GetNextSupportedChildType(&cookie, &supportedType) + == B_OK) { + BMessage* message = new BMessage(MSG_PARTITION_TYPE); + message->AddString("type", supportedType); + BMenuItem* item = new BMenuItem(supportedType, message); + fTypePopUpMenu->AddItem(item); - if (strcmp(supportedType, kPartitionTypeBFS) == 0) - item->SetMarked(true); + if (strcmp(supportedType, kPartitionTypeBFS) == 0) + item->SetMarked(true); + } } fTypeMenuField = new BMenuField(B_TRANSLATE("Partition type:"), diff --git a/src/kits/storage/disk_device/DiskDeviceJobGenerator.cpp b/src/kits/storage/disk_device/DiskDeviceJobGenerator.cpp index f132286994..e49b4c0d86 100644 --- a/src/kits/storage/disk_device/DiskDeviceJobGenerator.cpp +++ b/src/kits/storage/disk_device/DiskDeviceJobGenerator.cpp @@ -410,9 +410,10 @@ DiskDeviceJobGenerator::_GenerateRemainingJobs(BPartition* parent, } // parameters - if ((changeFlags & B_PARTITION_CHANGED_PARAMETERS) - || compare_string(partition->Parameters(), - partitionData->parameters)) { + if ((partition->Parameters() != NULL) + && ((changeFlags & B_PARTITION_CHANGED_PARAMETERS) != 0 + || compare_string(partition->Parameters(), + partitionData->parameters))) { if (!parent) return B_BAD_VALUE; @@ -441,9 +442,10 @@ DiskDeviceJobGenerator::_GenerateRemainingJobs(BPartition* parent, } // content parameters - if ((changeFlags & B_PARTITION_CHANGED_PARAMETERS) - || compare_string(partition->ContentParameters(), - partitionData->content_parameters)) { + if ((partition->ContentParameters() != NULL) + && ((changeFlags & B_PARTITION_CHANGED_PARAMETERS) != 0 + || compare_string(partition->ContentParameters(), + partitionData->content_parameters))) { status_t error = _GenerateSetContentParametersJob(partition); if (error != B_OK) return error; diff --git a/src/kits/storage/disk_device/DiskDeviceJobQueue.cpp b/src/kits/storage/disk_device/DiskDeviceJobQueue.cpp index 0b2ea74607..e10775ce2f 100644 --- a/src/kits/storage/disk_device/DiskDeviceJobQueue.cpp +++ b/src/kits/storage/disk_device/DiskDeviceJobQueue.cpp @@ -6,6 +6,7 @@ #include "DiskDeviceJobQueue.h" #include +#include #include @@ -54,7 +55,8 @@ DiskDeviceJobQueue::Execute() status_t error = job->Do(); if (error != B_OK) { - TRACE("DiskDeviceJobQueue::Execute(): executing job failed\n"); + TRACE("DiskDeviceJobQueue::Execute(): executing job failed: %s\n", + strerror(error)); return error; } }