VirtualBox

Changeset 69035 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Oct 11, 2017 9:38:54 AM (7 years ago)
Author:
vboxsync
Message:

UDF: Implemented directory listing. Works for root, other directories needs traversal and opendir impl.

File:
1 edited

Legend:

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

    r69029 r69035  
    14881488        {
    14891489            LogRelMax(45, ("ISO/UDF: ICB is too small: %u bytes\n", AllocDesc.cb));
    1490             return AllocDesc.cb == 0 ? VINF_SUCCESS : VERR_ISOFS_ICB_TOO_SMALL;
     1490            return AllocDesc.cb == 0 ? VINF_SUCCESS : VERR_ISOFS_ICB_ENTRY_TOO_SMALL;
    14911491        }
    14921492
     
    15871587 *                              Caller must've ZEROed this structure!
    15881588 * @param   pAllocDesc          The ICB allocation descriptor.
    1589  * @param   pFileIdDesc         The file ID descriptor.  Optional.
     1589 * @param   pFid                The file ID descriptor.  Optional.
    15901590 * @param   pVol                The instance.
    15911591 */
    15921592static int rtFsIsoCore_InitFromUdfIcbAndFileIdDesc(PRTFSISOCORE pCore, PCUDFLONGAD pAllocDesc,
    1593                                                    PCUDFFILEIDDESC pFileIdDesc, PRTFSISOVOL pVol)
     1593                                                   PCUDFFILEIDDESC pFid, PRTFSISOVOL pVol)
    15941594{
    15951595    Assert(pCore->cRefs == 0);
     
    15981598    Assert(pCore->pVol == NULL);
    15991599
    1600 RT_NOREF(pFileIdDesc);
    1601     if (pAllocDesc->cb > _64K)
    1602         return VERR_ISOFS_DIR_ICB_TOO_BIG;
    1603     if (pAllocDesc->cb < sizeof(UDFTAG) + sizeof(UDFICBTAG))
    1604         return VERR_ISOFS_DIR_ICB_TOO_SMALL;
     1600    /*
     1601     * Some size sanity checking.
     1602     */
     1603    if (pAllocDesc->cb <= _64K)
     1604    {
     1605        if (pAllocDesc->cb >= sizeof(UDFICBHDR))
     1606        { /* likely */ }
     1607        else
     1608        {
     1609            Log(("rtFsIsoCore_InitFromUdfIcbAndFileIdDesc: ICB too small: %#04x:%010RX32 LB %#x\n",
     1610                 pAllocDesc->Location.uPartitionNo, pAllocDesc->Location.off, pAllocDesc->cb));
     1611            return VERR_ISOFS_ICB_TOO_SMALL;
     1612        }
     1613    }
     1614    else
     1615    {
     1616        Log(("rtFsIsoCore_InitFromUdfIcbAndFileIdDesc: ICB too big: %#04x:%010RX32 LB %#x\n",
     1617             pAllocDesc->Location.uPartitionNo, pAllocDesc->Location.off, pAllocDesc->cb));
     1618        return VERR_ISOFS_ICB_TOO_BIG;
     1619    }
    16051620
    16061621    /*
     
    16181633            if (cProcessed > 0)
    16191634            {
     1635                if (pFid && (pFid->fFlags & UDF_FILE_FLAGS_HIDDEN))
     1636                    pCore->fAttrib |= RTFS_DOS_HIDDEN;
     1637
    16201638                pCore->cRefs = 1;
    16211639                pCore->pVol  = pVol;
     
    16471665static int rtFsIsoVolUdfExtentRead(PRTFSISOCORE pCore, uint64_t offRead, void *pvBuf, size_t cbToRead, size_t *pcbRead)
    16481666{
     1667    Assert(pCore->pVol->enmType == RTFSISOVOLTYPE_UDF);
     1668
    16491669    /*
    16501670     * Check for EOF.
     
    18961916    }
    18971917
     1918    if (pShared->Core.pVol->enmType == RTFSISOVOLTYPE_UDF)
     1919    {
     1920        return VERR_ISOFS_UDF_NOT_IMPLEMENTED;
     1921    }
    18981922
    18991923    /*
     
    23642388                                PCISO9660DIRREC *ppDirRec, uint32_t *pcDirRecs, PRTFMODE pfMode, uint32_t *puVersion)
    23652389{
     2390    Assert(pThis->Core.pVol->enmType != RTFSISOVOLTYPE_UDF);
     2391
    23662392    /* Set return values. */
    23672393    *poffDirRec = UINT64_MAX;
     
    26022628        PRTFSISODIROBJ      pThis = (PRTFSISODIROBJ)pvThis;
    26032629        PRTFSISODIRSHRD     pShared = pThis->pShared;
     2630        if (pShared->Core.pVol->enmType != RTFSISOVOLTYPE_UDF)
     2631        {
     2632            /*
     2633             * ISO 9660
     2634             */
     2635            PCISO9660DIRREC     pDirRec;
     2636            uint64_t            offDirRec;
     2637            uint32_t            cDirRecs;
     2638            RTFMODE             fMode;
     2639            uint32_t            uVersion;
     2640            rc = rtFsIsoDir_FindEntry(pShared, pszEntry, &offDirRec, &pDirRec, &cDirRecs, &fMode, &uVersion);
     2641            Log2(("rtFsIsoDir_TraversalOpen: FindEntry(,%s,) -> %Rrc\n", pszEntry, rc));
     2642            if (RT_SUCCESS(rc))
     2643            {
     2644                switch (fMode & RTFS_TYPE_MASK)
     2645                {
     2646                    case RTFS_TYPE_DIRECTORY:
     2647                        if (phVfsDir)
     2648                            rc = rtFsIsoDir_New9660(pShared->Core.pVol, pShared, pDirRec, cDirRecs, offDirRec, phVfsDir);
     2649                        else
     2650                            rc = VERR_NOT_SYMLINK;
     2651                        break;
     2652
     2653                    case RTFS_TYPE_SYMLINK:
     2654                        rc = VERR_NOT_IMPLEMENTED;
     2655                        break;
     2656                    case RTFS_TYPE_FILE:
     2657                    case RTFS_TYPE_DEV_BLOCK:
     2658                    case RTFS_TYPE_DEV_CHAR:
     2659                    case RTFS_TYPE_FIFO:
     2660                    case RTFS_TYPE_SOCKET:
     2661                        rc = VERR_NOT_A_DIRECTORY;
     2662                        break;
     2663                    default:
     2664                    case RTFS_TYPE_WHITEOUT:
     2665                        rc = VERR_PATH_NOT_FOUND;
     2666                        break;
     2667                }
     2668            }
     2669            else if (rc == VERR_FILE_NOT_FOUND)
     2670                rc = VERR_PATH_NOT_FOUND;
     2671        }
     2672        else
     2673        {
     2674            /*
     2675             * UDF
     2676             */
     2677            rc = VERR_ISOFS_UDF_NOT_IMPLEMENTED;
     2678        }
     2679    }
     2680    else
     2681        rc = VERR_PATH_NOT_FOUND;
     2682    return rc;
     2683}
     2684
     2685
     2686/**
     2687 * @interface_method_impl{RTVFSDIROPS,pfnOpenFile}
     2688 */
     2689static DECLCALLBACK(int) rtFsIsoDir_OpenFile(void *pvThis, const char *pszFilename, uint32_t fOpen, PRTVFSFILE phVfsFile)
     2690{
     2691    PRTFSISODIROBJ  pThis   = (PRTFSISODIROBJ)pvThis;
     2692    PRTFSISODIRSHRD pShared = pThis->pShared;
     2693
     2694    /*
     2695     * We cannot create or replace anything, just open stuff.
     2696     */
     2697    if (   (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE
     2698        || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE)
     2699        return VERR_WRITE_PROTECT;
     2700
     2701    /*
     2702     * Try open file.
     2703     */
     2704    int rc;
     2705    if (pShared->Core.pVol->enmType != RTFSISOVOLTYPE_UDF)
     2706    {
     2707        PCISO9660DIRREC pDirRec;
     2708        uint64_t        offDirRec;
     2709        uint32_t        cDirRecs;
     2710        RTFMODE         fMode;
     2711        uint32_t        uVersion;
     2712        rc = rtFsIsoDir_FindEntry(pShared, pszFilename, &offDirRec, &pDirRec, &cDirRecs, &fMode, &uVersion);
     2713        Log2(("rtFsIsoDir_OpenFile: FindEntry(,%s,) -> %Rrc\n", pszFilename, rc));
     2714        if (RT_SUCCESS(rc))
     2715        {
     2716            switch (fMode & RTFS_TYPE_MASK)
     2717            {
     2718                case RTFS_TYPE_FILE:
     2719                    rc = rtFsIsoFile_New9660(pShared->Core.pVol, pShared, pDirRec, cDirRecs, offDirRec, fOpen, uVersion, phVfsFile);
     2720                    break;
     2721
     2722                case RTFS_TYPE_SYMLINK:
     2723                case RTFS_TYPE_DEV_BLOCK:
     2724                case RTFS_TYPE_DEV_CHAR:
     2725                case RTFS_TYPE_FIFO:
     2726                case RTFS_TYPE_SOCKET:
     2727                case RTFS_TYPE_WHITEOUT:
     2728                    rc = VERR_NOT_IMPLEMENTED;
     2729                    break;
     2730
     2731                case RTFS_TYPE_DIRECTORY:
     2732                    rc = VERR_NOT_A_FILE;
     2733                    break;
     2734
     2735                default:
     2736                    rc = VERR_PATH_NOT_FOUND;
     2737                    break;
     2738            }
     2739        }
     2740    }
     2741    else
     2742    {
     2743        rc = VERR_ISOFS_UDF_NOT_IMPLEMENTED;
     2744    }
     2745    return rc;
     2746}
     2747
     2748
     2749/**
     2750 * @interface_method_impl{RTVFSDIROPS,pfnOpenDir}
     2751 */
     2752static DECLCALLBACK(int) rtFsIsoDir_OpenDir(void *pvThis, const char *pszSubDir, uint32_t fFlags, PRTVFSDIR phVfsDir)
     2753{
     2754    PRTFSISODIROBJ  pThis   = (PRTFSISODIROBJ)pvThis;
     2755    PRTFSISODIRSHRD pShared = pThis->pShared;
     2756    AssertReturn(!fFlags, VERR_INVALID_FLAGS);
     2757
     2758    /*
     2759     * Try open file.
     2760     */
     2761    int rc;
     2762    if (pShared->Core.pVol->enmType != RTFSISOVOLTYPE_UDF)
     2763    {
     2764        PCISO9660DIRREC pDirRec;
     2765        uint64_t        offDirRec;
     2766        uint32_t        cDirRecs;
     2767        RTFMODE         fMode;
     2768        uint32_t        uVersion;
     2769        rc = rtFsIsoDir_FindEntry(pShared, pszSubDir, &offDirRec, &pDirRec, &cDirRecs, &fMode, &uVersion);
     2770        Log2(("rtFsIsoDir_OpenDir: FindEntry(,%s,) -> %Rrc\n", pszSubDir, rc));
     2771        if (RT_SUCCESS(rc))
     2772        {
     2773            switch (fMode & RTFS_TYPE_MASK)
     2774            {
     2775                case RTFS_TYPE_DIRECTORY:
     2776                    rc = rtFsIsoDir_New9660(pShared->Core.pVol, pShared, pDirRec, cDirRecs, offDirRec, phVfsDir);
     2777                    break;
     2778
     2779                case RTFS_TYPE_FILE:
     2780                case RTFS_TYPE_SYMLINK:
     2781                case RTFS_TYPE_DEV_BLOCK:
     2782                case RTFS_TYPE_DEV_CHAR:
     2783                case RTFS_TYPE_FIFO:
     2784                case RTFS_TYPE_SOCKET:
     2785                case RTFS_TYPE_WHITEOUT:
     2786                    rc = VERR_NOT_A_DIRECTORY;
     2787                    break;
     2788
     2789                default:
     2790                    rc = VERR_PATH_NOT_FOUND;
     2791                    break;
     2792            }
     2793        }
     2794    }
     2795    else
     2796    {
     2797        rc = VERR_ISOFS_UDF_NOT_IMPLEMENTED;
     2798    }
     2799    return rc;
     2800}
     2801
     2802
     2803/**
     2804 * @interface_method_impl{RTVFSDIROPS,pfnCreateDir}
     2805 */
     2806static DECLCALLBACK(int) rtFsIsoDir_CreateDir(void *pvThis, const char *pszSubDir, RTFMODE fMode, PRTVFSDIR phVfsDir)
     2807{
     2808    RT_NOREF(pvThis, pszSubDir, fMode, phVfsDir);
     2809    return VERR_WRITE_PROTECT;
     2810}
     2811
     2812
     2813/**
     2814 * @interface_method_impl{RTVFSDIROPS,pfnOpenSymlink}
     2815 */
     2816static DECLCALLBACK(int) rtFsIsoDir_OpenSymlink(void *pvThis, const char *pszSymlink, PRTVFSSYMLINK phVfsSymlink)
     2817{
     2818    RT_NOREF(pvThis, pszSymlink, phVfsSymlink);
     2819    return VERR_NOT_SUPPORTED;
     2820}
     2821
     2822
     2823/**
     2824 * @interface_method_impl{RTVFSDIROPS,pfnCreateSymlink}
     2825 */
     2826static DECLCALLBACK(int) rtFsIsoDir_CreateSymlink(void *pvThis, const char *pszSymlink, const char *pszTarget,
     2827                                                  RTSYMLINKTYPE enmType, PRTVFSSYMLINK phVfsSymlink)
     2828{
     2829    RT_NOREF(pvThis, pszSymlink, pszTarget, enmType, phVfsSymlink);
     2830    return VERR_WRITE_PROTECT;
     2831}
     2832
     2833
     2834/**
     2835 * @interface_method_impl{RTVFSDIROPS,pfnQueryEntryInfo}
     2836 */
     2837static DECLCALLBACK(int) rtFsIsoDir_QueryEntryInfo(void *pvThis, const char *pszEntry,
     2838                                                   PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
     2839{
     2840    PRTFSISODIROBJ      pThis   = (PRTFSISODIROBJ)pvThis;
     2841    PRTFSISODIRSHRD     pShared = pThis->pShared;
     2842    int                 rc;
     2843    if (pShared->Core.pVol->enmType != RTFSISOVOLTYPE_UDF)
     2844    {
     2845        /*
     2846         * Try locate the entry.
     2847         */
    26042848        PCISO9660DIRREC     pDirRec;
    26052849        uint64_t            offDirRec;
     
    26082852        uint32_t            uVersion;
    26092853        rc = rtFsIsoDir_FindEntry(pShared, pszEntry, &offDirRec, &pDirRec, &cDirRecs, &fMode, &uVersion);
    2610         Log2(("rtFsIsoDir_TraversalOpen: FindEntry(,%s,) -> %Rrc\n", pszEntry, rc));
     2854        Log2(("rtFsIsoDir_QueryEntryInfo: FindEntry(,%s,) -> %Rrc\n", pszEntry, rc));
    26112855        if (RT_SUCCESS(rc))
    26122856        {
    2613             switch (fMode & RTFS_TYPE_MASK)
    2614             {
    2615                 case RTFS_TYPE_DIRECTORY:
    2616                     if (phVfsDir)
    2617                         rc = rtFsIsoDir_New9660(pShared->Core.pVol, pShared, pDirRec, cDirRecs, offDirRec, phVfsDir);
    2618                     else
    2619                         rc = VERR_NOT_SYMLINK;
    2620                     break;
    2621 
    2622                 case RTFS_TYPE_SYMLINK:
    2623                     rc = VERR_NOT_IMPLEMENTED;
    2624                     break;
    2625                 case RTFS_TYPE_FILE:
    2626                 case RTFS_TYPE_DEV_BLOCK:
    2627                 case RTFS_TYPE_DEV_CHAR:
    2628                 case RTFS_TYPE_FIFO:
    2629                 case RTFS_TYPE_SOCKET:
    2630                     rc = VERR_NOT_A_DIRECTORY;
    2631                     break;
    2632                 default:
    2633                 case RTFS_TYPE_WHITEOUT:
    2634                     rc = VERR_PATH_NOT_FOUND;
    2635                     break;
    2636             }
    2637         }
    2638         else if (rc == VERR_FILE_NOT_FOUND)
    2639             rc = VERR_PATH_NOT_FOUND;
     2857            /*
     2858             * To avoid duplicating code in rtFsIsoCore_InitFrom9660DirRec and
     2859             * rtFsIsoCore_QueryInfo, we create a dummy RTFSISOCORE on the stack.
     2860             */
     2861            RTFSISOCORE TmpObj;
     2862            RT_ZERO(TmpObj);
     2863            rc = rtFsIsoCore_InitFrom9660DirRec(&TmpObj, pDirRec, cDirRecs, offDirRec, uVersion, pShared->Core.pVol);
     2864            if (RT_SUCCESS(rc))
     2865            {
     2866                rc = rtFsIsoCore_QueryInfo(&TmpObj, pObjInfo, enmAddAttr);
     2867                RTMemFree(TmpObj.paExtents);
     2868            }
     2869        }
    26402870    }
    26412871    else
    2642         rc = VERR_PATH_NOT_FOUND;
    2643     return rc;
    2644 }
    2645 
    2646 
    2647 /**
    2648  * @interface_method_impl{RTVFSDIROPS,pfnOpenFile}
    2649  */
    2650 static DECLCALLBACK(int) rtFsIsoDir_OpenFile(void *pvThis, const char *pszFilename, uint32_t fOpen, PRTVFSFILE phVfsFile)
    2651 {
    2652     PRTFSISODIROBJ  pThis   = (PRTFSISODIROBJ)pvThis;
    2653     PRTFSISODIRSHRD pShared = pThis->pShared;
    2654 
    2655     /*
    2656      * We cannot create or replace anything, just open stuff.
    2657      */
    2658     if (   (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE
    2659         || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE)
    2660         return VERR_WRITE_PROTECT;
    2661 
    2662     /*
    2663      * Try open file.
    2664      */
    2665     PCISO9660DIRREC pDirRec;
    2666     uint64_t        offDirRec;
    2667     uint32_t        cDirRecs;
    2668     RTFMODE         fMode;
    2669     uint32_t        uVersion;
    2670     int rc = rtFsIsoDir_FindEntry(pShared, pszFilename, &offDirRec, &pDirRec, &cDirRecs, &fMode, &uVersion);
    2671     Log2(("rtFsIsoDir_OpenFile: FindEntry(,%s,) -> %Rrc\n", pszFilename, rc));
    2672     if (RT_SUCCESS(rc))
    2673     {
    2674         switch (fMode & RTFS_TYPE_MASK)
    2675         {
    2676             case RTFS_TYPE_FILE:
    2677                 rc = rtFsIsoFile_New9660(pShared->Core.pVol, pShared, pDirRec, cDirRecs, offDirRec, fOpen, uVersion, phVfsFile);
    2678                 break;
    2679 
    2680             case RTFS_TYPE_SYMLINK:
    2681             case RTFS_TYPE_DEV_BLOCK:
    2682             case RTFS_TYPE_DEV_CHAR:
    2683             case RTFS_TYPE_FIFO:
    2684             case RTFS_TYPE_SOCKET:
    2685             case RTFS_TYPE_WHITEOUT:
    2686                 rc = VERR_NOT_IMPLEMENTED;
    2687                 break;
    2688 
    2689             case RTFS_TYPE_DIRECTORY:
    2690                 rc = VERR_NOT_A_FILE;
    2691                 break;
    2692 
    2693             default:
    2694                 rc = VERR_PATH_NOT_FOUND;
    2695                 break;
    2696         }
    2697     }
    2698     return rc;
    2699 }
    2700 
    2701 
    2702 /**
    2703  * @interface_method_impl{RTVFSDIROPS,pfnOpenDir}
    2704  */
    2705 static DECLCALLBACK(int) rtFsIsoDir_OpenDir(void *pvThis, const char *pszSubDir, uint32_t fFlags, PRTVFSDIR phVfsDir)
    2706 {
    2707     PRTFSISODIROBJ  pThis   = (PRTFSISODIROBJ)pvThis;
    2708     PRTFSISODIRSHRD pShared = pThis->pShared;
    2709     AssertReturn(!fFlags, VERR_INVALID_FLAGS);
    2710 
    2711     /*
    2712      * Try open file.
    2713      */
    2714     PCISO9660DIRREC pDirRec;
    2715     uint64_t        offDirRec;
    2716     uint32_t        cDirRecs;
    2717     RTFMODE         fMode;
    2718     uint32_t        uVersion;
    2719     int rc = rtFsIsoDir_FindEntry(pShared, pszSubDir, &offDirRec, &pDirRec, &cDirRecs, &fMode, &uVersion);
    2720     Log2(("rtFsIsoDir_OpenDir: FindEntry(,%s,) -> %Rrc\n", pszSubDir, rc));
    2721     if (RT_SUCCESS(rc))
    2722     {
    2723         switch (fMode & RTFS_TYPE_MASK)
    2724         {
    2725             case RTFS_TYPE_DIRECTORY:
    2726                 rc = rtFsIsoDir_New9660(pShared->Core.pVol, pShared, pDirRec, cDirRecs, offDirRec, phVfsDir);
    2727                 break;
    2728 
    2729             case RTFS_TYPE_FILE:
    2730             case RTFS_TYPE_SYMLINK:
    2731             case RTFS_TYPE_DEV_BLOCK:
    2732             case RTFS_TYPE_DEV_CHAR:
    2733             case RTFS_TYPE_FIFO:
    2734             case RTFS_TYPE_SOCKET:
    2735             case RTFS_TYPE_WHITEOUT:
    2736                 rc = VERR_NOT_A_DIRECTORY;
    2737                 break;
    2738 
    2739             default:
    2740                 rc = VERR_PATH_NOT_FOUND;
    2741                 break;
    2742         }
    2743     }
    2744     return rc;
    2745 }
    2746 
    2747 
    2748 /**
    2749  * @interface_method_impl{RTVFSDIROPS,pfnCreateDir}
    2750  */
    2751 static DECLCALLBACK(int) rtFsIsoDir_CreateDir(void *pvThis, const char *pszSubDir, RTFMODE fMode, PRTVFSDIR phVfsDir)
    2752 {
    2753     RT_NOREF(pvThis, pszSubDir, fMode, phVfsDir);
    2754     return VERR_WRITE_PROTECT;
    2755 }
    2756 
    2757 
    2758 /**
    2759  * @interface_method_impl{RTVFSDIROPS,pfnOpenSymlink}
    2760  */
    2761 static DECLCALLBACK(int) rtFsIsoDir_OpenSymlink(void *pvThis, const char *pszSymlink, PRTVFSSYMLINK phVfsSymlink)
    2762 {
    2763     RT_NOREF(pvThis, pszSymlink, phVfsSymlink);
    2764 RTAssertMsg2("%s: %s\n", __FUNCTION__, pszSymlink);
    2765     return VERR_NOT_SUPPORTED;
    2766 }
    2767 
    2768 
    2769 /**
    2770  * @interface_method_impl{RTVFSDIROPS,pfnCreateSymlink}
    2771  */
    2772 static DECLCALLBACK(int) rtFsIsoDir_CreateSymlink(void *pvThis, const char *pszSymlink, const char *pszTarget,
    2773                                                   RTSYMLINKTYPE enmType, PRTVFSSYMLINK phVfsSymlink)
    2774 {
    2775     RT_NOREF(pvThis, pszSymlink, pszTarget, enmType, phVfsSymlink);
    2776     return VERR_WRITE_PROTECT;
    2777 }
    2778 
    2779 
    2780 /**
    2781  * @interface_method_impl{RTVFSDIROPS,pfnQueryEntryInfo}
    2782  */
    2783 static DECLCALLBACK(int) rtFsIsoDir_QueryEntryInfo(void *pvThis, const char *pszEntry,
    2784                                                    PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
    2785 {
    2786     /*
    2787      * Try locate the entry.
    2788      */
    2789     PRTFSISODIROBJ      pThis   = (PRTFSISODIROBJ)pvThis;
    2790     PRTFSISODIRSHRD     pShared = pThis->pShared;
    2791     PCISO9660DIRREC     pDirRec;
    2792     uint64_t            offDirRec;
    2793     uint32_t            cDirRecs;
    2794     RTFMODE             fMode;
    2795     uint32_t            uVersion;
    2796     int rc = rtFsIsoDir_FindEntry(pShared, pszEntry, &offDirRec, &pDirRec, &cDirRecs, &fMode, &uVersion);
    2797     Log2(("rtFsIsoDir_QueryEntryInfo: FindEntry(,%s,) -> %Rrc\n", pszEntry, rc));
    2798     if (RT_SUCCESS(rc))
    2799     {
    2800         /*
    2801          * To avoid duplicating code in rtFsIsoCore_InitFrom9660DirRec and
    2802          * rtFsIsoCore_QueryInfo, we create a dummy RTFSISOCORE on the stack.
    2803          */
    2804         RTFSISOCORE TmpObj;
    2805         RT_ZERO(TmpObj);
    2806         rc = rtFsIsoCore_InitFrom9660DirRec(&TmpObj, pDirRec, cDirRecs, offDirRec, uVersion, pShared->Core.pVol);
    2807         if (RT_SUCCESS(rc))
    2808         {
    2809             rc = rtFsIsoCore_QueryInfo(&TmpObj, pObjInfo, enmAddAttr);
    2810             RTMemFree(TmpObj.paExtents);
    2811         }
     2872    {
     2873        rc = VERR_ISOFS_UDF_NOT_IMPLEMENTED;
    28122874    }
    28132875    return rc;
     
    28472909
    28482910/**
    2849  * @interface_method_impl{RTVFSDIROPS,pfnReadDir}
    2850  */
    2851 static DECLCALLBACK(int) rtFsIsoDir_ReadDir(void *pvThis, PRTDIRENTRYEX pDirEntry, size_t *pcbDirEntry,
    2852                                             RTFSOBJATTRADD enmAddAttr)
    2853 {
    2854     PRTFSISODIROBJ  pThis   = (PRTFSISODIROBJ)pvThis;
    2855     PRTFSISODIRSHRD pShared = pThis->pShared;
    2856 
     2911 * The ISO 9660 worker for rtFsIsoDir_ReadDir
     2912 */
     2913static int rtFsIsoDir_ReadDirIso9660(PRTFSISODIROBJ pThis, PRTFSISODIRSHRD pShared, PRTDIRENTRYEX pDirEntry, size_t *pcbDirEntry,
     2914                                     RTFSOBJATTRADD enmAddAttr)
     2915{
    28572916    while (pThis->offDir + RT_UOFFSETOF(ISO9660DIRREC, achFileId) <= pShared->cbDir)
    28582917    {
     
    28742933                {
    28752934                    *pcbDirEntry = RT_UOFFSETOF(RTDIRENTRYEX, szName) + 2;
    2876                     Log3(("rtFsIsoDir_ReadDir: VERR_BUFFER_OVERFLOW (dot)\n"));
     2935                    Log3(("rtFsIsoDir_ReadDirIso9660: VERR_BUFFER_OVERFLOW (dot)\n"));
    28772936                    return VERR_BUFFER_OVERFLOW;
    28782937                }
     
    28872946                {
    28882947                    *pcbDirEntry = RT_UOFFSETOF(RTDIRENTRYEX, szName) + 3;
    2889                     Log3(("rtFsIsoDir_ReadDir: VERR_BUFFER_OVERFLOW (dot-dot)\n"));
     2948                    Log3(("rtFsIsoDir_ReadDirIso9660: VERR_BUFFER_OVERFLOW (dot-dot)\n"));
    28902949                    return VERR_BUFFER_OVERFLOW;
    28912950                }
     
    29112970                {
    29122971                    *pcbDirEntry = RT_UOFFSETOF(RTDIRENTRYEX, szName) + cchNeeded + 1;
    2913                     Log3(("rtFsIsoDir_ReadDir: VERR_BUFFER_OVERFLOW - cbDst=%zu cchNeeded=%zu (UTF-16BE)\n", cbDst, cchNeeded));
     2972                    Log3(("rtFsIsoDir_ReadDirIso9660: VERR_BUFFER_OVERFLOW - cbDst=%zu cchNeeded=%zu (UTF-16BE)\n", cbDst, cchNeeded));
    29142973                    return VERR_BUFFER_OVERFLOW;
    29152974                }
     
    29352994                if (*pcbDirEntry < cbNeeded)
    29362995                {
    2937                     Log3(("rtFsIsoDir_ReadDir: VERR_BUFFER_OVERFLOW - cbDst=%zu cbNeeded=%zu (ASCII)\n", *pcbDirEntry, cbNeeded));
     2996                    Log3(("rtFsIsoDir_ReadDirIso9660: VERR_BUFFER_OVERFLOW - cbDst=%zu cbNeeded=%zu (ASCII)\n", *pcbDirEntry, cbNeeded));
    29382997                    *pcbDirEntry = cbNeeded;
    29392998                    return VERR_BUFFER_OVERFLOW;
     
    29683027            if (!(pDirRec->fFileFlags & ISO9660_FILE_FLAGS_MULTI_EXTENT))
    29693028            {
    2970                 Log3(("rtFsIsoDir_ReadDir: offDir=%#07x: %s (rc=%Rrc)\n", pThis->offDir, pDirEntry->szName, rc));
     3029                Log3(("rtFsIsoDir_ReadDirIso9660: offDir=%#07x: %s (rc=%Rrc)\n", pThis->offDir, pDirEntry->szName, rc));
    29713030                pThis->offDir += pDirRec->cbDirRec;
    29723031            }
     
    29893048                        offDir = (offDir + pShared->Core.pVol->cbSector) & ~(pShared->Core.pVol->cbSector - 1U);
    29903049                }
    2991                 Log3(("rtFsIsoDir_ReadDir: offDir=%#07x, %u extents ending at %#07x: %s (rc=%Rrc)\n",
     3050                Log3(("rtFsIsoDir_ReadDirIso9660: offDir=%#07x, %u extents ending at %#07x: %s (rc=%Rrc)\n",
    29923051                      pThis->offDir, cExtents, offDir, pDirEntry->szName, rc));
    29933052                pThis->offDir = offDir;
     
    29983057    }
    29993058
    3000     Log3(("rtFsIsoDir_ReadDir: offDir=%#07x: VERR_NO_MORE_FILES\n", pThis->offDir));
     3059    Log3(("rtFsIsoDir_ReadDirIso9660: offDir=%#07x: VERR_NO_MORE_FILES\n", pThis->offDir));
    30013060    return VERR_NO_MORE_FILES;
     3061}
     3062
     3063
     3064/**
     3065 * The UDF worker for rtFsIsoDir_ReadDir
     3066 */
     3067static int rtFsIsoDir_ReadDirUdf(PRTFSISODIROBJ pThis, PRTFSISODIRSHRD pShared, PRTDIRENTRYEX pDirEntry, size_t *pcbDirEntry,
     3068                                 RTFSOBJATTRADD enmAddAttr)
     3069{
     3070    /*
     3071     * At offset zero we've got the '.' entry.  This has to be generated
     3072     * manually as it's not part of the directory content.  The directory
     3073     * offset has to be faked for this too, so offDir == 0 indicates the '.'
     3074     * entry whereas offDir == 1 is the first file id descriptor.
     3075     */
     3076    if (pThis->offDir == 0)
     3077    {
     3078        if (*pcbDirEntry < RT_UOFFSETOF(RTDIRENTRYEX, szName) + 2)
     3079        {
     3080            *pcbDirEntry = RT_UOFFSETOF(RTDIRENTRYEX, szName) + 2;
     3081            Log3(("rtFsIsoDir_ReadDirUdf: VERR_BUFFER_OVERFLOW (dot)\n"));
     3082            return VERR_BUFFER_OVERFLOW;
     3083        }
     3084        pDirEntry->cbName    = 1;
     3085        pDirEntry->szName[0] = '.';
     3086        pDirEntry->szName[1] = '\0';
     3087        pDirEntry->cwcShortName = 0;
     3088        pDirEntry->wszShortName[0] = '\0';
     3089
     3090        int rc = rtFsIsoCore_QueryInfo(&pShared->Core, &pDirEntry->Info, enmAddAttr);
     3091
     3092        Log3(("rtFsIsoDir_ReadDirUdf: offDir=%#07x: %s (rc=%Rrc)\n", pThis->offDir, pDirEntry->szName, rc));
     3093        pThis->offDir = 1;
     3094        return rc;
     3095    }
     3096
     3097    /*
     3098     * Do the directory content.
     3099     */
     3100    while (pThis->offDir + RT_UOFFSETOF(UDFFILEIDDESC, abImplementationUse) <= pShared->cbDir + 1)
     3101    {
     3102        PCUDFFILEIDDESC pFid  = (PCUDFFILEIDDESC)&pShared->pbDir[pThis->offDir - 1];
     3103        uint32_t const  cbFid = UDFFILEIDDESC_GET_SIZE(pFid);
     3104
     3105        if (pThis->offDir + cbFid <= pShared->cbDir + 1)
     3106        { /* likely */ }
     3107        else
     3108            break;
     3109
     3110        /*
     3111         * Do names first as they may cause overflows.
     3112         */
     3113        if (pFid->cbName > 1)
     3114        {
     3115            uint8_t const  *pbName = UDFFILEIDDESC_2_NAME(pFid);
     3116            uint32_t        cbSrc  = pFid->cbName;
     3117            if (*pbName == 8)
     3118            {
     3119                /* Figure out the UTF-8 length first. */
     3120                bool     fSimple = true;
     3121                uint32_t cchDst  = 0;
     3122                for (uint32_t offSrc = 1; offSrc < cbSrc; offSrc++)
     3123                    if (!(pbName[offSrc] & 0x80))
     3124                        cchDst++;
     3125                    else
     3126                    {
     3127                        cchDst += 2;
     3128                        fSimple = false;
     3129                    }
     3130
     3131                size_t cbNeeded = RT_UOFFSETOF(RTDIRENTRYEX, szName) + cchDst + 1;
     3132                if (*pcbDirEntry >= cbNeeded)
     3133                {
     3134                    if (fSimple)
     3135                    {
     3136                        Assert(cbSrc - 1 == cchDst);
     3137                        memcpy(pDirEntry->szName, &pbName[1], cchDst);
     3138                        pDirEntry->szName[cchDst] = '\0';
     3139                    }
     3140                    else
     3141                    {
     3142                        char *pszDst = pDirEntry->szName;
     3143                        for (uint32_t offSrc = 1; offSrc < cbSrc; offSrc++)
     3144                            pszDst = RTStrPutCp(pszDst, pbName[offSrc]);
     3145                        *pszDst = '\0';
     3146                        Assert((size_t)(pszDst - &pDirEntry->szName[0]) == cchDst);
     3147                    }
     3148                }
     3149                else
     3150                {
     3151                    Log3(("rtFsIsoDir_ReadDirUdf: VERR_BUFFER_OVERFLOW - cbDst=%zu cbNeeded=%zu (8-bit)\n", *pcbDirEntry, cbNeeded));
     3152                    *pcbDirEntry = cbNeeded;
     3153                    return VERR_BUFFER_OVERFLOW;
     3154                }
     3155            }
     3156            else
     3157            {
     3158                /* Let RTUtf16BigToUtf8Ex do the bounds checking. */
     3159                char  *pszDst    = pDirEntry->szName;
     3160                size_t cbDst     = *pcbDirEntry - RT_UOFFSETOF(RTDIRENTRYEX, szName);
     3161                size_t cchNeeded = 0;
     3162                int    rc;
     3163                if (*pbName == 16)
     3164                    rc = RTUtf16BigToUtf8Ex((PCRTUTF16)(pbName + 1), (cbSrc - 1) / sizeof(RTUTF16), &pszDst, cbDst, &cchNeeded);
     3165                else
     3166                    rc = VERR_INVALID_NAME;
     3167                if (RT_SUCCESS(rc))
     3168                    pDirEntry->cbName = (uint16_t)cchNeeded;
     3169                else if (rc == VERR_BUFFER_OVERFLOW)
     3170                {
     3171                    *pcbDirEntry = RT_UOFFSETOF(RTDIRENTRYEX, szName) + cchNeeded + 1;
     3172                    Log3(("rtFsIsoDir_ReadDirUdf: VERR_BUFFER_OVERFLOW - cbDst=%zu cchNeeded=%zu (16-bit)\n", cbDst, cchNeeded));
     3173                    return VERR_BUFFER_OVERFLOW;
     3174                }
     3175                else
     3176                {
     3177                    LogRelMax(90, ("ISO/UDF: Malformed directory entry name at %#x: %.*Rhxs\n", pThis->offDir - 1, cbSrc, pbName));
     3178                    ssize_t cchNeeded2 = RTStrPrintf2(pszDst, cbDst, "bad-name-%#x", pThis->offDir - 1);
     3179                    if (cchNeeded2 >= 0)
     3180                        pDirEntry->cbName = (uint16_t)cchNeeded2;
     3181                    else
     3182                    {
     3183                        *pcbDirEntry = RT_UOFFSETOF(RTDIRENTRYEX, szName) + (size_t)-cchNeeded2;
     3184                        return VERR_BUFFER_OVERFLOW;
     3185                    }
     3186                }
     3187            }
     3188        }
     3189        else if (pFid->fFlags & UDF_FILE_FLAGS_PARENT)
     3190        {
     3191            size_t cbNeeded = RT_UOFFSETOF(RTDIRENTRYEX, szName) + 2 + 1;
     3192            if (*pcbDirEntry < cbNeeded)
     3193            {
     3194                Log3(("rtFsIsoDir_ReadDirUdf: VERR_BUFFER_OVERFLOW - cbDst=%zu cbNeeded=%zu (dot-dot)\n", *pcbDirEntry, cbNeeded));
     3195                *pcbDirEntry = cbNeeded;
     3196                return VERR_BUFFER_OVERFLOW;
     3197            }
     3198            pDirEntry->cbName    = 2;
     3199            pDirEntry->szName[0] = '.';
     3200            pDirEntry->szName[1] = '.';
     3201            pDirEntry->szName[2] = '\0';
     3202        }
     3203        else
     3204        {
     3205            size_t cbNeeded = RT_UOFFSETOF(RTDIRENTRYEX, szName) + 1;
     3206            if (*pcbDirEntry < cbNeeded)
     3207            {
     3208                Log3(("rtFsIsoDir_ReadDirUdf: VERR_BUFFER_OVERFLOW - cbDst=%zu cbNeeded=%zu (empty)\n", *pcbDirEntry, cbNeeded));
     3209                *pcbDirEntry = cbNeeded;
     3210                return VERR_BUFFER_OVERFLOW;
     3211            }
     3212            pDirEntry->cbName    = 0;
     3213            pDirEntry->szName[0] = '\0';
     3214        }
     3215
     3216        pDirEntry->cwcShortName    = 0;
     3217        pDirEntry->wszShortName[0] = '\0';
     3218
     3219        /*
     3220         * To avoid duplicating code in rtFsIsoCore_InitUdf and
     3221         * rtFsIsoCore_QueryInfo, we create a dummy RTFSISOCORE on the stack.
     3222         */
     3223        RTFSISOCORE TmpObj;
     3224        RT_ZERO(TmpObj);
     3225        int rc = rtFsIsoCore_InitFromUdfIcbAndFileIdDesc(&TmpObj, &pFid->Icb, pFid, pShared->Core.pVol);
     3226        if (RT_SUCCESS(rc))
     3227        {
     3228            rc = rtFsIsoCore_QueryInfo(&TmpObj, &pDirEntry->Info, enmAddAttr);
     3229            rtFsIsoCore_Destroy(&TmpObj);
     3230        }
     3231
     3232        /*
     3233         * Update.
     3234         */
     3235        Log3(("rtFsIsoDir_ReadDirUdf: offDir=%#07x: %s (rc=%Rrc)\n", pThis->offDir, pDirEntry->szName, rc));
     3236        pThis->offDir += cbFid;
     3237
     3238        return rc;
     3239    }
     3240
     3241    Log3(("rtFsIsoDir_ReadDirUdf: offDir=%#07x: VERR_NO_MORE_FILES\n", pThis->offDir));
     3242    return VERR_NO_MORE_FILES;
     3243}
     3244
     3245
     3246/**
     3247 * @interface_method_impl{RTVFSDIROPS,pfnReadDir}
     3248 */
     3249static DECLCALLBACK(int) rtFsIsoDir_ReadDir(void *pvThis, PRTDIRENTRYEX pDirEntry, size_t *pcbDirEntry,
     3250                                            RTFSOBJATTRADD enmAddAttr)
     3251{
     3252    PRTFSISODIROBJ  pThis   = (PRTFSISODIROBJ)pvThis;
     3253    PRTFSISODIRSHRD pShared = pThis->pShared;
     3254    if (pShared->Core.pVol->enmType != RTFSISOVOLTYPE_UDF)
     3255        return rtFsIsoDir_ReadDirIso9660(pThis, pShared, pDirEntry, pcbDirEntry, enmAddAttr);
     3256    return rtFsIsoDir_ReadDirUdf(pThis, pShared, pDirEntry, pcbDirEntry, enmAddAttr);
    30023257}
    30033258
     
    32113466
    32123467
     3468#ifdef LOG_ENABLED
     3469/**
     3470 * Logs the content of a directory.
     3471 */
     3472static void rtFsIsoDirShrd_LogUdfContent(PRTFSISODIRSHRD pThis)
     3473{
     3474    if (LogIs2Enabled())
     3475    {
     3476        uint32_t offDesc = 0;
     3477        while (offDesc + RT_OFFSETOF(UDFFILEIDDESC, abImplementationUse) < pThis->cbDir)
     3478        {
     3479            PCUDFFILEIDDESC pFid  = (PCUDFFILEIDDESC)&pThis->pbDir[offDesc];
     3480            uint32_t const  cbFid = UDFFILEIDDESC_GET_SIZE(pFid);
     3481            if (offDesc + cbFid > pThis->cbDir)
     3482                break;
     3483
     3484            uint32_t    cwcName = 0;
     3485            RTUTF16     wszName[260];
     3486            if (pFid->cbName > 0)
     3487            {
     3488                uint8_t const *pbName = UDFFILEIDDESC_2_NAME(pFid);
     3489                uint32_t       offSrc = 1;
     3490                if (*pbName == 8)
     3491                    while (offSrc < pFid->cbName)
     3492                    {
     3493                        wszName[cwcName] = pbName[offSrc];
     3494                        cwcName++;
     3495                        offSrc++;
     3496                    }
     3497                else if (*pbName == 16)
     3498                    while (offSrc + 1 <= pFid->cbName)
     3499                    {
     3500                        wszName[cwcName] = RT_MAKE_U16(pbName[offSrc + 1], pbName[offSrc]);
     3501                        cwcName++;
     3502                        offSrc += 2;
     3503                    }
     3504                else
     3505                {
     3506                    RTUtf16CopyAscii(wszName, RT_ELEMENTS(wszName), "<bad type>");
     3507                    cwcName = 10;
     3508                }
     3509            }
     3510            else if (pFid->fFlags & UDF_FILE_FLAGS_PARENT)
     3511            {
     3512                wszName[0] = '.';
     3513                wszName[1] = '.';
     3514                cwcName    = 2;
     3515            }
     3516            else
     3517            {
     3518                RTUtf16CopyAscii(wszName, RT_ELEMENTS(wszName), "<empty>");
     3519                cwcName = 7;
     3520            }
     3521            wszName[cwcName] = '\0';
     3522
     3523            Log2(("ISO/UDF: %04x: fFlags=%#x uVer=%u Icb={%#04x:%#010RX32 LB %#06x t=%u} cbName=%#04x cbIU=%#x '%ls'\n",
     3524                  offDesc,
     3525                  pFid->fFlags,
     3526                  pFid->uVersion,
     3527                  pFid->Icb.Location.uPartitionNo,
     3528                  pFid->Icb.Location.off,
     3529                  pFid->Icb.cb,
     3530                  pFid->Icb.uType,
     3531                  pFid->cbName,
     3532                  pFid->cbImplementationUse,
     3533                  wszName));
     3534            int rc = rtFsIsoVolValidateUdfDescTagAndCrc(&pFid->Tag, pThis->cbDir - offDesc,
     3535                                                        UDF_TAG_ID_FILE_ID_DESC, pFid->Tag.offTag, NULL);
     3536            if (RT_FAILURE(rc))
     3537                Log2(("ISO/UDF:      Bad Tag: %Rrc - idTag=%#x\n", rc, pFid->Tag.idTag));
     3538            if (pFid->cbImplementationUse > 32)
     3539                Log2(("ISO/UDF:      impl use (%#x bytes):\n%.*RhxD\n", pFid->cbImplementationUse, pFid->abImplementationUse));
     3540            else if (pFid->cbImplementationUse > 0)
     3541                Log2(("ISO/UDF:      impl use (%#x bytes): %.*Rhxs\n", pFid->cbImplementationUse, pFid->abImplementationUse));
     3542
     3543            /* advance */
     3544            offDesc += cbFid;
     3545        }
     3546
     3547        if (offDesc < pThis->cbDir)
     3548            Log2(("ISO/UDF:  warning! %#x trailing bytes in directory:\n%.*RhxD\n",
     3549                  pThis->cbDir - offDesc, pThis->cbDir - offDesc, &pThis->pbDir[offDesc]));
     3550    }
     3551}
     3552#endif /* LOG_ENABLED */
     3553
     3554
    32133555/**
    32143556 * Instantiates a new shared directory structure, given UDF descriptors.
     
    32463588                    if (RT_SUCCESS(rc))
    32473589                    {
    3248                         Log3(("ISO/UDF: Directory content\n%.*RhxD\n", pShared->cbDir, pShared->pbDir));
    32493590#ifdef LOG_ENABLED
    3250                         //rtFsIsoDirShrd_Log9660Content(pShared);
     3591                        rtFsIsoDirShrd_LogUdfContent(pShared);
    32513592#endif
    32523593
     
    34653806                if (pTag->offTag == offTag)
    34663807                {
    3467                     Log2(("ISO/UDF: Valid descriptor %#06x at %#010RX32; cbDescriptorCrc=%#06RX32 uTagSerialNo=%#x\n",
    3468                           pTag->idTag, offTag, pTag->cbDescriptorCrc, pTag->uTagSerialNo));
     3808                    //Log3(("ISO/UDF: Valid descriptor %#06x at %#010RX32; cbDescriptorCrc=%#06RX32 uTagSerialNo=%#x\n",
     3809                    //      pTag->idTag, offTag, pTag->cbDescriptorCrc, pTag->uTagSerialNo));
    34693810                    return VINF_SUCCESS;
    34703811                }
     
    52345575     * If we found a UDF VRS and are interested in UDF, we have more work to do here.
    52355576     */
    5236 #if defined(DEBUG_bird) && 0
     5577#if defined(DEBUG_bird) && 1
    52375578    if (uUdfLevel > 0 && !(fFlags & RTFSISO9660_F_NO_UDF) )// && /* Just disable this code for now: */ (fFlags & RT_BIT(24)))
    52385579    {
     
    52635604                                   NULL /*pFileIdDesc*/, &pThis->pRootDir);
    52645605        /** @todo fall back on failure? */
    5265         if (RT_SUCCESS(rc))
    5266             rc = VERR_NOT_IMPLEMENTED;
    52675606        return rc;
    52685607    }
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