Usb通讯

1 工程文件需要增加 三个头文件 hidsdi.h hidsdi.h hidusage.h



2 公共头文件中增加声明
extern "C" 
{
#include "hidsdi.h"
#include <setupapi.h>
}


3 设备通讯基类 CDevice


#pragma once
class CDevice
{
public:
CDevice(void);
virtual ~CDevice(void);


virtual BOOL Open() = 0;
virtual BOOL SendData(CMemoryBlock &mb) = 0;
virtual BOOL Read(CMemoryBlock &mb) = 0;
virtual void Close() = 0;
virtual void CancelRead() = 0;
virtual BOOL IsOpen() = 0;


protected:
CCriticalSection m_cs;
UCHAR m_buf[16384];
OVERLAPPED m_WriteOverlapped;
OVERLAPPED m_ReadOverlapped;
};


#include "StdAfx.h"
#include "MemoryBlock.h"
#include "Device.h"




CDevice::CDevice(void)
{
}




CDevice::~CDevice(void)
{
}




4 HID设备通讯实现类CHIDDevice


#pragma once
class CHIDDevice : public CDevice
{
public:
CHIDDevice(int vid, int pid);
~CHIDDevice(void);


virtual BOOL Open();
virtual BOOL SendData(CMemoryBlock &mb);
virtual BOOL Read(CMemoryBlock &mb);
virtual void Close();
virtual void CancelRead();
virtual BOOL IsOpen();


private:
BOOL FindUSBDevice();
BOOL Send(BYTE *pData, WORD bSize);


private:
int m_vid;
int m_pid;


HANDLE m_hReadHandle;
HANDLE m_hWriteHandle;
};


#include "StdAfx.h"
#include "MemoryBlock.h"
#include "Device.h"
#include "HIDDevice.h"
#include <shlwapi.h> 
#pragma comment(lib, "shlwapi.lib") 


CHIDDevice::CHIDDevice(int vid, int pid)
{
m_hReadHandle=INVALID_HANDLE_VALUE;
m_hWriteHandle=INVALID_HANDLE_VALUE;
memset(&m_WriteOverlapped, 0, sizeof(m_WriteOverlapped));
memset(&m_ReadOverlapped, 0, sizeof(m_ReadOverlapped));
m_vid = vid;
m_pid = pid;
}


CHIDDevice::~CHIDDevice(void)
{
}


BOOL CHIDDevice::Open()
{
m_cs.Lock();
if (!FindUSBDevice()) {
m_cs.Unlock();
return FALSE;
}


m_WriteOverlapped.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
m_ReadOverlapped.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);


m_cs.Unlock();
return TRUE;
}


void CHIDDevice::CancelRead()
{
m_cs.Lock();
if (IsOpen())
SetEvent(m_ReadOverlapped.hEvent);
m_cs.Unlock();
}


BOOL CHIDDevice::IsOpen()
{
if (m_hReadHandle == INVALID_HANDLE_VALUE || m_hWriteHandle == INVALID_HANDLE_VALUE)
return FALSE;
else
return TRUE;
}


BOOL CHIDDevice::FindUSBDevice()
{
SP_DEVICE_INTERFACE_DATA DevInterfaceData;
DevInterfaceData.cbSize = sizeof(DevInterfaceData);


HIDD_ATTRIBUTES DevAttributes;
DevAttributes.Size = sizeof(DevAttributes);


GUID HidGuid;
HidD_GetHidGuid(&HidGuid);
HDEVINFO hDevInfoSet=SetupDiGetClassDevs(&HidGuid, NULL, NULL, DIGCF_DEVICEINTERFACE|DIGCF_PRESENT);


DWORD MemberIndex = 0;
BOOL bDevFound = FALSE;
while(TRUE)
{
BOOL bResult = SetupDiEnumDeviceInterfaces(hDevInfoSet, NULL, &HidGuid, MemberIndex, &DevInterfaceData);
if(bResult == FALSE) 
break;


MemberIndex++;


DWORD RequiredSize;
bResult = SetupDiGetDeviceInterfaceDetail(hDevInfoSet, &DevInterfaceData, NULL, NULL, &RequiredSize, NULL);


PSP_DEVICE_INTERFACE_DETAIL_DATA pDevDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(RequiredSize);
if(pDevDetailData == NULL)
break;
pDevDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
bResult = SetupDiGetDeviceInterfaceDetail(hDevInfoSet, &DevInterfaceData, pDevDetailData, RequiredSize, NULL, NULL);


CString szDevPathName = pDevDetailData->DevicePath;
free(pDevDetailData);


if(bResult == FALSE)
continue;


        HANDLE hDevHandle = CreateFile(szDevPathName, 
           NULL,
                        FILE_SHARE_READ|FILE_SHARE_WRITE, 
                        NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(hDevHandle != INVALID_HANDLE_VALUE){
bResult = HidD_GetAttributes(hDevHandle, &DevAttributes);
CloseHandle(hDevHandle);
if(bResult==FALSE) 
continue;
if (DevAttributes.ProductID != m_pid || DevAttributes.VendorID != m_vid)
continue;


bDevFound = TRUE;


m_hReadHandle=CreateFile(szDevPathName, 
GENERIC_READ,
                FILE_SHARE_READ|FILE_SHARE_WRITE, 
                NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
NULL);
m_hWriteHandle=CreateFile(szDevPathName, 
    GENERIC_WRITE,
                 FILE_SHARE_READ|FILE_SHARE_WRITE, 
                 NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
NULL);
break;
}
else
continue;
}
SetupDiDestroyDeviceInfoList(hDevInfoSet);
return bDevFound;
}


BOOL CHIDDevice::Read(CMemoryBlock &mb) {
m_ReadOverlapped.InternalHigh = 0;
m_ReadOverlapped.Internal = 0;
if (!ReadFile(m_hReadHandle, m_buf, 65, NULL, &m_ReadOverlapped)) {
if (GetLastError() != ERROR_IO_PENDING)
return FALSE;
}
DWORD dwCount = 0;
if (!GetOverlappedResult(m_hReadHandle, &m_ReadOverlapped, &dwCount, TRUE))
return FALSE;
if (dwCount == 0)
return FALSE;
mb.Create(m_buf + 1, dwCount - 1);
return TRUE;
}


BOOL CHIDDevice::SendData(CMemoryBlock &mb)
{
BYTE *pData = mb.GetMemory();
WORD wSize = (WORD)mb.GetSize();
if (wSize <65)
{
return Send(pData, wSize);
}
else
{
int iIndex = 0;
for (int i = 0; i < (int)wSize/64 ; i ++)
{
if (!Send(pData+iIndex, 64))
{
return FALSE;
}
iIndex += 64;
}


if (wSize % 64 != 0)
{
return Send(pData + iIndex, (int)wSize - iIndex);
}
}


return TRUE;
}


BOOL CHIDDevice::Send(BYTE *pData, WORD bSize)
{
m_cs.Lock();
if (!IsOpen()) {
m_cs.Unlock();
return FALSE;
}
BYTE buf[65] = {0};
memcpy(buf+1, pData, bSize);
ResetEvent(m_WriteOverlapped.hEvent);
BOOL bSuccess = WriteFile(m_hWriteHandle, &buf[0], 65, NULL, &m_WriteOverlapped);
if (bSuccess == FALSE && GetLastError() != ERROR_IO_PENDING) {
m_cs.Unlock();
return FALSE;
}
DWORD dwWait = WaitForSingleObject(m_WriteOverlapped.hEvent, 600);
m_cs.Unlock();
if (dwWait != WAIT_OBJECT_0)
return FALSE;
return TRUE;
}


void CHIDDevice::Close()
{
m_cs.Lock();
if (m_hReadHandle != INVALID_HANDLE_VALUE)
{
CloseHandle(m_hReadHandle);
m_hReadHandle = INVALID_HANDLE_VALUE;
}
if (m_hWriteHandle != INVALID_HANDLE_VALUE)
{
CloseHandle(m_hWriteHandle);
m_hWriteHandle = INVALID_HANDLE_VALUE;
}
if(m_ReadOverlapped.hEvent) {
CloseHandle(m_ReadOverlapped.hEvent);
m_ReadOverlapped.hEvent = NULL;
}
if(m_WriteOverlapped.hEvent) {
CloseHandle(m_WriteOverlapped.hEvent);
m_WriteOverlapped.hEvent = NULL;
}
m_cs.Unlock();
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值