我正试图从USB设备BSD Name获取该设备的实际安装卷,例如设备有BSD名称" disk2"并使用BSD名称安装单个卷" disk2s1" at" / Volumes / USBSTICK"。
这是我到目前为止所做的事情。使用
NSNotificationCenter NSWorkspaceDidMountNotification
我检测到添加了驱动器的时间。然后我扫描所有USB设备并使用
IORegistryEntrySearchCFProperty kIOBSDNameKey
获取设备的BSD名称。
对于我的USB记忆棒,它会返回" disk2"。运行
system_profiler SPUSBDataTypesystem_profiler SPUSBDataType
显示
Product ID: 0x5607
Vendor ID: 0x03f0 (Hewlett Packard)
Serial Number: AA04012700008687
Speed: Up to 480 Mb/sec
Manufacturer: HP
Location ID: 0x14200000 / 25
Current Available (mA): 500
Current Required (mA): 500
Capacity: 16.04 GB (16,039,018,496 bytes)
Removable Media: Yes
Detachable Drive: Yes
BSD Name: disk2
Partition Map Type: MBR (Master Boot Record)
S.M.A.R.T. status: Not Supported
Volumes:
USBSTICK:
Capacity: 16.04 GB (16,037,879,808 bytes)
Available: 5.22 GB (5,224,095,744 bytes)
Writable: Yes
File System: MS-DOS FAT32
BSD Name: disk2s1
Mount Point: /Volumes/USBSTICK
Content: Windows_FAT_32
这是有道理的,因为单个USB设备可能有多个卷。
我假设我可以使用DiskArbitration来查找实际的卷,但是
DASessionRef session = DASessionCreate(NULL);
if (session)
{
DADiskRef disk = DADiskCreateFromBSDName(NULL,session,"disk2");
if (disk)
{
CFDictionaryRef dict = DADiskCopyDescription(disk);
if (dict)
总是返回一个NULL字典。
那么,如何从USB设备的BSD名称到该设备的实际安装卷?我想应该可以迭代所有卷,获取他们的BSD名称并检查它是否以字符串开头,例如上面的/ Volumes / USBSTICK是" disk2s1",但这很糟糕,如果有磁盘等等怎么办。
答案 0 :(得分:2)
使用IOBSDNameMatching找到解决方案将创建一个字典,以使服务与给定的BSD名称相匹配。然后可以搜索该服务的子节点以查找其BSD名称。 注意:这是我第一次在OSX上做任何事情。此外,由于bug,上面代码中的'dict'为NULL,但是该字典对此无用。
这里是一些没有错误检查等的减少代码。
CFMutableDictionaryRef matchingDict;
matchingDict = IOBSDNameMatching(kIOMasterPortDefault, 0, "disk2");
io_iterator_t itr;
// Might only ever be one service so, MatchingService could be used. No sure though
IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &itr);
io_object_t service;
while ((service = IOIteratorNext(itr)))
{
io_iterator_t children;
io_registry_entry_t child;
// Obtain the service's children.
IORegistryEntryGetChildIterator(service, kIOServicePlane, &children);
while ((child = IOIteratorNext(children)))
{
CFTypeRef name = IORegistryEntrySearchCFProperty(child,
kIOServicePlane,
CFSTR(kIOBSDNameKey),
kCFAllocatorDefault,
kIORegistryIterateRecursively);
if (name)
{
// Got child BSD Name e.g. "disk2s1"
}
}
}