VirtualBox

Changeset 69813 in vbox


Ignore:
Timestamp:
Nov 23, 2017 6:33:30 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
119237
Message:

IPRT: VFS opening reworking in progress.

Location:
trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/err.h

    r69716 r69813  
    11981198/** Symbolic link not allowed. */
    11991199#define VERR_SYMLINK_NOT_ALLOWED            (-159)
     1200/** Is a symbolic link. */
     1201#define VERR_IS_A_SYMLINK                   (-160)
     1202/** Is a FIFO. */
     1203#define VERR_IS_A_FIFO                      (-161)
     1204/** Is a socket. */
     1205#define VERR_IS_A_SOCKET                    (-162)
     1206/** Is a block device. */
     1207#define VERR_IS_A_BLOCK_DEVICE              (-163)
     1208/** Is a character device. */
     1209#define VERR_IS_A_CHAR_DEVICE               (-164)
    12001210/** @} */
    12011211
     
    27862796/** Unsupported file system format. */
    27872797#define VERR_VFS_UNSUPPORTED_FORMAT                 (-24803)
     2798/** Unsupported create type in an RTVfsObjOpen or RTVfsDirOpenObj call.  */
     2799#define VERR_VFS_UNSUPPORTED_CREATE_TYPE            (-24804)
    27882800/** @} */
    27892801
  • trunk/include/iprt/mangling.h

    r69757 r69813  
    24212421# define RTVfsChainMsgError                             RT_MANGLER(RTVfsChainMsgError)
    24222422# define RTVfsChainMsgErrorExitFailure                  RT_MANGLER(RTVfsChainMsgErrorExitFailure)
     2423# define RTVfsChainOpenObj                              RT_MANGLER(RTVfsChainOpenObj)
    24232424# define RTVfsChainOpenDir                              RT_MANGLER(RTVfsChainOpenDir)
    24242425# define RTVfsChainOpenParentDir                        RT_MANGLER(RTVfsChainOpenParentDir)
     
    24402441# define RTVfsDirOpenFile                               RT_MANGLER(RTVfsDirOpenFile)
    24412442# define RTVfsDirOpenFileAsIoStream                     RT_MANGLER(RTVfsDirOpenFileAsIoStream)
     2443# define RTVfsDirOpenObj                                RT_MANGLER(RTVfsDirOpenObj)
    24422444# define RTVfsDirQueryPathInfo                          RT_MANGLER(RTVfsDirQueryPathInfo)
    24432445# define RTVfsDirReadEx                                 RT_MANGLER(RTVfsDirReadEx)
    24442446# define RTVfsDirRemoveDir                              RT_MANGLER(RTVfsDirRemoveDir)
     2447# define RTVfsDirSetPathMode                            RT_MANGLER(RTVfsDirSetPathMode)
    24452448# define RTVfsFileFlush                                 RT_MANGLER(RTVfsFileFlush)
    24462449# define RTVfsFileFromBuffer                            RT_MANGLER(RTVfsFileFromBuffer)
     
    25272530# define RTVfsObjFromSymlink                            RT_MANGLER(RTVfsObjFromSymlink)
    25282531# define RTVfsObjFromVfs                                RT_MANGLER(RTVfsObjFromVfs)
     2532# define RTVfsObjGetType                                RT_MANGLER(RTVfsObjGetType)
     2533# define RTVfsObjOpen                                   RT_MANGLER(RTVfsObjOpen)
    25292534# define RTVfsObjQueryInfo                              RT_MANGLER(RTVfsObjQueryInfo)
    25302535# define RTVfsObjRelease                                RT_MANGLER(RTVfsObjRelease)
    25312536# define RTVfsObjRetain                                 RT_MANGLER(RTVfsObjRetain)
    25322537# define RTVfsObjRetainDebug                            RT_MANGLER(RTVfsObjRetainDebug)
     2538# define RTVfsObjSetMode                                RT_MANGLER(RTVfsObjSetMode)
     2539# define RTVfsObjSetOwner                               RT_MANGLER(RTVfsObjSetOwner)
     2540# define RTVfsObjSetTimes                               RT_MANGLER(RTVfsObjSetTimes)
    25332541# define RTVfsObjToDir                                  RT_MANGLER(RTVfsObjToDir)
    25342542# define RTVfsObjToFile                                 RT_MANGLER(RTVfsObjToFile)
  • trunk/include/iprt/vfs.h

    r69753 r69813  
    166166RTDECL(uint32_t)        RTVfsObjRelease(RTVFSOBJ hVfsObj);
    167167
     168/** @name RTVFSOBJ_F_XXX - Flags or RTVfsObjOpen and RTVfsDirOpenObj.
     169 * @note Must leave space for RTPATH_F_XXX.
     170 * @{ */
     171/** Directory (RTFS_TYPE_DIRECTORY). */
     172#define RTVFSOBJ_F_OPEN_DIRECTORY           RT_BIT_32(8)
     173/** Symbolic link (RTFS_TYPE_SYMLINK). */
     174#define RTVFSOBJ_F_OPEN_SYMLINK             RT_BIT_32(9)
     175/** Regular file (RTFS_TYPE_FILE). */
     176#define RTVFSOBJ_F_OPEN_FILE                RT_BIT_32(10)
     177/** Character device (RTFS_TYPE_DEV_CHAR). */
     178#define RTVFSOBJ_F_OPEN_DEV_CHAR            RT_BIT_32(11)
     179/** Block device (RTFS_TYPE_DEV_BLOCK). */
     180#define RTVFSOBJ_F_OPEN_DEV_BLOCK           RT_BIT_32(12)
     181/** Named pipe (fifo) (RTFS_TYPE_FIFO). */
     182#define RTVFSOBJ_F_OPEN_FIFO                RT_BIT_32(13)
     183/** Socket (RTFS_TYPE_SOCKET). */
     184#define RTVFSOBJ_F_OPEN_SOCKET              RT_BIT_32(14)
     185/** Mask object types we wish to open. */
     186#define RTVFSOBJ_F_OPEN_MASK                UINT32_C(0x00003f00)
     187/** Any kind of object that translates to RTVFSOBJTYPE_FILE. */
     188#define RTVFSOBJ_F_OPEN_ANY_FILE            (RTVFSOBJ_F_FILE | RTVFSOBJ_F_DEV_BLOCK)
     189/** Any kind of object that translates to RTVFSOBJTYPE_IOS or
     190 *  RTVFSOBJTYPE_FILE. */
     191#define RTVFSOBJ_F_OPEN_ANY_IO_STREAM       (RTVFSOBJ_F_ANY_FILE | RTVFSOBJ_F_DEV_BLOCK | RTVFSOBJ_F_FIFO | RTVFSOBJ_F_SOCKET)
     192/** Any kind of object. */
     193#define RTVFSOBJ_F_OPEN_ANY                 RTVFSOBJ_F_OPEN_MASK
     194
     195/** Do't create anything, return file not found. */
     196#define RTVFSOBJ_F_CREATE_NOTHING           UINT32_C(0x00000000)
     197/** Create a file if the if the object was not found and the RTFILE_O_XXX
     198 * flags allows it. */
     199#define RTVFSOBJ_F_CREATE_FILE              UINT32_C(0x00010000)
     200/** Create a directory if the object was not found and the RTFILE_O_XXX
     201 * flags allows it. */
     202#define RTVFSOBJ_F_CREATE_DIRECTORY         UINT32_C(0x00020000)
     203/** The creation type mask. */
     204#define RTVFSOBJ_F_CREATE_MASK              UINT32_C(0x00070000)
     205
     206/** Indicate that this call is for traversal.
     207 * @internal only  */
     208#define RTVFSOBJ_F_TRAVERSAL                RT_BIT_32(31)
     209/** Valid mask for external callers. */
     210#define RTVFSOBJ_F_VALID_MASK               UINT32_C(0x00003f00)
     211/** @} */
     212
     213/**
     214 * Opens any file system object in the given VFS.
     215 *
     216 * @returns IPRT status code.
     217 * @param   hVfs            The VFS to open the object within.
     218 * @param   pszPath         Path to the file.
     219 * @param   fFileOpen       RTFILE_O_XXX flags.
     220 * @param   fObjFlags       More flags: RTVFSOBJ_F_XXX, RTPATH_F_XXX.
     221 * @param   phVfsObj        Where to return the object handle.
     222 * @sa      RTVfsDirOpenObj, RTVfsDirOpenDir, RTVfsDirOpenFile
     223 */
     224RTDECL(int)             RTVfsObjOpen(RTVFS hVfs, const char *pszPath, uint64_t fFileOpen, uint32_t fObjFlags, PRTVFSOBJ phVfsObj);
     225
    168226/**
    169227 * Query information about the object.
     
    181239RTDECL(int)             RTVfsObjQueryInfo(RTVFSOBJ hVfsObj, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr);
    182240
     241/**
     242 * Sets the file mode for the given VFS object.
     243 *
     244 * @returns IPRT status code.
     245 * @retval  VERR_INVALID_FUNCTION if the object type has no file mode to set.
     246 *          Only directories, files and symbolic links support this operation.
     247 *
     248 * @param   hVfsObj         The VFS object handle.
     249 * @param   fMode           The mode mask.
     250 * @param   fMask           The bits in the mode mask which should be changed.
     251 */
     252RTDECL(int)             RTVfsObjSetMode(RTVFSOBJ hVfsObj, RTFMODE fMode, RTFMODE fMask);
     253
     254/**
     255 * Sets one or more timestamps for the given VFS object.
     256 *
     257 * @returns IPRT status code.
     258 * @retval  VERR_INVALID_FUNCTION if the object type has no file mode to set.
     259 *          Only directories, files and symbolic links support this operation.
     260 *
     261 * @param   hVfsObj             The VFS object handle.
     262 * @param   pAccessTime         Pointer to the new access time. NULL if not to
     263 *                              be changed.
     264 * @param   pModificationTime   Pointer to the new modifcation time. NULL if not
     265 *                              to be changed.
     266 * @param   pChangeTime         Pointer to the new change time. NULL if not to
     267 *                              be changed.
     268 * @param   pBirthTime          Pointer to the new time of birth. NULL if not to
     269 *                              be changed.
     270 *
     271 * @remarks See RTFileSetTimes for restrictions and behavior imposed by the
     272 *          host OS or underlying VFS provider.
     273 * @sa      RTFileSetTimes, RTPathSetTimes
     274 */
     275RTDECL(int)             RTVfsObjSetTimes(RTVFSOBJ hVfsObj, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
     276                                         PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime);
     277
     278/**
     279 * Set the unix style owner and group on the given VFS object.
     280 *
     281 * @returns IPRT status code.
     282 * @retval  VERR_INVALID_FUNCTION if the object type has no file mode to set.
     283 *          Only directories, files and symbolic links support this operation.
     284 *
     285 * @param   hVfsObj         The VFS object handle.
     286 * @param   uid             The user ID of the new owner.  NIL_RTUID if
     287 *                          unchanged.
     288 * @param   gid             The group ID of the new owner group. NIL_RTGID if
     289 *                          unchanged.
     290 *
     291 * @sa      RTFileSetOwner, RTPathSetOwner.
     292 */
     293RTDECL(int)             RTVfsObjSetOwner(RTVFSOBJ hVfsObj, RTUID uid, RTGID gid);
     294
     295
     296/**
     297 * Gets the type of a VFS object.
     298 *
     299 * @returns The VFS object type on success, RTVFSOBJTYPE_INVALID on failure.
     300 * @param   hVfsObj         The VFS base object handle.
     301 */
     302RTDECL(RTVFSOBJTYPE)    RTVfsObjGetType(RTVFSOBJ hVfsObj);
    183303
    184304/**
     
    440560
    441561/**
     562 * Opens any file system object in or under the given directory.
     563 *
     564 * @returns IPRT status code.
     565 * @param   hVfsDir         The VFS directory start walking the @a pszPath
     566 *                          relative to.
     567 * @param   pszPath         Path to the file.
     568 * @param   fFileOpen       RTFILE_O_XXX flags.
     569 * @param   fObjFlags       More flags: RTVFSOBJ_F_XXX, RTPATH_F_XXX.
     570 * @param   phVfsObj        Where to return the object handle.
     571 * @sa      RTVfsObjOpen, RTVfsDirOpenDir, RTVfsDirOpenFile
     572 */
     573RTDECL(int) RTVfsDirOpenObj(RTVFSDIR hVfsDir, const char *pszPath, uint64_t fFileOpen, uint32_t fObjFlags, PRTVFSOBJ phVfsObj);
     574
     575/**
    442576 * Opens a file in or under the given directory.
    443577 *
     
    15591693RTDECL(int) RTVfsChainOpenVfs(const char *pszSpec, PRTVFS phVfs, uint32_t *poffError, PRTERRINFO pErrInfo);
    15601694RTDECL(int) RTVfsChainOpenFsStream(const char *pszSpec, PRTVFSFSSTREAM  phVfsFss, uint32_t *poffError, PRTERRINFO pErrInfo);
     1695
     1696/**
     1697 * Opens any kind of file system object.
     1698 *
     1699 * @returns IPRT status code.
     1700 * @param   pszSpec         The VFS chain specification or plain path.
     1701 * @param   fFileOpen       RTFILE_O_XXX flags.
     1702 * @param   fObjFlags       More flags: RTVFSOBJ_F_XXX, RTPATH_F_XXX.
     1703 * @param   phVfsObj        Where to return the handle to the opened object.
     1704 * @param   poffError       Where to on error return an offset into @a pszSpec
     1705 *                          of what cause the error.  Optional.
     1706 * @param   pErrInfo        Where to return additional error information.
     1707 *                          Optional.
     1708 */
     1709RTDECL(int) RTVfsChainOpenObj(const char *pszSpec, uint64_t fFileOpen, uint32_t fObjOpen,
     1710                              PRTVFSOBJ phVfsObj, uint32_t *poffError, PRTERRINFO pErrInfo);
     1711
    15611712RTDECL(int) RTVfsChainOpenDir(const char *pszSpec, uint32_t fOpen, PRTVFSDIR phVfsDir, uint32_t *poffError, PRTERRINFO pErrInfo);
    15621713RTDECL(int) RTVfsChainOpenParentDir(const char *pszSpec, uint32_t fOpen, PRTVFSDIR phVfsDir, const char **ppszChild,
  • trunk/include/iprt/vfslowlevel.h

    r69716 r69813  
    523523
    524524    /**
     525     * Generic method for opening any kind of file system object.
     526     *
     527     * Can also create files and directories.  Symbolic links, devices and such
     528     * needs to be created using special methods or this would end up being way more
     529     * complicated than it already is.
     530     *
     531     * There are optional specializations available.
     532     *
     533     * @returns IPRT status code.
     534     * @retval  VERR_PATH_NOT_FOUND or VERR_FILE_NOT_FOUND if @a pszEntry was not
     535     *          found.
     536     * @retval  VERR_IS_A_FILE if @a pszEntry is a file or similar but @a fFlags
     537     *          indicates that the type of object should not be opened.
     538     * @retval  VERR_IS_A_DIRECTORY if @a pszEntry is a directory but @a fFlags
     539     *          indicates that directories should not be opened.
     540     * @retval  VERR_IS_A_SYMLINK if @a pszEntry is a symbolic link but @a fFlags
     541     *          indicates that symbolic links should not be opened (or followed).
     542     * @retval  VERR_IS_A_FIFO if @a pszEntry is a FIFO but @a fFlags indicates that
     543     *          FIFOs should not be opened.
     544     * @retval  VERR_IS_A_SOCKET if @a pszEntry is a socket but @a fFlags indicates
     545     *          that sockets should not be opened.
     546     * @retval  VERR_IS_A_BLOCK_DEVICE if @a pszEntry is a block device but
     547     *          @a fFlags indicates that block devices should not be opened.
     548     * @retval  VERR_IS_A_BLOCK_DEVICE if @a pszEntry is a character device but
     549     *          @a fFlags indicates that character devices should not be opened.
     550     *
     551     * @param   pvThis      The implementation specific directory data.
     552     * @param   pszEntry    The name of the immediate file to open or create.
     553     * @param   fOpenFile   RTFILE_O_XXX combination.  Currently RTFILE_O_OPEN is
     554     *                      required, but this may change.
     555     * @param   fObjFlags   More flags: RTVFSOBJ_F_XXX, RTPATH_F_XXX.
     556     *                      The meaning of RTPATH_F_FOLLOW_LINK differs here, if
     557     *                      @a pszEntry is a symlink it should be opened for
     558     *                      traversal rather than according to @a fOpenFile.
     559     * @param   phVfsObj    Where to return the handle to the opened object.
     560     * @sa      RTFileOpen, RTDirOpen
     561     */
     562    DECLCALLBACKMEMBER(int, pfnOpen)(void *pvThis, const char *pszEntry, uint64_t fOpenFile,
     563                                     uint32_t fObjFlags, PRTVFSOBJ phVfsObj);
     564
     565    /**
    525566     * Opens a directory entry for traversal purposes.
    526567     *
     
    542583     * @todo    Should com dir, symlinks and mount points using some common
    543584     *          ancestor "class".
     585     * @note    Will be replaced by pfnOpenObj.
    544586     */
    545587    DECLCALLBACKMEMBER(int, pfnTraversalOpen)(void *pvThis, const char *pszEntry, PRTVFSDIR phVfsDir,
     
    553595     * @param   pszFilename The name of the immediate file to open or create.
    554596     * @param   fOpen       The open flags (RTFILE_O_XXX).
    555      * @param   phVfsFile   Where to return the thandle to the opened file.
     597     * @param   phVfsFile   Where to return the handle to the opened file.
     598     * @note    Optional.  RTVFSDIROPS::pfnOpenObj will be used if NULL.
    556599     * @sa      RTFileOpen.
    557600     */
    558     DECLCALLBACKMEMBER(int, pfnOpenFile)(void *pvThis, const char *pszFilename, uint32_t fOpen, PRTVFSFILE phVfsFile);
     601    DECLCALLBACKMEMBER(int, pfnOpenFile)(void *pvThis, const char *pszFilename, uint64_t fOpen, PRTVFSFILE phVfsFile);
    559602
    560603    /**
     
    567610     * @param   phVfsDir    Where to return the handle to the opened directory.
    568611     *                      Optional.
     612     * @note    Optional.  RTVFSDIROPS::pfnOpenObj will be used if NULL.
    569613     * @sa      RTDirOpen.
    570614     */
     
    580624     * @param   phVfsDir    Where to optionally return the handle to the newly
    581625     *                      create directory.
     626     * @note    Optional.  RTVFSDIROPS::pfnOpenObj will be used if NULL.
    582627     * @sa      RTDirCreate.
    583628     */
     
    592637     * @param   phVfsSymlink    Where to optionally return the handle to the
    593638     *                      newly create symbolic link.
     639     * @note    Optional.  RTVFSDIROPS::pfnOpenObj will be used if NULL.
    594640     * @sa      RTSymlinkCreate.
    595641     */
     
    619665     * @param   pObjInfo    Where to return the info on success.
    620666     * @param   enmAddAttr  Which set of additional attributes to request.
    621      *
     667     * @note    Optional.  RTVFSDIROPS::pfnOpenObj and RTVFSOBJOPS::pfnQueryInfo
     668     *          will be used if NULL.
    622669     * @sa      RTPathQueryInfo, RTVFSOBJOPS::pfnQueryInfo
    623670     */
     
    11691216{
    11701217    /** Open directory flags (RTFILE_O_XXX). */
    1171     uint32_t                fOpenFile;
     1218    uint64_t                fOpenFile;
    11721219    /** To be defined. */
    11731220    uint32_t                fOpenDir;
  • trunk/src/VBox/Runtime/common/dvm/dvmvfs.cpp

    r69616 r69813  
    736736
    737737/**
    738  * @interface_method_impl{RTVFSDIROPS,pfnOpenFile}
    739  */
    740 static DECLCALLBACK(int) rtDvmVfsDir_OpenFile(void *pvThis, const char *pszFilename, uint32_t fOpen, PRTVFSFILE phVfsFile)
     738 * @interface_method_impl{RTVFSDIROPS,pfnOpen}
     739 */
     740static DECLCALLBACK(int) rtDvmVfsDir_Open(void *pvThis, const char *pszEntry, uint64_t fOpen, uint32_t fFlags, PRTVFSOBJ phVfsObj)
    741741{
    742742    PRTDVMVFSDIR pThis = (PRTDVMVFSDIR)pvThis;
    743743    RTDVMVOLUME  hVolume;
    744     int rc = rtDvmVfsDir_FindEntry(pThis, pszFilename, &hVolume);
     744    int rc = rtDvmVfsDir_FindEntry(pThis, pszEntry, &hVolume);
    745745    if (RT_SUCCESS(rc))
    746746    {
     
    749749            || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE)
    750750        {
    751             if (   !(fOpen & RTFILE_O_WRITE)
    752                 || !pThis->pVfsVol->fReadOnly)
    753                 rc = rtDvmVfsCreateFileForVolume(pThis->pVfsVol, hVolume, fOpen, phVfsFile);
     751            if (fFlags & (RTVFSOBJ_F_OPEN_FILE | RTVFSOBJ_F_OPEN_DEV_BLOCK))
     752            {
     753                if (   !(fOpen & RTFILE_O_WRITE)
     754                    || !pThis->pVfsVol->fReadOnly)
     755                {
     756                    RTVFSFILE hVfsFile;
     757                    rc = rtDvmVfsCreateFileForVolume(pThis->pVfsVol, hVolume, fOpen, &hVfsFile);
     758                    if (RT_SUCCESS(rc))
     759                    {
     760                        *phVfsObj = RTVfsObjFromFile(hVfsFile);
     761                        RTVfsFileRelease(hVfsFile);
     762                        AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
     763                    }
     764                }
     765                else
     766                    rc = VERR_WRITE_PROTECT;
     767            }
    754768            else
    755                 rc = VERR_WRITE_PROTECT;
     769                rc = VERR_IS_A_FILE;
    756770        }
    757771        else
    758772            rc = VERR_ALREADY_EXISTS;
    759773        RTDvmVolumeRelease(hVolume);
     774    }
     775    return rc;
     776}
     777
     778
     779/**
     780 * @interface_method_impl{RTVFSDIROPS,pfnOpenFile}
     781 */
     782static DECLCALLBACK(int) rtDvmVfsDir_OpenFile(void *pvThis, const char *pszFilename, uint64_t fOpen, PRTVFSFILE phVfsFile)
     783{
     784    RTVFSOBJ hVfsObj;
     785    int rc = rtDvmVfsDir_Open(pvThis, pszFilename, fOpen, RTVFSOBJ_F_OPEN_FILE, &hVfsObj);
     786    if (RT_SUCCESS(rc))
     787    {
     788        *phVfsFile = RTVfsObjToFile(hVfsObj);
     789        RTVfsObjRelease(hVfsObj);
    760790    }
    761791    return rc;
     
    9831013        RTVFSOBJSETOPS_VERSION
    9841014    },
     1015    rtDvmVfsDir_Open,
    9851016    rtDvmVfsDir_TraversalOpen,
    9861017    rtDvmVfsDir_OpenFile,
  • trunk/src/VBox/Runtime/common/fs/fatvfs.cpp

    r69678 r69813  
    20742074static int rtFsFatObj_SetMode(PRTFSFATOBJ pThis, RTFMODE fMode, RTFMODE fMask)
    20752075{
     2076    __debugbreak();
    20762077#if 0
    20772078    if (fMask != ~RTFS_TYPE_MASK)
     
    40544055
    40554056/**
     4057 * @interface_method_impl{RTVFSDIROPS,pfnOpen}
     4058 */
     4059static DECLCALLBACK(int) rtFsFatDir_Open(void *pvThis, const char *pszEntry, uint64_t fOpen,
     4060                                         uint32_t fFlags, PRTVFSOBJ phVfsObj)
     4061{
     4062    PRTFSFATDIR     pThis   = (PRTFSFATDIR)pvThis;
     4063    PRTFSFATDIRSHRD pShared = pThis->pShared;
     4064
     4065    /*
     4066     * Try open existing file.
     4067     */
     4068    uint32_t    offEntryInDir;
     4069    bool        fLong;
     4070    FATDIRENTRY DirEntry;
     4071    int rc = rtFsFatDirShrd_FindEntry(pShared, pszEntry, &offEntryInDir, &fLong, &DirEntry);
     4072    if (RT_SUCCESS(rc))
     4073    {
     4074        switch (DirEntry.fAttrib & (FAT_ATTR_DIRECTORY | FAT_ATTR_VOLUME))
     4075        {
     4076            case 0:
     4077                if (fFlags & RTVFSOBJ_F_OPEN_FILE)
     4078                {
     4079                    if (   !(DirEntry.fAttrib & FAT_ATTR_READONLY)
     4080                        || !(fOpen & RTFILE_O_WRITE))
     4081                    {
     4082                        if (   (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN
     4083                            || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE
     4084                            || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE)
     4085                        {
     4086                            RTVFSFILE hVfsFile;
     4087                            rc = rtFsFatFile_New(pShared->Core.pVol, pShared, &DirEntry, offEntryInDir, fOpen, &hVfsFile);
     4088                            if (RT_SUCCESS(rc))
     4089                            {
     4090                                *phVfsObj = RTVfsObjFromFile(hVfsFile);
     4091                                RTVfsFileRelease(hVfsFile);
     4092                                AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
     4093                            }
     4094                        }
     4095                        else
     4096                            rc = VERR_ALREADY_EXISTS;
     4097                    }
     4098                    else
     4099                        rc = VERR_ACCESS_DENIED;
     4100                }
     4101                else
     4102                    rc = VERR_IS_A_FILE;
     4103                break;
     4104
     4105            case FAT_ATTR_DIRECTORY:
     4106                if (fFlags & RTVFSOBJ_F_OPEN_DIRECTORY)
     4107                {
     4108                    if (   !(DirEntry.fAttrib & FAT_ATTR_READONLY)
     4109                        || !(fOpen & RTFILE_O_WRITE))
     4110                    {
     4111                        if (   (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN
     4112                            || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE)
     4113                        {
     4114                            RTVFSDIR hVfsDir;
     4115                            rc = rtFsFatDir_New(pShared->Core.pVol, pShared, &DirEntry, offEntryInDir,
     4116                                                RTFSFAT_GET_CLUSTER(&DirEntry, pShared->Core.pVol), UINT64_MAX /*offDisk*/,
     4117                                                DirEntry.cbFile, &hVfsDir);
     4118                            if (RT_SUCCESS(rc))
     4119                            {
     4120                                *phVfsObj = RTVfsObjFromDir(hVfsDir);
     4121                                RTVfsDirRelease(hVfsDir);
     4122                                AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
     4123                            }
     4124                        }
     4125                        else if ((fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE)
     4126                            rc = VERR_INVALID_FUNCTION;
     4127                        else
     4128                            rc = VERR_ALREADY_EXISTS;
     4129                    }
     4130                    else
     4131                        rc = VERR_ACCESS_DENIED;
     4132                }
     4133                else
     4134                    rc = VERR_IS_A_DIRECTORY;
     4135                break;
     4136
     4137            default:
     4138                rc = VERR_PATH_NOT_FOUND;
     4139                break;
     4140        }
     4141    }
     4142    /*
     4143     * Create a file or directory?
     4144     */
     4145    else if (rc == VERR_FILE_NOT_FOUND)
     4146    {
     4147        if (   (   (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE
     4148                || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE
     4149                || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE)
     4150            && (fFlags & RTVFSOBJ_F_CREATE_MASK) != RTVFSOBJ_F_CREATE_NOTHING)
     4151        {
     4152            if ((fFlags & RTVFSOBJ_F_CREATE_MASK) == RTVFSOBJ_F_CREATE_FILE)
     4153            {
     4154                rc = rtFsFatDirShrd_CreateEntry(pShared, pszEntry, FAT_ATTR_ARCHIVE, 0 /*cbInitial*/, &offEntryInDir, &DirEntry);
     4155                if (RT_SUCCESS(rc))
     4156                {
     4157                    RTVFSFILE hVfsFile;
     4158                    rc = rtFsFatFile_New(pShared->Core.pVol, pShared, &DirEntry, offEntryInDir, fOpen, &hVfsFile);
     4159                    if (RT_SUCCESS(rc))
     4160                    {
     4161                        *phVfsObj = RTVfsObjFromFile(hVfsFile);
     4162                        RTVfsFileRelease(hVfsFile);
     4163                        AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
     4164                    }
     4165                }
     4166            }
     4167            else if ((fFlags & RTVFSOBJ_F_CREATE_MASK) == RTVFSOBJ_F_CREATE_DIRECTORY)
     4168            {
     4169                rc = rtFsFatDirShrd_CreateEntry(pShared, pszEntry, FAT_ATTR_ARCHIVE | FAT_ATTR_DIRECTORY,
     4170                                                pShared->Core.pVol->cbCluster, &offEntryInDir, &DirEntry);
     4171                if (RT_SUCCESS(rc))
     4172                {
     4173                    RTVFSDIR hVfsDir;
     4174                    rc = rtFsFatDir_New(pShared->Core.pVol, pShared, &DirEntry, offEntryInDir,
     4175                                        RTFSFAT_GET_CLUSTER(&DirEntry, pShared->Core.pVol), UINT64_MAX /*offDisk*/,
     4176                                        DirEntry.cbFile, &hVfsDir);
     4177                    if (RT_SUCCESS(rc))
     4178                    {
     4179                        *phVfsObj = RTVfsObjFromDir(hVfsDir);
     4180                        RTVfsDirRelease(hVfsDir);
     4181                        AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
     4182                    }
     4183                }
     4184            }
     4185            else
     4186                rc = VERR_VFS_UNSUPPORTED_CREATE_TYPE;
     4187        }
     4188    }
     4189
     4190    return rc;
     4191}
     4192
     4193
     4194/**
    40564195 * @interface_method_impl{RTVFSDIROPS,pfnOpenFile}
    40574196 */
    4058 static DECLCALLBACK(int) rtFsFatDir_OpenFile(void *pvThis, const char *pszFilename, uint32_t fOpen, PRTVFSFILE phVfsFile)
     4197static DECLCALLBACK(int) rtFsFatDir_OpenFile(void *pvThis, const char *pszFilename, uint64_t fOpen, PRTVFSFILE phVfsFile)
    40594198{
    40604199    PRTFSFATDIR     pThis   = (PRTFSFATDIR)pvThis;
     
    46394778        RTVFSOBJSETOPS_VERSION
    46404779    },
     4780    rtFsFatDir_Open,
    46414781    rtFsFatDir_TraversalOpen,
    46424782    rtFsFatDir_OpenFile,
  • trunk/src/VBox/Runtime/common/fs/isovfs.cpp

    r69594 r69813  
    29932993
    29942994/**
     2995 * @interface_method_impl{RTVFSDIROPS,pfnOpen}
     2996 */
     2997static DECLCALLBACK(int) rtFsIsoDir_Open(void *pvThis, const char *pszEntry, uint64_t fOpen,
     2998                                         uint32_t fFlags, PRTVFSOBJ phVfsObj)
     2999{
     3000    PRTFSISODIROBJ  pThis   = (PRTFSISODIROBJ)pvThis;
     3001    PRTFSISODIRSHRD pShared = pThis->pShared;
     3002
     3003    /*
     3004     * We cannot create or replace anything, just open stuff.
     3005     */
     3006    if (   (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE
     3007        || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE)
     3008        return VERR_WRITE_PROTECT;
     3009
     3010    /*
     3011     * Try open whatever it is.
     3012     */
     3013    int rc;
     3014    if (pShared->Core.pVol->enmType != RTFSISOVOLTYPE_UDF)
     3015    {
     3016        /*
     3017         * ISO 9660
     3018         */
     3019        PCISO9660DIRREC pDirRec;
     3020        uint64_t        offDirRec;
     3021        uint32_t        cDirRecs;
     3022        RTFMODE         fMode;
     3023        uint32_t        uVersion;
     3024        rc = rtFsIsoDir_FindEntry9660(pShared, pszEntry, &offDirRec, &pDirRec, &cDirRecs, &fMode, &uVersion);
     3025        Log2(("rtFsIsoDir_Open: FindEntry9660(,%s,) -> %Rrc\n", pszEntry, rc));
     3026        if (RT_SUCCESS(rc))
     3027        {
     3028            switch (fMode & RTFS_TYPE_MASK)
     3029            {
     3030                case RTFS_TYPE_FILE:
     3031                    if (fFlags & RTVFSOBJ_F_OPEN_FILE)
     3032                    {
     3033                        RTVFSFILE hVfsFile;
     3034                        rc = rtFsIsoFile_New9660(pShared->Core.pVol, pShared, pDirRec, cDirRecs,
     3035                                                 offDirRec, fOpen, uVersion, &hVfsFile);
     3036                        if (RT_SUCCESS(rc))
     3037                        {
     3038                            *phVfsObj = RTVfsObjFromFile(hVfsFile);
     3039                            RTVfsFileRelease(hVfsFile);
     3040                            AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
     3041                        }
     3042                    }
     3043                    else
     3044                        rc = VERR_IS_A_FILE;
     3045                    break;
     3046
     3047                case RTFS_TYPE_DIRECTORY:
     3048                    if (fFlags & RTVFSOBJ_F_OPEN_DIRECTORY)
     3049                    {
     3050                        RTVFSDIR hVfsDir;
     3051                        rc = rtFsIsoDir_New9660(pShared->Core.pVol, pShared, pDirRec, cDirRecs, offDirRec, &hVfsDir);
     3052                        if (RT_SUCCESS(rc))
     3053                        {
     3054                            *phVfsObj = RTVfsObjFromDir(hVfsDir);
     3055                            RTVfsDirRelease(hVfsDir);
     3056                            AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
     3057                        }
     3058                    }
     3059                    else
     3060                        rc = VERR_IS_A_DIRECTORY;
     3061                    break;
     3062
     3063                case RTFS_TYPE_SYMLINK:
     3064                case RTFS_TYPE_DEV_BLOCK:
     3065                case RTFS_TYPE_DEV_CHAR:
     3066                case RTFS_TYPE_FIFO:
     3067                case RTFS_TYPE_SOCKET:
     3068                case RTFS_TYPE_WHITEOUT:
     3069                    rc = VERR_NOT_IMPLEMENTED;
     3070                    break;
     3071
     3072                default:
     3073                    rc = VERR_PATH_NOT_FOUND;
     3074                    break;
     3075            }
     3076        }
     3077    }
     3078    else
     3079    {
     3080        /*
     3081         * UDF
     3082         */
     3083        PCUDFFILEIDDESC pFid;
     3084        rc = rtFsIsoDir_FindEntryUdf(pShared, pszEntry, &pFid);
     3085        Log2(("rtFsIsoDir_Open: FindEntryUdf(,%s,) -> %Rrc\n", pszEntry, rc));
     3086        if (RT_SUCCESS(rc))
     3087        {
     3088            if (!(pFid->fFlags & UDF_FILE_FLAGS_DELETED))
     3089            {
     3090                if (!(pFid->fFlags & UDF_FILE_FLAGS_DIRECTORY))
     3091                {
     3092                    if (fFlags & RTVFSOBJ_F_OPEN_FILE)
     3093                    {
     3094                        RTVFSFILE hVfsFile;
     3095                        rc = rtFsIsoFile_NewUdf(pShared->Core.pVol, pShared, pFid, fOpen, &hVfsFile);
     3096                        if (RT_SUCCESS(rc))
     3097                        {
     3098                            *phVfsObj = RTVfsObjFromFile(hVfsFile);
     3099                            RTVfsFileRelease(hVfsFile);
     3100                            AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
     3101                        }
     3102                    }
     3103                    else
     3104                        rc = VERR_IS_A_FILE;
     3105                }
     3106                else
     3107                {
     3108                    if (fFlags & RTVFSOBJ_F_OPEN_DIRECTORY)
     3109                    {
     3110                        RTVFSDIR hVfsDir;
     3111                        rc = rtFsIsoDir_NewUdf(pShared->Core.pVol, pShared, pFid, &hVfsDir);
     3112                        if (RT_SUCCESS(rc))
     3113                        {
     3114                            *phVfsObj = RTVfsObjFromDir(hVfsDir);
     3115                            RTVfsDirRelease(hVfsDir);
     3116                            AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
     3117                        }
     3118                    }
     3119                    else
     3120                        rc = VERR_IS_A_DIRECTORY;
     3121                }
     3122            }
     3123            /* We treat UDF_FILE_FLAGS_DELETED like RTFS_TYPE_WHITEOUT for now. */
     3124            else
     3125                rc = VERR_PATH_NOT_FOUND;
     3126        }
     3127    }
     3128    return rc;
     3129
     3130}
     3131
     3132
     3133/**
    29953134 * @interface_method_impl{RTVFSDIROPS,pfnOpenFile}
    29963135 */
    2997 static DECLCALLBACK(int) rtFsIsoDir_OpenFile(void *pvThis, const char *pszFilename, uint32_t fOpen, PRTVFSFILE phVfsFile)
     3136static DECLCALLBACK(int) rtFsIsoDir_OpenFile(void *pvThis, const char *pszFilename, uint64_t fOpen, PRTVFSFILE phVfsFile)
    29983137{
    29993138    PRTFSISODIROBJ  pThis   = (PRTFSISODIROBJ)pvThis;
     
    36543793        RTVFSOBJSETOPS_VERSION
    36553794    },
     3795    rtFsIsoDir_Open,
    36563796    rtFsIsoDir_TraversalOpen,
    36573797    rtFsIsoDir_OpenFile,
  • trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp

    r69720 r69813  
    352352*********************************************************************************************************************************/
    353353DECLINLINE(uint32_t) rtVfsObjRelease(RTVFSOBJINTERNAL *pThis);
     354static int rtVfsTraverseToParent(RTVFSINTERNAL *pThis, PRTVFSPARSEDPATH pPath, uint32_t fFlags, RTVFSDIRINTERNAL **ppVfsParentDir);
    354355
    355356
     
    966967
    967968
     969RTDECL(RTVFSOBJTYPE)    RTVfsObjGetType(RTVFSOBJ hVfsObj)
     970{
     971    RTVFSOBJINTERNAL *pThis = hVfsObj;
     972    if (pThis != NIL_RTVFSOBJ)
     973    {
     974        AssertPtrReturn(pThis, RTVFSOBJTYPE_INVALID);
     975        AssertReturn(pThis->uMagic == RTVFSOBJ_MAGIC, RTVFSOBJTYPE_INVALID);
     976        return pThis->pOps->enmType;
     977    }
     978    return RTVFSOBJTYPE_INVALID;
     979}
     980
     981
    968982RTDECL(RTVFS)           RTVfsObjToVfs(RTVFSOBJ hVfsObj)
    969983{
     
    11671181
    11681182
     1183RTDECL(int)             RTVfsObjOpen(RTVFS hVfs, const char *pszPath, uint64_t fFileOpen, uint32_t fObjFlags, PRTVFSOBJ phVfsObj)
     1184{
     1185    /*
     1186     * Validate input.
     1187     */
     1188    RTVFSINTERNAL *pThis = hVfs;
     1189    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     1190    AssertReturn(pThis->uMagic == RTVFS_MAGIC, VERR_INVALID_HANDLE);
     1191    AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
     1192    AssertPtrReturn(phVfsObj, VERR_INVALID_POINTER);
     1193
     1194    int rc = rtFileRecalcAndValidateFlags(&fFileOpen);
     1195    if (RT_FAILURE(rc))
     1196        return rc;
     1197    AssertMsgReturn(   RTPATH_F_IS_VALID(fObjFlags, RTVFSOBJ_F_VALID_MASK)
     1198                    && (fObjFlags & RTVFSOBJ_F_CREATE_MASK) <= RTVFSOBJ_F_CREATE_DIRECTORY,
     1199                    ("fObjFlags=%#x\n", fObjFlags),
     1200                    VERR_INVALID_FLAGS);
     1201    /*
     1202     * Parse the path, assume current directory is root since we've got no
     1203     * caller context here.
     1204     */
     1205    PRTVFSPARSEDPATH pPath;
     1206    rc = RTVfsParsePathA(pszPath, "/", &pPath);
     1207    if (RT_SUCCESS(rc))
     1208    {
     1209        if (pPath->cComponents > 0)
     1210        {
     1211            /*
     1212             * Tranverse the path, resolving the parent node, not
     1213             * checking for symbolic links in the final element.
     1214             */
     1215            RTVFSDIRINTERNAL *pVfsParentDir;
     1216            rc = rtVfsTraverseToParent(pThis, pPath, RTPATH_F_ON_LINK, &pVfsParentDir);
     1217            if (RT_SUCCESS(rc))
     1218            {
     1219                const char *pszEntryName = &pPath->szPath[pPath->aoffComponents[pPath->cComponents - 1]];
     1220
     1221                /*
     1222                 * If we've got a trailing directory slash, use pfnOpenDir
     1223                 * instead of pfnOpenObj.
     1224                 */
     1225                if (pPath->fDirSlash)
     1226                {
     1227                    RTVFSDIR hVfsDir;
     1228                    RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock);
     1229                    rc = pVfsParentDir->pOps->pfnOpenDir(pVfsParentDir->Base.pvThis, pszEntryName, 0 /** @todo fFlags*/, &hVfsDir);
     1230                    RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock);
     1231                    if (RT_SUCCESS(rc))
     1232                    {
     1233                        *phVfsObj = RTVfsObjFromDir(hVfsDir);
     1234                        RTVfsDirRelease(hVfsDir);
     1235                        AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
     1236                    }
     1237                }
     1238                else
     1239                {
     1240                    RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock);
     1241                    rc = pVfsParentDir->pOps->pfnOpen(pVfsParentDir->Base.pvThis, pszEntryName, fFileOpen, fObjFlags, phVfsObj);
     1242                    RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock);
     1243                }
     1244                RTVfsDirRelease(pVfsParentDir);
     1245            }
     1246        }
     1247        /*
     1248         * The path boils down to '.', call pfnOpenDir on pThis with '.' as input.
     1249         * The caller may wish for a new directory instance to enumerate the entries
     1250         * in parallel or some such thing.
     1251         */
     1252        else
     1253        {
     1254            RTVFSDIR hVfsDir;
     1255            RTVfsLockAcquireRead(pThis->Base.hLock);
     1256            rc = pThis->pOps->pfnOpenRoot(pThis->Base.pvThis, &hVfsDir); /** @todo flags */
     1257            RTVfsLockReleaseRead(pThis->Base.hLock);
     1258            if (RT_SUCCESS(rc))
     1259            {
     1260                *phVfsObj = RTVfsObjFromDir(hVfsDir);
     1261                RTVfsDirRelease(hVfsDir);
     1262                AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
     1263            }
     1264        }
     1265
     1266        RTVfsParsePathFree(pPath);
     1267    }
     1268    return rc;
     1269}
     1270
    11691271
    11701272RTDECL(int)         RTVfsObjQueryInfo(RTVFSOBJ hVfsObj, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
     
    11801282}
    11811283
     1284
     1285/**
     1286 * Gets the RTVFSOBJSETOPS for the given base object.
     1287 *
     1288 * @returns Pointer to the vtable if supported by the type, otherwise NULL.
     1289 * @param   pThis               The base object.
     1290 */
     1291static PCRTVFSOBJSETOPS rtVfsObjGetSetOps(RTVFSOBJINTERNAL *pThis)
     1292{
     1293    switch (pThis->pOps->enmType)
     1294    {
     1295        case RTVFSOBJTYPE_DIR:
     1296            return &RT_FROM_MEMBER(pThis, RTVFSDIRINTERNAL, Base)->pOps->ObjSet;
     1297        case RTVFSOBJTYPE_FILE:
     1298            return &RT_FROM_MEMBER(pThis, RTVFSFILEINTERNAL, Stream.Base)->pOps->ObjSet;
     1299        case RTVFSOBJTYPE_SYMLINK:
     1300            return &RT_FROM_MEMBER(pThis, RTVFSSYMLINKINTERNAL, Base)->pOps->ObjSet;
     1301        default:
     1302            return NULL;
     1303    }
     1304}
     1305
     1306
     1307RTDECL(int)         RTVfsObjSetMode(RTVFSOBJ hVfsObj, RTFMODE fMode, RTFMODE fMask)
     1308{
     1309    RTVFSOBJINTERNAL *pThis = hVfsObj;
     1310    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     1311    AssertReturn(pThis->uMagic == RTVFSOBJ_MAGIC, VERR_INVALID_HANDLE);
     1312
     1313    fMode = rtFsModeNormalize(fMode, NULL, 0);
     1314    if (!rtFsModeIsValid(fMode))
     1315        return VERR_INVALID_PARAMETER;
     1316
     1317    PCRTVFSOBJSETOPS pObjSetOps = rtVfsObjGetSetOps(pThis);
     1318    AssertReturn(pObjSetOps, VERR_INVALID_FUNCTION);
     1319
     1320    RTVfsLockAcquireWrite(pThis->hLock);
     1321    int rc = pObjSetOps->pfnSetMode(pThis->pvThis, fMode, fMask);
     1322    RTVfsLockReleaseWrite(pThis->hLock);
     1323    return rc;
     1324}
     1325
     1326
     1327RTDECL(int)         RTVfsObjSetTimes(RTVFSOBJ hVfsObj, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
     1328                                     PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime)
     1329{
     1330    RTVFSOBJINTERNAL *pThis = hVfsObj;
     1331    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     1332    AssertReturn(pThis->uMagic == RTVFSOBJ_MAGIC, VERR_INVALID_HANDLE);
     1333
     1334    AssertPtrNullReturn(pAccessTime, VERR_INVALID_POINTER);
     1335    AssertPtrNullReturn(pModificationTime, VERR_INVALID_POINTER);
     1336    AssertPtrNullReturn(pChangeTime, VERR_INVALID_POINTER);
     1337    AssertPtrNullReturn(pBirthTime, VERR_INVALID_POINTER);
     1338
     1339    PCRTVFSOBJSETOPS pObjSetOps = rtVfsObjGetSetOps(pThis);
     1340    AssertReturn(pObjSetOps, VERR_INVALID_FUNCTION);
     1341
     1342    RTVfsLockAcquireWrite(pThis->hLock);
     1343    int rc = pObjSetOps->pfnSetTimes(pThis->pvThis, pAccessTime, pModificationTime, pChangeTime, pBirthTime);
     1344    RTVfsLockReleaseWrite(pThis->hLock);
     1345    return rc;
     1346}
     1347
     1348
     1349RTDECL(int)         RTVfsObjSetOwner(RTVFSOBJ hVfsObj, RTUID uid, RTGID gid)
     1350{
     1351    RTVFSOBJINTERNAL *pThis = hVfsObj;
     1352    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     1353    AssertReturn(pThis->uMagic == RTVFSOBJ_MAGIC, VERR_INVALID_HANDLE);
     1354
     1355    PCRTVFSOBJSETOPS pObjSetOps = rtVfsObjGetSetOps(pThis);
     1356    AssertReturn(pObjSetOps, VERR_INVALID_FUNCTION);
     1357
     1358    RTVfsLockAcquireWrite(pThis->hLock);
     1359    int rc = pObjSetOps->pfnSetOwner(pThis->pvThis, uid, gid);
     1360    RTVfsLockReleaseWrite(pThis->hLock);
     1361    return rc;
     1362}
    11821363
    11831364
     
    24262607
    24272608    /*
    2428      * Parse the path, assume current directory is root since we've got no
    2429      * caller context here.
     2609     * Parse the relative path.
    24302610     */
    24312611    PRTVFSPARSEDPATH pPath;
     
    24812661}
    24822662
     2663
     2664RTDECL(int) RTVfsDirOpenObj(RTVFSDIR hVfsDir, const char *pszPath, uint64_t fFileOpen, uint32_t fObjFlags, PRTVFSOBJ phVfsObj)
     2665{
     2666    /*
     2667     * Validate input.
     2668     */
     2669    RTVFSDIRINTERNAL *pThis = hVfsDir;
     2670    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     2671    AssertReturn(pThis->uMagic == RTVFSDIR_MAGIC, VERR_INVALID_HANDLE);
     2672    AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
     2673    AssertPtrReturn(phVfsObj, VERR_INVALID_POINTER);
     2674
     2675    int rc = rtFileRecalcAndValidateFlags(&fFileOpen);
     2676    if (RT_FAILURE(rc))
     2677        return rc;
     2678    AssertMsgReturn(   RTPATH_F_IS_VALID(fObjFlags, RTVFSOBJ_F_VALID_MASK)
     2679                    && (fObjFlags & RTVFSOBJ_F_CREATE_MASK) <= RTVFSOBJ_F_CREATE_DIRECTORY,
     2680                    ("fObjFlags=%#x\n", fObjFlags),
     2681                    VERR_INVALID_FLAGS);
     2682
     2683    /*
     2684     * Parse the relative path.
     2685     */
     2686    PRTVFSPARSEDPATH pPath;
     2687    rc = RTVfsParsePathA(pszPath, NULL, &pPath);
     2688    if (RT_SUCCESS(rc))
     2689    {
     2690        if (pPath->cComponents > 0)
     2691        {
     2692            /*
     2693             * Tranverse the path, resolving the parent node, not
     2694             * checking for symbolic links in the final element.
     2695             */
     2696            RTVFSDIRINTERNAL *pVfsParentDir;
     2697            rc = rtVfsDirTraverseToParent(pThis, pPath, RTPATH_F_ON_LINK, &pVfsParentDir);
     2698            if (RT_SUCCESS(rc))
     2699            {
     2700                const char *pszEntryName = &pPath->szPath[pPath->aoffComponents[pPath->cComponents - 1]];
     2701
     2702                /*
     2703                 * If we've got a trailing directory slash, use pfnOpenDir
     2704                 * instead of pfnOpenObj.
     2705                 */
     2706                if (pPath->fDirSlash)
     2707                {
     2708                    RTVFSDIR hVfsDir;
     2709                    RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock);
     2710                    rc = pVfsParentDir->pOps->pfnOpenDir(pVfsParentDir->Base.pvThis, pszEntryName, 0 /** @todo fFlags*/, &hVfsDir);
     2711                    RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock);
     2712                    if (RT_SUCCESS(rc))
     2713                    {
     2714                        *phVfsObj = RTVfsObjFromDir(hVfsDir);
     2715                        RTVfsDirRelease(hVfsDir);
     2716                        AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
     2717                    }
     2718                }
     2719                else
     2720                {
     2721                    RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock);
     2722                    rc = pVfsParentDir->pOps->pfnOpen(pVfsParentDir->Base.pvThis, pszEntryName, fFileOpen, fObjFlags, phVfsObj);
     2723                    RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock);
     2724                }
     2725                RTVfsDirRelease(pVfsParentDir);
     2726            }
     2727        }
     2728        /*
     2729         * The path boils down to '.', call pfnOpenDir on pThis with '.' as input.
     2730         * The caller may wish for a new directory instance to enumerate the entries
     2731         * in parallel or some such thing.
     2732         */
     2733        else
     2734        {
     2735            RTVFSDIR hVfsDir;
     2736            RTVfsLockAcquireWrite(pThis->Base.hLock);
     2737            rc = pThis->pOps->pfnOpenDir(pThis->Base.pvThis, ".", 0 /** @todo fFlags*/, &hVfsDir);
     2738            RTVfsLockReleaseWrite(pThis->Base.hLock);
     2739            if (RT_SUCCESS(rc))
     2740            {
     2741                *phVfsObj = RTVfsObjFromDir(hVfsDir);
     2742                RTVfsDirRelease(hVfsDir);
     2743                AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
     2744            }
     2745        }
     2746
     2747        RTVfsParsePathFree(pPath);
     2748    }
     2749    return rc;
     2750}
    24832751
    24842752
     
    32453513    RTVFSIOSTREAM_ASSERT_OPS(&pFileOps->Stream, RTVFSOBJTYPE_FILE);
    32463514    Assert(cbInstance > 0);
    3247     Assert(fOpen & RTFILE_O_ACCESS_MASK);
     3515    Assert(fOpen & (RTFILE_O_ACCESS_MASK | RTFILE_O_ACCESS_ATTR_MASK));
    32483516    AssertPtr(ppvInstance);
    32493517    AssertPtr(phVfsFile);
  • trunk/src/VBox/Runtime/common/vfs/vfschain.cpp

    r69716 r69813  
    11141114
    11151115
     1116RTDECL(int) RTVfsChainOpenObj(const char *pszSpec, uint64_t fFileOpen, uint32_t fObjFlags,
     1117                              PRTVFSOBJ phVfsObj, uint32_t *poffError, PRTERRINFO pErrInfo)
     1118{
     1119    /*
     1120     * Validate input.
     1121     */
     1122    uint32_t offErrorIgn;
     1123    if (!poffError)
     1124        poffError = &offErrorIgn;
     1125    *poffError = 0;
     1126    AssertPtrReturn(pszSpec, VERR_INVALID_POINTER);
     1127    AssertReturn(*pszSpec != '\0', VERR_INVALID_PARAMETER);
     1128    AssertPtrReturn(phVfsObj, VERR_INVALID_POINTER);
     1129    AssertPtrNullReturn(pErrInfo, VERR_INVALID_POINTER);
     1130
     1131    int rc = rtFileRecalcAndValidateFlags(&fFileOpen);
     1132    if (RT_FAILURE(rc))
     1133        return rc;
     1134    AssertMsgReturn(   RTPATH_F_IS_VALID(fObjFlags, RTVFSOBJ_F_VALID_MASK)
     1135                    && (fObjFlags & RTVFSOBJ_F_CREATE_MASK) <= RTVFSOBJ_F_CREATE_DIRECTORY,
     1136                    ("fObjFlags=%#x\n", fObjFlags),
     1137                    VERR_INVALID_FLAGS);
     1138
     1139    /*
     1140     * Try for a VFS chain first, falling back on regular file system stuff if it's just a path.
     1141     */
     1142    PRTVFSCHAINSPEC pSpec = NULL;
     1143    if (strncmp(pszSpec, RTVFSCHAIN_SPEC_PREFIX, sizeof(RTVFSCHAIN_SPEC_PREFIX) - 1) == 0)
     1144    {
     1145        rc = RTVfsChainSpecParse(pszSpec,  0 /*fFlags*/, RTVFSOBJTYPE_DIR, &pSpec, poffError);
     1146        if (RT_FAILURE(rc))
     1147            return rc;
     1148
     1149        Assert(pSpec->cElements > 0);
     1150        if (   pSpec->cElements > 1
     1151            || pSpec->paElements[0].enmType != RTVFSOBJTYPE_END)
     1152        {
     1153            const char *pszFinal = NULL;
     1154            RTVFSOBJ    hVfsObj  = NIL_RTVFSOBJ;
     1155            pSpec->fOpenFile = fFileOpen;
     1156            rc = RTVfsChainSpecCheckAndSetup(pSpec, NULL /*pReuseSpec*/, &hVfsObj, &pszFinal, poffError, pErrInfo);
     1157            if (RT_SUCCESS(rc))
     1158            {
     1159                if (!pszFinal)
     1160                {
     1161                    *phVfsObj = hVfsObj;
     1162                    rc = VINF_SUCCESS;
     1163                }
     1164                else
     1165                {
     1166                    /*
     1167                     * Do a file open with the final path on the returned object.
     1168                     */
     1169                    RTVFS           hVfs    = RTVfsObjToVfs(hVfsObj);
     1170                    RTVFSDIR        hVfsDir = RTVfsObjToDir(hVfsObj);
     1171                    RTVFSFSSTREAM   hVfsFss = RTVfsObjToFsStream(hVfsObj);
     1172                    if (hVfs != NIL_RTVFS)
     1173                        rc = RTVfsObjOpen(hVfs, pszFinal, fFileOpen, fObjFlags, phVfsObj);
     1174                    else if (hVfsDir != NIL_RTVFSDIR)
     1175                        rc = RTVfsDirOpenObj(hVfsDir, pszFinal, fFileOpen, fObjFlags, phVfsObj);
     1176                    else if (hVfsFss != NIL_RTVFSFSSTREAM)
     1177                        rc = VERR_NOT_IMPLEMENTED;
     1178                    else
     1179                        rc = VERR_VFS_CHAIN_TYPE_MISMATCH_PATH_ONLY;
     1180                    RTVfsRelease(hVfs);
     1181                    RTVfsDirRelease(hVfsDir);
     1182                    RTVfsFsStrmRelease(hVfsFss);
     1183                    RTVfsObjRelease(hVfsObj);
     1184                }
     1185            }
     1186
     1187            RTVfsChainSpecFree(pSpec);
     1188            return rc;
     1189        }
     1190
     1191        /* Only a path element. */
     1192        pszSpec = pSpec->paElements[0].paArgs[0].psz;
     1193    }
     1194
     1195    /*
     1196     * Path to regular file system.
     1197     * Go via the directory VFS wrapper to avoid duplicating code.
     1198     */
     1199    RTVFSDIR hVfsParentDir = NIL_RTVFSDIR;
     1200    const char *pszFilename;
     1201    if (RTPathHasPath(pszSpec))
     1202    {
     1203        char *pszCopy = RTStrDup(pszSpec);
     1204        if (pszCopy)
     1205        {
     1206            RTPathStripFilename(pszCopy);
     1207            rc = RTVfsDirOpenNormal(pszCopy, 0 /*fOpen*/, &hVfsParentDir);
     1208            RTStrFree(pszCopy);
     1209        }
     1210        else
     1211            rc = VERR_NO_STR_MEMORY;
     1212        pszFilename = RTPathFilename(pszSpec);
     1213    }
     1214    else
     1215    {
     1216        pszFilename = pszSpec;
     1217        rc = RTVfsDirOpenNormal(".", 0 /*fOpen*/, &hVfsParentDir);
     1218    }
     1219    if (RT_SUCCESS(rc))
     1220    {
     1221        rc = RTVfsDirOpenObj(hVfsParentDir, pszFilename, fFileOpen, fObjFlags, phVfsObj);
     1222        RTVfsDirRelease(hVfsParentDir);
     1223    }
     1224
     1225    RTVfsChainSpecFree(pSpec);
     1226    return rc;
     1227}
     1228
     1229
    11161230RTDECL(int) RTVfsChainOpenDir(const char *pszSpec, uint32_t fOpen,
    11171231                              PRTVFSDIR phVfsDir, uint32_t *poffError, PRTERRINFO pErrInfo)
     
    11411255            || pSpec->paElements[0].enmType != RTVFSOBJTYPE_END)
    11421256        {
    1143 
    11441257            const char *pszFinal = NULL;
    11451258            RTVFSOBJ    hVfsObj  = NIL_RTVFSOBJ;
     
    11501263                if (!pszFinal)
    11511264                {
    1152                     /* Try convert it to a file object and we're done. */
     1265                    /* Try convert it to a directory object and we're done. */
    11531266                    *phVfsDir = RTVfsObjToDir(hVfsObj);
    11541267                    if (*phVfsDir)
     
    11951308    RTVfsChainSpecFree(pSpec);
    11961309    return rc;
    1197 
    11981310}
    11991311
     
    16301742{
    16311743    return pszSpec
    1632         && strcmp(pszSpec, RTVFSCHAIN_SPEC_PREFIX) == 0;
     1744        && strncmp(pszSpec, RT_STR_TUPLE(RTVFSCHAIN_SPEC_PREFIX)) == 0;
    16331745}
    16341746
  • trunk/src/VBox/Runtime/common/vfs/vfsstddir.cpp

    r69753 r69813  
    305305
    306306/**
     307 * @interface_method_impl{RTVFSDIROPS,pfnOpenObj}
     308 */
     309static DECLCALLBACK(int) rtVfsStdDir_OpenObj(void *pvThis, const char *pszEntry, uint64_t fOpen,
     310                                             uint32_t fFlags, PRTVFSOBJ phVfsObj)
     311{
     312    PRTVFSSTDDIR pThis = (PRTVFSSTDDIR)pvThis;
     313
     314    /*
     315     * This is subject to race conditions, but we haven't too much of a choice
     316     * without going platform specific here (we'll do that eventually).
     317     */
     318    RTFSOBJINFO  ObjInfo;
     319    int rc = RTDirRelPathQueryInfo(pThis->hDir, pszEntry, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
     320    if (RT_SUCCESS(rc))
     321    {
     322        switch (ObjInfo.Attr.fMode & RTFS_TYPE_MASK)
     323        {
     324            case RTFS_TYPE_DIRECTORY:
     325                if (!(fFlags & RTVFSOBJ_F_OPEN_DIRECTORY))
     326                {
     327                    if (   (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN
     328                        || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE
     329                        || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE)
     330                    {
     331                        RTDIR hSubDir;
     332                        rc = RTDirRelDirOpenFiltered(pThis->hDir, pszEntry, RTDIRFILTER_NONE, fFlags, &hSubDir);
     333                        if (RT_SUCCESS(rc))
     334                        {
     335                            RTVFSDIR hVfsDir;
     336                            rc = rtVfsDirFromRTDir(hSubDir, 0 /** @todo subdir open/inherit flags... */, false, &hVfsDir);
     337                            if (RT_SUCCESS(rc))
     338                            {
     339                                *phVfsObj = RTVfsObjFromDir(hVfsDir);
     340                                RTVfsDirRelease(hVfsDir);
     341                                AssertStmt(*phVfsObj == NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
     342                            }
     343                            else
     344                                RTDirClose(hSubDir);
     345                        }
     346                    }
     347                    else
     348                        rc = VERR_ALREADY_EXISTS;
     349                }
     350                else
     351                    rc = VERR_IS_A_DIRECTORY;
     352                break;
     353
     354            case RTFS_TYPE_FILE:
     355            case RTFS_TYPE_DEV_BLOCK:
     356            case RTFS_TYPE_DEV_CHAR:
     357            case RTFS_TYPE_FIFO:
     358            case RTFS_TYPE_SOCKET:
     359                switch (ObjInfo.Attr.fMode & RTFS_TYPE_MASK)
     360                {
     361                    case RTFS_TYPE_FILE:
     362                        rc = fFlags & RTVFSOBJ_F_OPEN_FILE      ? VINF_SUCCESS : VERR_IS_A_FILE;
     363                        break;
     364                    case RTFS_TYPE_DEV_BLOCK:
     365                        rc = fFlags & RTVFSOBJ_F_OPEN_DEV_BLOCK ? VINF_SUCCESS : VERR_IS_A_BLOCK_DEVICE;
     366                        break;
     367                    case RTFS_TYPE_DEV_CHAR:
     368                        rc = fFlags & RTVFSOBJ_F_OPEN_DEV_CHAR  ? VINF_SUCCESS : VERR_IS_A_CHAR_DEVICE;
     369                        break;
     370                    /** @todo These two types should not result in files, but pure I/O streams.
     371                     *        possibly char device too.  */
     372                    case RTFS_TYPE_FIFO:
     373                        rc = fFlags & RTVFSOBJ_F_OPEN_FIFO      ? VINF_SUCCESS : VERR_IS_A_FIFO;
     374                        break;
     375                    case RTFS_TYPE_SOCKET:
     376                        rc = fFlags & RTVFSOBJ_F_OPEN_SOCKET    ? VINF_SUCCESS : VERR_IS_A_SOCKET;
     377                        break;
     378                    default:
     379                        rc = VERR_INVALID_FLAGS;
     380                        break;
     381                }
     382                if (RT_SUCCESS(rc))
     383                {
     384                    if (   (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN
     385                        || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE
     386                        || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE)
     387                    {
     388                        RTFILE hFile;
     389                        rc = RTDirRelFileOpen(pThis->hDir, pszEntry, fOpen, &hFile);
     390                        if (RT_SUCCESS(rc))
     391                        {
     392                            RTVFSFILE hVfsFile;
     393                            rc = RTVfsFileFromRTFile(hFile, fOpen, false /*fLeaveOpen*/, &hVfsFile);
     394                            if (RT_SUCCESS(rc))
     395                            {
     396                                *phVfsObj = RTVfsObjFromFile(hVfsFile);
     397                                RTVfsFileRelease(hVfsFile);
     398                                AssertStmt(*phVfsObj == NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
     399                            }
     400                            else
     401                                RTFileClose(hFile);
     402                        }
     403                    }
     404                    else
     405                        rc = VERR_ALREADY_EXISTS;
     406                }
     407                break;
     408
     409            case RTFS_TYPE_SYMLINK:
     410                if (fFlags & RTVFSOBJ_F_OPEN_SYMLINK)
     411                {
     412                    uint32_t cRefs = RTVfsDirRetain(pThis->hSelf);
     413                    if (cRefs != UINT32_MAX)
     414                    {
     415                        RTVFSSYMLINK     hVfsSymlink;
     416                        PRTVFSSTDSYMLINK pNewSymlink;
     417                        size_t           cchSymlink = strlen(pszEntry);
     418                        rc = RTVfsNewSymlink(&g_rtVfsStdSymOps, RT_UOFFSETOF(RTVFSSTDSYMLINK, szSymlink[cchSymlink + 1]),
     419                                             NIL_RTVFS, NIL_RTVFSLOCK, &hVfsSymlink, (void **)&pNewSymlink);
     420                        if (RT_SUCCESS(rc))
     421                        {
     422                            memcpy(pNewSymlink->szSymlink, pszEntry, cchSymlink);
     423                            pNewSymlink->szSymlink[cchSymlink] = '\0';
     424                            pNewSymlink->pDir = pThis;
     425
     426                            *phVfsObj = RTVfsObjFromSymlink(hVfsSymlink);
     427                            RTVfsSymlinkRelease(hVfsSymlink);
     428                            AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
     429                        }
     430                        else
     431                            RTVfsDirRelease(pThis->hSelf);
     432                    }
     433                    else
     434                        rc = VERR_INTERNAL_ERROR_2;
     435                }
     436                else
     437                    rc = VERR_IS_A_SYMLINK;
     438                break;
     439
     440            default:
     441                break;
     442        }
     443    }
     444    else if (   rc == VERR_FILE_NOT_FOUND
     445             || rc == VERR_PATH_NOT_FOUND)
     446    {
     447        /*
     448         * Consider file or directory creation.
     449         */
     450        if (   (   (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE
     451                || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE
     452                || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE)
     453            && (fFlags & RTVFSOBJ_F_CREATE_MASK) != RTVFSOBJ_F_CREATE_NOTHING)
     454        {
     455
     456            if ((fFlags & RTVFSOBJ_F_CREATE_MASK) == RTVFSOBJ_F_CREATE_FILE)
     457            {
     458                RTFILE hFile;
     459                rc = RTDirRelFileOpen(pThis->hDir, pszEntry, fOpen, &hFile);
     460                if (RT_SUCCESS(rc))
     461                {
     462                    RTVFSFILE hVfsFile;
     463                    rc = RTVfsFileFromRTFile(hFile, fOpen, false /*fLeaveOpen*/, &hVfsFile);
     464                    if (RT_SUCCESS(rc))
     465                    {
     466                        *phVfsObj = RTVfsObjFromFile(hVfsFile);
     467                        RTVfsFileRelease(hVfsFile);
     468                        AssertStmt(*phVfsObj == NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
     469                    }
     470                    else
     471                        RTFileClose(hFile);
     472                }
     473            }
     474            else if ((fFlags & RTVFSOBJ_F_CREATE_MASK) == RTVFSOBJ_F_CREATE_DIRECTORY)
     475            {
     476                RTDIR hSubDir;
     477                rc = RTDirRelDirCreate(pThis->hDir, pszEntry, (fOpen & RTFILE_O_CREATE_MODE_MASK) >> RTFILE_O_CREATE_MODE_SHIFT,
     478                                       0 /* fFlags */, &hSubDir);
     479                if (RT_SUCCESS(rc))
     480                {
     481                    RTVFSDIR hVfsDir;
     482                    rc = rtVfsDirFromRTDir(hSubDir, 0 /** @todo subdir open/inherit flags... */, false, &hVfsDir);
     483                    if (RT_SUCCESS(rc))
     484                    {
     485                        *phVfsObj = RTVfsObjFromDir(hVfsDir);
     486                        RTVfsDirRelease(hVfsDir);
     487                        AssertStmt(*phVfsObj == NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
     488                    }
     489                    else
     490                        RTDirClose(hSubDir);
     491                }
     492            }
     493            else
     494                rc = VERR_VFS_UNSUPPORTED_CREATE_TYPE;
     495        }
     496        else
     497            rc = VERR_FILE_NOT_FOUND;
     498    }
     499    return rc;
     500}
     501
     502
     503/**
    307504 * @interface_method_impl{RTVFSDIROPS,pfnOpenFile}
    308505 */
    309 static DECLCALLBACK(int) rtVfsStdDir_OpenFile(void *pvThis, const char *pszFilename, uint32_t fOpen, PRTVFSFILE phVfsFile)
     506static DECLCALLBACK(int) rtVfsStdDir_OpenFile(void *pvThis, const char *pszFilename, uint64_t fOpen, PRTVFSFILE phVfsFile)
    310507{
    311508    PRTVFSSTDDIR pThis = (PRTVFSSTDDIR)pvThis;
     
    523720        RTVFSOBJSETOPS_VERSION
    524721    },
     722    rtVfsStdDir_OpenObj,
    525723    rtVfsStdDir_TraversalOpen,
    526724    rtVfsStdDir_OpenFile,
  • trunk/src/VBox/Runtime/tools/RTChMod.cpp

    r69802 r69813  
    2929*   Header Files                                                                                                                 *
    3030*********************************************************************************************************************************/
    31 #include <iprt/path.h>
     31#include <iprt/buildconfig.h>
    3232#include <iprt/err.h>
     33#include <iprt/file.h>
     34#include <iprt/getopt.h>
    3335#include <iprt/initterm.h>
    3436#include <iprt/message.h>
    35 
     37#include <iprt/path.h>
     38#include <iprt/stream.h>
     39#include <iprt/string.h>
    3640#include <iprt/vfs.h>
    37 #include <iprt/string.h>
    38 #include <iprt/stream.h>
    39 #include <iprt/getopt.h>
    40 #include <iprt/buildconfig.h>
    4141
    4242
     
    6464    kRTCmdChModNoise_Verbose
    6565} RTCMDCHMODNOISE;
     66
    6667
    6768typedef struct RTCMDCHMODOPTS
     
    131132    else
    132133    {
    133         /* Try via parent first as that's generally faster and more reliable. */
    134         RTVFSDIR        hVfsDir;
    135         const char     *pszChild;
     134        RTVFSOBJ        hVfsObj;
    136135        uint32_t        offError;
    137136        RTERRINFOSTATIC ErrInfo;
    138         rc = RTVfsChainOpenParentDir(pszPath, 0 /*fOpen*/, &hVfsDir, &pszChild, &offError, RTErrInfoInitStatic(&ErrInfo));
     137        rc = RTVfsChainOpenObj(pszPath, RTFILE_O_ACCESS_ATTR_READWRITE | RTFILE_O_DENY_NONE | RTFILE_O_OPEN,
     138                               RTVFSOBJ_F_OPEN_ANY | RTVFSOBJ_F_CREATE_NOTHING | RTPATH_F_FOLLOW_LINK,
     139                               &hVfsObj, &offError, RTErrInfoInitStatic(&ErrInfo));
    139140        if (RT_SUCCESS(rc))
    140141        {
    141             rc = RTVfsDirQueryPathInfo(hVfsDir, pszChild, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_FOLLOW_LINK);
     142            rc = RTVfsObjQueryInfo(hVfsObj, &ObjInfo, RTFSOBJATTRADD_NOTHING);
    142143            if (RT_SUCCESS(rc))
    143144            {
     
    146147                if (fChanges)
    147148                {
    148                     rc = VERR_NOT_IMPLEMENTED; //rc = RTVfsDirSetPathMode(hVfsDir, pszChild, fNewMode, RTPATH_F_FOLLOW_LINK);
     149                    rc = RTVfsObjSetMode(hVfsObj, fNewMode, RTCHMOD_SET_ALL_MASK);
    149150                    if (RT_FAILURE(rc))
    150                         RTMsgError("RTVfsDirSetPathMode failed on '%s' with fNewMode=%#x: %Rrc", pszPath, fNewMode, rc);
    151                 }
    152             }
    153             RTVfsDirRelease(hVfsDir);
    154         }
    155         /* If we have no child part, work on the chain as a whole. */
    156         else if (   rc == VERR_VFS_CHAIN_TOO_SHORT_FOR_PARENT
    157                  || rc == VERR_VFS_CHAIN_NOT_PATH_ONLY)
    158         {
    159             rc = RTVfsChainQueryInfo(pszPath, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_FOLLOW_LINK,
    160                                      &offError, RTErrInfoInitStatic(&ErrInfo));
    161             if (RT_SUCCESS(rc))
    162             {
    163                 RTFMODE fNewMode = rtCmdMkModCalcNewMode(pOpts, ObjInfo.Attr.fMode);
    164                 fChanges = fNewMode != ObjInfo.Attr.fMode;
    165                 if (fChanges)
    166                 {
    167                     rc = VERR_NOT_IMPLEMENTED; //rc = RTVfsChainSetMode(pszPath, fNewMode, &offError, RTErrInfoInitStatic(&ErrInfo));
    168                     if (RT_FAILURE(rc))
    169                         RTMsgError("RTVfsChainSetMode failed on '%s' with fNewMode=%#x: %Rrc", pszPath, fNewMode, rc);
     151                        RTMsgError("RTVfsObjSetMode failed on '%s' with fNewMode=%#x: %Rrc", pszPath, fNewMode, rc);
    170152                }
    171153            }
    172154            else
    173                 RTVfsChainMsgError("RTVfsChainQueryInfo", pszPath, rc, offError, &ErrInfo.Core);
     155                RTVfsChainMsgError("RTVfsObjQueryInfo", pszPath, rc, offError, &ErrInfo.Core);
     156            RTVfsObjRelease(hVfsObj);
    174157        }
    175         else /** @todo we could implement a fallback here so we don't require a final path element. */
    176             RTVfsChainMsgError("RTVfsChainOpenParentDir", pszPath, rc, offError, &ErrInfo.Core);
     158        else
     159            RTVfsChainMsgError("RTVfsChainOpenObject", pszPath, rc, offError, &ErrInfo.Core);
    177160    }
    178161
     
    219202
    220203    if (!RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode))
    221         return rtCmdChModOne(pOpts, pszPath);
    222 
    223     /** @todo do root detection. */
     204    {
     205        /*
     206         * Don't bother redoing the above work if its not necessary.
     207         */
     208        RTFMODE fNewMode = rtCmdMkModCalcNewMode(pOpts, ObjInfo.Attr.fMode);
     209        if (fNewMode != ObjInfo.Attr.fMode)
     210            return rtCmdChModOne(pOpts, pszPath);
     211        if (pOpts->enmNoiseLevel >= kRTCmdChModNoise_Verbose)
     212            RTPrintf("%s\n", pszPath);
     213        return RTEXITCODE_SUCCESS;
     214    }
    224215
    225216    /*
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette