@@ -166,7 +166,7 @@ QgsNative::NotificationResult QgsWinNative::showDesktopNotification( const QStri
166
166
bool QgsWinNativeEventFilter::nativeEventFilter ( const QByteArray &eventType, void *message, long * )
167
167
{
168
168
static const QByteArray sWindowsGenericMSG { " windows_generic_MSG" };
169
- if ( eventType != sWindowsGenericMSG )
169
+ if ( !message || eventType != sWindowsGenericMSG )
170
170
return false ;
171
171
172
172
MSG *pWindowsMessage = static_cast <MSG *>( message );
@@ -178,12 +178,27 @@ bool QgsWinNativeEventFilter::nativeEventFilter( const QByteArray &eventType, vo
178
178
unsigned int wParam = pWindowsMessage->wParam ;
179
179
if ( wParam == DBT_DEVICEARRIVAL || wParam == DBT_DEVICEREMOVECOMPLETE )
180
180
{
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 ;
183
185
if ( deviceType == DBT_DEVTYP_VOLUME )
184
186
{
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
+
185
200
// 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 ;
187
202
std::vector< QString > drives;
188
203
char driveName[] = " A:/" ;
189
204
unitmask &= 0x3ffffff ;
@@ -199,6 +214,7 @@ bool QgsWinNativeEventFilter::nativeEventFilter( const QByteArray &eventType, vo
199
214
{
200
215
emit usbStorageNotification ( QStringLiteral ( " %1:/" ).arg ( drive ), wParam == DBT_DEVICEARRIVAL );
201
216
}
217
+ return false ;
202
218
}
203
219
}
204
220
return false ;
0 commit comments