列出所有驱动器/分区,并使用Cocoa获取/ dev / rdisc设备

时间:2009-10-03 22:52:40

标签: cocoa api filesystems

是否有办法列出可用的驱动器,类似于“磁盘工具”,并获取相关的/dev/rdisk*设备?

“磁盘工具”可以访问此数据 - 当您选择驱动器并按“信息”按钮时,它会列出..

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

..或选择一个分区:

Disk Identifier : disk0s3
Mount Point : /Volumes/BOOTCAMP

是否有Cocoa API可以解决这个问题?如果是这样,通过Interface Builder显示它的最佳方法是什么?

3 个答案:

答案 0 :(得分:9)

正如土拨鼠所指出的那样,IORegistry确实是与设备相关的所有东西的首选来源。 IOKit文档非常详细且有用;你应该从IOKit Fundamentals开始,然后点击Accessing Hardware from Applications,然后最后查看Device File Access Guide for Storage Devices,如果你想获得BSD方式的信息。

在这种情况下,您可以使磁盘仲裁框架执行查询IO注册表和注册通知的繁重工作。这样可以节省大量代码,但是为了完成您想要做的所有事情,您最终需要将IOKit函数与基础IOMedia对象一起使用(请参阅DADiskCopyIOMedia())。

您可以在代表IO注册表中磁盘的IOMedia对象周围编写Cocoa包装器,然后使用对象控制器将属性绑定到UI。

以下是通过磁盘仲裁框架注册磁盘外观通知以帮助您入门的示例:

// 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 :(得分:3)

您最感兴趣的是IORegistry,其概念性地在IO Kit Fundamentals

中描述

答案 2 :(得分:1)

为什么不呢:

#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);
}
相关问题