194663Sscottl/*-
294663Sscottl * Copyright (c) 2001, 2002 Scott Long <scottl@freebsd.org>
394663Sscottl * All rights reserved.
494663Sscottl *
594663Sscottl * Redistribution and use in source and binary forms, with or without
694663Sscottl * modification, are permitted provided that the following conditions
794663Sscottl * are met:
894663Sscottl * 1. Redistributions of source code must retain the above copyright
994663Sscottl *    notice, this list of conditions and the following disclaimer.
1094663Sscottl * 2. Redistributions in binary form must reproduce the above copyright
1194663Sscottl *    notice, this list of conditions and the following disclaimer in the
1294663Sscottl *    documentation and/or other materials provided with the distribution.
1394663Sscottl *
1494663Sscottl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1594663Sscottl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1694663Sscottl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1794663Sscottl * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1894663Sscottl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1994663Sscottl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2094663Sscottl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2194663Sscottl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2294663Sscottl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2394663Sscottl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2494663Sscottl * SUCH DAMAGE.
2594663Sscottl *
2694663Sscottl * $FreeBSD$
2794663Sscottl */
2894663Sscottl
2994663Sscottl/* ecma167-udf.h */
3094663Sscottl/* Structure/definitions/constants a la ECMA 167 rev. 3 */
3194663Sscottl
3294663Sscottl/* Tag identifiers */
3394663Sscottlenum {
3494663Sscottl	TAGID_PRI_VOL =		1,
3594663Sscottl	TAGID_ANCHOR =		2,
3694663Sscottl	TAGID_VOL = 		3,
3794663Sscottl	TAGID_IMP_VOL =		4,
3894663Sscottl	TAGID_PARTITION =	5,
3994663Sscottl	TAGID_LOGVOL =		6,
4094663Sscottl	TAGID_UNALLOC_SPACE =	7,
4194663Sscottl	TAGID_TERM =		8,
4294663Sscottl	TAGID_LOGVOL_INTEGRITY = 9,
4394663Sscottl	TAGID_FSD =		256,
4494663Sscottl	TAGID_FID =		257,
4594663Sscottl	TAGID_FENTRY =		261
4694663Sscottl};
4794663Sscottl
4894663Sscottl/* Descriptor tag [3/7.2] */
4994663Sscottlstruct desc_tag {
5094795Sasmodai	uint16_t	id;
5194795Sasmodai	uint16_t	descriptor_ver;
5294795Sasmodai	uint8_t		cksum;
5394795Sasmodai	uint8_t		reserved;
5494795Sasmodai	uint16_t	serial_num;
5594795Sasmodai	uint16_t	desc_crc;
5694795Sasmodai	uint16_t	desc_crc_len;
5794795Sasmodai	uint32_t	tag_loc;
58103870Salfred} __packed;
5994663Sscottl
6094663Sscottl/* Recorded Address [4/7.1] */
6194663Sscottlstruct lb_addr {
6294795Sasmodai	uint32_t	lb_num;
6394795Sasmodai	uint16_t	part_num;
64103870Salfred} __packed;
6594663Sscottl
6694663Sscottl/* Extent Descriptor [3/7.1] */
6794663Sscottlstruct extent_ad {
6894795Sasmodai	uint32_t	len;
6994795Sasmodai	uint32_t	loc;
70103870Salfred} __packed;
7194663Sscottl
7294663Sscottl/* Short Allocation Descriptor [4/14.14.1] */
7394663Sscottlstruct short_ad {
7494795Sasmodai	uint32_t	len;
7594795Sasmodai	uint32_t	pos;
76103870Salfred} __packed;
7794663Sscottl
7894663Sscottl/* Long Allocation Descriptor [4/14.14.2] */
7994663Sscottlstruct long_ad {
8094795Sasmodai	uint32_t	len;
8194663Sscottl	struct lb_addr	loc;
8294795Sasmodai	uint16_t	ad_flags;
8394795Sasmodai	uint32_t	ad_id;
84103870Salfred} __packed;
8594663Sscottl
8694663Sscottl/* Extended Allocation Descriptor [4/14.14.3] */
8794663Sscottlstruct ext_ad {
8894795Sasmodai	uint32_t	ex_len;
8994795Sasmodai	uint32_t	rec_len;
9094795Sasmodai	uint32_t	inf_len;
9194663Sscottl	struct lb_addr	ex_loc;
9294795Sasmodai	uint8_t		reserved[2];
93103870Salfred} __packed;
9494663Sscottl
9594663Sscottlunion icb {
9694663Sscottl	struct short_ad	s_ad;
9794663Sscottl	struct long_ad	l_ad;
9894663Sscottl	struct ext_ad	e_ad;
9994663Sscottl};
10094663Sscottl
10194663Sscottl/* Character set spec [1/7.2.1] */
10294663Sscottlstruct charspec {
10394795Sasmodai	uint8_t		type;
10494795Sasmodai	uint8_t		inf[63];
105103870Salfred} __packed;
10694663Sscottl
10794663Sscottl/* Timestamp [1/7.3] */
10894663Sscottlstruct timestamp {
10994795Sasmodai	uint16_t	type_tz;
11094795Sasmodai	uint16_t	year;
11194795Sasmodai	uint8_t		month;
11294795Sasmodai	uint8_t		day;
11394795Sasmodai	uint8_t		hour;
11494795Sasmodai	uint8_t		minute;
11594795Sasmodai	uint8_t		second;
11694795Sasmodai	uint8_t		centisec;
11794795Sasmodai	uint8_t		hund_usec;
11894795Sasmodai	uint8_t		usec;
119103870Salfred} __packed;
12094663Sscottl
12194663Sscottl/* Entity Identifier [1/7.4] */
12294663Sscottl#define	UDF_REGID_ID_SIZE	23
12394663Sscottlstruct regid {
12494795Sasmodai	uint8_t		flags;
12594795Sasmodai	uint8_t		id[UDF_REGID_ID_SIZE];
12694795Sasmodai	uint8_t		id_suffix[8];
127103870Salfred} __packed;
12894663Sscottl
12994663Sscottl/* ICB Tag [4/14.6] */
13094663Sscottlstruct icb_tag {
13194795Sasmodai	uint32_t	prev_num_dirs;
13294795Sasmodai	uint16_t	strat_type;
13394795Sasmodai	uint8_t		strat_param[2];
13494795Sasmodai	uint16_t	max_num_entries;
13594795Sasmodai	uint8_t		reserved;
13694795Sasmodai	uint8_t		file_type;
13794663Sscottl	struct lb_addr	parent_icb;
13894795Sasmodai	uint16_t	flags;
139103870Salfred} __packed;
14094663Sscottl#define	UDF_ICB_TAG_FLAGS_SETUID	0x40
14194663Sscottl#define	UDF_ICB_TAG_FLAGS_SETGID	0x80
14294663Sscottl#define	UDF_ICB_TAG_FLAGS_STICKY	0x100
14394663Sscottl
14494663Sscottl/* Anchor Volume Descriptor Pointer [3/10.2] */
14594663Sscottlstruct anchor_vdp {
14694663Sscottl	struct desc_tag		tag;
14794663Sscottl	struct extent_ad	main_vds_ex;
14894663Sscottl	struct extent_ad	reserve_vds_ex;
149103870Salfred} __packed;
15094663Sscottl
15194663Sscottl/* Volume Descriptor Pointer [3/10.3] */
15294663Sscottlstruct vol_desc_ptr {
15394663Sscottl	struct desc_tag		tag;
15494795Sasmodai	uint32_t		vds_number;
15594663Sscottl	struct extent_ad	next_vds_ex;
156103870Salfred} __packed;
15794663Sscottl
15894663Sscottl/* Primary Volume Descriptor [3/10.1] */
15994663Sscottlstruct pri_vol_desc {
16094663Sscottl	struct desc_tag		tag;
16194795Sasmodai	uint32_t		seq_num;
16294795Sasmodai	uint32_t		pdv_num;
16394663Sscottl	char			vol_id[32];
16494795Sasmodai	uint16_t		vds_num;
16594795Sasmodai	uint16_t		max_vol_seq;
16694795Sasmodai	uint16_t		ichg_lvl;
16794795Sasmodai	uint16_t		max_ichg_lvl;
16894795Sasmodai	uint32_t		charset_list;
16994795Sasmodai	uint32_t		max_charset_list;
17094663Sscottl	char			volset_id[128];
17194663Sscottl	struct charspec		desc_charset;
17294663Sscottl	struct charspec		explanatory_charset;
17394663Sscottl	struct extent_ad	vol_abstract;
17494663Sscottl	struct extent_ad	vol_copyright;
17594663Sscottl	struct regid		app_id;
17694663Sscottl	struct timestamp	time;
17794663Sscottl	struct regid		imp_id;
17894795Sasmodai	uint8_t			imp_use[64];
17994795Sasmodai	uint32_t		prev_vds_lov;
18094795Sasmodai	uint16_t		flags;
18194795Sasmodai	uint8_t			reserved[22];
182103870Salfred} __packed;
18394663Sscottl
18494663Sscottl/* Logical Volume Descriptor [3/10.6] */
18594663Sscottlstruct logvol_desc {
18694663Sscottl	struct desc_tag		tag;
18794795Sasmodai	uint32_t		seq_num;
18894663Sscottl	struct charspec		desc_charset;
18994663Sscottl	char			logvol_id[128];
19094795Sasmodai	uint32_t		lb_size;
19194663Sscottl	struct regid		domain_id;
19294663Sscottl	union {
19394663Sscottl		struct long_ad	fsd_loc;
19494795Sasmodai		uint8_t		logvol_content_use[16];
19594663Sscottl	} _lvd_use;
19694795Sasmodai	uint32_t		mt_l; /* Partition map length */
19794795Sasmodai	uint32_t		n_pm; /* Number of partition maps */
19894663Sscottl	struct regid		imp_id;
19994795Sasmodai	uint8_t			imp_use[128];
20094663Sscottl	struct extent_ad	integrity_seq_id;
20194795Sasmodai	uint8_t			maps[1];
202103870Salfred} __packed;
20394663Sscottl
20494663Sscottl/* Type 1 Partition Map [3/10.7.2] */
20594663Sscottlstruct part_map_1 {
20694795Sasmodai	uint8_t			type;
20794795Sasmodai	uint8_t			len;
20894795Sasmodai	uint16_t		vol_seq_num;
20994795Sasmodai	uint16_t		part_num;
210103870Salfred} __packed;
21194663Sscottl
212160664Syar#define	UDF_PMAP_TYPE1_SIZE	6
213160664Syar
21494663Sscottl/* Type 2 Partition Map [3/10.7.3] */
21594663Sscottlstruct part_map_2 {
21694795Sasmodai	uint8_t			type;
21794795Sasmodai	uint8_t			len;
21894795Sasmodai	uint8_t			part_id[62];
219103870Salfred} __packed;
22094663Sscottl
221160664Syar#define	UDF_PMAP_TYPE2_SIZE	64
222160664Syar
22394663Sscottl/* Virtual Partition Map [UDF 2.01/2.2.8] */
22494663Sscottlstruct part_map_virt {
22594795Sasmodai	uint8_t			type;
22694795Sasmodai	uint8_t			len;
22794795Sasmodai	uint8_t			reserved[2];
22894663Sscottl	struct regid		id;
22994795Sasmodai	uint16_t		vol_seq_num;
23094795Sasmodai	uint16_t		part_num;
23194795Sasmodai	uint8_t			reserved1[24];
232103870Salfred} __packed;
23394663Sscottl
23494663Sscottl/* Sparable Partition Map [UDF 2.01/2.2.9] */
23594663Sscottlstruct part_map_spare {
23694795Sasmodai	uint8_t			type;
23794795Sasmodai	uint8_t			len;
23894795Sasmodai	uint8_t			reserved[2];
23994663Sscottl	struct regid		id;
24094795Sasmodai	uint16_t		vol_seq_num;
24194795Sasmodai	uint16_t		part_num;
24294795Sasmodai	uint16_t		packet_len;
24394795Sasmodai	uint8_t			n_st;	/* Number of Sparing Tables */
24494795Sasmodai	uint8_t			reserved1;
24594795Sasmodai	uint32_t		st_size;
24694795Sasmodai	uint32_t		st_loc[1];
247103870Salfred} __packed;
24894663Sscottl
24994663Sscottlunion udf_pmap {
25094663Sscottl	struct part_map_1	pm1;
25194663Sscottl	struct part_map_2	pm2;
25294663Sscottl	struct part_map_virt	pmv;
25394663Sscottl	struct part_map_spare	pms;
25494663Sscottl};
25594663Sscottl
25694663Sscottl/* Sparing Map Entry [UDF 2.01/2.2.11] */
25794663Sscottlstruct spare_map_entry {
25894795Sasmodai	uint32_t		org;
25994795Sasmodai	uint32_t		map;
260103870Salfred} __packed;
26194663Sscottl
26294663Sscottl/* Sparing Table [UDF 2.01/2.2.11] */
26394663Sscottlstruct udf_sparing_table {
26494663Sscottl	struct desc_tag		tag;
26594663Sscottl	struct regid		id;
26694795Sasmodai	uint16_t		rt_l;	/* Relocation Table len */
26794795Sasmodai	uint8_t			reserved[2];
26894795Sasmodai	uint32_t		seq_num;
26994663Sscottl	struct spare_map_entry	entries[1];
270103870Salfred} __packed;
27194663Sscottl
27294663Sscottl/* Partition Descriptor [3/10.5] */
27394663Sscottlstruct part_desc {
27494663Sscottl	struct desc_tag	tag;
27594795Sasmodai	uint32_t	seq_num;
27694795Sasmodai	uint16_t	flags;
27794795Sasmodai	uint16_t	part_num;
27894663Sscottl	struct regid	contents;
27994795Sasmodai	uint8_t		contents_use[128];
28094795Sasmodai	uint32_t	access_type;
28194795Sasmodai	uint32_t	start_loc;
28294795Sasmodai	uint32_t	part_len;
28394663Sscottl	struct regid	imp_id;
28494795Sasmodai	uint8_t		imp_use[128];
28594795Sasmodai	uint8_t		reserved[156];
286103870Salfred} __packed;
28794663Sscottl
28894663Sscottl/* File Set Descriptor [4/14.1] */
28994663Sscottlstruct fileset_desc {
29094663Sscottl	struct desc_tag		tag;
29194663Sscottl	struct timestamp	time;
29294795Sasmodai	uint16_t		ichg_lvl;
29394795Sasmodai	uint16_t		max_ichg_lvl;
29494795Sasmodai	uint32_t		charset_list;
29594795Sasmodai	uint32_t		max_charset_list;
29694795Sasmodai	uint32_t		fileset_num;
29794795Sasmodai	uint32_t		fileset_desc_num;
29894663Sscottl	struct charspec		logvol_id_charset;
29994663Sscottl	char			logvol_id[128];
30094663Sscottl	struct charspec		fileset_charset;
30194663Sscottl	char			fileset_id[32];
30294663Sscottl	char			copyright_file_id[32];
30394663Sscottl	char			abstract_file_id[32];
30494663Sscottl	struct long_ad		rootdir_icb;
30594663Sscottl	struct regid		domain_id;
30694663Sscottl	struct long_ad		next_ex;
30794663Sscottl	struct long_ad		streamdir_icb;
30894795Sasmodai	uint8_t			reserved[32];
309103870Salfred} __packed;
31094663Sscottl
31194663Sscottl/* File Identifier Descriptor [4/14.4] */
31294663Sscottlstruct fileid_desc {
31394663Sscottl	struct desc_tag	tag;
31494795Sasmodai	uint16_t	file_num;
31594795Sasmodai	uint8_t		file_char;
31694795Sasmodai	uint8_t		l_fi;	/* Length of file identifier area */
31794663Sscottl	struct long_ad	icb;
318145072Sbrueffer	uint16_t	l_iu;	/* Length of implementation use area */
31994795Sasmodai	uint8_t		data[1];
320103870Salfred} __packed;
32194663Sscottl#define	UDF_FID_SIZE	38
322101317Sscottl#define	UDF_FILE_CHAR_VIS	(1 << 0) /* Visible */
323101317Sscottl#define	UDF_FILE_CHAR_DIR	(1 << 1) /* Directory */
324101317Sscottl#define	UDF_FILE_CHAR_DEL	(1 << 2) /* Deleted */
325101317Sscottl#define	UDF_FILE_CHAR_PAR	(1 << 3) /* Parent Directory */
326101317Sscottl#define	UDF_FILE_CHAR_META	(1 << 4) /* Stream metadata */
32794663Sscottl
32894663Sscottl/* File Entry [4/14.9] */
32994663Sscottlstruct file_entry {
33094663Sscottl	struct desc_tag		tag;
33194663Sscottl	struct icb_tag		icbtag;
33294795Sasmodai	uint32_t		uid;
33394795Sasmodai	uint32_t		gid;
33494795Sasmodai	uint32_t		perm;
33594795Sasmodai	uint16_t		link_cnt;
33694795Sasmodai	uint8_t			rec_format;
33794795Sasmodai	uint8_t			rec_disp_attr;
33894795Sasmodai	uint32_t		rec_len;
33994795Sasmodai	uint64_t		inf_len;
34094795Sasmodai	uint64_t		logblks_rec;
34194663Sscottl	struct timestamp	atime;
34294663Sscottl	struct timestamp	mtime;
34394663Sscottl	struct timestamp	attrtime;
34494795Sasmodai	uint32_t		ckpoint;
34594663Sscottl	struct long_ad		ex_attr_icb;
34694663Sscottl	struct regid		imp_id;
34794795Sasmodai	uint64_t		unique_id;
34894795Sasmodai	uint32_t		l_ea;	/* Length of extended attribute area */
34994795Sasmodai	uint32_t		l_ad;	/* Length of allocation descriptors */
35094795Sasmodai	uint8_t			data[1];
351103870Salfred} __packed;
35294663Sscottl#define	UDF_FENTRY_SIZE	176
35394663Sscottl#define	UDF_FENTRY_PERM_USER_MASK	0x07
35494663Sscottl#define	UDF_FENTRY_PERM_GRP_MASK	0xE0
35594663Sscottl#define	UDF_FENTRY_PERM_OWNER_MASK	0x1C00
35694663Sscottl
357188251Sjhb/* Path Component [4/14.16.1] */
358188251Sjhbstruct path_component {
359188251Sjhb	uint8_t			type;
360188251Sjhb	uint8_t			length;
361188251Sjhb	uint16_t		version;
362188406Sjhb	uint8_t			identifier[1];
363188251Sjhb} __packed;
364188251Sjhb#define	UDF_PATH_ROOT		2
365188251Sjhb#define	UDF_PATH_DOTDOT		3
366188251Sjhb#define	UDF_PATH_DOT		4
367188251Sjhb#define	UDF_PATH_PATH		5
368188251Sjhb
36994663Sscottlunion dscrptr {
37094663Sscottl	struct desc_tag		tag;
37194663Sscottl	struct anchor_vdp	avdp;
37294663Sscottl	struct vol_desc_ptr	vdp;
37394663Sscottl	struct pri_vol_desc	pvd;
37494663Sscottl	struct logvol_desc	lvd;
37594663Sscottl	struct part_desc	pd;
37694663Sscottl	struct fileset_desc	fsd;
37794663Sscottl	struct fileid_desc	fid;
37894663Sscottl	struct file_entry	fe;
37994663Sscottl};
38094663Sscottl
38194663Sscottl/* Useful defines */
38294663Sscottl
38394663Sscottl#define	GETICB(ad_type, fentry, offset)	\
38494663Sscottl	(struct ad_type *)&fentry->data[offset]
38594663Sscottl
386155256Swill#define	GETICBLEN(ad_type, icb)	le32toh(((struct ad_type *)(icb))->len)
387