blob: a1a018a3d9638b5fce264cda1fbb1b7a5ea6f756 [file] [log] [blame]
Jay Srinivasan250549d2012-02-16 17:40:45 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <string.h>
6
7#include "CgptManager.h"
8
9extern "C" {
10#include "cgpt_params.h"
11}
12
13using std::string;
14
15// We don't use these variables for the libcgpt version.
16const char* progname = "";
17const char* command = "";
Jay Srinivasan5fac7572012-02-23 10:59:01 -080018void (*uuid_generator)(uint8_t* buffer) = NULL;
19
Jay Srinivasan250549d2012-02-16 17:40:45 -080020
21// This file implements the C++ wrapper methods over the C cgpt methods.
22
23CgptManager::CgptManager():
24 is_initialized_(false) {
25}
26
27CgptManager::~CgptManager() {
28}
29
30CgptErrorCode CgptManager::Initialize(const string& device_name) {
31 device_name_ = device_name;
32 is_initialized_ = true;
33 return kCgptSuccess;
34}
35
36CgptErrorCode CgptManager::ClearAll() {
37 if (!is_initialized_)
38 return kCgptNotInitialized;
39
40 CgptCreateParams params;
41 memset(&params, 0, sizeof(params));
42
43 params.drive_name = const_cast<char *>(device_name_.c_str());
44 params.zap = 0;
45
46 int retval = cgpt_create(&params);
47 if (retval != CGPT_OK)
48 return kCgptUnknownError;
49
50 return kCgptSuccess;
51}
52
53CgptErrorCode CgptManager::AddPartition(const string& label,
54 const Guid& partition_type_guid,
55 const Guid& unique_id,
56 uint64_t beginning_offset,
57 uint64_t num_sectors) {
58 if (!is_initialized_)
59 return kCgptNotInitialized;
60
61 CgptAddParams params;
62 memset(&params, 0, sizeof(params));
63
64 params.drive_name = const_cast<char *>(device_name_.c_str());
65 params.label = const_cast<char *>(label.c_str());
66
67 params.type_guid = partition_type_guid;
68 params.set_type = 1;
69
70 params.begin = beginning_offset;
71 params.set_begin = 1;
72
73 params.size = num_sectors;
74 params.set_size = 1;
75
76 if (!IsZero(&unique_id)) {
77 params.unique_guid = unique_id;
78 params.set_unique = 1;
79 }
80
81 int retval = cgpt_add(&params);
82 if (retval != CGPT_OK)
83 return kCgptUnknownError;
84
85 return kCgptSuccess;
86}
87
88CgptErrorCode CgptManager::GetNumNonEmptyPartitions(uint8_t* num_partitions) const {
89 if (!is_initialized_)
90 return kCgptNotInitialized;
91
92 if (!num_partitions)
93 return kCgptInvalidArgument;
94
95 CgptShowParams params;
96 memset(&params, 0, sizeof(params));
97
98 params.drive_name = const_cast<char *>(device_name_.c_str());
99 int retval = cgpt_get_num_non_empty_partitions(&params);
100
101 if (retval != CGPT_OK)
102 return kCgptUnknownError;
103
104 *num_partitions = params.num_partitions;
105 return kCgptSuccess;
106}
107
108CgptErrorCode CgptManager::SetPmbr(uint32_t boot_partition_number,
109 const string& boot_file_name,
110 bool should_create_legacy_partition) {
111 if (!is_initialized_)
112 return kCgptNotInitialized;
113
114 CgptBootParams params;
115 memset(&params, 0, sizeof(params));
116
117 params.drive_name = const_cast<char *>(device_name_.c_str());
118 if (!boot_file_name.empty())
119 params.bootfile = const_cast<char *>(boot_file_name.c_str());
120
121 params.partition = boot_partition_number;
122 params.create_pmbr = should_create_legacy_partition;
123
124 int retval = cgpt_boot(&params);
125 if (retval != CGPT_OK)
126 return kCgptUnknownError;
127
128 return kCgptSuccess;
129}
130
131CgptErrorCode CgptManager::GetPmbrBootPartitionNumber(
132 uint32_t* boot_partition) const {
133 if (!is_initialized_)
134 return kCgptNotInitialized;
135
136 if (!boot_partition)
137 return kCgptInvalidArgument;
138
139 CgptBootParams params;
140 memset(&params, 0, sizeof(params));
141
142 params.drive_name = const_cast<char *>(device_name_.c_str());
143
144 int retval = cgpt_get_boot_partition_number(&params);
145 if (retval != CGPT_OK)
146 return kCgptUnknownError;
147
148 *boot_partition = params.partition;
149 return kCgptSuccess;
150}
151
152CgptErrorCode CgptManager::SetSuccessful(
153 uint32_t partition_number,
154 bool is_successful) {
155 if (!is_initialized_)
156 return kCgptNotInitialized;
157
158 CgptAddParams params;
159 memset(&params, 0, sizeof(params));
160
161 params.drive_name = const_cast<char *>(device_name_.c_str());
162 params.partition = partition_number;
163
164 params.successful = is_successful;
165 params.set_successful = true;
166
167 int retval = cgpt_set_attributes(&params);
168 if (retval != CGPT_OK)
169 return kCgptUnknownError;
170
171 return kCgptSuccess;
172}
173
174CgptErrorCode CgptManager::GetSuccessful(uint32_t partition_number,
175 bool* is_successful) const {
176 if (!is_initialized_)
177 return kCgptNotInitialized;
178
179 if (!is_successful)
180 return kCgptInvalidArgument;
181
182 CgptAddParams params;
183 memset(&params, 0, sizeof(params));
184
185 params.drive_name = const_cast<char *>(device_name_.c_str());
186 params.partition = partition_number;
187
188 int retval = cgpt_get_partition_details(&params);
189 if (retval != CGPT_OK)
190 return kCgptUnknownError;
191
192 *is_successful = params.successful;
193 return kCgptSuccess;
194}
195
196CgptErrorCode CgptManager::SetNumTriesLeft(uint32_t partition_number,
197 int numTries) {
198 if (!is_initialized_)
199 return kCgptNotInitialized;
200
201 CgptAddParams params;
202 memset(&params, 0, sizeof(params));
203
204 params.drive_name = const_cast<char *>(device_name_.c_str());
205 params.partition = partition_number;
206
207 params.tries = numTries;
208 params.set_tries = true;
209
210 int retval = cgpt_set_attributes(&params);
211 if (retval != CGPT_OK)
212 return kCgptUnknownError;
213
214 return kCgptSuccess;
215}
216
217CgptErrorCode CgptManager::GetNumTriesLeft(uint32_t partition_number,
218 int* numTries) const {
219 if (!is_initialized_)
220 return kCgptNotInitialized;
221
222 if (!numTries)
223 return kCgptInvalidArgument;
224
225 CgptAddParams params;
226 memset(&params, 0, sizeof(params));
227
228 params.drive_name = const_cast<char *>(device_name_.c_str());
229 params.partition = partition_number;
230
231 int retval = cgpt_get_partition_details(&params);
232 if (retval != CGPT_OK)
233 return kCgptUnknownError;
234
235 *numTries = params.tries;
236 return kCgptSuccess;
237}
238
239CgptErrorCode CgptManager::SetPriority(uint32_t partition_number,
240 uint8_t priority) {
241 if (!is_initialized_)
242 return kCgptNotInitialized;
243
244 CgptAddParams params;
245 memset(&params, 0, sizeof(params));
246
247 params.drive_name = const_cast<char *>(device_name_.c_str());
248 params.partition = partition_number;
249
250 params.priority = priority;
251 params.set_priority = true;
252
253 int retval = cgpt_set_attributes(&params);
254 if (retval != CGPT_OK)
255 return kCgptUnknownError;
256
257 return kCgptSuccess;
258}
259
260CgptErrorCode CgptManager::GetPriority(uint32_t partition_number,
261 uint8_t* priority) const {
262 if (!is_initialized_)
263 return kCgptNotInitialized;
264
265 if (!priority)
266 return kCgptInvalidArgument;
267
268 CgptAddParams params;
269 memset(&params, 0, sizeof(params));
270
271 params.drive_name = const_cast<char *>(device_name_.c_str());
272 params.partition = partition_number;
273
274 int retval = cgpt_get_partition_details(&params);
275 if (retval != CGPT_OK)
276 return kCgptUnknownError;
277
278 *priority = params.priority;
279 return kCgptSuccess;
280}
281
282CgptErrorCode CgptManager::GetBeginningOffset(uint32_t partition_number,
283 uint64_t* offset) const {
284 if (!is_initialized_)
285 return kCgptNotInitialized;
286
287 if (!offset)
288 return kCgptInvalidArgument;
289
290 CgptAddParams params;
291 memset(&params, 0, sizeof(params));
292
293 params.drive_name = const_cast<char *>(device_name_.c_str());
294 params.partition = partition_number;
295
296 int retval = cgpt_get_partition_details(&params);
297 if (retval != CGPT_OK)
298 return kCgptUnknownError;
299
300 *offset = params.begin;
301 return kCgptSuccess;
302}
303
304CgptErrorCode CgptManager::GetNumSectors(uint32_t partition_number,
305 uint64_t* num_sectors) const {
306 if (!is_initialized_)
307 return kCgptNotInitialized;
308
309 if (!num_sectors)
310 return kCgptInvalidArgument;
311
312 CgptAddParams params;
313 memset(&params, 0, sizeof(params));
314
315 params.drive_name = const_cast<char *>(device_name_.c_str());
316 params.partition = partition_number;
317
318 int retval = cgpt_get_partition_details(&params);
319 if (retval != CGPT_OK)
320 return kCgptUnknownError;
321
322 *num_sectors = params.size;
323 return kCgptSuccess;
324}
325
326CgptErrorCode CgptManager::GetPartitionTypeId(uint32_t partition_number,
327 Guid* type_id) const {
328 if (!is_initialized_)
329 return kCgptNotInitialized;
330
331 if (!type_id)
332 return kCgptInvalidArgument;
333
334 CgptAddParams params;
335 memset(&params, 0, sizeof(params));
336
337 params.drive_name = const_cast<char *>(device_name_.c_str());
338 params.partition = partition_number;
339
340 int retval = cgpt_get_partition_details(&params);
341 if (retval != CGPT_OK)
342 return kCgptUnknownError;
343
344 *type_id = params.type_guid;
345 return kCgptSuccess;
346}
347
348CgptErrorCode CgptManager::GetPartitionUniqueId(uint32_t partition_number,
349 Guid* unique_id) const {
350 if (!is_initialized_)
351 return kCgptNotInitialized;
352
353 if (!unique_id)
354 return kCgptInvalidArgument;
355
356 CgptAddParams params;
357 memset(&params, 0, sizeof(params));
358
359 params.drive_name = const_cast<char *>(device_name_.c_str());
360 params.partition = partition_number;
361
362 int retval = cgpt_get_partition_details(&params);
363 if (retval != CGPT_OK)
364 return kCgptUnknownError;
365
366 *unique_id = params.unique_guid;
367 return kCgptSuccess;
368}
369
370CgptErrorCode CgptManager::GetPartitionNumberByUniqueId(
371 const Guid& unique_id,
372 uint32_t* partition_number) const {
373 if (!is_initialized_)
374 return kCgptNotInitialized;
375
376 if (!partition_number)
377 return kCgptInvalidArgument;
378
379 CgptAddParams params;
380 memset(&params, 0, sizeof(params));
381
382 params.drive_name = const_cast<char *>(device_name_.c_str());
383 params.unique_guid = unique_id;
384 params.set_unique = 1;
385
386 int retval = cgpt_get_partition_details(&params);
387 if (retval != CGPT_OK)
388 return kCgptUnknownError;
389
390 *partition_number = params.partition;
391 return kCgptSuccess;
392}
393
394CgptErrorCode CgptManager::SetHighestPriority(uint32_t partition_number,
395 uint8_t highest_priority) {
396 if (!is_initialized_)
397 return kCgptNotInitialized;
398
399 CgptPrioritizeParams params;
400 memset(&params, 0, sizeof(params));
401
402 params.drive_name = const_cast<char *>(device_name_.c_str());
403 params.set_partition = partition_number;
404 params.max_priority = highest_priority;
405
406 int retval = cgpt_prioritize(&params);
407 if (retval != CGPT_OK)
408 return kCgptUnknownError;
409
410 return kCgptSuccess;
411}
412
413CgptErrorCode CgptManager::SetHighestPriority(uint32_t partition_number) {
414 // The internal implementation in cgpt_prioritize automatically computes the
415 // right priority number if we supply 0 for the highest_priority argument.
416 return SetHighestPriority(partition_number, 0);
417}
418
419CgptErrorCode CgptManager::Validate() {
420 if (!is_initialized_)
421 return kCgptNotInitialized;
422
423 uint8_t num_partitions;
424
425 // GetNumNonEmptyPartitions does the check for GptSanityCheck.
426 // so call it (ignore the num_partitions result) and just return
427 // its success/failure result.
428 return GetNumNonEmptyPartitions(&num_partitions);
429}