static IntPtr RegisterDeviceNotification(IntPtr hwnd, Guid guid) { var notifyFilter = new NativeMethods.DEV_BROADCAST_DEVICEINTERFACE() { Size = Marshal.SizeOf(typeof(NativeMethods.DEV_BROADCAST_DEVICEINTERFACE)), ClassGuid = guid, DeviceType = NativeMethods.DBT_DEVTYP_DEVICEINTERFACE }; var notifyHandle = NativeMethods.RegisterDeviceNotification(hwnd, ref notifyFilter, 0); RunAssert(notifyHandle != IntPtr.Zero, "HidSharp RegisterDeviceNotification failed."); return(notifyHandle); }
internal string CheckDeviceChangeMessageSenderIsTargetDeviceOrNot(IntPtr LParam) { try { NativeMethods.DEV_BROADCAST_DEVICEINTERFACE devBroadcastDeviceInterface = new NativeMethods.DEV_BROADCAST_DEVICEINTERFACE(); NativeMethods.DEV_BROADCAST_HDR devBroadcastHdr = (NativeMethods.DEV_BROADCAST_HDR)Marshal.PtrToStructure(LParam, typeof(NativeMethods.DEV_BROADCAST_HDR)); if (devBroadcastHdr.dbch_devicetype == NativeMethods.DeviceType.DBT_DEVTYP_DEVICEINTERFACE) { // The dbch_devicetype parameter indicates that the event applies to a device interface. // So the structure in LParam is actually a DEV_BROADCAST_INTERFACE structure, // which begins with a DEV_BROADCAST_HDR. // Obtain the number of characters in dbch_name by subtracting the 32 bytes // in the structure that are not part of dbch_name and dividing by 2 because there are // 2 bytes per character. int stringSize = System.Convert.ToInt32((devBroadcastHdr.dbch_size - 32) / 2); // The dbcc_name parameter of broadcastDeviceInterface contains the device name. // Trim dbcc_name to match the size of the string. devBroadcastDeviceInterface.dbcc_name = new string(new char[stringSize + 1]); // Marshal data from the unmanaged block pointed to by m.LParam // to the managed object broadcastDeviceInterface. devBroadcastDeviceInterface = (NativeMethods.DEV_BROADCAST_DEVICEINTERFACE)Marshal.PtrToStructure(LParam, typeof(NativeMethods.DEV_BROADCAST_DEVICEINTERFACE)); return(devBroadcastDeviceInterface.dbcc_name); } } catch (Exception ex) { Debug.WriteLine(ex.Message); throw; } return(string.Empty); }
internal bool RegisterForDeviceNotifications(Guid classGuid) { IntPtr broadcastDeviceInterfaceBuffer = IntPtr.Zero; try { // A DEV_BROADCAST_DEVICEINTERFACE header holds information about the request. NativeMethods.DEV_BROADCAST_DEVICEINTERFACE broadcastDeviceInterface = new NativeMethods.DEV_BROADCAST_DEVICEINTERFACE(); // Set the parameters in the DEV_BROADCAST_DEVICEINTERFACE structure. broadcastDeviceInterface.dbcc_size = (uint)Marshal.SizeOf(broadcastDeviceInterface); // Request to receive notifications about a class of devices. broadcastDeviceInterface.dbcc_devicetype = NativeMethods.DeviceType.DBT_DEVTYP_DEVICEINTERFACE; broadcastDeviceInterface.dbcc_reserved = 0; // Specify the interface class to receive notifications about. broadcastDeviceInterface.dbcc_classguid = classGuid; // Allocate memory for the buffer that holds the DEV_BROADCAST_DEVICEINTERFACE structure. broadcastDeviceInterfaceBuffer = Marshal.AllocHGlobal((int)broadcastDeviceInterface.dbcc_size); // Copy the DEV_BROADCAST_DEVICEINTERFACE structure to the buffer. // Set fDeleteOld True to prevent memory leaks. Marshal.StructureToPtr(broadcastDeviceInterface, broadcastDeviceInterfaceBuffer, true); // *** // API function // summary // Request to receive notification messages when a device in an interface class // is attached or removed. // parameters // Handle to the window that will receive device events. // Pointer to a DEV_BROADCAST_DEVICEINTERFACE to specify the type of // device to send notifications for. // DEVICE_NOTIFY_WINDOW_HANDLE indicates the handle is a window handle. // Returns // Device notification handle or NULL on failure. // *** deviceNotificationHandle = NativeMethods.RegisterDeviceNotification( ownerWindowMessageMonitoringWindowHandle, broadcastDeviceInterfaceBuffer, NativeMethods.DEVICE_NOTIFY_WINDOW_HANDLE); // TODO: MUSTDO: BUG?? // Marshal data from the unmanaged block broadcastDeviceInterfaceBuffer to // the managed object broadcastDeviceInterface // Marshal.PtrToStructure(broadcastDeviceInterfaceBuffer, broadcastDeviceInterface); if ((deviceNotificationHandle == IntPtr.Zero)) { return(false); } else { return(true); } } catch (Exception ex) { Debug.WriteLine(ex.Message); throw; } finally { if (broadcastDeviceInterfaceBuffer != IntPtr.Zero) { // Free the memory allocated previously by AllocHGlobal. Marshal.FreeHGlobal(broadcastDeviceInterfaceBuffer); } } }
/// <summary> /// Worker function for WM_DEVICECHANGE messages. Invokes DeviceChangedMsg event. /// </summary> /// <param name="msg">Native Windows message - WM_DEVICECHANGE</param> private void OnDeviceChange(Message msg) { DeviceChangeEvent devEvent = DeviceChangeEvent.Unknown; String devDetails = String.Empty; if (msg.LParam != IntPtr.Zero) { NativeMethods.DEV_BROADCAST_HDR db = (NativeMethods.DEV_BROADCAST_HDR)Marshal.PtrToStructure(msg.LParam, typeof(NativeMethods.DEV_BROADCAST_HDR)); switch (msg.WParam.ToInt32()) { case NativeMethods.DBT_DEVICEARRIVAL: if (db.dbch_devicetype == NativeMethods.DBT_DEVTYP.DEVICEINTERFACE) { NativeMethods.DEV_BROADCAST_DEVICEINTERFACE dbdi = (NativeMethods.DEV_BROADCAST_DEVICEINTERFACE)Marshal.PtrToStructure(msg.LParam, typeof(NativeMethods.DEV_BROADCAST_DEVICEINTERFACE)); if (dbdi.dbcc_classguid == NativeMethods.GUID_DEVINTERFACE_USB_DEVICE) { devEvent = DeviceChangeEvent.DeviceArrival; devDetails = dbdi.dbcc_name; } else if (dbdi.dbcc_classguid == NativeMethods.GUID_DEVINTERFACE_USB_HUB) { devEvent = DeviceChangeEvent.HubArrival; devDetails = dbdi.dbcc_name; } } else if (db.dbch_devicetype == NativeMethods.DBT_DEVTYP.VOLUME) { NativeMethods.DEV_BROADCAST_VOLUME dbv = (NativeMethods.DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(msg.LParam, typeof(NativeMethods.DEV_BROADCAST_VOLUME)); devEvent = DeviceChangeEvent.VolumeArrival; devDetails = DrivesFromMask(dbv.dbcv_unitmask); } else if (db.dbch_devicetype == NativeMethods.DBT_DEVTYP.PORT) { NativeMethods.DEV_BROADCAST_PORT dbp = (NativeMethods.DEV_BROADCAST_PORT)Marshal.PtrToStructure(msg.LParam, typeof(NativeMethods.DEV_BROADCAST_PORT)); devEvent = DeviceChangeEvent.PortArrival; devDetails = dbp.dbcp_name; } break; case NativeMethods.DBT_DEVICEREMOVECOMPLETE: if (db.dbch_devicetype == NativeMethods.DBT_DEVTYP.DEVICEINTERFACE) { NativeMethods.DEV_BROADCAST_DEVICEINTERFACE dbdi = (NativeMethods.DEV_BROADCAST_DEVICEINTERFACE)Marshal.PtrToStructure(msg.LParam, typeof(NativeMethods.DEV_BROADCAST_DEVICEINTERFACE)); if (dbdi.dbcc_classguid == NativeMethods.GUID_DEVINTERFACE_USB_DEVICE) { devEvent = DeviceChangeEvent.DeviceRemoval; devDetails = dbdi.dbcc_name; } else if (dbdi.dbcc_classguid == NativeMethods.GUID_DEVINTERFACE_USB_HUB) { devEvent = DeviceChangeEvent.HubRemoval; devDetails = dbdi.dbcc_name; } } else if (db.dbch_devicetype == NativeMethods.DBT_DEVTYP.VOLUME) { NativeMethods.DEV_BROADCAST_VOLUME dbv = (NativeMethods.DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(msg.LParam, typeof(NativeMethods.DEV_BROADCAST_VOLUME)); devEvent = DeviceChangeEvent.VolumeRemoval; devDetails = DrivesFromMask(dbv.dbcv_unitmask); } else if (db.dbch_devicetype == NativeMethods.DBT_DEVTYP.PORT) { NativeMethods.DEV_BROADCAST_PORT dbp = (NativeMethods.DEV_BROADCAST_PORT)Marshal.PtrToStructure(msg.LParam, typeof(NativeMethods.DEV_BROADCAST_PORT)); devEvent = DeviceChangeEvent.PortRemoval; devDetails = dbp.dbcp_name; } break; default: Trace.Assert(false, "Invalid msg.WParam."); break; } // end switch (nEventType) Trace.WriteLine(String.Format("*** DeviceChangeWindow.OnDeviceChange(), {0}, {1}, {2}({3})", devEvent, devDetails, Thread.CurrentThread.Name, Thread.CurrentThread.GetHashCode())); // let's figure out what to do with the WM_DEVICECHANGE message // after we get out of this loop so we don't miss any messages. if (DeviceChangedMsg != null) { DeviceChangedMsg.BeginInvoke(devEvent, devDetails, null, null); } } // end if (lpdb) msg.Result = new IntPtr(1); // true return; }