VirtualBox

Ignore:
Timestamp:
Nov 28, 2017 7:01:35 PM (7 years ago)
Author:
vboxsync
Message:

iprt/formats/ntfs: updates

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/vfs/vfsmount.cpp

    r69853 r69861  
    3535#include <iprt/assert.h>
    3636#include <iprt/err.h>
     37#include <iprt/file.h>
    3738#include <iprt/fsvfs.h>
    3839#include <iprt/mem.h>
    3940#include <iprt/log.h>
    4041#include <iprt/string.h>
     42#include <iprt/vfslowlevel.h>
    4143
    4244#include <iprt/formats/fat.h>
     
    422424
    423425    if (rtVfsMountIsNtfs(&pBuf->Bootsector))
    424         return RTERRINFO_LOG_SET(pErrInfo, VERR_VFS_UNSUPPORTED_FORMAT, "NTFS not yet supported");
     426        return RTFsNtfsVolOpen(hVfsFileIn, fFlags, 0 /*fNtfsFlags*/, phVfs, pErrInfo);
    425427
    426428    if (rtVfsMountIsHpfs(&pBuf->Bootsector, hVfsFileIn, pBuf2))
     
    462464}
    463465
     466
     467/**
     468 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnValidate}
     469 */
     470static DECLCALLBACK(int) rtVfsChainMountVol_Validate(PCRTVFSCHAINELEMENTREG pProviderReg, PRTVFSCHAINSPEC pSpec,
     471                                                     PRTVFSCHAINELEMSPEC pElement, uint32_t *poffError, PRTERRINFO pErrInfo)
     472{
     473    RT_NOREF(pProviderReg);
     474
     475    /*
     476     * Basic checks.
     477     */
     478    if (pElement->enmTypeIn != RTVFSOBJTYPE_FILE)
     479        return pElement->enmTypeIn == RTVFSOBJTYPE_INVALID ? VERR_VFS_CHAIN_CANNOT_BE_FIRST_ELEMENT : VERR_VFS_CHAIN_TAKES_FILE;
     480    if (   pElement->enmType != RTVFSOBJTYPE_VFS
     481        && pElement->enmType != RTVFSOBJTYPE_DIR)
     482        return VERR_VFS_CHAIN_ONLY_DIR_OR_VFS;
     483    if (pElement->cArgs > 1)
     484        return VERR_VFS_CHAIN_AT_MOST_ONE_ARG;
     485
     486    /*
     487     * Parse the flag if present, save in pElement->uProvider.
     488     */
     489    bool fReadOnly = (pSpec->fOpenFile & RTFILE_O_ACCESS_MASK) == RTFILE_O_READ;
     490    if (pElement->cArgs > 0)
     491    {
     492        const char *psz = pElement->paArgs[0].psz;
     493        if (*psz)
     494        {
     495            if (!strcmp(psz, "ro"))
     496                fReadOnly = true;
     497            else if (!strcmp(psz, "rw"))
     498                fReadOnly = false;
     499            else
     500            {
     501                *poffError = pElement->paArgs[0].offSpec;
     502                return RTErrInfoSet(pErrInfo, VERR_VFS_CHAIN_INVALID_ARGUMENT, "Expected 'ro' or 'rw' as argument");
     503            }
     504        }
     505    }
     506
     507    pElement->uProvider = fReadOnly ? RTVFSMNT_F_READ_ONLY : 0;
     508    return VINF_SUCCESS;
     509}
     510
     511
     512/**
     513 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnInstantiate}
     514 */
     515static DECLCALLBACK(int) rtVfsChainMountVol_Instantiate(PCRTVFSCHAINELEMENTREG pProviderReg, PCRTVFSCHAINSPEC pSpec,
     516                                                        PCRTVFSCHAINELEMSPEC pElement, RTVFSOBJ hPrevVfsObj,
     517                                                        PRTVFSOBJ phVfsObj, uint32_t *poffError, PRTERRINFO pErrInfo)
     518{
     519    RT_NOREF(pProviderReg, pSpec, poffError);
     520
     521    int         rc;
     522    RTVFSFILE   hVfsFileIn = RTVfsObjToFile(hPrevVfsObj);
     523    if (hVfsFileIn != NIL_RTVFSFILE)
     524    {
     525        RTVFS hVfs;
     526        rc = RTVfsMountVol(hVfsFileIn, (uint32_t)pElement->uProvider, &hVfs, pErrInfo);
     527        RTVfsFileRelease(hVfsFileIn);
     528        if (RT_SUCCESS(rc))
     529        {
     530            *phVfsObj = RTVfsObjFromVfs(hVfs);
     531            RTVfsRelease(hVfs);
     532            if (*phVfsObj != NIL_RTVFSOBJ)
     533                return VINF_SUCCESS;
     534            rc = VERR_VFS_CHAIN_CAST_FAILED;
     535        }
     536    }
     537    else
     538        rc = VERR_VFS_CHAIN_CAST_FAILED;
     539    return rc;
     540}
     541
     542
     543/**
     544 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnCanReuseElement}
     545 */
     546static DECLCALLBACK(bool) rtVfsChainMountVol_CanReuseElement(PCRTVFSCHAINELEMENTREG pProviderReg,
     547                                                             PCRTVFSCHAINSPEC pSpec, PCRTVFSCHAINELEMSPEC pElement,
     548                                                             PCRTVFSCHAINSPEC pReuseSpec, PCRTVFSCHAINELEMSPEC pReuseElement)
     549{
     550    RT_NOREF(pProviderReg, pSpec, pReuseSpec);
     551    if (   pElement->paArgs[0].uProvider == pReuseElement->paArgs[0].uProvider
     552        || !pReuseElement->paArgs[0].uProvider)
     553        return true;
     554    return false;
     555}
     556
     557
     558/** VFS chain element 'file'. */
     559static RTVFSCHAINELEMENTREG g_rtVfsChainMountVolReg =
     560{
     561    /* uVersion = */            RTVFSCHAINELEMENTREG_VERSION,
     562    /* fReserved = */           0,
     563    /* pszName = */             "mount",
     564    /* ListEntry = */           { NULL, NULL },
     565    /* pszHelp = */             "Open a file system, requires a file object on the left side.\n"
     566                                "First argument is an optional 'ro' (read-only) or 'rw' (read-write) flag.\n",
     567    /* pfnValidate = */         rtVfsChainMountVol_Validate,
     568    /* pfnInstantiate = */      rtVfsChainMountVol_Instantiate,
     569    /* pfnCanReuseElement = */  rtVfsChainMountVol_CanReuseElement,
     570    /* uEndMarker = */          RTVFSCHAINELEMENTREG_VERSION
     571};
     572
     573RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER(&g_rtVfsChainMountVolReg, rtVfsChainMountVolReg);
     574
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