VirtualBox

Ignore:
Timestamp:
Nov 5, 2019 9:14:57 AM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
134424
Message:

USB/win: More work on USB enumeration.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/VBoxUSB/win/lib/VBoxUsbLib-win.cpp

    r81547 r81664  
    499499}
    500500
     501static uint16_t usbLibParseHexNumU16(LPCSTR *ppStr)
     502{
     503    const char  *pStr = *ppStr;
     504    char        c;
     505    uint16_t    num = 0;
     506    unsigned    u;
     507
     508    for (int i = 0; i < 4; ++i)
     509    {
     510        if (!*pStr)     /* Just in case the string is too short. */
     511            break;
     512
     513        c = *pStr;
     514        u = c >= 'A' ? c - 'A' + 10 : c - '0';  /* Hex digit to number. */
     515        num |= u << (12 - 4 * i);
     516        pStr++;
     517    }
     518    *ppStr = pStr;
     519
     520    return num;
     521}
     522
     523static bool usbLibParseLocation(LPCSTR LocStr, uint16_t *pBus, uint16_t *pPort)
     524{
     525#define PORT_PREFIX "Port_#"
     526#define BUS_PREFIX  ".Hub_#"
     527
     528    *pBus = *pPort = 0xFFFF;
     529
     530    /* The Location Information is in the format Port_#xxxx.Hub_#xxxx, with 'xxxx'
     531     * being 16-bit hexadecimal numbers. It should be reliable on Windows Vista and
     532     * later. Note that while the port corresponds to the port number aka address,
     533     * the hub nomber has no discernible relationship to how Windows enumerates hubs.
     534     */
     535
     536    if (strncmp(LocStr, PORT_PREFIX, strlen(PORT_PREFIX)))
     537        return false;
     538
     539    /* Point to the start of the port number and parse it. */
     540    LocStr += strlen(PORT_PREFIX);
     541    *pPort = usbLibParseHexNumU16(&LocStr);
     542
     543    if (strncmp(LocStr, BUS_PREFIX, strlen(BUS_PREFIX)))
     544        return false;
     545
     546    /* Point to the start of the hub/bus number and parse it. */
     547    LocStr += strlen(BUS_PREFIX);
     548    *pBus = usbLibParseHexNumU16(&LocStr);
     549
     550    return true;
     551#undef PORT_PREFIX
     552#undef BUS_PREFIX
     553}
     554
    501555static int usbLibDevPopulate(PUSBDEVICE pDev, PUSB_NODE_CONNECTION_INFORMATION_EX pConInfo, ULONG iPort, LPCSTR lpszLocation, LPCSTR lpszDrvKeyName, LPCSTR lpszHubName, PVBOXUSB_STRING_DR_ENTRY pDrList)
    502556{
     557    uint16_t    uPort;
     558    uint16_t    uBus;
     559
    503560    pDev->bcdUSB = pConInfo->DeviceDescriptor.bcdUSB;
    504561    pDev->bDeviceClass = pConInfo->DeviceDescriptor.bDeviceClass;
     
    508565    pDev->idProduct = pConInfo->DeviceDescriptor.idProduct;
    509566    pDev->bcdDevice = pConInfo->DeviceDescriptor.bcdDevice;
    510     pDev->bBus = 0; /** @todo figure out bBus on windows... */
    511     pDev->bPort = iPort;
     567
     568    /* Parse the bus (hub) and port out of the location. */
     569    if (usbLibParseLocation(lpszLocation, &uBus, &uPort))
     570    {
     571        Assert(uPort == iPort);
     572        pDev->bBus  = uBus;
     573        pDev->bPort = uPort;
     574    }
     575    else
     576    {
     577        /* Shouldn't happen but fall back to semi-sane values. */
     578        pDev->bBus  = 0;
     579        pDev->bPort = iPort;
     580    }
     581
    512582    /** @todo check which devices are used for primary input (keyboard & mouse) */
    513583    if (!lpszDrvKeyName || *lpszDrvKeyName == 0)
Note: See TracChangeset for help on using the changeset viewer.

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