Index: /trunk/doc/manual/en_US/SDKRef.xml
===================================================================
--- /trunk/doc/manual/en_US/SDKRef.xml	(revision 37524)
+++ /trunk/doc/manual/en_US/SDKRef.xml	(revision 37525)
@@ -3448,4 +3448,11 @@
       <itemizedlist>
         <listitem>
+          <para>The method <xref linkend="IVirtualBox__openMedium"
+          xreflabel="IVirtualBox::openMedium()" /> has one more parameter
+          now, which allows resolving duplicate medium UUIDs without the need
+          for external tools.</para>
+        </listitem>
+
+        <listitem>
           <para>The <xref linkend="INetworkAdapter" xreflabel="INetworkAdapter"/>
           interface has been cleaned up. The various methods to activate an
Index: /trunk/doc/manual/en_US/user_VBoxManage.xml
===================================================================
--- /trunk/doc/manual/en_US/user_VBoxManage.xml	(revision 37524)
+++ /trunk/doc/manual/en_US/user_VBoxManage.xml	(revision 37525)
@@ -1507,4 +1507,6 @@
                             [--mtype normal|writethrough|immutable|shareable]
                             [--comment &lt;text&gt;]
+                            [--setuuid &lt;uuid&gt;]
+                            [--setparentuuid &lt;uuid&gt;]
                             [--passthrough on|off]
                             [--bandwidthgroup name|none]
@@ -1643,4 +1645,19 @@
             server downstairs"). This is purely descriptive and not needed for
             the medium to function correctly.</para>
+          </glossdef>
+        </glossentry>
+
+        <glossentry>
+          <glossterm>setuuid, setparentuuid</glossterm>
+
+          <glossdef>
+            <para>Modifies the UUID or parent UUID of a medium before
+            attaching it to a VM. This is an expert option. Inappropriate use
+            can make the medium unusable or lead to broken VM configurations
+            if any other VM is referring to the same media already. The most
+            frequently used variant is <code>--setuuid ""</code>, which assigns
+            a new (random) UUID to an image. This is useful to resolve the
+            duplicate UUID errors if one duplicated an image using file copy
+            utilities.</para>
           </glossdef>
         </glossentry>
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h	(revision 37524)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h	(revision 37525)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -227,5 +227,5 @@
 HRESULT findOrOpenMedium(HandlerArg *a, const char *pszFilenameOrUuid,
                          DeviceType_T enmDevType, ComPtr<IMedium> &pMedium,
-                         bool *pfWasUnknown);
+                         bool fForceNewUuidOnOpen, bool *pfWasUnknown);
 int handleCreateHardDisk(HandlerArg *a);
 int handleModifyHardDisk(HandlerArg *a);
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp	(revision 37524)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp	(revision 37525)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -181,5 +181,5 @@
 HRESULT findOrOpenMedium(HandlerArg *a, const char *pszFilenameOrUuid,
                          DeviceType_T enmDevType, ComPtr<IMedium> &pMedium,
-                         bool *pfWasUnknown)
+                         bool fForceNewUuidOnOpen, bool *pfWasUnknown)
 {
     HRESULT rc;
@@ -207,4 +207,5 @@
         CHECK_ERROR(a->virtualBox, OpenMedium(Bstr(pszFilenameOrUuid).raw(),
                                               enmDevType, AccessMode_ReadWrite,
+                                              fForceNewUuidOnOpen,
                                               pMedium.asOutParam()));
         if (SUCCEEDED(rc))
@@ -476,5 +477,5 @@
     else
         rc = findOrOpenMedium(a, FilenameOrUuid, DeviceType_HardDisk,
-                              hardDisk, &unknown);
+                              hardDisk, false /* fForceNewUuidOnOpen */, &unknown);
     if (FAILED(rc))
         return 1;
@@ -630,5 +631,6 @@
     bool fDstUnknown = false;
 
-    rc = findOrOpenMedium(a, pszSrc, DeviceType_HardDisk, srcDisk, &fSrcUnknown);
+    rc = findOrOpenMedium(a, pszSrc, DeviceType_HardDisk, srcDisk,
+                          false /* fForceNewUuidOnOpen */, &fSrcUnknown);
     if (FAILED(rc))
         return 1;
@@ -639,5 +641,6 @@
         if (fExisting)
         {
-            rc = findOrOpenMedium(a, pszDst, DeviceType_HardDisk, dstDisk, &fDstUnknown);
+            rc = findOrOpenMedium(a, pszDst, DeviceType_HardDisk, dstDisk,
+                                  false /* fForceNewUuidOnOpen */, &fDstUnknown);
             if (FAILED(rc))
                 break;
@@ -925,5 +928,6 @@
     bool unknown = false;
 
-    rc = findOrOpenMedium(a, FilenameOrUuid, DeviceType_HardDisk, hardDisk, &unknown);
+    rc = findOrOpenMedium(a, FilenameOrUuid, DeviceType_HardDisk, hardDisk,
+                          false /* fForceNewUuidOnOpen */, &unknown);
     if (FAILED(rc))
         return 1;
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp	(revision 37524)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp	(revision 37525)
@@ -462,4 +462,6 @@
                      "                                     readonly|multiattach]\n"
                      "                            [--comment <text>]\n"
+                     "                            [--setuuid <uuid>]\n"
+                     "                            [--setparentuuid <uuid>]\n"
                      "                            [--passthrough on|off]\n"
                      "                            [--bandwidthgroup <name>]\n"
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp	(revision 37524)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp	(revision 37525)
@@ -712,5 +712,6 @@
                     ComPtr<IMedium> hardDisk;
                     rc = findOrOpenMedium(a, ValueUnion.psz, DeviceType_HardDisk,
-                                          hardDisk, NULL);
+                                          hardDisk, false /* fForceNewUuidOnOpen */,
+                                          NULL);
                     if (FAILED(rc))
                         break;
@@ -807,5 +808,6 @@
                     ComPtr<IMedium> hardDisk;
                     rc = findOrOpenMedium(a, ValueUnion.psz, DeviceType_HardDisk,
-                                          hardDisk, NULL);
+                                          hardDisk, false /* fForceNewUuidOnOpen */,
+                                          NULL);
                     if (FAILED(rc))
                         break;
@@ -934,5 +936,6 @@
                 {
                     rc = findOrOpenMedium(a, ValueUnion.psz, DeviceType_DVD,
-                                          dvdMedium, NULL);
+                                          dvdMedium, false /* fForceNewUuidOnOpen */,
+                                          NULL);
                     if (FAILED(rc))
                         break;
@@ -997,5 +1000,6 @@
                     {
                         rc = findOrOpenMedium(a, ValueUnion.psz, DeviceType_Floppy,
-                                              floppyMedium, NULL);
+                                              floppyMedium, false /* fForceNewUuidOnOpen */,
+                                              NULL);
                         if (FAILED(rc))
                             break;
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageStorageController.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageStorageController.cpp	(revision 37524)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageStorageController.cpp	(revision 37525)
@@ -55,4 +55,6 @@
     { "--forceunmount",     'f', RTGETOPT_REQ_NOTHING },
     { "--comment",          'C', RTGETOPT_REQ_STRING },
+    { "--setuuid",          'q', RTGETOPT_REQ_STRING },
+    { "--setparentuuid",    'Q', RTGETOPT_REQ_STRING },
     // iSCSI options
     { "--server",           'S', RTGETOPT_REQ_STRING },
@@ -74,4 +76,6 @@
     bool fForceUnmount = false;
     bool fSetMediumType = false;
+    bool fSetNewUuid = false;
+    bool fSetNewParentUuid = false;
     MediumType_T mediumType = MediumType_Normal;
     Bstr bstrComment;
@@ -81,4 +85,6 @@
     const char *pszPassThrough = NULL;
     const char *pszBandwidthGroup = NULL;
+    Bstr bstrNewUuid;
+    Bstr bstrNewParentUuid;
     // iSCSI options
     Bstr bstrServer;
@@ -181,5 +187,25 @@
                 else
                     rc = E_FAIL;
-            break;
+                break;
+
+            case 'q':
+                if (ValueUnion.psz)
+                {
+                    bstrNewUuid = ValueUnion.psz;
+                    fSetNewUuid = true;
+                }
+                else
+                    rc = E_FAIL;
+                break;
+
+            case 'Q':
+                if (ValueUnion.psz)
+                {
+                    bstrNewParentUuid = ValueUnion.psz;
+                    fSetNewParentUuid = true;
+                }
+                else
+                    rc = E_FAIL;
+                break;
 
             case 'S':   // --server
@@ -544,7 +570,16 @@
 
                 rc = findOrOpenMedium(a, pszMedium, devTypeRequested,
-                                      pMedium2Mount, NULL);
+                                      pMedium2Mount, fSetNewUuid, NULL);
                 if (FAILED(rc) || !pMedium2Mount)
                     throw Utf8StrFmt("Invalid UUID or filename \"%s\"", pszMedium);
+            }
+
+            // set medium/parent medium UUID, if so desired
+            if (fSetNewUuid || fSetNewParentUuid)
+            {
+                CHECK_ERROR(pMedium2Mount, SetIDs(fSetNewUuid, bstrNewUuid.raw(),
+                                                  fSetNewParentUuid, bstrNewParentUuid.raw()));
+                if (FAILED(rc))
+                    throw  Utf8Str("Failed to set the medium/parent medium UUID");
             }
 
Index: /trunk/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp	(revision 37524)
+++ /trunk/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp	(revision 37525)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -1459,5 +1459,6 @@
             RTPrintf("Adding hard disk '%s'...\n", hdaFile);
             pVirtualBox->OpenMedium(bstrHdaFile.raw(), DeviceType_HardDisk,
-                                    AccessMode_ReadWrite, pMedium.asOutParam());
+                                    AccessMode_ReadWrite, FALSE /* fForceNewUuid */,
+                                    pMedium.asOutParam());
         }
         /* do we have the right image now? */
@@ -1544,4 +1545,5 @@
                                                  DeviceType_Floppy,
                                                  AccessMode_ReadWrite,
+                                                 FALSE /* fForceNewUuid */,
                                                  pMedium.asOutParam()));
                 }
@@ -1624,4 +1626,5 @@
                                                  DeviceType_DVD,
                                                  AccessMode_ReadWrite,
+                                                 FALSE /* fForceNewUuid */,
                                                  pMedium.asOutParam()));
                 }
Index: /trunk/src/VBox/Frontends/VirtualBox/src/VBoxMediaManagerDlg.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/VBoxMediaManagerDlg.cpp	(revision 37524)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/VBoxMediaManagerDlg.cpp	(revision 37525)
@@ -7,5 +7,5 @@
 
 /*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -1651,5 +1651,5 @@
     }
 
-    CMedium med = mVBox.OpenMedium(aLocation, devType, KAccessMode_ReadWrite);
+    CMedium med = mVBox.OpenMedium(aLocation, devType, KAccessMode_ReadWrite, false /* fForceNewUuid */);
     if (mVBox.isOk())
         medium = VBoxMedium(CMedium(med), aType, KMediumState_Created);
Index: /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp	(revision 37524)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp	(revision 37525)
@@ -2754,5 +2754,5 @@
 
     /* Open corresponding medium: */
-    CMedium comMedium = vbox.OpenMedium(strMediumLocation, mediumTypeToGlobal(mediumType), KAccessMode_ReadWrite);
+    CMedium comMedium = vbox.OpenMedium(strMediumLocation, mediumTypeToGlobal(mediumType), KAccessMode_ReadWrite, false);
 
     if (vbox.isOk())
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp	(revision 37524)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp	(revision 37525)
@@ -7,5 +7,5 @@
 
 /*
- * Copyright (C) 2011 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -426,5 +426,5 @@
         if (image.isNull())
         {
-            image = vbox.OpenMedium(strSource, KDeviceType_DVD, KAccessMode_ReadWrite);
+            image = vbox.OpenMedium(strSource, KDeviceType_DVD, KAccessMode_ReadWrite, false /* fForceNewUuid */);
             if (vbox.isOk())
                 strUuid = image.GetId();
Index: /trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 37524)
+++ /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 37525)
@@ -1392,5 +1392,5 @@
   <interface
     name="IVirtualBox" extends="$unknown"
-    uuid="bc166b9b-9b62-4145-b1f6-6c39068aaf00"
+    uuid="d627bf11-2758-46be-9a4d-7d9ef794c247"
     wsmap="managed"
     >
@@ -1913,4 +1913,10 @@
         <desc>Whether to open the image in read/write or read-only mode. For
         a "DVD" device type, this is ignored and read-only mode is always assumed.</desc>
+      </param>
+      <param name="forceNewUuid" type="boolean" dir="in">
+        <desc>Allows the caller to request a completely new medium UUID for
+        the image which is to be opened. Useful if one intends to open an exact
+        copy of a previously opened image, as this would normally fail due to
+        the duplicate UUID.</desc>
       </param>
       <param name="medium" type="IMedium" dir="return">
Index: /trunk/src/VBox/Main/include/MediumImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/MediumImpl.h	(revision 37524)
+++ /trunk/src/VBox/Main/include/MediumImpl.h	(revision 37525)
@@ -7,5 +7,5 @@
 
 /*
- * Copyright (C) 2008-2010 Oracle Corporation
+ * Copyright (C) 2008-2011 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -78,4 +78,5 @@
                  const Utf8Str &aLocation,
                  HDDOpenMode enOpenMode,
+                 bool fForceNewUuid,
                  DeviceType_T aDeviceType);
 
Index: /trunk/src/VBox/Main/include/VirtualBoxImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/VirtualBoxImpl.h	(revision 37524)
+++ /trunk/src/VBox/Main/include/VirtualBoxImpl.h	(revision 37525)
@@ -140,4 +140,5 @@
                           DeviceType_T deviceType,
                           AccessMode_T accessMode,
+                          BOOL fForceNewUuid,
                           IMedium **aMedium);
     STDMETHOD(FindMedium)(IN_BSTR aLocation,
Index: /trunk/src/VBox/Main/src-server/MediumImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/MediumImpl.cpp	(revision 37524)
+++ /trunk/src/VBox/Main/src-server/MediumImpl.cpp	(revision 37525)
@@ -138,5 +138,7 @@
     bool autoReset : 1;
 
+    /** New UUID to be set on the next queryInfo() call. */
     const Guid uuidImage;
+    /** New parent UUID to be set on the next queryInfo() call. */
     const Guid uuidParentImage;
 
@@ -929,5 +931,5 @@
  * @param aFormat
  * @param aLocation     Storage unit location.
- * @param uuidMachineRegistry The registry to which this medium should be added (global registry UUI or medium UUID or empty if none).
+ * @param uuidMachineRegistry The registry to which this medium should be added (global registry UUID or machine UUID or empty if none).
  * @param pllRegistriesThatNeedSaving Optional list to receive the UUIDs of the media registries that need saving.
  */
@@ -1012,4 +1014,5 @@
  * @param aLocation     Storage unit location.
  * @param enOpenMode    Whether to open the medium read/write or read-only.
+ * @param fForceNewUuid Whether a new UUID should be set to avoid duplicates.
  * @param aDeviceType   Device type of medium.
  */
@@ -1017,4 +1020,5 @@
                      const Utf8Str &aLocation,
                      HDDOpenMode enOpenMode,
+                     bool fForceNewUuid,
                      DeviceType_T aDeviceType)
 {
@@ -1051,5 +1055,7 @@
 
     /* get all the information about the medium from the storage unit */
-    rc = queryInfo(false /* fSetImageId */, false /* fSetParentId */);
+    if (fForceNewUuid)
+        unconst(m->uuidImage).create();
+    rc = queryInfo(fForceNewUuid /* fSetImageId */, false /* fSetParentId */);
 
     if (SUCCEEDED(rc))
@@ -1089,5 +1095,5 @@
  * @param aParent       Parent medium disk or NULL for a root (base) medium.
  * @param aDeviceType   Device type of the medium.
- * @param uuidMachineRegistry The registry to which this medium should be added (global registry UUI or medium UUID).
+ * @param uuidMachineRegistry The registry to which this medium should be added (global registry UUID or machine UUID).
  * @param aNode         Configuration settings.
  * @param strMachineFolder The machine folder with which to resolve relative paths; if empty, then we use the VirtualBox home directory
@@ -1953,10 +1959,20 @@
     if (aSetImageId)
     {
-        imageId = Guid(aImageId);
-        if (imageId.isEmpty())
-            return setError(E_INVALIDARG, tr("Argument %s is empty"), "aImageId");
+        if (Bstr(aImageId).isEmpty())
+            imageId.create();
+        else
+        {
+            imageId = Guid(aImageId);
+            if (imageId.isEmpty())
+                return setError(E_INVALIDARG, tr("Argument %s is empty"), "aImageId");
+        }
     }
     if (aSetParentId)
-        parentId = Guid(aParentId);
+    {
+        if (Bstr(aParentId).isEmpty())
+            parentId.create();
+        else
+            parentId = Guid(aParentId);
+    }
 
     unconst(m->uuidImage) = imageId;
@@ -5090,7 +5106,7 @@
      * time in VirtualBox (such as VMDK for which VDOpen() needs to
      * generate an UUID if it is missing) */
-    if (    (m->hddOpenMode == OpenReadOnly)
+    if (    m->hddOpenMode == OpenReadOnly
          || m->type == MediumType_Readonly
-         || !isImport
+         || (!isImport && !fSetImageId && !fSetParentId)
        )
         uOpenFlags |= VD_OPEN_FLAGS_READONLY;
@@ -5169,4 +5185,5 @@
                     vrc = VDSetUuid(hdd, 0, m->uuidImage.raw());
                     ComAssertRCThrow(vrc, E_FAIL);
+                    mediumId = m->uuidImage;
                 }
                 if (fSetParentId)
@@ -5198,4 +5215,5 @@
                     if (mediumId != uuid)
                     {
+                        /** @todo r=klaus this always refers to VirtualBox.xml as the medium registry, even for new VMs */
                         lastAccessError = Utf8StrFmt(
                                 tr("UUID {%RTuuid} of the medium '%s' does not match the value {%RTuuid} stored in the media registry ('%s')"),
@@ -5213,11 +5231,13 @@
                  * underlying storage so use what we store in XML */
 
-                /* generate an UUID for an imported UUID-less medium */
-                if (isImport)
+                if (fSetImageId)
                 {
-                    if (fSetImageId)
-                        mediumId = m->uuidImage;
-                    else
-                        mediumId.create();
+                    /* set the UUID if an API client wants to change it */
+                    mediumId = m->uuidImage;
+                }
+                else if (isImport)
+                {
+                    /* generate an UUID for an imported UUID-less medium */
+                    mediumId.create();
                 }
             }
@@ -5305,4 +5325,5 @@
                         && m->pParent->getId() != parentId)
                     {
+                        /** @todo r=klaus this always refers to VirtualBox.xml as the medium registry, even for new VMs */
                         lastAccessError = Utf8StrFmt(
                                 tr("Parent UUID {%RTuuid} of the medium '%s' does not match UUID {%RTuuid} of its parent medium stored in the media registry ('%s')"),
@@ -5338,5 +5359,5 @@
     alock.enter();
 
-    if (isImport)
+    if (isImport || fSetImageId)
         unconst(m->id) = mediumId;
 
Index: /trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp	(revision 37524)
+++ /trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp	(revision 37525)
@@ -1482,4 +1482,5 @@
                                     DeviceType_T deviceType,
                                     AccessMode_T accessMode,
+                                    BOOL fForceNewUuid,
                                     IMedium **aMedium)
 {
@@ -1529,4 +1530,5 @@
                            aLocation,
                            (accessMode == AccessMode_ReadWrite) ? Medium::OpenReadWrite : Medium::OpenReadOnly,
+                           fForceNewUuid,
                            deviceType);
 
Index: /trunk/src/VBox/Main/testcase/tstVBoxAPILinux.cpp
===================================================================
--- /trunk/src/VBox/Main/testcase/tstVBoxAPILinux.cpp	(revision 37524)
+++ /trunk/src/VBox/Main/testcase/tstVBoxAPILinux.cpp	(revision 37525)
@@ -8,5 +8,5 @@
 
 /*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2011 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -359,4 +359,5 @@
                                 DeviceType_DVD,
                                 AccessMode_ReadOnly,
+                                false /* fForceNewUuid */,
                                 getter_AddRefs(dvdImage));
     if (NS_FAILED(rc))
