по какому принципу работают програмы типа portmon и как такое можно реализовать на практике.
Эти программы показывают все события в открытом (другой программой) COM порту.
Здравствуйте, indee, Вы писали:
I>Подскажите пожалуйста,
I>по какому принципу работают програмы типа portmon и как такое можно реализовать на практике. I>Эти программы показывают все события в открытом (другой программой) COM порту.
I>Спасибо!
На уровне kernel-mode наверняка можно.
Для этого достаточно установить над COM-устройством верхний фильтр и перехватывать запросы IOCTL_SERIAL_XXXX.
O>На уровне kernel-mode наверняка можно. O>Для этого достаточно установить над COM-устройством верхний фильтр и перехватывать запросы IOCTL_SERIAL_XXXX.
Здравствуйте, indee, Вы писали:
I>А можно по подробнее...
Вы с драйверной тематикой знакомы ? Если да — хорошо, особых затруднений быть не должно.
В Windows, как известно, система ввода-вывода унифицирована таким образом, чтобы с любым
устройством, независимо от его типа и особенностей, можно было работать посредством единого
файлового программного интерфейса. То есть, — CreateFile/ReadFile/WriteFile/DeviceIoControl/CloseHandle.
Есть и наборы дополнительных функций, специфичных для каждого устройства, но они, как правило,
в конечном счете все равно транслируются в вызовы DeviceIoControl.
Но это лишь верхушка айсберга.
Реальную работу по обслуживанию операций ввода-вывода выполняют драйверы режима ядра, а
координируется она специальным компонентом, который принято называть диспетчером ввода-вывода.
Еще одна особенность в том, что устройства, как правило, обслуживаются не одним драйвером,
а цепочкой драйверов, расположенных один над другим. Например, USB-мышь обслуживается
драйверами MOUCLASS, MOUHID, HIDUSB и HIDCLASS, причем здесь могуь быть и другие драйверы,
реализующие какую-то особую "фирменную" функциональность или выполняющие роль фильтров.
Драйверы различаются не только по позиции в стеке, но и по своей "классовой" принадлежности.
Есть драйверы, которые обслуживают одно конкретное устройство, а есть драйверы, которые
обслуживают целый класс устройств. Есть еще категория драйверов, которые ставятся в
определенную позицию стека и работают как фильтры, пропуская через себя все запросы и
отправляя их вниз. Они так и называются — фильтрующие драйверы. Причем можно фильтровать
как на уровне одного объекта (устройства), так и на уровне всего семейства устройств.
Когда мы с помощью CreateFile открываем устройство, например, последовательный порт, происходит следующее.
Диспетчер ввода-вывода создает пакет ввода-вывода со специальным кодом и параметрами, и отправляет его
самому верхнему драйверу в стеке драйверов данного устройства. Драйвер может обработать запрос,
либо отменить его, либо передать дальше, вниз по стеку, где им займется следующий драйвер.
В самом низу находится драйвер шины, который уже в самом прямом смысле "разговаривает" с оборудованием.
Строго говоря, это не совсем так, ибо есть еще HAL (дополнительный уровень абстракции), но к теме это
сильного отношения не имеет. В конце концов запрос завершается и CreateFile возвращает управление.
Сходным образом отрабатываются операции чтения-записи (ReadFile/WriteFile), а также
всякие управляющие сигналы, включая управление питанием, прерываниями и т.п.
Само собой, в этот процесс можно вклиниться, и это довольно просто сделать.
Для этого достаточно установить драйвер, который присоединится к стеку драйверов
данного устройства, после чего все запросы ввода-вывода будут проходить и через него.
А дальше с этими запросами можно делать все что угодно, вплоть до полной
виртуализации нижележащего оборудования, хотя клиенты, расположенные "наверху",
будут оставаться в неведении. Типичный пример — сетевые фильтрующие драйверы
всяких антивирусов и фаерволов, которые мониторят и модифицируют интернет-трафик,
при этом оставаясь незаметными для браузеров.
Как именно ставить фильтр — зависит от типа фильтруемого устройства, а также от целей фильтрации.
Если устройство не принадлежит к категории PnP-совместимых (драйвера, обслуживающие
такие устройства, называются Legacy-драйверами), то это означает получение адреса с
помощью так называемой символической ссылки, которую эти драйверы обычно создают.
Если же устройство принадлежит к известному классу устройств, это означает
установку верхнего фильтра посредством модификации определенных записей реестра, и
это может быть как фильтром устройства, так и фильтром всего класса устройств, как
уже упоминалось. Само собой, логика работы фильтра во всех этих случаях будет различаться.
Это все общие и очень поверхностные данные, но они должны дать примерную картину того,
что предстоит делать и с чем придется столкнуться.
Скелет такого драйвера будет содержать от силы несколько сотен строк кода, но
драйверная тема изобилует тонкостями, которые нужно знать и без которых никуда (такие,
как обработка IRP/работа с Plug-n-Play/уровни IRQ), более-менее толковая информация
лежит в книгах, статьях на MSDN/WDK/WHDC/OSRONLINE, а также в исходниках, поставляющихся
вместе с WDK. Например, vserial (драйвер виртуального последовательного порта).
Вот, кажется, расписал в общих чертах все, что знаю по теме.