xref: /haiku/src/add-ons/disk_systems/gpt/GPTPartitionHandle.cpp (revision e5d65858f2361fe0552495b61620c84dcee6bc00)
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