Index: /trunk/include/VBox/ssm.h
===================================================================
--- /trunk/include/VBox/ssm.h	(revision 24916)
+++ /trunk/include/VBox/ssm.h	(revision 24917)
@@ -979,6 +979,7 @@
      * @returns VBox status code.
      * @param   pvUser              The user argument.
+     * @param   fCancelled          True if the operation was cancelled.
      */
-    DECLCALLBACKMEMBER(int, pfnClose)(void *pvUser);
+    DECLCALLBACKMEMBER(int, pfnClose)(void *pvUser, bool fCancelled);
 
     /** Struct magic + version (SSMSTRMOPS_VERSION). */
Index: /trunk/src/VBox/Main/ConsoleImplTeleporter.cpp
===================================================================
--- /trunk/src/VBox/Main/ConsoleImplTeleporter.cpp	(revision 24916)
+++ /trunk/src/VBox/Main/ConsoleImplTeleporter.cpp	(revision 24917)
@@ -148,5 +148,6 @@
     uint32_t    u32Magic;
     /** The size of the data block following this header.
-     * 0 indicates the end of the stream. */
+     * 0 indicates the end of the stream, while UINT32_MAX indicates
+     * cancelation. */
     uint32_t    cb;
 } TELEPORTERTCPHDR;
@@ -388,7 +389,18 @@
                 return rc;
             }
-            if (   Hdr.u32Magic != TELEPORTERTCPHDR_MAGIC
-                || Hdr.cb > TELEPORTERTCPHDR_MAX_SIZE)
-            {
+
+            if (RT_UNLIKELY(   Hdr.u32Magic != TELEPORTERTCPHDR_MAGIC
+                            || Hdr.cb > TELEPORTERTCPHDR_MAX_SIZE
+                            || Hdr.cb == 0))
+            {
+                if (    Hdr.u32Magic == TELEPORTERTCPHDR_MAGIC
+                    &&  (   Hdr.cb == 0
+                         || Hdr.cb == UINT32_MAX)
+                   )
+                {
+                    pState->mfEndOfStream = true;
+                    pState->mcbReadBlock  = 0;
+                    return Hdr.cb ? VERR_SSM_CANCELLED : VERR_EOF;
+                }
                 pState->mfIOError = true;
                 LogRel(("Teleporter/TCP: Invalid block: u32Magic=%#x cb=%#x\n", Hdr.u32Magic, Hdr.cb));
@@ -397,10 +409,4 @@
 
             pState->mcbReadBlock = Hdr.cb;
-            if (!Hdr.cb)
-            {
-                pState->mfEndOfStream = true;
-                return VERR_EOF;
-            }
-
             if (pState->mfStopReading)
                 return VERR_EOF;
@@ -499,5 +505,5 @@
  * @copydoc SSMSTRMOPS::pfnClose
  */
-static DECLCALLBACK(int) teleporterTcpOpClose(void *pvUser)
+static DECLCALLBACK(int) teleporterTcpOpClose(void *pvUser, bool fCancelled)
 {
     TeleporterState *pState = (TeleporterState *)pvUser;
@@ -505,5 +511,7 @@
     if (pState->mfIsSource)
     {
-        TELEPORTERTCPHDR EofHdr = { TELEPORTERTCPHDR_MAGIC, 0 };
+        TELEPORTERTCPHDR EofHdr;
+        EofHdr.u32Magic = TELEPORTERTCPHDR_MAGIC;
+        EofHdr.cb       = fCancelled ? UINT32_MAX : 0;
         int rc = RTTcpWrite(pState->mhSocket, &EofHdr, sizeof(EofHdr));
         if (RT_SUCCESS(rc))
Index: /trunk/src/VBox/VMM/SSM.cpp
===================================================================
--- /trunk/src/VBox/VMM/SSM.cpp	(revision 24916)
+++ /trunk/src/VBox/VMM/SSM.cpp	(revision 24917)
@@ -1812,6 +1812,7 @@
  * @copydoc SSMSTRMOPS::pfnClose
  */
-static DECLCALLBACK(int) ssmR3FileClose(void *pvUser)
-{
+static DECLCALLBACK(int) ssmR3FileClose(void *pvUser, bool fCancelled)
+{
+    NOREF(fCancelled);
     return RTFileClose((RTFILE)(uintptr_t)pvUser);
 }
@@ -2157,6 +2158,8 @@
  * @returns VBox status code.
  * @param   pStrm           The stream handle.
- */
-static int ssmR3StrmClose(PSSMSTRM pStrm)
+ * @param   fCancelled      Indicates whether the operation was cancelled or
+ *                          not.
+ */
+static int ssmR3StrmClose(PSSMSTRM pStrm, bool fCancelled)
 {
     /*
@@ -2185,5 +2188,5 @@
         }
 
-        rc = pStrm->pOps->pfnClose(pStrm->pvUser);
+        rc = pStrm->pOps->pfnClose(pStrm->pvUser, fCancelled);
         if (RT_FAILURE(rc))
             ssmR3StrmSetError(pStrm, rc);
@@ -2191,5 +2194,5 @@
     else
     {
-        rc = pStrm->pOps->pfnClose(pStrm->pvUser);
+        rc = pStrm->pOps->pfnClose(pStrm->pvUser, fCancelled);
         if (RT_FAILURE(rc))
             ssmR3StrmSetError(pStrm, rc);
@@ -4126,5 +4129,5 @@
      */
     ssmR3SetCancellable(pVM, pSSM, false);
-    int rc = ssmR3StrmClose(&pSSM->Strm);
+    int rc = ssmR3StrmClose(&pSSM->Strm, pSSM->rc == VERR_SSM_CANCELLED);
     if (RT_SUCCESS(rc))
         rc = pSSM->rc;
@@ -5224,5 +5227,5 @@
     }
     /* bail out. */
-    int rc2 = ssmR3StrmClose(&pSSM->Strm);
+    int rc2 = ssmR3StrmClose(&pSSM->Strm, pSSM->rc == VERR_SSM_CANCELLED);
     RTMemFree(pSSM);
     rc2 = RTFileDelete(pszFilename);
@@ -5275,5 +5278,5 @@
  * decompressor, for saved file format version 1.
  *
- * @returns VBox status code.
+ * @returns VBox status code. Set pSSM->rc on error.
  * @param   pvSSM       The SSM handle.
  * @param   pvBuf       Where to store the compressed data.
@@ -5299,10 +5302,10 @@
             return VINF_SUCCESS;
         }
-        return rc;
+        return pSSM->rc = rc;
     }
 
     if (pSSM->enmAfter != SSMAFTER_DEBUG_IT)
         AssertMsgFailed(("SSM: attempted reading more than the unit!\n"));
-    return VERR_SSM_LOADED_TOO_MUCH;
+    return pSSM->rc = VERR_SSM_LOADED_TOO_MUCH;
 }
 
@@ -5310,4 +5313,6 @@
 /**
  * Internal read worker for reading data from a version 1 unit.
+ *
+ * @returns VBox status code, pSSM->rc is set on error.
  *
  * @param   pSSM            The saved state handle.
@@ -5396,7 +5401,5 @@
  * Read reader that keep works the progress indicator and unit offset.
  *
- * Does not set SSM::rc.
- *
- * @returns VBox status code.
+ * @returns VBox status code. Does NOT set pSSM->rc.
  * @param   pSSM            The saved state handle.
  * @param   pvBuf           Where to put the bits
@@ -5413,5 +5416,7 @@
     }
 
-    /** @todo weed out lazy saving */
+    if (rc == VERR_SSM_CANCELLED)
+        return rc;
+
     if (pSSM->enmAfter != SSMAFTER_DEBUG_IT)
         AssertMsgFailed(("SSM: attempted reading more than the unit!\n"));
@@ -5423,5 +5428,5 @@
  * Reads and checks the LZF "header".
  *
- * @returns VBox status code.
+ * @returns VBox status code. Sets pSSM->rc on error.
  * @param   pSSM            The saved state handle..
  * @param   pcbDecompr      Where to store the size of the decompressed data.
@@ -5438,5 +5443,5 @@
     int rc = ssmR3DataReadV2Raw(pSSM, &cKB, 1);
     if (RT_FAILURE(rc))
-        return rc;
+        return pSSM->rc = rc;
     pSSM->u.Read.cbRecLeft -= sizeof(cKB);
 
@@ -5456,5 +5461,5 @@
  * buffer.
  *
- * @returns VBox status code.
+ * @returns VBox status code. Sets pSSM->rc on error.
  * @param   SSM             The saved state handle.
  * @param   pvDst           Pointer to the output buffer.
@@ -5480,5 +5485,5 @@
         rc = ssmR3DataReadV2Raw(pSSM, &pSSM->u.Read.abComprBuffer[0], cbCompr);
         if (RT_FAILURE(rc))
-            return rc;
+            return pSSM->rc = rc;
         pb = &pSSM->u.Read.abComprBuffer[0];
     }
@@ -5498,5 +5503,5 @@
 
     AssertLogRelMsgFailed(("cbCompr=%#x cbDecompr=%#x rc=%Rrc\n", cbCompr, cbDecompr, rc));
-    return VERR_SSM_INTEGRITY_DECOMPRESSION;
+    return pSSM->rc = VERR_SSM_INTEGRITY_DECOMPRESSION;
 }
 
@@ -5505,5 +5510,5 @@
  * Reads and checks the raw zero "header".
  *
- * @returns VBox status code.
+ * @returns VBox status code. Sets pSSM->rc on error.
  * @param   pSSM            The saved state handle..
  * @param   pcbDecompr      Where to store the size of the zero data.
@@ -5517,5 +5522,5 @@
     int rc = ssmR3DataReadV2Raw(pSSM, &cKB, 1);
     if (RT_FAILURE(rc))
-        return rc;
+        return pSSM->rc = rc;
     pSSM->u.Read.cbRecLeft = 0;
 
@@ -5537,5 +5542,5 @@
  * is returned.
  *
- * @returns VBox status code.
+ * @returns VBox status code. Does not set pSSM->rc.
  * @param   pSSM            The saved state handle.
  */
@@ -5818,4 +5823,6 @@
  * Buffer miss, do a buffered read.
  *
+ * @returns VBox status code. Sets pSSM->rc on error.
+ *
  * @param   pSSM            The saved state handle.
  * @param   pvBuf           Where to store the read data.
@@ -7449,5 +7456,5 @@
 
         /* failure path */
-        ssmR3StrmClose(&pSSM->Strm);
+        ssmR3StrmClose(&pSSM->Strm, pSSM->rc == VERR_SSM_CANCELLED);
     }
     else
@@ -7774,5 +7781,6 @@
  * Executes the loading of a V2.X file.
  *
- * @returns VBox status code.
+ * @returns VBox status code.  May or may not set pSSM->rc, the returned
+ *          status code is ALWAYS the more accurate of the two.
  * @param   pVM                 The VM handle.
  * @param   pSSM                The saved state handle.
@@ -8131,5 +8139,4 @@
             }
         }
-        rc = Handle.rc;
 
         /* progress */
@@ -8138,5 +8145,6 @@
 
         ssmR3SetCancellable(pVM, &Handle, false);
-        ssmR3StrmClose(&Handle.Strm);
+        ssmR3StrmClose(&Handle.Strm, Handle.rc == VERR_SSM_CANCELLED);
+        rc = Handle.rc;
     }
 
@@ -8281,5 +8289,5 @@
                            false /*fChecksumOnRead*/, 1 /*cBuffers*/, &Handle);
     if (RT_SUCCESS(rc))
-        ssmR3StrmClose(&Handle.Strm);
+        ssmR3StrmClose(&Handle.Strm, false /*fCancelled*/);
     else
         Log(("SSM: Failed to open saved state file '%s', rc=%Rrc.\n",  pszFilename, rc));
@@ -8361,5 +8369,5 @@
      * Close the stream and free the handle.
      */
-    int rc = ssmR3StrmClose(&pSSM->Strm);
+    int rc = ssmR3StrmClose(&pSSM->Strm, pSSM->rc == VERR_SSM_CANCELLED);
     if (pSSM->u.Read.pZipDecompV1)
     {
