VirtualBox

Ignore:
Timestamp:
Aug 27, 2019 11:21:34 AM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
132929
Message:

VBoxUSBMon: Also obtain USB device class, subclass, and protocol through IoGetDeviceProperty if descriptors can't be read. Follow-up to bugref:9479

File:
1 edited

Legend:

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

    r80436 r80441  
    392392}
    393393
     394static uint8_t vboxUsbParseHexNumU8(WCHAR **ppStr)
     395{
     396    WCHAR       *pStr = *ppStr;
     397    WCHAR       wc;
     398    uint16_t    num = 0;
     399    unsigned    u;
     400
     401    for (int i = 0; i < 2; ++i)
     402    {
     403        if (!*pStr)     /* Just in case the string is too short. */
     404            break;
     405
     406        wc = *pStr;
     407        u = wc >= 'A' ? wc - 'A' + 10 : wc - '0';   /* Hex digit to number. */
     408        num |= u << (4 - 4 * i);
     409        pStr++;
     410    }
     411    *ppStr = pStr;
     412
     413    return num;
     414}
     415
    394416static bool vboxUsbParseHardwareID(WCHAR *pchIdStr, uint16_t *pVid, uint16_t *pPid, uint16_t *pRev)
    395417{
     
    433455}
    434456
     457static bool vboxUsbParseCompatibleIDs(WCHAR *pchIdStr, uint8_t *pClass, uint8_t *pSubClass, uint8_t *pProt)
     458{
     459#define CLS_PREFIX  L"USB\\Class_"
     460#define SUB_PREFIX  L"&SubClass_"
     461#define PRO_PREFIX  L"&Prot_"
     462
     463    *pClass = *pSubClass = *pProt = 0xFF;
     464
     465    /* The Compatible IDs string is in the format USB\Class_xx&SubClass_xx&Prot_xx,
     466     * with 'xx' being 8-bit hexadecimal numbers. Since this string is provided by the
     467     * PnP manager and USB devices always report these as part of the basic USB device
     468     * descriptor, we assume all three must be present.
     469     */
     470
     471    if (wcsncmp(pchIdStr, CLS_PREFIX, wcslen(CLS_PREFIX)))
     472        return false;
     473    /* Point to the start of the device class and parse it. */
     474    pchIdStr += wcslen(CLS_PREFIX);
     475    *pClass = vboxUsbParseHexNumU8(&pchIdStr);
     476
     477    if (wcsncmp(pchIdStr, SUB_PREFIX, wcslen(SUB_PREFIX)))
     478        return false;
     479
     480    /* Point to the start of the subclass and parse it. */
     481    pchIdStr += wcslen(SUB_PREFIX);
     482    *pSubClass = vboxUsbParseHexNumU8(&pchIdStr);
     483
     484    if (wcsncmp(pchIdStr, PRO_PREFIX, wcslen(PRO_PREFIX)))
     485        return false;
     486
     487    /* Point to the start of the protocol and parse it. */
     488    pchIdStr += wcslen(PRO_PREFIX);
     489    *pProt = vboxUsbParseHexNumU8(&pchIdStr);
     490
     491    return true;
     492#undef CLS_PREFIX
     493#undef SUB_PREFIX
     494#undef PRO_PREFIX
     495}
     496
    435497#define VBOXUSBMON_POPULATE_REQUEST_TIMEOUT_MS 10000
    436498
     
    460522            bool        rc;
    461523            uint16_t    vid, pid, rev;
     524            uint8_t     cls, sub, prt;
    462525
    463526            WARN(("getting device descriptor failed, Status (0x%x); falling back to IoGetDeviceProperty", Status));
     
    468531            {
    469532                /* This just isn't our day. We have no idea what the device is. */
    470                 WARN(("IoGetDeviceProperty failed, Status (0x%x)", Status));
     533                WARN(("IoGetDeviceProperty failed for DevicePropertyHardwareID, Status (0x%x)", Status));
    471534                break;
    472535            }
     
    479542            }
    480543
    481             LOG(("Parsed HardwareID: vid=%04X, pid=%04X, rev=%04X", vid, pid, rev));
     544            /* Now grab the Compatible IDs to get the class/subclass/protocol. */
     545            Status = IoGetDeviceProperty(pDo, DevicePropertyCompatibleIDs, sizeof(wchPropBuf), wchPropBuf, &ulResultLen);
     546            if (!NT_SUCCESS(Status))
     547            {
     548                /* We really kind of need these. */
     549                WARN(("IoGetDeviceProperty failed for DevicePropertyCompatibleIDs, Status (0x%x)", Status));
     550                break;
     551            }
     552            rc = vboxUsbParseCompatibleIDs(wchPropBuf, &cls, &sub, &prt);
     553            if (!rc)
     554            {
     555                /* This *really* should not happen. */
     556                WARN(("Failed to parse Hardware ID"));
     557                break;
     558            }
     559
     560            LOG(("Parsed HardwareID: vid=%04X, pid=%04X, rev=%04X, class=%02X, subcls=%02X, prot=%02X", vid, pid, rev, cls, sub, prt));
    482561            if (vid == 0xFFFF || pid == 0xFFFF)
    483562                break;
    484563
    485564            LOG(("Successfully fell back to IoGetDeviceProperty result"));
    486             /* The vendor/product ID is what matters. */
    487565            pDevDr->idVendor  = vid;
    488566            pDevDr->idProduct = pid;
    489567            pDevDr->bcdDevice = rev;
    490             /* The rest we don't really know. */
    491             pDevDr->bDeviceClass    = 0;
    492             pDevDr->bDeviceSubClass = 0;
    493             pDevDr->bDeviceProtocol = 0;
     568            pDevDr->bDeviceClass    = cls;
     569            pDevDr->bDeviceSubClass = sub;
     570            pDevDr->bDeviceProtocol = prt;
    494571        }
    495572
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