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