Struggling with DiskArbitration

Discussion in 'Mac Programming' started by NSUser, May 9, 2013.

  1. NSUser macrumors newbie

    May 9, 2013
    In my app I use DiskArbitration.framework to mount and unmount local drives.
    The code to mount a volume looks like this:

                CFAllocatorRef allocator = kCFAllocatorDefault;
                DASessionRef session = DASessionCreate(kCFAllocatorDefault);
                const char *name = [openVolume.volId UTF8String]; // open volume is an object that stores volume information
                DADiskRef disk = DADiskCreateFromBSDName(allocator,
                DASessionScheduleWithRunLoop(session, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
                CFDictionaryRef diskDescription = DADiskCopyDescription(disk);
                NSDictionary *diskData = (NSDictionary *)diskDescription;
                BOOL mountable = [[diskData objectForKey:@"DAVolumeMountable"] boolValue];
                if (mountable) {
                    if (debug) {NSLog(@"Open volume %@ with id %@", openVolume.volName, openVolume.volId);}
                    NSURL *url = NULL;
                    if (![openVolume.volPath isEqualToString:openVolume.mountPath]) {
                        url = [NSURL URLWithString:[[openVolume.mountPath stringByExpandingTildeInPath] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
                        if (debug) {NSLog(@"Open volume at URL: %@", url);}
                                (CFURLRef) url,
                } // is mountable
                if (disk) {CFRelease(disk);}
                if (session) {CFRelease(session);
    and the code to umount a volume looks like this:
                CFAllocatorRef allocator = kCFAllocatorDefault;
                DASessionRef session = DASessionCreate(kCFAllocatorDefault);
                NSURL *url = [NSURL URLWithString:[unmountVolume.volPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
                NSLog(@"Unmount volume at URL: %@", url);
                DADiskRef disk = DADiskCreateFromVolumePath(
                                                            (CFURLRef) url );
                if (disk && debug) {NSLog(@"Got disk...");}
                if (disk) {
                    DASessionScheduleWithRunLoop(session, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
                    if (disk && debug) {NSLog(@"disk unmounted...");}
                if (session) {CFRelease(session);}
    Basically this works fine. The 'message' contains info for the callback functions to open a mounted or eject an unmounted volume, respectively.

    But after mounting and unmounting a local usb drive several (2-3) times, I get a DADissenterRef in the 'OnDiskMounted' callback that I can not resolve from the info in the documentation (

    DADissenterGetStatus(dissenter) = 49153 
    When I then attempt to mount the volume again, directly after sending DADiskMount(), I get a notice that the disk description changed (usually this callback is called after succesfull mount/unmount because the path changed).
    For some reason, the 'DAVolumeName' key and - sooner or later - even the 'DAVolumeUUID' key get copied from the startup disk. The info of the respective DADiskRef remains corrupted even after physically removing and reconnecting the usb drive. In, the wrong name (of the startup disk) is displayed in the sidebar, while the correct name is used when testing the volume. The Finder also displayes the correct name. After restarting the computer everything works fine again. Until I mount and unmount the volume...

    What am I doing wrong? Is there anything I need to do in the mount/unmount callbacks? Do I have to unschedule the DASession from the current run loop? And if so, how owuld I do that?
    Or do I need to claim the disk for mount/unmount?

    I'd really appreciate any advice! Thanks!
  2. NSUser thread starter macrumors newbie

    May 9, 2013
    Solved: I sent '/Volumes' as mountpath to DADiskMount...

Share This Page