Chromium Code Reviews| 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 |