Index: /trunk/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxDrvTool.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxDrvTool.cpp	(revision 37046)
+++ /trunk/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxDrvTool.cpp	(revision 37047)
@@ -132,4 +132,48 @@
 }
 
+/* !!!NOTE: the caller MUST be the IRP owner!!! *
+ * !! one can not post threaded IRPs this way!! */
+VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolIoPostSyncWithTimeout(PDEVICE_OBJECT pDevObj, PIRP pIrp, ULONG dwTimeoutMs)
+{
+    KEVENT Event;
+    KeInitializeEvent(&Event, NotificationEvent, FALSE);
+    NTSTATUS Status = VBoxDrvToolIoPostAsync(pDevObj, pIrp, &Event);
+    if (Status == STATUS_PENDING)
+    {
+        LARGE_INTEGER Interval;
+        PLARGE_INTEGER pInterval = NULL;
+        if (dwTimeoutMs != RT_INDEFINITE_WAIT)
+        {
+            Interval.QuadPart = -(int64_t) dwTimeoutMs /* ms */ * 10000;
+            pInterval = &Interval;
+        }
+
+        Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, pInterval);
+        if (Status == STATUS_TIMEOUT)
+        {
+#ifdef DEBUG_misha
+            /* debugging only */
+            AssertFailed();
+#endif
+            if (!IoCancelIrp(pIrp))
+            {
+                /* this may happen, but this is something the caller with timeout is not expecting */
+                AssertFailed();
+            }
+
+            /* wait for the IRP to complete */
+            KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+        }
+        else
+        {
+            Assert(Status == STATUS_SUCCESS);
+        }
+
+        /* by this time the IRP is completed */
+        Status = pIrp->IoStatus.Status;
+    }
+    return Status;
+}
+
 VBOXDRVTOOL_DECL(VOID) VBoxDrvToolRefWaitEqual(PVBOXDRVTOOL_REF pRef, uint32_t u32Val)
 {
Index: /trunk/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxDrvTool.h
===================================================================
--- /trunk/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxDrvTool.h	(revision 37046)
+++ /trunk/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxDrvTool.h	(revision 37047)
@@ -76,4 +76,5 @@
 VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolIoPostAsync(PDEVICE_OBJECT pDevObj, PIRP pIrp, PKEVENT pEvent);
 VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolIoPostSync(PDEVICE_OBJECT pDevObj, PIRP pIrp);
+VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolIoPostSyncWithTimeout(PDEVICE_OBJECT pDevObj, PIRP pIrp, ULONG dwTimeoutMs);
 DECLINLINE(NTSTATUS) VBoxDrvToolIoComplete(PIRP pIrp, NTSTATUS Status, ULONG ulInfo)
 {
Index: /trunk/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxUsbTool.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxUsbTool.cpp	(revision 37046)
+++ /trunk/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxUsbTool.cpp	(revision 37047)
@@ -85,10 +85,12 @@
 }
 
-VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolUrbPost(PDEVICE_OBJECT pDevObj, PURB pUrb)
-{
-    return VBoxUsbToolIoInternalCtlSendSync(pDevObj, IOCTL_INTERNAL_USB_SUBMIT_URB, pUrb, NULL);
-}
-
-VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolGetDescriptor(PDEVICE_OBJECT pDevObj, void *pvBuffer, int cbBuffer, int Type, int iIndex, int LangId)
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolUrbPost(PDEVICE_OBJECT pDevObj, PURB pUrb, ULONG dwTimeoutMs)
+{
+    if (dwTimeoutMs == RT_INDEFINITE_WAIT)
+        return VBoxUsbToolIoInternalCtlSendSync(pDevObj, IOCTL_INTERNAL_USB_SUBMIT_URB, pUrb, NULL);
+    return VBoxUsbToolIoInternalCtlSendSyncWithTimeout(pDevObj, IOCTL_INTERNAL_USB_SUBMIT_URB, pUrb, NULL, dwTimeoutMs);
+}
+
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolGetDescriptor(PDEVICE_OBJECT pDevObj, void *pvBuffer, int cbBuffer, int Type, int iIndex, int LangId, ULONG dwTimeoutMs)
 {
     NTSTATUS Status;
@@ -100,4 +102,8 @@
         return STATUS_INSUFFICIENT_RESOURCES;
     }
+
+    PUSB_COMMON_DESCRIPTOR pCmn = (PUSB_COMMON_DESCRIPTOR)pvBuffer;
+    pCmn->bLength = cbBuffer;
+    pCmn->bDescriptorType = Type;
 
     pUrb->UrbHeader.Function = URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE;
@@ -109,5 +115,5 @@
     pUrb->UrbControlDescriptorRequest.LanguageId           = (USHORT)LangId;
 
-    Status = VBoxUsbToolUrbPost(pDevObj, pUrb);
+    Status = VBoxUsbToolUrbPost(pDevObj, pUrb, dwTimeoutMs);
 #ifdef DEBUG_misha
     Assert(Status == STATUS_SUCCESS);
@@ -129,5 +135,5 @@
 }
 
-VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolGetStringDescriptorA(PDEVICE_OBJECT pDevObj, char *pResult, ULONG cbResult, int iIndex, int LangId)
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolGetStringDescriptorA(PDEVICE_OBJECT pDevObj, char *pResult, ULONG cbResult, int iIndex, int LangId, ULONG dwTimeoutMs)
 {
     char aBuf[MAXIMUM_USB_STRING_LENGTH];
@@ -143,5 +149,5 @@
     pDr->bDescriptorType = USB_STRING_DESCRIPTOR_TYPE;
 
-    NTSTATUS Status = VBoxUsbToolGetDescriptor(pDevObj, pDr, cbBuf, USB_STRING_DESCRIPTOR_TYPE, iIndex, LangId);
+    NTSTATUS Status = VBoxUsbToolGetDescriptor(pDevObj, pDr, cbBuf, USB_STRING_DESCRIPTOR_TYPE, iIndex, LangId, dwTimeoutMs);
     if (NT_SUCCESS(Status))
     {
@@ -175,5 +181,5 @@
 }
 
-VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolGetLangID(PDEVICE_OBJECT pDevObj, int *pLangId)
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolGetLangID(PDEVICE_OBJECT pDevObj, int *pLangId, ULONG dwTimeoutMs)
 {
     char aBuf[MAXIMUM_USB_STRING_LENGTH];
@@ -189,5 +195,5 @@
     pDr->bDescriptorType = USB_STRING_DESCRIPTOR_TYPE;
 
-    NTSTATUS Status = VBoxUsbToolGetDescriptor(pDevObj, pDr, cbBuf, USB_STRING_DESCRIPTOR_TYPE, 0, 0);
+    NTSTATUS Status = VBoxUsbToolGetDescriptor(pDevObj, pDr, cbBuf, USB_STRING_DESCRIPTOR_TYPE, 0, 0, dwTimeoutMs);
     if (NT_SUCCESS(Status))
     {
@@ -260,5 +266,5 @@
     pUrb->UrbPipeRequest.Reserved = 0;
 
-    NTSTATUS Status = VBoxUsbToolUrbPost(pDevObj, pUrb);
+    NTSTATUS Status = VBoxUsbToolUrbPost(pDevObj, pUrb, RT_INDEFINITE_WAIT);
     if (!NT_SUCCESS(Status) || !USBD_SUCCESS(pUrb->UrbHeader.Status))
     {
@@ -287,5 +293,5 @@
     pSl->Parameters.Others.Argument2 = NULL;
 
-    NTSTATUS Status = VBoxUsbToolUrbPost(pDevObj, (PURB)&Urb);
+    NTSTATUS Status = VBoxUsbToolUrbPost(pDevObj, (PURB)&Urb, RT_INDEFINITE_WAIT);
     Assert(NT_SUCCESS(Status));
     if (NT_SUCCESS(Status))
@@ -307,8 +313,46 @@
     UsbBuildSelectConfigurationRequest(pUrb, (USHORT)cbUrb, NULL);
 
-    NTSTATUS Status = VBoxUsbToolUrbPost(pDevObj, pUrb);
+    NTSTATUS Status = VBoxUsbToolUrbPost(pDevObj, pUrb, RT_INDEFINITE_WAIT);
     Assert(NT_SUCCESS(Status));
 
     VBoxUsbToolUrbFree(pUrb);
+
+    return Status;
+}
+
+VBOXUSBTOOL_DECL(PIRP) VBoxUsbToolIoBuildAsyncInternalCtl(PDEVICE_OBJECT pDevObj, ULONG uCtl, void *pvArg1, void *pvArg2)
+{
+    PIRP pIrp = IoAllocateIrp(pDevObj->StackSize, FALSE);
+    Assert(pIrp);
+    if (!pIrp)
+    {
+        return NULL;
+    }
+
+    pIrp->IoStatus.Status = STATUS_SUCCESS;
+    pIrp->IoStatus.Information = NULL;
+
+    PIO_STACK_LOCATION pSl = IoGetNextIrpStackLocation(pIrp);
+    pSl->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
+    pSl->MinorFunction = 0;
+    pSl->Parameters.DeviceIoControl.IoControlCode = uCtl;
+    pSl->Parameters.Others.Argument1 = pvArg1;
+    pSl->Parameters.Others.Argument2 = pvArg2;
+    return pIrp;
+}
+
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolIoInternalCtlSendSyncWithTimeout(PDEVICE_OBJECT pDevObj, ULONG uCtl, void *pvArg1, void *pvArg2, ULONG dwTimeoutMs)
+{
+    /* since we're going to cancel the irp on timeout, we should allocate our own IRP rather than using the threaded one
+     * */
+    PIRP pIrp = VBoxUsbToolIoBuildAsyncInternalCtl(pDevObj, uCtl, pvArg1, pvArg2);
+    if (!pIrp)
+    {
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    NTSTATUS Status = VBoxDrvToolIoPostSyncWithTimeout(pDevObj, pIrp, dwTimeoutMs);
+
+    IoFreeIrp(pIrp);
 
     return Status;
Index: /trunk/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxUsbTool.h
===================================================================
--- /trunk/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxUsbTool.h	(revision 37046)
+++ /trunk/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxUsbTool.h	(revision 37047)
@@ -47,8 +47,8 @@
 VBOXUSBTOOL_DECL(PURB) VBoxUsbToolUrbReinit(PURB pUrb, USHORT cbSize, USHORT u16Function);
 VBOXUSBTOOL_DECL(VOID) VBoxUsbToolUrbFree(PURB pUrb);
-VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolUrbPost(PDEVICE_OBJECT pDevObj, PURB pUrb);
-VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolGetDescriptor(PDEVICE_OBJECT pDevObj, void *pvBuffer, int cbBuffer, int Type, int iIndex, int LangId);
-VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolGetStringDescriptorA(PDEVICE_OBJECT pDevObj, char *pResult, ULONG cbResult, int iIndex, int LangId);
-VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolGetLangID(PDEVICE_OBJECT pDevObj, int *pLangId);
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolUrbPost(PDEVICE_OBJECT pDevObj, PURB pUrb, ULONG dwTimeoutMs);
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolGetDescriptor(PDEVICE_OBJECT pDevObj, void *pvBuffer, int cbBuffer, int Type, int iIndex, int LangId, ULONG dwTimeoutMs);
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolGetStringDescriptorA(PDEVICE_OBJECT pDevObj, char *pResult, ULONG cbResult, int iIndex, int LangId, ULONG dwTimeoutMs);
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolGetLangID(PDEVICE_OBJECT pDevObj, int *pLangId, ULONG dwTimeoutMs);
 VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolGetDeviceSpeed(PDEVICE_OBJECT pDevObj, BOOLEAN *pbIsHigh);
 VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolPipeClear(PDEVICE_OBJECT pDevObj, HANDLE hPipe, bool fReset);
@@ -57,4 +57,6 @@
 VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolIoInternalCtlSendAsync(PDEVICE_OBJECT pDevObj, ULONG uCtl, void *pvArg1, void *pvArg2, PKEVENT pEvent, PIO_STATUS_BLOCK pIoStatus);
 VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolIoInternalCtlSendSync(PDEVICE_OBJECT pDevObj, ULONG uCtl, void *pvArg1, void *pvArg2);
+VBOXUSBTOOL_DECL(PIRP) VBoxUsbToolIoBuildAsyncInternalCtl(PDEVICE_OBJECT pDevObj, ULONG uCtl, void *pvArg1, void *pvArg2);
+VBOXUSBTOOL_DECL(NTSTATUS) VBoxUsbToolIoInternalCtlSendSyncWithTimeout(PDEVICE_OBJECT pDevObj, ULONG uCtl, void *pvArg1, void *pvArg2, ULONG dwTimeoutMs);
 VBOXUSBTOOL_DECL(VOID) VBoxUsbToolStringDescriptorToUnicodeString(PUSB_STRING_DESCRIPTOR pDr, PUNICODE_STRING pUnicode);
 
Index: /trunk/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbRt.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbRt.cpp	(revision 37046)
+++ /trunk/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbRt.cpp	(revision 37047)
@@ -301,5 +301,5 @@
     {
         memset(pDevExt->Rt.devdescr, 0, sizeof (USB_DEVICE_DESCRIPTOR));
-        Status = VBoxUsbToolGetDescriptor(pDevExt->pLowerDO, pDevExt->Rt.devdescr, sizeof (USB_DEVICE_DESCRIPTOR), USB_DEVICE_DESCRIPTOR_TYPE, 0, 0);
+        Status = VBoxUsbToolGetDescriptor(pDevExt->pLowerDO, pDevExt->Rt.devdescr, sizeof (USB_DEVICE_DESCRIPTOR), USB_DEVICE_DESCRIPTOR_TYPE, 0, 0, RT_INDEFINITE_WAIT);
         if (NT_SUCCESS(Status))
         {
@@ -312,5 +312,5 @@
                 for (; i < pDevExt->Rt.devdescr->bNumConfigurations; ++i)
                 {
-                    Status = VBoxUsbToolGetDescriptor(pDevExt->pLowerDO, pDr, sizeof (USB_CONFIGURATION_DESCRIPTOR), USB_CONFIGURATION_DESCRIPTOR_TYPE, i, 0);
+                    Status = VBoxUsbToolGetDescriptor(pDevExt->pLowerDO, pDr, sizeof (USB_CONFIGURATION_DESCRIPTOR), USB_CONFIGURATION_DESCRIPTOR_TYPE, i, 0, RT_INDEFINITE_WAIT);
                     if (!NT_SUCCESS(Status))
                     {
@@ -326,5 +326,5 @@
                     }
 
-                    Status = VBoxUsbToolGetDescriptor(pDevExt->pLowerDO, pDevExt->Rt.cfgdescr[i], uTotalLength, USB_CONFIGURATION_DESCRIPTOR_TYPE, i, 0);
+                    Status = VBoxUsbToolGetDescriptor(pDevExt->pLowerDO, pDevExt->Rt.cfgdescr[i], uTotalLength, USB_CONFIGURATION_DESCRIPTOR_TYPE, i, 0, RT_INDEFINITE_WAIT);
                     if (!NT_SUCCESS(Status))
                     {
@@ -428,5 +428,5 @@
     if (pDr)
     {
-        Status = VBoxUsbToolGetDescriptor(pDevExt->pLowerDO, pDr, sizeof(*pDr), USB_DEVICE_DESCRIPTOR_TYPE, 0, 0);
+        Status = VBoxUsbToolGetDescriptor(pDevExt->pLowerDO, pDr, sizeof(*pDr), USB_DEVICE_DESCRIPTOR_TYPE, 0, 0, RT_INDEFINITE_WAIT);
         if (NT_SUCCESS(Status))
         {
@@ -443,8 +443,8 @@
             {
                 int langId;
-                Status = VBoxUsbToolGetLangID(pDevExt->pLowerDO, &langId);
+                Status = VBoxUsbToolGetLangID(pDevExt->pLowerDO, &langId, RT_INDEFINITE_WAIT);
                 if (NT_SUCCESS(Status))
                 {
-                    Status = VBoxUsbToolGetStringDescriptorA(pDevExt->pLowerDO, pDevExt->Rt.szSerial, sizeof (pDevExt->Rt.szSerial), pDr->iSerialNumber, langId);
+                    Status = VBoxUsbToolGetStringDescriptorA(pDevExt->pLowerDO, pDevExt->Rt.szSerial, sizeof (pDevExt->Rt.szSerial), pDr->iSerialNumber, langId, RT_INDEFINITE_WAIT);
                 }
                 else
@@ -572,5 +572,5 @@
         pUrb->UrbSelectConfiguration.ConfigurationDescriptor = NULL;
 
-        Status = VBoxUsbToolUrbPost(pDevExt->pLowerDO, pUrb);
+        Status = VBoxUsbToolUrbPost(pDevExt->pLowerDO, pUrb, RT_INDEFINITE_WAIT);
         if(NT_SUCCESS(Status) && USBD_SUCCESS(pUrb->UrbHeader.Status))
         {
@@ -618,5 +618,5 @@
         if (pUrb)
         {
-            Status = VBoxUsbToolUrbPost(pDevExt->pLowerDO, pUrb);
+            Status = VBoxUsbToolUrbPost(pDevExt->pLowerDO, pUrb, RT_INDEFINITE_WAIT);
             if (NT_SUCCESS(Status) && USBD_SUCCESS(pUrb->UrbHeader.Status))
             {
@@ -815,5 +815,5 @@
             pUrb->UrbSelectInterface.Interface.Length = GET_USBD_INTERFACE_SIZE(pIfDr->bNumEndpoints);
 
-            Status = VBoxUsbToolUrbPost(pDevExt->pLowerDO, pUrb);
+            Status = VBoxUsbToolUrbPost(pDevExt->pLowerDO, pUrb, RT_INDEFINITE_WAIT);
             if (NT_SUCCESS(Status) && USBD_SUCCESS(pUrb->UrbHeader.Status))
             {
Index: /trunk/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbFlt.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbFlt.cpp	(revision 37046)
+++ /trunk/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbFlt.cpp	(revision 37047)
@@ -150,11 +150,80 @@
     KeReleaseSpinLock(&g_VBoxUsbFltGlobals.Lock.Lock, g_VBoxUsbFltGlobals.Lock.OldIrql);
 
+
+typedef struct VBOXUSBFLT_BLDEV
+{
+    LIST_ENTRY ListEntry;
+    uint16_t   idVendor;
+    uint16_t   idProduct;
+    uint16_t   bcdDevice;
+} VBOXUSBFLT_BLDEV, *PVBOXUSBFLT_BLDEV;
+
+#define PVBOXUSBFLT_BLDEV_FROM_LE(_pLe) ( (PVBOXUSBFLT_BLDEV)( ((uint8_t*)(_pLe)) - RT_OFFSETOF(VBOXUSBFLT_BLDEV, ListEntry) ) )
+
 typedef struct VBOXUSBFLTGLOBALS
 {
     LIST_ENTRY DeviceList;
     LIST_ENTRY ContextList;
+    /* devices known to misbehave */
+    LIST_ENTRY BlackDeviceList;
     VBOXUSBFLT_LOCK Lock;
 } VBOXUSBFLTGLOBALS, *PVBOXUSBFLTGLOBALS;
 static VBOXUSBFLTGLOBALS g_VBoxUsbFltGlobals;
+
+static bool vboxUsbFltBlDevMatchLocked(uint16_t idVendor, uint16_t idProduct, uint16_t bcdDevice)
+{
+    for (PLIST_ENTRY pEntry = g_VBoxUsbFltGlobals.BlackDeviceList.Flink;
+            pEntry != &g_VBoxUsbFltGlobals.BlackDeviceList;
+            pEntry = pEntry->Flink)
+    {
+        PVBOXUSBFLT_BLDEV pDev = PVBOXUSBFLT_BLDEV_FROM_LE(pEntry);
+        if (pDev->idVendor != idVendor)
+            continue;
+        if (pDev->idProduct != idProduct)
+            continue;
+        if (pDev->bcdDevice != bcdDevice)
+            continue;
+
+        return true;
+    }
+    return false;
+}
+
+static NTSTATUS vboxUsbFltBlDevAddLocked(uint16_t idVendor, uint16_t idProduct, uint16_t bcdDevice)
+{
+    if (vboxUsbFltBlDevMatchLocked(idVendor, idProduct, bcdDevice))
+        return STATUS_SUCCESS;
+    PVBOXUSBFLT_BLDEV pDev = (PVBOXUSBFLT_BLDEV)VBoxUsbMonMemAllocZ(sizeof (*pDev));
+    if (!pDev)
+    {
+        AssertFailed();
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    pDev->idVendor = idVendor;
+    pDev->idProduct = idProduct;
+    pDev->bcdDevice = bcdDevice;
+    InsertHeadList(&g_VBoxUsbFltGlobals.BlackDeviceList, &pDev->ListEntry);
+    return STATUS_SUCCESS;
+}
+
+static void vboxUsbFltBlDevClearLocked()
+{
+    PLIST_ENTRY pNext;
+    for (PLIST_ENTRY pEntry = g_VBoxUsbFltGlobals.BlackDeviceList.Flink;
+            pEntry != &g_VBoxUsbFltGlobals.BlackDeviceList;
+            pEntry = pNext)
+    {
+        pNext = pEntry->Flink;
+        VBoxUsbMonMemFree(pEntry);
+    }
+}
+
+static void vboxUsbFltBlDevPopulateWithKnownLocked()
+{
+    /* this one halts when trying to get string descriptors from it */
+    vboxUsbFltBlDevAddLocked(0x5ac, 0x921c, 0x115);
+}
+
 
 DECLINLINE(void) vboxUsbFltDevRetain(PVBOXUSBFLT_DEVICE pDevice)
@@ -217,5 +286,5 @@
 static PVBOXUSBFLT_DEVICE vboxUsbFltDevGetLocked(PDEVICE_OBJECT pPdo)
 {
-#ifdef DEBUG_mista
+#ifdef DEBUG_misha
     for (PLIST_ENTRY pEntry = g_VBoxUsbFltGlobals.DeviceList.Flink;
             pEntry != &g_VBoxUsbFltGlobals.DeviceList;
@@ -315,4 +384,6 @@
 }
 
+#define VBOXUSBMON_POPULATE_REQUEST_TIMEOUT_MS 10000
+
 static NTSTATUS vboxUsbFltDevPopulate(PVBOXUSBFLT_DEVICE pDevice, PDEVICE_OBJECT pDo /*, BOOLEAN bPopulateNonFilterProps*/)
 {
@@ -331,8 +402,18 @@
     do
     {
-        Status = VBoxUsbToolGetDescriptor(pDo, pDevDr, sizeof(*pDevDr), USB_DEVICE_DESCRIPTOR_TYPE, 0, 0);
+        Status = VBoxUsbToolGetDescriptor(pDo, pDevDr, sizeof(*pDevDr), USB_DEVICE_DESCRIPTOR_TYPE, 0, 0, VBOXUSBMON_POPULATE_REQUEST_TIMEOUT_MS);
         if (!NT_SUCCESS(Status))
         {
-            LogRel(("VBoxUSBGetDeviceDescription: getting device descriptor failed\n"));
+            LogRel((__FUNCTION__": getting device descriptor failed\n"));
+            break;
+        }
+
+        if (vboxUsbFltBlDevMatchLocked(pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice))
+        {
+            LogRel((__FUNCTION__": found a known black list device, vid(0x%x), pid(0x%x), rev(0x%x)\n", pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice));
+#ifdef DEBUG_misha
+            AssertFailed();
+#endif
+            Status = STATUS_UNSUCCESSFUL;
             break;
         }
@@ -354,8 +435,14 @@
             int             langId;
 
-            Status = VBoxUsbToolGetLangID(pDo, &langId);
+            Status = VBoxUsbToolGetLangID(pDo, &langId, VBOXUSBMON_POPULATE_REQUEST_TIMEOUT_MS);
             if (!NT_SUCCESS(Status))
             {
                 AssertMsgFailed((__FUNCTION__": reading language ID failed\n"));
+                if (Status == STATUS_CANCELLED)
+                {
+                    AssertMsgFailed((__FUNCTION__": found a new black list device, vid(0x%x), pid(0x%x), rev(0x%x)\n", pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice));
+                    vboxUsbFltBlDevAddLocked(pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice);
+                    Status = STATUS_UNSUCCESSFUL;
+                }
                 break;
             }
@@ -363,8 +450,14 @@
             if (pDevDr->iSerialNumber)
             {
-                Status = VBoxUsbToolGetStringDescriptorA(pDo, pDevice->szSerial, sizeof (pDevice->szSerial), pDevDr->iSerialNumber, langId);
+                Status = VBoxUsbToolGetStringDescriptorA(pDo, pDevice->szSerial, sizeof (pDevice->szSerial), pDevDr->iSerialNumber, langId, VBOXUSBMON_POPULATE_REQUEST_TIMEOUT_MS);
                 if (!NT_SUCCESS(Status))
                 {
                     AssertMsgFailed((__FUNCTION__": reading serial number failed\n"));
+                    if (Status == STATUS_CANCELLED)
+                    {
+                        AssertMsgFailed((__FUNCTION__": found a new black list device, vid(0x%x), pid(0x%x), rev(0x%x)\n", pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice));
+                        vboxUsbFltBlDevAddLocked(pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice);
+                        Status = STATUS_UNSUCCESSFUL;
+                    }
                     break;
                 }
@@ -373,8 +466,14 @@
             if (pDevDr->iManufacturer)
             {
-                Status = VBoxUsbToolGetStringDescriptorA(pDo, pDevice->szMfgName, sizeof (pDevice->szMfgName), pDevDr->iManufacturer, langId);
+                Status = VBoxUsbToolGetStringDescriptorA(pDo, pDevice->szMfgName, sizeof (pDevice->szMfgName), pDevDr->iManufacturer, langId, VBOXUSBMON_POPULATE_REQUEST_TIMEOUT_MS);
                 if (!NT_SUCCESS(Status))
                 {
                     AssertMsgFailed((__FUNCTION__": reading manufacturer name failed\n"));
+                    if (Status == STATUS_CANCELLED)
+                    {
+                        AssertMsgFailed((__FUNCTION__": found a new black list device, vid(0x%x), pid(0x%x), rev(0x%x)\n", pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice));
+                        vboxUsbFltBlDevAddLocked(pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice);
+                        Status = STATUS_UNSUCCESSFUL;
+                    }
                     break;
                 }
@@ -383,8 +482,14 @@
             if (pDevDr->iProduct)
             {
-                Status = VBoxUsbToolGetStringDescriptorA(pDo, pDevice->szProduct, sizeof (pDevice->szProduct), pDevDr->iProduct, langId);
+                Status = VBoxUsbToolGetStringDescriptorA(pDo, pDevice->szProduct, sizeof (pDevice->szProduct), pDevDr->iProduct, langId, VBOXUSBMON_POPULATE_REQUEST_TIMEOUT_MS);
                 if (!NT_SUCCESS(Status))
                 {
                     AssertMsgFailed((__FUNCTION__": reading product name failed\n"));
+                    if (Status == STATUS_CANCELLED)
+                    {
+                        AssertMsgFailed((__FUNCTION__": found a new black list device, vid(0x%x), pid(0x%x), rev(0x%x)\n", pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice));
+                        vboxUsbFltBlDevAddLocked(pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice);
+                        Status = STATUS_UNSUCCESSFUL;
+                    }
                     break;
                 }
@@ -1218,4 +1323,6 @@
     InitializeListHead(&g_VBoxUsbFltGlobals.DeviceList);
     InitializeListHead(&g_VBoxUsbFltGlobals.ContextList);
+    InitializeListHead(&g_VBoxUsbFltGlobals.BlackDeviceList);
+    vboxUsbFltBlDevPopulateWithKnownLocked();
     VBOXUSBFLT_LOCK_INIT();
     return STATUS_SUCCESS;
@@ -1269,4 +1376,7 @@
         vboxUsbFltDevRelease(pDevice);
     }
+
+    vboxUsbFltBlDevClearLocked();
+
     VBOXUSBFLT_LOCK_TERM();
 
