Author Topic: cant get handle to the USB HID??  (Read 31372 times)

jain1.anuj

  • Member
  • ***
  • Posts: 28
cant get handle to the USB HID??
« on: January 03, 2012, 04:18:50 am »
hello,
i am working on a USB HID device. it's a proximity device which detects the person's distance and fire keystrokes accordingly. i want the handle for the device so that i can perform the read and write operations over it.
i am using Hid.dll , Setupapi.dll , kernel32.dll. when i am using the CreateFile function, it is reaturning the invalid handle. can anybody help me in this regard.
the code is written below:-


Code: [Select]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
 

namespace WindowsFormsApplication4
{
    public partial class Form1 : Form
    {
        public Form1() : base()
        {
            InitializeComponent();
           
        }
 
       
 
        [ StructLayout( LayoutKind.Sequential ) ]
        internal class DEV_BROADCAST_HDR
        {
            internal Int32 dbch_size;
            internal Int32 dbch_devicetype;
            internal Int32 dbch_reserved;
        }
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        internal class DEV_BROADCAST_DEVICEINTERFACE_1
        {
            internal Int32 dbcc_size;
            internal Int32 dbcc_devicetype;
            internal Int32 dbcc_reserved;
            [MarshalAs(UnmanagedType.ByValArray,
           ArraySubType = UnmanagedType.U1,
           SizeConst = 16)]
            internal Byte[] dbcc_classguid;
            [MarshalAs(UnmanagedType.ByValArray,
            SizeConst = 255)]
            internal Char[] dbcc_name;
        }
 
       
        [DllImport("hid.dll", SetLastError = true)]
        public static extern void HidD_GetHidGuid(ref System.Guid HidGuid);
 
        [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
        internal static extern IntPtr SetupDiGetClassDevs
        (ref System.Guid ClassGuid,
        IntPtr Enumerator,
        IntPtr hwndParent,
        Int32 Flags);
 

        public struct SP_DEVINFO_DATA
        {
            public int cbSize;
            public System.Guid ClassGuid;
            public int DevInst;
            public int Reserved;
        }
 
        internal struct SP_DEVICE_INTERFACE_DATA
        {
            internal Int32 cbSize;
            internal Guid InterfaceClassGuid;
            internal Int32 Flags;
            internal IntPtr Reserved;
        }
 

        [DllImport("setupapi.dll", SetLastError = true)]
        internal static extern Boolean SetupDiEnumDeviceInterfaces
        (IntPtr DeviceInfoSet,
        IntPtr DeviceInfoData,
        ref System.Guid InterfaceClassGuid,
        Int32 MemberIndex,
        ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
 

 
        internal struct SP_DEVICE_INTERFACE_DETAIL_DATA
        {
            internal Int32 cbSize;
            internal String DevicePath;
        }
 

 
        [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
            internal static extern Boolean SetupDiGetDeviceInterfaceDetail
            (IntPtr DeviceInfoSet,
            ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
            IntPtr DeviceInterfaceDetailData,
            Int32 DeviceInterfaceDetailDataSize,
            ref Int32 RequiredSize,
            IntPtr DeviceInfoData);
 
        [DllImport("setupapi.dll", SetLastError = true)]
        internal static extern Int32 SetupDiDestroyDeviceInfoList
        (IntPtr DeviceInfoSet);
 
        [DllImport("setupapi.dll", SetLastError = true)]
 
           internal static extern Boolean SetupDiEnumDeviceInfo(
                IntPtr DeviceInfoSet,
                Int32 MemberIndex,
                SP_DEVINFO_DATA DeviceInfoData);
 

 

        internal const Int32 DBT_DEVTYP_HANDLE = 6;
        internal const Int32 DBT_DEVTYP_DEVICEINTERFACE = 5;
        internal const Int32 DEVICE_NOTIFY_WINDOW_HANDLE = 0;
        internal const Int32 DIGCF_PRESENT = 2;
        internal const Int32 DIGCF_DEVICEINTERFACE = 0X10;
        internal const Int32 WM_DEVICECHANGE = 0X219;
 
              [StructLayout(LayoutKind.Sequential)]
              internal class DEV_BROADCAST_DEVICEINTERFACE
              {
                  internal Int32 dbcc_size;
                  internal Int32 dbcc_devicetype;
                  internal Int32 dbcc_reserved;
                  internal Guid dbcc_classguid;
                  internal Int16 dbcc_name;
              }
 
              [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
              internal static extern IntPtr RegisterDeviceNotification
              (IntPtr hRecipient,
              IntPtr NotificationFilter,
              Int32 Flags);
 

              internal const Int32 DBT_DEVICEARRIVAL = 0X8000;
              internal const Int32 DBT_DEVICEREMOVECOMPLETE = 0X8004;
               public static Guid
GUID_DEVINTERFACE_USB_DEVICE = new Guid("A5DCBF10-6530-11D2-901F-00C04FB951ED");
 
internal const Int32 FILE_ATTRIBUTE_NORMAL = 0X80;
               internal const Int32 FILE_FLAG_OVERLAPPED = 0x40000000;
               internal const Int32 FILE_SHARE_READ = 1;
               internal const Int32 FILE_SHARE_WRITE = 2;
               internal const UInt32 GENERIC_READ = 0X80000000;
               internal const UInt32 GENERIC_WRITE = 0X40000000;
               internal const Int32 OPEN_EXISTING = 3;
 

               [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
               internal static extern SafeFileHandle CreateFile
               (String lpFileName,
               UInt32 dwDesiredAccess,
               Int32 dwShareMode,
               IntPtr lpSecurityAttributes,
               Int32 dwCreationDisposition,
               Int32 dwFlagsAndAttributes,
               Int32 hTemplateFile);
 

               [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
               internal static extern int GetLastError();
 

 

               [StructLayout(LayoutKind.Sequential)]
               internal struct HIDD_ATTRIBUTES
               {
                   internal Int32 Size;
                   internal UInt16 VendorID;
                   internal UInt16 ProductID;
                   internal UInt16 VersionNumber;
               }
 
               [DllImport("hid.dll", SetLastError = true)]
               internal static extern Boolean HidD_GetAttributes
                   (SafeFileHandle HidDeviceObject, ref HIDD_ATTRIBUTES Attributes);
               
             
                internal SafeFileHandle deviceHandle;
 
private Boolean Find(Message m)
        {
Boolean deviceFound ;
            Int32 bufferSize = 0;
            IntPtr detailDataBuffer;
            String[] devicePathName = new String[128];
            Int32 memberIndex = 0;
ntPtr deviceInfoSet ;
 
            deviceInfoSet = SetupDiGetClassDevs
            (ref GUID_DEVINTERFACE_USB_DEVICE,
            IntPtr.Zero,
            IntPtr.Zero,
            DIGCF_PRESENT | DIGCF_DEVICEINTERFACE );
 
            //MessageBox.Show(deviceInfoSet.ToString());

            deviceFound = false;
           // Int32 memberIndex = 0;
             
            SP_DEVICE_INTERFACE_DATA MyDeviceInterfaceData = new SP_DEVICE_INTERFACE_DATA();
            Boolean success = false;
 
            MyDeviceInterfaceData.cbSize =  Marshal.SizeOf( MyDeviceInterfaceData );
           
            //do
            //{

                success = SetupDiEnumDeviceInterfaces
                (deviceInfoSet,
                IntPtr.Zero,
                ref GUID_DEVINTERFACE_USB_DEVICE,
                memberIndex,
                ref MyDeviceInterfaceData);
 
                //MessageBox.Show(success.ToString());
                if (!success)
                {
                    return false;
                }
 

                else
                {
                    success = SetupDiGetDeviceInterfaceDetail
                    (deviceInfoSet,
                    ref MyDeviceInterfaceData,
                    IntPtr.Zero,
                    0,
                    ref bufferSize,
                    IntPtr.Zero);
 
                    detailDataBuffer = Marshal.AllocHGlobal(bufferSize);
                    Marshal.WriteInt32
                    (detailDataBuffer, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8);
 

                    success = SetupDiGetDeviceInterfaceDetail
                    (deviceInfoSet,
                    ref MyDeviceInterfaceData,
                    detailDataBuffer,
                    bufferSize,
                    ref bufferSize,
                    IntPtr.Zero);
 
                    //String devicePathName = "";

                    IntPtr pDevicePathName = new IntPtr(detailDataBuffer.ToInt32() + 4);
 
                    devicePathName[memberIndex] = Marshal.PtrToStringAuto(pDevicePathName);
                   
                    MessageBox.Show("path of device " + devicePathName[memberIndex]);
 
  DEV_BROADCAST_DEVICEINTERFACE_1 devBroadcastDeviceInterface =
                    new DEV_BROADCAST_DEVICEINTERFACE_1();
                    DEV_BROADCAST_HDR devBroadcastHeader = new DEV_BROADCAST_HDR();
                    Marshal.PtrToStructure(m.LParam, devBroadcastHeader);
                    if ((devBroadcastHeader.dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE))
                    {
                        Int32 stringSize = Convert.ToInt32((devBroadcastHeader.dbch_size - 32) / 2);
                        Array.Resize(ref devBroadcastDeviceInterface.dbcc_name, stringSize);
                        Marshal.PtrToStructure(m.LParam, devBroadcastDeviceInterface);
                        String deviceNameString = new String(devBroadcastDeviceInterface.dbcc_name, 0, stringSize);
                        MessageBox.Show("extracted path-: " + deviceNameString.ToString());
                        if ((String.Compare(deviceNameString, devicePathName[0], true) == 0))
                        {
                            MessageBox.Show("device name matched");
                        }
                        else
                        {
                            MessageBox.Show("device name not matched");
                        }
 

                    }
                     deviceFound = true ;
                }
 

if (deviceFound)
            {
               
               // memberIndex = 0;
                MessageBox.Show(devicePathName[0]);
                //SafeFileHandle deviceHandle;
                MessageBox.Show("inside file handle");
                deviceHandle = CreateFile
                    ("##?#USB#Vid_18c8&Pid_2bfa#063#{A5DCBF10-6530-11D2-901F-00C04FB951ED}",/*devicePathName[0]/*, /*GENERIC_WRITE | GENERIC_READ*/0, FILE_SHARE_READ | FILE_SHARE_WRITE,
                    IntPtr.Zero, OPEN_EXISTING, 0/*FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED*/, 0);
 
                MessageBox.Show("file handle " + deviceHandle.ToString());
                MessageBox.Show("handle value : " + deviceHandle.DangerousGetHandle().ToString());
 
                if (!deviceHandle.IsInvalid)
                {
                    MessageBox.Show("valid");
                    HIDD_ATTRIBUTES attribs = new HIDD_ATTRIBUTES();
                    attribs.Size = Marshal.SizeOf(attribs);
 
                    HidD_GetAttributes(deviceHandle, ref attribs);
 

                    MessageBox.Show("vendor id " + Convert.ToString(attribs.VendorID, 16));
 
                }
                else
                {
                    int error = GetLastError();
                    MessageBox.Show("in else " + error.ToString());
                }
               
           
            }
            return deviceFound;
 
        }
 
private void Register()
        {
            DEV_BROADCAST_DEVICEINTERFACE devBroadcastDeviceInterface =
            new DEV_BROADCAST_DEVICEINTERFACE();
            IntPtr devBroadcastDeviceInterfaceBuffer;
            IntPtr deviceNotificationHandle = IntPtr.Zero;
            Int32 size = 0;
 
            // frmMy is the form that will receive device-change messages.
           
 
            size = Marshal.SizeOf( devBroadcastDeviceInterface );
            devBroadcastDeviceInterface.dbcc_size = size;
            devBroadcastDeviceInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
            devBroadcastDeviceInterface.dbcc_reserved = 0;
            devBroadcastDeviceInterface.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;
            devBroadcastDeviceInterfaceBuffer = Marshal.AllocHGlobal( size );
            Marshal.StructureToPtr
            ( devBroadcastDeviceInterface,
            devBroadcastDeviceInterfaceBuffer,
            true );
 
            deviceNotificationHandle = RegisterDeviceNotification
            (new Form1().Handle,
            devBroadcastDeviceInterfaceBuffer,
            DEVICE_NOTIFY_WINDOW_HANDLE);
 
           
        }
     
 
        private void Form1_Load(object sender, EventArgs e)
        {
            Register();
 
        }
 
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_DEVICECHANGE)
            {
               
                OnDeviceChange(m);
            }
            base.WndProc(ref m);
        }
 
       
 
        private void OnDeviceChange(Message m)
        {
 
            if ((m.WParam.ToInt32() == DBT_DEVICEARRIVAL))
            {
               
                MessageBox.Show("device arrived");
                //Find(m);
               
                if (Find(m))
                {
                    MessageBox.Show("my device arrived");
                }
 
            }
            else if ((m.WParam.ToInt32() == DBT_DEVICEREMOVECOMPLETE))
            {
               
                MessageBox.Show("device removed");
            }
        }
 

    }
}

please help me in this regard. it is urgent

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: cant get handle to the USB HID??
« Reply #1 on: January 03, 2012, 11:04:08 am »
If your HID enumerates as a system keyboard, use Raw Input instead of the HID API.

Jan

jain1.anuj

  • Member
  • ***
  • Posts: 28
Re: cant get handle to the USB HID??
« Reply #2 on: January 03, 2012, 11:01:27 pm »
thanks for the reply JAN.
let me explain you about the device. it's a proximity device. User configures the keystrokes from the application provided with the device. As soon as user gets away from the range of the device, the device fires the keystrokes that were configured and saved by the user in the device. The device don't have any keys in it. It just fires the keystrokes configured and saved in it. The device has just the sensor in it.
« Last Edit: January 03, 2012, 11:31:45 pm by jain1.anuj »

jain1.anuj

  • Member
  • ***
  • Posts: 28
Re: cant get handle to the USB HID??
« Reply #3 on: January 05, 2012, 10:41:04 pm »
can anyone help me in solving my problem??

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: cant get handle to the USB HID??
« Reply #4 on: January 06, 2012, 10:33:02 am »
If the device's descriptors cause the host computer to see the device as a system keyboard, you need to use Raw Input or other means to read the keypresses, not the HID API. Whether it's a conventional keyboard doesn't matter. For example, many barcode scanners enumerate as system keyboards.

See if it shows up as a keyboard in Windows Device Manager.

Jan

jain1.anuj

  • Member
  • ***
  • Posts: 28
Re: cant get handle to the USB HID??
« Reply #5 on: January 08, 2012, 10:52:56 pm »
This is how my device enumerates in the device manager. (see the attached image)
It is when i VIEW the device "By CONNECTION" in device manager.


[attachment deleted by admin]

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: cant get handle to the USB HID??
« Reply #6 on: January 08, 2012, 11:13:43 pm »
View "by type" and see if it shows up as a keyboard.

Jan

jain1.anuj

  • Member
  • ***
  • Posts: 28
Re: cant get handle to the USB HID??
« Reply #7 on: January 08, 2012, 11:23:35 pm »
It show like this if i view it "By Type". (attached file)

[attachment deleted by admin]

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: cant get handle to the USB HID??
« Reply #8 on: January 09, 2012, 12:41:23 am »
Click the "+" at Keyboards.

Jan

jain1.anuj

  • Member
  • ***
  • Posts: 28
Re: cant get handle to the USB HID??
« Reply #9 on: January 09, 2012, 12:49:45 am »
here it is

[attachment deleted by admin]

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: cant get handle to the USB HID??
« Reply #10 on: January 09, 2012, 09:51:40 am »
If the keyboard device disappears when you detach your device, it's a keyboard.

Jan

jain1.anuj

  • Member
  • ***
  • Posts: 28
Re: cant get handle to the USB HID??
« Reply #11 on: January 09, 2012, 11:09:56 pm »
yes. it gets disappear when i de-attached the device.
so what should i use to read/write and registering the device? HID API's or RAW INPUT?

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: cant get handle to the USB HID??
« Reply #12 on: January 10, 2012, 11:33:52 am »
Raw input.

Jan

jain1.anuj

  • Member
  • ***
  • Posts: 28
Re: cant get handle to the USB HID??
« Reply #13 on: January 11, 2012, 01:19:21 am »
ok. but i dont think that we can write data with RAW INPUT. can we?

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: cant get handle to the USB HID??
« Reply #14 on: January 11, 2012, 09:20:56 am »
Just input. If you want to read and write, make it a generic HID and use the HID API. See my firmware for example descriptors:

http://www.lvr.com/hidpage.htm#MyExampleCode

Jan