diff --git a/libs/qextserialport/qextserialenumerator.h b/libs/qextserialport/qextserialenumerator.h deleted file mode 100644 index 3519d635c36896b287a40dc3f62284185efd182f..0000000000000000000000000000000000000000 --- a/libs/qextserialport/qextserialenumerator.h +++ /dev/null @@ -1,209 +0,0 @@ -/*! - * \file qextserialenumerator.h - * \author Michal Policht - * \see QextSerialEnumerator - */ - -#ifndef _QEXTSERIALENUMERATOR_H_ -#define _QEXTSERIALENUMERATOR_H_ - - -#include - -//#ifdef QEXTSERIALPORT_LIB -//# define QEXTSERIALPORT_EXPORT Q_DECL_EXPORT -//#else -//# define QEXTSERIALPORT_EXPORT Q_DECL_IMPORT -//#endif - -#define QEXTSERIALPORT_EXPORT - -#include -#include -#include -//#include "qextserialport_global.h" - -#ifdef Q_OS_WIN - #include - #include - #include -#endif /*Q_OS_WIN*/ - -#ifdef Q_OS_MAC - #include -#endif - -/*! - * Structure containing port information. - */ -struct QextPortInfo { - QString portName; ///< Port name. - QString physName; ///< Physical name. - QString friendName; ///< Friendly name. - QString enumName; ///< Enumerator name. - int vendorID; ///< Vendor ID. - int productID; ///< Product ID -}; - -#ifdef Q_OS_WIN -#ifdef QT_GUI_LIB -#include -class QextSerialEnumerator; - -class QextSerialRegistrationWidget : public QWidget -{ - Q_OBJECT - public: - QextSerialRegistrationWidget( QextSerialEnumerator* qese ) { - this->qese = qese; - } - ~QextSerialRegistrationWidget( ) { } - - protected: - QextSerialEnumerator* qese; - bool winEvent( MSG* message, long* result ); -}; -#endif // QT_GUI_LIB -#endif // Q_OS_WIN - -/*! - Provides list of ports available in the system. - - \section Usage - To poll the system for a list of connected devices, simply use getPorts(). Each - QextPortInfo structure will populated with information about the corresponding device. - - \b Example - \code - QList ports = QextSerialEnumerator::getPorts(); - foreach( QextPortInfo port, ports ) { - // inspect port... - } - \endcode - - To enable event-driven notification of device connection events, first call - setUpNotifications() and then connect to the deviceDiscovered() and deviceRemoved() - signals. Event-driven behavior is currently available only on Windows and OS X. - - \b Example - \code - QextSerialEnumerator* enumerator = new QextSerialEnumerator(); - connect(enumerator, SIGNAL(deviceDiscovered(const QextPortInfo &)), - myClass, SLOT(onDeviceDiscovered(const QextPortInfo &))); - connect(enumerator, SIGNAL(deviceRemoved(const QextPortInfo &)), - myClass, SLOT(onDeviceRemoved(const QextPortInfo &))); - \endcode - - \section Credits - Windows implementation is based on Zach Gorman's work from - The Code Project (http://www.codeproject.com/system/setupdi.asp). - - OS X implementation, see - http://developer.apple.com/documentation/DeviceDrivers/Conceptual/AccessingHardware/AH_Finding_Devices/chapter_4_section_2.html - - \author Michal Policht, Liam Staskawicz -*/ -class QEXTSERIALPORT_EXPORT QextSerialEnumerator : public QObject -{ -Q_OBJECT - public: - QextSerialEnumerator( ); - ~QextSerialEnumerator( ); - - #ifdef Q_OS_WIN - LRESULT onDeviceChangeWin( WPARAM wParam, LPARAM lParam ); - private: - /*! - * Get value of specified property from the registry. - * \param key handle to an open key. - * \param property property name. - * \return property value. - */ - static QString getRegKeyValue(HKEY key, LPCTSTR property); - - /*! - * Get specific property from registry. - * \param devInfo pointer to the device information set that contains the interface - * and its underlying device. Returned by SetupDiGetClassDevs() function. - * \param devData pointer to an SP_DEVINFO_DATA structure that defines the device instance. - * this is returned by SetupDiGetDeviceInterfaceDetail() function. - * \param property registry property. One of defined SPDRP_* constants. - * \return property string. - */ - static QString getDeviceProperty(HDEVINFO devInfo, PSP_DEVINFO_DATA devData, DWORD property); - - /*! - * Search for serial ports using setupapi. - * \param infoList list with result. - */ - static void setupAPIScan(QList & infoList); - void setUpNotificationWin( ); - static bool getDeviceDetailsWin( QextPortInfo* portInfo, HDEVINFO devInfo, - PSP_DEVINFO_DATA devData, WPARAM wParam = DBT_DEVICEARRIVAL ); - static void enumerateDevicesWin( const GUID & guidDev, QList* infoList ); - bool matchAndDispatchChangedDevice(const QString & deviceID, const GUID & guid, WPARAM wParam); - #ifdef QT_GUI_LIB - QextSerialRegistrationWidget* notificationWidget; - #endif - #endif /*Q_OS_WIN*/ - - #ifdef Q_OS_UNIX - #ifdef Q_OS_MAC - private: - /*! - * Search for serial ports using IOKit. - * \param infoList list with result. - */ - static void scanPortsOSX(QList & infoList); - static void iterateServicesOSX(io_object_t service, QList & infoList); - static bool getServiceDetailsOSX( io_object_t service, QextPortInfo* portInfo ); - - void setUpNotificationOSX( ); - void onDeviceDiscoveredOSX( io_object_t service ); - void onDeviceTerminatedOSX( io_object_t service ); - friend void deviceDiscoveredCallbackOSX( void *ctxt, io_iterator_t serialPortIterator ); - friend void deviceTerminatedCallbackOSX( void *ctxt, io_iterator_t serialPortIterator ); - - IONotificationPortRef notificationPortRef; - - #else // Q_OS_MAC - private: - /*! - * Search for serial ports on unix. - * \param infoList list with result. - */ - static void scanPortsNix(QList & infoList); - #endif // Q_OS_MAC - #endif /* Q_OS_UNIX */ - - public: - /*! - Get list of ports. - \return list of ports currently available in the system. - */ - static QList getPorts(); - /*! - Enable event-driven notifications of board discovery/removal. - */ - void setUpNotifications( ); - - signals: - /*! - A new device has been connected to the system. - - setUpNotifications() must be called first to enable event-driven device notifications. - Currently only implemented on Windows and OS X. - \param info The device that has been discovered. - */ - void deviceDiscovered( const QextPortInfo & info ); - /*! - A device has been disconnected from the system. - - setUpNotifications() must be called first to enable event-driven device notifications. - Currently only implemented on Windows and OS X. - \param info The device that was disconnected. - */ - void deviceRemoved( const QextPortInfo & info ); -}; - -#endif /*_QEXTSERIALENUMERATOR_H_*/ diff --git a/libs/qextserialport/qextserialenumerator_osx.cpp b/libs/qextserialport/qextserialenumerator_osx.cpp deleted file mode 100644 index 229d73f3734c41a8ff7432cac907864058ec2e35..0000000000000000000000000000000000000000 --- a/libs/qextserialport/qextserialenumerator_osx.cpp +++ /dev/null @@ -1,288 +0,0 @@ - - - -#include "qextserialenumerator.h" -#include -#include - -#include -#include -#include - -QextSerialEnumerator::QextSerialEnumerator( ) -{ - if( !QMetaType::isRegistered( QMetaType::type("QextPortInfo") ) ) - qRegisterMetaType("QextPortInfo"); -} - -QextSerialEnumerator::~QextSerialEnumerator( ) -{ - IONotificationPortDestroy( notificationPortRef ); -} - -// static -QList QextSerialEnumerator::getPorts() -{ - QList infoList; - io_iterator_t serialPortIterator = 0; - kern_return_t kernResult = KERN_FAILURE; - CFMutableDictionaryRef matchingDictionary; - - // first try to get any serialbsd devices, then try any USBCDC devices - if( !(matchingDictionary = IOServiceMatching(kIOSerialBSDServiceValue) ) ) { - qWarning("IOServiceMatching returned a NULL dictionary."); - return infoList; - } - CFDictionaryAddValue(matchingDictionary, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDAllTypes)); - - // then create the iterator with all the matching devices - if( IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDictionary, &serialPortIterator) != KERN_SUCCESS ) { - qCritical() << "IOServiceGetMatchingServices failed, returned" << kernResult; - return infoList; - } - iterateServicesOSX(serialPortIterator, infoList); - IOObjectRelease(serialPortIterator); - serialPortIterator = 0; - - if( !(matchingDictionary = IOServiceNameMatching("AppleUSBCDC")) ) { - qWarning("IOServiceNameMatching returned a NULL dictionary."); - return infoList; - } - - if( IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDictionary, &serialPortIterator) != KERN_SUCCESS ) { - qCritical() << "IOServiceGetMatchingServices failed, returned" << kernResult; - return infoList; - } - iterateServicesOSX(serialPortIterator, infoList); - IOObjectRelease(serialPortIterator); - - return infoList; -} - -void QextSerialEnumerator::iterateServicesOSX(io_object_t service, QList & infoList) -{ - // Iterate through all modems found. - io_object_t usbService; - while( ( usbService = IOIteratorNext(service) ) ) - { - QextPortInfo info; - info.vendorID = 0; - info.productID = 0; - getServiceDetailsOSX( usbService, &info ); - infoList.append(info); - } -} - -bool QextSerialEnumerator::getServiceDetailsOSX( io_object_t service, QextPortInfo* portInfo ) -{ - bool retval = true; - CFTypeRef bsdPathAsCFString = NULL; - CFTypeRef productNameAsCFString = NULL; - CFTypeRef vendorIdAsCFNumber = NULL; - CFTypeRef productIdAsCFNumber = NULL; - // check the name of the modem's callout device - bsdPathAsCFString = IORegistryEntryCreateCFProperty(service, CFSTR(kIOCalloutDeviceKey), - kCFAllocatorDefault, 0); - - // wander up the hierarchy until we find the level that can give us the - // vendor/product IDs and the product name, if available - io_registry_entry_t parent; - kern_return_t kernResult = IORegistryEntryGetParentEntry(service, kIOServicePlane, &parent); - while( kernResult == KERN_SUCCESS && !vendorIdAsCFNumber && !productIdAsCFNumber ) - { - if(!productNameAsCFString) - productNameAsCFString = IORegistryEntrySearchCFProperty(parent, - kIOServicePlane, - CFSTR("Product Name"), - kCFAllocatorDefault, 0); - vendorIdAsCFNumber = IORegistryEntrySearchCFProperty(parent, - kIOServicePlane, - CFSTR(kUSBVendorID), - kCFAllocatorDefault, 0); - productIdAsCFNumber = IORegistryEntrySearchCFProperty(parent, - kIOServicePlane, - CFSTR(kUSBProductID), - kCFAllocatorDefault, 0); - io_registry_entry_t oldparent = parent; - kernResult = IORegistryEntryGetParentEntry(parent, kIOServicePlane, &parent); - IOObjectRelease(oldparent); - } - - io_string_t ioPathName; - IORegistryEntryGetPath( service, kIOServicePlane, ioPathName ); - portInfo->physName = ioPathName; - - if( bsdPathAsCFString ) - { - char path[MAXPATHLEN]; - if( CFStringGetCString((CFStringRef)bsdPathAsCFString, path, - PATH_MAX, kCFStringEncodingUTF8) ) - portInfo->portName = path; - CFRelease(bsdPathAsCFString); - } - - if(productNameAsCFString) - { - char productName[MAXPATHLEN]; - if( CFStringGetCString((CFStringRef)productNameAsCFString, productName, - PATH_MAX, kCFStringEncodingUTF8) ) - portInfo->friendName = productName; - CFRelease(productNameAsCFString); - } - - if(vendorIdAsCFNumber) - { - SInt32 vID; - if(CFNumberGetValue((CFNumberRef)vendorIdAsCFNumber, kCFNumberSInt32Type, &vID)) - portInfo->vendorID = vID; - CFRelease(vendorIdAsCFNumber); - } - - if(productIdAsCFNumber) - { - SInt32 pID; - if(CFNumberGetValue((CFNumberRef)productIdAsCFNumber, kCFNumberSInt32Type, &pID)) - portInfo->productID = pID; - CFRelease(productIdAsCFNumber); - } - IOObjectRelease(service); - return retval; -} - -// IOKit callbacks registered via setupNotifications() -void deviceDiscoveredCallbackOSX( void *ctxt, io_iterator_t serialPortIterator ); -void deviceTerminatedCallbackOSX( void *ctxt, io_iterator_t serialPortIterator ); - -void deviceDiscoveredCallbackOSX( void *ctxt, io_iterator_t serialPortIterator ) -{ - QextSerialEnumerator* qese = (QextSerialEnumerator*)ctxt; - io_object_t serialService; - while ((serialService = IOIteratorNext(serialPortIterator))) - qese->onDeviceDiscoveredOSX(serialService); -} - -void deviceTerminatedCallbackOSX( void *ctxt, io_iterator_t serialPortIterator ) -{ - QextSerialEnumerator* qese = (QextSerialEnumerator*)ctxt; - io_object_t serialService; - while ((serialService = IOIteratorNext(serialPortIterator))) - qese->onDeviceTerminatedOSX(serialService); -} - -/* - A device has been discovered via IOKit. - Create a QextPortInfo if possible, and emit the signal indicating that we've found it. -*/ -void QextSerialEnumerator::onDeviceDiscoveredOSX( io_object_t service ) -{ - QextPortInfo info; - info.vendorID = 0; - info.productID = 0; - if( getServiceDetailsOSX( service, &info ) ) - emit deviceDiscovered( info ); -} - -/* - Notification via IOKit that a device has been removed. - Create a QextPortInfo if possible, and emit the signal indicating that it's gone. -*/ -void QextSerialEnumerator::onDeviceTerminatedOSX( io_object_t service ) -{ - QextPortInfo info; - info.vendorID = 0; - info.productID = 0; - if( getServiceDetailsOSX( service, &info ) ) - emit deviceRemoved( info ); -} - -/* - Create matching dictionaries for the devices we want to get notifications for, - and add them to the current run loop. Invoke the callbacks that will be responding - to these notifications once to arm them, and discover any devices that - are currently connected at the time notifications are setup. -*/ -void QextSerialEnumerator::setUpNotifications( ) -{ - kern_return_t kernResult; - mach_port_t masterPort; - CFRunLoopSourceRef notificationRunLoopSource; - CFMutableDictionaryRef classesToMatch; - CFMutableDictionaryRef cdcClassesToMatch; - io_iterator_t portIterator; - - kernResult = IOMasterPort(MACH_PORT_NULL, &masterPort); - if (KERN_SUCCESS != kernResult) { - qDebug() << "IOMasterPort returned:" << kernResult; - return; - } - - classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue); - if (classesToMatch == NULL) - qDebug("IOServiceMatching returned a NULL dictionary."); - else - CFDictionarySetValue(classesToMatch, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDAllTypes)); - - if( !(cdcClassesToMatch = IOServiceNameMatching("AppleUSBCDC") ) ) { - qWarning("couldn't create cdc matching dict"); - return; - } - - // Retain an additional reference since each call to IOServiceAddMatchingNotification consumes one. - classesToMatch = (CFMutableDictionaryRef) CFRetain(classesToMatch); - cdcClassesToMatch = (CFMutableDictionaryRef) CFRetain(cdcClassesToMatch); - - notificationPortRef = IONotificationPortCreate(masterPort); - if(notificationPortRef == NULL) { - qDebug("IONotificationPortCreate return a NULL IONotificationPortRef."); - return; - } - - notificationRunLoopSource = IONotificationPortGetRunLoopSource(notificationPortRef); - if (notificationRunLoopSource == NULL) { - qDebug("IONotificationPortGetRunLoopSource returned NULL CFRunLoopSourceRef."); - return; - } - - CFRunLoopAddSource(CFRunLoopGetCurrent(), notificationRunLoopSource, kCFRunLoopDefaultMode); - - kernResult = IOServiceAddMatchingNotification(notificationPortRef, kIOMatchedNotification, classesToMatch, - deviceDiscoveredCallbackOSX, this, &portIterator); - if (kernResult != KERN_SUCCESS) { - qDebug() << "IOServiceAddMatchingNotification return:" << kernResult; - return; - } - - // arm the callback, and grab any devices that are already connected - deviceDiscoveredCallbackOSX( this, portIterator ); - - kernResult = IOServiceAddMatchingNotification(notificationPortRef, kIOMatchedNotification, cdcClassesToMatch, - deviceDiscoveredCallbackOSX, this, &portIterator); - if (kernResult != KERN_SUCCESS) { - qDebug() << "IOServiceAddMatchingNotification return:" << kernResult; - return; - } - - // arm the callback, and grab any devices that are already connected - deviceDiscoveredCallbackOSX( this, portIterator ); - - kernResult = IOServiceAddMatchingNotification(notificationPortRef, kIOTerminatedNotification, classesToMatch, - deviceTerminatedCallbackOSX, this, &portIterator); - if (kernResult != KERN_SUCCESS) { - qDebug() << "IOServiceAddMatchingNotification return:" << kernResult; - return; - } - - // arm the callback, and clear any devices that are terminated - deviceTerminatedCallbackOSX( this, portIterator ); - - kernResult = IOServiceAddMatchingNotification(notificationPortRef, kIOTerminatedNotification, cdcClassesToMatch, - deviceTerminatedCallbackOSX, this, &portIterator); - if (kernResult != KERN_SUCCESS) { - qDebug() << "IOServiceAddMatchingNotification return:" << kernResult; - return; - } - - // arm the callback, and clear any devices that are terminated - deviceTerminatedCallbackOSX( this, portIterator ); -} - diff --git a/libs/qextserialport/qextserialenumerator_unix.cpp b/libs/qextserialport/qextserialenumerator_unix.cpp deleted file mode 100644 index 08b97412468dcb46b8b2d982e1865e8857341054..0000000000000000000000000000000000000000 --- a/libs/qextserialport/qextserialenumerator_unix.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "qextserialenumerator.h" -#include -#include -#include -#include - -QextSerialEnumerator::QextSerialEnumerator( ) -{ - if( !QMetaType::isRegistered( QMetaType::type("QextPortInfo") ) ) - qRegisterMetaType("QextPortInfo"); -} - -QextSerialEnumerator::~QextSerialEnumerator( ) -{ -} - -QList QextSerialEnumerator::getPorts() -{ - QList infoList; -#ifdef Q_OS_LINUX - QStringList portNamePrefixes, portNameList; - portNamePrefixes << "ttyS*"; // list normal serial ports first - - QDir dir("/dev"); - portNameList = dir.entryList(portNamePrefixes, (QDir::System | QDir::Files), QDir::Name); - - // remove the values which are not serial ports for e.g. /dev/ttysa - for (int i = 0; i < portNameList.size(); i++) { - bool ok; - QString current = portNameList.at(i); - // remove the ttyS part, and check, if the other part is a number - current.remove(0,4).toInt(&ok, 10); - if (!ok) { - portNameList.removeAt(i); - i--; - } - } - - // get the non standard serial ports names - // (USB-serial, bluetooth-serial, 18F PICs, and so on) - // if you know an other name prefix for serial ports please let us know - portNamePrefixes.clear(); - portNamePrefixes << "ttyACM*" << "ttyUSB*" << "rfcomm*"; - portNameList.append(dir.entryList(portNamePrefixes, (QDir::System | QDir::Files), QDir::Name)); - - foreach (QString str , portNameList) { - QextPortInfo inf; - inf.physName = "/dev/"+str; - inf.portName = str; - - if (str.contains("ttyS")) { - inf.friendName = "Serial port "+str.remove(0, 4); - } - else if (str.contains("ttyUSB")) { - inf.friendName = "USB-serial adapter "+str.remove(0, 6); - } - else if (str.contains("rfcomm")) { - inf.friendName = "Bluetooth-serial adapter "+str.remove(0, 6); - } - inf.enumName = "/dev"; // is there a more helpful name for this? - infoList.append(inf); - } -#else - qCritical("Enumeration for POSIX systems (except Linux) is not implemented yet."); -#endif - return infoList; -} - -void QextSerialEnumerator::setUpNotifications( ) -{ - qCritical("Notifications for *Nix/FreeBSD are not implemented yet"); -} diff --git a/libs/qextserialport/qextserialenumerator_win.cpp b/libs/qextserialport/qextserialenumerator_win.cpp deleted file mode 100644 index 1f205acc36a162b63b267fd5154e83b0e9f968cc..0000000000000000000000000000000000000000 --- a/libs/qextserialport/qextserialenumerator_win.cpp +++ /dev/null @@ -1,222 +0,0 @@ - - - -#include "qextserialenumerator.h" -#include -#include - -#include -#include -//#include "qextserialport.h" -#include -#ifdef Q_OS_WIN -#ifndef _MSC_VER -#include -#include -#include -#endif -#endif - -QextSerialEnumerator::QextSerialEnumerator( ) -{ - if( !QMetaType::isRegistered( QMetaType::type("QextPortInfo") ) ) - qRegisterMetaType("QextPortInfo"); -#if (defined QT_GUI_LIB) - notificationWidget = 0; -#endif // Q_OS_WIN -} - -QextSerialEnumerator::~QextSerialEnumerator( ) -{ -#if (defined QT_GUI_LIB) - if( notificationWidget ) - delete notificationWidget; -#endif -} - - - -// see http://msdn.microsoft.com/en-us/library/ms791134.aspx for list of GUID classes -#ifndef GUID_DEVCLASS_PORTS - DEFINE_GUID(GUID_DEVCLASS_PORTS, 0x4D36E978, 0xE325, 0x11CE, 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 ); -#endif - -/* Gordon Schumacher's macros for TCHAR -> QString conversions and vice versa */ -#ifdef UNICODE - #define QStringToTCHAR(x) (wchar_t*) x.utf16() - #define PQStringToTCHAR(x) (wchar_t*) x->utf16() - #define TCHARToQString(x) QString::fromUtf16((ushort*)(x)) - #define TCHARToQStringN(x,y) QString::fromUtf16((ushort*)(x),(y)) -#else - #define QStringToTCHAR(x) x.local8Bit().constData() - #define PQStringToTCHAR(x) x->local8Bit().constData() - #define TCHARToQString(x) QString::fromLocal8Bit((x)) - #define TCHARToQStringN(x,y) QString::fromLocal8Bit((x),(y)) -#endif /*UNICODE*/ - - -//static -QString QextSerialEnumerator::getRegKeyValue(HKEY key, LPCTSTR property) -{ - DWORD size = 0; - DWORD type; - RegQueryValueEx(key, property, NULL, NULL, NULL, & size); - BYTE* buff = new BYTE[size]; - QString result; - if( RegQueryValueEx(key, property, NULL, &type, buff, & size) == ERROR_SUCCESS ) - result = TCHARToQString(buff); - RegCloseKey(key); - delete [] buff; - return result; -} - -//static -QString QextSerialEnumerator::getDeviceProperty(HDEVINFO devInfo, PSP_DEVINFO_DATA devData, DWORD property) -{ - DWORD buffSize = 0; - SetupDiGetDeviceRegistryProperty(devInfo, devData, property, NULL, NULL, 0, & buffSize); - BYTE* buff = new BYTE[buffSize]; - SetupDiGetDeviceRegistryProperty(devInfo, devData, property, NULL, buff, buffSize, NULL); - QString result = TCHARToQString(buff); - delete [] buff; - return result; -} - -QList QextSerialEnumerator::getPorts() -{ - QList ports; - enumerateDevicesWin(GUID_DEVCLASS_PORTS, &ports); - return ports; -} - -void QextSerialEnumerator::enumerateDevicesWin( const GUID & guid, QList* infoList ) -{ - HDEVINFO devInfo; - if( (devInfo = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT)) != INVALID_HANDLE_VALUE) - { - SP_DEVINFO_DATA devInfoData; - devInfoData.cbSize = sizeof(SP_DEVINFO_DATA); - for(int i = 0; SetupDiEnumDeviceInfo(devInfo, i, &devInfoData); i++) - { - QextPortInfo info; - info.productID = info.vendorID = 0; - getDeviceDetailsWin( &info, devInfo, &devInfoData ); - infoList->append(info); - } - SetupDiDestroyDeviceInfoList(devInfo); - } -} - -#ifdef QT_GUI_LIB -bool QextSerialRegistrationWidget::winEvent( MSG* message, long* result ) -{ - if ( message->message == WM_DEVICECHANGE ) { - qese->onDeviceChangeWin( message->wParam, message->lParam ); - *result = 1; - return true; - } - return false; -} -#endif - -void QextSerialEnumerator::setUpNotifications( ) -{ - #ifdef QT_GUI_LIB - if(notificationWidget) - return; - notificationWidget = new QextSerialRegistrationWidget(this); - - DEV_BROADCAST_DEVICEINTERFACE dbh; - ZeroMemory(&dbh, sizeof(dbh)); - dbh.dbcc_size = sizeof(dbh); - dbh.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; - CopyMemory(&dbh.dbcc_classguid, &GUID_DEVCLASS_PORTS, sizeof(GUID)); - if( RegisterDeviceNotification( notificationWidget->winId( ), &dbh, DEVICE_NOTIFY_WINDOW_HANDLE ) == NULL) - qWarning() << "RegisterDeviceNotification failed:" << GetLastError(); - // setting up notifications doesn't tell us about devices already connected - // so get those manually - foreach( QextPortInfo port, getPorts() ) - emit deviceDiscovered( port ); - #else - qWarning("QextSerialEnumerator: GUI not enabled - can't register for device notifications."); - #endif // QT_GUI_LIB -} - -LRESULT QextSerialEnumerator::onDeviceChangeWin( WPARAM wParam, LPARAM lParam ) -{ - if ( DBT_DEVICEARRIVAL == wParam || DBT_DEVICEREMOVECOMPLETE == wParam ) - { - PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam; - if( pHdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE ) - { - PDEV_BROADCAST_DEVICEINTERFACE pDevInf = (PDEV_BROADCAST_DEVICEINTERFACE)pHdr; - // delimiters are different across APIs...change to backslash. ugh. - QString deviceID = TCHARToQString(pDevInf->dbcc_name).toUpper().replace("#", "\\"); - - matchAndDispatchChangedDevice(deviceID, GUID_DEVCLASS_PORTS, wParam); - } - } - return 0; -} - -bool QextSerialEnumerator::matchAndDispatchChangedDevice(const QString & deviceID, const GUID & guid, WPARAM wParam) -{ - bool rv = false; - DWORD dwFlag = (DBT_DEVICEARRIVAL == wParam) ? DIGCF_PRESENT : DIGCF_ALLCLASSES; - HDEVINFO devInfo; - if( (devInfo = SetupDiGetClassDevs(&guid,NULL,NULL,dwFlag)) != INVALID_HANDLE_VALUE ) - { - SP_DEVINFO_DATA spDevInfoData; - spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA); - for(int i=0; SetupDiEnumDeviceInfo(devInfo, i, &spDevInfoData); i++) - { - DWORD nSize=0 ; - TCHAR buf[MAX_PATH]; - if ( SetupDiGetDeviceInstanceId(devInfo, &spDevInfoData, buf, MAX_PATH, &nSize) && - deviceID.contains(TCHARToQString(buf))) // we found a match - { - rv = true; - QextPortInfo info; - info.productID = info.vendorID = 0; - getDeviceDetailsWin( &info, devInfo, &spDevInfoData, wParam ); - if( wParam == DBT_DEVICEARRIVAL ) - emit deviceDiscovered(info); - else if( wParam == DBT_DEVICEREMOVECOMPLETE ) - emit deviceRemoved(info); - break; - } - } - SetupDiDestroyDeviceInfoList(devInfo); - } - return rv; -} - -bool QextSerialEnumerator::getDeviceDetailsWin( QextPortInfo* portInfo, HDEVINFO devInfo, PSP_DEVINFO_DATA devData, WPARAM wParam ) -{ - portInfo->friendName = getDeviceProperty(devInfo, devData, SPDRP_FRIENDLYNAME); - if( wParam == DBT_DEVICEARRIVAL) - portInfo->physName = getDeviceProperty(devInfo, devData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME); - portInfo->enumName = getDeviceProperty(devInfo, devData, SPDRP_ENUMERATOR_NAME); - QString hardwareIDs = getDeviceProperty(devInfo, devData, SPDRP_HARDWAREID); - HKEY devKey = SetupDiOpenDevRegKey(devInfo, devData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); - - QRegExp rx("^COM(\\d+)"); - QString fullName(getRegKeyValue(devKey, TEXT("PortName"))); - if(fullName.contains(rx)) { - int portnum = rx.cap(1).toInt(); - if(portnum > 9) // COM ports greater than 9 need \\.\ prepended - fullName.prepend("\\\\.\\"); - } - - portInfo->portName = fullName; - QRegExp idRx("VID_(\\w+)&PID_(\\w+)"); - if( hardwareIDs.toUpper().contains(idRx) ) - { - bool dummy; - portInfo->vendorID = idRx.cap(1).toInt(&dummy, 16); - portInfo->productID = idRx.cap(2).toInt(&dummy, 16); - //qDebug() << "got vid:" << vid << "pid:" << pid; - } - return true; -} -