- 浏览: 958133 次
- 性别:
- 来自: 珠海
文章分类
最新评论
-
Yunjey:
Yunjey 写道这样子的话、grid中的editable如何 ...
Flex创建可编辑以及分页的DataGrid -
Yunjey:
这样子的话、grid中的editable如何设置啊?!
Flex创建可编辑以及分页的DataGrid -
di1984HIT:
写的很好~~
JCalendar组件 -
sanny81:
此文真棒!感谢一路风尘的奉献!
但我有一疑 ...
Filter发送自定义数据详解 -
umgsai:
求完整demo umgsai@126.com
Flex和Jsp创建用户登入系统
一直所做的都是同步实现的。当然很多情况这并不是很好的解决问题。现在手上的问题是:用户层通知底层驱动(Filter Driver)做某件事,然后返回该事件执行的结果。如果该事件是一件简单的事情,这里是指极短时间内可以完成的,那么在允许范围内,我们可以用同步来完成。但是如果该事件是一件耗时的工作,而应用程序不能一直在等着该事件的完成信号,况且好像DeviceIoControl有时间限制的(?)。这就需要用异步的方式来解决问题:例如:同事叫你去吃饭,你听到后,可以马上去,也可以等会再去,吃完后再回到Office就好了。关键是我以前没有实现过,现在就手上的数资料来分析下可以实现的流程。
一、我们先看看关键函数DeviceIoControl:
BOOL WINAPI DeviceIoControl( __in HANDLE hDevice, __in DWORD dwIoControlCode, __in_opt LPVOID lpInBuffer, __in DWORD nInBufferSize, __out_opt LPVOID lpOutBuffer, __in DWORD nOutBufferSize, __out_opt LPDWORD lpBytesReturned, __inout_opt LPOVERLAPPED lpOverlapped );
+ ===== lpOverlapped =====
+ 一个指向OVERLAPPED结构体的指针
。
+ 如果hDevice用FILE_FLAG_OVERLAPPED 形式打开,lpOverlapped 必须指向一个合法的OVERLAPPED结构体。在这种情况下,进行异步操作
。
+ 如果hDevice用FILE_FLAG_OVERLAPPED 形式打开,而lpOverlapped为NULL,函数会返回不可预知的错误。
+ 如果hDevice打开时没有指定FILE_FLAG_OVERLAPPED 标志,lpOverlapped参数将被忽略,进行同步操作,函数直到操作完成或出现错误时才返回。
所以这里我们必须首先以FILE_FLAG_OVERLAPPED打开设备驱动。这里我们需要在CreateFile中指定:
HANDLE WINAPI CreateFile( __in LPCTSTR lpFileName, __in DWORD dwDesiredAccess, __in DWORD dwShareMode, __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes, __in DWORD dwCreationDisposition, __in DWORD dwFlagsAndAttributes, __in_opt HANDLE hTemplateFile );
如果dwFlagsAndAttributes指定值为:FILE_FLAG_OVERLAPPED,那么
When subsequent I/O operations are completed on this handle, the event specified in the OVERLAPPED structure will be set to the signaled state.
If this flag is specified, the file can be used for simultaneous read and write operations.
If this flag is not specified, then I/O operations are serialized, even if the calls to the read and write functions specify an OVERLAPPED structure.
For information about considerations when using a file handle created with this flag, see the Synchronous and Asynchronous I/O Handles section of this topic.
现在的问题来了,我们Overlapped的方式打开设备驱动,然后以异步的方式调用了DeviceIoControl,所以该函数会立马返回,返回值正确的应该为:ERROR_IO_PENDING 。这就表明底层驱动接受到了请求,然后应用程序应该有一种方式可以检测到该请求被底层正确执行完成的信号。
这里有个疑问:网上看到很多的例子,都是手动触发异步的完成,包括:驱动和应用层的异步通信
他们的做法没有等到最后的执行结果返回:所以在底层驱动手动设置了一些信息:
//获取irp状态 pIrp->IoStatus.Information = 0; pIrp->IoStatus.Status = STATUS_SUCCESS; pIrpStack = IoGetCurrentIrpStackLocation(pIrp); IoCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode; switch (IoCode) { case IO_TEST_PENDING: status = PsCreateSystemThread(&hthread, (ACCESS_MASK)0L, NULL, (HANDLE)0, NULL, ThreadPending, NULL); if (!NT_SUCCESS(status)) { return status; } KdPrint(("Pending thread ok...")); //直接设置为pending 返回给应用层。 status = STATUS_PENDING; IoMarkIrpPending(pIrp); pIrp->IoStatus.Status = status; return status; break; }
可能他们仅仅是为了测试,没有叫底层驱动做一些复杂的事情。接着讲...
二、等待执行完成信号
这里调用WaitForSingleObject并传递设备内核对象的句柄。
WaitForSingleObject会挂起调用线程直至内核对象变成有信号态。
DWORD WINAPI WaitForSingleObject( __in HANDLE hHandle, __in DWORD dwMilliseconds );
WaitForSingleObject 函数用来检测 hHandle 事件的信号状态,当函数的执行时间超过 dwMilliseconds 就返回,但如果参数 dwMilliseconds 为 INFINITE 时函数将直到相应时间事件变成有信号状态才返回,否则就一直等待下去,直到 WaitForSingleObject 有返回直才执行后面的代码。
这里我们把它处理成一个Event,所以在调用DeviceIoControl之前,我们必须创建一个Event:
HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes, // 安全属性 BOOL bManualReset, // 复位方式 BOOL bInitialState, // 初始状态 LPCTSTR lpName // 对象名称 );
示例: // 创建一个有名的,不能被继承的,手动复原,初始状态是无信号状态的事件对象
Handle h = CreateEvent(NULL,TRUE,FALSE,“MyEvent”);
然后作为OVERLAPPED数据成员传入DeviceIoControl函数。
例如:
OVERLAPPED varHIDOverlapped; .. varEventObjectHandle = CreateEvent(NULL, TRUE, TRUE, ""); if(varEventObjectHandle == INVALID_HANDLE_VALUE || varEventObjectHandle == NULL){ ..} varHIDOverlapped.hEvent = varEventObjectHandle; varHIDOverlapped.Offset = 0; varHIDOverlapped.OffsetHigh = 0; varCommand[0] = 0x05; varCommand[1] = 0; varCommand[2] = 0; DeviceIoControl (varUSBHandle, IOCTL_USBPRINT_VENDOR_GET_COMMAND, varCommand, 3, varStatus, 31, (LPDWORD)&varNumberOfBytes, (LPOVERLAPPED) &varHIDOverlapped); varEventResult = WaitForSingleObject(varEventObjectHandle, 2000);
当varEventResult返回的结果是:WAIT_OBJECT_0。表明句柄是一个signaled状态,然后应用线程接着执行余下的代码:
switch (varEventResult) { case WAIT_OBJECT_0: // It works break; case WAIT_TIMEOUT: // Timeout varEventResult = CancelIo(varUSBHandle); break; default: break; }
当然你也可是这样使用:
// This will return immediately... ULONG rc = DeviceIoControl( handle_, IOCTL_TSII_BOARD_SIGNAL_AT_TIMECODE, &tcsp, sizeof(tcsp), NULL, NULL, &nbytes, &overlapped); // How do I handle this??? if (rc == 0){ if (GetLastError() != ERROR_IO_PENDING) { throw Exception("overlapped i/o exception\n"); } } DWORD transf_byte; if(GetOverlappedResult(handle_,&overlapped,&transf_byte,TRUE) == 0) { //ERROR }
关于GetOverlappedResult:
BOOL WINAPI GetOverlappedResult( HANDLE hFile, LPOVERLAPPED lpOverlapped, LPDWORD lpNumberOfBytesTransferred, BOOL bWait )
The GetOverlappedResult function returns the result of the last
operation that used lpOverlapped and returned ERROR_IO_PENDING.
这样应该就差不多可以了吧(我猜的~,细节除外)。
下面是参考资料:
- 驱动和应用层的异步通信 http://bbs.pediy.com/showthread.php?t=59015
- DeviceIoControl的异步问题http://bbs.driverdevelop.com/read.php?tid-67288.html
- WaitForSingleObject的用法http://hi.baidu.com/zouhaoo/blog/item/1e863851615e3b858d54306c.html
- 多线程中使用waitforsingleobject方法http://www.360doc.com/content/09/0428/12/27287_3299491.shtml
- DeviceIoControl return code using Overlapped I/O http://www.osronline.com/showthread.cfm?link=167510
- 应用层跟驱动异步通信的问题,irp该如何处理?http://bbs.driverdevelop.com/read.php?tid-113399.html
- DeviceIOControl and overlapped I/O problem http://forums.devshed.com/c-programming-42/deviceiocontrol-and-overlapped-i-o-problem-255708.html
- http://www.techtalkz.com/microsoft-device-drivers/295657-deviceiocontrol-overlapped.html
- DeviceIoControl and OVERLAPPED problem
发表评论
-
Filter驱动:过滤(修改)接受数据包
2010-04-20 16:18 9215Filter驱动可以实现简单的防火墙功能。它可以过滤所有接收到 ... -
Ndis过滤驱动:拷贝NetBufferList数据
2010-04-19 22:40 9449今天我们来看看如何拷贝NBL中的数据。有时候需要更改数据包中的 ... -
在Filter驱动内核中获取IP地址
2010-04-18 01:48 3845项目开发中有时候需要在Filter驱动中获取有效地Unic ... -
如何在内核中获得当前系统时间
2010-04-16 15:08 2659在 Windows NT 内核中你是无法使用 tim ... -
Filter发送自定义数据详解
2010-04-16 10:30 5683... -
DebugPrint 格式说明符
2010-04-13 19:46 17241) 直接打印字符串。 DbgPrint(“Hello ... -
WDK+Visual Studio 2008配置编译驱动
2010-04-12 23:36 5519Introduction As it is known, ... -
疑问:关于内存释放
2010-04-12 21:33 1408今天碰到一个比较棘手的内存处理问题。 首先来看一个数据结构: ... -
Windows NT 驱动程序开发人员提示 -- 应注意避免的事项
2010-04-10 11:32 2284原讨论链接: http://community.cs ... -
关于DeviceIoControl实现异步的笔记【2】
2010-04-09 23:17 5040前面我们谈到了关于异步I/O的实现:关于DeviceIoCon ... -
驱动和应用层的异步通信
2010-04-08 20:55 5337作 者: sislcb时 间: 2008-01-28,11:1 ... -
Windows系统编程之异步I/O和完成端口
2010-04-08 19:40 2222一、 同步I/O和异步I/O ... -
纵横捭阖C++之从异步谈起
2010-04-08 19:31 3138一般来说,简单的异步(Asynchronous)调用是这样一种 ... -
使用DeviceIoControl通信
2010-04-04 22:53 7844在很多时候,某些用户需要与底层驱动有一个交互式的操作,所 ... -
在驱动中使用链表
2010-04-03 14:06 3238文章作者:grayfox 作 ... -
疑问:数据包Length增大的原因
2010-04-01 14:35 1326现象: 自己定义一个仅含有Ethernet Header的数 ... -
疑问:为何无线网卡无法发送数据?
2010-03-30 22:42 4481所有的测试流程表明,程序已经成功的创建新的数据包,然后调用Nd ... -
InsertHeadList和CONTAINING_RECORD
2010-03-29 16:36 3718LIST_ENTRY定义一个双向链表的数据结构: typed ... -
如何区分不同的Filter Module Instance
2010-03-29 14:50 1504前文 说到如何区分不同Filter Module Inst ... -
大数据是否需要封装在多个MDL中发送
2010-03-27 21:40 2462前段时间,我们已经解决如何发送自定义的网络数据。那么接下来要做 ...
相关推荐
DeviceIoControl的技术应用,我刚从网上下来的,非常好的语言
驱动程序函数DEVICEIOCONTROL的详细说明
硬件设备读写的基本操作DeviceIoControl,入门级教程
易语言DeviceIoControl取硬盘序列号源码,DeviceIoControl取硬盘序列号,倒序排列,DeviceIoControl,CreateFileA,CloseHandle,GetLastError,LocalAlloc,LocalFree
DeviceIoControl取硬盘序列号.rar
DeviceIOControl实战演示及源代码,是应用程序与设备通信很好的示例教程
硬件读写操作函数DeviceIoControl具体说明和用法,含样例代码
实战DeviceIoControl。 Aida整理。希望与大家多交流驱动开发经验。
DeviceIoControl CreateFile DeviceIoControl读取无线网卡mac完整工程实例 方便大家学习,如果还是看不懂,可以给我发邮件,帮你们解决
DeviceIoControl() CreateFile() 读取硬件物理网卡mac完整工程实例 Vs2012 c++ 源代码 功能:结合WMI和DeviceIoControl获取网卡原生MAC地址和当前MAC地址 入口参数: iQueryType:需要获取的网卡类型 0:包括...
简单讲述了下KernelIoControl和DeviceIoControl的区别,及其使用方法
一个WDM驱动,然后caller使用DeviceIoControl进行和驱动的通信。输出buffer使用METHOD_IN_DIRECT进行数据传输。
实战DeviceIoControl:通过API访问设备驱动程序
驱动开发:DeviceIoControl函数的详细使用说明,附加实例
网上有很多版本的《实战DeviceIoControl》,我这里做了一下整理,希望能对大家有所帮助。
实战DeviceIoControl:通过API访问设备驱动程序
VC++在使用DeviceIoControl函数时可以直接使用控制码的代号,VB(或者其它语言)就没这么方便了。本程序可以根据控制码的代号得到控制码的16进制值。