|  | ||||||||||||||||||||||||||||||
|   |  | 
 | 
 | |||||||||||||||||||||||||||
|  | ||||||||||||||||||||||||||||||
| 
 | 
 Пример создания 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 писать можно. Но вот только стоит ли? Ссылки по теме 
 |  | |||||||