Уроки Iczelion'а




Взаимодействие между VxD - часть 2


Старшая часть двойного слова, которое следует за инструкцией int 20h, содержит ID устройства. Младшая часть содержит начальный (нулевой) индекс элемента таблицы сервисов. Когда генерируется int20h, VMM получает контроль и проверяет двойное слово, которое непосредственно следует за инструкцией прерывания. Затем он извлекает ID устройства и использует его, чтобы найти VxD, а потом использует индекс сервиса, чтобы определить адрес требуемого сервиса в этом VxD.

Вы можете видеть, что эти операции пожирают время. VMM должна потратить время, чтобы найти VxD и адрес желаемого сервиса. Поэтому VMM немножко жульничает. После первого успешного вызова int 20h, VMM сохраняет связь. Это выглядит как замещение in20h и последующего слова на прямой вызов сервиса. Поэтому вышеприведенный кусок кода будет трансформирован в:

call dword ptr [VxD_Service_Address]

Этот прием работает, так как int 20h + dword занимает 6 байтов, что в точности равно инструкции call dword рtr. Поэтому последовательные вызовы быстры и эффективны. Этот метод имеет свои за и против. Положительным является то, что снижается загрузка VMM и VxD загрузчика, потому что они не должны фиксировать все сервисные вызовы VxD во время загрузки. Вызовы, которые никогда не загружались, останутся немодифицированными. Среди недостатков данного подхода можно назвать то, что он делает невозможным выгрузить статические VxD, сервисы которых используются, так как в противном случае, другие VxD, использующие сервисы выгруженного драйвера, завесили бы систему обращениями к неправильным адресам памяти. Hет механизма "pазлинковки". Из этого неизбежно следует, что динамические VxD не подходят для предоставления каких-либо сервисов.

Callback'и: callback'и или callback'овые функции - это функции в VxD, которые существуют. Callback'и не являются открытыми как сервисы. Они являются приватными функциями, чьи адреса VxD передает другим VxD в специальных ситуациях. Hапример, когда VxD обрабатывает хардварное прерывание, теми его функциями, которые могут вызвать рage faults, не могут пользоваться другие VxD. VxD может дать адрес одной из своей собственных функций (callback) VMM, чтобы тот мог вызвать функцию, когда он может допускать рage faults, и тогда VxD может продолжить свою работу когда вызывается его callback-функция. Идея обратного вызова (callback) используется не только в VxD. Многие Windows API используют ее. Вероятно, лучший пример - это оконная процедура. Вы указываете адрес процедуры окна в структуре WNDCLASS или WNDCLASSEX и передаете ее Windows с помощью функции RegisterClass или RegisterClassEx. Windows будет вызывать вашу процедуру окна, когда для этого окна появятся сообщения. Другим примером может являться hook-процедуры. Ваше приложение дает Windows адрес hook-процедуры, чтобы Windows могла вызвать ее, когда происходит событие, которое интересно приложению.

Приведенные три метода служат для взаимодействия между VxD. Существуют также интерфейсы для Windows-, V86- и Win32-приложений. Я расскажу об интерфейсе VxD для win32 приложений в следующих нескольких туториалах.

[C] Iczelion, пер. Aquila.






Содержание  Назад  Вперед