来自:http://ponymaggie.blog.sohu.com/158699015.html
二 读写设备
正确到识别到设备后,下面就是对设备进行读写了.
对设备进行写操作,有两个方法可以用, 分别是HidD_SetOutputReport 和WriteFile. 前者到底层只能用control transfer, 而WriteFile可以用interrupt out transfer来传输数据. 同样对于读操作,也有两个类似的操作. 下面的表格比较清楚的说明这几个函数的关系:
先来说说写,以WriteFile举例. 可以用类似下面的形式发送一个报告
BOOL bRet = WriteFile(HidDevice,
WriteBuffer,
Capabilities.OutputReportByteLength,
&NumberOfBytesWriten,
&WriteOverlapped)
HidDevice是CreateFile返回的句柄, WriteBuffer是发送数据的缓冲区, Capabilities.OutputReportByteLength是要发送的数据长度,这个值就是报告的大小加1, NumberOfBytesWriten返回实际发送的大小. 最后一个参数比较复杂点, 它跟CreateFile有关,如果在前面的CreateFile中用的是重叠模式(异步),这里最后一个参数就不能为空. 在异步模式下,即使WriteFile没有完成,函数也会返回, 这种情况下, GetLastError会返回ERROR_IO_PENDING, 我们的程序可以根据这个返回值继续完成对设备的写操作. 那么如何等待写操作的完成呢, windows为我们提供了一个API,
BOOL GetOverlappedResult(
HANDLE hFile,
LPOVERLAPPED lpOverlapped,
LPDWORD lpNumberOfBytesTransferred,
BOOL bWait
);
注意它的第三个参数跟WriteFile是一样的,事实上, 在异步模式操作时,WriteFile的第三个参数可以置空,因为它并没有实际的意义,在写操作完成时,getoverlappedresult函数会返回实际传送的字节数.
读操作与写操作类似, 同样也是用重叠异步模式, 可以设置个超时时间,在这个时间内把数据读出来. 实际应用中,是用异步还是同步模式,没有什么具体要求,我曾经试过做两种模式下的主机程序,效果差别不大. 不过,从程序的高效性和健壮性上考虑,肯定用异步模式.
至于重叠(异步)模式的概念及应用其实远不止于此,不过这不是我这篇文章的重点,下面这篇博文写的不错:
http://www.cppblog.com/Lee7/archive/2008/01/07/40630.html
作完读写操作,最后要释放一些资源, 既然有CreateFile, CloseHandle是必不可少的. 另外,如果在识别设备阶段调用了DDK的
HidD_GetPreparsedData函数, 那么最后要调用HidD_FreePreparsedData释放掉.