Повторяющаяся операция в драйвере - таймер?

Тема в разделе "WASM.NT.KERNEL", создана пользователем simnet_, 28 дек 2009.

  1. simnet_

    simnet_ New Member

    Публикаций:
    0
    Регистрация:
    18 дек 2007
    Сообщения:
    109
    Здравствуйте
    Как правильно организовать повторяющуюся через какой-то интервал времени операцию в Kernelmode?
    Есть ли в ядре объекты, наподобие мультимедийных таймеров?
    То, что я придумал - создать отдельный системный поток, где WaitForSingleObject ожидает, пока таймер, созданный KeInitializeTimerEx, перейдет в сигнальное состояния. Затем этот поток делает нужную операцию и "заводит" таймер снова.
    Может можно обойтись без лишних потоков (использовать что-то наподобие callback-функции)? Тогда как это можно было бы организовать?
    Спасибо!
     
  2. Partner

    Partner Павел

    Публикаций:
    0
    Регистрация:
    28 фев 2008
    Сообщения:
    917
    Адрес:
    Los Angeles
    SetWaitableTimer c CompletionRoutine
     
  3. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Это наиболее правильный вариант решения задачи. Уточним только, что таймеры, запускаемые через KeSetTimerEx(), она с автовзводом, т.е. они будут просигнализированы независимо от того, закончил ты свою операцию или нет. Другими словами, отсчёт следующего интервала начнётся сразу же по истечении предыдущего. Если же тебе надо вручную взводить таймер для отсчёта следующего интервала (обычно делается именно так), тогда следует воспользоваться KeSetTimer(), либо KeSetTimerEx() без указания периода.

    ZwCreateTimer(), ZwSetTimer() и так далее, но это недокументировано и проблем тут можно огрести совершенно также: не забываем о ZwCancelTimer().
     
  4. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Речь о режиме ядра.
     
  5. Partner

    Partner Павел

    Публикаций:
    0
    Регистрация:
    28 фев 2008
    Сообщения:
    917
    Адрес:
    Los Angeles
    Сорри, был невнимателен.
     
  6. simnet_

    simnet_ New Member

    Публикаций:
    0
    Регистрация:
    18 дек 2007
    Сообщения:
    109
    x64
    Спасибо
     
  7. simnet_

    simnet_ New Member

    Публикаций:
    0
    Регистрация:
    18 дек 2007
    Сообщения:
    109
    Еще раз здравствуйте :)
    Такая проблема, сколько ни пытался, не удается создать нужную задержку - такое впечатление, что KeSetTimer не переводит таймер в несигнальное состояние. Перепробовал самые разные значения периода - не помогает :dntknw:. Что может быть не не так?
    Код (Text):
    1. #include <ntddk.h>
    2. #include <wdm.h>
    3.  
    4.     KTIMER keTimer;
    5.     LARGE_INTEGER PERIOD={(__int64)(10000000)};
    6.     int i=0;
    7.     int exitt = 0;
    8.  
    9.     HANDLE hThreadHandle;
    10.  
    11. VOID ThreadRoutine(PVOID arg) {
    12.     //LARGE_INTEGER i = {1000, 1000}
    13.     while((!exitt) && (i<25)) {
    14.         KeWaitForSingleObject(&keTimer, Executive, KernelMode, FALSE, NULL);
    15.         DbgPrint("Timer tick! %u\n", i);
    16.         KeSetTimer(&keTimer, PERIOD, NULL);
    17.         i++;
    18.     }
    19.     PsTerminateSystemThread(STATUS_SUCCESS);
    20. }
    21.  
    22.  
    23. VOID DriverUnload(PDRIVER_OBJECT pDriverObject) {
    24.     KeCancelTimer(&keTimer);
    25.     exitt=1;
    26. }
    27.  
    28. NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING usRegKey) {
    29.     pDriverObject->DriverUnload = DriverUnload;
    30.     KeInitializeTimer(&keTimer);
    31.     KeSetTimer(&keTimer, PERIOD, NULL);
    32.     PsCreateSystemThread(&hThreadHandle, THREAD_ALL_ACCESS, NULL, NULL, NULL, ThreadRoutine, (PVOID)&keTimer);
    33.     return STATUS_SUCCESS;
    34. }
     
  8. AntiFreeze

    AntiFreeze Дмитрий

    Публикаций:
    0
    Регистрация:
    26 июн 2008
    Сообщения:
    65
    Читайте внимательно документацию - укажите относительное время.
    Также почитайте, что вам x64 написал - возможно вам не нужно вручную каждый раз взводить таймер, тогда используйте KeSetTimerEx с ненулевым периодом. Это по логике ближе к мультимедийным таймерам.