1 ////////////////////////////////////////////////////////////////////
4 // E V E N T L O G G I N G F U N C T I O N S
7 ////////////////////////////////////////////////////////////////////
14 #include <WINNT/afsreg.h>
16 #include "afsd_eventlog.h"
18 static BOOL GetServicePath(LPTSTR lpPathBuf, PDWORD pdwPathBufSize);
19 static BOOL AddEventSource(void);
22 GetServicePath(LPTSTR lpPathBuf, PDWORD pdwPathBufSize)
30 if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_SUBKEY, 0, KEY_QUERY_VALUE, &hKey ) )
36 // prepare user's buffer and read into it
37 dwData = *pdwPathBufSize;
38 memset(lpPathBuf, '\0', dwData);
39 if ( RegQueryValueEx( hKey, // handle to key
40 "ImagePath", // value name
43 (LPBYTE) lpPathBuf, // data buffer
44 &dwData)) // size of data buffer
50 *pdwPathBufSize = dwData;
61 // Ensure name for message file is in proper location in Registry.
66 HKEY hKey = NULL, hLogKey;
67 UCHAR szBuf[MAX_PATH] = "afsd_service.exe";
68 DWORD dwData, dwDisposition;
69 static BOOL bRet = TRUE;
70 static BOOL bOnce = TRUE;
75 if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, AFSREG_APPLOG_SUBKEY, 0,
76 KEY_SET_VALUE, &hLogKey ) )
79 if ( RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSREG_APPLOG_SUBKEY, 0,
80 NULL, REG_OPTION_NON_VOLATILE,
81 KEY_ALL_ACCESS, NULL, &hLogKey,
89 // Let's see if key already exists as a subkey under the
90 // Application key in the EventLog registry key. If not,
92 if ( RegOpenKeyEx( hLogKey, AFSREG_CLT_APPLOG_SUBKEY, 0,
93 KEY_SET_VALUE, &hKey ) )
96 if ( RegCreateKeyEx(hLogKey, AFSREG_CLT_APPLOG_SUBKEY, 0,
97 NULL, REG_OPTION_NON_VOLATILE,
98 KEY_ALL_ACCESS, NULL, &hKey,
106 // Add the name to the EventMessageFile subkey.
107 if ( RegSetValueEx( hKey, // subkey handle
108 AFSREG_APPLOG_MSGFILE_VALUE, // value name
110 REG_SZ, // value type
111 (LPBYTE) szBuf, // pointer to value data
112 (DWORD)strlen(szBuf) + 1)) // length of value data
118 // Set the supported event types in the TypesSupported subkey.
119 dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE |
120 EVENTLOG_INFORMATION_TYPE;
122 if ( RegSetValueEx( hKey, // subkey handle
123 AFSREG_APPLOG_MSGTYPE_VALUE, // value name
125 REG_DWORD, // value type
126 (LPBYTE) &dwData, // pointer to value data
127 sizeof(DWORD))) // length of value data
138 RegCloseKey(hLogKey);
143 // Log an event with a formatted system message as the (only) substitution
144 // string, from the given message ID.
146 LogEventMessage(WORD wEventType, DWORD dwEventID, DWORD dwMessageID)
150 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
151 NULL, dwMessageID, 0, (LPTSTR)&msgBuf, 0, NULL);
152 LogEvent(wEventType, dwEventID, msgBuf, NULL);
157 // Use the ReportEvent API to write an entry to the system event log.
163 LogEvent(WORD wEventType, DWORD dwEventID, ...)
167 HANDLE hMutex = NULL;
168 LPTSTR lpArgs[MAXARGS];
169 CHAR lpStrings[MAXARGS][STRLEN];
170 static CHAR lpLastStrings[MAXARGS][STRLEN];
172 static WORD wLastNumArgs = MAXARGS;
173 static time_t lastMessageTime = 0;
174 static WORD wLastEventType = 0;
175 static DWORD dwLastEventID = 0;
178 BOOL bLogMessage = TRUE;
181 // Ensure that our event source is properly initialized.
182 if (!AddEventSource())
185 // Get a handle to the event log.
186 hEventSource = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
187 if (hEventSource == NULL)
190 // Construct the array of substitution strings.
191 va_start(listArgs, dwEventID);
193 switch ( dwEventID ) {
194 case MSG_FLUSH_NO_SHARE_NAME:
195 case MSG_FLUSH_NO_MEMORY:
196 case MSG_FLUSH_IMPERSONATE_ERROR:
197 case MSG_FLUSH_UNEXPECTED_EVENT:
198 case MSG_UNHANDLED_EXCEPTION:
199 case MSG_SMB_ZERO_TRANSACTION_COUNT:
200 case MSG_SERVICE_START_PENDING:
201 case MSG_SERVICE_INCORRECT_VERSIONS:
202 case MSG_SERVICE_RUNNING:
203 case MSG_SERVICE_STOPPING:
204 case MSG_SERVICE_ERROR_STOP:
208 case MSG_FLUSH_BAD_SHARE_NAME:
209 case MSG_FLUSH_OPEN_ENUM_ERROR:
210 case MSG_FLUSH_ENUM_ERROR:
211 case MSG_FLUSH_FAILED:
212 case MSG_RX_HARD_DEAD_TIME_EXCEEDED:
213 case MSG_SERVICE_ERROR_STOP_WITH_MSG:
214 case MSG_SMB_SEND_PACKET_FAILURE:
215 case MSG_UNEXPECTED_SMB_SESSION_CLOSE:
216 case MSG_RX_MSGSIZE_EXCEEDED:
218 lpArgs[0] = va_arg(listArgs, LPTSTR);
220 case MSG_TIME_FLUSH_PER_VOLUME:
221 case MSG_TIME_FLUSH_TOTAL:
222 case MSG_SMB_MAX_MPX_COUNT:
223 case MSG_SMB_MAX_BUFFER_SIZE:
225 lpArgs[0] = va_arg(listArgs, LPTSTR);
226 lpArgs[1] = va_arg(listArgs, LPTSTR);
228 case MSG_SERVER_REPORTS_VNOVOL:
229 case MSG_SERVER_REPORTS_VMOVED:
230 case MSG_SERVER_REPORTS_VOFFLINE:
231 case MSG_SERVER_REPORTS_VSALVAGE:
232 case MSG_SERVER_REPORTS_VNOSERVICE:
233 case MSG_SERVER_REPORTS_VIO:
234 case MSG_SERVER_REPORTS_VBUSY:
235 case MSG_SERVER_REPORTS_VRESTARTING:
236 case MSG_ALL_SERVERS_BUSY:
237 case MSG_ALL_SERVERS_OFFLINE:
238 case MSG_ALL_SERVERS_DOWN:
240 lpArgs[0] = va_arg(listArgs, LPTSTR);
241 StringCbPrintf(lpStrings[1],STRLEN,"%d",va_arg(listArgs,afs_int32));
242 lpArgs[1] = lpStrings[1];
244 case MSG_BAD_SMB_PARAM:
246 lpArgs[0] = va_arg(listArgs, LPTSTR);
247 StringCbPrintf(lpStrings[1],STRLEN,"%d",va_arg(listArgs,int));
248 StringCbPrintf(lpStrings[2],STRLEN,"%d",va_arg(listArgs,int));
249 StringCbPrintf(lpStrings[3],STRLEN,"%d",va_arg(listArgs,int));
250 StringCbPrintf(lpStrings[4],STRLEN,"%d",va_arg(listArgs,WORD));
251 lpArgs[1] = lpStrings[1];
252 lpArgs[2] = lpStrings[2];
253 lpArgs[3] = lpStrings[3];
254 lpArgs[4] = lpStrings[4];
256 case MSG_BAD_SMB_PARAM_WITH_OFFSET:
258 lpArgs[0] = va_arg(listArgs, LPTSTR);
259 StringCbPrintf(lpStrings[1],STRLEN,"%d",va_arg(listArgs,int));
260 StringCbPrintf(lpStrings[2],STRLEN,"%d",va_arg(listArgs,int));
261 StringCbPrintf(lpStrings[3],STRLEN,"%d",va_arg(listArgs,int));
262 StringCbPrintf(lpStrings[4],STRLEN,"%d",va_arg(listArgs,int));
263 StringCbPrintf(lpStrings[5],STRLEN,"%d",va_arg(listArgs,WORD));
264 lpArgs[1] = lpStrings[1];
265 lpArgs[2] = lpStrings[2];
266 lpArgs[3] = lpStrings[3];
267 lpArgs[4] = lpStrings[4];
268 lpArgs[5] = lpStrings[5];
270 case MSG_BAD_SMB_TOO_SHORT:
271 case MSG_BAD_SMB_INVALID:
272 case MSG_BAD_SMB_INCOMPLETE:
274 StringCbPrintf(lpStrings[0],STRLEN,"%d",va_arg(listArgs,WORD));
275 lpArgs[0] = lpStrings[0];
277 case MSG_SMB_SESSION_START:
279 StringCbPrintf(lpStrings[0],STRLEN,"%d",va_arg(listArgs,long));
280 lpArgs[0] = lpStrings[0];
282 case MSG_BAD_SMB_WRONG_SESSION:
284 StringCbPrintf(lpStrings[0],STRLEN,"%d",va_arg(listArgs,DWORD));
285 StringCbPrintf(lpStrings[1],STRLEN,"%d",va_arg(listArgs,WORD));
286 lpArgs[0] = lpStrings[0];
287 lpArgs[1] = lpStrings[1];
291 StringCbPrintf(lpStrings[0],STRLEN,"%d",va_arg(listArgs,UCHAR));
292 StringCbPrintf(lpStrings[1],STRLEN,"%d",va_arg(listArgs,UCHAR));
293 StringCbPrintf(lpStrings[2],STRLEN,"%d",va_arg(listArgs,UCHAR));
294 StringCbPrintf(lpStrings[3],STRLEN,"%d",va_arg(listArgs,UCHAR));
295 lpArgs[0] = lpStrings[0];
296 lpArgs[1] = lpStrings[1];
297 lpArgs[2] = lpStrings[2];
298 lpArgs[3] = lpStrings[3];
300 case MSG_SERVICE_ERROR_STOP_WITH_MSG_AND_LOCATION:
302 lpArgs[0] = va_arg(listArgs, LPTSTR);
303 StringCbPrintf(lpStrings[1],STRLEN,"%d",va_arg(listArgs,int));
304 lpArgs[1] = lpStrings[1];
305 lpArgs[2] = va_arg(listArgs,LPTSTR);
307 case MSG_DIRTY_BUFFER_AT_SHUTDOWN:
309 lpArgs[0] = va_arg(listArgs, LPTSTR);
310 lpArgs[1] = va_arg(listArgs, LPTSTR);
311 StringCbPrintf(lpStrings[2],STRLEN,"%u",va_arg(listArgs,int));
312 StringCbPrintf(lpStrings[3],STRLEN,"%u",va_arg(listArgs,int));
313 StringCbPrintf(lpStrings[4],STRLEN,"%I64u",va_arg(listArgs,afs_int64));
314 StringCbPrintf(lpStrings[5],STRLEN,"%I64u",va_arg(listArgs,afs_int64));
315 lpArgs[2] = lpStrings[2];
316 lpArgs[3] = lpStrings[3];
317 lpArgs[4] = lpStrings[4];
318 lpArgs[5] = lpStrings[5];
323 // Make sure we were not given too many args.
324 if (wNumArgs >= MAXARGS)
327 hMutex = CreateMutex( NULL, TRUE, "AFSD Event Log Mutex");
331 if (GetLastError() == ERROR_ALREADY_EXISTS) {
332 code = WaitForSingleObject( hMutex, 500);
333 if (code != WAIT_OBJECT_0)
338 * We rate limit consecutive duplicate messages to one every
342 if (now < lastMessageTime + 5 &&
343 wEventType == wLastEventType &&
344 dwEventID == dwLastEventID &&
345 wNumArgs == wLastNumArgs) {
346 for (i=0; i<wNumArgs; i++) {
347 if ( strncmp(lpArgs[i], lpLastStrings[i], STRLEN))
355 wLastNumArgs = wNumArgs;
356 wLastEventType = wEventType;
357 dwLastEventID = dwEventID;
358 lastMessageTime = now;
360 for ( j = (i == wNumArgs ? 0 : i) ; i < wNumArgs; i++) {
361 StringCbCopyEx( lpLastStrings[i], STRLEN, lpArgs[i], NULL, NULL, STRSAFE_NULL_ON_FAILURE);
365 ReleaseMutex(hMutex);
369 code = ReportEvent(hEventSource, // handle of event source
370 wEventType, // event type
372 dwEventID, // event ID
373 NULL, // current user's SID
374 wNumArgs, // strings in lpszArgs
375 0, // no bytes of raw data
376 wNumArgs ? lpArgs : NULL,// array of error strings
377 NULL); // no raw data
383 DeregisterEventSource(hEventSource);