Программирование драйверов Windows




Таймеры и их использование - часть 10


if( !NT_SUCCESS(status) ) { DbgPrint("-Example- Error in KeWaitForSingleObject."); DbgPrint("-Example- STATUS eq %x.",status); } else { DbgPrint("-Example- KeWaitForSingleObject OK."); }

// Считываем состояние таймера после окончания ожидания: if(KeReadStateTimer(pTimer)) { DbgPrint("-Example- KeReadStateTimer returns TRUE (after)."); } else { DbgPrint("-Example- KeReadStateTimer returns FALSE (after)."); } break; } case IOCTL_CANCEL_TIMER: // Удаляем объект таймера и объект DPC { BOOLEAN result = KeCancelTimer(pTimer); if(result) { DbgPrint("-Example- KeCancelTimer returns TRUE."); } else { DbgPrint("-Example- KeCancelTimer returns FALSE."); } ExFreePool(pTimer); ExFreePool(pDpcObject); pTimer=NULL; break; }

Ниже приводится фрагмент кода пользовательского приложения, которое тестирует рассмотренный выше код драйвера.

DWORD BytesReturned; unsigned long ioctlCode=IOCTL_PRINT_DEBUG_MESS; if( !DeviceIoControl( hHandle, ioctlCode, NULL, 0, // Input NULL, 0, // Output &BytesReturned, NULL ) ) { printf( "Error in IOCTL_PRINT_DEBUG_MESS!" ); } // Запуская данное приложение в отладчике в пошаговом режиме, // здесь сделаем паузу, давая отработать несколько раз DPC // процедуре, шаги с 216 по 241 в распечатке ниже. // Интервал вызовов DPC процедуры составляет 5 секунд. ioctlCode=IOCTL_CHANGE_IRQL; if( !DeviceIoControl( hHandle, ioctlCode, NULL, 0, // Input NULL, 0, // Output &BytesReturned, NULL ) ) { printf( "Error in IOCTL_CHANGE_IRQL!" ); }

Функция MyDeferredRoutine начинает запускаться только после перехода таймера в сигнальное состояние. Период ее запусков определен значением третьего параметра в вызове KeSetTimerEx.

Ниже приводится распечатка log-файла сообщений, выводимых макросами DbgPrint

в окно программы DebugView. Вторая колонка &#8212 отсчеты в секундах.

00000010 0.00241344 -Example- IOCTL_TEST_TIMER.
00000011 0.00243578 -Example- KeStallExecutionProcessor.shortCycles=0.



Содержание  Назад  Вперед