1 ////////////////////////////////////////////////////////////////////
4 // E V E N T L O G G I N G F U N C T I O N S
7 ////////////////////////////////////////////////////////////////////
10 #include <afsconfig.h>
11 #include <afs/param.h>
18 #include <WINNT/afsreg.h>
20 #include "afsd_eventlog.h"
21 #define AFS_VERSION_STRINGS
22 #include "afs_component_version_number.h"
24 static BOOL GetServicePath(LPTSTR lpPathBuf, PDWORD pdwPathBufSize);
25 static BOOL AddEventSource(void);
28 GetServicePath(LPTSTR lpPathBuf, PDWORD pdwPathBufSize)
36 if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_SUBKEY, 0, KEY_QUERY_VALUE, &hKey ) )
42 // prepare user's buffer and read into it
43 dwData = *pdwPathBufSize;
44 memset(lpPathBuf, '\0', dwData);
45 if ( RegQueryValueEx( hKey, // handle to key
46 "ImagePath", // value name
49 (LPBYTE) lpPathBuf, // data buffer
50 &dwData)) // size of data buffer
56 *pdwPathBufSize = dwData;
67 // Ensure name for message file is in proper location in Registry.
72 HKEY hKey = NULL, hLogKey;
73 UCHAR szBuf[MAX_PATH] = "afsd_service.exe";
74 DWORD dwData, dwDisposition;
75 static BOOL bRet = TRUE;
76 static BOOL bOnce = TRUE;
81 if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, AFSREG_APPLOG_SUBKEY, 0,
82 KEY_SET_VALUE, &hLogKey ) )
85 if ( RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSREG_APPLOG_SUBKEY, 0,
86 NULL, REG_OPTION_NON_VOLATILE,
87 KEY_ALL_ACCESS, NULL, &hLogKey,
95 // Let's see if key already exists as a subkey under the
96 // Application key in the EventLog registry key. If not,
98 if ( RegOpenKeyEx( hLogKey, AFSREG_CLT_APPLOG_SUBKEY, 0,
99 KEY_SET_VALUE, &hKey ) )
102 if ( RegCreateKeyEx(hLogKey, AFSREG_CLT_APPLOG_SUBKEY, 0,
103 NULL, REG_OPTION_NON_VOLATILE,
104 KEY_ALL_ACCESS, NULL, &hKey,
112 // Add the name to the EventMessageFile subkey.
113 if ( RegSetValueEx( hKey, // subkey handle
114 AFSREG_APPLOG_MSGFILE_VALUE, // value name
116 REG_SZ, // value type
117 (LPBYTE) szBuf, // pointer to value data
118 (DWORD)strlen(szBuf) + 1)) // length of value data
124 // Set the supported event types in the TypesSupported subkey.
125 dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE |
126 EVENTLOG_INFORMATION_TYPE;
128 if ( RegSetValueEx( hKey, // subkey handle
129 AFSREG_APPLOG_MSGTYPE_VALUE, // value name
131 REG_DWORD, // value type
132 (LPBYTE) &dwData, // pointer to value data
133 sizeof(DWORD))) // length of value data
144 RegCloseKey(hLogKey);
149 // Log an event with a formatted system message as the (only) substitution
150 // string, from the given message ID.
152 LogEventMessage(WORD wEventType, DWORD dwEventID, DWORD dwMessageID)
156 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
157 NULL, dwMessageID, 0, (LPTSTR)&msgBuf, 0, NULL);
158 LogEvent(wEventType, dwEventID, msgBuf, NULL);
163 // Use the ReportEvent API to write an entry to the system event log.
169 LogEvent(WORD wEventType, DWORD dwEventID, ...)
173 HANDLE hMutex = NULL;
174 LPTSTR lpArgs[MAXARGS];
175 CHAR lpStrings[MAXARGS][STRLEN];
176 static CHAR lpLastStrings[MAXARGS][STRLEN];
178 static WORD wLastNumArgs = MAXARGS;
179 static time_t lastMessageTime = 0;
180 static WORD wLastEventType = 0;
181 static DWORD dwLastEventID = 0;
184 BOOL bLogMessage = TRUE;
187 // Ensure that our event source is properly initialized.
188 if (!AddEventSource())
191 // Get a handle to the event log.
192 hEventSource = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
193 if (hEventSource == NULL)
196 // Construct the array of substitution strings.
197 va_start(listArgs, dwEventID);
199 switch ( dwEventID ) {
200 case MSG_FLUSH_NO_SHARE_NAME:
201 case MSG_FLUSH_NO_MEMORY:
202 case MSG_FLUSH_IMPERSONATE_ERROR:
203 case MSG_FLUSH_UNEXPECTED_EVENT:
204 case MSG_UNHANDLED_EXCEPTION:
205 case MSG_SMB_ZERO_TRANSACTION_COUNT:
206 case MSG_SERVICE_INCORRECT_VERSIONS:
207 case MSG_SERVICE_STOPPING:
208 case MSG_SERVICE_STOPPED:
209 case MSG_SERVICE_ERROR_STOP:
213 case MSG_SERVICE_START_PENDING:
215 lpArgs[0] = AFSVersion;
217 case MSG_SERVICE_RUNNING:
219 if (smb_Enabled && RDR_Initialized)
220 lpArgs[0] = "SMB and RDR interfaces";
221 else if (smb_Enabled)
222 lpArgs[0] = "SMB interface";
223 else if (RDR_Initialized)
224 lpArgs[0] = "RDR interface";
226 lpArgs[0] = "No active interface";
228 case MSG_FLUSH_BAD_SHARE_NAME:
229 case MSG_FLUSH_OPEN_ENUM_ERROR:
230 case MSG_FLUSH_ENUM_ERROR:
231 case MSG_FLUSH_FAILED:
232 case MSG_RX_HARD_DEAD_TIME_EXCEEDED:
233 case MSG_SERVICE_ERROR_STOP_WITH_MSG:
234 case MSG_SMB_SEND_PACKET_FAILURE:
235 case MSG_UNEXPECTED_SMB_SESSION_CLOSE:
236 case MSG_RX_MSGSIZE_EXCEEDED:
237 case MSG_RX_BUSY_CALL_CHANNEL:
239 lpArgs[0] = va_arg(listArgs, LPTSTR);
241 case MSG_TIME_FLUSH_PER_VOLUME:
242 case MSG_TIME_FLUSH_TOTAL:
243 case MSG_SMB_MAX_MPX_COUNT:
244 case MSG_SMB_MAX_BUFFER_SIZE:
246 lpArgs[0] = va_arg(listArgs, LPTSTR);
247 lpArgs[1] = va_arg(listArgs, LPTSTR);
249 case MSG_SERVER_REPORTS_VNOVOL:
250 case MSG_SERVER_REPORTS_VMOVED:
251 case MSG_SERVER_REPORTS_VOFFLINE:
252 case MSG_SERVER_REPORTS_VSALVAGE:
253 case MSG_SERVER_REPORTS_VNOSERVICE:
254 case MSG_SERVER_REPORTS_VIO:
255 case MSG_SERVER_REPORTS_VBUSY:
256 case MSG_SERVER_REPORTS_VRESTARTING:
257 case MSG_SERVER_REPLIED_BAD_STATUS:
259 lpArgs[0] = va_arg(listArgs, LPTSTR);
260 StringCbPrintf(lpStrings[1],STRLEN,"%d",va_arg(listArgs,afs_int32));
261 lpArgs[1] = lpStrings[1];
262 lpArgs[2] = va_arg(listArgs, LPTSTR);
264 case MSG_ALL_SERVERS_BUSY:
265 case MSG_ALL_SERVERS_OFFLINE:
266 case MSG_ALL_SERVERS_DOWN:
267 case MSG_RX_IDLE_DEAD_TIMEOUT:
269 lpArgs[0] = va_arg(listArgs, LPTSTR);
270 StringCbPrintf(lpStrings[1],STRLEN,"%d",va_arg(listArgs,afs_int32));
271 lpArgs[1] = lpStrings[1];
273 case MSG_BAD_SMB_PARAM:
275 lpArgs[0] = va_arg(listArgs, LPTSTR);
276 StringCbPrintf(lpStrings[1],STRLEN,"%d",va_arg(listArgs,int));
277 StringCbPrintf(lpStrings[2],STRLEN,"%d",va_arg(listArgs,int));
278 StringCbPrintf(lpStrings[3],STRLEN,"%d",va_arg(listArgs,int));
279 StringCbPrintf(lpStrings[4],STRLEN,"%d",va_arg(listArgs,WORD));
280 lpArgs[1] = lpStrings[1];
281 lpArgs[2] = lpStrings[2];
282 lpArgs[3] = lpStrings[3];
283 lpArgs[4] = lpStrings[4];
285 case MSG_BAD_SMB_PARAM_WITH_OFFSET:
287 lpArgs[0] = va_arg(listArgs, LPTSTR);
288 StringCbPrintf(lpStrings[1],STRLEN,"%d",va_arg(listArgs,int));
289 StringCbPrintf(lpStrings[2],STRLEN,"%d",va_arg(listArgs,int));
290 StringCbPrintf(lpStrings[3],STRLEN,"%d",va_arg(listArgs,int));
291 StringCbPrintf(lpStrings[4],STRLEN,"%d",va_arg(listArgs,int));
292 StringCbPrintf(lpStrings[5],STRLEN,"%d",va_arg(listArgs,WORD));
293 lpArgs[1] = lpStrings[1];
294 lpArgs[2] = lpStrings[2];
295 lpArgs[3] = lpStrings[3];
296 lpArgs[4] = lpStrings[4];
297 lpArgs[5] = lpStrings[5];
299 case MSG_BAD_SMB_TOO_SHORT:
300 case MSG_BAD_SMB_INVALID:
301 case MSG_BAD_SMB_INCOMPLETE:
303 StringCbPrintf(lpStrings[0],STRLEN,"%d",va_arg(listArgs,WORD));
304 lpArgs[0] = lpStrings[0];
306 case MSG_SMB_SESSION_START:
308 StringCbPrintf(lpStrings[0],STRLEN,"%d",va_arg(listArgs,long));
309 lpArgs[0] = lpStrings[0];
311 case MSG_BAD_SMB_WRONG_SESSION:
313 StringCbPrintf(lpStrings[0],STRLEN,"%d",va_arg(listArgs,DWORD));
314 StringCbPrintf(lpStrings[1],STRLEN,"%d",va_arg(listArgs,WORD));
315 lpArgs[0] = lpStrings[0];
316 lpArgs[1] = lpStrings[1];
320 StringCbPrintf(lpStrings[0],STRLEN,"%d",va_arg(listArgs,UCHAR));
321 StringCbPrintf(lpStrings[1],STRLEN,"%d",va_arg(listArgs,UCHAR));
322 StringCbPrintf(lpStrings[2],STRLEN,"%d",va_arg(listArgs,UCHAR));
323 StringCbPrintf(lpStrings[3],STRLEN,"%d",va_arg(listArgs,UCHAR));
324 lpArgs[0] = lpStrings[0];
325 lpArgs[1] = lpStrings[1];
326 lpArgs[2] = lpStrings[2];
327 lpArgs[3] = lpStrings[3];
329 case MSG_SERVICE_ERROR_STOP_WITH_MSG_AND_LOCATION:
331 lpArgs[0] = va_arg(listArgs, LPTSTR);
332 StringCbPrintf(lpStrings[1],STRLEN,"%d",va_arg(listArgs,int));
333 lpArgs[1] = lpStrings[1];
334 lpArgs[2] = va_arg(listArgs,LPTSTR);
336 case MSG_DIRTY_BUFFER_AT_SHUTDOWN:
338 lpArgs[0] = va_arg(listArgs, LPTSTR);
339 lpArgs[1] = va_arg(listArgs, LPTSTR);
340 StringCbPrintf(lpStrings[2],STRLEN,"%u",va_arg(listArgs,int));
341 StringCbPrintf(lpStrings[3],STRLEN,"%u",va_arg(listArgs,int));
342 StringCbPrintf(lpStrings[4],STRLEN,"%I64u",va_arg(listArgs,afs_int64));
343 StringCbPrintf(lpStrings[5],STRLEN,"%I64u",va_arg(listArgs,afs_int64));
344 lpArgs[2] = lpStrings[2];
345 lpArgs[3] = lpStrings[3];
346 lpArgs[4] = lpStrings[4];
347 lpArgs[5] = lpStrings[5];
352 // Make sure we were not given too many args.
353 if (wNumArgs >= MAXARGS)
356 hMutex = CreateMutex( NULL, TRUE, "AFSD Event Log Mutex");
360 if (GetLastError() == ERROR_ALREADY_EXISTS) {
361 code = WaitForSingleObject( hMutex, 500);
362 if (code != WAIT_OBJECT_0)
367 * We rate limit consecutive duplicate messages to one every
371 if (now < lastMessageTime + 5 &&
372 wEventType == wLastEventType &&
373 dwEventID == dwLastEventID &&
374 wNumArgs == wLastNumArgs) {
375 for (i=0; i<wNumArgs; i++) {
376 if ( strncmp(lpArgs[i], lpLastStrings[i], STRLEN))
384 wLastNumArgs = wNumArgs;
385 wLastEventType = wEventType;
386 dwLastEventID = dwEventID;
387 lastMessageTime = now;
389 for ( j = (i == wNumArgs ? 0 : i) ; i < wNumArgs; i++) {
390 StringCbCopyEx( lpLastStrings[i], STRLEN, lpArgs[i], NULL, NULL, STRSAFE_NULL_ON_FAILURE);
394 ReleaseMutex(hMutex);
398 code = ReportEvent(hEventSource, // handle of event source
399 wEventType, // event type
401 dwEventID, // event ID
402 NULL, // current user's SID
403 wNumArgs, // strings in lpszArgs
404 0, // no bytes of raw data
405 wNumArgs ? lpArgs : NULL,// array of error strings
406 NULL); // no raw data
412 DeregisterEventSource(hEventSource);