xref: /aosp_15_r20/external/exfatprogs/include/exfat_ondisk.h (revision 508ec739de867a7549a0b8584942a00612dc5f1c)
1*508ec739SDaniel Rosenberg /* SPDX-License-Identifier: GPL-2.0-or-later */
2*508ec739SDaniel Rosenberg /*
3*508ec739SDaniel Rosenberg  *  Copyright (C) 2019 Namjae Jeon <[email protected]>
4*508ec739SDaniel Rosenberg  */
5*508ec739SDaniel Rosenberg 
6*508ec739SDaniel Rosenberg #ifndef _EXFAT_H
7*508ec739SDaniel Rosenberg #define _EXFAT_H
8*508ec739SDaniel Rosenberg 
9*508ec739SDaniel Rosenberg #include <stdint.h>
10*508ec739SDaniel Rosenberg #include <linux/fs.h>
11*508ec739SDaniel Rosenberg 
12*508ec739SDaniel Rosenberg #ifdef HAVE_CONFIG_H
13*508ec739SDaniel Rosenberg #include <config.h>
14*508ec739SDaniel Rosenberg #endif
15*508ec739SDaniel Rosenberg 
16*508ec739SDaniel Rosenberg #ifdef WORDS_BIGENDIAN
17*508ec739SDaniel Rosenberg #define cpu_to_le16(x)	((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8))
18*508ec739SDaniel Rosenberg #define cpu_to_le32(x)	\
19*508ec739SDaniel Rosenberg 	((((x) & 0xff000000u) >> 24) | (((x) & 0x00ff0000u) >>  8) | \
20*508ec739SDaniel Rosenberg 	 (((x) & 0x0000ff00u) <<  8) | (((x) & 0x000000ffu) << 24))
21*508ec739SDaniel Rosenberg #define cpu_to_le64(x)	(cpu_to_le32((uint64_t)(x)) << 32 | \
22*508ec739SDaniel Rosenberg 			cpu_to_le32((uint64_t)(x) >> 32))
23*508ec739SDaniel Rosenberg #else
24*508ec739SDaniel Rosenberg #define cpu_to_le16(x)	(x)
25*508ec739SDaniel Rosenberg #define cpu_to_le32(x)	(x)
26*508ec739SDaniel Rosenberg #define cpu_to_le64(x)	(x)
27*508ec739SDaniel Rosenberg #endif
28*508ec739SDaniel Rosenberg 
29*508ec739SDaniel Rosenberg #define le64_to_cpu(x)  ((uint64_t)cpu_to_le64(x))
30*508ec739SDaniel Rosenberg #define le32_to_cpu(x)  ((uint32_t)cpu_to_le32(x))
31*508ec739SDaniel Rosenberg #define le16_to_cpu(x)  ((uint16_t)cpu_to_le16(x))
32*508ec739SDaniel Rosenberg 
33*508ec739SDaniel Rosenberg #define PBR_SIGNATURE		0xAA55
34*508ec739SDaniel Rosenberg 
35*508ec739SDaniel Rosenberg #define VOL_CLEAN		0x0000
36*508ec739SDaniel Rosenberg #define VOL_DIRTY		0x0002
37*508ec739SDaniel Rosenberg 
38*508ec739SDaniel Rosenberg #define DENTRY_SIZE		32 /* directory entry size */
39*508ec739SDaniel Rosenberg #define DENTRY_SIZE_BITS	5
40*508ec739SDaniel Rosenberg /* exFAT allows 8388608(256MB) directory entries */
41*508ec739SDaniel Rosenberg #define MAX_EXFAT_DENTRIES	8388608
42*508ec739SDaniel Rosenberg #define MIN_FILE_DENTRIES	3
43*508ec739SDaniel Rosenberg 
44*508ec739SDaniel Rosenberg /* dentry types */
45*508ec739SDaniel Rosenberg #define MSDOS_DELETED		0xE5	/* deleted mark */
46*508ec739SDaniel Rosenberg #define MSDOS_UNUSED		0x00	/* end of directory */
47*508ec739SDaniel Rosenberg 
48*508ec739SDaniel Rosenberg #define EXFAT_LAST		0x00	/* end of directory */
49*508ec739SDaniel Rosenberg #define EXFAT_DELETE		~(0x80)
50*508ec739SDaniel Rosenberg #define IS_EXFAT_DELETED(x)	((x) < 0x80) /* deleted file (0x01~0x7F) */
51*508ec739SDaniel Rosenberg #define EXFAT_INVAL		0x80	/* invalid value */
52*508ec739SDaniel Rosenberg #define EXFAT_BITMAP		0x81	/* allocation bitmap */
53*508ec739SDaniel Rosenberg #define EXFAT_UPCASE		0x82	/* upcase table */
54*508ec739SDaniel Rosenberg #define EXFAT_VOLUME		0x83	/* volume label */
55*508ec739SDaniel Rosenberg #define EXFAT_FILE		0x85	/* file or dir */
56*508ec739SDaniel Rosenberg #define EXFAT_GUID		0xA0
57*508ec739SDaniel Rosenberg #define EXFAT_PADDING		0xA1
58*508ec739SDaniel Rosenberg #define EXFAT_ACLTAB		0xA2
59*508ec739SDaniel Rosenberg #define EXFAT_STREAM		0xC0	/* stream entry */
60*508ec739SDaniel Rosenberg #define EXFAT_NAME		0xC1	/* file name entry */
61*508ec739SDaniel Rosenberg #define EXFAT_ACL		0xC2	/* stream entry */
62*508ec739SDaniel Rosenberg 
63*508ec739SDaniel Rosenberg /* checksum types */
64*508ec739SDaniel Rosenberg #define CS_DIR_ENTRY		0
65*508ec739SDaniel Rosenberg #define CS_PBR_SECTOR		1
66*508ec739SDaniel Rosenberg #define CS_DEFAULT		2
67*508ec739SDaniel Rosenberg 
68*508ec739SDaniel Rosenberg /* file attributes */
69*508ec739SDaniel Rosenberg #define ATTR_READONLY		0x0001
70*508ec739SDaniel Rosenberg #define ATTR_HIDDEN		0x0002
71*508ec739SDaniel Rosenberg #define ATTR_SYSTEM		0x0004
72*508ec739SDaniel Rosenberg #define ATTR_VOLUME		0x0008
73*508ec739SDaniel Rosenberg #define ATTR_SUBDIR		0x0010
74*508ec739SDaniel Rosenberg #define ATTR_ARCHIVE		0x0020
75*508ec739SDaniel Rosenberg #define ATTR_EXTEND		(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | \
76*508ec739SDaniel Rosenberg 				 ATTR_VOLUME) /* 0x000F */
77*508ec739SDaniel Rosenberg 
78*508ec739SDaniel Rosenberg #define ATTR_EXTEND_MASK	(ATTR_EXTEND | ATTR_SUBDIR | ATTR_ARCHIVE)
79*508ec739SDaniel Rosenberg #define ATTR_RWMASK		(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME | \
80*508ec739SDaniel Rosenberg 				 ATTR_SUBDIR | ATTR_ARCHIVE)
81*508ec739SDaniel Rosenberg 
82*508ec739SDaniel Rosenberg #define ATTR_READONLY_LE	cpu_to_le16(0x0001)
83*508ec739SDaniel Rosenberg #define ATTR_HIDDEN_LE		cpu_to_le16(0x0002)
84*508ec739SDaniel Rosenberg #define ATTR_SYSTEM_LE		cpu_to_le16(0x0004)
85*508ec739SDaniel Rosenberg #define ATTR_VOLUME_LE		cpu_to_le16(0x0008)
86*508ec739SDaniel Rosenberg #define ATTR_SUBDIR_LE		cpu_to_le16(0x0010)
87*508ec739SDaniel Rosenberg #define ATTR_ARCHIVE_LE		cpu_to_le16(0x0020)
88*508ec739SDaniel Rosenberg 
89*508ec739SDaniel Rosenberg /* stream flags */
90*508ec739SDaniel Rosenberg #define EXFAT_SF_CONTIGUOUS		0x02
91*508ec739SDaniel Rosenberg 
92*508ec739SDaniel Rosenberg #define CLUSTER_32(x)			((unsigned int)((x) & 0xFFFFFFFFU))
93*508ec739SDaniel Rosenberg #define EXFAT_EOF_CLUSTER		CLUSTER_32(~0)
94*508ec739SDaniel Rosenberg #define EXFAT_BAD_CLUSTER		(0xFFFFFFF7U)
95*508ec739SDaniel Rosenberg #define EXFAT_FREE_CLUSTER		(0)
96*508ec739SDaniel Rosenberg #define EXFAT_FIRST_CLUSTER		(2)
97*508ec739SDaniel Rosenberg #define EXFAT_RESERVED_CLUSTERS		(2)
98*508ec739SDaniel Rosenberg 
99*508ec739SDaniel Rosenberg 
100*508ec739SDaniel Rosenberg /* EXFAT BIOS parameter block (64 bytes) */
101*508ec739SDaniel Rosenberg struct bpb64 {
102*508ec739SDaniel Rosenberg 	__u8 jmp_boot[3];
103*508ec739SDaniel Rosenberg 	__u8 oem_name[8];
104*508ec739SDaniel Rosenberg 	__u8 res_zero[53];
105*508ec739SDaniel Rosenberg };
106*508ec739SDaniel Rosenberg 
107*508ec739SDaniel Rosenberg /* EXFAT EXTEND BIOS parameter block (56 bytes) */
108*508ec739SDaniel Rosenberg struct bsx64 {
109*508ec739SDaniel Rosenberg 	__le64 vol_offset;
110*508ec739SDaniel Rosenberg 	__le64 vol_length;
111*508ec739SDaniel Rosenberg 	__le32 fat_offset;
112*508ec739SDaniel Rosenberg 	__le32 fat_length;
113*508ec739SDaniel Rosenberg 	__le32 clu_offset;
114*508ec739SDaniel Rosenberg 	__le32 clu_count;
115*508ec739SDaniel Rosenberg 	__le32 root_cluster;
116*508ec739SDaniel Rosenberg 	__le32 vol_serial;
117*508ec739SDaniel Rosenberg 	__u8 fs_version[2];
118*508ec739SDaniel Rosenberg 	__le16 vol_flags;
119*508ec739SDaniel Rosenberg 	__u8 sect_size_bits;
120*508ec739SDaniel Rosenberg 	__u8 sect_per_clus_bits;
121*508ec739SDaniel Rosenberg 	__u8 num_fats;
122*508ec739SDaniel Rosenberg 	__u8 phy_drv_no;
123*508ec739SDaniel Rosenberg 	__u8 perc_in_use;
124*508ec739SDaniel Rosenberg 	__u8 reserved2[7];
125*508ec739SDaniel Rosenberg };
126*508ec739SDaniel Rosenberg 
127*508ec739SDaniel Rosenberg /* Common PBR[Partition Boot Record] (512 bytes) */
128*508ec739SDaniel Rosenberg struct pbr {
129*508ec739SDaniel Rosenberg 	struct bpb64 bpb;
130*508ec739SDaniel Rosenberg 	struct bsx64 bsx;
131*508ec739SDaniel Rosenberg 	__u8 boot_code[390];
132*508ec739SDaniel Rosenberg 	__le16 signature;
133*508ec739SDaniel Rosenberg };
134*508ec739SDaniel Rosenberg 
135*508ec739SDaniel Rosenberg #define VOLUME_LABEL_MAX_LEN	11
136*508ec739SDaniel Rosenberg #define ENTRY_NAME_MAX		15
137*508ec739SDaniel Rosenberg 
138*508ec739SDaniel Rosenberg struct exfat_dentry {
139*508ec739SDaniel Rosenberg 	__u8 type;
140*508ec739SDaniel Rosenberg 	union {
141*508ec739SDaniel Rosenberg 		struct {
142*508ec739SDaniel Rosenberg 			__u8 character_count;
143*508ec739SDaniel Rosenberg 			__le16 volume_label[VOLUME_LABEL_MAX_LEN];
144*508ec739SDaniel Rosenberg 			__u8 reserved[8];
145*508ec739SDaniel Rosenberg 		} __attribute__((packed)) vol; /* file directory entry */
146*508ec739SDaniel Rosenberg 
147*508ec739SDaniel Rosenberg 		struct {
148*508ec739SDaniel Rosenberg 			__u8 num_ext;
149*508ec739SDaniel Rosenberg 			__le16 checksum;
150*508ec739SDaniel Rosenberg 			__le16 attr;
151*508ec739SDaniel Rosenberg 			__le16 reserved1;
152*508ec739SDaniel Rosenberg 			__le16 create_time;
153*508ec739SDaniel Rosenberg 			__le16 create_date;
154*508ec739SDaniel Rosenberg 			__le16 modify_time;
155*508ec739SDaniel Rosenberg 			__le16 modify_date;
156*508ec739SDaniel Rosenberg 			__le16 access_time;
157*508ec739SDaniel Rosenberg 			__le16 access_date;
158*508ec739SDaniel Rosenberg 			__u8 create_time_ms;
159*508ec739SDaniel Rosenberg 			__u8 modify_time_ms;
160*508ec739SDaniel Rosenberg 			__u8 create_tz;
161*508ec739SDaniel Rosenberg 			__u8 modify_tz;
162*508ec739SDaniel Rosenberg 			__u8 access_tz;
163*508ec739SDaniel Rosenberg 			__u8 reserved2[7];
164*508ec739SDaniel Rosenberg 		} __attribute__((packed)) file; /* file directory entry */
165*508ec739SDaniel Rosenberg 		struct {
166*508ec739SDaniel Rosenberg 			__u8 flags;
167*508ec739SDaniel Rosenberg 			__u8 reserved1;
168*508ec739SDaniel Rosenberg 			__u8 name_len;
169*508ec739SDaniel Rosenberg 			__le16 name_hash;
170*508ec739SDaniel Rosenberg 			__le16 reserved2;
171*508ec739SDaniel Rosenberg 			__le64 valid_size;
172*508ec739SDaniel Rosenberg 			__le32 reserved3;
173*508ec739SDaniel Rosenberg 			__le32 start_clu;
174*508ec739SDaniel Rosenberg 			__le64 size;
175*508ec739SDaniel Rosenberg 		} __attribute__((packed)) stream; /* stream extension directory entry */
176*508ec739SDaniel Rosenberg 		struct {
177*508ec739SDaniel Rosenberg 			__u8 flags;
178*508ec739SDaniel Rosenberg 			__le16 unicode_0_14[15];
179*508ec739SDaniel Rosenberg 		} __attribute__((packed)) name; /* file name directory entry */
180*508ec739SDaniel Rosenberg 		struct {
181*508ec739SDaniel Rosenberg 			__u8 flags;
182*508ec739SDaniel Rosenberg 			__u8 reserved[18];
183*508ec739SDaniel Rosenberg 			__le32 start_clu;
184*508ec739SDaniel Rosenberg 			__le64 size;
185*508ec739SDaniel Rosenberg 		} __attribute__((packed)) bitmap; /* allocation bitmap directory entry */
186*508ec739SDaniel Rosenberg 		struct {
187*508ec739SDaniel Rosenberg 			__u8 reserved1[3];
188*508ec739SDaniel Rosenberg 			__le32 checksum;
189*508ec739SDaniel Rosenberg 			__u8 reserved2[12];
190*508ec739SDaniel Rosenberg 			__le32 start_clu;
191*508ec739SDaniel Rosenberg 			__le64 size;
192*508ec739SDaniel Rosenberg 		} __attribute__((packed)) upcase; /* up-case table directory entry */
193*508ec739SDaniel Rosenberg 	} __attribute__((packed)) dentry;
194*508ec739SDaniel Rosenberg } __attribute__((packed));
195*508ec739SDaniel Rosenberg 
196*508ec739SDaniel Rosenberg #define vol_char_cnt			dentry.vol.character_count
197*508ec739SDaniel Rosenberg #define vol_label			dentry.vol.volume_label
198*508ec739SDaniel Rosenberg #define file_num_ext			dentry.file.num_ext
199*508ec739SDaniel Rosenberg #define file_checksum			dentry.file.checksum
200*508ec739SDaniel Rosenberg #define file_attr			dentry.file.attr
201*508ec739SDaniel Rosenberg #define file_create_time		dentry.file.create_time
202*508ec739SDaniel Rosenberg #define file_create_date		dentry.file.create_date
203*508ec739SDaniel Rosenberg #define file_modify_time		dentry.file.modify_time
204*508ec739SDaniel Rosenberg #define file_modify_date		dentry.file.modify_date
205*508ec739SDaniel Rosenberg #define file_access_time		dentry.file.access_time
206*508ec739SDaniel Rosenberg #define file_access_date		dentry.file.access_date
207*508ec739SDaniel Rosenberg #define file_create_time_ms		dentry.file.create_time_ms
208*508ec739SDaniel Rosenberg #define file_modify_time_ms		dentry.file.modify_time_ms
209*508ec739SDaniel Rosenberg #define file_access_time_ms		dentry.file.access_time_ms
210*508ec739SDaniel Rosenberg #define stream_flags			dentry.stream.flags
211*508ec739SDaniel Rosenberg #define stream_name_len			dentry.stream.name_len
212*508ec739SDaniel Rosenberg #define stream_name_hash		dentry.stream.name_hash
213*508ec739SDaniel Rosenberg #define stream_start_clu		dentry.stream.start_clu
214*508ec739SDaniel Rosenberg #define stream_valid_size		dentry.stream.valid_size
215*508ec739SDaniel Rosenberg #define stream_size			dentry.stream.size
216*508ec739SDaniel Rosenberg #define name_flags			dentry.name.flags
217*508ec739SDaniel Rosenberg #define name_unicode			dentry.name.unicode_0_14
218*508ec739SDaniel Rosenberg #define bitmap_flags			dentry.bitmap.flags
219*508ec739SDaniel Rosenberg #define bitmap_start_clu		dentry.bitmap.start_clu
220*508ec739SDaniel Rosenberg #define bitmap_size			dentry.bitmap.size
221*508ec739SDaniel Rosenberg #define upcase_start_clu		dentry.upcase.start_clu
222*508ec739SDaniel Rosenberg #define upcase_size			dentry.upcase.size
223*508ec739SDaniel Rosenberg #define upcase_checksum			dentry.upcase.checksum
224*508ec739SDaniel Rosenberg 
225*508ec739SDaniel Rosenberg #endif /* !_EXFAT_H */
226