2009-10-03 4 views
6

Existe-t-il un moyen de répertorier les lecteurs disponibles, similaire à Utilitaire de disque, et d'obtenir le périphérique /dev/rdisk* correspondant?Répertorie tous les lecteurs/partitions et récupère le périphérique/dev/rdisc avec Cocoa

Utilitaire de disque a accès à ces données - lorsque vous sélectionnez un lecteur et appuyez sur le bouton Info, il énumère ..

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

..ou sélectionner une partition:

Disk Identifier : disk0s3 
Mount Point : /Volumes/BOOTCAMP 

est-il une API Cocoa pour y arriver? Si oui, quelle est la meilleure façon de l'afficher via Interface Builder?

Répondre

9

Comme le souligne la marmotte sur le IORegistry est en effet le feu à la source pour toutes les choses liées au dispositif. Les documents IOKit sont très détaillés et utiles; vous devriez commencer par IOKit Fundamentals, puis appuyez sur Accessing Hardware from Applications, puis enfin sur Device File Access Guide for Storage Devices si vous voulez obtenir des informations sur la façon BSD.

Dans ce cas, vous pouvez faire en sorte que l'infrastructure d'arbitrage de disque soulève un grand nombre de questions lors de l'interrogation du registre d'E/S et de l'enregistrement des notifications. Cela économise beaucoup de code, mais pour faire tout ce que vous voulez faire, vous devrez éventuellement utiliser les fonctions IOKit avec l'objet sous-jacent IOMedia (voir DADiskCopyIOMedia()).

Vous pouvez facilement écrire un wrapper Cocoa autour des objets IOMedia qui représentent les disques dans le registre IO, puis utilisez les contrôleurs d'objet pour lier les propriétés à votre interface utilisateur.

Voici un exemple d'enregistrement pour les notifications d'apparence de disque à travers le cadre d'arbitrage de disque pour vous aider à démarrer:

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

Et voici la sortie d'un échantillon analysé:

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

Pourquoi ne pas simplement:

#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

Vraisemblablement c'est similaire à la liste de 'mount'? Si c'est le cas, je ne suis pas sûr que ce soit exactement ce que je recherchais: ça va lister des choses comme 'devfs', alors que l'Utilitaire de disque ne liste que des" volumes "comme OS X s'y réfère ... peut-être ..? Cependant, cela fonctionnerait probablement pour ce que je voulais, et est certainement une réponse utile - merci! – dbr

Questions connexes