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 33GPTPartitionHandle::GPTPartitionHandle(BMutablePartition* partition) 34 : 35 BPartitionHandle(partition) 36{ 37} 38 39 40GPTPartitionHandle::~GPTPartitionHandle() 41{ 42} 43 44 45status_t 46GPTPartitionHandle::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 69uint32 70GPTPartitionHandle::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 90uint32 91GPTPartitionHandle::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 101status_t 102GPTPartitionHandle::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 119status_t 120GPTPartitionHandle::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 144status_t 145GPTPartitionHandle::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 161status_t 162GPTPartitionHandle::ValidateCreateChild(off_t* _offset, off_t* _size, 163 const char* typeString, BString* name, const char* parameters) 164{ 165 return B_OK; 166} 167 168 169status_t 170GPTPartitionHandle::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 192status_t 193GPTPartitionHandle::DeleteChild(BMutablePartition* child) 194{ 195 BMutablePartition* parent = child->Parent(); 196 return parent->DeleteChild(child); 197} 198