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