Приклад створення VxD-драйвера на Delphi (исходники), Різне, Програмування, статті

Компіляція даного прикладу можливий лише з Delphi 3. Delphi 2 не був випробуваний у зв’язку з його відсутністю, об’єктні фали створені Delphi 4 відкидаються Microsoft Linker 5.12.8181 як файли невідомого формату.
При написанні цього матеріалу було використано Microsoft Macro Assembler ver. 6.11d і Microsoft Incremental Linker ver. 5.12.8181 з поставки Windows 98DDK


Введення


VxD драйвера діляться два типи:


Практично можливе створення драйвера підтримує обидва типи завантаження.

Нам необхідний динамічно завантажуваний VxD драйвер (далі “VxD”) тому такий драйвер можна буде без перезавантаження Windows завантажувати з Win32 ® додатків використовуючи процедуру CreateFile().
Коли Win32 додаток відкриває дескриптор для VxD, віртуальне пристрій VWIN32 використовуючи сервіс LoadDevice завантажує VxD-драйвер в пам’ять і посилає інформаційне повідомлення W32_DEVICEIOCONTROL завантаженому VxD.


Таким чином для побудови VxD необхідно обробляти як мінімум три системні повідомлення:



, Повідомлення SYS_DYNAMIC_DEVICE_INIT посилається при спробі динамічного завантаження VxD, SYS_DYNAMIC_DEVICE_EXIT посилається при спробі динамічної вивантаженні. З обробників повідомлень для підтвердження успіху необхідно повернути VXD_SUCCESS в регістрі AX
Повідомлення W32_DEVICEIOCONTROL має наступні значення для параметра dwService



Завантажувальний модуль (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 писати можна. Але от тільки чи варто?
Використання VxD має сенс тільки для використання Windows 3.1 і Windows 95. Та й доступ до апаратних ресурсів в них набагато прозоріше ніж Windows NT/2000. Windows 98, Windows NT і Windows2000 підтримують нову модель драйверів WDM 1.0/2.0, що використовує формат PE (Portable Executable) і (приблизно) проблем буде менше, ніж з VxD і його LE (Linear Executable) форматом драйверів.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*