Общение serial port драйвера c user-mode.
От: Andrew S Россия http://alchemy-lab.com
Дата: 28.07.02 19:48
Оценка:
Привет всем. Жизнь заставляет писАть драйвер ком-порта, при этом возникает необходимость общения с user-mode приложением (для управления поведением драйвера, вызовом некоторых функций и т.п.).
Очевидно, для общения с драйвером посредством отложенного DeviceIoControl необходимо получить хандл драйвера. Также очевидно, что напрямую сделать ЭТО в случае с ком портом не представляется возможным, т.к. такой хандл должно мочь создать приложение пользователя. Очевидно, есть 2 решения.
1. Писать filter драйвер. Ну, или совмещать его функциональность в основном.
2. Использовать неизвестные мне недокументированные возможности и создавать таки хандл (точнее, его копию) из юзер моде.
Интересует следующее.
а) Возможно ли совместить функционал 2-х типов драйверов в одном, т.е. сначала сделать IoCreateDevice и IoAttachDeviceToDeviceStack для собственно драйвера последовательного порта, а потом сделать в нем же так называемый вторичный девайс, спеиально для общения с нашим управляющим user-mode приложением, и потом тоже его IoAttachDeviceToDeviceStack. Соотв., управляющее юзер-моде приложение будет создавать объект вторичного девайса, а приложение пользователя — первичного. (?) какие параметры передавать IoCreateDevice в этом случае для успешной работы вторичного девайса. Очевидно, в этом случае на функциях IOCTLххх и IRP_ххх прижется разбирать, какой именно драйвер вызывается.
б) Другие варианты.

Возможно, я что то недопонимаю, т.к. опыта написания таких драйверов немного.
Всем спасибо за советы.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re: Общение serial port драйвера c user-mode.
От: Vovkos Россия https://ioninja.com
Дата: 28.07.02 22:49
Оценка: 4 (1)
Здравствуйте Andrew S, Вы писали:

AS>Привет всем. Жизнь заставляет писАть драйвер ком-порта, при этом возникает необходимость общения с user-mode приложением (для управления поведением драйвера, вызовом некоторых функций и т.п.).

AS>Очевидно, для общения с драйвером посредством отложенного DeviceIoControl необходимо получить хандл драйвера. Также очевидно, что напрямую сделать ЭТО в случае с ком портом не представляется возможным, т.к. такой хандл должно мочь создать приложение пользователя. Очевидно, есть 2 решения.
AS>1. Писать filter драйвер. Ну, или совмещать его функциональность в основном.
AS>2. Использовать неизвестные мне недокументированные возможности и создавать таки хандл (точнее, его копию) из юзер моде.
AS>Интересует следующее.
AS>а) Возможно ли совместить функционал 2-х типов драйверов в одном, т.е. сначала сделать IoCreateDevice и IoAttachDeviceToDeviceStack для собственно драйвера последовательного порта, а потом сделать в нем же так называемый вторичный девайс, спеиально для общения с нашим управляющим user-mode приложением, и потом тоже его IoAttachDeviceToDeviceStack. Соотв., управляющее юзер-моде приложение будет создавать объект вторичного девайса, а приложение пользователя — первичного. (?) какие параметры передавать IoCreateDevice в этом случае для успешной работы вторичного девайса. Очевидно, в этом случае на функциях IOCTLххх и IRP_ххх прижется разбирать, какой именно драйвер вызывается.
AS>б) Другие варианты.

AS>Возможно, я что то недопонимаю, т.к. опыта написания таких драйверов немного.

AS>Всем спасибо за советы.

Просто создай для общения с приложением второй девайс (DEVICE_TYPE возьми какойнть начиная с 0x8000) и симболик линк для него создай, и все. Никуда его аттачить не надо
Re[2]: Общение serial port драйвера c user-mode.
От: Andrew S Россия http://alchemy-lab.com
Дата: 29.07.02 12:24
Оценка:
Здравствуйте Vovkos, Вы писали:

А IRP проще наверное стеково передавать? Дело в том, что многие из IRP будут нести данные, нужные lower level драйверу. Поэтому я и решил, чтобу не разводить копии IRP — проще аттачить его на стек драйверов. В этом случае функции filter части вторичного девайса драйвера сводятся просто к передачи запроса Lower level драйверу.
Или я неправ?

V>Просто создай для общения с приложением второй девайс (DEVICE_TYPE возьми какойнть начиная с 0x8000) и симболик линк для него создай, и все. Никуда его аттачить не надо
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[2]: Общение serial port драйвера c user-mode.
От: Andrew S Россия http://alchemy-lab.com
Дата: 29.07.02 12:29
Оценка:
Здравствуйте Vovkos, Вы писали:

Да, и сразу же второй вопрос. Как лучшее — создавать один вторичный девайс, или для каждого первичного создавать свой вторичный. В смысле, как будет меньше оверхед при использовании?
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[3]: Общение serial port драйвера c user-mode.
От: Vovkos Россия https://ioninja.com
Дата: 29.07.02 21:20
Оценка:
Здравствуйте Andrew S, Вы писали:

AS>А IRP проще наверное стеково передавать? Дело в том, что многие из IRP будут нести данные, нужные lower level драйверу. Поэтому я и решил, чтобу не разводить копии IRP — проще аттачить его на стек драйверов. В этом случае функции filter части вторичного девайса драйвера сводятся просто к передачи запроса Lower level драйверу.

AS>Или я неправ?

Ну здесь дело в том что устройство, которое аттачится наверх стека, по-хорошему должно сохранять флаги нижних устройств, в частности и флаг эксклюзивности, а так как сериалпорт должен быть эксклюзивным, то при такой архитектуре (устройство для общения с приложением сидит наверху стека) — не удастся открыть более одного хэндла. Поэтому твое приложение и какаянить другая програмка не смогут работать одновременно. Или же наоборот, если ты снимешь флаг экслюзивности, то 2 приложения смогут открыть сериалпорт, что тоже неправильно. Отсюда и необходимость "вторичного" устройства. Пробовать передавать оригинальный ИРП из девайса-сателлита прямо в девайс сериал порта — очень не рекомендую, даже если данные запроса менять не надо. Лучше иметь пул preallocated ирпов для девайса сериал порта, и брать из него при необходимости (ну и пополнять его соответвенно тоже). Отвечая на следующий пост — на мой взгляд, можно вообще пренебречь "оверхедом" от создания дополнительных девайсов, и действовать так, как будет архитектурно правильно. Если тебе кажется, что логичнее чтоб у каждого порта был свое устройство-"сателлит" — значит так и делай.
Удачи!
Re[4]: Общение serial port драйвера c user-mode.
От: Andrew S Россия http://alchemy-lab.com
Дата: 29.07.02 22:08
Оценка:
Слушай, извини, что мучаю, но больше никто, видимо, ответить не могет. Народа, общающегося с кернел, не так то много:)

Насчет эксклюзивности ты уверен абсолютно или все же стОит попробовать?
Насколько я знаю, filter драйверы пишутся именно так, и вроде все работает. Например, фильтер драйвер для ком порта.
И после этого юзерские приложения не могут открывать более одного раза ком порт, как и положено.

А если использовать IoAttachDevice для вторичного девайса вместо IoAttachDeviceToDeviceStack?
Тут то экслюзивность сохраняется? И можно ли после этого убить SourceDevice (см. IoAttachDevice), или они должны жить вместе с AttachedDevice долго и умереть в один день?

А оверхед... В принципе, всего 2 варианта:
1. Для каждого девайса — свой саттелит. При этом в DEVICE_EXTENSION саттелита хранится lower device настоящего девайса. Соотв, надо различать, запрос к чему идет. Можно для это цели выбрать первый элемент структуры в DEVICE_EXTENSION, который будет указывать, саттелит это или нет. Соотв., дальнейшие поля DEVICE_EXTENSION в зависимости от этого интерпретируются по-разному.
2. Для всех девайсов — один саттелит. При этом при первом вызове из юзер-моде приложения ему возвращается соотв. DEVICE_OBJECT настоящего девайса, который потом и используется при вызовах для роутинга между настоящими девайсами.

Для метода (2) наверное, каждый запрос к драйверу требует нового IRP. Или нет?
Очевидно, что для (1) все может быть проще — просто передаем запрос ниже по стеку драйверов и все.
Правда, если только насчет эксклюзивности ты ошибся :)

Мне просто интересно не как логичнее на мой взгляд, а как делают другие, т.к. у меня опыта пока немного и все кажется весьма сложным.
И еще. А почему рекомендуешь создавать пул IRP заранее (под пулом подразумевается LinkedList?)? Чем это удобно? Почему нельзя создавать IRP непосредственно при необходимости, в момент запроса?
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[5]: Общение serial port драйвера c user-mode.
От: Vovkos Россия https://ioninja.com
Дата: 30.07.02 08:45
Оценка: 6 (1)
Здравствуйте Andrew S, Вы писали:

AS>Слушай, извини, что мучаю, но больше никто, видимо, ответить не могет. Народа, общающегося с кернел, не так то много


AS>Насчет эксклюзивности ты уверен абсолютно или все же стОит попробовать?

AS>Насколько я знаю, filter драйверы пишутся именно так, и вроде все работает. Например, фильтер драйвер для ком порта.
AS>И после этого юзерские приложения не могут открывать более одного раза ком порт, как и положено.

По хорошему фильтры должны брать флаги нижележащих устройств (ну и модифицировать их по необходимости). Но здесь все равно имеется логическая проблема. Даже если ты уберешь флаг экслюзивности у устройства, какое-нить приложение может создать хэндл сериал порта для эксклюзивного доступа (передать 0 в dwShareMode при CreateFile), поэтому неприемлемо иметь устройство для общения с твоим приложением, сидящее наверху стека самого сериалпорта (если только действительно нужна работа этого приложения одновременно с другими, пользующимися портом)

AS>А если использовать IoAttachDevice для вторичного девайса вместо IoAttachDeviceToDeviceStack?

AS>Тут то экслюзивность сохраняется?
Эксклюзивность задается при IoCreateDevice (флаг bExclusive) или позже, через DEVICE_OBJECT::Flags (DO_EXCLUSIVE)

AS>И можно ли после этого убить SourceDevice (см. IoAttachDevice), или они должны жить вместе с AttachedDevice долго и умереть в один день?

Какже ты его убъешь??? Ты ж его только что приаттачил сверху на стек???

AS>А оверхед... В принципе, всего 2 варианта:

AS>1. Для каждого девайса — свой саттелит. При этом в DEVICE_EXTENSION саттелита хранится lower device настоящего девайса. Соотв, надо различать, запрос к чему идет. Можно для это цели выбрать первый элемент структуры в DEVICE_EXTENSION, который будет указывать, саттелит это или нет. Соотв., дальнейшие поля DEVICE_EXTENSION в зависимости от этого интерпретируются по-разному.
AS>2. Для всех девайсов — один саттелит. При этом при первом вызове из юзер-моде приложения ему возвращается соотв. DEVICE_OBJECT настоящего девайса, который потом и используется при вызовах для роутинга между настоящими девайсами.

AS>Для метода (2) наверное, каждый запрос к драйверу требует нового IRP. Или нет?

AS>Очевидно, что для (1) все может быть проще — просто передаем запрос ниже по стеку драйверов и все.
AS>Правда, если только насчет эксклюзивности ты ошибся

AS>Мне просто интересно не как логичнее на мой взгляд, а как делают другие, т.к. у меня опыта пока немного и все кажется весьма сложным.

Ну все зависит от логики работы этого "вторичного" устройства. Если логично и удобно чтоб он был один, надо делать один. Если нужно много — можно сделать много, на "оверхед" можно не обращать внимания. Если сообщищь, что собирается делать приложение, можно чтонить поконкретнее сказать =)

AS>И еще. А почему рекомендуешь создавать пул IRP заранее (под пулом подразумевается LinkedList?)? Чем это удобно? Почему нельзя создавать IRP непосредственно при необходимости, в момент запроса?

Вообще-то это неудобно =) Но если нет гарантий, что dispatchentry будет вызвана при PASSIVE_LEVEL — это необходимо.
Если ты уверен, что будет PASSIVE_LEVEL (например если все запросы к твоему устройству идут от тебя же), можешь создавать новый ирп прям в момент запроса.
Re[6]: Общение serial port драйвера c user-mode.
От: Andrew S Россия http://alchemy-lab.com
Дата: 30.07.02 11:20
Оценка:
Нет, ну это понятно. А как же тогда пишутся фильтры для последовательных портов? Например, PortMon. Он одновременно общается и со своим юзер-може приложением, и одновременно дает открыть lower level драйвер ком-порта обычным приложениям. Ок. Я все же попробую, что получится — скажу.

Спасибо!

V>По хорошему фильтры должны брать флаги нижележащих устройств (ну и модифицировать их по необходимости). Но здесь все равно имеется логическая проблема. Даже если ты уберешь флаг экслюзивности у устройства, какое-нить приложение может создать хэндл сериал порта для эксклюзивного доступа (передать 0 в dwShareMode при CreateFile), поэтому неприемлемо иметь устройство для общения с твоим приложением, сидящее наверху стека самого сериалпорта (если только действительно нужна работа этого приложения одновременно с другими, пользующимися портом)


AS>>А если использовать IoAttachDevice для вторичного девайса вместо IoAttachDeviceToDeviceStack?

AS>>Тут то экслюзивность сохраняется?
V>Эксклюзивность задается при IoCreateDevice (флаг bExclusive) или позже, через DEVICE_OBJECT::Flags (DO_EXCLUSIVE)

AS>>И можно ли после этого убить SourceDevice (см. IoAttachDevice), или они должны жить вместе с AttachedDevice долго и умереть в один день?

V>Какже ты его убъешь??? Ты ж его только что приаттачил сверху на стек???

AS>>А оверхед... В принципе, всего 2 варианта:

AS>>1. Для каждого девайса — свой саттелит. При этом в DEVICE_EXTENSION саттелита хранится lower device настоящего девайса. Соотв, надо различать, запрос к чему идет. Можно для это цели выбрать первый элемент структуры в DEVICE_EXTENSION, который будет указывать, саттелит это или нет. Соотв., дальнейшие поля DEVICE_EXTENSION в зависимости от этого интерпретируются по-разному.
AS>>2. Для всех девайсов — один саттелит. При этом при первом вызове из юзер-моде приложения ему возвращается соотв. DEVICE_OBJECT настоящего девайса, который потом и используется при вызовах для роутинга между настоящими девайсами.

AS>>Для метода (2) наверное, каждый запрос к драйверу требует нового IRP. Или нет?

AS>>Очевидно, что для (1) все может быть проще — просто передаем запрос ниже по стеку драйверов и все.
AS>>Правда, если только насчет эксклюзивности ты ошибся

AS>>Мне просто интересно не как логичнее на мой взгляд, а как делают другие, т.к. у меня опыта пока немного и все кажется весьма сложным.

V>Ну все зависит от логики работы этого "вторичного" устройства. Если логично и удобно чтоб он был один, надо делать один. Если нужно много — можно сделать много, на "оверхед" можно не обращать внимания. Если сообщищь, что собирается делать приложение, можно чтонить поконкретнее сказать =)

AS>>И еще. А почему рекомендуешь создавать пул IRP заранее (под пулом подразумевается LinkedList?)? Чем это удобно? Почему нельзя создавать IRP непосредственно при необходимости, в момент запроса?

V>Вообще-то это неудобно =) Но если нет гарантий, что dispatchentry будет вызвана при PASSIVE_LEVEL — это необходимо.
V>Если ты уверен, что будет PASSIVE_LEVEL (например если все запросы к твоему устройству идут от тебя же), можешь создавать новый ирп прям в момент запроса.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re: Общение serial port драйвера c user-mode.
От: Andrew S Россия http://alchemy-lab.com
Дата: 11.08.02 15:43
Оценка:
Привет всем еще раз. Попробовал я сделать, как рекомендовалось. Т.е. просто создать саттелит-девайс без аттачинья его куда-либо (в том же драйвере, что и основной). И симболик линк на него. Это не заработало. Девайс создается, линк на него тоже. Но вот не окрывается из юзер-моде. Основной — открывается, а этот нет.

Итак, у кого еще есть какие мнения. Приложению управления нужно получать данные из последовательного порта, и отправлять ему тоже. При этом, естественно, порт открыт другим юзер-моде приложением пользователя, и открыть его еще раз приложения управления не может, т.к. порт уже открыт. Очевидно, что такая проблема на других устройствах решается filter-драйвером. Однако тут проскочило замечание, что с последовательным портом такое не пройдет, т.к. присутствует флаг эксклюзитвности.
К тому же задача осложняется (или упрощается?) тем, что это хорошо бы совместить в одном драйвере — т.е. и функционал драйвера com-порта, и фильтер-драйвера.
Т.е. создается устройство — саттелит (как?), с которым и общается юзер-моде приложение.
Илди может можно без дополнительного гемморая, получить каким то образом юзер-моде хандл на уже открытый другим юзер-моде приложением девайс и отдать его приложению управления (это, конечно, ересь — т.к. хандл привязан к процессу, его открывшему, но вдруг...)?
очевидно, проблема решаема, т.к. существуют подобные продукты. (Да взять хотя бы драйвера вин-модемов)

Буду всем признателен за любую помощь. К сожалению, в той литературе, что есть у меня, этот вопрос не освещен вообще.



Здравствуйте Andrew S, Вы писали:

AS>Привет всем. Жизнь заставляет писАть драйвер ком-порта, при этом возникает необходимость общения с user-mode приложением (для управления поведением драйвера, вызовом некоторых функций и т.п.).

AS>Очевидно, для общения с драйвером посредством отложенного DeviceIoControl необходимо получить хандл драйвера. Также очевидно, что напрямую сделать ЭТО в случае с ком портом не представляется возможным, т.к. такой хандл должно мочь создать приложение пользователя. Очевидно, есть 2 решения.
AS>1. Писать filter драйвер. Ну, или совмещать его функциональность в основном.
AS>2. Использовать неизвестные мне недокументированные возможности и создавать таки хандл (точнее, его копию) из юзер моде.
AS>Интересует следующее.
AS>а) Возможно ли совместить функционал 2-х типов драйверов в одном, т.е. сначала сделать IoCreateDevice и IoAttachDeviceToDeviceStack для собственно драйвера последовательного порта, а потом сделать в нем же так называемый вторичный девайс, спеиально для общения с нашим управляющим user-mode приложением, и потом тоже его IoAttachDeviceToDeviceStack. Соотв., управляющее юзер-моде приложение будет создавать объект вторичного девайса, а приложение пользователя — первичного. (?) какие параметры передавать IoCreateDevice в этом случае для успешной работы вторичного девайса. Очевидно, в этом случае на функциях IOCTLххх и IRP_ххх прижется разбирать, какой именно драйвер вызывается.
AS>б) Другие варианты.

AS>Возможно, я что то недопонимаю, т.к. опыта написания таких драйверов немного.

AS>Всем спасибо за советы.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re: Общение serial port драйвера c user-mode.
От: FiW  
Дата: 19.06.05 17:24
Оценка:
Здравствуйте, Andrew S, Вы писали:

Хотелось бы узнать чем все это закончилось?

AS>Привет всем. Жизнь заставляет писАть драйвер ком-порта, при этом возникает необходимость общения с user-mode приложением (для управления поведением драйвера, вызовом некоторых функций и т.п.).

AS>Очевидно, для общения с драйвером посредством отложенного DeviceIoControl необходимо получить хандл драйвера. Также очевидно, что напрямую сделать ЭТО в случае с ком портом не представляется возможным, т.к. такой хандл должно мочь создать приложение пользователя. Очевидно, есть 2 решения.
AS>1. Писать filter драйвер. Ну, или совмещать его функциональность в основном.
AS>2. Использовать неизвестные мне недокументированные возможности и создавать таки хандл (точнее, его копию) из юзер моде.
AS>Интересует следующее.
AS>а) Возможно ли совместить функционал 2-х типов драйверов в одном, т.е. сначала сделать IoCreateDevice и IoAttachDeviceToDeviceStack для собственно драйвера последовательного порта, а потом сделать в нем же так называемый вторичный девайс, спеиально для общения с нашим управляющим user-mode приложением, и потом тоже его IoAttachDeviceToDeviceStack. Соотв., управляющее юзер-моде приложение будет создавать объект вторичного девайса, а приложение пользователя — первичного. (?) какие параметры передавать IoCreateDevice в этом случае для успешной работы вторичного девайса. Очевидно, в этом случае на функциях IOCTLххх и IRP_ххх прижется разбирать, какой именно драйвер вызывается.
AS>б) Другие варианты.

AS>Возможно, я что то недопонимаю, т.к. опыта написания таких драйверов немного.

AS>Всем спасибо за советы.
Re[2]: Общение serial port драйвера c user-mode.
От: Andrew S Россия http://alchemy-lab.com
Дата: 19.06.05 17:35
Оценка:
FiW>Хотелось бы узнать чем все это закончилось?

Скелет драйвера был почти написан, а проект заброшен
Честно говоря, сейчас даже и не помню всех проблем, которые решали и которые еще предстояло решить.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[3]: Общение serial port драйвера c user-mode.
От: FiW  
Дата: 19.06.05 17:53
Оценка:
Здравствуйте, Andrew S, Вы писали:

FiW>>Хотелось бы узнать чем все это закончилось?


AS>Скелет драйвера был почти написан, а проект заброшен

AS>Честно говоря, сейчас даже и не помню всех проблем, которые решали и которые еще предстояло решить.

вот блин, я в таком же "тупике" сейчас... а исходников не осталось? может там были "крупицы истины"?
Re[4]: Общение serial port драйвера c user-mode.
От: Andrew S Россия http://alchemy-lab.com
Дата: 19.06.05 18:37
Оценка:
FiW>вот блин, я в таком же "тупике" сейчас... а исходников не осталось? может там были "крупицы истины"?

Все уже давно поксерено... Я думаю — самый правильный вариант — почитать форум хардваре, поспрашивать там — подобные темы там были и варианты решения тоже. Еще можно попробовать поискать иходники port mon.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[5]: Общение serial port драйвера c user-mode.
От: FiW  
Дата: 19.06.05 19:06
Оценка:
Здравствуйте, Andrew S, Вы писали:

FiW>>вот блин, я в таком же "тупике" сейчас... а исходников не осталось? может там были "крупицы истины"?


AS>Все уже давно поксерено... Я думаю — самый правильный вариант — почитать форум хардваре, поспрашивать там — подобные темы там были и варианты решения тоже. Еще можно попробовать поискать иходники port mon.


Да фильтер-драйвер уже есть (который "слушает", как PortMon), а вот как реализовать передачу в порт от другой программы? Мне казалось что я вот-вот у цели... а теперь я в тупике

ps: у меня порт захвачен сервисом постоянно, а иногда нужно послать пару тройку команд туда...
Re[6]: Общение serial port драйвера c user-mode.
От: Andrew S Россия http://alchemy-lab.com
Дата: 19.06.05 19:21
Оценка:
FiW>>>вот блин, я в таком же "тупике" сейчас... а исходников не осталось? может там были "крупицы истины"?

AS>>Все уже давно поксерено... Я думаю — самый правильный вариант — почитать форум хардваре, поспрашивать там — подобные темы там были и варианты решения тоже. Еще можно попробовать поискать иходники port mon.


FiW>Да фильтер-драйвер уже есть (который "слушает", как PortMon), а вот как реализовать передачу в порт от другой программы? Мне казалось что я вот-вот у цели... а теперь я в тупике


FiW>ps: у меня порт захвачен сервисом постоянно, а иногда нужно послать пару тройку команд туда...


Насколько я помню, туда на стек аттачится дополнительный девайс, который собственно может как пропускать IRP (то бишь выполнять роль фильтра), так и формировать новые. Но это лучше в hardware спросить — я слишком давно всем этим занимался, а копаться в этом белье мне сейчас просто не когда...
http://www.rusyaz.ru/pr — стараемся писАть по-русски
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.