2009-10-03 33 views
6

Có cách nào để liệt kê các ổ đĩa có sẵn, tương tự như Disk Utility và nhận thiết bị /dev/rdisk* được liên kết cho nó không?Liệt kê tất cả các ổ đĩa/phân vùng và nhận thiết bị/dev/rdisc với Cocoa

Disk Utility có quyền truy cập vào dữ liệu này - khi bạn chọn một ổ đĩa và nhấn nút Info, nó sẽ liệt kê ..

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

..or chọn một phân vùng:

Disk Identifier : disk0s3 
Mount Point : /Volumes/BOOTCAMP 

Có một API Cocoa để có được điều này? Nếu vậy, cách tốt nhất để hiển thị điều này thông qua Trình tạo giao diện là gì?

Trả lời

9

Như Groundhog chỉ ra, các IORegistry thực sự là đường đi đến nguồn cho tất cả mọi thứ thiết bị liên quan đến. Tài liệu IOKit rất chi tiết và hữu ích; bạn nên bắt đầu với IOKit Fundamentals, sau đó nhấn Accessing Hardware from Applications, sau đó cuối cùng kiểm tra Device File Access Guide for Storage Devices nếu bạn muốn nhận thông tin theo cách BSD.

Trong trường hợp này, bạn có thể làm cho khung Trọng tài đĩa thực hiện một số thao tác nâng truy vấn đăng ký IO và đăng ký thông báo. Điều này tiết kiệm rất nhiều mã, nhưng để làm tất cả mọi thứ bạn muốn làm, cuối cùng bạn sẽ cần phải sử dụng chức năng IOKit với đối tượng cơ bản IOMedia (xem DADiskCopyIOMedia()).

Bạn có thể dễ dàng viết vỏ bọc Cocoa quanh các đối tượng IOMedia đại diện cho các đĩa trong sổ đăng ký IO, sau đó sử dụng bộ điều khiển đối tượng để liên kết các thuộc tính với giao diện người dùng của bạn.

Dưới đây là một ví dụ về đăng ký thông báo đĩa xuất hiện thông qua các khuôn khổ đĩa Trọng tài để giúp bạn bắt đầu:

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

Và đây là kết quả từ một chạy mẫu:

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

Tại sao không chỉ:

#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

Có lẽ điều đó tương tự với danh sách từ 'núi'? Nếu vậy, không chắc chắn đây là chính xác những gì tôi đã sau: nó sẽ liệt kê những thứ như 'devfs', trong khi Disk Utility chỉ liệt kê" khối lượng "như OS X đề cập đến họ .. có lẽ ..? Tuy nhiên điều này có lẽ sẽ làm việc cho những gì tôi muốn, và chắc chắn là một câu trả lời hữu ích - cảm ơn! – dbr

Các vấn đề liên quan