Whether Delphi can develop a Windows Driver (the driver here does not refer to VxD ^_^) has always been a concern of the majority of Delphi fans. Let's stop talking about whether the driver can be used or not. Let's take a look at the technical issues that need to be addressed when developing the driver with Delphi.
Delphi's linker cannot generate Windows kernel-mode programs. Therefore, you cannot directly generate drivers using Delphi. M $'s linker can generate Windows Kernel Mode programs. Can I use Delphi to generate the target file and then use M $ to link it? To do so, you must solve the following problems:
The target file generated by Delphi is in The OMF format. Although M $ link claims to support the target file in the OMF format, it is useless. It is best to convert the OMF format to the coff format. elicz's omf2d can solve this problem. Solved the target format problem. Is everything OK? It's far from that simple. Before proceeding, let's take a look at the famous dddk.
Dddk (Delphi driver development kit) is a tool kit for developing Windows drivers using Delphi released by the hacker defender project team. The latest version is 0.0.4. Dddk uses Delphi to package frequently-used driver APIs in the dddk unit, as shown below:
Code:
Unit dddk;
Interface
Const
Ntkernelpolic'ntoskrnl.exe ';
......
Procedure iocompleterequest (IRP: pirp; priorityboost: integer); stdcall;
......
Implementation
Procedure krnliocompleterequest (IRP: pirp; priorityboost: integer); stdcall; External ntkernel name 'iocompleterequest ';
Procedure iocompleterequest (IRP: pirp; priorityboost: integer); stdcall;
Begin
Krnliocompleterequest (IRP, priorityboost );
End;
......
Before linking the driver file, use omf2d to perform the following operations on the driver API to be introduced in dddk. OBJ:
Omf2d Inc \ dddk. OBJ/U-/ceiocompleterequest = _ iocompleterequest @ 8 2> NUL changes iocompleterequest in dddk. OBJ to _ iocompleterequest @ 8. Why? This is because import and export operations such as ntoskrnl. Lib are in coff format, and the coff format is named like this. After completing this step, you can call M $ link to link the target file to the driver file.
This can generate the correct driver file, but the disadvantage is obvious. The driver API is packaged in Delphi. These functions packaged in Delphi are linked to the final generated driver file regardless of whether they are used. This increases the size of the driver file, besides, the efficiency of calling the driver API through the encapsulated function of Delphi is also affected, and omf2d Inc \ dddk is used before each link. OBJ/U-/ceiocompleterequest = _ iocompleterequest @ 8 to convert the target file of Delphi, which is both troublesome and error-prone. Is there a better way?
Omf2d converts the Delphi naming method to the coff _ xxxxxxx @ XX format. By default, omf2d removes the leading underline and the @ XX suffix, you can use the/U _ * switch so that omf2d does not delete the leading underline. If we do not have the @ XX suffix to import the database, the problem is much simpler. However, M $ does not provide the import/export function without the @ XX suffix. Let's make it by ourselves ^ _ ^, which is actually very simple. For example, we want to generate Hal. DLL import library, you only need to edit a Hal of the following content. def file:
Code:
Library Hal. dll
Exports
Exacquirefastmutex
Exreleasefastmutex
Extrytoacquirefastmutex
Halacquiredisplayownership
Haladjustresourcelist
Halallprocessorsstarted
......
Then, run the link/lib/machine: ix86/DEF: Hal. DEF/out: Hal. Lib command to generate the imported and exported file without the @ XX suffix. With this file, it will be much easier to handle. Let's start using Delphi to develop a simple driver beeper.
This driver is converted from beeper in the kmdkit of Four-F. The program aims to make the PC speaker speak through the access port, and the program uses three methods to make the speaker speak, one is direct access port, and the other is calling Hal. the read_port_uchar and write_port_uchar access ports of DLL. The third method is to call Hal. the halmakebeep function of DLL.
Code:
Unit beeper;
Interface
Uses Windows, dddk, Hal;
Function _ DriverEntry (driverobject: pdriverobject; registrypath: punicodestring): ntstatus; stdcall;
Implementation
Const
Timer_frequency: DWORD = 1193167; {1,193,167Hz}
Ave ave: DWORD = 2; {octave multiplier}
Pitch_c: DWORD = 523; {C-523,25Hz}
Pitch_cs: DWORD = 554; {C #-554,37Hz}
Pitch_d: DWORD = 587; {d-587,33Hz}
Pitch_ds: DWORD = 622; {d #-622,25Hz}
Pitch_e: DWORD = 659; {e-659,25Hz}
Pitch_f: DWORD = 698; {f-698, 46 HZ}
Pitch_fs: DWORD = 740; {f #-739,99Hz}
Pitch_g: DWORD = 784; {G-783,99Hz}
Pitch_gs: DWORD = 831; {G #-830,61Hz}
Pitch_a: DWORD = 880; {A-880, 00Hz}
Pitch_as: DWORD = 988; {B-987,77Hz}
Pitch_h: DWORD = 1047; {H-keys 6, 50Hz}
{We are going to play C-major chord}
Delay: DWORD = $18000000; {for my ~ 800 MHz box}
Tone_1: DWORD = 1141;
Tone_2: DWORD = 905;
Tone_3: DWORD = 1568; {for halmakebeep}
Status_device_configuration_error: DWORD = $00c0000182;
Procedure makebeep1 (dwpitch: DWORD); stdcall; Cycler;
ASM
CLI
MoV Al, 10110110b
Out 43 H, Al
MoV eax, dwpitch
Out 42 h, Al
MoV Al, ah
Out 42 h, Al
{Turn speaker on}
In Al, 61 H
Or Al, 11b
Out 61 H, Al
STI
Push eax
MoV eax, delay
@ 1:
Dec eax
Jnz @ 1
Pop eax
CLI
{Turn speaker off}
In Al, 61 H
And Al, 11111100b
Out 61 H, Al
STI
End;
Procedure makebeep2 (dwpitch: DWORD); stdcall;
VaR
Dwport, I: DWORD;
Begin
ASM
CLI;
End;
Write_port_uchar (puchar ($43), $ B6 );
Write_port_uchar (puchar ($42), dwpitch and $ ff );
Write_port_uchar (puchar ($42), (dwpitch SHR 8) and $ ff ));
Dwport: = read_port_uchar (puchar ($61 ));
Dwport: = dwport or 3;
Write_port_uchar (puchar ($61), dwport );
ASM
STI
End;
For I: = 1 to delay do
Begin
End;
ASM
CLI
End;
{Turn speaker off}
Dwport: = read_port_uchar (puchar ($61 ));
Dwport: = dwport and $ FC;
Write_port_uchar (puchar ($61), dwport );
ASM
STI
End;
End;
Function _ DriverEntry (driverobject: pdriverobject; registrypath: punicodestring): ntstatus; stdcall;
VaR
I: integer;
Begin
Makebeep1 (tone_1 );
Makebeep2 (tone_2 );
Halmakebeep (tone_3 );
For I: = 1 to delay do
Begin
End;
Halmakebeep (0 );
Result: = status_device_configuration_error;
End;
End.
Code: Unit Hal;
Interface
Uses
Windows;
Const
Nthal = 'hal. dll ';
Function halmakebeep (frequency: ulong): Boolean; stdcall;
Function read_port_uchar (Port: puchar): uchar; stdcall;
Procedure write_port_uchar (Port: puchar; Value: uchar); stdcall;
Implementation
Function halmakebeep (frequency: ulong): Boolean; stdcall; External nthal name '_ halmakebeep ';
Function read_port_uchar (Port: puchar): uchar; stdcall; External nthal name '_ read_port_uchar ';
Procedure write_port_uchar (Port: puchar; Value: uchar); stdcall; External nthal name '_ write_port_uchar ';
End.
1. use dcc32-u .. \ include-B-Cg-JP-$ A-, C-, D-, G-, H-, I-, L-, p-, V-, W +, y-beeper. PAS generates the target file (here .. \ Inc is the directory for storing the relevant Delphi unit files. You may not be using this directory)
2. Use omf2d beeper. OBJ/U _ * to convert the target file to be linked by M $ link.
3. use link/nologo/align: 32/base: 0x10000/subsystem: Native/driver/Force: unresolved/Force: Multiple/entry: DriverEntry .. \ Lib \ Hal. lib beeper. OBJ/out: beeper. sys generates the Final Driver file. (Note that/Force: unresolved is used here because dcc32 will add some unit initialization and destruction code to the Delphi target file, which are not required in the driver, therefore, a bunch of link warnings will also appear when you forcibly ignore them ).
After performing the preceding steps, a beeper. SYS file is generated in your directory. Copy it to the beeper directory of kmdkit and load it with its SCP file. The PC's speakers make a clear sound, proving that our Delphi driver is correct. Beeper generated using this method. sys is only 1376 bytes, only better than the beeper using kmdkit assembly code. sys is several hundred bytes in size, and the beeper generated by dddk is used. sys must exceed 3 K.
It is really not easy to write so many words. This tutorial is here. In the next article, we will use Delphi to create a more interesting stuff.
Author: mickeylan to: http://bbs.pediy.com/showthread.php? T = 57762