Question

I'm trying to get some information (such a product name) via IOUSBDeviceInterface245 (from IOKit on Mac OS X):
Code #1

io_iterator_t iterator;
io_object_t   usb_device  
SInt32 score = 0;
kern_return_t kr = IOServiceGetMatchingServices(kIOMasterPortDefault,     
                                           IOServiceNameMatching("AppleUSBOHCI"),    
                                           &iterator);   
IOCFPlugInInterface     **plugin_interface = NULL; 
IOUSBDeviceInterface245 **usb_interface    = NULL;
// ...
// enumerate devices (usb_device = IOIteratorNext(iterator))
// ...
IOReturn return_code = IOCreatePlugInInterfaceForService(usb_device,  
                                                  kIOUSBDeviceUserClientTypeID, 
                                                  kIOCFPlugInInterfaceID,  
                                                  &plugin_interface,
                                                  &score);
HRESULT h_result = (*pluginInterface)->QueryInterface(pluginInterface,
                                  CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID245), 
                                  (LPVOID)&usb_interface);
IODestroyPlugInInterface(pluginInterface);

UInt8 product_string_index;
return_code = (*usb_interface)->USBGetProductStringIndex(usb_interface,  
                                                         &product_string_index);
// Next, getting a product string by string's index. To do so, we need to send  
// IOUSBDevRequest (with type "kUSBRqGetDescriptor") to the current USB-device.
// Code bellow - is a pseudocode:
char *product_name = malloc(128);
get_string_by_index(usb_interface, product_string_index, product_string, 128);

This code is working well for all working-now devices, but it doesn't working for suspended ("sleeping")
devices (product_name is just a blank string).

But, if I using this code:
Code #2

 CFMutableDictionaryRef child_properties = CFDictionaryCreateMutable(NULL, 0,  
                                                                NULL,NULL);
 kern_return_t kr;
 io_service_t io_service;
 // iterator = iterator for "AppleUSBOHCI" or "AppleUSBEHCI" services
 while((io_service = IOIteratorNext(iterator))) {      
    io_iterator_t   children_iterator;
    kernel_return = IORegistryEntryGetChildIterator(io_service, kIOServicePlane,  
                                                   &children_iterator);
    io_registry_entry_t child;
    while((child = IOIteratorNext(children_iterator))) {
      // Create a CFDictionary with usb-device's properties
      IORegistryEntryCreateCFProperties(child, &child_properties,  
                                        kCFAllocatorDefault, 
                                        kNilOptions);
      NSLog(@"%@",[(NSDictionary*)child_properties valueForKey:@"USB Product Name"]);
    }
  }

that's working for all devices at all (I don't know why).

I tried to wakeup a suspended devices by this code (using with the code #1):

(*usb_interface)->USBDeviceSuspend(usb_interface, false);

but it's changed nothing.

One thing that I noticed - the code #1 is fully working for all properties of sleeping devices, except string values (which getting by string's index).

UPDATE:
So, my question is how can I unsuspend a device for using with the first code block?
Thank you.

Was it helpful?

Solution

You can't read the string from a suspended device (as in code #1) as it is read directly from the device (which can't respond, as it is suspended). To read these directly, you will need to unsuspend the device first (which may be a bad idea if it was suspended by a driver, also, remember to check for success)

If you want to read the standard strings, use the second code block (which reads the properties, which were already fetched from the device)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top