上位机——自定义HID设备与主机通讯

一、开发环境
平台:vs2015
头文件:

#include <Windows.h>
#include <SetupAPI.h>
#include <hidsdi.h>
#include <initguid.h>

库文件:
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 <Windows.h>
#include <SetupAPI.h>
#include <hidsdi.h>
#include <initguid.h>
#include <iostream>

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;
}

 

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值