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