git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3828 a95241bf-73f2-0310-859d-f6bbb57e9c96
441 lines
14 KiB
C++
441 lines
14 KiB
C++
//----------------------------------------------------------------------
|
|
// This software is part of the OpenBeOS distribution and is covered
|
|
// by the OpenBeOS license.
|
|
//
|
|
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
|
//----------------------------------------------------------------------
|
|
|
|
/*! \file DiskStructures.cpp
|
|
|
|
UDF on-disk data structure definitions
|
|
*/
|
|
|
|
#include "DiskStructures.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include "CS0String.h"
|
|
|
|
using namespace Udf;
|
|
|
|
//----------------------------------------------------------------------
|
|
// Constants
|
|
//----------------------------------------------------------------------
|
|
|
|
//const charspec kCS0Charspec = { _character_set_type: 0,
|
|
// _character_set_info: "OSTA Compressed Unicode"
|
|
// "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
|
// "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
|
// };
|
|
|
|
// Volume structure descriptor ids
|
|
const char* Udf::kVSDID_BEA = "BEA01";
|
|
const char* Udf::kVSDID_TEA = "TEA01";
|
|
const char* Udf::kVSDID_BOOT = "BOOT2";
|
|
const char* Udf::kVSDID_ISO = "CD001";
|
|
const char* Udf::kVSDID_ECMA167_2 = "NSR02";
|
|
const char* Udf::kVSDID_ECMA167_3 = "NSR03";
|
|
const char* Udf::kVSDID_ECMA168 = "CDW02";
|
|
|
|
//----------------------------------------------------------------------
|
|
// udf_volume_structure_descriptor_header
|
|
//----------------------------------------------------------------------
|
|
|
|
/*! \brief Returns true if the given \a id matches the header's id.
|
|
*/
|
|
bool
|
|
udf_volume_structure_descriptor_header::id_matches(const char *id)
|
|
{
|
|
return strncmp(this->id, id, 5) == 0;
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
// udf_charspec
|
|
//----------------------------------------------------------------------
|
|
|
|
void
|
|
udf_charspec::dump()
|
|
{
|
|
DUMP_INIT(CF_PUBLIC | CF_DUMP, "udf_charspec");
|
|
PRINT(("character_set_type: %d\n", character_set_type()));
|
|
PRINT(("character_set_info: `%s'\n", character_set_info()));
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
// udf_timestamp
|
|
//----------------------------------------------------------------------
|
|
|
|
void
|
|
udf_timestamp::dump()
|
|
{
|
|
DUMP_INIT(CF_PUBLIC | CF_DUMP, "udf_timestamp");
|
|
PRINT(("type: %d\n", type()));
|
|
PRINT(("timezone: %d\n", timezone()));
|
|
PRINT(("year: %d\n", year()));
|
|
PRINT(("month: %d\n", month()));
|
|
PRINT(("day: %d\n", day()));
|
|
PRINT(("hour: %d\n", hour()));
|
|
PRINT(("minute: %d\n", minute()));
|
|
PRINT(("second: %d\n", second()));
|
|
PRINT(("centisecond: %d\n", centisecond()));
|
|
PRINT(("hundred_microsecond: %d\n", hundred_microsecond()));
|
|
PRINT(("microsecond: %d\n", microsecond()));
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// udf_entity_id
|
|
//----------------------------------------------------------------------
|
|
|
|
void
|
|
udf_entity_id::dump()
|
|
{
|
|
DUMP_INIT(CF_PUBLIC | CF_DUMP, "udf_entity_id");
|
|
PRINT(("flags: %d\n", flags()));
|
|
PRINT(("identifier: `%s'\n", identifier()));
|
|
PRINT(("identifier_suffix: `%s'\n", identifier_suffix()));
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
// udf_extent_address
|
|
//----------------------------------------------------------------------
|
|
|
|
void
|
|
udf_extent_address::dump()
|
|
{
|
|
DUMP_INIT(CF_PUBLIC | CF_DUMP, "udf_extent_address");
|
|
PRINT(("length: %ld\n", length()));
|
|
PRINT(("location: %ld\n", location()));
|
|
}
|
|
|
|
void
|
|
udf_logical_block_address::dump()
|
|
{
|
|
DUMP_INIT(CF_PUBLIC | CF_DUMP, "udf_logical_block_address");
|
|
PRINT(("block: %ld\n", block()));
|
|
PRINT(("partition: %d\n", partition()));
|
|
}
|
|
|
|
void
|
|
udf_long_address::dump()
|
|
{
|
|
DUMP_INIT(CF_PUBLIC | CF_DUMP, "udf_long_address");
|
|
PRINT(("length: %ld\n", length()));
|
|
PRINT(("block: %ld\n", block()));
|
|
PRINT(("partiton: %d\n", partition()));
|
|
PRINT(("implementation_use:\n"));
|
|
DUMP(implementation_use());
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// udf_tag
|
|
//----------------------------------------------------------------------
|
|
|
|
void
|
|
udf_tag::dump()
|
|
{
|
|
DUMP_INIT(CF_PUBLIC | CF_VOLUME_OPS | CF_DUMP, "udf_descriptor_tag");
|
|
PRINT(("id: %d\n", id()));
|
|
PRINT(("version: %d\n", version()));
|
|
PRINT(("checksum: %d\n", checksum()));
|
|
PRINT(("serial_number: %d\n", serial_number()));
|
|
PRINT(("crc: %d\n", crc()));
|
|
PRINT(("crc_length: %d\n", crc_length()));
|
|
PRINT(("location: %ld\n", location()));
|
|
}
|
|
|
|
|
|
/*! \brief Calculates the tag's CRC, verifies the tag's checksum, and
|
|
verifies the tag's location on the medium.
|
|
|
|
\todo Calc the CRC.
|
|
*/
|
|
status_t
|
|
udf_tag::init_check(uint32 diskBlock)
|
|
{
|
|
DEBUG_INIT(CF_PUBLIC | CF_VOLUME_OPS | CF_HIGH_VOLUME, "udf_descriptor_tag");
|
|
PRINT(("diskLocation == %ld\n", diskBlock));
|
|
PRINT(("location() == %ld\n", location()));
|
|
status_t err = (diskBlock == location()) ? B_OK : B_NO_INIT;
|
|
// checksum
|
|
if (!err) {
|
|
uint32 sum = 0;
|
|
for (int i = 0; i <= 3; i++)
|
|
sum += ((uint8*)this)[i];
|
|
for (int i = 5; i <= 15; i++)
|
|
sum += ((uint8*)this)[i];
|
|
err = sum % 256 == checksum() ? B_OK : B_NO_INIT;
|
|
}
|
|
|
|
RETURN(err);
|
|
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
// udf_primary_descriptor
|
|
//----------------------------------------------------------------------
|
|
|
|
void
|
|
udf_primary_descriptor::dump()
|
|
{
|
|
DUMP_INIT(CF_PUBLIC | CF_VOLUME_OPS | CF_DUMP, "udf_primary_descriptor");
|
|
|
|
CS0String string;
|
|
|
|
PRINT(("tag:\n"));
|
|
DUMP(tag());
|
|
PRINT(("vds_number: %ld\n", vds_number()));
|
|
PRINT(("primary_volume_descriptor_number: %ld\n", primary_volume_descriptor_number()));
|
|
string = volume_identifier();
|
|
PRINT(("volume_identifier: `%s'\n", string.String()));
|
|
PRINT(("volume_sequence_number: %d\n", volume_sequence_number()));
|
|
PRINT(("max_volume_sequence_number: %d\n", max_volume_sequence_number()));
|
|
PRINT(("interchange_level: %d\n", interchange_level()));
|
|
PRINT(("max_interchange_level: %d\n", max_interchange_level()));
|
|
PRINT(("character_set_list: %ld\n", character_set_list()));
|
|
PRINT(("max_character_set_list: %ld\n", max_character_set_list()));
|
|
string = volume_set_identifier();
|
|
PRINT(("volume_set_identifier: `%s'\n", string.String()));
|
|
PRINT(("descriptor_character_set:\n"));
|
|
DUMP(descriptor_character_set());
|
|
PRINT(("explanatory_character_set:\n"));
|
|
DUMP(explanatory_character_set());
|
|
PRINT(("volume_abstract:\n"));
|
|
DUMP(volume_abstract());
|
|
PRINT(("volume_copyright_notice:\n"));
|
|
DUMP(volume_copyright_notice());
|
|
PRINT(("application_id:\n"));
|
|
DUMP(application_id());
|
|
PRINT(("recording_date_and_time:\n"));
|
|
DUMP(recording_date_and_time());
|
|
PRINT(("implementation_id:\n"));
|
|
DUMP(implementation_id());
|
|
PRINT(("implementation_use:\n"));
|
|
DUMP(implementation_use());
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
// udf_anchor_volume_descriptor_pointer
|
|
//----------------------------------------------------------------------
|
|
|
|
void
|
|
udf_anchor_descriptor::dump()
|
|
{
|
|
DUMP_INIT(CF_PUBLIC | CF_VOLUME_OPS | CF_DUMP, "udf_anchor_descriptor");
|
|
PRINT(("tag:\n"));
|
|
DUMP(tag());
|
|
PRINT(("main_vds:\n"));
|
|
DUMP(main_vds());
|
|
PRINT(("reserve_vds:\n"));
|
|
DUMP(reserve_vds());
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
// udf_implementation_use_descriptor
|
|
//----------------------------------------------------------------------
|
|
|
|
void
|
|
udf_implementation_use_descriptor::dump()
|
|
{
|
|
DUMP_INIT(CF_PUBLIC | CF_VOLUME_OPS | CF_DUMP, "udf_implementation_use_descriptor");
|
|
PRINT(("tag:\n"));
|
|
DUMP(tag());
|
|
PRINT(("vds_number: %ld\n", vds_number()));
|
|
PRINT(("implementation_id:\n"));
|
|
DUMP(implementation_id());
|
|
PRINT(("implementation_use: XXX\n"));
|
|
DUMP(implementation_use());
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
// udf_partition_descriptor
|
|
//----------------------------------------------------------------------
|
|
|
|
void
|
|
udf_partition_descriptor::dump()
|
|
{
|
|
DUMP_INIT(CF_PUBLIC | CF_VOLUME_OPS | CF_DUMP, "udf_partition_descriptor");
|
|
PRINT(("tag:\n"));
|
|
DUMP(tag());
|
|
PRINT(("vds_number: %ld\n", vds_number()));
|
|
PRINT(("partition_flags: %d\n", partition_flags()));
|
|
PRINT(("partition_flags.allocated: %s\n", allocated() ? "true" : "false"));
|
|
PRINT(("partition_number: %d\n", partition_number()));
|
|
PRINT(("partition_contents:\n"));
|
|
DUMP(partition_contents());
|
|
PRINT(("partition_contents_use: XXX\n"));
|
|
DUMP(partition_contents_use());
|
|
PRINT(("access_type: %ld\n", access_type()));
|
|
PRINT(("start: %ld\n", start()));
|
|
PRINT(("length: %ld\n", length()));
|
|
PRINT(("implementation_id:\n"));
|
|
DUMP(implementation_id());
|
|
PRINT(("implementation_use: XXX\n"));
|
|
DUMP(implementation_use());
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// udf_logical_descriptor
|
|
//----------------------------------------------------------------------
|
|
|
|
void
|
|
udf_logical_descriptor::dump()
|
|
{
|
|
DUMP_INIT(CF_PUBLIC | CF_VOLUME_OPS | CF_DUMP, "udf_logical_descriptor");
|
|
PRINT(("tag:\n"));
|
|
DUMP(tag());
|
|
PRINT(("vds_number: %ld\n", vds_number()));
|
|
PRINT(("character_set:\n"));
|
|
DUMP(character_set());
|
|
CS0String string(logical_volume_identifier());
|
|
PRINT(("logical_volume_identifier: `%s'\n", string.String()));
|
|
PRINT(("logical_block_size: %ld\n", logical_block_size()));
|
|
PRINT(("domain_id:\n"));
|
|
DUMP(domain_id());
|
|
PRINT(("logical_volume_contents_use:\n"));
|
|
DUMP(logical_volume_contents_use());
|
|
PRINT(("file_set_address:\n"));
|
|
DUMP(file_set_address());
|
|
PRINT(("map_table_length: %ld\n", map_table_length()));
|
|
PRINT(("partition_map_count: %ld\n", partition_map_count()));
|
|
PRINT(("implementation_id:\n"));
|
|
DUMP(implementation_id());
|
|
PRINT(("implementation_use:\n"));
|
|
DUMP(implementation_use());
|
|
PRINT(("integrity_sequence_extent:\n"));
|
|
DUMP(integrity_sequence_extent());
|
|
// \todo dump partition_maps
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
// udf_unallocated_space_descriptor
|
|
//----------------------------------------------------------------------
|
|
|
|
void
|
|
udf_unallocated_space_descriptor::dump()
|
|
{
|
|
DUMP_INIT(CF_PUBLIC | CF_VOLUME_OPS | CF_DUMP, "udf_unallocated_space_descriptor");
|
|
PRINT(("tag:\n"));
|
|
DUMP(tag());
|
|
PRINT(("vds_number: %ld\n", vds_number()));
|
|
PRINT(("allocation_descriptor_count: %ld\n", allocation_descriptor_count()));
|
|
// \todo dump alloc_descriptors
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
// udf_terminating_descriptor
|
|
//----------------------------------------------------------------------
|
|
|
|
void
|
|
udf_terminating_descriptor::dump()
|
|
{
|
|
DUMP_INIT(CF_PUBLIC | CF_VOLUME_OPS | CF_DUMP, "udf_terminating_descriptor");
|
|
PRINT(("tag:\n"));
|
|
DUMP(tag());
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// udf_file_set_descriptor
|
|
//----------------------------------------------------------------------
|
|
|
|
void
|
|
udf_file_set_descriptor::dump()
|
|
{
|
|
DUMP_INIT(CF_PUBLIC | CF_VOLUME_OPS | CF_DUMP, "udf_file_set_descriptor");
|
|
PRINT(("tag:\n"));
|
|
DUMP(tag());
|
|
PRINT(("recording_date_and_time:\n"));
|
|
DUMP(recording_date_and_time());
|
|
PRINT(("interchange_level: %d\n", interchange_level()));
|
|
PRINT(("max_interchange_level: %d\n", max_interchange_level()));
|
|
PRINT(("character_set_list: %ld\n", character_set_list()));
|
|
PRINT(("max_character_set_list: %ld\n", max_character_set_list()));
|
|
PRINT(("file_set_number: %ld\n", file_set_number()));
|
|
PRINT(("file_set_descriptor_number: %ld\n", file_set_descriptor_number()));
|
|
PRINT(("logical_volume_id_character_set:\n"));
|
|
DUMP(logical_volume_id_character_set());
|
|
PRINT(("logical_volume_id:\n"));
|
|
DUMP(logical_volume_id());
|
|
PRINT(("file_set_charspec:\n"));
|
|
DUMP(file_set_charspec());
|
|
PRINT(("file_set_id:\n"));
|
|
DUMP(file_set_id());
|
|
PRINT(("copyright_file_id:\n"));
|
|
DUMP(copyright_file_id());
|
|
PRINT(("abstract_file_id:\n"));
|
|
DUMP(abstract_file_id());
|
|
PRINT(("root_directory_icb:\n"));
|
|
DUMP(root_directory_icb());
|
|
PRINT(("domain_id:\n"));
|
|
DUMP(domain_id());
|
|
PRINT(("next_extent:\n"));
|
|
DUMP(next_extent());
|
|
PRINT(("system_stream_directory_icb:\n"));
|
|
DUMP(system_stream_directory_icb());
|
|
}
|
|
|
|
void
|
|
udf_icb_entry_tag::dump()
|
|
{
|
|
DUMP_INIT(CF_PUBLIC, "udf_icb_entry_tag");
|
|
PRINT(("prior_entries: %ld\n", prior_recorded_number_of_direct_entries()));
|
|
PRINT(("strategy_type: %d\n", strategy_type()));
|
|
PRINT(("strategy_parameters:\n"));
|
|
DUMP(strategy_parameters());
|
|
PRINT(("entry_count: %d\n", entry_count()));
|
|
PRINT(("file_type: %d\n", file_type()));
|
|
PRINT(("parent_icb_location:\n"));
|
|
DUMP(parent_icb_location());
|
|
PRINT(("all_flags: %d\n", flags()));
|
|
|
|
/*
|
|
uint32 prior_recorded_number_of_direct_entries;
|
|
uint16 strategy_type;
|
|
array<uint8, 2> strategy_parameters;
|
|
uint16 entry_count;
|
|
uint8 reserved;
|
|
uint8 file_type;
|
|
udf_logical_block_address parent_icb_location;
|
|
union {
|
|
uint16 all_flags;
|
|
struct {
|
|
uint16 descriptor_flags:3,
|
|
if_directory_then_sort:1, //!< To be set to 0 per UDF-2.01 2.3.5.4
|
|
non_relocatable:1,
|
|
archive:1,
|
|
setuid:1,
|
|
setgid:1,
|
|
sticky:1,
|
|
contiguous:1,
|
|
system:1,
|
|
transformed:1,
|
|
multi_version:1, //!< To be set to 0 per UDF-2.01 2.3.5.4
|
|
is_stream:1,
|
|
reserved_icb_entry_flags:2;
|
|
} flags;
|
|
};
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
void
|
|
udf_icb_header::dump()
|
|
{
|
|
DUMP_INIT(CF_PUBLIC | CF_DUMP, "udf_icb_header");
|
|
|
|
PRINT(("tag:\n"));
|
|
DUMP(tag());
|
|
PRINT(("icb_tag:\n"));
|
|
DUMP(icb_tag());
|
|
|
|
}
|