Jak świstak wskazuje obecnie, IORegistry
jest rzeczywiście iść do źródłem wszystkich rzeczy związanych z urządzeniem. Dokumenty IOKit
są bardzo szczegółowe i pomocne; powinieneś zacząć od IOKit Fundamentals, następnie naciśnij Accessing Hardware from Applications, a następnie sprawdź na Device File Access Guide for Storage Devices, jeśli chcesz uzyskać informacje na temat BSD.
W tym przypadku można sprawić, aby struktura Dysk Arbitrażowa wykonywała niektóre z ciężkich zadań związanych z rejestrowaniem rejestru IO i rejestrowaniem powiadomień. Pozwala to zaoszczędzić sporo kodu, ale aby zrobić wszystko, co chcesz, musisz ostatecznie użyć funkcji IOKit
z bazowym obiektem IOMedia
(patrz).
Można łatwo napisać opakowanie kakao wokół obiektów IOMedia
reprezentujących dyski w rejestrze IO, a następnie użyć kontrolerów obiektów do powiązania właściwości z interfejsem użytkownika.
Oto przykład z rejestracji powiadomień wyglądu dysku poprzez ramach Disk Arbitrażowego na dobry początek:
// gcc -Wall -framework Foundation -framework DiskArbitration disk_arbiter.m -o disk_arbiter
/* @file disk_arbiter.m
* @author Jeremy W. Sherman
* @date 2009-10-03
*
* Demonstrates registering for disk appeared notifications from
* the DiskArbitration framework.
*
* Note that disk appeared notifications are delivered for all
* already-appeared disks at the time of registration, and then
* trickle in as the events actually happen thereafter.
*/
#import <Foundation/Foundation.h>
#import <DiskArbitration/DiskArbitration.h>
#import <signal.h>
sig_atomic_t sShouldExit = 0;
static void RegisterInterruptHandler(void);
static void HandleInterrupt(int);
static void OnDiskAppeared(DADiskRef disk, void *__attribute__((__unused__)));
int
main(void) {
CFStringRef const kDARunLoopMode = kCFRunLoopDefaultMode;
RegisterInterruptHandler();
// Set up session.
DASessionRef session = DASessionCreate(kCFAllocatorDefault);
DARegisterDiskAppearedCallback(session, NULL/*all disks*/, OnDiskAppeared, (void *)NULL);
DASessionScheduleWithRunLoop(session, CFRunLoopGetCurrent(), kDARunLoopMode);
// Run event loop.
printf("Starting...\n(Press Ctrl-C to exit.)\n\n");
const Boolean kAndReturnAfterHandlingSource = TRUE;
const CFTimeInterval kForOneSecond = 1.0;
while (!sShouldExit)
(void)CFRunLoopRunInMode(kCFRunLoopDefaultMode,
kForOneSecond, kAndReturnAfterHandlingSource);
// Tear down and exit.
printf("\nExiting...\n");
DASessionUnscheduleFromRunLoop(session, CFRunLoopGetCurrent(), kDARunLoopMode);
CFRelease(session);
exit(EXIT_SUCCESS);
return EXIT_SUCCESS;
}
static void
RegisterInterruptHandler(void) {
struct sigaction sigact;
sigact.sa_handler = HandleInterrupt;
(void)sigaction(SIGINT, &sigact, NULL/*discard previous handler*/);
}
static void
HandleInterrupt(int __attribute__((__unused__)) signo) {
sShouldExit = 1;
RegisterInterruptHandler();
}
static void
OnDiskAppeared(DADiskRef disk, void *__attribute__((__unused__)) ctx) {
printf("Lo, a disk appears!\n");
CFShow(disk);
}
A oto wyjście z przebiegu próby:
$ ./disk_arbiter
Starting...
(Press Ctrl-C to exit.)
Lo, a disk appears!
<DADisk 0x104f80 [0xa01c01a0]>{id = /dev/disk3}
Lo, a disk appears!
<DADisk 0x105b40 [0xa01c01a0]>{id = /dev/disk2s1}
Lo, a disk appears!
<DADisk 0x105ae0 [0xa01c01a0]>{id = /dev/disk2s2}
Lo, a disk appears!
<DADisk 0x105b60 [0xa01c01a0]>{id = /dev/disk2}
Lo, a disk appears!
<DADisk 0x105950 [0xa01c01a0]>{id = /dev/disk1}
Lo, a disk appears!
<DADisk 0x105bc0 [0xa01c01a0]>{id = /dev/disk1s1}
Lo, a disk appears!
<DADisk 0x105540 [0xa01c01a0]>{id = /dev/disk0}
Lo, a disk appears!
<DADisk 0x105660 [0xa01c01a0]>{id = /dev/disk0s1}
Lo, a disk appears!
<DADisk 0x1054a0 [0xa01c01a0]>{id = /dev/disk0s2}
^C
Exiting...
Przypuszczalnie jest to podobne do listy z 'mount'? Jeśli tak, to nie jestem pewien, czy to jest dokładnie to, o co prosiłem: będzie lista rzeczy takich jak 'devfs', podczas gdy Disk Utility wyświetla tylko" woluminy ", jak OS X odnosi się do nich .. może ..? Jednak prawdopodobnie zadziałałoby to, co chciałem, i zdecydowanie jest przydatna odpowiedź - dzięki! – dbr