f7f932ffcd638d65c1eafa96aa784dc3ae4fa407
[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 <WINNT/afsreg.h>
14 #include "afsd_eventlog.h"
15
16 static CHAR     szKeyName[] = AFSREG_APPLOG_SUBKEY "\\" AFSREG_CLT_SVC_NAME;
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                 
30                 // Open key
31                 if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, AFSREG_SVR_SVC_SUBKEY, 0, KEY_QUERY_VALUE, &hKey ) )
32                 {               
33                         bRet = FALSE;
34                         break;
35                 }
36
37                 // prepare user's buffer and read into it
38                 dwData = *pdwPathBufSize;
39                 memset(lpPathBuf, '\0', dwData);
40                 if ( RegQueryValueEx( 
41                                 hKey,                   // handle to key
42                                 "ImagePath",            // value name
43                                 NULL,                   // reserved
44                                 NULL,                   // type buffer
45                                 (LPBYTE) lpPathBuf,     // data buffer
46                                 &dwData))               // size of data buffer
47                 {
48                         bRet = FALSE;
49                         break;
50                 }
51                 
52                 *pdwPathBufSize = dwData;
53
54         } while (0);
55                                 
56         if (hKey != NULL)
57                 RegCloseKey(hKey); 
58         
59         return bRet;
60
61
62 //
63 // Ensure name for message file is in proper location in Registry.
64 //
65 static BOOL
66 AddEventSource()
67 {
68         HKEY    hKey = NULL; 
69         UCHAR   szBuf[MAX_PATH]; 
70         DWORD   dwData, dwDisposition; 
71         BOOL    bRet = TRUE;
72
73         do {
74                 // Let's see if key already exists as a subkey under the 
75                 // Application key in the EventLog registry key.  If not,
76                 // create it.
77                 if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyName, 0,
78                                    KEY_QUERY_VALUE, &hKey ) )
79                 {               
80                         // nope - create it             
81                         if ( RegCreateKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0,
82                                             NULL, REG_OPTION_NON_VOLATILE,
83                                             KEY_ALL_ACCESS, NULL, &hKey,
84                                             &dwDisposition)) 
85                         {
86                                 bRet = FALSE;
87                                 break;
88                         }
89                                                 
90                         // Set the name of the message file
91                         // Get "ImagePath" from TransarcAFSDaemon service
92                         memset(szBuf, '\0', MAX_PATH);
93                         dwData = MAX_PATH;
94                         GetServicePath(szBuf, &dwData);
95
96                         // Add the name to the EventMessageFile subkey. 
97                         if ( RegSetValueEx(
98                                         hKey,                   // subkey handle 
99                                         AFSREG_SVR_APPLOG_MSGFILE_VALUE,        // value name 
100                                         0,                      // must be zero 
101                                         REG_EXPAND_SZ,          // value type 
102                                         (LPBYTE) szBuf,         // pointer to value data 
103                                         (DWORD)strlen(szBuf) + 1))      // length of value data
104                         {
105                                 bRet = FALSE;
106                                 break;
107                         }
108  
109                         // Set the supported event types in the TypesSupported subkey. 
110                         dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | 
111                                                 EVENTLOG_INFORMATION_TYPE; 
112  
113                         if ( RegSetValueEx(
114                                         hKey,                   // subkey handle 
115                                         AFSREG_SVR_APPLOG_MSGTYPE_VALUE,        // value name 
116                                         0,                      // must be zero 
117                                         REG_DWORD,              // value type 
118                                         (LPBYTE) &dwData,       // pointer to value data 
119                                         sizeof(DWORD)))         // length of value data
120                         {
121                                 bRet = FALSE;
122                                 break;
123                         }
124                 }
125
126                 else
127                 {
128                         // key was opened - read it
129                         memset(szBuf, '\0', MAX_PATH);
130                         dwData = MAX_PATH;
131                         if ( RegQueryValueEx( 
132                                         hKey,                   // handle to key
133                                         AFSREG_SVR_APPLOG_MSGFILE_VALUE,        // value name
134                                         NULL,                   // reserved
135                                         NULL,                   // type buffer
136                                         (LPBYTE) szBuf,         // data buffer
137                                         &dwData))               // size of data buffer
138                         {
139                                 bRet = FALSE;
140                                 break;
141                         }
142                 }
143                 
144         } while (0);
145                                 
146         if (hKey != NULL)
147                 RegCloseKey(hKey); 
148
149         return bRet;
150
151
152 // Log an event with a formatted system message as the (only) substitution
153 // string, from the given message ID.
154 VOID
155 LogEventMessage(WORD wEventType, DWORD dwEventID, DWORD dwMessageID)
156 {
157         LPTSTR msgBuf;
158
159         FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
160                       | FORMAT_MESSAGE_ALLOCATE_BUFFER,
161                       NULL, dwMessageID, 0, (LPTSTR)&msgBuf, 0, NULL);
162         LogEvent(wEventType, dwEventID, msgBuf, NULL);
163         LocalFree(msgBuf);
164 }
165
166 //
167 // Use the ReportEvent API to write an entry to the system event log.
168 //
169 #define MAXSTRINGARGS 100
170 VOID
171 LogEvent(WORD wEventType, DWORD dwEventID, LPTSTR lpString, ...)
172 {
173         va_list listStrings;
174         HANDLE  hEventSource;
175         LPTSTR lpStrings[MAXSTRINGARGS];
176         WORD wNumStrings;
177
178         // Ensure that our event source is properly initialized.
179         if (!AddEventSource())
180                 return;
181
182         // Get a handle to the event log.
183         hEventSource = RegisterEventSource(NULL, AFSREG_CLT_SVC_PARAM_KEY);
184         if (hEventSource == NULL)
185                 return;
186
187         // Construct the array of substitution strings.
188         va_start(listStrings, lpString);
189         for (wNumStrings = 0;
190              lpString != NULL && wNumStrings < MAXSTRINGARGS;
191              wNumStrings++)
192         {
193                 lpStrings[wNumStrings] = lpString;
194                 // Advance to the next argument.
195                 lpString = va_arg(listStrings, LPTSTR);
196         }
197         va_end(listStrings);
198
199         // Make sure we were not given too many args.
200         if (wNumStrings >= MAXSTRINGARGS)
201                 return;
202
203         // Log the event.
204         ReportEvent(hEventSource,               // handle of event source
205                     wEventType,                 // event type
206                     0,                          // event category
207                     dwEventID,                  // event ID
208                     NULL,                       // current user's SID
209                     wNumStrings,                // strings in lpszStrings
210                     0,                          // no bytes of raw data
211                     lpStrings,                  // array of error strings
212                     NULL);                      // no raw data
213
214         DeregisterEventSource(hEventSource);
215 }