diff --git a/src/add-ons/disk_systems/Jamfile b/src/add-ons/disk_systems/Jamfile index 6262e19a6f..9ef53ba605 100644 --- a/src/add-ons/disk_systems/Jamfile +++ b/src/add-ons/disk_systems/Jamfile @@ -1,5 +1,6 @@ SubDir HAIKU_TOP src add-ons disk_systems ; SubInclude HAIKU_TOP src add-ons disk_systems bfs ; +SubInclude HAIKU_TOP src add-ons disk_systems gpt ; SubInclude HAIKU_TOP src add-ons disk_systems intel ; SubInclude HAIKU_TOP src add-ons disk_systems ntfs ; diff --git a/src/add-ons/disk_systems/gpt/GPTDiskAddOn.cpp b/src/add-ons/disk_systems/gpt/GPTDiskAddOn.cpp new file mode 100644 index 0000000000..5fc79e0ecb --- /dev/null +++ b/src/add-ons/disk_systems/gpt/GPTDiskAddOn.cpp @@ -0,0 +1,155 @@ +/* + * Copyright 2013, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + */ + + +#include "GPTDiskAddOn.h" + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "efi_gpt.h" + +#include "GPTPartitionHandle.h" +#include "Utility.h" + + +//#define TRACE_GPT_DISK_ADD_ON +#undef TRACE +#ifdef TRACE_GPT_DISK_ADD_ON +# define TRACE(x...) printf(x) +#else +# define TRACE(x...) do {} while (false) +#endif + + +static const uint32 kDiskSystemFlags = + 0 +// | B_DISK_SYSTEM_SUPPORTS_CHECKING +// | B_DISK_SYSTEM_SUPPORTS_REPAIRING +// | B_DISK_SYSTEM_SUPPORTS_RESIZING +// | B_DISK_SYSTEM_SUPPORTS_MOVING +// | B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_NAME +// | B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_PARAMETERS + | B_DISK_SYSTEM_SUPPORTS_INITIALIZING +// | B_DISK_SYSTEM_SUPPORTS_CONTENT_NAME + +// | B_DISK_SYSTEM_SUPPORTS_RESIZING_CHILD +// | B_DISK_SYSTEM_SUPPORTS_MOVING_CHILD +// | B_DISK_SYSTEM_SUPPORTS_SETTING_NAME + | B_DISK_SYSTEM_SUPPORTS_SETTING_TYPE +// | B_DISK_SYSTEM_SUPPORTS_SETTING_PARAMETERS + | B_DISK_SYSTEM_SUPPORTS_CREATING_CHILD + | B_DISK_SYSTEM_SUPPORTS_DELETING_CHILD +// | B_DISK_SYSTEM_SUPPORTS_NAME +; + + +// #pragma mark - GPTDiskAddOn + + +GPTDiskAddOn::GPTDiskAddOn() + : + BDiskSystemAddOn(EFI_PARTITION_NAME, kDiskSystemFlags) +{ +} + + +GPTDiskAddOn::~GPTDiskAddOn() +{ +} + + +status_t +GPTDiskAddOn::CreatePartitionHandle(BMutablePartition* partition, + BPartitionHandle** _handle) +{ + GPTPartitionHandle* handle + = new(std::nothrow) GPTPartitionHandle(partition); + if (handle == NULL) + return B_NO_MEMORY; + + status_t error = handle->Init(); + if (error != B_OK) { + delete handle; + return error; + } + + *_handle = handle; + return B_OK; +} + + +bool +GPTDiskAddOn::CanInitialize(const BMutablePartition* partition) +{ + // If it's big enough, we can initialize it. + return partition->Size() >= round_up(partition->BlockSize() + + EFI_PARTITION_ENTRY_COUNT * EFI_PARTITION_ENTRY_SIZE, + partition->BlockSize()); +} + + +status_t +GPTDiskAddOn::GetInitializationParameterEditor( + const BMutablePartition* partition, BPartitionParameterEditor** editor) +{ + // Nothing to edit, really. + *editor = NULL; + return B_OK; +} + + +status_t +GPTDiskAddOn::ValidateInitialize(const BMutablePartition* partition, + BString* name, const char* parameters) +{ + if (!CanInitialize(partition) + || (parameters != NULL && parameters[0] != '\0')) + return B_BAD_VALUE; + + // we don't support a content name + if (name != NULL) + name->Truncate(0); + + return B_OK; +} + + +status_t +GPTDiskAddOn::Initialize(BMutablePartition* partition, const char* name, + const char* parameters, BPartitionHandle** _handle) +{ + if (!CanInitialize(partition) + || (name != NULL && name[0] != '\0') + || (parameters != NULL && parameters[0] != '\0')) + return B_BAD_VALUE; + + GPTPartitionHandle* handle + = new(std::nothrow) GPTPartitionHandle(partition); + if (handle == NULL) + return B_NO_MEMORY; + + status_t status = partition->SetContentType(Name()); + if (status != B_OK) { + delete handle; + return status; + } + + partition->SetContentName(NULL); + partition->SetContentParameters(NULL); + partition->SetContentSize( + round_down(partition->Size(), partition->BlockSize())); + + *_handle = handle; + return B_OK; +} diff --git a/src/add-ons/disk_systems/gpt/GPTDiskAddOn.h b/src/add-ons/disk_systems/gpt/GPTDiskAddOn.h new file mode 100644 index 0000000000..40349b7f71 --- /dev/null +++ b/src/add-ons/disk_systems/gpt/GPTDiskAddOn.h @@ -0,0 +1,35 @@ +/* + * Copyright 2013, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + */ +#ifndef GPT_DISK_ADD_ON_H +#define GPT_DISK_ADD_ON_H + + +#include + + +class GPTDiskAddOn : public BDiskSystemAddOn { +public: + GPTDiskAddOn(); + virtual ~GPTDiskAddOn(); + + virtual status_t CreatePartitionHandle( + BMutablePartition* partition, + BPartitionHandle** handle); + + virtual bool CanInitialize( + const BMutablePartition* partition); + virtual status_t GetInitializationParameterEditor( + const BMutablePartition* partition, + BPartitionParameterEditor** editor); + virtual status_t ValidateInitialize( + const BMutablePartition* partition, + BString* name, const char* parameters); + virtual status_t Initialize(BMutablePartition* partition, + const char* name, const char* parameters, + BPartitionHandle** handle); +}; + + +#endif // GPT_DISK_ADD_ON_H diff --git a/src/add-ons/disk_systems/gpt/GPTDiskAddOn.rdef b/src/add-ons/disk_systems/gpt/GPTDiskAddOn.rdef new file mode 100644 index 0000000000..18ca93a59f --- /dev/null +++ b/src/add-ons/disk_systems/gpt/GPTDiskAddOn.rdef @@ -0,0 +1,15 @@ +/* + * IntelDiskAddOn.rdef + */ + +resource app_signature "application/x-vnd.Haiku-IntelDiskAddOn"; + +resource app_version { + major = 1, + middle = 0, + minor = 0, + variety = 0, + internal = 0, + short_info = "1.0.0", + long_info = "Haiku Intel disk add-on." +}; diff --git a/src/add-ons/disk_systems/gpt/GPTDiskSystem.cpp b/src/add-ons/disk_systems/gpt/GPTDiskSystem.cpp new file mode 100644 index 0000000000..a40b84065c --- /dev/null +++ b/src/add-ons/disk_systems/gpt/GPTDiskSystem.cpp @@ -0,0 +1,24 @@ +/* + * Copyright 2013, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + */ + + +#include + +#include + +#include "GPTDiskAddOn.h" + + +status_t +get_disk_system_add_ons(BList* addOns) +{ + GPTDiskAddOn* addOn = new(std::nothrow) GPTDiskAddOn(); + if (!addOns->AddItem(addOn)) { + delete addOn; + return B_NO_MEMORY; + } + + return B_OK; +} diff --git a/src/add-ons/disk_systems/gpt/GPTPartitionHandle.cpp b/src/add-ons/disk_systems/gpt/GPTPartitionHandle.cpp new file mode 100644 index 0000000000..abff127287 --- /dev/null +++ b/src/add-ons/disk_systems/gpt/GPTPartitionHandle.cpp @@ -0,0 +1,155 @@ +/* + * Copyright 2013, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + */ + + +#include "GPTPartitionHandle.h" + +#include +#include + +#include +#include +#include +#include + +#include + +#include "gpt_known_guids.h" + + +//#define TRACE_GPT_PARTITION_HANDLE +#undef TRACE +#ifdef TRACE_GPT_PARTITION_HANDLE +# define TRACE(x...) printf(x) +#else +# define TRACE(x...) do {} while (false) +#endif + + +GPTPartitionHandle::GPTPartitionHandle(BMutablePartition* partition) + : + BPartitionHandle(partition) +{ +} + + +GPTPartitionHandle::~GPTPartitionHandle() +{ +} + + +status_t +GPTPartitionHandle::Init() +{ + return B_OK; +} + + +uint32 +GPTPartitionHandle::SupportedOperations(uint32 mask) +{ + uint32 flags = B_DISK_SYSTEM_SUPPORTS_RESIZING + | B_DISK_SYSTEM_SUPPORTS_MOVING + | B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_PARAMETERS + | B_DISK_SYSTEM_SUPPORTS_INITIALIZING; + + // creating child + if ((mask & B_DISK_SYSTEM_SUPPORTS_CREATING_CHILD) != 0) { + BPartitioningInfo info; + if (GetPartitioningInfo(&info) == B_OK + && info.CountPartitionableSpaces() > 1) { + flags |= B_DISK_SYSTEM_SUPPORTS_CREATING_CHILD; + } + } + + return flags; +} + + +uint32 +GPTPartitionHandle::SupportedChildOperations(const BMutablePartition* child, + uint32 mask) +{ + return B_DISK_SYSTEM_SUPPORTS_RESIZING_CHILD + | B_DISK_SYSTEM_SUPPORTS_MOVING_CHILD + | B_DISK_SYSTEM_SUPPORTS_SETTING_TYPE + | B_DISK_SYSTEM_SUPPORTS_DELETING_CHILD; +} + + +status_t +GPTPartitionHandle::GetNextSupportedType(const BMutablePartition* child, + int32* cookie, BString* type) +{ + int32 index = *cookie; + TRACE("GPTPartitionHandle::GetNextSupportedType(child: %p, cookie: %ld)\n", + child, index); + + if (index >= int32(sizeof(kTypeMap) / sizeof(kTypeMap[0]))) + return B_ENTRY_NOT_FOUND; + + type->SetTo(kTypeMap[index].type); + *cookie = index + 1; + + return B_OK; +} + + +status_t +GPTPartitionHandle::GetPartitioningInfo(BPartitioningInfo* info) +{ + // init to the full size (minus the first sector) + off_t size = Partition()->ContentSize(); + status_t error = info->SetTo(Partition()->BlockSize(), + size - Partition()->BlockSize()); + if (error != B_OK) + return error; + + // TODO: exclude the space of the existing partitions + + return B_OK; +} + + +status_t +GPTPartitionHandle::GetParameterEditor(B_PARAMETER_EDITOR_TYPE type, + BPartitionParameterEditor** editor) +{ + *editor = NULL; + if (type == B_CREATE_PARAMETER_EDITOR) { + try { + *editor = new BPartitionParameterEditor(); + } catch (std::bad_alloc) { + return B_NO_MEMORY; + } + return B_OK; + } + return B_NOT_SUPPORTED; +} + + +status_t +GPTPartitionHandle::ValidateCreateChild(off_t* _offset, off_t* _size, + const char* typeString, BString* name, const char* parameters) +{ + return B_BAD_VALUE; +} + + +status_t +GPTPartitionHandle::CreateChild(off_t offset, off_t size, + const char* typeString, const char* name, const char* parameters, + BMutablePartition** _child) +{ + return B_BAD_VALUE; +} + + +status_t +GPTPartitionHandle::DeleteChild(BMutablePartition* child) +{ + BMutablePartition* parent = child->Parent(); + return parent->DeleteChild(child); +} diff --git a/src/add-ons/disk_systems/gpt/GPTPartitionHandle.h b/src/add-ons/disk_systems/gpt/GPTPartitionHandle.h new file mode 100644 index 0000000000..23fbf14119 --- /dev/null +++ b/src/add-ons/disk_systems/gpt/GPTPartitionHandle.h @@ -0,0 +1,45 @@ +/* + * Copyright 2013, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + */ +#ifndef GPT_PARTITION_HANDLE_H +#define GPT_PARTITION_HANDLE_H + + +#include + + +class GPTPartitionHandle : public BPartitionHandle { +public: + GPTPartitionHandle( + BMutablePartition* partition); + virtual ~GPTPartitionHandle(); + + status_t Init(); + + virtual uint32 SupportedOperations(uint32 mask); + virtual uint32 SupportedChildOperations( + const BMutablePartition* child, + uint32 mask); + + virtual status_t GetNextSupportedType( + const BMutablePartition* child, + int32* cookie, BString* type); + + virtual status_t GetPartitioningInfo(BPartitioningInfo* info); + + virtual status_t GetParameterEditor( + B_PARAMETER_EDITOR_TYPE type, + BPartitionParameterEditor** editor); + virtual status_t ValidateCreateChild(off_t* offset, + off_t* size, const char* type, + BString* name, const char* parameters); + virtual status_t CreateChild(off_t offset, off_t size, + const char* type, const char* name, + const char* parameters, + BMutablePartition** child); + virtual status_t DeleteChild(BMutablePartition* child); +}; + + +#endif // GPT_PARTITION_HANDLE_H diff --git a/src/add-ons/disk_systems/gpt/Jamfile b/src/add-ons/disk_systems/gpt/Jamfile new file mode 100644 index 0000000000..2c26d45985 --- /dev/null +++ b/src/add-ons/disk_systems/gpt/Jamfile @@ -0,0 +1,17 @@ +SubDir HAIKU_TOP src add-ons disk_systems gpt ; + +UsePrivateHeaders shared storage ; +UsePrivateSystemHeaders ; + +SEARCH_SOURCE + += [ FDirName $(HAIKU_TOP) src add-ons kernel partitioning_systems efi ] ; + +AddResources gpt : GPTDiskAddOn.rdef ; + +Addon gpt : + GPTDiskSystem.cpp + GPTDiskAddOn.cpp + GPTPartitionHandle.cpp + + : be $(TARGET_LIBSUPC++) +; diff --git a/src/add-ons/disk_systems/gpt/Utility.h b/src/add-ons/disk_systems/gpt/Utility.h new file mode 100644 index 0000000000..2c2ad1a077 --- /dev/null +++ b/src/add-ons/disk_systems/gpt/Utility.h @@ -0,0 +1,26 @@ +/* + * Copyright 2013, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + */ +#ifndef UTILITY_H +#define UTILITY_H + + +#include + + +static inline off_t +round_down(off_t a, uint32 b) +{ + return a / b * b; +} + + +static inline off_t +round_up(off_t a, uint32 b) +{ + return round_down(a + b - 1, b); +} + + +#endif // UTILITY_H