VirtualBox

Changeset 82444 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Dec 6, 2019 7:28:14 AM (5 years ago)
Author:
vboxsync
Message:

USB/Win: Added logic to VBoxUSBMon to query USB device location, enabling more accurate matching (see bugref:9518).

Location:
trunk/src/VBox/HostDrivers/VBoxUSB/win
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/VBoxUSB/win/Makefile.kmk

    r81023 r82444  
    7575VBoxUSBMon_INCS       := $(PATH_SUB_CURRENT)/..
    7676VBoxUSBMon_SDKS        = ReorderCompilerIncs $(VBOX_WINDDK) $(VBOX_WINPSDK)INCS
    77 VBoxUSBMon_DEFS        = IN_RT_R0 IN_SUP_R0 i386=1 STD_CALL CONDITION_HANDLING=1 NT_INST=0 \
    78         WIN32=100 _NT1X_=100 WINNT=1 _WIN32_WINNT=0x0501 WINVER=0x0501 _WIN32_IE=0x0600 WIN32_LEAN_AND_MEAN=1 \
     77VBoxUSBMon_DEFS        = IN_RT_R0 IN_SUP_R0 NTDDI_WINNT=_NTDDI_VISTA \
    7978        VBOXUSBFILTERMGR_USB_SPINLOCK VBOX_DBG_LOG_NAME=\"USBMon\"
    8079VBoxUSBMon_LDFLAGS.x86 = -Entry:DriverEntry@8
  • trunk/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbFlt.cpp

    r81083 r82444  
    4646#include <VBox/usblib.h>
    4747#include <devguid.h>
     48#include <devpkey.h>
    4849
    4950
     
    113114    uint8_t         bSubClass;
    114115    uint8_t         bProtocol;
     116    uint8_t         bPort;
    115117    char            szSerial[MAX_USB_SERIAL_STRING];
    116118    char            szMfgName[MAX_USB_SERIAL_STRING];
    117119    char            szProduct[MAX_USB_SERIAL_STRING];
     120    WCHAR           szLocationPath[768];
    118121#if 0
    119122    char            szDrvKeyName[512];
     
    375378    }
    376379
     380    /* If the port number looks valid, add it to the filter. */
     381    if (pDevice->bPort != 0xffff)
     382    {
     383        USBFilterSetNumExact(&DevFlt, USBFILTERIDX_PORT, pDevice->bPort, true);
     384    }
     385
    377386    /* Run filters on the thing. */
    378387    PVBOXUSBFLTCTX pOwner = VBoxUSBFilterMatchEx(&DevFlt, puId, fRemoveFltIfOneShot, pfFilter, pfIsOneShot);
     
    522531}
    523532
     533static bool vboxUsbParseLocation(WCHAR *pchLocStr, uint16_t *pHub, uint16_t *pPort)
     534{
     535#define PORT_PREFIX L"Port_#"
     536#define BUS_PREFIX  L".Hub_#"
     537
     538    *pHub = *pPort = 0xFFFF;
     539
     540    /* The Location Information is in the format Port_#xxxx.Hub_#xxxx, with 'xxxx'
     541     * being 16-bit hexadecimal numbers. It should be reliable on Windows Vista and
     542     * later. Note that while the port corresponds to the port number aka address,
     543     * the hub number has no discernible relationship to how Windows enumerates hubs.
     544     */
     545
     546    if (wcsncmp(pchLocStr, PORT_PREFIX, wcslen(PORT_PREFIX)))
     547        return false;
     548
     549    /* Point to the start of the port number and parse it. */
     550    pchLocStr += wcslen(PORT_PREFIX);
     551    *pPort = vboxUsbParseHexNumU16(&pchLocStr);
     552
     553    if (wcsncmp(pchLocStr, BUS_PREFIX, wcslen(BUS_PREFIX)))
     554        return false;
     555
     556    /* Point to the start of the hub/bus number and parse it. */
     557    pchLocStr += wcslen(BUS_PREFIX);
     558    *pHub = vboxUsbParseHexNumU16(&pchLocStr);
     559
     560    return true;
     561#undef PORT_PREFIX
     562#undef BUS_PREFIX
     563}
     564
    524565#define VBOXUSBMON_POPULATE_REQUEST_TIMEOUT_MS 10000
    525566
    526567static NTSTATUS vboxUsbFltDevPopulate(PVBOXUSBFLT_DEVICE pDevice, PDEVICE_OBJECT pDo /*, BOOLEAN bPopulateNonFilterProps*/)
    527568{
    528     NTSTATUS Status;
    529     PUSB_DEVICE_DESCRIPTOR pDevDr = 0;
     569    NTSTATUS                Status;
     570    PUSB_DEVICE_DESCRIPTOR  pDevDr = 0;
     571    ULONG                   ulResultLen;
     572    DEVPROPTYPE             type;
     573    WCHAR                   wchPropBuf[256];
     574    uint16_t                port, hub;
     575    bool                    rc;
    530576
    531577    pDevice->Pdo = pDo;
     
    546592        if (!NT_SUCCESS(Status))
    547593        {
    548             WCHAR       wchPropBuf[256];
    549             ULONG       ulResultLen;
    550             bool        rc;
    551594            uint16_t    vid, pid, rev;
    552595            uint8_t     cls, sub, prt;
     
    554597            WARN(("getting device descriptor failed, Status (0x%x); falling back to IoGetDeviceProperty", Status));
    555598
    556             /* Try falling back to IoGetDeviceProperty. */
    557             Status = IoGetDeviceProperty(pDo, DevicePropertyHardwareID, sizeof(wchPropBuf), wchPropBuf, &ulResultLen);
     599            /* Try falling back to IoGetDevicePropertyData. */
     600            Status = IoGetDevicePropertyData(pDo, &DEVPKEY_Device_HardwareIds, LOCALE_NEUTRAL, 0, sizeof(wchPropBuf), wchPropBuf, &ulResultLen, &type);
    558601            if (!NT_SUCCESS(Status))
    559602            {
    560603                /* This just isn't our day. We have no idea what the device is. */
    561                 WARN(("IoGetDeviceProperty failed for DevicePropertyHardwareID, Status (0x%x)", Status));
     604                WARN(("IoGetDevicePropertyData failed for DEVPKEY_Device_HardwareIds, Status (0x%x)", Status));
    562605                break;
    563606            }
     
    571614
    572615            /* Now grab the Compatible IDs to get the class/subclass/protocol. */
    573             Status = IoGetDeviceProperty(pDo, DevicePropertyCompatibleIDs, sizeof(wchPropBuf), wchPropBuf, &ulResultLen);
     616            Status = IoGetDevicePropertyData(pDo, &DEVPKEY_Device_CompatibleIds, LOCALE_NEUTRAL, 0, sizeof(wchPropBuf), wchPropBuf, &ulResultLen, &type);
    574617            if (!NT_SUCCESS(Status))
    575618            {
    576619                /* We really kind of need these. */
    577                 WARN(("IoGetDeviceProperty failed for DevicePropertyCompatibleIDs, Status (0x%x)", Status));
     620                WARN(("IoGetDevicePropertyData failed for DEVPKEY_Device_CompatibleIds, Status (0x%x)", Status));
    578621                break;
    579622            }
     
    604647        }
    605648
     649        /* Query the location path. The path is purely a function of the physical device location
     650         * and does not change if the device changes, and also does not change depending on
     651         * whether the device is captured or not.
     652         * NB: We ignore any additional strings and only look at the first one.
     653         */
     654        Status = IoGetDevicePropertyData(pDo, &DEVPKEY_Device_LocationPaths, LOCALE_NEUTRAL, 0, sizeof(pDevice->szLocationPath), pDevice->szLocationPath, &ulResultLen, &type);
     655        if (!NT_SUCCESS(Status))
     656        {
     657            /* We do need this, and it should always be available. */
     658            WARN(("IoGetDevicePropertyData failed for DEVPKEY_Device_LocationPaths, Status (0x%x)", Status));
     659            break;
     660        }
     661        LOG_STRW(pDevice->szLocationPath);
     662
     663        /* Query the location information. The hub number is iffy because the numbering is
     664         * non-obvious and not necessarily stable, but the port number is well defined and useful.
     665         */
     666        Status = IoGetDevicePropertyData(pDo, &DEVPKEY_Device_LocationInfo, LOCALE_NEUTRAL, 0, sizeof(wchPropBuf), wchPropBuf, &ulResultLen, &type);
     667        if (!NT_SUCCESS(Status))
     668        {
     669            /* We may well need this, and it should always be available. */
     670            WARN(("IoGetDevicePropertyData failed for DEVPKEY_Device_LocationInfo, Status (0x%x)", Status));
     671            break;
     672        }
     673        LOG_STRW(wchPropBuf);
     674        rc = vboxUsbParseLocation(wchPropBuf, &hub, &port);
     675        if (!rc)
     676        {
     677            /* This *really* should not happen but it's not fatal. */
     678            WARN(("Failed to parse Location Info"));
     679        }
     680
    606681        if (vboxUsbFltBlDevMatchLocked(pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice))
    607682        {
     
    612687
    613688        LOG(("Device pid=%x vid=%x rev=%x", pDevDr->idVendor, pDevDr->idProduct, pDevDr->bcdDevice));
     689        pDevice->bPort        = port;
    614690        pDevice->idVendor     = pDevDr->idVendor;
    615691        pDevice->idProduct    = pDevDr->idProduct;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette