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