#ifndef _FS_UDF_ECMA167_UDF_H_
#define _FS_UDF_ECMA167_UDF_H_
struct vrs_desc {
uint8_t struct_type;
uint8_t identifier[5];
uint8_t version;
uint8_t data[2041];
} __packed;
#define VRS_NSR02 "NSR02"
#define VRS_NSR03 "NSR03"
#define VRS_BEA01 "BEA01"
#define VRS_TEA01 "TEA01"
#define VRS_CD001 "CD001"
#define VRS_CDW02 "CDW02"
#define MAX_TAGID_VOLUMES 9
enum {
TAGID_SPARING_TABLE = 0,
TAGID_PRI_VOL = 1,
TAGID_ANCHOR = 2,
TAGID_VOL = 3,
TAGID_IMP_VOL = 4,
TAGID_PARTITION = 5,
TAGID_LOGVOL = 6,
TAGID_UNALLOC_SPACE = 7,
TAGID_TERM = 8,
TAGID_LOGVOL_INTEGRITY= 9,
TAGID_FSD = 256,
TAGID_FID = 257,
TAGID_ALLOCEXTENT = 258,
TAGID_INDIRECTENTRY = 259,
TAGID_ICB_TERM = 260,
TAGID_FENTRY = 261,
TAGID_EXTATTR_HDR = 262,
TAGID_UNALL_SP_ENTRY = 263,
TAGID_SPACE_BITMAP = 264,
TAGID_PART_INTEGRITY = 265,
TAGID_EXTFENTRY = 266,
TAGID_MAX = 266
};
enum {
UDF_DOMAIN_FLAG_HARD_WRITE_PROTECT = 1,
UDF_DOMAIN_FLAG_SOFT_WRITE_PROTECT = 2
};
enum {
UDF_ACCESSTYPE_NOT_SPECIFIED = 0,
UDF_ACCESSTYPE_PSEUDO_OVERWITE = 0,
UDF_ACCESSTYPE_READ_ONLY = 1,
UDF_ACCESSTYPE_WRITE_ONCE = 2,
UDF_ACCESSTYPE_REWRITABLE = 3,
UDF_ACCESSTYPE_OVERWRITABLE = 4
};
struct desc_tag {
uint16_t id;
uint16_t descriptor_ver;
uint8_t cksum;
uint8_t reserved;
uint16_t serial_num;
uint16_t desc_crc;
uint16_t desc_crc_len;
uint32_t tag_loc;
} __packed;
#define UDF_DESC_TAG_LENGTH 16
struct lb_addr {
uint32_t lb_num;
uint16_t part_num;
} __packed;
struct extent_ad {
uint32_t len;
uint32_t loc;
} __packed;
struct short_ad {
uint32_t len;
uint32_t lb_num;
} __packed;
struct UDF_ADImp_use {
uint16_t flags;
uint32_t unique_id;
} __packed;
#define UDF_ADIMP_FLAGS_EXTENT_ERASED 1
struct long_ad {
uint32_t len;
struct lb_addr loc;
union {
uint8_t bytes[6];
struct UDF_ADImp_use im_used;
} __packed impl;
} __packed;
#define longad_uniqueid impl.im_used.unique_id
struct ext_ad {
uint32_t ex_len;
uint32_t rec_len;
uint32_t inf_len;
struct lb_addr ex_loc;
uint8_t reserved[2];
} __packed;
union icb {
struct short_ad s_ad;
struct long_ad l_ad;
struct ext_ad e_ad;
} __packed;
#define UDF_EXT_ALLOCATED (0<<30)
#define UDF_EXT_FREED (1<<30)
#define UDF_EXT_ALLOCATED_BUT_NOT_USED (1<<30)
#define UDF_EXT_FREE (2<<30)
#define UDF_EXT_REDIRECT (3<<30)
#define UDF_EXT_FLAGS(len) ((len) & (3<<30))
#define UDF_EXT_LEN(len) ((len) & ((1<<30)-1))
#define UDF_EXT_MAXLEN ((1<<30)-1)
struct charspec {
uint8_t type;
uint8_t inf[63];
} __packed;
struct pathcomp {
uint8_t type;
uint8_t l_ci;
uint16_t comp_filever;
uint8_t ident[256];
} __packed;
#define UDF_PATH_COMP_SIZE 4
#define UDF_PATH_COMP_RESERVED 0
#define UDF_PATH_COMP_ROOT 1
#define UDF_PATH_COMP_MOUNTROOT 2
#define UDF_PATH_COMP_PARENTDIR 3
#define UDF_PATH_COMP_CURDIR 4
#define UDF_PATH_COMP_NAME 5
struct timestamp {
uint16_t type_tz;
uint16_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
uint8_t second;
uint8_t centisec;
uint8_t hund_usec;
uint8_t usec;
} __packed;
#define UDF_TIMESTAMP_SIZE 12
#define UDF_REGID_ID_SIZE 23
struct regid {
uint8_t flags;
uint8_t id[UDF_REGID_ID_SIZE];
uint8_t id_suffix[8];
} __packed;
struct icb_tag {
uint32_t prev_num_dirs;
uint16_t strat_type;
uint8_t strat_param[2];
uint16_t max_num_entries;
uint8_t reserved;
uint8_t file_type;
struct lb_addr parent_icb;
uint16_t flags;
} __packed;
#define UDF_ICB_TAG_FLAGS_ALLOC_MASK 0x03
#define UDF_ICB_SHORT_ALLOC 0x00
#define UDF_ICB_LONG_ALLOC 0x01
#define UDF_ICB_EXT_ALLOC 0x02
#define UDF_ICB_INTERN_ALLOC 0x03
#define UDF_ICB_TAG_FLAGS_DIRORDERED (1<< 3)
#define UDF_ICB_TAG_FLAGS_NONRELOC (1<< 4)
#define UDF_ICB_TAG_FLAGS_CONTIGUOUS (1<< 9)
#define UDF_ICB_TAG_FLAGS_MULTIPLEVERS (1<<12)
#define UDF_ICB_TAG_FLAGS_SETUID (1<< 6)
#define UDF_ICB_TAG_FLAGS_SETGID (1<< 7)
#define UDF_ICB_TAG_FLAGS_STICKY (1<< 8)
#define UDF_ICB_FILETYPE_UNKNOWN 0
#define UDF_ICB_FILETYPE_UNALLOCSPACE 1
#define UDF_ICB_FILETYPE_PARTINTEGRITY 2
#define UDF_ICB_FILETYPE_INDIRECTENTRY 3
#define UDF_ICB_FILETYPE_DIRECTORY 4
#define UDF_ICB_FILETYPE_RANDOMACCESS 5
#define UDF_ICB_FILETYPE_BLOCKDEVICE 6
#define UDF_ICB_FILETYPE_CHARDEVICE 7
#define UDF_ICB_FILETYPE_EXTATTRREC 8
#define UDF_ICB_FILETYPE_FIFO 9
#define UDF_ICB_FILETYPE_SOCKET 10
#define UDF_ICB_FILETYPE_TERM 11
#define UDF_ICB_FILETYPE_SYMLINK 12
#define UDF_ICB_FILETYPE_STREAMDIR 13
#define UDF_ICB_FILETYPE_VAT 248
#define UDF_ICB_FILETYPE_REALTIME 249
#define UDF_ICB_FILETYPE_META_MAIN 250
#define UDF_ICB_FILETYPE_META_MIRROR 251
struct anchor_vdp {
struct desc_tag tag;
struct extent_ad main_vds_ex;
struct extent_ad reserve_vds_ex;
} __packed;
struct vol_desc_ptr {
struct desc_tag tag;
uint32_t vds_number;
struct extent_ad next_vds_ex;
} __packed;
struct pri_vol_desc {
struct desc_tag tag;
uint32_t seq_num;
uint32_t pvd_num;
char vol_id[32];
uint16_t vds_num;
uint16_t max_vol_seq;
uint16_t ichg_lvl;
uint16_t max_ichg_lvl;
uint32_t charset_list;
uint32_t max_charset_list;
char volset_id[128];
struct charspec desc_charset;
struct charspec explanatory_charset;
struct extent_ad vol_abstract;
struct extent_ad vol_copyright;
struct regid app_id;
struct timestamp time;
struct regid imp_id;
uint8_t imp_use[64];
uint32_t prev_vds_loc;
uint16_t flags;
uint8_t reserved[22];
} __packed;
struct udf_lv_info {
struct charspec lvi_charset;
char logvol_id[128];
char lvinfo1[36];
char lvinfo2[36];
char lvinfo3[36];
struct regid impl_id;
uint8_t impl_use[128];
} __packed;
struct impvol_desc {
struct desc_tag tag;
uint32_t seq_num;
struct regid impl_id;
union {
struct udf_lv_info lv_info;
char impl_use[460];
} __packed _impl_use;
} __packed;
struct logvol_desc {
struct desc_tag tag;
uint32_t seq_num;
struct charspec desc_charset;
char logvol_id[128];
uint32_t lb_size;
struct regid domain_id;
union {
struct long_ad fsd_loc;
uint8_t logvol_content_use[16];
} __packed _lvd_use;
uint32_t mt_l;
uint32_t n_pm;
struct regid imp_id;
uint8_t imp_use[128];
struct extent_ad integrity_seq_loc;
uint8_t maps[1];
} __packed;
#define lv_fsd_loc _lvd_use.fsd_loc
#define UDF_INTEGRITY_OPEN 0
#define UDF_INTEGRITY_CLOSED 1
#define UDF_PMAP_SIZE 64
struct part_map_1 {
uint8_t type;
uint8_t len;
uint16_t vol_seq_num;
uint16_t part_num;
} __packed;
struct part_map_2 {
uint8_t type;
uint8_t len;
uint8_t reserved[2];
struct regid part_id;
uint16_t vol_seq_num;
uint16_t part_num;
uint8_t reserved2[24];
} __packed;
struct part_map_virt {
uint8_t type;
uint8_t len;
uint8_t reserved[2];
struct regid id;
uint16_t vol_seq_num;
uint16_t part_num;
uint8_t reserved1[24];
} __packed;
struct part_map_spare {
uint8_t type;
uint8_t len;
uint8_t reserved[2];
struct regid id;
uint16_t vol_seq_num;
uint16_t part_num;
uint16_t packet_len;
uint8_t n_st;
uint8_t reserved1;
uint32_t st_size;
uint32_t st_loc[1];
} __packed;
struct part_map_meta {
uint8_t type;
uint8_t len;
uint8_t reserved[2];
struct regid id;
uint16_t vol_seq_num;
uint16_t part_num;
uint32_t meta_file_lbn;
uint32_t meta_mirror_file_lbn;
uint32_t meta_bitmap_file_lbn;
uint32_t alloc_unit_size;
uint16_t alignment_unit_size;
uint8_t flags;
uint8_t reserved1[5];
} __packed;
#define METADATA_DUPLICATED 1
union udf_pmap {
uint8_t data[UDF_PMAP_SIZE];
struct part_map_1 pm1;
struct part_map_2 pm2;
struct part_map_virt pmv;
struct part_map_spare pms;
struct part_map_meta pmm;
} __packed;
struct spare_map_entry {
uint32_t org;
uint32_t map;
} __packed;
struct udf_sparing_table {
struct desc_tag tag;
struct regid id;
uint16_t rt_l;
uint8_t reserved[2];
uint32_t seq_num;
struct spare_map_entry entries[1];
} __packed;
#define UDF_NO_PREV_VAT 0xffffffff
struct udf_oldvat_tail {
struct regid id;
uint32_t prev_vat;
} __packed;
struct udf_vat {
uint16_t header_len;
uint16_t impl_use_len;
char logvol_id[128];
uint32_t prev_vat;
uint32_t num_files;
uint32_t num_directories;
uint16_t min_udf_readver;
uint16_t min_udf_writever;
uint16_t max_udf_writever;
uint16_t reserved;
uint8_t data[1];
} __packed;
struct space_bitmap_desc {
struct desc_tag tag;
uint32_t num_bits;
uint32_t num_bytes;
uint8_t data[1];
} __packed;
struct space_entry_desc {
struct desc_tag tag;
struct icb_tag icbtag;
uint32_t l_ad;
uint8_t entry[1];
} __packed;
struct part_hdr_desc {
struct short_ad unalloc_space_table;
struct short_ad unalloc_space_bitmap;
struct short_ad part_integrity_table;
struct short_ad freed_space_table;
struct short_ad freed_space_bitmap;
uint8_t reserved[88];
} __packed;
struct part_desc {
struct desc_tag tag;
uint32_t seq_num;
uint16_t flags;
uint16_t part_num;
struct regid contents;
union {
struct part_hdr_desc part_hdr;
uint8_t contents_use[128];
} _impl_use;
uint32_t access_type;
uint32_t start_loc;
uint32_t part_len;
struct regid imp_id;
uint8_t imp_use[128];
uint8_t reserved[156];
} __packed;
#define pd_part_hdr _impl_use.part_hdr
#define UDF_PART_FLAG_ALLOCATED 1
struct unalloc_sp_desc {
struct desc_tag tag;
uint32_t seq_num;
uint32_t alloc_desc_num;
struct extent_ad alloc_desc[1];
} __packed;
struct logvolhdr {
uint64_t next_unique_id;
} __packed;
struct udf_logvol_info {
struct regid impl_id;
uint32_t num_files;
uint32_t num_directories;
uint16_t min_udf_readver;
uint16_t min_udf_writever;
uint16_t max_udf_writever;
} __packed;
struct logvol_int_desc {
struct desc_tag tag;
struct timestamp time;
uint32_t integrity_type;
struct extent_ad next_extent;
union {
struct logvolhdr logvolhdr;
int8_t reserved[32];
} __packed _impl_use;
uint32_t num_part;
uint32_t l_iu;
uint32_t tables[1];
} __packed;
#define lvint_next_unique_id _impl_use.logvolhdr.next_unique_id
struct fileset_desc {
struct desc_tag tag;
struct timestamp time;
uint16_t ichg_lvl;
uint16_t max_ichg_lvl;
uint32_t charset_list;
uint32_t max_charset_list;
uint32_t fileset_num;
uint32_t fileset_desc_num;
struct charspec logvol_id_charset;
char logvol_id[128];
struct charspec fileset_charset;
char fileset_id[32];
char copyright_file_id[32];
char abstract_file_id[32];
struct long_ad rootdir_icb;
struct regid domain_id;
struct long_ad next_ex;
struct long_ad streamdir_icb;
uint8_t reserved[32];
} __packed;
struct fileid_desc {
struct desc_tag tag;
uint16_t file_version_num;
uint8_t file_char;
uint8_t l_fi;
struct long_ad icb;
uint16_t l_iu;
uint8_t data[0];
} __packed;
#define UDF_FID_SIZE 38
#define UDF_FILE_CHAR_VIS (1 << 0)
#define UDF_FILE_CHAR_DIR (1 << 1)
#define UDF_FILE_CHAR_DEL (1 << 2)
#define UDF_FILE_CHAR_PAR (1 << 3)
#define UDF_FILE_CHAR_META (1 << 4)
struct extattrhdr_desc {
struct desc_tag tag;
uint32_t impl_attr_loc;
uint32_t appl_attr_loc;
} __packed;
#define UDF_IMPL_ATTR_LOC_NOT_PRESENT 0xffffffff
#define UDF_APPL_ATTR_LOC_NOT_PRESENT 0xffffffff
struct extattr_entry {
uint32_t type;
uint8_t subtype;
uint8_t reserved[3];
uint32_t a_l;
} __packed;
struct impl_extattr_entry {
struct extattr_entry hdr;
uint32_t iu_l;
struct regid imp_id;
uint8_t data[1];
} __packed;
struct appl_extattr_entry {
struct extattr_entry hdr;
uint32_t au_l;
struct regid appl_id;
uint8_t data[1];
} __packed;
struct filetimes_extattr_entry {
struct extattr_entry hdr;
uint32_t d_l;
uint32_t existence;
struct timestamp times[1];
} __packed;
#define UDF_FILETIMES_ATTR_NO 5
#define UDF_FILETIMES_FILE_CREATION 1
#define UDF_FILETIMES_FILE_DELETION 4
#define UDF_FILETIMES_FILE_EFFECTIVE 8
#define UDF_FILETIMES_FILE_BACKUPED 16
#define UDF_FILETIMES_ATTR_SIZE(no) (20 + (no)*sizeof(struct timestamp))
struct device_extattr_entry {
struct extattr_entry hdr;
uint32_t iu_l;
uint32_t major;
uint32_t minor;
uint8_t data[1];
} __packed;
#define UDF_DEVICESPEC_ATTR_NO 12
struct vatlvext_extattr_entry {
uint64_t unique_id_chk;
uint32_t num_files;
uint32_t num_directories;
char logvol_id[128];
} __packed;
struct file_entry {
struct desc_tag tag;
struct icb_tag icbtag;
uint32_t uid;
uint32_t gid;
uint32_t perm;
uint16_t link_cnt;
uint8_t rec_format;
uint8_t rec_disp_attr;
uint32_t rec_len;
uint64_t inf_len;
uint64_t logblks_rec;
struct timestamp atime;
struct timestamp mtime;
struct timestamp attrtime;
uint32_t ckpoint;
struct long_ad ex_attr_icb;
struct regid imp_id;
uint64_t unique_id;
uint32_t l_ea;
uint32_t l_ad;
uint8_t data[1];
} __packed;
#define UDF_FENTRY_SIZE 176
#define UDF_FENTRY_PERM_USER_MASK 0x07
#define UDF_FENTRY_PERM_GRP_MASK 0xE0
#define UDF_FENTRY_PERM_OWNER_MASK 0x1C00
struct extfile_entry {
struct desc_tag tag;
struct icb_tag icbtag;
uint32_t uid;
uint32_t gid;
uint32_t perm;
uint16_t link_cnt;
uint8_t rec_format;
uint8_t rec_disp_attr;
uint32_t rec_len;
uint64_t inf_len;
uint64_t obj_size;
uint64_t logblks_rec;
struct timestamp atime;
struct timestamp mtime;
struct timestamp ctime;
struct timestamp attrtime;
uint32_t ckpoint;
uint32_t reserved1;
struct long_ad ex_attr_icb;
struct long_ad streamdir_icb;
struct regid imp_id;
uint64_t unique_id;
uint32_t l_ea;
uint32_t l_ad;
uint8_t data[1];
} __packed;
#define UDF_EXTFENTRY_SIZE 216
struct indirect_entry {
struct desc_tag tag;
struct icb_tag icbtag;
struct long_ad indirect_icb;
} __packed;
struct alloc_ext_entry {
struct desc_tag tag;
uint32_t prev_entry;
uint32_t l_ad;
uint8_t data[1];
} __packed;
union dscrptr {
struct desc_tag tag;
struct anchor_vdp avdp;
struct vol_desc_ptr vdp;
struct pri_vol_desc pvd;
struct logvol_desc lvd;
struct unalloc_sp_desc usd;
struct logvol_int_desc lvid;
struct impvol_desc ivd;
struct part_desc pd;
struct fileset_desc fsd;
struct fileid_desc fid;
struct file_entry fe;
struct extfile_entry efe;
struct extattrhdr_desc eahd;
struct indirect_entry inde;
struct alloc_ext_entry aee;
struct udf_sparing_table spt;
struct space_bitmap_desc sbd;
struct space_entry_desc sed;
} __packed;
#define GETICB(ad_type, fentry, offset) \
(struct ad_type *)&fentry->data[offset]
#define GETICBLEN(ad_type, icb) letoh32(((struct ad_type *)(icb))->len)
#endif