VirtualBox

Changeset 79392 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jun 27, 2019 12:44:14 PM (6 years ago)
Author:
vboxsync
Message:

VBoxUsbMon: Implemented fallback method of obtaining USB vendor/product ID (see bugref:9479).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/VBoxUSB/win/mon/VBoxUsbFlt.cpp

    r79334 r79392  
    399399}
    400400
     401static uint16_t vboxUsbParseHexNumU16(WCHAR **ppStr)
     402{
     403    WCHAR       *pStr = *ppStr;
     404    WCHAR       wc;
     405    uint16_t    num = 0;
     406    unsigned    u;
     407
     408    for (int i = 0; i < 4; ++i)
     409    {
     410        if (!*pStr)     /* Just in case the string is too short. */
     411            break;
     412
     413        wc = *pStr;
     414        u = wc >= 'A' ? wc - 'A' + 10 : wc - '0';   /* Hex digit to number. */
     415        num |= u << (12 - 4 * i);
     416        pStr++;
     417    }
     418    *ppStr = pStr;
     419
     420    return num;
     421}
     422
     423static bool vboxUsbParseHardwareID(WCHAR *pchIdStr, uint16_t *pVid, uint16_t *pPid, uint16_t *pRev)
     424{
     425#define VID_PREFIX  L"USB\\VID_"
     426#define PID_PREFIX  L"&PID_"
     427#define REV_PREFIX  L"&REV_"
     428
     429    *pVid = *pPid = *pRev = 0xFFFF;
     430
     431    /* The Hardware ID is in the format USB\VID_xxxx&PID_xxxx&REV_xxxx, with 'xxxx'
     432     * being 16-bit hexadecimal numbers. The string is coming from the
     433     * Windows PnP manager so OEMs should have no opportunity to mess it up.
     434     */
     435
     436    if (wcsncmp(pchIdStr, VID_PREFIX, wcslen(VID_PREFIX)))
     437        return false;
     438    /* Point to the start of the vendor ID number and parse it. */
     439    pchIdStr += wcslen(VID_PREFIX);
     440    *pVid = vboxUsbParseHexNumU16(&pchIdStr);
     441
     442    if (wcsncmp(pchIdStr, PID_PREFIX, wcslen(PID_PREFIX)))
     443        return false;
     444    /* Point to the start of the product ID number and parse it. */
     445    pchIdStr += wcslen(PID_PREFIX);
     446    *pPid = vboxUsbParseHexNumU16(&pchIdStr);
     447
     448    /* The revision might not be there; the Windows documentation is not
     449     * entirely clear if it will be always present for USB devices or not.
     450     * If it's not there, still consider this a success. */
     451    if (wcsncmp(pchIdStr, REV_PREFIX, wcslen(REV_PREFIX)))
     452        return true;
     453
     454    /* Point to the start of the revision number and parse it. */
     455    pchIdStr += wcslen(REV_PREFIX);
     456    *pRev = vboxUsbParseHexNumU16(&pchIdStr);
     457
     458    return true;
     459#undef VID_PREFIX
     460#undef PID_PREFIX
     461#undef REV_PREFIX
     462}
     463
    401464#define VBOXUSBMON_POPULATE_REQUEST_TIMEOUT_MS 10000
    402465
     
    422485        if (!NT_SUCCESS(Status))
    423486        {
    424             WARN(("getting device descriptor failed, Status (0x%x)", Status));
    425             break;
     487            WCHAR       wchPropBuf[256];
     488            ULONG       ulResultLen;
     489            bool        rc;
     490            uint16_t    vid, pid, rev;
     491
     492            WARN(("getting device descriptor failed, Status (0x%x); falling back to IoGetDeviceProperty", Status));
     493
     494            /* Try falling back to IoGetDeviceProperty. */
     495            Status = IoGetDeviceProperty(pDo, DevicePropertyHardwareID, sizeof(wchPropBuf), wchPropBuf, &ulResultLen);
     496            if (!NT_SUCCESS(Status))
     497            {
     498                /* This just isn't our day. We have no idea what the device is. */
     499                WARN(("IoGetDeviceProperty failed, Status (0x%x)", Status));
     500                break;
     501            }
     502            rc = vboxUsbParseHardwareID(wchPropBuf, &vid, &pid, &rev);
     503            if (!rc)
     504            {
     505                /* This *really* should not happen. */
     506                WARN(("Failed to parse Hardware ID", Status));
     507                break;
     508            }
     509
     510            LOG(("Parsed HardwareID: vid=%04X, pid=%04X, rev=%04X", vid, pid, rev));
     511            if (vid == 0xFFFF || pid == 0xFFFF)
     512                break;
     513
     514            LOG(("Successfully fell back to IoGetDeviceProperty result"));
     515            /* The vendor/product ID is what matters. */
     516            pDevDr->idVendor  = vid;
     517            pDevDr->idProduct = pid;
     518            pDevDr->bcdDevice = rev;
     519            /* The rest we don't really know. */
     520            pDevDr->bDeviceClass    = 0;
     521            pDevDr->bDeviceSubClass = 0;
     522            pDevDr->bDeviceProtocol = 0;
    426523        }
    427524
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