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
25const 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
33const char* kVSDID_BEA 			= "BEA01";
34const char* kVSDID_TEA 			= "TEA01";
35const char* kVSDID_BOOT 		= "BOOT2";
36const char* kVSDID_ISO 			= "CD001";
37const char* kVSDID_ECMA167_2 	= "NSR02";
38const char* kVSDID_ECMA167_3 	= "NSR03";
39const char* kVSDID_ECMA168		= "CDW02";
40
41//! crc 010041 table, as generated by crc_table.cpp
42const 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
77const uint32 kLogicalVolumeDescriptorBaseSize = sizeof(logical_volume_descriptor)
78                                                     - (UDF_MAX_PARTITION_MAPS
79                                                        * UDF_MAX_PARTITION_MAP_SIZE);
80
81// entity_ids
82entity_id kMetadataPartitionMapId;
83entity_id kSparablePartitionMapId;
84entity_id kVirtualPartitionMapId;
85entity_id kImplementationId;
86entity_id kPartitionContentsId1xx;
87entity_id kPartitionContentsId2xx;
88entity_id kLogicalVolumeInfoId150;
89entity_id kLogicalVolumeInfoId201;
90entity_id kDomainId150;
91entity_id kDomainId201;
92
93
94//----------------------------------------------------------------------
95// Entities initialization
96//----------------------------------------------------------------------
97
98void
99init_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
120const 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
180volume_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*/
190bool
191volume_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
201charspec::charspec(uint8 type, const char *info)
202{
203	set_character_set_type(type);
204	set_character_set_info(info);
205}
206
207void
208charspec::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
215void
216charspec::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
228static
229int
230get_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
246timestamp::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
309void
310timestamp::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
326void
327timestamp::_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
346udf_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
359implementation_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
371domain_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
382entity_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
394entity_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
404entity_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
414entity_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
424void
425entity_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
434bool
435entity_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
451extent_address::extent_address(uint32 location, uint32 length)
452{
453	set_location(location);
454	set_length(length);
455}
456
457void
458extent_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
469void
470logical_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
477logical_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
487long_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
497void
498long_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
512void
513descriptor_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*/
545status_t
546descriptor_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
586void
587primary_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
636void
637anchor_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
652void
653logical_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
675void
676implementation_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
692void
693partition_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
719void
720logical_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
776logical_volume_descriptor&
777logical_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
808void
809physical_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
822void
823sparable_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
843void
844unallocated_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
860void
861terminating_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
872void
873file_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
914void
915logical_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
975void
976file_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
999void
1000icb_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
1049void
1050icb_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
1065long_address file_icb_entry::_dummy_stream_directory_icb;
1066
1067void
1068file_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
1142void
1143extended_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