/** @brief detect devices based on usb pid / vid. * @return list with usb VID / PID values. */ QMap<uint32_t, QString> System::listUsbDevices(void) { QMap<uint32_t, QString> usbids; // usb pid detection qDebug() << "[System] Searching for USB devices"; #if defined(Q_OS_LINUX) #if defined(LIBUSB1) libusb_device **devs; if(libusb_init(NULL) != 0) { qDebug() << "[System] Initializing libusb-1 failed."; return usbids; } if(libusb_get_device_list(NULL, &devs) < 1) { qDebug() << "[System] Error getting device list."; return usbids; } libusb_device *dev; int i = 0; while((dev = devs[i++]) != NULL) { QString name; unsigned char buf[256]; uint32_t id; struct libusb_device_descriptor descriptor; if(libusb_get_device_descriptor(dev, &descriptor) == 0) { id = descriptor.idVendor << 16 | descriptor.idProduct; libusb_device_handle *dh; if(libusb_open(dev, &dh) == 0) { libusb_get_string_descriptor_ascii(dh, descriptor.iManufacturer, buf, 256); name += QString::fromLatin1((char*)buf) + " "; libusb_get_string_descriptor_ascii(dh, descriptor.iProduct, buf, 256); name += QString::fromLatin1((char*)buf); libusb_close(dh); } if(name.isEmpty()) name = tr("(no description available)"); if(id) { usbids.insert(id, name); qDebug("[System] USB: 0x%08x, %s", id, name.toLocal8Bit().data()); } } } libusb_free_device_list(devs, 1); libusb_exit(NULL); #else usb_init(); usb_find_busses(); usb_find_devices(); struct usb_bus *b; b = usb_busses; while(b) { if(b->devices) { struct usb_device *u; u = b->devices; while(u) { uint32_t id; id = u->descriptor.idVendor << 16 | u->descriptor.idProduct; // get identification strings usb_dev_handle *dev; QString name; char string[256]; int res; dev = usb_open(u); if(dev) { if(u->descriptor.iManufacturer) { res = usb_get_string_simple(dev, u->descriptor.iManufacturer, string, sizeof(string)); if(res > 0) name += QString::fromLatin1(string) + " "; } if(u->descriptor.iProduct) { res = usb_get_string_simple(dev, u->descriptor.iProduct, string, sizeof(string)); if(res > 0) name += QString::fromLatin1(string); } usb_close(dev); } if(name.isEmpty()) name = tr("(no description available)"); if(id) { usbids.insert(id, name); qDebug() << "[System] USB:" << QString("0x%1").arg(id, 8, 16) << name; } u = u->next; } } b = b->next; } #endif #endif #if defined(Q_OS_MACX) kern_return_t result = KERN_FAILURE; CFMutableDictionaryRef usb_matching_dictionary; io_iterator_t usb_iterator = IO_OBJECT_NULL; usb_matching_dictionary = IOServiceMatching(kIOUSBDeviceClassName); result = IOServiceGetMatchingServices(kIOMasterPortDefault, usb_matching_dictionary, &usb_iterator); if(result) { qDebug() << "[System] USB: IOKit: Could not get matching services."; return usbids; } io_object_t usbCurrentObj; while((usbCurrentObj = IOIteratorNext(usb_iterator))) { uint32_t id; QString name; /* get vendor ID */ CFTypeRef vidref = NULL; int vid = 0; vidref = IORegistryEntryCreateCFProperty(usbCurrentObj, CFSTR("idVendor"), kCFAllocatorDefault, 0); CFNumberGetValue((CFNumberRef)vidref, kCFNumberIntType, &vid); CFRelease(vidref); /* get product ID */ CFTypeRef pidref = NULL; int pid = 0; pidref = IORegistryEntryCreateCFProperty(usbCurrentObj, CFSTR("idProduct"), kCFAllocatorDefault, 0); CFNumberGetValue((CFNumberRef)pidref, kCFNumberIntType, &pid); CFRelease(pidref); id = vid << 16 | pid; /* get product vendor */ char vendor_buf[256]; CFIndex vendor_buflen = 256; CFTypeRef vendor_name_ref = NULL; vendor_name_ref = IORegistryEntrySearchCFProperty(usbCurrentObj, kIOServicePlane, CFSTR("USB Vendor Name"), kCFAllocatorDefault, 0); if(vendor_name_ref != NULL) { CFStringGetCString((CFStringRef)vendor_name_ref, vendor_buf, vendor_buflen, kCFStringEncodingUTF8); name += QString::fromUtf8(vendor_buf) + " "; CFRelease(vendor_name_ref); } else { name += QObject::tr("(unknown vendor name) "); } /* get product name */ char product_buf[256]; CFIndex product_buflen = 256; CFTypeRef product_name_ref = NULL; product_name_ref = IORegistryEntrySearchCFProperty(usbCurrentObj, kIOServicePlane, CFSTR("USB Product Name"), kCFAllocatorDefault, 0); if(product_name_ref != NULL) { CFStringGetCString((CFStringRef)product_name_ref, product_buf, product_buflen, kCFStringEncodingUTF8); name += QString::fromUtf8(product_buf); CFRelease(product_name_ref); } else { name += QObject::tr("(unknown product name)"); } if(id) { usbids.insert(id, name); qDebug() << "[System] USB:" << QString("0x%1").arg(id, 8, 16) << name; } } IOObjectRelease(usb_iterator); #endif #if defined(Q_OS_WIN32) HDEVINFO deviceInfo; SP_DEVINFO_DATA infoData; DWORD i; // Iterate over all devices // by doing it this way it's unneccessary to use GUIDs which might be not // present in current MinGW. It also seemed to be more reliably than using // a GUID. // See KB259695 for an example. deviceInfo = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT); infoData.cbSize = sizeof(SP_DEVINFO_DATA); for(i = 0; SetupDiEnumDeviceInfo(deviceInfo, i, &infoData); i++) { DWORD data; LPTSTR buffer = NULL; DWORD buffersize = 0; QString description; // get device desriptor first // for some reason not doing so results in bad things (tm) while(!SetupDiGetDeviceRegistryProperty(deviceInfo, &infoData, SPDRP_DEVICEDESC, &data, (PBYTE)buffer, buffersize, &buffersize)) { if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) { if(buffer) free(buffer); // double buffer size to avoid problems as per KB888609 buffer = (LPTSTR)malloc(buffersize * 2); } else { break; } } description = QString::fromWCharArray(buffer); // now get the hardware id, which contains PID and VID. while(!SetupDiGetDeviceRegistryProperty(deviceInfo, &infoData, SPDRP_HARDWAREID, &data, (PBYTE)buffer, buffersize, &buffersize)) { if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) { if(buffer) free(buffer); // double buffer size to avoid problems as per KB888609 buffer = (LPTSTR)malloc(buffersize * 2); } else { break; } } unsigned int vid, pid; // convert buffer text to upper case to avoid depending on the case of // the keys (W7 uses different casing than XP at least). int len = _tcslen(buffer); while(len--) buffer[len] = _totupper(buffer[len]); if(_stscanf(buffer, _TEXT("USB\\VID_%x&PID_%x"), &vid, &pid) == 2) { uint32_t id; id = vid << 16 | pid; usbids.insert(id, description); qDebug("[System] USB VID: %04x, PID: %04x", vid, pid); } if(buffer) free(buffer); } SetupDiDestroyDeviceInfoList(deviceInfo); #endif return usbids; }
USBLIB_DECL(int) USBLibInit(void) { /* * Already open? * This isn't properly serialized, but we'll be fine with the current usage. */ if (g_cUsers) { ASMAtomicIncU32(&g_cUsers); return VINF_SUCCESS; } /* * Finding the VBoxUSB service. */ mach_port_t MasterPort; kern_return_t kr = IOMasterPort(MACH_PORT_NULL, &MasterPort); if (kr != kIOReturnSuccess) { LogRel(("USBLib: IOMasterPort -> %#x\n", kr)); return RTErrConvertFromDarwinKern(kr); } CFDictionaryRef ClassToMatch = IOServiceMatching(IOCLASS_NAME); if (!ClassToMatch) { LogRel(("USBLib: IOServiceMatching(\"%s\") failed.\n", IOCLASS_NAME)); return VERR_GENERAL_FAILURE; } /* Create an io_iterator_t for all instances of our drivers class that exist in the IORegistry. */ io_iterator_t Iterator; kr = IOServiceGetMatchingServices(g_MasterPort, ClassToMatch, &Iterator); if (kr != kIOReturnSuccess) { LogRel(("USBLib: IOServiceGetMatchingServices returned %#x\n", kr)); return RTErrConvertFromDarwinKern(kr); } /* Get the first item in the iterator and release it. */ io_service_t ServiceObject = IOIteratorNext(Iterator); IOObjectRelease(Iterator); if (!ServiceObject) { LogRel(("USBLib: Couldn't find any matches.\n")); return VERR_GENERAL_FAILURE; } /* * Open the service. * This will cause the user client class in VBoxUSB.cpp to be instantiated. */ kr = IOServiceOpen(ServiceObject, mach_task_self(), VBOXUSB_DARWIN_IOSERVICE_COOKIE, &g_Connection); IOObjectRelease(ServiceObject); if (kr != kIOReturnSuccess) { LogRel(("USBLib: IOServiceOpen returned %#x\n", kr)); return RTErrConvertFromDarwinKern(kr); } ASMAtomicIncU32(&g_cUsers); return VINF_SUCCESS; }
/* Function to scan the system for joysticks. * Joystick 0 should be the system default joystick. * This function should return the number of available joysticks, or -1 * on an unrecoverable fatal error. */ int SDL_SYS_JoystickInit(void) { IOReturn result = kIOReturnSuccess; mach_port_t masterPort = NULL; io_iterator_t hidObjectIterator = NULL; CFMutableDictionaryRef hidMatchDictionary = NULL; recDevice *device, *lastDevice; io_object_t ioHIDDeviceObject = NULL; SDL_numjoysticks = 0; if (NULL != gpDeviceList) { SDL_SetError("Joystick: Device list already inited."); return -1; } result = IOMasterPort (bootstrap_port, &masterPort); if (kIOReturnSuccess != result) { SDL_SetError("Joystick: IOMasterPort error with bootstrap_port."); return -1; } /* Set up a matching dictionary to search I/O Registry by class name for all HID class devices. */ hidMatchDictionary = IOServiceMatching (kIOHIDDeviceKey); if ((hidMatchDictionary != NULL)) { /* Add key for device type (joystick, in this case) to refine the matching dictionary. */ /* NOTE: we now perform this filtering later UInt32 usagePage = kHIDPage_GenericDesktop; UInt32 usage = kHIDUsage_GD_Joystick; CFNumberRef refUsage = NULL, refUsagePage = NULL; refUsage = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &usage); CFDictionarySetValue (hidMatchDictionary, CFSTR (kIOHIDPrimaryUsageKey), refUsage); refUsagePage = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &usagePage); CFDictionarySetValue (hidMatchDictionary, CFSTR (kIOHIDPrimaryUsagePageKey), refUsagePage); */ } else { SDL_SetError("Joystick: Failed to get HID CFMutableDictionaryRef via IOServiceMatching."); return -1; } /*/ Now search I/O Registry for matching devices. */ result = IOServiceGetMatchingServices (masterPort, hidMatchDictionary, &hidObjectIterator); /* Check for errors */ if (kIOReturnSuccess != result) { SDL_SetError("Joystick: Couldn't create a HID object iterator."); return -1; } if (NULL == hidObjectIterator) /* there are no joysticks */ { gpDeviceList = NULL; SDL_numjoysticks = 0; return 0; } /* IOServiceGetMatchingServices consumes a reference to the dictionary, so we don't need to release the dictionary ref. */ /* build flat linked list of devices from device iterator */ gpDeviceList = lastDevice = NULL; while ((ioHIDDeviceObject = IOIteratorNext (hidObjectIterator))) { /* build a device record */ device = HIDBuildDevice (ioHIDDeviceObject); if (!device) continue; /* dump device object, it is no longer needed */ result = IOObjectRelease (ioHIDDeviceObject); // if (KERN_SUCCESS != result) // HIDReportErrorNum ("IOObjectRelease error with ioHIDDeviceObject.", result); /* Filter device list to non-keyboard/mouse stuff */ if ( (device->usagePage != kHIDPage_GenericDesktop) || ((device->usage != kHIDUsage_GD_Joystick && device->usage != kHIDUsage_GD_GamePad)) ) { /* release memory for the device */ HIDDisposeDevice (&device); DisposePtr((Ptr)device); continue; } /* Add device to the end of the list */ if (lastDevice) lastDevice->pNext = device; else gpDeviceList = device; lastDevice = device; } result = IOObjectRelease (hidObjectIterator); /* release the iterator */ /* Count the total number of devices we found */ device = gpDeviceList; while (device) { SDL_numjoysticks++; device = device->pNext; } return SDL_numjoysticks; }
/** Initializes the USB system. Returns 0 on success, -1 on error. */ static int init_usb(ifc_match_func callback, usb_handle **handle) { int ret = -1; CFMutableDictionaryRef matchingDict; kern_return_t result; io_iterator_t iterator; usb_handle h; h.success = 0; h.callback = callback; /* * Create our matching dictionary to find appropriate devices. * IOServiceAddMatchingNotification consumes the reference, so we * do not need to release it. */ matchingDict = IOServiceMatching(kIOUSBDeviceClassName); if (matchingDict == NULL) { ERR("Couldn't create USB matching dictionary.\n"); return -1; } result = IOServiceGetMatchingServices( kIOMasterPortDefault, matchingDict, &iterator); if (result != 0) { ERR("Could not create iterator."); return -1; } for (;;) { if (! IOIteratorIsValid(iterator)) { /* * Apple documentation advises resetting the iterator if * it should become invalid during iteration. */ IOIteratorReset(iterator); continue; } io_service_t device = IOIteratorNext(iterator); if (device == 0) { break; } if (try_device(device, &h) != 0) { IOObjectRelease(device); ret = -1; break; } if (h.success) { *handle = calloc(1, sizeof(usb_handle)); memcpy(*handle, &h, sizeof(usb_handle)); ret = 0; break; } IOObjectRelease(device); } IOObjectRelease(iterator); return ret; }
/* * Finds PC Card devices currently registered in the system that match any of * the drivers detected in the driver bundle vector. */ static int HPDriversMatchPCCardDevices(HPDriver * driverBundle, HPDeviceList * readerList) { CFDictionaryRef pccMatch = IOServiceMatching("IOPCCard16Device"); if (pccMatch == NULL) { Log1(PCSC_LOG_ERROR, "error getting PCCard match from IOServiceMatching()"); return 1; } io_iterator_t pccIter; kern_return_t kret = IOServiceGetMatchingServices(kIOMasterPortDefault, pccMatch, &pccIter); if (kret != 0) { Log1(PCSC_LOG_ERROR, "error getting iterator from IOServiceGetMatchingServices()"); return 1; } IOIteratorReset(pccIter); io_object_t pccDevice = 0; while ((pccDevice = IOIteratorNext(pccIter))) { char namebuf[1024]; kret = IORegistryEntryGetName(pccDevice, namebuf); if (kret != 0) { Log1(PCSC_LOG_ERROR, "error getting plugin interface from IOCreatePlugInInterfaceForService()"); return 1; } UInt32 vendorId = 0; UInt32 productId = 0; UInt32 pccAddress = 0; CFTypeRef valueRef = IORegistryEntryCreateCFProperty(pccDevice, CFSTR("VendorID"), kCFAllocatorDefault, 0); if (!valueRef) { Log1(PCSC_LOG_ERROR, "error getting vendor"); } else { CFNumberGetValue((CFNumberRef) valueRef, kCFNumberSInt32Type, &vendorId); } valueRef = IORegistryEntryCreateCFProperty(pccDevice, CFSTR("DeviceID"), kCFAllocatorDefault, 0); if (!valueRef) { Log1(PCSC_LOG_ERROR, "error getting device"); } else { CFNumberGetValue((CFNumberRef) valueRef, kCFNumberSInt32Type, &productId); } valueRef = IORegistryEntryCreateCFProperty(pccDevice, CFSTR("SocketNumber"), kCFAllocatorDefault, 0); if (!valueRef) { Log1(PCSC_LOG_ERROR, "error getting PC Card socket"); } else { CFNumberGetValue((CFNumberRef) valueRef, kCFNumberSInt32Type, &pccAddress); } HPDriver *driver = driverBundle; for (; driver->m_vendorId; ++driver) { if ((driver->m_vendorId == vendorId) && (driver->m_productId == productId)) { *readerList = HPDeviceListInsert(*readerList, driver, pccAddress); } } } IOObjectRelease(pccIter); return 0; }
static void get_via_generic_iokit (double *ret_capacity_full, /* {{{ */ double *ret_capacity_design, double *ret_current, double *ret_voltage) { kern_return_t status; io_iterator_t iterator; io_object_t io_obj; CFDictionaryRef bat_root_dict; CFArrayRef bat_info_arry; CFIndex bat_info_arry_len; CFIndex bat_info_arry_pos; CFDictionaryRef bat_info_dict; double temp_double; status = IOServiceGetMatchingServices (kIOMasterPortDefault, IOServiceNameMatching ("battery"), &iterator); if (status != kIOReturnSuccess) { DEBUG ("IOServiceGetMatchingServices failed."); return; } while ((io_obj = IOIteratorNext (iterator))) { status = IORegistryEntryCreateCFProperties (io_obj, (CFMutableDictionaryRef *) &bat_root_dict, kCFAllocatorDefault, kNilOptions); if (status != kIOReturnSuccess) { DEBUG ("IORegistryEntryCreateCFProperties failed."); continue; } bat_info_arry = (CFArrayRef) CFDictionaryGetValue (bat_root_dict, CFSTR ("IOBatteryInfo")); if (bat_info_arry == NULL) { CFRelease (bat_root_dict); continue; } bat_info_arry_len = CFArrayGetCount (bat_info_arry); for (bat_info_arry_pos = 0; bat_info_arry_pos < bat_info_arry_len; bat_info_arry_pos++) { bat_info_dict = (CFDictionaryRef) CFArrayGetValueAtIndex (bat_info_arry, bat_info_arry_pos); if (isnan (*ret_capacity_full)) { temp_double = dict_get_double (bat_info_dict, "Capacity"); *ret_capacity_full = temp_double / 1000.0; } if (isnan (*ret_capacity_design)) { temp_double = dict_get_double (bat_info_dict, "AbsoluteMaxCapacity"); *ret_capacity_design = temp_double / 1000.0; } if (isnan (*ret_current)) { temp_double = dict_get_double (bat_info_dict, "Current"); *ret_current = temp_double / 1000.0; } if (isnan (*ret_voltage)) { temp_double = dict_get_double (bat_info_dict, "Voltage"); *ret_voltage = temp_double / 1000.0; } } CFRelease (bat_root_dict); } IOObjectRelease (iterator); } /* }}} void get_via_generic_iokit */
int main(int argc, char* argv[]) { kern_return_t kernResult; io_service_t service; io_iterator_t iterator; bool driverFound = false; // This will launch the Console.app so you can see the IOLogs from the kext. MyLaunchConsoleApp(); // Look up the objects we wish to open. This example uses simple class // matching (IOServiceMatching()) to find instances of the class defined by the kext. // // Because Mac OS X has no weak-linking support in the kernel, the only way to // support mutually-exclusive KPIs is to provide separate kexts. This in turn means that the // separate kexts must have their own unique CFBundleIdentifiers and I/O Kit class names. // // This sample shows how to do this in the SimpleUserClient and SimpleUserClient_10.4 Xcode targets. // // From the userland perspective, a process must look for any of the class names it is prepared to talk to. // This creates an io_iterator_t of all instances of our driver that exist in the I/O Registry. kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching(kSimpleDriverClassName), &iterator); if (kernResult != KERN_SUCCESS) { fprintf(stderr, "IOServiceGetMatchingServices returned 0x%08x\n\n", kernResult); return -1; } while ((service = IOIteratorNext(iterator)) != IO_OBJECT_NULL) { driverFound = true; printf("Found a device of class "kSimpleDriverClassName".\n\n"); TestUserClient(service); } // Release the io_iterator_t now that we're done with it. IOObjectRelease(iterator); // Repeat the test on any instances of the Mac OS X 10.4 version of the driver. kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching(kSimpleDriverClassName_10_4), &iterator); if (kernResult != KERN_SUCCESS) { fprintf(stderr, "IOServiceGetMatchingServices returned 0x%08x\n\n", kernResult); return -1; } while ((service = IOIteratorNext(iterator)) != IO_OBJECT_NULL) { driverFound = true; printf("Found a device of class "kSimpleDriverClassName_10_4".\n\n"); TestUserClient(service); } // Release the io_iterator_t now that we're done with it. IOObjectRelease(iterator); if (driverFound == false) { fprintf(stderr, "No matching drivers found.\n"); } return EXIT_SUCCESS; }
RString ArchHooks_MacOSX::GetMachineId() const { RString ret; CFMutableDictionaryRef dict = IOServiceMatching( "IOPlatformExpertDevice" ); CFMutableDictionaryRef property; io_service_t service; if( dict ) { // This consumes the reference. service = IOServiceGetMatchingService( kIOMasterPortDefault, dict ); if( service ) { CFTypeRef serial; CFStringRef key = CFSTR( "IOPlatformSerialNumber" ); // kIOPlatformSerialNumberKey serial = IORegistryEntryCreateCFProperty( service, key, kCFAllocatorDefault, 0 ); if( serial ) { const char *str = CFStringGetCStringPtr( (CFStringRef)serial, CFStringGetSystemEncoding() ); ret = str? str:""; CFRelease( serial ); } IOObjectRelease( service ); } } dict = IOServiceMatching( kIOEthernetInterfaceClass ); if( !dict ) return ret; property = CFDictionaryCreateMutable( kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); if( !property ) { CFRelease( dict ); return ret; } CFDictionarySetValue( property, CFSTR(kIOPrimaryInterface), kCFBooleanTrue ); CFDictionarySetValue( dict, CFSTR(kIOPropertyMatchKey), property ); CFRelease( property ); io_iterator_t iter; if( IOServiceGetMatchingServices(kIOMasterPortDefault, dict, &iter) != KERN_SUCCESS ) return ret; while( (service = IOIteratorNext(iter)) ) { CFTypeRef data; io_object_t controller; if( IORegistryEntryGetParentEntry(service, kIOServicePlane, &controller) != KERN_SUCCESS ) { IOObjectRelease( service ); continue; } data = IORegistryEntryCreateCFProperty( controller, CFSTR(kIOMACAddress), kCFAllocatorDefault, 0 ); if( data ) { const uint8_t *p = CFDataGetBytePtr( (CFDataRef)data ); ret += ssprintf( "-%02x:%02x:%02x:%02x:%02x:%02x", p[0], p[1], p[2], p[3], p[4], p[5] ); CFRelease( data ); } IOObjectRelease( controller ); IOObjectRelease( service ); } IOObjectRelease( iter ); return ret; }
void InitJoystick() { mach_port_t masterPort = NULL; io_iterator_t hidObjectIterator = NULL; IOReturn result = IOMasterPort (bootstrap_port, &masterPort); if(result != kIOReturnSuccess) return; CFMutableDictionaryRef hidMatchDictionary = IOServiceMatching (kIOHIDDeviceKey); if(!hidMatchDictionary) return; result = IOServiceGetMatchingServices (masterPort, hidMatchDictionary, &hidObjectIterator); if(result != kIOReturnSuccess) return; // find the first joystick/gamepad on the USB for(;;) { IOHIDDeviceInterface **device; io_object_t ioHIDDeviceObject = IOIteratorNext(hidObjectIterator); if(!ioHIDDeviceObject) break; CFMutableDictionaryRef hidProperties = 0; long kresult = IORegistryEntryCreateCFProperties(ioHIDDeviceObject, &hidProperties, kCFAllocatorDefault, kNilOptions); if(kresult == KERN_SUCCESS && hidProperties) { CFTypeRef refCF = 0; refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDProductKey)); if(CFGetTypeID(refCF) == CFStringGetTypeID()) { CFIndex bufferSize = CFStringGetLength (refCF) + 1; char * buffer = (char *)malloc (bufferSize); if (buffer) { if (CFStringGetCString (refCF, buffer, bufferSize, CFStringGetSystemEncoding ())) strncpy(gJoystickName, buffer, MaxJoystickNameLen); free(buffer); } } refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDPrimaryUsagePageKey)); long usage, usagePage; CFNumberGetValue (refCF, kCFNumberLongType, &usagePage); refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDPrimaryUsageKey)); CFNumberGetValue (refCF, kCFNumberLongType, &usage); if ( (usagePage == kHIDPage_GenericDesktop) && ((usage == kHIDUsage_GD_Joystick || usage == kHIDUsage_GD_GamePad)) ) { CFTypeRef refElementTop = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDElementKey)); if (refElementTop) { CFTypeID type = CFGetTypeID (refElementTop); if (type == CFArrayGetTypeID()) /* if element is an array */ { CFRange range = {0, CFArrayGetCount (refElementTop)}; /* CountElementsCFArrayHandler called for each array member */ CFArrayApplyFunction (refElementTop, range, HIDGetElementsCFArrayHandler, NULL); IOCFPlugInInterface ** ppPlugInInterface = NULL; S32 score; IOReturn result = IOCreatePlugInInterfaceForService (ioHIDDeviceObject, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &ppPlugInInterface, &score); if (result == kIOReturnSuccess) { // Call a method of the intermediate plug-in to create the device interface (*ppPlugInInterface)->QueryInterface (ppPlugInInterface, CFUUIDGetUUIDBytes (kIOHIDDeviceInterfaceID), (void *) &device); if(device) { result = (*device)->open(device, 0); gController.device = device; gJoystickInit = true; } (*ppPlugInInterface)->Release (ppPlugInInterface); } } } } CFRelease(hidProperties); } IOObjectRelease(ioHIDDeviceObject); if(gJoystickInit) break; } IOObjectRelease (hidObjectIterator); /* release the iterator */ }
int iterateDevices(io_iterator_t deviceIterator) { io_object_t usbDevice; int err = -1; IOReturn ret; IOUSBDeviceInterface245 **dev=NULL; SInt32 config = 0; int exclusiveErrs, attempts; for(attempts = 1; attempts < 5; attempts++) { exclusiveErrs = 0; usbDevice = IOIteratorNext(deviceIterator); if(usbDevice == IO_OBJECT_NULL) { fprintf(stderr, "Unable to find first matching USB device\n"); return(-1); } while(usbDevice != IO_OBJECT_NULL) { dev = getUSBDevice(usbDevice); if(dev != nil) { config = openUSBDevice(dev); if(config == -2) { exclusiveErrs++; } else if(config >= 0) { // Device sucessfully opened if(config > 0) { useUSBDevice(dev, config); } else { printf("What use is a device with a zero configuration????\n"); } ret = (*dev)->USBDeviceClose(dev); } ret = (*dev)->Release(dev); // Not worth bothering with errors here } IOObjectRelease(usbDevice); if(config >= 0) // we have sucessfully used device { return(0); } usbDevice = IOIteratorNext(deviceIterator); }; if(exclusiveErrs > 0) { sleep(1); IOIteratorReset(deviceIterator); printf("Trying open again %d\n", attempts); } else { break; } } return(err); }
int mp_input_ar_init(void) { io_iterator_t hidObjectIterator; io_object_t hidDevice; int i; IOHIDElementCookie *cookies = NULL; int nr_cookies = 0; if (initialized) mp_input_ar_close(-1); if (floor(NSAppKitVersionNumber) <= 824 /* NSAppKitVersionNumber10_4 */) { ar_codes = &ar_codes_tiger[0]; is_leopard = 0; } else { ar_codes = &ar_codes_leopard[0]; is_leopard = 1; } if (FindHIDDevices(kIOMasterPortDefault, &hidObjectIterator)) return -1; // Multiple controls could be found, we only use the first usable one. while ((hidDevice = IOIteratorNext(hidObjectIterator))) { if (CreateHIDDeviceInterface(hidDevice, &hidDeviceInterface) < 0) { hidDeviceInterface = NULL; IOObjectRelease(hidDevice); continue; } if (getHIDCookies((IOHIDDeviceInterface122 **)hidDeviceInterface, &cookies, &nr_cookies) < 0) { (*hidDeviceInterface)->Release(hidDeviceInterface); hidDeviceInterface = NULL; IOObjectRelease(hidDevice); continue; } IOObjectRelease(hidDevice); break; } if (hidDeviceInterface == NULL) goto mp_input_ar_init_error; // Open the device. if ((*hidDeviceInterface)->open(hidDeviceInterface, kIOHIDOptionsTypeSeizeDevice) != kIOReturnSuccess) goto mp_input_ar_init_error; hidDeviceIsOpen = 1; if ((queue = (*hidDeviceInterface)->allocQueue(hidDeviceInterface)) == NULL || *queue == NULL) goto mp_input_ar_init_error; // Create the queue. (*queue)->create(queue, 0, MAX_QUEUE_SIZE); // Add elements to the queue to make the queue work. // On tiger, it's a sequence from 1 to 21, // maybe it's the range of cookie values. for (i = 0;i < nr_cookies;i++) (*queue)->addElement(queue, cookies[i], 0); // not used anymore free(cookies); // Start data delivery to the queue. (*queue)->start(queue); // not useful anymore IOObjectRelease(hidObjectIterator); initialized = 1; return 0; mp_input_ar_init_error: free(cookies); if (hidDeviceInterface != NULL) { if (*hidDeviceInterface != NULL) { (*hidDeviceInterface)->close(hidDeviceInterface); (*hidDeviceInterface)->Release(hidDeviceInterface); } hidDeviceInterface = NULL; } IOObjectRelease(hidObjectIterator); return -1; }
bool OpenPortalHandleFromGUID(CFUUIDBytes guid, IOUSBDeviceInterface300*** phPortalHandle) { io_iterator_t iterator = 0; io_service_t usbRef; bool bResult = true; SInt32 score; HDEVINFO hDevInfo; SP_DEVICE_INTERFACE_DATA deviceInterfaceData; IOUSBConfigurationDescriptorPtr config; IOCFPlugInInterface** plugin; HIDD_ATTRIBUTES attributes; CFMutableDictionaryRef matchingDict = NULL; ULONG requiredLength=0; //Set up matching dictionary for class IOUSBDevice and its subclasses matchingDict = IOServiceMatching(kIOUSBDeviceClassName); if (!matchingDict) { printf("Couldn’t create a USB matching dictionary\n"); return false; } IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iterator); usbRef = IOIteratorNext(iterator); *phPortalHandle = NULL; while (usbRef != 0) { IOCreatePlugInInterfaceForService(usbRef, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, &score); IOObjectRelease(usbRef); (*plugin)->QueryInterface(plugin, guid, (LPVOID)phPortalHandle); (*plugin)->Release(plugin); if(guid == xbox_guid) { break; // we are done. xbox_guid does not have HID attributes } if (*phPortalHandle != NULL) { UInt16 VendorID, ProductID; (**phPortalHandle)->GetDeviceVendor(*phPortalHandle, &VendorID); (**phPortalHandle)->GetDeviceProduct(*phPortalHandle, &ProductID); if (((VendorID == 0x12ba) || (VendorID == 0x54c)) || (VendorID == 0x1430)) { if ((ProductID == 0x150) || (ProductID == 0x967)) { (**phPortalHandle)->USBDeviceOpen(*phPortalHandle); ret = (**phPortalHandle)->GetConfigurationDescriptorPtr(*phPortalHandle, 0, &config); (**phPortalHandle)->SetConfiguration(*phPortalHandle, config->bConfigurationValue); break; // found the portal. leave the handle open } } } (**phPortalHandle)->Release(*phPortalHandle); *phPortalHandle = NULL; } usbRef = IOIteratorNext(iterator); }
/** Try out all the interfaces and see if there's a match. Returns 0 on * success, -1 on failure. */ static int try_interfaces(IOUSBDeviceInterface182 **dev, usb_handle *handle) { IOReturn kr; IOUSBFindInterfaceRequest request; io_iterator_t iterator; io_service_t usbInterface; IOCFPlugInInterface **plugInInterface; IOUSBInterfaceInterface190 **interface = NULL; HRESULT result; SInt32 score; UInt8 interfaceNumEndpoints; UInt8 endpoint; UInt8 configuration; // Placing the constant KIOUSBFindInterfaceDontCare into the following // fields of the IOUSBFindInterfaceRequest structure will allow us to // find all of the interfaces request.bInterfaceClass = kIOUSBFindInterfaceDontCare; request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; request.bAlternateSetting = kIOUSBFindInterfaceDontCare; // SetConfiguration will kill an existing UMS connection, so let's // not do this if not necessary. configuration = 0; (*dev)->GetConfiguration(dev, &configuration); if (configuration != 1) (*dev)->SetConfiguration(dev, 1); // Get an iterator for the interfaces on the device kr = (*dev)->CreateInterfaceIterator(dev, &request, &iterator); if (kr != 0) { ERR("Couldn't create a device interface iterator: (%08x)\n", kr); return -1; } while ((usbInterface = IOIteratorNext(iterator))) { // Create an intermediate plugin kr = IOCreatePlugInInterfaceForService( usbInterface, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); // No longer need the usbInterface object now that we have the plugin (void) IOObjectRelease(usbInterface); if ((kr != 0) || (!plugInInterface)) { WARN("Unable to create plugin (%08x)\n", kr); continue; } // Now create the interface interface for the interface result = (*plugInInterface)->QueryInterface( plugInInterface, CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), (LPVOID) &interface); // No longer need the intermediate plugin (*plugInInterface)->Release(plugInInterface); if (result || !interface) { ERR("Couldn't create interface interface: (%08x)\n", (unsigned int) result); // continue so we can try the next interface continue; } /* * Now open the interface. This will cause the pipes * associated with the endpoints in the interface descriptor * to be instantiated. */ /* * TODO: Earlier comments here indicated that it was a bad * idea to just open any interface, because opening "mass * storage endpoints" is bad. However, the only way to find * out if an interface does bulk in or out is to open it, and * the framework in this application wants to be told about * bulk in / out before deciding whether it actually wants to * use the interface. Maybe something needs to be done about * this situation. */ kr = (*interface)->USBInterfaceOpen(interface); if (kr != 0) { WARN("Could not open interface: (%08x)\n", kr); (void) (*interface)->Release(interface); // continue so we can try the next interface continue; } // Get the number of endpoints associated with this interface. kr = (*interface)->GetNumEndpoints(interface, &interfaceNumEndpoints); if (kr != 0) { ERR("Unable to get number of endpoints: (%08x)\n", kr); goto next_interface; } // Get interface class, subclass and protocol if ((*interface)->GetInterfaceClass(interface, &handle->info.ifc_class) != 0 || (*interface)->GetInterfaceSubClass(interface, &handle->info.ifc_subclass) != 0 || (*interface)->GetInterfaceProtocol(interface, &handle->info.ifc_protocol) != 0) { ERR("Unable to get interface class, subclass and protocol\n"); goto next_interface; } handle->info.has_bulk_in = 0; handle->info.has_bulk_out = 0; // Iterate over the endpoints for this interface and see if there // are any that do bulk in/out. for (endpoint = 0; endpoint <= interfaceNumEndpoints; endpoint++) { UInt8 transferType; UInt16 maxPacketSize; UInt8 interval; UInt8 number; UInt8 direction; kr = (*interface)->GetPipeProperties(interface, endpoint, &direction, &number, &transferType, &maxPacketSize, &interval); if (kr == 0) { if (transferType != kUSBBulk) { continue; } if (direction == kUSBIn) { handle->info.has_bulk_in = 1; handle->bulkIn = endpoint; } else if (direction == kUSBOut) { handle->info.has_bulk_out = 1; handle->bulkOut = endpoint; } if (handle->info.ifc_protocol == 0x01) { handle->zero_mask = maxPacketSize - 1; } } else { ERR("could not get pipe properties\n"); } if (handle->info.has_bulk_in && handle->info.has_bulk_out) { break; } } if (handle->callback(&handle->info) == 0) { handle->interface = interface; handle->success = 1; /* * Clear both the endpoints, because it has been observed * that the Mac may otherwise (incorrectly) start out with * them in bad state. */ if (handle->info.has_bulk_in) { kr = (*interface)->ClearPipeStallBothEnds(interface, handle->bulkIn); if (kr != 0) { ERR("could not clear input pipe; result %d", kr); return -1; } } if (handle->info.has_bulk_out) { kr = (*interface)->ClearPipeStallBothEnds(interface, handle->bulkOut); if (kr != 0) { ERR("could not clear output pipe; result %d", kr); return -1; } } return 0; } next_interface: (*interface)->USBInterfaceClose(interface); (*interface)->Release(interface); } return 0; }
qint32 QUsbDevice::open() { IOCFPlugInInterface** plugin; io_iterator_t iterator = 0; io_service_t usbRef = 0; qint32 ret = 0; qint32 score = 0; CFDictionaryAddValue(mMatchingDictionary, CFSTR(kUSBVendorID), CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &mFilter.vid)); CFDictionaryAddValue(mMatchingDictionary, CFSTR(kUSBProductID), CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &mFilter.pid)); IOServiceGetMatchingServices(kIOMasterPortDefault, mMatchingDictionary, &iterator); usbRef = IOIteratorNext(iterator); if (usbRef == 0) { qWarning("Device not found"); return -1; } IOObjectRelease(iterator); IOCreatePlugInInterfaceForService(usbRef, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, &score); IOObjectRelease(usbRef); ret = (*plugin)->QueryInterface(plugin, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID300), (LPVOID)&mUsbInterface); (*plugin)->Release(plugin); if (ret || !mUsbInterface) { qWarning("Could not get interface (error: %x)\n", ret); return -2; } ret = (*mUsbDevice)->USBDeviceOpen(mUsbDevice); if (ret == kIOReturnSuccess) { // set first configuration as active ret = (*mUsbDevice)->GetConfigurationDescriptorPtr(mUsbDevice, 0, &config); if (ret != kIOReturnSuccess) { qWarning("Could not set active configuration (error: %x)\n", ret); return -3; } (*mUsbDevice)->SetConfiguration(mUsbDevice, config->bConfigurationValue); } else if (ret == kIOReturnExclusiveAccess) { // this is not a problem as we can still do some things } else { qWarning("Could not open device (error: %x)\n", ret); return -4; } ret = (*mUsbInterface)->USBInterfaceOpen(mUsbInterface); if (ret != kIOReturnSuccess) { qWarning("Could not open interface (error: %x)\n", ret); return -5; } return 0; }
bool wxHIDDevice::Create (int nClass, int nType, int nDev) { //Create the mach port wxIOCHECK(IOMasterPort(bootstrap_port, &m_pPort), "Could not create mach port"); //Dictionary that will hold first //the matching dictionary for determining which kind of devices we want, //then later some registry properties from an iterator (see below) CFMutableDictionaryRef pDictionary; //Create a dictionary //The call to IOServiceMatching filters down the //the services we want to hid services (and also eats the //dictionary up for us (consumes one reference)) wxVERIFY((pDictionary = IOServiceMatching(kIOHIDDeviceKey)) != NULL ); //Here we'll filter down the services to what we want if (nType != -1) { CFNumberRef pType = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &nType); CFDictionarySetValue(pDictionary, CFSTR(kIOHIDPrimaryUsageKey), pType); CFRelease(pType); } if (nClass != -1) { CFNumberRef pClass = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &nClass); CFDictionarySetValue(pDictionary, CFSTR(kIOHIDPrimaryUsagePageKey), pClass); CFRelease(pClass); } //Now get the maching services io_iterator_t pIterator; wxIOCHECK(IOServiceGetMatchingServices(m_pPort, pDictionary, &pIterator), "No Matching HID Services"); wxASSERT_MSG(pIterator != 0, wxT("No devices found!")); //Now we iterate through them io_object_t pObject; while ( (pObject = IOIteratorNext(pIterator)) != 0) { if(--nDev != 0) continue; wxVERIFY(IORegistryEntryCreateCFProperties(pObject, &pDictionary, kCFAllocatorDefault, kNilOptions) == KERN_SUCCESS); //Just for sanity :) wxASSERT(CFGetTypeID(CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductKey))) == CFStringGetTypeID()); /* kIOHIDTransportKey; kIOHIDVendorIDKey; kIOHIDProductIDKey; kIOHIDVersionNumberKey; kIOHIDManufacturerKey; kIOHIDSerialNumberKey; if !kIOHIDLocationIDKey kUSBDevicePropertyLocationID kIOHIDPrimaryUsageKey kIOHIDPrimaryUsagePageKey idProduct idVendor USB Product Name */ //Get [product] name m_szProductName = wxMacCFStringHolder( (CFStringRef) CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductKey)), false ).AsString(); CFNumberRef nref = (CFNumberRef) CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductIDKey)); if (nref) CFNumberGetValue( nref, kCFNumberIntType, &m_nProductId ); nref = (CFNumberRef) CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDVendorIDKey)); if (nref) CFNumberGetValue( nref, kCFNumberIntType, &m_nManufacturerId ); //Create the interface (good grief - long function names!) SInt32 nScore; IOCFPlugInInterface** ppPlugin; wxIOCHECK(IOCreatePlugInInterfaceForService(pObject, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &ppPlugin, &nScore), ""); //Now, the final thing we can check before we fall back to asserts //(because the dtor only checks if the device is ok, so if anything //fails from now on the dtor will delete the device anyway, so we can't break from this). //Get the HID interface from the plugin to the mach port wxSCHECK((*ppPlugin)->QueryInterface(ppPlugin, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (void**) &m_ppDevice), ""); //release the plugin (*ppPlugin)->Release(ppPlugin); //open the HID interface... wxVERIFY((*m_ppDevice)->open(m_ppDevice, 0) == S_OK); // //Now the hard part - in order to scan things we need "cookies" - // wxCFArray CookieArray = CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDElementKey)); BuildCookies(CookieArray); //cleanup CFRelease(pDictionary); IOObjectRelease(pObject); break; } //iterator cleanup IOObjectRelease(pIterator); return true; }//end Create()
/* Function to scan the system for joysticks. * Joystick 0 should be the system default joystick. * This function should return the number of available joysticks, or -1 * on an unrecoverable fatal error. */ int SDL_SYS_JoystickInit(void) { IOReturn result = kIOReturnSuccess; mach_port_t masterPort = 0; io_iterator_t hidObjectIterator = 0; CFMutableDictionaryRef hidMatchDictionary = NULL; io_object_t ioHIDDeviceObject = 0; io_iterator_t portIterator = 0; if (gpDeviceList) { return SDL_SetError("Joystick: Device list already inited."); } result = IOMasterPort(bootstrap_port, &masterPort); if (kIOReturnSuccess != result) { return SDL_SetError("Joystick: IOMasterPort error with bootstrap_port."); } /* Set up a matching dictionary to search I/O Registry by class name for all HID class devices. */ hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey); if (hidMatchDictionary) { /* Add key for device type (joystick, in this case) to refine the matching dictionary. */ /* NOTE: we now perform this filtering later UInt32 usagePage = kHIDPage_GenericDesktop; UInt32 usage = kHIDUsage_GD_Joystick; CFNumberRef refUsage = NULL, refUsagePage = NULL; refUsage = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &usage); CFDictionarySetValue (hidMatchDictionary, CFSTR (kIOHIDPrimaryUsageKey), refUsage); refUsagePage = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &usagePage); CFDictionarySetValue (hidMatchDictionary, CFSTR (kIOHIDPrimaryUsagePageKey), refUsagePage); */ } else { return SDL_SetError ("Joystick: Failed to get HID CFMutableDictionaryRef via IOServiceMatching."); } /* Now search I/O Registry for matching devices. */ result = IOServiceGetMatchingServices(masterPort, hidMatchDictionary, &hidObjectIterator); /* Check for errors */ if (kIOReturnSuccess != result) { return SDL_SetError("Joystick: Couldn't create a HID object iterator."); } if (!hidObjectIterator) { /* there are no joysticks */ gpDeviceList = NULL; return 0; } /* IOServiceGetMatchingServices consumes a reference to the dictionary, so we don't need to release the dictionary ref. */ /* build flat linked list of devices from device iterator */ gpDeviceList = NULL; while ((ioHIDDeviceObject = IOIteratorNext(hidObjectIterator))) { AddDeviceHelper( ioHIDDeviceObject ); } result = IOObjectRelease(hidObjectIterator); /* release the iterator */ /* now connect notification for new devices */ notificationPort = IONotificationPortCreate(masterPort); hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey); CFRunLoopAddSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(notificationPort), kCFRunLoopDefaultMode); /* Register for notifications when a serial port is added to the system */ result = IOServiceAddMatchingNotification(notificationPort, kIOFirstMatchNotification, hidMatchDictionary, JoystickDeviceWasAddedCallback, NULL, &portIterator); while (IOIteratorNext(portIterator)) {}; /* Run out the iterator or notifications won't start (you can also use it to iterate the available devices). */ return SDL_SYS_NumJoysticks(); }
static int probe_sms(int kernFunc, char *servMatch, int dataType, void *data) { kern_return_t result; mach_port_t masterPort; io_iterator_t iterator; io_object_t aDevice; io_connect_t dataPort; IOItemCount structureInputSize; IOByteCount structureOutputSize; union motion_data inputStructure; union motion_data *outputStructure; outputStructure = (union motion_data *)data; result = IOMasterPort(MACH_PORT_NULL, &masterPort); CFMutableDictionaryRef matchingDictionary = IOServiceMatching(servMatch); result = IOServiceGetMatchingServices(masterPort, matchingDictionary, &iterator); if (result != KERN_SUCCESS) { return -1; } aDevice = IOIteratorNext(iterator); IOObjectRelease(iterator); if (aDevice == 0) { return -2; } result = IOServiceOpen(aDevice, mach_task_self(), 0, &dataPort); IOObjectRelease(aDevice); if (result != KERN_SUCCESS) { return 3; } switch ( dataType ) { case PB_IB: structureInputSize = sizeof(struct pb_ib_data); structureOutputSize = sizeof(struct pb_ib_data); break; case MBP: structureInputSize = sizeof(struct mbp_data); structureOutputSize = sizeof(struct mbp_data); break; default: return 0; } memset(&inputStructure, 0, sizeof(union motion_data)); memset(outputStructure, 0, sizeof(union motion_data)); result = IOConnectMethodStructureIStructureO(dataPort, kernFunc, structureInputSize, &structureOutputSize, &inputStructure, outputStructure); IOServiceClose(dataPort); if (result != KERN_SUCCESS) { return -4; } return 1; }
/* * Finds USB devices currently registered in the system that match any of * the drivers detected in the driver bundle vector. */ static int HPDriversMatchUSBDevices(HPDriverVector driverBundle, HPDeviceList * readerList) { CFDictionaryRef usbMatch = IOServiceMatching("IOUSBDevice"); if (0 == usbMatch) { Log1(PCSC_LOG_ERROR, "error getting USB match from IOServiceMatching()"); return 1; } io_iterator_t usbIter; kern_return_t kret = IOServiceGetMatchingServices(kIOMasterPortDefault, usbMatch, &usbIter); if (kret != 0) { Log1(PCSC_LOG_ERROR, "error getting iterator from IOServiceGetMatchingServices()"); return 1; } IOIteratorReset(usbIter); io_object_t usbDevice = 0; while ((usbDevice = IOIteratorNext(usbIter))) { char namebuf[1024]; kret = IORegistryEntryGetName(usbDevice, namebuf); if (kret != 0) { Log1(PCSC_LOG_ERROR, "error getting device name from IORegistryEntryGetName()"); return 1; } IOCFPlugInInterface **iodev; SInt32 score; kret = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &iodev, &score); if (kret != 0) { Log1(PCSC_LOG_ERROR, "error getting plugin interface from IOCreatePlugInInterfaceForService()"); return 1; } IOObjectRelease(usbDevice); IOUSBDeviceInterface **usbdev; HRESULT hres = (*iodev)->QueryInterface(iodev, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID *) & usbdev); (*iodev)->Release(iodev); if (hres) { Log1(PCSC_LOG_ERROR, "error querying interface in QueryInterface()"); return 1; } UInt16 vendorId = 0; UInt16 productId = 0; UInt32 usbAddress = 0; kret = (*usbdev)->GetDeviceVendor(usbdev, &vendorId); kret = (*usbdev)->GetDeviceProduct(usbdev, &productId); kret = (*usbdev)->GetLocationID(usbdev, &usbAddress); (*usbdev)->Release(usbdev); #ifdef DEBUG_HOTPLUG Log4(PCSC_LOG_DEBUG, "Found USB device 0x%04X:0x%04X at 0x%X", vendorId, productId, usbAddress); #endif HPDriver *driver; for (driver = driverBundle; driver->m_vendorId; ++driver) { if ((driver->m_vendorId == vendorId) && (driver->m_productId == productId)) { #ifdef DEBUG_HOTPLUG Log4(PCSC_LOG_DEBUG, "Adding USB device %04X:%04X at 0x%X", vendorId, productId, usbAddress); #endif *readerList = HPDeviceListInsert(*readerList, driver, usbAddress); } } } IOObjectRelease(usbIter); return 0; }
/* return icom error */ int icompaths_refresh_paths(icompaths *p) { int rv, usbend = 0; int i,j; a1logd(p->log, 8, "icoms_get_paths: called\n"); /* Clear any existing paths */ p->clear(p); #ifdef ENABLE_USB if ((rv = hid_get_paths(p)) != ICOM_OK) return rv; if ((rv = usb_get_paths(p)) != ICOM_OK) return rv; #endif /* ENABLE_USB */ usbend = p->npaths; #if defined(ENABLE_SERIAL) || defined(ENABLE_FAST_SERIAL) #ifdef __APPLE__ /* Search the OSX registry for serial ports */ { kern_return_t kstat; mach_port_t mp; /* Master IO port */ CFMutableDictionaryRef sdict; /* Serial Port dictionary */ io_iterator_t mit; /* Matching itterator */ io_object_t ioob; /* Serial object found */ /* Get dictionary of serial ports */ if ((sdict = IOServiceMatching(kIOSerialBSDServiceValue)) == NULL) { a1loge(p->log, ICOM_SYS, "IOServiceMatching returned a NULL dictionary\n"); return ICOM_OK; } /* Set value to match to RS232 type serial */ CFDictionarySetValue(sdict, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDRS232Type)); /* Init itterator to find matching types. Consumes sdict reference */ if ((kstat = IOServiceGetMatchingServices(kIOMasterPortDefault, sdict, &mit)) != KERN_SUCCESS) { a1loge(p->log, ICOM_SYS, "IOServiceGetMatchingServices returned %d\n", kstat); return ICOM_SYS; } /* Find all the matching serial ports */ for (;;) { char pname[200]; icom_ser_attr sattr = icom_normal; CFTypeRef dfp; /* Device file path */ if ((ioob = IOIteratorNext(mit)) == 0) break; /* Get the callout device's path (/dev/cu.xxxxx). */ if ((dfp = IORegistryEntryCreateCFProperty(ioob, CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0)) == NULL) goto continue1; /* Convert from CF string to C string */ if (!CFStringGetCString(dfp, pname, 100, kCFStringEncodingASCII)) goto continue2; /* Ignore infra red port or Bluetooth, or any other noise */ if (strstr(pname, "IrDA") != NULL || strstr(pname, "Dialup") != NULL || strstr(pname, "Bluetooth") != NULL) goto continue2; /* Would be nice to identify FTDI serial ports more specifically ? */ if (strstr(pname, "usbserial") != NULL) sattr |= icom_fast; #ifndef ENABLE_SERIAL if (sattr & icom_fast) { /* Only add fast ports if !ENABLE_SERIAL */ #endif /* Add the port to the list */ p->add_serial(p, pname, pname, sattr); a1logd(p->log, 8, "icoms_get_paths: Added path '%s' attr 0x%x\n",pname, sattr); #ifndef ENABLE_SERIAL } #endif /* If fast, try and identify it */ if (sattr & icom_fast) { icompath *path; icoms *icom; if ((path = p->get_last_path(p)) != NULL && (icom = new_icoms(path, p->log)) != NULL) { instType itype = fast_ser_inst_type(icom, 0, NULL, NULL); if (itype != instUnknown) icompaths_set_serial_itype(path, itype); icom->del(icom); } } continue2: CFRelease(dfp); continue1: IOObjectRelease(ioob); /* Release found object */ } IOObjectRelease(mit); /* Release the itterator */ } #else /* Other UNIX like systems */ /* Many are crude and list every available device name, whether */ /* it's usable or not. Do any UNIX systems have a mechanism for listing */ /* serial ports ?? */ /* On Linux, the list in /proc/tty/driver/serial may indicate */ /* which are real or not (if "uart:unknown" then not real) */ /* e.g.: 0: uart:16550A port:000003F8 irq:4 tx:3 rx:1755 brk:1 RTS|DTR 1: uart:16550A port:000002F8 irq:3 tx:11 rx:3 brk:3 2: uart:unknown port:000003E8 irq:4 3: uart:unknown port:000002E8 irq:3 4: uart:unknown port:00000000 irq:0 5: uart:unknown port:00000000 irq:0 6: uart:unknown port:00000000 irq:0 7: uart:unknown port:00000000 irq:0 but the permissions don't allow looking at this. */ /* (This info is similar to what is returned by "setserial -g /dev/ttyS*", */ /* and "setserial -gb /dev/ttyS*" returns just the real ports.) */ /* None of this can distinguish if one is the mouse. */ /* From "QTSerialPort": */ /* Constant Used By Naming Convention ---------- ------------- ------------------------ _TTY_WIN_ Windows COM1, COM2 _TTY_IRIX_ SGI/IRIX /dev/ttyf1, /dev/ttyf2 _TTY_HPUX_ HP-UX /dev/tty1p0, /dev/tty2p0 _TTY_SUN_ SunOS/Solaris /dev/ttya, /dev/ttyb _TTY_DIGITAL_ Digital UNIX /dev/tty01, /dev/tty02 _TTY_FREEBSD_ FreeBSD /dev/ttyd0, /dev/ttyd1 _TTY_LINUX_ Linux /dev/ttyS0, /dev/ttyS1 <none> Linux /dev/ttyS0, /dev/ttyS1 Linux /dev/ttyUSB0, /dev/ttyUSB1 */ /* "Most program set a lock in /var/lock/LCK..tty<XX> on Linux ? <http://sunsite.ualberta.ca/LDP/LDP/nag2/x-087-2-serial.devices.html> <http://docs.freebsd.org/info/uucp/uucp.info.UUCP_Lock_Files.html> We should really use the lock files to avoid treading on other programs toes. We assume at the moment that the user only picks a serial port with an instrument on it. */ /* Search for devices that match the pattern /dev/ttyS[0-9]* and /dev/ttyUSB* */ /* We will assume that ttyUSB* ports includes FTDI ports */ { DIR *dd; struct dirent *de; char *dirn = "/dev/"; if ((dd = opendir(dirn)) == NULL) { a1loge(p->log, ICOM_SYS, "failed to open directory \"%s\"\n",dirn); return ICOM_OK; } for (;;) { int fd; char *dpath; icom_ser_attr sattr = icom_normal; if ((de = readdir(dd)) == NULL) break; if (!( #if defined(__FreeBSD__) || defined(__OpenBSD__) /* This should match uart & USB devs. */ ( strncmp (de->d_name, "cua", 3) == 0 && strlen (de->d_name) < 7) #else /* Presumably Linux.. */ ( strncmp(de->d_name, "ttyS", 4) == 0 && de->d_name[4] >= '0' && de->d_name[4] <= '9') || ( strncmp(de->d_name, "ttyUSB", 5) == 0) #endif )) continue; if ((dpath = (char *)malloc(strlen(dirn) + strlen(de->d_name) + 1)) == NULL) { closedir(dd); a1loge(p->log, ICOM_SYS, "icompaths_refresh_paths() malloc failed!\n"); return ICOM_SYS; } strcpy(dpath, dirn); strcat(dpath, de->d_name); /* See if the serial port is real */ if (strncmp(de->d_name, "ttyUSB", 5) != 0) { /* Hmm. This is probably a bad idea - it can upset other */ /* programs that use the serial ports ? */ if ((fd = open(dpath, O_RDONLY | O_NOCTTY | O_NONBLOCK)) < 0) { a1logd(p->log, 8, "icoms_get_paths: failed to open serial \"%s\" - not real\n",dpath); free(dpath); continue; } /* On linux we could do a struct serial_struct serinfo; serinfo.reserved_char[0] = 0; if (ioctl(fd, TIOCGSERIAL, &serinfo) < 0 || serinfo.type == PORT_UNKNOWN) { free(dpath); continue; } */ close(fd); } a1logd(p->log, 8, "icoms_get_paths: open'd serial \"%s\" - assume real\n",dpath); if (strncmp(de->d_name, "ttyUSB", 5) == 0) sattr |= icom_fast; #ifndef ENABLE_SERIAL if (sattr & icom_fast) { /* Only add fast ports if !ENABLE_SERIAL */ #endif /* Add the path to the list */ p->add_serial(p, dpath, dpath, 0); a1logd(p->log, 8, "icoms_get_paths: Added path '%s' attr 0x%x\n",dpath,sattr); #ifndef ENABLE_SERIAL } #endif free(dpath); /* If fast, try and identify it */ if (sattr & icom_fast) { icompath *path; icoms *icom; if ((path = p->get_last_path(p)) != NULL && (icom = new_icoms(path, p->log)) != NULL) { instType itype = fast_ser_inst_type(icom, 0, NULL, NULL); if (itype != instUnknown) icompaths_set_serial_itype(path, itype); icom->del(icom); } } } closedir(dd); } #endif /* ! __APPLE__ */ #endif /* ENABLE_SERIAL */ /* Sort the serial /dev keys so people don't get confused... */ /* Sort identified instruments ahead of unknown serial ports */ for (i = usbend; i < (p->npaths-1); i++) { for (j = i+1; j < p->npaths; j++) { if ((p->paths[i]->itype == instUnknown && p->paths[j]->itype != instUnknown) || (((p->paths[i]->itype == instUnknown && p->paths[j]->itype == instUnknown) || (p->paths[i]->itype != instUnknown && p->paths[j]->itype != instUnknown)) && strcmp(p->paths[i]->name, p->paths[j]->name) > 0)) { icompath *tt = p->paths[i]; p->paths[i] = p->paths[j]; p->paths[j] = tt; } } } return ICOM_OK; }
IOReturn IOPMCopyBatteryInfo( mach_port_t masterPort, CFArrayRef * oInfo ) { io_registry_entry_t root_domain; IOReturn kr = kIOReturnUnsupported; *oInfo = NULL; // ******************************************************************** // For PPC machines (with PMU), battery location is published under // IOPMrootDomain root_domain = IORegistryEntryFromPath( masterPort, kIOPowerPlane ":/IOPowerConnection/IOPMrootDomain"); if(!root_domain) return kIOReturnUnsupported; *oInfo = IORegistryEntryCreateCFProperty( root_domain, CFSTR(kIOBatteryInfoKey), kCFAllocatorDefault, kNilOptions); IOObjectRelease(root_domain); if(*oInfo) { // Successfully read battery info from IOPMrootDomain return kIOReturnSuccess; } // ******************************************************************** // For non-PMU based batteries with IOPMPowerSource conforming classes // Scan IORegistry for IOPMPowerSource nodes with IOLegacyBatteryInfo // - Toss all IOLegacyBatteryInfo dictionaries into an OSArray int batt_count = 0; io_registry_entry_t battery; io_iterator_t ioreg_batteries; CFMutableArrayRef legacyArray = CFArrayCreateMutable( kCFAllocatorDefault, 1, &kCFTypeArrayCallBacks); if(!legacyArray) return kIOReturnNoMemory; kr = IOServiceGetMatchingServices( MACH_PORT_NULL, IOServiceMatching("IOPMPowerSource"), &ioreg_batteries); if(KERN_SUCCESS != kr) { CFRelease(legacyArray); return kIOReturnError; } while( (battery = (io_registry_entry_t)IOIteratorNext(ioreg_batteries)) ) { CFDictionaryRef legacyDict; legacyDict = IORegistryEntryCreateCFProperty( battery, CFSTR(kIOPMPSLegacyBatteryInfoKey), kCFAllocatorDefault, 0); if(!legacyDict) continue; batt_count++; CFArrayAppendValue(legacyArray, legacyDict); CFRelease(legacyDict); IOObjectRelease(battery); } IOObjectRelease(ioreg_batteries); if(batt_count > 0) { *oInfo = legacyArray; } else { CFRelease(legacyArray); // Returns kIOReturnUnsupported if no batteries found return kIOReturnUnsupported; } return kIOReturnSuccess; }
static void AndroidInterfaceAdded(void *refCon, io_iterator_t iterator) { kern_return_t kr; io_service_t usbDevice; io_service_t usbInterface; IOCFPlugInInterface **plugInInterface = NULL; IOUSBInterfaceInterface220 **iface = NULL; IOUSBDeviceInterface197 **dev = NULL; HRESULT result; SInt32 score; UInt16 vendor; UInt16 product; UInt8 serialIndex; char serial[256]; while ((usbInterface = IOIteratorNext(iterator))) { //* Create an intermediate interface plugin kr = IOCreatePlugInInterfaceForService(usbInterface, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); IOObjectRelease(usbInterface); if ((kIOReturnSuccess != kr) || (!plugInInterface)) { DBG("ERR: Unable to create an interface plug-in (%08x)\n", kr); continue; } //* This gets us the interface object result = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), (LPVOID) &iface); //* We only needed the plugin to get the interface, so discard it (*plugInInterface)->Release(plugInInterface); if (result || !iface) { DBG("ERR: Couldn't query the interface (%08x)\n", (int) result); continue; } //* this gets us an ioservice, with which we will find the actual //* device; after getting a plugin, and querying the interface, of //* course. //* Gotta love OS X kr = (*iface)->GetDevice(iface, &usbDevice); if (kIOReturnSuccess != kr || !usbDevice) { DBG("ERR: Couldn't grab device from interface (%08x)\n", kr); continue; } plugInInterface = NULL; score = 0; //* create an intermediate device plugin kr = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); //* only needed this to find the plugin (void)IOObjectRelease(usbDevice); if ((kIOReturnSuccess != kr) || (!plugInInterface)) { DBG("ERR: Unable to create a device plug-in (%08x)\n", kr); continue; } result = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID) &dev); //* only needed this to query the plugin (*plugInInterface)->Release(plugInInterface); if (result || !dev) { DBG("ERR: Couldn't create a device interface (%08x)\n", (int) result); continue; } //* Now after all that, we actually have a ref to the device and //* the interface that matched our criteria kr = (*dev)->GetDeviceVendor(dev, &vendor); kr = (*dev)->GetDeviceProduct(dev, &product); kr = (*dev)->USBGetSerialNumberStringIndex(dev, &serialIndex); if (serialIndex > 0) { IOUSBDevRequest req; UInt16 buffer[256]; UInt16 languages[128]; memset(languages, 0, sizeof(languages)); req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice); req.bRequest = kUSBRqGetDescriptor; req.wValue = (kUSBStringDesc << 8) | 0; req.wIndex = 0; req.pData = languages; req.wLength = sizeof(languages); kr = (*dev)->DeviceRequest(dev, &req); if (kr == kIOReturnSuccess && req.wLenDone > 0) { int langCount = (req.wLenDone - 2) / 2, lang; for (lang = 1; lang <= langCount; lang++) { memset(buffer, 0, sizeof(buffer)); memset(&req, 0, sizeof(req)); req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice); req.bRequest = kUSBRqGetDescriptor; req.wValue = (kUSBStringDesc << 8) | serialIndex; req.wIndex = languages[lang]; req.pData = buffer; req.wLength = sizeof(buffer); kr = (*dev)->DeviceRequest(dev, &req); if (kr == kIOReturnSuccess && req.wLenDone > 0) { int i, count; // skip first word, and copy the rest to the serial string, // changing shorts to bytes. count = (req.wLenDone - 1) / 2; for (i = 0; i < count; i++) serial[i] = buffer[i + 1]; serial[i] = 0; break; } } } } (*dev)->Release(dev); DBG("INFO: Found vid=%04x pid=%04x serial=%s\n", vendor, product, serial); usb_handle* handle = CheckInterface((IOUSBInterfaceInterface**)iface, vendor, product); if (handle == NULL) { DBG("ERR: Could not find device interface: %08x\n", kr); (*iface)->Release(iface); continue; } DBG("AndroidDeviceAdded calling register_usb_transport\n"); register_usb_transport(handle, (serial[0] ? serial : NULL), 1); // Register for an interest notification of this device being removed. // Pass the reference to our private data as the refCon for the // notification. kr = IOServiceAddInterestNotification(notificationPort, usbInterface, kIOGeneralInterest, AndroidInterfaceNotify, handle, &handle->usbNotification); if (kIOReturnSuccess != kr) { DBG("ERR: Unable to create interest notification (%08x)\n", kr); } } }
static stDeviceListItem* GetSerialDevices() { kern_return_t kernResult = KERN_FAILURE; io_iterator_t serialPortIterator; char bsdPath[MAXPATHLEN]; kernResult = FindModems(&serialPortIterator); io_service_t modemService; kernResult = KERN_FAILURE; Boolean modemFound = false; // Initialize the returned path *bsdPath = '\0'; stDeviceListItem* devices = NULL; stDeviceListItem* lastDevice = NULL; int length = 0; while ((modemService = IOIteratorNext(serialPortIterator))) { CFTypeRef bsdPathAsCFString; bsdPathAsCFString = IORegistryEntrySearchCFProperty(modemService, kIOServicePlane, CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, kIORegistryIterateRecursively); if (bsdPathAsCFString) { Boolean result; // Convert the path from a CFString to a C (NUL-terminated) result = CFStringGetCString((CFStringRef) bsdPathAsCFString, bsdPath, sizeof(bsdPath), kCFStringEncodingUTF8); CFRelease(bsdPathAsCFString); if (result) { stDeviceListItem *deviceListItem = (stDeviceListItem*) malloc(sizeof(stDeviceListItem)); stSerialDevice *serialDevice = &(deviceListItem->value); strcpy(serialDevice->port, bsdPath); memset(serialDevice->locationId, 0, sizeof(serialDevice->locationId)); memset(serialDevice->vendorId, 0, sizeof(serialDevice->vendorId)); memset(serialDevice->productId, 0, sizeof(serialDevice->productId)); serialDevice->manufacturer[0] = '\0'; serialDevice->serialNumber[0] = '\0'; deviceListItem->next = NULL; deviceListItem->length = &length; if (devices == NULL) { devices = deviceListItem; } else { lastDevice->next = deviceListItem; } lastDevice = deviceListItem; length++; modemFound = true; kernResult = KERN_SUCCESS; uv_mutex_lock(&list_mutex); io_registry_entry_t device = GetUsbDevice(bsdPath); if (device) { CFStringRef manufacturerAsCFString = (CFStringRef) IORegistryEntrySearchCFProperty(device, kIOServicePlane, CFSTR(kUSBVendorString), kCFAllocatorDefault, kIORegistryIterateRecursively); if (manufacturerAsCFString) { Boolean result; char manufacturer[MAXPATHLEN]; // Convert from a CFString to a C (NUL-terminated) result = CFStringGetCString(manufacturerAsCFString, manufacturer, sizeof(manufacturer), kCFStringEncodingUTF8); if (result) { strcpy(serialDevice->manufacturer, manufacturer); } CFRelease(manufacturerAsCFString); } CFStringRef serialNumberAsCFString = (CFStringRef) IORegistryEntrySearchCFProperty(device, kIOServicePlane, CFSTR(kUSBSerialNumberString), kCFAllocatorDefault, kIORegistryIterateRecursively); if (serialNumberAsCFString) { Boolean result; char serialNumber[MAXPATHLEN]; // Convert from a CFString to a C (NUL-terminated) result = CFStringGetCString(serialNumberAsCFString, serialNumber, sizeof(serialNumber), kCFStringEncodingUTF8); if (result) { strcpy(serialDevice->serialNumber, serialNumber); } CFRelease(serialNumberAsCFString); } IOCFPlugInInterface **plugInInterface = NULL; SInt32 score; HRESULT res; IOUSBDeviceInterface **deviceInterface = NULL; kernResult = IOCreatePlugInInterfaceForService(device, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); if ((kIOReturnSuccess != kernResult) || !plugInInterface) { continue; } // Use the plugin interface to retrieve the device interface. res = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID*) &deviceInterface); // Now done with the plugin interface. (*plugInInterface)->Release(plugInInterface); if (res || deviceInterface == NULL) { continue; } // Extract the desired Information ExtractUsbInformation(serialDevice, deviceInterface); // Release the Interface (*deviceInterface)->Release(deviceInterface); // Release the device (void) IOObjectRelease(device); } uv_mutex_unlock(&list_mutex); } } // Release the io_service_t now that we are done with it. (void) IOObjectRelease(modemService); } IOObjectRelease(serialPortIterator); // Release the iterator. return devices; }
void RawDeviceAdded(void *refCon, io_iterator_t iterator) { kern_return_t kr; io_service_t usbDevice; IOCFPlugInInterface **plugInInterface = NULL; IOUSBDeviceInterface **dev = NULL; HRESULT result; SInt32 score; UInt16 vendor; UInt16 product; UInt16 release; while (usbDevice = IOIteratorNext(iterator)) { //Create an intermediate plug-in kr = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); //Don’t need the device object after intermediate plug-in is created kr = IOObjectRelease(usbDevice); if ((kIOReturnSuccess != kr) || !plugInInterface) { printf("Unable to create a plug-in (%08x)\n", kr); continue; } //Now create the device interface result = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID *)&dev); //Don’t need the intermediate plug-in after device interface //is created (*plugInInterface)->Release(plugInInterface); if (result || !dev) { printf("Couldn’t create a device interface (%08x)\n", (int) result); continue; } //Check these values for confirmation kr = (*dev)->GetDeviceVendor(dev, &vendor); kr = (*dev)->GetDeviceProduct(dev, &product); kr = (*dev)->GetDeviceReleaseNumber(dev, &release); if ((vendor != kOurVendorID) || (product != kOurProductID) || (release != 1)) { printf("Found unwanted device (vendor = %d, product = %d)\n", vendor, product); printf("(or the release was not equal to 1: release = %d)\n", release); (void) (*dev)->Release(dev); continue; } //Open the device to change its state kr = (*dev)->USBDeviceOpen(dev); if (kr != kIOReturnSuccess) { printf("Unable to open device: %08x\n", kr); (void) (*dev)->Release(dev); continue; } //Configure device kr = ConfigureDevice(dev); if (kr != kIOReturnSuccess) { printf("Unable to configure device: %08x\n", kr); (void) (*dev)->USBDeviceClose(dev); (void) (*dev)->Release(dev); continue; } /* //Download firmware to device kr = DownloadToDevice(dev); if (kr != kIOReturnSuccess) { printf("Unable to download firmware to device: %08x\n", kr); (void) (*dev)->USBDeviceClose(dev); (void) (*dev)->Release(dev); continue; } */ //Close this device and release object kr = (*dev)->USBDeviceClose(dev); kr = (*dev)->Release(dev); } }
/**************************************************************************** * darwin_getTOC: get the TOC ****************************************************************************/ static CDTOC *darwin_getTOC( vlc_object_t * p_this, const vcddev_t *p_vcddev ) { mach_port_t port; char *psz_devname; kern_return_t ret; CDTOC *pTOC = NULL; io_iterator_t iterator; io_registry_entry_t service; CFMutableDictionaryRef properties; CFDataRef data; /* get the device name */ if( ( psz_devname = strrchr( p_vcddev->psz_dev, '/') ) != NULL ) ++psz_devname; else psz_devname = p_vcddev->psz_dev; /* unraw the device name */ if( *psz_devname == 'r' ) ++psz_devname; /* get port for IOKit communication */ if( ( ret = IOMasterPort( MACH_PORT_NULL, &port ) ) != KERN_SUCCESS ) { msg_Err( p_this, "IOMasterPort: 0x%08x", ret ); return( NULL ); } /* get service iterator for the device */ if( ( ret = IOServiceGetMatchingServices( port, IOBSDNameMatching( port, 0, psz_devname ), &iterator ) ) != KERN_SUCCESS ) { msg_Err( p_this, "IOServiceGetMatchingServices: 0x%08x", ret ); return( NULL ); } /* first service */ service = IOIteratorNext( iterator ); IOObjectRelease( iterator ); /* search for kIOCDMediaClass */ while( service && !IOObjectConformsTo( service, kIOCDMediaClass ) ) { if( ( ret = IORegistryEntryGetParentIterator( service, kIOServicePlane, &iterator ) ) != KERN_SUCCESS ) { msg_Err( p_this, "IORegistryEntryGetParentIterator: 0x%08x", ret ); IOObjectRelease( service ); return( NULL ); } IOObjectRelease( service ); service = IOIteratorNext( iterator ); IOObjectRelease( iterator ); } if( !service ) { msg_Err( p_this, "search for kIOCDMediaClass came up empty" ); return( NULL ); } /* create a CF dictionary containing the TOC */ if( ( ret = IORegistryEntryCreateCFProperties( service, &properties, kCFAllocatorDefault, kNilOptions ) ) != KERN_SUCCESS ) { msg_Err( p_this, "IORegistryEntryCreateCFProperties: 0x%08x", ret ); IOObjectRelease( service ); return( NULL ); } /* get the TOC from the dictionary */ if( ( data = (CFDataRef) CFDictionaryGetValue( properties, CFSTR(kIOCDMediaTOCKey) ) ) != NULL ) { CFRange range; CFIndex buf_len; buf_len = CFDataGetLength( data ) + 1; range = CFRangeMake( 0, buf_len ); if( ( pTOC = malloc( buf_len ) ) != NULL ) { CFDataGetBytes( data, range, (u_char *)pTOC ); } } else { msg_Err( p_this, "CFDictionaryGetValue failed" ); } CFRelease( properties ); IOObjectRelease( service ); return( pTOC ); }
/** * Get the MAC address of the first logical IP-enabled network interface * * @param out the output character array * @return CPL_OK on success or an error code */ cpl_return_t cpl_platform_get_mac_address(cpl_mac_address_t* out) { #ifdef __unix__ // From: http://stackoverflow.com/questions/1779715/how-to-get-mac-address-of-your-machine-using-a-c-program ifreq ifr; ifconf ifc; char buf[1024]; int success = 0; int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); if (sock == -1) return CPL_E_PLATFORM_ERROR; ifc.ifc_len = sizeof(buf); ifc.ifc_buf = buf; if (ioctl(sock, SIOCGIFCONF, &ifc) == -1) return CPL_E_PLATFORM_ERROR; ifreq* it = ifc.ifc_req; const ifreq* const end = it + (ifc.ifc_len / sizeof(ifreq)); for (; it != end; ++it) { strcpy(ifr.ifr_name, it->ifr_name); if (ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) { if (! (ifr.ifr_flags & IFF_LOOPBACK)) { // don't count loopback if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) { success = 1; break; } } } else { /* ignore error */ } } if (success && out) { memcpy(out, ifr.ifr_hwaddr.sa_data, 6); } if (!success) return CPL_E_NOT_FOUND; #elif defined(__APPLE__) /* * Adapted from GetMACAddress.c: * http://opensource.apple.com/source/DirectoryService * /DirectoryService-621/CoreFramework/Private/GetMACAddress.c * * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. */ kern_return_t kernResult = KERN_FAILURE; mach_port_t masterPort = MACH_PORT_NULL; CFMutableDictionaryRef classesToMatch = NULL; io_object_t intfService = MACH_PORT_NULL; io_object_t controllerService = MACH_PORT_NULL; io_iterator_t intfIterator = MACH_PORT_NULL; unsigned char macAddress[kIOEthernetAddressSize]; io_iterator_t *matchingServices = &intfIterator; UInt8 *MACAddress = macAddress; // Create an iterator with Primary Ethernet interface kernResult = IOMasterPort(MACH_PORT_NULL, &masterPort); if (kernResult != KERN_SUCCESS) return CPL_E_PLATFORM_ERROR; // Ethernet interfaces are instances of class kIOEthernetInterfaceClass classesToMatch = IOServiceMatching(kIOEthernetInterfaceClass); if (classesToMatch != NULL) { CFMutableDictionaryRef propertyMatch; propertyMatch = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(propertyMatch, CFSTR(kIOPrimaryInterface), kCFBooleanTrue); CFDictionarySetValue(classesToMatch, CFSTR(kIOPropertyMatchKey), propertyMatch); CFRelease(propertyMatch); kernResult = IOServiceGetMatchingServices(masterPort, classesToMatch, matchingServices); } // Given an iterator across a set of Ethernet interfaces, return the // MAC address of the first one. intfService = IOIteratorNext(intfIterator); if (intfService == MACH_PORT_NULL) { IOObjectRelease(intfIterator); return CPL_E_PLATFORM_ERROR; } CFDataRef MACAddressAsCFData = NULL; kernResult = IORegistryEntryGetParentEntry(intfService, kIOServicePlane, &controllerService); if (kernResult != KERN_SUCCESS || controllerService == MACH_PORT_NULL) { IOObjectRelease(intfService); IOObjectRelease(intfIterator); return CPL_E_PLATFORM_ERROR; } MACAddressAsCFData = (CFDataRef) IORegistryEntryCreateCFProperty( controllerService, CFSTR(kIOMACAddress), kCFAllocatorDefault, 0); if (MACAddressAsCFData != NULL) { CFDataGetBytes(MACAddressAsCFData, CFRangeMake(0, kIOEthernetAddressSize), MACAddress); CFRelease(MACAddressAsCFData); } else { IOObjectRelease(controllerService); IOObjectRelease(intfService); IOObjectRelease(intfIterator); return CPL_E_NOT_FOUND; } IOObjectRelease(controllerService); IOObjectRelease(intfService); IOObjectRelease(intfIterator); if (out) memcpy(out, macAddress, 6); #elif defined(_WINDOWS) PIP_ADAPTER_ADDRESSES AdapterAddresses; ULONG family = AF_UNSPEC; ULONG flags = 0; ULONG outBufLen = 0; bool success = false; DWORD dwRetVal = GetAdaptersAddresses(family, flags, NULL, NULL, &outBufLen); if (dwRetVal == ERROR_NO_DATA) return CPL_E_NOT_FOUND; if (dwRetVal == 0 && outBufLen == 0) return CPL_E_NOT_FOUND; if (dwRetVal != ERROR_BUFFER_OVERFLOW) return CPL_E_PLATFORM_ERROR; AdapterAddresses = (IP_ADAPTER_ADDRESSES*) malloc(sizeof(IP_ADAPTER_ADDRESSES) * outBufLen); if (AdapterAddresses == NULL) return CPL_E_INSUFFICIENT_RESOURCES; dwRetVal = GetAdaptersAddresses(family, flags, NULL, AdapterAddresses, &outBufLen); if (dwRetVal != 0) { free(AdapterAddresses); return CPL_E_PLATFORM_ERROR; } for (PIP_ADAPTER_ADDRESSES p = AdapterAddresses; p != NULL; p = p->Next) { if (p->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue; if (p->PhysicalAddressLength != 6 /* Ethernet */) continue; success = true; if (out) memcpy(out, p->PhysicalAddress, 6); break; } free(AdapterAddresses); if (!success) return CPL_E_NOT_FOUND; #else #error "Not implemented for this platform" #endif return CPL_OK; }