Содержимое файла 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 — вывести сообщение. Параметры хранятся в регистрах:
И еще, при выходе драйвер должен очищать флаг переноса. В нашем случае очистка флага переноса обусловлена правильным выполнением функции SHELL_Message.