Index: trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 48973)
+++ trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 48983)
@@ -18312,5 +18312,5 @@
   <enum
     name="StorageBus"
-    uuid="eee67ab3-668d-4ef5-91e0-7025fe4a0d7a"
+    uuid="2dab9df1-9683-48fd-8c11-caada236fcb0"
     >
     <desc>
@@ -18326,9 +18326,10 @@
     <const name="Floppy"    value="4"/>
     <const name="SAS"       value="5"/>
+    <const name="USB"       value="6"/>
   </enum>
 
   <enum
     name="StorageControllerType"
-    uuid="8a412b8a-f43e-4456-bd37-b474f0879a58"
+    uuid="02e190af-b546-4109-b036-6deaa4ef6e69"
     >
     <desc>
@@ -18363,4 +18364,7 @@
     <const name="LsiLogicSas"   value="8">
       <desc>A variant of the LsiLogic controller using SAS.</desc>
+    </const>
+    <const name="USB"           value="9">
+      <desc>Special USB based storage controller.</desc>
     </const>
   </enum>
Index: trunk/src/VBox/Main/include/ConsoleImpl.h
===================================================================
--- trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 48973)
+++ trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 48983)
@@ -51,4 +51,5 @@
 class DisplayMouseInterface;
 
+#include <iprt/uuid.h>
 #include <VBox/RemoteDesktop/VRDE.h>
 #include <VBox/vmm/pdmdrv.h>
@@ -497,7 +498,22 @@
     };
 
+    /**
+     * Class for managing emulated USB MSDs.
+     */
+    class USBStorageDevice
+    {
+    public:
+        USBStorageDevice()
+        { }
+        /** The UUID associated with the USB device. */
+        RTUUID   mUuid;
+        /** Port of the storage device. */
+        LONG     iPort;
+    };
+
     typedef std::map<Utf8Str, ComObjPtr<SharedFolder> > SharedFolderMap;
     typedef std::map<Utf8Str, SharedFolderData> SharedFolderDataMap;
     typedef std::map<Utf8Str, ComPtr<IMediumAttachment> > MediumAttachmentMap;
+    typedef std::list <USBStorageDevice> USBStorageDeviceList;
 
 private:
@@ -827,5 +843,7 @@
         iLedSas     = iLedScsi + cLedScsi,
         cLedSas     = 8,
-        cLedStorage = cLedFloppy + cLedIde + cLedSata + cLedScsi + cLedSas
+        iLedUsb     = iLedSas + cLedSas,
+        cLedUsb     = 8,
+        cLedStorage = cLedFloppy + cLedIde + cLedSata + cLedScsi + cLedSas + cLedUsb
     };
     DeviceType_T maStorageDevType[cLedStorage];
@@ -836,4 +854,7 @@
 
     MediumAttachmentMap mapMediumAttachments;
+
+    /** List of attached USB storage devices. */
+    USBStorageDeviceList mUSBStorageDevices;
 
 /* Note: FreeBSD needs this whether netflt is used or not. */
Index: trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 48973)
+++ trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 48983)
@@ -3462,4 +3462,6 @@
         case StorageControllerType_I82078:
             return "i82078";
+        case StorageControllerType_USB:
+            return "Msd";
         default:
             return NULL;
@@ -3484,4 +3486,13 @@
         {
             uLun = port;
+            return S_OK;
+        }
+        case StorageBus_USB:
+        {
+             /*
+              * It is always the first lun, the port denotes the device instance
+              * for the Msd device.
+              */
+            uLun = 0;
             return S_OK;
         }
@@ -3940,7 +3951,15 @@
     }
 
-    /* Determine the base path for the device instance. */
+    /*
+     * Determine the base path for the device instance. USB Msd devices are handled different
+     * because the PDM USB API requires a differnet CFGM tree when attaching a new USB device.
+     */
     PCFGMNODE pCtlInst;
-    pCtlInst = CFGMR3GetChildF(CFGMR3GetRootU(pUVM), "Devices/%s/%u/", pcszDevice, uInstance);
+
+    if (enmBus == StorageBus_USB)
+        pCtlInst = CFGMR3CreateTree(pUVM);
+    else
+        pCtlInst = CFGMR3GetChildF(CFGMR3GetRootU(pUVM), "Devices/%s/%u/", pcszDevice, uInstance);
+
     AssertReturn(pCtlInst, VERR_INTERNAL_ERROR);
 
@@ -3967,5 +3986,6 @@
     /** @todo this dumps everything attached to this device instance, which
      * is more than necessary. Dumping the changed LUN would be enough. */
-    CFGMR3Dump(pCtlInst);
+    if (enmBus != StorageBus_USB)
+        CFGMR3Dump(pCtlInst);
 
     /*
@@ -4186,5 +4206,5 @@
     PCFGMNODE pCtlInst;
     pCtlInst = CFGMR3GetChildF(CFGMR3GetRootU(pUVM), "Devices/%s/%u/", pcszDevice, uInstance);
-    AssertReturn(pCtlInst, VERR_INTERNAL_ERROR);
+    AssertReturn(pCtlInst || enmBus == StorageBus_USB, VERR_INTERNAL_ERROR);
 
 #define H()         AssertMsgReturn(!FAILED(hrc), ("hrc=%Rhrc\n", hrc), VERR_GENERAL_FAILURE)
@@ -4207,27 +4227,45 @@
 #undef H
 
-    /* First check if the LUN really exists. */
-    pLunL0 = CFGMR3GetChildF(pCtlInst, "LUN#%u", uLUN);
-    if (pLunL0)
-    {
-        uint32_t fFlags = 0;
-
-        if (fSilent)
-            fFlags |= PDM_TACH_FLAGS_NOT_HOT_PLUG;
-
-        rc = PDMR3DeviceDetach(pUVM, pcszDevice, uInstance, uLUN, fFlags);
-        if (rc == VERR_PDM_NO_DRIVER_ATTACHED_TO_LUN)
-            rc = VINF_SUCCESS;
+    if (enmBus != StorageBus_USB)
+    {
+        /* First check if the LUN really exists. */
+        pLunL0 = CFGMR3GetChildF(pCtlInst, "LUN#%u", uLUN);
+        if (pLunL0)
+        {
+            uint32_t fFlags = 0;
+
+            if (fSilent)
+                fFlags |= PDM_TACH_FLAGS_NOT_HOT_PLUG;
+
+            rc = PDMR3DeviceDetach(pUVM, pcszDevice, uInstance, uLUN, fFlags);
+            if (rc == VERR_PDM_NO_DRIVER_ATTACHED_TO_LUN)
+                rc = VINF_SUCCESS;
+            AssertRCReturn(rc, rc);
+            CFGMR3RemoveNode(pLunL0);
+
+            Utf8Str devicePath = Utf8StrFmt("%s/%u/LUN#%u", pcszDevice, uInstance, uLUN);
+            pConsole->mapMediumAttachments.erase(devicePath);
+
+        }
+        else
+            AssertFailedReturn(VERR_INTERNAL_ERROR);
+
+        CFGMR3Dump(pCtlInst);
+    }
+    else
+    {
+        /* Find the correct USB device in the list. */
+        USBStorageDeviceList::iterator it;
+        for (it = pConsole->mUSBStorageDevices.begin(); it != pConsole->mUSBStorageDevices.end(); it++)
+        {
+            if (it->iPort == lPort)
+                break;
+        }
+
+        AssertReturn(it != pConsole->mUSBStorageDevices.end(), VERR_INTERNAL_ERROR);
+        rc = PDMR3UsbDetachDevice(pUVM, &it->mUuid);
         AssertRCReturn(rc, rc);
-        CFGMR3RemoveNode(pLunL0);
-
-        Utf8Str devicePath = Utf8StrFmt("%s/%u/LUN#%u", pcszDevice, uInstance, uLUN);
-        pConsole->mapMediumAttachments.erase(devicePath);
-
-    }
-    else
-        AssertFailedReturn(VERR_INTERNAL_ERROR);
-
-    CFGMR3Dump(pCtlInst);
+        pConsole->mUSBStorageDevices.erase(it);
+    }
 
     /*
@@ -9452,5 +9490,10 @@
     /* Determine the base path for the device instance. */
     PCFGMNODE pCtlInst;
-    pCtlInst = CFGMR3GetChildF(CFGMR3GetRootU(pUVM), "Devices/%s/%u/", pcszDevice, uInstance);
+
+    if (enmBus == StorageBus_USB)
+        pCtlInst = CFGMR3GetChildF(CFGMR3GetRootU(pUVM), "USB/%s/", pcszDevice);
+    else
+        pCtlInst = CFGMR3GetChildF(CFGMR3GetRootU(pUVM), "Devices/%s/%u/", pcszDevice, uInstance);
+
     AssertReturn(pCtlInst, VERR_INTERNAL_ERROR);
 
Index: trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 48973)
+++ trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 48983)
@@ -66,4 +66,5 @@
 #include <VBox/param.h>
 #include <VBox/vmm/pdmapi.h> /* For PDMR3DriverAttach/PDMR3DriverDetach */
+#include <VBox/vmm/pdmusb.h> /* For PDMR3UsbCreateEmulatedDevice */
 #include <VBox/version.h>
 #include <VBox/HostServices/VBoxClipboardSvc.h>
@@ -1085,4 +1086,5 @@
 
 
+
         /*
          * MM values.
@@ -1576,4 +1578,224 @@
 
         /*
+         * The USB Controllers.
+         */
+        com::SafeIfaceArray<IUSBController> usbCtrls;
+        hrc = pMachine->COMGETTER(USBControllers)(ComSafeArrayAsOutParam(usbCtrls));        H();
+        bool fOhciPresent = false; /**< Flag whether at least one OHCI controller is present. */
+
+        for (size_t i = 0; i < usbCtrls.size(); ++i)
+        {
+            USBControllerType_T enmCtrlType;
+            rc = usbCtrls[i]->COMGETTER(Type)(&enmCtrlType);                                   H();
+            if (enmCtrlType == USBControllerType_OHCI)
+            {
+                fOhciPresent = true;
+                break;
+            }
+        }
+
+        /*
+         * Currently EHCI is only enabled when a OHCI controller is present too.
+         * This might change when XHCI is supported.
+         */
+        if (fOhciPresent)
+            mfVMHasUsbController = true;
+
+        PCFGMNODE pUsbDevices = NULL; /**< Required for USB storage controller later. */
+        if (mfVMHasUsbController)
+        {
+            for (size_t i = 0; i < usbCtrls.size(); ++i)
+            {
+                USBControllerType_T enmCtrlType;
+                rc = usbCtrls[i]->COMGETTER(Type)(&enmCtrlType);                                   H();
+
+                if (enmCtrlType == USBControllerType_OHCI)
+                {
+                    InsertConfigNode(pDevices, "usb-ohci", &pDev);
+                    InsertConfigNode(pDev,     "0", &pInst);
+                    InsertConfigNode(pInst,    "Config", &pCfg);
+                    InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
+                    hrc = pBusMgr->assignPCIDevice("usb-ohci", pInst);                          H();
+                    InsertConfigNode(pInst,    "LUN#0", &pLunL0);
+                    InsertConfigString(pLunL0, "Driver",               "VUSBRootHub");
+                    InsertConfigNode(pLunL0,   "Config", &pCfg);
+
+                    /*
+                     * Attach the status driver.
+                     */
+                    attachStatusDriver(pInst, &mapUSBLed[0], 0, 0, NULL, NULL, 0);
+                }
+#ifdef VBOX_WITH_EHCI
+                else if (enmCtrlType == USBControllerType_EHCI)
+                {
+                    /*
+                     * USB 2.0 is only available if the proper ExtPack is installed.
+                     *
+                     * Note. Configuring EHCI here and providing messages about
+                     * the missing extpack isn't exactly clean, but it is a
+                     * necessary evil to patch over legacy compatability issues
+                     * introduced by the new distribution model.
+                     */
+                    static const char *s_pszUsbExtPackName = "Oracle VM VirtualBox Extension Pack";
+# ifdef VBOX_WITH_EXTPACK
+                    if (mptrExtPackManager->isExtPackUsable(s_pszUsbExtPackName))
+# endif
+                    {
+                        InsertConfigNode(pDevices, "usb-ehci", &pDev);
+                        InsertConfigNode(pDev,     "0", &pInst);
+                        InsertConfigNode(pInst,    "Config", &pCfg);
+                        InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
+                        hrc = pBusMgr->assignPCIDevice("usb-ehci", pInst);                  H();
+
+                        InsertConfigNode(pInst,    "LUN#0", &pLunL0);
+                        InsertConfigString(pLunL0, "Driver",               "VUSBRootHub");
+                        InsertConfigNode(pLunL0,   "Config", &pCfg);
+
+                        /*
+                         * Attach the status driver.
+                         */
+                        attachStatusDriver(pInst, &mapUSBLed[1], 0, 0, NULL, NULL, 0);
+                    }
+# ifdef VBOX_WITH_EXTPACK
+                    else
+                    {
+                        /* Always fatal! Up to VBox 4.0.4 we allowed to start the VM anyway
+                         * but this induced problems when the user saved + restored the VM! */
+                        return VMR3SetError(pUVM, VERR_NOT_FOUND, RT_SRC_POS,
+                                N_("Implementation of the USB 2.0 controller not found!\n"
+                                   "Because the USB 2.0 controller state is part of the saved "
+                                   "VM state, the VM cannot be started. To fix "
+                                   "this problem, either install the '%s' or disable USB 2.0 "
+                                   "support in the VM settings"),
+                                s_pszUsbExtPackName);
+                    }
+# endif
+                }
+#endif
+            } /* for every USB controller. */
+
+
+            /*
+             * Virtual USB Devices.
+             */
+            InsertConfigNode(pRoot, "USB", &pUsbDevices);
+
+#ifdef VBOX_WITH_USB
+            {
+                /*
+                 * Global USB options, currently unused as we'll apply the 2.0 -> 1.1 morphing
+                 * on a per device level now.
+                 */
+                InsertConfigNode(pUsbDevices, "USBProxy", &pCfg);
+                InsertConfigNode(pCfg, "GlobalConfig", &pCfg);
+                // This globally enables the 2.0 -> 1.1 device morphing of proxied devices to keep windows quiet.
+                //InsertConfigInteger(pCfg, "Force11Device", true);
+                // The following breaks stuff, but it makes MSDs work in vista. (I include it here so
+                // that it's documented somewhere.) Users needing it can use:
+                //      VBoxManage setextradata "myvm" "VBoxInternal/USB/USBProxy/GlobalConfig/Force11PacketSize" 1
+                //InsertConfigInteger(pCfg, "Force11PacketSize", true);
+            }
+#endif
+
+#ifdef VBOX_WITH_USB_CARDREADER
+            BOOL aEmulatedUSBCardReaderEnabled = FALSE;
+            hrc = pMachine->COMGETTER(EmulatedUSBCardReaderEnabled)(&aEmulatedUSBCardReaderEnabled);    H();
+            if (aEmulatedUSBCardReaderEnabled)
+            {
+                InsertConfigNode(pUsbDevices, "CardReader", &pDev);
+                InsertConfigNode(pDev,     "0", &pInst);
+                InsertConfigNode(pInst,    "Config", &pCfg);
+
+                InsertConfigNode(pInst,    "LUN#0", &pLunL0);
+# ifdef VBOX_WITH_USB_CARDREADER_TEST
+                InsertConfigString(pLunL0, "Driver", "DrvDirectCardReader");
+                InsertConfigNode(pLunL0,   "Config", &pCfg);
+# else
+                InsertConfigString(pLunL0, "Driver", "UsbCardReader");
+                InsertConfigNode(pLunL0,   "Config", &pCfg);
+                InsertConfigInteger(pCfg,  "Object", (uintptr_t)mUsbCardReader);
+# endif
+             }
+#endif
+
+            /* Virtual USB Mouse/Tablet */
+            if (   aPointingHID == PointingHIDType_USBMouse
+                || aPointingHID == PointingHIDType_ComboMouse
+                || aPointingHID == PointingHIDType_USBTablet
+                || aPointingHID == PointingHIDType_USBMultiTouch)
+                InsertConfigNode(pUsbDevices, "HidMouse", &pDev);
+            if (aPointingHID == PointingHIDType_USBMouse)
+            {
+                InsertConfigNode(pDev,     "0", &pInst);
+                InsertConfigNode(pInst,    "Config", &pCfg);
+
+                InsertConfigString(pCfg,   "Mode", "relative");
+                InsertConfigNode(pInst,    "LUN#0", &pLunL0);
+                InsertConfigString(pLunL0, "Driver",        "MouseQueue");
+                InsertConfigNode(pLunL0,   "Config", &pCfg);
+                InsertConfigInteger(pCfg,  "QueueSize",            128);
+
+                InsertConfigNode(pLunL0,   "AttachedDriver", &pLunL1);
+                InsertConfigString(pLunL1, "Driver",        "MainMouse");
+                InsertConfigNode(pLunL1,   "Config", &pCfg);
+                InsertConfigInteger(pCfg,  "Object",     (uintptr_t)pMouse);
+            }
+            if (   aPointingHID == PointingHIDType_USBTablet
+                || aPointingHID == PointingHIDType_USBMultiTouch)
+            {
+                InsertConfigNode(pDev,     "1", &pInst);
+                InsertConfigNode(pInst,    "Config", &pCfg);
+
+                InsertConfigString(pCfg,   "Mode", "absolute");
+                InsertConfigNode(pInst,    "LUN#0", &pLunL0);
+                InsertConfigString(pLunL0, "Driver",        "MouseQueue");
+                InsertConfigNode(pLunL0,   "Config", &pCfg);
+                InsertConfigInteger(pCfg,  "QueueSize",            128);
+
+                InsertConfigNode(pLunL0,   "AttachedDriver", &pLunL1);
+                InsertConfigString(pLunL1, "Driver",        "MainMouse");
+                InsertConfigNode(pLunL1,   "Config", &pCfg);
+                InsertConfigInteger(pCfg,  "Object",     (uintptr_t)pMouse);
+            }
+            if (aPointingHID == PointingHIDType_USBMultiTouch)
+            {
+                InsertConfigNode(pDev,     "2", &pInst);
+                InsertConfigNode(pInst,    "Config", &pCfg);
+
+                InsertConfigString(pCfg,   "Mode", "multitouch");
+                InsertConfigNode(pInst,    "LUN#0", &pLunL0);
+                InsertConfigString(pLunL0, "Driver",        "MouseQueue");
+                InsertConfigNode(pLunL0,   "Config", &pCfg);
+                InsertConfigInteger(pCfg,  "QueueSize",            128);
+
+                InsertConfigNode(pLunL0,   "AttachedDriver", &pLunL1);
+                InsertConfigString(pLunL1, "Driver",        "MainMouse");
+                InsertConfigNode(pLunL1,   "Config", &pCfg);
+                InsertConfigInteger(pCfg,  "Object",     (uintptr_t)pMouse);
+            }
+
+            /* Virtual USB Keyboard */
+            KeyboardHIDType_T aKbdHID;
+            hrc = pMachine->COMGETTER(KeyboardHIDType)(&aKbdHID);                       H();
+            if (aKbdHID == KeyboardHIDType_USBKeyboard)
+            {
+                InsertConfigNode(pUsbDevices, "HidKeyboard", &pDev);
+                InsertConfigNode(pDev,     "0", &pInst);
+                InsertConfigNode(pInst,    "Config", &pCfg);
+
+                InsertConfigNode(pInst,    "LUN#0", &pLunL0);
+                InsertConfigString(pLunL0, "Driver",               "KeyboardQueue");
+                InsertConfigNode(pLunL0,   "Config", &pCfg);
+                InsertConfigInteger(pCfg,  "QueueSize",            64);
+
+                InsertConfigNode(pLunL0,   "AttachedDriver", &pLunL1);
+                InsertConfigString(pLunL1, "Driver",               "MainKeyboard");
+                InsertConfigNode(pLunL1,   "Config", &pCfg);
+                pKeyboard = mKeyboard;
+                InsertConfigInteger(pCfg,  "Object",     (uintptr_t)pKeyboard);
+            }
+        }
+
+        /*
          * Storage controllers.
          */
@@ -1589,5 +1811,6 @@
             StorageControllerType_T enmCtrlType;
             rc = ctrls[i]->COMGETTER(ControllerType)(&enmCtrlType);                         H();
-            AssertRelease((unsigned)enmCtrlType < RT_ELEMENTS(aCtrlNodes));
+            AssertRelease((unsigned)enmCtrlType < RT_ELEMENTS(aCtrlNodes)
+                          || enmCtrlType == StorageControllerType_USB);
 
             StorageBus_T enmBus;
@@ -1606,20 +1829,23 @@
             rc = ctrls[i]->COMGETTER(Bootable)(&fBootable);                                 H();
 
-            /* /Devices/<ctrldev>/ */
+            PCFGMNODE pCtlInst = NULL;
             const char *pszCtrlDev = convertControllerTypeToDev(enmCtrlType);
-            pDev = aCtrlNodes[enmCtrlType];
-            if (!pDev)
-            {
-                InsertConfigNode(pDevices, pszCtrlDev, &pDev);
-                aCtrlNodes[enmCtrlType] = pDev; /* IDE variants are handled in the switch */
-            }
-
-            /* /Devices/<ctrldev>/<instance>/ */
-            PCFGMNODE pCtlInst = NULL;
-            InsertConfigNode(pDev, Utf8StrFmt("%u", ulInstance).c_str(), &pCtlInst);
-
-            /* Device config: /Devices/<ctrldev>/<instance>/<values> & /ditto/Config/<values> */
-            InsertConfigInteger(pCtlInst, "Trusted",   1);
-            InsertConfigNode(pCtlInst,    "Config",    &pCfg);
+            if (enmCtrlType != StorageControllerType_USB)
+            {
+                /* /Devices/<ctrldev>/ */
+                pDev = aCtrlNodes[enmCtrlType];
+                if (!pDev)
+                {
+                    InsertConfigNode(pDevices, pszCtrlDev, &pDev);
+                    aCtrlNodes[enmCtrlType] = pDev; /* IDE variants are handled in the switch */
+                }
+
+                /* /Devices/<ctrldev>/<instance>/ */
+                InsertConfigNode(pDev, Utf8StrFmt("%u", ulInstance).c_str(), &pCtlInst);
+
+                /* Device config: /Devices/<ctrldev>/<instance>/<values> & /ditto/Config/<values> */
+                InsertConfigInteger(pCtlInst, "Trusted",   1);
+                InsertConfigNode(pCtlInst,    "Config",    &pCfg);
+            }
 
             switch (enmCtrlType)
@@ -1798,4 +2024,24 @@
                                        &mapMediumAttachments, pszCtrlDev, ulInstance);
                     paLedDevType = &maStorageDevType[iLedSas];
+                    break;
+                }
+
+                case StorageControllerType_USB:
+                {
+                    if (pUsbDevices)
+                    {
+                        /*
+                         * USB MSDs are handled a bit different as the device instance
+                         * doesn't match the storage controller instance but the port.
+                         */
+                        InsertConfigNode(pUsbDevices, "Msd", &pDev);
+                        pCtlInst = pDev;
+                    }
+                    else
+                        return VMR3SetError(pUVM, VERR_NOT_FOUND, RT_SRC_POS,
+                                N_("There is no USB controller enabled but there\n"
+                                   "is at least one USB storage device configured for this VM.\n"
+                                   "To fix this problem either enable the USB controller or remove\n"
+                                   "the storage device from the VM"));
                     break;
                 }
@@ -2333,246 +2579,4 @@
             hrc = pMachine->COMGETTER(Name)(bstr.asOutParam());                             H();
             InsertConfigString(pCfg, "StreamName", bstr);
-        }
-
-        /*
-         * The USB Controllers.
-         */
-        com::SafeIfaceArray<IUSBController> usbCtrls;
-        hrc = pMachine->COMGETTER(USBControllers)(ComSafeArrayAsOutParam(usbCtrls));        H();
-        bool fOhciPresent = false; /**< Flag whether at least one OHCI controller is presnet. */
-
-        for (size_t i = 0; i < usbCtrls.size(); ++i)
-        {
-            USBControllerType_T enmCtrlType;
-            rc = usbCtrls[i]->COMGETTER(Type)(&enmCtrlType);                                   H();
-            if (enmCtrlType == USBControllerType_OHCI)
-            {
-                fOhciPresent = true;
-                break;
-            }
-        }
-
-        /*
-         * Currently EHCI is only enabled when a OHCI controller is present too.
-         * This might change when XHCI is supported.
-         */
-        if (fOhciPresent)
-            mfVMHasUsbController = true;
-
-        if (mfVMHasUsbController)
-        {
-            for (size_t i = 0; i < usbCtrls.size(); ++i)
-            {
-                USBControllerType_T enmCtrlType;
-                rc = usbCtrls[i]->COMGETTER(Type)(&enmCtrlType);                                   H();
-
-                if (enmCtrlType == USBControllerType_OHCI)
-                {
-                    InsertConfigNode(pDevices, "usb-ohci", &pDev);
-                    InsertConfigNode(pDev,     "0", &pInst);
-                    InsertConfigNode(pInst,    "Config", &pCfg);
-                    InsertConfigInteger(pInst, "Trusted",              1); /* boolean */
-                    hrc = pBusMgr->assignPCIDevice("usb-ohci", pInst);                          H();
-                    InsertConfigNode(pInst,    "LUN#0", &pLunL0);
-                    InsertConfigString(pLunL0, "Driver",               "VUSBRootHub");
-                    InsertConfigNode(pLunL0,   "Config", &pCfg);
-
-                    /*
-                     * Attach the status driver.
-                     */
-                    attachStatusDriver(pInst, &mapUSBLed[0], 0, 0, NULL, NULL, 0);
-                }
-#ifdef VBOX_WITH_EHCI
-                else if (enmCtrlType == USBControllerType_EHCI)
-                {
-                    /*
-                     * USB 2.0 is only available if the proper ExtPack is installed.
-                     *
-                     * Note. Configuring EHCI here and providing messages about
-                     * the missing extpack isn't exactly clean, but it is a
-                     * necessary evil to patch over legacy compatability issues
-                     * introduced by the new distribution model.
-                     */
-                    static const char *s_pszUsbExtPackName = "Oracle VM VirtualBox Extension Pack";
-# ifdef VBOX_WITH_EXTPACK
-                    if (mptrExtPackManager->isExtPackUsable(s_pszUsbExtPackName))
-# endif
-                    {
-                        InsertConfigNode(pDevices, "usb-ehci", &pDev);
-                        InsertConfigNode(pDev,     "0", &pInst);
-                        InsertConfigNode(pInst,    "Config", &pCfg);
-                        InsertConfigInteger(pInst, "Trusted", 1); /* boolean */
-                        hrc = pBusMgr->assignPCIDevice("usb-ehci", pInst);                  H();
-
-                        InsertConfigNode(pInst,    "LUN#0", &pLunL0);
-                        InsertConfigString(pLunL0, "Driver",               "VUSBRootHub");
-                        InsertConfigNode(pLunL0,   "Config", &pCfg);
-
-                        /*
-                         * Attach the status driver.
-                         */
-                        attachStatusDriver(pInst, &mapUSBLed[1], 0, 0, NULL, NULL, 0);
-                    }
-# ifdef VBOX_WITH_EXTPACK
-                    else
-                    {
-                        /* Always fatal! Up to VBox 4.0.4 we allowed to start the VM anyway
-                         * but this induced problems when the user saved + restored the VM! */
-                        return VMR3SetError(pUVM, VERR_NOT_FOUND, RT_SRC_POS,
-                                N_("Implementation of the USB 2.0 controller not found!\n"
-                                   "Because the USB 2.0 controller state is part of the saved "
-                                   "VM state, the VM cannot be started. To fix "
-                                   "this problem, either install the '%s' or disable USB 2.0 "
-                                   "support in the VM settings"),
-                                s_pszUsbExtPackName);
-                    }
-# endif
-                }
-#endif
-            } /* for every USB controller. */
-
-
-            /*
-             * Virtual USB Devices.
-             */
-            PCFGMNODE pUsbDevices = NULL;
-            InsertConfigNode(pRoot, "USB", &pUsbDevices);
-
-#ifdef VBOX_WITH_USB
-            {
-                /*
-                 * Global USB options, currently unused as we'll apply the 2.0 -> 1.1 morphing
-                 * on a per device level now.
-                 */
-                InsertConfigNode(pUsbDevices, "USBProxy", &pCfg);
-                InsertConfigNode(pCfg, "GlobalConfig", &pCfg);
-                // This globally enables the 2.0 -> 1.1 device morphing of proxied devices to keep windows quiet.
-                //InsertConfigInteger(pCfg, "Force11Device", true);
-                // The following breaks stuff, but it makes MSDs work in vista. (I include it here so
-                // that it's documented somewhere.) Users needing it can use:
-                //      VBoxManage setextradata "myvm" "VBoxInternal/USB/USBProxy/GlobalConfig/Force11PacketSize" 1
-                //InsertConfigInteger(pCfg, "Force11PacketSize", true);
-            }
-#endif
-
-#ifdef VBOX_WITH_USB_CARDREADER
-            BOOL aEmulatedUSBCardReaderEnabled = FALSE;
-            hrc = pMachine->COMGETTER(EmulatedUSBCardReaderEnabled)(&aEmulatedUSBCardReaderEnabled);    H();
-            if (aEmulatedUSBCardReaderEnabled)
-            {
-                InsertConfigNode(pUsbDevices, "CardReader", &pDev);
-                InsertConfigNode(pDev,     "0", &pInst);
-                InsertConfigNode(pInst,    "Config", &pCfg);
-
-                InsertConfigNode(pInst,    "LUN#0", &pLunL0);
-# ifdef VBOX_WITH_USB_CARDREADER_TEST
-                InsertConfigString(pLunL0, "Driver", "DrvDirectCardReader");
-                InsertConfigNode(pLunL0,   "Config", &pCfg);
-# else
-                InsertConfigString(pLunL0, "Driver", "UsbCardReader");
-                InsertConfigNode(pLunL0,   "Config", &pCfg);
-                InsertConfigInteger(pCfg,  "Object", (uintptr_t)mUsbCardReader);
-# endif
-             }
-#endif
-
-# if 0  /* Virtual MSD*/
-            InsertConfigNode(pUsbDevices, "Msd", &pDev);
-            InsertConfigNode(pDev,     "0", &pInst);
-            InsertConfigNode(pInst,    "Config", &pCfg);
-            InsertConfigNode(pInst,    "LUN#0", &pLunL0);
-
-            InsertConfigString(pLunL0, "Driver", "SCSI");
-            InsertConfigNode(pLunL0,   "Config", &pCfg);
-
-            InsertConfigNode(pLunL0,   "AttachedDriver", &pLunL1);
-            InsertConfigString(pLunL1, "Driver", "Block");
-            InsertConfigNode(pLunL1,   "Config", &pCfg);
-            InsertConfigString(pCfg,   "Type", "HardDisk");
-            InsertConfigInteger(pCfg,  "Mountable", 0);
-
-            InsertConfigNode(pLunL1,   "AttachedDriver", &pLunL2);
-            InsertConfigString(pLunL2, "Driver", "VD");
-            InsertConfigNode(pLunL2,   "Config", &pCfg);
-            InsertConfigString(pCfg,   "Path", "/Volumes/DataHFS/bird/VDIs/linux.vdi");
-            InsertConfigString(pCfg,   "Format", "VDI");
-# endif
-
-            /* Virtual USB Mouse/Tablet */
-            if (   aPointingHID == PointingHIDType_USBMouse
-                || aPointingHID == PointingHIDType_ComboMouse
-                || aPointingHID == PointingHIDType_USBTablet
-                || aPointingHID == PointingHIDType_USBMultiTouch)
-                InsertConfigNode(pUsbDevices, "HidMouse", &pDev);
-            if (aPointingHID == PointingHIDType_USBMouse)
-            {
-                InsertConfigNode(pDev,     "0", &pInst);
-                InsertConfigNode(pInst,    "Config", &pCfg);
-
-                InsertConfigString(pCfg,   "Mode", "relative");
-                InsertConfigNode(pInst,    "LUN#0", &pLunL0);
-                InsertConfigString(pLunL0, "Driver",        "MouseQueue");
-                InsertConfigNode(pLunL0,   "Config", &pCfg);
-                InsertConfigInteger(pCfg,  "QueueSize",            128);
-
-                InsertConfigNode(pLunL0,   "AttachedDriver", &pLunL1);
-                InsertConfigString(pLunL1, "Driver",        "MainMouse");
-                InsertConfigNode(pLunL1,   "Config", &pCfg);
-                InsertConfigInteger(pCfg,  "Object",     (uintptr_t)pMouse);
-            }
-            if (   aPointingHID == PointingHIDType_USBTablet
-                || aPointingHID == PointingHIDType_USBMultiTouch)
-            {
-                InsertConfigNode(pDev,     "1", &pInst);
-                InsertConfigNode(pInst,    "Config", &pCfg);
-
-                InsertConfigString(pCfg,   "Mode", "absolute");
-                InsertConfigNode(pInst,    "LUN#0", &pLunL0);
-                InsertConfigString(pLunL0, "Driver",        "MouseQueue");
-                InsertConfigNode(pLunL0,   "Config", &pCfg);
-                InsertConfigInteger(pCfg,  "QueueSize",            128);
-
-                InsertConfigNode(pLunL0,   "AttachedDriver", &pLunL1);
-                InsertConfigString(pLunL1, "Driver",        "MainMouse");
-                InsertConfigNode(pLunL1,   "Config", &pCfg);
-                InsertConfigInteger(pCfg,  "Object",     (uintptr_t)pMouse);
-            }
-            if (aPointingHID == PointingHIDType_USBMultiTouch)
-            {
-                InsertConfigNode(pDev,     "2", &pInst);
-                InsertConfigNode(pInst,    "Config", &pCfg);
-
-                InsertConfigString(pCfg,   "Mode", "multitouch");
-                InsertConfigNode(pInst,    "LUN#0", &pLunL0);
-                InsertConfigString(pLunL0, "Driver",        "MouseQueue");
-                InsertConfigNode(pLunL0,   "Config", &pCfg);
-                InsertConfigInteger(pCfg,  "QueueSize",            128);
-
-                InsertConfigNode(pLunL0,   "AttachedDriver", &pLunL1);
-                InsertConfigString(pLunL1, "Driver",        "MainMouse");
-                InsertConfigNode(pLunL1,   "Config", &pCfg);
-                InsertConfigInteger(pCfg,  "Object",     (uintptr_t)pMouse);
-            }
-
-            /* Virtual USB Keyboard */
-            KeyboardHIDType_T aKbdHID;
-            hrc = pMachine->COMGETTER(KeyboardHIDType)(&aKbdHID);                       H();
-            if (aKbdHID == KeyboardHIDType_USBKeyboard)
-            {
-                InsertConfigNode(pUsbDevices, "HidKeyboard", &pDev);
-                InsertConfigNode(pDev,     "0", &pInst);
-                InsertConfigNode(pInst,    "Config", &pCfg);
-
-                InsertConfigNode(pInst,    "LUN#0", &pLunL0);
-                InsertConfigString(pLunL0, "Driver",               "KeyboardQueue");
-                InsertConfigNode(pLunL0,   "Config", &pCfg);
-                InsertConfigInteger(pCfg,  "QueueSize",            64);
-
-                InsertConfigNode(pLunL0,   "AttachedDriver", &pLunL1);
-                InsertConfigString(pLunL1, "Driver",               "MainKeyboard");
-                InsertConfigNode(pLunL1,   "Config", &pCfg);
-                pKeyboard = mKeyboard;
-                InsertConfigInteger(pCfg,  "Object",     (uintptr_t)pKeyboard);
-            }
         }
 
@@ -3345,4 +3349,44 @@
         hrc = Console::convertBusPortDeviceToLun(enmBus, lPort, lDev, uLUN);                H();
 
+        if (enmBus == StorageBus_USB)
+        {
+            PCFGMNODE pCfg = NULL;
+
+            /* Create correct instance. */
+            if (!fHotplug && !fAttachDetach)
+                InsertConfigNode(pCtlInst, Utf8StrFmt("%d", lPort).c_str(), &pCtlInst);
+            else if (fAttachDetach)
+                pCtlInst = CFGMR3GetChildF(pCtlInst, "%d/", lPort);
+
+            if (!fAttachDetach)
+                InsertConfigNode(pCtlInst, "Config", &pCfg);
+
+            uInstance = lPort; /* Overwrite uInstance with the correct one. */
+
+            if (!fHotplug && !fAttachDetach)
+            {
+                char aszUuid[RTUUID_STR_LENGTH + 1];
+                USBStorageDevice UsbMsd = USBStorageDevice();
+
+                memset(aszUuid, 0, sizeof(aszUuid));
+                rc = RTUuidCreate(&UsbMsd.mUuid);
+                AssertRCReturn(rc, rc);
+                rc = RTUuidToStr(&UsbMsd.mUuid, aszUuid, sizeof(aszUuid));
+                AssertRCReturn(rc, rc);
+
+                UsbMsd.iPort = uInstance;
+
+                InsertConfigString(pCtlInst, "UUID", aszUuid);
+                mUSBStorageDevices.push_back(UsbMsd);
+
+                /** @todo: No LED after hotplugging. */
+                /* Attach the status driver */
+                Assert(cLedUsb >= 8);
+                attachStatusDriver(pCtlInst, &mapStorageLeds[iLedUsb], 0, 7,
+                                   &mapMediumAttachments, pcszDevice, 0);
+                paLedDevType = &maStorageDevType[iLedUsb];
+            }
+        }
+
         /* First check if the LUN already exists. */
         pLunL0 = CFGMR3GetChildF(pCtlInst, "LUN#%u", uLUN);
@@ -3377,5 +3421,8 @@
                 }
 
-                rc = PDMR3DeviceDetach(pUVM, pcszDevice, uInstance, uLUN, fHotplug ? 0 : PDM_TACH_FLAGS_NOT_HOT_PLUG);
+                if (enmBus == StorageBus_USB)
+                    rc = PDMR3UsbDriverDetach(pUVM, pcszDevice, uInstance, uLUN, NULL, 0, fHotplug ? 0 : PDM_TACH_FLAGS_NOT_HOT_PLUG);
+                else
+                    rc = PDMR3DeviceDetach(pUVM, pcszDevice, uInstance, uLUN, fHotplug ? 0 : PDM_TACH_FLAGS_NOT_HOT_PLUG);
                 if (rc == VERR_PDM_NO_DRIVER_ATTACHED_TO_LUN)
                     rc = VINF_SUCCESS;
@@ -3420,5 +3467,5 @@
 
         /* SCSI has a another driver between device and block. */
-        if (enmBus == StorageBus_SCSI || enmBus == StorageBus_SAS)
+        if (enmBus == StorageBus_SCSI || enmBus == StorageBus_SAS || enmBus == StorageBus_USB)
         {
             InsertConfigString(pLunL0, "Driver", "SCSI");
@@ -3670,6 +3717,22 @@
         {
             /* Attach the new driver. */
-            rc = PDMR3DeviceAttach(pUVM, pcszDevice, uInstance, uLUN,
-                                   fHotplug ? 0 : PDM_TACH_FLAGS_NOT_HOT_PLUG, NULL /*ppBase*/);
+            if (enmBus == StorageBus_USB)
+            {
+                if (fHotplug)
+                {
+                    USBStorageDevice UsbMsd = USBStorageDevice();
+                    RTUuidCreate(&UsbMsd.mUuid);
+                    UsbMsd.iPort = uInstance;
+                    rc = PDMR3UsbCreateEmulatedDevice(pUVM, pcszDevice, pCtlInst, &UsbMsd.mUuid);
+                    if (RT_SUCCESS(rc))
+                        mUSBStorageDevices.push_back(UsbMsd);
+                }
+                else
+                    rc = PDMR3UsbDriverAttach(pUVM, pcszDevice, uInstance, uLUN,
+                                              fHotplug ? 0 : PDM_TACH_FLAGS_NOT_HOT_PLUG, NULL /*ppBase*/);
+            }
+            else
+                rc = PDMR3DeviceAttach(pUVM, pcszDevice, uInstance, uLUN,
+                                       fHotplug ? 0 : PDM_TACH_FLAGS_NOT_HOT_PLUG, NULL /*ppBase*/);
             AssertRCReturn(rc, rc);
 
Index: trunk/src/VBox/Main/src-server/MachineImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/MachineImpl.cpp	(revision 48973)
+++ trunk/src/VBox/Main/src-server/MachineImpl.cpp	(revision 48983)
@@ -6381,5 +6381,5 @@
 
     if (   (aConnectionType <= StorageBus_Null)
-        || (aConnectionType >  StorageBus_SAS))
+        || (aConnectionType >  StorageBus_USB))
         return setError(E_INVALIDARG,
                         tr("Invalid connection type: %d"),
@@ -12488,4 +12488,5 @@
     {
         case StorageControllerType_IntelAhci:
+        case StorageControllerType_USB:
             return true;
         case StorageControllerType_LsiLogic:
Index: trunk/src/VBox/Main/src-server/StorageControllerImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/StorageControllerImpl.cpp	(revision 48973)
+++ trunk/src/VBox/Main/src-server/StorageControllerImpl.cpp	(revision 48983)
@@ -135,5 +135,5 @@
     ComAssertRet(aParent && !aName.isEmpty(), E_INVALIDARG);
     if (   (aStorageBus <= StorageBus_Null)
-        || (aStorageBus >  StorageBus_SAS))
+        || (aStorageBus >  StorageBus_USB))
         return setError(E_INVALIDARG,
                         tr("Invalid storage connection type"));
@@ -192,4 +192,7 @@
             m->bd->mPortCount = 8;
             m->bd->mStorageControllerType = StorageControllerType_LsiLogicSas;
+        case StorageBus_USB:
+            m->bd->mPortCount = 8;
+            m->bd->mStorageControllerType = StorageControllerType_USB;
             break;
     }
@@ -398,4 +401,10 @@
             break;
         }
+        case StorageBus_USB:
+        {
+            if (aControllerType != StorageControllerType_USB)
+                rc = E_INVALIDARG;
+            break;
+        }
         default:
             AssertMsgFailed(("Invalid controller type %d\n", m->bd->mStorageBus));
@@ -519,4 +528,5 @@
         }
         case StorageBus_SAS:
+        case StorageBus_USB:
         {
             /*
Index: trunk/src/VBox/Main/src-server/SystemPropertiesImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/SystemPropertiesImpl.cpp	(revision 48973)
+++ trunk/src/VBox/Main/src-server/SystemPropertiesImpl.cpp	(revision 48983)
@@ -423,4 +423,5 @@
         case StorageBus_SCSI:
         case StorageBus_SAS:
+        case StorageBus_USB:
         {
             /* SATA and both SCSI controllers only support one device per port. */
@@ -475,4 +476,5 @@
         }
         case StorageBus_SAS:
+        case StorageBus_USB:
         {
             *aMinPortCount = 8;
@@ -518,4 +520,5 @@
         }
         case StorageBus_SAS:
+        case StorageBus_USB:
         {
             *aMaxPortCount = 8;
@@ -548,4 +551,5 @@
             cCtrs = aChipset == ChipsetType_ICH9 ? 8 : 1;
             break;
+        case StorageBus_USB:
         case StorageBus_IDE:
         case StorageBus_Floppy:
@@ -578,4 +582,5 @@
         case StorageBus_SCSI:
         case StorageBus_SAS:
+        case StorageBus_USB:
         {
             com::SafeArray<DeviceType_T> saDeviceTypes(2);
@@ -613,4 +618,5 @@
         case StorageControllerType_IntelAhci:
         case StorageControllerType_LsiLogicSas:
+        case StorageControllerType_USB:
             *aEnabled = false;
             break;
Index: trunk/src/VBox/Main/xml/Settings.cpp
===================================================================
--- trunk/src/VBox/Main/xml/Settings.cpp	(revision 48973)
+++ trunk/src/VBox/Main/xml/Settings.cpp	(revision 48983)
@@ -3426,4 +3426,9 @@
             sctl.controllerType = StorageControllerType_LsiLogicSas;
         }
+        else if (strType == "USB")
+        {
+            sctl.storageBus = StorageBus_USB;
+            sctl.controllerType = StorageControllerType_USB;
+        }
         else
             throw ConfigFileError(this, pelmController, N_("Invalid value '%s' for StorageController/@type attribute"), strType.c_str());
@@ -4854,4 +4859,5 @@
             case StorageControllerType_I82078: pcszType = "I82078"; break;
             case StorageControllerType_LsiLogicSas: pcszType = "LsiLogicSas"; break;
+            case StorageControllerType_USB: pcszType = "USB"; break;
             default: /*case StorageControllerType_PIIX3:*/ pcszType = "PIIX3"; break;
         }
