VirtualBox

Changeset 68509 in vbox


Ignore:
Timestamp:
Aug 22, 2017 2:45:13 PM (7 years ago)
Author:
vboxsync
Message:

isovfs.cpp: Started on UDF recognition sequence.

Location:
trunk
Files:
2 edited

Legend:

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

    r66735 r68509  
    121121/** @name RTFSISO9660_F_XXX - ISO 9660 mount flags.
    122122 * @{ */
     123/** Do not use the UDF part if present. */
     124#define RTFSISO9660_F_NO_UDF        RT_BIT_32(0)
    123125/** Do not use the joliet part. */
    124 #define RTFSISO9660_F_NO_JOLIET     RT_BIT_32(0)
     126#define RTFSISO9660_F_NO_JOLIET     RT_BIT_32(1)
    125127/** Do not use the rock ridge extensions if present. */
    126 #define RTFSISO9660_F_NO_ROCK       RT_BIT_32(0)
     128#define RTFSISO9660_F_NO_ROCK       RT_BIT_32(2)
    127129/** Valid ISO 9660 mount option mask.   */
    128 #define RTFSISO9660_F_VALID_MASK    UINT32_C(0x00000003)
     130#define RTFSISO9660_F_VALID_MASK    UINT32_C(0x00000007)
    129131/** @}  */
    130132
  • trunk/src/VBox/Runtime/common/fs/isovfs.cpp

    r68345 r68509  
    4646#include <iprt/vfslowlevel.h>
    4747#include <iprt/formats/iso9660.h>
     48#include <iprt/formats/udf.h>
    4849
    4950
     
    189190    /** The sector size (in bytes). */
    190191    uint32_t                cbSector;
     192
     193    /** @name ISO 9660 specific data
     194     *  @{ */
    191195    /** The size of a logical block in bytes. */
    192196    uint32_t                cbBlock;
     
    201205    /** Set if using UTF16-2 (joliet). */
    202206    bool                    fIsUtf16;
     207    /** @} */
    203208
    204209    /** The root directory shared data. */
     
    25562561    RT_ZERO(JolietRootDir);
    25572562
     2563    uint8_t         uUdfLevel               = 0;
     2564    uint64_t        offUdfBootVolDesc       = UINT64_MAX;
     2565
    25582566    uint32_t        cPrimaryVolDescs        = 0;
    25592567    uint32_t        cSupplementaryVolDescs  = 0;
    25602568    uint32_t        cBootRecordVolDescs     = 0;
    25612569    uint32_t        offVolDesc              = 16 * cbSector;
     2570    enum
     2571    {
     2572        kStateStart = 0,
     2573        kStateNoSeq,
     2574        kStateCdSeq,
     2575        kStateUdfSeq,
     2576    }               enmState = kStateStart;
    25622577    for (uint32_t iVolDesc = 0; ; iVolDesc++, offVolDesc += cbSector)
    25632578    {
    25642579        if (iVolDesc > 32)
    2565             return RTErrInfoSet(pErrInfo, rc, "More than 32 volume descriptors, doesn't seem right...");
     2580            return RTErrInfoSet(pErrInfo, VERR_VFS_BOGUS_FORMAT, "More than 32 volume descriptors, doesn't seem right...");
    25662581
    25672582        /* Read the next one and check the signature. */
     
    25702585            return RTErrInfoSetF(pErrInfo, rc, "Unable to read volume descriptor #%u", iVolDesc);
    25712586
    2572         if (   Buf.VolDescHdr.achStdId[0] != ISO9660VOLDESC_STD_ID_0
    2573             || Buf.VolDescHdr.achStdId[1] != ISO9660VOLDESC_STD_ID_1
    2574             || Buf.VolDescHdr.achStdId[2] != ISO9660VOLDESC_STD_ID_2
    2575             || Buf.VolDescHdr.achStdId[3] != ISO9660VOLDESC_STD_ID_3
    2576             || Buf.VolDescHdr.achStdId[4] != ISO9660VOLDESC_STD_ID_4)
    2577         {
    2578             if (!iVolDesc)
     2587#define MATCH_STD_ID(a_achStdId1, a_szStdId2) \
     2588            (   (a_achStdId1)[0] == (a_szStdId2)[0] \
     2589             && (a_achStdId1)[1] == (a_szStdId2)[1] \
     2590             && (a_achStdId1)[2] == (a_szStdId2)[2] \
     2591             && (a_achStdId1)[3] == (a_szStdId2)[3] \
     2592             && (a_achStdId1)[4] == (a_szStdId2)[4] )
     2593#define MATCH_HDR(a_pStd, a_bType2, a_szStdId2, a_bVer2) \
     2594            (    MATCH_STD_ID((a_pStd)->achStdId, a_szStdId2) \
     2595             && (a_pStd)->bDescType    == (a_bType2) \
     2596             && (a_pStd)->bDescVersion == (a_bVer2) )
     2597
     2598        /*
     2599         * ISO 9660 ("CD001").
     2600         */
     2601        if (   (   enmState == kStateStart
     2602                || enmState == kStateCdSeq
     2603                || enmState == kStateNoSeq)
     2604            && MATCH_STD_ID(Buf.VolDescHdr.achStdId, ISO9660VOLDESC_STD_ID) )
     2605        {
     2606            enmState = kStateCdSeq;
     2607
     2608            /* Do type specific handling. */
     2609            Log(("ISO9660: volume desc #%u: type=%#x\n", iVolDesc, Buf.VolDescHdr.bDescType));
     2610            if (Buf.VolDescHdr.bDescType == ISO9660VOLDESC_TYPE_PRIMARY)
     2611            {
     2612                cPrimaryVolDescs++;
     2613                if (Buf.VolDescHdr.bDescVersion != ISO9660PRIMARYVOLDESC_VERSION)
     2614                    return RTErrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
     2615                                         "Unsupported primary volume descriptor version: %#x", Buf.VolDescHdr.bDescVersion);
     2616#ifdef LOG_ENABLED
     2617                rtFsIso9660VolLogPrimarySupplementaryVolDesc(&Buf.SupVolDesc);
     2618#endif
     2619                if (cPrimaryVolDescs > 1)
     2620                    return RTErrInfoSet(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, "More than one primary volume descriptor");
     2621                rc = rtFsIso9660VolHandlePrimaryVolDesc(pThis, &Buf.PrimaryVolDesc, offVolDesc, &RootDir, &offRootDirRec, pErrInfo);
     2622            }
     2623            else if (Buf.VolDescHdr.bDescType == ISO9660VOLDESC_TYPE_SUPPLEMENTARY)
     2624            {
     2625                cSupplementaryVolDescs++;
     2626                if (Buf.VolDescHdr.bDescVersion != ISO9660SUPVOLDESC_VERSION)
     2627                    return RTErrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
     2628                                         "Unsupported supplemental volume descriptor version: %#x", Buf.VolDescHdr.bDescVersion);
     2629#ifdef LOG_ENABLED
     2630                rtFsIso9660VolLogPrimarySupplementaryVolDesc(&Buf.SupVolDesc);
     2631#endif
     2632                rc = rtFsIso9660VolHandleSupplementaryVolDesc(pThis, &Buf.SupVolDesc, offVolDesc, &bJolietUcs2Level, &JolietRootDir,
     2633                                                              &offJolietRootDirRec, pErrInfo);
     2634            }
     2635            else if (Buf.VolDescHdr.bDescType == ISO9660VOLDESC_TYPE_BOOT_RECORD)
     2636            {
     2637                cBootRecordVolDescs++;
     2638            }
     2639            else if (Buf.VolDescHdr.bDescType == ISO9660VOLDESC_TYPE_TERMINATOR)
     2640            {
     2641                if (!cPrimaryVolDescs)
     2642                    return RTErrInfoSet(pErrInfo, VERR_VFS_BOGUS_FORMAT, "No primary volume descriptor");
     2643                enmState = kStateNoSeq;
     2644            }
     2645            else
     2646                return RTErrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
     2647                                     "Unknown volume descriptor: %#x", Buf.VolDescHdr.bDescType);
     2648        }
     2649        /*
     2650         * UDF volume recognition sequence (VRS).
     2651         */
     2652        else if (   (   enmState == kStateNoSeq
     2653                     || enmState == kStateStart)
     2654                 && MATCH_HDR(&Buf.VolDescHdr, UDF_EXT_VOL_DESC_TYPE, UDF_EXT_VOL_DESC_STD_ID_BEGIN, UDF_EXT_VOL_DESC_VERSION) )
     2655        {
     2656            if (uUdfLevel == 0)
     2657                enmState = kStateUdfSeq;
     2658            else
     2659                return RTErrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Only one BEA01 sequence is supported");
     2660        }
     2661        else if (   enmState == kStateUdfSeq
     2662                 && MATCH_HDR(&Buf.VolDescHdr, UDF_EXT_VOL_DESC_TYPE, UDF_EXT_VOL_DESC_STD_ID_NSR_02, UDF_EXT_VOL_DESC_VERSION) )
     2663            uUdfLevel = 2;
     2664        else if (   enmState == kStateUdfSeq
     2665                 && MATCH_HDR(&Buf.VolDescHdr, UDF_EXT_VOL_DESC_TYPE, UDF_EXT_VOL_DESC_STD_ID_NSR_03, UDF_EXT_VOL_DESC_VERSION) )
     2666            uUdfLevel = 3;
     2667        else if (   enmState == kStateUdfSeq
     2668                 && MATCH_HDR(&Buf.VolDescHdr, UDF_EXT_VOL_DESC_TYPE, UDF_EXT_VOL_DESC_STD_ID_BOOT, UDF_EXT_VOL_DESC_VERSION) )
     2669        {
     2670            if (offUdfBootVolDesc == UINT64_MAX)
     2671                offUdfBootVolDesc = iVolDesc * cbSector;
     2672            else
     2673                return RTErrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Only one BOOT2 descriptor is supported");
     2674        }
     2675        else if (   enmState == kStateUdfSeq
     2676                 && MATCH_HDR(&Buf.VolDescHdr, UDF_EXT_VOL_DESC_TYPE, UDF_EXT_VOL_DESC_STD_ID_TERM, UDF_EXT_VOL_DESC_VERSION) )
     2677        {
     2678            if (uUdfLevel != 0)
     2679                enmState = kStateNoSeq;
     2680            else
     2681                return RTErrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Found BEA01 & TEA01, but no NSR02 or NSR03 descriptors");
     2682        }
     2683        /*
     2684         * Unknown, probably the end.
     2685         */
     2686        else if (enmState == kStateNoSeq)
     2687            break;
     2688        else if (enmState == kStateStart)
    25792689                return RTErrInfoSetF(pErrInfo, VERR_VFS_UNKNOWN_FORMAT,
    2580                                      "No ISO 9660 CD001 signature, instead found: %.5Rhxs", Buf.VolDescHdr.achStdId);
    2581             return RTErrInfoSet(pErrInfo, VERR_VFS_BOGUS_FORMAT, "Missing terminator volume descriptor?");
    2582         }
    2583 
    2584         /* Do type specific handling. */
    2585         Log(("ISO9660: volume desc #%u: type=%#x\n", iVolDesc, Buf.VolDescHdr.bDescType));
    2586         if (Buf.VolDescHdr.bDescType == ISO9660VOLDESC_TYPE_PRIMARY)
    2587         {
    2588             cPrimaryVolDescs++;
    2589             if (Buf.VolDescHdr.bDescVersion != ISO9660PRIMARYVOLDESC_VERSION)
    2590                 return RTErrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
    2591                                      "Unsupported primary volume descriptor version: %#x", Buf.VolDescHdr.bDescVersion);
    2592 #ifdef LOG_ENABLED
    2593             rtFsIso9660VolLogPrimarySupplementaryVolDesc(&Buf.SupVolDesc);
    2594 #endif
    2595             if (cPrimaryVolDescs > 1)
    2596                 return RTErrInfoSet(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, "More than one primary volume descriptor");
    2597             rc = rtFsIso9660VolHandlePrimaryVolDesc(pThis, &Buf.PrimaryVolDesc, offVolDesc, &RootDir, &offRootDirRec, pErrInfo);
    2598         }
    2599         else if (Buf.VolDescHdr.bDescType == ISO9660VOLDESC_TYPE_SUPPLEMENTARY)
    2600         {
    2601             cSupplementaryVolDescs++;
    2602             if (Buf.VolDescHdr.bDescVersion != ISO9660SUPVOLDESC_VERSION)
    2603                 return RTErrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
    2604                                      "Unsupported supplemental volume descriptor version: %#x", Buf.VolDescHdr.bDescVersion);
    2605 #ifdef LOG_ENABLED
    2606             rtFsIso9660VolLogPrimarySupplementaryVolDesc(&Buf.SupVolDesc);
    2607 #endif
    2608             rc = rtFsIso9660VolHandleSupplementaryVolDesc(pThis, &Buf.SupVolDesc, offVolDesc, &bJolietUcs2Level, &JolietRootDir,
    2609                                                           &offJolietRootDirRec, pErrInfo);
    2610         }
    2611         else if (Buf.VolDescHdr.bDescType == ISO9660VOLDESC_TYPE_BOOT_RECORD)
    2612         {
    2613             cBootRecordVolDescs++;
    2614         }
    2615         else if (Buf.VolDescHdr.bDescType == ISO9660VOLDESC_TYPE_TERMINATOR)
    2616         {
    2617             if (!cPrimaryVolDescs)
    2618                 return RTErrInfoSet(pErrInfo, VERR_VFS_BOGUS_FORMAT, "No primary volume descriptor");
    2619             break;
    2620         }
     2690                                     "Not ISO? Unable to recognize volume descriptor signature: %.5Rhxs", Buf.VolDescHdr.achStdId);
     2691        else if (enmState == kStateCdSeq)
     2692            return RTErrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT,
     2693                                 "Missing ISO 9660 terminator volume descriptor? (Found %.5Rhxs)", Buf.VolDescHdr.achStdId);
     2694        else if (enmState == kStateUdfSeq)
     2695            return RTErrInfoSetF(pErrInfo, VERR_VFS_BOGUS_FORMAT,
     2696                                 "Missing UDF terminator volume descriptor? (Found %.5Rhxs)", Buf.VolDescHdr.achStdId);
    26212697        else
    2622             return RTErrInfoSetF(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT,
    2623                                  "Unknown volume descriptor: %#x", Buf.VolDescHdr.bDescType);
     2698            return RTErrInfoSetF(pErrInfo, VERR_VFS_UNKNOWN_FORMAT,
     2699                                 "Unknown volume descriptor signature found at sector %u: %.5Rhxs",
     2700                                 16 + iVolDesc, Buf.VolDescHdr.achStdId);
    26242701        if (RT_FAILURE(rc))
    26252702            return rc;
     2703    }
     2704
     2705    /*
     2706     * If we found a UDF VRS and are interested in UDF, we have more work to do here.
     2707     */
     2708    if (uUdfLevel > 0)
     2709    {
     2710        Log(("rtFsIso9660VolTryInit: uUdfLevel=%d - TODO\n", uUdfLevel));
    26262711    }
    26272712
     
    27202805                else if (!strcmp(psz, "norock"))
    27212806                    fFlags |= RTFSISO9660_F_NO_ROCK;
     2807                else if (!strcmp(psz, "noudf"))
     2808                    fFlags |= RTFSISO9660_F_NO_UDF;
    27222809                else
    27232810                {
     
    27882875    /* ListEntry = */           { NULL, NULL },
    27892876    /* pszHelp = */             "Open a ISO 9660 file system, requires a file object on the left side.\n"
     2877                                "The 'noudf' option make it ignore any UDF.\n"
    27902878                                "The 'nojoliet' option make it ignore any joliet supplemental volume.\n"
    27912879                                "The 'norock' option make it ignore any rock ridge info.\n",
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