Сопоставьте имя диска 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"
}
}
}