1*c2c66affSColin Finck //////////////////////////////////////////////////////////////////// 2*c2c66affSColin Finck // Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine 3*c2c66affSColin Finck // All rights reserved 4*c2c66affSColin Finck // This file was released under the GPLv2 on June 2015. 5*c2c66affSColin Finck //////////////////////////////////////////////////////////////////// 6*c2c66affSColin Finck 7*c2c66affSColin Finck #ifndef _OSTA_MISC_H_ 8*c2c66affSColin Finck #define _OSTA_MISC_H_ 9*c2c66affSColin Finck 10*c2c66affSColin Finck /* based on ECMA 167 structure definitions */ 11*c2c66affSColin Finck #include "ecma_167.h" 12*c2c66affSColin Finck 13*c2c66affSColin Finck #pragma pack(push, 1) 14*c2c66affSColin Finck 15*c2c66affSColin Finck /* -------- Basic types and constants ----------- */ 16*c2c66affSColin Finck /* UDF character set (UDF 1.50 2.1.2) */ 17*c2c66affSColin Finck #define UDF_CHAR_SET_TYPE 0 18*c2c66affSColin Finck #define UDF_CHAR_SET_INFO "OSTA Compressed Unicode" 19*c2c66affSColin Finck 20*c2c66affSColin Finck #define UDF_ID_DEVELOPER ("*WINNT " VER_STR_PRODUCT_NAME " UDF") 21*c2c66affSColin Finck 22*c2c66affSColin Finck #define UDF_ID_DEVELOPER_ADAPTEC "*Adaptec DirectCD" 23*c2c66affSColin Finck 24*c2c66affSColin Finck /* UDF 1.02 2.2.6.4 */ 25*c2c66affSColin Finck struct LogicalVolIntegrityDescImpUse 26*c2c66affSColin Finck { 27*c2c66affSColin Finck EntityID impIdent; 28*c2c66affSColin Finck uint32 numFiles; 29*c2c66affSColin Finck uint32 numDirs; 30*c2c66affSColin Finck uint16 minUDFReadRev; 31*c2c66affSColin Finck uint16 minUDFWriteRev; 32*c2c66affSColin Finck uint16 maxUDFWriteRev; 33*c2c66affSColin Finck }; 34*c2c66affSColin Finck 35*c2c66affSColin Finck /* UDF 1.02 2.2.7.2 */ 36*c2c66affSColin Finck /* LVInformation may be present in ImpUseVolDesc.impUse */ 37*c2c66affSColin Finck struct ImpUseVolDescImpUse 38*c2c66affSColin Finck { 39*c2c66affSColin Finck charspec LVICharset; 40*c2c66affSColin Finck dstring logicalVolIdent[128]; 41*c2c66affSColin Finck dstring LVInfo1[36]; 42*c2c66affSColin Finck dstring LVInfo2[36]; 43*c2c66affSColin Finck dstring LVInfo3[36]; 44*c2c66affSColin Finck EntityID impIdent; 45*c2c66affSColin Finck uint8 impUse[128]; 46*c2c66affSColin Finck }; 47*c2c66affSColin Finck 48*c2c66affSColin Finck struct UdfPartitionMap2 49*c2c66affSColin Finck { 50*c2c66affSColin Finck uint8 partitionMapType; 51*c2c66affSColin Finck uint8 partitionMapLength; 52*c2c66affSColin Finck uint8 reserved1[2]; 53*c2c66affSColin Finck EntityID partIdent; 54*c2c66affSColin Finck uint16 volSeqNum; 55*c2c66affSColin Finck uint16 partitionNum; 56*c2c66affSColin Finck uint8 reserved2[24]; 57*c2c66affSColin Finck }; 58*c2c66affSColin Finck 59*c2c66affSColin Finck /* UDF 1.5 2.2.8 */ 60*c2c66affSColin Finck struct VirtualPartitionMap 61*c2c66affSColin Finck { 62*c2c66affSColin Finck uint8 partitionMapType; /* 2 */ 63*c2c66affSColin Finck uint8 partitionMapLength; /* 64 */ 64*c2c66affSColin Finck uint8 reserved1[2]; /* #00 */ 65*c2c66affSColin Finck EntityID partIdent; 66*c2c66affSColin Finck uint16 volSeqNum; 67*c2c66affSColin Finck uint16 partitionNum; 68*c2c66affSColin Finck uint8 reserved2[24]; /* #00 */ 69*c2c66affSColin Finck }; 70*c2c66affSColin Finck 71*c2c66affSColin Finck #define UDF_VAT_FREE_ENTRY 0xffffffff 72*c2c66affSColin Finck 73*c2c66affSColin Finck /* UDF 1.5 2.2.9 */ 74*c2c66affSColin Finck typedef struct _SPARABLE_PARTITION_MAP 75*c2c66affSColin Finck { 76*c2c66affSColin Finck uint8 partitionMapType; /* 2 */ 77*c2c66affSColin Finck uint8 partitionMapLength; /* 64 */ 78*c2c66affSColin Finck uint8 reserved1[2]; /* #00 */ 79*c2c66affSColin Finck EntityID partIdent; /* Flags = 0 */ 80*c2c66affSColin Finck /* Id = UDF_ID_SPARABLE */ 81*c2c66affSColin Finck /* IdSuf = 2.1.5.3 */ 82*c2c66affSColin Finck uint16 volSeqNum; 83*c2c66affSColin Finck uint16 partitionNum; 84*c2c66affSColin Finck uint16 packetLength; /* 32 */ 85*c2c66affSColin Finck uint8 numSparingTables; 86*c2c66affSColin Finck uint8 reserved2[1]; /* #00 */ 87*c2c66affSColin Finck uint32 sizeSparingTable; 88*c2c66affSColin Finck // uint32 locSparingTable[0]; 89*c2c66affSColin Finck // uint8 pad[0]; 90*c2c66affSColin Finck } SPARABLE_PARTITION_MAP, *PSPARABLE_PARTITION_MAP; 91*c2c66affSColin Finck 92*c2c66affSColin Finck #define UDF_TYPE1_MAP15 0x1511U 93*c2c66affSColin Finck #define UDF_VIRTUAL_MAP15 0x1512U 94*c2c66affSColin Finck #define UDF_VIRTUAL_MAP20 0x2012U 95*c2c66affSColin Finck #define UDF_SPARABLE_MAP15 0x1522U 96*c2c66affSColin Finck #define UDF_METADATA_MAP25 0x2522U 97*c2c66affSColin Finck 98*c2c66affSColin Finck #ifndef PACKETSIZE_UDF 99*c2c66affSColin Finck #define PACKETSIZE_UDF 32 100*c2c66affSColin Finck #endif //PACKETSIZE_UDF 101*c2c66affSColin Finck 102*c2c66affSColin Finck /* UDF 2.5 */ 103*c2c66affSColin Finck typedef struct _METADATA_PARTITION_MAP 104*c2c66affSColin Finck { 105*c2c66affSColin Finck uint8 partitionMapType; /* 2 */ 106*c2c66affSColin Finck uint8 partitionMapLength; /* 64 */ 107*c2c66affSColin Finck uint8 reserved1[2]; /* #00 */ 108*c2c66affSColin Finck EntityID partIdent; /* Flags = 0 */ 109*c2c66affSColin Finck /* Id = UDF_ID_METADATA */ 110*c2c66affSColin Finck /* IdSuf = 2.1.5.3 */ 111*c2c66affSColin Finck uint16 volSeqNum; 112*c2c66affSColin Finck uint16 partitionNum; 113*c2c66affSColin Finck uint32 metadataFELocation; 114*c2c66affSColin Finck uint32 metadataMirrorFELocation; 115*c2c66affSColin Finck uint32 metadataBitmapFELocation; 116*c2c66affSColin Finck uint32 allocationUnit; /* blocks */ 117*c2c66affSColin Finck uint16 alignmentUnit; /* blocks */ 118*c2c66affSColin Finck uint8 flags; 119*c2c66affSColin Finck uint8 pad[5]; 120*c2c66affSColin Finck } METADATA_PARTITION_MAP, *PMETADATA_PARTITION_MAP; 121*c2c66affSColin Finck 122*c2c66affSColin Finck #define UDF_METADATA_DUPLICATED 0x01U 123*c2c66affSColin Finck 124*c2c66affSColin Finck /* DVD Copyright Management Info, see UDF 1.02 3.3.4.5.1.2 */ 125*c2c66affSColin Finck /* when ImpUseExtendedAttr.impIdent= "*UDF DVD CGMS Info" */ 126*c2c66affSColin Finck struct DVDCopyrightImpUse { 127*c2c66affSColin Finck uint16 headerChecksum; 128*c2c66affSColin Finck uint8 CGMSInfo; 129*c2c66affSColin Finck uint8 dataType; 130*c2c66affSColin Finck uint8 protectionSystemInfo[4]; 131*c2c66affSColin Finck }; 132*c2c66affSColin Finck 133*c2c66affSColin Finck /* the impUse of long_ad used in AllocDescs - UDF 1.02 2.3.10.1 */ 134*c2c66affSColin Finck struct ADImpUse 135*c2c66affSColin Finck { 136*c2c66affSColin Finck uint16 flags; 137*c2c66affSColin Finck uint8 impUse[4]; 138*c2c66affSColin Finck }; 139*c2c66affSColin Finck 140*c2c66affSColin Finck /* the impUse of long_ad used in AllocDescs - UDF 1.02 2.3.10.1 */ 141*c2c66affSColin Finck struct FidADImpUse 142*c2c66affSColin Finck { 143*c2c66affSColin Finck uint8 reserved[2]; 144*c2c66affSColin Finck uint32 uniqueID; 145*c2c66affSColin Finck }; 146*c2c66affSColin Finck 147*c2c66affSColin Finck /* UDF 1.02 2.3.10.1 */ 148*c2c66affSColin Finck #define UDF_EXTENT_LENGTH_MASK 0x3FFFFFFF 149*c2c66affSColin Finck #define UDF_EXTENT_FLAG_MASK 0xc0000000 150*c2c66affSColin Finck #define UDF_EXTENT_FLAG_ERASED 0x40000000 151*c2c66affSColin Finck 152*c2c66affSColin Finck /* 153*c2c66affSColin Finck * Important! VirtualAllocationTables are 154*c2c66affSColin Finck * very different between 1.5 and 2.0! 155*c2c66affSColin Finck */ 156*c2c66affSColin Finck 157*c2c66affSColin Finck /* ----------- 1.5 ------------- */ 158*c2c66affSColin Finck /* UDF 1.5 2.2.10 */ 159*c2c66affSColin Finck #define UDF_FILE_TYPE_VAT15 0x0U 160*c2c66affSColin Finck 161*c2c66affSColin Finck /* UDF 1.5 2.2.10 - VAT layout: */ 162*c2c66affSColin Finck struct VirtualAllocationTable15 { 163*c2c66affSColin Finck /* uint32 VirtualSector[0];*/ 164*c2c66affSColin Finck EntityID ident; 165*c2c66affSColin Finck uint32 previousVATICB; 166*c2c66affSColin Finck }; 167*c2c66affSColin Finck /* where number of VirtualSector's is (VATSize-36)/4 */ 168*c2c66affSColin Finck 169*c2c66affSColin Finck /* ----------- 2.0 ------------- */ 170*c2c66affSColin Finck /* UDF 2.0 2.2.10 */ 171*c2c66affSColin Finck #define UDF_FILE_TYPE_VAT20 0xf8U 172*c2c66affSColin Finck 173*c2c66affSColin Finck /* UDF 2.0 2.2.10 (different from 1.5!) */ 174*c2c66affSColin Finck struct VirtualAllocationTable20 { 175*c2c66affSColin Finck uint16 lengthHeader; 176*c2c66affSColin Finck uint16 lengthImpUse; 177*c2c66affSColin Finck dstring logicalVolIdent[128]; 178*c2c66affSColin Finck uint32 previousVatICBLoc; 179*c2c66affSColin Finck uint32 numFIDSFiles; 180*c2c66affSColin Finck uint32 numFIDSDirectories; /* non-parent */ 181*c2c66affSColin Finck uint16 minReadRevision; 182*c2c66affSColin Finck uint16 minWriteRevision; 183*c2c66affSColin Finck uint16 maxWriteRevision; 184*c2c66affSColin Finck uint16 reserved; 185*c2c66affSColin Finck /* uint8 impUse[0];*/ 186*c2c66affSColin Finck /* uint32 vatEntry[0];*/ 187*c2c66affSColin Finck }; 188*c2c66affSColin Finck 189*c2c66affSColin Finck /* Sparing maps, see UDF 1.5 2.2.11 */ 190*c2c66affSColin Finck typedef struct _SparingEntry { 191*c2c66affSColin Finck uint32 origLocation; 192*c2c66affSColin Finck uint32 mappedLocation; 193*c2c66affSColin Finck } SparingEntry; 194*c2c66affSColin Finck 195*c2c66affSColin Finck #define SPARING_LOC_AVAILABLE 0xffffffff 196*c2c66affSColin Finck #define SPARING_LOC_CORRUPTED 0xfffffff0 197*c2c66affSColin Finck 198*c2c66affSColin Finck typedef SparingEntry SPARING_ENTRY; 199*c2c66affSColin Finck typedef SPARING_ENTRY* PSPARING_ENTRY; 200*c2c66affSColin Finck 201*c2c66affSColin Finck typedef SPARING_ENTRY SPARING_MAP; 202*c2c66affSColin Finck typedef PSPARING_ENTRY PSPARING_MAP; 203*c2c66affSColin Finck 204*c2c66affSColin Finck /* sparing maps, see UDF 2.0 2.2.11 */ 205*c2c66affSColin Finck typedef struct _SPARING_TABLE { 206*c2c66affSColin Finck tag descTag; 207*c2c66affSColin Finck EntityID sparingIdent; /* *UDF Sparing Table */ 208*c2c66affSColin Finck uint16 reallocationTableLen; 209*c2c66affSColin Finck uint16 reserved; /* #00 */ 210*c2c66affSColin Finck uint32 sequenceNum; 211*c2c66affSColin Finck // SparingEntry mapEntry[0]; 212*c2c66affSColin Finck } SPARING_TABLE, *PSPARING_TABLE; 213*c2c66affSColin Finck 214*c2c66affSColin Finck /* Identifier Suffixes, see EntityID */ 215*c2c66affSColin Finck 216*c2c66affSColin Finck typedef struct { 217*c2c66affSColin Finck uint16 currentRev; 218*c2c66affSColin Finck uint8 flags; 219*c2c66affSColin Finck uint8 reserved[5]; 220*c2c66affSColin Finck } domainIdentSuffix; 221*c2c66affSColin Finck 222*c2c66affSColin Finck #define ENTITYID_FLAGS_HARD_RO 0x01U 223*c2c66affSColin Finck #define ENTITYID_FLAGS_SOFT_RO 0x02U 224*c2c66affSColin Finck 225*c2c66affSColin Finck typedef struct { 226*c2c66affSColin Finck uint16 currentRev; 227*c2c66affSColin Finck uint8 OSClass; 228*c2c66affSColin Finck uint8 OSIdent; 229*c2c66affSColin Finck uint8 reserved[4]; 230*c2c66affSColin Finck } UDFIdentSuffix; 231*c2c66affSColin Finck 232*c2c66affSColin Finck typedef struct { 233*c2c66affSColin Finck uint8 OSClass; 234*c2c66affSColin Finck uint8 OSIdent; 235*c2c66affSColin Finck uint8 reserved[6]; 236*c2c66affSColin Finck } impIdentSuffix; 237*c2c66affSColin Finck 238*c2c66affSColin Finck /* Unique ID maps, see UDF 2.0 2.2.11 */ 239*c2c66affSColin Finck 240*c2c66affSColin Finck typedef struct { 241*c2c66affSColin Finck uint32 uniqueID; 242*c2c66affSColin Finck uint32 parentLogicalBlock; 243*c2c66affSColin Finck uint32 objectLogicalBlock; 244*c2c66affSColin Finck uint16 parentPartitionReferenceNum; 245*c2c66affSColin Finck uint16 objectPartitionReferenceNum; 246*c2c66affSColin Finck } UniqueIDEntry; 247*c2c66affSColin Finck 248*c2c66affSColin Finck typedef UniqueIDEntry UID_MAPPING_ENTRY; 249*c2c66affSColin Finck typedef UID_MAPPING_ENTRY* PUID_MAPPING_ENTRY; 250*c2c66affSColin Finck 251*c2c66affSColin Finck typedef struct { 252*c2c66affSColin Finck EntityID ident; 253*c2c66affSColin Finck uint32 flags; 254*c2c66affSColin Finck uint32 entryCount; 255*c2c66affSColin Finck uint8 reserved[8]; 256*c2c66affSColin Finck // UniqueIDEntry mapEntry[0]; 257*c2c66affSColin Finck } UniqueIDMappingData; 258*c2c66affSColin Finck 259*c2c66affSColin Finck typedef UniqueIDMappingData UID_MAPPING_TABLE; 260*c2c66affSColin Finck typedef UID_MAPPING_TABLE* PUID_MAPPING_TABLE; 261*c2c66affSColin Finck 262*c2c66affSColin Finck /* Entity Identifiers (UDF 1.50 6.1) */ 263*c2c66affSColin Finck #define UDF_ID_COMPLIANT "*OSTA UDF Compliant" 264*c2c66affSColin Finck #define UDF_ID_LV_INFO "*UDF LV Info" 265*c2c66affSColin Finck #define UDF_ID_FREE_EA "*UDF FreeEASpace" 266*c2c66affSColin Finck #define UDF_ID_FREE_APP_EA "*UDF FreeAppEASpace" 267*c2c66affSColin Finck #define UDF_ID_DVD_CGMS "*UDF DVD CGMS Info" 268*c2c66affSColin Finck #define UDF_ID_OS2_EA "*UDF OS/2 EA" 269*c2c66affSColin Finck #define UDF_ID_OS2_EA_LENGTH "*UDF OS/2 EALength" 270*c2c66affSColin Finck #define UDF_ID_OS400_DIRINFO "*UDF OS/400 DirInfo" 271*c2c66affSColin Finck #define UDF_ID_MAC_VOLUME "*UDF Mac VolumeInfo" 272*c2c66affSColin Finck #define UDF_ID_MAC_FINDER "*UDF Mac FinderInfo" 273*c2c66affSColin Finck #define UDF_ID_MAC_UNIQUE "*UDF Mac UniqueIDTable" 274*c2c66affSColin Finck #define UDF_ID_MAC_RESOURCE "*UDF Mac ResourceFork" 275*c2c66affSColin Finck #define UDF_ID_VIRTUAL "*UDF Virtual Partition" 276*c2c66affSColin Finck #define UDF_ID_SPARABLE "*UDF Sparable Partition" 277*c2c66affSColin Finck #define UDF_ID_METADATA "*UDF Metadata Partition" 278*c2c66affSColin Finck #define UDF_ID_ALLOC "*UDF Virtual Alloc Tbl" 279*c2c66affSColin Finck #define UDF_ID_SPARING "*UDF Sparing Table" 280*c2c66affSColin Finck 281*c2c66affSColin Finck /* Operating System Identifiers (UDF 1.50 6.3) */ 282*c2c66affSColin Finck #define UDF_OS_CLASS_UNDEF 0x00U 283*c2c66affSColin Finck #define UDF_OS_CLASS_DOS 0x01U 284*c2c66affSColin Finck #define UDF_OS_CLASS_OS2 0x02U 285*c2c66affSColin Finck #define UDF_OS_CLASS_MAC 0x03U 286*c2c66affSColin Finck #define UDF_OS_CLASS_UNIX 0x04U 287*c2c66affSColin Finck #define UDF_OS_CLASS_WIN95 0x05U 288*c2c66affSColin Finck #define UDF_OS_CLASS_WINNT 0x06U 289*c2c66affSColin Finck #define UDF_OS_CLASS_OS400 0x07U 290*c2c66affSColin Finck #define UDF_OS_CLASS_BEOS 0x08U 291*c2c66affSColin Finck #define UDF_OS_CLASS_WINCE 0x09U 292*c2c66affSColin Finck 293*c2c66affSColin Finck #define UDF_OS_ID_GENERIC 0x00U 294*c2c66affSColin Finck #define UDF_OS_ID_UNDEF 0x00U 295*c2c66affSColin Finck #define UDF_OS_ID_DOS 0x00U 296*c2c66affSColin Finck #define UDF_OS_ID_OS2 0x00U 297*c2c66affSColin Finck #define UDF_OS_ID_MAC 0x00U 298*c2c66affSColin Finck #define UDF_OS_ID_UNIX 0x00U 299*c2c66affSColin Finck #define UDF_OS_ID_WIN95 0x00U 300*c2c66affSColin Finck #define UDF_OS_ID_WINNT 0x00U 301*c2c66affSColin Finck #define UDF_OS_ID_OS400 0x00U 302*c2c66affSColin Finck #define UDF_OS_ID_BEOS 0x00U 303*c2c66affSColin Finck 304*c2c66affSColin Finck #define UDF_OS_ID_AIX 0x01U 305*c2c66affSColin Finck #define UDF_OS_ID_SOLARIS 0x02U 306*c2c66affSColin Finck #define UDF_OS_ID_HPUX 0x03U 307*c2c66affSColin Finck #define UDF_OS_ID_IRIX 0x04U 308*c2c66affSColin Finck #define UDF_OS_ID_LINUX 0x05U 309*c2c66affSColin Finck #define UDF_OS_ID_MKLINUX 0x06U 310*c2c66affSColin Finck #define UDF_OS_ID_FREEBSD 0x07U 311*c2c66affSColin Finck #define UDF_OS_ID_NETBSD 0x08U 312*c2c66affSColin Finck 313*c2c66affSColin Finck #define UDF_NAME_PAD 4 314*c2c66affSColin Finck #define UDF_NAME_LEN 255 315*c2c66affSColin Finck #define UDF_EXT_SIZE 5 // ??? 316*c2c66affSColin Finck #define UDF_PATH_LEN 1023 317*c2c66affSColin Finck #define UDF_VOL_LABEL_LEN 32 318*c2c66affSColin Finck 319*c2c66affSColin Finck /* Reserved file names */ 320*c2c66affSColin Finck 321*c2c66affSColin Finck #define UDF_FN_NON_ALLOCATABLE L"Non-Allocatable Space" 322*c2c66affSColin Finck #define UDF_FN_NON_ALLOCATABLE_2 L"Non-Allocatable List" 323*c2c66affSColin Finck 324*c2c66affSColin Finck #define UDF_FN_NON_ALLOCATABLE_USER "Non-Allocatable Space" 325*c2c66affSColin Finck #define UDF_FN_NON_ALLOCATABLE_2_USER "Non-Allocatable List" 326*c2c66affSColin Finck 327*c2c66affSColin Finck /* Reserved system stream names */ 328*c2c66affSColin Finck /* METADATA bit shall be set to 1 */ 329*c2c66affSColin Finck 330*c2c66affSColin Finck #define UDF_SN_UID_MAPPING L"*UDF Unique ID Mapping Data" 331*c2c66affSColin Finck #define UDF_SN_NON_ALLOCATABLE L"*UDF Non-Allocatable Space" 332*c2c66affSColin Finck #define UDF_SN_POWER_CAL_TABLE L"*UDF Power Cal Table" 333*c2c66affSColin Finck #define UDF_SN_BACKUP L"*UDF Backup" 334*c2c66affSColin Finck 335*c2c66affSColin Finck /* Reserved non-system stream names */ 336*c2c66affSColin Finck /* METADATA bit shall be set to 0 */ 337*c2c66affSColin Finck 338*c2c66affSColin Finck #define UDF_SN_MAC_RESOURCE_FORK L"*UDF Macintosh Resource Fork" 339*c2c66affSColin Finck #define UDF_SN_OS2_EA L"*UDF OS/2 EA" 340*c2c66affSColin Finck #define UDF_SN_NT_ACL L"*UDF NT ACL" 341*c2c66affSColin Finck #define UDF_SN_UNIX_ACL L"*UDF UNIX ACL" 342*c2c66affSColin Finck 343*c2c66affSColin Finck #define UDF_RESERVED_NAME_HDR L"*UDF " 344*c2c66affSColin Finck 345*c2c66affSColin Finck /* ----------- 2.01 ------------ */ 346*c2c66affSColin Finck /* UDF 2.0 2.2.10 */ 347*c2c66affSColin Finck #define UDF_FILE_TYPE_REALTIME 0xf9U 348*c2c66affSColin Finck 349*c2c66affSColin Finck #define TID_ADAPTEC_LOGICAL_VOL_DESC 0x9999U 350*c2c66affSColin Finck 351*c2c66affSColin Finck #pragma pack(pop) 352*c2c66affSColin Finck 353*c2c66affSColin Finck #endif /* _OSTA_MISC_H */ 354