Ассемблер для Windows

       

Содержимое файла VXD MAP



III

Приступим теперь к написанию простого, но работающего статического виртуального драйвера. Такой драйвер представлен на Рисунок 4.7.3. Ниже мы обсудем этот драйвер, а также построение статических виртуальных драйверов.

.386P

include vmm.inc include shell.inc include vcond.inc

; заполнить структуру DDB DECLARE_VIRTUAL_DEVICE VXD2,1,0, VXD2_Control, \ UNDEFINED_DEVICE_ID, UNDEFINED_INIT_ORDER

; объявить принимаемые сообщения и процедуры, ; которые их обрабатывают Begin_control_dispatch VXD2 Control_Dispatch Create_VM, OnVMCreate Control_Dispatch VM_Terminate2, OnVMClose End_control_dispatch VXD2

; сегмент для хранения сообщений VxD_PAGEABLE_DATA_SEG MsgTitle db "Сообщение драйвера VXD",0 VMCreated db "Создается виртуальная машина",0 VMDestroyed db "Уничтожается виртуальная машина",0 VMFocus db "Смена фокуса виртуальной машины" VxD_PAGEABLE_DATA_ENDS

; сегмент, содержащий код VxD_PAGEABLE_CODE_SEG

; процедура - реакция на создание виртуальной машины BeginProc OnVMCreate ; здесь можно вставить код - реакцию на ; открытие виртуальной машины

MOV ECX,OFFSET VMCreated CALL MES RET EndProc OnVMCreate

; процедура - реакция на закрытие виртуальной машины BeginProc OnVMClose ; здесь можно вставить код - реакцию на ; закрытие виртуальной машины

MOV ECX,OFFSET VMDestroyed CALL MES RET EndProc OnVMClose

; процедура, выводящая сообщение MES PROC ; получить дескриптор системной виртуальной машины VMMCall Get_sys_vm_handle ; дескриптор возвращается в EBX ; в EAX - флаг сообщения MOV EAX,MB_OK ; адрес заголовка сообщения MOV EDI, OFFSET MsgTitle ; адрес CallBack функции, в данном случае NULL XOR ESI,ESI ; ссылка на данные для CallBack-функции XOR EDX,EDX ; сервисная функция VXD - окно сообщения VxDCall SHELL_Message MES ENDP VxD_PAGEABLE_CODE_ENDS



end

Рисунок 4.7.3. Пример простого статического виртуального драйвера.

Как мы уже указывали, статический драйвер загружается при загрузке системы и остается в памяти до завершения работы операционной системы. Удобнее всего загрузить драйвер, указав строку device=имя_драйвера в секции [386enh] файла SYSTEM.INI. Можно также использовать системный реестр: HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\key\StaticVxD=pathname.




Первое, однако, более удобно, т.к. в случае ошибки в VXD- драйвере можно исключить его запуск, отредактировав файл SYSTEM.INI в MS DOS.

При установке виртуальных драйверов VMM посылает драйверам следующие три сообщения в порядке списка.

SysCriticalInit - посылается при переключении в защищенный режим, но до разрешения прерываний.

Device_Init - посылается после разрешения прерываний. Именно это сообщение чаще всего используется виртуальными драйверами для проведения начальной инициализации.

Init_Complete - последнее сообщение, посылаемое виртуальным драйверам при загрузке системы.

Получив сообщение и выполнив необходимую работу, драйвер должен сбросить флаг переноса и возвратить управление системе.

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

System_Exit2 - сообщение посылается перед выгрузкой системы. Микропроцессор находится еще в защищенном режиме.

Sys_Critical_Exit2 - следующее сообщение перед выгрузкой системы.

Device_Reboot_Notify2 - сообщают виртуальным драйверам, что система "собирается" выгружаться. Прерывания еще доступны.

Crit_Reboot_Notify2 - аналогичное предыдущему сообщению, но прерывания недоступны.

Обратимся теперь к программе на Рисунок 4.7.3. Этот драйвер выводит сообщение при активизации виртуальной машины (например, создание консоли или просто запуск DOS-приложения) и при ее деактивизации. В драйвере мы использовали две сервисные функции: получить дескриптор системной виртуальной машины и вывести сообщение. Рассмотрим эти функции:

Get_sys_vm_handle - получить дескриптор системной виртуальной машины. Причем дескриптор возвращается в регистре EBX.

SHELL_Message — вывести сообщение. Параметры хранятся в регистрах:


  • EBX — дескриптор виртуальной машины.
  • EAX - флаг сообщения, например MB_OK.
  • ECX - 32-битный адрес строки-сообщения.
  • EDI - 32-битный адрес строки-заголовка.
  • ESI - адрес функции - реакции на действие пользователя. Если функции нет, тогда 0.
  • EDX - адрес данных, которые будут посылаться функции.


  • И еще, при выходе драйвер должен очищать флаг переноса. В нашем случае очистка флага переноса обусловлена правильным выполнением функции SHELL_Message.


    Содержание раздела