Changeset 81083 in vbox for trunk/src/VBox/HostDrivers/VBoxUSB
- Timestamp:
- Sep 30, 2019 3:35:52 PM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 133689
- Location:
- trunk/src/VBox/HostDrivers/VBoxUSB/win/mon
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbFlt.cpp
r81078 r81083 47 47 #include <devguid.h> 48 48 49 50 /* We should be including ntifs.h but that's not as easy as it sounds. */ 51 extern "C" { 52 NTKERNELAPI PDEVICE_OBJECT IoGetDeviceAttachmentBaseRef(__in PDEVICE_OBJECT DeviceObject); 53 } 49 54 50 55 /* … … 905 910 for (ULONG k = 0; k < pDevRelations->Count; ++k) 906 911 { 907 PDEVICE_OBJECT pDevObj = pDevRelations->Objects[k]; 912 PDEVICE_OBJECT pDevObj; 913 914 /* Grab the PDO+reference. We won't need the upper layer device object 915 * anymore, so dereference that right here, and drop the PDO ref later. 916 */ 917 pDevObj = IoGetDeviceAttachmentBaseRef(pDevRelations->Objects[k]); 918 LOG(("DevObj=%p, PDO=%p\n", pDevRelations->Objects[k], pDevObj)); 919 ObDereferenceObject(pDevRelations->Objects[k]); 920 pDevRelations->Objects[k] = pDevObj; 908 921 909 922 LOG(("Found existing USB PDO 0x%p", pDevObj)); … … 1299 1312 PVBOXUSBFLT_DEVICE pDevice; 1300 1313 1314 /* Find the real PDO+reference. Dereference when we're done with it. Note that 1315 * the input pPdo was not explicitly referenced so we're not dropping its ref. 1316 */ 1317 PDEVICE_OBJECT pDevObj = IoGetDeviceAttachmentBaseRef(pPdo); 1318 LOG(("DevObj=%p, real PDO=%p\n", pPdo, pDevObj)); 1319 pPdo = pDevObj; 1320 1301 1321 /* first check if device is in the a already */ 1302 1322 VBOXUSBFLT_LOCK_ACQUIRE(); … … 1309 1329 *pbFiltered = pDevice->enmState >= VBOXUSBFLT_DEVSTATE_CAPTURING; 1310 1330 VBOXUSBFLT_LOCK_RELEASE(); 1331 ObDereferenceObject(pPdo); 1311 1332 return STATUS_SUCCESS; 1312 1333 } … … 1316 1337 { 1317 1338 WARN(("VBoxUsbMonMemAllocZ failed")); 1339 ObDereferenceObject(pPdo); 1318 1340 return STATUS_NO_MEMORY; 1319 1341 } … … 1325 1347 { 1326 1348 WARN(("vboxUsbFltDevPopulate failed, Status 0x%x", Status)); 1349 ObDereferenceObject(pPdo); 1327 1350 VBoxUsbMonMemFree(pDevice); 1328 1351 return Status; … … 1337 1360 /* (paranoia) re-check the device is still not here */ 1338 1361 pTmpDev = vboxUsbFltDevGetLocked(pPdo); 1362 1363 /* Drop the PDO ref, now we won't need it anymore. */ 1364 ObDereferenceObject(pPdo); 1365 1339 1366 if (pTmpDev) 1340 1367 { … … 1385 1412 { 1386 1413 VBOXUSBFLT_DEVSTATE enmState = VBOXUSBFLT_DEVSTATE_REMOVED; 1414 1415 /* Find the real PDO+reference. Dereference when we're done with it. Note that 1416 * the input pPdo was not explicitly referenced so we're not dropping its ref. 1417 */ 1418 PDEVICE_OBJECT pDevObj = IoGetDeviceAttachmentBaseRef(pPdo); 1419 LOG(("DevObj=%p, real PDO=%p\n", pPdo, pDevObj)); 1420 pPdo = pDevObj; 1421 1387 1422 VBOXUSBFLT_LOCK_ACQUIRE(); 1388 1423 … … 1392 1427 1393 1428 VBOXUSBFLT_LOCK_RELEASE(); 1429 ObDereferenceObject(pPdo); 1394 1430 1395 1431 return enmState >= VBOXUSBFLT_DEVSTATE_CAPTURING; … … 1400 1436 PVBOXUSBFLT_DEVICE pDevice; 1401 1437 VBOXUSBFLT_DEVSTATE enmOldState; 1438 1439 /* Find the real PDO+reference. Dereference when we're done with it. Note that 1440 * the input pPdo was not explicitly referenced so we're not dropping its ref. 1441 */ 1442 PDEVICE_OBJECT pDevObj = IoGetDeviceAttachmentBaseRef(pPdo); 1443 LOG(("DevObj=%p, real PDO=%p\n", pPdo, pDevObj)); 1444 pPdo = pDevObj; 1402 1445 1403 1446 VBOXUSBFLT_LOCK_ACQUIRE(); … … 1410 1453 } 1411 1454 VBOXUSBFLT_LOCK_RELEASE(); 1455 ObDereferenceObject(pPdo); 1412 1456 if (pDevice) 1413 1457 vboxUsbFltDevRelease(pDevice); … … 1419 1463 PVBOXUSBFLT_DEVICE pDevice; 1420 1464 VBOXUSBFLT_LOCK_ACQUIRE(); 1465 1466 /* NB: The USB proxy (VBoxUSB.sys) passes us the real PDO, not anything above that. */ 1421 1467 pDevice = vboxUsbFltDevGetLocked(pPdo); 1422 1468 /* -
trunk/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbMon.cpp
r81070 r81083 23 23 * You may elect to license modified versions of this file under the 24 24 * terms and conditions of either the GPL or the CDDL or both. 25 */ 26 27 28 /* 29 * 30 * Theory of Operation 31 * - or - 32 * The Document I Wish The Original Author Had Written 33 * 34 * 35 * The USB Monitor (VBoxUSBMon.sys) serves to capture and uncapture USB 36 * devices. Its job is to ensure that the USB proxy (VBoxUSB.sys) gets installed 37 * for captured devices and removed again when not needed, restoring the regular 38 * driver (if any). 39 * 40 * The USB Monitor does not handle any actual USB traffic; that is the role of 41 * VBoxUSB.sys, the USB proxy. A typical solution for installing such USB proxy 42 * is using a filter driver, but that approach was rejected because filter drivers 43 * cannot be dynamically added and removed. What VBoxUSBMon does instead is hook 44 * into the dispatch routine of the bus driver, i.e. USB hub driver, and alter 45 * the PnP information returned by the bus driver. 46 * 47 * The key functionality for capturing is cycling a USB port (which causes a USB 48 * device reset and triggers re-enumeration in the Windows USB driver stack), and 49 * then modifying IRP_MN_QUERY_ID / BusQueryHardwareIDs and related requests so 50 * that they return the synthetic USB VID/PID that VBoxUSB.sys handles rather than 51 * the true hardware VID/PID. That causes Windows to install VBoxUSB.sys for the 52 * device. 53 * 54 * Uncapturing again cycles the USB port but returns unmodified hardware IDs, 55 * causing Windows to load the normal driver for the device. 56 * 57 * Identifying devices to capture or release (uncapture) is done through USB filters, 58 * a cross-platform concept which matches USB device based on their VID/PID, class, 59 * and other criteria. 60 * 61 * There is an IOCTL interface for adding/removing USB filters and applying them. 62 * The IOCTLs are normally issued by VBoxSVC. 63 * 64 * USB devices are enumerated by finding all USB hubs (GUID_DEVINTERFACE_USB_HUB) 65 * and querying their child devices (i.e. USB devices or other hubs) by sending 66 * IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations. This is done when 67 * applying existing filters. 68 * 69 * Newly arrived USB devices are intercepted early in their PnP enumeration 70 * through the hooked bus driver dispatch routine. Devices which satisty the 71 * filter matching criteria are morphed (see above) such that VBoxUSB.sys loads 72 * for them before any default driver does. 73 * 74 * There is an IDC interface to VBoxUSB.sys which allows the USB proxy to report 75 * that it's installed for a given USB device, and also report when the USB proxy 76 * is unloaded (typically caused by either unplugging the device or uncapturing 77 * and cycling the port). VBoxUSBMon.sys relies on these IDC calls to track 78 * captured devices and be informed when VBoxUSB.sys unloads. 79 * 80 * Windows 8+ complicates the USB Monitor's life by automatically putting some 81 * USB devices to a low-power state where they are unable to respond to any USB 82 * requests and VBoxUSBMon can't read any of their descriptors (note that in 83 * userland, the device descriptor can always be read, but string descriptors 84 * can't). Such devices' USB VID/PID/revision is recovered using the Windows 85 * PnP Manager from their DevicePropertyHardwareID, but their USB class/subclass 86 * and protocol unfortunately cannot be unambiguously recovered from their 87 * DevicePropertyCompatibleIDs. 88 * 89 * Filter drivers add another complication. With filter drivers in place, the 90 * device objects returned by the BusRelations query (or passing through the PnP 91 * hooks) may not be PDOs but rather filter DOs higher in the stack. To avoid 92 * confusion, we flatten the references to their base, i.e. the real PDO, which 93 * should remain the same for the lifetime of a device. Note that VBoxUSB.sys 94 * always passes its own PDO in the proxy startup IOCTL. 25 95 */ 26 96
Note:
See TracChangeset
for help on using the changeset viewer.