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

叁歲伎倆 2022-08-04 14:53 319阅读 0赞

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

  1. BOOLEAN KeSetTimer(
  2. _Inout_ PKTIMER Timer,<span style="white-space:pre"> </span>///---定时器
  3. _In_ LARGE_INTEGER DueTime,<span style="white-space:pre"> </span>///---延后执行的时间
  4. _In_opt_ PKDPC Dpc<span style="white-space:pre"> </span>///---要执行的回调函数结构
  5. );

定时器Timer 和要 执行的 回调函数 结构Dpc 都必须先初始化,Timer的初始化比如 向下面这样:

  1. KTIMER my_timer;
  2. KeInitalizeTimer(&my_timer);

Dpc的初始化比较麻烦,因为需要一个回调函数。看看它的原型:

  1. VOID KeInitializeDpc(
  2. _Out_ PRKDPC Dpc,
  3. _In_ PKDEFERRED_ROUTINE DeferredRoutine,
  4. _In_opt_ PVOID DeferredContext
  5. );

PKDEFERRED_ROUTINE 这个函数指针类型所对应的函数类型实际上是这样的:

  1. VOID CustomDpc(
  2. _In_ struct _KDPC *Dpc,
  3. _In_opt_ PVOID DeferredContext,
  4. _In_opt_ PVOID SystemArgument1,
  5. _In_opt_ PVOID SystemArgument2
  6. )
  7. { ... }

我们只关心 DeferredContext。这个参数是KeInitalizeDpc 调用时传入的参数。用来提供给CustomDpc 被调用的时,让用户传入一些参数。

SystemArgument1 和 SystemArgument2 ,不需理会。

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

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

  1. typedef struct MY_TIMER_
  2. {
  3. KDPC dpc;
  4. KTIMER timer;
  5. PKDEFERRED_ROUTINE func; //-回调函数
  6. PVOID private_context;
  7. } MY_TIMER, *PMY_TIMER;
  8. ///--初始化
  9. void MyTimerInit(PMY_TIMER timer, PKDEFERRED_ROUTINE func)
  10. {
  11. KeInitalizeDpc(&timer->dpc, sf_my_dpc_routine, timer);
  12. timer->func = func;
  13. KeInitalizeTimer(&timer->timer);
  14. return (wd_timer_h)timer;
  15. }
  16. BOOLEAN MyTimerSet(PMY_TIMER timer, ULONG msec, PVOID context)
  17. {
  18. LARGE_INTEGER due;
  19. ///---msc 是毫秒
  20. timer->private_context = context;
  21. return KeSetTimer(&timer->timer, due, &mytimer->dpc);
  22. }
  23. //---停止运行
  24. void MyTimerDestroy(PMY_TIMER timer)
  25. {
  26. KeCancelTimer(&timer->timer);
  27. }

下面是 MyOntimer函数的代码

  1. void MyOnTimer(
  2. IN struct _KDPC *Dpc,
  3. IN PVOID DeferredContext,
  4. IN PVOID SystemArgument1,
  5. IN PVOID SystemArgument2 )
  6. {
  7. ///----这传入的是上下文是timer结构,用来下次再启动延迟时调用
  8. PMY_TIMER timer = (PMY_TIMER)deferredContext;
  9. ///---获得用户上下文
  10. PVOID my_context = timer->private_context;
  11. //---这里做 OnTimer总要做的事儿。
  12. /// .......
  13. ///------再次调用。这里设置的是每1秒调用
  14. MyTimerSet(timer, 1000, my_context);
  15. }

发表评论

表情:
评论列表 (有 0 条评论,319人围观)

还没有评论,来说两句吧...

相关阅读