Skip to content

Commit

Permalink
Further protection in windows event message handling
Browse files Browse the repository at this point in the history
Refs #20386
  • Loading branch information
nyalldawson committed Nov 9, 2018
1 parent d6aa46c commit df9307b
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 4 deletions.
24 changes: 20 additions & 4 deletions src/native/win/qgswinnative.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ QgsNative::NotificationResult QgsWinNative::showDesktopNotification( const QStri
bool QgsWinNativeEventFilter::nativeEventFilter( const QByteArray &eventType, void *message, long * ) bool QgsWinNativeEventFilter::nativeEventFilter( const QByteArray &eventType, void *message, long * )
{ {
static const QByteArray sWindowsGenericMSG{ "windows_generic_MSG" }; static const QByteArray sWindowsGenericMSG{ "windows_generic_MSG" };
if ( eventType != sWindowsGenericMSG ) if ( !message || eventType != sWindowsGenericMSG )
return false; return false;


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

unsigned long deviceType = reinterpret_cast<DEV_BROADCAST_HDR *>( pWindowsMessage->lParam )->dbch_devicetype;
if ( deviceType == DBT_DEVTYP_VOLUME ) 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 // 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; std::vector< QString > drives;
char driveName[] = "A:/"; char driveName[] = "A:/";
unitmask &= 0x3ffffff; unitmask &= 0x3ffffff;
Expand All @@ -199,6 +214,7 @@ bool QgsWinNativeEventFilter::nativeEventFilter( const QByteArray &eventType, vo
{ {
emit usbStorageNotification( QStringLiteral( "%1:/" ).arg( drive ), wParam == DBT_DEVICEARRIVAL ); emit usbStorageNotification( QStringLiteral( "%1:/" ).arg( drive ), wParam == DBT_DEVICEARRIVAL );
} }
return false;
} }
} }
return false; return false;
Expand Down
4 changes: 4 additions & 0 deletions src/native/win/qgswinnative.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ class QgsWinNativeEventFilter : public QObject, public QAbstractNativeEventFilte
signals: signals:


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

private:

quintptr mLastMessageHash = 0;
}; };




Expand Down

0 comments on commit df9307b

Please sign in to comment.