3

我正在尝试使用磁盘仲裁框架获取所有可弹出磁盘的列表。问题是 Ejectable 属性总是假的(即使diskutil infoEjectable: 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;
}
4

0 回答 0