OSX:获取 IOUSBDevice 的 BSD 名称的解决方法

OSX: Workaround for getting BSD name of an IOUSBDevice

我们一直在使用 OSX: How to get a volume name (or bsd name) from a IOUSBDeviceInterface or location id 中描述的解决方案将 USB 设备从 IOKit 映射到其相应的 BSD 设备位置。代码是:

CFTypeRef name = IORegistryEntrySearchCFProperty(usbDevice,
                                                 kIOServicePlane,
                                                 CFSTR(kIOBSDNameKey),
                                                 kCFAllocatorDefault,
                                                 kIORegistryIterateRecursively);

由于测试版中引入的回归,此解决方案不再适用于 El Capitan。根据 https://forums.developer.apple.com/thread/7974 上的帖子,Apple 已确认该错误,但尚未发布修复程序,因此我需要一个解决方法。到目前为止,我所知道的唯一一个涉及从根目录解析整个 I/O 注册表并查找我的特定设备。

有人知道更简单的解决方法吗?

最近运行也遇到了这个问题。问题不是从为我过滤 bsdName 开始的,它实际上与首先从 USB 查询获取结果有关。事实证明,在 El Capitan 中,IOUSBDevice 有点被弃用,取而代之的是 IOUSBHostDevice。这是我为获得所需内容所做的工作:

// -- Begin Relevant Changes Part! ---
// Get current version
auto current_supported_version = __MAC_OS_X_VERSION_MAX_ALLOWED;
// El Capitan is 101100 (in AvailabilityInternal.h)
auto el_capitan = 101100;

// IOUSBDevice has become IOUSBHostDevice in El Capitan...
auto service_matcher = current_supported_version < el_capitan ? "IOUSBDevice" : "IOUSBHostDevice";

// Create matching dict to search
CFMutableDictionaryRef matchingDict = IOServiceMatching(service_matcher);
// -- End Relevant Changes Part! ---


// The rest of this is just example implementation code.
if (matchingDict == NULL)
{
   // IOServiceMatching Failed
}

// Fill it with other stuff if necessary (vendor id, etc...)

// Do actual search
io_iterator_t iter;
kern_return_t kr;
kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iter);
if (kr != KERN_SUCCESS)
{
    // IOServiceGetMatchingServices Failed
}

io_service_t service;
while ((service = IOIteratorNext(iter)))
{
    // Ought to work now, regardless of version of OSX being ran.
    CFStringRef bsdName = (CFStringRef) IORegistryEntrySearchCFProperty(
        service,
        kIOServicePlane,
        CFSTR(kIOBSDNameKey),
        kCFAllocatorDefault,
        kIORegistryIterateRecursively
        );
}