VirtualBox

Changeset 69013 in vbox for trunk/src/VBox/Runtime/common/fs


Ignore:
Timestamp:
Oct 9, 2017 12:08:12 PM (7 years ago)
Author:
vboxsync
Message:

IPRT: UDF updates

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/fs/isovfs.cpp

    r68991 r69013  
    4949#include <iprt/formats/udf.h>
    5050
     51/** @todo move to err.h:   */
     52#define VERR_ISOFS_IPE_0                                (-25390)
    5153
    5254
     
    176178
    177179/** Pointer to info about a UDF volume. */
    178 typedef struct RTFSISOVOLUDFVOL *PRTFSISOVOLUDFVOL;
     180typedef struct RTFSISOUDFVOLINFO *PRTFSISOUDFVOLINFO;
     181
     182
     183/** @name RTFSISO_UDF_PMAP_T_XXX
     184 * @{ */
     185#define RTFSISO_UDF_PMAP_T_PLAIN        1
     186#define RTFSISO_UDF_PMAP_T_VPM_15       2
     187#define RTFSISO_UDF_PMAP_T_VPM_20       3
     188#define RTFSISO_UDF_PMAP_T_SPM          4
     189#define RTFSISO_UDF_PMAP_T_MPM          5
     190/** @} */
    179191
    180192/**
     
    184196 * and the UDFPARTMAPTYPE2 structure.
    185197 */
    186 typedef struct RTFSISOVOLUDFPART
    187 {
    188     /** Partition number (not index). */
    189     uint16_t            uPartitionNo;
    190     /** Parition flags (UDF_PARTITION_FLAGS_XXX). */
    191     uint16_t            fFlags;
    192     /** Number of sectors. */
    193     uint32_t            cSectors;
     198typedef struct RTFSISOVOLUDFPMAP
     199{
    194200    /** Partition starting location as a byte offset. */
    195201    uint64_t            offByteLocation;
    196202    /** Partition starting location (logical sector number). */
    197203    uint32_t            offLocation;
     204    /** Number of sectors. */
     205    uint32_t            cSectors;
     206
     207    /** Partition descriptor index (for processing). */
     208    uint16_t            idxPartDesc;
     209    /** Offset info the map table. */
     210    uint16_t            offMapTable;
     211    /** Partition number (not index). */
     212    uint16_t            uPartitionNo;
     213    /** Partition number (not index). */
     214    uint16_t            uVolumeSeqNo;
     215
     216    /** The access type (UDF_PART_ACCESS_TYPE_XXX). */
     217    uint32_t            uAccessType;
     218    /** Partition flags (UDF_PARTITION_FLAGS_XXX). */
     219    uint16_t            fFlags;
     220    /** RTFSISO_UDF_PMAP_T_XXX. */
     221    uint8_t             bType;
    198222    /** Set if Hdr is valid. */
    199223    bool                fHaveHdr;
     
    201225    UDFPARTITIONHDRDESC Hdr;
    202226
    203     /** Pointer to the volume this partition belongs to. */
    204     PRTFSISOVOLUDFVOL   pVol;
    205 } RTFSISOVOLUDFPART;
    206 typedef RTFSISOVOLUDFPART *PRTFSISOVOLUDFPART;
     227} RTFSISOVOLUDFPMAP;
     228typedef RTFSISOVOLUDFPMAP *PRTFSISOVOLUDFPMAP;
    207229
    208230/**
     
    214236 *       implementation.  So, this can be considered a volume and a volume set.
    215237 */
    216 typedef struct RTFSISOVOLUDFVOL
     238typedef struct RTFSISOUDFVOLINFO
    217239{
    218240    /** The extent containing the file set descriptor. */
    219241    UDFLONGAD           FileSetDescriptor;
    220242
     243    /** The root directory location (from the file set descriptor). */
     244    UDFLONGAD           RootDirIcb;
     245    /** Location of the system stream directory associated with the file set. */
     246    UDFLONGAD           SystemStreamDirIcb;
     247
    221248    /** The logical block size on this volume. */
    222249    uint32_t            cbBlock;
    223     /** Primary volume descriptor number. */
    224     uint32_t            uPrimaryVolumeDescNo;
    225     /** Volume sequence number. */
    226     uint16_t            uVolumeSeqNo;
    227     /** Maximum volume sequence number. */
    228     uint16_t            uMaxVolumeSeqNo;
     250    /** The log2 of cbBlock. */
     251    uint32_t            cShiftBlock;
    229252    /** Flags (UDF_PVD_FLAGS_XXX). */
    230253    uint16_t            fFlags;
    231254
    232     /** Number of partitions in this volume. */
     255    /** Number of partitions mapp in this volume. */
    233256    uint16_t            cPartitions;
    234257    /** Partitions in this volume. */
    235     PRTFSISOVOLUDFPART  paPartitions;
    236 
    237     /** Volume identifier (dstring). */
    238     UDFDSTRING          achVolumeID[32];
     258    PRTFSISOVOLUDFPMAP  paPartitions;
     259
    239260    /** The volume ID string. */
    240261    UDFDSTRING          achLogicalVolumeID[128];
    241 } RTFSISOVOLUDFVOL;
    242 
     262} RTFSISOUDFVOLINFO;
     263
     264
     265/**
     266 * Indicates which of the possible content types we're accessing.
     267 */
     268typedef enum RTFSISOVOLTYPE
     269{
     270    /** Accessing the primary ISO-9660 volume. */
     271    RTFSISOVOLTYPE_ISO9960 = 0,
     272    /** Accessing the joliet volume (secondary ISO-9660). */
     273    RTFSISOVOLTYPE_JOLIET,
     274    /** Accessing the UDF volume. */
     275    RTFSISOVOLTYPE_UDF
     276} RTFSISOVOLTYPE;
    243277
    244278/**
     
    259293    /** The sector size (in bytes). */
    260294    uint32_t            cbSector;
     295    /** What we're accessing. */
     296    RTFSISOVOLTYPE      enmType;
    261297
    262298    /** @name ISO 9660 specific data
     
    279315    struct
    280316    {
    281         /** Offset of the Anchor volume descriptor sequence. */
    282         uint64_t        offAvdp;
    283         /** Length of the anchor volume descriptor sequence. */
    284         uint32_t        cbAvdp;
     317        /** Volume information. */
     318        RTFSISOUDFVOLINFO   VolInfo;
    285319        /** The UDF level. */
    286         uint8_t         uLevel;
    287         /** Number of volume sets. */
    288         uint8_t         cVolumeSets;
    289         /** Number of entries in the array paPartitions points to. */
    290         uint8_t         cPartitions;
    291         /** Set if we already seen the primary volume descriptor. */
    292         bool            fSeenPrimaryDesc : 1;
    293         /** Partitions. */
    294         PRTFSISOVOLUDFPART paPartitions;
    295 
    296 #if 0
    297         /** Volume sets. */
    298         struct
    299         {
    300             /** Number of partitions in the set. */
    301             uint16_t        cPartitions;
    302 
    303 
    304         } aVolumeSets[1];
    305 
    306 #endif
    307     } udf;
     320        uint8_t             uLevel;
     321    } Udf;
    308322
    309323    /** The root directory shared data. */
     
    311325} RTFSISOVOL;
    312326
     327
     328/**
     329 * Info gathered from a VDS sequence.
     330 */
     331typedef struct RTFSISOVDSINFO
     332{
     333    /** Number of entries in apPrimaryVols. */
     334    uint32_t                cPrimaryVols;
     335    /** Number of entries in apLogicalVols. */
     336    uint32_t                cLogicalVols;
     337    /** Number of entries in apPartitions. */
     338    uint32_t                cPartitions;
     339    /** Pointer to primary volume descriptors (native endian). */
     340    PUDFPRIMARYVOLUMEDESC   apPrimaryVols[8];
     341    /** Pointer to logical volume descriptors (native endian). */
     342    PUDFLOGICALVOLUMEDESC   apLogicalVols[8];
     343    /** Pointer to partition descriptors (native endian). */
     344    PUDFPARTITIONDESC       apPartitions[16];
     345
     346    /** Created after scanning the sequence (here for cleanup purposes). */
     347    PRTFSISOVOLUDFPMAP      paPartMaps;
     348} RTFSISOVDSINFO;
     349/** Pointer to VDS sequence info. */
     350typedef RTFSISOVDSINFO *PRTFSISOVDSINFO;
     351
     352
     353
     354/*********************************************************************************************************************************
     355*   Defined Constants And Macros                                                                                                 *
     356*********************************************************************************************************************************/
     357/** Check if an entity ID field equals the given ID string. */
     358#define UDF_ENTITY_ID_EQUALS(a_pEntityId, a_szId)  \
     359    ( memcmp(&(a_pEntityId)->achIdentifier[0], a_szId, RT_MIN(sizeof(a_szId), sizeof(a_pEntityId)->achIdentifier)) == 0 )
     360/** Checks if a character set indicator indicates OSTA compressed unicode. */
     361#define UDF_IS_CHAR_SET_OSTA(a_pCharSet) \
     362    (   (a_pCharSet)->uType == UDF_CHAR_SET_OSTA_COMPRESSED_UNICODE \
     363     && memcmp((a_pCharSet)->abInfo, UDF_CHAR_SET_OSTA_COMPRESSED_UNICODE_INFO, \
     364               sizeof(UDF_CHAR_SET_OSTA_COMPRESSED_UNICODE_INFO)) == 0 )
     365
     366
     367/** @name UDF structure logging macros
     368 * @{ */
     369#define UDF_LOG2_MEMBER(a_pStruct, a_szFmt, a_Member) \
     370    Log2(("ISO/UDF:   %-32s %" a_szFmt "\n", #a_Member ":", (a_pStruct)->a_Member))
     371#define UDF_LOG2_MEMBER_EX(a_pStruct, a_szFmt, a_Member, a_cchIndent) \
     372    Log2(("ISO/UDF:   %*s%-32s %" a_szFmt "\n", a_cchIndent, "", #a_Member ":", (a_pStruct)->a_Member))
     373#define UDF_LOG2_MEMBER_ENTITY_ID_EX(a_pStruct, a_Member, a_cchIndent) \
     374    Log2(("ISO/UDF:   %*s%-32s '%.23s' fFlags=%#06x Suffix=%.8Rhxs\n", a_cchIndent, "", #a_Member ":", \
     375          (a_pStruct)->a_Member.achIdentifier, (a_pStruct)->a_Member.fFlags, &(a_pStruct)->a_Member.Suffix))
     376#define UDF_LOG2_MEMBER_ENTITY_ID(a_pStruct, a_Member) UDF_LOG2_MEMBER_ENTITY_ID_EX(a_pStruct, a_Member, 0)
     377#define UDF_LOG2_MEMBER_EXTENTAD(a_pStruct, a_Member) \
     378    Log2(("ISO/UDF:   %-32s sector %#010RX32 LB %#010RX32\n", #a_Member ":", (a_pStruct)->a_Member.off, (a_pStruct)->a_Member.cb))
     379#define UDF_LOG2_MEMBER_SHORTAD(a_pStruct, a_Member) \
     380    Log2(("ISO/UDF:   %-32s sector %#010RX32 LB %#010RX32 %s\n", #a_Member ":", (a_pStruct)->a_Member.off, (a_pStruct)->a_Member.cb, \
     381          (a_pStruct)->a_Member.uType == UDF_AD_TYPE_RECORDED_AND_ALLOCATED ? "alloced+recorded" \
     382          : (a_pStruct)->a_Member.uType == UDF_AD_TYPE_ONLY_ALLOCATED ? "alloced" \
     383          : (a_pStruct)->a_Member.uType == UDF_AD_TYPE_FREE ? "free" : "next" ))
     384#define UDF_LOG2_MEMBER_LONGAD(a_pStruct, a_Member) \
     385    Log2(("ISO/UDF:   %-32s partition %#RX16, block %#010RX32 LB %#010RX32 %s idUnique=%#010RX32 fFlags=%#RX16\n", #a_Member ":", \
     386          (a_pStruct)->a_Member.Location.uPartitionNo, (a_pStruct)->a_Member.Location.off, (a_pStruct)->a_Member.cb, \
     387          (a_pStruct)->a_Member.uType == UDF_AD_TYPE_RECORDED_AND_ALLOCATED ? "alloced+recorded" \
     388          : (a_pStruct)->a_Member.uType == UDF_AD_TYPE_ONLY_ALLOCATED ? "alloced" \
     389          : (a_pStruct)->a_Member.uType == UDF_AD_TYPE_FREE ? "free" : "next", \
     390          (a_pStruct)->a_Member.ImplementationUse.Fid.idUnique, (a_pStruct)->a_Member.ImplementationUse.Fid.fFlags ))
     391
     392#define UDF_LOG2_MEMBER_TIMESTAMP(a_pStruct, a_Member) \
     393    Log2(("ISO/UDF:   %-32s %04d-%02u-%02u %02u:%02u:%02u.%02u%02u%02u uTypeAndZone=%#x\n", #a_Member ":", \
     394          (a_pStruct)->a_Member.iYear, (a_pStruct)->a_Member.uMonth, (a_pStruct)->a_Member.uDay, \
     395          (a_pStruct)->a_Member.uHour, (a_pStruct)->a_Member.uMinute, (a_pStruct)->a_Member.uSecond, \
     396          (a_pStruct)->a_Member.cCentiseconds, (a_pStruct)->a_Member.cHundredsOfMicroseconds, \
     397          (a_pStruct)->a_Member.cMicroseconds, (a_pStruct)->a_Member.uTypeAndZone))
     398#define UDF_LOG2_MEMBER_CHARSPEC(a_pStruct, a_Member) \
     399    do { \
     400        if (   (a_pStruct)->a_Member.uType == UDF_CHAR_SET_OSTA_COMPRESSED_UNICODE \
     401            && memcmp(&(a_pStruct)->a_Member.abInfo[0], UDF_CHAR_SET_OSTA_COMPRESSED_UNICODE_INFO, \
     402                      sizeof(UDF_CHAR_SET_OSTA_COMPRESSED_UNICODE_INFO)) == 0) \
     403            Log2(("ISO/UDF:   %-32s OSTA COMPRESSED UNICODE INFO\n", #a_Member ":")); \
     404        else if (ASMMemIsZero(&(a_pStruct)->a_Member, sizeof((a_pStruct)->a_Member))) \
     405            Log2(("ISO/UDF:   %-32s all zeros\n", #a_Member ":")); \
     406        else \
     407            Log2(("ISO/UDF:   %-32s %#x info: %.63Rhxs\n", #a_Member ":", \
     408                  (a_pStruct)->a_Member.uType, (a_pStruct)->a_Member.abInfo)); \
     409    } while (0)
     410#define UDF_LOG2_MEMBER_DSTRING(a_pStruct, a_Member) \
     411    do { \
     412        if ((a_pStruct)->a_Member[0] == 8) \
     413            Log2(("ISO/UDF:   %-32s  8: '%s' len=%u (actual=%u)\n", #a_Member ":", &(a_pStruct)->a_Member[1], \
     414                  (a_pStruct)->a_Member[sizeof((a_pStruct)->a_Member) - 1], \
     415                  RTStrNLen(&(a_pStruct)->a_Member[1], sizeof((a_pStruct)->a_Member) - 2) + 1 )); \
     416        else if ((a_pStruct)->a_Member[0] == 16) \
     417        { \
     418            PCRTUTF16 pwszTmp = (PCRTUTF16)&(a_pStruct)->a_Member[1]; \
     419            char *pszTmp = NULL; \
     420            RTUtf16BigToUtf8Ex(pwszTmp, (sizeof((a_pStruct)->a_Member) - 2) / sizeof(RTUTF16), &pszTmp, 0, NULL); \
     421            Log2(("ISO/UDF:   %-32s 16: '%s' len=%u (actual=%u)\n", #a_Member ":", pszTmp, \
     422                  (a_pStruct)->a_Member[sizeof((a_pStruct)->a_Member) - 1], \
     423                  RTUtf16NLen(pwszTmp, (sizeof((a_pStruct)->a_Member) - 2) / sizeof(RTUTF16)) * sizeof(RTUTF16) + 1 /*??*/ )); \
     424        } \
     425        else if (ASMMemIsZero(&(a_pStruct)->a_Member[0], sizeof((a_pStruct)->a_Member))) \
     426            Log2(("ISO/UDF:   %-32s empty\n", #a_Member ":")); \
     427        else \
     428            Log2(("ISO/UDF:   %-32s bad: %.*Rhxs\n", #a_Member ":", sizeof((a_pStruct)->a_Member), &(a_pStruct)->a_Member[0] )); \
     429    } while (0)
     430/** @} */
    313431
    314432
     
    325443                               uint32_t cDirRecs, uint64_t offDirRec, PRTVFSDIR phVfsDir);
    326444static PRTFSISOCORE rtFsIsoDir_LookupShared(PRTFSISODIRSHRD pThis, uint64_t offDirRec);
     445
     446
     447/**
     448 * UDF virtual partition read function.
     449 *
     450 * This deals with all the fun related to block mapping and such.
     451 *
     452 * @returns VBox status code.
     453 * @param   pThis           The instance.
     454 * @param   idxPart         The virtual partition number.
     455 * @param   idxBlock        The block number.
     456 * @param   offByteAddend   The byte offset relative to the block.
     457 * @param   pvBuf           The output buffer.
     458 * @param   cbBuf           The number of bytes to read.
     459 */
     460static int rtFsIsoVolUdfVpRead(PRTFSISOVOL pThis, uint32_t idxPart, uint32_t idxBlock, uint64_t offByteAddend,
     461                               void *pvBuf, size_t cbToRead)
     462{
     463    uint64_t const offByte = ((uint64_t)idxBlock << pThis->Udf.VolInfo.cShiftBlock) + offByteAddend;
     464
     465    int rc;
     466    if (idxPart < pThis->Udf.VolInfo.cPartitions)
     467    {
     468        PRTFSISOVOLUDFPMAP  pPart = &pThis->Udf.VolInfo.paPartitions[idxPart];
     469        switch (pPart->bType)
     470        {
     471            case RTFSISO_UDF_PMAP_T_PLAIN:
     472                rc = RTVfsFileReadAt(pThis->hVfsBacking, offByte + pPart->offByteLocation, pvBuf, cbToRead, NULL);
     473                if (RT_SUCCESS(rc))
     474                {
     475                    Log3(("ISO/UDF: Read %#x bytes at %#RX64 (%#x:%#RX64)\n",
     476                          cbToRead, offByte + pPart->offByteLocation, idxPart, offByte));
     477                    return VINF_SUCCESS;
     478                }
     479                Log(("ISO/UDF: Error reading %#x bytes at %#RX64 (%#x:%#RX64): %Rrc\n",
     480                     cbToRead, offByte + pPart->offByteLocation, idxPart, offByte, rc));
     481                break;
     482
     483            default:
     484                AssertFailed();
     485                rc = VERR_ISOFS_IPE_1;
     486                break;
     487        }
     488    }
     489    else
     490    {
     491        Log(("ISO/UDF: Invalid partition index %#x (offset %#RX64), max partitions %#x\n",
     492             idxPart, offByte, pThis->Udf.VolInfo.cPartitions));
     493        rc = VERR_ISOFS_INVALID_PARTITION_INDEX;
     494    }
     495    return rc;
     496}
    327497
    328498
     
    619789    switch (enmAddAttr)
    620790    {
    621         case RTFSOBJATTRADD_NOTHING: /* fall thru */
     791        case RTFSOBJATTRADD_NOTHING: RT_FALL_THRU();
    622792        case RTFSOBJATTRADD_UNIX:
    623793            pObjInfo->Attr.u.Unix.uid           = NIL_RTUID;
     
    20362206
    20372207
     2208#if 0
     2209/**
     2210 * Instantiates a new shared directory structure, given 9660 records.
     2211 *
     2212 * @returns IPRT status code.
     2213 * @param   pThis           The FAT volume instance.
     2214 * @param   pParentDir      The parent directory.  This is NULL for the root
     2215 *                          directory.
     2216 * @param   pDirRec         The directory record.  Will access @a cDirRecs
     2217 *                          records.
     2218 * @param   cDirRecs        Number of directory records if more than one.
     2219 * @param   offDirRec       The byte offset of the directory record.
     2220 * @param   ppShared        Where to return the shared directory structure.
     2221 */
     2222static int rtFsIsoDirShrd_NewUdf(PRTFSISOVOL pThis, PRTFSISODIRSHRD pParentDir,
     2223                                 PCUDFEXTVOLDESCNSR
     2224
     2225                                 PCISO9660DIRREC pDirRec, uint32_t cDirRecs, uint64_t offDirRec,
     2226                                 PRTFSISODIRSHRD *ppShared)
     2227{
     2228    /*
     2229     * Allocate a new structure and initialize it.
     2230     */
     2231    int rc = VERR_NO_MEMORY;
     2232    PRTFSISODIRSHRD pShared = (PRTFSISODIRSHRD)RTMemAllocZ(sizeof(*pShared));
     2233    if (pShared)
     2234    {
     2235        rc = rtFsIsoCore_InitFrom9660DirRec(&pShared->Core, pDirRec, cDirRecs, offDirRec, 0 /*uVersion*/, pThis);
     2236        if (RT_SUCCESS(rc))
     2237        {
     2238            RTListInit(&pShared->OpenChildren);
     2239            pShared->cbDir = ISO9660_GET_ENDIAN(&pDirRec->cbData);
     2240            pShared->pbDir = (uint8_t *)RTMemAllocZ(pShared->cbDir + 256);
     2241            if (pShared->pbDir)
     2242            {
     2243                rc = RTVfsFileReadAt(pThis->hVfsBacking, pShared->Core.FirstExtent.offDisk, pShared->pbDir, pShared->cbDir, NULL);
     2244                if (RT_SUCCESS(rc))
     2245                {
     2246#ifdef LOG_ENABLED
     2247                    rtFsIsoDirShrd_Log9660Content(pShared);
     2248#endif
     2249
     2250                    /*
     2251                     * Link into parent directory so we can use it to update
     2252                     * our directory entry.
     2253                     */
     2254                    if (pParentDir)
     2255                        rtFsIsoDirShrd_AddOpenChild(pParentDir, &pShared->Core);
     2256                    *ppShared = pShared;
     2257                    return VINF_SUCCESS;
     2258                }
     2259            }
     2260        }
     2261        RTMemFree(pShared);
     2262    }
     2263    *ppShared = NULL;
     2264    return rc;
     2265}
     2266#endif
     2267
     2268
    20382269/**
    20392270 * Instantiates a new directory with a shared structure presupplied.
     
    22352466                Log(("rtFsIsoVolValidateUdfDescTag(,%#x,%#010RX32,): Sector mismatch: %#RX32 (%.*Rhxs)\n",
    22362467                     idTag, offTag, pTag->offTag, sizeof(*pTag), pTag));
    2237                 return RTErrInfoSetF(pErrInfo, VERR_ISOFS_TAG_SECTOR_MISMATCH,
    2238                                      "Descriptor tag sector number mismatch: %#x, expected %#x (%.*Rhxs)",
    2239                                      pTag->offTag, offTag, sizeof(*pTag), pTag);
     2468                return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_TAG_SECTOR_MISMATCH,
     2469                                           "Descriptor tag sector number mismatch: %#x, expected %#x (%.*Rhxs)",
     2470                                           pTag->offTag, offTag, sizeof(*pTag), pTag);
    22402471            }
    22412472            Log(("rtFsIsoVolValidateUdfDescTag(,%#x,%#010RX32,): Tag ID mismatch: %#x (%.*Rhxs)\n",
    22422473                 idTag, offTag, pTag->idTag, sizeof(*pTag), pTag));
    2243             return RTErrInfoSetF(pErrInfo, VERR_MISMATCH, "Descriptor tag ID mismatch: %#x, expected %#x (%.*Rhxs)",
    2244                                  pTag->idTag, idTag, sizeof(*pTag), pTag);
     2474            return RTERRINFO_LOG_SET_F(pErrInfo, VERR_MISMATCH, "Descriptor tag ID mismatch: %#x, expected %#x (%.*Rhxs)",
     2475                                       pTag->idTag, idTag, sizeof(*pTag), pTag);
    22452476        }
    22462477        if (ASMMemIsZero(pTag, sizeof(*pTag)))
    22472478        {
    22482479            Log(("rtFsIsoVolValidateUdfDescTag(,%#x,%#010RX32,): All zeros\n", idTag, offTag));
    2249             return RTErrInfoSet(pErrInfo, VERR_ISOFS_TAG_IS_ALL_ZEROS, "Descriptor is all zeros");
     2480            return RTERRINFO_LOG_SET(pErrInfo, VERR_ISOFS_TAG_IS_ALL_ZEROS, "Descriptor is all zeros");
    22502481        }
    22512482
    22522483        Log(("rtFsIsoVolValidateUdfDescTag(,%#x,%#010RX32,): Unsupported version: %#x (%.*Rhxs)\n",
    22532484             idTag, offTag, pTag->uVersion, sizeof(*pTag), pTag));
    2254         return RTErrInfoSetF(pErrInfo, VERR_ISOFS_UNSUPPORTED_TAG_VERSION, "Unsupported descriptor tag version: %#x, expected 2 or 3 (%.*Rhxs)",
    2255                              pTag->uVersion, sizeof(*pTag), pTag);
     2485        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_UNSUPPORTED_TAG_VERSION, "Unsupported descriptor tag version: %#x, expected 2 or 3 (%.*Rhxs)",
     2486                                   pTag->uVersion, sizeof(*pTag), pTag);
    22562487    }
    22572488    Log(("rtFsIsoVolValidateUdfDescTag(,%#x,%#010RX32,): checksum error: %#x, calc %#x (%.*Rhxs)\n",
    22582489         idTag, offTag, pTag->uChecksum, bChecksum, sizeof(*pTag), pTag));
    2259     return RTErrInfoSetF(pErrInfo, VERR_ISOFS_BAD_TAG_CHECKSUM,
    2260                          "Descriptor tag checksum error: %#x, calculated %#x (%.*Rhxs)",
    2261                          pTag->uChecksum, bChecksum, sizeof(*pTag), pTag);
     2490    return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_BAD_TAG_CHECKSUM,
     2491                               "Descriptor tag checksum error: %#x, calculated %#x (%.*Rhxs)",
     2492                               pTag->uChecksum, bChecksum, sizeof(*pTag), pTag);
    22622493}
    22632494
     
    22842515        Log(("rtFsIsoVolValidateUdfDescCrc(,%#x,%#010RX32,): Descriptor CRC mismatch: expected %#x, calculated %#x (cbDescriptorCrc=%#x)\n",
    22852516             pTag->idTag, pTag->offTag, pTag->uDescriptorCrc, uCrc, pTag->cbDescriptorCrc));
    2286         return RTErrInfoSetF(pErrInfo, VERR_ISOFS_DESC_CRC_MISMATCH,
    2287                              "Descriptor CRC mismatch: exepcted %#x, calculated %#x (cbDescriptor=%#x, idTag=%#x, offTag=%#010RX32)",
    2288                              pTag->uDescriptorCrc, uCrc, pTag->cbDescriptorCrc, pTag->idTag, pTag->offTag);
     2517        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_DESC_CRC_MISMATCH,
     2518                                   "Descriptor CRC mismatch: exepcted %#x, calculated %#x (cbDescriptor=%#x, idTag=%#x, offTag=%#010RX32)",
     2519                                   pTag->uDescriptorCrc, uCrc, pTag->cbDescriptorCrc, pTag->idTag, pTag->offTag);
    22892520    }
    22902521
    22912522    Log(("rtFsIsoVolValidateUdfDescCrc(,%#x,%#010RX32,): Insufficient data to CRC: cbDescriptorCrc=%#x cbDesc=%#zx\n",
    22922523         pTag->idTag, pTag->offTag, pTag->cbDescriptorCrc, cbDesc));
    2293     return RTErrInfoSetF(pErrInfo, VERR_ISOFS_INSUFFICIENT_DATA_FOR_DESC_CRC,
    2294                          "Insufficient data to CRC: cbDescriptorCrc=%#x cbDesc=%#zx (idTag=%#x, offTag=%#010RX32)",
    2295                          pTag->cbDescriptorCrc, cbDesc, pTag->idTag, pTag->offTag);
     2524    return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_INSUFFICIENT_DATA_FOR_DESC_CRC,
     2525                               "Insufficient data to CRC: cbDescriptorCrc=%#x cbDesc=%#zx (idTag=%#x, offTag=%#010RX32)",
     2526                               pTag->cbDescriptorCrc, cbDesc, pTag->idTag, pTag->offTag);
    22962527}
    22972528
     
    23262557
    23272558
    2328 #define UDF_LOG2_MEMBER(a_pStruct, a_szFmt, a_Member) \
    2329     Log2(("ISO/UDF:   %-32s %" a_szFmt "\n", #a_Member ":", (a_pStruct)->a_Member))
    2330 #define UDF_LOG2_MEMBER_EX(a_pStruct, a_szFmt, a_Member, a_cchIndent) \
    2331     Log2(("ISO/UDF:   %*s%-32s %" a_szFmt "\n", a_cchIndent, "", #a_Member ":", (a_pStruct)->a_Member))
    2332 #define UDF_LOG2_MEMBER_ENTITY_ID_EX(a_pStruct, a_Member, a_cchIndent) \
    2333     Log2(("ISO/UDF:   %*s%-32s '%.23s' fFlags=%#06x Suffix=%.8Rhxs\n", a_cchIndent, "", #a_Member ":", \
    2334           (a_pStruct)->a_Member.achIdentifier, (a_pStruct)->a_Member.fFlags, &(a_pStruct)->a_Member.Suffix))
    2335 #define UDF_LOG2_MEMBER_ENTITY_ID(a_pStruct, a_Member) UDF_LOG2_MEMBER_ENTITY_ID_EX(a_pStruct, a_Member, 0)
    2336 #define UDF_LOG2_MEMBER_EXTENTAD(a_pStruct, a_Member) \
    2337     Log2(("ISO/UDF:   %-32s sector %#010RX32 LB %#010RX32\n", #a_Member ":", (a_pStruct)->a_Member.off, (a_pStruct)->a_Member.cb))
    2338 #define UDF_LOG2_MEMBER_SHORTAD(a_pStruct, a_Member) \
    2339     Log2(("ISO/UDF:   %-32s sector %#010RX32 LB %#010RX32 %s\n", #a_Member ":", (a_pStruct)->a_Member.off, (a_pStruct)->a_Member.cb, \
    2340           (a_pStruct)->a_Member.uType == UDF_AD_TYPE_RECORDED_AND_ALLOCATED ? "alloced+recorded" \
    2341           : (a_pStruct)->a_Member.uType == UDF_AD_TYPE_ONLY_ALLOCATED ? "alloced" \
    2342           : (a_pStruct)->a_Member.uType == UDF_AD_TYPE_FREE ? "free" : "next" ))
    2343 #define UDF_LOG2_MEMBER_LONGAD(a_pStruct, a_Member) \
    2344     Log2(("ISO/UDF:   %-32s partition %#RX16, sector %#010RX32 LB %#010RX32 %s idUnique=%#010RX32 fFlags=%#RX16\n", #a_Member ":", \
    2345           (a_pStruct)->a_Member.Location.uPartitionNo, (a_pStruct)->a_Member.Location.off, (a_pStruct)->a_Member.cb, \
    2346           (a_pStruct)->a_Member.uType == UDF_AD_TYPE_RECORDED_AND_ALLOCATED ? "alloced+recorded" \
    2347           : (a_pStruct)->a_Member.uType == UDF_AD_TYPE_ONLY_ALLOCATED ? "alloced" \
    2348           : (a_pStruct)->a_Member.uType == UDF_AD_TYPE_FREE ? "free" : "next", \
    2349           (a_pStruct)->a_Member.ImplementationUse.Fid.idUnique, (a_pStruct)->a_Member.ImplementationUse.Fid.fFlags ))
    2350 
    2351 #define UDF_LOG2_MEMBER_TIMESTAMP(a_pStruct, a_Member) \
    2352     Log2(("ISO/UDF:   %-32s %04d-%02u-%02u %02u:%02u:%02u.%02u%02u%02u uTypeAndZone=%#x\n", #a_Member ":", \
    2353           (a_pStruct)->a_Member.iYear, (a_pStruct)->a_Member.uMonth, (a_pStruct)->a_Member.uDay, \
    2354           (a_pStruct)->a_Member.uHour, (a_pStruct)->a_Member.uMinute, (a_pStruct)->a_Member.uSecond, \
    2355           (a_pStruct)->a_Member.cCentiseconds, (a_pStruct)->a_Member.cHundredsOfMicroseconds, \
    2356           (a_pStruct)->a_Member.cMicroseconds, (a_pStruct)->a_Member.uTypeAndZone))
    2357 #define UDF_LOG2_MEMBER_CHARSPEC(a_pStruct, a_Member) \
    2358     do { \
    2359         if (   (a_pStruct)->a_Member.uType == UDF_CHAR_SET_OSTA_COMPRESSED_UNICODE \
    2360             && memcmp(&(a_pStruct)->a_Member.abInfo[0], UDF_CHAR_SET_OSTA_COMPRESSED_UNICODE_INFO, \
    2361                       sizeof(UDF_CHAR_SET_OSTA_COMPRESSED_UNICODE_INFO)) == 0) \
    2362             Log2(("ISO/UDF:   %-32s OSTA COMPRESSED UNICODE INFO\n", #a_Member ":")); \
    2363         else if (ASMMemIsZero(&(a_pStruct)->a_Member, sizeof((a_pStruct)->a_Member))) \
    2364             Log2(("ISO/UDF:   %-32s all zeros\n", #a_Member ":")); \
    2365         else \
    2366             Log2(("ISO/UDF:   %-32s %#x info: %.63Rhxs\n", #a_Member ":", \
    2367                   (a_pStruct)->a_Member.uType, (a_pStruct)->a_Member.abInfo)); \
    2368     } while (0)
    2369 #define UDF_LOG2_MEMBER_DSTRING(a_pStruct, a_Member) \
    2370     do { \
    2371         if ((a_pStruct)->a_Member[0] == 8) \
    2372             Log2(("ISO/UDF:   %-32s  8: '%s' len=%u (actual=%u)\n", #a_Member ":", &(a_pStruct)->a_Member[1], \
    2373                   (a_pStruct)->a_Member[sizeof((a_pStruct)->a_Member) - 1], strlen(&(a_pStruct)->a_Member[1]) + 1 )); \
    2374         else if ((a_pStruct)->a_Member[0] == 16) \
    2375         { \
    2376             PCRTUTF16 pwszTmp = (PCRTUTF16)&(a_pStruct)->a_Member[1]; \
    2377             char *pszTmp = NULL; \
    2378             RTUtf16BigToUtf8Ex(pwszTmp, (sizeof((a_pStruct)->a_Member) - 2) / sizeof(RTUTF16), &pszTmp, 0, NULL); \
    2379             Log2(("ISO/UDF:   %-32s 16: '%s' len=%u (actual=%u)\n", #a_Member ":", pszTmp, \
    2380                   (a_pStruct)->a_Member[sizeof((a_pStruct)->a_Member) - 1], RTUtf16Len(pwszTmp) * sizeof(RTUTF16) + 1 /*??*/ )); \
    2381         } \
    2382         else if (ASMMemIsZero(&(a_pStruct)->a_Member[0], sizeof((a_pStruct)->a_Member))) \
    2383             Log2(("ISO/UDF:   %-32s empty\n", #a_Member ":")); \
    2384         else \
    2385             Log2(("ISO/UDF:   %-32s bad: %.*Rhxs\n", #a_Member ":", sizeof((a_pStruct)->a_Member), &(a_pStruct)->a_Member[0] )); \
    2386     } while (0)
    2387 
     2559
     2560
     2561static int rtFsIsoVolProcessUdfFileSetDescs(PRTFSISOVOL pThis, uint8_t *pbBuf, size_t cbBuf, PRTERRINFO pErrInfo)
     2562{
     2563
     2564    /*
     2565     * We assume there is a single file descriptor and don't bother checking what comes next.
     2566     */
     2567    PUDFFILESETDESC pFsd     = (PUDFFILESETDESC)pbBuf;
     2568    Assert(cbBuf > sizeof(*pFsd)); NOREF(cbBuf);
     2569    RT_ZERO(*pFsd);
     2570    size_t          cbToRead = RT_MAX(pThis->Udf.VolInfo.FileSetDescriptor.cb, sizeof(*pFsd));
     2571    int rc = rtFsIsoVolUdfVpRead(pThis, pThis->Udf.VolInfo.FileSetDescriptor.Location.uPartitionNo,
     2572                                 pThis->Udf.VolInfo.FileSetDescriptor.Location.off, 0, pFsd, cbToRead);
     2573    if (RT_SUCCESS(rc))
     2574    {
     2575        rc = rtFsIsoVolValidateUdfDescTagAndCrc(&pFsd->Tag, cbToRead, UDF_TAG_ID_FILE_SET_DESC,
     2576                                                pThis->Udf.VolInfo.FileSetDescriptor.Location.off, pErrInfo);
     2577        if (RT_SUCCESS(rc))
     2578        {
     2579#ifdef LOG_ENABLED
     2580            Log(("ISO/UDF: File set descriptor at %#RX32 (%#RX32:%#RX32)\n", pFsd->Tag.offTag,
     2581                 pThis->Udf.VolInfo.FileSetDescriptor.Location.uPartitionNo,
     2582                 pThis->Udf.VolInfo.FileSetDescriptor.Location.off));
     2583            if (LogIs2Enabled())
     2584            {
     2585                UDF_LOG2_MEMBER_TIMESTAMP(pFsd, RecordingTimestamp);
     2586                UDF_LOG2_MEMBER(pFsd, "#06RX16", uInterchangeLevel);
     2587                UDF_LOG2_MEMBER(pFsd, "#06RX16", uMaxInterchangeLevel);
     2588                UDF_LOG2_MEMBER(pFsd, "#010RX32", fCharacterSets);
     2589                UDF_LOG2_MEMBER(pFsd, "#010RX32", fMaxCharacterSets);
     2590                UDF_LOG2_MEMBER(pFsd, "#010RX32", uFileSetNo);
     2591                UDF_LOG2_MEMBER(pFsd, "#010RX32", uFileSetDescNo);
     2592                UDF_LOG2_MEMBER_CHARSPEC(pFsd, LogicalVolumeIDCharSet);
     2593                UDF_LOG2_MEMBER_DSTRING(pFsd, achLogicalVolumeID);
     2594                UDF_LOG2_MEMBER_CHARSPEC(pFsd, FileSetCharSet);
     2595                UDF_LOG2_MEMBER_DSTRING(pFsd, achFileSetID);
     2596                UDF_LOG2_MEMBER_DSTRING(pFsd, achCopyrightFile);
     2597                UDF_LOG2_MEMBER_DSTRING(pFsd, achAbstractFile);
     2598                UDF_LOG2_MEMBER_LONGAD(pFsd, RootDirIcb);
     2599                UDF_LOG2_MEMBER_ENTITY_ID(pFsd, idDomain);
     2600                UDF_LOG2_MEMBER_LONGAD(pFsd, NextExtent);
     2601                UDF_LOG2_MEMBER_LONGAD(pFsd, SystemStreamDirIcb);
     2602                if (!ASMMemIsZero(&pFsd->abReserved[0], sizeof(pFsd->abReserved)))
     2603                    UDF_LOG2_MEMBER(pFsd, "%.32Rhxs", abReserved);
     2604            }
     2605#endif
     2606
     2607            /*
     2608             * Do some basic sanity checking.
     2609             */
     2610            if (!UDF_IS_CHAR_SET_OSTA(&pFsd->FileSetCharSet))
     2611                return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_FSD_UNSUPPORTED_CHAR_SET,
     2612                                           "Invalid file set charset %.64Rhxs", &pFsd->FileSetCharSet);
     2613            if (   pFsd->RootDirIcb.cb == 0
     2614                || pFsd->RootDirIcb.uType != UDF_AD_TYPE_RECORDED_AND_ALLOCATED)
     2615                return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_FSD_ZERO_ROOT_DIR,
     2616                                           "Root Dir ICB location is zero or malformed: uType=%#x cb=%#x loc=%#x:%#RX32",
     2617                                           pFsd->RootDirIcb.uType, pFsd->RootDirIcb.cb,
     2618                                           pFsd->RootDirIcb.Location.uPartitionNo, pFsd->RootDirIcb.Location.off);
     2619            if (   pFsd->NextExtent.cb != 0
     2620                && pFsd->NextExtent.uType == UDF_AD_TYPE_RECORDED_AND_ALLOCATED)
     2621                return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_FSD_NEXT_EXTENT,
     2622                                           "NextExtent isn't zero: uType=%#x cb=%#x loc=%#x:%#RX32",
     2623                                           pFsd->NextExtent.uType, pFsd->NextExtent.cb,
     2624                                           pFsd->NextExtent.Location.uPartitionNo, pFsd->NextExtent.Location.off);
     2625
     2626            /*
     2627             * Copy the information we need.
     2628             */
     2629            pThis->Udf.VolInfo.RootDirIcb         = pFsd->RootDirIcb;
     2630            if (   pFsd->SystemStreamDirIcb.cb > 0
     2631                && pFsd->SystemStreamDirIcb.uType == UDF_AD_TYPE_RECORDED_AND_ALLOCATED)
     2632                pThis->Udf.VolInfo.SystemStreamDirIcb = pFsd->SystemStreamDirIcb;
     2633            else
     2634                RT_ZERO(pThis->Udf.VolInfo.SystemStreamDirIcb);
     2635            return VINF_SUCCESS;
     2636        }
     2637        return rc;
     2638    }
     2639    return RTERRINFO_LOG_SET(pErrInfo, rc, "Error reading file set descriptor");
     2640}
     2641
     2642
     2643/**
     2644 * Check validatity and extract information from the descriptors in the VDS seq.
     2645 *
     2646 * @returns IPRT status code
     2647 * @param   pThis       The instance.
     2648 * @param   pInfo       The VDS sequence info.
     2649 * @param   pErrInfo    Where to return extended error info.
     2650 */
     2651static int rtFsIsoVolProcessUdfVdsSeqInfo(PRTFSISOVOL pThis, PRTFSISOVDSINFO pInfo, PRTERRINFO pErrInfo)
     2652{
     2653    /*
     2654     * Check the basic descriptor counts.
     2655     */
     2656    PUDFPRIMARYVOLUMEDESC pPvd;
     2657    if (pInfo->cPrimaryVols == 1)
     2658        pPvd = pInfo->apPrimaryVols[0];
     2659    else
     2660    {
     2661        if (pInfo->cPrimaryVols == 0)
     2662            return RTERRINFO_LOG_SET(pErrInfo, VERR_ISOFS_NO_PVD, "No primary volume descriptor was found");
     2663        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_MULTIPLE_PVDS,
     2664                                   "More than one primary volume descriptor was found: %u", pInfo->cPrimaryVols);
     2665    }
     2666
     2667    PUDFLOGICALVOLUMEDESC pLvd;
     2668    if (pInfo->cLogicalVols == 1)
     2669        pLvd = pInfo->apLogicalVols[0];
     2670    else
     2671    {
     2672        if (pInfo->cLogicalVols == 0)
     2673            return RTERRINFO_LOG_SET(pErrInfo, VERR_ISOFS_NO_LVD, "No logical volume descriptor was found");
     2674        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_MULTIPLE_LVDS,
     2675                                   "More than one logical volume descriptor was found: %u", pInfo->cLogicalVols);
     2676    }
     2677
     2678#if 0
     2679    if (pInfo->cPartitions == 0)
     2680        return RTERRINFO_LOG_SET(pErrInfo, VERR_ISOFS_NO_PD, "No partition descriptors was found");
     2681#endif
     2682
     2683    /*
     2684     * Check out the partition map in the logical volume descriptor.
     2685     * Produce the mapping table while going about that.
     2686     */
     2687    if (pLvd->cPartitionMaps > 64)
     2688        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_TOO_MANY_PART_MAPS,
     2689                                   "Too many partition maps: %u (max 64)", pLvd->cPartitionMaps);
     2690
     2691    PRTFSISOVOLUDFPMAP paPartMaps = NULL;
     2692    if (pLvd->cPartitionMaps > 0)
     2693    {
     2694        pInfo->paPartMaps = paPartMaps = (PRTFSISOVOLUDFPMAP)RTMemAllocZ(sizeof(paPartMaps[0]) * pLvd->cPartitionMaps);
     2695        if (!paPartMaps)
     2696            return VERR_NO_MEMORY;
     2697    }
     2698    uint32_t cPartMaps = 0;
     2699
     2700    if (pLvd->cbMapTable)
     2701    {
     2702        uint32_t off  = 0;
     2703        while (off + sizeof(UDFPARTMAPHDR) <= pLvd->cbMapTable)
     2704        {
     2705            PCUDFPARTMAPHDR pHdr = (PCUDFPARTMAPHDR)&pLvd->abPartitionMaps[off];
     2706
     2707            /*
     2708             * Bounds checking.
     2709             */
     2710            if (off + pHdr->cb > pLvd->cbMapTable)
     2711            {
     2712                if (cPartMaps < pLvd->cbMapTable)
     2713                    return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_MALFORMED_PART_MAP_TABLE,
     2714                                               "Incomplete partition map entry at offset %#x: cb=%#x -> offEnd=%#x cbMapTable=%#x (type=%#x)",
     2715                                               off, pHdr->cb, off + pHdr->cb, pLvd->cbMapTable, pHdr->bType);
     2716                LogRel(("ISO/UDF: Warning: Incomplete partition map entry at offset %#x: cb=%#x -> offEnd=%#x cbMapTable=%#x (type=%#x)\n",
     2717                        off, pHdr->cb, off + pHdr->cb, pLvd->cbMapTable, pHdr->bType));
     2718                break;
     2719            }
     2720            if (cPartMaps >= pLvd->cPartitionMaps)
     2721            {
     2722                LogRel(("ISO/UDF: Warning: LVD::cPartitionMaps is %u but there are more bytes in the table. (off=%#x cb=%#x cbMapTable=%#x bType=%#x)\n",
     2723                        off, pHdr->cb, pLvd->cbMapTable, pHdr->bType));
     2724                break;
     2725            }
     2726
     2727            /*
     2728             * Extract relevant info out of the entry.
     2729             */
     2730            paPartMaps[cPartMaps].offMapTable = (uint16_t)off;
     2731            uint16_t uPartitionNo;
     2732            if (pHdr->bType == 1)
     2733            {
     2734                PCUDFPARTMAPTYPE1 pType1 = (PCUDFPARTMAPTYPE1)pHdr;
     2735                paPartMaps[cPartMaps].uVolumeSeqNo = pType1->uVolumeSeqNo;
     2736                paPartMaps[cPartMaps].bType        = RTFSISO_UDF_PMAP_T_PLAIN;
     2737                uPartitionNo = pType1->uPartitionNo;
     2738            }
     2739            else if (pHdr->bType == 2)
     2740            {
     2741                PCUDFPARTMAPTYPE2 pType2 = (PCUDFPARTMAPTYPE2)pHdr;
     2742                if (UDF_ENTITY_ID_EQUALS(&pType2->idPartitionType, UDF_ENTITY_ID_VPM_PARTITION_TYPE))
     2743                {
     2744                    paPartMaps[cPartMaps].bType = pType2->idPartitionType.Suffix.Udf.uUdfRevision >= 0x200
     2745                                                ? RTFSISO_UDF_PMAP_T_VPM_20 : RTFSISO_UDF_PMAP_T_VPM_15;
     2746                    return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_VPM_NOT_SUPPORTED, "Partition type '%.23s' (%#x) not supported",
     2747                                               pType2->idPartitionType.achIdentifier, pType2->idPartitionType.Suffix.Udf.uUdfRevision);
     2748                }
     2749                else if (UDF_ENTITY_ID_EQUALS(&pType2->idPartitionType, UDF_ENTITY_ID_SPM_PARTITION_TYPE))
     2750                {
     2751                    paPartMaps[cPartMaps].bType = RTFSISO_UDF_PMAP_T_SPM;
     2752                    return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_SPM_NOT_SUPPORTED, "Partition type '%.23s' (%#x) not supported",
     2753                                               pType2->idPartitionType.achIdentifier, pType2->idPartitionType.Suffix.Udf.uUdfRevision);
     2754                }
     2755                else if (UDF_ENTITY_ID_EQUALS(&pType2->idPartitionType, UDF_ENTITY_ID_MPM_PARTITION_TYPE))
     2756                {
     2757                    paPartMaps[cPartMaps].bType = RTFSISO_UDF_PMAP_T_MPM;
     2758                    return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_MPM_NOT_SUPPORTED, "Partition type '%.23s' (%#x) not supported",
     2759                                               pType2->idPartitionType.achIdentifier, pType2->idPartitionType.Suffix.Udf.uUdfRevision);
     2760                }
     2761                else
     2762                    return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_UNKNOWN_PART_MAP_TYPE_ID,
     2763                                               "Unknown partition map ID for #%u @ %#x: %.23s",
     2764                                               cPartMaps, off, pType2->idPartitionType.achIdentifier);
     2765#if 0 /* unreachable code */
     2766                paPartMaps[cPartMaps].uVolumeSeqNo = pType2->uVolumeSeqNo;
     2767                uPartitionNo = pType2->uPartitionNo;
     2768#endif
     2769            }
     2770            else
     2771                return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_UNKNOWN_PART_MAP_ENTRY_TYPE,
     2772                                           "Unknown partition map entry type #%u @ %#x: %u", cPartMaps, off, pHdr->bType);
     2773            paPartMaps[cPartMaps].uPartitionNo = uPartitionNo;
     2774
     2775            /*
     2776             * Lookup the partition number and retrieve the relevant info from the partition descriptor.
     2777             */
     2778            uint32_t i = pInfo->cPartitions;
     2779            while (i-- > 0)
     2780            {
     2781                PUDFPARTITIONDESC pPd = pInfo->apPartitions[i];
     2782                if (paPartMaps[cPartMaps].uPartitionNo == pPd->uPartitionNo)
     2783                {
     2784                    paPartMaps[cPartMaps].idxPartDesc     = (uint16_t)i;
     2785                    paPartMaps[cPartMaps].cSectors        = pPd->cSectors;
     2786                    paPartMaps[cPartMaps].offLocation     = pPd->offLocation;
     2787                    paPartMaps[cPartMaps].offByteLocation = (uint64_t)pPd->offLocation * pThis->cbSector;
     2788                    paPartMaps[cPartMaps].fFlags          = pPd->fFlags;
     2789                    paPartMaps[cPartMaps].uAccessType     = pPd->uAccessType;
     2790                    if (!UDF_ENTITY_ID_EQUALS(&pPd->PartitionContents, UDF_ENTITY_ID_PD_PARTITION_CONTENTS_UDF))
     2791                        paPartMaps[cPartMaps].fHaveHdr    = false;
     2792                    else
     2793                    {
     2794                        paPartMaps[cPartMaps].fHaveHdr    = true;
     2795                        paPartMaps[cPartMaps].Hdr         = pPd->ContentsUse.Hdr;
     2796                    }
     2797                    break;
     2798                }
     2799            }
     2800            if (i > pInfo->cPartitions)
     2801                return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_PARTITION_NOT_FOUND,
     2802                                           "Partition #%u (%#x) specified by mapping entry #%u (@ %#x) was not found! (int-type %u)",
     2803                                           uPartitionNo, uPartitionNo, cPartMaps, off, paPartMaps[cPartMaps].bType);
     2804
     2805            /*
     2806             * Advance.
     2807             */
     2808            cPartMaps++;
     2809            off += pHdr->cb;
     2810        }
     2811
     2812        if (cPartMaps < pLvd->cPartitionMaps)
     2813            return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_INCOMPLETE_PART_MAP_TABLE,
     2814                                       "Only found %u of the %u announced partition mapping table entries",
     2815                                       cPartMaps, pLvd->cPartitionMaps);
     2816    }
     2817
     2818    /* It might be theoretically possible to not use virtual partitions for
     2819       accessing data, so just warn if there aren't any. */
     2820    if (cPartMaps == 0)
     2821        LogRel(("ISO/UDF: Warning: No partition maps!\n"));
     2822
     2823    /*
     2824     * Check out the logical volume descriptor.
     2825     */
     2826    if (   pLvd->cbLogicalBlock < pThis->cbSector
     2827        || pLvd->cbLogicalBlock > _16K
     2828        || (pLvd->cbLogicalBlock % pThis->cbSector) != 0)
     2829        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_UNSUPPORTED_LOGICAL_BLOCK_SIZE,
     2830                                   "Logical block size of %#x is not supported with a sector size of %#x",
     2831                                   pLvd->cbLogicalBlock, pThis->cbSector);
     2832
     2833    if (!UDF_ENTITY_ID_EQUALS(&pLvd->idDomain, UDF_ENTITY_ID_LVD_DOMAIN))
     2834        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_BAD_LVD_DOMAIN_ID,
     2835                                   "Unsupported domain ID in logical volume descriptor: '%.23s'", pLvd->idDomain.achIdentifier);
     2836
     2837    if (   pLvd->ContentsUse.FileSetDescriptor.uType != UDF_AD_TYPE_RECORDED_AND_ALLOCATED
     2838        || pLvd->ContentsUse.FileSetDescriptor.cb    == 0
     2839        || pLvd->ContentsUse.FileSetDescriptor.Location.uPartitionNo >= cPartMaps)
     2840        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_BAD_LVD_FILE_SET_DESC_LOCATION,
     2841                                   "Malformed file set descriptor location (type=%u cb=%#x part=%#x)",
     2842                                   pLvd->ContentsUse.FileSetDescriptor.uType,
     2843                                   pLvd->ContentsUse.FileSetDescriptor.cb,
     2844                                   pLvd->ContentsUse.FileSetDescriptor.Location.uPartitionNo);
     2845
     2846    bool fLvdHaveVolId = !ASMMemIsZero(pLvd->achLogicalVolumeID, sizeof(pLvd->achLogicalVolumeID));
     2847    if (   fLvdHaveVolId
     2848        && !UDF_IS_CHAR_SET_OSTA(&pLvd->DescCharSet))
     2849        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_BAD_LVD_DESC_CHAR_SET,
     2850                                   "Logical volume ID is not using OSTA compressed unicode");
     2851
     2852    /*
     2853     * We can ignore much, if not all of the primary volume descriptor.
     2854     */
     2855
     2856    /*
     2857     * We're good. So copy over the data.
     2858     */
     2859    pThis->Udf.VolInfo.FileSetDescriptor = pLvd->ContentsUse.FileSetDescriptor;
     2860    pThis->Udf.VolInfo.cbBlock           = pLvd->cbLogicalBlock;
     2861    pThis->Udf.VolInfo.cShiftBlock       = 9;
     2862    while (pThis->Udf.VolInfo.cbBlock != RT_BIT_32(pThis->Udf.VolInfo.cShiftBlock))
     2863        pThis->Udf.VolInfo.cShiftBlock++;
     2864    pThis->Udf.VolInfo.fFlags            = pPvd->fFlags;
     2865    pThis->Udf.VolInfo.cPartitions       = cPartMaps;
     2866    pThis->Udf.VolInfo.paPartitions      = paPartMaps;
     2867    pInfo->paPartMaps = NULL;
     2868    if (fLvdHaveVolId)
     2869        memcpy(pThis->Udf.VolInfo.achLogicalVolumeID, pLvd->achLogicalVolumeID, sizeof(pThis->Udf.VolInfo.achLogicalVolumeID));
     2870    else
     2871        RT_ZERO(pThis->Udf.VolInfo.achLogicalVolumeID);
     2872
     2873    return VINF_SUCCESS;
     2874}
    23882875
    23892876
     
    23922879 *
    23932880 * @returns IPRT status code.
    2394  * @param   pThis       The instance.
     2881 * @param   pInfo       Where we gather descriptor information.
    23952882 * @param   pDesc       The descriptor.
    23962883 * @param   pErrInfo    Where to return extended error information.
    23972884 */
    23982885//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
    2399 static int rtFsIsoVolProcessUdfPrimaryVolDesc(PRTFSISOVOL pThis, PCUDFPRIMARYVOLUMEDESC pDesc, PRTERRINFO pErrInfo)
     2886static int rtFsIsoVolProcessUdfPrimaryVolDesc(PRTFSISOVDSINFO pInfo, PCUDFPRIMARYVOLUMEDESC pDesc, PRTERRINFO pErrInfo)
    24002887{
    24012888#ifdef LOG_ENABLED
     
    24302917#endif
    24312918
    2432     RT_NOREF(pThis, pDesc, pErrInfo);
     2919    /*
     2920     * Check if this is a new revision of an existing primary volume descriptor.
     2921     */
     2922    PUDFPRIMARYVOLUMEDESC pEndianConvert = NULL;
     2923    uint32_t i = pInfo->cPrimaryVols;
     2924    while (i--> 0)
     2925    {
     2926        if (   memcmp(pDesc->achVolumeID, pInfo->apPrimaryVols[i]->achVolumeID, sizeof(pDesc->achVolumeID)) == 0
     2927            && memcmp(&pDesc->DescCharSet, &pInfo->apPrimaryVols[i]->DescCharSet, sizeof(pDesc->DescCharSet)) == 0)
     2928        {
     2929            if (RT_LE2H_U32(pDesc->uVolumeDescSeqNo) >= pInfo->apPrimaryVols[i]->uVolumeDescSeqNo)
     2930            {
     2931                Log(("ISO/UDF: Primary descriptor prevails over previous! (%u >= %u)\n",
     2932                     RT_LE2H_U32(pDesc->uVolumeDescSeqNo), pInfo->apPartitions[i]->uVolumeDescSeqNo));
     2933                pEndianConvert = pInfo->apPrimaryVols[i];
     2934                memcpy(pEndianConvert, pDesc, sizeof(*pDesc));
     2935            }
     2936            else
     2937                Log(("ISO/UDF: Primary descriptor has lower sequence number than the previous! (%u < %u)\n",
     2938                     RT_LE2H_U32(pDesc->uVolumeDescSeqNo), pInfo->apPartitions[i]->uVolumeDescSeqNo));
     2939            break;
     2940        }
     2941    }
     2942    if (i >= pInfo->cPrimaryVols)
     2943    {
     2944        /*
     2945         * It wasn't. Append it.
     2946         */
     2947        i = pInfo->cPrimaryVols;
     2948        if (i < RT_ELEMENTS(pInfo->apPrimaryVols))
     2949        {
     2950            pInfo->apPrimaryVols[i] = pEndianConvert = (PUDFPRIMARYVOLUMEDESC)RTMemDup(pDesc, sizeof(*pDesc));
     2951            if (pEndianConvert)
     2952                pInfo->cPrimaryVols = i + 1;
     2953            else
     2954                return VERR_NO_MEMORY;
     2955            Log2(("ISO/UDF: ++New primary descriptor.\n"));
     2956        }
     2957        else
     2958            return RTERRINFO_LOG_SET(pErrInfo, VERR_ISOFS_TOO_MANY_PVDS, "Encountered too many primary volume descriptors");
     2959    }
     2960
     2961#ifdef RT_BIG_ENDIAN
     2962    /*
     2963     * Do endian conversion of the descriptor.
     2964     */
     2965    if (pEndianConvert)
     2966    {
     2967        AssertFailed();
     2968    }
     2969#else
     2970    RT_NOREF(pEndianConvert);
     2971#endif
    24332972    return VINF_SUCCESS;
    24342973}
     
    24392978 *
    24402979 * @returns IPRT status code.
    2441  * @param   pThis       The instance.
     2980 * @param   pInfo       Where we gather descriptor information.
    24422981 * @param   pDesc       The descriptor.
     2982 * @param   cbSector    The sector size (UDF defines the logical and physical
     2983 *                      sector size to be the same).
    24432984 * @param   pErrInfo    Where to return extended error information.
    24442985 */
    2445 static int rtFsIsoVolProcessUdfLogicalVolumeDesc(PRTFSISOVOL pThis, PCUDFLOGICALVOLUMEDESC pDesc, PRTERRINFO pErrInfo)
     2986static int rtFsIsoVolProcessUdfLogicalVolumeDesc(PRTFSISOVDSINFO pInfo, PCUDFLOGICALVOLUMEDESC pDesc,
     2987                                                 uint32_t cbSector, PRTERRINFO pErrInfo)
    24462988{
    24472989#ifdef LOG_ENABLED
     
    24502992    {
    24512993        UDF_LOG2_MEMBER(pDesc, "#010RX32", uVolumeDescSeqNo);
    2452         UDF_LOG2_MEMBER_CHARSPEC(pDesc, DescriptorCharSet);
     2994        UDF_LOG2_MEMBER_CHARSPEC(pDesc, DescCharSet);
    24532995        UDF_LOG2_MEMBER_DSTRING(pDesc, achLogicalVolumeID);
    24542996        UDF_LOG2_MEMBER(pDesc, "#010RX32", cbLogicalBlock);
    24552997        UDF_LOG2_MEMBER_ENTITY_ID(pDesc, idDomain);
    2456         if (memcmp(&pDesc->idDomain.achIdentifier[0], RT_STR_TUPLE(UDF_ENTITY_ID_LVD_DOMAIN) + 1) == 0)
     2998        if (UDF_ENTITY_ID_EQUALS(&pDesc->idDomain, UDF_ENTITY_ID_LVD_DOMAIN))
    24572999            UDF_LOG2_MEMBER_LONGAD(pDesc, ContentsUse.FileSetDescriptor);
    24583000        else if (!ASMMemIsZero(&pDesc->ContentsUse.ab[0], sizeof(pDesc->ContentsUse.ab)))
     
    25023044#endif
    25033045
    2504     RT_NOREF(pThis, pDesc, pErrInfo);
     3046    /*
     3047     * Check if this is a newer revision of an existing primary volume descriptor.
     3048     */
     3049    size_t cbDesc = (size_t)pDesc->cbMapTable + RT_UOFFSETOF(UDFLOGICALVOLUMEDESC, abPartitionMaps);
     3050    if (   pDesc->cbMapTable >= (UINT32_MAX >> 1)
     3051        || cbDesc > cbSector)
     3052    {
     3053        Log(("ISO/UDF: Logical volume descriptor is too big: %#zx (cbSector=%#x)\n", cbDesc, cbSector));
     3054        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_TOO_BIT_PARTMAP_IN_LVD,
     3055                                   "Logical volume descriptor is too big: %#zx (cbSector=%#x)\n", cbDesc, cbSector);
     3056    }
     3057
     3058    PUDFLOGICALVOLUMEDESC pEndianConvert = NULL;
     3059    uint32_t i = pInfo->cLogicalVols;
     3060    while (i--> 0)
     3061        if (   memcmp(pDesc->achLogicalVolumeID, pInfo->apLogicalVols[i]->achLogicalVolumeID,
     3062                      sizeof(pDesc->achLogicalVolumeID)) == 0
     3063            && memcmp(&pDesc->DescCharSet, &pInfo->apLogicalVols[i]->DescCharSet,
     3064                      sizeof(pDesc->DescCharSet)) == 0)
     3065        {
     3066            if (RT_LE2H_U32(pDesc->uVolumeDescSeqNo) >= pInfo->apLogicalVols[i]->uVolumeDescSeqNo)
     3067            {
     3068                Log(("ISO/UDF: Logical descriptor prevails over previous! (%u >= %u)\n",
     3069                     RT_LE2H_U32(pDesc->uVolumeDescSeqNo), pInfo->apLogicalVols[i]->uVolumeDescSeqNo));
     3070                pEndianConvert = (PUDFLOGICALVOLUMEDESC)RTMemDup(pDesc, cbDesc);
     3071                if (!pEndianConvert)
     3072                    return VERR_NO_MEMORY;
     3073                RTMemFree(pInfo->apLogicalVols[i]);
     3074                pInfo->apLogicalVols[i] = pEndianConvert;
     3075            }
     3076            else
     3077                Log(("ISO/UDF: Logical descriptor has lower sequence number than the previous! (%u >= %u)\n",
     3078                     RT_LE2H_U32(pDesc->uVolumeDescSeqNo), pInfo->apLogicalVols[i]->uVolumeDescSeqNo));
     3079            break;
     3080        }
     3081    if (i >= pInfo->cLogicalVols)
     3082    {
     3083        /*
     3084         * It wasn't. Append it.
     3085         */
     3086        i = pInfo->cLogicalVols;
     3087        if (i < RT_ELEMENTS(pInfo->apLogicalVols))
     3088        {
     3089            pInfo->apLogicalVols[i] = pEndianConvert = (PUDFLOGICALVOLUMEDESC)RTMemDup(pDesc, cbDesc);
     3090            if (pEndianConvert)
     3091                pInfo->cLogicalVols = i + 1;
     3092            else
     3093                return VERR_NO_MEMORY;
     3094            Log2(("ISO/UDF: ++New logical volume descriptor.\n"));
     3095        }
     3096        else
     3097            return RTERRINFO_LOG_SET(pErrInfo, VERR_ISOFS_TOO_MANY_LVDS, "Too many logical volume descriptors");
     3098    }
     3099
     3100#ifdef RT_BIG_ENDIAN
     3101    /*
     3102     * Do endian conversion of the descriptor.
     3103     */
     3104    if (pEndianConvert)
     3105    {
     3106        AssertFailed();
     3107    }
     3108#else
     3109    RT_NOREF(pEndianConvert);
     3110#endif
    25053111    return VINF_SUCCESS;
    25063112}
     
    25113117 *
    25123118 * @returns IPRT status code.
    2513  * @param   pThis       The instance.
     3119 * @param   pInfo       Where we gather descriptor information.
    25143120 * @param   pDesc       The descriptor.
    25153121 * @param   pErrInfo    Where to return extended error information.
    25163122 */
    2517 static int rtFsIsoVolProcessUdfPartitionDesc(PRTFSISOVOL pThis, PCUDFPARTITIONDESC pDesc, PRTERRINFO pErrInfo)
     3123static int rtFsIsoVolProcessUdfPartitionDesc(PRTFSISOVDSINFO pInfo, PCUDFPARTITIONDESC pDesc, PRTERRINFO pErrInfo)
    25183124{
    25193125#ifdef LOG_ENABLED
     
    25253131        UDF_LOG2_MEMBER(pDesc, "#06RX16", uPartitionNo);
    25263132        UDF_LOG2_MEMBER_ENTITY_ID(pDesc, PartitionContents);
    2527         if (memcmp(&pDesc->PartitionContents.achIdentifier[0], RT_STR_TUPLE(UDF_ENTITY_ID_PD_PARTITION_CONTENTS_UDF) + 1) == 0)
     3133        if (UDF_ENTITY_ID_EQUALS(&pDesc->PartitionContents, UDF_ENTITY_ID_PD_PARTITION_CONTENTS_UDF))
    25283134        {
    25293135            UDF_LOG2_MEMBER_SHORTAD(&pDesc->ContentsUse, Hdr.UnallocatedSpaceTable);
     
    25493155#endif
    25503156
    2551     RT_NOREF(pThis, pDesc, pErrInfo);
     3157    /*
     3158     * Check if this is a newer revision of an existing primary volume descriptor.
     3159     */
     3160    PUDFPARTITIONDESC pEndianConvert = NULL;
     3161    uint32_t i = pInfo->cPartitions;
     3162    while (i--> 0)
     3163        if (pDesc->uPartitionNo == pInfo->apPartitions[i]->uPartitionNo)
     3164        {
     3165            if (RT_LE2H_U32(pDesc->uVolumeDescSeqNo) >= pInfo->apPartitions[i]->uVolumeDescSeqNo)
     3166            {
     3167                Log(("ISO/UDF: Partition descriptor for part %#u prevails over previous! (%u >= %u)\n",
     3168                     pDesc->uPartitionNo, RT_LE2H_U32(pDesc->uVolumeDescSeqNo), pInfo->apPartitions[i]->uVolumeDescSeqNo));
     3169                pEndianConvert = pInfo->apPartitions[i];
     3170                memcpy(pEndianConvert, pDesc, sizeof(*pDesc));
     3171            }
     3172            else
     3173                Log(("ISO/UDF: Partition descriptor for part %#u has a lower sequence number than the previous! (%u < %u)\n",
     3174                     pDesc->uPartitionNo, RT_LE2H_U32(pDesc->uVolumeDescSeqNo), pInfo->apPartitions[i]->uVolumeDescSeqNo));
     3175            break;
     3176        }
     3177    if (i >= pInfo->cPartitions)
     3178    {
     3179        /*
     3180         * It wasn't. Append it.
     3181         */
     3182        i = pInfo->cPartitions;
     3183        if (i < RT_ELEMENTS(pInfo->apPartitions))
     3184        {
     3185            pInfo->apPartitions[i] = pEndianConvert = (PUDFPARTITIONDESC)RTMemDup(pDesc, sizeof(*pDesc));
     3186            if (pEndianConvert)
     3187                pInfo->cPartitions = i + 1;
     3188            else
     3189                return VERR_NO_MEMORY;
     3190            Log2(("ISO/UDF: ++New partition descriptor.\n"));
     3191        }
     3192        else
     3193            return RTERRINFO_LOG_SET(pErrInfo, VERR_ISOFS_TOO_MANY_PDS, "Too many physical volume descriptors");
     3194    }
     3195
     3196#ifdef RT_BIG_ENDIAN
     3197    /*
     3198     * Do endian conversion of the descriptor.
     3199     */
     3200    if (pEndianConvert)
     3201    {
     3202        AssertFailed();
     3203    }
     3204#else
     3205    RT_NOREF(pEndianConvert);
     3206#endif
    25523207    return VINF_SUCCESS;
    25533208}
     
    25583213 *
    25593214 * @returns IPRT status code.
    2560  * @param   pThis       The instance.
     3215 * @param   pInfo       Where we gather descriptor information.
    25613216 * @param   pDesc       The descriptor.
    25623217 * @param   pErrInfo    Where to return extended error information.
    25633218 */
    2564 static int rtFsIsoVolProcessUdfImplUseVolDesc(PRTFSISOVOL pThis, PCUDFIMPLEMENTATIONUSEVOLUMEDESC pDesc, PRTERRINFO pErrInfo)
     3219static int rtFsIsoVolProcessUdfImplUseVolDesc(PRTFSISOVDSINFO pInfo, PCUDFIMPLEMENTATIONUSEVOLUMEDESC pDesc, PRTERRINFO pErrInfo)
    25653220{
    25663221#ifdef LOG_ENABLED
     
    25703225        UDF_LOG2_MEMBER(pDesc, "#010RX32", uVolumeDescSeqNo);
    25713226        UDF_LOG2_MEMBER_ENTITY_ID(pDesc, idImplementation);
    2572         if (memcmp(pDesc->idImplementation.achIdentifier, RT_STR_TUPLE(UDF_ENTITY_ID_IUVD_IMPLEMENTATION) + 1) == 0)
     3227        if (UDF_ENTITY_ID_EQUALS(&pDesc->idImplementation, UDF_ENTITY_ID_IUVD_IMPLEMENTATION))
    25733228        {
    25743229            UDF_LOG2_MEMBER_CHARSPEC(&pDesc->ImplementationUse, Lvi.Charset);
     
    25863241#endif
    25873242
    2588     RT_NOREF(pThis, pDesc, pErrInfo);
     3243    RT_NOREF(pInfo, pDesc, pErrInfo);
    25893244    return VINF_SUCCESS;
    25903245}
     
    26063261
    26073262
     3263
    26083264/**
    26093265 * Process a VDS sequence, recursively dealing with volume descriptor pointers.
     3266 *
     3267 * This function only gathers information from the sequence, handling the
     3268 * prevailing descriptor fun.
    26103269 *
    26113270 * @returns IPRT status code.
    26123271 * @param   pThis           The instance.
     3272 * @param   pInfo           Where to store info from the VDS sequence.
    26133273 * @param   offSeq          The byte offset of the sequence.
    26143274 * @param   cbSeq           The length of the sequence.
     
    26193279 * @param   pErrInfo        Where to return extended error info.
    26203280 */
    2621 static int rtFsIsoVolReadAndProcessUdfVdsSeq(PRTFSISOVOL pThis, uint64_t offSeq, uint32_t cbSeq, uint8_t *pbBuf, size_t cbBuf,
    2622                                              uint32_t cNestings, PRTERRINFO pErrInfo)
     3281static int rtFsIsoVolReadAndProcessUdfVdsSeq(PRTFSISOVOL pThis, PRTFSISOVDSINFO pInfo, uint64_t offSeq, uint32_t cbSeq,
     3282                                             uint8_t *pbBuf, size_t cbBuf, uint32_t cNestings, PRTERRINFO pErrInfo)
    26233283{
    26243284    AssertReturn(cbBuf >= pThis->cbSector, VERR_INTERNAL_ERROR);
     
    26283288     */
    26293289    if (cNestings > 5)
    2630         return RTErrInfoSet(pErrInfo, VERR_TOO_MUCH_DATA, "The volume descriptor sequence (VDS) is nested too deeply.");
     3290        return RTERRINFO_LOG_SET(pErrInfo, VERR_TOO_MUCH_DATA, "The volume descriptor sequence (VDS) is nested too deeply.");
    26313291
    26323292
     
    26453305        rc = RTVfsFileReadAt(pThis->hVfsBacking, offSeq + offInSeq, pbBuf, pThis->cbSector, NULL);
    26463306        if (RT_FAILURE(rc))
    2647             return RTErrInfoSetF(pErrInfo, rc, "Error reading VDS content at %RX64 (LB %#x): %Rrc",
    2648                                  offSeq + offInSeq, pThis->cbSector, rc);
     3307            return RTERRINFO_LOG_SET_F(pErrInfo, rc, "Error reading VDS content at %RX64 (LB %#x): %Rrc",
     3308                                       offSeq + offInSeq, pThis->cbSector, rc);
    26493309        if (cbSeq - offInSeq < pThis->cbSector)
    26503310            memset(&pbBuf[cbSeq - offInSeq], 0, pThis->cbSector - (cbSeq - offInSeq));
     
    26673327            {
    26683328                case UDF_TAG_ID_PRIMARY_VOL_DESC:
    2669                     rc = rtFsIsoVolProcessUdfPrimaryVolDesc(pThis, (PCUDFPRIMARYVOLUMEDESC)pTag, pErrInfo);
     3329                    rc = rtFsIsoVolProcessUdfPrimaryVolDesc(pInfo, (PCUDFPRIMARYVOLUMEDESC)pTag, pErrInfo);
    26703330                    break;
    26713331
    26723332                case UDF_TAG_ID_IMPLEMENTATION_USE_VOLUME_DESC:
    2673                     rc = rtFsIsoVolProcessUdfImplUseVolDesc(pThis, (PCUDFIMPLEMENTATIONUSEVOLUMEDESC)pTag, pErrInfo);
     3333                    rc = rtFsIsoVolProcessUdfImplUseVolDesc(pInfo, (PCUDFIMPLEMENTATIONUSEVOLUMEDESC)pTag, pErrInfo);
    26743334                    break;
    26753335
    26763336                case UDF_TAG_ID_PARTITION_DESC:
    2677                     rc = rtFsIsoVolProcessUdfPartitionDesc(pThis, (PCUDFPARTITIONDESC)pTag, pErrInfo);
     3337                    rc = rtFsIsoVolProcessUdfPartitionDesc(pInfo, (PCUDFPARTITIONDESC)pTag, pErrInfo);
    26783338                    break;
    26793339
    26803340                case UDF_TAG_ID_LOGICAL_VOLUME_DESC:
    2681                     rc = rtFsIsoVolProcessUdfLogicalVolumeDesc(pThis, (PCUDFLOGICALVOLUMEDESC)pTag, pErrInfo);
     3341                    if (rc != VERR_ISOFS_INSUFFICIENT_DATA_FOR_DESC_CRC)
     3342                        rc = rtFsIsoVolProcessUdfLogicalVolumeDesc(pInfo, (PCUDFLOGICALVOLUMEDESC)pTag,
     3343                                                                   pThis->cbSector, pErrInfo);
     3344                    else
     3345                        rc = VERR_ISOFS_TOO_BIT_PARTMAP_IN_LVD;
    26823346                    break;
    26833347
     
    27033367                         offSeq + offInSeq, pVdp->NextVolumeDescSeq.off, pVdp->NextVolumeDescSeq.cb,
    27043368                         pVdp->uVolumeDescSeqNo, cNestings));
    2705                     rc = rtFsIsoVolReadAndProcessUdfVdsSeq(pThis, (uint64_t)pVdp->NextVolumeDescSeq.off * pThis->cbSector,
     3369                    rc = rtFsIsoVolReadAndProcessUdfVdsSeq(pThis, pInfo, (uint64_t)pVdp->NextVolumeDescSeq.off * pThis->cbSector,
    27063370                                                           pVdp->NextVolumeDescSeq.cb, pbBuf, cbBuf, cNestings + 1, pErrInfo);
    27073371                    break;
     
    27133377
    27143378                default:
    2715                     return RTErrInfoSetF(pErrInfo, VERR_ISOFS_UNEXPECTED_VDS_DESC,
    2716                                          "Unexpected/unknown VDS descriptor %#x at byte offset %#RX64",
    2717                                          pThis->cbSector, offSeq + offInSeq);
     3379                    return RTERRINFO_LOG_SET_F(pErrInfo, VERR_ISOFS_UNEXPECTED_VDS_DESC,
     3380                                               "Unexpected/unknown VDS descriptor %#x at byte offset %#RX64",
     3381                                               pThis->cbSector, offSeq + offInSeq);
    27183382            }
     3383            if (RT_FAILURE(rc))
     3384                return rc;
    27193385        }
    27203386        /* The descriptor sequence is usually zero padded to 16 sectors.  Just
     
    27713437
    27723438    /*
    2773      * Reset the state before we start processing the descriptors.
     3439     * Gather relevant descriptor info from the VDS then process it and on
     3440     * success copy it into the instance.
    27743441     *
    27753442     * The processing has to be done in a different function because there may
     
    27773444     * recursing and check that we don't go to deep.
    27783445     */
    2779 
    2780     /** @todo state reset */
    2781 
    2782     return rtFsIsoVolReadAndProcessUdfVdsSeq(pThis, offSeq, cbSeq, pbBuf, cbBuf, 0, pErrInfo);
     3446    RTFSISOVDSINFO Info;
     3447    RT_ZERO(Info);
     3448    int rc = rtFsIsoVolReadAndProcessUdfVdsSeq(pThis, &Info, offSeq, cbSeq, pbBuf, cbBuf, 0, pErrInfo);
     3449    if (RT_SUCCESS(rc))
     3450    {
     3451        rc = rtFsIsoVolProcessUdfVdsSeqInfo(pThis, &Info, pErrInfo);
     3452        if (RT_SUCCESS(rc))
     3453            rc = rtFsIsoVolProcessUdfFileSetDescs(pThis, pbBuf, cbBuf, pErrInfo);
     3454    }
     3455
     3456    /*
     3457     * Clean up info.
     3458     */
     3459    i = Info.cPrimaryVols;
     3460    while (i-- > 0)
     3461        RTMemFree(Info.apPrimaryVols[i]);
     3462
     3463    i = Info.cLogicalVols;
     3464    while (i-- > 0)
     3465        RTMemFree(Info.apLogicalVols[i]);
     3466
     3467    i = Info.cPartitions;
     3468    while (i-- > 0)
     3469        RTMemFree(Info.apPartitions[i]);
     3470
     3471    RTMemFree(Info.paPartMaps);
     3472
     3473    return rc;
    27833474}
    27843475
     
    28173508            }
    28183509            else
    2819                 rc = RTErrInfoSetF(pErrInfo, VERR_NOT_FOUND,
    2820                                    "MainVolumeDescSeq is out of bounds: sector %#RX32 LB %#RX32 bytes, image is %#RX64 sectors",
    2821                                    pAvdp->MainVolumeDescSeq.off, pAvdp->MainVolumeDescSeq.cb, pThis->cBackingSectors);
     3510                rc = RTERRINFO_LOG_SET_F(pErrInfo, VERR_NOT_FOUND,
     3511                                         "MainVolumeDescSeq is out of bounds: sector %#RX32 LB %#RX32 bytes, image is %#RX64 sectors",
     3512                                         pAvdp->MainVolumeDescSeq.off, pAvdp->MainVolumeDescSeq.cb, pThis->cBackingSectors);
    28223513            if (ReserveVolumeDescSeq.cb > 0)
    28233514            {
     
    28333524                }
    28343525                else if (RT_SUCCESS(rc))
    2835                     rc = RTErrInfoSetF(pErrInfo, VERR_NOT_FOUND,
    2836                                        "ReserveVolumeDescSeq is out of bounds: sector %#RX32 LB %#RX32 bytes, image is %#RX64 sectors",
    2837                                        ReserveVolumeDescSeq.off, ReserveVolumeDescSeq.cb, pThis->cBackingSectors);
     3526                    rc = RTERRINFO_LOG_SET_F(pErrInfo, VERR_NOT_FOUND,
     3527                                             "ReserveVolumeDescSeq is out of bounds: sector %#RX32 LB %#RX32 bytes, image is %#RX64 sectors",
     3528                                             ReserveVolumeDescSeq.off, ReserveVolumeDescSeq.cb, pThis->cBackingSectors);
    28383529            }
    28393530        }
    28403531    }
    28413532    else
    2842         rc = RTErrInfoSetF(pErrInfo, rc,
    2843                            "Error reading sector at offset %#RX64 (anchor volume descriptor pointer): %Rrc", offAvdp, rc);
     3533        rc = RTERRINFO_LOG_SET_F(pErrInfo, rc,
     3534                                 "Error reading sector at offset %#RX64 (anchor volume descriptor pointer): %Rrc", offAvdp, rc);
    28443535
    28453536    return rc;
     
    28783569     * again when alternative AVDP sectors points to the same sequences.
    28793570     */
     3571    pThis->Udf.uLevel = *puUdfLevel;
    28803572    RTFSISOSEENSEQENCES SeenSequences = { 0 };
    2881     int rc = rtFsIsoVolReadAndHandleUdfAvdp(pThis, 256 * pThis->cbSector, pbBuf, cbBuf,
    2882                                             &SeenSequences, pErrInfo);
    2883     if (RT_FAILURE(rc))
    2884         rc = rtFsIsoVolReadAndHandleUdfAvdp(pThis,  pThis->cbBacking - 256 * pThis->cbSector,
    2885                                             pbBuf, cbBuf, &SeenSequences, pErrInfo);
    2886     if (RT_FAILURE(rc))
    2887         rc = rtFsIsoVolReadAndHandleUdfAvdp(pThis,  pThis->cbBacking - pThis->cbSector,
    2888                                             pbBuf, cbBuf, &SeenSequences, pErrInfo);
    2889     if (RT_SUCCESS(rc))
    2890         return rc;
    2891     *puUdfLevel = 0;
     3573    int rc1 = rtFsIsoVolReadAndHandleUdfAvdp(pThis, 256 * pThis->cbSector, pbBuf, cbBuf,
     3574                                             &SeenSequences, pErrInfo);
     3575    if (RT_SUCCESS(rc1))
     3576        return rc1;
     3577
     3578    int rc2 = rtFsIsoVolReadAndHandleUdfAvdp(pThis,  pThis->cbBacking - 256 * pThis->cbSector,
     3579                                             pbBuf, cbBuf, &SeenSequences, pErrInfo);
     3580    if (RT_SUCCESS(rc2))
     3581        return rc2;
     3582
     3583    int rc3 = rtFsIsoVolReadAndHandleUdfAvdp(pThis,  pThis->cbBacking - pThis->cbSector,
     3584                                             pbBuf, cbBuf, &SeenSequences, pErrInfo);
     3585    if (RT_SUCCESS(rc3))
     3586        return rc3;
     3587
     3588    /*
     3589     * Return failure if the alternatives have been excluded.
     3590     *
     3591     * Note! The error info won't be correct here.
     3592     */
     3593    pThis->Udf.uLevel = *puUdfLevel = 0;
     3594
     3595    if (RTFSISO9660_F_IS_ONLY_TYPE(pThis->fFlags, RTFSISO9660_F_NO_UDF))
     3596        return rc1 != VERR_NOT_FOUND ? rc1 : rc2 != VERR_NOT_FOUND ? rc2 : rc3;
    28923597    return VINF_SUCCESS;
    28933598}
     
    31243829{
    31253830    if (pRootDir->cbDirRec < RT_OFFSETOF(ISO9660DIRREC, achFileId))
    3126         return RTErrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Root dir record size is too small: %#x (min %#x)",
    3127                              pRootDir->cbDirRec, RT_OFFSETOF(ISO9660DIRREC, achFileId));
     3831        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Root dir record size is too small: %#x (min %#x)",
     3832                                   pRootDir->cbDirRec, RT_OFFSETOF(ISO9660DIRREC, achFileId));
    31283833
    31293834    if (!(pRootDir->fFileFlags & ISO9660_FILE_FLAGS_DIRECTORY))
    3130         return RTErrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT,
    3131                              "Root dir is not flagged as directory: %#x", pRootDir->fFileFlags);
     3835        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT,
     3836                                   "Root dir is not flagged as directory: %#x", pRootDir->fFileFlags);
    31323837    if (pRootDir->fFileFlags & ISO9660_FILE_FLAGS_MULTI_EXTENT)
    3133         return RTErrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT,
    3134                              "Root dir is cannot be multi-extent: %#x", pRootDir->fFileFlags);
     3838        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT,
     3839                                   "Root dir is cannot be multi-extent: %#x", pRootDir->fFileFlags);
    31353840
    31363841    if (RT_LE2H_U32(pRootDir->cbData.le) != RT_BE2H_U32(pRootDir->cbData.be))
    3137         return RTErrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid root dir size: {%#RX32,%#RX32}",
    3138                              RT_BE2H_U32(pRootDir->cbData.be), RT_LE2H_U32(pRootDir->cbData.le));
     3842        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid root dir size: {%#RX32,%#RX32}",
     3843                                   RT_BE2H_U32(pRootDir->cbData.be), RT_LE2H_U32(pRootDir->cbData.le));
    31393844    if (RT_LE2H_U32(pRootDir->cbData.le) == 0)
    3140         return RTErrInfoSet(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Zero sized root dir");
     3845        return RTERRINFO_LOG_SET(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Zero sized root dir");
    31413846
    31423847    if (RT_LE2H_U32(pRootDir->offExtent.le) != RT_BE2H_U32(pRootDir->offExtent.be))
    3143         return RTErrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid root dir extent: {%#RX32,%#RX32}",
    3144                              RT_BE2H_U32(pRootDir->offExtent.be), RT_LE2H_U32(pRootDir->offExtent.le));
     3848        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid root dir extent: {%#RX32,%#RX32}",
     3849                                   RT_BE2H_U32(pRootDir->offExtent.be), RT_LE2H_U32(pRootDir->offExtent.le));
    31453850
    31463851    if (RT_LE2H_U16(pRootDir->VolumeSeqNo.le) != RT_BE2H_U16(pRootDir->VolumeSeqNo.be))
    3147         return RTErrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid root dir volume sequence ID: {%#RX16,%#RX16}",
    3148                              RT_BE2H_U16(pRootDir->VolumeSeqNo.be), RT_LE2H_U16(pRootDir->VolumeSeqNo.le));
     3852        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid root dir volume sequence ID: {%#RX16,%#RX16}",
     3853                                   RT_BE2H_U16(pRootDir->VolumeSeqNo.be), RT_LE2H_U16(pRootDir->VolumeSeqNo.le));
    31493854    if (RT_LE2H_U16(pRootDir->VolumeSeqNo.le) != pThis->idPrimaryVol)
    3150         return RTErrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
    3151                              "Expected root dir to have same volume sequence number as primary volume: %#x, expected %#x",
    3152                              RT_LE2H_U16(pRootDir->VolumeSeqNo.le), pThis->idPrimaryVol);
     3855        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
     3856                                   "Expected root dir to have same volume sequence number as primary volume: %#x, expected %#x",
     3857                                   RT_LE2H_U16(pRootDir->VolumeSeqNo.le), pThis->idPrimaryVol);
    31533858
    31543859    /*
     
    31753880{
    31763881    if (pVolDesc->bFileStructureVersion != ISO9660_FILE_STRUCTURE_VERSION)
    3177         return RTErrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
    3178                              "Unsupported file structure version: %#x", pVolDesc->bFileStructureVersion);
     3882        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
     3883                                   "Unsupported file structure version: %#x", pVolDesc->bFileStructureVersion);
    31793884
    31803885    /*
     
    31853890        || !RT_IS_POWER_OF_TWO(pThis->cbBlock)
    31863891        || pThis->cbBlock / pThis->cbSector < 1)
    3187         return RTErrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid logical block size: {%#RX16,%#RX16}",
    3188                              RT_BE2H_U16(pVolDesc->cbLogicalBlock.be), RT_LE2H_U16(pVolDesc->cbLogicalBlock.le));
     3892        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid logical block size: {%#RX16,%#RX16}",
     3893                                   RT_BE2H_U16(pVolDesc->cbLogicalBlock.be), RT_LE2H_U16(pVolDesc->cbLogicalBlock.le));
    31893894    if (pThis->cbBlock / pThis->cbSector > 128)
    3190         return RTErrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, "Unsupported block size: %#x\n", pThis->cbBlock);
     3895        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, "Unsupported block size: %#x\n", pThis->cbBlock);
    31913896
    31923897    /*
     
    31953900    pThis->cBlocksInPrimaryVolumeSpace = RT_LE2H_U32(pVolDesc->VolumeSpaceSize.le);
    31963901    if (pThis->cBlocksInPrimaryVolumeSpace != RT_BE2H_U32(pVolDesc->VolumeSpaceSize.be))
    3197         return RTErrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid volume space size: {%#RX32,%#RX32}",
    3198                              RT_BE2H_U32(pVolDesc->VolumeSpaceSize.be), RT_LE2H_U32(pVolDesc->VolumeSpaceSize.le));
     3902        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid volume space size: {%#RX32,%#RX32}",
     3903                                   RT_BE2H_U32(pVolDesc->VolumeSpaceSize.be), RT_LE2H_U32(pVolDesc->VolumeSpaceSize.le));
    31993904    pThis->cbPrimaryVolumeSpace = pThis->cBlocksInPrimaryVolumeSpace * (uint64_t)pThis->cbBlock;
    32003905
     
    32053910    if (   pThis->cVolumesInSet != RT_BE2H_U16(pVolDesc->cVolumesInSet.be)
    32063911        || pThis->cVolumesInSet == 0)
    3207         return RTErrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid volume set size: {%#RX16,%#RX16}",
    3208                              RT_BE2H_U16(pVolDesc->cVolumesInSet.be), RT_LE2H_U16(pVolDesc->cVolumesInSet.le));
     3912        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid volume set size: {%#RX16,%#RX16}",
     3913                                   RT_BE2H_U16(pVolDesc->cVolumesInSet.be), RT_LE2H_U16(pVolDesc->cVolumesInSet.le));
    32093914    if (pThis->cVolumesInSet > 32)
    3210         return RTErrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, "Too large volume set size: %#x\n", pThis->cVolumesInSet);
     3915        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, "Too large volume set size: %#x\n", pThis->cVolumesInSet);
    32113916
    32123917    /*
     
    32153920    pThis->idPrimaryVol = RT_LE2H_U16(pVolDesc->VolumeSeqNo.le);
    32163921    if (pThis->idPrimaryVol != RT_BE2H_U16(pVolDesc->VolumeSeqNo.be))
    3217         return RTErrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid volume sequence ID: {%#RX16,%#RX16}",
    3218                              RT_BE2H_U16(pVolDesc->VolumeSeqNo.be), RT_LE2H_U16(pVolDesc->VolumeSeqNo.le));
     3922        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Invalid volume sequence ID: {%#RX16,%#RX16}",
     3923                                   RT_BE2H_U16(pVolDesc->VolumeSeqNo.be), RT_LE2H_U16(pVolDesc->VolumeSeqNo.le));
    32193924    if (   pThis->idPrimaryVol > pThis->cVolumesInSet
    32203925        || pThis->idPrimaryVol < 1)
    3221         return RTErrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
    3222                              "Volume sequence ID out of of bound: %#x (1..%#x)\n", pThis->idPrimaryVol, pThis->cVolumesInSet);
     3926        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
     3927                                   "Volume sequence ID out of of bound: %#x (1..%#x)\n", pThis->idPrimaryVol, pThis->cVolumesInSet);
    32233928
    32243929    /*
     
    32493954{
    32503955    if (pVolDesc->bFileStructureVersion != ISO9660_FILE_STRUCTURE_VERSION)
    3251         return RTErrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
    3252                              "Unsupported file structure version: %#x", pVolDesc->bFileStructureVersion);
     3956        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
     3957                                   "Unsupported file structure version: %#x", pVolDesc->bFileStructureVersion);
    32533958
    32543959    /*
     
    32743979     */
    32753980    if (pThis->cbBlock == 0)
    3276         return RTErrInfoSet(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
    3277                             "Supplementary joliet volume descriptor is not supported when appearing before the primary volume descriptor");
     3981        return RTERRINFO_LOG_SET(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
     3982                                 "Supplementary joliet volume descriptor is not supported when appearing before the primary volume descriptor");
    32783983    if (ISO9660_GET_ENDIAN(&pVolDesc->cbLogicalBlock) != pThis->cbBlock)
    3279         return RTErrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
    3280                              "Logical block size for joliet volume descriptor differs from primary: %#RX16 vs %#RX16\n",
    3281                              ISO9660_GET_ENDIAN(&pVolDesc->cbLogicalBlock), pThis->cbBlock);
     3984        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
     3985                                   "Logical block size for joliet volume descriptor differs from primary: %#RX16 vs %#RX16\n",
     3986                                   ISO9660_GET_ENDIAN(&pVolDesc->cbLogicalBlock), pThis->cbBlock);
    32823987    if (ISO9660_GET_ENDIAN(&pVolDesc->VolumeSpaceSize) != pThis->cBlocksInPrimaryVolumeSpace)
    3283         return RTErrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
    3284                              "Volume space size for joliet volume descriptor differs from primary: %#RX32 vs %#RX32\n",
    3285                              ISO9660_GET_ENDIAN(&pVolDesc->VolumeSpaceSize), pThis->cBlocksInPrimaryVolumeSpace);
     3988        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
     3989                                   "Volume space size for joliet volume descriptor differs from primary: %#RX32 vs %#RX32\n",
     3990                                   ISO9660_GET_ENDIAN(&pVolDesc->VolumeSpaceSize), pThis->cBlocksInPrimaryVolumeSpace);
    32863991    if (ISO9660_GET_ENDIAN(&pVolDesc->cVolumesInSet) != pThis->cVolumesInSet)
    3287         return RTErrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
    3288                              "Volume set size for joliet volume descriptor differs from primary: %#RX16 vs %#RX32\n",
    3289                              ISO9660_GET_ENDIAN(&pVolDesc->cVolumesInSet), pThis->cVolumesInSet);
     3992        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
     3993                                   "Volume set size for joliet volume descriptor differs from primary: %#RX16 vs %#RX32\n",
     3994                                   ISO9660_GET_ENDIAN(&pVolDesc->cVolumesInSet), pThis->cVolumesInSet);
    32903995    if (ISO9660_GET_ENDIAN(&pVolDesc->VolumeSeqNo) != pThis->idPrimaryVol)
    3291         return RTErrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
    3292                              "Volume sequence ID for joliet volume descriptor differs from primary: %#RX16 vs %#RX32\n",
    3293                              ISO9660_GET_ENDIAN(&pVolDesc->VolumeSeqNo), pThis->idPrimaryVol);
     3996        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
     3997                                   "Volume sequence ID for joliet volume descriptor differs from primary: %#RX16 vs %#RX32\n",
     3998                                   ISO9660_GET_ENDIAN(&pVolDesc->VolumeSeqNo), pThis->idPrimaryVol);
    32943999
    32954000    if (*pbUcs2Level != 0)
    3296         return RTErrInfoSet(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, "More than one supplementary joliet volume descriptor");
     4001        return RTERRINFO_LOG_SET(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, "More than one supplementary joliet volume descriptor");
    32974002
    32984003    /*
     
    33954100    {
    33964101        if (iVolDesc > 32)
    3397             return RTErrInfoSet(pErrInfo, VERR_VFS_BOGUS_FORMAT, "More than 32 volume descriptors, doesn't seem right...");
     4102            return RTERRINFO_LOG_SET(pErrInfo, VERR_VFS_BOGUS_FORMAT, "More than 32 volume descriptors, doesn't seem right...");
    33984103
    33994104        /* Read the next one and check the signature. */
    34004105        rc = RTVfsFileReadAt(hVfsBacking, offVolDesc, &Buf, cbSector, NULL);
    34014106        if (RT_FAILURE(rc))
    3402             return RTErrInfoSetF(pErrInfo, rc, "Unable to read volume descriptor #%u", iVolDesc);
     4107            return RTERRINFO_LOG_SET_F(pErrInfo, rc, "Unable to read volume descriptor #%u", iVolDesc);
    34034108
    34044109#define MATCH_STD_ID(a_achStdId1, a_szStdId2) \
     
    34294134                cPrimaryVolDescs++;
    34304135                if (Buf.VolDescHdr.bDescVersion != ISO9660PRIMARYVOLDESC_VERSION)
    3431                     return RTErrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
    3432                                          "Unsupported primary volume descriptor version: %#x", Buf.VolDescHdr.bDescVersion);
     4136                    return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
     4137                                               "Unsupported primary volume descriptor version: %#x", Buf.VolDescHdr.bDescVersion);
    34334138#ifdef LOG_ENABLED
    34344139                rtFsIsoVolLogPrimarySupplementaryVolDesc(&Buf.SupVolDesc);
    34354140#endif
    34364141                if (cPrimaryVolDescs > 1)
    3437                     return RTErrInfoSet(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, "More than one primary volume descriptor");
     4142                    return RTERRINFO_LOG_SET(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, "More than one primary volume descriptor");
    34384143                rc = rtFsIsoVolHandlePrimaryVolDesc(pThis, &Buf.PrimaryVolDesc, offVolDesc, &RootDir, &offRootDirRec, pErrInfo);
    34394144            }
     
    34424147                cSupplementaryVolDescs++;
    34434148                if (Buf.VolDescHdr.bDescVersion != ISO9660SUPVOLDESC_VERSION)
    3444                     return RTErrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
    3445                                          "Unsupported supplemental volume descriptor version: %#x", Buf.VolDescHdr.bDescVersion);
     4149                    return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
     4150                                               "Unsupported supplemental volume descriptor version: %#x", Buf.VolDescHdr.bDescVersion);
    34464151#ifdef LOG_ENABLED
    34474152                rtFsIsoVolLogPrimarySupplementaryVolDesc(&Buf.SupVolDesc);
     
    34574162            {
    34584163                if (!cPrimaryVolDescs)
    3459                     return RTErrInfoSet(pErrInfo, VERR_VFS_BOGUS_FORMAT, "No primary volume descriptor");
     4164                    return RTERRINFO_LOG_SET(pErrInfo, VERR_VFS_BOGUS_FORMAT, "No primary volume descriptor");
    34604165                enmState = kStateNoSeq;
    34614166            }
    34624167            else
    3463                 return RTErrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
    3464                                      "Unknown volume descriptor: %#x", Buf.VolDescHdr.bDescType);
     4168                return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
     4169                                           "Unknown volume descriptor: %#x", Buf.VolDescHdr.bDescType);
    34654170        }
    34664171        /*
     
    34744179                enmState = kStateUdfSeq;
    34754180            else
    3476                 return RTErrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Only one BEA01 sequence is supported");
     4181                return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Only one BEA01 sequence is supported");
    34774182        }
    34784183        else if (   enmState == kStateUdfSeq
     
    34884193                offUdfBootVolDesc = iVolDesc * cbSector;
    34894194            else
    3490                 return RTErrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Only one BOOT2 descriptor is supported");
     4195                return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Only one BOOT2 descriptor is supported");
    34914196        }
    34924197        else if (   enmState == kStateUdfSeq
     
    34964201                enmState = kStateNoSeq;
    34974202            else
    3498                 return RTErrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Found BEA01 & TEA01, but no NSR02 or NSR03 descriptors");
     4203                return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Found BEA01 & TEA01, but no NSR02 or NSR03 descriptors");
    34994204        }
    35004205        /*
     
    35044209            break;
    35054210        else if (enmState == kStateStart)
    3506                 return RTErrInfoSetF(pErrInfo, VERR_VFS_UNKNOWN_FORMAT,
    3507                                      "Not ISO? Unable to recognize volume descriptor signature: %.5Rhxs", Buf.VolDescHdr.achStdId);
     4211                return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNKNOWN_FORMAT,
     4212                                           "Not ISO? Unable to recognize volume descriptor signature: %.5Rhxs", Buf.VolDescHdr.achStdId);
    35084213        else if (enmState == kStateCdSeq)
    3509             return RTErrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT,
    3510                                  "Missing ISO 9660 terminator volume descriptor? (Found %.5Rhxs)", Buf.VolDescHdr.achStdId);
     4214            return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT,
     4215                                       "Missing ISO 9660 terminator volume descriptor? (Found %.5Rhxs)", Buf.VolDescHdr.achStdId);
    35114216        else if (enmState == kStateUdfSeq)
    3512             return RTErrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT,
    3513                                  "Missing UDF terminator volume descriptor? (Found %.5Rhxs)", Buf.VolDescHdr.achStdId);
     4217            return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_BOGUS_FORMAT,
     4218                                       "Missing UDF terminator volume descriptor? (Found %.5Rhxs)", Buf.VolDescHdr.achStdId);
    35144219        else
    3515             return RTErrInfoSetF(pErrInfo, VERR_VFS_UNKNOWN_FORMAT,
    3516                                  "Unknown volume descriptor signature found at sector %u: %.5Rhxs",
    3517                                  16 + iVolDesc, Buf.VolDescHdr.achStdId);
     4220            return RTERRINFO_LOG_SET_F(pErrInfo, VERR_VFS_UNKNOWN_FORMAT,
     4221                                       "Unknown volume descriptor signature found at sector %u: %.5Rhxs",
     4222                                       16 + iVolDesc, Buf.VolDescHdr.achStdId);
    35184223        if (RT_FAILURE(rc))
    35194224            return rc;
     
    35234228     * If we found a UDF VRS and are interested in UDF, we have more work to do here.
    35244229     */
    3525     if (uUdfLevel > 0 && !(fFlags & RTFSISO9660_F_NO_UDF) && /* Just disable this code for now: */ (fFlags & RT_BIT(24)))
     4230#if 0
     4231    if (uUdfLevel > 0 && !(fFlags & RTFSISO9660_F_NO_UDF) )// && /* Just disable this code for now: */ (fFlags & RT_BIT(24)))
    35264232    {
    35274233        Log(("rtFsIsoVolTryInit: uUdfLevel=%d\n", uUdfLevel));
     
    35304236            return rc;
    35314237    }
    3532 #if 0
    3533     return VERR_NOT_IMPLEMENTED;
     4238
     4239    /*
     4240     * Decide which to prefer.
     4241     *
     4242     * By default we pick UDF over any of the two ISO 9960, there is currently
     4243     * no way to override this without using the RTFSISO9660_F_NO_XXX options.
     4244     *
     4245     * If there isn't UDF, we may faced with choosing between joliet and rock
     4246     * ridge.  The joliet option is generally favorable as we don't have to
     4247     * guess wrt to the file name encoding.  So, we'll pick that for now.
     4248     *
     4249     * Note! Should we change this preference for joliet, there fun wrt making sure
     4250     *       there really is rock ridge stuff in the primary volume as well as
     4251     *       making sure there really is anything of value in the primary volume.
     4252     */
     4253    if (uUdfLevel > 0)
     4254    {
     4255        pThis->enmType = RTFSISOVOLTYPE_UDF;
     4256        //return rtFsIsoDirShrd_NewUdf(pThis, xxx);
     4257        return VERR_NOT_IMPLEMENTED;
     4258    }
    35344259#else
     4260    if (uUdfLevel > 0 && !(fFlags & RTFSISO9660_F_NO_UDF) && /* Just disable this code for now: */ (fFlags & RT_BIT(24)))
     4261        rc = rtFsIsoVolHandleUdfDetection(pThis, &uUdfLevel, offUdfBootVolDesc, Buf.ab, sizeof(Buf), pErrInfo);
    35354262
    35364263    /*
     
    35444271     *       making sure there really is anything of value in the primary volume.
    35454272     */
     4273#endif
    35464274    if (bJolietUcs2Level != 0)
    35474275    {
     4276        pThis->enmType = RTFSISOVOLTYPE_JOLIET;
    35484277        pThis->fIsUtf16 = true;
    35494278        return rtFsIsoDirShrd_New9660(pThis, NULL, &JolietRootDir, 1, offJolietRootDirRec, &pThis->pRootDir);
    35504279    }
     4280    pThis->enmType = RTFSISOVOLTYPE_ISO9960;
    35514281    return rtFsIsoDirShrd_New9660(pThis, NULL, &RootDir, 1, offRootDirRec, &pThis->pRootDir);
    3552 #endif
    35534282}
    35544283
     
    36344363                {
    36354364                    *poffError = pElement->paArgs[iArg].offSpec;
    3636                     return RTErrInfoSet(pErrInfo, VERR_VFS_CHAIN_INVALID_ARGUMENT, "Only knows: 'nojoliet' and 'norock'");
     4365                    return RTERRINFO_LOG_SET(pErrInfo, VERR_VFS_CHAIN_INVALID_ARGUMENT, "Only knows: 'nojoliet' and 'norock'");
    36374366                }
    36384367            }
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