定时器

c

Posted by YiMiTuMi on March 18, 2022

封装定时器

参考:天书夜读_从汇编语言到Windows内核编程

结构体:

typedef struct _TIMER_INFO  //定时器结构体
{
	KDPC dpc;
	KTIMER timer;
	PKDEFERRED_ROUTINE timerFunc;
	PVOID privateInfo;  //用来传递数据

} TIMER_INFO, * PTIMER_INFO;

初始化一个定时器:

void TimerInit(PTIMER_INFO timerInfo, PKDEFERRED_ROUTINE timerFunc)
{
	//初始化DPC
	KeInitializeDpc(&(timerInfo->dpc), timerFunc, (PVOID)timerInfo);
	timerInfo->timerFunc = timerFunc;

	//初始化定时器
	KeInitializeTimer(&(timerInfo->timer));
}

设置定时器:

这个定时器要一直通过循环调用这个来实现:

BOOLEAN TimerSet(PTIMER_INFO timerInfo, ULONG msec, PVOID privateInfo)
{
	LARGE_INTEGER due;
	BOOLEAN bRet = FALSE;

	//转换时间
	due.QuadPart = -10000 * msec;

	//设置上下文
	timerInfo->privateInfo = privateInfo;
	
	//设置定时器
	bRet = KeSetTimer(&(timerInfo->timer), due, &(timerInfo->dpc));

	return bRet;
}

停止定时器:

void TimerDestroy(PTIMER_INFO timerInfo)
{
	KeCancelTimer(&(timerInfo->timer));
}

使用例子

定义一个定时器的回调函数格式都是这样的:

//函数名字可以修改
void OnTimer(IN struct _KDPC* Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2);

例子:

void OnTimer(IN struct _KDPC* Dpc,
	IN PVOID DeferredContext,
	IN PVOID SystemArgument1,
	IN PVOID SystemArgument2)
{
	PTIMER_INFO timer = (PTIMER_INFO)DeferredContext;
	PVOID privateInfo = timer->privateInfo;

	DbgPrint("过去1秒! \n");
	
	//打印我传入的参数
	DbgPrint("CurrentTime  = %ws \n", (PWCHAR)privateInfo);


	//再次调用,
	TimerSet(timer, 1000, privateInfo);
	
	//用于测试,再次掉用 TimerSet 是否会导致和递归一样内存一直被占用没有通过函数结束释放
	DbgPrint("过去2秒! \n");
}

//一个全局的定时器
PTIMER_INFO g_TimeTimerInfo;

//驱动入口函数
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg) //返回一个地址、返回驱动被注册到注册表的某个地方
{
	DbgPrint("pdriver = %wZ, , %x\n", pReg, pDriver);
	
	//随便传个参数
	WCHAR szTime[32] = L"1111";

	//设定定时器
	g_TimeTimerInfo = (PTIMER_INFO)ExAllocatePool(PagedPool, sizeof(TIMER_INFO));
	RtlZeroMemory(g_TimeTimerInfo, sizeof(TIMER_INFO));
	TimerInit(g_TimeTimerInfo, OnTimer);
	TimerSet(g_TimeTimerInfo, 1000, (PVOID)szTime); //1000毫秒


	return STATUS_SUCCESS;
}

薰衣草 – 等待爱情