Skip to content
Permalink
Browse files

Further protection in windows event message handling

Refs #20386

(cherry picked from commit df9307b)
  • Loading branch information
nyalldawson committed Nov 9, 2018
1 parent 75c4a00 commit 2b4dc9250eb13668f7efab07ea45f7c379aa4d6a
Showing with 24 additions and 4 deletions.
  1. +20 −4 src/native/win/qgswinnative.cpp
  2. +4 −0 src/native/win/qgswinnative.h
@@ -166,7 +166,7 @@ QgsNative::NotificationResult QgsWinNative::showDesktopNotification( const QStri
bool QgsWinNativeEventFilter::nativeEventFilter( const QByteArray &eventType, void *message, long * )
{
static const QByteArray sWindowsGenericMSG{ "windows_generic_MSG" };
if ( eventType != sWindowsGenericMSG )
if ( !message || eventType != sWindowsGenericMSG )
return false;

MSG *pWindowsMessage = static_cast<MSG *>( message );
@@ -178,12 +178,27 @@ bool QgsWinNativeEventFilter::nativeEventFilter( const QByteArray &eventType, vo
unsigned int wParam = pWindowsMessage->wParam;
if ( wParam == DBT_DEVICEARRIVAL || wParam == DBT_DEVICEREMOVECOMPLETE )
{
long lParam = pWindowsMessage->lParam;
unsigned long deviceType = reinterpret_cast<DEV_BROADCAST_HDR *>( lParam )->dbch_devicetype;
if ( !pWindowsMessage->lParam )
return false;

unsigned long deviceType = reinterpret_cast<DEV_BROADCAST_HDR *>( pWindowsMessage->lParam )->dbch_devicetype;
if ( deviceType == DBT_DEVTYP_VOLUME )
{
const DEV_BROADCAST_VOLUME *broadcastVolume = reinterpret_cast<const DEV_BROADCAST_VOLUME *>( pWindowsMessage->lParam );
if ( !broadcastVolume )
return false;

// Seen in qfilesystemwatcher_win.cpp from Qt:
// WM_DEVICECHANGE/DBT_DEVTYP_VOLUME messages are sent to all toplevel windows. Compare a hash value to ensure
// it is handled only once.
const quintptr newHash = reinterpret_cast<quintptr>( broadcastVolume ) + pWindowsMessage->wParam
+ quintptr( broadcastVolume->dbcv_flags ) + quintptr( broadcastVolume->dbcv_unitmask );
if ( newHash == mLastMessageHash )
return false;
mLastMessageHash = newHash;

// need to handle disks with multiple partitions -- these are given by a single event
unsigned long unitmask = reinterpret_cast<DEV_BROADCAST_VOLUME *>( lParam )->dbcv_unitmask;
unsigned long unitmask = broadcastVolume->dbcv_unitmask;
std::vector< QString > drives;
char driveName[] = "A:/";
unitmask &= 0x3ffffff;
@@ -199,6 +214,7 @@ bool QgsWinNativeEventFilter::nativeEventFilter( const QByteArray &eventType, vo
{
emit usbStorageNotification( QStringLiteral( "%1:/" ).arg( drive ), wParam == DBT_DEVICEARRIVAL );
}
return false;
}
}
return false;
@@ -40,6 +40,10 @@ class QgsWinNativeEventFilter : public QObject, public QAbstractNativeEventFilte
signals:

void usbStorageNotification( const QString &path, bool inserted );

private:

quintptr mLastMessageHash = 0;
};


0 comments on commit 2b4dc92

Please sign in to comment.
You can’t perform that action at this time.