public static IEnumerable <DeviceInfo> EnumerateHidDevices() { var devices = new List <DeviceInfo>(); var hidClass = HidDevices.HidClassGuid; var deviceInfoSet = NativeMethods.SetupDiGetClassDevs( classGuid: ref hidClass, enumerator: null, hwndParent: 0, flags: NativeMethods.DIGCF_PRESENT | NativeMethods.DIGCF_DEVICEINTERFACE ); if (deviceInfoSet.ToInt64() != NativeMethods.INVALID_HANDLE_VALUE) { var deviceInfoData = CreateDeviceInfoData(); var deviceIndex = 0; while (NativeMethods.SetupDiEnumDeviceInfo(deviceInfoSet, deviceIndex, ref deviceInfoData)) { deviceIndex += 1; var deviceInterfaceData = new NativeMethods.SP_DEVICE_INTERFACE_DATA(); deviceInterfaceData.cbSize = Marshal.SizeOf(deviceInterfaceData); var deviceInterfaceIndex = 0; while (NativeMethods.SetupDiEnumDeviceInterfaces(deviceInfoSet, ref deviceInfoData, ref hidClass, deviceInterfaceIndex, ref deviceInterfaceData)) { deviceInterfaceIndex++; var devicePath = GetDevicePath(deviceInfoSet, deviceInterfaceData); var description = GetBusReportedDeviceDescription(deviceInfoSet, ref deviceInfoData) ?? GetDeviceDescription(deviceInfoSet, ref deviceInfoData); devices.Add(new DeviceInfo { Path = devicePath, Description = description }); } } NativeMethods.SetupDiDestroyDeviceInfoList(deviceInfoSet); } return(devices); }
/// <summary> /// Document how that looks like for the controllers /// </summary> /// <param name="deviceInfoSet"></param> /// <param name="deviceInterfaceData"></param> /// <returns></returns> private static string GetDevicePath(IntPtr deviceInfoSet, NativeMethods.SP_DEVICE_INTERFACE_DATA deviceInterfaceData) { var bufferSize = 0; const int intPtrByteSize32Bits = 4; const int intPtrByteSize64Bits = 8; int deviceInterfaceDetailDataSize = intPtrByteSize64Bits; if (IntPtr.Size == intPtrByteSize32Bits) { deviceInterfaceDetailDataSize = intPtrByteSize32Bits + Marshal.SystemDefaultCharSize; } var deviceInterfaceDetailData = new NativeMethods.SP_DEVICE_INTERFACE_DETAIL_DATA { Size = deviceInterfaceDetailDataSize }; NativeMethods.SetupDiGetDeviceInterfaceDetailBuffer( deviceInfoSet, ref deviceInterfaceData, deviceInterfaceDetailData: IntPtr.Zero, // no details deviceInterfaceDetailDataSize: 0, requiredSize: ref bufferSize, deviceInfoData: IntPtr.Zero ); var success = NativeMethods.SetupDiGetDeviceInterfaceDetail( deviceInfoSet, ref deviceInterfaceData, ref deviceInterfaceDetailData, deviceInterfaceDetailDataSize: bufferSize, requiredSize: ref bufferSize, deviceInfoData: IntPtr.Zero ); if (success) { return(deviceInterfaceDetailData.DevicePath); } return(null); }