-revert janderwalds change until because it breaks the gcc 4.x build
[reactos.git] / reactos / base / services / eventlog / eventlog.c
1 /*
2 * PROJECT: ReactOS kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: services/eventlog/eventlog.c
5 * PURPOSE: Event logging service
6 * COPYRIGHT: Copyright 2002 Eric Kohl
7 * Copyright 2005 Saveliy Tretiakov
8 */
9
10 /* INCLUDES *****************************************************************/
11
12 #include "eventlog.h"
13
14 /* GLOBALS ******************************************************************/
15
16 VOID CALLBACK ServiceMain(DWORD argc, LPTSTR *argv);
17 SERVICE_TABLE_ENTRY ServiceTable[2] =
18 {
19 {L"EventLog", (LPSERVICE_MAIN_FUNCTION)ServiceMain},
20 {NULL, NULL}
21 };
22
23 HANDLE MyHeap = NULL;
24 BOOL onLiveCD = FALSE; // On livecd events will go to debug output only
25 extern CRITICAL_SECTION LogListCs;
26 extern PLOGFILE LogListHead;
27
28 /* FUNCTIONS ****************************************************************/
29
30 VOID CALLBACK ServiceMain(DWORD argc, LPTSTR *argv)
31 {
32 HANDLE hThread;
33
34 hThread = CreateThread(NULL,
35 0,
36 (LPTHREAD_START_ROUTINE)
37 PortThreadRoutine,
38 NULL,
39 0,
40 NULL);
41
42 if(!hThread) DPRINT("Can't create PortThread\n");
43 else CloseHandle(hThread);
44
45 #ifdef RPC_ENABLED
46 hThread = CreateThread(NULL,
47 0,
48 (LPTHREAD_START_ROUTINE)
49 RpcThreadRoutine,
50 NULL,
51 0,
52 NULL);
53
54 if(!hThread) DPRINT("Can't create RpcThread\n");
55 else CloseHandle(hThread);
56 #endif
57 }
58
59 BOOL LoadLogFile(HKEY hKey, WCHAR *LogName)
60 {
61 DWORD MaxValueLen, ValueLen, Type, ExpandedLen;
62 WCHAR *Buf = NULL, *Expanded = NULL;
63 LONG Result;
64 BOOL ret = TRUE;
65 PLOGFILE pLogf;
66
67 DPRINT("LoadLogFile: %S\n", LogName);
68
69 RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
70 NULL, &MaxValueLen, NULL, NULL);
71
72 Buf = HeapAlloc(MyHeap, 0, MaxValueLen);
73
74 if(!Buf)
75 {
76 DPRINT1("Can't allocate heap!\n");
77 return FALSE;
78 }
79
80 ValueLen = MaxValueLen;
81
82 Result = RegQueryValueEx(hKey, L"File",
83 NULL,
84 &Type,
85 (LPBYTE)Buf,
86 &ValueLen);
87
88 if(Result != ERROR_SUCCESS)
89 {
90 DPRINT1("RegQueryValueEx failed: %d\n", GetLastError());
91 HeapFree(MyHeap, 0, Buf);
92 return FALSE;
93 }
94 if(Type != REG_EXPAND_SZ && Type != REG_SZ)
95 {
96 DPRINT1("%S\\File - value of wrong type %x.\n", LogName, Type);
97 HeapFree(MyHeap, 0, Buf);
98 return FALSE;
99 }
100
101 ExpandedLen = ExpandEnvironmentStrings(Buf, NULL, 0);
102 Expanded = HeapAlloc(MyHeap, 0, ExpandedLen*sizeof(WCHAR));
103
104 if(!Expanded)
105 {
106 DPRINT1("Can't allocate heap!\n");
107 HeapFree(MyHeap, 0, Buf);
108 return FALSE;
109 }
110
111 ExpandEnvironmentStrings(Buf, Expanded, ExpandedLen);
112
113 DPRINT("%S -> %S\n", Buf, Expanded);
114
115 pLogf = LogfCreate(LogName, Expanded);
116
117 if(pLogf == NULL)
118 {
119 DPRINT1("Failed to create %S!\n", Expanded);
120 ret = FALSE;
121 }
122
123 HeapFree(MyHeap, 0, Buf);
124 HeapFree(MyHeap, 0, Expanded);
125 return ret;
126 }
127
128 BOOL LoadLogFiles(HKEY eventlogKey)
129 {
130 LONG result;
131 DWORD MaxLognameLen, LognameLen;
132 WCHAR *Buf = NULL;
133 INT i;
134
135 RegQueryInfoKey(eventlogKey, NULL, NULL, NULL, NULL, &MaxLognameLen,
136 NULL, NULL, NULL, NULL, NULL, NULL);
137
138 MaxLognameLen++;
139
140 Buf = HeapAlloc(MyHeap, 0, MaxLognameLen*sizeof(WCHAR));
141
142 if(!Buf)
143 {
144 DPRINT1("Error: can't allocate heap!\n");
145 return FALSE;
146 }
147
148 i = 0;
149 LognameLen=MaxLognameLen;
150
151 while(RegEnumKeyEx(eventlogKey, i, Buf, &LognameLen, NULL, NULL,
152 NULL, NULL) == ERROR_SUCCESS)
153 {
154 HKEY SubKey;
155 DPRINT("%S\n", Buf);
156
157 result = RegOpenKeyEx(eventlogKey, Buf, 0, KEY_ALL_ACCESS, &SubKey);
158 if(result != ERROR_SUCCESS)
159 {
160 DPRINT1("Failed to open %S key.\n", Buf);
161 HeapFree(MyHeap, 0, Buf);
162 return FALSE;
163 }
164
165 if(!LoadLogFile(SubKey, Buf))
166 DPRINT1("Failed to load %S\n", Buf);
167 else DPRINT("Loaded %S\n", Buf);
168
169 RegCloseKey(SubKey);
170 LognameLen=MaxLognameLen;
171 i++;
172 }
173
174 HeapFree(MyHeap, 0, Buf);
175 return TRUE;
176 }
177
178 INT main()
179 {
180 WCHAR LogPath[MAX_PATH];
181 PLOGFILE pLogf;
182 INT RetCode = 0;
183 LONG result;
184 HKEY elogKey;
185
186 InitializeCriticalSection(&LogListCs);
187
188 MyHeap = HeapCreate(0, 1024*256, 0);
189
190 if(MyHeap==NULL)
191 {
192 DPRINT1("FATAL ERROR, can't create heap.\n");
193 RetCode = 1;
194 goto bye_bye;
195 }
196
197 GetWindowsDirectory(LogPath, MAX_PATH);
198 if(GetDriveType(LogPath) == DRIVE_CDROM)
199 {
200 DPRINT("LiveCD detected\n");
201 onLiveCD = TRUE;
202 }
203 else
204 {
205 result = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
206 L"SYSTEM\\CurrentControlSet\\Services\\EventLog",
207 0,
208 KEY_ALL_ACCESS,
209 &elogKey);
210
211 if(result != ERROR_SUCCESS)
212 {
213 DPRINT1("Fatal error: can't open eventlog registry key.\n");
214 RetCode = 1;
215 goto bye_bye;
216 }
217
218 LoadLogFiles(elogKey);
219 }
220
221 StartServiceCtrlDispatcher(ServiceTable);
222
223 bye_bye:
224 DeleteCriticalSection(&LogListCs);
225
226 // Close all log files.
227 for(pLogf = LogListHead; pLogf; pLogf = ((PLOGFILE)pLogf)->Next)
228 LogfClose(pLogf);
229
230 if(MyHeap) HeapDestroy(MyHeap);
231
232 return RetCode;
233 }
234
235 VOID EventTimeToSystemTime(DWORD EventTime,
236 SYSTEMTIME *pSystemTime)
237 {
238 SYSTEMTIME st1970 = { 1970, 1, 0, 1, 0, 0, 0, 0 };
239 FILETIME ftLocal;
240 union {
241 FILETIME ft;
242 ULONGLONG ll;
243 } u1970, uUCT;
244
245 uUCT.ft.dwHighDateTime = 0;
246 uUCT.ft.dwLowDateTime = EventTime;
247 SystemTimeToFileTime(&st1970, &u1970.ft);
248 uUCT.ll = uUCT.ll * 10000000 + u1970.ll;
249 FileTimeToLocalFileTime(&uUCT.ft, &ftLocal);
250 FileTimeToSystemTime(&ftLocal, pSystemTime);
251 }
252
253 VOID SystemTimeToEventTime(SYSTEMTIME *pSystemTime,
254 DWORD *pEventTime)
255 {
256 SYSTEMTIME st1970 = { 1970, 1, 0, 1, 0, 0, 0, 0 };
257 union {
258 FILETIME ft;
259 ULONGLONG ll;
260 } Time, u1970;
261
262 SystemTimeToFileTime(pSystemTime, &Time.ft);
263 SystemTimeToFileTime(&st1970, &u1970.ft);
264 *pEventTime = (Time.ll - u1970.ll) / 10000000;
265 }
266
267 VOID PRINT_HEADER(PFILE_HEADER header)
268 {
269 DPRINT("SizeOfHeader=%d\n",header->SizeOfHeader);
270 DPRINT("Signature=0x%x\n",header->Signature);
271 DPRINT("MajorVersion=%d\n",header->MajorVersion);
272 DPRINT("MinorVersion=%d\n",header->MinorVersion);
273 DPRINT("FirstRecordOffset=%d\n",header->FirstRecordOffset);
274 DPRINT("EofOffset=0x%x\n",header->EofOffset);
275 DPRINT("NextRecord=%d\n",header->NextRecord);
276 DPRINT("OldestRecord=%d\n",header->OldestRecord);
277 DPRINT("unknown1=0x%x\n",header->unknown1);
278 DPRINT("unknown2=0x%x\n",header->unknown2);
279 DPRINT("SizeOfHeader2=%d\n",header->SizeOfHeader2);
280 DPRINT("Flags: ");
281 if(header->Flags & LOGFILE_FLAG1)DPRINT("LOGFILE_FLAG1 ");
282 if(header->Flags & LOGFILE_FLAG2)DPRINT("| LOGFILE_FLAG2 ");
283 if(header->Flags & LOGFILE_FLAG3)DPRINT("| LOGFILE_FLAG3 ");
284 if(header->Flags & LOGFILE_FLAG4)DPRINT("| LOGFILE_FLAG4");
285 DPRINT("\n");
286 }
287
288 VOID PRINT_RECORD(PEVENTLOGRECORD pRec)
289 {
290 UINT i;
291 WCHAR *str;
292 SYSTEMTIME time;
293
294 DPRINT("Length=%d\n", pRec->Length );
295 DPRINT("Reserved=0x%x\n", pRec->Reserved );
296 DPRINT("RecordNumber=%d\n", pRec->RecordNumber );
297
298 EventTimeToSystemTime(pRec->TimeGenerated, &time);
299 DPRINT("TimeGenerated=%d.%d.%d %d:%d:%d\n",
300 time.wDay, time.wMonth, time.wYear,
301 time.wHour, time.wMinute, time.wSecond);
302
303 EventTimeToSystemTime(pRec->TimeWritten, &time);
304 DPRINT("TimeWritten=%d.%d.%d %d:%d:%d\n",
305 time.wDay, time.wMonth, time.wYear,
306 time.wHour, time.wMinute, time.wSecond);
307
308 DPRINT("EventID=%d\n", pRec->EventID );
309
310 switch(pRec->EventType)
311 {
312 case EVENTLOG_ERROR_TYPE:
313 DPRINT("EventType = EVENTLOG_ERROR_TYPE\n");
314 break;
315 case EVENTLOG_WARNING_TYPE:
316 DPRINT("EventType = EVENTLOG_WARNING_TYPE\n");
317 break;
318 case EVENTLOG_INFORMATION_TYPE:
319 DPRINT("EventType = EVENTLOG_INFORMATION_TYPE\n");
320 break;
321 case EVENTLOG_AUDIT_SUCCESS:
322 DPRINT("EventType = EVENTLOG_AUDIT_SUCCESS\n");
323 break;
324 case EVENTLOG_AUDIT_FAILURE:
325 DPRINT("EventType = EVENTLOG_AUDIT_FAILURE\n");
326 break;
327 default:
328 DPRINT("EventType = %x\n");
329 }
330
331 DPRINT("NumStrings=%d\n", pRec->NumStrings );
332 DPRINT("EventCategory=%d\n", pRec->EventCategory);
333 DPRINT("ReservedFlags=0x%x\n", pRec->ReservedFlags);
334 DPRINT("ClosingRecordNumber=%d\n", pRec->ClosingRecordNumber);
335 DPRINT("StringOffset=%d\n", pRec->StringOffset);
336 DPRINT("UserSidLength=%d\n", pRec->UserSidLength);
337 DPRINT("UserSidOffset=%d\n", pRec->UserSidOffset);
338 DPRINT("DataLength=%d\n", pRec->DataLength);
339 DPRINT("DataOffset=%d\n", pRec->DataOffset);
340
341 DPRINT("SourceName: %S\n", (WCHAR *)(((PBYTE)pRec)+sizeof(EVENTLOGRECORD)));
342 i = (lstrlenW((WCHAR *)(((PBYTE)pRec)+sizeof(EVENTLOGRECORD)))+1)*sizeof(WCHAR);
343 DPRINT("ComputerName: %S\n", (WCHAR *)(((PBYTE)pRec)+sizeof(EVENTLOGRECORD)+i));
344
345 if(pRec->StringOffset < pRec->Length && pRec->NumStrings){
346 DPRINT("Strings:\n");
347 str = (WCHAR*)(((PBYTE)pRec)+pRec->StringOffset);
348 for(i = 0; i < pRec->NumStrings; i++)
349 {
350 DPRINT("[%d] %S\n", i, str);
351 str = str+lstrlenW(str)+1;
352 }
353 }
354
355 DPRINT("Length2=%d\n", *(PDWORD)(((PBYTE)pRec)+pRec->Length-4));
356 }