feat: (iso9660) implement file read (for both interleaved and non-interleaved mode)
[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/types.h>
18
19 #define ISO_SIGNATURE_LO 0x30304443UL
20 #define ISO_SIGNATURE_HI 0x31
21
22 // Volume Types
23 #define ISO_VOLBOOT 0   // Boot Record
24 #define ISO_VOLPRIM 1   // Primary
25 #define ISO_VOLSUPP 2   // Supplementary
26 #define ISO_VOLPART 3   // Partition
27 #define ISO_VOLTERM 255 // Volume descriptor set terminator
28
29 #define ISO_FHIDDEN 0x1   // a hidden file
30 #define ISO_FDIR 0x2      // a directory file
31 #define ISO_FASSOC 0x4    // a associated file
32 #define ISO_FRECORD 0x8   // file store in iso record fashion
33 #define ISO_FPROTECT 0x10 // file being protected by access control
34 #define ISO_FEXTENTS 0x80 // the extent by this record is a file partial
35
36 #define ISO9660_BLKSZ 2048
37 #define ISO9660_IDLEN 256
38
39 // NOTES:
40 // Each Descriptor sized 1 logical block (2048 bytes in common cases)
41 // ISO9660 store number in both-byte order. That is, for a d-bits number, it
42 //   will result in 2d bits of storage. The lower d-bits are little-endian and
43 //   upper d-bits are big-endian.
44
45 struct iso_vol
46 {
47     u8_t type;
48     u8_t std_id[5]; // CD001
49     u8_t version;
50 } PACKED;
51
52 struct iso_vol_boot
53 {
54     struct iso_vol header;
55     u8_t sys_id[32];
56     u8_t boot_id[32];
57     u8_t reserved; // align to data line width
58 } PACKED;
59
60 struct iso_datetime
61 {
62     u8_t year[4];
63     u8_t month[2];
64     u8_t day[2];
65     u8_t hour[2];
66     u8_t min[2];
67     u8_t sec[2];
68     u8_t ms[2];
69     u8_t gmt;
70 } PACKED;
71
72 // 32bits both-byte-order integer
73 typedef struct iso_bbo32
74 {
75     u32_t le; // little-endian
76     u32_t be; // big-endian
77 } PACKED iso_bbo32_t;
78
79 // 16bits both-byte-order integer
80 typedef struct iso_bbo16
81 {
82     u16_t le; // little-endian
83     u16_t be; // big-endian
84 } PACKED iso_bbo16_t;
85
86 // (8.4) Describe a primary volume space
87 struct iso_vol_primary
88 {
89     struct iso_vol header;
90     u8_t reserved_1;
91     u8_t sys_id[32];
92     u8_t vol_id[32];
93     u8_t reserved_2[8];
94     iso_bbo32_t vol_size;
95     u8_t reserved_3[32];
96     iso_bbo16_t set_size;
97     iso_bbo16_t seq_num;
98     iso_bbo16_t lb_size;
99     iso_bbo32_t ptable_size;
100     u32_t lpath_tbl_ptr; // Type L Path table location (LBA)
101     u32_t reserved_4[3]; // use type M if big endian machine.
102     u8_t root_record[34];
103     u8_t set_id[128];
104     u8_t publisher_id[128];
105     u8_t preparer_id[128];
106     u8_t app_id[128];
107     u8_t copyright_id[128];
108     u8_t asbtract_id[128];
109     u8_t bib_id[128];
110     struct iso_datetime ctime;   // creation
111     struct iso_datetime mtime;   // modification
112     struct iso_datetime ex_time; // expiration
113     struct iso_datetime ef_time; // effective
114     u8_t fstruct_ver;            // file structure version, don't care!
115 } PACKED;                        // size 1124
116
117 // Layout for Supplementary Vol. is almost identical to primary vol.
118 // We ignore it for now. (see section 8.5, table 6)
119
120 // (8.6) Describe a volume partition within a volume space
121 struct iso_partition
122 {
123     struct iso_vol header;
124     u8_t reserved;
125     u8_t sys_id[32];
126     u8_t part_id[32];
127     iso_bbo32_t part_addr;
128     iso_bbo32_t part_size;
129 } PACKED;
130
131 // (6.10.4) MDU with variable record
132 struct iso_var_mdu
133 {
134     u8_t len;
135     u8_t content[0];
136 } PACKED;
137
138 // (9.1) Directory Record [Embedded into Variable MDU]
139 struct iso_drecord
140 {
141     u8_t xattr_len;
142     iso_bbo32_t extent_addr;
143     iso_bbo32_t data_size;
144     struct
145     {
146         u8_t year;
147         u8_t month;
148         u8_t day;
149         u8_t hour;
150         u8_t min;
151         u8_t sec;
152         u8_t gmt;
153     } PACKED mktime; // Time the record is made, see 9.1.5
154     u8_t flags;
155     u8_t fu_sz;  // size of file unit (FU)
156     u8_t gap_sz; // size of gap if FU is interleaved.
157     iso_bbo16_t vol_seq;
158     struct iso_var_mdu name;
159 } PACKED;
160
161 // (9.4) L-Path Table Record. [Embedded into Variable MDU]
162 struct iso_precord
163 {
164     u8_t xattr_len;
165     u32_t extent_addr;
166     u8_t parent; // indexed into path table
167     u8_t id[0];  // length = iso_var_mdu::len
168 } PACKED;
169
170 struct iso_xattr
171 {
172     iso_bbo16_t owner;
173     iso_bbo16_t group;
174     u16_t perm;
175     struct iso_datetime ctime;
176     struct iso_datetime mtime;
177     struct iso_datetime ex_time;
178     struct iso_datetime ef_time;
179     u8_t record_fmt;
180     u8_t record_attr;
181     iso_bbo16_t record_len;
182     u32_t sys_id;
183     u8_t reserved1[64];
184     u8_t version;
185     u8_t len_esc;
186     u8_t reserved2[64];
187     iso_bbo16_t payload_sz;
188     u8_t payload[0];
189     // There is also a escape sequence after payload,
190     // It however marked as optional, hence we ignore it.
191 } PACKED;
192
193 struct iso_ptable
194 {
195     u32_t start_lba;
196     u32_t current_lba;
197     u32_t size;
198     u32_t range_lower;
199     u32_t range_upper;
200     void* ptable_part;
201 };
202
203 struct iso_inode
204 {
205     time_t ctime;
206     time_t mtime;
207     u32_t record_fmt;
208     u32_t fu_size;
209     u32_t gap_size;
210     struct llist_header* drecaches;
211 };
212
213 struct iso_drecache
214 {
215     struct llist_header caches;
216     u32_t extent_addr;
217     u32_t data_size;
218     u32_t xattr_len;
219     u32_t fu_size;
220     u32_t gap_size;
221     u32_t flags;
222     struct hstr name;
223     char name_val[ISO9660_IDLEN];
224 };
225
226 struct iso_superblock
227 {
228     u32_t volume_size;
229     u32_t lb_size;
230 };
231
232 struct iso_drecord*
233 iso9660_get_drecord(struct iso_var_mdu* drecord_mdu);
234
235 int
236 iso9660_fill_inode(struct v_inode* inode, struct iso_drecache* dir, int ino);
237
238 time_t
239 iso9660_dt2unix(struct iso_datetime* isodt);
240
241 void
242 iso9660_init();
243
244 int
245 iso9660_setup_dnode(struct v_dnode* dnode, struct v_inode* inode);
246
247 void
248 iso9660_fill_drecache(struct iso_drecache* cache, struct iso_drecord* drec);
249
250 int
251 iso9660_dir_lookup(struct v_inode* this, struct v_dnode* dnode);
252
253 int
254 iso9660_readdir(struct v_file* file, struct dir_context* dctx);
255
256 int
257 iso9660_open(struct v_inode* this, struct v_file* file);
258
259 int
260 iso9660_close(struct v_file* file);
261
262 int
263 iso9660_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
264
265 int
266 iso9660_write(struct v_inode* inode, void* buffer, size_t len, size_t fpos);
267
268 int
269 iso9660_seek(struct v_inode* inode, size_t offset);
270
271 #endif /* __LUNAIX_ISO9660_H */