//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設(shè)備 參數(shù):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,我實(shí)際在用時(shí)這兩個(gè)效果一樣,為了避免USB異常引起的死機(jī),我文件打開采用非阻塞模式。 */ 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設(shè)備路徑 參數(shù):pGUID 返回:outNameBuf USB設(shè)備路徑 */ 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設(shè)備路徑 參數(shù):pGUID 設(shè)備GUID 返回:outNameBuf USB設(shè)備路徑 */ 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設(shè)備路徑 參數(shù):pGUID 返回:path 路徑 */ int GetUsbPath(char *path,char *pid) { if ( !GetUsbDeviceFileName((LPGUID) &GUID_CLASS_I82930_BULK,path,pid) ) { return 0; } return 1; } /*名稱:WriteUsb 功能:向USB寫數(shù)據(jù) 參數(shù):hUsb USB句柄,Outbut 數(shù)據(jù)指針,len 數(shù)據(jù)長(zhǎng)度 */ 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; //設(shè)備使用指定0 ol.OffsetHigh=0; //設(shè)備使用指定0 ol.hEvent=NULL; //標(biāo)識(shí)事件為非信號(hào)狀態(tài),數(shù)據(jù)傳送完成時(shí),它將被設(shè)為信號(hào)狀態(tài) ol.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); if(!WriteFile(hUsb,Outbuff,len,&nBytesWrite,&ol)) { //出錯(cuò)信息處理-------------------------------- 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,"寫串口時(shí)間過長(zhǎng),目前串口發(fā)送緩沖區(qū)中的數(shù)據(jù)數(shù)目為空ol.hEvent=%x,dwError=%d,nBytesWrite=%d",ol.hEvent,dwError,nBytesWrite); MessageBox(NULL,buf,NULL,NULL); break; } if(dwError=ERROR_IO_INCOMPLETE) continue; //未完全讀完時(shí)的正常返回結(jié)果 else { // 發(fā)生錯(cuò)誤,嘗試恢復(fù)! break; } } } //-------------------------------------------------// } //char buf[1000]; // sprintf(buf,"寫串口時(shí)間過長(zhǎng),目前串口發(fā)送緩沖區(qū)中的數(shù)據(jù)數(shù)目為空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設(shè)備發(fā)來的數(shù)據(jù) 參數(shù):hUsb USB句柄,nToRead讀取的長(zhǎng)度 返回:inbuff 讀到的數(shù)據(jù),nBytesRead 讀到的長(zhǎng)度 */ int ReadUsb(HANDLE hUsb,BYTE inbuff[], DWORD &nBytesRead,int nToRead) { DWORD lrc; ///縱向冗余校驗(yàn) DWORD endtime; /////////jiesuo static OVERLAPPED ol; int ReadNumber=0; int numCount=0 ; //控制讀取的數(shù)目 DWORD dwErrorMask; DWORD dwEvtMask=0 ; DWORD ntoread; int ReadTime; ReadTime=2000; ntoread=nToRead; ol.Offset=0; ///相對(duì)文件開始的字節(jié)偏移量 ol.OffsetHigh=0; ///開始傳送數(shù)據(jù)的字節(jié)偏移量的高位字,管道和通信時(shí)調(diào)用進(jìn)程可忽略。 ol.hEvent=NULL; ///標(biāo)識(shí)事件,數(shù)據(jù)傳送完成時(shí)設(shè)為信號(hào)狀態(tài) ol.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); if(!ReadFile(hUsb,inbuff,ntoread,&nBytesRead,&ol)) { if((lrc=GetLastError())==ERROR_IO_PENDING) { /////////////////// endtime=GetTickCount()+ReadTime;//GetTickCount()取回系統(tǒng)開始至此所用的時(shí)間(毫秒) while(!GetOverlappedResult(hUsb,&ol,&nBytesRead,FALSE))//該函數(shù)取回重疊操作的結(jié)果 { 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 具體的調(diào)用過程為 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);
|