Index: trunk/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbFlt.cpp
===================================================================
--- trunk/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbFlt.cpp	(revision 38436)
+++ trunk/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbFlt.cpp	(revision 38488)
@@ -403,5 +403,5 @@
     if (pDevDr == NULL)
     {
-        WARN(("Failed to alloc mem for urb\n"));
+        WARN(("Failed to alloc mem for urb"));
         return STATUS_INSUFFICIENT_RESOURCES;
     }
@@ -412,5 +412,5 @@
         if (!NT_SUCCESS(Status))
         {
-            WARN(("getting device descriptor failed, Status (0x%x)\n", Status));
+            WARN(("getting device descriptor failed, Status (0x%x)", Status));
             break;
         }
@@ -418,10 +418,10 @@
         if (vboxUsbFltBlDevMatchLocked(pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice))
         {
-            WARN(("found a known black list device, vid(0x%x), pid(0x%x), rev(0x%x)\n", pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice));
+            WARN(("found a known black list device, vid(0x%x), pid(0x%x), rev(0x%x)", pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice));
             Status = STATUS_UNSUCCESSFUL;
             break;
         }
 
-        LOG(("Device pid=%x vid=%x rev=%x\n", pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice));
+        LOG(("Device pid=%x vid=%x rev=%x", pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice));
         pDevice->idVendor     = pDevDr->idVendor;
         pDevice->idProduct    = pDevDr->idProduct;
@@ -442,8 +442,8 @@
             if (!NT_SUCCESS(Status))
             {
-                WARN(("reading language ID failed\n"));
+                WARN(("reading language ID failed"));
                 if (Status == STATUS_CANCELLED)
                 {
-                    WARN(("found a new black list device, vid(0x%x), pid(0x%x), rev(0x%x)\n", pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice));
+                    WARN(("found a new black list device, vid(0x%x), pid(0x%x), rev(0x%x)", pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice));
                     vboxUsbFltBlDevAddLocked(pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice);
                     Status = STATUS_UNSUCCESSFUL;
@@ -457,9 +457,9 @@
                 if (!NT_SUCCESS(Status))
                 {
-                    WARN(("reading serial number failed\n"));
+                    WARN(("reading serial number failed"));
                     ASSERT_WARN(pDevice->szSerial[0] == '\0', ("serial is not zero!!"));
                     if (Status == STATUS_CANCELLED)
                     {
-                        WARN(("found a new black list device, vid(0x%x), pid(0x%x), rev(0x%x)\n", pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice));
+                        WARN(("found a new black list device, vid(0x%x), pid(0x%x), rev(0x%x)", pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice));
                         vboxUsbFltBlDevAddLocked(pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice);
                         Status = STATUS_UNSUCCESSFUL;
@@ -476,9 +476,9 @@
                 if (!NT_SUCCESS(Status))
                 {
-                    WARN(("reading manufacturer name failed\n"));
+                    WARN(("reading manufacturer name failed"));
                     ASSERT_WARN(pDevice->szMfgName[0] == '\0', ("szMfgName is not zero!!"));
                     if (Status == STATUS_CANCELLED)
                     {
-                        WARN(("found a new black list device, vid(0x%x), pid(0x%x), rev(0x%x)\n", pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice));
+                        WARN(("found a new black list device, vid(0x%x), pid(0x%x), rev(0x%x)", pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice));
                         vboxUsbFltBlDevAddLocked(pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice);
                         Status = STATUS_UNSUCCESSFUL;
@@ -495,9 +495,9 @@
                 if (!NT_SUCCESS(Status))
                 {
-                    WARN(("reading product name failed\n"));
+                    WARN(("reading product name failed"));
                     ASSERT_WARN(pDevice->szProduct[0] == '\0', ("szProduct is not zero!!"));
                     if (Status == STATUS_CANCELLED)
                     {
-                        WARN(("found a new black list device, vid(0x%x), pid(0x%x), rev(0x%x)\n", pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice));
+                        WARN(("found a new black list device, vid(0x%x), pid(0x%x), rev(0x%x)", pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice));
                         vboxUsbFltBlDevAddLocked(pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice);
                         Status = STATUS_UNSUCCESSFUL;
@@ -521,5 +521,5 @@
                 if (!NT_SUCCESS(Status))
                 {
-                    AssertMsgFailed((__FUNCTION__": IoGetDeviceProperty failed Status (0x%x)\n", Status));
+                    AssertMsgFailed((__FUNCTION__": IoGetDeviceProperty failed Status (0x%x)", Status));
                     break;
                 }
@@ -535,5 +535,5 @@
                 if (!NT_SUCCESS(Status))
                 {
-                    AssertMsgFailed((__FUNCTION__": RtlUnicodeStringToAnsiString failed Status (0x%x)\n", Status));
+                    AssertMsgFailed((__FUNCTION__": RtlUnicodeStringToAnsiString failed Status (0x%x)", Status));
                     break;
                 }
@@ -543,10 +543,10 @@
                 if (!NT_SUCCESS(Status))
                 {
-                    AssertMsgFailed((__FUNCTION__": VBoxUsbToolGetDeviceSpeed failed Status (0x%x)\n", Status));
+                    AssertMsgFailed((__FUNCTION__": VBoxUsbToolGetDeviceSpeed failed Status (0x%x)", Status));
                     break;
                 }
             }
 #endif
-            LOG((": strings: '%s':'%s':'%s' (lang ID %x)\n",
+            LOG((": strings: '%s':'%s':'%s' (lang ID %x)",
                         pDevice->szMfgName, pDevice->szProduct, pDevice->szSerial, langId));
         }
@@ -754,182 +754,141 @@
 }
 
+typedef struct VBOXUSBFLTCHECKWALKER
+{
+    PVBOXUSBFLTCTX pContext;
+} VBOXUSBFLTCHECKWALKER, *PVBOXUSBFLTCHECKWALKER;
+
+static DECLCALLBACK(BOOLEAN) vboxUsbFltFilterCheckWalker(PFILE_OBJECT pFile, PDEVICE_OBJECT pTopDo, PDEVICE_OBJECT pHubDo, PVOID pvContext)
+{
+    PVBOXUSBFLTCHECKWALKER pData = (PVBOXUSBFLTCHECKWALKER)pvContext;
+    PVBOXUSBFLTCTX pContext = pData->pContext;
+
+    LOG(("Visiting pFile(0x%p), pTopDo(0x%p), pHubDo(0x%p), oContext(0x%p)", pFile, pTopDo, pHubDo, pContext));
+    KIRQL Irql = KeGetCurrentIrql();
+    ASSERT_WARN(Irql == PASSIVE_LEVEL, ("unexpected IRQL (%d)", Irql));
+
+
+
+    PDEVICE_RELATIONS pDevRelations = NULL;
+
+    NTSTATUS Status = VBoxUsbMonQueryBusRelations(pTopDo, pFile, &pDevRelations);
+    if (Status == STATUS_SUCCESS && pDevRelations)
+    {
+        ULONG cReplugPdos = pDevRelations->Count;
+        LIST_ENTRY ReplugDevList;
+        InitializeListHead(&ReplugDevList);
+        for (ULONG k = 0; k < pDevRelations->Count; ++k)
+        {
+            PDEVICE_OBJECT pDevObj = pDevRelations->Objects[k];
+
+            LOG(("Found existing USB PDO 0x%p", pDevObj));
+            VBOXUSBFLT_LOCK_ACQUIRE();
+            PVBOXUSBFLT_DEVICE pDevice = vboxUsbFltDevGetLocked(pDevObj);
+            if (pDevice)
+            {
+                LOG(("Found existing device info (0x%p) for PDO 0x%p", pDevice, pDevObj));
+                bool bReplug = vboxUsbFltDevCheckReplugLocked(pDevice, pContext);
+                if (bReplug)
+                {
+                    LOG(("Replug needed for device (0x%p)", pDevice));
+                    InsertHeadList(&ReplugDevList, &pDevice->RepluggingLe);
+                    vboxUsbFltDevRetain(pDevice);
+                    /* do not dereference object since we will use it later */
+                }
+                else
+                {
+                    LOG(("Replug NOT needed for device (0x%p)", pDevice));
+                    ObDereferenceObject(pDevObj);
+                }
+
+                VBOXUSBFLT_LOCK_RELEASE();
+
+                pDevRelations->Objects[k] = NULL;
+                --cReplugPdos;
+                ASSERT_WARN((uint32_t)cReplugPdos < UINT32_MAX/2, ("cReplugPdos(%d) state broken", cReplugPdos));
+                continue;
+            }
+            VBOXUSBFLT_LOCK_RELEASE();
+
+            LOG(("NO device info found for PDO 0x%p", pDevObj));
+            VBOXUSBFLT_DEVICE Device;
+            Status = vboxUsbFltDevPopulate(&Device, pDevObj /*, FALSE /* only need filter properties */);
+            if (NT_SUCCESS(Status))
+            {
+                uintptr_t uId = 0;
+                bool fFilter = false;
+                bool fIsOneShot = false;
+                VBOXUSBFLT_LOCK_ACQUIRE();
+                PVBOXUSBFLTCTX pCtx = vboxUsbFltDevMatchLocked(&Device, &uId,
+                        false, /* do not remove a one-shot filter */
+                        &fFilter, &fIsOneShot);
+                VBOXUSBFLT_LOCK_RELEASE();
+                LOG(("Matching Info: Filter (0x%p), pCtx(0x%p), fFilter(%d), fIsOneShot(%d)", uId, pCtx, (int)fFilter, (int)fIsOneShot));
+                if (fFilter)
+                {
+                    LOG(("Matching: This device SHOULD be filtered"));
+                    /* this device needs to be filtered, but it's not,
+                     * leave the PDO in array to issue a replug request for it
+                     * later on */
+                    continue;
+                }
+            }
+            else
+            {
+                WARN(("vboxUsbFltDevPopulate for PDO 0x%p failed with Status 0x%x", pDevObj, Status));
+            }
+
+            LOG(("Matching: This device should NOT be filtered"));
+            /* this device should not be filtered, and it's not */
+            ObDereferenceObject(pDevObj);
+            pDevRelations->Objects[k] = NULL;
+            --cReplugPdos;
+            ASSERT_WARN((uint32_t)cReplugPdos < UINT32_MAX/2, ("cReplugPdos is %d", cReplugPdos));
+        }
+
+        LOG(("(%d) non-matched PDOs to be replugged", cReplugPdos));
+
+        if (cReplugPdos)
+        {
+            for (ULONG k = 0; k < pDevRelations->Count; ++k)
+            {
+                if (!pDevRelations->Objects[k])
+                    continue;
+
+                Status = vboxUsbFltPdoReplug(pDevRelations->Objects[k]);
+                ASSERT_WARN(Status == STATUS_SUCCESS, ("vboxUsbFltPdoReplug ailed Status(0x%x)", Status));
+                ObDereferenceObject(pDevRelations->Objects[k]);
+                if (!--cReplugPdos)
+                    break;
+            }
+
+            ASSERT_WARN(!cReplugPdos, ("cReplugPdosreached zero!"));
+        }
+
+        vboxUsbFltReplugList(&ReplugDevList);
+
+        ExFreePool(pDevRelations);
+    }
+    else
+    {
+        WARN(("VBoxUsbMonQueryBusRelations failed for DO(0x%p), Status(0x%x), pDevRelations(0x%p)",
+                pTopDo, Status, pDevRelations));
+    }
+
+    LOG(("Done Visiting pFile(0x%p), pTopDo(0x%p), pHubDo(0x%p), oContext(0x%p)", pFile, pTopDo, pHubDo, pContext));
+
+    return TRUE;
+}
+
 NTSTATUS VBoxUsbFltFilterCheck(PVBOXUSBFLTCTX pContext)
 {
-    NTSTATUS Status;
-    UNICODE_STRING szStandardControllerName[RT_ELEMENTS(lpszStandardControllerName)];
     KIRQL Irql = KeGetCurrentIrql();
-    Assert(Irql == PASSIVE_LEVEL);
+    ASSERT_WARN(Irql == PASSIVE_LEVEL, ("unexpected IRQL (%d)", Irql));
 
     LOG(("Running filters, Context (0x%p)..", pContext));
 
-    for (int i=0;i<RT_ELEMENTS(lpszStandardControllerName);i++)
-    {
-        szStandardControllerName[i].Length = 0;
-        szStandardControllerName[i].MaximumLength = 0;
-        szStandardControllerName[i].Buffer = 0;
-
-        RtlInitUnicodeString(&szStandardControllerName[i], lpszStandardControllerName[i]);
-    }
-
-    for (int i = 0; i < 16; i++)
-    {
-        char            szHubName[32];
-        WCHAR           szwHubName[32];
-        UNICODE_STRING  UnicodeName;
-        ANSI_STRING     AnsiName;
-        PDEVICE_OBJECT  pHubDevObj;
-        PFILE_OBJECT    pHubFileObj;
-
-        sprintf(szHubName, "\\Device\\USBPDO-%d", i);
-
-        UnicodeName.Length = 0;
-        UnicodeName.MaximumLength = sizeof (szwHubName);
-        UnicodeName.Buffer = szwHubName;
-
-        RtlInitAnsiString(&AnsiName, szHubName);
-        RtlAnsiStringToUnicodeString(&UnicodeName, &AnsiName, FALSE);
-
-        Status = IoGetDeviceObjectPointer(&UnicodeName, FILE_READ_DATA, &pHubFileObj, &pHubDevObj);
-        if (Status == STATUS_SUCCESS)
-        {
-            LOG(("IoGetDeviceObjectPointer for %s returned %p %p\n", szHubName, pHubDevObj, pHubFileObj));
-
-            if (pHubDevObj->DriverObject
-                && pHubDevObj->DriverObject->DriverName.Buffer
-                && pHubDevObj->DriverObject->DriverName.Length
-               )
-            {
-                for (int j = 0; j < RT_ELEMENTS(lpszStandardControllerName); ++j)
-                {
-                    if (!RtlCompareUnicodeString(&szStandardControllerName[j], &pHubDevObj->DriverObject->DriverName, TRUE /* case insensitive */))
-                    {
-                        PDEVICE_RELATIONS pDevRelations = NULL;
-
-                        LOG(("Flt Associated driver "));
-                        LOG_USTR(&pHubDevObj->DriverObject->DriverName);
-                        LOG((" -> related dev obj=0x%p", pHubDevObj));
-
-                        Status = VBoxUsbMonQueryBusRelations(pHubDevObj, pHubFileObj, &pDevRelations);
-                        if (Status == STATUS_SUCCESS && pDevRelations)
-                        {
-                            ULONG cReplugPdos = pDevRelations->Count;
-                            LIST_ENTRY ReplugDevList;
-                            InitializeListHead(&ReplugDevList);
-                            for (ULONG k = 0; k < pDevRelations->Count; ++k)
-                            {
-                                PDEVICE_OBJECT pDevObj = pDevRelations->Objects[k];
-
-                                LOG(("Found existing USB PDO 0x%p", pDevObj));
-                                VBOXUSBFLT_LOCK_ACQUIRE();
-                                PVBOXUSBFLT_DEVICE pDevice = vboxUsbFltDevGetLocked(pDevObj);
-                                if (pDevice)
-                                {
-                                    LOG(("Found existing device info (0x%p) for PDO 0x%p", pDevice, pDevObj));
-                                    bool bReplug = vboxUsbFltDevCheckReplugLocked(pDevice, pContext);
-                                    if (bReplug)
-                                    {
-                                        LOG(("Replug needed for device (0x%p)", pDevice));
-                                        InsertHeadList(&ReplugDevList, &pDevice->RepluggingLe);
-                                        vboxUsbFltDevRetain(pDevice);
-                                        /* do not dereference object since we will use it later */
-                                    }
-                                    else
-                                    {
-                                        LOG(("Replug NOT needed for device (0x%p)", pDevice));
-                                        ObDereferenceObject(pDevObj);
-                                    }
-
-                                    VBOXUSBFLT_LOCK_RELEASE();
-
-                                    pDevRelations->Objects[k] = NULL;
-                                    --cReplugPdos;
-                                    ASSERT_WARN((uint32_t)cReplugPdos < UINT32_MAX/2, ("cReplugPdos(%d) state broken", cReplugPdos));
-                                    continue;
-                                }
-                                VBOXUSBFLT_LOCK_RELEASE();
-
-                                LOG(("NO device info found for PDO 0x%p", pDevObj));
-                                VBOXUSBFLT_DEVICE Device;
-                                Status = vboxUsbFltDevPopulate(&Device, pDevObj /*, FALSE /* only need filter properties */);
-                                if (NT_SUCCESS(Status))
-                                {
-                                    uintptr_t uId = 0;
-                                    bool fFilter = false;
-                                    bool fIsOneShot = false;
-                                    VBOXUSBFLT_LOCK_ACQUIRE();
-                                    PVBOXUSBFLTCTX pCtx = vboxUsbFltDevMatchLocked(&Device, &uId,
-                                            false, /* do not remove a one-shot filter */
-                                            &fFilter, &fIsOneShot);
-                                    VBOXUSBFLT_LOCK_RELEASE();
-                                    LOG(("Matching Info: Filter (0x%p), pCtx(0x%p), fFilter(%d), fIsOneShot(%d)", uId, pCtx, (int)fFilter, (int)fIsOneShot));
-                                    if (fFilter)
-                                    {
-                                        LOG(("Matching: This device SHOULD be filtered"));
-                                        /* this device needs to be filtered, but it's not,
-                                         * leave the PDO in array to issue a replug request for it
-                                         * later on */
-                                        continue;
-                                    }
-                                }
-                                else
-                                {
-                                    WARN(("vboxUsbFltDevPopulate for PDO 0x%p failed with Status 0x%x", pDevObj, Status));
-                                }
-
-                                LOG(("Matching: This device should NOT be filtered"));
-                                /* this device should not be filtered, and it's not */
-                                ObDereferenceObject(pDevObj);
-                                pDevRelations->Objects[k] = NULL;
-                                --cReplugPdos;
-                                ASSERT_WARN((uint32_t)cReplugPdos < UINT32_MAX/2, ("cReplugPdos is %d", cReplugPdos));
-                            }
-
-                            LOG(("(%d) non-matched PDOs to be replugged", cReplugPdos));
-
-                            if (cReplugPdos)
-                            {
-                                for (ULONG k = 0; k < pDevRelations->Count; ++k)
-                                {
-                                    if (!pDevRelations->Objects[k])
-                                        continue;
-
-                                    Status = vboxUsbFltPdoReplug(pDevRelations->Objects[k]);
-                                    ASSERT_WARN(Status == STATUS_SUCCESS, ("vboxUsbFltPdoReplug ailed Status(0x%x)", Status));
-                                    ObDereferenceObject(pDevRelations->Objects[k]);
-                                    if (!--cReplugPdos)
-                                        break;
-                                }
-
-                                ASSERT_WARN(!cReplugPdos, ("cReplugPdosreached zero!"));
-                            }
-
-                            vboxUsbFltReplugList(&ReplugDevList);
-
-                            ExFreePool(pDevRelations);
-                        }
-                        else
-                        {
-                            WARN(("VBoxUsbMonQueryBusRelations failed for DO(0x%p), Status(0x%x), pDevRelations(0x%p)",
-                                    pHubDevObj, Status, pDevRelations));
-                        }
-                    }
-                    else
-                    {
-                        LOG(("driver name not match, was:"));
-                        LOG_USTR(&pHubDevObj->DriverObject->DriverName);
-                        LOG(("but expected:"));
-                        LOG_USTR(&szStandardControllerName[j]);
-                    }
-                }
-            }
-            else
-            {
-                LOG(("null driver object (0x%p) or name buffer (0x%p), length(%d)", pHubDevObj->DriverObject,
-                        pHubDevObj->DriverObject ? pHubDevObj->DriverObject->DriverName.Buffer : NULL,
-                        pHubDevObj->DriverObject ? pHubDevObj->DriverObject->DriverName.Length : 0));
-            }
-            ObDereferenceObject(pHubFileObj);
-        }
-    }
+    VBOXUSBFLTCHECKWALKER Data;
+    Data.pContext = pContext;
+    vboxUsbMonHubDevWalk(vboxUsbFltFilterCheckWalker, &Data, VBOXUSBMONHUBWALK_F_FDO);
 
     LOG(("DONE Running filters, Context (0x%p)", pContext));
@@ -1029,10 +988,10 @@
     *pId = 0;
     /* LOG the filter details. */
-    LOG((__FUNCTION__": %s %s %s\n",
+    LOG((__FUNCTION__": %s %s %s",
         USBFilterGetString(pFilter, USBFILTERIDX_MANUFACTURER_STR)  ? USBFilterGetString(pFilter, USBFILTERIDX_MANUFACTURER_STR)  : "<null>",
         USBFilterGetString(pFilter, USBFILTERIDX_PRODUCT_STR)       ? USBFilterGetString(pFilter, USBFILTERIDX_PRODUCT_STR)       : "<null>",
         USBFilterGetString(pFilter, USBFILTERIDX_SERIAL_NUMBER_STR) ? USBFilterGetString(pFilter, USBFILTERIDX_SERIAL_NUMBER_STR) : "<null>"));
 #ifdef VBOX_USB_WITH_VERBOSE_LOGGING
-    LOG(("VBoxUSBClient::addFilter: idVendor=%#x idProduct=%#x bcdDevice=%#x bDeviceClass=%#x bDeviceSubClass=%#x bDeviceProtocol=%#x bBus=%#x bPort=%#x Type%#x\n",
+    LOG(("VBoxUSBClient::addFilter: idVendor=%#x idProduct=%#x bcdDevice=%#x bDeviceClass=%#x bDeviceSubClass=%#x bDeviceProtocol=%#x bBus=%#x bPort=%#x Type%#x",
               USBFilterGetNum(pFilter, USBFILTERIDX_VENDOR_ID),
               USBFilterGetNum(pFilter, USBFILTERIDX_PRODUCT_ID),
@@ -1394,5 +1353,5 @@
     {
         pDevice->enmState = VBOXUSBFLT_DEVSTATE_CAPTURED;
-        LOG(("The proxy notified proxy start for the captured device 0x%x\n", pDevice));
+        LOG(("The proxy notified proxy start for the captured device 0x%x", pDevice));
         vboxUsbFltDevRetain(pDevice);
         vboxUsbFltSignalChangeLocked();
@@ -1415,5 +1374,5 @@
     {
         /* this is due to devie was physically removed */
-        LOG(("The proxy notified proxy stop for the captured device 0x%x, current state %d\n", pDevice, pDevice->enmState));
+        LOG(("The proxy notified proxy stop for the captured device 0x%x, current state %d", pDevice, pDevice->enmState));
         pDevice->enmState = VBOXUSBFLT_DEVSTATE_CAPTURING;
         vboxUsbFltSignalChangeLocked();
Index: trunk/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbMon.cpp
===================================================================
--- trunk/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbMon.cpp	(revision 38436)
+++ trunk/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbMon.cpp	(revision 38488)
@@ -102,5 +102,5 @@
         case _t: return #_t
 #define VBOXUSBDBG_STRCASE_UNKNOWN(_v) \
-        default: LOG((__FUNCTION__": Unknown Value (0n%d), (0x%x)\n", _v, _v)); return "Unknown"
+        default: LOG((__FUNCTION__": Unknown Value (0n%d), (0x%x)", _v, _v)); return "Unknown"
 
 static const char* vboxUsbDbgStrPnPMn(UCHAR uMn)
@@ -168,5 +168,5 @@
     if (!pIrp)
     {
-        WARN(("IoBuildDeviceIoControlRequest failed!!\n"));
+        WARN(("IoBuildDeviceIoControlRequest failed!!"));
         return STATUS_INSUFFICIENT_RESOURCES;
     }
@@ -182,5 +182,5 @@
     if (Status == STATUS_PENDING)
     {
-        LOG(("IoCallDriver returned STATUS_PENDING!!\n"));
+        LOG(("IoCallDriver returned STATUS_PENDING!!"));
         KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
         Status = IoStatus.Status;
@@ -190,5 +190,5 @@
     {
         PDEVICE_RELATIONS pRel = (PDEVICE_RELATIONS)IoStatus.Information;
-        LOG(("pRel = %p\n", pRel));
+        LOG(("pRel = %p", pRel));
         if (VALID_PTR(pRel))
         {
@@ -197,17 +197,315 @@
         else
         {
-            WARN(("Invalid pointer %p\n", pRel));
+            WARN(("Invalid pointer %p", pRel));
         }
     }
     else
     {
-        WARN(("IRP_MN_QUERY_DEVICE_RELATIONS failed Status(0x%x)\n", Status));
-    }
-
-    LOG(("IoCallDriver returned %x\n", Status));
+        WARN(("IRP_MN_QUERY_DEVICE_RELATIONS failed Status(0x%x)", Status));
+    }
+
+    LOG(("IoCallDriver returned %x", Status));
     return Status;
 }
 
-static PDRIVER_OBJECT vboxUsbMonHookFindHubDrvObj()
+RT_C_DECLS_BEGIN
+/* these two come from IFS Kit, which is not included in 2K DDK we use,
+ * although they are documented and exported in ntoskrnl,
+ * and both should be present for >= XP according to MSDN */
+NTKERNELAPI
+NTSTATUS
+ObQueryNameString(
+    __in PVOID Object,
+    __out_bcount_opt(Length) POBJECT_NAME_INFORMATION ObjectNameInfo,
+    __in ULONG Length,
+    __out PULONG ReturnLength
+    );
+
+NTKERNELAPI
+PDEVICE_OBJECT
+IoGetLowerDeviceObject(
+    __in  PDEVICE_OBJECT  DeviceObject
+    );
+
+RT_C_DECLS_END
+
+typedef DECLCALLBACK(VOID) FNVBOXUSBDEVNAMEMATCHER(PDEVICE_OBJECT pDo, PUNICODE_STRING pName, PVOID pvMatcher);
+typedef FNVBOXUSBDEVNAMEMATCHER *PFNVBOXUSBDEVNAMEMATCHER;
+
+static NTSTATUS vboxUsbObjCheckName(PDEVICE_OBJECT pDo, PFNVBOXUSBDEVNAMEMATCHER pfnMatcher, PVOID pvMatcher)
+{
+    union
+    {
+        OBJECT_NAME_INFORMATION Info;
+        char buf[1024];
+    } buf;
+    ULONG cbLength = 0;
+
+    POBJECT_NAME_INFORMATION pInfo = &buf.Info;
+    NTSTATUS Status = ObQueryNameString(pDo, &buf.Info, sizeof (buf), &cbLength);
+    if (!NT_SUCCESS(Status))
+    {
+        if (STATUS_INFO_LENGTH_MISMATCH != Status)
+        {
+            WARN(("ObQueryNameString failed 0x%x", Status));
+            return Status;
+        }
+
+        LOG(("ObQueryNameString returned STATUS_INFO_LENGTH_MISMATCH, required size %d", cbLength));
+
+        pInfo = (POBJECT_NAME_INFORMATION)VBoxUsbMonMemAlloc(cbLength);
+        if (!pInfo)
+        {
+            WARN(("VBoxUsbMonMemAlloc failed"));
+            return STATUS_NO_MEMORY;
+        }
+        Status = ObQueryNameString(pDo, pInfo, cbLength, &cbLength);
+        if (!NT_SUCCESS(Status))
+        {
+            WARN(("ObQueryNameString second try failed 0x%x", Status));
+            VBoxUsbMonMemFree(pInfo);
+            return Status;
+        }
+    }
+
+    /* we've got the name! */
+    LOG(("got the name:"));
+    LOG_USTR(&pInfo->Name);
+    pfnMatcher(pDo, &pInfo->Name, pvMatcher);
+
+    if (&buf.Info != pInfo)
+    {
+        LOG(("freeing allocated pInfo(0x%p)", pInfo));
+        VBoxUsbMonMemFree(pInfo);
+    }
+    else
+    {
+        LOG(("no freeing info needed"));
+    }
+
+    return STATUS_SUCCESS;
+}
+
+
+typedef DECLCALLBACK(BOOLEAN) FNVBOXUSBDEVSTACKWALKER(PDEVICE_OBJECT pTopDo, PDEVICE_OBJECT pCurDo, PVOID pvContext);
+typedef FNVBOXUSBDEVSTACKWALKER *PFNVBOXUSBDEVSTACKWALKER;
+
+VOID vboxUsbObjDevStackWalk(PDEVICE_OBJECT pDo, PFNVBOXUSBDEVSTACKWALKER pfnWalker, PVOID pvWalker)
+{
+    LOG(("==>tree walk for Do 0x%p", pDo));
+    PDEVICE_OBJECT pCurDo = pDo;
+    ObReferenceObject(pCurDo); /* <- to make sure the dereferencing logic below works correctly */
+    do
+    {
+        LOG(("==Do 0x%p", pCurDo));
+#ifdef VBOX_USB_WITH_VERBOSE_LOGGING
+        {
+            union
+            {
+                OBJECT_NAME_INFORMATION Info;
+                char buf[1024];
+            } buf;
+            ULONG cbLength = 0;
+
+            NTSTATUS tmpStatus = ObQueryNameString(pCurDo, &buf.Info, sizeof (buf), &cbLength);
+            if (NT_SUCCESS(tmpStatus))
+            {
+                LOG(("  Obj name:"));
+                LOG_USTR(&buf.Info.Name);
+            }
+            else
+            {
+                if (STATUS_INFO_LENGTH_MISMATCH != tmpStatus)
+                {
+                    WARN(("ObQueryNameString failed 0x%x", tmpStatus));
+                }
+                else
+                {
+                    WARN(("ObQueryNameString STATUS_INFO_LENGTH_MISMATCH, required %d", cbLength));
+                }
+            }
+
+            if (pCurDo->DriverObject
+                && pCurDo->DriverObject->DriverName.Buffer
+                && pCurDo->DriverObject->DriverName.Length)
+            {
+                LOG(("  Drv Obj(0x%p), name:", pCurDo->DriverObject));
+                LOG_USTR(&pCurDo->DriverObject->DriverName);
+            }
+            else
+            {
+                LOG(("  No Drv Name, Drv Obj(0x%p)", pCurDo->DriverObject));
+                if (pCurDo->DriverObject)
+                {
+                    LOG(("  driver name is zero, Length(%d), Buffer(0x%p)",
+                                pCurDo->DriverObject->DriverName.Length, pCurDo->DriverObject->DriverName.Buffer));
+                }
+                else
+                {
+                    LOG(("  driver object is NULL"));
+                }
+            }
+        }
+#endif
+        if (!pfnWalker(pDo, pCurDo, pvWalker))
+        {
+            LOG(("the walker said to stop"));
+            ObDereferenceObject(pCurDo);
+            break;
+        }
+
+        PDEVICE_OBJECT pLowerDo = IoGetLowerDeviceObject(pCurDo);
+        ObDereferenceObject(pCurDo);
+        if (!pLowerDo)
+        {
+            LOG(("IoGetLowerDeviceObject returnned NULL, stop"));
+            break;
+        }
+        pCurDo = pLowerDo;
+    } while (1);
+
+    LOG(("<==tree walk"));
+}
+
+static DECLCALLBACK(BOOLEAN) vboxUsbObjNamePrefixMatch(PUNICODE_STRING pName, PUNICODE_STRING pNamePrefix, BOOLEAN fCaseInSensitive)
+{
+    LOG(("Matching prefix:"));
+    LOG_USTR(pNamePrefix);
+    if (pNamePrefix->Length > pName->Length)
+    {
+        LOG(("Pregix Length(%d) > Name Length(%d)", pNamePrefix->Length, pName->Length));
+        return FALSE;
+    }
+
+    LOG(("Pregix Length(%d) <= Name Length(%d)", pNamePrefix->Length, pName->Length));
+
+    UNICODE_STRING NamePrefix = *pName;
+    NamePrefix.Length = pNamePrefix->Length;
+    LONG rc = RtlCompareUnicodeString(&NamePrefix, pNamePrefix, fCaseInSensitive);
+
+    if (!rc)
+    {
+        LOG(("prefix MATCHED!"));
+        return TRUE;
+    }
+
+    LOG(("prefix NOT matched!"));
+    return FALSE;
+}
+
+typedef struct VBOXUSBOBJNAMEPREFIXMATCHER
+{
+    PUNICODE_STRING pNamePrefix;
+    BOOLEAN fMatched;
+} VBOXUSBOBJNAMEPREFIXMATCHER, *PVBOXUSBOBJNAMEPREFIXMATCHER;
+
+static DECLCALLBACK(VOID) vboxUsbObjDevNamePrefixMatcher(PDEVICE_OBJECT pDo, PUNICODE_STRING pName, PVOID pvMatcher)
+{
+    PVBOXUSBOBJNAMEPREFIXMATCHER pData = (PVBOXUSBOBJNAMEPREFIXMATCHER)pvMatcher;
+    PUNICODE_STRING pNamePrefix = pData->pNamePrefix;
+    ASSERT_WARN(!pData->fMatched, ("match flag already set!"));
+    pData->fMatched = vboxUsbObjNamePrefixMatch(pName, pNamePrefix, TRUE /* fCaseInSensitive */);
+    LOG(("match result (%d)", (int)pData->fMatched));
+}
+
+typedef struct VBOXUSBOBJDRVOBJSEARCHER
+{
+    PDEVICE_OBJECT pDevObj;
+    PUNICODE_STRING pDrvName;
+    PUNICODE_STRING pPdoNamePrefix;
+    ULONG fFlags;
+} VBOXUSBOBJDRVOBJSEARCHER, *PVBOXUSBOBJDRVOBJSEARCHER;
+
+static DECLCALLBACK(BOOLEAN) vboxUsbObjDevObjSearcherWalker(PDEVICE_OBJECT pTopDo, PDEVICE_OBJECT pCurDo, PVOID pvContext)
+{
+    PVBOXUSBOBJDRVOBJSEARCHER pData = (PVBOXUSBOBJDRVOBJSEARCHER)pvContext;
+    ASSERT_WARN(!pData->pDevObj, ("non-null dev object (0x%p) on enter", pData->pDevObj));
+    pData->pDevObj = NULL;
+    if (pCurDo->DriverObject
+        && pCurDo->DriverObject->DriverName.Buffer
+        && pCurDo->DriverObject->DriverName.Length
+        && !RtlCompareUnicodeString(pData->pDrvName, &pCurDo->DriverObject->DriverName, TRUE /* case insensitive */))
+    {
+        LOG(("MATCHED driver:"));
+        LOG_USTR(&pCurDo->DriverObject->DriverName);
+        if ((pData->fFlags & VBOXUSBMONHUBWALK_F_ALL) != VBOXUSBMONHUBWALK_F_ALL)
+        {
+            VBOXUSBOBJNAMEPREFIXMATCHER Data = {0};
+            Data.pNamePrefix = pData->pPdoNamePrefix;
+            NTSTATUS Status = vboxUsbObjCheckName(pCurDo, vboxUsbObjDevNamePrefixMatcher, &Data);
+            if (!NT_SUCCESS(Status))
+            {
+                WARN(("vboxUsbObjCheckName failed Status (0x%x)", Status));
+                return TRUE;
+            }
+
+
+            LOG(("prefix match result (%d)", Data.fMatched));
+            if ((pData->fFlags & VBOXUSBMONHUBWALK_F_FDO) == VBOXUSBMONHUBWALK_F_FDO)
+            {
+                LOG(("VBOXUSBMONHUBWALK_F_FDO"));
+                if (Data.fMatched)
+                {
+                    LOG(("this is a PDO object, skip it and stop search"));
+                    /* stop search as we will not find FDO here */
+                    return FALSE;
+                }
+
+                LOG(("this is a FDO object, MATCHED!!"));
+            }
+            else if ((pData->fFlags & VBOXUSBMONHUBWALK_F_PDO) == VBOXUSBMONHUBWALK_F_PDO)
+            {
+                LOG(("VBOXUSBMONHUBWALK_F_PDO"));
+                if (!Data.fMatched)
+                {
+                    LOG(("this is a FDO object, skip it and continue search"));
+                    /* continue seach since since this could be a nested hub that would have a usbhub-originated PDO */
+                    return TRUE;
+                }
+
+                LOG(("this is a PDO object, MATCHED!!"));
+            }
+
+        }
+        else
+        {
+            LOG(("VBOXUSBMONHUBWALK_F_ALL"));
+            LOG(("either PDO or FDO, MATCHED!!"));
+        }
+
+        /* ensure the dev object is not destroyed */
+        ObReferenceObject(pCurDo);
+        pData->pDevObj = pCurDo;
+        /* we are done */
+        return FALSE;
+    }
+    else
+    {
+        LOG(("driver object (0x%p) no match", pCurDo->DriverObject));
+        if (pCurDo->DriverObject)
+        {
+            if (   pCurDo->DriverObject->DriverName.Buffer
+                && pCurDo->DriverObject->DriverName.Length)
+            {
+                LOG(("driver name not match, was:"));
+                LOG_USTR(&pCurDo->DriverObject->DriverName);
+                LOG(("but expected:"));
+                LOG_USTR(pData->pDrvName);
+            }
+            else
+            {
+                LOG(("driver name is zero, Length(%d), Buffer(0x%p)",
+                        pCurDo->DriverObject->DriverName.Length, pCurDo->DriverObject->DriverName.Buffer));
+            }
+        }
+        else
+        {
+            LOG(("driver object is NULL"));
+        }
+    }
+    return TRUE;
+}
+
+VOID vboxUsbMonHubDevWalk(PFNVBOXUSBMONDEVWALKER pfnWalker, PVOID pvWalker, ULONG fFlags)
 {
     NTSTATUS Status = STATUS_UNSUCCESSFUL;
@@ -218,10 +516,14 @@
     szStandardHubName.Buffer = 0;
     RtlInitUnicodeString(&szStandardHubName, L"\\Driver\\usbhub");
-
-    LOG(("Search USB hub\n"));
+    UNICODE_STRING szStandardHubPdoNamePrefix;
+    szStandardHubPdoNamePrefix.Length = 0;
+    szStandardHubPdoNamePrefix.MaximumLength = 0;
+    szStandardHubPdoNamePrefix.Buffer = 0;
+    RtlInitUnicodeString(&szStandardHubPdoNamePrefix, L"\\Device\\USBPDO-");
+
     for (int i = 0; i < 16; i++)
     {
-        WCHAR           szwHubName[32] = {};
-        char            szHubName[32] = {};
+        WCHAR           szwHubName[32] = {0};
+        char            szHubName[32] = {0};
         ANSI_STRING     AnsiName;
         UNICODE_STRING  UnicodeName;
@@ -244,52 +546,37 @@
             if (Status == STATUS_SUCCESS)
             {
-                LOG(("IoGetDeviceObjectPointer for %S returned %p %p\n", szwHubName, pHubDevObj, pHubFileObj));
-
-                if (pHubDevObj->DriverObject
-                    && pHubDevObj->DriverObject->DriverName.Buffer
-                    && pHubDevObj->DriverObject->DriverName.Length
-                    && !RtlCompareUnicodeString(&szStandardHubName, &pHubDevObj->DriverObject->DriverName, TRUE /* case insensitive */))
+                LOG(("IoGetDeviceObjectPointer for %S returned %p %p", szwHubName, pHubDevObj, pHubFileObj));
+
+                VBOXUSBOBJDRVOBJSEARCHER Data = {0};
+                Data.pDrvName = &szStandardHubName;
+                Data.pPdoNamePrefix = &szStandardHubPdoNamePrefix;
+                Data.fFlags = fFlags;
+
+                vboxUsbObjDevStackWalk(pHubDevObj, vboxUsbObjDevObjSearcherWalker, &Data);
+                if (Data.pDevObj)
                 {
-                    LOG(("Associated driver"));
-                    LOG_USTR(&pHubDevObj->DriverObject->DriverName);
-                    LOG(("pnp handler %p\n", pHubDevObj->DriverObject->MajorFunction[IRP_MJ_PNP]));
-
-                    pDrvObj = pHubDevObj->DriverObject;
-                    /* ensure the driver object is not destroyed */
-                    ObReferenceObject(pDrvObj);
-                    /* release the file object which will releade the dev objectas well,
-                     * as we do not need those anymore */
-                    ObDereferenceObject(pHubFileObj);
-                    break;
+                    LOG(("found hub dev obj (0x%p)", Data.pDevObj));
+                    if (!pfnWalker(pHubFileObj, pHubDevObj, Data.pDevObj, pvWalker))
+                    {
+                        LOG(("the walker said to stop"));
+                        ObDereferenceObject(Data.pDevObj);
+                        break;
+                    }
+
+                    LOG(("going forward.."));
+                    ObDereferenceObject(Data.pDevObj);
                 }
                 else
                 {
-                    LOG(("driver object (0x%p) no match", pHubDevObj->DriverObject));
-                    if (pHubDevObj->DriverObject)
-                    {
-                        if (   pHubDevObj->DriverObject->DriverName.Buffer
-                            && pHubDevObj->DriverObject->DriverName.Length)
-                        {
-                            LOG(("driver name not match, was:"));
-                            LOG_USTR(&pHubDevObj->DriverObject->DriverName);
-                            LOG(("but expected:"));
-                            LOG_USTR(&szStandardHubName);
-                        }
-                        else
-                        {
-                            LOG(("driver name is zero, Length(%d), Buffer(0x%p)",
-                                    pHubDevObj->DriverObject->DriverName.Length, pHubDevObj->DriverObject->DriverName.Buffer));
-                        }
-                    }
-                    else
-                    {
-                        LOG(("driver object is NULL"));
-                    }
+                    LOG(("no hub driver obj found"));
+                    ASSERT_WARN(!Data.pDevObj, ("non-null dev obj poiter returned (0x%p)", Data.pDevObj));
                 }
+
+                /* this will dereference both file and dev obj */
                 ObDereferenceObject(pHubFileObj);
             }
             else
             {
-                WARN(("IoGetDeviceObjectPointer returned Status (0x%x) for (%S)", Status, szwHubName));
+                LOG(("IoGetDeviceObjectPointer returned Status (0x%x) for (%S)", Status, szwHubName));
             }
         }
@@ -299,6 +586,51 @@
         }
     }
-
-    return pDrvObj;
+}
+
+typedef struct VBOXUSBMONFINDHUBWALKER
+{
+    PDRIVER_OBJECT pDrvObj;
+} VBOXUSBMONFINDHUBWALKER, *PVBOXUSBMONFINDHUBWALKER;
+
+static DECLCALLBACK(BOOLEAN) vboxUsbMonFindHubDrvObjWalker(PFILE_OBJECT pFile, PDEVICE_OBJECT pTopDo, PDEVICE_OBJECT pHubDo, PVOID pvContext)
+{
+    PVBOXUSBMONFINDHUBWALKER pData = (PVBOXUSBMONFINDHUBWALKER)pvContext;
+    PDRIVER_OBJECT pDrvObj = pHubDo->DriverObject;
+
+    ASSERT_WARN(!pData->pDrvObj, ("pDrvObj expected null on enter, but was(0x%p)", pData->pDrvObj));
+    if(pDrvObj)
+    {
+        LOG(("found driver object 0x%p", pDrvObj));
+        ObReferenceObject(pDrvObj);
+        pData->pDrvObj = pDrvObj;
+        return FALSE;
+    }
+
+    WARN(("null pDrvObj!"));
+    return TRUE;
+}
+
+static PDRIVER_OBJECT vboxUsbMonHookFindHubDrvObj()
+{
+    NTSTATUS Status = STATUS_UNSUCCESSFUL;
+    UNICODE_STRING szStandardHubName;
+    PDRIVER_OBJECT pDrvObj = NULL;
+    szStandardHubName.Length = 0;
+    szStandardHubName.MaximumLength = 0;
+    szStandardHubName.Buffer = 0;
+    RtlInitUnicodeString(&szStandardHubName, L"\\Driver\\usbhub");
+
+    LOG(("Search USB hub"));
+    VBOXUSBMONFINDHUBWALKER Data = {0};
+    vboxUsbMonHubDevWalk(vboxUsbMonFindHubDrvObjWalker, &Data, VBOXUSBMONHUBWALK_F_ALL);
+    if (Data.pDrvObj)
+    {
+        LOG(("returning driver object 0x%p", Data.pDrvObj));
+    }
+    else
+    {
+        WARN(("no hub driver object found!"));
+    }
+    return Data.pDrvObj;
 }
 
@@ -308,10 +640,10 @@
 static NTSTATUS vboxUsbMonHandlePnPIoctl(PDEVICE_OBJECT pDevObj, PIO_STACK_LOCATION pSl, PIO_STATUS_BLOCK pIoStatus)
 {
-    LOG(("IRQL = %d\n", KeGetCurrentIrql()));
+    LOG(("IRQL = %d", KeGetCurrentIrql()));
     switch(pSl->MinorFunction)
     {
         case IRP_MN_QUERY_DEVICE_TEXT:
         {
-            LOG(("IRP_MN_QUERY_DEVICE_TEXT: pIoStatus->Status = %x\n", pIoStatus->Status));
+            LOG(("IRP_MN_QUERY_DEVICE_TEXT: pIoStatus->Status = %x", pIoStatus->Status));
             if (pIoStatus->Status == STATUS_SUCCESS)
             {
@@ -358,5 +690,5 @@
                 }
                 else
-                    LOG(("Invalid pointer %p\n", pId));
+                    LOG(("Invalid pointer %p", pId));
             }
             break;
@@ -365,5 +697,5 @@
         case IRP_MN_QUERY_ID:
         {
-            LOG(("IRP_MN_QUERY_ID: Irp->pIoStatus->Status = %x\n", pIoStatus->Status));
+            LOG(("IRP_MN_QUERY_ID: Irp->pIoStatus->Status = %x", pIoStatus->Status));
             if (pIoStatus->Status == STATUS_SUCCESS &&  pDevObj)
             {
@@ -511,5 +843,5 @@
                 else
                 {
-                    LOG(("Invalid pointer %p\n", pId));
+                    LOG(("Invalid pointer %p", pId));
                 }
             }
@@ -524,10 +856,10 @@
             case BusRelations:
             {
-                LOG(("BusRelations\n"));
+                LOG(("BusRelations"));
 
                 if (pIoStatus->Status == STATUS_SUCCESS)
                 {
                     PDEVICE_RELATIONS pRel = (PDEVICE_RELATIONS)pIoStatus->Information;
-                    LOG(("pRel = %p\n", pRel));
+                    LOG(("pRel = %p", pRel));
                     if (VALID_PTR(pRel))
                     {
@@ -535,20 +867,20 @@
                         {
                             if (VBoxUsbFltPdoIsFiltered(pDevObj))
-                                LOG(("New PDO %p\n", pRel->Objects[i]));
+                                LOG(("New PDO %p", pRel->Objects[i]));
                         }
                     }
                     else
-                        LOG(("Invalid pointer %p\n", pRel));
+                        LOG(("Invalid pointer %p", pRel));
                 }
                 break;
             }
             case TargetDeviceRelation:
-                LOG(("TargetDeviceRelation\n"));
+                LOG(("TargetDeviceRelation"));
                 break;
             case RemovalRelations:
-                LOG(("RemovalRelations\n"));
+                LOG(("RemovalRelations"));
                 break;
             case EjectionRelations:
-                LOG(("EjectionRelations\n"));
+                LOG(("EjectionRelations"));
                 break;
             }
@@ -558,5 +890,5 @@
         case IRP_MN_QUERY_CAPABILITIES:
         {
-            LOG(("IRP_MN_QUERY_CAPABILITIES: pIoStatus->Status = %x\n", pIoStatus->Status));
+            LOG(("IRP_MN_QUERY_CAPABILITIES: pIoStatus->Status = %x", pIoStatus->Status));
             if (pIoStatus->Status == STATUS_SUCCESS)
             {
@@ -564,11 +896,11 @@
                 if (VALID_PTR(pCaps))
                 {
-                    LOG(("Caps.SilentInstall  = %d\n", pCaps->SilentInstall));
-                    LOG(("Caps.UniqueID       = %d\n", pCaps->UniqueID ));
-                    LOG(("Caps.Address        = %d\n", pCaps->Address ));
-                    LOG(("Caps.UINumber       = %d\n", pCaps->UINumber ));
+                    LOG(("Caps.SilentInstall  = %d", pCaps->SilentInstall));
+                    LOG(("Caps.UniqueID       = %d", pCaps->UniqueID ));
+                    LOG(("Caps.Address        = %d", pCaps->Address ));
+                    LOG(("Caps.UINumber       = %d", pCaps->UINumber ));
                 }
                 else
-                    LOG(("Invalid pointer %p\n", pCaps));
+                    LOG(("Invalid pointer %p", pCaps));
             }
             break;
@@ -580,5 +912,5 @@
     } /*switch */
 
-    LOG(("Done returns %x (IRQL = %d)\n", pIoStatus->Status, KeGetCurrentIrql()));
+    LOG(("Done returns %x (IRQL = %d)", pIoStatus->Status, KeGetCurrentIrql()));
     return pIoStatus->Status;
 }
@@ -586,5 +918,5 @@
 NTSTATUS _stdcall VBoxUsbPnPCompletion(DEVICE_OBJECT *pDevObj, IRP *pIrp, void *pvContext)
 {
-    LOG(("Completion PDO(0x%p), IRP(0x%p), Status(0x%x)\n", pDevObj, pIrp, pIrp->IoStatus.Status));
+    LOG(("Completion PDO(0x%p), IRP(0x%p), Status(0x%x)", pDevObj, pIrp, pIrp->IoStatus.Status));
     ASSERT_WARN(pvContext, ("zero context"));
 
@@ -657,5 +989,5 @@
     }
 
-    LOG(("<==PnP: Mn(%s), PDO(0x%p), IRP(0x%p), Status(0x%x), Sl PDO(0x%p), Compl PDO(0x%p)\n",
+    LOG(("<==PnP: Mn(%s), PDO(0x%p), IRP(0x%p), Status(0x%x), Sl PDO(0x%p), Compl PDO(0x%p)",
                             vboxUsbDbgStrPnPMn(pSl->MinorFunction),
                             pRealDevObj, pIrp, pIrp->IoStatus.Status,
@@ -684,5 +1016,5 @@
 NTSTATUS _stdcall VBoxUsbMonPnPHook(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp)
 {
-    LOG(("==>PnP: Mn(%s), PDO(0x%p), IRP(0x%p), Status(0x%x)\n", vboxUsbDbgStrPnPMn(IoGetCurrentIrpStackLocation(pIrp)->MinorFunction), pDevObj, pIrp, pIrp->IoStatus.Status));
+    LOG(("==>PnP: Mn(%s), PDO(0x%p), IRP(0x%p), Status(0x%x)", vboxUsbDbgStrPnPMn(IoGetCurrentIrpStackLocation(pIrp)->MinorFunction), pDevObj, pIrp, pIrp->IoStatus.Status));
 
     if(!VBoxUsbHookRetain(&g_VBoxUsbMonGlobals.UsbHubPnPHook.Hook))
@@ -761,5 +1093,5 @@
     if (!NT_SUCCESS(Status))
     {
-        AssertMsgFailed(("usbhub pnp unhook failed, setting the fUninitFailed flag, the current value of fUninitFailed (%d)\n", g_VBoxUsbMonGlobals.UsbHubPnPHook.fUninitFailed));
+        AssertMsgFailed(("usbhub pnp unhook failed, setting the fUninitFailed flag, the current value of fUninitFailed (%d)", g_VBoxUsbMonGlobals.UsbHubPnPHook.fUninitFailed));
         g_VBoxUsbMonGlobals.UsbHubPnPHook.fUninitFailed = true;
     }
@@ -924,5 +1256,5 @@
         if (!InterlockedExchange(&g_VBoxUsbMonGlobals.ulPreventUnloadOn, 1))
         {
-            LOGREL(("ulPreventUnloadOn not set, preventing unload\n"));
+            LOGREL(("ulPreventUnloadOn not set, preventing unload"));
             UNICODE_STRING UniName;
             PDEVICE_OBJECT pTmpDevObj;
@@ -1034,8 +1366,8 @@
             PUSBSUP_VERSION pOut = (PUSBSUP_VERSION)pvBuffer;
 
-            LOG(("SUPUSBFLT_IOCTL_GET_VERSION\n"));
+            LOG(("SUPUSBFLT_IOCTL_GET_VERSION"));
             if (!pvBuffer || cbOutBuffer != sizeof(*pOut) || cbInBuffer != 0)
             {
-                WARN(("SUPUSBFLT_IOCTL_GET_VERSION: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.\n",
+                WARN(("SUPUSBFLT_IOCTL_GET_VERSION: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.",
                         cbInBuffer, 0, cbOutBuffer, sizeof (*pOut)));
                 Status = STATUS_INVALID_PARAMETER;
@@ -1057,5 +1389,5 @@
             if (RT_UNLIKELY(!pvBuffer || cbInBuffer != sizeof (*pFilter) || cbOutBuffer != sizeof (*pOut)))
             {
-                WARN(("SUPUSBFLT_IOCTL_ADD_FILTER: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.\n",
+                WARN(("SUPUSBFLT_IOCTL_ADD_FILTER: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.",
                         cbInBuffer, sizeof (*pFilter), cbOutBuffer, sizeof (*pOut)));
                 Status = STATUS_INVALID_PARAMETER;
@@ -1078,10 +1410,10 @@
             if (!pvBuffer || cbInBuffer != sizeof (*pIn) || (cbOutBuffer && cbOutBuffer != sizeof (*pRc)))
             {
-                WARN(("SUPUSBFLT_IOCTL_REMOVE_FILTER: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.\n",
+                WARN(("SUPUSBFLT_IOCTL_REMOVE_FILTER: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.",
                         cbInBuffer, sizeof (*pIn), cbOutBuffer, 0));
                 Status = STATUS_INVALID_PARAMETER;
                 break;
             }
-            LOG(("SUPUSBFLT_IOCTL_REMOVE_FILTER %x\n", *pIn));
+            LOG(("SUPUSBFLT_IOCTL_REMOVE_FILTER %x", *pIn));
             int rc = VBoxUsbMonFltRemove(pContext, *pIn);
             if (cbOutBuffer)
@@ -1100,10 +1432,10 @@
             if (pvBuffer || cbInBuffer || cbOutBuffer)
             {
-                WARN(("SUPUSBFLT_IOCTL_RUN_FILTERS: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.\n",
+                WARN(("SUPUSBFLT_IOCTL_RUN_FILTERS: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.",
                         cbInBuffer, 0, cbOutBuffer, 0));
                 Status = STATUS_INVALID_PARAMETER;
                 break;
             }
-            LOG(("SUPUSBFLT_IOCTL_RUN_FILTERS \n"));
+            LOG(("SUPUSBFLT_IOCTL_RUN_FILTERS "));
             Status = VBoxUsbMonRunFilters(pContext);
             ASSERT_WARN(Status != STATUS_PENDING, ("status pending!"));
@@ -1117,5 +1449,5 @@
             if (!pvBuffer || cbInBuffer != sizeof (hDevice) || cbOutBuffer < sizeof (*pOut))
             {
-                WARN(("SUPUSBFLT_IOCTL_GET_DEVICE: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected >= %d.\n",
+                WARN(("SUPUSBFLT_IOCTL_GET_DEVICE: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected >= %d.",
                         cbInBuffer, sizeof (hDevice), cbOutBuffer, sizeof (*pOut)));
                 Status = STATUS_INVALID_PARAMETER;
@@ -1141,5 +1473,5 @@
             if (!pvBuffer || cbInBuffer != sizeof (*pSne) || cbOutBuffer != sizeof (*pSne))
             {
-                WARN(("SUPUSBFLT_IOCTL_SET_NOTIFY_EVENT: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.\n",
+                WARN(("SUPUSBFLT_IOCTL_SET_NOTIFY_EVENT: Invalid input/output sizes. cbIn=%d expected %d. cbOut=%d expected %d.",
                         cbInBuffer, sizeof (*pSne), cbOutBuffer, sizeof (*pSne)));
                 Status = STATUS_INVALID_PARAMETER;
@@ -1208,8 +1540,8 @@
             PVBOXUSBIDC_VERSION pOut = (PVBOXUSBIDC_VERSION)pvBuffer;
 
-            LOG(("VBOXUSBIDC_INTERNAL_IOCTL_GET_VERSION\n"));
+            LOG(("VBOXUSBIDC_INTERNAL_IOCTL_GET_VERSION"));
             if (!pvBuffer)
             {
-                WARN(("VBOXUSBIDC_INTERNAL_IOCTL_GET_VERSION: Buffer is NULL\n"));
+                WARN(("VBOXUSBIDC_INTERNAL_IOCTL_GET_VERSION: Buffer is NULL"));
                 Status = STATUS_INVALID_PARAMETER;
                 break;
@@ -1225,8 +1557,8 @@
             PVBOXUSBIDC_PROXY_STARTUP pOut = (PVBOXUSBIDC_PROXY_STARTUP)pvBuffer;
 
-            LOG(("VBOXUSBIDC_INTERNAL_IOCTL_PROXY_STARTUP\n"));
+            LOG(("VBOXUSBIDC_INTERNAL_IOCTL_PROXY_STARTUP"));
             if (!pvBuffer)
             {
-                WARN(("VBOXUSBIDC_INTERNAL_IOCTL_PROXY_STARTUP: Buffer is NULL\n"));
+                WARN(("VBOXUSBIDC_INTERNAL_IOCTL_PROXY_STARTUP: Buffer is NULL"));
                 Status = STATUS_INVALID_PARAMETER;
                 break;
@@ -1243,8 +1575,8 @@
             PVBOXUSBIDC_PROXY_TEARDOWN pOut = (PVBOXUSBIDC_PROXY_TEARDOWN)pvBuffer;
 
-            LOG(("VBOXUSBIDC_INTERNAL_IOCTL_PROXY_TEARDOWN\n"));
+            LOG(("VBOXUSBIDC_INTERNAL_IOCTL_PROXY_TEARDOWN"));
             if (!pvBuffer)
             {
-                WARN(("VBOXUSBIDC_INTERNAL_IOCTL_PROXY_TEARDOWN: Buffer is NULL\n"));
+                WARN(("VBOXUSBIDC_INTERNAL_IOCTL_PROXY_TEARDOWN: Buffer is NULL"));
                 Status = STATUS_INVALID_PARAMETER;
                 break;
@@ -1296,5 +1628,5 @@
 static void _stdcall VBoxUsbMonUnload(PDRIVER_OBJECT pDrvObj)
 {
-    LOG(("VBoxUSBMonUnload pDrvObj (0x%p)\n", pDrvObj));
+    LOG(("VBoxUSBMonUnload pDrvObj (0x%p)", pDrvObj));
 
     IoReleaseRemoveLockAndWait(&g_VBoxUsbMonGlobals.RmLock, &g_VBoxUsbMonGlobals);
@@ -1369,5 +1701,5 @@
 
                 g_VBoxUsbMonGlobals.pDevObj = pDevObj;
-                LOG(("VBoxUSBMon::DriverEntry returning STATUS_SUCCESS\n"));
+                LOG(("VBoxUSBMon::DriverEntry returning STATUS_SUCCESS"));
                 return STATUS_SUCCESS;
             }
Index: trunk/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbMon.h
===================================================================
--- trunk/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbMon.h	(revision 38436)
+++ trunk/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbMon.h	(revision 38488)
@@ -47,3 +47,15 @@
 void vboxUsbDbgPrintUnicodeString(PUNICODE_STRING pUnicodeString);
 
+/* visit usbhub-originated device PDOs */
+#define VBOXUSBMONHUBWALK_F_PDO 0x00000001
+/* visit usbhub device FDOs */
+#define VBOXUSBMONHUBWALK_F_FDO 0x00000002
+/* visit all usbhub-originated device objects */
+#define VBOXUSBMONHUBWALK_F_ALL (VBOXUSBMONHUBWALK_F_FDO | VBOXUSBMONHUBWALK_F_PDO)
+
+typedef DECLCALLBACK(BOOLEAN) FNVBOXUSBMONDEVWALKER(PFILE_OBJECT pFile, PDEVICE_OBJECT pTopDo, PDEVICE_OBJECT pHubDo, PVOID pvContext);
+typedef FNVBOXUSBMONDEVWALKER *PFNVBOXUSBMONDEVWALKER;
+
+VOID vboxUsbMonHubDevWalk(PFNVBOXUSBMONDEVWALKER pfnWalker, PVOID pvWalker, ULONG fFlags);
+
 #endif /* #ifndef ___VBoxUsbMon_h___ */
