阅读:2066回复:7
驱动程序怎样与上层应用程序通信??
我的驱动程序处于核心模式,想主动向位于用户模式的程序发送数据,但我不知道该怎样做?我想通过内存共享的方式,但我不知道具体该怎样做,现在仍然一筹莫展!那位高手可以提示一下吗?
|
|
最新喜欢:![]() |
沙发#
发布于:2002-03-21 09:41
好象是说可以用个共享EVENT什么的来通知应用程序,找找把,好象有这种贴子
|
|
|
板凳#
发布于:2002-03-21 09:49
用WmiFireEvent向application发送event,然后由application来向driver要数据
|
|
|
地板#
发布于:2002-03-21 10:06
我的驱动程序是要不连贯地随时向一个特定的程序发送数据.
楼上那位说的方法,我不太熟悉,能否介绍一下驱动程序和应用程序具体怎样传送数据? |
|
地下室#
发布于:2002-03-21 10:19
其实我也没有经验,不太懂。
好像一般流程是这样的: driver用WmiFireEvent向application发送event,然后application在响应这个event的时候就去向driver主动要数据。这样虽然还是driver被动的等待要数据,但是是由driver主动发起这次数据传送的。 似乎没有什么别的办法可以让driver直接把数据送给application。如果有,大家知道了告诉我哦。 |
|
|
5楼#
发布于:2002-03-21 10:24
这是论坛上的一篇文章,你可以 专栏文章 里找到
概要 在 Windows NT 和 Windows 2000 中,内核模式驱动程序无法回调到用户模式的应用程序中。 这是设计使然。 对于要将异步事件通知应用程序的驱动程序,应用程序需要一直使用驱动程序来使 I/O 请求保持挂起状态,以便在每次发生事件时驱动程序都可以完成请求。 本文概述应用程序与驱动程序可以用来完成异步通知的典型方案。 更多信息 应用程序 应用程序可以有专用的输入线程。 线程将进入发送 I/O 请求并等待响应的循环中。 如果驱动程序已打开,并且获得 hDevice 句柄,则循环类似于如下: while (!Application exiting) { returnval = DeviceIoControl (hDevice, dwIoControlCode, lpvInBuffer, cbInBuffer, lpvOutBuffer, cbOutBuffer, lpcbBytesReturned, lpoOverlapped); if (!returnval && (GetLastError() == ERROR_IO_PENDING)) { WaitForSingleObject (hEvent, INFINITE) // hEvent is located in overlapped structure as well ... // Code to do action ResetEvent (hEvent) } { ... // Code to handle other situations } } BOOL 型 Application exiting() 代表循环应停止检查事件的条件。 如果需要退出,应用程序的主线程可以将该 BOOL 型设置为 TRUE。 I/O 控制代码 dwIoControlCode() 是由驱动程序定义的。 为使其它应用程序线程能够在该请求挂起时继续将请求发送到驱动程序,必须异步进行上述 DeviceIoControl 调用。 可以使用已被初始化的事件并传入 DeviceIoControl 调用的重叠结构中,使该线程与请求完成保持同步。 一旦事件被满足,该线程就可以通知其它应用程序线程:该事件已发出信号。 如果没有指定重叠结构,在驱动程序中处理该请求的同时,所有其它线程将被阻塞。 直到完成同步的 DeviceIoControl,其它线程才会被释放。 如果驱动程序使用读取请求发送异步事件通知,则用户模式线程还可以使用 ReadFile() 或 ReadFileEx(),而不使用 DeviceIoControl()。 驱动程序 驱动程序应当等到事件已经发生才完成 I/O 请求。当驱动程序收到 I/O 请求时,如果事件已发生且正等待被发送到应用程序,则驱动程序可以在调度例程中完成该请求。 如果没有任何等待报告的事件,驱动程序应执行下列步骤: 使用 IoMarkIrpPending() 将 Irp 标记为等待。 使用 IoSetCancelRoutine() 为 Irp 建立取消例程。 将 Irp 放在存储位置中(如队列)。 从调度例程返回 STATUS_PENDING。 以后,当事件已发生时,驱动程序可以通过它的延时过程调用 (DPC) 例程来完成挂起的请求。 完成 Irp 之前,驱动程序应使用 IoSetCancelRoutine 将取消例程地址设置为 NULL。 |
|
|
6楼#
发布于:2002-03-21 11:32
另一种方法是建立一个命名事件对象,让应用程序和驱动程序来共享这个事件对象。至于这个事件对象由谁来建立,没有多大关系,但一般都习惯于由驱动程序来建立。
然后应用程序端就可以等待这个事件信号状态,驱动程序想主动和应用程序通讯的时候就会置这个事件信号状态。 Best regards! |
|
|
7楼#
发布于:2002-03-21 12:17
另一种方法是建立一个命名事件对象,让应用程序和驱动程序来共享这个事件对象。至于这个事件对象由谁来建立,没有多大关系,但一般都习惯于由驱动程序来建立。 我说的就是这个方法,是用WMI的机制。 |
|
|