1 /* 2 * Copyright 2013, Axel Dörfler, axeld@pinc-software.de. 3 * Copyright 2007, Ingo Weinhold, bonefish@users.sf.net. 4 * Distributed under the terms of the MIT License. 5 */ 6 7 8 #include "GPTPartitionHandle.h" 9 10 #include <new> 11 #include <stdio.h> 12 13 #include <DiskDeviceTypes.h> 14 #include <MutablePartition.h> 15 #include <PartitioningInfo.h> 16 #include <PartitionParameterEditor.h> 17 #include <Path.h> 18 19 #include <AutoDeleter.h> 20 21 #include "gpt_known_guids.h" 22 23 24 //#define TRACE_GPT_PARTITION_HANDLE 25 #undef TRACE 26 #ifdef TRACE_GPT_PARTITION_HANDLE 27 # define TRACE(x...) printf(x) 28 #else 29 # define TRACE(x...) do {} while (false) 30 #endif 31 32 33 GPTPartitionHandle::GPTPartitionHandle(BMutablePartition* partition) 34 : 35 BPartitionHandle(partition) 36 { 37 } 38 39 40 GPTPartitionHandle::~GPTPartitionHandle() 41 { 42 } 43 44 45 status_t 46 GPTPartitionHandle::Init() 47 { 48 // TODO: how to get the path of a BMutablePartition? 49 //BPath path; 50 //status_t status = Partition()->GetPath(&path); 51 //if (status != B_OK) 52 //return status; 53 54 //fd = open(path.Path(), O_RDONLY); 55 //if (fd < 0) 56 //return errno; 57 58 //fHeader = new EFI::Header(fd, Partition()->BlockSize(), 59 //Partition()->BlockSize()); 60 //status = fHeader->InitCheck(); 61 //if (status != B_OK) 62 //return status; 63 64 //close(fd); 65 return B_OK; 66 } 67 68 69 uint32 70 GPTPartitionHandle::SupportedOperations(uint32 mask) 71 { 72 uint32 flags = B_DISK_SYSTEM_SUPPORTS_RESIZING 73 | B_DISK_SYSTEM_SUPPORTS_MOVING 74 | B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_PARAMETERS 75 | B_DISK_SYSTEM_SUPPORTS_INITIALIZING; 76 77 // creating child 78 if ((mask & B_DISK_SYSTEM_SUPPORTS_CREATING_CHILD) != 0) { 79 BPartitioningInfo info; 80 if (GetPartitioningInfo(&info) == B_OK 81 && info.CountPartitionableSpaces() > 1) { 82 flags |= B_DISK_SYSTEM_SUPPORTS_CREATING_CHILD; 83 } 84 } 85 86 return flags; 87 } 88 89 90 uint32 91 GPTPartitionHandle::SupportedChildOperations(const BMutablePartition* child, 92 uint32 mask) 93 { 94 return B_DISK_SYSTEM_SUPPORTS_RESIZING_CHILD 95 | B_DISK_SYSTEM_SUPPORTS_MOVING_CHILD 96 | B_DISK_SYSTEM_SUPPORTS_SETTING_TYPE 97 | B_DISK_SYSTEM_SUPPORTS_DELETING_CHILD; 98 } 99 100 101 status_t 102 GPTPartitionHandle::GetNextSupportedType(const BMutablePartition* child, 103 int32* cookie, BString* type) 104 { 105 int32 index = *cookie; 106 TRACE("GPTPartitionHandle::GetNextSupportedType(child: %p, cookie: %ld)\n", 107 child, index); 108 109 if (index >= int32(sizeof(kTypeMap) / sizeof(kTypeMap[0]))) 110 return B_ENTRY_NOT_FOUND; 111 112 type->SetTo(kTypeMap[index].type); 113 *cookie = index + 1; 114 115 return B_OK; 116 } 117 118 119 status_t 120 GPTPartitionHandle::GetPartitioningInfo(BPartitioningInfo* info) 121 { 122 // init to the full size (minus the GPT table header and entries) 123 off_t size = Partition()->ContentSize(); 124 // TODO: use fHeader 125 size_t headerSize = Partition()->BlockSize() + 16384; 126 status_t status = info->SetTo(Partition()->BlockSize() + headerSize, 127 size - Partition()->BlockSize() - 2 * headerSize); 128 if (status != B_OK) 129 return status; 130 131 // Exclude the space of the existing partitions 132 size_t count = Partition()->CountChildren(); 133 for (size_t index = 0; index < count; index++) { 134 BMutablePartition* child = Partition()->ChildAt(index); 135 status = info->ExcludeOccupiedSpace(child->Offset(), child->Size()); 136 if (status != B_OK) 137 return status; 138 } 139 140 return B_OK; 141 } 142 143 144 status_t 145 GPTPartitionHandle::GetParameterEditor(B_PARAMETER_EDITOR_TYPE type, 146 BPartitionParameterEditor** editor) 147 { 148 *editor = NULL; 149 if (type == B_CREATE_PARAMETER_EDITOR) { 150 try { 151 *editor = new BPartitionParameterEditor(); 152 } catch (std::bad_alloc) { 153 return B_NO_MEMORY; 154 } 155 return B_OK; 156 } 157 return B_NOT_SUPPORTED; 158 } 159 160 161 status_t 162 GPTPartitionHandle::ValidateCreateChild(off_t* _offset, off_t* _size, 163 const char* typeString, BString* name, const char* parameters) 164 { 165 return B_OK; 166 } 167 168 169 status_t 170 GPTPartitionHandle::CreateChild(off_t offset, off_t size, 171 const char* typeString, const char* name, const char* parameters, 172 BMutablePartition** _child) 173 { 174 // create the child 175 BMutablePartition* partition = Partition(); 176 BMutablePartition* child; 177 status_t status = partition->CreateChild(partition->CountChildren(), 178 typeString, name, parameters, &child); 179 if (status != B_OK) 180 return status; 181 182 // init the child 183 child->SetOffset(offset); 184 child->SetSize(size); 185 child->SetBlockSize(partition->BlockSize()); 186 187 *_child = child; 188 return B_OK; 189 } 190 191 192 status_t 193 GPTPartitionHandle::DeleteChild(BMutablePartition* child) 194 { 195 BMutablePartition* parent = child->Parent(); 196 return parent->DeleteChild(child); 197 } 198