Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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;
        }