一个关于DeviceIoControl的函数的问题

80后传播者 2010-01-12 09:50:25
有这样一个控制HID设备的函数HidD_FlushQueue定义如下:
HidD_FlushQueue(
IN HANDLE HidDeviceObject
)
{
DWORD ret;

return DeviceIoControl(
HidDeviceObject,
IOCTL_HID_FLUSHQUEUE,
NULL,
0,
NULL,
0,
&ret,
NULL);
}

其中#define IOCTL_HID_FLUSHQUEUE CTL_CODE(FILE_DEVICE_HID, 0x65, METHOD_NEITHER, FILE_ANY_ACCESS)

请问这个DeviceIoControl实现什么功能,请高手指教!谢谢!!
...全文
478 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
junfzhao 2010-12-04
  • 打赏
  • 举报
回复
学习一下
学习一下!!!!!!1
80后传播者 2010-01-13
  • 打赏
  • 举报
回复
谢谢楼上几位。
wangk 2010-01-13
  • 打赏
  • 举报
回复
推测是刷新当前设备的数据队列吧,具体什么功能应该看设备是怎么响应的。
比如说,某个键盘设备它是这样处理的:


case IOCTL_GET_SYS_BUTTON_CAPS:
case IOCTL_HID_FLUSH_QUEUE:
case IOCTL_HID_SET_FEATURE:
case IOCTL_HID_GET_FEATURE:
case IOCTL_GET_PHYSICAL_DESCRIPTOR:
case IOCTL_HID_GET_HARDWARE_ID:
case IOCTL_HID_GET_MANUFACTURER_STRING:
case IOCTL_HID_GET_PRODUCT_STRING:
case IOCTL_HID_GET_SERIALNUMBER_STRING:
case IOCTL_HID_GET_INDEXED_STRING:
if (deviceExtension->PnP && (deviceExtension != Globals.GrandMaster)) {
IoSkipCurrentIrpStackLocation (Irp);
status = IoCallDriver (deviceExtension->TopPort, Irp);
break;
}

luckzengwei 2010-01-13
  • 打赏
  • 举报
回复
你这个DeviceIoControl里面参数的设置第三个到第六个都分别是NULL和0,这不就相当于你应用程序传递给驱动程序的数据缓冲区地址和数据字节数以及驱动程序返回数据的缓冲区地址和返回缓冲区字节数都是没有什么实际意义啦,你这个时候第二个参数应用程序调用驱动程序的控制命令还能够起作用吗?我不是很理解,我觉得你应用程序和底层驱动应该没办法完成通信
个人见解欢迎拍砖
80后传播者 2010-01-13
  • 打赏
  • 举报
回复
明白了,谢谢
MoXiaoRab 2010-01-13
  • 打赏
  • 举报
回复
你的程序Sleep完毕了,驱动没Sleep(实际上是一种类似Sleep)完毕,就Flush强制它放Buffer,然后你才能Read到。明白???

MoXiaoRab 2010-01-13
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 firstyangfeng 的回复:]
不好意思,我没说清楚,这个Sleep(2000)是我写的,不是驱动里的。
现在是:
WriteFile(……)//写数据到hid—usb
ReadFile(……)//读数据
读出来的就是老值;

但是
WriteFile(……)//写数据到hid—usb
Sleep(2000)
ReadFile(……)//读数据

or
WriteFile(……)//写数据到hid—usb
HidD_FlushQueue
ReadFile(……)  //读数据

就实现了“即读即写”的功能。HidD_FlushQueue之类的函数都是hid.dll中定义的,其实现无非是调用API函数DeviceIoControl来调用驱动例程。我所不明白的是为什么Sleep(2000)或HidD_FlushQueue之后就可以读到新值,否则就读到旧值。我不了解WriteFile和ReadFile的实现过程。现在要写一个报告把其原因说明一下,所以比较急。所以发了这么多帖,真诚希望得到高手的帮助。


[/Quote]
哎,你理解能力太不行了。

驱动 你的程序
Sleep Sleep
将内容放到IRP的Buffer ReadFile

明白!!!????
80后传播者 2010-01-13
  • 打赏
  • 举报
回复
不好意思,我没说清楚,这个Sleep(2000)是我写的,不是驱动里的。
现在是:
WriteFile(……)//写数据到hid—usb
ReadFile(……)//读数据
读出来的就是老值;

但是
WriteFile(……)//写数据到hid—usb
Sleep(2000)
ReadFile(……)//读数据

or
WriteFile(……)//写数据到hid—usb
HidD_FlushQueue
ReadFile(……) //读数据

就实现了“即读即写”的功能。HidD_FlushQueue之类的函数都是hid.dll中定义的,其实现无非是调用API函数DeviceIoControl来调用驱动例程。我所不明白的是为什么Sleep(2000)或HidD_FlushQueue之后就可以读到新值,否则就读到旧值。我不了解WriteFile和ReadFile的实现过程。现在要写一个报告把其原因说明一下,所以比较急。所以发了这么多帖,真诚希望得到高手的帮助。

MoXiaoRab 2010-01-13
  • 打赏
  • 举报
回复
轮询是根据驱动来的。也许驱动中就是将轮询设置成了1s多。
轮询其实是在IRP_MJ_READ里面一个写IRP的Buffer的过程,驱动里面“Sleep”一会再写那个缓冲区

当然,驱动里面Sleep不是通过Sleep函数。
Ytery 2010-01-13
  • 打赏
  • 举报
回复
旁观
80后传播者 2010-01-13
  • 打赏
  • 举报
回复
大牛!!哦,原来Flush的功能是强制PC将USB设备的数据读到缓冲区;那要是不用flush呢,轮询速度很快的,为什么要sleep(2000)才能readflie到新值呢?再有WriteFile和ReadFile写入和读出的缓冲区都是一个吗。
MoXiaoRab 2010-01-13
  • 打赏
  • 举报
回复
我前面的说法是针对Write的,不晓得原来你要的是Read。Read虽然原理差不多,但是有区别。
#12说的也是Write

"有人讲"那个是对的。要么是PC轮询,那么是自己Flush去强制PC将USB设备读到缓冲区,然后去ReadFile。
80后传播者 2010-01-13
  • 打赏
  • 举报
回复
有人讲ReadFile的IRP_MJ_READ就是直接从设备缓冲区中读数据,而PC不断向HID设备发出IN的中断轮询,将数据从USB设备读到缓冲区,再由ReadFile读取,按您的说法就是:PC轮询设备将数据读出->数据收集,待一定时间后-->写入设备缓冲区--〉ReadFile读取之。而flush后,就会消除收集时间,从而直接读到缓冲区中。不知我的理解对否,小弟这方面是菜鸟,望指正。
MoXiaoRab 2010-01-13
  • 打赏
  • 举报
回复
一样。要看它IRP_MJ_READ的写法了
80后传播者 2010-01-13
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 tr0j4n 的回复:]
引用 11 楼 firstyangfeng 的回复:
谢谢,那么收集数据一段时间的过程中如果没有新的数据来,也就是说没有收集到更多的数据的话,时间片到了之后是否也要将数据写入缓冲区呢?另外这个收集数据的缓冲区在哪里?是在驱动程序里吗?谢谢高手了。

要看你设备的驱动了。缓冲区在驱动里面的说法不准确,说是随着IRP传递,也觉得不够准确。大概是本人表达能力欠缺。
[/Quote]

您说的收集数据一段时间是不是指的 向设备写数据时在缓冲区收集一段时间,不直接写到设备上,我说的
正好相反,是从设备读数据(ReadFile读取HID设备),这个过程又是怎样呢?谢谢
80后传播者 2010-01-13
  • 打赏
  • 举报
回复
回复Tr0j4n

您说的收集数据一段时间是不是指的 向设备写数据时在缓冲区收集一段时间,不直接写到设备上,我说的
正好相反,是从设备读数据(ReadFile读取HID设备),这个过程又是怎样呢?谢谢
MoXiaoRab 2010-01-13
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 firstyangfeng 的回复:]
谢谢,那么收集数据一段时间的过程中如果没有新的数据来,也就是说没有收集到更多的数据的话,时间片到了之后是否也要将数据写入缓冲区呢?另外这个收集数据的缓冲区在哪里?是在驱动程序里吗?谢谢高手了。
[/Quote]
要看你设备的驱动了。缓冲区在驱动里面的说法不准确,说是随着IRP传递,也觉得不够准确。大概是本人表达能力欠缺。
80后传播者 2010-01-13
  • 打赏
  • 举报
回复
我用过的,不行,FlushFileBuffers好像只对disk IO进行刷新,我这个是HID设备。
wangk 2010-01-13
  • 打赏
  • 举报
回复
WriteFile后可以用FlushFileBuffers来刷新会比较和谐。
80后传播者 2010-01-13
  • 打赏
  • 举报
回复
谢谢,那么收集数据一段时间的过程中如果没有新的数据来,也就是说没有收集到更多的数据的话,时间片到了之后是否也要将数据写入缓冲区呢?另外这个收集数据的缓冲区在哪里?是在驱动程序里吗?谢谢高手了。
加载更多回复(7)

2,641

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧