- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我使用 SetupAPI 执行函数 SetupDiGetClassDevs
并获取指针或句柄。
然后我开始一个循环并运行:
Return = SetupDiEnumDeviceInterfaces();
与
SP_DEVICE_INTERFACE_DATA.cbSize = 0
获取 SP_DEVICE_INTERFACE_DATA
所需的大小。
然后我设置这个大小并再次执行:
SP_DEVICE_INTERFACE_DATA.cbSize = return; // (the size)
SetupDiEnumDeviceInterfaces();
从我得到的数据结构中:
DevicePath
来自 SP_DEVINFO_DATA
和来自注册表的一堆信息,如果我想要的话,我相信。
我真正想要的是访问 HID 库并调用HidD_GetAttributes
从这个枚举设备中获取 VendorID
、ProductID
和 VersionNumber
,这样我就可以识别设备。
我预计此特定信息将来自 USB 设备本身。谁能告诉我该怎么做?
顺便说一句,在我的 Windows XP 版本中,我使用的是注册表路径,我找不到 HKEY_LOCAL_MACHINE\Enum\HID\...\Class
。
我什至没有找到 HKEY_LOCAL_MACHINE\Enum\
。我认为这是因为我还没有执行函数SetupDiEnumDeviceInterfaces
。
我只能在 Lakeview Research 中找到完整的数据。但它不包括这个主题。为什么它是垃圾时却在网上到处都是?
最佳答案
不确定这是不是你要找的:
BOOL CheckIfPresentAndGetUSBDevicePath(void)
{
/*
Before we can "connect" our application to our USB embedded device, we must first find the device.
A USB bus can have many devices simultaneously connected, so somehow we have to find our device only.
This is done with the Vendor ID (VID) and Product ID (PID). Each USB product line should have
a unique combination of VID and PID.
Microsoft has created a number of functions which are useful for finding plug and play devices. Documentation
for each function used can be found in the MSDN library. We will be using the following functions:
SetupDiGetClassDevs() //provided by setupapi.dll, which comes with Windows
SetupDiEnumDeviceInterfaces() //provided by setupapi.dll, which comes with Windows
GetLastError() //provided by kernel32.dll, which comes with Windows
SetupDiDestroyDeviceInfoList() //provided by setupapi.dll, which comes with Windows
SetupDiGetDeviceInterfaceDetail() //provided by setupapi.dll, which comes with Windows
SetupDiGetDeviceRegistryProperty() //provided by setupapi.dll, which comes with Windows
malloc() //part of C runtime library, msvcrt.dll?
CreateFile() //provided by kernel32.dll, which comes with Windows
We will also be using the following unusual data types and structures. Documentation can also be found in
the MSDN library:
PSP_DEVICE_INTERFACE_DATA
PSP_DEVICE_INTERFACE_DETAIL_DATA
SP_DEVINFO_DATA
HDEVINFO
HANDLE
GUID
The ultimate objective of the following code is to get the device path, which will be used elsewhere for getting
read and write handles to the USB device. Once the read/write handles are opened, only then can this
PC application begin reading/writing to the USB device using the WriteFile() and ReadFile() functions.
Getting the device path is a multi-step round about process, which requires calling several of the
SetupDixxx() functions provided by setupapi.dll.
*/
HDEVINFO DeviceInfoTable = INVALID_HANDLE_VALUE;
PSP_DEVICE_INTERFACE_DATA InterfaceDataStructure = new SP_DEVICE_INTERFACE_DATA;
// PSP_DEVICE_INTERFACE_DETAIL_DATA DetailedInterfaceDataStructure = new SP_DEVICE_INTERFACE_DETAIL_DATA; //Globally declared instead
SP_DEVINFO_DATA DevInfoData;
DWORD InterfaceIndex = 0;
DWORD StatusLastError = 0;
DWORD dwRegType;
DWORD dwRegSize;
DWORD StructureSize = 0;
PBYTE PropertyValueBuffer;
bool MatchFound = false;
DWORD ErrorStatus;
BOOL BoolStatus = FALSE;
DWORD LoopCounter = 0;
char * DeviceIDToFind = MY_DEVICE_ID;
// First populate a list of plugged in devices (by specifying "DIGCF_PRESENT"), which are of the specified class GUID.
DeviceInfoTable = SetupDiGetClassDevsUM(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
// Now look through the list we just populated. We are trying to see if any of them match our device.
while(true)
{
InterfaceDataStructure->cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
if(SetupDiEnumDeviceInterfacesUM(DeviceInfoTable, NULL, &InterfaceClassGuid, InterfaceIndex, InterfaceDataStructure))
{
ErrorStatus = GetLastError();
if(ErrorStatus == ERROR_NO_MORE_ITEMS) // Did we reach the end of the list of matching devices in the DeviceInfoTable?
{ // Cound not find the device. Must not have been attached.
SetupDiDestroyDeviceInfoListUM(DeviceInfoTable); //Clean up the old structure we no longer need.
return FALSE;
}
}
else // Else some other kind of unknown error ocurred...
{
ErrorStatus = GetLastError();
SetupDiDestroyDeviceInfoListUM(DeviceInfoTable); // Clean up the old structure we no longer need.
return FALSE;
}
// Now retrieve the hardware ID from the registry. The hardware ID contains the VID and PID, which we will then
// check to see if it is the correct device or not.
// Initialize an appropriate SP_DEVINFO_DATA structure. We need this structure for SetupDiGetDeviceRegistryProperty().
DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
SetupDiEnumDeviceInfoUM(DeviceInfoTable, InterfaceIndex, &DevInfoData);
// First query for the size of the hardware ID, so we can know how big a buffer to allocate for the data.
SetupDiGetDeviceRegistryPropertyUM(DeviceInfoTable, &DevInfoData, SPDRP_HARDWAREID, &dwRegType, NULL, 0, &dwRegSize);
// Allocate a buffer for the hardware ID.
PropertyValueBuffer = (BYTE *) malloc (dwRegSize);
if(PropertyValueBuffer == NULL) // if null, error, couldn't allocate enough memory
{ // Can't really recover from this situation, just exit instead.
SetupDiDestroyDeviceInfoListUM(DeviceInfoTable); // Clean up the old structure we no longer need.
return FALSE;
}
// Retrieve the hardware IDs for the current device we are looking at. PropertyValueBuffer gets filled with a
// REG_MULTI_SZ (array of null terminated strings). To find a device, we only care about the very first string in the
// buffer, which will be the "device ID". The device ID is a string which contains the VID and PID, in the example
// format "Vid_04d8&Pid_003f".
SetupDiGetDeviceRegistryPropertyUM(DeviceInfoTable, &DevInfoData, SPDRP_HARDWAREID, &dwRegType, PropertyValueBuffer, dwRegSize, NULL);
// Now check if the first string in the hardware ID matches the device ID of my USB device.
#ifdef UNICODE
String^ DeviceIDFromRegistry = gcnew String((wchar_t *)PropertyValueBuffer);
#else
String^ DeviceIDFromRegistry = gcnew String((char *)PropertyValueBuffer);
#endif
free(PropertyValueBuffer); // No longer need the PropertyValueBuffer, free the memory to prevent potential memory leaks
// Convert both strings to lower case. This makes the code more robust/portable accross OS Versions
DeviceIDFromRegistry = DeviceIDFromRegistry->ToLowerInvariant();
DeviceIDToFind = DeviceIDToFind->ToLowerInvariant();
// Now check if the hardware ID we are looking at contains the correct VID/PID
MatchFound = DeviceIDFromRegistry->Contains(DeviceIDToFind);
if(MatchFound == true)
{
// Device must have been found. Open WinUSB interface handle now. In order to do this, we will need the actual device path first.
// We can get the path by calling SetupDiGetDeviceInterfaceDetail(), however, we have to call this function twice: The first
// time to get the size of the required structure/buffer to hold the detailed interface data, then a second time to actually
// get the structure (after we have allocated enough memory for the structure.)
DetailedInterfaceDataStructure->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
// First call populates "StructureSize" with the correct value
SetupDiGetDeviceInterfaceDetailUM(DeviceInfoTable, InterfaceDataStructure, NULL, NULL, &StructureSize, NULL);
DetailedInterfaceDataStructure = (PSP_DEVICE_INTERFACE_DETAIL_DATA)(malloc(StructureSize)); //Allocate enough memory
if(DetailedInterfaceDataStructure == NULL) //if null, error, couldn't allocate enough memory
{ // Can't really recover from this situation, just exit instead.
SetupDiDestroyDeviceInfoListUM(DeviceInfoTable); //Clean up the old structure we no longer need.
return FALSE;
}
DetailedInterfaceDataStructure->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
// Now call SetupDiGetDeviceInterfaceDetail() a second time to receive the goods.
SetupDiGetDeviceInterfaceDetailUM(DeviceInfoTable, InterfaceDataStructure, DetailedInterfaceDataStructure, StructureSize, NULL, NULL);
// We now have the proper device path, and we can finally open a device handle to the device.
// WinUSB requires the device handle to be opened with the FILE_FLAG_OVERLAPPED attribute.
SetupDiDestroyDeviceInfoListUM(DeviceInfoTable); //Clean up the old structure we no longer need.
return TRUE;
}
InterfaceIndex++;
// Keep looping until we either find a device with matching VID and PID, or until we run out of devices to check.
// However, just in case some unexpected error occurs, keep track of the number of loops executed.
// If the number of loops exceeds a very large number, exit anyway, to prevent inadvertent infinite looping.
LoopCounter++;
if(LoopCounter == 10000000) // Surely there aren't more than 10 million devices attached to any forseeable PC...
{
return FALSE;
}
}//end of while(true)
}
关于c++ - SetupAPI.DLL 到 HID.DLL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2583125/
我正在构建一个 HID 设备。有谁知道 HID 协议(protocol)是否支持两种通信方式——主机可以向设备发送命令,例如,打开或关闭 LED、关闭电源等...? 最佳答案 是的。例如。可以使用 h
我正在尝试与某些 HID 设备进行数据交换。我设法使用 libusb_interrupt_transfer 函数实现从该设备读取,但我不知道如何实现向 HID 发送缓冲区,因为设备没有 OUT 端点。
我正在寻找为 HID 设备(具有自定义 VID/PID)创建一个 inf 文件。我只想用我们的字符串替换我们设备的字符串“HID 兼容设备”和“USB 输入设备”。 我知道这需要由 Microsoft
我在生成 HID 描述符时遇到了一些问题。 我想使用简单的报告,ID1 用于输入,ID2 用于输出 64 字节数据。 我意识到尽管 RTFMing 和谷歌搜索,我仍然不知道 HID 描述符中的某些字段
我有一个带有几个按钮的蓝牙 LE 操纵杆。我想不使用蓝牙设置直接将它连接到应用程序,而是通过 BluetoothLeScanner 连接到它. 我已经可以连接到心率监测器并定期收到心率值通知。 我还创
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 4 年前。
我试图通过 HID OMNIKEY 5427 CK 通过 APDUs 命令来操作 MIFARE 卡,即。 Ultralight C 卡,在 Windows 10 x64 操作系统环境中使用 WinSC
我正在尝试使用 AOA 2.0 协议(protocol)和 libusb 将按键发送到 Android 设备。我能够设置设备配件模式并能够注册 HID 设备。但是,每当我发送事件时,我都会收到错误:
使用 USB HID 传感器,我似乎只能用 chrome.usb API 枚举设备在 ChromeOS 上。 在 OS X 上我可以用 chrome.hid API 枚举没问题。 在 Chrome 操
我正在尝试使用 IOHIDManager API 从 Mac OsX 上的设备的 HID 报告中读取数据,例如鼠标的 X、Y、button1、Button2(Magic Apple Mouse) 使用
我正在尝试编写用户空间设备驱动程序以从自定义 HID 设备中提取一些数据。我执行以下操作以将 HID 管理中的设备引用存储到变量中。 CFSetRef device = IOHIDManagerCop
我正在尝试安装 cython-hidapi 以在 Ubuntu 12.04 上读取 USB。我已按照 https://github.com/gbishop/cython-hidapi 的说明进行操作并
在 Safari 4.0 上,我有一张打印“????”的支票。如果隐藏 === "#but0_0" 作品: $("#but0_0").attr("onmousedown",function(){ale
这个问题可能与 this 重复和 this线。但是由于他们都没有为我的问题提供明确的解决方案,所以我再次询问。 我需要的任务是通过 USB 连接 2 个键盘,然后通过 Java 应用程序分别管理每个键
我正在从事一个使用蓝牙 HID 配置文件的项目。我知道 Android 中的 BlueZ 堆栈具有 HID 支持,但它没有通过 Android Framework 扩展到应用程序层。 我主要关心的是了
我问@Stackoverflow 有点新,但这是我所拥有的最接近圣经的东西(除了 Ritchie 的 C 书),特别是在我的大多数主题的期末项目的这些日子里。无论如何,我的问题是关于与 HID 设备通
我正在尝试使用 UsbDeviceConnection.controlTransfer 获取 USB 设备的 HID 报告描述符,这样我就可以看到 USB HID 设备有哪些按钮。 我已经能够使用 b
我对使用 libhid 访问我们在 PIC 微 Controller 上开发的自定义 HID 设备很感兴趣。我已经能够成功运行 test_libhid 代码。使用此库读取和写入设备的说明在 test_
我正在尝试将 STM32F0-disco 用作 Windows PC 的键盘。正在打印的字符有问题。 下面的代码等到板载按钮被按下,然后应该打印一次这三个字符。 /* USER CODE BE
我想解构从 hid_read 的hidapi函数收到的原始报告。 据我了解,这可以通过使用设备报告描述符中的信息来实现。但是,当尝试查询那些描述符时,我迷失在HID Spec和hidapi中可用的方法
我是一名优秀的程序员,十分优秀!