2009-10-03 8 views
6

Gibt es eine Möglichkeit, verfügbare Laufwerke aufzulisten, ähnlich dem Festplatten-Dienstprogramm, und das zugehörige /dev/rdisk* Gerät dafür zu bekommen?Alle Laufwerke/Partitionen auflisten und/dev/rdisc-Gerät mit Cocoa

Disk Utility hat Zugriff auf diese Daten - wenn Sie ein Laufwerk und drücken Sie die Info-Taste wählen, listet es ..

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

..oder eine Partition:

Disk Identifier : disk0s3 
Mount Point : /Volumes/BOOTCAMP 

Gibt es eine Cocoa API, um das zu erreichen? Wenn ja, wie kann dies am besten über den Interface Builder angezeigt werden?

Antwort

9

Wie Murmeltier weist darauf hin, die IORegistry ist in der Tat die Go-to für alle Dinge beziehen gerätebezogenen. Die IOKit Dokumente sind sehr detailliert und hilfreich; Sie sollten mit IOKit Fundamentals starten, dann drücken Sie Accessing Hardware from Applications, dann überprüfen Sie schließlich Device File Access Guide for Storage Devices, wenn Sie Informationen auf dem BSD-Weg erhalten möchten.

In diesem Fall können Sie das Disk-Arbitration-Framework dazu bringen, die Abfrage der E/A-Registrierung und die Registrierung für Benachrichtigungen erheblich zu erschweren. Dies spart eine Menge Code, aber um alles zu tun, was Sie tun möchten, müssen Sie schließlich IOKit Funktionen mit dem zugrunde liegenden IOMedia Objekt verwenden (siehe DADiskCopyIOMedia()).

Sie könnten leicht einen Cocoa-Wrapper um die Objekte IOMedia schreiben, die die Datenträger in der IO-Registrierung darstellen, und dann mithilfe von Objektcontrollern Eigenschaften an Ihre Benutzeroberfläche binden.

Hier ist ein Beispiel für Platten Aussehen Benachrichtigungen durch den Disk-Arbitration Rahmen der Registrierung für den Einstieg: Und hier ist Ausgabe von einem Probelauf

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

:

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

Warum nicht einfach:

#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

Vermutlich ist das der Liste von 'mount' ähnlich? Wenn ja, bin ich mir nicht sicher, dass genau das der Fall ist, nach dem ich gesucht habe: Es werden Dinge wie 'devfs' aufgelistet, während das Festplatten-Dienstprogramm nur" Volumes "auflistet, wie OS X sie bezeichnet .. vielleicht ..? Aber das würde wahrscheinlich für das funktionieren, was ich wollte, und ist definitiv eine nützliche Antwort - danke! – dbr

Verwandte Themen