Учитывая точку монтирования, могу ли я получить значения 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 для более простого анализа.

Другие вопросы по тегам