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

📄 usb.cpp

📁 usb的skype电话
💻 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 + -