Соберите информацию о приостановленных USB-устройствах через IOUSBDeviceInterface245 - PullRequest
0 голосов
/ 11 сентября 2011

Я пытаюсь получить некоторую информацию (например, название продукта) через IOUSBDeviceInterface245 (из IOKit в Mac OS X):
Код # 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 Ответ

1 голос
/ 11 сентября 2011

Вы не можете прочитать строку с приостановленного устройства (как в коде # 1), так как она читается непосредственно с устройства (которое не может ответить, так как оно приостановлено). Чтобы прочитать их напрямую, сначала необходимо отключить устройство (что может быть плохой идеей, если оно было приостановлено драйвером, также не забудьте проверить его на успешность)

Если вы хотите прочитать стандартные строки, используйте второй блок кода (который считывает свойства, которые уже были извлечены из устройства)

...