xref: /haiku/src/add-ons/kernel/file_systems/exfat/exfat.h (revision b46615c55ad2c8fe6de54412055a0713da3d610a)
1 /*
2  * Copyright 2011, Jérôme Duval, korli@users.berlios.de.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef EXFAT_H
6 #define EXFAT_H
7 
8 
9 #include <sys/stat.h>
10 
11 #include <ByteOrder.h>
12 #include <fs_interface.h>
13 #include <KernelExport.h>
14 
15 
16 typedef uint64 fileblock_t;		// file block number
17 typedef uint64 fsblock_t;		// filesystem block number
18 
19 typedef uint32 cluster_t;
20 
21 #define EXFAT_SUPER_BLOCK_OFFSET	0x0
22 
23 
24 struct exfat_super_block {
25 	uint8	jump_boot[3];
26 	char	filesystem[8];
27 	uint8	reserved[53];
28 	uint64	first_block;
29 	uint64	num_blocks;
30 	uint32	first_fat_block;
31 	uint32	fat_length;
32 	uint32	first_data_block;
33 	uint32	cluster_count;
34 	uint32	root_dir_cluster;
35 	uint32	serial_number;
36 	uint8	version_minor;
37 	uint8	version_major;
38 	uint16	flags;
39 	uint8	block_shift;
40 	uint8	blocks_per_cluster_shift;
41 	uint8	fat_count;
42 	uint8	drive_select;
43 	uint8	used_percent;
44 	uint8	reserved2[7];
45 	uint8	boot_code[390];
46 	uint16	signature;
47 
48 	bool IsValid();
49 		// implemented in Volume.cpp
50 	uint64 FirstBlock() const { return B_LENDIAN_TO_HOST_INT64(first_block); }
51 	uint64 NumBlocks() const { return B_LENDIAN_TO_HOST_INT32(num_blocks); }
52 	uint32 FirstFatBlock() const
53 		{ return B_LENDIAN_TO_HOST_INT32(first_fat_block); }
54 	uint32 FatLength() const
55 		{ return B_LENDIAN_TO_HOST_INT32(fat_length); }
56 	uint32 FirstDataBlock() const
57 		{ return B_LENDIAN_TO_HOST_INT32(first_data_block); }
58 	uint32 ClusterCount() const
59 		{ return B_LENDIAN_TO_HOST_INT32(cluster_count); }
60 	uint32 RootDirCluster() const
61 		{ return B_LENDIAN_TO_HOST_INT32(root_dir_cluster); }
62 	uint32 SerialNumber() const
63 		{ return B_LENDIAN_TO_HOST_INT32(serial_number); }
64 	uint8 VersionMinor() const { return version_minor; }
65 	uint8 VersionMajor() const { return version_major; }
66 	uint16 Flags() const { return B_LENDIAN_TO_HOST_INT16(flags); }
67 	uint8 BlockShift() const { return block_shift; }
68 	uint8 BlocksPerClusterShift() const { return blocks_per_cluster_shift; }
69 	uint8 FatCount() const { return fat_count; }
70 	uint8 DriveSelect() const { return drive_select; }
71 	uint8 UsedPercent() const { return used_percent; }
72 } _PACKED;
73 
74 
75 #define EXFAT_SUPER_BLOCK_MAGIC			"EXFAT   "
76 
77 #define EXFAT_ENTRY_TYPE_BITMAP		0x81
78 #define EXFAT_ENTRY_TYPE_UPPERCASE	0x82
79 #define EXFAT_ENTRY_TYPE_LABEL		0x83
80 #define EXFAT_ENTRY_TYPE_FILE		0x85
81 #define EXFAT_ENTRY_TYPE_FILEINFO	0xc0
82 #define EXFAT_ENTRY_TYPE_FILENAME	0xc1
83 #define EXFAT_CLUSTER_END 	0xffffffff
84 #define EXFAT_ENTRY_ATTRIB_SUBDIR	0x10
85 
86 #define EXFAT_ENTRY_FLAG_CONTIGUOUS	0x3
87 
88 #define EXFAT_FILENAME_MAX_LENGTH	512
89 
90 struct exfat_entry {
91 	uint8	type;
92 	union {
93 		struct {
94 			uint8 length;
95 			char name[30];
96 		} _PACKED name_label;
97 		struct {
98 			uint8 reserved[3];
99 			uint32 checksum;
100 			uint8 reserved2[12];
101 			uint32 start_cluster;
102 			uint64 size;
103 		} _PACKED bitmap_uppercase;
104 		struct {
105 			uint8 chunkCount;
106 			uint16 checksum;
107 			uint16 attribs;
108 			uint16 reserved;
109 			uint16 creation_time;
110 			uint16 creation_date;
111 			uint16 modification_time;
112 			uint16 modification_date;
113 			uint16 access_time;
114 			uint16 access_date;
115 			uint8 creation_time_low;
116 			uint8 modification_time_low;
117 			uint8 reserved2[10];
118 			uint16 ModificationTime() const
119 				{ return B_LENDIAN_TO_HOST_INT16(modification_time); }
120 			uint16 ModificationDate() const
121 				{ return B_LENDIAN_TO_HOST_INT16(modification_date); }
122 			uint16 AccessTime() const
123 				{ return B_LENDIAN_TO_HOST_INT16(access_time); }
124 			uint16 AccessDate() const
125 				{ return B_LENDIAN_TO_HOST_INT16(access_date); }
126 			uint16 CreationTime() const
127 				{ return B_LENDIAN_TO_HOST_INT16(creation_time); }
128 			uint16 CreationDate() const
129 				{ return B_LENDIAN_TO_HOST_INT16(creation_date); }
130 			uint16 Attribs() const
131 				{ return B_LENDIAN_TO_HOST_INT16(attribs); }
132 			void SetAttribs(uint16 newAttribs)
133 				{ attribs = B_HOST_TO_LENDIAN_INT16(newAttribs); }
134 		} _PACKED file;
135 		struct {
136 			uint8 flag;
137 			uint8 reserved;
138 			uint8 name_length;
139 			uint16 name_hash;
140 			uint8 reserved2[2];
141 			uint64 size1;
142 			uint8 reserved3[4];
143 			uint32 start_cluster;
144 			uint64 size2;
145 			uint32 StartCluster() const
146 				{ return B_LENDIAN_TO_HOST_INT32(start_cluster); }
147 			void SetStartCluster(uint32 startCluster)
148 				{ start_cluster = B_HOST_TO_LENDIAN_INT32(startCluster); }
149 			bool IsContiguous() const
150 				{ return (flag & EXFAT_ENTRY_FLAG_CONTIGUOUS) != 0; }
151 			void SetFlag(uint8 newFlag)
152 				{ flag = newFlag; }
153 			uint64 Size() const
154 				{ return B_LENDIAN_TO_HOST_INT64(size1); }
155 		} _PACKED file_info;
156 	};
157 } _PACKED;
158 
159 
160 struct file_cookie {
161 	bigtime_t	last_notification;
162 	off_t		last_size;
163 	int			open_mode;
164 };
165 
166 #define EXFAT_OPEN_MODE_USER_MASK		0x7fffffff
167 
168 extern fs_volume_ops gExfatVolumeOps;
169 extern fs_vnode_ops gExfatVnodeOps;
170 
171 #endif	// EXFAT_H
172