Changeset 69035 in vbox for trunk/src/VBox
- Timestamp:
- Oct 11, 2017 9:38:54 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/fs/isovfs.cpp
r69029 r69035 1488 1488 { 1489 1489 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; 1491 1491 } 1492 1492 … … 1587 1587 * Caller must've ZEROed this structure! 1588 1588 * @param pAllocDesc The ICB allocation descriptor. 1589 * @param pFi leIdDescThe file ID descriptor. Optional.1589 * @param pFid The file ID descriptor. Optional. 1590 1590 * @param pVol The instance. 1591 1591 */ 1592 1592 static int rtFsIsoCore_InitFromUdfIcbAndFileIdDesc(PRTFSISOCORE pCore, PCUDFLONGAD pAllocDesc, 1593 PCUDFFILEIDDESC pFi leIdDesc, PRTFSISOVOL pVol)1593 PCUDFFILEIDDESC pFid, PRTFSISOVOL pVol) 1594 1594 { 1595 1595 Assert(pCore->cRefs == 0); … … 1598 1598 Assert(pCore->pVol == NULL); 1599 1599 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 } 1605 1620 1606 1621 /* … … 1618 1633 if (cProcessed > 0) 1619 1634 { 1635 if (pFid && (pFid->fFlags & UDF_FILE_FLAGS_HIDDEN)) 1636 pCore->fAttrib |= RTFS_DOS_HIDDEN; 1637 1620 1638 pCore->cRefs = 1; 1621 1639 pCore->pVol = pVol; … … 1647 1665 static int rtFsIsoVolUdfExtentRead(PRTFSISOCORE pCore, uint64_t offRead, void *pvBuf, size_t cbToRead, size_t *pcbRead) 1648 1666 { 1667 Assert(pCore->pVol->enmType == RTFSISOVOLTYPE_UDF); 1668 1649 1669 /* 1650 1670 * Check for EOF. … … 1896 1916 } 1897 1917 1918 if (pShared->Core.pVol->enmType == RTFSISOVOLTYPE_UDF) 1919 { 1920 return VERR_ISOFS_UDF_NOT_IMPLEMENTED; 1921 } 1898 1922 1899 1923 /* … … 2364 2388 PCISO9660DIRREC *ppDirRec, uint32_t *pcDirRecs, PRTFMODE pfMode, uint32_t *puVersion) 2365 2389 { 2390 Assert(pThis->Core.pVol->enmType != RTFSISOVOLTYPE_UDF); 2391 2366 2392 /* Set return values. */ 2367 2393 *poffDirRec = UINT64_MAX; … … 2602 2628 PRTFSISODIROBJ pThis = (PRTFSISODIROBJ)pvThis; 2603 2629 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 */ 2689 static 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 */ 2752 static 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 */ 2806 static 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 */ 2816 static 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 */ 2826 static 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 */ 2837 static 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 */ 2604 2848 PCISO9660DIRREC pDirRec; 2605 2849 uint64_t offDirRec; … … 2608 2852 uint32_t uVersion; 2609 2853 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)); 2611 2855 if (RT_SUCCESS(rc)) 2612 2856 { 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 } 2640 2870 } 2641 2871 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; 2812 2874 } 2813 2875 return rc; … … 2847 2909 2848 2910 /** 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 */ 2913 static int rtFsIsoDir_ReadDirIso9660(PRTFSISODIROBJ pThis, PRTFSISODIRSHRD pShared, PRTDIRENTRYEX pDirEntry, size_t *pcbDirEntry, 2914 RTFSOBJATTRADD enmAddAttr) 2915 { 2857 2916 while (pThis->offDir + RT_UOFFSETOF(ISO9660DIRREC, achFileId) <= pShared->cbDir) 2858 2917 { … … 2874 2933 { 2875 2934 *pcbDirEntry = RT_UOFFSETOF(RTDIRENTRYEX, szName) + 2; 2876 Log3(("rtFsIsoDir_ReadDir : VERR_BUFFER_OVERFLOW (dot)\n"));2935 Log3(("rtFsIsoDir_ReadDirIso9660: VERR_BUFFER_OVERFLOW (dot)\n")); 2877 2936 return VERR_BUFFER_OVERFLOW; 2878 2937 } … … 2887 2946 { 2888 2947 *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")); 2890 2949 return VERR_BUFFER_OVERFLOW; 2891 2950 } … … 2911 2970 { 2912 2971 *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)); 2914 2973 return VERR_BUFFER_OVERFLOW; 2915 2974 } … … 2935 2994 if (*pcbDirEntry < cbNeeded) 2936 2995 { 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)); 2938 2997 *pcbDirEntry = cbNeeded; 2939 2998 return VERR_BUFFER_OVERFLOW; … … 2968 3027 if (!(pDirRec->fFileFlags & ISO9660_FILE_FLAGS_MULTI_EXTENT)) 2969 3028 { 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)); 2971 3030 pThis->offDir += pDirRec->cbDirRec; 2972 3031 } … … 2989 3048 offDir = (offDir + pShared->Core.pVol->cbSector) & ~(pShared->Core.pVol->cbSector - 1U); 2990 3049 } 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", 2992 3051 pThis->offDir, cExtents, offDir, pDirEntry->szName, rc)); 2993 3052 pThis->offDir = offDir; … … 2998 3057 } 2999 3058 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)); 3001 3060 return VERR_NO_MORE_FILES; 3061 } 3062 3063 3064 /** 3065 * The UDF worker for rtFsIsoDir_ReadDir 3066 */ 3067 static 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 */ 3249 static 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); 3002 3257 } 3003 3258 … … 3211 3466 3212 3467 3468 #ifdef LOG_ENABLED 3469 /** 3470 * Logs the content of a directory. 3471 */ 3472 static 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 3213 3555 /** 3214 3556 * Instantiates a new shared directory structure, given UDF descriptors. … … 3246 3588 if (RT_SUCCESS(rc)) 3247 3589 { 3248 Log3(("ISO/UDF: Directory content\n%.*RhxD\n", pShared->cbDir, pShared->pbDir));3249 3590 #ifdef LOG_ENABLED 3250 //rtFsIsoDirShrd_Log9660Content(pShared);3591 rtFsIsoDirShrd_LogUdfContent(pShared); 3251 3592 #endif 3252 3593 … … 3465 3806 if (pTag->offTag == offTag) 3466 3807 { 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)); 3469 3810 return VINF_SUCCESS; 3470 3811 } … … 5234 5575 * If we found a UDF VRS and are interested in UDF, we have more work to do here. 5235 5576 */ 5236 #if defined(DEBUG_bird) && 05577 #if defined(DEBUG_bird) && 1 5237 5578 if (uUdfLevel > 0 && !(fFlags & RTFSISO9660_F_NO_UDF) )// && /* Just disable this code for now: */ (fFlags & RT_BIT(24))) 5238 5579 { … … 5263 5604 NULL /*pFileIdDesc*/, &pThis->pRootDir); 5264 5605 /** @todo fall back on failure? */ 5265 if (RT_SUCCESS(rc))5266 rc = VERR_NOT_IMPLEMENTED;5267 5606 return rc; 5268 5607 }
Note:
See TracChangeset
for help on using the changeset viewer.