Index: /trunk/src/VBox/Main/include/ConsoleImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 38910)
+++ /trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 38911)
@@ -228,5 +228,5 @@
     void VRDPInterceptClipboard(uint32_t u32ClientId);
 
-    void processRemoteUSBDevices(uint32_t u32ClientId, VRDEUSBDEVICEDESC *pDevList, uint32_t cbDevList);
+    void processRemoteUSBDevices(uint32_t u32ClientId, VRDEUSBDEVICEDESC *pDevList, uint32_t cbDevList, bool fDescExt);
 
     // callback callers (partly; for some events console callbacks are notified
Index: /trunk/src/VBox/Main/include/RemoteUSBBackend.h
===================================================================
--- /trunk/src/VBox/Main/include/RemoteUSBBackend.h	(revision 38910)
+++ /trunk/src/VBox/Main/include/RemoteUSBBackend.h	(revision 38911)
@@ -131,4 +131,7 @@
         /* VRDP_USB_VERSION_2: the client version. */
         uint32_t mClientVersion;
+
+        /* VRDP_USB_VERSION_3: the client sends VRDE_USB_REQ_DEVICE_LIST_EXT_RET. */
+        bool mfDescExt;
 };
 
Index: /trunk/src/VBox/Main/include/RemoteUSBDeviceImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/RemoteUSBDeviceImpl.h	(revision 38910)
+++ /trunk/src/VBox/Main/include/RemoteUSBDeviceImpl.h	(revision 38911)
@@ -50,5 +50,5 @@
 
     // public initializer/uninitializer for internal purposes only
-    HRESULT init(uint32_t u32ClientId, VRDEUSBDEVICEDESC *pDevDesc);
+    HRESULT init(uint32_t u32ClientId, VRDEUSBDEVICEDESC *pDevDesc, bool fDescExt);
     void uninit();
 
Index: /trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 38910)
+++ /trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 38911)
@@ -8261,8 +8261,8 @@
  * @note Locks this object for writing.
  */
-void Console::processRemoteUSBDevices(uint32_t u32ClientId, VRDEUSBDEVICEDESC *pDevList, uint32_t cbDevList)
+void Console::processRemoteUSBDevices(uint32_t u32ClientId, VRDEUSBDEVICEDESC *pDevList, uint32_t cbDevList, bool fDescExt)
 {
     LogFlowThisFuncEnter();
-    LogFlowThisFunc(("u32ClientId = %d, pDevList=%p, cbDevList = %d\n", u32ClientId, pDevList, cbDevList));
+    LogFlowThisFunc(("u32ClientId = %d, pDevList=%p, cbDevList = %d, fDescExt = %d\n", u32ClientId, pDevList, cbDevList, fDescExt));
 
     AutoCaller autoCaller(this);
@@ -8335,5 +8335,5 @@
             ComObjPtr<RemoteUSBDevice> pUSBDevice;
             pUSBDevice.createObject();
-            pUSBDevice->init(u32ClientId, e);
+            pUSBDevice->init(u32ClientId, e, fDescExt);
 
             mRemoteUSBDevices.push_back(pUSBDevice);
Index: /trunk/src/VBox/Main/src-client/RemoteUSBBackend.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/RemoteUSBBackend.cpp	(revision 38910)
+++ /trunk/src/VBox/Main/src-client/RemoteUSBBackend.cpp	(revision 38911)
@@ -805,5 +805,5 @@
     {
         /* Unmount all remote USB devices. */
-        mConsole->processRemoteUSBDevices (mu32ClientId, NULL, 0);
+        mConsole->processRemoteUSBDevices (mu32ClientId, NULL, 0, false);
 
         menmPollRemoteDevicesStatus = PollRemoteDevicesStatus_Dereferenced;
@@ -822,5 +822,6 @@
             parm.code = VRDE_USB_REQ_NEGOTIATE;
             parm.version = VRDE_USB_VERSION;
-            parm.flags = 0;
+            /* VRDE_USB_VERSION_3: support VRDE_USB_REQ_DEVICE_LIST_EXT_RET. */
+            parm.flags = VRDE_USB_SERVER_CAPS_PORT_VERSION;
 
             mServer->SendUSBRequest (mu32ClientId, &parm, sizeof (parm));
@@ -864,5 +865,5 @@
             if (mfHasDeviceList)
             {
-                mConsole->processRemoteUSBDevices (mu32ClientId, (VRDEUSBDEVICEDESC *)mpvDeviceList, mcbDeviceList);
+                mConsole->processRemoteUSBDevices (mu32ClientId, (VRDEUSBDEVICEDESC *)mpvDeviceList, mcbDeviceList, mfDescExt);
                 LogFlow(("USB::PollRemoteDevices: WaitResponse after process\n"));
 
@@ -950,5 +951,6 @@
     mpDevices (NULL),
     mfWillBeDeleted (false),
-    mClientVersion (0)                   /* VRDE_USB_VERSION_2: the client version. */
+    mClientVersion (0),                   /* VRDE_USB_VERSION_2: the client version. */
+    mfDescExt (false)                     /* VRDE_USB_VERSION_3: VRDE_USB_REQ_DEVICE_LIST_EXT_RET. */
 {
     Assert(console);
@@ -1045,4 +1047,20 @@
         LogRel(("VRDP: remote USB protocol version %d.\n", mClientVersion));
 
+        /* VRDE_USB_VERSION_3: check the client capabilities: VRDE_USB_CLIENT_CAPS_*. */
+        if (mClientVersion == VRDE_USB_VERSION_3)
+        {
+            if (cbRet >= sizeof (VRDEUSBREQNEGOTIATERET_3))
+            {
+                VRDEUSBREQNEGOTIATERET_3 *pret3 = (VRDEUSBREQNEGOTIATERET_3 *)pret;
+
+                mfDescExt = (pret3->u32Flags & VRDE_USB_CLIENT_CAPS_PORT_VERSION) != 0;
+            }
+            else
+            {
+                LogRel(("VRDP: ERROR: invalid remote USB negotiate request packet size %d.\n", cbRet));
+                rc = VERR_NOT_SUPPORTED;
+            }
+        }
+
         menmPollRemoteDevicesStatus = PollRemoteDevicesStatus_SendRequest;
     }
Index: /trunk/src/VBox/Main/src-client/RemoteUSBDeviceImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/RemoteUSBDeviceImpl.cpp	(revision 38910)
+++ /trunk/src/VBox/Main/src-client/RemoteUSBDeviceImpl.cpp	(revision 38911)
@@ -55,5 +55,5 @@
  * Initializes the remote USB device object.
  */
-HRESULT RemoteUSBDevice::init (uint32_t u32ClientId, VRDEUSBDEVICEDESC *pDevDesc)
+HRESULT RemoteUSBDevice::init (uint32_t u32ClientId, VRDEUSBDEVICEDESC *pDevDesc, bool fDescExt)
 {
     LogFlowThisFunc(("u32ClientId=%d,pDevDesc=%p\n", u32ClientId, pDevDesc));
@@ -79,5 +79,27 @@
     unconst(mData.port)         = pDevDesc->idPort;
     unconst(mData.version)      = pDevDesc->bcdUSB >> 8;
-    unconst(mData.portVersion)  = mData.version; /** @todo fix this */
+    if (fDescExt)
+    {
+        VRDEUSBDEVICEDESCEXT *pDevDescExt = (VRDEUSBDEVICEDESCEXT *)pDevDesc;
+        switch (pDevDescExt->u16DeviceSpeed)
+        {
+            default:
+            case VRDE_USBDEVICESPEED_UNKNOWN:
+            case VRDE_USBDEVICESPEED_LOW:
+            case VRDE_USBDEVICESPEED_FULL:
+                unconst(mData.portVersion) = 1;
+                break;
+
+            case VRDE_USBDEVICESPEED_HIGH:
+            case VRDE_USBDEVICESPEED_VARIABLE:
+            case VRDE_USBDEVICESPEED_SUPERSPEED:
+                unconst(mData.portVersion) = 2;
+                break;
+        }
+    }
+    else
+    {
+        unconst(mData.portVersion)  = mData.version;
+    }
 
     mData.state                  = USBDeviceState_Available;
