Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(175)

Side by Side Diff: src/platform/vboot_reference/utility/gbb_utility.cc

Issue 2549001: Refine gbb_utility for better maintainance (Closed) Base URL: ssh://gitrw.chromium.org/chromiumos
Patch Set: fix lint errors (extra space) Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/platform/vboot_reference/utility/include/gbb_utility.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 // Utility for manipulating Google Binary Block (GBB) 5 // Utility for manipulating Google Binary Block (GBB)
6 // 6 //
7 7
8 #include "gbb_utility.h" 8 #include "gbb_utility.h"
9 9
10 #include <assert.h> 10 #include <assert.h>
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 last_found_pos++; // for next iteration 148 last_found_pos++; // for next iteration
149 } 149 }
150 150
151 return found_signatures; 151 return found_signatures;
152 } 152 }
153 153
154 // uility function for load_gbb_header to check property range 154 // uility function for load_gbb_header to check property range
155 static bool check_property_range(uint32_t off, uint32_t sz, 155 static bool check_property_range(uint32_t off, uint32_t sz,
156 uint32_t hdr_sz, uint32_t max_sz, 156 uint32_t hdr_sz, uint32_t max_sz,
157 const char *prop_name, bool verbose) { 157 const char *prop_name, bool verbose) {
158 // for backward compatibility, we allow zero entry here.
159 if (off == 0 && sz == 0) {
160 if (verbose)
161 fprintf(stderr, " warning: property %s is EMPTY.\n", prop_name);
162 return true;
163 }
164
158 if (off + sz > max_sz) { 165 if (off + sz > max_sz) {
159 if (verbose) 166 if (verbose)
160 fprintf(stderr, " error: property %s exceed GBB.\n", prop_name); 167 fprintf(stderr, " error: property %s exceed GBB.\n", prop_name);
161 return false; 168 return false;
162 } 169 }
163 170
164 if (off < hdr_sz) { 171 if (off < hdr_sz) {
165 if (verbose) 172 if (verbose)
166 fprintf(stderr, " error: property %s overlap GBB header.\n", prop_name); 173 fprintf(stderr, " error: property %s overlap GBB header.\n", prop_name);
167 return false; 174 return false;
(...skipping 30 matching lines...) Expand all
198 return false; 205 return false;
199 } 206 }
200 207
201 if (h.header_size < GBB_HEADER_SIZE) { 208 if (h.header_size < GBB_HEADER_SIZE) {
202 if (verbose) 209 if (verbose)
203 fprintf(stderr, " error: incompatible header size (%d < %d)\n", 210 fprintf(stderr, " error: incompatible header size (%d < %d)\n",
204 h.header_size, GBB_HEADER_SIZE); 211 h.header_size, GBB_HEADER_SIZE);
205 return false; 212 return false;
206 } 213 }
207 214
208 // verify location of properties 215 // verify properties
209 if (!check_property_range(h.hwid_offset, h.hwid_size, 216 for (int i = 0; i < PROP_RANGE; i++) {
210 h.header_size, block_size, "hwid", verbose) || 217 uint32_t off, size;
211 !check_property_range(h.rootkey_offset, h.rootkey_size, 218 const char *name;
212 h.header_size, block_size, "rootkey", verbose) || 219
213 !check_property_range(h.bmpfv_offset, h.bmpfv_size, 220 if (!find_property(static_cast<PROPINDEX>(i),
214 h.header_size, block_size, "bmpfv", verbose)) { 221 &off, &size, &name)) {
215 return false; 222 assert(!"invalid property.");
223 return false;
224 }
225
226 if (!check_property_range(off, size,
227 h.header_size, block_size, name, verbose))
228 return false;
216 } 229 }
217 230
218 return true; 231 return true;
219 } 232 }
220 233
221 bool GoogleBinaryBlockUtil::find_property(PROPINDEX i, 234 bool GoogleBinaryBlockUtil::find_property(PROPINDEX i,
222 uint32_t *poffset, 235 uint32_t *poffset,
223 uint32_t *psize) const { 236 uint32_t *psize,
237 const char** pname) const {
224 switch (i) { 238 switch (i) {
225 case PROP_HWID: 239 case PROP_HWID:
226 *poffset = header_.hwid_offset; 240 *poffset = header_.hwid_offset;
227 *psize = header_.hwid_size; 241 *psize = header_.hwid_size;
242 if (pname)
243 *pname = "hardware_id";
228 break; 244 break;
229 245
230 case PROP_ROOTKEY: 246 case PROP_ROOTKEY:
231 *poffset = header_.rootkey_offset; 247 *poffset = header_.rootkey_offset;
232 *psize = header_.rootkey_size; 248 *psize = header_.rootkey_size;
249 if (pname)
250 *pname = "root_key";
233 break; 251 break;
234 252
235 case PROP_BMPFV: 253 case PROP_BMPFV:
236 *poffset = header_.bmpfv_offset; 254 *poffset = header_.bmpfv_offset;
237 *psize = header_.bmpfv_size; 255 *psize = header_.bmpfv_size;
256 if (pname)
257 *pname = "bmp_fv";
238 break; 258 break;
239 259
240 default: 260 default:
241 assert(!"invalid property index."); 261 assert(!"invalid property index.");
242 return false; 262 return false;
243 } 263 }
244 264
245 return true; 265 return true;
246 } 266 }
247 267
248 bool GoogleBinaryBlockUtil::set_property(PROPINDEX i, const string &value) { 268 bool GoogleBinaryBlockUtil::set_property(PROPINDEX i, const string &value) {
249 uint32_t prop_size; 269 uint32_t prop_size;
250 uint32_t prop_offset; 270 uint32_t prop_offset;
271 const char *prop_name;
251 272
252 assert(is_valid_gbb); 273 assert(is_valid_gbb);
253 274
254 if (!find_property(i, &prop_offset, &prop_size)) { 275 if (!find_property(i, &prop_offset, &prop_size, &prop_name)) {
255 if (verbose) 276 if (verbose)
256 fprintf(stderr, " internal error: unknown property (%d).\n", 277 fprintf(stderr, " internal error: unknown property (%d).\n",
257 static_cast<int>(i)); 278 static_cast<int>(i));
258 return false; 279 return false;
259 } 280 }
260 281
261 if (prop_size < value.size()) { 282 if (prop_size < value.size()) {
262 if (verbose) 283 if (verbose)
263 fprintf(stderr, " error: value size (%zu) exceed capacity (%u).\n", 284 fprintf(stderr, " error: value size (%zu) exceed property capacity "
264 value.size(), prop_size); 285 "(%u): %s\n", value.size(), prop_size, prop_name);
265 return false; 286 return false;
266 } 287 }
267 288
268 if (i == PROP_HWID && prop_size == value.size()) { 289 if (i == PROP_HWID && prop_size == value.size()) {
269 // special case: this is NUL-terminated so it's better to keep one more \0 290 // special case: this is NUL-terminated so it's better to keep one more \0
270 if (verbose) 291 if (verbose)
271 fprintf(stderr, "error: NUL-terminated string exceed capacity (%d)\n", 292 fprintf(stderr, "error: NUL-terminated string exceed capacity (%d): %s\n",
272 prop_size); 293 prop_size, prop_name);
273 return false; 294 return false;
274 } 295 }
275 296
276 string::iterator dest = file_content_.begin() + header_offset_ + prop_offset; 297 string::iterator dest = file_content_.begin() + header_offset_ + prop_offset;
277 file_content_.replace(dest, dest+prop_size, prop_size, '\0'); // wipe first 298 file_content_.replace(dest, dest+prop_size, prop_size, '\0'); // wipe first
278 std::copy(value.begin(), value.end(), dest); 299 std::copy(value.begin(), value.end(), dest);
279 300
280 return true; 301 return true;
281 } 302 }
282 303
283 string GoogleBinaryBlockUtil::get_property(PROPINDEX i) const { 304 string GoogleBinaryBlockUtil::get_property(PROPINDEX i) const {
284 uint32_t prop_size; 305 uint32_t prop_size;
285 uint32_t prop_offset; 306 uint32_t prop_offset;
307 const char *prop_name;
286 308
287 assert(is_valid_gbb); 309 assert(is_valid_gbb);
288 310
289 if (!find_property(i, &prop_offset, &prop_size)) { 311 if (!find_property(i, &prop_offset, &prop_size, &prop_name)) {
290 if (verbose) 312 if (verbose)
291 fprintf(stderr, " internal error: unknown property (%d).\n", 313 fprintf(stderr, " internal error: unknown property (%d).\n",
292 static_cast<int>(i)); 314 static_cast<int>(i));
293 return ""; 315 return "";
294 } 316 }
295 317
318 // check range again to allow empty value (for compatbility)
319 if (prop_offset == 0 && prop_size == 0) {
320 if (verbose)
321 fprintf(stderr, " warning: empty property (%d): %s.\n",
322 static_cast<int>(i), prop_name);
323 return "";
324 }
325
296 string::const_iterator dest = file_content_.begin() + 326 string::const_iterator dest = file_content_.begin() +
297 header_offset_ + prop_offset; 327 header_offset_ + prop_offset;
298 return string(dest, dest + prop_size); 328 return string(dest, dest + prop_size);
299 } 329 }
300 330
331 string GoogleBinaryBlockUtil::get_property_name(PROPINDEX i) const {
332 uint32_t unused_off, unused_size;
333 const char *prop_name;
334
335 if (!find_property(i, &unused_off, &unused_size, &prop_name)) {
336 if (verbose)
337 fprintf(stderr, " internal error: unknown property (%d).\n",
338 static_cast<int>(i));
339 assert(!"invalid property index.");
340 return "";
341 }
342
343 return prop_name;
344 }
345
301 bool GoogleBinaryBlockUtil::set_hwid(const char *hwid) { 346 bool GoogleBinaryBlockUtil::set_hwid(const char *hwid) {
302 return set_property(PROP_HWID, hwid); 347 return set_property(PROP_HWID, hwid);
303 } 348 }
304 349
305 bool GoogleBinaryBlockUtil::set_rootkey(const std::string &value) { 350 bool GoogleBinaryBlockUtil::set_rootkey(const std::string &value) {
306 return set_property(PROP_ROOTKEY, value); 351 return set_property(PROP_ROOTKEY, value);
307 } 352 }
308 353
309 bool GoogleBinaryBlockUtil::set_bmpfv(const string &value) { 354 bool GoogleBinaryBlockUtil::set_bmpfv(const string &value) {
310 return set_property(PROP_BMPFV, value); 355 return set_property(PROP_BMPFV, value);
311 } 356 }
312 357
313 } // namespace vboot_reference 358 } // namespace vboot_reference
314 359
315 #ifdef WITH_UTIL_MAIN 360 #ifdef WITH_UTIL_MAIN
316 361
317 /////////////////////////////////////////////////////////////////////// 362 ///////////////////////////////////////////////////////////////////////
318 // command line utilities 363 // command line utilities
319 364
365 #include <map>
366
367 using vboot_reference::GoogleBinaryBlockUtil;
368
320 // utility function: provide usage of this utility and exit. 369 // utility function: provide usage of this utility and exit.
321 static void usagehelp_exit(const char *prog_name) { 370 static void usagehelp_exit(const char *prog_name) {
322 printf( 371 printf(
323 "Utility to manage Google Binary Block (GBB)\n" 372 "Utility to manage Google Binary Block (GBB)\n"
324 "Usage: %s [-g|-s] [OPTIONS] bios_file [output_file]\n\n" 373 "Usage: %s [-g|-s] [OPTIONS] bios_file [output_file]\n"
325 "-g, --get \tGet (read) from bios_file, " 374 "\n"
375 "GET MODE:\n"
376 "-g, --get (default)\tGet (read) from bios_file, "
326 "with following options:\n" 377 "with following options:\n"
327 " --hwid \tReport hardware id (default).\n" 378 " --hwid \tReport hardware id (default).\n"
328 " -k, --rootkey=FILE \tFile name to export Root Key.\n" 379 " -k, --rootkey=FILE \tFile name to export Root Key.\n"
329 " -b, --bmpfv=FILE \tFile name to export Bitmap FV.\n" 380 " -b, --bmpfv=FILE \tFile name to export Bitmap FV.\n"
330 "\n" 381 "\n"
382 "SET MODE:\n"
331 "-s, --set \tSet (write) to bios_file, " 383 "-s, --set \tSet (write) to bios_file, "
332 "with following options:\n" 384 "with following options:\n"
385 " -o, --output=FILE \tNew file name for ouptput.\n"
333 " -i, --hwid=HWID \tThe new hardware id to be changed.\n" 386 " -i, --hwid=HWID \tThe new hardware id to be changed.\n"
334 " -k, --rootkey=FILE \tFile name of new Root Key.\n" 387 " -k, --rootkey=FILE \tFile name of new Root Key.\n"
335 " -b, --bmpfv=FILE \tFile name of new Bitmap FV\n" 388 " -b, --bmpfv=FILE \tFile name of new Bitmap FV.\n"
336 "\n" 389 "\n"
337 " SAMPLE:\n" 390 "SAMPLE:\n"
338 " %s -g bios.bin\n" 391 " %s -g bios.bin\n"
339 " %s --set --hwid='New Model' -k key.bin bios.bin newbios.bin\n" 392 " %s --set --hwid='New Model' -k key.bin bios.bin newbios.bin\n"
340 , prog_name, prog_name, prog_name); 393 , prog_name, prog_name, prog_name);
341 exit(1); 394 exit(1);
342 } 395 }
343 396
344 // utility function: export a property from GBB to given file. 397 // utility function: export a property from GBB to given file.
398 // if filename was empty, export to console (screen).
345 // return true on success, otherwise false. 399 // return true on success, otherwise false.
346 static bool export_property_to_file(const string &filename, 400 static bool export_property(GoogleBinaryBlockUtil::PROPINDEX idx,
347 const char *name, const string &value) { 401 const string &filename,
348 assert(!filename.empty()); 402 const GoogleBinaryBlockUtil &util) {
349 const char *fn = filename.c_str(); 403 string prop_name = util.get_property_name(idx),
404 value = util.get_property(idx);
405 const char *name = prop_name.c_str();
350 406
351 if (!write_nonempty_file(fn, value)) { 407 if (filename.empty()) {
352 fprintf(stderr, "error: failed to export %s to file: %s\n", name, fn); 408 // write to console
353 return false; 409 printf("%s: %s\n", name, value.c_str());
410 } else {
411 const char *fn = filename.c_str();
412
413 if (!write_nonempty_file(fn, value)) {
414 fprintf(stderr, "error: failed to export %s to file: %s\n", name, fn);
415 return false;
416 }
417 printf(" - exported %s to file: %s\n", name, fn);
354 } 418 }
355 419
356 printf(" - exported %s to file: %s\n", name, fn);
357 return true; 420 return true;
358 } 421 }
359 422
360 // utility function: import a property to GBB by given file. 423 // utility function: import a property to GBB by given source (file or string).
361 // return true on success, otherwise false. 424 // return true on success, otherwise false.
362 // is succesfully imported into GBB. 425 // is succesfully imported into GBB.
363 static bool import_property_from_file( 426 static bool import_property(
364 const string &filename, const char *name, 427 GoogleBinaryBlockUtil::PROPINDEX idx, const string &source,
365 bool (vboot_reference::GoogleBinaryBlockUtil::*setter)(const string &value), 428 bool source_as_file, GoogleBinaryBlockUtil *putil) {
366 vboot_reference::GoogleBinaryBlockUtil *putil) { 429 assert(!source.empty());
367 assert(!filename.empty()); 430 string prop_name = putil->get_property_name(idx);
368 431
369 printf(" - import %s from %s: ", name, filename.c_str()); 432 if (source_as_file) {
370 string v = read_nonempty_file(filename.c_str()); 433 printf(" - import %s from %s: ", prop_name.c_str(), source.c_str());
371 if (v.empty()) { 434 string v = read_nonempty_file(source.c_str());
372 printf("invalid file.\n"); 435 if (v.empty()) {
373 return false; 436 printf("invalid file.\n");
437 return false;
438 }
439 if (!putil->set_property(idx, v)) {
440 printf("invalid content.\n");
441 return false;
442 }
443 printf("success.\n");
444 } else {
445 // source as string
446 string old_value = putil->get_property(idx);
447 bool result = putil->set_property(idx, source);
448 printf(" - %s changed from '%s' to '%s': %s\n",
449 prop_name.c_str(), old_value.c_str(), source.c_str(),
450 result ? "success" : "failed");
451 if (!result)
452 return false;
374 } 453 }
375 454
376 if (!(putil->*setter)(v)) {
377 printf("invalid content.\n");
378 return false;
379 }
380
381 printf("success.\n");
382 return true; 455 return true;
383 } 456 }
384 457
385 /////////////////////////////////////////////////////////////////////// 458 ///////////////////////////////////////////////////////////////////////
386 // main 459 // main
387 460
388 int main(int argc, char *argv[]) { 461 int main(int argc, char *argv[]) {
389 const char *myname = argv[0]; 462 const char *myname = argv[0];
390 int err_stage = 0; // an indicator for error exits 463 int err_stage = 0; // an indicator for error exits
391 464
465 // small parameter helper class
466 class OptPropertyMap: public
467 std::map<GoogleBinaryBlockUtil::PROPINDEX, string> {
468 public:
469 bool set_new_value(GoogleBinaryBlockUtil::PROPINDEX id, const string &v) {
470 if (find(id) != end())
471 return false;
472 (*this)[id] = v;
473 return true;
474 }
475 };
476 OptPropertyMap opt_props;
477
392 struct GBBUtilOptions { 478 struct GBBUtilOptions {
393 bool get_mode, set_mode; 479 bool get_mode, set_mode;
394 bool use_hwid, use_rootkey, use_bmpfv; 480 string input_fn, output_fn;
395 string hwid, rootkey_fn, bmpfv_fn;
396 } myopts; 481 } myopts;
397
398 myopts.get_mode = myopts.set_mode = false; 482 myopts.get_mode = myopts.set_mode = false;
399 myopts.use_hwid = myopts.use_rootkey = myopts.use_bmpfv = false;
400 483
401 // snippets for getopt_long 484 // snippets for getopt_long
402 int option_index, opt; 485 int option_index, opt;
403 static struct option long_options[] = { 486 static struct option long_options[] = {
404 {"get", 0, NULL, 'g' }, 487 {"get", 0, NULL, 'g' },
405 {"set", 0, NULL, 's' }, 488 {"set", 0, NULL, 's' },
406 {"hwid", 2, NULL, 'i' }, 489 {"output", 1, NULL, 'o' },
490 {"hwid", 2, NULL, 'i' },
407 {"rootkey", 1, NULL, 'k' }, 491 {"rootkey", 1, NULL, 'k' },
408 {"bmpfv", 1, NULL, 'b' }, 492 {"bmpfv", 1, NULL, 'b' },
409 { NULL, 0, NULL, 0 }, 493 { NULL, 0, NULL, 0 },
410 }; 494 };
411 int opt_props = 0; // number of assigned properties.
412 495
413 // parse command line options 496 // parse command line options
414 while ((opt = getopt_long(argc, argv, "gsi:k:b:", 497 while ((opt = getopt_long(argc, argv, "gso:i:k:b:",
415 long_options, &option_index)) >= 0) { 498 long_options, &option_index)) >= 0) {
416 switch (opt) { 499 switch (opt) {
417 case 'g': 500 case 'g':
418 myopts.get_mode = true; 501 myopts.get_mode = true;
419 break; 502 break;
420 503
421 case 's': 504 case 's':
422 myopts.set_mode = true; 505 myopts.set_mode = true;
423 break; 506 break;
424 507
508 case 'o':
509 myopts.output_fn = optarg;
510 break;
511
425 case 'i': 512 case 'i':
426 opt_props++; 513 if (!opt_props.set_new_value(
427 myopts.use_hwid = true; 514 GoogleBinaryBlockUtil::PROP_HWID, optarg ? optarg : ""))
428 if (optarg) 515 usagehelp_exit(myname);
429 myopts.hwid = optarg;
430 break; 516 break;
431 517
432 case 'k': 518 case 'k':
433 opt_props++; 519 if (!opt_props.set_new_value(
434 myopts.use_rootkey = true; 520 GoogleBinaryBlockUtil::PROP_ROOTKEY, optarg))
435 myopts.rootkey_fn = optarg; 521 usagehelp_exit(myname);
436 break; 522 break;
437 523
438 case 'b': 524 case 'b':
439 opt_props++; 525 if (!opt_props.set_new_value(
440 myopts.use_bmpfv = true; 526 GoogleBinaryBlockUtil::PROP_BMPFV, optarg))
441 myopts.bmpfv_fn = optarg; 527 usagehelp_exit(myname);
442 break; 528 break;
443 529
444 default: 530 default:
445 case '?': 531 case '?':
446 usagehelp_exit(myname); 532 usagehelp_exit(myname);
447 break; 533 break;
448 } 534 }
449 } 535 }
450 argc -= optind; 536 argc -= optind;
451 argv += optind; 537 argv += optind;
452 538
453 // check parameters configuration 539 // adjust non-dashed parameters
454 if (!(argc == 1 || (myopts.set_mode && argc == 2))) 540 if (myopts.output_fn.empty() && argc == 2) {
541 myopts.output_fn = argv[1];
542 argc--;
543 }
544
545 // currently, the only parameter is 'input file'.
546 if (argc == 1) {
547 myopts.input_fn = argv[0];
548 } else {
455 usagehelp_exit(myname); 549 usagehelp_exit(myname);
550 }
456 551
457 // stage: parameter parsing 552 // stage: complete parameter parsing and checking
458 err_stage++; 553 err_stage++;
459 if (myopts.get_mode == myopts.set_mode) { 554 if (myopts.get_mode == myopts.set_mode) {
460 printf("error: please assign either get or set mode.\n"); 555 if (myopts.get_mode) {
556 printf("error: please assign either get or set mode.\n");
557 return err_stage;
558 } else {
559 // enter 'get' mode by default, if not assigned.
560 myopts.get_mode = true;
561 }
562 }
563 if (myopts.get_mode && !myopts.output_fn.empty()) {
564 printf("error: get-mode does not create output files.\n");
461 return err_stage; 565 return err_stage;
462 } 566 }
463 567
464 // stage: load image files 568 // stage: load image files
465 err_stage++; 569 err_stage++;
466 vboot_reference::GoogleBinaryBlockUtil util; 570 GoogleBinaryBlockUtil util;
467 const char *input_filename = argv[0],
468 *output_filename= (argc > 1) ? argv[1] : argv[0];
469 571
470 if (!util.load_from_file(input_filename)) { 572 assert(!myopts.input_fn.empty());
471 printf("error: cannot load valid BIOS file: %s\n", input_filename); 573 if (!util.load_from_file(myopts.input_fn.c_str())) {
574 printf("error: cannot load valid BIOS file: %s\n", myopts.input_fn.c_str());
472 return err_stage; 575 return err_stage;
473 } 576 }
474 577
475 // stage: processing by mode 578 // stage: processing by mode
476 err_stage++; 579 err_stage++;
477 if (myopts.get_mode) { 580 if (myopts.get_mode) {
478 // get mode 581 // get mode
479 if (opt_props < 1) // enable hwid by default 582 if (opt_props.empty()) // enable hwid by default
480 myopts.use_hwid = true; 583 opt_props.set_new_value(GoogleBinaryBlockUtil::PROP_HWID, "");
481 584
482 if (myopts.use_hwid) 585 for (OptPropertyMap::const_iterator i = opt_props.begin();
483 printf("Hardware ID: %s\n", util.get_hwid().c_str()); 586 i != opt_props.end();
484 if (myopts.use_rootkey) 587 i++) {
485 export_property_to_file(myopts.rootkey_fn, "rootkey", util.get_rootkey()); 588 export_property(i->first, i->second, util);
486 if (myopts.use_bmpfv) 589 }
487 export_property_to_file(myopts.bmpfv_fn, "bmpfv", util.get_bmpfv()); 590
488 } else { 591 } else {
489 // set mode 592 // set mode
490 assert(myopts.set_mode); 593 assert(myopts.set_mode);
491 if (opt_props < 1) { 594
595 if (opt_props.empty()) {
492 printf("nothing to change. abort.\n"); 596 printf("nothing to change. abort.\n");
493 return err_stage; 597 return err_stage;
494 } 598 }
495 599
496 // HWID does not come from file, so update it direcly here. 600 for (OptPropertyMap::const_iterator i = opt_props.begin();
497 if (myopts.use_hwid) { 601 i != opt_props.end();
498 string old_hwid = util.get_hwid(); 602 i++) {
499 if (!util.set_hwid(myopts.hwid.c_str())) { 603 bool source_as_file = true;
500 printf("error: inproper hardware id: %s\n", 604
501 myopts.hwid.c_str()); 605 // the hwid command line parameter was a simple string.
606 if (i->first == GoogleBinaryBlockUtil::PROP_HWID)
607 source_as_file = false;
608
609 if (!import_property(i->first, i->second, source_as_file, &util)) {
610 printf("error: cannot set properties. abort.\n");
502 return err_stage; 611 return err_stage;
503 } 612 }
504 printf(" - Hardware id changed: %s -> %s.\n",
505 old_hwid.c_str(), util.get_hwid().c_str());
506 }
507
508 // import other properties from file
509 if ((myopts.use_rootkey &&
510 !import_property_from_file(myopts.rootkey_fn, "rootkey",
511 &vboot_reference::GoogleBinaryBlockUtil::set_rootkey, &util)) ||
512 (myopts.use_bmpfv &&
513 !import_property_from_file(myopts.bmpfv_fn, "bmpfv",
514 &vboot_reference::GoogleBinaryBlockUtil::set_bmpfv, &util))) {
515 printf("error: cannot set new properties. abort.\n");
516 return err_stage;
517 } 613 }
518 614
519 // stage: write output 615 // stage: write output
520 err_stage++; 616 err_stage++;
521 if (!util.save_to_file(output_filename)) { 617
522 printf("error: cannot save to file: %s\n", output_filename); 618 // use input filename (overwrite) by default
619 if (myopts.output_fn.empty())
620 myopts.output_fn = myopts.input_fn;
621
622 assert(!myopts.output_fn.empty());
623 if (!util.save_to_file(myopts.output_fn.c_str())) {
624 printf("error: cannot save to file: %s\n", myopts.output_fn.c_str());
523 return err_stage; 625 return err_stage;
524 } else { 626 } else {
525 printf("successfully saved new image to: %s\n", output_filename); 627 printf("successfully saved new image to: %s\n", myopts.output_fn.c_str());
526 } 628 }
527 } 629 }
528 630
529 return 0; 631 return 0;
530 } 632 }
531 633
532 #endif // WITH_UTIL_MAIN 634 #endif // WITH_UTIL_MAIN
533 635
OLDNEW
« no previous file with comments | « no previous file | src/platform/vboot_reference/utility/include/gbb_utility.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698