1 // Copyright 2016 The Fuchsia 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 #pragma once
6 
7 #include <stdbool.h>
8 #include <stdint.h>
9 #include <unistd.h>
10 
11 #include <zircon/compiler.h>
12 #include <zircon/device/block.h>
13 #include <zircon/hw/gpt.h>
14 
15 typedef gpt_entry_t gpt_partition_t;
16 
17 __BEGIN_CDECLS
18 
19 #define PARTITIONS_COUNT 128
20 #define GPT_GUID_STRLEN 37
21 
22 // Helpers for translating the |name| field of "gpt_partition_t".
23 // Assumes UTF-16LE.
24 // Assumes all code points are less than or equal to U+007F, and
25 // discards any upper bits, forcing all inputs to be in this
26 // range.
27 //
28 // |len| refers to the length of the input string, in chars.
29 void cstring_to_utf16(uint16_t* dst, const char* src, size_t len);
30 // |len| refers to the length of the input string, in 16-bit pairs.
31 char* utf16_to_cstring(char* dst, const uint16_t* src, size_t len);
32 
33 typedef struct gpt_device {
34     // true if the partition table on the device is valid
35     bool valid;
36 
37     // pointer to a list of partitions
38     gpt_partition_t* partitions[PARTITIONS_COUNT];
39 } gpt_device_t;
40 
41 // determines whether guid is system guid
42 bool gpt_is_sys_guid(uint8_t* guid, ssize_t len);
43 
44 // determines whether guid is data guid
45 bool gpt_is_data_guid(uint8_t* guid, ssize_t len);
46 
47 // determines whether guid is install guid
48 bool gpt_is_install_guid(uint8_t* guid, ssize_t len);
49 
50 // determines whether guid is efi guid
51 bool gpt_is_efi_guid(uint8_t* guid, ssize_t len);
52 
53 // read the partition table from the device.
54 int gpt_device_init(int fd, uint32_t blocksize, uint64_t blocks, gpt_device_t** out_dev);
55 
56 // releases the device
57 void gpt_device_release(gpt_device_t* dev);
58 
59 // Returns the range of usable blocks within the GPT, from [block_start, block_end] (inclusive)
60 int gpt_device_range(const gpt_device_t* dev, uint64_t* block_start, uint64_t* block_end);
61 
62 // writes the partition table to the device. it is the caller's responsibility to
63 // rescan partitions for the block device if needed
64 int gpt_device_sync(gpt_device_t* dev);
65 
66 // perform all checks and computations on the in-memory representation, but DOES
67 // NOT write it out to disk. To perform checks AND write to disk, use
68 // gpt_device_sync
69 int gpt_device_finalize(gpt_device_t* dev);
70 
71 // adds a partition
72 int gpt_partition_add(gpt_device_t* dev, const char* name, const uint8_t* type,
73                       const uint8_t* guid, uint64_t offset, uint64_t blocks,
74                       uint64_t flags);
75 
76 // Writes zeroed blocks at an arbitrary offset (in blocks) within the device.
77 //
78 // Can be used alongside gpt_partition_add to ensure a newly created partition
79 // will not read stale superblock data.
80 int gpt_partition_clear(gpt_device_t* dev, uint64_t offset, uint64_t blocks);
81 
82 // removes a partition
83 int gpt_partition_remove(gpt_device_t* dev, const uint8_t* guid);
84 
85 // removes all partitions
86 int gpt_partition_remove_all(gpt_device_t* dev);
87 
88 // converts GUID to a string
89 void uint8_to_guid_string(char* dst, const uint8_t* src);
90 
91 // given a gpt device, get the GUID for the disk
92 void gpt_device_get_header_guid(const gpt_device_t* dev,
93                                 uint8_t (*disk_guid_out)[GPT_GUID_LEN]);
94 
95 // return true if partition# idx has been locally modified
96 int gpt_get_diffs(const gpt_device_t* dev, int idx, unsigned* diffs);
97 
98 // print out the GPT
99 void print_table(const gpt_device_t* device);
100 
101 // Sort an array of gpt_partition_t pointers in-place based on the values of
102 // gpt_partition_t->first.
103 void gpt_sort_partitions(gpt_partition_t** partitions, size_t count);
104 
105 // Attempt to read a GPT from the file descriptor. dev_out will be NULL if
106 // the read fails or read succeeds and GPT is invalid.
107 int gpt_device_read_gpt(int fd, gpt_device_t** dev_out);
108 
109 void gpt_set_debug_output_enabled(bool enabled);
110 
111 // Return the human-readable version of the type GUID.
112 const char* gpt_guid_to_type(const char* guid);
113 
114 #define GPT_DIFF_TYPE    (0x01u)
115 #define GPT_DIFF_GUID    (0x02u)
116 #define GPT_DIFF_FIRST   (0x04u)
117 #define GPT_DIFF_LAST    (0x08u)
118 #define GPT_DIFF_FLAGS   (0x10u)
119 #define GPT_DIFF_NAME    (0x20u)
120 
121 __END_CDECLS
122