1-
1+ using System . ComponentModel ;
22using System . Runtime . InteropServices ;
33using System . Windows . Interop ;
44
88
99namespace MarvinsAIRARefactored . Components ;
1010
11- public sealed class HidHotplugMonitor : IDisposable
11+ public sealed class HidHotPlugMonitor : IDisposable
1212{
1313 private HwndSource ? _hwndSource ;
1414 private HDEVNOTIFY _deviceNotifyHandle ;
@@ -22,10 +22,14 @@ public void Initialize()
2222 {
2323 var app = App . Instance ! ;
2424
25+ app . Logger . WriteLine ( "[HidHotPlugMonitor] Initialize >>>" ) ;
26+
2527 app . MainWindow . SourceInitialized += ( _ , __ ) =>
2628 {
2729 var hwnd = new WindowInteropHelper ( app . MainWindow ) . Handle ;
2830
31+ app . Logger . WriteLine ( $ "[HidHotPlugMonitor] SourceInitialized hwnd=0x{ hwnd . ToInt64 ( ) : X} " ) ;
32+
2933 SetupForHwnd ( hwnd ) ;
3034 } ;
3135
@@ -37,30 +41,62 @@ public void Initialize()
3741 {
3842 var hwnd = new WindowInteropHelper ( app . MainWindow ) . EnsureHandle ( ) ;
3943
44+ app . Logger . WriteLine ( $ "[HidHotPlugMonitor] EnsureHandle hwnd=0x{ hwnd . ToInt64 ( ) : X} " ) ;
45+
4046 SetupForHwnd ( hwnd ) ;
4147 } ) ;
4248
4349 app . MainWindow . Closed += ( _ , __ ) => Dispose ( ) ;
50+
51+ app . Logger . WriteLine ( "[HidHotPlugMonitor] <<< Initialize" ) ;
4452 }
4553
4654 public void Dispose ( )
4755 {
56+ var app = App . Instance ! ;
57+
58+ app . Logger . WriteLine ( "[HidHotPlugMonitor] Dispose >>>" ) ;
59+
4860 if ( _deviceNotifyHandle != HDEVNOTIFY . Null )
4961 {
50- _ = PInvoke . UnregisterDeviceNotification ( _deviceNotifyHandle ) ;
62+ var unregisterSucceeded = PInvoke . UnregisterDeviceNotification ( _deviceNotifyHandle ) ;
63+
64+ if ( unregisterSucceeded )
65+ {
66+ app . Logger . WriteLine ( "[HidHotPlugMonitor] UnregisterDeviceNotification succeeded." ) ;
67+ }
68+ else
69+ {
70+ var lastError = Marshal . GetLastPInvokeError ( ) ;
71+ var lastErrorMessage = new Win32Exception ( lastError ) . Message ;
72+
73+ app . Logger . WriteLine ( $ "[HidHotPlugMonitor] UnregisterDeviceNotification failed. Error={ lastError } ({ lastErrorMessage } )" ) ;
74+ }
5175
5276 _deviceNotifyHandle = HDEVNOTIFY . Null ;
5377 }
78+ else
79+ {
80+ app . Logger . WriteLine ( "[HidHotPlugMonitor] No device notification handle to unregister." ) ;
81+ }
5482
5583 _hwndSource ? . RemoveHook ( WndProc ) ;
5684
5785 _hwndSource = null ;
5886
5987 _debounceTimer ? . Dispose ( ) ;
88+ _debounceTimer = null ;
89+
90+ app . Logger . WriteLine ( "[HidHotPlugMonitor] <<< Dispose" ) ;
6091 }
6192
6293 private unsafe void RegisterForHidNotifications ( IntPtr hwnd )
6394 {
95+ var app = App . Instance ! ;
96+
97+ app . Logger . WriteLine ( "[HidHotPlugMonitor] RegisterForHidNotifications >>>" ) ;
98+ app . Logger . WriteLine ( $ "[HidHotPlugMonitor] Registering HID notifications for hwnd=0x{ hwnd . ToInt64 ( ) : X} , interfaceGuid={ _hidInterfaceGuid } " ) ;
99+
64100 var deviceBroadcastInterface = new DEV_BROADCAST_DEVICEINTERFACE_W
65101 {
66102 dbcc_size = ( uint ) sizeof ( DEV_BROADCAST_DEVICEINTERFACE_W ) ,
@@ -72,46 +108,102 @@ private unsafe void RegisterForHidNotifications( IntPtr hwnd )
72108 new HANDLE ( hwnd ) ,
73109 & deviceBroadcastInterface ,
74110 REGISTER_NOTIFICATION_FLAGS . DEVICE_NOTIFY_WINDOW_HANDLE ) ;
111+
112+ if ( _deviceNotifyHandle == HDEVNOTIFY . Null )
113+ {
114+ var lastError = Marshal . GetLastPInvokeError ( ) ;
115+ var lastErrorMessage = new Win32Exception ( lastError ) . Message ;
116+
117+ app . Logger . WriteLine ( $ "[HidHotPlugMonitor] RegisterDeviceNotification failed. Error={ lastError } ({ lastErrorMessage } )" ) ;
118+ }
119+ else
120+ {
121+ app . Logger . WriteLine ( "[HidHotPlugMonitor] RegisterDeviceNotification succeeded." ) ;
122+ }
123+
124+ app . Logger . WriteLine ( "[HidHotPlugMonitor] <<< RegisterForHidNotifications" ) ;
75125 }
76126
77127 private void SetupForHwnd ( IntPtr hwnd )
78128 {
79- if ( ( hwnd == IntPtr . Zero ) || ( _hwndSource is not null ) )
129+ var app = App . Instance ! ;
130+
131+ app . Logger . WriteLine ( "[HidHotPlugMonitor] SetupForHwnd >>>" ) ;
132+
133+ if ( hwnd == IntPtr . Zero )
80134 {
135+ app . Logger . WriteLine ( "[HidHotPlugMonitor] SetupForHwnd skipped because hwnd is zero." ) ;
136+ app . Logger . WriteLine ( "[HidHotPlugMonitor] <<< SetupForHwnd" ) ;
137+
138+ return ;
139+ }
140+
141+ if ( _hwndSource is not null )
142+ {
143+ app . Logger . WriteLine ( $ "[HidHotPlugMonitor] SetupForHwnd skipped because HwndSource already exists. hwnd=0x{ hwnd . ToInt64 ( ) : X} " ) ;
144+ app . Logger . WriteLine ( "[HidHotPlugMonitor] <<< SetupForHwnd" ) ;
145+
81146 return ;
82147 }
83148
84149 _hwndSource = HwndSource . FromHwnd ( hwnd ) ;
85- _hwndSource ? . AddHook ( WndProc ) ;
150+
151+ if ( _hwndSource is null )
152+ {
153+ app . Logger . WriteLine ( $ "[HidHotPlugMonitor] HwndSource.FromHwnd returned null. hwnd=0x{ hwnd . ToInt64 ( ) : X} " ) ;
154+ app . Logger . WriteLine ( "[HidHotPlugMonitor] <<< SetupForHwnd" ) ;
155+
156+ return ;
157+ }
158+
159+ _hwndSource . AddHook ( WndProc ) ;
160+
161+ app . Logger . WriteLine ( $ "[HidHotPlugMonitor] WndProc hook added. hwnd=0x{ hwnd . ToInt64 ( ) : X} " ) ;
86162
87163 RegisterForHidNotifications ( hwnd ) ;
88164
89165 if ( _debounceTimer is null )
90166 {
91167 _debounceTimer = new System . Timers . Timer ( 2000 ) { AutoReset = false } ;
92168
93- _debounceTimer . Elapsed += ( _ , __ ) => DeviceListMightHaveChanged ? . Invoke ( this , EventArgs . Empty ) ;
169+ _debounceTimer . Elapsed += ( _ , __ ) =>
170+ {
171+ app . Logger . WriteLine ( "[HidHotPlugMonitor] Device change debounce elapsed. Raising DeviceListMightHaveChanged." ) ;
172+
173+ DeviceListMightHaveChanged ? . Invoke ( this , EventArgs . Empty ) ;
174+ } ;
175+
176+ app . Logger . WriteLine ( "[HidHotPlugMonitor] Device change debounce timer created." ) ;
94177 }
178+
179+ app . Logger . WriteLine ( "[HidHotPlugMonitor] <<< SetupForHwnd" ) ;
95180 }
96181
97182 private IntPtr WndProc ( IntPtr hwnd , int msg , IntPtr wParam , IntPtr lParam , ref bool handled )
98183 {
99184 if ( msg == PInvoke . WM_DEVICECHANGE )
100185 {
186+ var app = App . Instance ! ;
101187 var eventType = wParam . ToInt32 ( ) ;
102188
189+ app . Logger . WriteLine ( $ "[HidHotPlugMonitor] WM_DEVICECHANGE eventType=0x{ eventType : X} , lParam=0x{ lParam . ToInt64 ( ) : X} " ) ;
190+
103191 if ( eventType == PInvoke . DBT_DEVICEARRIVAL || eventType == PInvoke . DBT_DEVICEREMOVECOMPLETE )
104192 {
105193 _debounceTimer ? . Stop ( ) ;
106194 _debounceTimer ? . Start ( ) ;
107195
108196 if ( lParam == IntPtr . Zero )
109197 {
198+ app . Logger . WriteLine ( "[HidHotPlugMonitor] Device change lParam is zero; no device path available." ) ;
199+
110200 return IntPtr . Zero ;
111201 }
112202
113203 var broadcastHeader = Marshal . PtrToStructure < DEV_BROADCAST_HDR > ( lParam ) ;
114204
205+ app . Logger . WriteLine ( $ "[HidHotPlugMonitor] Device change broadcast type={ broadcastHeader . dbch_devicetype } " ) ;
206+
115207 if ( broadcastHeader . dbch_devicetype == DEV_BROADCAST_HDR_DEVICE_TYPE . DBT_DEVTYP_DEVICEINTERFACE )
116208 {
117209 var nameOffset = Marshal . OffsetOf < DEV_BROADCAST_DEVICEINTERFACE_W > (
@@ -120,8 +212,6 @@ private IntPtr WndProc( IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref
120212 var namePtr = IntPtr . Add ( lParam , nameOffset ) ;
121213 var devicePath = Marshal . PtrToStringUni ( namePtr ) ?? string . Empty ;
122214
123- var app = App . Instance ! ;
124-
125215 if ( eventType == PInvoke . DBT_DEVICEREMOVECOMPLETE )
126216 {
127217 app . Logger . WriteLine ( $ "[HidHotPlugMonitor] Device { devicePath } was removed!" ) ;
@@ -131,9 +221,13 @@ private IntPtr WndProc( IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref
131221 app . Logger . WriteLine ( $ "[HidHotPlugMonitor] Device { devicePath } was added!" ) ;
132222 }
133223 }
224+ else
225+ {
226+ app . Logger . WriteLine ( $ "[HidHotPlugMonitor] Ignoring non-device-interface broadcast type={ broadcastHeader . dbch_devicetype } " ) ;
227+ }
134228 }
135229 }
136230
137231 return IntPtr . Zero ;
138232 }
139- }
233+ }
0 commit comments