2012年(158)
分类: C/C++
2012-11-26 15:51:13
下载了一个不知道谁写的UsbPort代码,里面不相干的文件很多,有用的就几行(代码错误得一塌糊涂,必须初始化的变量没初始化,“==号”写成“=号”,……),历经多次失败终于运行正确,步骤如下:
1.
去微软网站下载WinDDK,现改名叫WDK,最新版本是GRMWDK_EN_7600_1.ISO,安装它。因为必须的文件hidsdi.h,hidpi.h,hidusage.h,hid.lib,
hidclass.lib, hidparse.lib在VC中没自带。
2. 将WDK安装目录加入到VC设定中,加入到工程设定中是没用的
menu:Tools\Options\Projects and Solutions\VC++ Directories,右边Show directories
for中选择Include files,将两个目录添加进去,顺序如下:
C:\WinDDK\7600.16385.1\inc\ddk
$(VCInstallDir)include
$(VCInstallDir)atlmfc\include
C:\WinDDK\7600.16385.1\inc\api
$(WindowsSdkDir)\include
$(FrameworkSDKDir)include
即保证 C:\WinDDK\7600.16385.1\inc\api 在
$(WindowsSdkDir)\include 前面,这样#include
menu:Tools\Options\Projects and
Solutions\VC++ Directories,右边Show directories for中选择Library files,添加
C:\WinDDK\7600.16385.1\lib\wxp\i386
3. 修改后的代码如下:
#include
#include
#include
#include
#pragma comment( lib,
"setupapi.lib" )
extern "C" {
#include
}
#pragma
comment( lib, "hid.lib" )
#define ShowError() ShowError_(_T(__FILE__),__LINE__)
void
ShowError_(LPCTSTR file, long line)
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS
, NULL, GetLastError(), 0, (LPTSTR)&lpMsgBuf, 0, NULL );
_tprintf(
_T("---ERROR %s(%ld): %s\n"), file, line, (LPCTSTR)lpMsgBuf );
LocalFree(
lpMsgBuf );
}
int main()
{
GUID guidHID;
HidD_GetHidGuid( &guidHID
);
_tprintf( _T("HID GUID:
{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n")
,
guidHID.Data1, guidHID.Data2, guidHID.Data3
, guidHID.Data4[0],
guidHID.Data4[1], guidHID.Data4[2], guidHID.Data4[3],
guidHID.Data4[4]
, guidHID.Data4[5], guidHID.Data4[6],
guidHID.Data4[7] );
HDEVINFO hDevInfo = SetupDiGetClassDevs( &guidHID, NULL, 0,
DIGCF_PRESENT|DIGCF_DEVICEINTERFACE );
if( INVALID_HANDLE_VALUE !=
hDevInfo )
{
SP_DEVICE_INTERFACE_DATA strtInterfaceData = {
sizeof(SP_DEVICE_INTERFACE_DATA) };
for( DWORD index=0;
SetupDiEnumDeviceInterfaces(hDevInfo,NULL,&guidHID,index,&strtInterfaceData);
++index )
{
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 );
HANDLE hUsb = CreateFile( strtDetailData.DevicePath,
0//GENERIC_READ|GENERIC_WRITE
,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
NULL );
if( INVALID_HANDLE_VALUE != hUsb )
{
// 查询设备标识
HIDD_ATTRIBUTES
strtAttrib = { sizeof(HIDD_ATTRIBUTES) };
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 );
}
else
ShowError();
CloseHandle( hUsb );
}
else
ShowError();
}
else
ShowError();
}
if( GetLastError() != ERROR_NO_MORE_ITEMS )
ShowError();
SetupDiDestroyDeviceInfoList( hDevInfo );
}
else
ShowError();
return 0;
}
假如不想下载庞大的WDK包,我打包了必须的文件(XP系统),连同测试工程,下载地址为:http://blog.vckbase.com/Files/bruceteen/USBTest.zip
使用API操作USB太麻烦了,[七猫]告诉我可以用LibUSB-Win32()
a.
调用usb_init函数,进行初始化
b.
调用usb_find_busses、usb_find_devices和usb_get_busses这三个函数获得已找到的USB总线序列;然后通过链表遍历所有的USB设备,根据已知的要打开USB设备的ID(VID/PID),找到相应的USB设备;最后调用usb_open函数打开该USB设备(在这里假设总线上没有相同VID和PID的USB设备。如果总线上存在着相同VID和PID的设备,还需要进行其他条件判断,比如设备名称,以保证是打开的是期望的USB设备)。
c.
使用usb_control_msg函数与USB设备进行通信,向USB设备读取数据或写入数据。
d. 关闭USB设备。