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