Двусторонняя связь между драйвером режима ядра и пользовательским приложением?

Мне нужна двусторонняя связь между драйвером WFP в режиме ядра и приложением пользовательского режима. Драйвер инициирует связь, передавая URL-адрес приложению, которое затем классифицирует этот URL-адрес (Entertainment, News, Adult и т. Д.) И передает эту категорию обратно в драйвер. Драйвер должен знать категорию в функции фильтра, поскольку он может блокировать определенные веб-страницы на основе этой информации. У меня был поток в приложении, который делал запрос ввода-вывода, который будет содержать драйвер с URL-адресом и GUID, а затем приложение будет записывать категорию в реестр под этим GUID, где драйвер подберет его. К сожалению, как указал верификатор драйвера, это нестабильно, поскольку функции реестра Zw должны запускаться на PASSIVE\_LEVEL. Я думал о том, чтобы попробовать то же самое с сопоставленными буферами памяти, но я не уверен, что для этого требуются требования прерывания. Кроме того, я думал о снижении уровня прерывания перед вызовом функции реестра, но я не знаю, каковы его побочные эффекты.

Вам просто нужно иметь два разных типа ввода-вывода.

Если вы используете  [`DeviceIoControl`](https://msdn.microsoft.com/en-us/library/aa363216%28v=vs.85%29.aspx) , чтобы получить URL-адреса (я думаю, что это был бы самый подходящий метод), это так же просто, как добавление второго кода управления ввода-вывода.

If you're using `ReadFile` or equivalent, things would normally get a bit messier, but as it happens in this specific case you only have two kinds of operations, one of which is a read (driver->application) and the other of which is a write (application->driver). So you could just use `WriteFile` to send the reply, including of course the GUID so that the driver can match up your reply to the right query.

Другой подход (более похожий на ваш оригинальный) - использовать буфер общей памяти. Подробнее см.  [этот ответ](https://stackoverflow.com/a/11047456/886887) . Проблема с этой идеей заключается в том, что вам придется либо использовать спин-блокировку (за счет производительности системы и энергопотребления, и, конечно, не в состоянии работать в одноядерной системе), либо опросить (что неэффективно и неэффективно не очень подходит для чувствительных к времени операций).



PASSIVE\_LEVEL ничего нестабильно. Доступ к реестру должен быть на PASSIVE\_LEVEL, поэтому это невозможно сразу, если драйвер работает на более высоком IRQL. Однако вы можете сделать это, разгрузив рабочий элемент. Понижение IRQL обычно не рекомендуется, поскольку это противоречит намерениям ОС.

Your protocol indeed sounds somewhat cumbersome and doing a direct app-driver communication is probably preferable. You can find useful information about this here: [http://msdn.microsoft.com/en-us/library/windows/hardware/ff554436(v=vs.85).aspx](https://msdn.microsoft.com/en-us/library/windows/hardware/ff554436(v=vs.85).aspx)



Поскольку выноски находятся в DISPATCH, ваша обработка должна выполняться либо в рабочем потоке, либо в DPC, что позволит вам использовать ZwXXX. Вы должны перевернутые обратные вызовы для целей связи, есть хороший документ в OSR.

Я только начал совать WFP, но он похож даже на образцы, которые они предоставляют, Microsoft повторно загружает пакеты. Я не заглянул в нее так близко, но кажется, что они отбрасывают пакет и повторно вводят всякий раз, когда обрабатываются. Этого будет достаточно для того, чтобы ваш механизм режима использования принял решение. Вы также должны ограничить захват пакетов определенным портом (80 в вашем случае), чтобы не выполнять дополнительную обработку, которая вам не нужна.