- 一.获得 I/O Kit 主端口
- 1>建立一个信号句柄,让我们从命令行中断时候可以清理,否则,这个runloop永远循环运行。
- sig_t oldHandler;
- oldHandler = signal(SIGINT, SignalHandler);
- if (oldHandler == SIG_ERR)
- printf("Could not establish new signal handler");
- 创建一个端口
- mach_port_t myMasterPort;
- kern_return_t result;
- result = IOMasterPort(MACH_PORT_NULL, &myMasterPort);
- //也可以
- /*
- IOServiceGetMatchingServices(myMasterPort, myMatchingDictionary,
- &myIterator);
- IOServiceGetMatchingServices(kIOMasterPortDefault, myMatchingDictionary,
- &myIterator);
- */
- 创建一个USB 设备dictionary 使用usbclass
- CFMutableDictionaryRef matchingDict;
- // Set up the matching criteria for the devices we're interested in
- atchingDict = IOServiceMatching(kIOUSBDeviceClassName);
- if (!matchingDict)
- {
- mach_port_deallocate(mach_task_self(), masterPort);
- return -1;
- }
- 2>.设置设备的字典(dictionary)对象和寻找设备(find devices)在字典里面添加我们设备的信息如productID,vendorID和bcdDevice(key and value)等.我们能够指定我们的设备信息。如:
- // Add our vendor and product IDs to the matching criteria
- CFDictionarySetValue(
- matchingDict,
- CFSTR(kUSBVendorID),
- CFNumberCreate(kCFAllocatorDefaul,kCFNumberSInt32Type, &usbVendor));
- CFDictionarySetValue(
- matchingDict,
- CFSTR(kUSBProductID),
- CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt32Type,&usbProduct));
- //还有很多key这些都是usbDevice 标准的属性
- 在IOKitKeys.h 文件中还有很多。可以参考
- // Keys for matching IOService properties by name
- #define kIOProviderClassKey "IOProviderClass"
- #define kIONameMatchKey "IONameMatch"
- #define kIOPropertyMatchKey "IOPropertyMatch"
- #define kIOPathMatchKey "IOPathMatch"
- #define kIOLocationMatchKey "IOLocationMatch"
- #define kIOResourceMatchKey "IOResourceMatch"
- 也可以通过 I/O Registry Explorer 查看设备的信息。
- 通过调用函数创建包含设备类名的属性字典(dictionary)
- CFMutableDictionaryRef myUSBMatchDictionary=NULL;
- myUSBMatchDictionary= IOServiceMatching(kIOUSBDeviceClassName);
- 通过函数创建一个包含设备名字的属性字典
- CFMutableDictionaryRef myCompanyDeviceMatchDictionary = NULL;
- myCompanyDeviceMatchDictionary = IOServiceNameMatching("MyCompany");
- 通过函数创建一个包含设备文件名的属于字典
- CFMutableDictionaryRef myBSDMatchDictionary=NULL;
- myBSDMatchDictionary = IOBSDNameMatching(kIOMasterPortDefault, 0, "disk1s8");
- 第三个参数不能是路径.
- 字典在不使用之后要释放。 CFRelease(matchDic);
- 对生成的字典你可以修改,删除,修改,增加key and value;构建你想要的设备属性字典
- 二.当设备到达和离去的时候
- 使用 IONotificationPortCreate 函数创建notification 对象能监听 I/O Kit notifications的通知消息.
- IONotificationPortRef notificationObject;
- mach_port_t masterPort;
- notificationObject = IONotificationPortCreate(masterPort);
- 创建run-loop
- CFRunLoopSourceRef notificationRunLoopSource;
- //Use the notification object received from IONotificationPortCreate
- notificationRunLoopSource=IONotificationPortGetRunLoopSource(notificationObject);
- //增加run-loop
- CFRunLoopAddSource(CFRunLoopGetCurrent(),notificationRunLoopSource,kCFRunLoopDefaultMode);
- io_iterator_t gAddedIter //获得设备指针列表-关键
- // Now set up a notification to be called when a device is first matched by I/O Kit.
- kern_return_t kr = IOServiceAddMatchingNotification(
- gNotifyPort, // notifyPort
- kIOFirstMatchNotification, // notificationType
- matchingDict, // matching
- DeviceAdded, // callback 函数
- NULL, // refCon
- &gAddedIter // notification
- );