博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
驱动自定义回调例程
阅读量:6967 次
发布时间:2019-06-27

本文共 4585 字,大约阅读时间需要 15 分钟。

前言:

熟悉驱动开发的人们都知道,在windows系统内,系统自动提供许多回调函数,比如,进程回调,模块回调,注册表回调,等等。但windows也提供了一些函数使得开发者也可以自定义回调。利用回调也可以实现驱动模块间的通讯。相关函数如下:

//创建回调或者打开回调NTSTATUSExCreateCallback (    _Outptr_ PCALLBACK_OBJECT *CallbackObject,    _In_ POBJECT_ATTRIBUTES ObjectAttributes,    _In_ BOOLEAN Create,    _In_ BOOLEAN AllowMultipleCallbacks    );//注册回调PVOIDExRegisterCallback (    _Inout_ PCALLBACK_OBJECT CallbackObject,    _In_ PCALLBACK_FUNCTION CallbackFunction,    _In_opt_ PVOID CallbackContext    );//回调通知VOIDExNotifyCallback (    _In_ PVOID CallbackObject,    _In_opt_ PVOID Argument1,    _In_opt_ PVOID Argument2    );//回调例程VOID CALLBACK_FUNC(	_In_ PVOID CallbackContext,	_In_ PVOID Argument1,	_In_ PVOID Argument2);

 相关函数用法,这里不做多介绍,自行查阅msdn学习。

这里写一个测试例子,分为sender和receiver,sender注册回调后创建一个线程,定时的通知receiver。
receiver打开回调,注册回调,一旦接收到通知后,把数据打印出来。

//sender#include 
#define CALLBACKNAME L"\\Callback\\driverStart"VOID UnloadDriver(PDRIVER_OBJECT driver);VOID MyThread(PVOID context);BOOLEAN gbSuccess = 0;//线程句柄HANDLE ghThread = NULL;//回调指针PCALLBACK_OBJECT gpObjCallback = NULL;KEVENT gEvent;NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING registry){ UNREFERENCED_PARAMETER(registry); NTSTATUS status; OBJECT_ATTRIBUTES objAttri; driver->DriverUnload = UnloadDriver; //初始化通知事件 KeInitializeEvent(&gEvent, SynchronizationEvent, FALSE); UNICODE_STRING uniCallbackName = RTL_CONSTANT_STRING(CALLBACKNAME); //这里必须指定OBJ_PERMANENT属性,否则会失败 InitializeObjectAttributes(&objAttri, &uniCallbackName, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, NULL); //注册回调对象 status = ExCreateCallback(&gpObjCallback, &objAttri, TRUE, TRUE); if (!NT_SUCCESS(status)) { KdPrint(("[sysTest] ExCreateCallback error code:(0x%x).\n", status)); return status; } //注册成功 gbSuccess = 1; //创建线程,定期发送 ExNotifyCallback status = PsCreateSystemThread(&ghThread, THREAD_ALL_ACCESS, NULL, NULL, NULL, MyThread, NULL); if (!NT_SUCCESS(status)) { KdPrint(("[sysTest] PsCreateSystemThread error code:(0x%x).\n", status)); return status; } status = STATUS_SUCCESS; return status;}VOID MyThread(PVOID context){ UNREFERENCED_PARAMETER(context); NTSTATUS status; ULONG type = 1; //ULONG ulData = 0; PCHAR ulData = "hello"; LARGE_INTEGER tick = { 0 }; //时间间隔是定位2秒 tick = RtlConvertLongToLargeInteger(-10 * 1000 * 1000 * 2); while (tick.QuadPart != 0) { //等待3秒 status = KeWaitForSingleObject(&gEvent, Executive, KernelMode, FALSE, &tick); if (STATUS_TIMEOUT != status) { break; } //通知 ExNotifyCallback(gpObjCallback, &type, ulData); KdPrint(("[sysTest] send.\n")); } KdPrint(("[sysTest] thread ended.\n")); PsTerminateSystemThread(STATUS_SUCCESS);}VOID UnloadDriver(PDRIVER_OBJECT driver){ UNREFERENCED_PARAMETER(driver); KeSetEvent(&gEvent, 0, TRUE); if (NULL != ghThread) { ZwWaitForSingleObject(ghThread, FALSE, NULL); ZwClose(ghThread); ghThread = NULL; } if (gbSuccess) { ObDereferenceObject(gpObjCallback); } KdPrint(("[sysTest] driver stoped.\n"));}//receiver#include
#define CALLBACKNAME L"\\Callback\\driverStart"VOID UnloadDriver(_In_ PDRIVER_OBJECT driver);VOID CALLBACK_FUNC( _In_ PVOID CallbackContext, _In_ PVOID Argument1, _In_ PVOID Argument2);PCALLBACK_OBJECT gpObjCallback = NULL;BOOLEAN gbSuccess = 0;PVOID gpCookie = NULL;NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING registry){ UNREFERENCED_PARAMETER(registry); driver->DriverUnload = UnloadDriver; NTSTATUS status; UNICODE_STRING uniName = RTL_CONSTANT_STRING(CALLBACKNAME); OBJECT_ATTRIBUTES objAttri; InitializeObjectAttributes(&objAttri, &uniName, OBJ_CASE_INSENSITIVE, NULL, NULL); status = ExCreateCallback(&gpObjCallback, &objAttri, FALSE, TRUE); if (!NT_SUCCESS(status)) { KdPrint(("[sysRecv1] ExCreateCallback error code:(0x%x).\n", status)); return status; } gbSuccess = 1; gpCookie = ExRegisterCallback(gpObjCallback, CALLBACK_FUNC, NULL); if (NULL == gpCookie) { KdPrint(("[sysRecv1] ExRegisterCallback error.\n")); return STATUS_UNSUCCESSFUL; } status = STATUS_SUCCESS; return status;}VOID UnloadDriver(_In_ PDRIVER_OBJECT driver){ UNREFERENCED_PARAMETER(driver); if (NULL != gpCookie) { ExUnregisterCallback(gpCookie); } KdPrint(("[sysRecv1] Drvier unloaded.\n"));}VOID CALLBACK_FUNC( _In_ PVOID CallbackContext, _In_ PVOID Argument1, _In_ PVOID Argument2){ UNREFERENCED_PARAMETER(CallbackContext); ULONG ulType; PCHAR ulValue; ulType = *(ULONG*)Argument1; ulValue = (PCHAR)Argument2; KdPrint(("[sysRecv1]:get notify ulType:(%d)\tulValue:(%s)\n", ulType, ulValue));}

 结果如下:

 从结果分析可知是正确的,当没有回调注册时,即使发送通知其它驱动也收不到任何通知,当注册回调以后,每当发送通知都可以接收到的消息。

转载于:https://www.cnblogs.com/priarieNew/p/9759473.html

你可能感兴趣的文章
Python标准库_ sys,random,time
查看>>
GP通过外部表装载数据时遇到ERROR:extra data after last expected column解决方法
查看>>
C#开发中碰到的问题------Uncaught TypeError: Cannot read property 'style' of undefined
查看>>
Android 网络编程
查看>>
正则表达式
查看>>
Tomcat & SVN
查看>>
推荐系统学习03-SVDFeature
查看>>
mysql启动和关闭外键约束的方法
查看>>
安装 Docker <一>
查看>>
C#中的Dictionary字典类介绍
查看>>
PHP 设计模式 笔记与总结(5)PHP 魔术方法的使用
查看>>
Microsoft Visual Studio 下载转帖
查看>>
证券交易买进卖出手续费公式
查看>>
SQL Server存储(6/8) :理解DCM页
查看>>
epoll使用具体解释(精髓)
查看>>
毕业季-回去体检
查看>>
WordPress前台后台页面打开慢的解决方法
查看>>
【m从翻译os文章】写日志禁令Sqlnet.log和Listener.log
查看>>
GRUB启动管理器
查看>>
Maven最佳实践:Maven仓库
查看>>