Index: /trunk/src/VBox/Main/src-server/MediumImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/MediumImpl.cpp	(revision 36980)
+++ /trunk/src/VBox/Main/src-server/MediumImpl.cpp	(revision 36981)
@@ -239,5 +239,5 @@
     PVDINTERFACE mVDOperationIfaces;
 
-    // Whether the caller needs to call VirtualBox::saveSettings() after
+    // Whether the caller needs to call VirtualBox::saveRegistries() after
     // the task function returns. Only used in synchronous (wait) mode;
     // otherwise the task will save the settings itself.
@@ -1312,6 +1312,4 @@
     m->strDescription = aDescription;
 
-/// @todo generate uuid (similarly to host network interface uuid) from location and device type
-
     autoInitSpan.setSucceeded();
     return S_OK;
@@ -2257,9 +2255,9 @@
 
     GuidList llRegistriesThatNeedSaving;
-    HRESULT rc = close(&llRegistriesThatNeedSaving, autoCaller);
-
-    pVirtualBox->saveRegistries(llRegistriesThatNeedSaving);
-
-    return rc;
+    MultiResult mrc = close(&llRegistriesThatNeedSaving, autoCaller);
+    /* Must save the registries, since an entry was most likely removed. */
+    mrc = pVirtualBox->saveRegistries(llRegistriesThatNeedSaving);
+
+    return mrc;
 }
 
@@ -2476,13 +2474,14 @@
 
     GuidList llRegistriesThatNeedSaving;
-    HRESULT rc = deleteStorage(&pProgress,
-                               false /* aWait */,
-                               &llRegistriesThatNeedSaving);
-    m->pVirtualBox->saveRegistries(llRegistriesThatNeedSaving);
-
-    if (SUCCEEDED(rc))
+    MultiResult mrc = deleteStorage(&pProgress,
+                                    false /* aWait */,
+                                    &llRegistriesThatNeedSaving);
+    /* Must save the registries in any case, since an entry was removed. */
+    mrc = m->pVirtualBox->saveRegistries(llRegistriesThatNeedSaving);
+
+    if (SUCCEEDED(mrc))
         pProgress.queryInterfaceTo(aProgress);
 
-    return rc;
+    return mrc;
 }
 
@@ -3792,5 +3791,5 @@
  *                          creating an asynchronous thread.
  * @param pllRegistriesThatNeedSaving Optional pointer to a list of UUIDs that will receive the registry IDs that need saving.
- *                          This only works in "wait" mode; otherwise saveSettings is called automatically by the thread that
+ *                          This only works in "wait" mode; otherwise saveRegistries is called automatically by the thread that
  *                          was created, and this parameter is ignored.
  *
@@ -3929,5 +3928,5 @@
 /**
  * Implementation for the public Medium::Close() with the exception of calling
- * VirtualBox::saveSettings(), in case someone wants to call this for several
+ * VirtualBox::saveRegistries(), in case someone wants to call this for several
  * media.
  *
@@ -4013,6 +4012,6 @@
  *                      an asynchronous thread.
  * @param pfNeedsGlobalSaveSettings Optional pointer to a bool that must have been initialized to false and that will be set to true
- *                by this function if the caller should invoke VirtualBox::saveSettings() because the global settings have changed.
- *                This only works in "wait" mode; otherwise saveSettings gets called automatically by the thread that was created,
+ *                by this function if the caller should invoke VirtualBox::saveRegistries() because the global settings have changed.
+ *                This only works in "wait" mode; otherwise saveRegistries gets called automatically by the thread that was created,
  *                and this parameter is ignored.
  *
@@ -4631,6 +4630,6 @@
  *                      an asynchronous thread.
  * @param pfNeedsGlobalSaveSettings Optional pointer to a bool that must have been initialized to false and that will be set to true
- *                by this function if the caller should invoke VirtualBox::saveSettings() because the global settings have changed.
- *                This only works in "wait" mode; otherwise saveSettings gets called automatically by the thread that was created,
+ *                by this function if the caller should invoke VirtualBox::saveRegistries() because the global settings have changed.
+ *                This only works in "wait" mode; otherwise saveRegistries gets called automatically by the thread that was created,
  *                and this parameter is ignored.
  *
@@ -4845,8 +4844,8 @@
         catch (int aVRC)
         {
-            throw setError(E_FAIL,
-                            tr("Could not update medium UUID references to parent '%s' (%s)"),
-                            m->strLocationFull.c_str(),
-                            vdError(aVRC).c_str());
+            rc = setError(E_FAIL,
+                          tr("Could not update medium UUID references to parent '%s' (%s)"),
+                          m->strLocationFull.c_str(),
+                          vdError(aVRC).c_str());
         }
 
@@ -6274,5 +6273,5 @@
 HRESULT Medium::taskCreateDiffHandler(Medium::CreateDiffTask &task)
 {
-    HRESULT rc = S_OK;
+    HRESULT rcTmp = S_OK;
 
     const ComObjPtr<Medium> &pTarget = task.mTarget;
@@ -6357,5 +6356,5 @@
             if (capabilities & VD_CAP_FILE)
             {
-                rc = VirtualBox::ensureFilePathExists(targetLocation);
+                HRESULT rc = VirtualBox::ensureFilePathExists(targetLocation);
                 if (FAILED(rc))
                     throw rc;
@@ -6384,11 +6383,13 @@
                 variant = (MediumVariant_T)uImageFlags;
         }
-        catch (HRESULT aRC) { rc = aRC; }
+        catch (HRESULT aRC) { rcTmp = aRC; }
 
         VDDestroy(hdd);
     }
-    catch (HRESULT aRC) { rc = aRC; }
-
-    if (SUCCEEDED(rc))
+    catch (HRESULT aRC) { rcTmp = aRC; }
+
+    MultiResult mrc(rcTmp);
+
+    if (SUCCEEDED(mrc))
     {
         AutoWriteLock treeLock(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS);
@@ -6408,7 +6409,7 @@
          * Created state only on success (leaving an orphan file is
          * better than breaking media registry consistency) */
-        rc = m->pVirtualBox->registerHardDisk(pTarget, &llRegistriesThatNeedSaving);
-
-        if (FAILED(rc))
+        mrc = m->pVirtualBox->registerHardDisk(pTarget, &llRegistriesThatNeedSaving);
+
+        if (FAILED(mrc))
             /* break the parent association on failure to register */
             deparent();
@@ -6417,5 +6418,5 @@
     AutoMultiWriteLock2 mediaLock(this, pTarget COMMA_LOCKVAL_SRC_POS);
 
-    if (SUCCEEDED(rc))
+    if (SUCCEEDED(mrc))
     {
         pTarget->m->state = MediumState_Created;
@@ -6444,5 +6445,5 @@
     {
         mediaLock.release();
-        m->pVirtualBox->saveRegistries(llRegistriesThatNeedSaving);
+        mrc = m->pVirtualBox->saveRegistries(llRegistriesThatNeedSaving);
     }
     else
@@ -6454,5 +6455,5 @@
      * unlock the medium. */
 
-    return rc;
+    return mrc;
 }
 
@@ -6471,5 +6472,5 @@
 HRESULT Medium::taskMergeHandler(Medium::MergeTask &task)
 {
-    HRESULT rc = S_OK;
+    HRESULT rcTmp = S_OK;
 
     const ComObjPtr<Medium> &pTarget = task.mTarget;
@@ -6598,21 +6599,23 @@
             }
         }
-        catch (HRESULT aRC) { rc = aRC; }
+        catch (HRESULT aRC) { rcTmp = aRC; }
         catch (int aVRC)
         {
-            throw setError(VBOX_E_FILE_ERROR,
-                            tr("Could not merge the medium '%s' to '%s'%s"),
-                            m->strLocationFull.c_str(),
-                            pTarget->m->strLocationFull.c_str(),
-                            vdError(aVRC).c_str());
+            rcTmp = setError(VBOX_E_FILE_ERROR,
+                             tr("Could not merge the medium '%s' to '%s'%s"),
+                             m->strLocationFull.c_str(),
+                             pTarget->m->strLocationFull.c_str(),
+                             vdError(aVRC).c_str());
         }
 
         VDDestroy(hdd);
     }
-    catch (HRESULT aRC) { rc = aRC; }
-
+    catch (HRESULT aRC) { rcTmp = aRC; }
+
+    ErrorInfoKeeper eik;
+    MultiResult mrc(rcTmp);
     HRESULT rc2;
 
-    if (SUCCEEDED(rc))
+    if (SUCCEEDED(mrc))
     {
         /* all media but the target were successfully deleted by
@@ -6731,5 +6734,8 @@
         GuidList llRegistriesThatNeedSaving;
         addToRegistryIDList(llRegistriesThatNeedSaving);
-        rc = m->pVirtualBox->saveRegistries(llRegistriesThatNeedSaving);
+        /* collect multiple errors */
+        eik.restore();
+        mrc = m->pVirtualBox->saveRegistries(llRegistriesThatNeedSaving);
+        eik.fetch();
     }
     else
@@ -6738,10 +6744,10 @@
             pTarget->addToRegistryIDList(*task.m_pllRegistriesThatNeedSaving);
 
-    if (FAILED(rc))
+    if (FAILED(mrc))
     {
         /* Here we come if either VDMerge() failed (in which case we
          * assume that it tried to do everything to make a further
          * retry possible -- e.g. not deleted intermediate media
-         * and so on) or VirtualBox::saveSettings() failed (where we
+         * and so on) or VirtualBox::saveRegistries() failed (where we
          * should have the original tree but with intermediate storage
          * units deleted by VDMerge()). We have to only restore states
@@ -6757,5 +6763,5 @@
     }
 
-    return rc;
+    return mrc;
 }
 
@@ -6771,5 +6777,5 @@
 HRESULT Medium::taskCloneHandler(Medium::CloneTask &task)
 {
-    HRESULT rc = S_OK;
+    HRESULT rcTmp = S_OK;
 
     const ComObjPtr<Medium> &pTarget = task.mTarget;
@@ -6853,5 +6859,5 @@
             if (capabilities & VD_CAP_FILE)
             {
-                rc = VirtualBox::ensureFilePathExists(targetLocation);
+                HRESULT rc = VirtualBox::ensureFilePathExists(targetLocation);
                 if (FAILED(rc))
                     throw rc;
@@ -6932,16 +6938,19 @@
                     variant = (MediumVariant_T)uImageFlags;
             }
-            catch (HRESULT aRC) { rc = aRC; }
+            catch (HRESULT aRC) { rcTmp = aRC; }
 
             VDDestroy(targetHdd);
         }
-        catch (HRESULT aRC) { rc = aRC; }
+        catch (HRESULT aRC) { rcTmp = aRC; }
 
         VDDestroy(hdd);
     }
-    catch (HRESULT aRC) { rc = aRC; }
+    catch (HRESULT aRC) { rcTmp = aRC; }
+
+    ErrorInfoKeeper eik;
+    MultiResult mrc(rcTmp);
 
     /* Only do the parent changes for newly created media. */
-    if (SUCCEEDED(rc) && fCreatingTarget)
+    if (SUCCEEDED(mrc) && fCreatingTarget)
     {
         /* we set mParent & children() */
@@ -6960,7 +6969,9 @@
              * Created state only on success (leaving an orphan file is
              * better than breaking media registry consistency) */
-            rc = pParent->m->pVirtualBox->registerHardDisk(pTarget, NULL /* pllRegistriesThatNeedSaving */);
-
-            if (FAILED(rc))
+            eik.restore();
+            mrc = pParent->m->pVirtualBox->registerHardDisk(pTarget, NULL /* pllRegistriesThatNeedSaving */);
+            eik.fetch();
+
+            if (FAILED(mrc))
                 /* break parent association on failure to register */
                 pTarget->deparent();     // removes target from parent
@@ -6969,5 +6980,7 @@
         {
             /* just register  */
-            rc = m->pVirtualBox->registerHardDisk(pTarget, NULL /* pllRegistriesThatNeedSaving */);
+            eik.restore();
+            mrc = m->pVirtualBox->registerHardDisk(pTarget, NULL /* pllRegistriesThatNeedSaving */);
+            eik.fetch();
         }
     }
@@ -6977,5 +6990,5 @@
         AutoWriteLock mLock(pTarget COMMA_LOCKVAL_SRC_POS);
 
-        if (SUCCEEDED(rc))
+        if (SUCCEEDED(mrc))
         {
             pTarget->m->state = MediumState_Created;
@@ -7001,5 +7014,8 @@
         GuidList llRegistriesThatNeedSaving;
         addToRegistryIDList(llRegistriesThatNeedSaving);
-        HRESULT rc1 = m->pVirtualBox->saveRegistries(llRegistriesThatNeedSaving);
+        /* collect multiple errors */
+        eik.restore();
+        mrc = m->pVirtualBox->saveRegistries(llRegistriesThatNeedSaving);
+        eik.fetch();
     }
 
@@ -7012,5 +7028,5 @@
     task.mpSourceMediumLockList->Clear();
 
-    return rc;
+    return mrc;
 }
 
@@ -7553,5 +7569,5 @@
 HRESULT Medium::taskImportHandler(Medium::ImportTask &task)
 {
-    HRESULT rc = S_OK;
+    HRESULT rcTmp = S_OK;
 
     const ComObjPtr<Medium> &pParent = task.mParent;
@@ -7617,5 +7633,5 @@
             if (capabilities & VD_CAP_FILE)
             {
-                rc = VirtualBox::ensureFilePathExists(targetLocation);
+                HRESULT rc = VirtualBox::ensureFilePathExists(targetLocation);
                 if (FAILED(rc))
                     throw rc;
@@ -7696,16 +7712,19 @@
                     variant = (MediumVariant_T)uImageFlags;
             }
-            catch (HRESULT aRC) { rc = aRC; }
+            catch (HRESULT aRC) { rcTmp = aRC; }
 
             VDDestroy(targetHdd);
         }
-        catch (HRESULT aRC) { rc = aRC; }
+        catch (HRESULT aRC) { rcTmp = aRC; }
 
         VDDestroy(hdd);
     }
-    catch (HRESULT aRC) { rc = aRC; }
+    catch (HRESULT aRC) { rcTmp = aRC; }
+
+    ErrorInfoKeeper eik;
+    MultiResult mrc(rcTmp);
 
     /* Only do the parent changes for newly created media. */
-    if (SUCCEEDED(rc) && fCreatingTarget)
+    if (SUCCEEDED(mrc) && fCreatingTarget)
     {
         /* we set mParent & children() */
@@ -7724,7 +7743,9 @@
              * Created state only on success (leaving an orphan file is
              * better than breaking media registry consistency) */
-            rc = pParent->m->pVirtualBox->registerHardDisk(this, NULL /* llRegistriesThatNeedSaving */);
-
-            if (FAILED(rc))
+            eik.restore();
+            mrc = pParent->m->pVirtualBox->registerHardDisk(this, NULL /* llRegistriesThatNeedSaving */);
+            eik.fetch();
+
+            if (FAILED(mrc))
                 /* break parent association on failure to register */
                 this->deparent();     // removes target from parent
@@ -7733,5 +7754,7 @@
         {
             /* just register  */
-            rc = m->pVirtualBox->registerHardDisk(this, NULL /* pllRegistriesThatNeedSaving */);
+            eik.restore();
+            mrc = m->pVirtualBox->registerHardDisk(this, NULL /* pllRegistriesThatNeedSaving */);
+            eik.fetch();
         }
     }
@@ -7741,5 +7764,5 @@
         AutoWriteLock mLock(this COMMA_LOCKVAL_SRC_POS);
 
-        if (SUCCEEDED(rc))
+        if (SUCCEEDED(mrc))
         {
             m->state = MediumState_Created;
@@ -7765,5 +7788,8 @@
         GuidList llRegistriesThatNeedSaving;
         addToRegistryIDList(llRegistriesThatNeedSaving);
-        HRESULT rc1 = m->pVirtualBox->saveRegistries(llRegistriesThatNeedSaving);
+        /* collect multiple errors */
+        eik.restore();
+        mrc = m->pVirtualBox->saveRegistries(llRegistriesThatNeedSaving);
+        eik.fetch();
     }
 
@@ -7775,5 +7801,5 @@
     task.mpTargetMediumLockList->Clear();
 
-    return rc;
+    return mrc;
 }
 
