Здравствуйте 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 (например если все запросы к твоему устройству идут от тебя же), можешь создавать новый ирп прям в момент запроса.