Я не устаю ссылаться на книгу “
Сегодня я хочу продемонстрировать пример из книги, показывающий работу с Disk Arbitration (я надеюсь, что приводя пример, я способствую увеличению количества читателей этой книги; также я написал Amit Singh, автору книги с просьбой дать разрешение на использование на сайте его кода).
Подсистема Disk Arbitration управляет дисками и образами дисков. Она содержит демон
- обрабатывает подключенные к системе диски на предмет возможности монтирования разделов
- уведомляет клиентов, подписанных на нотификации, о появлении и исчезновении дисков и разделов
- выступает арбитром, разрешающим или запрещающим доступ к дискам
Ранее я описал, как можно отключить возможность подключения внешних USB-носителей, удаляя соответствующий модуль kext. Но более правильный метод основан как раз на взаимодействии с diskarbitrationd. Привожу пример из книги:
// dissent_mount.c #include#define OUT_ON_NULL(ptr, msg) \ if (!ptr) { fprintf(stderr, "%s\n", msg); goto out; } DADissenterRef mountApprovalCallback(DADiskRef disk, void *context) { // В ответ на любой запрос монтирования выдать запрет DADissenterRef dissenter = DADissenterCreate(kCFAllocatorDefault, kDAReturnNotPermitted, CFSTR("mount disallowed")); printf("%s: mount disallowed\n", DADiskGetBSDName(disk)); return dissenter; } int main(void) { DAApprovalSessionRef session = DAApprovalSessionCreate(kCFAllocatorDefault); OUT_ON_NULL(session, "failed to create Disk Arbitration session"); // Зарегистрировать callback-функцию, вызываемую при монтировании DARegisterDiskMountApprovalCallback(session, NULL, // matches all disk objects mountApprovalCallback, NULL); // context DAApprovalSessionScheduleWithRunLoop(session, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); // Программа работает 30 секунд, после чего производится выход CFRunLoopRunInMode(kCFRunLoopDefaultMode, 30 /* seconds */, false); DAApprovalSessionUnscheduleFromRunLoop(session, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); DAUnregisterApprovalCallback(session, mountApprovalCallback, NULL); out: if (session) CFRelease(session); exit(0); }
Компиляция:
$ gcc -Wall -o dissent_mount dissent_mount.c \ -framework DiskArbitration -framework CoreFoundation
Запуск:
$ ./dissent_mount disk3s2: mount disallowed disk3s2: mount disallowed
Программа запускается на 30 секунд и не даёт ничего смонтировать, пока она работает. Например, те же USB-диски подключить будет невозможно. В качестве развития программы можно выборочно анализировать тип подключаемых дисков, и, допустим, разрешать монтировать образы, но запрещать монтировать диски. Также можно запустить программу при старте системы, в итоге пользователи без административных прав не смогут её отключить.
Более жёсткий метод борьбы с монтированием приводится на
$ sudo launchctl unload \ /System/Library/LaunchDaemons/com.apple.diskarbitrationd.plist