1c530d46cSJérôme Duval/*
2c530d46cSJérôme Duval * Copyright 2012, J��r��me Duval, korli@users.berlios.de.
3c530d46cSJérôme Duval * Copyright (c) 2003 Tyler Dauwalder, tyler@dauwalder.net
4c530d46cSJérôme Duval * This file may be used under the terms of the MIT License.
5c530d46cSJérôme Duval */
61a2f87c1STyler Dauwalder#ifndef _UDF_DISK_STRUCTURES_H
71a2f87c1STyler Dauwalder#define _UDF_DISK_STRUCTURES_H
81a2f87c1STyler Dauwalder
9fbdfed81STyler Dauwalder#include <string.h>
10fbdfed81STyler Dauwalder
11fbdfed81STyler Dauwalder#include <ByteOrder.h>
121a2f87c1STyler Dauwalder#include <SupportDefs.h>
131a2f87c1STyler Dauwalder
14fbdfed81STyler Dauwalder#include "UdfDebug.h"
1520d84995SRene Gollent#include "Utils.h"
161a2f87c1STyler Dauwalder
1756f47960STyler Dauwalder#include "Array.h"
1856f47960STyler Dauwalder
19c21aaa8aSTyler Dauwalder/*! \file UdfStructures.h
201a2f87c1STyler Dauwalder
21edd2334cSTyler Dauwalder	\brief UDF on-disk data structure declarations
22edd2334cSTyler Dauwalder
23edd2334cSTyler Dauwalder	UDF is a specialization of the ECMA-167 standard. For the most part,
24edd2334cSTyler Dauwalder	ECMA-167 structures are used by UDF with special restrictions. In a
25edd2334cSTyler Dauwalder	few instances, UDF introduces its own structures to augment those
26edd2334cSTyler Dauwalder	supplied by ECMA-167; those structures are clearly marked.
27edd2334cSTyler Dauwalder
28edd2334cSTyler Dauwalder	For UDF info: <a href='http://www.osta.org'>http://www.osta.org</a>
29edd2334cSTyler Dauwalder	For ECMA info: <a href='http://www.ecma-international.org'>http://www.ecma-international.org</a>
30edd2334cSTyler Dauwalder
31d0da9166STyler Dauwalder	For lack of a better place to store this info, the structures that
32d0da9166STyler Dauwalder	are allowed to have length greater than the logical block size are
33d0da9166STyler Dauwalder	as follows (other length restrictions may be found in UDF-2.01 5.1):
341379cacaSTyler Dauwalder	- \c logical_volume_descriptor
351379cacaSTyler Dauwalder	- \c unallocated_space_descriptor
361379cacaSTyler Dauwalder	- \c logical_volume_integrity_descriptor
371379cacaSTyler Dauwalder	- \c space_bitmap_descriptor
38edd2334cSTyler Dauwalder
39267fd7e7STyler Dauwalder	Other links of interest:
40267fd7e7STyler Dauwalder	- <a href='http://www.extra.research.philips.com/udf/'>Philips UDF verifier</a>
41928e0500STyler Dauwalder	- <a href='http://www.hi-ho.ne.jp/y-komachi/committees/fpro/fpro.htm'>Possible test disc image generator (?)</a>
421a2f87c1STyler Dauwalder*/
431a2f87c1STyler Dauwalder
44edd2334cSTyler Dauwalder//----------------------------------------------------------------------
45edd2334cSTyler Dauwalder// ECMA-167 Part 1
46edd2334cSTyler Dauwalder//----------------------------------------------------------------------
47edd2334cSTyler Dauwalder
48edd2334cSTyler Dauwalder/*! \brief Character set specifications
49edd2334cSTyler Dauwalder
50edd2334cSTyler Dauwalder	The character_set_info field shall be set to the ASCII string
51edd2334cSTyler Dauwalder	"OSTA Compressed Unicode" (padded right with NULL chars).
52edd2334cSTyler Dauwalder
53edd2334cSTyler Dauwalder	See also: ECMA 167 1/7.2.1, UDF-2.01 2.1.2
54edd2334cSTyler Dauwalder*/
551379cacaSTyler Dauwalderstruct charspec {
56fbdfed81STyler Dauwalderpublic:
571801834fSTyler Dauwalder	charspec(uint8 type = 0, const char *info = NULL);
581801834fSTyler Dauwalder
59d5366ff7STyler Dauwalder	void dump() const;
60fbdfed81STyler Dauwalder
61fbdfed81STyler Dauwalder	uint8 character_set_type() const { return _character_set_type; }
62fbdfed81STyler Dauwalder	const char* character_set_info() const { return _character_set_info; }
63fbdfed81STyler Dauwalder	char* character_set_info() { return _character_set_info; }
64fbdfed81STyler Dauwalder
651801834fSTyler Dauwalder	void set_character_set_type(uint8 type) { _character_set_type = type; }
661801834fSTyler Dauwalder	void set_character_set_info(const char *info);
67fbdfed81STyler Dauwalderprivate:
68fbdfed81STyler Dauwalder	uint8 _character_set_type;	//!< to be set to 0 to indicate CS0
69fbdfed81STyler Dauwalder	char _character_set_info[63];	//!< "OSTA Compressed Unicode"
70edd2334cSTyler Dauwalder} __attribute__((packed));
71edd2334cSTyler Dauwalder
721801834fSTyler Dauwalderextern const charspec kCs0CharacterSet;
73edd2334cSTyler Dauwalder
74edd2334cSTyler Dauwalder/*! \brief Date and time stamp
75edd2334cSTyler Dauwalder
76edd2334cSTyler Dauwalder	See also: ECMA 167 1/7.3, UDF-2.01 2.1.4
77edd2334cSTyler Dauwalder*/
781379cacaSTyler Dauwalderclass timestamp {
79fbdfed81STyler Dauwalderprivate:
80fbdfed81STyler Dauwalder	union type_and_timezone_accessor {
81edd2334cSTyler Dauwalder		uint16 type_and_timezone;
82fbdfed81STyler Dauwalder		struct {
8310186d5dSTyler Dauwalder			uint16 timezone:12,
8410186d5dSTyler Dauwalder			       type:4;
85fbdfed81STyler Dauwalder		} bits;
86edd2334cSTyler Dauwalder	};
87fbdfed81STyler Dauwalder
88fbdfed81STyler Dauwalderpublic:
899b438e89STyler Dauwalder	timestamp() { _clear(); }
909b438e89STyler Dauwalder	timestamp(time_t time);
919b438e89STyler Dauwalder
92d5366ff7STyler Dauwalder	void dump() const;
93fbdfed81STyler Dauwalder
94fbdfed81STyler Dauwalder	// Get functions
95fbdfed81STyler Dauwalder	uint16 type_and_timezone() const { return B_LENDIAN_TO_HOST_INT16(_type_and_timezone); }
96fbdfed81STyler Dauwalder	uint8 type() const {
97fbdfed81STyler Dauwalder		type_and_timezone_accessor t;
98fbdfed81STyler Dauwalder		t.type_and_timezone = type_and_timezone();
99fbdfed81STyler Dauwalder		return t.bits.type;
100fbdfed81STyler Dauwalder	}
10183d7be1cSTyler Dauwalder	int16 timezone() const {
102fbdfed81STyler Dauwalder		type_and_timezone_accessor t;
103fbdfed81STyler Dauwalder		t.type_and_timezone = type_and_timezone();
1049b438e89STyler Dauwalder		int16 result = t.bits.timezone;
1059b438e89STyler Dauwalder		// Fill the lefmost bits with ones if timezone is negative
1069b438e89STyler Dauwalder		result <<= 4;
1079b438e89STyler Dauwalder		result >>= 4;
1089b438e89STyler Dauwalder		return result;
109fbdfed81STyler Dauwalder	}
110fbdfed81STyler Dauwalder	uint16 year() const { return B_LENDIAN_TO_HOST_INT16(_year); }
111fbdfed81STyler Dauwalder	uint8 month() const { return _month; }
112fbdfed81STyler Dauwalder	uint8 day() const { return _day; }
113fbdfed81STyler Dauwalder	uint8 hour() const { return _hour; }
114fbdfed81STyler Dauwalder	uint8 minute() const { return _minute; }
115fbdfed81STyler Dauwalder	uint8 second() const { return _second; }
116fbdfed81STyler Dauwalder	uint8 centisecond() const { return _centisecond; }
117fbdfed81STyler Dauwalder	uint8 hundred_microsecond() const { return _hundred_microsecond; }
118fbdfed81STyler Dauwalder	uint8 microsecond() const { return _microsecond; }
119fbdfed81STyler Dauwalder
120fbdfed81STyler Dauwalder	// Set functions
121c530d46cSJérôme Duval	void set_type_and_timezone(uint16 type_and_timezone) {
122c530d46cSJérôme Duval		_type_and_timezone = B_HOST_TO_LENDIAN_INT16(type_and_timezone); }
123fbdfed81STyler Dauwalder	void set_type(uint8 type) {
124fbdfed81STyler Dauwalder		type_and_timezone_accessor t;
125fbdfed81STyler Dauwalder		t.type_and_timezone = type_and_timezone();
126fbdfed81STyler Dauwalder		t.bits.type = type;
127fbdfed81STyler Dauwalder		set_type_and_timezone(t.type_and_timezone);
128fbdfed81STyler Dauwalder	}
129003d4e83STyler Dauwalder	void set_timezone(int16 tz) {
130fbdfed81STyler Dauwalder		type_and_timezone_accessor t;
131fbdfed81STyler Dauwalder		t.type_and_timezone = type_and_timezone();
132003d4e83STyler Dauwalder		t.bits.timezone = tz;
133fbdfed81STyler Dauwalder		set_type_and_timezone(t.type_and_timezone);
134fbdfed81STyler Dauwalder	}
135fbdfed81STyler Dauwalder	void set_year(uint16 year) { _year = B_HOST_TO_LENDIAN_INT16(year); }
136fbdfed81STyler Dauwalder	void set_month(uint8 month) { _month = month; }
137fbdfed81STyler Dauwalder	void set_day(uint8 day) { _day = day; }
138fbdfed81STyler Dauwalder	void set_hour(uint8 hour) { _hour = hour; }
139fbdfed81STyler Dauwalder	void set_minute(uint8 minute) { _minute = minute; }
140fbdfed81STyler Dauwalder	void set_second(uint8 second) { _second = second; }
141fbdfed81STyler Dauwalder	void set_centisecond(uint8 centisecond) { _centisecond = centisecond; }
142c530d46cSJérôme Duval	void set_hundred_microsecond(uint8 hundred_microsecond) {
143c530d46cSJérôme Duval		_hundred_microsecond = hundred_microsecond; }
144fbdfed81STyler Dauwalder	void set_microsecond(uint8 microsecond) { _microsecond = microsecond; }
145fbdfed81STyler Dauwalderprivate:
1469b438e89STyler Dauwalder	void _clear();
1479b438e89STyler Dauwalder
148fbdfed81STyler Dauwalder	uint16 _type_and_timezone;
149fbdfed81STyler Dauwalder	uint16 _year;
150fbdfed81STyler Dauwalder	uint8 _month;
151fbdfed81STyler Dauwalder	uint8 _day;
152fbdfed81STyler Dauwalder	uint8 _hour;
153fbdfed81STyler Dauwalder	uint8 _minute;
154fbdfed81STyler Dauwalder	uint8 _second;
155fbdfed81STyler Dauwalder	uint8 _centisecond;
156fbdfed81STyler Dauwalder	uint8 _hundred_microsecond;
157fbdfed81STyler Dauwalder	uint8 _microsecond;
158fbdfed81STyler Dauwalder
159edd2334cSTyler Dauwalder} __attribute__((packed));
160edd2334cSTyler Dauwalder
161edd2334cSTyler Dauwalder
1629a043bf9STyler Dauwalder/*! \brief UDF ID Identify Suffix
1639a043bf9STyler Dauwalder
1649a043bf9STyler Dauwalder	See also: UDF 2.50 2.1.5.3
1659a043bf9STyler Dauwalder*/
1669a043bf9STyler Dauwalderstruct udf_id_suffix {
1679a043bf9STyler Dauwalderpublic:
1689a043bf9STyler Dauwalder	udf_id_suffix(uint16 udfRevision, uint8 os_class, uint8 os_identifier);
1699a043bf9STyler Dauwalder
1709a043bf9STyler Dauwalder	//! Note that revision 2.50 is denoted by 0x0250.
1719a043bf9STyler Dauwalder	uint16 udf_revision() const { return _udf_revision; }
1729a043bf9STyler Dauwalder	uint8 os_class() const { return _os_class; }
1739a043bf9STyler Dauwalder	uint8 os_identifier() const { return _os_identifier; }
1749a043bf9STyler Dauwalder
1759a043bf9STyler Dauwalder	void set_os_class(uint8 os_class) { _os_class = os_class; }
1769a043bf9STyler Dauwalder	void set_os_identifier(uint8 identifier) { _os_identifier = identifier; }
1779a043bf9STyler Dauwalderprivate:
1789a043bf9STyler Dauwalder	uint16 _udf_revision;
1799a043bf9STyler Dauwalder	uint8 _os_class;
1809a043bf9STyler Dauwalder	uint8 _os_identifier;
1819a043bf9STyler Dauwalder	array<uint8, 4> _reserved;
1829a043bf9STyler Dauwalder};
1839a043bf9STyler Dauwalder
1849b438e89STyler Dauwalder/*! \brief Implementation ID Identify Suffix
1859b438e89STyler Dauwalder
1869b438e89STyler Dauwalder	See also: UDF 2.50 2.1.5.3
1879b438e89STyler Dauwalder*/
1889b438e89STyler Dauwalderstruct implementation_id_suffix {
1899b438e89STyler Dauwalderpublic:
1909b438e89STyler Dauwalder	implementation_id_suffix(uint8 os_class, uint8 os_identifier);
1919b438e89STyler Dauwalder
1929b438e89STyler Dauwalder	uint8 os_class() const { return _os_class; }
1939b438e89STyler Dauwalder	uint8 os_identifier() const { return _os_identifier; }
1949b438e89STyler Dauwalder
1959b438e89STyler Dauwalder	void set_os_class(uint8 os_class) { _os_class = os_class; }
1969b438e89STyler Dauwalder	void set_os_identifier(uint8 identifier) { _os_identifier = identifier; }
1979b438e89STyler Dauwalderprivate:
1989b438e89STyler Dauwalder	uint8 _os_class;
1999b438e89STyler Dauwalder	uint8 _os_identifier;
2009b438e89STyler Dauwalder	array<uint8, 6> _implementation_use;
2019b438e89STyler Dauwalder};
2029b438e89STyler Dauwalder
2039b438e89STyler Dauwalder/*! \brief Operating system classes for implementation_id_suffixes
2049b438e89STyler Dauwalder
2059b438e89STyler Dauwalder	See also: Udf 2.50 6.3
2069b438e89STyler Dauwalder*/
2079b438e89STyler Dauwalderenum {
2089b438e89STyler Dauwalder	OS_UNDEFINED = 0,
2099b438e89STyler Dauwalder	OS_DOS,
2109b438e89STyler Dauwalder	OS_OS2,
2119b438e89STyler Dauwalder	OS_MACOS,
2129b438e89STyler Dauwalder	OS_UNIX,
2139b438e89STyler Dauwalder	OS_WIN9X,
2149b438e89STyler Dauwalder	OS_WINNT,
2159b438e89STyler Dauwalder	OS_OS400,
2169b438e89STyler Dauwalder	OS_BEOS,
2179b438e89STyler Dauwalder	OS_WINCE
2189b438e89STyler Dauwalder};
2199b438e89STyler Dauwalder
2209b438e89STyler Dauwalder/*! \brief BeOS operating system classes identifiers for implementation_id_suffixes
2219b438e89STyler Dauwalder
2229b438e89STyler Dauwalder	See also: Udf 2.50 6.3
2239b438e89STyler Dauwalder*/
2249b438e89STyler Dauwalderenum {
2259b438e89STyler Dauwalder	BEOS_GENERIC = 0,
2269b438e89STyler Dauwalder	BEOS_OPENBEOS = 1	// not part of the standard, but perhaps someday. :-)
2279b438e89STyler Dauwalder};
2289b438e89STyler Dauwalder
229730ba00aSTyler Dauwalder/*! \brief Domain ID Identify Suffix
230730ba00aSTyler Dauwalder
231730ba00aSTyler Dauwalder	See also: UDF 2.50 2.1.5.3
232730ba00aSTyler Dauwalder*/
233730ba00aSTyler Dauwalderstruct domain_id_suffix {
234730ba00aSTyler Dauwalderpublic:
235730ba00aSTyler Dauwalder	domain_id_suffix(uint16 udfRevision, uint8 domainFlags);
236730ba00aSTyler Dauwalder
237730ba00aSTyler Dauwalder	//! Note that revision 2.50 is denoted by 0x0250.
238730ba00aSTyler Dauwalder	uint16 udf_revision() const { return _udf_revision; }
239730ba00aSTyler Dauwalder	uint8 domain_flags() const { return _domain_flags; }
240730ba00aSTyler Dauwalder
241730ba00aSTyler Dauwalder	void set_udf_revision(uint16 revision) { _udf_revision = B_HOST_TO_LENDIAN_INT16(revision); }
242730ba00aSTyler Dauwalder	void set_domain_flags(uint8 flags) { _domain_flags = flags; }
243730ba00aSTyler Dauwalderprivate:
24410186d5dSTyler Dauwalder	uint16 _udf_revision;
245730ba00aSTyler Dauwalder	uint8 _domain_flags;
246730ba00aSTyler Dauwalder	array<uint8, 5> _reserved;
247730ba00aSTyler Dauwalder};
248730ba00aSTyler Dauwalder
249730ba00aSTyler Dauwalder/*! \brief Domain flags
250730ba00aSTyler Dauwalder
251730ba00aSTyler Dauwalder	See also: UDF 2.50 2.1.5.3
252730ba00aSTyler Dauwalder*/
253730ba00aSTyler Dauwalderenum {
254730ba00aSTyler Dauwalder	DF_HARD_WRITE_PROTECT = 0x01,
255730ba00aSTyler Dauwalder	DF_SOFT_WRITE_PROTECT = 0x02
256730ba00aSTyler Dauwalder};
257730ba00aSTyler Dauwalder
258edd2334cSTyler Dauwalder/*! \brief Identifier used to designate the implementation responsible
259edd2334cSTyler Dauwalder	for writing associated data structures on the medium.
260edd2334cSTyler Dauwalder
261edd2334cSTyler Dauwalder	See also: ECMA 167 1/7.4, UDF 2.01 2.1.5
262edd2334cSTyler Dauwalder*/
2631379cacaSTyler Dauwalderstruct entity_id {
264fbdfed81STyler Dauwalderpublic:
2659b438e89STyler Dauwalder	static const int kIdentifierLength = 23;
2669b438e89STyler Dauwalder	static const int kIdentifierSuffixLength = 8;
2679b438e89STyler Dauwalder
26820d84995SRene Gollent	entity_id(uint8 flags = 0, const char *identifier = NULL,
2699b438e89STyler Dauwalder	          uint8 *identifier_suffix = NULL);
27020d84995SRene Gollent	entity_id(uint8 flags, const char *identifier,
2719a043bf9STyler Dauwalder	          const udf_id_suffix &suffix);
27220d84995SRene Gollent	entity_id(uint8 flags, const char *identifier,
2739b438e89STyler Dauwalder	          const implementation_id_suffix &suffix);
27420d84995SRene Gollent	entity_id(uint8 flags, const char *identifier,
275730ba00aSTyler Dauwalder	          const domain_id_suffix &suffix);
27678b6ddeaSTyler Dauwalder
277d5366ff7STyler Dauwalder	void dump() const;
2781379cacaSTyler Dauwalder	bool matches(const entity_id &id) const;
279fbdfed81STyler Dauwalder
280fbdfed81STyler Dauwalder	// Get functions
281fbdfed81STyler Dauwalder	uint8 flags() const { return _flags; }
282fbdfed81STyler Dauwalder	const char* identifier() const { return _identifier; }
283fbdfed81STyler Dauwalder	char* identifier() { return _identifier; }
2849b438e89STyler Dauwalder	const array<uint8, kIdentifierSuffixLength>& identifier_suffix() const { return _identifier_suffix; }
2859b438e89STyler Dauwalder	array<uint8, kIdentifierSuffixLength>& identifier_suffix() { return _identifier_suffix; }
286fbdfed81STyler Dauwalder
287fbdfed81STyler Dauwalder	// Set functions
28878b6ddeaSTyler Dauwalder	void set_flags(uint8 flags) { _flags = flags; }
289fbdfed81STyler Dauwalderprivate:
290fbdfed81STyler Dauwalder	uint8 _flags;
29178b6ddeaSTyler Dauwalder	char _identifier[kIdentifierLength];
2929b438e89STyler Dauwalder	array<uint8, kIdentifierSuffixLength> _identifier_suffix;
293edd2334cSTyler Dauwalder} __attribute__((packed));
294edd2334cSTyler Dauwalder
295c530d46cSJérôme Duvalextern entity_id kMetadataPartitionMapId;
296c530d46cSJérôme Duvalextern entity_id kSparablePartitionMapId;
297c530d46cSJérôme Duvalextern entity_id kVirtualPartitionMapId;
298c530d46cSJérôme Duvalextern entity_id kImplementationId;
299c530d46cSJérôme Duvalextern entity_id kPartitionContentsId1xx;
300c530d46cSJérôme Duvalextern entity_id kPartitionContentsId2xx;
301c530d46cSJérôme Duvalextern entity_id kUdfId;
302c530d46cSJérôme Duvalextern entity_id kLogicalVolumeInfoId150;
303c530d46cSJérôme Duvalextern entity_id kLogicalVolumeInfoId201;
304c530d46cSJérôme Duvalextern entity_id kDomainId150;
305c530d46cSJérôme Duvalextern entity_id kDomainId201;
306c530d46cSJérôme Duvalextern void init_entities(void);
307edd2334cSTyler Dauwalder
308edd2334cSTyler Dauwalder//----------------------------------------------------------------------
309edd2334cSTyler Dauwalder// ECMA-167 Part 2
310edd2334cSTyler Dauwalder//----------------------------------------------------------------------
311edd2334cSTyler Dauwalder
312edd2334cSTyler Dauwalder
3131a2f87c1STyler Dauwalder/*! \brief Header for volume structure descriptors
3141a2f87c1STyler Dauwalder
3151a2f87c1STyler Dauwalder	Each descriptor consumes an entire block. All unused trailing
3161a2f87c1STyler Dauwalder	bytes in the descriptor should be set to 0.
3171a2f87c1STyler Dauwalder
3181a2f87c1STyler Dauwalder	The following descriptors contain no more information than
3191a2f87c1STyler Dauwalder	that contained in the header:
3201a2f87c1STyler Dauwalder
3211a2f87c1STyler Dauwalder	- BEA01:
3221a2f87c1STyler Dauwalder	  - type: 0
3231a2f87c1STyler Dauwalder	  - id: "BEA01"
3241a2f87c1STyler Dauwalder	  - version: 1
3251a2f87c1STyler Dauwalder
3261a2f87c1STyler Dauwalder	- TEA01:
3271a2f87c1STyler Dauwalder	  - type: 0
3281a2f87c1STyler Dauwalder	  - id: "TEA01"
3291a2f87c1STyler Dauwalder	  - version: 1
3301a2f87c1STyler Dauwalder
3311a2f87c1STyler Dauwalder	- NSR03:
3321a2f87c1STyler Dauwalder	  - type: 0
3331a2f87c1STyler Dauwalder	  - id: "NSR03"
3341a2f87c1STyler Dauwalder	  - version: 1
335edd2334cSTyler Dauwalder
336edd2334cSTyler Dauwalder	See also: ECMA 167 2/9.1
3371a2f87c1STyler Dauwalder*/
3381379cacaSTyler Dauwalderstruct volume_structure_descriptor_header {
3392cc6b97aSTyler Dauwalderpublic:
3402cc6b97aSTyler Dauwalder	volume_structure_descriptor_header(uint8 type, const char *id, uint8 version);
3412cc6b97aSTyler Dauwalder
3421a2f87c1STyler Dauwalder	uint8 type;
3439feb1a72STyler Dauwalder	char id[5];
3441a2f87c1STyler Dauwalder	uint8 version;
3459feb1a72STyler Dauwalder
3469feb1a72STyler Dauwalder	bool id_matches(const char *id);
3471a2f87c1STyler Dauwalder} __attribute__((packed));
3481a2f87c1STyler Dauwalder
3491a2f87c1STyler Dauwalder// Volume structure descriptor ids
3509feb1a72STyler Dauwalderextern const char* kVSDID_BEA;
3519feb1a72STyler Dauwalderextern const char* kVSDID_TEA;
3529feb1a72STyler Dauwalderextern const char* kVSDID_BOOT;
3539feb1a72STyler Dauwalderextern const char* kVSDID_ISO;
3549feb1a72STyler Dauwalderextern const char* kVSDID_ECMA167_2;
3559feb1a72STyler Dauwalderextern const char* kVSDID_ECMA167_3;
3569feb1a72STyler Dauwalderextern const char* kVSDID_ECMA168;
3571a2f87c1STyler Dauwalder
358edd2334cSTyler Dauwalder//----------------------------------------------------------------------
359edd2334cSTyler Dauwalder// ECMA-167 Part 3
360edd2334cSTyler Dauwalder//----------------------------------------------------------------------
3611a2f87c1STyler Dauwalder
3621a2f87c1STyler Dauwalder
363928e0500STyler Dauwalder/*! \brief Location and length of a contiguous chunk of data on the volume.
364928e0500STyler Dauwalder
365928e0500STyler Dauwalder	\c _location is an absolute block address.
3661a2f87c1STyler Dauwalder
3671a2f87c1STyler Dauwalder	See also: ECMA 167 3/7.1
3681a2f87c1STyler Dauwalder*/
3691379cacaSTyler Dauwalderstruct extent_address {
370fbdfed81STyler Dauwalderpublic:
371c21aaa8aSTyler Dauwalder	extent_address(uint32 location = 0, uint32 length = 0);
372c21aaa8aSTyler Dauwalder
373d5366ff7STyler Dauwalder	void dump() const;
374fbdfed81STyler Dauwalder
375d5366ff7STyler Dauwalder	uint32 length() const { return B_LENDIAN_TO_HOST_INT32(_length); }
376d5366ff7STyler Dauwalder	uint32 location() const { return B_LENDIAN_TO_HOST_INT32(_location); }
377fbdfed81STyler Dauwalder
378fbdfed81STyler Dauwalder	void set_length(int32 length) { _length = B_HOST_TO_LENDIAN_INT32(length); }
379fbdfed81STyler Dauwalder	void set_location(int32 location) { _location = B_HOST_TO_LENDIAN_INT32(location); }
380fbdfed81STyler Dauwalderprivate:
381fbdfed81STyler Dauwalder	uint32 _length;
382fbdfed81STyler Dauwalder	uint32 _location;
3831a2f87c1STyler Dauwalder} __attribute__((packed));
3841a2f87c1STyler Dauwalder
3851a2f87c1STyler Dauwalder
38656f47960STyler Dauwalder/*! \brief Location of a logical block within a logical volume.
38756f47960STyler Dauwalder
38856f47960STyler Dauwalder	See also: ECMA 167 4/7.1
38956f47960STyler Dauwalder*/
3901379cacaSTyler Dauwalderstruct logical_block_address {
391d0da9166STyler Dauwalderpublic:
392d5366ff7STyler Dauwalder	void dump() const;
393e631ed51STyler Dauwalder	logical_block_address(uint16 partition = 0, uint32 block = 0);
394d0da9166STyler Dauwalder
395d0da9166STyler Dauwalder	uint32 block() const { return B_LENDIAN_TO_HOST_INT32(_block); }
396d0da9166STyler Dauwalder	uint16 partition() const { return B_LENDIAN_TO_HOST_INT16(_partition); }
397d0da9166STyler Dauwalder
398d0da9166STyler Dauwalder	void set_block(uint32 block) { _block = B_HOST_TO_LENDIAN_INT32(block); }
399d0da9166STyler Dauwalder	void set_partition(uint16 partition) { _partition = B_HOST_TO_LENDIAN_INT16(partition); }
400d0da9166STyler Dauwalder
401d0da9166STyler Dauwalderprivate:
402d0da9166STyler Dauwalder	uint32 _block;	//!< Block location relative to start of corresponding partition
403d0da9166STyler Dauwalder	uint16 _partition;	//!< Numeric partition id within logical volume
40456f47960STyler Dauwalder} __attribute__((packed));
40556f47960STyler Dauwalder
4061379cacaSTyler Dauwalder/*! \brief Extent types used in short_address, long_address,
4071379cacaSTyler Dauwalder	and extended_address.
408928e0500STyler Dauwalder
409928e0500STyler Dauwalder	See also: ECMA-167 4/14.14.1.1
410928e0500STyler Dauwalder*/
4111379cacaSTyler Dauwalderenum extent_type {
412928e0500STyler Dauwalder	EXTENT_TYPE_RECORDED = 0,	//!< Allocated and recorded
413928e0500STyler Dauwalder	EXTENT_TYPE_ALLOCATED,		//!< Allocated but unrecorded
414928e0500STyler Dauwalder	EXTENT_TYPE_UNALLOCATED,	//!< Unallocated and unrecorded
415928e0500STyler Dauwalder	EXTENT_TYPE_CONTINUATION,	//!< Specifies next extent of descriptors
416928e0500STyler Dauwalder};
417928e0500STyler Dauwalder
41856f47960STyler Dauwalder
41956f47960STyler Dauwalder/*! \brief Allocation descriptor.
42056f47960STyler Dauwalder
42156f47960STyler Dauwalder	See also: ECMA 167 4/14.14.1
42256f47960STyler Dauwalder*/
4231379cacaSTyler Dauwalderstruct short_address {
424928e0500STyler Dauwalderprivate:
425928e0500STyler Dauwalder	union type_and_length_accessor {
426928e0500STyler Dauwalder		uint32 type_and_length;
427928e0500STyler Dauwalder		struct {
428928e0500STyler Dauwalder			uint32 length:30,
429928e0500STyler Dauwalder			       type:2;
430928e0500STyler Dauwalder//			uint32 type:2,
431928e0500STyler Dauwalder//			       length:30;
432928e0500STyler Dauwalder		} bits;
433928e0500STyler Dauwalder	};
434928e0500STyler Dauwalder
435d0da9166STyler Dauwalderpublic:
436d5366ff7STyler Dauwalder	void dump() const;
437d0da9166STyler Dauwalder
438928e0500STyler Dauwalder	uint8 type() const {
439928e0500STyler Dauwalder		type_and_length_accessor t;
440928e0500STyler Dauwalder		t.type_and_length = type_and_length();
441928e0500STyler Dauwalder		return t.bits.type;
442928e0500STyler Dauwalder	}
443928e0500STyler Dauwalder	uint32 length() const {
444928e0500STyler Dauwalder		type_and_length_accessor t;
445928e0500STyler Dauwalder		t.type_and_length = type_and_length();
446928e0500STyler Dauwalder		return t.bits.length;
447928e0500STyler Dauwalder	}
448928e0500STyler Dauwalder	uint32 block() const { return B_LENDIAN_TO_HOST_INT32(_block); }
449d0da9166STyler Dauwalder
450928e0500STyler Dauwalder	void set_type(uint8 type) {
451928e0500STyler Dauwalder		type_and_length_accessor t;
452928e0500STyler Dauwalder		t.type_and_length = type_and_length();
453928e0500STyler Dauwalder		t.bits.type = type;
454928e0500STyler Dauwalder		set_type_and_length(t.type_and_length);
455928e0500STyler Dauwalder	}
456928e0500STyler Dauwalder	void set_length(uint32 length) {
457928e0500STyler Dauwalder		type_and_length_accessor t;
458928e0500STyler Dauwalder		t.type_and_length = type_and_length();
459928e0500STyler Dauwalder		t.bits.length = length;
460928e0500STyler Dauwalder		set_type_and_length(t.type_and_length);
461928e0500STyler Dauwalder	}
462928e0500STyler Dauwalder	void set_block(uint32 block) { _block = B_HOST_TO_LENDIAN_INT32(block); }
463d0da9166STyler Dauwalderprivate:
464928e0500STyler Dauwalder	uint32 type_and_length() const { return B_LENDIAN_TO_HOST_INT32(_type_and_length); }
465928e0500STyler Dauwalder	void set_type_and_length(uint32 value) { _type_and_length = B_HOST_TO_LENDIAN_INT32(value); }
466928e0500STyler Dauwalder
467928e0500STyler Dauwalder	uint32 _type_and_length;
468928e0500STyler Dauwalder	uint32 _block;
46956f47960STyler Dauwalder} __attribute__((packed));
47056f47960STyler Dauwalder
47156f47960STyler Dauwalder
47256f47960STyler Dauwalder/*! \brief Allocation descriptor w/ 6 byte implementation use field.
47356f47960STyler Dauwalder
47456f47960STyler Dauwalder	See also: ECMA 167 4/14.14.2
47556f47960STyler Dauwalder*/
4761379cacaSTyler Dauwalderstruct long_address {
477928e0500STyler Dauwalderprivate:
478928e0500STyler Dauwalder	union type_and_length_accessor {
479928e0500STyler Dauwalder		uint32 type_and_length;
480928e0500STyler Dauwalder		struct {
481928e0500STyler Dauwalder			uint32 length:30,
482928e0500STyler Dauwalder			       type:2;
483928e0500STyler Dauwalder		} bits;
484928e0500STyler Dauwalder	};
485928e0500STyler Dauwalder
48656f47960STyler Dauwalderpublic:
487d1a0387eSTyler Dauwalder	long_address(uint16 partition = 0, uint32 block = 0, uint32 length = 0,
488d1a0387eSTyler Dauwalder	             uint8 type = 0);
489d1a0387eSTyler Dauwalder
490d5366ff7STyler Dauwalder	void dump() const;
49156f47960STyler Dauwalder
492928e0500STyler Dauwalder	uint8 type() const {
493928e0500STyler Dauwalder		type_and_length_accessor t;
494928e0500STyler Dauwalder		t.type_and_length = type_and_length();
495928e0500STyler Dauwalder		return t.bits.type;
496928e0500STyler Dauwalder	}
497928e0500STyler Dauwalder	uint32 length() const {
498928e0500STyler Dauwalder		type_and_length_accessor t;
499928e0500STyler Dauwalder		t.type_and_length = type_and_length();
500928e0500STyler Dauwalder		return t.bits.length;
501928e0500STyler Dauwalder	}
50256f47960STyler Dauwalder
503d0da9166STyler Dauwalder	uint32 block() const { return _location.block(); }
504d0da9166STyler Dauwalder	uint16 partition() const { return _location.partition(); }
50556f47960STyler Dauwalder
50656f47960STyler Dauwalder	const array<uint8, 6>& implementation_use() const { return _implementation_use; }
50756f47960STyler Dauwalder	array<uint8, 6>& implementation_use() { return _implementation_use; }
50880b849abSTyler Dauwalder
50980b849abSTyler Dauwalder	uint16 flags() const { return B_LENDIAN_TO_HOST_INT16(_accessor().flags); }
51080b849abSTyler Dauwalder	uint32 unique_id() const { return B_LENDIAN_TO_HOST_INT32(_accessor().unique_id); }
51156f47960STyler Dauwalder
512928e0500STyler Dauwalder	void set_type(uint8 type) {
513928e0500STyler Dauwalder		type_and_length_accessor t;
514928e0500STyler Dauwalder		t.type_and_length = type_and_length();
515928e0500STyler Dauwalder		t.bits.type = type;
516928e0500STyler Dauwalder		set_type_and_length(t.type_and_length);
517928e0500STyler Dauwalder	}
518928e0500STyler Dauwalder	void set_length(uint32 length) {
519928e0500STyler Dauwalder		type_and_length_accessor t;
520928e0500STyler Dauwalder		t.type_and_length = type_and_length();
521928e0500STyler Dauwalder		t.bits.length = length;
522928e0500STyler Dauwalder		set_type_and_length(t.type_and_length);
523928e0500STyler Dauwalder	}
524d0da9166STyler Dauwalder	void set_block(uint32 block) { _location.set_block(block); }
525d0da9166STyler Dauwalder	void set_partition(uint16 partition) { _location.set_partition(partition); }
52680b849abSTyler Dauwalder
52780b849abSTyler Dauwalder	void set_flags(uint16 flags) { _accessor().flags = B_HOST_TO_LENDIAN_INT16(flags); }
52880b849abSTyler Dauwalder	void set_unique_id(uint32 id) { _accessor().unique_id = B_HOST_TO_LENDIAN_INT32(id); }
52956f47960STyler Dauwalder
530928e0500STyler Dauwalder	void set_to(uint32 block, uint16 partition, uint32 length = 1,
53180b849abSTyler Dauwalder	       uint8 type = EXTENT_TYPE_RECORDED, uint16 flags = 0, uint32 unique_id = 0)
532928e0500STyler Dauwalder	{
533928e0500STyler Dauwalder		set_block(block);
534928e0500STyler Dauwalder		set_partition(partition);
535928e0500STyler Dauwalder		set_length(length);
536928e0500STyler Dauwalder		set_type(type);
53780b849abSTyler Dauwalder		set_flags(flags);
53880b849abSTyler Dauwalder		set_unique_id(unique_id);
539928e0500STyler Dauwalder	}
540928e0500STyler Dauwalder
54156f47960STyler Dauwalderprivate:
54280b849abSTyler Dauwalder	//! See UDF-2.50 2.3.4.3
54380b849abSTyler Dauwalder	struct _implementation_use_accessor {
54480b849abSTyler Dauwalder		uint16 flags;
54580b849abSTyler Dauwalder		uint32 unique_id;
54680b849abSTyler Dauwalder	} __attribute__((packed));
54780b849abSTyler Dauwalder
54880b849abSTyler Dauwalder	_implementation_use_accessor& _accessor() { return
54980b849abSTyler Dauwalder		*reinterpret_cast<_implementation_use_accessor*>(implementation_use().data); }
55080b849abSTyler Dauwalder	const _implementation_use_accessor& _accessor() const { return
55180b849abSTyler Dauwalder		*reinterpret_cast<const _implementation_use_accessor*>(implementation_use().data); }
55280b849abSTyler Dauwalder
553928e0500STyler Dauwalder	uint32 type_and_length() const { return B_LENDIAN_TO_HOST_INT32(_type_and_length); }
554928e0500STyler Dauwalder	void set_type_and_length(uint32 value) { _type_and_length = B_HOST_TO_LENDIAN_INT32(value); }
555928e0500STyler Dauwalder
556928e0500STyler Dauwalder	uint32 _type_and_length;
5571379cacaSTyler Dauwalder	logical_block_address _location;
55856f47960STyler Dauwalder	array<uint8, 6> _implementation_use;
55956f47960STyler Dauwalder} __attribute__((packed));
56056f47960STyler Dauwalder
561edd2334cSTyler Dauwalder/*! \brief Common tag found at the beginning of most udf descriptor structures.
5621a2f87c1STyler Dauwalder
5631379cacaSTyler Dauwalder	For error checking, \c descriptor_tag  structures have:
564edd2334cSTyler Dauwalder	- The disk location of the tag redundantly stored in the tag itself
565edd2334cSTyler Dauwalder	- A checksum value for the tag
566edd2334cSTyler Dauwalder	- A CRC value and length
5671a2f87c1STyler Dauwalder
568edd2334cSTyler Dauwalder	See also: ECMA 167 1/7.2, UDF 2.01 2.2.1, UDF 2.01 2.3.1
5691a2f87c1STyler Dauwalder*/
570e9927e2bSTyler Dauwalderstruct descriptor_tag {
571fbdfed81STyler Dauwalderpublic:
572d5366ff7STyler Dauwalder	void dump() const;
573fbdfed81STyler Dauwalder
5745a97c04eSTyler Dauwalder	status_t init_check(uint32 block, bool calculateCrc = true);
575fbdfed81STyler Dauwalder
576d5366ff7STyler Dauwalder	uint16 id() const { return B_LENDIAN_TO_HOST_INT16(_id); }
577d5366ff7STyler Dauwalder	uint16 version() const { return B_LENDIAN_TO_HOST_INT16(_version); }
578d5366ff7STyler Dauwalder	uint8 checksum() const { return _checksum; }
579d5366ff7STyler Dauwalder	uint16 serial_number() const { return B_LENDIAN_TO_HOST_INT16(_serial_number); }
580d5366ff7STyler Dauwalder	uint16 crc() const { return B_LENDIAN_TO_HOST_INT16(_crc); }
581d5366ff7STyler Dauwalder	uint16 crc_length() const { return B_LENDIAN_TO_HOST_INT16(_crc_length); }
582d5366ff7STyler Dauwalder	uint32 location() const { return B_LENDIAN_TO_HOST_INT32(_location); }
583fbdfed81STyler Dauwalder
584fbdfed81STyler Dauwalder	void set_id(uint16 id) { _id = B_HOST_TO_LENDIAN_INT16(id); }
585fbdfed81STyler Dauwalder	void set_version(uint16 version) { _version = B_HOST_TO_LENDIAN_INT16(version); }
586fbdfed81STyler Dauwalder	void set_checksum(uint8 checksum) { _checksum = checksum; }
587fbdfed81STyler Dauwalder	void set_serial_number(uint16 serial_number) { _serial_number = B_HOST_TO_LENDIAN_INT16(serial_number); }
588fbdfed81STyler Dauwalder	void set_crc(uint16 crc) { _crc = B_HOST_TO_LENDIAN_INT16(crc); }
589fbdfed81STyler Dauwalder	void set_crc_length(uint16 crc_length) { _crc_length = B_HOST_TO_LENDIAN_INT16(crc_length); }
590fbdfed81STyler Dauwalder	void set_location(uint32 location) { _location = B_HOST_TO_LENDIAN_INT32(location); }
591fbdfed81STyler Dauwalder
5925a97c04eSTyler Dauwalder	/*! \brief Calculates and sets the crc length, crc checksumm, and
5935a97c04eSTyler Dauwalder		checksum for the tag.
5945a97c04eSTyler Dauwalder
5955a97c04eSTyler Dauwalder		This function should not be called until all member variables in
5965a97c04eSTyler Dauwalder		the descriptor_tag's enclosing descriptor and all member variables
5975a97c04eSTyler Dauwalder		in the descriptor_tag itself other than crc_length, crc, and checksum
5985a97c04eSTyler Dauwalder		have been set (since the checksum is based off of values in the
5995a97c04eSTyler Dauwalder		descriptor_tag, and the crc is based off the values in and the
6005a97c04eSTyler Dauwalder		size of the	enclosing descriptor).
6015a97c04eSTyler Dauwalder
6025a97c04eSTyler Dauwalder		\param The tag's enclosing descriptor.
6035a97c04eSTyler Dauwalder		\param The size of the tag's enclosing descriptor (including the
6045a97c04eSTyler Dauwalder		       tag); only necessary if different from sizeof(Descriptor).
6055a97c04eSTyler Dauwalder	*/
6065a97c04eSTyler Dauwalder	template <class Descriptor>
6075a97c04eSTyler Dauwalder	void
6085a97c04eSTyler Dauwalder	set_checksums(Descriptor &descriptor, uint16 size = sizeof(Descriptor))
6095a97c04eSTyler Dauwalder	{
6105a97c04eSTyler Dauwalder
6115a97c04eSTyler Dauwalder		// check that this tag is actually owned by
6125a97c04eSTyler Dauwalder		// the given descriptor
6135a97c04eSTyler Dauwalder		if (this == &descriptor.tag())
6145a97c04eSTyler Dauwalder		{
6155a97c04eSTyler Dauwalder			// crc_length, based off provided descriptor
6165a97c04eSTyler Dauwalder			set_crc_length(size - sizeof(descriptor_tag));
6175a97c04eSTyler Dauwalder			// crc
618c49d6efcSSalvatore Benedetto			uint16 crc = calculate_crc(reinterpret_cast<uint8*>(this)
6195a97c04eSTyler Dauwalder			               + sizeof(descriptor_tag), crc_length());
6205a97c04eSTyler Dauwalder			set_crc(crc);
6215a97c04eSTyler Dauwalder			// checksum (which depends on the other two values)
6225a97c04eSTyler Dauwalder			uint32 sum = 0;
6235a97c04eSTyler Dauwalder			for (int i = 0; i <= 3; i++)
6245a97c04eSTyler Dauwalder				sum += reinterpret_cast<uint8*>(this)[i];
6255a97c04eSTyler Dauwalder			for (int i = 5; i <= 15; i++)
6265a97c04eSTyler Dauwalder				sum += reinterpret_cast<uint8*>(this)[i];
6275a97c04eSTyler Dauwalder			set_checksum(sum % 256);
6285a97c04eSTyler Dauwalder		}
6295a97c04eSTyler Dauwalder	}
630fbdfed81STyler Dauwalderprivate:
631fbdfed81STyler Dauwalder	uint16 _id;
632fbdfed81STyler Dauwalder	uint16 _version;
633fbdfed81STyler Dauwalder	uint8 _checksum;			//!< Sum modulo 256 of bytes 0-3 and 5-15 of this struct.
634fbdfed81STyler Dauwalder	uint8 _reserved;			//!< Set to #00.
635fbdfed81STyler Dauwalder	uint16 _serial_number;
636fbdfed81STyler Dauwalder	uint16 _crc;				//!< May be 0 if \c crc_length field is 0.
637edd2334cSTyler Dauwalder	/*! \brief Length of the data chunk used to calculate CRC.
638edd2334cSTyler Dauwalder
639edd2334cSTyler Dauwalder		If 0, no CRC was calculated, and the \c crc field must be 0.
640edd2334cSTyler Dauwalder
641edd2334cSTyler Dauwalder		According to UDF-2.01 2.3.1.2, the CRC shall be calculated for all descriptors
642edd2334cSTyler Dauwalder		unless otherwise noted, and this field shall be set to:
643edd2334cSTyler Dauwalder
644edd2334cSTyler Dauwalder		<code>(descriptor length) - (descriptor tag length)</code>
645edd2334cSTyler Dauwalder	*/
646fbdfed81STyler Dauwalder	uint16 _crc_length;
647edd2334cSTyler Dauwalder	/*! \brief Address of this tag within its partition (for error checking).
648edd2334cSTyler Dauwalder
649edd2334cSTyler Dauwalder		For virtually addressed structures (i.e. those accessed thru a VAT), this
650edd2334cSTyler Dauwalder		shall be the virtual address, not the physical or logical address.
651edd2334cSTyler Dauwalder	*/
652fbdfed81STyler Dauwalder	uint32 _location;
6531a2f87c1STyler Dauwalder
6541a2f87c1STyler Dauwalder} __attribute__((packed));
6551a2f87c1STyler Dauwalder
6561a2f87c1STyler Dauwalder
6571379cacaSTyler Dauwalder/*! \c descriptor_tag ::id values
6581a2f87c1STyler Dauwalder*/
6591379cacaSTyler Dauwalderenum tag_id {
6601a2f87c1STyler Dauwalder	TAGID_UNDEFINED	= 0,
6611a2f87c1STyler Dauwalder
6621a2f87c1STyler Dauwalder	// ECMA 167, PART 3
6631a2f87c1STyler Dauwalder	TAGID_PRIMARY_VOLUME_DESCRIPTOR,
6641a2f87c1STyler Dauwalder	TAGID_ANCHOR_VOLUME_DESCRIPTOR_POINTER,
6651a2f87c1STyler Dauwalder	TAGID_VOLUME_DESCRIPTOR_POINTER,
6661a2f87c1STyler Dauwalder	TAGID_IMPLEMENTATION_USE_VOLUME_DESCRIPTOR,
6671a2f87c1STyler Dauwalder	TAGID_PARTITION_DESCRIPTOR,
6681a2f87c1STyler Dauwalder	TAGID_LOGICAL_VOLUME_DESCRIPTOR,
6691a2f87c1STyler Dauwalder	TAGID_UNALLOCATED_SPACE_DESCRIPTOR,
6701a2f87c1STyler Dauwalder	TAGID_TERMINATING_DESCRIPTOR,
6711a2f87c1STyler Dauwalder	TAGID_LOGICAL_VOLUME_INTEGRITY_DESCRIPTOR,
6721a2f87c1STyler Dauwalder
6731a2f87c1STyler Dauwalder	TAGID_CUSTOM_START = 65280,
6741a2f87c1STyler Dauwalder	TAGID_CUSTOM_END = 65535,
6751a2f87c1STyler Dauwalder
6761a2f87c1STyler Dauwalder	// ECMA 167, PART 4
6771a2f87c1STyler Dauwalder	TAGID_FILE_SET_DESCRIPTOR = 256,
6784f0e6a75STyler Dauwalder	TAGID_FILE_ID_DESCRIPTOR,
6791a2f87c1STyler Dauwalder	TAGID_ALLOCATION_EXTENT_DESCRIPTOR,
6801a2f87c1STyler Dauwalder	TAGID_INDIRECT_ENTRY,
6811a2f87c1STyler Dauwalder	TAGID_TERMINAL_ENTRY,
6821a2f87c1STyler Dauwalder	TAGID_FILE_ENTRY,
6831a2f87c1STyler Dauwalder	TAGID_EXTENDED_ATTRIBUTE_HEADER_DESCRIPTOR,
6841a2f87c1STyler Dauwalder	TAGID_UNALLOCATED_SPACE_ENTRY,
6851a2f87c1STyler Dauwalder	TAGID_SPACE_BITMAP_DESCRIPTOR,
6861a2f87c1STyler Dauwalder	TAGID_PARTITION_INTEGRITY_ENTRY,
6871a2f87c1STyler Dauwalder	TAGID_EXTENDED_FILE_ENTRY,
6889feb1a72STyler Dauwalder};
6891a2f87c1STyler Dauwalder
6901379cacaSTyler Dauwalderconst char *tag_id_to_string(tag_id id);
69115851e7aSTyler Dauwalder
692e05a3e1eSTyler Dauwalderextern const uint16 kCrcTable[256];
693e05a3e1eSTyler Dauwalder
6941a2f87c1STyler Dauwalder/*! \brief Primary volume descriptor
6951a2f87c1STyler Dauwalder*/
6969b8775eaSTyler Dauwalderstruct primary_volume_descriptor {
697fbdfed81STyler Dauwalderpublic:
698d5366ff7STyler Dauwalder	void dump() const;
699fbdfed81STyler Dauwalder
700fbdfed81STyler Dauwalder	// Get functions
7011379cacaSTyler Dauwalder	const descriptor_tag & tag() const { return _tag; }
7021379cacaSTyler Dauwalder	descriptor_tag & tag() { return _tag; }
703fbdfed81STyler Dauwalder
70456f47960STyler Dauwalder	uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
705fbdfed81STyler Dauwalder	uint32 primary_volume_descriptor_number() const { return B_LENDIAN_TO_HOST_INT32(_primary_volume_descriptor_number); }
706fbdfed81STyler Dauwalder
707d0da9166STyler Dauwalder	const array<char, 32>& volume_identifier() const { return _volume_identifier; }
708d0da9166STyler Dauwalder	array<char, 32>& volume_identifier() { return _volume_identifier; }
709fbdfed81STyler Dauwalder
710fbdfed81STyler Dauwalder	uint16 volume_sequence_number() const { return B_LENDIAN_TO_HOST_INT16(_volume_sequence_number); }
711fbdfed81STyler Dauwalder	uint16 max_volume_sequence_number() const { return B_LENDIAN_TO_HOST_INT16(_max_volume_sequence_number); }
712fbdfed81STyler Dauwalder	uint16 interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_interchange_level); }
713fbdfed81STyler Dauwalder	uint16 max_interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_max_interchange_level); }
714fbdfed81STyler Dauwalder	uint32 character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_character_set_list); }
715fbdfed81STyler Dauwalder	uint32 max_character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_max_character_set_list); }
716fbdfed81STyler Dauwalder
717d0da9166STyler Dauwalder	const array<char, 128>& volume_set_identifier() const { return _volume_set_identifier; }
718d0da9166STyler Dauwalder	array<char, 128>& volume_set_identifier() { return _volume_set_identifier; }
719fbdfed81STyler Dauwalder
7201379cacaSTyler Dauwalder	const charspec& descriptor_character_set() const { return _descriptor_character_set; }
7211379cacaSTyler Dauwalder	charspec& descriptor_character_set() { return _descriptor_character_set; }
722fbdfed81STyler Dauwalder
7231379cacaSTyler Dauwalder	const charspec& explanatory_character_set() const { return _explanatory_character_set; }
7241379cacaSTyler Dauwalder	charspec& explanatory_character_set() { return _explanatory_character_set; }
725fbdfed81STyler Dauwalder
7261379cacaSTyler Dauwalder	const extent_address& volume_abstract() const { return _volume_abstract; }
7271379cacaSTyler Dauwalder	extent_address& volume_abstract() { return _volume_abstract; }
7281379cacaSTyler Dauwalder	const extent_address& volume_copyright_notice() const { return _volume_copyright_notice; }
7291379cacaSTyler Dauwalder	extent_address& volume_copyright_notice() { return _volume_copyright_notice; }
730fbdfed81STyler Dauwalder
7311379cacaSTyler Dauwalder	const entity_id& application_id() const { return _application_id; }
7321379cacaSTyler Dauwalder	entity_id& application_id() { return _application_id; }
733fbdfed81STyler Dauwalder
7341379cacaSTyler Dauwalder	const timestamp& recording_date_and_time() const { return _recording_date_and_time; }
7351379cacaSTyler Dauwalder	timestamp& recording_date_and_time() { return _recording_date_and_time; }
736fbdfed81STyler Dauwalder
7371379cacaSTyler Dauwalder	const entity_id& implementation_id() const { return _implementation_id; }
7381379cacaSTyler Dauwalder	entity_id& implementation_id() { return _implementation_id; }
739fbdfed81STyler Dauwalder
74056f47960STyler Dauwalder	const array<uint8, 64>& implementation_use() const { return _implementation_use; }
74156f47960STyler Dauwalder	array<uint8, 64>& implementation_use() { return _implementation_use; }
742fbdfed81STyler Dauwalder
743fbdfed81STyler Dauwalder	uint32 predecessor_volume_descriptor_sequence_location() const
744fbdfed81STyler Dauwalder	  { return B_LENDIAN_TO_HOST_INT32(_predecessor_volume_descriptor_sequence_location); }
745fbdfed81STyler Dauwalder	uint16 flags() const { return B_LENDIAN_TO_HOST_INT16(_flags); }
7469b438e89STyler Dauwalder
7479b438e89STyler Dauwalder	const array<uint8, 22>& reserved() const { return _reserved; }
7489b438e89STyler Dauwalder	array<uint8, 22>& reserved() { return _reserved; }
749fbdfed81STyler Dauwalder
750fbdfed81STyler Dauwalder	// Set functions
75156f47960STyler Dauwalder	void set_vds_number(uint32 number)
75256f47960STyler Dauwalder	  { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
753fbdfed81STyler Dauwalder	void set_primary_volume_descriptor_number(uint32 number)
754fbdfed81STyler Dauwalder	  { _primary_volume_descriptor_number = B_HOST_TO_LENDIAN_INT32(number); }
755fbdfed81STyler Dauwalder	void set_volume_sequence_number(uint16 number)
756fbdfed81STyler Dauwalder	  { _volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); }
757fbdfed81STyler Dauwalder	void set_max_volume_sequence_number(uint16 number)
758fbdfed81STyler Dauwalder	  { _max_volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); }
759fbdfed81STyler Dauwalder	void set_interchange_level(uint16 level)
760fbdfed81STyler Dauwalder	  { _interchange_level = B_HOST_TO_LENDIAN_INT16(level); }
761fbdfed81STyler Dauwalder	void set_max_interchange_level(uint16 level)
762fbdfed81STyler Dauwalder	  { _max_interchange_level = B_HOST_TO_LENDIAN_INT16(level); }
763fbdfed81STyler Dauwalder	void set_character_set_list(uint32 list)
764fbdfed81STyler Dauwalder	  { _character_set_list = B_HOST_TO_LENDIAN_INT32(list); }
765fbdfed81STyler Dauwalder	void set_max_character_set_list(uint32 list)
766fbdfed81STyler Dauwalder	  { _max_character_set_list = B_HOST_TO_LENDIAN_INT32(list); }
767fbdfed81STyler Dauwalder	void set_predecessor_volume_descriptor_sequence_location(uint32 location)
768fbdfed81STyler Dauwalder	  { _predecessor_volume_descriptor_sequence_location = B_HOST_TO_LENDIAN_INT32(location); }
769fbdfed81STyler Dauwalder	void set_flags(uint16 flags)
770fbdfed81STyler Dauwalder	  { _flags = B_HOST_TO_LENDIAN_INT16(flags); }
771fbdfed81STyler Dauwalder
772fbdfed81STyler Dauwalderprivate:
7731379cacaSTyler Dauwalder	descriptor_tag  _tag;
77456f47960STyler Dauwalder	uint32 _vds_number;
775fbdfed81STyler Dauwalder	uint32 _primary_volume_descriptor_number;
776d0da9166STyler Dauwalder	array<char, 32> _volume_identifier;
777fbdfed81STyler Dauwalder	uint16 _volume_sequence_number;
778fbdfed81STyler Dauwalder	uint16 _max_volume_sequence_number;
779fbdfed81STyler Dauwalder	uint16 _interchange_level; //!< to be set to 3 if part of multivolume set, 2 otherwise
780fbdfed81STyler Dauwalder	uint16 _max_interchange_level; //!< to be set to 3 unless otherwise directed by user
781fbdfed81STyler Dauwalder	uint32 _character_set_list;
782fbdfed81STyler Dauwalder	uint32 _max_character_set_list;
783d0da9166STyler Dauwalder	array<char, 128> _volume_set_identifier;
7841a2f87c1STyler Dauwalder
7851a2f87c1STyler Dauwalder	/*! \brief Identifies the character set for the \c volume_identifier
7861a2f87c1STyler Dauwalder		and \c volume_set_identifier fields.
7871a2f87c1STyler Dauwalder
7881a2f87c1STyler Dauwalder		To be set to CS0.
7891a2f87c1STyler Dauwalder	*/
7901379cacaSTyler Dauwalder	charspec _descriptor_character_set;
7911a2f87c1STyler Dauwalder
7921a2f87c1STyler Dauwalder	/*! \brief Identifies the character set used in the \c volume_abstract
7931a2f87c1STyler Dauwalder		and \c volume_copyright_notice extents.
7941a2f87c1STyler Dauwalder
7951a2f87c1STyler Dauwalder		To be set to CS0.
7961a2f87c1STyler Dauwalder	*/
7971379cacaSTyler Dauwalder	charspec _explanatory_character_set;
7981a2f87c1STyler Dauwalder
7991379cacaSTyler Dauwalder	extent_address _volume_abstract;
8001379cacaSTyler Dauwalder	extent_address _volume_copyright_notice;
8011a2f87c1STyler Dauwalder
8021379cacaSTyler Dauwalder	entity_id _application_id;
8031379cacaSTyler Dauwalder	timestamp _recording_date_and_time;
8041379cacaSTyler Dauwalder	entity_id _implementation_id;
80556f47960STyler Dauwalder	array<uint8, 64> _implementation_use;
806fbdfed81STyler Dauwalder	uint32 _predecessor_volume_descriptor_sequence_location;
807fbdfed81STyler Dauwalder	uint16 _flags;
8089b438e89STyler Dauwalder	array<uint8, 22> _reserved;
8091a2f87c1STyler Dauwalder
8101a2f87c1STyler Dauwalder} __attribute__((packed));
8111a2f87c1STyler Dauwalder
8121a2f87c1STyler Dauwalder
8131a2f87c1STyler Dauwalder/*! \brief Anchor Volume Descriptor Pointer
8141a2f87c1STyler Dauwalder
8151a2f87c1STyler Dauwalder	vd recorded at preset locations in the partition, used as a reference
8161a2f87c1STyler Dauwalder	point to the main vd sequences
8171a2f87c1STyler Dauwalder
8181a2f87c1STyler Dauwalder	According to UDF 2.01, an avdp shall be recorded in at least 2 of
8191a2f87c1STyler Dauwalder	the 3 following locations, where N is the last recordable sector
8201a2f87c1STyler Dauwalder	of the partition:
8211a2f87c1STyler Dauwalder	- 256
8221a2f87c1STyler Dauwalder	- (N - 256)
8231a2f87c1STyler Dauwalder	- N
8241a2f87c1STyler Dauwalder
8251a2f87c1STyler Dauwalder	See also: ECMA 167 3/10.2, UDF-2.01 2.2.3
8261a2f87c1STyler Dauwalder*/
8279b8775eaSTyler Dauwalderstruct anchor_volume_descriptor {
828fbdfed81STyler Dauwalderpublic:
82910186d5dSTyler Dauwalder	anchor_volume_descriptor() { memset(_reserved.data, 0, _reserved.size()); }
830d5366ff7STyler Dauwalder	void dump() const;
83156f47960STyler Dauwalder
8321379cacaSTyler Dauwalder	descriptor_tag & tag() { return _tag; }
8331379cacaSTyler Dauwalder	const descriptor_tag & tag() const { return _tag; }
834d5366ff7STyler Dauwalder
8351379cacaSTyler Dauwalder	extent_address& main_vds() { return _main_vds; }
8361379cacaSTyler Dauwalder	const extent_address& main_vds() const { return _main_vds; }
837d5366ff7STyler Dauwalder
8381379cacaSTyler Dauwalder	extent_address& reserve_vds() { return _reserve_vds; }
8391379cacaSTyler Dauwalder	const extent_address& reserve_vds() const { return _reserve_vds; }
840fbdfed81STyler Dauwalderprivate:
8411379cacaSTyler Dauwalder	descriptor_tag  _tag;
8421379cacaSTyler Dauwalder	extent_address _main_vds;	//!< min length of 16 sectors
8431379cacaSTyler Dauwalder	extent_address _reserve_vds;	//!< min length of 16 sectors
84410186d5dSTyler Dauwalder	array<uint8, 480> _reserved;
8451a2f87c1STyler Dauwalder} __attribute__((packed));
8461a2f87c1STyler Dauwalder
8471a2f87c1STyler Dauwalder
8481a2f87c1STyler Dauwalder/*! \brief Volume Descriptor Pointer
8491a2f87c1STyler Dauwalder
8501a2f87c1STyler Dauwalder	Used to chain extents of volume descriptor sequences together.
8511a2f87c1STyler Dauwalder
8521a2f87c1STyler Dauwalder	See also: ECMA 167 3/10.3
8531a2f87c1STyler Dauwalder*/
8541379cacaSTyler Dauwalderstruct descriptor_pointer {
8551379cacaSTyler Dauwalder	descriptor_tag  tag;
8561a2f87c1STyler Dauwalder	uint32 vds_number;
8571379cacaSTyler Dauwalder	extent_address next;
8581a2f87c1STyler Dauwalder} __attribute__((packed));
8591a2f87c1STyler Dauwalder
8601a2f87c1STyler Dauwalder
8619a043bf9STyler Dauwalder/*! \brief UDF Implementation Use Volume Descriptor struct found in
8629a043bf9STyler Dauwalder	implementation_use() field of implementation_use_descriptor when
8639a043bf9STyler Dauwalder	said descriptor's implementation_id() field specifies "*UDF LV Info"
8649a043bf9STyler Dauwalder
8659a043bf9STyler Dauwalder	See also: UDF 2.50 2.2.7
8669a043bf9STyler Dauwalder*/
8679a043bf9STyler Dauwalderstruct logical_volume_info {
8689a043bf9STyler Dauwalderpublic:
8699a043bf9STyler Dauwalder	void dump() const;
8709a043bf9STyler Dauwalder
8719a043bf9STyler Dauwalder	charspec& character_set() { return _character_set; }
8729a043bf9STyler Dauwalder	const charspec& character_set() const { return _character_set; }
8739a043bf9STyler Dauwalder
8749a043bf9STyler Dauwalder	array<char, 128>& logical_volume_id() { return _logical_volume_id; }
8759a043bf9STyler Dauwalder	const array<char, 128>& logical_volume_id() const { return _logical_volume_id; }
8769a043bf9STyler Dauwalder
8779a043bf9STyler Dauwalder	array<char, 36>& logical_volume_info_1() { return _logical_volume_info.data[0]; }
8789a043bf9STyler Dauwalder	const array<char, 36>& logical_volume_info_1() const { return _logical_volume_info.data[0]; }
8799a043bf9STyler Dauwalder
8809a043bf9STyler Dauwalder	array<char, 36>& logical_volume_info_2() { return _logical_volume_info.data[1]; }
8819a043bf9STyler Dauwalder	const array<char, 36>& logical_volume_info_2() const { return _logical_volume_info.data[1]; }
8829a043bf9STyler Dauwalder
8839a043bf9STyler Dauwalder	array<char, 36>& logical_volume_info_3() { return _logical_volume_info.data[2]; }
8849a043bf9STyler Dauwalder	const array<char, 36>& logical_volume_info_3() const { return _logical_volume_info.data[2]; }
8859a043bf9STyler Dauwalder
8869a043bf9STyler Dauwalder	entity_id& implementation_id() { return _implementation_id; }
8879a043bf9STyler Dauwalder	const entity_id& implementation_id() const { return _implementation_id; }
8889a043bf9STyler Dauwalder
8899a043bf9STyler Dauwalder	array<uint8, 128>& implementation_use() { return _implementation_use; }
8909a043bf9STyler Dauwalder	const array<uint8, 128>& implementation_use() const { return _implementation_use; }
8919a043bf9STyler Dauwalderprivate:
8929a043bf9STyler Dauwalder	charspec _character_set;
8939a043bf9STyler Dauwalder	array<char, 128> _logical_volume_id;				// d-string
8949a043bf9STyler Dauwalder	array<array<char, 36>, 3> _logical_volume_info;	// d-strings
8959a043bf9STyler Dauwalder	entity_id _implementation_id;
8969a043bf9STyler Dauwalder	array<uint8, 128> _implementation_use;
8979a043bf9STyler Dauwalder} __attribute__((packed));
8989a043bf9STyler Dauwalder
8991a2f87c1STyler Dauwalder/*! \brief Implementation Use Volume Descriptor
9001a2f87c1STyler Dauwalder
9011a2f87c1STyler Dauwalder	See also: ECMA 167 3/10.4
9021a2f87c1STyler Dauwalder*/
9031379cacaSTyler Dauwalderstruct implementation_use_descriptor {
90456f47960STyler Dauwalderpublic:
905d5366ff7STyler Dauwalder	void dump() const;
90656f47960STyler Dauwalder
90756f47960STyler Dauwalder	// Get functions
9081379cacaSTyler Dauwalder	const descriptor_tag & tag() const { return _tag; }
9091379cacaSTyler Dauwalder	descriptor_tag & tag() { return _tag; }
91056f47960STyler Dauwalder
91156f47960STyler Dauwalder	uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
91256f47960STyler Dauwalder
9131379cacaSTyler Dauwalder	const entity_id& implementation_id() const { return _implementation_id; }
9141379cacaSTyler Dauwalder	entity_id& implementation_id() { return _implementation_id; }
91556f47960STyler Dauwalder
91656f47960STyler Dauwalder	const array<uint8, 460>& implementation_use() const { return _implementation_use; }
91756f47960STyler Dauwalder	array<uint8, 460>& implementation_use() { return _implementation_use; }
91856f47960STyler Dauwalder
9199a043bf9STyler Dauwalder	// Only valid if implementation_id() returns Udf::kLogicalVolumeInfoId.
9209a043bf9STyler Dauwalder	logical_volume_info& info() { return *reinterpret_cast<logical_volume_info*>(_implementation_use.data); }
9219a043bf9STyler Dauwalder	const logical_volume_info& info() const { return *reinterpret_cast<const logical_volume_info*>(_implementation_use.data); }
9229a043bf9STyler Dauwalder
92356f47960STyler Dauwalder	// Set functions
92456f47960STyler Dauwalder	void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
92556f47960STyler Dauwalderprivate:
9261379cacaSTyler Dauwalder	descriptor_tag  _tag;
92756f47960STyler Dauwalder	uint32 _vds_number;
9281379cacaSTyler Dauwalder	entity_id _implementation_id;
92956f47960STyler Dauwalder	array<uint8, 460> _implementation_use;
9301a2f87c1STyler Dauwalder} __attribute__((packed));
9311a2f87c1STyler Dauwalder
9321a2f87c1STyler Dauwalder
93360fcc4e6STyler Dauwalder/*! \brief Maximum number of partition descriptors to be found in volume
93460fcc4e6STyler Dauwalder	descriptor sequence, per UDF-2.50
93560fcc4e6STyler Dauwalder*/
9369c707f06SJonathan Schleiferconst uint8 kMaxPartitionDescriptors = 2;
9374302df3cSTyler Dauwalder#define UDF_MAX_PARTITION_MAPS 2
93878b6ddeaSTyler Dauwalder#define UDF_MAX_PARTITION_MAP_SIZE 64
93960fcc4e6STyler Dauwalder
9401a2f87c1STyler Dauwalder/*! \brief Partition Descriptor
9411a2f87c1STyler Dauwalder
9421a2f87c1STyler Dauwalder	See also: ECMA 167 3/10.5
9431a2f87c1STyler Dauwalder*/
9441379cacaSTyler Dauwalderstruct partition_descriptor {
94556f47960STyler Dauwalderprivate:
94656f47960STyler Dauwalder	union partition_flags_accessor {
9471a2f87c1STyler Dauwalder		uint16 partition_flags;
948fbdfed81STyler Dauwalder		struct {
9491a2f87c1STyler Dauwalder			uint16 allocated:1,
9501a2f87c1STyler Dauwalder			       reserved:15;
95156f47960STyler Dauwalder		} bits;
9521a2f87c1STyler Dauwalder	};
9531a2f87c1STyler Dauwalder
95456f47960STyler Dauwalderpublic:
955d5366ff7STyler Dauwalder	void dump() const;
95656f47960STyler Dauwalder
95756f47960STyler Dauwalder	// Get functions
9581379cacaSTyler Dauwalder	const descriptor_tag & tag() const { return _tag; }
9591379cacaSTyler Dauwalder	descriptor_tag & tag() { return _tag; }
96056f47960STyler Dauwalder
96156f47960STyler Dauwalder	uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
96256f47960STyler Dauwalder	uint16 partition_flags() const { return B_LENDIAN_TO_HOST_INT16(_partition_flags); }
96356f47960STyler Dauwalder	bool allocated() const {
96456f47960STyler Dauwalder		partition_flags_accessor f;
96556f47960STyler Dauwalder		f.partition_flags = partition_flags();
96656f47960STyler Dauwalder		return f.bits.allocated;
96756f47960STyler Dauwalder	}
96856f47960STyler Dauwalder	uint16 partition_number() const { return B_LENDIAN_TO_HOST_INT16(_partition_number); }
96956f47960STyler Dauwalder
9701379cacaSTyler Dauwalder	const entity_id& partition_contents() const { return _partition_contents; }
9711379cacaSTyler Dauwalder	entity_id& partition_contents() { return _partition_contents; }
97256f47960STyler Dauwalder
97356f47960STyler Dauwalder	const array<uint8, 128>& partition_contents_use() const { return _partition_contents_use; }
97456f47960STyler Dauwalder	array<uint8, 128>& partition_contents_use() { return _partition_contents_use; }
97556f47960STyler Dauwalder
97656f47960STyler Dauwalder	uint32 access_type() const { return B_LENDIAN_TO_HOST_INT32(_access_type); }
97756f47960STyler Dauwalder	uint32 start() const { return B_LENDIAN_TO_HOST_INT32(_start); }
97856f47960STyler Dauwalder	uint32 length() const { return B_LENDIAN_TO_HOST_INT32(_length); }
97956f47960STyler Dauwalder
9801379cacaSTyler Dauwalder	const entity_id& implementation_id() const { return _implementation_id; }
9811379cacaSTyler Dauwalder	entity_id& implementation_id() { return _implementation_id; }
98256f47960STyler Dauwalder
98356f47960STyler Dauwalder	const array<uint8, 128>& implementation_use() const { return _implementation_use; }
98456f47960STyler Dauwalder	array<uint8, 128>& implementation_use() { return _implementation_use; }
98556f47960STyler Dauwalder
986003d4e83STyler Dauwalder	const array<uint8, 156>& reserved() const { return _reserved; }
987003d4e83STyler Dauwalder	array<uint8, 156>& reserved() { return _reserved; }
988003d4e83STyler Dauwalder
98956f47960STyler Dauwalder	// Set functions
99056f47960STyler Dauwalder	void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
99156f47960STyler Dauwalder	void set_partition_flags(uint16 flags) { _partition_flags = B_HOST_TO_LENDIAN_INT16(flags); }
99256f47960STyler Dauwalder	void set_allocated(bool allocated) {
99356f47960STyler Dauwalder		partition_flags_accessor f;
99456f47960STyler Dauwalder		f.partition_flags = partition_flags();
99556f47960STyler Dauwalder		f.bits.allocated = allocated;
99656f47960STyler Dauwalder		set_partition_flags(f.partition_flags);
99756f47960STyler Dauwalder	}
998003d4e83STyler Dauwalder	void set_partition_number(uint16 number) { _partition_number = B_HOST_TO_LENDIAN_INT16(number); }
99956f47960STyler Dauwalder	void set_access_type(uint32 type) { _access_type = B_HOST_TO_LENDIAN_INT32(type); }
100056f47960STyler Dauwalder	void set_start(uint32 start) { _start = B_HOST_TO_LENDIAN_INT32(start); }
100156f47960STyler Dauwalder	void set_length(uint32 length) { _length = B_HOST_TO_LENDIAN_INT32(length); }
100256f47960STyler Dauwalder
100356f47960STyler Dauwalderprivate:
10041379cacaSTyler Dauwalder	descriptor_tag  _tag;
100556f47960STyler Dauwalder	uint32 _vds_number;
100656f47960STyler Dauwalder	/*! Bit 0: If 0, shall mean volume space has not been allocated. If 1,
100756f47960STyler Dauwalder	    shall mean volume space has been allocated.
100856f47960STyler Dauwalder	*/
100956f47960STyler Dauwalder	uint16 _partition_flags;
101056f47960STyler Dauwalder	uint16 _partition_number;
101156f47960STyler Dauwalder
10121a2f87c1STyler Dauwalder	/*! - "+NSR03" Volume recorded according to ECMA-167, i.e. UDF
10131a2f87c1STyler Dauwalder		- "+CD001" Volume recorded according to ECMA-119, i.e. iso9660
10141a2f87c1STyler Dauwalder		- "+FDC01" Volume recorded according to ECMA-107
10151a2f87c1STyler Dauwalder		- "+CDW02" Volume recorded according to ECMA-168
10161a2f87c1STyler Dauwalder	*/
10171379cacaSTyler Dauwalder	entity_id _partition_contents;
101856f47960STyler Dauwalder	array<uint8, 128> _partition_contents_use;
10191a2f87c1STyler Dauwalder
10201a2f87c1STyler Dauwalder	/*! See \c partition_access_type enum
10211a2f87c1STyler Dauwalder	*/
102256f47960STyler Dauwalder	uint32 _access_type;
102356f47960STyler Dauwalder	uint32 _start;
102456f47960STyler Dauwalder	uint32 _length;
10251379cacaSTyler Dauwalder	entity_id _implementation_id;
102656f47960STyler Dauwalder	array<uint8, 128> _implementation_use;
1027003d4e83STyler Dauwalder	array<uint8, 156> _reserved;
10281a2f87c1STyler Dauwalder} __attribute__((packed));
10291a2f87c1STyler Dauwalder
10301a2f87c1STyler Dauwalder
10311a2f87c1STyler Dauwalderenum partition_access_type {
1032003d4e83STyler Dauwalder	ACCESS_UNSPECIFIED,
1033003d4e83STyler Dauwalder	ACCESS_READ_ONLY,
1034003d4e83STyler Dauwalder	ACCESS_WRITE_ONCE,
1035003d4e83STyler Dauwalder	ACCESS_REWRITABLE,
1036003d4e83STyler Dauwalder	ACCESS_OVERWRITABLE,
10371a2f87c1STyler Dauwalder};
10381a2f87c1STyler Dauwalder
10391a2f87c1STyler Dauwalder
10401a2f87c1STyler Dauwalder/*! \brief Logical volume descriptor
10411a2f87c1STyler Dauwalder
10421a2f87c1STyler Dauwalder	See also: ECMA 167 3/10.6, UDF-2.01 2.2.4
10431a2f87c1STyler Dauwalder*/
10449b8775eaSTyler Dauwalderstruct logical_volume_descriptor {
1045d5366ff7STyler Dauwalder	void dump() const;
104656f47960STyler Dauwalder
104756f47960STyler Dauwalder	// Get functions
10481379cacaSTyler Dauwalder	const descriptor_tag & tag() const { return _tag; }
10491379cacaSTyler Dauwalder	descriptor_tag & tag() { return _tag; }
105056f47960STyler Dauwalder
105156f47960STyler Dauwalder	uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
105256f47960STyler Dauwalder
10531379cacaSTyler Dauwalder	const charspec& character_set() const { return _character_set; }
10541379cacaSTyler Dauwalder	charspec& character_set() { return _character_set; }
105556f47960STyler Dauwalder
1056d0da9166STyler Dauwalder	const array<char, 128>& logical_volume_identifier() const { return _logical_volume_identifier; }
1057d0da9166STyler Dauwalder	array<char, 128>& logical_volume_identifier() { return _logical_volume_identifier; }
105856f47960STyler Dauwalder
105956f47960STyler Dauwalder	uint32 logical_block_size() const { return B_LENDIAN_TO_HOST_INT32(_logical_block_size); }
106056f47960STyler Dauwalder
10611379cacaSTyler Dauwalder	const entity_id& domain_id() const { return _domain_id; }
10621379cacaSTyler Dauwalder	entity_id& domain_id() { return _domain_id; }
106356f47960STyler Dauwalder
106456f47960STyler Dauwalder	const array<uint8, 16>& logical_volume_contents_use() const { return _logical_volume_contents_use; }
106556f47960STyler Dauwalder	array<uint8, 16>& logical_volume_contents_use() { return _logical_volume_contents_use; }
106656f47960STyler Dauwalder
1067d1a0387eSTyler Dauwalder	const long_address& file_set_address() const { return *reinterpret_cast<const long_address*>(&_logical_volume_contents_use); }
1068d1a0387eSTyler Dauwalder	long_address& file_set_address() { return *reinterpret_cast<long_address*>(&_logical_volume_contents_use); }
106956f47960STyler Dauwalder
107056f47960STyler Dauwalder	uint32 map_table_length() const { return B_LENDIAN_TO_HOST_INT32(_map_table_length); }
107156f47960STyler Dauwalder	uint32 partition_map_count() const { return B_LENDIAN_TO_HOST_INT32(_partition_map_count); }
107256f47960STyler Dauwalder
10731379cacaSTyler Dauwalder	const entity_id& implementation_id() const { return _implementation_id; }
10741379cacaSTyler Dauwalder	entity_id& implementation_id() { return _implementation_id; }
107556f47960STyler Dauwalder
107656f47960STyler Dauwalder	const array<uint8, 128>& implementation_use() const { return _implementation_use; }
107756f47960STyler Dauwalder	array<uint8, 128>& implementation_use() { return _implementation_use; }
107856f47960STyler Dauwalder
10791379cacaSTyler Dauwalder	const extent_address& integrity_sequence_extent() const { return _integrity_sequence_extent; }
10801379cacaSTyler Dauwalder	extent_address& integrity_sequence_extent() { return _integrity_sequence_extent; }
108156f47960STyler Dauwalder
108256f47960STyler Dauwalder	const uint8* partition_maps() const { return _partition_maps; }
108356f47960STyler Dauwalder	uint8* partition_maps() { return _partition_maps; }
108456f47960STyler Dauwalder
108556f47960STyler Dauwalder	// Set functions
108656f47960STyler Dauwalder	void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
108756f47960STyler Dauwalder	void set_logical_block_size(uint32 size) { _logical_block_size = B_HOST_TO_LENDIAN_INT32(size); }
108856f47960STyler Dauwalder
108956f47960STyler Dauwalder	void set_map_table_length(uint32 length) { _map_table_length = B_HOST_TO_LENDIAN_INT32(length); }
109056f47960STyler Dauwalder	void set_partition_map_count(uint32 count) { _partition_map_count = B_HOST_TO_LENDIAN_INT32(count); }
109156f47960STyler Dauwalder
10924302df3cSTyler Dauwalder	// Other functions
10939b8775eaSTyler Dauwalder	logical_volume_descriptor& operator=(const logical_volume_descriptor &rhs);
10944302df3cSTyler Dauwalder
109556f47960STyler Dauwalderprivate:
10961379cacaSTyler Dauwalder	descriptor_tag  _tag;
109756f47960STyler Dauwalder	uint32 _vds_number;
10981a2f87c1STyler Dauwalder
10991a2f87c1STyler Dauwalder	/*! \brief Identifies the character set for the
11001a2f87c1STyler Dauwalder		\c logical_volume_identifier field.
11011a2f87c1STyler Dauwalder
11021a2f87c1STyler Dauwalder		To be set to CS0.
11031a2f87c1STyler Dauwalder	*/
11041379cacaSTyler Dauwalder	charspec _character_set;
1105d0da9166STyler Dauwalder	array<char, 128> _logical_volume_identifier;
110656f47960STyler Dauwalder	uint32 _logical_block_size;
11071a2f87c1STyler Dauwalder
11081a2f87c1STyler Dauwalder	/*! \brief To be set to 0 or "*OSTA UDF Compliant". See UDF specs.
11091a2f87c1STyler Dauwalder	*/
11101379cacaSTyler Dauwalder	entity_id _domain_id;
11111a2f87c1STyler Dauwalder
1112d1a0387eSTyler Dauwalder	/*! \brief For UDF, shall contain a \c long_address which identifies
1113d1a0387eSTyler Dauwalder		the location of the logical volume's first file set.
1114d1a0387eSTyler Dauwalder	*/
1115d1a0387eSTyler Dauwalder	array<uint8, 16> _logical_volume_contents_use;
1116edd2334cSTyler Dauwalder
111756f47960STyler Dauwalder	uint32 _map_table_length;
111856f47960STyler Dauwalder	uint32 _partition_map_count;
11191379cacaSTyler Dauwalder	entity_id _implementation_id;
112056f47960STyler Dauwalder	array<uint8, 128> _implementation_use;
11211a2f87c1STyler Dauwalder
11221a2f87c1STyler Dauwalder	/*! \brief Logical volume integrity sequence location.
11231a2f87c1STyler Dauwalder
11241a2f87c1STyler Dauwalder		For re/overwritable media, shall be a min of 8KB in length.
11251a2f87c1STyler Dauwalder		For WORM media, shall be quite frickin large, as a new volume
11261a2f87c1STyler Dauwalder		must be added to the set if the extent fills up (since you
11271a2f87c1STyler Dauwalder		can't chain lvis's I guess).
11281a2f87c1STyler Dauwalder	*/
11291379cacaSTyler Dauwalder	extent_address _integrity_sequence_extent;
11301a2f87c1STyler Dauwalder
11311a2f87c1STyler Dauwalder	/*! \brief Restricted to maps of type 1 for normal maps and
1132edd2334cSTyler Dauwalder		UDF type 2 for virtual maps or maps on systems not supporting
11331a2f87c1STyler Dauwalder		defect management.
11341a2f87c1STyler Dauwalder
113578b6ddeaSTyler Dauwalder		Note that we actually allocate memory for the partition maps
11369b8775eaSTyler Dauwalder		here due to the fact that we allocate logical_volume_descriptor
113778b6ddeaSTyler Dauwalder		objects on the stack sometimes.
113878b6ddeaSTyler Dauwalder
11391a2f87c1STyler Dauwalder		See UDF-2.01 2.2.8, 2.2.9
11401a2f87c1STyler Dauwalder	*/
114178b6ddeaSTyler Dauwalder	uint8 _partition_maps[UDF_MAX_PARTITION_MAPS * UDF_MAX_PARTITION_MAP_SIZE];
1142edd2334cSTyler Dauwalder} __attribute__((packed));
11431a2f87c1STyler Dauwalder
1144730ba00aSTyler Dauwalder//! Base size (excluding partition maps) of lvd
1145730ba00aSTyler Dauwalderextern const uint32 kLogicalVolumeDescriptorBaseSize;
11461a2f87c1STyler Dauwalder
114778b6ddeaSTyler Dauwalder/*! \brief (Mostly) common portion of various partition maps
11481a2f87c1STyler Dauwalder
11491a2f87c1STyler Dauwalder	See also: ECMA-167 3/10.7.1
11501a2f87c1STyler Dauwalder*/
11511379cacaSTyler Dauwalderstruct partition_map_header {
11524302df3cSTyler Dauwalderpublic:
11534302df3cSTyler Dauwalder	uint8 type() const { return _type; }
11544302df3cSTyler Dauwalder	uint8 length() const { return _length; }
11554302df3cSTyler Dauwalder	uint8 *map_data() { return _map_data; }
11564302df3cSTyler Dauwalder	const uint8 *map_data() const { return _map_data; }
115778b6ddeaSTyler Dauwalder
11581379cacaSTyler Dauwalder	entity_id& partition_type_id()
11591379cacaSTyler Dauwalder		{ return *reinterpret_cast<entity_id*>(&_map_data[2]); }
11601379cacaSTyler Dauwalder	const entity_id& partition_type_id() const
11611379cacaSTyler Dauwalder		{ return *reinterpret_cast<const entity_id*>(&_map_data[2]); }
11624302df3cSTyler Dauwalder
11634302df3cSTyler Dauwalder	void set_type(uint8 type) { _type = type; }
11644302df3cSTyler Dauwalder	void set_length(uint8 length) { _length = length; }
11654302df3cSTyler Dauwalderprivate:
11664302df3cSTyler Dauwalder	uint8 _type;
11674302df3cSTyler Dauwalder	uint8 _length;
11684302df3cSTyler Dauwalder	uint8 _map_data[0];
11694302df3cSTyler Dauwalder};// __attribute__((packed));
1170edd2334cSTyler Dauwalder
11711a2f87c1STyler Dauwalder
11721a2f87c1STyler Dauwalder/*! \brief Physical partition map (i.e. ECMA-167 Type 1 partition map)
11731a2f87c1STyler Dauwalder
11741a2f87c1STyler Dauwalder	See also: ECMA-167 3/10.7.2
11751a2f87c1STyler Dauwalder*/
11761379cacaSTyler Dauwalderstruct physical_partition_map {
11774302df3cSTyler Dauwalderpublic:
11784302df3cSTyler Dauwalder	void dump();
11794302df3cSTyler Dauwalder
11804302df3cSTyler Dauwalder	uint8 type() const { return _type; }
11814302df3cSTyler Dauwalder	uint8 length() const { return _length; }
11824302df3cSTyler Dauwalder
11834302df3cSTyler Dauwalder	uint16 volume_sequence_number() const {
11844302df3cSTyler Dauwalder		return B_LENDIAN_TO_HOST_INT16(_volume_sequence_number); }
11854302df3cSTyler Dauwalder	uint16 partition_number() const {
11864302df3cSTyler Dauwalder		return B_LENDIAN_TO_HOST_INT16(_partition_number); }
11874302df3cSTyler Dauwalder
11884302df3cSTyler Dauwalder	void set_type(uint8 type) { _type = type; }
11894302df3cSTyler Dauwalder	void set_length(uint8 length) { _length = length; }
11904302df3cSTyler Dauwalder	void set_volume_sequence_number(uint16 number) {
11914302df3cSTyler Dauwalder		_volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); }
11924302df3cSTyler Dauwalder	void set_partition_number(uint16 number) {
11934302df3cSTyler Dauwalder		_partition_number = B_HOST_TO_LENDIAN_INT16(number); }
11944302df3cSTyler Dauwalderprivate:
11954302df3cSTyler Dauwalder	uint8 _type;
11964302df3cSTyler Dauwalder	uint8 _length;
11974302df3cSTyler Dauwalder	uint16 _volume_sequence_number;
11984302df3cSTyler Dauwalder	uint16 _partition_number;
1199edd2334cSTyler Dauwalder} __attribute__((packed));
1200edd2334cSTyler Dauwalder
12011a2f87c1STyler Dauwalder
1202edd2334cSTyler Dauwalder/* ----UDF Specific---- */
12034302df3cSTyler Dauwalder/*! \brief Virtual partition map
12041a2f87c1STyler Dauwalder
12054302df3cSTyler Dauwalder	Note that this map is a customization of the ECMA-167
12064302df3cSTyler Dauwalder	type 2 partition map.
12071a2f87c1STyler Dauwalder
12081a2f87c1STyler Dauwalder	See also: UDF-2.01 2.2.8
12091a2f87c1STyler Dauwalder*/
12101379cacaSTyler Dauwalderstruct virtual_partition_map {
12111a2f87c1STyler Dauwalder	uint8 type;
12121a2f87c1STyler Dauwalder	uint8 length;
12131a2f87c1STyler Dauwalder	uint8 reserved1[2];
12141a2f87c1STyler Dauwalder
12151a2f87c1STyler Dauwalder	/*! - flags: 0
12161a2f87c1STyler Dauwalder	    - identifier: "*UDF Virtual Partition"
12171a2f87c1STyler Dauwalder	    - identifier_suffix: per UDF-2.01 2.1.5.3
12181a2f87c1STyler Dauwalder	*/
12191379cacaSTyler Dauwalder	entity_id partition_type_id;
12201a2f87c1STyler Dauwalder	uint16 volume_sequence_number;
12211a2f87c1STyler Dauwalder
12221a2f87c1STyler Dauwalder	/*! corresponding type 1 partition map in same logical volume
12231a2f87c1STyler Dauwalder	*/
12241a2f87c1STyler Dauwalder	uint16 partition_number;
12251a2f87c1STyler Dauwalder	uint8 reserved2[24];
1226edd2334cSTyler Dauwalder} __attribute__((packed));
1227edd2334cSTyler Dauwalder
12281a2f87c1STyler Dauwalder
12294302df3cSTyler Dauwalder/*! \brief Maximum number of redundant sparing tables found in
12301379cacaSTyler Dauwalder	sparable_partition_map structures.
12314302df3cSTyler Dauwalder*/
12324302df3cSTyler Dauwalder#define UDF_MAX_SPARING_TABLE_COUNT 4
12334302df3cSTyler Dauwalder
12344302df3cSTyler Dauwalder/* ----UDF Specific---- */
12354302df3cSTyler Dauwalder/*! \brief Sparable partition map
12364302df3cSTyler Dauwalder
12374302df3cSTyler Dauwalder	Note that this map is a customization of the ECMA-167
12384302df3cSTyler Dauwalder	type 2 partition map.
12394302df3cSTyler Dauwalder
12404302df3cSTyler Dauwalder	See also: UDF-2.01 2.2.9
12414302df3cSTyler Dauwalder*/
12421379cacaSTyler Dauwalderstruct sparable_partition_map {
12434302df3cSTyler Dauwalderpublic:
12444302df3cSTyler Dauwalder	void dump();
12454302df3cSTyler Dauwalder
12464302df3cSTyler Dauwalder	uint8 type() const { return _type; }
12474302df3cSTyler Dauwalder	uint8 length() const { return _length; }
12484302df3cSTyler Dauwalder
12491379cacaSTyler Dauwalder	entity_id& partition_type_id() { return _partition_type_id; }
12501379cacaSTyler Dauwalder	const entity_id& partition_type_id() const { return _partition_type_id; }
12514302df3cSTyler Dauwalder
12524302df3cSTyler Dauwalder	uint16 volume_sequence_number() const {
12534302df3cSTyler Dauwalder		return B_LENDIAN_TO_HOST_INT16(_volume_sequence_number); }
12544302df3cSTyler Dauwalder	uint16 partition_number() const {
12554302df3cSTyler Dauwalder		return B_LENDIAN_TO_HOST_INT16(_partition_number); }
12564302df3cSTyler Dauwalder	uint16 packet_length() const {
12574302df3cSTyler Dauwalder		return B_LENDIAN_TO_HOST_INT16(_packet_length); }
12584302df3cSTyler Dauwalder	uint8 sparing_table_count() const { return _sparing_table_count; }
12594302df3cSTyler Dauwalder	uint32 sparing_table_size() const {
12604302df3cSTyler Dauwalder		return B_LENDIAN_TO_HOST_INT32(_sparing_table_size); }
12614302df3cSTyler Dauwalder	uint32 sparing_table_location(uint8 index) const {
12624302df3cSTyler Dauwalder		return B_LENDIAN_TO_HOST_INT32(_sparing_table_locations[index]); }
12634302df3cSTyler Dauwalder
12644302df3cSTyler Dauwalder
12654302df3cSTyler Dauwalder	void set_type(uint8 type) { _type = type; }
12664302df3cSTyler Dauwalder	void set_length(uint8 length) { _length = length; }
12674302df3cSTyler Dauwalder	void set_volume_sequence_number(uint16 number) {
12684302df3cSTyler Dauwalder		_volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); }
12694302df3cSTyler Dauwalder	void set_partition_number(uint16 number) {
12704302df3cSTyler Dauwalder		_partition_number = B_HOST_TO_LENDIAN_INT16(number); }
12714302df3cSTyler Dauwalder	void set_packet_length(uint16 length) {
12724302df3cSTyler Dauwalder		_packet_length = B_HOST_TO_LENDIAN_INT16(length); }
12734302df3cSTyler Dauwalder	void set_sparing_table_count(uint8 count) {
12744302df3cSTyler Dauwalder		_sparing_table_count = count; }
12754302df3cSTyler Dauwalder	void set_sparing_table_size(uint32 size) {
12764302df3cSTyler Dauwalder		_sparing_table_size = B_HOST_TO_LENDIAN_INT32(size); }
12774302df3cSTyler Dauwalder	void set_sparing_table_location(uint8 index, uint32 location) {
12784302df3cSTyler Dauwalder		_sparing_table_locations[index] = B_HOST_TO_LENDIAN_INT32(location); }
12794302df3cSTyler Dauwalderprivate:
12804302df3cSTyler Dauwalder	uint8 _type;
12814302df3cSTyler Dauwalder	uint8 _length;
12824302df3cSTyler Dauwalder	uint8 _reserved1[2];
12834302df3cSTyler Dauwalder
12844302df3cSTyler Dauwalder	/*! - flags: 0
12854302df3cSTyler Dauwalder	    - identifier: "*UDF Sparable Partition"
12864302df3cSTyler Dauwalder	    - identifier_suffix: per UDF-2.01 2.1.5.3
12874302df3cSTyler Dauwalder	*/
12881379cacaSTyler Dauwalder	entity_id _partition_type_id;
12894302df3cSTyler Dauwalder	uint16 _volume_sequence_number;
12904302df3cSTyler Dauwalder
12914302df3cSTyler Dauwalder	//! partition number of corresponding partition descriptor
12924302df3cSTyler Dauwalder	uint16 _partition_number;
12934302df3cSTyler Dauwalder	uint16 _packet_length;
12944302df3cSTyler Dauwalder	uint8 _sparing_table_count;
12954302df3cSTyler Dauwalder	uint8 _reserved2;
12964302df3cSTyler Dauwalder	uint32 _sparing_table_size;
12974302df3cSTyler Dauwalder	uint32 _sparing_table_locations[UDF_MAX_SPARING_TABLE_COUNT];
12984302df3cSTyler Dauwalder} __attribute__((packed));
12994302df3cSTyler Dauwalder
13004302df3cSTyler Dauwalder
130178b6ddeaSTyler Dauwalder/* ----UDF Specific---- */
130278b6ddeaSTyler Dauwalder/*! \brief Metadata partition map
130378b6ddeaSTyler Dauwalder
130478b6ddeaSTyler Dauwalder	Note that this map is a customization of the ECMA-167
130578b6ddeaSTyler Dauwalder	type 2 partition map.
130678b6ddeaSTyler Dauwalder
130778b6ddeaSTyler Dauwalder	See also: UDF-2.50 2.2.10
130878b6ddeaSTyler Dauwalder*/
13091379cacaSTyler Dauwalderstruct metadata_partition_map {
1310c530d46cSJérôme Duvalpublic:
1311c530d46cSJérôme Duval	entity_id& partition_type_id() { return _partition_type_id; }
1312c530d46cSJérôme Duval	const entity_id& partition_type_id() const { return _partition_type_id; }
1313c530d46cSJérôme Duval
1314c530d46cSJérôme Duval	uint16 volume_sequence_number() const {
1315c530d46cSJérôme Duval		return B_LENDIAN_TO_HOST_INT16(_volume_sequence_number); }
1316c530d46cSJérôme Duval	void set_volume_sequence_number(uint16 number) {
1317c530d46cSJérôme Duval		_volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); }
1318c530d46cSJérôme Duval
1319c530d46cSJérôme Duval	uint16 partition_number() const {
1320c530d46cSJérôme Duval		return B_LENDIAN_TO_HOST_INT16(_partition_number); }
1321c530d46cSJérôme Duval	void set_partition_number(uint16 number) {
1322c530d46cSJérôme Duval		_partition_number = B_HOST_TO_LENDIAN_INT16(number); }
1323c530d46cSJérôme Duval
1324c530d46cSJérôme Duval	uint32 metadata_file_location() const {
1325c530d46cSJérôme Duval		return B_LENDIAN_TO_HOST_INT32(_metadata_file_location); }
1326c530d46cSJérôme Duval	void set_metadata_file_location(uint32 location) {
1327c530d46cSJérôme Duval		_metadata_file_location = B_HOST_TO_LENDIAN_INT32(location); }
1328c530d46cSJérôme Duval
1329c530d46cSJérôme Duval	uint32 metadata_mirror_file_location() const {
1330c530d46cSJérôme Duval		return B_LENDIAN_TO_HOST_INT32(_metadata_mirror_file_location); }
1331c530d46cSJérôme Duval	void set_metadata_mirror_file_location(uint32 location) {
1332c530d46cSJérôme Duval		_metadata_mirror_file_location = B_HOST_TO_LENDIAN_INT32(location); }
1333c530d46cSJérôme Duval
1334c530d46cSJérôme Duval	uint32 metadata_bitmap_file_location() const {
1335c530d46cSJérôme Duval		return B_LENDIAN_TO_HOST_INT32(_metadata_bitmap_file_location); }
1336c530d46cSJérôme Duval	void set_metadata_bitmap_file_location(uint32 location) {
1337c530d46cSJérôme Duval		_metadata_bitmap_file_location = B_HOST_TO_LENDIAN_INT32(location); }
1338c530d46cSJérôme Duval
1339c530d46cSJérôme Duval	uint32 allocation_unit_size() const {
1340c530d46cSJérôme Duval		return B_LENDIAN_TO_HOST_INT32(_allocation_unit_size); }
1341c530d46cSJérôme Duval	void set_allocation_unit_size(uint32 size) {
1342c530d46cSJérôme Duval		_allocation_unit_size = B_HOST_TO_LENDIAN_INT32(size); }
1343c530d46cSJérôme Duval
1344c530d46cSJérôme Duval	uint32 alignment_unit_size() const {
1345c530d46cSJérôme Duval		return B_LENDIAN_TO_HOST_INT32(_alignment_unit_size); }
1346c530d46cSJérôme Duval	void set_alignment_unit_size(uint32 size) {
1347c530d46cSJérôme Duval		_alignment_unit_size = B_HOST_TO_LENDIAN_INT32(size); }
1348c530d46cSJérôme Duval
1349c530d46cSJérôme Duval	uint8 flags() const { return _flags; }
1350c530d46cSJérôme Duval	void set_flags(uint8 flags) { _flags = flags; }
1351c530d46cSJérôme Duval
1352c530d46cSJérôme Duvalprivate:
135378b6ddeaSTyler Dauwalder	uint8 type;
135478b6ddeaSTyler Dauwalder	uint8 length;
135578b6ddeaSTyler Dauwalder	uint8 reserved1[2];
135678b6ddeaSTyler Dauwalder
135778b6ddeaSTyler Dauwalder	/*! - flags: 0
135878b6ddeaSTyler Dauwalder	    - identifier: "*UDF Metadata Partition"
135978b6ddeaSTyler Dauwalder	    - identifier_suffix: per UDF-2.50 2.1.5
136078b6ddeaSTyler Dauwalder	*/
1361c530d46cSJérôme Duval	entity_id _partition_type_id;
1362c530d46cSJérôme Duval	uint16 _volume_sequence_number;
136378b6ddeaSTyler Dauwalder
136478b6ddeaSTyler Dauwalder	/*! corresponding type 1 or type 2 sparable partition
136578b6ddeaSTyler Dauwalder	    map in same logical volume
136678b6ddeaSTyler Dauwalder	*/
1367c530d46cSJérôme Duval	uint16 _partition_number;
1368c530d46cSJérôme Duval	uint32 _metadata_file_location;
1369c530d46cSJérôme Duval	uint32 _metadata_mirror_file_location;
1370c530d46cSJérôme Duval	uint32 _metadata_bitmap_file_location;
1371c530d46cSJérôme Duval	uint32 _allocation_unit_size;
1372c530d46cSJérôme Duval	uint16 _alignment_unit_size;
1373c530d46cSJérôme Duval	uint8 _flags;
1374c530d46cSJérôme Duval	uint8 reserved2[5];
137578b6ddeaSTyler Dauwalder} __attribute__((packed));
137678b6ddeaSTyler Dauwalder
137778b6ddeaSTyler Dauwalder
13781a2f87c1STyler Dauwalder/*! \brief Unallocated space descriptor
13791a2f87c1STyler Dauwalder
13801a2f87c1STyler Dauwalder	See also: ECMA-167 3/10.8
13811a2f87c1STyler Dauwalder*/
13821379cacaSTyler Dauwalderstruct unallocated_space_descriptor {
1383d5366ff7STyler Dauwalder	void dump() const;
138456f47960STyler Dauwalder
138556f47960STyler Dauwalder	// Get functions
13861379cacaSTyler Dauwalder	const descriptor_tag & tag() const { return _tag; }
13871379cacaSTyler Dauwalder	descriptor_tag & tag() { return _tag; }
138856f47960STyler Dauwalder	uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
138956f47960STyler Dauwalder	uint32 allocation_descriptor_count() const { return B_LENDIAN_TO_HOST_INT32(_allocation_descriptor_count); }
13901379cacaSTyler Dauwalder	extent_address* allocation_descriptors() { return _allocation_descriptors; }
139156f47960STyler Dauwalder
139256f47960STyler Dauwalder	// Set functions
139356f47960STyler Dauwalder	void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
139456f47960STyler Dauwalder	void set_allocation_descriptor_count(uint32 count) { _allocation_descriptor_count = B_HOST_TO_LENDIAN_INT32(count); }
139556f47960STyler Dauwalderprivate:
13961379cacaSTyler Dauwalder	descriptor_tag  _tag;
139756f47960STyler Dauwalder	uint32 _vds_number;
139856f47960STyler Dauwalder	uint32 _allocation_descriptor_count;
13991379cacaSTyler Dauwalder	extent_address _allocation_descriptors[0];
14001a2f87c1STyler Dauwalder} __attribute__((packed));
14011a2f87c1STyler Dauwalder
14021a2f87c1STyler Dauwalder
14031a2f87c1STyler Dauwalder/*! \brief Terminating descriptor
14041a2f87c1STyler Dauwalder
14051a2f87c1STyler Dauwalder	See also: ECMA-167 3/10.9
14061a2f87c1STyler Dauwalder*/
14071379cacaSTyler Dauwalderstruct terminating_descriptor {
140810186d5dSTyler Dauwalder	terminating_descriptor() { memset(_reserved.data, 0, _reserved.size()); }
1409d5366ff7STyler Dauwalder	void dump() const;
141056f47960STyler Dauwalder
141156f47960STyler Dauwalder	// Get functions
14121379cacaSTyler Dauwalder	const descriptor_tag & tag() const { return _tag; }
14131379cacaSTyler Dauwalder	descriptor_tag & tag() { return _tag; }
141456f47960STyler Dauwalderprivate:
14151379cacaSTyler Dauwalder	descriptor_tag  _tag;
141610186d5dSTyler Dauwalder	array<uint8, 496> _reserved;
14171a2f87c1STyler Dauwalder} __attribute__((packed));
14181a2f87c1STyler Dauwalder
14191a2f87c1STyler Dauwalder
14201a2f87c1STyler Dauwalder/*! \brief Logical volume integrity descriptor
14211a2f87c1STyler Dauwalder
1422