Home | History | Annotate | Download | only in cgpt
      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 #include <fcntl.h>
      9 #ifndef HAVE_MACOS
     10 #include <features.h>
     11 #endif
     12 #include <stdint.h>
     13 #include <stdio.h>
     14 #include <stdlib.h>
     15 #include "cgpt_endian.h"
     16 #include "cgptlib.h"
     17 #include "gpt.h"
     18 
     19 struct legacy_partition {
     20   uint8_t  status;
     21   uint8_t  f_head;
     22   uint8_t  f_sect;
     23   uint8_t  f_cyl;
     24   uint8_t  type;
     25   uint8_t  l_head;
     26   uint8_t  l_sect;
     27   uint8_t  l_cyl;
     28   uint32_t f_lba;
     29   uint32_t num_sect;
     30 } __attribute__((packed));
     31 
     32 // syslinux uses this format:
     33 struct pmbr {
     34   uint8_t                 bootcode[424];
     35   Guid                    boot_guid;
     36   uint32_t                disk_id;
     37   uint8_t                 magic[2];     // 0x1d, 0x9a
     38   struct legacy_partition part[4];
     39   uint8_t                 sig[2];       // 0x55, 0xaa
     40 } __attribute__((packed));
     41 
     42 void PMBRToStr(struct pmbr *pmbr, char *str, unsigned int buflen);
     43 
     44 // Handle to the drive storing the GPT.
     45 struct drive {
     46   uint64_t size;    /* total size (in bytes) */
     47   GptData gpt;
     48   struct pmbr pmbr;
     49   int fd;       /* file descriptor */
     50 };
     51 
     52 // Opens a block device or file, loads raw GPT data from it.
     53 // 'mode' should be O_RDONLY or O_RDWR.
     54 // If 'drive_size' is 0, both the partitions and GPT structs reside on the same
     55 // 'drive_path'.
     56 // Otherwise, 'drive_size' is taken as the size of the device that all
     57 // partitions will reside on, and 'drive_path' is where we store GPT structs.
     58 //
     59 // Returns CGPT_FAILED if any error happens.
     60 // Returns CGPT_OK if success and information are stored in 'drive'. */
     61 int DriveOpen(const char *drive_path, struct drive *drive, int mode,
     62               uint64_t drive_size);
     63 int DriveClose(struct drive *drive, int update_as_needed);
     64 int CheckValid(const struct drive *drive);
     65 
     66 /* Loads sectors from 'drive'.
     67  * *buf is pointed to an allocated memory when returned, and should be
     68  * freed.
     69  *
     70  *   drive -- open drive.
     71  *   buf -- pointer to buffer pointer
     72  *   sector -- offset of starting sector (in sectors)
     73  *   sector_bytes -- bytes per sector
     74  *   sector_count -- number of sectors to load
     75  *
     76  * Returns CGPT_OK for successful. Aborts if any error occurs.
     77  */
     78 int Load(struct drive *drive, uint8_t **buf,
     79                 const uint64_t sector,
     80                 const uint64_t sector_bytes,
     81                 const uint64_t sector_count);
     82 
     83 /* Saves sectors to 'drive'.
     84  *
     85  *   drive -- open drive
     86  *   buf -- pointer to buffer
     87  *   sector -- starting sector offset
     88  *   sector_bytes -- bytes per sector
     89  *   sector_count -- number of sector to save
     90  *
     91  * Returns CGPT_OK for successful, CGPT_FAILED for failed.
     92  */
     93 int Save(struct drive *drive, const uint8_t *buf,
     94                 const uint64_t sector,
     95                 const uint64_t sector_bytes,
     96                 const uint64_t sector_count);
     97 
     98 
     99 /* GUID conversion functions. Accepted format:
    100  *
    101  *   "C12A7328-F81F-11D2-BA4B-00A0C93EC93B"
    102  *
    103  * At least GUID_STRLEN bytes should be reserved in 'str' (included the tailing
    104  * '\0').
    105  */
    106 #define GUID_STRLEN 37
    107 int StrToGuid(const char *str, Guid *guid);
    108 void GuidToStr(const Guid *guid, char *str, unsigned int buflen);
    109 int GuidEqual(const Guid *guid1, const Guid *guid2);
    110 int IsZero(const Guid *guid);
    111 
    112 /* Constant global type values to compare against */
    113 extern const Guid guid_chromeos_firmware;
    114 extern const Guid guid_chromeos_kernel;
    115 extern const Guid guid_chromeos_rootfs;
    116 extern const Guid guid_linux_data;
    117 extern const Guid guid_chromeos_reserved;
    118 extern const Guid guid_efi;
    119 extern const Guid guid_unused;
    120 
    121 int ReadPMBR(struct drive *drive);
    122 int WritePMBR(struct drive *drive);
    123 
    124 /* Convert possibly unterminated UTF16 string to UTF8.
    125  * Caller must prepare enough space for UTF8, which could be up to
    126  * twice the byte length of UTF16 string plus the terminating '\0'.
    127  *
    128  * Return: CGPT_OK --- all character are converted successfully.
    129  *         CGPT_FAILED --- convert error, i.e. output buffer is too short.
    130  */
    131 int UTF16ToUTF8(const uint16_t *utf16, unsigned int maxinput,
    132                 uint8_t *utf8, unsigned int maxoutput);
    133 
    134 /* Convert null-terminated UTF8 string to UTF16.
    135  * Caller must prepare enough space for UTF16, which is the byte length of UTF8
    136  * plus the terminating 0x0000.
    137  *
    138  * Return: CGPT_OK --- all character are converted successfully.
    139  *         CGPT_FAILED --- convert error, i.e. output buffer is too short.
    140  */
    141 int UTF8ToUTF16(const uint8_t *utf8, uint16_t *utf16, unsigned int maxoutput);
    142 
    143 /* Helper functions for supported GPT types. */
    144 int ResolveType(const Guid *type, char *buf);
    145 int SupportedType(const char *name, Guid *type);
    146 void PrintTypes(void);
    147 void EntryDetails(GptEntry *entry, uint32_t index, int raw);
    148 
    149 uint32_t GetNumberOfEntries(const struct drive *drive);
    150 GptEntry *GetEntry(GptData *gpt, int secondary, uint32_t entry_index);
    151 
    152 void SetPriority(struct drive *drive, int secondary, uint32_t entry_index,
    153                  int priority);
    154 int GetPriority(struct drive *drive, int secondary, uint32_t entry_index);
    155 void SetTries(struct drive *drive, int secondary, uint32_t entry_index,
    156               int tries);
    157 int GetTries(struct drive *drive, int secondary, uint32_t entry_index);
    158 void SetSuccessful(struct drive *drive, int secondary, uint32_t entry_index,
    159                    int success);
    160 int GetSuccessful(struct drive *drive, int secondary, uint32_t entry_index);
    161 
    162 void SetRaw(struct drive *drive, int secondary, uint32_t entry_index,
    163            uint32_t raw);
    164 
    165 void UpdateAllEntries(struct drive *drive);
    166 
    167 uint8_t RepairHeader(GptData *gpt, const uint32_t valid_headers);
    168 uint8_t RepairEntries(GptData *gpt, const uint32_t valid_entries);
    169 void UpdateCrc(GptData *gpt);
    170 int IsSynonymous(const GptHeader* a, const GptHeader* b);
    171 
    172 int IsUnused(struct drive *drive, int secondary, uint32_t index);
    173 int IsKernel(struct drive *drive, int secondary, uint32_t index);
    174 
    175 // Optional. Applications that need this must provide an implementation.
    176 //
    177 // Explanation:
    178 //   Some external utilities need to manipulate the GPT, but don't create new
    179 //   partitions from scratch. The cgpt executable uses libuuid to provide this
    180 //   functionality, but we don't want to have to build or install a separate
    181 //   instance of that library just for the 32-bit static post-install tool,
    182 //   which doesn't need this function.
    183 int GenerateGuid(Guid *newguid);
    184 
    185 // For usage and error messages.
    186 void Error(const char *format, ...);
    187 void Warning(const char *format, ...);
    188 
    189 // Command functions.
    190 int cmd_show(int argc, char *argv[]);
    191 int cmd_repair(int argc, char *argv[]);
    192 int cmd_create(int argc, char *argv[]);
    193 int cmd_add(int argc, char *argv[]);
    194 int cmd_boot(int argc, char *argv[]);
    195 int cmd_find(int argc, char *argv[]);
    196 int cmd_prioritize(int argc, char *argv[]);
    197 int cmd_legacy(int argc, char *argv[]);
    198 
    199 #define ARRAY_COUNT(array) (sizeof(array)/sizeof((array)[0]))
    200 const char *GptError(int errnum);
    201 
    202 // Size in chars of the GPT Entry's PartitionName field
    203 #define GPT_PARTNAME_LEN 72
    204 
    205 /* The standard "assert" macro goes away when NDEBUG is defined. This doesn't.
    206  */
    207 #define require(A) do { \
    208   if (!(A)) { \
    209     fprintf(stderr, "condition (%s) failed at %s:%d\n", \
    210             #A, __FILE__, __LINE__); \
    211     exit(1); } \
    212   } while (0)
    213 
    214 #endif  // VBOOT_REFERENCE_UTILITY_CGPT_CGPT_H_
    215