1a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 2a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// Use of this source code is governed by a BSD-style license that can be 3a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// found in the LICENSE file. 4a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 5a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan#define __STDC_FORMAT_MACROS 6a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 7a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan#include <string.h> 8a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 90c3ba249abb1dc60f5ebabccf84ff13206440b83Bill Richardson#include "cgpt.h" 10a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan#include "cgptlib_internal.h" 11455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo#include "crc32.h" 120c3ba249abb1dc60f5ebabccf84ff13206440b83Bill Richardson#include "vboot_host.h" 13a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 14a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan/* Generate output like: 15a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan * 16a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan * [AB-CD-EF-01] for group = 1 17a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan * [ABCD-EF01] for group = 3 (low byte first) 18a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan * 19a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan * Needs (size*3-1+3) bytes of space in 'buf' (included the tailing '\0'). 20a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan */ 21a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan#define BUFFER_SIZE(size) (size *3 - 1 + 3) 22a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasanstatic short Uint8To2Chars(const uint8_t t) { 23a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan int h = t >> 4; 24a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan int l = t & 0xf; 25a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan h = (h >= 0xA) ? h - 0xA + 'A' : h + '0'; 26a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan l = (l >= 0xA) ? l - 0xA + 'A' : l + '0'; 27a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan return (h << 8) + l; 28a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan} 29a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 30a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasanstatic void RawDump(const uint8_t *memory, const int size, 31a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan char *buf, int group) { 32a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan int i, outlen = 0; 33a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan buf[outlen++] = '['; 34a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan for (i = 0; i < size; ++i) { 35a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan short c2 = Uint8To2Chars(memory[i]); 36a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan buf[outlen++] = c2 >> 8; 37a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan buf[outlen++] = c2 & 0xff; 38a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if (i != (size - 1) && ((i + 1) % group) == 0) 39a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan buf[outlen++] = '-'; 40a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 41a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan buf[outlen++] = ']'; 42a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan buf[outlen++] = '\0'; 43a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan} 44a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 45a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan/* Output formatters */ 4682bb80262e87d253731251f829471005e0b9d8e7Shawn Nematbakhsh#define TITLE_FMT "%12s%12s%8s %s\n" 4782bb80262e87d253731251f829471005e0b9d8e7Shawn Nematbakhsh#define GPT_FMT "%12d%12d%8s %s\n" 4882bb80262e87d253731251f829471005e0b9d8e7Shawn Nematbakhsh#define GPT_MORE "%12s%12s%8s ", "", "", "" 4982bb80262e87d253731251f829471005e0b9d8e7Shawn Nematbakhsh#define PARTITION_FMT "%12d%12d%8d %s\n" 5082bb80262e87d253731251f829471005e0b9d8e7Shawn Nematbakhsh#define PARTITION_MORE "%12s%12s%8s %s%s\n", "", "", "" 51a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 521c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulkvoid PrintSignature(const char *indent, const char *sig, size_t n, int raw) { 531c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk size_t i; 54a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan printf("%sSig: ", indent); 55a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if (!raw) { 56a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan printf("["); 571c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk for (i = 0; i < n; ++i) 581c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk printf("%c", sig[i]); 59a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan printf("]"); 60a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } else { 611c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk char *buf = malloc(BUFFER_SIZE(n)); 621c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk RawDump((uint8_t *)sig, n, buf, 1); 63a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan printf("%s", buf); 641c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk free(buf); 65a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 66a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan printf("\n"); 671c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk} 681c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk 691c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulkstatic void HeaderDetails(GptHeader *header, GptEntry *entries, 701c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk const char *indent, int raw) { 711c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk PrintSignature(indent, header->signature, sizeof(header->signature), raw); 72a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 73a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan printf("%sRev: 0x%08x\n", indent, header->revision); 74a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan printf("%sSize: %d\n", indent, header->size); 75455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo printf("%sHeader CRC: 0x%08x %s\n", indent, header->header_crc32, 76455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo (HeaderCrc(header) != header->header_crc32) ? "(INVALID)" : ""); 77a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan printf("%sMy LBA: %lld\n", indent, (long long)header->my_lba); 78a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan printf("%sAlternate LBA: %lld\n", indent, (long long)header->alternate_lba); 79a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan printf("%sFirst LBA: %lld\n", indent, (long long)header->first_usable_lba); 80a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan printf("%sLast LBA: %lld\n", indent, (long long)header->last_usable_lba); 81a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 82a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan { /* For disk guid */ 83a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan char buf[GUID_STRLEN]; 84a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan GuidToStr(&header->disk_uuid, buf, GUID_STRLEN); 85a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan printf("%sDisk UUID: %s\n", indent, buf); 86a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 87a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 88a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan printf("%sEntries LBA: %lld\n", indent, (long long)header->entries_lba); 89a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan printf("%sNumber of entries: %d\n", indent, header->number_of_entries); 90a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan printf("%sSize of entry: %d\n", indent, header->size_of_entry); 91455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo printf("%sEntries CRC: 0x%08x %s\n", indent, header->entries_crc32, 92455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo header->entries_crc32 != 93455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo Crc32((const uint8_t *)entries,header->size_of_entry * 94455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo header->number_of_entries) 95455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo ? "INVALID" : "" 96455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo ); 97a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan} 98a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 99a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasanvoid EntryDetails(GptEntry *entry, uint32_t index, int raw) { 100a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan char contents[256]; // scratch buffer for formatting output 101a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan uint8_t label[GPT_PARTNAME_LEN]; 10232fd6dead10a8255fea27f6e5ce9ba92d8716008Albert Chaulk char type[GUID_STRLEN], unique[GUID_STRLEN]; 103a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 10432fd6dead10a8255fea27f6e5ce9ba92d8716008Albert Chaulk UTF16ToUTF8(entry->name, sizeof(entry->name) / sizeof(entry->name[0]), 10532fd6dead10a8255fea27f6e5ce9ba92d8716008Albert Chaulk label, sizeof(label)); 10632fd6dead10a8255fea27f6e5ce9ba92d8716008Albert Chaulk require(snprintf(contents, sizeof(contents), 10732fd6dead10a8255fea27f6e5ce9ba92d8716008Albert Chaulk "Label: \"%s\"", label) < sizeof(contents)); 10832fd6dead10a8255fea27f6e5ce9ba92d8716008Albert Chaulk printf(PARTITION_FMT, (int)entry->starting_lba, 10932fd6dead10a8255fea27f6e5ce9ba92d8716008Albert Chaulk (int)(entry->ending_lba - entry->starting_lba + 1), 11032fd6dead10a8255fea27f6e5ce9ba92d8716008Albert Chaulk index+1, contents); 111a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 11232fd6dead10a8255fea27f6e5ce9ba92d8716008Albert Chaulk if (!raw && CGPT_OK == ResolveType(&entry->type, type)) { 11332fd6dead10a8255fea27f6e5ce9ba92d8716008Albert Chaulk printf(PARTITION_MORE, "Type: ", type); 11432fd6dead10a8255fea27f6e5ce9ba92d8716008Albert Chaulk } else { 11532fd6dead10a8255fea27f6e5ce9ba92d8716008Albert Chaulk GuidToStr(&entry->type, type, GUID_STRLEN); 11632fd6dead10a8255fea27f6e5ce9ba92d8716008Albert Chaulk printf(PARTITION_MORE, "Type: ", type); 11732fd6dead10a8255fea27f6e5ce9ba92d8716008Albert Chaulk } 11832fd6dead10a8255fea27f6e5ce9ba92d8716008Albert Chaulk GuidToStr(&entry->unique, unique, GUID_STRLEN); 11932fd6dead10a8255fea27f6e5ce9ba92d8716008Albert Chaulk printf(PARTITION_MORE, "UUID: ", unique); 12032fd6dead10a8255fea27f6e5ce9ba92d8716008Albert Chaulk 12132fd6dead10a8255fea27f6e5ce9ba92d8716008Albert Chaulk if (!raw) { 122a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if (GuidEqual(&guid_chromeos_kernel, &entry->type)) { 123a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan int tries = (entry->attrs.fields.gpt_att & 124a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan CGPT_ATTRIBUTE_TRIES_MASK) >> 125a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan CGPT_ATTRIBUTE_TRIES_OFFSET; 126a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan int successful = (entry->attrs.fields.gpt_att & 127a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan CGPT_ATTRIBUTE_SUCCESSFUL_MASK) >> 128a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan CGPT_ATTRIBUTE_SUCCESSFUL_OFFSET; 129a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan int priority = (entry->attrs.fields.gpt_att & 130a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan CGPT_ATTRIBUTE_PRIORITY_MASK) >> 131a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan CGPT_ATTRIBUTE_PRIORITY_OFFSET; 132a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan require(snprintf(contents, sizeof(contents), 133a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan "priority=%d tries=%d successful=%d", 134a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan priority, tries, successful) < sizeof(contents)); 135a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan printf(PARTITION_MORE, "Attr: ", contents); 136a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 137a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } else { 138a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan require(snprintf(contents, sizeof(contents), 139a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan "[%x]", entry->attrs.fields.gpt_att) < sizeof(contents)); 140a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan printf(PARTITION_MORE, "Attr: ", contents); 141a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 142a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan} 143a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 144fa6b35c1ffa33833b3250a6515869ccd4cb59121Albert Chaulkvoid EntriesDetails(struct drive *drive, const int secondary, int raw) { 145a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan uint32_t i; 146a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 147fa6b35c1ffa33833b3250a6515869ccd4cb59121Albert Chaulk for (i = 0; i < GetNumberOfEntries(drive); ++i) { 148a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan GptEntry *entry; 149fa6b35c1ffa33833b3250a6515869ccd4cb59121Albert Chaulk entry = GetEntry(&drive->gpt, secondary, i); 150a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 1513f806a2abf07d7b801852a4a6f3a9080a4b5c427Bill Richardson if (GuidIsZero(&entry->type)) 152a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan continue; 153a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 154a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan EntryDetails(entry, i, raw); 155a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 156a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan} 157a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 15818e03706df6ab4256a89f4e578ecf0f165641c8aBill Richardsonstatic int GptShow(struct drive *drive, CgptShowParams *params) { 1591c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk int gpt_retval; 1601c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive->gpt))) { 161a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan Error("GptSanityCheck() returned %d: %s\n", 162a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan gpt_retval, GptError(gpt_retval)); 163a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan return CGPT_FAILED; 164a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 165a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 166a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if (params->partition) { // show single partition 167a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 1681c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk if (params->partition > GetNumberOfEntries(drive)) { 169a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan Error("invalid partition number: %d\n", params->partition); 170a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan return CGPT_FAILED; 171a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 172a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 173a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan uint32_t index = params->partition - 1; 1741c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk GptEntry *entry = GetEntry(&drive->gpt, ANY_VALID, index); 175a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan char buf[256]; // scratch buffer for string conversion 176a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 177a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if (params->single_item) { 178a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan switch(params->single_item) { 179a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan case 'b': 180a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan printf("%" PRId64 "\n", entry->starting_lba); 181a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan break; 18298624d37447d01a9a78d9e0a1f55cbbce2ee99e4Mike Frysinger case 's': { 18398624d37447d01a9a78d9e0a1f55cbbce2ee99e4Mike Frysinger uint64_t size = 0; 18498624d37447d01a9a78d9e0a1f55cbbce2ee99e4Mike Frysinger // If these aren't actually defined, don't show anything 18598624d37447d01a9a78d9e0a1f55cbbce2ee99e4Mike Frysinger if (entry->ending_lba || entry->starting_lba) 18698624d37447d01a9a78d9e0a1f55cbbce2ee99e4Mike Frysinger size = entry->ending_lba - entry->starting_lba + 1; 18798624d37447d01a9a78d9e0a1f55cbbce2ee99e4Mike Frysinger printf("%" PRId64 "\n", size); 188a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan break; 18998624d37447d01a9a78d9e0a1f55cbbce2ee99e4Mike Frysinger } 190a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan case 't': 191a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan GuidToStr(&entry->type, buf, sizeof(buf)); 192a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan printf("%s\n", buf); 193a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan break; 194a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan case 'u': 195a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan GuidToStr(&entry->unique, buf, sizeof(buf)); 196a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan printf("%s\n", buf); 197a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan break; 198a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan case 'l': 199a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan UTF16ToUTF8(entry->name, sizeof(entry->name) / sizeof(entry->name[0]), 200a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan (uint8_t *)buf, sizeof(buf)); 201a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan printf("%s\n", buf); 202a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan break; 203a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan case 'S': 2041c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk printf("%d\n", GetSuccessful(drive, ANY_VALID, index)); 205a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan break; 206a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan case 'T': 2071c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk printf("%d\n", GetTries(drive, ANY_VALID, index)); 208a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan break; 209a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan case 'P': 2101c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk printf("%d\n", GetPriority(drive, ANY_VALID, index)); 211a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan break; 212a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan case 'A': 213a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan printf("0x%x\n", entry->attrs.fields.gpt_att); 214a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan break; 215a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 216a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } else { 217a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan printf(TITLE_FMT, "start", "size", "part", "contents"); 218a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan EntryDetails(entry, index, params->numeric); 219a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 220a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 221a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } else if (params->quick) { // show all partitions, quickly 222a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan uint32_t i; 223a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan GptEntry *entry; 224a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan char type[GUID_STRLEN]; 225a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 2261c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk for (i = 0; i < GetNumberOfEntries(drive); ++i) { 2271c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk entry = GetEntry(&drive->gpt, ANY_VALID, i); 228a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 2293f806a2abf07d7b801852a4a6f3a9080a4b5c427Bill Richardson if (GuidIsZero(&entry->type)) 230a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan continue; 231a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 232a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if (!params->numeric && CGPT_OK == ResolveType(&entry->type, type)) { 233a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } else { 234a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan GuidToStr(&entry->type, type, GUID_STRLEN); 235a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 236a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan printf(PARTITION_FMT, (int)entry->starting_lba, 237a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan (int)(entry->ending_lba - entry->starting_lba + 1), 238a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan i+1, type); 239a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 240a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } else { // show all partitions 241455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo GptEntry *entries; 242455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo 2431c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk if (CGPT_OK != ReadPMBR(drive)) { 244a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan Error("Unable to read PMBR\n"); 245a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan return CGPT_FAILED; 246a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 247a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 248a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan printf(TITLE_FMT, "start", "size", "part", "contents"); 249a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan char buf[256]; // buffer for formatted PMBR content 2501c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk PMBRToStr(&drive->pmbr, buf, sizeof(buf)); // will exit if buf is too small 25188458d9b5281aca162821a369707781ac9abb44eNam T. Nguyen printf(GPT_FMT, 0, GPT_PMBR_SECTORS, "", buf); 252a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 2531c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk if (drive->gpt.valid_headers & MASK_PRIMARY) { 25488458d9b5281aca162821a369707781ac9abb44eNam T. Nguyen printf(GPT_FMT, (int)GPT_PMBR_SECTORS, 25588458d9b5281aca162821a369707781ac9abb44eNam T. Nguyen (int)GPT_HEADER_SECTORS, "", "Pri GPT header"); 256a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } else { 25788458d9b5281aca162821a369707781ac9abb44eNam T. Nguyen printf(GPT_FMT, (int)GPT_PMBR_SECTORS, 25888458d9b5281aca162821a369707781ac9abb44eNam T. Nguyen (int)GPT_HEADER_SECTORS, "INVALID", "Pri GPT header"); 259a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 260a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 261455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo if (params->debug || 2621c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk ((drive->gpt.valid_headers & MASK_PRIMARY) && params->verbose)) { 263455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo GptHeader *header; 264455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo char indent[64]; 265455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo 266455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo require(snprintf(indent, sizeof(indent), GPT_MORE) < sizeof(indent)); 2671c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk header = (GptHeader*)drive->gpt.primary_header; 2681c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk entries = (GptEntry*)drive->gpt.primary_entries; 269455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo HeaderDetails(header, entries, indent, params->numeric); 270455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo } 271455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo 272a2d72f70c18905aba25eb0971f6f601dd1fa5a60Nam T. Nguyen GptHeader* primary_header = (GptHeader*)drive->gpt.primary_header; 273a2d72f70c18905aba25eb0971f6f601dd1fa5a60Nam T. Nguyen printf(GPT_FMT, (int)primary_header->entries_lba, 2743200401242aec1521e7c4a8b1906366fcabfb1a2Nam T. Nguyen (int)CalculateEntriesSectors(primary_header), 2751c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk drive->gpt.valid_entries & MASK_PRIMARY ? "" : "INVALID", 276a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan "Pri GPT table"); 277a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 278455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo if (params->debug || 2791c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk (drive->gpt.valid_entries & MASK_PRIMARY)) 2801c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk EntriesDetails(drive, PRIMARY, params->numeric); 281a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 282455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo /****************************** Secondary *************************/ 283a2d72f70c18905aba25eb0971f6f601dd1fa5a60Nam T. Nguyen GptHeader* secondary_header = (GptHeader*)drive->gpt.secondary_header; 284a2d72f70c18905aba25eb0971f6f601dd1fa5a60Nam T. Nguyen printf(GPT_FMT, (int)secondary_header->entries_lba, 2853200401242aec1521e7c4a8b1906366fcabfb1a2Nam T. Nguyen (int)CalculateEntriesSectors(secondary_header), 2861c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk drive->gpt.valid_entries & MASK_SECONDARY ? "" : "INVALID", 287a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan "Sec GPT table"); 288a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan /* We show secondary table details if any of following is true. 289455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo * 1. in debug mode. 290455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo * 2. only secondary is valid. 291455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo * 3. secondary is not identical to promary. 292a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan */ 293455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo if (params->debug || 2941c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk ((drive->gpt.valid_entries & MASK_SECONDARY) && 2951c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk (!(drive->gpt.valid_entries & MASK_PRIMARY) || 2961c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk memcmp(drive->gpt.primary_entries, drive->gpt.secondary_entries, 2973200401242aec1521e7c4a8b1906366fcabfb1a2Nam T. Nguyen secondary_header->number_of_entries * 2983200401242aec1521e7c4a8b1906366fcabfb1a2Nam T. Nguyen secondary_header->size_of_entry)))) { 2991c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk EntriesDetails(drive, SECONDARY, params->numeric); 300a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 301a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 3021c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk if (drive->gpt.valid_headers & MASK_SECONDARY) 3036ee52d9a929d00e871e7316240b54f381146fbc6Nam T. Nguyen printf(GPT_FMT, (int)(drive->gpt.gpt_drive_sectors - GPT_HEADER_SECTORS), 30488458d9b5281aca162821a369707781ac9abb44eNam T. Nguyen (int)GPT_HEADER_SECTORS, "", "Sec GPT header"); 305a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan else 30688458d9b5281aca162821a369707781ac9abb44eNam T. Nguyen printf(GPT_FMT, (int)GPT_PMBR_SECTORS, 30788458d9b5281aca162821a369707781ac9abb44eNam T. Nguyen (int)GPT_HEADER_SECTORS, "INVALID", "Sec GPT header"); 308a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan /* We show secondary header if any of following is true: 309455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo * 1. in debug mode. 310455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo * 2. only secondary is valid. 311455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo * 3. secondary is not synonymous to primary. 312a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan */ 313455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo if (params->debug || 3141c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk ((drive->gpt.valid_headers & MASK_SECONDARY) && 3151c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk (!(drive->gpt.valid_headers & MASK_PRIMARY) || 3161c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk !IsSynonymous((GptHeader*)drive->gpt.primary_header, 3171c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk (GptHeader*)drive->gpt.secondary_header)) && 318455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo params->verbose)) { 319455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo GptHeader *header; 320455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo char indent[64]; 321455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo 322455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo require(snprintf(indent, sizeof(indent), GPT_MORE) < sizeof(indent)); 3231c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk header = (GptHeader*)drive->gpt.secondary_header; 3241c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk entries = (GptEntry*)drive->gpt.secondary_entries; 325455b119dc0f3cd5538c4a53f0e2ab38534bcdf14Louis Yung-Chieh Lo HeaderDetails(header, entries, indent, params->numeric); 326a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 327a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 328a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 3291c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk CheckValid(drive); 3301c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk 3311c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk return CGPT_OK; 3321c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk} 3331c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk 3341c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulkint CgptShow(CgptShowParams *params) { 3351c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk struct drive drive; 3361c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk 3371c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk if (params == NULL) 3381c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk return CGPT_FAILED; 3391c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk 340ab899591808dd3e5f955ab7693b54a83389cd35fNam T. Nguyen if (CGPT_OK != DriveOpen(params->drive_name, &drive, O_RDONLY, 341ab899591808dd3e5f955ab7693b54a83389cd35fNam T. Nguyen params->drive_size)) 3421c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk return CGPT_FAILED; 343a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 3448577b5360ca4c9514d9091ed9aded2bb3193f1f0Nam T. Nguyen if (GptShow(&drive, params)) 3458577b5360ca4c9514d9091ed9aded2bb3193f1f0Nam T. Nguyen return CGPT_FAILED; 3461c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk 3471c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk DriveClose(&drive, 0); 348a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan return CGPT_OK; 349a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan} 350