📄 usb.cpp
字号:
#include "stdafx.h"
#include "usbhead.h"
#include "usb.h"
/*----------------------------------------------------------------------------
; 显示DEBUG信息
----------------------------------------------------------------------------*/
void ShowMessage(CString str)
{
return;
TRACE(str);
}
/*----------------------------------------------------------------------------
; 显示操作结果
----------------------------------------------------------------------------*/
void ShowResult(void)
{
return;
DWORD Err;
CString Info;
Err=GetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,NULL,Err,0,
Info.GetBuffer(128),128,NULL);
ShowMessage(Info);
}
/*----------------------------------------------------------------------------
; 判断是否目标设备
; ReportID 键值 属性
----------------------------------------------------------------------------*/
UINT ThreadWaitForUsbKey(LPVOID pParam)
{
TRACE("ThreadWaitForUsbKey \n");
DWORD TransforBytes;
UCHAR buff[8]={0x02,};
HANDLE hKeyDevice;
CUsbTerminal *pUsb=(CUsbTerminal *)pParam;
try_connect:
while(pUsb->SeachHIDdevice(C_VendorID, C_ProductID, C_VersionNumber)==0)
{
Sleep(2000);
}
if(pUsb->m_Hwnd && pUsb->m_Msg) //设备连接成功
SendMessage(pUsb->m_Hwnd, pUsb->m_Msg, C_WM_CONNECT_TERMINAL, C_CONNECT_ON );
//打开设备接口
hKeyDevice=CreateFile (
pUsb->UsbDevice[C_KEY_REPORT].DeviceName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
NULL);
pUsb->m_hKeyDevice= hKeyDevice;
HANDLE IoWait=CreateEvent(NULL,TRUE,FALSE,NULL);
OVERLAPPED OL;
OL.Offset=0;
OL.OffsetHigh=0;
OL.hEvent=IoWait;
while(1)
{
ResetEvent(IoWait);
if(!ReadFile(hKeyDevice,buff, pUsb->UsbDevice[C_KEY_REPORT].InputReportByteLength,
&TransforBytes, &OL))
{
if(GetLastError()!=ERROR_IO_PENDING) //错误
{
TRACE("ThreadWaitForUsbKey ReadFile ERROR \n");
ShowResult();
if(pUsb->m_Hwnd && pUsb->m_Msg) //设备无连接
SendMessage(pUsb->m_Hwnd, pUsb->m_Msg, C_WM_CONNECT_TERMINAL, C_CONNECT_OFF );
pUsb->ReleaseSrouce();
goto try_connect;
}
while(WaitForSingleObject(IoWait, 0xFFFFFFFF)==WAIT_TIMEOUT);
}
//收到按键
SendMessage(pUsb->m_Hwnd, pUsb->m_Msg, C_WM_KEY_DOWN, buff[1]+buff[2]*0x100);
TRACE("Receive: %2x, %2x, %2x, %2x, %2x \n", buff[0], buff[1],buff[2],buff[3],buff[4]);
}
}
/*----------------------------------------------------------------------------
; 判断是否目标设备
----------------------------------------------------------------------------*/
bool CUsbTerminal::ValidReportId(UCHAR ReportId)
{
switch(ReportId)
{
case 0x02:
case 0x03:
return(1);
default:
return(0);
}
}
bool CUsbTerminal::IsMyDevice(HDEVINFO hDevInfo, SP_DEVICE_INTERFACE_DATA strtInterfaceData,
USHORT VendorID, USHORT ProductID, USHORT VersionNumber)
{
bool Result=FALSE;
CString strShow;
HANDLE hDevice;
HIDD_ATTRIBUTES strtAttrib;
PSP_DEVICE_INTERFACE_DETAIL_DATA strtDetailData;
//获取接口详细的信息,包括设备名称
DWORD strSzie=0,requiesize=0;
SetupDiGetDeviceInterfaceDetail(hDevInfo,&strtInterfaceData,NULL,0,&strSzie,NULL);
requiesize=strSzie;
strtDetailData=(PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(requiesize);
strtDetailData->cbSize=sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if (!SetupDiGetDeviceInterfaceDetail(hDevInfo,&strtInterfaceData,
strtDetailData,strSzie,&requiesize,NULL))
{
ShowMessage("查找设备路径时出错!");
goto check_end;
}
strShow.Format("设备路径:\r\n%s\r\n",strtDetailData->DevicePath);
ShowMessage(strShow);
//打开设备接口
hDevice = CreateFile (
strtDetailData->DevicePath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hDevice == INVALID_HANDLE_VALUE)
{
ShowMessage("设备打开失败!");
goto check_end;
}
//读取设备的标识
strtAttrib.Size=sizeof(HIDD_ATTRIBUTES);
if (!HidD_GetAttributes(hDevice,&strtAttrib))
{
ShowMessage("读取设备的标识失败!");
goto check_end;
}
//比较VendorID ProductID VersionNumber
if(VendorID==strtAttrib.VendorID && ProductID==strtAttrib.ProductID)
{
if(VersionNumber==0 || VersionNumber==strtAttrib.VersionNumber)
{
PHIDP_PREPARSED_DATA PreparsedData;
HIDP_CAPS Capabilities;
HIDP_VALUE_CAPS ValueCaps;
//
HidD_GetPreparsedData(hDevice, &PreparsedData);
ShowResult();
HidP_GetCaps(PreparsedData, &Capabilities);
ShowResult();
HidP_GetValueCaps(HidP_Input, &ValueCaps,
&Capabilities.NumberInputValueCaps, PreparsedData);
ShowResult();
UCHAR ReportId=ValueCaps.ReportID;
if(!ValidReportId(ReportId))
goto check_end;
UsbDevice[ReportId].hDevice=hDevice;
UsbDevice[ReportId].DeviceName=strtDetailData->DevicePath;
UsbDevice[ReportId].ReportID=ValueCaps.ReportID;
UsbDevice[ReportId].InputReportByteLength=Capabilities.InputReportByteLength;
UsbDevice[ReportId].OutputReporByteLength=Capabilities.OutputReportByteLength;
Result=TRUE;
}
}
check_end:
if(hDevice && Result==FALSE)
CloseHandle(hDevice);
if(strtDetailData)
free(strtDetailData);
return Result;
}
/*==========================================================================
; 查找目标设备
==========================================================================*/
bool CUsbTerminal::SeachHIDdevice(USHORT VendorID, USHORT ProductID, USHORT VersionNumber)
{
// TRACE("SeachHIDdevice \n");
bool Result=FALSE;
CString strShow;
//取HID类的GUID标识
GUID guidHID;
HidD_GetHidGuid(&guidHID);
strShow="HID类的GUID标识为:\r\n";
ShowMessage(strShow);
strShow.Format("%08x-%04x-%04x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\r\n",
guidHID.Data1,guidHID.Data2,guidHID.Data3,guidHID.Data4[0],
guidHID.Data4[1],guidHID.Data4[2],guidHID.Data4[3],guidHID.Data4[4],
guidHID.Data4[5],guidHID.Data4[6],guidHID.Data4[7]);
ShowMessage(strShow);
//取HID设备集合的句柄
HDEVINFO hDevInfo = SetupDiGetClassDevs(&guidHID,NULL,0,
DIGCF_PRESENT|DIGCF_DEVICEINTERFACE );
if(hDevInfo==INVALID_HANDLE_VALUE)
{
SetupDiDestroyDeviceInfoList(hDevInfo);
ShowMessage("查找USB设备出错!\r\n");
return Result;
}
//查询HID设备集中每一个设备的接口信息
SP_DEVICE_INTERFACE_DATA strtInterfaceData;
strtInterfaceData.cbSize=sizeof(SP_DEVICE_INTERFACE_DATA);
DWORD i;
for(i=0; i<10; i++)
{
if(SetupDiEnumDeviceInterfaces(hDevInfo,NULL,&guidHID,i,&strtInterfaceData))
{
if(strtInterfaceData.Flags==SPINT_ACTIVE )
{
if(IsMyDevice(hDevInfo,strtInterfaceData,VendorID,ProductID,VersionNumber))
{
Result=TRUE;
// break;
}
}
}
else
break;
}
strShow.Format("查找设备数%d \n",i);
ShowMessage(strShow);
SetupDiDestroyDeviceInfoList(hDevInfo);
return Result;
}
/*----------------------------------------------------------------------------
; 释放资源
----------------------------------------------------------------------------*/
void CUsbTerminal::ReleaseSrouce(void)
{
TRACE("ReleaseSrouce \n");
int i;
for(i=0; i<C_MAX_USB_DEVICE; i++)
{
if(UsbDevice[i].hDevice)
{
CloseHandle(UsbDevice[i].hDevice);
ShowResult();
UsbDevice[i].hDevice=NULL;
}
}
if(m_hKeyDevice)
{
CloseHandle(m_hKeyDevice);
ShowResult();
m_hKeyDevice=NULL;
}
}
/*==========================================================================
; 查找目标设备
==========================================================================*/
void CUsbTerminal::UsbOpen(void)
{
if(IOThread==NULL)
{
IOThread=AfxBeginThread(ThreadWaitForUsbKey, this);
ShowResult();
TRACE("AfxBeginThread IOThread %x \n",IOThread->m_nThreadID);
}
}
void CUsbTerminal::UsbClose(void)
{
if(IOThread)
{
TerminateThread(IOThread->m_hThread, 0);
ShowResult();
TRACE("TerminateThread IOThread\n");
CloseHandle(IOThread->m_hThread);
ShowResult();
TRACE("CloseHandle IOThread\n");
IOThread=NULL;
}
ReleaseSrouce();
}
/*==========================================================================
; 把数据分解成SetReport数据包格式发送
; 格式: ReportID, Len, (用户数据DATA1 .... DATAn), 填充数据xx ...
==========================================================================*/
void CUsbTerminal::UsbWrite(UCHAR ReportId, PUCHAR data, DWORD Len)
{
// TRACE("UsbWrite \n");
UCHAR Buff[256];
DWORD ReportByteLength, DataLen;
DWORD TransforBytes;
if(UsbDevice[ReportId].hDevice==NULL)
return;
Buff[0]=UsbDevice[ReportId].ReportID;
ReportByteLength=UsbDevice[ReportId].OutputReporByteLength;
while(Len)
{
if(Len>ReportByteLength-2)
DataLen=ReportByteLength-2;
else
DataLen=Len;
Buff[1]=(UCHAR)DataLen;
memcpy(Buff+2, data, DataLen);
WriteFile( UsbDevice[ReportId].hDevice, Buff,
ReportByteLength, &TransforBytes, 0);
ShowResult();
Len-=DataLen;
data+=DataLen;
}
}
CUsbTerminal::CUsbTerminal()
{
m_Hwnd=NULL;
m_Msg=NULL;
IOThread=NULL;
m_hKeyDevice=NULL;
for(int i=0; i<C_MAX_USB_DEVICE; i++)
{
UsbDevice[i].hDevice=NULL;
}
}
CUsbTerminal::~CUsbTerminal()
{
UsbClose();
m_Hwnd=NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -