Handling usb device change event in Csharp using win32 APIs
 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using ChitrakshLibrary.API;
namespace ChitrakshLibrary
{

    /**********All below codes and classes are somewhere used for 'DeviceChangeHandleClass'***********/
    ////
    public class DeviceChangeHandleClass : System.IDisposable
    {
        public MyEventsDelegate myeventhandler;
        private nativewindow window;
        public bool isDisposed;
        public bool showInBuildMsgBox;

        public Queue<MyDeviceChangeEventArgs> bridge_list;
        public DeviceChangeHandleClass(MyEventsDelegate eventFunction, bool showInBuildMsgBox = false)
        {
            window = new nativewindow();
            window.myevent += new MyEventsDelegate(eventFunction);
            myeventhandler = eventFunction;
            isDisposed = false;
            bridge_list = new Queue<MyDeviceChangeEventArgs>();
            this.showInBuildMsgBox = showInBuildMsgBox;

        }
        public void Dispose()
        {
            if (!isDisposed)
            {
                if (window != null)
                {
                    window.myevent -= new MyEventsDelegate(abc);
                    window.Dispose();
                    window = null;
                }

                isDisposed = true;
                GC.SuppressFinalize(this);
            }
        }
        ~DeviceChangeHandleClass()
        {
            Dispose();
        }

        //event actual code is this
        public event MyEventsDelegate myevent
        {
            add
            {
                if (window == null)
                {
                    // create the driver window once a consumer registers for notifications
                    window = new nativewindow();
                    window.myevent += new MyEventsDelegate(abc);
                }

                myeventhandler = (MyEventsDelegate)Delegate.Combine(myeventhandler, value);
            }
            remove
            {
                myeventhandler = (MyEventsDelegate)Delegate.Remove(myeventhandler, value);
                if (myeventhandler == null)
                {
                    // destroy the driver window once the consumer stops listening
                    window.myevent -= new MyEventsDelegate(abc);
                    window.Dispose();
                    window = null;
                }
            }
        }

        public void abc(MyDeviceChangeEventArgs myeventarg)
        {

            bridge_list.Enqueue(myeventarg);
            if (this.showInBuildMsgBox == true)
                System.Windows.Forms.MessageBox.Show(myeventarg.eventmessage);
        }

    }
    public class MyDeviceChangeEventArgs : EventArgs
    {
        public DeviceManagement.Device Device
        {
            get;
            private set;
        }
        public IntPtr lParam
        {
            get;
            private set;
        }
        public IntPtr wParam
        {
            get;
            private set;
        }
        public String eventmessage
        {
            get;
            set;
            //private set;
        }
        public DateTime instance
        {
            get;
            set;
        }
        public string eventtype
        {
            get;
            set;
        }
        public string devicetype
        {
            get;
            set;
        }
        public MyDeviceChangeEventArgs(string eventmessage, DateTime instance, IntPtr lp, IntPtr wp,DeviceManagement.Device device,string evettype,string devtype)
        {
            this.lParam = lp;
            this.wParam = wp;
            this.eventmessage = eventmessage;
            this.instance = instance;
            this.Device = device;
            this.eventtype = evettype;
            this.devicetype = devtype;
        }

    }
    public delegate void MyEventsDelegate(MyDeviceChangeEventArgs myeventargs);
    internal class nativewindow : System.Windows.Forms.NativeWindow, System.IDisposable
    {

        //defining events
        public IntPtr deviceNotificationHandle;
        public event MyEventsDelegate myevent;
        public bool HookQueryRemove;
        //constructor: register for..
        public nativewindow(bool HookQueryRemove = false)
        {
            // create a generic window with no class name
            this.HookQueryRemove = HookQueryRemove;
            base.CreateHandle(new System.Windows.Forms.CreateParams());

            //registering notification
            // A DEV_BROADCAST_DEVICEINTERFACE header holds information about the request.
            Win32StructureWrapper.DEV_BROADCAST_DEVICEINTERFACE devBroadcastDeviceInterface = 
                new Win32StructureWrapper.DEV_BROADCAST_DEVICEINTERFACE();
            IntPtr devBroadcastDeviceInterfaceBuffer = IntPtr.Zero;
            Int32 size = 0;
            try
            {
                size = System.Runtime.InteropServices.Marshal.SizeOf(devBroadcastDeviceInterface);

                // Allocate memory for the buffer that holds the DEV_BROADCAST_DEVICEINTERFACE structure.
                devBroadcastDeviceInterfaceBuffer = System.Runtime.InteropServices.Marshal.AllocHGlobal(size);

                devBroadcastDeviceInterface.dbcc_size = size;

                // Request to receive notifications about a class of devices.
                devBroadcastDeviceInterface.dbcc_devicetype = Win32StructureWrapper.DBT_DEVTYP_DEVICEINTERFACE;
                devBroadcastDeviceInterface.dbcc_reserved = 0;
                try
                {
                    // Specify the interface class to receive notifications about.
                    devBroadcastDeviceInterface.dbcc_classguid = Win32StructureWrapper.GUID_DEVINTERFACE_USB_DEVICE;

                    // Copy the DEV_BROADCAST_DEVICEINTERFACE structure to the buffer.
                    // Set fDeleteOld True to prevent memory leaks.
                    System.Runtime.InteropServices.Marshal.StructureToPtr(devBroadcastDeviceInterface, devBroadcastDeviceInterfaceBuffer, 
                        true);
                    //when you user DEVICE_NOTIFY_ALL_INTERFACE_CLASSES then the function RegisterDeviceNotification will ignore dbcc_classguid
                    deviceNotificationHandle = Win32Wrapper.RegisterDeviceNotification(base.Handle, devBroadcastDeviceInterfaceBuffer, 
                        Win32StructureWrapper.DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
                }
                catch
                {
                    System.Windows.Forms.MessageBox.Show("Error in register deviece notification=>GUID_DEVINTERFACE_USB_DEVICE", "DeviceChangeHandler");
                }

            }
            catch (Exception ex)
            {
                System.Runtime.InteropServices.Marshal.FreeHGlobal(devBroadcastDeviceInterfaceBuffer);
                System.Windows.Forms.MessageBox.Show("Error in register deviece notification=>" + ex.ToString(), "DeviceChangeHandler");
            }
        }
        //must be implemented becoz of interface IDisposable
        public void Dispose()
        {
            try
            {
                Win32Wrapper.UnregisterDeviceNotification(deviceNotificationHandle);
            }
            catch
            {
            }
            base.DestroyHandle();
            GC.SuppressFinalize(this);
        }

        //WindowProce methods of vc++
        protected override void WndProc(ref System.Windows.Forms.Message m)
        {
            DeviceManagement.Device device = null;
            string eventmessage = "";
            base.WndProc(ref m);
            
            if (m.Msg == (int)Win32StructureWrapper.WindowsMessages.WM_DEVICECHANGE)
            {


                int devType = -1;
                string devtype_in = "";
                if (m.LParam != IntPtr.Zero)
                {
                    devType = System.Runtime.InteropServices.Marshal.ReadInt32(m.LParam, 4);

                    switch (devType)
                    {
                        case Win32StructureWrapper.DBT_DEVTYP_DEVICEINTERFACE:
                            devtype_in = "DBT_DEVTYP_DEVICEINTERFACE";
                            Win32StructureWrapper.DEV_BROADCAST_DEVICEINTERFACE devInterface;
                            devInterface = (Win32StructureWrapper.DEV_BROADCAST_DEVICEINTERFACE)System.Runtime.InteropServices.Marshal.PtrToStructure(
                                m.LParam, typeof(Win32StructureWrapper.DEV_BROADCAST_DEVICEINTERFACE));
                            string devicepathafter4 = devInterface.dbcc_name.Substring(4);

                            string DevId = "";
                            string Classvalue = "";
                            if (devicepathafter4.Length > 4)
                            {
                                int lstindex = devicepathafter4.LastIndexOf("#");
                                if (lstindex >= 0)
                                {
                                    DevId = devicepathafter4.Substring(0, lstindex);
                                    DevId = DevId.Replace("#", "\");
                                    DevId = DevId.ToUpper();
                                    DevId = DevId.Trim();
                                    int frstindex = DevId.IndexOf("\");
                                    if (frstindex >= 0)
                                    {
                                        Classvalue = DevId.Substring(0, frstindex);

                                    }
                                }
                            }
                            System.Windows.Forms.ImageList imagelist = new System.Windows.Forms.ImageList();
                            System.Data.DataSet ds = DeviceManagement.ListAllDevices(ref imagelist, Guid.Empty, Classvalue, DevId);
                            String aaaa = "";
                            try
                            {
                                aaaa = ds.Tables[0].Rows[0]["DeviceFrndName"].ToString();// Name
                                if (aaaa.Trim().Length == 0)
                                {
                                    aaaa = ds.Tables[0].Rows[0]["Name"].ToString();
                                    if (aaaa.Trim().Length == 0)
                                    {
                                        aaaa = ds.Tables[0].Rows[0]["DeviceClass"].ToString();
                                        if (aaaa.Trim().Length == 0)
                                        {
                                            aaaa = ds.Tables[0].Rows[0]["DevicePath"].ToString();
                                        }
                                    }
                                }
                            }
                            catch
                            {
                                if (aaaa.Trim().Length == 0)
                                    aaaa = " Error in getting name";
                            }
                            eventmessage = Classvalue+" ==>"+ aaaa;;
                            break;
                        case Win32StructureWrapper.DBT_DEVTYP_DEVNODE:
                            devtype_in = "DBT_DEVTYP_DEVNODE";
                            eventmessage = "DBT_DEVTYP_DEVNODE";
                            break;
                        case Win32StructureWrapper.DBT_DEVTYP_HANDLE:
                            Win32StructureWrapper.DEV_BROADCAST_HANDLE devhandle;
                            devhandle = (Win32StructureWrapper.DEV_BROADCAST_HANDLE)System.Runtime.InteropServices.Marshal.PtrToStructure(
                                    m.LParam, typeof(Win32StructureWrapper.DEV_BROADCAST_HANDLE));
                            devtype_in = "DBT_DEVTYP_HANDLE";
                            eventmessage = "GUID=" + devhandle.dbch_eventguid.ToString();
                            break;
                        case Win32StructureWrapper.DBT_DEVTYP_NET:

                            devtype_in = "DBT_DEVTYP_NET";
                            eventmessage = "DBT_DEVTYP_NET";
                            break;
                        case Win32StructureWrapper.DBT_DEVTYP_OEM:
                            devtype_in = "DBT_DEVTYP_OEM";
                            eventmessage = "DBT_DEVTYP_OEM";
                            break;
                        case Win32StructureWrapper.DBT_DEVTYP_PORT:
                            devtype_in = "DBT_DEVTYP_PORT";
                            Win32StructureWrapper.DEV_BROADCAST_PORT devPort;
                            devPort = (Win32StructureWrapper.DEV_BROADCAST_PORT)System.Runtime.InteropServices.Marshal.PtrToStructure(
                                m.LParam, typeof(Win32StructureWrapper.DEV_BROADCAST_PORT));
                            eventmessage = "Portname=" + devPort.dbcp_name;
                            break;
                        case Win32StructureWrapper.DBT_DEVTYP_VOLUME:
                            devtype_in = "DBT_DEVTYP_VOLUME";
                            Win32StructureWrapper.DEV_BROADCAST_VOLUME vol;
                            vol = (Win32StructureWrapper.DEV_BROADCAST_VOLUME)System.Runtime.InteropServices.Marshal.PtrToStructure(
                                    m.LParam, typeof(Win32StructureWrapper.DEV_BROADCAST_VOLUME));
                            DeviceManagement.DevicesClass deviceclass = new DeviceManagement.DevicesClass(Win32StructureWrapper.GUID_DEVINTERFACE_VOLUME, IntPtr.Zero);

                            eventmessage = "Drive=" + DeviceManagement.getDeviceTypeOrDriveLetterfromDriveMask(m.WParam, m.LParam) +
                                    ",(mask= " + vol.dbcv_unitmask.ToString() + ") Size mask=" + vol.dbcv_size.ToString() + " Type mask=" + vol.dbcv_devicetype.ToString();
                            break;
                        default:
                            devtype_in = "Some Other Device";
                            eventmessage = "please refer <<Win32StructureWrapper>> class for the name of dev type";
                            break;
                    }

                }
                string eventtype = "";
                switch (m.WParam.ToInt32())
                {
                    case Win32StructureWrapper.DBT_DEVICEARRIVAL:
                        eventtype = "DBT_DEVICE ARRIVAL";
                        break;
                    case Win32StructureWrapper.DBT_DEVICEQUERYREMOVE:
                        eventtype = "DBT_DEVICE QUERY REMOVE";
                        //this event will occur only if register the device notification using RegisterDeviceNotification  API
                        break;
                    case Win32StructureWrapper.DBT_DEVICEREMOVECOMPLETE:
                        eventtype = "DBT_DEVICE REMOVE COMPLETE";
                        break;
                    case Win32StructureWrapper.DBT_DEVNODES_CHANGED:
                        eventtype = "DBT_DEVNODES_CHANGED"; //lParam set to zero.
                        break;
                    case Win32StructureWrapper.DBT_LOW_DISK_SPACE:
                        eventtype = "The device has low disk space";
                        break;
                    default:
                        eventtype = "please refer <<Win32StructureWrapper>> class for the name of event";
                        break;
                }
                MyDeviceChangeEventArgs arg = new MyDeviceChangeEventArgs(eventmessage, DateTime.Now, m.LParam, m.WParam, device, eventtype, devtype_in);
                myevent(arg);
            }
        }


    }
    ////
}

share on whatapp
706 Views

Comments

Show All Amazon Product

Private Policy   Terms of Service