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



Простейший драйвер для работы с прерываниями - часть 2


При обработке прерывания Isr функция планирует вызов DpcForIsr процедуры, которая получает управление, читает данные из регистра состояния, помещает их в буфер для хранения и запускает новый перенос (с генерацией прерывания).

Таким образом, начиная с момента первой генерации прерывания до окончания всех данных, поступивших от клиента в одном запросе на запись, перенос половины первого байта продолжается переносом половины второго байта и т.п. По окончании передачи половины последнего байта и прохождении последнего прерывания, процедура DpcForIsr, получив управление, выполняет последнее чтение из порта, но уже не вызывает DoNextTransfer. Перенос данных закончен фактически. Формально же обработка запроса от вызова WriteFile могла бы закончиться раньше &#8212 после запуска DoNextTransfer (разумеется, с подачи KeSynchronizeExecution) рабочая функция драйвера DispatchWrite (обработчик запросов от WriteFile) сразу же пытается завершить обработку IRP пакета, поскольку ее основная задача &#8212 заполнить внутренний буфер и стартовать первый перенос. Однако в том случае, когда заглушка на месте, в работу поочередно вступают высокоприоритетные фрагменты кода (Isr, DpcForIsr, функции, вызываемые с подачи KeSynchronizeExecution), что более вероятно &#8212 перенос данных завершится еще до выхода из DispatchWrite. Лишь при отсутствии заглушки CheckIt прерывания не влияют на работу драйвера. Запуская тестовое приложение в отсутствие заглушки, можем наблюдать, что процедура DispatchWrite завершается, а при входе в DispatchRead драйвер видит, что предыдущий перенос не завершен (нет заглушки &#8212 нет способа генерировать прерывания и передавать данные), о чем драйвер и сообщает клиенту кодом ошибки 170, который программой ErrLook расшифровывается как "Требуемый ресурс занят". Такое же сообщение можно увидеть и при повторных запусках тестового приложения (если заглушка CheckIt отсутствует).




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