private static extern bool HidD_GetAttributes(SafeFileHandle DeviceObject, ref HIDD_ATTRIBUTES Attributes);
public SafeFileHandle Open(ushort vid, ushort pid, int usagePage, int usage) { HidD_GetHidGuid(out Guid guid); var info = SetupDiGetClassDevs(ref guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (info == INVALID_HANDLE_VALUE) { // printf("HID/win32: SetupDiGetClassDevs failed"); return(new SafeFileHandle(IntPtr.Zero, false)); } var deviceInfoData = new SP_DEVICE_INTERFACE_DATA { cbSize = Marshal.SizeOf(typeof(SP_DEVICE_INTERFACE_DATA)) }; for (var index = 0;; index++) { var hasMore = SetupDiEnumDeviceInterfaces(info, NULL, ref guid, index, ref deviceInfoData); if (!hasMore) { SetupDiDestroyDeviceInfoList(info); return(new SafeFileHandle(IntPtr.Zero, false)); } if (GetDeviceDetails(info, deviceInfoData, out var details)) { continue; } var h = CreateFile(details.DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, NULL); if (h.IsInvalid) { continue; } var attrib = new HIDD_ATTRIBUTES { Size = Marshal.SizeOf <HIDD_ATTRIBUTES>() }; hasMore = HidD_GetAttributes(h, ref attrib); if (!hasMore) { h.Close(); continue; } //printf("HID/win32: USB Device:\n"); //printf("HID/win32: vid = 0x%04X\n", (int)(attrib.VendorID)); //printf("HID/win32: pid = 0x%04X\n", (int)(attrib.ProductID)); if (vid > 0 && vid != (int)(attrib.VendorID)) { h.Close(); continue; } if (pid > 0 && pid != (int)(attrib.ProductID)) { h.Close(); continue; } var hid_data = IntPtr.Zero; if (!HidD_GetPreparsedData(h, ref hid_data)) { // printf("HID/win32: HidD_GetPreparsedData failed\n"); h.Close(); continue; } var capabilities = new HIDP_CAPS(); HidP_GetCaps(hid_data, ref capabilities); // if (hidPGetCaps != 0) // { //// printf("HID/win32: HidP_GetCaps failed\n"); // HidD_FreePreparsedData(ref hid_data); // h.Close(); // continue; // } if (usagePage > 0 && usagePage != (int)(capabilities.UsagePage)) { HidD_FreePreparsedData(ref hid_data); h.Close(); continue; } if (usage > 0 && usage != (int)(capabilities.Usage)) { HidD_FreePreparsedData(ref hid_data); h.Close(); continue; } HidD_FreePreparsedData(ref hid_data); return(h); } }