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