Cocoa: обнаружение USB-устройств по идентификатору поставщика

Я пишу инструмент Foundation для Mac и пытаюсь определить, когда устройства Apple подключаются и отключаются через USB. Я нашел некоторую помощь в этом постевместе с USBPrivateDataSample— но, похоже, он работает только в том случае, если я укажу как идентификатор поставщика, так и идентификатор продукта. Я хотел бы удалить идентификатор продукта и найти все события USB на устройствах Apple (идентификатор поставщика 1452). Любая помощь здесь?

Вот мой код, который, кажется, не обнаруживает никаких устройств:

#include 

#include 
#include 
#include 
#include 

#define kMyVendorID 1452

int list_devices(void);

int list_devices(void){
    CFMutableDictionaryRef matchingDict;
    io_iterator_t iter;
    kern_return_t kr;
    io_service_t device;
    CFNumberRef numberRef;
    long usbVendor = kMyVendorID;

    /* set up a matching dictionary for the class */
    matchingDict = IOServiceMatching(kIOUSBDeviceClassName);    // Interested in instances of class
    // IOUSBDevice and its subclasses
    if (matchingDict == NULL) {
        fprintf(stderr, "IOServiceMatching returned NULL.\n");
        return -1;
    }

    // We are interested in all USB devices (as opposed to USB interfaces).  The Common Class Specification
    // tells us that we need to specify the idVendor, idProduct, and bcdDevice fields, or, if we're not interested
    // in particular bcdDevices, just the idVendor and idProduct.  Note that if we were trying to match an 
    // IOUSBInterface, we would need to set more values in the matching dictionary (e.g. idVendor, idProduct, 
    // bInterfaceNumber and bConfigurationValue.

    // Create a CFNumber for the idVendor and set the value in the dictionary
    numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbVendor);
    CFDictionarySetValue(matchingDict, 
                         CFSTR(kUSBVendorID), 
                         numberRef);
    CFRelease(numberRef);
    numberRef = NULL;    


    /* Now we have a dictionary, get an iterator.*/
    kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iter);
    if (kr != KERN_SUCCESS)
        return -1;

    /* iterate */
    while ((device = IOIteratorNext(iter)))
    {
        io_name_t       deviceName;
        CFStringRef     deviceNameAsCFString;   

        /* do something with device, eg. check properties */
        /* ... */
        /* And free the reference taken before continuing to the next item */

        // Get the USB device's name.
        kr = IORegistryEntryGetName(device, deviceName);
        if (KERN_SUCCESS != kr) {
            deviceName[0] = '\0';
        }

        deviceNameAsCFString = CFStringCreateWithCString(kCFAllocatorDefault, deviceName, 
                                                         kCFStringEncodingASCII);

        // Dump our data to stderr just to see what it looks like.
        fprintf(stderr, "deviceName: ");
        CFShow(deviceNameAsCFString);

        IOObjectRelease(device);
    }

    /* Done, release the iterator */
    IOObjectRelease(iter);

    return 1;
}

int main(int argc, char* argv[])
{
    while(1){
        list_devices();
        sleep(1);
    }
    return 0;
}

Примечание: если я добавлю идентификатор продукта в MatchDict и подключу такое устройство, он найдет устройство без проблем (без изменения идентификатора поставщика). ). Но я не могу найти его только по идентификатору поставщика.

7
задан Community 23 May 2017 в 10:31
поделиться