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