定时器是一个 延时执行 的过程,只执行一次,除非在回调函数中再次调用.
设置定时器
BOOLEAN KeSetTimer (
_Inout_ PKTIMER Timer,//定时器,需要初始化
_In_ LARGE_INTEGER DueTime,//延时执行事件
_In_opt_ PKDPC Dpc//回调函数结构,需要初始化
);
//初始化定时器
KTIMER mytimer;
KeInitializeTimer(&mytimer);
//初始化回调函数结构
VOID KeInitializeDpc (
_Out_ __drv_aliasesMem PRKDPC Dpc,
_In_ PKDEFERRED_ROUTINE DeferredRoutine,//函数指针实际指向 CustomDpc ,这个函数运行在 APC 中断级别,所以不是所有事情都可以做
_In_opt_ __drv_aliasesMem PVOID DeferredContext//提供CustomDpc被调用时提供用户传入的参数
);
VOID CustomDpc(
_In_ struct _KDPC *Dpc,//回调这个函数的KDPC结构
_In_opt_ PVOID DeferredContext,
_In_opt_ PVOID SystemArgument1,
_In_opt_ PVOID SystemArgument2
)
{ ... }
大概是目前语遇到最难的部分了
蓝屏了好几次之后,大概算实现了吧
完整代码:
#include
#include
KTIMER mytimer;
//上下文?
WCHAR userpara[20] = { 0 };
//初始化回调函数结构
KDPC dpc;
//指向自定义回调函数
PKDEFERRED_ROUTINE customdpc;
//计时器的设置
BOOLEAN mysettimer(PKTIMER ptimer, ULONG msec, PKDPC dpc){
//64位的时间间隔,正值表示至1601.1.1算起,负数表示相对当前时间的间隔
LARGE_INTEGER due;
//间隔毫秒数 单位:毫秒
due.QuadPart = -10000 * (LONG)msec;
//设置定时器
return KeSetTimer(ptimer, due, dpc);
}
//停止计时器
VOID myouttimer(PKTIMER ptimer){
KeCancelTimer(ptimer);
}
//定时器函数,回调函数?
VOID mycalltimer(struct _KDPC *Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2){
//用来下次启动延时调用
DbgPrint("misaka: lalala\r\n");
//从新设置定时器,不然只执行一次
mysettimer(&mytimer, 3000, Dpc);
}
VOID DriverUnload(PDRIVER_OBJECT driver){
myouttimer(&mytimer);
DbgPrint("misaka: uninstall driver\r\n");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path){
//初始化定时器
KeInitializeTimer(&mytimer);
//初始化dpc结构
customdpc = mycalltimer;
KeInitializeDpc(&dpc, customdpc, userpara);
mysettimer(&mytimer, 3000, &dpc);
driver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
输出结果:,没3秒输出lalala,但是好像不怎么精确?
misaka: lalala
misaka: lalala
misaka: lalala
misaka: lalala
misaka: uninstall driver