1 /* 2 * Copyright 2012, Jérôme Duval, korli@users.berlios.de. 3 * Copyright (c) 2003 Tyler Dauwalder, tyler@dauwalder.net 4 * This file may be used under the terms of the MIT License. 5 */ 6 7 8 /*! \file UdfStructures.cpp 9 10 UDF on-disk data structure definitions 11 */ 12 13 #include "UdfStructures.h" 14 15 #include <string.h> 16 17 #include "UdfString.h" 18 #include "Utils.h" 19 20 21 //---------------------------------------------------------------------- 22 // Constants 23 //---------------------------------------------------------------------- 24 25 const charspec kCs0CharacterSet(0, "OSTA Compressed Unicode"); 26 //const charspec kCs0Charspec = { _character_set_type: 0, 27 // _character_set_info: "OSTA Compressed Unicode" 28 // "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" 29 // "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" 30 // }; 31 32 // Volume structure descriptor ids 33 const char* kVSDID_BEA = "BEA01"; 34 const char* kVSDID_TEA = "TEA01"; 35 const char* kVSDID_BOOT = "BOOT2"; 36 const char* kVSDID_ISO = "CD001"; 37 const char* kVSDID_ECMA167_2 = "NSR02"; 38 const char* kVSDID_ECMA167_3 = "NSR03"; 39 const char* kVSDID_ECMA168 = "CDW02"; 40 41 //! crc 010041 table, as generated by crc_table.cpp 42 const uint16 kCrcTable[256] = { 43 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 44 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 45 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 46 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 47 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 48 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 49 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 50 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 51 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 52 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 53 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 54 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 55 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 56 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 57 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 58 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 59 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 60 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 61 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 62 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 63 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 64 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 65 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 66 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 67 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 68 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 69 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 70 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 71 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 72 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 73 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 74 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 75 }; 76 77 const uint32 kLogicalVolumeDescriptorBaseSize = sizeof(logical_volume_descriptor) 78 - (UDF_MAX_PARTITION_MAPS 79 * UDF_MAX_PARTITION_MAP_SIZE); 80 81 // entity_ids 82 entity_id kMetadataPartitionMapId; 83 entity_id kSparablePartitionMapId; 84 entity_id kVirtualPartitionMapId; 85 entity_id kImplementationId; 86 entity_id kPartitionContentsId1xx; 87 entity_id kPartitionContentsId2xx; 88 entity_id kLogicalVolumeInfoId150; 89 entity_id kLogicalVolumeInfoId201; 90 entity_id kDomainId150; 91 entity_id kDomainId201; 92 93 94 //---------------------------------------------------------------------- 95 // Entities initialization 96 //---------------------------------------------------------------------- 97 98 void 99 init_entities() 100 { 101 kMetadataPartitionMapId = entity_id(0, "*UDF Metadata Partition"); 102 kSparablePartitionMapId = entity_id(0, "*UDF Sparable Partition"); 103 kVirtualPartitionMapId = entity_id(0, "*UDF Virtual Partition"); 104 kImplementationId = entity_id(0, "*OpenBeOS UDF", implementation_id_suffix(OS_BEOS, BEOS_GENERIC)); 105 kPartitionContentsId1xx = entity_id(0, "+NSR02"); 106 kPartitionContentsId2xx = entity_id(0, "+NSR03"); 107 kLogicalVolumeInfoId150 = entity_id(0, "*UDF LV Info", udf_id_suffix(0x0150, OS_BEOS, BEOS_GENERIC)); 108 kLogicalVolumeInfoId201 = entity_id(0, "*UDF LV Info", udf_id_suffix(0x0201, OS_BEOS, BEOS_GENERIC)); 109 kDomainId150 = entity_id(0, "*OSTA UDF Compliant", domain_id_suffix(0x0150, 110 DF_HARD_WRITE_PROTECT)); 111 kDomainId201 = entity_id(0, "*OSTA UDF Compliant", domain_id_suffix(0x0201, 112 DF_HARD_WRITE_PROTECT)); 113 } 114 115 116 //---------------------------------------------------------------------- 117 // Helper functions 118 //---------------------------------------------------------------------- 119 120 const char *tag_id_to_string(tag_id id) 121 { 122 switch (id) { 123 case TAGID_UNDEFINED: 124 return "undefined"; 125 126 case TAGID_PRIMARY_VOLUME_DESCRIPTOR: 127 return "primary volume descriptor"; 128 case TAGID_ANCHOR_VOLUME_DESCRIPTOR_POINTER: 129 return "anchor volume descriptor pointer"; 130 case TAGID_VOLUME_DESCRIPTOR_POINTER: 131 return "volume descriptor pointer"; 132 case TAGID_IMPLEMENTATION_USE_VOLUME_DESCRIPTOR: 133 return "implementation use volume descriptor"; 134 case TAGID_PARTITION_DESCRIPTOR: 135 return "partition descriptor"; 136 case TAGID_LOGICAL_VOLUME_DESCRIPTOR: 137 return "logical volume descriptor"; 138 case TAGID_UNALLOCATED_SPACE_DESCRIPTOR: 139 return "unallocated space descriptor"; 140 case TAGID_TERMINATING_DESCRIPTOR: 141 return "terminating descriptor"; 142 case TAGID_LOGICAL_VOLUME_INTEGRITY_DESCRIPTOR: 143 return "logical volume integrity descriptor"; 144 145 case TAGID_FILE_SET_DESCRIPTOR: 146 return "file set descriptor"; 147 case TAGID_FILE_ID_DESCRIPTOR: 148 return "file identifier descriptor"; 149 case TAGID_ALLOCATION_EXTENT_DESCRIPTOR: 150 return "allocation extent descriptor"; 151 case TAGID_INDIRECT_ENTRY: 152 return "indirect entry"; 153 case TAGID_TERMINAL_ENTRY: 154 return "terminal entry"; 155 case TAGID_FILE_ENTRY: 156 return "file entry"; 157 case TAGID_EXTENDED_ATTRIBUTE_HEADER_DESCRIPTOR: 158 return "extended attribute header descriptor"; 159 case TAGID_UNALLOCATED_SPACE_ENTRY: 160 return "unallocated space entry"; 161 case TAGID_SPACE_BITMAP_DESCRIPTOR: 162 return "space bitmap descriptor"; 163 case TAGID_PARTITION_INTEGRITY_ENTRY: 164 return "partition integrity entry"; 165 case TAGID_EXTENDED_FILE_ENTRY: 166 return "extended file entry"; 167 168 default: 169 if (TAGID_CUSTOM_START <= id && id <= TAGID_CUSTOM_END) 170 return "custom"; 171 return "reserved"; 172 } 173 } 174 175 176 //---------------------------------------------------------------------- 177 // volume_structure_descriptor_header 178 //---------------------------------------------------------------------- 179 180 volume_structure_descriptor_header::volume_structure_descriptor_header(uint8 type, const char *_id, uint8 version) 181 : type(type) 182 , version(version) 183 { 184 memcpy(id, _id, 5); 185 } 186 187 188 /*! \brief Returns true if the given \a id matches the header's id. 189 */ 190 bool 191 volume_structure_descriptor_header::id_matches(const char *id) 192 { 193 return strncmp(this->id, id, 5) == 0; 194 } 195 196 197 //---------------------------------------------------------------------- 198 // charspec 199 //---------------------------------------------------------------------- 200 201 charspec::charspec(uint8 type, const char *info) 202 { 203 set_character_set_type(type); 204 set_character_set_info(info); 205 } 206 207 void 208 charspec::dump() const 209 { 210 DUMP_INIT("charspec"); 211 PRINT(("character_set_type: %d\n", character_set_type())); 212 PRINT(("character_set_info: `%s'\n", character_set_info())); 213 } 214 215 void 216 charspec::set_character_set_info(const char *info) 217 { 218 memset(_character_set_info, 0, 63); 219 if (info) 220 strncpy(_character_set_info, info, 63); 221 } 222 223 //---------------------------------------------------------------------- 224 // timestamp 225 //---------------------------------------------------------------------- 226 227 #if _KERNEL_MODE 228 static 229 int 230 get_month_length(int month, int year) 231 { 232 if (0 <= month && month < 12 && year >= 1970) { 233 const int monthLengths[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 234 int result = monthLengths[month]; 235 if (month == 1 && ((year - 1968) % 4 == 0)) 236 result++; 237 return result; 238 } else { 239 DEBUG_INIT_ETC(NULL, ("month: %d, year: %d", month, year)); 240 PRINT(("Invalid month or year! Returning 0\n")); 241 return 0; 242 } 243 } 244 #endif 245 246 timestamp::timestamp(time_t time) 247 { 248 #if !_KERNEL_MODE 249 // Is it me, or is localtime() broken? 250 tm *local = localtime(&time); 251 if (local) { 252 set_microsecond(0); 253 set_hundred_microsecond(0); 254 set_centisecond(0); 255 set_second(local->tm_sec); 256 set_minute(local->tm_min); 257 set_hour(local->tm_hour); 258 set_day(local->tm_mday); 259 set_month(local->tm_mon+1); 260 set_year(local->tm_year+1900); 261 set_type(1); 262 set_timezone(local->tm_gmtoff / 60); 263 } else { 264 _clear(); 265 } 266 #else // no localtime() in the R5 kernel... 267 // real_time_clock() is returning the time offset by -16 hours. 268 // Considering I'm -8 hours from GMT, this doesn't really make 269 // sense. For the moment I'm offsetting it manually here, but 270 // I'm not sure what the freaking deal is, and unfortunately, 271 // localtime() appears to be broken... 272 time += 16 * 60 * 60; 273 274 set_microsecond(0); 275 set_hundred_microsecond(0); 276 set_centisecond(0); 277 set_second(time % 60); 278 time = time / 60; // convert to minutes 279 set_minute(time % 60); 280 time = time / 60; // convert to hours 281 set_hour(time % 24); 282 time = time / 24; // convert to days 283 284 // From here we start at time == 0 and count up 285 // by days until we figure out what the day, month, 286 // and year are. 287 int year = 0; 288 int month = 0; 289 time_t clock = 0; 290 for (clock = 0; 291 clock + get_month_length(month, year+1970) < time; 292 clock += get_month_length(month, year+1970)) 293 { 294 month++; 295 if (month == 12) { 296 year++; 297 month = 0; 298 } 299 } 300 int day = time - clock; 301 set_day(day); 302 set_month(month+1); 303 set_year(year+1970); 304 set_type(1); 305 set_timezone(-2047); // -2047 == no timezone specified 306 #endif 307 } 308 309 void 310 timestamp::dump() const 311 { 312 DUMP_INIT("timestamp"); 313 PRINT(("type: %d\n", type())); 314 PRINT(("timezone: %d\n", timezone())); 315 PRINT(("year: %d\n", year())); 316 PRINT(("month: %d\n", month())); 317 PRINT(("day: %d\n", day())); 318 PRINT(("hour: %d\n", hour())); 319 PRINT(("minute: %d\n", minute())); 320 PRINT(("second: %d\n", second())); 321 PRINT(("centisecond: %d\n", centisecond())); 322 PRINT(("hundred_microsecond: %d\n", hundred_microsecond())); 323 PRINT(("microsecond: %d\n", microsecond())); 324 } 325 326 void 327 timestamp::_clear() 328 { 329 set_microsecond(0); 330 set_hundred_microsecond(0); 331 set_centisecond(0); 332 set_second(0); 333 set_minute(0); 334 set_hour(0); 335 set_day(0); 336 set_month(0); 337 set_year(0); 338 set_type(0); 339 set_timezone(0); 340 } 341 342 //---------------------------------------------------------------------- 343 // udf_id_suffix 344 //---------------------------------------------------------------------- 345 346 udf_id_suffix::udf_id_suffix(uint16 udfRevision, uint8 os_class, 347 uint8 os_identifier) 348 : _udf_revision(udfRevision) 349 , _os_class(os_class) 350 , _os_identifier(os_identifier) 351 { 352 memset(_reserved.data, 0, _reserved.size()); 353 } 354 355 //---------------------------------------------------------------------- 356 // implementation_id_suffix 357 //---------------------------------------------------------------------- 358 359 implementation_id_suffix::implementation_id_suffix(uint8 os_class, 360 uint8 os_identifier) 361 : _os_class(os_class) 362 , _os_identifier(os_identifier) 363 { 364 memset(_implementation_use.data, 0, _implementation_use.size()); 365 } 366 367 //---------------------------------------------------------------------- 368 // domain_id_suffix 369 //---------------------------------------------------------------------- 370 371 domain_id_suffix::domain_id_suffix(uint16 udfRevision, uint8 domainFlags) 372 : _udf_revision(udfRevision) 373 , _domain_flags(domainFlags) 374 { 375 memset(_reserved.data, 0, _reserved.size()); 376 } 377 378 //---------------------------------------------------------------------- 379 // entity_id 380 //---------------------------------------------------------------------- 381 382 entity_id::entity_id(uint8 flags, const char *identifier, uint8 *identifier_suffix) 383 : _flags(flags) 384 { 385 memset(_identifier, 0, kIdentifierLength); 386 if (identifier) 387 strncpy(_identifier, identifier, kIdentifierLength); 388 if (identifier_suffix) 389 memcpy(_identifier_suffix.data, identifier_suffix, kIdentifierSuffixLength); 390 else 391 memset(_identifier_suffix.data, 0, kIdentifierSuffixLength); 392 } 393 394 entity_id::entity_id(uint8 flags, const char *identifier, 395 const udf_id_suffix &suffix) 396 : _flags(flags) 397 { 398 memset(_identifier, 0, kIdentifierLength); 399 if (identifier) 400 strncpy(_identifier, identifier, kIdentifierLength); 401 memcpy(_identifier_suffix.data, &suffix, kIdentifierSuffixLength); 402 } 403 404 entity_id::entity_id(uint8 flags, const char *identifier, 405 const implementation_id_suffix &suffix) 406 : _flags(flags) 407 { 408 memset(_identifier, 0, kIdentifierLength); 409 if (identifier) 410 strncpy(_identifier, identifier, kIdentifierLength); 411 memcpy(_identifier_suffix.data, &suffix, kIdentifierSuffixLength); 412 } 413 414 entity_id::entity_id(uint8 flags, const char *identifier, 415 const domain_id_suffix &suffix) 416 : _flags(flags) 417 { 418 memset(_identifier, 0, kIdentifierLength); 419 if (identifier) 420 strncpy(_identifier, identifier, kIdentifierLength); 421 memcpy(_identifier_suffix.data, &suffix, kIdentifierSuffixLength); 422 } 423 424 void 425 entity_id::dump() const 426 { 427 DUMP_INIT("entity_id"); 428 PRINT(("flags: %d\n", flags())); 429 PRINT(("identifier: `%.23s'\n", identifier())); 430 PRINT(("identifier_suffix:\n")); 431 DUMP(identifier_suffix()); 432 } 433 434 bool 435 entity_id::matches(const entity_id &id) const 436 { 437 bool result = true; 438 for (int i = 0; i < entity_id::kIdentifierLength; i++) { 439 if (identifier()[i] != id.identifier()[i]) { 440 result = false; 441 break; 442 } 443 } 444 return result; 445 } 446 447 //---------------------------------------------------------------------- 448 // extent_address 449 //---------------------------------------------------------------------- 450 451 extent_address::extent_address(uint32 location, uint32 length) 452 { 453 set_location(location); 454 set_length(length); 455 } 456 457 void 458 extent_address::dump() const 459 { 460 DUMP_INIT("extent_address"); 461 PRINT(("length: %ld\n", length())); 462 PRINT(("location: %ld\n", location())); 463 } 464 465 //---------------------------------------------------------------------- 466 // logical_block_address 467 //---------------------------------------------------------------------- 468 469 void 470 logical_block_address::dump() const 471 { 472 DUMP_INIT("logical_block_address"); 473 PRINT(("block: %ld\n", block())); 474 PRINT(("partition: %d\n", partition())); 475 } 476 477 logical_block_address::logical_block_address(uint16 partition, uint32 block) 478 { 479 set_partition(partition); 480 set_block(block); 481 } 482 483 //---------------------------------------------------------------------- 484 // long_address 485 //---------------------------------------------------------------------- 486 487 long_address::long_address(uint16 partition, uint32 block, uint32 length, 488 uint8 type) 489 { 490 set_partition(partition); 491 set_block(block); 492 set_length(length); 493 set_type(type); 494 memset(_implementation_use.data, 0, _implementation_use.size()); 495 } 496 497 void 498 long_address::dump() const 499 { 500 DUMP_INIT("long_address"); 501 PRINT(("length: %ld\n", length())); 502 PRINT(("block: %ld\n", block())); 503 PRINT(("partition: %d\n", partition())); 504 PRINT(("implementation_use:\n")); 505 DUMP(implementation_use()); 506 } 507 508 //---------------------------------------------------------------------- 509 // descriptor_tag 510 //---------------------------------------------------------------------- 511 512 void 513 descriptor_tag::dump() const 514 { 515 DUMP_INIT("descriptor_tag"); 516 PRINT(("id: %d (%s)\n", id(), tag_id_to_string(tag_id(id())))); 517 PRINT(("version: %d\n", version())); 518 PRINT(("checksum: %d\n", checksum())); 519 PRINT(("serial_number: %d\n", serial_number())); 520 PRINT(("crc: %d\n", crc())); 521 PRINT(("crc_length: %d\n", crc_length())); 522 PRINT(("location: %ld\n", location())); 523 } 524 525 526 /*! \brief Calculates the tag's CRC, verifies the tag's checksum, and 527 verifies the tag's location on the medium. 528 529 Note that this function makes the assumption that the descriptor_tag 530 is the first data member in a larger descriptor structure, the remainder 531 of which immediately follows the descriptor_tag itself in memory. This 532 is generally a safe assumption, as long as the entire descriptor (and 533 not the its tag) is read in before init_check() is called. If this is 534 not the case, it's best to call this function with a \a calculateCrc 535 value of false, to keep from trying to calculate a crc value on invalid 536 and possibly unowned memory. 537 538 \param block The block location of this descriptor as taken from the 539 corresponding allocation descriptor. If the address specifies 540 a block in a partition, the partition block is the desired 541 location, not the mapped physical disk block. 542 \param calculateCrc Whether or not to perform the crc calculation 543 on the descriptor data following the tag. 544 */ 545 status_t 546 descriptor_tag::init_check(uint32 block, bool calculateCrc) 547 { 548 DEBUG_INIT_ETC("descriptor_tag", ("location: %ld, calculateCrc: %s", 549 block, bool_to_string(calculateCrc))); 550 PRINT(("location (parameter) == %ld\n", block)); 551 PRINT(("location (in structure) == %ld\n", location())); 552 if (calculateCrc) { 553 PRINT(("crc (calculated) == %d\n", 554 calculate_crc(reinterpret_cast<uint8*>(this)+sizeof(descriptor_tag), 555 crc_length()))) 556 } else { 557 PRINT(("crc (calculated) == (not calculated)\n")); 558 } 559 PRINT(("crc (in structure) == %d\n", crc())); 560 PRINT(("crc_length (in structure) == %d\n", crc_length())); 561 // location 562 status_t error = (block == location()) ? B_OK : B_NO_INIT; 563 // checksum 564 if (!error) { 565 uint32 sum = 0; 566 for (int i = 0; i <= 3; i++) 567 sum += reinterpret_cast<uint8*>(this)[i]; 568 for (int i = 5; i <= 15; i++) 569 sum += reinterpret_cast<uint8*>(this)[i]; 570 error = sum % 256 == checksum() ? B_OK : B_NO_INIT; 571 } 572 // crc 573 if (!error && calculateCrc) { 574 uint16 _crc = calculate_crc(reinterpret_cast<uint8*>(this) 575 + sizeof(descriptor_tag), crc_length()); 576 error = _crc == crc() ? B_OK : B_NO_INIT; 577 } 578 RETURN(error); 579 } 580 581 //---------------------------------------------------------------------- 582 // primary_volume_descriptor 583 //---------------------------------------------------------------------- 584 585 void 586 primary_volume_descriptor::dump() const 587 { 588 DUMP_INIT("primary_volume_descriptor"); 589 590 UdfString string; 591 592 PRINT(("tag:\n")); 593 DUMP(tag()); 594 PRINT(("vds_number: %ld\n", vds_number())); 595 PRINT(("primary_volume_descriptor_number: %ld\n", primary_volume_descriptor_number())); 596 string = volume_identifier(); 597 PRINT(("volume_identifier: `%s'\n", string.Utf8())); 598 PRINT(("volume_sequence_number: %d\n", volume_sequence_number())); 599 PRINT(("max_volume_sequence_number: %d\n", max_volume_sequence_number())); 600 PRINT(("interchange_level: %d\n", interchange_level())); 601 PRINT(("max_interchange_level: %d\n", max_interchange_level())); 602 PRINT(("character_set_list: %ld\n", character_set_list())); 603 PRINT(("max_character_set_list: %ld\n", max_character_set_list())); 604 string = volume_set_identifier(); 605 PRINT(("volume_set_identifier: `%s'\n", string.Utf8())); 606 PRINT(("descriptor_character_set:\n")); 607 DUMP(descriptor_character_set()); 608 PRINT(("explanatory_character_set:\n")); 609 DUMP(explanatory_character_set()); 610 PRINT(("volume_abstract:\n")); 611 DUMP(volume_abstract()); 612 PRINT(("volume_copyright_notice:\n")); 613 DUMP(volume_copyright_notice()); 614 PRINT(("application_id:\n")); 615 DUMP(application_id()); 616 PRINT(("recording_date_and_time:\n")); 617 DUMP(recording_date_and_time()); 618 PRINT(("implementation_id:\n")); 619 DUMP(implementation_id()); 620 PRINT(("implementation_use:\n")); 621 DUMP(implementation_use()); 622 PRINT(("predecessor_vds_location: %ld\n", 623 predecessor_volume_descriptor_sequence_location())); 624 PRINT(("flags: %d\n", flags())); 625 } 626 627 628 //---------------------------------------------------------------------- 629 // anchor_volume_descriptor_pointer 630 //---------------------------------------------------------------------- 631 632 void 633 anchor_volume_descriptor::dump() const 634 { 635 DUMP_INIT("anchor_volume_descriptor"); 636 PRINT(("tag:\n")); 637 DUMP(tag()); 638 PRINT(("main_vds:\n")); 639 DUMP(main_vds()); 640 PRINT(("reserve_vds:\n")); 641 DUMP(reserve_vds()); 642 } 643 644 //---------------------------------------------------------------------- 645 // logical_volume_info 646 //---------------------------------------------------------------------- 647 648 void 649 logical_volume_info::dump() const 650 { 651 UdfString string; 652 DUMP_INIT("logical_volume_information"); 653 PRINT(("character_set:\n")); 654 DUMP(character_set()); 655 string = logical_volume_id(); 656 PRINT(("logical_volume_id: `%s'\n", string.Utf8())); 657 for (uint32 i = 0; i < _logical_volume_info.length(); i++) { 658 string = _logical_volume_info[i]; 659 PRINT(("logical_volume_info #%ld: %s\n", i, string.Utf8())); 660 } 661 PRINT(("implementation_id:\n")); 662 DUMP(implementation_id()); 663 PRINT(("implementation_use:\n")); 664 DUMP(implementation_use()); 665 } 666 667 //---------------------------------------------------------------------- 668 // implementation_use_descriptor 669 //---------------------------------------------------------------------- 670 671 void 672 implementation_use_descriptor::dump() const 673 { 674 DUMP_INIT("implementation_use_descriptor"); 675 PRINT(("tag:\n")); 676 DUMP(tag()); 677 PRINT(("vds_number: %ld\n", vds_number())); 678 PRINT(("implementation_id:\n")); 679 DUMP(implementation_id()); 680 PRINT(("implementation_use: XXX\n")); 681 DUMP(implementation_use()); 682 } 683 684 //---------------------------------------------------------------------- 685 // partition_descriptor 686 //---------------------------------------------------------------------- 687 688 const uint8 kMaxPartitionDescriptors = 2; 689 690 void 691 partition_descriptor::dump() const 692 { 693 DUMP_INIT("partition_descriptor"); 694 PRINT(("tag:\n")); 695 DUMP(tag()); 696 PRINT(("vds_number: %ld\n", vds_number())); 697 PRINT(("partition_flags: %d\n", partition_flags())); 698 PRINT(("partition_flags.allocated: %s\n", allocated() ? "true" : "false")); 699 PRINT(("partition_number: %d\n", partition_number())); 700 PRINT(("partition_contents:\n")); 701 DUMP(partition_contents()); 702 PRINT(("partition_contents_use: XXX\n")); 703 DUMP(partition_contents_use()); 704 PRINT(("access_type: %ld\n", access_type())); 705 PRINT(("start: %ld\n", start())); 706 PRINT(("length: %ld\n", length())); 707 PRINT(("implementation_id:\n")); 708 DUMP(implementation_id()); 709 PRINT(("implementation_use: XXX\n")); 710 DUMP(implementation_use()); 711 } 712 713 //---------------------------------------------------------------------- 714 // logical_volume_descriptor 715 //---------------------------------------------------------------------- 716 717 void 718 logical_volume_descriptor::dump() const 719 { 720 DUMP_INIT("logical_volume_descriptor"); 721 PRINT(("tag:\n")); 722 DUMP(tag()); 723 PRINT(("vds_number: %ld\n", vds_number())); 724 PRINT(("character_set:\n")); 725 DUMP(character_set()); 726 UdfString string(logical_volume_identifier()); 727 PRINT(("logical_volume_identifier: `%s'\n", string.Utf8())); 728 PRINT(("logical_block_size: %ld\n", logical_block_size())); 729 PRINT(("domain_id:\n")); 730 DUMP(domain_id()); 731 PRINT(("logical_volume_contents_use:\n")); 732 DUMP(logical_volume_contents_use()); 733 PRINT(("file_set_address:\n")); 734 DUMP(file_set_address()); 735 PRINT(("map_table_length: %ld\n", map_table_length())); 736 PRINT(("partition_map_count: %ld\n", partition_map_count())); 737 PRINT(("implementation_id:\n")); 738 DUMP(implementation_id()); 739 PRINT(("implementation_use:\n")); 740 DUMP(implementation_use()); 741 PRINT(("integrity_sequence_extent:\n")); 742 DUMP(integrity_sequence_extent()); 743 // PRINT(("partition_maps:\n")); 744 const uint8 *maps = partition_maps(); 745 int offset = 0; 746 for (uint i = 0; i < partition_map_count(); i++) { 747 PRINT(("partition_map #%d:\n", i)); 748 uint8 type = maps[offset]; 749 uint8 length = maps[offset+1]; 750 PRINT((" type: %d\n", type)); 751 PRINT((" length: %d\n", length)); 752 switch (type) { 753 case 1: 754 for (int j = 0; j < length-2; j++) 755 PRINT((" data[%d]: %d\n", j, maps[offset+2+j])); 756 break; 757 case 2: { 758 PRINT((" partition_number: %d\n", *reinterpret_cast<const uint16*>(&(maps[offset+38])))); 759 PRINT((" entity_id:\n")); 760 const entity_id *id = reinterpret_cast<const entity_id*>(&(maps[offset+4])); 761 if (id) // To kill warning when DEBUG==0 762 PDUMP(id); 763 break; 764 } 765 } 766 offset += maps[offset+1]; 767 } 768 // \todo dump partition_maps 769 } 770 771 772 logical_volume_descriptor& 773 logical_volume_descriptor::operator=(const logical_volume_descriptor &rhs) 774 { 775 _tag = rhs._tag; 776 _vds_number = rhs._vds_number; 777 _character_set = rhs._character_set; 778 _logical_volume_identifier = rhs._logical_volume_identifier; 779 _logical_block_size = rhs._logical_block_size; 780 _domain_id = rhs._domain_id; 781 _logical_volume_contents_use = rhs._logical_volume_contents_use; 782 _map_table_length = rhs._map_table_length; 783 _partition_map_count = rhs._partition_map_count; 784 _implementation_id = rhs._implementation_id; 785 _implementation_use = rhs._implementation_use; 786 _integrity_sequence_extent = rhs._integrity_sequence_extent; 787 // copy the partition maps one by one 788 uint8 *lhsMaps = partition_maps(); 789 const uint8 *rhsMaps = rhs.partition_maps(); 790 int offset = 0; 791 for (uint8 i = 0; i < rhs.partition_map_count(); i++) { 792 uint8 length = rhsMaps[offset+1]; 793 memcpy(&lhsMaps[offset], &rhsMaps[offset], length); 794 offset += length; 795 } 796 return *this; 797 } 798 799 800 //---------------------------------------------------------------------- 801 // physical_partition_map 802 //---------------------------------------------------------------------- 803 804 void 805 physical_partition_map::dump() 806 { 807 DUMP_INIT("physical_partition_map"); 808 PRINT(("type: %d\n", type())); 809 PRINT(("length: %d\n", length())); 810 PRINT(("volume_sequence_number: %d\n", volume_sequence_number())); 811 PRINT(("partition_number: %d\n", partition_number())); 812 } 813 814 //---------------------------------------------------------------------- 815 // sparable_partition_map 816 //---------------------------------------------------------------------- 817 818 void 819 sparable_partition_map::dump() 820 { 821 DUMP_INIT("sparable_partition_map"); 822 PRINT(("type: %d\n", type())); 823 PRINT(("length: %d\n", length())); 824 PRINT(("partition_type_id:")); 825 DUMP(partition_type_id()); 826 PRINT(("volume_sequence_number: %d\n", volume_sequence_number())); 827 PRINT(("partition_number: %d\n", partition_number())); 828 PRINT(("sparing_table_count: %d\n", sparing_table_count())); 829 PRINT(("sparing_table_size: %ld\n", sparing_table_size())); 830 PRINT(("sparing_table_locations:")); 831 for (uint8 i = 0; i < sparing_table_count(); i++) 832 PRINT((" %d: %ld\n", i, sparing_table_location(i))); 833 } 834 835 //---------------------------------------------------------------------- 836 // unallocated_space_descriptor 837 //---------------------------------------------------------------------- 838 839 void 840 unallocated_space_descriptor::dump() const 841 { 842 DUMP_INIT("unallocated_space_descriptor"); 843 PRINT(("tag:\n")); 844 DUMP(tag()); 845 PRINT(("vds_number: %ld\n", vds_number())); 846 PRINT(("allocation_descriptor_count: %ld\n", allocation_descriptor_count())); 847 // \todo dump alloc_descriptors 848 } 849 850 851 //---------------------------------------------------------------------- 852 // terminating_descriptor 853 //---------------------------------------------------------------------- 854 855 void 856 terminating_descriptor::dump() const 857 { 858 DUMP_INIT("terminating_descriptor"); 859 PRINT(("tag:\n")); 860 DUMP(tag()); 861 } 862 863 //---------------------------------------------------------------------- 864 // file_set_descriptor 865 //---------------------------------------------------------------------- 866 867 void 868 file_set_descriptor::dump() const 869 { 870 DUMP_INIT("file_set_descriptor"); 871 PRINT(("tag:\n")); 872 DUMP(tag()); 873 PRINT(("recording_date_and_time:\n")); 874 DUMP(recording_date_and_time()); 875 PRINT(("interchange_level: %d\n", interchange_level())); 876 PRINT(("max_interchange_level: %d\n", max_interchange_level())); 877 PRINT(("character_set_list: %ld\n", character_set_list())); 878 PRINT(("max_character_set_list: %ld\n", max_character_set_list())); 879 PRINT(("file_set_number: %ld\n", file_set_number())); 880 PRINT(("file_set_descriptor_number: %ld\n", file_set_descriptor_number())); 881 PRINT(("logical_volume_id_character_set:\n")); 882 DUMP(logical_volume_id_character_set()); 883 PRINT(("logical_volume_id:\n")); 884 DUMP(logical_volume_id()); 885 PRINT(("file_set_id_character_set:\n")); 886 DUMP(file_set_id_character_set()); 887 PRINT(("file_set_id:\n")); 888 DUMP(file_set_id()); 889 PRINT(("copyright_file_id:\n")); 890 DUMP(copyright_file_id()); 891 PRINT(("abstract_file_id:\n")); 892 DUMP(abstract_file_id()); 893 PRINT(("root_directory_icb:\n")); 894 DUMP(root_directory_icb()); 895 PRINT(("domain_id:\n")); 896 DUMP(domain_id()); 897 PRINT(("next_extent:\n")); 898 DUMP(next_extent()); 899 PRINT(("system_stream_directory_icb:\n")); 900 DUMP(system_stream_directory_icb()); 901 } 902 903 //---------------------------------------------------------------------- 904 // logical_volume_integrity_descriptor 905 //---------------------------------------------------------------------- 906 907 void 908 logical_volume_integrity_descriptor::dump() const 909 { 910 DUMP_INIT("logical_volume_integrity_descriptor"); 911 PRINT(("tag:\n")); 912 DUMP(tag()); 913 PRINT(("recording_time:\n")); 914 DUMP(recording_time()); 915 PRINT(("integrity_type: ")); 916 switch (integrity_type()) { 917 case INTEGRITY_OPEN: 918 SIMPLE_PRINT(("open\n")); 919 break; 920 case INTEGRITY_CLOSED: 921 SIMPLE_PRINT(("closed\n")); 922 break; 923 default: 924 SIMPLE_PRINT(("invalid integrity type (%ld)", integrity_type())); 925 break; 926 } 927 PRINT(("next_integrity_extent:\n")); 928 DUMP(next_integrity_extent()); 929 PRINT(("logical_volume_contents_use:\n")); 930 DUMP(logical_volume_contents_use()); 931 PRINT(("next_unique_id: %Ld\n", next_unique_id())); 932 PRINT(("partition_count: %ld\n", partition_count())); 933 PRINT(("implementation_use_length: %ld\n", implementation_use_length())); 934 if (partition_count() > 0) { 935 PRINT(("free_space_table:\n")); 936 for (uint32 i = 0; i < partition_count(); i++) { 937 PRINT(("partition %ld: %ld free blocks\n", i, free_space_table()[i])); 938 } 939 PRINT(("size_table:\n")); 940 for (uint32 i = 0; i < partition_count(); i++) { 941 PRINT(("partition %ld: %ld blocks large\n", i, size_table()[i])); 942 } 943 } 944 945 if (implementation_use_length() >= minimum_implementation_use_length) { 946 PRINT(("implementation_id:\n")); 947 DUMP(implementation_id()); 948 PRINT(("file_count: %ld\n", file_count())); 949 PRINT(("directory_count: %ld\n", directory_count())); 950 PRINT(("minimum_udf_read_revision: 0x%04x\n", minimum_udf_read_revision())); 951 PRINT(("minimum_udf_write_revision: 0x%04x\n", minimum_udf_write_revision())); 952 PRINT(("maximum_udf_write_revision: 0x%04x\n", maximum_udf_write_revision())); 953 } else { 954 PRINT(("NOTE: implementation_use() field of insufficient length to contain \n")); 955 PRINT((" appropriate UDF-2.50 2.2.6.4 fields.\n")); 956 } 957 } 958 959 //---------------------------------------------------------------------- 960 // file_id_descriptor 961 //---------------------------------------------------------------------- 962 963 void 964 file_id_descriptor::dump() const 965 { 966 DUMP_INIT("file_id_descriptor"); 967 PRINT(("tag:\n")); 968 DUMP(tag()); 969 PRINT(("version_number: %d\n", version_number())); 970 PRINT(("may_be_hidden: %d\n", may_be_hidden())); 971 PRINT(("is_directory: %d\n", is_directory())); 972 PRINT(("is_deleted: %d\n", is_deleted())); 973 PRINT(("is_parent: %d\n", is_parent())); 974 PRINT(("is_metadata_stream: %d\n", is_metadata_stream())); 975 PRINT(("id_length: %d\n", id_length())); 976 PRINT(("icb:\n")); 977 DUMP(icb()); 978 PRINT(("implementation_use_length: %d\n", is_parent())); 979 UdfString fileId(id()); 980 PRINT(("id: `%s'", fileId.Utf8())); 981 } 982 983 //---------------------------------------------------------------------- 984 // icb_entry_tag 985 //---------------------------------------------------------------------- 986 987 void 988 icb_entry_tag::dump() const 989 { 990 DUMP_INIT("icb_entry_tag"); 991 PRINT(("prior_entries: %ld\n", prior_recorded_number_of_direct_entries())); 992 PRINT(("strategy_type: %d\n", strategy_type())); 993 PRINT(("strategy_parameters:\n")); 994 DUMP(strategy_parameters()); 995 PRINT(("entry_count: %d\n", entry_count())); 996 PRINT(("file_type: %d\n", file_type())); 997 PRINT(("parent_icb_location:\n")); 998 DUMP(parent_icb_location()); 999 PRINT(("all_flags: %d\n", flags())); 1000 1001 /* 1002 uint32 prior_recorded_number_of_direct_entries; 1003 uint16 strategy_type; 1004 array<uint8, 2> strategy_parameters; 1005 uint16 entry_count; 1006 uint8 reserved; 1007 uint8 file_type; 1008 logical_block_address parent_icb_location; 1009 union { 1010 uint16 all_flags; 1011 struct { 1012 uint16 descriptor_flags:3, 1013 if_directory_then_sort:1, //!< To be set to 0 per UDF-2.01 2.3.5.4 1014 non_relocatable:1, 1015 archive:1, 1016 setuid:1, 1017 setgid:1, 1018 sticky:1, 1019 contiguous:1, 1020 system:1, 1021 transformed:1, 1022 multi_version:1, //!< To be set to 0 per UDF-2.01 2.3.5.4 1023 is_stream:1, 1024 reserved_icb_entry_flags:2; 1025 } flags; 1026 }; 1027 1028 */ 1029 1030 } 1031 1032 //---------------------------------------------------------------------- 1033 // icb_header 1034 //---------------------------------------------------------------------- 1035 1036 void 1037 icb_header::dump() const 1038 { 1039 DUMP_INIT("icb_header"); 1040 1041 PRINT(("tag:\n")); 1042 DUMP(tag()); 1043 PRINT(("icb_tag:\n")); 1044 DUMP(icb_tag()); 1045 1046 } 1047 1048 //---------------------------------------------------------------------- 1049 // file_icb_entry 1050 //---------------------------------------------------------------------- 1051 1052 long_address file_icb_entry::_dummy_stream_directory_icb; 1053 1054 void 1055 file_icb_entry::dump() const 1056 { 1057 DUMP_INIT("file_icb_entry"); 1058 1059 PRINT(("tag:\n")); 1060 DUMP(tag()); 1061 PRINT(("icb_tag:\n")); 1062 DUMP(icb_tag()); 1063 1064 PRINT(("uid: %lu, 0x%lx\n", uid(), uid())); 1065 PRINT(("gid: %lu, 0x%lx\n", gid(), gid())); 1066 PRINT(("permissions: %ld, 0x%lx\n", permissions(), permissions())); 1067 PRINT(("file_link_count: %d\n", file_link_count())); 1068 PRINT(("record_format: %d\n", record_format())); 1069 PRINT(("record_display_attributes: %d\n", record_display_attributes())); 1070 PRINT(("record_length: %d\n", record_length())); 1071 PRINT(("information_length: %Ld\n", information_length())); 1072 PRINT(("logical_blocks_recorded: %Ld\n", logical_blocks_recorded())); 1073 PRINT(("access_date_and_time:\n")); 1074 DUMP(access_date_and_time()); 1075 PRINT(("modification_date_and_time:\n")); 1076 DUMP(modification_date_and_time()); 1077 PRINT(("attribute_date_and_time:\n")); 1078 DUMP(attribute_date_and_time()); 1079 PRINT(("checkpoint: %ld\n", checkpoint())); 1080 1081 PRINT(("extended_attribute_icb:\n")); 1082 DUMP(extended_attribute_icb()); 1083 PRINT(("implementation_id:\n")); 1084 DUMP(implementation_id()); 1085 1086 PRINT(("unique_id: %Ld\n", unique_id())); 1087 PRINT(("extended_attributes_length: %ld\n", extended_attributes_length())); 1088 PRINT(("allocation_descriptors_length: %ld\n", allocation_descriptors_length())); 1089 1090 PRINT(("allocation_descriptors:\n")); 1091 switch (icb_tag().descriptor_flags()) { 1092 case ICB_DESCRIPTOR_TYPE_SHORT: 1093 PRINT((" short descriptors...\n")); 1094 break; 1095 case ICB_DESCRIPTOR_TYPE_LONG: 1096 { 1097 const long_address *address = reinterpret_cast<const long_address*>(allocation_descriptors()); 1098 for (uint32 length = allocation_descriptors_length(); 1099 length >= sizeof(long_address); 1100 length -= sizeof(long_address), address++) 1101 { 1102 PDUMP(address); 1103 } 1104 break; 1105 } 1106 case ICB_DESCRIPTOR_TYPE_EXTENDED: 1107 PRINT((" extended descriptors...\n")); 1108 break; 1109 case ICB_DESCRIPTOR_TYPE_EMBEDDED: 1110 PRINT((" embedded descriptors...\n")); 1111 break; 1112 default: 1113 PRINT((" invalid descriptors type\n")); 1114 break; 1115 } 1116 } 1117 1118 //---------------------------------------------------------------------- 1119 // extended_file_icb_entry 1120 //---------------------------------------------------------------------- 1121 1122 void 1123 extended_file_icb_entry::dump() const 1124 { 1125 DUMP_INIT("extended_file_icb_entry"); 1126 1127 PRINT(("tag:\n")); 1128 DUMP(tag()); 1129 PRINT(("icb_tag:\n")); 1130 DUMP(icb_tag()); 1131 1132 PRINT(("uid: %lu, 0x%lx\n", uid(), uid())); 1133 PRINT(("gid: %lu, 0x%lx\n", gid(), gid())); 1134 PRINT(("permissions: %ld, 0x%lx\n", permissions(), permissions())); 1135 PRINT(("file_link_count: %d\n", file_link_count())); 1136 PRINT(("record_format: %d\n", record_format())); 1137 PRINT(("record_display_attributes: %d\n", record_display_attributes())); 1138 PRINT(("record_length: %ld\n", record_length())); 1139 PRINT(("information_length: %Ld\n", information_length())); 1140 PRINT(("logical_blocks_recorded: %Ld\n", logical_blocks_recorded())); 1141 PRINT(("access_date_and_time:\n")); 1142 DUMP(access_date_and_time()); 1143 PRINT(("modification_date_and_time:\n")); 1144 DUMP(modification_date_and_time()); 1145 PRINT(("creation_date_and_time:\n")); 1146 DUMP(creation_date_and_time()); 1147 PRINT(("attribute_date_and_time:\n")); 1148 DUMP(attribute_date_and_time()); 1149 PRINT(("checkpoint: %ld\n", checkpoint())); 1150 1151 PRINT(("extended_attribute_icb:\n")); 1152 DUMP(extended_attribute_icb()); 1153 PRINT(("stream_directory_icb:\n")); 1154 DUMP(stream_directory_icb()); 1155 PRINT(("implementation_id:\n")); 1156 DUMP(implementation_id()); 1157 1158 PRINT(("unique_id: %Ld\n", unique_id())); 1159 PRINT(("extended_attributes_length: %ld\n", extended_attributes_length())); 1160 PRINT(("allocation_descriptors_length: %ld\n", allocation_descriptors_length())); 1161 1162 PRINT(("allocation_descriptors:\n")); 1163 switch (icb_tag().descriptor_flags()) { 1164 case ICB_DESCRIPTOR_TYPE_SHORT: 1165 PRINT((" short descriptors...\n")); 1166 break; 1167 case ICB_DESCRIPTOR_TYPE_LONG: 1168 { 1169 const long_address *address = reinterpret_cast<const long_address*>(allocation_descriptors()); 1170 for (uint32 length = allocation_descriptors_length(); 1171 length >= sizeof(long_address); 1172 length -= sizeof(long_address), address++) 1173 { 1174 PDUMP(address); 1175 } 1176 break; 1177 } 1178 case ICB_DESCRIPTOR_TYPE_EXTENDED: 1179 PRINT((" extended descriptors...\n")); 1180 break; 1181 case ICB_DESCRIPTOR_TYPE_EMBEDDED: 1182 PRINT((" embedded descriptors...\n")); 1183 break; 1184 default: 1185 PRINT((" invalid descriptors type\n")); 1186 break; 1187 } 1188 } 1189