xref: /haiku/src/add-ons/kernel/file_systems/udf/UdfStructures.h (revision d1a0387efb0f49eca7af9e5e7846d7769aed001b)
1 //----------------------------------------------------------------------
2 // This software is part of the OpenBeOS distribution and is covered
3 //  by the OpenBeOS license.
4 //
5 //  Copyright (c) 2003 Tyler Dauwalder, tyler@dauwalder.net
6 //---------------------------------------------------------------------
7 #ifndef _UDF_DISK_STRUCTURES_H
8 #define _UDF_DISK_STRUCTURES_H
9 
10 #include <string.h>
11 
12 #include <ByteOrder.h>
13 #include <SupportDefs.h>
14 
15 #include "kernel_cpp.h"
16 #include "UdfDebug.h"
17 
18 #include "Array.h"
19 
20 /*! \file UdfStructures.h
21 
22 	\brief UDF on-disk data structure declarations
23 
24 	UDF is a specialization of the ECMA-167 standard. For the most part,
25 	ECMA-167 structures are used by UDF with special restrictions. In a
26 	few instances, UDF introduces its own structures to augment those
27 	supplied by ECMA-167; those structures are clearly marked.
28 
29 	For UDF info: <a href='http://www.osta.org'>http://www.osta.org</a>
30 	For ECMA info: <a href='http://www.ecma-international.org'>http://www.ecma-international.org</a>
31 
32 	For lack of a better place to store this info, the structures that
33 	are allowed to have length greater than the logical block size are
34 	as follows (other length restrictions may be found in UDF-2.01 5.1):
35 	- \c logical_volume_descriptor
36 	- \c unallocated_space_descriptor
37 	- \c logical_volume_integrity_descriptor
38 	- \c space_bitmap_descriptor
39 
40 	Other links of interest:
41 	- <a href='http://www.extra.research.philips.com/udf/'>Philips UDF verifier</a>
42 	- <a href='http://www.hi-ho.ne.jp/y-komachi/committees/fpro/fpro.htm'>Possible test disc image generator (?)</a>
43 */
44 
45 namespace Udf {
46 
47 //----------------------------------------------------------------------
48 // ECMA-167 Part 1
49 //----------------------------------------------------------------------
50 
51 /*! \brief Character set specifications
52 
53 	The character_set_info field shall be set to the ASCII string
54 	"OSTA Compressed Unicode" (padded right with NULL chars).
55 
56 	See also: ECMA 167 1/7.2.1, UDF-2.01 2.1.2
57 */
58 struct charspec {
59 public:
60 	charspec(uint8 type = 0, const char *info = NULL);
61 
62 	void dump() const;
63 
64 	uint8 character_set_type() const { return _character_set_type; }
65 	const char* character_set_info() const { return _character_set_info; }
66 	char* character_set_info() { return _character_set_info; }
67 
68 	void set_character_set_type(uint8 type) { _character_set_type = type; }
69 	void set_character_set_info(const char *info);
70 private:
71 	uint8 _character_set_type;	//!< to be set to 0 to indicate CS0
72 	char _character_set_info[63];	//!< "OSTA Compressed Unicode"
73 } __attribute__((packed));
74 
75 extern const charspec kCs0CharacterSet;
76 
77 /*! \brief Date and time stamp
78 
79 	See also: ECMA 167 1/7.3, UDF-2.01 2.1.4
80 */
81 class timestamp {
82 private:
83 	union type_and_timezone_accessor {
84 		uint16 type_and_timezone;
85 		struct {
86 			uint16 type:4,
87 			       timezone:12;
88 		} bits;
89 	};
90 
91 public:
92 	timestamp() { _clear(); }
93 	timestamp(time_t time);
94 
95 	void dump() const;
96 
97 	// Get functions
98 	uint16 type_and_timezone() const { return B_LENDIAN_TO_HOST_INT16(_type_and_timezone); }
99 	uint8 type() const {
100 		type_and_timezone_accessor t;
101 		t.type_and_timezone = type_and_timezone();
102 		return t.bits.type;
103 	}
104 	int16 timezone() const {
105 		type_and_timezone_accessor t;
106 		t.type_and_timezone = type_and_timezone();
107 		int16 result = t.bits.timezone;
108 		// Fill the lefmost bits with ones if timezone is negative
109 		result <<= 4;
110 		result >>= 4;
111 		return result;
112 	}
113 	uint16 year() const { return B_LENDIAN_TO_HOST_INT16(_year); }
114 	uint8 month() const { return _month; }
115 	uint8 day() const { return _day; }
116 	uint8 hour() const { return _hour; }
117 	uint8 minute() const { return _minute; }
118 	uint8 second() const { return _second; }
119 	uint8 centisecond() const { return _centisecond; }
120 	uint8 hundred_microsecond() const { return _hundred_microsecond; }
121 	uint8 microsecond() const { return _microsecond; }
122 
123 	// Set functions
124 	void set_type_and_timezone(uint16 type_and_timezone) { _type_and_timezone = B_HOST_TO_LENDIAN_INT16(type_and_timezone); }
125 	void set_type(uint8 type) {
126 		type_and_timezone_accessor t;
127 		t.type_and_timezone = type_and_timezone();
128 		t.bits.type = type;
129 		set_type_and_timezone(t.type_and_timezone);
130 	}
131 	void set_timezone(int16 tz) {
132 		type_and_timezone_accessor t;
133 		t.type_and_timezone = type_and_timezone();
134 		t.bits.timezone = tz;
135 		set_type_and_timezone(t.type_and_timezone);
136 	}
137 	void set_year(uint16 year) { _year = B_HOST_TO_LENDIAN_INT16(year); }
138 	void set_month(uint8 month) { _month = month; }
139 	void set_day(uint8 day) { _day = day; }
140 	void set_hour(uint8 hour) { _hour = hour; }
141 	void set_minute(uint8 minute) { _minute = minute; }
142 	void set_second(uint8 second) { _second = second; }
143 	void set_centisecond(uint8 centisecond) { _centisecond = centisecond; }
144 	void set_hundred_microsecond(uint8 hundred_microsecond) { _hundred_microsecond = hundred_microsecond; }
145 	void set_microsecond(uint8 microsecond) { _microsecond = microsecond; }
146 private:
147 	void _clear();
148 
149 	uint16 _type_and_timezone;
150 	uint16 _year;
151 	uint8 _month;
152 	uint8 _day;
153 	uint8 _hour;
154 	uint8 _minute;
155 	uint8 _second;
156 	uint8 _centisecond;
157 	uint8 _hundred_microsecond;
158 	uint8 _microsecond;
159 
160 } __attribute__((packed));
161 
162 
163 /*! \brief Implementation ID Identify Suffix
164 
165 	See also: UDF 2.50 2.1.5.3
166 */
167 struct implementation_id_suffix {
168 public:
169 	implementation_id_suffix(uint8 os_class, uint8 os_identifier);
170 
171 	uint8 os_class() const { return _os_class; }
172 	uint8 os_identifier() const { return _os_identifier; }
173 
174 	void set_os_class(uint8 os_class) { _os_class = os_class; }
175 	void set_os_identifier(uint8 identifier) { _os_identifier = identifier; }
176 private:
177 	uint8 _os_class;
178 	uint8 _os_identifier;
179 	array<uint8, 6> _implementation_use;
180 };
181 
182 /*! \brief Operating system classes for implementation_id_suffixes
183 
184 	See also: Udf 2.50 6.3
185 */
186 enum {
187 	OS_UNDEFINED = 0,
188 	OS_DOS,
189 	OS_OS2,
190 	OS_MACOS,
191 	OS_UNIX,
192 	OS_WIN9X,
193 	OS_WINNT,
194 	OS_OS400,
195 	OS_BEOS,
196 	OS_WINCE
197 };
198 
199 /*! \brief BeOS operating system classes identifiers for implementation_id_suffixes
200 
201 	See also: Udf 2.50 6.3
202 */
203 enum {
204 	BEOS_GENERIC = 0,
205 	BEOS_OPENBEOS = 1	// not part of the standard, but perhaps someday. :-)
206 };
207 
208 /*! \brief Domain ID Identify Suffix
209 
210 	See also: UDF 2.50 2.1.5.3
211 */
212 struct domain_id_suffix {
213 public:
214 	domain_id_suffix(uint16 udfRevision, uint8 domainFlags);
215 
216 	//! Note that revision 2.50 is denoted by 0x0250.
217 	uint16 udf_revision() const { return _udf_revision; }
218 	uint8 domain_flags() const { return _domain_flags; }
219 
220 	void set_udf_revision(uint16 revision) { _udf_revision = B_HOST_TO_LENDIAN_INT16(revision); }
221 	void set_domain_flags(uint8 flags) { _domain_flags = flags; }
222 private:
223 	uint8 _udf_revision;
224 	uint8 _domain_flags;
225 	array<uint8, 5> _reserved;
226 };
227 
228 /*! \brief Domain flags
229 
230 	See also: UDF 2.50 2.1.5.3
231 */
232 enum {
233 	DF_HARD_WRITE_PROTECT = 0x01,
234 	DF_SOFT_WRITE_PROTECT = 0x02
235 };
236 
237 /*! \brief Identifier used to designate the implementation responsible
238 	for writing associated data structures on the medium.
239 
240 	See also: ECMA 167 1/7.4, UDF 2.01 2.1.5
241 */
242 struct entity_id {
243 public:
244 	static const int kIdentifierLength = 23;
245 	static const int kIdentifierSuffixLength = 8;
246 
247 	entity_id(uint8 flags = 0, char *identifier = NULL,
248 	          uint8 *identifier_suffix = NULL);
249 	entity_id(uint8 flags, char *identifier,
250 	          const implementation_id_suffix &suffix);
251 	entity_id(uint8 flags, char *identifier,
252 	          const domain_id_suffix &suffix);
253 
254 	void dump() const;
255 	bool matches(const entity_id &id) const;
256 
257 	// Get functions
258 	uint8 flags() const { return _flags; }
259 	const char* identifier() const { return _identifier; }
260 	char* identifier() { return _identifier; }
261 	const array<uint8, kIdentifierSuffixLength>& identifier_suffix() const { return _identifier_suffix; }
262 	array<uint8, kIdentifierSuffixLength>& identifier_suffix() { return _identifier_suffix; }
263 
264 	// Set functions
265 	void set_flags(uint8 flags) { _flags = flags; }
266 private:
267 	uint8 _flags;
268 	char _identifier[kIdentifierLength];
269 	array<uint8, kIdentifierSuffixLength> _identifier_suffix;
270 } __attribute__((packed));
271 
272 extern const entity_id kMetadataPartitionMapId;
273 extern const entity_id kSparablePartitionMapId;
274 extern const entity_id kVirtualPartitionMapId;
275 extern const entity_id kImplementationId;
276 extern const entity_id kPartitionContentsId;
277 extern const entity_id kUdfId;
278 
279 //----------------------------------------------------------------------
280 // ECMA-167 Part 2
281 //----------------------------------------------------------------------
282 
283 
284 /*! \brief Header for volume structure descriptors
285 
286 	Each descriptor consumes an entire block. All unused trailing
287 	bytes in the descriptor should be set to 0.
288 
289 	The following descriptors contain no more information than
290 	that contained in the header:
291 
292 	- BEA01:
293 	  - type: 0
294 	  - id: "BEA01"
295 	  - version: 1
296 
297 	- TEA01:
298 	  - type: 0
299 	  - id: "TEA01"
300 	  - version: 1
301 
302 	- NSR03:
303 	  - type: 0
304 	  - id: "NSR03"
305 	  - version: 1
306 
307 	See also: ECMA 167 2/9.1
308 */
309 struct volume_structure_descriptor_header {
310 public:
311 	volume_structure_descriptor_header(uint8 type, const char *id, uint8 version);
312 
313 	uint8 type;
314 	char id[5];
315 	uint8 version;
316 
317 	bool id_matches(const char *id);
318 } __attribute__((packed));
319 
320 // Volume structure descriptor ids
321 extern const char* kVSDID_BEA;
322 extern const char* kVSDID_TEA;
323 extern const char* kVSDID_BOOT;
324 extern const char* kVSDID_ISO;
325 extern const char* kVSDID_ECMA167_2;
326 extern const char* kVSDID_ECMA167_3;
327 extern const char* kVSDID_ECMA168;
328 
329 //----------------------------------------------------------------------
330 // ECMA-167 Part 3
331 //----------------------------------------------------------------------
332 
333 
334 /*! \brief Location and length of a contiguous chunk of data on the volume.
335 
336 	\c _location is an absolute block address.
337 
338 	See also: ECMA 167 3/7.1
339 */
340 struct extent_address {
341 public:
342 	extent_address(uint32 location = 0, uint32 length = 0);
343 
344 	void dump() const;
345 
346 	uint32 length() const { return B_LENDIAN_TO_HOST_INT32(_length); }
347 	uint32 location() const { return B_LENDIAN_TO_HOST_INT32(_location); }
348 
349 	void set_length(int32 length) { _length = B_HOST_TO_LENDIAN_INT32(length); }
350 	void set_location(int32 location) { _location = B_HOST_TO_LENDIAN_INT32(location); }
351 private:
352 	uint32 _length;
353 	uint32 _location;
354 } __attribute__((packed));
355 
356 
357 /*! \brief Location of a logical block within a logical volume.
358 
359 	See also: ECMA 167 4/7.1
360 */
361 struct logical_block_address {
362 public:
363 	void dump() const;
364 
365 	uint32 block() const { return B_LENDIAN_TO_HOST_INT32(_block); }
366 	uint16 partition() const { return B_LENDIAN_TO_HOST_INT16(_partition); }
367 
368 	void set_block(uint32 block) { _block = B_HOST_TO_LENDIAN_INT32(block); }
369 	void set_partition(uint16 partition) { _partition = B_HOST_TO_LENDIAN_INT16(partition); }
370 
371 private:
372 	uint32 _block;	//!< Block location relative to start of corresponding partition
373 	uint16 _partition;	//!< Numeric partition id within logical volume
374 } __attribute__((packed));
375 
376 /*! \brief Extent types used in short_address, long_address,
377 	and extended_address.
378 
379 	See also: ECMA-167 4/14.14.1.1
380 */
381 enum extent_type {
382 	EXTENT_TYPE_RECORDED = 0,	//!< Allocated and recorded
383 	EXTENT_TYPE_ALLOCATED,		//!< Allocated but unrecorded
384 	EXTENT_TYPE_UNALLOCATED,	//!< Unallocated and unrecorded
385 	EXTENT_TYPE_CONTINUATION,	//!< Specifies next extent of descriptors
386 };
387 
388 
389 /*! \brief Allocation descriptor.
390 
391 	See also: ECMA 167 4/14.14.1
392 */
393 struct short_address {
394 private:
395 	union type_and_length_accessor {
396 		uint32 type_and_length;
397 		struct {
398 			uint32 length:30,
399 			       type:2;
400 //			uint32 type:2,
401 //			       length:30;
402 		} bits;
403 	};
404 
405 public:
406 	void dump() const;
407 
408 	uint8 type() const {
409 		type_and_length_accessor t;
410 		t.type_and_length = type_and_length();
411 		return t.bits.type;
412 	}
413 	uint32 length() const {
414 		type_and_length_accessor t;
415 		t.type_and_length = type_and_length();
416 		return t.bits.length;
417 	}
418 	uint32 block() const { return B_LENDIAN_TO_HOST_INT32(_block); }
419 
420 	void set_type(uint8 type) {
421 		type_and_length_accessor t;
422 		t.type_and_length = type_and_length();
423 		t.bits.type = type;
424 		set_type_and_length(t.type_and_length);
425 	}
426 	void set_length(uint32 length) {
427 		type_and_length_accessor t;
428 		t.type_and_length = type_and_length();
429 		t.bits.length = length;
430 		set_type_and_length(t.type_and_length);
431 	}
432 	void set_block(uint32 block) { _block = B_HOST_TO_LENDIAN_INT32(block); }
433 private:
434 	uint32 type_and_length() const { return B_LENDIAN_TO_HOST_INT32(_type_and_length); }
435 	void set_type_and_length(uint32 value) { _type_and_length = B_HOST_TO_LENDIAN_INT32(value); }
436 
437 	uint32 _type_and_length;
438 	uint32 _block;
439 } __attribute__((packed));
440 
441 
442 /*! \brief Allocation descriptor w/ 6 byte implementation use field.
443 
444 	See also: ECMA 167 4/14.14.2
445 */
446 struct long_address {
447 private:
448 	union type_and_length_accessor {
449 		uint32 type_and_length;
450 		struct {
451 			uint32 length:30,
452 			       type:2;
453 		} bits;
454 	};
455 
456 public:
457 	long_address(uint16 partition = 0, uint32 block = 0, uint32 length = 0,
458 	             uint8 type = 0);
459 
460 	void dump() const;
461 
462 	uint8 type() const {
463 		type_and_length_accessor t;
464 		t.type_and_length = type_and_length();
465 		return t.bits.type;
466 	}
467 	uint32 length() const {
468 		type_and_length_accessor t;
469 		t.type_and_length = type_and_length();
470 		return t.bits.length;
471 	}
472 
473 	uint32 block() const { return _location.block(); }
474 	uint16 partition() const { return _location.partition(); }
475 
476 	const array<uint8, 6>& implementation_use() const { return _implementation_use; }
477 	array<uint8, 6>& implementation_use() { return _implementation_use; }
478 
479 	void set_type(uint8 type) {
480 		type_and_length_accessor t;
481 		t.type_and_length = type_and_length();
482 		t.bits.type = type;
483 		set_type_and_length(t.type_and_length);
484 	}
485 	void set_length(uint32 length) {
486 		type_and_length_accessor t;
487 		t.type_and_length = type_and_length();
488 		t.bits.length = length;
489 		set_type_and_length(t.type_and_length);
490 	}
491 	void set_block(uint32 block) { _location.set_block(block); }
492 	void set_partition(uint16 partition) { _location.set_partition(partition); }
493 
494 	void set_to(uint32 block, uint16 partition, uint32 length = 1,
495 	       uint8 type = EXTENT_TYPE_RECORDED)
496 	{
497 		set_block(block);
498 		set_partition(partition);
499 		set_length(length);
500 		set_type(type);
501 	}
502 
503 private:
504 	uint32 type_and_length() const { return B_LENDIAN_TO_HOST_INT32(_type_and_length); }
505 	void set_type_and_length(uint32 value) { _type_and_length = B_HOST_TO_LENDIAN_INT32(value); }
506 
507 	uint32 _type_and_length;
508 	logical_block_address _location;
509 	array<uint8, 6> _implementation_use;
510 } __attribute__((packed));
511 
512 /*! \brief Common tag found at the beginning of most udf descriptor structures.
513 
514 	For error checking, \c descriptor_tag  structures have:
515 	- The disk location of the tag redundantly stored in the tag itself
516 	- A checksum value for the tag
517 	- A CRC value and length
518 
519 	See also: ECMA 167 1/7.2, UDF 2.01 2.2.1, UDF 2.01 2.3.1
520 */
521 struct descriptor_tag  {
522 public:
523 	void dump() const;
524 
525 	status_t init_check(uint32 block, bool calculateCrc = true);
526 
527 	uint16 id() const { return B_LENDIAN_TO_HOST_INT16(_id); }
528 	uint16 version() const { return B_LENDIAN_TO_HOST_INT16(_version); }
529 	uint8 checksum() const { return _checksum; }
530 	uint16 serial_number() const { return B_LENDIAN_TO_HOST_INT16(_serial_number); }
531 	uint16 crc() const { return B_LENDIAN_TO_HOST_INT16(_crc); }
532 	uint16 crc_length() const { return B_LENDIAN_TO_HOST_INT16(_crc_length); }
533 	uint32 location() const { return B_LENDIAN_TO_HOST_INT32(_location); }
534 
535 	void set_id(uint16 id) { _id = B_HOST_TO_LENDIAN_INT16(id); }
536 	void set_version(uint16 version) { _version = B_HOST_TO_LENDIAN_INT16(version); }
537 	void set_checksum(uint8 checksum) { _checksum = checksum; }
538 	void set_serial_number(uint16 serial_number) { _serial_number = B_HOST_TO_LENDIAN_INT16(serial_number); }
539 	void set_crc(uint16 crc) { _crc = B_HOST_TO_LENDIAN_INT16(crc); }
540 	void set_crc_length(uint16 crc_length) { _crc_length = B_HOST_TO_LENDIAN_INT16(crc_length); }
541 	void set_location(uint32 location) { _location = B_HOST_TO_LENDIAN_INT32(location); }
542 
543 	/*! \brief Calculates and sets the crc length, crc checksumm, and
544 		checksum for the tag.
545 
546 		This function should not be called until all member variables in
547 		the descriptor_tag's enclosing descriptor and all member variables
548 		in the descriptor_tag itself other than crc_length, crc, and checksum
549 		have been set (since the checksum is based off of values in the
550 		descriptor_tag, and the crc is based off the values in and the
551 		size of the	enclosing descriptor).
552 
553 		\param The tag's enclosing descriptor.
554 		\param The size of the tag's enclosing descriptor (including the
555 		       tag); only necessary if different from sizeof(Descriptor).
556 	*/
557 	template <class Descriptor>
558 	void
559 	set_checksums(Descriptor &descriptor, uint16 size = sizeof(Descriptor))
560 	{
561 
562 		// check that this tag is actually owned by
563 		// the given descriptor
564 		if (this == &descriptor.tag())
565 		{
566 			// crc_length, based off provided descriptor
567 			set_crc_length(size - sizeof(descriptor_tag));
568 			// crc
569 			uint16 crc = Udf::calculate_crc(reinterpret_cast<uint8*>(this)
570 			               + sizeof(descriptor_tag), crc_length());
571 			set_crc(crc);
572 			// checksum (which depends on the other two values)
573 			uint32 sum = 0;
574 			for (int i = 0; i <= 3; i++)
575 				sum += reinterpret_cast<uint8*>(this)[i];
576 			for (int i = 5; i <= 15; i++)
577 				sum += reinterpret_cast<uint8*>(this)[i];
578 			set_checksum(sum % 256);
579 		}
580 	}
581 private:
582 	uint16 _id;
583 	uint16 _version;
584 	uint8 _checksum;			//!< Sum modulo 256 of bytes 0-3 and 5-15 of this struct.
585 	uint8 _reserved;			//!< Set to #00.
586 	uint16 _serial_number;
587 	uint16 _crc;				//!< May be 0 if \c crc_length field is 0.
588 	/*! \brief Length of the data chunk used to calculate CRC.
589 
590 		If 0, no CRC was calculated, and the \c crc field must be 0.
591 
592 		According to UDF-2.01 2.3.1.2, the CRC shall be calculated for all descriptors
593 		unless otherwise noted, and this field shall be set to:
594 
595 		<code>(descriptor length) - (descriptor tag length)</code>
596 	*/
597 	uint16 _crc_length;
598 	/*! \brief Address of this tag within its partition (for error checking).
599 
600 		For virtually addressed structures (i.e. those accessed thru a VAT), this
601 		shall be the virtual address, not the physical or logical address.
602 	*/
603 	uint32 _location;
604 
605 } __attribute__((packed));
606 
607 
608 /*! \c descriptor_tag ::id values
609 */
610 enum tag_id {
611 	TAGID_UNDEFINED	= 0,
612 
613 	// ECMA 167, PART 3
614 	TAGID_PRIMARY_VOLUME_DESCRIPTOR,
615 	TAGID_ANCHOR_VOLUME_DESCRIPTOR_POINTER,
616 	TAGID_VOLUME_DESCRIPTOR_POINTER,
617 	TAGID_IMPLEMENTATION_USE_VOLUME_DESCRIPTOR,
618 	TAGID_PARTITION_DESCRIPTOR,
619 	TAGID_LOGICAL_VOLUME_DESCRIPTOR,
620 	TAGID_UNALLOCATED_SPACE_DESCRIPTOR,
621 	TAGID_TERMINATING_DESCRIPTOR,
622 	TAGID_LOGICAL_VOLUME_INTEGRITY_DESCRIPTOR,
623 
624 	TAGID_CUSTOM_START = 65280,
625 	TAGID_CUSTOM_END = 65535,
626 
627 	// ECMA 167, PART 4
628 	TAGID_FILE_SET_DESCRIPTOR = 256,
629 	TAGID_FILE_IDENTIFIER_DESCRIPTOR,
630 	TAGID_ALLOCATION_EXTENT_DESCRIPTOR,
631 	TAGID_INDIRECT_ENTRY,
632 	TAGID_TERMINAL_ENTRY,
633 	TAGID_FILE_ENTRY,
634 	TAGID_EXTENDED_ATTRIBUTE_HEADER_DESCRIPTOR,
635 	TAGID_UNALLOCATED_SPACE_ENTRY,
636 	TAGID_SPACE_BITMAP_DESCRIPTOR,
637 	TAGID_PARTITION_INTEGRITY_ENTRY,
638 	TAGID_EXTENDED_FILE_ENTRY,
639 };
640 
641 const char *tag_id_to_string(tag_id id);
642 
643 extern const uint16 kCrcTable[256];
644 
645 /*! \brief Primary volume descriptor
646 */
647 struct primary_volume_descriptor {
648 public:
649 	void dump() const;
650 
651 	// Get functions
652 	const descriptor_tag & tag() const { return _tag; }
653 	descriptor_tag & tag() { return _tag; }
654 
655 	uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
656 	uint32 primary_volume_descriptor_number() const { return B_LENDIAN_TO_HOST_INT32(_primary_volume_descriptor_number); }
657 
658 	const array<char, 32>& volume_identifier() const { return _volume_identifier; }
659 	array<char, 32>& volume_identifier() { return _volume_identifier; }
660 
661 	uint16 volume_sequence_number() const { return B_LENDIAN_TO_HOST_INT16(_volume_sequence_number); }
662 	uint16 max_volume_sequence_number() const { return B_LENDIAN_TO_HOST_INT16(_max_volume_sequence_number); }
663 	uint16 interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_interchange_level); }
664 	uint16 max_interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_max_interchange_level); }
665 	uint32 character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_character_set_list); }
666 	uint32 max_character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_max_character_set_list); }
667 
668 	const array<char, 128>& volume_set_identifier() const { return _volume_set_identifier; }
669 	array<char, 128>& volume_set_identifier() { return _volume_set_identifier; }
670 
671 	const charspec& descriptor_character_set() const { return _descriptor_character_set; }
672 	charspec& descriptor_character_set() { return _descriptor_character_set; }
673 
674 	const charspec& explanatory_character_set() const { return _explanatory_character_set; }
675 	charspec& explanatory_character_set() { return _explanatory_character_set; }
676 
677 	const extent_address& volume_abstract() const { return _volume_abstract; }
678 	extent_address& volume_abstract() { return _volume_abstract; }
679 	const extent_address& volume_copyright_notice() const { return _volume_copyright_notice; }
680 	extent_address& volume_copyright_notice() { return _volume_copyright_notice; }
681 
682 	const entity_id& application_id() const { return _application_id; }
683 	entity_id& application_id() { return _application_id; }
684 
685 	const timestamp& recording_date_and_time() const { return _recording_date_and_time; }
686 	timestamp& recording_date_and_time() { return _recording_date_and_time; }
687 
688 	const entity_id& implementation_id() const { return _implementation_id; }
689 	entity_id& implementation_id() { return _implementation_id; }
690 
691 	const array<uint8, 64>& implementation_use() const { return _implementation_use; }
692 	array<uint8, 64>& implementation_use() { return _implementation_use; }
693 
694 	uint32 predecessor_volume_descriptor_sequence_location() const
695 	  { return B_LENDIAN_TO_HOST_INT32(_predecessor_volume_descriptor_sequence_location); }
696 	uint16 flags() const { return B_LENDIAN_TO_HOST_INT16(_flags); }
697 
698 	const array<uint8, 22>& reserved() const { return _reserved; }
699 	array<uint8, 22>& reserved() { return _reserved; }
700 
701 	// Set functions
702 	void set_vds_number(uint32 number)
703 	  { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
704 	void set_primary_volume_descriptor_number(uint32 number)
705 	  { _primary_volume_descriptor_number = B_HOST_TO_LENDIAN_INT32(number); }
706 	void set_volume_sequence_number(uint16 number)
707 	  { _volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); }
708 	void set_max_volume_sequence_number(uint16 number)
709 	  { _max_volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); }
710 	void set_interchange_level(uint16 level)
711 	  { _interchange_level = B_HOST_TO_LENDIAN_INT16(level); }
712 	void set_max_interchange_level(uint16 level)
713 	  { _max_interchange_level = B_HOST_TO_LENDIAN_INT16(level); }
714 	void set_character_set_list(uint32 list)
715 	  { _character_set_list = B_HOST_TO_LENDIAN_INT32(list); }
716 	void set_max_character_set_list(uint32 list)
717 	  { _max_character_set_list = B_HOST_TO_LENDIAN_INT32(list); }
718 	void set_predecessor_volume_descriptor_sequence_location(uint32 location)
719 	  { _predecessor_volume_descriptor_sequence_location = B_HOST_TO_LENDIAN_INT32(location); }
720 	void set_flags(uint16 flags)
721 	  { _flags = B_HOST_TO_LENDIAN_INT16(flags); }
722 
723 private:
724 	descriptor_tag  _tag;
725 	uint32 _vds_number;
726 	uint32 _primary_volume_descriptor_number;
727 	array<char, 32> _volume_identifier;
728 	uint16 _volume_sequence_number;
729 	uint16 _max_volume_sequence_number;
730 	uint16 _interchange_level; //!< to be set to 3 if part of multivolume set, 2 otherwise
731 	uint16 _max_interchange_level; //!< to be set to 3 unless otherwise directed by user
732 	uint32 _character_set_list;
733 	uint32 _max_character_set_list;
734 	array<char, 128> _volume_set_identifier;
735 
736 	/*! \brief Identifies the character set for the \c volume_identifier
737 		and \c volume_set_identifier fields.
738 
739 		To be set to CS0.
740 	*/
741 	charspec _descriptor_character_set;
742 
743 	/*! \brief Identifies the character set used in the \c volume_abstract
744 		and \c volume_copyright_notice extents.
745 
746 		To be set to CS0.
747 	*/
748 	charspec _explanatory_character_set;
749 
750 	extent_address _volume_abstract;
751 	extent_address _volume_copyright_notice;
752 
753 	entity_id _application_id;
754 	timestamp _recording_date_and_time;
755 	entity_id _implementation_id;
756 	array<uint8, 64> _implementation_use;
757 	uint32 _predecessor_volume_descriptor_sequence_location;
758 	uint16 _flags;
759 	array<uint8, 22> _reserved;
760 
761 } __attribute__((packed));
762 
763 
764 /*! \brief Anchor Volume Descriptor Pointer
765 
766 	vd recorded at preset locations in the partition, used as a reference
767 	point to the main vd sequences
768 
769 	According to UDF 2.01, an avdp shall be recorded in at least 2 of
770 	the 3 following locations, where N is the last recordable sector
771 	of the partition:
772 	- 256
773 	- (N - 256)
774 	- N
775 
776 	See also: ECMA 167 3/10.2, UDF-2.01 2.2.3
777 */
778 struct anchor_volume_descriptor {
779 public:
780 	void dump() const;
781 
782 	descriptor_tag & tag() { return _tag; }
783 	const descriptor_tag & tag() const { return _tag; }
784 
785 	extent_address& main_vds() { return _main_vds; }
786 	const extent_address& main_vds() const { return _main_vds; }
787 
788 	extent_address& reserve_vds() { return _reserve_vds; }
789 	const extent_address& reserve_vds() const { return _reserve_vds; }
790 private:
791 	descriptor_tag  _tag;
792 	extent_address _main_vds;	//!< min length of 16 sectors
793 	extent_address _reserve_vds;	//!< min length of 16 sectors
794 	char _reserved[480];
795 } __attribute__((packed));
796 
797 
798 /*! \brief Volume Descriptor Pointer
799 
800 	Used to chain extents of volume descriptor sequences together.
801 
802 	See also: ECMA 167 3/10.3
803 */
804 struct descriptor_pointer {
805 	descriptor_tag  tag;
806 	uint32 vds_number;
807 	extent_address next;
808 } __attribute__((packed));
809 
810 
811 /*! \brief Implementation Use Volume Descriptor
812 
813 	See also: ECMA 167 3/10.4
814 */
815 struct implementation_use_descriptor {
816 public:
817 	void dump() const;
818 
819 	// Get functions
820 	const descriptor_tag & tag() const { return _tag; }
821 	descriptor_tag & tag() { return _tag; }
822 
823 	uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
824 
825 	const entity_id& implementation_id() const { return _implementation_id; }
826 	entity_id& implementation_id() { return _implementation_id; }
827 
828 	const array<uint8, 460>& implementation_use() const { return _implementation_use; }
829 	array<uint8, 460>& implementation_use() { return _implementation_use; }
830 
831 	// Set functions
832 	void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
833 private:
834 	descriptor_tag  _tag;
835 	uint32 _vds_number;
836 	entity_id _implementation_id;
837 	array<uint8, 460> _implementation_use;
838 } __attribute__((packed));
839 
840 
841 /*! \brief Maximum number of partition descriptors to be found in volume
842 	descriptor sequence, per UDF-2.50
843 */
844 extern const uint8 kMaxPartitionDescriptors;
845 #define UDF_MAX_PARTITION_MAPS 2
846 #define UDF_MAX_PARTITION_MAP_SIZE 64
847 
848 /*! \brief Partition Descriptor
849 
850 	See also: ECMA 167 3/10.5
851 */
852 struct partition_descriptor {
853 private:
854 	union partition_flags_accessor {
855 		uint16 partition_flags;
856 		struct {
857 			uint16 allocated:1,
858 			       reserved:15;
859 		} bits;
860 	};
861 
862 public:
863 	void dump() const;
864 
865 	// Get functions
866 	const descriptor_tag & tag() const { return _tag; }
867 	descriptor_tag & tag() { return _tag; }
868 
869 	uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
870 	uint16 partition_flags() const { return B_LENDIAN_TO_HOST_INT16(_partition_flags); }
871 	bool allocated() const {
872 		partition_flags_accessor f;
873 		f.partition_flags = partition_flags();
874 		return f.bits.allocated;
875 	}
876 	uint16 partition_number() const { return B_LENDIAN_TO_HOST_INT16(_partition_number); }
877 
878 	const entity_id& partition_contents() const { return _partition_contents; }
879 	entity_id& partition_contents() { return _partition_contents; }
880 
881 	const array<uint8, 128>& partition_contents_use() const { return _partition_contents_use; }
882 	array<uint8, 128>& partition_contents_use() { return _partition_contents_use; }
883 
884 	uint32 access_type() const { return B_LENDIAN_TO_HOST_INT32(_access_type); }
885 	uint32 start() const { return B_LENDIAN_TO_HOST_INT32(_start); }
886 	uint32 length() const { return B_LENDIAN_TO_HOST_INT32(_length); }
887 
888 	const entity_id& implementation_id() const { return _implementation_id; }
889 	entity_id& implementation_id() { return _implementation_id; }
890 
891 	const array<uint8, 128>& implementation_use() const { return _implementation_use; }
892 	array<uint8, 128>& implementation_use() { return _implementation_use; }
893 
894 	const array<uint8, 156>& reserved() const { return _reserved; }
895 	array<uint8, 156>& reserved() { return _reserved; }
896 
897 	// Set functions
898 	void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
899 	void set_partition_flags(uint16 flags) { _partition_flags = B_HOST_TO_LENDIAN_INT16(flags); }
900 	void set_allocated(bool allocated) {
901 		partition_flags_accessor f;
902 		f.partition_flags = partition_flags();
903 		f.bits.allocated = allocated;
904 		set_partition_flags(f.partition_flags);
905 	}
906 	void set_partition_number(uint16 number) { _partition_number = B_HOST_TO_LENDIAN_INT16(number); }
907 	void set_access_type(uint32 type) { _access_type = B_HOST_TO_LENDIAN_INT32(type); }
908 	void set_start(uint32 start) { _start = B_HOST_TO_LENDIAN_INT32(start); }
909 	void set_length(uint32 length) { _length = B_HOST_TO_LENDIAN_INT32(length); }
910 
911 private:
912 	descriptor_tag  _tag;
913 	uint32 _vds_number;
914 	/*! Bit 0: If 0, shall mean volume space has not been allocated. If 1,
915 	    shall mean volume space has been allocated.
916 	*/
917 	uint16 _partition_flags;
918 	uint16 _partition_number;
919 
920 	/*! - "+NSR03" Volume recorded according to ECMA-167, i.e. UDF
921 		- "+CD001" Volume recorded according to ECMA-119, i.e. iso9660
922 		- "+FDC01" Volume recorded according to ECMA-107
923 		- "+CDW02" Volume recorded according to ECMA-168
924 	*/
925 	entity_id _partition_contents;
926 	array<uint8, 128> _partition_contents_use;
927 
928 	/*! See \c partition_access_type enum
929 	*/
930 	uint32 _access_type;
931 	uint32 _start;
932 	uint32 _length;
933 	entity_id _implementation_id;
934 	array<uint8, 128> _implementation_use;
935 	array<uint8, 156> _reserved;
936 } __attribute__((packed));
937 
938 
939 enum partition_access_type {
940 	ACCESS_UNSPECIFIED,
941 	ACCESS_READ_ONLY,
942 	ACCESS_WRITE_ONCE,
943 	ACCESS_REWRITABLE,
944 	ACCESS_OVERWRITABLE,
945 };
946 
947 
948 /*! \brief Logical volume descriptor
949 
950 	See also: ECMA 167 3/10.6, UDF-2.01 2.2.4
951 */
952 struct logical_volume_descriptor {
953 	void dump() const;
954 
955 	// Get functions
956 	const descriptor_tag & tag() const { return _tag; }
957 	descriptor_tag & tag() { return _tag; }
958 
959 	uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
960 
961 	const charspec& character_set() const { return _character_set; }
962 	charspec& character_set() { return _character_set; }
963 
964 	const array<char, 128>& logical_volume_identifier() const { return _logical_volume_identifier; }
965 	array<char, 128>& logical_volume_identifier() { return _logical_volume_identifier; }
966 
967 	uint32 logical_block_size() const { return B_LENDIAN_TO_HOST_INT32(_logical_block_size); }
968 
969 	const entity_id& domain_id() const { return _domain_id; }
970 	entity_id& domain_id() { return _domain_id; }
971 
972 	const array<uint8, 16>& logical_volume_contents_use() const { return _logical_volume_contents_use; }
973 	array<uint8, 16>& logical_volume_contents_use() { return _logical_volume_contents_use; }
974 
975 	const long_address& file_set_address() const { return *reinterpret_cast<const long_address*>(&_logical_volume_contents_use); }
976 	long_address& file_set_address() { return *reinterpret_cast<long_address*>(&_logical_volume_contents_use); }
977 
978 	uint32 map_table_length() const { return B_LENDIAN_TO_HOST_INT32(_map_table_length); }
979 	uint32 partition_map_count() const { return B_LENDIAN_TO_HOST_INT32(_partition_map_count); }
980 
981 	const entity_id& implementation_id() const { return _implementation_id; }
982 	entity_id& implementation_id() { return _implementation_id; }
983 
984 	const array<uint8, 128>& implementation_use() const { return _implementation_use; }
985 	array<uint8, 128>& implementation_use() { return _implementation_use; }
986 
987 	const extent_address& integrity_sequence_extent() const { return _integrity_sequence_extent; }
988 	extent_address& integrity_sequence_extent() { return _integrity_sequence_extent; }
989 
990 	const uint8* partition_maps() const { return _partition_maps; }
991 	uint8* partition_maps() { return _partition_maps; }
992 
993 	// Set functions
994 	void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
995 	void set_logical_block_size(uint32 size) { _logical_block_size = B_HOST_TO_LENDIAN_INT32(size); }
996 
997 	void set_map_table_length(uint32 length) { _map_table_length = B_HOST_TO_LENDIAN_INT32(length); }
998 	void set_partition_map_count(uint32 count) { _partition_map_count = B_HOST_TO_LENDIAN_INT32(count); }
999 
1000 	// Other functions
1001 	logical_volume_descriptor& operator=(const logical_volume_descriptor &rhs);
1002 
1003 private:
1004 	descriptor_tag  _tag;
1005 	uint32 _vds_number;
1006 
1007 	/*! \brief Identifies the character set for the
1008 		\c logical_volume_identifier field.
1009 
1010 		To be set to CS0.
1011 	*/
1012 	charspec _character_set;
1013 	array<char, 128> _logical_volume_identifier;
1014 	uint32 _logical_block_size;
1015 
1016 	/*! \brief To be set to 0 or "*OSTA UDF Compliant". See UDF specs.
1017 	*/
1018 	entity_id _domain_id;
1019 
1020 	/*! \brief For UDF, shall contain a \c long_address which identifies
1021 		the location of the logical volume's first file set.
1022 	*/
1023 	array<uint8, 16> _logical_volume_contents_use;
1024 
1025 	uint32 _map_table_length;
1026 	uint32 _partition_map_count;
1027 	entity_id _implementation_id;
1028 	array<uint8, 128> _implementation_use;
1029 
1030 	/*! \brief Logical volume integrity sequence location.
1031 
1032 		For re/overwritable media, shall be a min of 8KB in length.
1033 		For WORM media, shall be quite frickin large, as a new volume
1034 		must be added to the set if the extent fills up (since you
1035 		can't chain lvis's I guess).
1036 	*/
1037 	extent_address _integrity_sequence_extent;
1038 
1039 	/*! \brief Restricted to maps of type 1 for normal maps and
1040 		UDF type 2 for virtual maps or maps on systems not supporting
1041 		defect management.
1042 
1043 		Note that we actually allocate memory for the partition maps
1044 		here due to the fact that we allocate logical_volume_descriptor
1045 		objects on the stack sometimes.
1046 
1047 		See UDF-2.01 2.2.8, 2.2.9
1048 	*/
1049 	uint8 _partition_maps[UDF_MAX_PARTITION_MAPS * UDF_MAX_PARTITION_MAP_SIZE];
1050 } __attribute__((packed));
1051 
1052 //! Base size (excluding partition maps) of lvd
1053 extern const uint32 kLogicalVolumeDescriptorBaseSize;
1054 
1055 /*! \brief (Mostly) common portion of various partition maps
1056 
1057 	See also: ECMA-167 3/10.7.1
1058 */
1059 struct partition_map_header {
1060 public:
1061 	uint8 type() const { return _type; }
1062 	uint8 length() const { return _length; }
1063 	uint8 *map_data() { return _map_data; }
1064 	const uint8 *map_data() const { return _map_data; }
1065 
1066 	entity_id& partition_type_id()
1067 		{ return *reinterpret_cast<entity_id*>(&_map_data[2]); }
1068 	const entity_id& partition_type_id() const
1069 		{ return *reinterpret_cast<const entity_id*>(&_map_data[2]); }
1070 
1071 	void set_type(uint8 type) { _type = type; }
1072 	void set_length(uint8 length) { _length = length; }
1073 private:
1074 	uint8 _type;
1075 	uint8 _length;
1076 	uint8 _map_data[0];
1077 };// __attribute__((packed));
1078 
1079 
1080 /*! \brief Physical partition map (i.e. ECMA-167 Type 1 partition map)
1081 
1082 	See also: ECMA-167 3/10.7.2
1083 */
1084 struct physical_partition_map {
1085 public:
1086 	void dump();
1087 
1088 	uint8 type() const { return _type; }
1089 	uint8 length() const { return _length; }
1090 
1091 	uint16 volume_sequence_number() const {
1092 		return B_LENDIAN_TO_HOST_INT16(_volume_sequence_number); }
1093 	uint16 partition_number() const {
1094 		return B_LENDIAN_TO_HOST_INT16(_partition_number); }
1095 
1096 	void set_type(uint8 type) { _type = type; }
1097 	void set_length(uint8 length) { _length = length; }
1098 	void set_volume_sequence_number(uint16 number) {
1099 		_volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); }
1100 	void set_partition_number(uint16 number) {
1101 		_partition_number = B_HOST_TO_LENDIAN_INT16(number); }
1102 private:
1103 	uint8 _type;
1104 	uint8 _length;
1105 	uint16 _volume_sequence_number;
1106 	uint16 _partition_number;
1107 } __attribute__((packed));
1108 
1109 
1110 /* ----UDF Specific---- */
1111 /*! \brief Virtual partition map
1112 
1113 	Note that this map is a customization of the ECMA-167
1114 	type 2 partition map.
1115 
1116 	See also: UDF-2.01 2.2.8
1117 */
1118 struct virtual_partition_map {
1119 	uint8 type;
1120 	uint8 length;
1121 	uint8 reserved1[2];
1122 
1123 	/*! - flags: 0
1124 	    - identifier: "*UDF Virtual Partition"
1125 	    - identifier_suffix: per UDF-2.01 2.1.5.3
1126 	*/
1127 	entity_id partition_type_id;
1128 	uint16 volume_sequence_number;
1129 
1130 	/*! corresponding type 1 partition map in same logical volume
1131 	*/
1132 	uint16 partition_number;
1133 	uint8 reserved2[24];
1134 } __attribute__((packed));
1135 
1136 
1137 /*! \brief Maximum number of redundant sparing tables found in
1138 	sparable_partition_map structures.
1139 */
1140 #define UDF_MAX_SPARING_TABLE_COUNT 4
1141 
1142 /* ----UDF Specific---- */
1143 /*! \brief Sparable partition map
1144 
1145 	Note that this map is a customization of the ECMA-167
1146 	type 2 partition map.
1147 
1148 	See also: UDF-2.01 2.2.9
1149 */
1150 struct sparable_partition_map {
1151 public:
1152 	void dump();
1153 
1154 	uint8 type() const { return _type; }
1155 	uint8 length() const { return _length; }
1156 
1157 	entity_id& partition_type_id() { return _partition_type_id; }
1158 	const entity_id& partition_type_id() const { return _partition_type_id; }
1159 
1160 	uint16 volume_sequence_number() const {
1161 		return B_LENDIAN_TO_HOST_INT16(_volume_sequence_number); }
1162 	uint16 partition_number() const {
1163 		return B_LENDIAN_TO_HOST_INT16(_partition_number); }
1164 	uint16 packet_length() const {
1165 		return B_LENDIAN_TO_HOST_INT16(_packet_length); }
1166 	uint8 sparing_table_count() const { return _sparing_table_count; }
1167 	uint32 sparing_table_size() const {
1168 		return B_LENDIAN_TO_HOST_INT32(_sparing_table_size); }
1169 	uint32 sparing_table_location(uint8 index) const {
1170 		return B_LENDIAN_TO_HOST_INT32(_sparing_table_locations[index]); }
1171 
1172 
1173 	void set_type(uint8 type) { _type = type; }
1174 	void set_length(uint8 length) { _length = length; }
1175 	void set_volume_sequence_number(uint16 number) {
1176 		_volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); }
1177 	void set_partition_number(uint16 number) {
1178 		_partition_number = B_HOST_TO_LENDIAN_INT16(number); }
1179 	void set_packet_length(uint16 length) {
1180 		_packet_length = B_HOST_TO_LENDIAN_INT16(length); }
1181 	void set_sparing_table_count(uint8 count) {
1182 		_sparing_table_count = count; }
1183 	void set_sparing_table_size(uint32 size) {
1184 		_sparing_table_size = B_HOST_TO_LENDIAN_INT32(size); }
1185 	void set_sparing_table_location(uint8 index, uint32 location) {
1186 		_sparing_table_locations[index] = B_HOST_TO_LENDIAN_INT32(location); }
1187 private:
1188 	uint8 _type;
1189 	uint8 _length;
1190 	uint8 _reserved1[2];
1191 
1192 	/*! - flags: 0
1193 	    - identifier: "*UDF Sparable Partition"
1194 	    - identifier_suffix: per UDF-2.01 2.1.5.3
1195 	*/
1196 	entity_id _partition_type_id;
1197 	uint16 _volume_sequence_number;
1198 
1199 	//! partition number of corresponding partition descriptor
1200 	uint16 _partition_number;
1201 	uint16 _packet_length;
1202 	uint8 _sparing_table_count;
1203 	uint8 _reserved2;
1204 	uint32 _sparing_table_size;
1205 	uint32 _sparing_table_locations[UDF_MAX_SPARING_TABLE_COUNT];
1206 } __attribute__((packed));
1207 
1208 
1209 /* ----UDF Specific---- */
1210 /*! \brief Metadata partition map
1211 
1212 	Note that this map is a customization of the ECMA-167
1213 	type 2 partition map.
1214 
1215 	See also: UDF-2.50 2.2.10
1216 */
1217 struct metadata_partition_map {
1218 	uint8 type;
1219 	uint8 length;
1220 	uint8 reserved1[2];
1221 
1222 	/*! - flags: 0
1223 	    - identifier: "*UDF Metadata Partition"
1224 	    - identifier_suffix: per UDF-2.50 2.1.5
1225 	*/
1226 	entity_id partition_type_id;
1227 	uint16 volume_sequence_number;
1228 
1229 	/*! corresponding type 1 or type 2 sparable partition
1230 	    map in same logical volume
1231 	*/
1232 	uint16 partition_number;
1233 	uint8 reserved2[24];
1234 } __attribute__((packed));
1235 
1236 
1237 /*! \brief Unallocated space descriptor
1238 
1239 	See also: ECMA-167 3/10.8
1240 */
1241 struct unallocated_space_descriptor {
1242 	void dump() const;
1243 
1244 	// Get functions
1245 	const descriptor_tag & tag() const { return _tag; }
1246 	descriptor_tag & tag() { return _tag; }
1247 	uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); }
1248 	uint32 allocation_descriptor_count() const { return B_LENDIAN_TO_HOST_INT32(_allocation_descriptor_count); }
1249 	extent_address* allocation_descriptors() { return _allocation_descriptors; }
1250 
1251 	// Set functions
1252 	void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); }
1253 	void set_allocation_descriptor_count(uint32 count) { _allocation_descriptor_count = B_HOST_TO_LENDIAN_INT32(count); }
1254 private:
1255 	descriptor_tag  _tag;
1256 	uint32 _vds_number;
1257 	uint32 _allocation_descriptor_count;
1258 	extent_address _allocation_descriptors[0];
1259 } __attribute__((packed));
1260 
1261 
1262 /*! \brief Terminating descriptor
1263 
1264 	See also: ECMA-167 3/10.9
1265 */
1266 struct terminating_descriptor {
1267 	void dump() const;
1268 
1269 	// Get functions
1270 	const descriptor_tag & tag() const { return _tag; }
1271 	descriptor_tag & tag() { return _tag; }
1272 
1273 private:
1274 	descriptor_tag  _tag;
1275 	uint8 _reserved[496];
1276 } __attribute__((packed));
1277 
1278 
1279 /*! \brief Logical volume integrity descriptor
1280 
1281 	See also: ECMA-167 3/10.10
1282 */
1283 struct logical_volume_integrity_descriptor {
1284 	descriptor_tag  tag;
1285 	timestamp recording_time;
1286 	uint32 integrity_type;
1287 	extent_address next_integrity_extent;
1288 	array<uint8, 32> logical_volume_contents_use;
1289 	uint32 partition_count;
1290 	uint32 implementation_use_length;
1291 
1292 	/*! \todo double-check the pointer arithmetic here. */
1293 	uint32* free_space_table() { return (uint32*)(this+80); }
1294 	uint32* size_table() { return (uint32*)(free_space_table()+partition_count*sizeof(uint32)); }
1295 	uint8* implementation_use() { return (uint8*)(size_table()+partition_count*sizeof(uint32)); }
1296 
1297 } __attribute__((packed));
1298 
1299 /*! \brief Logical volume integrity types
1300 */
1301 enum {
1302 	LVIT_OPEN = 1,
1303 	LVIT_CLOSED,
1304 };
1305 
1306 //----------------------------------------------------------------------
1307 // ECMA-167 Part 4
1308 //----------------------------------------------------------------------
1309 
1310 
1311 
1312 /*! \brief File set descriptor
1313 
1314 	Contains all the pertinent info about a file set (i.e. a hierarchy of files)
1315 
1316 	According to UDF-2.01, only one file set descriptor shall be recorded,
1317 	except on WORM media, where the following rules apply:
1318 	- Multiple file sets are allowed only on WORM media
1319 	- The default file set shall be the one with highest value \c file_set_number field.
1320 	- Only the default file set may be flagged as writeable. All others shall be
1321 	  flagged as "hard write protect".
1322 	- No writeable file set may reference metadata structures which are referenced
1323 	  (directly or indirectly) by any other file set. Writeable file sets may, however,
1324 	  reference actual file data extents that are also referenced by other file sets.
1325 */
1326 struct file_set_descriptor {
1327 	void dump() const;
1328 
1329 	// Get functions
1330 	const descriptor_tag & tag() const { return _tag; }
1331 	descriptor_tag & tag() { return _tag; }
1332 
1333 	const timestamp& recording_date_and_time() const { return _recording_date_and_time; }
1334 	timestamp& recording_date_and_time() { return _recording_date_and_time; }
1335 
1336 	uint16 interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_interchange_level); }
1337 	uint16 max_interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_max_interchange_level); }
1338 	uint32 character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_character_set_list); }
1339 	uint32 max_character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_max_character_set_list); }
1340 	uint32 file_set_number() const { return B_LENDIAN_TO_HOST_INT32(_file_set_number); }
1341 	uint32 file_set_descriptor_number() const { return B_LENDIAN_TO_HOST_INT32(_file_set_descriptor_number); }
1342 
1343 	const charspec& logical_volume_id_character_set() const { return _logical_volume_id_character_set; }
1344 	charspec& logical_volume_id_character_set() { return _logical_volume_id_character_set; }
1345 
1346 	const array<char, 128>& logical_volume_id() const { return _logical_volume_id; }
1347 	array<char, 128>& logical_volume_id() { return _logical_volume_id; }
1348 
1349 	const charspec& file_set_id_character_set() const { return _file_set_id_character_set; }
1350 	charspec& file_set_id_character_set() { return _file_set_id_character_set; }
1351 
1352 	const array<char, 32>& file_set_id() const { return _file_set_id; }
1353 	array<char, 32>& file_set_id() { return _file_set_id; }
1354 
1355 	const array<char, 32>& copyright_file_id() const { return _copyright_file_id; }
1356 	array<char, 32>& copyright_file_id() { return _copyright_file_id; }
1357 
1358 	const array<char, 32>& abstract_file_id() const { return _abstract_file_id; }
1359 	array<char, 32>& abstract_file_id() { return _abstract_file_id; }
1360 
1361 	const long_address& root_directory_icb() const { return _root_directory_icb; }
1362 	long_address& root_directory_icb() { return _root_directory_icb; }
1363 
1364 	const entity_id& domain_id() const { return _domain_id; }
1365 	entity_id& domain_id() { return _domain_id; }
1366 
1367 	const long_address& next_extent() const { return _next_extent; }
1368 	long_address& next_extent() { return _next_extent; }
1369 
1370 	const long_address& system_stream_directory_icb() const { return _system_stream_directory_icb; }
1371 	long_address& system_stream_directory_icb() { return _system_stream_directory_icb; }
1372 
1373 	const array<uint8, 32>& reserved() const { return _reserved; }
1374 	array<uint8, 32>& reserved() { return _reserved; }
1375 
1376 	// Set functions
1377 	void set_interchange_level(uint16 level) { _interchange_level = B_HOST_TO_LENDIAN_INT16(level); }
1378 	void set_max_interchange_level(uint16 level) { _max_interchange_level = B_HOST_TO_LENDIAN_INT16(level); }
1379 	void set_character_set_list(uint32 list) { _character_set_list = B_HOST_TO_LENDIAN_INT32(list); }
1380 	void set_max_character_set_list(uint32 list) { _max_character_set_list = B_HOST_TO_LENDIAN_INT32(list); }
1381 	void set_file_set_number(uint32 number) { _file_set_number = B_HOST_TO_LENDIAN_INT32(number); }
1382 	void set_file_set_descriptor_number(uint32 number) { _file_set_descriptor_number = B_HOST_TO_LENDIAN_INT32(number); }
1383 private:
1384 	descriptor_tag  _tag;
1385 	timestamp _recording_date_and_time;
1386 	uint16 _interchange_level;			//!< To be set to 3 (see UDF-2.01 2.3.2.1)
1387 	uint16 _max_interchange_level;		//!< To be set to 3 (see UDF-2.01 2.3.2.2)
1388 	uint32 _character_set_list;
1389 	uint32 _max_character_set_list;
1390 	uint32 _file_set_number;
1391 	uint32 _file_set_descriptor_number;
1392 	charspec _logical_volume_id_character_set;	//!< To be set to kCSOCharspec
1393 	array<char, 128> _logical_volume_id;
1394 	charspec _file_set_id_character_set;
1395 	array<char, 32> _file_set_id;
1396 	array<char, 32> _copyright_file_id;
1397 	array<char, 32> _abstract_file_id;
1398 	long_address _root_directory_icb;
1399 	entity_id _domain_id;
1400 	long_address _next_extent;
1401 	long_address _system_stream_directory_icb;
1402 	array<uint8, 32> _reserved;
1403 } __attribute__((packed));
1404 
1405 
1406 /*! \brief Partition header descriptor
1407 
1408 	Contains references to unallocated and freed space data structures.
1409 
1410 	Note that unallocated space is space ready to be written with no
1411 	preprocessing. Freed space is space needing preprocessing (i.e.
1412 	a special write pass) before use.
1413 
1414 	Per UDF-2.01 2.3.3, the use of tables or bitmaps shall be consistent,
1415 	i.e. only one type or the other shall be used, not both.
1416 
1417 	To indicate disuse of a certain field, the fields of the allocation
1418 	descriptor shall all be set to 0.
1419 
1420 	See also: ECMA-167 4/14.3, UDF-2.01 2.2.3
1421 */
1422 struct partition_header_descriptor {
1423 	long_address unallocated_space_table;
1424 	long_address unallocated_space_bitmap;
1425 	/*! Unused, per UDF-2.01 2.2.3 */
1426 	long_address partition_integrity_table;
1427 	long_address freed_space_table;
1428 	long_address freed_space_bitmap;
1429 	uint8 reserved[88];
1430 } __attribute__((packed));
1431 
1432 #define kMaxFileIdSize (sizeof(file_id_descriptor)+512+3)
1433 
1434 /*! \brief File identifier descriptor
1435 
1436 	Identifies the name of a file entry, and the location of its corresponding
1437 	ICB.
1438 
1439 	See also: ECMA-167 4/14.4, UDF-2.01 2.3.4
1440 
1441 	\todo Check pointer arithmetic
1442 */
1443 struct file_id_descriptor {
1444 public:
1445 	void dump() const;
1446 
1447 	descriptor_tag & tag() { return _tag; }
1448 	const descriptor_tag & tag() const { return _tag; }
1449 
1450 	uint16 version_number() const { return B_LENDIAN_TO_HOST_INT16(_version_number); }
1451 
1452 	uint8 characteristics() const { return _characteristics; }
1453 
1454 	bool may_be_hidden() const {
1455 		characteristics_accessor c;
1456 		c.all = characteristics();
1457 		return c.bits.may_be_hidden;
1458 	}
1459 
1460 	bool is_directory() const {
1461 		characteristics_accessor c;
1462 		c.all = characteristics();
1463 		return c.bits.is_directory;
1464 	}
1465 
1466 	bool is_deleted() const {
1467 		characteristics_accessor c;
1468 		c.all = characteristics();
1469 		return c.bits.is_deleted;
1470 	}
1471 
1472 	bool is_parent() const {
1473 		characteristics_accessor c;
1474 		c.all = characteristics();
1475 		return c.bits.is_parent;
1476 	}
1477 
1478 	bool is_metadata_stream() const {
1479 		characteristics_accessor c;
1480 		c.all = characteristics();
1481 		return c.bits.is_metadata_stream;
1482 	}
1483 
1484 	uint8 id_length() const { return _id_length; }
1485 
1486 	long_address& icb() { return _icb; }
1487 	const long_address& icb() const { return _icb; }
1488 
1489 	uint8 implementation_use_length() const { return _implementation_use_length; }
1490 
1491 	/*! If implementation_use_length is greater than 0, the first 32
1492 		bytes of implementation_use() shall be an entity_id identifying
1493 		the implementation that generated the rest of the data in the
1494 		implementation_use() field.
1495 	*/
1496 	uint8* implementation_use() { return ((uint8*)this)+38; }
1497 	char* id() { return ((char*)this)+38+implementation_use_length(); }
1498 	const char* id() const { return ((const char*)this)+38+implementation_use_length(); }
1499 
1500 	uint16 structure_length() const { return 38 + id_length() + implementation_use_length(); }
1501 	uint16 padding_length() const { return ((structure_length()+3)/4)*4 - structure_length(); }
1502 	uint16 total_length() const { return structure_length() + padding_length(); }
1503 
1504 	// Set functions
1505 	void set_version_number(uint16 number) { _version_number = B_HOST_TO_LENDIAN_INT16(number); }
1506 
1507 	void set_characteristics(uint8 characteristics) { _characteristics = characteristics; }
1508 
1509 	void set_may_be_hidden(bool how) {
1510 		characteristics_accessor c;
1511 		c.all = characteristics();
1512 		c.bits.may_be_hidden = how;
1513 		set_characteristics(c.all);
1514 	}
1515 
1516 	void set_is_directory(bool how) {
1517 		characteristics_accessor c;
1518 		c.all = characteristics();
1519 		c.bits.is_directory = how;
1520 		set_characteristics(c.all);
1521 	}
1522 
1523 	void set_is_deleted(bool how) {
1524 		characteristics_accessor c;
1525 		c.all = characteristics();
1526 		c.bits.is_deleted = how;
1527 		set_characteristics(c.all);
1528 	}
1529 
1530 	void set_is_parent(bool how) {
1531 		characteristics_accessor c;
1532 		c.all = characteristics();
1533 		c.bits.is_parent = how;
1534 		set_characteristics(c.all);
1535 	}
1536 
1537 	void set_is_metadata_stream(bool how) {
1538 		characteristics_accessor c;
1539 		c.all = characteristics();
1540 		c.bits.is_metadata_stream = how;
1541 		set_characteristics(c.all);
1542 	}
1543 
1544 
1545 	void set_id_length(uint8 id_length) { _id_length = id_length; }
1546 	void set_implementation_use_length(uint8 implementation_use_length) { _implementation_use_length = implementation_use_length; }
1547 
1548 
1549 
1550 private:
1551 	union characteristics_accessor {
1552 		uint8 all;
1553 		struct {
1554 			uint8	may_be_hidden:1,
1555 					is_directory:1,
1556 					is_deleted:1,
1557 					is_parent:1,
1558 					is_metadata_stream:1,
1559 					reserved_characteristics:3;
1560 		} bits;
1561 	};
1562 
1563 	descriptor_tag  _tag;
1564 	/*! According to ECMA-167: 1 <= valid version_number <= 32767, 32768 <= reserved <= 65535.
1565 
1566 		However, according to UDF-2.01, there shall be exactly one version of
1567 		a file, and it shall be 1.
1568 	 */
1569 	uint16 _version_number;
1570 	/*! \todo Check UDF-2.01 2.3.4.2 for some more restrictions. */
1571 	uint8 _characteristics;
1572 	uint8 _id_length;
1573 	long_address _icb;
1574 	uint8 _implementation_use_length;
1575 } __attribute__((packed));
1576 
1577 
1578 /*! \brief Allocation extent descriptor
1579 
1580 	See also: ECMA-167 4/14.5
1581 */
1582 struct allocation_extent_descriptor {
1583 	descriptor_tag  tag;
1584 	uint32 previous_allocation_extent_location;
1585 	uint32 length_of_allocation_descriptors;
1586 
1587 	/*! \todo Check that this is really how things work: */
1588 	uint8* allocation_descriptors() { return (uint8*)(this+sizeof(allocation_extent_descriptor)); }
1589 } __attribute__((packed));
1590 
1591 
1592 /*! \brief icb_tag::file_type values
1593 
1594 	See also ECMA-167 4/14.6.6
1595 */
1596 enum icb_file_types {
1597 	ICB_TYPE_UNSPECIFIED = 0,
1598 	ICB_TYPE_UNALLOCATED_SPACE_ENTRY,
1599 	ICB_TYPE_PARTITION_INTEGRITY_ENTRY,
1600 	ICB_TYPE_INDIRECT_ENTRY,
1601 	ICB_TYPE_DIRECTORY,
1602 	ICB_TYPE_REGULAR_FILE,
1603 	ICB_TYPE_BLOCK_SPECIAL_DEVICE,
1604 	ICB_TYPE_CHARACTER_SPECIAL_DEVICE,
1605 	ICB_TYPE_EXTENDED_ATTRIBUTES_FILE,
1606 	ICB_TYPE_FIFO,
1607 	ICB_TYPE_ISSOCK,
1608 	ICB_TYPE_TERMINAL,
1609 	ICB_TYPE_SYMLINK,
1610 	ICB_TYPE_STREAM_DIRECTORY,
1611 
1612 	ICB_TYPE_RESERVED_START = 14,
1613 	ICB_TYPE_RESERVED_END = 247,
1614 
1615 	ICB_TYPE_CUSTOM_START = 248,
1616 	ICB_TYPE_CUSTOM_END = 255,
1617 };
1618 
1619 /*!	\brief idb_entry_tag::_flags::descriptor_flags() values
1620 
1621 	See also ECMA-167 4/14.6.8
1622 */
1623 enum icb_descriptor_types {
1624 	ICB_DESCRIPTOR_TYPE_SHORT = 0,
1625 	ICB_DESCRIPTOR_TYPE_LONG,
1626 	ICB_DESCRIPTOR_TYPE_EXTENDED,
1627 	ICB_DESCRIPTOR_TYPE_EMBEDDED,
1628 };
1629 
1630 /*! \brief ICB entry tag
1631 
1632 	Common tag found in all ICB entries (in addition to, and immediately following,
1633 	the descriptor tag).
1634 
1635 	See also: ECMA-167 4/14.6, UDF-2.01 2.3.5
1636 */
1637 struct icb_entry_tag {
1638 private:
1639 	union flags_accessor {
1640 		uint16 all_flags;
1641 		struct {
1642 			uint16	descriptor_flags:3,
1643 					if_directory_then_sort:1,	//!< To be set to 0 per UDF-2.01 2.3.5.4
1644 					non_relocatable:1,
1645 					archive:1,
1646 					setuid:1,
1647 					setgid:1,
1648 					sticky:1,
1649 					contiguous:1,
1650 					system:1,
1651 					transformed:1,
1652 					multi_version:1,			//!< To be set to 0 per UDF-2.01 2.3.5.4
1653 					is_stream:1,
1654 					reserved_icb_entry_flags:2;
1655 		} flags;
1656 	};
1657 
1658 public:
1659 	void dump() const;
1660 
1661 	uint32 prior_recorded_number_of_direct_entries() const { return B_LENDIAN_TO_HOST_INT32(_prior_recorded_number_of_direct_entries); }
1662 	uint16 strategy_type() const { return B_LENDIAN_TO_HOST_INT16(_strategy_type); }
1663 
1664 	array<uint8, 2>& strategy_parameters() { return _strategy_parameters; }
1665 	const array<uint8, 2>& strategy_parameters() const { return _strategy_parameters; }
1666 
1667 	uint16 entry_count() const { return B_LENDIAN_TO_HOST_INT16(_entry_count); }
1668 	uint8 file_type() const { return _file_type; }
1669 	logical_block_address& parent_icb_location() { return _parent_icb_location; }
1670 	const logical_block_address& parent_icb_location() const { return _parent_icb_location; }
1671 
1672 	uint16 flags() const { return B_LENDIAN_TO_HOST_INT16(_flags); }
1673 
1674 	// flags accessor functions
1675 	uint8 descriptor_flags() const {
1676 		flags_accessor f;
1677 		f.all_flags = flags();
1678 		return f.flags.descriptor_flags;
1679 	}
1680 
1681 	void set_prior_recorded_number_of_direct_entries(uint32 entries) { _prior_recorded_number_of_direct_entries = B_LENDIAN_TO_HOST_INT32(entries); }
1682 	void set_strategy_type(uint16 type) { _strategy_type = B_HOST_TO_LENDIAN_INT16(type); }
1683 
1684 	void set_entry_count(uint16 count) { _entry_count = B_LENDIAN_TO_HOST_INT16(count); }
1685 	void set_file_type(uint8 type) { _file_type = type; }
1686 
1687 	void set_flags(uint16 flags) { _flags = B_LENDIAN_TO_HOST_INT16(flags); }
1688 
1689 private:
1690 	uint32 _prior_recorded_number_of_direct_entries;
1691 	/*! Per UDF-2.01 2.3.5.1, only strategy types 4 and 4096 shall be supported.
1692 
1693 		\todo Describe strategy types here.
1694 	*/
1695 	uint16 _strategy_type;
1696 	array<uint8, 2> _strategy_parameters;
1697 	uint16 _entry_count;
1698 	uint8 _reserved;
1699 	/*! \brief icb_file_type value identifying the type of this icb entry */
1700 	uint8 _file_type;
1701 	logical_block_address _parent_icb_location;
1702 	uint16 _flags;
1703 } __attribute__((packed));
1704 
1705 /*! \brief Header portion of an ICB entry.
1706 */
1707 struct icb_header {
1708 public:
1709 	void dump() const;
1710 
1711 	descriptor_tag  &tag() { return _tag; }
1712 	const descriptor_tag  &tag() const { return _tag; }
1713 
1714 	icb_entry_tag &icb_tag() { return _icb_tag; }
1715 	const icb_entry_tag &icb_tag() const { return _icb_tag; }
1716 private:
1717 	descriptor_tag  _tag;
1718 	icb_entry_tag _icb_tag;
1719 };
1720 
1721 /*! \brief Indirect ICB entry
1722 */
1723 struct indirect_icb_entry {
1724 	descriptor_tag  tag;
1725 	icb_entry_tag icb_tag;
1726 	long_address indirect_icb;
1727 } __attribute__((packed));
1728 
1729 
1730 /*! \brief Terminal ICB entry
1731 */
1732 struct terminal_icb_entry {
1733 	descriptor_tag  tag;
1734 	icb_entry_tag icb_tag;
1735 } __attribute__((packed));
1736 
1737 
1738 /*! \brief File ICB entry
1739 
1740 	See also: ECMA-167 4/14.9
1741 
1742 	\todo Check pointer math.
1743 */
1744 struct file_icb_entry {
1745 	// get functions
1746 	descriptor_tag & tag() { return _tag; }
1747 	const descriptor_tag & tag() const { return _tag; }
1748 
1749 	icb_entry_tag& icb_tag() { return _icb_tag; }
1750 	const icb_entry_tag& icb_tag() const { return _icb_tag; }
1751 
1752 	uint32 uid() { return B_LENDIAN_TO_HOST_INT32(_uid); }
1753 	uint32 gid() { return B_LENDIAN_TO_HOST_INT32(_gid); }
1754 	uint32 permissions() { return B_LENDIAN_TO_HOST_INT32(_permissions); }
1755 	uint16 file_link_count() { return B_LENDIAN_TO_HOST_INT16(_file_link_count); }
1756 	uint8 record_format() { return _record_format; }
1757 	uint8 record_display_attributes() { return _record_display_attributes; }
1758 	uint8 record_length() { return _record_length; }
1759 	uint64 information_length() { return B_LENDIAN_TO_HOST_INT64(_information_length); }
1760 	uint64 logical_blocks_recorded() { return B_LENDIAN_TO_HOST_INT64(_logical_blocks_recorded); }
1761 
1762 	timestamp& access_date_and_time() { return _access_date_and_time; }
1763 	const timestamp& access_date_and_time() const { return _access_date_and_time; }
1764 
1765 	timestamp& modification_date_and_time() { return _modification_date_and_time; }
1766 	const timestamp& modification_date_and_time() const { return _modification_date_and_time; }
1767 
1768 	timestamp& attribute_date_and_time() { return _attribute_date_and_time; }
1769 	const timestamp& attribute_date_and_time() const { return _attribute_date_and_time; }
1770 
1771 	uint32 checkpoint() { return B_LENDIAN_TO_HOST_INT32(_checkpoint); }
1772 
1773 	long_address& extended_attribute_icb() { return _extended_attribute_icb; }
1774 	const long_address& extended_attribute_icb() const { return _extended_attribute_icb; }
1775 
1776 	entity_id& implementation_id() { return _implementation_id; }
1777 	const entity_id& implementation_id() const { return _implementation_id; }
1778 
1779 	uint64 unique_id() { return B_LENDIAN_TO_HOST_INT64(_unique_id); }
1780 	uint32 extended_attributes_length() { return B_LENDIAN_TO_HOST_INT32(_extended_attributes_length); }
1781 	uint32 allocation_descriptors_length() { return B_LENDIAN_TO_HOST_INT32(_allocation_descriptors_length); }
1782 
1783 	uint8* extended_attributes() { return ((uint8*)(this))+sizeof(file_icb_entry); }
1784 	uint8* allocation_descriptors() { return ((uint8*)(this))+sizeof(file_icb_entry)+extended_attributes_length(); }
1785 
1786 	// set functions
1787 	void set_uid(uint32 uid) { _uid = B_HOST_TO_LENDIAN_INT32(uid); }
1788 	void set_gid(uint32 gid) { _gid = B_HOST_TO_LENDIAN_INT32(gid); }
1789 	void set_permissions(uint32 permissions) { _permissions = B_HOST_TO_LENDIAN_INT32(permissions); }
1790 
1791 	void set_file_link_count(uint16 count) { _file_link_count = B_HOST_TO_LENDIAN_INT16(count); }
1792 	void set_record_format(uint8 format) { _record_format = format; }
1793 	void set_record_display_attributes(uint8 attributes) { _record_display_attributes = attributes; }
1794 	void set_record_length(uint8 length) { _record_length = length; }
1795 
1796 	void set_information_length(uint64 length) { _information_length = B_HOST_TO_LENDIAN_INT64(length); }
1797 	void set_logical_blocks_recorded(uint64 blocks) { _logical_blocks_recorded = B_HOST_TO_LENDIAN_INT64(blocks); }
1798 
1799 	void set_checkpoint(uint32 checkpoint) { _checkpoint = B_HOST_TO_LENDIAN_INT32(checkpoint); }
1800 
1801 	void set_unique_id(uint64 id) { _unique_id = B_HOST_TO_LENDIAN_INT64(id); }
1802 
1803 	void set_extended_attributes_length(uint32 length) { _extended_attributes_length = B_HOST_TO_LENDIAN_INT32(length); }
1804 	void set_allocation_descriptors_length(uint32 length) { _allocation_descriptors_length = B_HOST_TO_LENDIAN_INT32(length); }
1805 
1806 private:
1807 	descriptor_tag  _tag;
1808 	icb_entry_tag _icb_tag;
1809 	uint32 _uid;
1810 	uint32 _gid;
1811 	/*! \todo List perms in comment and add handy union thingy */
1812 	uint32 _permissions;
1813 	/*! Identifies the number of file identifier descriptors referencing
1814 		this icb.
1815 	*/
1816 	uint16 _file_link_count;
1817 	uint8 _record_format;				//!< To be set to 0 per UDF-2.01 2.3.6.1
1818 	uint8 _record_display_attributes;	//!< To be set to 0 per UDF-2.01 2.3.6.2
1819 	uint8 _record_length;				//!< To be set to 0 per UDF-2.01 2.3.6.3
1820 	uint64 _information_length;
1821 	uint64 _logical_blocks_recorded;		//!< To be 0 for files and dirs with embedded data
1822 	timestamp _access_date_and_time;
1823 	timestamp _modification_date_and_time;
1824 
1825 	// NOTE: data members following this point in the descriptor are in
1826 	// different locations in extended file entries
1827 
1828 	timestamp _attribute_date_and_time;
1829 	/*! \brief Initially 1, may be incremented upon user request. */
1830 	uint32 _checkpoint;
1831 	long_address _extended_attribute_icb;
1832 	entity_id _implementation_id;
1833 	/*! \brief The unique id identifying this file entry
1834 
1835 		The id of the root directory of a file set shall be 0.
1836 
1837 		\todo Detail the system specific requirements for unique ids from UDF-2.01
1838 	*/
1839 	uint64 _unique_id;
1840 	uint32 _extended_attributes_length;
1841 	uint32 _allocation_descriptors_length;
1842 
1843 };
1844 
1845 
1846 /*! \brief Extended file ICB entry
1847 
1848 	See also: ECMA-167 4/14.17
1849 
1850 	\todo Check pointer math.
1851 */
1852 struct extended_file_icb_entry {
1853 	// get functions
1854 	descriptor_tag & tag() { return _tag; }
1855 	const descriptor_tag & tag() const { return _tag; }
1856 
1857 	icb_entry_tag& icb_tag() { return _icb_tag; }
1858 	const icb_entry_tag& icb_tag() const { return _icb_tag; }
1859 
1860 	uint32 uid() { return B_LENDIAN_TO_HOST_INT32(_uid); }
1861 	uint32 gid() { return B_LENDIAN_TO_HOST_INT32(_gid); }
1862 	uint32 permissions() { return B_LENDIAN_TO_HOST_INT32(_permissions); }
1863 	uint16 file_link_count() { return B_LENDIAN_TO_HOST_INT16(_file_link_count); }
1864 	uint8 record_format() { return _record_format; }
1865 	uint8 record_display_attributes() { return _record_display_attributes; }
1866 	uint8 record_length() { return _record_length; }
1867 	uint64 information_length() { return B_LENDIAN_TO_HOST_INT64(_information_length); }
1868 	uint64 logical_blocks_recorded() { return B_LENDIAN_TO_HOST_INT64(_logical_blocks_recorded); }
1869 
1870 	timestamp& access_date_and_time() { return _access_date_and_time; }
1871 	const timestamp& access_date_and_time() const { return _access_date_and_time; }
1872 
1873 	timestamp& modification_date_and_time() { return _modification_date_and_time; }
1874 	const timestamp& modification_date_and_time() const { return _modification_date_and_time; }
1875 
1876 	timestamp& attribute_date_and_time() { return _attribute_date_and_time; }
1877 	const timestamp& attribute_date_and_time() const { return _attribute_date_and_time; }
1878 
1879 	uint32 checkpoint() { return B_LENDIAN_TO_HOST_INT32(_checkpoint); }
1880 
1881 	long_address& extended_attribute_icb() { return _extended_attribute_icb; }
1882 	const long_address& extended_attribute_icb() const { return _extended_attribute_icb; }
1883 
1884 	entity_id& implementation_id() { return _implementation_id; }
1885 	const entity_id& implementation_id() const { return _implementation_id; }
1886 
1887 	uint64 unique_id() { return B_LENDIAN_TO_HOST_INT64(_unique_id); }
1888 	uint32 extended_attributes_length() { return B_LENDIAN_TO_HOST_INT32(_extended_attributes_length); }
1889 	uint32 allocation_descriptors_length() { return B_LENDIAN_TO_HOST_INT32(_allocation_descriptors_length); }
1890 
1891 	uint8* extended_attributes() { return (uint8*)(this+sizeof(*this)); }
1892 	uint8* allocation_descriptors() { return (uint8*)(this+sizeof(*this)+extended_attributes_length()); }
1893 
1894 	// set functions
1895 	void set_uid(uint32 uid) { _uid = B_HOST_TO_LENDIAN_INT32(uid); }
1896 	void set_gid(uint32 gid) { _gid = B_HOST_TO_LENDIAN_INT32(gid); }
1897 	void set_permissions(uint32 permissions) { _permissions = B_HOST_TO_LENDIAN_INT32(permissions); }
1898 
1899 	void set_file_link_count(uint16 count) { _file_link_count = B_HOST_TO_LENDIAN_INT16(count); }
1900 	void set_record_format(uint8 format) { _record_format = format; }
1901 	void set_record_display_attributes(uint8 attributes) { _record_display_attributes = attributes; }
1902 	void set_record_length(uint8 length) { _record_length = length; }
1903 
1904 	void set_information_length(uint64 length) { _information_length = B_HOST_TO_LENDIAN_INT64(length); }
1905 	void set_logical_blocks_recorded(uint64 blocks) { _logical_blocks_recorded = B_HOST_TO_LENDIAN_INT64(blocks); }
1906 
1907 	void set_checkpoint(uint32 checkpoint) { _checkpoint = B_HOST_TO_LENDIAN_INT32(checkpoint); }
1908 
1909 	void set_unique_id(uint64 id) { _unique_id = B_HOST_TO_LENDIAN_INT64(id); }
1910 
1911 	void set_extended_attributes_length(uint32 length) { _extended_attributes_length = B_HOST_TO_LENDIAN_INT32(length); }
1912 	void set_allocation_descriptors_length(uint32 length) { _allocation_descriptors_length = B_HOST_TO_LENDIAN_INT32(length); }
1913 
1914 private:
1915 	descriptor_tag  _tag;
1916 	icb_entry_tag _icb_tag;
1917 	uint32 _uid;
1918 	uint32 _gid;
1919 	/*! \todo List perms in comment and add handy union thingy */
1920 	uint32 _permissions;
1921 	/*! Identifies the number of file identifier descriptors referencing
1922 		this icb.
1923 	*/
1924 	uint16 _file_link_count;
1925 	uint8 _record_format;				//!< To be set to 0 per UDF-2.01 2.3.6.1
1926 	uint8 _record_display_attributes;	//!< To be set to 0 per UDF-2.01 2.3.6.2
1927 	uint8 _record_length;				//!< To be set to 0 per UDF-2.01 2.3.6.3
1928 	uint64 _information_length;
1929 	uint64 _logical_blocks_recorded;		//!< To be 0 for files and dirs with embedded data
1930 	timestamp _access_date_and_time;
1931 	timestamp _modification_date_and_time;
1932 	timestamp _creation_date_and_time;	// <== EXTENDED FILE ENTRY ONLY
1933 	timestamp _attribute_date_and_time;
1934 	/*! \brief Initially 1, may be incremented upon user request. */
1935 	uint32 _checkpoint;
1936 	uint32 _reserved;	// <== EXTENDED FILE ENTRY ONLY
1937 	long_address _extended_attribute_icb;
1938 	long_address _stream_directory_icb;	// <== EXTENDED FILE ENTRY ONLY
1939 	entity_id _implementation_id;
1940 	/*! \brief The unique id identifying this file entry
1941 
1942 		The id of the root directory of a file set shall be 0.
1943 
1944 		\todo Detail the system specific requirements for unique ids from UDF-2.01 3.2.1.1
1945 	*/
1946 	uint64 _unique_id;
1947 	uint32 _extended_attributes_length;
1948 	uint32 _allocation_descriptors_length;
1949 
1950 };
1951 
1952 
1953 };	// namespace Udf
1954 
1955 #endif	// _UDF_DISK_STRUCTURES_H
1956 
1957