Skip to main content
1 of 2
user1118321
  • 11.8k
  • 1
  • 19
  • 46

There are 2 things missing from your code. As @Hanzaplastique mentioned, you need to wait for the callback to be executed. Secondly, you need to pass a valid queue to DASessionSetDispatchQueue(). If you pass NULL as in your code, you're telling it to unschedule the session.

You can use a dispatch_semaphore_t to wait between threads. Putting it all together, I get this:

#include <stdio.h>
#import <CoreFoundation/CoreFoundation.h>
#import <DiskArbitration/DiskArbitration.h>

static dispatch_semaphore_t semaphore;

void MountCallback(DADiskRef disk, DADissenterRef dissenter, void *context);

int main(int argc, const char *argv[]) {
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <disk>\n", argv[0]);
        return EXIT_FAILURE;
    }
    
    const char *deviceName = argv[1];
    
    // Create the semaphore we'll wait on.
    semaphore = dispatch_semaphore_create(0);
    
    DASessionRef session = DASessionCreate(kCFAllocatorDefault);
    DADiskRef disk = DADiskCreateFromBSDName(kCFAllocatorDefault, session, deviceName);
    
    // Pass NULL for a "standard" mount path.
    DADiskMount(disk, NULL, kDADiskMountOptionWhole, MountCallback, (void *)deviceName);
    
    // We'll pass the global concurrent queue here so it gets executed in the background
    DASessionSetDispatchQueue(session, dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0));
    CFRelease(session);
    session = NULL;
    
    // Wait for the callback to signal that it's done
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    // Clean up
    dispatch_release(semaphore);
    
    return EXIT_SUCCESS;
}

void MountCallback(DADiskRef disk, DADissenterRef dissenter, void *context) {
    const char *mountedDisk = context;
    fprintf(stderr, "Device mounted: %s\n", mountedDisk);
    fflush(stderr);

    // Tell the main thread that we've finished up.
    dispatch_semaphore_signal(semaphore);
    return;
}
user1118321
  • 11.8k
  • 1
  • 19
  • 46