VirtualBox

Changeset 68920 in vbox


Ignore:
Timestamp:
Sep 29, 2017 8:25:15 AM (7 years ago)
Author:
vboxsync
Message:

iprt: udf reading updates

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/err.h

    r67842 r68920  
    28672867/** @} */
    28682868
     2869
     2870/** @name RTFsIsoVol status codes
     2871 * @{ */
     2872/** Descriptor tag is all zeros. */
     2873#define VERR_ISOFS_TAG_IS_ALL_ZEROS                     (-25300)
     2874/** Unsupported descriptor tag version. */
     2875#define VERR_ISOFS_UNSUPPORTED_TAG_VERSION              (-25301)
     2876/** Bad descriptor tag checksum. */
     2877#define VERR_ISOFS_BAD_TAG_CHECKSUM                     (-25302)
     2878/** Descriptor tag sector number mismatch. */
     2879#define VERR_ISOFS_TAG_SECTOR_MISMATCH                  (-25303)
     2880/** Descriptor CRC mismatch. */
     2881#define VERR_ISOFS_DESC_CRC_MISMATCH                    (-25304)
     2882/** Insufficient data to check descriptor CRC. */
     2883#define VERR_ISOFS_INSUFFICIENT_DATA_FOR_DESC_CRC       (-25305)
     2884/** Unexpected/unknown/bad descriptor in volume descriptor sequence. */
     2885#define VERR_ISOFS_UNEXPECTED_VDS_DESC                  (-25306)
     2886
     2887/** @} */
     2888
    28692889/* SED-END */
    28702890
  • trunk/include/iprt/formats/udf.h

    r68687 r68920  
    346346 *
    347347 * @{ */
    348 /** Primary volume descriptor, implementation ID field.
    349  * Implementation ID suffix. */
    350 #define UDF_ENTITY_ID_PVD_IMPLEMENTATION        "*Developer ID"
    351 /** Primary volume descriptor, application ID field.
    352  * Application ID suffix. */
    353 #define UDF_ENTITY_ID_PVD_APPLICATION           "*Application ID"
    354 
    355348/** Implementation use volume descriptor, implementation ID field.
    356349 * UDF ID suffix. */
    357350#define UDF_ENTITY_ID_IUVD_IMPLEMENTATION       "*UDF LV Info"
    358 /** Implementation use volume descriptor, implementation ID field in Use field.
    359  * Implementation ID suffix. */
    360 #define UDF_ENTITY_ID_IUVD_USE_IMPLEMENTATION   "*Developer ID"
    361 
    362 /** Partition descriptor, implementation ID field.
    363  * Implementation ID suffix. */
    364 #define UDF_ENTITY_ID_PD_IMPLEMENTATION         "*Developer ID"
     351
    365352/** Partition descriptor, partition contents field, set to indicate UDF
    366353 * (ECMA-167 3rd edition). Application ID suffix. */
     
    376363#define UDF_ENTITY_ID_PD_PARTITION_CONTENTS_FAT     "+FDC01"
    377364
    378 /** Logical volume descriptor, implementation ID field.
    379  * Implementation ID suffix. */
    380 #define UDF_ENTITY_ID_LVD_IMPLEMENTATION        "*Developer ID"
    381365/** Logical volume descriptor, domain ID field.
    382366 * Domain ID suffix. */
     
    386370 * Domain ID suffix. */
    387371#define UDF_ENTITY_FSD_LVD_DOMAIN               "*OSTA UDF Compliant"
    388 
    389 /** File identifier descriptor, implementation use field.
    390  * Implementation ID suffix. */
    391 #define UDF_ENTITY_ID_FID_IMPLEMENTATION_USE    "*Developer ID"
    392 
    393 /** File entry, implementation ID field.
    394  * Implementation ID suffix. */
    395 #define UDF_ENTITY_ID_FE_IMPLEMENTATION         "*Developer ID"
    396 
    397 /** Device specification extended attribute, implementation use field.
    398  * Implementation ID suffix. */
    399 #define UDF_ENTITY_ID_DSEA_IMPLEMENTATION_USE   "*Developer ID"
    400372
    401373/** UDF implementation use extended attribute, implementation ID field, set
     
    418390#define UDF_ENTITY_ID_IUEA_OS400_DIR_INFO       "*UDF OS/400 DirInfo"
    419391
    420 /** Non-UDF implementation use extended attribute, implementation ID field.
    421  * Implementation ID suffix. */
    422 #define UDF_ENTITY_ID_NUIUSEA_IMPLEMENTATION    "*Developer ID"
    423 
    424392/** UDF application use extended attribute, application ID field, set
    425393 * to free application use EA space.  UDF ID suffix. */
    426394#define UDF_ENTITY_ID_AUEA_FREE_EA_SPACE        "*UDF FreeAppEASpace"
    427395
    428 /** Non-UDF application use extended attribute, implementation ID field.
    429  * Application ID suffix. */
    430 #define UDF_ENTITY_ID_NUAUEA_IMPLEMENTATION     "*Application ID"
    431 
    432 /** UDF unique ID mapping data, implementation ID field.
    433  * Implementation ID suffix. */
    434 #define UDF_ENTITY_ID_UIMD_IMPLEMENTATION       "*Developer ID"
    435 
    436 /** Power calibration table stream, implementation ID field.
    437  * Implementation ID suffix. */
    438 #define UDF_ENTITY_ID_PCTS_IMPLEMENTATION       "*Developer ID"
    439 
    440 /** Logical volume integrity descriptor, implementation ID field.
    441  * Implementation ID suffix. */
    442 #define UDF_ENTITY_ID_LVID_IMPLEMENTATION       "*Developer ID"
    443 
    444396/** Virtual partition map, partition type field.
    445397 * UDF ID suffix. */
    446398#define UDF_ENTITY_ID_VPM_PARTITION_TYPE        "*UDF Virtual Partition"
    447 
    448 /** Virtual allocation table, implementation use field.
    449  * Implementation ID suffix. */
    450 #define UDF_ENTITY_ID_VAT_IMPLEMENTATION_USE    "*Developer ID"
    451399
    452400/** Sparable partition map, partition type field.
     
    559507    /** 0x150: Volume copyright notice. */
    560508    UDFEXTENTAD     VolumeCopyrightNotice;
    561     /** 0x158: Application identifier (UDF_ENTITY_ID_PVD_APPLICATION). */
     509    /** 0x158: Application identifier ("*Application ID"). */
    562510    UDFENTITYID     idApplication;
    563511    /** 0x178: Recording date and time. */
    564512    UDFTIMESTAMP    RecordingTimestamp;
    565     /** 0x184: Implementation identifier (UDF_ENTITY_ID_PVD_IMPLEMENTATION). */
     513    /** 0x184: Implementation identifier ("*Developer ID"). */
    566514    UDFENTITYID     idImplementation;
    567515    /** 0x1a4: Implementation use. */
     
    665613            /** 0x13c: Info string \#3. */
    666614            UDFDSTRING      achInfo3[36];
    667             /** 0x160: The implementation identifier
    668              * (UDF_ENTITY_ID_IUVD_USE_IMPLEMENTATION). */
     615            /** 0x160: The implementation identifier ("*Developer ID"). */
    669616            UDFENTITYID     idImplementation;
    670617            /** 0x180: Additional use bytes. */
     
    744691    /** 0x0c0: Partition length in sectors. */
    745692    uint32_t        cSectors;
    746     /** 0x0c4: Implementation identifier (UDF_ENTITY_ID_PD_IMPLEMENTATION). */
     693    /** 0x0c4: Implementation identifier ("*Developer ID"). */
    747694    UDFENTITYID     idImplementation;
    748695    /** 0x0e4: Implemenation use bytes. */
     
    751698        /** Generic view. */
    752699        uint8_t     ab[128];
    753 
    754700    } ImplementationUse;
    755701    /** 0x164: Reserved. */
     
    757703} UDFPARTITIONDESC;
    758704AssertCompileSize(UDFPARTITIONDESC, 512);
     705/** Pointer to an UDF partitions descriptor. */
     706typedef UDFPARTITIONDESC *PUDFPARTITIONDESC;
     707/** Pointer to a const UDF partitions descriptor. */
     708typedef const UDFPARTITIONDESC *PCUDFPARTITIONDESC;
    759709
    760710/** @name UDF_PART_ACCESS_TYPE_XXX - UDF partition access types
     
    807757    /** 0x10c: Number of partition maps. */
    808758    uint32_t        cPartitionMaps;
    809     /** 0x110: Implementation identifier (UDF_ENTITY_ID_LVD_IMPLEMENTATION). */
     759    /** 0x110: Implementation identifier ("*Developer ID"). */
    810760    UDFENTITYID     idImplementation;
    811761    /** 0x130: Implementation use. */
     
    817767    /** 0x1b0: Integrity sequence extent. Can be zero if cPartitionMaps is zero. */
    818768    UDFEXTENTAD     IntegritySeqExtent;
    819     /** 0x1b8: Partition maps (length given by @a cPartitionMaps). */
     769    /** 0x1b8: Partition maps (length given by @a cbMapTable), data format is
     770     * defined by UDFPARTMAPHDR, UDFPARTMAPTYPE1 and UDFPARTMAPTYPE2. */
    820771    uint8_t         abPartitionMaps[RT_FLEXIBLE_ARRAY];
    821772} UDFLOGICALVOLUMEDESC;
     
    825776/** Pointer to a const UDF logical volume descriptor. */
    826777typedef UDFLOGICALVOLUMEDESC const *PCUDFLOGICALVOLUMEDESC;
     778
     779/**
     780 * Partition map header (UDFLOGICALVOLUMEDESC::abPartitionMaps).
     781 */
     782typedef struct UDFPARTMAPHDR
     783{
     784    /** 0x00: The partition map type. */
     785    uint8_t         bType;
     786    /** 0x01: The partition map length (header included). */
     787    uint8_t         cb;
     788} UDFPARTMAPHDR;
     789AssertCompileSize(UDFPARTMAPHDR, 2);
     790/** Pointer to a partition map header. */
     791typedef UDFPARTMAPHDR *PUDFPARTMAPHDR;
     792/** Pointer to a const partition map header. */
     793typedef UDFPARTMAPHDR const *PCUDFPARTMAPHDR;
     794
     795/**
     796 * Partition map type 1 (UDFLOGICALVOLUMEDESC::abPartitionMaps).
     797 */
     798typedef struct UDFPARTMAPTYPE1
     799{
     800    /** 0x00: Header (uType=1, cb=6). */
     801    UDFPARTMAPHDR   Hdr;
     802    /** 0x02: Volume sequence number. */
     803    uint16_t        uVolumeSeqNo;
     804    /** 0x04: Partition number. */
     805    uint16_t        uPartitionNo;
     806} UDFPARTMAPTYPE1;
     807AssertCompileSize(UDFPARTMAPTYPE1, 6);
     808/** Pointer to a type 1 partition map. */
     809typedef UDFPARTMAPTYPE1 *PUDFPARTMAPTYPE1;
     810/** Pointer to a const type 1 partition map. */
     811typedef UDFPARTMAPTYPE1 const *PCUDFPARTMAPTYPE1;
     812
     813/**
     814 * Partition map type 2 (UDFLOGICALVOLUMEDESC::abPartitionMaps).
     815 */
     816typedef struct UDFPARTMAPTYPE2
     817{
     818    /** 0x00: Header (uType=2, cb=64). */
     819    UDFPARTMAPHDR   Hdr;
     820    /** 0x02: Reserved \#1. */
     821    uint16_t        uReserved1;
     822    /** 0x04: Partition number (UDF_ENTITY_ID_VPM_PARTITION_TYPE). */
     823    UDFENTITYID     idPartitionType;
     824    /** 0x24: Volume sequence number. */
     825    uint16_t        uVolumeSeqNo;
     826    /** 0x26: Partition number. */
     827    uint16_t        uPartitionNo;
     828    /** 0x28: Reserved \#2. */
     829    uint8_t         abReserved2[24];
     830} UDFPARTMAPTYPE2;
     831AssertCompileSize(UDFPARTMAPTYPE2, 64);
     832/** Pointer to a type 2 partition map. */
     833typedef UDFPARTMAPTYPE2 *PUDFPARTMAPTYPE2;
     834/** Pointer to a const type 2 partition map1. */
     835typedef UDFPARTMAPTYPE2 const *PCUDFPARTMAPTYPE2;
    827836
    828837
     
    12451254    /** 0x70: Extended attribute information control block location. */
    12461255    UDFLONGAD       ExtAttribIcb;
    1247     /** 0x80: Implementation identifier (UDF_ENTITY_ID_FE_IMPLEMENTATION). */
     1256    /** 0x80: Implementation identifier ("*Developer ID"). */
    12481257    UDFENTITYID     idImplementation;
    12491258    /** 0xa0: Unique ID. */
     
    14521461    uint32_t        uMinorDeviceNo;
    14531462    /** 0x0c/0x18: Implementation use field (variable length).
    1454      * UDF specficiation expects UDFENTITYID with
    1455      * UDF_ENTITY_ID_DSEA_IMPLEMENTATION_USE as first part here. */
     1463     * UDF specficiation expects UDFENTITYID with a "*Developer ID" as first part
     1464     * here. */
    14561465    uint8_t         abImplementationUse[RT_FLEXIBLE_ARRAY_IN_NESTED_UNION];
    14571466} UDFEADATADEVICESPEC;
  • trunk/src/VBox/Runtime/common/fs/isovfs.cpp

    r68697 r68920  
    3636#include <iprt/assert.h>
    3737#include <iprt/err.h>
     38#include <iprt/crc.h>
    3839#include <iprt/ctype.h>
    3940#include <iprt/file.h>
     
    174175typedef RTFSISODIROBJ *PRTFSISODIROBJ;
    175176
     177/**
     178 * Information about a logical partition.
     179 */
     180typedef struct RTFSISOVOLUDFPART
     181{
     182    /** Partition number (not index). */
     183    uint16_t            uPartitionNo;
     184    uint16_t            fFlags;
     185    /** Number of sectors. */
     186    uint32_t            cSectors;
     187#if 0
     188
     189
     190    /** 0x000: The descriptor tag (UDF_TAG_ID_PARTITION_DESC). */
     191    UDFTAG          Tag;
     192    /** 0x010: Volume descriptor sequence number. */
     193    uint32_t        uVolumeDescSeqNo;
     194    /** 0x014: The partition flags (UDF_PARTITION_FLAGS_XXX).   */
     195    uint16_t        fFlags;
     196    /** 0x016: The partition number. */
     197    uint16_t        uPartitionNo;
     198    /** 0x018: Partition contents (UDF_ENTITY_ID_PD_PARTITION_CONTENTS_XXX). */
     199    UDFENTITYID     PartitionContents;
     200    /** 0x038: partition contents use (depends on the PartitionContents field). */
     201    union
     202    {
     203        /** Generic view. */
     204        uint8_t     ab[128];
     205        /** UDF partition header descriptor (UDF_ENTITY_ID_PD_PARTITION_CONTENTS_UDF). */
     206        UDFPARTITIONHDRDESC Hdr;
     207    } ContentsUse;
     208    /** 0x0b8: Access type (UDF_PART_ACCESS_TYPE_XXX).  */
     209    uint32_t        uAccessType;
     210    /** 0x0bc: Partition starting location (logical sector number). */
     211    uint32_t        offLocation;
     212    /** 0x0c0: Partition length in sectors. */
     213    uint32_t        cSectors;
     214    /** 0x0c4: Implementation identifier ("*Developer ID"). */
     215    UDFENTITYID     idImplementation;
     216    /** 0x0e4: Implemenation use bytes. */
     217    union
     218    {
     219        /** Generic view. */
     220        uint8_t     ab[128];
     221    } ImplementationUse;
     222    /** 0x164: Reserved. */
     223    uint8_t         abReserved[156];
     224#endif
     225
     226} RTFSISOVOLUDFPART;
     227
    176228
    177229/**
     
    209261    /** @} */
    210262
    211     /** @name UDF specific data.
    212      * @{ */
    213     /** Offset of the Anchor volume descriptor sequence. */
    214     uint64_t            offAvdp;
    215     /** Length of the anchor volume descriptor sequence. */
    216     uint32_t            cbAvdp;
    217     /** @} */
     263    /** UDF specific data. */
     264    struct
     265    {
     266        /** Offset of the Anchor volume descriptor sequence. */
     267        uint64_t        offAvdp;
     268        /** Length of the anchor volume descriptor sequence. */
     269        uint32_t        cbAvdp;
     270        /** The UDF level. */
     271        uint8_t         uLevel;
     272        /** Number of volume sets. */
     273        uint8_t         cVolumeSets;
     274        /** Set if we already seen the primary volume descriptor. */
     275        bool            fSeenPrimaryDesc : 1;
     276#if 0
     277        /** Volume sets. */
     278        struct
     279        {
     280            /** Number of partitions in the set. */
     281            uint16_t        cPartitions;
     282
     283
     284        } aVolumeSets[1];
     285
     286
     287        /** Partitions. */
     288        struct
     289        {
     290
     291        } aPartitions[]
     292#endif
     293    } udf;
    218294
    219295    /** The root directory shared data. */
     
    226302*   Global Variables                                                                                                             *
    227303*********************************************************************************************************************************/
    228 
    229304
    230305/*********************************************************************************************************************************
     
    234309static void rtFsIsoDirShrd_RemoveOpenChild(PRTFSISODIRSHRD pDir, PRTFSISOCORE pChild);
    235310static int  rtFsIsoDir_New9660(PRTFSISOVOL pThis, PRTFSISODIRSHRD pParentDir, PCISO9660DIRREC pDirRec,
    236                            uint32_t cDirRecs, uint64_t offDirRec, PRTVFSDIR phVfsDir);
     311                               uint32_t cDirRecs, uint64_t offDirRec, PRTVFSDIR phVfsDir);
    237312static PRTFSISOCORE rtFsIsoDir_LookupShared(PRTFSISODIRSHRD pThis, uint64_t offDirRec);
    238313
     
    20892164
    20902165
     2166/**
     2167 * Checks the descriptor tag and CRC.
     2168 *
     2169 * @retval  IPRT status code.
     2170 * @retval  VERR_ISOFS_TAG_IS_ALL_ZEROS
     2171 * @retval  VERR_MISMATCH
     2172 * @retval  VERR_ISOFS_UNSUPPORTED_TAG_VERSION
     2173 * @retval  VERR_ISOFS_TAG_SECTOR_MISMATCH
     2174 * @retval  VERR_ISOFS_BAD_TAG_CHECKSUM
     2175 *
     2176 * @param   pTag        The tag to check.
     2177 * @param   idTag       The expected descriptor tag ID, UINT16_MAX matches any
     2178 *                      tag ID.
     2179 * @param   offTag      The sector offset of the tag.
     2180 * @param   pErrInfo    Where to return extended error info.
     2181 */
    20912182static int rtFsIsoVolValidateUdfDescTag(PCUDFTAG pTag, uint16_t idTag, uint32_t offTag, PRTERRINFO pErrInfo)
    20922183{
     
    21222213            {
    21232214                if (pTag->offTag == offTag)
     2215                {
     2216                    Log2(("ISO/UDF: Valid descriptor %#06x at %#010RX32; cbDescriptorCrc=%#06RX32 uTagSerialNo=%#x\n",
     2217                          pTag->idTag, offTag, pTag->cbDescriptorCrc, pTag->uTagSerialNo));
    21242218                    return VINF_SUCCESS;
     2219                }
    21252220
    21262221                Log(("rtFsIsoVolValidateUdfDescTag(,%#x,%#010RX32,): Sector mismatch: %#RX32 (%.*Rhxs)\n",
    21272222                     idTag, offTag, pTag->offTag, sizeof(*pTag), pTag));
    2128                 return RTErrInfoSetF(pErrInfo, VERR_MISMATCH, "Descriptor tag sector number mismatch: %#x, expected %#x (%.*Rhxs)",
     2223                return RTErrInfoSetF(pErrInfo, VERR_ISOFS_TAG_SECTOR_MISMATCH,
     2224                                     "Descriptor tag sector number mismatch: %#x, expected %#x (%.*Rhxs)",
    21292225                                     pTag->offTag, offTag, sizeof(*pTag), pTag);
    21302226            }
     
    21342230                                 pTag->idTag, idTag, sizeof(*pTag), pTag);
    21352231        }
     2232        if (ASMMemIsZero(pTag, sizeof(*pTag)))
     2233        {
     2234            Log(("rtFsIsoVolValidateUdfDescTag(,%#x,%#010RX32,): All zeros\n", idTag, offTag));
     2235            return RTErrInfoSet(pErrInfo, VERR_ISOFS_TAG_IS_ALL_ZEROS, "Descriptor is all zeros");
     2236        }
     2237
    21362238        Log(("rtFsIsoVolValidateUdfDescTag(,%#x,%#010RX32,): Unsupported version: %#x (%.*Rhxs)\n",
    21372239             idTag, offTag, pTag->uVersion, sizeof(*pTag), pTag));
    2138         return RTErrInfoSetF(pErrInfo, VERR_MISMATCH, "Unsupported descriptor tag version: %#x, expected 2 or 3 (%.*Rhxs)",
     2240        return RTErrInfoSetF(pErrInfo, VERR_ISOFS_UNSUPPORTED_TAG_VERSION, "Unsupported descriptor tag version: %#x, expected 2 or 3 (%.*Rhxs)",
    21392241                             pTag->uVersion, sizeof(*pTag), pTag);
    21402242    }
    21412243    Log(("rtFsIsoVolValidateUdfDescTag(,%#x,%#010RX32,): checksum error: %#x, calc %#x (%.*Rhxs)\n",
    21422244         idTag, offTag, pTag->uChecksum, bChecksum, sizeof(*pTag), pTag));
    2143     return RTErrInfoSetF(pErrInfo, VERR_MISMATCH,
     2245    return RTErrInfoSetF(pErrInfo, VERR_ISOFS_BAD_TAG_CHECKSUM,
    21442246                         "Descriptor tag checksum error: %#x, calculated %#x (%.*Rhxs)",
    21452247                         pTag->uChecksum, bChecksum, sizeof(*pTag), pTag);
    21462248}
     2249
     2250
     2251/**
     2252 * Checks the descriptor CRC.
     2253 *
     2254 * @retval  VINF_SUCCESS
     2255 * @retval  VERR_ISOFS_INSUFFICIENT_DATA_FOR_DESC_CRC
     2256 * @retval  VERR_ISOFS_DESC_CRC_MISMATCH
     2257 *
     2258 * @param   pTag        The descriptor buffer to checksum.
     2259 * @param   cbDesc      The size of the descriptor buffer.
     2260 * @param   pErrInfo    Where to return extended error info.
     2261 */
     2262static int rtFsIsoVolValidateUdfDescCrc(PCUDFTAG pTag, size_t cbDesc, PRTERRINFO pErrInfo)
     2263{
     2264    if (pTag->cbDescriptorCrc + sizeof(*pTag) <= cbDesc)
     2265    {
     2266        uint16_t uCrc = RTCrc16Ccitt(pTag + 1, pTag->cbDescriptorCrc);
     2267        if (pTag->uDescriptorCrc == uCrc)
     2268            return VINF_SUCCESS;
     2269
     2270        Log(("rtFsIsoVolValidateUdfDescCrc(,%#x,%#010RX32,): Descriptor CRC mismatch: expected %#x, calculated %#x (cbDescriptorCrc=%#x)\n",
     2271             pTag->idTag, pTag->offTag, pTag->uDescriptorCrc, uCrc, pTag->cbDescriptorCrc));
     2272        return RTErrInfoSetF(pErrInfo, VERR_ISOFS_DESC_CRC_MISMATCH,
     2273                             "Descriptor CRC mismatch: exepcted %#x, calculated %#x (cbDescriptor=%#x, idTag=%#x, offTag=%#010RX32)",
     2274                             pTag->uDescriptorCrc, uCrc, pTag->cbDescriptorCrc, pTag->idTag, pTag->offTag);
     2275    }
     2276
     2277    Log(("rtFsIsoVolValidateUdfDescCrc(,%#x,%#010RX32,): Insufficient data to CRC: cbDescriptorCrc=%#x cbDesc=%#zx\n",
     2278         pTag->idTag, pTag->offTag, pTag->cbDescriptorCrc, cbDesc));
     2279    return RTErrInfoSetF(pErrInfo, VERR_ISOFS_INSUFFICIENT_DATA_FOR_DESC_CRC,
     2280                         "Insufficient data to CRC: cbDescriptorCrc=%#x cbDesc=%#zx (idTag=%#x, offTag=%#010RX32)",
     2281                         pTag->cbDescriptorCrc, cbDesc, pTag->idTag, pTag->offTag);
     2282}
     2283
     2284
     2285/**
     2286 * Checks the descriptor tag and CRC.
     2287 *
     2288 * @retval  VINF_SUCCESS
     2289 * @retval  VERR_ISOFS_INSUFFICIENT_DATA_FOR_DESC_CRC
     2290 * @retval  VERR_ISOFS_TAG_IS_ALL_ZEROS
     2291 * @retval  VERR_MISMATCH
     2292 * @retval  VERR_ISOFS_UNSUPPORTED_TAG_VERSION
     2293 * @retval  VERR_ISOFS_TAG_SECTOR_MISMATCH
     2294 * @retval  VERR_ISOFS_BAD_TAG_CHECKSUM
     2295 * @retval  VERR_ISOFS_DESC_CRC_MISMATCH
     2296 *
     2297 * @param   pTag        The descriptor buffer to check the tag of and to
     2298 *                      checksum.
     2299 * @param   cbDesc      The size of the descriptor buffer.
     2300 * @param   idTag       The expected descriptor tag ID, UINT16_MAX
     2301 *                      matches any tag ID.
     2302 * @param   offTag      The sector offset of the tag.
     2303 * @param   pErrInfo    Where to return extended error info.
     2304 */
     2305static int rtFsIsoVolValidateUdfDescTagAndCrc(PCUDFTAG pTag, size_t cbDesc, uint16_t idTag, uint32_t offTag, PRTERRINFO pErrInfo)
     2306{
     2307    int rc = rtFsIsoVolValidateUdfDescTag(pTag, idTag, offTag, pErrInfo);
     2308    if (RT_SUCCESS(rc))
     2309        rc = rtFsIsoVolValidateUdfDescCrc(pTag, cbDesc, pErrInfo);
     2310    return rc;
     2311}
     2312
     2313
     2314#define UDF_LOG2_MEMBER(a_pStruct, a_szFmt, a_Member) \
     2315    Log2(("ISO/UDF:   %-32s %" a_szFmt "\n", #a_Member ":", (a_pStruct)->a_Member))
     2316#define UDF_LOG2_MEMBER_EX(a_pStruct, a_szFmt, a_Member, a_cchIndent) \
     2317    Log2(("ISO/UDF:   %*s%-32s %" a_szFmt "\n", a_cchIndent, "", #a_Member ":", (a_pStruct)->a_Member))
     2318#define UDF_LOG2_MEMBER_ENTITY_ID_EX(a_pStruct, a_Member, a_cchIndent) \
     2319    Log2(("ISO/UDF:   %*s%-32s '%.23s' fFlags=%#06x Suffix=%.8Rhxs\n", a_cchIndent, "", #a_Member ":", \
     2320          (a_pStruct)->a_Member.achIdentifier, (a_pStruct)->a_Member.fFlags, &(a_pStruct)->a_Member.Suffix))
     2321#define UDF_LOG2_MEMBER_ENTITY_ID(a_pStruct, a_Member) UDF_LOG2_MEMBER_ENTITY_ID_EX(a_pStruct, a_Member, 0)
     2322#define UDF_LOG2_MEMBER_EXTENTAD(a_pStruct, a_Member) \
     2323    Log2(("ISO/UDF:   %-32s sector %#010RX32 LB %#010RX32\n", #a_Member ":", (a_pStruct)->a_Member.off, (a_pStruct)->a_Member.cb))
     2324#define UDF_LOG2_MEMBER_SHORTAD(a_pStruct, a_Member) \
     2325    Log2(("ISO/UDF:   %-32s sector %#010RX32 LB %#010RX32 %s\n", #a_Member ":", (a_pStruct)->a_Member.off, (a_pStruct)->a_Member.cb, \
     2326          (a_pStruct)->a_Member.uType == UDF_AD_TYPE_RECORDED_AND_ALLOCATED ? "alloced+recorded" \
     2327          : (a_pStruct)->a_Member.uType == UDF_AD_TYPE_ONLY_ALLOCATED ? "alloced" \
     2328          : (a_pStruct)->a_Member.uType == UDF_AD_TYPE_FREE ? "free" : "next" ))
     2329#define UDF_LOG2_MEMBER_LONGAD(a_pStruct, a_Member) \
     2330    Log2(("ISO/UDF:   %-32s partition %#RX16, sector %#010RX32 LB %#010RX32 %s idUnique=%#010RX32 fFlags=%#RX16\n", #a_Member ":", \
     2331          (a_pStruct)->a_Member.Location.uPartitionNo, (a_pStruct)->a_Member.Location.off, (a_pStruct)->a_Member.cb, \
     2332          (a_pStruct)->a_Member.uType == UDF_AD_TYPE_RECORDED_AND_ALLOCATED ? "alloced+recorded" \
     2333          : (a_pStruct)->a_Member.uType == UDF_AD_TYPE_ONLY_ALLOCATED ? "alloced" \
     2334          : (a_pStruct)->a_Member.uType == UDF_AD_TYPE_FREE ? "free" : "next", \
     2335          (a_pStruct)->a_Member.ImplementationUse.Fid.idUnique, (a_pStruct)->a_Member.ImplementationUse.Fid.fFlags ))
     2336
     2337#define UDF_LOG2_MEMBER_TIMESTAMP(a_pStruct, a_Member) \
     2338    Log2(("ISO/UDF:   %-32s %04d-%02u-%02u %02u:%02u:%02u.%02u%02u%02u uTypeAndZone=%#x\n", #a_Member ":", \
     2339          (a_pStruct)->a_Member.iYear, (a_pStruct)->a_Member.uMonth, (a_pStruct)->a_Member.uDay, \
     2340          (a_pStruct)->a_Member.uHour, (a_pStruct)->a_Member.uMinute, (a_pStruct)->a_Member.uSecond, \
     2341          (a_pStruct)->a_Member.cCentiseconds, (a_pStruct)->a_Member.cHundredsOfMicroseconds, \
     2342          (a_pStruct)->a_Member.cMicroseconds, (a_pStruct)->a_Member.uTypeAndZone))
     2343#define UDF_LOG2_MEMBER_CHARSPEC(a_pStruct, a_Member) \
     2344    do { \
     2345        if (   (a_pStruct)->a_Member.uType == UDF_CHAR_SET_OSTA_COMPRESSED_UNICODE \
     2346            && memcmp(&(a_pStruct)->a_Member.abInfo[0], UDF_CHAR_SET_OSTA_COMPRESSED_UNICODE_INFO, \
     2347                      sizeof(UDF_CHAR_SET_OSTA_COMPRESSED_UNICODE_INFO)) == 0) \
     2348            Log2(("ISO/UDF:   %-32s OSTA COMPRESSED UNICODE INFO\n", #a_Member ":")); \
     2349        else if (ASMMemIsZero(&(a_pStruct)->a_Member, sizeof((a_pStruct)->a_Member))) \
     2350            Log2(("ISO/UDF:   %-32s all zeros\n", #a_Member ":")); \
     2351        else \
     2352            Log2(("ISO/UDF:   %-32s %#x info: %.63Rhxs\n", #a_Member ":", \
     2353                  (a_pStruct)->a_Member.uType, (a_pStruct)->a_Member.abInfo)); \
     2354    } while (0)
     2355#define UDF_LOG2_MEMBER_DSTRING(a_pStruct, a_Member) \
     2356    do { \
     2357        if ((a_pStruct)->a_Member[0] == 8) \
     2358            Log2(("ISO/UDF:   %-32s  8: '%s' len=%u (actual=%u)\n", #a_Member ":", &(a_pStruct)->a_Member[1], \
     2359                  (a_pStruct)->a_Member[sizeof((a_pStruct)->a_Member) - 1], strlen(&(a_pStruct)->a_Member[1]) + 1 )); \
     2360        else if ((a_pStruct)->a_Member[0] == 16) \
     2361        { \
     2362            PCRTUTF16 pwszTmp = (PCRTUTF16)&(a_pStruct)->a_Member[1]; \
     2363            char *pszTmp = NULL; \
     2364            RTUtf16BigToUtf8Ex(pwszTmp, (sizeof((a_pStruct)->a_Member) - 2) / sizeof(RTUTF16), &pszTmp, 0, NULL); \
     2365            Log2(("ISO/UDF:   %-32s 16: '%s' len=%u (actual=%u)\n", #a_Member ":", pszTmp, \
     2366                  (a_pStruct)->a_Member[sizeof((a_pStruct)->a_Member) - 1], RTUtf16Len(pwszTmp) * sizeof(RTUTF16) + 1 /*??*/ )); \
     2367        } \
     2368        else if (ASMMemIsZero(&(a_pStruct)->a_Member[0], sizeof((a_pStruct)->a_Member))) \
     2369            Log2(("ISO/UDF:   %-32s empty\n", #a_Member ":")); \
     2370        else \
     2371            Log2(("ISO/UDF:   %-32s bad: %.*Rhxs\n", #a_Member ":", sizeof((a_pStruct)->a_Member), &(a_pStruct)->a_Member[0] )); \
     2372    } while (0)
     2373
     2374
     2375
     2376/**
     2377 * Processes a primary volume descriptor in the VDS (UDF).
     2378 *
     2379 * @returns IPRT status code.
     2380 * @param   pThis       The instance.
     2381 * @param   pDesc       The descriptor.
     2382 * @param   pErrInfo    Where to return extended error information.
     2383 */
     2384//cmd: kmk VBoxRT && kmk_redirect -E VBOX_LOG_DEST="nofile stderr" -E VBOX_LOG="rt_fs=~0" -E VBOX_LOG_FLAGS="unbuffered enabled" -- e:\vbox\svn\trunk\out\win.amd64\debug\bin\tools\RTLs.exe :iprtvfs:file(open,d:\Downloads\en_windows_10_enterprise_version_1703_updated_march_2017_x64_dvd_10189290.iso,r):vfs(isofs):/ -la
     2385static int rtFsIsoVolProcessUdfPrimaryVolDesc(PRTFSISOVOL pThis, PCUDFPRIMARYVOLUMEDESC pDesc, PRTERRINFO pErrInfo)
     2386{
     2387#ifdef LOG_ENABLED
     2388    Log(("ISO/UDF: Primary volume descriptor at sector %#RX32\n", pDesc->Tag.offTag));
     2389    if (LogIs2Enabled())
     2390    {
     2391        UDF_LOG2_MEMBER(pDesc, "#010RX32", uVolumeDescSeqNo);
     2392        UDF_LOG2_MEMBER(pDesc, "#010RX32", uPrimaryVolumeDescNo);
     2393        UDF_LOG2_MEMBER_DSTRING(pDesc, achVolumeID);
     2394        UDF_LOG2_MEMBER(pDesc, "#06RX16", uVolumeSeqNo);
     2395        UDF_LOG2_MEMBER(pDesc, "#06RX16", uVolumeSeqNo);
     2396        UDF_LOG2_MEMBER(pDesc, "#06RX16", uMaxVolumeSeqNo);
     2397        UDF_LOG2_MEMBER(pDesc, "#06RX16", uInterchangeLevel);
     2398        UDF_LOG2_MEMBER(pDesc, "#06RX16", uMaxInterchangeLevel);
     2399        UDF_LOG2_MEMBER(pDesc, "#010RX32", fCharacterSets);
     2400        UDF_LOG2_MEMBER(pDesc, "#010RX32", fMaxCharacterSets);
     2401        UDF_LOG2_MEMBER_DSTRING(pDesc, achVolumeSetID);
     2402        UDF_LOG2_MEMBER_CHARSPEC(pDesc, DescCharSet);
     2403        UDF_LOG2_MEMBER_CHARSPEC(pDesc, ExplanatoryCharSet);
     2404        UDF_LOG2_MEMBER_EXTENTAD(pDesc, VolumeAbstract);
     2405        UDF_LOG2_MEMBER_EXTENTAD(pDesc, VolumeCopyrightNotice);
     2406        UDF_LOG2_MEMBER_ENTITY_ID(pDesc, idApplication);
     2407        UDF_LOG2_MEMBER_TIMESTAMP(pDesc, RecordingTimestamp);
     2408        UDF_LOG2_MEMBER_ENTITY_ID(pDesc, idImplementation);
     2409        if (!ASMMemIsZero(&pDesc->abImplementationUse, sizeof(pDesc->abImplementationUse)))
     2410            Log2(("ISO/UDF:   %-32s %.64Rhxs\n", "abReserved[64]:", &pDesc->abImplementationUse[0]));
     2411        UDF_LOG2_MEMBER(pDesc, "#010RX32", offPredecessorVolDescSeq);
     2412        UDF_LOG2_MEMBER(pDesc, "#06RX16", fFlags);
     2413        if (!ASMMemIsZero(&pDesc->abReserved, sizeof(pDesc->abReserved)))
     2414            Log2(("ISO/UDF:   %-32s %.22Rhxs\n", "abReserved[22]:", &pDesc->abReserved[0]));
     2415    }
     2416#endif
     2417
     2418    RT_NOREF(pThis, pDesc, pErrInfo);
     2419    return VINF_SUCCESS;
     2420}
     2421
     2422
     2423/**
     2424 * Processes an logical volume descriptor in the VDS (UDF).
     2425 *
     2426 * @returns IPRT status code.
     2427 * @param   pThis       The instance.
     2428 * @param   pDesc       The descriptor.
     2429 * @param   pErrInfo    Where to return extended error information.
     2430 */
     2431static int rtFsIsoVolProcessUdfLogicalVolumeDesc(PRTFSISOVOL pThis, PCUDFLOGICALVOLUMEDESC pDesc, PRTERRINFO pErrInfo)
     2432{
     2433#ifdef LOG_ENABLED
     2434    Log(("ISO/UDF: Logical volume descriptor at sector %#RX32\n", pDesc->Tag.offTag));
     2435    if (LogIs2Enabled())
     2436    {
     2437        UDF_LOG2_MEMBER(pDesc, "#010RX32", uVolumeDescSeqNo);
     2438        UDF_LOG2_MEMBER_CHARSPEC(pDesc, DescriptorCharSet);
     2439        UDF_LOG2_MEMBER_DSTRING(pDesc, achLogicalVolumeID);
     2440        UDF_LOG2_MEMBER(pDesc, "#010RX32", cbLogicalBlock);
     2441        UDF_LOG2_MEMBER_ENTITY_ID(pDesc, idDomain);
     2442        if (memcmp(&pDesc->idDomain.achIdentifier[0], RT_STR_TUPLE(UDF_ENTITY_ID_LVD_DOMAIN) + 1) == 0)
     2443            UDF_LOG2_MEMBER_LONGAD(pDesc, ContentsUse.FileSetDescriptor);
     2444        else if (!ASMMemIsZero(&pDesc->ContentsUse.ab[0], sizeof(pDesc->ContentsUse.ab)))
     2445            Log2(("ISO/UDF:   %-32s %.16Rhxs\n", "ContentsUse.ab[16]:", &pDesc->ContentsUse.ab[0]));
     2446        UDF_LOG2_MEMBER(pDesc, "#010RX32", cbMapTable);
     2447        UDF_LOG2_MEMBER(pDesc, "#010RX32", cPartitionMaps);
     2448        UDF_LOG2_MEMBER_ENTITY_ID(pDesc, idImplementation);
     2449        if (!ASMMemIsZero(&pDesc->ImplementationUse.ab[0], sizeof(pDesc->ImplementationUse.ab)))
     2450            Log2(("ISO/UDF:   %-32s\n%.128Rhxd\n", "ImplementationUse.ab[128]:", &pDesc->ImplementationUse.ab[0]));
     2451        UDF_LOG2_MEMBER_EXTENTAD(pDesc, IntegritySeqExtent);
     2452        if (pDesc->cbMapTable)
     2453        {
     2454            Log2(("ISO/UDF:   %-32s\n", "abPartitionMaps"));
     2455            uint32_t iMap = 0;
     2456            uint32_t off  = 0;
     2457            while (off + sizeof(UDFPARTMAPHDR) <= pDesc->cbMapTable)
     2458            {
     2459                PCUDFPARTMAPHDR pHdr = (PCUDFPARTMAPHDR)&pDesc->abPartitionMaps[off];
     2460                Log2(("ISO/UDF:     %02u @ %#05x: type %u, length %u\n", iMap, off, pHdr->bType, pHdr->cb));
     2461                if (off + pHdr->cb > pDesc->cbMapTable)
     2462                {
     2463                    Log2(("ISO/UDF:                 BAD! Entry is %d bytes too long!\n", off + pHdr->cb - pDesc->cbMapTable));
     2464                    break;
     2465                }
     2466                if (pHdr->bType == 1)
     2467                {
     2468                    PCUDFPARTMAPTYPE1 pType1 = (PCUDFPARTMAPTYPE1)pHdr;
     2469                    UDF_LOG2_MEMBER_EX(pType1, "#06RX16", uVolumeSeqNo, 5);
     2470                    UDF_LOG2_MEMBER_EX(pType1, "#06RX16", uPartitionNo, 5);
     2471                }
     2472                else if (pHdr->bType == 2)
     2473                {
     2474                    PCUDFPARTMAPTYPE2 pType2 = (PCUDFPARTMAPTYPE2)pHdr;
     2475                    UDF_LOG2_MEMBER_ENTITY_ID_EX(pType2, idPartitionType, 5);
     2476                    UDF_LOG2_MEMBER_EX(pType2, "#06RX16", uVolumeSeqNo, 5);
     2477                    UDF_LOG2_MEMBER_EX(pType2, "#06RX16", uPartitionNo, 5);
     2478                }
     2479                else
     2480                    Log2(("ISO/UDF:                 BAD! Unknown type!\n"));
     2481
     2482                /* advance */
     2483                off += pHdr->cb;
     2484                iMap++;
     2485            }
     2486        }
     2487    }
     2488#endif
     2489
     2490    RT_NOREF(pThis, pDesc, pErrInfo);
     2491    return VINF_SUCCESS;
     2492}
     2493
     2494
     2495/**
     2496 * Processes an partition descriptor in the VDS (UDF).
     2497 *
     2498 * @returns IPRT status code.
     2499 * @param   pThis       The instance.
     2500 * @param   pDesc       The descriptor.
     2501 * @param   pErrInfo    Where to return extended error information.
     2502 */
     2503static int rtFsIsoVolProcessUdfPartitionDesc(PRTFSISOVOL pThis, PCUDFPARTITIONDESC pDesc, PRTERRINFO pErrInfo)
     2504{
     2505#ifdef LOG_ENABLED
     2506    Log(("ISO/UDF: Partition descriptor at sector %#RX32\n", pDesc->Tag.offTag));
     2507    if (LogIs2Enabled())
     2508    {
     2509        UDF_LOG2_MEMBER(pDesc, "#010RX32", uVolumeDescSeqNo);
     2510        UDF_LOG2_MEMBER(pDesc, "#06RX16", fFlags);
     2511        UDF_LOG2_MEMBER(pDesc, "#06RX16", uPartitionNo);
     2512        UDF_LOG2_MEMBER_ENTITY_ID(pDesc, PartitionContents);
     2513        if (memcmp(&pDesc->PartitionContents.achIdentifier[0], RT_STR_TUPLE(UDF_ENTITY_ID_PD_PARTITION_CONTENTS_UDF) + 1) == 0)
     2514        {
     2515            UDF_LOG2_MEMBER_SHORTAD(&pDesc->ContentsUse, Hdr.UnallocatedSpaceTable);
     2516            UDF_LOG2_MEMBER_SHORTAD(&pDesc->ContentsUse, Hdr.UnallocatedSpaceBitmap);
     2517            UDF_LOG2_MEMBER_SHORTAD(&pDesc->ContentsUse, Hdr.PartitionIntegrityTable);
     2518            UDF_LOG2_MEMBER_SHORTAD(&pDesc->ContentsUse, Hdr.FreedSpaceTable);
     2519            UDF_LOG2_MEMBER_SHORTAD(&pDesc->ContentsUse, Hdr.FreedSpaceBitmap);
     2520            if (!ASMMemIsZero(&pDesc->ContentsUse.Hdr.abReserved[0], sizeof(pDesc->ContentsUse.Hdr.abReserved)))
     2521                Log2(("ISO/UDF:   %-32s\n%.88Rhxd\n", "Hdr.abReserved[88]:", &pDesc->ContentsUse.Hdr.abReserved[0]));
     2522        }
     2523        else if (!ASMMemIsZero(&pDesc->ContentsUse.ab[0], sizeof(pDesc->ContentsUse.ab)))
     2524            Log2(("ISO/UDF:   %-32s\n%.128Rhxd\n", "ContentsUse.ab[128]:", &pDesc->ContentsUse.ab[0]));
     2525        UDF_LOG2_MEMBER(pDesc, "#010RX32", uAccessType);
     2526        UDF_LOG2_MEMBER(pDesc, "#010RX32", offLocation);
     2527        UDF_LOG2_MEMBER(pDesc, "#010RX32", cSectors);
     2528        UDF_LOG2_MEMBER_ENTITY_ID(pDesc, idImplementation);
     2529        if (!ASMMemIsZero(&pDesc->ImplementationUse.ab[0], sizeof(pDesc->ImplementationUse.ab)))
     2530            Log2(("ISO/UDF:   %-32s\n%.128Rhxd\n", "ImplementationUse.ab[128]:", &pDesc->ImplementationUse.ab[0]));
     2531
     2532        if (!ASMMemIsZero(&pDesc->abReserved[0], sizeof(pDesc->abReserved)))
     2533            Log2(("ISO/UDF:   %-32s\n%.156Rhxd\n", "ImplementationUse.ab[156]:", &pDesc->abReserved[0]));
     2534    }
     2535#endif
     2536
     2537    RT_NOREF(pThis, pDesc, pErrInfo);
     2538    return VINF_SUCCESS;
     2539}
     2540
     2541
     2542/**
     2543 * Processes an implementation use descriptor in the VDS (UDF).
     2544 *
     2545 * @returns IPRT status code.
     2546 * @param   pThis       The instance.
     2547 * @param   pDesc       The descriptor.
     2548 * @param   pErrInfo    Where to return extended error information.
     2549 */
     2550static int rtFsIsoVolProcessUdfImplUseVolDesc(PRTFSISOVOL pThis, PCUDFIMPLEMENTATIONUSEVOLUMEDESC pDesc, PRTERRINFO pErrInfo)
     2551{
     2552#ifdef LOG_ENABLED
     2553    Log(("ISO/UDF: Implementation use volume descriptor at sector %#RX32\n", pDesc->Tag.offTag));
     2554    if (LogIs2Enabled())
     2555    {
     2556        UDF_LOG2_MEMBER(pDesc, "#010RX32", uVolumeDescSeqNo);
     2557        UDF_LOG2_MEMBER_ENTITY_ID(pDesc, idImplementation);
     2558        if (memcmp(pDesc->idImplementation.achIdentifier, RT_STR_TUPLE(UDF_ENTITY_ID_IUVD_IMPLEMENTATION) + 1) == 0)
     2559        {
     2560            UDF_LOG2_MEMBER_CHARSPEC(&pDesc->ImplementationUse, Lvi.Charset);
     2561            UDF_LOG2_MEMBER_DSTRING(&pDesc->ImplementationUse, Lvi.achVolumeID);
     2562            UDF_LOG2_MEMBER_DSTRING(&pDesc->ImplementationUse, Lvi.achInfo1);
     2563            UDF_LOG2_MEMBER_DSTRING(&pDesc->ImplementationUse, Lvi.achInfo2);
     2564            UDF_LOG2_MEMBER_DSTRING(&pDesc->ImplementationUse, Lvi.achInfo3);
     2565            UDF_LOG2_MEMBER_ENTITY_ID(&pDesc->ImplementationUse, Lvi.idImplementation);
     2566            if (!ASMMemIsZero(&pDesc->ImplementationUse.Lvi.abUse[0], sizeof(pDesc->ImplementationUse.Lvi.abUse)))
     2567                Log2(("ISO/UDF:   %-32s\n%.128Rhxd\n", "Lvi.abUse[128]:", &pDesc->ImplementationUse.Lvi.abUse[0]));
     2568        }
     2569        else if (!ASMMemIsZero(&pDesc->ImplementationUse.ab[0], sizeof(pDesc->ImplementationUse.ab)))
     2570            Log2(("ISO/UDF:   %-32s\n%.460Rhxd\n", "ImplementationUse.ab[460]:", &pDesc->ImplementationUse.ab[0]));
     2571    }
     2572#endif
     2573
     2574    RT_NOREF(pThis, pDesc, pErrInfo);
     2575    return VINF_SUCCESS;
     2576}
     2577
     2578
    21472579
    21482580typedef struct RTFSISOSEENSEQENCES
     
    21632595 * Process a VDS sequence, recursively dealing with volume descriptor pointers.
    21642596 *
    2165  * @returns
    2166  * @param   pThis           .
    2167  * @param   offSeq          .
    2168  * @param   cbSeq           .
    2169  * @param   pbBuf           .
    2170  * @param   cbBuf           .
     2597 * @returns IPRT status code.
     2598 * @param   pThis           The instance.
     2599 * @param   offSeq          The byte offset of the sequence.
     2600 * @param   cbSeq           The length of the sequence.
     2601 * @param   pbBuf           Read buffer.
     2602 * @param   cbBuf           Size of the read buffer.  This is at least one
     2603 *                          sector big.
    21712604 * @param   cNestings       The VDS nesting depth.
    2172  * @param   pErrInfo        .
     2605 * @param   pErrInfo        Where to return extended error info.
    21732606 */
    21742607static int rtFsIsoVolReadAndProcessUdfVdsSeq(PRTFSISOVOL pThis, uint64_t offSeq, uint32_t cbSeq, uint8_t *pbBuf, size_t cbBuf,
     
    22072640         */
    22082641        PCUDFTAG pTag = (PCUDFTAG)pbBuf;
    2209         rc = rtFsIsoVolValidateUdfDescTag(pTag, UINT16_MAX, (offSeq + offInSeq) / pThis->cbSector, pErrInfo);
    2210         if (RT_FAILURE(rc))
     2642        rc = rtFsIsoVolValidateUdfDescTagAndCrc(pTag, pThis->cbSector, UINT16_MAX, (offSeq + offInSeq) / pThis->cbSector, pErrInfo);
     2643        if (   RT_SUCCESS(rc)
     2644            || (   rc == VERR_ISOFS_INSUFFICIENT_DATA_FOR_DESC_CRC
     2645                && (   pTag->idTag == UDF_TAG_ID_LOGICAL_VOLUME_INTEGRITY_DESC
     2646                    || pTag->idTag == UDF_TAG_ID_LOGICAL_VOLUME_DESC
     2647                    || pTag->idTag == UDF_TAG_ID_UNALLOCATED_SPACE_DESC
     2648                   )
     2649               )
     2650           )
     2651        {
     2652            switch (pTag->idTag)
     2653            {
     2654                case UDF_TAG_ID_PRIMARY_VOL_DESC:
     2655                    rc = rtFsIsoVolProcessUdfPrimaryVolDesc(pThis, (PCUDFPRIMARYVOLUMEDESC)pTag, pErrInfo);
     2656                    break;
     2657
     2658                case UDF_TAG_ID_IMPLEMENATION_USE_VOLUME_DESC:
     2659                    rc = rtFsIsoVolProcessUdfImplUseVolDesc(pThis, (PCUDFIMPLEMENTATIONUSEVOLUMEDESC)pTag, pErrInfo);
     2660                    break;
     2661
     2662                case UDF_TAG_ID_PARTITION_DESC:
     2663                    rc = rtFsIsoVolProcessUdfPartitionDesc(pThis, (PCUDFPARTITIONDESC)pTag, pErrInfo);
     2664                    break;
     2665
     2666                case UDF_TAG_ID_LOGICAL_VOLUME_DESC:
     2667                    rc = rtFsIsoVolProcessUdfLogicalVolumeDesc(pThis, (PCUDFLOGICALVOLUMEDESC)pTag, pErrInfo);
     2668                    break;
     2669
     2670                case UDF_TAG_ID_LOGICAL_VOLUME_INTEGRITY_DESC:
     2671                    Log(("ISO/UDF: Ignoring logical volume integrity descriptor at offset %#RX64.\n", offSeq + offInSeq));
     2672                    rc = VINF_SUCCESS;
     2673                    break;
     2674
     2675                case UDF_TAG_ID_UNALLOCATED_SPACE_DESC:
     2676                    Log(("ISO/UDF: Ignoring unallocated space descriptor at offset %#RX64.\n", offSeq + offInSeq));
     2677                    rc = VINF_SUCCESS;
     2678                    break;
     2679
     2680                case UDF_TAG_ID_ANCHOR_VOLUME_DESC_PTR:
     2681                    Log(("ISO/UDF: Ignoring AVDP in VDS (at offset %#RX64).\n", offSeq + offInSeq));
     2682                    rc = VINF_SUCCESS;
     2683                    break;
     2684
     2685                case UDF_TAG_ID_VOLUME_DESC_PTR:
     2686                {
     2687                    PCUDFVOLUMEDESCPTR pVdp = (PCUDFVOLUMEDESCPTR)pTag;
     2688                    Log(("ISO/UDF: Processing volume descriptor pointer at offset %#RX64: %#x LB %#x (seq %#x); cNestings=%d\n",
     2689                         offSeq + offInSeq, pVdp->NextVolumeDescSeq.off, pVdp->NextVolumeDescSeq.cb,
     2690                         pVdp->uVolumeDescSeqNo, cNestings));
     2691                    rc = rtFsIsoVolReadAndProcessUdfVdsSeq(pThis, (uint64_t)pVdp->NextVolumeDescSeq.off * pThis->cbSector,
     2692                                                           pVdp->NextVolumeDescSeq.cb, pbBuf, cbBuf, cNestings + 1, pErrInfo);
     2693                    break;
     2694                }
     2695
     2696                case UDF_TAG_ID_TERMINATING_DESC:
     2697                    Log(("ISO/UDF: Terminating descriptor at offset %#RX64\n", offSeq + offInSeq));
     2698                    return VINF_SUCCESS;
     2699
     2700                default:
     2701                    return RTErrInfoSetF(pErrInfo, VERR_ISOFS_UNEXPECTED_VDS_DESC, "Unexpected/unknown VDS descriptor %#x",
     2702                                         offSeq + offInSeq, pThis->cbSector, rc);
     2703            }
     2704        }
     2705        /* The descriptor sequence is usually zero padded to 16 sectors.  Just
     2706           ignore zero descriptors. */
     2707        else if (rc != VERR_ISOFS_TAG_IS_ALL_ZEROS)
    22112708            return rc;
    2212 
    2213         switch (pTag->idTag)
    2214         {
    2215             case UDF_TAG_ID_PRIMARY_VOL_DESC:                 /* UDFPRIMARYVOLUMEDESC */
    2216                 break;
    2217             case UDF_TAG_ID_ANCHOR_VOLUME_DESC_PTR:           /* UDFANCHORVOLUMEDESCPTR */
    2218                 break;
    2219             case UDF_TAG_ID_VOLUME_DESC_PTR:                  /* UDFVOLUMEDESCPTR */
    2220                 break;
    2221             case UDF_TAG_ID_IMPLEMENATION_USE_VOLUME_DESC:    /* UDFIMPLEMENTATIONUSEVOLUMEDESC */
    2222                 break;
    2223             case UDF_TAG_ID_PARTITION_DESC:                   /* UDFPARTITIONDESC */
    2224                 break;
    2225             case UDF_TAG_ID_LOGICAL_VOLUME_DESC:              /* UDFLOGICALVOLUMEDESC */
    2226                 break;
    2227             case UDF_TAG_ID_UNALLOCATED_SPACE_DESC:           /* UDFUNALLOCATEDSPACEDESC */
    2228                 break;
    2229             case UDF_TAG_ID_TERMINATING_DESC:                 /* UDFTERMINATINGDESC */
    2230                 break;
    2231             case UDF_TAG_ID_LOGICAL_VOLUME_INTEGRITY_DESC:    /* UDFLOGICALVOLINTEGRITYDESC */
    2232                 break;
    2233 
    2234         }
    22352709
    22362710        /*
     
    22792753    pSeenSequences->cSequences++;
    22802754
    2281     LogFlow(("ISO/UDF: Processing anchor volume descriptor sequence at %#RX64 LB %#RX32\n", offSeq, cbSeq));
     2755    LogFlow(("ISO/UDF: Processing anchor volume descriptor sequence at offset %#RX64 LB %#RX32\n", offSeq, cbSeq));
    22822756
    22832757    /*
     
    30413515            return rc;
    30423516    }
     3517#if 0
     3518    return VERR_NOT_IMPLEMENTED;
     3519#else
    30433520
    30443521    /*
     
    30583535    }
    30593536    return rtFsIsoDirShrd_New9660(pThis, NULL, &RootDir, 1, offRootDirRec, &pThis->pRootDir);
     3537#endif
    30603538}
    30613539
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette