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