static int iokit_unmount (MMCDEV *mmc) { if (0 == mmc->is_mounted) { return 0; /* nothing to do */ } BD_DEBUG(DBG_MMC, "Unmounting disk\n"); mmc->session = DASessionCreate (kCFAllocatorDefault); if (NULL == mmc->session) { BD_DEBUG(DBG_MMC, "Could not create a disc arbitration session\n"); return -1; } mmc->disk = DADiskCreateFromBSDName (kCFAllocatorDefault, mmc->session, mmc->bsd_name); if (NULL == mmc->disk) { BD_DEBUG(DBG_MMC, "Could not create a disc arbitration disc for the device\n"); CFRelease (mmc->session); mmc->session = NULL; return -1; } DAApprovalSessionScheduleWithRunLoop (mmc->session, CFRunLoopGetCurrent (), kCFRunLoopDefaultMode); DADiskUnmount (mmc->disk, kDADiskUnmountOptionForce, iokit_unmount_complete, mmc); CFRunLoopRunInMode (kCFRunLoopDefaultMode, 10, true); return mmc->is_mounted ? -1 : 0; }
int main(int argc, const char *argv[]) { int argi; bool useConsole; for (argi = 1; argi < argc && argv[argi][0] == '-'; argi++) { if (!strcmp(argv[argi], "-quiet")) { quiet = true; } else { fprintf(stderr, "unknown parameter `%s'\n", argv[argi]); } } signal(SIGHUP, signal_handler); signal(SIGTERM, signal_handler); signal(SIGINT, signal_handler); signal(SIGQUIT, signal_handler); DAApprovalSessionRef session = DAApprovalSessionCreate(kCFAllocatorDefault); if (!session) { fprintf(stderr, "failed to create Disk Arbitration session\n"); } else if (argc - argi <= 0) { fprintf(stderr, "usage: %s [-quiet] <name> ...\n", argv[0]); } else { CFStringRef cfStringNames[argc - argi]; if(!quiet) fprintf(stderr, "blocking:\n"); for(nameCount = 0; nameCount < argc - argi; nameCount++) { if(!quiet) fprintf(stderr, "(%d) `%s'\n", nameCount + 1, argv[nameCount + argi]); cfStringNames[nameCount] = CFStringCreateWithCStringNoCopy(NULL, argv[nameCount + argi], kCFStringEncodingUTF8, kCFAllocatorNull); } names = cfStringNames; DARegisterDiskMountApprovalCallback(session, NULL, BlockMount, NULL); DAApprovalSessionScheduleWithRunLoop(session, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); while (run) { CFRunLoopRun(); } DAApprovalSessionUnscheduleFromRunLoop(session, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); DAUnregisterApprovalCallback(session, BlockMount, NULL); CFRelease(session); } return 0; }