Files
2025-03-13 12:04:22 -07:00

249 lines
9.8 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
}
}
}