总结应用和驱动之间用事件通讯的办法
2009-03-15 12:47
288 查看
总结应用和驱动之间用事件通讯的办法
1. 驱动中IoCreateNotificationEvent,KeClearEvent
应用中OpenEvent(SYNCHRONIZE, FALSE, EVENT_NAME)
这样,只能在应用中WaitForSingleObject,而不能SetEvent,ResetEvent
驱动中可以KeSetEvent,(而且必须紧接着KeClearEvent,因为在应用中不能修改核心态创建的对象的状态,只能在这个时候清除状态了),即只能由驱动通知应用,在某些应用只需要等待通知的场合足够了,如应用等待数据准备好的通知,这时可以在中断处理函数中设置事件有信号
注意,OpenEvent第一个参数不能为EVENT_ALL_ACCESS,因为应用没有这么大权限操作在系统上下文创建的事件
2.在驱动中创建事件,并把时间句柄传给应用,应用不必OpenEvent。应用程序可以随意set,reset事件,这样可以和驱动中的系统线程进行同步
这种方法的前提条件是,event是在应用的进程上下文(在系统上下文创建的话就不可以)创建,并传给应用的,比如可以在某个IOCtl分支中创建事件并传给应用。
解释:在使用EVENT的PROCESS context中创的HANDLE就在这个进程的句柄表里,经检验没有权限限制,可以由应用直接使用;而在system context中创建的HANDLE当然就在SYSTEM进程里啦,若单单传句柄值给应用,而句柄表里根本就没有对应的句柄,当然不成功了。
代码如下
驱动中:
void ppppp(PVOID event)
{
KeWaitForSingleObject((PKEVENT)event,Executive,UserMode,0,0);
//......验证处
}
......
WCHAR wEventNameBuf[]=L"//BaseNamedObjects//SharedEvent";
UNICODE_STRING uEventName;
PKEVENT pEvent;
HANDLE hEvent,hThread;
......
case IOCTL_******:
RtlInitUnicodeString(&uEventName,wEventNameBuf);
pEvent = IoCreateNotificationEvent(&uEventName,&hEvent);
KeResetEvent(pEvent);
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,&hEvent,4);
PsCreateSystemThread(&hThread,THREAD_ALL_ACCESS,0,0,0,ppppp,pEvent);
应用中:
if(!DeviceIoControl(hDevice,IOCTL_******,0,0,&Handle,4,&Bytes,0))
MessageBox("DeviceIo Error!");
esle{
wsprintf(str,"%x,%x,%x",hDevice,Bytes,Handle);
MessageBox(str);
if(!SetEvent((HANDLE)Handle))
......
}
会看到,点击MessageBox OK后ppppp的确继续执行了。
3.在应用中创建事件,然后通过ioctl传给驱动,驱动中ObReferenceObjectByHandle来引用该事件对象。
这样应用和驱动中都可以检查和修改事件状态。
应用程序:
HANDLE m_hCommEvent = CreateEvent(NULL,
false,
false,
NULL);
// download event object to device driver,
// m_hCommDevice is the device object
DeviceIoControl(m_hCommDevice,
IO_REFERENCE_EVENT,
(LPVOID) m_hCommEvent,
0,
NULL,
0,
dwReturn,
NULL);
在需要的地方等待
while(true)
{
WaitForSingleObject(m_hCommEvent, INFINITE);
// After this function, the event is set to
// non signaled. Get information and deal with it.
}
驱动程序:
case IO_REFERENCE_EVENT:
hEvent = (HANDLE) irpStack->
Parameters.DeviceIoControl.Type3InputBuffer;
status = ObReferenceObjectByHandle(hEvent,
GENERIC_ALL,
NULL,
KernelMode,
&gpEventObject,
&objHandleInfo);
the gpEventObject is a PRKEVENT object, so we can use KeEventXXX and KeWaitForXXX to operate it.
当事件发生时,置信号
KeSetEvent(gpEventObject, 0, FALSE);
当不再需要事件对象时:
case IO_DEREFERENCE_EVENT:
if(gpEventObject)
ObDereferenceObject(gpEventObject);
1. 驱动中IoCreateNotificationEvent,KeClearEvent
应用中OpenEvent(SYNCHRONIZE, FALSE, EVENT_NAME)
这样,只能在应用中WaitForSingleObject,而不能SetEvent,ResetEvent
驱动中可以KeSetEvent,(而且必须紧接着KeClearEvent,因为在应用中不能修改核心态创建的对象的状态,只能在这个时候清除状态了),即只能由驱动通知应用,在某些应用只需要等待通知的场合足够了,如应用等待数据准备好的通知,这时可以在中断处理函数中设置事件有信号
注意,OpenEvent第一个参数不能为EVENT_ALL_ACCESS,因为应用没有这么大权限操作在系统上下文创建的事件
2.在驱动中创建事件,并把时间句柄传给应用,应用不必OpenEvent。应用程序可以随意set,reset事件,这样可以和驱动中的系统线程进行同步
这种方法的前提条件是,event是在应用的进程上下文(在系统上下文创建的话就不可以)创建,并传给应用的,比如可以在某个IOCtl分支中创建事件并传给应用。
解释:在使用EVENT的PROCESS context中创的HANDLE就在这个进程的句柄表里,经检验没有权限限制,可以由应用直接使用;而在system context中创建的HANDLE当然就在SYSTEM进程里啦,若单单传句柄值给应用,而句柄表里根本就没有对应的句柄,当然不成功了。
代码如下
驱动中:
void ppppp(PVOID event)
{
KeWaitForSingleObject((PKEVENT)event,Executive,UserMode,0,0);
//......验证处
}
......
WCHAR wEventNameBuf[]=L"//BaseNamedObjects//SharedEvent";
UNICODE_STRING uEventName;
PKEVENT pEvent;
HANDLE hEvent,hThread;
......
case IOCTL_******:
RtlInitUnicodeString(&uEventName,wEventNameBuf);
pEvent = IoCreateNotificationEvent(&uEventName,&hEvent);
KeResetEvent(pEvent);
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,&hEvent,4);
PsCreateSystemThread(&hThread,THREAD_ALL_ACCESS,0,0,0,ppppp,pEvent);
应用中:
if(!DeviceIoControl(hDevice,IOCTL_******,0,0,&Handle,4,&Bytes,0))
MessageBox("DeviceIo Error!");
esle{
wsprintf(str,"%x,%x,%x",hDevice,Bytes,Handle);
MessageBox(str);
if(!SetEvent((HANDLE)Handle))
......
}
会看到,点击MessageBox OK后ppppp的确继续执行了。
3.在应用中创建事件,然后通过ioctl传给驱动,驱动中ObReferenceObjectByHandle来引用该事件对象。
这样应用和驱动中都可以检查和修改事件状态。
应用程序:
HANDLE m_hCommEvent = CreateEvent(NULL,
false,
false,
NULL);
// download event object to device driver,
// m_hCommDevice is the device object
DeviceIoControl(m_hCommDevice,
IO_REFERENCE_EVENT,
(LPVOID) m_hCommEvent,
0,
NULL,
0,
dwReturn,
NULL);
在需要的地方等待
while(true)
{
WaitForSingleObject(m_hCommEvent, INFINITE);
// After this function, the event is set to
// non signaled. Get information and deal with it.
}
驱动程序:
case IO_REFERENCE_EVENT:
hEvent = (HANDLE) irpStack->
Parameters.DeviceIoControl.Type3InputBuffer;
status = ObReferenceObjectByHandle(hEvent,
GENERIC_ALL,
NULL,
KernelMode,
&gpEventObject,
&objHandleInfo);
the gpEventObject is a PRKEVENT object, so we can use KeEventXXX and KeWaitForXXX to operate it.
当事件发生时,置信号
KeSetEvent(gpEventObject, 0, FALSE);
当不再需要事件对象时:
case IO_DEREFERENCE_EVENT:
if(gpEventObject)
ObDereferenceObject(gpEventObject);
相关文章推荐
- 总结应用和驱动之间用事件通讯的办法
- 总结应用和驱动之间用事件通讯的办法
- 总结应用和驱动之间用事件通讯的办法(转)
- (转载)总结应用和驱动之间用事件通讯的办法
- 应用和驱动之间用事件通讯的办法(转载)
- 驱动与应用层之间的共享内存通信与事件通知
- 如何在驱动层和应用层之间共享事件?
- 2017年8月10日---阶段性工作总结(事件驱动)
- Workflow Foundation 4.0中的事件驱动流程设计和应用(一)
- file、inode在应用层和驱动层之间的联系
- 利用JavaScript开发事件驱动的Web应用 – node.js简介
- Flex Tree应用总结(一)—数据源配置+选择事件
- Workflow Foundation 4.0中的事件驱动流程设计和应用(二)
- 服务器端 js 利用JavaScript开发事件驱动的Web应用 – node.js简介
- 应用层与驱动层同步事件处理方法
- Windows 驱动与应用通信 之 事件对象
- 总结Ext中的事件应用
- linux总结应用之六 驱动设备块设备中的中断
- Workflow Foundation 4.0中的事件驱动流程设计和应用(三)
- Prism的IEventAggregator事件聚合器, 事件订阅发布, ViewModel之间的通讯