3
** Copyright (C) 2000-2005 SIA Zabbix
5
** This program is free software; you can redistribute it and/or modify
6
** it under the terms of the GNU General Public License as published by
7
** the Free Software Foundation; either version 2 of the License, or
8
** (at your option) any later version.
10
** This program is distributed in the hope that it will be useful,
11
** but WITHOUT ANY WARRANTY; without even the implied warranty of
12
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
** GNU General Public License for more details.
15
** You should have received a copy of the GNU General Public License
16
** along with this program; if not, write to the Free Software
17
** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
#if defined (_WINDOWS)
27
#define MAX_INSERT_STRS 64
28
#define MAX_MSG_LENGTH 1024
30
/* open event logger and return number of records */
31
static long zbx_open_eventlog(
33
HANDLE *eventlog_handle,
38
assert(eventlog_handle);
40
assert(pLatestRecord);
45
*eventlog_handle = OpenEventLog(NULL, source); /* open log file */
47
if (!*eventlog_handle) return GetLastError();
49
GetNumberOfEventLogRecords(*eventlog_handle,(unsigned long*)pNumRecords); /* get number of records */
50
GetOldestEventLogRecord(*eventlog_handle,(unsigned long*)pLatestRecord);
55
/* close event logger */
56
static long zbx_close_eventlog(HANDLE eventlog_handle)
58
if (eventlog_handle) CloseEventLog(eventlog_handle);
63
/* get Nth error from event log. 1 is the first. */
64
static long zbx_get_eventlog_message(
66
HANDLE eventlog_handle,
70
unsigned short *out_severity,
71
unsigned long *out_timestamp
74
EVENTLOGRECORD *pELR = NULL;
75
BYTE bBuffer[1024]; /* hold the event log record raw data */
76
DWORD dwRead, dwNeeded;
77
char stat_buf[MAX_PATH];
78
char MsgDll[MAX_PATH]; /* the name of the message DLL */
82
HINSTANCE hLib = NULL; /* handle to the messagetable DLL */
83
char *pCh = NULL, *pFile = NULL, *pNextFile = NULL;
84
char *aInsertStrs[MAX_INSERT_STRS]; /* array of pointers to insert */
86
LPTSTR msgBuf = NULL; /* hold text of the error message that we */
92
assert(out_timestamp);
99
if (!eventlog_handle) return(0);
101
if(!ReadEventLog(eventlog_handle, /* event-log handle */
102
EVENTLOG_SEEK_READ | /* read forward */
103
EVENTLOG_FORWARDS_READ, /* sequential read */
104
which, /* which record to read 1 is first */
105
bBuffer, /* address of buffer */
106
sizeof(bBuffer), /* size of buffer */
107
&dwRead, /* count of bytes read */
108
&dwNeeded)) /* bytes in next record */
110
return GetLastError();
113
pELR = (EVENTLOGRECORD*)bBuffer; /* point to data */
115
*out_severity = pELR->EventType; /* return event type */
116
*out_timestamp = pELR->TimeGenerated; /* return timestamp */
118
*out_source = strdup((char*)pELR + sizeof(EVENTLOGRECORD)); /* copy source name */
122
if( source && *source )
124
/* Get path to message dll */
125
zbx_snprintf(stat_buf, sizeof(stat_buf),
126
"SYSTEM\\CurrentControlSet\\Services\\EventLog\\%s\\%s",
133
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, stat_buf, 0, KEY_READ, &hk) == ERROR_SUCCESS)
136
Data = sizeof(stat_buf);
138
err = RegQueryValueEx(
139
hk, /* handle of key to query */
140
"EventMessageFile", /* value name */
141
NULL, /* must be NULL */
142
&Type, /* address of type value */
143
(UCHAR*)pFile, /* address of value data */
144
&Data); /* length of value data */
148
if(err != ERROR_SUCCESS)
154
while(pFile && FAIL == err)
156
pNextFile = strchr(pFile,';');
163
if (ExpandEnvironmentStrings(pFile, MsgDll, MAX_PATH))
165
hLib = LoadLibraryEx(MsgDll, NULL, LOAD_LIBRARY_AS_DATAFILE);
168
/* prepare the array of insert strings for FormatMessage - the
169
insert strings are in the log entry. */
171
i = 0, pCh = (char *)((LPBYTE)pELR + pELR->StringOffset);
172
i < pELR->NumStrings && i < MAX_INSERT_STRS;
173
i++, pCh += strlen(pCh) + 1) /* point to next string */
175
aInsertStrs[i] = pCh;
178
/* Format the message from the message DLL with the insert strings */
180
FORMAT_MESSAGE_FROM_HMODULE |
181
FORMAT_MESSAGE_ALLOCATE_BUFFER |
182
FORMAT_MESSAGE_ARGUMENT_ARRAY |
183
FORMAT_MESSAGE_FROM_SYSTEM,
184
hLib, /* the messagetable DLL handle */
185
pELR->EventID, /* message ID */
186
MAKELANGID(LANG_NEUTRAL, SUBLANG_ENGLISH_US), /* language ID */
187
(LPTSTR) &msgBuf, /* address of pointer to buffer for message */
188
MAX_MSG_LENGTH, /* maximum size of the message buffer */
189
aInsertStrs); /* array of insert strings for the message */
193
*out_message = strdup(msgBuf); /* copy message */
195
/* Free the buffer that FormatMessage allocated for us. */
196
LocalFree((HLOCAL) msgBuf);
210
i = 0, pCh = (char *)((LPBYTE)pELR + pELR->StringOffset);
211
i < pELR->NumStrings && i < MAX_INSERT_STRS;
212
i++, pCh += strlen(pCh) + 1) /* point to next string */
215
*out_message = zbx_strdcat(*out_message, pCh);
217
*out_message = zbx_strdcatf(*out_message, ",%s", pCh);
223
#endif /* _WINDOWS */
225
int process_eventlog(
228
unsigned long *out_timestamp,
230
unsigned short *out_severity,
235
#if defined(_WINDOWS)
237
HANDLE eventlog_handle;
245
assert(out_timestamp);
247
assert(out_severity);
255
#if defined(_WINDOWS)
257
if (source && source[0] && 0 == zbx_open_eventlog(source,&eventlog_handle,&LastID /* number */, &FirstID /* oldest */))
261
if(*lastlogsize > LastID)
262
*lastlogsize = FirstID;
263
else if((*lastlogsize) >= FirstID)
264
FirstID = (*lastlogsize)+1;
266
for (i = FirstID; i < LastID && ret == FAIL; i++)
268
if( 0 == zbx_get_eventlog_message(
277
switch(*out_severity)
279
case EVENTLOG_ERROR_TYPE: *out_severity = 4; break;
280
case EVENTLOG_AUDIT_FAILURE: *out_severity = 7; break;
281
case EVENTLOG_AUDIT_SUCCESS: *out_severity = 8; break;
282
case EVENTLOG_INFORMATION_TYPE: *out_severity = 1; break;
283
case EVENTLOG_WARNING_TYPE: *out_severity = 2; break;
291
zbx_close_eventlog(eventlog_handle);
294
#endif /* _WINDOWS */