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


Исполняемый код драйвера - часть 9


/p>

//========================================================================= // Процедура обслуживания прерывания: // BOOLEAN Isr (IN PKINTERRUPT pInterruptObject, IN PVOID pServiceContext ) { PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION) pServiceContext; PDEVICE_OBJECT pDevObj = pDevExt-&#62pDevice; #if DBG==1 KIRQL currentIrql = KeGetCurrentIrql(); DbgPrint("LPTPORT: In Isr procedure, ISR_Irql=%d\n", currentIrql); #endif //=============================================================== // Строго говоря, следовало бы проверить, имело ли место // прерывание и наше ли это прерывание: // UCHAR status = ReadStatusRegister( pDevExt ); // if( status & 0x04 ) return FALSE; // прерывания не было // Однако в силу упомянутых накладок с использованием бита SR.2, // не проверяем это вовсе, делая допущение, что если Isr получила // управление, то прерывание - наше. //=============================================================== // Общей практикой является блокирование поступления прерываний // в этом месте:

// WriteControlRegister( pDevExt, CR_DEFAULT);

// Однако, мы не будем этого делать, чтобы не испортить данные, // находящиеся сейчас в Status Register. Полагаем, что кроме // нашего драйвера такие прерывания никто не генерирует, а драйвер // защищен тем, что Write запросы отвергаются до полного переноса // данных. //================================================================ // Планируем вызов DPC процедуры для обработки прерывания позднее // IoRequestDpc( pDevObj, // &#60- указание на объект устройства здесь // однозначно определяет, какая процедура // DPC (здесь - DpcForIsr) будет вызвана NULL, // &#60- Arg1 in DpcForIsr NULL ); // &#60- Arg2 in DpcForIsr

return TRUE; // нормальное завершение обработки прерывания } //========================================================================= // Код, который посылает в порт данные, вызывающие (при наличии // CheckIt заглушки) сигнал прерывания: // VOID ForceInterrupt( PDEVICE_EXTENSION pDevExt, UCHAR bits ) { // Генерируем сигнал прерывания WriteControlRegister( pDevExt, bits | CR_INT_ENB | CR_DEFAULT ); KeStallExecutionProcessor(50); // Удерживаем состояние 50 мкс // Импульс ACK# WriteControlRegister( pDevExt, bits | CR_INT_ENB | CR_NOT_RST | CR_DEFAULT ); KeStallExecutionProcessor(50); // Удерживаем состояние 50 мкс // Удерживая информационные биты, снимаем импульс ACK# WriteControlRegister( pDevExt, bits | CR_INT_ENB | CR_DEFAULT ); } //========================================================================= // Функция DoNextTransfer безопасно (от вмешательства кода прерывания, ISR // функции) записывает данные в параллельный порт: // BOOLEAN DoNextTransfer ( IN PVOID pContext ) {




Начало  Назад  Вперед