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