DPC与定时器

发布于:2025-08-14 ⋅ 阅读:(11) ⋅ 点赞:(0)

简介

本项目主要为使用定时器做的示例,可以把DPC理解为是基于CPU核心的一个定时任务,下面通过使用DPC和定时器来演示在DISPATCH_LEVELPASSIVE_LEVEL分别如何创建定时循环任务。

代码

#include <ntifs.h>

PKDPC kdpc = NULL;
PKDPC kTimer = NULL;

HANDLE hTimer = NULL;

VOID workDpc2(
	_In_ struct _KDPC *Dpc,
	_In_opt_ PVOID DeferredContext,
	_In_opt_ PVOID SystemArgument1,
	_In_opt_ PVOID SystemArgument2
)
{
	static int count = 0;
	DbgPrintEx(77, 0, "[xxxx] %d\r\n", ++count);
	
	KeInitializeTimer(kTimer);
	LARGE_INTEGER inTime = { 0 };

	inTime.QuadPart = -10000 * 1000;
	KeSetTimer(kTimer, inTime, kdpc);
}

VOID workDpc1(
	_In_ struct _KDPC *Dpc,
	_In_opt_ PVOID DeferredContext,
	_In_opt_ PVOID SystemArgument1,
	_In_opt_ PVOID SystemArgument2
)
{
	static int count = 0;
	
	DbgPrintEx(77, 0, "[xxxx] 2 irql = %d,count=%d ,number = %d\r\n", KeGetCurrentIrql(), ++count,KeGetCurrentProcessorNumber());

	//清空DPC内存
	//ExFreePool(Dpc);
}
//
VOID apcTimer(
	_In_ PVOID TimerContext,
	_In_ ULONG TimerLowValue,
	_In_ LONG TimerHighValue
)
{
	static int count = 0;
	DbgPrintEx(77, 0, "[xxxx] 3 irql = %d,count=%d \r\n", KeGetCurrentIrql(), ++count);
}

VOID DriverUnload(PDRIVER_OBJECT pDriver)
{
	if (hTimer)
	{
		ZwCancelTimer(hTimer, NULL);
	}
	/*
	//实验二需要的代码
	KeCancelTimer(kTimer);
	ExFreePool(kTimer);
	ExFreePool(kdpc);
	*/
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg)
{
	LARGE_INTEGER inTime = { 0 };
	inTime.QuadPart = -10000 * 10000;
	kdpc = ExAllocatePool(NonPagedPool, sizeof(KDPC));
	KeInitializeDpc(kdpc, workDpc1, NULL);
	/*
	//实验一:指定在特定核运行DPC
	KeSetTargetProcessorDpc(kdpc, 1);
	KeInsertQueueDpc(kdpc, NULL, NULL);
	*/
	/*
	//实验二:使用内核时钟定时器
	kTimer = ExAllocatePool(NonPagedPool, sizeof(KTIMER));
	//KeInitializeTimer(kTimer);
	//KeSetTimer(kTimer, inTime, kdpc);
	
	//使用扩展内核时钟定时器,使用workDpc1即可实现循环功能
	KeInitializeTimerEx(kTimer, SynchronizationTimer);
	//运行在DISPATCH_LEVEL等级
	KeSetTimerEx(kTimer, inTime, 1000, kdpc);
	*/

	
	//实验三:使用应用层时钟定时器,运行在PASSIVE_LEVEL等级
	NTSTATUS status = ZwCreateTimer(&hTimer, PROCESS_ALL_ACCESS, NULL, SynchronizationTimer);
	if (NT_SUCCESS(status))
	{
		ZwSetTimer(hTimer, &inTime, apcTimer, NULL, FALSE, 1000, NULL);
	}
	

	pDriver->DriverUnload = DriverUnload;
	return STATUS_SUCCESS;
}

参考资料

火哥五期


网站公告

今日签到

点亮在社区的每一天
去签到