Index: /trunk/include/iprt/dir.h
===================================================================
--- /trunk/include/iprt/dir.h	(revision 33819)
+++ /trunk/include/iprt/dir.h	(revision 33820)
@@ -4,5 +4,5 @@
 
 /*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -29,7 +29,5 @@
 #include <iprt/cdefs.h>
 #include <iprt/types.h>
-#ifdef IN_RING3
-# include <iprt/fs.h>
-#endif
+#include <iprt/fs.h>
 
 
@@ -40,6 +38,4 @@
  * @{
  */
-
-#ifdef IN_RING3
 
 /**
@@ -412,5 +408,4 @@
                             PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime);
 
-#endif /* IN_RING3 */
 /** @} */
 
Index: /trunk/include/iprt/vfs.h
===================================================================
--- /trunk/include/iprt/vfs.h	(revision 33820)
+++ /trunk/include/iprt/vfs.h	(revision 33820)
@@ -0,0 +1,200 @@
+/** @file
+ * IPRT - Virtual Filesystem.
+ */
+
+/*
+ * Copyright (C) 2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_vfs_h
+#define ___iprt_vfs_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/dir.h>
+#include <iprt/fs.h>
+#include <iprt/symlink.h>
+#include <iprt/sg.h>
+#include <iprt/time.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_fs    RTVfs - Virtual Filesystem
+ * @ingroup grp_rt
+ * @{
+ */
+
+/** Virtual Filesystem handle. */
+typedef struct RTVFSINTERNAL           *RTVFS;
+/** Pointer to a VFS handle. */
+typedef RTVFS                          *PRTVFS;
+/** A NIL VFS directory handle. */
+#define NIL_RTVFS                       ((RTVFS)~(uintptr_t)0)
+
+/** Virtual Filesystem directory handle. */
+typedef struct RTVFSDIRINTERNAL        *RTVFSDIR;
+/** Pointer to a VFS directory handle. */
+typedef RTVFSDIR                       *PRTVFSDIR;
+/** A NIL VFS directory handle. */
+#define NIL_RTVFSDIR                    ((RTVFSDIR)~(uintptr_t)0)
+
+/** Virtual Filesystem I/O stream handle. */
+typedef struct RTVFSIOSTREAMINTERNAL   *RTVFSIOSTREAM;
+/** Pointer to a VFS I/O stream handle. */
+typedef RTVFSIOSTREAM                  *PRTVFSIOSTREAM;
+/** A NIL VFS I/O stream handle. */
+#define NIL_RTVFSIOSTREAM               ((RTVFSIOSTREAM)~(uintptr_t)0)
+
+/** Virtual Filesystem file handle. */
+typedef struct RTVFSFILEINTERNAL       *RTVFSFILE;
+/** Pointer to a VFS file handle. */
+typedef RTVFSFILE                      *PRTVFSFILE;
+/** A NIL VFS file handle. */
+#define NIL_RTVFSFILE                   ((RTVFSFILE)~(uintptr_t)0)
+
+/** Virtual Filesystem symbolic link handle. */
+typedef struct RTVFSSYMLINKINTERNAL    *RTVFSSYMLINK;
+/** Pointer to a VFS symbolic link handle. */
+typedef RTVFSSYMLINK                   *PRTVFSSYMLINK;
+/** A NIL VFS symbolic link handle. */
+#define NIL_RTVFSSYMLINK                ((RTVFSSYMLINK)~(uintptr_t)0)
+
+
+/** @name RTVfsCreate flags
+ * @{ */
+/** Whether the file system is read-only. */
+#define RTVFS_C_READONLY                RT_BIT(0)
+/** Whether we the VFS should be thread safe (i.e. automaticaly employ
+ * locks). */
+#define RTVFS_C_THREAD_SAFE             RT_BIT(1)
+/** @}  */
+
+/**
+ * Creates an empty virtual filesystem.
+ *
+ * @returns IPRT status code.
+ * @param   pszName     Name, for logging and such.
+ * @param   fFlags      Flags, MBZ.
+ * @param   phVfs       Where to return the VFS handle.  Release the returned
+ *                      reference by calling RTVfsRelease.
+ */
+RTDECL(int)         RTVfsCreate(const char *pszName, uint32_t fFlags, PRTVFS phVfs);
+RTDECL(uint32_t)    RTVfsRetain(RTVFS phVfs);
+RTDECL(uint32_t)    RTVfsRelease(RTVFS phVfs);
+RTDECL(int)         RTVfsAttach(RTVFS hVfs, const char *pszMountPoint, uint32_t fFlags, RTVFS hVfsAttach);
+RTDECL(int)         RTVfsDetach(RTVFS hVfs, const char *pszMountPoint, RTVFS hVfsToDetach, PRTVFS *phVfsDetached);
+RTDECL(uint32_t)    RTVfsGetAttachmentCount(RTVFS hVfs);
+RTDECL(int)         RTVfsGetAttachment(RTVFS hVfs, uint32_t iOrdinal, PRTVFS *phVfsAttached, uint32_t *pfFlags,
+                                       char *pszMountPoint, size_t cbMountPoint);
+
+/** @defgroup grp_vfs_dir           VFS Directory API
+ * @{
+ */
+/** @}  */
+
+
+/** @defgroup grp_vfs_iostream      VFS I/O Stream
+ * @{
+ */
+RTDECL(uint32_t)    RTVfsIoStrmRetain(RTVFSIOSTREAM hVfsIos);
+RTDECL(uint32_t)    RTVfsIoStrmRelease(RTVFSIOSTREAM hVfsIos);
+RTDECL(RTVFSFILE)   RTVfsIoStrmToFile(RTVFSIOSTREAM hVfsIos);
+RTDECL(int)         RTVfsIoStrmQueryInfo(RTVFSIOSTREAM hVfsIos, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr);
+RTDECL(int)         RTVfsIoStrmRead(RTVFSIOSTREAM hVfsIos, void *pvBuf, size_t cbToRead, size_t *pcbRead);
+RTDECL(int)         RTVfsIoStrmWrite(RTVFSIOSTREAM hVfsIos, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten);
+RTDECL(int)         RTVfsIoStrmSgRead(RTVFSIOSTREAM hVfsIos, PCRTSGBUF pSgBuf, size_t *pcbRead);
+RTDECL(int)         RTVfsIoStrmSgWrite(RTVFSIOSTREAM hVfsIos, PCRTSGBUF pSgBuf, size_t *pcbWritten);
+RTDECL(int)         RTVfsIoStrmFlush(RTVFSIOSTREAM hVfsIos);
+RTDECL(RTFOFF)      RTVfsIoStrmPoll(RTVFSIOSTREAM hVfsIos, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr,
+                                    uint32_t *pfRetEvents);
+RTDECL(RTFOFF)      RTVfsIoStrmTell(RTVFSIOSTREAM hVfsIos);
+/** @} */
+
+
+/** @defgroup grp_vfs_file          VFS File API
+ * @{
+ */
+RTDECL(int)         RTVfsFileOpen(RTVFS hVfs, const char *pszFilename, uint32_t fOpen, PRTVFSFILE phVfsFile);
+
+/**
+ * Create a VFS file handle from a standard IPRT file handle (RTFILE).
+ *
+ * @returns IPRT status code.
+ * @param   hFile           The standard IPRT file handle.
+ * @param   fOpen           The flags the handle was opened with.  Pass 0 to
+ *                          have these detected.
+ * @param   fLeaveOpen      Whether to leave the handle open when the VFS file
+ *                          is released, or to close it (@c false).
+ * @param   phVfsFile       Where to return the VFS file handle.
+ */
+RTDECL(int)         RTVfsFileFromRTFile(RTFILE hFile, uint32_t fOpen, bool fLeaveOpen, PRTVFSFILE phVfsFile);
+RTDECL(RTHCUINTPTR) RTVfsFileToNative(RTFILE hVfsFile);
+
+/**
+ * Convert the VFS file handle to a VFS I/O stream handle.
+ *
+ * @returns The VFS I/O stream handle on success, this must be released.
+ *          NIL_RTVFSIOSTREAM if the file handle is invalid.
+ * @param   hVfsFile        The VFS file handle.
+ */
+RTDECL(RTVFSIOSTREAM) RTVfsFileToIoStream(RTVFSFILE hVfsFile);
+
+/**
+ * Retains a reference to the VFS file handle.
+ *
+ * @returns New reference count on success, UINT32_MAX on failure.
+ * @param   hVfsFile        The VFS file handle.
+ */
+RTDECL(uint32_t)    RTVfsFileRetain(RTVFSFILE hVfsFile);
+
+/**
+ * Releases a reference to the VFS file handle.
+ *
+ * @returns New reference count on success (0 if closed), UINT32_MAX on failure.
+ * @param   hVfsFile        The VFS file handle.
+ */
+RTDECL(uint32_t)    RTVfsFileRelease(RTVFSFILE hVfsFile);
+
+RTDECL(int)         RTVfsFileQueryInfo(RTVFSFILE hVfsFile, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr);
+RTDECL(int)         RTVfsFileRead(RTVFSFILE hVfsFile, void *pvBuf, size_t cbToRead, size_t *pcbRead);
+RTDECL(int)         RTVfsFileReadAt(RTVFSFILE hVfsFile, RTFOFF off, void *pvBuf, size_t cbToRead, size_t *pcbRead);
+RTDECL(int)         RTVfsFileWrite(RTVFSFILE hVfsFile, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten);
+RTDECL(int)         RTVfsFileWriteAt(RTVFSFILE hVfsFile, RTFOFF off, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten);
+RTDECL(int)         RTVfsFileFlush(RTVFSFILE hVfsFile);
+RTDECL(RTFOFF)      RTVfsFilePoll(RTVFSFILE hVfsFile, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr,
+                                  uint32_t *pfRetEvents);
+RTDECL(RTFOFF)      RTVfsFileTell(RTVFSFILE hVfsFile);
+
+RTDECL(int)         RTVfsFileSeek(RTVFSFILE hVfsFile, RTFOFF offSeek, uint32_t uMethod, uint64_t *poffActual);
+RTDECL(int)         RTVfsFileSetSize(RTVFSFILE hVfsFile, uint64_t cbSize);
+RTDECL(int)         RTVfsFileGetSize(RTVFSFILE hVfsFile, uint64_t *pcbSize);
+RTDECL(RTFOFF)      RTVfsFileGetMaxSize(RTVFSFILE hVfsFile);
+RTDECL(int)         RTVfsFileGetMaxSizeEx(RTVFSFILE hVfsFile, PRTFOFF pcbMax);
+
+/** @} */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif /* !___iprt_vfs_h */
+
+
Index: /trunk/include/iprt/vfslowlevel.h
===================================================================
--- /trunk/include/iprt/vfslowlevel.h	(revision 33820)
+++ /trunk/include/iprt/vfslowlevel.h	(revision 33820)
@@ -0,0 +1,519 @@
+/** @file
+ * IPRT - Virtual Filesystem.
+ */
+
+/*
+ * Copyright (C) 2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___iprt_vfslowlevel_h
+#define ___iprt_vfslowlevel_h
+
+#include <iprt/vfs.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_vfs_lowlevel   RTVfs - Low-level Interface.
+ * @ingroup grp_rt_vfs
+ * @{
+ */
+
+/**
+ * The VFS operations.
+ */
+typedef struct RTVFSOPS
+{
+    /** The structure version (RTVFSOPS_VERSION). */
+    uint32_t                uVersion;
+    /** The virtual file system feature mask.  */
+    uint32_t                fFeatures;
+    /** The name of the operations. */
+    const char             *pszName;
+
+    /**
+     * Destructor.
+     *
+    * @param   pvThis      The implementation specific data.
+     */
+    DECLCALLBACKMEMBER(void, pfnDestroy)(void *pvThis);
+
+    /**
+     * Opens the root directory.
+     *
+     * @returns IPRT status code.
+     * @param   pvThis      The implementation specific data.
+     * @param   phVfsDir    Where to return the handle to the root directory.
+     */
+    DECLCALLBACKMEMBER(int, pfnOpenRoot)(void *pvThis, PRTVFSDIR phVfsDir);
+
+    /** @todo There will be more methods here to optimize opening and
+     *        querying. */
+
+#if 0
+    /**
+     * Optional entry point for optimizing path traversal within the file system.
+     *
+     * @returns IPRT status code.
+     * @param   pvThis      The implementation specific data.
+     * @param   pszPath     The path to resolve.
+     * @param   poffPath    The current path offset on input, what we've
+     *                      traversed to on successful return.
+     * @param   phVfs???    Return handle to what we've traversed.
+     * @param   p???        Return other stuff...
+     */
+    DECLCALLBACKMEMBER(int, pfnTraverse)(void *pvThis, const char *pszPath, size_t *poffPath, PRTVFS??? phVfs?, ???* p???);
+#endif
+
+    /** Marks the end of the structure (RTVFSOPS_VERSION). */
+    uintptr_t               uEndMarker;
+} RTVFSOPS;
+/** Pointer to constant VFS operations. */
+typedef RTVFSOPS const PCRTVFSOPS;
+
+/** The RTVFSOPS structure version. */
+#define RTVFSOPS_VERSION            RT_MAKE_U32_FROM_U8(0xff,0x0f,1,0)
+
+/** @name RTVFSOPS::fFeatures
+ * @{ */
+/** The VFS supports attaching other systems. */
+#define RTVFSOPS_FEAT_ATTACH        RT_BIT_32(0)
+/** @}  */
+
+
+/**
+ * The object type.
+ */
+typedef enum RTVFSOBJTYPE
+{
+    /** Invalid type. */
+    RTVFSOBJTYPE_INVALID = 0,
+    /** Directory. */
+    RTVFSOBJTYPE_DIR,
+    /** Pure I/O stream. */
+    RTVFSOBJTYPE_IOSTREAM,
+    /** File. */
+    RTVFSOBJTYPE_FILE,
+    /** End of valid object types. */
+    RTVFSOBJTYPE_END,
+    /** Pure I/O stream. */
+    RTVFSOBJTYPE_32BIT_HACK = 0x7fffffff
+} RTVFSOBJTYPE;
+
+/**
+ * The basis for all virtual file system objects except RTVFS.
+ */
+typedef struct RTVFSOBJOPS
+{
+    /** The structure version (RTVFSOBJOPS_VERSION). */
+    uint32_t                uVersion;
+    /** The object type for type introspection. */
+    RTVFSOBJTYPE            enmType;
+    /** The name of the operations. */
+    const char             *pszName;
+
+    /**
+     * Close the object.
+     *
+     * @returns IPRT status code.
+     * @param   pvThis      The implementation specific file data.
+     */
+    DECLCALLBACKMEMBER(int, pfnClose)(void *pvThis);
+
+    /**
+     * Get information about the file.
+     *
+     * @returns IPRT status code.
+     * @param   pvThis      The implementation specific file data.
+     * @param   pObjInfo    Where to return the object info on success.
+     * @param   enmAddAttr  Which set of additional attributes to request.
+     * @sa      RTFileQueryInfo
+     */
+    DECLCALLBACKMEMBER(int, pfnQueryInfo)(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr);
+
+    /** Marks the end of the structure (RTVFSOBJOPS_VERSION). */
+    uintptr_t               uEndMarker;
+} RTVFSOBJOPS;
+/** Pointer to constant VFS object operations. */
+typedef RTVFSOBJOPS const *PCRTVFSOBJOPS;
+
+/** The RTVFSOBJOPS structure version. */
+#define RTVFSOBJOPS_VERSION         RT_MAKE_U32_FROM_U8(0xff,0x1f,1,0)
+
+
+/**
+ * Additional operations for setting object attributes.
+ */
+typedef struct RTVFSOBJSETOPS
+{
+    /** The structure version (RTVFSOBJSETOPS_VERSION). */
+    uint32_t                uVersion;
+    /** The offset to the RTVFSOBJOPS structure. */
+    int32_t                 offObjOps;
+
+    /**
+     * Set the unix style owner and group.
+     *
+     * @returns IPRT status code.
+     * @param   pvThis              The implementation specific file data.
+     * @param   fMode               The new mode bits.
+     * @param   fMask               The mask indicating which bits we are
+     *                              changing.
+     * @sa      RTFileSetMode
+     */
+    DECLCALLBACKMEMBER(int, pfnSetMode)(void *pvThis, RTFMODE fMode, RTFMODE fMask);
+
+    /**
+     * Set the timestamps associated with the object.
+     *
+     * @returns IPRT status code.
+     * @param   pvThis              The implementation specific file data.
+     * @param   pAccessTime         Pointer to the new access time. NULL if not
+     *                              to be changed.
+     * @param   pModificationTime   Pointer to the new modifcation time. NULL if
+     *                              not to be changed.
+     * @param   pChangeTime         Pointer to the new change time. NULL if not
+     *                              to be changed.
+     * @param   pBirthTime          Pointer to the new time of birth. NULL if
+     *                              not to be changed.
+     * @remarks See RTFileSetTimes for restrictions and behavior imposed by the
+     *          host OS or underlying VFS provider.
+     * @sa      RTFileSetTimes
+     */
+    DECLCALLBACKMEMBER(int, pfnSetTimes)(void *pvThis, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
+                                         PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime);
+
+    /**
+     * Set the unix style owner and group.
+     *
+     * @returns IPRT status code.
+     * @param   pvThis      The implementation specific file data.
+     * @param   uid         The user ID of the new owner.  NIL_RTUID if
+     *                      unchanged.
+     * @param   gid         The group ID of the new owner group.  NIL_RTGID if
+     *                      unchanged.
+     * @sa      RTFileSetOwner
+     */
+    DECLCALLBACKMEMBER(int, pfnSetOwner)(void *pvThis, RTUID uid, RTGID gid);
+
+    /** Marks the end of the structure (RTVFSOBJSETOPS_VERSION). */
+    uintptr_t               uEndMarker;
+} RTVFSOBJSETOPS;
+/** Pointer to const object attribute setter operations. */
+typedef RTVFSOBJSETOPS const *PCRTVFSOBJSETOPS;
+
+/** The RTVFSOBJSETOPS structure version. */
+#define RTVFSOBJSETOPS_VERSION      RT_MAKE_U32_FROM_U8(0xff,0x2f,1,0)
+
+
+/**
+ * The directory operations.
+ *
+ * @extends RTVFSOBJOPS
+ * @extends RTVFSOBJSETOPS
+ */
+typedef struct RTVFSDIROPS
+{
+    /** The basic object operation.  */
+    RTVFSOBJOPS             Obj;
+    /** The structure version (RTVFSDIROPS_VERSION). */
+    uint32_t                uVersion;
+    /** Reserved field, MBZ. */
+    uint32_t                fReserved;
+    /** The object setter operations. */
+    RTVFSOBJSETOPS          ObjSet;
+
+    /**
+     * Open or create a file.
+     *
+     * @returns IPRT status code.
+     * @param   pvThis      The implementation specific directory data.
+     * @param   pszFilename The name of the immediate file to open or create.
+     * @param   fOpen       The open flags (RTFILE_O_XXX).
+     * @param   phVfsFile   Where to return the thandle to the opened file.
+     * @sa      RTFileOpen.
+     */
+    DECLCALLBACKMEMBER(int, pfnOpenFile)(void *pvThis, const char *pszFilename, uint32_t fOpen, PRTVFSFILE phVfsFile);
+
+    /**
+     * Open an existing subdirectory.
+     *
+     * @returns IPRT status code.
+     * @param   pvThis      The implementation specific directory data.
+     * @param   pszSubDir   The name of the immediate subdirectory to open.
+     * @param   phVfsDir    Where to return the handle to the opened directory.
+     * @sa      RTDirOpen.
+     */
+    DECLCALLBACKMEMBER(int, pfnOpenDir)(void *pvThis, const char *pszSubDir, PRTVFSDIR phVfsDir);
+
+    /**
+     * Creates a new subdirectory.
+     *
+     * @returns IPRT status code.
+     * @param   pvThis      The implementation specific directory data.
+     * @param   pszSubDir   The name of the immediate subdirectory to create.
+     * @param   fMode       The mode mask of the new directory.
+     * @param   phVfsDir    Where to optionally return the handle to the newly
+     *                      create directory.
+     * @sa      RTDirCreate.
+     */
+    DECLCALLBACKMEMBER(int, pfnCreateDir)(void *pvThis, const char *pszSubDir, RTFMODE fMode, PRTVFSDIR phVfsDir);
+
+    /**
+     * Opens an existing symbolic link.
+     *
+     * @returns IPRT status code.
+     * @param   pvThis      The implementation specific directory data.
+     * @param   pszSymlink  The name of the immediate symbolic link to open.
+     * @param   phVfsSymlink    Where to optionally return the handle to the
+     *                      newly create symbolic link.
+     * @sa      RTSymlinkCreate.
+     */
+    DECLCALLBACKMEMBER(int, pfnOpenSymlink)(void *pvThis, const char *pszSymlink, PRTVFSSYMLINK phVfsSymlink);
+
+    /**
+     * Creates a new symbolic link.
+     *
+     * @returns IPRT status code.
+     * @param   pvThis      The implementation specific directory data.
+     * @param   pszSymlink  The name of the immediate symbolic link to create.
+     * @param   pszTarget   The symbolic link target.
+     * @param   enmType     The symbolic link type.
+     * @param   phVfsSymlink    Where to optionally return the handle to the
+     *                      newly create symbolic link.
+     * @sa      RTSymlinkCreate.
+     */
+    DECLCALLBACKMEMBER(int, pfnCreateSymlink)(void *pvThis, const char *pszSymlink, const char *pszTarget,
+                                              RTSYMLINKTYPE enmType, PRTVFSSYMLINK phVfsSymlink);
+
+    /**
+     * Removes a directory entry.
+     *
+     * @returns IPRT status code.
+     * @param   pvThis      The implementation specific directory data.
+     * @param   pszEntry    The name of the directory entry to remove.
+     * @param   fType       If non-zero, this restricts the type of the entry to
+     *                      the object type indicated by the mask
+     *                      (RTFS_TYPE_XXX).
+     * @sa      RTFileRemove, RTDirRemove, RTSymlinkRemove.
+     */
+    DECLCALLBACKMEMBER(int, pfnUnlinkEntry)(void *pvThis, const char *pszEntry, RTFMODE fType, PRTVFSDIR phVfsDir);
+
+    /**
+     * Rewind the directory stream so that the next read returns the first
+     * entry.
+     *
+     * @returns IPRT status code.
+     * @param   pvThis      The implementation specific directory data.
+     */
+    DECLCALLBACKMEMBER(int, pfnRewindDir)(void *pvThis);
+
+    /**
+     * Rewind the directory stream so that the next read returns the first
+     * entry.
+     *
+     * @returns IPRT status code.
+     * @param   pvThis      The implementation specific directory data.
+     * @param   pDirEntry   Output buffer.
+     * @param   pcbDirEntry Complicated, see RTDirReadEx.
+     * @param   enmAddAttr  Which set of additional attributes to request.
+     * @sa      RTDirReadEx
+     */
+    DECLCALLBACKMEMBER(int, pfnReadDir)(void *pvThis, PRTDIRENTRYEX pDirEntry, size_t *pcbDirEntry, RTFSOBJATTRADD enmAddAttr);
+
+
+    /** Marks the end of the structure (RTVFSDIROPS_VERSION). */
+    uintptr_t               uEndMarker;
+} RTVFSDIROPS;
+/** Pointer to const directory operations. */
+typedef RTVFSDIROPS const *PCRTVFSDIROPS;
+/** The RTVFSDIROPS structure version. */
+#define RTVFSDIROPS_VERSION         RT_MAKE_U32_FROM_U8(0xff,0x3f,1,0)
+
+
+/**
+ * The basis for all I/O objects (files, pipes, sockets, devices, ++).
+ *
+ * @extends RTVFSOBJOPS
+ */
+typedef struct RTVFSIOSTREAMOPS
+{
+    /** The basic object operation.  */
+    RTVFSOBJOPS             Obj;
+    /** The structure version (RTVFSIOSTREAMOPS_VERSION). */
+    uint32_t                uVersion;
+    /** Reserved field, MBZ. */
+    uint32_t                fReserved;
+
+    /**
+     * Reads from the file/stream.
+     *
+     * @returns IPRT status code.
+     * @param   pvThis      The implementation specific file data.
+     * @param   off         Where to read at, -1 for the current position.
+     * @param   pSgBuf      Gather buffer describing the bytes that are to be
+     *                      written.
+     * @param   fBlocking   If @c true, the call is blocking, if @c false it
+     *                      should not block.
+     * @param   pcbRead     Where return the number of bytes actually read.  If
+     *                      NULL, try read all and fail if incomplete.
+     * @sa      RTFileRead, RTFileReadAt.
+     */
+    DECLCALLBACKMEMBER(int, pfnRead)(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead);
+
+    /**
+     * Writes to the file/stream.
+     *
+     * @returns IPRT status code.
+     * @param   pvThis      The implementation specific file data.
+     * @param   off         Where to start wrinting, -1 for the current
+     *                      position.
+     * @param   pSgBuf      Gather buffers describing the bytes that are to be
+     *                      written.
+     * @param   fBlocking   If @c true, the call is blocking, if @c false it
+     *                      should not block.
+     * @param   pcbWrite    Where to return the number of bytes actually
+     *                      written.  If  NULL, try write it all and fail if
+     *                      incomplete.
+     * @sa      RTFileWrite, RTFileWriteAt.
+     */
+    DECLCALLBACKMEMBER(int, pfnWrite)(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten);
+
+    /**
+     * Flushes any pending data writes to the stream.
+     *
+     * @returns IPRT status code.
+     * @param   pvThis      The implementation specific file data.
+     * @sa      RTFileFlush.
+     */
+    DECLCALLBACKMEMBER(int, pfnFlush)(void *pvThis);
+
+    /**
+     * Poll for events.
+     *
+     * @returns IPRT status code.
+     * @param   pvThis      The implementation specific file data.
+     * @param   fEvents     The events to poll for (RTPOLL_EVT_XXX).
+     * @param   cMillies    How long to wait for event to eventuate.
+     * @param   fIntr       Whether the wait is interruptible and can return
+     *                      VERR_INTERRUPTED (@c true) or if this condition
+     *                      should be hidden from the caller (@c false).
+     * @param   pfRetEvents Where to return the event mask.
+     * @sa      RTPollSetAdd, RTPoll, RTPollNoResume.
+     */
+    DECLCALLBACKMEMBER(int, pfnPollOne)(void *pvThis, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr,
+                                        uint32_t *pfRetEvents);
+
+    /**
+     * Tells the current file/stream position.
+     *
+     * @returns IPRT status code.
+     * @param   pvThis      The implementation specific file data.
+     * @param   poffActual  Where to return the actual offset.
+     * @sa      RTFileSeek
+     */
+    DECLCALLBACKMEMBER(int, pfnTell)(void *pvThis, PRTFOFF poffActual);
+
+    /** Marks the end of the structure (RTVFSIOSTREAMOPS_VERSION). */
+    uintptr_t               uEndMarker;
+} RTVFSIOSTREAMOPS;
+/** Pointer to const I/O stream operations. */
+typedef RTVFSIOSTREAMOPS const *PCRTVFSIOSTREAMOPS;
+
+/** The RTVFSIOSTREAMOPS structure version. */
+#define RTVFSIOSTREAMOPS_VERSION    RT_MAKE_U32_FROM_U8(0xff,0x4f,1,0)
+
+
+/**
+ * The file operations.
+ *
+ * @extends RTVFSIOSTREAMOPS
+ * @extends RTVFSOBJSETOPS
+ */
+typedef struct RTVFSFILEOPS
+{
+    /** The I/O stream and basis object operations. */
+    RTVFSIOSTREAMOPS        Stream;
+    /** The structure version (RTVFSFILEOPS_VERSION). */
+    uint32_t                uVersion;
+    /** Reserved field, MBZ. */
+    uint32_t                fReserved;
+    /** The object setter operations. */
+    RTVFSOBJSETOPS          ObjSet;
+
+    /**
+     * Changes the current file position.
+     *
+     * @returns IPRT status code.
+     * @param   pvThis      The implementation specific file data.
+     * @param   offSeek     The offset to seek.
+     * @param   uMethod     The seek method, i.e. what the seek is relative to.
+     * @param   poffActual  Where to return the actual offset.
+     * @sa      RTFileSeek
+     */
+    DECLCALLBACKMEMBER(int, pfnSeek)(void *pvThis, RTFOFF offSeek, unsigned uMethod, PRTFOFF poffActual);
+
+    /**
+     * Get the current file/stream size.
+     *
+     * @returns IPRT status code.
+     * @param   pvThis      The implementation specific file data.
+     * @param   pcbFile     Where to store the current file size.
+     * @sa      RTFileGetSize
+     */
+    DECLCALLBACKMEMBER(int, pfnQuerySize)(void *pvThis, uint64_t *pcbFile);
+
+    /** @todo There will be more methods here. */
+
+    /** Marks the end of the structure (RTVFSFILEOPS_VERSION). */
+    uintptr_t               uEndMarker;
+} RTVFSFILEOPS;
+/** Pointer to const file operations. */
+typedef RTVFSFILEOPS const *PCRTVFSFILEOPS;
+
+/** The RTVFSFILEOPS structure version. */
+#define RTVFSFILEOPS_VERSION        RT_MAKE_U32_FROM_U8(0xff,0x5f,1,0)
+
+/**
+ * Creates a new VFS file handle.
+ *
+ * @returns IPRT status code
+ * @param   pFileOps            The file operations.
+ * @param   cbInstance          The size of the instance data.
+ * @param   fOpen               The open flags.  The minimum is the access mask.
+ * @param   hVfs                The VFS handle to associate this file with.
+ *                              NIL_VFS is ok.
+ * @param   phVfsFile           Where to return the new handle.
+ * @param   ppvInstance         Where to return the pointer to the instance data
+ *                              (size is @a cbInstance).
+ */
+RTDECL(int) RTVfsNewFile(PCRTVFSFILEOPS pFileOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs,
+                         PRTVFSFILE phVfsFile, void **ppvInstance);
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif /* !___iprt_vfslowlevel_h */
+
+
+
+
Index: /trunk/src/VBox/Runtime/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Runtime/Makefile.kmk	(revision 33819)
+++ /trunk/src/VBox/Runtime/Makefile.kmk	(revision 33820)
@@ -369,4 +369,6 @@
 	common/time/timeprog.cpp \
 	common/time/timesup.cpp \
+	common/vfs/vfsbase.cpp \
+	common/vfs/vfsstdfile.cpp \
 	generic/critsect-generic.cpp \
 	generic/env-generic.cpp \
Index: /trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp	(revision 33820)
+++ /trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp	(revision 33820)
@@ -0,0 +1,274 @@
+/* $Id$ */
+/** @file
+ * IPRT - Virtual File System, Base.
+ */
+
+/*
+ * Copyright (C) 2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include <iprt/vfs.h>
+#include <iprt/vfslowlevel.h>
+
+#include <iprt/asm.h>
+#include <iprt/err.h>
+#include <iprt/file.h>
+#include <iprt/mem.h>
+
+
+/*******************************************************************************
+*   Defined Constants And Macros                                               *
+*******************************************************************************/
+#define RTVFS_MAGIC                 UINT32_C(0x11112222)
+#define RTVFS_MAGIC_DEAD            (~RTVFS_MAGIC)
+#define RTVFSIOSTREAM_MAGIC         UINT32_C(0x33334444)
+#define RTVFSIOSTREAM_MAGIC_DEAD    (~RTVFSIOSTREAM_MAGIC)
+#define RTVFSFILE_MAGIC             UINT32_C(0x55556666)
+#define RTVFSFILE_MAGIC_DEAD        (~RTVFSFILE_MAGIC)
+
+/** The instance data alignment. */
+#define RTVFS_INST_ALIGNMENT        16U
+
+
+/*******************************************************************************
+*   Structures and Typedefs                                                    *
+*******************************************************************************/
+/** @todo Move all this stuff to internal/vfs.h */
+
+/**
+ * The VFS handle data.
+ */
+typedef struct RTVFSINTERNAL
+{
+    /** The VFS magic (RTVFS_MAGIC). */
+    uint32_t                uMagic;
+    /** Creation flags (RTVFS_C_XXX). */
+    uint32_t                fFlags;
+    /** Pointer to the instance data. */
+    void                   *pvThis;
+    /** The vtable. */
+    PCRTVFSOPS              pOps;
+    /** Read-write semaphore protecting all access to the VFS
+     * Only valid RTVFS_C_THREAD_SAFE is set, otherwise it is NIL_RTSEMRW. */
+    RTSEMRW                 hSemRW;
+    /** The number of references to this VFS.
+     * This count includes objects within the file system, so that the VFS
+     * won't be destroyed before all objects are closed. */
+    uint32_t volatile       cRefs;
+} RTVFSINTERNAL;
+
+
+/**
+ * The VFS directory handle data.
+ */
+typedef struct RTVFSDIRINTERNAL
+{
+    /** The VFS magic (RTVFSDIR_MAGIC). */
+    uint32_t                uMagic;
+    /** Reserved for flags or something. */
+    uint32_t                fReserved;
+    /** Pointer to the instance data. */
+    void                   *pvThis;
+    /** The vtable. */
+    PCRTVFSDIROPS           pOps;
+    /** The VFS RW sem if serialized. */
+    RTSEMRW                 hSemRW;
+    /** Reference back to the VFS containing this directory. */
+    RTVFS                   hVfs;
+    /** The number of references to this directory handle.  This does not
+     * include files or anything. */
+    uint32_t volatile       cRefs;
+} RTVFSDIRINTERNAL;
+
+
+/**
+ * The VFS I/O stream handle data.
+ *
+ * This is normally part of a type specific handle, like a file or pipe.
+ */
+typedef struct RTVFSIOSTREAMINTERNAL
+{
+    /** The VFS magic (RTVFSIOSTREAM_MAGIC). */
+    uint32_t                uMagic;
+    /** File open flags, at a minimum the access mask. */
+    uint32_t                fFlags;
+    /** Pointer to the instance data. */
+    void                   *pvThis;
+    /** The vtable. */
+    PCRTVFSIOSTREAMOPS      pOps;
+    /** The VFS RW sem if serialized. */
+    RTSEMRW                 hSemRW;
+    /** Reference back to the VFS containing this directory. */
+    RTVFS                   hVfs;
+    /** The number of references to this file VFS. */
+    uint32_t volatile       cRefs;
+} RTVFSIOSTREAMINTERNAL;
+
+
+/**
+ * The VFS file handle data.
+ *
+ * @extends RTVFSIOSTREAMINTERNAL
+ */
+typedef struct RTVFSFILEINTERNAL
+{
+    /** The VFS magic (RTVFSFILE_MAGIC). */
+    uint32_t                uMagic;
+    /** Reserved for flags or something. */
+    uint32_t                fReserved;
+    /** The vtable. */
+    PCRTVFSFILEOPS          pOps;
+    /** The stream handle data. */
+    RTVFSIOSTREAMINTERNAL   Stream;
+} RTVFSFILEINTERNAL;
+
+
+/**
+ * Internal object retainer that asserts sanity in strict builds.
+ *
+ * @returns The new reference count.
+ * @param   pcRefs              The reference counter.
+ */
+DECLINLINE(uint32_t) rtVfsRetain(uint32_t volatile *pcRefs)
+{
+    uint32_t cRefs = ASMAtomicIncU32(pcRefs);
+    AssertMsg(cRefs > 1 && cRefs < _1M, ("%#x\n", cRefs));
+    return cRefs;
+}
+
+
+/**
+ * Internal object retainer that asserts sanity in strict builds.
+ *
+ * @param   pcRefs              The reference counter.
+ */
+DECLINLINE(void) rtVfsRetainVoid(uint32_t volatile *pcRefs)
+{
+    (void)rtVfsRetain(pcRefs);
+}
+
+
+/**
+ * Internal object releaser that asserts sanity in strict builds.
+ *
+ * @returns The new reference count.
+ * @param   pcRefs              The reference counter.
+ */
+DECLINLINE(uint32_t) rtVfsRelease(uint32_t volatile *pcRefs)
+{
+    uint32_t cRefs = ASMAtomicDecU32(pcRefs);
+    AssertMsg(cRefs < _1M, ("%#x\n", cRefs));
+    return cRefs;
+}
+
+
+RTDECL(int) RTVfsNewFile(PCRTVFSFILEOPS pFileOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs,
+                         PRTVFSFILE phVfsFile, void **ppvInstance)
+{
+    /*
+     * Validate the input, be extra strict in strict builds.
+     */
+    AssertPtr(pFileOps);
+    AssertReturn(pFileOps->uVersion   == RTVFSFILEOPS_VERSION, VERR_VERSION_MISMATCH);
+    AssertReturn(pFileOps->uEndMarker == RTVFSFILEOPS_VERSION, VERR_VERSION_MISMATCH);
+    Assert(!pFileOps->fReserved);
+    Assert(cbInstance > 0);
+    Assert(fOpen & RTFILE_O_ACCESS_MASK);
+    AssertPtr(ppvInstance);
+    AssertPtr(phVfsFile);
+
+    RTVFSINTERNAL *pVfs = NULL;
+    if (hVfs == NIL_RTVFS)
+    {
+        pVfs = hVfs;
+        AssertPtrReturn(pVfs, VERR_INVALID_HANDLE);
+        AssertReturn(pVfs->uMagic == RTVFS_MAGIC, VERR_INVALID_HANDLE);
+    }
+
+    /*
+     * Allocate the handle + instance data.
+     */
+    size_t const cbThis = RT_ALIGN_Z(sizeof(RTVFSFILEINTERNAL), RTVFS_INST_ALIGNMENT)
+                        + RT_ALIGN_Z(cbInstance, RTVFS_INST_ALIGNMENT);
+    RTVFSFILEINTERNAL *pThis = (RTVFSFILEINTERNAL *)RTMemAllocZ(cbThis);
+    if (!pThis)
+        return VERR_NO_MEMORY;
+
+    pThis->uMagic           = RTVFSFILE_MAGIC;
+    pThis->fReserved        = 0;
+    pThis->pOps             = pFileOps;
+    pThis->Stream.uMagic    = RTVFSIOSTREAM_MAGIC;
+    pThis->Stream.fFlags    = fOpen;
+    pThis->Stream.pvThis    = (char *)pThis + RT_ALIGN_Z(sizeof(*pThis), RTVFS_INST_ALIGNMENT);
+    pThis->Stream.pOps      = &pFileOps->Stream;
+    pThis->Stream.hSemRW    = pVfs ? pVfs->hSemRW : NIL_RTSEMRW;
+    pThis->Stream.hVfs      = hVfs;
+    pThis->Stream.cRefs     = 1;
+    if (hVfs != NIL_RTVFS)
+        rtVfsRetainVoid(&pVfs->cRefs);
+
+    *phVfsFile   = pThis;
+    *ppvInstance = pThis->Stream.pvThis;
+    return VINF_SUCCESS;
+}
+
+
+RTDECL(uint32_t)    RTVfsFileRetain(RTVFSFILE hVfsFile)
+{
+    RTVFSFILEINTERNAL *pThis = hVfsFile;
+    AssertPtrReturn(pThis, UINT32_MAX);
+    AssertReturn(pThis->uMagic == RTVFSFILE_MAGIC, UINT32_MAX);
+    return rtVfsRetain(&pThis->Stream.cRefs);
+}
+
+
+RTDECL(uint32_t)    RTVfsFileRelease(RTVFSFILE hVfsFile)
+{
+    RTVFSFILEINTERNAL *pThis = hVfsFile;
+    AssertPtrReturn(pThis, UINT32_MAX);
+    AssertReturn(pThis->uMagic == RTVFSFILE_MAGIC, UINT32_MAX);
+
+    uint32_t cRefs = rtVfsRelease(&pThis->Stream.cRefs);
+    if (!cRefs)
+    {
+        ASMAtomicWriteU32(&pThis->uMagic, RTVFSFILE_MAGIC_DEAD);
+        ASMAtomicWriteU32(&pThis->Stream.uMagic, RTVFSIOSTREAM_MAGIC_DEAD);
+        pThis->pOps->Stream.Obj.pfnClose(pThis->Stream.pvThis);
+        RTMemFree(pThis);
+    }
+
+    return cRefs;
+}
+
+
+RTDECL(RTVFSIOSTREAM) RTVfsFileToIoStream(RTVFSFILE hVfsFile)
+{
+    RTVFSFILEINTERNAL *pThis = hVfsFile;
+    AssertPtrReturn(pThis, NIL_RTVFSIOSTREAM);
+    AssertReturn(pThis->uMagic == RTVFSFILE_MAGIC, NIL_RTVFSIOSTREAM);
+
+    rtVfsRetainVoid(&pThis->Stream.cRefs);
+    return &pThis->Stream;
+}
+
Index: /trunk/src/VBox/Runtime/common/vfs/vfsstdfile.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/vfs/vfsstdfile.cpp	(revision 33820)
+++ /trunk/src/VBox/Runtime/common/vfs/vfsstdfile.cpp	(revision 33820)
@@ -0,0 +1,387 @@
+/* $Id$ */
+/** @file
+ * IPRT - Virtual File System, Standard File Implementation.
+ */
+
+/*
+ * Copyright (C) 2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include <iprt/vfs.h>
+#include <iprt/vfslowlevel.h>
+
+#include <iprt/err.h>
+#include <iprt/file.h>
+#include <iprt/poll.h>
+#include <iprt/thread.h>
+
+
+/*******************************************************************************
+*   Structures and Typedefs                                                    *
+*******************************************************************************/
+/**
+ * Private data of a standard file.
+ */
+typedef struct RTVFSSTDFILE
+{
+    /** The file handle. */
+    RTFILE          hFile;
+    /** Whether to leave the handle open when the VFS handle is closed. */
+    bool            fLeaveOpen;
+} RTVFSSTDFILE;
+/** Pointer to the private data of a standard file. */
+typedef RTVFSSTDFILE *PRTVFSSTDFILE;
+
+
+/**
+ * @interface_method_impl{RTVFSOBJOPS,pfnClose}
+ */
+static DECLCALLBACK(int) rtVfsStdFile_Close(void *pvThis)
+{
+    PRTVFSSTDFILE pThis = (PRTVFSSTDFILE)pvThis;
+
+    int rc;
+    if (!pThis->fLeaveOpen)
+        rc = RTFileClose(pThis->hFile);
+    else
+        rc = VINF_SUCCESS;
+    pThis->hFile = NIL_RTFILE;
+
+    return rc;
+}
+
+
+/**
+ * @interface_method_impl{RTVFSOBJOPS,pfnQueryInfo}
+ */
+static DECLCALLBACK(int) rtVfsStdFile_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
+{
+    PRTVFSSTDFILE pThis = (PRTVFSSTDFILE)pvThis;
+    return RTFileQueryInfo(pThis->hFile, pObjInfo, enmAddAttr);
+}
+
+
+/**
+ * @interface_method_impl{RTVFSIOSTREAMOPS,pfnRead}
+ */
+static DECLCALLBACK(int) rtVfsStdFile_Read(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead)
+{
+    PRTVFSSTDFILE pThis = (PRTVFSSTDFILE)pvThis;
+    int           rc;
+
+    NOREF(fBlocking);
+    if (pSgBuf->cSegs == 1)
+    {
+        if (off < 0)
+            rc = RTFileRead(pThis->hFile, pSgBuf->paSegs[0].pvSeg, pSgBuf->paSegs[0].cbSeg, pcbRead);
+        else
+            rc = RTFileReadAt(pThis->hFile, off, pSgBuf->paSegs[0].pvSeg, pSgBuf->paSegs[0].cbSeg, pcbRead);
+    }
+    else
+    {
+        size_t  cbRead     = 0;
+        size_t  cbReadSeg;
+        size_t *pcbReadSeg = pcbRead ? &cbReadSeg : NULL;
+
+        for (uint32_t iSeg = 0; iSeg < pSgBuf->cSegs; iSeg++)
+        {
+            void   *pvSeg  = pSgBuf->paSegs[iSeg].pvSeg;
+            size_t  cbSeg  = pSgBuf->paSegs[iSeg].cbSeg;
+
+            cbReadSeg = 0;
+            if (off < 0)
+                rc = RTFileRead(pThis->hFile, pvSeg, cbSeg, pcbReadSeg);
+            else
+            {
+                rc = RTFileReadAt(pThis->hFile, off, pvSeg, cbSeg, pcbReadSeg);
+                off += cbSeg;
+            }
+            if (RT_FAILURE(rc))
+                break;
+            if (pcbRead)
+            {
+                cbRead += cbReadSeg;
+                if (cbReadSeg != cbSeg)
+                    break;
+            }
+        }
+
+        if (pcbRead)
+            *pcbRead = cbRead;
+    }
+
+    return rc;
+}
+
+
+/**
+ * @interface_method_impl{RTVFSIOSTREAMOPS,pfnWrite}
+ */
+static DECLCALLBACK(int) rtVfsStdFile_Write(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten)
+{
+    PRTVFSSTDFILE pThis = (PRTVFSSTDFILE)pvThis;
+    int           rc;
+
+    NOREF(fBlocking);
+    if (pSgBuf->cSegs == 1)
+    {
+        if (off < 0)
+            rc = RTFileWrite(pThis->hFile, pSgBuf->paSegs[0].pvSeg, pSgBuf->paSegs[0].cbSeg, pcbWritten);
+        else
+            rc = RTFileWriteAt(pThis->hFile, off, pSgBuf->paSegs[0].pvSeg, pSgBuf->paSegs[0].cbSeg, pcbWritten);
+    }
+    else
+    {
+        size_t  cbWritten     = 0;
+        size_t  cbWrittenSeg;
+        size_t *pcbWrittenSeg = pcbWritten ? &cbWrittenSeg : NULL;
+
+        for (uint32_t iSeg = 0; iSeg < pSgBuf->cSegs; iSeg++)
+        {
+            void   *pvSeg  = pSgBuf->paSegs[iSeg].pvSeg;
+            size_t  cbSeg  = pSgBuf->paSegs[iSeg].cbSeg;
+
+            cbWrittenSeg = 0;
+            if (off < 0)
+                rc = RTFileWrite(pThis->hFile, pvSeg, cbSeg, pcbWrittenSeg);
+            else
+            {
+                rc = RTFileWriteAt(pThis->hFile, off, pvSeg, cbSeg, pcbWrittenSeg);
+                off += cbSeg;
+            }
+            if (RT_FAILURE(rc))
+                break;
+            if (pcbWritten)
+            {
+                cbWritten += cbWrittenSeg;
+                if (cbWrittenSeg != cbSeg)
+                    break;
+            }
+        }
+
+        if (pcbWritten)
+            *pcbWritten = cbWritten;
+    }
+
+    return rc;
+}
+
+
+/**
+ * @interface_method_impl{RTVFSIOSTREAMOPS,pfnFlush}
+ */
+static DECLCALLBACK(int) rtVfsStdFile_Flush(void *pvThis)
+{
+    PRTVFSSTDFILE pThis = (PRTVFSSTDFILE)pvThis;
+    return RTFileFlush(pThis->hFile);
+}
+
+
+/**
+ * @interface_method_impl{RTVFSIOSTREAMOPS,pfnPollOne}
+ */
+static DECLCALLBACK(int) rtVfsStdFile_PollOne(void *pvThis, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr,
+                                              uint32_t *pfRetEvents)
+{
+    PRTVFSSTDFILE pThis = (PRTVFSSTDFILE)pvThis;
+    int           rc;
+
+    if (fEvents != RTPOLL_EVT_ERROR)
+    {
+        *pfRetEvents = fEvents & ~RTPOLL_EVT_ERROR;
+        rc = VINF_SUCCESS;
+    }
+    else if (fIntr)
+        rc = RTThreadSleep(cMillies);
+    else
+    {
+        uint64_t uMsStart = RTTimeMilliTS();
+        do
+            rc = RTThreadSleep(cMillies);
+        while (   rc == VERR_INTERRUPTED
+               && !fIntr
+               && RTTimeMilliTS() - uMsStart < cMillies);
+        if (rc == VERR_INTERRUPTED)
+            rc = VERR_TIMEOUT;
+    }
+    return rc;
+}
+
+
+/**
+ * @interface_method_impl{RTVFSIOSTREAMOPS,pfnTell}
+ */
+static DECLCALLBACK(int) rtVfsStdFile_Tell(void *pvThis, PRTFOFF poffActual)
+{
+    PRTVFSSTDFILE pThis = (PRTVFSSTDFILE)pvThis;
+    return RTFileTell(pThis->hFile);
+}
+
+
+/**
+ * @interface_method_impl{RTVFSOBJSETOPS,pfnMode}
+ */
+static DECLCALLBACK(int) rtVfsStdFile_SetMode(void *pvThis, RTFMODE fMode, RTFMODE fMask)
+{
+    PRTVFSSTDFILE pThis = (PRTVFSSTDFILE)pvThis;
+    if (fMask != ~RTFS_TYPE_MASK)
+    {
+#if 0
+        RTFMODE fCurMode;
+        int rc = RTFileGetMode(pThis->hFile, &fCurMode);
+        if (RT_FAILURE(rc))
+            return rc;
+        fMode |= ~fMask & fCurMode;
+#else
+        RTFSOBJINFO ObjInfo;
+        int rc = RTFileQueryInfo(pThis->hFile, &ObjInfo, RTFSOBJATTRADD_NOTHING);
+        if (RT_FAILURE(rc))
+            return rc;
+        fMode |= ~fMask & ObjInfo.Attr.fMode;
+#endif
+    }
+    return RTFileSetMode(pThis->hFile, fMode);
+}
+
+
+/**
+ * @interface_method_impl{RTVFSOBJSETOPS,pfnSetTimes}
+ */
+static DECLCALLBACK(int) rtVfsStdFile_SetTimes(void *pvThis, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
+                                               PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime)
+{
+    PRTVFSSTDFILE pThis = (PRTVFSSTDFILE)pvThis;
+    return RTFileSetTimes(pThis->hFile, pAccessTime, pModificationTime, pChangeTime, pBirthTime);
+}
+
+
+/**
+ * @interface_method_impl{RTVFSOBJSETOPS,pfnSetOwner}
+ */
+static DECLCALLBACK(int) rtVfsStdFile_SetOwner(void *pvThis, RTUID uid, RTGID gid)
+{
+    PRTVFSSTDFILE pThis = (PRTVFSSTDFILE)pvThis;
+#if 0
+    return RTFileSetOwner(pThis->hFile, uid, gid);
+#else
+    return VERR_NOT_IMPLEMENTED;
+#endif
+}
+
+
+/**
+ * @interface_method_impl{RTVFSFILEOPS,pfnSeek}
+ */
+static DECLCALLBACK(int) rtVfsStdFile_Seek(void *pvThis, RTFOFF offSeek, unsigned uMethod, PRTFOFF poffActual)
+{
+    PRTVFSSTDFILE pThis     = (PRTVFSSTDFILE)pvThis;
+    uint64_t      offActual = 0;
+    int rc = RTFileSeek(pThis->hFile, offSeek, uMethod, &offActual);
+    if (RT_SUCCESS(rc))
+        *poffActual = offActual;
+    return rc;
+}
+
+
+/**
+ * @interface_method_impl{RTVFSFILEOPS,pfnQuerySize}
+ */
+static DECLCALLBACK(int) rtVfsStdFile_QuerySize(void *pvThis, uint64_t *pcbFile)
+{
+    PRTVFSSTDFILE pThis = (PRTVFSSTDFILE)pvThis;
+    return RTFileGetSize(pThis->hFile, pcbFile);
+}
+
+
+/**
+ * Standard file operations.
+ */
+DECLHIDDEN(const RTVFSFILEOPS) g_rtVfsStdFileOps =
+{
+    { /* Stream */
+        /** The basic object operation.  */
+        { /* Obj */
+            RTVFSOBJOPS_VERSION,
+            RTVFSOBJTYPE_FILE,
+            "StdFile",
+            rtVfsStdFile_Close,
+            rtVfsStdFile_QueryInfo,
+            RTVFSOBJOPS_VERSION
+        },
+        RTVFSIOSTREAMOPS_VERSION,
+        0,
+        rtVfsStdFile_Read,
+        rtVfsStdFile_Write,
+        rtVfsStdFile_Flush,
+        rtVfsStdFile_PollOne,
+        rtVfsStdFile_Tell,
+        RTVFSIOSTREAMOPS_VERSION,
+    },
+    RTVFSFILEOPS_VERSION,
+    0,
+    { /* ObjSet */
+        RTVFSOBJSETOPS_VERSION,
+        RT_OFFSETOF(RTVFSFILEOPS, Stream.Obj) - RT_OFFSETOF(RTVFSFILEOPS, ObjSet),
+        rtVfsStdFile_SetMode,
+        rtVfsStdFile_SetTimes,
+        rtVfsStdFile_SetOwner,
+        RTVFSOBJSETOPS_VERSION
+    },
+    rtVfsStdFile_Seek,
+    rtVfsStdFile_QuerySize,
+    RTVFSFILEOPS_VERSION
+};
+
+
+RTDECL(int) RTVfsFileFromRTFile(RTFILE hFile, uint32_t fOpen, bool fLeaveOpen, PRTVFSFILE phVfsFile)
+{
+    /*
+     * Check the handle validity.
+     */
+    RTFSOBJINFO ObjInfo;
+    int rc = RTFileQueryInfo(hFile, &ObjInfo, RTFSOBJATTRADD_NOTHING);
+    if (RT_FAILURE(rc))
+        return rc;
+
+    /*
+     * Set up some fake fOpen flags.
+     */
+    if (!fOpen)
+        fOpen = RTFILE_O_READWRITE | RTFILE_O_DENY_NONE | RTFILE_O_OPEN_CREATE;
+
+    /*
+     * Create the handle.
+     */
+    PRTVFSSTDFILE   pThis;
+    RTVFSFILE       hVfsFile;
+    rc = RTVfsNewFile(&g_rtVfsStdFileOps, sizeof(RTVFSSTDFILE), fOpen, NIL_RTVFS, &hVfsFile, (void **)&pThis);
+    if (RT_FAILURE(rc))
+        return rc;
+
+    pThis->hFile        = hFile;
+    pThis->fLeaveOpen   = fLeaveOpen;
+    *phVfsFile = hVfsFile;
+    return VINF_SUCCESS;
+}
+
