基于MyUsbDevice类的一个例子

首先新建一个线程,这个线程负责监控设备的插入拔出

线程入口函数:

 1 int DeviceThreadEntryForMac(ClassProcMan *pProcMan)
 2 {
 3     if(pProcMan == NULL) {
 4         fprintf(stderr, "DeviceThreadEntryForMac called NULL pointer\n");
 5         return __LINE__;
 6     }
 7     mach_port_t                masterPort;
 8     CFMutableDictionaryRef    matchingDict;
 9     kern_return_t            kr;
10     SInt32                    usbVendor = kOurVendorID;
11     SInt32                    usbProduct = kOurProductID;
12     CFRunLoopSourceRef        runLoopSource;
13     
14     printf("DeviceThreadEntryForMac called\n");
15 
16     sig_t oldHandler = signal(SIGTERM, CleanUp);
17     if(oldHandler == SIG_ERR)
18         printf("Create new signal handler failed\n");
19 
20     kr = IOMasterPort(MACH_PORT_NULL,  &masterPort);
21     if (kr != kIOReturnSuccess || !masterPort) {
22         fprintf(stderr, "Couldn't create a master I/O Kit port (%08x)\n", kr);
23         return __LINE__;
24     }
25 
26     matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
27     if (!matchingDict) {
28         fprintf(stderr, "Couldn't cerate a USB matching dictionary\n");
29         mach_port_deallocate(mach_task_self(), masterPort);
30         return __LINE__;
31     }
32 
33     CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorName),
34             CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbVendor));
35     CFDictionarySetValue(matchingDict, CFSTR(kUSBProductName),
36             CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbProduct));
37 
38     gNotifyPort = IONotificationPortCreate(masterPort);
39     runLoopSource = IONotificationPortGetRunLoopSource(gNotifyPort);
40     CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource,
41             kCFRunLoopDefaultMode);
42 
43     matchingDict = (CFMutableDictionaryRef) CFRetain(matchingDict);
44 
45     kr = IOServiceAddMatchingNotification(gNotifyPort,
46             kIOFirstMatchNotification, matchingDict,
47             DeviceAttach, (void *)pProcMan, &gAttachIter);
48     DeviceAttach((void *)pProcMan, gAttachIter);
49 
50     kr = IOServiceAddMatchingNotification(gNotifyPort,
51             kIOTerminatedNotification, matchingDict,
52             DeviceDetach, (void *)pProcMan, &gDetachIter);
53     DeviceDetach((void *)pProcMan, gDetachIter);
54 
55     mach_port_deallocate(mach_task_self(), masterPort);
56     masterPort = 0;
57 
58     CFRunLoopRun();
59 
60     return 0;
61 }

设备进入或者拔出,由类ClassProcMan的实例来处理。

 1 void DeviceAttach(void *refcon, io_iterator_t iterator)
 2 {
 3     kern_return_t            kr;
 4     io_service_t            usbDevice;
 5     IOCFPlugInInterface        **plugInInterface = NULL;
 6     IOUSBDeviceInterface    **dev = NULL;
 7     HRESULT                    result;
 8     SInt32                    score;
 9     UInt16                    vendor;
10     UInt16                    product;
11     ClassProcMan *pProcMan = (ClassProcMan *)refcon;
12 
13     while ((usbDevice = IOIteratorNext(iterator))) {
14 
15         kr = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID,
16                 kIOCFPlugInInterfaceID, &plugInInterface, &score);
17         kr = IOObjectRelease(usbDevice);
18         if (kr != kIOReturnSuccess || !plugInInterface) {
19 
20             fprintf(stderr, "Unable to create a plug-in (%08x)\n", kr);
21             continue;
22         }
23 
24         result = (*plugInInterface)->QueryInterface(plugInInterface,
25                 CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID *)&dev);
26         (*plugInInterface)->Release(plugInInterface);
27         if (result || !dev) {
28             fprintf(stderr, "Unable to create a device interface (%08x)\n", (int)result);
29             continue;
30         }
31 
32         kr = (*dev)->GetDeviceVendor(dev, &vendor);
33         kr = (*dev)->GetDeviceProduct(dev, &product);
34         if(vendor == kOurVendorID && product == kOurProductID) {  //找到了我们指定的设备
35             char szRet[32] = {0};
36             UInt32 locationID;
37             (*dev)->GetLocationID(dev, (UInt32 *)&locationID);
38             sprintf(szRet, "%08x", locationID);
39             pProcMan->GetDeviceMessage().DevicePlugIn(szRet, TRUE);  //处理设备插入
40         }
41     }
42 }
43 
44 void DeviceDetach(void *refcon, io_iterator_t iterator)
45 {
46     kern_return_t   kr;
47     io_service_t    object;
48     ClassProcMan        *pProc = (ClassProcMan *)refcon;
49 
50     while ((object = IOIteratorNext(iterator))) {
51 
52         kr = IOObjectRelease(object);
53         if (kr != kIOReturnSuccess) {
54 
55             fprintf(stderr, "Couldn't release raw device object: %08x\n", kr);
56             continue;
57         }
58     }
59 //    pProcMan->m_DeviceMessage.DevicePlugOut(szRet, TRUE);
60 }
61 
62 static void CleanUp(int sigraised)
63 {
64     printf("\nClean up\n");
65     
66     // Clean up here
67     IONotificationPortDestroy(gNotifyPort);
68     if(gAttachIter) {
69         IOObjectRelease(gAttachIter);
70         gAttachIter = 0;
71     }
72     if(gDetachIter) {
73         IOObjectRelease(gDetachIter);
74         gDetachIter = 0;
75     }
76 }
原文地址:https://www.cnblogs.com/jojodru/p/2715075.html