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