Index: /trunk/include/VBox/ssm.h
===================================================================
--- /trunk/include/VBox/ssm.h	(revision 23539)
+++ /trunk/include/VBox/ssm.h	(revision 23540)
@@ -658,5 +658,5 @@
 VMMR3DECL(int)          SSMR3HandleSetStatus(PSSMHANDLE pSSM, int iStatus);
 VMMR3DECL(SSMAFTER)     SSMR3HandleGetAfter(PSSMHANDLE pSSM);
-VMMR3DECL(uint64_t)     SSMR3HandleGetUnitOffset(PSSMHANDLE pSSM);
+VMMR3DECL(bool)         SSMR3HandleIsLiveSave(PSSMHANDLE pSSM);
 VMMR3_INT_DECL(int)     SSMR3SetGCPtrSize(PSSMHANDLE pSSM, unsigned cbGCPtr);
 VMMR3DECL(int)          SSMR3Cancel(PVM pVM);
Index: /trunk/src/VBox/VMM/SSM.cpp
===================================================================
--- /trunk/src/VBox/VMM/SSM.cpp	(revision 23539)
+++ /trunk/src/VBox/VMM/SSM.cpp	(revision 23540)
@@ -191,4 +191,6 @@
 /** The stream is checkesummed up to the footer using CRC-32. */
 #define SSMFILEHDR_FLAGS_STREAM_CRC32           RT_BIT_32(0)
+/** Indicates that the file was produced by a live save. */
+#define SSMFILEHDR_FLAGS_STREAM_LIVE_SAVE       RT_BIT_32(1)
 /** @} */
 
@@ -318,4 +320,11 @@
     } while (0)
 
+#define SSM_ASSERT_VALID_HANDLE(pSSM) \
+    do \
+    { \
+        AssertPtr(pSSM); \
+        Assert(pSSM->enmOp > SSMSTATE_INVALID && pSSM->enmOp < SSMSTATE_OPEN_END); \
+    } while (0)
+
 
 /*******************************************************************************
@@ -337,5 +346,6 @@
     SSMSTATE_LOAD_EXEC,
     SSMSTATE_LOAD_DONE,
-    SSMSTATE_OPEN_READ
+    SSMSTATE_OPEN_READ,
+    SSMSTATE_OPEN_END
 } SSMSTATE;
 
@@ -440,4 +450,6 @@
     /** The current uncompressed offset into the data unit. */
     uint64_t                offUnit;
+    /** Indicates that this is a live save or restore operation. */
+    bool                    fLiveSave;
 
     /** Pointer to the progress callback function. */
@@ -3805,5 +3817,6 @@
 
     /* (progress should be pending 99% now) */
-    AssertMsg(pSSM->uPercent == (101 - pSSM->uPercentDone), ("%d\n", pSSM->uPercent));
+    AssertMsg(   pSSM->uPercent == (101 - pSSM->uPercentDone)
+              || pSSM->fLiveSave, ("%d\n", pSSM->uPercent));
     return VINF_SUCCESS;
 }
@@ -3962,4 +3975,6 @@
     FileHdr.cUnits       = pVM->ssm.s.cUnits;
     FileHdr.fFlags       = SSMFILEHDR_FLAGS_STREAM_CRC32;
+    if (pSSM->fLiveSave)
+        FileHdr.fFlags  |= SSMFILEHDR_FLAGS_STREAM_LIVE_SAVE;
     FileHdr.cbMaxDecompr = RT_SIZEOFMEMB(SSMHANDLE, u.Read.abDataBuffer);
     FileHdr.u32CRC       = 0;
@@ -4009,4 +4024,5 @@
     pSSM->cbUnitLeftV1          = 0;
     pSSM->offUnit               = UINT64_MAX;
+    pSSM->fLiveSave             = false;
     pSSM->pfnProgress           = pfnProgress;
     pSSM->pvUser                = pvUser;
@@ -4377,5 +4393,5 @@
             }
         }
-#if 0
+#if 0 /** @todo check this out... */
         /*
          * Check the VM state to see if it has changed.
@@ -4515,4 +4531,5 @@
     pSSM->uPercentPrepare = 20; /** @todo fix these. */
     pSSM->uPercentDone    = 2;
+    pSSM->fLiveSave       = true;
 
     /*
@@ -4525,5 +4542,6 @@
     {
 /** @todo If it turns out we don't need to do ssmR3DoLivePrepRun on EMT0,
- *        simply move the code to SSMR3LiveDoStep1. */
+ *        simply move the code to SSMR3LiveDoStep1.
+ *  Update: This is certinaly the case, move it. */
         rc = ssmR3DoLivePrepRun(pVM, pSSM);
         if (RT_SUCCESS(rc))
@@ -6027,6 +6045,7 @@
  *
  * @returns VBox status.
- * @param   File                File to validate.
- *                              The file position is undefined on return.
+ * @param   pSSM                The saved state handle.  A number of field will
+ *                              be updated, mostly header related information.
+ *                              fLiveSave is also set if appropriate.
  * @param   fChecksumIt         Whether to checksum the file or not.  This will
  *                              be ignored if it the stream isn't a file.
@@ -6112,5 +6131,5 @@
                 return VERR_SSM_INTEGRITY;
             }
-            if ((uHdr.v2_0.fFlags & ~SSMFILEHDR_FLAGS_STREAM_CRC32))
+            if (uHdr.v2_0.fFlags & ~(SSMFILEHDR_FLAGS_STREAM_CRC32 | SSMFILEHDR_FLAGS_STREAM_LIVE_SAVE))
             {
                 LogRel(("SSM: Unknown header flags: %08x\n", uHdr.v2_0.fFlags));
@@ -6133,6 +6152,7 @@
             pSSM->u.Read.cbGCPhys       = uHdr.v2_0.cbGCPhys;
             pSSM->u.Read.cbGCPtr        = uHdr.v2_0.cbGCPtr;
-            pSSM->u.Read.fFixedGCPtrSize = true;
+            pSSM->u.Read.fFixedGCPtrSize= true;
             fChecksummed = !!(uHdr.v2_0.fFlags & SSMFILEHDR_FLAGS_STREAM_CRC32);
+            pSSM->fLiveSave             = !!(uHdr.v2_0.fFlags & SSMFILEHDR_FLAGS_STREAM_LIVE_SAVE);
         }
         else
@@ -6338,4 +6358,5 @@
     pSSM->cbUnitLeftV1      = 0;
     pSSM->offUnit           = UINT64_MAX;
+    pSSM->fLiveSave         = false;
     pSSM->pfnProgress       = NULL;
     pSSM->pvUser            = NULL;
@@ -7321,4 +7342,5 @@
 VMMR3DECL(int) SSMR3HandleGetStatus(PSSMHANDLE pSSM)
 {
+    SSM_ASSERT_VALID_HANDLE(pSSM);
     return pSSM->rc;
 }
@@ -7338,4 +7360,5 @@
 VMMR3DECL(int) SSMR3HandleSetStatus(PSSMHANDLE pSSM, int iStatus)
 {
+    SSM_ASSERT_VALID_HANDLE(pSSM);
     Assert(pSSM->enmOp != SSMSTATE_LIVE_VOTE);
     if (RT_FAILURE(iStatus))
@@ -7359,4 +7382,5 @@
 VMMR3DECL(SSMAFTER) SSMR3HandleGetAfter(PSSMHANDLE pSSM)
 {
+    SSM_ASSERT_VALID_HANDLE(pSSM);
     return pSSM->enmAfter;
 }
@@ -7364,13 +7388,13 @@
 
 /**
- * Get the current unit byte offset (uncompressed).
- *
- * @returns The offset. UINT64_MAX if called at a wrong time.
+ * Checks if it is a live save operation or not.
+ *
+ * @returns True if it is, false if it isn't.
  * @param   pSSM            SSM operation handle.
  */
-VMMR3DECL(uint64_t) SSMR3HandleGetUnitOffset(PSSMHANDLE pSSM)
-{
-    AssertMsgFailed(("/** @todo this isn't correct any longer. */"));
-    return pSSM->offUnit;
+VMMR3DECL(bool) SSMR3HandleIsLiveSave(PSSMHANDLE pSSM)
+{
+    SSM_ASSERT_VALID_HANDLE(pSSM);
+    return pSSM->fLiveSave;
 }
 
