1 /* 2 * Copyright 2013, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "GPTDiskAddOn.h" 8 9 #include <new> 10 #include <stdio.h> 11 12 #include <DiskDeviceTypes.h> 13 #include <MutablePartition.h> 14 #include <PartitioningInfo.h> 15 #include <PartitionParameterEditor.h> 16 17 #include <AutoDeleter.h> 18 #include <disk_device_types.h> 19 20 #include "gpt.h" 21 22 #include "GPTPartitionHandle.h" 23 #include "Utility.h" 24 25 26 //#define TRACE_GPT_DISK_ADD_ON 27 #undef TRACE 28 #ifdef TRACE_GPT_DISK_ADD_ON 29 # define TRACE(x...) printf(x) 30 #else 31 # define TRACE(x...) do {} while (false) 32 #endif 33 34 35 static const uint32 kDiskSystemFlags = 36 0 37 // | B_DISK_SYSTEM_SUPPORTS_CHECKING 38 // | B_DISK_SYSTEM_SUPPORTS_REPAIRING 39 // | B_DISK_SYSTEM_SUPPORTS_RESIZING 40 // | B_DISK_SYSTEM_SUPPORTS_MOVING 41 // | B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_NAME 42 // | B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_PARAMETERS 43 | B_DISK_SYSTEM_SUPPORTS_INITIALIZING 44 // | B_DISK_SYSTEM_SUPPORTS_CONTENT_NAME 45 46 // | B_DISK_SYSTEM_SUPPORTS_RESIZING_CHILD 47 // | B_DISK_SYSTEM_SUPPORTS_MOVING_CHILD 48 | B_DISK_SYSTEM_SUPPORTS_SETTING_NAME 49 | B_DISK_SYSTEM_SUPPORTS_SETTING_TYPE 50 // | B_DISK_SYSTEM_SUPPORTS_SETTING_PARAMETERS 51 | B_DISK_SYSTEM_SUPPORTS_CREATING_CHILD 52 | B_DISK_SYSTEM_SUPPORTS_DELETING_CHILD 53 | B_DISK_SYSTEM_SUPPORTS_NAME 54 ; 55 56 57 // #pragma mark - GPTDiskAddOn 58 59 60 GPTDiskAddOn::GPTDiskAddOn() 61 : 62 BDiskSystemAddOn(EFI_PARTITION_NAME, kDiskSystemFlags) 63 { 64 } 65 66 67 GPTDiskAddOn::~GPTDiskAddOn() 68 { 69 } 70 71 72 status_t 73 GPTDiskAddOn::CreatePartitionHandle(BMutablePartition* partition, 74 BPartitionHandle** _handle) 75 { 76 GPTPartitionHandle* handle 77 = new(std::nothrow) GPTPartitionHandle(partition); 78 if (handle == NULL) 79 return B_NO_MEMORY; 80 81 status_t error = handle->Init(); 82 if (error != B_OK) { 83 delete handle; 84 return error; 85 } 86 87 *_handle = handle; 88 return B_OK; 89 } 90 91 92 bool 93 GPTDiskAddOn::CanInitialize(const BMutablePartition* partition) 94 { 95 // If it's big enough, we can initialize it. 96 return partition->Size() >= round_up(partition->BlockSize() 97 + EFI_PARTITION_ENTRY_COUNT * EFI_PARTITION_ENTRY_SIZE, 98 partition->BlockSize()); 99 } 100 101 102 status_t 103 GPTDiskAddOn::ValidateInitialize(const BMutablePartition* partition, 104 BString* name, const char* parameters) 105 { 106 if (!CanInitialize(partition) 107 || (parameters != NULL && parameters[0] != '\0')) 108 return B_BAD_VALUE; 109 110 // we don't support a content name 111 if (name != NULL) 112 name->Truncate(0); 113 114 return B_OK; 115 } 116 117 118 status_t 119 GPTDiskAddOn::Initialize(BMutablePartition* partition, const char* name, 120 const char* parameters, BPartitionHandle** _handle) 121 { 122 if (!CanInitialize(partition) 123 || (name != NULL && name[0] != '\0') 124 || (parameters != NULL && parameters[0] != '\0')) 125 return B_BAD_VALUE; 126 127 GPTPartitionHandle* handle 128 = new(std::nothrow) GPTPartitionHandle(partition); 129 if (handle == NULL) 130 return B_NO_MEMORY; 131 132 status_t status = partition->SetContentType(Name()); 133 if (status != B_OK) { 134 delete handle; 135 return status; 136 } 137 138 partition->SetContentName(NULL); 139 partition->SetContentParameters(NULL); 140 partition->SetContentSize( 141 round_down(partition->Size(), partition->BlockSize())); 142 partition->Changed(B_PARTITION_CHANGED_INITIALIZATION); 143 144 *_handle = handle; 145 return B_OK; 146 } 147