none
usb cdc(通信设备类)在用vc++写上层应用程序调用SetupDiEnumDeviceInterfaces()出错 RRS feed

  • 问题

  • USB写一个应用时调用SetupDiEnumDeviceInterfaces()这个函数出错.

    因为是CDC通信(端口(COM和LPT))而不是HID通信, 所以用得是固定"安装类"的GUID,网上也有很多人提过这问题,但一直木有人解决, 求救呀, 搞了很久很久了...

    int main()
    {
        GUID guidHID = {0x4D36E978, 0xE325, 0x11CE, 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18};  //安装类GUID是在inf驱动文件上的GUID
        //HidD_GetHidGuid( &guidHID );    //因为不是HID设备,所以不用这个来获得GUID, 而是用上面这个固定GUID	
         HDEVINFO hDevInfo = SetupDiGetClassDevs( &guidHID, NULL, 0, DIGCF_PRESENT);     //由于是"安装类的GUID"而非"接口类GUID", 所以在最后一个参数没加DIGCF_DEVICEINTERFACE
         if( INVALID_HANDLE_VALUE != hDevInfo )   //调用成功返回文件句柄, 如果调用失败返回INVALID_HANDLE_VALUE
        {
            SP_DEVICE_INTERFACE_DATA strtInterfaceData = { sizeof(SP_DEVICE_INTERFACE_DATA) };
    		// 查找USB设备接口
            for( DWORD index=0; SetupDiEnumDeviceInterfaces(hDevInfo,NULL,&guidHID,index,&strtInterfaceData); ++index )
            {   //在这里出错 SetupDiEnumDeviceInterfaces一直返回是0
                char buf[1000];
                SP_DEVICE_INTERFACE_DETAIL_DATA& strtDetailData = (SP_DEVICE_INTERFACE_DETAIL_DATA&)buf[0];
                strtDetailData.cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
    			// 若找到了设备,则读取设备路径名
                if( SetupDiGetDeviceInterfaceDetail(hDevInfo,&strtInterfaceData,&strtDetailData,_countof(buf),NULL,NULL) )
                {
                    _tprintf( _T("[%d] path: %s\n"), index, strtDetailData.DevicePath );   //设备路径名
    				//用CreateFile打开或创建设备
                    HANDLE hUsb = CreateFile( strtDetailData.DevicePath, GENERIC_READ|GENERIC_WRITE//0
                        , FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
                    if( INVALID_HANDLE_VALUE != hUsb )   //调用成功返回文件句柄, 如果调用失败返回INVALID_HANDLE_VALUE
                    {
                        // 查询设备标识
                        HIDD_ATTRIBUTES strtAttrib = { sizeof(HIDD_ATTRIBUTES) };
    					//用HidD_GetAttributes获得特定HID属性
                        if( HidD_GetAttributes(hUsb,&strtAttrib) )
                        {
                            _tprintf( _T("VendorID : %hX\n"), strtAttrib.VendorID );
                            _tprintf( _T("ProductID: %hX\n"), strtAttrib.ProductID );
                            _tprintf( _T("VerNumber: %hX\n"), strtAttrib.VersionNumber );
    						if(strtAttrib.VendorID==0x3006 && strtAttrib.ProductID==0x1977)
    						{
    							_tprintf( _T("Find:VendorID-0x3006, ProductID-0x1977\n")); 
    							COMSTAT ComStat;
    							DWORD dwErrorFlags;
    							//ClearCommError(hUsb,&dwErrorFlags,&ComStat);  //读写设备之前应先调用这个函数清除错误标志
    							BYTE pBuffer[8] = {0};  
    							if( DeviceWrite(hUsb,pBuffer, 7)  )
    							{
    								for(int i=0;i<8;i++)
    								{
    									_tprintf( _T("Read: %02X"),pBuffer[i]);
    									if(((i+1)%16)==0)
    									{
    										_tprintf( _T("\n")); 
    									}
    								}
    							}
    							else
    							{
    								_tprintf( _T("Read error"));
    							}
    						}
    						
                        }
                        else
                            ShowError();
    					//释放资源
                        CloseHandle( hUsb );
                    }
                    else
                        ShowError();
                }
                else
                    ShowError();
            }
            if( GetLastError() != ERROR_NO_MORE_ITEMS )
                ShowError();
            SetupDiDestroyDeviceInfoList( hDevInfo );
        }
        else
            ShowError();
    	getch();       // 得到键盘输入后再退出
        return 0;
    }
    BOOL DeviceWrite(HANDLE handle, LPCVOID lpBuffer, DWORD dwSize)  
    {  
        BYTE wBuffer[8] = {0};  
        DWORD dwRet;  
        BOOL bRet;  
        wBuffer[0] = 0x01;  
        wBuffer[1] = 0x00;  
        memcpy(&wBuffer[2], lpBuffer, min(6, dwSize));  
        bRet = WriteFile(handle, wBuffer, 8, &dwRet, NULL);  
        return bRet;  
    }  
    BOOL DeviceRead(HANDLE handle, LPVOID lpBuffer, DWORD dwSize)  
    {  
        BYTE rBuffer[8] = {0};  
        DWORD dwRet;  
        BOOL bRet;  
        rBuffer[0] = 0x01;  
        rBuffer[1] = 0xff;  
        bRet = WriteFile(handle, rBuffer, 8, &dwRet, NULL);  
        bRet &= ReadFile(handle, rBuffer, 8, &dwRet, NULL);  
        memcpy(lpBuffer, &rBuffer[1], min(7, dwSize));  
        return bRet;  
    }

    2015年5月21日 2:03