Cocoa:按供应商ID检测USB设备

ska*_*ous 7 macos usb cocoa iokit foundation

我正在为Mac编写一个Foundation工具,并尝试检测Apple设备何时通过USB连接和断开连接.我在这篇文章中找到了一些帮助以及USBPrivateDataSample - 但它似乎只有在我同时提供供应商ID和产品ID时才有效.我想消除产品ID并找到Apple设备上的所有USB事件(供应商ID 1452).这里有什么帮助?

这是我的代码似乎没有检测到任何设备:

#include <CoreFoundation/CoreFoundation.h>

#include <IOKit/IOKitLib.h>
#include <IOKit/IOMessage.h>
#include <IOKit/IOCFPlugIn.h>
#include <IOKit/usb/IOUSBLib.h>

#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;
}
Run Code Online (Sandbox Code Playgroud)

值得注意的是:如果我将一个产品ID添加到matchingDict并插入这样的设备,它将发现该设备没有问题(不更改供应商ID).但我无法单独使用供应商ID找到它.

Rav*_*ash 4

要获取属于特定供应商的所有产品的列表,您可以在产品 ID 字段中使用通配符。示例匹配条件如下:

            long vid = 1452; //Apple vendor ID
        CFNumberRef refVendorId = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &vid);
        CFDictionarySetValue (matchingDict, CFSTR ("idVendor"), refVendorId);
        CFRelease(refVendorId);
        //all product by same vendor
        CFDictionarySetValue (matchingDict, CFSTR ("idProduct"), CFSTR("*"));
Run Code Online (Sandbox Code Playgroud)

  • +1,我还想注意Apple的[USB驱动程序匹配提示](http://developer.apple.com/library/mac/#qa/qa1076/_index.html)页面,其中包含如何匹配的描述匹配规则有效。这包括有关使用通配符和掩码的信息。 (3认同)