]> err.no Git - yubikey-personalization/commitdiff
rework the osx implementation to look at all devices
authorKlas Lindfors <klas@yubico.com>
Wed, 9 Jan 2013 12:24:23 +0000 (12:24 +0000)
committerKlas Lindfors <klas@yubico.com>
Wed, 9 Jan 2013 12:24:23 +0000 (12:24 +0000)
avoids the wacky api of key and value matching

ykcore/ykcore_osx.c

index 003802ec14651fb0a967162e542bb05efc7be3a1..b070bea094d3413202409071eaba2b0803a60276 100644 (file)
@@ -68,6 +68,19 @@ static void _ykosx_CopyToCFArray(const void *value, void *context)
        CFArrayAppendValue( ( CFMutableArrayRef ) context, value );
 }
 
+static int _ykosx_getIntProperty( IOHIDDeviceRef dev, CFStringRef key ) {
+       int result = 0;
+       CFTypeRef tCFTypeRef = IOHIDDeviceGetProperty( dev, key );
+       if ( tCFTypeRef ) {
+               // if this is a number
+               if ( CFNumberGetTypeID( ) == CFGetTypeID( tCFTypeRef ) ) {
+                       // get its value
+                       CFNumberGetValue( ( CFNumberRef ) tCFTypeRef, kCFNumberSInt32Type, &result );
+               }
+       }
+       return result;
+}
+
 void *_ykusb_open_device(int vendor_id, int *product_ids, size_t pids_len)
 {
        void *yk = NULL;
@@ -76,46 +89,44 @@ void *_ykusb_open_device(int vendor_id, int *product_ids, size_t pids_len)
 
        size_t i;
 
-       CFMutableArrayRef matches = CFArrayCreateMutable( kCFAllocatorDefault, pids_len, &kCFTypeArrayCallBacks );
-
-       CFNumberRef vendorID = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &vendor_id );
-       for(i = 0; i < pids_len; i++) {
-               CFDictionaryRef dict;
-               CFStringRef keys[2];
-               CFStringRef values[2];
-
-               CFNumberRef productID = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &product_ids[i] );
-
-               keys[0] = CFSTR( kIOHIDVendorIDKey );  values[0] = (void *) vendorID;
-               keys[1] = CFSTR( kIOHIDProductIDKey ); values[1] = (void *) productID;
-
-               dict = CFDictionaryCreate( kCFAllocatorDefault, (const void **) &keys, (const void **) &values, 1, NULL, NULL);
-               CFArrayAppendValue( matches, dict );
-
-               CFRelease( productID );
-               CFRelease( dict );
-       }
-
-       IOHIDManagerSetDeviceMatchingMultiple( ykosxManager, matches );
+       IOHIDManagerSetDeviceMatchingMultiple( ykosxManager, NULL );
 
        CFSetRef devSet = IOHIDManagerCopyDevices( ykosxManager );
 
        if ( devSet ) {
-               rc = YK_EUSBERR;
-
                CFMutableArrayRef array = CFArrayCreateMutable( kCFAllocatorDefault, 0, NULL );
 
                CFSetApplyFunction( devSet, _ykosx_CopyToCFArray, array );
 
                CFIndex cnt = CFArrayGetCount( array );
 
-               if (cnt == 1) {
-                       yk = (void *) CFArrayGetValueAtIndex( array, 0 );
-                       CFRetain(yk);
-               } else if(cnt > 1) {
-                       rc = YK_EMORETHANONE;
+               CFIndex i;
+
+               for(i = 0; i < cnt; i++) {
+                       IOHIDDeviceRef dev = CFArrayGetValueAtIndex( array, i );
+                       long devVendorId = _ykosx_getIntProperty( dev, CFSTR( kIOHIDVendorIDKey ));
+                       if(devVendorId == vendor_id) {
+                               long devProductId = _ykosx_getIntProperty( dev, CFSTR( kIOHIDProductIDKey ));
+                               size_t j;
+                               for(j = 0; j < pids_len; j++) {
+                                       if(product_ids[j] == devProductId) {
+                                               if(yk == NULL) {
+                                                       yk = dev;
+                                                       break;
+                                               } else {
+                                                       rc = YK_EMORETHANONE;
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+                       if(rc == YK_EMORETHANONE) {
+                               yk = NULL;
+                               break;
+                       }
                }
-               else {
+
+               if(rc != YK_EMORETHANONE) {
                        rc = YK_ENOKEY;
                }
 
@@ -127,14 +138,13 @@ void *_ykusb_open_device(int vendor_id, int *product_ids, size_t pids_len)
                CFRelease( devSet );
        }
 
-       CFRelease( vendorID );
-       CFRelease( matches );
-
        if (yk) {
+               CFRetain(yk);
                _ykusb_IOReturn = IOHIDDeviceOpen( yk, 0L );
 
                if ( _ykusb_IOReturn != kIOReturnSuccess ) {
                        CFRelease(yk);
+                       rc = YK_EUSBERR;
                        goto error;
                }