社区
硬件/系统
帖子详情
读写USB设备出错,WriteFile、ReadFile失败,高手请帮忙!急!
xingkong1985
2009-07-09 02:00:47
最近在做USB设备的通信程序,芯片厂家已提供驱动,在通信程序中,我已经成功枚举出连接在PC机上所有USB设备,并且可以正确获得设备句柄,CreateFile是成功的(独占设备除外)。但是在对句柄进行ReadFile和WriteFile读写操作时,总是不成功,用GetLastError检查,返回值是87,参数错误,无论我怎么修改,参照MSDN,都不成功,希望高手能帮忙。感激不尽啊!
...全文
2169
12
打赏
收藏
读写USB设备出错,WriteFile、ReadFile失败,高手请帮忙!急!
最近在做USB设备的通信程序,芯片厂家已提供驱动,在通信程序中,我已经成功枚举出连接在PC机上所有USB设备,并且可以正确获得设备句柄,CreateFile是成功的(独占设备除外)。但是在对句柄进行ReadFile和WriteFile读写操作时,总是不成功,用GetLastError检查,返回值是87,参数错误,无论我怎么修改,参照MSDN,都不成功,希望高手能帮忙。感激不尽啊!
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
12 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
luckyboy1979
2010-08-20
打赏
举报
回复
//编译环境: Borland C++ Builder 6.0, Windows Server 2003 DDK
//运行环境: Win98/2000/XP/2003
//下面是访问 USB 口必备的函数:
#include <vcl.h>
#include <dir.h>
#include <setupapi.h>
#include "C:/WINDDK/3790/inc/ddk/w2k/usbdi.h"
#include "C:/WINDDK/3790/inc/ddk/w2k/devioctl.h"
#include <initguid.h>
//---------------------------------------------------------------------------
// 下面必须为驱动程序的 GUID 值, 这里我乱写的数
DEFINE_GUID(USB_DRIVER_GUID, 0x12345678,0xabcd,0x1122,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00);
//---------------------------------------------------------------------------
HANDLE OpenOneDevice(HDEVINFO hDvcInfo, PSP_INTERFACE_DEVICE_DATA DvcInfoData, char *sDevNameBuf)
{
HANDLE hOut = INVALID_HANDLE_VALUE;
ULONG iReqLen = 0;
SetupDiGetInterfaceDeviceDetail(hDvcInfo, DvcInfoData, NULL, 0, &iReqLen, NULL);
ULONG iDevDataLen = iReqLen; //sizeof(SP_FNCLASS_DEVICE_DATA) + 512;
PSP_INTERFACE_DEVICE_DETAIL_DATA pDevData = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(iDevDataLen);
pDevData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
if(SetupDiGetInterfaceDeviceDetail(hDvcInfo, DvcInfoData, pDevData, iDevDataLen, &iReqLen, NULL))
{
strcpy(sDevNameBuf, pDevData->DevicePath);
hOut = CreateFile(pDevData->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
}
free(pDevData);
return hOut;
}
//---------------------------------------------------------------------------
HANDLE OpenUsbDevice(const GUID *pGuid, char *sDevNameBuf)
{
HANDLE hOut = INVALID_HANDLE_VALUE;
HDEVINFO hDevInfo = SetupDiGetClassDevs(pGuid, NULL, NULL, DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
SP_INTERFACE_DEVICE_DATA deviceInfoData;
deviceInfoData.cbSize = sizeof (SP_INTERFACE_DEVICE_DATA);
ULONG nGuessCount = MAXLONG;
for(ULONG iDevIndex=0; iDevIndex<nGuessCount; iDevIndex++)
{
if(SetupDiEnumDeviceInterfaces(hDevInfo, 0, pGuid, iDevIndex, &deviceInfoData))
{
if((hOut=OpenOneDevice(hDevInfo, &deviceInfoData, sDevNameBuf)) != INVALID_HANDLE_VALUE)
break;
}
else if(GetLastError() == ERROR_NO_MORE_ITEMS) //No more items
{
break;
}
}
SetupDiDestroyDeviceInfoList(hDevInfo);
return hOut;
}
//---------------------------------------------------------------------------
bool GetUsbDeviceFileName(const GUID *pGuid, char *sDevNameBuf)
{
HANDLE hDev = OpenUsbDevice(pGuid, sDevNameBuf);
if(hDev != INVALID_HANDLE_VALUE)
{
CloseHandle(hDev);
return true;
}
return false;
}
//---------------------------------------------------------------------------
HANDLE OpenMyDevice()
{
char DeviceName[MAXPATH] = "";
return OpenUsbDevice(&USB_DRIVER_GUID, DeviceName);
}
//---------------------------------------------------------------------------
HANDLE OpenMyDevPipe(const char *PipeName)
{
char DeviceName[MAXPATH] = "";
if(GetUsbDeviceFileName(&USB_DRIVER_GUID, DeviceName))
{
strcat(DeviceName,"\\");
strcat(DeviceName,PipeName);
return CreateFile(DeviceName, GENERIC_WRITE|GENERIC_READ, FILE_SHARE_WRITE|FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
}
return INVALID_HANDLE_VALUE;
}
//---------------------------------------------------------------------------
有了上面的函数就可以访问 USB 口了:
//打开 USB 口读写, 由驱动程序的 Pipe 名确定
HANDLE hPipe = OpenMyDevPipe("MyPipe1"); //驱动程序里面的 Pipe 名, 对应访问某个端点的 I/O, 这里我乱写的, 需要与驱动一致
if(hPipe != INVALID_HANDLE_VALUE) //打开 Pipe 成功
{
ReadFile(hPipe, Buffer, BufSize, &nBytesRead, NULL); //从 hPipe 里读取数据到 Buffer 里
//WriteFile(hPipe, Buffer, BytesToWrite, &nBytesWritten, NULL); //把 Buffer 里面的 BytesToWrite 字节写入 hPipe
CloseHandle(hPipe);
}
//使用 DeviceIoControl 访问 USB 设备
HANDLE hDevice = OpenMyDevice();
if(hDevice != INVALID_HANDLE_VALUE) //打开设备成功
{
//这些 DeviceIoControl 功能都是由设备定义的, 具体看设备和驱动的资料
if(DeviceIoControl(hDevice, IOCTL_READ_xxxx, &IOBlock, sizeof(IOBLOCK), &c, 1, &nBytes, NULL))
{
//成功
}
CloseHandle(hDevice);
}
这也是我看到的,不知道是否有帮助
snowwood
2010-07-30
打赏
举报
回复
我也遇到了同样的问题,有谁知道请回复一下呗
yylooker2008
2010-06-13
打赏
举报
回复
mark;
krpol2005
2009-11-16
打赏
举报
回复
lz问题解决了没有?
我也出现了和你一样的问题
西山小月
2009-07-10
打赏
举报
回复
用DeviceIoControl
xingkong1985
2009-07-10
打赏
举报
回复
那么用DeviceIoControl应该怎么做呢?是直接用它读取和写入数据,还是用它打开pipe后再读写?
marrco2005
2009-07-09
打赏
举报
回复
mark
xingkong1985
2009-07-09
打赏
举报
回复
我发送数据想改用DeviceIoControl,也不行,总是说请求无效!
char ReceiveNum[512];
DWORD ReceiveNumSize=sizeof(ReceiveNum);
ULONG bytesreturned;
HANDLE handle;
handle=hCom[1];
bret=DeviceIoControl(handle,
IOCTL_SEND_BUFFERED_PACKETS,
ReceiveNum,
ReceiveNumSize,
NULL,
0,
&bytesreturned,
NULL);
CString test;
int error;
error=GetLastError();
test.Format("%d",error);
if (bret)
{
MessageBox("写入成功!");
}
else
{
MessageBox("写入失败!");
MessageBox(test);
}
请各位高手帮帮忙。
xingkong1985
2009-07-09
打赏
举报
回复
#define IOCTL_SEND_BUFFERED_PACKETS CTL_CODE(FILE_DEVICE_PHYSICAL_NETCARD,0x839, METHOD_BUFFERED,FILE_READ_DATA)
GUID Deviceguid = {0xa5dcbf10, 0x6530, 0x11d2, 0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed};
HANDLE hCom[11];
BOOL bret=FALSE;
CString ShowMessage;
ShowMessage.Empty();
ShowMessage = _T("开始查找USB设备......\r\nUSB类的GUID标识为:\r\n");
SetDlgItemText(IDC_EDIT_SHOW,ShowMessage);
ShowMessage+= _T("a5dcbf10-6530-11d2-901f-00c04fb951ed\r\n\r\n");
SetDlgItemText(IDC_EDIT_SHOW,ShowMessage);
LPGUID pInterfaceGuid = &Deviceguid;
HDEVINFO hDeviceInfo = SetupDiGetClassDevs(pInterfaceGuid,
NULL,
NULL,
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (hDeviceInfo==INVALID_HANDLE_VALUE)
{
MessageBox("设备信息不可用!");
}
/* CString test;
test.Format("%d",hDeviceInfo);
MessageBox(test);*/
ShowMessage += _T("正在查找可用的USB设备...\r\n");
SetDlgItemText(IDC_EDIT_SHOW,ShowMessage);
SP_DEVICE_INTERFACE_DATA spDevInterData;
memset(&spDevInterData, 0x00, sizeof(SP_DEVICE_INTERFACE_DATA));
spDevInterData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
DWORD nIndex = 0;
ShowMessage += _T("查找USB设备接口...\r\n");
SetDlgItemText(IDC_EDIT_SHOW,ShowMessage);
while(TRUE)
{
bret=SetupDiEnumDeviceInterfaces( hDeviceInfo,
NULL,
pInterfaceGuid,
nIndex,
&spDevInterData);
if ((!bret)&&(GetLastError()==ERROR_NO_MORE_ITEMS))
{
if (nIndex==0)
{
AfxMessageBox(_T("未找到可用的设备!"));
return;
}
else
{
ShowMessage += _T("\r\n目前没有更多可用的设备!");
SetDlgItemText(IDC_EDIT_SHOW,ShowMessage);
SetupDiDestroyDeviceInfoList(hDeviceInfo);
return;
}
}
ShowMessage += _T("\r\n找到一个USB设备!\r\n");
SetDlgItemText(IDC_EDIT_SHOW,ShowMessage);
ShowMessage += _T("读取设备路径名......\r\n");
SetDlgItemText(IDC_EDIT_SHOW,ShowMessage);
DWORD Length=0;
bret = SetupDiGetDeviceInterfaceDetail(
hDeviceInfo,
&spDevInterData,
NULL,
0,
&Length,
NULL);
if (!bret)
{
if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
{
ShowMessage += _T("计算所需长度......\r\n");
SetDlgItemText(IDC_EDIT_SHOW,ShowMessage);
}
}
PSP_DEVICE_INTERFACE_DETAIL_DATA pstDetailData;
pstDetailData = NULL;
pstDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length);
if(NULL == pstDetailData)
{
MessageBox("HeapAlloc Memory Failed");
if (!SetupDiDestroyDeviceInfoList(hDeviceInfo))
{
MessageBox("SetupDiDestroyDeviceInfoList Error!");
}
return;
}
pstDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
//SP_DEVINFO_DATA infodata;
//infodata.cbSize=sizeof(SP_DEVINFO_DATA);
bret = SetupDiGetDeviceInterfaceDetail(
hDeviceInfo,
&spDevInterData,
pstDetailData,
Length,
&Length,
NULL);
if (!bret)
{
MessageBox("查找路径时出错!");
return;
}
vDevicePath=pstDetailData->DevicePath;
CString strshow;
strshow.Empty();
strshow.Format("可以通过路径:\r\n%s\r\n访问设备\r\n",vDevicePath);
ShowMessage += strshow;
SetDlgItemText(IDC_EDIT_SHOW,ShowMessage);
ShowMessage += _T("打开设备接口......\r\n");
SetDlgItemText(IDC_EDIT_SHOW,ShowMessage);
hCom[nIndex] = CreateFile(pstDetailData->DevicePath,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
Comnumber.Empty();
if (hCom[nIndex]==INVALID_HANDLE_VALUE)
{
MessageBox("打开通信端口失败!");
ShowMessage += _T("句柄号———hCom[");
Comnumber.Format("%d",nIndex);
ShowMessage = ShowMessage+Comnumber+_T("]\r\n");
SetDlgItemText(IDC_EDIT_SHOW,ShowMessage);
goto next;
}
else
{
MessageBox("打开通信端口成功!");
ShowMessage +=_T("句柄号———hCom[");
Comnumber.Format("%d",nIndex);
ShowMessage = ShowMessage+Comnumber+_T("]\r\n");
SetDlgItemText(IDC_EDIT_SHOW,ShowMessage);
CString test;
test.Format("%d",hCom[nIndex]);
MessageBox(test);
goto read;
}
read:
{
DWORD BufferSize=512;
DWORD NumberRead=0;
char* Buffer;
Buffer= new char[512];
while (bret=ReadFile(hCom[nIndex],Buffer,BufferSize,&NumberRead,NULL))
{
if (bret)
{
MessageBox("读取成功!");
}
else
{
MessageBox("读取失败!");//总是失败,用GetLastError来看,返回87.
}
}
}
next:
if (NULL != pstDetailData)
{
HeapFree(GetProcessHeap(), 0, pstDetailData);
pstDetailData = NULL;
}
nIndex++;
}
kondykuang
2009-07-09
打赏
举报
回复
在网上找找 相关的程序 看看别人是这么写的·
wangk
2009-07-09
打赏
举报
回复
厂家没有提供通讯规范吗?
要发多大Buffer,哪些位要特殊标记,等等……
还是要厂家要求support吧。
一条晚起的虫
2009-07-09
打赏
举报
回复
//请贴出代码
vb
usb
调试程序 源代码
简单的
usb
调试程序,vb6开发,可用于初学者的借鉴和测试
易语言
设备
操作模块源码-易语言
易语言
设备
操作模块源码
串口编程源代码.zip
串口编程源代码例程,VC6例程,作为入门例子有参考价值。
SerialPort+-+串口通信代码_C语言串口_C语言serial_c语言串口_serialport_SerialPort+
在C语言中的SerialPort+-+串口通信代码
VC实现串口通信
用VC++6.0实现串口调试助手功能,是学习串口通信编程的好资料
硬件/系统
2,643
社区成员
17,232
社区内容
发帖
与我相关
我的任务
硬件/系统
VC/MFC 硬件/系统
复制链接
扫一扫
分享
社区描述
VC/MFC 硬件/系统
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章