![]() |
Библиотека Интернет Индустрии I2R.ru |
||
Пример создания VxD-драйвера на DelphiОбщая информация Компиляция данного примера возможна только с Delphi 3.
Delphi 2 не был опробован в связи с его отсутствием, объектные фалы
созданные Delphi 4 отвергаются Microsoft R Linker 5.12.8181 как файлы
неизвестного формата. Введение VxD драйвера делятся два типа:
Нам необходим динамически загружаемый VxD драйвер (далее "VxD") т.к.
такой драйвер можно будет без перезагрузки Windows загружать из Win32R
приложений используя процедуру 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, '+
'[email protected], 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 писать можно. Но вот только стоит
ли? Emil Biserov |
|
| 2000-2008 г. Все авторские права соблюдены. |