Changeset 66601 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Apr 18, 2017 10:38:18 AM (8 years ago)
- Location:
- trunk/src/VBox/Runtime/common
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp
r66576 r66601 1198 1198 1199 1199 1200 /** @todo Replace RTVfsParsePath with RTPathParse and friends? */ 1200 1201 RTDECL(int) RTVfsParsePath(PRTVFSPARSEDPATH pPath, const char *pszPath, const char *pszCwd) 1201 1202 { … … 1341 1342 * (referenced). 1342 1343 */ 1343 static int rtVfs TraverseToParent(RTVFSINTERNAL *pThis, PRTVFSPARSEDPATH pPath, bool fFollowSymlink,1344 RTVFSDIRINTERNAL **ppVfsParentDir)1344 static int rtVfsDirTraverseToParent(RTVFSDIRINTERNAL *pThis, PRTVFSPARSEDPATH pPath, bool fFollowSymlink, 1345 RTVFSDIRINTERNAL **ppVfsParentDir) 1345 1346 { 1346 1347 /* … … 1348 1349 */ 1349 1350 AssertPtr(pThis); 1350 Assert(pThis->uMagic == RTVFS _MAGIC);1351 Assert(pThis->uMagic == RTVFSDIR_MAGIC); 1351 1352 Assert(pThis->Base.cRefs > 0); 1352 1353 AssertPtr(pPath); … … 1356 1357 1357 1358 /* 1358 * Open the root directory. 1359 */ 1360 /** @todo Union mounts, traversal optimization methods, races, ++ */ 1361 RTVFSDIRINTERNAL *pCurDir; 1362 RTVfsLockAcquireRead(pThis->Base.hLock); 1363 int rc = pThis->pOps->pfnOpenRoot(pThis->Base.pvThis, &pCurDir); 1364 RTVfsLockReleaseRead(pThis->Base.hLock); 1365 if (RT_FAILURE(rc)) 1366 return rc; 1367 Assert(pCurDir->uMagic == RTVFSDIR_MAGIC); 1359 * Start with the pThis directory. 1360 */ 1361 if (RTVfsDirRetain(pThis) == UINT32_MAX) 1362 return VERR_INVALID_HANDLE; 1363 RTVFSDIRINTERNAL *pCurDir = pThis; 1368 1364 1369 1365 /* 1370 1366 * The traversal loop. 1371 1367 */ 1368 int rc = VINF_SUCCESS; 1372 1369 unsigned cLinks = 0; 1373 1370 uint16_t iComponent = 0; … … 1461 1458 if (iRestartComp != iComponent) 1462 1459 { 1463 /* Must restart from the root (optimize this). */1460 /* Must restart from the root. */ 1464 1461 RTVfsDirRelease(pCurDir); 1465 RTVfsLockAcquireRead(pThis->Base.hLock); 1466 rc = pThis->pOps->pfnOpenRoot(pThis->Base.pvThis, &pCurDir); 1467 RTVfsLockReleaseRead(pThis->Base.hLock); 1468 if (RT_FAILURE(rc)) 1462 if (RTVfsDirRetain(pThis) == UINT32_MAX) 1469 1463 { 1464 rc = VERR_INVALID_HANDLE; 1470 1465 pCurDir = NULL; 1471 1466 break; 1472 1467 } 1468 pCurDir = pThis; 1473 1469 iComponent = 0; 1474 1470 } … … 1481 1477 RTVfsDirRelease(pCurDir); 1482 1478 RTVfsLockAcquireRead(hVfsMnt->Base.hLock); 1483 rc = pThis->pOps->pfnOpenRoot(hVfsMnt->Base.pvThis, &pCurDir);1479 rc = hVfsMnt->pOps->pfnOpenRoot(hVfsMnt->Base.pvThis, &pCurDir); 1484 1480 RTVfsLockReleaseRead(hVfsMnt->Base.hLock); 1485 1481 if (RT_FAILURE(rc)) … … 1500 1496 1501 1497 1498 /** 1499 * Internal worker for various open functions as well as RTVfsTraverseToParent. 1500 * 1501 * @returns IPRT status code. 1502 * @param pThis The VFS. 1503 * @param pPath The parsed path. This may be changed as symbolic 1504 * links are processed during the path traversal. 1505 * @param fFollowSymlink Whether to follow the final component if it is a 1506 * symbolic link. 1507 * @param ppVfsParentDir Where to return the parent directory handle 1508 * (referenced). 1509 */ 1510 static int rtVfsTraverseToParent(RTVFSINTERNAL *pThis, PRTVFSPARSEDPATH pPath, bool fFollowSymlink, 1511 RTVFSDIRINTERNAL **ppVfsParentDir) 1512 { 1513 /* 1514 * Assert sanity. 1515 */ 1516 AssertPtr(pThis); 1517 Assert(pThis->uMagic == RTVFS_MAGIC); 1518 Assert(pThis->Base.cRefs > 0); 1519 AssertPtr(pPath); 1520 AssertPtr(ppVfsParentDir); 1521 *ppVfsParentDir = NULL; 1522 AssertReturn(pPath->cComponents > 0, VERR_INTERNAL_ERROR_3); 1523 1524 /* 1525 * Open the root directory and join paths with the directory traversal. 1526 */ 1527 /** @todo Union mounts, traversal optimization methods, races, ++ */ 1528 RTVFSDIRINTERNAL *pRootDir; 1529 RTVfsLockAcquireRead(pThis->Base.hLock); 1530 int rc = pThis->pOps->pfnOpenRoot(pThis->Base.pvThis, &pRootDir); 1531 RTVfsLockReleaseRead(pThis->Base.hLock); 1532 if (RT_SUCCESS(rc)) 1533 { 1534 rc = rtVfsDirTraverseToParent(pRootDir, pPath, fFollowSymlink, ppVfsParentDir); 1535 RTVfsDirRelease(pRootDir); 1536 } 1537 return rc; 1538 } 1539 1540 1502 1541 RTDECL(int) RTVfsUtilDummyPollOne(uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr, uint32_t *pfRetEvents) 1503 1542 { … … 1625 1664 1626 1665 1627 RTDECL(uint32_t) 1666 RTDECL(uint32_t) RTVfsRetain(RTVFS hVfs) 1628 1667 { 1629 1668 RTVFSINTERNAL *pThis = hVfs; … … 1634 1673 1635 1674 1636 RTDECL(uint32_t) 1675 RTDECL(uint32_t) RTVfsRelease(RTVFS hVfs) 1637 1676 { 1638 1677 RTVFSINTERNAL *pThis = hVfs; … … 1645 1684 1646 1685 1647 RTDECL(int) RTVfsIsRangeInUse(RTVFS hVfs, uint64_t off, size_t cb, bool *pfUsed)1686 RTDECL(int) RTVfsOpenRoot(RTVFS hVfs, PRTVFSDIR phDir) 1648 1687 { 1649 1688 RTVFSINTERNAL *pThis = hVfs; 1650 1689 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 1651 1690 AssertReturn(pThis->uMagic == RTVFS_MAGIC, VERR_INVALID_HANDLE); 1691 AssertPtrReturn(phDir, VERR_INVALID_POINTER); 1692 *phDir = NIL_RTVFSDIR; 1652 1693 1653 1694 if (!pThis->pOps->pfnIsRangeInUse) 1654 1695 return VERR_NOT_SUPPORTED; 1655 RTVfsLockAcquireWrite(pThis->Base.hLock); 1696 RTVfsLockAcquireRead(pThis->Base.hLock); 1697 int rc = pThis->pOps->pfnOpenRoot(pThis->Base.pvThis, phDir); 1698 RTVfsLockReleaseRead(pThis->Base.hLock); 1699 1700 return rc; 1701 } 1702 1703 1704 1705 RTDECL(int) RTVfsIsRangeInUse(RTVFS hVfs, uint64_t off, size_t cb, bool *pfUsed) 1706 { 1707 RTVFSINTERNAL *pThis = hVfs; 1708 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 1709 AssertReturn(pThis->uMagic == RTVFS_MAGIC, VERR_INVALID_HANDLE); 1710 1711 if (!pThis->pOps->pfnIsRangeInUse) 1712 return VERR_NOT_SUPPORTED; 1713 RTVfsLockAcquireRead(pThis->Base.hLock); 1656 1714 int rc = pThis->pOps->pfnIsRangeInUse(pThis->Base.pvThis, off, cb, pfUsed); 1657 RTVfsLockReleaseWrite(pThis->Base.hLock); 1658 1659 return rc; 1660 } 1715 RTVfsLockReleaseRead(pThis->Base.hLock); 1716 1717 return rc; 1718 } 1719 1720 1661 1721 1662 1722 … … 1773 1833 */ 1774 1834 1775 RTDECL(uint32_t) 1835 RTDECL(uint32_t) RTVfsDirRetain(RTVFSDIR hVfsDir) 1776 1836 { 1777 1837 RTVFSDIRINTERNAL *pThis = hVfsDir; … … 1782 1842 1783 1843 1784 RTDECL(uint32_t) 1844 RTDECL(uint32_t) RTVfsDirRelease(RTVFSDIR hVfsDir) 1785 1845 { 1786 1846 RTVFSDIRINTERNAL *pThis = hVfsDir; … … 1792 1852 } 1793 1853 1854 1855 RTDECL(int) RTVfsDirOpen(RTVFS hVfs, const char *pszPath, uint32_t fFlags, PRTVFSDIR phVfsDir) 1856 { 1857 /* 1858 * Validate input. 1859 */ 1860 RTVFSINTERNAL *pThis = hVfs; 1861 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 1862 AssertReturn(pThis->uMagic == RTVFS_MAGIC, VERR_INVALID_HANDLE); 1863 AssertPtrReturn(pszPath, VERR_INVALID_POINTER); 1864 AssertPtrReturn(phVfsDir, VERR_INVALID_POINTER); 1865 AssertReturn(!fFlags, VERR_INVALID_FLAGS); 1866 1867 /* 1868 * Parse the path, assume current directory is root since we've got no 1869 * caller context here. 1870 */ 1871 PRTVFSPARSEDPATH pPath; 1872 int rc = RTVfsParsePathA(pszPath, "/", &pPath); 1873 if (RT_SUCCESS(rc)) 1874 { 1875 /* 1876 * Tranverse the path, resolving the parent node and any symlinks 1877 * in the final element, and ask the directory to open the subdir. 1878 */ 1879 RTVFSDIRINTERNAL *pVfsParentDir; 1880 rc = rtVfsTraverseToParent(pThis, pPath, true /*fFollowSymlink*/, &pVfsParentDir); 1881 if (RT_SUCCESS(rc)) 1882 { 1883 const char *pszEntryName = &pPath->szPath[pPath->aoffComponents[pPath->cComponents - 1]]; 1884 1885 /** @todo there is a symlink creation race here. */ 1886 RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock); 1887 rc = pVfsParentDir->pOps->pfnOpenDir(pVfsParentDir->Base.pvThis, pszEntryName, fFlags, phVfsDir); 1888 RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock); 1889 1890 RTVfsDirRelease(pVfsParentDir); 1891 1892 if (RT_SUCCESS(rc)) 1893 { 1894 AssertPtr(*phVfsDir); 1895 Assert((*phVfsDir)->uMagic == RTVFSDIR_MAGIC); 1896 } 1897 } 1898 RTVfsParsePathFree(pPath); 1899 } 1900 return rc; 1901 } 1902 1903 1904 RTDECL(int) RTVfsDirOpenDir(RTVFSDIR hVfsDir, const char *pszPath, uint32_t fFlags, PRTVFSDIR phVfsDir) 1905 { 1906 /* 1907 * Validate input. 1908 */ 1909 RTVFSDIRINTERNAL *pThis = hVfsDir; 1910 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 1911 AssertReturn(pThis->uMagic == RTVFSDIR_MAGIC, VERR_INVALID_HANDLE); 1912 AssertPtrReturn(pszPath, VERR_INVALID_POINTER); 1913 AssertPtrReturn(phVfsDir, VERR_INVALID_POINTER); 1914 AssertReturn(!fFlags, VERR_INVALID_FLAGS); 1915 1916 /* 1917 * Parse the path, it's always relative to the given directory. 1918 */ 1919 PRTVFSPARSEDPATH pPath; 1920 int rc = RTVfsParsePathA(pszPath, "/", &pPath); 1921 if (RT_SUCCESS(rc)) 1922 { 1923 /* 1924 * Tranverse the path, resolving the parent node and any symlinks 1925 * in the final element, and ask the directory to open the subdir. 1926 */ 1927 RTVFSDIRINTERNAL *pVfsParentDir; 1928 rc = rtVfsDirTraverseToParent(pThis, pPath, true /*fFollowSymlink*/, &pVfsParentDir); 1929 if (RT_SUCCESS(rc)) 1930 { 1931 const char *pszEntryName = &pPath->szPath[pPath->aoffComponents[pPath->cComponents - 1]]; 1932 1933 /** @todo there is a symlink creation race here. */ 1934 RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock); 1935 rc = pVfsParentDir->pOps->pfnOpenDir(pVfsParentDir->Base.pvThis, pszEntryName, fFlags, phVfsDir); 1936 RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock); 1937 1938 RTVfsDirRelease(pVfsParentDir); 1939 1940 if (RT_SUCCESS(rc)) 1941 { 1942 AssertPtr(*phVfsDir); 1943 Assert((*phVfsDir)->uMagic == RTVFSDIR_MAGIC); 1944 } 1945 } 1946 RTVfsParsePathFree(pPath); 1947 } 1948 return rc; 1949 } 1950 1951 1952 RTDECL(int) RTVfsDirOpenFile(RTVFSDIR hVfsDir, const char *pszPath, uint64_t fOpen, PRTVFSFILE phVfsFile) 1953 { 1954 /* 1955 * Validate input. 1956 */ 1957 RTVFSDIRINTERNAL *pThis = hVfsDir; 1958 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 1959 AssertReturn(pThis->uMagic == RTVFSDIR_MAGIC, VERR_INVALID_HANDLE); 1960 AssertPtrReturn(pszPath, VERR_INVALID_POINTER); 1961 AssertPtrReturn(phVfsFile, VERR_INVALID_POINTER); 1962 1963 int rc = rtFileRecalcAndValidateFlags(&fOpen); 1964 if (RT_FAILURE(rc)) 1965 return rc; 1966 1967 /* 1968 * Parse the path, assume current directory is root since we've got no 1969 * caller context here. 1970 */ 1971 PRTVFSPARSEDPATH pPath; 1972 rc = RTVfsParsePathA(pszPath, "/", &pPath); 1973 if (RT_SUCCESS(rc)) 1974 { 1975 if (!pPath->fDirSlash) 1976 { 1977 /* 1978 * Tranverse the path, resolving the parent node and any symlinks 1979 * in the final element, and ask the directory to open the file. 1980 */ 1981 RTVFSDIRINTERNAL *pVfsParentDir; 1982 rc = rtVfsDirTraverseToParent(pThis, pPath, true /*fFollowSymlink*/, &pVfsParentDir); 1983 if (RT_SUCCESS(rc)) 1984 { 1985 const char *pszEntryName = &pPath->szPath[pPath->aoffComponents[pPath->cComponents - 1]]; 1986 1987 /** @todo there is a symlink creation race here. */ 1988 RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock); 1989 rc = pVfsParentDir->pOps->pfnOpenFile(pVfsParentDir->Base.pvThis, pszEntryName, fOpen, phVfsFile); 1990 RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock); 1991 1992 RTVfsDirRelease(pVfsParentDir); 1993 1994 if (RT_SUCCESS(rc)) 1995 { 1996 AssertPtr(*phVfsFile); 1997 Assert((*phVfsFile)->uMagic == RTVFSFILE_MAGIC); 1998 } 1999 } 2000 } 2001 else 2002 rc = VERR_INVALID_PARAMETER; 2003 RTVfsParsePathFree(pPath); 2004 } 2005 return rc; 2006 } 1794 2007 1795 2008 … … 2433 2646 2434 2647 2435 RTDECL(int) 2648 RTDECL(int) RTVfsFileOpen(RTVFS hVfs, const char *pszFilename, uint64_t fOpen, PRTVFSFILE phVfsFile) 2436 2649 { 2437 2650 /* -
trunk/src/VBox/Runtime/common/vfs/vfschain.cpp
r66594 r66601 48 48 49 49 50 /********************************************************************************************************************************* 51 * Internal Functions * 52 *********************************************************************************************************************************/ 53 static PCRTVFSCHAINELEMENTREG rtVfsChainFindProviderLocked(const char *pszProvider); 54 50 55 51 56 /********************************************************************************************************************************* … … 61 66 62 67 68 RTDECL(int) RTVfsChainValidateOpenFileOrIoStream(PRTVFSCHAINSPEC pSpec, PRTVFSCHAINELEMSPEC pElement, uint32_t *poffError) 69 { 70 if (pElement->cArgs < 1) 71 return VERR_VFS_CHAIN_AT_LEAST_ONE_ARG; 72 if (pElement->cArgs > 4) 73 return VERR_VFS_CHAIN_AT_MOST_FOUR_ARGS; 74 if (!*pElement->paArgs[0].psz) 75 return VERR_VFS_CHAIN_EMPTY_ARG; 76 77 /* 78 * Calculate the flags, storing them in the first argument. 79 */ 80 const char *pszAccess = pElement->cArgs >= 2 ? pElement->paArgs[1].psz : ""; 81 if (!*pszAccess) 82 pszAccess = (pSpec->fOpenFile & RTFILE_O_ACCESS_MASK) == RTFILE_O_READWRITE ? "rw" 83 : (pSpec->fOpenFile & RTFILE_O_ACCESS_MASK) == RTFILE_O_READ ? "r" 84 : (pSpec->fOpenFile & RTFILE_O_ACCESS_MASK) == RTFILE_O_WRITE ? "w" 85 : "rw"; 86 87 const char *pszDisp = pElement->cArgs >= 3 ? pElement->paArgs[2].psz : ""; 88 if (!*pszDisp) 89 pszDisp = strchr(pszAccess, 'w') != NULL ? "open-create" : "open"; 90 91 const char *pszSharing = pElement->cArgs >= 4 ? pElement->paArgs[3].psz : ""; 92 93 int rc = RTFileModeToFlagsEx(pszAccess, pszDisp, pszSharing, &pElement->uProvider); 94 if (RT_SUCCESS(rc)) 95 return VINF_SUCCESS; 96 97 /* 98 * Now try figure out which argument offended us. 99 */ 100 AssertReturn(pElement->cArgs > 1, VERR_VFS_CHAIN_IPE); 101 if ( pElement->cArgs == 2 102 || RT_FAILURE(RTFileModeToFlagsEx(pszAccess, "open-create", "", &pElement->uProvider))) 103 *poffError = pElement->paArgs[1].offSpec; 104 else if ( pElement->cArgs == 3 105 || RT_FAILURE(RTFileModeToFlagsEx(pszAccess, pszDisp, "", &pElement->uProvider))) 106 *poffError = pElement->paArgs[2].offSpec; 107 else 108 *poffError = pElement->paArgs[3].offSpec; 109 return VERR_VFS_CHAIN_INVALID_ARGUMENT; 110 } 111 112 113 /** 114 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnValidate} 115 */ 116 static DECLCALLBACK(int) rtVfsChainOpen_Validate(PCRTVFSCHAINELEMENTREG pProviderReg, PRTVFSCHAINSPEC pSpec, 117 PRTVFSCHAINELEMSPEC pElement, uint32_t *poffError) 118 { 119 RT_NOREF(pProviderReg); 120 121 /* 122 * Basic checks. 123 */ 124 if ( pElement->enmType != RTVFSOBJTYPE_DIR 125 && pElement->enmType != RTVFSOBJTYPE_FILE 126 && pElement->enmType != RTVFSOBJTYPE_IO_STREAM) 127 return VERR_VFS_CHAIN_ONLY_FILE_OR_IOS_OR_DIR; 128 if ( pElement->enmTypeIn != RTVFSOBJTYPE_DIR 129 && pElement->enmTypeIn != RTVFSOBJTYPE_FS_STREAM 130 && pElement->enmTypeIn != RTVFSOBJTYPE_VFS) 131 { 132 if (pElement->enmTypeIn == RTVFSOBJTYPE_INVALID) 133 { 134 /* 135 * First element: Ttransform into 'stdfile' or 'stddir' if registered. 136 */ 137 const char *pszNewProvider = pElement->enmType == RTVFSOBJTYPE_DIR ? "stddir" : "stdfile"; 138 PCRTVFSCHAINELEMENTREG pNewProvider = rtVfsChainFindProviderLocked(pszNewProvider); 139 if (pNewProvider) 140 { 141 pElement->pProvider = pNewProvider; 142 return pNewProvider->pfnValidate(pNewProvider, pSpec, pElement, poffError); 143 } 144 return VERR_VFS_CHAIN_CANNOT_BE_FIRST_ELEMENT; 145 } 146 return VERR_VFS_CHAIN_TAKES_DIR_OR_FSS_OR_VFS; 147 } 148 149 /* 150 * Make common cause with 'stdfile' if we're opening a file or I/O stream. 151 * If the input is a FSS, we have to make sure it's a read-only operation. 152 */ 153 if ( pElement->enmType != RTVFSOBJTYPE_FILE 154 && pElement->enmType != RTVFSOBJTYPE_IO_STREAM) 155 { 156 int rc = RTVfsChainValidateOpenFileOrIoStream(pSpec, pElement, poffError); 157 if (RT_SUCCESS(rc)) 158 { 159 if (pElement->enmTypeIn != RTVFSOBJTYPE_FS_STREAM) 160 return VINF_SUCCESS; 161 if ( !(pElement->uProvider & RTFILE_O_WRITE) 162 && (pElement->uProvider & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN) 163 return VINF_SUCCESS; 164 *poffError = pElement->cArgs > 1 ? pElement->paArgs[1].offSpec : pElement->offSpec; 165 return VERR_VFS_CHAIN_INVALID_ARGUMENT; 166 } 167 } 168 169 /* 170 * Directory checks. Path argument only, optional. If not given the root directory of a VFS or the 171 */ 172 if (pElement->cArgs > 1) 173 return VERR_VFS_CHAIN_AT_MOST_ONE_ARG; 174 return VINF_SUCCESS; 175 } 176 177 178 /** 179 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnInstantiate} 180 */ 181 static DECLCALLBACK(int) rtVfsChainOpen_Instantiate(PCRTVFSCHAINELEMENTREG pProviderReg, PCRTVFSCHAINSPEC pSpec, 182 PCRTVFSCHAINELEMSPEC pElement, RTVFSOBJ hPrevVfsObj, 183 PRTVFSOBJ phVfsObj, uint32_t *poffError) 184 { 185 RT_NOREF(pProviderReg, pSpec, pElement, poffError); 186 AssertReturn(hPrevVfsObj != NIL_RTVFSOBJ, VERR_VFS_CHAIN_IPE); 187 188 /* 189 * File system stream: Seek thru the stream looking for the object to open. 190 */ 191 RTVFSFSSTREAM hVfsFssIn = RTVfsObjToFsStream(hPrevVfsObj); 192 if (hVfsFssIn != NIL_RTVFSFSSTREAM) 193 { 194 return VERR_NOT_IMPLEMENTED; 195 } 196 197 /* 198 * VFS: Use RTVfsFileOpen or RTVfsDirOpen. 199 */ 200 RTVFS hVfsIn = RTVfsObjToVfs(hPrevVfsObj); 201 if (hVfsIn != NIL_RTVFS) 202 { 203 if ( pElement->enmType == RTVFSOBJTYPE_FILE 204 || pElement->enmType == RTVFSOBJTYPE_IO_STREAM) 205 { 206 RTVFSFILE hVfsFile = NIL_RTVFSFILE; 207 int rc = RTVfsFileOpen(hVfsIn, pElement->paArgs[0].psz, pElement->uProvider, &hVfsFile); 208 if (RT_SUCCESS(rc)) 209 { 210 *phVfsObj = RTVfsObjFromFile(hVfsFile); 211 RTVfsFileRelease(hVfsFile); 212 if (*phVfsObj != NIL_RTVFSOBJ) 213 return VINF_SUCCESS; 214 rc = VERR_VFS_CHAIN_CAST_FAILED; 215 } 216 return rc; 217 } 218 if (pElement->enmType == RTVFSOBJTYPE_DIR) 219 { 220 RTVFSDIR hVfsDir = NIL_RTVFSDIR; 221 int rc = RTVfsDirOpen(hVfsIn, pElement->paArgs[0].psz, (uint32_t)pElement->uProvider, &hVfsDir); 222 if (RT_SUCCESS(rc)) 223 { 224 *phVfsObj = RTVfsObjFromDir(hVfsDir); 225 RTVfsDirRelease(hVfsDir); 226 if (*phVfsObj != NIL_RTVFSOBJ) 227 return VINF_SUCCESS; 228 rc = VERR_VFS_CHAIN_CAST_FAILED; 229 } 230 return rc; 231 } 232 return VERR_VFS_CHAIN_IPE; 233 } 234 235 /* 236 * Directory: Similar to above, just relative to a directory. 237 */ 238 RTVFSDIR hVfsDirIn = RTVfsObjToDir(hPrevVfsObj); 239 if (hVfsDirIn != NIL_RTVFSDIR) 240 { 241 if ( pElement->enmType == RTVFSOBJTYPE_FILE 242 || pElement->enmType == RTVFSOBJTYPE_IO_STREAM) 243 { 244 RTVFSFILE hVfsFile = NIL_RTVFSFILE; 245 int rc = RTVfsDirOpenFile(hVfsDirIn, pElement->paArgs[0].psz, pElement->uProvider, &hVfsFile); 246 if (RT_SUCCESS(rc)) 247 { 248 *phVfsObj = RTVfsObjFromFile(hVfsFile); 249 RTVfsFileRelease(hVfsFile); 250 if (*phVfsObj != NIL_RTVFSOBJ) 251 return VINF_SUCCESS; 252 rc = VERR_VFS_CHAIN_CAST_FAILED; 253 } 254 return rc; 255 } 256 if (pElement->enmType == RTVFSOBJTYPE_DIR) 257 { 258 RTVFSDIR hVfsDir = NIL_RTVFSDIR; 259 int rc = RTVfsDirOpenDir(hVfsDirIn, pElement->paArgs[0].psz, pElement->uProvider, &hVfsDir); 260 if (RT_SUCCESS(rc)) 261 { 262 *phVfsObj = RTVfsObjFromDir(hVfsDir); 263 RTVfsDirRelease(hVfsDir); 264 if (*phVfsObj != NIL_RTVFSOBJ) 265 return VINF_SUCCESS; 266 rc = VERR_VFS_CHAIN_CAST_FAILED; 267 } 268 return rc; 269 } 270 return VERR_VFS_CHAIN_IPE; 271 } 272 273 AssertFailed(); 274 return VERR_VFS_CHAIN_CAST_FAILED; 275 } 276 277 278 /** 279 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnCanReuseElement} 280 */ 281 static DECLCALLBACK(bool) rtVfsChainOpen_CanReuseElement(PCRTVFSCHAINELEMENTREG pProviderReg, 282 PCRTVFSCHAINSPEC pSpec, PCRTVFSCHAINELEMSPEC pElement, 283 PCRTVFSCHAINSPEC pReuseSpec, PCRTVFSCHAINELEMSPEC pReuseElement) 284 { 285 RT_NOREF(pProviderReg, pSpec, pElement, pReuseSpec, pReuseElement); 286 return false; 287 } 288 289 290 /** VFS chain element 'gunzip'. */ 291 static RTVFSCHAINELEMENTREG g_rtVfsChainGunzipReg = 292 { 293 /* uVersion = */ RTVFSCHAINELEMENTREG_VERSION, 294 /* fReserved = */ 0, 295 /* pszName = */ "open", 296 /* ListEntry = */ { NULL, NULL }, 297 /* pszHelp = */ "Generic VFS open, that can open files (or I/O stream) and directories in a VFS, directory or file system stream.\n" 298 "If used as the first element in a chain, it will work like 'stdfile' or 'stddir' and work on the real file system.\n" 299 "First argument is the filename or directory path.\n" 300 "Second argument is access mode, files only, optional: r, w, rw.\n" 301 "Third argument is open disposition, files only, optional: create, create-replace, open, open-create, open-append, open-truncate.\n" 302 "Forth argument is file sharing, files only, optional: nr, nw, nrw, d.", 303 /* pfnValidate = */ rtVfsChainOpen_Validate, 304 /* pfnInstantiate = */ rtVfsChainOpen_Instantiate, 305 /* pfnCanReuseElement = */ rtVfsChainOpen_CanReuseElement, 306 /* uEndMarker = */ RTVFSCHAINELEMENTREG_VERSION 307 }; 308 309 RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER(&g_rtVfsChainGunzipReg, rtVfsChainGunzipReg); 310 311 312 63 313 64 314 /** … … 155 405 pSpec->fOpenDir = 0; 156 406 pSpec->cElements = 0; 157 pSpec->uProvider = 0;158 407 pSpec->paElements = NULL; 159 408 } … … 628 877 { 629 878 PRTVFSCHAINELEMSPEC const pElement = &pSpec->paElements[i]; 879 *poffError = pElement->offSpec; 630 880 631 881 /* … … 862 1112 } 863 1113 1114 -
trunk/src/VBox/Runtime/common/vfs/vfsreadahead.cpp
r66598 r66601 826 826 * Basics. 827 827 */ 828 if (pElement->enmTypeIn == RTVFSOBJTYPE_INVALID)829 return VERR_VFS_CHAIN_CANNOT_BE_FIRST_ELEMENT;830 if (pElement->cArgs > 2)831 return VERR_VFS_CHAIN_AT_MOST_TWO_ARGS;832 828 if ( pElement->enmType != RTVFSOBJTYPE_FILE 833 829 && pElement->enmType != RTVFSOBJTYPE_IO_STREAM) 834 830 return VERR_VFS_CHAIN_ONLY_FILE_OR_IOS; 831 if (pElement->enmTypeIn == RTVFSOBJTYPE_INVALID) 832 return VERR_VFS_CHAIN_CANNOT_BE_FIRST_ELEMENT; 833 if ( pElement->enmTypeIn != RTVFSOBJTYPE_FILE 834 && pElement->enmTypeIn != RTVFSOBJTYPE_IO_STREAM) 835 return VERR_VFS_CHAIN_TAKES_FILE_OR_IOS; 835 836 if (pSpec->fOpenFile & RTFILE_O_WRITE) 836 837 return VERR_VFS_CHAIN_READ_ONLY_IOS; 838 if (pElement->cArgs > 2) 839 return VERR_VFS_CHAIN_AT_MOST_TWO_ARGS; 837 840 838 841 /* … … 872 875 * Save the parsed arguments in the spec since their both optional. 873 876 */ 874 p Spec->uProvider = RT_MAKE_U64(cBuffers, cbBuffer);877 pElement->uProvider = RT_MAKE_U64(cBuffers, cbBuffer); 875 878 876 879 return VINF_SUCCESS; … … 894 897 { 895 898 RTVFSFILE hVfsFile = NIL_RTVFSFILE; 896 rc = RTVfsCreateReadAheadForFile(hVfsFileIn, 0 /*fFlags*/, RT_LO_U32(p Spec->uProvider),897 RT_HI_U32(p Spec->uProvider), &hVfsFile);899 rc = RTVfsCreateReadAheadForFile(hVfsFileIn, 0 /*fFlags*/, RT_LO_U32(pElement->uProvider), 900 RT_HI_U32(pElement->uProvider), &hVfsFile); 898 901 RTVfsFileRelease(hVfsFileIn); 899 902 if (RT_SUCCESS(rc)) … … 912 915 { 913 916 RTVFSIOSTREAM hVfsIos = NIL_RTVFSIOSTREAM; 914 rc = RTVfsCreateReadAheadForIoStream(hVfsIosIn, 0 /*fFlags*/, RT_LO_U32(p Spec->uProvider),915 RT_HI_U32(p Spec->uProvider), &hVfsIos);917 rc = RTVfsCreateReadAheadForIoStream(hVfsIosIn, 0 /*fFlags*/, RT_LO_U32(pElement->uProvider), 918 RT_HI_U32(pElement->uProvider), &hVfsIos); 916 919 RTVfsIoStrmRelease(hVfsIosIn); 917 920 if (RT_SUCCESS(rc)) -
trunk/src/VBox/Runtime/common/vfs/vfsstdfile.cpp
r66594 r66601 526 526 if (pElement->enmTypeIn != RTVFSOBJTYPE_INVALID) 527 527 return VERR_VFS_CHAIN_MUST_BE_FIRST_ELEMENT; 528 if (pElement->cArgs < 1)529 return VERR_VFS_CHAIN_AT_LEAST_ONE_ARG;530 if (pElement->cArgs > 4)531 return VERR_VFS_CHAIN_AT_MOST_FOUR_ARGS;532 if (!*pElement->paArgs[0].psz)533 return VERR_VFS_CHAIN_EMPTY_ARG;534 528 if ( pElement->enmType != RTVFSOBJTYPE_FILE 535 529 && pElement->enmType != RTVFSOBJTYPE_IO_STREAM) 536 530 return VERR_VFS_CHAIN_ONLY_FILE_OR_IOS; 537 531 532 538 533 /* 539 * Calculate the flags, storing them in the first argument.534 * Join common cause with the 'open' provider. 540 535 */ 541 const char *pszAccess = pElement->cArgs >= 2 ? pElement->paArgs[1].psz : ""; 542 if (!*pszAccess) 543 pszAccess = (pSpec->fOpenFile & RTFILE_O_ACCESS_MASK) == RTFILE_O_READWRITE ? "rw" 544 : (pSpec->fOpenFile & RTFILE_O_ACCESS_MASK) == RTFILE_O_READ ? "r" 545 : (pSpec->fOpenFile & RTFILE_O_ACCESS_MASK) == RTFILE_O_WRITE ? "w" 546 : "rw"; 547 548 const char *pszDisp = pElement->cArgs >= 3 ? pElement->paArgs[2].psz : ""; 549 if (!*pszDisp) 550 pszDisp = strchr(pszAccess, 'w') != NULL ? "open-create" : "open"; 551 552 const char *pszSharing = pElement->cArgs >= 4 ? pElement->paArgs[3].psz : ""; 553 554 int rc = RTFileModeToFlagsEx(pszAccess, pszDisp, pszSharing, &pElement->paArgs[0].uProvider); 555 if (RT_SUCCESS(rc)) 556 return VINF_SUCCESS; 557 558 /* 559 * Now try figure out which argument offended us. 560 */ 561 AssertReturn(pElement->cArgs > 1, VERR_VFS_CHAIN_IPE); 562 if ( pElement->cArgs == 2 563 || RT_FAILURE(RTFileModeToFlagsEx(pszAccess, "open-create", "", &pElement->paArgs[0].uProvider))) 564 *poffError = pElement->paArgs[1].offSpec; 565 else if ( pElement->cArgs == 3 566 || RT_FAILURE(RTFileModeToFlagsEx(pszAccess, pszDisp, "", &pElement->paArgs[0].uProvider))) 567 *poffError = pElement->paArgs[2].offSpec; 568 else 569 *poffError = pElement->paArgs[3].offSpec; 570 return VERR_VFS_CHAIN_INVALID_ARGUMENT; 536 return RTVfsChainValidateOpenFileOrIoStream(pSpec, pElement, poffError); 571 537 } 572 538 … … 583 549 584 550 RTVFSFILE hVfsFile; 585 int rc = RTVfsFileOpenNormal(pElement->paArgs[0].psz, pElement-> paArgs[0].uProvider, &hVfsFile);551 int rc = RTVfsFileOpenNormal(pElement->paArgs[0].psz, pElement->uProvider, &hVfsFile); 586 552 if (RT_SUCCESS(rc)) 587 553 { -
trunk/src/VBox/Runtime/common/zip/gzipvfs.cpp
r66596 r66601 839 839 RT_NOREF(pProviderReg, poffError); 840 840 841 if (pElement->enmType != RTVFSOBJTYPE_IO_STREAM) 842 return VERR_VFS_CHAIN_ONLY_IOS; 841 843 if (pElement->enmTypeIn == RTVFSOBJTYPE_INVALID) 842 844 return VERR_VFS_CHAIN_CANNOT_BE_FIRST_ELEMENT; 845 if ( pElement->enmTypeIn != RTVFSOBJTYPE_FILE 846 && pElement->enmTypeIn != RTVFSOBJTYPE_IO_STREAM) 847 return VERR_VFS_CHAIN_TAKES_FILE_OR_IOS; 848 if (pSpec->fOpenFile & RTFILE_O_WRITE) 849 return VERR_VFS_CHAIN_READ_ONLY_IOS; 843 850 if (pElement->cArgs != 0) 844 851 return VERR_VFS_CHAIN_NO_ARGS; 845 if (pElement->enmType != RTVFSOBJTYPE_IO_STREAM)846 return VERR_VFS_CHAIN_ONLY_IOS;847 if (pSpec->fOpenFile & RTFILE_O_WRITE)848 return VERR_VFS_CHAIN_READ_ONLY_IOS;849 852 850 853 return VINF_SUCCESS; … … 922 925 * Basics. 923 926 */ 927 if (pElement->enmType != RTVFSOBJTYPE_IO_STREAM) 928 return VERR_VFS_CHAIN_ONLY_IOS; 924 929 if (pElement->enmTypeIn == RTVFSOBJTYPE_INVALID) 925 930 return VERR_VFS_CHAIN_CANNOT_BE_FIRST_ELEMENT; 931 if ( pElement->enmTypeIn != RTVFSOBJTYPE_FILE 932 && pElement->enmTypeIn != RTVFSOBJTYPE_IO_STREAM) 933 return VERR_VFS_CHAIN_TAKES_FILE_OR_IOS; 934 if (pSpec->fOpenFile & RTFILE_O_READ) 935 return VERR_VFS_CHAIN_WRITE_ONLY_IOS; 926 936 if (pElement->cArgs > 1) 927 937 return VERR_VFS_CHAIN_AT_MOST_ONE_ARG; 928 if (pElement->enmType != RTVFSOBJTYPE_IO_STREAM)929 return VERR_VFS_CHAIN_ONLY_IOS;930 if (pSpec->fOpenFile & RTFILE_O_READ)931 return VERR_VFS_CHAIN_WRITE_ONLY_IOS;932 938 933 939 /* … … 939 945 const char *psz = pElement->paArgs[0].psz; 940 946 if (!*psz || !strcmp(psz, "default")) 941 p Spec->uProvider = 6;947 pElement->uProvider = 6; 942 948 else if (!strcmp(psz, "fast")) 943 p Spec->uProvider = 3;949 pElement->uProvider = 3; 944 950 else if ( RT_C_IS_DIGIT(*psz) 945 951 && *psz != '0' 946 952 && *RTStrStripL(psz + 1) == '\0') 947 p Spec->uProvider = *psz - '0';953 pElement->uProvider = *psz - '0'; 948 954 else 949 955 { … … 953 959 } 954 960 else 955 p Spec->uProvider = 6;961 pElement->uProvider = 6; 956 962 957 963 return VINF_SUCCESS; … … 974 980 975 981 RTVFSIOSTREAM hVfsIos = NIL_RTVFSIOSTREAM; 976 int rc = RTZipGzipCompressIoStream(hVfsIosOut, 0 /*fFlags*/, p Spec->uProvider, &hVfsIos);982 int rc = RTZipGzipCompressIoStream(hVfsIosOut, 0 /*fFlags*/, pElement->uProvider, &hVfsIos); 977 983 RTVfsObjFromIoStream(hVfsIosOut); 978 984 if (RT_SUCCESS(rc))
Note:
See TracChangeset
for help on using the changeset viewer.