【问题标题】:OSX: How to get a volume name (or bsd name) from a IOUSBDeviceInterface or location idOSX:如何从 IOUSBDeviceInterface 或位置 ID 获取卷名(或 bsd 名)
【发布时间】:2011-01-28 09:36:59
【问题描述】:

我正在尝试编写一个将特定 USB 字符串描述符(USB 大容量存储设备的)与其卷或 bsd 名称相关联的应用程序。

所以代码会遍历所有连接的 USB 设备,获取字符串描述符并从中提取信息。我想获取这些 USB 设备的卷名。我找不到合适的 API 来做到这一点。 我已经尝试过这样做:

DASessionRef session = DASessionCreate(kCFAllocatorDefault);
DADiskRef disk_ref = DADiskCreateFromIOMedia(kCFAllocatorDefault, 
                                             session,
                                             usb_device_ref);
const char* name = DADiskGetBSDName(disk_ref);

但是 DADiskCreateFromIOMedia 函数返回 nil,我假设我传递的 usb_device_ref 与函数期望的 io_service_t 不兼容。

那么如何获取 USB 设备的卷名呢?

我可以使用位置 ID 来执行此操作吗?

感谢阅读。 -L

FOO_Result              result = FOO_SUCCESS;
mach_port_t             master_port;
kern_return_t           k_result;
io_iterator_t           iterator = 0;
io_service_t            usb_device_ref;
CFMutableDictionaryRef  matching_dictionary = NULL; 

// first create a master_port
if (FOO_FAILED(k_result = IOMasterPort(MACH_PORT_NULL, &master_port))) {
    fprintf(stderr, "could not create master port, err = %d\n", k_result);
    goto cleanup;
}
if ((matching_dictionary = IOServiceMatching(kIOUSBDeviceClassName)) == NULL)
{
    fprintf(stderr, "could not create matching dictionary, err = %d\n", k_result);
    goto cleanup;
}
if (FOO_FAILED(k_result = IOServiceGetMatchingServices(master_port, matching_dictionary, &iterator))) {
    fprintf(stderr, "could not find any matching services, err = %d\n", k_result);
    goto cleanup;
}
while (usb_device_ref = IOIteratorNext(iterator))
{       
    IOReturn                        err;
    IOCFPlugInInterface             **iodev;        // requires <IOKit/IOCFPlugIn.h>
    IOUSBDeviceInterface            **dev;
    SInt32                          score;

    err = IOCreatePlugInInterfaceForService(usb_device_ref, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &iodev, &score);
    if (err || !iodev)
    {
        printf("dealWithDevice: unable to create plugin. ret = %08x, iodev = %p\n", err, iodev);
        return;
    }
    err = (*iodev)->QueryInterface(iodev, 
                                   CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), 
                                   (LPVOID*)&dev);
    (*iodev)->Release(iodev);               // done with this


    FOO_String string_value;
    UInt8 string_index = 0x1;
    FOO_Result result = FOO_SUCCESS;
    CFStringRef device_name_as_cf_string;
    do {
        if (FOO_SUCCEEDED(result = FOO_GetStringDescriptor(dev, string_index, 0, string_value))) {
            printf("String at index %i is %s\n", string_index, string_value.GetChars());
            // extract the command code if it is the FOO string
            if (string_value.CompareN("FOO:", 4) == 0) {
                FOO_Byte code = 0;
                FOO_HexToByte(string_value.GetChars() + 4, code);
                // Get other relevant information from the device
                io_name_t        device_name;
                UInt32           location_id = 0;

                // Get the USB device's name.
                err = IORegistryEntryGetName(usb_device_ref, device_name);
                device_name_as_cf_string = CFStringCreateWithCString(kCFAllocatorDefault, device_name, 
                                                                     kCFStringEncodingASCII); 

                err = (*dev)->GetLocationID(dev, &location_id);

                // TODO: get volume or BSD name 

                // add the device to the list

                break;
            }
        }
        string_index++;
    } while (FOO_SUCCEEDED(result));


    err = (*dev)->USBDeviceClose(dev);
    if (err)
    {
        printf("dealWithDevice: error closing device - %08x\n", err);
        (*dev)->Release(dev);
        return;
    }
    err = (*dev)->Release(dev);
    if (err)
    {
        printf("dealWithDevice: error releasing device - %08x\n", err);
        return;
    }

    IOObjectRelease(usb_device_ref);            // no longer need this reference
}

【问题讨论】:

    标签: macos usb iokit


    【解决方案1】:

    另见:

    usbdevs - 列出已安装的 USB 设备及其在 Mac OS X 上的卷路径

    https://gist.github.com/atr000/621561

    【讨论】:

      【解决方案2】:

      一旦有了 io_service_t,就可以通过 IORegistry 递归查找 BSD 名称。您不需要实际创建接口。

      #import <IOKit/IOBSD.h>
      
      CFStringRef bsdName = ( CFStringRef ) IORegistryEntrySearchCFProperty ( usbDevice,
                                                                             kIOServicePlane,
                                                                             CFSTR ( kIOBSDNameKey ),
                                                                             kCFAllocatorDefault,
                                                                             kIORegistryIterateRecursively );
      

      【讨论】:

      • 不确定这是否与 bsd 名称相同,但我得到的设备名称如下:io_name_t deviceName; IORegistryEntryGetName(usbDevice, deviceName);
      猜你喜欢
      • 2020-09-09
      • 1970-01-01
      • 2017-10-20
      • 2012-07-11
      • 2014-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-24
      相关资源
      最近更新 更多