利用同步事件实现驱动主动通知应用

一、同步事件

对数据结构 KEVENT 进行初始化、等待和设置,实现多个线程之间的同步。例如,希望主线程 A 在等待线程 B 完成某事后才能做某事,可在主线程 A 中配置KEVENT事件等待,在线程B中完成操作后,对正在等待的KEVENT事件进行设置即可。

实例如下:

// 定义一个事件
KEVENT event;
// 事件初始化
KeInitializeEvent(&event, SynchronizationEvent, FALSE);

<!-- more --> 

// ......

// 主线程A中:
// 在此处等待 KEVENT 事件。若该事件没有被设置,则会一直阻塞在这里继续等待。
KeWaitForSingleObject(&event, Executive, KernelMode, 0, 0);

// ......

// 线程B中:
// 在此处设置 KEVENT 事件。一旦设置了此事件,前面等待的地方将继续执行。
KeSetEvent(&event, 0, TRUE);

几个函数的原型如下:

VOID
KeInitializeEvent(
  IN PRKEVENT Event,  // 所定义的事件
  IN EVENT_TYPE Type,   // 事件类型,分为 SynchronizationEvent 和 NotificationEvent 两种
  IN BOOLEAN State      // 初始化状态,一般设置为 FALSE,即等待者需要等待设置后才能通过。
);
LONG
KeSetEvent(
  IN PREVENT event,     // 要设置的事件
  IN KPRIORITY Increment, // 提升优先权
  IN BOOLEAN Wait         // 表示是否后面马上紧跟一个 KeWaitSingleObject 来等待这个时间,一般设置为 TRUE(事件初始化之后,一般就要开始等待了)。
);

二、驱动主动通知应用的实现方式

应用程序:开一个线程,在线程内向驱动程序发送 IOCTL 请求,并等待 IOCTL 返回;主线程继续执行其他操作。

驱动程序:在 IOCTL 分发函数(DeviceIoControl)中等待一个同步事件 event,当驱动程序中其他地方设置(Set)了该同步事件后,触发对之前在等待的 IOCTL 请求的响应。

三、测试结果

测试结果

可以看出,若为串行操作,应用向驱动发送 IOCTL 请求①,在驱动等待为该请求服务的数据到来的期间,应用不再发送其他 IOCTL 请求,这种情况下可以正常响应,相当于阻塞了 IOCTL 通道。若为并行操作,应用向驱动发送 IOCTL 请求②,在驱动等待为该请求服务的数据到来期间,应用又向驱动发送了 IOCTL 请求③,经测试,驱动收不到该请求,再次证明 IOCTL 通道被阻塞。


参考资料:

  1. 《Windows内核安全与驱动开发》4.4.3 & 5.3
  2. Microsoft Doc - Windows Driver: Defining and Using an Event Object

猜你喜欢

转载自blog.csdn.net/Hooooxz/article/details/80060418
今日推荐