VirtualBox

Changeset 70395 in vbox for trunk/src/VBox/Runtime/common/fs


Ignore:
Timestamp:
Jan 1, 2018 12:26:11 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
120000
Message:

IPRT/VISO: Pass a the directory of a VISO file to the ISO maker to allow for relative file/dir specification from it. Nested push-iso now possible. Tweak importer code to handle NT 3.1 iso where the big endian volume sequence number wasn't set.

Location:
trunk/src/VBox/Runtime/common/fs
Files:
2 edited

Legend:

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

    r69157 r70395  
    340340    uint32_t            cbRandomOrderVerifciationBlock;
    341341
    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];
    348356
    349357    /** @name Processing of inputs
     
    381389    /** @} */
    382390
    383     /** @name Filteringer
     391    /** @name Filtering
    384392     * @{ */
    385393    /** The trans.tbl filename when enabled.  We must not import these files. */
     
    429437        kSrcType_None,
    430438        kSrcType_Normal,
     439        kSrcType_NormalSrcStack,
    431440        kSrcType_Remove,
    432441        kSrcType_MustRemove
     
    796805    }
    797806
    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--;
    802814    }
    803815
     
    14071419
    14081420/**
     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 */
     1428static 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/**
    14091449 * Processes a non-option argument.
    14101450 *
     
    14601500                else if (cchName == 13 && strcmp(pszSpec, ":must-remove:") == 0)
    14611501                    pParsed->enmSrcType = RTFSISOMKCMDPARSEDNAMES::kSrcType_MustRemove;
     1502                else if (rtFsIsoMakerCmdUseSrcStack(pOpts, pszSpec))
     1503                    pParsed->enmSrcType = RTFSISOMKCMDPARSEDNAMES::kSrcType_NormalSrcStack;
    14621504            }
    14631505            break;
     
    15971639    int      rc;
    15981640    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);
    16031646        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);
    16121650
    16131651        rc = RTFsIsoMakerAddUnnamedFileWithVfsFile(pOpts->hIsoMaker, hVfsFileSrc, &idxObj);
     
    16161654            return rtFsIsoMakerCmdErrorRc(pOpts, rc, "Error adding '%s' (VFS): %Rrc", pszSrc, rc);
    16171655    }
     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
    16181663
    16191664    pOpts->cItemsAdded++;
     
    18451890    RTPathChangeToUnixSlashes(pszDir, true /*fForce*/); /* VFS currently only understand unix slashes. */
    18461891    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);
    18481893    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);
    18511897
    18521898    /*
     
    19071953    int         rc;
    19081954    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
    19111965    {
    19121966        uint32_t        offError;
    19131967        RTERRINFOSTATIC ErrInfo;
    19141968        rc = RTVfsChainQueryInfo(pszSrc, &ObjInfo, RTFSOBJATTRADD_UNIX,
    1915                                      RTPATH_F_FOLLOW_LINK, &offError, RTErrInfoInitStatic(&ErrInfo));
     1969                                 RTPATH_F_FOLLOW_LINK, &offError, RTErrInfoInitStatic(&ErrInfo));
    19161970        if (RT_FAILURE(rc))
    19171971            return rtFsIsoMakerCmdChainError(pOpts, "RTVfsChainQueryInfo", pszSrc, rc, offError, &ErrInfo.Core);
    1918     }
    1919     else
    1920     {
    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);
    19251972    }
    19261973
     
    19722019                }
    19732020            }
    1974         if (   Parsed.enmSrcType  == RTFSISOMKCMDPARSEDNAMES::kSrcType_MustRemove
     2021        if (   Parsed.enmSrcType == RTFSISOMKCMDPARSEDNAMES::kSrcType_MustRemove
    19752022            && cRemoved == 0)
    19762023            return rtFsIsoMakerCmdErrorRc(pOpts, VERR_NOT_FOUND, "Failed to locate '%s' for removal", pszSpec);
     
    19832030        const char     *pszSrc = Parsed.aNames[Parsed.cNamesWithSrc - 1].szPath;
    19842031        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
    19872042        {
    19882043            uint32_t        offError;
     
    19932048                return rtFsIsoMakerCmdChainError(pOpts, "RTVfsChainQueryInfo", pszSrc, rc, offError, &ErrInfo.Core);
    19942049        }
    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: */
    20022052
    20032053        if (RTFS_IS_FILE(ObjInfo.Attr.fMode))
     
    20062056        if (RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode))
    20072057        {
    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);
    20122061        }
    20132062
     
    20352084static int rtFsIsoMakerCmdOptPushIso(PRTFSISOMAKERCMDOPTS pOpts, const char *pszIsoSpec, const char *pszOption, uint32_t fFlags)
    20362085{
    2037     if (pOpts->hSrcVfs != NIL_RTVFS)
     2086    int32_t iSrcStack = pOpts->iSrcStack + 1;
     2087    if (iSrcStack >= RT_ELEMENTS(pOpts->aSrcStack))
    20382088        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);
    20412094
    20422095    /*
    20432096     * Try open the file.
    20442097     */
    2045     RTVFSFILE       hVfsFileIso;
    2046     uint32_t        offError;
     2098    int             rc;
     2099    RTVFSFILE       hVfsFileIso = NIL_RTVFSFILE;
    20472100    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,
    20492113                                &hVfsFileIso, &offError, RTErrInfoInitStatic(&ErrInfo));
     2114        if (RT_FAILURE(rc))
     2115            rc = rtFsIsoMakerCmdChainError(pOpts, "RTVfsChainOpenFile", pszIsoSpec, rc, offError, &ErrInfo.Core);
     2116    }
    20502117    if (RT_SUCCESS(rc))
    20512118    {
     
    20552122        if (RT_SUCCESS(rc))
    20562123        {
    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);
    20612136        }
    2062 
    2063         if (RTErrInfoIsSet(&ErrInfo.Core))
     2137        else if (RTErrInfoIsSet(&ErrInfo.Core))
    20642138            rc = rtFsIsoMakerCmdErrorRc(pOpts, rc, "Failed to open '%s' as ISO FS: %Rrc - %s",
    20652139                                        pszIsoSpec, rc, ErrInfo.Core.pszMsg);
     
    20672141            rc = rtFsIsoMakerCmdErrorRc(pOpts, rc, "Failed to open '%s' as ISO FS: %Rrc", pszIsoSpec, rc);
    20682142    }
     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 */
     2153static 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 */
     2179static 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    }
    20692196    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
    21042205    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);
    21072209
    21082210    pOpts->cItemsAdded += Results.cAddedFiles;
     
    21272229    if (RT_SUCCESS(rc))
    21282230        return rc;
    2129     if (Results.offError != UINT32_MAX)
    2130         return rtFsIsoMakerCmdChainError(pOpts, "RTFsIsoMakerImport", pszIsoSpec, rc, Results.offError, &ErrInfo.Core);
    21312231    if (RTErrInfoIsSet(&ErrInfo.Core))
    21322232        return rtFsIsoMakerCmdErrorRc(pOpts, rc, "RTFsIsoMakerImport failed: %Rrc - %s", rc, ErrInfo.Core.pszMsg);
     
    33343434 *
    33353435 * @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 */
     3448RTDECL(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
    33453454    /*
    33463455     * Create instance.
     
    33513460    Opts.pErrInfo               = pErrInfo;
    33523461    Opts.fVirtualImageMaker     = phVfsFile != NULL;
    3353     Opts.hSrcVfs                = NIL_RTVFS;
    33543462    Opts.cNameSpecifiers        = 1;
    33553463    Opts.afNameSpecifiers[0]    = RTFSISOMAKERCMDNAME_MAJOR_MASK;
    33563464    Opts.fDstNamespaces         = RTFSISOMAKERCMDNAME_MAJOR_MASK;
    33573465    Opts.pszTransTbl            = "TRANS.TBL"; /** @todo query this below */
    3358     if (phVfsFile)
    3359         *phVfsFile = NIL_RTVFSFILE;
    33603466    for (uint32_t i = 0; i < RT_ELEMENTS(Opts.aBootCatEntries); i++)
    33613467        Opts.aBootCatEntries[i].u.Section.idxImageObj = UINT32_MAX;
    33623468
     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
    33633489    /* Create the ISO creator instance. */
    33643490    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    {
    33793493        /*
    3380          * Final actions.
     3494         * Parse the command line and check for mandatory options.
    33813495         */
    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)
    33853498        {
     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
    33863504            /*
    3387              * Finalize the image and get the virtual file.
     3505             * Final actions.
    33883506             */
    3389             rc = RTFsIsoMakerFinalize(Opts.hIsoMaker);
     3507            if (RT_SUCCESS(rc))
     3508                rc = rtFsIsoMakerCmdOptEltoritoCommitBootCatalog(&Opts);
    33903509            if (RT_SUCCESS(rc))
    33913510            {
    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);
    33943515                if (RT_SUCCESS(rc))
    33953516                {
    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                    }
    34013532                    else
    3402                     {
    3403                         rc = rtFsIsoMakerCmdWriteImage(&Opts, hVfsFile);
    3404                         RTVfsFileRelease(hVfsFile);
    3405                     }
     3533                        rc = rtFsIsoMakerCmdErrorRc(&Opts, rc, "RTFsIsoMakerCreateVfsOutputFile failed: %Rrc", rc);
    34063534                }
    34073535                else
    3408                     rc = rtFsIsoMakerCmdErrorRc(&Opts, rc, "RTFsIsoMakerCreateVfsOutputFile failed: %Rrc", rc);
     3536                    rc = rtFsIsoMakerCmdErrorRc(&Opts, rc, "RTFsIsoMakerFinalize failed: %Rrc", rc);
    34093537            }
    3410             else
    3411                 rc = rtFsIsoMakerCmdErrorRc(&Opts, rc, "RTFsIsoMakerFinalize failed: %Rrc", rc);
    34123538        }
     3539    }
     3540    else
     3541    {
     3542        rc = rtFsIsoMakerCmdErrorRc(&Opts, rc, "RTFsIsoMakerCreate failed: %Rrc", rc);
     3543        Opts.hIsoMaker = NIL_RTFSISOMAKER;
    34133544    }
    34143545
     
    34263557RTDECL(RTEXITCODE) RTFsIsoMakerCmd(unsigned cArgs, char **papszArgs)
    34273558{
    3428     int rc = RTFsIsoMakerCmdEx(cArgs, papszArgs, NULL, NULL);
     3559    int rc = RTFsIsoMakerCmdEx(cArgs, papszArgs, NIL_RTVFSDIR, NULL, NULL, NULL);
    34293560    return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
    34303561}
  • trunk/src/VBox/Runtime/common/fs/isomakerimport.cpp

    r67860 r70395  
    18751875                               RT_BE2H_U16(pVolDesc->cVolumesInSet.be), RT_LE2H_U16(pVolDesc->cVolumesInSet.le));
    18761876    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    }
    18801887    if (RT_LE2H_U32(pVolDesc->cbPathTable.le) != RT_BE2H_U32(pVolDesc->cbPathTable.be))
    18811888        return rtFsIsoImpError(pThis, VERR_ISOMK_IMPORT_BAD_PRIMARY_VOL_DESC,
     
    24752482 *
    24762483 * @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 */
     2493RTDECL(int) RTFsIsoMakerImport(RTFSISOMAKER hIsoMaker, RTVFSFILE hIsoFile, uint32_t fFlags,
    24882494                               PRTFSISOMAKERIMPORTRESULTS pResults, PRTERRINFO pErrInfo)
    24892495{
     
    25002506    pResults->cbSysArea         = 0;
    25012507    pResults->cErrors           = 0;
    2502     pResults->offError          = UINT32_MAX;
    25032508    AssertReturn(!(fFlags & ~RTFSISOMK_IMPORT_F_VALID_MASK), VERR_INVALID_FLAGS);
    25042509
    25052510    /*
    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     /*
    25162511     * Get the file size.
    25172512     */
    25182513    uint64_t cbSrcFile = 0;
    2519     rc = RTVfsFileGetSize(hSrcFile, &cbSrcFile);
     2514    int rc = RTVfsFileGetSize(hIsoFile, &cbSrcFile);
    25202515    if (RT_SUCCESS(rc))
    25212516    {
     
    25302525            pThis->rc               = VINF_SUCCESS;
    25312526            pThis->pErrInfo         = pErrInfo;
    2532             pThis->hSrcFile         = hSrcFile;
     2527            pThis->hSrcFile         = hIsoFile;
    25332528            pThis->cbSrcFile        = cbSrcFile;
    25342529            pThis->cBlocksInSrcFile = cbSrcFile / ISO9660_SECTOR_SIZE;
     
    25482543             * Check if this looks like a plausible ISO by checking out the first volume descriptor.
    25492544             */
    2550             rc = RTVfsFileReadAt(hSrcFile, _32K, &pThis->uSectorBuf.PrimVolDesc, sizeof(pThis->uSectorBuf.PrimVolDesc), NULL);
     2545            rc = RTVfsFileReadAt(hIsoFile, _32K, &pThis->uSectorBuf.PrimVolDesc, sizeof(pThis->uSectorBuf.PrimVolDesc), NULL);
    25512546            if (RT_SUCCESS(rc))
    25522547            {
     
    26242619                        }
    26252620
    2626                         rc = RTVfsFileReadAt(hSrcFile, _32K + iVolDesc * ISO9660_SECTOR_SIZE,
     2621                        rc = RTVfsFileReadAt(hIsoFile, _32K + iVolDesc * ISO9660_SECTOR_SIZE,
    26272622                                             &pThis->uSectorBuf, sizeof(pThis->uSectorBuf), NULL);
    26282623                        if (RT_FAILURE(rc))
     
    26552650                    if (RT_SUCCESS(pThis->rc) || pThis->idxSrcFile != UINT32_MAX)
    26562651                    {
    2657                         rc = RTVfsFileReadAt(hSrcFile, 0, pThis->abBuf, _32K, NULL);
     2652                        rc = RTVfsFileReadAt(hIsoFile, 0, pThis->abBuf, _32K, NULL);
    26582653                        if (RT_SUCCESS(rc))
    26592654                        {
     
    26842679                        && (RT_SUCCESS(pThis->rc) || pThis->idxSrcFile != UINT32_MAX))
    26852680                    {
    2686                         rc = RTVfsFileReadAt(hSrcFile, _32K + iElTorito * ISO9660_SECTOR_SIZE,
     2681                        rc = RTVfsFileReadAt(hIsoFile, _32K + iElTorito * ISO9660_SECTOR_SIZE,
    26872682                                             &pThis->uSectorBuf, sizeof(pThis->uSectorBuf), NULL);
    26882683                        if (RT_SUCCESS(rc))
     
    27122707            rc = VERR_NO_MEMORY;
    27132708    }
    2714     RTVfsFileRelease(hSrcFile);
    27152709    return rc;
    2716 
    27172710}
    27182711
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