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