2009-10-03 11 views
6

¿Hay alguna forma de enumerar las unidades disponibles, similar a la Utilidad de Discos, y obtener el dispositivo asociado /dev/rdisk* para ello?Listar todas las unidades/particiones, y obtener/dev/rdisc dispositivo con Cocoa

utilidad de disco tiene acceso a estos datos - cuando se selecciona una unidad y pulsa el botón de información, enumera ..

Partition Map Scheme : GUID Partition Table 
Disk Identifier : disk0 
Media Name : Hitachi HTS541612J9SA00 Media 

..o seleccionar una partición:

Disk Identifier : disk0s3 
Mount Point : /Volumes/BOOTCAMP 

¿Hay una Cocoa API para llegar a esto? Si es así, ¿cuál es la mejor manera de mostrar esto a través de Interface Builder?

Respuesta

9

Como marmota señala, el IORegistry es de hecho la fuente go-to para todas las cosas Relacionado con el aparato. Los documentos IOKit son muy detallados y útiles; Deberías comenzar con IOKit Fundamentals, luego presionar Accessing Hardware from Applications, y luego verificar Device File Access Guide for Storage Devices si deseas obtener información de la manera BSD.

En este caso, puede hacer que el marco de Arbitraje de disco realice una gran parte de la tarea de consultar el registro de IO y registrarse para recibir notificaciones. Esto ahorra una gran cantidad de código, pero para hacer todo lo que desea hacer, eventualmente necesitará usar las funciones IOKit con el objeto IOMedia subyacente (consulte DADiskCopyIOMedia()).

Puede escribir fácilmente un envoltorio de Cocoa alrededor de los objetos IOMedia que representan los discos en el registro de IO, y luego usar los controladores de objetos para vincular las propiedades a su UI.

He aquí un ejemplo de registro de notificaciones de apariencia disco a través del marco arbitraje de disco para empezar:

// 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); 
} 

Y aquí está la salida de un análisis de la muestra:

$ ./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... 
1

¿Por qué no:

#include <sys/mount.h> 

struct statfs *mntbufp; 
int num_of_mnts = 0; 
int i; 

/* get our mount infos */ 
num_of_mnts = getmntinfo(&mntbufp, MNT_WAIT); 
if(num_of_mnts == 0) /* no mounts returned, something is drastically wrong. */ 
{ 
    fprintf(stderr, "No mounts???\n"); 
    return false; 
} 
/* go though the mounts */ 
for(i = 0; i < num_of_mnts; i++) 
{ 
    fprintf(stdout, "[INFO Mount: %i (%s on %s)]\n", i, mntbufp[i].f_mntfromname, mntbufp[i].f_mntonname); 
} 
+0

Probablemente eso es similar a la lista de 'mount'? Si es así, no estoy seguro de que esto sea exactamente lo que buscaba: enumerará cosas como 'devfs', mientras que la Utilidad de disco solo enumera los" volúmenes "ya que OS X se refiere a ellos ... ¿quizás ...? Sin embargo, esto probablemente funcionaría para lo que yo quería, y definitivamente es una respuesta útil, ¡gracias! – dbr

Cuestiones relacionadas