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() - ");
48 bool isWholeMedia =
false;
51 kernResult = IORegistryEntryCreateIterator(service,
53 kIORegistryIterateRecursively
54 | kIORegistryIterateParents,
57 if (KERN_SUCCESS != kernResult)
59 LOG(VB_GENERAL, LOG_CRIT, msg +
60 QString(
"IORegistryEntryCreateIterator returned %1")
65 LOG(VB_GENERAL, LOG_CRIT, msg +
66 "IORegistryEntryCreateIterator returned NULL iterator");
72 IOObjectRetain(service);
77 if (IOObjectConformsTo(service, kIOMediaClass))
81 wholeMedia = IORegistryEntryCreateCFProperty
82 (service, CFSTR(kIOMediaWholeKey),
83 kCFAllocatorDefault, 0);
87 LOG(VB_GENERAL, LOG_ALERT, msg +
88 "Could not retrieve Whole property");
92 isWholeMedia = CFBooleanGetValue((CFBooleanRef)wholeMedia);
93 CFRelease(wholeMedia);
99 if (IOObjectConformsTo(service, kIODVDMediaClass))
101 else if (IOObjectConformsTo(service, kIOCDMediaClass))
105 IOObjectRelease(service);
107 }
while ((service = IOIteratorNext(iter))
110 IOObjectRelease(iter);
120 CFMutableDictionaryRef matchingDict;
121 kern_return_t kernResult;
123 io_service_t service;
124 QString msg = QString(
"MediaTypeForBSDName(%1)")
129 if (!bsdName || !*bsdName)
131 LOG(VB_GENERAL, LOG_ALERT, msg +
" - No name supplied?");
135 matchingDict = IOBSDNameMatching(
sMasterPort, 0, bsdName);
138 LOG(VB_GENERAL, LOG_ALERT,
139 msg +
" - IOBSDNameMatching() returned a NULL dictionary.");
145 kernResult = IOServiceGetMatchingServices(
sMasterPort, matchingDict, &iter);
147 if (KERN_SUCCESS != kernResult)
149 LOG(VB_GENERAL, LOG_ALERT,
150 QString(msg +
" - IOServiceGetMatchingServices() returned %2")
156 LOG(VB_GENERAL, LOG_ALERT,
157 msg +
" - IOServiceGetMatchingServices() returned a NULL "
162 service = IOIteratorNext(iter);
166 IOObjectRelease(iter);
170 LOG(VB_GENERAL, LOG_ALERT,
171 msg +
" - IOIteratorNext() returned a NULL iterator");
175 IOObjectRelease(service);
190 CFDictionaryGetValue(diskDetails, kDADiskDescriptionVolumeNameKey);
195 size = CFStringGetLength(name) + 1;
196 volName = (
char *) malloc(size);
199 LOG(VB_GENERAL, LOG_ALERT,
200 QString(
"getVolName() - Can't malloc(%1)?").
arg(size));
204 if (!CFStringGetCString(name, volName, size, kCFStringEncodingUTF8))
216 static QString
getModel(CFDictionaryRef diskDetails)
222 if (kCFBooleanTrue ==
223 CFDictionaryGetValue(diskDetails,
224 kDADiskDescriptionDeviceInternalKey))
225 desc.append(
"Internal ");
228 strRef = CFDictionaryGetValue(diskDetails,
229 kDADiskDescriptionDeviceVendorKey);
232 desc.append(CFStringGetCStringPtr((CFStringRef)strRef,
233 kCFStringEncodingMacRoman));
238 strRef = CFDictionaryGetValue(diskDetails,
239 kDADiskDescriptionDeviceModelKey);
242 desc.append(CFStringGetCStringPtr((CFStringRef)strRef,
243 kCFStringEncodingMacRoman));
248 desc.truncate(desc.length() - 1);
264 const char *BSDname = DADiskGetBSDName(disk);
265 CFDictionaryRef details;
270 QString msg =
"diskAppearedCallback() - ";
276 LOG(VB_MEDIA, LOG_INFO, msg +
"Skipping non-local device");
282 LOG(VB_GENERAL, LOG_ALERT, msg +
"Error. Invoked with a NULL context.");
294 details = DADiskCopyDescription(disk);
296 if (kCFBooleanFalse ==
297 CFDictionaryGetValue(details, kDADiskDescriptionMediaRemovableKey))
299 LOG(VB_MEDIA, LOG_INFO, msg + QString(
"Skipping non-removable %1")
309 LOG(VB_MEDIA, LOG_INFO, msg + QString(
"No volume name for dev %1")
317 if (model.contains(
"Disk Image"))
319 LOG(VB_MEDIA, LOG_INFO, msg + QString(
"DMG %1 mounted, ignoring")
333 LOG(VB_MEDIA, LOG_INFO, QString(
"Found disk %1 - volume name '%2'.")
334 .
arg(BSDname).
arg(volName));
336 mtd->
diskInsert(BSDname, volName, model, isCDorDVD);
344 const char *BSDname = DADiskGetBSDName(disk);
352 if (CFArrayContainsValue(keys, CFRangeMake(0, CFArrayGetCount(keys)),
353 kDADiskDescriptionVolumeNameKey))
355 const char *BSDname = DADiskGetBSDName(disk);
356 CFDictionaryRef details = DADiskCopyDescription(disk);
359 LOG(VB_MEDIA, LOG_INFO, QString(
"Disk %1 - changed name to '%2'.")
360 .
arg(BSDname).
arg(volName));
363 ->diskRename(BSDname, volName);
376 CFDictionaryRef match = kDADiskDescriptionMatchVolumeMountable;
377 DASessionRef daSession = DASessionCreate(kCFAllocatorDefault);
381 DARegisterDiskAppearedCallback(daSession, match,
383 DARegisterDiskDisappearedCallback(daSession, match,
385 DARegisterDiskDescriptionChangedCallback(daSession, match,
386 kDADiskDescriptionWatchVolumeName,
389 DASessionScheduleWithRunLoop(daSession,
390 CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
399 CFRunLoopRunInMode(kCFRunLoopDefaultMode,
406 CFRelease(daSession);
418 QString model,
bool isCDorDVD)
421 QString msg =
"MonitorThreadDarwin::diskInsert";
423 LOG(VB_MEDIA, LOG_DEBUG, msg + QString(
"(%1,%2,'%3',%4)")
433 LOG(VB_GENERAL, LOG_ALERT, msg +
"Couldn't create MythMediaDevice.");
442 QString mnt =
"/Volumes/"; mnt += volName;
449 LOG(VB_MEDIA, LOG_WARNING,
450 (msg +
"() - Waiting for mount '%1' to become stable.").
arg(mnt));
451 usleep(std::chrono::microseconds(120000));
452 if ( ++attempts > 4 )
453 usleep(std::chrono::microseconds(200000));
457 LOG(VB_MEDIA, LOG_ALERT, msg +
"() - Giving up");
479 LOG(VB_MEDIA, LOG_DEBUG,
480 QString(
"MonitorThreadDarwin::diskRemove(%1)").
arg(devName));
487 LOG(VB_MEDIA, LOG_INFO,
"Couldn't find MythMediaDevice: " + devName);
500 LOG(VB_MEDIA, LOG_DEBUG,
501 QString(
"MonitorThreadDarwin::diskRename(%1,%2)")
502 .
arg(devName).
arg(volName));
512 pDevice->
setMountPath((QString(
"/Volumes/") + volName).toLatin1());
520 LOG(VB_MEDIA, LOG_INFO,
521 QString(
"Couldn't find MythMediaDevice: %1").
arg(devName));
545 qRegisterMetaType<MythMediaStatus>(
"MythMediaStatus");
547 LOG(VB_MEDIA, LOG_NOTICE,
"Starting MediaMonitor");
561 LOG(VB_GENERAL, LOG_ERR,
"MediaMonitor::AddDevice(null)");
591 CFMutableDictionaryRef props =
nullptr;
593 props = (CFMutableDictionaryRef) IORegistryEntrySearchCFProperty(drive, kIOServicePlane, CFSTR(kIOPropertyProtocolCharacteristicsKey), kCFAllocatorDefault, kIORegistryIterateParents | kIORegistryIterateRecursively);
597 const void *location = CFDictionaryGetValue(props, CFSTR(kIOPropertyPhysicalInterconnectLocationKey));
598 if (CFEqual(location, CFSTR(
"Internal")))
599 desc.append(
"Internal ");
602 props = (CFMutableDictionaryRef) IORegistryEntrySearchCFProperty(drive, kIOServicePlane, CFSTR(kIOPropertyDeviceCharacteristicsKey), kCFAllocatorDefault, kIORegistryIterateParents | kIORegistryIterateRecursively);
605 const void *product = CFDictionaryGetValue(props, CFSTR(kIOPropertyProductNameKey));
606 const void *vendor = CFDictionaryGetValue(props, CFSTR(kIOPropertyVendorNameKey));
609 desc.append(CFStringGetCStringPtr((CFStringRef)vendor, kCFStringEncodingMacRoman));
614 desc.append(CFStringGetCStringPtr((CFStringRef)product, kCFStringEncodingMacRoman));
620 desc.truncate(desc.length() - 1);
636 kern_return_t kernResult;
637 CFMutableDictionaryRef devices;
640 QString msg = QString(
"GetCDRomBlockDevices() - ");
643 devices = IOServiceMatching(kIOBlockStorageDeviceClass);
646 LOG(VB_GENERAL, LOG_ALERT, msg +
"No Storage Devices? Unlikely!");
651 kernResult = IOServiceGetMatchingServices(
sMasterPort, devices, &iter);
653 if (KERN_SUCCESS != kernResult)
655 LOG(VB_GENERAL, LOG_ALERT, msg +
656 QString(
"IORegistryEntryCreateIterator returned %1")
662 LOG(VB_GENERAL, LOG_ALERT, msg +
663 "IORegistryEntryCreateIterator returned a NULL iterator");
669 while ((drive = IOIteratorNext(iter)))
671 CFMutableDictionaryRef
p =
nullptr;
673 IORegistryEntryCreateCFProperties(drive, &
p, kCFAllocatorDefault, 0);
676 const void *
type = CFDictionaryGetValue(
p, CFSTR(
"device-type"));
678 if (CFEqual(
type, CFSTR(
"DVD")) || CFEqual(
type, CFSTR(
"CD")))
683 LOG(VB_MEDIA, LOG_INFO, desc.prepend(
"Found CD/DVD: "));
688 LOG(VB_GENERAL, LOG_ALERT,
689 msg +
"Could not retrieve drive properties");
691 IOObjectRelease(drive);
694 IOObjectRelease(iter);