|
|
|||||||||||||||||||||||||||||
|
Пример создания VxD-драйвера на Delphi (исходники)Компиляция данного примера возможна только с Delphi 3. Delphi 2 не был опробован в связи с его отсутствием, объектные фалы созданные Delphi 4 отвергаются Microsoft Linker 5.12.8181 как файлы неизвестного формата. Введение VxD драйвера делятся два типа:
Практически возможно создание драйвера поддерживающего оба типа загрузки. Нам необходим динамически загружаемый VxD драйвер (далее "VxD") т.к. такой драйвер можно будет без перезагрузки Windows загружать из Win32® приложений используя процедуру CreateFile(). Таким образом для построения VxD необходимо обрабатывать как минимум три системных сообщения:
Собщение SYS_DYNAMIC_DEVICE_INIT посылается при попытке динамической загрузки VxD, SYS_DYNAMIC_DEVICE_EXIT посылается при попытке динамической выгрузке. Из обработчиков сообщений для подтверждения успеха необходимо вернуть VXD_SUCCESS в регистре AX
Загрузочный модуль (vxdmain.asm) При обращении к процедурам находящимся в модулях Delphi надо учесть для fastcall-процедур к имени добавляется в начале символ "@" ... extrn SysDynamicDeviceInit :PROC extrn SysDynamicDeviceExit :PROC extrn W32DeviceIoControl :PROC ... Control_0 proc cmp eax, SYS_DYNAMIC_DEVICE_INIT jnz short chkSysDynExit call SysDynamicDeviceInit cmp eax, 1 retn ;------------- chkSysDynExit: cmp eax, SYS_DYNAMIC_DEVICE_EXIT jnz short chkDevIOCtl call SysDynamicDeviceExit cmp eax, 1 retn ;------------- chkDevIOCtl: cmp eax, W32_DEVICEIOCONTROL jnz short loc_ret push esi push edx push ebx push ecx call W32DeviceIoControl cmp eax, 1 retn ;------------- loc_ret: clc retn Control_0 endp ... Delphi создает код для инициализации/деинициализации модулей, обращаясь к внешним процедурам HandleFinaly и initialization даже если блоки initilization и finalization в модуле отсутствуют. Создадим пустую "заглушку" для этих процедур и объявим их доступными для внешних модулей. ...
Public @@HandleFinally
Public @initialization
...
@@HandleFinally:
@initialization:
ret
...
end.
Процедурный модуль (vxdProcs.pas)
procedure ShellMessage(Handle, Flags : integer;
const Message, Caption : PChar;
Callback, ReferenceData : pointer); stdcall; assembler;
asm
mov ebx, Handle // virtual machine handle
mov eax, Flags // message box flags
mov ecx, Message // address of message text
mov edi, Caption // address of caption text
mov esi, Callback // address of callback
mov edx, ReferenceData // reference data for callback
int 20H // VxDCall
dd 170004h // Shell_Message
end;
const
Copyright : PChar = '(c) 1999 Emil Biserov, '+
'fatty@mail.primorye.ru, http://dinfo.da.ru';
function SysDynamicDeviceInit : INTEGER;
begin
ShellMessage(0, $10, Copyright,
'SysDynInit: Hello from Delphi VxD !!!', nil, nil);
Result := VXD_SUCCESS;
end;
function SysDynamicDeviceExit : INTEGER;
begin
ShellMessage(0, $10, Copyright,
'SysDynDevExit: Bye from Delphi VxD !!!', nil, nil);
Result := VXD_SUCCESS;
end;
var
Str : array [0..16] of char;
function W32DeviceIoControl(dwService : INTEGER;
dwDDB : INTEGER;
hDevice : INTEGER;
lpDIOCParms : pointer) : INTEGER;
begin
ShellMessage(0, $10, Copyright, 'W32DevIOCtl', nil, nil);
if (dwService = DIOC_OPEN) then
begin
Result := NO_ERROR;
end
//
//
else if (dwService = DIOC_CLOSEHANDLE) then
begin
Result := VXD_SUCCESS;
end
else if (dwService > MAX_PASVXD_W32_API) then
begin
Result := ERROR_NOT_SUPPORTED;
end
else
begin
Result := VXD_SUCCESS;
end;
end;
Инструмент для загрузки/выгрузки VxD
Представляет из себя простую форму с двумя кнопками. Приведу лишь методы для открытия и закрытия VxD драйвера. const VxDName = '\\.\DELPHIIO.VXD'; ... function TVxDTestForm.OpenVxDDriver: boolean; begin HVxDHandle := CreateFile(VxDName,0,0,nil,0,FILE_FLAG_DELETE_ON_CLOSE,0); Result := HVxDHandle <> INVALID_HANDLE_VALUE; end; procedure TVxDTestForm.CloseVxDDriver; begin if HVxDHandle <> INVALID_HANDLE_VALUE then begin CloseHandle(HVxDHandle); HVxDHandle := INVALID_HANDLE_VALUE; end; end; Выгрузку неиспользуемого модуля можно производить автоматически, указав в параметрах CreateFile(,,,,,FILE_FLAG_DELETE_ON_CLOSE,). В данном случае система при каждом открытии дескриптора к VxD будет увеличивать внутренний счетчик использования на 1 и вычитать 1 при закрытии дескриптора. При значении счетчика равном нулю VxD будет автоматически выгружен. Выводы
Драйвера на Delphi писать можно. Но вот только стоит ли? Ссылки по теме
|
|
|||||||