Index: trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 36037)
+++ trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 36041)
@@ -137,5 +137,5 @@
  *
  * If \a aUsesVMPtr parameter is true, the task structure will also add itself
- * as a Console::mpVM caller with the same meaning as above. See
+ * as a Console::mpUVM caller with the same meaning as above. See
  * Console::addVMCaller() for more info.
  */
@@ -150,5 +150,7 @@
           mProgress(aProgress),
           mServerProgress(aServerProgress),
-          mVMCallerAdded(false)
+          mpVM(NULL),
+          mRC(E_FAIL),
+          mpSafeVMPtr(NULL)
     {
         AssertReturnVoid(aConsole);
@@ -158,7 +160,9 @@
         if (aUsesVMPtr)
         {
-            mRC = aConsole->addVMCaller();
-            if (SUCCEEDED(mRC))
-                mVMCallerAdded = true;
+            mpSafeVMPtr = new Console::SafeVMPtr(aConsole);
+            if (mpSafeVMPtr->isOk())
+                mpVM = mpSafeVMPtr->raw();
+            else
+                mRC = mpSafeVMPtr->rc();
         }
     }
@@ -166,6 +170,5 @@
     ~VMTask()
     {
-        if (mVMCallerAdded)
-            mConsole->releaseVMCaller();
+        releaseVMCaller();
     }
 
@@ -176,19 +179,21 @@
     void releaseVMCaller()
     {
-        AssertReturnVoid(mVMCallerAdded);
-        mConsole->releaseVMCaller();
-        mVMCallerAdded = false;
-    }
-
-    const ComObjPtr<Console> mConsole;
-    AutoCaller mConsoleCaller;
-    const ComObjPtr<Progress> mProgress;
-    Utf8Str mErrorMsg;
-    const ComPtr<IProgress> mServerProgress;
+        if (mpSafeVMPtr)
+        {
+            delete mpSafeVMPtr;
+            mpSafeVMPtr = NULL;
+        }
+    }
+
+    const ComObjPtr<Console>    mConsole;
+    AutoCaller                  mConsoleCaller;
+    const ComObjPtr<Progress>   mProgress;
+    Utf8Str                     mErrorMsg;
+    const ComPtr<IProgress>     mServerProgress;
+    PVM                         mpVM;
 
 private:
-
-    HRESULT mRC;
-    bool mVMCallerAdded : 1;
+    HRESULT                     mRC;
+    Console::SafeVMPtr         *mpSafeVMPtr;
 };
 
@@ -350,5 +355,5 @@
     : mSavedStateDataLoaded(false)
     , mConsoleVRDPServer(NULL)
-    , mpVM(NULL)
+    , mpUVM(NULL)
     , mVMCallers(0)
     , mVMZeroCallersSem(NIL_RTSEMEVENT)
@@ -567,8 +572,8 @@
 
     /* power down the VM if necessary */
-    if (mpVM)
+    if (mpUVM)
     {
         powerDown();
-        Assert(mpVM == NULL);
+        Assert(mpUVM == NULL);
     }
 
@@ -1908,12 +1913,13 @@
         return setInvalidMachineStateError();
 
-    /* protect mpVM */
-    AutoVMCaller autoVMCaller(this);
-    if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
+    /* protect mpUVM */
+    SafeVMPtr ptrVM(this);
+    if (!ptrVM.isOk())
+        return ptrVM.rc();
 
     /* leave the lock before a VMR3* call (EMT will call us back)! */
     alock.leave();
 
-    int vrc = VMR3Reset(mpVM);
+    int vrc = VMR3Reset(ptrVM);
 
     HRESULT rc = RT_SUCCESS(vrc) ? S_OK :
@@ -1927,11 +1933,11 @@
 }
 
-DECLCALLBACK(int) Console::unplugCpu(Console *pThis, unsigned uCpu)
-{
-    LogFlowFunc(("pThis=%p uCpu=%u\n", pThis, uCpu));
+/*static*/ DECLCALLBACK(int) Console::unplugCpu(Console *pThis, PVM pVM, unsigned uCpu)
+{
+    LogFlowFunc(("pThis=%p pVM=%p uCpu=%u\n", pThis, pVM, uCpu));
 
     AssertReturn(pThis, VERR_INVALID_PARAMETER);
 
-    int vrc = PDMR3DeviceDetach(pThis->mpVM, "acpi", 0, uCpu, 0);
+    int vrc = PDMR3DeviceDetach(pVM, "acpi", 0, uCpu, 0);
     Log(("UnplugCpu: rc=%Rrc\n", vrc));
 
@@ -1939,5 +1945,5 @@
 }
 
-HRESULT Console::doCPURemove(ULONG aCpu)
+HRESULT Console::doCPURemove(ULONG aCpu, PVM pVM)
 {
     HRESULT rc = S_OK;
@@ -1952,6 +1958,6 @@
 
     AssertReturn(m_pVMMDev, E_FAIL);
-    PPDMIVMMDEVPORT pDevPort = m_pVMMDev->getVMMDevPort();
-    AssertReturn(pDevPort, E_FAIL);
+    PPDMIVMMDEVPORT pVmmDevPort = m_pVMMDev->getVMMDevPort();
+    AssertReturn(pVmmDevPort, E_FAIL);
 
     if (   mMachineState != MachineState_Running
@@ -1961,46 +1967,36 @@
         return setInvalidMachineStateError();
 
-    /* protect mpVM */
-    AutoVMCaller autoVMCaller(this);
-    if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
     /* Check if the CPU is present */
     BOOL fCpuAttached;
     rc = mMachine->GetCPUStatus(aCpu, &fCpuAttached);
-    if (FAILED(rc)) return rc;
-
+    if (FAILED(rc))
+        return rc;
     if (!fCpuAttached)
-        return setError(E_FAIL,
-                        tr("CPU %d is not attached"), aCpu);
+        return setError(E_FAIL, tr("CPU %d is not attached"), aCpu);
 
     /* Leave the lock before any EMT/VMMDev call. */
     alock.release();
+    bool fLocked = true;
 
     /* Check if the CPU is unlocked */
     PPDMIBASE pBase;
-    int vrc = PDMR3QueryDeviceLun(mpVM, "acpi", 0, aCpu, &pBase);
-    bool fLocked = true;
+    int vrc = PDMR3QueryDeviceLun(pVM, "acpi", 0, aCpu, &pBase);
     if (RT_SUCCESS(vrc))
     {
+        Assert(pBase);
+        PPDMIACPIPORT pApicPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIACPIPORT);
+
+        /* Notify the guest if possible. */
         uint32_t idCpuCore, idCpuPackage;
-
-        /* Notify the guest if possible. */
-        vrc = VMR3GetCpuCoreAndPackageIdFromCpuId(mpVM, aCpu, &idCpuCore, &idCpuPackage);
-        AssertRC(vrc);
-
-        Assert(pBase);
-
-        PPDMIACPIPORT pPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIACPIPORT);
-
-        vrc = pDevPort->pfnCpuHotUnplug(pDevPort, idCpuCore, idCpuPackage);
+        vrc = VMR3GetCpuCoreAndPackageIdFromCpuId(pVM, aCpu, &idCpuCore, &idCpuPackage); AssertRC(vrc);
         if (RT_SUCCESS(vrc))
+            vrc = pVmmDevPort->pfnCpuHotUnplug(pVmmDevPort, idCpuCore, idCpuPackage);
+        if (RT_SUCCESS(vrc))
         {
             unsigned cTries = 100;
-
             do
             {
-                /* It will take some time until the event is processed in the guest. Wait  */
-                vrc = pPort ? pPort->pfnGetCpuStatus(pPort, aCpu, &fLocked) : VERR_INVALID_POINTER;
-
+                /* It will take some time until the event is processed in the guest. Wait...  */
+                vrc = pApicPort ? pApicPort->pfnGetCpuStatus(pApicPort, aCpu, &fLocked) : VERR_INVALID_POINTER;
                 if (RT_SUCCESS(vrc) && !fLocked)
                     break;
@@ -2013,5 +2009,5 @@
         {
             /* Query one time. It is possible that the user ejected the CPU. */
-            vrc = pPort ? pPort->pfnGetCpuStatus(pPort, aCpu, &fLocked) : VERR_INVALID_POINTER;
+            vrc = pApicPort ? pApicPort->pfnGetCpuStatus(pApicPort, aCpu, &fLocked) : VERR_INVALID_POINTER;
         }
     }
@@ -2025,8 +2021,7 @@
          */
         PVMREQ pReq;
-        vrc = VMR3ReqCall(mpVM, 0, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
-                          (PFNRT)Console::unplugCpu, 2,
-                          this, aCpu);
-
+        vrc = VMR3ReqCall(pVM, 0, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
+                          (PFNRT)Console::unplugCpu, 3,
+                          this, pVM, aCpu);
         if (vrc == VERR_TIMEOUT || RT_SUCCESS(vrc))
         {
@@ -2041,5 +2036,5 @@
         {
             /* Detach it from the VM  */
-            vrc = VMR3HotUnplugCpu(mpVM, aCpu);
+            vrc = VMR3HotUnplugCpu(pVM, aCpu);
             AssertRC(vrc);
         }
@@ -2057,5 +2052,5 @@
 }
 
-DECLCALLBACK(int) Console::plugCpu(Console *pThis, unsigned uCpu)
+/*static*/ DECLCALLBACK(int) Console::plugCpu(Console *pThis, PVM pVM, unsigned uCpu)
 {
     LogFlowFunc(("pThis=%p uCpu=%u\n", pThis, uCpu));
@@ -2063,8 +2058,8 @@
     AssertReturn(pThis, VERR_INVALID_PARAMETER);
 
-    int rc = VMR3HotPlugCpu(pThis->mpVM, uCpu);
+    int rc = VMR3HotPlugCpu(pVM, uCpu);
     AssertRC(rc);
 
-    PCFGMNODE pInst = CFGMR3GetChild(CFGMR3GetRoot(pThis->mpVM), "Devices/acpi/0/");
+    PCFGMNODE pInst = CFGMR3GetChild(CFGMR3GetRoot(pVM), "Devices/acpi/0/");
     AssertRelease(pInst);
     /* nuke anything which might have been left behind. */
@@ -2083,5 +2078,5 @@
      */
     PPDMIBASE pBase;
-    rc = PDMR3DeviceAttach(pThis->mpVM, "acpi", 0, uCpu, 0, &pBase); RC_CHECK();
+    rc = PDMR3DeviceAttach(pVM, "acpi", 0, uCpu, 0, &pBase); RC_CHECK();
 
     Log(("PlugCpu: rc=%Rrc\n", rc));
@@ -2094,5 +2089,5 @@
 }
 
-HRESULT Console::doCPUAdd(ULONG aCpu)
+HRESULT Console::doCPUAdd(ULONG aCpu, PVM pVM)
 {
     HRESULT rc = S_OK;
@@ -2117,8 +2112,4 @@
     AssertReturn(pDevPort, E_FAIL);
 
-    /* protect mpVM */
-    AutoVMCaller autoVMCaller(this);
-    if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
     /* Check if the CPU is present */
     BOOL fCpuAttached;
@@ -2136,7 +2127,7 @@
      */
     PVMREQ pReq;
-    int vrc = VMR3ReqCall(mpVM, 0, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
-                          (PFNRT)Console::plugCpu, 2,
-                          this, aCpu);
+    int vrc = VMR3ReqCall(pVM, 0, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
+                          (PFNRT)Console::plugCpu, 3,
+                          this, pVM, aCpu);
 
     /* leave the lock before a VMR3* call (EMT will call us back)! */
@@ -2159,11 +2150,9 @@
     if (RT_SUCCESS(vrc))
     {
+        /* Notify the guest if possible. */
         uint32_t idCpuCore, idCpuPackage;
-
-        /* Notify the guest if possible. */
-        vrc = VMR3GetCpuCoreAndPackageIdFromCpuId(mpVM, aCpu, &idCpuCore, &idCpuPackage);
-        AssertRC(vrc);
-
-        vrc = pDevPort->pfnCpuHotPlug(pDevPort, idCpuCore, idCpuPackage);
+        vrc = VMR3GetCpuCoreAndPackageIdFromCpuId(pVM, aCpu, &idCpuCore, &idCpuPackage); AssertRC(vrc);
+        if (RT_SUCCESS(vrc))
+            vrc = pDevPort->pfnCpuHotPlug(pDevPort, idCpuCore, idCpuPackage);
         /** @todo warning if the guest doesn't support it */
     }
@@ -2199,7 +2188,8 @@
     }
 
-    /* protect mpVM */
-    AutoVMCaller autoVMCaller(this);
-    if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
+    /* get the VM handle. */
+    SafeVMPtr ptrVM(this);
+    if (!ptrVM.isOk())
+        return ptrVM.rc();
 
     LogFlowThisFunc(("Sending PAUSE request...\n"));
@@ -2208,5 +2198,5 @@
     alock.leave();
 
-    int vrc = VMR3Suspend(mpVM);
+    int vrc = VMR3Suspend(ptrVM);
 
     HRESULT hrc = S_OK;
@@ -2233,7 +2223,8 @@
                         Global::stringifyMachineState(mMachineState));
 
-    /* protect mpVM */
-    AutoVMCaller autoVMCaller(this);
-    if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
+    /* get the VM handle. */
+    SafeVMPtr ptrVM(this);
+    if (!ptrVM.isOk())
+        return ptrVM.rc();
 
     LogFlowThisFunc(("Sending RESUME request...\n"));
@@ -2243,5 +2234,5 @@
 
 #ifdef VBOX_WITH_EXTPACK
-    int vrc = mptrExtPackManager->callAllVmPowerOnHooks(this, mpVM); /** @todo called a few times too many... */
+    int vrc = mptrExtPackManager->callAllVmPowerOnHooks(this, ptrVM); /** @todo called a few times too many... */
 #else
     int vrc = VINF_SUCCESS;
@@ -2249,8 +2240,8 @@
     if (RT_SUCCESS(vrc))
     {
-        if (VMR3GetState(mpVM) == VMSTATE_CREATED)
-            vrc = VMR3PowerOn(mpVM); /* (PowerUpPaused) */
+        if (VMR3GetState(ptrVM) == VMSTATE_CREATED)
+            vrc = VMR3PowerOn(ptrVM); /* (PowerUpPaused) */
         else
-            vrc = VMR3Resume(mpVM);
+            vrc = VMR3Resume(ptrVM);
     }
 
@@ -2280,15 +2271,21 @@
         return setInvalidMachineStateError();
 
-    /* protect mpVM */
-    AutoVMCaller autoVMCaller(this);
-    if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
+    /* get the VM handle. */
+    SafeVMPtr ptrVM(this);
+    if (!ptrVM.isOk())
+        return ptrVM.rc();
+/** @todo leave the console lock? */
+
+    /* get the acpi device interface and press the button. */
     PPDMIBASE pBase;
-    int vrc = PDMR3QueryDeviceLun(mpVM, "acpi", 0, 0, &pBase);
+    int vrc = PDMR3QueryDeviceLun(ptrVM, "acpi", 0, 0, &pBase);
     if (RT_SUCCESS(vrc))
     {
         Assert(pBase);
         PPDMIACPIPORT pPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIACPIPORT);
-        vrc = pPort ? pPort->pfnPowerButtonPress(pPort) : VERR_INVALID_POINTER;
+        if (pPort)
+            vrc = pPort->pfnPowerButtonPress(pPort);
+        else
+            vrc = VERR_PDM_MISSING_INTERFACE;
     }
 
@@ -2321,16 +2318,26 @@
         return setInvalidMachineStateError();
 
-    /* protect mpVM */
-    AutoVMCaller autoVMCaller(this);
-    if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
+    /* get the VM handle. */
+    SafeVMPtr ptrVM(this);
+    if (!ptrVM.isOk())
+        return ptrVM.rc();
+/** @todo leave the console lock? */
+
+    /* get the acpi device interface and check if the button press was handled. */
     PPDMIBASE pBase;
-    int vrc = PDMR3QueryDeviceLun(mpVM, "acpi", 0, 0, &pBase);
-    bool handled = false;
+    int vrc = PDMR3QueryDeviceLun(ptrVM, "acpi", 0, 0, &pBase);
     if (RT_SUCCESS(vrc))
     {
         Assert(pBase);
         PPDMIACPIPORT pPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIACPIPORT);
-        vrc = pPort ? pPort->pfnGetPowerButtonHandled(pPort, &handled) : VERR_INVALID_POINTER;
+        if (pPort)
+        {
+            bool fHandled = false;
+            vrc = pPort->pfnGetPowerButtonHandled(pPort, &fHandled);
+            if (RT_SUCCESS(vrc))
+                *aHandled = fHandled;
+        }
+        else
+            vrc = VERR_PDM_MISSING_INTERFACE;
     }
 
@@ -2339,6 +2346,4 @@
             tr("Checking if the ACPI Power Button event was handled by the guest OS failed (%Rrc)"),
             vrc);
-
-    *aHandled = handled;
 
     LogFlowThisFunc(("rc=%Rhrc\n", rc));
@@ -2367,19 +2372,28 @@
             Global::stringifyMachineState(mMachineState));
 
-    /* protect mpVM */
-    AutoVMCaller autoVMCaller(this);
-    if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
+    /* get the VM handle. */
+    SafeVMPtr ptrVM(this);
+    if (!ptrVM.isOk())
+        return ptrVM.rc();
+
+/** @todo leave the console lock? */
+
+    /* get the acpi device interface and query the information. */
     PPDMIBASE pBase;
-    int vrc = PDMR3QueryDeviceLun(mpVM, "acpi", 0, 0, &pBase);
-    bool entered = false;
+    int vrc = PDMR3QueryDeviceLun(ptrVM, "acpi", 0, 0, &pBase);
     if (RT_SUCCESS(vrc))
     {
         Assert(pBase);
         PPDMIACPIPORT pPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIACPIPORT);
-        vrc = pPort ? pPort->pfnGetGuestEnteredACPIMode(pPort, &entered) : VERR_INVALID_POINTER;
-    }
-
-    *aEntered = RT_SUCCESS(vrc) ? entered : false;
+        if (pPort)
+        {
+            bool fEntered = false;
+            vrc = pPort->pfnGetGuestEnteredACPIMode(pPort, &fEntered);
+            if (RT_SUCCESS(vrc))
+                *aEntered = fEntered;
+        }
+        else
+            vrc = VERR_PDM_MISSING_INTERFACE;
+    }
 
     LogFlowThisFuncLeave();
@@ -2399,15 +2413,22 @@
         return setInvalidMachineStateError();
 
-    /* protect mpVM */
-    AutoVMCaller autoVMCaller(this);
-    if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
+    /* get the VM handle. */
+    SafeVMPtr ptrVM(this);
+    if (!ptrVM.isOk())
+        return ptrVM.rc();
+
+/** @todo leave the console lock? */
+
+    /* get the acpi device interface and press the sleep button. */
     PPDMIBASE pBase;
-    int vrc = PDMR3QueryDeviceLun(mpVM, "acpi", 0, 0, &pBase);
+    int vrc = PDMR3QueryDeviceLun(ptrVM, "acpi", 0, 0, &pBase);
     if (RT_SUCCESS(vrc))
     {
         Assert(pBase);
         PPDMIACPIPORT pPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIACPIPORT);
-        vrc = pPort ? pPort->pfnSleepButtonPress(pPort) : VERR_INVALID_POINTER;
+        if (pPort)
+            vrc = pPort->pfnSleepButtonPress(pPort);
+        else
+            vrc = VERR_PDM_MISSING_INTERFACE;
     }
 
@@ -2448,5 +2469,6 @@
     {
         HRESULT rc = Pause();
-        if (FAILED(rc)) return rc;
+        if (FAILED(rc))
+            return rc;
     }
 
@@ -2467,5 +2489,6 @@
         rc = mControl->BeginSavingState(pProgress.asOutParam(),
                                         stateFilePath.asOutParam());
-        if (FAILED(rc)) break;
+        if (FAILED(rc))
+            break;
 
         fBeganSavingState = true;
@@ -2508,5 +2531,5 @@
 
         /* create a thread to wait until the VM state is saved */
-        int vrc = RTThreadCreate(NULL, Console::saveStateThread, (void *) task.get(),
+        int vrc = RTThreadCreate(NULL, Console::saveStateThread, (void *)task.get(),
                                  0, RTTHREADTYPE_MAIN_WORKER, 0, "VMSave");
         if (RT_FAILURE(vrc))
@@ -2521,6 +2544,5 @@
         /* return the progress to the caller */
         pProgress.queryInterfaceTo(aProgress);
-    }
-    while (0);
+    } while (0);
 
     if (FAILED(rc) && !fTaskCreationFailed)
@@ -2694,11 +2716,12 @@
             Global::stringifyMachineState(mMachineState));
 
-    /* protect mpVM */
-    AutoVMCaller autoVMCaller(this);
-    if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
+    /* Get the VM handle. */
+    SafeVMPtr ptrVM(this);
+    if (!ptrVM.isOk())
+        return ptrVM.rc();
 
     /* Don't proceed unless we've found the usb controller. */
     PPDMIBASE pBase = NULL;
-    int vrc = PDMR3QueryLun(mpVM, "usb-ohci", 0, 0, &pBase);
+    int vrc = PDMR3QueryLun(ptrVM, "usb-ohci", 0, 0, &pBase);
     if (RT_FAILURE(vrc))
         return setError(VBOX_E_PDM_ERROR,
@@ -2710,8 +2733,5 @@
 
     /* Request the device capture */
-    HRESULT rc = mControl->CaptureUSBDevice(aId);
-    if (FAILED(rc)) return rc;
-
-    return rc;
+    return mControl->CaptureUSBDevice(aId);
 
 #else   /* !VBOX_WITH_USB */
@@ -2898,16 +2918,12 @@
     if (FAILED(rc)) return rc;
 
-    /* protect mpVM (if not NULL) */
-    AutoVMCallerQuietWeak autoVMCaller(this);
-
-    if (    mpVM
-         && autoVMCaller.isOk()
+    /* If the VM is online and supports shared folders, share this folder
+     * under the specified name. (Ignore any failure to obtain the VM handle.) */
+    SafeVMPtrQuiet ptrVM(this);
+    if (    ptrVM.isOk()
          && m_pVMMDev
          && m_pVMMDev->isShFlActive()
        )
     {
-        /* If the VM is online and supports shared folders, share this folder
-         * under the specified name. */
-
         /* first, remove the machine or the global folder if there is any */
         SharedFolderDataMap::const_iterator it;
@@ -2915,10 +2931,12 @@
         {
             rc = removeSharedFolder(aName);
-            if (FAILED(rc)) return rc;
+            if (FAILED(rc))
+                return rc;
         }
 
         /* second, create the given folder */
         rc = createSharedFolder(aName, SharedFolderData(aHostPath, aWritable, aAutoMount));
-        if (FAILED(rc)) return rc;
+        if (FAILED(rc))
+            return rc;
     }
 
@@ -2964,9 +2982,7 @@
     if (FAILED(rc)) return rc;
 
-    /* protect mpVM (if not NULL) */
-    AutoVMCallerQuietWeak autoVMCaller(this);
-
-    if (    mpVM
-         && autoVMCaller.isOk()
+    /* protect the VM handle (if not NULL) */
+    SafeVMPtrQuiet ptrVM(this);
+    if (    ptrVM.isOk()
          && m_pVMMDev
          && m_pVMMDev->isShFlActive()
@@ -3110,5 +3126,5 @@
         int vrc = RTThreadCreate(NULL,
                                  Console::fntTakeSnapshotWorker,
-                                 (void*)pTask,
+                                 (void *)pTask,
                                  0,
                                  RTTHREADTYPE_MAIN_WORKER,
@@ -3291,8 +3307,9 @@
  * @param aMediumAttachment The medium attachment with the new medium state.
  * @param fForce            Force medium chance, if it is locked or not.
+ * @param pVM               Safe VM handle.
  *
  * @note Locks this object for writing.
  */
-HRESULT Console::doMediumChange(IMediumAttachment *aMediumAttachment, bool fForce)
+HRESULT Console::doMediumChange(IMediumAttachment *aMediumAttachment, bool fForce, PVM pVM)
 {
     AutoCaller autoCaller(this);
@@ -3352,8 +3369,4 @@
     AssertComRC(rc);
 
-    /* protect mpVM */
-    AutoVMCaller autoVMCaller(this);
-    AssertComRCReturnRC(autoVMCaller.rc());
-
     /*
      * Call worker in EMT, that's faster and safer than doing everything
@@ -3362,12 +3375,13 @@
      */
     PVMREQ pReq;
-    int vrc = VMR3ReqCall(mpVM,
+    int vrc = VMR3ReqCall(pVM,
                           VMCPUID_ANY,
-&pReq,
+                          &pReq,
                           0 /* no wait! */,
                           VMREQFLAGS_VBOX_STATUS,
                           (PFNRT)Console::changeRemovableMedium,
-                          7,
+                          8,
                           this,
+                          pVM,
                           pszDevice,
                           uInstance,
@@ -3411,4 +3425,5 @@
  *
  * @param   pThis           Pointer to the Console object.
+ * @param   pVM             The VM handle.
  * @param   pcszDevice      The PDM device name.
  * @param   uInstance       The PDM device instance.
@@ -3425,4 +3440,5 @@
  */
 DECLCALLBACK(int) Console::changeRemovableMedium(Console *pConsole,
+                                                 PVM pVM,
                                                  const char *pcszDevice,
                                                  unsigned uInstance,
@@ -3439,6 +3455,4 @@
     AutoCaller autoCaller(pConsole);
     AssertComRCReturn(autoCaller.rc(), VERR_ACCESS_DENIED);
-
-    PVM pVM = pConsole->mpVM;
 
     /*
@@ -3559,10 +3573,7 @@
 
     /* don't trigger network change if the VM isn't running */
-    if (mpVM)
-    {
-        /* protect mpVM */
-        AutoVMCaller autoVMCaller(this);
-        if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
+    SafeVMPtrQuiet ptrVM(this);
+    if (ptrVM.isOk())
+    {
         /* Get the properties we need from the adapter */
         BOOL fCableConnected, fTraceEnabled;
@@ -3590,5 +3601,5 @@
                 const char *pszAdapterName = networkAdapterTypeToName(adapterType);
                 PPDMIBASE pBase;
-                int vrc = PDMR3QueryDeviceLun(mpVM, pszAdapterName, ulInstance, 0, &pBase);
+                int vrc = PDMR3QueryDeviceLun(ptrVM, pszAdapterName, ulInstance, 0, &pBase);
                 if (RT_SUCCESS(vrc))
                 {
@@ -3607,5 +3618,5 @@
                     if (RT_SUCCESS(vrc) && changeAdapter)
                     {
-                        VMSTATE enmVMState = VMR3GetState(mpVM);
+                        VMSTATE enmVMState = VMR3GetState(ptrVM);
                         if (    enmVMState == VMSTATE_RUNNING    /** @todo LiveMigration: Forbid or deal correctly with the _LS variants */
                             ||  enmVMState == VMSTATE_SUSPENDED)
@@ -3617,5 +3628,5 @@
                             }
 
-                            rc = doNetworkAdapterChange(pszAdapterName, ulInstance, 0, aNetworkAdapter);
+                            rc = doNetworkAdapterChange(ptrVM, pszAdapterName, ulInstance, 0, aNetworkAdapter);
 
                             if (fTraceEnabled && fCableConnected && pINetCfg)
@@ -3628,8 +3639,6 @@
                 }
                 else if (vrc == VERR_PDM_DEVICE_INSTANCE_NOT_FOUND)
-                {
                     return setError(E_FAIL,
                             tr("The network adapter #%u is not enabled"), ulInstance);
-                }
                 else
                     ComAssertRC(vrc);
@@ -3639,4 +3648,5 @@
             }
         }
+        ptrVM.release();
     }
 
@@ -3655,5 +3665,5 @@
  */
 HRESULT Console::onNATRedirectRuleChange(ULONG ulInstance, BOOL aNatRuleRemove,
-                                 NATProtocol_T aProto, IN_BSTR aHostIp, LONG aHostPort, IN_BSTR aGuestIp, LONG aGuestPort)
+                                         NATProtocol_T aProto, IN_BSTR aHostIp, LONG aHostPort, IN_BSTR aGuestIp, LONG aGuestPort)
 {
     LogFlowThisFunc(("\n"));
@@ -3665,69 +3675,73 @@
 
     HRESULT rc = S_OK;
-    int vrc = VINF_SUCCESS;
-    PPDMINETWORKNATCONFIG pNetNatCfg = NULL;
+
     /* don't trigger nat engine change if the VM isn't running */
-    if (mpVM)
-    {
-        /* protect mpVM */
-        AutoVMCaller autoVMCaller(this);
-        if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
-        ComPtr<INetworkAdapter> pNetworkAdapter;
-        rc = machine()->GetNetworkAdapter(ulInstance, pNetworkAdapter.asOutParam());
-        if (   FAILED(rc)
-            || pNetworkAdapter.isNull())
-            goto done;
-
-        /*
-         * Find the adapter instance, get the config interface and update
-         * the link state.
-         */
-        NetworkAdapterType_T adapterType;
-        rc = pNetworkAdapter->COMGETTER(AdapterType)(&adapterType);
-        AssertComRC(rc);
-        if (FAILED(rc))
-        {
-            rc = E_FAIL;
-            goto done;
-        }
-
-        const char *pszAdapterName = networkAdapterTypeToName(adapterType);
-        PPDMIBASE pBase;
-        vrc = PDMR3QueryLun(mpVM, pszAdapterName, ulInstance, 0, &pBase);
-        ComAssertRC(vrc);
-        if (RT_FAILURE(vrc))
-        {
-            rc = E_FAIL;
-            goto done;
-        }
-        NetworkAttachmentType_T attachmentType;
-        vrc = pNetworkAdapter->COMGETTER(AttachmentType)(&attachmentType);
-
-        if (   RT_FAILURE(vrc)
-            || attachmentType != NetworkAttachmentType_NAT)
-        {
-            rc = (RT_FAILURE(vrc)) ? E_FAIL: rc;
-            goto done;
-        }
-
-        /* look down for PDMINETWORKNATCONFIG interface */
-        while (pBase)
-        {
-            if ((pNetNatCfg = (PPDMINETWORKNATCONFIG)pBase->pfnQueryInterface(pBase, PDMINETWORKNATCONFIG_IID)))
+    SafeVMPtrQuiet ptrVM(this);
+    if (ptrVM.isOk())
+    {
+        do
+        {
+            ComPtr<INetworkAdapter> pNetworkAdapter;
+            rc = machine()->GetNetworkAdapter(ulInstance, pNetworkAdapter.asOutParam());
+            if (   FAILED(rc)
+                || pNetworkAdapter.isNull())
                 break;
-            PPDMDRVINS drvins = PDMIBASE_2_PDMDRV(pBase);
-            pBase = drvins->pDownBase;
-        }
-        if (!pNetNatCfg)
-            goto done;
-        bool fUdp = (aProto == NATProtocol_UDP);
-        vrc = pNetNatCfg->pfnRedirectRuleCommand(pNetNatCfg, aNatRuleRemove, fUdp,
-                                                 Utf8Str(aHostIp).c_str(), aHostPort, Utf8Str(aGuestIp).c_str(),
-                                                 aGuestPort);
-        if (RT_FAILURE(vrc))
-            rc = E_FAIL;
-    }
-done:
+
+            /*
+             * Find the adapter instance, get the config interface and update
+             * the link state.
+             */
+            NetworkAdapterType_T adapterType;
+            rc = pNetworkAdapter->COMGETTER(AdapterType)(&adapterType);
+            if (FAILED(rc))
+            {
+                AssertComRC(rc);
+                rc = E_FAIL;
+                break;
+            }
+
+            const char *pszAdapterName = networkAdapterTypeToName(adapterType);
+            PPDMIBASE pBase;
+            int vrc = PDMR3QueryLun(ptrVM, pszAdapterName, ulInstance, 0, &pBase);
+            if (RT_FAILURE(vrc))
+            {
+                ComAssertRC(vrc);
+                rc = E_FAIL;
+                break;
+            }
+
+            NetworkAttachmentType_T attachmentType;
+            rc = pNetworkAdapter->COMGETTER(AttachmentType)(&attachmentType);
+            if (   FAILED(rc)
+                || attachmentType != NetworkAttachmentType_NAT)
+            {
+                rc = E_FAIL;
+                break;
+            }
+
+            /* look down for PDMINETWORKNATCONFIG interface */
+            PPDMINETWORKNATCONFIG pNetNatCfg = NULL;
+            while (pBase)
+            {
+                pNetNatCfg = (PPDMINETWORKNATCONFIG)pBase->pfnQueryInterface(pBase, PDMINETWORKNATCONFIG_IID);
+                if (pNetNatCfg)
+                    break;
+                /** @todo r=bird: This stinks! */
+                PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pBase);
+                pBase = pDrvIns->pDownBase;
+            }
+            if (!pNetNatCfg)
+                break;
+
+            bool fUdp = aProto == NATProtocol_UDP;
+            vrc = pNetNatCfg->pfnRedirectRuleCommand(pNetNatCfg, aNatRuleRemove, fUdp,
+                                                     Utf8Str(aHostIp).c_str(), aHostPort, Utf8Str(aGuestIp).c_str(),
+                                                     aGuestPort);
+            if (RT_FAILURE(vrc))
+                rc = E_FAIL;
+        } while (0); /* break loop */
+        ptrVM.release();
+    }
+
     LogFlowThisFunc(("Leaving rc=%#x\n", rc));
     return rc;
@@ -3740,4 +3754,5 @@
  * @returns COM status code.
  *
+ * @parma   pVM                 The VM handle (caller hold this safely).
  * @param   pszDevice           The PDM device name.
  * @param   uInstance           The PDM device instance.
@@ -3747,5 +3762,6 @@
  * @note Locks this object for writing.
  */
-HRESULT Console::doNetworkAdapterChange(const char *pszDevice,
+HRESULT Console::doNetworkAdapterChange(PVM pVM,
+                                        const char *pszDevice,
                                         unsigned uInstance,
                                         unsigned uLun,
@@ -3761,7 +3777,8 @@
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
-    /* protect mpVM */
-    AutoVMCaller autoVMCaller(this);
-    if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
+    /* Get the VM handle. */
+    SafeVMPtr ptrVM(this);
+    if (!ptrVM.isOk())
+        return ptrVM.rc();
 
     /*
@@ -3771,7 +3788,7 @@
      */
     PVMREQ pReq;
-    int vrc = VMR3ReqCall(mpVM, 0 /*idDstCpu*/, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
-                          (PFNRT) Console::changeNetworkAttachment, 5,
-                          this, pszDevice, uInstance, uLun, aNetworkAdapter);
+    int vrc = VMR3ReqCall(pVM, 0 /*idDstCpu*/, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
+                          (PFNRT) Console::changeNetworkAttachment, 6,
+                          this, ptrVM.raw(), pszDevice, uInstance, uLun, aNetworkAdapter);
 
     /* leave the lock before waiting for a result (EMT will call us back!) */
@@ -3805,4 +3822,5 @@
  *
  * @param   pThis               Pointer to the Console object.
+ * @param   pVM                 The VM handle.
  * @param   pszDevice           The PDM device name.
  * @param   uInstance           The PDM device instance.
@@ -3814,4 +3832,5 @@
  */
 DECLCALLBACK(int) Console::changeNetworkAttachment(Console *pThis,
+                                                   PVM pVM,
                                                    const char *pszDevice,
                                                    unsigned uInstance,
@@ -3827,6 +3846,6 @@
                   || !strcmp(pszDevice, "e1000")
                   || !strcmp(pszDevice, "virtio-net"))
-              && (uLun == 0)
-              && (uInstance < SchemaDefs::NetworkAdapterCount),
+              && uLun == 0
+              && uInstance < SchemaDefs::NetworkAdapterCount,
               ("pszDevice=%s uLun=%d uInstance=%d\n", pszDevice, uLun, uInstance));
     Log(("pszDevice=%s uLun=%d uInstance=%d\n", pszDevice, uLun, uInstance));
@@ -3834,10 +3853,4 @@
     AutoCaller autoCaller(pThis);
     AssertComRCReturn(autoCaller.rc(), VERR_ACCESS_DENIED);
-
-    /* protect mpVM */
-    AutoVMCaller autoVMCaller(pThis);
-    if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
-    PVM pVM = pThis->mpVM;
 
     /*
@@ -3932,11 +3945,9 @@
 
     /* don't trigger serial port change if the VM isn't running */
-    if (mpVM)
-    {
-        /* protect mpVM */
-        AutoVMCaller autoVMCaller(this);
-        if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
+    SafeVMPtrQuiet ptrVM(this);
+    if (ptrVM.isOk())
+    {
         /* nothing to do so far */
+        ptrVM.release();
     }
 
@@ -3966,11 +3977,9 @@
 
     /* don't trigger parallel port change if the VM isn't running */
-    if (mpVM)
-    {
-        /* protect mpVM */
-        AutoVMCaller autoVMCaller(this);
-        if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
+    SafeVMPtrQuiet ptrVM(this);
+    if (ptrVM.isOk())
+    {
         /* nothing to do so far */
+        ptrVM.release();
     }
 
@@ -4000,11 +4009,9 @@
 
     /* don't trigger storage controller change if the VM isn't running */
-    if (mpVM)
-    {
-        /* protect mpVM */
-        AutoVMCaller autoVMCaller(this);
-        if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
+    SafeVMPtrQuiet ptrVM(this);
+    if (ptrVM.isOk())
+    {
         /* nothing to do so far */
+        ptrVM.release();
     }
 
@@ -4034,11 +4041,9 @@
 
     /* don't trigger medium change if the VM isn't running */
-    if (mpVM)
-    {
-        /* protect mpVM */
-        AutoVMCaller autoVMCaller(this);
-        if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
-        rc = doMediumChange(aMediumAttachment, !!aForce);
+    SafeVMPtrQuiet ptrVM(this);
+    if (ptrVM.isOk())
+    {
+        rc = doMediumChange(aMediumAttachment, !!aForce, ptrVM);
+        ptrVM.release();
     }
 
@@ -4066,10 +4071,12 @@
 
     /* don't trigger CPU change if the VM isn't running */
-    if (mpVM)
+    SafeVMPtrQuiet ptrVM(this);
+    if (ptrVM.isOk())
     {
         if (aRemove)
-            rc = doCPURemove(aCPU);
+            rc = doCPURemove(aCPU, ptrVM);
         else
-            rc = doCPUAdd(aCPU);
+            rc = doCPUAdd(aCPU, ptrVM);
+        ptrVM.release();
     }
 
@@ -4099,10 +4106,7 @@
 
     /* don't trigger the CPU priority change if the VM isn't running */
-    if (mpVM)
-    {
-        /* protect mpVM */
-        AutoVMCaller autoVMCaller(this);
-        if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
+    SafeVMPtrQuiet ptrVM(this);
+    if (ptrVM.isOk())
+    {
         if (   mMachineState == MachineState_Running
             || mMachineState == MachineState_Teleporting
@@ -4111,8 +4115,9 @@
         {
             /* No need to call in the EMT thread. */
-            rc = VMR3SetCpuExecutionCap(mpVM, aExecutionCap);
+            rc = VMR3SetCpuExecutionCap(ptrVM, aExecutionCap);
         }
         else
             rc = setInvalidMachineStateError();
+        ptrVM.release();
     }
 
@@ -4215,5 +4220,6 @@
 
     /* don't trigger USB controller change if the VM isn't running */
-    if (mpVM)
+    SafeVMPtrQuiet ptrVM(this);
+    if (ptrVM.isOk())
     {
         /// @todo implement one day.
@@ -4224,9 +4230,6 @@
         // handle it at this time... :-)
 
-        /* protect mpVM */
-        AutoVMCaller autoVMCaller(this);
-        if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
         /* nothing to do so far */
+        ptrVM.release();
     }
 
@@ -4288,7 +4291,7 @@
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
-    /* protect mpVM (we don't need error info, since it's a callback) */
-    AutoVMCallerQuiet autoVMCaller(this);
-    if (FAILED(autoVMCaller.rc()))
+    /* Get the VM pointer (we don't need error info, since it's a callback). */
+    SafeVMPtrQuiet ptrVM(this);
+    if (!ptrVM.isOk())
     {
         /* The VM may be no more operational when this message arrives
@@ -4297,5 +4300,5 @@
         LogFlowThisFunc(("Attach request ignored (mMachineState=%d).\n",
                           mMachineState));
-        return autoVMCaller.rc();
+        return ptrVM.rc();
     }
 
@@ -4308,5 +4311,5 @@
 
     /* Don't proceed unless there's at least one USB hub. */
-    if (!PDMR3USBHasHub(mpVM))
+    if (!PDMR3USBHasHub(ptrVM))
     {
         LogFlowThisFunc(("Attach request ignored (no USB controller).\n"));
@@ -4437,10 +4440,7 @@
 
     /* don't trigger the CPU priority change if the VM isn't running */
-    if (mpVM)
-    {
-        /* protect mpVM */
-        AutoVMCaller autoVMCaller(this);
-        if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
-
+    SafeVMPtrQuiet ptrVM(this);
+    if (ptrVM.isOk())
+    {
         if (   mMachineState == MachineState_Running
             || mMachineState == MachineState_Teleporting
@@ -4458,5 +4458,5 @@
             {
                 int vrc;
-                vrc = PDMR3AsyncCompletionBwMgrSetMaxForFile(mpVM, Utf8Str(strName).c_str(),
+                vrc = PDMR3AsyncCompletionBwMgrSetMaxForFile(ptrVM, Utf8Str(strName).c_str(),
                                                              cMax * _1M);
                 AssertRC(vrc);
@@ -4465,4 +4465,5 @@
         else
             rc = setInvalidMachineStateError();
+        ptrVM.release();
     }
 
@@ -4683,5 +4684,5 @@
 
 /**
- * @note Temporarily locks this object for writing.
+ * @note Temporarily locks this object for writing. bird: And/or reading?
  */
 HRESULT Console::onlineMergeMedium(IMediumAttachment *aMediumAttachment,
@@ -4698,5 +4699,9 @@
     HRESULT rc = S_OK;
     int vrc = VINF_SUCCESS;
-    PVM pVM = mpVM;
+
+    /* Get the VM - must be done before the read-locking. */
+    SafeVMPtr ptrVM(this);
+    if (!ptrVM.isOk())
+        return ptrVM.rc();
 
     /* We will need to release the lock before doing the actual merge */
@@ -4714,4 +4719,6 @@
     }
 
+    /** @todo AssertComRC -> AssertComRCReturn! Could potentially end up
+     *        using uninitialized variables here. */
     BOOL fBuiltinIoCache;
     rc = mMachine->COMGETTER(IoCacheEnabled)(&fBuiltinIoCache);
@@ -4778,5 +4785,5 @@
 
     /* Pause the VM, as it might have pending IO on this drive */
-    VMSTATE enmVMState = VMR3GetState(pVM);
+    VMSTATE enmVMState = VMR3GetState(ptrVM);
     if (mMachineState == MachineState_DeletingSnapshotOnline)
     {
@@ -4784,15 +4791,15 @@
         /* disable the callback to prevent Console-level state change */
         mVMStateChangeCallbackDisabled = true;
-        int vrc2 = VMR3Suspend(pVM);
+        int vrc2 = VMR3Suspend(ptrVM);
         mVMStateChangeCallbackDisabled = false;
         AssertRCReturn(vrc2, E_FAIL);
     }
 
-    vrc = VMR3ReqCallWait(pVM,
+    vrc = VMR3ReqCallWait(ptrVM,
                           VMCPUID_ANY,
                           (PFNRT)reconfigureMediumAttachment,
                           13,
                           this,
-                          pVM,
+                          ptrVM.raw(),
                           pcszDevice,
                           uInstance,
@@ -4813,5 +4820,5 @@
         /* disable the callback to prevent Console-level state change */
         mVMStateChangeCallbackDisabled = true;
-        int vrc2 = VMR3Resume(pVM);
+        int vrc2 = VMR3Resume(ptrVM);
         mVMStateChangeCallbackDisabled = false;
         if (RT_FAILURE(vrc2))
@@ -4819,5 +4826,5 @@
             /* too bad, we failed. try to sync the console state with the VMM state */
             AssertLogRelRC(vrc2);
-            vmstateChangeCallback(pVM, VMSTATE_SUSPENDED, enmVMState, this);
+            vmstateChangeCallback(ptrVM, VMSTATE_SUSPENDED, enmVMState, this);
         }
     }
@@ -4830,5 +4837,5 @@
     PPDMIBASE pIBase = NULL;
     PPDMIMEDIA pIMedium = NULL;
-    vrc = PDMR3QueryDriverOnLun(pVM, pcszDevice, uInstance, uLUN, "VD", &pIBase);
+    vrc = PDMR3QueryDriverOnLun(ptrVM, pcszDevice, uInstance, uLUN, "VD", &pIBase);
     if (RT_SUCCESS(vrc))
     {
@@ -4849,5 +4856,5 @@
 
     /* Pause the VM, as it might have pending IO on this drive */
-    enmVMState = VMR3GetState(pVM);
+    enmVMState = VMR3GetState(ptrVM);
     if (mMachineState == MachineState_DeletingSnapshotOnline)
     {
@@ -4855,5 +4862,5 @@
         /* disable the callback to prevent Console-level state change */
         mVMStateChangeCallbackDisabled = true;
-        int vrc2 = VMR3Suspend(pVM);
+        int vrc2 = VMR3Suspend(ptrVM);
         mVMStateChangeCallbackDisabled = false;
         AssertRCReturn(vrc2, E_FAIL);
@@ -4865,10 +4872,10 @@
                                            ComSafeArrayInArg(aChildrenToReparent));
 
-    vrc = VMR3ReqCallWait(pVM,
+    vrc = VMR3ReqCallWait(ptrVM,
                           VMCPUID_ANY,
                           (PFNRT)reconfigureMediumAttachment,
                           13,
                           this,
-                          pVM,
+                          ptrVM.raw(),
                           pcszDevice,
                           uInstance,
@@ -4889,5 +4896,5 @@
         /* disable the callback to prevent Console-level state change */
         mVMStateChangeCallbackDisabled = true;
-        int vrc2 = VMR3Resume(pVM);
+        int vrc2 = VMR3Resume(ptrVM);
         mVMStateChangeCallbackDisabled = false;
         AssertRC(vrc2);
@@ -4895,5 +4902,5 @@
         {
             /* too bad, we failed. try to sync the console state with the VMM state */
-            vmstateChangeCallback(pVM, VMSTATE_SUSPENDED, enmVMState, this);
+            vmstateChangeCallback(ptrVM, VMSTATE_SUSPENDED, enmVMState, this);
         }
     }
@@ -5197,5 +5204,5 @@
     }
 
-    if (mpVM == NULL)
+    if (mpUVM == NULL)
     {
         Assert(aAllowNullVM == true);
@@ -5224,5 +5231,5 @@
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
-    AssertReturnVoid(mpVM != NULL);
+    AssertReturnVoid(mpUVM != NULL);
 
     Assert(mVMCallers > 0);
@@ -5235,4 +5242,60 @@
     }
 }
+
+
+HRESULT Console::safeVMPtrRetainer(PVM *a_ppVM, PUVM *a_ppUVM, bool a_Quiet)
+{
+    *a_ppVM  = NULL;
+    *a_ppUVM = NULL;
+
+    AutoCaller autoCaller(this);
+    AssertComRCReturnRC(autoCaller.rc());
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    /*
+     * Repeat the checks done by addVMCaller.
+     */
+    if (mVMDestroying) /* powerDown() is waiting for all callers to finish */
+        return a_Quiet
+            ? E_ACCESSDENIED
+            : setError(E_ACCESSDENIED, tr("The virtual machine is being powered down"));
+    PUVM pUVM = mpUVM;
+    if (!pUVM)
+        return a_Quiet
+            ? E_ACCESSDENIED
+            : setError(E_ACCESSDENIED, tr("The virtual machine is was powered off"));
+
+    /*
+     * Retain a reference to the user mode VM handle and get the global handle.
+     */
+    uint32_t cRefs = VMR3RetainUVM(pUVM);
+    if (cRefs == UINT32_MAX)
+        return a_Quiet
+            ? E_ACCESSDENIED
+            : setError(E_ACCESSDENIED, tr("The virtual machine is was powered off"));
+
+    PVM pVM = VMR3GetVM(pUVM);
+    if (!pVM)
+    {
+        VMR3ReleaseUVM(pUVM);
+        return a_Quiet
+            ? E_ACCESSDENIED
+            : setError(E_ACCESSDENIED, tr("The virtual machine is was powered off"));
+    }
+
+    /* done */
+    *a_ppVM  = pVM;
+    *a_ppUVM = pUVM;
+    return S_OK;
+}
+
+void Console::safeVMPtrReleaser(PVM *a_ppVM, PUVM *a_ppUVM)
+{
+    if (*a_ppVM && *a_ppUVM)
+        VMR3ReleaseUVM(*a_ppUVM);
+    *a_ppVM  = NULL;
+    *a_ppUVM = NULL;
+}
+
 
 /**
@@ -5870,5 +5933,6 @@
     Assert(mVMDestroying == false);
 
-    Assert(mpVM != NULL);
+    PUVM     pUVM  = mpUVM;                 Assert(pUVM != NULL);
+    uint32_t cRefs = VMR3RetainUVM(pUVM);   Assert(cRefs != UINT32_MAX);
 
     AssertMsg(   mMachineState == MachineState_Running
@@ -5986,7 +6050,7 @@
         LogFlowThisFunc(("Powering off the VM...\n"));
         alock.leave();
-        vrc = VMR3PowerOff(mpVM);
+        vrc = VMR3PowerOff(VMR3GetVM(pUVM));
 #ifdef VBOX_WITH_EXTPACK
-        mptrExtPackManager->callAllVmPowerOffHooks(this, mpVM);
+        mptrExtPackManager->callAllVmPowerOffHooks(this, VMR3GetVM(pUVM));
 #endif
         alock.enter();
@@ -6028,5 +6092,5 @@
         {
             PPDMIBASE pBase;
-            vrc = PDMR3QueryLun(mpVM, "usb-ohci", 0, 0, &pBase);
+            vrc = PDMR3QueryLun(VMR3GetVM(pUVM), "usb-ohci", 0, 0, &pBase);
             if (RT_SUCCESS(vrc))
             {
@@ -6043,8 +6107,8 @@
          * mVMDestroying is set which should prevent any activity. */
 
-        /* Set mpVM to NULL early just in case if some old code is not using
-         * addVMCaller()/releaseVMCaller(). */
-        PVM pVM = mpVM;
-        mpVM = NULL;
+        /* Set mpUVM to NULL early just in case if some old code is not using
+         * addVMCaller()/releaseVMCaller(). (We have our own ref on pUVM.) */
+        VMR3ReleaseUVM(mpUVM);
+        mpUVM = NULL;
 
         LogFlowThisFunc(("Destroying the VM...\n"));
@@ -6052,5 +6116,5 @@
         alock.leave();
 
-        vrc = VMR3Destroy(pVM);
+        vrc = VMR3Destroy(VMR3GetVM(pUVM));
 
         /* take the lock again */
@@ -6075,6 +6139,7 @@
         else
         {
-            /* bad bad bad, but what to do? */
-            mpVM = pVM;
+            /* bad bad bad, but what to do? (Give Console our UVM ref.) */
+            mpUVM = pUVM;
+            pUVM = NULL;
             rc = setError(VBOX_E_VM_ERROR,
                 tr("Could not destroy the machine. (Error: %Rrc)"),
@@ -6097,9 +6162,15 @@
     }
 
-    /* Finished with destruction. Note that if something impossible happened and
-     * we've failed to destroy the VM, mVMDestroying will remain true and
-     * mMachineState will be something like Stopping, so most Console methods
-     * will return an error to the caller. */
-    if (mpVM == NULL)
+    /*
+     * Finished with the destruction.
+     *
+     * Note that if something impossible happened and we've failed to destroy
+     * the VM, mVMDestroying will remain true and mMachineState will be
+     * something like Stopping, so most Console methods will return an error
+     * to the caller.
+     */
+    if (mpUVM != NULL)
+        VMR3ReleaseUVM(pUVM);
+    else
         mVMDestroying = false;
 
@@ -6215,13 +6286,12 @@
     LogFlowThisFunc(("Entering\n"));
 
-    /* protect mpVM (if not NULL) */
+    /* Check if we're online and keep it that way. */
+    SafeVMPtrQuiet ptrVM(this);
     AutoVMCallerQuietWeak autoVMCaller(this);
+    bool const online = ptrVM.isOk()
+                     && m_pVMMDev
+                     && m_pVMMDev->isShFlActive();
 
     HRESULT rc = S_OK;
-
-    bool online =    mpVM
-                  && autoVMCaller.isOk()
-                  && m_pVMMDev
-                  && m_pVMMDev->isShFlActive();
 
     try
@@ -6336,5 +6406,5 @@
     {
         if (online)
-            setVMRuntimeErrorCallbackF(mpVM, this, 0, "BrokenSharedFolder",
+            setVMRuntimeErrorCallbackF(ptrVM, this, 0, "BrokenSharedFolder",
                                        N_("Broken shared folder!"));
     }
@@ -6389,5 +6459,5 @@
 
     /* sanity checks */
-    AssertReturn(mpVM, E_FAIL);
+    AssertReturn(mpUVM, E_FAIL);
     AssertReturn(m_pVMMDev && m_pVMMDev->isShFlActive(), E_FAIL);
 
@@ -6494,5 +6564,5 @@
 
     /* sanity checks */
-    AssertReturn(mpVM, E_FAIL);
+    AssertReturn(mpUVM, E_FAIL);
     AssertReturn(m_pVMMDev && m_pVMMDev->isShFlActive(), E_FAIL);
 
@@ -6889,7 +6959,8 @@
     ComAssertComRCRetRC(hrc);
 
-    /* protect mpVM */
-    AutoVMCaller autoVMCaller(this);
-    if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
+    /* Get the VM handle. */
+    SafeVMPtr ptrVM(this);
+    if (!ptrVM.isOk())
+        return ptrVM.rc();
 
     LogFlowThisFunc(("Proxying USB device '%s' {%RTuuid}...\n",
@@ -6900,6 +6971,7 @@
 
 /** @todo just do everything here and only wrap the PDMR3Usb call. That'll offload some notification stuff from the EMT thread. */
-    int vrc = VMR3ReqCallWait(mpVM, VMCPUID_ANY,
-                              (PFNRT)usbAttachCallback, 6, this, aHostDevice, uuid.raw(), fRemote, Address.c_str(), aMaskedIfs);
+    int vrc = VMR3ReqCallWait(ptrVM, VMCPUID_ANY,
+                              (PFNRT)usbAttachCallback, 7,
+                              this, ptrVM.raw(), aHostDevice, uuid.raw(), fRemote, Address.c_str(), aMaskedIfs);
 
     /* restore the lock */
@@ -6911,5 +6983,5 @@
     {
         LogWarningThisFunc(("Failed to create proxy device for '%s' {%RTuuid} (%Rrc)\n",
-                             Address.c_str(), uuid.raw(), vrc));
+                            Address.c_str(), uuid.raw(), vrc));
 
         switch (vrc)
@@ -6945,5 +7017,5 @@
 //static
 DECLCALLBACK(int)
-Console::usbAttachCallback(Console *that, IUSBDevice *aHostDevice, PCRTUUID aUuid, bool aRemote, const char *aAddress, ULONG aMaskedIfs)
+Console::usbAttachCallback(Console *that, PVM pVM, IUSBDevice *aHostDevice, PCRTUUID aUuid, bool aRemote, const char *aAddress, ULONG aMaskedIfs)
 {
     LogFlowFuncEnter();
@@ -6968,5 +7040,5 @@
     Assert(portVersion == 1 || portVersion == 2);
 
-    int vrc = PDMR3USBCreateProxyDevice(that->mpVM, aUuid, aRemote, aAddress, pvRemoteBackend,
+    int vrc = PDMR3USBCreateProxyDevice(pVM, aUuid, aRemote, aAddress, pvRemoteBackend,
                                         portVersion == 1 ? VUSB_STDVER_11 : VUSB_STDVER_20, aMaskedIfs);
     if (RT_SUCCESS(vrc))
@@ -7008,13 +7080,14 @@
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
-    /* protect mpVM */
-    AutoVMCaller autoVMCaller(this);
-    if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
+    /* Get the VM handle. */
+    SafeVMPtr ptrVM(this);
+    if (!ptrVM.isOk())
+        return ptrVM.rc();
 
     /* if the device is attached, then there must at least one USB hub. */
-    AssertReturn(PDMR3USBHasHub(mpVM), E_FAIL);
+    AssertReturn(PDMR3USBHasHub(ptrVM), E_FAIL);
 
     LogFlowThisFunc(("Detaching USB proxy device {%RTuuid}...\n",
-                      (*aIt)->id().raw()));
+                     (*aIt)->id().raw()));
 
     /* leave the lock before a VMR3* call (EMT will call us back)! */
@@ -7022,6 +7095,7 @@
 
 /** @todo just do everything here and only wrap the PDMR3Usb call. That'll offload some notification stuff from the EMT thread. */
-    int vrc = VMR3ReqCallWait(mpVM, VMCPUID_ANY,
-                              (PFNRT) usbDetachCallback, 4, this, &aIt, (*aIt)->id().raw());
+    int vrc = VMR3ReqCallWait(ptrVM, VMCPUID_ANY,
+                              (PFNRT)usbDetachCallback, 5,
+                              this, ptrVM.raw(), &aIt, (*aIt)->id().raw());
     ComAssertRCRet(vrc, E_FAIL);
 
@@ -7040,5 +7114,5 @@
 //static
 DECLCALLBACK(int)
-Console::usbDetachCallback(Console *that, USBDeviceList::iterator *aIt, PCRTUUID aUuid)
+Console::usbDetachCallback(Console *that, PVM pVM, USBDeviceList::iterator *aIt, PCRTUUID aUuid)
 {
     LogFlowFuncEnter();
@@ -7064,5 +7138,5 @@
     }
 
-    int vrc = PDMR3USBDetachDevice(that->mpVM, aUuid);
+    int vrc = PDMR3USBDetachDevice(pVM, aUuid);
 
     if (RT_SUCCESS(vrc))
@@ -7731,5 +7805,5 @@
 
     /* sanity */
-    Assert(pConsole->mpVM == NULL);
+    Assert(pConsole->mpUVM == NULL);
 
     try
@@ -7956,5 +8030,5 @@
                     /* -> ConsoleImplTeleporter.cpp */
                     bool fPowerOffOnFailure;
-                    rc = pConsole->teleporterTrg(pVM, pMachine, &task->mErrorMsg, task->mStartPaused,
+                    rc = pConsole->teleporterTrg(VMR3GetUVM(pVM), pMachine, &task->mErrorMsg, task->mStartPaused,
                                                  task->mProgress, &fPowerOffOnFailure);
                     if (FAILED(rc) && fPowerOffOnFailure)
@@ -8060,5 +8134,6 @@
              * If VMR3Create() failed it has released the VM memory.
              */
-            pConsole->mpVM = NULL;
+            VMR3ReleaseUVM(pConsole->mpUVM);
+            pConsole->mpUVM = NULL;
         }
 
@@ -8107,5 +8182,5 @@
         ErrorInfoKeeper eik;
 
-        Assert(pConsole->mpVM == NULL);
+        Assert(pConsole->mpUVM == NULL);
         vmstateChangeCallback(NULL, VMSTATE_TERMINATED, VMSTATE_CREATING,
                               pConsole);
@@ -8232,6 +8307,6 @@
 static void takesnapshotProgressCancelCallback(void *pvUser)
 {
-    PVM pVM = (PVM)pvUser;
-    SSMR3Cancel(pVM);
+    PUVM pUVM = (PUVM)pvUser;
+    SSMR3Cancel(VMR3GetVM(pUVM));
 }
 
@@ -8308,11 +8383,15 @@
             Utf8Str strSavedStateFile(pTask->bstrSavedStateFile);
 
+            SafeVMPtr ptrVM(that);
+            if (!ptrVM.isOk())
+                throw ptrVM.rc();
+
             pTask->mProgress->SetNextOperation(Bstr(tr("Saving the machine state")).raw(),
                                                pTask->ulMemSize);       // operation weight, same as computed when setting up progress object
-            pTask->mProgress->setCancelCallback(takesnapshotProgressCancelCallback, that->mpVM);
+            pTask->mProgress->setCancelCallback(takesnapshotProgressCancelCallback, ptrVM.rawUVM());
 
             alock.leave();
             LogFlowFunc(("VMR3Save...\n"));
-            int vrc = VMR3Save(that->mpVM,
+            int vrc = VMR3Save(ptrVM,
                                strSavedStateFile.c_str(),
                                true /*fContinueAfterwards*/,
@@ -8391,10 +8470,10 @@
                  * isn't going to need the Console lock.
                  */
-                vrc = VMR3ReqCallWait(that->mpVM,
+                vrc = VMR3ReqCallWait(ptrVM,
                                       VMCPUID_ANY,
                                       (PFNRT)reconfigureMediumAttachment,
                                       13,
                                       that,
-                                      that->mpVM,
+                                      ptrVM.raw(),
                                       pcszDevice,
                                       lInstance,
@@ -8462,6 +8541,7 @@
             {
                 LogFlowFunc(("VMR3Resume...\n"));
+                SafeVMPtr ptrVM(that);
                 alock.leave();
-                int vrc = VMR3Resume(that->mpVM);
+                int vrc = VMR3Resume(ptrVM);
                 alock.enter();
                 if (RT_FAILURE(vrc))
@@ -8480,5 +8560,5 @@
             /** @todo this could probably be made more generic and reused elsewhere. */
             /* paranoid cleanup on for a failed online snapshot. */
-            VMSTATE enmVMState = VMR3GetState(that->mpVM);
+            VMSTATE enmVMState = VMR3GetStateU(that->mpUVM);
             switch (enmVMState)
             {
@@ -8519,6 +8599,7 @@
                         Assert(pTask->lastMachineState == MachineState_Running);
                         LogFlowFunc(("VMR3Resume (on failure)...\n"));
+                        SafeVMPtr ptrVM(that);
                         alock.leave();
-                        int vrc = VMR3Resume(that->mpVM); AssertLogRelRC(vrc);
+                        int vrc = VMR3Resume(ptrVM); AssertLogRelRC(vrc);
                         alock.enter();
                         if (RT_FAILURE(vrc))
@@ -8580,5 +8661,5 @@
 
     bool fSuspenededBySave;
-    int vrc = VMR3Save(that->mpVM,
+    int vrc = VMR3Save(task->mpVM,
                        task->mSavedStateFile.c_str(),
                        false, /*fContinueAfterwards*/
Index: trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 36037)
+++ trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 36041)
@@ -557,8 +557,12 @@
      * can easily reset the VM handle on failure.
      */
-    pConsole->mpVM = pVM;
+    PUVM pUVM = pConsole->mpUVM = VMR3GetUVM(pVM);
+    VMR3RetainUVM(pUVM);
     int vrc = pConsole->configConstructorInner(pVM, &alock);
     if (RT_FAILURE(vrc))
-        pConsole->mpVM = NULL;
+    {
+        pConsole->mpUVM = NULL;
+        VMR3ReleaseUVM(pUVM);
+    }
 
     return vrc;
@@ -3169,11 +3173,11 @@
                     Bstr loc;
                     hrc = pMedium->COMGETTER(Location)(loc.asOutParam());               H();
-                    setVMRuntimeErrorCallbackF(mpVM,
-                                            this,
-                                            0,
-                                            "DvdOrFloppyImageInaccessible",
-                                            "The image file '%ls' is inaccessible and is being ignored. Please select a different image file for the virtual %s drive.",
-                                            loc.raw(),
-                                            (enmType == DeviceType_DVD) ? "DVD" : "floppy");
+                    setVMRuntimeErrorCallbackF(VMR3GetVM(mpUVM),
+                                               this,
+                                               0,
+                                               "DvdOrFloppyImageInaccessible",
+                                               "The image file '%ls' is inaccessible and is being ignored. Please select a different image file for the virtual %s drive.",
+                                               loc.raw(),
+                                               enmType == DeviceType_DVD ? "DVD" : "floppy");
                     pMedium = NULL;
                 }
@@ -3391,5 +3395,6 @@
  *                               (makes only sense for bridged/host-only networks).
  *
- *  @note Locks this object for writing.
+ *  @note   Locks this object for writing.
+ *  @thread EMT
  */
 int Console::configNetwork(const char *pszDevice,
@@ -3422,5 +3427,5 @@
         AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
-        PVM pVM = mpVM;
+        PVM pVM = VMR3GetVM(mpUVM);     /* We're on an EMT, so this is safe. */
 
         ComPtr<IMachine> pMachine = machine();
@@ -3904,12 +3909,11 @@
                     {
                         struct ifreq Req;
-
-                        memset(&Req, 0, sizeof(Req));
+                        RT_ZERO(Req);
                         strncpy(Req.ifr_name, pszHifName, sizeof(Req.ifr_name) - 1);
                         if (ioctl(iSock, SIOCGIFFLAGS, &Req) >= 0)
                             if ((Req.ifr_flags & IFF_UP) == 0)
-                            {
-                                setVMRuntimeErrorCallbackF(pVM, this, 0, "BridgedInterfaceDown", "Bridged interface %s is down. Guest will not be able to use this interface", pszHifName);
-                            }
+                                setVMRuntimeErrorCallbackF(pVM, this, 0, "BridgedInterfaceDown",
+                                                           "Bridged interface %s is down. Guest will not be able to use this interface",
+                                                           pszHifName);
 
                         close(iSock);
Index: trunk/src/VBox/Main/src-client/ConsoleImplTeleporter.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/ConsoleImplTeleporter.cpp	(revision 36037)
+++ trunk/src/VBox/Main/src-client/ConsoleImplTeleporter.cpp	(revision 36041)
@@ -54,5 +54,5 @@
 public:
     ComPtr<Console>     mptrConsole;
-    PVM                 mpVM;
+    PUVM                mpUVM;
     ComObjPtr<Progress> mptrProgress;
     Utf8Str             mstrPassword;
@@ -69,7 +69,7 @@
     /** @} */
 
-    TeleporterState(Console *pConsole, PVM pVM, Progress *pProgress, bool fIsSource)
+    TeleporterState(Console *pConsole, PUVM pUVM, Progress *pProgress, bool fIsSource)
         : mptrConsole(pConsole)
-        , mpVM(pVM)
+        , mpUVM(pUVM)
         , mptrProgress(pProgress)
         , mfIsSource(fIsSource)
@@ -81,4 +81,11 @@
         , mfIOError(false)
     {
+        VMR3RetainUVM(mpUVM);
+    }
+
+    ~TeleporterState()
+    {
+        VMR3ReleaseUVM(mpUVM);
+        mpUVM = NULL;
     }
 };
@@ -98,6 +105,6 @@
     bool                mfUnlockedMedia;
 
-    TeleporterStateSrc(Console *pConsole, PVM pVM, Progress *pProgress, MachineState_T enmOldMachineState)
-        : TeleporterState(pConsole, pVM, pProgress, true /*fIsSource*/)
+    TeleporterStateSrc(Console *pConsole, PUVM pUVM, Progress *pProgress, MachineState_T enmOldMachineState)
+        : TeleporterState(pConsole, pUVM, pProgress, true /*fIsSource*/)
         , muPort(UINT32_MAX)
         , mcMsMaxDowntime(250)
@@ -124,8 +131,8 @@
     Utf8Str                     mErrorText;
 
-    TeleporterStateTrg(Console *pConsole, PVM pVM, Progress *pProgress,
+    TeleporterStateTrg(Console *pConsole, PUVM pUVM, Progress *pProgress,
                        IMachine *pMachine, IInternalMachineControl *pControl,
                        PRTTIMERLR phTimerLR, bool fStartPaused)
-        : TeleporterState(pConsole, pVM, pProgress, false /*fIsSource*/)
+        : TeleporterState(pConsole, pUVM, pProgress, false /*fIsSource*/)
         , mpMachine(pMachine)
         , mpControl(pControl)
@@ -566,5 +573,5 @@
 {
     TeleporterState *pState = (TeleporterState *)pvUser;
-    SSMR3Cancel(pState->mpVM);
+    SSMR3Cancel(VMR3GetVM(pState->mpUVM));
     if (!pState->mfIsSource)
     {
@@ -590,5 +597,5 @@
             if (SUCCEEDED(hrc) && fCanceled)
             {
-                SSMR3Cancel(pState->mpVM);
+                SSMR3Cancel(VMR3GetVM(pState->mpUVM));
                 return VERR_SSM_CANCELLED;
             }
@@ -678,7 +685,8 @@
     RTSocketRetain(pState->mhSocket);
     void *pvUser = static_cast<void *>(static_cast<TeleporterState *>(pState));
-    vrc = VMR3Teleport(pState->mpVM, pState->mcMsMaxDowntime,
-                       &g_teleporterTcpOps, pvUser,
-                       teleporterProgressCallback, pvUser,
+    vrc = VMR3Teleport(VMR3GetVM(pState->mpUVM),
+                       pState->mcMsMaxDowntime,
+                       &g_teleporterTcpOps,         pvUser,
+                       teleporterProgressCallback,  pvUser,
                        &pState->mfSuspendedByUs);
     RTSocketRelease(pState->mhSocket);
@@ -758,6 +766,6 @@
      * and do the cleanups afterwards.
      */
-    AutoVMCaller autoVMCaller(pState->mptrConsole);
-    HRESULT hrc = autoVMCaller.rc();
+    SafeVMPtr ptrVM(pState->mptrConsole);
+    HRESULT hrc = ptrVM.rc();
 
     if (SUCCEEDED(hrc))
@@ -786,5 +794,5 @@
     pState->mptrConsole->mptrCancelableProgress.setNull();
 
-    VMSTATE const        enmVMState      = VMR3GetState(pState->mpVM);
+    VMSTATE const        enmVMState      = VMR3GetStateU(pState->mpUVM);
     MachineState_T const enmMachineState = pState->mptrConsole->mMachineState;
     if (SUCCEEDED(hrc))
@@ -799,5 +807,5 @@
         AssertLogRelMsg(enmMachineState == MachineState_TeleportingPausedVM, ("%s\n", Global::stringifyMachineState(enmMachineState)));
 
-        autoVMCaller.release();
+        ptrVM.release();
 
         pState->mptrConsole->mVMIsAlreadyPoweringOff = true; /* (Make sure we stick in the TeleportingPausedVM state.) */
@@ -878,5 +886,5 @@
                         {
                             autoLock.leave();
-                            int rc = VMR3Resume(pState->mpVM);
+                            int rc = VMR3Resume(VMR3GetVM(pState->mpUVM));
                             AssertLogRelMsgRC(rc, ("VMR3Resume -> %Rrc\n", rc));
                             autoLock.enter();
@@ -955,11 +963,12 @@
     ComObjPtr<Progress> ptrProgress;
     HRESULT hrc = ptrProgress.createObject();
-    if (FAILED(hrc)) return hrc;
-    hrc = ptrProgress->init(static_cast<IConsole *>(this),
-                            Bstr(tr("Teleporter")).raw(),
-                            TRUE /*aCancelable*/);
-    if (FAILED(hrc)) return hrc;
-
-    TeleporterStateSrc *pState = new TeleporterStateSrc(this, mpVM, ptrProgress, mMachineState);
+    if (SUCCEEDED(hrc))
+        hrc = ptrProgress->init(static_cast<IConsole *>(this),
+                                Bstr(tr("Teleporter")).raw(),
+                                TRUE /*aCancelable*/);
+    if (FAILED(hrc))
+        return hrc;
+
+    TeleporterStateSrc *pState = new TeleporterStateSrc(this, mpUVM, ptrProgress, mMachineState);
     pState->mstrPassword    = aPassword;
     pState->mstrHostname    = aHostname;
@@ -1002,5 +1011,5 @@
  *
  * @returns VBox status code.
- * @param   pVM                 The VM handle
+ * @param   pUVM                The user-mode VM handle
  * @param   pMachine            The IMachine for the virtual machine.
  * @param   pErrorMsg           Pointer to the error string for VMSetError.
@@ -1015,8 +1024,8 @@
  */
 HRESULT
-Console::teleporterTrg(PVM pVM, IMachine *pMachine, Utf8Str *pErrorMsg, bool fStartPaused,
+Console::teleporterTrg(PUVM pUVM, IMachine *pMachine, Utf8Str *pErrorMsg, bool fStartPaused,
                        Progress *pProgress, bool *pfPowerOffOnFailure)
 {
-    LogThisFunc(("pVM=%p pMachine=%p fStartPaused=%RTbool pProgress=%p\n", pVM, pMachine, fStartPaused, pProgress));
+    LogThisFunc(("pUVM=%p pMachine=%p fStartPaused=%RTbool pProgress=%p\n", pUVM, pMachine, fStartPaused, pProgress));
 
     *pfPowerOffOnFailure = true;
@@ -1087,5 +1096,5 @@
              * Do the job, when it returns we're done.
              */
-            TeleporterStateTrg theState(this, pVM, pProgress, pMachine, mControl, &hTimerLR, fStartPaused);
+            TeleporterStateTrg theState(this, pUVM, pProgress, pMachine, mControl, &hTimerLR, fStartPaused);
             theState.mstrPassword      = strPassword;
             theState.mhServer          = hServer;
@@ -1111,5 +1120,5 @@
                         else
                         {
-                            VMSTATE enmVMState = VMR3GetState(pVM);
+                            VMSTATE enmVMState = VMR3GetStateU(pUVM);
                             if (    enmVMState != VMSTATE_OFF
                                 &&  enmVMState != VMSTATE_POWERING_OFF)
@@ -1320,14 +1329,16 @@
                 break;
 
-            int vrc2 = VMR3AtErrorRegister(pState->mpVM, Console::genericVMSetErrorCallback, &pState->mErrorText); AssertRC(vrc2);
+            int vrc2 = VMR3AtErrorRegisterU(pState->mpUVM,
+                                            Console::genericVMSetErrorCallback, &pState->mErrorText); AssertRC(vrc2);
             RTSocketRetain(pState->mhSocket); /* For concurrent access by I/O thread and EMT. */
             pState->moffStream = 0;
 
             void *pvUser2 = static_cast<void *>(static_cast<TeleporterState *>(pState));
-            vrc = VMR3LoadFromStream(pState->mpVM, &g_teleporterTcpOps, pvUser2,
+            vrc = VMR3LoadFromStream(VMR3GetVM(pState->mpUVM),
+                                     &g_teleporterTcpOps, pvUser2,
                                      teleporterProgressCallback, pvUser2);
 
             RTSocketRelease(pState->mhSocket);
-            vrc2 = VMR3AtErrorDeregister(pState->mpVM, Console::genericVMSetErrorCallback, &pState->mErrorText); AssertRC(vrc2);
+            vrc2 = VMR3AtErrorDeregister(VMR3GetVM(pState->mpUVM), Console::genericVMSetErrorCallback, &pState->mErrorText); AssertRC(vrc2);
 
             if (RT_FAILURE(vrc))
@@ -1392,5 +1403,5 @@
                 {
                     if (!strcmp(szCmd, "hand-over-resume"))
-                        vrc = VMR3Resume(pState->mpVM);
+                        vrc = VMR3Resume(VMR3GetVM(pState->mpUVM));
                     else
                         pState->mptrConsole->setMachineState(MachineState_Paused);
