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

Unified Diff: utility/cgpt/cgpt.c

Issue 2719008: Nearly complete rewrite of cgpt tool. (Closed) Base URL: ssh://git@chromiumos-git//vboot_reference.git
Patch Set: Created 10 years, 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « utility/cgpt/cgpt.h ('k') | utility/cgpt/cgpt_add_modify_delete.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: utility/cgpt/cgpt.c
diff --git a/utility/cgpt/cgpt.c b/utility/cgpt/cgpt.c
deleted file mode 100644
index 5bcba17c83308fea0d31fbe4ec6c3f25cb8b69ce..0000000000000000000000000000000000000000
--- a/utility/cgpt/cgpt.c
+++ /dev/null
@@ -1,457 +0,0 @@
-/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * Utility for ChromeOS-specific GPT partitions, Please see corresponding .c
- * files for more details.
- */
-/* To compile on host without compatility to BSD, we include
- * endian.h under chroot. */
-#define _BSD_SOURCE
-#include "endian.h"
-
-#define __USE_LARGEFILE64
-#define __USE_FILE_OFFSET64
-#define _LARGEFILE64_SOURCE
-#include "cgpt.h"
-#include "cgpt_tofix.h"
-#include <errno.h>
-#include <fcntl.h>
-#include <getopt.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include "cgptlib_internal.h"
-#include "utility.h"
-
-/* For usage print */
-const char* progname;
-
-/* Lists all command here. */
-struct {
- const char *name;
- int (*fp)(int argc, char *argv[]);
- const char *comment;
-} cmds[] = {
- {"add", CgptAdm, "Add a partition to drive"},
- {"delete", CgptAdm, "Delete a partition on drive"},
- {"modify", CgptAdm, "Modify the partition on drive"},
- {"attribute", CgptAttribute, "Update GPT attribute bits "
- "(for ChromeOS kernel entry only)"},
- {"dev", CgptDev, "Developper mode"},
- {"repair", CgptRepair, "Repair primary and secondary headers and tables"},
- {"show", CgptShow, "Show partition details"},
-};
-
-/* Shows main menu. If 'message' is non-NULL, shows it as header. Then, this
- * traverses cmds[] and shows supported commands and their comments. */
-void Usage(const char *message) {
- int i;
-
- if (message) printf("%s\n", message);
- printf("Usage: %s COMMAND [OPTIONS]\n\n"
- "Supported COMMANDs:\n\n",
- progname);
- for (i = 0; i < sizeof(cmds)/sizeof(cmds[0]); ++i) {
- printf(" %-10s %s\n", cmds[i].name, cmds[i].comment);
- }
- printf("\nFor more detailed usage, use %s COMMAND --help.\n\n", progname);
-}
-
-/* GUID conversion functions. Accepted format:
- *
- * "C12A7328-F81F-11D2-BA4B-00A0C93EC93B"
- *
- * Returns CGPT_OK if parsing is successful; otherwise CGPT_FAILED.
- */
-int StrToGuid(const char *str, Guid *guid) {
- uint32_t time_low, time_mid, time_high_and_version;
-
- if (11 > sscanf(str, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
- &time_low,
- (unsigned int *)&time_mid,
- (unsigned int *)&time_high_and_version,
- (unsigned int *)&guid->u.Uuid.clock_seq_high_and_reserved,
- (unsigned int *)&guid->u.Uuid.clock_seq_low,
- (unsigned int *)&guid->u.Uuid.node[0],
- (unsigned int *)&guid->u.Uuid.node[1],
- (unsigned int *)&guid->u.Uuid.node[2],
- (unsigned int *)&guid->u.Uuid.node[3],
- (unsigned int *)&guid->u.Uuid.node[4],
- (unsigned int *)&guid->u.Uuid.node[5])) return CGPT_FAILED;
-
- guid->u.Uuid.time_low = htole32(time_low);
- guid->u.Uuid.time_mid = htole16(time_mid);
- guid->u.Uuid.time_high_and_version = htole16(time_high_and_version);
-
- return CGPT_OK;
-}
-
-void GuidToStr(const Guid *guid, char *str) {
- sprintf(str, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
- le32toh(guid->u.Uuid.time_low), le16toh(guid->u.Uuid.time_mid),
- le16toh(guid->u.Uuid.time_high_and_version),
- guid->u.Uuid.clock_seq_high_and_reserved, guid->u.Uuid.clock_seq_low,
- guid->u.Uuid.node[0], guid->u.Uuid.node[1], guid->u.Uuid.node[2],
- guid->u.Uuid.node[3], guid->u.Uuid.node[4], guid->u.Uuid.node[5]);
-}
-
-/* Convert UTF16 string to UTF8. Rewritten from gpt utility.
- * Caller must prepare enough space for UTF8. The rough estimation is:
- *
- * utf8 length = bytecount(utf16) * 1.5
- */
-#define SIZEOF_GPTENTRY_NAME 36 /* sizeof(GptEntry.name[]) */
-void UTF16ToUTF8(const uint16_t *utf16, uint8_t *utf8)
-{
- size_t s8idx, s16idx, s16len;
- uint32_t utfchar;
- unsigned int next_utf16;
-
- for (s16len = 0; s16len < SIZEOF_GPTENTRY_NAME && utf16[s16len]; ++s16len);
-
- *utf8 = s8idx = s16idx = 0;
- while (s16idx < s16len) {
- utfchar = le16toh(utf16[s16idx++]);
- if ((utfchar & 0xf800) == 0xd800) {
- next_utf16 = le16toh(utf16[s16idx]);
- if ((utfchar & 0x400) != 0 || (next_utf16 & 0xfc00) != 0xdc00)
- utfchar = 0xfffd;
- else
- s16idx++;
- }
- if (utfchar < 0x80) {
- utf8[s8idx++] = utfchar;
- } else if (utfchar < 0x800) {
- utf8[s8idx++] = 0xc0 | (utfchar >> 6);
- utf8[s8idx++] = 0x80 | (utfchar & 0x3f);
- } else if (utfchar < 0x10000) {
- utf8[s8idx++] = 0xe0 | (utfchar >> 12);
- utf8[s8idx++] = 0x80 | ((utfchar >> 6) & 0x3f);
- utf8[s8idx++] = 0x80 | (utfchar & 0x3f);
- } else if (utfchar < 0x200000) {
- utf8[s8idx++] = 0xf0 | (utfchar >> 18);
- utf8[s8idx++] = 0x80 | ((utfchar >> 12) & 0x3f);
- utf8[s8idx++] = 0x80 | ((utfchar >> 6) & 0x3f);
- utf8[s8idx++] = 0x80 | (utfchar & 0x3f);
- }
- }
- utf8[s8idx++] = 0;
-}
-
-/* Convert UTF8 string to UTF16. Rewritten from gpt utility.
- * Caller must prepare enough space for UTF16. The conservative estimation is:
- *
- * utf16 bytecount = bytecount(utf8) / 3 * 4
- */
-void UTF8ToUTF16(const uint8_t *utf8, uint16_t *utf16)
-{
- size_t s16idx, s8idx, s8len;
- uint32_t utfchar;
- unsigned int c, utfbytes;
-
- for (s8len = 0; utf8[s8len]; ++s8len);
-
- s8idx = s16idx = 0;
- utfbytes = 0;
- do {
- c = utf8[s8idx++];
- if ((c & 0xc0) != 0x80) {
- /* Initial characters. */
- if (utfbytes != 0) {
- /* Incomplete encoding. */
- utf16[s16idx++] = 0xfffd;
- }
- if ((c & 0xf8) == 0xf0) {
- utfchar = c & 0x07;
- utfbytes = 3;
- } else if ((c & 0xf0) == 0xe0) {
- utfchar = c & 0x0f;
- utfbytes = 2;
- } else if ((c & 0xe0) == 0xc0) {
- utfchar = c & 0x1f;
- utfbytes = 1;
- } else {
- utfchar = c & 0x7f;
- utfbytes = 0;
- }
- } else {
- /* Followup characters. */
- if (utfbytes > 0) {
- utfchar = (utfchar << 6) + (c & 0x3f);
- utfbytes--;
- } else if (utfbytes == 0)
- utfbytes = -1;
- utfchar = 0xfffd;
- }
- if (utfbytes == 0) {
- if (utfchar >= 0x10000) {
- utf16[s16idx++] = htole16(0xd800 | ((utfchar>>10)-0x40));
- if (s16idx >= SIZEOF_GPTENTRY_NAME) break;
- utf16[s16idx++] = htole16(0xdc00 | (utfchar & 0x3ff));
- } else {
- utf16[s16idx++] = htole16(utfchar);
- }
- }
- } while (c != 0 && s16idx < SIZEOF_GPTENTRY_NAME);
- if (s16idx < SIZEOF_GPTENTRY_NAME)
- utf16[s16idx++] = 0;
-}
-
-struct {
- Guid type;
- char *name;
- char *description;
-} supported_types[] = {
- {GPT_ENT_TYPE_UNUSED, "unused", "Unused partition"},
- {GPT_ENT_TYPE_EFI, "efi", "EFI System Partition"},
- {GPT_ENT_TYPE_CHROMEOS_KERNEL, "croskern", "ChromeOS kernel"},
- {GPT_ENT_TYPE_CHROMEOS_ROOTFS, "crosroot", "ChromeOS rootfs"},
- {GPT_ENT_TYPE_CHROMEOS_RESERVED, "crosresv", "ChromeOS reserved"},
- {GPT_ENT_TYPE_LINUX_DATA, "data", "Linux data"},
-};
-
-/* Resolves human-readable GPT type.
- * Returns CGPT_OK if found.
- * Returns CGPT_FAILED if no known type found. */
-int ResolveType(const Guid *type, char *buf) {
- int i;
- for (i = 0; i < ARRAY_COUNT(supported_types); ++i) {
- if (!Memcmp(type, &supported_types[i].type, sizeof(Guid))) {
- strcpy(buf, supported_types[i].description);
- return CGPT_OK;
- }
- }
- return CGPT_FAILED;
-}
-
-int SupportedType(const char *name, Guid *type) {
- int i;
- for (i = 0; i < ARRAY_COUNT(supported_types); ++i) {
- if (!strcmp(name, supported_types[i].name)) {
- Memcpy(type, &supported_types[i].type, sizeof(Guid));
- return CGPT_OK;
- }
- }
- return CGPT_FAILED;
-}
-
-void PrintTypes(void) {
- int i;
- printf("\n* For --type option, you can use the following alias, "
- "instead of hex values:\n");
- for (i = 0; i < ARRAY_COUNT(supported_types); ++i) {
- printf(" %-10s %s\n", supported_types[i].name,
- supported_types[i].description);
- }
- printf("\n");
-}
-
-/* Loads sectors from 'fd'.
- * *buf is pointed to an allocated memory when returned, and should be
- * freed by cgpt_close().
- *
- * fd -- file descriptot.
- * buf -- pointer to buffer pointer
- * sector -- offset of starting sector (in sectors)
- * sector_bytes -- bytes per sector
- * sector_count -- number of sectors to load
- *
- * Returns CGPT_OK for successful. Aborts if any error occurs.
- */
-int Load(const int fd, uint8_t **buf,
- const uint64_t sector,
- const uint64_t sector_bytes,
- const uint64_t sector_count) {
- int count; /* byte count to read */
- int nread;
-
- assert(buf);
- count = sector_bytes * sector_count;
- *buf = Malloc(count);
- assert(*buf);
-
- if (-1 == lseek64(fd, sector * sector_bytes, SEEK_SET))
- goto error_free;
-
- nread = read(fd, *buf, count);
- if (nread < count)
- goto error_free;
-
- return CGPT_OK;
-
-error_free:
- Free(*buf);
- *buf = 0;
- abort();
-}
-
-/* Saves sectors to 'fd'.
- *
- * fd -- file descriptot.
- * buf -- pointer to buffer
- * sector -- starting sector offset
- * sector_bytes -- bytes per sector
- * sector_count -- number of sector to save
- *
- * Returns CGPT_OK for successful, CGPT_FAILED for failed.
- */
-int Save(const int fd, const uint8_t *buf,
- const uint64_t sector,
- const uint64_t sector_bytes,
- const uint64_t sector_count) {
- int count; /* byte count to write */
- int nwrote;
-
- assert(buf);
- count = sector_bytes * sector_count;
-
- if (-1 == lseek64(fd, sector * sector_bytes, SEEK_SET))
- return CGPT_FAILED;
-
- nwrote = write(fd, buf, count);
- if (nwrote < count)
- return CGPT_FAILED;
-
- return CGPT_OK;
-}
-
-int CheckValid(const struct drive *drive) {
- if ((drive->gpt.valid_headers != MASK_BOTH) ||
- (drive->gpt.valid_entries != MASK_BOTH)) {
- printf("\n[ERROR] any of GPT header/entries is invalid, "
- "please run '%s repair' first\n", progname);
- return CGPT_FAILED;
- }
- return CGPT_OK;
-}
-
-/* Opens a block device (a regular file works well too).
- *
- * Returns CGPT_FAILED if any error happens.
- * Returns CGPT_OK if success and information are stored in 'drive'. */
-int DriveOpen(const char *drive_path, struct drive *drive) {
- struct stat stat;
- int gpt_retval;
-
- assert(drive_path);
- assert(drive);
-
- Memset(drive, 0, sizeof(struct drive));
- drive->fd = open(drive_path, O_RDWR | O_LARGEFILE);
- if (drive->fd == -1) {
- printf("[ERROR] Cannot open drive file [%s]: %s\n",
- drive_path, strerror(errno));
- return CGPT_FAILED;
- }
-
- if (fstat(drive->fd, &stat) == -1) {
- goto error_close;
- }
- if ((stat.st_mode & S_IFMT) != S_IFREG) {
- if (ioctl(drive->fd, BLKGETSIZE64, &drive->size) < 0) {
- printf("[ERROR] Cannot get sector size from drive file [%s]: %s\n",
- drive_path, strerror(errno));
- goto error_close;
- }
- if (ioctl(drive->fd, BLKSSZGET, &drive->gpt.sector_bytes) < 0) {
- printf("[ERROR] Cannot get drive size from drive file [%s]: %s\n",
- drive_path, strerror(errno));
- goto error_close;
- }
- } else {
- drive->gpt.sector_bytes = 512; /* bytes */
- drive->size = stat.st_size;
- }
- if (drive->size % drive->gpt.sector_bytes) {
- printf("[ERROR] Media size (%llu) is not the multiple of sector size(%d)\n",
- (long long unsigned int)drive->size, drive->gpt.sector_bytes);
- goto error_close;
- }
- drive->gpt.drive_sectors = drive->size / drive->gpt.sector_bytes;
-
- Load(drive->fd, &drive->gpt.primary_header, GPT_PMBR_SECTOR,
- drive->gpt.sector_bytes, GPT_HEADER_SECTOR);
- Load(drive->fd, &drive->gpt.secondary_header,
- drive->gpt.drive_sectors - GPT_PMBR_SECTOR,
- drive->gpt.sector_bytes, GPT_HEADER_SECTOR);
- Load(drive->fd, &drive->gpt.primary_entries,
- GPT_PMBR_SECTOR + GPT_HEADER_SECTOR,
- drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS);
- Load(drive->fd, &drive->gpt.secondary_entries,
- drive->gpt.drive_sectors - GPT_HEADER_SECTOR - GPT_ENTRIES_SECTORS,
- drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS);
-
- if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive->gpt))) {
- printf("[ERROR] GptSanityCheck(): %s\n", GptError(gpt_retval));
- goto error_close;
- }
-
- drive->inited = 1;
-
- return CGPT_OK;
-
-error_close:
- close(drive->fd);
- return CGPT_FAILED;
-}
-
-int DriveClose(struct drive *drive) {
- if (drive->inited) {
- if (drive->gpt.modified & GPT_MODIFIED_HEADER1)
- assert(CGPT_OK ==
- Save(drive->fd, drive->gpt.primary_header, GPT_PMBR_SECTOR,
- drive->gpt.sector_bytes, GPT_HEADER_SECTOR));
- if (drive->gpt.modified & GPT_MODIFIED_HEADER2)
- assert(CGPT_OK ==
- Save(drive->fd, drive->gpt.secondary_header,
- drive->gpt.drive_sectors - GPT_PMBR_SECTOR,
- drive->gpt.sector_bytes, GPT_HEADER_SECTOR));
- if (drive->gpt.modified & GPT_MODIFIED_ENTRIES1)
- assert(CGPT_OK ==
- Save(drive->fd, drive->gpt.primary_entries,
- GPT_PMBR_SECTOR + GPT_HEADER_SECTOR,
- drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS));
- if (drive->gpt.modified & GPT_MODIFIED_ENTRIES2)
- assert(CGPT_OK ==
- Save(drive->fd, drive->gpt.secondary_entries,
- drive->gpt.drive_sectors - GPT_HEADER_SECTOR -
- GPT_ENTRIES_SECTORS,
- drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS));
-
- close(drive->fd);
- }
-
- Free(drive->gpt.primary_header);
- drive->gpt.primary_header = 0;
- Free(drive->gpt.primary_entries);
- drive->gpt.primary_entries = 0;
- Free(drive->gpt.secondary_header);
- drive->gpt.secondary_header = 0;
- Free(drive->gpt.secondary_entries);
- drive->gpt.secondary_entries = 0;
-
- drive->inited = 0;
- return CGPT_OK;
-}
-
-int main(int argc, char *argv[]) {
- char *cmd;
- int i;
-
- progname = argv[0];
- cmd = argv[optind++];
- for (i = 0; i < sizeof(cmds)/sizeof(cmds[0]); ++i) {
- if (cmd && !strcmp(cmds[i].name, cmd))
- return cmds[i].fp(argc, argv);
- }
-
- Usage(0);
- return CGPT_FAILED;
-}
« no previous file with comments | « utility/cgpt/cgpt.h ('k') | utility/cgpt/cgpt_add_modify_delete.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698