Skip to content

Instantly share code, notes, and snippets.

@PhilCS
Created November 5, 2021 17:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PhilCS/bec23749b046435894b9e7d49057932a to your computer and use it in GitHub Desktop.
Save PhilCS/bec23749b046435894b9e7d49057932a to your computer and use it in GitHub Desktop.
- (BOOL) registerForUSBNotificationsVendorId:(long) vendorId productId:(long)productId
{
CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
if ( !matchingDict )
return YES;
if ( vendorId != 0)
((__bridge NSMutableDictionary*)matchingDict)[@"idVendor"] = @(vendorId);
else
((__bridge NSMutableDictionary*)matchingDict)[@"idVendor"] = @"*";
if ( productId != 0)
((__bridge NSMutableDictionary*)matchingDict)[@"idProduct"] = @(productId);
else
((__bridge NSMutableDictionary*)matchingDict)[@"idProduct"] = @"*";
mach_port_t masterPort;
if ( IOMasterPort( MACH_PORT_NULL, &masterPort ) || !masterPort ) {
CFRelease(matchingDict);
return YES;
}
// To set up asynchronous notifications, create a notification port and
// add its run loop event source to the program’s run loop
IONotificationPortRef notifyPort = IONotificationPortCreate(masterPort);
CFRunLoopSourceRef runLoopSource = IONotificationPortGetRunLoopSource(notifyPort);
CFRunLoopRef gRunLoop = CFRunLoopGetCurrent();
CFRunLoopAddSource(gRunLoop, runLoopSource, kCFRunLoopDefaultMode);
// Retain additional dictionary references because each call to
// IOServiceAddMatchingNotification consumes one reference
CFRetain(matchingDict);
CFRetain(matchingDict);
CFRetain(matchingDict);
// Now set up two notifications: one to be called when a raw device
// is first matched by the I/O Kit and another to be called when the
// device is terminated
// Notification of first match:
kern_return_t kr;
io_iterator_t addedIter;
kr = IOServiceAddMatchingNotification( notifyPort,
kIOFirstMatchNotification,
matchingDict,
USBDeviceInserted,
NULL,
&addedIter );
USBDeviceInserted( NULL, addedIter );
if ( kr ) {
// Error in IOServiceAddMatchingNotification
mach_port_deallocate( mach_task_self(), masterPort );
return YES;
}
// Notification of termination:
io_iterator_t removedIter;
kr = IOServiceAddMatchingNotification( notifyPort,
kIOTerminatedNotification,
matchingDict,
USBDeviceRemoved,
NULL,
&removedIter );
USBDeviceRemoved( NULL, removedIter );
if ( kr ) {
// Error in IOServiceAddMatchingNotification
mach_port_deallocate( mach_task_self(), masterPort );
return YES;
}
mach_port_deallocate( mach_task_self(), masterPort );
return NO;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment