Collectez des informations sur les périphériques USB suspendus via iousbdeviceInterface245
Question
J'essaie d'obtenir des informations (un tel nom de produit) via IOUSBDeviceInterface245
(d'Iokit sur Mac OS X):
Code n ° 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);
Ce code fonctionne bien pour tous les appareils qui travaillent, mais cela ne fonctionne pas pour Suspended ("Sleeping")
dispositifs (product_name
est juste une chaîne vierge).
Mais, si j'utilise ce code:
Code n ° 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"]);
}
}
Cela fonctionne pour tous les appareils (je ne sais pas pourquoi).
J'ai essayé de réveiller un dispositif suspendu par ce code (en utilisant avec le code # 1):
(*usb_interface)->USBDeviceSuspend(usb_interface, false);
Mais ça n'a rien changé.
Une chose que j'ai remarquée - le code # 1 fonctionne pleinement pour toutes les propriétés des périphériques de sommeil, à l'exception des valeurs de chaîne (qui obtient par l'index de String).
METTRE À JOUR:
Donc, ma question est Comment puis-je mener un dispositif à utiliser avec le premier bloc de code?
Merci.
La solution
Vous ne pouvez pas lire la chaîne à partir d'un appareil suspendu (comme dans le code n ° 1) car il est lu directement à partir de l'appareil (qui ne peut pas répondre, car il est suspendu). Pour les lire directement, vous devrez d'abord insusiter l'appareil (ce qui peut être une mauvaise idée s'il a été suspendu par un conducteur, n'oubliez pas non plus de vérifier le succès)
Si vous souhaitez lire les chaînes standard, utilisez le deuxième bloc de code (qui lit les propriétés, qui ont déjà été récupérées à partir de l'appareil)