public static bool GetHIDDeviceCapabilities(SafeFileHandle hidHandle, ref HIDP_CAPS caps)
        {
            int    length        = -1;
            IntPtr preparsedData = IntPtr.Zero;
            bool   result        = HID.HidD_GetPreparsedData(hidHandle, ref preparsedData);

            if (result)
            {
                length = HID.HidP_GetCaps(preparsedData, ref caps);
                HID.HidD_FreePreparsedData(preparsedData);
            }
            return(result && length > 0);
        }
        public static string GetHidUsage(HIDP_CAPS capabilities)
        {
            int num = capabilities.UsagePage * 256 + capabilities.Usage;

            if (num == 0x0102)
            {
                return("mouse");
            }
            if (num == 0x0106)
            {
                return("keyboard");
            }

            return(null);
        }
        public static bool GetHIDDeviceCapabilities(string devicePath, ref HIDP_CAPS caps)
        {
            if (string.IsNullOrWhiteSpace(devicePath))
            {
                throw new ArgumentNullException(nameof(devicePath), "设备路径不能为空");
            }

            IntPtr hidHandle = Kernel32.Kernel32.CreateFile(devicePath,
                                                            AccessRights.DEFAULT,
                                                            ShareMode.FILE_SHARE_READ | ShareMode.FILE_SHARE_WRITE,
                                                            IntPtr.Zero,
                                                            CreationDisposition.OPEN_EXISTING,
                                                            0,
                                                            IntPtr.Zero);

            bool result = GetHIDDeviceCapabilities(new SafeFileHandle(hidHandle, true), ref caps);

            return(result);
        }
        public static DeviceInfo GetDevice(int vid, int pid)
        {
            string[] paths = HIDExtension.GetHIDDevicesPath();

            for (int i = 0; i < paths.Length; i++)
            {
                Console.WriteLine(paths[i]);
                IntPtr handle = Kernel32.Kernel32.CreateFile(paths[i], 3221225472u, 3, IntPtr.Zero, 3, 0x40000000, IntPtr.Zero);
                if (handle == IntPtr.Zero)
                {
                    Console.WriteLine("SafeFileHandle IsInvalid");
                    Console.WriteLine(Kernel32Extension.GetSysErrroMessage("CreateFile"));
                    continue;
                }

                HIDD_ATTRIBUTES attributes = new HIDD_ATTRIBUTES();
                bool            result1    = HIDExtension.GetHIDDeviceAttributes(new SafeFileHandle(handle, true), ref attributes);
                if (!result1)
                {
                    Console.WriteLine("GetHIDDeviceAttributes Error");
                    continue;
                }
                Console.WriteLine(attributes);

                HIDP_CAPS caps    = new HIDP_CAPS();
                bool      result2 = HIDExtension.GetHIDDeviceCapabilities(new SafeFileHandle(handle, true), ref caps);
                if (!result2)
                {
                    Console.WriteLine("GetHIDDeviceCapabilities Error.");
                    continue;
                }

                if (attributes.VendorID == vid && attributes.ProductID == pid && caps.InputReportByteLength > 0)
                {
                    Console.WriteLine("{0}  {1}", HIDExtension.GetHidUsage(caps), caps);
                    if (caps.InputReportByteLength > 0)
                    {
                        Console.WriteLine("Index::{0}", i);
                    }

                    int  numberBuffer = 0;
                    bool result3      = HID.HidD_GetNumInputBuffers(new SafeFileHandle(handle, true), ref numberBuffer);
                    Console.WriteLine("result3:{0} {1}", result3, numberBuffer);

                    byte[] inputReportBuffer = new byte[caps.InputReportByteLength];
                    bool   result4           = HID.HidD_GetInputReport(new SafeFileHandle(handle, true), inputReportBuffer, inputReportBuffer.Length + 1);
                    Console.WriteLine("result4:{0}", result4);

                    DeviceInfo device = new DeviceInfo();
                    device.Path         = paths[i];
                    device.Capabilities = caps;
                    device.Attributes   = attributes;
                    device.HidUsage     = GetHidUsage(caps);

                    /*
                     * device.HidHandle = Kernel32.Kernel32.CreateFile(paths[i],
                     *   0u,//AccessRights.GENERIC_READ | AccessRights.GENERIC_WRITE,
                     *   ShareMode.FILE_SHARE_READ | ShareMode.FILE_SHARE_WRITE,
                     *   IntPtr.Zero,
                     *   CreationDisposition.OPEN_EXISTING,
                     *   0,
                     *   IntPtr.Zero);
                     */
                    device.HidHandle         = new SafeFileHandle(handle, true);
                    device.InputReportLength = caps.InputReportByteLength;
                    //bool gib = HID.HidD_GetNumInputBuffers(handle, ref device.InputReportLength);
                    //Console.WriteLine("GNIB:{0} {1}", gib, device.InputReportLength);

                    device.FileStream = new FileStream(device.HidHandle, FileAccess.ReadWrite, caps.InputReportByteLength, true);
                    HID.HidD_FlushQueue(device.HidHandle);

                    return(device);
                }
            }

            return(null);// deviceList.ToArray();
        }
 public static extern int HidP_GetCaps(IntPtr PreparsedData, ref HIDP_CAPS Capabilities);