Определение виртуального драйвера
Исходный текст каждого виртуального драйвера должен содержать так называемое определение драйвера. Для того чтобы определить виртуальный драйвер, в начале исходного текста следует разместить вызов макрокоманды Declare_Virtual_Device, имеющей несколько параметров (до девяти).
Параметры разделяются запятыми, причем можно указывать не все параметры:
Declare_Virtual_Device VXDSRV, HiVers, LoVers, \ VXDSRV_Control, VXDSRV_Id, Undefined_Init_Order, \ VXDSRV_V86API_Handler, VXDSRV_PMAPI_Handler,
Макрокоманда Declare_Virtual_Device создает блок описания устройства DDB.
Первый параметр макрокоманды определяет имя виртуального устройства (т. е. имя виртуального драйвера). В приведенном выше примере виртуальный драйвер имеет имя VXDSRV.
Второй и третий параметры указывают старший и младший номер версии драйвера, соответственно. Здесь вы можете использовать целые числа или символические константы, определенные оператором equ. В нашем случае мы использовали символические константы HiVers и LoVers, которые соответствуют версии 1.1:
HiVers equ 1 ; верхний номер версии драйвера LoVers equ 1 ; нижний номер версии драйвера
Четвертый параметр представляет собой метку управляющей точки входа виртуального драйвера, т. е. FLAT-адрес управляющей процедуры. Управляющая процедура вызывается при возникновении ряда событий в системе. В частности, эта точка получает управление несколько раз на различных стадиях инициализации драйвера. В нашем примере указана процедура VXDSRV_Control, которая будет описана позже:
BeginProc VXDSRV_Control Control_Dispatch Sys_Critical_Init, VXDSRV_Sys_Crit_Init clc ret EndProc VXDSRV_Control
Пятый параметр - идентификатор виртуального драйвера. Это число вы должны получить от фирмы Microsoft, послав запрос в произвольной форме через электронную почту по адресу vxdid@microsoft.com. В ответ на этот запрос вам придет бланк, который нужно заполнить и отправить обратно по тому же адресу. После этого через пару недель вы получите идентификатор.
Каждый виртуальный драйвер, предоставляющий сервис приложениям Windows и программам, работающим в среде виртуальных машин MS-DOS, должен иметь свой собственный идентификатор, отличный от идентификаторов других виртуальных драйверов.
В противном случае возможен конфликт идентификаторов, который приведет к ошибке при загрузке виртуального драйвера. Использование идентификатора, полученного у Microsoft, гарантирует отсутствие конфликта с другими зарегистрированными виртуальными драйверами.
Если ваш драйвер не предоставляет никакого сервиса, ему не нужен идентификатор. В этом случае в качестве пятого параметра можно указать значение Undefined_Device_ID, определенное в файле vmm.inc.
С помощью шестого параметра можно указать порядок выполнения инициализации данного драйвера по отношению к другим виртуальным драйверам. Дело в том, что на этапе инициализации ваш виртуальный драйвер может пользоваться сервисом, предоставляемым другими виртуальными драйверами. Последние на момент инициализации вашего драйвера должны быть уже проинициализированы.
В нашем примере порядок инициализации не имеет значения, поэтому мы указали константу Undefined_Init_Order, определенную в файле vmm.inc.
В том случае, когда ваш драйвер предоставляет сервис приложениям Windows или программам, запущенным в среде виртуальной машины MS-DOS, необходимо указывать седьмой и восьмой параметры. Это точки входа процедур, получающих управление при вызове драйвера для получения сервиса.
Седьмой параметр определяет адрес процедуры, которая вызывается при обращении к драйверу из виртуальной машины MS-DOS, восьмой - из приложения Windows. В нашем примере указаны адреса процедур VXDSRV_V86API_Handler и VXDSRV_PMAPI_Handler (седьмой и восьмой параметры, соответственно).
И, наконец, девятый параметр предназначен для создания структуры, обеспечивающей предоставление вашим драйвером сервиса для других виртуальных драйверов. В нашей книге из-за недостатка места мы не будем рассматривать такую возможность, оставив ее вам на самостоятельное изучение.
После макрокоманды определения виртуального драйвера в исходном тексте следует расположить все необходимые сегменты кода и данных, к описанию которых мы и переходим.