diff --git a/src/add-ons/kernel/file_systems/udf/DiskStructures.cpp b/src/add-ons/kernel/file_systems/udf/DiskStructures.cpp index 963b18d947..4b3ab07ae9 100644 --- a/src/add-ons/kernel/file_systems/udf/DiskStructures.cpp +++ b/src/add-ons/kernel/file_systems/udf/DiskStructures.cpp @@ -37,6 +37,11 @@ const char* Udf::kVSDID_ECMA167_2 = "NSR02"; const char* Udf::kVSDID_ECMA167_3 = "NSR03"; const char* Udf::kVSDID_ECMA168 = "CDW02"; +// udf_entity_ids +const udf_entity_id Udf::kMetadataPartitionMapId(0, "*UDF Metadata Partition"); +const udf_entity_id Udf::kSparablePartitionMapId(0, "*UDF Sparable Partition"); +const udf_entity_id Udf::kVirtualPartitionMapId(0, "*UDF Virtual Partition"); + //---------------------------------------------------------------------- // Helper functions //---------------------------------------------------------------------- @@ -148,15 +153,40 @@ udf_timestamp::dump() const // udf_entity_id //---------------------------------------------------------------------- +udf_entity_id::udf_entity_id(uint8 flags, char *identifier, char *identifier_suffix) + : _flags(flags) +{ + if (identifier) + strncpy(_identifier, identifier, kIdentifierLength); + else + memset(_identifier, 0, kIdentifierLength); + if (identifier_suffix) + strncpy(_identifier_suffix, identifier_suffix, kIdentifierSuffixLength); + else + memset(_identifier_suffix, 0, kIdentifierSuffixLength); +} + void udf_entity_id::dump() const { DUMP_INIT(CF_PUBLIC | CF_DUMP, "udf_entity_id"); PRINT(("flags: %d\n", flags())); - PRINT(("identifier: `%s'\n", identifier())); + PRINT(("identifier: `%.23s'\n", identifier())); PRINT(("identifier_suffix: `%s'\n", identifier_suffix())); } +bool +udf_entity_id::matches(const udf_entity_id &id) const +{ + bool result = true; + for (int i = 0; i < udf_entity_id::kIdentifierLength; i++) { + if (identifier()[i] != id.identifier()[i]) { + result = false; + break; + } + } + return result; +} //---------------------------------------------------------------------- // udf_extent_address diff --git a/src/add-ons/kernel/file_systems/udf/DiskStructures.h b/src/add-ons/kernel/file_systems/udf/DiskStructures.h index f3e4505d45..902287ee64 100644 --- a/src/add-ons/kernel/file_systems/udf/DiskStructures.h +++ b/src/add-ons/kernel/file_systems/udf/DiskStructures.h @@ -157,7 +157,11 @@ private: */ struct udf_entity_id { public: + udf_entity_id(uint8 flags = 0, char *identifier = NULL, + char *identifier_suffix = NULL); + void dump() const; + bool matches(const udf_entity_id &id) const; // Get functions uint8 flags() const { return _flags; } @@ -167,13 +171,19 @@ public: char* identifier_suffix() { return _identifier_suffix; } // Set functions - void set_flags(uint8 flags) { _flags = flags; } + void set_flags(uint8 flags) { _flags = flags; } + + static const int kIdentifierLength = 23; + static const int kIdentifierSuffixLength = 8; private: uint8 _flags; - char _identifier[23]; - char _identifier_suffix[8]; + char _identifier[kIdentifierLength]; + char _identifier_suffix[kIdentifierSuffixLength]; } __attribute__((packed)); +extern const udf_entity_id kMetadataPartitionMapId; +extern const udf_entity_id kSparablePartitionMapId; +extern const udf_entity_id kVirtualPartitionMapId; //---------------------------------------------------------------------- // ECMA-167 Part 2 @@ -213,7 +223,6 @@ struct udf_volume_structure_descriptor_header { bool id_matches(const char *id); } __attribute__((packed)); - // Volume structure descriptor ids extern const char* kVSDID_BEA; extern const char* kVSDID_TEA; @@ -223,7 +232,6 @@ extern const char* kVSDID_ECMA167_2; extern const char* kVSDID_ECMA167_3; extern const char* kVSDID_ECMA168; - //---------------------------------------------------------------------- // ECMA-167 Part 3 //---------------------------------------------------------------------- @@ -693,6 +701,7 @@ private: */ extern const uint8 kMaxPartitionDescriptors; #define UDF_MAX_PARTITION_MAPS 2 +#define UDF_MAX_PARTITION_MAP_SIZE 64 /*! \brief Partition Descriptor @@ -889,22 +898,31 @@ private: UDF type 2 for virtual maps or maps on systems not supporting defect management. + Note that we actually allocate memory for the partition maps + here due to the fact that we allocate udf_logical_descriptor + objects on the stack sometimes. + See UDF-2.01 2.2.8, 2.2.9 */ - uint8 _partition_maps[0]; + uint8 _partition_maps[UDF_MAX_PARTITION_MAPS * UDF_MAX_PARTITION_MAP_SIZE]; } __attribute__((packed)); -/*! \brief Generic partition map +/*! \brief (Mostly) common portion of various partition maps See also: ECMA-167 3/10.7.1 */ -struct udf_generic_partition_map { +struct udf_partition_map_header { public: uint8 type() const { return _type; } uint8 length() const { return _length; } uint8 *map_data() { return _map_data; } const uint8 *map_data() const { return _map_data; } + + udf_entity_id& partition_type_id() + { return *reinterpret_cast(&_map_data[2]); } + const udf_entity_id& partition_type_id() const + { return *reinterpret_cast(&_map_data[2]); } void set_type(uint8 type) { _type = type; } void set_length(uint8 length) { _length = length; } @@ -1044,6 +1062,34 @@ private: } __attribute__((packed)); +/* ----UDF Specific---- */ +/*! \brief Metadata partition map + + Note that this map is a customization of the ECMA-167 + type 2 partition map. + + See also: UDF-2.50 2.2.10 +*/ +struct udf_metadata_partition_map { + uint8 type; + uint8 length; + uint8 reserved1[2]; + + /*! - flags: 0 + - identifier: "*UDF Metadata Partition" + - identifier_suffix: per UDF-2.50 2.1.5 + */ + udf_entity_id partition_type_id; + uint16 volume_sequence_number; + + /*! corresponding type 1 or type 2 sparable partition + map in same logical volume + */ + uint16 partition_number; + uint8 reserved2[24]; +} __attribute__((packed)); + + /*! \brief Unallocated space descriptor See also: ECMA-167 3/10.8