Changeset 70395 in vbox for trunk/src/VBox/Runtime/common/fs
- Timestamp:
- Jan 1, 2018 12:26:11 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 120000
- Location:
- trunk/src/VBox/Runtime/common/fs
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/fs/isomakercmd.cpp
r69157 r70395 340 340 uint32_t cbRandomOrderVerifciationBlock; 341 341 342 /** The current source VFS, NIL_RTVFS if regular file system is used. */ 343 RTVFS hSrcVfs; 344 /** The specifier for hSrcVfs (error messages). */ 345 const char *pszSrcVfs; 346 /** The option for hSrcVfs. */ 347 const char *pszSrcVfsOption; 342 /** Index of the top source stack entry, -1 if empty. */ 343 int32_t iSrcStack; 344 struct 345 { 346 /** The root VFS dir or the CWD for relative paths. */ 347 RTVFSDIR hSrcDir; 348 /** The current source VFS, NIL_RTVFS if the regular file system is used. */ 349 RTVFS hSrcVfs; 350 /** The specifier for hSrcVfs (error messages). */ 351 const char *pszSrcVfs; 352 /** The option for hSrcVfs. 353 * This is NULL for a CWD passed via the API that shouldn't be popped. */ 354 const char *pszSrcVfsOption; 355 } aSrcStack[5]; 348 356 349 357 /** @name Processing of inputs … … 381 389 /** @} */ 382 390 383 /** @name Filtering er391 /** @name Filtering 384 392 * @{ */ 385 393 /** The trans.tbl filename when enabled. We must not import these files. */ … … 429 437 kSrcType_None, 430 438 kSrcType_Normal, 439 kSrcType_NormalSrcStack, 431 440 kSrcType_Remove, 432 441 kSrcType_MustRemove … … 796 805 } 797 806 798 if (pOpts->hSrcVfs != NIL_RTVFS) 799 { 800 RTVfsRelease(pOpts->hSrcVfs); 801 pOpts->hSrcVfs = NIL_RTVFS; 807 while (pOpts->iSrcStack >= 0) 808 { 809 RTVfsDirRelease(pOpts->aSrcStack[pOpts->iSrcStack].hSrcDir); 810 RTVfsRelease(pOpts->aSrcStack[pOpts->iSrcStack].hSrcVfs); 811 pOpts->aSrcStack[pOpts->iSrcStack].hSrcDir = NIL_RTVFSDIR; 812 pOpts->aSrcStack[pOpts->iSrcStack].hSrcVfs = NIL_RTVFS; 813 pOpts->iSrcStack--; 802 814 } 803 815 … … 1407 1419 1408 1420 /** 1421 * Checks if we should use the source stack or the regular file system for 1422 * opening a source. 1423 * 1424 * @returns true / false. 1425 * @param pOpts The ISO maker command instance. 1426 * @param pszSrc The source path under consideration. 1427 */ 1428 static bool rtFsIsoMakerCmdUseSrcStack(PRTFSISOMAKERCMDOPTS pOpts, const char *pszSrc) 1429 { 1430 /* Not if there isn't any stack. */ 1431 if (pOpts->iSrcStack < 0) 1432 return false; 1433 1434 /* Not if we've got a :iprtvfs: incantation. */ 1435 if (RTVfsChainIsSpec(pszSrc)) 1436 return false; 1437 1438 /* If the top entry is a CWD rather than a VFS, we only do it for root-less paths. */ 1439 if (pOpts->aSrcStack[pOpts->iSrcStack].pszSrcVfsOption == NULL) 1440 { 1441 if (RTPathStartsWithRoot(pszSrc)) 1442 return false; 1443 } 1444 return true; 1445 } 1446 1447 1448 /** 1409 1449 * Processes a non-option argument. 1410 1450 * … … 1460 1500 else if (cchName == 13 && strcmp(pszSpec, ":must-remove:") == 0) 1461 1501 pParsed->enmSrcType = RTFSISOMKCMDPARSEDNAMES::kSrcType_MustRemove; 1502 else if (rtFsIsoMakerCmdUseSrcStack(pOpts, pszSpec)) 1503 pParsed->enmSrcType = RTFSISOMKCMDPARSEDNAMES::kSrcType_NormalSrcStack; 1462 1504 } 1463 1505 break; … … 1597 1639 int rc; 1598 1640 uint32_t idxObj = UINT32_MAX; 1599 if ( pOpts->hSrcVfs == NIL_RTVFS 1600 || RTVfsChainIsSpec(pszSrc)) 1601 { 1602 rc = RTFsIsoMakerAddUnnamedFileWithSrcPath(pOpts->hIsoMaker, pszSrc, &idxObj); 1641 if (pParsed->enmSrcType == RTFSISOMKCMDPARSEDNAMES::kSrcType_NormalSrcStack) 1642 { 1643 RTVFSFILE hVfsFileSrc; 1644 rc = RTVfsDirOpenFile(pOpts->aSrcStack[pOpts->iSrcStack].hSrcDir, pszSrc, 1645 RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, &hVfsFileSrc); 1603 1646 if (RT_FAILURE(rc)) 1604 return rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error adding '%s': %Rrc", pszSrc, rc); 1605 } 1606 else 1607 { 1608 RTVFSFILE hVfsFileSrc; 1609 rc = RTVfsFileOpen(pOpts->hSrcVfs, pszSrc, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, &hVfsFileSrc); 1610 if (RT_FAILURE(rc)) 1611 return rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error opening '%s' (inside '%s'): %Rrc", pszSrc, pOpts->pszSrcVfs, rc); 1647 return rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error opening '%s' (%s '%s'): %Rrc", 1648 pszSrc, pOpts->aSrcStack[pOpts->iSrcStack].pszSrcVfsOption ? "inside" : "relative to", 1649 pOpts->aSrcStack[pOpts->iSrcStack].pszSrcVfs, rc); 1612 1650 1613 1651 rc = RTFsIsoMakerAddUnnamedFileWithVfsFile(pOpts->hIsoMaker, hVfsFileSrc, &idxObj); … … 1616 1654 return rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error adding '%s' (VFS): %Rrc", pszSrc, rc); 1617 1655 } 1656 else 1657 { 1658 rc = RTFsIsoMakerAddUnnamedFileWithSrcPath(pOpts->hIsoMaker, pszSrc, &idxObj); 1659 if (RT_FAILURE(rc)) 1660 return rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error adding '%s': %Rrc", pszSrc, rc); 1661 } 1662 1618 1663 1619 1664 pOpts->cItemsAdded++; … … 1845 1890 RTPathChangeToUnixSlashes(pszDir, true /*fForce*/); /* VFS currently only understand unix slashes. */ 1846 1891 RTVFSDIR hVfsDirSrc; 1847 int rc = RTVfsDirOpen (pOpts->hSrcVfs, pszDir, 0 /*fFlags*/, &hVfsDirSrc);1892 int rc = RTVfsDirOpenDir(pOpts->aSrcStack[pOpts->iSrcStack].hSrcDir, pszDir, 0 /*fFlags*/, &hVfsDirSrc); 1848 1893 if (RT_FAILURE(rc)) 1849 return rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error opening directory '%s' (inside '%s'): %Rrc", 1850 pszDir, pOpts->pszSrcVfs, rc); 1894 return rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error opening directory '%s' (%s '%s'): %Rrc", pszDir, 1895 pOpts->aSrcStack[pOpts->iSrcStack].pszSrcVfsOption ? "inside" : "relative to", 1896 pOpts->aSrcStack[pOpts->iSrcStack].pszSrcVfs, rc); 1851 1897 1852 1898 /* … … 1907 1953 int rc; 1908 1954 RTFSOBJINFO ObjInfo; 1909 if ( pOpts->hSrcVfs == NIL_RTVFS 1910 || RTVfsChainIsSpec(pszSrc)) 1955 if (pParsed->enmSrcType == RTFSISOMKCMDPARSEDNAMES::kSrcType_NormalSrcStack) 1956 { 1957 rc = RTVfsDirQueryPathInfo(pOpts->aSrcStack[pOpts->iSrcStack].hSrcDir, pszSrc, 1958 &ObjInfo, RTFSOBJATTRADD_UNIX, RTPATH_F_FOLLOW_LINK); 1959 if (RT_FAILURE(rc)) 1960 return rtFsIsoMakerCmdErrorRc(pOpts, rc, "RTVfsQueryPathInfo failed on %s (%s %s): %Rrc", pszSrc, 1961 pOpts->aSrcStack[pOpts->iSrcStack].pszSrcVfsOption ? "inside" : "relative to", 1962 pOpts->aSrcStack[pOpts->iSrcStack].pszSrcVfs, rc); 1963 } 1964 else 1911 1965 { 1912 1966 uint32_t offError; 1913 1967 RTERRINFOSTATIC ErrInfo; 1914 1968 rc = RTVfsChainQueryInfo(pszSrc, &ObjInfo, RTFSOBJATTRADD_UNIX, 1915 1969 RTPATH_F_FOLLOW_LINK, &offError, RTErrInfoInitStatic(&ErrInfo)); 1916 1970 if (RT_FAILURE(rc)) 1917 1971 return rtFsIsoMakerCmdChainError(pOpts, "RTVfsChainQueryInfo", pszSrc, rc, offError, &ErrInfo.Core); 1918 }1919 else1920 {1921 rc = RTVfsQueryPathInfo(pOpts->hSrcVfs, pszSrc, &ObjInfo, RTFSOBJATTRADD_UNIX, RTPATH_F_FOLLOW_LINK);1922 if (RT_FAILURE(rc))1923 return rtFsIsoMakerCmdErrorRc(pOpts, rc, "RTVfsQueryPathInfo failed on %s (inside %s): %Rrc",1924 pszSrc, pOpts->pszSrcVfs, rc);1925 1972 } 1926 1973 … … 1972 2019 } 1973 2020 } 1974 if ( Parsed.enmSrcType 2021 if ( Parsed.enmSrcType == RTFSISOMKCMDPARSEDNAMES::kSrcType_MustRemove 1975 2022 && cRemoved == 0) 1976 2023 return rtFsIsoMakerCmdErrorRc(pOpts, VERR_NOT_FOUND, "Failed to locate '%s' for removal", pszSpec); … … 1983 2030 const char *pszSrc = Parsed.aNames[Parsed.cNamesWithSrc - 1].szPath; 1984 2031 RTFSOBJINFO ObjInfo; 1985 if ( pOpts->hSrcVfs == NIL_RTVFS 1986 || RTVfsChainIsSpec(pszSrc)) 2032 if (Parsed.enmSrcType == RTFSISOMKCMDPARSEDNAMES::kSrcType_NormalSrcStack) 2033 { 2034 rc = RTVfsDirQueryPathInfo(pOpts->aSrcStack[pOpts->iSrcStack].hSrcDir, pszSrc, 2035 &ObjInfo, RTFSOBJATTRADD_UNIX, RTPATH_F_FOLLOW_LINK); 2036 if (RT_FAILURE(rc)) 2037 return rtFsIsoMakerCmdErrorRc(pOpts, rc, "RTVfsQueryPathInfo failed on %s (%s %s): %Rrc", pszSrc, 2038 pOpts->aSrcStack[pOpts->iSrcStack].pszSrcVfsOption ? "inside" : "relative to", 2039 pOpts->aSrcStack[pOpts->iSrcStack].pszSrcVfs, rc); 2040 } 2041 else 1987 2042 { 1988 2043 uint32_t offError; … … 1993 2048 return rtFsIsoMakerCmdChainError(pOpts, "RTVfsChainQueryInfo", pszSrc, rc, offError, &ErrInfo.Core); 1994 2049 } 1995 else 1996 { 1997 rc = RTVfsQueryPathInfo(pOpts->hSrcVfs, pszSrc, &ObjInfo, RTFSOBJATTRADD_UNIX, RTPATH_F_FOLLOW_LINK); 1998 if (RT_FAILURE(rc)) 1999 return rtFsIsoMakerCmdErrorRc(pOpts, rc, "RTVfsQueryPathInfo failed on %s (in %s): %Rrc", 2000 pszSrc, pOpts->pszSrcVfs, rc); 2001 } 2050 2051 /* By type: */ 2002 2052 2003 2053 if (RTFS_IS_FILE(ObjInfo.Attr.fMode)) … … 2006 2056 if (RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode)) 2007 2057 { 2008 if ( pOpts->hSrcVfs == NIL_RTVFS 2009 || RTVfsChainIsSpec(pszSrc)) 2010 return rtFsIsoMakerCmdAddDir(pOpts, pszSrc, &Parsed); 2011 return rtFsIsoMakerCmdAddVfsDir(pOpts, &Parsed, &ObjInfo); 2058 if (Parsed.enmSrcType == RTFSISOMKCMDPARSEDNAMES::kSrcType_NormalSrcStack) 2059 return rtFsIsoMakerCmdAddVfsDir(pOpts, &Parsed, &ObjInfo); 2060 return rtFsIsoMakerCmdAddDir(pOpts, pszSrc, &Parsed); 2012 2061 } 2013 2062 … … 2035 2084 static int rtFsIsoMakerCmdOptPushIso(PRTFSISOMAKERCMDOPTS pOpts, const char *pszIsoSpec, const char *pszOption, uint32_t fFlags) 2036 2085 { 2037 if (pOpts->hSrcVfs != NIL_RTVFS) 2086 int32_t iSrcStack = pOpts->iSrcStack + 1; 2087 if (iSrcStack >= RT_ELEMENTS(pOpts->aSrcStack)) 2038 2088 return rtFsIsoMakerCmdErrorRc(pOpts, VERR_NOT_IMPLEMENTED, 2039 "Nested %s usage is not supported (previous: %s %s)", 2040 pszOption, pOpts->pszSrcVfsOption, pOpts->pszSrcVfs); 2089 "Too many pushes %s %s (previous: %s %s, %s %s, %s %s, ...)", 2090 pszOption, pszIsoSpec, 2091 pOpts->aSrcStack[iSrcStack - 1].pszSrcVfsOption, pOpts->aSrcStack[iSrcStack - 1].pszSrcVfs, 2092 pOpts->aSrcStack[iSrcStack - 2].pszSrcVfsOption, pOpts->aSrcStack[iSrcStack - 2].pszSrcVfs, 2093 pOpts->aSrcStack[iSrcStack - 3].pszSrcVfsOption, pOpts->aSrcStack[iSrcStack - 3].pszSrcVfs); 2041 2094 2042 2095 /* 2043 2096 * Try open the file. 2044 2097 */ 2045 RTVFSFILE hVfsFileIso;2046 uint32_t offError;2098 int rc; 2099 RTVFSFILE hVfsFileIso = NIL_RTVFSFILE; 2047 2100 RTERRINFOSTATIC ErrInfo; 2048 int rc = RTVfsChainOpenFile(pszIsoSpec, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, 2101 if (rtFsIsoMakerCmdUseSrcStack(pOpts, pszIsoSpec)) 2102 { 2103 rc = RTVfsDirOpenFile(pOpts->aSrcStack[iSrcStack - 1].hSrcDir, pszIsoSpec, 2104 RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, &hVfsFileIso); 2105 if (RT_FAILURE(rc)) 2106 rc = rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error opening '%s' relative to '%s'", 2107 pszIsoSpec, pOpts->aSrcStack[iSrcStack - 1].pszSrcVfs); 2108 } 2109 else 2110 { 2111 uint32_t offError; 2112 rc = RTVfsChainOpenFile(pszIsoSpec, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, 2049 2113 &hVfsFileIso, &offError, RTErrInfoInitStatic(&ErrInfo)); 2114 if (RT_FAILURE(rc)) 2115 rc = rtFsIsoMakerCmdChainError(pOpts, "RTVfsChainOpenFile", pszIsoSpec, rc, offError, &ErrInfo.Core); 2116 } 2050 2117 if (RT_SUCCESS(rc)) 2051 2118 { … … 2055 2122 if (RT_SUCCESS(rc)) 2056 2123 { 2057 pOpts->hSrcVfs = hSrcVfs; 2058 pOpts->pszSrcVfs = pszIsoSpec; 2059 pOpts->pszSrcVfsOption = pszOption; 2060 return VINF_SUCCESS; 2124 RTVFSDIR hVfsSrcRootDir; 2125 rc = RTVfsOpenRoot(hSrcVfs, &hVfsSrcRootDir); 2126 if (RT_SUCCESS(rc)) 2127 { 2128 pOpts->aSrcStack[iSrcStack].hSrcDir = hVfsSrcRootDir; 2129 pOpts->aSrcStack[iSrcStack].hSrcVfs = hSrcVfs; 2130 pOpts->aSrcStack[iSrcStack].pszSrcVfs = pszIsoSpec; 2131 pOpts->aSrcStack[iSrcStack].pszSrcVfsOption = pszOption; 2132 pOpts->iSrcStack = iSrcStack; 2133 return VINF_SUCCESS; 2134 } 2135 RTVfsRelease(hSrcVfs); 2061 2136 } 2062 2063 if (RTErrInfoIsSet(&ErrInfo.Core)) 2137 else if (RTErrInfoIsSet(&ErrInfo.Core)) 2064 2138 rc = rtFsIsoMakerCmdErrorRc(pOpts, rc, "Failed to open '%s' as ISO FS: %Rrc - %s", 2065 2139 pszIsoSpec, rc, ErrInfo.Core.pszMsg); … … 2067 2141 rc = rtFsIsoMakerCmdErrorRc(pOpts, rc, "Failed to open '%s' as ISO FS: %Rrc", pszIsoSpec, rc); 2068 2142 } 2143 return rc; 2144 } 2145 2146 2147 /** 2148 * Counter part to --push-iso and friends. 2149 * 2150 * @returns IPRT status code. 2151 * @param pOpts The ISO maker command instance. 2152 */ 2153 static int rtFsIsoMakerCmdOptPop(PRTFSISOMAKERCMDOPTS pOpts) 2154 { 2155 int32_t const iSrcStack = pOpts->iSrcStack; 2156 if ( iSrcStack >= 0 2157 && pOpts->aSrcStack[iSrcStack].pszSrcVfsOption) 2158 { 2159 RTVfsDirRelease(pOpts->aSrcStack[iSrcStack].hSrcDir); 2160 RTVfsRelease(pOpts->aSrcStack[iSrcStack].hSrcVfs); 2161 pOpts->aSrcStack[iSrcStack].hSrcDir = NIL_RTVFSDIR; 2162 pOpts->aSrcStack[iSrcStack].hSrcVfs = NIL_RTVFS; 2163 pOpts->aSrcStack[iSrcStack].pszSrcVfs = NULL; 2164 pOpts->aSrcStack[iSrcStack].pszSrcVfsOption = NULL; 2165 pOpts->iSrcStack = iSrcStack - 1; 2166 return VINF_SUCCESS; 2167 } 2168 return rtFsIsoMakerCmdErrorRc(pOpts, VERR_NOT_FOUND, "--pop without --push-xxx"); 2169 } 2170 2171 2172 /** 2173 * Deals with the --import-iso {iso-file-spec} options. 2174 * 2175 * @returns IPRT status code 2176 * @param pOpts The ISO maker command instance. 2177 * @param pszIsoSpec The ISO path specifier. 2178 */ 2179 static int rtFsIsoMakerCmdOptImportIso(PRTFSISOMAKERCMDOPTS pOpts, const char *pszIsoSpec) 2180 { 2181 /* 2182 * Open the input file. 2183 */ 2184 RTERRINFOSTATIC ErrInfo; 2185 RTVFSFILE hIsoFile; 2186 int rc; 2187 if (rtFsIsoMakerCmdUseSrcStack(pOpts, pszIsoSpec)) 2188 { 2189 rc = RTVfsDirOpenFile(pOpts->aSrcStack[pOpts->iSrcStack].hSrcDir, pszIsoSpec, 2190 RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, &hIsoFile); 2191 if (RT_FAILURE(rc)) 2192 return rtFsIsoMakerCmdErrorRc(pOpts, rc, "Failed to open '%s' %s %s for importing: %Rrc", pszIsoSpec, 2193 pOpts->aSrcStack[pOpts->iSrcStack].pszSrcVfsOption ? "inside" : "relative to", 2194 pOpts->aSrcStack[pOpts->iSrcStack].pszSrcVfs, rc); 2195 } 2069 2196 else 2070 rc = rtFsIsoMakerCmdChainError(pOpts, "RTVfsChainOpenFile", pszIsoSpec, rc, offError, &ErrInfo.Core); 2071 return rc; 2072 } 2073 2074 2075 /** 2076 * Counter part to --push-iso and friends. 2077 * 2078 * @returns IPRT status code. 2079 * @param pOpts The ISO maker command instance. 2080 */ 2081 static int rtFsIsoMakerCmdOptPop(PRTFSISOMAKERCMDOPTS pOpts) 2082 { 2083 if (pOpts->hSrcVfs != NIL_RTVFS) 2084 { 2085 RTVfsRelease(pOpts->hSrcVfs); 2086 pOpts->hSrcVfs = NIL_RTVFS; 2087 pOpts->pszSrcVfs = NULL; 2088 pOpts->pszSrcVfsOption = NULL; 2089 return VINF_SUCCESS; 2090 } 2091 return rtFsIsoMakerCmdErrorRc(pOpts, VERR_NOT_FOUND, "--pop without --push-xxx"); 2092 } 2093 2094 2095 /** 2096 * Deals with the --import-iso {iso-file-spec} options. 2097 * 2098 * @returns IPRT status code 2099 * @param pOpts The ISO maker command instance. 2100 * @param pszIsoSpec The ISO path specifier. 2101 */ 2102 static int rtFsIsoMakerCmdOptImportIso(PRTFSISOMAKERCMDOPTS pOpts, const char *pszIsoSpec) 2103 { 2197 { 2198 uint32_t offError; 2199 rc = RTVfsChainOpenFile(pszIsoSpec, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, 2200 &hIsoFile, &offError, RTErrInfoInitStatic(&ErrInfo)); 2201 if (RT_FAILURE(rc)) 2202 return rtFsIsoMakerCmdChainError(pOpts, "RTVfsChainOpenFile", pszIsoSpec, rc, offError, &ErrInfo.Core); 2203 } 2204 2104 2205 RTFSISOMAKERIMPORTRESULTS Results; 2105 RTERRINFOSTATIC ErrInfo; 2106 int rc = RTFsIsoMakerImport(pOpts->hIsoMaker, pszIsoSpec, 0 /*fFlags*/, &Results, RTErrInfoInitStatic(&ErrInfo)); 2206 rc = RTFsIsoMakerImport(pOpts->hIsoMaker, hIsoFile, 0 /*fFlags*/, &Results, RTErrInfoInitStatic(&ErrInfo)); 2207 2208 RTVfsFileRelease(hIsoFile); 2107 2209 2108 2210 pOpts->cItemsAdded += Results.cAddedFiles; … … 2127 2229 if (RT_SUCCESS(rc)) 2128 2230 return rc; 2129 if (Results.offError != UINT32_MAX)2130 return rtFsIsoMakerCmdChainError(pOpts, "RTFsIsoMakerImport", pszIsoSpec, rc, Results.offError, &ErrInfo.Core);2131 2231 if (RTErrInfoIsSet(&ErrInfo.Core)) 2132 2232 return rtFsIsoMakerCmdErrorRc(pOpts, rc, "RTFsIsoMakerImport failed: %Rrc - %s", rc, ErrInfo.Core.pszMsg); … … 3334 3434 * 3335 3435 * @returns IPRT status code 3336 * @param cArgs Number of arguments. 3337 * @param papszArgs Pointer to argument array. 3338 * @param phVfsFile Where to return the virtual ISO. Pass NULL to 3339 * for normal operation (creates file on disk). 3340 * @param pErrInfo Where to return extended error information in 3341 * the virtual ISO mode. 3342 */ 3343 RTDECL(int) RTFsIsoMakerCmdEx(unsigned cArgs, char **papszArgs, PRTVFSFILE phVfsFile, PRTERRINFO pErrInfo) 3344 { 3436 * @param cArgs Number of arguments. 3437 * @param papszArgs Pointer to argument array. 3438 * @param hVfsCwd The current working directory to assume when processing 3439 * relative file/dir references. Pass NIL_RTVFSDIR to use 3440 * the current CWD of the process. 3441 * @param pszCwd Path to @a hVfsCwdDir. Use for error reporting and 3442 * optimizing the open file count if possible. 3443 * @param phVfsFile Where to return the virtual ISO. Pass NULL to for 3444 * normal operation (creates file on disk). 3445 * @param pErrInfo Where to return extended error information in the 3446 * virtual ISO mode. 3447 */ 3448 RTDECL(int) RTFsIsoMakerCmdEx(unsigned cArgs, char **papszArgs, RTVFSDIR hVfsCwd, const char *pszCwd, 3449 PRTVFSFILE phVfsFile, PRTERRINFO pErrInfo) 3450 { 3451 if (phVfsFile) 3452 *phVfsFile = NIL_RTVFSFILE; 3453 3345 3454 /* 3346 3455 * Create instance. … … 3351 3460 Opts.pErrInfo = pErrInfo; 3352 3461 Opts.fVirtualImageMaker = phVfsFile != NULL; 3353 Opts.hSrcVfs = NIL_RTVFS;3354 3462 Opts.cNameSpecifiers = 1; 3355 3463 Opts.afNameSpecifiers[0] = RTFSISOMAKERCMDNAME_MAJOR_MASK; 3356 3464 Opts.fDstNamespaces = RTFSISOMAKERCMDNAME_MAJOR_MASK; 3357 3465 Opts.pszTransTbl = "TRANS.TBL"; /** @todo query this below */ 3358 if (phVfsFile)3359 *phVfsFile = NIL_RTVFSFILE;3360 3466 for (uint32_t i = 0; i < RT_ELEMENTS(Opts.aBootCatEntries); i++) 3361 3467 Opts.aBootCatEntries[i].u.Section.idxImageObj = UINT32_MAX; 3362 3468 3469 /* Initialize the source stack with NILs (to be on the safe size). */ 3470 Opts.iSrcStack = -1; 3471 for (uint32_t i = 0; i < RT_ELEMENTS(Opts.aSrcStack); i++) 3472 { 3473 Opts.aSrcStack[i].hSrcDir = NIL_RTVFSDIR; 3474 Opts.aSrcStack[i].hSrcVfs = NIL_RTVFS; 3475 } 3476 3477 /* Push the CWD if present. */ 3478 if (hVfsCwd != NIL_RTVFSDIR) 3479 { 3480 AssertReturn(pszCwd, VERR_INVALID_PARAMETER); 3481 uint32_t cRefs = RTVfsDirRetain(hVfsCwd); 3482 AssertReturn(cRefs != UINT32_MAX, VERR_INVALID_HANDLE); 3483 3484 Opts.aSrcStack[0].hSrcDir = hVfsCwd; 3485 Opts.aSrcStack[0].pszSrcVfs = pszCwd; 3486 Opts.iSrcStack = 0; 3487 } 3488 3363 3489 /* Create the ISO creator instance. */ 3364 3490 int rc = RTFsIsoMakerCreate(&Opts.hIsoMaker); 3365 if (RT_FAILURE(rc)) 3366 return rtFsIsoMakerCmdErrorRc(&Opts, rc, "RTFsIsoMakerCreate failed: %Rrc", rc); 3367 3368 /* 3369 * Parse the command line and check for mandatory options. 3370 */ 3371 rc = rtFsIsoMakerCmdParse(&Opts, cArgs, papszArgs, 0); 3372 if (RT_SUCCESS(rc) && rc != VINF_CALLBACK_RETURN) 3373 { 3374 if (!Opts.cItemsAdded) 3375 rc = rtFsIsoMakerCmdErrorRc(&Opts, VERR_NO_DATA, "Cowardly refuses to create empty ISO image"); 3376 else if (!Opts.pszOutFile && !Opts.fVirtualImageMaker) 3377 rc = rtFsIsoMakerCmdErrorRc(&Opts, VERR_INVALID_PARAMETER, "No output file specified (--output <file>)"); 3378 3491 if (RT_SUCCESS(rc)) 3492 { 3379 3493 /* 3380 * Final actions.3494 * Parse the command line and check for mandatory options. 3381 3495 */ 3382 if (RT_SUCCESS(rc)) 3383 rc = rtFsIsoMakerCmdOptEltoritoCommitBootCatalog(&Opts); 3384 if (RT_SUCCESS(rc)) 3496 rc = rtFsIsoMakerCmdParse(&Opts, cArgs, papszArgs, 0); 3497 if (RT_SUCCESS(rc) && rc != VINF_CALLBACK_RETURN) 3385 3498 { 3499 if (!Opts.cItemsAdded) 3500 rc = rtFsIsoMakerCmdErrorRc(&Opts, VERR_NO_DATA, "Cowardly refuses to create empty ISO image"); 3501 else if (!Opts.pszOutFile && !Opts.fVirtualImageMaker) 3502 rc = rtFsIsoMakerCmdErrorRc(&Opts, VERR_INVALID_PARAMETER, "No output file specified (--output <file>)"); 3503 3386 3504 /* 3387 * Final ize the image and get the virtual file.3505 * Final actions. 3388 3506 */ 3389 rc = RTFsIsoMakerFinalize(Opts.hIsoMaker); 3507 if (RT_SUCCESS(rc)) 3508 rc = rtFsIsoMakerCmdOptEltoritoCommitBootCatalog(&Opts); 3390 3509 if (RT_SUCCESS(rc)) 3391 3510 { 3392 RTVFSFILE hVfsFile; 3393 rc = RTFsIsoMakerCreateVfsOutputFile(Opts.hIsoMaker, &hVfsFile); 3511 /* 3512 * Finalize the image and get the virtual file. 3513 */ 3514 rc = RTFsIsoMakerFinalize(Opts.hIsoMaker); 3394 3515 if (RT_SUCCESS(rc)) 3395 3516 { 3396 /* 3397 * We're done now if we're only setting up a virtual image. 3398 */ 3399 if (Opts.fVirtualImageMaker) 3400 *phVfsFile = hVfsFile; 3517 RTVFSFILE hVfsFile; 3518 rc = RTFsIsoMakerCreateVfsOutputFile(Opts.hIsoMaker, &hVfsFile); 3519 if (RT_SUCCESS(rc)) 3520 { 3521 /* 3522 * We're done now if we're only setting up a virtual image. 3523 */ 3524 if (Opts.fVirtualImageMaker) 3525 *phVfsFile = hVfsFile; 3526 else 3527 { 3528 rc = rtFsIsoMakerCmdWriteImage(&Opts, hVfsFile); 3529 RTVfsFileRelease(hVfsFile); 3530 } 3531 } 3401 3532 else 3402 { 3403 rc = rtFsIsoMakerCmdWriteImage(&Opts, hVfsFile); 3404 RTVfsFileRelease(hVfsFile); 3405 } 3533 rc = rtFsIsoMakerCmdErrorRc(&Opts, rc, "RTFsIsoMakerCreateVfsOutputFile failed: %Rrc", rc); 3406 3534 } 3407 3535 else 3408 rc = rtFsIsoMakerCmdErrorRc(&Opts, rc, "RTFsIsoMaker CreateVfsOutputFile failed: %Rrc", rc);3536 rc = rtFsIsoMakerCmdErrorRc(&Opts, rc, "RTFsIsoMakerFinalize failed: %Rrc", rc); 3409 3537 } 3410 else3411 rc = rtFsIsoMakerCmdErrorRc(&Opts, rc, "RTFsIsoMakerFinalize failed: %Rrc", rc);3412 3538 } 3539 } 3540 else 3541 { 3542 rc = rtFsIsoMakerCmdErrorRc(&Opts, rc, "RTFsIsoMakerCreate failed: %Rrc", rc); 3543 Opts.hIsoMaker = NIL_RTFSISOMAKER; 3413 3544 } 3414 3545 … … 3426 3557 RTDECL(RTEXITCODE) RTFsIsoMakerCmd(unsigned cArgs, char **papszArgs) 3427 3558 { 3428 int rc = RTFsIsoMakerCmdEx(cArgs, papszArgs, N ULL, NULL);3559 int rc = RTFsIsoMakerCmdEx(cArgs, papszArgs, NIL_RTVFSDIR, NULL, NULL, NULL); 3429 3560 return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE; 3430 3561 } -
trunk/src/VBox/Runtime/common/fs/isomakerimport.cpp
r67860 r70395 1875 1875 RT_BE2H_U16(pVolDesc->cVolumesInSet.be), RT_LE2H_U16(pVolDesc->cVolumesInSet.le)); 1876 1876 if (RT_LE2H_U16(pVolDesc->VolumeSeqNo.le) != RT_BE2H_U16(pVolDesc->VolumeSeqNo.be)) 1877 return rtFsIsoImpError(pThis, VERR_ISOMK_IMPORT_BAD_PRIMARY_VOL_DESC, 1878 "Mismatching volume sequence no.: {%#RX16,%#RX16}", 1879 RT_BE2H_U16(pVolDesc->VolumeSeqNo.be), RT_LE2H_U16(pVolDesc->VolumeSeqNo.le)); 1877 { 1878 /* Hack alert! An Windows NT 3.1 ISO was found to not have the big endian bit set here, so work around it. */ 1879 if ( pVolDesc->VolumeSeqNo.be == 0 1880 && pVolDesc->VolumeSeqNo.le == RT_H2LE_U16_C(1)) 1881 pVolDesc->VolumeSeqNo.be = RT_H2BE_U16_C(1); 1882 else 1883 return rtFsIsoImpError(pThis, VERR_ISOMK_IMPORT_BAD_PRIMARY_VOL_DESC, 1884 "Mismatching volume sequence no.: {%#RX16,%#RX16}", 1885 RT_BE2H_U16(pVolDesc->VolumeSeqNo.be), RT_LE2H_U16(pVolDesc->VolumeSeqNo.le)); 1886 } 1880 1887 if (RT_LE2H_U32(pVolDesc->cbPathTable.le) != RT_BE2H_U32(pVolDesc->cbPathTable.be)) 1881 1888 return rtFsIsoImpError(pThis, VERR_ISOMK_IMPORT_BAD_PRIMARY_VOL_DESC, … … 2475 2482 * 2476 2483 * @returns IRPT status code. 2477 * @param hIsoMaker The ISO maker handle. 2478 * @param pszIso Path to the existing image to import / clone. 2479 * This is fed to RTVfsChainOpenFile. 2480 * @param fFlags Reserved for the future, MBZ. 2481 * @param poffError Where to return the position in @a pszIso 2482 * causing trouble when opening it for reading. 2483 * Optional. 2484 * @param pErrInfo Where to return additional error information. 2485 * Optional. 2486 */ 2487 RTDECL(int) RTFsIsoMakerImport(RTFSISOMAKER hIsoMaker, const char *pszIso, uint32_t fFlags, 2484 * @param hIsoMaker The ISO maker handle. 2485 * @param hIsoFile VFS file handle to the existing image to import / clone. 2486 * @param fFlags Reserved for the future, MBZ. 2487 * @param poffError Where to return the position in @a pszIso 2488 * causing trouble when opening it for reading. 2489 * Optional. 2490 * @param pErrInfo Where to return additional error information. 2491 * Optional. 2492 */ 2493 RTDECL(int) RTFsIsoMakerImport(RTFSISOMAKER hIsoMaker, RTVFSFILE hIsoFile, uint32_t fFlags, 2488 2494 PRTFSISOMAKERIMPORTRESULTS pResults, PRTERRINFO pErrInfo) 2489 2495 { … … 2500 2506 pResults->cbSysArea = 0; 2501 2507 pResults->cErrors = 0; 2502 pResults->offError = UINT32_MAX;2503 2508 AssertReturn(!(fFlags & ~RTFSISOMK_IMPORT_F_VALID_MASK), VERR_INVALID_FLAGS); 2504 2509 2505 2510 /* 2506 * Open the input file and start working on it.2507 */2508 RTVFSFILE hSrcFile;2509 int rc = RTVfsChainOpenFile(pszIso, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE,2510 &hSrcFile, &pResults->offError, pErrInfo);2511 if (RT_FAILURE(rc))2512 return rc;2513 pResults->offError = UINT32_MAX;2514 2515 /*2516 2511 * Get the file size. 2517 2512 */ 2518 2513 uint64_t cbSrcFile = 0; 2519 rc = RTVfsFileGetSize(hSrcFile, &cbSrcFile);2514 int rc = RTVfsFileGetSize(hIsoFile, &cbSrcFile); 2520 2515 if (RT_SUCCESS(rc)) 2521 2516 { … … 2530 2525 pThis->rc = VINF_SUCCESS; 2531 2526 pThis->pErrInfo = pErrInfo; 2532 pThis->hSrcFile = h SrcFile;2527 pThis->hSrcFile = hIsoFile; 2533 2528 pThis->cbSrcFile = cbSrcFile; 2534 2529 pThis->cBlocksInSrcFile = cbSrcFile / ISO9660_SECTOR_SIZE; … … 2548 2543 * Check if this looks like a plausible ISO by checking out the first volume descriptor. 2549 2544 */ 2550 rc = RTVfsFileReadAt(h SrcFile, _32K, &pThis->uSectorBuf.PrimVolDesc, sizeof(pThis->uSectorBuf.PrimVolDesc), NULL);2545 rc = RTVfsFileReadAt(hIsoFile, _32K, &pThis->uSectorBuf.PrimVolDesc, sizeof(pThis->uSectorBuf.PrimVolDesc), NULL); 2551 2546 if (RT_SUCCESS(rc)) 2552 2547 { … … 2624 2619 } 2625 2620 2626 rc = RTVfsFileReadAt(h SrcFile, _32K + iVolDesc * ISO9660_SECTOR_SIZE,2621 rc = RTVfsFileReadAt(hIsoFile, _32K + iVolDesc * ISO9660_SECTOR_SIZE, 2627 2622 &pThis->uSectorBuf, sizeof(pThis->uSectorBuf), NULL); 2628 2623 if (RT_FAILURE(rc)) … … 2655 2650 if (RT_SUCCESS(pThis->rc) || pThis->idxSrcFile != UINT32_MAX) 2656 2651 { 2657 rc = RTVfsFileReadAt(h SrcFile, 0, pThis->abBuf, _32K, NULL);2652 rc = RTVfsFileReadAt(hIsoFile, 0, pThis->abBuf, _32K, NULL); 2658 2653 if (RT_SUCCESS(rc)) 2659 2654 { … … 2684 2679 && (RT_SUCCESS(pThis->rc) || pThis->idxSrcFile != UINT32_MAX)) 2685 2680 { 2686 rc = RTVfsFileReadAt(h SrcFile, _32K + iElTorito * ISO9660_SECTOR_SIZE,2681 rc = RTVfsFileReadAt(hIsoFile, _32K + iElTorito * ISO9660_SECTOR_SIZE, 2687 2682 &pThis->uSectorBuf, sizeof(pThis->uSectorBuf), NULL); 2688 2683 if (RT_SUCCESS(rc)) … … 2712 2707 rc = VERR_NO_MEMORY; 2713 2708 } 2714 RTVfsFileRelease(hSrcFile);2715 2709 return rc; 2716 2717 2710 } 2718 2711
Note:
See TracChangeset
for help on using the changeset viewer.