Выполнения кода процедуры DpcForIsr
В ответ на выполненный ISR процедурой вызов IoRequestDpc, принадлежащая данному драйверу процедура DpcForIsr добавляется в очередь DPC объектов (DPC dispatch queue). Когда значение процессорного IRQL падает ниже DISPATCH_LEVEL, диспетчер процедур обработки отложенных вызовов выполняет вызов DpcForIsr данного драйвера. Процедура DpcForIsr выполняется на уровне DISPATCH_LEVEL, что означает: она не должна работать с адресами страничной памяти.
Диспетчер ввода/вывода игнорирует множественные вызовы IoRequestDpc
для данного объекта устройства до начала выполнения DpcForIsr. Попытки повторно поместить объект DPC в очередь отклоняются. Это является нормальным отношением ко всем DPC объектам. В случае если логика работы драйвера такова, что он может выдавать перекрывающиеся DPC запросы для одного и того же устройства, и их следует учитывать, то такой драйвер должен реализовать собственную очередь DPC запросов (объектов).
Перечень обязанностей типовой процедуры DpcForIsr может включать:
VOID DpcForIsr( PKDPC Dpc, PDEVICE_OBJECT pDevObject, PIRP junk, PDEVICE EXTENSION pDevExtension) { // Неким образом получаем текущий IRP (например, из очереди // queueReadWrite, которую поддерживает сам драйвер): PIRP pIrp = GetCurrentIrp(&pDevExtension->queueReadWrite);
// Инициируем поступление IRP из внутренней очереди в // в процедуру StartIO(): TodoStartNextPacket(&pDevExtension->dqReadWrite, pDevObject)
// Даем возможность отработать процедурам завершения всех // вышестоящий драйверов, если они есть: IoCompleteRequest(pIrp, IO_NO_INCREMENT); }