Страница 3 из 13 Статические и динамические драйверы По способу загрузки VxD разделяются на статические — загружаемые один раз в процессе старта Windows и работающие до ее закрытия, и динамические — загружаемые и выгружаемые по запросу системы и приложений. Динамические VxD используются в тех случаях, когда постоянное присутствие драйвера в системе необязательно, однако по понятной причине они не могут участвовать в начальной инициализации системы. Статические VxD могут участвовать в инициализации системы, однако не могут быть выгружены в процессе ее работы. Порядок загрузки статических драйверов Статические драйверы загружаются системой в определенном порядке при этом основные драйверы должны загружаться первыми, а после этого — зависящие от них драйверы более высокого уровня. Для этой процедуры каждый драйвер имеет параметр Init Order — числовую константу, определяющую место драйвера в списке загрузки, которая происходит в порядке возрастания значений параметра. Системным драйверам назначены определенные значения, отражающие их зависимость друг от друга. Если порядок загрузки не имеет смысла — используется нулевое значение параметра; такие драйверы загружаются после завершения инициализации «номерных» VxD. Системные сообщения драйверу Система взаимодействует с драйвером путем передачи ему системных сообщений о загрузке/выгрузке драйвера, а также при наступлении определенных системных событий, которые могут потребовать вмешательства драйвера (создание/удаление виртуальной машины, приложения, задачи (thread), смена текущей виртуальной машины/задачи, перезагрузка системы, появление нового устройства и т.п.). Для обработки системных сообщений каждый драйвер должен содержать диспетчер сообщений — процедуру, которая получает управление при передаче сообщения драйверу. Процедуре передается код сообщения и его параметры, после завершения обработки процедура возвращает результат, определяющий последующие действия системы. Сервисные функции драйвера Каждый драйвер, имеющий идентификатор, может поддерживать набор сервисных функций, доступных для других VxD в системе. Если VxD представляет какое-либо виртуальное устройство, эти функции служат для управления устройством либо просто воплощают какие-либо операции, ради которых создавался драйвер. Сервисные функции драйвера имеют номера начиная с нуля, по которым их могут вызывать другие VxD. Драйвер предоставляет системе таблицу адресов процедур — обработчиков функций, обращение к которым происходит путем вызова процедуры по индексу из таблицы. Обязательна для поддержки только функция с нулевым номером — Get Version (запрос версии). Поддержка и назначение остальных функций оставлена на усмотрение разработчика драйвера. Механизм вызова сервисных функций использует идентификатор драйвера, по которому происходит поиск нужного драйвера в системе. Поэтому драйверы, не имеющие идентификатора, не могут быть вызваны для обработки сервисных функций. Интерфейс с прикладными программами Для взаимодействия с прикладными программами VxD может предоставлять три вида API (Application Program Interface — интерфейс прикладных программ): - V86 API — для 16-разрядных приложений DOS (программ режима V86).
- PM API — для 16-разрядных приложений Windows, которые до появления Windows 9x назывались Protected Mode Applications (приложения защищенного режима).
- Win32 API — для приложений Win32.
Для обработки запросов от 16-разрядных программ в драйвере предусматриваются две различные функции — для запросов от виртуальных машин DOS и для запросов от приложений Win16. Запросы от приложений Win32 передаются в виде системных сообщений их общему диспетчеру. 16-разрядные приложения получают доступ к своим API посредством функции 0x1684 программного прерывания 2F, которая возвращает адрес шлюза (gate) для вызова VxD. Поиск нужного драйвера возможен как по идентификатору, так и по имени; поиск по имени был введен позднее, поэтому документирован не во всех описаниях функции int 2F. При выполнении вызова через шлюз происходит переключение в 32-разрядный режим с сохранением всех регистров вызвавшей виртуальной машины (клиента) в специальной структуре, после чего управление передается соответствующей процедуре обработки в VxD. При возврате происходит восстановление значений регистров, которые могут быть модифицированы процедурой обработки. Приложения Win32 получают доступ к API посредством функции CreateFile, загружающей VxD, если он динамический, и открывающей его интерфейс. Поиск драйвера происходит по имени драйвера, имени его файла либо по имени ключа реестра, описывающего драйвер. Обращение к обработчику Win32 API в драйвере происходит при вызове приложением функции DeviceIoControl. При этом выполняется переключение в режим ядра и передача диспетчеру системных сообщений драйвера сообщения W32_DEVICEIOCONTROL. Для обмена данными передаются два независимых указателя (буфер параметров и буфер результата), которые могут ссылаться и на одну и ту же область памяти. Если драйвер поддерживает механизм асинхронных (overlapped) операций, фактическое завершение операции может происходить независимо от момента возврата управления из диспетчера. |