2014-11-01 84 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" 
     } 
    } 
} 
相關問題