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
GPTDiskAddOn()60 GPTDiskAddOn::GPTDiskAddOn()
61 :
62 BDiskSystemAddOn(EFI_PARTITION_NAME, kDiskSystemFlags)
63 {
64 }
65
66
~GPTDiskAddOn()67 GPTDiskAddOn::~GPTDiskAddOn()
68 {
69 }
70
71
72 status_t
CreatePartitionHandle(BMutablePartition * partition,BPartitionHandle ** _handle)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
CanInitialize(const BMutablePartition * partition)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
ValidateInitialize(const BMutablePartition * partition,BString * name,const char * parameters)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
Initialize(BMutablePartition * partition,const char * name,const char * parameters,BPartitionHandle ** _handle)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