[Lazarus] RE : Read Windows EventLog...
Ludo Brands
ludo.brands at free.fr
Sat Sep 10 20:32:23 CEST 2011
>
> Hello team
>
> Somebody know how read from Windows EventLog with Free Pascal
> and Lazarus?
>
> Liyuan
>
>
A quick and dirty program:
program dumpEventLog;
uses windows,sysutils,classes;
procedure geteventlog(const provider: string; var sl:TStringList) ;
var hnd:HANDLE;
lpBuffer: Pointer;
pnBytesRead, pnMinNumberOfBytesNeeded: DWORD;
pRecord: PEVENTLOGRECORD;
eventtype,sdate,computer,source,data:string;
user,domain:array [0..255] of char;
userlen,domlen:dword;
datestart:TDateTime;
peUse: SID_NAME_USE;
p:pchar;
i:integer;
begin
hnd:=OpenEventLog(nil,pchar(provider));
if hnd<>0 then
begin
datestart:=EncodeDate(1970,1,1);
getmem(lpbuffer,$10000);
while ReadEventLog(hnd,EVENTLOG_SEQUENTIAL_READ or
EVENTLOG_BACKWARDS_READ, 0,
lpBuffer, $10000, pnBytesRead, pnMinNumberOfBytesNeeded) do
begin
pRecord:=lpBuffer;
while pRecord< lpBuffer+pnBytesRead do
begin
case pRecord^.EventType of
EVENTLOG_ERROR_TYPE :eventtype:='Error';
EVENTLOG_WARNING_TYPE :eventtype:='Warning';
EVENTLOG_INFORMATION_TYPE :eventtype:='Information';
EVENTLOG_AUDIT_SUCCESS :eventtype:='Audit Success';
EVENTLOG_AUDIT_FAILURE :eventtype:='Audit Failure';
end;
sdate:=DateTimeToStr(datestart+pRecord^.TimeGenerated/24/3600);
if pRecord^.UserSidLength=0 then
begin
user:='N/A';
domain:='N/A';
end
else
begin
userlen:=256;
domlen:=256;
LookUpAccountSID(Nil,PSID(pointer(pRecord)+pRecord^.UserSidOffset),user,user
len,domain,domlen,peUse);
end;
source:=pchar(PSID(pointer(pRecord)+sizeof(TEventLogRecord)));
computer:=pchar(PSID(pointer(pRecord)+sizeof(TEventLogRecord)+length(source)
+1));
data:='';
p:=pchar(pointer(pRecord)+pRecord^.StringOffset);
for i:=1 to pRecord^.NumStrings do
begin
data:=data+p+';';
p:=p+strlen(p)+1;
end;
sl.Add(format('Number: %d Date: %s ID: %d Type: %s Category: %d
User: %s Domain: %s Computer: %s Source %s Data: %s',
[pRecord^.RecordNumber,sdate,pRecord^.EventID and $FFFF ,
eventtype ,pRecord^.EventCategory ,
user,domain,computer,source,data]));
pRecord:=PEVENTLOGRECORD(pointer(pRecord)+pRecord^.Length);
end;
end;
freemem(lpbuffer);
CloseEventLog(hnd);
end;
end;
var
sl:TStringList;
i:integer;
begin
sl:=TStringList.create;
geteventlog('Security',sl);
for i:=0 to sl.Count-1 do
writeln(sl[I]);
sl.destroy;
end.
Change Security to Application to System or ... to get the other logs.
This program just dumps the data strings unformated. To get the nice error
message as displayed in the event viewer, quite some more work is needed.
The data in the eventlog are just the variable parts in a formatted string.
To get the format string you need to take the source of the event (say
crypt32 in the Application log), read the registry value
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application\cr
ypt32\EventMessageFile which is the filename of a dll, load that library,
lookup the resource with ID EventID and substitute the data in the format
string.
Ludo
More information about the Lazarus
mailing list