@@ -166,7 +166,7 @@ QgsNative::NotificationResult QgsWinNative::showDesktopNotification( const QStri
166166bool 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 ;
0 commit comments