Index: /trunk/include/iprt/path.h
===================================================================
--- /trunk/include/iprt/path.h	(revision 69817)
+++ /trunk/include/iprt/path.h	(revision 69818)
@@ -65,10 +65,12 @@
  * @{ */
 /** Last component: Work on the link. */
-#define RTPATH_F_ON_LINK          RT_BIT_32(0)
+#define RTPATH_F_ON_LINK            RT_BIT_32(0)
 /** Last component: Follow if link. */
-#define RTPATH_F_FOLLOW_LINK      RT_BIT_32(1)
+#define RTPATH_F_FOLLOW_LINK        RT_BIT_32(1)
 /** Don't allow symbolic links as part of the path.
  * @remarks this flag is currently not implemented and will be ignored. */
-#define RTPATH_F_NO_SYMLINKS      RT_BIT_32(2)
+#define RTPATH_F_NO_SYMLINKS        RT_BIT_32(2)
+/** Current RTPATH_F_XXX flag mask. */
+#define RTPATH_F_MASK               UINT32_C(0x00000007)
 /** @} */
 
Index: /trunk/include/iprt/vfs.h
===================================================================
--- /trunk/include/iprt/vfs.h	(revision 69817)
+++ /trunk/include/iprt/vfs.h	(revision 69818)
@@ -183,11 +183,14 @@
 /** Socket (RTFS_TYPE_SOCKET). */
 #define RTVFSOBJ_F_OPEN_SOCKET              RT_BIT_32(14)
+/** Mounted VFS. */
+#define RTVFSOBJ_F_OPEN_MOUNT               RT_BIT_32(15)
 /** Mask object types we wish to open. */
-#define RTVFSOBJ_F_OPEN_MASK                UINT32_C(0x00003f00)
+#define RTVFSOBJ_F_OPEN_MASK                UINT32_C(0x0000ff00)
 /** Any kind of object that translates to RTVFSOBJTYPE_FILE. */
-#define RTVFSOBJ_F_OPEN_ANY_FILE            (RTVFSOBJ_F_FILE | RTVFSOBJ_F_DEV_BLOCK)
+#define RTVFSOBJ_F_OPEN_ANY_FILE            (RTVFSOBJ_F_OPEN_FILE | RTVFSOBJ_F_OPEN_DEV_BLOCK)
 /** Any kind of object that translates to RTVFSOBJTYPE_IOS or
  *  RTVFSOBJTYPE_FILE. */
-#define RTVFSOBJ_F_OPEN_ANY_IO_STREAM       (RTVFSOBJ_F_ANY_FILE | RTVFSOBJ_F_DEV_BLOCK | RTVFSOBJ_F_FIFO | RTVFSOBJ_F_SOCKET)
+#define RTVFSOBJ_F_OPEN_ANY_IO_STREAM       (  RTVFSOBJ_F_ANY_OPEN_FILE | RTVFSOBJ_F_DEV_OPEN_BLOCK \
+                                             | RTVFSOBJ_F_OPEN_FIFO     | RTVFSOBJ_F_OPEN_SOCKET)
 /** Any kind of object. */
 #define RTVFSOBJ_F_OPEN_ANY                 RTVFSOBJ_F_OPEN_MASK
@@ -208,5 +211,5 @@
 #define RTVFSOBJ_F_TRAVERSAL                RT_BIT_32(31)
 /** Valid mask for external callers. */
-#define RTVFSOBJ_F_VALID_MASK               UINT32_C(0x00003f00)
+#define RTVFSOBJ_F_VALID_MASK               UINT32_C(0x0007ff00)
 /** @} */
 
Index: /trunk/include/iprt/vfslowlevel.h
===================================================================
--- /trunk/include/iprt/vfslowlevel.h	(revision 69817)
+++ /trunk/include/iprt/vfslowlevel.h	(revision 69818)
@@ -562,29 +562,4 @@
     DECLCALLBACKMEMBER(int, pfnOpen)(void *pvThis, const char *pszEntry, uint64_t fOpenFile,
                                      uint32_t fObjFlags, PRTVFSOBJ phVfsObj);
-
-    /**
-     * Opens a directory entry for traversal purposes.
-     *
-     * Method which sole purpose is helping the path traversal.  Only one of
-     * the three output variables will be set, the others will left untouched
-     * (caller sets them to NIL).
-     *
-     * @returns IPRT status code.
-     * @retval  VERR_PATH_NOT_FOUND if @a pszEntry was not found.
-     * @retval  VERR_NOT_A_DIRECTORY if @a pszEntry isn't a directory or symlink.
-     * @param   pvThis          The implementation specific directory data.
-     * @param   pszEntry        The name of the directory entry to remove.
-     * @param   phVfsDir        If not NULL and it is a directory, open it and
-     *                          return the handle here.
-     * @param   phVfsSymlink    If not NULL and it is a symbolic link, open it
-     *                          and return the handle here.
-     * @param   phVfsMounted    If not NULL and it is a mounted VFS directory,
-     *                          reference it and return the handle here.
-     * @todo    Should com dir, symlinks and mount points using some common
-     *          ancestor "class".
-     * @note    Will be replaced by pfnOpenObj.
-     */
-    DECLCALLBACKMEMBER(int, pfnTraversalOpen)(void *pvThis, const char *pszEntry, PRTVFSDIR phVfsDir,
-                                              PRTVFSSYMLINK phVfsSymlink, PRTVFS phVfsMounted);
 
     /**
Index: /trunk/src/VBox/Runtime/common/dvm/dvmvfs.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/dvm/dvmvfs.cpp	(revision 69817)
+++ /trunk/src/VBox/Runtime/common/dvm/dvmvfs.cpp	(revision 69818)
@@ -648,23 +648,4 @@
 
 
-/**
- * @interface_method_impl{RTVFSOBJOPS,pfnTraversalOpen}
- */
-static DECLCALLBACK(int) rtDvmVfsDir_TraversalOpen(void *pvThis, const char *pszEntry, PRTVFSDIR phVfsDir,
-                                                  PRTVFSSYMLINK phVfsSymlink, PRTVFS phVfsMounted)
-{
-    RT_NOREF(pvThis, pszEntry);
-
-    /* We don't do any subdirs. */
-    if (phVfsSymlink)
-        *phVfsSymlink = NIL_RTVFSSYMLINK;
-    if (phVfsMounted)
-        *phVfsMounted = NIL_RTVFS;
-    if (phVfsDir)
-        *phVfsDir = NIL_RTVFSDIR;
-    return VERR_PATH_NOT_FOUND;
-}
-
-
 static int rtDvmVfsDir_FindEntry(PRTDVMVFSDIR pThis, const char *pszEntry, PRTDVMVOLUME phVolume)
 {
@@ -1014,5 +995,4 @@
     },
     rtDvmVfsDir_Open,
-    rtDvmVfsDir_TraversalOpen,
     rtDvmVfsDir_OpenFile,
     rtDvmVfsDir_OpenDir,
Index: /trunk/src/VBox/Runtime/common/fs/fatvfs.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/fs/fatvfs.cpp	(revision 69817)
+++ /trunk/src/VBox/Runtime/common/fs/fatvfs.cpp	(revision 69818)
@@ -3999,59 +3999,4 @@
 
 /**
- * @interface_method_impl{RTVFSOBJOPS,pfnTraversalOpen}
- */
-static DECLCALLBACK(int) rtFsFatDir_TraversalOpen(void *pvThis, const char *pszEntry, PRTVFSDIR phVfsDir,
-                                                  PRTVFSSYMLINK phVfsSymlink, PRTVFS phVfsMounted)
-{
-    /*
-     * FAT doesn't do symbolic links and mounting file systems within others
-     * haven't been implemented yet, I think, so only care if a directory is
-     * asked for.
-     */
-    int rc;
-    if (phVfsSymlink)
-        *phVfsSymlink = NIL_RTVFSSYMLINK;
-    if (phVfsMounted)
-        *phVfsMounted = NIL_RTVFS;
-    if (phVfsDir)
-    {
-        *phVfsDir = NIL_RTVFSDIR;
-
-        PRTFSFATDIR     pThis   = (PRTFSFATDIR)pvThis;
-        PRTFSFATDIRSHRD pShared = pThis->pShared;
-        uint32_t        offEntryInDir;
-        bool            fLong;
-        FATDIRENTRY     DirEntry;
-        rc = rtFsFatDirShrd_FindEntry(pShared, pszEntry, &offEntryInDir, &fLong, &DirEntry);
-        if (RT_SUCCESS(rc))
-        {
-            switch (DirEntry.fAttrib & (FAT_ATTR_DIRECTORY | FAT_ATTR_VOLUME))
-            {
-                case FAT_ATTR_DIRECTORY:
-                {
-                    rc = rtFsFatDir_New(pShared->Core.pVol, pShared, &DirEntry, offEntryInDir,
-                                        RTFSFAT_GET_CLUSTER(&DirEntry, pShared->Core.pVol), UINT64_MAX /*offDisk*/,
-                                        DirEntry.cbFile, phVfsDir);
-                    break;
-                }
-                case 0:
-                    rc = VERR_NOT_A_DIRECTORY;
-                    break;
-                default:
-                    rc = VERR_PATH_NOT_FOUND;
-                    break;
-            }
-        }
-        else if (rc == VERR_FILE_NOT_FOUND)
-            rc = VERR_PATH_NOT_FOUND;
-    }
-    else
-        rc = VERR_PATH_NOT_FOUND;
-    LogFlow(("rtFsFatDir_TraversalOpen: %s -> %Rrc\n", pszEntry, rc));
-    return rc;
-}
-
-
-/**
  * @interface_method_impl{RTVFSDIROPS,pfnOpen}
  */
@@ -4778,5 +4723,4 @@
     },
     rtFsFatDir_Open,
-    rtFsFatDir_TraversalOpen,
     rtFsFatDir_OpenFile,
     rtFsFatDir_OpenDir,
Index: /trunk/src/VBox/Runtime/common/fs/isovfs.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/fs/isovfs.cpp	(revision 69817)
+++ /trunk/src/VBox/Runtime/common/fs/isovfs.cpp	(revision 69818)
@@ -2890,107 +2890,4 @@
 
 /**
- * @interface_method_impl{RTVFSOBJOPS,pfnTraversalOpen}
- */
-static DECLCALLBACK(int) rtFsIsoDir_TraversalOpen(void *pvThis, const char *pszEntry, PRTVFSDIR phVfsDir,
-                                                  PRTVFSSYMLINK phVfsSymlink, PRTVFS phVfsMounted)
-{
-    /*
-     * We may have symbolic links if rock ridge is being used, though currently
-     * we won't have nested mounts.
-     */
-    int rc;
-    if (phVfsMounted)
-        *phVfsMounted = NIL_RTVFS;
-    if (phVfsDir || phVfsSymlink)
-    {
-        if (phVfsSymlink)
-            *phVfsSymlink = NIL_RTVFSSYMLINK;
-        if (phVfsDir)
-            *phVfsDir = NIL_RTVFSDIR;
-
-        PRTFSISODIROBJ      pThis = (PRTFSISODIROBJ)pvThis;
-        PRTFSISODIRSHRD     pShared = pThis->pShared;
-        if (pShared->Core.pVol->enmType != RTFSISOVOLTYPE_UDF)
-        {
-            /*
-             * ISO 9660
-             */
-            PCISO9660DIRREC     pDirRec;
-            uint64_t            offDirRec;
-            uint32_t            cDirRecs;
-            RTFMODE             fMode;
-            uint32_t            uVersion;
-            rc = rtFsIsoDir_FindEntry9660(pShared, pszEntry, &offDirRec, &pDirRec, &cDirRecs, &fMode, &uVersion);
-            Log2(("rtFsIsoDir_TraversalOpen: FindEntry9660(,%s,) -> %Rrc\n", pszEntry, rc));
-            if (RT_SUCCESS(rc))
-            {
-                switch (fMode & RTFS_TYPE_MASK)
-                {
-                    case RTFS_TYPE_DIRECTORY:
-                        if (phVfsDir)
-                            rc = rtFsIsoDir_New9660(pShared->Core.pVol, pShared, pDirRec, cDirRecs, offDirRec, phVfsDir);
-                        else
-                            rc = VERR_NOT_SYMLINK;
-                        break;
-
-                    case RTFS_TYPE_SYMLINK:
-                        rc = VERR_NOT_IMPLEMENTED;
-                        break;
-                    case RTFS_TYPE_FILE:
-                    case RTFS_TYPE_DEV_BLOCK:
-                    case RTFS_TYPE_DEV_CHAR:
-                    case RTFS_TYPE_FIFO:
-                    case RTFS_TYPE_SOCKET:
-                        rc = VERR_NOT_A_DIRECTORY;
-                        break;
-                    default:
-                    case RTFS_TYPE_WHITEOUT:
-                        rc = VERR_PATH_NOT_FOUND;
-                        break;
-                }
-            }
-            else if (rc == VERR_FILE_NOT_FOUND)
-                rc = VERR_PATH_NOT_FOUND;
-        }
-        else
-        {
-            /*
-             * UDF
-             */
-            PCUDFFILEIDDESC pFid;
-            rc = rtFsIsoDir_FindEntryUdf(pShared, pszEntry, &pFid);
-            Log2(("rtFsIsoDir_TraversalOpen: FindEntryUdf(,%s,) -> %Rrc\n", pszEntry, rc));
-            if (RT_SUCCESS(rc))
-            {
-                if (!(pFid->fFlags & UDF_FILE_FLAGS_DELETED))
-                {
-                    if (pFid->fFlags & UDF_FILE_FLAGS_DIRECTORY)
-                    {
-                        if (phVfsDir)
-                            rc = rtFsIsoDir_NewUdf(pShared->Core.pVol, pShared, pFid, phVfsDir);
-                        else
-                            rc = VERR_NOT_SYMLINK;
-                    }
-                    else if (phVfsSymlink)
-                    {
-                        /** @todo symlink support */
-                        rc = VERR_NOT_A_DIRECTORY;
-                    }
-                    else
-                        rc = VERR_NOT_A_DIRECTORY;
-                }
-                /* We treat UDF_FILE_FLAGS_DELETED like RTFS_TYPE_WHITEOUT for now. */
-                else
-                    rc = VERR_PATH_NOT_FOUND;
-            }
-        }
-    }
-    else
-        rc = VERR_PATH_NOT_FOUND;
-    return rc;
-}
-
-
-/**
  * @interface_method_impl{RTVFSDIROPS,pfnOpen}
  */
@@ -3794,5 +3691,4 @@
     },
     rtFsIsoDir_Open,
-    rtFsIsoDir_TraversalOpen,
     rtFsIsoDir_OpenFile,
     rtFsIsoDir_OpenDir,
Index: /trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp	(revision 69817)
+++ /trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp	(revision 69818)
@@ -92,9 +92,9 @@
         Assert((pDirOps)->uVersion == RTVFSDIROPS_VERSION); \
         Assert(!(pDirOps)->fReserved); \
-        AssertPtr((pDirOps)->pfnTraversalOpen); \
-        AssertPtr((pDirOps)->pfnOpenFile); \
-        AssertPtr((pDirOps)->pfnOpenDir); \
-        AssertPtr((pDirOps)->pfnCreateDir); \
-        AssertPtr((pDirOps)->pfnOpenSymlink); \
+        AssertPtr((pDirOps)->pfnOpen); \
+        AssertPtrNull((pDirOps)->pfnOpenFile); \
+        AssertPtrNull((pDirOps)->pfnOpenDir); \
+        AssertPtrNull((pDirOps)->pfnCreateDir); \
+        AssertPtrNull((pDirOps)->pfnOpenSymlink); \
         AssertPtr((pDirOps)->pfnCreateSymlink); \
         AssertPtr((pDirOps)->pfnUnlinkEntry); \
@@ -1697,44 +1697,59 @@
         RTVFSSYMLINK    hSymlink = NIL_RTVFSSYMLINK;
         RTVFS           hVfsMnt  = NIL_RTVFS;
+        RTVFSOBJ        hVfsObj  = NIL_RTVFSOBJ;
         if (fFinal)
         {
             RTVfsLockAcquireRead(pCurDir->Base.hLock);
-            rc = pCurDir->pOps->pfnTraversalOpen(pCurDir->Base.pvThis, pszEntry, NULL, &hSymlink, NULL);
+            rc = pCurDir->pOps->pfnOpen(pCurDir->Base.pvThis, pszEntry,
+                                        RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE,
+                                        RTVFSOBJ_F_OPEN_SYMLINK | RTVFSOBJ_F_CREATE_NOTHING
+                                        | RTVFSOBJ_F_TRAVERSAL | RTPATH_F_ON_LINK,
+                                        &hVfsObj);
             RTVfsLockReleaseRead(pCurDir->Base.hLock);
             *pszEntryEnd = '\0';
-            if (   rc == VERR_PATH_NOT_FOUND
-                || rc == VERR_FILE_NOT_FOUND
-                || rc == VERR_NOT_A_DIRECTORY
-                || rc == VERR_NOT_SYMLINK)
-                rc = VINF_SUCCESS;
             if (RT_FAILURE(rc))
+            {
+                if (   rc == VERR_PATH_NOT_FOUND
+                    || rc == VERR_FILE_NOT_FOUND
+                    || rc == VERR_IS_A_DIRECTORY
+                    || rc == VERR_IS_A_FILE
+                    || rc == VERR_IS_A_FIFO
+                    || rc == VERR_IS_A_SOCKET
+                    || rc == VERR_IS_A_CHAR_DEVICE
+                    || rc == VERR_IS_A_BLOCK_DEVICE
+                    || rc == VERR_NOT_SYMLINK)
+                {
+                    *ppVfsParentDir = pCurDir;
+                    return VINF_SUCCESS;
+                }
                 break;
-
-            if (hSymlink == NIL_RTVFSSYMLINK)
-            {
-                *ppVfsParentDir = pCurDir;
-                return VINF_SUCCESS;
             }
+            hSymlink = RTVfsObjToSymlink(hVfsObj);
+            Assert(hSymlink != NIL_RTVFSSYMLINK);
         }
         else
         {
             RTVfsLockAcquireRead(pCurDir->Base.hLock);
-            rc = pCurDir->pOps->pfnTraversalOpen(pCurDir->Base.pvThis, pszEntry, &hDir, &hSymlink, &hVfsMnt);
+            rc = pCurDir->pOps->pfnOpen(pCurDir->Base.pvThis, pszEntry,
+                                        RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE,
+                                        RTVFSOBJ_F_OPEN_DIRECTORY   | RTVFSOBJ_F_OPEN_SYMLINK | RTVFSOBJ_F_OPEN_MOUNT
+                                        | RTVFSOBJ_F_CREATE_NOTHING | RTVFSOBJ_F_TRAVERSAL    | RTPATH_F_ON_LINK,
+                                        &hVfsObj);
             RTVfsLockReleaseRead(pCurDir->Base.hLock);
             *pszEntryEnd = '/';
             if (RT_FAILURE(rc))
-                break;
-
-            if (   hDir     == NIL_RTVFSDIR
-                && hSymlink == NIL_RTVFSSYMLINK
-                && hVfsMnt  == NIL_RTVFS)
             {
-                rc = VERR_NOT_A_DIRECTORY;
+                if (rc == VERR_FILE_NOT_FOUND)
+                    rc = VERR_PATH_NOT_FOUND;
                 break;
             }
+            hDir     = RTVfsObjToDir(hVfsObj);
+            hSymlink = RTVfsObjToSymlink(hVfsObj);
+            hVfsMnt  = RTVfsObjToVfs(hVfsObj);
         }
         Assert(   (hDir != NIL_RTVFSDIR && hSymlink == NIL_RTVFSSYMLINK && hVfsMnt == NIL_RTVFS)
                || (hDir == NIL_RTVFSDIR && hSymlink != NIL_RTVFSSYMLINK && hVfsMnt == NIL_RTVFS)
                || (hDir == NIL_RTVFSDIR && hSymlink == NIL_RTVFSSYMLINK && hVfsMnt != NIL_RTVFS));
+        RTVfsObjRelease(hVfsObj);
 
         if (hDir != NIL_RTVFSDIR)
@@ -2613,6 +2628,5 @@
     if (RT_SUCCESS(rc))
     {
-        if (   !pPath->fDirSlash
-            && pPath->cComponents > 0)
+        if (pPath->cComponents > 0)
         {
             /*
@@ -2621,15 +2635,40 @@
              */
             RTVFSDIRINTERNAL *pVfsParentDir;
-            rc = rtVfsDirTraverseToParent(pThis, pPath, RTPATH_F_FOLLOW_LINK, &pVfsParentDir);
+            rc = rtVfsDirTraverseToParent(pThis, pPath,
+                                          (fOpen & RTFILE_O_NO_SYMLINKS ? RTPATH_F_NO_SYMLINKS : 0) | RTPATH_F_FOLLOW_LINK,
+                                          &pVfsParentDir);
             if (RT_SUCCESS(rc))
             {
                 const char *pszEntryName = &pPath->szPath[pPath->aoffComponents[pPath->cComponents - 1]];
 
-                /** @todo there is a symlink creation race here. */
-                RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock);
-                rc = pVfsParentDir->pOps->pfnOpenFile(pVfsParentDir->Base.pvThis, pszEntryName, fOpen, phVfsFile);
-                RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock);
-
-                RTVfsDirRelease(pVfsParentDir);
+                if (   pVfsParentDir->pOps->pfnOpenFile == NULL
+                    || pPath->fDirSlash)
+                {
+                    RTVFSOBJ hVfsObj;
+                    RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock);
+                    rc = pVfsParentDir->pOps->pfnOpen(pVfsParentDir->Base.pvThis, pszEntryName, fOpen,
+                                                      RTVFSOBJ_F_OPEN_ANY_FILE | RTVFSOBJ_F_CREATE_FILE
+                                                      | RTPATH_F_FOLLOW_LINK, &hVfsObj);
+                    RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock);
+                    if (RT_SUCCESS(rc))
+                    {
+                        if (RTVfsObjGetType(hVfsObj) != RTVFSOBJTYPE_SYMLINK)
+                            *phVfsFile = RTVfsObjToFile(hVfsObj);
+                        else
+                        {
+                            /** @todo parse symbolic links. */
+                            AssertFailed();
+                            rc = VERR_NOT_IMPLEMENTED;
+                        }
+                        RTVfsObjRelease(hVfsObj);
+                    }
+                }
+                else
+                {
+                    /** @todo there is a symlink creation race here. */
+                    RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock);
+                    rc = pVfsParentDir->pOps->pfnOpenFile(pVfsParentDir->Base.pvThis, pszEntryName, fOpen, phVfsFile);
+                    RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock);
+                }
 
                 if (RT_SUCCESS(rc))
@@ -2638,4 +2677,6 @@
                     Assert((*phVfsFile)->uMagic == RTVFSFILE_MAGIC);
                 }
+
+                RTVfsDirRelease(pVfsParentDir);
             }
         }
@@ -2682,5 +2723,7 @@
 
     /*
-     * Parse the relative path.
+     * Parse the relative path.  If it ends with a directory slash or it boils
+     * down to an empty path (i.e. re-opening hVfsDir), adjust the flags to only
+     * open/create directories.
      */
     PRTVFSPARSEDPATH pPath;
@@ -2690,64 +2733,48 @@
         if (   pPath->fDirSlash
             || pPath->cComponents == 0)
+        {
             fObjFlags &= ~RTVFSOBJ_F_OPEN_ANY | RTVFSOBJ_F_OPEN_DIRECTORY;
-
+            if ((fObjFlags & RTVFSOBJ_F_CREATE_MASK) != RTVFSOBJ_F_CREATE_DIRECTORY)
+                fObjFlags = (fObjFlags & ~RTVFSOBJ_F_CREATE_MASK) | RTVFSOBJ_F_CREATE_NOTHING;
+        }
+
+        /*
+         * Tranverse the path, resolving the parent node, not checking for
+         * symbolic links in the final element.
+         */
+        const char       *pszEntryName;
+        RTVFSDIRINTERNAL *pVfsParentDir;
         if (pPath->cComponents > 0)
         {
+            rc = rtVfsDirTraverseToParent(pThis, pPath, fObjFlags & RTPATH_F_MASK, &pVfsParentDir);
+            pszEntryName = &pPath->szPath[pPath->aoffComponents[pPath->cComponents - 1]];
+        }
+        else
+        {
+            RTVfsDirRetain(pThis);
+            pVfsParentDir = pThis;
+            pszEntryName  = ".";
+        }
+        if (RT_SUCCESS(rc))
+        {
             /*
-             * Tranverse the path, resolving the parent node, not
-             * checking for symbolic links in the final element.
+             * Do the opening.
              */
-            RTVFSDIRINTERNAL *pVfsParentDir;
-            rc = rtVfsDirTraverseToParent(pThis, pPath, RTPATH_F_ON_LINK, &pVfsParentDir);
-            if (RT_SUCCESS(rc))
+            RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock);
+            rc = pVfsParentDir->pOps->pfnOpen(pVfsParentDir->Base.pvThis, pszEntryName, fFileOpen, fObjFlags, phVfsObj);
+            RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock);
+
+            if (   (fObjFlags & RTPATH_F_FOLLOW_LINK)
+                && RTVfsObjGetType(*phVfsObj) == RTVFSOBJTYPE_SYMLINK)
             {
-                const char *pszEntryName = &pPath->szPath[pPath->aoffComponents[pPath->cComponents - 1]];
-
-                /*
-                 * If we've got a trailing directory slash, use pfnOpenDir
-                 * instead of pfnOpenObj.
-                 */
-                if (pPath->fDirSlash)
-                {
-                    RTVFSDIR hVfsSubDir;
-                    RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock);
-                    rc = pVfsParentDir->pOps->pfnOpenDir(pVfsParentDir->Base.pvThis, pszEntryName,
-                                                         0 /** @todo fFlags*/, &hVfsSubDir);
-                    RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock);
-                    if (RT_SUCCESS(rc))
-                    {
-                        *phVfsObj = RTVfsObjFromDir(hVfsSubDir);
-                        RTVfsDirRelease(hVfsSubDir);
-                        AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
-                    }
-                }
-                else
-                {
-                    RTVfsLockAcquireWrite(pVfsParentDir->Base.hLock);
-                    rc = pVfsParentDir->pOps->pfnOpen(pVfsParentDir->Base.pvThis, pszEntryName, fFileOpen, fObjFlags, phVfsObj);
-                    RTVfsLockReleaseWrite(pVfsParentDir->Base.hLock);
-                }
-                RTVfsDirRelease(pVfsParentDir);
+                /** @todo implement following symbolic links. */
+                AssertFailed();
+                RTVfsObjRelease(*phVfsObj);
+                *phVfsObj = NIL_RTVFSOBJ;
+                rc = VERR_NOT_IMPLEMENTED;
             }
-        }
-        /*
-         * The path boils down to '.', call pfnOpenDir on pThis with '.' as input.
-         * The caller may wish for a new directory instance to enumerate the entries
-         * in parallel or some such thing.
-         */
-        else
-        {
-            RTVFSDIR hVfsSubDir;
-            RTVfsLockAcquireWrite(pThis->Base.hLock);
-            rc = pThis->pOps->pfnOpenDir(pThis->Base.pvThis, ".", 0 /** @todo fFlags*/, &hVfsSubDir);
-            RTVfsLockReleaseWrite(pThis->Base.hLock);
-            if (RT_SUCCESS(rc))
-            {
-                *phVfsObj = RTVfsObjFromDir(hVfsSubDir);
-                RTVfsDirRelease(hVfsSubDir);
-                AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
-            }
-        }
-
+
+            RTVfsDirRelease(pVfsParentDir);
+        }
         RTVfsParsePathFree(pPath);
     }
Index: /trunk/src/VBox/Runtime/common/vfs/vfsstddir.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/vfs/vfsstddir.cpp	(revision 69817)
+++ /trunk/src/VBox/Runtime/common/vfs/vfsstddir.cpp	(revision 69818)
@@ -251,62 +251,9 @@
 
 
-
-/**
- * @interface_method_impl{RTVFSDIROPS,pfnTraversalOpen}
- */
-static DECLCALLBACK(int) rtVfsStdDir_TraversalOpen(void *pvThis, const char *pszEntry, PRTVFSDIR phVfsDir,
-                                                   PRTVFSSYMLINK phVfsSymlink, PRTVFS phVfsMounted)
-{
-    /* No union mounting or mount points here (yet). */
-    if (phVfsMounted)
-        *phVfsMounted = NIL_RTVFS;
-
-    int rc;
-    if (phVfsDir || phVfsSymlink)
-    {
-        if (phVfsDir)
-            *phVfsDir = NIL_RTVFSDIR;
-        if (phVfsSymlink)
-            *phVfsSymlink = NIL_RTVFSSYMLINK;
-
-        RTFSOBJINFO ObjInfo;
-        rc = rtVfsStdDir_QueryEntryInfo(pvThis, pszEntry, &ObjInfo, RTFSOBJATTRADD_NOTHING);
-        if (RT_SUCCESS(rc))
-        {
-            switch (ObjInfo.Attr.fMode & RTFS_TYPE_MASK)
-            {
-                case RTFS_TYPE_DIRECTORY:
-                    if (phVfsDir)
-                        rc = rtVfsStdDir_OpenDir(pvThis, pszEntry, 0, phVfsDir);
-                    else
-                        rc = VERR_NOT_SYMLINK;
-                    break;
-
-                case RTFS_TYPE_SYMLINK:
-                    if (phVfsSymlink)
-                        rc = rtVfsStdDir_OpenSymlink(pvThis, pszEntry, phVfsSymlink);
-                    else
-                        rc = VERR_NOT_A_DIRECTORY;
-                    break;
-
-                default:
-                    rc = phVfsDir ? VERR_NOT_A_DIRECTORY : VERR_NOT_SYMLINK;
-                    break;
-            }
-        }
-    }
-    else
-        rc = VERR_PATH_NOT_FOUND;
-
-    LogFlow(("rtVfsStdDir_TraversalOpen: %s -> %Rrc\n", pszEntry, rc));
-    return rc;
-}
-
-
-/**
- * @interface_method_impl{RTVFSDIROPS,pfnOpenObj}
- */
-static DECLCALLBACK(int) rtVfsStdDir_OpenObj(void *pvThis, const char *pszEntry, uint64_t fOpen,
-                                             uint32_t fFlags, PRTVFSOBJ phVfsObj)
+/**
+ * @interface_method_impl{RTVFSDIROPS,pfnOpen}
+ */
+static DECLCALLBACK(int) rtVfsStdDir_Open(void *pvThis, const char *pszEntry, uint64_t fFileOpen,
+                                          uint32_t fVfsFlags, PRTVFSOBJ phVfsObj)
 {
     PRTVFSSTDDIR pThis = (PRTVFSSTDDIR)pvThis;
@@ -323,12 +270,12 @@
         {
             case RTFS_TYPE_DIRECTORY:
-                if (!(fFlags & RTVFSOBJ_F_OPEN_DIRECTORY))
+                if (!(fVfsFlags & RTVFSOBJ_F_OPEN_DIRECTORY))
                 {
-                    if (   (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN
-                        || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE
-                        || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE)
+                    if (   (fFileOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN
+                        || (fFileOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE
+                        || (fFileOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE)
                     {
                         RTDIR hSubDir;
-                        rc = RTDirRelDirOpenFiltered(pThis->hDir, pszEntry, RTDIRFILTER_NONE, fFlags, &hSubDir);
+                        rc = RTDirRelDirOpenFiltered(pThis->hDir, pszEntry, RTDIRFILTER_NONE, fVfsFlags, &hSubDir);
                         if (RT_SUCCESS(rc))
                         {
@@ -339,5 +286,5 @@
                                 *phVfsObj = RTVfsObjFromDir(hVfsDir);
                                 RTVfsDirRelease(hVfsDir);
-                                AssertStmt(*phVfsObj == NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
+                                AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
                             }
                             else
@@ -360,19 +307,19 @@
                 {
                     case RTFS_TYPE_FILE:
-                        rc = fFlags & RTVFSOBJ_F_OPEN_FILE      ? VINF_SUCCESS : VERR_IS_A_FILE;
+                        rc = fVfsFlags & RTVFSOBJ_F_OPEN_FILE      ? VINF_SUCCESS : VERR_IS_A_FILE;
                         break;
                     case RTFS_TYPE_DEV_BLOCK:
-                        rc = fFlags & RTVFSOBJ_F_OPEN_DEV_BLOCK ? VINF_SUCCESS : VERR_IS_A_BLOCK_DEVICE;
+                        rc = fVfsFlags & RTVFSOBJ_F_OPEN_DEV_BLOCK ? VINF_SUCCESS : VERR_IS_A_BLOCK_DEVICE;
                         break;
                     case RTFS_TYPE_DEV_CHAR:
-                        rc = fFlags & RTVFSOBJ_F_OPEN_DEV_CHAR  ? VINF_SUCCESS : VERR_IS_A_CHAR_DEVICE;
+                        rc = fVfsFlags & RTVFSOBJ_F_OPEN_DEV_CHAR  ? VINF_SUCCESS : VERR_IS_A_CHAR_DEVICE;
                         break;
                     /** @todo These two types should not result in files, but pure I/O streams.
                      *        possibly char device too.  */
                     case RTFS_TYPE_FIFO:
-                        rc = fFlags & RTVFSOBJ_F_OPEN_FIFO      ? VINF_SUCCESS : VERR_IS_A_FIFO;
+                        rc = fVfsFlags & RTVFSOBJ_F_OPEN_FIFO      ? VINF_SUCCESS : VERR_IS_A_FIFO;
                         break;
                     case RTFS_TYPE_SOCKET:
-                        rc = fFlags & RTVFSOBJ_F_OPEN_SOCKET    ? VINF_SUCCESS : VERR_IS_A_SOCKET;
+                        rc = fVfsFlags & RTVFSOBJ_F_OPEN_SOCKET    ? VINF_SUCCESS : VERR_IS_A_SOCKET;
                         break;
                     default:
@@ -382,19 +329,19 @@
                 if (RT_SUCCESS(rc))
                 {
-                    if (   (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN
-                        || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE
-                        || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE)
+                    if (   (fFileOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN
+                        || (fFileOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE
+                        || (fFileOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE)
                     {
                         RTFILE hFile;
-                        rc = RTDirRelFileOpen(pThis->hDir, pszEntry, fOpen, &hFile);
+                        rc = RTDirRelFileOpen(pThis->hDir, pszEntry, fFileOpen, &hFile);
                         if (RT_SUCCESS(rc))
                         {
                             RTVFSFILE hVfsFile;
-                            rc = RTVfsFileFromRTFile(hFile, fOpen, false /*fLeaveOpen*/, &hVfsFile);
+                            rc = RTVfsFileFromRTFile(hFile, fFileOpen, false /*fLeaveOpen*/, &hVfsFile);
                             if (RT_SUCCESS(rc))
                             {
                                 *phVfsObj = RTVfsObjFromFile(hVfsFile);
                                 RTVfsFileRelease(hVfsFile);
-                                AssertStmt(*phVfsObj == NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
+                                AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
                             }
                             else
@@ -408,5 +355,5 @@
 
             case RTFS_TYPE_SYMLINK:
-                if (fFlags & RTVFSOBJ_F_OPEN_SYMLINK)
+                if (fVfsFlags & RTVFSOBJ_F_OPEN_SYMLINK)
                 {
                     uint32_t cRefs = RTVfsDirRetain(pThis->hSelf);
@@ -448,23 +395,23 @@
          * Consider file or directory creation.
          */
-        if (   (   (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE
-                || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE
-                || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE)
-            && (fFlags & RTVFSOBJ_F_CREATE_MASK) != RTVFSOBJ_F_CREATE_NOTHING)
+        if (   (   (fFileOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE
+                || (fFileOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE
+                || (fFileOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE)
+            && (fVfsFlags & RTVFSOBJ_F_CREATE_MASK) != RTVFSOBJ_F_CREATE_NOTHING)
         {
 
-            if ((fFlags & RTVFSOBJ_F_CREATE_MASK) == RTVFSOBJ_F_CREATE_FILE)
+            if ((fVfsFlags & RTVFSOBJ_F_CREATE_MASK) == RTVFSOBJ_F_CREATE_FILE)
             {
                 RTFILE hFile;
-                rc = RTDirRelFileOpen(pThis->hDir, pszEntry, fOpen, &hFile);
+                rc = RTDirRelFileOpen(pThis->hDir, pszEntry, fFileOpen, &hFile);
                 if (RT_SUCCESS(rc))
                 {
                     RTVFSFILE hVfsFile;
-                    rc = RTVfsFileFromRTFile(hFile, fOpen, false /*fLeaveOpen*/, &hVfsFile);
+                    rc = RTVfsFileFromRTFile(hFile, fFileOpen, false /*fLeaveOpen*/, &hVfsFile);
                     if (RT_SUCCESS(rc))
                     {
                         *phVfsObj = RTVfsObjFromFile(hVfsFile);
                         RTVfsFileRelease(hVfsFile);
-                        AssertStmt(*phVfsObj == NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
+                        AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
                     }
                     else
@@ -472,9 +419,9 @@
                 }
             }
-            else if ((fFlags & RTVFSOBJ_F_CREATE_MASK) == RTVFSOBJ_F_CREATE_DIRECTORY)
+            else if ((fVfsFlags & RTVFSOBJ_F_CREATE_MASK) == RTVFSOBJ_F_CREATE_DIRECTORY)
             {
                 RTDIR hSubDir;
-                rc = RTDirRelDirCreate(pThis->hDir, pszEntry, (fOpen & RTFILE_O_CREATE_MODE_MASK) >> RTFILE_O_CREATE_MODE_SHIFT,
-                                       0 /* fFlags */, &hSubDir);
+                rc = RTDirRelDirCreate(pThis->hDir, pszEntry, (fFileOpen & RTFILE_O_CREATE_MODE_MASK) >> RTFILE_O_CREATE_MODE_SHIFT,
+                                       0 /* fVfsFlags */, &hSubDir);
                 if (RT_SUCCESS(rc))
                 {
@@ -720,6 +667,5 @@
         RTVFSOBJSETOPS_VERSION
     },
-    rtVfsStdDir_OpenObj,
-    rtVfsStdDir_TraversalOpen,
+    rtVfsStdDir_Open,
     rtVfsStdDir_OpenFile,
     rtVfsStdDir_OpenDir,
