给定一个挂载点,我可以使用IOKit获取USB供应商/产品/串行值吗?

时间:2013-09-24 07:56:29

标签: 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名称确实出现在那里。

他们是如何得到的?

或者,有没有办法绕过这个东西并直接从BSD设备到USB设备?

1 个答案:

答案 0 :(得分:2)

我认为您可能需要解析IO注册表。这可以使用IOKit API(例如,通过枚举USB设备然后使用IORegistryEntryGetChildIterator())或通过解析“ioreg”控制台命令的输出来完成。

您需要查看“IOService”注册表平面。一种方法是迭代类IOUSBDevice的所有实例(将提供USB标识符),然后解析子对象,直到找到描述设备挂载点的IOMedia对象。或者,您可以找到所有IOMedia对象,然后向上迭代以查找具有所需IOUSBDevice的对象。

层次结构很深 - 在我的机器上:

IOUSBDevice:IOUSBInterface:IOUSBInterface:IOSCSIDevicePeripheralDeviceNub:IOSCSIPeripheralDeviceType00:IOBlockStorageServices:IOBlockStorageDriver:IOMedia

(IOMedia下面还有IOFDiskPartitionScheme对象描述了磁盘上的各个分区。)

显示所有这些的ioreg命令是“ioreg -l”或“ioreg -l -a”,如果您希望XML格式的输出更容易解析。