xref: /haiku/src/add-ons/kernel/file_systems/udf/UdfStructures.cpp (revision aa94570a34695672df9b47adda2257f75d8da880)
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