Mac OS X: Comment obtenir un nom de volume (ou le nom bsd) à partir d'un IOUSBDeviceInterface ou l'identifiant de localisation
Question
Je suis en train d'écrire une application qui associe un descripteur de chaîne USB particulière (d'un périphérique de stockage de masse USB) avec son nom de volume ou bsd.
Ainsi, le code passe par tous les périphériques USB connectés, obtient les descripteurs de chaîne et extrait les informations d'un d'entre eux. Je voudrais obtenir le nom de volume de ces périphériques USB. Je ne peux pas trouver la bonne API pour le faire. J'ai essayé de le faire:
DASessionRef session = DASessionCreate(kCFAllocatorDefault);
DADiskRef disk_ref = DADiskCreateFromIOMedia(kCFAllocatorDefault,
session,
usb_device_ref);
const char* name = DADiskGetBSDName(disk_ref);
Mais la fonction DADiskCreateFromIOMedia est revenu nul, je suppose que je l'usb_device_ref passé était pas compatible avec la io_service_t que la fonction attend.
Alors, comment puis-je obtenir le nom de volume d'un périphérique USB?
Suis-je utiliser l'identifiant de l'emplacement pour le faire?
Merci pour la lecture. -L
FOO_Result result = FOO_SUCCESS;
mach_port_t master_port;
kern_return_t k_result;
io_iterator_t iterator = 0;
io_service_t usb_device_ref;
CFMutableDictionaryRef matching_dictionary = NULL;
// first create a master_port
if (FOO_FAILED(k_result = IOMasterPort(MACH_PORT_NULL, &master_port))) {
fprintf(stderr, "could not create master port, err = %d\n", k_result);
goto cleanup;
}
if ((matching_dictionary = IOServiceMatching(kIOUSBDeviceClassName)) == NULL)
{
fprintf(stderr, "could not create matching dictionary, err = %d\n", k_result);
goto cleanup;
}
if (FOO_FAILED(k_result = IOServiceGetMatchingServices(master_port, matching_dictionary, &iterator))) {
fprintf(stderr, "could not find any matching services, err = %d\n", k_result);
goto cleanup;
}
while (usb_device_ref = IOIteratorNext(iterator))
{
IOReturn err;
IOCFPlugInInterface **iodev; // requires <IOKit/IOCFPlugIn.h>
IOUSBDeviceInterface **dev;
SInt32 score;
err = IOCreatePlugInInterfaceForService(usb_device_ref, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &iodev, &score);
if (err || !iodev)
{
printf("dealWithDevice: unable to create plugin. ret = %08x, iodev = %p\n", err, iodev);
return;
}
err = (*iodev)->QueryInterface(iodev,
CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID),
(LPVOID*)&dev);
(*iodev)->Release(iodev); // done with this
FOO_String string_value;
UInt8 string_index = 0x1;
FOO_Result result = FOO_SUCCESS;
CFStringRef device_name_as_cf_string;
do {
if (FOO_SUCCEEDED(result = FOO_GetStringDescriptor(dev, string_index, 0, string_value))) {
printf("String at index %i is %s\n", string_index, string_value.GetChars());
// extract the command code if it is the FOO string
if (string_value.CompareN("FOO:", 4) == 0) {
FOO_Byte code = 0;
FOO_HexToByte(string_value.GetChars() + 4, code);
// Get other relevant information from the device
io_name_t device_name;
UInt32 location_id = 0;
// Get the USB device's name.
err = IORegistryEntryGetName(usb_device_ref, device_name);
device_name_as_cf_string = CFStringCreateWithCString(kCFAllocatorDefault, device_name,
kCFStringEncodingASCII);
err = (*dev)->GetLocationID(dev, &location_id);
// TODO: get volume or BSD name
// add the device to the list
break;
}
}
string_index++;
} while (FOO_SUCCEEDED(result));
err = (*dev)->USBDeviceClose(dev);
if (err)
{
printf("dealWithDevice: error closing device - %08x\n", err);
(*dev)->Release(dev);
return;
}
err = (*dev)->Release(dev);
if (err)
{
printf("dealWithDevice: error releasing device - %08x\n", err);
return;
}
IOObjectRelease(usb_device_ref); // no longer need this reference
}
La solution
Une fois que vous avez la io_service_t, vous pouvez récursif à travers le IORegistry pour trouver le nom BSD. Vous n'avez pas besoin de créer une interface réellement.
#import <IOKit/IOBSD.h>
CFStringRef bsdName = ( CFStringRef ) IORegistryEntrySearchCFProperty ( usbDevice,
kIOServicePlane,
CFSTR ( kIOBSDNameKey ),
kCFAllocatorDefault,
kIORegistryIterateRecursively );
Autres conseils
Voir aussi:
usbdevs - Les périphériques USB montés sur la liste et leurs chemins de volume sur Mac OS X