• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define KB			(1024)
14 #define MB			(1024*1024)
15 #define GB			(1024UL*1024UL*1024UL)
16 
17 #define __round_mask(x, y) ((__typeof__(x))((y)-1))
18 #define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
19 #define round_down(x, y) ((x) & ~__round_mask(x, y))
20 
21 #define MIN(a, b)	((a) < (b) ? (a) : (b))
22 #define MAX(a, b)	((a) > (b) ? (a) : (b))
23 
24 #define DIV_ROUND_UP(__i, __d)	(((__i) + (__d) - 1) / (__d))
25 
26 #define EXFAT_MIN_NUM_SEC_VOL		(2048)
27 #define EXFAT_MAX_NUM_SEC_VOL		((2 << 64) - 1)
28 
29 #define EXFAT_MAX_NUM_CLUSTER		(0xFFFFFFF5)
30 
31 #define DEFAULT_BOUNDARY_ALIGNMENT	(1024*1024)
32 
33 #define DEFAULT_SECTOR_SIZE	(512)
34 
35 #define VOLUME_LABEL_BUFFER_SIZE	(VOLUME_LABEL_MAX_LEN*MB_LEN_MAX+1)
36 
37 /* Upcase tabel macro */
38 #define EXFAT_UPCASE_TABLE_SIZE		(5836)
39 
40 /* Flags for tune.exfat and exfatlabel */
41 #define EXFAT_GET_VOLUME_LABEL		0x01
42 #define EXFAT_SET_VOLUME_LABEL		0x02
43 #define EXFAT_GET_VOLUME_SERIAL		0x03
44 #define EXFAT_SET_VOLUME_SERIAL		0x04
45 
46 enum {
47 	BOOT_SEC_IDX = 0,
48 	EXBOOT_SEC_IDX,
49 	EXBOOT_SEC_NUM = 8,
50 	OEM_SEC_IDX,
51 	RESERVED_SEC_IDX,
52 	CHECKSUM_SEC_IDX,
53 	BACKUP_BOOT_SEC_IDX,
54 };
55 
56 struct exfat_blk_dev {
57 	int dev_fd;
58 	unsigned long long offset;
59 	unsigned long long size;
60 	unsigned int sector_size;
61 	unsigned int sector_size_bits;
62 	unsigned long long num_sectors;
63 	unsigned int num_clusters;
64 	unsigned int cluster_size;
65 };
66 
67 struct exfat_user_input {
68 	char dev_name[255];
69 	bool writeable;
70 	unsigned int cluster_size;
71 	unsigned int sec_per_clu;
72 	unsigned int boundary_align;
73 	bool pack_bitmap;
74 	bool quick;
75 	__u16 volume_label[VOLUME_LABEL_MAX_LEN];
76 	int volume_label_len;
77 	unsigned int volume_serial;
78 };
79 
80 void show_version(void);
81 
82 void exfat_set_bit(struct exfat_blk_dev *bd, char *bitmap,
83 		unsigned int clu);
84 void exfat_clear_bit(struct exfat_blk_dev *bd, char *bitmap,
85 		unsigned int clu);
86 wchar_t exfat_bad_char(wchar_t w);
87 void boot_calc_checksum(unsigned char *sector, unsigned short size,
88 		bool is_boot_sec, __le32 *checksum);
89 void init_user_input(struct exfat_user_input *ui);
90 int exfat_get_blk_dev_info(struct exfat_user_input *ui,
91 		struct exfat_blk_dev *bd);
92 ssize_t exfat_read(int fd, void *buf, size_t size, off_t offset);
93 ssize_t exfat_write(int fd, void *buf, size_t size, off_t offset);
94 
95 size_t exfat_utf16_len(const __le16 *str, size_t max_size);
96 ssize_t exfat_utf16_enc(const char *in_str, __u16 *out_str, size_t out_size);
97 ssize_t exfat_utf16_dec(const __u16 *in_str, size_t in_len,
98 			char *out_str, size_t out_size);
99 off_t exfat_get_root_entry_offset(struct exfat_blk_dev *bd);
100 int exfat_show_volume_label(struct exfat_blk_dev *bd, off_t root_clu_off);
101 int exfat_set_volume_label(struct exfat_blk_dev *bd,
102 		char *label_input, off_t root_clu_off);
103 int exfat_read_sector(struct exfat_blk_dev *bd, void *buf,
104 		unsigned int sec_off);
105 int exfat_write_sector(struct exfat_blk_dev *bd, void *buf,
106 		unsigned int sec_off);
107 int exfat_write_checksum_sector(struct exfat_blk_dev *bd,
108 		unsigned int checksum, bool is_backup);
109 char *exfat_conv_volume_label(struct exfat_dentry *vol_entry);
110 int exfat_show_volume_serial(struct exfat_blk_dev *bd,
111 		struct exfat_user_input *ui);
112 int exfat_set_volume_serial(struct exfat_blk_dev *bd,
113 		struct exfat_user_input *ui);
114 unsigned int exfat_clus_to_blk_dev_off(struct exfat_blk_dev *bd,
115 		unsigned int clu_off, unsigned int clu);
116 
117 
118 /*
119  * Exfat Print
120  */
121 
122 extern unsigned int print_level;
123 
124 #define EXFAT_ERROR	(1)
125 #define EXFAT_INFO	(2)
126 #define EXFAT_DEBUG	(3)
127 
128 #define exfat_msg(level, dir, fmt, ...)					\
129 	do {								\
130 		if (print_level >= level) {				\
131 			fprintf(dir, fmt, ##__VA_ARGS__);		\
132 		}							\
133 	} while (0)							\
134 
135 #define exfat_err(fmt, ...)	exfat_msg(EXFAT_ERROR, stderr,		\
136 					fmt, ##__VA_ARGS__)
137 #define exfat_info(fmt, ...)	exfat_msg(EXFAT_INFO, stdout,		\
138 					fmt, ##__VA_ARGS__)
139 #define exfat_debug(fmt, ...)	exfat_msg(EXFAT_DEBUG, stdout,		\
140 					"[%s:%4d] " fmt, __func__, 	\
141 					__LINE__, ##__VA_ARGS__)
142 
143 #endif /* !_LIBEXFAT_H */
144