⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chiddevice.cpp

📁 有关USB接口的HID主机应用软件开发通用例子,值得参考收藏@+@
💻 CPP
字号:
//*****************************************************************
//  ===================================================
//                  南  太  电  子 (深圳)  公 司                 
//  ===================================================
//  Copyright (C) 2005-2010  Namtai                               
//                                                              
//  软件名称:      Buzz Test                                             
//  模 块 名:      CHIDDevice.cpp                                             
//  使用语言:      VC6.0                                           
//  原设计人:      诸葛炼                                            
//  设计日期:      2005.3                                            
//  更改纪录:                                                  
//  ===================================================  
//  | 更改日期 | 更 改 人 |   更    改   说   明               |  
//  ===================================================  
//  |          |          |  3                                  |  
//  |          |          |                                    |  
//  ===================================================  
//  内容摘要 : 读写HID设备的文件
//  备    注 : 
//*****************************************************************
#include "stdafx.h"
#include "CHIDDevice.h"
#include "DBT.h"
#include <afx.h>
extern "C"
{
	#include "hidsdi.h"
	#include <setupapi.h>
}
#define VID 0x054c
#define PID 0x1000
//#define VID 0x046D
//#define PID 0xC220

CHIDDevice::CHIDDevice()
{
	DeviceHandle=NULL;
}

//===========================================================
// 功能说明: 查找并打开设备。
// 函数原形: IsOurProduct()
// 输入参数: 无
// 输出参数: 无
// 备    注: 
//===========================================================
BOOL CHIDDevice::IsOurProduct()// CreateFile is in this function
{
	int Index=0;
	PSP_INTERFACE_DEVICE_DETAIL_DATA detailData = NULL;
	HDEVINFO hDevInfo;
	if(DeviceHandle!=NULL)
	{
		CloseHandle(DeviceHandle);
		DeviceHandle=NULL;
	}
	while(1)									//循环查找
	{
		GUID HidGuid;
		HidD_GetHidGuid(&HidGuid);
		hDevInfo=SetupDiGetClassDevs(&HidGuid,NULL,NULL,DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);  //取得HID信息结构数组
		if(hDevInfo==INVALID_HANDLE_VALUE)
		{
			return 0;
		}
		SP_DEVICE_INTERFACE_DATA devInfoData;
		devInfoData.cbSize=sizeof(devInfoData);
		if(!SetupDiEnumDeviceInterfaces(hDevInfo,0,&HidGuid,Index,&devInfoData))      //设备枚举
		{
			SetupDiDestroyDeviceInfoList(hDevInfo);
			hDevInfo=NULL;
			return 0;
		}
		DWORD Length=0,RequiredSize=0;
		SetupDiGetDeviceInterfaceDetail(hDevInfo,&devInfoData,NULL,0,&Length,NULL);    //取得设备路径
		detailData=(PSP_INTERFACE_DEVICE_DETAIL_DATA) malloc(Length); 
		detailData->cbSize=sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA );
		if(!SetupDiGetDeviceInterfaceDetail(hDevInfo,&devInfoData,detailData,Length,&RequiredSize,NULL))   //取得设备路径
		{
			SetupDiDestroyDeviceInfoList(hDevInfo);
			free(detailData);
			detailData=NULL;
			hDevInfo=NULL;
			return 0;
		}
		DeviceHandle=CreateFile(detailData->DevicePath,GENERIC_READ|GENERIC_WRITE,
			/*FILE_SHARE_READ|FILE_SHARE_WRITE*/0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);   //开启设备
		HIDD_ATTRIBUTES Attributes;
		Attributes.Size=sizeof(Attributes);
		HidD_GetAttributes(DeviceHandle,&Attributes);			//取得厂商与产口ID
//			AfxMessageBox("取得厂商与产品ID错误");
//			return 0;
		if((Attributes.VendorID!=VID)||(Attributes.ProductID!=PID))  //
		{
			if(detailData!=NULL)									 //不是,继续查找
				free(detailData);
			SetupDiDestroyDeviceInfoList(hDevInfo);
			Index++;
			CloseHandle(DeviceHandle);
			detailData=NULL;
			hDevInfo=NULL;
			DeviceHandle=NULL;
		}
		else														 //是我们产品
		{
			if(detailData!=NULL)
				free(detailData);
			return 1;
		}
	}

	return 0;
}

//===========================================================
// 功能说明: 取得HID设备能力。
// 函数原形: Prepare()
// 输入参数: 无
// 输出参数: 无
// 备    注: 
//===========================================================
BOOL CHIDDevice::Prepare()
{
	if(!IsOurProduct())
		return 0;
	PHIDP_PREPARSED_DATA PreparsedData;
	HidD_GetPreparsedData(DeviceHandle,&PreparsedData);				//取得包含设备能力缓冲指针// get address
	NTSTATUS Status=HidP_GetCaps(PreparsedData,&Capabilities);       //取得设备能力	// get byte number
	//'Capabilities' is used in the third parameter in WriteFile indicate the byte number which the exe pass to driver
	//即, 应用程序传递给驱动程序的数据字节数
	return 1;
}

CHIDDevice::~CHIDDevice()
{
	Close();
}

//===========================================================
// 功能说明: 发送数据到HID设备。
// 函数原形: SendData(UCHAR* sSendData,int Length)
// 输入参数: sSendData :发送数据指针
// 输出参数: 无
// 备    注: 数据长度由报表确定
//===========================================================
UINT CHIDDevice::SendData(UCHAR* sSendData )
{
	unsigned long BytesWrite=0;
	OVERLAPPED HIDOverlapped;
	HANDLE hEventObject = CreateEvent(NULL,TRUE,TRUE,"");
	HIDOverlapped.hEvent = hEventObject;
	HIDOverlapped.Offset = 0;
	HIDOverlapped.OffsetHigh =0;
	WriteFile(DeviceHandle,sSendData,Capabilities.OutputReportByteLength,&BytesWrite,(LPOVERLAPPED) &HIDOverlapped);
	DWORD waitRes = 0;
	if( (waitRes=WaitForSingleObject(hEventObject,300)) == WAIT_TIMEOUT)
		CancelIo(DeviceHandle);
	CloseHandle(HIDOverlapped.hEvent);
	return waitRes;
}

//===========================================================
// 功能说明: 接收HID设备数据。
// 函数原形: ReceiveData(UCHAR* sReceiveData)
// 输入参数: sReceiveData :接收数据指针
// 输出参数: 无
// 备    注: 数据长度由报表确定
//===========================================================
UINT CHIDDevice::ReceiveData(UCHAR* sReceiveData)
{
	//AfxMessageBox("123");
	//TRACE("recv !\r\n");
	unsigned long BytesRead=0;
	OVERLAPPED HIDOverlapped;
	HANDLE hEventObject = CreateEvent(NULL,TRUE,TRUE,"");// 此处不太懂,为什么要创建事件?
	HIDOverlapped.hEvent = hEventObject;
	HIDOverlapped.Offset = 0;
	HIDOverlapped.OffsetHigh =0;
	ReadFile(DeviceHandle,sReceiveData,Capabilities.InputReportByteLength,&BytesRead,(LPOVERLAPPED) &HIDOverlapped);
	DWORD waitRes = 0;
	if( (waitRes=WaitForSingleObject(hEventObject,300)) == WAIT_TIMEOUT)
		CancelIo(DeviceHandle);
	CloseHandle(HIDOverlapped.hEvent);
	return waitRes;
}


HDEVNOTIFY CHIDDevice::RegisterNotificationInterface(HWND Reghandle)
{
       //AfxMessageBox("RegisterNotificationInterface");
		DEV_BROADCAST_DEVICEINTERFACE    broadcastInterface;
		broadcastInterface.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
		broadcastInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
		HidD_GetHidGuid(&broadcastInterface.dbcc_classguid);
		//AfxMessageBox("RegisterNotificationInterface");
		return RegisterDeviceNotification(Reghandle, &broadcastInterface, DEVICE_NOTIFY_WINDOW_HANDLE);

}

BOOL CHIDDevice::Close()
{
	BOOL bClose = 0 ;
	if(DeviceHandle!=NULL)
		bClose = CloseHandle(DeviceHandle);
	DeviceHandle=NULL;
	return bClose;
}

HDEVNOTIFY CHIDDevice::RegisterNotificationHandle(HWND Reghandle)
{
		DEV_BROADCAST_HANDLE broadcastHandle;

		broadcastHandle.dbch_size = sizeof(DEV_BROADCAST_HANDLE);
		broadcastHandle.dbch_devicetype = DBT_DEVTYP_HANDLE;
		broadcastHandle.dbch_handle = DeviceHandle;

		return RegisterDeviceNotification( Reghandle,
									&broadcastHandle,
									DEVICE_NOTIFY_WINDOW_HANDLE);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -