Windows内核编程基础篇之定时器

    驱动开发中,与SetTimer()对应的函数是KeSetTimer():

BOOLEAN KeSetTimer(
  _Inout_  PKTIMER       Timer,<span style="white-space:pre">			</span>///---定时器
  _In_     LARGE_INTEGER DueTime,<span style="white-space:pre">		</span>///---延后执行的时间
  _In_opt_ PKDPC         Dpc<span style="white-space:pre">			</span>///---要执行的回调函数结构
);
    定时器Timer 和要 执行的 回调函数 结构Dpc 都必须先初始化,Timer的初始化比如 向下面这样:
KTIMER my_timer;
KeInitalizeTimer(&my_timer);
    Dpc的初始化比较麻烦,因为需要一个回调函数。看看它的原型:

VOID KeInitializeDpc(
  _Out_    PRKDPC             Dpc,
  _In_     PKDEFERRED_ROUTINE DeferredRoutine,
  _In_opt_ PVOID              DeferredContext
);
    PKDEFERRED_ROUTINE 这个函数指针类型所对应的函数类型实际上是这样的:

VOID CustomDpc(
  _In_     struct _KDPC *Dpc,
  _In_opt_ PVOID        DeferredContext,
  _In_opt_ PVOID        SystemArgument1,
  _In_opt_ PVOID        SystemArgument2
)
{ ... }
    我们只关心 DeferredContext。这个参数是KeInitalizeDpc 调用时传入的参数。用来提供给CustomDpc 被调用的时,让用户传入一些参数。

    SystemArgument1 SystemArgument2 ,不需理会。

     注意!!!! CustomDpc  函数将运行在APC中断级,因此并不是所有的事情都可以做。     

    下面的代码摘自<天书夜读-从汇编到Windows内核编程>,封装了定时器的需要全部信息。

typedef struct  MY_TIMER_
{
	KDPC dpc;
	KTIMER timer;
	PKDEFERRED_ROUTINE func; //-回调函数
	PVOID private_context;
} MY_TIMER, *PMY_TIMER;

///--初始化
void MyTimerInit(PMY_TIMER timer, PKDEFERRED_ROUTINE func)
{
	KeInitalizeDpc(&timer->dpc, sf_my_dpc_routine, timer);
	timer->func = func;
	KeInitalizeTimer(&timer->timer);
	return (wd_timer_h)timer;
}

BOOLEAN MyTimerSet(PMY_TIMER timer, ULONG msec, PVOID context)
{
	LARGE_INTEGER due;
	///---msc 是毫秒
	timer->private_context = context;
	return KeSetTimer(&timer->timer, due, &mytimer->dpc);
}

//---停止运行
void MyTimerDestroy(PMY_TIMER timer)
{
	KeCancelTimer(&timer->timer);
}
    
下面是 MyOntimer函数的代码

void MyOnTimer(
	IN struct  _KDPC *Dpc,
	IN PVOID DeferredContext,
	IN PVOID SystemArgument1,
	IN PVOID SystemArgument2 )
{
	///----这传入的是上下文是timer结构,用来下次再启动延迟时调用
	PMY_TIMER timer = (PMY_TIMER)deferredContext;
	///---获得用户上下文
	PVOID my_context = timer->private_context;

	//---这里做 OnTimer总要做的事儿。
	///   .......
	///------再次调用。这里设置的是每1秒调用
	MyTimerSet(timer, 1000, my_context);
}

你可能感兴趣的:(window内核编程,使用定时器)