Index: /trunk/src/VBox/Main/ConsoleImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/ConsoleImpl.cpp	(revision 23809)
+++ /trunk/src/VBox/Main/ConsoleImpl.cpp	(revision 23810)
@@ -4635,5 +4635,6 @@
         progressDesc = tr("Starting virtual machine");
     rc = powerupProgress->init(static_cast<IConsole *>(this),
-                               progressDesc, FALSE /* aCancelable */);
+                               progressDesc,
+                               fTeleporterEnabled /* aCancelable */);
     CheckComRCReturnRC(rc);
 
@@ -6763,6 +6764,5 @@
                 {
                     /* -> ConsoleImplTeleporter.cpp */
-                    vrc = console->teleporterTrg(pVM, pMachine, task->mStartPaused,
-                                                 static_cast<VMProgressTask*>(task.get()));
+                    vrc = console->teleporterTrg(pVM, pMachine, task->mStartPaused, task->mProgress);
                     if (RT_FAILURE(vrc))
                         VMR3PowerOff(pVM);
Index: /trunk/src/VBox/Main/ConsoleImplTeleporter.cpp
===================================================================
--- /trunk/src/VBox/Main/ConsoleImplTeleporter.cpp	(revision 23809)
+++ /trunk/src/VBox/Main/ConsoleImplTeleporter.cpp	(revision 23810)
@@ -54,4 +54,5 @@
     ComPtr<Console>     mptrConsole;
     PVM                 mpVM;
+    ComObjPtr<Progress> mptrProgress;
     Utf8Str             mstrPassword;
     bool const          mfIsSource;
@@ -67,7 +68,8 @@
     /** @} */
 
-    TeleporterState(Console *pConsole, PVM pVM, bool fIsSource)
+    TeleporterState(Console *pConsole, PVM pVM, Progress *pProgress, bool fIsSource)
         : mptrConsole(pConsole)
         , mpVM(pVM)
+        , mptrProgress(pProgress)
         , mfIsSource(fIsSource)
         , mhSocket(NIL_RTSOCKET)
@@ -88,10 +90,9 @@
 {
 public:
-    ComPtr<Progress>    mptrProgress;
     Utf8Str             mstrHostname;
     uint32_t            muPort;
 
-    TeleporterStateSrc(Console *pConsole, PVM pVM)
-        : TeleporterState(pConsole, pVM, true /*fIsSource*/)
+    TeleporterStateSrc(Console *pConsole, PVM pVM, Progress *pProgress)
+        : TeleporterState(pConsole, pVM, pProgress, true /*fIsSource*/)
         , muPort(UINT32_MAX)
     {
@@ -107,13 +108,12 @@
 public:
     IMachine           *mpMachine;
-    void               *mpvVMCallbackTask;
     PRTTCPSERVER        mhServer;
     PRTTIMERLR          mphTimerLR;
     int                 mRc;
 
-    TeleporterStateTrg(Console *pConsole, PVM pVM, IMachine *pMachine, PRTTIMERLR phTimerLR)
-        : TeleporterState(pConsole, pVM, false /*fIsSource*/)
+    TeleporterStateTrg(Console *pConsole, PVM pVM, Progress *pProgress,
+                       IMachine *pMachine, PRTTIMERLR phTimerLR)
+        : TeleporterState(pConsole, pVM, pProgress, false /*fIsSource*/)
         , mpMachine(pMachine)
-        , mpvVMCallbackTask(NULL)
         , mhServer(NULL)
         , mphTimerLR(phTimerLR)
@@ -496,7 +496,47 @@
 
 /**
+ * Progress cancelation callback.
+ */
+static void teleporterProgressCancelCallback(void *pvUser)
+{
+    TeleporterState *pState = (TeleporterState *)pvUser;
+    SSMR3Cancel(pState->mpVM);
+    if (!pState->mfIsSource)
+    {
+        TeleporterStateTrg *pStateTrg = (TeleporterStateTrg *)pState;
+        RTTcpServerShutdown(pStateTrg->mhServer);
+    }
+}
+
+/**
+ * @copydoc PFNVMPROGRESS
+ */
+static DECLCALLBACK(int) teleporterProgressCallback(PVM pVM, unsigned uPercent, void *pvUser)
+{
+    TeleporterState *pState = (TeleporterState *)pvUser;
+    if (pState->mptrProgress)
+    {
+        HRESULT hrc = pState->mptrProgress->SetCurrentOperationProgress(uPercent);
+        if (FAILED(hrc))
+        {
+            /* check if the failure was caused by cancellation. */
+            BOOL fCanceled;
+            hrc = pState->mptrProgress->COMGETTER(Canceled)(&fCanceled);
+            if (SUCCEEDED(hrc) && fCanceled)
+            {
+                SSMR3Cancel(pState->mpVM);
+                return VERR_SSM_CANCELLED;
+            }
+        }
+    }
+
+    return VINF_SUCCESS;
+}
+
+
+/**
  * @copydoc FNRTTIMERLR
  */
-static DECLCALLBACK(void) teleporterTimeout(RTTIMERLR hTimerLR, void *pvUser, uint64_t iTick)
+static DECLCALLBACK(void) teleporterDstTimeout(RTTIMERLR hTimerLR, void *pvUser, uint64_t iTick)
 {
     /* This is harmless for any open connections. */
@@ -573,5 +613,5 @@
 
     void *pvUser = static_cast<void *>(static_cast<TeleporterState *>(pState));
-    vrc = VMR3Teleport(pState->mpVM, &g_teleporterTcpOps, pvUser, NULL/** @todo progress*/, pvUser);
+    vrc = VMR3Teleport(pState->mpVM, &g_teleporterTcpOps, pvUser, teleporterProgressCallback, pvUser);
     if (vrc)
         return setError(E_FAIL, tr("VMR3Teleport -> %Rrc"), vrc);
@@ -660,4 +700,6 @@
         pState->mhSocket = NIL_RTSOCKET;
     }
+
+    pState->mptrProgress->setCancelCallback(NULL, NULL);
     delete pState;
 
@@ -713,17 +755,19 @@
     LogFlowThisFunc(("Initiating TELEPORTER request...\n"));
 
-    ComObjPtr<Progress> ptrTelportationProgress;
-    HRESULT hrc = ptrTelportationProgress.createObject();
+    ComObjPtr<Progress> ptrProgress;
+    HRESULT hrc = ptrProgress.createObject();
     CheckComRCReturnRC(hrc);
-    hrc = ptrTelportationProgress->init(static_cast<IConsole *>(this),
+    hrc = ptrProgress->init(static_cast<IConsole *>(this),
                                         Bstr(tr("Teleporter")),
                                         TRUE /*aCancelable*/);
     CheckComRCReturnRC(hrc);
 
-    TeleporterStateSrc *pState = new TeleporterStateSrc(this, mpVM);
+    TeleporterStateSrc *pState = new TeleporterStateSrc(this, mpVM, ptrProgress);
     pState->mstrPassword = aPassword;
     pState->mstrHostname = aHostname;
     pState->muPort       = aPort;
-    pState->mptrProgress = ptrTelportationProgress;
+
+    void *pvUser = static_cast<void *>(static_cast<TeleporterState *>(pState));
+    ptrProgress->setCancelCallback(teleporterProgressCancelCallback, pvUser);
 
     int vrc = RTThreadCreate(NULL, Console::teleporterSrcThreadWrapper, (void *)pState, 0 /*cbStack*/,
@@ -733,10 +777,11 @@
         hrc = setMachineState(MachineState_Saving);
         if (SUCCEEDED(hrc))
-            ptrTelportationProgress.queryInterfaceTo(aProgress);
+            ptrProgress.queryInterfaceTo(aProgress);
         else
-            ptrTelportationProgress->Cancel();
+            ptrProgress->Cancel();
     }
     else
     {
+        ptrProgress->setCancelCallback(NULL, NULL);
         delete pState;
         hrc = setError(E_FAIL, tr("RTThreadCreate -> %Rrc"), vrc);
@@ -756,9 +801,8 @@
  * @param   fStartPaused        Whether to start it in the Paused (true) or
  *                              Running (false) state,
- * @param   pvVMCallbackTask    The callback task pointer for
- *                              stateProgressCallback().
+ * @param   pProgress           Pointer to the progress object.
  */
 int
-Console::teleporterTrg(PVM pVM, IMachine *pMachine, bool fStartPaused, void *pvVMCallbackTask)
+Console::teleporterTrg(PVM pVM, IMachine *pMachine, bool fStartPaused, Progress *pProgress)
 {
     /*
@@ -818,5 +862,5 @@
      */
     RTTIMERLR hTimerLR;
-    vrc = RTTimerLRCreateEx(&hTimerLR, 0 /*ns*/, RTTIMER_FLAGS_CPU_ANY, teleporterTimeout, hServer);
+    vrc = RTTimerLRCreateEx(&hTimerLR, 0 /*ns*/, RTTIMER_FLAGS_CPU_ANY, teleporterDstTimeout, hServer);
     if (RT_SUCCESS(vrc))
     {
@@ -827,8 +871,10 @@
              * Do the job, when it returns we're done.
              */
-            TeleporterStateTrg State(this, pVM, pMachine, &hTimerLR);
+            TeleporterStateTrg State(this, pVM, pProgress, pMachine, &hTimerLR);
             State.mstrPassword      = strPassword;
             State.mhServer          = hServer;
-            State.mpvVMCallbackTask = pvVMCallbackTask;
+
+            void *pvUser = static_cast<void *>(static_cast<TeleporterState *>(&State));
+            pProgress->setCancelCallback(teleporterProgressCancelCallback, pvUser);
 
             vrc = RTTcpServerListen(hServer, Console::teleporterTrgServeConnection, &State);
@@ -846,4 +892,6 @@
                 LogRel(("Teleporter: RTTcpServerListen -> %Rrc\n", vrc));
             }
+
+            pProgress->setCancelCallback(NULL, NULL);
         }
 
@@ -954,5 +1002,5 @@
             void *pvUser = static_cast<void *>(static_cast<TeleporterState *>(pState));
             vrc = VMR3LoadFromStream(pState->mpVM, &g_teleporterTcpOps, pvUser,
-                                     Console::stateProgressCallback, pState->mpvVMCallbackTask);
+                                     teleporterProgressCallback, pvUser);
             if (RT_FAILURE(vrc))
             {
@@ -978,5 +1026,6 @@
         }
         /** @todo implement config verification and hardware compatability checks. Or
-         *        maybe leave part of these to the saved state machinery? */
+         *        maybe leave part of these to the saved state machinery?
+         * Update: We're doing as much as possible in the first SSM pass. */
         else if (!strcmp(szCmd, "done"))
         {
Index: /trunk/src/VBox/Main/ProgressImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/ProgressImpl.cpp	(revision 23809)
+++ /trunk/src/VBox/Main/ProgressImpl.cpp	(revision 23810)
@@ -69,4 +69,7 @@
     // get creation timestamp
     m_ullTimestamp = RTTimeMilliTS();
+
+    m_pfnCancelCallback = NULL;
+    m_pvCancelUserArg = NULL;
 
     return S_OK;
@@ -509,4 +512,22 @@
     return resultCode;
 }
+
+/**
+ * Sets the cancellation callback.
+ *
+ * @param   pfnCallback     The function to be called upon cancelation.
+ * @param   pvUser          The callback argument.
+ */
+void ProgressBase::setCancelCallback(void (*pfnCallback)(void *), void *pvUser)
+{
+    AutoCaller autoCaller(this);
+    AssertComRCReturnVoid(autoCaller.rc());
+
+    AutoWriteLock alock(this);
+
+    m_pvCancelUserArg   = pvUser;
+    m_pfnCancelCallback = pfnCallback;
+}
+
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -867,5 +888,11 @@
                         tr("Operation cannot be canceled"));
 
-    mCanceled = TRUE;
+    if (!mCanceled)
+    {
+        mCanceled = TRUE;
+        if (m_pfnCancelCallback)
+            m_pfnCancelCallback(m_pvCancelUserArg);
+
+    }
     return S_OK;
 }
@@ -1566,5 +1593,15 @@
         return setError (E_FAIL, tr ("Operation cannot be cancelled"));
 
-    mCanceled = TRUE;
+    if (!mCanceled)
+    {
+        mCanceled = TRUE;
+/** @todo Teleportation: Shouldn't this be propagated to mProgresses? If
+ *        powerUp creates passes a combined progress object to the client, I
+ *        won't get called back since I'm only getting the powerupProgress ...
+ *        Or what? */
+        if (m_pfnCancelCallback)
+            m_pfnCancelCallback(m_pvCancelUserArg);
+
+    }
     return S_OK;
 }
Index: /trunk/src/VBox/Main/include/ConsoleImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 23809)
+++ /trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 23810)
@@ -523,5 +523,5 @@
     HRESULT                     teleporterSrcReadACK(TeleporterStateSrc *pState, const char *pszWhich, const char *pszNAckMsg = NULL);
     HRESULT                     teleporterSrcSubmitCommand(TeleporterStateSrc *pState, const char *pszCommand);
-    int                         teleporterTrg(PVM pVM, IMachine *pMachine, bool fStartPaused, void *pvVMCallbackTask);
+    int                         teleporterTrg(PVM pVM, IMachine *pMachine, bool fStartPaused, Progress *pProgress);
     static DECLCALLBACK(int)    teleporterTrgServeConnection(RTSOCKET Sock, void *pvUser);
     /** @} */
Index: /trunk/src/VBox/Main/include/ProgressImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/ProgressImpl.h	(revision 23809)
+++ /trunk/src/VBox/Main/include/ProgressImpl.h	(revision 23810)
@@ -86,4 +86,6 @@
 
     static HRESULT setErrorInfoOnThread (IProgress *aProgress);
+    void setCancelCallback(void (*pfnCallback)(void *), void *pvUser);
+
 
     // unsafe inline public methods for internal purposes only (ensure there is
@@ -107,4 +109,7 @@
 
     uint64_t m_ullTimestamp;                        // progress object creation timestamp, for ETA computation
+
+    void (*m_pfnCancelCallback)(void *);
+    void *m_pvCancelUserArg;
 
     /* The fields below are to be properly initalized by subclasses */
