C++ 实现USB

来源:互联网 发布:mac卸载 编辑:程序博客网 时间:2024/06/08 20:13

源代码--如下:

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_INCLUDED2.mcdHid.h#ifndef MCDHID_H_INCLUDED#define MCDHID_H_INCLUDEDextern "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.cppfunction: open HID device ,close HID device ,read data from HID device , write data to HID deviceauthor:date:version:*/#include <stdlib.h>#include <windows.h>#include <stdio.h>#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_MSGMCDHid::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<sizeof(_inputReportBuffer); i++) {  _inputReportBuffer[i] = mcdHid._inputReportBuffer[i]; } for(int i = 0; i<sizeof(_outputReportBuffer); 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;}