源代码如下:(生成.dll .lib)
1.MCDInterface.h
/*
*MCDInterface.h
*author:
*data:
*/
#ifndef MCDBOX_H_INCLUDED
#define MCDBOX_H_INCLUDED
#pragma once
#define MCD_IOCTRL_OPEN_SIG 0x1001
#define MCD_IOCTRL_CLOSE_SIG 0x1002
#define MCD_IOCTRL_FIND_SIG 0x1003
#define MCD_IOCTRL_READY 0x1003
#define MCD_IOCTRL_UNREADY 0x1004
#define KEY_0 0x3A
#define KEY_1 0x3B
#define KEY_2 0x3C
#define KEY_3 0x3D
#define KEY_4 0x3E
#define KEY_5 0x3F
#define KEY_6 0x40
#define KEY_7 0x41
#define KEY_8 0x42
#define KEY_9 0x43
#define KEY_STAR 0x44
#define KEY_POUND 0x45
#define MSG_HOOKOFF 0x16
#define MSG_HOOKON 0x12
#define MSG_RINGING 0x15
#define HID_DEVICE_REMOVE 0x76 //硬件被移走
#define CLIENT_READY_WRITE_SIG 0x92 //通知设备软件正在运行,每隔一段时间向缓冲区写该数据
#define DLL_EXPORT __declspec(dllexport)
#define DLL_IMPORT __declspec(dllimport)
//定义用于回调的枚举消息
enum{
MCD_CALLBACK_MSG_VERSION,//not used
MCD_CALLBACK_MSG_SERIALNO,//not used
MCD_CALLBACK_DEVICE_FOUND,
MCD_CALLBACK_DEVICE_NOT_FOUND,
MCD_CALLBACK_DEVICE_REMOVE,
MCD_CALLBACK_KEYDOWN,
MCD_CALLBACK_KEYBUFFER_CHANGED,
MCD_CALLBACK_HOOKOFF,
MCD_CALLBACK_HOOKON,
MCD_CALLBACK_RINGING,
MCD_CALLBACK_MSG_WARNING = -2,
MCD_CALLBACK_MSG_ERROR = -1,
};
DLL_EXPORT unsigned long MCD_DeviceIoControl(unsigned long dwIoControlCode,
void* lpInBuffer = 0, unsigned long nInBufferSize = 0,
void* lpOutBuffer = 0, unsigned long nOutBufferSize = 0);
//定义设备状态返回信息
enum{
MCD_RETURN_SUCCESS = 0,
MCD_RETURN_FOUND_HID,
MCD_RETURN_NO_FOUND_HID,
MCD_RETURN_HID_IS_OPENED,//?
MCD_RETURN_HID_NO_OPEN,//?
};
#endif // MCDBOX_H_INCLUDED
2.mcdHid.h
#ifndef MCDHID_H_INCLUDED
#define MCDHID_H_INCLUDED
extern "C"
{
#include "setupapi.h"
#include "hidsdi.h"
#include "dbt.h"
}
typedef struct _HID_DEVICE {
PCHAR DevicePath;
HANDLE HidDevice; // A file handle to the hid device.
HIDP_CAPS Caps; // The Capabilities of this hid device.
HIDD_ATTRIBUTES Attributes;
} HID_DEVICE, *PHID_DEVICE;
class MCDHid
{
public:
static MCDHid & getInstance(){
static MCDHid mcdHid;
return mcdHid;
}
MCDHid(MCDHid & mcdHid);
MCDHid & operator=(MCDHid &mcdHid);
~MCDHid();
unsigned long openMCDHid();
void closeMCDHid();
void startComm(void * pParam);
int writeToHid();
int readFromHid();
char * getHidDeviceName()
{
return _hidDeviceName;
}
bool findMCDHid();
HID_DEVICE* getHidDevice(){
return & _hidDevice;
}
bool getUsbCommRunning(){
return _fUsbCommRunning;
}
bool getOffHookSignal(){
return _offHookSignal;
}
unsigned long getDataWaitProcess(){
return _dataWaitProcess;
}
void setUsbCommRunning(bool usbCommRunning)
{
_fUsbCommRunning = usbCommRunning;
}
unsigned char _inputReportBuffer[9];
unsigned char _outputReportBuffer[2];
private:
MCDHid();
void copy(MCDHid & mcdHid);
char *_hidDeviceName;
HANDLE _hEventObject;
OVERLAPPED _hIDOverlapped;
HID_DEVICE _hidDevice;
bool _fUsbCommRunning;
bool _offHookSignal;
unsigned long _dataWaitProcess;
unsigned long _inputReportByteLength;
unsigned long _outputReportByteLength;
};
#endif // MCDHID_H_INCLUDED
3.mcdHid.cpp
/*
mcdhid.cpp
function: open HID device ,close HID device ,read data from HID device , write data to HID device
author:
date:
version:
*/
#include
#include
#include
#include "mcdhid.h"
#include "MCDInterface.h"
#include "mcdbox.h"
#include "pthread.h"
void *getDataThread(void *pParam);
#define VENDOR_ID 0x1241//test device vendorId
#define PRODUCT_ID 0xe001//test device productId
#define CLIENT_RUNNING_MSG
MCDHid::MCDHid()
{
_hidDeviceName = "MCD Human Interface Device";
_fUsbCommRunning = false;
_offHookSignal = false;
_dataWaitProcess = 1;
memset(_inputReportBuffer,0,sizeof(_inputReportBuffer));
memset(_outputReportBuffer,0,sizeof(_outputReportBuffer));
}
MCDHid::MCDHid(MCDHid & mcdHid)
{
copy(mcdHid);
}
MCDHid & MCDHid::operator=(MCDHid & mcdHid)
{
copy(mcdHid);
return *this;
}
void MCDHid::copy(MCDHid & mcdHid)
{
_hidDeviceName = mcdHid._hidDeviceName;
_hEventObject = mcdHid._hEventObject;
_hIDOverlapped = mcdHid._hIDOverlapped;
_hidDevice = mcdHid._hidDevice;
_fUsbCommRunning = mcdHid._fUsbCommRunning;
_offHookSignal = mcdHid._offHookSignal;
_dataWaitProcess = mcdHid._dataWaitProcess;
_inputReportByteLength = mcdHid._inputReportByteLength;
_outputReportByteLength = mcdHid._outputReportByteLength;
for(int i = 0; i {
_inputReportBuffer[i] = mcdHid._inputReportBuffer[i];
}
for(int i = 0; i {
_inputReportBuffer[i] = mcdHid._outputReportBuffer[i];
}
}
MCDHid::~MCDHid()
{
}
unsigned long MCDHid::openMCDHid()
{
if(findMCDHid())
{
//采用重叠传输方式
//if( _hEventObject == 0)
// {
_hEventObject = CreateEvent(
NULL,
true,
true,
"");
_hIDOverlapped.hEvent = _hEventObject;
_hIDOverlapped.Offset = 0;
_hIDOverlapped.OffsetHigh =0;
// }
return MCD_RETURN_SUCCESS;
}
else
return MCD_RETURN_NO_FOUND_HID;
}
void MCDHid::closeMCDHid()
{
CloseHandle(_hidDevice.HidDevice);
_hidDevice.HidDevice = INVALID_HANDLE_VALUE;
}
void MCDHid::startComm(void *pParam)
{
int thr_id;
pthread_t m_processT;
if((thr_id=pthread_create(&m_processT, NULL, getDataThread, pParam) != 0))
{
//printf("pthread_create error:%s/n", strerror(thr_id));
return;
}
}
bool MCDHid::findMCDHid()
{
int vendorID = VENDOR_ID;
int productID = PRODUCT_ID;
DWORD required;
GUID hidGuid;
HDEVINFO hDevInfo;
SP_DEVICE_INTERFACE_DATA devInfoData;
int memberIndex = 0;
LONG result;
bool lastDevice = false;
DWORD length;
PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL;
bool deviceDetected = false;
HidD_GetHidGuid(&hidGuid);
hDevInfo = SetupDiGetClassDevs
(&hidGuid,
NULL,
NULL,
DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
//当应用程序不再需要使用SetupDiGetClassDevs函数的传回值hDevInfo所指的数组时,应该调用SetupDiDeStroyDeviceInfoList函数来释放资源
if(hDevInfo == INVALID_HANDLE_VALUE)
{
//printf("Failed to open device handle!");
return false;
}
devInfoData.cbSize = sizeof(devInfoData);
do
{
result = SetupDiEnumDeviceInterfaces(
hDevInfo,
0,
&hidGuid,
memberIndex,
&devInfoData);
if (result != 0)
{
result = SetupDiGetDeviceInterfaceDetail(
hDevInfo,
&devInfoData,
NULL,
0,
&length,
NULL);
detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(length);
if(!detailData)
{
//printf("Device information allacation failed!");
return false;
}
detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
result = SetupDiGetDeviceInterfaceDetail(
hDevInfo,
&devInfoData,
detailData,
length,
&required,
NULL);
if(!result)
{
//printf("Device information reallocation failed!");
return false;
}
_hidDevice.HidDevice = CreateFile(
detailData->DevicePath,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
(LPSECURITY_ATTRIBUTES)NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
_hidDevice.Attributes.Size = sizeof(HIDD_ATTRIBUTES);
result = HidD_GetAttributes(
_hidDevice.HidDevice,
&_hidDevice.Attributes);
if ((_hidDevice.Attributes.VendorID == vendorID) && (_hidDevice.Attributes.ProductID == productID))
{
int status;
PHIDP_PREPARSED_DATA PreparsedData ;
deviceDetected = true;
//获取USB设备的预解析数据
result = HidD_GetPreparsedData(_hidDevice.HidDevice,&PreparsedData);
if(!result)
{
//printf("无法获取USB设备的预解析数据!");
return false;
}
status= HidP_GetCaps(PreparsedData, &_hidDevice.Caps);
_fUsbCommRunning = true;
HidD_FreePreparsedData(PreparsedData);
PreparsedData = NULL;
}
else
{
//printf("没有找到设备!");
closeMCDHid();
}
free(detailData);
detailData = NULL;
}
else
{
lastDevice = true;
}
memberIndex = memberIndex + 1;
}while((lastDevice == false)&&(deviceDetected == false));
SetupDiDestroyDeviceInfoList(hDevInfo);
return deviceDetected;
}
/*
*写入数据为MCD设备状态通知,把标识位放在第1位
*/
int MCDHid::writeToHid()
{
return 0;
}
int MCDHid::readFromHid()
//int readFromHid()
{
if(_hidDevice.HidDevice != INVALID_HANDLE_VALUE)
{
int result = 0;
DWORD numberOfBytesRead;
result = ReadFile(_hidDevice.HidDevice,
&_inputReportBuffer,
_hidDevice.Caps.InputReportByteLength,
&numberOfBytesRead,
(LPOVERLAPPED)&_hIDOverlapped);
_inputReportByteLength = _hidDevice.Caps.InputReportByteLength;
}
int waitResult = 0;
waitResult = WaitForSingleObject(
_hEventObject,
10);
switch(waitResult)
{
case WAIT_OBJECT_0: break;
case WAIT_TIMEOUT:
{
CancelIo(_hidDevice.HidDevice);
break;
}
default:
{
break;
}
}
ResetEvent(_hEventObject);
return 0;
}
/**************************************************************************
*启动一个读取数据线程,读取数据为拨打电话号码
*启动一个写入数据线程, 写入数据为MCD设备状态通知,现在还没有写数据
***************************************************************************/
void *getDataThread(void *pParam)
{
MCDBox *ht = (MCDBox *)pParam;
MCDHid *hr = &(MCDHid::getInstance());
while(hr->getUsbCommRunning())//USB设备running,并且有摘机信号
{
hr->readFromHid();
//readFromHid();
//printf("获取缓冲区的数据/n");
if(hr->getDataWaitProcess() > 0)//可以定义_dataWaitProcess为一次拨号数据的长度
{
unsigned long i = 0;
for(i = 0; i < 9; i++)
{
ht->_inputReportBuffer[i] = hr->_inputReportBuffer[i];
//printf("read data from device is:%d/n",ht->_inputReportBuffer[1]);
}
ht->processData();
memset(hr->_inputReportBuffer,0,sizeof(hr->_inputReportBuffer));
//printf("数据处理!/n");
}
int status = 0;
//PHIDP_PREPARSED_DATA PreparsedData ;
//status = HidD_GetPreparsedData(_hidDevice.HidDevice,&PreparsedData);
status = HidD_GetAttributes(
hr->getHidDevice()->HidDevice,
&hr->getHidDevice()->Attributes);
if(!status)
{
hr->setUsbCommRunning(false);
memset(ht->_inputReportBuffer,0,sizeof(ht->_inputReportBuffer));
ht->_inputReportBuffer[2] = HID_DEVICE_REMOVE;
ht->processData();
printf("设备移走!");
//return false;
break;
}
//HidD_FreePreparsedData (PreparsedData);
// PreparsedData = NULL;
Sleep(100);
}
return 0;
}
4.mcdbox.h
#ifndef MCDMAIN_H_INCLUDED
#define MCDMAIN_H_INCLUDED
class MCDHid;
class MCDCallBack;
class MCDBox
{
public:
static MCDBox & getInstance(){
static MCDBox mcdBox;
return mcdBox;
}
~MCDBox();
unsigned long deviceIOControl(unsigned long dwIoControlCode,
void* lpInBuffer, unsigned long nInBufferSize,
void* lpOutBuffer, unsigned long nOutBufferSize);
void findDevice(void* lpInBuffer, unsigned long nInBufferSize,
void* lpOutBuffer, unsigned long nOutBufferSize);
unsigned long openDevice(void* lpInBuffer, unsigned long nInBufferSize,
void* lpOutBuffer, unsigned long nOutBufferSize);
void closeDevice();
void processData();
unsigned char _inputReportBuffer[9];
unsigned char _outputReportBuffer[9];
unsigned long _inputBufferByteLength;
unsigned long _outputBufferByteLength;
bool isDeviceOpen(){
return _openDevice;
}
void setDeviceOpen(bool deviceOpen)
{
_openDevice = deviceOpen;
}
private:
MCDBox();
char * _mcdHidName;
unsigned long _mcdStatus;
MCDHid & _mcdHid;
MCDCallBack &_mcdCallback;
bool _openDevice;
//char _key;
};
/*
*定义回调函数
*/
typedef void (*CALLBACK_MCDBOX)(void* wParam, void* lParam, unsigned long ParameterOfApp);
class MCDCallBack
{
public:
static MCDCallBack & getInstance(){
static MCDCallBack mcdCallback;
return mcdCallback;
}
MCDCallBack(MCDCallBack & mcdCallback);
MCDCallBack & operator=(MCDCallBack & mcdCallback);
virtual ~MCDCallBack();
void create(void* pCallBackFunction = 0, unsigned long dwParameterOfApplication = 0);
void callBack(unsigned long wParam,void* lParam = 0);
private:
MCDCallBack();
void copy(MCDCallBack & mcdCallback);
struct {
CALLBACK_MCDBOX func;
unsigned long lParam;
}_fCallBack;
};
//extern MCDCallBack mcdCallBack;
#endif // MCDMAIN_H_INCLUDED
5.cpp
/*
mcdbox.cpp
function description: 数据处理接口
author:
date:
version:
*/
#ifndef MCDBOX_CPP_INCLUDED
#define MCDBOX_CPP_INCLUDED
#include
#include
#include "mcdbox.h"
#include "MCDInterface.h"
#include "mcdhid.h"
#include "pthread.h"
void *findDeviceThread(void *param);
unsigned long MCD_DeviceIoControl(unsigned long dwIoControlCode,
void* lpInBuffer, unsigned long nInBufferSize,
void* lpOutBuffer, unsigned long nOutBufferSize)
{
unsigned long br = 0;
MCDBox *ht = (MCDBox *)&(MCDBox::getInstance());
//MCDBox ht = getInstance();;
try
{
br = ht->deviceIOControl(dwIoControlCode,lpInBuffer,nInBufferSize,lpOutBuffer,nOutBufferSize);
}
catch (unsigned long BytesReturned)
{
br = BytesReturned;
}
return br;
}
MCDBox::MCDBox()
:_mcdHid(MCDHid::getInstance()),
_mcdCallback(MCDCallBack::getInstance())
{
_openDevice =false;
_inputBufferByteLength = 8;
_outputBufferByteLength = 8;
for (int i = 0; i < (int)_inputBufferByteLength; i++)
{
_inputReportBuffer[i] = 0;
}
for (int j = 0;j < (int)_outputBufferByteLength; j++)
{
_outputReportBuffer[j] = 0;
}
}
MCDBox::~MCDBox()
{
}
unsigned long MCDBox::deviceIOControl(unsigned long dwIoControlCode,
void* lpInBuffer, unsigned long nInBufferSize,
void* lpOutBuffer, unsigned long nOutBufferSize)
{
switch (dwIoControlCode)
{
case MCD_IOCTRL_FIND_SIG:
findDevice(lpInBuffer,nInBufferSize,lpOutBuffer,nOutBufferSize);
break;
case MCD_IOCTRL_CLOSE_SIG:
if (_openDevice)
{
closeDevice();
}
_mcdHid.closeMCDHid();
_openDevice = false;
return 0;
case MCD_IOCTRL_OPEN_SIG:
if (_openDevice)
return MCD_RETURN_HID_IS_OPENED;
openDevice(lpInBuffer,nInBufferSize,lpOutBuffer,nOutBufferSize);
break;
//case CLIENT_READY_WRITE_SIG://软件运行正常,通知硬件设备
// _mcdHid.writeToHid();
// return 0;
default:
if (!_openDevice) return MCD_RETURN_HID_NO_OPEN;
break;
}
return 0;
}
void MCDBox::findDevice(void* lpInBuffer, unsigned long nInBufferSize,
void* lpOutBuffer, unsigned long nOutBufferSize)
{
pthread_t m_processT;
int threadID;
_mcdCallback.create(lpInBuffer,nInBufferSize);
if((threadID=pthread_create(&m_processT, NULL, findDeviceThread, this) != 0))
{
return ;
}
}
unsigned long MCDBox::openDevice(void* lpInBuffer, unsigned long nInBufferSize,
void* lpOutBuffer, unsigned long nOutBufferSize)
{
_mcdCallback.create(lpInBuffer,nInBufferSize);
unsigned long dwReturnValue = _mcdHid.openMCDHid();
if(dwReturnValue == MCD_RETURN_SUCCESS)
{
_openDevice = true;
// _mcdCallback.create(lpInBuffer,nInBufferSize);
_mcdStatus = MCD_IOCTRL_READY;
//_mcdHid.writeToHid();//软件运行正常,通知硬件设备
//_key = 0;
_mcdHid.startComm(this);
_mcdHidName = _mcdHid.getHidDeviceName();
}
else
{
_mcdHid.closeMCDHid();
}
return dwReturnValue;
}
void MCDBox::closeDevice()
{
_mcdHid.closeMCDHid();
}
/********************************************************************************
/***读取缓冲区,第二个字节为有效数据,buffer size = 8bytes。。。(目前暂定)
*********************************************************************************/
void MCDBox::processData()
{
/*
*test:对key_buffer赋值为0x34,看能否回调成功,test结果:right!
*/
unsigned long isExist = _inputReportBuffer[2];
if(isExist == HID_DEVICE_REMOVE)
{
//printf("device removed/n");
_openDevice = false;
_mcdCallback.callBack(MCD_CALLBACK_DEVICE_REMOVE,(void*)0);
closeDevice();
return;
}
unsigned char key_buffer = _inputReportBuffer[1];
if(key_buffer > 0x00 && key_buffer < 0x3A)
{
if(key_buffer == MSG_HOOKOFF)
{
_mcdCallback.callBack(MCD_CALLBACK_HOOKOFF,(void*)key_buffer);
key_buffer = 0x00;
//printf("MSG_HOOKOFF/n");
return;
}
if(key_buffer == MSG_HOOKON)
{
_mcdCallback.callBack(MCD_CALLBACK_HOOKON,(void*)key_buffer);
key_buffer = 0x00;
//printf("MSG_HOOKON/n");
return;
}
if(key_buffer == MSG_RINGING)
{
_mcdCallback.callBack(MCD_CALLBACK_RINGING,(void*)key_buffer);
key_buffer = 0x00;
//printf("MSG_RINGING/n");
return;
}
}
else if(key_buffer >= KEY_0 && key_buffer <= KEY_POUND)//should be ||,or not be &&??
{
_mcdCallback.callBack(MCD_CALLBACK_KEYDOWN,(void*)key_buffer);
//printf("您按下的是%d键/n",(key_buffer-0X3A));
key_buffer = 0x00;
return;
}
else
{
return;
}
}
MCDCallBack::MCDCallBack()
{
_fCallBack.func =0;
_fCallBack.lParam = 0;
}
MCDCallBack::MCDCallBack(MCDCallBack & mcdCallback)
{
copy(mcdCallback);
}
MCDCallBack & MCDCallBack::operator=(MCDCallBack & mcdCallback)
{
copy(mcdCallback);
return *this;
}
MCDCallBack::~MCDCallBack()
{
}
void MCDCallBack::copy(MCDCallBack & mcdCallback)
{
_fCallBack.func = mcdCallback._fCallBack.func;
_fCallBack.lParam = mcdCallback._fCallBack.lParam;
}
void MCDCallBack::create(void* pCallBackFunction, unsigned long dwParameterOfApplication )
{
_fCallBack.func = (CALLBACK_MCDBOX)pCallBackFunction;
_fCallBack.lParam = dwParameterOfApplication;
}
void MCDCallBack::callBack(unsigned long wParam,void* lParam )
{
if(_fCallBack.func)
{
(*_fCallBack.func)((void*)wParam,lParam,_fCallBack.lParam);
}
}
void *findDeviceThread(void *param)
{
bool isHidFind = false;
while(!isHidFind)
{
MCDHid &mcdHid = MCDHid::getInstance();
MCDCallBack & mcdCallback = MCDCallBack::getInstance();
isHidFind = mcdHid.findMCDHid();
if(isHidFind)
{
//printf("find device/n");
mcdCallback.callBack(MCD_CALLBACK_DEVICE_FOUND,(void*)0);
return 0;
}
Sleep(1000);
}
return 0;
}
#endif // MCDBOX_CPP_INCLUDED