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);
///
/// Zero prevents other processes from opening a file or device if they request delete, read, or write access.
///
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);
///
/// The caller of this function must delete the returned device information set when it is no longer needed by calling SetupDiDestroyDeviceInfoList.
///
///
///
///
[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);
///
/// HidD_GetAttributes returns TRUE if succeeds; otherwise, it returns FALSE.
///
///
///
///
[DllImport("hid.dll")]
public static extern bool HidD_GetAttributes(IntPtr HidDeviceObject, HIDD_ATTRIBUTES Attributes);
///
/// [out] Pointer to a caller-allocated GUID buffer that the routine uses to return the device interface GUID for HIDClass devices.
///
///
[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);
///
/// 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).
///
///
///
///
/// bool
[DllImport("hid.dll")]
public static extern bool HidD_GetManufacturerString(IntPtr HidDeviceObject, out string Buffer, ulong BufferLength);
///
/// HidD_GetPhysicalDescriptor returns TRUE if it succeeds; otherwise, it returns FALSE. Use GetLastError to get extended error information.
///
///
///
///
///
[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);
///
/// The supplied buffer must be <= 4093 bytes (2^12 – 3).
///
///
///
///
///
[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);
///
/// 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.
///
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);
}
}
}