////////////////////////////////////////////////////////////////////
//
//
-// E V E N T L O G G I N G F U N C T I O N S
+// E V E N T L O G G I N G F U N C T I O N S
//
//
////////////////////////////////////////////////////////////////////
+#include <afsconfig.h>
+#include <afs/param.h>
+#include <roken.h>
+
#include <windows.h>
#include <stdarg.h>
#include <string.h>
#include <WINNT/afsreg.h>
#include "afsd.h"
#include "afsd_eventlog.h"
+#define AFS_VERSION_STRINGS
+#include "afs_component_version_number.h"
static BOOL GetServicePath(LPTSTR lpPathBuf, PDWORD pdwPathBufSize);
static BOOL AddEventSource(void);
static BOOL
GetServicePath(LPTSTR lpPathBuf, PDWORD pdwPathBufSize)
{
- HKEY hKey = NULL;
+ HKEY hKey = NULL;
DWORD dwData = 0;
BOOL bRet = TRUE;
do {
// Open key
if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_SUBKEY, 0, KEY_QUERY_VALUE, &hKey ) )
- {
+ {
bRet = FALSE;
break;
}
NULL, // type buffer
(LPBYTE) lpPathBuf, // data buffer
&dwData)) // size of data buffer
- {
+ {
bRet = FALSE;
break;
}
-
+
*pdwPathBufSize = dwData;
} while (0);
-
+
if (hKey != NULL)
- RegCloseKey(hKey);
+ RegCloseKey(hKey);
return bRet;
-}
+}
//
// Ensure name for message file is in proper location in Registry.
static BOOL
AddEventSource()
{
- HKEY hKey = NULL, hLogKey;
- UCHAR szBuf[MAX_PATH];
- DWORD dwData, dwDisposition;
- BOOL bRet = TRUE;
+ HKEY hKey = NULL, hLogKey;
+ UCHAR szBuf[MAX_PATH] = "afsd_service.exe";
+ DWORD dwData, dwDisposition;
+ static BOOL bRet = TRUE;
+ static BOOL bOnce = TRUE;
- do {
- if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, AFSREG_APPLOG_SUBKEY, 0,
- KEY_QUERY_VALUE, &hLogKey ) )
- {
- // nope - create it
- if ( RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSREG_APPLOG_SUBKEY, 0,
- NULL, REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS, NULL, &hLogKey,
- &dwDisposition))
- {
- bRet = FALSE;
- break;
- }
- }
+ if (!bOnce)
+ return bRet;
- // Let's see if key already exists as a subkey under the
- // Application key in the EventLog registry key. If not,
- // create it.
- if ( RegOpenKeyEx( hLogKey, AFSREG_CLT_APPLOG_SUBKEY, 0,
- KEY_QUERY_VALUE, &hKey ) )
- {
- // nope - create it
- if ( RegCreateKeyEx(hLogKey, AFSREG_CLT_APPLOG_SUBKEY, 0,
- NULL, REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS, NULL, &hKey,
- &dwDisposition))
- {
- bRet = FALSE;
- break;
- }
-
- // Set the name of the message file
- // Get "ImagePath" from TransarcAFSDaemon service
- memset(szBuf, '\0', MAX_PATH);
- dwData = MAX_PATH;
- GetServicePath(szBuf, &dwData);
-
- // Add the name to the EventMessageFile subkey.
- if ( RegSetValueEx( hKey, // subkey handle
- AFSREG_APPLOG_MSGFILE_VALUE, // value name
- 0, // must be zero
- REG_EXPAND_SZ, // value type
- (LPBYTE) szBuf, // pointer to value data
- (DWORD)strlen(szBuf) + 1)) // length of value data
- {
- bRet = FALSE;
- break;
- }
-
- // Set the supported event types in the TypesSupported subkey.
- dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE |
- EVENTLOG_INFORMATION_TYPE;
-
- if ( RegSetValueEx( hKey, // subkey handle
- AFSREG_APPLOG_MSGTYPE_VALUE, // value name
- 0, // must be zero
- REG_DWORD, // value type
- (LPBYTE) &dwData, // pointer to value data
- sizeof(DWORD))) // length of value data
- {
- bRet = FALSE;
- break;
- }
- }
- else
- {
- // key was opened - read it
- memset(szBuf, '\0', MAX_PATH);
- dwData = MAX_PATH;
- if ( RegQueryValueEx( hKey, // handle to key
- AFSREG_APPLOG_MSGFILE_VALUE, // value name
- NULL, // reserved
- NULL, // type buffer
- (LPBYTE) szBuf, // data buffer
- &dwData)) // size of data buffer
- {
- bRet = FALSE;
- break;
- }
- }
- } while (0);
-
+ if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, AFSREG_APPLOG_SUBKEY, 0,
+ KEY_SET_VALUE, &hLogKey ) )
+ {
+ // nope - create it
+ if ( RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSREG_APPLOG_SUBKEY, 0,
+ NULL, REG_OPTION_NON_VOLATILE,
+ KEY_ALL_ACCESS, NULL, &hLogKey,
+ &dwDisposition))
+ {
+ bRet = FALSE;
+ goto done;
+ }
+ }
+
+ // Let's see if key already exists as a subkey under the
+ // Application key in the EventLog registry key. If not,
+ // create it.
+ if ( RegOpenKeyEx( hLogKey, AFSREG_CLT_APPLOG_SUBKEY, 0,
+ KEY_SET_VALUE, &hKey ) )
+ {
+ // nope - create it
+ if ( RegCreateKeyEx(hLogKey, AFSREG_CLT_APPLOG_SUBKEY, 0,
+ NULL, REG_OPTION_NON_VOLATILE,
+ KEY_ALL_ACCESS, NULL, &hKey,
+ &dwDisposition))
+ {
+ bRet = FALSE;
+ goto done;
+ }
+ }
+
+ // Add the name to the EventMessageFile subkey.
+ if ( RegSetValueEx( hKey, // subkey handle
+ AFSREG_APPLOG_MSGFILE_VALUE, // value name
+ 0, // must be zero
+ REG_SZ, // value type
+ (LPBYTE) szBuf, // pointer to value data
+ (DWORD)strlen(szBuf) + 1)) // length of value data
+ {
+ bRet = FALSE;
+ goto done;
+ }
+
+ // Set the supported event types in the TypesSupported subkey.
+ dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE |
+ EVENTLOG_INFORMATION_TYPE;
+
+ if ( RegSetValueEx( hKey, // subkey handle
+ AFSREG_APPLOG_MSGTYPE_VALUE, // value name
+ 0, // must be zero
+ REG_DWORD, // value type
+ (LPBYTE) &dwData, // pointer to value data
+ sizeof(DWORD))) // length of value data
+ {
+ bRet = FALSE;
+ goto done;
+ }
+
+ done:
if (hKey != NULL)
- RegCloseKey(hKey);
+ RegCloseKey(hKey);
if (hLogKey != NULL)
- RegCloseKey(hLogKey);
+ RegCloseKey(hLogKey);
return bRet;
-}
+}
// Log an event with a formatted system message as the (only) substitution
// string, from the given message ID.
// Use the ReportEvent API to write an entry to the system event log.
//
#define MAXARGS 8
-#define STRLEN 64
+#define STRLEN 128
+
VOID
LogEvent(WORD wEventType, DWORD dwEventID, ...)
{
va_list listArgs;
HANDLE hEventSource;
+ HANDLE hMutex = NULL;
LPTSTR lpArgs[MAXARGS];
CHAR lpStrings[MAXARGS][STRLEN];
+ static CHAR lpLastStrings[MAXARGS][STRLEN];
WORD wNumArgs = 0;
- WORD wNumStrings = 0;
- DWORD code;
+ static WORD wLastNumArgs = MAXARGS;
+ static time_t lastMessageTime = 0;
+ static WORD wLastEventType = 0;
+ static DWORD dwLastEventID = 0;
+ time_t now;
+ DWORD code;
+ BOOL bLogMessage = TRUE;
+ WORD i = 0, j;
// Ensure that our event source is properly initialized.
if (!AddEventSource())
case MSG_FLUSH_UNEXPECTED_EVENT:
case MSG_UNHANDLED_EXCEPTION:
case MSG_SMB_ZERO_TRANSACTION_COUNT:
- case MSG_SERVICE_START_PENDING:
case MSG_SERVICE_INCORRECT_VERSIONS:
- case MSG_SERVICE_RUNNING:
case MSG_SERVICE_STOPPING:
+ case MSG_SERVICE_STOPPED:
case MSG_SERVICE_ERROR_STOP:
+ case MSG_CRYPT_OFF:
+ case MSG_CRYPT_ON:
break;
+ case MSG_SERVICE_START_PENDING:
+ wNumArgs = 1;
+ lpArgs[0] = AFSVersion;
+ break;
+ case MSG_SERVICE_RUNNING:
+ wNumArgs = 1;
+ if (smb_Enabled && RDR_Initialized)
+ lpArgs[0] = "SMB and RDR interfaces";
+ else if (smb_Enabled)
+ lpArgs[0] = "SMB interface";
+ else if (RDR_Initialized)
+ lpArgs[0] = "RDR interface";
+ else
+ lpArgs[0] = "No active interface";
+ break;
case MSG_FLUSH_BAD_SHARE_NAME:
case MSG_FLUSH_OPEN_ENUM_ERROR:
case MSG_FLUSH_ENUM_ERROR:
case MSG_FLUSH_FAILED:
case MSG_RX_HARD_DEAD_TIME_EXCEEDED:
case MSG_SERVICE_ERROR_STOP_WITH_MSG:
+ case MSG_SMB_SEND_PACKET_FAILURE:
+ case MSG_UNEXPECTED_SMB_SESSION_CLOSE:
+ case MSG_RX_MSGSIZE_EXCEEDED:
+ case MSG_RX_BUSY_CALL_CHANNEL:
wNumArgs = 1;
lpArgs[0] = va_arg(listArgs, LPTSTR);
break;
case MSG_TIME_FLUSH_PER_VOLUME:
case MSG_TIME_FLUSH_TOTAL:
+ case MSG_SMB_MAX_MPX_COUNT:
+ case MSG_SMB_MAX_BUFFER_SIZE:
wNumArgs = 2;
lpArgs[0] = va_arg(listArgs, LPTSTR);
lpArgs[1] = va_arg(listArgs, LPTSTR);
case MSG_SERVER_REPORTS_VSALVAGE:
case MSG_SERVER_REPORTS_VNOSERVICE:
case MSG_SERVER_REPORTS_VIO:
+ case MSG_SERVER_REPORTS_VBUSY:
+ case MSG_SERVER_REPORTS_VRESTARTING:
+ wNumArgs = 3;
+ lpArgs[0] = va_arg(listArgs, LPTSTR);
+ StringCbPrintf(lpStrings[1],STRLEN,"%d",va_arg(listArgs,afs_int32));
+ lpArgs[1] = lpStrings[1];
+ lpArgs[2] = va_arg(listArgs, LPTSTR);
+ break;
+ case MSG_ALL_SERVERS_BUSY:
+ case MSG_ALL_SERVERS_OFFLINE:
+ case MSG_ALL_SERVERS_DOWN:
wNumArgs = 2;
lpArgs[0] = va_arg(listArgs, LPTSTR);
StringCbPrintf(lpStrings[1],STRLEN,"%d",va_arg(listArgs,afs_int32));
lpArgs[1] = lpStrings[1];
lpArgs[2] = va_arg(listArgs,LPTSTR);
break;
+ case MSG_DIRTY_BUFFER_AT_SHUTDOWN:
+ wNumArgs = 6;
+ lpArgs[0] = va_arg(listArgs, LPTSTR);
+ lpArgs[1] = va_arg(listArgs, LPTSTR);
+ StringCbPrintf(lpStrings[2],STRLEN,"%u",va_arg(listArgs,int));
+ StringCbPrintf(lpStrings[3],STRLEN,"%u",va_arg(listArgs,int));
+ StringCbPrintf(lpStrings[4],STRLEN,"%I64u",va_arg(listArgs,afs_int64));
+ StringCbPrintf(lpStrings[5],STRLEN,"%I64u",va_arg(listArgs,afs_int64));
+ lpArgs[2] = lpStrings[2];
+ lpArgs[3] = lpStrings[3];
+ lpArgs[4] = lpStrings[4];
+ lpArgs[5] = lpStrings[5];
+ break;
}
va_end(listArgs);
// Make sure we were not given too many args.
if (wNumArgs >= MAXARGS)
- return;
+ goto done;
+
+ hMutex = CreateMutex( NULL, TRUE, "AFSD Event Log Mutex");
+ if (hMutex == NULL)
+ goto done;
+
+ if (GetLastError() == ERROR_ALREADY_EXISTS) {
+ code = WaitForSingleObject( hMutex, 500);
+ if (code != WAIT_OBJECT_0)
+ goto done;
+ }
+
+ /*
+ * We rate limit consecutive duplicate messages to one every
+ * five seconds.
+ */
+ now = time(NULL);
+ if (now < lastMessageTime + 5 &&
+ wEventType == wLastEventType &&
+ dwEventID == dwLastEventID &&
+ wNumArgs == wLastNumArgs) {
+ for (i=0; i<wNumArgs; i++) {
+ if ( strncmp(lpArgs[i], lpLastStrings[i], STRLEN))
+ break;
+ }
+ if (i == wNumArgs)
+ bLogMessage = FALSE;
+ }
+
+ if ( bLogMessage) {
+ wLastNumArgs = wNumArgs;
+ wLastEventType = wEventType;
+ dwLastEventID = dwEventID;
+ lastMessageTime = now;
+
+ for ( j = (i == wNumArgs ? 0 : i) ; i < wNumArgs; i++) {
+ StringCbCopyEx( lpLastStrings[i], STRLEN, lpArgs[i], NULL, NULL, STRSAFE_NULL_ON_FAILURE);
+ }
+ }
+
+ ReleaseMutex(hMutex);
// Log the event.
- code = ReportEvent(hEventSource, // handle of event source
- wEventType, // event type
- 0, // event category
- dwEventID, // event ID
- NULL, // current user's SID
- wNumArgs, // strings in lpszArgs
- 0, // no bytes of raw data
- wNumArgs ? lpArgs : NULL, // array of error strings
- NULL); // no raw data
+ if ( bLogMessage)
+ code = ReportEvent(hEventSource, // handle of event source
+ wEventType, // event type
+ 0, // event category
+ dwEventID, // event ID
+ NULL, // current user's SID
+ wNumArgs, // strings in lpszArgs
+ 0, // no bytes of raw data
+ wNumArgs ? lpArgs : NULL,// array of error strings
+ NULL); // no raw data
+ done:
+ if (hMutex)
+ CloseHandle(hMutex);
DeregisterEventSource(hEventSource);
-}
+}