IOUSBDeviceControllerLib.c [plain text]
#include <pthread.h>
#include <CoreFoundation/CFRuntime.h>
#include <IOKit/IOKitLib.h>
#include <sys/sysctl.h>
#include "IOUSBDeviceControllerLib.h"
#define CONFIG_FILE_PATH CFSTR("/System/Library/AppleUSBDevice/USBDeviceConfiguration.plist")
static void __IOUSBDeviceControllerRelease( CFTypeRef object );
static IOUSBDeviceControllerRef __deviceRefFromService(CFAllocatorRef allocator, io_service_t service);
static pthread_once_t __sessionTypeInit = PTHREAD_ONCE_INIT;
static CFTypeID __kIOUSBDeviceControllerTypeID = _kCFRuntimeNotATypeID;
static CFRunLoopRef _runLoop;
static CFStringRef _runLoopMode;
static IOUSBDeviceArrivalCallback _arrivalCallback;
static void* _arrivalContext;
static IONotificationPortRef _notifyPort;
static io_iterator_t _notifyIterator;
static CFTypeID __kIOUSBDeviceDescriptionTypeID = _kCFRuntimeNotATypeID;
static void __IOUSBDeviceDescriptionRelease( CFTypeRef object );
static CFStringRef __IOUSBDeviceDescriptionSerializeDebug(CFTypeRef cf);
static pthread_once_t __deviceDescriptionTypeInit = PTHREAD_ONCE_INIT;
#define DESTROY(thing) if(thing) CFRelease(thing)
static IOUSBDeviceDescriptionRef __IOUSBDeviceDescriptionCreateFromDictionary(CFAllocatorRef allocator, CFMutableDictionaryRef descDict);
static IOUSBDeviceDescriptionRef __IOUSBDeviceDescriptionCreateFromFile( CFAllocatorRef allocator, CFStringRef filePath );
typedef struct __IOUSBDeviceDescription
{
CFRuntimeBase cfBase;
CFMutableDictionaryRef info;
CFAllocatorRef allocator;
}__IOUSBDeviceDescription;
static const CFRuntimeClass __IOUSBDeviceDescriptionClass = {
0, "IOUSBDeviceDescription", NULL, NULL, __IOUSBDeviceDescriptionRelease, NULL, NULL, NULL, __IOUSBDeviceDescriptionSerializeDebug,
NULL,
NULL
};
typedef struct __IOUSBDeviceController
{
CFRuntimeBase cfBase; io_service_t deviceIOService;
} __IOUSBDeviceController, *__IOUSBDeviceControllerRef;
static const CFRuntimeClass __IOUSBDeviceControllerClass = {
0, "IOUSBDeviceController", NULL, NULL, __IOUSBDeviceControllerRelease, NULL, NULL, NULL, NULL,
NULL,
NULL
};
static void __controllerPublished(void *refcon __attribute__((unused)), io_iterator_t iterator)
{
io_service_t service;
IOUSBDeviceControllerRef device;
while((service = IOIteratorNext(iterator)))
{
device = __deviceRefFromService(kCFAllocatorDefault, service);
if(device)
{
_arrivalCallback(_arrivalContext, device);
CFRelease(device);
}
}
}
void __IOUSBDeviceControllerRegister(void)
{
__kIOUSBDeviceControllerTypeID = _CFRuntimeRegisterClass(&__IOUSBDeviceControllerClass);
}
CFTypeID IOUSBDeviceControllerGetTypeID(void)
{
if ( _kCFRuntimeNotATypeID == __kIOUSBDeviceControllerTypeID )
pthread_once(&__sessionTypeInit, __IOUSBDeviceControllerRegister);
return __kIOUSBDeviceControllerTypeID;
}
static IOUSBDeviceControllerRef __deviceRefFromService(CFAllocatorRef allocator, io_service_t service)
{
IOUSBDeviceControllerRef device = NULL;
void * offset = NULL;
uint32_t size;
size = sizeof(__IOUSBDeviceController) - sizeof(CFRuntimeBase);
device = (IOUSBDeviceControllerRef)_CFRuntimeCreateInstance(
allocator,
IOUSBDeviceControllerGetTypeID(),
size,
NULL);
if (!device)
return NULL;
offset = device;
bzero(offset + sizeof(CFRuntimeBase), size);
device->deviceIOService = service;
IOObjectRetain(service);
return device;
}
IOReturn IOUSBDeviceControllerCreate(
CFAllocatorRef allocator,
IOUSBDeviceControllerRef* deviceRefPtr
)
{
CFMutableDictionaryRef matchingDict;
io_service_t deviceIOService;
IOUSBDeviceControllerRef deviceRef;
matchingDict = IOServiceMatching("IOUSBDeviceController");
if (!matchingDict)
return kIOReturnNoMemory;
deviceIOService = IOServiceGetMatchingService(kIOMasterPortDefault, matchingDict);
if(!deviceIOService)
return kIOReturnNotFound;
deviceRef = __deviceRefFromService(allocator, deviceIOService);
IOObjectRelease(deviceIOService);
if(deviceRef == NULL)
return kIOReturnNoMemory;
*deviceRefPtr = deviceRef;
return kIOReturnSuccess;
}
IOReturn IOUSBDeviceControllerGoOffAndOnBus(IOUSBDeviceControllerRef device, uint32_t msecdelay)
{
IOReturn rval;
CFNumberRef delay = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &msecdelay);
if(!delay)
return kIOReturnNoMemory;
rval = IOUSBDeviceControllerSendCommand(device, CFSTR("GoOffAndOnBus"), delay);
CFRelease(delay);
return rval;
}
IOReturn IOUSBDeviceControllerForceOffBus(IOUSBDeviceControllerRef device, int enable)
{
if(enable)
return IOUSBDeviceControllerSendCommand(device, CFSTR("ForceOffBusEnable"), NULL);
else
return IOUSBDeviceControllerSendCommand(device, CFSTR("ForceOffBusDisable"), NULL);
}
void IOUSBDeviceControllerRemoveArrivalCallback()
{
if(!_notifyPort)
return;
IOObjectRelease(_notifyIterator);
CFRunLoopRemoveSource(_runLoop, IONotificationPortGetRunLoopSource(_notifyPort), _runLoopMode);
IONotificationPortDestroy(_notifyPort);
_notifyIterator = 0; _runLoop = NULL; _runLoopMode = NULL; _notifyPort = NULL;
}
IOReturn IOUSBDeviceControllerRegisterArrivalCallback(IOUSBDeviceArrivalCallback callback, void *context,CFRunLoopRef runLoop, CFStringRef runLoopMode)
{
IOReturn kr;
CFMutableDictionaryRef matchingDict;
_runLoop = runLoop;
_runLoopMode = runLoopMode;
if(_runLoop)
{
if(!_notifyPort)
_notifyPort = IONotificationPortCreate(kIOMasterPortDefault);
CFRunLoopAddSource(_runLoop, IONotificationPortGetRunLoopSource(_notifyPort), _runLoopMode);
}
if(!_notifyPort)
return kIOReturnError;
_arrivalCallback = callback;
_arrivalContext = context;
matchingDict = IOServiceMatching("IOUSBDeviceController");
if((kr = IOServiceAddMatchingNotification(_notifyPort, kIOPublishNotification, matchingDict, __controllerPublished, 0, &_notifyIterator)))
return kr;
__controllerPublished(NULL, _notifyIterator);
return kIOReturnSuccess;
}
static void __IOUSBDeviceControllerRelease( CFTypeRef object )
{
IOUSBDeviceControllerRef device = (IOUSBDeviceControllerRef)object;
if ( device->deviceIOService )
IOObjectRelease(device->deviceIOService);
device->deviceIOService = 0;
}
IOReturn IOUSBDeviceControllerSendCommand(IOUSBDeviceControllerRef device, CFStringRef command, CFTypeRef param)
{
CFMutableDictionaryRef dict;
IOReturn kr;
dict = CFDictionaryCreateMutable(NULL, 0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
if(!dict)
return kIOReturnNoMemory;
CFDictionarySetValue(dict, CFSTR("USBDeviceCommand"), command);
if(param)
CFDictionarySetValue(dict, CFSTR("USBDeviceCommandParameter"), param);
kr = IORegistryEntrySetCFProperties(device->deviceIOService, dict);
CFRelease(dict);
return kr;
}
IOReturn IOUSBDeviceControllerSetPreferredConfiguration(IOUSBDeviceControllerRef device, int config)
{
IOReturn kr = kIOReturnBadArgument;
CFNumberRef config_number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &config);
if ( config_number )
{
kr = IOUSBDeviceControllerSendCommand(device, CFSTR("SetDevicePreferredConfiguration"), config_number);
CFRelease(config_number);
}
return kr;
}
io_service_t IOUSBDeviceControllerGetService(IOUSBDeviceControllerRef controller)
{
return controller->deviceIOService;
}
IOReturn IOUSBDeviceControllerSetDescription(IOUSBDeviceControllerRef device, IOUSBDeviceDescriptionRef description)
{
return IOUSBDeviceControllerSendCommand(device, CFSTR("SetDeviceDescription"), description->info);
}
static void __IOUSBDeviceDescriptionRelease( CFTypeRef object )
{
IOUSBDeviceDescriptionRef desc = (IOUSBDeviceDescriptionRef)object;
DESTROY(desc->info);
}
static CFStringRef __IOUSBDeviceDescriptionSerializeDebug(CFTypeRef cf) {
IOUSBDeviceDescriptionRef desc = (IOUSBDeviceDescriptionRef)cf;
return CFStringCreateWithFormat(NULL, NULL, CFSTR("IOUSBDeviceDescription: pid/vid/ver=%04x/%04x/%d class/sub/prot=%d/%d/%d Mfg:%@ Prod:%@ Ser:%@\n%@"),
IOUSBDeviceDescriptionGetProductID(desc), IOUSBDeviceDescriptionGetVendorID(desc), IOUSBDeviceDescriptionGetVersion(desc),
IOUSBDeviceDescriptionGetClass(desc), IOUSBDeviceDescriptionGetSubClass(desc), IOUSBDeviceDescriptionGetProtocol(desc),
IOUSBDeviceDescriptionGetManufacturerString(desc), IOUSBDeviceDescriptionGetProductString(desc), IOUSBDeviceDescriptionGetSerialString(desc),
desc->info);
}
void __IOUSBDeviceDescriptionRegister(void)
{
__kIOUSBDeviceDescriptionTypeID = _CFRuntimeRegisterClass(&__IOUSBDeviceDescriptionClass);
}
CFTypeID IOUSBDevicDeviceDescriptionGetTypeID(void)
{
if ( _kCFRuntimeNotATypeID == __kIOUSBDeviceDescriptionTypeID )
pthread_once(&__deviceDescriptionTypeInit, __IOUSBDeviceDescriptionRegister);
return __kIOUSBDeviceDescriptionTypeID;
}
IOUSBDeviceDescriptionRef IOUSBDeviceDescriptionCreate(CFAllocatorRef allocator)
{
IOUSBDeviceDescriptionRef devdesc = NULL;
void * offset = NULL;
uint32_t size;
size = sizeof(__IOUSBDeviceDescription) - sizeof(CFRuntimeBase);
devdesc = (IOUSBDeviceDescriptionRef)_CFRuntimeCreateInstance(
allocator,
IOUSBDevicDeviceDescriptionGetTypeID(),
size,
NULL);
if (!devdesc)
return NULL;
offset = devdesc;
bzero(offset + sizeof(CFRuntimeBase), size);
devdesc->info = CFDictionaryCreateMutable(allocator, 8, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
devdesc->allocator = allocator;
CFMutableArrayRef configs = CFArrayCreateMutable(allocator, 4, &kCFTypeArrayCallBacks);
CFDictionarySetValue(devdesc->info, CFSTR("ConfigurationDescriptors"), configs);
CFRelease(configs);
return devdesc;
}
IOUSBDeviceDescriptionRef IOUSBDeviceDescriptionCreateFromController(CFAllocatorRef allocator, IOUSBDeviceControllerRef controllerRef)
{
CFMutableDictionaryRef descDict;
IOUSBDeviceDescriptionRef descRef = NULL;
if((descDict = (CFMutableDictionaryRef)IORegistryEntryCreateCFProperty(controllerRef->deviceIOService, CFSTR("DeviceDescription"), kCFAllocatorDefault, 0)))
{
descRef = __IOUSBDeviceDescriptionCreateFromDictionary(allocator, descDict);
CFRelease(descDict);
}
return descRef;
}
static IOUSBDeviceDescriptionRef __IOUSBDeviceDescriptionCreateFromDictionary(CFAllocatorRef allocator, CFMutableDictionaryRef descDict)
{
IOUSBDeviceDescriptionRef descRef = NULL;
if((descRef = IOUSBDeviceDescriptionCreate(allocator)))
{
if(descDict != descRef->info)
{
CFRelease(descRef->info);
descRef->info = (CFMutableDictionaryRef)CFRetain(descDict);
}
}
return descRef;
}
uint32_t __getDictNumber(IOUSBDeviceDescriptionRef ref, CFStringRef key)
{
CFNumberRef aNumber;
uint32_t val=0;
if((aNumber = CFDictionaryGetValue(ref->info, key )))
CFNumberGetValue(aNumber, kCFNumberSInt32Type, &val);
return val;
}
uint8_t IOUSBDeviceDescriptionGetClass(IOUSBDeviceDescriptionRef ref)
{
return __getDictNumber(ref, CFSTR("deviceClass"));
}
void IOUSBDeviceDescriptionSetClass(IOUSBDeviceDescriptionRef devDesc, UInt8 class)
{
CFNumberRef aNumber = CFNumberCreate(devDesc->allocator, kCFNumberCharType, &class);
CFDictionarySetValue(devDesc->info, CFSTR("deviceClass"), aNumber);
CFRelease(aNumber);
}
void IOUSBDeviceDescriptionSetSubClass(IOUSBDeviceDescriptionRef devDesc, UInt8 subclass)
{
CFNumberRef aNumber = CFNumberCreate(devDesc->allocator, kCFNumberCharType, &subclass);
CFDictionarySetValue(devDesc->info, CFSTR("deviceSubClass"), aNumber);
CFRelease(aNumber);
}
uint8_t IOUSBDeviceDescriptionGetSubClass(IOUSBDeviceDescriptionRef ref)
{
return __getDictNumber(ref, CFSTR("deviceSubClass"));
}
void IOUSBDeviceDescriptionSetProtocol(IOUSBDeviceDescriptionRef devDesc, UInt8 protocol)
{
CFNumberRef aNumber = CFNumberCreate(devDesc->allocator, kCFNumberCharType, &protocol);
CFDictionarySetValue(devDesc->info, CFSTR("deviceProtocol"), aNumber);
CFRelease(aNumber);
}
uint8_t IOUSBDeviceDescriptionGetProtocol(IOUSBDeviceDescriptionRef ref)
{
return __getDictNumber(ref, CFSTR("deviceProtocol"));
}
uint16_t IOUSBDeviceDescriptionGetVendorID(IOUSBDeviceDescriptionRef ref)
{
return __getDictNumber(ref, CFSTR("vendorID"));
}
void IOUSBDeviceDescriptionSetVendorID(IOUSBDeviceDescriptionRef devDesc, UInt16 vendorID)
{
CFNumberRef aNumber = CFNumberCreate(devDesc->allocator, kCFNumberShortType, &vendorID);
CFDictionarySetValue(devDesc->info, CFSTR("vendorID"), aNumber);
CFRelease(aNumber);
}
uint16_t IOUSBDeviceDescriptionGetProductID(IOUSBDeviceDescriptionRef ref)
{
return __getDictNumber(ref, CFSTR("productID"));
}
void IOUSBDeviceDescriptionSetProductID(IOUSBDeviceDescriptionRef devDesc, UInt16 productID)
{
CFNumberRef aNumber = CFNumberCreate(devDesc->allocator, kCFNumberShortType, &productID);
CFDictionarySetValue(devDesc->info, CFSTR("productID"), aNumber);
CFRelease(aNumber);
}
uint16_t IOUSBDeviceDescriptionGetVersion(IOUSBDeviceDescriptionRef ref)
{
return __getDictNumber(ref, CFSTR("deviceID"));
}
CFStringRef IOUSBDeviceDescriptionGetManufacturerString(IOUSBDeviceDescriptionRef ref)
{
return CFDictionaryGetValue(ref->info, CFSTR("manufacturerString"));
}
CFStringRef IOUSBDeviceDescriptionGetProductString(IOUSBDeviceDescriptionRef ref)
{
return CFDictionaryGetValue(ref->info, CFSTR("productString"));
}
CFStringRef IOUSBDeviceDescriptionGetSerialString(IOUSBDeviceDescriptionRef ref)
{
return CFDictionaryGetValue(ref->info, CFSTR("serialNumber"));
}
void IOUSBDeviceDescriptionSetSerialString(IOUSBDeviceDescriptionRef ref, CFStringRef serial)
{
CFDictionarySetValue(ref->info, CFSTR("serialNumber"), serial);
}
void IOUSBDeviceDescriptionRemoveAllConfigurations(IOUSBDeviceDescriptionRef devDesc)
{
CFArrayRemoveAllValues((CFMutableArrayRef)CFDictionaryGetValue(devDesc->info, CFSTR("ConfigurationDescriptors")));
}
int IOUSBDeviceDescriptionGetMatchingConfiguration(IOUSBDeviceDescriptionRef devDesc, CFArrayRef interfaceNames)
{
CFArrayRef configDescs = (CFMutableArrayRef)CFDictionaryGetValue(devDesc->info, CFSTR("ConfigurationDescriptors"));
CFIndex count, index;
Boolean pass = FALSE;
int config = 0;
int defaultConfig = 0;
if ( !configDescs )
return 0;
count = CFArrayGetCount(configDescs);
if ( !count )
return 0;
for ( index=0; index<count && !pass; index++)
{
CFDictionaryRef configuration = CFArrayGetValueAtIndex(configDescs, index);
CFArrayRef configInterfaces;
CFIndex configInterfaceCount;
if ( !configuration )
continue;
if ( CFDictionaryGetValue(configuration, CFSTR("DefaultConfiguration")) == kCFBooleanTrue )
defaultConfig = index + 1;
configInterfaces = CFDictionaryGetValue(configuration, CFSTR("Interfaces"));
if ( !configInterfaces )
continue;
configInterfaceCount = CFArrayGetCount(configInterfaces);
if ( !configInterfaceCount )
continue;
if ( !interfaceNames )
continue;
CFIndex nameCount = CFArrayGetCount(interfaceNames);
CFIndex nameIndex;
if ( !nameCount )
continue;
pass = TRUE;
for (nameIndex=0; nameIndex<nameCount; nameIndex++)
{
CFStringRef intefaceName = CFArrayGetValueAtIndex(interfaceNames, nameIndex);
if ( kCFNotFound == CFArrayGetFirstIndexOfValue(configInterfaces, CFRangeMake(0, configInterfaceCount), intefaceName) )
{
pass = FALSE;
break;
}
}
if ( pass )
{
config = index + 1;
break;
}
}
if ( !config )
config = defaultConfig;
return config;
}
int IOUSBDeviceDescriptionAppendConfiguration(IOUSBDeviceDescriptionRef devDesc, CFStringRef textDescription, UInt8 attributes, UInt8 maxPower)
{
CFMutableArrayRef configs = (CFMutableArrayRef)CFDictionaryGetValue(devDesc->info, CFSTR("ConfigurationDescriptors"));
CFMutableDictionaryRef theConfig;
CFNumberRef aNumber;
CFMutableArrayRef interfaces;
CFDictionarySetValue(devDesc->info, CFSTR("AllowMultipleCreates"), kCFBooleanTrue);
theConfig = CFDictionaryCreateMutable(devDesc->allocator, 3, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
interfaces = CFArrayCreateMutable(devDesc->allocator, 4, &kCFTypeArrayCallBacks);
CFDictionaryAddValue(theConfig, CFSTR("Interfaces"), interfaces);
CFRelease(interfaces);
if(textDescription)
CFDictionaryAddValue(theConfig, CFSTR("Description"), textDescription);
aNumber = CFNumberCreate(devDesc->allocator, kCFNumberCharType, &attributes);
CFDictionaryAddValue(theConfig, CFSTR("Attributes"), aNumber);
CFRelease(aNumber);
aNumber = CFNumberCreate(devDesc->allocator, kCFNumberCharType, &maxPower);
CFDictionaryAddValue(theConfig, CFSTR("MaxPower"), aNumber);
CFRelease(aNumber);
CFArrayAppendValue(configs, theConfig);
CFRelease(theConfig);
return CFArrayGetCount(configs) - 1;
}
int IOUSBDeviceDescriptionAppendInterfaceToConfiguration(IOUSBDeviceDescriptionRef devDesc, int config, CFStringRef name)
{
CFMutableDictionaryRef theConfig;
CFMutableArrayRef configs = (CFMutableArrayRef)CFDictionaryGetValue(devDesc->info, CFSTR("ConfigurationDescriptors"));
CFMutableArrayRef interfaces;
theConfig = (CFMutableDictionaryRef)CFArrayGetValueAtIndex(configs, config);
if(NULL == theConfig)
return -1;
interfaces = (CFMutableArrayRef)CFDictionaryGetValue(theConfig, CFSTR("Interfaces"));
CFArrayAppendValue(interfaces, name);
return CFArrayGetCount(interfaces) - 1;
}
CFArrayRef IOUSBDeviceDescriptionCopyInterfaces(IOUSBDeviceDescriptionRef devDesc)
{
CFArrayRef configs = CFDictionaryGetValue(devDesc->info, CFSTR("ConfigurationDescriptors"));
CFIndex numConfigs = CFArrayGetCount(configs);
CFMutableArrayRef allInterfaces = CFArrayCreateMutable(devDesc->allocator, numConfigs, &kCFTypeArrayCallBacks);
if (allInterfaces != NULL) {
for (CFIndex i = 0; i < numConfigs; i++) {
CFDictionaryRef config = CFArrayGetValueAtIndex(configs, i);
CFArrayRef interfaces = CFDictionaryGetValue(config, CFSTR("Interfaces"));
CFArrayRef interfacesCopy = CFArrayCreateCopy(devDesc->allocator, interfaces);
if (interfacesCopy == NULL) {
CFRelease(allInterfaces);
allInterfaces = NULL;
break;
}
CFArrayAppendValue(allInterfaces, interfacesCopy);
CFRelease(interfacesCopy);
}
}
return allInterfaces;
}
static IOUSBDeviceDescriptionRef __IOUSBDeviceDescriptionCreateFromFile( CFAllocatorRef allocator, CFStringRef filePath )
{
IOUSBDeviceDescriptionRef devDesc = NULL;
CFURLRef fileURL = CFURLCreateWithFileSystemPath( allocator, filePath, kCFURLPOSIXPathStyle, false );
if(fileURL)
{
CFDataRef resourceData = NULL;
SInt32 errorCode;
CFURLCreateDataAndPropertiesFromResource(allocator, fileURL, &resourceData, NULL, NULL, &errorCode);
if(resourceData)
{
CFDictionaryRef allDescriptions;
allDescriptions = CFPropertyListCreateFromXMLData( allocator,resourceData,kCFPropertyListMutableContainersAndLeaves, NULL);
if(allDescriptions)
{
int rval;
char machineName[64];
size_t maxSize=sizeof(machineName);
CFMutableDictionaryRef thisDeviceDescription = NULL;
CFStringRef machineNameKey;
CFDictionaryRef devices;
rval = sysctlbyname("hw.machine", machineName, &maxSize, NULL, 0);
if(rval != 0)
strncpy(machineName, "sysctl hw.machine failed", sizeof(machineName));
machineNameKey = CFStringCreateWithCString(kCFAllocatorDefault, (const char *)machineName, kCFStringEncodingASCII);
devices = CFDictionaryGetValue(allDescriptions, CFSTR("devices"));
if(!devices) thisDeviceDescription = (CFMutableDictionaryRef)CFDictionaryGetValue(allDescriptions, machineNameKey);
else
{
thisDeviceDescription = (CFMutableDictionaryRef)CFDictionaryGetValue(devices, machineNameKey);
if(!thisDeviceDescription) thisDeviceDescription = (CFMutableDictionaryRef)CFDictionaryGetValue(devices, CFSTR("unknownHardware"));
if(thisDeviceDescription)
{
CFStringRef configName = CFDictionaryGetValue(thisDeviceDescription, CFSTR("ConfigurationDescriptors"));
if(CFGetTypeID(configName) == CFStringGetTypeID()) {
CFDictionaryRef configs = CFDictionaryGetValue(allDescriptions, CFSTR("configurations"));
CFDictionaryRef thisConfig = CFDictionaryGetValue(configs, configName);
CFDictionarySetValue(thisDeviceDescription, CFSTR("ConfigurationDescriptors"), thisConfig);
}
}
}
if(thisDeviceDescription)
devDesc = __IOUSBDeviceDescriptionCreateFromDictionary(NULL, thisDeviceDescription);
CFRelease(machineNameKey);
CFRelease(allDescriptions);
}
CFRelease(resourceData);
}
CFRelease(fileURL);
}
return devDesc;
}
IOUSBDeviceDescriptionRef IOUSBDeviceDescriptionCreateFromDefaults(CFAllocatorRef allocator)
{
return __IOUSBDeviceDescriptionCreateFromFile(allocator, CONFIG_FILE_PATH);
}