//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);
|