Здравствуйте Как правильно организовать повторяющуюся через какой-то интервал времени операцию в Kernelmode? Есть ли в ядре объекты, наподобие мультимедийных таймеров? То, что я придумал - создать отдельный системный поток, где WaitForSingleObject ожидает, пока таймер, созданный KeInitializeTimerEx, перейдет в сигнальное состояния. Затем этот поток делает нужную операцию и "заводит" таймер снова. Может можно обойтись без лишних потоков (использовать что-то наподобие callback-функции)? Тогда как это можно было бы организовать? Спасибо!
Это наиболее правильный вариант решения задачи. Уточним только, что таймеры, запускаемые через KeSetTimerEx(), она с автовзводом, т.е. они будут просигнализированы независимо от того, закончил ты свою операцию или нет. Другими словами, отсчёт следующего интервала начнётся сразу же по истечении предыдущего. Если же тебе надо вручную взводить таймер для отсчёта следующего интервала (обычно делается именно так), тогда следует воспользоваться KeSetTimer(), либо KeSetTimerEx() без указания периода. ZwCreateTimer(), ZwSetTimer() и так далее, но это недокументировано и проблем тут можно огрести совершенно также: не забываем о ZwCancelTimer().
Еще раз здравствуйте Такая проблема, сколько ни пытался, не удается создать нужную задержку - такое впечатление, что KeSetTimer не переводит таймер в несигнальное состояние. Перепробовал самые разные значения периода - не помогает . Что может быть не не так? Код (Text): #include <ntddk.h> #include <wdm.h> KTIMER keTimer; LARGE_INTEGER PERIOD={(__int64)(10000000)}; int i=0; int exitt = 0; HANDLE hThreadHandle; VOID ThreadRoutine(PVOID arg) { //LARGE_INTEGER i = {1000, 1000} while((!exitt) && (i<25)) { KeWaitForSingleObject(&keTimer, Executive, KernelMode, FALSE, NULL); DbgPrint("Timer tick! %u\n", i); KeSetTimer(&keTimer, PERIOD, NULL); i++; } PsTerminateSystemThread(STATUS_SUCCESS); } VOID DriverUnload(PDRIVER_OBJECT pDriverObject) { KeCancelTimer(&keTimer); exitt=1; } NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING usRegKey) { pDriverObject->DriverUnload = DriverUnload; KeInitializeTimer(&keTimer); KeSetTimer(&keTimer, PERIOD, NULL); PsCreateSystemThread(&hThreadHandle, THREAD_ALL_ACCESS, NULL, NULL, NULL, ThreadRoutine, (PVOID)&keTimer); return STATUS_SUCCESS; }
Читайте внимательно документацию - укажите относительное время. Также почитайте, что вам x64 написал - возможно вам не нужно вручную каждый раз взводить таймер, тогда используйте KeSetTimerEx с ненулевым периодом. Это по логике ближе к мультимедийным таймерам.