مقدمة
استخدم Delphi 3.0 لكتابة برنامج تشغيل جهاز VxD. فهو يجمع ويمرر تحت Delphi 3. لا يوجد اختبار تحت Delphi 2. لا يمكن التعرف على ملف الكائن M$ Linker 5.12.8181 الذي تم إنشاؤه بواسطة Delphi 4. المجمع المستخدم هنا هو M$ إصدار Macro Assembler 6.11d، الرابط هو M$ Incremental Linker الإصدار 5.12.8181 ، فهي تأتي من Windows 98DDK (http://www.microsoft.com/ddk/ddk98.htm).
يقدم
هناك نوعان من برامج تشغيل أجهزة VxD لنظام التشغيل Windows:
1. VxD ثابت، يتم تحميله في نظام التشغيل وموجود بشكل دائم في الذاكرة؛
2. VxD الديناميكي، الذي يتم تحميله في الذاكرة عند الحاجة إليه. بعد الاستخدام، قم بإغلاق VxD لتحرير الذاكرة.
يتمتع InPRise Delphi بالقدرة على إنشاء أي نوع من برامج تشغيل أجهزة VxD. وسنقدم أدناه كيفية إنشاء VxD الديناميكي.
عندما يفتح تطبيق Win32 جهاز VxD "افتراضي"، يستخدم VWIN32 LoadDevice لتحميل VxD في الذاكرة ويقوم بإنشاء رسالة W32_DEVICEIOCONTROL ويرسلها إلى VxD.
وهذا يعني أن VxD يجب أن يستجيب على الأقل لرسالتي النظام التاليتين ويكتب إحدى الوظائف التالية:
SYS_DYNAMIC_DEVICE_INIT
SYS_DYNAMIC_DEVICE_EXIT
وظيفة W32_DEVICEIOCONTROL.
يتم إرسال الرسالة SYS_DYNAMIC_DEVICE_INIT إلى VxD عند محاولة تحميل VxD، ويتم إرسال الرسالة SYS_DYNAMIC_DEVICE_EXIT إلى VxD عند محاولة التبادل بشكل حيوي. يجب أن يقوم معالج الرسالة بإرجاع علامة VXD_SUCCESS في السجل AX بعد نجاح المعالجة.
تحتوي المعلمة dwService الخاصة بـ W32_DEVICEIOCONTROL على القيم التالية:
يتم إرسال DIOC_OPEN عندما يحاول VxD إجراء عملية مفتوحة من خلال الدالة CreateFile() (بعد الرسالة SYS_DYNAMIC_DEVICE_INIT)، ويقوم بإرجاع NO_ERROR (0) في حالة النجاح؛
يتم إرسال DIOC_CLOSEHANDLE عندما يحاول VxD إجراء عملية إغلاق عبر الدالة CloseHandle() (قبل SYS_DYNAMIC_DEVICE_EXIT)
كافة القيم الأخرى > 0 تعني استدعاء دالة مختلفة (يتم تقديمها بواسطة dwIoControlCode) عند استدعاء VxD بواسطة الدالة DeviceIoControl.
وحدة البدء (vxdmain.asm)
...
extrn SysDynamicDeviceInit:PROC
extrn SysDynamicDeviceExit:PROC
خارجي W32DeviceIoControl:PROC
...
DELPHIIO_DDB العام
عام@@التعامل مع النهاية
التهيئة العامة
...
Control_0 بروك
cmp eax، SYS_DYNAMIC_DEVICE_INIT
jnz قصير chkSysDynExit
استدعاء SysDynamicDeviceInit
سي إم بي إياكس، 1
retn
;------------
تشكسيدينيكسيت:
cmp eax، SYS_DYNAMIC_DEVICE_EXIT
jnz قصير chkDevIOCtl
استدعاء SysDynamicDeviceExit
سي إم بي إياكس، 1
retn
;-------------
chkDevIOCtl:
cmp eax، W32_DEVICEIOCONTROL
jnz قصير loc_ret
ادفع إيسي
ادفع إدكس
com.pushebx
com.pushecx
استدعاء W32DeviceIoControl
سي إم بي إياكس، 1
retn
;-------------
loc_ret:
clc
retn
Control_0 نهاية
@@التعامل مع النهاية:
@التهيئة:
متقاعد
_انتهى النص
نهاية
ستقوم دلفي باستدعاء الإجراءات الخارجية HandleFinaly والتهيئة للتهيئة/الانتهاء من الوحدة، حتى لو لم تكن التهيئة/الإنهاء موجودة في الوحدة. لذلك، نقوم بإنشاء إدخال إجراء خارجي فارغ في ملف بدء تشغيل التجميع.
وحدة برنامج دلفي الرئيسية (vxdProcs.pas)
...
إجراء ShellMessage(Handle, Flags: integer; const message, Caption: PChar;
رد الاتصال، البيانات المرجعية: المؤشر stdcall؛
asm
mov ebx، المقبض // مقبض الجهاز الظاهري
mov eax، الأعلام // أعلام مربع الرسالة
mov ecx، الرسالة // عنوان نص الرسالة
mov edi، تسمية توضيحية // عنوان نص التسمية التوضيحية
mov esi، رد الاتصال // عنوان رد الاتصال
mov edx، ReferenceData // البيانات المرجعية لرد الاتصال
int 20H // VxDCall
dd 170004h // Shell_Message
نهاية؛
الدالة SysDynamicDeviceInit: INTEGER;
يبدأ
ShellMessage(0, $10, Copyright, 'SysDynInit: مرحبًا من Delphi VxD !!!', nil, nil);
النتيجة := VXD_SUCCESS;
نهاية؛
الدالة SysDynamicDeviceExit: INTEGER;
يبدأ
ShellMessage(0, $10, Copyright, 'SysDynDevExit: وداعاً من Delphi VxD !!!', nil, nil);
النتيجة := VXD_SUCCESS;
نهاية؛
وظيفة W32DeviceIoControl(dwService: INTEGER;
dwDDB : عدد صحيح؛
hDevice: عدد صحيح؛
lpDIOCParms : المؤشر): عدد صحيح؛
يبدأ
ShellMessage(0, $10, Copyright, 'W32DevIOCtl', nil, nil);
إذا (dwService = DIOC_OPEN) إذن
يبدأ
النتيجة := NO_ERROR؛
نهاية
وإلا إذا (dwService = DIOC_CLOSEHANDLE) إذن
يبدأ
النتيجة := VXD_SUCCESS;
نهاية
وإلا إذا (dwService > MAX_PASVXD_W32_API) إذن
يبدأ
النتيجة := ERROR_NOT_SUPPORTED؛
نهاية
آخر
يبدأ
النتيجة := VXD_SUCCESS;
نهاية؛
نهاية؛
...
[المترجم: حسنًا، لقد تمت كتابة برنامج تشغيل جهاز VxD البسيط. يمكنك استخدامه كقالب لكتابة برامج تشغيل الأجهزة VxD. ]
الملحق 1: Make.bat
D:VISUAL~198DDKBINWin98ml -coff -DBLD_COFF -DIS_32 -W2 -c -Cx -Zm -DMASM6 vxdmain.asm
اتصل بـ dcc3.bat -J vxdprocs.pas
D:VISUAL~198DDKBINlink /DEF:vxddef.def /VXD vxdmain.obj vxdprocs /OUT:delphiio.vxd
الملحق 2:
الآن دعونا نكتب برنامج اختبار لـ VxD، باستخدام زرين: أحدهما لفتح VxD، والآخر لإغلاق VxD.
ثابت
VxDName = '/.DELPHIIO.VXD';
...
الدالة TVxDTestForm.OpenVxDDriver: منطقية؛
يبدأ
HVxDHandle := CreateFile(VxDName,0,0,nil,0,FILE_FLAG_DELETE_ON_CLOSE,0);
النتيجة: = HVxDHandle <> INVALID_HANDLE_VALUE؛
نهاية؛
الإجراء TVxDTestForm.CloseVxDDriver؛
يبدأ
إذا كان HVxDHandle <> INVALID_HANDLE_VALUE، فابدأ
CloseHandle(HVxDHandle);
HVxDHandle := INVALID_HANDLE_VALUE;
نهاية؛
نهاية