Управление дисками и объемами
В дополнение к наблюдению за изменениями в объемах и отказе монтируют, размонтировали и извлекают вызовы, Дисковая Арбитражная платформа предоставляет возможность, чтобы получить различные данные об объеме, смонтировать и размонтировать объемы, и т.д. В этой главе описываются, как сделать это.
Получение дискового объекта
Прежде чем можно будет управлять диском или объемом, необходимо получить a DADiskRef объект для того диска или объема. Можно получить a DADiskRef объект четырьмя способами:
В качестве параметра переданный Вашему обратному вызову события (описанный в Использовании Дискового Арбитражного Уведомления и Обратных вызовов Утверждения)
От
io_service_tссылка пространства пользователя наIOMediaобъект для допустимой части устройства путем вызоваDADiskCreateFromIOMediaМожно получить
io_service_tссылка пространства пользователя наIOMediaобъект путем вызоваIOServiceGetMatchingServiceилиIOServiceGetMatchingServices. Для приобретения знаний о работе с Реестром I/O считайте Основные принципы IOKit.От имени устройства BSD (
disk1s1, например) использованиеDADiskCreateFromBSDNameОт точки монтирования путем вызова
DADiskCreateFromVolumePath
Если у Вас есть любой io_service_t возразите или имя устройства BSD, Ваше приложение может создать a DADiskRef объект следующим образом:
Создайте a
DASessionRefвозразите, как описано в Создании Сеанса.Запланируйте его, как описано в Планировании Сеанса с Очередью Цикла или Отгрузки Выполнения. Убедитесь, что работает Ваша очередь отгрузки или выполни цикл.
Создайте дисковые объекты.
Управляйте ими, как желаемый.
Получение информации о диске
Дисковый арбитраж обеспечивает три функции для получения дополнительной информации о дисках и разделах: DADiskCopyDescription, DADiskGetBSDName, и DADiskCopyIOMedia. Как правило можно получить почти любую информацию об определенном диске путем вызова DADiskCopyDescription. Для некоторых довольно тайных данных, однако, Вам, вероятно, придется получить IOMedia объект для диска и запроса тот объект.
Если Вам нужно имя устройства BSD диска или раздела (
disk1s1, например) как струна до (обычно используемый при работе с уровнем POSIX APIs), вызватьDADiskGetBSDName.Для большей части другой информации вызвать
DADiskCopyDescription, как описано в Получении Словаря Описания.Если информация через, в которой Вы нуждаетесь не доступна
DADiskCopyDescription, вызватьDADiskCopyIOMedia.
Получение словаря описания
DADiskCopyDescription метод возвращает a CFDictionaryRef объект, содержащий несколько дюжин данных о диске или разделе. Некоторые обычно используемые данные включают:
Точка монтирования и имя тома
Имя узла устройства BSD и главные и незначительные числа
Информация об аппаратных средствах (устройство ID, идентификатор поставщика, GUID, и т.д.)
Информация соединения (соединяют шиной имя и путь),
Можно найти полный список свойств в DADisk.h заголовок в Дисковой Арбитражной Платформе, вместе с описанием ожидаемых типов данных для значений каждого ключа.
Например, для печати пути точки монтирования для объема:
DADiskRef disk; |
CFDictionaryRef *diskinfo; |
... |
diskinfo = DADiskCopyDescription(disk); |
CFURLRef fspath = CFDictionaryGetValue(dict, |
kDADiskDescriptionVolumePathKey); |
char buf[MAXPATHLEN]; |
if (CFURLGetFileSystemRepresentation(fspath, false, (UInt8 *)buf, sizeof(buf))) { |
printf("Disk %s mounted at %s\n", |
DADiskGetBSDName(disk), |
buf); |
/* Print the complete dictionary for debugging. */ |
CFShow(diskinfo); |
} else { |
/* Something is *really* wrong. */ |
} |
Для полного списка ключей словаря посмотрите раздел Constants в Ссылке DADisk.h.
Получение дополнительной информации от набора I/O
В некоторых редких ситуациях Вы, возможно, должны получить дополнительную информацию о диске вне того, что доступно от Дискового Арбитража. Если Вы делаете, можно вызвать DADiskCopyIOMedia получить io_service_t объект, который является представлением пространства пользователя IOMedia объект. Можно управлять этим объектом так же, как Вы были бы любой объект Реестра I/O.
Например, можно получить Базовый словарь Основы со свойствами I/O Registry носителей путем вызова IORegistryEntryCreateCFProperties на полученном объекте.
Свойства в словаре Реестра I/O определяются в Платформе Набора I/O. Для получения дополнительной информации посмотрите Ссылку Платформы Набора I/O.
Монтирование и размонтирование объемов
Чтобы смонтировать или размонтировать объем, вызвать DADiskMount или DADiskUnmount. Если Вы заботитесь, были ли монтирование или размонтирование успешны, необходимо также обеспечить обратный вызов для обработки результата.
Также можно вызвать DADiskMountWithArguments если необходимо передать дополнительные опции mount команда. Эта команда берет завершенный нулем массив CFStringRef значения, каждое из которых становится параметром mount команда. Можно найти наиболее распространенные опции в странице руководства для mount. Для дополнительных параметров формата объема см. страницу руководства для определенных команд монтирования, такой как mount_hfs.
Для каждой из этих функций функция обратного вызова берет три параметра: a DADiskRef объект, a DADissenterRef объект и указатель контекста (передал в качестве параметра, когда Вы регистрируете обратный вызов). Если работа была успешна, объект инакомыслящего NULL. Иначе, это предоставляет информацию о том, почему работа перестала работать.
Например, следующий отрывок размонтировал объем:
void unmount_done(DADiskRef disk, |
DADissenterRef dissenter, |
void *context); |
... |
DADiskUnmount(disk, kDADiskUnmountOptionDefault, |
unmount_done, NULL); |
... |
void unmount_done(DADiskRef disk, |
DADissenterRef dissenter, |
void *context) |
{ |
if (dissenter) { |
/* Unmount failed. */ |
char buf[MAXPATHLEN]; |
if (CFURLGetFileSystemRepresentation(fspath, false, (UInt8 *)buf, sizeof(buf))) { |
fprintf(stderr, "Unmount failed (Error: 0x%x Reason: %s). Retrying.\n", |
DADissenterGetStatus(dissenter), |
buf); |
} else { |
/* Something is *really* wrong. */ |
} |
} else { |
/* Do something. */ |
} |
} |
Наиболее распространенные значения кода ошибки (ошибки, определенные для дискового арбитража), описаны в DAReturn перечисление. Однако эта функция может также потенциально возвратить любой другой код ошибки в mach_error_t пространство (ошибки UNIX, и т.д.).
Монтирование объема подобно за исключением того, что можно указать a CFURLRef объект с путем точки монтирования (или передача NULL смонтировать объем в стандартном расположении). Например:
unsigned char *mppath = "/mnt/mydisk"; |
path = CFURLCreateFromFileSystemRepresentation( |
kCFAllocatorDefault, |
mppath, |
strlen(mppath), |
true); |
DADiskMountWithArguments(disk, path, kDADiskMountOptionDefault, |
mount_complete_callback, NULL, |
NULL); |
Извлечение диска
Извлечение диска подобно размонтированию объема. Существует два основных отличия:
Можно извлечь только целый раздел диска (
/dev/disk0, например), не листовой раздел (/dev/disk0s3, например). Если Вы запускаете с листового раздела, необходимо сначала получить целый раздел диска, содержащий его.Необходимо размонтировать все объемы на диске прежде, чем извлечь его. Чтобы гарантировать, что все объемы размонтированы (если возможный), сначала вызовите
DADiskUnmount, передача целого раздела диска как дисковый параметр и установкаkDADiskUnmountOptionWholeфлаг в опциях размонтирования.
Для получения целого раздела диска, содержащего данный листовой раздел использовать DADiskCopyWholeDisk. Например:
DADiskRef wholedisk = DADiskCopyWholeDisk(disk); |
Следующий отрывок, данный a DADiskRef объект связался с единственным разделом (вызванный partition), размонтировал все объемы на базовом диске, затем извлекает диск:
void unmount_done(DADiskRef disk, |
DADissenterRef dissenter, |
void *context); |
void eject_done(DADiskRef disk, |
DADissenterRef dissenter, |
void *context); |
... |
/* Unmount all volumes */ |
DADiskRef wholedisk = DADiskCopyWholeDisk(partition); |
DADiskUnmount(wholedisk, kDADiskUnmountOptionWhole, |
unmount_done, NULL); |
CFRelease(wholedisk); |
... |
/* In the unmount callback, eject the volume. */ |
void unmount_done(DADiskRef disk, |
DADissenterRef dissenter, |
void *context) |
{ |
if (dissenter) { |
... |
} else { |
DADiskEject(disk, kDADiskEjectOptionDefault, |
eject_done, NULL); |
} |
} |
/* Eject callback. */ |
void eject_done(DADiskRef disk, |
DADissenterRef dissenter, |
void *context) |
{ |
if (dissenter) { |
... |
} else { |
... |
} |
} |