Index: /trunk/src/VBox/Main/src-server/MachineImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/MachineImpl.cpp	(revision 55727)
+++ /trunk/src/VBox/Main/src-server/MachineImpl.cpp	(revision 55728)
@@ -3208,5 +3208,4 @@
 HRESULT Machine::lockMachine(const ComPtr<ISession> &aSession,
                              LockType_T aLockType)
-
 {
     /* check the session state */
@@ -3260,5 +3259,4 @@
 
         // copy pointers to W (the write-locking session) before leaving lock (these must not be NULL)
-        ComAssertRet(mData->mSession.mLockType == LockType_Write || mData->mSession.mLockType == LockType_VM, E_FAIL);
         ComPtr<IInternalSessionControl> pSessionW = mData->mSession.mDirectControl;
         ComAssertRet(!pSessionW.isNull(), E_FAIL);
@@ -10008,5 +10006,6 @@
             // a saved state in the current state, so keep everything as is
          || (    (   mData->mMachineState == MachineState_Snapshotting
-                  || mData->mMachineState == MachineState_DeletingSnapshot)
+                  || mData->mMachineState == MachineState_DeletingSnapshot
+                  || mData->mMachineState == MachineState_RestoringSnapshot)
               && (!mSSData->strStateFilePath.isEmpty())
             )
Index: /trunk/src/VBox/Main/src-server/MediumImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/MediumImpl.cpp	(revision 55727)
+++ /trunk/src/VBox/Main/src-server/MediumImpl.cpp	(revision 55728)
@@ -4647,4 +4647,24 @@
                            tr("Medium format '%s' does not support storage deletion"),
                            m->strFormat.c_str());
+
+        /* Wait for a concurrently running Medium::i_queryInfo to complete. */
+        /** @todo r=klaus would be great if this could be moved to the async
+         * part of the operation as it can take quite a while */
+        if (m->queryInfoRunning)
+        {
+            while (m->queryInfoRunning)
+            {
+                multilock.release();
+                /* Must not hold the media tree lock or the object lock, as
+                 * Medium::i_queryInfo needs this lock and thus we would run
+                 * into a deadlock here. */
+                Assert(!m->pVirtualBox->i_getMediaTreeLockHandle().isWriteLockOnCurrentThread());
+                Assert(!isWriteLockOnCurrentThread());
+                {
+                    AutoReadLock qlock(m->queryInfoSem COMMA_LOCKVAL_SRC_POS);
+                }
+                multilock.acquire();
+            }
+        }
 
         /* Note that we are fine with Inaccessible state too: a) for symmetry
Index: /trunk/src/VBox/Main/src-server/SnapshotImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/SnapshotImpl.cpp	(revision 55727)
+++ /trunk/src/VBox/Main/src-server/SnapshotImpl.cpp	(revision 55728)
@@ -1796,4 +1796,7 @@
     task.m_pProgress->i_notifyComplete(rc);
 
+    if (SUCCEEDED(rc))
+        mParent->i_onSnapshotTaken(mData->mUuid,
+                                   task.m_pSnapshot->i_getId());
     LogFlowThisFuncLeave();
 }
@@ -1864,8 +1867,4 @@
         /* associate old hard disks with the snapshot and do locking/unlocking*/
         i_commitMedia(task.m_fTakingSnapshotOnline);
-
-        /* inform callbacks */
-        mParent->i_onSnapshotTaken(mData->mUuid,
-                                   task.m_pSnapshot->i_getId());
         alock.release();
     }
@@ -2039,6 +2038,4 @@
 
     HRESULT rc = S_OK;
-
-    bool stateRestored = false;
 
     try
@@ -2161,9 +2158,7 @@
          * state accordingly no matter of the delete snapshot result */
         if (mSSData->strStateFilePath.isNotEmpty())
-            i_setMachineState(MachineState_Saved);
+            task.modifyBackedUpState(MachineState_Saved);
         else
-            i_setMachineState(MachineState_PoweredOff);
-
-        stateRestored = true;
+            task.modifyBackedUpState(MachineState_PoweredOff);
 
         /* Paranoia: no one must have saved the settings in the mean time. If
@@ -2252,12 +2247,10 @@
         i_rollback(false /* aNotify */);
 
-        if (!stateRestored)
-        {
-            /* restore the machine state */
-            i_setMachineState(task.m_machineStateBackup);
-        }
     }
 
     mParent->i_saveModifiedRegistries();
+
+    /* restore the machine state */
+    i_setMachineState(task.m_machineStateBackup);
 
     /* set the result (this will try to fetch current error info on failure) */
