Skip to content

Commit df9307b

Browse files
committedNov 9, 2018
Further protection in windows event message handling
Refs #20386
1 parent d6aa46c commit df9307b

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed
 

‎src/native/win/qgswinnative.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ QgsNative::NotificationResult QgsWinNative::showDesktopNotification( const QStri
166166
bool QgsWinNativeEventFilter::nativeEventFilter( const QByteArray &eventType, void *message, long * )
167167
{
168168
static const QByteArray sWindowsGenericMSG{ "windows_generic_MSG" };
169-
if ( eventType != sWindowsGenericMSG )
169+
if ( !message || eventType != sWindowsGenericMSG )
170170
return false;
171171

172172
MSG *pWindowsMessage = static_cast<MSG *>( message );
@@ -178,12 +178,27 @@ bool QgsWinNativeEventFilter::nativeEventFilter( const QByteArray &eventType, vo
178178
unsigned int wParam = pWindowsMessage->wParam;
179179
if ( wParam == DBT_DEVICEARRIVAL || wParam == DBT_DEVICEREMOVECOMPLETE )
180180
{
181-
long lParam = pWindowsMessage->lParam;
182-
unsigned long deviceType = reinterpret_cast<DEV_BROADCAST_HDR *>( lParam )->dbch_devicetype;
181+
if ( !pWindowsMessage->lParam )
182+
return false;
183+
184+
unsigned long deviceType = reinterpret_cast<DEV_BROADCAST_HDR *>( pWindowsMessage->lParam )->dbch_devicetype;
183185
if ( deviceType == DBT_DEVTYP_VOLUME )
184186
{
187+
const DEV_BROADCAST_VOLUME *broadcastVolume = reinterpret_cast<const DEV_BROADCAST_VOLUME *>( pWindowsMessage->lParam );
188+
if ( !broadcastVolume )
189+
return false;
190+
191+
// Seen in qfilesystemwatcher_win.cpp from Qt:
192+
// WM_DEVICECHANGE/DBT_DEVTYP_VOLUME messages are sent to all toplevel windows. Compare a hash value to ensure
193+
// it is handled only once.
194+
const quintptr newHash = reinterpret_cast<quintptr>( broadcastVolume ) + pWindowsMessage->wParam
195+
+ quintptr( broadcastVolume->dbcv_flags ) + quintptr( broadcastVolume->dbcv_unitmask );
196+
if ( newHash == mLastMessageHash )
197+
return false;
198+
mLastMessageHash = newHash;
199+
185200
// need to handle disks with multiple partitions -- these are given by a single event
186-
unsigned long unitmask = reinterpret_cast<DEV_BROADCAST_VOLUME *>( lParam )->dbcv_unitmask;
201+
unsigned long unitmask = broadcastVolume->dbcv_unitmask;
187202
std::vector< QString > drives;
188203
char driveName[] = "A:/";
189204
unitmask &= 0x3ffffff;
@@ -199,6 +214,7 @@ bool QgsWinNativeEventFilter::nativeEventFilter( const QByteArray &eventType, vo
199214
{
200215
emit usbStorageNotification( QStringLiteral( "%1:/" ).arg( drive ), wParam == DBT_DEVICEARRIVAL );
201216
}
217+
return false;
202218
}
203219
}
204220
return false;

‎src/native/win/qgswinnative.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ class QgsWinNativeEventFilter : public QObject, public QAbstractNativeEventFilte
4040
signals:
4141

4242
void usbStorageNotification( const QString &path, bool inserted );
43+
44+
private:
45+
46+
quintptr mLastMessageHash = 0;
4347
};
4448

4549

0 commit comments

Comments
 (0)
Please sign in to comment.