驱动程序与驱动程序交互事件对象

最近看张帆的《windows驱动技术开发详解》,看了一些东西通过写一些Demo来加深理解,这里把自己学习的东西和写的Demo记录下来,如有不妥,还请批评指正。

8.5.5 驱动程序与驱动程序交互事件对象

当我们在Ring0与Ring0交互的时候,类似于Ring0A与RingB各自的派遣函数要同步则我们要在这两者之间进行交互事件对象。

这里的关键是,A与B的事件对象的问题,即如何让A获得B的事件对象,书中的方法是让B创建一个有“名字”的事件对象,让A根据这个“名字”来找事件对象的指针,

在前面的章节中曾经提过IoCreateNotificationEvent和IoCreateSynchronizationEvent函数,前者创建“通知事件”对象,后者创建“同步事件”对象。主要的区别在8.5.3 内核模式下的事件对象中有讲,即如果创建的是通知事件,那么当事件对象变为激发态,程序员需要手动将其改为未激发态,如果创建的是同步事件,那么当事件处于激发态的时候,如果遇到KeWaitForxxxxx的函数的时候,事件对象则自动变回未激发态(这里有Demo,之后再说,虽然有一些问题和书上还有出入等解决在发出来)。

这里我们取名字为:

#define EVENT_NAME L"\BaseNamedObjects\ServerKernelEvent"

我们都用UNICODE_STRING来描述内核事件对象的名字,然后使用IoCreateNotificationEvent,这个函数:如果内核中不存在指定名称的内核事件对象则创建该名称的内核事件对象,如果内核中存在指定名称的内核事件对象,则打开这个内核事件对象。

测试的话,x86,x64都通过

先上Server

然后上Client

 最后记得要将两个驱动都卸载

 以上

server

1 #include <ntifs.h>
2 
3 #define EVENT_NAME  L"\BaseNamedObjects\ServerKernelEvent"
4 
5 
6 void ThreadProc(PVOID ParameterData);
7 
8 
9 VOID DriverUnload(PDRIVER_OBJECT DriverObject);
 1 #include "Ring0_Server.h"
 2 
 3 PKEVENT __KEvent;
 4 HANDLE  __EventHandle;
 5 
 6 NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath)
 7 {
 8     NTSTATUS Status = STATUS_SUCCESS;
 9     PDEVICE_OBJECT  DeviceObject = NULL;
10     UNICODE_STRING EventName;
11     HANDLE ThreadHandle = NULL;
12     CLIENT_ID ClientID = { 0 };
13     DbgPrint("DriverEntry()
");
14 
15     DriverObject->DriverUnload = DriverUnload;
16     
17     RtlInitUnicodeString(&EventName, EVENT_NAME);
18 
19     __KEvent = IoCreateNotificationEvent(
20         &EventName,
21         &__EventHandle
22     );//如果内核中不存在指定名称的内核事件对象则创建该名称的内核事件对象
23     //如果内核中存在指定名称的内核事件对象,则打开这个内核事件对象
24     
25     KeResetEvent(__KEvent);
26     
27     Status = PsCreateSystemThread(
28         &ThreadHandle, 
29         0, 
30         NULL, 
31         NtCurrentProcess(),
32         &ClientID,
33         (PKSTART_ROUTINE)ThreadProc, 
34         NULL);
35 
36     return Status;
37 }
38 
39 void ThreadProc(PVOID ParameterData)
40 {
41     NTSTATUS Status;
42 
43     KeWaitForSingleObject(
44         __KEvent, 
45         Executive, 
46         KernelMode, 
47         FALSE, 
48         NULL
49     );
50     
51     DbgPrint("ThreadProcedure() Exit
");
52     PsTerminateSystemThread(STATUS_SUCCESS);
53 }
54 
55 
56 VOID DriverUnload(PDRIVER_OBJECT DriverObject)
57 {
58     DbgPrint("DriverUnload()
");
59     //记得关闭
60     if (__EventHandle != NULL)
61     {
62         KeClearEvent(__KEvent);
63 
64         ZwClose(__EventHandle);
65 
66         __EventHandle = NULL;
67         __KEvent = NULL;
68     }
69 }
Ring0_Server.c

//client

1 #include <ntifs.h>
2 
3 #define EVENT_NAME  L"\BaseNamedObjects\ServerKernelEvent"
4 
5 
6 
7 VOID DriverUnload(PDRIVER_OBJECT DriverObject);
Ring0_Client.h
 1 #include "Ring0_Client.h"
 2 
 3 PKEVENT __KEvent;
 4 HANDLE  __EventHandle;
 5 
 6 
 7 NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath)
 8 {
 9     NTSTATUS Status = STATUS_SUCCESS;
10     PDEVICE_OBJECT  DeviceObject = NULL;
11     UNICODE_STRING  EventName;
12     DbgPrint("DriverEntry()
");
13     DriverObject->DriverUnload = DriverUnload;
14 
15     RtlInitUnicodeString(&EventName, EVENT_NAME);
16     __KEvent = IoCreateNotificationEvent(
17         &EventName, 
18         &__EventHandle
19     );    
20     KeSetEvent(__KEvent, IO_NO_INCREMENT, FALSE);
21     return Status;
22 }
23 
24 
25 VOID DriverUnload(PDRIVER_OBJECT DriverObject)
26 {
27     DbgPrint("DriverUnload()
");
28 
29     if (__EventHandle != NULL)
30     {
31         KeClearEvent(__KEvent);
32         ZwClose(__EventHandle);
33         __EventHandle = NULL;
34         __KEvent = NULL;
35     }
36 
37 }
Ring0_Client.c
原文地址:https://www.cnblogs.com/1228073191Blog/p/7342021.html