转载请注明出处
作者:小马
二读写设备
正确到识别到设备后,下面就是对设备进行读写了.
对设备进行写操作,有两个方法可以用, 分别是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 );
读操作与写操作类似, 同样也是用重叠异步模式, 可以设置个超时时间,在这个时间内把数据读出来. 实际应用中,是用异步还是同步模式,
没有什么具体要求,我曾经试过做两种模式下的主机程序,效果差别不大. 不过,从程序的高效性和健壮性上考虑,肯定用异步模式.
至于重叠(异步)模式的概念及应用其实远不止于此,不过这不是我这篇文章的重点,下面这篇博文写的不错:
http://www.cppblog.com/Lee7/archive/2008/01/07/40630.html
作完读写操作,最后要释放一些资源, 既然有CreateFile, CloseHandle是必不可少的. 另外,如果在识别设备阶段调用了DDK的HidD_GetPreparsedData函数, 最后要调用HidD_FreePreparsedData释放掉.