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:-
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