Thursday, September 25, 2014

DMG path from mount point on OS X

Getting the DMG file path for a mount point using Disk arbitration framework.

input CFURLRef volumePathRef;

//Create DADiskRef from a given volume
DASessionRef session = DASessionCreate(NULL);
DADiskRef diskRef = DADiskCreateFromVolumePath(kCFAllocatorDefault, session, volumePathRef);
DADiskRef wholeDiskRef = DADiskCopyWholeDisk(diskRef);
CFDictionaryRef wholeDiskDesc = DADiskCopyDescription(wholeDiskRef);

//Get device path
CFStringRef val = NULL;
if (CFDictionaryGetValueIfPresent(wholeDiskDesc, kDADiskDescriptionDevicePathKey, (const void**)&val))
{ 
    //Convert CFString to C-string
    CFStringRef devPathRef = (CFStringRef*)val;
    char devPath[1024];//Assuming 1024 max len, may need more, allocate dynamically.
    memset(devPath, 0, sizeof(devPath));
    CFRange range = CFRangeMake(0, CFStringGetLength(devPathRef));
    CFStringGetBytes(devPathRef, range, kCFStringEncodingUTF8, '?', FALSE, (UInt8 *)&devPath[0], 1024, NULL);


    io_registry_entry_t entry = IORegistryEntryFromPath(kIOMasterPortDefault, devPath);
    if (entry)
    {
        //Get Protocol Characteristics
        CFTypeRef ref = IORegistryEntryCreateCFProperty(entry, CFSTR(kIOPropertyProtocolCharacteristicsKey), kCFAllocatorDefault, 0);
        if (ref)
        {
            //Get DMG path
            CFDictionaryRef props = (CFDictionaryRef)ref;
            const void *val = NULL;
            if (CFDictionaryGetValueIfPresent(props, CFSTR("Virtual Interface Location Path"), &val))
            {
                const char*path = (const char*)CFDataGetBytePtr((CFDataRef)val);
                std::cout << "DMG Path " << path <<"\n";
            }
        }
    }
}

Note: CFRelease/free/delete allocated/copied resources.

No comments:

Post a Comment