【问题标题】:OSX: Workaround for getting BSD name of an IOUSBDeviceOSX:获取 IOUSBDevice 的 BSD 名称的解决方法
【发布时间】:2015-10-17 01:11:06
【问题描述】:

我们一直在使用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 注册表并查找我的特定设备。

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

【问题讨论】:

  • 你试过磁盘仲裁方法吗?
  • 看起来磁盘仲裁可以让我们识别何时连接了 USB 设备。知道它是否能够找到特定的 IO 服务 USB 设备条目吗?我们需要获取有关 USB 设备的特定属性,因此仅安装点是不够的。
  • 当你有一个 DADisk 对象时,你可以通过 DADiskCopyIOMedia 获得对其 IOMedia 对象的引用。从那里,你应该能够找到你需要的东西。

标签: macos iokit


【解决方案1】:

最近也遇到了这个问题。问题并没有从为我过滤 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
        );
}

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2017-08-28
  • 1970-01-01
  • 2022-10-23
  • 2011-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-09
相关资源
最近更新 更多