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

Side by Side Diff: src/platform/vboot_reference/utility/cgpt/cgpt_show.c

Issue 2231002: complete 'cgpt show' and refactor for incoming commands. (Closed) Base URL: ssh://git@chromiumos-git/chromeos
Patch Set: Created 10 years, 7 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 | « src/platform/vboot_reference/utility/cgpt/cgpt_repair.c ('k') | no next file » | 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 * Update GPT attribute bits. 5 * Update GPT attribute bits.
6 */ 6 */
7 #include <getopt.h> 7 #include <getopt.h>
8 #include <stdio.h> 8 #include <stdio.h>
9 #include <stdlib.h> 9 #include <stdlib.h>
10 #include "cgpt.h" 10 #include "cgpt.h"
11 #include "cgptlib_internal.h" 11 #include "cgptlib_internal.h"
12 #include "utility.h" 12 #include "utility.h"
13 13
14 /* Integers to store parsed argument. */ 14 /* Integers to store parsed argument. */
15 static int help, raw; 15 static int help, number, verbose;
16 16
17 /* The structure for getopt_long(). When you add/delete any line, please refine 17 /* The structure for getopt_long(). When you add/delete any line, please refine
18 * attribute_comments[] and third parameter of getopt_long() too. */ 18 * attribute_comments[] and third parameter of getopt_long() too. */
19 static struct option show_options[] = { 19 static struct option show_options[] = {
20 {.name = "help", .has_arg = no_argument, .flag = 0, .val = 'h'}, 20 {.name = "help", .has_arg = no_argument, .flag = 0, .val = 'h'},
21 {.name = "raw", .has_arg = no_argument, .flag = 0, .val = 'r'}, 21 {.name = "number", .has_arg = no_argument, .flag = 0, .val = 'n'},
22 {.name = "verbose", .has_arg = no_argument, .flag = 0, .val = 'v'},
22 }; 23 };
23 24
24 /* Extra information than struct option, please update this structure if you 25 /* Extra information than struct option, please update this structure if you
25 * add/remove any line in attribute_options[]. */ 26 * add/remove any line in attribute_options[]. */
26 static struct option_details show_options_details[] = { 27 static struct option_details show_options_details[] = {
27 /* help */ 28 /* help */
28 { .comment = "print this help", 29 { .comment = "print this help",
29 .validator = AssignTrue, 30 .validator = AssignTrue,
30 .valid_range = 0, 31 .valid_range = 0,
31 .parsed = &help}, 32 .parsed = &help},
32 /* raw */ 33 /* number */
33 { .comment = "print raw data (byte-by-byte)", 34 { .comment = "print raw numbers (don't interpret)",
34 .validator = AssignTrue, 35 .validator = AssignTrue,
35 .valid_range = 0, 36 .valid_range = 0,
36 .parsed = &raw}, 37 .parsed = &number},
38 /* verbose */
39 { .comment = "verbose print",
40 .validator = AssignTrue,
41 .valid_range = 0,
42 .parsed = &verbose},
37 }; 43 };
38 44
39 void ShowHelp() { 45 void ShowHelp() {
40 printf("\nUsage: %s show [OPTIONS] device_name\n\n", progname); 46 printf("\nUsage: %s show [OPTIONS] device_name\n\n", progname);
41 ShowOptions(show_options, show_options_details, ARRAY_COUNT(show_options)); 47 ShowOptions(show_options, show_options_details, ARRAY_COUNT(show_options));
42 printf("\n"); 48 printf("\n");
43 } 49 }
44 50
45 /* Generate output like: 51 /* Generate output like:
46 * 52 *
47 * {AB-CD-EF-01} 53 * [AB-CD-EF-01] for group = 1
54 * [ABCD-EF01] for group = 3 (low byte first)
48 * 55 *
49 * Needs (size*3-1+3) bytes of space in 'buf'. 56 * Needs (size*3-1+3) bytes of space in 'buf' (included the tailing '\0').
50 */ 57 */
58 #define BUFFER_SIZE(size) (size *3 - 1 + 3)
51 static short Uint8To2Chars(const uint8_t t) { 59 static short Uint8To2Chars(const uint8_t t) {
52 int h = t >> 4; 60 int h = t >> 4;
53 int l = t & 0xf; 61 int l = t & 0xf;
54 h = (h >= 0xA) ? h - 0xA + 'A' : h + '0'; 62 h = (h >= 0xA) ? h - 0xA + 'A' : h + '0';
55 l = (l >= 0xA) ? l - 0xA + 'A' : l + '0'; 63 l = (l >= 0xA) ? l - 0xA + 'A' : l + '0';
56 return (h << 8) + l; 64 return (h << 8) + l;
57 } 65 }
58 static void RawDump(const uint8_t *memory, const int size, char *buf) { 66 static void RawDump(const uint8_t *memory, const int size,
59 int i; 67 char *buf, int group) {
60 buf[0] = '{'; 68 int i, outlen = 0;
69 buf[outlen++] = '[';
61 for (i = 0; i < size; ++i) { 70 for (i = 0; i < size; ++i) {
62 short c2 = Uint8To2Chars(memory[i]); 71 short c2 = Uint8To2Chars(memory[i]);
63 buf[i * 3 + 1] = c2 >> 8; 72 buf[outlen++] = c2 >> 8;
64 buf[i * 3 + 2] = c2 & 0xff; 73 buf[outlen++] = c2 & 0xff;
65 if (i != (size - 1)) 74 if (i != (size - 1) && ((i + 1) % group) == 0)
66 buf[i * 3 + 3] = '-'; 75 buf[outlen++] = '-';
67 } 76 }
68 buf[i * 3 + 0] = '}'; 77 buf[outlen++] = ']';
69 buf[i * 3 + 1] = '\0'; 78 buf[outlen++] = '\0';
70 } 79 }
71 80
72 /* Parses all options (and validates them), then opens the drive and sets 81 /* Outpur formatters */
73 * corresponding bits in GPT entry. */ 82 #define TITLE_FMT "%10s%10s%8s %s\n"
83 #define GPT_FMT "%10d%10d%8s %s\n"
84 #define GPT_MORE "%10s%10s%8s ", "", "", ""
85 #define PARTITION_FMT "%10d%10d%8d %s\n"
86 #define PARTITION_MORE "%10s%10s%8s %s%s\n", "", "", ""
87
88 static void HeaderDetails(GptHeader *header, const char *indent) {
89 int i;
90
91 printf("%sSig: ", indent);
92 if (number == NOT_INITED) {
93 printf("[");
94 for (i = 0; i < sizeof(header->signature); ++i)
95 printf("%c", header->signature[i]);
96 printf("]");
97 } else {
98 char buf[BUFFER_SIZE(sizeof(header->signature))];
99 RawDump((uint8_t *)header->signature, sizeof(header->signature), buf, 1);
100 printf("%s", buf);
101 }
102 printf("\n");
103
104 printf("%sRev: 0x%08x\n", indent, header->revision);
105 printf("%sSize: %d\n", indent, header->size);
106 printf("%sHeader CRC: 0x%08x\n", indent, header->header_crc32);
107 printf("%sMy LBA: %lld\n", indent, (long long)header->my_lba);
108 printf("%sAlter LBA: %lld\n", indent, (long long)header->alternate_lba);
109 printf("%sFirst LBA: %lld\n", indent, (long long)header->first_usable_lba);
110 printf("%sLast LBA: %lld\n", indent, (long long)header->last_usable_lba);
111
112 { /* For disk guid */
113 char buf[GUID_STRLEN];
114 GuidToStr(&header->disk_uuid, buf);
115 printf("%sDisk UUID: %s\n", indent, buf);
116 }
117
118 printf("%sEntries LBA: %lld\n", indent, (long long)header->entries_lba);
119 printf("%sNumber of entries: %d\n", indent, header->number_of_entries);
120 printf("%sSize of entry: %d\n", indent, header->size_of_entry);
121 printf("%sEntries CRC: 0x%08x\n", indent, header->entries_crc32);
122 }
123
124 /* Resolves human-readable GPT type.
125 * Returns CGPT_OK if found.
126 * Returns CGPT_FAILED if no known type found. */
127 int ResolveType(const Guid *type, char *buf) {
128 struct {
129 Guid type;
130 char *description;
131 } known[] = {
132 {GPT_ENT_TYPE_UNUSED, "Unused partition"},
133 {GPT_ENT_TYPE_EFI, "EFI partition"},
134 {GPT_ENT_TYPE_CHROMEOS_KERNEL, "ChromeOS kernel"},
135 {GPT_ENT_TYPE_CHROMEOS_ROOTFS, "ChromeOS rootfs"},
136 {GPT_ENT_TYPE_CHROMEOS_RESERVED, "ChromeOS reserved"},
137 };
138 int i;
139
140 for (i = 0; i < ARRAY_COUNT(known); ++i) {
141 if (!Memcmp(type, &known[i].type, sizeof(Guid))) {
142 strcpy(buf, known[i].description);
143 return CGPT_OK;
144 }
145 }
146 return CGPT_FAILED;
147 }
148
149 void EntriesDetails(GptData *gpt, const int secondary) {
150 int i;
151
152 for (i = 0; i < GetNumberOfEntries(gpt); ++i) {
153 static Guid unused = GPT_ENT_TYPE_UNUSED;
154 char contents[256];
155
156 GptEntry *entry;
157 entry = GetEntry(gpt, secondary, i);
158
159 if (!Memcmp(&unused, &entry->type, sizeof(unused))) continue;
160
161 if (number == NOT_INITED) {
162 uint8_t label[sizeof(entry->name) * 3 / 2];
163 char type[GUID_STRLEN], unique[GUID_STRLEN];;
164
165 UTF16ToUTF8(entry->name, label);
166 snprintf(contents, sizeof(contents), "Label: \"%s\"", label);
167 printf(PARTITION_FMT, (int)entry->starting_lba,
168 (int)(entry->ending_lba - entry->starting_lba + 1),
169 i, contents);
170 if (CGPT_OK == ResolveType(&entry->type, type)) {
171 printf(PARTITION_MORE, "Type: ", type);
172 } else {
173 GuidToStr(&entry->type, type);
174 printf(PARTITION_MORE, "Type: ", type);
175 }
176 GuidToStr(&entry->unique, unique);
177 printf(PARTITION_MORE, "UUID: ", unique);
178 } else {
179 char label[BUFFER_SIZE(sizeof(entry->name))];
180 char type[GUID_STRLEN], unique[GUID_STRLEN],
181 attributes[BUFFER_SIZE(sizeof(uint64_t))];
182
183 RawDump((void*)entry->name, sizeof(entry->name), label, 2);
184 snprintf(contents, sizeof(contents), "Label: %s", label);
185 printf(PARTITION_FMT, (int)entry->starting_lba,
186 (int)(entry->ending_lba - entry->starting_lba + 1),
187 i, contents);
188 GuidToStr(&entry->type, type);
189 printf(PARTITION_MORE, "Type: ", type);
190 GuidToStr(&entry->unique, unique);
191 printf(PARTITION_MORE, "UUID: ", unique);
192 RawDump((uint8_t*)&entry->attributes, 8, attributes, 4);
193 printf(PARTITION_MORE, "Attr: ", attributes);
194 }
195 }
196 }
197
198 /* Parses all options (and validates them), then opens the drive.
199 * Show GPT information in following order:
200 *
201 * Primary header sector
202 * details (if -v applied)
203 *
204 * Primary table sectors
205 *
206 * 1st partition
207 * details (if -v applied)
208 * :
209 * last partition
210 * details (if -v applied)
211 *
212 * Secondary table sectors
213 *
214 * Secondary header sector
215 * details (if -v applied)
216 */
74 int CgptShow(int argc, char *argv[]) { 217 int CgptShow(int argc, char *argv[]) {
75 struct drive drive; 218 struct drive drive;
76 int i;
77 219
78 /* I know this is NOT the perfect place to put code to make options[] and 220 /* I know this is NOT the perfect place to put code to make options[] and
79 * details[] are synced. But this is the best place we have right now since C 221 * details[] are synced. But this is the best place we have right now since C
80 * preprocessor doesn't know sizeof() for #if directive. */ 222 * preprocessor doesn't know sizeof() for #if directive. */
81 assert(ARRAY_COUNT(show_options) == 223 assert(ARRAY_COUNT(show_options) ==
82 ARRAY_COUNT(show_options_details)); 224 ARRAY_COUNT(show_options_details));
83 225
84 help = raw = NOT_INITED; 226 help = number = NOT_INITED;
85 227
86 if (CGPT_OK != HandleOptions(argc, argv, 228 if (CGPT_OK != HandleOptions(argc, argv,
87 "hr", 229 "hnv",
88 ARRAY_COUNT(show_options), 230 ARRAY_COUNT(show_options),
89 show_options, 231 show_options,
90 show_options_details)) 232 show_options_details))
91 return CGPT_FAILED; 233 return CGPT_FAILED;
92 if (help != NOT_INITED) { 234 if (help != NOT_INITED) {
93 ShowHelp(); 235 ShowHelp();
94 return CGPT_FAILED; 236 return CGPT_FAILED;
95 } 237 }
96 238
97 if (CGPT_OK != OpenDriveInLastArgument(argc, argv, &drive)) 239 if (CGPT_OK != OpenDriveInLastArgument(argc, argv, &drive))
98 return CGPT_FAILED; 240 return CGPT_FAILED;
99 241
100 #define TITLE_FMT "%7s%7s%7s %s\n"
101 #define GPT_FMT "%7d%7d%7s %s\n"
102 #define GPT_MORE "%7s%7s%7s %s\n", "", "", ""
103 #define PARTITION_FMT "%7d%7d%7d %s\n"
104 #define PARTITION_MORE "%7s%7s%7s %s%s\n", "", "", ""
105 printf(TITLE_FMT, "start", "size", "index", "contents"); 242 printf(TITLE_FMT, "start", "size", "index", "contents");
106 printf(GPT_FMT, 0, GPT_PMBR_SECTOR, "", "PMBR"); 243 printf(GPT_FMT, 0, GPT_PMBR_SECTOR, "", "PMBR");
107 printf(GPT_FMT, (int)GPT_PMBR_SECTOR, 244
108 (int)GPT_HEADER_SECTOR, "", "Pri GPT header"); 245 if (drive.gpt.valid_headers & MASK_PRIMARY) {
246 printf(GPT_FMT, (int)GPT_PMBR_SECTOR,
247 (int)GPT_HEADER_SECTOR, "", "Pri GPT header");
248 if (verbose) {
249 GptHeader *header;
250 char indent[64];
251
252 snprintf(indent, sizeof(indent), GPT_MORE);
253 header = (GptHeader*)drive.gpt.primary_header;
254 HeaderDetails(header, indent);
255 }
256 } else {
257 printf(GPT_FMT, (int)GPT_PMBR_SECTOR,
258 (int)GPT_HEADER_SECTOR, "INVALID", "Pri GPT header");
259 }
260
109 printf(GPT_FMT, (int)(GPT_PMBR_SECTOR + GPT_HEADER_SECTOR), 261 printf(GPT_FMT, (int)(GPT_PMBR_SECTOR + GPT_HEADER_SECTOR),
110 (int)GPT_ENTRIES_SECTORS, "", "Pri GPT table"); 262 (int)GPT_ENTRIES_SECTORS,
263 drive.gpt.valid_entries & MASK_PRIMARY ? "" : "INVALID",
264 "Pri GPT table");
111 265
112 for (i = 0; i < GetNumberOfEntries(&drive.gpt); ++i) { 266 if (drive.gpt.valid_entries & MASK_PRIMARY)
113 static Guid zero = {{{0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0}}}}; 267 EntriesDetails(&drive.gpt, PRIMARY);
114 char contents[128];
115 GptEntry *entry;
116 entry = GetEntry(&drive.gpt, PRIMARY, i);
117 268
118 if (!Memcmp(&zero, &entry->type, sizeof(zero))) continue; 269 printf(GPT_FMT, (int)(drive.gpt.drive_sectors - GPT_HEADER_SECTOR -
270 GPT_ENTRIES_SECTORS),
271 (int)GPT_ENTRIES_SECTORS,
272 drive.gpt.valid_entries & MASK_SECONDARY ? "" : "INVALID",
273 "Sec GPT table");
274 /* We show secondary table details if any of following is true.
275 * 1. only secondary is valid.
276 * 2. secondary is not identical to promary.
277 */
278 if ((drive.gpt.valid_entries & MASK_SECONDARY) &&
279 (!(drive.gpt.valid_entries & MASK_PRIMARY) ||
280 Memcmp(drive.gpt.primary_entries, drive.gpt.secondary_entries,
281 TOTAL_ENTRIES_SIZE))) {
282 EntriesDetails(&drive.gpt, SECONDARY);
283 }
119 284
120 if (raw == NOT_INITED) { 285 if (drive.gpt.valid_headers & MASK_SECONDARY)
121 /* TODO(yjlou): support pretty dump */ 286 printf(GPT_FMT, (int)(drive.gpt.drive_sectors - GPT_HEADER_SECTOR),
122 snprintf(contents, sizeof(contents), 287 (int)GPT_HEADER_SECTOR, "", "Sec GPT header");
123 "* Not supported yet *"); 288 else
124 printf(PARTITION_FMT, (int)entry->starting_lba, 289 printf(GPT_FMT, (int)GPT_PMBR_SECTOR,
125 (int)(entry->ending_lba - entry->starting_lba + 1), 290 (int)GPT_HEADER_SECTOR, "INVALID", "Sec GPT header");
126 i, contents); 291 /* We show secondary header if any of following is true:
127 } else { 292 * 1. only secondary is valid.
128 char type[50], unique[50], attributes[26]; 293 * 2. secondary is not synonymous to primary.
294 */
295 if ((drive.gpt.valid_headers & MASK_SECONDARY) &&
296 (!(drive.gpt.valid_headers & MASK_PRIMARY) ||
297 !IsSynonymous((GptHeader*)drive.gpt.primary_header,
298 (GptHeader*)drive.gpt.secondary_header))) {
299 if (verbose) {
300 GptHeader *header;
301 char indent[64];
129 302
130 snprintf(contents, sizeof(contents), 303 snprintf(indent, sizeof(indent), GPT_MORE);
131 "%s", ""); 304 header = (GptHeader*)drive.gpt.secondary_header;
132 printf(PARTITION_FMT, (int)entry->starting_lba, 305 HeaderDetails(header, indent);
133 (int)(entry->ending_lba - entry->starting_lba + 1),
134 i, contents);
135 RawDump((uint8_t*)&entry->type, 16, type);
136 printf(PARTITION_MORE, "type: ", type);
137 RawDump((uint8_t*)&entry->unique, 16, unique);
138 printf(PARTITION_MORE, "uuid: ", unique);
139 RawDump((uint8_t*)&entry->attributes, 8, attributes);
140 printf(PARTITION_MORE, "attr: ", attributes);
141 } 306 }
142 } 307 }
143 308
144 printf(GPT_FMT, (int)(drive.gpt.drive_sectors - GPT_HEADER_SECTOR - 309 CheckValid(&drive);
145 GPT_ENTRIES_SECTORS),
146 (int)GPT_ENTRIES_SECTORS, "", "Sec GPT table");
147 printf(GPT_FMT, (int)(drive.gpt.drive_sectors - GPT_HEADER_SECTOR),
148 (int)GPT_HEADER_SECTOR, "", "Sec GPT header");
149
150 DriveClose(&drive); 310 DriveClose(&drive);
151 311
152 return CGPT_OK; 312 return CGPT_OK;
153 } 313 }
OLDNEW
« no previous file with comments | « src/platform/vboot_reference/utility/cgpt/cgpt_repair.c ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698