18 #include <IOKit/IOKitLib.h>
19 #include <IOKit/storage/IOMedia.h>
20 #include <IOKit/storage/IOCDMedia.h>
21 #include <IOKit/storage/IODVDMedia.h>
22 #include <IOKit/storage/IOBlockStorageDevice.h>
23 #include <IOKit/storage/IOStorageDeviceCharacteristics.h>
24 #include <IOKit/storage/IOStorageProtocolCharacteristics.h>
25 #include <DiskArbitration/DiskArbitration.h>
33 CFArrayRef keys,
void *context);
44 kern_return_t kernResult;
47 QString msg = QString(
"FindMediaType() - ");
50 kernResult = IORegistryEntryCreateIterator(service,
52 kIORegistryIterateRecursively
53 | kIORegistryIterateParents,
56 if (KERN_SUCCESS != kernResult)
58 LOG(VB_GENERAL, LOG_CRIT, msg +
59 QString(
"IORegistryEntryCreateIterator returned %1")
64 LOG(VB_GENERAL, LOG_CRIT, msg +
65 "IORegistryEntryCreateIterator returned NULL iterator");
71 IOObjectRetain(service);
75 bool isWholeMedia =
false;
76 if (IOObjectConformsTo(service, kIOMediaClass))
80 wholeMedia = IORegistryEntryCreateCFProperty
81 (service, CFSTR(kIOMediaWholeKey),
82 kCFAllocatorDefault, 0);
86 LOG(VB_GENERAL, LOG_ALERT, msg +
87 "Could not retrieve Whole property");
91 isWholeMedia = CFBooleanGetValue((CFBooleanRef)wholeMedia);
92 CFRelease(wholeMedia);
98 if (IOObjectConformsTo(service, kIODVDMediaClass))
100 else if (IOObjectConformsTo(service, kIOCDMediaClass))
104 IOObjectRelease(service);
106 }
while ((service = IOIteratorNext(iter))
109 IOObjectRelease(iter);
119 CFMutableDictionaryRef matchingDict;
120 kern_return_t kernResult;
122 io_service_t service;
123 QString msg = QString(
"MediaTypeForBSDName(%1)")
128 if (!bsdName || !*bsdName)
130 LOG(VB_GENERAL, LOG_ALERT, msg +
" - No name supplied?");
134 matchingDict = IOBSDNameMatching(
sMasterPort, 0, bsdName);
137 LOG(VB_GENERAL, LOG_ALERT,
138 msg +
" - IOBSDNameMatching() returned a NULL dictionary.");
144 kernResult = IOServiceGetMatchingServices(
sMasterPort, matchingDict, &iter);
146 if (KERN_SUCCESS != kernResult)
148 LOG(VB_GENERAL, LOG_ALERT,
149 QString(msg +
" - IOServiceGetMatchingServices() returned %2")
155 LOG(VB_GENERAL, LOG_ALERT,
156 msg +
" - IOServiceGetMatchingServices() returned a NULL "
161 service = IOIteratorNext(iter);
165 IOObjectRelease(iter);
169 LOG(VB_GENERAL, LOG_ALERT,
170 msg +
" - IOIteratorNext() returned a NULL iterator");
174 IOObjectRelease(service);
189 CFDictionaryGetValue(diskDetails, kDADiskDescriptionVolumeNameKey);
194 size = CFStringGetLength(name) + 1;
195 volName = (
char *) malloc(size);
198 LOG(VB_GENERAL, LOG_ALERT,
199 QString(
"getVolName() - Can't malloc(%1)?").arg(size));
203 if (!CFStringGetCString(name, volName, size, kCFStringEncodingUTF8))
215 static QString
getModel(CFDictionaryRef diskDetails)
221 if (kCFBooleanTrue ==
222 CFDictionaryGetValue(diskDetails,
223 kDADiskDescriptionDeviceInternalKey))
224 desc.append(
"Internal ");
227 strRef = CFDictionaryGetValue(diskDetails,
228 kDADiskDescriptionDeviceVendorKey);
231 desc.append(CFStringGetCStringPtr((CFStringRef)strRef,
232 kCFStringEncodingMacRoman));
237 strRef = CFDictionaryGetValue(diskDetails,
238 kDADiskDescriptionDeviceModelKey);
241 desc.append(CFStringGetCStringPtr((CFStringRef)strRef,
242 kCFStringEncodingMacRoman));
247 desc.truncate(desc.length() - 1);
263 const char *BSDname = DADiskGetBSDName(disk);
264 CFDictionaryRef details;
269 QString msg =
"diskAppearedCallback() - ";
275 LOG(VB_MEDIA, LOG_INFO, msg +
"Skipping non-local device");
281 LOG(VB_GENERAL, LOG_ALERT, msg +
"Error. Invoked with a NULL context.");
293 details = DADiskCopyDescription(disk);
295 if (kCFBooleanFalse ==
296 CFDictionaryGetValue(details, kDADiskDescriptionMediaRemovableKey))
298 LOG(VB_MEDIA, LOG_INFO, msg + QString(
"Skipping non-removable %1")
308 LOG(VB_MEDIA, LOG_INFO, msg + QString(
"No volume name for dev %1")
316 if (model.contains(
"Disk Image"))
318 LOG(VB_MEDIA, LOG_INFO, msg + QString(
"DMG %1 mounted, ignoring")
332 LOG(VB_MEDIA, LOG_INFO, QString(
"Found disk %1 - volume name '%2'.")
333 .arg(BSDname).arg(volName));
335 mtd->
diskInsert(BSDname, volName, model, isCDorDVD);
343 const char *BSDname = DADiskGetBSDName(disk);
351 if (CFArrayContainsValue(keys, CFRangeMake(0, CFArrayGetCount(keys)),
352 kDADiskDescriptionVolumeNameKey))
354 const char *BSDname = DADiskGetBSDName(disk);
355 CFDictionaryRef details = DADiskCopyDescription(disk);
358 LOG(VB_MEDIA, LOG_INFO, QString(
"Disk %1 - changed name to '%2'.")
359 .arg(BSDname).arg(volName));
362 ->diskRename(BSDname, volName);
375 CFDictionaryRef match = kDADiskDescriptionMatchVolumeMountable;
376 DASessionRef daSession = DASessionCreate(kCFAllocatorDefault);
380 DARegisterDiskAppearedCallback(daSession, match,
382 DARegisterDiskDisappearedCallback(daSession, match,
384 DARegisterDiskDescriptionChangedCallback(daSession, match,
385 kDADiskDescriptionWatchVolumeName,
388 DASessionScheduleWithRunLoop(daSession,
389 CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
398 CFRunLoopRunInMode(kCFRunLoopDefaultMode,
405 CFRelease(daSession);
417 QString model,
bool isCDorDVD)
420 QString msg =
"MonitorThreadDarwin::diskInsert";
422 LOG(VB_MEDIA, LOG_DEBUG, msg + QString(
"(%1,%2,'%3',%4)")
423 .arg(devName).arg(volName).arg(model).arg(isCDorDVD));
432 LOG(VB_GENERAL, LOG_ALERT, msg +
"Couldn't create MythMediaDevice.");
441 QString mnt =
"/Volumes/"; mnt += volName;
448 LOG(VB_MEDIA, LOG_WARNING,
449 (msg +
"() - Waiting for mount '%1' to become stable.").arg(mnt));
450 usleep(std::chrono::microseconds(120000));
451 if ( ++attempts > 4 )
452 usleep(std::chrono::microseconds(200000));
456 LOG(VB_MEDIA, LOG_ALERT, msg +
"() - Giving up");
478 LOG(VB_MEDIA, LOG_DEBUG,
479 QString(
"MonitorThreadDarwin::diskRemove(%1)").arg(devName));
486 LOG(VB_MEDIA, LOG_INFO,
"Couldn't find MythMediaDevice: " + devName);
499 LOG(VB_MEDIA, LOG_DEBUG,
500 QString(
"MonitorThreadDarwin::diskRename(%1,%2)")
501 .arg(devName).arg(volName));
511 pDevice->
setMountPath((QString(
"/Volumes/") + volName).toLatin1());
519 LOG(VB_MEDIA, LOG_INFO,
520 QString(
"Couldn't find MythMediaDevice: %1").arg(devName));
544 qRegisterMetaType<MythMediaStatus>(
"MythMediaStatus");
546 LOG(VB_MEDIA, LOG_NOTICE,
"Starting MediaMonitor");
560 LOG(VB_GENERAL, LOG_ERR,
"MediaMonitor::AddDevice(null)");
590 CFMutableDictionaryRef props =
nullptr;
592 props = (CFMutableDictionaryRef) IORegistryEntrySearchCFProperty(drive, kIOServicePlane, CFSTR(kIOPropertyProtocolCharacteristicsKey), kCFAllocatorDefault, kIORegistryIterateParents | kIORegistryIterateRecursively);
596 const void *location = CFDictionaryGetValue(props, CFSTR(kIOPropertyPhysicalInterconnectLocationKey));
597 if (CFEqual(location, CFSTR(
"Internal")))
598 desc.append(
"Internal ");
601 props = (CFMutableDictionaryRef) IORegistryEntrySearchCFProperty(drive, kIOServicePlane, CFSTR(kIOPropertyDeviceCharacteristicsKey), kCFAllocatorDefault, kIORegistryIterateParents | kIORegistryIterateRecursively);
604 const void *product = CFDictionaryGetValue(props, CFSTR(kIOPropertyProductNameKey));
605 const void *vendor = CFDictionaryGetValue(props, CFSTR(kIOPropertyVendorNameKey));
608 desc.append(CFStringGetCStringPtr((CFStringRef)vendor, kCFStringEncodingMacRoman));
613 desc.append(CFStringGetCStringPtr((CFStringRef)product, kCFStringEncodingMacRoman));
619 desc.truncate(desc.length() - 1);
635 kern_return_t kernResult;
636 CFMutableDictionaryRef devices;
639 QString msg = QString(
"GetCDRomBlockDevices() - ");
642 devices = IOServiceMatching(kIOBlockStorageDeviceClass);
645 LOG(VB_GENERAL, LOG_ALERT, msg +
"No Storage Devices? Unlikely!");
650 kernResult = IOServiceGetMatchingServices(
sMasterPort, devices, &iter);
652 if (KERN_SUCCESS != kernResult)
654 LOG(VB_GENERAL, LOG_ALERT, msg +
655 QString(
"IORegistryEntryCreateIterator returned %1")
661 LOG(VB_GENERAL, LOG_ALERT, msg +
662 "IORegistryEntryCreateIterator returned a NULL iterator");
668 while ((drive = IOIteratorNext(iter)))
670 CFMutableDictionaryRef
p =
nullptr;
672 IORegistryEntryCreateCFProperties(drive, &
p, kCFAllocatorDefault, 0);
675 const void *
type = CFDictionaryGetValue(
p, CFSTR(
"device-type"));
677 if (CFEqual(
type, CFSTR(
"DVD")) || CFEqual(
type, CFSTR(
"CD")))
682 LOG(VB_MEDIA, LOG_INFO, desc.prepend(
"Found CD/DVD: "));
687 LOG(VB_GENERAL, LOG_ALERT,
688 msg +
"Could not retrieve drive properties");
690 IOObjectRelease(drive);
693 IOObjectRelease(iter);