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

Side by Side Diff: src/platform/vboot_reference/utility/cgpt/cgpt.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
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 * Utility for ChromeOS-specific GPT partitions, Please see corresponding .c 5 * Utility for ChromeOS-specific GPT partitions, Please see corresponding .c
6 * files for more details. 6 * files for more details.
7 */ 7 */
8 /* To compile on host without compatility to BSD, we include
9 * endian.h under chroot. */
10 #define _BSD_SOURCE
11 #include "endian.h"
12
13 #define __USE_LARGEFILE64
14 #define __USE_FILE_OFFSET64
15 #define _LARGEFILE64_SOURCE
8 #include "cgpt.h" 16 #include "cgpt.h"
9 #include <errno.h> 17 #include <errno.h>
10 #include <fcntl.h> 18 #include <fcntl.h>
11 #include <getopt.h> 19 #include <getopt.h>
12 #include <stdint.h> 20 #include <stdint.h>
13 #include <stdio.h> 21 #include <stdio.h>
14 #include <stdlib.h> 22 #include <stdlib.h>
15 #include <string.h> 23 #include <string.h>
16 #include <sys/ioctl.h> 24 #include <sys/ioctl.h>
17 #include <sys/mount.h> 25 #include <sys/mount.h>
18 #include <sys/stat.h> 26 #include <sys/stat.h>
19 #include <sys/types.h> 27 #include <sys/types.h>
20 #include <unistd.h> 28 #include <unistd.h>
29 #include "cgptlib_internal.h"
21 #include "utility.h" 30 #include "utility.h"
22 31
23 /* For usage print */ 32 /* For usage print */
24 const char* progname; 33 const char* progname;
25 34
26 /* Lists all command here. */ 35 /* Lists all command here. */
27 struct { 36 struct {
28 const char *name; 37 const char *name;
29 int (*fp)(int argc, char *argv[]); 38 int (*fp)(int argc, char *argv[]);
30 const char *comment; 39 const char *comment;
(...skipping 12 matching lines...) Expand all
43 if (message) printf("%s\n", message); 52 if (message) printf("%s\n", message);
44 printf("Usage: %s COMMAND [OPTIONS]\n\n" 53 printf("Usage: %s COMMAND [OPTIONS]\n\n"
45 "Supported commands:\n\n", 54 "Supported commands:\n\n",
46 progname); 55 progname);
47 for (i = 0; i < sizeof(cmds)/sizeof(cmds[0]); ++i) { 56 for (i = 0; i < sizeof(cmds)/sizeof(cmds[0]); ++i) {
48 printf(" %-10s %s\n", cmds[i].name, cmds[i].comment); 57 printf(" %-10s %s\n", cmds[i].name, cmds[i].comment);
49 } 58 }
50 printf("\nFor more detailed usage, use %s COMMAND --help.\n\n", progname); 59 printf("\nFor more detailed usage, use %s COMMAND --help.\n\n", progname);
51 } 60 }
52 61
62 /* GUID conversion functions. Accepted format:
63 *
64 * "C12A7328-F81F-11D2-BA4B-00A0C93EC93B"
65 */
66 void StrToGuid(const char *str, Guid *guid) {
67 uint32_t time_low, time_mid, time_high_and_version;
68
69 sscanf(str, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
70 &time_low,
71 (unsigned int *)&time_mid,
72 (unsigned int *)&time_high_and_version,
73 (unsigned int *)&guid->u.Uuid.clock_seq_high_and_reserved,
74 (unsigned int *)&guid->u.Uuid.clock_seq_low,
75 (unsigned int *)&guid->u.Uuid.node[0],
76 (unsigned int *)&guid->u.Uuid.node[1],
77 (unsigned int *)&guid->u.Uuid.node[2],
78 (unsigned int *)&guid->u.Uuid.node[3],
79 (unsigned int *)&guid->u.Uuid.node[4],
80 (unsigned int *)&guid->u.Uuid.node[5]);
81
82 guid->u.Uuid.time_low = htole32(time_low);
83 guid->u.Uuid.time_mid = htole16(time_mid);
84 guid->u.Uuid.time_high_and_version = htole16(time_high_and_version);
85 }
86
87 void GuidToStr(const Guid *guid, char *str) {
88 sprintf(str, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
89 le32toh(guid->u.Uuid.time_low), le16toh(guid->u.Uuid.time_mid),
90 le16toh(guid->u.Uuid.time_high_and_version),
91 guid->u.Uuid.clock_seq_high_and_reserved, guid->u.Uuid.clock_seq_low,
92 guid->u.Uuid.node[0], guid->u.Uuid.node[1], guid->u.Uuid.node[2],
93 guid->u.Uuid.node[3], guid->u.Uuid.node[4], guid->u.Uuid.node[5]);
94 }
95
96 /* Convert UTF16 string to UTF8. Rewritten from gpt utility.
97 * Caller must prepare enough space for UTF8. The rough estimation is:
98 *
99 * utf8 length = bytecount(utf16) * 1.5
100 */
101 #define SIZEOF_GPTENTRY_NAME 36 /* sizeof(GptEntry.name[]) */
102 void UTF16ToUTF8(const uint16_t *utf16, uint8_t *utf8)
103 {
104 size_t s8idx, s16idx, s16len;
105 uint32_t utfchar;
106 unsigned int next_utf16;
107
108 for (s16len = 0; s16len < SIZEOF_GPTENTRY_NAME && utf16[s16len]; ++s16len);
109
110 *utf8 = s8idx = s16idx = 0;
111 while (s16idx < s16len) {
112 utfchar = le16toh(utf16[s16idx++]);
113 if ((utfchar & 0xf800) == 0xd800) {
114 next_utf16 = le16toh(utf16[s16idx]);
115 if ((utfchar & 0x400) != 0 || (next_utf16 & 0xfc00) != 0xdc00)
116 utfchar = 0xfffd;
117 else
118 s16idx++;
119 }
120 if (utfchar < 0x80) {
121 utf8[s8idx++] = utfchar;
122 } else if (utfchar < 0x800) {
123 utf8[s8idx++] = 0xc0 | (utfchar >> 6);
124 utf8[s8idx++] = 0x80 | (utfchar & 0x3f);
125 } else if (utfchar < 0x10000) {
126 utf8[s8idx++] = 0xe0 | (utfchar >> 12);
127 utf8[s8idx++] = 0x80 | ((utfchar >> 6) & 0x3f);
128 utf8[s8idx++] = 0x80 | (utfchar & 0x3f);
129 } else if (utfchar < 0x200000) {
130 utf8[s8idx++] = 0xf0 | (utfchar >> 18);
131 utf8[s8idx++] = 0x80 | ((utfchar >> 12) & 0x3f);
132 utf8[s8idx++] = 0x80 | ((utfchar >> 6) & 0x3f);
133 utf8[s8idx++] = 0x80 | (utfchar & 0x3f);
134 }
135 }
136 }
137
138 /* Convert UTF8 string to UTF16. Rewritten from gpt utility.
139 * Caller must prepare enough space for UTF16. The conservative estimation is:
140 *
141 * utf16 bytecount = bytecount(utf8) / 3 * 4
142 */
143 void UTF8ToUTF16(const uint8_t *utf8, uint16_t *utf16)
144 {
145 size_t s16idx, s8idx, s8len;
146 uint32_t utfchar;
147 unsigned int c, utfbytes;
148
149 for (s8len = 0; utf8[s8len]; ++s8len);
150
151 s8idx = s16idx = 0;
152 utfbytes = 0;
153 do {
154 c = utf8[s8idx++];
155 if ((c & 0xc0) != 0x80) {
156 /* Initial characters. */
157 if (utfbytes != 0) {
158 /* Incomplete encoding. */
159 utf16[s16idx++] = 0xfffd;
160 }
161 if ((c & 0xf8) == 0xf0) {
162 utfchar = c & 0x07;
163 utfbytes = 3;
164 } else if ((c & 0xf0) == 0xe0) {
165 utfchar = c & 0x0f;
166 utfbytes = 2;
167 } else if ((c & 0xe0) == 0xc0) {
168 utfchar = c & 0x1f;
169 utfbytes = 1;
170 } else {
171 utfchar = c & 0x7f;
172 utfbytes = 0;
173 }
174 } else {
175 /* Followup characters. */
176 if (utfbytes > 0) {
177 utfchar = (utfchar << 6) + (c & 0x3f);
178 utfbytes--;
179 } else if (utfbytes == 0)
180 utfbytes = -1;
181 utfchar = 0xfffd;
182 }
183 if (utfbytes == 0) {
184 if (utfchar >= 0x10000) {
185 utf16[s16idx++] = htole16(0xd800 | ((utfchar>>10)-0x40));
186 if (s16idx >= SIZEOF_GPTENTRY_NAME) break;
187 utf16[s16idx++] = htole16(0xdc00 | (utfchar & 0x3ff));
188 } else {
189 utf16[s16idx++] = htole16(utfchar);
190 }
191 }
192 } while (c != 0 && s16idx < SIZEOF_GPTENTRY_NAME);
193 if (s16idx < SIZEOF_GPTENTRY_NAME)
194 utf16[s16idx++] = 0;
195 }
196
53 /* Loads sectors from 'fd'. 197 /* Loads sectors from 'fd'.
54 * *buf is pointed to an allocated memory when returned, and should be 198 * *buf is pointed to an allocated memory when returned, and should be
55 * freed by cgpt_close(). 199 * freed by cgpt_close().
56 * 200 *
57 * fd -- file descriptot. 201 * fd -- file descriptot.
58 * buf -- pointer to buffer pointer 202 * buf -- pointer to buffer pointer
59 * sector -- offset of starting sector (in sectors) 203 * sector -- offset of starting sector (in sectors)
60 * sector_bytes -- bytes per sector 204 * sector_bytes -- bytes per sector
61 * sector_count -- number of sectors to load 205 * sector_count -- number of sectors to load
62 * 206 *
63 * Returns CGPT_OK for successful. Aborts if any error occurs. 207 * Returns CGPT_OK for successful. Aborts if any error occurs.
64 */ 208 */
65 int Load(const int fd, uint8_t **buf, 209 int Load(const int fd, uint8_t **buf,
66 const uint64_t sector, 210 const uint64_t sector,
67 const uint64_t sector_bytes, 211 const uint64_t sector_bytes,
68 const uint64_t sector_count) { 212 const uint64_t sector_count) {
69 int count; /* byte count to read */ 213 int count; /* byte count to read */
70 int nread; 214 int nread;
71 215
72 assert(buf); 216 assert(buf);
73 count = sector_bytes * sector_count; 217 count = sector_bytes * sector_count;
74 *buf = Malloc(count); 218 *buf = Malloc(count);
75 assert(*buf); 219 assert(*buf);
76 220
77 if (-1 == lseek(fd, sector * sector_bytes, SEEK_SET)) 221 if (-1 == lseek64(fd, sector * sector_bytes, SEEK_SET))
78 goto error_free; 222 goto error_free;
79 223
80 nread = read(fd, *buf, count); 224 nread = read(fd, *buf, count);
81 if (nread < count) 225 if (nread < count)
82 goto error_free; 226 goto error_free;
83 227
84 return CGPT_OK; 228 return CGPT_OK;
85 229
86 error_free: 230 error_free:
87 Free(*buf); 231 Free(*buf);
(...skipping 14 matching lines...) Expand all
102 int Save(const int fd, const uint8_t *buf, 246 int Save(const int fd, const uint8_t *buf,
103 const uint64_t sector, 247 const uint64_t sector,
104 const uint64_t sector_bytes, 248 const uint64_t sector_bytes,
105 const uint64_t sector_count) { 249 const uint64_t sector_count) {
106 int count; /* byte count to write */ 250 int count; /* byte count to write */
107 int nwrote; 251 int nwrote;
108 252
109 assert(buf); 253 assert(buf);
110 count = sector_bytes * sector_count; 254 count = sector_bytes * sector_count;
111 255
112 if (-1 == lseek(fd, sector * sector_bytes, SEEK_SET)) 256 if (-1 == lseek64(fd, sector * sector_bytes, SEEK_SET))
113 return CGPT_FAILED; 257 return CGPT_FAILED;
114 258
115 nwrote = write(fd, buf, count); 259 nwrote = write(fd, buf, count);
116 if (nwrote < count) 260 if (nwrote < count)
117 return CGPT_FAILED; 261 return CGPT_FAILED;
118 262
119 return CGPT_OK; 263 return CGPT_OK;
120 } 264 }
121 265
266 int CheckValid(const struct drive *drive) {
267 if ((drive->gpt.valid_headers != MASK_BOTH) ||
268 (drive->gpt.valid_entries != MASK_BOTH)) {
269 printf("\n[ERROR] any of GPT header/entries is invalid, "
270 "please run --repair first\n");
271 return CGPT_FAILED;
272 }
273 return CGPT_OK;
274 }
275
122 /* Opens a block device (a regular file works well too). 276 /* Opens a block device (a regular file works well too).
123 * 277 *
124 * Returns CGPT_FAILED if any error happens. 278 * Returns CGPT_FAILED if any error happens.
125 * Returns CGPT_OK if success and information are stored in 'drive'. */ 279 * Returns CGPT_OK if success and information are stored in 'drive'. */
126 int DriveOpen(const char *drive_path, struct drive *drive) { 280 int DriveOpen(const char *drive_path, struct drive *drive) {
127 struct stat stat; 281 struct stat stat;
128 int gpt_retval; 282 int gpt_retval;
129 283
130 assert(drive_path); 284 assert(drive_path);
131 assert(drive); 285 assert(drive);
132 286
133 Memset(drive, 0, sizeof(struct drive)); 287 Memset(drive, 0, sizeof(struct drive));
134 drive->fd = open(drive_path, O_RDWR); 288 drive->fd = open(drive_path, O_RDWR | O_LARGEFILE);
135 if (drive->fd == -1) { 289 if (drive->fd == -1) {
136 printf("[ERROR] Cannot open drive file [%s]: %s\n", 290 printf("[ERROR] Cannot open drive file [%s]: %s\n",
137 drive_path, strerror(errno)); 291 drive_path, strerror(errno));
138 return CGPT_FAILED; 292 return CGPT_FAILED;
139 } 293 }
140 294
141 if (fstat(drive->fd, &stat) == -1) { 295 if (fstat(drive->fd, &stat) == -1) {
142 goto error_close; 296 goto error_close;
143 } 297 }
144 if ((stat.st_mode & S_IFMT) != S_IFREG) { 298 if ((stat.st_mode & S_IFMT) != S_IFREG) {
(...skipping 26 matching lines...) Expand all
171 Load(drive->fd, &drive->gpt.secondary_header, 325 Load(drive->fd, &drive->gpt.secondary_header,
172 drive->gpt.drive_sectors - GPT_PMBR_SECTOR, 326 drive->gpt.drive_sectors - GPT_PMBR_SECTOR,
173 drive->gpt.sector_bytes, GPT_HEADER_SECTOR); 327 drive->gpt.sector_bytes, GPT_HEADER_SECTOR);
174 Load(drive->fd, &drive->gpt.primary_entries, 328 Load(drive->fd, &drive->gpt.primary_entries,
175 GPT_PMBR_SECTOR + GPT_HEADER_SECTOR, 329 GPT_PMBR_SECTOR + GPT_HEADER_SECTOR,
176 drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS); 330 drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS);
177 Load(drive->fd, &drive->gpt.secondary_entries, 331 Load(drive->fd, &drive->gpt.secondary_entries,
178 drive->gpt.drive_sectors - GPT_HEADER_SECTOR - GPT_ENTRIES_SECTORS, 332 drive->gpt.drive_sectors - GPT_HEADER_SECTOR - GPT_ENTRIES_SECTORS,
179 drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS); 333 drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS);
180 334
181 if (GPT_SUCCESS != (gpt_retval = GptInit(&drive->gpt))) { 335 if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive->gpt))) {
182 printf("[ERROR] GptInit(): %s\n", GptError(gpt_retval)); 336 printf("[ERROR] GptSanityCheck(): %s\n", GptError(gpt_retval));
183 goto error_close; 337 goto error_close;
184 } 338 }
185 339
186 drive->inited = 1; 340 drive->inited = 1;
187 341
188 return CGPT_OK; 342 return CGPT_OK;
189 343
190 error_close: 344 error_close:
191 close(drive->fd); 345 close(drive->fd);
192 return CGPT_FAILED; 346 return CGPT_FAILED;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 progname = argv[0]; 392 progname = argv[0];
239 cmd = argv[optind++]; 393 cmd = argv[optind++];
240 for (i = 0; i < sizeof(cmds)/sizeof(cmds[0]); ++i) { 394 for (i = 0; i < sizeof(cmds)/sizeof(cmds[0]); ++i) {
241 if (cmd && !strcmp(cmds[i].name, cmd)) 395 if (cmd && !strcmp(cmds[i].name, cmd))
242 return cmds[i].fp(argc, argv); 396 return cmds[i].fp(argc, argv);
243 } 397 }
244 398
245 Usage(0); 399 Usage(0);
246 return CGPT_FAILED; 400 return CGPT_FAILED;
247 } 401 }
OLDNEW
« no previous file with comments | « src/platform/vboot_reference/utility/cgpt/cgpt.h ('k') | src/platform/vboot_reference/utility/cgpt/cgpt_attribute.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698