From Objective C (or Swift), I need to determine if a mounted volume is a Disk Image (mounted from a .dmg file).
Similar questions led me to NSURL Volume Property Keys, but none of them seem to give the type/protocol of the volume.
However, I can see this information with the terminal diskutil
function under Protocol
:
~/Temp$ diskutil info /dev/disk8
Device Identifier: disk8
Device Node: /dev/disk8
Part of Whole: disk8
Device / Media Name: Apple UDIF read-only Media
Volume Name: Not applicable (no file system)
Mounted: Not applicable (no file system)
File System: None
Content (IOContent): GUID_partition_scheme
OS Can Be Installed: No
Media Type: Generic
Protocol: Disk Image <=== THIS IS WHAT I WANT
SMART Status: Not Supported
Total Size: 5.2 MB (5242880 Bytes) (exactly 10240 512-Byte-Units)
Volume Free Space: Not applicable (no file system)
Device Block Size: 512 Bytes
Read-Only Media: Yes
Read-Only Volume: Not applicable (no file system)
Ejectable: Yes
Whole: Yes
Internal: No
OS 9 Drivers: No
Low Level Format: Not supported
EDIT: Found some code that at least used to do this, by means of this included category extension to NSWorkspace. However, it is pre-ARC and I'm not sure if it would still work.
Found it via this partial answer on other question..
You can obtain this information using the DiskArbitration framework. To use the example below, you must link against and #import
it.
#import <DiskArbitration/DiskArbitration.h>
...
- (BOOL)isDMGVolumeAtURL:(NSURL *)url
{
BOOL isDMG = NO;
if (url.isFileURL) {
DASessionRef session = DASessionCreate(kCFAllocatorDefault);
if (session != nil) {
DADiskRef disk = DADiskCreateFromVolumePath(kCFAllocatorDefault, session, (__bridge CFURLRef)url);
if (disk != nil) {
NSDictionary * desc = CFBridgingRelease(DADiskCopyDescription(disk));
NSString * model = desc[(NSString *)kDADiskDescriptionDeviceModelKey];
isDMG = ([model isEqualToString:@"Disk Image"]);
CFRelease(disk);
}
CFRelease(session);
}
}
return isDMG;
}
Usage:
BOOL isDMG = [someObject isDMGVolumeAtURL:[NSURL fileURLWithPath:@"/Volumes/Some Volume"]];
I hope this helps.