根据GUID和PID和USB设备通信的方法
//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);
posted on 2009-11-06 08:22 常州市润邦电子科技 阅读(6253) 评论(0) 编辑 收藏 举报