249 lines
9.8 KiB
C#
249 lines
9.8 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Runtime.InteropServices;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace Win_API
|
||
{
|
||
public static class NativeMethods
|
||
{
|
||
// The following GitHub link was very helpful in understanding how some of the WinApi calls work together, as well as
|
||
// for certain const values like DIGCF_PRESENT. https://github.com/mikeobrien/HidLibrary/tree/dc9026067dd0c511574c8ce726682ece4f45939e
|
||
|
||
//https://docs.microsoft.com/en-us/windows-hardware/drivers/install/setupapi
|
||
|
||
//https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/introduction-to-hid-concepts
|
||
|
||
|
||
public const uint GENERIC_READ = 0x80000000;
|
||
public const uint GENERIC_WRITE = 0x40000000;
|
||
public const int FILE_FLAG_OVERLAPPED = 0x40000000;
|
||
public const int FILE_ATTRIBUTE_NORMAL = 0x128;
|
||
|
||
public const short DIGCF_PRESENT = 0x2;
|
||
public const short DIGCF_DEVICEINTERFACE = 0x10;
|
||
public const int DIGCF_ALLCLASSES = 0x4;
|
||
|
||
public static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
|
||
|
||
/// <summary>
|
||
/// Zero prevents other processes from opening a file or device if they request delete, read, or write access.
|
||
/// </summary>
|
||
public enum FileShareMode
|
||
{
|
||
Zero = 0x00000000,
|
||
FILE_SHARE_DELETE = 0x00000004,
|
||
FILE_SHARE_READ = 0x00000001,
|
||
FILE_SHARE_WRITE = 0x00000002
|
||
}
|
||
|
||
public struct SECURITY_ATTRIBUTES
|
||
{
|
||
public int nLength;
|
||
public IntPtr lpSecurityDescriptor;
|
||
public bool bInheritHandle;
|
||
}
|
||
[DllImport("kernel32.dll")]
|
||
public static extern bool CancelIo(IntPtr hFile);
|
||
|
||
[DllImport("kernel32.dll")]
|
||
public static extern IntPtr CreateFileA(
|
||
string lpFileName,
|
||
uint dwDesiredAccess,
|
||
int dwShareMode,
|
||
ref SECURITY_ATTRIBUTES lpSecurityAttributes,
|
||
int dwCreationDisposition,
|
||
int dwFlagsAndAttributes,
|
||
IntPtr hTemplateFile);
|
||
|
||
[DllImport("kernel32.dll")]
|
||
public static extern bool ReadFile(
|
||
IntPtr hFile,
|
||
IntPtr lpBuffer,
|
||
uint nNumberOfBytesToRead,
|
||
out uint lpNumberOfBytesRead,
|
||
[In] ref System.Threading.NativeOverlapped lpOverlapped);
|
||
|
||
[DllImport("kernel32.dll")]
|
||
public static extern bool WriteFile(
|
||
IntPtr hFile,
|
||
byte[] lpBuffer,
|
||
uint nNumberOfBytesToWrite,
|
||
out uint lpNumberOfBytesWritten,
|
||
[In] ref System.Threading.NativeOverlapped lpOverlapped);
|
||
|
||
[DllImport("kernel32.dll")]
|
||
public static extern bool CloseHandle(IntPtr hHandle);
|
||
|
||
/// <summary>
|
||
/// The caller of this function must delete the returned device information set when it is no longer needed by calling SetupDiDestroyDeviceInfoList.
|
||
/// </summary>
|
||
/// <param name="guid"></param>
|
||
/// <param name="hwndParent"></param>
|
||
/// <returns></returns>
|
||
[DllImport("Setupapi.dll")]
|
||
public static extern IntPtr SetupDiCreateDeviceInfoList(Guid Guid, IntPtr HwndParent);
|
||
|
||
[DllImport("setupapi.dll")]
|
||
public static extern bool SetupDiCreateDeviceInfo(IntPtr DeviceInfoSet, string DeviceName, Guid ClassGuid, string DeviceDescription, uint CreationFlags, IntPtr DeviceInfoData);
|
||
|
||
[DllImport("setupapi.dll")]
|
||
public static extern bool SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet, uint MemberIndex, ref SP_DEVINFO_DATA DeviceInfoData);
|
||
|
||
[DllImport("setupapi.dll")]
|
||
public static extern bool SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData, Guid InterfaceClassGuid, uint MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
|
||
|
||
[DllImport("setupapi.dll")]
|
||
public static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr DeviceInterfaceDetailData, uint DeviceInterfaceDetailDataSize, ref uint RequiredSize, IntPtr DeviceInfoData);
|
||
|
||
[DllImport("setupapi.dll")]
|
||
public static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, ref SP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData, uint DeviceInterfaceDetailDataSize, ref uint RequiredSize, IntPtr DeviceInfoData);
|
||
|
||
[DllImport("setupapi.dll")]
|
||
public static extern bool SetupDiGetClassDevs(Guid ClassGuid, IntPtr Enumerator, IntPtr hwndParent, uint Flags);
|
||
|
||
[DllImport("setupapi.dll")]
|
||
public static extern bool SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);
|
||
|
||
/// <summary>
|
||
/// HidD_GetAttributes returns TRUE if succeeds; otherwise, it returns FALSE.
|
||
/// </summary>
|
||
/// <param name="HidDeviceObject"></param>
|
||
/// <param name="Attributes"></param>
|
||
/// <returns></returns>
|
||
[DllImport("hid.dll")]
|
||
public static extern bool HidD_GetAttributes(IntPtr HidDeviceObject, HIDD_ATTRIBUTES Attributes);
|
||
/// <summary>
|
||
/// [out] Pointer to a caller-allocated GUID buffer that the routine uses to return the device interface GUID for HIDClass devices.
|
||
/// </summary>
|
||
/// <param name="HidGuid"></param>
|
||
[DllImport("hid.dll")]
|
||
public static extern void HidD_GetHidGuid(out Guid HidGuid);
|
||
|
||
[DllImport("hid.dll")]
|
||
public static extern bool HidD_GetIndexString(IntPtr HidDeviceObject, ulong StringIndex, out string Buffer, ulong BufferLength);
|
||
/// <summary>
|
||
/// The maximum possible number of characters in an embedded string is device specific. For USB devices, the maximum string length is 126 wide characters (not including the terminating NULL character).
|
||
/// If the supplied buffer is not <= 4093 bytes(2^12 – 3) the call may fail(depending on the underlying protocol, HID/Bluetooth/SPI) with error code ERROR_GEN_FAILURE(0x0000001f).
|
||
/// </summary>
|
||
/// <param name="HidDeviceObject"></param>
|
||
/// <param name="Buffer"></param>
|
||
/// <param name="BufferLength"></param>
|
||
/// <returns>bool</returns>
|
||
[DllImport("hid.dll")]
|
||
public static extern bool HidD_GetManufacturerString(IntPtr HidDeviceObject, out string Buffer, ulong BufferLength);
|
||
|
||
/// <summary>
|
||
/// HidD_GetPhysicalDescriptor returns TRUE if it succeeds; otherwise, it returns FALSE. Use GetLastError to get extended error information.
|
||
/// </summary>
|
||
/// <param name="HidDeviceObject"></param>
|
||
/// <param name="Buffer"></param>
|
||
/// <param name="BufferLength"></param>
|
||
/// <returns></returns>
|
||
[DllImport("hid.dll")]
|
||
public static extern bool HidD_GetPhysicalDescriptor(IntPtr HidDeviceObject, out string Buffer, [In] ulong BufferLength);
|
||
|
||
[DllImport("hid.dll")]
|
||
public static extern bool HidD_GetPreparsedData(IntPtr HidDeviceObject, out HID_COLLECTION_INFORMATION PreparsedData);
|
||
|
||
/// <summary>
|
||
/// The supplied buffer must be <= 4093 bytes (2^12 – 3).
|
||
/// </summary>
|
||
/// <param name="HidDeviceObject"></param>
|
||
/// <param name="Buffer"></param>
|
||
/// <param name="BufferLength"></param>
|
||
/// <returns></returns>
|
||
[DllImport("hid.dll")]
|
||
public static extern bool HidD_GetProductString(IntPtr HidDeviceObject, out string Buffer, ulong BufferLength);
|
||
|
||
[DllImport("hid.dll")]
|
||
public static extern bool HidD_GetSerialNumberString(IntPtr HidDeviceObject, out string Buffer, ulong BufferLength);
|
||
|
||
[DllImport("hid.dll")]
|
||
public static extern bool HidD_GetNumInputBuffers(IntPtr HidDeviceObject, out ulong NumberBuffers);
|
||
[DllImport("hid.dll")]
|
||
public static extern bool HidD_SetNumInputBuffers(IntPtr HidDeviceObject, ulong NumberBuffers);
|
||
|
||
/// <summary>
|
||
/// A caller of HidD_GetAttributes, uses this structure to obtain a device's vendor information.
|
||
/// Before using a HIDD_ATTRIBUTES structure with HIDClass support routines, the caller must set the Size member.
|
||
/// </summary>
|
||
public struct HIDD_ATTRIBUTES
|
||
{
|
||
public ulong Size;
|
||
public ushort VendorID;
|
||
public ushort ProductID;
|
||
public ushort VersionNumber;
|
||
}
|
||
|
||
public struct HID_COLLECTION_INFORMATION
|
||
{
|
||
public ulong DescriptorSize;
|
||
public bool Polled;
|
||
public char[] Reserved1;
|
||
public ushort VendorID;
|
||
public ushort ProductID;
|
||
public ushort VersionNumber;
|
||
}
|
||
|
||
[StructLayout(LayoutKind.Sequential)]
|
||
public struct SP_DEVICE_INTERFACE_DATA
|
||
{
|
||
public uint cbSize;
|
||
public Guid InterfaceClassGuid;
|
||
public uint Flags;
|
||
public IntPtr Reserved;
|
||
}
|
||
|
||
[StructLayout(LayoutKind.Sequential)]
|
||
public struct SP_DEVINFO_DATA
|
||
{
|
||
public uint cbSize;
|
||
public Guid ClassGuid;
|
||
public uint DevInst;
|
||
public IntPtr Reserved;
|
||
}
|
||
|
||
[StructLayout(LayoutKind.Sequential)]
|
||
public struct SP_DEVICE_INTERFACE_DETAIL_DATA
|
||
{
|
||
public uint cbSize;
|
||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
|
||
public string DevicePath;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
public static SECURITY_ATTRIBUTES InitWithDefaultAttributes()
|
||
{
|
||
SECURITY_ATTRIBUTES attributes = new SECURITY_ATTRIBUTES
|
||
{
|
||
bInheritHandle = false,
|
||
lpSecurityDescriptor = IntPtr.Zero
|
||
};
|
||
attributes.nLength = Marshal.SizeOf(attributes);
|
||
return attributes;
|
||
}
|
||
public static IntPtr CreateNonManagedBuffer(byte[] buffer)
|
||
{
|
||
return Marshal.AllocHGlobal(buffer.Length);
|
||
}
|
||
|
||
public static byte[] CopyUnManagedBufferToManagedBuffer(IntPtr unManagedBuffer, int bytesRead)
|
||
{
|
||
var buffer = new byte[] { };
|
||
Marshal.Copy(unManagedBuffer, buffer, 0, bytesRead);
|
||
return buffer;
|
||
}
|
||
public static void DisposeNonManagedObject(IntPtr nonManagedObj)
|
||
{
|
||
Marshal.FreeHGlobal(nonManagedObj);
|
||
}
|
||
}
|
||
|
||
}
|