有这样一个控制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实现什么功能,请高手指教!谢谢!!

解决方案 »

  1.   

    http://baike.baidu.com/view/1288761.htm?fr=ala0_1
    对设备进行操作
      

  2.   

    这个网页我看过了,说得很笼统,能否结合我上面的代码讲一下?我具体想知道函数HidD_FlushQueue的功能是什么。谢谢
      

  3.   

    你这个DeviceIoControl里面参数的设置第三个到第六个都分别是NULL和0,这不就相当于你应用程序传递给驱动程序的数据缓冲区地址和数据字节数以及驱动程序返回数据的缓冲区地址和返回缓冲区字节数都是没有什么实际意义啦,你这个时候第二个参数应用程序调用驱动程序的控制命令还能够起作用吗?我不是很理解,我觉得你应用程序和底层驱动应该没办法完成通信
    个人见解欢迎拍砖
      

  4.   

    推测是刷新当前设备的数据队列吧,具体什么功能应该看设备是怎么响应的。
    比如说,某个键盘设备它是这样处理的:
        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;
            }
      

  5.   

    谢谢呵!补充一下,这几天一直发帖
    实现HID设备与PC的双向通信。目前设备已识别,而且可以正常通信。读写数据的代码如下: 
    memcpy(&wBuffer[1], m_writebuff, min(32, m_writebuff.GetLength())); 
    if(WriteFile(hidHandle, wBuffer, 33, &dwRet,NULL)) 

    //写成功 Sleep(2000); 
    if(ReadFile(hidHandle, rBuffer, 33, &dwRet, NULL)) 

    //读成功 
    memcpy(str, &rBuffer[1], min(32, strlen((char *)&rBuffer[1]))); 
    m_readbuff=str; 
    UpdateData(false); 

    else 
    MessageBox("读失败!"); MessageBox("读写成功!"); } 
    else 
    MessageBox("写失败!"); 但是必须得有Sleep(2000);一句,否则读出的数据就是“旧值”,需要读好几次才能读到“新值”。也就是说先用WriteFile写数据,马上用ReadFile读数据是不行的,需要延迟。而且我已测明不是hid设备慢,因为使用一个软件读写该设备可以实现“即写即读”。一位高手建议在WriteFile后面调用函数HidD_FlushQueue,结果果然奏效,但是不知其所以然,在这里刷新handle的buffer有什么用,其实现机理是什么?核心问题集中在函数HidD_FlushQueue的作用,为什么刷新数据队列后即可以实现hid 设备读写的同步。谢谢!!!!!
      

  6.   

    在WriteFile后面调用函数HidD_FlushQueue也可,CloseHandle也可。CLose的时候系统会把缓存写入,要么你自己强制Flush将缓存写入。
      

  7.   

    谢谢,我试过CloseHandle,是不行的,目前只有HidD_FlushQueue函数可以。为什么清除了缓冲区后ReadFile就能读到新值了?hid设备应该是通过轮询设备将hid的数据读到缓冲区的,ReadFile只是从缓冲区中读取设备,按道理PC的轮询周期应该很快呀,为什么不加HidD_FlushQueue函数,要延时2秒左右才能读到新值呢?望高手指点!!
      

  8.   

    CloseHandle之后再重新打开时可以的。我以前用过,可能实际中和你有差异系统对设备并不是数据以来就放进设备缓冲区的,要么是在收集数据一段时间后,统一写入缓存。要么是关闭后,系统会写入,要么是自己强制Flush。这是出于效率性能的考虑
      

  9.   

    WriteFile后可以用FlushFileBuffers来刷新会比较和谐。
      

  10.   

    我用过的,不行,FlushFileBuffers好像只对disk IO进行刷新,我这个是HID设备。
      

  11.   

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

  12.   

    回复Tr0j4n您说的收集数据一段时间是不是指的 向设备写数据时在缓冲区收集一段时间,不直接写到设备上,我说的
    正好相反,是从设备读数据(ReadFile读取HID设备),这个过程又是怎样呢?谢谢
      

  13.   


    您说的收集数据一段时间是不是指的 向设备写数据时在缓冲区收集一段时间,不直接写到设备上,我说的 
    正好相反,是从设备读数据(ReadFile读取HID设备),这个过程又是怎样呢?谢谢
      

  14.   

    一样。要看它IRP_MJ_READ的写法了
      

  15.   

    有人讲ReadFile的IRP_MJ_READ就是直接从设备缓冲区中读数据,而PC不断向HID设备发出IN的中断轮询,将数据从USB设备读到缓冲区,再由ReadFile读取,按您的说法就是:PC轮询设备将数据读出->数据收集,待一定时间后-->写入设备缓冲区--〉ReadFile读取之。而flush后,就会消除收集时间,从而直接读到缓冲区中。不知我的理解对否,小弟这方面是菜鸟,望指正。
      

  16.   

    我前面的说法是针对Write的,不晓得原来你要的是Read。Read虽然原理差不多,但是有区别。
    #12说的也是Write"有人讲"那个是对的。要么是PC轮询,那么是自己Flush去强制PC将USB设备读到缓冲区,然后去ReadFile。
      

  17.   

    大牛!!哦,原来Flush的功能是强制PC将USB设备的数据读到缓冲区;那要是不用flush呢,轮询速度很快的,为什么要sleep(2000)才能readflie到新值呢?再有WriteFile和ReadFile写入和读出的缓冲区都是一个吗。
      

  18.   

    轮询是根据驱动来的。也许驱动中就是将轮询设置成了1s多。
    轮询其实是在IRP_MJ_READ里面一个写IRP的Buffer的过程,驱动里面“Sleep”一会再写那个缓冲区当然,驱动里面Sleep不是通过Sleep函数。
      

  19.   

    不好意思,我没说清楚,这个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的实现过程。现在要写一个报告把其原因说明一下,所以比较急。所以发了这么多帖,真诚希望得到高手的帮助。
      

  20.   

    哎,你理解能力太不行了。驱动                    你的程序
    Sleep                 Sleep
    将内容放到IRP的Buffer  ReadFile明白!!!????  
      

  21.   

    你的程序Sleep完毕了,驱动没Sleep(实际上是一种类似Sleep)完毕,就Flush强制它放Buffer,然后你才能Read到。明白???