3

Optical disc device names (examle: /dev/disk4) are a bit weird on Mac OS X. Unlike on other OSs, they belong to the mounted media, not the drive so only exist when a disc is inserted. Additionally they are in no term stable. They can change already when anoter .dmg file is mounted before the next disc is inserted into the drive. On Windows drive letters are stable and linux has device names like /dev/cdrom or /dev/sr0 which are quite stable. Changes in hard discs, usb drives and packages have no effect on optical device names there.

I develop a C library working with audio CDs and would like to use the drive numbering exposed by drutil from C. drutil list lists all drives connected to the machine (with or without disc and gives them numbers. With drutil details -drive 1 I can then get the details for the first drive, including the (BSD) device name when a disc is in the drive. This would be perfect to set a prefered drive in the configuration or similar.

In C I wasn't able to list or index the drives without discs. So when I get the first inserted disc I don't know which drive this disc belongs to. I can get device names for inserted discs with the IOCDMediaClass. I do get a one drive listed with the IOCDBlockStorageDeviceClass (with or without a disc inserted), but I can't access the device name even when a disc is in the drive.

I prepared some example code that tries to list members of both classes and the device name if available.

The output without a disc in the drive:

detected media:
detected CD block devices:
drive 1:
        class name: IODVDServices

The output with a disc in the drive:

detected media:
drive 1:
        device name: disk4
        class name: IOCDMedia
detected CD block devices:
drive 1:
        class name: IODVDServices

PS: I know I can call drutil from C, but that would be a last resort.

4

1 回答 1

1

ioreg -r -c IODVDServices我使用( ioreg )找到了附加到 IODVDServices 的信息。相应的注册表项具有(大)子项,其中一个在驱动器中没有 CD 时属于 IODVDMedia 类型,当驱动器中有音频光盘时属于 IOCDMedia 类型(包括插入光盘时的设备名称)。

这些孩子可以通过以下方式访问IORegistryEntryCreateIterator()并测试为某个类IOObjectConformsTo()

static io_object_t get_media(io_object_t storageDevice)
{
    io_iterator_t childrenIterator;
    io_object_t nextChild;
    io_object_t mediaObject = 0;

    IORegistryEntryCreateIterator(storageDevice,
            kIOServicePlane, kIORegistryIterateRecursively,
            &childrenIterator);
    while ((nextChild = IOIteratorNext(childrenIterator))) {
        if (IOObjectConformsTo(nextChild, kIOCDMediaClass))
            mediaObject = nextChild;
        else
            IOObjectRelease(nextChild);
    }
    IOObjectRelease(childrenIterator);
    return mediaObject;
}

我推了一个完整的解决方案

这会尝试查找附加到 IOCDBlockStorageDeviceClass 特定驱动器的已安装媒体。查找该媒体的设备名称与问题中指定的方法和 Apple 提供的CDROMSample相同。


编辑:

你也可以在一个(递归)子级中使用任何 BSD 名称IORegistryEntrySearchCFProperty。不应该有其他具有设备名称的孩子,这样可以节省额外的迭代。

deviceFilePathAsCFString = IORegistryEntrySearchCFProperty(storageDevice,
                kIOServicePlane, CFSTR(kIOBSDNameKey),
                kCFAllocatorDefault, kIORegistryIterateRecursively);

用于 libdiscid 的实现

于 2013-07-31T16:55:52.467 回答