OLD | NEW |
---|---|
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 * Show GPT details. | 5 * Show GPT details. |
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" |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
81 buf[outlen++] = '\0'; | 81 buf[outlen++] = '\0'; |
82 } | 82 } |
83 | 83 |
84 /* Outpur formatters */ | 84 /* Outpur formatters */ |
85 #define TITLE_FMT "%10s%10s%8s %s\n" | 85 #define TITLE_FMT "%10s%10s%8s %s\n" |
86 #define GPT_FMT "%10d%10d%8s %s\n" | 86 #define GPT_FMT "%10d%10d%8s %s\n" |
87 #define GPT_MORE "%10s%10s%8s ", "", "", "" | 87 #define GPT_MORE "%10s%10s%8s ", "", "", "" |
88 #define PARTITION_FMT "%10d%10d%8d %s\n" | 88 #define PARTITION_FMT "%10d%10d%8d %s\n" |
89 #define PARTITION_MORE "%10s%10s%8s %s%s\n", "", "", "" | 89 #define PARTITION_MORE "%10s%10s%8s %s%s\n", "", "", "" |
90 | 90 |
91 static void HeaderDetails(GptHeader *header, const char *indent) { | 91 static void HeaderDetails(GptHeader *header, const char *indent, int raw) { |
92 int i; | 92 int i; |
93 | 93 |
94 printf("%sSig: ", indent); | 94 printf("%sSig: ", indent); |
95 if (number == NOT_INITED) { | 95 if (raw == NOT_INITED) { |
96 printf("["); | 96 printf("["); |
97 for (i = 0; i < sizeof(header->signature); ++i) | 97 for (i = 0; i < sizeof(header->signature); ++i) |
98 printf("%c", header->signature[i]); | 98 printf("%c", header->signature[i]); |
99 printf("]"); | 99 printf("]"); |
100 } else { | 100 } else { |
101 char buf[BUFFER_SIZE(sizeof(header->signature))]; | 101 char buf[BUFFER_SIZE(sizeof(header->signature))]; |
102 RawDump((uint8_t *)header->signature, sizeof(header->signature), buf, 1); | 102 RawDump((uint8_t *)header->signature, sizeof(header->signature), buf, 1); |
103 printf("%s", buf); | 103 printf("%s", buf); |
104 } | 104 } |
105 printf("\n"); | 105 printf("\n"); |
(...skipping 10 matching lines...) Expand all Loading... | |
116 GuidToStr(&header->disk_uuid, buf); | 116 GuidToStr(&header->disk_uuid, buf); |
117 printf("%sDisk UUID: %s\n", indent, buf); | 117 printf("%sDisk UUID: %s\n", indent, buf); |
118 } | 118 } |
119 | 119 |
120 printf("%sEntries LBA: %lld\n", indent, (long long)header->entries_lba); | 120 printf("%sEntries LBA: %lld\n", indent, (long long)header->entries_lba); |
121 printf("%sNumber of entries: %d\n", indent, header->number_of_entries); | 121 printf("%sNumber of entries: %d\n", indent, header->number_of_entries); |
122 printf("%sSize of entry: %d\n", indent, header->size_of_entry); | 122 printf("%sSize of entry: %d\n", indent, header->size_of_entry); |
123 printf("%sEntries CRC: 0x%08x\n", indent, header->entries_crc32); | 123 printf("%sEntries CRC: 0x%08x\n", indent, header->entries_crc32); |
124 } | 124 } |
125 | 125 |
126 void EntriesDetails(GptData *gpt, const int secondary) { | 126 void EntryDetails(GptEntry *entry, int index, int raw) { |
127 char contents[256]; | |
128 | |
129 if (raw == NOT_INITED) { | |
130 uint8_t label[sizeof(entry->name) * 3 / 2]; | |
131 char type[GUID_STRLEN], unique[GUID_STRLEN];; | |
132 | |
133 UTF16ToUTF8(entry->name, label); | |
134 snprintf(contents, sizeof(contents), "Label: \"%s\"", label); | |
135 printf(PARTITION_FMT, (int)entry->starting_lba, | |
136 (int)(entry->ending_lba - entry->starting_lba + 1), | |
137 index+1, contents); | |
138 if (CGPT_OK == ResolveType(&entry->type, type)) { | |
139 printf(PARTITION_MORE, "Type: ", type); | |
140 } else { | |
141 GuidToStr(&entry->type, type); | |
142 printf(PARTITION_MORE, "Type: ", type); | |
143 } | |
144 GuidToStr(&entry->unique, unique); | |
145 printf(PARTITION_MORE, "UUID: ", unique); | |
146 if (!Memcmp(&guid_chromeos_kernel, &entry->type, sizeof(Guid))) { | |
147 int tries = (entry->attributes & CGPT_ATTRIBUTE_TRIES_MASK) >> | |
148 CGPT_ATTRIBUTE_TRIES_OFFSET; | |
Randall Spangler
2010/06/03 22:29:50
Should these line up with the ( above?
| |
149 int successful = (entry->attributes & CGPT_ATTRIBUTE_SUCCESSFUL_MASK) >> | |
150 CGPT_ATTRIBUTE_SUCCESSFUL_OFFSET; | |
151 int priority = (entry->attributes & CGPT_ATTRIBUTE_PRIORITY_MASK) >> | |
152 CGPT_ATTRIBUTE_PRIORITY_OFFSET; | |
153 snprintf(contents, sizeof(contents), | |
154 "priority=%d tries=%d successful=%d", | |
155 priority, tries, successful); | |
156 printf(PARTITION_MORE, "Attr: ", contents); | |
157 } | |
158 } else { | |
159 char label[BUFFER_SIZE(sizeof(entry->name))]; | |
160 char type[GUID_STRLEN], unique[GUID_STRLEN]; | |
161 | |
162 RawDump((void*)entry->name, sizeof(entry->name), label, 2); | |
163 snprintf(contents, sizeof(contents), "Label: %s", label); | |
164 printf(PARTITION_FMT, (int)entry->starting_lba, | |
165 (int)(entry->ending_lba - entry->starting_lba + 1), | |
166 index+1, contents); | |
167 GuidToStr(&entry->type, type); | |
168 printf(PARTITION_MORE, "Type: ", type); | |
169 GuidToStr(&entry->unique, unique); | |
170 printf(PARTITION_MORE, "UUID: ", unique); | |
171 snprintf(contents, sizeof(contents), "[%016lx]", entry->attributes); | |
172 printf(PARTITION_MORE, "Attr: ", contents); | |
173 } | |
174 } | |
175 | |
176 void EntriesDetails(GptData *gpt, const int secondary, int raw) { | |
127 int i; | 177 int i; |
128 | 178 |
129 for (i = 0; i < GetNumberOfEntries(gpt); ++i) { | 179 for (i = 0; i < GetNumberOfEntries(gpt); ++i) { |
130 static Guid unused = GPT_ENT_TYPE_UNUSED; | |
131 char contents[256]; | |
132 | |
133 GptEntry *entry; | 180 GptEntry *entry; |
134 entry = GetEntry(gpt, secondary, i); | 181 entry = GetEntry(gpt, secondary, i); |
135 | 182 |
136 if (!Memcmp(&unused, &entry->type, sizeof(unused))) continue; | 183 if (!Memcmp(&guid_unused, &entry->type, sizeof(Guid))) continue; |
137 | 184 |
138 if (number == NOT_INITED) { | 185 EntryDetails(entry, i, raw); |
139 uint8_t label[sizeof(entry->name) * 3 / 2]; | |
140 char type[GUID_STRLEN], unique[GUID_STRLEN];; | |
141 | |
142 UTF16ToUTF8(entry->name, label); | |
143 snprintf(contents, sizeof(contents), "Label: \"%s\"", label); | |
144 printf(PARTITION_FMT, (int)entry->starting_lba, | |
145 (int)(entry->ending_lba - entry->starting_lba + 1), | |
146 i, contents); | |
147 if (CGPT_OK == ResolveType(&entry->type, type)) { | |
148 printf(PARTITION_MORE, "Type: ", type); | |
149 } else { | |
150 GuidToStr(&entry->type, type); | |
151 printf(PARTITION_MORE, "Type: ", type); | |
152 } | |
153 GuidToStr(&entry->unique, unique); | |
154 printf(PARTITION_MORE, "UUID: ", unique); | |
155 } else { | |
156 char label[BUFFER_SIZE(sizeof(entry->name))]; | |
157 char type[GUID_STRLEN], unique[GUID_STRLEN], | |
158 attributes[BUFFER_SIZE(sizeof(uint64_t))]; | |
159 | |
160 RawDump((void*)entry->name, sizeof(entry->name), label, 2); | |
161 snprintf(contents, sizeof(contents), "Label: %s", label); | |
162 printf(PARTITION_FMT, (int)entry->starting_lba, | |
163 (int)(entry->ending_lba - entry->starting_lba + 1), | |
164 i, contents); | |
165 GuidToStr(&entry->type, type); | |
166 printf(PARTITION_MORE, "Type: ", type); | |
167 GuidToStr(&entry->unique, unique); | |
168 printf(PARTITION_MORE, "UUID: ", unique); | |
169 RawDump((uint8_t*)&entry->attributes, 8, attributes, 4); | |
170 printf(PARTITION_MORE, "Attr: ", attributes); | |
171 } | |
172 } | 186 } |
173 } | 187 } |
174 | 188 |
175 /* Parses all options (and validates them), then opens the drive. | 189 /* Parses all options (and validates them), then opens the drive. |
176 * Show GPT information in following order: | 190 * Show GPT information in following order: |
177 * | 191 * |
178 * Primary header sector | 192 * Primary header sector |
179 * details (if -v applied) | 193 * details (if -v applied) |
180 * | 194 * |
181 * Primary table sectors | 195 * Primary table sectors |
(...skipping 27 matching lines...) Expand all Loading... | |
209 show_options_details)) | 223 show_options_details)) |
210 return CGPT_FAILED; | 224 return CGPT_FAILED; |
211 if (help != NOT_INITED) { | 225 if (help != NOT_INITED) { |
212 ShowHelp(); | 226 ShowHelp(); |
213 return CGPT_FAILED; | 227 return CGPT_FAILED; |
214 } | 228 } |
215 | 229 |
216 if (CGPT_OK != OpenDriveInLastArgument(argc, argv, &drive)) | 230 if (CGPT_OK != OpenDriveInLastArgument(argc, argv, &drive)) |
217 return CGPT_FAILED; | 231 return CGPT_FAILED; |
218 | 232 |
219 printf(TITLE_FMT, "start", "size", "index", "contents"); | 233 printf(TITLE_FMT, "start", "size", "part", "contents"); |
220 printf(GPT_FMT, 0, GPT_PMBR_SECTOR, "", "PMBR"); | 234 printf(GPT_FMT, 0, GPT_PMBR_SECTOR, "", "PMBR"); |
221 | 235 |
222 if (drive.gpt.valid_headers & MASK_PRIMARY) { | 236 if (drive.gpt.valid_headers & MASK_PRIMARY) { |
223 printf(GPT_FMT, (int)GPT_PMBR_SECTOR, | 237 printf(GPT_FMT, (int)GPT_PMBR_SECTOR, |
224 (int)GPT_HEADER_SECTOR, "", "Pri GPT header"); | 238 (int)GPT_HEADER_SECTOR, "", "Pri GPT header"); |
225 if (verbose) { | 239 if (verbose) { |
226 GptHeader *header; | 240 GptHeader *header; |
227 char indent[64]; | 241 char indent[64]; |
228 | 242 |
229 snprintf(indent, sizeof(indent), GPT_MORE); | 243 snprintf(indent, sizeof(indent), GPT_MORE); |
230 header = (GptHeader*)drive.gpt.primary_header; | 244 header = (GptHeader*)drive.gpt.primary_header; |
231 HeaderDetails(header, indent); | 245 HeaderDetails(header, indent, number); |
232 } | 246 } |
233 } else { | 247 } else { |
234 printf(GPT_FMT, (int)GPT_PMBR_SECTOR, | 248 printf(GPT_FMT, (int)GPT_PMBR_SECTOR, |
235 (int)GPT_HEADER_SECTOR, "INVALID", "Pri GPT header"); | 249 (int)GPT_HEADER_SECTOR, "INVALID", "Pri GPT header"); |
236 } | 250 } |
237 | 251 |
238 printf(GPT_FMT, (int)(GPT_PMBR_SECTOR + GPT_HEADER_SECTOR), | 252 printf(GPT_FMT, (int)(GPT_PMBR_SECTOR + GPT_HEADER_SECTOR), |
239 (int)GPT_ENTRIES_SECTORS, | 253 (int)GPT_ENTRIES_SECTORS, |
240 drive.gpt.valid_entries & MASK_PRIMARY ? "" : "INVALID", | 254 drive.gpt.valid_entries & MASK_PRIMARY ? "" : "INVALID", |
241 "Pri GPT table"); | 255 "Pri GPT table"); |
242 | 256 |
243 if (drive.gpt.valid_entries & MASK_PRIMARY) | 257 if (drive.gpt.valid_entries & MASK_PRIMARY) |
244 EntriesDetails(&drive.gpt, PRIMARY); | 258 EntriesDetails(&drive.gpt, PRIMARY, number); |
245 | 259 |
246 printf(GPT_FMT, (int)(drive.gpt.drive_sectors - GPT_HEADER_SECTOR - | 260 printf(GPT_FMT, (int)(drive.gpt.drive_sectors - GPT_HEADER_SECTOR - |
247 GPT_ENTRIES_SECTORS), | 261 GPT_ENTRIES_SECTORS), |
248 (int)GPT_ENTRIES_SECTORS, | 262 (int)GPT_ENTRIES_SECTORS, |
249 drive.gpt.valid_entries & MASK_SECONDARY ? "" : "INVALID", | 263 drive.gpt.valid_entries & MASK_SECONDARY ? "" : "INVALID", |
250 "Sec GPT table"); | 264 "Sec GPT table"); |
251 /* We show secondary table details if any of following is true. | 265 /* We show secondary table details if any of following is true. |
252 * 1. only secondary is valid. | 266 * 1. only secondary is valid. |
253 * 2. secondary is not identical to promary. | 267 * 2. secondary is not identical to promary. |
254 */ | 268 */ |
255 if ((drive.gpt.valid_entries & MASK_SECONDARY) && | 269 if ((drive.gpt.valid_entries & MASK_SECONDARY) && |
256 (!(drive.gpt.valid_entries & MASK_PRIMARY) || | 270 (!(drive.gpt.valid_entries & MASK_PRIMARY) || |
257 Memcmp(drive.gpt.primary_entries, drive.gpt.secondary_entries, | 271 Memcmp(drive.gpt.primary_entries, drive.gpt.secondary_entries, |
258 TOTAL_ENTRIES_SIZE))) { | 272 TOTAL_ENTRIES_SIZE))) { |
259 EntriesDetails(&drive.gpt, SECONDARY); | 273 EntriesDetails(&drive.gpt, SECONDARY, number); |
260 } | 274 } |
261 | 275 |
262 if (drive.gpt.valid_headers & MASK_SECONDARY) | 276 if (drive.gpt.valid_headers & MASK_SECONDARY) |
263 printf(GPT_FMT, (int)(drive.gpt.drive_sectors - GPT_HEADER_SECTOR), | 277 printf(GPT_FMT, (int)(drive.gpt.drive_sectors - GPT_HEADER_SECTOR), |
264 (int)GPT_HEADER_SECTOR, "", "Sec GPT header"); | 278 (int)GPT_HEADER_SECTOR, "", "Sec GPT header"); |
265 else | 279 else |
266 printf(GPT_FMT, (int)GPT_PMBR_SECTOR, | 280 printf(GPT_FMT, (int)GPT_PMBR_SECTOR, |
267 (int)GPT_HEADER_SECTOR, "INVALID", "Sec GPT header"); | 281 (int)GPT_HEADER_SECTOR, "INVALID", "Sec GPT header"); |
268 /* We show secondary header if any of following is true: | 282 /* We show secondary header if any of following is true: |
269 * 1. only secondary is valid. | 283 * 1. only secondary is valid. |
270 * 2. secondary is not synonymous to primary. | 284 * 2. secondary is not synonymous to primary. |
271 */ | 285 */ |
272 if ((drive.gpt.valid_headers & MASK_SECONDARY) && | 286 if ((drive.gpt.valid_headers & MASK_SECONDARY) && |
273 (!(drive.gpt.valid_headers & MASK_PRIMARY) || | 287 (!(drive.gpt.valid_headers & MASK_PRIMARY) || |
274 !IsSynonymous((GptHeader*)drive.gpt.primary_header, | 288 !IsSynonymous((GptHeader*)drive.gpt.primary_header, |
275 (GptHeader*)drive.gpt.secondary_header))) { | 289 (GptHeader*)drive.gpt.secondary_header))) { |
276 if (verbose) { | 290 if (verbose) { |
277 GptHeader *header; | 291 GptHeader *header; |
278 char indent[64]; | 292 char indent[64]; |
279 | 293 |
280 snprintf(indent, sizeof(indent), GPT_MORE); | 294 snprintf(indent, sizeof(indent), GPT_MORE); |
281 header = (GptHeader*)drive.gpt.secondary_header; | 295 header = (GptHeader*)drive.gpt.secondary_header; |
282 HeaderDetails(header, indent); | 296 HeaderDetails(header, indent, number); |
283 } | 297 } |
284 } | 298 } |
285 | 299 |
286 CheckValid(&drive); | 300 CheckValid(&drive); |
287 DriveClose(&drive); | 301 DriveClose(&drive); |
288 | 302 |
289 return CGPT_OK; | 303 return CGPT_OK; |
290 } | 304 } |
OLD | NEW |