Index: trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp
===================================================================
--- trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp	(revision 59524)
+++ trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp	(revision 59620)
@@ -2135,5 +2135,5 @@
 
 
-RTDECL(int) RTVfsIoStrmSgRead(RTVFSIOSTREAM hVfsIos, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead)
+RTDECL(int) RTVfsIoStrmSgRead(RTVFSIOSTREAM hVfsIos, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead)
 {
     AssertPtrNullReturn(pcbRead, VERR_INVALID_POINTER);
@@ -2150,5 +2150,5 @@
     int rc;
     if (!(pThis->pOps->fFeatures & RTVFSIOSTREAMOPS_FEAT_NO_SG))
-        rc = pThis->pOps->pfnRead(pThis->Base.pvThis, -1 /*off*/, pSgBuf, fBlocking, pcbRead);
+        rc = pThis->pOps->pfnRead(pThis->Base.pvThis, off, pSgBuf, fBlocking, pcbRead);
     else
     {
@@ -2162,5 +2162,5 @@
 
             size_t cbReadSeg = pcbRead ? 0 : pSgBuf->paSegs[iSeg].cbSeg;
-            rc = pThis->pOps->pfnRead(pThis->Base.pvThis, -1 /*off*/, &SgBuf, fBlocking, pcbRead ? &cbReadSeg : NULL);
+            rc = pThis->pOps->pfnRead(pThis->Base.pvThis, off, &SgBuf, fBlocking, pcbRead ? &cbReadSeg : NULL);
             if (RT_FAILURE(rc))
                 break;
@@ -2168,4 +2168,6 @@
             if ((pcbRead && cbReadSeg != SgBuf.paSegs[0].cbSeg) || rc != VINF_SUCCESS)
                 break;
+            if (off != -1)
+                off += cbReadSeg;
         }
 
@@ -2178,5 +2180,5 @@
 
 
-RTDECL(int) RTVfsIoStrmSgWrite(RTVFSIOSTREAM hVfsIos, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten)
+RTDECL(int) RTVfsIoStrmSgWrite(RTVFSIOSTREAM hVfsIos, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten)
 {
     AssertPtrNullReturn(pcbWritten, VERR_INVALID_POINTER);
@@ -2193,5 +2195,5 @@
     int rc;
     if (!(pThis->pOps->fFeatures & RTVFSIOSTREAMOPS_FEAT_NO_SG))
-        rc = pThis->pOps->pfnWrite(pThis->Base.pvThis, -1 /*off*/, pSgBuf, fBlocking, pcbWritten);
+        rc = pThis->pOps->pfnWrite(pThis->Base.pvThis, off, pSgBuf, fBlocking, pcbWritten);
     else
     {
@@ -2205,5 +2207,5 @@
 
             size_t cbWrittenSeg = 0;
-            rc = pThis->pOps->pfnWrite(pThis->Base.pvThis, -1 /*off*/, &SgBuf, fBlocking, pcbWritten ? &cbWrittenSeg : NULL);
+            rc = pThis->pOps->pfnWrite(pThis->Base.pvThis, off, &SgBuf, fBlocking, pcbWritten ? &cbWrittenSeg : NULL);
             if (RT_FAILURE(rc))
                 break;
@@ -2213,5 +2215,9 @@
                 if (cbWrittenSeg != SgBuf.paSegs[0].cbSeg)
                     break;
+                if (off != -1)
+                    off += cbWrittenSeg;
             }
+            else if (off != -1)
+                off += pSgBuf->paSegs[iSeg].cbSeg;
         }
 
Index: trunk/src/VBox/Runtime/common/vfs/vfsiosmisc.cpp
===================================================================
--- trunk/src/VBox/Runtime/common/vfs/vfsiosmisc.cpp	(revision 59524)
+++ trunk/src/VBox/Runtime/common/vfs/vfsiosmisc.cpp	(revision 59620)
@@ -33,4 +33,5 @@
 
 #include <iprt/err.h>
+#include <iprt/mem.h>
 #include <iprt/string.h>
 
@@ -124,2 +125,103 @@
 }
 
+
+/** Header size.  */
+#define READ_ALL_HEADER_SIZE    0x20
+/** The header magic. It's followed by the size (both size_t). */
+#define READ_ALL_HEADER_MAGIC   UINT32_C(0x11223355)
+
+RTDECL(int) RTVfsIoStrmReadAll(RTVFSIOSTREAM hVfsIos, void **ppvBuf, size_t *pcbBuf)
+{
+    /*
+     * Try query the object information and in case the stream has a known
+     * size we could use for guidance.
+     */
+    RTFSOBJINFO ObjInfo;
+    int    rc = RTVfsIoStrmQueryInfo(hVfsIos, &ObjInfo, RTFSOBJATTRADD_NOTHING);
+    size_t cbAllocated = RT_SUCCESS(rc) && ObjInfo.cbObject > 0 && ObjInfo.cbObject < _1G
+                       ? (size_t)ObjInfo.cbObject + 1 : _16K;
+    cbAllocated += READ_ALL_HEADER_SIZE;
+    void *pvBuf = RTMemAlloc(cbAllocated);
+    if (pvBuf)
+    {
+        memset(pvBuf, 0xfe, READ_ALL_HEADER_SIZE);
+        size_t off = 0;
+        for (;;)
+        {
+            /*
+             * Handle buffer growing and detecting the end of it all.
+             */
+            size_t cbToRead = cbAllocated - off - READ_ALL_HEADER_SIZE - 1;
+            if (!cbToRead)
+            {
+                /* The end? */
+                uint8_t bIgn;
+                size_t cbIgn;
+                rc = RTVfsIoStrmRead(hVfsIos, &bIgn, 0, true /*fBlocking*/, &cbIgn);
+                if (rc == VINF_EOF)
+                    break;
+
+                /* Grow the buffer. */
+                cbAllocated -= READ_ALL_HEADER_SIZE - 1;
+                cbAllocated  = RT_MAX(RT_MIN(cbAllocated, _32M), _1K);
+                cbAllocated  = RT_ALIGN_Z(cbAllocated, _4K);
+                cbAllocated += READ_ALL_HEADER_SIZE + 1;
+
+                void *pvNew = RTMemRealloc(pvBuf, cbAllocated);
+                AssertBreakStmt(pvNew, rc = VERR_NO_MEMORY);
+
+                cbToRead = cbAllocated - off - READ_ALL_HEADER_SIZE - 1;
+            }
+            Assert(cbToRead < cbAllocated);
+
+            /*
+             * Read.
+             */
+            size_t cbActual;
+            rc = RTVfsIoStrmRead(hVfsIos, (uint8_t *)pvBuf + READ_ALL_HEADER_SIZE + off, cbToRead,
+                                 true /*fBlocking*/, &cbActual);
+            if (RT_FAILURE(rc))
+                break;
+            Assert(cbActual > 0);
+            Assert(cbActual <= cbToRead);
+            off += cbActual;
+            if (rc == VINF_EOF)
+                break;
+        }
+        Assert(rc != VERR_EOF);
+        if (RT_SUCCESS(rc))
+        {
+            ((size_t *)pvBuf)[0] = READ_ALL_HEADER_MAGIC;
+            ((size_t *)pvBuf)[1] = off;
+            ((uint8_t *)pvBuf)[READ_ALL_HEADER_SIZE + off] = 0;
+
+            *ppvBuf = (uint8_t *)pvBuf + READ_ALL_HEADER_SIZE;
+            *pcbBuf = off;
+            return VINF_SUCCESS;
+        }
+
+        RTMemFree(pvBuf);
+    }
+    else
+        rc = VERR_NO_MEMORY;
+    *ppvBuf = NULL;
+    *pcbBuf = 0;
+    return rc;
+}
+
+
+RTDECL(void) RTVfsIoStrmReadAllFree(void *pvBuf, size_t cbBuf)
+{
+    AssertPtrReturnVoid(pvBuf);
+
+    /* Spool back to the start of the header. */
+    pvBuf = (uint8_t *)pvBuf - READ_ALL_HEADER_SIZE;
+
+    /* Make sure the caller isn't messing with us. Hardcoded, but works. */
+    Assert(((size_t *)pvBuf)[0] == READ_ALL_HEADER_MAGIC);
+    Assert(((size_t *)pvBuf)[1] == cbBuf);
+
+    /* Free it. */
+    RTMemFree(pvBuf);
+}
+
Index: trunk/src/VBox/Runtime/common/vfs/vfsmemory.cpp
===================================================================
--- trunk/src/VBox/Runtime/common/vfs/vfsmemory.cpp	(revision 59524)
+++ trunk/src/VBox/Runtime/common/vfs/vfsmemory.cpp	(revision 59620)
@@ -805,5 +805,5 @@
 
 
-RTDECL(int) RTVfsFileFromBuffer(RTVFSIOSTREAM hVfsIos, uint32_t fFlags, void const *pvBuf, size_t cbBuf, PRTVFSFILE phVfsFile)
+RTDECL(int) RTVfsFileFromBuffer(uint32_t fFlags, void const *pvBuf, size_t cbBuf, PRTVFSFILE phVfsFile)
 {
     /*
@@ -832,4 +832,17 @@
             return VINF_SUCCESS;
         }
+        RTVfsFileRelease(hVfsFile);
+    }
+    return rc;
+}
+
+
+RTDECL(int) RTVfsIoStrmFromBuffer(uint32_t fFlags, void const *pvBuf, size_t cbBuf, PRTVFSIOSTREAM phVfsIos)
+{
+    RTVFSFILE hVfsFile;
+    int rc = RTVfsFileFromBuffer(fFlags, pvBuf, cbBuf, &hVfsFile);
+    if (RT_SUCCESS(rc))
+    {
+        *phVfsIos = RTVfsFileToIoStream(hVfsFile);
         RTVfsFileRelease(hVfsFile);
     }
Index: trunk/src/VBox/Runtime/common/vfs/vfsstdfile.cpp
===================================================================
--- trunk/src/VBox/Runtime/common/vfs/vfsstdfile.cpp	(revision 59524)
+++ trunk/src/VBox/Runtime/common/vfs/vfsstdfile.cpp	(revision 59620)
@@ -502,6 +502,9 @@
     int rc = RTVfsFileOpenNormal(pszFilename, fOpen, &hVfsFile);
     if (RT_SUCCESS(rc))
+    {
         *phVfsIos = RTVfsFileToIoStream(hVfsFile);
-    return rc;
-}
-
+        RTVfsFileRelease(hVfsFile);
+    }
+    return rc;
+}
+
