全部博文(282)
分类: WINDOWS
2008-05-24 19:47:33
unit DDDK;
interface
const
NtKernel='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;
……
LIBRARY HAL.DLL
EXPORTS
ExAcquireFastMutex
ExReleaseFastMutex
ExTryToAcquireFastMutex
HalAcquireDisplayOwnership
HalAdjustResourceList
HalAllProcessorsStarted
……然后用LINK /LIB /MACHINE:IX86 /DEF:hal.def /OUT:hal.lib命令就可以生成我们需要的没有@xx 后缀的导入库文件了。有了这个文件,事情就好办多了。下面就让我们开始用delphi来开发一个简单的驱动程序beeper吧。
这个驱动程序是从Four-F的KmdKit里的beeper转换过来的,程序的目标就是通过访问端口让PC的扬声器发声,程序通过三种方法让扬声器发声,一种是直接访问端口,一种是调用hal.dll的READ_PORT_UCHAR和WRITE_PORT_UCHAR访问端口,第三种方法则是调用 hal.dll的HalMakeBeep函数。
代码:
unit beeper;
interface
uses windows, DDDK, hal;
function _DriverEntry(DriverObject:PDriverObject;RegistryPath:PUnicodeString):NTSTATUS; stdcall;
implementation
const
TIMER_FREQUENCY:DWORD = 1193167; {1,193,167 Hz}
OCTAVE:DWORD = 2; {octave multiplier}
PITCH_C:DWORD = 523; {C - 523,25 Hz}
PITCH_Cs:DWORD = 554; {C# - 554,37 Hz}
PITCH_D:DWORD = 587; {D - 587,33 Hz}
PITCH_Ds:DWORD = 622; {D# - 622,25 Hz}
PITCH_E:DWORD = 659; {E - 659,25 Hz}
PITCH_F:DWORD = 698; {F - 698,46 Hz}
PITCH_Fs:DWORD = 740; {F# - 739,99 Hz}
PITCH_G:DWORD = 784; {G - 783,99 Hz}
PITCH_Gs:DWORD = 831; {G# - 830,61 Hz}
PITCH_A:DWORD = 880; {A - 880,00 Hz}
PITCH_As:DWORD = 988; {B - 987,77 Hz}
PITCH_H:DWORD = 1047; {H - 1046,50 Hz}
{ We are going to play c-major chord }
DELAY:DWORD = $18000000; {for my ~800mHz 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; assembler;
asm
cli
mov al, 10110110b
out 43h, al
mov eax, dwPitch
out 42h, al
mov al, ah
out 42h, al
{Turn speaker ON}
in al, 61h
or al, 11b
out 61h, al
sti
push eax
mov eax, DELAY
@@1:
dec eax
jnz @@1
pop eax
cli
{Turn speaker OFF}
in al, 61h
and al, 11111100b
out 61h, 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.
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.