一、开发环境
平台:vs2015
头文件:
#include
#include
#include
#include
库文件:
setupapi.lib
hid.lib
二、开发流程
1、获取HID设备的GUID
void __stdcall HidD_GetHidGuid (_Out_ LPGUID HidGuid);
typedef struct _GUID {
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[ 8 ];
} GUID;
2、获取设备信息集合
HDEVINFO SetupDiGetClassDevs(
_In_opt_ CONST GUID *ClassGuid, //指定设备的GUID
_In_opt_ PCWSTR Enumerator, //指定设备实例字符串,NULL为不指定
_In_opt_ HWND hwndParent, //窗口句柄
_In_ DWORD Flags
);
3、获取设备接口信息
BOOL SetupDiEnumDeviceInterfaces(
_In_ HDEVINFO DeviceInfoSet, //设备信息集合
_In_opt_ PSP_DEVINFO_DATA DeviceInfoData, //指定某个设备信息
_In_ CONST GUID *InterfaceClassGuid, //GUID
_In_ DWORD MemberIndex, //设备index
_Out_ PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
);
4、获取设备接口详细信息
BOOL SetupDiGetDeviceInterfaceDetail(
_In_ HDEVINFO DeviceInfoSet,
_In_ PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
_Out_writes_bytes_to_opt_(DeviceInterfaceDetailDataSize, *RequiredSize) PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData,
_In_ DWORD DeviceInterfaceDetailDataSize,
_Out_opt_ _Out_range_(>=, sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W)) PDWORD RequiredSize,
_Out_opt_ PSP_DEVINFO_DATA DeviceInfoData
);
5、创建设备文件
HANDLE CreateFile(
_In_ LPCWSTR lpFileName,
_In_ DWORD dwDesiredAccess,
_In_ DWORD dwShareMode,
_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
_In_ DWORD dwCreationDisposition,
_In_ DWORD dwFlagsAndAttributes,
_In_opt_ HANDLE hTemplateFile
);
6、获取HID 信息
BOOLEAN __stdcall
HidD_GetAttributes (
_In_ HANDLE HidDeviceObject,
_Out_ PHIDD_ATTRIBUTES Attributes
);
typedef struct _HIDD_ATTRIBUTES {
ULONG Size; // = sizeof (struct _HIDD_ATTRIBUTES)
USHORT VendorID;
USHORT ProductID;
USHORT VersionNumber;
} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
7、读数据
BOOL ReadFile(
_In_ HANDLE hFile,
LPVOID lpBuffer,
_In_ DWORD nNumberOfBytesToRead,
_Out_opt_ LPDWORD lpNumberOfBytesRead,
_Inout_opt_ LPOVERLAPPED lpOverlapped
);
8、写数据
BOOL WriteFile(
_In_ HANDLE hFile,
LPCVOID lpBuffer,
_In_ DWORD nNumberOfBytesToWrite,
_Out_opt_ LPDWORD lpNumberOfBytesWritten,
_Inout_opt_ LPOVERLAPPED lpOverlapped
);
三、完整示例代码
#include
#include
#include
#include
#include
using namespace std;
HANDLE userHidFileHandle;
BOOL find_device(uint32_t PID, uint32_t VID);
int main(int argc, char *argv[])
{
BOOL isReadFile = false;
uint8_t readbuf[3];
DWORD numberOfBytesRead;
cout << "***********User Hid Device SoftWare************ " << endl;
if (find_device(22352, 1155))
{
while (true)
{
Sleep(1);
isReadFile = ReadFile(userHidFileHandle, readbuf,3,&numberOfBytesRead,NULL);
if(isReadFile)
{
for (int i = 0; i < numberOfBytesRead; i++)
{
cout << "0x" << hex << (uint32_t)readbuf[i] << endl;
}
}
}
}
return 0;
}
void show_guid(LPGUID HidGuid)
{
cout << hex << HidGuid->Data1 << "-";
cout << hex << HidGuid->Data2 << "-";
cout << hex << HidGuid->Data3 << "-";
for (int i = 0; i < 8; i++)
{
cout << hex << (uint32_t)(HidGuid->Data4[i]);
}
cout << endl;
}
BOOL find_device(uint32_t PID, uint32_t VID)
{
BOOL isFind = false;
GUID hid_guid;
HDEVINFO device_info;
BOOL isGetDeviceInterfaces = false;
BOOL isGetDeviceInterfaceDetail = false;
BOOL isGetAttributes = false;
uint32_t deviceIndex = 0;
SP_DEVICE_INTERFACE_DATA device_interface_data;
PSP_DEVICE_INTERFACE_DETAIL_DATA p_device_interface_detail_data;
DWORD requiredSize = 0;
HANDLE fileHandle;
HIDD_ATTRIBUTES hid_attribute;
HidD_GetHidGuid(&hid_guid);
show_guid(&hid_guid);
device_info = SetupDiGetClassDevs(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
do
{
device_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
isGetDeviceInterfaces = SetupDiEnumDeviceInterfaces(device_info, NULL, &hid_guid, deviceIndex,
&device_interface_data);
deviceIndex++;
if (isGetDeviceInterfaces)
{
cout << "GetDeviceInterFace success" << endl;
}
/*获取requiredSize*/
SetupDiGetDeviceInterfaceDetail(device_info, &device_interface_data,
NULL, 0, &requiredSize, NULL);
cout << "requiredSize:" << requiredSize << endl;
p_device_interface_detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(requiredSize);
p_device_interface_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
isGetDeviceInterfaceDetail = SetupDiGetDeviceInterfaceDetail(
device_info,
&device_interface_data,
p_device_interface_detail_data,
requiredSize,
NULL,
NULL);
if (isGetDeviceInterfaceDetail)
{
cout << "GetDeviceInterFaceDetail success" << endl;
/*创建设备文件*/
fileHandle = CreateFile(
p_device_interface_detail_data->DevicePath,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ| FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (fileHandle == INVALID_HANDLE_VALUE)
{
cout << "CreateFile Error!" << endl;
}
else
{
cout << "CreateFile success!" << endl;
/*获取HID信息*/
isGetAttributes = HidD_GetAttributes(fileHandle,&hid_attribute);
if (isGetAttributes)
{
cout << "PID:0x"<< hid_attribute.ProductID << endl;
cout << "VID:0x"<< hid_attribute.VendorID << endl;
if (hid_attribute.ProductID == PID && hid_attribute.VendorID == VID)
{
userHidFileHandle = fileHandle;
return true;
}
}
}
}
} while (isGetDeviceInterfaces);
return isFind;
}