Сопоставьте имя диска USB USB с фактическим подключенным накопителем (дисками) в OSX

Я пытаюсь перейти от имени BSD устройства USB к фактическому подключенному тому (ам) для этого устройства, например, устройство имеет имя BSD "disk2" и монтирует один том с именем BSD "disk2s1" в "/Volumes/USBSTICK".

Вот что я делал до сих пор. С помощью

NSNotificationCenter NSWorkspaceDidMountNotification

Я обнаруживаю, когда диск был добавлен. Затем я сканирую все USB-устройства и использую

IORegistryEntrySearchCFProperty kIOBSDNameKey

чтобы получить имя BSD устройства.

Для моей флешки это возвращает "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)

всегда возвращает пустой словарь.

Итак, как мне перейти от имени BSD для устройства USB к фактическому подключенному тому (ам) для этого устройства? Я предполагаю, что должна быть возможность пройти итерацию по всем томам, получить их имя BSD и проверить, начинается ли оно со строки, например, / Volumes / USBSTICK выше "disk2s1", но это хакерство и что, если есть диск20 и т. Д.

1 ответ

Найденное решение с использованием 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"
        }
    }
}
Другие вопросы по тегам