// main.m
// pnp
//
// Created by Sharath Menon on 22/09/22.
//
#import <Foundation/Foundation.h>
#import <IOUSBHost/IOUSBHost.h>
#include <IOKit/IOTypes.h>
#include <dispatch/dispatch.h>
#include <IOKit/usb/IOUSBLib.h>
#ifdef __OBJC__
@class IOUSBHostDevice;
typedef IOUSBHostDevice * USBHostDevPtr;
#else
typedef void * USBHostDevPtr;
#endif
USBHostDevPtr mUSBDevice;
dispatch_queue_t mQueue;
//boost::function<void()> mCallback;
int captureDevice(io_service_t aService)
{
NSError* error = nil;
IOUSBHostInterestHandler handler = ^void(IOUSBHostObject* hostObject, uint32_t messageType, void* _Nullable messageArgument) {
if( messageType == kIOMessageServiceIsTerminated )
{
// The callback will eventually take care of cleaning up the object
// mCallback();
NSLog(@"if PNP device removed");
}
NSLog(@"PNP device removed");
};
// Create the device with IOUSBHostObjectInitOptionsDeviceCapture to get exclusive access to the device
IOUSBHostDevice* device = [[IOUSBHostDevice alloc] initWithIOService:aService
options:IOUSBHostObjectInitOptionsDeviceCapture
queue:mQueue
error:&error
interestHandler:handler];
if(device == NULL)
{
return -1;
}
mUSBDevice = device;
// configureDevice(aService);
return 0;
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
mQueue = dispatch_queue_create("DeviceQueue", DISPATCH_QUEUE_SERIAL);
NSLog(@"Hello, World!");
CFMutableDictionaryRef RefMatchingDict = IOServiceMatching( kIOUSBDeviceClassName );
io_iterator_t USBDevices;
IOServiceGetMatchingServices( kIOMasterPortDefault, RefMatchingDict, &USBDevices );
// IOServiceGetMatchingServices( kIOMainPortDefault, RefMatchingDict, &USBDevices );
io_object_t USBDevice;
while ( ( USBDevice = IOIteratorNext( USBDevices ) ) )
{
io_string_t strDevPath;
IORegistryEntryGetPath( USBDevice, kIOServicePlane, strDevPath );
captureDevice(USBDevice);
IOObjectRelease( USBDevice );
}
IOObjectRelease( USBDevices );
// USBDevices = NULL;
}
return 0;
}
Hey all, I have been seeing a weird issues while using IOUSBHost framework. Whenever i run the given sample code on M1 machine it works perfectly fine; but the same on an Intel machine is giving the below error.
The weirdest part is when i run this on catalina with xcode 11.6 (Intel machine) it works again.
My process is running as root and not sandboxed so i would not be requiring any entitlements as mentioned in the doc for using IOUSBHostObjectInitOptionsDeviceCapture. Thoughts???
* @enum IOUSBHostObjectInitOptions
* @brief Options for <code>initWithIOService:options:queue:error:interestHandler</code>
* @constant IOUSBHostObjectInitOptionsDeviceCapture Callers must have the "com.apple.vm.device-access" entitlement
* and the IOUSBHostDevice IOService object needs to have successfully been authorized by IOServiceAuthorize().
* If the caller has root privelages the entitlement and authorization is not needed. Using this option
* will terminate all clients and drivers of the IOUSBHostDevice and associated IOUSBHostInterface clients
* besides the caller.
* Upon <code>destroy</code> of the IOUSBHostDevice, the device will be reset and drivers will be re-registered
* for matching. This option is only valid for macOS
*/
typedef NS_OPTIONS (NSUInteger, IOUSBHostObjectInitOptions)
{
IOUSBHostObjectInitOptionsNone = 0,
IOUSBHostObjectInitOptionsDeviceCapture = (1 << 0)
};