internal static HIDDeviceInfo GetDevice(string hidPath) { bool result; HIDDeviceInfo hid = new HIDDeviceInfo(); hid.DIDetail.DevicePath = hidPath; // Open the device handle if (!hid.OpenHandle()) { return(null); } // Get the attributes of the current device result = NativeMethods.HidD_GetAttributes(hid.Handle.DangerousGetHandle(), ref hid.HIDAttr); // Close the device before returning in // case the user doesn't want it afterall. hid.Close(); if (result) { return(hid); } // Otherwise this isn't an HID device return(null); }
internal static IEnumerable <HIDDeviceInfo> EnumerateDevices(CancellationToken token, Predicate <HIDDeviceInfo> match) { IntPtr hDevInfo = IntPtr.Zero; try { int index = -1; bool result; int size; HIDDeviceInfo hid; // Create a new interface data struct and initialize its size SP_DEVICE_INTERFACE_DATA diData = new SP_DEVICE_INTERFACE_DATA(); diData.cbSize = Marshal.SizeOf <SP_DEVICE_INTERFACE_DATA>(); // Get a handle to all devices that are part of the HID class // Fun fact: DIGCF_PRESENT worked on my machine just fine. I reinstalled Vista, and now it no longer finds the Wiimote with that parameter enabled... hDevInfo = NativeMethods.SetupDiGetClassDevs(ref HIDGuid, null, IntPtr.Zero, DeviceInfoFlags.DeviceInterface); // | DeviceInfoFlags.Present); while (NativeMethods.SetupDiEnumDeviceInterfaces(hDevInfo, IntPtr.Zero, ref HIDGuid, ++index, ref diData)) { hid = new HIDDeviceInfo(diData); size = 0; if (token.IsCancellationRequested) { yield break; } // Get the buffer size for this device detail instance (returned in the size parameter) NativeMethods.SetupDiGetDeviceInterfaceDetail(hDevInfo, ref hid.DIData, IntPtr.Zero, 0, out size, IntPtr.Zero); // Actually get the detail struct if (!NativeMethods.SetupDiGetDeviceInterfaceDetail(hDevInfo, ref hid.DIData, ref hid.DIDetail, size, out size, IntPtr.Zero)) { continue; } //Debug.WriteLine(string.Format("{0}: {1} - {2}", index, hid.Path, Marshal.GetLastWin32Error())); // Open the device handle if (!hid.OpenHandle()) { continue; } result = NativeMethods.HidD_GetAttributes(hid.DangerousHandle, ref hid.HIDAttr); // Close the device before returning in // case the user doesn't want it afterall. hid.Close(); if (result && (match?.Invoke(hid) ?? true)) { yield return(hid); } } } finally { // clean up our list if (hDevInfo != IntPtr.Zero) { NativeMethods.SetupDiDestroyDeviceInfoList(hDevInfo); } } }