1c530d46cSJérôme Duval /* 2c530d46cSJérôme Duval * Copyright 2012, Jérôme Duval, korli@users.berlios.de. 3c530d46cSJérôme Duval * Copyright (c) 2003 Tyler Dauwalder, tyler@dauwalder.net 4c530d46cSJérôme Duval * This file may be used under the terms of the MIT License. 5c530d46cSJérôme Duval */ 6ead0c3e2STyler Dauwalder #ifndef _UDF_DISK_STRUCTURES_H 7ead0c3e2STyler Dauwalder #define _UDF_DISK_STRUCTURES_H 8ead0c3e2STyler Dauwalder 9ead0c3e2STyler Dauwalder #include <string.h> 10ead0c3e2STyler Dauwalder 11ead0c3e2STyler Dauwalder #include <ByteOrder.h> 12ead0c3e2STyler Dauwalder #include <SupportDefs.h> 13ead0c3e2STyler Dauwalder 14ead0c3e2STyler Dauwalder #include "UdfDebug.h" 1520d84995SRene Gollent #include "Utils.h" 16ead0c3e2STyler Dauwalder 17ead0c3e2STyler Dauwalder #include "Array.h" 18ead0c3e2STyler Dauwalder 19c21aaa8aSTyler Dauwalder /*! \file UdfStructures.h 20ead0c3e2STyler Dauwalder 21ead0c3e2STyler Dauwalder \brief UDF on-disk data structure declarations 22ead0c3e2STyler Dauwalder 23ead0c3e2STyler Dauwalder UDF is a specialization of the ECMA-167 standard. For the most part, 24ead0c3e2STyler Dauwalder ECMA-167 structures are used by UDF with special restrictions. In a 25ead0c3e2STyler Dauwalder few instances, UDF introduces its own structures to augment those 26ead0c3e2STyler Dauwalder supplied by ECMA-167; those structures are clearly marked. 27ead0c3e2STyler Dauwalder 28ead0c3e2STyler Dauwalder For UDF info: <a href='http://www.osta.org'>http://www.osta.org</a> 29ead0c3e2STyler Dauwalder For ECMA info: <a href='http://www.ecma-international.org'>http://www.ecma-international.org</a> 30ead0c3e2STyler Dauwalder 31ead0c3e2STyler Dauwalder For lack of a better place to store this info, the structures that 32ead0c3e2STyler Dauwalder are allowed to have length greater than the logical block size are 33ead0c3e2STyler Dauwalder as follows (other length restrictions may be found in UDF-2.01 5.1): 34ead0c3e2STyler Dauwalder - \c logical_volume_descriptor 35ead0c3e2STyler Dauwalder - \c unallocated_space_descriptor 36ead0c3e2STyler Dauwalder - \c logical_volume_integrity_descriptor 37ead0c3e2STyler Dauwalder - \c space_bitmap_descriptor 38ead0c3e2STyler Dauwalder 39ead0c3e2STyler Dauwalder Other links of interest: 40ead0c3e2STyler Dauwalder - <a href='http://www.extra.research.philips.com/udf/'>Philips UDF verifier</a> 41ead0c3e2STyler Dauwalder - <a href='http://www.hi-ho.ne.jp/y-komachi/committees/fpro/fpro.htm'>Possible test disc image generator (?)</a> 42ead0c3e2STyler Dauwalder */ 43ead0c3e2STyler Dauwalder 44ead0c3e2STyler Dauwalder //---------------------------------------------------------------------- 45ead0c3e2STyler Dauwalder // ECMA-167 Part 1 46ead0c3e2STyler Dauwalder //---------------------------------------------------------------------- 47ead0c3e2STyler Dauwalder 48ead0c3e2STyler Dauwalder /*! \brief Character set specifications 49ead0c3e2STyler Dauwalder 50ead0c3e2STyler Dauwalder The character_set_info field shall be set to the ASCII string 51ead0c3e2STyler Dauwalder "OSTA Compressed Unicode" (padded right with NULL chars). 52ead0c3e2STyler Dauwalder 53ead0c3e2STyler Dauwalder See also: ECMA 167 1/7.2.1, UDF-2.01 2.1.2 54ead0c3e2STyler Dauwalder */ 55ead0c3e2STyler Dauwalder struct charspec { 56ead0c3e2STyler Dauwalder public: 571801834fSTyler Dauwalder charspec(uint8 type = 0, const char *info = NULL); 581801834fSTyler Dauwalder 59ead0c3e2STyler Dauwalder void dump() const; 60ead0c3e2STyler Dauwalder character_set_typecharspec61ead0c3e2STyler Dauwalder uint8 character_set_type() const { return _character_set_type; } character_set_infocharspec62ead0c3e2STyler Dauwalder const char* character_set_info() const { return _character_set_info; } character_set_infocharspec63ead0c3e2STyler Dauwalder char* character_set_info() { return _character_set_info; } 64ead0c3e2STyler Dauwalder set_character_set_typecharspec65ead0c3e2STyler Dauwalder void set_character_set_type(uint8 type) { _character_set_type = type; } 661801834fSTyler Dauwalder void set_character_set_info(const char *info); 67ead0c3e2STyler Dauwalder private: 68ead0c3e2STyler Dauwalder uint8 _character_set_type; //!< to be set to 0 to indicate CS0 69ead0c3e2STyler Dauwalder char _character_set_info[63]; //!< "OSTA Compressed Unicode" 70ead0c3e2STyler Dauwalder } __attribute__((packed)); 71ead0c3e2STyler Dauwalder 721801834fSTyler Dauwalder extern const charspec kCs0CharacterSet; 73ead0c3e2STyler Dauwalder 74ead0c3e2STyler Dauwalder /*! \brief Date and time stamp 75ead0c3e2STyler Dauwalder 76ead0c3e2STyler Dauwalder See also: ECMA 167 1/7.3, UDF-2.01 2.1.4 77ead0c3e2STyler Dauwalder */ 78ead0c3e2STyler Dauwalder class timestamp { 79ead0c3e2STyler Dauwalder private: 80ead0c3e2STyler Dauwalder union type_and_timezone_accessor { 81ead0c3e2STyler Dauwalder uint16 type_and_timezone; 82ead0c3e2STyler Dauwalder struct { 8310186d5dSTyler Dauwalder uint16 timezone:12, 8410186d5dSTyler Dauwalder type:4; 85ead0c3e2STyler Dauwalder } bits; 86ead0c3e2STyler Dauwalder }; 87ead0c3e2STyler Dauwalder 88ead0c3e2STyler Dauwalder public: timestamp()899b438e89STyler Dauwalder timestamp() { _clear(); } 909b438e89STyler Dauwalder timestamp(time_t time); 919b438e89STyler Dauwalder 92ead0c3e2STyler Dauwalder void dump() const; 93ead0c3e2STyler Dauwalder 94ead0c3e2STyler Dauwalder // Get functions type_and_timezone()95ead0c3e2STyler Dauwalder uint16 type_and_timezone() const { return B_LENDIAN_TO_HOST_INT16(_type_and_timezone); } type()96ead0c3e2STyler Dauwalder uint8 type() const { 97ead0c3e2STyler Dauwalder type_and_timezone_accessor t; 98ead0c3e2STyler Dauwalder t.type_and_timezone = type_and_timezone(); 99ead0c3e2STyler Dauwalder return t.bits.type; 100ead0c3e2STyler Dauwalder } timezone()101ead0c3e2STyler Dauwalder int16 timezone() const { 102ead0c3e2STyler Dauwalder type_and_timezone_accessor t; 103ead0c3e2STyler Dauwalder t.type_and_timezone = type_and_timezone(); 1049b438e89STyler Dauwalder int16 result = t.bits.timezone; 1059b438e89STyler Dauwalder // Fill the lefmost bits with ones if timezone is negative 1069b438e89STyler Dauwalder result <<= 4; 1079b438e89STyler Dauwalder result >>= 4; 1089b438e89STyler Dauwalder return result; 109ead0c3e2STyler Dauwalder } year()110ead0c3e2STyler Dauwalder uint16 year() const { return B_LENDIAN_TO_HOST_INT16(_year); } month()111ead0c3e2STyler Dauwalder uint8 month() const { return _month; } day()112ead0c3e2STyler Dauwalder uint8 day() const { return _day; } hour()113ead0c3e2STyler Dauwalder uint8 hour() const { return _hour; } minute()114ead0c3e2STyler Dauwalder uint8 minute() const { return _minute; } second()115ead0c3e2STyler Dauwalder uint8 second() const { return _second; } centisecond()116ead0c3e2STyler Dauwalder uint8 centisecond() const { return _centisecond; } hundred_microsecond()117ead0c3e2STyler Dauwalder uint8 hundred_microsecond() const { return _hundred_microsecond; } microsecond()118ead0c3e2STyler Dauwalder uint8 microsecond() const { return _microsecond; } 119ead0c3e2STyler Dauwalder 120ead0c3e2STyler Dauwalder // Set functions set_type_and_timezone(uint16 type_and_timezone)121c530d46cSJérôme Duval void set_type_and_timezone(uint16 type_and_timezone) { 122c530d46cSJérôme Duval _type_and_timezone = B_HOST_TO_LENDIAN_INT16(type_and_timezone); } set_type(uint8 type)123ead0c3e2STyler Dauwalder void set_type(uint8 type) { 124ead0c3e2STyler Dauwalder type_and_timezone_accessor t; 125ead0c3e2STyler Dauwalder t.type_and_timezone = type_and_timezone(); 126ead0c3e2STyler Dauwalder t.bits.type = type; 127ead0c3e2STyler Dauwalder set_type_and_timezone(t.type_and_timezone); 128ead0c3e2STyler Dauwalder } set_timezone(int16 tz)129003d4e83STyler Dauwalder void set_timezone(int16 tz) { 130ead0c3e2STyler Dauwalder type_and_timezone_accessor t; 131ead0c3e2STyler Dauwalder t.type_and_timezone = type_and_timezone(); 132003d4e83STyler Dauwalder t.bits.timezone = tz; 133ead0c3e2STyler Dauwalder set_type_and_timezone(t.type_and_timezone); 134ead0c3e2STyler Dauwalder } set_year(uint16 year)135ead0c3e2STyler Dauwalder void set_year(uint16 year) { _year = B_HOST_TO_LENDIAN_INT16(year); } set_month(uint8 month)136ead0c3e2STyler Dauwalder void set_month(uint8 month) { _month = month; } set_day(uint8 day)137ead0c3e2STyler Dauwalder void set_day(uint8 day) { _day = day; } set_hour(uint8 hour)138ead0c3e2STyler Dauwalder void set_hour(uint8 hour) { _hour = hour; } set_minute(uint8 minute)139ead0c3e2STyler Dauwalder void set_minute(uint8 minute) { _minute = minute; } set_second(uint8 second)140ead0c3e2STyler Dauwalder void set_second(uint8 second) { _second = second; } set_centisecond(uint8 centisecond)141ead0c3e2STyler Dauwalder void set_centisecond(uint8 centisecond) { _centisecond = centisecond; } set_hundred_microsecond(uint8 hundred_microsecond)142c530d46cSJérôme Duval void set_hundred_microsecond(uint8 hundred_microsecond) { 143c530d46cSJérôme Duval _hundred_microsecond = hundred_microsecond; } set_microsecond(uint8 microsecond)144ead0c3e2STyler Dauwalder void set_microsecond(uint8 microsecond) { _microsecond = microsecond; } 145ead0c3e2STyler Dauwalder private: 1469b438e89STyler Dauwalder void _clear(); 1479b438e89STyler Dauwalder 148ead0c3e2STyler Dauwalder uint16 _type_and_timezone; 149ead0c3e2STyler Dauwalder uint16 _year; 150ead0c3e2STyler Dauwalder uint8 _month; 151ead0c3e2STyler Dauwalder uint8 _day; 152ead0c3e2STyler Dauwalder uint8 _hour; 153ead0c3e2STyler Dauwalder uint8 _minute; 154ead0c3e2STyler Dauwalder uint8 _second; 155ead0c3e2STyler Dauwalder uint8 _centisecond; 156ead0c3e2STyler Dauwalder uint8 _hundred_microsecond; 157ead0c3e2STyler Dauwalder uint8 _microsecond; 158ead0c3e2STyler Dauwalder 159ead0c3e2STyler Dauwalder } __attribute__((packed)); 160ead0c3e2STyler Dauwalder 161ead0c3e2STyler Dauwalder 1629a043bf9STyler Dauwalder /*! \brief UDF ID Identify Suffix 1639a043bf9STyler Dauwalder 1649a043bf9STyler Dauwalder See also: UDF 2.50 2.1.5.3 1659a043bf9STyler Dauwalder */ 1669a043bf9STyler Dauwalder struct udf_id_suffix { 1679a043bf9STyler Dauwalder public: 1689a043bf9STyler Dauwalder udf_id_suffix(uint16 udfRevision, uint8 os_class, uint8 os_identifier); 1699a043bf9STyler Dauwalder 1709a043bf9STyler Dauwalder //! Note that revision 2.50 is denoted by 0x0250. udf_revisionudf_id_suffix1719a043bf9STyler Dauwalder uint16 udf_revision() const { return _udf_revision; } os_classudf_id_suffix1729a043bf9STyler Dauwalder uint8 os_class() const { return _os_class; } os_identifierudf_id_suffix1739a043bf9STyler Dauwalder uint8 os_identifier() const { return _os_identifier; } 1749a043bf9STyler Dauwalder set_os_classudf_id_suffix1759a043bf9STyler Dauwalder void set_os_class(uint8 os_class) { _os_class = os_class; } set_os_identifierudf_id_suffix1769a043bf9STyler Dauwalder void set_os_identifier(uint8 identifier) { _os_identifier = identifier; } 1779a043bf9STyler Dauwalder private: 1789a043bf9STyler Dauwalder uint16 _udf_revision; 1799a043bf9STyler Dauwalder uint8 _os_class; 1809a043bf9STyler Dauwalder uint8 _os_identifier; 1819a043bf9STyler Dauwalder array<uint8, 4> _reserved; 1829a043bf9STyler Dauwalder }; 1839a043bf9STyler Dauwalder 1849b438e89STyler Dauwalder /*! \brief Implementation ID Identify Suffix 1859b438e89STyler Dauwalder 1869b438e89STyler Dauwalder See also: UDF 2.50 2.1.5.3 1879b438e89STyler Dauwalder */ 1889b438e89STyler Dauwalder struct implementation_id_suffix { 1899b438e89STyler Dauwalder public: 1909b438e89STyler Dauwalder implementation_id_suffix(uint8 os_class, uint8 os_identifier); 1919b438e89STyler Dauwalder os_classimplementation_id_suffix1929b438e89STyler Dauwalder uint8 os_class() const { return _os_class; } os_identifierimplementation_id_suffix1939b438e89STyler Dauwalder uint8 os_identifier() const { return _os_identifier; } 1949b438e89STyler Dauwalder set_os_classimplementation_id_suffix1959b438e89STyler Dauwalder void set_os_class(uint8 os_class) { _os_class = os_class; } set_os_identifierimplementation_id_suffix1969b438e89STyler Dauwalder void set_os_identifier(uint8 identifier) { _os_identifier = identifier; } 1979b438e89STyler Dauwalder private: 1989b438e89STyler Dauwalder uint8 _os_class; 1999b438e89STyler Dauwalder uint8 _os_identifier; 2009b438e89STyler Dauwalder array<uint8, 6> _implementation_use; 2019b438e89STyler Dauwalder }; 2029b438e89STyler Dauwalder 2039b438e89STyler Dauwalder /*! \brief Operating system classes for implementation_id_suffixes 2049b438e89STyler Dauwalder 2059b438e89STyler Dauwalder See also: Udf 2.50 6.3 2069b438e89STyler Dauwalder */ 2079b438e89STyler Dauwalder enum { 2089b438e89STyler Dauwalder OS_UNDEFINED = 0, 2099b438e89STyler Dauwalder OS_DOS, 2109b438e89STyler Dauwalder OS_OS2, 2119b438e89STyler Dauwalder OS_MACOS, 2129b438e89STyler Dauwalder OS_UNIX, 2139b438e89STyler Dauwalder OS_WIN9X, 2149b438e89STyler Dauwalder OS_WINNT, 2159b438e89STyler Dauwalder OS_OS400, 2169b438e89STyler Dauwalder OS_BEOS, 2179b438e89STyler Dauwalder OS_WINCE 2189b438e89STyler Dauwalder }; 2199b438e89STyler Dauwalder 2209b438e89STyler Dauwalder /*! \brief BeOS operating system classes identifiers for implementation_id_suffixes 2219b438e89STyler Dauwalder 2229b438e89STyler Dauwalder See also: Udf 2.50 6.3 2239b438e89STyler Dauwalder */ 2249b438e89STyler Dauwalder enum { 2259b438e89STyler Dauwalder BEOS_GENERIC = 0, 2269b438e89STyler Dauwalder BEOS_OPENBEOS = 1 // not part of the standard, but perhaps someday. :-) 2279b438e89STyler Dauwalder }; 2289b438e89STyler Dauwalder 229730ba00aSTyler Dauwalder /*! \brief Domain ID Identify Suffix 230730ba00aSTyler Dauwalder 231730ba00aSTyler Dauwalder See also: UDF 2.50 2.1.5.3 232730ba00aSTyler Dauwalder */ 233730ba00aSTyler Dauwalder struct domain_id_suffix { 234730ba00aSTyler Dauwalder public: 235730ba00aSTyler Dauwalder domain_id_suffix(uint16 udfRevision, uint8 domainFlags); 236730ba00aSTyler Dauwalder 237730ba00aSTyler Dauwalder //! Note that revision 2.50 is denoted by 0x0250. udf_revisiondomain_id_suffix238730ba00aSTyler Dauwalder uint16 udf_revision() const { return _udf_revision; } domain_flagsdomain_id_suffix239730ba00aSTyler Dauwalder uint8 domain_flags() const { return _domain_flags; } 240730ba00aSTyler Dauwalder set_udf_revisiondomain_id_suffix241730ba00aSTyler Dauwalder void set_udf_revision(uint16 revision) { _udf_revision = B_HOST_TO_LENDIAN_INT16(revision); } set_domain_flagsdomain_id_suffix242730ba00aSTyler Dauwalder void set_domain_flags(uint8 flags) { _domain_flags = flags; } 243730ba00aSTyler Dauwalder private: 24410186d5dSTyler Dauwalder uint16 _udf_revision; 245730ba00aSTyler Dauwalder uint8 _domain_flags; 246730ba00aSTyler Dauwalder array<uint8, 5> _reserved; 247730ba00aSTyler Dauwalder }; 248730ba00aSTyler Dauwalder 249730ba00aSTyler Dauwalder /*! \brief Domain flags 250730ba00aSTyler Dauwalder 251730ba00aSTyler Dauwalder See also: UDF 2.50 2.1.5.3 252730ba00aSTyler Dauwalder */ 253730ba00aSTyler Dauwalder enum { 254730ba00aSTyler Dauwalder DF_HARD_WRITE_PROTECT = 0x01, 255730ba00aSTyler Dauwalder DF_SOFT_WRITE_PROTECT = 0x02 256730ba00aSTyler Dauwalder }; 257730ba00aSTyler Dauwalder 258ead0c3e2STyler Dauwalder /*! \brief Identifier used to designate the implementation responsible 259ead0c3e2STyler Dauwalder for writing associated data structures on the medium. 260ead0c3e2STyler Dauwalder 261ead0c3e2STyler Dauwalder See also: ECMA 167 1/7.4, UDF 2.01 2.1.5 262ead0c3e2STyler Dauwalder */ 263ead0c3e2STyler Dauwalder struct entity_id { 264ead0c3e2STyler Dauwalder public: 2659b438e89STyler Dauwalder static const int kIdentifierLength = 23; 2669b438e89STyler Dauwalder static const int kIdentifierSuffixLength = 8; 2679b438e89STyler Dauwalder 26820d84995SRene Gollent entity_id(uint8 flags = 0, const char *identifier = NULL, 2699b438e89STyler Dauwalder uint8 *identifier_suffix = NULL); 27020d84995SRene Gollent entity_id(uint8 flags, const char *identifier, 2719a043bf9STyler Dauwalder const udf_id_suffix &suffix); 27220d84995SRene Gollent entity_id(uint8 flags, const char *identifier, 2739b438e89STyler Dauwalder const implementation_id_suffix &suffix); 27420d84995SRene Gollent entity_id(uint8 flags, const char *identifier, 275730ba00aSTyler Dauwalder const domain_id_suffix &suffix); 276ead0c3e2STyler Dauwalder 277ead0c3e2STyler Dauwalder void dump() const; 278ead0c3e2STyler Dauwalder bool matches(const entity_id &id) const; 279ead0c3e2STyler Dauwalder 280ead0c3e2STyler Dauwalder // Get functions flagsentity_id281ead0c3e2STyler Dauwalder uint8 flags() const { return _flags; } identifierentity_id282ead0c3e2STyler Dauwalder const char* identifier() const { return _identifier; } identifierentity_id283ead0c3e2STyler Dauwalder char* identifier() { return _identifier; } identifier_suffixentity_id2849b438e89STyler Dauwalder const array<uint8, kIdentifierSuffixLength>& identifier_suffix() const { return _identifier_suffix; } identifier_suffixentity_id2859b438e89STyler Dauwalder array<uint8, kIdentifierSuffixLength>& identifier_suffix() { return _identifier_suffix; } 286ead0c3e2STyler Dauwalder 287ead0c3e2STyler Dauwalder // Set functions set_flagsentity_id288ead0c3e2STyler Dauwalder void set_flags(uint8 flags) { _flags = flags; } 289ead0c3e2STyler Dauwalder private: 290ead0c3e2STyler Dauwalder uint8 _flags; 291ead0c3e2STyler Dauwalder char _identifier[kIdentifierLength]; 2929b438e89STyler Dauwalder array<uint8, kIdentifierSuffixLength> _identifier_suffix; 293ead0c3e2STyler Dauwalder } __attribute__((packed)); 294ead0c3e2STyler Dauwalder 295c530d46cSJérôme Duval extern entity_id kMetadataPartitionMapId; 296c530d46cSJérôme Duval extern entity_id kSparablePartitionMapId; 297c530d46cSJérôme Duval extern entity_id kVirtualPartitionMapId; 298c530d46cSJérôme Duval extern entity_id kImplementationId; 299c530d46cSJérôme Duval extern entity_id kPartitionContentsId1xx; 300c530d46cSJérôme Duval extern entity_id kPartitionContentsId2xx; 301c530d46cSJérôme Duval extern entity_id kUdfId; 302c530d46cSJérôme Duval extern entity_id kLogicalVolumeInfoId150; 303c530d46cSJérôme Duval extern entity_id kLogicalVolumeInfoId201; 304c530d46cSJérôme Duval extern entity_id kDomainId150; 305c530d46cSJérôme Duval extern entity_id kDomainId201; 306c530d46cSJérôme Duval extern void init_entities(void); 307ead0c3e2STyler Dauwalder 308ead0c3e2STyler Dauwalder //---------------------------------------------------------------------- 309ead0c3e2STyler Dauwalder // ECMA-167 Part 2 310ead0c3e2STyler Dauwalder //---------------------------------------------------------------------- 311ead0c3e2STyler Dauwalder 312ead0c3e2STyler Dauwalder 313ead0c3e2STyler Dauwalder /*! \brief Header for volume structure descriptors 314ead0c3e2STyler Dauwalder 315ead0c3e2STyler Dauwalder Each descriptor consumes an entire block. All unused trailing 316ead0c3e2STyler Dauwalder bytes in the descriptor should be set to 0. 317ead0c3e2STyler Dauwalder 318ead0c3e2STyler Dauwalder The following descriptors contain no more information than 319ead0c3e2STyler Dauwalder that contained in the header: 320ead0c3e2STyler Dauwalder 321ead0c3e2STyler Dauwalder - BEA01: 322ead0c3e2STyler Dauwalder - type: 0 323ead0c3e2STyler Dauwalder - id: "BEA01" 324ead0c3e2STyler Dauwalder - version: 1 325ead0c3e2STyler Dauwalder 326ead0c3e2STyler Dauwalder - TEA01: 327ead0c3e2STyler Dauwalder - type: 0 328ead0c3e2STyler Dauwalder - id: "TEA01" 329ead0c3e2STyler Dauwalder - version: 1 330ead0c3e2STyler Dauwalder 331ead0c3e2STyler Dauwalder - NSR03: 332ead0c3e2STyler Dauwalder - type: 0 333ead0c3e2STyler Dauwalder - id: "NSR03" 334ead0c3e2STyler Dauwalder - version: 1 335ead0c3e2STyler Dauwalder 336ead0c3e2STyler Dauwalder See also: ECMA 167 2/9.1 337ead0c3e2STyler Dauwalder */ 338ead0c3e2STyler Dauwalder struct volume_structure_descriptor_header { 3392cc6b97aSTyler Dauwalder public: 3402cc6b97aSTyler Dauwalder volume_structure_descriptor_header(uint8 type, const char *id, uint8 version); 3412cc6b97aSTyler Dauwalder 342ead0c3e2STyler Dauwalder uint8 type; 343ead0c3e2STyler Dauwalder char id[5]; 344ead0c3e2STyler Dauwalder uint8 version; 345ead0c3e2STyler Dauwalder 346ead0c3e2STyler Dauwalder bool id_matches(const char *id); 347ead0c3e2STyler Dauwalder } __attribute__((packed)); 348ead0c3e2STyler Dauwalder 349ead0c3e2STyler Dauwalder // Volume structure descriptor ids 350ead0c3e2STyler Dauwalder extern const char* kVSDID_BEA; 351ead0c3e2STyler Dauwalder extern const char* kVSDID_TEA; 352ead0c3e2STyler Dauwalder extern const char* kVSDID_BOOT; 353ead0c3e2STyler Dauwalder extern const char* kVSDID_ISO; 354ead0c3e2STyler Dauwalder extern const char* kVSDID_ECMA167_2; 355ead0c3e2STyler Dauwalder extern const char* kVSDID_ECMA167_3; 356ead0c3e2STyler Dauwalder extern const char* kVSDID_ECMA168; 357ead0c3e2STyler Dauwalder 358ead0c3e2STyler Dauwalder //---------------------------------------------------------------------- 359ead0c3e2STyler Dauwalder // ECMA-167 Part 3 360ead0c3e2STyler Dauwalder //---------------------------------------------------------------------- 361ead0c3e2STyler Dauwalder 362ead0c3e2STyler Dauwalder 363ead0c3e2STyler Dauwalder /*! \brief Location and length of a contiguous chunk of data on the volume. 364ead0c3e2STyler Dauwalder 365ead0c3e2STyler Dauwalder \c _location is an absolute block address. 366ead0c3e2STyler Dauwalder 367ead0c3e2STyler Dauwalder See also: ECMA 167 3/7.1 368ead0c3e2STyler Dauwalder */ 369ead0c3e2STyler Dauwalder struct extent_address { 370ead0c3e2STyler Dauwalder public: 371c21aaa8aSTyler Dauwalder extent_address(uint32 location = 0, uint32 length = 0); 372c21aaa8aSTyler Dauwalder 373ead0c3e2STyler Dauwalder void dump() const; 374ead0c3e2STyler Dauwalder lengthextent_address375ead0c3e2STyler Dauwalder uint32 length() const { return B_LENDIAN_TO_HOST_INT32(_length); } locationextent_address376ead0c3e2STyler Dauwalder uint32 location() const { return B_LENDIAN_TO_HOST_INT32(_location); } 377ead0c3e2STyler Dauwalder set_lengthextent_address378ead0c3e2STyler Dauwalder void set_length(int32 length) { _length = B_HOST_TO_LENDIAN_INT32(length); } set_locationextent_address379ead0c3e2STyler Dauwalder void set_location(int32 location) { _location = B_HOST_TO_LENDIAN_INT32(location); } 380ead0c3e2STyler Dauwalder private: 381ead0c3e2STyler Dauwalder uint32 _length; 382ead0c3e2STyler Dauwalder uint32 _location; 383ead0c3e2STyler Dauwalder } __attribute__((packed)); 384ead0c3e2STyler Dauwalder 385ead0c3e2STyler Dauwalder 386ead0c3e2STyler Dauwalder /*! \brief Location of a logical block within a logical volume. 387ead0c3e2STyler Dauwalder 388ead0c3e2STyler Dauwalder See also: ECMA 167 4/7.1 389ead0c3e2STyler Dauwalder */ 390ead0c3e2STyler Dauwalder struct logical_block_address { 391ead0c3e2STyler Dauwalder public: 392ead0c3e2STyler Dauwalder void dump() const; 393e631ed51STyler Dauwalder logical_block_address(uint16 partition = 0, uint32 block = 0); 394ead0c3e2STyler Dauwalder blocklogical_block_address395ead0c3e2STyler Dauwalder uint32 block() const { return B_LENDIAN_TO_HOST_INT32(_block); } partitionlogical_block_address396ead0c3e2STyler Dauwalder uint16 partition() const { return B_LENDIAN_TO_HOST_INT16(_partition); } 397ead0c3e2STyler Dauwalder set_blocklogical_block_address398ead0c3e2STyler Dauwalder void set_block(uint32 block) { _block = B_HOST_TO_LENDIAN_INT32(block); } set_partitionlogical_block_address399ead0c3e2STyler Dauwalder void set_partition(uint16 partition) { _partition = B_HOST_TO_LENDIAN_INT16(partition); } 400ead0c3e2STyler Dauwalder 401ead0c3e2STyler Dauwalder private: 402ead0c3e2STyler Dauwalder uint32 _block; //!< Block location relative to start of corresponding partition 403ead0c3e2STyler Dauwalder uint16 _partition; //!< Numeric partition id within logical volume 404ead0c3e2STyler Dauwalder } __attribute__((packed)); 405ead0c3e2STyler Dauwalder 406ead0c3e2STyler Dauwalder /*! \brief Extent types used in short_address, long_address, 407ead0c3e2STyler Dauwalder and extended_address. 408ead0c3e2STyler Dauwalder 409ead0c3e2STyler Dauwalder See also: ECMA-167 4/14.14.1.1 410ead0c3e2STyler Dauwalder */ 411ead0c3e2STyler Dauwalder enum extent_type { 412ead0c3e2STyler Dauwalder EXTENT_TYPE_RECORDED = 0, //!< Allocated and recorded 413ead0c3e2STyler Dauwalder EXTENT_TYPE_ALLOCATED, //!< Allocated but unrecorded 414ead0c3e2STyler Dauwalder EXTENT_TYPE_UNALLOCATED, //!< Unallocated and unrecorded 415ead0c3e2STyler Dauwalder EXTENT_TYPE_CONTINUATION, //!< Specifies next extent of descriptors 416ead0c3e2STyler Dauwalder }; 417ead0c3e2STyler Dauwalder 418ead0c3e2STyler Dauwalder 419ead0c3e2STyler Dauwalder /*! \brief Allocation descriptor. 420ead0c3e2STyler Dauwalder 421ead0c3e2STyler Dauwalder See also: ECMA 167 4/14.14.1 422ead0c3e2STyler Dauwalder */ 423ead0c3e2STyler Dauwalder struct short_address { 424ead0c3e2STyler Dauwalder private: 425ead0c3e2STyler Dauwalder union type_and_length_accessor { 426ead0c3e2STyler Dauwalder uint32 type_and_length; 427ead0c3e2STyler Dauwalder struct { 428ead0c3e2STyler Dauwalder uint32 length:30, 429ead0c3e2STyler Dauwalder type:2; 430ead0c3e2STyler Dauwalder // uint32 type:2, 431ead0c3e2STyler Dauwalder // length:30; 432ead0c3e2STyler Dauwalder } bits; 433ead0c3e2STyler Dauwalder }; 434ead0c3e2STyler Dauwalder 435ead0c3e2STyler Dauwalder public: 436ead0c3e2STyler Dauwalder void dump() const; 437ead0c3e2STyler Dauwalder typeshort_address438ead0c3e2STyler Dauwalder uint8 type() const { 439ead0c3e2STyler Dauwalder type_and_length_accessor t; 440ead0c3e2STyler Dauwalder t.type_and_length = type_and_length(); 441ead0c3e2STyler Dauwalder return t.bits.type; 442ead0c3e2STyler Dauwalder } lengthshort_address443ead0c3e2STyler Dauwalder uint32 length() const { 444ead0c3e2STyler Dauwalder type_and_length_accessor t; 445ead0c3e2STyler Dauwalder t.type_and_length = type_and_length(); 446ead0c3e2STyler Dauwalder return t.bits.length; 447ead0c3e2STyler Dauwalder } blockshort_address448ead0c3e2STyler Dauwalder uint32 block() const { return B_LENDIAN_TO_HOST_INT32(_block); } 449ead0c3e2STyler Dauwalder set_typeshort_address450ead0c3e2STyler Dauwalder void set_type(uint8 type) { 451ead0c3e2STyler Dauwalder type_and_length_accessor t; 452ead0c3e2STyler Dauwalder t.type_and_length = type_and_length(); 453ead0c3e2STyler Dauwalder t.bits.type = type; 454ead0c3e2STyler Dauwalder set_type_and_length(t.type_and_length); 455ead0c3e2STyler Dauwalder } set_lengthshort_address456ead0c3e2STyler Dauwalder void set_length(uint32 length) { 457ead0c3e2STyler Dauwalder type_and_length_accessor t; 458ead0c3e2STyler Dauwalder t.type_and_length = type_and_length(); 459ead0c3e2STyler Dauwalder t.bits.length = length; 460ead0c3e2STyler Dauwalder set_type_and_length(t.type_and_length); 461ead0c3e2STyler Dauwalder } set_blockshort_address462ead0c3e2STyler Dauwalder void set_block(uint32 block) { _block = B_HOST_TO_LENDIAN_INT32(block); } 463ead0c3e2STyler Dauwalder private: type_and_lengthshort_address464ead0c3e2STyler Dauwalder uint32 type_and_length() const { return B_LENDIAN_TO_HOST_INT32(_type_and_length); } set_type_and_lengthshort_address465ead0c3e2STyler Dauwalder void set_type_and_length(uint32 value) { _type_and_length = B_HOST_TO_LENDIAN_INT32(value); } 466ead0c3e2STyler Dauwalder 467ead0c3e2STyler Dauwalder uint32 _type_and_length; 468ead0c3e2STyler Dauwalder uint32 _block; 469ead0c3e2STyler Dauwalder } __attribute__((packed)); 470ead0c3e2STyler Dauwalder 471ead0c3e2STyler Dauwalder 472ead0c3e2STyler Dauwalder /*! \brief Allocation descriptor w/ 6 byte implementation use field. 473ead0c3e2STyler Dauwalder 474ead0c3e2STyler Dauwalder See also: ECMA 167 4/14.14.2 475ead0c3e2STyler Dauwalder */ 476ead0c3e2STyler Dauwalder struct long_address { 477ead0c3e2STyler Dauwalder private: 478ead0c3e2STyler Dauwalder union type_and_length_accessor { 479ead0c3e2STyler Dauwalder uint32 type_and_length; 480ead0c3e2STyler Dauwalder struct { 481ead0c3e2STyler Dauwalder uint32 length:30, 482ead0c3e2STyler Dauwalder type:2; 483ead0c3e2STyler Dauwalder } bits; 484ead0c3e2STyler Dauwalder }; 485ead0c3e2STyler Dauwalder 486ead0c3e2STyler Dauwalder public: 487d1a0387eSTyler Dauwalder long_address(uint16 partition = 0, uint32 block = 0, uint32 length = 0, 488d1a0387eSTyler Dauwalder uint8 type = 0); 489d1a0387eSTyler Dauwalder 490ead0c3e2STyler Dauwalder void dump() const; 491ead0c3e2STyler Dauwalder typelong_address492ead0c3e2STyler Dauwalder uint8 type() const { 493ead0c3e2STyler Dauwalder type_and_length_accessor t; 494ead0c3e2STyler Dauwalder t.type_and_length = type_and_length(); 495ead0c3e2STyler Dauwalder return t.bits.type; 496ead0c3e2STyler Dauwalder } lengthlong_address497ead0c3e2STyler Dauwalder uint32 length() const { 498ead0c3e2STyler Dauwalder type_and_length_accessor t; 499ead0c3e2STyler Dauwalder t.type_and_length = type_and_length(); 500ead0c3e2STyler Dauwalder return t.bits.length; 501ead0c3e2STyler Dauwalder } 502ead0c3e2STyler Dauwalder blocklong_address503ead0c3e2STyler Dauwalder uint32 block() const { return _location.block(); } partitionlong_address504ead0c3e2STyler Dauwalder uint16 partition() const { return _location.partition(); } 505ead0c3e2STyler Dauwalder implementation_uselong_address506ead0c3e2STyler Dauwalder const array<uint8, 6>& implementation_use() const { return _implementation_use; } implementation_uselong_address507ead0c3e2STyler Dauwalder array<uint8, 6>& implementation_use() { return _implementation_use; } 508ead0c3e2STyler Dauwalder flagslong_address50980b849abSTyler Dauwalder uint16 flags() const { return B_LENDIAN_TO_HOST_INT16(_accessor().flags); } unique_idlong_address51080b849abSTyler Dauwalder uint32 unique_id() const { return B_LENDIAN_TO_HOST_INT32(_accessor().unique_id); } 51180b849abSTyler Dauwalder set_typelong_address512ead0c3e2STyler Dauwalder void set_type(uint8 type) { 513ead0c3e2STyler Dauwalder type_and_length_accessor t; 514ead0c3e2STyler Dauwalder t.type_and_length = type_and_length(); 515ead0c3e2STyler Dauwalder t.bits.type = type; 516ead0c3e2STyler Dauwalder set_type_and_length(t.type_and_length); 517ead0c3e2STyler Dauwalder } set_lengthlong_address518ead0c3e2STyler Dauwalder void set_length(uint32 length) { 519ead0c3e2STyler Dauwalder type_and_length_accessor t; 520ead0c3e2STyler Dauwalder t.type_and_length = type_and_length(); 521ead0c3e2STyler Dauwalder t.bits.length = length; 522ead0c3e2STyler Dauwalder set_type_and_length(t.type_and_length); 523ead0c3e2STyler Dauwalder } set_blocklong_address524ead0c3e2STyler Dauwalder void set_block(uint32 block) { _location.set_block(block); } set_partitionlong_address525ead0c3e2STyler Dauwalder void set_partition(uint16 partition) { _location.set_partition(partition); } 526ead0c3e2STyler Dauwalder set_flagslong_address52780b849abSTyler Dauwalder void set_flags(uint16 flags) { _accessor().flags = B_HOST_TO_LENDIAN_INT16(flags); } set_unique_idlong_address52880b849abSTyler Dauwalder void set_unique_id(uint32 id) { _accessor().unique_id = B_HOST_TO_LENDIAN_INT32(id); } 52980b849abSTyler Dauwalder 530ead0c3e2STyler Dauwalder void set_to(uint32 block, uint16 partition, uint32 length = 1, 53180b849abSTyler Dauwalder uint8 type = EXTENT_TYPE_RECORDED, uint16 flags = 0, uint32 unique_id = 0) 532ead0c3e2STyler Dauwalder { 533ead0c3e2STyler Dauwalder set_block(block); 534ead0c3e2STyler Dauwalder set_partition(partition); 535ead0c3e2STyler Dauwalder set_length(length); 536ead0c3e2STyler Dauwalder set_type(type); 53780b849abSTyler Dauwalder set_flags(flags); 53880b849abSTyler Dauwalder set_unique_id(unique_id); 539ead0c3e2STyler Dauwalder } 540ead0c3e2STyler Dauwalder 541ead0c3e2STyler Dauwalder private: 54280b849abSTyler Dauwalder //! See UDF-2.50 2.3.4.3 54380b849abSTyler Dauwalder struct _implementation_use_accessor { 54480b849abSTyler Dauwalder uint16 flags; 54580b849abSTyler Dauwalder uint32 unique_id; 54680b849abSTyler Dauwalder } __attribute__((packed)); 54780b849abSTyler Dauwalder _accessorlong_address54880b849abSTyler Dauwalder _implementation_use_accessor& _accessor() { return 54980b849abSTyler Dauwalder *reinterpret_cast<_implementation_use_accessor*>(implementation_use().data); } _accessorlong_address55080b849abSTyler Dauwalder const _implementation_use_accessor& _accessor() const { return 55180b849abSTyler Dauwalder *reinterpret_cast<const _implementation_use_accessor*>(implementation_use().data); } 55280b849abSTyler Dauwalder type_and_lengthlong_address553ead0c3e2STyler Dauwalder uint32 type_and_length() const { return B_LENDIAN_TO_HOST_INT32(_type_and_length); } set_type_and_lengthlong_address554ead0c3e2STyler Dauwalder void set_type_and_length(uint32 value) { _type_and_length = B_HOST_TO_LENDIAN_INT32(value); } 555ead0c3e2STyler Dauwalder 556ead0c3e2STyler Dauwalder uint32 _type_and_length; 557ead0c3e2STyler Dauwalder logical_block_address _location; 558ead0c3e2STyler Dauwalder array<uint8, 6> _implementation_use; 559ead0c3e2STyler Dauwalder } __attribute__((packed)); 560ead0c3e2STyler Dauwalder 561ead0c3e2STyler Dauwalder /*! \brief Common tag found at the beginning of most udf descriptor structures. 562ead0c3e2STyler Dauwalder 563ead0c3e2STyler Dauwalder For error checking, \c descriptor_tag structures have: 564ead0c3e2STyler Dauwalder - The disk location of the tag redundantly stored in the tag itself 565ead0c3e2STyler Dauwalder - A checksum value for the tag 566ead0c3e2STyler Dauwalder - A CRC value and length 567ead0c3e2STyler Dauwalder 568ead0c3e2STyler Dauwalder See also: ECMA 167 1/7.2, UDF 2.01 2.2.1, UDF 2.01 2.3.1 569ead0c3e2STyler Dauwalder */ 570ead0c3e2STyler Dauwalder struct descriptor_tag { 571ead0c3e2STyler Dauwalder public: 572ead0c3e2STyler Dauwalder void dump() const; 573ead0c3e2STyler Dauwalder 57404d90c2aSTyler Dauwalder status_t init_check(uint32 block, bool calculateCrc = true); 575ead0c3e2STyler Dauwalder iddescriptor_tag576ead0c3e2STyler Dauwalder uint16 id() const { return B_LENDIAN_TO_HOST_INT16(_id); } versiondescriptor_tag577ead0c3e2STyler Dauwalder uint16 version() const { return B_LENDIAN_TO_HOST_INT16(_version); } checksumdescriptor_tag578ead0c3e2STyler Dauwalder uint8 checksum() const { return _checksum; } serial_numberdescriptor_tag579ead0c3e2STyler Dauwalder uint16 serial_number() const { return B_LENDIAN_TO_HOST_INT16(_serial_number); } crcdescriptor_tag580ead0c3e2STyler Dauwalder uint16 crc() const { return B_LENDIAN_TO_HOST_INT16(_crc); } crc_lengthdescriptor_tag581ead0c3e2STyler Dauwalder uint16 crc_length() const { return B_LENDIAN_TO_HOST_INT16(_crc_length); } locationdescriptor_tag582ead0c3e2STyler Dauwalder uint32 location() const { return B_LENDIAN_TO_HOST_INT32(_location); } 583ead0c3e2STyler Dauwalder set_iddescriptor_tag584ead0c3e2STyler Dauwalder void set_id(uint16 id) { _id = B_HOST_TO_LENDIAN_INT16(id); } set_versiondescriptor_tag585ead0c3e2STyler Dauwalder void set_version(uint16 version) { _version = B_HOST_TO_LENDIAN_INT16(version); } set_checksumdescriptor_tag586ead0c3e2STyler Dauwalder void set_checksum(uint8 checksum) { _checksum = checksum; } set_serial_numberdescriptor_tag587ead0c3e2STyler Dauwalder void set_serial_number(uint16 serial_number) { _serial_number = B_HOST_TO_LENDIAN_INT16(serial_number); } set_crcdescriptor_tag588ead0c3e2STyler Dauwalder void set_crc(uint16 crc) { _crc = B_HOST_TO_LENDIAN_INT16(crc); } set_crc_lengthdescriptor_tag589ead0c3e2STyler Dauwalder void set_crc_length(uint16 crc_length) { _crc_length = B_HOST_TO_LENDIAN_INT16(crc_length); } set_locationdescriptor_tag590ead0c3e2STyler Dauwalder void set_location(uint32 location) { _location = B_HOST_TO_LENDIAN_INT32(location); } 591ead0c3e2STyler Dauwalder 5925a97c04eSTyler Dauwalder /*! \brief Calculates and sets the crc length, crc checksumm, and 5935a97c04eSTyler Dauwalder checksum for the tag. 5945a97c04eSTyler Dauwalder 5955a97c04eSTyler Dauwalder This function should not be called until all member variables in 5965a97c04eSTyler Dauwalder the descriptor_tag's enclosing descriptor and all member variables 5975a97c04eSTyler Dauwalder in the descriptor_tag itself other than crc_length, crc, and checksum 5985a97c04eSTyler Dauwalder have been set (since the checksum is based off of values in the 5995a97c04eSTyler Dauwalder descriptor_tag, and the crc is based off the values in and the 6005a97c04eSTyler Dauwalder size of the enclosing descriptor). 6015a97c04eSTyler Dauwalder 6025a97c04eSTyler Dauwalder \param The tag's enclosing descriptor. 6035a97c04eSTyler Dauwalder \param The size of the tag's enclosing descriptor (including the 6045a97c04eSTyler Dauwalder tag); only necessary if different from sizeof(Descriptor). 6055a97c04eSTyler Dauwalder */ 6065a97c04eSTyler Dauwalder template <class Descriptor> 6075a97c04eSTyler Dauwalder void 6085a97c04eSTyler Dauwalder set_checksums(Descriptor &descriptor, uint16 size = sizeof(Descriptor)) 6095a97c04eSTyler Dauwalder { 6105a97c04eSTyler Dauwalder 6115a97c04eSTyler Dauwalder // check that this tag is actually owned by 6125a97c04eSTyler Dauwalder // the given descriptor 6135a97c04eSTyler Dauwalder if (this == &descriptor.tag()) 6145a97c04eSTyler Dauwalder { 6155a97c04eSTyler Dauwalder // crc_length, based off provided descriptor 6165a97c04eSTyler Dauwalder set_crc_length(size - sizeof(descriptor_tag)); 6175a97c04eSTyler Dauwalder // crc 618c49d6efcSSalvatore Benedetto uint16 crc = calculate_crc(reinterpret_cast<uint8*>(this) 6195a97c04eSTyler Dauwalder + sizeof(descriptor_tag), crc_length()); 6205a97c04eSTyler Dauwalder set_crc(crc); 6215a97c04eSTyler Dauwalder // checksum (which depends on the other two values) 6225a97c04eSTyler Dauwalder uint32 sum = 0; 6235a97c04eSTyler Dauwalder for (int i = 0; i <= 3; i++) 6245a97c04eSTyler Dauwalder sum += reinterpret_cast<uint8*>(this)[i]; 6255a97c04eSTyler Dauwalder for (int i = 5; i <= 15; i++) 6265a97c04eSTyler Dauwalder sum += reinterpret_cast<uint8*>(this)[i]; 6275a97c04eSTyler Dauwalder set_checksum(sum % 256); 6285a97c04eSTyler Dauwalder } 6295a97c04eSTyler Dauwalder } 630ead0c3e2STyler Dauwalder private: 631ead0c3e2STyler Dauwalder uint16 _id; 632ead0c3e2STyler Dauwalder uint16 _version; 633ead0c3e2STyler Dauwalder uint8 _checksum; //!< Sum modulo 256 of bytes 0-3 and 5-15 of this struct. 634ead0c3e2STyler Dauwalder uint8 _reserved; //!< Set to #00. 635ead0c3e2STyler Dauwalder uint16 _serial_number; 636ead0c3e2STyler Dauwalder uint16 _crc; //!< May be 0 if \c crc_length field is 0. 637ead0c3e2STyler Dauwalder /*! \brief Length of the data chunk used to calculate CRC. 638ead0c3e2STyler Dauwalder 639ead0c3e2STyler Dauwalder If 0, no CRC was calculated, and the \c crc field must be 0. 640ead0c3e2STyler Dauwalder 641ead0c3e2STyler Dauwalder According to UDF-2.01 2.3.1.2, the CRC shall be calculated for all descriptors 642ead0c3e2STyler Dauwalder unless otherwise noted, and this field shall be set to: 643ead0c3e2STyler Dauwalder 644ead0c3e2STyler Dauwalder <code>(descriptor length) - (descriptor tag length)</code> 645ead0c3e2STyler Dauwalder */ 646ead0c3e2STyler Dauwalder uint16 _crc_length; 647ead0c3e2STyler Dauwalder /*! \brief Address of this tag within its partition (for error checking). 648ead0c3e2STyler Dauwalder 649ead0c3e2STyler Dauwalder For virtually addressed structures (i.e. those accessed thru a VAT), this 650ead0c3e2STyler Dauwalder shall be the virtual address, not the physical or logical address. 651ead0c3e2STyler Dauwalder */ 652ead0c3e2STyler Dauwalder uint32 _location; 653ead0c3e2STyler Dauwalder 654ead0c3e2STyler Dauwalder } __attribute__((packed)); 655ead0c3e2STyler Dauwalder 656ead0c3e2STyler Dauwalder 657ead0c3e2STyler Dauwalder /*! \c descriptor_tag ::id values 658ead0c3e2STyler Dauwalder */ 659ead0c3e2STyler Dauwalder enum tag_id { 660ead0c3e2STyler Dauwalder TAGID_UNDEFINED = 0, 661ead0c3e2STyler Dauwalder 662ead0c3e2STyler Dauwalder // ECMA 167, PART 3 663ead0c3e2STyler Dauwalder TAGID_PRIMARY_VOLUME_DESCRIPTOR, 664ead0c3e2STyler Dauwalder TAGID_ANCHOR_VOLUME_DESCRIPTOR_POINTER, 665ead0c3e2STyler Dauwalder TAGID_VOLUME_DESCRIPTOR_POINTER, 666ead0c3e2STyler Dauwalder TAGID_IMPLEMENTATION_USE_VOLUME_DESCRIPTOR, 667ead0c3e2STyler Dauwalder TAGID_PARTITION_DESCRIPTOR, 668ead0c3e2STyler Dauwalder TAGID_LOGICAL_VOLUME_DESCRIPTOR, 669ead0c3e2STyler Dauwalder TAGID_UNALLOCATED_SPACE_DESCRIPTOR, 670ead0c3e2STyler Dauwalder TAGID_TERMINATING_DESCRIPTOR, 671ead0c3e2STyler Dauwalder TAGID_LOGICAL_VOLUME_INTEGRITY_DESCRIPTOR, 672ead0c3e2STyler Dauwalder 673ead0c3e2STyler Dauwalder TAGID_CUSTOM_START = 65280, 674ead0c3e2STyler Dauwalder TAGID_CUSTOM_END = 65535, 675ead0c3e2STyler Dauwalder 676ead0c3e2STyler Dauwalder // ECMA 167, PART 4 677ead0c3e2STyler Dauwalder TAGID_FILE_SET_DESCRIPTOR = 256, 6784f0e6a75STyler Dauwalder TAGID_FILE_ID_DESCRIPTOR, 679ead0c3e2STyler Dauwalder TAGID_ALLOCATION_EXTENT_DESCRIPTOR, 680ead0c3e2STyler Dauwalder TAGID_INDIRECT_ENTRY, 681ead0c3e2STyler Dauwalder TAGID_TERMINAL_ENTRY, 682ead0c3e2STyler Dauwalder TAGID_FILE_ENTRY, 683ead0c3e2STyler Dauwalder TAGID_EXTENDED_ATTRIBUTE_HEADER_DESCRIPTOR, 684ead0c3e2STyler Dauwalder TAGID_UNALLOCATED_SPACE_ENTRY, 685ead0c3e2STyler Dauwalder TAGID_SPACE_BITMAP_DESCRIPTOR, 686ead0c3e2STyler Dauwalder TAGID_PARTITION_INTEGRITY_ENTRY, 687ead0c3e2STyler Dauwalder TAGID_EXTENDED_FILE_ENTRY, 688ead0c3e2STyler Dauwalder }; 689ead0c3e2STyler Dauwalder 690ead0c3e2STyler Dauwalder const char *tag_id_to_string(tag_id id); 691ead0c3e2STyler Dauwalder 692e05a3e1eSTyler Dauwalder extern const uint16 kCrcTable[256]; 693e05a3e1eSTyler Dauwalder 694ead0c3e2STyler Dauwalder /*! \brief Primary volume descriptor 695ead0c3e2STyler Dauwalder */ 696ead0c3e2STyler Dauwalder struct primary_volume_descriptor { 697ead0c3e2STyler Dauwalder public: 698ead0c3e2STyler Dauwalder void dump() const; 699ead0c3e2STyler Dauwalder 700ead0c3e2STyler Dauwalder // Get functions tagprimary_volume_descriptor701ead0c3e2STyler Dauwalder const descriptor_tag & tag() const { return _tag; } tagprimary_volume_descriptor702ead0c3e2STyler Dauwalder descriptor_tag & tag() { return _tag; } 703ead0c3e2STyler Dauwalder vds_numberprimary_volume_descriptor704ead0c3e2STyler Dauwalder uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); } primary_volume_descriptor_numberprimary_volume_descriptor705ead0c3e2STyler Dauwalder uint32 primary_volume_descriptor_number() const { return B_LENDIAN_TO_HOST_INT32(_primary_volume_descriptor_number); } 706ead0c3e2STyler Dauwalder volume_identifierprimary_volume_descriptor707ead0c3e2STyler Dauwalder const array<char, 32>& volume_identifier() const { return _volume_identifier; } volume_identifierprimary_volume_descriptor708ead0c3e2STyler Dauwalder array<char, 32>& volume_identifier() { return _volume_identifier; } 709ead0c3e2STyler Dauwalder volume_sequence_numberprimary_volume_descriptor710ead0c3e2STyler Dauwalder uint16 volume_sequence_number() const { return B_LENDIAN_TO_HOST_INT16(_volume_sequence_number); } max_volume_sequence_numberprimary_volume_descriptor711ead0c3e2STyler Dauwalder uint16 max_volume_sequence_number() const { return B_LENDIAN_TO_HOST_INT16(_max_volume_sequence_number); } interchange_levelprimary_volume_descriptor712ead0c3e2STyler Dauwalder uint16 interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_interchange_level); } max_interchange_levelprimary_volume_descriptor713ead0c3e2STyler Dauwalder uint16 max_interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_max_interchange_level); } character_set_listprimary_volume_descriptor714ead0c3e2STyler Dauwalder uint32 character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_character_set_list); } max_character_set_listprimary_volume_descriptor715ead0c3e2STyler Dauwalder uint32 max_character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_max_character_set_list); } 716ead0c3e2STyler Dauwalder volume_set_identifierprimary_volume_descriptor717ead0c3e2STyler Dauwalder const array<char, 128>& volume_set_identifier() const { return _volume_set_identifier; } volume_set_identifierprimary_volume_descriptor718ead0c3e2STyler Dauwalder array<char, 128>& volume_set_identifier() { return _volume_set_identifier; } 719ead0c3e2STyler Dauwalder descriptor_character_setprimary_volume_descriptor720ead0c3e2STyler Dauwalder const charspec& descriptor_character_set() const { return _descriptor_character_set; } descriptor_character_setprimary_volume_descriptor721ead0c3e2STyler Dauwalder charspec& descriptor_character_set() { return _descriptor_character_set; } 722ead0c3e2STyler Dauwalder explanatory_character_setprimary_volume_descriptor723ead0c3e2STyler Dauwalder const charspec& explanatory_character_set() const { return _explanatory_character_set; } explanatory_character_setprimary_volume_descriptor724ead0c3e2STyler Dauwalder charspec& explanatory_character_set() { return _explanatory_character_set; } 725ead0c3e2STyler Dauwalder volume_abstractprimary_volume_descriptor726ead0c3e2STyler Dauwalder const extent_address& volume_abstract() const { return _volume_abstract; } volume_abstractprimary_volume_descriptor727ead0c3e2STyler Dauwalder extent_address& volume_abstract() { return _volume_abstract; } volume_copyright_noticeprimary_volume_descriptor728ead0c3e2STyler Dauwalder const extent_address& volume_copyright_notice() const { return _volume_copyright_notice; } volume_copyright_noticeprimary_volume_descriptor729ead0c3e2STyler Dauwalder extent_address& volume_copyright_notice() { return _volume_copyright_notice; } 730ead0c3e2STyler Dauwalder application_idprimary_volume_descriptor731ead0c3e2STyler Dauwalder const entity_id& application_id() const { return _application_id; } application_idprimary_volume_descriptor732ead0c3e2STyler Dauwalder entity_id& application_id() { return _application_id; } 733ead0c3e2STyler Dauwalder recording_date_and_timeprimary_volume_descriptor734ead0c3e2STyler Dauwalder const timestamp& recording_date_and_time() const { return _recording_date_and_time; } recording_date_and_timeprimary_volume_descriptor735ead0c3e2STyler Dauwalder timestamp& recording_date_and_time() { return _recording_date_and_time; } 736ead0c3e2STyler Dauwalder implementation_idprimary_volume_descriptor737ead0c3e2STyler Dauwalder const entity_id& implementation_id() const { return _implementation_id; } implementation_idprimary_volume_descriptor738ead0c3e2STyler Dauwalder entity_id& implementation_id() { return _implementation_id; } 739ead0c3e2STyler Dauwalder implementation_useprimary_volume_descriptor740ead0c3e2STyler Dauwalder const array<uint8, 64>& implementation_use() const { return _implementation_use; } implementation_useprimary_volume_descriptor741ead0c3e2STyler Dauwalder array<uint8, 64>& implementation_use() { return _implementation_use; } 742ead0c3e2STyler Dauwalder predecessor_volume_descriptor_sequence_locationprimary_volume_descriptor743ead0c3e2STyler Dauwalder uint32 predecessor_volume_descriptor_sequence_location() const 744ead0c3e2STyler Dauwalder { return B_LENDIAN_TO_HOST_INT32(_predecessor_volume_descriptor_sequence_location); } flagsprimary_volume_descriptor745ead0c3e2STyler Dauwalder uint16 flags() const { return B_LENDIAN_TO_HOST_INT16(_flags); } 746ead0c3e2STyler Dauwalder reservedprimary_volume_descriptor7479b438e89STyler Dauwalder const array<uint8, 22>& reserved() const { return _reserved; } reservedprimary_volume_descriptor7489b438e89STyler Dauwalder array<uint8, 22>& reserved() { return _reserved; } 7499b438e89STyler Dauwalder 750ead0c3e2STyler Dauwalder // Set functions set_vds_numberprimary_volume_descriptor751ead0c3e2STyler Dauwalder void set_vds_number(uint32 number) 752ead0c3e2STyler Dauwalder { _vds_number = B_HOST_TO_LENDIAN_INT32(number); } set_primary_volume_descriptor_numberprimary_volume_descriptor753ead0c3e2STyler Dauwalder void set_primary_volume_descriptor_number(uint32 number) 754ead0c3e2STyler Dauwalder { _primary_volume_descriptor_number = B_HOST_TO_LENDIAN_INT32(number); } set_volume_sequence_numberprimary_volume_descriptor755ead0c3e2STyler Dauwalder void set_volume_sequence_number(uint16 number) 756ead0c3e2STyler Dauwalder { _volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); } set_max_volume_sequence_numberprimary_volume_descriptor757ead0c3e2STyler Dauwalder void set_max_volume_sequence_number(uint16 number) 758ead0c3e2STyler Dauwalder { _max_volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); } set_interchange_levelprimary_volume_descriptor759ead0c3e2STyler Dauwalder void set_interchange_level(uint16 level) 760ead0c3e2STyler Dauwalder { _interchange_level = B_HOST_TO_LENDIAN_INT16(level); } set_max_interchange_levelprimary_volume_descriptor761ead0c3e2STyler Dauwalder void set_max_interchange_level(uint16 level) 762ead0c3e2STyler Dauwalder { _max_interchange_level = B_HOST_TO_LENDIAN_INT16(level); } set_character_set_listprimary_volume_descriptor763ead0c3e2STyler Dauwalder void set_character_set_list(uint32 list) 764ead0c3e2STyler Dauwalder { _character_set_list = B_HOST_TO_LENDIAN_INT32(list); } set_max_character_set_listprimary_volume_descriptor765ead0c3e2STyler Dauwalder void set_max_character_set_list(uint32 list) 766ead0c3e2STyler Dauwalder { _max_character_set_list = B_HOST_TO_LENDIAN_INT32(list); } set_predecessor_volume_descriptor_sequence_locationprimary_volume_descriptor767ead0c3e2STyler Dauwalder void set_predecessor_volume_descriptor_sequence_location(uint32 location) 768ead0c3e2STyler Dauwalder { _predecessor_volume_descriptor_sequence_location = B_HOST_TO_LENDIAN_INT32(location); } set_flagsprimary_volume_descriptor769ead0c3e2STyler Dauwalder void set_flags(uint16 flags) 770ead0c3e2STyler Dauwalder { _flags = B_HOST_TO_LENDIAN_INT16(flags); } 771ead0c3e2STyler Dauwalder 772ead0c3e2STyler Dauwalder private: 773ead0c3e2STyler Dauwalder descriptor_tag _tag; 774ead0c3e2STyler Dauwalder uint32 _vds_number; 775ead0c3e2STyler Dauwalder uint32 _primary_volume_descriptor_number; 776ead0c3e2STyler Dauwalder array<char, 32> _volume_identifier; 777ead0c3e2STyler Dauwalder uint16 _volume_sequence_number; 778ead0c3e2STyler Dauwalder uint16 _max_volume_sequence_number; 779ead0c3e2STyler Dauwalder uint16 _interchange_level; //!< to be set to 3 if part of multivolume set, 2 otherwise 780ead0c3e2STyler Dauwalder uint16 _max_interchange_level; //!< to be set to 3 unless otherwise directed by user 781ead0c3e2STyler Dauwalder uint32 _character_set_list; 782ead0c3e2STyler Dauwalder uint32 _max_character_set_list; 783ead0c3e2STyler Dauwalder array<char, 128> _volume_set_identifier; 784ead0c3e2STyler Dauwalder 785ead0c3e2STyler Dauwalder /*! \brief Identifies the character set for the \c volume_identifier 786ead0c3e2STyler Dauwalder and \c volume_set_identifier fields. 787ead0c3e2STyler Dauwalder 788ead0c3e2STyler Dauwalder To be set to CS0. 789ead0c3e2STyler Dauwalder */ 790ead0c3e2STyler Dauwalder charspec _descriptor_character_set; 791ead0c3e2STyler Dauwalder 792ead0c3e2STyler Dauwalder /*! \brief Identifies the character set used in the \c volume_abstract 793ead0c3e2STyler Dauwalder and \c volume_copyright_notice extents. 794ead0c3e2STyler Dauwalder 795ead0c3e2STyler Dauwalder To be set to CS0. 796ead0c3e2STyler Dauwalder */ 797ead0c3e2STyler Dauwalder charspec _explanatory_character_set; 798ead0c3e2STyler Dauwalder 799ead0c3e2STyler Dauwalder extent_address _volume_abstract; 800ead0c3e2STyler Dauwalder extent_address _volume_copyright_notice; 801ead0c3e2STyler Dauwalder 802ead0c3e2STyler Dauwalder entity_id _application_id; 803ead0c3e2STyler Dauwalder timestamp _recording_date_and_time; 804ead0c3e2STyler Dauwalder entity_id _implementation_id; 805ead0c3e2STyler Dauwalder array<uint8, 64> _implementation_use; 806ead0c3e2STyler Dauwalder uint32 _predecessor_volume_descriptor_sequence_location; 807ead0c3e2STyler Dauwalder uint16 _flags; 8089b438e89STyler Dauwalder array<uint8, 22> _reserved; 809ead0c3e2STyler Dauwalder 810ead0c3e2STyler Dauwalder } __attribute__((packed)); 811ead0c3e2STyler Dauwalder 812ead0c3e2STyler Dauwalder 813ead0c3e2STyler Dauwalder /*! \brief Anchor Volume Descriptor Pointer 814ead0c3e2STyler Dauwalder 815ead0c3e2STyler Dauwalder vd recorded at preset locations in the partition, used as a reference 816ead0c3e2STyler Dauwalder point to the main vd sequences 817ead0c3e2STyler Dauwalder 818ead0c3e2STyler Dauwalder According to UDF 2.01, an avdp shall be recorded in at least 2 of 819ead0c3e2STyler Dauwalder the 3 following locations, where N is the last recordable sector 820ead0c3e2STyler Dauwalder of the partition: 821ead0c3e2STyler Dauwalder - 256 822ead0c3e2STyler Dauwalder - (N - 256) 823ead0c3e2STyler Dauwalder - N 824ead0c3e2STyler Dauwalder 825ead0c3e2STyler Dauwalder See also: ECMA 167 3/10.2, UDF-2.01 2.2.3 826ead0c3e2STyler Dauwalder */ 827ead0c3e2STyler Dauwalder struct anchor_volume_descriptor { 828ead0c3e2STyler Dauwalder public: anchor_volume_descriptoranchor_volume_descriptor82910186d5dSTyler Dauwalder anchor_volume_descriptor() { memset(_reserved.data, 0, _reserved.size()); } 830ead0c3e2STyler Dauwalder void dump() const; 831ead0c3e2STyler Dauwalder taganchor_volume_descriptor832ead0c3e2STyler Dauwalder descriptor_tag & tag() { return _tag; } taganchor_volume_descriptor833ead0c3e2STyler Dauwalder const descriptor_tag & tag() const { return _tag; } 834ead0c3e2STyler Dauwalder main_vdsanchor_volume_descriptor835ead0c3e2STyler Dauwalder extent_address& main_vds() { return _main_vds; } main_vdsanchor_volume_descriptor836ead0c3e2STyler Dauwalder const extent_address& main_vds() const { return _main_vds; } 837ead0c3e2STyler Dauwalder reserve_vdsanchor_volume_descriptor838ead0c3e2STyler Dauwalder extent_address& reserve_vds() { return _reserve_vds; } reserve_vdsanchor_volume_descriptor839ead0c3e2STyler Dauwalder const extent_address& reserve_vds() const { return _reserve_vds; } 840ead0c3e2STyler Dauwalder private: 841ead0c3e2STyler Dauwalder descriptor_tag _tag; 842ead0c3e2STyler Dauwalder extent_address _main_vds; //!< min length of 16 sectors 843ead0c3e2STyler Dauwalder extent_address _reserve_vds; //!< min length of 16 sectors 84410186d5dSTyler Dauwalder array<uint8, 480> _reserved; 845ead0c3e2STyler Dauwalder } __attribute__((packed)); 846ead0c3e2STyler Dauwalder 847ead0c3e2STyler Dauwalder 848ead0c3e2STyler Dauwalder /*! \brief Volume Descriptor Pointer 849ead0c3e2STyler Dauwalder 850ead0c3e2STyler Dauwalder Used to chain extents of volume descriptor sequences together. 851ead0c3e2STyler Dauwalder 852ead0c3e2STyler Dauwalder See also: ECMA 167 3/10.3 853ead0c3e2STyler Dauwalder */ 854ead0c3e2STyler Dauwalder struct descriptor_pointer { 855ead0c3e2STyler Dauwalder descriptor_tag tag; 856ead0c3e2STyler Dauwalder uint32 vds_number; 857ead0c3e2STyler Dauwalder extent_address next; 858ead0c3e2STyler Dauwalder } __attribute__((packed)); 859ead0c3e2STyler Dauwalder 860ead0c3e2STyler Dauwalder 8619a043bf9STyler Dauwalder /*! \brief UDF Implementation Use Volume Descriptor struct found in 8629a043bf9STyler Dauwalder implementation_use() field of implementation_use_descriptor when 8639a043bf9STyler Dauwalder said descriptor's implementation_id() field specifies "*UDF LV Info" 8649a043bf9STyler Dauwalder 8659a043bf9STyler Dauwalder See also: UDF 2.50 2.2.7 8669a043bf9STyler Dauwalder */ 8679a043bf9STyler Dauwalder struct logical_volume_info { 8689a043bf9STyler Dauwalder public: 8699a043bf9STyler Dauwalder void dump() const; 8709a043bf9STyler Dauwalder character_setlogical_volume_info8719a043bf9STyler Dauwalder charspec& character_set() { return _character_set; } character_setlogical_volume_info8729a043bf9STyler Dauwalder const charspec& character_set() const { return _character_set; } 8739a043bf9STyler Dauwalder logical_volume_idlogical_volume_info8749a043bf9STyler Dauwalder array<char, 128>& logical_volume_id() { return _logical_volume_id; } logical_volume_idlogical_volume_info8759a043bf9STyler Dauwalder const array<char, 128>& logical_volume_id() const { return _logical_volume_id; } 8769a043bf9STyler Dauwalder logical_volume_info_1logical_volume_info8779a043bf9STyler Dauwalder array<char, 36>& logical_volume_info_1() { return _logical_volume_info.data[0]; } logical_volume_info_1logical_volume_info8789a043bf9STyler Dauwalder const array<char, 36>& logical_volume_info_1() const { return _logical_volume_info.data[0]; } 8799a043bf9STyler Dauwalder logical_volume_info_2logical_volume_info8809a043bf9STyler Dauwalder array<char, 36>& logical_volume_info_2() { return _logical_volume_info.data[1]; } logical_volume_info_2logical_volume_info8819a043bf9STyler Dauwalder const array<char, 36>& logical_volume_info_2() const { return _logical_volume_info.data[1]; } 8829a043bf9STyler Dauwalder logical_volume_info_3logical_volume_info8839a043bf9STyler Dauwalder array<char, 36>& logical_volume_info_3() { return _logical_volume_info.data[2]; } logical_volume_info_3logical_volume_info8849a043bf9STyler Dauwalder const array<char, 36>& logical_volume_info_3() const { return _logical_volume_info.data[2]; } 8859a043bf9STyler Dauwalder implementation_idlogical_volume_info8869a043bf9STyler Dauwalder entity_id& implementation_id() { return _implementation_id; } implementation_idlogical_volume_info8879a043bf9STyler Dauwalder const entity_id& implementation_id() const { return _implementation_id; } 8889a043bf9STyler Dauwalder implementation_uselogical_volume_info8899a043bf9STyler Dauwalder array<uint8, 128>& implementation_use() { return _implementation_use; } implementation_uselogical_volume_info8909a043bf9STyler Dauwalder const array<uint8, 128>& implementation_use() const { return _implementation_use; } 8919a043bf9STyler Dauwalder private: 8929a043bf9STyler Dauwalder charspec _character_set; 8939a043bf9STyler Dauwalder array<char, 128> _logical_volume_id; // d-string 8949a043bf9STyler Dauwalder array<array<char, 36>, 3> _logical_volume_info; // d-strings 8959a043bf9STyler Dauwalder entity_id _implementation_id; 8969a043bf9STyler Dauwalder array<uint8, 128> _implementation_use; 8979a043bf9STyler Dauwalder } __attribute__((packed)); 8989a043bf9STyler Dauwalder 899ead0c3e2STyler Dauwalder /*! \brief Implementation Use Volume Descriptor 900ead0c3e2STyler Dauwalder 901ead0c3e2STyler Dauwalder See also: ECMA 167 3/10.4 902ead0c3e2STyler Dauwalder */ 903ead0c3e2STyler Dauwalder struct implementation_use_descriptor { 904ead0c3e2STyler Dauwalder public: 905ead0c3e2STyler Dauwalder void dump() const; 906ead0c3e2STyler Dauwalder 907ead0c3e2STyler Dauwalder // Get functions tagimplementation_use_descriptor908ead0c3e2STyler Dauwalder const descriptor_tag & tag() const { return _tag; } tagimplementation_use_descriptor909ead0c3e2STyler Dauwalder descriptor_tag & tag() { return _tag; } 910ead0c3e2STyler Dauwalder vds_numberimplementation_use_descriptor911ead0c3e2STyler Dauwalder uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); } 912ead0c3e2STyler Dauwalder implementation_idimplementation_use_descriptor913ead0c3e2STyler Dauwalder const entity_id& implementation_id() const { return _implementation_id; } implementation_idimplementation_use_descriptor914ead0c3e2STyler Dauwalder entity_id& implementation_id() { return _implementation_id; } 915ead0c3e2STyler Dauwalder implementation_useimplementation_use_descriptor916ead0c3e2STyler Dauwalder const array<uint8, 460>& implementation_use() const { return _implementation_use; } implementation_useimplementation_use_descriptor917ead0c3e2STyler Dauwalder array<uint8, 460>& implementation_use() { return _implementation_use; } 918ead0c3e2STyler Dauwalder 9199a043bf9STyler Dauwalder // Only valid if implementation_id() returns Udf::kLogicalVolumeInfoId. infoimplementation_use_descriptor9209a043bf9STyler Dauwalder logical_volume_info& info() { return *reinterpret_cast<logical_volume_info*>(_implementation_use.data); } infoimplementation_use_descriptor9219a043bf9STyler Dauwalder const logical_volume_info& info() const { return *reinterpret_cast<const logical_volume_info*>(_implementation_use.data); } 9229a043bf9STyler Dauwalder 923ead0c3e2STyler Dauwalder // Set functions set_vds_numberimplementation_use_descriptor924ead0c3e2STyler Dauwalder void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); } 925ead0c3e2STyler Dauwalder private: 926ead0c3e2STyler Dauwalder descriptor_tag _tag; 927ead0c3e2STyler Dauwalder uint32 _vds_number; 928ead0c3e2STyler Dauwalder entity_id _implementation_id; 929ead0c3e2STyler Dauwalder array<uint8, 460> _implementation_use; 930ead0c3e2STyler Dauwalder } __attribute__((packed)); 931ead0c3e2STyler Dauwalder 932ead0c3e2STyler Dauwalder 933ead0c3e2STyler Dauwalder /*! \brief Maximum number of partition descriptors to be found in volume 934ead0c3e2STyler Dauwalder descriptor sequence, per UDF-2.50 935ead0c3e2STyler Dauwalder */ 936*9c707f06SJonathan Schleifer const uint8 kMaxPartitionDescriptors = 2; 937ead0c3e2STyler Dauwalder #define UDF_MAX_PARTITION_MAPS 2 938ead0c3e2STyler Dauwalder #define UDF_MAX_PARTITION_MAP_SIZE 64 939ead0c3e2STyler Dauwalder 940ead0c3e2STyler Dauwalder /*! \brief Partition Descriptor 941ead0c3e2STyler Dauwalder 942ead0c3e2STyler Dauwalder See also: ECMA 167 3/10.5 943ead0c3e2STyler Dauwalder */ 944ead0c3e2STyler Dauwalder struct partition_descriptor { 945ead0c3e2STyler Dauwalder private: 946ead0c3e2STyler Dauwalder union partition_flags_accessor { 947ead0c3e2STyler Dauwalder uint16 partition_flags; 948ead0c3e2STyler Dauwalder struct { 949ead0c3e2STyler Dauwalder uint16 allocated:1, 950ead0c3e2STyler Dauwalder reserved:15; 951ead0c3e2STyler Dauwalder } bits; 952ead0c3e2STyler Dauwalder }; 953ead0c3e2STyler Dauwalder 954ead0c3e2STyler Dauwalder public: 955ead0c3e2STyler Dauwalder void dump() const; 956ead0c3e2STyler Dauwalder 957ead0c3e2STyler Dauwalder // Get functions tagpartition_descriptor958ead0c3e2STyler Dauwalder const descriptor_tag & tag() const { return _tag; } tagpartition_descriptor959ead0c3e2STyler Dauwalder descriptor_tag & tag() { return _tag; } 960ead0c3e2STyler Dauwalder vds_numberpartition_descriptor961ead0c3e2STyler Dauwalder uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); } partition_flagspartition_descriptor962ead0c3e2STyler Dauwalder uint16 partition_flags() const { return B_LENDIAN_TO_HOST_INT16(_partition_flags); } allocatedpartition_descriptor963ead0c3e2STyler Dauwalder bool allocated() const { 964ead0c3e2STyler Dauwalder partition_flags_accessor f; 965ead0c3e2STyler Dauwalder f.partition_flags = partition_flags(); 966ead0c3e2STyler Dauwalder return f.bits.allocated; 967ead0c3e2STyler Dauwalder } partition_numberpartition_descriptor968ead0c3e2STyler Dauwalder uint16 partition_number() const { return B_LENDIAN_TO_HOST_INT16(_partition_number); } 969ead0c3e2STyler Dauwalder partition_contentspartition_descriptor970ead0c3e2STyler Dauwalder const entity_id& partition_contents() const { return _partition_contents; } partition_contentspartition_descriptor971ead0c3e2STyler Dauwalder entity_id& partition_contents() { return _partition_contents; } 972ead0c3e2STyler Dauwalder partition_contents_usepartition_descriptor973ead0c3e2STyler Dauwalder const array<uint8, 128>& partition_contents_use() const { return _partition_contents_use; } partition_contents_usepartition_descriptor974ead0c3e2STyler Dauwalder array<uint8, 128>& partition_contents_use() { return _partition_contents_use; } 975ead0c3e2STyler Dauwalder access_typepartition_descriptor976ead0c3e2STyler Dauwalder uint32 access_type() const { return B_LENDIAN_TO_HOST_INT32(_access_type); } startpartition_descriptor977ead0c3e2STyler Dauwalder uint32 start() const { return B_LENDIAN_TO_HOST_INT32(_start); } lengthpartition_descriptor978ead0c3e2STyler Dauwalder uint32 length() const { return B_LENDIAN_TO_HOST_INT32(_length); } 979ead0c3e2STyler Dauwalder implementation_idpartition_descriptor980ead0c3e2STyler Dauwalder const entity_id& implementation_id() const { return _implementation_id; } implementation_idpartition_descriptor981ead0c3e2STyler Dauwalder entity_id& implementation_id() { return _implementation_id; } 982ead0c3e2STyler Dauwalder implementation_usepartition_descriptor983ead0c3e2STyler Dauwalder const array<uint8, 128>& implementation_use() const { return _implementation_use; } implementation_usepartition_descriptor984ead0c3e2STyler Dauwalder array<uint8, 128>& implementation_use() { return _implementation_use; } 985ead0c3e2STyler Dauwalder reservedpartition_descriptor986003d4e83STyler Dauwalder const array<uint8, 156>& reserved() const { return _reserved; } reservedpartition_descriptor987003d4e83STyler Dauwalder array<uint8, 156>& reserved() { return _reserved; } 988003d4e83STyler Dauwalder 989ead0c3e2STyler Dauwalder // Set functions set_vds_numberpartition_descriptor990ead0c3e2STyler Dauwalder void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); } set_partition_flagspartition_descriptor991ead0c3e2STyler Dauwalder void set_partition_flags(uint16 flags) { _partition_flags = B_HOST_TO_LENDIAN_INT16(flags); } set_allocatedpartition_descriptor992ead0c3e2STyler Dauwalder void set_allocated(bool allocated) { 993ead0c3e2STyler Dauwalder partition_flags_accessor f; 994ead0c3e2STyler Dauwalder f.partition_flags = partition_flags(); 995ead0c3e2STyler Dauwalder f.bits.allocated = allocated; 996ead0c3e2STyler Dauwalder set_partition_flags(f.partition_flags); 997ead0c3e2STyler Dauwalder } set_partition_numberpartition_descriptor998003d4e83STyler Dauwalder void set_partition_number(uint16 number) { _partition_number = B_HOST_TO_LENDIAN_INT16(number); } set_access_typepartition_descriptor999ead0c3e2STyler Dauwalder void set_access_type(uint32 type) { _access_type = B_HOST_TO_LENDIAN_INT32(type); } set_startpartition_descriptor1000ead0c3e2STyler Dauwalder void set_start(uint32 start) { _start = B_HOST_TO_LENDIAN_INT32(start); } set_lengthpartition_descriptor1001ead0c3e2STyler Dauwalder void set_length(uint32 length) { _length = B_HOST_TO_LENDIAN_INT32(length); } 1002ead0c3e2STyler Dauwalder 1003ead0c3e2STyler Dauwalder private: 1004ead0c3e2STyler Dauwalder descriptor_tag _tag; 1005ead0c3e2STyler Dauwalder uint32 _vds_number; 1006ead0c3e2STyler Dauwalder /*! Bit 0: If 0, shall mean volume space has not been allocated. If 1, 1007ead0c3e2STyler Dauwalder shall mean volume space has been allocated. 1008ead0c3e2STyler Dauwalder */ 1009ead0c3e2STyler Dauwalder uint16 _partition_flags; 1010ead0c3e2STyler Dauwalder uint16 _partition_number; 1011ead0c3e2STyler Dauwalder 1012ead0c3e2STyler Dauwalder /*! - "+NSR03" Volume recorded according to ECMA-167, i.e. UDF 1013ead0c3e2STyler Dauwalder - "+CD001" Volume recorded according to ECMA-119, i.e. iso9660 1014ead0c3e2STyler Dauwalder - "+FDC01" Volume recorded according to ECMA-107 1015ead0c3e2STyler Dauwalder - "+CDW02" Volume recorded according to ECMA-168 1016ead0c3e2STyler Dauwalder */ 1017ead0c3e2STyler Dauwalder entity_id _partition_contents; 1018ead0c3e2STyler Dauwalder array<uint8, 128> _partition_contents_use; 1019ead0c3e2STyler Dauwalder 1020ead0c3e2STyler Dauwalder /*! See \c partition_access_type enum 1021ead0c3e2STyler Dauwalder */ 1022ead0c3e2STyler Dauwalder uint32 _access_type; 1023ead0c3e2STyler Dauwalder uint32 _start; 1024ead0c3e2STyler Dauwalder uint32 _length; 1025ead0c3e2STyler Dauwalder entity_id _implementation_id; 1026ead0c3e2STyler Dauwalder array<uint8, 128> _implementation_use; 1027003d4e83STyler Dauwalder array<uint8, 156> _reserved; 1028ead0c3e2STyler Dauwalder } __attribute__((packed)); 1029ead0c3e2STyler Dauwalder 1030ead0c3e2STyler Dauwalder 1031ead0c3e2STyler Dauwalder enum partition_access_type { 1032003d4e83STyler Dauwalder ACCESS_UNSPECIFIED, 1033003d4e83STyler Dauwalder ACCESS_READ_ONLY, 1034003d4e83STyler Dauwalder ACCESS_WRITE_ONCE, 1035003d4e83STyler Dauwalder ACCESS_REWRITABLE, 1036003d4e83STyler Dauwalder ACCESS_OVERWRITABLE, 1037ead0c3e2STyler Dauwalder }; 1038ead0c3e2STyler Dauwalder 1039ead0c3e2STyler Dauwalder 1040ead0c3e2STyler Dauwalder /*! \brief Logical volume descriptor 1041ead0c3e2STyler Dauwalder 1042ead0c3e2STyler Dauwalder See also: ECMA 167 3/10.6, UDF-2.01 2.2.4 1043ead0c3e2STyler Dauwalder */ 1044ead0c3e2STyler Dauwalder struct logical_volume_descriptor { 1045ead0c3e2STyler Dauwalder void dump() const; 1046ead0c3e2STyler Dauwalder 1047ead0c3e2STyler Dauwalder // Get functions taglogical_volume_descriptor1048ead0c3e2STyler Dauwalder const descriptor_tag & tag() const { return _tag; } taglogical_volume_descriptor1049ead0c3e2STyler Dauwalder descriptor_tag & tag() { return _tag; } 1050ead0c3e2STyler Dauwalder vds_numberlogical_volume_descriptor1051ead0c3e2STyler Dauwalder uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); } 1052ead0c3e2STyler Dauwalder character_setlogical_volume_descriptor1053ead0c3e2STyler Dauwalder const charspec& character_set() const { return _character_set; } character_setlogical_volume_descriptor1054ead0c3e2STyler Dauwalder charspec& character_set() { return _character_set; } 1055ead0c3e2STyler Dauwalder logical_volume_identifierlogical_volume_descriptor1056ead0c3e2STyler Dauwalder const array<char, 128>& logical_volume_identifier() const { return _logical_volume_identifier; } logical_volume_identifierlogical_volume_descriptor1057ead0c3e2STyler Dauwalder array<char, 128>& logical_volume_identifier() { return _logical_volume_identifier; } 1058ead0c3e2STyler Dauwalder logical_block_sizelogical_volume_descriptor1059ead0c3e2STyler Dauwalder uint32 logical_block_size() const { return B_LENDIAN_TO_HOST_INT32(_logical_block_size); } 1060ead0c3e2STyler Dauwalder domain_idlogical_volume_descriptor1061ead0c3e2STyler Dauwalder const entity_id& domain_id() const { return _domain_id; } domain_idlogical_volume_descriptor1062ead0c3e2STyler Dauwalder entity_id& domain_id() { return _domain_id; } 1063ead0c3e2STyler Dauwalder logical_volume_contents_uselogical_volume_descriptor1064ead0c3e2STyler Dauwalder const array<uint8, 16>& logical_volume_contents_use() const { return _logical_volume_contents_use; } logical_volume_contents_uselogical_volume_descriptor1065ead0c3e2STyler Dauwalder array<uint8, 16>& logical_volume_contents_use() { return _logical_volume_contents_use; } 1066ead0c3e2STyler Dauwalder file_set_addresslogical_volume_descriptor1067d1a0387eSTyler Dauwalder const long_address& file_set_address() const { return *reinterpret_cast<const long_address*>(&_logical_volume_contents_use); } file_set_addresslogical_volume_descriptor1068d1a0387eSTyler Dauwalder long_address& file_set_address() { return *reinterpret_cast<long_address*>(&_logical_volume_contents_use); } 1069ead0c3e2STyler Dauwalder map_table_lengthlogical_volume_descriptor1070ead0c3e2STyler Dauwalder uint32 map_table_length() const { return B_LENDIAN_TO_HOST_INT32(_map_table_length); } partition_map_countlogical_volume_descriptor1071ead0c3e2STyler Dauwalder uint32 partition_map_count() const { return B_LENDIAN_TO_HOST_INT32(_partition_map_count); } 1072ead0c3e2STyler Dauwalder implementation_idlogical_volume_descriptor1073ead0c3e2STyler Dauwalder const entity_id& implementation_id() const { return _implementation_id; } implementation_idlogical_volume_descriptor1074ead0c3e2STyler Dauwalder entity_id& implementation_id() { return _implementation_id; } 1075ead0c3e2STyler Dauwalder implementation_uselogical_volume_descriptor1076ead0c3e2STyler Dauwalder const array<uint8, 128>& implementation_use() const { return _implementation_use; } implementation_uselogical_volume_descriptor1077ead0c3e2STyler Dauwalder array<uint8, 128>& implementation_use() { return _implementation_use; } 1078ead0c3e2STyler Dauwalder integrity_sequence_extentlogical_volume_descriptor1079ead0c3e2STyler Dauwalder const extent_address& integrity_sequence_extent() const { return _integrity_sequence_extent; } integrity_sequence_extentlogical_volume_descriptor1080ead0c3e2STyler Dauwalder extent_address& integrity_sequence_extent() { return _integrity_sequence_extent; } 1081ead0c3e2STyler Dauwalder partition_mapslogical_volume_descriptor1082ead0c3e2STyler Dauwalder const uint8* partition_maps() const { return _partition_maps; } partition_mapslogical_volume_descriptor1083ead0c3e2STyler Dauwalder uint8* partition_maps() { return _partition_maps; } 1084ead0c3e2STyler Dauwalder 1085ead0c3e2STyler Dauwalder // Set functions set_vds_numberlogical_volume_descriptor1086ead0c3e2STyler Dauwalder void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); } set_logical_block_sizelogical_volume_descriptor1087ead0c3e2STyler Dauwalder void set_logical_block_size(uint32 size) { _logical_block_size = B_HOST_TO_LENDIAN_INT32(size); } 1088ead0c3e2STyler Dauwalder set_map_table_lengthlogical_volume_descriptor1089ead0c3e2STyler Dauwalder void set_map_table_length(uint32 length) { _map_table_length = B_HOST_TO_LENDIAN_INT32(length); } set_partition_map_countlogical_volume_descriptor1090ead0c3e2STyler Dauwalder void set_partition_map_count(uint32 count) { _partition_map_count = B_HOST_TO_LENDIAN_INT32(count); } 1091ead0c3e2STyler Dauwalder 1092ead0c3e2STyler Dauwalder // Other functions 1093ead0c3e2STyler Dauwalder logical_volume_descriptor& operator=(const logical_volume_descriptor &rhs); 1094ead0c3e2STyler Dauwalder 1095ead0c3e2STyler Dauwalder private: 1096ead0c3e2STyler Dauwalder descriptor_tag _tag; 1097ead0c3e2STyler Dauwalder uint32 _vds_number; 1098ead0c3e2STyler Dauwalder 1099ead0c3e2STyler Dauwalder /*! \brief Identifies the character set for the 1100ead0c3e2STyler Dauwalder \c logical_volume_identifier field. 1101ead0c3e2STyler Dauwalder 1102ead0c3e2STyler Dauwalder To be set to CS0. 1103ead0c3e2STyler Dauwalder */ 1104ead0c3e2STyler Dauwalder charspec _character_set; 1105ead0c3e2STyler Dauwalder array<char, 128> _logical_volume_identifier; 1106ead0c3e2STyler Dauwalder uint32 _logical_block_size; 1107ead0c3e2STyler Dauwalder 1108ead0c3e2STyler Dauwalder /*! \brief To be set to 0 or "*OSTA UDF Compliant". See UDF specs. 1109ead0c3e2STyler Dauwalder */ 1110ead0c3e2STyler Dauwalder entity_id _domain_id; 1111ead0c3e2STyler Dauwalder 1112ead0c3e2STyler Dauwalder /*! \brief For UDF, shall contain a \c long_address which identifies 1113ead0c3e2STyler Dauwalder the location of the logical volume's first file set. 1114ead0c3e2STyler Dauwalder */ 1115ead0c3e2STyler Dauwalder array<uint8, 16> _logical_volume_contents_use; 1116ead0c3e2STyler Dauwalder 1117ead0c3e2STyler Dauwalder uint32 _map_table_length; 1118ead0c3e2STyler Dauwalder uint32 _partition_map_count; 1119ead0c3e2STyler Dauwalder entity_id _implementation_id; 1120ead0c3e2STyler Dauwalder array<uint8, 128> _implementation_use; 1121ead0c3e2STyler Dauwalder 1122ead0c3e2STyler Dauwalder /*! \brief Logical volume integrity sequence location. 1123ead0c3e2STyler Dauwalder 1124ead0c3e2STyler Dauwalder For re/overwritable media, shall be a min of 8KB in length. 1125ead0c3e2STyler Dauwalder For WORM media, shall be quite frickin large, as a new volume 1126ead0c3e2STyler Dauwalder must be added to the set if the extent fills up (since you 1127ead0c3e2STyler Dauwalder can't chain lvis's I guess). 1128ead0c3e2STyler Dauwalder */ 1129ead0c3e2STyler Dauwalder extent_address _integrity_sequence_extent; 1130ead0c3e2STyler Dauwalder 1131ead0c3e2STyler Dauwalder /*! \brief Restricted to maps of type 1 for normal maps and 1132ead0c3e2STyler Dauwalder UDF type 2 for virtual maps or maps on systems not supporting 1133ead0c3e2STyler Dauwalder defect management. 1134ead0c3e2STyler Dauwalder 1135ead0c3e2STyler Dauwalder Note that we actually allocate memory for the partition maps 1136ead0c3e2STyler Dauwalder here due to the fact that we allocate logical_volume_descriptor 1137ead0c3e2STyler Dauwalder objects on the stack sometimes. 1138ead0c3e2STyler Dauwalder 1139ead0c3e2STyler Dauwalder See UDF-2.01 2.2.8, 2.2.9 1140ead0c3e2STyler Dauwalder */ 1141ead0c3e2STyler Dauwalder uint8 _partition_maps[UDF_MAX_PARTITION_MAPS * UDF_MAX_PARTITION_MAP_SIZE]; 1142ead0c3e2STyler Dauwalder } __attribute__((packed)); 1143ead0c3e2STyler Dauwalder 1144730ba00aSTyler Dauwalder //! Base size (excluding partition maps) of lvd 1145730ba00aSTyler Dauwalder extern const uint32 kLogicalVolumeDescriptorBaseSize; 1146ead0c3e2STyler Dauwalder 1147ead0c3e2STyler Dauwalder /*! \brief (Mostly) common portion of various partition maps 1148ead0c3e2STyler Dauwalder 1149ead0c3e2STyler Dauwalder See also: ECMA-167 3/10.7.1 1150ead0c3e2STyler Dauwalder */ 1151ead0c3e2STyler Dauwalder struct partition_map_header { 1152ead0c3e2STyler Dauwalder public: typepartition_map_header1153ead0c3e2STyler Dauwalder uint8 type() const { return _type; } lengthpartition_map_header1154ead0c3e2STyler Dauwalder uint8 length() const { return _length; } map_datapartition_map_header1155ead0c3e2STyler Dauwalder uint8 *map_data() { return _map_data; } map_datapartition_map_header1156ead0c3e2STyler Dauwalder const uint8 *map_data() const { return _map_data; } 1157ead0c3e2STyler Dauwalder partition_type_idpartition_map_header1158ead0c3e2STyler Dauwalder entity_id& partition_type_id() 1159ead0c3e2STyler Dauwalder { return *reinterpret_cast<entity_id*>(&_map_data[2]); } partition_type_idpartition_map_header1160ead0c3e2STyler Dauwalder const entity_id& partition_type_id() const 1161ead0c3e2STyler Dauwalder { return *reinterpret_cast<const entity_id*>(&_map_data[2]); } 1162ead0c3e2STyler Dauwalder set_typepartition_map_header1163ead0c3e2STyler Dauwalder void set_type(uint8 type) { _type = type; } set_lengthpartition_map_header1164ead0c3e2STyler Dauwalder void set_length(uint8 length) { _length = length; } 1165ead0c3e2STyler Dauwalder private: 1166ead0c3e2STyler Dauwalder uint8 _type; 1167ead0c3e2STyler Dauwalder uint8 _length; 1168ead0c3e2STyler Dauwalder uint8 _map_data[0]; 1169ead0c3e2STyler Dauwalder };// __attribute__((packed)); 1170ead0c3e2STyler Dauwalder 1171ead0c3e2STyler Dauwalder 1172ead0c3e2STyler Dauwalder /*! \brief Physical partition map (i.e. ECMA-167 Type 1 partition map) 1173ead0c3e2STyler Dauwalder 1174ead0c3e2STyler Dauwalder See also: ECMA-167 3/10.7.2 1175ead0c3e2STyler Dauwalder */ 1176ead0c3e2STyler Dauwalder struct physical_partition_map { 1177ead0c3e2STyler Dauwalder public: 1178ead0c3e2STyler Dauwalder void dump(); 1179ead0c3e2STyler Dauwalder typephysical_partition_map1180ead0c3e2STyler Dauwalder uint8 type() const { return _type; } lengthphysical_partition_map1181ead0c3e2STyler Dauwalder uint8 length() const { return _length; } 1182ead0c3e2STyler Dauwalder volume_sequence_numberphysical_partition_map1183ead0c3e2STyler Dauwalder uint16 volume_sequence_number() const { 1184ead0c3e2STyler Dauwalder return B_LENDIAN_TO_HOST_INT16(_volume_sequence_number); } partition_numberphysical_partition_map1185ead0c3e2STyler Dauwalder uint16 partition_number() const { 1186ead0c3e2STyler Dauwalder return B_LENDIAN_TO_HOST_INT16(_partition_number); } 1187ead0c3e2STyler Dauwalder set_typephysical_partition_map1188ead0c3e2STyler Dauwalder void set_type(uint8 type) { _type = type; } set_lengthphysical_partition_map1189ead0c3e2STyler Dauwalder void set_length(uint8 length) { _length = length; } set_volume_sequence_numberphysical_partition_map1190ead0c3e2STyler Dauwalder void set_volume_sequence_number(uint16 number) { 1191ead0c3e2STyler Dauwalder _volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); } set_partition_numberphysical_partition_map1192ead0c3e2STyler Dauwalder void set_partition_number(uint16 number) { 1193ead0c3e2STyler Dauwalder _partition_number = B_HOST_TO_LENDIAN_INT16(number); } 1194ead0c3e2STyler Dauwalder private: 1195ead0c3e2STyler Dauwalder uint8 _type; 1196ead0c3e2STyler Dauwalder uint8 _length; 1197ead0c3e2STyler Dauwalder uint16 _volume_sequence_number; 1198ead0c3e2STyler Dauwalder uint16 _partition_number; 1199ead0c3e2STyler Dauwalder } __attribute__((packed)); 1200ead0c3e2STyler Dauwalder 1201ead0c3e2STyler Dauwalder 1202ead0c3e2STyler Dauwalder /* ----UDF Specific---- */ 1203ead0c3e2STyler Dauwalder /*! \brief Virtual partition map 1204ead0c3e2STyler Dauwalder 1205ead0c3e2STyler Dauwalder Note that this map is a customization of the ECMA-167 1206ead0c3e2STyler Dauwalder type 2 partition map. 1207ead0c3e2STyler Dauwalder 1208ead0c3e2STyler Dauwalder See also: UDF-2.01 2.2.8 1209ead0c3e2STyler Dauwalder */ 1210ead0c3e2STyler Dauwalder struct virtual_partition_map { 1211ead0c3e2STyler Dauwalder uint8 type; 1212ead0c3e2STyler Dauwalder uint8 length; 1213ead0c3e2STyler Dauwalder uint8 reserved1[2]; 1214ead0c3e2STyler Dauwalder 1215ead0c3e2STyler Dauwalder /*! - flags: 0 1216ead0c3e2STyler Dauwalder - identifier: "*UDF Virtual Partition" 1217ead0c3e2STyler Dauwalder - identifier_suffix: per UDF-2.01 2.1.5.3 1218ead0c3e2STyler Dauwalder */ 1219ead0c3e2STyler Dauwalder entity_id partition_type_id; 1220ead0c3e2STyler Dauwalder uint16 volume_sequence_number; 1221ead0c3e2STyler Dauwalder 1222ead0c3e2STyler Dauwalder /*! corresponding type 1 partition map in same logical volume 1223ead0c3e2STyler Dauwalder */ 1224ead0c3e2STyler Dauwalder uint16 partition_number; 1225ead0c3e2STyler Dauwalder uint8 reserved2[24]; 1226ead0c3e2STyler Dauwalder } __attribute__((packed)); 1227ead0c3e2STyler Dauwalder 1228ead0c3e2STyler Dauwalder 1229ead0c3e2STyler Dauwalder /*! \brief Maximum number of redundant sparing tables found in 1230ead0c3e2STyler Dauwalder sparable_partition_map structures. 1231ead0c3e2STyler Dauwalder */ 1232ead0c3e2STyler Dauwalder #define UDF_MAX_SPARING_TABLE_COUNT 4 1233ead0c3e2STyler Dauwalder 1234ead0c3e2STyler Dauwalder /* ----UDF Specific---- */ 1235ead0c3e2STyler Dauwalder /*! \brief Sparable partition map 1236ead0c3e2STyler Dauwalder 1237ead0c3e2STyler Dauwalder Note that this map is a customization of the ECMA-167 1238ead0c3e2STyler Dauwalder type 2 partition map. 1239ead0c3e2STyler Dauwalder 1240ead0c3e2STyler Dauwalder See also: UDF-2.01 2.2.9 1241ead0c3e2STyler Dauwalder */ 1242ead0c3e2STyler Dauwalder struct sparable_partition_map { 1243ead0c3e2STyler Dauwalder public: 1244ead0c3e2STyler Dauwalder void dump(); 1245ead0c3e2STyler Dauwalder typesparable_partition_map1246ead0c3e2STyler Dauwalder uint8 type() const { return _type; } lengthsparable_partition_map1247ead0c3e2STyler Dauwalder uint8 length() const { return _length; } 1248ead0c3e2STyler Dauwalder partition_type_idsparable_partition_map1249ead0c3e2STyler Dauwalder entity_id& partition_type_id() { return _partition_type_id; } partition_type_idsparable_partition_map1250ead0c3e2STyler Dauwalder const entity_id& partition_type_id() const { return _partition_type_id; } 1251ead0c3e2STyler Dauwalder volume_sequence_numbersparable_partition_map1252ead0c3e2STyler Dauwalder uint16 volume_sequence_number() const { 1253ead0c3e2STyler Dauwalder return B_LENDIAN_TO_HOST_INT16(_volume_sequence_number); } partition_numbersparable_partition_map1254ead0c3e2STyler Dauwalder uint16 partition_number() const { 1255ead0c3e2STyler Dauwalder return B_LENDIAN_TO_HOST_INT16(_partition_number); } packet_lengthsparable_partition_map1256ead0c3e2STyler Dauwalder uint16 packet_length() const { 1257ead0c3e2STyler Dauwalder return B_LENDIAN_TO_HOST_INT16(_packet_length); } sparing_table_countsparable_partition_map1258ead0c3e2STyler Dauwalder uint8 sparing_table_count() const { return _sparing_table_count; } sparing_table_sizesparable_partition_map1259ead0c3e2STyler Dauwalder uint32 sparing_table_size() const { 1260ead0c3e2STyler Dauwalder return B_LENDIAN_TO_HOST_INT32(_sparing_table_size); } sparing_table_locationsparable_partition_map1261ead0c3e2STyler Dauwalder uint32 sparing_table_location(uint8 index) const { 1262ead0c3e2STyler Dauwalder return B_LENDIAN_TO_HOST_INT32(_sparing_table_locations[index]); } 1263ead0c3e2STyler Dauwalder 1264ead0c3e2STyler Dauwalder set_typesparable_partition_map1265ead0c3e2STyler Dauwalder void set_type(uint8 type) { _type = type; } set_lengthsparable_partition_map1266ead0c3e2STyler Dauwalder void set_length(uint8 length) { _length = length; } set_volume_sequence_numbersparable_partition_map1267ead0c3e2STyler Dauwalder void set_volume_sequence_number(uint16 number) { 1268ead0c3e2STyler Dauwalder _volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); } set_partition_numbersparable_partition_map1269ead0c3e2STyler Dauwalder void set_partition_number(uint16 number) { 1270ead0c3e2STyler Dauwalder _partition_number = B_HOST_TO_LENDIAN_INT16(number); } set_packet_lengthsparable_partition_map1271ead0c3e2STyler Dauwalder void set_packet_length(uint16 length) { 1272ead0c3e2STyler Dauwalder _packet_length = B_HOST_TO_LENDIAN_INT16(length); } set_sparing_table_countsparable_partition_map1273ead0c3e2STyler Dauwalder void set_sparing_table_count(uint8 count) { 1274ead0c3e2STyler Dauwalder _sparing_table_count = count; } set_sparing_table_sizesparable_partition_map1275ead0c3e2STyler Dauwalder void set_sparing_table_size(uint32 size) { 1276ead0c3e2STyler Dauwalder _sparing_table_size = B_HOST_TO_LENDIAN_INT32(size); } set_sparing_table_locationsparable_partition_map1277ead0c3e2STyler Dauwalder void set_sparing_table_location(uint8 index, uint32 location) { 1278ead0c3e2STyler Dauwalder _sparing_table_locations[index] = B_HOST_TO_LENDIAN_INT32(location); } 1279ead0c3e2STyler Dauwalder private: 1280ead0c3e2STyler Dauwalder uint8 _type; 1281ead0c3e2STyler Dauwalder uint8 _length; 1282ead0c3e2STyler Dauwalder uint8 _reserved1[2]; 1283ead0c3e2STyler Dauwalder 1284ead0c3e2STyler Dauwalder /*! - flags: 0 1285ead0c3e2STyler Dauwalder - identifier: "*UDF Sparable Partition" 1286ead0c3e2STyler Dauwalder - identifier_suffix: per UDF-2.01 2.1.5.3 1287ead0c3e2STyler Dauwalder */ 1288ead0c3e2STyler Dauwalder entity_id _partition_type_id; 1289ead0c3e2STyler Dauwalder uint16 _volume_sequence_number; 1290ead0c3e2STyler Dauwalder 1291ead0c3e2STyler Dauwalder //! partition number of corresponding partition descriptor 1292ead0c3e2STyler Dauwalder uint16 _partition_number; 1293ead0c3e2STyler Dauwalder uint16 _packet_length; 1294ead0c3e2STyler Dauwalder uint8 _sparing_table_count; 1295ead0c3e2STyler Dauwalder uint8 _reserved2; 1296ead0c3e2STyler Dauwalder uint32 _sparing_table_size; 1297ead0c3e2STyler Dauwalder uint32 _sparing_table_locations[UDF_MAX_SPARING_TABLE_COUNT]; 1298ead0c3e2STyler Dauwalder } __attribute__((packed)); 1299ead0c3e2STyler Dauwalder 1300ead0c3e2STyler Dauwalder 1301ead0c3e2STyler Dauwalder /* ----UDF Specific---- */ 1302ead0c3e2STyler Dauwalder /*! \brief Metadata partition map 1303ead0c3e2STyler Dauwalder 1304ead0c3e2STyler Dauwalder Note that this map is a customization of the ECMA-167 1305ead0c3e2STyler Dauwalder type 2 partition map. 1306ead0c3e2STyler Dauwalder 1307ead0c3e2STyler Dauwalder See also: UDF-2.50 2.2.10 1308ead0c3e2STyler Dauwalder */ 1309ead0c3e2STyler Dauwalder struct metadata_partition_map { 1310c530d46cSJérôme Duval public: partition_type_idmetadata_partition_map1311c530d46cSJérôme Duval entity_id& partition_type_id() { return _partition_type_id; } partition_type_idmetadata_partition_map1312c530d46cSJérôme Duval const entity_id& partition_type_id() const { return _partition_type_id; } 1313c530d46cSJérôme Duval volume_sequence_numbermetadata_partition_map1314c530d46cSJérôme Duval uint16 volume_sequence_number() const { 1315c530d46cSJérôme Duval return B_LENDIAN_TO_HOST_INT16(_volume_sequence_number); } set_volume_sequence_numbermetadata_partition_map1316c530d46cSJérôme Duval void set_volume_sequence_number(uint16 number) { 1317c530d46cSJérôme Duval _volume_sequence_number = B_HOST_TO_LENDIAN_INT16(number); } 1318c530d46cSJérôme Duval partition_numbermetadata_partition_map1319c530d46cSJérôme Duval uint16 partition_number() const { 1320c530d46cSJérôme Duval return B_LENDIAN_TO_HOST_INT16(_partition_number); } set_partition_numbermetadata_partition_map1321c530d46cSJérôme Duval void set_partition_number(uint16 number) { 1322c530d46cSJérôme Duval _partition_number = B_HOST_TO_LENDIAN_INT16(number); } 1323c530d46cSJérôme Duval metadata_file_locationmetadata_partition_map1324c530d46cSJérôme Duval uint32 metadata_file_location() const { 1325c530d46cSJérôme Duval return B_LENDIAN_TO_HOST_INT32(_metadata_file_location); } set_metadata_file_locationmetadata_partition_map1326c530d46cSJérôme Duval void set_metadata_file_location(uint32 location) { 1327c530d46cSJérôme Duval _metadata_file_location = B_HOST_TO_LENDIAN_INT32(location); } 1328c530d46cSJérôme Duval metadata_mirror_file_locationmetadata_partition_map1329c530d46cSJérôme Duval uint32 metadata_mirror_file_location() const { 1330c530d46cSJérôme Duval return B_LENDIAN_TO_HOST_INT32(_metadata_mirror_file_location); } set_metadata_mirror_file_locationmetadata_partition_map1331c530d46cSJérôme Duval void set_metadata_mirror_file_location(uint32 location) { 1332c530d46cSJérôme Duval _metadata_mirror_file_location = B_HOST_TO_LENDIAN_INT32(location); } 1333c530d46cSJérôme Duval metadata_bitmap_file_locationmetadata_partition_map1334c530d46cSJérôme Duval uint32 metadata_bitmap_file_location() const { 1335c530d46cSJérôme Duval return B_LENDIAN_TO_HOST_INT32(_metadata_bitmap_file_location); } set_metadata_bitmap_file_locationmetadata_partition_map1336c530d46cSJérôme Duval void set_metadata_bitmap_file_location(uint32 location) { 1337c530d46cSJérôme Duval _metadata_bitmap_file_location = B_HOST_TO_LENDIAN_INT32(location); } 1338c530d46cSJérôme Duval allocation_unit_sizemetadata_partition_map1339c530d46cSJérôme Duval uint32 allocation_unit_size() const { 1340c530d46cSJérôme Duval return B_LENDIAN_TO_HOST_INT32(_allocation_unit_size); } set_allocation_unit_sizemetadata_partition_map1341c530d46cSJérôme Duval void set_allocation_unit_size(uint32 size) { 1342c530d46cSJérôme Duval _allocation_unit_size = B_HOST_TO_LENDIAN_INT32(size); } 1343c530d46cSJérôme Duval alignment_unit_sizemetadata_partition_map1344c530d46cSJérôme Duval uint32 alignment_unit_size() const { 1345c530d46cSJérôme Duval return B_LENDIAN_TO_HOST_INT32(_alignment_unit_size); } set_alignment_unit_sizemetadata_partition_map1346c530d46cSJérôme Duval void set_alignment_unit_size(uint32 size) { 1347c530d46cSJérôme Duval _alignment_unit_size = B_HOST_TO_LENDIAN_INT32(size); } 1348c530d46cSJérôme Duval flagsmetadata_partition_map1349c530d46cSJérôme Duval uint8 flags() const { return _flags; } set_flagsmetadata_partition_map1350c530d46cSJérôme Duval void set_flags(uint8 flags) { _flags = flags; } 1351c530d46cSJérôme Duval 1352c530d46cSJérôme Duval private: 1353ead0c3e2STyler Dauwalder uint8 type; 1354ead0c3e2STyler Dauwalder uint8 length; 1355ead0c3e2STyler Dauwalder uint8 reserved1[2]; 1356ead0c3e2STyler Dauwalder 1357ead0c3e2STyler Dauwalder /*! - flags: 0 1358ead0c3e2STyler Dauwalder - identifier: "*UDF Metadata Partition" 1359ead0c3e2STyler Dauwalder - identifier_suffix: per UDF-2.50 2.1.5 1360ead0c3e2STyler Dauwalder */ 1361c530d46cSJérôme Duval entity_id _partition_type_id; 1362c530d46cSJérôme Duval uint16 _volume_sequence_number; 1363ead0c3e2STyler Dauwalder 1364ead0c3e2STyler Dauwalder /*! corresponding type 1 or type 2 sparable partition 1365ead0c3e2STyler Dauwalder map in same logical volume 1366ead0c3e2STyler Dauwalder */ 1367c530d46cSJérôme Duval uint16 _partition_number; 1368c530d46cSJérôme Duval uint32 _metadata_file_location; 1369c530d46cSJérôme Duval uint32 _metadata_mirror_file_location; 1370c530d46cSJérôme Duval uint32 _metadata_bitmap_file_location; 1371c530d46cSJérôme Duval uint32 _allocation_unit_size; 1372c530d46cSJérôme Duval uint16 _alignment_unit_size; 1373c530d46cSJérôme Duval uint8 _flags; 1374c530d46cSJérôme Duval uint8 reserved2[5]; 1375ead0c3e2STyler Dauwalder } __attribute__((packed)); 1376ead0c3e2STyler Dauwalder 1377ead0c3e2STyler Dauwalder 1378ead0c3e2STyler Dauwalder /*! \brief Unallocated space descriptor 1379ead0c3e2STyler Dauwalder 1380ead0c3e2STyler Dauwalder See also: ECMA-167 3/10.8 1381ead0c3e2STyler Dauwalder */ 1382ead0c3e2STyler Dauwalder struct unallocated_space_descriptor { 1383ead0c3e2STyler Dauwalder void dump() const; 1384ead0c3e2STyler Dauwalder 1385ead0c3e2STyler Dauwalder // Get functions tagunallocated_space_descriptor1386ead0c3e2STyler Dauwalder const descriptor_tag & tag() const { return _tag; } tagunallocated_space_descriptor1387ead0c3e2STyler Dauwalder descriptor_tag & tag() { return _tag; } vds_numberunallocated_space_descriptor1388ead0c3e2STyler Dauwalder uint32 vds_number() const { return B_LENDIAN_TO_HOST_INT32(_vds_number); } allocation_descriptor_countunallocated_space_descriptor1389ead0c3e2STyler Dauwalder uint32 allocation_descriptor_count() const { return B_LENDIAN_TO_HOST_INT32(_allocation_descriptor_count); } allocation_descriptorsunallocated_space_descriptor1390ead0c3e2STyler Dauwalder extent_address* allocation_descriptors() { return _allocation_descriptors; } 1391ead0c3e2STyler Dauwalder 1392ead0c3e2STyler Dauwalder // Set functions set_vds_numberunallocated_space_descriptor1393ead0c3e2STyler Dauwalder void set_vds_number(uint32 number) { _vds_number = B_HOST_TO_LENDIAN_INT32(number); } set_allocation_descriptor_countunallocated_space_descriptor1394ead0c3e2STyler Dauwalder void set_allocation_descriptor_count(uint32 count) { _allocation_descriptor_count = B_HOST_TO_LENDIAN_INT32(count); } 1395ead0c3e2STyler Dauwalder private: 1396ead0c3e2STyler Dauwalder descriptor_tag _tag; 1397ead0c3e2STyler Dauwalder uint32 _vds_number; 1398ead0c3e2STyler Dauwalder uint32 _allocation_descriptor_count; 1399ead0c3e2STyler Dauwalder extent_address _allocation_descriptors[0]; 1400ead0c3e2STyler Dauwalder } __attribute__((packed)); 1401ead0c3e2STyler Dauwalder 1402ead0c3e2STyler Dauwalder 1403ead0c3e2STyler Dauwalder /*! \brief Terminating descriptor 1404ead0c3e2STyler Dauwalder 1405ead0c3e2STyler Dauwalder See also: ECMA-167 3/10.9 1406ead0c3e2STyler Dauwalder */ 1407ead0c3e2STyler Dauwalder struct terminating_descriptor { terminating_descriptorterminating_descriptor140810186d5dSTyler Dauwalder terminating_descriptor() { memset(_reserved.data, 0, _reserved.size()); } 1409ead0c3e2STyler Dauwalder void dump() const; 1410ead0c3e2STyler Dauwalder 1411ead0c3e2STyler Dauwalder // Get functions tagterminating_descriptor1412ead0c3e2STyler Dauwalder const descriptor_tag & tag() const { return _tag; } tagterminating_descriptor1413ead0c3e2STyler Dauwalder descriptor_tag & tag() { return _tag; } 1414ead0c3e2STyler Dauwalder private: 1415ead0c3e2STyler Dauwalder descriptor_tag _tag; 141610186d5dSTyler Dauwalder array<uint8, 496> _reserved; 1417ead0c3e2STyler Dauwalder } __attribute__((packed)); 1418ead0c3e2STyler Dauwalder 1419ead0c3e2STyler Dauwalder 1420ead0c3e2STyler Dauwalder /*! \brief Logical volume integrity descriptor 1421ead0c3e2STyler Dauwalder 1422335fd883STyler Dauwalder See also: ECMA-167 3/10.10, UDF-2.50 2.2.6 1423ead0c3e2STyler Dauwalder */ 1424ead0c3e2STyler Dauwalder struct logical_volume_integrity_descriptor { 1425335fd883STyler Dauwalder public: 1426b3a4ae39STyler Dauwalder static const uint32 minimum_implementation_use_length = 46; 1427b3a4ae39STyler Dauwalder 1428335fd883STyler Dauwalder void dump() const; descriptor_sizelogical_volume_integrity_descriptor142910186d5dSTyler Dauwalder uint32 descriptor_size() const { return sizeof(*this)+implementation_use_length() 143010186d5dSTyler Dauwalder + partition_count()*sizeof(uint32)*2; } 1431335fd883STyler Dauwalder taglogical_volume_integrity_descriptor1432335fd883STyler Dauwalder descriptor_tag& tag() { return _tag; } taglogical_volume_integrity_descriptor1433335fd883STyler Dauwalder const descriptor_tag& tag() const { return _tag; } 1434335fd883STyler Dauwalder recording_timelogical_volume_integrity_descriptor1435335fd883STyler Dauwalder timestamp& recording_time() { return _recording_time; } recording_timelogical_volume_integrity_descriptor1436335fd883STyler Dauwalder const timestamp& recording_time() const { return _recording_time; } 1437335fd883STyler Dauwalder integrity_typelogical_volume_integrity_descriptor1438335fd883STyler Dauwalder uint32 integrity_type() const { return B_LENDIAN_TO_HOST_INT32(_integrity_type); } 1439335fd883STyler Dauwalder next_integrity_extentlogical_volume_integrity_descriptor1440335fd883STyler Dauwalder extent_address& next_integrity_extent() { return _next_integrity_extent; } next_integrity_extentlogical_volume_integrity_descriptor1441335fd883STyler Dauwalder const extent_address& next_integrity_extent() const { return _next_integrity_extent; } 1442335fd883STyler Dauwalder logical_volume_contents_uselogical_volume_integrity_descriptor1443335fd883STyler Dauwalder array<uint8, 32>& logical_volume_contents_use() { return _logical_volume_contents_use; } logical_volume_contents_uselogical_volume_integrity_descriptor1444335fd883STyler Dauwalder const array<uint8, 32>& logical_volume_contents_use() const { return _logical_volume_contents_use; } 1445335fd883STyler Dauwalder 1446b3a4ae39STyler Dauwalder // next_unique_id() field is actually stored in the logical_volume_contents_use() 1447b3a4ae39STyler Dauwalder // field, per UDF-2.50 3.2.1 next_unique_idlogical_volume_integrity_descriptor1448b3a4ae39STyler Dauwalder uint64 next_unique_id() const { return B_LENDIAN_TO_HOST_INT64(_next_unique_id()); } 1449b3a4ae39STyler Dauwalder partition_countlogical_volume_integrity_descriptor1450335fd883STyler Dauwalder uint32 partition_count() const { return B_LENDIAN_TO_HOST_INT32(_partition_count); } implementation_use_lengthlogical_volume_integrity_descriptor1451335fd883STyler Dauwalder uint32 implementation_use_length() const { return B_LENDIAN_TO_HOST_INT32(_implementation_use_length); } 1452ead0c3e2STyler Dauwalder 1453ead0c3e2STyler Dauwalder /*! \todo double-check the pointer arithmetic here. */ free_space_tablelogical_volume_integrity_descriptor1454b3a4ae39STyler Dauwalder uint32* free_space_table() { return reinterpret_cast<uint32*>(reinterpret_cast<uint8*>(this)+80); } free_space_tablelogical_volume_integrity_descriptor1455b3a4ae39STyler Dauwalder const uint32* free_space_table() const { return reinterpret_cast<const uint32*>(reinterpret_cast<const uint8*>(this)+80); } size_tablelogical_volume_integrity_descriptor1456b3a4ae39STyler Dauwalder uint32* size_table() { return reinterpret_cast<uint32*>(reinterpret_cast<uint8*>(free_space_table())+partition_count()*sizeof(uint32)); } size_tablelogical_volume_integrity_descriptor1457b3a4ae39STyler Dauwalder const uint32* size_table() const { return reinterpret_cast<const uint32*>(reinterpret_cast<const uint8*>(free_space_table())+partition_count()*sizeof(uint32)); } implementation_uselogical_volume_integrity_descriptor1458b3a4ae39STyler Dauwalder uint8* implementation_use() { return reinterpret_cast<uint8*>(reinterpret_cast<uint8*>(size_table())+partition_count()*sizeof(uint32)); } implementation_uselogical_volume_integrity_descriptor1459b3a4ae39STyler Dauwalder const uint8* implementation_use() const { return reinterpret_cast<const uint8*>(reinterpret_cast<const uint8*>(size_table())+partition_count()*sizeof(uint32)); } 1460335fd883STyler Dauwalder 1461335fd883STyler Dauwalder // accessors for fields stored in implementation_use() field per UDF-2.50 2.2.6.4 implementation_idlogical_volume_integrity_descriptor1462b3a4ae39STyler Dauwalder entity_id& implementation_id() { return _accessor().id; } implementation_idlogical_volume_integrity_descriptor1463b3a4ae39STyler Dauwalder const entity_id& implementation_id() const { return _accessor().id; } file_countlogical_volume_integrity_descriptor1464335fd883STyler Dauwalder uint32 file_count() const { return B_LENDIAN_TO_HOST_INT32(_accessor().file_count); } directory_countlogical_volume_integrity_descriptor1465335fd883STyler Dauwalder uint32 directory_count() const { return B_LENDIAN_TO_HOST_INT32(_accessor().directory_count); } minimum_udf_read_revisionlogical_volume_integrity_descriptor1466335fd883STyler Dauwalder uint16 minimum_udf_read_revision() const { return B_LENDIAN_TO_HOST_INT16(_accessor().minimum_udf_read_revision); } minimum_udf_write_revisionlogical_volume_integrity_descriptor1467335fd883STyler Dauwalder uint16 minimum_udf_write_revision() const { return B_LENDIAN_TO_HOST_INT16(_accessor().minimum_udf_write_revision); } maximum_udf_write_revisionlogical_volume_integrity_descriptor1468335fd883STyler Dauwalder uint16 maximum_udf_write_revision() const { return B_LENDIAN_TO_HOST_INT16(_accessor().maximum_udf_write_revision); } 1469335fd883STyler Dauwalder 1470335fd883STyler Dauwalder // set functions set_integrity_typelogical_volume_integrity_descriptor1471335fd883STyler Dauwalder void set_integrity_type(uint32 type) { _integrity_type = B_HOST_TO_LENDIAN_INT32(type); } set_next_unique_idlogical_volume_integrity_descriptor1472b3a4ae39STyler Dauwalder void set_next_unique_id(uint64 id) { _next_unique_id() = B_HOST_TO_LENDIAN_INT64(id); } set_partition_countlogical_volume_integrity_descriptor1473335fd883STyler Dauwalder void set_partition_count(uint32 count) { _partition_count = B_HOST_TO_LENDIAN_INT32(count); } set_implementation_use_lengthlogical_volume_integrity_descriptor1474b3a4ae39STyler Dauwalder void set_implementation_use_length(uint32 length) { _implementation_use_length = B_HOST_TO_LENDIAN_INT32(length); } 1475335fd883STyler Dauwalder 1476335fd883STyler Dauwalder // set functions for fields stored in implementation_use() field per UDF-2.50 2.2.6.4 set_file_countlogical_volume_integrity_descriptor1477335fd883STyler Dauwalder void set_file_count(uint32 count) { _accessor().file_count = B_HOST_TO_LENDIAN_INT32(count); } set_directory_countlogical_volume_integrity_descriptor1478335fd883STyler Dauwalder void set_directory_count(uint32 count) { _accessor().directory_count = B_HOST_TO_LENDIAN_INT32(count); } set_minimum_udf_read_revisionlogical_volume_integrity_descriptor1479335fd883STyler Dauwalder void set_minimum_udf_read_revision(uint16 revision) { _accessor().minimum_udf_read_revision = B_HOST_TO_LENDIAN_INT16(revision); } set_minimum_udf_write_revisionlogical_volume_integrity_descriptor1480335fd883STyler Dauwalder void set_minimum_udf_write_revision(uint16 revision) { _accessor().minimum_udf_write_revision = B_HOST_TO_LENDIAN_INT16(revision); } set_maximum_udf_write_revisionlogical_volume_integrity_descriptor1481335fd883STyler Dauwalder void set_maximum_udf_write_revision(uint16 revision) { _accessor().maximum_udf_write_revision = B_HOST_TO_LENDIAN_INT16(revision); } 1482335fd883STyler Dauwalder 1483335fd883STyler Dauwalder private: 1484335fd883STyler Dauwalder struct _lvid_implementation_use_accessor { 1485335fd883STyler Dauwalder entity_id id; 1486335fd883STyler Dauwalder uint32 file_count; 1487335fd883STyler Dauwalder uint32 directory_count; 1488335fd883STyler Dauwalder uint16 minimum_udf_read_revision; 1489335fd883STyler Dauwalder uint16 minimum_udf_write_revision; 1490335fd883STyler Dauwalder uint16 maximum_udf_write_revision; 1491335fd883STyler Dauwalder }; 1492335fd883STyler Dauwalder _accessorlogical_volume_integrity_descriptor1493335fd883STyler Dauwalder _lvid_implementation_use_accessor& _accessor() { 1494335fd883STyler Dauwalder return *reinterpret_cast<_lvid_implementation_use_accessor*>(implementation_use()); 1495335fd883STyler Dauwalder } _accessorlogical_volume_integrity_descriptor1496335fd883STyler Dauwalder const _lvid_implementation_use_accessor& _accessor() const { 1497335fd883STyler Dauwalder return *reinterpret_cast<const _lvid_implementation_use_accessor*>(implementation_use()); 1498335fd883STyler Dauwalder } 1499335fd883STyler Dauwalder _next_unique_idlogical_volume_integrity_descriptor1500b3a4ae39STyler Dauwalder uint64& _next_unique_id() { return *reinterpret_cast<uint64*>(logical_volume_contents_use().data); } _next_unique_idlogical_volume_integrity_descriptor1501b3a4ae39STyler Dauwalder const uint64& _next_unique_id() const { return *reinterpret_cast<const uint64*>(logical_volume_contents_use().data); } 1502b3a4ae39STyler Dauwalder 1503335fd883STyler Dauwalder descriptor_tag _tag; 1504335fd883STyler Dauwalder timestamp _recording_time; 1505335fd883STyler Dauwalder uint32 _integrity_type; 1506335fd883STyler Dauwalder extent_address _next_integrity_extent; 1507335fd883STyler Dauwalder array<uint8, 32> _logical_volume_contents_use; 1508335fd883STyler Dauwalder uint32 _partition_count; 1509335fd883STyler Dauwalder uint32 _implementation_use_length; 1510ead0c3e2STyler Dauwalder 1511ead0c3e2STyler Dauwalder } __attribute__((packed)); 1512ead0c3e2STyler Dauwalder 1513ead0c3e2STyler Dauwalder /*! \brief Logical volume integrity types 1514ead0c3e2STyler Dauwalder */ 1515ead0c3e2STyler Dauwalder enum { 1516335fd883STyler Dauwalder INTEGRITY_OPEN = 0, 1517335fd883STyler Dauwalder INTEGRITY_CLOSED = 1, 1518ead0c3e2STyler Dauwalder }; 1519ead0c3e2STyler Dauwalder 1520e9927e2bSTyler Dauwalder /*! \brief Highest currently supported UDF read revision. 1521e9927e2bSTyler Dauwalder */ 1522c530d46cSJérôme Duval #define UDF_MAX_READ_REVISION 0x0250 1523e9927e2bSTyler Dauwalder 1524ead0c3e2STyler Dauwalder //---------------------------------------------------------------------- 1525ead0c3e2STyler Dauwalder // ECMA-167 Part 4 1526ead0c3e2STyler Dauwalder //---------------------------------------------------------------------- 1527ead0c3e2STyler Dauwalder 1528ead0c3e2STyler Dauwalder 1529ead0c3e2STyler Dauwalder 1530ead0c3e2STyler Dauwalder /*! \brief File set descriptor 1531ead0c3e2STyler Dauwalder 1532ead0c3e2STyler Dauwalder Contains all the pertinent info about a file set (i.e. a hierarchy of files) 1533ead0c3e2STyler Dauwalder 1534ead0c3e2STyler Dauwalder According to UDF-2.01, only one file set descriptor shall be recorded, 1535ead0c3e2STyler Dauwalder except on WORM media, where the following rules apply: 1536ead0c3e2STyler Dauwalder - Multiple file sets are allowed only on WORM media 1537ead0c3e2STyler Dauwalder - The default file set shall be the one with highest value \c file_set_number field. 1538ead0c3e2STyler Dauwalder - Only the default file set may be flagged as writeable. All others shall be 1539ead0c3e2STyler Dauwalder flagged as "hard write protect". 1540ead0c3e2STyler Dauwalder - No writeable file set may reference metadata structures which are referenced 1541ead0c3e2STyler Dauwalder (directly or indirectly) by any other file set. Writeable file sets may, however, 1542ead0c3e2STyler Dauwalder reference actual file data extents that are also referenced by other file sets. 1543ead0c3e2STyler Dauwalder */ 1544ead0c3e2STyler Dauwalder struct file_set_descriptor { 1545ead0c3e2STyler Dauwalder void dump() const; 1546ead0c3e2STyler Dauwalder 1547ead0c3e2STyler Dauwalder // Get functions tagfile_set_descriptor1548ead0c3e2STyler Dauwalder const descriptor_tag & tag() const { return _tag; } tagfile_set_descriptor1549ead0c3e2STyler Dauwalder descriptor_tag & tag() { return _tag; } 1550ead0c3e2STyler Dauwalder recording_date_and_timefile_set_descriptor1551ead0c3e2STyler Dauwalder const timestamp& recording_date_and_time() const { return _recording_date_and_time; } recording_date_and_timefile_set_descriptor1552ead0c3e2STyler Dauwalder timestamp& recording_date_and_time() { return _recording_date_and_time; } 1553ead0c3e2STyler Dauwalder interchange_levelfile_set_descriptor1554ead0c3e2STyler Dauwalder uint16 interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_interchange_level); } max_interchange_levelfile_set_descriptor1555ead0c3e2STyler Dauwalder uint16 max_interchange_level() const { return B_LENDIAN_TO_HOST_INT16(_max_interchange_level); } character_set_listfile_set_descriptor1556ead0c3e2STyler Dauwalder uint32 character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_character_set_list); } max_character_set_listfile_set_descriptor1557ead0c3e2STyler Dauwalder uint32 max_character_set_list() const { return B_LENDIAN_TO_HOST_INT32(_max_character_set_list); } file_set_numberfile_set_descriptor1558ead0c3e2STyler Dauwalder uint32 file_set_number() const { return B_LENDIAN_TO_HOST_INT32(_file_set_number); } file_set_descriptor_numberfile_set_descriptor1559ead0c3e2STyler Dauwalder uint32 file_set_descriptor_number() const { return B_LENDIAN_TO_HOST_INT32(_file_set_descriptor_number); } 1560ead0c3e2STyler Dauwalder logical_volume_id_character_setfile_set_descriptor1561ead0c3e2STyler Dauwalder const charspec& logical_volume_id_character_set() const { return _logical_volume_id_character_set; } logical_volume_id_character_setfile_set_descriptor1562ead0c3e2STyler Dauwalder charspec& logical_volume_id_character_set() { return _logical_volume_id_character_set; } 1563ead0c3e2STyler Dauwalder logical_volume_idfile_set_descriptor1564ead0c3e2STyler Dauwalder const array<char, 128>& logical_volume_id() const { return _logical_volume_id; } logical_volume_idfile_set_descriptor1565ead0c3e2STyler Dauwalder array<char, 128>& logical_volume_id() { return _logical_volume_id; } 1566ead0c3e2STyler Dauwalder file_set_id_character_setfile_set_descriptor1567d1a0387eSTyler Dauwalder const charspec& file_set_id_character_set() const { return _file_set_id_character_set; } file_set_id_character_setfile_set_descriptor1568d1a0387eSTyler Dauwalder charspec& file_set_id_character_set() { return _file_set_id_character_set; } 1569d1a0387eSTyler Dauwalder file_set_idfile_set_descriptor1570ead0c3e2STyler Dauwalder const array<char, 32>& file_set_id() const { return _file_set_id; } file_set_idfile_set_descriptor1571ead0c3e2STyler Dauwalder array<char, 32>& file_set_id() { return _file_set_id; } 1572ead0c3e2STyler Dauwalder copyright_file_idfile_set_descriptor1573ead0c3e2STyler Dauwalder const array<char, 32>& copyright_file_id() const { return _copyright_file_id; } copyright_file_idfile_set_descriptor1574ead0c3e2STyler Dauwalder array<char, 32>& copyright_file_id() { return _copyright_file_id; } 1575ead0c3e2STyler Dauwalder abstract_file_idfile_set_descriptor1576ead0c3e2STyler Dauwalder const array<char, 32>& abstract_file_id() const { return _abstract_file_id; } abstract_file_idfile_set_descriptor1577ead0c3e2STyler Dauwalder array<char, 32>& abstract_file_id() { return _abstract_file_id; } 1578ead0c3e2STyler Dauwalder root_directory_icbfile_set_descriptor1579ead0c3e2STyler Dauwalder const long_address& root_directory_icb() const { return _root_directory_icb; } root_directory_icbfile_set_descriptor1580ead0c3e2STyler Dauwalder long_address& root_directory_icb() { return _root_directory_icb; } 1581ead0c3e2STyler Dauwalder domain_idfile_set_descriptor1582ead0c3e2STyler Dauwalder const entity_id& domain_id() const { return _domain_id; } domain_idfile_set_descriptor1583ead0c3e2STyler Dauwalder entity_id& domain_id() { return _domain_id; } 1584ead0c3e2STyler Dauwalder next_extentfile_set_descriptor1585ead0c3e2STyler Dauwalder const long_address& next_extent() const { return _next_extent; } next_extentfile_set_descriptor1586ead0c3e2STyler Dauwalder long_address& next_extent() { return _next_extent; } 1587ead0c3e2STyler Dauwalder system_stream_directory_icbfile_set_descriptor1588ead0c3e2STyler Dauwalder const long_address& system_stream_directory_icb() const { return _system_stream_directory_icb; } system_stream_directory_icbfile_set_descriptor1589ead0c3e2STyler Dauwalder long_address& system_stream_directory_icb() { return _system_stream_directory_icb; } 1590ead0c3e2STyler Dauwalder reservedfile_set_descriptor1591d1a0387eSTyler Dauwalder const array<uint8, 32>& reserved() const { return _reserved; } reservedfile_set_descriptor1592d1a0387eSTyler Dauwalder array<uint8, 32>& reserved() { return _reserved; } 1593d1a0387eSTyler Dauwalder 1594ead0c3e2STyler Dauwalder // Set functions set_interchange_levelfile_set_descriptor1595ead0c3e2STyler Dauwalder void set_interchange_level(uint16 level) { _interchange_level = B_HOST_TO_LENDIAN_INT16(level); } set_max_interchange_levelfile_set_descriptor1596ead0c3e2STyler Dauwalder void set_max_interchange_level(uint16 level) { _max_interchange_level = B_HOST_TO_LENDIAN_INT16(level); } set_character_set_listfile_set_descriptor1597ead0c3e2STyler Dauwalder void set_character_set_list(uint32 list) { _character_set_list = B_HOST_TO_LENDIAN_INT32(list); } set_max_character_set_listfile_set_descriptor1598ead0c3e2STyler Dauwalder void set_max_character_set_list(uint32 list) { _max_character_set_list = B_HOST_TO_LENDIAN_INT32(list); } set_file_set_numberfile_set_descriptor1599ead0c3e2STyler Dauwalder void set_file_set_number(uint32 number) { _file_set_number = B_HOST_TO_LENDIAN_INT32(number); } set_file_set_descriptor_numberfile_set_descriptor1600ead0c3e2STyler Dauwalder void set_file_set_descriptor_number(uint32 number) { _file_set_descriptor_number = B_HOST_TO_LENDIAN_INT32(number); } 1601ead0c3e2STyler Dauwalder private: 1602ead0c3e2STyler Dauwalder descriptor_tag _tag; 1603ead0c3e2STyler Dauwalder timestamp _recording_date_and_time; 1604ead0c3e2STyler Dauwalder uint16 _interchange_level; //!< To be set to 3 (see UDF-2.01 2.3.2.1) 1605ead0c3e2STyler Dauwalder uint16 _max_interchange_level; //!< To be set to 3 (see UDF-2.01 2.3.2.2) 1606ead0c3e2STyler Dauwalder uint32 _character_set_list; 1607ead0c3e2STyler Dauwalder uint32 _max_character_set_list; 1608ead0c3e2STyler Dauwalder uint32 _file_set_number; 1609ead0c3e2STyler Dauwalder uint32 _file_set_descriptor_number; 1610ead0c3e2STyler Dauwalder charspec _logical_volume_id_character_set; //!< To be set to kCSOCharspec 1611ead0c3e2STyler Dauwalder array<char, 128> _logical_volume_id; 1612d1a0387eSTyler Dauwalder charspec _file_set_id_character_set; 1613ead0c3e2STyler Dauwalder array<char, 32> _file_set_id; 1614ead0c3e2STyler Dauwalder array<char, 32> _copyright_file_id; 1615ead0c3e2STyler Dauwalder array<char, 32> _abstract_file_id; 1616ead0c3e2STyler Dauwalder long_address _root_directory_icb; 1617ead0c3e2STyler Dauwalder entity_id _domain_id; 1618ead0c3e2STyler Dauwalder long_address _next_extent; 1619ead0c3e2STyler Dauwalder long_address _system_stream_directory_icb; 1620d1a0387eSTyler Dauwalder array<uint8, 32> _reserved; 1621ead0c3e2STyler Dauwalder } __attribute__((packed)); 1622ead0c3e2STyler Dauwalder 1623ead0c3e2STyler Dauwalder 1624ead0c3e2STyler Dauwalder /*! \brief Partition header descriptor 1625ead0c3e2STyler Dauwalder 1626ead0c3e2STyler Dauwalder Contains references to unallocated and freed space data structures. 1627ead0c3e2STyler Dauwalder 1628ead0c3e2STyler Dauwalder Note that unallocated space is space ready to be written with no 1629ead0c3e2STyler Dauwalder preprocessing. Freed space is space needing preprocessing (i.e. 1630ead0c3e2STyler Dauwalder a special write pass) before use. 1631ead0c3e2STyler Dauwalder 1632ead0c3e2STyler Dauwalder Per UDF-2.01 2.3.3, the use of tables or bitmaps shall be consistent, 1633ead0c3e2STyler Dauwalder i.e. only one type or the other shall be used, not both. 1634ead0c3e2STyler Dauwalder 1635ead0c3e2STyler Dauwalder To indicate disuse of a certain field, the fields of the allocation 1636ead0c3e2STyler Dauwalder descriptor shall all be set to 0. 1637ead0c3e2STyler Dauwalder 1638ead0c3e2STyler Dauwalder See also: ECMA-167 4/14.3, UDF-2.01 2.2.3 1639ead0c3e2STyler Dauwalder */ 1640ead0c3e2STyler Dauwalder struct partition_header_descriptor { 1641ead0c3e2STyler Dauwalder long_address unallocated_space_table; 1642ead0c3e2STyler Dauwalder long_address unallocated_space_bitmap; 1643ead0c3e2STyler Dauwalder /*! Unused, per UDF-2.01 2.2.3 */ 1644ead0c3e2STyler Dauwalder long_address partition_integrity_table; 1645ead0c3e2STyler Dauwalder long_address freed_space_table; 1646ead0c3e2STyler Dauwalder long_address freed_space_bitmap; 1647ead0c3e2STyler Dauwalder uint8 reserved[88]; 1648ead0c3e2STyler Dauwalder } __attribute__((packed)); 1649ead0c3e2STyler Dauwalder 1650ead0c3e2STyler Dauwalder #define kMaxFileIdSize (sizeof(file_id_descriptor)+512+3) 1651ead0c3e2STyler Dauwalder 1652ead0c3e2STyler Dauwalder /*! \brief File identifier descriptor 1653ead0c3e2STyler Dauwalder 1654ead0c3e2STyler Dauwalder Identifies the name of a file entry, and the location of its corresponding 1655ead0c3e2STyler Dauwalder ICB. 1656ead0c3e2STyler Dauwalder 1657ead0c3e2STyler Dauwalder See also: ECMA-167 4/14.4, UDF-2.01 2.3.4 1658ead0c3e2STyler Dauwalder 1659ead0c3e2STyler Dauwalder \todo Check pointer arithmetic 1660ead0c3e2STyler Dauwalder */ 1661ead0c3e2STyler Dauwalder struct file_id_descriptor { 1662ead0c3e2STyler Dauwalder public: descriptor_sizefile_id_descriptor166380b849abSTyler Dauwalder uint32 descriptor_size() const { return total_length(); } 1664ead0c3e2STyler Dauwalder void dump() const; 1665ead0c3e2STyler Dauwalder tagfile_id_descriptor1666ead0c3e2STyler Dauwalder descriptor_tag & tag() { return _tag; } tagfile_id_descriptor1667ead0c3e2STyler Dauwalder const descriptor_tag & tag() const { return _tag; } 1668ead0c3e2STyler Dauwalder version_numberfile_id_descriptor1669ead0c3e2STyler Dauwalder uint16 version_number() const { return B_LENDIAN_TO_HOST_INT16(_version_number); } 1670ead0c3e2STyler Dauwalder characteristicsfile_id_descriptor1671ead0c3e2STyler Dauwalder uint8 characteristics() const { return _characteristics; } 1672ead0c3e2STyler Dauwalder may_be_hiddenfile_id_descriptor1673ead0c3e2STyler Dauwalder bool may_be_hidden() const { 1674ead0c3e2STyler Dauwalder characteristics_accessor c; 1675ead0c3e2STyler Dauwalder c.all = characteristics(); 1676ead0c3e2STyler Dauwalder return c.bits.may_be_hidden; 1677ead0c3e2STyler Dauwalder } 1678ead0c3e2STyler Dauwalder is_directoryfile_id_descriptor1679ead0c3e2STyler Dauwalder bool is_directory() const { 1680ead0c3e2STyler Dauwalder characteristics_accessor c; 1681ead0c3e2STyler Dauwalder c.all = characteristics(); 1682ead0c3e2STyler Dauwalder return c.bits.is_directory; 1683ead0c3e2STyler Dauwalder } 1684ead0c3e2STyler Dauwalder is_deletedfile_id_descriptor1685ead0c3e2STyler Dauwalder bool is_deleted() const { 1686ead0c3e2STyler Dauwalder characteristics_accessor c; 1687ead0c3e2STyler Dauwalder c.all = characteristics(); 1688ead0c3e2STyler Dauwalder return c.bits.is_deleted; 1689ead0c3e2STyler Dauwalder } 1690ead0c3e2STyler Dauwalder is_parentfile_id_descriptor1691ead0c3e2STyler Dauwalder bool is_parent() const { 1692ead0c3e2STyler Dauwalder characteristics_accessor c; 1693ead0c3e2STyler Dauwalder c.all = characteristics(); 1694ead0c3e2STyler Dauwalder return c.bits.is_parent; 1695ead0c3e2STyler Dauwalder } 1696ead0c3e2STyler Dauwalder is_metadata_streamfile_id_descriptor1697ead0c3e2STyler Dauwalder bool is_metadata_stream() const { 1698ead0c3e2STyler Dauwalder characteristics_accessor c; 1699ead0c3e2STyler Dauwalder c.all = characteristics(); 1700ead0c3e2STyler Dauwalder return c.bits.is_metadata_stream; 1701ead0c3e2STyler Dauwalder } 1702ead0c3e2STyler Dauwalder id_lengthfile_id_descriptor1703ead0c3e2STyler Dauwalder uint8 id_length() const { return _id_length; } 1704ead0c3e2STyler Dauwalder icbfile_id_descriptor1705ead0c3e2STyler Dauwalder long_address& icb() { return _icb; } icbfile_id_descriptor1706ead0c3e2STyler Dauwalder const long_address& icb() const { return _icb; } 1707ead0c3e2STyler Dauwalder implementation_use_lengthfile_id_descriptor170880b849abSTyler Dauwalder uint16 implementation_use_length() const { return B_LENDIAN_TO_HOST_INT16(_implementation_use_length); } 1709ead0c3e2STyler Dauwalder 1710ead0c3e2STyler Dauwalder /*! If implementation_use_length is greater than 0, the first 32 1711ead0c3e2STyler Dauwalder bytes of implementation_use() shall be an entity_id identifying 1712ead0c3e2STyler Dauwalder the implementation that generated the rest of the data in the 1713ead0c3e2STyler Dauwalder implementation_use() field. 1714ead0c3e2STyler Dauwalder */ implementation_usefile_id_descriptor17154f0e6a75STyler Dauwalder uint8* implementation_use() { return ((uint8*)this)+(38); } idfile_id_descriptor17164f0e6a75STyler Dauwalder char* id() { return ((char*)this)+(38)+implementation_use_length(); } idfile_id_descriptor17174f0e6a75STyler Dauwalder const char* id() const { return ((const char*)this)+(38)+implementation_use_length(); } 1718ead0c3e2STyler Dauwalder structure_lengthfile_id_descriptor17194f0e6a75STyler Dauwalder uint16 structure_length() const { return (38) + id_length() + implementation_use_length(); } padding_lengthfile_id_descriptor1720ead0c3e2STyler Dauwalder uint16 padding_length() const { return ((structure_length()+3)/4)*4 - structure_length(); } total_lengthfile_id_descriptor1721ead0c3e2STyler Dauwalder uint16 total_length() const { return structure_length() + padding_length(); } 1722ead0c3e2STyler Dauwalder 1723ead0c3e2STyler Dauwalder // Set functions set_version_numberfile_id_descriptor1724ead0c3e2STyler Dauwalder void set_version_number(uint16 number) { _version_number = B_HOST_TO_LENDIAN_INT16(number); } 1725ead0c3e2STyler Dauwalder set_characteristicsfile_id_descriptor1726ead0c3e2STyler Dauwalder void set_characteristics(uint8 characteristics) { _characteristics = characteristics; } 1727ead0c3e2STyler Dauwalder set_may_be_hiddenfile_id_descriptor1728ead0c3e2STyler Dauwalder void set_may_be_hidden(bool how) { 1729ead0c3e2STyler Dauwalder characteristics_accessor c; 1730ead0c3e2STyler Dauwalder c.all = characteristics(); 1731ead0c3e2STyler Dauwalder c.bits.may_be_hidden = how; 1732ead0c3e2STyler Dauwalder set_characteristics(c.all); 1733ead0c3e2STyler Dauwalder } 1734ead0c3e2STyler Dauwalder set_is_directoryfile_id_descriptor1735ead0c3e2STyler Dauwalder void set_is_directory(bool how) { 1736ead0c3e2STyler Dauwalder characteristics_accessor c; 1737ead0c3e2STyler Dauwalder c.all = characteristics(); 1738ead0c3e2STyler Dauwalder c.bits.is_directory = how; 1739ead0c3e2STyler Dauwalder set_characteristics(c.all); 1740ead0c3e2STyler Dauwalder } 1741ead0c3e2STyler Dauwalder set_is_deletedfile_id_descriptor1742ead0c3e2STyler Dauwalder void set_is_deleted(bool how) { 1743ead0c3e2STyler Dauwalder characteristics_accessor c; 1744ead0c3e2STyler Dauwalder c.all = characteristics(); 1745ead0c3e2STyler Dauwalder c.bits.is_deleted = how; 1746ead0c3e2STyler Dauwalder set_characteristics(c.all); 1747ead0c3e2STyler Dauwalder } 1748ead0c3e2STyler Dauwalder set_is_parentfile_id_descriptor1749ead0c3e2STyler Dauwalder void set_is_parent(bool how) { 1750ead0c3e2STyler Dauwalder characteristics_accessor c; 1751ead0c3e2STyler Dauwalder c.all = characteristics(); 1752ead0c3e2STyler Dauwalder c.bits.is_parent = how; 1753ead0c3e2STyler Dauwalder set_characteristics(c.all); 1754ead0c3e2STyler Dauwalder } 1755ead0c3e2STyler Dauwalder set_is_metadata_streamfile_id_descriptor1756ead0c3e2STyler Dauwalder void set_is_metadata_stream(bool how) { 1757ead0c3e2STyler Dauwalder characteristics_accessor c; 1758ead0c3e2STyler Dauwalder c.all = characteristics(); 1759ead0c3e2STyler Dauwalder c.bits.is_metadata_stream = how; 1760ead0c3e2STyler Dauwalder set_characteristics(c.all); 1761ead0c3e2STyler Dauwalder } 1762ead0c3e2STyler Dauwalder 1763ead0c3e2STyler Dauwalder set_id_lengthfile_id_descriptor1764ead0c3e2STyler Dauwalder void set_id_length(uint8 id_length) { _id_length = id_length; } set_implementation_use_lengthfile_id_descriptor176580b849abSTyler Dauwalder void set_implementation_use_length(uint16 implementation_use_length) { _implementation_use_length = B_HOST_TO_LENDIAN_INT16(implementation_use_length); } 1766ead0c3e2STyler Dauwalder 1767ead0c3e2STyler Dauwalder 1768ead0c3e2STyler Dauwalder 1769ead0c3e2STyler Dauwalder private: 1770ead0c3e2STyler Dauwalder union characteristics_accessor { 1771ead0c3e2STyler Dauwalder uint8 all; 1772ead0c3e2STyler Dauwalder struct { 1773ead0c3e2STyler Dauwalder uint8 may_be_hidden:1, 1774ead0c3e2STyler Dauwalder is_directory:1, 1775ead0c3e2STyler Dauwalder is_deleted:1, 1776ead0c3e2STyler Dauwalder is_parent:1, 1777ead0c3e2STyler Dauwalder is_metadata_stream:1, 1778ead0c3e2STyler Dauwalder reserved_characteristics:3; 1779ead0c3e2STyler Dauwalder } bits; 1780ead0c3e2STyler Dauwalder }; 1781ead0c3e2STyler Dauwalder 1782ead0c3e2STyler Dauwalder descriptor_tag _tag; 1783ead0c3e2STyler Dauwalder /*! According to ECMA-167: 1 <= valid version_number <= 32767, 32768 <= reserved <= 65535. 1784ead0c3e2STyler Dauwalder 1785ead0c3e2STyler Dauwalder However, according to UDF-2.01, there shall be exactly one version of 1786ead0c3e2STyler Dauwalder a file, and it shall be 1. 1787ead0c3e2STyler Dauwalder */ 1788ead0c3e2STyler Dauwalder uint16 _version_number; 1789ead0c3e2STyler Dauwalder /*! \todo Check UDF-2.01 2.3.4.2 for some more restrictions. */ 1790ead0c3e2STyler Dauwalder uint8 _characteristics; 1791ead0c3e2STyler Dauwalder uint8 _id_length; 1792ead0c3e2STyler Dauwalder long_address _icb; 179380b849abSTyler Dauwalder uint16 _implementation_use_length; 1794ead0c3e2STyler Dauwalder } __attribute__((packed)); 1795ead0c3e2STyler Dauwalder 1796ead0c3e2STyler Dauwalder 1797ead0c3e2STyler Dauwalder /*! \brief Allocation extent descriptor 1798ead0c3e2STyler Dauwalder 1799ead0c3e2STyler Dauwalder See also: ECMA-167 4/14.5 1800ead0c3e2STyler Dauwalder */ 1801ead0c3e2STyler Dauwalder struct allocation_extent_descriptor { 1802ead0c3e2STyler Dauwalder descriptor_tag tag; 1803ead0c3e2STyler Dauwalder uint32 previous_allocation_extent_location; 1804ead0c3e2STyler Dauwalder uint32 length_of_allocation_descriptors; 1805ead0c3e2STyler Dauwalder 1806ead0c3e2STyler Dauwalder /*! \todo Check that this is really how things work: */ allocation_descriptorsallocation_extent_descriptor1807b3a4ae39STyler Dauwalder uint8* allocation_descriptors() { return (uint8*)(reinterpret_cast<uint8*>(this)+sizeof(allocation_extent_descriptor)); } 1808ead0c3e2STyler Dauwalder } __attribute__((packed)); 1809ead0c3e2STyler Dauwalder 1810ead0c3e2STyler Dauwalder 1811ead0c3e2STyler Dauwalder /*! \brief icb_tag::file_type values 1812ead0c3e2STyler Dauwalder 1813ead0c3e2STyler Dauwalder See also ECMA-167 4/14.6.6 1814ead0c3e2STyler Dauwalder */ 1815ead0c3e2STyler Dauwalder enum icb_file_types { 1816ead0c3e2STyler Dauwalder ICB_TYPE_UNSPECIFIED = 0, 1817ead0c3e2STyler Dauwalder ICB_TYPE_UNALLOCATED_SPACE_ENTRY, 1818ead0c3e2STyler Dauwalder ICB_TYPE_PARTITION_INTEGRITY_ENTRY, 1819ead0c3e2STyler Dauwalder ICB_TYPE_INDIRECT_ENTRY, 1820ead0c3e2STyler Dauwalder ICB_TYPE_DIRECTORY, 1821ead0c3e2STyler Dauwalder ICB_TYPE_REGULAR_FILE, 1822ead0c3e2STyler Dauwalder ICB_TYPE_BLOCK_SPECIAL_DEVICE, 1823ead0c3e2STyler Dauwalder ICB_TYPE_CHARACTER_SPECIAL_DEVICE, 1824ead0c3e2STyler Dauwalder ICB_TYPE_EXTENDED_ATTRIBUTES_FILE, 1825ead0c3e2STyler Dauwalder ICB_TYPE_FIFO, 1826ead0c3e2STyler Dauwalder ICB_TYPE_ISSOCK, 1827ead0c3e2STyler Dauwalder ICB_TYPE_TERMINAL, 1828ead0c3e2STyler Dauwalder ICB_TYPE_SYMLINK, 1829ead0c3e2STyler Dauwalder ICB_TYPE_STREAM_DIRECTORY, 1830ead0c3e2STyler Dauwalder 1831ead0c3e2STyler Dauwalder ICB_TYPE_RESERVED_START = 14, 1832ead0c3e2STyler Dauwalder ICB_TYPE_RESERVED_END = 247, 1833ead0c3e2STyler Dauwalder 1834ead0c3e2STyler Dauwalder ICB_TYPE_CUSTOM_START = 248, 1835ead0c3e2STyler Dauwalder ICB_TYPE_CUSTOM_END = 255, 1836ead0c3e2STyler Dauwalder }; 1837ead0c3e2STyler Dauwalder 1838ead0c3e2STyler Dauwalder /*! \brief idb_entry_tag::_flags::descriptor_flags() values 1839ead0c3e2STyler Dauwalder 1840ead0c3e2STyler Dauwalder See also ECMA-167 4/14.6.8 1841ead0c3e2STyler Dauwalder */ 1842ead0c3e2STyler Dauwalder enum icb_descriptor_types { 1843ead0c3e2STyler Dauwalder ICB_DESCRIPTOR_TYPE_SHORT = 0, 1844ead0c3e2STyler Dauwalder ICB_DESCRIPTOR_TYPE_LONG, 1845ead0c3e2STyler Dauwalder ICB_DESCRIPTOR_TYPE_EXTENDED, 1846ead0c3e2STyler Dauwalder ICB_DESCRIPTOR_TYPE_EMBEDDED, 1847ead0c3e2STyler Dauwalder }; 1848ead0c3e2STyler Dauwalder 1849e631ed51STyler Dauwalder /*! \brief idb_entry_tag::strategy_type() values 1850e631ed51STyler Dauwalder 1851e631ed51STyler Dauwalder See also UDF-2.50 2.3.5.1 1852e631ed51STyler Dauwalder */ 1853e631ed51STyler Dauwalder enum icb_strategy_types { 1854e631ed51STyler Dauwalder ICB_STRATEGY_SINGLE = 4, 1855e631ed51STyler Dauwalder ICB_STRATEGY_LINKED_LIST = 4096 1856e631ed51STyler Dauwalder }; 1857e631ed51STyler Dauwalder 1858ead0c3e2STyler Dauwalder /*! \brief ICB entry tag 1859ead0c3e2STyler Dauwalder 1860ead0c3e2STyler Dauwalder Common tag found in all ICB entries (in addition to, and immediately following, 1861ead0c3e2STyler Dauwalder the descriptor tag). 1862ead0c3e2STyler Dauwalder 1863ead0c3e2STyler Dauwalder See also: ECMA-167 4/14.6, UDF-2.01 2.3.5 1864ead0c3e2STyler Dauwalder */ 1865ead0c3e2STyler Dauwalder struct icb_entry_tag { 1866e631ed51STyler Dauwalder public: 1867ead0c3e2STyler Dauwalder union flags_accessor { 1868ead0c3e2STyler Dauwalder uint16 all_flags; 1869ead0c3e2STyler Dauwalder struct { 1870ead0c3e2STyler Dauwalder uint16 descriptor_flags:3, 1871ead0c3e2STyler Dauwalder if_directory_then_sort:1, //!< To be set to 0 per UDF-2.01 2.3.5.4 1872ead0c3e2STyler Dauwalder non_relocatable:1, 1873ead0c3e2STyler Dauwalder archive:1, 1874ead0c3e2STyler Dauwalder setuid:1, 1875ead0c3e2STyler Dauwalder setgid:1, 1876ead0c3e2STyler Dauwalder sticky:1, 1877ead0c3e2STyler Dauwalder contiguous:1, 1878ead0c3e2STyler Dauwalder system:1, 1879ead0c3e2STyler Dauwalder transformed:1, 1880ead0c3e2STyler Dauwalder multi_version:1, //!< To be set to 0 per UDF-2.01 2.3.5.4 1881ead0c3e2STyler Dauwalder is_stream:1, 1882ead0c3e2STyler Dauwalder reserved_icb_entry_flags:2; 1883ead0c3e2STyler Dauwalder } flags; 1884ead0c3e2STyler Dauwalder }; 1885ead0c3e2STyler Dauwalder 1886ead0c3e2STyler Dauwalder public: 1887ead0c3e2STyler Dauwalder void dump() const; 1888ead0c3e2STyler Dauwalder prior_recorded_number_of_direct_entriesicb_entry_tag1889ead0c3e2STyler Dauwalder uint32 prior_recorded_number_of_direct_entries() const { return B_LENDIAN_TO_HOST_INT32(_prior_recorded_number_of_direct_entries); } strategy_typeicb_entry_tag1890ead0c3e2STyler Dauwalder uint16 strategy_type() const { return B_LENDIAN_TO_HOST_INT16(_strategy_type); } 1891ead0c3e2STyler Dauwalder strategy_parametersicb_entry_tag1892ead0c3e2STyler Dauwalder array<uint8, 2>& strategy_parameters() { return _strategy_parameters; } strategy_parametersicb_entry_tag1893ead0c3e2STyler Dauwalder const array<uint8, 2>& strategy_parameters() const { return _strategy_parameters; } 1894ead0c3e2STyler Dauwalder entry_counticb_entry_tag1895ead0c3e2STyler Dauwalder uint16 entry_count() const { return B_LENDIAN_TO_HOST_INT16(_entry_count); } reservedicb_entry_tag1896e631ed51STyler Dauwalder uint8& reserved() { return _reserved; } file_typeicb_entry_tag1897ead0c3e2STyler Dauwalder uint8 file_type() const { return _file_type; } parent_icb_locationicb_entry_tag1898ead0c3e2STyler Dauwalder logical_block_address& parent_icb_location() { return _parent_icb_location; } parent_icb_locationicb_entry_tag1899ead0c3e2STyler Dauwalder const logical_block_address& parent_icb_location() const { return _parent_icb_location; } 1900ead0c3e2STyler Dauwalder flagsicb_entry_tag1901ead0c3e2STyler Dauwalder uint16 flags() const { return B_LENDIAN_TO_HOST_INT16(_flags); } flags_accessicb_entry_tag1902e631ed51STyler Dauwalder flags_accessor& flags_access() { return *reinterpret_cast<flags_accessor*>(&_flags); } 1903ead0c3e2STyler Dauwalder 1904ead0c3e2STyler Dauwalder // flags accessor functions descriptor_flagsicb_entry_tag1905ead0c3e2STyler Dauwalder uint8 descriptor_flags() const { 1906ead0c3e2STyler Dauwalder flags_accessor f; 1907ead0c3e2STyler Dauwalder f.all_flags = flags(); 1908ead0c3e2STyler Dauwalder return f.flags.descriptor_flags; 1909ead0c3e2STyler Dauwalder } 1910e631ed51STyler Dauwalder /* void set_descriptor_flags(uint8 value) { 1911e631ed51STyler Dauwalder flags_accessor f; 1912e631ed51STyler Dauwalder f.all_flags = flags(); 1913e631ed51STyler Dauwalder f.flags.descriptor_flags = value; 1914e631ed51STyler Dauwalder set_flags 1915e631ed51STyler Dauwalder */ 1916ead0c3e2STyler Dauwalder set_prior_recorded_number_of_direct_entriesicb_entry_tag1917ead0c3e2STyler Dauwalder void set_prior_recorded_number_of_direct_entries(uint32 entries) { _prior_recorded_number_of_direct_entries = B_LENDIAN_TO_HOST_INT32(entries); } set_strategy_typeicb_entry_tag1918ead0c3e2STyler Dauwalder void set_strategy_type(uint16 type) { _strategy_type = B_HOST_TO_LENDIAN_INT16(type); } 1919ead0c3e2STyler Dauwalder set_entry_counticb_entry_tag1920ead0c3e2STyler Dauwalder void set_entry_count(uint16 count) { _entry_count = B_LENDIAN_TO_HOST_INT16(count); } set_file_typeicb_entry_tag1921ead0c3e2STyler Dauwalder void set_file_type(uint8 type) { _file_type = type; } 1922ead0c3e2STyler Dauwalder set_flagsicb_entry_tag1923ead0c3e2STyler Dauwalder void set_flags(uint16 flags) { _flags = B_LENDIAN_TO_HOST_INT16(flags); } 1924ead0c3e2STyler Dauwalder 1925ead0c3e2STyler Dauwalder private: 1926ead0c3e2STyler Dauwalder uint32 _prior_recorded_number_of_direct_entries; 1927ead0c3e2STyler Dauwalder /*! Per UDF-2.01 2.3.5.1, only strategy types 4 and 4096 shall be supported. 1928ead0c3e2STyler Dauwalder 1929ead0c3e2STyler Dauwalder \todo Describe strategy types here. 1930ead0c3e2STyler Dauwalder */ 1931ead0c3e2STyler Dauwalder uint16 _strategy_type; 1932ead0c3e2STyler Dauwalder array<uint8, 2> _strategy_parameters; 1933ead0c3e2STyler Dauwalder uint16 _entry_count; 1934ead0c3e2STyler Dauwalder uint8 _reserved; 1935ead0c3e2STyler Dauwalder /*! \brief icb_file_type value identifying the type of this icb entry */ 1936ead0c3e2STyler Dauwalder uint8 _file_type; 1937ead0c3e2STyler Dauwalder logical_block_address _parent_icb_location; 1938ead0c3e2STyler Dauwalder uint16 _flags; 1939ead0c3e2STyler Dauwalder } __attribute__((packed)); 1940ead0c3e2STyler Dauwalder 1941ead0c3e2STyler Dauwalder /*! \brief Header portion of an ICB entry. 1942ead0c3e2STyler Dauwalder */ 1943ead0c3e2STyler Dauwalder struct icb_header { 1944ead0c3e2STyler Dauwalder public: 1945ead0c3e2STyler Dauwalder void dump() const; 1946ead0c3e2STyler Dauwalder tagicb_header1947ead0c3e2STyler Dauwalder descriptor_tag &tag() { return _tag; } tagicb_header1948ead0c3e2STyler Dauwalder const descriptor_tag &tag() const { return _tag; } 1949ead0c3e2STyler Dauwalder icb_tagicb_header1950ead0c3e2STyler Dauwalder icb_entry_tag &icb_tag() { return _icb_tag; } icb_tagicb_header1951ead0c3e2STyler Dauwalder const icb_entry_tag &icb_tag() const { return _icb_tag; } 1952ead0c3e2STyler Dauwalder private: 1953ead0c3e2STyler Dauwalder descriptor_tag _tag; 1954ead0c3e2STyler Dauwalder icb_entry_tag _icb_tag; 1955ead0c3e2STyler Dauwalder }; 1956ead0c3e2STyler Dauwalder 1957ead0c3e2STyler Dauwalder /*! \brief Indirect ICB entry 1958ead0c3e2STyler Dauwalder */ 1959ead0c3e2STyler Dauwalder struct indirect_icb_entry { 1960ead0c3e2STyler Dauwalder descriptor_tag tag; 1961ead0c3e2STyler Dauwalder icb_entry_tag icb_tag; 1962ead0c3e2STyler Dauwalder long_address indirect_icb; 1963ead0c3e2STyler Dauwalder } __attribute__((packed)); 1964ead0c3e2STyler Dauwalder 1965ead0c3e2STyler Dauwalder 1966ead0c3e2STyler Dauwalder /*! \brief Terminal ICB entry 1967ead0c3e2STyler Dauwalder */ 1968ead0c3e2STyler Dauwalder struct terminal_icb_entry { 1969ead0c3e2STyler Dauwalder descriptor_tag tag; 1970ead0c3e2STyler Dauwalder icb_entry_tag icb_tag; 1971ead0c3e2STyler Dauwalder } __attribute__((packed)); 1972ead0c3e2STyler Dauwalder 1973e631ed51STyler Dauwalder enum permissions { 1974e631ed51STyler Dauwalder OTHER_EXECUTE = 0x0001, 1975e631ed51STyler Dauwalder OTHER_WRITE = 0x0002, 1976e631ed51STyler Dauwalder OTHER_READ = 0x0004, 1977e631ed51STyler Dauwalder OTHER_ATTRIBUTES = 0x0008, 1978e631ed51STyler Dauwalder OTHER_DELETE = 0x0010, 1979e631ed51STyler Dauwalder GROUP_EXECUTE = 0x0020, 1980e631ed51STyler Dauwalder GROUP_WRITE = 0x0040, 1981e631ed51STyler Dauwalder GROUP_READ = 0x0080, 1982e631ed51STyler Dauwalder GROUP_ATTRIBUTES = 0x0100, 1983e631ed51STyler Dauwalder GROUP_DELETE = 0x0200, 1984e631ed51STyler Dauwalder USER_EXECUTE = 0x0400, 1985e631ed51STyler Dauwalder USER_WRITE = 0x0800, 1986e631ed51STyler Dauwalder USER_READ = 0x1000, 1987e631ed51STyler Dauwalder USER_ATTRIBUTES = 0x2000, 1988e631ed51STyler Dauwalder USER_DELETE = 0x4000, 1989e631ed51STyler Dauwalder }; 1990ead0c3e2STyler Dauwalder 1991ead0c3e2STyler Dauwalder /*! \brief File ICB entry 1992ead0c3e2STyler Dauwalder 1993ead0c3e2STyler Dauwalder See also: ECMA-167 4/14.9 1994ead0c3e2STyler Dauwalder 1995ead0c3e2STyler Dauwalder \todo Check pointer math. 1996ead0c3e2STyler Dauwalder */ 1997ead0c3e2STyler Dauwalder struct file_icb_entry { 1998e631ed51STyler Dauwalder void dump() const; descriptor_sizefile_icb_entry1999e9927e2bSTyler Dauwalder uint32 descriptor_size() const { return sizeof(*this)+extended_attributes_length() 2000e9927e2bSTyler Dauwalder +allocation_descriptors_length(); } descriptor_namefile_icb_entry2001e9927e2bSTyler Dauwalder const char* descriptor_name() const { return "file_icb_entry"; } 2002e631ed51STyler Dauwalder 2003ead0c3e2STyler Dauwalder // get functions tagfile_icb_entry2004ead0c3e2STyler Dauwalder descriptor_tag & tag() { return _tag; } tagfile_icb_entry2005ead0c3e2STyler Dauwalder const descriptor_tag & tag() const { return _tag; } 2006ead0c3e2STyler Dauwalder icb_tagfile_icb_entry2007ead0c3e2STyler Dauwalder icb_entry_tag& icb_tag() { return _icb_tag; } icb_tagfile_icb_entry2008ead0c3e2STyler Dauwalder const icb_entry_tag& icb_tag() const { return _icb_tag; } 2009ead0c3e2STyler Dauwalder uidfile_icb_entry2010e631ed51STyler Dauwalder uint32 uid() const { return B_LENDIAN_TO_HOST_INT32(_uid); } gidfile_icb_entry2011e631ed51STyler Dauwalder uint32 gid() const { return B_LENDIAN_TO_HOST_INT32(_gid); } permissionsfile_icb_entry2012