Fix thread synchronization, use critical sections.
[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
11 #include "eventlog.h"
12
13 VOID CALLBACK ServiceMain(DWORD argc, LPTSTR *argv);
14
15 SERVICE_TABLE_ENTRY ServiceTable[2] =
16 {
17 {L"EventLog", (LPSERVICE_MAIN_FUNCTION)ServiceMain},
18 {NULL, NULL}
19 };
20
21 /* GLOBAL VARIABLES */
22 HANDLE MyHeap = NULL;
23 PLOGFILE SystemLog = NULL;
24 PLOGFILE ApplicationLog = NULL;
25 PLOGFILE SecurityLog = NULL;
26 BOOL onLiveCD = FALSE; // On livecd events will go to debug output only
27
28 extern CRITICAL_SECTION LogListCs;
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
60 int main(int argc, char *argv[])
61 {
62 WCHAR LogPath[MAX_PATH];
63 MyHeap = HeapCreate(0, 1024*256, 0);
64
65 if(MyHeap==NULL)
66 {
67 DbgPrint("EventLog: FATAL ERROR, can't create heap.\n");
68 return 1;
69 }
70
71 InitializeCriticalSection(&LogListCs);
72
73 /*
74 This will be fixed in near future
75 */
76
77 GetWindowsDirectory(LogPath, MAX_PATH);
78 if(GetDriveType(LogPath) == DRIVE_CDROM)
79 {
80 DPRINT("LiveCD detected\n");
81 onLiveCD = TRUE;
82 }
83 else
84 {
85 lstrcat(LogPath, L"\\system32\\config\\SysEvent.evt");
86
87 SystemLog = LogfCreate(L"System", LogPath);
88
89 if(SystemLog == NULL)
90 {
91 DbgPrint("EventLog: FATAL ERROR, can't create %S\n", LogPath);
92 HeapDestroy(MyHeap);
93 return 1;
94 }
95
96 GetWindowsDirectory(LogPath, MAX_PATH);
97 lstrcat(LogPath, L"\\system32\\config\\AppEvent.evt");
98
99 ApplicationLog = LogfCreate(L"Application", LogPath);
100
101 if(ApplicationLog == NULL)
102 {
103 DbgPrint("EventLog: FATAL ERROR, can't create %S\n", LogPath);
104 HeapDestroy(MyHeap);
105 return 1;
106 }
107 }
108
109 StartServiceCtrlDispatcher(ServiceTable);
110
111
112 LogfClose(SystemLog);
113 DeleteCriticalSection(&LogListCs);
114 HeapDestroy(MyHeap);
115
116 return 0;
117 }
118
119 VOID EventTimeToSystemTime(DWORD EventTime,
120 SYSTEMTIME *pSystemTime)
121 {
122 SYSTEMTIME st1970 = { 1970, 1, 0, 1, 0, 0, 0, 0 };
123 FILETIME ftLocal;
124 union {
125 FILETIME ft;
126 ULONGLONG ll;
127 } u1970, uUCT;
128
129 uUCT.ft.dwHighDateTime = 0;
130 uUCT.ft.dwLowDateTime = EventTime;
131 SystemTimeToFileTime(&st1970, &u1970.ft);
132 uUCT.ll = uUCT.ll * 10000000 + u1970.ll;
133 FileTimeToLocalFileTime(&uUCT.ft, &ftLocal);
134 FileTimeToSystemTime(&ftLocal, pSystemTime);
135 }
136
137 VOID SystemTimeToEventTime(SYSTEMTIME *pSystemTime,
138 DWORD *pEventTime)
139 {
140 SYSTEMTIME st1970 = { 1970, 1, 0, 1, 0, 0, 0, 0 };
141 union {
142 FILETIME ft;
143 ULONGLONG ll;
144 } Time, u1970;
145
146 SystemTimeToFileTime(pSystemTime, &Time.ft);
147 SystemTimeToFileTime(&st1970, &u1970.ft);
148 *pEventTime = (Time.ll - u1970.ll) / 10000000;
149 }
150
151 VOID PRINT_HEADER(PFILE_HEADER header)
152 {
153 DPRINT("SizeOfHeader=%d\n",header->SizeOfHeader);
154 DPRINT("Signature=0x%x\n",header->Signature);
155 DPRINT("MajorVersion=%d\n",header->MajorVersion);
156 DPRINT("MinorVersion=%d\n",header->MinorVersion);
157 DPRINT("FirstRecordOffset=%d\n",header->FirstRecordOffset);
158 DPRINT("EofOffset=0x%x\n",header->EofOffset);
159 DPRINT("NextRecord=%d\n",header->NextRecord);
160 DPRINT("OldestRecord=%d\n",header->OldestRecord);
161 DPRINT("unknown1=0x%x\n",header->unknown1);
162 DPRINT("unknown2=0x%x\n",header->unknown2);
163 DPRINT("SizeOfHeader2=%d\n",header->SizeOfHeader2);
164 DPRINT("Flags: ");
165 if(header->Flags & LOGFILE_FLAG1)DPRINT("LOGFILE_FLAG1 ");
166 if(header->Flags & LOGFILE_FLAG2)DPRINT("| LOGFILE_FLAG2 ");
167 if(header->Flags & LOGFILE_FLAG3)DPRINT("| LOGFILE_FLAG3 ");
168 if(header->Flags & LOGFILE_FLAG4)DPRINT("| LOGFILE_FLAG4");
169 DPRINT("\n");
170 }
171
172 VOID PRINT_RECORD(PEVENTLOGRECORD pRec)
173 {
174 UINT i;
175 WCHAR *str;
176 SYSTEMTIME time;
177
178 DPRINT("Length=%d\n", pRec->Length );
179 DPRINT("Reserved=0x%x\n", pRec->Reserved );
180 DPRINT("RecordNumber=%d\n", pRec->RecordNumber );
181
182 EventTimeToSystemTime(pRec->TimeGenerated, &time);
183 DPRINT("TimeGenerated=%d.%d.%d %d:%d:%d\n",
184 time.wDay, time.wMonth, time.wYear,
185 time.wHour, time.wMinute, time.wSecond);
186
187 EventTimeToSystemTime(pRec->TimeWritten, &time);
188 DPRINT("TimeWritten=%d.%d.%d %d:%d:%d\n",
189 time.wDay, time.wMonth, time.wYear,
190 time.wHour, time.wMinute, time.wSecond);
191
192 DPRINT("EventID=%d\n", pRec->EventID );
193
194 switch(pRec->EventType)
195 {
196 case EVENTLOG_ERROR_TYPE:
197 DPRINT("EventType = EVENTLOG_ERROR_TYPE\n");
198 break;
199 case EVENTLOG_WARNING_TYPE:
200 DPRINT("EventType = EVENTLOG_WARNING_TYPE\n");
201 break;
202 case EVENTLOG_INFORMATION_TYPE:
203 DPRINT("EventType = EVENTLOG_INFORMATION_TYPE\n");
204 break;
205 case EVENTLOG_AUDIT_SUCCESS:
206 DPRINT("EventType = EVENTLOG_AUDIT_SUCCESS\n");
207 break;
208 case EVENTLOG_AUDIT_FAILURE:
209 DPRINT("EventType = EVENTLOG_AUDIT_FAILURE\n");
210 break;
211 default:
212 DPRINT("EventType = %x\n");
213 }
214
215 DPRINT("NumStrings=%d\n", pRec->NumStrings );
216 DPRINT("EventCategory=%d\n", pRec->EventCategory);
217 DPRINT("ReservedFlags=0x%x\n", pRec->ReservedFlags);
218 DPRINT("ClosingRecordNumber=%d\n", pRec->ClosingRecordNumber);
219 DPRINT("StringOffset=%d\n", pRec->StringOffset);
220 DPRINT("UserSidLength=%d\n", pRec->UserSidLength);
221 DPRINT("UserSidOffset=%d\n", pRec->UserSidOffset);
222 DPRINT("DataLength=%d\n", pRec->DataLength);
223 DPRINT("DataOffset=%d\n", pRec->DataOffset);
224
225 DPRINT("SourceName: %S\n", (WCHAR *)(((PBYTE)pRec)+sizeof(EVENTLOGRECORD)));
226 i = (lstrlenW((WCHAR *)(((PBYTE)pRec)+sizeof(EVENTLOGRECORD)))+1)*sizeof(WCHAR);
227 DPRINT("ComputerName: %S\n", (WCHAR *)(((PBYTE)pRec)+sizeof(EVENTLOGRECORD)+i));
228
229 if(pRec->StringOffset < pRec->Length && pRec->NumStrings){
230 DPRINT("Strings:\n");
231 str = (WCHAR*)(((PBYTE)pRec)+pRec->StringOffset);
232 for(i = 0; i < pRec->NumStrings; i++)
233 {
234 DPRINT("[%d] %S\n", i, str);
235 str = str+lstrlenW(str)+1;
236 }
237 }
238
239 DPRINT("Length2=%d\n", *(PDWORD)(((PBYTE)pRec)+pRec->Length-4));
240 }
241
242
243