Index: trunk/src/VBox/Runtime/common/fs/fatvfs.cpp
===================================================================
--- trunk/src/VBox/Runtime/common/fs/fatvfs.cpp	(revision 69678)
+++ trunk/src/VBox/Runtime/common/fs/fatvfs.cpp	(revision 69813)
@@ -2074,4 +2074,5 @@
 static int rtFsFatObj_SetMode(PRTFSFATOBJ pThis, RTFMODE fMode, RTFMODE fMask)
 {
+    __debugbreak();
 #if 0
     if (fMask != ~RTFS_TYPE_MASK)
@@ -4054,7 +4055,145 @@
 
 /**
+ * @interface_method_impl{RTVFSDIROPS,pfnOpen}
+ */
+static DECLCALLBACK(int) rtFsFatDir_Open(void *pvThis, const char *pszEntry, uint64_t fOpen,
+                                         uint32_t fFlags, PRTVFSOBJ phVfsObj)
+{
+    PRTFSFATDIR     pThis   = (PRTFSFATDIR)pvThis;
+    PRTFSFATDIRSHRD pShared = pThis->pShared;
+
+    /*
+     * Try open existing file.
+     */
+    uint32_t    offEntryInDir;
+    bool        fLong;
+    FATDIRENTRY DirEntry;
+    int rc = rtFsFatDirShrd_FindEntry(pShared, pszEntry, &offEntryInDir, &fLong, &DirEntry);
+    if (RT_SUCCESS(rc))
+    {
+        switch (DirEntry.fAttrib & (FAT_ATTR_DIRECTORY | FAT_ATTR_VOLUME))
+        {
+            case 0:
+                if (fFlags & RTVFSOBJ_F_OPEN_FILE)
+                {
+                    if (   !(DirEntry.fAttrib & FAT_ATTR_READONLY)
+                        || !(fOpen & RTFILE_O_WRITE))
+                    {
+                        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)
+                        {
+                            RTVFSFILE hVfsFile;
+                            rc = rtFsFatFile_New(pShared->Core.pVol, pShared, &DirEntry, offEntryInDir, fOpen, &hVfsFile);
+                            if (RT_SUCCESS(rc))
+                            {
+                                *phVfsObj = RTVfsObjFromFile(hVfsFile);
+                                RTVfsFileRelease(hVfsFile);
+                                AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
+                            }
+                        }
+                        else
+                            rc = VERR_ALREADY_EXISTS;
+                    }
+                    else
+                        rc = VERR_ACCESS_DENIED;
+                }
+                else
+                    rc = VERR_IS_A_FILE;
+                break;
+
+            case FAT_ATTR_DIRECTORY:
+                if (fFlags & RTVFSOBJ_F_OPEN_DIRECTORY)
+                {
+                    if (   !(DirEntry.fAttrib & FAT_ATTR_READONLY)
+                        || !(fOpen & RTFILE_O_WRITE))
+                    {
+                        if (   (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN
+                            || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_OPEN_CREATE)
+                        {
+                            RTVFSDIR hVfsDir;
+                            rc = rtFsFatDir_New(pShared->Core.pVol, pShared, &DirEntry, offEntryInDir,
+                                                RTFSFAT_GET_CLUSTER(&DirEntry, pShared->Core.pVol), UINT64_MAX /*offDisk*/,
+                                                DirEntry.cbFile, &hVfsDir);
+                            if (RT_SUCCESS(rc))
+                            {
+                                *phVfsObj = RTVfsObjFromDir(hVfsDir);
+                                RTVfsDirRelease(hVfsDir);
+                                AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
+                            }
+                        }
+                        else if ((fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE)
+                            rc = VERR_INVALID_FUNCTION;
+                        else
+                            rc = VERR_ALREADY_EXISTS;
+                    }
+                    else
+                        rc = VERR_ACCESS_DENIED;
+                }
+                else
+                    rc = VERR_IS_A_DIRECTORY;
+                break;
+
+            default:
+                rc = VERR_PATH_NOT_FOUND;
+                break;
+        }
+    }
+    /*
+     * Create a file or directory?
+     */
+    else if (rc == VERR_FILE_NOT_FOUND)
+    {
+        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 ((fFlags & RTVFSOBJ_F_CREATE_MASK) == RTVFSOBJ_F_CREATE_FILE)
+            {
+                rc = rtFsFatDirShrd_CreateEntry(pShared, pszEntry, FAT_ATTR_ARCHIVE, 0 /*cbInitial*/, &offEntryInDir, &DirEntry);
+                if (RT_SUCCESS(rc))
+                {
+                    RTVFSFILE hVfsFile;
+                    rc = rtFsFatFile_New(pShared->Core.pVol, pShared, &DirEntry, offEntryInDir, fOpen, &hVfsFile);
+                    if (RT_SUCCESS(rc))
+                    {
+                        *phVfsObj = RTVfsObjFromFile(hVfsFile);
+                        RTVfsFileRelease(hVfsFile);
+                        AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
+                    }
+                }
+            }
+            else if ((fFlags & RTVFSOBJ_F_CREATE_MASK) == RTVFSOBJ_F_CREATE_DIRECTORY)
+            {
+                rc = rtFsFatDirShrd_CreateEntry(pShared, pszEntry, FAT_ATTR_ARCHIVE | FAT_ATTR_DIRECTORY,
+                                                pShared->Core.pVol->cbCluster, &offEntryInDir, &DirEntry);
+                if (RT_SUCCESS(rc))
+                {
+                    RTVFSDIR hVfsDir;
+                    rc = rtFsFatDir_New(pShared->Core.pVol, pShared, &DirEntry, offEntryInDir,
+                                        RTFSFAT_GET_CLUSTER(&DirEntry, pShared->Core.pVol), UINT64_MAX /*offDisk*/,
+                                        DirEntry.cbFile, &hVfsDir);
+                    if (RT_SUCCESS(rc))
+                    {
+                        *phVfsObj = RTVfsObjFromDir(hVfsDir);
+                        RTVfsDirRelease(hVfsDir);
+                        AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
+                    }
+                }
+            }
+            else
+                rc = VERR_VFS_UNSUPPORTED_CREATE_TYPE;
+        }
+    }
+
+    return rc;
+}
+
+
+/**
  * @interface_method_impl{RTVFSDIROPS,pfnOpenFile}
  */
-static DECLCALLBACK(int) rtFsFatDir_OpenFile(void *pvThis, const char *pszFilename, uint32_t fOpen, PRTVFSFILE phVfsFile)
+static DECLCALLBACK(int) rtFsFatDir_OpenFile(void *pvThis, const char *pszFilename, uint64_t fOpen, PRTVFSFILE phVfsFile)
 {
     PRTFSFATDIR     pThis   = (PRTFSFATDIR)pvThis;
@@ -4639,4 +4778,5 @@
         RTVFSOBJSETOPS_VERSION
     },
+    rtFsFatDir_Open,
     rtFsFatDir_TraversalOpen,
     rtFsFatDir_OpenFile,
Index: trunk/src/VBox/Runtime/common/fs/isovfs.cpp
===================================================================
--- trunk/src/VBox/Runtime/common/fs/isovfs.cpp	(revision 69678)
+++ trunk/src/VBox/Runtime/common/fs/isovfs.cpp	(revision 69813)
@@ -2993,7 +2993,146 @@
 
 /**
+ * @interface_method_impl{RTVFSDIROPS,pfnOpen}
+ */
+static DECLCALLBACK(int) rtFsIsoDir_Open(void *pvThis, const char *pszEntry, uint64_t fOpen,
+                                         uint32_t fFlags, PRTVFSOBJ phVfsObj)
+{
+    PRTFSISODIROBJ  pThis   = (PRTFSISODIROBJ)pvThis;
+    PRTFSISODIRSHRD pShared = pThis->pShared;
+
+    /*
+     * We cannot create or replace anything, just open stuff.
+     */
+    if (   (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE
+        || (fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE_REPLACE)
+        return VERR_WRITE_PROTECT;
+
+    /*
+     * Try open whatever it is.
+     */
+    int rc;
+    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_Open: FindEntry9660(,%s,) -> %Rrc\n", pszEntry, rc));
+        if (RT_SUCCESS(rc))
+        {
+            switch (fMode & RTFS_TYPE_MASK)
+            {
+                case RTFS_TYPE_FILE:
+                    if (fFlags & RTVFSOBJ_F_OPEN_FILE)
+                    {
+                        RTVFSFILE hVfsFile;
+                        rc = rtFsIsoFile_New9660(pShared->Core.pVol, pShared, pDirRec, cDirRecs,
+                                                 offDirRec, fOpen, uVersion, &hVfsFile);
+                        if (RT_SUCCESS(rc))
+                        {
+                            *phVfsObj = RTVfsObjFromFile(hVfsFile);
+                            RTVfsFileRelease(hVfsFile);
+                            AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
+                        }
+                    }
+                    else
+                        rc = VERR_IS_A_FILE;
+                    break;
+
+                case RTFS_TYPE_DIRECTORY:
+                    if (fFlags & RTVFSOBJ_F_OPEN_DIRECTORY)
+                    {
+                        RTVFSDIR hVfsDir;
+                        rc = rtFsIsoDir_New9660(pShared->Core.pVol, pShared, pDirRec, cDirRecs, offDirRec, &hVfsDir);
+                        if (RT_SUCCESS(rc))
+                        {
+                            *phVfsObj = RTVfsObjFromDir(hVfsDir);
+                            RTVfsDirRelease(hVfsDir);
+                            AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
+                        }
+                    }
+                    else
+                        rc = VERR_IS_A_DIRECTORY;
+                    break;
+
+                case RTFS_TYPE_SYMLINK:
+                case RTFS_TYPE_DEV_BLOCK:
+                case RTFS_TYPE_DEV_CHAR:
+                case RTFS_TYPE_FIFO:
+                case RTFS_TYPE_SOCKET:
+                case RTFS_TYPE_WHITEOUT:
+                    rc = VERR_NOT_IMPLEMENTED;
+                    break;
+
+                default:
+                    rc = VERR_PATH_NOT_FOUND;
+                    break;
+            }
+        }
+    }
+    else
+    {
+        /*
+         * UDF
+         */
+        PCUDFFILEIDDESC pFid;
+        rc = rtFsIsoDir_FindEntryUdf(pShared, pszEntry, &pFid);
+        Log2(("rtFsIsoDir_Open: 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 (fFlags & RTVFSOBJ_F_OPEN_FILE)
+                    {
+                        RTVFSFILE hVfsFile;
+                        rc = rtFsIsoFile_NewUdf(pShared->Core.pVol, pShared, pFid, fOpen, &hVfsFile);
+                        if (RT_SUCCESS(rc))
+                        {
+                            *phVfsObj = RTVfsObjFromFile(hVfsFile);
+                            RTVfsFileRelease(hVfsFile);
+                            AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
+                        }
+                    }
+                    else
+                        rc = VERR_IS_A_FILE;
+                }
+                else
+                {
+                    if (fFlags & RTVFSOBJ_F_OPEN_DIRECTORY)
+                    {
+                        RTVFSDIR hVfsDir;
+                        rc = rtFsIsoDir_NewUdf(pShared->Core.pVol, pShared, pFid, &hVfsDir);
+                        if (RT_SUCCESS(rc))
+                        {
+                            *phVfsObj = RTVfsObjFromDir(hVfsDir);
+                            RTVfsDirRelease(hVfsDir);
+                            AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
+                        }
+                    }
+                    else
+                        rc = VERR_IS_A_DIRECTORY;
+                }
+            }
+            /* We treat UDF_FILE_FLAGS_DELETED like RTFS_TYPE_WHITEOUT for now. */
+            else
+                rc = VERR_PATH_NOT_FOUND;
+        }
+    }
+    return rc;
+
+}
+
+
+/**
  * @interface_method_impl{RTVFSDIROPS,pfnOpenFile}
  */
-static DECLCALLBACK(int) rtFsIsoDir_OpenFile(void *pvThis, const char *pszFilename, uint32_t fOpen, PRTVFSFILE phVfsFile)
+static DECLCALLBACK(int) rtFsIsoDir_OpenFile(void *pvThis, const char *pszFilename, uint64_t fOpen, PRTVFSFILE phVfsFile)
 {
     PRTFSISODIROBJ  pThis   = (PRTFSISODIROBJ)pvThis;
@@ -3654,4 +3793,5 @@
         RTVFSOBJSETOPS_VERSION
     },
+    rtFsIsoDir_Open,
     rtFsIsoDir_TraversalOpen,
     rtFsIsoDir_OpenFile,
