Exemple #1
0
/** @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;
}
Exemple #3
0
/* 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;
}
Exemple #4
0
/** 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;
}
Exemple #6
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;
}
Exemple #9
0
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 */
}
Exemple #10
0
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);
}
Exemple #11
0
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);

	}
Exemple #13
0
/** 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;
}
Exemple #14
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;
}
Exemple #15
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();
}
Exemple #17
0
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;
}
Exemple #19
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;
}
Exemple #20
0
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;
}
Exemple #21
0
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;
}
Exemple #23
0
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);
    }
}
Exemple #24
0
/****************************************************************************
 * 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;
}