使用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设备?
答案 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格式的输出更容易解析。