Skip to content

Instantly share code, notes, and snippets.

@crsayen
Last active May 7, 2020 12:49
Show Gist options
  • Save crsayen/ffea66d1fbfa5d91e929ffdfd4f02d69 to your computer and use it in GitHub Desktop.
Save crsayen/ffea66d1fbfa5d91e929ffdfd4f02d69 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
namespace HHKBKeymapTool.Models
{
public class USBDriver : IUSBDriver
{
private bool cancel = true;
private IntPtr hardwareDeviceInfo;
private bool HID_quit;
private int nbrDevices;
private int iHIDD;
private const int DIGCF_DEFAULT = 1;
private const int DIGCF_PRESENT = 2;
private const int DIGCF_ALLCLASSES = 4;
private const int DIGCF_PROFILE = 8;
private const int DIGCF_DEVICEINTERFACE = 16;
private const uint GENERIC_READ = 2147483648;
private const uint GENERIC_WRITE = 1073741824;
private const uint GENERIC_EXECUTE = 536870912;
private const uint GENERIC_ALL = 268435456;
private const uint FILE_SHARE_READ = 1;
private const uint FILE_SHARE_WRITE = 2;
private const uint FILE_SHARE_DELETE = 4;
private const uint CREATE_NEW = 1;
private const uint CREATE_ALWAYS = 2;
private const uint OPEN_EXISTING = 3;
private const uint OPEN_ALWAYS = 4;
private const uint TRUNCATE_EXISTING = 5;
private const uint FILE_FLAG_OVERLAPPED = 1073741824;
private const int HIDP_STATUS_SUCCESS = 1114112;
private const int DEVICE_PATH = 260;
private const int INVALID_HANDLE_VALUE = -1;
private bool isConnected;
private short connectedProductId;
private ILogger logger;
private USBDriver.HID_DEVICE? currentDevice;
[DllImport("user32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
[DllImport("setupapi.dll", SetLastError = true)]
private static extern IntPtr SetupDiGetClassDevs(
ref Guid ClassGuid,
IntPtr Enumerator,
IntPtr hwndParent,
int Flags);
[DllImport("setupapi.dll", SetLastError = true)]
private static extern bool SetupDiEnumDeviceInterfaces(
IntPtr hDevInfo,
IntPtr devInfo,
ref Guid interfaceClassGuid,
int memberIndex,
ref USBDriver.SP_DEVICE_INTERFACE_DATA deviceInterfaceData);
[DllImport("setupapi.dll", SetLastError = true)]
private static extern bool SetupDiGetDeviceInterfaceDetail(
IntPtr DeviceInfoSet,
ref USBDriver.SP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
ref USBDriver.SP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData,
int DeviceInterfaceDetailDataSize,
ref int RequiredSize,
IntPtr DeviceInfoData);
[DllImport("setupapi.dll", SetLastError = true)]
private static extern bool SetupDiGetDeviceInterfaceDetail(
IntPtr DeviceInfoSet,
ref USBDriver.SP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
IntPtr DeviceInterfaceDetailData,
int DeviceInterfaceDetailDataSize,
ref int RequiredSize,
IntPtr DeviceInfoData);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr CreateFile(
string fileName,
uint fileAccess,
uint fileShare,
USBDriver.FileMapProtection securityAttributes,
uint creationDisposition,
uint flags,
IntPtr overlapped);
[DllImport("kernel32.dll")]
private static extern bool WriteFile(
IntPtr hFile,
[Out] byte[] lpBuffer,
uint nNumberOfBytesToWrite,
ref uint lpNumberOfBytesWritten,
IntPtr lpOverlapped);
[DllImport("kernel32.dll")]
private static extern bool ReadFile(
IntPtr hFile,
[Out] byte[] lpBuffer,
uint nNumberOfBytesToRead,
ref uint lpNumberOfBytesRead,
IntPtr lpOverlapped);
[DllImport("hid.dll")]
private static extern void HidD_GetHidGuid(ref Guid Guid);
[DllImport("hid.dll", SetLastError = true)]
private static extern bool HidD_GetPreparsedData(
IntPtr HidDeviceObject,
ref IntPtr PreparsedData);
[DllImport("hid.dll", SetLastError = true)]
private static extern bool HidD_GetAttributes(
IntPtr DeviceObject,
ref USBDriver.HIDD_ATTRIBUTES Attributes);
[DllImport("hid.dll", SetLastError = true)]
private static extern uint HidP_GetCaps(
IntPtr PreparsedData,
ref USBDriver.HIDP_CAPS Capabilities);
[DllImport("hid.dll", SetLastError = true)]
private static extern int HidP_GetButtonCaps(
USBDriver.HIDP_REPORT_TYPE ReportType,
[In, Out] USBDriver.HIDP_BUTTON_CAPS[] ButtonCaps,
ref ushort ButtonCapsLength,
IntPtr PreparsedData);
[DllImport("hid.dll", SetLastError = true)]
private static extern int HidP_GetValueCaps(
USBDriver.HIDP_REPORT_TYPE ReportType,
[In, Out] USBDriver.HIDP_VALUE_CAPS[] ValueCaps,
ref ushort ValueCapsLength,
IntPtr PreparsedData);
[DllImport("hid.dll", SetLastError = true)]
private static extern int HidP_MaxUsageListLength(
USBDriver.HIDP_REPORT_TYPE ReportType,
ushort UsagePage,
IntPtr PreparsedData);
[DllImport("hid.dll", SetLastError = true)]
private static extern int HidP_SetUsages(
USBDriver.HIDP_REPORT_TYPE ReportType,
ushort UsagePage,
short LinkCollection,
short Usages,
ref int UsageLength,
IntPtr PreparsedData,
IntPtr Report,
int ReportLength);
[DllImport("hid.dll", SetLastError = true)]
private static extern int HidP_SetUsageValue(
USBDriver.HIDP_REPORT_TYPE ReportType,
ushort UsagePage,
short LinkCollection,
ushort Usage,
ulong UsageValue,
IntPtr PreparsedData,
IntPtr Report,
int ReportLength);
[DllImport("setupapi.dll", SetLastError = true)]
private static extern bool SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll")]
private static extern IntPtr GlobalFree(object hMem);
[DllImport("hid.dll", SetLastError = true)]
private static extern bool HidD_FreePreparsedData(ref IntPtr PreparsedData);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool SetCommTimeouts(
IntPtr hFile,
ref USBDriver.COMMTIMEOUTS lpCommTimeouts);
[DllImport("kernel32.dll")]
private static extern uint GetLastError();
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CancelIo(IntPtr hFile);
public bool IsConnected
{
get
{
return this.isConnected;
}
private set
{
this.isConnected = value;
}
}
public short ConnectedProductId
{
get
{
return this.connectedProductId;
}
private set
{
this.connectedProductId = value;
}
}
public USBDriver(ILogger logger)
{
this.logger = logger;
}
private USBDriver.HID_DEVICE[] FindKnownHidDevices(
int vendorId,
int[] productIds,
string pattern)
{
Guid guid = new Guid();
USBDriver.SP_DEVICE_INTERFACE_DATA deviceInterfaceData = new USBDriver.SP_DEVICE_INTERFACE_DATA();
USBDriver.SP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData = new USBDriver.SP_DEVICE_INTERFACE_DETAIL_DATA();
List<USBDriver.HID_DEVICE> hidDeviceList = new List<USBDriver.HID_DEVICE>();
USBDriver.HidD_GetHidGuid(ref guid);
USBDriver.SetupDiDestroyDeviceInfoList(this.hardwareDeviceInfo);
this.hardwareDeviceInfo = USBDriver.SetupDiGetClassDevs(ref guid, IntPtr.Zero, IntPtr.Zero, 18);
deviceInterfaceData.cbSize = Marshal.SizeOf(typeof (USBDriver.SP_DEVICE_INTERFACE_DATA));
for (int memberIndex = 0; USBDriver.SetupDiEnumDeviceInterfaces(this.hardwareDeviceInfo, IntPtr.Zero, ref guid, memberIndex, ref deviceInterfaceData); ++memberIndex)
{
int RequiredSize = 0;
USBDriver.SetupDiGetDeviceInterfaceDetail(this.hardwareDeviceInfo, ref deviceInterfaceData, IntPtr.Zero, 0, ref RequiredSize, IntPtr.Zero);
switch (IntPtr.Size)
{
case 4:
DeviceInterfaceDetailData.cbSize = 5;
break;
case 8:
DeviceInterfaceDetailData.cbSize = 8;
break;
}
USBDriver.SetupDiGetDeviceInterfaceDetail(this.hardwareDeviceInfo, ref deviceInterfaceData, ref DeviceInterfaceDetailData, RequiredSize, ref RequiredSize, IntPtr.Zero);
USBDriver.HID_DEVICE hidDevice = this.OpenHidDevice(DeviceInterfaceDetailData.DevicePath, vendorId, productIds, pattern);
if (hidDevice.HidDevice != IntPtr.Zero)
hidDeviceList.Add(hidDevice);
}
return hidDeviceList.ToArray();
}
private USBDriver.HID_DEVICE OpenHidDevice(
string DevicePath,
int vendorId,
int[] productIds,
string pattern)
{
this.logger.Info("OpenHidDevice Start", nameof (OpenHidDevice), "D:\\dev\\hhkb-keymap-tool\\HHKBKeymapTool\\Models\\USBDriver.cs", 554);
USBDriver.HID_DEVICE hidDevice = new USBDriver.HID_DEVICE();
hidDevice.DevicePath = DevicePath;
USBDriver.CloseHandle(hidDevice.HidDevice);
hidDevice.HidDevice = USBDriver.CreateFile(hidDevice.DevicePath, 3221225472U, 3U, (USBDriver.FileMapProtection) 0, 3U, 0U, IntPtr.Zero);
if (hidDevice.HidDevice == IntPtr.Zero)
{
this.logger.Error(string.Format("CreateFile Error ({0})", (object) DevicePath), nameof (OpenHidDevice), "D:\\dev\\hhkb-keymap-tool\\HHKBKeymapTool\\Models\\USBDriver.cs", 578);
return hidDevice;
}
hidDevice.Caps = new USBDriver.HIDP_CAPS();
hidDevice.Attributes = new USBDriver.HIDD_ATTRIBUTES();
if (!USBDriver.HidD_FreePreparsedData(ref hidDevice.Ppd))
this.logger.Info(string.Format("HidD_FreePreparsedData Error ({0})", (object) DevicePath), nameof (OpenHidDevice), "D:\\dev\\hhkb-keymap-tool\\HHKBKeymapTool\\Models\\USBDriver.cs", 592);
hidDevice.Ppd = IntPtr.Zero;
if (!USBDriver.HidD_GetAttributes(hidDevice.HidDevice, ref hidDevice.Attributes))
this.logger.Info(string.Format("HidD_GetAttributes Error ({0})", (object) DevicePath), nameof (OpenHidDevice), "D:\\dev\\hhkb-keymap-tool\\HHKBKeymapTool\\Models\\USBDriver.cs", 598);
int num = 0;
if ((int) hidDevice.Attributes.VendorID == vendorId)
++num;
if (((IEnumerable<int>) productIds).Contains<int>((int) hidDevice.Attributes.ProductID))
++num;
if (hidDevice.DevicePath.Contains(pattern))
++num;
if (num < 3)
{
USBDriver.CloseHandle(hidDevice.HidDevice);
hidDevice.HidDevice = IntPtr.Zero;
return hidDevice;
}
if (!USBDriver.HidD_GetPreparsedData(hidDevice.HidDevice, ref hidDevice.Ppd))
{
this.logger.Info(string.Format("HidD_GetPreparsedData Error ({0})", (object) DevicePath), nameof (OpenHidDevice), "D:\\dev\\hhkb-keymap-tool\\HHKBKeymapTool\\Models\\USBDriver.cs", 624);
hidDevice.Caps.InputReportByteLength = hidDevice.Caps.OutputReportByteLength = (ushort) (ConstDefinition.BufferSizeUSB + 1);
this.logger.Info("OpenHidDevice Abnormal End", nameof (OpenHidDevice), "D:\\dev\\hhkb-keymap-tool\\HHKBKeymapTool\\Models\\USBDriver.cs", 629);
return hidDevice;
}
if (USBDriver.HidP_GetCaps(hidDevice.Ppd, ref hidDevice.Caps) == 0U)
this.logger.Info(string.Format("HidP_GetCaps Error ({0})", (object) DevicePath), nameof (OpenHidDevice), "D:\\dev\\hhkb-keymap-tool\\HHKBKeymapTool\\Models\\USBDriver.cs", 635);
this.logger.Info("OpenHidDevice End", nameof (OpenHidDevice), "D:\\dev\\hhkb-keymap-tool\\HHKBKeymapTool\\Models\\USBDriver.cs", 638);
return hidDevice;
}
public bool Connect(int vendorId, int[] productIds, string pattern)
{
this.Disconnect();
USBDriver.HID_DEVICE[] knownHidDevices = this.FindKnownHidDevices(vendorId, productIds, pattern);
for (int index = 0; index < knownHidDevices.Length; ++index)
{
int num = 0;
if ((int) knownHidDevices[index].Attributes.VendorID == vendorId)
++num;
if (((IEnumerable<int>) productIds).Contains<int>((int) knownHidDevices[index].Attributes.ProductID))
++num;
if (knownHidDevices[index].DevicePath.Contains(pattern))
++num;
if (num == 3)
{
this.iHIDD = index;
this.currentDevice = new USBDriver.HID_DEVICE?(knownHidDevices[this.iHIDD]);
this.IsConnected = true;
this.ConnectedProductId = knownHidDevices[index].Attributes.ProductID;
this.logger.Info(string.Format("USB Found (VID:{0}, PID:{1}, PAT:{2}", (object) vendorId, (object) knownHidDevices[index].Attributes.ProductID, (object) pattern), nameof (Connect), "D:\\dev\\hhkb-keymap-tool\\HHKBKeymapTool\\Models\\USBDriver.cs", 679);
return true;
}
}
this.logger.Info(string.Format("USB Not Found (VID:{0}, PID:{1}, PAT:{2}", (object) vendorId, (object) ToolUtility.ConvertIntsToString(productIds), (object) pattern), nameof (Connect), "D:\\dev\\hhkb-keymap-tool\\HHKBKeymapTool\\Models\\USBDriver.cs", 686);
return false;
}
public void Disconnect()
{
if (this.currentDevice.HasValue)
USBDriver.CloseHandle(this.currentDevice.Value.HidDevice);
this.currentDevice = new USBDriver.HID_DEVICE?();
this.IsConnected = false;
}
public void ForcedDisconnect()
{
if (!this.currentDevice.HasValue)
return;
USBDriver.CancelIo(this.currentDevice.Value.HidDevice);
this.currentDevice = new USBDriver.HID_DEVICE?();
this.IsConnected = false;
}
public int Send(byte[] sendData, int timeout)
{
if (!this.currentDevice.HasValue)
{
this.logger.Info("No Connected Device.", nameof (Send), "D:\\dev\\hhkb-keymap-tool\\HHKBKeymapTool\\Models\\USBDriver.cs", 729);
return -1;
}
USBDriver.HID_DEVICE device = this.currentDevice.Value;
byte[] Report = new byte[(int) device.Caps.OutputReportByteLength];
uint sentLength = 0;
Report[0] = (byte) 0;
for (int index = 0; index < sendData.Length; ++index)
Report[index + 1] = sendData[index];
this.logger.Info(string.Format("Senddata\r\n{0}", (object) ToolUtility.ConvertBytesToString(sendData)), nameof (Send), "D:\\dev\\hhkb-keymap-tool\\HHKBKeymapTool\\Models\\USBDriver.cs", 745);
bool taskFinished = false;
Task.Factory.StartNew((Action) (() =>
{
USBDriver.WriteFile(device.HidDevice, Report, (uint) device.Caps.OutputReportByteLength, ref sentLength, IntPtr.Zero);
taskFinished = true;
})).Wait(timeout);
if (!taskFinished)
{
this.ForcedDisconnect();
throw new TimeoutException();
}
if (sentLength != 0U)
return (int) sentLength;
this.logger.Info(string.Format("Send Error : {0}", (object) ToolUtility.ConvertBytesToString(((IEnumerable<byte>) sendData).Take<byte>(8).ToArray<byte>())), nameof (Send), "D:\\dev\\hhkb-keymap-tool\\HHKBKeymapTool\\Models\\USBDriver.cs", 764);
this.logger.Info(string.Format("Senddata\r\n{0}", (object) ToolUtility.ConvertBytesToString(sendData)), nameof (Send), "D:\\dev\\hhkb-keymap-tool\\HHKBKeymapTool\\Models\\USBDriver.cs", 765);
return -1;
}
public byte[] Receive(int timeout)
{
if (!this.currentDevice.HasValue)
{
this.logger.Info("No Connected Device.", nameof (Receive), "D:\\dev\\hhkb-keymap-tool\\HHKBKeymapTool\\Models\\USBDriver.cs", 782);
return (byte[]) null;
}
USBDriver.HID_DEVICE device = this.currentDevice.Value;
byte[] Report = new byte[(int) device.Caps.InputReportByteLength];
uint receiveLength = 0;
bool taskFinished = false;
Task.Factory.StartNew((Action) (() =>
{
USBDriver.ReadFile(device.HidDevice, Report, (uint) device.Caps.InputReportByteLength, ref receiveLength, IntPtr.Zero);
taskFinished = true;
})).Wait(timeout);
if (!taskFinished)
{
this.ForcedDisconnect();
throw new TimeoutException();
}
if (receiveLength == 0U)
{
this.logger.Info(string.Format("Receive Error"), nameof (Receive), "D:\\dev\\hhkb-keymap-tool\\HHKBKeymapTool\\Models\\USBDriver.cs", 808);
return (byte[]) null;
}
byte[] data = new byte[ConstDefinition.BufferSizeUSB];
for (int index = 0; (long) index < (long) (receiveLength - 1U); ++index)
data[index] = Report[index + 1];
this.logger.Info(string.Format("Receivedata\r\n{0}", (object) ToolUtility.ConvertBytesToString(data)), nameof (Receive), "D:\\dev\\hhkb-keymap-tool\\HHKBKeymapTool\\Models\\USBDriver.cs", 819);
return data;
}
private enum FileMapProtection : uint
{
PageReadonly = 2,
PageReadWrite = 4,
PageWriteCopy = 8,
PageExecuteRead = 32, // 0x00000020
PageExecuteReadWrite = 64, // 0x00000040
SectionImage = 16777216, // 0x01000000
SectionReserve = 67108864, // 0x04000000
SectionCommit = 134217728, // 0x08000000
SectionNoCache = 268435456, // 0x10000000
}
private enum HIDP_REPORT_TYPE : ushort
{
HidP_Input,
HidP_Output,
HidP_Feature,
}
private struct LIST_ENTRY
{
public IntPtr Flink;
public IntPtr Blink;
}
private struct DEVICE_LIST_NODE
{
public USBDriver.LIST_ENTRY Hdr;
public IntPtr NotificationHandle;
public USBDriver.HID_DEVICE HidDeviceInfo;
public bool DeviceOpened;
}
private struct SP_DEVICE_INTERFACE_DATA
{
public int cbSize;
public Guid interfaceClassGuid;
public int flags;
private UIntPtr reserved;
}
private struct SP_DEVICE_INTERFACE_DETAIL_DATA
{
public int cbSize;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string DevicePath;
}
private struct SP_DEVINFO_DATA
{
public int cbSize;
public Guid classGuid;
public uint devInst;
public IntPtr reserved;
}
private struct HIDP_CAPS
{
[MarshalAs(UnmanagedType.U2)]
public ushort Usage;
[MarshalAs(UnmanagedType.U2)]
public ushort UsagePage;
[MarshalAs(UnmanagedType.U2)]
public ushort InputReportByteLength;
[MarshalAs(UnmanagedType.U2)]
public ushort OutputReportByteLength;
[MarshalAs(UnmanagedType.U2)]
public ushort FeatureReportByteLength;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
public ushort[] Reserved;
[MarshalAs(UnmanagedType.U2)]
public ushort NumberLinkCollectionNodes;
[MarshalAs(UnmanagedType.U2)]
public ushort NumberInputButtonCaps;
[MarshalAs(UnmanagedType.U2)]
public ushort NumberInputValueCaps;
[MarshalAs(UnmanagedType.U2)]
public ushort NumberInputDataIndices;
[MarshalAs(UnmanagedType.U2)]
public ushort NumberOutputButtonCaps;
[MarshalAs(UnmanagedType.U2)]
public ushort NumberOutputValueCaps;
[MarshalAs(UnmanagedType.U2)]
public ushort NumberOutputDataIndices;
[MarshalAs(UnmanagedType.U2)]
public ushort NumberFeatureButtonCaps;
[MarshalAs(UnmanagedType.U2)]
public ushort NumberFeatureValueCaps;
[MarshalAs(UnmanagedType.U2)]
public ushort NumberFeatureDataIndices;
}
private struct HIDD_ATTRIBUTES
{
public int Size;
public short VendorID;
public short ProductID;
public short VersionNumber;
}
public struct ButtonData
{
public int UsageMin;
public int UsageMax;
public int MaxUsageLength;
public short Usages;
}
public struct ValueData
{
public ushort Usage;
public ushort Reserved;
public ulong Value;
public long ScaledValue;
}
[StructLayout(LayoutKind.Explicit)]
private struct HID_DATA
{
[FieldOffset(0)]
public bool IsButtonData;
[FieldOffset(1)]
public byte Reserved;
[FieldOffset(2)]
public ushort UsagePage;
[FieldOffset(4)]
public int Status;
[FieldOffset(8)]
public int ReportID;
[FieldOffset(16)]
public bool IsDataSet;
[FieldOffset(17)]
public USBDriver.ButtonData ButtonData;
[FieldOffset(17)]
public USBDriver.ValueData ValueData;
}
public struct HIDP_Range
{
public ushort UsageMin;
public ushort UsageMax;
public ushort StringMin;
public ushort StringMax;
public ushort DesignatorMin;
public ushort DesignatorMax;
public ushort DataIndexMin;
public ushort DataIndexMax;
}
public struct HIDP_NotRange
{
public ushort Usage;
public ushort Reserved1;
public ushort StringIndex;
public ushort Reserved2;
public ushort DesignatorIndex;
public ushort Reserved3;
public ushort DataIndex;
public ushort Reserved4;
}
[StructLayout(LayoutKind.Explicit)]
private struct HIDP_BUTTON_CAPS
{
[FieldOffset(0)]
public ushort UsagePage;
[FieldOffset(2)]
public byte ReportID;
[MarshalAs(UnmanagedType.U1)]
[FieldOffset(3)]
public bool IsAlias;
[FieldOffset(4)]
public short BitField;
[FieldOffset(6)]
public short LinkCollection;
[FieldOffset(8)]
public short LinkUsage;
[FieldOffset(10)]
public short LinkUsagePage;
[MarshalAs(UnmanagedType.U1)]
[FieldOffset(12)]
public bool IsRange;
[MarshalAs(UnmanagedType.U1)]
[FieldOffset(13)]
public bool IsStringRange;
[MarshalAs(UnmanagedType.U1)]
[FieldOffset(14)]
public bool IsDesignatorRange;
[MarshalAs(UnmanagedType.U1)]
[FieldOffset(15)]
public bool IsAbsolute;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
[FieldOffset(16)]
public int[] Reserved;
[FieldOffset(56)]
public USBDriver.HIDP_Range Range;
[FieldOffset(56)]
public USBDriver.HIDP_NotRange NotRange;
}
[StructLayout(LayoutKind.Explicit)]
private struct HIDP_VALUE_CAPS
{
[FieldOffset(0)]
public ushort UsagePage;
[FieldOffset(2)]
public byte ReportID;
[MarshalAs(UnmanagedType.U1)]
[FieldOffset(3)]
public bool IsAlias;
[FieldOffset(4)]
public ushort BitField;
[FieldOffset(6)]
public ushort LinkCollection;
[FieldOffset(8)]
public ushort LinkUsage;
[FieldOffset(10)]
public ushort LinkUsagePage;
[MarshalAs(UnmanagedType.U1)]
[FieldOffset(12)]
public bool IsRange;
[MarshalAs(UnmanagedType.U1)]
[FieldOffset(13)]
public bool IsStringRange;
[MarshalAs(UnmanagedType.U1)]
[FieldOffset(14)]
public bool IsDesignatorRange;
[MarshalAs(UnmanagedType.U1)]
[FieldOffset(15)]
public bool IsAbsolute;
[MarshalAs(UnmanagedType.U1)]
[FieldOffset(16)]
public bool HasNull;
[FieldOffset(17)]
public byte Reserved;
[FieldOffset(18)]
public short BitSize;
[FieldOffset(20)]
public short ReportCount;
[FieldOffset(22)]
public ushort Reserved2a;
[FieldOffset(24)]
public ushort Reserved2b;
[FieldOffset(26)]
public ushort Reserved2c;
[FieldOffset(28)]
public ushort Reserved2d;
[FieldOffset(30)]
public ushort Reserved2e;
[FieldOffset(32)]
public int UnitsExp;
[FieldOffset(36)]
public int Units;
[FieldOffset(40)]
public int LogicalMin;
[FieldOffset(44)]
public int LogicalMax;
[FieldOffset(48)]
public int PhysicalMin;
[FieldOffset(52)]
public int PhysicalMax;
[FieldOffset(56)]
public USBDriver.HIDP_Range Range;
[FieldOffset(56)]
public USBDriver.HIDP_NotRange NotRange;
}
private struct HID_DEVICE
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string DevicePath;
public IntPtr HidDevice;
public bool OpenedForRead;
public bool OpenedForWrite;
public bool OpenedOverlapped;
public bool OpenedExclusive;
public IntPtr Ppd;
public USBDriver.HIDP_CAPS Caps;
public USBDriver.HIDD_ATTRIBUTES Attributes;
public IntPtr[] InputReportBuffer;
public USBDriver.HID_DATA[] InputData;
public int InputDataLength;
public USBDriver.HIDP_BUTTON_CAPS[] InputButtonCaps;
public USBDriver.HIDP_VALUE_CAPS[] InputValueCaps;
public IntPtr[] OutputReportBuffer;
public USBDriver.HID_DATA[] OutputData;
public int OutputDataLength;
public USBDriver.HIDP_BUTTON_CAPS[] OutputButtonCaps;
public USBDriver.HIDP_VALUE_CAPS[] OutputValueCaps;
public IntPtr[] FeatureReportBuffer;
public USBDriver.HID_DATA[] FeatureData;
public int FeatureDataLength;
public USBDriver.HIDP_BUTTON_CAPS[] FeatureButtonCaps;
public USBDriver.HIDP_VALUE_CAPS[] FeatureValueCaps;
}
public struct COMMTIMEOUTS
{
public uint ReadIntervalTimeout;
public uint ReadTotalTimeoutMultiplier;
public uint ReadTotalTimeoutConstant;
public uint WriteTotalTimeoutMultiplier;
public uint WriteTotalTimeoutConstant;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment