2014-11-01 99 views
2

我正试图从USB设备BSD名称获取该设备的实际安装体积,设备具有BSD名称“disk2”,并在“/ Volumes/USBSTICK”处安装带有BSD名称“disk2s1”的单个卷。将USB磁盘BSD名称映射到OSX中的实际安装驱动器

这是我迄今为止所做的。使用

NSNotificationCenter NSWorkspaceDidMountNotification 

我检测何时已添加驱动器。然后我扫描所有USB设备并使用

IORegistryEntrySearchCFProperty kIOBSDNameKey 

获取设备的BSD名称。

对于我的U盘,这返回“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”,但这是hacky,如果有一个磁盘20等。

回答

2

找到一个使用IOBSDNameMatching的解决方案将创建一个字典,以匹配服务与给定的BSD名称。然后可以搜索该服务的子女的BSD名称。 注意:这是我第一次在OSX上做任何事情。另外,上面的代码中的'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" 
     } 
    } 
} 
相关问题