3392af3af8014ba715b12969e19e224fd94174b9
[lunaix-os.git] / lunaix-os / includes / lunaix / fs / iso9660.h
1 /**
2  * @file iso9660.h
3  * @author Lunaixsky (zelong56@gmail.com)
4  * @brief ISO9660 File system header file. (Reference: ECMA-119, 4th ed.)
5  * @version 0.1
6  * @date 2022-10-03
7  *
8  * @copyright Copyright (c) 2022
9  *
10  */
11
12 #ifndef __LUNAIX_ISO9660_H
13 #define __LUNAIX_ISO9660_H
14
15 #include <lunaix/clock.h>
16 #include <lunaix/device.h>
17 #include <lunaix/fs.h>
18 #include <lunaix/types.h>
19
20 #define ISO_SIGNATURE_LO 0x30304443UL
21 #define ISO_SIGNATURE_HI 0x31
22
23 // Volume Types
24 #define ISO_VOLBOOT 0   // Boot Record
25 #define ISO_VOLPRIM 1   // Primary
26 #define ISO_VOLSUPP 2   // Supplementary
27 #define ISO_VOLPART 3   // Partition
28 #define ISO_VOLTERM 255 // Volume descriptor set terminator
29
30 #define ISO_FHIDDEN 0x1   // a hidden file
31 #define ISO_FDIR 0x2      // a directory file
32 #define ISO_FASSOC 0x4    // a associated file
33 #define ISO_FRECORD 0x8   // file store in iso record fashion
34 #define ISO_FPROTECT 0x10 // file being protected by access control
35 #define ISO_FEXTENTS 0x80 // the extent by this record is a file partial
36
37 #define ISO9660_BLKSZ 2048
38 #define ISO9660_IDLEN 256
39
40 // NOTES:
41 // Each Descriptor sized 1 logical block (2048 bytes in common cases)
42 // ISO9660 store number in both-byte order. That is, for a d-bits number, it
43 //   will result in 2d bits of storage. The lower d-bits are little-endian and
44 //   upper d-bits are big-endian.
45
46 struct iso_vol
47 {
48     u8_t type;
49     u8_t std_id[5]; // CD001
50     u8_t version;
51 } PACKED;
52
53 struct iso_vol_boot
54 {
55     struct iso_vol header;
56     u8_t sys_id[32];
57     u8_t boot_id[32];
58     u8_t reserved; // align to data line width
59 } PACKED;
60
61 struct iso_datetime
62 {
63     u8_t year[4];
64     u8_t month[2];
65     u8_t day[2];
66     u8_t hour[2];
67     u8_t min[2];
68     u8_t sec[2];
69     u8_t ms[2];
70     u8_t gmt;
71 } PACKED;
72
73 // 32bits both-byte-order integer
74 typedef struct iso_bbo32
75 {
76     u32_t le; // little-endian
77     u32_t be; // big-endian
78 } PACKED iso_bbo32_t;
79
80 // 16bits both-byte-order integer
81 typedef struct iso_bbo16
82 {
83     u16_t le; // little-endian
84     u16_t be; // big-endian
85 } PACKED iso_bbo16_t;
86
87 // (8.4) Describe a primary volume space
88 struct iso_vol_primary
89 {
90     struct iso_vol header;
91     u8_t reserved_1;
92     u8_t sys_id[32];
93     u8_t vol_id[32];
94     u8_t reserved_2[8];
95     iso_bbo32_t vol_size;
96     u8_t reserved_3[32];
97     iso_bbo16_t set_size;
98     iso_bbo16_t seq_num;
99     iso_bbo16_t lb_size;
100     iso_bbo32_t ptable_size;
101     u32_t lpath_tbl_ptr; // Type L Path table location (LBA)
102     u32_t reserved_4[3]; // use type M if big endian machine.
103     u8_t root_record[34];
104     u8_t set_id[128];
105     u8_t publisher_id[128];
106     u8_t preparer_id[128];
107     u8_t app_id[128];
108     u8_t copyright_id[128];
109     u8_t asbtract_id[128];
110     u8_t bib_id[128];
111     struct iso_datetime ctime;   // creation
112     struct iso_datetime mtime;   // modification
113     struct iso_datetime ex_time; // expiration
114     struct iso_datetime ef_time; // effective
115     u8_t fstruct_ver;            // file structure version, don't care!
116 } PACKED;                        // size 1124
117
118 // Layout for Supplementary Vol. is almost identical to primary vol.
119 // We ignore it for now. (see section 8.5, table 6)
120
121 // (8.6) Describe a volume partition within a volume space
122 struct iso_partition
123 {
124     struct iso_vol header;
125     u8_t reserved;
126     u8_t sys_id[32];
127     u8_t part_id[32];
128     iso_bbo32_t part_addr;
129     iso_bbo32_t part_size;
130 } PACKED;
131
132 // (6.10.4) MDU with variable record
133 struct iso_var_mdu
134 {
135     u8_t len;
136     u8_t content[0];
137 } PACKED;
138
139 struct iso_datetime2
140 {
141     u8_t year;
142     u8_t month;
143     u8_t day;
144     u8_t hour;
145     u8_t min;
146     u8_t sec;
147     u8_t gmt;
148 } PACKED;
149
150 // (9.1) Directory Record [Embedded into Variable MDU]
151 struct iso_drecord
152 {
153     u8_t xattr_len;
154     iso_bbo32_t extent_addr;
155     iso_bbo32_t data_size;
156     struct iso_datetime2 PACKED mktime; // Time the record is made, see 9.1.5
157     u8_t flags;
158     u8_t fu_sz;  // size of file unit (FU)
159     u8_t gap_sz; // size of gap if FU is interleaved.
160     iso_bbo16_t vol_seq;
161     struct iso_var_mdu name;
162 } PACKED;
163
164 struct iso_xattr
165 {
166     iso_bbo16_t owner;
167     iso_bbo16_t group;
168     u16_t perm;
169     struct iso_datetime ctime;
170     struct iso_datetime mtime;
171     struct iso_datetime ex_time;
172     struct iso_datetime ef_time;
173     u8_t record_fmt;
174     u8_t record_attr;
175     iso_bbo16_t record_len;
176     u32_t sys_id;
177     u8_t reserved1[64];
178     u8_t version;
179     u8_t len_esc;
180     u8_t reserved2[64];
181     iso_bbo16_t payload_sz;
182     u8_t payload[0];
183     // There is also a escape sequence after payload,
184     // It however marked as optional, hence we ignore it.
185 } PACKED;
186
187 ///
188 /// -------- IEEE P1281 SUSP ---------
189 ///
190
191 #define ISOSU_ER 0x5245
192 #define ISOSU_ST 0x5453
193
194 struct isosu_base
195 {
196     u16_t signature;
197     u8_t length;
198     u8_t version;
199 } PACKED;
200
201 struct isosu_er
202 {
203     struct isosu_base header;
204     u8_t id_len;
205     u8_t des_len;
206     u8_t src_len;
207     u8_t ext_ver;
208     u8_t id_des_src[0];
209 } PACKED;
210
211 ///
212 /// -------- Rock Ridge Extension --------
213 ///
214
215 #define ISORR_PX 0x5850
216 #define ISORR_PN 0x4e50
217 #define ISORR_SL 0x4c53
218 #define ISORR_NM 0x4d4e
219 #define ISORR_TF 0x4654
220
221 #define ISORR_NM_CONT 0x1
222
223 #define ISORR_TF_CTIME 0x1
224 #define ISORR_TF_MTIME 0x2
225 #define ISORR_TF_ATIME 0x4
226 #define ISORR_TF_LONG_FORM 0x80
227
228 struct isorr_px
229 {
230     struct isosu_base header;
231     iso_bbo32_t mode;
232     iso_bbo32_t link;
233     iso_bbo32_t uid;
234     iso_bbo32_t gid;
235     iso_bbo32_t sn;
236 } PACKED;
237
238 struct isorr_pn
239 {
240     struct isosu_base header;
241     iso_bbo32_t dev_hi;
242     iso_bbo32_t dev_lo;
243 } PACKED;
244
245 struct isorr_sl
246 {
247     struct isosu_base header;
248     u8_t flags;
249     char symlink[0];
250 } PACKED;
251
252 struct isorr_nm
253 {
254     struct isosu_base header;
255     u8_t flags;
256     char name[0];
257 } PACKED;
258
259 struct isorr_tf
260 {
261     struct isosu_base header;
262     u8_t flags;
263     char times[0];
264 } PACKED;
265
266 ///
267 /// -------- VFS integration ---------
268 ///
269
270 struct iso_inode
271 {
272     u32_t record_fmt;
273     u32_t fu_size;
274     u32_t gap_size;
275     struct llist_header drecaches;
276 };
277
278 struct iso_drecache
279 {
280     struct llist_header caches;
281     u32_t extent_addr;
282     u32_t data_size;
283     u32_t xattr_len;
284     u32_t fno;
285     u32_t fu_size;
286     u32_t gap_size;
287     u32_t flags;
288     time_t ctime;
289     time_t atime;
290     time_t mtime;
291     struct hstr name;
292     char name_val[ISO9660_IDLEN];
293 };
294
295 struct iso_superblock
296 {
297     u32_t volume_size;
298     u32_t lb_size;
299 };
300
301 struct iso_drecord*
302 iso9660_get_drecord(struct iso_var_mdu* drecord_mdu);
303
304 int
305 iso9660_fill_inode(struct v_inode* inode, struct iso_drecache* dir, int ino);
306
307 time_t
308 iso9660_dt2unix(struct iso_datetime* isodt);
309
310 time_t
311 iso9660_dt22unix(struct iso_datetime2* isodt2);
312
313 void
314 iso9660_init();
315
316 int
317 iso9660_setup_dnode(struct v_dnode* dnode, struct v_inode* inode);
318
319 void
320 iso9660_fill_drecache(struct iso_drecache* cache,
321                       struct iso_drecord* drec,
322                       u32_t len);
323
324 int
325 iso9660_dir_lookup(struct v_inode* this, struct v_dnode* dnode);
326
327 int
328 iso9660_readdir(struct v_file* file, struct dir_context* dctx);
329
330 int
331 iso9660_open(struct v_inode* this, struct v_file* file);
332
333 int
334 iso9660_close(struct v_file* file);
335
336 int
337 iso9660_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
338
339 int
340 iso9660_write(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
341
342 int
343 iso9660_seek(struct v_inode* inode, size_t offset);
344
345 int
346 isorr_parse_px(struct iso_drecache* cache, void* px_start);
347
348 int
349 isorr_parse_nm(struct iso_drecache* cache, void* nm_start);
350
351 int
352 isorr_parse_tf(struct iso_drecache* cache, void* tf_start);
353
354 #endif /* __LUNAIX_ISO9660_H */