Index: /trunk/include/iprt/mangling.h
===================================================================
--- /trunk/include/iprt/mangling.h	(revision 84191)
+++ /trunk/include/iprt/mangling.h	(revision 84192)
@@ -2808,4 +2808,5 @@
 # define RTVfsObjToFsStream                             RT_MANGLER(RTVfsObjToFsStream)
 # define RTVfsObjToIoStream                             RT_MANGLER(RTVfsObjToIoStream)
+# define RTVfsObjToPrivate                              RT_MANGLER(RTVfsObjToPrivate)
 # define RTVfsObjToSymlink                              RT_MANGLER(RTVfsObjToSymlink)
 # define RTVfsObjToVfs                                  RT_MANGLER(RTVfsObjToVfs)
@@ -2828,4 +2829,5 @@
 # define RTVfsSymlinkSetOwner                           RT_MANGLER(RTVfsSymlinkSetOwner)
 # define RTVfsSymlinkSetTimes                           RT_MANGLER(RTVfsSymlinkSetTimes)
+# define RTVfsSymlinkToPrivate                          RT_MANGLER(RTVfsSymlinkToPrivate)
 # define RTVfsUtilDummyPollOne                          RT_MANGLER(RTVfsUtilDummyPollOne)
 # define RTVfsUtilPumpIoStreams                         RT_MANGLER(RTVfsUtilPumpIoStreams)
Index: /trunk/include/iprt/vfslowlevel.h
===================================================================
--- /trunk/include/iprt/vfslowlevel.h	(revision 84191)
+++ /trunk/include/iprt/vfslowlevel.h	(revision 84192)
@@ -311,4 +311,15 @@
                             PRTVFSOBJ phVfsObj, void **ppvInstance);
 
+
+/**
+ * Gets the private data of a base object.
+ *
+ * @returns Pointer to the private data.  NULL if the handle is invalid in some
+ *          way.
+ * @param   hVfsObj             The I/O base object handle.
+ * @param   pObjOps             The base object operations.  This servers as a
+ *                              sort of password.
+ */
+RTDECL(void *) RTVfsObjToPrivate(RTVFSOBJ hVfsObj, PCRTVFSOBJOPS pObjOps);
 
 /**
@@ -493,10 +504,10 @@
  *                              object.  The reference is consumed.  NIL and
  *                              special lock handles are fine.
- * @param   fReadOnly           Set if read-only, clear if write-only.
+ * @param   fAccess             RTFILE_O_READ and/or RTFILE_O_WRITE.
  * @param   phVfsFss            Where to return the new handle.
  * @param   ppvInstance         Where to return the pointer to the instance data
  *                              (size is @a cbInstance).
  */
-RTDECL(int) RTVfsNewFsStream(PCRTVFSFSSTREAMOPS pFsStreamOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock, bool fReadOnly,
+RTDECL(int) RTVfsNewFsStream(PCRTVFSFSSTREAMOPS pFsStreamOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock, uint32_t fAccess,
                              PRTVFSFSSTREAM phVfsFss, void **ppvInstance);
 
@@ -828,4 +839,15 @@
                             PRTVFSSYMLINK phVfsSym, void **ppvInstance);
 
+
+/**
+ * Gets the private data of a symbolic link.
+ *
+ * @returns Pointer to the private data.  NULL if the handle is invalid in some
+ *          way.
+ * @param   hVfsIos             The I/O stream handle.
+ * @param   pSymlinkOps         The symlink operations.  This servers as a sort
+ *                              of password.
+ */
+RTDECL(void *) RTVfsSymlinkToPrivate(RTVFSSYMLINK hVfsSym, PCRTVFSSYMLINKOPS pSymlinkOps);
 
 /**
Index: /trunk/include/iprt/zip.h
===================================================================
--- /trunk/include/iprt/zip.h	(revision 84191)
+++ /trunk/include/iprt/zip.h	(revision 84192)
@@ -324,6 +324,8 @@
  *       twice. */
 #define RTZIPTAR_C_SPARSE           RT_BIT_32(0)
+/** Set if opening for updating. */
+#define RTZIPTAR_C_UPDATE           RT_BIT_32(1)
 /** Valid bits. */
-#define RTZIPTAR_C_VALID_MASK       UINT32_C(0x00000001)
+#define RTZIPTAR_C_VALID_MASK       UINT32_C(0x00000003)
 /** @} */
 
@@ -392,4 +394,26 @@
 RTDECL(int) RTZipTarFsStreamSetMTime(RTVFSFSSTREAM hVfsFss, PCRTTIMESPEC pModificationTime);
 
+/**
+ * Truncates a TAR creator stream in update mode.
+ *
+ * Use RTVfsFsStrmNext to examine the TAR stream and locate the cut-off point.
+ *
+ * After performing this call, the stream will be in write mode and
+ * RTVfsFsStrmNext will stop working (VERR_WRONG_ORDER).   The RTVfsFsStrmAdd()
+ * and RTVfsFsStrmPushFile() can be used to add new object to the TAR file,
+ * starting at the trunction point.  RTVfsFsStrmEnd() is used to finish the TAR
+ * file (this performs the actual file trunction).
+ *
+ * @returns IPRT status code.
+ * @param   hVfsFss             The handle to a TAR creator in update mode.
+ * @param   hVfsObj             Object returned by RTVfsFsStrmNext that the
+ *                              trunction is relative to.  This doesn't have to
+ *                              be the current stream object, it can be an
+ *                              earlier one too.
+ * @param   fAfter              If set, @a hVfsObj will remain in the update TAR
+ *                              file.  If clear, @a hVfsObj will not be
+ *                              included.
+ */
+RTDECL(int) RTZipTarFsStreamTruncate(RTVFSFSSTREAM hVfsFss, RTVFSOBJ hVfsObj, bool fAfter);
 
 /**
Index: /trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp	(revision 84191)
+++ /trunk/src/VBox/Runtime/common/vfs/vfsbase.cpp	(revision 84192)
@@ -813,4 +813,15 @@
     *ppvInstance = pThis->pvThis;
     return VINF_SUCCESS;
+}
+
+
+RTDECL(void *) RTVfsObjToPrivate(RTVFSOBJ hVfsObj, PCRTVFSOBJOPS pObjOps)
+{
+    RTVFSOBJINTERNAL *pThis = hVfsObj;
+    AssertPtrReturn(pThis, NULL);
+    AssertReturn(pThis->uMagic == RTVFSOBJ_MAGIC, NULL);
+    if (pThis->pOps != pObjOps)
+        return NULL;
+    return pThis->pvThis;
 }
 
@@ -2282,5 +2293,5 @@
 
 
-RTDECL(int) RTVfsNewFsStream(PCRTVFSFSSTREAMOPS pFsStreamOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock, bool fReadOnly,
+RTDECL(int) RTVfsNewFsStream(PCRTVFSFSSTREAMOPS pFsStreamOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock, uint32_t fAccess,
                              PRTVFSFSSTREAM phVfsFss, void **ppvInstance)
 {
@@ -2293,7 +2304,9 @@
     Assert(!pFsStreamOps->fReserved);
     RTVFSOBJ_ASSERT_OPS(&pFsStreamOps->Obj, RTVFSOBJTYPE_FS_STREAM);
-    if (fReadOnly)
+    Assert((fAccess & (RTFILE_O_READ | RTFILE_O_WRITE)) == fAccess);
+    Assert(fAccess);
+    if (fAccess & RTFILE_O_READ)
         AssertPtr(pFsStreamOps->pfnNext);
-    else
+    if (fAccess & RTFILE_O_WRITE)
     {
         AssertPtr(pFsStreamOps->pfnAdd);
@@ -2324,8 +2337,12 @@
 
     pThis->uMagic = RTVFSFSSTREAM_MAGIC;
-    pThis->fFlags = fReadOnly
-                  ? RTFILE_O_READ  | RTFILE_O_OPEN   | RTFILE_O_DENY_NONE
-                  : RTFILE_O_WRITE | RTFILE_O_CREATE | RTFILE_O_DENY_ALL;
     pThis->pOps   = pFsStreamOps;
+    pThis->fFlags = fAccess;
+    if (fAccess == RTFILE_O_READ)
+        pThis->fFlags |= RTFILE_O_OPEN   | RTFILE_O_DENY_NONE;
+    else if (fAccess == RTFILE_O_WRITE)
+        pThis->fFlags |= RTFILE_O_CREATE | RTFILE_O_DENY_ALL;
+    else
+        pThis->fFlags |= RTFILE_O_OPEN   | RTFILE_O_DENY_ALL;
 
     *phVfsFss     = pThis;
@@ -3277,4 +3294,15 @@
 
 
+RTDECL(void *) RTVfsSymlinkToPrivate(RTVFSSYMLINK hVfsSym, PCRTVFSSYMLINKOPS pSymlinkOps)
+{
+    RTVFSSYMLINKINTERNAL *pThis = hVfsSym;
+    AssertPtrReturn(pThis, NULL);
+    AssertReturn(pThis->uMagic == RTVFSSYMLINK_MAGIC, NULL);
+    if (pThis->pOps != pSymlinkOps)
+        return NULL;
+    return pThis->Base.pvThis;
+}
+
+
 RTDECL(uint32_t)    RTVfsSymlinkRetain(RTVFSSYMLINK hVfsSym)
 {
Index: /trunk/src/VBox/Runtime/common/vfs/vfsfss2dir.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/vfs/vfsfss2dir.cpp	(revision 84191)
+++ /trunk/src/VBox/Runtime/common/vfs/vfsfss2dir.cpp	(revision 84192)
@@ -311,5 +311,5 @@
     PRTVFSFSSWRITE2DIR      pThis;
     RTVFSFSSTREAM           hVfsFss;
-    int rc = RTVfsNewFsStream(&g_rtVfsFssToDirOps, sizeof(*pThis), NIL_RTVFS, NIL_RTVFSLOCK, false /*fReadOnly*/,
+    int rc = RTVfsNewFsStream(&g_rtVfsFssToDirOps, sizeof(*pThis), NIL_RTVFS, NIL_RTVFSLOCK, RTFILE_O_WRITE,
                               &hVfsFss, (void **)&pThis);
     if (RT_SUCCESS(rc))
@@ -370,5 +370,5 @@
                 RTVFSFSSTREAM           hVfsFss;
                 rc = RTVfsNewFsStream(&g_rtVfsFssToDirOps, RT_UOFFSETOF_DYN(RTVFSFSSWRITE2DIR, szBaseDir[cbBaseDir]),
-                                      NIL_RTVFS, NIL_RTVFSLOCK, false /*fReadOnly*/, &hVfsFss, (void **)&pThis);
+                                      NIL_RTVFS, NIL_RTVFSLOCK, RTFILE_O_WRITE, &hVfsFss, (void **)&pThis);
                 if (RT_SUCCESS(rc))
                 {
Index: /trunk/src/VBox/Runtime/common/zip/pkzipvfs.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/zip/pkzipvfs.cpp	(revision 84191)
+++ /trunk/src/VBox/Runtime/common/zip/pkzipvfs.cpp	(revision 84192)
@@ -1264,5 +1264,5 @@
     PRTZIPPKZIPFSSTREAM pThis;
     RTVFSFSSTREAM     hVfsFss;
-    int rc = RTVfsNewFsStream(&rtZipPkzipFssOps, sizeof(*pThis), NIL_RTVFS, NIL_RTVFSLOCK, true /*fReadOnly*/,
+    int rc = RTVfsNewFsStream(&rtZipPkzipFssOps, sizeof(*pThis), NIL_RTVFS, NIL_RTVFSLOCK, RTFILE_O_READ,
                               &hVfsFss, (void **)&pThis);
     if (RT_SUCCESS(rc))
Index: /trunk/src/VBox/Runtime/common/zip/tarvfs.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/zip/tarvfs.cpp	(revision 84191)
+++ /trunk/src/VBox/Runtime/common/zip/tarvfs.cpp	(revision 84192)
@@ -43,130 +43,5 @@
 
 #include "tar.h"
-
-
-/*********************************************************************************************************************************
-*   Structures and Typedefs                                                                                                      *
-*********************************************************************************************************************************/
-/**
- * TAR reader state machine states.
- */
-typedef enum RTZIPTARREADERSTATE
-{
-    /** Invalid state. */
-    RTZIPTARREADERSTATE_INVALID = 0,
-    /** Expecting the next file/dir/whatever entry. */
-    RTZIPTARREADERSTATE_FIRST,
-    /** Expecting more zero headers or the end of the stream. */
-    RTZIPTARREADERSTATE_ZERO,
-    /** Expecting a GNU long name. */
-    RTZIPTARREADERSTATE_GNU_LONGNAME,
-    /** Expecting a GNU long link. */
-    RTZIPTARREADERSTATE_GNU_LONGLINK,
-    /** Expecting a normal header or another GNU specific one. */
-    RTZIPTARREADERSTATE_GNU_NEXT,
-    /** End of valid states (not included). */
-    RTZIPTARREADERSTATE_END
-} RTZIPTARREADERSTATE;
-
-/**
- * Tar reader instance data.
- */
-typedef struct RTZIPTARREADER
-{
-    /** Zero header counter. */
-    uint32_t                cZeroHdrs;
-    /** The state machine state. */
-    RTZIPTARREADERSTATE     enmState;
-    /** The type of the previous TAR header.
-     * @remarks Same a enmType for the first header in the TAR stream. */
-    RTZIPTARTYPE            enmPrevType;
-    /** The type of the current TAR header. */
-    RTZIPTARTYPE            enmType;
-    /** The current header. */
-    RTZIPTARHDR             Hdr;
-    /** The expected long name/link length (GNU). */
-    uint32_t                cbGnuLongExpect;
-    /** The current long name/link length (GNU). */
-    uint32_t                offGnuLongCur;
-    /** The name of the current object.
-     * This is for handling GNU and PAX long names. */
-    char                    szName[RTPATH_MAX];
-    /** The current link target if symlink or hardlink. */
-    char                    szTarget[RTPATH_MAX];
-} RTZIPTARREADER;
-/** Pointer to the TAR reader instance data. */
-typedef RTZIPTARREADER *PRTZIPTARREADER;
-
-/**
- * Tar directory, character device, block device, fifo socket or symbolic link.
- */
-typedef struct RTZIPTARBASEOBJ
-{
-    /** The stream offset of the (first) header.  */
-    RTFOFF                  offHdr;
-    /** Pointer to the reader instance data (resides in the filesystem
-     * stream).
-     * @todo Fix this so it won't go stale... Back ref from this obj to fss? */
-    PRTZIPTARREADER         pTarReader;
-    /** The object info with unix attributes. */
-    RTFSOBJINFO             ObjInfo;
-} RTZIPTARBASEOBJ;
-/** Pointer to a TAR filesystem stream base object. */
-typedef RTZIPTARBASEOBJ *PRTZIPTARBASEOBJ;
-
-
-/**
- * Tar file represented as a VFS I/O stream.
- */
-typedef struct RTZIPTARIOSTREAM
-{
-    /** The basic TAR object data. */
-    RTZIPTARBASEOBJ         BaseObj;
-    /** The number of bytes in the file. */
-    RTFOFF                  cbFile;
-    /** The current file position. */
-    RTFOFF                  offFile;
-    /** The start position in the hVfsIos (for seekable hVfsIos). */
-    RTFOFF                  offStart;
-    /** The number of padding bytes following the file. */
-    uint32_t                cbPadding;
-    /** Set if we've reached the end of the file. */
-    bool                    fEndOfStream;
-    /** The input I/O stream. */
-    RTVFSIOSTREAM           hVfsIos;
-} RTZIPTARIOSTREAM;
-/** Pointer to a the private data of a TAR file I/O stream. */
-typedef RTZIPTARIOSTREAM *PRTZIPTARIOSTREAM;
-
-
-/**
- * Tar filesystem stream private data.
- */
-typedef struct RTZIPTARFSSTREAM
-{
-    /** The input I/O stream. */
-    RTVFSIOSTREAM           hVfsIos;
-
-    /** The current object (referenced). */
-    RTVFSOBJ                hVfsCurObj;
-    /** Pointer to the private data if hVfsCurObj is representing a file. */
-    PRTZIPTARIOSTREAM       pCurIosData;
-
-    /** The start offset. */
-    RTFOFF                  offStart;
-    /** The offset of the next header. */
-    RTFOFF                  offNextHdr;
-
-    /** Set if we've reached the end of the stream. */
-    bool                    fEndOfStream;
-    /** Set if we've encountered a fatal error. */
-    int                     rcFatal;
-
-    /** The TAR reader instance data. */
-    RTZIPTARREADER          TarReader;
-} RTZIPTARFSSTREAM;
-/** Pointer to a the private data of a TAR filesystem stream. */
-typedef RTZIPTARFSSTREAM *PRTZIPTARFSSTREAM;
-
+#include "tarvfsreader.h"
 
 
@@ -1236,5 +1111,5 @@
  * @interface_method_impl{RTVFSFSSTREAMOPS,pfnNext}
  */
-static DECLCALLBACK(int) rtZipTarFss_Next(void *pvThis, char **ppszName, RTVFSOBJTYPE *penmType, PRTVFSOBJ phVfsObj)
+DECLHIDDEN(DECLCALLBACK(int)) rtZipTarFss_Next(void *pvThis, char **ppszName, RTVFSOBJTYPE *penmType, PRTVFSOBJ phVfsObj)
 {
     PRTZIPTARFSSTREAM pThis = (PRTZIPTARFSSTREAM)pvThis;
@@ -1285,4 +1160,6 @@
     if (offHdr > pThis->offNextHdr)
         return pThis->rcFatal = VERR_INTERNAL_ERROR_3;
+    Assert(pThis->offNextHdr == offHdr);
+    pThis->offCurHdr = offHdr;
 
     /*
@@ -1356,13 +1233,14 @@
                 return pThis->rcFatal = rc;
 
-            pIosData->BaseObj.offHdr    = offHdr;
-            pIosData->BaseObj.pTarReader= &pThis->TarReader;
-            pIosData->BaseObj.ObjInfo   = Info;
-            pIosData->cbFile            = Info.cbObject;
-            pIosData->offFile           = 0;
-            pIosData->offStart          = RTVfsIoStrmTell(pThis->hVfsIos);
-            pIosData->cbPadding         = (uint32_t)(Info.cbAllocated - Info.cbObject);
-            pIosData->fEndOfStream      = false;
-            pIosData->hVfsIos           = pThis->hVfsIos;
+            pIosData->BaseObj.offHdr     = offHdr;
+            pIosData->BaseObj.offNextHdr = pThis->offNextHdr;
+            pIosData->BaseObj.pTarReader = &pThis->TarReader;
+            pIosData->BaseObj.ObjInfo    = Info;
+            pIosData->cbFile             = Info.cbObject;
+            pIosData->offFile            = 0;
+            pIosData->offStart           = RTVfsIoStrmTell(pThis->hVfsIos);
+            pIosData->cbPadding          = (uint32_t)(Info.cbAllocated - Info.cbObject);
+            pIosData->fEndOfStream       = false;
+            pIosData->hVfsIos            = pThis->hVfsIos;
             RTVfsIoStrmRetain(pThis->hVfsIos);
 
@@ -1394,7 +1272,8 @@
                 return pThis->rcFatal = rc;
 
-            pBaseObjData->offHdr    = offHdr;
-            pBaseObjData->pTarReader= &pThis->TarReader;
-            pBaseObjData->ObjInfo   = Info;
+            pBaseObjData->offHdr     = offHdr;
+            pBaseObjData->offNextHdr = pThis->offNextHdr;
+            pBaseObjData->pTarReader = &pThis->TarReader;
+            pBaseObjData->ObjInfo    = Info;
 
             enmType = RTVFSOBJTYPE_SYMLINK;
@@ -1424,7 +1303,8 @@
                 return pThis->rcFatal = rc;
 
-            pBaseObjData->offHdr    = offHdr;
-            pBaseObjData->pTarReader= &pThis->TarReader;
-            pBaseObjData->ObjInfo   = Info;
+            pBaseObjData->offHdr     = offHdr;
+            pBaseObjData->offNextHdr = pThis->offNextHdr;
+            pBaseObjData->pTarReader = &pThis->TarReader;
+            pBaseObjData->ObjInfo    = Info;
 
             enmType = RTVFSOBJTYPE_BASE;
@@ -1485,4 +1365,26 @@
 
 
+/**
+ * Internal function use both by RTZipTarFsStreamFromIoStream() and by
+ * RTZipTarFsStreamForFile() in updating mode.
+ */
+DECLHIDDEN(void) rtZipTarReaderInit(PRTZIPTARFSSTREAM pThis, RTVFSIOSTREAM hVfsIos, uint64_t offStart)
+{
+    pThis->hVfsIos              = hVfsIos;
+    pThis->hVfsCurObj           = NIL_RTVFSOBJ;
+    pThis->pCurIosData          = NULL;
+    pThis->offStart             = offStart;
+    pThis->offNextHdr           = offStart;
+    pThis->fEndOfStream         = false;
+    pThis->rcFatal              = VINF_SUCCESS;
+    pThis->TarReader.enmPrevType= RTZIPTARTYPE_INVALID;
+    pThis->TarReader.enmType    = RTZIPTARTYPE_INVALID;
+    pThis->TarReader.enmState   = RTZIPTARREADERSTATE_FIRST;
+
+    /* Don't check if it's a TAR stream here, do that in the
+       rtZipTarFss_Next. */
+}
+
+
 RTDECL(int) RTZipTarFsStreamFromIoStream(RTVFSIOSTREAM hVfsIosIn, uint32_t fFlags, PRTVFSFSSTREAM phVfsFss)
 {
@@ -1506,22 +1408,9 @@
     PRTZIPTARFSSTREAM pThis;
     RTVFSFSSTREAM     hVfsFss;
-    int rc = RTVfsNewFsStream(&rtZipTarFssOps, sizeof(*pThis), NIL_RTVFS, NIL_RTVFSLOCK, true /*fReadOnly*/,
+    int rc = RTVfsNewFsStream(&rtZipTarFssOps, sizeof(*pThis), NIL_RTVFS, NIL_RTVFSLOCK, RTFILE_O_READ,
                               &hVfsFss, (void **)&pThis);
     if (RT_SUCCESS(rc))
     {
-        pThis->hVfsIos              = hVfsIosIn;
-        pThis->hVfsCurObj           = NIL_RTVFSOBJ;
-        pThis->pCurIosData          = NULL;
-        pThis->offStart             = offStart;
-        pThis->offNextHdr           = offStart;
-        pThis->fEndOfStream         = false;
-        pThis->rcFatal              = VINF_SUCCESS;
-        pThis->TarReader.enmPrevType= RTZIPTARTYPE_INVALID;
-        pThis->TarReader.enmType    = RTZIPTARTYPE_INVALID;
-        pThis->TarReader.enmState   = RTZIPTARREADERSTATE_FIRST;
-
-        /* Don't check if it's a TAR stream here, do that in the
-           rtZipTarFss_Next. */
-
+        rtZipTarReaderInit(pThis, hVfsIosIn, fFlags);
         *phVfsFss = hVfsFss;
         return VINF_SUCCESS;
@@ -1532,2 +1421,44 @@
 }
 
+
+/**
+ * Used by RTZipTarFsStreamTruncate to resolve @a hVfsObj.
+ */
+DECLHIDDEN(PRTZIPTARBASEOBJ) rtZipTarFsStreamBaseObjToPrivate(PRTZIPTARFSSTREAM pThis, RTVFSOBJ hVfsObj)
+{
+    PRTZIPTARBASEOBJ pThisObj;
+    RTVFSOBJTYPE enmType = RTVfsObjGetType(hVfsObj);
+    switch (enmType)
+    {
+        case RTVFSOBJTYPE_IO_STREAM:
+        {
+            RTVFSIOSTREAM hVfsIos = RTVfsObjToIoStream(hVfsObj);
+            AssertReturn(hVfsIos != NIL_RTVFSIOSTREAM, NULL);
+            PRTZIPTARIOSTREAM pThisStrm = (PRTZIPTARIOSTREAM)RTVfsIoStreamToPrivate(hVfsIos, &g_rtZipTarFssIosOps);
+            RTVfsIoStrmRelease(hVfsIos);
+            pThisObj = &pThisStrm->BaseObj;
+            break;
+        }
+
+        case RTVFSOBJTYPE_SYMLINK:
+        {
+            RTVFSSYMLINK hVfsSymlink = RTVfsObjToSymlink(hVfsObj);
+            AssertReturn(hVfsSymlink != NIL_RTVFSSYMLINK, NULL);
+            pThisObj = (PRTZIPTARBASEOBJ)RTVfsSymlinkToPrivate(hVfsSymlink, &g_rtZipTarFssSymOps);
+            RTVfsSymlinkRelease(hVfsSymlink);
+            break;
+        }
+
+        case RTVFSOBJTYPE_BASE:
+            pThisObj = (PRTZIPTARBASEOBJ)RTVfsObjToPrivate(hVfsObj, &g_rtZipTarFssBaseObjOps);
+            break;
+
+        default:
+            /** @todo implement.   */
+            AssertFailedReturn(NULL);
+    }
+
+    AssertReturn(pThisObj->pTarReader == &pThis->TarReader, NULL);
+    return pThisObj;
+}
+
Index: /trunk/src/VBox/Runtime/common/zip/tarvfsreader.h
===================================================================
--- /trunk/src/VBox/Runtime/common/zip/tarvfsreader.h	(revision 84192)
+++ /trunk/src/VBox/Runtime/common/zip/tarvfsreader.h	(revision 84192)
@@ -0,0 +1,169 @@
+/* $Id$ */
+/** @file
+ * IPRT - TAR Virtual Filesystem.
+ */
+
+/*
+ * Copyright (C) 2010-2020 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_INCLUDED_SRC_common_zip_tarvfsreader_h
+#define IPRT_INCLUDED_SRC_common_zip_tarvfsreader_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "tar.h"
+
+
+/**
+ * TAR reader state machine states.
+ */
+typedef enum RTZIPTARREADERSTATE
+{
+    /** Invalid state. */
+    RTZIPTARREADERSTATE_INVALID = 0,
+    /** Expecting the next file/dir/whatever entry. */
+    RTZIPTARREADERSTATE_FIRST,
+    /** Expecting more zero headers or the end of the stream. */
+    RTZIPTARREADERSTATE_ZERO,
+    /** Expecting a GNU long name. */
+    RTZIPTARREADERSTATE_GNU_LONGNAME,
+    /** Expecting a GNU long link. */
+    RTZIPTARREADERSTATE_GNU_LONGLINK,
+    /** Expecting a normal header or another GNU specific one. */
+    RTZIPTARREADERSTATE_GNU_NEXT,
+    /** End of valid states (not included). */
+    RTZIPTARREADERSTATE_END
+} RTZIPTARREADERSTATE;
+
+/**
+ * Tar reader instance data.
+ */
+typedef struct RTZIPTARREADER
+{
+    /** Zero header counter. */
+    uint32_t                cZeroHdrs;
+    /** The state machine state. */
+    RTZIPTARREADERSTATE     enmState;
+    /** The type of the previous TAR header.
+     * @remarks Same a enmType for the first header in the TAR stream. */
+    RTZIPTARTYPE            enmPrevType;
+    /** The type of the current TAR header. */
+    RTZIPTARTYPE            enmType;
+    /** The current header. */
+    RTZIPTARHDR             Hdr;
+    /** The expected long name/link length (GNU). */
+    uint32_t                cbGnuLongExpect;
+    /** The current long name/link length (GNU). */
+    uint32_t                offGnuLongCur;
+    /** The name of the current object.
+     * This is for handling GNU and PAX long names. */
+    char                    szName[RTPATH_MAX];
+    /** The current link target if symlink or hardlink. */
+    char                    szTarget[RTPATH_MAX];
+} RTZIPTARREADER;
+/** Pointer to the TAR reader instance data. */
+typedef RTZIPTARREADER *PRTZIPTARREADER;
+
+/**
+ * Tar directory, character device, block device, fifo socket or symbolic link.
+ */
+typedef struct RTZIPTARBASEOBJ
+{
+    /** The stream offset of the (first) header in the input stream/file.  */
+    RTFOFF                  offHdr;
+    /** The stream offset of the first header of the next object (for truncating the
+     * tar file after this object (updating)). */
+    RTFOFF                  offNextHdr;
+    /** Pointer to the reader instance data (resides in the filesystem
+     * stream).
+     * @todo Fix this so it won't go stale... Back ref from this obj to fss? */
+    PRTZIPTARREADER         pTarReader;
+    /** The object info with unix attributes. */
+    RTFSOBJINFO             ObjInfo;
+} RTZIPTARBASEOBJ;
+/** Pointer to a TAR filesystem stream base object. */
+typedef RTZIPTARBASEOBJ *PRTZIPTARBASEOBJ;
+
+
+/**
+ * Tar file represented as a VFS I/O stream.
+ */
+typedef struct RTZIPTARIOSTREAM
+{
+    /** The basic TAR object data. */
+    RTZIPTARBASEOBJ         BaseObj;
+    /** The number of bytes in the file. */
+    RTFOFF                  cbFile;
+    /** The current file position. */
+    RTFOFF                  offFile;
+    /** The start position in the hVfsIos (for seekable hVfsIos). */
+    RTFOFF                  offStart;
+    /** The number of padding bytes following the file. */
+    uint32_t                cbPadding;
+    /** Set if we've reached the end of this file. */
+    bool                    fEndOfStream;
+    /** The input I/O stream. */
+    RTVFSIOSTREAM           hVfsIos;
+} RTZIPTARIOSTREAM;
+/** Pointer to a the private data of a TAR file I/O stream. */
+typedef RTZIPTARIOSTREAM *PRTZIPTARIOSTREAM;
+
+
+/**
+ * Tar filesystem stream private data.
+ */
+typedef struct RTZIPTARFSSTREAM
+{
+    /** The input I/O stream. */
+    RTVFSIOSTREAM           hVfsIos;
+
+    /** The current object (referenced). */
+    RTVFSOBJ                hVfsCurObj;
+    /** Pointer to the private data if hVfsCurObj is representing a file. */
+    PRTZIPTARIOSTREAM       pCurIosData;
+
+    /** The start offset. */
+    RTFOFF                  offStart;
+    /** The offset of the next header. */
+    RTFOFF                  offNextHdr;
+    /** The offset of the first header for the current object.
+     * When reaching the end, this will be the same as offNextHdr which will be
+     * pointing to the first zero header */
+    RTFOFF                  offCurHdr;
+
+    /** Set if we've reached the end of the stream. */
+    bool                    fEndOfStream;
+    /** Set if we've encountered a fatal error. */
+    int                     rcFatal;
+
+    /** The TAR reader instance data. */
+    RTZIPTARREADER          TarReader;
+} RTZIPTARFSSTREAM;
+/** Pointer to a the private data of a TAR filesystem stream. */
+typedef RTZIPTARFSSTREAM *PRTZIPTARFSSTREAM;
+
+DECLHIDDEN(void)                rtZipTarReaderInit(PRTZIPTARFSSTREAM pThis, RTVFSIOSTREAM hVfsIos, uint64_t offStart);
+DECLHIDDEN(DECLCALLBACK(int))   rtZipTarFss_Next(void *pvThis, char **ppszName, RTVFSOBJTYPE *penmType, PRTVFSOBJ phVfsObj);
+DECLHIDDEN(PRTZIPTARBASEOBJ)    rtZipTarFsStreamBaseObjToPrivate(PRTZIPTARFSSTREAM pThis, RTVFSOBJ hVfsObj);
+
+#endif /* !IPRT_INCLUDED_SRC_common_zip_tarvfsreader_h */
+
Index: /trunk/src/VBox/Runtime/common/zip/tarvfswriter.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/zip/tarvfswriter.cpp	(revision 84191)
+++ /trunk/src/VBox/Runtime/common/zip/tarvfswriter.cpp	(revision 84192)
@@ -44,4 +44,6 @@
 
 #include "tar.h"
+
+#include "tarvfsreader.h"
 
 
@@ -161,5 +163,5 @@
     /** Set if we've encountered a fatal error. */
     int                     rcFatal;
-    /** Flags. */
+    /** Flags, RTZIPTAR_C_XXX. */
     uint32_t                fFlags;
 
@@ -183,4 +185,10 @@
     RTFMODE                 fDirModeOrMask;     /**< Directory mode OR mask. */
     /** @} */
+
+    /** When in update mode (RTZIPTAR_C_UPDATE) we have an reader FSS instance,
+     * though w/o the RTVFSFSSTREAM bits. (Allocated after this structure.) */
+    PRTZIPTARFSSTREAM       pRead;
+    /** Set if we're in writing mode and pfnNext shall fail. */
+    bool                    fWriting;
 
 
@@ -909,4 +917,60 @@
 
 /**
+ * Does the actual work for rtZipTarFssWriter_SwitchToWriteMode().
+ *
+ * @note    We won't be here if we've truncate the tar file.   Truncation
+ *          switches it into write mode.
+ */
+DECL_NO_INLINE(static, int) rtZipTarFssWriter_SwitchToWriteModeSlow(PRTZIPTARFSSTREAMWRITER pThis)
+{
+    /* Always go thru rtZipTarFssWriter_SwitchToWriteMode(). */
+    AssertRCReturn(pThis->rcFatal, pThis->rcFatal);
+    AssertReturn(!pThis->fWriting, VINF_SUCCESS);
+    AssertReturn(pThis->fFlags & RTZIPTAR_C_UPDATE, VERR_INTERNAL_ERROR_3);
+
+    /*
+     * If we're not at the end, locate the end of the tar file.
+     * Because I'm lazy, we do that using rtZipTarFss_Next.  This isn't entirely
+     * optimial as it involves VFS object instantations and such.
+     */
+    /** @todo Optimize skipping to end of tar file in update mode. */
+    while (!pThis->pRead->fEndOfStream)
+    {
+        int rc = rtZipTarFss_Next(pThis->pRead, NULL, NULL, NULL);
+        if (rc == VERR_EOF)
+            break;
+        AssertRCReturn(rc, rc);
+    }
+
+    /*
+     * Seek to the desired cut-off point and indicate that we've switched to writing.
+     */
+    Assert(pThis->pRead->offNextHdr == pThis->pRead->offCurHdr);
+    int rc = RTVfsFileSeek(pThis->hVfsFile, pThis->pRead->offNextHdr, RTFILE_SEEK_BEGIN, NULL /*poffActual*/);
+    if (RT_SUCCESS(rc))
+        pThis->fWriting = true;
+    else
+        pThis->rcFatal = rc;
+
+    return rc;
+}
+
+
+/**
+ * Switches the stream into writing mode if necessary.
+ *
+ * @returns VBox status code.
+ * @param   pThis           The TAR writer instance.
+ *
+ */
+DECLINLINE(int) rtZipTarFssWriter_SwitchToWriteMode(PRTZIPTARFSSTREAMWRITER pThis)
+{
+    if (pThis->fWriting)
+        return VINF_SUCCESS; /* ASSUMES caller already checked pThis->rcFatal. */
+    return rtZipTarFssWriter_SwitchToWriteModeSlow(pThis);
+}
+
+
+/**
  * Allocates a buffer for transfering file data.
  *
@@ -922,5 +986,5 @@
  * @param   cbFile          The file size.  Used as a buffer size hint.
  */
-static uint8_t *rtZipTarFssWrite_AllocBuf(PRTZIPTARFSSTREAMWRITER pThis, size_t *pcbBuf, void **ppvFree, uint64_t cbObject)
+static uint8_t *rtZipTarFssWriter_AllocBuf(PRTZIPTARFSSTREAMWRITER pThis, size_t *pcbBuf, void **ppvFree, uint64_t cbObject)
 {
     uint8_t *pbBuf;
@@ -1274,5 +1338,5 @@
     void    *pvBufFree;
     size_t   cbBuf;
-    uint8_t *pbBuf = rtZipTarFssWrite_AllocBuf(pThis, &cbBuf, &pvBufFree, pObjInfo->cbObject);
+    uint8_t *pbBuf = rtZipTarFssWriter_AllocBuf(pThis, &cbBuf, &pvBufFree, pObjInfo->cbObject);
 
     PRTZIPTARSPARSE pSparse;
@@ -1399,7 +1463,7 @@
                 void    *pvBufFree;
                 size_t   cbBuf;
-                uint8_t *pbBuf = rtZipTarFssWrite_AllocBuf(pThis, &cbBuf, &pvBufFree,
-                                                           pObjInfo->cbObject > 0 && pObjInfo->cbObject != RTFOFF_MAX
-                                                           ? pObjInfo->cbObject : _1G);
+                uint8_t *pbBuf = rtZipTarFssWriter_AllocBuf(pThis, &cbBuf, &pvBufFree,
+                                                            pObjInfo->cbObject > 0 && pObjInfo->cbObject != RTFOFF_MAX
+                                                            ? pObjInfo->cbObject : _1G);
 
                 uint64_t cbReadTotal = 0;
@@ -1502,5 +1566,5 @@
             void    *pvBufFree;
             size_t   cbBuf;
-            uint8_t *pbBuf = rtZipTarFssWrite_AllocBuf(pThis, &cbBuf, &pvBufFree, pObjInfo->cbObject);
+            uint8_t *pbBuf = rtZipTarFssWriter_AllocBuf(pThis, &cbBuf, &pvBufFree, pObjInfo->cbObject);
 
             uint64_t cbLeft = pObjInfo->cbObject;
@@ -1684,4 +1748,24 @@
 
 /**
+ * @interface_method_impl{RTVFSFSSTREAMOPS,pfnNext}
+ */
+static DECLCALLBACK(int) rtZipTarFssWriter_Next(void *pvThis, char **ppszName, RTVFSOBJTYPE *penmType, PRTVFSOBJ phVfsObj)
+{
+    PRTZIPTARFSSTREAMWRITER pThis = (PRTZIPTARFSSTREAMWRITER)pvThis;
+
+    /*
+     * This only works in update mode and up to the point where
+     * modifications takes place (truncating the archive or appending files).
+     */
+    AssertReturn(pThis->pRead, VERR_ACCESS_DENIED);
+    AssertReturn(pThis->fFlags & RTZIPTAR_C_UPDATE, VERR_ACCESS_DENIED);
+
+    AssertReturn(!pThis->fWriting, VERR_WRONG_ORDER);
+
+    return rtZipTarFss_Next(pThis->pRead, ppszName, penmType, phVfsObj);
+}
+
+
+/**
  * @interface_method_impl{RTVFSFSSTREAMOPS,pfnAdd}
  */
@@ -1694,6 +1778,5 @@
      */
     int rc = rtZipTarFssWriter_CompleteCurrentPushFile(pThis);
-    if (RT_FAILURE(rc))
-        return rc;
+    AssertRCReturn(rc, rc);
 
     /*
@@ -1713,4 +1796,10 @@
     if (RT_FAILURE(rc) || ObjGrpName.Attr.u.UnixGroup.szName[0] == '\0')
         strcpy(ObjGrpName.Attr.u.UnixGroup.szName, "somegroup");
+
+    /*
+     * Switch the stream into write mode if necessary.
+     */
+    rc = rtZipTarFssWriter_SwitchToWriteMode(pThis);
+    AssertRCReturn(rc, rc);
 
     /*
@@ -1780,6 +1869,5 @@
      */
     int rc = rtZipTarFssWriter_CompleteCurrentPushFile(pThis);
-    if (RT_FAILURE(rc))
-        return rc;
+    AssertRCReturn(rc, rc);
 
     /*
@@ -1833,4 +1921,10 @@
 
     /*
+     * Switch the stream into write mode if necessary.
+     */
+    rc = rtZipTarFssWriter_SwitchToWriteMode(pThis);
+    AssertRCReturn(rc, rc);
+
+    /*
      * Create an I/O stream object for the caller to use.
      */
@@ -1925,4 +2019,21 @@
              */
             rc = RTVfsIoStrmFlush(pThis->hVfsIos);
+
+            /*
+             * If we're in update mode, set the end-of-file here to make sure
+             * unwanted bytes are really discarded.
+             */
+            if (RT_SUCCESS(rc) && (pThis->fFlags & RTZIPTAR_C_UPDATE))
+            {
+                RTFOFF cbTarFile = RTVfsFileTell(pThis->hVfsFile);
+                if (cbTarFile >= 0)
+                    rc =  RTVfsFileSetSize(pThis->hVfsFile, (uint64_t)cbTarFile, RTVFSFILE_SIZE_F_NORMAL);
+                else
+                    rc = (int)cbTarFile;
+            }
+
+            /*
+             * Success?
+             */
             if (RT_SUCCESS(rc))
                 return rc;
@@ -1949,5 +2060,5 @@
     RTVFSFSSTREAMOPS_VERSION,
     0,
-    NULL,
+    rtZipTarFssWriter_Next,
     rtZipTarFssWriter_Add,
     rtZipTarFssWriter_PushFile,
@@ -1968,4 +2079,5 @@
     AssertReturn(enmFormat > RTZIPTARFORMAT_INVALID && enmFormat < RTZIPTARFORMAT_END, VERR_INVALID_PARAMETER);
     AssertReturn(!(fFlags & ~RTZIPTAR_C_VALID_MASK), VERR_INVALID_FLAGS);
+    AssertReturn(!(fFlags & RTZIPTAR_C_UPDATE), VERR_NOT_SUPPORTED); /* Must use RTZipTarFsStreamForFile! */
 
     if (enmFormat == RTZIPTARFORMAT_DEFAULT)
@@ -1983,5 +2095,5 @@
     PRTZIPTARFSSTREAMWRITER pThis;
     RTVFSFSSTREAM           hVfsFss;
-    int rc = RTVfsNewFsStream(&g_rtZipTarFssOps, sizeof(*pThis), NIL_RTVFS, NIL_RTVFSLOCK, false /*fReadOnly*/,
+    int rc = RTVfsNewFsStream(&g_rtZipTarFssOps, sizeof(*pThis), NIL_RTVFS, NIL_RTVFSLOCK, RTFILE_O_WRITE,
                               &hVfsFss, (void **)&pThis);
     if (RT_SUCCESS(rc))
@@ -2004,4 +2116,5 @@
         pThis->fDirModeAndMask  = ~(RTFMODE)0;
         pThis->fDirModeOrMask   = 0;
+        pThis->fWriting         = true;
 
         *phVfsFss = hVfsFss;
@@ -2010,4 +2123,76 @@
 
     RTVfsIoStrmRelease(hVfsIosOut);
+    return rc;
+}
+
+
+RTDECL(int) RTZipTarFsStreamForFile(RTVFSFILE hVfsFile, RTZIPTARFORMAT enmFormat, uint32_t fFlags, PRTVFSFSSTREAM phVfsFss)
+{
+    /*
+     * Input validation.
+     */
+    AssertPtrReturn(phVfsFss, VERR_INVALID_HANDLE);
+    *phVfsFss = NIL_RTVFSFSSTREAM;
+    AssertPtrReturn(hVfsFile != NIL_RTVFSFILE, VERR_INVALID_HANDLE);
+    AssertReturn(enmFormat > RTZIPTARFORMAT_INVALID && enmFormat < RTZIPTARFORMAT_END, VERR_INVALID_PARAMETER);
+    AssertReturn(!(fFlags & ~RTZIPTAR_C_VALID_MASK), VERR_INVALID_FLAGS);
+
+    if (enmFormat == RTZIPTARFORMAT_DEFAULT)
+        enmFormat = RTZIPTARFORMAT_GNU;
+    AssertReturn(   enmFormat == RTZIPTARFORMAT_GNU
+                 || enmFormat == RTZIPTARFORMAT_USTAR
+                 , VERR_NOT_IMPLEMENTED); /* Only implementing GNU and USTAR output at the moment. */
+
+    RTFOFF const offStart = RTVfsFileTell(hVfsFile);
+    AssertReturn(offStart >= 0, (int)offStart);
+
+    uint32_t cRefs = RTVfsFileRetain(hVfsFile);
+    AssertReturn(cRefs != UINT32_MAX, VERR_INVALID_HANDLE);
+
+    RTVFSIOSTREAM hVfsIos = RTVfsFileToIoStream(hVfsFile);
+    AssertReturnStmt(hVfsIos != NIL_RTVFSIOSTREAM, RTVfsFileRelease(hVfsFile), VERR_INVALID_HANDLE);
+
+    /*
+     * Retain the input stream and create a new filesystem stream handle.
+     */
+    PRTZIPTARFSSTREAMWRITER pThis;
+    size_t const            cbThis = sizeof(*pThis) + (fFlags & RTZIPTAR_C_UPDATE ? sizeof(*pThis->pRead) : 0);
+    RTVFSFSSTREAM           hVfsFss;
+    int rc = RTVfsNewFsStream(&g_rtZipTarFssOps, cbThis, NIL_RTVFS, NIL_RTVFSLOCK, RTFILE_O_WRITE,
+                              &hVfsFss, (void **)&pThis);
+    if (RT_SUCCESS(rc))
+    {
+        pThis->hVfsIos          = hVfsIos;
+        pThis->hVfsFile         = hVfsFile;
+
+        pThis->enmFormat        = enmFormat;
+        pThis->fFlags           = fFlags;
+        pThis->rcFatal          = VINF_SUCCESS;
+
+        pThis->uidOwner         = NIL_RTUID;
+        pThis->pszOwner         = NULL;
+        pThis->gidGroup         = NIL_RTGID;
+        pThis->pszGroup         = NULL;
+        pThis->pszPrefix        = NULL;
+        pThis->pModTime         = NULL;
+        pThis->fFileModeAndMask = ~(RTFMODE)0;
+        pThis->fFileModeOrMask  = 0;
+        pThis->fDirModeAndMask  = ~(RTFMODE)0;
+        pThis->fDirModeOrMask   = 0;
+        if (!(fFlags & RTZIPTAR_C_UPDATE))
+            pThis->fWriting     = true;
+        else
+        {
+            pThis->fWriting     = false;
+            pThis->pRead        = (PRTZIPTARFSSTREAM)(pThis + 1);
+            rtZipTarReaderInit(pThis->pRead, hVfsIos, (uint64_t)offStart);
+        }
+
+        *phVfsFss = hVfsFss;
+        return VINF_SUCCESS;
+    }
+
+    RTVfsIoStrmRelease(hVfsIos);
+    RTVfsFileRelease(hVfsFile);
     return rc;
 }
@@ -2136,2 +2321,31 @@
 }
 
+
+RTDECL(int) RTZipTarFsStreamTruncate(RTVFSFSSTREAM hVfsFss, RTVFSOBJ hVfsObj, bool fAfter)
+{
+    /*
+     * Translate and validate the input.
+     */
+    PRTZIPTARFSSTREAMWRITER pThis = (PRTZIPTARFSSTREAMWRITER)RTVfsFsStreamToPrivate(hVfsFss, &g_rtZipTarFssOps);
+    AssertReturn(pThis, VERR_WRONG_TYPE);
+
+    AssertReturn(hVfsObj != NIL_RTVFSOBJ, VERR_INVALID_HANDLE);
+    PRTZIPTARBASEOBJ pThisObj = rtZipTarFsStreamBaseObjToPrivate(pThis->pRead, hVfsObj);
+    AssertReturn(pThis, VERR_NOT_OWNER);
+
+    AssertReturn(pThis->pRead, VERR_ACCESS_DENIED);
+    AssertReturn(pThis->fFlags & RTZIPTAR_C_UPDATE, VERR_ACCESS_DENIED);
+    AssertReturn(!pThis->fWriting, VERR_WRONG_ORDER);
+
+    /*
+     * Seek to the desired cut-off point and indicate that we've switched to writing.
+     */
+    int rc = RTVfsFileSeek(pThis->hVfsFile, fAfter ? pThisObj->offNextHdr : pThisObj->offHdr,
+                           RTFILE_SEEK_BEGIN, NULL /*poffActual*/);
+    if (RT_SUCCESS(rc))
+        pThis->fWriting = true;
+    else
+        pThis->rcFatal = rc;
+    return rc;
+}
+
Index: /trunk/src/VBox/Runtime/common/zip/xarvfs.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/zip/xarvfs.cpp	(revision 84191)
+++ /trunk/src/VBox/Runtime/common/zip/xarvfs.cpp	(revision 84192)
@@ -2090,5 +2090,5 @@
                     PRTZIPXARFSSTREAM pThis;
                     RTVFSFSSTREAM     hVfsFss;
-                    rc = RTVfsNewFsStream(&rtZipXarFssOps, sizeof(*pThis), NIL_RTVFS, NIL_RTVFSLOCK, true /*fReadOnly*/,
+                    rc = RTVfsNewFsStream(&rtZipXarFssOps, sizeof(*pThis), NIL_RTVFS, NIL_RTVFSLOCK, RTFILE_O_READ,
                                           &hVfsFss, (void **)&pThis);
                     if (RT_SUCCESS(rc))
