[SETUPLIB] Improve the bootloader 'validity' checks -- Addendum to f06734e5 (r74512).
[reactos.git] / base / services / eventlog / eventsource.c
1 /*
2 * PROJECT: ReactOS EventLog Service
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/services/eventlog/eventsource.c
5 * PURPOSE: Event log sources support
6 * COPYRIGHT: Copyright 2011 Eric Kohl
7 */
8
9 /* INCLUDES *****************************************************************/
10
11 #include "eventlog.h"
12
13 #define NDEBUG
14 #include <debug.h>
15
16 static LIST_ENTRY EventSourceListHead;
17 static CRITICAL_SECTION EventSourceListCs;
18
19 /* FUNCTIONS ****************************************************************/
20
21 VOID
22 InitEventSourceList(VOID)
23 {
24 InitializeCriticalSection(&EventSourceListCs);
25 InitializeListHead(&EventSourceListHead);
26 }
27
28
29 static VOID
30 DumpEventSourceList(VOID)
31 {
32 PLIST_ENTRY CurrentEntry;
33 PEVENTSOURCE EventSource;
34
35 DPRINT("DumpEventSourceList()\n");
36 EnterCriticalSection(&EventSourceListCs);
37
38 CurrentEntry = EventSourceListHead.Flink;
39 while (CurrentEntry != &EventSourceListHead)
40 {
41 EventSource = CONTAINING_RECORD(CurrentEntry,
42 EVENTSOURCE,
43 EventSourceListEntry);
44
45 DPRINT("EventSource->szName: %S\n", EventSource->szName);
46
47 CurrentEntry = CurrentEntry->Flink;
48 }
49
50 LeaveCriticalSection(&EventSourceListCs);
51
52 DPRINT("Done\n");
53 }
54
55
56 static BOOL
57 AddNewEventSource(PLOGFILE pLogFile,
58 PWSTR lpSourceName)
59 {
60 PEVENTSOURCE lpEventSource;
61
62 lpEventSource = HeapAlloc(GetProcessHeap(), 0,
63 FIELD_OFFSET(EVENTSOURCE, szName[wcslen(lpSourceName) + 1]));
64 if (lpEventSource != NULL)
65 {
66 wcscpy(lpEventSource->szName, lpSourceName);
67 lpEventSource->LogFile = pLogFile;
68
69 DPRINT("Insert event source: %S\n", lpEventSource->szName);
70
71 EnterCriticalSection(&EventSourceListCs);
72 InsertTailList(&EventSourceListHead,
73 &lpEventSource->EventSourceListEntry);
74 LeaveCriticalSection(&EventSourceListCs);
75 }
76
77 return (lpEventSource != NULL);
78 }
79
80
81 BOOL
82 LoadEventSources(HKEY hKey,
83 PLOGFILE pLogFile)
84 {
85 BOOL Success;
86 DWORD dwNumSubKeys, dwMaxSubKeyLength;
87 DWORD dwEventSourceNameLength, MaxValueLen;
88 DWORD dwIndex;
89 PWSTR Buf = NULL, SourceList = NULL, Source = NULL;
90 size_t cchRemaining = 0;
91 LONG Result;
92
93 DPRINT("LoadEventSources\n");
94
95 Result = RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &dwNumSubKeys, &dwMaxSubKeyLength,
96 NULL, NULL, NULL, NULL, NULL, NULL);
97 if (Result != ERROR_SUCCESS)
98 {
99 DPRINT1("RegQueryInfoKeyW failed: %lu\n", Result);
100 return FALSE;
101 }
102
103 dwMaxSubKeyLength++;
104
105 Buf = HeapAlloc(GetProcessHeap(), 0, dwMaxSubKeyLength * sizeof(WCHAR));
106 if (!Buf)
107 {
108 DPRINT1("Error: cannot allocate heap!\n");
109 return FALSE;
110 }
111
112 /*
113 * Allocate a buffer for storing the names of the sources as a REG_MULTI_SZ
114 * in the registry. Also add the event log as its own source.
115 * Add a final NULL-terminator.
116 */
117 MaxValueLen = dwNumSubKeys * dwMaxSubKeyLength + wcslen(pLogFile->LogName) + 2;
118 SourceList = HeapAlloc(GetProcessHeap(), 0, MaxValueLen * sizeof(WCHAR));
119 if (!SourceList)
120 {
121 DPRINT1("Error: cannot allocate heap!\n");
122 /* It is not dramatic if we cannot create it */
123 }
124 else
125 {
126 cchRemaining = MaxValueLen;
127 Source = SourceList;
128 }
129
130 /*
131 * Enumerate all the subkeys of the event log key, that constitute
132 * all the possible event sources for this event log. At this point,
133 * skip the possible existing source having the same name as the
134 * event log, it will be added later on.
135 */
136 dwEventSourceNameLength = dwMaxSubKeyLength;
137 dwIndex = 0;
138 while (RegEnumKeyExW(hKey,
139 dwIndex,
140 Buf,
141 &dwEventSourceNameLength,
142 NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
143 {
144 if (_wcsicmp(pLogFile->LogName, Buf) != 0)
145 {
146 DPRINT("Event Source: %S\n", Buf);
147 Success = AddNewEventSource(pLogFile, Buf);
148 if (Success && (Source != NULL))
149 {
150 /* Append the event source name and an extra NULL-terminator */
151 StringCchCopyExW(Source, cchRemaining, Buf, &Source, &cchRemaining, 0);
152 if (cchRemaining > 0)
153 {
154 *++Source = L'\0';
155 cchRemaining--;
156 }
157 }
158 }
159
160 dwEventSourceNameLength = dwMaxSubKeyLength;
161 dwIndex++;
162 }
163
164 /* Finally, allow the event log itself to be its own source */
165 DPRINT("Event Source: %S\n", pLogFile->LogName);
166 Success = AddNewEventSource(pLogFile, pLogFile->LogName);
167 if (Success && (Source != NULL))
168 {
169 /* Append the event source name and an extra NULL-terminator */
170 StringCchCopyExW(Source, cchRemaining, pLogFile->LogName, &Source, &cchRemaining, 0);
171 if (cchRemaining > 0)
172 {
173 *++Source = L'\0';
174 cchRemaining--;
175 }
176 }
177
178 /* Save the list of sources in the registry */
179 Result = RegSetValueExW(hKey,
180 L"Sources",
181 0,
182 REG_MULTI_SZ,
183 (LPBYTE)SourceList,
184 (MaxValueLen - cchRemaining + 1) * sizeof(WCHAR));
185 if (Result != ERROR_SUCCESS)
186 {
187 DPRINT1("RegSetValueExW failed: %lu\n", Result);
188 }
189
190 if (SourceList)
191 HeapFree(GetProcessHeap(), 0, SourceList);
192
193 HeapFree(GetProcessHeap(), 0, Buf);
194
195 DumpEventSourceList();
196
197 return TRUE;
198 }
199
200
201 PEVENTSOURCE
202 GetEventSourceByName(LPCWSTR Name)
203 {
204 PLIST_ENTRY CurrentEntry;
205 PEVENTSOURCE Item, Result = NULL;
206
207 DPRINT("GetEventSourceByName(%S)\n", Name);
208 EnterCriticalSection(&EventSourceListCs);
209
210 CurrentEntry = EventSourceListHead.Flink;
211 while (CurrentEntry != &EventSourceListHead)
212 {
213 Item = CONTAINING_RECORD(CurrentEntry,
214 EVENTSOURCE,
215 EventSourceListEntry);
216
217 DPRINT("Item->szName: %S\n", Item->szName);
218 // if ((*(Item->szName) != 0) && !_wcsicmp(Item->szName, Name))
219 if (_wcsicmp(Item->szName, Name) == 0)
220 {
221 DPRINT("Found it\n");
222 Result = Item;
223 break;
224 }
225
226 CurrentEntry = CurrentEntry->Flink;
227 }
228
229 LeaveCriticalSection(&EventSourceListCs);
230
231 DPRINT("Done (Result: %p)\n", Result);
232
233 return Result;
234 }