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
35static 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
60GPTDiskAddOn::GPTDiskAddOn()
61	:
62	BDiskSystemAddOn(EFI_PARTITION_NAME, kDiskSystemFlags)
63{
64}
65
66
67GPTDiskAddOn::~GPTDiskAddOn()
68{
69}
70
71
72status_t
73GPTDiskAddOn::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
92bool
93GPTDiskAddOn::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
102status_t
103GPTDiskAddOn::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
118status_t
119GPTDiskAddOn::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