2 * PROJECT: ReactOS Tests
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: rostests/win32/advapi32/eventlog/EvtLogTest.c
5 * PURPOSE: Interactively test some EventLog service APIs and its behaviour.
6 * PROGRAMMER: Hermes Belusca-Maito
12 #define WIN32_LEAN_AND_MEAN
15 #include "MyEventProvider.h"
17 #define PROVIDER_NAME L"MyEventProvider"
19 BOOL
CreateEventLog(LPCWSTR EventLogName
,
22 LPCWSTR EventLogSources
[])
26 HKEY hKey
= NULL
, hEventKey
= NULL
, hSrcKey
= NULL
;
28 // WCHAR evtFile[] = L"D:\\myfile.evtx";
30 wprintf(L
"Creating log %s of MaxSize 0x%x with %d sources...", EventLogName
, MaxSize
, SourcesCount
);
32 lRet
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
33 L
"SYSTEM\\CurrentControlSet\\Services\\Eventlog",
34 0, KEY_CREATE_SUB_KEY
,
36 if (lRet
!= ERROR_SUCCESS
)
40 * At this precise moment, EventLog detects we create a new log registry key
41 * and therefore creates for us the log file in System32\config (<= Win2k3)
42 * or in System32\winevt\Logs (>= Vista).
44 lRet
= RegCreateKeyExW(hKey
,
46 0, NULL
, REG_OPTION_NON_VOLATILE
,
47 KEY_CREATE_SUB_KEY
| KEY_SET_VALUE
, NULL
,
49 if (lRet
!= ERROR_SUCCESS
)
52 RegSetValueExW(hEventKey
, L
"MaxSize", 0, REG_DWORD
,
53 (LPBYTE
)&MaxSize
, sizeof(MaxSize
));
56 RegSetValueExW(hEventKey
, L
"Retention", 0, REG_DWORD
,
57 (LPBYTE
)&i
, sizeof(i
));
61 * Set the flag that will allow EventLog to use an alternative log file name.
62 * If this flag is not set, EventLog will not care about the "File" value.
63 * When the flag is set, EventLog monitors for the "File" value, which can be
64 * changed at run-time, in which case a new event log file is created.
67 RegSetValueExW(hEventKey
, L
"Flags", 0, REG_DWORD
,
68 (LPBYTE
)&i
, sizeof(i
));
70 RegSetValueExW(hEventKey
, L
"File", 0, REG_EXPAND_SZ
,
71 (LPBYTE
)evtFile
, sizeof(evtFile
));
74 for (i
= 0; i
< SourcesCount
; i
++)
76 lRet
= RegCreateKeyExW(hEventKey
,
78 0, NULL
, REG_OPTION_NON_VOLATILE
,
79 KEY_QUERY_VALUE
, NULL
,
85 RegFlushKey(hEventKey
);
91 wprintf(L
"Success\n");
93 wprintf(L
"Failure\n");
96 RegCloseKey(hEventKey
);
104 BOOL
RemoveEventLog(LPCWSTR EventLogName
)
106 BOOL Success
= FALSE
;
108 HKEY hKey
, hEventKey
;
109 DWORD MaxKeyNameLen
, KeyNameLen
;
112 wprintf(L
"Deleting log %s...", EventLogName
);
114 lRet
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
115 L
"SYSTEM\\CurrentControlSet\\Services\\Eventlog",
116 0, KEY_CREATE_SUB_KEY
,
118 if (lRet
!= ERROR_SUCCESS
)
121 lRet
= RegOpenKeyExW(hKey
,
123 0, KEY_ENUMERATE_SUB_KEYS
| KEY_QUERY_VALUE
,
125 if (lRet
!= ERROR_SUCCESS
)
128 lRet
= RegQueryInfoKeyW(hEventKey
,
129 NULL
, NULL
, NULL
, NULL
,
131 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
132 if (lRet
!= ERROR_SUCCESS
)
137 Buf
= (LPWSTR
)HeapAlloc(GetProcessHeap(), 0, MaxKeyNameLen
* sizeof(WCHAR
));
141 KeyNameLen
= MaxKeyNameLen
;
142 while (RegEnumKeyExW(hEventKey
,
146 NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
148 RegDeleteKeyW(hEventKey
, Buf
);
149 KeyNameLen
= MaxKeyNameLen
;
152 RegFlushKey(hEventKey
);
154 HeapFree(GetProcessHeap(), 0, Buf
);
161 RegCloseKey(hEventKey
);
162 RegDeleteKeyW(hKey
, EventLogName
);
164 wprintf(L
"Success\n");
169 RegCloseKey(hEventKey
);
171 wprintf(L
"Failure\n");
180 VOID
TestEventsGeneration(VOID
)
182 BOOL Success
= FALSE
;
183 LPCWSTR EvtLog
= L
"MyLog";
184 LPCWSTR Sources
[] = {L
"Source1", L
"Source2"};
186 ULONG MaxSize
= max(0x30 + 0x28 + 0x200, 0x010000);
188 /* Create the test event log */
189 if (!CreateEventLog(EvtLog
, MaxSize
, ARRAYSIZE(Sources
), Sources
))
192 wprintf(L
"Press any key to continue...\n");
195 /* To report events we can either use a handle got from OpenEventLog or from RegisterEventSource! */
196 hEventLog
= OpenEventLogW(NULL
, EvtLog
);
197 wprintf(L
"OpenEventLogW(NULL, EvtLog = %s) ", EvtLog
);
200 LPCWSTR String
= L
"Event from OpenEventLog handle with EvtLog";
202 wprintf(L
"succeeded\n");
203 Success
= ReportEventW(hEventLog
, EVENTLOG_INFORMATION_TYPE
, 1, 1, NULL
, 1, 0, &String
, NULL
);
205 wprintf(L
" Failed to report event\n");
209 wprintf(L
"failed\n");
211 CloseEventLog(hEventLog
);
213 /* This call should fail (where we use a source name for OpenEventLog) */
214 hEventLog
= OpenEventLogW(NULL
, L
"Source1");
215 wprintf(L
"OpenEventLogW(NULL, Source = %s) ", L
"Source1");
218 LPCWSTR String
= L
"Event from OpenEventLog handle with Source";
220 wprintf(L
"succeeded\n");
221 Success
= ReportEventW(hEventLog
, EVENTLOG_INFORMATION_TYPE
, 1, 1, NULL
, 1, 0, &String
, NULL
);
223 wprintf(L
" Failed to report event\n");
227 wprintf(L
"failed\n");
229 CloseEventLog(hEventLog
);
231 /* Now use RegisterEventSource */
232 hEventLog
= RegisterEventSourceW(NULL
, EvtLog
);
233 wprintf(L
"RegisterEventSourceW(NULL, EvtLog = %s) ", EvtLog
);
236 LPCWSTR String
= L
"Event from RegisterEventSource handle with EvtLog";
238 wprintf(L
"succeeded\n");
239 Success
= ReportEventW(hEventLog
, EVENTLOG_INFORMATION_TYPE
, 1, 1, NULL
, 1, 0, &String
, NULL
);
241 wprintf(L
" Failed to report event\n");
245 wprintf(L
"failed\n");
247 DeregisterEventSource(hEventLog
);
249 /* Now use RegisterEventSource */
250 hEventLog
= RegisterEventSourceW(NULL
, L
"Source1");
251 wprintf(L
"RegisterEventSourceW(NULL, Source = %s) ", L
"Source1");
254 LPCWSTR String
= L
"Event from RegisterEventSource handle with Source";
256 wprintf(L
"succeeded\n");
257 Success
= ReportEventW(hEventLog
, EVENTLOG_INFORMATION_TYPE
, 1, 1, NULL
, 1, 0, &String
, NULL
);
259 wprintf(L
" Failed to report event\n");
263 wprintf(L
"failed\n");
265 DeregisterEventSource(hEventLog
);
267 /* Now fill the log with one big event */
268 hEventLog
= OpenEventLogW(NULL
, EvtLog
);
269 wprintf(L
"OpenEventLogW(NULL, EvtLog = %s) ", EvtLog
);
272 // LPWSTR String = L"Big event";
275 wprintf(L
"succeeded\n");
277 // MaxSize -= (0x30 + 0x28 + 0x300 + 0x40);
278 MaxSize
= 0xFC80 - sizeof(EVENTLOGRECORD
); // With a StartOffset of 0x14, that should allow seeing the effect of splitting the EOF record in half...
279 Data
= HeapAlloc(GetProcessHeap(), 0, MaxSize
);
282 RtlFillMemory(Data
, MaxSize
, 0xCA);
283 Success
= ReportEventW(hEventLog
, EVENTLOG_INFORMATION_TYPE
, 1, 1, NULL
, 0 /* 1 */, MaxSize
, NULL
/* &String */, Data
);
285 wprintf(L
" Failed to report event\n");
287 HeapFree(GetProcessHeap(), 0, Data
);
292 wprintf(L
"failed\n");
294 CloseEventLog(hEventLog
);
296 wprintf(L
"Press any key to continue...\n");
299 /* Delete the test event log */
300 RemoveEventLog(EvtLog
);
304 * This code was adapted from the MSDN article "Reporting Events" at:
305 * https://msdn.microsoft.com/en-us/library/windows/desktop/aa363680(v=vs.85).aspx
307 VOID
TestMyEventProvider(VOID
)
310 HKEY hKey
= NULL
, hSourceKey
= NULL
;
312 // WCHAR DllPath[] = L"C:\\Users\\ReactOS\\Desktop\\EvtLogTest\\Debug\\" PROVIDER_NAME L".dll";
313 WCHAR DllPath
[] = L
"C:\\" PROVIDER_NAME L
".dll";
315 wprintf(L
"Testing \"" PROVIDER_NAME L
"\" in 'Application' log...");
317 lRet
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
318 L
"SYSTEM\\CurrentControlSet\\Services\\Eventlog\\Application",
319 0, KEY_CREATE_SUB_KEY
,
321 if (lRet
!= ERROR_SUCCESS
)
324 lRet
= RegCreateKeyExW(hKey
,
326 0, NULL
, REG_OPTION_NON_VOLATILE
,
327 KEY_CREATE_SUB_KEY
| KEY_SET_VALUE
, NULL
,
329 if (lRet
!= ERROR_SUCCESS
)
333 RegSetValueExW(hSourceKey
, L
"CategoryCount", 0, REG_DWORD
,
334 (LPBYTE
)&dwData
, sizeof(dwData
));
336 dwData
= EVENTLOG_ERROR_TYPE
| EVENTLOG_WARNING_TYPE
| EVENTLOG_INFORMATION_TYPE
;
337 RegSetValueExW(hSourceKey
, L
"TypesSupported", 0, REG_DWORD
,
338 (LPBYTE
)&dwData
, sizeof(dwData
));
340 RegSetValueExW(hSourceKey
, L
"CategoryMessageFile", 0, REG_SZ
,
341 (LPBYTE
)DllPath
, sizeof(DllPath
));
343 RegSetValueExW(hSourceKey
, L
"EventMessageFile", 0, REG_SZ
,
344 (LPBYTE
)DllPath
, sizeof(DllPath
));
346 RegSetValueExW(hSourceKey
, L
"ParameterMessageFile", 0, REG_SZ
,
347 (LPBYTE
)DllPath
, sizeof(DllPath
));
349 RegFlushKey(hSourceKey
);
352 CONST LPWSTR pBadCommand
= L
"The command that was not valid";
353 CONST LPWSTR pFilename
= L
"c:\\folder\\file.ext";
354 CONST LPWSTR pNumberOfRetries
= L
"3";
355 CONST LPWSTR pSuccessfulRetries
= L
"0";
356 CONST LPWSTR pQuarts
= L
"8";
357 CONST LPWSTR pGallons
= L
"2";
359 HANDLE hEventLog
= NULL
;
360 LPWSTR pInsertStrings
[2] = {NULL
, NULL
};
361 DWORD dwEventDataSize
= 0;
363 // The source name (provider) must exist as a subkey of Application.
364 hEventLog
= RegisterEventSourceW(NULL
, PROVIDER_NAME
);
365 if (NULL
== hEventLog
)
367 wprintf(L
"RegisterEventSource failed with 0x%x.\n", GetLastError());
371 // This event includes user-defined data as part of the event.
372 // The event message does not use insert strings.
373 dwEventDataSize
= ((DWORD
)wcslen(pBadCommand
) + 1) * sizeof(WCHAR
);
374 if (!ReportEventW(hEventLog
, EVENTLOG_ERROR_TYPE
, UI_CATEGORY
, MSG_INVALID_COMMAND
, NULL
, 0, dwEventDataSize
, NULL
, pBadCommand
))
376 wprintf(L
"ReportEvent failed with 0x%x for event 0x%x.\n", GetLastError(), MSG_INVALID_COMMAND
);
380 // This event uses insert strings.
381 pInsertStrings
[0] = pFilename
;
382 if (!ReportEventW(hEventLog
, EVENTLOG_ERROR_TYPE
, DATABASE_CATEGORY
, MSG_BAD_FILE_CONTENTS
, NULL
, 1, 0, (LPCWSTR
*)pInsertStrings
, NULL
))
384 wprintf(L
"ReportEvent failed with 0x%x for event 0x%x.\n", GetLastError(), MSG_BAD_FILE_CONTENTS
);
388 // This event uses insert strings.
389 pInsertStrings
[0] = pNumberOfRetries
;
390 pInsertStrings
[1] = pSuccessfulRetries
;
391 if (!ReportEventW(hEventLog
, EVENTLOG_WARNING_TYPE
, NETWORK_CATEGORY
, MSG_RETRIES
, NULL
, 2, 0, (LPCWSTR
*)pInsertStrings
, NULL
))
393 wprintf(L
"ReportEvent failed with 0x%x for event 0x%x.\n", GetLastError(), MSG_RETRIES
);
397 // This event uses insert strings.
398 pInsertStrings
[0] = pQuarts
;
399 pInsertStrings
[1] = pGallons
;
400 if (!ReportEventW(hEventLog
, EVENTLOG_INFORMATION_TYPE
, UI_CATEGORY
, MSG_COMPUTE_CONVERSION
, NULL
, 2, 0, (LPCWSTR
*)pInsertStrings
, NULL
))
402 wprintf(L
"ReportEvent failed with 0x%x for event 0x%x.\n", GetLastError(), MSG_COMPUTE_CONVERSION
);
406 wprintf(L
"All events successfully reported.\n");
411 DeregisterEventSource(hEventLog
);
416 // RegDeleteKeyW(hKey, PROVIDER_NAME);
422 int wmain(int argc
, WCHAR
* argv
[])
427 L
"EventLog API interactive tester for ReactOS\n"
428 L
"===========================================\n"
434 wprintf(L
"What do you want to do:\n"
435 L
"1) Test events generation.\n"
436 L
"2) Test customized event provider.\n"
438 L
"0) Quit the program.\n"
439 L
"(Enter the right number, or 0 to quit): ");
440 wscanf(L
"%lu", &Choice
);
442 } while ((Choice
!= 0) && (Choice
!= 1) && (Choice
!= 2));
451 TestEventsGeneration();
455 TestMyEventProvider();
461 wprintf(L
"\n\n\n\n");
465 wprintf(L
"Press any key to quit...\n");