Учитывая точку монтирования, могу ли я получить значения USB-производителя / продукта / серийного номера, используя IOKit?
Используя IOKit, я уже выяснил, как получить имя устройства BSD для точки монтирования, но тогда я не смог выяснить, как получить устройство USB с этим именем.
Я обнаружил, что могу перечислять устройства следующим образом (если код выглядит странно, это потому, что это Java):
int kr;
IOKit ioKit = IOKit.INSTANCE;
CoreFoundation coreFoundation = CoreFoundation.INSTANCE;
CFDictionary.CFMutableDictionaryRef matchingDict =
ioKit.IOServiceMatching(IOUSBLib.kIOUSBDeviceClassName);
if (matchingDict == null)
{
logger.error("Couldn't create a USB matching dictionary");
return null;
}
PointerByReference iterator = new PointerByReference();
kr = ioKit.IOServiceGetMatchingServices(null, matchingDict, iterator);
if (kr != IOReturn.kIOReturnSuccess)
{
logger.error(String.format("Couldn't enumerate devices: %08x", kr));
return null;
}
while (true)
{
Pointer device = ioKit.IOIteratorNext(iterator.getValue()); // returns an io_object_t
if (device == null)
{
break; // end of the iterator.
}
// do stuff with the device here
kr = ioKit.IOObjectRelease(usbRef);
if (kr != IOReturn.kIOReturnSuccess)
{
logger.warn(String.format("Couldn't release device object: %08x", kr));
}
}
Это возвращает много устройств, и ни у одного из них нет свойства BSD Name или чего-то похожего на него. Но устройство, которое я хочу , возвращается. Если я смотрю в System Profiler, я вижу устройство, на которое я нацеливаюсь, и там появляется BSD Name.
Как они это получают?
В качестве альтернативы, есть ли какой-нибудь способ обойти необходимость зацикливания этих вещей и просто напрямую перейти с устройства BSD на устройство USB?
1 ответ
Я думаю, что вам, вероятно, нужно проанализировать реестр ввода-вывода. Это можно сделать с помощью API-интерфейсов IOKit (например, путем перечисления USB-устройств, а затем с помощью IORegistryEntryGetChildIterator()) или путем анализа выходных данных команды консоли "ioreg".
Вы должны смотреть в плоскости реестра IOService. Один из подходов состоит в том, чтобы выполнить итерацию всех экземпляров класса IOUSBDevice (который будет предоставлять идентификаторы USB), а затем анализировать дочерние объекты, пока не найдете объект IOMedia, который описывает точку монтирования устройства. В качестве альтернативы, вы можете найти все объекты IOMedia, а затем выполнить итерацию вверх, чтобы найти объект, который имеет требуемый IOUSBDevice.
Иерархия довольно глубокая - на моей машине:
IOUSBDevice: IOUSBInterface: IOUSBInterface: IOSCSIDevicePeripheralDeviceNub: IOSCSIPeripheralDeviceType00: IOBlockStorageServices: IOBlockStorageDriver: IOMedia
(и есть также объекты IOFDiskPartitionScheme под IOMedia, которые описывают отдельные разделы на диске).
Команда ioreg, показывающая все это, - это "ioreg -l" или "ioreg -l -a", если вы хотите вывод в формате XML для более простого анализа.