驱动自定义回调例程

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

//创建回调或者打开回调
NTSTATUS
ExCreateCallback (
    _Outptr_ PCALLBACK_OBJECT *CallbackObject,
    _In_ POBJECT_ATTRIBUTES ObjectAttributes,
    _In_ BOOLEAN Create,
    _In_ BOOLEAN AllowMultipleCallbacks
    );

//注册回调

PVOID
ExRegisterCallback (
    _Inout_ PCALLBACK_OBJECT CallbackObject,
    _In_ PCALLBACK_FUNCTION CallbackFunction,
    _In_opt_ PVOID CallbackContext
    );

//回调通知

VOID
ExNotifyCallback (
    _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 <ntifs.h>


#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 <ntifs.h>

#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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值