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, "*Haiku 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: %" B_PRIu32 "\n", length())); 462 PRINT(("location: %" B_PRIu32 "\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: %" B_PRIu32 "\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: %" B_PRIu32 "\n", length())); 502 PRINT(("block: %" B_PRIu32 "\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: %" B_PRIu32 "\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: %" B_PRIu32 ", " 549 "calculateCrc: %s", 550 block, bool_to_string(calculateCrc))); 551 PRINT(("location (parameter) == %" B_PRIu32 "\n", block)); 552 PRINT(("location (in structure) == %" B_PRIu32 "\n", location())); 553 if (calculateCrc) { 554 PRINT(("crc (calculated) == %d\n", 555 calculate_crc(reinterpret_cast<uint8*>(this)+sizeof(descriptor_tag), 556 crc_length()))) 557 } else { 558 PRINT(("crc (calculated) == (not calculated)\n")); 559 } 560 PRINT(("crc (in structure) == %d\n", crc())); 561 PRINT(("crc_length (in structure) == %d\n", crc_length())); 562 // location 563 status_t error = (block == location()) ? B_OK : B_NO_INIT; 564 // checksum 565 if (!error) { 566 uint32 sum = 0; 567 for (int i = 0; i <= 3; i++) 568 sum += reinterpret_cast<uint8*>(this)[i]; 569 for (int i = 5; i <= 15; i++) 570 sum += reinterpret_cast<uint8*>(this)[i]; 571 error = sum % 256 == checksum() ? B_OK : B_NO_INIT; 572 } 573 // crc 574 if (!error && calculateCrc) { 575 uint16 _crc = calculate_crc(reinterpret_cast<uint8*>(this) 576 + sizeof(descriptor_tag), crc_length()); 577 error = _crc == crc() ? B_OK : B_NO_INIT; 578 } 579 RETURN(error); 580 } 581 582 //---------------------------------------------------------------------- 583 // primary_volume_descriptor 584 //---------------------------------------------------------------------- 585 586 void 587 primary_volume_descriptor::dump() const 588 { 589 DUMP_INIT("primary_volume_descriptor"); 590 591 UdfString string; 592 593 PRINT(("tag:\n")); 594 DUMP(tag()); 595 PRINT(("vds_number: %" B_PRIu32 "\n", vds_number())); 596 PRINT(("primary_volume_descriptor_number: %" B_PRIu32 "\n", 597 primary_volume_descriptor_number())); 598 string = volume_identifier(); 599 PRINT(("volume_identifier: `%s'\n", string.Utf8())); 600 PRINT(("volume_sequence_number: %d\n", volume_sequence_number())); 601 PRINT(("max_volume_sequence_number: %d\n", max_volume_sequence_number())); 602 PRINT(("interchange_level: %d\n", interchange_level())); 603 PRINT(("max_interchange_level: %d\n", max_interchange_level())); 604 PRINT(("character_set_list: %" B_PRIu32 "\n", 605 character_set_list())); 606 PRINT(("max_character_set_list: %" B_PRIu32 "\n", 607 max_character_set_list())); 608 string = volume_set_identifier(); 609 PRINT(("volume_set_identifier: `%s'\n", string.Utf8())); 610 PRINT(("descriptor_character_set:\n")); 611 DUMP(descriptor_character_set()); 612 PRINT(("explanatory_character_set:\n")); 613 DUMP(explanatory_character_set()); 614 PRINT(("volume_abstract:\n")); 615 DUMP(volume_abstract()); 616 PRINT(("volume_copyright_notice:\n")); 617 DUMP(volume_copyright_notice()); 618 PRINT(("application_id:\n")); 619 DUMP(application_id()); 620 PRINT(("recording_date_and_time:\n")); 621 DUMP(recording_date_and_time()); 622 PRINT(("implementation_id:\n")); 623 DUMP(implementation_id()); 624 PRINT(("implementation_use:\n")); 625 DUMP(implementation_use()); 626 PRINT(("predecessor_vds_location: %" B_PRIu32 "\n", 627 predecessor_volume_descriptor_sequence_location())); 628 PRINT(("flags: %d\n", flags())); 629 } 630 631 632 //---------------------------------------------------------------------- 633 // anchor_volume_descriptor_pointer 634 //---------------------------------------------------------------------- 635 636 void 637 anchor_volume_descriptor::dump() const 638 { 639 DUMP_INIT("anchor_volume_descriptor"); 640 PRINT(("tag:\n")); 641 DUMP(tag()); 642 PRINT(("main_vds:\n")); 643 DUMP(main_vds()); 644 PRINT(("reserve_vds:\n")); 645 DUMP(reserve_vds()); 646 } 647 648 //---------------------------------------------------------------------- 649 // logical_volume_info 650 //---------------------------------------------------------------------- 651 652 void 653 logical_volume_info::dump() const 654 { 655 UdfString string; 656 DUMP_INIT("logical_volume_information"); 657 PRINT(("character_set:\n")); 658 DUMP(character_set()); 659 string = logical_volume_id(); 660 PRINT(("logical_volume_id: `%s'\n", string.Utf8())); 661 for (uint32 i = 0; i < _logical_volume_info.length(); i++) { 662 string = _logical_volume_info[i]; 663 PRINT(("logical_volume_info #%" B_PRIu32 ": %s\n", i, string.Utf8())); 664 } 665 PRINT(("implementation_id:\n")); 666 DUMP(implementation_id()); 667 PRINT(("implementation_use:\n")); 668 DUMP(implementation_use()); 669 } 670 671 //---------------------------------------------------------------------- 672 // implementation_use_descriptor 673 //---------------------------------------------------------------------- 674 675 void 676 implementation_use_descriptor::dump() const 677 { 678 DUMP_INIT("implementation_use_descriptor"); 679 PRINT(("tag:\n")); 680 DUMP(tag()); 681 PRINT(("vds_number: %" B_PRIu32 "\n", vds_number())); 682 PRINT(("implementation_id:\n")); 683 DUMP(implementation_id()); 684 PRINT(("implementation_use: XXX\n")); 685 DUMP(implementation_use()); 686 } 687 688 //---------------------------------------------------------------------- 689 // partition_descriptor 690 //---------------------------------------------------------------------- 691 692 void 693 partition_descriptor::dump() const 694 { 695 DUMP_INIT("partition_descriptor"); 696 PRINT(("tag:\n")); 697 DUMP(tag()); 698 PRINT(("vds_number: %" B_PRIu32 "\n", vds_number())); 699 PRINT(("partition_flags: %d\n", partition_flags())); 700 PRINT(("partition_flags.allocated: %s\n", allocated() ? "true" : "false")); 701 PRINT(("partition_number: %d\n", partition_number())); 702 PRINT(("partition_contents:\n")); 703 DUMP(partition_contents()); 704 PRINT(("partition_contents_use: XXX\n")); 705 DUMP(partition_contents_use()); 706 PRINT(("access_type: %" B_PRIu32 "\n", access_type())); 707 PRINT(("start: %" B_PRIu32 "\n", start())); 708 PRINT(("length: %" B_PRIu32 "\n", length())); 709 PRINT(("implementation_id:\n")); 710 DUMP(implementation_id()); 711 PRINT(("implementation_use: XXX\n")); 712 DUMP(implementation_use()); 713 } 714 715 //---------------------------------------------------------------------- 716 // logical_volume_descriptor 717 //---------------------------------------------------------------------- 718 719 void 720 logical_volume_descriptor::dump() const 721 { 722 DUMP_INIT("logical_volume_descriptor"); 723 PRINT(("tag:\n")); 724 DUMP(tag()); 725 PRINT(("vds_number: %" B_PRIu32 "\n", vds_number())); 726 PRINT(("character_set:\n")); 727 DUMP(character_set()); 728 UdfString string(logical_volume_identifier()); 729 PRINT(("logical_volume_identifier: `%s'\n", string.Utf8())); 730 PRINT(("logical_block_size: %" B_PRIu32 "\n", 731 logical_block_size())); 732 PRINT(("domain_id:\n")); 733 DUMP(domain_id()); 734 PRINT(("logical_volume_contents_use:\n")); 735 DUMP(logical_volume_contents_use()); 736 PRINT(("file_set_address:\n")); 737 DUMP(file_set_address()); 738 PRINT(("map_table_length: %" B_PRIu32 "\n", map_table_length())); 739 PRINT(("partition_map_count: %" B_PRIu32 "\n", 740 partition_map_count())); 741 PRINT(("implementation_id:\n")); 742 DUMP(implementation_id()); 743 PRINT(("implementation_use:\n")); 744 DUMP(implementation_use()); 745 PRINT(("integrity_sequence_extent:\n")); 746 DUMP(integrity_sequence_extent()); 747 // PRINT(("partition_maps:\n")); 748 const uint8 *maps = partition_maps(); 749 int offset = 0; 750 for (uint i = 0; i < partition_map_count(); i++) { 751 PRINT(("partition_map #%d:\n", i)); 752 uint8 type = maps[offset]; 753 uint8 length = maps[offset+1]; 754 PRINT((" type: %d\n", type)); 755 PRINT((" length: %d\n", length)); 756 switch (type) { 757 case 1: 758 for (int j = 0; j < length-2; j++) 759 PRINT((" data[%d]: %d\n", j, maps[offset+2+j])); 760 break; 761 case 2: { 762 PRINT((" partition_number: %d\n", *reinterpret_cast<const uint16*>(&(maps[offset+38])))); 763 PRINT((" entity_id:\n")); 764 const entity_id *id = reinterpret_cast<const entity_id*>(&(maps[offset+4])); 765 if (id) // To kill warning when DEBUG==0 766 PDUMP(id); 767 break; 768 } 769 } 770 offset += maps[offset+1]; 771 } 772 // \todo dump partition_maps 773 } 774 775 776 logical_volume_descriptor& 777 logical_volume_descriptor::operator=(const logical_volume_descriptor &rhs) 778 { 779 _tag = rhs._tag; 780 _vds_number = rhs._vds_number; 781 _character_set = rhs._character_set; 782 _logical_volume_identifier = rhs._logical_volume_identifier; 783 _logical_block_size = rhs._logical_block_size; 784 _domain_id = rhs._domain_id; 785 _logical_volume_contents_use = rhs._logical_volume_contents_use; 786 _map_table_length = rhs._map_table_length; 787 _partition_map_count = rhs._partition_map_count; 788 _implementation_id = rhs._implementation_id; 789 _implementation_use = rhs._implementation_use; 790 _integrity_sequence_extent = rhs._integrity_sequence_extent; 791 // copy the partition maps one by one 792 uint8 *lhsMaps = partition_maps(); 793 const uint8 *rhsMaps = rhs.partition_maps(); 794 int offset = 0; 795 for (uint8 i = 0; i < rhs.partition_map_count(); i++) { 796 uint8 length = rhsMaps[offset+1]; 797 memcpy(&lhsMaps[offset], &rhsMaps[offset], length); 798 offset += length; 799 } 800 return *this; 801 } 802 803 804 //---------------------------------------------------------------------- 805 // physical_partition_map 806 //---------------------------------------------------------------------- 807 808 void 809 physical_partition_map::dump() 810 { 811 DUMP_INIT("physical_partition_map"); 812 PRINT(("type: %d\n", type())); 813 PRINT(("length: %d\n", length())); 814 PRINT(("volume_sequence_number: %d\n", volume_sequence_number())); 815 PRINT(("partition_number: %d\n", partition_number())); 816 } 817 818 //---------------------------------------------------------------------- 819 // sparable_partition_map 820 //---------------------------------------------------------------------- 821 822 void 823 sparable_partition_map::dump() 824 { 825 DUMP_INIT("sparable_partition_map"); 826 PRINT(("type: %d\n", type())); 827 PRINT(("length: %d\n", length())); 828 PRINT(("partition_type_id:")); 829 DUMP(partition_type_id()); 830 PRINT(("volume_sequence_number: %d\n", volume_sequence_number())); 831 PRINT(("partition_number: %d\n", partition_number())); 832 PRINT(("sparing_table_count: %d\n", sparing_table_count())); 833 PRINT(("sparing_table_size: %" B_PRIu32 "\n", sparing_table_size())); 834 PRINT(("sparing_table_locations:")); 835 for (uint8 i = 0; i < sparing_table_count(); i++) 836 PRINT((" %d: %" B_PRIu32 "\n", i, sparing_table_location(i))); 837 } 838 839 //---------------------------------------------------------------------- 840 // unallocated_space_descriptor 841 //---------------------------------------------------------------------- 842 843 void 844 unallocated_space_descriptor::dump() const 845 { 846 DUMP_INIT("unallocated_space_descriptor"); 847 PRINT(("tag:\n")); 848 DUMP(tag()); 849 PRINT(("vds_number: %" B_PRIu32 "\n", vds_number())); 850 PRINT(("allocation_descriptor_count: %" B_PRIu32 "\n", 851 allocation_descriptor_count())); 852 // \todo dump alloc_descriptors 853 } 854 855 856 //---------------------------------------------------------------------- 857 // terminating_descriptor 858 //---------------------------------------------------------------------- 859 860 void 861 terminating_descriptor::dump() const 862 { 863 DUMP_INIT("terminating_descriptor"); 864 PRINT(("tag:\n")); 865 DUMP(tag()); 866 } 867 868 //---------------------------------------------------------------------- 869 // file_set_descriptor 870 //---------------------------------------------------------------------- 871 872 void 873 file_set_descriptor::dump() const 874 { 875 DUMP_INIT("file_set_descriptor"); 876 PRINT(("tag:\n")); 877 DUMP(tag()); 878 PRINT(("recording_date_and_time:\n")); 879 DUMP(recording_date_and_time()); 880 PRINT(("interchange_level: %d\n", interchange_level())); 881 PRINT(("max_interchange_level: %d\n", max_interchange_level())); 882 PRINT(("character_set_list: %" B_PRIu32 "\n", character_set_list())); 883 PRINT(("max_character_set_list: %" B_PRIu32 "\n", 884 max_character_set_list())); 885 PRINT(("file_set_number: %" B_PRIu32 "\n", file_set_number())); 886 PRINT(("file_set_descriptor_number: %" B_PRIu32 "\n", 887 file_set_descriptor_number())); 888 PRINT(("logical_volume_id_character_set:\n")); 889 DUMP(logical_volume_id_character_set()); 890 PRINT(("logical_volume_id:\n")); 891 DUMP(logical_volume_id()); 892 PRINT(("file_set_id_character_set:\n")); 893 DUMP(file_set_id_character_set()); 894 PRINT(("file_set_id:\n")); 895 DUMP(file_set_id()); 896 PRINT(("copyright_file_id:\n")); 897 DUMP(copyright_file_id()); 898 PRINT(("abstract_file_id:\n")); 899 DUMP(abstract_file_id()); 900 PRINT(("root_directory_icb:\n")); 901 DUMP(root_directory_icb()); 902 PRINT(("domain_id:\n")); 903 DUMP(domain_id()); 904 PRINT(("next_extent:\n")); 905 DUMP(next_extent()); 906 PRINT(("system_stream_directory_icb:\n")); 907 DUMP(system_stream_directory_icb()); 908 } 909 910 //---------------------------------------------------------------------- 911 // logical_volume_integrity_descriptor 912 //---------------------------------------------------------------------- 913 914 void 915 logical_volume_integrity_descriptor::dump() const 916 { 917 DUMP_INIT("logical_volume_integrity_descriptor"); 918 PRINT(("tag:\n")); 919 DUMP(tag()); 920 PRINT(("recording_time:\n")); 921 DUMP(recording_time()); 922 PRINT(("integrity_type: ")); 923 switch (integrity_type()) { 924 case INTEGRITY_OPEN: 925 SIMPLE_PRINT(("open\n")); 926 break; 927 case INTEGRITY_CLOSED: 928 SIMPLE_PRINT(("closed\n")); 929 break; 930 default: 931 SIMPLE_PRINT(("invalid integrity type (%" B_PRIu32 ")", 932 integrity_type())); 933 break; 934 } 935 PRINT(("next_integrity_extent:\n")); 936 DUMP(next_integrity_extent()); 937 PRINT(("logical_volume_contents_use:\n")); 938 DUMP(logical_volume_contents_use()); 939 PRINT(("next_unique_id: %" B_PRIu64 "\n", next_unique_id())); 940 PRINT(("partition_count: %" B_PRIu32 "\n", partition_count())); 941 PRINT(("implementation_use_length: %" B_PRIu32 "\n", 942 implementation_use_length())); 943 if (partition_count() > 0) { 944 PRINT(("free_space_table:\n")); 945 for (uint32 i = 0; i < partition_count(); i++) { 946 PRINT(("partition %" B_PRIu32 ": %" B_PRIu32 " free blocks\n", 947 i, free_space_table()[i])); 948 } 949 PRINT(("size_table:\n")); 950 for (uint32 i = 0; i < partition_count(); i++) { 951 PRINT(("partition %" B_PRIu32 ": %" B_PRIu32 " blocks large\n", 952 i, size_table()[i])); 953 } 954 } 955 956 if (implementation_use_length() >= minimum_implementation_use_length) { 957 PRINT(("implementation_id:\n")); 958 DUMP(implementation_id()); 959 PRINT(("file_count: %" B_PRIu32 "\n", file_count())); 960 PRINT(("directory_count: %" B_PRIu32 "\n", 961 directory_count())); 962 PRINT(("minimum_udf_read_revision: 0x%04x\n", minimum_udf_read_revision())); 963 PRINT(("minimum_udf_write_revision: 0x%04x\n", minimum_udf_write_revision())); 964 PRINT(("maximum_udf_write_revision: 0x%04x\n", maximum_udf_write_revision())); 965 } else { 966 PRINT(("NOTE: implementation_use() field of insufficient length to contain \n")); 967 PRINT((" appropriate UDF-2.50 2.2.6.4 fields.\n")); 968 } 969 } 970 971 //---------------------------------------------------------------------- 972 // file_id_descriptor 973 //---------------------------------------------------------------------- 974 975 void 976 file_id_descriptor::dump() const 977 { 978 DUMP_INIT("file_id_descriptor"); 979 PRINT(("tag:\n")); 980 DUMP(tag()); 981 PRINT(("version_number: %d\n", version_number())); 982 PRINT(("may_be_hidden: %d\n", may_be_hidden())); 983 PRINT(("is_directory: %d\n", is_directory())); 984 PRINT(("is_deleted: %d\n", is_deleted())); 985 PRINT(("is_parent: %d\n", is_parent())); 986 PRINT(("is_metadata_stream: %d\n", is_metadata_stream())); 987 PRINT(("id_length: %d\n", id_length())); 988 PRINT(("icb:\n")); 989 DUMP(icb()); 990 PRINT(("implementation_use_length: %d\n", is_parent())); 991 UdfString fileId(id()); 992 PRINT(("id: `%s'", fileId.Utf8())); 993 } 994 995 //---------------------------------------------------------------------- 996 // icb_entry_tag 997 //---------------------------------------------------------------------- 998 999 void 1000 icb_entry_tag::dump() const 1001 { 1002 DUMP_INIT("icb_entry_tag"); 1003 PRINT(("prior_entries: %" B_PRIu32 "\n", 1004 prior_recorded_number_of_direct_entries())); 1005 PRINT(("strategy_type: %d\n", strategy_type())); 1006 PRINT(("strategy_parameters:\n")); 1007 DUMP(strategy_parameters()); 1008 PRINT(("entry_count: %d\n", entry_count())); 1009 PRINT(("file_type: %d\n", file_type())); 1010 PRINT(("parent_icb_location:\n")); 1011 DUMP(parent_icb_location()); 1012 PRINT(("all_flags: %d\n", flags())); 1013 1014 /* 1015 uint32 prior_recorded_number_of_direct_entries; 1016 uint16 strategy_type; 1017 array<uint8, 2> strategy_parameters; 1018 uint16 entry_count; 1019 uint8 reserved; 1020 uint8 file_type; 1021 logical_block_address parent_icb_location; 1022 union { 1023 uint16 all_flags; 1024 struct { 1025 uint16 descriptor_flags:3, 1026 if_directory_then_sort:1, //!< To be set to 0 per UDF-2.01 2.3.5.4 1027 non_relocatable:1, 1028 archive:1, 1029 setuid:1, 1030 setgid:1, 1031 sticky:1, 1032 contiguous:1, 1033 system:1, 1034 transformed:1, 1035 multi_version:1, //!< To be set to 0 per UDF-2.01 2.3.5.4 1036 is_stream:1, 1037 reserved_icb_entry_flags:2; 1038 } flags; 1039 }; 1040 1041 */ 1042 1043 } 1044 1045 //---------------------------------------------------------------------- 1046 // icb_header 1047 //---------------------------------------------------------------------- 1048 1049 void 1050 icb_header::dump() const 1051 { 1052 DUMP_INIT("icb_header"); 1053 1054 PRINT(("tag:\n")); 1055 DUMP(tag()); 1056 PRINT(("icb_tag:\n")); 1057 DUMP(icb_tag()); 1058 1059 } 1060 1061 //---------------------------------------------------------------------- 1062 // file_icb_entry 1063 //---------------------------------------------------------------------- 1064 1065 long_address file_icb_entry::_dummy_stream_directory_icb; 1066 1067 void 1068 file_icb_entry::dump() const 1069 { 1070 DUMP_INIT("file_icb_entry"); 1071 1072 PRINT(("tag:\n")); 1073 DUMP(tag()); 1074 PRINT(("icb_tag:\n")); 1075 DUMP(icb_tag()); 1076 1077 PRINT(("uid: %" B_PRIu32 ", 0x%" B_PRIx32 "\n", 1078 uid(), uid())); 1079 PRINT(("gid: %" B_PRIu32 ", 0x%" B_PRIx32 "\n", 1080 gid(), gid())); 1081 PRINT(("permissions: %" B_PRIu32 ", 0x%" B_PRIx32 "\n", 1082 permissions(), permissions())); 1083 PRINT(("file_link_count: %d\n", file_link_count())); 1084 PRINT(("record_format: %d\n", record_format())); 1085 PRINT(("record_display_attributes: %d\n", record_display_attributes())); 1086 PRINT(("record_length: %d\n", record_length())); 1087 PRINT(("information_length: %" B_PRIu64 "\n", 1088 information_length())); 1089 PRINT(("logical_blocks_recorded: %" B_PRIu64 "\n", 1090 logical_blocks_recorded())); 1091 PRINT(("access_date_and_time:\n")); 1092 DUMP(access_date_and_time()); 1093 PRINT(("modification_date_and_time:\n")); 1094 DUMP(modification_date_and_time()); 1095 PRINT(("attribute_date_and_time:\n")); 1096 DUMP(attribute_date_and_time()); 1097 PRINT(("checkpoint: %" B_PRIu32 "\n", checkpoint())); 1098 1099 PRINT(("extended_attribute_icb:\n")); 1100 DUMP(extended_attribute_icb()); 1101 PRINT(("implementation_id:\n")); 1102 DUMP(implementation_id()); 1103 1104 PRINT(("unique_id: %" B_PRIu64 "\n", unique_id())); 1105 PRINT(("extended_attributes_length: %" B_PRIu32 "\n", 1106 extended_attributes_length())); 1107 PRINT(("allocation_descriptors_length: %" B_PRIu32 "\n", 1108 allocation_descriptors_length())); 1109 1110 PRINT(("allocation_descriptors:\n")); 1111 switch (icb_tag().descriptor_flags()) { 1112 case ICB_DESCRIPTOR_TYPE_SHORT: 1113 PRINT((" short descriptors...\n")); 1114 break; 1115 case ICB_DESCRIPTOR_TYPE_LONG: 1116 { 1117 const long_address *address = reinterpret_cast<const long_address*>(allocation_descriptors()); 1118 for (uint32 length = allocation_descriptors_length(); 1119 length >= sizeof(long_address); 1120 length -= sizeof(long_address), address++) 1121 { 1122 PDUMP(address); 1123 } 1124 break; 1125 } 1126 case ICB_DESCRIPTOR_TYPE_EXTENDED: 1127 PRINT((" extended descriptors...\n")); 1128 break; 1129 case ICB_DESCRIPTOR_TYPE_EMBEDDED: 1130 PRINT((" embedded descriptors...\n")); 1131 break; 1132 default: 1133 PRINT((" invalid descriptors type\n")); 1134 break; 1135 } 1136 } 1137 1138 //---------------------------------------------------------------------- 1139 // extended_file_icb_entry 1140 //---------------------------------------------------------------------- 1141 1142 void 1143 extended_file_icb_entry::dump() const 1144 { 1145 DUMP_INIT("extended_file_icb_entry"); 1146 1147 PRINT(("tag:\n")); 1148 DUMP(tag()); 1149 PRINT(("icb_tag:\n")); 1150 DUMP(icb_tag()); 1151 1152 PRINT(("uid: %" B_PRIu32 ", 0x%" B_PRIx32 "\n", 1153 uid(), uid())); 1154 PRINT(("gid: %" B_PRIu32 ", 0x%" B_PRIx32 "\n", 1155 gid(), gid())); 1156 PRINT(("permissions: %" B_PRIu32 ", 0x%" B_PRIx32 "\n", 1157 permissions(), permissions())); 1158 PRINT(("file_link_count: %d\n", file_link_count())); 1159 PRINT(("record_format: %d\n", record_format())); 1160 PRINT(("record_display_attributes: %d\n", record_display_attributes())); 1161 PRINT(("record_length: %" B_PRIu32 "\n", record_length())); 1162 PRINT(("information_length: %" B_PRIu64 "\n", 1163 information_length())); 1164 PRINT(("logical_blocks_recorded: %" B_PRIu64 "\n", 1165 logical_blocks_recorded())); 1166 PRINT(("access_date_and_time:\n")); 1167 DUMP(access_date_and_time()); 1168 PRINT(("modification_date_and_time:\n")); 1169 DUMP(modification_date_and_time()); 1170 PRINT(("creation_date_and_time:\n")); 1171 DUMP(creation_date_and_time()); 1172 PRINT(("attribute_date_and_time:\n")); 1173 DUMP(attribute_date_and_time()); 1174 PRINT(("checkpoint: %" B_PRIu32 "\n", checkpoint())); 1175 1176 PRINT(("extended_attribute_icb:\n")); 1177 DUMP(extended_attribute_icb()); 1178 PRINT(("stream_directory_icb:\n")); 1179 DUMP(stream_directory_icb()); 1180 PRINT(("implementation_id:\n")); 1181 DUMP(implementation_id()); 1182 1183 PRINT(("unique_id: %" B_PRIu64 "\n", unique_id())); 1184 PRINT(("extended_attributes_length: %" B_PRIu32 "\n", 1185 extended_attributes_length())); 1186 PRINT(("allocation_descriptors_length: %" B_PRIu32 "\n", 1187 allocation_descriptors_length())); 1188 1189 PRINT(("allocation_descriptors:\n")); 1190 switch (icb_tag().descriptor_flags()) { 1191 case ICB_DESCRIPTOR_TYPE_SHORT: 1192 PRINT((" short descriptors...\n")); 1193 break; 1194 case ICB_DESCRIPTOR_TYPE_LONG: 1195 { 1196 const long_address *address = reinterpret_cast<const long_address*>(allocation_descriptors()); 1197 for (uint32 length = allocation_descriptors_length(); 1198 length >= sizeof(long_address); 1199 length -= sizeof(long_address), address++) 1200 { 1201 PDUMP(address); 1202 } 1203 break; 1204 } 1205 case ICB_DESCRIPTOR_TYPE_EXTENDED: 1206 PRINT((" extended descriptors...\n")); 1207 break; 1208 case ICB_DESCRIPTOR_TYPE_EMBEDDED: 1209 PRINT((" embedded descriptors...\n")); 1210 break; 1211 default: 1212 PRINT((" invalid descriptors type\n")); 1213 break; 1214 } 1215 } 1216