1 Star 0 Fork 0

jeffkuang/USB_ICCardReader_Test

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
Hid.cpp 18.08 KB
一键复制 编辑 原始数据 按行查看 历史
jeffkuang 提交于 2015-06-08 21:06 +08:00 . 建立VS2008工程项目。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
//////////////////////////////////////////////////////////////////////////
// Hid.cpp: implementation of the CHid class. //
// 百合电子工作室 //
// www.baiheee.com //
//////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
//#include "EasyUsbProgramer.h"
#include "Hid.h"
#include "Windows.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
/* global constants */
#define VID 0x0483//0x0471
#define PID 0x5750//0x0666
extern "C" {
// This file is in the Windows DDK available from Microsoft.
#include "hidsdi.h"
#include <setupapi.h>
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CHid::CHid(HANDLE *hParentWnd)
{
m_hParentWnd = hParentWnd;
}
CHid::CHid()
{
m_bMyDeviceDetected = FALSE;
m_bDeviceNoficationRegistered = FALSE;
}
CHid::~CHid()
{
/* end HID device plug/unplug notifications */
UnregisterDeviceNotification( m_hDevNotify );
}
/**********************************************************
*
* Function: OpenHidDevice
* Purpose: tries to open a HID device based on VID and PID
* Parameters: vid - HID device's vendor ID
* pid - HID device's product ID
* HidDevHandle - pointer to a handle to the HID device
* Returns: TRUE, if device is found
* FALSE, if device is not found
*
**********************************************************/
BOOL CHid::OpenHidDevice(HANDLE *HidDevHandle, USHORT vid, USHORT pid)
{
static GUID HidGuid; /* HID Globally Unique ID: windows supplies us with this value */
HDEVINFO HidDevInfo; /* handle to structure containing all attached HID Device information */
SP_DEVICE_INTERFACE_DATA devInfoData; /* Information structure for HID devices */
BOOLEAN Result; /* result of getting next device information structure */
DWORD Index; /* index of HidDevInfo array entry */
DWORD DataSize; /* size of the DeviceInterfaceDetail structure */
BOOLEAN GotRequiredSize; /* 1-shot got device info data structure size flag */
PSP_DEVICE_INTERFACE_DETAIL_DATA detailData;/* device info data */
DWORD RequiredSize; /* size of device info data structure */
BOOLEAN DIDResult; /* get device info data result */
HIDD_ATTRIBUTES HIDAttrib; /* HID device attributes */
/* initialize variables */
GotRequiredSize = FALSE;
/* 1) Get the HID Globally Unique ID from the OS */
HidD_GetHidGuid(&HidGuid);
/* 2) Get an array of structures containing information about
all attached and enumerated HIDs */
HidDevInfo = SetupDiGetClassDevs( &HidGuid,
NULL,
NULL,
DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
/* 3) Step through the attached device list 1 by 1 and examine
each of the attached devices. When there are no more entries in
the array of structures, the function will return FALSE. */
Index = 0; /* init to first index of array */
devInfoData.cbSize = sizeof(devInfoData); /* set to the size of the structure
that will contain the device info data */
do {
/* Get information about the HID device with the 'Index' array entry */
Result = SetupDiEnumDeviceInterfaces( HidDevInfo,
0,
&HidGuid,
Index,
&devInfoData);
/* If we run into this condition, then there are no more entries
to examine, we might as well return FALSE at point */
if(Result == FALSE)
{
/* free the memory allocated for DetailData */
if(detailData != NULL)
// free(detailData);
/* free HID device info list resources */
SetupDiDestroyDeviceInfoList(HidDevInfo);
return FALSE;
}
if(GotRequiredSize == FALSE)
{
/* 3) Get the size of the DEVICE_INTERFACE_DETAIL_DATA
structure. The first call will return an error condition,
but we'll get the size of the strucure */
DIDResult = SetupDiGetDeviceInterfaceDetail(HidDevInfo,
&devInfoData,
NULL,
0,
&DataSize,
NULL);
GotRequiredSize = TRUE;
/* allocate memory for the HidDevInfo structure */
detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(DataSize);
/* set the size parameter of the structure */
detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
}
/* 4) Now call the function with the correct size parameter. This
function will return data from one of the array members that
Step #2 pointed to. This way we can start to identify the
attributes of particular HID devices. */
DIDResult = SetupDiGetDeviceInterfaceDetail( HidDevInfo,
&devInfoData,
detailData,
DataSize,
&RequiredSize,
NULL);
/* 5) Open a file handle to the device. Make sure the
attibutes specify overlapped transactions or the IN
transaction may block the input thread. */
*HidDevHandle = CreateFile( detailData->DevicePath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
(LPSECURITY_ATTRIBUTES)NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
/* 6) Get the Device VID & PID to see if it's the device we want */
if(*HidDevHandle != INVALID_HANDLE_VALUE)
{
HIDAttrib.Size = sizeof(HIDAttrib);
HidD_GetAttributes( *HidDevHandle, &HIDAttrib);
if((HIDAttrib.VendorID == VID) && (HIDAttrib.ProductID == PID))
{
/* free the memory allocated for DetailData */
if(detailData != NULL)
free(detailData);
/* free HID device info list resources */
SetupDiDestroyDeviceInfoList(HidDevInfo);
return TRUE; /* found HID device */
}
/* 7) Close the Device Handle because we didn't find the device
with the correct VID and PID */
CloseHandle(*HidDevHandle);
}
Index++; /* increment the array index to search the next entry */
} while(Result == TRUE);
/* free the memory allocated for DetailData */
if(detailData != NULL)
free(detailData);
/* free HID device info list resources */
SetupDiDestroyDeviceInfoList(HidDevInfo);
return FALSE;
}
/**********************************************************
*
* Function: HidDeviceNotify
* Purpose: Sets up the HID device notification events. The
* message contains the events
* DBT_DEVICEARRIVAL and DBT_DEVICEREMOVALCOMPLETE. It
* is then up to the application to find out if the
* event is refering to the device it is connected with by
* parsing a structure that the event points to.
* Parameters: hWnd - handle to window that notifications should be
* sent to.
* Returns: TRUE, if device notification is set up
* FALSE, if device notification setup fails
*
**********************************************************/
BOOL CHid::RegisterHidDeviceNotify(/*HWND hWnd, HDEVNOTIFY hDevNotify*/) //HDEVNOTIFY结构需要在StdAfx.h中定义#deinfe WINVER 0x0500
{
GUID HidGuid; /* temporarily stores Windows HID Class GUID */
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter; /* un/plug notification filter */
/* Set up device notification (i.e. plug or unplug of HID Devices) */
/* 1) get the HID GUID */
HidD_GetHidGuid(&HidGuid);
/* 2) clear the notification filter */
ZeroMemory( &NotificationFilter, sizeof(NotificationFilter));
/* 3) assign the previously cleared structure with the correct data
so that the application is notified of HID device un/plug events */
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
NotificationFilter.dbcc_classguid = HidGuid;
/* 4) register device notifications for this application */
m_hDevNotify = RegisterDeviceNotification( m_hParentWnd,
&NotificationFilter,
DEVICE_NOTIFY_WINDOW_HANDLE);
/* 5) notify the calling procedure if the HID device will not be recognized */
if(!m_hDevNotify)
return FALSE;
return TRUE;
}
/**********************************************************
*
* Function ReadHid
* Purpose: This thread data from the hid device
* Parameters: ucDataBuffer->the data buffer to read
* ucDataLength->the data length to read
* Returns: none
*
**********************************************************/
void CHid::ReadHid(unsigned char ucDataBuffer[], unsigned char ucDataLength)
{
HANDLE hDevice;
unsigned long numBytesReturned;
unsigned char inbuffer[128]; /* input buffer*/
BOOL bResult;
HIDP_CAPS Capabilities;
PHIDP_PREPARSED_DATA HidParsedData;
OVERLAPPED HidOverlapped;
HANDLE ReportEvent;
if(!m_bMyDeviceDetected)
return;
/* Open the HID device handle */
if(OpenHidDevice( &hDevice, VID, PID) == TRUE)
{
/* get a handle to a buffer that describes the device's capabilities. This
line plus the following two lines of code extract the report length the
device is claiming to support */
HidD_GetPreparsedData(hDevice, &HidParsedData);
/* extract the capabilities info */
HidP_GetCaps( HidParsedData ,&Capabilities);
/* Free the memory allocated when getting the preparsed data */
HidD_FreePreparsedData(HidParsedData);
/* Create a new event for report capture */
ReportEvent = CreateEvent(NULL, TRUE, TRUE, "");//CreateEvent(NULL, TRUE, FALSE, NULL);
/* fill the HidOverlapped structure so that Windows knows which
event to cause when the device sends an IN report */
HidOverlapped.hEvent = ReportEvent;
HidOverlapped.Offset = 0;
HidOverlapped.OffsetHigh = 0;
/* get a temperature report from the HID device. Note that
this call to ReadFile only kicks off the reading of the report.
If the input buffer is full then this routine will cause an
event to happen and data will be presented immediately. If not
the event will occur when the HID decide provides a HID report
on the IN endpoint. */
bResult = ReadFile( hDevice, /* handle to device */
&inbuffer[0], /* IN report buffer to fill */
Capabilities.InputReportByteLength, /* input buffer size */
// ucDataLength+1, //如果ucDataLength的值为64的话,Capabilities.InputReportByteLength就为65
&numBytesReturned, /* returned buffer size */
(LPOVERLAPPED) &HidOverlapped ); /* long pointer to an OVERLAPPED structure */
/* wait for IN report event. Note that if a report does not occur
in the time set by the 'dwMilliseconds' parameter, then this function
returns with a FALSE result and the HID device did not provide a
report. If the function returns TRUE, then a report did occur and the
data is ready to be read from the buffer specified in the ReadFile
function call.*/
bResult = WaitForSingleObject( ReportEvent, 5000);
/* if the transaction timed out, then we have to manually cancel
the request */
if(bResult == WAIT_TIMEOUT || bResult == WAIT_ABANDONED)
CancelIo(&hDevice);
/* Process in the input data. Note that the first byte (i.e.
inbuffer[0] is the report ID for the HID report. We can just
ignore this value. The first data byte of interest is
inbuffer[1] */
if(bResult == WAIT_OBJECT_0)
{
//Save data to ucDataBuffer(this parameter will return by this funciotn)
for(int i=0;i<ucDataLength;i++)
{
ucDataBuffer[i] = inbuffer[i+1];
TRACE("0x%.2X ",ucDataBuffer[i]);
}
TRACE("\n");
}
else
{
AfxMessageBox(_T("bResult != WAIT_OBJECT_0!"));
}
ResetEvent(ReportEvent);
/* close the HID device handle */
CloseHandle(hDevice);
}
// TMThreadActive = FALSE;
}
/**********************************************************
*
* Function ReadHid
* Purpose: This thread data from the hid device
* Parameters: ucDataBuffer->the data buffer to read
* ucDataLength->the data length to read
* Returns: none
*
**********************************************************/
void CHid::ReadHidEx(HANDLE hDevice, unsigned char ucDataBuffer[], unsigned char ucDataLength)
{
unsigned long numBytesReturned;
BOOL bResult;
OVERLAPPED HidOverlapped;
HANDLE ReportEvent;
/* Create a new event for report capture */
ReportEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
/* fill the HidOverlapped structure so that Windows knows which
event to cause when the device sends an IN report */
HidOverlapped.hEvent = ReportEvent;
HidOverlapped.Offset = 0;
HidOverlapped.OffsetHigh = 0;
/* get a temperature report from the HID device. Note that
this call to ReadFile only kicks off the reading of the report.
If the input buffer is full then this routine will cause an
event to happen and data will be presented immediately. If not
the event will occur when the HID decide provides a HID report
on the IN endpoint. */
bResult = ReadFile( hDevice, /* handle to device */
ucDataBuffer, /* IN report buffer to fill */
ucDataLength, /* input buffer size */
&numBytesReturned, /* returned buffer size */
(LPOVERLAPPED) &HidOverlapped ); /* long pointer to an OVERLAPPED structure */
/* wait for IN report event. Note that if a report does not occur
in the time set by the 'dwMilliseconds' parameter, then this function
returns with a FALSE result and the HID device did not provide a
report. If the function returns TRUE, then a report did occur and the
data is ready to be read from the buffer specified in the ReadFile
function call.*/
bResult = WaitForSingleObject( ReportEvent, 500);
switch(bResult)
{
case WAIT_OBJECT_0:
break;
case WAIT_TIMEOUT:
case WAIT_ABANDONED:
AfxMessageBox(_T("bResult != WAIT_OBJECT_0!"));
CancelIo(&hDevice);
break;
default:
break;
}
ResetEvent(ReportEvent);
CloseHandle(ReportEvent);
}
/**********************************************************
*
* Function WriteAndReadHid
* Purpose: This thread write data to hid device
* Parameters: ucTxBuffer->the data buffer to send
* ucTxLength->the data length to send(If zero,don't send any data)
ucRxBuffer->the data buffer to read
* ucRxLength->the data length to read(If zero,don't read any data)
* Returns: none
*
**********************************************************/
void CHid::WriteHid(unsigned char ucTxBuffer[], unsigned char ucTxLength)
{
HANDLE hDevice;
unsigned long numBytesReturned;
unsigned char outbuffer[128]; /* output buffer */
BOOL bResult;
HIDP_CAPS Capabilities;
PHIDP_PREPARSED_DATA HidParsedData;
OVERLAPPED HidOverlapped;
HANDLE ReportEvent;
if(!m_bMyDeviceDetected)
return;
/* Open the HID device handle */
if(OpenHidDevice( &hDevice, VID, PID) == TRUE)
{
/* get a handle to a buffer that describes the device's capabilities. This
line plus the following two lines of code extract the report length the
device is claiming to support */
HidD_GetPreparsedData(hDevice, &HidParsedData);
/* extract the capabilities info */
HidP_GetCaps( HidParsedData ,&Capabilities);
/* Free the memory allocated when getting the preparsed data */
HidD_FreePreparsedData(HidParsedData);
/* Create a new event for report capture */
ReportEvent = CreateEvent(NULL, TRUE, TRUE, "");
/* fill the HidOverlapped structure so that Windows knows which
event to cause when the device sends an IN report */
HidOverlapped.hEvent = ReportEvent;
HidOverlapped.Offset = 0;
HidOverlapped.OffsetHigh = 0;
/* Use WriteFile to send an output report to the HID device. Firt we should
fill the outbuffer*/
//outbuffer[0] = 0x01; /* this is used as the report ID */
for(int i=0;i<ucTxLength;i++) //copy data form ucDataBuffer
outbuffer[i] = ucTxBuffer[i];
bResult = WriteFile( hDevice,
&outbuffer[0],
Capabilities.OutputReportByteLength,
// ucTxLength+1,
&numBytesReturned,
(LPOVERLAPPED) &HidOverlapped);
bResult = WaitForSingleObject(ReportEvent, 10);//INFINITE);
switch(bResult)
{
case WAIT_OBJECT_0:
break;
case WAIT_TIMEOUT:
CancelIo(&hDevice);
break;
default:
break;
}
ResetEvent(ReportEvent);
/* close the HID device handle */
CloseHandle(hDevice);
}
// TMThreadActive = FALSE;
}
/**********************************************************
*
* Function WriteAndReadHid
* Purpose: This thread write data to hid device
* Parameters: ucTxBuffer->the data buffer to send
* ucTxLength->the data length to send(If zero,don't send any data)
ucRxBuffer->the data buffer to read
* ucRxLength->the data length to read(If zero,don't read any data)
* Returns: none
*
**********************************************************/
void CHid::WriteHidEx(HANDLE hDevice, unsigned char ucTxBuffer[], unsigned char ucTxLength)
{
unsigned long numBytesReturned;
BOOL bResult;
OVERLAPPED HidOverlapped;
HANDLE ReportEvent;
/* Create a new event for report capture */
ReportEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
/* fill the HidOverlapped structure so that Windows knows which
event to cause when the device sends an IN report */
HidOverlapped.hEvent = ReportEvent;
HidOverlapped.Offset = 0;
HidOverlapped.OffsetHigh = 0;
bResult = WriteFile( hDevice,
ucTxBuffer,
ucTxLength,
&numBytesReturned,
(LPOVERLAPPED) &HidOverlapped);
bResult = WaitForSingleObject(ReportEvent, INFINITE);
switch(bResult)
{
case WAIT_OBJECT_0:
break;
case WAIT_TIMEOUT:
case WAIT_ABANDONED:
CancelIo(&hDevice);
break;
default:
break;
}
ResetEvent(ReportEvent);
CloseHandle(ReportEvent);
}
BOOL CHid::FindHid()
{
HANDLE HidDevHandle; //The handle of the hid device return by OpenHidDevice
USHORT usPid,usVid;
usPid = PID;
usVid = VID;
BOOL bFindHid = OpenHidDevice(&HidDevHandle,usVid,usPid);
if(!m_bDeviceNoficationRegistered)
{
RegisterHidDeviceNotify(/*m_hParentWnd,m_hDevNotify*/);
m_bDeviceNoficationRegistered = TRUE;
}
if(bFindHid)
{
TRACE("My Device detected.");
m_bMyDeviceDetected = TRUE;
CloseHandle(HidDevHandle);
return TRUE;
}
else
{
TRACE("My Device not detected.");
// if(m_bMyDeviceDetected)
// CloseHandle(HidDevHandle); //未找到指定设备,故设备指针没有用,可以释放
m_bMyDeviceDetected = FALSE;
return FALSE;
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/jeffkuang_workspace/USB_ICCardReader_Test.git
git@gitee.com:jeffkuang_workspace/USB_ICCardReader_Test.git
jeffkuang_workspace
USB_ICCardReader_Test
USB_ICCardReader_Test
master

搜索帮助