我正在尝试使用磁盘仲裁框架获取所有可弹出磁盘的列表。问题是 Ejectable 属性总是假的(即使diskutil info
说Ejectable: Yes
)。这是怎么回事?我需要先做一个 DADiskClaim 吗?
- (NSArray *)disks {
NSMutableArray *disks = @[].mutableCopy;
// Get a list of everything in /Volumes/
NSArray *volumes = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:@"/Volumes/" error:NULL];
DASessionRef session = DASessionCreate(kCFAllocatorDefault);
// Use NSSet for easy object finding
NSMutableSet *bsdNamesOfDisks = @[].mutableCopy;
for (NSString *volume in volumes) {
// Create the URL for the volume mount point
NSURL *volumeURL = [NSURL URLWithString:[[NSString stringWithFormat:@"/Volumes/%@", volume] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
// Create DADisk for the volume
DADiskRef volumeDisk = DADiskCreateFromVolumePath(kCFAllocatorDefault, session, (__bridge CFURLRef)volumeURL);
// Filter out files/directories that aren't volumes
if (volumeDisk) {
// Get disk description
NSDictionary *description = (__bridge_transfer NSDictionary *)DADiskCopyDescription(volumeDisk);
// Get BSD name and ejectable property
NSString *bsdName = description[(__bridge id)kDADiskDescriptionMediaBSDNameKey];
CFBooleanRef ejectable = (__bridge CFBooleanRef)description[(__bridge id)kDADiskDescriptionMediaEjectableKey];
// Check to see if this is a volume we're interested in
if (bsdName && ejectable && CFBooleanGetValue(ejectable)) {
// Deletes "disk" in "disk0s1" and separates the numbers
NSArray *numbersInName = [[bsdName substringFromIndex:4] componentsSeparatedByCharactersInSet:[NSCharacterSet letterCharacterSet]];
// Scan the first number
NSScanner *scanner = [NSScanner scannerWithString:numbersInName[0]];
NSInteger diskNumber;
[scanner scanInteger:&diskNumber];
// Construct BSD name for the whole disk
NSString *bsdDiskName = [NSString stringWithFormat:@"disk%ld", diskNumber];
// Check to see if we already added this disk to our array (e.g. disk0s1 and disk0s2 both give disk0)
if (![bsdNamesOfDisks containsObject:bsdDiskName]) {
// Create DADisk for the whole disk
DADiskRef disk = DADiskCreateFromBSDName(kCFAllocatorDefault, session, bsdDiskName.UTF8String);
// Add DADisk to disk array and BSD name to name array
[disks addObject:(__bridge_transfer id)disk];
[bsdNamesOfDisks addObject:bsdDiskName];
}
}
CFRelease(volumeDisk);
}
}
CFRelease(session);
return disks.copy;
}