cgpt.h revision 5fac757abef456bf66d9dd96b316ec61fe04b48e
1// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef VBOOT_REFERENCE_UTILITY_CGPT_CGPT_H_
6#define VBOOT_REFERENCE_UTILITY_CGPT_CGPT_H_
7
8#ifndef _GNU_SOURCE
9#define _GNU_SOURCE
10#endif
11
12#define _FILE_OFFSET_BITS 64
13#include <features.h>
14#include <stdint.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include "endian.h"
18#include "gpt.h"
19#include "cgptlib.h"
20
21
22// Just for clarity
23enum {
24  CGPT_OK = 0,
25  CGPT_FAILED,
26};
27
28
29struct legacy_partition {
30  uint8_t  status;
31  uint8_t  f_head;
32  uint8_t  f_sect;
33  uint8_t  f_cyl;
34  uint8_t  type;
35  uint8_t  l_head;
36  uint8_t  l_sect;
37  uint8_t  l_cyl;
38  uint32_t f_lba;
39  uint32_t num_sect;
40} __attribute__((packed));
41
42
43// syslinux uses this format:
44struct pmbr {
45  uint8_t                 bootcode[424];
46  Guid                    boot_guid;
47  uint32_t                disk_id;
48  uint8_t                 magic[2];     // 0x1d, 0x9a
49  struct legacy_partition part[4];
50  uint8_t                 sig[2];       // 0x55, 0xaa
51} __attribute__((packed));
52
53void PMBRToStr(struct pmbr *pmbr, char *str, unsigned int buflen);
54
55// Handle to the drive storing the GPT.
56struct drive {
57  int fd;           /* file descriptor */
58  uint64_t size;    /* total size (in bytes) */
59  GptData gpt;
60  struct pmbr pmbr;
61};
62
63
64int DriveOpen(const char *drive_path, struct drive *drive);
65int DriveClose(struct drive *drive, int update_as_needed);
66int CheckValid(const struct drive *drive);
67
68/* GUID conversion functions. Accepted format:
69 *
70 *   "C12A7328-F81F-11D2-BA4B-00A0C93EC93B"
71 *
72 * At least GUID_STRLEN bytes should be reserved in 'str' (included the tailing
73 * '\0').
74 */
75#define GUID_STRLEN 37
76int StrToGuid(const char *str, Guid *guid);
77void GuidToStr(const Guid *guid, char *str, unsigned int buflen);
78int GuidEqual(const Guid *guid1, const Guid *guid2);
79int IsZero(const Guid *guid);
80
81/* Constant global type values to compare against */
82extern const Guid guid_chromeos_firmware;
83extern const Guid guid_chromeos_kernel;
84extern const Guid guid_chromeos_rootfs;
85extern const Guid guid_linux_data;
86extern const Guid guid_chromeos_reserved;
87extern const Guid guid_efi;
88extern const Guid guid_unused;
89
90int ReadPMBR(struct drive *drive);
91int WritePMBR(struct drive *drive);
92
93/* Convert possibly unterminated UTF16 string to UTF8.
94 * Caller must prepare enough space for UTF8, which could be up to
95 * twice the byte length of UTF16 string plus the terminating '\0'.
96 *
97 * Return: CGPT_OK --- all character are converted successfully.
98 *         CGPT_FAILED --- convert error, i.e. output buffer is too short.
99 */
100int UTF16ToUTF8(const uint16_t *utf16, unsigned int maxinput,
101                uint8_t *utf8, unsigned int maxoutput);
102
103/* Convert null-terminated UTF8 string to UTF16.
104 * Caller must prepare enough space for UTF16, which is the byte length of UTF8
105 * plus the terminating 0x0000.
106 *
107 * Return: CGPT_OK --- all character are converted successfully.
108 *         CGPT_FAILED --- convert error, i.e. output buffer is too short.
109 */
110int UTF8ToUTF16(const uint8_t *utf8, uint16_t *utf16, unsigned int maxoutput);
111
112/* Helper functions for supported GPT types. */
113int ResolveType(const Guid *type, char *buf);
114int SupportedType(const char *name, Guid *type);
115void PrintTypes(void);
116void EntryDetails(GptEntry *entry, uint32_t index, int raw);
117
118uint32_t GetNumberOfEntries(const GptData *gpt);
119GptEntry *GetEntry(GptData *gpt, int secondary, uint32_t entry_index);
120void SetPriority(GptData *gpt, int secondary, uint32_t entry_index,
121                 int priority);
122int GetPriority(GptData *gpt, int secondary, uint32_t entry_index);
123void SetTries(GptData *gpt, int secondary, uint32_t entry_index, int tries);
124int GetTries(GptData *gpt, int secondary, uint32_t entry_index);
125void SetSuccessful(GptData *gpt, int secondary, uint32_t entry_index,
126                   int success);
127int GetSuccessful(GptData *gpt, int secondary, uint32_t entry_index);
128
129uint8_t RepairHeader(GptData *gpt, const uint32_t valid_headers);
130uint8_t RepairEntries(GptData *gpt, const uint32_t valid_entries);
131void UpdateCrc(GptData *gpt);
132int IsSynonymous(const GptHeader* a, const GptHeader* b);
133
134// For usage and error messages.
135extern const char* progname;
136extern const char* command;
137void Error(const char *format, ...);
138
139// The code paths that require uuid_generate are not used currently in
140// libcgpt-cc.a so using this method would create an unnecessary dependency
141// on libuuid which then requires us to build it for 32-bit for the static
142// post-installer. So, we just expose this function pointer which should be
143// set to uuid_generate in case of the cgpt binary and can be null or some
144// no-op method in case of ilbcgpt-cc.a.
145extern void (*uuid_generator)(uint8_t* buffer);
146
147// Command functions.
148int cmd_show(int argc, char *argv[]);
149int cmd_repair(int argc, char *argv[]);
150int cmd_create(int argc, char *argv[]);
151int cmd_add(int argc, char *argv[]);
152int cmd_boot(int argc, char *argv[]);
153int cmd_find(int argc, char *argv[]);
154int cmd_prioritize(int argc, char *argv[]);
155
156#define ARRAY_COUNT(array) (sizeof(array)/sizeof((array)[0]))
157const char *GptError(int errnum);
158
159// Size in chars of the GPT Entry's PartitionName field
160#define GPT_PARTNAME_LEN 72
161
162/* The standard "assert" macro goes away when NDEBUG is defined. This doesn't.
163 */
164#define require(A) do { \
165  if (!(A)) { \
166    fprintf(stderr, "condition (%s) failed at %s:%d\n", \
167            #A, __FILE__, __LINE__); \
168    exit(1); } \
169  } while (0)
170
171#endif  // VBOOT_REFERENCE_UTILITY_CGPT_CGPT_H_
172