Created
August 2, 2014 10:45
-
-
Save hiszpanski/0ebc53ab4989d904a04c to your computer and use it in GitHub Desktop.
Prints vendor and product ids of USB devices as they are added
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // main.c | |
| // usblog | |
| // | |
| #include <assert.h> | |
| #include <stdio.h> | |
| #import <IOKit/usb/IOUSBLib.h> | |
| // @brief (callback) Called when USB device is added | |
| static void usbDeviceEvent(void *refcon, io_iterator_t iterator) | |
| { | |
| io_service_t dev; | |
| kern_return_t kr; | |
| while (dev = IOIteratorNext(iterator), dev) { | |
| HRESULT res; | |
| SInt32 score; | |
| UInt16 pid, vid; | |
| IOCFPlugInInterface **plugInInterface = NULL; | |
| IOUSBDeviceInterface **deviceInterface = NULL; | |
| kr = IOCreatePlugInInterfaceForService(dev, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); | |
| assert(kr == kIOReturnSuccess); | |
| assert(plugInInterface); | |
| res = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID*) &deviceInterface); | |
| (*plugInInterface)->Release(plugInInterface); | |
| assert(!res); | |
| assert(deviceInterface); | |
| kr = (*deviceInterface)->GetDeviceVendor(deviceInterface, &vid); | |
| assert(kr == kIOReturnSuccess); | |
| kr = (*deviceInterface)->GetDeviceProduct(deviceInterface, &pid); | |
| assert(kr == kIOReturnSuccess); | |
| fprintf(stderr, "%s: vid = 0x%04x pid = 0x%04x\n", (const char *)refcon, vid, pid); | |
| kr = IOObjectRelease(dev); | |
| assert(kr == kIOReturnSuccess); | |
| } | |
| } | |
| // @brief Main loop | |
| int main(int argc, const char * argv[]) | |
| { | |
| io_iterator_t deviceAddedIterator; | |
| // io_iterator_t deviceRemovedIterator; | |
| io_service_t device; | |
| kern_return_t kr; | |
| // Create port for receiving I/O Kit notifications | |
| IONotificationPortRef notifyPort = IONotificationPortCreate(kIOMasterPortDefault); | |
| assert(notifyPort); | |
| // Get runloop source for port | |
| CFRunLoopSourceRef runLoopSource = IONotificationPortGetRunLoopSource(notifyPort); | |
| // Add source to current runloop | |
| CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode); | |
| // Matching dictionary for any USB device | |
| CFDictionaryRef matching = IOServiceMatching(kIOUSBDeviceClassName); | |
| // Matching dictionary used twice, once for addition and once for removal, so increase reference count | |
| matching = (CFDictionaryRef)CFRetain(matching); | |
| // Add matching notifications | |
| kr = IOServiceAddMatchingNotification(notifyPort, kIOFirstMatchNotification, matching, usbDeviceEvent, "added", &deviceAddedIterator); | |
| assert(kr == kIOReturnSuccess); | |
| // kr = IOServiceAddMatchingNotification(notifyPort, kIOTerminatedNotification, matching, usbDeviceEvent, "removed", &deviceRemovedIterator); | |
| // assert(kr == kIOReturnSuccess); | |
| // Arm notifications and handle existing devices | |
| do { | |
| usbDeviceEvent("added", deviceAddedIterator); | |
| } while ((device = IOIteratorNext(deviceAddedIterator))); | |
| // do { | |
| // usbDeviceEvent("removed", deviceRemovedIterator); | |
| // } while ((device = IOIteratorNext(deviceRemovedIterator))); | |
| // Run | |
| CFRunLoopRun(); | |
| return 0; | |
| } | |
Author
Thanks! Hereby licensing under LGPL. Use it as you wish.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Beautiful job and exactly what I needed. I am working on an open source serial driver with extra features for interfacing to Vintage Atari 8-bit Computers via SIO2PC. Sadly the VID/PIDs are all over the place.
Does this code have a license?
Thanks!