#include <windows.h>
#include <stdio.h>
#include <winnt.h>
#include <errno.h>
#include <time.h>
#include <string.h>
#include <hidsdi.h>
#include <setupapi.h>
/*********************************************************************************************************************/
// 模块宏定义
/*********************************************************************************************************************/
#define OVERLAP_MODE 0 /* 是否要启用重叠异步模式打开HID设备文件 */
/*********************************************************************************************************************/
// 函数功能:主函数 - 用来列举出系统中所有可用的HID设备信息,并尝试打开他们获取其属性(有可能会打开失败)
// 输入参数:
// 输出参数:
// 返回参数:
/*********************************************************************************************************************/
int main(int argc, char** argv)
{
int deviceNo;
bool result;
HANDLE hidHandle;
GUID hidGuid;
ULONG requiredLength;
SP_DEVICE_INTERFACE_DATA devInfoData;
deviceNo = 0;
hidHandle = NULL;
devInfoData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
printf("Begin to list all HID device...\r\n\r\n");
/* HidD_GetHidGuid routine returns the device interfaceGUID for HIDClass devices - from MS */
HidD_GetHidGuid(&hidGuid);
printf("Get HID Guid: Data1[0x%X]. Data2[0x%X]. Data3[0x%X]. Data4[0x%X%X%X%X%X%X%X%X]\r\n", hidGuid.Data1, hidGuid.Data2, hidGuid.Data3,
hidGuid.Data4[0], hidGuid.Data4[1], hidGuid.Data4[2], hidGuid.Data4[3], hidGuid.Data4[4], hidGuid.Data4[5], hidGuid.Data4[6], hidGuid.Data4[7]);
/* SetupDiGetClassDevs返回一个包含本机上所有被请求的设备信息的设备信息集句柄 */
/* SetupDiGetClassDevs function returns a handle to a device information set that contains requested device information elements for a local computer - from MS */
HDEVINFO hDevInfo = SetupDiGetClassDevs(&hidGuid, NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE));
if (hDevInfo == INVALID_HANDLE_VALUE) {
printf("Fatal Error: SetupDiGetClassDevs Fail!!!\r\n");
return 1;
}
SetLastError(NO_ERROR); /* 首先清空错误代码,以便于后面的使用 */
while (1) {
printf("\r\ntry deviceNo %d.\r\n", deviceNo);
/* The SetupDiEnumDeviceInterfaces function enumerates the device interfaces that are contained in a device information set - from MS */
result = SetupDiEnumInterfaceDevice(hDevInfo, 0, &hidGuid, deviceNo, &devInfoData);
if ((result == false) || (GetLastError() == ERROR_NO_MORE_ITEMS)) { /* 出现ERROR_NO_MORE_ITEMS错误表示已经找完了所有的设备 */
printf("No More Item Left!!!\r\n\r\n");
break;
} else {
printf("----Get devInfoData: cbSize[%d]. Flags[0x%.2X]. InterfaceClassGuid([0x%X] [0x%X] [0x%X] [0x%X%X%X%X%X%X%X%X])\r\n",
devInfoData.cbSize, devInfoData.Flags, devInfoData.InterfaceClassGuid.Data1, devInfoData.InterfaceClassGuid.Data2, devInfoData.InterfaceClassGuid.Data3,
devInfoData.InterfaceClassGuid.Data4[0], devInfoData.InterfaceClassGuid.Data4[1], devInfoData.InterfaceClassGuid.Data4[2], devInfoData.InterfaceClassGuid.Data4[3],
devInfoData.InterfaceClassGuid.Data4[4], devInfoData.InterfaceClassGuid.Data4[5], devInfoData.InterfaceClassGuid.Data4[6], devInfoData.InterfaceClassGuid.Data4[7]);
}
/* The SetupDiGetDeviceInterfaceDetail function returns details about a device interface - From MS */
requiredLength = 0; /* 先将变量置零,以便于下一步进行获取 */
SetupDiGetInterfaceDeviceDetail(hDevInfo, &devInfoData, NULL, 0, &requiredLength, NULL); /* 第一次调用,为了获取requiredLength */
PSP_INTERFACE_DEVICE_DETAIL_DATA devDetail = (SP_INTERFACE_DEVICE_DETAIL_DATA *)malloc(requiredLength); /* 根据获取到的长度申请动态内存 */
devDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); /* 先对变量进行部分初始化 */
result = SetupDiGetInterfaceDeviceDetail(hDevInfo, &devInfoData, devDetail, requiredLength, NULL, NULL); /* 第二次调用,为了获取devDetail */
if (result == false) {
printf("Fatal Error: SetupDiGetInterfaceDeviceDetail fail!!!\r\n");
free(devDetail);
SetupDiDestroyDeviceInfoList(hDevInfo);
return 1;
} else {
printf("----Get devDetail: cbSize[%d] DevicePath[%s]\r\n", devDetail->cbSize, devDetail->DevicePath);
}
if (OVERLAP_MODE == 1) {
hidHandle = CreateFile(devDetail->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
} else {
hidHandle = CreateFile(devDetail->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
}
free(devDetail);
if (hidHandle == INVALID_HANDLE_VALUE) { /* 系统会将部分HID设备设置成独占模式 */
printf("CreateFile fail!!! dev maybe in_use. continue to try next one...\r\n");
++deviceNo;
continue;
}
_HIDD_ATTRIBUTES hidAttributes;
result = HidD_GetAttributes(hidHandle, &hidAttributes); /* 获取HID设备的属性 */
if (result == false) {
printf("Fatal Error: HidD_GetAttributes fail!!!\r\n");
CloseHandle(hidHandle);
SetupDiDestroyDeviceInfoList(hDevInfo);
return 1;
} else {
printf("----Get hidAttributes: Size[%d]. VersionNumber[%d]. ProductID[0x%X]. VendorID[0x%X]\r\n",
hidAttributes.Size, hidAttributes.VersionNumber, hidAttributes.ProductID, hidAttributes.VendorID);
}
CloseHandle(hidHandle);
++deviceNo;
}
/* The SetupDiDestroyDeviceInfoList function deletes a device information set and frees all associated memory - From MS */
SetupDiDestroyDeviceInfoList(hDevInfo);
printf("Search is Over!!! find %d HID_Dev altogether in your computer...\r\n\r\n", deviceNo);
printf("任务完成,按任意键退出...\r\n");
getchar();
getchar();
return 0;
}
VS2017简单的HID设备枚举工程及源码
3星 · 超过75%的资源 需积分: 50 68 浏览量
2019-02-20
20:08:51
上传
评论
收藏 5KB ZIP 举报
leon1741
- 粉丝: 1694
- 资源: 112
最新资源
- 永宏PLC例程源码东芝350T压铸机PLC程序
- Visual Basic语言教程.docx
- 永宏PLC例程源码18层永宏电梯程序
- Scratch语言教程.docx
- (资源包名是松下不必介意实际是台达)台达PLC例程源码自制收线架台达PLC程序(有注释)与威沦触摸屏程序
- Rust语言教程.docx
- (资源包名是松下不必介意实际是台达)台达PLC例程源码用台达PLC485通信控制11台英威腾变频启动停止速度设定
- (资源包名是松下不必介意实际是台达)台达PLC例程源码用台达EH2-40PLC两台控制5台台达ASDA-B伺服,天任文本作对话的
- (资源包名是松下不必介意实际是台达)台达PLC例程源码液压切块机程序
- (资源包名是松下不必介意实际是台达)台达PLC例程源码压瓦机
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈