6d71062e9b63e49c33f080832cb75ea5a1f87378
[openafs.git] / src / WINNT / afsd / afsd_eventlog.c
1 ////////////////////////////////////////////////////////////////////
2 //
3 //
4 //              E V E N T   L O G G I N G   F U N C T I O N S 
5 //
6 //
7 ////////////////////////////////////////////////////////////////////
8
9
10 #include <windows.h>
11 #include <stdarg.h>
12 #include <string.h>
13 #include <strsafe.h>
14 #include <WINNT/afsreg.h>
15 #include "afsd.h"
16 #include "afsd_eventlog.h"
17
18 static BOOL     GetServicePath(LPTSTR lpPathBuf, PDWORD pdwPathBufSize);
19 static BOOL     AddEventSource(void);
20
21 static BOOL
22 GetServicePath(LPTSTR lpPathBuf, PDWORD pdwPathBufSize)
23 {
24     HKEY        hKey = NULL; 
25     DWORD       dwData = 0;
26     BOOL        bRet = TRUE;
27
28     do {
29         // Open key
30         if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_SUBKEY, 0, KEY_QUERY_VALUE, &hKey ) )
31         {               
32             bRet = FALSE;
33             break;
34         }
35
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
41                               NULL,                     // reserved
42                               NULL,                     // type buffer
43                               (LPBYTE) lpPathBuf,       // data buffer
44                               &dwData))         // size of data buffer
45         {       
46             bRet = FALSE;
47             break;
48         }
49                 
50         *pdwPathBufSize = dwData;
51
52     } while (0);
53                                 
54     if (hKey != NULL)
55         RegCloseKey(hKey); 
56
57     return bRet;
58
59
60 //
61 // Ensure name for message file is in proper location in Registry.
62 //
63 static BOOL
64 AddEventSource()
65 {
66     HKEY        hKey = NULL, hLogKey; 
67     UCHAR       szBuf[MAX_PATH]; 
68     DWORD       dwData, dwDisposition; 
69     BOOL        bRet = TRUE;
70
71     do {
72         if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, AFSREG_APPLOG_SUBKEY, 0,
73                            KEY_QUERY_VALUE, &hLogKey ) )
74         {                       
75             // nope - create it         
76             if ( RegCreateKeyEx(HKEY_LOCAL_MACHINE, AFSREG_APPLOG_SUBKEY, 0,
77                                  NULL, REG_OPTION_NON_VOLATILE,
78                                  KEY_ALL_ACCESS, NULL, &hLogKey,
79                                  &dwDisposition)) 
80             {   
81                 bRet = FALSE;
82                 break;
83             }
84         }
85
86         // Let's see if key already exists as a subkey under the 
87         // Application key in the EventLog registry key.  If not,
88         // create it.
89         if ( RegOpenKeyEx( hLogKey, AFSREG_CLT_APPLOG_SUBKEY, 0,
90                            KEY_QUERY_VALUE, &hKey ) )
91         {                       
92             // nope - create it         
93             if ( RegCreateKeyEx(hLogKey, AFSREG_CLT_APPLOG_SUBKEY, 0,
94                                  NULL, REG_OPTION_NON_VOLATILE,
95                                  KEY_ALL_ACCESS, NULL, &hKey,
96                                  &dwDisposition)) 
97             {   
98                 bRet = FALSE;
99                 break;
100             }
101
102             // Set the name of the message file
103             // Get "ImagePath" from TransarcAFSDaemon service
104             memset(szBuf, '\0', MAX_PATH);
105             dwData = MAX_PATH;
106             GetServicePath(szBuf, &dwData);
107
108             // Add the name to the EventMessageFile subkey. 
109             if ( RegSetValueEx( hKey,                   // subkey handle 
110                                 AFSREG_APPLOG_MSGFILE_VALUE,    // value name 
111                                 0,                      // must be zero 
112                                 REG_EXPAND_SZ,          // value type 
113                                 (LPBYTE) szBuf,         // pointer to value data 
114                                 (DWORD)strlen(szBuf) + 1))      // length of value data
115             {   
116                 bRet = FALSE;
117                 break;
118             }
119
120             // Set the supported event types in the TypesSupported subkey. 
121             dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | 
122                 EVENTLOG_INFORMATION_TYPE; 
123
124             if ( RegSetValueEx( hKey,                   // subkey handle 
125                                 AFSREG_APPLOG_MSGTYPE_VALUE,    // value name 
126                                 0,                      // must be zero 
127                                 REG_DWORD,              // value type 
128                                 (LPBYTE) &dwData,       // pointer to value data 
129                                 sizeof(DWORD)))         // length of value data
130             {   
131                 bRet = FALSE;
132                 break;
133             }
134         }
135         else
136         {
137             // key was opened - read it
138             memset(szBuf, '\0', MAX_PATH);
139             dwData = MAX_PATH;
140             if ( RegQueryValueEx( hKey,                 // handle to key
141                                   AFSREG_APPLOG_MSGFILE_VALUE,  // value name
142                                   NULL,                 // reserved
143                                   NULL,                 // type buffer
144                                   (LPBYTE) szBuf,               // data buffer
145                                   &dwData))             // size of data buffer
146             {   
147                 bRet = FALSE;
148                 break;
149             }
150         }
151     } while (0);
152                                 
153     if (hKey != NULL)
154         RegCloseKey(hKey); 
155
156     if (hLogKey != NULL)
157         RegCloseKey(hLogKey); 
158
159     return bRet;
160 }       
161
162 // Log an event with a formatted system message as the (only) substitution
163 // string, from the given message ID.
164 VOID
165 LogEventMessage(WORD wEventType, DWORD dwEventID, DWORD dwMessageID)
166 {
167     LPTSTR msgBuf;
168
169     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
170                    NULL, dwMessageID, 0, (LPTSTR)&msgBuf, 0, NULL);
171     LogEvent(wEventType, dwEventID, msgBuf, NULL);
172     LocalFree(msgBuf);
173 }
174
175 //
176 // Use the ReportEvent API to write an entry to the system event log.
177 //
178 #define MAXARGS 8
179 #define STRLEN  64
180 VOID
181 LogEvent(WORD wEventType, DWORD dwEventID, ...)
182 {
183     va_list     listArgs;
184     HANDLE      hEventSource;
185     LPTSTR      lpArgs[MAXARGS];
186     CHAR        lpStrings[MAXARGS][STRLEN];
187     WORD        wNumArgs = 0;
188     WORD        wNumStrings = 0;
189         DWORD   code;
190
191     // Ensure that our event source is properly initialized.
192     if (!AddEventSource())
193         return;
194
195     // Get a handle to the event log.
196     hEventSource = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
197     if (hEventSource == NULL)
198         return;
199
200     // Construct the array of substitution strings.
201     va_start(listArgs, dwEventID);
202
203     switch ( dwEventID ) {
204     case MSG_FLUSH_NO_SHARE_NAME:
205     case MSG_FLUSH_NO_MEMORY:
206     case MSG_FLUSH_IMPERSONATE_ERROR:
207     case MSG_FLUSH_UNEXPECTED_EVENT:
208     case MSG_UNHANDLED_EXCEPTION:
209     case MSG_SMB_ZERO_TRANSACTION_COUNT:
210     case MSG_SERVICE_START_PENDING:
211     case MSG_SERVICE_INCORRECT_VERSIONS:
212     case MSG_SERVICE_RUNNING:
213     case MSG_SERVICE_STOPPING:
214     case MSG_SERVICE_ERROR_STOP:
215     case MSG_CRYPT_OFF:
216     case MSG_CRYPT_ON:
217         break;
218     case MSG_FLUSH_BAD_SHARE_NAME:
219     case MSG_FLUSH_OPEN_ENUM_ERROR:
220     case MSG_FLUSH_ENUM_ERROR:
221     case MSG_FLUSH_FAILED:
222     case MSG_RX_HARD_DEAD_TIME_EXCEEDED:
223     case MSG_SERVICE_ERROR_STOP_WITH_MSG:
224     case MSG_SMB_SEND_PACKET_FAILURE:
225     case MSG_UNEXPECTED_SMB_SESSION_CLOSE:
226         wNumArgs = 1;
227         lpArgs[0] = va_arg(listArgs, LPTSTR);
228         break;
229     case MSG_TIME_FLUSH_PER_VOLUME:
230     case MSG_TIME_FLUSH_TOTAL:
231         wNumArgs = 2;
232         lpArgs[0] = va_arg(listArgs, LPTSTR);
233         lpArgs[1] = va_arg(listArgs, LPTSTR);
234         break;
235     case MSG_SERVER_REPORTS_VNOVOL:
236     case MSG_SERVER_REPORTS_VMOVED:
237     case MSG_SERVER_REPORTS_VOFFLINE:
238     case MSG_SERVER_REPORTS_VSALVAGE:
239     case MSG_SERVER_REPORTS_VNOSERVICE:
240     case MSG_SERVER_REPORTS_VIO:
241         wNumArgs = 2;
242         lpArgs[0] = va_arg(listArgs, LPTSTR);
243         StringCbPrintf(lpStrings[1],STRLEN,"%d",va_arg(listArgs,afs_int32));
244         lpArgs[1] = lpStrings[1];
245         break;
246     case MSG_BAD_SMB_PARAM:
247         wNumArgs = 5;
248         lpArgs[0] = va_arg(listArgs, LPTSTR);
249         StringCbPrintf(lpStrings[1],STRLEN,"%d",va_arg(listArgs,int));
250         StringCbPrintf(lpStrings[2],STRLEN,"%d",va_arg(listArgs,int));
251         StringCbPrintf(lpStrings[3],STRLEN,"%d",va_arg(listArgs,int));
252         StringCbPrintf(lpStrings[4],STRLEN,"%d",va_arg(listArgs,WORD));
253         lpArgs[1] = lpStrings[1];
254         lpArgs[2] = lpStrings[2];
255         lpArgs[3] = lpStrings[3];
256         lpArgs[4] = lpStrings[4];
257         break;
258     case MSG_BAD_SMB_PARAM_WITH_OFFSET:
259         wNumArgs = 6;
260         lpArgs[0] = va_arg(listArgs, LPTSTR);
261         StringCbPrintf(lpStrings[1],STRLEN,"%d",va_arg(listArgs,int));
262         StringCbPrintf(lpStrings[2],STRLEN,"%d",va_arg(listArgs,int));
263         StringCbPrintf(lpStrings[3],STRLEN,"%d",va_arg(listArgs,int));
264         StringCbPrintf(lpStrings[4],STRLEN,"%d",va_arg(listArgs,int));
265         StringCbPrintf(lpStrings[5],STRLEN,"%d",va_arg(listArgs,WORD));
266         lpArgs[1] = lpStrings[1];
267         lpArgs[2] = lpStrings[2];
268         lpArgs[3] = lpStrings[3];
269         lpArgs[4] = lpStrings[4];
270         lpArgs[5] = lpStrings[5];
271         break;
272     case MSG_BAD_SMB_TOO_SHORT:
273     case MSG_BAD_SMB_INVALID:
274     case MSG_BAD_SMB_INCOMPLETE:
275         wNumArgs = 1;
276         StringCbPrintf(lpStrings[0],STRLEN,"%d",va_arg(listArgs,WORD));
277         lpArgs[0] = lpStrings[0];
278         break;
279     case MSG_SMB_SESSION_START:
280         wNumArgs = 1;
281         StringCbPrintf(lpStrings[0],STRLEN,"%d",va_arg(listArgs,long));
282         lpArgs[0] = lpStrings[0];
283         break;
284     case MSG_BAD_SMB_WRONG_SESSION:
285         wNumArgs = 2;
286         StringCbPrintf(lpStrings[0],STRLEN,"%d",va_arg(listArgs,DWORD));
287         StringCbPrintf(lpStrings[1],STRLEN,"%d",va_arg(listArgs,WORD));
288         lpArgs[0] = lpStrings[0];
289         lpArgs[1] = lpStrings[1];
290         break;
291     case MSG_BAD_VCP:
292         wNumArgs = 4;
293         StringCbPrintf(lpStrings[0],STRLEN,"%d",va_arg(listArgs,UCHAR));
294         StringCbPrintf(lpStrings[1],STRLEN,"%d",va_arg(listArgs,UCHAR));
295         StringCbPrintf(lpStrings[2],STRLEN,"%d",va_arg(listArgs,UCHAR));
296         StringCbPrintf(lpStrings[3],STRLEN,"%d",va_arg(listArgs,UCHAR));
297         lpArgs[0] = lpStrings[0];
298         lpArgs[1] = lpStrings[1];
299         lpArgs[2] = lpStrings[2];
300         lpArgs[3] = lpStrings[3];
301         break;
302     case MSG_SERVICE_ERROR_STOP_WITH_MSG_AND_LOCATION:
303         wNumArgs = 3;
304         lpArgs[0] = va_arg(listArgs, LPTSTR);
305         StringCbPrintf(lpStrings[1],STRLEN,"%d",va_arg(listArgs,int));
306         lpArgs[1] = lpStrings[1];
307         lpArgs[2] = va_arg(listArgs,LPTSTR);
308         break;
309     }
310     va_end(listArgs);
311
312     // Make sure we were not given too many args.
313     if (wNumArgs >= MAXARGS)
314         return;
315
316     // Log the event.
317     code = ReportEvent(hEventSource,            // handle of event source
318                  wEventType,            // event type
319                  0,                     // event category
320                  dwEventID,             // event ID
321                  NULL,                  // current user's SID
322                  wNumArgs,              // strings in lpszArgs
323                  0,                     // no bytes of raw data
324                  wNumArgs ? lpArgs : NULL,              // array of error strings
325                  NULL);                 // no raw data
326
327
328     DeregisterEventSource(hEventSource);
329 }       
330
331