คำนำ
ใช้ Delphi 3.0 เพื่อเขียนไดรเวอร์อุปกรณ์ VxD โดยคอมไพล์และส่งผ่านภายใต้ Delphi 3 ไม่มีการทดสอบภายใต้ Delphi 2 ไฟล์ Object M$ Linker 5.12.8181 ที่สร้างโดย Delphi 4 ไม่ได้รับการยอมรับ แอสเซมเบลอร์ที่ใช้ที่นี่คือ M$ Macro Assembler เวอร์ชัน 6.11d ตัวเชื่อมโยงคือ M$ Increamental Linker เวอร์ชัน 5.12.8181 ซึ่งมาจาก Windows 98DDK (http://www.microsoft.com/ddk/ddk98.htm)
แนะนำ
มีไดรเวอร์อุปกรณ์ VxD สองประเภทสำหรับ Windows:
1. VxD แบบคงที่ โหลดเข้าสู่ระบบปฏิบัติการและมีอยู่ในหน่วยความจำอย่างถาวร
2. Dynamic 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) เมื่อฟังก์ชัน DeviceIoControl เรียก VxD
โมดูลสตาร์ท (vxdmain.asm)
-
extrn SysDynamicDeviceInit:PROC
extrn SysDynamicDeviceExit:PROC
ภายนอก W32DeviceIoControl:PROC
-
สาธารณะ DELPHIIO_DDB
สาธารณะ @@HandleFinally
สาธารณะ @การเริ่มต้น
-
กระบวนการ Control_0
cmp eax, SYS_DYNAMIC_DEVICE_INIT
jnz สั้น chkSysDynExit
เรียก SysDynamicDeviceInit
ซีเอ็มพี อีเอ็กซ์, 1
อีกครั้ง
-
chkSysDynทางออก:
cmp eax, SYS_DYNAMIC_DEVICE_EXIT
jnz สั้น chkDevIOCtl
เรียก SysDynamicDeviceExit
ซีเอ็มพี อีเอ็กซ์, 1
อีกครั้ง
-
chkDevIOCtl:
cmp eax, W32_DEVICEIOCONTROL
jnz สั้น loc_ret
ดันอีซี่
ดัน edx
pushebx
พุชเทคx
เรียก W32DeviceIoControl
ซีเอ็มพี อีเอ็กซ์, 1
อีกครั้ง
-
loc_ret:
ซีแอลซี
อีกครั้ง
Control_0 สิ้นสุด
@@จัดการในที่สุด:
@การเริ่มต้น:
เกษียณ
_LTEXT สิ้นสุด
จบ
Delphi จะเรียกขั้นตอนภายนอก HandleFinaly และการกำหนดค่าเริ่มต้นสำหรับการเริ่มต้น/ขั้นสุดท้ายของหน่วย แม้ว่าจะไม่มีการกำหนดค่าเริ่มต้น/ขั้นสุดท้ายในหน่วยก็ตาม ดังนั้นเราจึงสร้างรายการขั้นตอนภายนอกที่ว่างเปล่าในไฟล์เริ่มต้นแอสเซมบลี
หน่วยโปรแกรมหลักของ Delphi (vxdProcs.pas)
-
ขั้นตอน ShellMessage (ตัวจัดการ, แฟล็ก: จำนวนเต็ม; ข้อความ const, คำบรรยาย: PChar;
โทรกลับ ReferenceData : ตัวชี้ stdcall;
asm
mov ebx, Handle // ตัวจัดการเครื่องเสมือน
mov eax, Flags // ธงกล่องข้อความ
mov ecx, ข้อความ // ที่อยู่ของข้อความ
mov edi, คำบรรยายภาพ // ที่อยู่ของข้อความคำบรรยาย
mov esi, โทรกลับ // ที่อยู่ของการโทรกลับ
mov edx, ReferenceData // ข้อมูลอ้างอิงสำหรับการโทรกลับ
int 20H // VxDCall
dd 170004h // Shell_Message
จบ;
ฟังก์ชั่น SysDynamicDeviceInit: INTEGER;
เริ่ม
ShellMessage (0, $ 10, ลิขสิทธิ์, 'SysDynInit: สวัสดีจาก Delphi VxD !!!', ไม่มี, ไม่มี);
ผลลัพธ์ := VXD_SUCCESS;
จบ;
ฟังก์ชั่น SysDynamicDeviceExit: INTEGER;
เริ่ม
ShellMessage (0, $ 10, ลิขสิทธิ์, 'SysDynDevExit: ลาก่อนจาก Delphi VxD !!!', ไม่มี, ไม่มี);
ผลลัพธ์ := VXD_SUCCESS;
จบ;
ฟังก์ชั่น W32DeviceIoControl (dwService : INTEGER;
dwDDB : จำนวนเต็ม;
อุปกรณ์: INTEGER;
lpDIOCParms : ตัวชี้) : INTEGER;
เริ่ม
ShellMessage(0, $10, ลิขสิทธิ์, 'W32DevIOCtl', ไม่มี, ไม่มี);
ถ้า (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~198DDKBINลิงก์ /DEF:vxddef.def /VXD vxdmain.obj vxdprocs /ออก:delphiio.vxd
ภาคผนวก 2:
ตอนนี้เรามาเขียนโปรแกรมทดสอบสำหรับ VxD โดยมีปุ่มสองปุ่ม: ปุ่มหนึ่งสำหรับเปิด VxD; ปุ่มหนึ่งสำหรับปิด VxD
ค่าคงที่
VxDName = '/.DELPHIIO.VXD';
-
ฟังก์ชั่น TVxDTestForm.OpenVxDDriver: บูลีน;
เริ่ม
HVxDHandle := CreateFile(VxDName,0,0,ไม่มี,0,FILE_FLAG_DELETE_ON_CLOSE,0);
ผลลัพธ์ := HVxDHandle <> INVALID_HANDLE_VALUE;
จบ;
ขั้นตอน TVxDTestForm.CloseVxDDriver;
เริ่ม
ถ้า HVxDHandle <> INVALID_HANDLE_VALUE ให้เริ่มต้น
มือจับปิด(HVxDHandle);
HVxDHandle := INVALID_HANDLE_VALUE;
จบ;
จบ