Index: /trunk/include/iprt/vfs.h
===================================================================
--- /trunk/include/iprt/vfs.h	(revision 33821)
+++ /trunk/include/iprt/vfs.h	(revision 33822)
@@ -40,4 +40,18 @@
 /** @defgroup grp_rt_fs    RTVfs - Virtual Filesystem
  * @ingroup grp_rt
+ *
+ * The virtual filesystem APIs are intended to make it possible to work on
+ * container files, file system sub-trees, file system overlays and other custom
+ * filesystem configurations.  It also makes it possible to create filters, like
+ * automatically gunzipping a tar.gz file before feeding it to the RTTar API for
+ * unpacking - or wise versa.
+ *
+ * The virtual filesystem APIs are intended to mirror the RTDir, RTFile, RTPath
+ * and RTFs APIs pretty closely so that rewriting a piece of code to work with
+ * it should be easy.  However there are some differences to the way the APIs
+ * works and the user should heed the documentation.  The differences are
+ * usually motivated by simplification and in some case to make the VFS more
+ * flexible.
+ *
  * @{
  */
@@ -115,15 +129,138 @@
  * @{
  */
+
+/**
+ * Retains a reference to the VFS I/O stream handle.
+ *
+ * @returns New reference count on success, UINT32_MAX on failure.
+ * @param   hVfsIos         The VFS I/O stream handle.
+ */
 RTDECL(uint32_t)    RTVfsIoStrmRetain(RTVFSIOSTREAM hVfsIos);
+
+/**
+ * Releases a reference to the VFS I/O stream handle.
+ *
+ * @returns New reference count on success (0 if closed), UINT32_MAX on failure.
+ * @param   hVfsIos         The VFS I/O stream handle.
+ */
 RTDECL(uint32_t)    RTVfsIoStrmRelease(RTVFSIOSTREAM hVfsIos);
+
+/**
+ * Convert the VFS I/O stream handle to a VFS file handle.
+ *
+ * @returns The VFS file handle on success, this must be released.
+ *          NIL_RTVFSFILE if the I/O stream handle is invalid.
+ * @param   hVfsIos         The VFS I/O stream handle.
+ * @sa      RTVfsFileToIoStream
+ */
 RTDECL(RTVFSFILE)   RTVfsIoStrmToFile(RTVFSIOSTREAM hVfsIos);
+
+/**
+ * Query information about the I/O stream.
+ *
+ * @returns IPRT status code.
+ * @param   hVfsIos         The VFS I/O stream handle.
+ * @param   pObjInfo        Where to return the info.
+ * @param   enmAddAttr      Which additional attributes should be retrieved.
+ * @sa      RTFileQueryInfo
+ */
 RTDECL(int)         RTVfsIoStrmQueryInfo(RTVFSIOSTREAM hVfsIos, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr);
+
+/**
+ * Read bytes from the I/O stream.
+ *
+ * @returns IPRT status code.
+ * @param   hVfsIos         The VFS I/O stream handle.
+ * @param   pvBuf           Where to store the read bytes.
+ * @param   cbToRead        The number of bytes to read.
+ * @param   pcbRead         Where to store the number of bytes actually read.
+ *                          If this is NULL, the call will block until @a
+ *                          cbToRead bytes are available.  If this is non-NULL,
+ *                          the call will not block and return what is currently
+ *                          avaiable.
+ * @sa      RTFileRead, RTPipeRead, RTPipeReadBlocking, RTSocketRead
+ */
 RTDECL(int)         RTVfsIoStrmRead(RTVFSIOSTREAM hVfsIos, void *pvBuf, size_t cbToRead, size_t *pcbRead);
+
+/**
+ * Write bytes to the I/O stream.
+ *
+ * @returns IPRT status code.
+ * @param   hVfsIos         The VFS I/O stream handle.
+ * @param   pvBuf           The bytes to write.
+ * @param   cbToWrite       The number of bytes to write.
+ * @param   pcbWritten      Where to store the number of bytes actually written.
+ *                          If this is NULL, the call will block until @a
+ *                          cbToWrite bytes are available.  If this is non-NULL,
+ *                          the call will not block and return after writing
+ *                          what is possible.
+ * @sa      RTFileWrite, RTPipeWrite, RTPipeWriteBlocking, RTSocketWrite
+ */
 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);
+
+/**
+ * Reads bytes from the I/O stream into a scatter buffer.
+ *
+ * @returns IPRT status code.
+ * @param   hVfsIos         The VFS I/O stream handle.
+ * @param   pSgBuf          Pointer to a scatter buffer descriptor.  The number
+ *                          of bytes described by the segments is what will be
+ *                          attemted read.
+ * @param   fBlocking       Whether the call is blocking (@c true) or not.  If
+ *                          not, the @a pcbRead parameter must not be NULL.
+ * @param   pcbRead         Where to store the number of bytes actually read.
+ *                          This can be NULL if @a fBlocking is true.
+ * @sa      RTFileSgRead, RTSocketSgRead
+ */
+RTDECL(int)         RTVfsIoStrmSgRead(RTVFSIOSTREAM hVfsIos, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead);
+
+/**
+ * Write bytes to the I/O stream from a gather buffer.
+ *
+ * @returns IPRT status code.
+ * @param   hVfsIos         The VFS I/O stream handle.
+ * @param   pSgBuf          Pointer to a gather buffer descriptor.  The number
+ *                          of bytes described by the segments is what will be
+ *                          attemted written.
+ * @param   fBlocking       Whether the call is blocking (@c true) or not.  If
+ *                          not, the @a pcbWritten parameter must not be NULL.
+ * @param   pcbRead         Where to store the number of bytes actually written.
+ *                          This can be NULL if @a fBlocking is true.
+ * @sa      RTFileSgWrite, RTSocketSgWrite
+ */
+RTDECL(int)         RTVfsIoStrmSgWrite(RTVFSIOSTREAM hVfsIos, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten);
+
+/**
+ * Flush any buffered data to the I/O stream.
+ *
+ * @returns IPRT status code.
+ * @param   hVfsIos         The VFS I/O stream handle.
+ * @sa      RTFileFlush, RTPipeFlush
+ */
 RTDECL(int)         RTVfsIoStrmFlush(RTVFSIOSTREAM hVfsIos);
+
+/**
+ * Poll for events.
+ *
+ * @returns IPRT status code.
+ * @param   hVfsIos         The VFS I/O stream handle.
+ * @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.
+ */
 RTDECL(RTFOFF)      RTVfsIoStrmPoll(RTVFSIOSTREAM hVfsIos, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr,
                                     uint32_t *pfRetEvents);
+/**
+ * Tells the current I/O stream position.
+ *
+ * @returns Zero or higher - where to return the I/O stream offset.  Values
+ *          below zero are IPRT status codes (VERR_XXX).
+ * @param   hVfsIos         The VFS I/O stream handle.
+ * @sa      RTFileTell
+ */
 RTDECL(RTFOFF)      RTVfsIoStrmTell(RTVFSIOSTREAM hVfsIos);
 /** @} */
@@ -155,4 +292,5 @@
  *          NIL_RTVFSIOSTREAM if the file handle is invalid.
  * @param   hVfsFile        The VFS file handle.
+ * @sa      RTVfsIoStrmToFile
  */
 RTDECL(RTVFSIOSTREAM) RTVfsFileToIoStream(RTVFSFILE hVfsFile);
Index: /trunk/include/iprt/vfslowlevel.h
===================================================================
--- /trunk/include/iprt/vfslowlevel.h	(revision 33821)
+++ /trunk/include/iprt/vfslowlevel.h	(revision 33822)
@@ -428,5 +428,5 @@
      * @param   pvThis      The implementation specific file data.
      * @param   poffActual  Where to return the actual offset.
-     * @sa      RTFileSeek
+     * @sa      RTFileTell
      */
     DECLCALLBACKMEMBER(int, pfnTell)(void *pvThis, PRTFOFF poffActual);
Index: /trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp	(revision 33821)
+++ /trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp	(revision 33822)
@@ -184,4 +184,172 @@
 
 
+RTDECL(uint32_t)    RTVfsIoStrmRetain(RTVFSIOSTREAM hVfsIos)
+{
+    RTVFSIOSTREAMINTERNAL *pThis = hVfsIos;
+    AssertPtrReturn(pThis, UINT32_MAX);
+    AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, UINT32_MAX);
+    return rtVfsRetain(&pThis->cRefs);
+}
+
+
+RTDECL(uint32_t)    RTVfsIoStrmRelease(RTVFSIOSTREAM hVfsIos)
+{
+    RTVFSIOSTREAMINTERNAL *pThis = hVfsIos;
+    AssertPtrReturn(pThis, UINT32_MAX);
+    AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, UINT32_MAX);
+
+    uint32_t cRefs = rtVfsRelease(&pThis->cRefs);
+    if (!cRefs)
+    {
+        /*
+         * That was the last reference, close the stream.
+         *
+         * This is a little bit more complicated than when releasing a file or
+         * directory handle because the I/O stream can be a sub-object and we
+         * need to get to the real one before handing it to RTMemFree.
+         */
+        ASMAtomicWriteU32(&pThis->uMagic, RTVFSIOSTREAM_MAGIC_DEAD);
+        pThis->pOps->Obj.pfnClose(pThis->pvThis);
+
+        switch (pThis->pOps->Obj.enmType)
+        {
+            case RTVFSOBJTYPE_IOSTREAM:
+                RTMemFree(pThis);
+                break;
+
+            case RTVFSOBJTYPE_FILE:
+            {
+                RTVFSFILEINTERNAL *pThisFile = RT_FROM_MEMBER(pThis, RTVFSFILEINTERNAL, Stream);
+                ASMAtomicWriteU32(&pThisFile->uMagic, RTVFSIOSTREAM_MAGIC_DEAD);
+                RTMemFree(pThisFile);
+                break;
+            }
+
+            /* Add new I/O stream compatible handle types here. */
+
+            default:
+                AssertMsgFailed(("%d\n", pThis->pOps->Obj.enmType));
+                break;
+        }
+    }
+
+    return cRefs;
+
+}
+
+
+RTDECL(RTVFSFILE)   RTVfsIoStrmToFile(RTVFSIOSTREAM hVfsIos)
+{
+    RTVFSIOSTREAMINTERNAL *pThis = hVfsIos;
+    AssertPtrReturn(pThis, NIL_RTVFSFILE);
+    AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, NIL_RTVFSFILE);
+
+    if (pThis->pOps->Obj.enmType == RTVFSOBJTYPE_FILE)
+    {
+        rtVfsRetainVoid(&pThis->cRefs);
+        return RT_FROM_MEMBER(pThis, RTVFSFILEINTERNAL, Stream);
+    }
+
+    /* this is no crime, so don't assert. */
+    return NIL_RTVFSFILE;
+}
+
+
+RTDECL(int)         RTVfsIoStrmQueryInfo(RTVFSIOSTREAM hVfsIos, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
+{
+    RTVFSIOSTREAMINTERNAL *pThis = hVfsIos;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, VERR_INVALID_HANDLE);
+
+    return pThis->pOps->Obj.pfnQueryInfo(pThis->pvThis, pObjInfo, enmAddAttr);
+}
+
+
+RTDECL(int)         RTVfsIoStrmRead(RTVFSIOSTREAM hVfsIos, void *pvBuf, size_t cbToRead, size_t *pcbRead)
+{
+    RTVFSIOSTREAMINTERNAL *pThis = hVfsIos;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, VERR_INVALID_HANDLE);
+
+    RTSGSEG Seg = { pvBuf, cbToRead };
+    RTSGBUF SgBuf;
+    RTSgBufInit(&SgBuf, &Seg, 1);
+    return pThis->pOps->pfnRead(pThis->pvThis, -1 /*off*/, &SgBuf, pcbRead == NULL /*fBlocking*/, pcbRead);
+}
+
+
+RTDECL(int)         RTVfsIoStrmWrite(RTVFSIOSTREAM hVfsIos, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten)
+{
+    RTVFSIOSTREAMINTERNAL *pThis = hVfsIos;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, VERR_INVALID_HANDLE);
+
+    RTSGSEG Seg = { (void *)pvBuf, cbToWrite };
+    RTSGBUF SgBuf;
+    RTSgBufInit(&SgBuf, &Seg, 1);
+    return pThis->pOps->pfnWrite(pThis->pvThis, -1 /*off*/, &SgBuf, pcbWritten == NULL /*fBlocking*/, pcbWritten);
+}
+
+
+RTDECL(int)         RTVfsIoStrmSgRead(RTVFSIOSTREAM hVfsIos, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead)
+{
+    RTVFSIOSTREAMINTERNAL *pThis = hVfsIos;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, VERR_INVALID_HANDLE);
+    AssertPtr(pSgBuf);
+    AssertReturn(fBlocking || VALID_PTR(pcbRead), VERR_INVALID_PARAMETER);
+
+    return pThis->pOps->pfnRead(pThis->pvThis, -1 /*off*/, pSgBuf, fBlocking, pcbRead);
+}
+
+
+RTDECL(int)         RTVfsIoStrmSgWrite(RTVFSIOSTREAM hVfsIos, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten)
+{
+    RTVFSIOSTREAMINTERNAL *pThis = hVfsIos;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, VERR_INVALID_HANDLE);
+    AssertPtr(pSgBuf);
+    AssertReturn(fBlocking || VALID_PTR(pcbWritten), VERR_INVALID_PARAMETER);
+
+    return pThis->pOps->pfnWrite(pThis->pvThis, -1 /*off*/, pSgBuf, fBlocking, pcbWritten);
+}
+
+
+RTDECL(int)         RTVfsIoStrmFlush(RTVFSIOSTREAM hVfsIos)
+{
+    RTVFSIOSTREAMINTERNAL *pThis = hVfsIos;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, VERR_INVALID_HANDLE);
+
+    return pThis->pOps->pfnFlush(pThis->pvThis);
+}
+
+
+RTDECL(RTFOFF)      RTVfsIoStrmPoll(RTVFSIOSTREAM hVfsIos, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr,
+                                    uint32_t *pfRetEvents)
+{
+    RTVFSIOSTREAMINTERNAL *pThis = hVfsIos;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, VERR_INVALID_HANDLE);
+
+    return pThis->pOps->pfnPollOne(pThis->pvThis, fEvents, cMillies, fIntr, pfRetEvents);
+}
+
+
+RTDECL(RTFOFF)      RTVfsIoStrmTell(RTVFSIOSTREAM hVfsIos)
+{
+    RTVFSIOSTREAMINTERNAL *pThis = hVfsIos;
+    AssertPtrReturn(pThis, -1);
+    AssertReturn(pThis->uMagic == RTVFSIOSTREAM_MAGIC, -1);
+
+    RTFOFF off;
+    int rc = pThis->pOps->pfnTell(pThis->pvThis, &off);
+    if (RT_FAILURE(rc))
+        off = rc;
+    return off;
+}
+
+
+
 RTDECL(int) RTVfsNewFile(PCRTVFSFILEOPS pFileOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs,
                          PRTVFSFILE phVfsFile, void **ppvInstance)
