Index: /trunk/src/VBox/Main/ConsoleImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/ConsoleImpl.cpp	(revision 29863)
+++ /trunk/src/VBox/Main/ConsoleImpl.cpp	(revision 29864)
@@ -5233,5 +5233,25 @@
                                progressDesc,
                                fTeleporterEnabled /* aCancelable */);
-    if (FAILED(rc)) return rc;
+    if (FAILED(rc))
+        return rc;
+
+    /* Tell VBoxSVC and Machine about the progress object so they can combine
+       proxy it to any openRemoteSession caller. */
+    rc = mControl->BeginPowerUp(powerupProgress);
+    if (FAILED(rc))
+    {
+        LogFlowThisFunc(("BeginPowerUp failed\n"));
+        return rc;
+    }
+
+    BOOL fCanceled;
+    rc = powerupProgress->COMGETTER(Canceled)(&fCanceled);
+    if (FAILED(rc))
+        return rc;
+    if (fCanceled)
+    {
+        LogFlowThisFunc(("Canceled in BeginPowerUp\n"));
+        return setError(E_FAIL, tr("Powerup was canceled"));
+    }
 
     /* setup task object and thread to carry out the operation
@@ -7489,5 +7509,4 @@
         /* Notify the progress object of the success */
         task->mProgress->notifyComplete(S_OK);
-        console->mControl->SetPowerUpInfo(NULL);
     }
     else
@@ -7495,25 +7514,9 @@
         /* The progress object will fetch the current error info */
         task->mProgress->notifyComplete(rc);
-        ProgressErrorInfo info(task->mProgress);
-        ComObjPtr<VirtualBoxErrorInfo> errorInfo;
-        rc = errorInfo.createObject();
-        if (SUCCEEDED(rc))
-        {
-            errorInfo->init(info.getResultCode(),
-                            info.getInterfaceID(),
-                            info.getComponent(),
-                            info.getText());
-            console->mControl->SetPowerUpInfo(errorInfo);
-        }
-        else
-        {
-            /* If it's not possible to create an IVirtualBoxErrorInfo object
-             * signal success, as not signalling anything will cause a stuck
-             * progress object in VBoxSVC. */
-            console->mControl->SetPowerUpInfo(NULL);
-        }
-
         LogRel(("Power up failed (vrc=%Rrc, rc=%Rhrc (%#08X))\n", vrc, rc, rc));
     }
+
+    /* Notify VBoxSVC and any waiting openRemoteSession progress object. */
+    console->mControl->EndPowerUp(rc);
 
 #if defined(RT_OS_WINDOWS)
Index: /trunk/src/VBox/Main/MachineImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/MachineImpl.cpp	(revision 29863)
+++ /trunk/src/VBox/Main/MachineImpl.cpp	(revision 29864)
@@ -36,4 +36,5 @@
 #include "MachineImpl.h"
 #include "ProgressImpl.h"
+#include "ProgressProxyImpl.h"
 #include "MediumAttachmentImpl.h"
 #include "MediumImpl.h"
@@ -5175,5 +5176,6 @@
 
     AutoCaller autoCaller(this);
-    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+    if (FAILED(autoCaller.rc()))
+        return autoCaller.rc();
 
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
@@ -5327,4 +5329,6 @@
     {
         /* Note that the progress object is finalized later */
+        /** @todo Consider checking mData->mSession.mProgress for cancellation
+         *        around here.  */
 
         /* We don't reset mSession.mPid here because it is necessary for
@@ -5378,5 +5382,5 @@
         sessionMachine->uninit();
 
-    LogFlowThisFunc(("rc=%08X\n", rc));
+    LogFlowThisFunc(("rc=%Rhrc\n", rc));
     LogFlowThisFuncLeave();
     return rc;
@@ -5390,5 +5394,5 @@
                                    IN_BSTR aType,
                                    IN_BSTR aEnvironment,
-                                   Progress *aProgress)
+                                   ProgressProxy *aProgress)
 {
     LogFlowThisFuncEnter();
@@ -5613,4 +5617,5 @@
     return S_OK;
 }
+
 
 /**
@@ -9825,5 +9830,5 @@
  *  @note Locks this object for writing.
  */
-STDMETHODIMP SessionMachine::SetPowerUpInfo(IVirtualBoxErrorInfo *aError)
+STDMETHODIMP SessionMachine::BeginPowerUp(IProgress *aProgress)
 {
     AutoCaller autoCaller(this);
@@ -9832,36 +9837,35 @@
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
-    if (   mData->mSession.mState == SessionState_Open
-        && mData->mSession.mProgress)
-    {
-        /* Finalize the progress, since the remote session has completed
-         * power on (successful or not). */
-        if (aError)
-        {
-            /* Transfer error information immediately, as the
-             * IVirtualBoxErrorInfo object is most likely transient. */
-            HRESULT rc;
-            LONG rRc = S_OK;
-            rc = aError->COMGETTER(ResultCode)(&rRc);
-            AssertComRCReturnRC(rc);
-            Bstr rIID;
-            rc = aError->COMGETTER(InterfaceID)(rIID.asOutParam());
-            AssertComRCReturnRC(rc);
-            Bstr rComponent;
-            rc = aError->COMGETTER(Component)(rComponent.asOutParam());
-            AssertComRCReturnRC(rc);
-            Bstr rText;
-            rc = aError->COMGETTER(Text)(rText.asOutParam());
-            AssertComRCReturnRC(rc);
-            mData->mSession.mProgress->notifyComplete(rRc, Guid(rIID), rComponent, Utf8Str(rText).raw());
-        }
-        else
-            mData->mSession.mProgress->notifyComplete(S_OK);
+    if (mData->mSession.mState != SessionState_Open)
+        return VBOX_E_INVALID_OBJECT_STATE;
+
+    if (!mData->mSession.mProgress.isNull())
+        mData->mSession.mProgress->setOtherProgressObject(aProgress, 7);
+
+    return S_OK;
+}
+
+
+/**
+ *  @note Locks this object for writing.
+ */
+STDMETHODIMP SessionMachine::EndPowerUp(LONG iResult)
+{
+    AutoCaller autoCaller(this);
+    AssertComRCReturn(autoCaller.rc(), autoCaller.rc());
+
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    if (mData->mSession.mState != SessionState_Open)
+        return VBOX_E_INVALID_OBJECT_STATE;
+
+    /* Finalize the openRemoteSession progress object. */
+    if (mData->mSession.mProgress)
+    {
+        mData->mSession.mProgress->clearOtherProgressObject(tr("Finalizing"), 1);
+        mData->mSession.mProgress->notifyComplete((HRESULT)iResult);
         mData->mSession.mProgress.setNull();
-
-        return S_OK;
-    }
-    else
-        return VBOX_E_INVALID_OBJECT_STATE;
+    }
+    return S_OK;
 }
 
@@ -10057,11 +10061,14 @@
         /*  Create the progress object the client will use to wait until
          * #checkForDeath() is called to uninitialize this session object after
-         * it releases the IPC semaphore. */
+         * it releases the IPC semaphore.
+         * Note! Because we're "reusing" mProgress here, this must be a proxy
+         *       object just like for openRemoteSession. */
         Assert(mData->mSession.mProgress.isNull());
-        ComObjPtr<Progress> progress;
+        ComObjPtr<ProgressProxy> progress;
         progress.createObject();
         ComPtr<IUnknown> pPeer(mPeer);
         progress->init(mParent, pPeer,
-                       Bstr(tr("Closing session")), FALSE /* aCancelable */);
+                       Bstr(tr("Closing session")),
+                       FALSE /* aCancelable */);
         progress.queryInterfaceTo(aProgress);
         mData->mSession.mProgress = progress;
Index: /trunk/src/VBox/Main/VirtualBoxImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/VirtualBoxImpl.cpp	(revision 29863)
+++ /trunk/src/VBox/Main/VirtualBoxImpl.cpp	(revision 29864)
@@ -57,4 +57,5 @@
 #include "SharedFolderImpl.h"
 #include "ProgressImpl.h"
+#include "ProgressProxyImpl.h"
 #include "HostImpl.h"
 #include "USBControllerImpl.h"
@@ -1995,21 +1996,28 @@
 
     /* create a progress object */
-    ComObjPtr<Progress> progress;
+    ComObjPtr<ProgressProxy> progress;
     progress.createObject();
-    progress->init(this, static_cast <IMachine *>(machine),
-                   Bstr(tr("Spawning session")),
-                   FALSE /* aCancelable */);
-
-    rc = machine->openRemoteSession(control, aType, aEnvironment, progress);
-
+    rc = progress->init(this,
+                        static_cast <IMachine *>(machine),
+                        Bstr(tr("Spawning session")),
+                        TRUE /* aCancelable */,
+                        1 /* cOtherProgressObjects */,
+                        10 /* uTotalOperationsWeight */,
+                        Bstr(tr("Spawning session")),
+                        3 /* uFirstOperationWeight */,
+                        NULL /* pId */);
     if (SUCCEEDED(rc))
     {
-        progress.queryInterfaceTo(aProgress);
-
-        /* signal the client watcher thread */
-        updateClientWatcher();
-
-        /* fire an event */
-        onSessionStateChange(id, SessionState_Spawning);
+        rc = machine->openRemoteSession(control, aType, aEnvironment, progress);
+        if (SUCCEEDED(rc))
+        {
+            progress.queryInterfaceTo(aProgress);
+
+            /* signal the client watcher thread */
+            updateClientWatcher();
+
+            /* fire an event */
+            onSessionStateChange(id, SessionState_Spawning);
+        }
     }
 
@@ -4489,5 +4497,5 @@
 #ifdef RT_OS_WINDOWS
 #if 0
-    // WIP 
+    // WIP
     int nConnections = mVirtualBox->m_vec.GetSize();
     for (int i=0; i<nConnections; i++)
Index: /trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 29863)
+++ /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 29864)
@@ -3750,5 +3750,5 @@
   <interface
      name="IInternalMachineControl" extends="$unknown"
-     uuid="57e9a280-8d57-4331-aa31-f009f5194f52"
+     uuid="26604a54-8628-491b-a0ea-e1392a16d13b"
      internal="yes"
      wsmap="suppress"
@@ -3778,13 +3778,26 @@
     </method>
 
-    <method name="setPowerUpInfo">
-      <desc>
-        Transfers success (@c null) or error information for this session.
-        This method updates the progress object to signal completion of the
-        <link to="IVirtualBox::openRemoteSession"/> method if appropriate,
-        which means that the progress object returned by
-        <link to="IConsole::powerUp"/>.
-      </desc>
-      <param name="error" type="IVirtualBoxErrorInfo" dir="in"/>
+    <method name="beginPowerUp">
+      <desc>
+        Tells VBoxSVC that <link to="IConsole::powerUp"/> is under ways and
+	gives it the progress object that should be part of any pending
+	<link to="IVirtualBox::openRemoteSession"/> operations.  The progress
+	object may be called back to reflect an early cancelation, so some care
+	have to be taken with respect to any cancelation callbacks. The console
+	object will call <link to="IInternalMachineControl::endPowerUp"/>
+	to signal the completion of the progress object.
+      </desc>
+      <param name="progress" type="IProgress" dir="in"/>
+    </method>
+
+    <method name="endPowerUp">
+      <desc>
+        Tells VBoxSVC that <link to="IConsole::powerUp"/> has completed.
+	This method may query status information from the progress object it
+	received in <link to="IInternalMachineControl::beginPowerUp"/> and copy
+	it over to any in progress <link to="IVirtualBox::openRemoteSession"/>
+	call in order to complete that progress object.
+      </desc>
+      <param name="result" type="long" dir="in"/>
     </method>
 
Index: /trunk/src/VBox/Main/include/MachineImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/MachineImpl.h	(revision 29863)
+++ /trunk/src/VBox/Main/include/MachineImpl.h	(revision 29864)
@@ -54,4 +54,5 @@
 
 class Progress;
+class ProgressProxy;
 class Keyboard;
 class Mouse;
@@ -125,5 +126,5 @@
 
             /** openRemoteSession() and OnSessionEnd() progress indicator */
-            ComObjPtr<Progress> mProgress;
+            ComObjPtr<ProgressProxy> mProgress;
 
             /**
@@ -622,5 +623,5 @@
     HRESULT openRemoteSession(IInternalSessionControl *aControl,
                               IN_BSTR aType, IN_BSTR aEnvironment,
-                              Progress *aProgress);
+                              ProgressProxy *aProgress);
     HRESULT openExistingSession(IInternalSessionControl *aControl);
 
@@ -887,5 +888,6 @@
     STDMETHOD(UpdateState)(MachineState_T machineState);
     STDMETHOD(GetIPCId)(BSTR *id);
-    STDMETHOD(SetPowerUpInfo)(IVirtualBoxErrorInfo *aError);
+    STDMETHOD(BeginPowerUp)(IProgress *aProgress);
+    STDMETHOD(EndPowerUp)(LONG iResult);
     STDMETHOD(RunUSBDeviceFilters)(IUSBDevice *aUSBDevice, BOOL *aMatched, ULONG *aMaskedIfs);
     STDMETHOD(CaptureUSBDevice)(IN_BSTR aId);
Index: /trunk/src/VBox/Main/xpcom/server.cpp
===================================================================
--- /trunk/src/VBox/Main/xpcom/server.cpp	(revision 29863)
+++ /trunk/src/VBox/Main/xpcom/server.cpp	(revision 29864)
@@ -67,4 +67,5 @@
 #include <MediumFormatImpl.h>
 #include <ProgressCombinedImpl.h>
+#include <ProgressProxyImpl.h>
 #include <VRDPServerImpl.h>
 #include <SharedFolderImpl.h>
@@ -127,4 +128,7 @@
 NS_DECL_CLASSINFO(CombinedProgress)
 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(CombinedProgress, IProgress)
+
+NS_DECL_CLASSINFO(ProgressProxy)
+NS_IMPL_THREADSAFE_ISUPPORTS1_CI(ProgressProxy, IProgress)
 
 NS_DECL_CLASSINFO(SharedFolder)
