X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/baca54322c66983205edecd2ebb00d997878be50..270869139db617e29a35bb9ded41087bb702f9ac:/lunaix-os/kernel/fs/iso9660/iso9660.h diff --git a/lunaix-os/kernel/fs/iso9660/iso9660.h b/lunaix-os/kernel/fs/iso9660/iso9660.h new file mode 100644 index 0000000..708a28a --- /dev/null +++ b/lunaix-os/kernel/fs/iso9660/iso9660.h @@ -0,0 +1,361 @@ +/** + * @file iso9660.h + * @author Lunaixsky (zelong56@gmail.com) + * @brief ISO9660 File system header file. (Reference: ECMA-119, 4th ed.) + * @version 0.1 + * @date 2022-10-03 + * + * @copyright Copyright (c) 2022 + * + */ + +#ifndef __LUNAIX_ISO9660_H +#define __LUNAIX_ISO9660_H + +#include +#include +#include +#include + +#define ISO_SIGNATURE_LO 0x30304443UL +#define ISO_SIGNATURE_HI 0x31 + +// Volume Types +#define ISO_VOLBOOT 0 // Boot Record +#define ISO_VOLPRIM 1 // Primary +#define ISO_VOLSUPP 2 // Supplementary +#define ISO_VOLPART 3 // Partition +#define ISO_VOLTERM 255 // Volume descriptor set terminator + +#define ISO_FHIDDEN 0x1 // a hidden file +#define ISO_FDIR 0x2 // a directory file +#define ISO_FASSOC 0x4 // a associated file +#define ISO_FRECORD 0x8 // file store in iso record fashion +#define ISO_FPROTECT 0x10 // file being protected by access control +#define ISO_FEXTENTS 0x80 // the extent by this record is a file partial + +#define ISO9660_BLKSZ 2048 +#define ISO9660_IDLEN 256 +#define ISO9660_READ_OFF (ISO9660_BLKSZ * 16) + +// NOTES: +// Each Descriptor sized 1 logical block (2048 bytes in common cases) +// ISO9660 store number in both-byte order. That is, for a d-bits number, it +// will result in 2d bits of storage. The lower d-bits are little-endian and +// upper d-bits are big-endian. + +struct iso_vol +{ + u8_t type; + u8_t std_id[5]; // CD001 + u8_t version; +} compact; + +struct iso_vol_boot +{ + struct iso_vol header; + u8_t sys_id[32]; + u8_t boot_id[32]; + u8_t reserved; // align to data line width +} compact; + +struct iso_datetime +{ + u8_t year[4]; + u8_t month[2]; + u8_t day[2]; + u8_t hour[2]; + u8_t min[2]; + u8_t sec[2]; + u8_t ms[2]; + u8_t gmt; +} compact; + +// 32bits both-byte-order integer +typedef struct iso_bbo32 +{ + u32_t le; // little-endian + u32_t be; // big-endian +} compact iso_bbo32_t; + +// 16bits both-byte-order integer +typedef struct iso_bbo16 +{ + u16_t le; // little-endian + u16_t be; // big-endian +} compact iso_bbo16_t; + +// (8.4) Describe a primary volume space +struct iso_vol_primary +{ + struct iso_vol header; + u8_t reserved_1; + u8_t sys_id[32]; + u8_t vol_id[32]; + u8_t reserved_2[8]; + iso_bbo32_t vol_size; + u8_t reserved_3[32]; + iso_bbo16_t set_size; + iso_bbo16_t seq_num; + iso_bbo16_t lb_size; + iso_bbo32_t ptable_size; + u32_t lpath_tbl_ptr; // Type L Path table location (LBA) + u32_t reserved_4[3]; // use type M if big endian machine. + u8_t root_record[34]; + u8_t set_id[128]; + u8_t publisher_id[128]; + u8_t preparer_id[128]; + u8_t app_id[128]; + u8_t copyright_id[128]; + u8_t asbtract_id[128]; + u8_t bib_id[128]; + struct iso_datetime ctime; // creation + struct iso_datetime mtime; // modification + struct iso_datetime ex_time; // expiration + struct iso_datetime ef_time; // effective + u8_t fstruct_ver; // file structure version, don't care! +} compact; // size 1124 + +// Layout for Supplementary Vol. is almost identical to primary vol. +// We ignore it for now. (see section 8.5, table 6) + +// (8.6) Describe a volume partition within a volume space +struct iso_partition +{ + struct iso_vol header; + u8_t reserved; + u8_t sys_id[32]; + u8_t part_id[32]; + iso_bbo32_t part_addr; + iso_bbo32_t part_size; +} compact; + +// (6.10.4) MDU with variable record +struct iso_var_mdu +{ + u8_t len; + u8_t content[0]; +} compact; + +struct iso_datetime2 +{ + u8_t year; + u8_t month; + u8_t day; + u8_t hour; + u8_t min; + u8_t sec; + u8_t gmt; +} compact; + +// (9.1) Directory Record [Embedded into Variable MDU] +struct iso_drecord +{ + u8_t xattr_len; + iso_bbo32_t extent_addr; + iso_bbo32_t data_size; + struct iso_datetime2 mktime; // Time the record is made, see 9.1.5 + u8_t flags; + u8_t fu_sz; // size of file unit (FU) + u8_t gap_sz; // size of gap if FU is interleaved. + iso_bbo16_t vol_seq; + struct iso_var_mdu name; +} compact; + +struct iso_xattr +{ + iso_bbo16_t owner; + iso_bbo16_t group; + u16_t perm; + struct iso_datetime ctime; + struct iso_datetime mtime; + struct iso_datetime ex_time; + struct iso_datetime ef_time; + u8_t record_fmt; + u8_t record_attr; + iso_bbo16_t record_len; + u32_t sys_id; + u8_t reserved1[64]; + u8_t version; + u8_t len_esc; + u8_t reserved2[64]; + iso_bbo16_t payload_sz; + u8_t payload[0]; + // There is also a escape sequence after payload, + // It however marked as optional, hence we ignore it. +} compact; + +/// +/// -------- IEEE P1281 SUSP --------- +/// + +#define ISOSU_ER 0x5245 +#define ISOSU_ST 0x5453 + +struct isosu_base +{ + u16_t signature; + u8_t length; + u8_t version; +} compact; + +struct isosu_er +{ + struct isosu_base header; + u8_t id_len; + u8_t des_len; + u8_t src_len; + u8_t ext_ver; + u8_t id_des_src[0]; +} compact; + +/// +/// -------- Rock Ridge Extension -------- +/// + +#define ISORR_PX 0x5850 +#define ISORR_PN 0x4e50 +#define ISORR_SL 0x4c53 +#define ISORR_NM 0x4d4e +#define ISORR_TF 0x4654 + +#define ISORR_NM_CONT 0x1 + +#define ISORR_TF_CTIME 0x1 +#define ISORR_TF_MTIME 0x2 +#define ISORR_TF_ATIME 0x4 +#define ISORR_TF_LONG_FORM 0x80 + +struct isorr_px +{ + struct isosu_base header; + iso_bbo32_t mode; + iso_bbo32_t link; + iso_bbo32_t uid; + iso_bbo32_t gid; + iso_bbo32_t sn; +} compact; + +struct isorr_pn +{ + struct isosu_base header; + iso_bbo32_t dev_hi; + iso_bbo32_t dev_lo; +} compact; + +struct isorr_sl +{ + struct isosu_base header; + u8_t flags; + char symlink[0]; +} compact; + +struct isorr_nm +{ + struct isosu_base header; + u8_t flags; + char name[0]; +} compact; + +struct isorr_tf +{ + struct isosu_base header; + u8_t flags; + char times[0]; +} compact; + +/// +/// -------- VFS integration --------- +/// + +struct iso_inode +{ + u32_t record_fmt; + u32_t fu_size; + u32_t gap_size; + struct llist_header drecaches; +}; + +struct iso_drecache +{ + struct llist_header caches; + u32_t extent_addr; + u32_t data_size; + u32_t xattr_len; + u32_t fno; + u32_t fu_size; + u32_t gap_size; + u32_t flags; + time_t ctime; + time_t atime; + time_t mtime; + struct hstr name; + char name_val[ISO9660_IDLEN]; +}; + +struct iso_superblock +{ + u32_t volume_size; + u32_t lb_size; +}; + +struct iso_drecord* +iso9660_get_drecord(struct iso_var_mdu* drecord_mdu); + +int +iso9660_fill_inode(struct v_inode* inode, struct iso_drecache* dir, int ino); + +time_t +iso9660_dt2unix(struct iso_datetime* isodt); + +time_t +iso9660_dt22unix(struct iso_datetime2* isodt2); + +void +iso9660_init(); + +int +iso9660_setup_dnode(struct v_dnode* dnode, struct v_inode* inode); + +void +iso9660_fill_drecache(struct iso_drecache* cache, + struct iso_drecord* drec, + u32_t len); + +int +iso9660_dir_lookup(struct v_inode* this, struct v_dnode* dnode); + +int +iso9660_readdir(struct v_file* file, struct dir_context* dctx); + +int +iso9660_open(struct v_inode* this, struct v_file* file); + +int +iso9660_close(struct v_file* file); + +int +iso9660_read(struct v_inode* inode, void* buffer, size_t len, size_t fpos); + +int +iso9660_write(struct v_inode* inode, void* buffer, size_t len, size_t fpos); + +int +iso9660_read_page(struct v_inode* inode, void* buffer, size_t fpos); + +int +iso9660_write_page(struct v_inode* inode, void* buffer, size_t fpos); + +int +iso9660_seek(struct v_file* file, size_t offset); + +int +isorr_parse_px(struct iso_drecache* cache, void* px_start); + +int +isorr_parse_nm(struct iso_drecache* cache, void* nm_start); + +int +isorr_parse_tf(struct iso_drecache* cache, void* tf_start); + +#endif /* __LUNAIX_ISO9660_H */