void CUDisksProvider::DeviceChanged(const char *object, IStorageEventsCallback *callback) { CLog::Log(LOGDEBUG, "UDisks: DeviceChanged (%s)", object); CUDiskDevice *device = m_AvailableDevices[object]; if (device == NULL) { CLog::Log(LOGWARNING, "UDisks: Inconsistency found! DeviceChanged on an unindexed disk"); DeviceAdded(object, callback); } else { bool mounted = device->m_isMounted; if (!mounted && g_advancedSettings.m_handleMounting) device->Mount(); device->Update(); if (!mounted && device->m_isMounted && callback) callback->OnStorageAdded(device->m_Label, device->m_MountPath); else if (mounted && !device->m_isMounted && callback) callback->OnStorageSafelyRemoved(device->m_Label); CLog::Log(LOGDEBUG, "UDisks: DeviceChanged - %s", device->toString().c_str()); } }
void CddaLister::Init() { cdio_init(); #ifdef Q_OS_DARWIN if (!cdio_have_driver(DRIVER_OSX)) { qLog(Error) << "libcdio was compiled without support for OS X!"; } #endif char **devices = cdio_get_devices(DRIVER_DEVICE); if (!devices) { qLog(Debug) << "No CD devices found"; return; } for (; *devices != NULL; ++devices) { QString device(*devices); QFileInfo device_info(device); if (device_info.isSymLink()) { device = device_info.symLinkTarget(); } #ifdef Q_OS_DARWIN // Every track is detected as a separate device on Darwin. The raw disk looks // like /dev/rdisk1 if (!device.contains(QRegExp("^/dev/rdisk[0-9]$"))) { continue; } #endif if (!devices_list_.contains(device)) { devices_list_ << device; emit DeviceAdded(device); } } }
void CUDisksProvider::DeviceChanged(const char *object, IStorageEventsCallback *callback) { CLog::Log(LOGDEBUG|LOGDBUS, "UDisks: DeviceChanged (%s)", object); CUDiskDevice *device = m_AvailableDevices[object]; if (device == NULL) { CLog::Log(LOGWARNING, "UDisks: Inconsistency found! DeviceChanged on an unindexed disk"); DeviceAdded(object, callback); } else { bool mounted = device->m_isMounted; /* make sure to not silently remount ejected usb thumb drives that user wants to eject, but make sure to mount blurays */ if (!mounted && g_advancedSettings.m_handleMounting && device->m_isOptical) device->Mount(); device->Update(); if (!mounted && device->m_isMounted && callback) callback->OnStorageAdded(device->m_Label, device->m_MountPath); else if (mounted && !device->m_isMounted && callback) callback->OnStorageSafelyRemoved(device->m_Label); CLog::Log(LOGDEBUG|LOGDBUS, "UDisks: DeviceChanged - %s", device->toString().c_str()); } }
void WmdmLister::WMDMDeviceAdded(const QString& canonical_name) { ScopedWCharArray name(canonical_name); IWMDMDevice* device = NULL; if (thread_->manager()->GetDeviceFromCanonicalName(name, &device)) { qLog(Warning) << "Error in GetDeviceFromCanonicalName for" << canonical_name; return; } IWMDMDevice2* device2 = NULL; if (device->QueryInterface(IID_IWMDMDevice2, (void**) &device2)) { qLog(Warning) << "Error getting IWMDMDevice2 from device"; device->Release(); return; } device->Release(); DeviceInfo info = ReadDeviceInfo(device2); if (info.is_suitable_) { QString id = info.unique_id(); { QMutexLocker l(&mutex_); devices_[id] = info; } emit DeviceAdded(id); } else { device2->Release(); } }
bool UPower::connectInterfaces() { if(m_interface==0 || !m_interface->isValid()) { m_interface = new QDBusInterface("org.freedesktop.UPower", "/org/freedesktop/UPower", "org.freedesktop.UPower", QDBusConnection::systemBus()); if(!m_interface->isValid()) { m_interface->deleteLater(); m_interface = 0; if (m_interfaceProps) m_interfaceProps->deleteLater(); m_interfaceProps = 0; return false; } connect(m_interface, SIGNAL(DeviceAdded(QString)), this, SLOT(deviceAdded(QString))); connect(m_interface, SIGNAL(DeviceRemoved(QString)), this, SIGNAL(batteryDisconnected(QString))); connect(m_interface, SIGNAL(Changed()), this, SLOT(changed())); } if(m_interfaceProps==0 || !m_interfaceProps->isValid()) { m_interfaceProps = new QDBusInterface("org.freedesktop.UPower", "/org/freedesktop/UPower", "org.freedesktop.DBus.Properties", QDBusConnection::systemBus()); if(!m_interfaceProps->isValid()) { if (m_interface) m_interface->deleteLater(); m_interface = 0; m_interfaceProps->deleteLater(); m_interfaceProps = 0; return false; } } emit upowerAvailable(); return true; }
bool CDeviceKitDisksProvider::PumpDriveChangeEvents(IStorageEventsCallback *callback) { bool result = false; if (m_connection) { dbus_connection_read_write(m_connection, 0); DBusMessage *msg = dbus_connection_pop_message(m_connection); if (msg) { char *object; if (dbus_message_get_args (msg, NULL, DBUS_TYPE_OBJECT_PATH, &object, DBUS_TYPE_INVALID)) { result = true; if (dbus_message_is_signal(msg, "org.freedesktop.DeviceKit.Disks", "DeviceAdded")) DeviceAdded(object, callback); else if (dbus_message_is_signal(msg, "org.freedesktop.DeviceKit.Disks", "DeviceRemoved")) DeviceRemoved(object, callback); else if (dbus_message_is_signal(msg, "org.freedesktop.DeviceKit.Disks", "DeviceChanged")) DeviceChanged(object, callback); } dbus_message_unref(msg); } } return result; }
void Udisks2Lister::HandleFinishedMountJob( const Udisks2Lister::PartitionData& partition_data) { qLog(Debug) << "UDisks2 mount job finished: Drive = " << partition_data.dbus_drive_path << " | Partition = " << partition_data.dbus_path; QWriteLocker locker(&device_data_lock_); device_data_[partition_data.unique_id()] = partition_data; DeviceAdded(partition_data.unique_id()); }
void DeviceKitLister::Init() { interface_.reset(new OrgFreedesktopUDisksInterface( OrgFreedesktopUDisksInterface::staticInterfaceName(), "/org/freedesktop/UDisks", QDBusConnection::systemBus())); // Get all the devices currently attached QDBusPendingReply<QList<QDBusObjectPath> > reply = interface_->EnumerateDevices(); reply.waitForFinished(); if (!reply.isValid()) { qLog(Warning) << "Error enumerating DeviceKit-disks devices:" << reply.error().name() << reply.error().message(); interface_.reset(); return; } // Listen for changes connect(interface_.get(), SIGNAL(DeviceAdded(QDBusObjectPath)), SLOT(DBusDeviceAdded(QDBusObjectPath))); connect(interface_.get(), SIGNAL(DeviceRemoved(QDBusObjectPath)), SLOT(DBusDeviceRemoved(QDBusObjectPath))); connect(interface_.get(), SIGNAL(DeviceChanged(QDBusObjectPath)), SLOT(DBusDeviceChanged(QDBusObjectPath))); // Get information about each one QMap<QString, DeviceData> device_data; for (const QDBusObjectPath& path : reply.value()) { DeviceData data = ReadDeviceData(path); if (data.suitable) device_data[data.unique_id()] = data; } // Update the internal cache { QMutexLocker l(&mutex_); device_data_ = device_data; } // Notify about the changes for (const QString& id : device_data.keys()) { emit DeviceAdded(id); } }
void DeviceKitLister::DBusDeviceAdded(const QDBusObjectPath& path) { DeviceData data = ReadDeviceData(path); if (!data.suitable) return; { QMutexLocker l(&mutex_); device_data_[data.unique_id()] = data; } emit DeviceAdded(data.unique_id()); }
void CDeviceKitDisksProvider::Initialize() { CLog::Log(LOGDEBUG, "Selected DeviceKit.Disks as storage provider"); m_DaemonVersion = atoi(CDBusUtil::GetVariant("org.freedesktop.DeviceKit.Disks", "/org/freedesktop/DeviceKit/Disks", "org.freedesktop.DeviceKit.Disks", "DaemonVersion").asString().c_str()); CLog::Log(LOGDEBUG, "DeviceKit.Disks: DaemonVersion %i", m_DaemonVersion); CLog::Log(LOGDEBUG, "DeviceKit.Disks: Querying available devices"); std::vector<CStdString> devices = EnumerateDisks(); for (unsigned int i = 0; i < devices.size(); i++) DeviceAdded(devices[i].c_str(), NULL); }
LRESULT CInterfacePlugInWnd::OnMyDeviceChange(WPARAM wParam, LPARAM lParam) { PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam; switch (wParam) { case DBT_DEVICEARRIVAL: DeviceAdded(pHdr); break; case DBT_DEVICEREMOVECOMPLETE: DeviceRemoved(pHdr); break; default: break; } return 0; }
void iLister::DeviceAddedCallback(const char* uuid) { DeviceInfo info = ReadDeviceInfo(uuid); QString id = UniqueId(uuid); QString name = MakeFriendlyName(id); if (info.product_type == "iPhone 3,1" || info.product_type.startsWith("iPad")) { // iPhone 4 and iPad unsupported by libgpod as of 0.7.94. return; } { QMutexLocker l(&mutex_); devices_[id] = info; } emit DeviceAdded(id); }
void GioLister::MountAdded(GMount* mount) { g_object_ref(mount); DeviceInfo info; info.ReadVolumeInfo(g_mount_get_volume(mount)); #ifdef HAVE_AUDIOCD if (info.volume_root_uri.startsWith("cdda")) // Audio CD devices are already handled by CDDA lister return; #endif info.ReadMountInfo(mount); info.ReadDriveInfo(g_mount_get_drive(mount)); if (!info.is_suitable()) return; QString old_id; { QMutexLocker l(&mutex_); // The volume might already exist - either mounted or unmounted. foreach (const QString& id, devices_.keys()) { if (devices_[id].volume == info.volume) { old_id = id; break; } } if (!old_id.isEmpty() && old_id != info.unique_id()) { // If the ID has changed (for example, after it's been mounted), we need // to remove the old device. devices_.remove(old_id); emit DeviceRemoved(old_id); old_id = QString(); } devices_[info.unique_id()] = info; } if (!old_id.isEmpty()) emit DeviceChanged(old_id); else { emit DeviceAdded(info.unique_id()); } }
void ColordEngine::init() { // Creates a ColorD interface, it must be created with new // otherwise the object will be deleted when this block ends QDBusInterface *interface; interface = new QDBusInterface(QLatin1String("org.freedesktop.ColorManager"), QLatin1String("/org/freedesktop/ColorManager"), QLatin1String("org.freedesktop.ColorManager"), QDBusConnection::systemBus(), this); // listen to colord for device events connect(interface, SIGNAL(DeviceAdded(QDBusObjectPath)), this, SLOT(deviceAdded(QDBusObjectPath))); connect(interface, SIGNAL(DeviceRemoved(QDBusObjectPath)), this, SLOT(deviceRemoved(QDBusObjectPath))); connect(interface, SIGNAL(DeviceChanged(QDBusObjectPath)), this, SLOT(deviceChanged(QDBusObjectPath))); // listen to colord for profile events connect(interface, SIGNAL(ProfileAdded(QDBusObjectPath)), this, SLOT(profileAdded(QDBusObjectPath))); connect(interface, SIGNAL(ProfileRemoved(QDBusObjectPath)), this, SLOT(profileRemoved(QDBusObjectPath))); connect(interface, SIGNAL(ProfileChanged(QDBusObjectPath)), this, SLOT(profileChanged(QDBusObjectPath))); // Ask for profiles QDBusMessage msg; msg = QDBusMessage::createMethodCall(QLatin1String("org.freedesktop.ColorManager"), QLatin1String("/org/freedesktop/ColorManager"), QLatin1String("org.freedesktop.ColorManager"), QLatin1String("GetProfiles")); QDBusConnection::systemBus().callWithCallback(msg, this, SLOT(gotProfiles(QDBusMessage))); // Ask for devices QDBusMessage message; message = QDBusMessage::createMethodCall(QLatin1String("org.freedesktop.ColorManager"), QLatin1String("/org/freedesktop/ColorManager"), QLatin1String("org.freedesktop.ColorManager"), QLatin1String("GetDevices")); QDBusConnection::systemBus().callWithCallback(message, this, SLOT(gotDevices(QDBusMessage))); }
void InitDetection() { kern_return_t kr; // Set up the matching criteria for the devices we're interested in. The matching criteria needs to follow // the same rules as kernel drivers: mainly it needs to follow the USB Common Class Specification, pp. 6-7. // See also Technical Q&A QA1076 "Tips on USB driver matching on Mac OS X" // <http://developer.apple.com/qa/qa2001/qa1076.html>. // One exception is that you can use the matching dictionary "as is", i.e. without adding any matching // criteria to it and it will match every IOUSBDevice in the system. IOServiceAddMatchingNotification will // consume this dictionary reference, so there is no need to release it later on. // Interested in instances of class // IOUSBDevice and its subclasses matchingDict = IOServiceMatching(kIOUSBDeviceClassName); if (matchingDict == NULL) { fprintf(stderr, "IOServiceMatching returned NULL.\n"); } // Create a notification port and add its run loop event source to our run loop // This is how async notifications get set up. gNotifyPort = IONotificationPortCreate(kIOMasterPortDefault); // Now set up a notification to be called when a device is first matched by I/O Kit. kr = IOServiceAddMatchingNotification( gNotifyPort, // notifyPort kIOFirstMatchNotification, // notificationType matchingDict, // matching DeviceAdded, // callback NULL, // refCon &gAddedIter // notification ); if (KERN_SUCCESS != kr) { printf("IOServiceAddMatchingNotification returned 0x%08x.\n", kr); } // Iterate once to get already-present devices and arm the notification DeviceAdded(NULL, gAddedIter); initialDeviceImport = false; }
void GioLister::VolumeAdded(GVolume* volume) { g_object_ref(volume); DeviceInfo info; info.ReadVolumeInfo(volume); #ifdef HAVE_AUDIOCD if (info.volume_root_uri.startsWith("cdda")) // Audio CD devices are already handled by CDDA lister return; #endif info.ReadDriveInfo(g_volume_get_drive(volume)); info.ReadMountInfo(g_volume_get_mount(volume)); if (!info.is_suitable()) return; { QMutexLocker l(&mutex_); devices_[info.unique_id()] = info; } emit DeviceAdded(info.unique_id()); }
devicemodel::devicemodel(QObject* parent) :QAbstractListModel(parent) { QHash<int, QByteArray> roles; roles.insert( devicemodel::DeviceName, "deviceName"); roles.insert( devicemodel::DeviceLabel, "deviceLabel"); setRoleNames(roles); m_deviceInterface = new org::freedesktop::UDisks( QString("org.freedesktop.UDisks"), QString("/org/freedesktop/UDisks"), QDBusConnection::systemBus(), this); connect(m_deviceInterface,SIGNAL(DeviceAdded(QDBusObjectPath)),this, SLOT(addDevice(QDBusObjectPath))); connect(m_deviceInterface,SIGNAL(DeviceRemoved(QDBusObjectPath)),this, SLOT(removeDevice(QDBusObjectPath))); listDevices(); }
void Udisks2Lister::Init() { udisks2_interface_.reset(new OrgFreedesktopDBusObjectManagerInterface( udisks2_service_, "/org/freedesktop/UDisks2", QDBusConnection::systemBus())); QDBusPendingReply<ManagedObjectList> reply = udisks2_interface_->GetManagedObjects(); reply.waitForFinished(); if (!reply.isValid()) { qLog(Warning) << "Error enumerating udisks2 devices:" << reply.error().name() << reply.error().message(); udisks2_interface_.reset(); return; } for (const QDBusObjectPath& path : reply.value().keys()) { auto partition_data = ReadPartitionData(path); if (!partition_data.dbus_path.isEmpty()) { QWriteLocker locker(&device_data_lock_); device_data_[partition_data.unique_id()] = partition_data; } } for (const auto& id : device_data_.keys()) { emit DeviceAdded(id); } connect(udisks2_interface_.get(), SIGNAL(InterfacesAdded(QDBusObjectPath, InterfacesAndProperties)), SLOT(DBusInterfaceAdded(QDBusObjectPath, InterfacesAndProperties))); connect(udisks2_interface_.get(), SIGNAL(InterfacesRemoved(QDBusObjectPath, QStringList)), SLOT(DBusInterfaceRemoved(QDBusObjectPath, QStringList))); }
void WmdmLister::Init() { qLog(Debug) << "Starting"; thread_.reset(new WmdmThread); if (!thread_->manager()) return; // Register for notifications qLog(Debug) << "Obtaining CP container"; IConnectionPointContainer* cp_container = NULL; thread_->manager()->QueryInterface(IID_IConnectionPointContainer, (void**)&cp_container); qLog(Debug) << "Obtaining CP"; IConnectionPoint* cp = NULL; cp_container->FindConnectionPoint(IID_IWMDMNotification, &cp); qLog(Debug) << "Registering for notifications"; cp->Advise(this, ¬ification_cookie_); cp->Release(); cp_container->Release(); // Fetch the initial list of devices qLog(Debug) << "Fetching device list"; IWMDMEnumDevice* device_it = NULL; if (thread_->manager()->EnumDevices2(&device_it)) { qLog(Warning) << "Error querying WMDM devices"; return; } // Iterate through the devices QMap<QString, DeviceInfo> devices; forever { IWMDMDevice* device = NULL; IWMDMDevice2* device2 = NULL; ULONG fetched = 0; if (device_it->Next(1, &device, &fetched) || fetched != 1) break; qLog(Debug) << "Querying device"; if (device->QueryInterface(IID_IWMDMDevice2, (void**)&device2)) { qLog(Warning) << "Error getting IWMDMDevice2 from device"; device->Release(); continue; } device->Release(); DeviceInfo info = ReadDeviceInfo(device2); if (info.is_suitable_) devices[info.unique_id()] = info; else device2->Release(); } device_it->Release(); // Update the internal cache qLog(Debug) << "Updating device cache"; { QMutexLocker l(&mutex_); devices_ = devices; } // Notify about the changes foreach (const QString& id, devices.keys()) { emit DeviceAdded(id); } qLog(Debug) << "Startup complete"; }
//================================================================================================ // main //================================================================================================ // int main (int argc, const char *argv[]) { mach_port_t masterPort; CFMutableDictionaryRef matchingDict; CFRunLoopSourceRef runLoopSource; CFNumberRef numberRef; CFStringRef stringRef; kern_return_t kr; long usbVendor = kMyVendorID; sig_t oldHandler; // pick up command line arguments // if (argc > 1) usbVendor = atoi(argv[1]); // Set up a signal handler so we can clean up when we're interrupted from the command line // Otherwise we stay in our run loop forever. // oldHandler = signal(SIGINT, SignalHandler); if (oldHandler == SIG_ERR) printf("Could not establish new signal handler"); // first create a master_port for my task // kr = IOMasterPort(MACH_PORT_NULL, &masterPort); if (kr || !masterPort) { printf("ERR: Couldn't create a master IOKit Port(%08x)\n", kr); return -1; } printf("Looking for devices matching vendor ID=%ld\n", usbVendor); // Set up the matching criteria for the devices we're interested in. The matching criteria needs to follow // the same rules as kernel drivers: mainly it needs to follow the USB Common Class Specification, pp. 6-7. // See also http://developer.apple.com/qa/qa2001/qa1076.html // One exception is that you can use the matching dictionary "as is", i.e. without adding any matching criteria // to it and it will match every IOUSBDevice in the system. IOServiceAddMatchingNotification will consume this // dictionary reference, so there is no need to release it later on. // matchingDict = IOServiceMatching(kIOUSBDeviceClassName); // Interested in instances of class // IOUSBDevice and its subclasses if (!matchingDict) { printf("Can't create a USB matching dictionary\n"); mach_port_deallocate(mach_task_self(), masterPort); return -1; } // We are interested in all USB Devices (as opposed to USB interfaces). The Common Class Specification // tells us that we need to specify the idVendor, idProduct, and bcdDevice fields, or, if we're not interested // in particular bcdDevices, just the idVendor and idProduct. Note that if we were trying to match an IOUSBInterface, // we would need to set more values in the matching dictionary (e.g. idVendor, idProduct, bInterfaceNumber and // bConfigurationValue. // // Create a CFNumber for the idVendor and set the value in the dictionary // numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbVendor); CFDictionarySetValue( matchingDict, CFSTR(kUSBVendorID), numberRef); CFRelease(numberRef); numberRef = 0; // Create a CFString for the wildcard product ID and set the value in the dictionary // stringRef = CFSTR("*"); CFDictionarySetValue( matchingDict, CFSTR(kUSBProductID), stringRef); CFRelease(stringRef); stringRef = 0; // Create a notification port and add its run loop event source to our run loop // This is how async notifications get set up. // gNotifyPort = IONotificationPortCreate(masterPort); runLoopSource = IONotificationPortGetRunLoopSource(gNotifyPort); gRunLoop = CFRunLoopGetCurrent(); CFRunLoopAddSource(gRunLoop, runLoopSource, kCFRunLoopDefaultMode); // Now set up a notification to be called when a device is first matched by I/O Kit. // Note that this will not catch any devices that were already plugged in so we take // care of those later. // kr = IOServiceAddMatchingNotification(gNotifyPort, // notifyPort kIOFirstMatchNotification, // notificationType matchingDict, // matching DeviceAdded, // callback NULL, // refCon &gAddedIter // notification ); // Iterate once to get already-present devices and arm the notification // DeviceAdded(NULL, gAddedIter); // Now done with the master_port mach_port_deallocate(mach_task_self(), masterPort); masterPort = 0; // Start the run loop. Now we'll receive notifications. // printf("Starting run loop.\n"); CFRunLoopRun(); // We should never get here // printf("Unexpectedly back from CFRunLoopRun()!\n"); return 0; }
//================================================================================================ // main //================================================================================================ int main(int argc, const char *argv[]) { CFMutableDictionaryRef matchingDict; CFRunLoopSourceRef runLoopSource; CFNumberRef numberRef; kern_return_t kr; long usbVendor = kMyVendorID; long usbProduct = kMyProductID; sig_t oldHandler; // pick up command line arguments if (argc > 1) { usbVendor = atoi(argv[1]); } if (argc > 2) { usbProduct = atoi(argv[2]); } // Set up a signal handler so we can clean up when we're interrupted from the command line // Otherwise we stay in our run loop forever. oldHandler = signal(SIGINT, SignalHandler); if (oldHandler == SIG_ERR) { fprintf(stderr, "Could not establish new signal handler."); } fprintf(stderr, "Looking for devices matching vendor ID=%ld and product ID=%ld.\n", usbVendor, usbProduct); // Set up the matching criteria for the devices we're interested in. The matching criteria needs to follow // the same rules as kernel drivers: mainly it needs to follow the USB Common Class Specification, pp. 6-7. // See also Technical Q&A QA1076 "Tips on USB driver matching on Mac OS X" // <http://developer.apple.com/qa/qa2001/qa1076.html>. // One exception is that you can use the matching dictionary "as is", i.e. without adding any matching // criteria to it and it will match every IOUSBDevice in the system. IOServiceAddMatchingNotification will // consume this dictionary reference, so there is no need to release it later on. matchingDict = IOServiceMatching(kIOUSBDeviceClassName); // Interested in instances of class // IOUSBDevice and its subclasses if (matchingDict == NULL) { fprintf(stderr, "IOServiceMatching returned NULL.\n"); return -1; } // We are interested in all USB devices (as opposed to USB interfaces). The Common Class Specification // tells us that we need to specify the idVendor, idProduct, and bcdDevice fields, or, if we're not interested // in particular bcdDevices, just the idVendor and idProduct. Note that if we were trying to match an // IOUSBInterface, we would need to set more values in the matching dictionary (e.g. idVendor, idProduct, // bInterfaceNumber and bConfigurationValue. // Create a CFNumber for the idVendor and set the value in the dictionary numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbVendor); CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID), numberRef); CFRelease(numberRef); // Create a CFNumber for the idProduct and set the value in the dictionary numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbProduct); CFDictionarySetValue(matchingDict, CFSTR(kUSBProductID), numberRef); CFRelease(numberRef); numberRef = NULL; // Create a notification port and add its run loop event source to our run loop // This is how async notifications get set up. gNotifyPort = IONotificationPortCreate(kIOMasterPortDefault); runLoopSource = IONotificationPortGetRunLoopSource(gNotifyPort); gRunLoop = CFRunLoopGetCurrent(); CFRunLoopAddSource(gRunLoop, runLoopSource, kCFRunLoopDefaultMode); // Now set up a notification to be called when a device is first matched by I/O Kit. kr = IOServiceAddMatchingNotification(gNotifyPort, // notifyPort kIOFirstMatchNotification, // notificationType matchingDict, // matching DeviceAdded, // callback NULL, // refCon &gAddedIter // notification ); // Iterate once to get already-present devices and arm the notification DeviceAdded(NULL, gAddedIter); // Start the run loop. Now we'll receive notifications. fprintf(stderr, "Starting run loop.\n\n"); CFRunLoopRun(); // We should never get here fprintf(stderr, "Unexpectedly back from CFRunLoopRun()!\n"); return 0; }
int main(int argc, const char *argv[]) { time_t current_time = time(NULL); char* c_time_string = ctime(¤t_time); size_t l = strlen(c_time_string); if (l > 0) c_time_string[l-1] = 0; DEBUG_LOG("%s: VoodooPS2Daemon 1.7.12 starting...\n", c_time_string); // first check for trackpad driver g_ioservice = IOServiceGetMatchingService(0, IOServiceMatching("ApplePS2SynapticsTouchPad")); if (!g_ioservice) { // otherwise, talk to mouse driver g_ioservice = IOServiceGetMatchingService(0, IOServiceMatching("ApplePS2Mouse")); if (!g_ioservice) { DEBUG_LOG("No ApplePS2SynapticsTouchPad or ApplePS2Mouse found\n"); return -1; } } // Set up a signal handler so we can clean up when we're interrupted from the command line // or otherwise asked to terminate. if (SIG_ERR == signal(SIGINT, SignalHandler1)) DEBUG_LOG("Could not establish new SIGINT handler\n"); if (SIG_ERR == signal(SIGTERM, SignalHandler1)) DEBUG_LOG("Could not establish new SIGTERM handler\n"); // First create a master_port for my task mach_port_t masterPort; kern_return_t kr = IOMasterPort(MACH_PORT_NULL, &masterPort); if (kr || !masterPort) { DEBUG_LOG("ERR: Couldn't create a master IOKit Port(%08x)\n", kr); return -1; } // Create dictionary to match all USB devices CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName); if (!matchingDict) { DEBUG_LOG("Can't create a USB matching dictionary\n"); mach_port_deallocate(mach_task_self(), masterPort); return -1; } // Create a notification port and add its run loop event source to our run loop // This is how async notifications get set up. g_NotifyPort = IONotificationPortCreate(masterPort); CFRunLoopSourceRef runLoopSource = IONotificationPortGetRunLoopSource(g_NotifyPort); CFRunLoopRef runLoop = CFRunLoopGetCurrent(); CFRunLoopAddSource(runLoop, runLoopSource, kCFRunLoopDefaultMode); // Now set up a notification to be called when a device is first matched by I/O Kit. // Note that this will not catch any devices that were already plugged in so we take // care of those later. kr = IOServiceAddMatchingNotification(g_NotifyPort, kIOFirstMatchNotification, matchingDict, DeviceAdded, NULL, &g_AddedIter); // Iterate once to get already-present devices and arm the notification DeviceAdded(NULL, g_AddedIter); // Now done with the master_port mach_port_deallocate(mach_task_self(), masterPort); masterPort = 0; // Start the run loop. Now we'll receive notifications. CFRunLoopRun(); // We should never get here DEBUG_LOG("Unexpectedly back from CFRunLoopRun()!\n"); return 0; }