]> git.sven.stormbind.net Git - sven/exfatprogs.git/blob - include/libexfat.h
Add CVE ID to debian changelog
[sven/exfatprogs.git] / include / libexfat.h
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  *  Copyright (C) 2019 Namjae Jeon <linkinjeon@kernel.org>
4  */
5
6 #ifndef _LIBEXFAT_H
7
8 #include <stdbool.h>
9 #include <sys/types.h>
10 #include <wchar.h>
11 #include <limits.h>
12
13 typedef __u32 clus_t;
14
15 #define KB                      (1024)
16 #define MB                      (1024*1024)
17 #define GB                      (1024UL*1024UL*1024UL)
18
19 #define __round_mask(x, y) ((__typeof__(x))((y)-1))
20 #define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
21 #define round_down(x, y) ((x) & ~__round_mask(x, y))
22
23 #define MIN(a, b)       ((a) < (b) ? (a) : (b))
24 #define MAX(a, b)       ((a) > (b) ? (a) : (b))
25
26 #define DIV_ROUND_UP(__i, __d)  (((__i) + (__d) - 1) / (__d))
27
28 #define EXFAT_MIN_NUM_SEC_VOL           (2048)
29 #define EXFAT_MAX_NUM_SEC_VOL           ((2 << 64) - 1)
30
31 #define EXFAT_MAX_NUM_CLUSTER           (0xFFFFFFF5)
32
33 #define DEFAULT_BOUNDARY_ALIGNMENT      (1024*1024)
34
35 #define DEFAULT_SECTOR_SIZE     (512)
36
37 #define VOLUME_LABEL_BUFFER_SIZE        (VOLUME_LABEL_MAX_LEN*MB_LEN_MAX+1)
38
39 /* Upcase table macro */
40 #define EXFAT_UPCASE_TABLE_CHARS        (0x10000)
41 #define EXFAT_UPCASE_TABLE_SIZE         (5836)
42
43 /* Flags for tune.exfat and exfatlabel */
44 #define EXFAT_GET_VOLUME_LABEL          0x01
45 #define EXFAT_SET_VOLUME_LABEL          0x02
46 #define EXFAT_GET_VOLUME_SERIAL         0x03
47 #define EXFAT_SET_VOLUME_SERIAL         0x04
48 #define EXFAT_GET_VOLUME_GUID           0x05
49 #define EXFAT_SET_VOLUME_GUID           0x06
50
51 #define EXFAT_MAX_SECTOR_SIZE           4096
52
53 #define EXFAT_CLUSTER_SIZE(pbr) (1 << ((pbr)->bsx.sect_size_bits +      \
54                                         (pbr)->bsx.sect_per_clus_bits))
55 #define EXFAT_SECTOR_SIZE(pbr) (1 << (pbr)->bsx.sect_size_bits)
56
57 #define EXFAT_MAX_HASH_COUNT            (UINT16_MAX + 1)
58
59 enum {
60         BOOT_SEC_IDX = 0,
61         EXBOOT_SEC_IDX,
62         EXBOOT_SEC_NUM = 8,
63         OEM_SEC_IDX,
64         RESERVED_SEC_IDX,
65         CHECKSUM_SEC_IDX,
66         BACKUP_BOOT_SEC_IDX,
67 };
68
69 struct exfat_blk_dev {
70         int dev_fd;
71         unsigned long long offset;
72         unsigned long long size;
73         unsigned int sector_size;
74         unsigned int sector_size_bits;
75         unsigned long long num_sectors;
76         unsigned int num_clusters;
77         unsigned int cluster_size;
78 };
79
80 struct exfat_user_input {
81         char dev_name[255];
82         bool writeable;
83         unsigned int cluster_size;
84         unsigned int sec_per_clu;
85         unsigned int boundary_align;
86         bool pack_bitmap;
87         bool quick;
88         __u16 volume_label[VOLUME_LABEL_MAX_LEN];
89         int volume_label_len;
90         unsigned int volume_serial;
91         const char *guid;
92 };
93
94 struct exfat;
95 struct exfat_inode;
96
97 #ifdef WORDS_BIGENDIAN
98 typedef __u8    bitmap_t;
99 #else
100 typedef __u32   bitmap_t;
101 #endif
102
103 #define BITS_PER        (sizeof(bitmap_t) * 8)
104 #define BIT_MASK(__c)   (1 << ((__c) % BITS_PER))
105 #define BIT_ENTRY(__c)  ((__c) / BITS_PER)
106
107 #define EXFAT_BITMAP_SIZE(__c_count)    \
108         (DIV_ROUND_UP(__c_count, BITS_PER) * sizeof(bitmap_t))
109
110 #define BITMAP_GET(bmap, bit)   \
111         (((bitmap_t *)(bmap))[BIT_ENTRY(bit)] & BIT_MASK(bit))
112
113 #define BITMAP_SET(bmap, bit)   \
114         (((bitmap_t *)(bmap))[BIT_ENTRY(bit)] |= BIT_MASK(bit))
115
116 static inline bool exfat_bitmap_get(char *bmap, clus_t c)
117 {
118         clus_t cc = c - EXFAT_FIRST_CLUSTER;
119
120         return BITMAP_GET(bmap, cc);
121 }
122
123 static inline void exfat_bitmap_set(char *bmap, clus_t c)
124 {
125         clus_t cc = c - EXFAT_FIRST_CLUSTER;
126
127         BITMAP_SET(bmap, cc);
128 }
129
130 static inline void exfat_bitmap_clear(char *bmap, clus_t c)
131 {
132         clus_t cc = c - EXFAT_FIRST_CLUSTER;
133         (((bitmap_t *)(bmap))[BIT_ENTRY(cc)] &= ~BIT_MASK(cc));
134 }
135
136 void exfat_bitmap_set_range(struct exfat *exfat, char *bitmap,
137                             clus_t start_clus, clus_t count);
138 int exfat_bitmap_find_zero(struct exfat *exfat, char *bmap,
139                            clus_t start_clu, clus_t *next);
140 int exfat_bitmap_find_one(struct exfat *exfat, char *bmap,
141                           clus_t start_clu, clus_t *next);
142
143 void show_version(void);
144
145 wchar_t exfat_bad_char(wchar_t w);
146 void boot_calc_checksum(unsigned char *sector, unsigned short size,
147                 bool is_boot_sec, __le32 *checksum);
148 void init_user_input(struct exfat_user_input *ui);
149 int exfat_get_blk_dev_info(struct exfat_user_input *ui,
150                 struct exfat_blk_dev *bd);
151 ssize_t exfat_read(int fd, void *buf, size_t size, off_t offset);
152 ssize_t exfat_write(int fd, void *buf, size_t size, off_t offset);
153
154 size_t exfat_utf16_len(const __le16 *str, size_t max_size);
155 ssize_t exfat_utf16_enc(const char *in_str, __u16 *out_str, size_t out_size);
156 ssize_t exfat_utf16_dec(const __u16 *in_str, size_t in_len,
157                         char *out_str, size_t out_size);
158 off_t exfat_get_root_entry_offset(struct exfat_blk_dev *bd);
159 int exfat_read_volume_label(struct exfat *exfat);
160 int exfat_set_volume_label(struct exfat *exfat, char *label_input);
161 int __exfat_set_volume_guid(struct exfat_dentry *dentry, const char *guid);
162 int exfat_read_volume_guid(struct exfat *exfat);
163 int exfat_set_volume_guid(struct exfat *exfat, const char *guid);
164 int exfat_read_sector(struct exfat_blk_dev *bd, void *buf,
165                 unsigned int sec_off);
166 int exfat_write_sector(struct exfat_blk_dev *bd, void *buf,
167                 unsigned int sec_off);
168 int exfat_write_checksum_sector(struct exfat_blk_dev *bd,
169                 unsigned int checksum, bool is_backup);
170 char *exfat_conv_volume_label(struct exfat_dentry *vol_entry);
171 int exfat_show_volume_serial(int fd);
172 int exfat_set_volume_serial(struct exfat_blk_dev *bd,
173                 struct exfat_user_input *ui);
174 unsigned int exfat_clus_to_blk_dev_off(struct exfat_blk_dev *bd,
175                 unsigned int clu_off, unsigned int clu);
176 int exfat_get_next_clus(struct exfat *exfat, clus_t clus, clus_t *next);
177 int exfat_get_inode_next_clus(struct exfat *exfat, struct exfat_inode *node,
178                               clus_t clus, clus_t *next);
179 int exfat_set_fat(struct exfat *exfat, clus_t clus, clus_t next_clus);
180 off_t exfat_s2o(struct exfat *exfat, off_t sect);
181 off_t exfat_c2o(struct exfat *exfat, unsigned int clus);
182 int exfat_o2c(struct exfat *exfat, off_t device_offset,
183               unsigned int *clu, unsigned int *offset);
184 bool exfat_heap_clus(struct exfat *exfat, clus_t clus);
185 int exfat_root_clus_count(struct exfat *exfat);
186 int read_boot_sect(struct exfat_blk_dev *bdev, struct pbr **bs);
187
188 /*
189  * Exfat Print
190  */
191
192 extern unsigned int print_level;
193
194 #define EXFAT_ERROR     (1)
195 #define EXFAT_INFO      (2)
196 #define EXFAT_DEBUG     (3)
197
198 #define exfat_msg(level, dir, fmt, ...)                                 \
199         do {                                                            \
200                 if (print_level >= level) {                             \
201                         fprintf(dir, fmt, ##__VA_ARGS__);               \
202                 }                                                       \
203         } while (0)                                                     \
204
205 #define exfat_err(fmt, ...)     exfat_msg(EXFAT_ERROR, stderr,          \
206                                         fmt, ##__VA_ARGS__)
207 #define exfat_info(fmt, ...)    exfat_msg(EXFAT_INFO, stdout,           \
208                                         fmt, ##__VA_ARGS__)
209 #define exfat_debug(fmt, ...)   exfat_msg(EXFAT_DEBUG, stdout,          \
210                                         "[%s:%4d] " fmt, __func__,      \
211                                         __LINE__, ##__VA_ARGS__)
212
213 #endif /* !_LIBEXFAT_H */