Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp	(revision 53353)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp	(revision 53354)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2013 Oracle Corporation
+ * Copyright (C) 2006-2014 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -481,4 +481,6 @@
             { "clonevm",          USAGE_CLONEVM,           handleCloneVM },
             { "hdproperty",       USAGE_HDPROPERTY,        handleMediumProperty },
+            { "createdvd",        USAGE_CREATEDVD,         handleCreateDVD },
+            { "createfloppy",     USAGE_CREATEFLOPPY,      handleCreateFloppy },
             { "createhd",         USAGE_CREATEHD,          handleCreateHardDisk },
             { "createvdi",        USAGE_CREATEHD,          handleCreateHardDisk }, /* backward compatibility */
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h	(revision 53353)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h	(revision 53354)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2013 Oracle Corporation
+ * Copyright (C) 2006-2014 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -105,4 +105,6 @@
 #define USAGE_NATNETWORK            RT_BIT_64(59)
 #define USAGE_HDPROPERTY            RT_BIT_64(60)
+#define USAGE_CREATEFLOPPY          RT_BIT_64(61)
+#define USAGE_CREATEDVD             RT_BIT_64(62)
 #define USAGE_ALL                   (~(uint64_t)0)
 /** @} */
@@ -259,4 +261,6 @@
                    bool fSilent);
 int handleCreateHardDisk(HandlerArg *a);
+int handleCreateDVD(HandlerArg *a);
+int handleCreateFloppy(HandlerArg *a);
 int handleModifyHardDisk(HandlerArg *a);
 int handleCloneHardDisk(HandlerArg *a);
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp	(revision 53353)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp	(revision 53354)
@@ -187,4 +187,58 @@
 }
 
+static HRESULT createFloppy(HandlerArg *a, const char *pszFormat,
+                            const char *pszFilename, ComPtr<IMedium> &pMedium)
+{
+    HRESULT rc;
+    char szFilenameAbs[RTPATH_MAX] = "";
+
+    /** @todo laziness shortcut. should really check the MediumFormatCapabilities */
+    if (RTStrICmp(pszFormat, "iSCSI"))
+    {
+        int irc = RTPathAbs(pszFilename, szFilenameAbs, sizeof(szFilenameAbs));
+        if (RT_FAILURE(irc))
+        {
+            RTMsgError("Cannot convert filename \"%s\" to absolute path", pszFilename);
+            return E_FAIL;
+        }
+        pszFilename = szFilenameAbs;
+    }
+
+    CHECK_ERROR(a->virtualBox, CreateMedium(Bstr(pszFormat).raw(),
+                                            Bstr(pszFilename).raw(),
+                                            AccessMode_ReadWrite,
+                                            TRUE,
+                                            DeviceType_Floppy,
+                                            pMedium.asOutParam()));
+    return rc;
+}
+
+static HRESULT createDVD(HandlerArg *a, const char *pszFormat,
+                        const char *pszFilename, ComPtr<IMedium> &pMedium)
+{
+    HRESULT rc;
+    char szFilenameAbs[RTPATH_MAX] = "";
+
+    /** @todo laziness shortcut. should really check the MediumFormatCapabilities */
+    if (RTStrICmp(pszFormat, "iSCSI"))
+    {
+        int irc = RTPathAbs(pszFilename, szFilenameAbs, sizeof(szFilenameAbs));
+        if (RT_FAILURE(irc))
+        {
+            RTMsgError("Cannot convert filename \"%s\" to absolute path", pszFilename);
+            return E_FAIL;
+        }
+        pszFilename = szFilenameAbs;
+    }
+
+    CHECK_ERROR(a->virtualBox, CreateMedium(Bstr(pszFormat).raw(),
+                                            Bstr(pszFilename).raw(),
+                                            AccessMode_ReadWrite,
+                                            TRUE,
+                                            DeviceType_DVD,
+                                            pMedium.asOutParam()));
+    return rc;
+}
+
 static HRESULT createHardDisk(HandlerArg *a, const char *pszFormat,
                               const char *pszFilename, ComPtr<IMedium> &pMedium)
@@ -399,4 +453,346 @@
 
         CHECK_ERROR(hardDisk, Close());
+    }
+    return SUCCEEDED(rc) ? 0 : 1;
+}
+
+int handleCreateFloppy(HandlerArg *a)
+{
+    HRESULT rc;
+    int vrc;
+    const char *filename = NULL;
+    const char *diffparent = NULL;
+    uint64_t size = 0;
+    const char *format = NULL;
+    bool fBase = true;
+    MediumVariant_T DiskVariant = MediumVariant_Standard;
+
+    int c;
+    RTGETOPTUNION ValueUnion;
+    RTGETOPTSTATE GetState;
+    // start at 0 because main() has hacked both the argc and argv given to us
+    RTGetOptInit(&GetState, a->argc, a->argv, g_aCreateHardDiskOptions, RT_ELEMENTS(g_aCreateHardDiskOptions),
+                 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+    while ((c = RTGetOpt(&GetState, &ValueUnion)))
+    {
+        switch (c)
+        {
+            case 'f':   // --filename
+                filename = ValueUnion.psz;
+                break;
+
+            case 'd':   // --diffparent
+                diffparent = ValueUnion.psz;
+                fBase = false;
+                break;
+
+            case 's':   // --size
+                size = ValueUnion.u64 * _1M;
+                break;
+
+            case 'S':   // --sizebyte
+                size = ValueUnion.u64;
+                break;
+
+            case 'o':   // --format
+                format = ValueUnion.psz;
+                break;
+
+            case 'F':   // --static ("fixed"/"flat")
+            {
+                unsigned uDiskVariant = (unsigned)DiskVariant;
+                uDiskVariant |= MediumVariant_Fixed;
+                DiskVariant = (MediumVariant_T)uDiskVariant;
+                break;
+            }
+
+            case 'm':   // --variant
+                vrc = parseDiskVariant(ValueUnion.psz, &DiskVariant);
+                if (RT_FAILURE(vrc))
+                    return errorArgument("Invalid medium variant '%s'", ValueUnion.psz);
+                break;
+
+            case VINF_GETOPT_NOT_OPTION:
+                return errorSyntax(USAGE_CREATEFLOPPY, "Invalid parameter '%s'", ValueUnion.psz);
+
+            default:
+                if (c > 0)
+                {
+                    if (RT_C_IS_PRINT(c))
+                        return errorSyntax(USAGE_CREATEFLOPPY, "Invalid option -%c", c);
+                    else
+                        return errorSyntax(USAGE_CREATEFLOPPY, "Invalid option case %i", c);
+                }
+                else if (c == VERR_GETOPT_UNKNOWN_OPTION)
+                    return errorSyntax(USAGE_CREATEFLOPPY, "unknown option: %s\n", ValueUnion.psz);
+                else if (ValueUnion.pDef)
+                    return errorSyntax(USAGE_CREATEFLOPPY, "%s: %Rrs", ValueUnion.pDef->pszLong, c);
+                else
+                    return errorSyntax(USAGE_CREATEFLOPPY, "error: %Rrs", c);
+        }
+    }
+
+    /* check the outcome */
+    ComPtr<IMedium> parentMedium;
+    if (fBase)
+    {
+        if (   !filename
+            || !*filename
+            || size == 0)
+            return errorSyntax(USAGE_CREATEHD, "Parameters --filename and --size are required");
+        if (!format || !*format)
+            format = "RAW";
+    }
+    else
+    {
+        if (   !filename
+            || !*filename)
+            return errorSyntax(USAGE_CREATEHD, "Parameters --filename is required");
+        size = 0;
+        DiskVariant = MediumVariant_Diff;
+        if (!format || !*format)
+        {
+            const char *pszExt = RTPathSuffix(filename);
+            /* Skip over . if there is an extension. */
+            if (pszExt)
+                pszExt++;
+            if (!pszExt || !*pszExt)
+                format = "RAW";
+            else
+                format = pszExt;
+        }
+        rc = openMedium(a, diffparent, DeviceType_Floppy,
+                        AccessMode_ReadWrite, parentMedium,
+                        false /* fForceNewUuidOnOpen */, false /* fSilent */);
+        if (FAILED(rc))
+            return 1;
+        if (parentMedium.isNull())
+        {
+            RTMsgError("Invalid parent medium reference, avoiding crash");
+            return 1;
+        }
+        MediumState_T state;
+        CHECK_ERROR(parentMedium, COMGETTER(State)(&state));
+        if (FAILED(rc))
+            return 1;
+        if (state == MediumState_Inaccessible)
+        {
+            CHECK_ERROR(parentMedium, RefreshState(&state));
+            if (FAILED(rc))
+                return 1;
+        }
+    }
+    /* check for filename extension */
+    /** @todo use IMediumFormat to cover all extensions generically */
+    Utf8Str strName(filename);
+    if (!RTPathHasSuffix(strName.c_str()))
+    {
+        Utf8Str strFormat(format);
+        strName.append(".raw");
+        filename = strName.c_str();
+    }
+
+    ComPtr<IMedium> medium;
+    rc = createFloppy(a, format, filename, medium);
+    if (SUCCEEDED(rc) && medium)
+    {
+        ComPtr<IProgress> progress;
+        com::SafeArray<MediumVariant_T> l_variants(sizeof(MediumVariant_T)*8);
+
+        for (ULONG i = 0; i < l_variants.size(); ++i)
+        {
+            ULONG temp = DiskVariant;
+            temp &= 1<<i;
+            l_variants [i] = (MediumVariant_T)temp;
+        }
+
+        if (fBase)
+            CHECK_ERROR(medium, CreateBaseStorage(size, ComSafeArrayAsInParam(l_variants), progress.asOutParam()));
+        else
+            CHECK_ERROR(parentMedium, CreateDiffStorage(medium, ComSafeArrayAsInParam(l_variants), progress.asOutParam()));
+        if (SUCCEEDED(rc) && progress)
+        {
+            rc = showProgress(progress);
+            CHECK_PROGRESS_ERROR(progress, ("Failed to create Floppy"));
+            if (SUCCEEDED(rc))
+            {
+                Bstr uuid;
+                CHECK_ERROR(medium, COMGETTER(Id)(uuid.asOutParam()));
+                RTPrintf("Disk image created. UUID: %s\n", Utf8Str(uuid).c_str());
+            }
+        }
+
+        CHECK_ERROR(medium, Close());
+    }
+    return SUCCEEDED(rc) ? 0 : 1;
+}
+
+int handleCreateDVD(HandlerArg *a)
+{
+    HRESULT rc;
+    int vrc;
+    const char *filename = NULL;
+    const char *diffparent = NULL;
+    uint64_t size = 0;
+    const char *format = NULL;
+    bool fBase = true;
+    MediumVariant_T DiskVariant = MediumVariant_Standard;
+
+    int c;
+    RTGETOPTUNION ValueUnion;
+    RTGETOPTSTATE GetState;
+    // start at 0 because main() has hacked both the argc and argv given to us
+    RTGetOptInit(&GetState, a->argc, a->argv, g_aCreateHardDiskOptions, RT_ELEMENTS(g_aCreateHardDiskOptions),
+                 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
+    while ((c = RTGetOpt(&GetState, &ValueUnion)))
+    {
+        switch (c)
+        {
+            case 'f':   // --filename
+                filename = ValueUnion.psz;
+                break;
+
+            case 'd':   // --diffparent
+                diffparent = ValueUnion.psz;
+                fBase = false;
+                break;
+
+            case 's':   // --size
+                size = ValueUnion.u64 * _1M;
+                break;
+
+            case 'S':   // --sizebyte
+                size = ValueUnion.u64;
+                break;
+
+            case 'o':   // --format
+                format = ValueUnion.psz;
+                break;
+
+            case 'F':   // --static ("fixed"/"flat")
+            {
+                unsigned uDiskVariant = (unsigned)DiskVariant;
+                uDiskVariant |= MediumVariant_Fixed;
+                DiskVariant = (MediumVariant_T)uDiskVariant;
+                break;
+            }
+
+            case 'm':   // --variant
+                vrc = parseDiskVariant(ValueUnion.psz, &DiskVariant);
+                if (RT_FAILURE(vrc))
+                    return errorArgument("Invalid medium variant '%s'", ValueUnion.psz);
+                break;
+
+            case VINF_GETOPT_NOT_OPTION:
+                return errorSyntax(USAGE_CREATEDVD, "Invalid parameter '%s'", ValueUnion.psz);
+
+            default:
+                if (c > 0)
+                {
+                    if (RT_C_IS_PRINT(c))
+                        return errorSyntax(USAGE_CREATEDVD, "Invalid option -%c", c);
+                    else
+                        return errorSyntax(USAGE_CREATEDVD, "Invalid option case %i", c);
+                }
+                else if (c == VERR_GETOPT_UNKNOWN_OPTION)
+                    return errorSyntax(USAGE_CREATEDVD, "unknown option: %s\n", ValueUnion.psz);
+                else if (ValueUnion.pDef)
+                    return errorSyntax(USAGE_CREATEDVD, "%s: %Rrs", ValueUnion.pDef->pszLong, c);
+                else
+                    return errorSyntax(USAGE_CREATEDVD, "error: %Rrs", c);
+        }
+    }
+
+    /* check the outcome */
+    ComPtr<IMedium> parentMedium;
+    if (fBase)
+    {
+        if (   !filename
+            || !*filename
+            || size == 0)
+            return errorSyntax(USAGE_CREATEHD, "Parameters --filename and --size are required");
+        if (!format || !*format)
+            format = "ISO";
+    }
+    else
+    {
+        if (   !filename
+            || !*filename)
+            return errorSyntax(USAGE_CREATEHD, "Parameters --filename is required");
+        size = 0;
+        DiskVariant = MediumVariant_Diff;
+        if (!format || !*format)
+        {
+            const char *pszExt = RTPathSuffix(filename);
+            /* Skip over . if there is an extension. */
+            if (pszExt)
+                pszExt++;
+            if (!pszExt || !*pszExt)
+                format = "ISO";
+            else
+                format = pszExt;
+        }
+        rc = openMedium(a, diffparent, DeviceType_DVD,
+                        AccessMode_ReadWrite, parentMedium,
+                        false /* fForceNewUuidOnOpen */, false /* fSilent */);
+        if (FAILED(rc))
+            return 1;
+        if (parentMedium.isNull())
+        {
+            RTMsgError("Invalid parent hard disk reference, avoiding crash");
+            return 1;
+        }
+        MediumState_T state;
+        CHECK_ERROR(parentMedium, COMGETTER(State)(&state));
+        if (FAILED(rc))
+            return 1;
+        if (state == MediumState_Inaccessible)
+        {
+            CHECK_ERROR(parentMedium, RefreshState(&state));
+            if (FAILED(rc))
+                return 1;
+        }
+    }
+    /* check for filename extension */
+    /** @todo use IMediumFormat to cover all extensions generically */
+    Utf8Str strName(filename);
+    if (!RTPathHasSuffix(strName.c_str()))
+    {
+        Utf8Str strFormat(format);
+        strName.append(".iso");
+        filename = strName.c_str();
+    }
+
+    ComPtr<IMedium> medium;
+    rc = createDVD(a, format, filename, medium);
+    if (SUCCEEDED(rc) && medium)
+    {
+        ComPtr<IProgress> progress;
+        com::SafeArray<MediumVariant_T> l_variants(sizeof(MediumVariant_T)*8);
+
+        for (ULONG i = 0; i < l_variants.size(); ++i)
+        {
+            ULONG temp = DiskVariant;
+            temp &= 1<<i;
+            l_variants [i] = (MediumVariant_T)temp;
+        }
+
+        if (fBase)
+            CHECK_ERROR(medium, CreateBaseStorage(size, ComSafeArrayAsInParam(l_variants), progress.asOutParam()));
+        else
+            CHECK_ERROR(parentMedium, CreateDiffStorage(medium, ComSafeArrayAsInParam(l_variants), progress.asOutParam()));
+        if (SUCCEEDED(rc) && progress)
+        {
+            rc = showProgress(progress);
+            CHECK_PROGRESS_ERROR(progress, ("Failed to create DVD"));
+            if (SUCCEEDED(rc))
+            {
+                Bstr uuid;
+                CHECK_ERROR(medium, COMGETTER(Id)(uuid.asOutParam()));
+                RTPrintf("Disk image created. UUID: %s\n", Utf8Str(uuid).c_str());
+            }
+        }
+
+        CHECK_ERROR(medium, Close());
     }
     return SUCCEEDED(rc) ? 0 : 1;
Index: /trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 53353)
+++ /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 53354)
@@ -1813,5 +1813,5 @@
   <interface
     name="IVirtualBox" extends="$unknown"
-    uuid="fafa4e17-1ee2-4905-a10e-fe7c18bf5554"
+    uuid="5e67bc8a-5f8f-11e4-aa15-123b93f75cba"
     wsmap="managed"
     >
@@ -2281,4 +2281,88 @@
       <param name="appliance" type="IAppliance" dir="return">
         <desc>New appliance.</desc>
+      </param>
+    </method>
+
+    <method name="createMedium">
+      <desc>
+        Creates a new base medium object that will use the given storage
+        format and location for medium data.
+
+        The actual storage unit is not created by this method. In order to
+        do it, and before you are able to attach the created medium to
+        virtual machines, you must call one of the following methods to
+        allocate a format-specific storage unit at the specified location:
+        <ul>
+          <li><link to="IMedium::createBaseStorage"/></li>
+          <li><link to="IMedium::createDiffStorage"/></li>
+        </ul>
+
+        Some medium attributes, such as <link to="IMedium::id"/>, may
+        remain uninitialized until the medium storage unit is successfully
+        created by one of the above methods.
+
+        Depending on the given device type, the file at the storage location
+        must be in one of the media formats understood by VirtualBox:
+
+        <ul>
+          <li>With a "HardDisk" device type, the file must be a hard disk image
+            in one of the formats supported by VirtualBox (see
+            <link to="ISystemProperties::mediumFormats" />).
+            After the storage unit is successfully created and this method succeeds, 
+            if the medium is a base medium, it
+            will be added to the <link to="#hardDisks"/> array attribute. </li>
+          <li>With a "DVD" device type, the file must be an ISO 9960 CD/DVD image.
+            After this method succeeds, the medium will be added to the
+            <link to="#DVDImages"/> array attribute.</li>
+          <li>With a "Floppy" device type, the file must be an RAW floppy image.
+            After this method succeeds, the medium will be added to the
+            <link to="#floppyImages"/> array attribute.</li>
+        </ul>
+
+        The list of all storage formats supported by this VirtualBox
+        installation can be obtained using
+        <link to="ISystemProperties::mediumFormats"/>. If the @a format
+        attribute is empty or @c null then the default storage format
+        specified by <link to="ISystemProperties::defaultHardDiskFormat"/> will
+        be used for disks r creating a storage unit of the medium.
+
+        Note that the format of the location string is storage format specific.
+        See <link to="IMedium::location"/> and IMedium for more details.
+
+        <result name="VBOX_E_OBJECT_NOT_FOUND">
+          @a format identifier is invalid. See
+          <link to="ISystemProperties::mediumFormats"/>.
+        </result>
+        <result name="VBOX_E_FILE_ERROR">
+          @a location is a not valid file name (for file-based formats only).
+        </result>
+      </desc>
+      <param name="format" type="wstring" dir="in">
+        <desc>
+          Identifier of the storage format to use for the new medium.
+        </desc>
+      </param>
+      <param name="location" type="wstring" dir="in">
+        <desc>
+          Location of the storage unit for the new medium.
+        </desc>
+      </param>
+      <param name="accessMode" type="AccessMode" dir="in">
+        <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="aDeviceTypeType" type="DeviceType" dir="in">
+        <desc>
+          Must be one of "HardDisk", "DVD" or "Floppy".
+        </desc>
+      </param>
+      <param name="medium" type="IMedium" dir="return">
+        <desc>Created medium object.</desc>
       </param>
     </method>
Index: /trunk/src/VBox/Main/include/MediumImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/MediumImpl.h	(revision 53353)
+++ /trunk/src/VBox/Main/include/MediumImpl.h	(revision 53354)
@@ -18,4 +18,5 @@
  */
 
+
 #ifndef ____H_MEDIUMIMPL
 #define ____H_MEDIUMIMPL
@@ -55,9 +56,10 @@
     // public initializer/uninitializer for internal purposes only
 
-    // initializer to create empty medium (VirtualBox::CreateHardDisk())
+    // initializer to create empty medium (VirtualBox::CreateMedium())
     HRESULT init(VirtualBox *aVirtualBox,
                  const Utf8Str &aFormat,
                  const Utf8Str &aLocation,
-                 const Guid &uuidMachineRegistry);
+                 const Guid &uuidMachineRegistry,
+                 const DeviceType_T aDeviceType);
 
     // initializer for opening existing media
Index: /trunk/src/VBox/Main/include/VirtualBoxImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/VirtualBoxImpl.h	(revision 53353)
+++ /trunk/src/VBox/Main/include/VirtualBoxImpl.h	(revision 53354)
@@ -217,5 +217,6 @@
     int i_calculateFullPath(const Utf8Str &strPath, Utf8Str &aResult);
     void i_copyPathRelativeToConfig(const Utf8Str &strSource, Utf8Str &strTarget);
-    HRESULT i_registerMedium(const ComObjPtr<Medium> &pMedium, ComObjPtr<Medium> *ppMedium, DeviceType_T argType, AutoWriteLock &mediaTreeLock);
+    HRESULT i_registerMedium(const ComObjPtr<Medium> &pMedium, ComObjPtr<Medium> *ppMedium, DeviceType_T argType,
+                             AutoWriteLock &mediaTreeLock);
     HRESULT i_unregisterMedium(Medium *pMedium);
     void i_pushMediumToListWithChildren(MediaList &llMedia, Medium *pMedium);
@@ -240,4 +241,6 @@
     void i_storeSettingsKey(const Utf8Str &aKey);
     bool i_isMediaUuidInUse(const Guid &aId, DeviceType_T deviceType);
+
+
 
 private:
@@ -295,4 +298,10 @@
                            const com::Utf8Str &aLocation,
                            ComPtr<IMedium> &aMedium);
+    HRESULT createMedium(const com::Utf8Str &aFormat,
+                         const com::Utf8Str &aLocation,
+                         AccessMode_T aAccessMode,
+                         BOOL aForceNewUuid,
+                         DeviceType_T aDeviceType,
+                         ComPtr<IMedium> &aMedium);
     HRESULT openMedium(const com::Utf8Str &aLocation,
                        DeviceType_T aDeviceType,
Index: /trunk/src/VBox/Main/src-server/ApplianceImplImport.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/ApplianceImplImport.cpp	(revision 53353)
+++ /trunk/src/VBox/Main/src-server/ApplianceImplImport.cpp	(revision 53354)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2008-2013 Oracle Corporation
+ * Copyright (C) 2008-2014 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -751,5 +751,8 @@
     }
 
-    AssertReturn(!(m->optListImport.contains(ImportOptions_KeepAllMACs) && m->optListImport.contains(ImportOptions_KeepNATMACs)), E_INVALIDARG);
+    AssertReturn(!(m->optListImport.contains
+                   (ImportOptions_KeepAllMACs)
+                   && m->optListImport.contains(ImportOptions_KeepNATMACs)
+                  ), E_INVALIDARG);
 
     // do not allow entering this method if the appliance is busy reading or writing
@@ -2513,5 +2516,6 @@
                                      strTrgFormat,
                                      *strTargetPath,
-                                     Guid::Empty /* media registry: none yet */);
+                                     Guid::Empty /* media registry: none yet */,
+                                     DeviceType_HardDisk);
                 if (FAILED(rc)) throw rc;
 
Index: /trunk/src/VBox/Main/src-server/MachineImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/MachineImpl.cpp	(revision 53353)
+++ /trunk/src/VBox/Main/src-server/MachineImpl.cpp	(revision 53354)
@@ -4093,5 +4093,6 @@
                         medium->i_getPreferredDiffFormat(),
                         strFullSnapshotFolder.append(RTPATH_SLASH_STR),
-                        uuidRegistryParent);
+                        uuidRegistryParent,
+                        DeviceType_HardDisk);
         if (FAILED(rc)) return rc;
 
@@ -10586,5 +10587,6 @@
                             pMedium->i_getPreferredDiffFormat(),
                             strFullSnapshotFolder.append(RTPATH_SLASH_STR),
-                            uuidRegistryParent);
+                            uuidRegistryParent,
+                            DeviceType_HardDisk);
             if (FAILED(rc)) throw rc;
 
Index: /trunk/src/VBox/Main/src-server/MachineImplCloneVM.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/MachineImplCloneVM.cpp	(revision 53353)
+++ /trunk/src/VBox/Main/src-server/MachineImplCloneVM.cpp	(revision 53354)
@@ -677,5 +677,6 @@
                         pParent->i_getPreferredDiffFormat(),
                         Utf8StrFmt("%s%c", strSnapshotFolder.c_str(), RTPATH_DELIMITER),
-                                   Guid::Empty /* empty media registry */);
+                                   Guid::Empty /* empty media registry */,
+                                   DeviceType_HardDisk);
         if (FAILED(rc)) throw rc;
 
@@ -1204,5 +1205,6 @@
                                            Utf8Str(bstrSrcFormat),
                                            strFile,
-                                           Guid::Empty /* empty media registry */);
+                                           Guid::Empty /* empty media registry */,
+                                           DeviceType_HardDisk);
                         if (FAILED(rc)) throw rc;
 
Index: /trunk/src/VBox/Main/src-server/MediumImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/MediumImpl.cpp	(revision 53353)
+++ /trunk/src/VBox/Main/src-server/MediumImpl.cpp	(revision 53354)
@@ -15,5 +15,4 @@
  * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
  */
-
 #include "MediumImpl.h"
 #include "TokenImpl.h"
@@ -899,9 +898,11 @@
  * @param uuidMachineRegistry The registry to which this medium should be added
  *                            (global registry UUID or machine UUID or empty if none).
+ * @param deviceType    Device Type.
  */
 HRESULT Medium::init(VirtualBox *aVirtualBox,
                      const Utf8Str &aFormat,
                      const Utf8Str &aLocation,
-                     const Guid &uuidMachineRegistry)
+                     const Guid &uuidMachineRegistry,
+                     const DeviceType_T aDeviceType)
 {
     AssertReturn(aVirtualBox != NULL, E_FAIL);
@@ -925,4 +926,6 @@
     m->hostDrive = false;
 
+    m->devType = aDeviceType;
+
     /* No storage unit is created yet, no need to call Medium::i_queryInfo */
 
@@ -937,6 +940,6 @@
        )
     {
-        /* Storage for hard disks of this format can neither be explicitly
-         * created by VirtualBox nor deleted, so we place the hard disk to
+        /* Storage for mediums of this format can neither be explicitly
+         * created by VirtualBox nor deleted, so we place the medium to
          * Inaccessible state here and also add it to the registry. The
          * state means that one has to use RefreshState() to update the
@@ -959,5 +962,5 @@
             bool fInUse;
 
-            fInUse = m->pVirtualBox->i_isMediaUuidInUse(m->id, DeviceType_HardDisk);
+            fInUse = m->pVirtualBox->i_isMediaUuidInUse(m->id, aDeviceType);
             if (fInUse)
             {
@@ -969,5 +972,5 @@
         }
 
-        rc = m->pVirtualBox->i_registerMedium(this, &pMedium, DeviceType_HardDisk, treeLock);
+        rc = m->pVirtualBox->i_registerMedium(this, &pMedium, aDeviceType, treeLock);
         Assert(this == pMedium || FAILED(rc));
     }
@@ -6076,5 +6079,5 @@
  */
 HRESULT Medium::i_setLocation(const Utf8Str &aLocation,
-                            const Utf8Str &aFormat /* = Utf8Str::Empty */)
+                              const Utf8Str &aFormat /* = Utf8Str::Empty */)
 {
     AssertReturn(!aLocation.isEmpty(), E_FAIL);
Index: /trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp	(revision 53353)
+++ /trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp	(revision 53354)
@@ -1740,16 +1740,65 @@
 {
     /* we don't access non-const data members so no need to lock */
+    HRESULT rc = createMedium(aFormat, aLocation, AccessMode_ReadWrite, TRUE, DeviceType_HardDisk, aMedium);
+
+    return rc;
+}
+
+HRESULT VirtualBox::createMedium(const com::Utf8Str &aFormat,
+                                 const com::Utf8Str &aLocation,
+                                 AccessMode_T aAccessMode,
+                                 BOOL aForceNewUuid,
+                                 DeviceType_T aDeviceType,
+                                 ComPtr<IMedium> &aMedium)
+{
+    HRESULT rc = S_OK;
+
+    ComObjPtr<Medium> medium;
+    medium.createObject();
     com::Utf8Str format = aFormat;
-    if (format.isEmpty())
-        i_getDefaultHardDiskFormat(format);
-
-    ComObjPtr<Medium> hardDisk;
-    hardDisk.createObject();
-    HRESULT rc = hardDisk->init(this,
-                                format,
-                                aLocation,
-                                Guid::Empty /* media registry: none yet */);
+
+    switch (aDeviceType)
+    {
+        case DeviceType_HardDisk:
+        {
+
+            /* we don't access non-const data members so no need to lock */
+            if (format.isEmpty())
+                i_getDefaultHardDiskFormat(format);
+
+            rc = medium->init(this,
+                              format,
+                              aLocation,
+                              Guid::Empty /* media registry: none yet */,
+                              aDeviceType);
+        }
+        break;
+
+        case DeviceType_DVD:
+        case DeviceType_Floppy:
+        {
+
+            if (format.isEmpty())
+                return setError(E_INVALIDARG, "Format must be Valid Type%s", format.c_str());
+
+            // enforce read-only for DVDs even if caller specified ReadWrite
+            if (aDeviceType == DeviceType_DVD)
+                aAccessMode = AccessMode_ReadOnly;
+
+             rc = medium->init(this,
+                               format,
+                               aLocation,
+                               Guid::Empty /* media registry: none yet */,
+                               aDeviceType);
+
+         }
+         break;
+
+         default:
+             return setError(E_INVALIDARG, "Device type must be HardDisk, DVD or Floppy %d", aDeviceType);
+    }
+
     if (SUCCEEDED(rc))
-        hardDisk.queryInterfaceTo(aMedium.asOutParam());
+        medium.queryInterfaceTo(aMedium.asOutParam());
 
     return rc;
@@ -1788,8 +1837,8 @@
             if (id.isValid() && !id.isZero())
                 rc = i_findDVDOrFloppyImage(aDeviceType, &id, Utf8Str::Empty,
-                                          false /* setError */, &pMedium);
+                                            false /* setError */, &pMedium);
             else
                 rc = i_findDVDOrFloppyImage(aDeviceType, NULL, aLocation,
-                                          false /* setError */, &pMedium);
+                                            false /* setError */, &pMedium);
 
             // enforce read-only for DVDs even if caller specified ReadWrite
