分享

根据GUID和PID和USB设备通信的方法

 刀下巴 2015-03-24

//usbport.cpp
#include "stdafx.h"
#include "usbport.h"
 
//8a3bf75d-83c7-440e-8276-5ae3f3ea6e77
//DEFINE_GUID(GUID_CLASS_I82930_BULK,0x8a3bf75d, 0x83c7, 0x440e,0x82, 0x76, 0x5a, 0xe3, 0xf3, 0xea, 0x6e, 0x77);
DEFINE_GUID(GUID_CLASS_I82930_BULK,0x28d78fad, 0x5a12, 0x11d1,0xae,0x5b , 0x00, 0x00, 0xf8,0x03 ,0xa8 , 0xc2);
  //{                                  28d78fad   -5a12   -11d1 -ae5b-0000f803a8c2}
//  DEFINE_GUID( GUID_CLASS_I82930_BULK,0x18457c9f,   0xa3d8,   0x4fa3,0x8f,   0x10,   0x11,   0x45,   0xcd,   0x1a,   0xa3,   0x67);
             
BOOL            GetUsbDeviceFileName( LPGUID pGuid, char *outNameBuf,char *pid);
HANDLE   OpenUsbDevice( LPGUID pGuid, char *outNameBuf,char *pid);
HANDLE   OpenOneDevice (HDEVINFO HardwareDeviceInfo, PSP_INTERFACE_DEVICE_DATA   DeviceInfoData,char *devName);
int                  GetUsbPath(char *path,char *pid);
int                  WriteUsb(HANDLE hUsb,char *Outbuff, int len);
int                  ReadUsb(HANDLE hUsb,BYTE inbuff[], DWORD &nBytesRead,int nToRead);
 
/*名称:open_file
 功能:打开USB设备
 参数:filename 定义为”PIPE00” pipe name for bulk input pipe on our test board ,”PIPE01” pipe name for bulk output pipe on our test board。
PIPE00 和 PIPE01 是参考src\usb\bulkusb,我实际在用时这两个效果一样,为了避免USB异常引起的死机,我文件打开采用非阻塞模式。
*/
HANDLE open_file( char *filename,char *pid)
{
 
       int success = 1;
       HANDLE h;
       char completeDeviceName[256] = ""; //generated from the GUID registered by the driver itself

       if ( !GetUsbDeviceFileName((LPGUID) &GUID_CLASS_I82930_BULK,completeDeviceName,pid) )
       {
              //NOISY(("Failed to GetUsbDeviceFileName\n", GetLastError()));
              return INVALID_HANDLE_VALUE;
       }
 
    strcat (completeDeviceName,       "\\");                     
 
    strcat (completeDeviceName,       filename);                                   
 
       //printf("completeDeviceName = (%s)\n", completeDeviceName);
 
       h = CreateFile(completeDeviceName,
              GENERIC_WRITE | GENERIC_READ,
              FILE_SHARE_WRITE | FILE_SHARE_READ,
              NULL,
              OPEN_EXISTING,
              FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
              NULL);
 
       if (h == INVALID_HANDLE_VALUE) {
              //NOISY(("Failed to open (%s) = %d", completeDeviceName, GetLastError()));
              success = 0;
       } else {
                     //NOISY(("Opened successfully.\n"));
    }            
 
       return h;
}
/*名称:GetUsbDeviceFileName
 功能:获取USB设备路径
 参数:pGUID
 返回:outNameBuf USB设备路径
*/
BOOL GetUsbDeviceFileName( LPGUID pGuid, char *outNameBuf,char *pid)
{
       HANDLE hDev = OpenUsbDevice( pGuid, outNameBuf,pid );
       if ( hDev != INVALID_HANDLE_VALUE )
       {
              CloseHandle( hDev );
              return TRUE;
       }
       return FALSE;
 
}
/*名称:OpenUsbDevice
 功能:获取USB设备路径
 参数:pGUID 设备GUID
 返回:outNameBuf USB设备路径
*/
HANDLE OpenUsbDevice( LPGUID pGuid, char *outNameBuf,char *pid)
{
   ULONG NumberDevices;
   HANDLE hOut = INVALID_HANDLE_VALUE;
   HDEVINFO                 hardwareDeviceInfo;
   SP_INTERFACE_DEVICE_DATA deviceInfoData;
   ULONG                    i;
   BOOLEAN                  done;
   PUSB_DEVICE_DESCRIPTOR   usbDeviceInst;
   PUSB_DEVICE_DESCRIPTOR   *UsbDevices = &usbDeviceInst;
 
   *UsbDevices = NULL;
   NumberDevices = 0;
 
   //
   // Open a handle to the plug and play dev node.
   // SetupDiGetClassDevs() returns a device information set that contains info on all
   // installed devices of a specified class.
   //
   hardwareDeviceInfo = SetupDiGetClassDevs (
                           pGuid,
                           NULL, // Define no enumerator (global)
                           NULL, // Define no
                           (DIGCF_PRESENT | // Only Devices present
                            DIGCF_INTERFACEDEVICE)); // Function class devices.
 
   //
   // Take a wild guess at the number of devices we have;
   // Be prepared to realloc and retry if there are more than we guessed
   //
   NumberDevices = 4;
   done = FALSE;
   deviceInfoData.cbSize = sizeof (SP_INTERFACE_DEVICE_DATA);
 
   i=0;
   while (!done) 
   {
      NumberDevices *= 2;
 
      if (*UsbDevices) 
        {
         *UsbDevices = (PUSB_DEVICE_DESCRIPTOR)realloc (*UsbDevices, (NumberDevices * sizeof (USB_DEVICE_DESCRIPTOR)));
      } 
        else 
        {
         *UsbDevices = (PUSB_DEVICE_DESCRIPTOR)calloc (NumberDevices, sizeof (USB_DEVICE_DESCRIPTOR));
      }
 
      if (NULL == *UsbDevices) 
        {
 
         // SetupDiDestroyDeviceInfoList destroys a device information set
         // and frees all associated memory.
 
         SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
         return INVALID_HANDLE_VALUE;
      }
 
      usbDeviceInst = *UsbDevices + i;
 
      for (; i < NumberDevices; i++) 
        {
 
         // SetupDiEnumDeviceInterfaces() returns information about device interfaces
         // exposed by one or more devices. Each call returns information about one interface;
         // the routine can be called repeatedly to get information about several interfaces
         // exposed by one or more devices.
 
         if (SetupDiEnumDeviceInterfaces (hardwareDeviceInfo,
                                         0, // We don't care about specific PDOs
                                                                       pGuid,
                                         i,
                                         &deviceInfoData)) {
 
            hOut = OpenOneDevice (hardwareDeviceInfo, &deviceInfoData, outNameBuf);
                     if ( hOut != INVALID_HANDLE_VALUE ) 
                     {
       if(strstr(outNameBuf,pid)!=NULL)
       {
       done = TRUE;
       break;
       }
                     }
         } 
               else 
               {
            if (ERROR_NO_MORE_ITEMS == GetLastError()) 
                     {
               done = TRUE;
               break;
            }
         }
      }
   }
 
   NumberDevices = i;
 
   // SetupDiDestroyDeviceInfoList() destroys a device information set
   // and frees all associated memory.
 
   SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
   free ( *UsbDevices );
   return hOut;
}
HANDLE OpenOneDevice (
    IN       HDEVINFO                    HardwareDeviceInfo,
    IN       PSP_INTERFACE_DEVICE_DATA   DeviceInfoData,
       IN          char *devName
    )
{
    PSP_INTERFACE_DEVICE_DETAIL_DATA     functionClassDeviceData = NULL;
    ULONG                                predictedLength = 0;
    ULONG                                requiredLength = 0;
       HANDLE                                                        hOut = INVALID_HANDLE_VALUE;
 
    //
    // allocate a function class device data structure to receive the
    // goods about this particular device.
    //
    SetupDiGetInterfaceDeviceDetail (
            HardwareDeviceInfo,
            DeviceInfoData,
            NULL, // probing so no output buffer yet
            0, // probing so output buffer length of zero
            &requiredLength,
            NULL); // not interested in the specific dev-node
 
 
    predictedLength = requiredLength;
    // sizeof (SP_FNCLASS_DEVICE_DATA) + 512;
 
    functionClassDeviceData = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc (predictedLength);
    functionClassDeviceData->cbSize = sizeof (SP_INTERFACE_DEVICE_DETAIL_DATA);
 
    //
    // Retrieve the information from Plug and Play.
    //
    if (! SetupDiGetInterfaceDeviceDetail(
               HardwareDeviceInfo,
               DeviceInfoData,
               functionClassDeviceData,
               predictedLength,
               &requiredLength,
               NULL)) {
              free( functionClassDeviceData );
        return INVALID_HANDLE_VALUE;
    }
 
       strcpy( devName,functionClassDeviceData->DevicePath) ;
       //printf( "Attempting to open %s\n", devName );
 
    hOut = CreateFile (
                  functionClassDeviceData->DevicePath,
                  GENERIC_READ | GENERIC_WRITE,
                  FILE_SHARE_READ | FILE_SHARE_WRITE,
                  NULL, // no SECURITY_ATTRIBUTES structure
                  OPEN_EXISTING, // No special create flags
                  0, // No special attributes
                  NULL); // No template file
 
    if (INVALID_HANDLE_VALUE == hOut) 
       {
              //printf( "FAILED to open %s\n", devName );
    }
       free( functionClassDeviceData );
       return hOut;
}
/*名称:GetUsbPath
 功能:返回USB设备路径
 参数:pGUID
 返回:path 路径
*/
int   GetUsbPath(char *path,char *pid)
{
       if ( !GetUsbDeviceFileName((LPGUID) &GUID_CLASS_I82930_BULK,path,pid) )
       {
              return 0;
       }
       return 1;
}
/*名称:WriteUsb
 功能:向USB写数据
 参数:hUsb USB句柄,Outbut 数据指针,len 数据长度
*/
int WriteUsb(HANDLE hUsb,char *Outbuff, int len)
{
    DWORD nBytesWrite,endtime,lrc;
    static OVERLAPPED ol;
    DWORD dwErrorMask,dwError;
    COMSTAT comstat;
       if(hUsb==NULL)
              return 0;
    ol.Offset=0; //设备使用指定0            
    ol.OffsetHigh=0; //设备使用指定0
    ol.hEvent=NULL;   //标识事件为非信号状态,数据传送完成时,它将被设为信号状态
    ol.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); 
 
    if(!WriteFile(hUsb,Outbuff,len,&nBytesWrite,&ol)) 
    {
       //出错信息处理--------------------------------
        if((lrc=GetLastError())==ERROR_IO_PENDING)
        {
            endtime=GetTickCount()+1000;
            while(!GetOverlappedResult(hUsb,&ol,&nBytesWrite,FALSE))
            {   
                dwError=GetLastError();
                if(GetTickCount()>endtime)
                {   
     char buf[1000];
     sprintf(buf,"写串口时间过长,目前串口发送缓冲区中的数据数目为空ol.hEvent=%x,dwError=%d,nBytesWrite=%d",ol.hEvent,dwError,nBytesWrite);

                    MessageBox(NULL,buf,NULL,NULL);
                    break;
                }
                if(dwError=ERROR_IO_INCOMPLETE) 
                    continue;          //未完全读完时的正常返回结果
                else
                {
                    //    发生错误,尝试恢复!                    
                    break;
                }
            }
        } 
       //-------------------------------------------------//          
    }    
 //char buf[1000];
    // sprintf(buf,"写串口时间过长,目前串口发送缓冲区中的数据数目为空ol.hEvent=%x,dwError=%d,nBytesWrite=%d",ol.hEvent,dwError,nBytesWrite);

                   // MessageBox(NULL,buf,NULL,NULL);
    CloseHandle(ol.hEvent);
    FlushFileBuffers(hUsb);    
    return 1;
}
/*名称:ReadUsb
 功能:读取USB设备发来的数据
 参数:hUsb USB句柄,nToRead读取的长度
 返回:inbuff 读到的数据,nBytesRead 读到的长度
*/
int ReadUsb(HANDLE hUsb,BYTE inbuff[], DWORD &nBytesRead,int nToRead)
{
    DWORD lrc;                                 ///纵向冗余校验
    DWORD endtime;                            /////////jiesuo
    static OVERLAPPED ol;
    int ReadNumber=0;    
    int numCount=0 ;                             //控制读取的数目
    DWORD dwErrorMask;      
       DWORD dwEvtMask=0 ; 
       DWORD      ntoread;
       int          ReadTime;
 
    ReadTime=2000;
    ntoread=nToRead;
       ol.Offset=0;                            ///相对文件开始的字节偏移量
    ol.OffsetHigh=0;                        ///开始传送数据的字节偏移量的高位字,管道和通信时调用进程可忽略。
    ol.hEvent=NULL;                         ///标识事件,数据传送完成时设为信号状态
    ol.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); 
    if(!ReadFile(hUsb,inbuff,ntoread,&nBytesRead,&ol))
    {    
        if((lrc=GetLastError())==ERROR_IO_PENDING)
        {
            ///////////////////
            endtime=GetTickCount()+ReadTime;//GetTickCount()取回系统开始至此所用的时间(毫秒)
            while(!GetOverlappedResult(hUsb,&ol,&nBytesRead,FALSE))//该函数取回重叠操作的结果
            {
                if(GetTickCount()>endtime)
                    break;
            }    
        }        
    }     
       CloseHandle(ol.hEvent);
    return 1;     
}

 //usbport.h

 

//#define WINVER 0x0500
#include <windows.h>
#include <setupapi.h>
#include <basetyps.h>
#include "D:\\WINDDK\\2600\\inc\\wxp\\usbdi.h"
#include <initguid.h>
#include <stdio.h>

#pragma comment(lib,"setupapi.lib")
#pragma comment(lib,"D:\\WINDDK\\2600\\lib\\wxp\\i386\\hid.lib")
#pragma comment(lib,"comctl32.lib")
 
#ifndef BULKUSBH_INC
#define BULKUSBH_INC
 
#define BULKUSB_IOCTL_INDEX 0x0000
 
 
#define IOCTL_BULKUSB_GET_CONFIG_DESCRIPTOR     CTL_CODE(FILE_DEVICE_UNKNOWN, \
                                                   BULKUSB_IOCTL_INDEX,\
                                                   METHOD_BUFFERED, \
                                                   FILE_ANY_ACCESS)
                                                   
#define IOCTL_BULKUSB_RESET_DEVICE   CTL_CODE(FILE_DEVICE_UNKNOWN, \
                                                   BULKUSB_IOCTL_INDEX+1,\
                                                   METHOD_BUFFERED, \
                                                   FILE_ANY_ACCESS)                                                              
                                                   
#define IOCTL_BULKUSB_RESET_PIPE CTL_CODE(FILE_DEVICE_UNKNOWN, \
                                                   BULKUSB_IOCTL_INDEX+2,\
                                                   METHOD_BUFFERED, \
                                                   FILE_ANY_ACCESS)             
extern HANDLE            open_file(char *filename,char *pid);
extern int               GetUsbPath(char *path);
extern int               WriteUsb(HANDLE hUsb,char *Outbuff, int len);
extern int               ReadUsb(HANDLE hUsb,BYTE inbuff[],DWORD &nBytesRead,int nToRead);

#endif

具体的调用过程为

HANDLE  hDisplay=open_file("USB Printing Support",Display_PID);

char cmdBuf[100];

char ansBuf[100];

int  n=WriteUsb(hDisplay,cmdBuf,4);

   n=ReadUsb(hDisplay,ansBuf,i,3);

 


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多