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