2
votes

for example, i have a flash disk(KingStone Mass Storage), and only one partition , so when I plug it on mac. I'll see a Volume(it might be /Volumes/KingStone) was mounted automatically. we could see volume(/Volumes/Kingstone) is belong to the KingSton disk.

but now I pluged another disk, such as AData disk. and another volume was mounted. and how could I know which volume is belong to kingstone disk.(we could know which disk is kongston by VenderID).

now in code, we could know mounted volumes by call [[NSWorkspace sharedWorkspace] mountedRemovableMedia] OR [[NSFileManager defaultFileManager] mountedVolumeURLsInclud.....]

we could also know all usb device by using kIOUSBDeviceClassName with IOServiceMatching and IOServicesGetMatchingServices

even kIOMediaClassName with the two function we will know volume media,

we could determine every volume media belongs to which usb device by path.

but I don't know the mount point of volume media.

either something else useful.

sorry for my pool English.

1
use function getmntinfo() we'll get information like execute command 'mount' element f_mntonname and f_mntfromname in statfs f_mntfromname will be /dev/bsdname we could get bsdname be check the "BSD Name" property of object we get by using kIOMediaClassName so, I archive my goal though it might be some complex. - YuDenzel

1 Answers

1
votes

Another way.

Create a Matching Dictionary with kIOMediaClass

matchingDict = IOServiceMatching(kIOMediaClass);

if you only want to get removable storage volume set the dictionary with kIOMediaRemovableKey and kCFBooleanTrue

CFDictionarySetValue(matchingDict, CFSTR(kIOMediaRemovableKey), kCFBooleanTrue);

and getting matching service now,

IOServiceGetMatchingService(kIOMasterPortDefault, matchingDict, &iterator);

you can enumerate your device now.

while((removableMedia = IOteratorNext(iterator)))
{
    IORegistryEntryGetName(removableMedia, deviceName); 
    // and something else you can do   


    kr = IORegistryGetPath(removableMedia, kIOServicePlane, devicePath);
    // compare the path with path you get in device.
    // if one device's path is the substring of this media
    // we could simply think this media is belong to the device

    // you could get mount point by following code
    DASessionRef sessionRef = DASessionCreate(kCFAllocatorDefault);
    if (sessionRef) {
        DADiskRef diskRef - DADiskCreateFromIOMedia(kCFAllocatorDefault, sessionRef, removableMedia);
        if (diskRef) {
            CFDictionaryRef *diskProperty=DADisCopyDescription(diskRef);
            if (property) {
                NSURL *mountURL = [(NSDictionary*)property objectForKey:(NSString*)kDADiskDescriptionVolumePathKey];
                // mountURL or [mountURL path] is the mount point you want

                CFRelease(diskProperty);
            }
            CFRelease(diskRef);
        }
        CFRelease(sessionRef);
    }

    // don't forget to release
    IOObjectRelease(removableMedia);
}

and you could Observer mount/unmount event like below

[[[NSWorkSpace sharedWorkspace] notificationCenter] addObsever:self selector:@selector(volumeMounted:) name:NSWorkspaceDidMountNotification object:nil];
[[[NSWorkSpace sharedWorkspace] notificationCenter] addObsever:self selector:@selector(volumeUnmounted:) name:NSWorkspaceDidUnmountNotification object:nil];