Example #1
0
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());
  }
}
Example #2
0
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);
    }
  }
}
Example #3
0
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());
  }
}
Example #4
0
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();
  }
}
Example #5
0
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;
}
Example #7
0
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());
}
Example #8
0
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);
  }
}
Example #9
0
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);
}
Example #11
0
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;
}
Example #12
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);
}
Example #13
0
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());
  }
}
Example #14
0
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)));
}
Example #15
0
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;
}
Example #16
0
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();
}
Example #18
0
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)));
}
Example #19
0
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, &notification_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";
}
Example #20
0
//================================================================================================
//	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;
}
Example #21
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;
}
Example #22
0
int main(int argc, const char *argv[])
{
    time_t current_time = time(NULL);
    char* c_time_string = ctime(&current_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;
}