通过IOUSBDeviceInterface245收集有关挂起的USB设备的信息

时间:2011-09-11 08:29:12

标签: macos usb iokit

我正试图通过IOUSBDeviceInterface245(来自Mac OS X上的IOKit)获取一些信息(例如产品名称):
代码#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);

此代码适用于所有正在运行的设备,但它不适用于暂停(“休眠”)
设备(product_name只是一个空白字符串)。

但是,如果我使用这段代码:
代码#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"]);
    }
  }

这对所有设备都有效(我不知道为什么)。

我尝试通过此代码唤醒已暂停的设备(使用代码#1):

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

但它什么都没改变。

  

我注意到的一件事 - 代码#1完全适用于所有属性   睡眠设备,除了字符串值(通过字符串获取)   指数)。

更新
所以,我的问题是如何取消暂停使用第一个代码块的设备
谢谢。

1 个答案:

答案 0 :(得分:1)

您无法从挂起的设备读取字符串(如代码#1),因为它是直接从设备读取的(因为它被挂起而无法响应)。要直接阅读这些内容,您需要先取消暂停设备(如果驱动程序暂停设置,这可能是一个坏主意,还记得要检查是否成功)

如果要读取标准字符串,请使用第二个代码块(读取已从设备中提取的属性)