总结应用和驱动之间用事件通讯的办法

 总结应用和驱动之间用事件通讯的办法
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); 

应用中:

会看到,点击MessageBox OK后ppppp的确继续执行了。

3.在应用中创建事件,然后通过ioctl传给驱动,驱动中ObReferenceObjectByHandle来引用该事件对象。
这样应用和驱动中都可以检查和修改事件状态。
应用程序:

if ( ! DeviceIoControl(hDevice,IOCTL_ ****** , 0 , 0 , & Handle, 4 , & Bytes, 0 )) 
MessageBox(
" DeviceIo Error! " ); 
else
    wsprintf(str,
" %x,%x,%x " ,hDevice,Bytes,Handle); 
    MessageBox(str); 
    
if ( ! SetEvent((HANDLE)Handle)) 
        ...... 

 

 

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); 


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值