Warning, /utilities/isoimagewriter/isoimagewriter/usbdevicemonitor_mac.mm is written in an unsupported language. File is not indexed.
0001 /* 0002 SPDX-FileCopyrightText: 2016 ROSA 0003 SPDX-License-Identifier: GPL-3.0-or-later 0004 */ 0005 0006 //////////////////////////////////////////////////////////////////////////////// 0007 // Mac OS X implementation of UsbDeviceMonitor 0008 0009 #include "usbdevicemonitor.h" 0010 #include "usbdevicemonitor_mac_p.h" 0011 0012 #include <Cocoa/Cocoa.h> 0013 #include <IOKit/IOBSD.h> 0014 0015 0016 // Private class implementation 0017 0018 UsbDeviceMonitorPrivate::UsbDeviceMonitorPrivate() 0019 { 0020 } 0021 0022 UsbDeviceMonitorPrivate::~UsbDeviceMonitorPrivate() 0023 { 0024 } 0025 0026 0027 // Supplemental callback functions 0028 0029 void UsbDeviceAddedCallback(void *refCon, io_iterator_t iterator) 0030 { 0031 while (IOIteratorNext(iterator)) {}; // Run out the iterator or notifications won't start 0032 UsbDeviceMonitor* monitor = (UsbDeviceMonitor*)refCon; 0033 emit monitor->deviceChanged(); 0034 } 0035 0036 void UsbDeviceRemovedCallback(void *refCon, io_iterator_t iterator) 0037 { 0038 while (IOIteratorNext(iterator)) {}; // Run out the iterator or notifications won't start 0039 UsbDeviceMonitor* monitor = (UsbDeviceMonitor*)refCon; 0040 emit monitor->deviceChanged(); 0041 } 0042 0043 0044 // Main class implementation 0045 0046 UsbDeviceMonitor::UsbDeviceMonitor(QObject *parent) : 0047 QObject(parent), 0048 d_ptr(new UsbDeviceMonitorPrivate()) 0049 { 0050 } 0051 0052 UsbDeviceMonitor::~UsbDeviceMonitor() 0053 { 0054 cleanup(); 0055 delete d_ptr; 0056 } 0057 0058 // Closes handles and frees resources 0059 void UsbDeviceMonitor::cleanup() 0060 { 0061 } 0062 0063 // Implements QAbstractNativeEventFilter interface for processing WM_DEVICECHANGE messages (Windows) 0064 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0065 bool UsbDeviceMonitor::nativeEventFilter(const QByteArray& eventType, void* message, long* result) 0066 #else 0067 bool UsbDeviceMonitor::nativeEventFilter(const QByteArray& eventType, void* message, qintptr* result) 0068 #endif 0069 { 0070 Q_UNUSED(eventType); 0071 Q_UNUSED(message); 0072 Q_UNUSED(result); 0073 return false; 0074 } 0075 0076 bool UsbDeviceMonitor::startMonitoring() 0077 { 0078 IONotificationPortRef notificationPort = IONotificationPortCreate(kIOMasterPortDefault); 0079 CFRunLoopAddSource(CFRunLoopGetCurrent(), 0080 IONotificationPortGetRunLoopSource(notificationPort), 0081 kCFRunLoopDefaultMode); 0082 0083 // If we monitor USB devices, notification comes too early, and the new disk device is not present yet. 0084 // So, instead we monitor for the new disks. 0085 CFMutableDictionaryRef matchingDict = IOServiceMatching("IOMediaBSDClient"); 0086 CFRetain(matchingDict); // Need to use it twice and IOServiceAddMatchingNotification() consumes a reference 0087 0088 io_iterator_t portIterator = 0; 0089 // Register for notifications when a serial port is added to the system 0090 kern_return_t result = IOServiceAddMatchingNotification(notificationPort, 0091 kIOPublishNotification, 0092 matchingDict, 0093 UsbDeviceAddedCallback, 0094 this, 0095 &portIterator); 0096 while (IOIteratorNext(portIterator)) {}; // Run out the iterator or notifications won't start (you can also use it to iterate the available devices). 0097 0098 // Also register for removal notifications 0099 IONotificationPortRef terminationNotificationPort = IONotificationPortCreate(kIOMasterPortDefault); 0100 CFRunLoopAddSource(CFRunLoopGetCurrent(), 0101 IONotificationPortGetRunLoopSource(terminationNotificationPort), 0102 kCFRunLoopDefaultMode); 0103 result = IOServiceAddMatchingNotification(terminationNotificationPort, 0104 kIOTerminatedNotification, 0105 matchingDict, 0106 UsbDeviceRemovedCallback, 0107 this, // refCon/contextInfo 0108 &portIterator); 0109 0110 while (IOIteratorNext(portIterator)) {}; // Run out the iterator or notifications won't start (you can also use it to iterate the available devices). 0111 0112 return true; 0113 }