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 timezone:12, 87 type:4; 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 uint16 _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 logical_block_address(uint16 partition = 0, uint32 block = 0); 365 366 uint32 block() const { return B_LENDIAN_TO_HOST_INT32(_block); } 367 uint16 partition() const { return B_LENDIAN_TO_HOST_INT16(_partition); } 368 369 void set_block(uint32 block) { _block = B_HOST_TO_LENDIAN_INT32(block); } 370 void set_partition(uint16 partition) { _partition = B_HOST_TO_LENDIAN_INT16(partition); } 371 372 private: 373 uint32 _block; //!< Block location relative to start of corresponding partition 374 uint16 _partition; //!< Numeric partition id within logical volume 375 } __attribute__((packed)); 376 377 /*! \brief Extent types used in short_address, long_address, 378 and extended_address. 379 380 See also: ECMA-167 4/14.14.1.1 381 */ 382 enum extent_type { 383 EXTENT_TYPE_RECORDED = 0, //!< Allocated and recorded 384 EXTENT_TYPE_ALLOCATED, //!< Allocated but unrecorded 385 EXTENT_TYPE_UNALLOCATED, //!< Unallocated and unrecorded 386 EXTENT_TYPE_CONTINUATION, //!< Specifies next extent of descriptors 387 }; 388 389 390 /*! \brief Allocation descriptor. 391 392 See also: ECMA 167 4/14.14.1 393 */ 394 struct short_address { 395 private: 396 union type_and_length_accessor { 397 uint32 type_and_length; 398 struct { 399 uint32 length:30, 400 type:2; 401 // uint32 type:2, 402 // length:30; 403 } bits; 404 }; 405 406 public: 407 void dump() const; 408 409 uint8 type() const { 410 type_and_length_accessor t; 411 t.type_and_length = type_and_length(); 412 return t.bits.type; 413 } 414 uint32 length() const { 415 type_and_length_accessor t; 416 t.type_and_length = type_and_length(); 417 return t.bits.length; 418 } 419 uint32 block() const { return B_LENDIAN_TO_HOST_INT32(_block); } 420 421 void set_type(uint8 type) { 422 type_and_length_accessor t; 423 t.type_and_length = type_and_length(); 424 t.bits.type = type; 425 set_type_and_length(t.type_and_length); 426 } 427 void set_length(uint32 length) { 428 type_and_length_accessor t; 429 t.type_and_length = type_and_length(); 430 t.bits.length = length; 431 set_type_and_length(t.type_and_length); 432 } 433 void set_block(uint32 block) { _block = B_HOST_TO_LENDIAN_INT32(block); } 434 private: 435 uint32 type_and_length() const { return B_LENDIAN_TO_HOST_INT32(_type_and_length); } 436 void set_type_and_length(uint32 value) { _type_and_length = B_HOST_TO_LENDIAN_INT32(value); } 437 438 uint32 _type_and_length; 439 uint32 _block; 440 } __attribute__((packed)); 441 442 443 /*! \brief Allocation descriptor w/ 6 byte implementation use field. 444 445 See also: ECMA 167 4/14.14.2 446 */ 447 struct long_address { 448 private: 449 union type_and_length_accessor { 450 uint32 type_and_length; 451 struct { 452 uint32 length:30, 453 type:2; 454 } bits; 455 }; 456 457 public: 458 long_address(uint16 partition = 0, uint32 block = 0, uint32 length = 0, 459 uint8 type = 0); 460 461 void dump() const; 462 463 uint8 type() const { 464 type_and_length_accessor t; 465 t.type_and_length = type_and_length(); 466 return t.bits.type; 467 } 468 uint32 length() const { 469 type_and_length_accessor t; 470 t.type_and_length = type_and_length(); 471 return t.bits.length; 472 } 473 474 uint32 block() const { return _location.block(); } 475 uint16 partition() const { return _location.partition(); } 476 477 const array<uint8, 6>& implementation_use() const { return _implementation_use; } 478 array<uint8, 6>& implementation_use() { return _implementation_use; } 479 480 void set_type(uint8 type) { 481 type_and_length_accessor t; 482 t.type_and_length = type_and_length(); 483 t.bits.type = type; 484 set_type_and_length(t.type_and_length); 485 } 486 void set_length(uint32 length) { 487 type_and_length_accessor t; 488 t.type_and_length = type_and_length(); 489 t.bits.length = length; 490 set_type_and_length(t.type_and_length); 491 } 492 void set_block(uint32 block) { _location.set_block(block); } 493 void set_partition(uint16 partition) { _location.set_partition(partition); } 494 495 void set_to(uint32 block, uint16 partition, uint32 length = 1, 496 uint8 type = EXTENT_TYPE_RECORDED) 497 { 498 set_block(block); 499 set_partition(partition); 500 set_length(length); 501 set_type(type); 502 } 503 504 private: 505 uint32 type_and_length() const { return B_LENDIAN_TO_HOST_INT32(_type_and_length); } 506 void set_type_and_length(uint32 value) { _type_and_length = B_HOST_TO_LENDIAN_INT32(value); } 507 508 uint32 _type_and_length; 509 logical_block_address _location; 510 array<uint8, 6> _implementation_use; 511 } __attribute__((packed)); 512 513 /*! \brief Common tag found at the beginning of most udf descriptor structures. 514 515 For error checking, \c descriptor_tag structures have: 516 - The disk location of the tag redundantly stored in the tag itself 517 - A checksum value for the tag 518 - A CRC value and length 519 520 See also: ECMA 167 1/7.2, UDF 2.01 2.2.1, UDF 2.01 2.3.1 521 */ 522 struct descriptor_tag { 523 public: 524 void dump() const; 525 526 status_t init_check(uint32 block, bool calculateCrc = true); 527 528 uint16 id() const { return B_LENDIAN_TO_HOST_INT16(_id); } 529 uint16 version() const { return B_LENDIAN_TO_HOST_INT16(_version); } 530 uint8 checksum() const { return _checksum; } 531 uint16 serial_number() const { return B_LENDIAN_TO_HOST_INT16(_serial_number); } 532 uint16 crc() const { return B_LENDIAN_TO_HOST_INT16(_crc); } 533 uint16 crc_length() const { return B_LENDIAN_TO_HOST_INT16(_crc_length); } 534 uint32 location() const { return B_LENDIAN_TO_HOST_INT32(_location); } 535 536 void set_id(uint16 id) { _id = B_HOST_TO_LENDIAN_INT16(id); } 537 void set_version(uint16 version) { _version = B_HOST_TO_LENDIAN_INT16(version); } 538 void set_checksum(uint8 checksum) { _checksum = checksum; } 539 void set_serial_number(uint16 serial_number) { _serial_number = B_HOST_TO_LENDIAN_INT16(serial_number); } 540 void set_crc(uint16 crc) { _crc = B_HOST_TO_LENDIAN_INT16(crc); } 541 void set_crc_length(uint16 crc_length) { _crc_length = B_HOST_TO_LENDIAN_INT16(crc_length); } 542 void set_location(uint32 location) { _location = B_HOST_TO_LENDIAN_INT32(location); } 543 544 /*! \brief Calculates and sets the crc length, crc checksumm, and 545 checksum for the tag. 546 547 This function should not be called until all member variables in 548 the descriptor_tag's enclosing descriptor and all member variables 549 in the descriptor_tag itself other than crc_length, crc, and checksum 550 have been set (since the checksum is based off of values in the 551 descriptor_tag, and the crc is based off the values in and the 552 size of the enclosing descriptor). 553 554 \param The tag's enclosing descriptor. 555 \param The size of the tag's enclosing descriptor (including the 556 tag); only necessary if different from sizeof(Descriptor). 557 */ 558 template <class Descriptor> 559 void 560 set_checksums(Descriptor &descriptor, uint16 size = sizeof(Descriptor)) 561 { 562 563 // check that this tag is actually owned by 564 // the given descriptor 565 if (this == &descriptor.tag()) 566 { 567 // crc_length, based off provided descriptor 568 set_crc_length(size - sizeof(descriptor_tag)); 569 // crc 570 uint16 crc = Udf::calculate_crc(reinterpret_cast<uint8*>(this) 571 + sizeof(descriptor_tag), crc_length()); 572 set_crc(crc); 573 // checksum (which depends on the other two values) 574 uint32 sum = 0; 575 for (int i = 0; i <= 3; i++) 576 sum += reinterpret_cast<uint8*>(this)[i]; 577 for (int i = 5; i <= 15; i++) 578 sum += reinterpret_cast<uint8*>(this)[i]; 579 set_checksum(sum % 256); 580 } 581 } 582 private: 583 uint16 _id; 584 uint16 _version; 585 uint8 _checksum; //!< Sum modulo 256 of bytes 0-3 and 5-15 of this struct. 586 uint8 _reserved; //!< Set to #00. 587 uint16 _serial_number; 588 uint16 _crc; //!< May be 0 if \c crc_length field is 0. 589 /*! \brief Length of the data chunk used to calculate CRC. 590 591 If 0, no CRC was calculated, and the \c crc field must be 0. 592 593 According to UDF-2.01 2.3.1.2, the CRC shall be calculated for all descriptors 594 unless otherwise noted, and this field shall be set to: 595 596 <code>(descriptor length) - (descriptor tag length)</code> 597 */ 598 uint16 _crc_length; 599 /*! \brief Address of this tag within its partition (for error checking). 600 601 For virtually addressed structures (i.e. those accessed thru a VAT), this 602 shall be the virtual address, not the physical or logical address. 603 */ 604 uint32 _location; 605 606 } __attribute__((packed)); 607 608 609 /*! \c descriptor_tag ::id values 610 */ 611 enum tag_id { 612 TAGID_UNDEFINED = 0, 613 614 // ECMA 167, PART 3 615 TAGID_PRIMARY_VOLUME_DESCRIPTOR, 616 TAGID_ANCHOR_VOLUME_DESCRIPTOR_POINTER, 617 TAGID_VOLUME_DESCRIPTOR_POINTER, 618 TAGID_IMPLEMENTATION_USE_VOLUME_DESCRIPTOR, 619 TAGID_PARTITION_DESCRIPTOR, 620 TAGID_LOGICAL_VOLUME_DESCRIPTOR, 621 TAGID_UNALLOCATED_SPACE_DESCRIPTOR, 622 TAGID_TERMINATING_DESCRIPTOR, 623 TAGID_LOGICAL_VOLUME_INTEGRITY_DESCRIPTOR, 624 625 TAGID_CUSTOM_START = 65280, 626 TAGID_CUSTOM_END = 65535, 627 628 // ECMA 167, PART 4 629 TAGID_FILE_SET_DESCRIPTOR = 256, 630 TAGID_FILE_ID_DESCRIPTOR, 631 TAGID_ALLOCATION_EXTENT_DESCRIPTOR, 632 TAGID_INDIRECT_ENTRY, 633 TAGID_TERMINAL_ENTRY, 634 TAGID_FILE_ENTRY, 635 TAGID_EXTENDED_ATTRIBUTE_HEADER_DESCRIPTOR, 636 TAGID_UNALLOCATED_SPACE_ENTRY, 637 TAGID_SPACE_BITMAP_DESCRIPTOR, 638 TAGID_PARTITION_INTEGRITY_ENTRY, 639 TAGID_EXTENDED_FILE_ENTRY, 640 }; 641 642 const char *tag_id_to_string(tag_id id); 643 644 extern const uint16 kCrcTable[256]; 645 646 /*! \brief Primary volume descriptor 647 */ 648 struct primary_volume_descriptor { 649 public: 650 void dump() const; 651 652 // Get functions 653 const descriptor_tag & tag() const { return _tag; } 654 descriptor_tag & tag() { return _tag; } 655 656 uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); } 657 uint32 primary_volume_descriptor_number() const { return B_LENDIAN_TO_HOST_INT32(_primary_volume_descriptor_number); } 658 659 const array<char, 32>& volume_identifier() const { return _volume_identifier; } 660 array<char, 32>& volume_identifier() { return _volume_identifier; } 661 662 uint16 volume_sequence_number() const { return B_LENDIAN_TO_HOST_INT16(_volume_sequence_number); } 663 uint16 max_volume_sequence_number() const { return B_LENDIAN_TO_HOST_INT16(_max_volume_sequence_number); } 664 uint16 interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_interchange_level); } 665 uint16 max_interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_max_interchange_level); } 666 uint32 character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_character_set_list); } 667 uint32 max_character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_max_character_set_list); } 668 669 const array<char, 128>& volume_set_identifier() const { return _volume_set_identifier; } 670 array<char, 128>& volume_set_identifier() { return _volume_set_identifier; } 671 672 const charspec& descriptor_character_set() const { return _descriptor_character_set; } 673 charspec& descriptor_character_set() { return _descriptor_character_set; } 674 675 const charspec& explanatory_character_set() const { return _explanatory_character_set; } 676 charspec& explanatory_character_set() { return _explanatory_character_set; } 677 678 const extent_address& volume_abstract() const { return _volume_abstract; } 679 extent_address& volume_abstract() { return _volume_abstract; } 680 const extent_address& volume_copyright_notice() const { return _volume_copyright_notice; } 681 extent_address& volume_copyright_notice() { return _volume_copyright_notice; } 682 683 const entity_id& application_id() const { return _application_id; } 684 entity_id& application_id() { return _application_id; } 685 686 const timestamp& recording_date_and_time() const { return _recording_date_and_time; } 687 timestamp& recording_date_and_time() { return _recording_date_and_time; } 688 689 const entity_id& implementation_id() const { return _implementation_id; } 690 entity_id& implementation_id() { return _implementation_id; } 691 692 const array<uint8, 64>& implementation_use() const { return _implementation_use; } 693 array<uint8, 64>& implementation_use() { return _implementation_use; } 694 695 uint32 predecessor_volume_descriptor_sequence_location() const 696 { return B_LENDIAN_TO_HOST_INT32(_predecessor_volume_descriptor_sequence_location); } 697 uint16 flags() const { return B_LENDIAN_TO_HOST_INT16(_flags); } 698 699 const array<uint8, 22>& reserved() const { return _reserved; } 700 array<uint8, 22>& reserved() { return _reserved; } 701 702 // Set functions 703 void set_vds_number(uint32 number) 704 { _vds_number = B_HOST_TO_LENDIAN_INT32(number); } 705 void set_primary_volume_descriptor_number(uint32 number) 706 { _primary_volume_descriptor_number = B_HOST_TO_LENDIAN_INT32(number); } 707 void set_volume_sequence_number(uint16 number) 708 { _volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); } 709 void set_max_volume_sequence_number(uint16 number) 710 { _max_volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); } 711 void set_interchange_level(uint16 level) 712 { _interchange_level = B_HOST_TO_LENDIAN_INT16(level); } 713 void set_max_interchange_level(uint16 level) 714 { _max_interchange_level = B_HOST_TO_LENDIAN_INT16(level); } 715 void set_character_set_list(uint32 list) 716 { _character_set_list = B_HOST_TO_LENDIAN_INT32(list); } 717 void set_max_character_set_list(uint32 list) 718 { _max_character_set_list = B_HOST_TO_LENDIAN_INT32(list); } 719 void set_predecessor_volume_descriptor_sequence_location(uint32 location) 720 { _predecessor_volume_descriptor_sequence_location = B_HOST_TO_LENDIAN_INT32(location); } 721 void set_flags(uint16 flags) 722 { _flags = B_HOST_TO_LENDIAN_INT16(flags); } 723 724 private: 725 descriptor_tag _tag; 726 uint32 _vds_number; 727 uint32 _primary_volume_descriptor_number; 728 array<char, 32> _volume_identifier; 729 uint16 _volume_sequence_number; 730 uint16 _max_volume_sequence_number; 731 uint16 _interchange_level; //!< to be set to 3 if part of multivolume set, 2 otherwise 732 uint16 _max_interchange_level; //!< to be set to 3 unless otherwise directed by user 733 uint32 _character_set_list; 734 uint32 _max_character_set_list; 735 array<char, 128> _volume_set_identifier; 736 737 /*! \brief Identifies the character set for the \c volume_identifier 738 and \c volume_set_identifier fields. 739 740 To be set to CS0. 741 */ 742 charspec _descriptor_character_set; 743 744 /*! \brief Identifies the character set used in the \c volume_abstract 745 and \c volume_copyright_notice extents. 746 747 To be set to CS0. 748 */ 749 charspec _explanatory_character_set; 750 751 extent_address _volume_abstract; 752 extent_address _volume_copyright_notice; 753 754 entity_id _application_id; 755 timestamp _recording_date_and_time; 756 entity_id _implementation_id; 757 array<uint8, 64> _implementation_use; 758 uint32 _predecessor_volume_descriptor_sequence_location; 759 uint16 _flags; 760 array<uint8, 22> _reserved; 761 762 } __attribute__((packed)); 763 764 765 /*! \brief Anchor Volume Descriptor Pointer 766 767 vd recorded at preset locations in the partition, used as a reference 768 point to the main vd sequences 769 770 According to UDF 2.01, an avdp shall be recorded in at least 2 of 771 the 3 following locations, where N is the last recordable sector 772 of the partition: 773 - 256 774 - (N - 256) 775 - N 776 777 See also: ECMA 167 3/10.2, UDF-2.01 2.2.3 778 */ 779 struct anchor_volume_descriptor { 780 public: 781 anchor_volume_descriptor() { memset(_reserved.data, 0, _reserved.size()); } 782 void dump() const; 783 784 descriptor_tag & tag() { return _tag; } 785 const descriptor_tag & tag() const { return _tag; } 786 787 extent_address& main_vds() { return _main_vds; } 788 const extent_address& main_vds() const { return _main_vds; } 789 790 extent_address& reserve_vds() { return _reserve_vds; } 791 const extent_address& reserve_vds() const { return _reserve_vds; } 792 private: 793 descriptor_tag _tag; 794 extent_address _main_vds; //!< min length of 16 sectors 795 extent_address _reserve_vds; //!< min length of 16 sectors 796 array<uint8, 480> _reserved; 797 } __attribute__((packed)); 798 799 800 /*! \brief Volume Descriptor Pointer 801 802 Used to chain extents of volume descriptor sequences together. 803 804 See also: ECMA 167 3/10.3 805 */ 806 struct descriptor_pointer { 807 descriptor_tag tag; 808 uint32 vds_number; 809 extent_address next; 810 } __attribute__((packed)); 811 812 813 /*! \brief Implementation Use Volume Descriptor 814 815 See also: ECMA 167 3/10.4 816 */ 817 struct implementation_use_descriptor { 818 public: 819 void dump() const; 820 821 // Get functions 822 const descriptor_tag & tag() const { return _tag; } 823 descriptor_tag & tag() { return _tag; } 824 825 uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); } 826 827 const entity_id& implementation_id() const { return _implementation_id; } 828 entity_id& implementation_id() { return _implementation_id; } 829 830 const array<uint8, 460>& implementation_use() const { return _implementation_use; } 831 array<uint8, 460>& implementation_use() { return _implementation_use; } 832 833 // Set functions 834 void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); } 835 private: 836 descriptor_tag _tag; 837 uint32 _vds_number; 838 entity_id _implementation_id; 839 array<uint8, 460> _implementation_use; 840 } __attribute__((packed)); 841 842 843 /*! \brief Maximum number of partition descriptors to be found in volume 844 descriptor sequence, per UDF-2.50 845 */ 846 extern const uint8 kMaxPartitionDescriptors; 847 #define UDF_MAX_PARTITION_MAPS 2 848 #define UDF_MAX_PARTITION_MAP_SIZE 64 849 850 /*! \brief Partition Descriptor 851 852 See also: ECMA 167 3/10.5 853 */ 854 struct partition_descriptor { 855 private: 856 union partition_flags_accessor { 857 uint16 partition_flags; 858 struct { 859 uint16 allocated:1, 860 reserved:15; 861 } bits; 862 }; 863 864 public: 865 void dump() const; 866 867 // Get functions 868 const descriptor_tag & tag() const { return _tag; } 869 descriptor_tag & tag() { return _tag; } 870 871 uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); } 872 uint16 partition_flags() const { return B_LENDIAN_TO_HOST_INT16(_partition_flags); } 873 bool allocated() const { 874 partition_flags_accessor f; 875 f.partition_flags = partition_flags(); 876 return f.bits.allocated; 877 } 878 uint16 partition_number() const { return B_LENDIAN_TO_HOST_INT16(_partition_number); } 879 880 const entity_id& partition_contents() const { return _partition_contents; } 881 entity_id& partition_contents() { return _partition_contents; } 882 883 const array<uint8, 128>& partition_contents_use() const { return _partition_contents_use; } 884 array<uint8, 128>& partition_contents_use() { return _partition_contents_use; } 885 886 uint32 access_type() const { return B_LENDIAN_TO_HOST_INT32(_access_type); } 887 uint32 start() const { return B_LENDIAN_TO_HOST_INT32(_start); } 888 uint32 length() const { return B_LENDIAN_TO_HOST_INT32(_length); } 889 890 const entity_id& implementation_id() const { return _implementation_id; } 891 entity_id& implementation_id() { return _implementation_id; } 892 893 const array<uint8, 128>& implementation_use() const { return _implementation_use; } 894 array<uint8, 128>& implementation_use() { return _implementation_use; } 895 896 const array<uint8, 156>& reserved() const { return _reserved; } 897 array<uint8, 156>& reserved() { return _reserved; } 898 899 // Set functions 900 void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); } 901 void set_partition_flags(uint16 flags) { _partition_flags = B_HOST_TO_LENDIAN_INT16(flags); } 902 void set_allocated(bool allocated) { 903 partition_flags_accessor f; 904 f.partition_flags = partition_flags(); 905 f.bits.allocated = allocated; 906 set_partition_flags(f.partition_flags); 907 } 908 void set_partition_number(uint16 number) { _partition_number = B_HOST_TO_LENDIAN_INT16(number); } 909 void set_access_type(uint32 type) { _access_type = B_HOST_TO_LENDIAN_INT32(type); } 910 void set_start(uint32 start) { _start = B_HOST_TO_LENDIAN_INT32(start); } 911 void set_length(uint32 length) { _length = B_HOST_TO_LENDIAN_INT32(length); } 912 913 private: 914 descriptor_tag _tag; 915 uint32 _vds_number; 916 /*! Bit 0: If 0, shall mean volume space has not been allocated. If 1, 917 shall mean volume space has been allocated. 918 */ 919 uint16 _partition_flags; 920 uint16 _partition_number; 921 922 /*! - "+NSR03" Volume recorded according to ECMA-167, i.e. UDF 923 - "+CD001" Volume recorded according to ECMA-119, i.e. iso9660 924 - "+FDC01" Volume recorded according to ECMA-107 925 - "+CDW02" Volume recorded according to ECMA-168 926 */ 927 entity_id _partition_contents; 928 array<uint8, 128> _partition_contents_use; 929 930 /*! See \c partition_access_type enum 931 */ 932 uint32 _access_type; 933 uint32 _start; 934 uint32 _length; 935 entity_id _implementation_id; 936 array<uint8, 128> _implementation_use; 937 array<uint8, 156> _reserved; 938 } __attribute__((packed)); 939 940 941 enum partition_access_type { 942 ACCESS_UNSPECIFIED, 943 ACCESS_READ_ONLY, 944 ACCESS_WRITE_ONCE, 945 ACCESS_REWRITABLE, 946 ACCESS_OVERWRITABLE, 947 }; 948 949 950 /*! \brief Logical volume descriptor 951 952 See also: ECMA 167 3/10.6, UDF-2.01 2.2.4 953 */ 954 struct logical_volume_descriptor { 955 void dump() const; 956 957 // Get functions 958 const descriptor_tag & tag() const { return _tag; } 959 descriptor_tag & tag() { return _tag; } 960 961 uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); } 962 963 const charspec& character_set() const { return _character_set; } 964 charspec& character_set() { return _character_set; } 965 966 const array<char, 128>& logical_volume_identifier() const { return _logical_volume_identifier; } 967 array<char, 128>& logical_volume_identifier() { return _logical_volume_identifier; } 968 969 uint32 logical_block_size() const { return B_LENDIAN_TO_HOST_INT32(_logical_block_size); } 970 971 const entity_id& domain_id() const { return _domain_id; } 972 entity_id& domain_id() { return _domain_id; } 973 974 const array<uint8, 16>& logical_volume_contents_use() const { return _logical_volume_contents_use; } 975 array<uint8, 16>& logical_volume_contents_use() { return _logical_volume_contents_use; } 976 977 const long_address& file_set_address() const { return *reinterpret_cast<const long_address*>(&_logical_volume_contents_use); } 978 long_address& file_set_address() { return *reinterpret_cast<long_address*>(&_logical_volume_contents_use); } 979 980 uint32 map_table_length() const { return B_LENDIAN_TO_HOST_INT32(_map_table_length); } 981 uint32 partition_map_count() const { return B_LENDIAN_TO_HOST_INT32(_partition_map_count); } 982 983 const entity_id& implementation_id() const { return _implementation_id; } 984 entity_id& implementation_id() { return _implementation_id; } 985 986 const array<uint8, 128>& implementation_use() const { return _implementation_use; } 987 array<uint8, 128>& implementation_use() { return _implementation_use; } 988 989 const extent_address& integrity_sequence_extent() const { return _integrity_sequence_extent; } 990 extent_address& integrity_sequence_extent() { return _integrity_sequence_extent; } 991 992 const uint8* partition_maps() const { return _partition_maps; } 993 uint8* partition_maps() { return _partition_maps; } 994 995 // Set functions 996 void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); } 997 void set_logical_block_size(uint32 size) { _logical_block_size = B_HOST_TO_LENDIAN_INT32(size); } 998 999 void set_map_table_length(uint32 length) { _map_table_length = B_HOST_TO_LENDIAN_INT32(length); } 1000 void set_partition_map_count(uint32 count) { _partition_map_count = B_HOST_TO_LENDIAN_INT32(count); } 1001 1002 // Other functions 1003 logical_volume_descriptor& operator=(const logical_volume_descriptor &rhs); 1004 1005 private: 1006 descriptor_tag _tag; 1007 uint32 _vds_number; 1008 1009 /*! \brief Identifies the character set for the 1010 \c logical_volume_identifier field. 1011 1012 To be set to CS0. 1013 */ 1014 charspec _character_set; 1015 array<char, 128> _logical_volume_identifier; 1016 uint32 _logical_block_size; 1017 1018 /*! \brief To be set to 0 or "*OSTA UDF Compliant". See UDF specs. 1019 */ 1020 entity_id _domain_id; 1021 1022 /*! \brief For UDF, shall contain a \c long_address which identifies 1023 the location of the logical volume's first file set. 1024 */ 1025 array<uint8, 16> _logical_volume_contents_use; 1026 1027 uint32 _map_table_length; 1028 uint32 _partition_map_count; 1029 entity_id _implementation_id; 1030 array<uint8, 128> _implementation_use; 1031 1032 /*! \brief Logical volume integrity sequence location. 1033 1034 For re/overwritable media, shall be a min of 8KB in length. 1035 For WORM media, shall be quite frickin large, as a new volume 1036 must be added to the set if the extent fills up (since you 1037 can't chain lvis's I guess). 1038 */ 1039 extent_address _integrity_sequence_extent; 1040 1041 /*! \brief Restricted to maps of type 1 for normal maps and 1042 UDF type 2 for virtual maps or maps on systems not supporting 1043 defect management. 1044 1045 Note that we actually allocate memory for the partition maps 1046 here due to the fact that we allocate logical_volume_descriptor 1047 objects on the stack sometimes. 1048 1049 See UDF-2.01 2.2.8, 2.2.9 1050 */ 1051 uint8 _partition_maps[UDF_MAX_PARTITION_MAPS * UDF_MAX_PARTITION_MAP_SIZE]; 1052 } __attribute__((packed)); 1053 1054 //! Base size (excluding partition maps) of lvd 1055 extern const uint32 kLogicalVolumeDescriptorBaseSize; 1056 1057 /*! \brief (Mostly) common portion of various partition maps 1058 1059 See also: ECMA-167 3/10.7.1 1060 */ 1061 struct partition_map_header { 1062 public: 1063 uint8 type() const { return _type; } 1064 uint8 length() const { return _length; } 1065 uint8 *map_data() { return _map_data; } 1066 const uint8 *map_data() const { return _map_data; } 1067 1068 entity_id& partition_type_id() 1069 { return *reinterpret_cast<entity_id*>(&_map_data[2]); } 1070 const entity_id& partition_type_id() const 1071 { return *reinterpret_cast<const entity_id*>(&_map_data[2]); } 1072 1073 void set_type(uint8 type) { _type = type; } 1074 void set_length(uint8 length) { _length = length; } 1075 private: 1076 uint8 _type; 1077 uint8 _length; 1078 uint8 _map_data[0]; 1079 };// __attribute__((packed)); 1080 1081 1082 /*! \brief Physical partition map (i.e. ECMA-167 Type 1 partition map) 1083 1084 See also: ECMA-167 3/10.7.2 1085 */ 1086 struct physical_partition_map { 1087 public: 1088 void dump(); 1089 1090 uint8 type() const { return _type; } 1091 uint8 length() const { return _length; } 1092 1093 uint16 volume_sequence_number() const { 1094 return B_LENDIAN_TO_HOST_INT16(_volume_sequence_number); } 1095 uint16 partition_number() const { 1096 return B_LENDIAN_TO_HOST_INT16(_partition_number); } 1097 1098 void set_type(uint8 type) { _type = type; } 1099 void set_length(uint8 length) { _length = length; } 1100 void set_volume_sequence_number(uint16 number) { 1101 _volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); } 1102 void set_partition_number(uint16 number) { 1103 _partition_number = B_HOST_TO_LENDIAN_INT16(number); } 1104 private: 1105 uint8 _type; 1106 uint8 _length; 1107 uint16 _volume_sequence_number; 1108 uint16 _partition_number; 1109 } __attribute__((packed)); 1110 1111 1112 /* ----UDF Specific---- */ 1113 /*! \brief Virtual partition map 1114 1115 Note that this map is a customization of the ECMA-167 1116 type 2 partition map. 1117 1118 See also: UDF-2.01 2.2.8 1119 */ 1120 struct virtual_partition_map { 1121 uint8 type; 1122 uint8 length; 1123 uint8 reserved1[2]; 1124 1125 /*! - flags: 0 1126 - identifier: "*UDF Virtual Partition" 1127 - identifier_suffix: per UDF-2.01 2.1.5.3 1128 */ 1129 entity_id partition_type_id; 1130 uint16 volume_sequence_number; 1131 1132 /*! corresponding type 1 partition map in same logical volume 1133 */ 1134 uint16 partition_number; 1135 uint8 reserved2[24]; 1136 } __attribute__((packed)); 1137 1138 1139 /*! \brief Maximum number of redundant sparing tables found in 1140 sparable_partition_map structures. 1141 */ 1142 #define UDF_MAX_SPARING_TABLE_COUNT 4 1143 1144 /* ----UDF Specific---- */ 1145 /*! \brief Sparable partition map 1146 1147 Note that this map is a customization of the ECMA-167 1148 type 2 partition map. 1149 1150 See also: UDF-2.01 2.2.9 1151 */ 1152 struct sparable_partition_map { 1153 public: 1154 void dump(); 1155 1156 uint8 type() const { return _type; } 1157 uint8 length() const { return _length; } 1158 1159 entity_id& partition_type_id() { return _partition_type_id; } 1160 const entity_id& partition_type_id() const { return _partition_type_id; } 1161 1162 uint16 volume_sequence_number() const { 1163 return B_LENDIAN_TO_HOST_INT16(_volume_sequence_number); } 1164 uint16 partition_number() const { 1165 return B_LENDIAN_TO_HOST_INT16(_partition_number); } 1166 uint16 packet_length() const { 1167 return B_LENDIAN_TO_HOST_INT16(_packet_length); } 1168 uint8 sparing_table_count() const { return _sparing_table_count; } 1169 uint32 sparing_table_size() const { 1170 return B_LENDIAN_TO_HOST_INT32(_sparing_table_size); } 1171 uint32 sparing_table_location(uint8 index) const { 1172 return B_LENDIAN_TO_HOST_INT32(_sparing_table_locations[index]); } 1173 1174 1175 void set_type(uint8 type) { _type = type; } 1176 void set_length(uint8 length) { _length = length; } 1177 void set_volume_sequence_number(uint16 number) { 1178 _volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); } 1179 void set_partition_number(uint16 number) { 1180 _partition_number = B_HOST_TO_LENDIAN_INT16(number); } 1181 void set_packet_length(uint16 length) { 1182 _packet_length = B_HOST_TO_LENDIAN_INT16(length); } 1183 void set_sparing_table_count(uint8 count) { 1184 _sparing_table_count = count; } 1185 void set_sparing_table_size(uint32 size) { 1186 _sparing_table_size = B_HOST_TO_LENDIAN_INT32(size); } 1187 void set_sparing_table_location(uint8 index, uint32 location) { 1188 _sparing_table_locations[index] = B_HOST_TO_LENDIAN_INT32(location); } 1189 private: 1190 uint8 _type; 1191 uint8 _length; 1192 uint8 _reserved1[2]; 1193 1194 /*! - flags: 0 1195 - identifier: "*UDF Sparable Partition" 1196 - identifier_suffix: per UDF-2.01 2.1.5.3 1197 */ 1198 entity_id _partition_type_id; 1199 uint16 _volume_sequence_number; 1200 1201 //! partition number of corresponding partition descriptor 1202 uint16 _partition_number; 1203 uint16 _packet_length; 1204 uint8 _sparing_table_count; 1205 uint8 _reserved2; 1206 uint32 _sparing_table_size; 1207 uint32 _sparing_table_locations[UDF_MAX_SPARING_TABLE_COUNT]; 1208 } __attribute__((packed)); 1209 1210 1211 /* ----UDF Specific---- */ 1212 /*! \brief Metadata partition map 1213 1214 Note that this map is a customization of the ECMA-167 1215 type 2 partition map. 1216 1217 See also: UDF-2.50 2.2.10 1218 */ 1219 struct metadata_partition_map { 1220 uint8 type; 1221 uint8 length; 1222 uint8 reserved1[2]; 1223 1224 /*! - flags: 0 1225 - identifier: "*UDF Metadata Partition" 1226 - identifier_suffix: per UDF-2.50 2.1.5 1227 */ 1228 entity_id partition_type_id; 1229 uint16 volume_sequence_number; 1230 1231 /*! corresponding type 1 or type 2 sparable partition 1232 map in same logical volume 1233 */ 1234 uint16 partition_number; 1235 uint8 reserved2[24]; 1236 } __attribute__((packed)); 1237 1238 1239 /*! \brief Unallocated space descriptor 1240 1241 See also: ECMA-167 3/10.8 1242 */ 1243 struct unallocated_space_descriptor { 1244 void dump() const; 1245 1246 // Get functions 1247 const descriptor_tag & tag() const { return _tag; } 1248 descriptor_tag & tag() { return _tag; } 1249 uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); } 1250 uint32 allocation_descriptor_count() const { return B_LENDIAN_TO_HOST_INT32(_allocation_descriptor_count); } 1251 extent_address* allocation_descriptors() { return _allocation_descriptors; } 1252 1253 // Set functions 1254 void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); } 1255 void set_allocation_descriptor_count(uint32 count) { _allocation_descriptor_count = B_HOST_TO_LENDIAN_INT32(count); } 1256 private: 1257 descriptor_tag _tag; 1258 uint32 _vds_number; 1259 uint32 _allocation_descriptor_count; 1260 extent_address _allocation_descriptors[0]; 1261 } __attribute__((packed)); 1262 1263 1264 /*! \brief Terminating descriptor 1265 1266 See also: ECMA-167 3/10.9 1267 */ 1268 struct terminating_descriptor { 1269 terminating_descriptor() { memset(_reserved.data, 0, _reserved.size()); } 1270 void dump() const; 1271 1272 // Get functions 1273 const descriptor_tag & tag() const { return _tag; } 1274 descriptor_tag & tag() { return _tag; } 1275 private: 1276 descriptor_tag _tag; 1277 array<uint8, 496> _reserved; 1278 } __attribute__((packed)); 1279 1280 1281 /*! \brief Logical volume integrity descriptor 1282 1283 See also: ECMA-167 3/10.10, UDF-2.50 2.2.6 1284 */ 1285 struct logical_volume_integrity_descriptor { 1286 public: 1287 static const uint32 minimum_implementation_use_length = 46; 1288 1289 void dump() const; 1290 uint32 descriptor_size() const { return sizeof(*this)+implementation_use_length() 1291 + partition_count()*sizeof(uint32)*2; } 1292 1293 descriptor_tag& tag() { return _tag; } 1294 const descriptor_tag& tag() const { return _tag; } 1295 1296 timestamp& recording_time() { return _recording_time; } 1297 const timestamp& recording_time() const { return _recording_time; } 1298 1299 uint32 integrity_type() const { return B_LENDIAN_TO_HOST_INT32(_integrity_type); } 1300 1301 extent_address& next_integrity_extent() { return _next_integrity_extent; } 1302 const extent_address& next_integrity_extent() const { return _next_integrity_extent; } 1303 1304 array<uint8, 32>& logical_volume_contents_use() { return _logical_volume_contents_use; } 1305 const array<uint8, 32>& logical_volume_contents_use() const { return _logical_volume_contents_use; } 1306 1307 // next_unique_id() field is actually stored in the logical_volume_contents_use() 1308 // field, per UDF-2.50 3.2.1 1309 uint64 next_unique_id() const { return B_LENDIAN_TO_HOST_INT64(_next_unique_id()); } 1310 1311 uint32 partition_count() const { return B_LENDIAN_TO_HOST_INT32(_partition_count); } 1312 uint32 implementation_use_length() const { return B_LENDIAN_TO_HOST_INT32(_implementation_use_length); } 1313 1314 /*! \todo double-check the pointer arithmetic here. */ 1315 uint32* free_space_table() { return reinterpret_cast<uint32*>(reinterpret_cast<uint8*>(this)+80); } 1316 const uint32* free_space_table() const { return reinterpret_cast<const uint32*>(reinterpret_cast<const uint8*>(this)+80); } 1317 uint32* size_table() { return reinterpret_cast<uint32*>(reinterpret_cast<uint8*>(free_space_table())+partition_count()*sizeof(uint32)); } 1318 const uint32* size_table() const { return reinterpret_cast<const uint32*>(reinterpret_cast<const uint8*>(free_space_table())+partition_count()*sizeof(uint32)); } 1319 uint8* implementation_use() { return reinterpret_cast<uint8*>(reinterpret_cast<uint8*>(size_table())+partition_count()*sizeof(uint32)); } 1320 const uint8* implementation_use() const { return reinterpret_cast<const uint8*>(reinterpret_cast<const uint8*>(size_table())+partition_count()*sizeof(uint32)); } 1321 1322 // accessors for fields stored in implementation_use() field per UDF-2.50 2.2.6.4 1323 entity_id& implementation_id() { return _accessor().id; } 1324 const entity_id& implementation_id() const { return _accessor().id; } 1325 uint32 file_count() const { return B_LENDIAN_TO_HOST_INT32(_accessor().file_count); } 1326 uint32 directory_count() const { return B_LENDIAN_TO_HOST_INT32(_accessor().directory_count); } 1327 uint16 minimum_udf_read_revision() const { return B_LENDIAN_TO_HOST_INT16(_accessor().minimum_udf_read_revision); } 1328 uint16 minimum_udf_write_revision() const { return B_LENDIAN_TO_HOST_INT16(_accessor().minimum_udf_write_revision); } 1329 uint16 maximum_udf_write_revision() const { return B_LENDIAN_TO_HOST_INT16(_accessor().maximum_udf_write_revision); } 1330 1331 // set functions 1332 void set_integrity_type(uint32 type) { _integrity_type = B_HOST_TO_LENDIAN_INT32(type); } 1333 void set_next_unique_id(uint64 id) { _next_unique_id() = B_HOST_TO_LENDIAN_INT64(id); } 1334 void set_partition_count(uint32 count) { _partition_count = B_HOST_TO_LENDIAN_INT32(count); } 1335 void set_implementation_use_length(uint32 length) { _implementation_use_length = B_HOST_TO_LENDIAN_INT32(length); } 1336 1337 // set functions for fields stored in implementation_use() field per UDF-2.50 2.2.6.4 1338 void set_file_count(uint32 count) { _accessor().file_count = B_HOST_TO_LENDIAN_INT32(count); } 1339 void set_directory_count(uint32 count) { _accessor().directory_count = B_HOST_TO_LENDIAN_INT32(count); } 1340 void set_minimum_udf_read_revision(uint16 revision) { _accessor().minimum_udf_read_revision = B_HOST_TO_LENDIAN_INT16(revision); } 1341 void set_minimum_udf_write_revision(uint16 revision) { _accessor().minimum_udf_write_revision = B_HOST_TO_LENDIAN_INT16(revision); } 1342 void set_maximum_udf_write_revision(uint16 revision) { _accessor().maximum_udf_write_revision = B_HOST_TO_LENDIAN_INT16(revision); } 1343 1344 private: 1345 struct _lvid_implementation_use_accessor { 1346 entity_id id; 1347 uint32 file_count; 1348 uint32 directory_count; 1349 uint16 minimum_udf_read_revision; 1350 uint16 minimum_udf_write_revision; 1351 uint16 maximum_udf_write_revision; 1352 }; 1353 1354 _lvid_implementation_use_accessor& _accessor() { 1355 return *reinterpret_cast<_lvid_implementation_use_accessor*>(implementation_use()); 1356 } 1357 const _lvid_implementation_use_accessor& _accessor() const { 1358 return *reinterpret_cast<const _lvid_implementation_use_accessor*>(implementation_use()); 1359 } 1360 1361 uint64& _next_unique_id() { return *reinterpret_cast<uint64*>(logical_volume_contents_use().data); } 1362 const uint64& _next_unique_id() const { return *reinterpret_cast<const uint64*>(logical_volume_contents_use().data); } 1363 1364 descriptor_tag _tag; 1365 timestamp _recording_time; 1366 uint32 _integrity_type; 1367 extent_address _next_integrity_extent; 1368 array<uint8, 32> _logical_volume_contents_use; 1369 uint32 _partition_count; 1370 uint32 _implementation_use_length; 1371 1372 } __attribute__((packed)); 1373 1374 /*! \brief Logical volume integrity types 1375 */ 1376 enum { 1377 INTEGRITY_OPEN = 0, 1378 INTEGRITY_CLOSED = 1, 1379 }; 1380 1381 //---------------------------------------------------------------------- 1382 // ECMA-167 Part 4 1383 //---------------------------------------------------------------------- 1384 1385 1386 1387 /*! \brief File set descriptor 1388 1389 Contains all the pertinent info about a file set (i.e. a hierarchy of files) 1390 1391 According to UDF-2.01, only one file set descriptor shall be recorded, 1392 except on WORM media, where the following rules apply: 1393 - Multiple file sets are allowed only on WORM media 1394 - The default file set shall be the one with highest value \c file_set_number field. 1395 - Only the default file set may be flagged as writeable. All others shall be 1396 flagged as "hard write protect". 1397 - No writeable file set may reference metadata structures which are referenced 1398 (directly or indirectly) by any other file set. Writeable file sets may, however, 1399 reference actual file data extents that are also referenced by other file sets. 1400 */ 1401 struct file_set_descriptor { 1402 void dump() const; 1403 1404 // Get functions 1405 const descriptor_tag & tag() const { return _tag; } 1406 descriptor_tag & tag() { return _tag; } 1407 1408 const timestamp& recording_date_and_time() const { return _recording_date_and_time; } 1409 timestamp& recording_date_and_time() { return _recording_date_and_time; } 1410 1411 uint16 interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_interchange_level); } 1412 uint16 max_interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_max_interchange_level); } 1413 uint32 character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_character_set_list); } 1414 uint32 max_character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_max_character_set_list); } 1415 uint32 file_set_number() const { return B_LENDIAN_TO_HOST_INT32(_file_set_number); } 1416 uint32 file_set_descriptor_number() const { return B_LENDIAN_TO_HOST_INT32(_file_set_descriptor_number); } 1417 1418 const charspec& logical_volume_id_character_set() const { return _logical_volume_id_character_set; } 1419 charspec& logical_volume_id_character_set() { return _logical_volume_id_character_set; } 1420 1421 const array<char, 128>& logical_volume_id() const { return _logical_volume_id; } 1422 array<char, 128>& logical_volume_id() { return _logical_volume_id; } 1423 1424 const charspec& file_set_id_character_set() const { return _file_set_id_character_set; } 1425 charspec& file_set_id_character_set() { return _file_set_id_character_set; } 1426 1427 const array<char, 32>& file_set_id() const { return _file_set_id; } 1428 array<char, 32>& file_set_id() { return _file_set_id; } 1429 1430 const array<char, 32>& copyright_file_id() const { return _copyright_file_id; } 1431 array<char, 32>& copyright_file_id() { return _copyright_file_id; } 1432 1433 const array<char, 32>& abstract_file_id() const { return _abstract_file_id; } 1434 array<char, 32>& abstract_file_id() { return _abstract_file_id; } 1435 1436 const long_address& root_directory_icb() const { return _root_directory_icb; } 1437 long_address& root_directory_icb() { return _root_directory_icb; } 1438 1439 const entity_id& domain_id() const { return _domain_id; } 1440 entity_id& domain_id() { return _domain_id; } 1441 1442 const long_address& next_extent() const { return _next_extent; } 1443 long_address& next_extent() { return _next_extent; } 1444 1445 const long_address& system_stream_directory_icb() const { return _system_stream_directory_icb; } 1446 long_address& system_stream_directory_icb() { return _system_stream_directory_icb; } 1447 1448 const array<uint8, 32>& reserved() const { return _reserved; } 1449 array<uint8, 32>& reserved() { return _reserved; } 1450 1451 // Set functions 1452 void set_interchange_level(uint16 level) { _interchange_level = B_HOST_TO_LENDIAN_INT16(level); } 1453 void set_max_interchange_level(uint16 level) { _max_interchange_level = B_HOST_TO_LENDIAN_INT16(level); } 1454 void set_character_set_list(uint32 list) { _character_set_list = B_HOST_TO_LENDIAN_INT32(list); } 1455 void set_max_character_set_list(uint32 list) { _max_character_set_list = B_HOST_TO_LENDIAN_INT32(list); } 1456 void set_file_set_number(uint32 number) { _file_set_number = B_HOST_TO_LENDIAN_INT32(number); } 1457 void set_file_set_descriptor_number(uint32 number) { _file_set_descriptor_number = B_HOST_TO_LENDIAN_INT32(number); } 1458 private: 1459 descriptor_tag _tag; 1460 timestamp _recording_date_and_time; 1461 uint16 _interchange_level; //!< To be set to 3 (see UDF-2.01 2.3.2.1) 1462 uint16 _max_interchange_level; //!< To be set to 3 (see UDF-2.01 2.3.2.2) 1463 uint32 _character_set_list; 1464 uint32 _max_character_set_list; 1465 uint32 _file_set_number; 1466 uint32 _file_set_descriptor_number; 1467 charspec _logical_volume_id_character_set; //!< To be set to kCSOCharspec 1468 array<char, 128> _logical_volume_id; 1469 charspec _file_set_id_character_set; 1470 array<char, 32> _file_set_id; 1471 array<char, 32> _copyright_file_id; 1472 array<char, 32> _abstract_file_id; 1473 long_address _root_directory_icb; 1474 entity_id _domain_id; 1475 long_address _next_extent; 1476 long_address _system_stream_directory_icb; 1477 array<uint8, 32> _reserved; 1478 } __attribute__((packed)); 1479 1480 1481 /*! \brief Partition header descriptor 1482 1483 Contains references to unallocated and freed space data structures. 1484 1485 Note that unallocated space is space ready to be written with no 1486 preprocessing. Freed space is space needing preprocessing (i.e. 1487 a special write pass) before use. 1488 1489 Per UDF-2.01 2.3.3, the use of tables or bitmaps shall be consistent, 1490 i.e. only one type or the other shall be used, not both. 1491 1492 To indicate disuse of a certain field, the fields of the allocation 1493 descriptor shall all be set to 0. 1494 1495 See also: ECMA-167 4/14.3, UDF-2.01 2.2.3 1496 */ 1497 struct partition_header_descriptor { 1498 long_address unallocated_space_table; 1499 long_address unallocated_space_bitmap; 1500 /*! Unused, per UDF-2.01 2.2.3 */ 1501 long_address partition_integrity_table; 1502 long_address freed_space_table; 1503 long_address freed_space_bitmap; 1504 uint8 reserved[88]; 1505 } __attribute__((packed)); 1506 1507 #define kMaxFileIdSize (sizeof(file_id_descriptor)+512+3) 1508 1509 /*! \brief File identifier descriptor 1510 1511 Identifies the name of a file entry, and the location of its corresponding 1512 ICB. 1513 1514 See also: ECMA-167 4/14.4, UDF-2.01 2.3.4 1515 1516 \todo Check pointer arithmetic 1517 */ 1518 struct file_id_descriptor { 1519 public: 1520 void dump() const; 1521 1522 descriptor_tag & tag() { return _tag; } 1523 const descriptor_tag & tag() const { return _tag; } 1524 1525 uint16 version_number() const { return B_LENDIAN_TO_HOST_INT16(_version_number); } 1526 1527 uint8 characteristics() const { return _characteristics; } 1528 1529 bool may_be_hidden() const { 1530 characteristics_accessor c; 1531 c.all = characteristics(); 1532 return c.bits.may_be_hidden; 1533 } 1534 1535 bool is_directory() const { 1536 characteristics_accessor c; 1537 c.all = characteristics(); 1538 return c.bits.is_directory; 1539 } 1540 1541 bool is_deleted() const { 1542 characteristics_accessor c; 1543 c.all = characteristics(); 1544 return c.bits.is_deleted; 1545 } 1546 1547 bool is_parent() const { 1548 characteristics_accessor c; 1549 c.all = characteristics(); 1550 return c.bits.is_parent; 1551 } 1552 1553 bool is_metadata_stream() const { 1554 characteristics_accessor c; 1555 c.all = characteristics(); 1556 return c.bits.is_metadata_stream; 1557 } 1558 1559 uint8 id_length() const { return _id_length; } 1560 1561 long_address& icb() { return _icb; } 1562 const long_address& icb() const { return _icb; } 1563 1564 uint8 implementation_use_length() const { return _implementation_use_length; } 1565 1566 /*! If implementation_use_length is greater than 0, the first 32 1567 bytes of implementation_use() shall be an entity_id identifying 1568 the implementation that generated the rest of the data in the 1569 implementation_use() field. 1570 */ 1571 uint8* implementation_use() { return ((uint8*)this)+(38); } 1572 char* id() { return ((char*)this)+(38)+implementation_use_length(); } 1573 const char* id() const { return ((const char*)this)+(38)+implementation_use_length(); } 1574 1575 uint16 structure_length() const { return (38) + id_length() + implementation_use_length(); } 1576 uint16 padding_length() const { return ((structure_length()+3)/4)*4 - structure_length(); } 1577 uint16 total_length() const { return structure_length() + padding_length(); } 1578 1579 // Set functions 1580 void set_version_number(uint16 number) { _version_number = B_HOST_TO_LENDIAN_INT16(number); } 1581 1582 void set_characteristics(uint8 characteristics) { _characteristics = characteristics; } 1583 1584 void set_may_be_hidden(bool how) { 1585 characteristics_accessor c; 1586 c.all = characteristics(); 1587 c.bits.may_be_hidden = how; 1588 set_characteristics(c.all); 1589 } 1590 1591 void set_is_directory(bool how) { 1592 characteristics_accessor c; 1593 c.all = characteristics(); 1594 c.bits.is_directory = how; 1595 set_characteristics(c.all); 1596 } 1597 1598 void set_is_deleted(bool how) { 1599 characteristics_accessor c; 1600 c.all = characteristics(); 1601 c.bits.is_deleted = how; 1602 set_characteristics(c.all); 1603 } 1604 1605 void set_is_parent(bool how) { 1606 characteristics_accessor c; 1607 c.all = characteristics(); 1608 c.bits.is_parent = how; 1609 set_characteristics(c.all); 1610 } 1611 1612 void set_is_metadata_stream(bool how) { 1613 characteristics_accessor c; 1614 c.all = characteristics(); 1615 c.bits.is_metadata_stream = how; 1616 set_characteristics(c.all); 1617 } 1618 1619 1620 void set_id_length(uint8 id_length) { _id_length = id_length; } 1621 void set_implementation_use_length(uint8 implementation_use_length) { _implementation_use_length = implementation_use_length; } 1622 1623 1624 1625 private: 1626 union characteristics_accessor { 1627 uint8 all; 1628 struct { 1629 uint8 may_be_hidden:1, 1630 is_directory:1, 1631 is_deleted:1, 1632 is_parent:1, 1633 is_metadata_stream:1, 1634 reserved_characteristics:3; 1635 } bits; 1636 }; 1637 1638 descriptor_tag _tag; 1639 /*! According to ECMA-167: 1 <= valid version_number <= 32767, 32768 <= reserved <= 65535. 1640 1641 However, according to UDF-2.01, there shall be exactly one version of 1642 a file, and it shall be 1. 1643 */ 1644 uint16 _version_number; 1645 /*! \todo Check UDF-2.01 2.3.4.2 for some more restrictions. */ 1646 uint8 _characteristics; 1647 uint8 _id_length; 1648 long_address _icb; 1649 uint8 _implementation_use_length; 1650 } __attribute__((packed)); 1651 1652 1653 /*! \brief Allocation extent descriptor 1654 1655 See also: ECMA-167 4/14.5 1656 */ 1657 struct allocation_extent_descriptor { 1658 descriptor_tag tag; 1659 uint32 previous_allocation_extent_location; 1660 uint32 length_of_allocation_descriptors; 1661 1662 /*! \todo Check that this is really how things work: */ 1663 uint8* allocation_descriptors() { return (uint8*)(reinterpret_cast<uint8*>(this)+sizeof(allocation_extent_descriptor)); } 1664 } __attribute__((packed)); 1665 1666 1667 /*! \brief icb_tag::file_type values 1668 1669 See also ECMA-167 4/14.6.6 1670 */ 1671 enum icb_file_types { 1672 ICB_TYPE_UNSPECIFIED = 0, 1673 ICB_TYPE_UNALLOCATED_SPACE_ENTRY, 1674 ICB_TYPE_PARTITION_INTEGRITY_ENTRY, 1675 ICB_TYPE_INDIRECT_ENTRY, 1676 ICB_TYPE_DIRECTORY, 1677 ICB_TYPE_REGULAR_FILE, 1678 ICB_TYPE_BLOCK_SPECIAL_DEVICE, 1679 ICB_TYPE_CHARACTER_SPECIAL_DEVICE, 1680 ICB_TYPE_EXTENDED_ATTRIBUTES_FILE, 1681 ICB_TYPE_FIFO, 1682 ICB_TYPE_ISSOCK, 1683 ICB_TYPE_TERMINAL, 1684 ICB_TYPE_SYMLINK, 1685 ICB_TYPE_STREAM_DIRECTORY, 1686 1687 ICB_TYPE_RESERVED_START = 14, 1688 ICB_TYPE_RESERVED_END = 247, 1689 1690 ICB_TYPE_CUSTOM_START = 248, 1691 ICB_TYPE_CUSTOM_END = 255, 1692 }; 1693 1694 /*! \brief idb_entry_tag::_flags::descriptor_flags() values 1695 1696 See also ECMA-167 4/14.6.8 1697 */ 1698 enum icb_descriptor_types { 1699 ICB_DESCRIPTOR_TYPE_SHORT = 0, 1700 ICB_DESCRIPTOR_TYPE_LONG, 1701 ICB_DESCRIPTOR_TYPE_EXTENDED, 1702 ICB_DESCRIPTOR_TYPE_EMBEDDED, 1703 }; 1704 1705 /*! \brief idb_entry_tag::strategy_type() values 1706 1707 See also UDF-2.50 2.3.5.1 1708 */ 1709 enum icb_strategy_types { 1710 ICB_STRATEGY_SINGLE = 4, 1711 ICB_STRATEGY_LINKED_LIST = 4096 1712 }; 1713 1714 /*! \brief ICB entry tag 1715 1716 Common tag found in all ICB entries (in addition to, and immediately following, 1717 the descriptor tag). 1718 1719 See also: ECMA-167 4/14.6, UDF-2.01 2.3.5 1720 */ 1721 struct icb_entry_tag { 1722 public: 1723 union flags_accessor { 1724 uint16 all_flags; 1725 struct { 1726 uint16 descriptor_flags:3, 1727 if_directory_then_sort:1, //!< To be set to 0 per UDF-2.01 2.3.5.4 1728 non_relocatable:1, 1729 archive:1, 1730 setuid:1, 1731 setgid:1, 1732 sticky:1, 1733 contiguous:1, 1734 system:1, 1735 transformed:1, 1736 multi_version:1, //!< To be set to 0 per UDF-2.01 2.3.5.4 1737 is_stream:1, 1738 reserved_icb_entry_flags:2; 1739 } flags; 1740 }; 1741 1742 public: 1743 void dump() const; 1744 1745 uint32 prior_recorded_number_of_direct_entries() const { return B_LENDIAN_TO_HOST_INT32(_prior_recorded_number_of_direct_entries); } 1746 uint16 strategy_type() const { return B_LENDIAN_TO_HOST_INT16(_strategy_type); } 1747 1748 array<uint8, 2>& strategy_parameters() { return _strategy_parameters; } 1749 const array<uint8, 2>& strategy_parameters() const { return _strategy_parameters; } 1750 1751 uint16 entry_count() const { return B_LENDIAN_TO_HOST_INT16(_entry_count); } 1752 uint8& reserved() { return _reserved; } 1753 uint8 file_type() const { return _file_type; } 1754 logical_block_address& parent_icb_location() { return _parent_icb_location; } 1755 const logical_block_address& parent_icb_location() const { return _parent_icb_location; } 1756 1757 uint16 flags() const { return B_LENDIAN_TO_HOST_INT16(_flags); } 1758 flags_accessor& flags_access() { return *reinterpret_cast<flags_accessor*>(&_flags); } 1759 1760 // flags accessor functions 1761 uint8 descriptor_flags() const { 1762 flags_accessor f; 1763 f.all_flags = flags(); 1764 return f.flags.descriptor_flags; 1765 } 1766 /* void set_descriptor_flags(uint8 value) { 1767 flags_accessor f; 1768 f.all_flags = flags(); 1769 f.flags.descriptor_flags = value; 1770 set_flags 1771 */ 1772 1773 void set_prior_recorded_number_of_direct_entries(uint32 entries) { _prior_recorded_number_of_direct_entries = B_LENDIAN_TO_HOST_INT32(entries); } 1774 void set_strategy_type(uint16 type) { _strategy_type = B_HOST_TO_LENDIAN_INT16(type); } 1775 1776 void set_entry_count(uint16 count) { _entry_count = B_LENDIAN_TO_HOST_INT16(count); } 1777 void set_file_type(uint8 type) { _file_type = type; } 1778 1779 void set_flags(uint16 flags) { _flags = B_LENDIAN_TO_HOST_INT16(flags); } 1780 1781 private: 1782 uint32 _prior_recorded_number_of_direct_entries; 1783 /*! Per UDF-2.01 2.3.5.1, only strategy types 4 and 4096 shall be supported. 1784 1785 \todo Describe strategy types here. 1786 */ 1787 uint16 _strategy_type; 1788 array<uint8, 2> _strategy_parameters; 1789 uint16 _entry_count; 1790 uint8 _reserved; 1791 /*! \brief icb_file_type value identifying the type of this icb entry */ 1792 uint8 _file_type; 1793 logical_block_address _parent_icb_location; 1794 uint16 _flags; 1795 } __attribute__((packed)); 1796 1797 /*! \brief Header portion of an ICB entry. 1798 */ 1799 struct icb_header { 1800 public: 1801 void dump() const; 1802 1803 descriptor_tag &tag() { return _tag; } 1804 const descriptor_tag &tag() const { return _tag; } 1805 1806 icb_entry_tag &icb_tag() { return _icb_tag; } 1807 const icb_entry_tag &icb_tag() const { return _icb_tag; } 1808 private: 1809 descriptor_tag _tag; 1810 icb_entry_tag _icb_tag; 1811 }; 1812 1813 /*! \brief Indirect ICB entry 1814 */ 1815 struct indirect_icb_entry { 1816 descriptor_tag tag; 1817 icb_entry_tag icb_tag; 1818 long_address indirect_icb; 1819 } __attribute__((packed)); 1820 1821 1822 /*! \brief Terminal ICB entry 1823 */ 1824 struct terminal_icb_entry { 1825 descriptor_tag tag; 1826 icb_entry_tag icb_tag; 1827 } __attribute__((packed)); 1828 1829 enum permissions { 1830 OTHER_EXECUTE = 0x0001, 1831 OTHER_WRITE = 0x0002, 1832 OTHER_READ = 0x0004, 1833 OTHER_ATTRIBUTES = 0x0008, 1834 OTHER_DELETE = 0x0010, 1835 GROUP_EXECUTE = 0x0020, 1836 GROUP_WRITE = 0x0040, 1837 GROUP_READ = 0x0080, 1838 GROUP_ATTRIBUTES = 0x0100, 1839 GROUP_DELETE = 0x0200, 1840 USER_EXECUTE = 0x0400, 1841 USER_WRITE = 0x0800, 1842 USER_READ = 0x1000, 1843 USER_ATTRIBUTES = 0x2000, 1844 USER_DELETE = 0x4000, 1845 }; 1846 1847 /*! \brief File ICB entry 1848 1849 See also: ECMA-167 4/14.9 1850 1851 \todo Check pointer math. 1852 */ 1853 struct file_icb_entry { 1854 void dump() const; 1855 1856 // get functions 1857 descriptor_tag & tag() { return _tag; } 1858 const descriptor_tag & tag() const { return _tag; } 1859 1860 icb_entry_tag& icb_tag() { return _icb_tag; } 1861 const icb_entry_tag& icb_tag() const { return _icb_tag; } 1862 1863 uint32 uid() const { return B_LENDIAN_TO_HOST_INT32(_uid); } 1864 uint32 gid() const { return B_LENDIAN_TO_HOST_INT32(_gid); } 1865 uint32 permissions() const { return B_LENDIAN_TO_HOST_INT32(_permissions); } 1866 uint16 file_link_count() const { return B_LENDIAN_TO_HOST_INT16(_file_link_count); } 1867 uint8 record_format() const { return _record_format; } 1868 uint8 record_display_attributes() const { return _record_display_attributes; } 1869 uint8 record_length() const { return _record_length; } 1870 uint64 information_length() const { return B_LENDIAN_TO_HOST_INT64(_information_length); } 1871 uint64 logical_blocks_recorded() const { return B_LENDIAN_TO_HOST_INT64(_logical_blocks_recorded); } 1872 1873 timestamp& access_date_and_time() { return _access_date_and_time; } 1874 const timestamp& access_date_and_time() const { return _access_date_and_time; } 1875 1876 timestamp& modification_date_and_time() { return _modification_date_and_time; } 1877 const timestamp& modification_date_and_time() const { return _modification_date_and_time; } 1878 1879 timestamp& attribute_date_and_time() { return _attribute_date_and_time; } 1880 const timestamp& attribute_date_and_time() const { return _attribute_date_and_time; } 1881 1882 uint32 checkpoint() const { return B_LENDIAN_TO_HOST_INT32(_checkpoint); } 1883 1884 long_address& extended_attribute_icb() { return _extended_attribute_icb; } 1885 const long_address& extended_attribute_icb() const { return _extended_attribute_icb; } 1886 1887 entity_id& implementation_id() { return _implementation_id; } 1888 const entity_id& implementation_id() const { return _implementation_id; } 1889 1890 uint64 unique_id() const { return B_LENDIAN_TO_HOST_INT64(_unique_id); } 1891 uint32 extended_attributes_length() const { return B_LENDIAN_TO_HOST_INT32(_extended_attributes_length); } 1892 uint32 allocation_descriptors_length() const { return B_LENDIAN_TO_HOST_INT32(_allocation_descriptors_length); } 1893 1894 uint8* extended_attributes() { return _end(); } 1895 const uint8* extended_attributes() const { return _end(); } 1896 uint8* allocation_descriptors() { return _end()+extended_attributes_length(); } 1897 const uint8* allocation_descriptors() const { return _end()+extended_attributes_length(); } 1898 1899 // set functions 1900 void set_uid(uint32 uid) { _uid = B_HOST_TO_LENDIAN_INT32(uid); } 1901 void set_gid(uint32 gid) { _gid = B_HOST_TO_LENDIAN_INT32(gid); } 1902 void set_permissions(uint32 permissions) { _permissions = B_HOST_TO_LENDIAN_INT32(permissions); } 1903 1904 void set_file_link_count(uint16 count) { _file_link_count = B_HOST_TO_LENDIAN_INT16(count); } 1905 void set_record_format(uint8 format) { _record_format = format; } 1906 void set_record_display_attributes(uint8 attributes) { _record_display_attributes = attributes; } 1907 void set_record_length(uint8 length) { _record_length = length; } 1908 1909 void set_information_length(uint64 length) { _information_length = B_HOST_TO_LENDIAN_INT64(length); } 1910 void set_logical_blocks_recorded(uint64 blocks) { _logical_blocks_recorded = B_HOST_TO_LENDIAN_INT64(blocks); } 1911 1912 void set_checkpoint(uint32 checkpoint) { _checkpoint = B_HOST_TO_LENDIAN_INT32(checkpoint); } 1913 1914 void set_unique_id(uint64 id) { _unique_id = B_HOST_TO_LENDIAN_INT64(id); } 1915 1916 void set_extended_attributes_length(uint32 length) { _extended_attributes_length = B_HOST_TO_LENDIAN_INT32(length); } 1917 void set_allocation_descriptors_length(uint32 length) { _allocation_descriptors_length = B_HOST_TO_LENDIAN_INT32(length); } 1918 1919 private: 1920 static const uint32 _descriptor_length = 176; 1921 uint8* _end() { return reinterpret_cast<uint8*>(this)+_descriptor_length; } 1922 const uint8* _end() const { return reinterpret_cast<const uint8*>(this)+_descriptor_length; } 1923 1924 descriptor_tag _tag; 1925 icb_entry_tag _icb_tag; 1926 uint32 _uid; 1927 uint32 _gid; 1928 /*! \todo List perms in comment and add handy union thingy */ 1929 uint32 _permissions; 1930 /*! Identifies the number of file identifier descriptors referencing 1931 this icb. 1932 */ 1933 uint16 _file_link_count; 1934 uint8 _record_format; //!< To be set to 0 per UDF-2.01 2.3.6.1 1935 uint8 _record_display_attributes; //!< To be set to 0 per UDF-2.01 2.3.6.2 1936 uint8 _record_length; //!< To be set to 0 per UDF-2.01 2.3.6.3 1937 uint64 _information_length; 1938 uint64 _logical_blocks_recorded; //!< To be 0 for files and dirs with embedded data 1939 timestamp _access_date_and_time; 1940 timestamp _modification_date_and_time; 1941 1942 // NOTE: data members following this point in the descriptor are in 1943 // different locations in extended file entries 1944 1945 timestamp _attribute_date_and_time; 1946 /*! \brief Initially 1, may be incremented upon user request. */ 1947 uint32 _checkpoint; 1948 long_address _extended_attribute_icb; 1949 entity_id _implementation_id; 1950 /*! \brief The unique id identifying this file entry 1951 1952 The id of the root directory of a file set shall be 0. 1953 1954 \todo Detail the system specific requirements for unique ids from UDF-2.01 1955 */ 1956 uint64 _unique_id; 1957 uint32 _extended_attributes_length; 1958 uint32 _allocation_descriptors_length; 1959 1960 }; 1961 1962 1963 /*! \brief Extended file ICB entry 1964 1965 See also: ECMA-167 4/14.17 1966 1967 \todo Check pointer math. 1968 */ 1969 struct extended_file_icb_entry { 1970 void dump() const; 1971 uint32 descriptor_size() const { return sizeof(*this)+extended_attributes_length() 1972 +allocation_descriptors_length(); } 1973 1974 // get functions 1975 descriptor_tag & tag() { return _tag; } 1976 const descriptor_tag & tag() const { return _tag; } 1977 1978 icb_entry_tag& icb_tag() { return _icb_tag; } 1979 const icb_entry_tag& icb_tag() const { return _icb_tag; } 1980 1981 uint32 uid() const { return B_LENDIAN_TO_HOST_INT32(_uid); } 1982 uint32 gid() const { return B_LENDIAN_TO_HOST_INT32(_gid); } 1983 uint32 permissions() const { return B_LENDIAN_TO_HOST_INT32(_permissions); } 1984 uint16 file_link_count() const { return B_LENDIAN_TO_HOST_INT16(_file_link_count); } 1985 uint8 record_format() const { return _record_format; } 1986 uint8 record_display_attributes() const { return _record_display_attributes; } 1987 uint32 record_length() const { return _record_length; } 1988 uint64 information_length() const { return B_LENDIAN_TO_HOST_INT64(_information_length); } 1989 uint64 object_size() const { return B_LENDIAN_TO_HOST_INT64(_object_size); } 1990 uint64 logical_blocks_recorded() const { return B_LENDIAN_TO_HOST_INT64(_logical_blocks_recorded); } 1991 1992 timestamp& access_date_and_time() { return _access_date_and_time; } 1993 const timestamp& access_date_and_time() const { return _access_date_and_time; } 1994 1995 timestamp& modification_date_and_time() { return _modification_date_and_time; } 1996 const timestamp& modification_date_and_time() const { return _modification_date_and_time; } 1997 1998 timestamp& creation_date_and_time() { return _creation_date_and_time; } 1999 const timestamp& creation_date_and_time() const { return _creation_date_and_time; } 2000 2001 timestamp& attribute_date_and_time() { return _attribute_date_and_time; } 2002 const timestamp& attribute_date_and_time() const { return _attribute_date_and_time; } 2003 2004 uint32 checkpoint() const { return B_LENDIAN_TO_HOST_INT32(_checkpoint); } 2005 2006 long_address& extended_attribute_icb() { return _extended_attribute_icb; } 2007 const long_address& extended_attribute_icb() const { return _extended_attribute_icb; } 2008 2009 long_address& stream_directory_icb() { return _stream_directory_icb; } 2010 const long_address& stream_directory_icb() const { return _stream_directory_icb; } 2011 2012 entity_id& implementation_id() { return _implementation_id; } 2013 const entity_id& implementation_id() const { return _implementation_id; } 2014 2015 uint64 unique_id() const { return B_LENDIAN_TO_HOST_INT64(_unique_id); } 2016 uint32 extended_attributes_length() const { return B_LENDIAN_TO_HOST_INT32(_extended_attributes_length); } 2017 uint32 allocation_descriptors_length() const { return B_LENDIAN_TO_HOST_INT32(_allocation_descriptors_length); } 2018 2019 uint8* extended_attributes() { return _end(); } 2020 const uint8* extended_attributes() const { return _end(); } 2021 uint8* allocation_descriptors() { return _end()+extended_attributes_length(); } 2022 const uint8* allocation_descriptors() const { return _end()+extended_attributes_length(); } 2023 2024 // set functions 2025 void set_uid(uint32 uid) { _uid = B_HOST_TO_LENDIAN_INT32(uid); } 2026 void set_gid(uint32 gid) { _gid = B_HOST_TO_LENDIAN_INT32(gid); } 2027 void set_permissions(uint32 permissions) { _permissions = B_HOST_TO_LENDIAN_INT32(permissions); } 2028 2029 void set_file_link_count(uint16 count) { _file_link_count = B_HOST_TO_LENDIAN_INT16(count); } 2030 void set_record_format(uint8 format) { _record_format = format; } 2031 void set_record_display_attributes(uint8 attributes) { _record_display_attributes = attributes; } 2032 void set_record_length(uint32 length) { _record_length = B_HOST_TO_LENDIAN_INT32(length); } 2033 2034 void set_information_length(uint64 length) { _information_length = B_HOST_TO_LENDIAN_INT64(length); } 2035 void set_object_size(uint64 size) { _object_size = B_HOST_TO_LENDIAN_INT64(size); } 2036 void set_logical_blocks_recorded(uint64 blocks) { _logical_blocks_recorded = B_HOST_TO_LENDIAN_INT64(blocks); } 2037 2038 void set_checkpoint(uint32 checkpoint) { _checkpoint = B_HOST_TO_LENDIAN_INT32(checkpoint); } 2039 void set_reserved(uint32 reserved) { _reserved = B_HOST_TO_LENDIAN_INT32(reserved); } 2040 2041 void set_unique_id(uint64 id) { _unique_id = B_HOST_TO_LENDIAN_INT64(id); } 2042 2043 void set_extended_attributes_length(uint32 length) { _extended_attributes_length = B_HOST_TO_LENDIAN_INT32(length); } 2044 void set_allocation_descriptors_length(uint32 length) { _allocation_descriptors_length = B_HOST_TO_LENDIAN_INT32(length); } 2045 2046 private: 2047 static const uint32 _descriptor_length = 216; 2048 uint8* _end() { return reinterpret_cast<uint8*>(this)+_descriptor_length; } 2049 const uint8* _end() const { return reinterpret_cast<const uint8*>(this)+_descriptor_length; } 2050 2051 descriptor_tag _tag; 2052 icb_entry_tag _icb_tag; 2053 uint32 _uid; 2054 uint32 _gid; 2055 /*! \todo List perms in comment and add handy union thingy */ 2056 uint32 _permissions; 2057 /*! Identifies the number of file identifier descriptors referencing 2058 this icb. 2059 */ 2060 uint16 _file_link_count; 2061 uint8 _record_format; //!< To be set to 0 per UDF-2.01 2.3.6.1 2062 uint8 _record_display_attributes; //!< To be set to 0 per UDF-2.01 2.3.6.2 2063 uint32 _record_length; //!< To be set to 0 per UDF-2.01 2.3.6.3 2064 uint64 _information_length; 2065 uint64 _object_size; 2066 uint64 _logical_blocks_recorded; //!< To be 0 for files and dirs with embedded data 2067 timestamp _access_date_and_time; 2068 timestamp _modification_date_and_time; 2069 timestamp _creation_date_and_time; // <== EXTENDED FILE ENTRY ONLY 2070 timestamp _attribute_date_and_time; 2071 /*! \brief Initially 1, may be incremented upon user request. */ 2072 uint32 _checkpoint; 2073 uint32 _reserved; // <== EXTENDED FILE ENTRY ONLY 2074 long_address _extended_attribute_icb; 2075 long_address _stream_directory_icb; // <== EXTENDED FILE ENTRY ONLY 2076 entity_id _implementation_id; 2077 /*! \brief The unique id identifying this file entry 2078 2079 The id of the root directory of a file set shall be 0. 2080 2081 \todo Detail the system specific requirements for unique ids from UDF-2.01 3.2.1.1 2082 */ 2083 uint64 _unique_id; 2084 uint32 _extended_attributes_length; 2085 uint32 _allocation_descriptors_length; 2086 2087 }; 2088 2089 2090 }; // namespace Udf 2091 2092 #endif // _UDF_DISK_STRUCTURES_H 2093 2094