rsaenh: Fix padding bytes check for 0-byte payload.
[wine] / dlls / advapi32 / tests / eventlog.c
1 /*
2  * Unit tests for Event Logging functions
3  *
4  * Copyright (c) 2009 Paul Vriens
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include <stdarg.h>
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winerror.h"
26 #include "winnt.h"
27 #include "winreg.h"
28 #include "sddl.h"
29
30 #include "wine/test.h"
31
32 static BOOL (WINAPI *pCreateWellKnownSid)(WELL_KNOWN_SID_TYPE,PSID,PSID,DWORD*);
33 static BOOL (WINAPI *pGetEventLogInformation)(HANDLE,DWORD,LPVOID,DWORD,LPDWORD);
34 static BOOL (WINAPI *pWow64DisableWow64FsRedirection)(PVOID *);
35 static BOOL (WINAPI *pWow64RevertWow64FsRedirection)(PVOID);
36
37 static void init_function_pointers(void)
38 {
39     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
40     HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
41
42     pCreateWellKnownSid = (void*)GetProcAddress(hadvapi32, "CreateWellKnownSid");
43     pGetEventLogInformation = (void*)GetProcAddress(hadvapi32, "GetEventLogInformation");
44
45     pWow64DisableWow64FsRedirection = (void*)GetProcAddress(hkernel32, "Wow64DisableWow64FsRedirection");
46     pWow64RevertWow64FsRedirection = (void*)GetProcAddress(hkernel32, "Wow64RevertWow64FsRedirection");
47 }
48
49 static void create_backup(const char *filename)
50 {
51     HANDLE handle;
52
53     DeleteFileA(filename);
54     handle = OpenEventLogA(NULL, "Application");
55     BackupEventLogA(handle, filename);
56     CloseEventLog(handle);
57
58     todo_wine
59     ok(GetFileAttributesA(filename) != INVALID_FILE_ATTRIBUTES, "Expected a backup file\n");
60 }
61
62 static void test_open_close(void)
63 {
64     HANDLE handle;
65     BOOL ret;
66
67     SetLastError(0xdeadbeef);
68     ret = CloseEventLog(NULL);
69     ok(!ret, "Expected failure\n");
70     ok(GetLastError() == ERROR_INVALID_HANDLE ||
71        GetLastError() == ERROR_NOACCESS, /* W2K */
72        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
73
74     SetLastError(0xdeadbeef);
75     handle = OpenEventLogA(NULL, NULL);
76     ok(handle == NULL, "Didn't expect a handle\n");
77     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
78
79     SetLastError(0xdeadbeef);
80     handle = OpenEventLogA("IDontExist", NULL);
81     ok(handle == NULL, "Didn't expect a handle\n");
82     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
83
84     SetLastError(0xdeadbeef);
85     handle = OpenEventLogA("IDontExist", "deadbeef");
86     ok(handle == NULL, "Didn't expect a handle\n");
87     ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE ||
88        GetLastError() == RPC_S_INVALID_NET_ADDR, /* Some Vista and Win7 */
89        "Expected RPC_S_SERVER_UNAVAILABLE, got %d\n", GetLastError());
90
91     /* This one opens the Application log */
92     handle = OpenEventLogA(NULL, "deadbeef");
93     ok(handle != NULL, "Expected a handle\n");
94     ret = CloseEventLog(handle);
95     ok(ret, "Expected success\n");
96     /* Close a second time */
97     SetLastError(0xdeadbeef);
98     ret = CloseEventLog(handle);
99     todo_wine
100     {
101     ok(!ret, "Expected failure\n");
102     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
103     }
104
105     /* Empty servername should be read as local server */
106     handle = OpenEventLogA("", "Application");
107     ok(handle != NULL, "Expected a handle\n");
108     CloseEventLog(handle);
109
110     handle = OpenEventLogA(NULL, "Application");
111     ok(handle != NULL, "Expected a handle\n");
112     CloseEventLog(handle);
113 }
114
115 static void test_info(void)
116 {
117     HANDLE handle;
118     BOOL ret;
119     DWORD needed;
120     EVENTLOG_FULL_INFORMATION efi;
121
122     if (!pGetEventLogInformation)
123     {
124         /* NT4 */
125         win_skip("GetEventLogInformation is not available\n");
126         return;
127     }
128     SetLastError(0xdeadbeef);
129     ret = pGetEventLogInformation(NULL, 1, NULL, 0, NULL);
130     ok(!ret, "Expected failure\n");
131     ok(GetLastError() == ERROR_INVALID_LEVEL, "Expected ERROR_INVALID_LEVEL, got %d\n", GetLastError());
132
133     SetLastError(0xdeadbeef);
134     ret = pGetEventLogInformation(NULL, EVENTLOG_FULL_INFO, NULL, 0, NULL);
135     ok(!ret, "Expected failure\n");
136     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
137
138     handle = OpenEventLogA(NULL, "Application");
139
140     SetLastError(0xdeadbeef);
141     ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, NULL, 0, NULL);
142     ok(!ret, "Expected failure\n");
143     ok(GetLastError() == RPC_X_NULL_REF_POINTER, "Expected RPC_X_NULL_REF_POINTER, got %d\n", GetLastError());
144
145     SetLastError(0xdeadbeef);
146     ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, NULL, 0, &needed);
147     ok(!ret, "Expected failure\n");
148     ok(GetLastError() == RPC_X_NULL_REF_POINTER, "Expected RPC_X_NULL_REF_POINTER, got %d\n", GetLastError());
149
150     SetLastError(0xdeadbeef);
151     ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, (LPVOID)&efi, 0, NULL);
152     ok(!ret, "Expected failure\n");
153     ok(GetLastError() == RPC_X_NULL_REF_POINTER, "Expected RPC_X_NULL_REF_POINTER, got %d\n", GetLastError());
154
155     SetLastError(0xdeadbeef);
156     needed = 0xdeadbeef;
157     efi.dwFull = 0xdeadbeef;
158     ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, (LPVOID)&efi, 0, &needed);
159     ok(!ret, "Expected failure\n");
160     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
161     ok(needed == sizeof(EVENTLOG_FULL_INFORMATION), "Expected sizeof(EVENTLOG_FULL_INFORMATION), got %d\n", needed);
162     ok(efi.dwFull == 0xdeadbeef, "Expected no change to the dwFull member\n");
163
164     /* Not that we care, but on success last error is set to ERROR_IO_PENDING */
165     efi.dwFull = 0xdeadbeef;
166     needed *= 2;
167     ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, (LPVOID)&efi, needed, &needed);
168     ok(ret, "Expected success\n");
169     ok(needed == sizeof(EVENTLOG_FULL_INFORMATION), "Expected sizeof(EVENTLOG_FULL_INFORMATION), got %d\n", needed);
170     ok(efi.dwFull == 0 || efi.dwFull == 1, "Expected 0 (not full) or 1 (full), got %d\n", efi.dwFull);
171
172     CloseEventLog(handle);
173 }
174
175 static void test_count(void)
176 {
177     HANDLE handle;
178     BOOL ret;
179     DWORD count;
180     const char backup[] = "backup.evt";
181
182     SetLastError(0xdeadbeef);
183     ret = GetNumberOfEventLogRecords(NULL, NULL);
184     ok(!ret, "Expected failure\n");
185     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
186
187     SetLastError(0xdeadbeef);
188     count = 0xdeadbeef;
189     ret = GetNumberOfEventLogRecords(NULL, &count);
190     ok(!ret, "Expected failure\n");
191     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
192     ok(count == 0xdeadbeef, "Expected count to stay unchanged\n");
193
194     handle = OpenEventLogA(NULL, "Application");
195
196     SetLastError(0xdeadbeef);
197     ret = GetNumberOfEventLogRecords(handle, NULL);
198     ok(!ret, "Expected failure\n");
199     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
200
201     count = 0xdeadbeef;
202     ret = GetNumberOfEventLogRecords(handle, &count);
203     ok(ret, "Expected success\n");
204     ok(count != 0xdeadbeef, "Expected the number of records\n");
205
206     CloseEventLog(handle);
207
208     /* Make a backup eventlog to work with */
209     create_backup(backup);
210
211     handle = OpenBackupEventLogA(NULL, backup);
212     todo_wine
213     ok(handle != NULL, "Expected a handle\n");
214
215     /* Does GetNumberOfEventLogRecords work with backup eventlogs? */
216     count = 0xdeadbeef;
217     ret = GetNumberOfEventLogRecords(handle, &count);
218     todo_wine
219     {
220     ok(ret, "Expected success\n");
221     ok(count != 0xdeadbeef, "Expected the number of records\n");
222     }
223
224     CloseEventLog(handle);
225     DeleteFileA(backup);
226 }
227
228 static void test_oldest(void)
229 {
230     HANDLE handle;
231     BOOL ret;
232     DWORD oldest;
233     const char backup[] = "backup.evt";
234
235     SetLastError(0xdeadbeef);
236     ret = GetOldestEventLogRecord(NULL, NULL);
237     ok(!ret, "Expected failure\n");
238     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
239
240     SetLastError(0xdeadbeef);
241     oldest = 0xdeadbeef;
242     ret = GetOldestEventLogRecord(NULL, &oldest);
243     ok(!ret, "Expected failure\n");
244     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
245     ok(oldest == 0xdeadbeef, "Expected oldest to stay unchanged\n");
246
247     handle = OpenEventLogA(NULL, "Application");
248
249     SetLastError(0xdeadbeef);
250     ret = GetOldestEventLogRecord(handle, NULL);
251     ok(!ret, "Expected failure\n");
252     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
253
254     oldest = 0xdeadbeef;
255     ret = GetOldestEventLogRecord(handle, &oldest);
256     ok(ret, "Expected success\n");
257     ok(oldest != 0xdeadbeef, "Expected the number of the oldest record\n");
258
259     CloseEventLog(handle);
260
261     /* Make a backup eventlog to work with */
262     create_backup(backup);
263
264     handle = OpenBackupEventLogA(NULL, backup);
265     todo_wine
266     ok(handle != NULL, "Expected a handle\n");
267
268     /* Does GetOldestEventLogRecord work with backup eventlogs? */
269     oldest = 0xdeadbeef;
270     ret = GetOldestEventLogRecord(handle, &oldest);
271     todo_wine
272     {
273     ok(ret, "Expected success\n");
274     ok(oldest != 0xdeadbeef, "Expected the number of the oldest record\n");
275     }
276
277     CloseEventLog(handle);
278     DeleteFileA(backup);
279 }
280
281 static void test_backup(void)
282 {
283     HANDLE handle;
284     BOOL ret;
285     const char backup[] = "backup.evt";
286     const char backup2[] = "backup2.evt";
287
288     SetLastError(0xdeadbeef);
289     ret = BackupEventLogA(NULL, NULL);
290     ok(!ret, "Expected failure\n");
291     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
292
293     SetLastError(0xdeadbeef);
294     ret = BackupEventLogA(NULL, backup);
295     ok(!ret, "Expected failure\n");
296     ok(GetFileAttributesA(backup) == INVALID_FILE_ATTRIBUTES, "Expected no backup file\n");
297
298     handle = OpenEventLogA(NULL, "Application");
299
300     SetLastError(0xdeadbeef);
301     ret = BackupEventLogA(handle, NULL);
302     ok(!ret, "Expected failure\n");
303     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
304
305     ret = BackupEventLogA(handle, backup);
306     ok(ret, "Expected success\n");
307     todo_wine
308     ok(GetFileAttributesA(backup) != INVALID_FILE_ATTRIBUTES, "Expected a backup file\n");
309
310     /* Try to overwrite */
311     SetLastError(0xdeadbeef);
312     ret = BackupEventLogA(handle, backup);
313     todo_wine
314     {
315     ok(!ret, "Expected failure\n");
316     ok(GetLastError() == ERROR_ALREADY_EXISTS, "Expected ERROR_ALREADY_EXISTS, got %d\n", GetLastError());
317     }
318
319     CloseEventLog(handle);
320
321     /* Can we make a backup of a backup? */
322     handle = OpenBackupEventLogA(NULL, backup);
323     todo_wine
324     ok(handle != NULL, "Expected a handle\n");
325
326     ret = BackupEventLogA(handle, backup2);
327     todo_wine
328     {
329     ok(ret, "Expected success\n");
330     ok(GetFileAttributesA(backup2) != INVALID_FILE_ATTRIBUTES, "Expected a backup file\n");
331     }
332
333     CloseEventLog(handle);
334     DeleteFileA(backup);
335     DeleteFileA(backup2);
336 }
337
338 static void test_read(void)
339 {
340     HANDLE handle;
341     BOOL ret;
342     DWORD count, toread, read, needed;
343     void *buf;
344
345     SetLastError(0xdeadbeef);
346     ret = ReadEventLogA(NULL, 0, 0, NULL, 0, NULL, NULL);
347     ok(!ret, "Expected failure\n");
348     todo_wine
349     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
350
351     read = 0xdeadbeef;
352     SetLastError(0xdeadbeef);
353     ret = ReadEventLogA(NULL, 0, 0, NULL, 0, &read, NULL);
354     ok(!ret, "Expected failure\n");
355     ok(read == 0xdeadbeef, "Expected 'read' parameter to remain unchanged\n");
356     todo_wine
357     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
358
359     needed = 0xdeadbeef;
360     SetLastError(0xdeadbeef);
361     ret = ReadEventLogA(NULL, 0, 0, NULL, 0, NULL, &needed);
362     ok(!ret, "Expected failure\n");
363     ok(needed == 0xdeadbeef, "Expected 'needed' parameter to remain unchanged\n");
364     todo_wine
365     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
366
367     /* 'read' and 'needed' are only filled when the needed buffer size is passed back or when the call succeeds */
368     SetLastError(0xdeadbeef);
369     ret = ReadEventLogA(NULL, 0, 0, NULL, 0, &read, &needed);
370     ok(!ret, "Expected failure\n");
371     todo_wine
372     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
373
374     SetLastError(0xdeadbeef);
375     ret = ReadEventLogA(NULL, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, NULL, 0, NULL, NULL);
376     ok(!ret, "Expected failure\n");
377     todo_wine
378     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
379
380     SetLastError(0xdeadbeef);
381     ret = ReadEventLogA(NULL, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, NULL, 0, &read, &needed);
382     ok(!ret, "Expected failure\n");
383     todo_wine
384     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
385
386     buf = NULL;
387     SetLastError(0xdeadbeef);
388     ret = ReadEventLogA(NULL, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
389                         0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
390     ok(!ret, "Expected failure\n");
391     todo_wine
392     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
393
394     buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD));
395     SetLastError(0xdeadbeef);
396     ret = ReadEventLogA(NULL, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
397                         0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
398     ok(!ret, "Expected failure\n");
399     todo_wine
400     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
401     HeapFree(GetProcessHeap(), 0, buf);
402
403     handle = OpenEventLogA(NULL, "Application");
404
405     /* Show that we need the proper dwFlags with a (for the rest) proper call */
406     buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD));
407
408     SetLastError(0xdeadbeef);
409     ret = ReadEventLogA(handle, 0, 0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
410     ok(!ret, "Expected failure\n");
411     todo_wine
412     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
413
414     SetLastError(0xdeadbeef);
415     ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ, 0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
416     ok(!ret, "Expected failure\n");
417     todo_wine
418     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
419
420     SetLastError(0xdeadbeef);
421     ret = ReadEventLogA(handle, EVENTLOG_SEEK_READ, 0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
422     ok(!ret, "Expected failure\n");
423     todo_wine
424     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
425
426     SetLastError(0xdeadbeef);
427     ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ | EVENTLOG_BACKWARDS_READ,
428                         0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
429     ok(!ret, "Expected failure\n");
430     todo_wine
431     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
432
433     SetLastError(0xdeadbeef);
434     ret = ReadEventLogA(handle, EVENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ | EVENTLOG_BACKWARDS_READ,
435                         0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
436     ok(!ret, "Expected failure\n");
437     todo_wine
438     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
439
440     SetLastError(0xdeadbeef);
441     ret = ReadEventLogA(handle, EVENTLOG_SEEK_READ | EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
442                         0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
443     ok(!ret, "Expected failure\n");
444     todo_wine
445     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
446
447     HeapFree(GetProcessHeap(), 0, buf);
448
449     /* First check if there are any records (in practice only on Wine: FIXME) */
450     count = 0;
451     GetNumberOfEventLogRecords(handle, &count);
452     if (!count)
453     {
454         skip("No records in the 'Application' log\n");
455         CloseEventLog(handle);
456         return;
457     }
458
459     /* Get the buffer size for the first record */
460     buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD));
461     read = needed = 0xdeadbeef;
462     SetLastError(0xdeadbeef);
463     ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
464                         0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
465     ok(!ret, "Expected failure\n");
466     ok(read == 0, "Expected no bytes read\n");
467     ok(needed > sizeof(EVENTLOGRECORD), "Expected the needed buffersize to be bigger than sizeof(EVENTLOGRECORD)\n");
468     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
469
470     /* Read the first record */
471     toread = needed;
472     buf = HeapReAlloc(GetProcessHeap(), 0, buf, toread);
473     read = needed = 0xdeadbeef;
474     SetLastError(0xdeadbeef);
475     ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, buf, toread, &read, &needed);
476     ok(ret, "Expected success\n");
477     ok(read == toread ||
478        broken(read < toread), /* NT4 wants a buffer size way bigger than just 1 record */
479        "Expected the requested size to be read\n");
480     ok(needed == 0, "Expected no extra bytes to be read\n");
481     HeapFree(GetProcessHeap(), 0, buf);
482
483     CloseEventLog(handle);
484 }
485
486 static void test_openbackup(void)
487 {
488     HANDLE handle, handle2, file;
489     DWORD written;
490     const char backup[] = "backup.evt";
491     const char text[] = "Just some text";
492
493     SetLastError(0xdeadbeef);
494     handle = OpenBackupEventLogA(NULL, NULL);
495     ok(handle == NULL, "Didn't expect a handle\n");
496     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
497
498     SetLastError(0xdeadbeef);
499     handle = OpenBackupEventLogA(NULL, "idontexist.evt");
500     ok(handle == NULL, "Didn't expect a handle\n");
501     ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
502
503     SetLastError(0xdeadbeef);
504     handle = OpenBackupEventLogA("IDontExist", NULL);
505     ok(handle == NULL, "Didn't expect a handle\n");
506     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
507
508     SetLastError(0xdeadbeef);
509     handle = OpenBackupEventLogA("IDontExist", "idontexist.evt");
510     ok(handle == NULL, "Didn't expect a handle\n");
511     ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE ||
512        GetLastError() == RPC_S_INVALID_NET_ADDR, /* Some Vista and Win7 */
513        "Expected RPC_S_SERVER_UNAVAILABLE, got %d\n", GetLastError());
514
515     /* Make a backup eventlog to work with */
516     create_backup(backup);
517
518     /* FIXME: Wine stops here */
519     if (GetFileAttributesA(backup) == INVALID_FILE_ATTRIBUTES)
520     {
521         skip("We don't have a backup eventlog to work with\n");
522         return;
523     }
524
525     SetLastError(0xdeadbeef);
526     handle = OpenBackupEventLogA("IDontExist", backup);
527     ok(handle == NULL, "Didn't expect a handle\n");
528     ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE ||
529        GetLastError() == RPC_S_INVALID_NET_ADDR, /* Some Vista and Win7 */
530        "Expected RPC_S_SERVER_UNAVAILABLE, got %d\n", GetLastError());
531
532     /* Empty servername should be read as local server */
533     handle = OpenBackupEventLogA("", backup);
534     ok(handle != NULL, "Expected a handle\n");
535     CloseEventLog(handle);
536
537     handle = OpenBackupEventLogA(NULL, backup);
538     ok(handle != NULL, "Expected a handle\n");
539
540     /* Can we open that same backup eventlog more than once? */
541     handle2 = OpenBackupEventLogA(NULL, backup);
542     ok(handle2 != NULL, "Expected a handle\n");
543     ok(handle2 != handle, "Didn't expect the same handle\n");
544     CloseEventLog(handle2);
545
546     CloseEventLog(handle);
547     DeleteFileA(backup);
548
549     /* Is there any content checking done? */
550     file = CreateFileA(backup, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL);
551     CloseHandle(file);
552     SetLastError(0xdeadbeef);
553     handle = OpenBackupEventLogA(NULL, backup);
554     ok(handle == NULL, "Didn't expect a handle\n");
555     ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY ||
556        GetLastError() == ERROR_EVENTLOG_FILE_CORRUPT, /* Vista and Win7 */
557        "Expected ERROR_NOT_ENOUGH_MEMORY, got %d\n", GetLastError());
558     CloseEventLog(handle);
559     DeleteFileA(backup);
560
561     file = CreateFileA(backup, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL);
562     WriteFile(file, text, sizeof(text), &written, NULL);
563     CloseHandle(file);
564     SetLastError(0xdeadbeef);
565     handle = OpenBackupEventLogA(NULL, backup);
566     ok(handle == NULL, "Didn't expect a handle\n");
567     ok(GetLastError() == ERROR_EVENTLOG_FILE_CORRUPT, "Expected ERROR_EVENTLOG_FILE_CORRUPT, got %d\n", GetLastError());
568     CloseEventLog(handle);
569     DeleteFileA(backup);
570 }
571
572 static void test_clear(void)
573 {
574     HANDLE handle;
575     BOOL ret;
576     const char backup[] = "backup.evt";
577     const char backup2[] = "backup2.evt";
578
579     SetLastError(0xdeadbeef);
580     ret = ClearEventLogA(NULL, NULL);
581     ok(!ret, "Expected failure\n");
582     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
583
584     /* Make a backup eventlog to work with */
585     create_backup(backup);
586
587     SetLastError(0xdeadbeef);
588     ret = ClearEventLogA(NULL, backup);
589     ok(!ret, "Expected failure\n");
590     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
591
592     handle = OpenBackupEventLogA(NULL, backup);
593     todo_wine
594     ok(handle != NULL, "Expected a handle\n");
595
596     /* A real eventlog would fail with ERROR_ALREADY_EXISTS */
597     SetLastError(0xdeadbeef);
598     ret = ClearEventLogA(handle, backup);
599     ok(!ret, "Expected failure\n");
600     /* The eventlog service runs under an account that doesn't have the necessary
601      * permissions on the users home directory on a default Vista+ system.
602      */
603     ok(GetLastError() == ERROR_INVALID_HANDLE ||
604        GetLastError() == ERROR_ACCESS_DENIED, /* Vista+ */
605        "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
606
607     /* Show that ClearEventLog only works for real eventlogs. */
608     SetLastError(0xdeadbeef);
609     ret = ClearEventLogA(handle, backup2);
610     ok(!ret, "Expected failure\n");
611     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
612     ok(GetFileAttributesA(backup2) == INVALID_FILE_ATTRIBUTES, "Expected no backup file\n");
613
614     SetLastError(0xdeadbeef);
615     ret = ClearEventLogA(handle, NULL);
616     ok(!ret, "Expected failure\n");
617     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
618
619     CloseEventLog(handle);
620     todo_wine
621     ok(DeleteFileA(backup), "Could not delete the backup file\n");
622 }
623
624 static const char eventlogsvc[] = "SYSTEM\\CurrentControlSet\\Services\\Eventlog";
625 static const char eventlogname[] = "Wine";
626 static const char eventsources[][11] = { "WineSrc", "WineSrc1", "WineSrc20", "WineSrc300" };
627
628 static BOOL create_new_eventlog(void)
629 {
630     HKEY key, eventkey;
631     BOOL bret = FALSE;
632     LONG lret;
633     int i;
634
635     /* First create our eventlog */
636     lret = RegOpenKeyA(HKEY_LOCAL_MACHINE, eventlogsvc, &key);
637      /* FIXME: Wine stops here */
638     if (lret != ERROR_SUCCESS)
639     {
640         skip("Could not open the EventLog service registry key\n");
641         return FALSE;
642     }
643     lret = RegCreateKeyA(key, eventlogname, &eventkey);
644     if (lret != ERROR_SUCCESS)
645     {
646         skip("Could not create the eventlog '%s' registry key\n", eventlogname);
647         goto cleanup;
648     }
649
650     /* Create some event sources, the registry value 'Sources' is updated automatically */
651     for (i = 0; i < sizeof(eventsources)/sizeof(eventsources[0]); i++)
652     {
653         HKEY srckey;
654
655         lret = RegCreateKeyA(eventkey, eventsources[i], &srckey);
656         if (lret != ERROR_SUCCESS)
657         {
658             skip("Could not create the eventsource '%s' registry key\n", eventsources[i]);
659             goto cleanup;
660         }
661         RegFlushKey(srckey);
662         RegCloseKey(srckey);
663     }
664
665     bret = TRUE;
666
667     /* The flushing of the registry (here and above) gives us some assurance
668      * that we are not to quickly writing events as 'Sources' could still be
669      * not updated.
670      */
671     RegFlushKey(eventkey);
672 cleanup:
673     RegCloseKey(eventkey);
674     RegCloseKey(key);
675
676     return bret;
677 }
678
679 static const char *one_string[] = { "First string" };
680 static const char *two_strings[] = { "First string", "Second string" };
681 static const struct
682 {
683     const char  *evt_src;
684     WORD         evt_type;
685     WORD         evt_cat;
686     DWORD        evt_id;
687     BOOL         evt_sid;
688     WORD         evt_numstrings;
689     const char **evt_strings;
690 } read_write [] =
691 {
692     { eventlogname,    EVENTLOG_INFORMATION_TYPE, 1, 1,  FALSE, 1, one_string },
693     { eventsources[0], EVENTLOG_WARNING_TYPE,     1, 2,  FALSE, 0, NULL },
694     { eventsources[1], EVENTLOG_AUDIT_FAILURE,    1, 3,  FALSE, 2, two_strings },
695     { eventsources[2], EVENTLOG_ERROR_TYPE,       1, 4,  FALSE, 0, NULL },
696     { eventsources[3], EVENTLOG_WARNING_TYPE,     1, 5,  FALSE, 1, one_string },
697     { eventlogname,    EVENTLOG_SUCCESS,          2, 6,  TRUE,  2, two_strings },
698     { eventsources[0], EVENTLOG_AUDIT_FAILURE,    2, 7,  TRUE,  0, NULL },
699     { eventsources[1], EVENTLOG_AUDIT_SUCCESS,    2, 8,  TRUE,  2, two_strings },
700     { eventsources[2], EVENTLOG_WARNING_TYPE,     2, 9,  TRUE,  0, NULL },
701     { eventsources[3], EVENTLOG_ERROR_TYPE,       2, 10, TRUE,  1, one_string }
702 };
703
704 static void test_readwrite(void)
705 {
706     HANDLE handle;
707     PSID user;
708     DWORD sidsize, count;
709     BOOL ret, sidavailable;
710     BOOL on_vista = FALSE; /* Used to indicate Vista, W2K8 or Win7 */
711     int i;
712     char localcomputer[MAX_COMPUTERNAME_LENGTH + 1];
713     DWORD len = sizeof(localcomputer);
714
715     if (pCreateWellKnownSid)
716     {
717         sidsize = SECURITY_MAX_SID_SIZE;
718         user = HeapAlloc(GetProcessHeap(), 0, sidsize);
719         SetLastError(0xdeadbeef);
720         pCreateWellKnownSid(WinInteractiveSid, NULL, user, &sidsize);
721         sidavailable = TRUE;
722     }
723     else
724     {
725         win_skip("Skipping some SID related tests\n");
726         sidavailable = FALSE;
727         user = NULL;
728     }
729
730     GetComputerNameA(localcomputer, &len);
731
732     /* Write an event with an incorrect event type. This will fail on Windows 7
733      * but succeed on all others, hence it's not part of the struct.
734      */
735     handle = OpenEventLogA(NULL, eventlogname);
736     if (!handle)
737     {
738         /* Intermittently seen on NT4 when tests are run immediately after boot */
739         win_skip("Could not get a handle to the eventlog\n");
740         HeapFree(GetProcessHeap(), 0, user);
741         return;
742     }
743
744     count = 0xdeadbeef;
745     GetNumberOfEventLogRecords(handle, &count);
746     if (count != 0)
747     {
748         /* Needed for W2K3 without a service pack */
749         win_skip("We most likely opened the Application eventlog\n");
750         CloseEventLog(handle);
751         Sleep(2000);
752
753         handle = OpenEventLogA(NULL, eventlogname);
754         count = 0xdeadbeef;
755         GetNumberOfEventLogRecords(handle, &count);
756         if (count != 0)
757         {
758             win_skip("We didn't open our new eventlog\n");
759             HeapFree(GetProcessHeap(), 0, user);
760             CloseEventLog(handle);
761             return;
762         }
763     }
764
765     SetLastError(0xdeadbeef);
766     ret = ReportEvent(handle, 0x20, 0, 0, NULL, 0, 0, NULL, NULL);
767     if (!ret && GetLastError() == ERROR_CRC)
768     {
769         win_skip("Win7 fails when using incorrect event types\n");
770         ret = ReportEvent(handle, 0, 0, 0, NULL, 0, 0, NULL, NULL);
771     }
772     else
773     {
774         void *buf;
775         DWORD read, needed;
776         EVENTLOGRECORD *record;
777
778         /* Needed to catch earlier Vista (with no ServicePack for example) */
779         buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD));
780         ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
781                       0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
782
783         buf = HeapReAlloc(GetProcessHeap(), 0, buf, needed);
784         ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
785                       0, buf, needed, &read, &needed);
786
787         record = (EVENTLOGRECORD *)buf;
788
789         /* Vista and W2K8 return EVENTLOG_SUCCESS, Windows versions before return
790          * the written eventtype (0x20 in this case).
791          */
792         if (record->EventType == EVENTLOG_SUCCESS)
793             on_vista = TRUE;
794
795         HeapFree(GetProcessHeap(), 0, buf);
796     }
797     ok(ret, "Expected success : %d\n", GetLastError());
798
799     /* This will clear the eventlog. The record numbering for new
800      * events however differs on Vista SP1+. Before Vista the first
801      * event would be numbered 1, on Vista SP1+ it's higher as we already
802      * had at least one event (more in case of multiple test runs without
803      * a reboot).
804      */
805     ClearEventLogA(handle, NULL);
806     CloseEventLog(handle);
807
808     /* Write a bunch of events while using different event sources */
809     for (i = 0; i < sizeof(read_write)/sizeof(read_write[0]); i++)
810     {
811         DWORD oldest;
812         BOOL run_sidtests = read_write[i].evt_sid & sidavailable;
813
814         /* We don't need to use RegisterEventSource to report events */
815         if (i % 2)
816             handle = OpenEventLogA(NULL, read_write[i].evt_src);
817         else
818             handle = RegisterEventSourceA(NULL, read_write[i].evt_src);
819         ok(handle != NULL, "Expected a handle\n");
820
821         SetLastError(0xdeadbeef);
822         ret = ReportEvent(handle, read_write[i].evt_type, read_write[i].evt_cat,
823                           read_write[i].evt_id, run_sidtests ? user : NULL,
824                           read_write[i].evt_numstrings, 0, read_write[i].evt_strings, NULL);
825
826         count = 0xdeadbeef;
827         ret = GetNumberOfEventLogRecords(handle, &count);
828         ok(ret, "Expected success\n");
829         ok(count == (i + 1), "Expected %d records, got %d\n", i + 1, count);
830
831         oldest = 0xdeadbeef;
832         ret = GetOldestEventLogRecord(handle, &oldest);
833         ok(ret, "Expected success\n");
834         ok(oldest == 1 ||
835            (oldest > 1 && oldest != 0xdeadbeef), /* Vista SP1+, W2K8 and Win7 */
836            "Expected oldest to be 1 or higher, got %d\n", oldest);
837         if (oldest > 1 && oldest != 0xdeadbeef)
838             on_vista = TRUE;
839
840         if (i % 2)
841             ret = CloseEventLog(handle);
842         else
843             ret = DeregisterEventSource(handle);
844         ok(ret, "Expected success : %d\n", GetLastError());
845     }
846
847     handle = OpenEventLogA(NULL, eventlogname);
848     count = 0xdeadbeef;
849     ret = GetNumberOfEventLogRecords(handle, &count);
850     ok(ret, "Expected success\n");
851     ok(count == i, "Expected %d records, got %d\n", i, count);
852     CloseEventLog(handle);
853
854     if (count == 0)
855     {
856         skip("No events were written to the eventlog\n");
857         return;
858     }
859
860     /* Report only once */
861     if (on_vista)
862         skip("There is no DWORD alignment enforced for UserSid on Vista, W2K8 or Win7\n");
863
864     /* Read all events from our created eventlog, one by one */
865     handle = OpenEventLogA(NULL, eventlogname);
866     i = 0;
867     for (;;)
868     {
869         void *buf;
870         DWORD read, needed;
871         EVENTLOGRECORD *record;
872         char *sourcename, *computername;
873         int k;
874         char *ptr;
875         BOOL run_sidtests = read_write[i].evt_sid & sidavailable;
876
877         buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD));
878         SetLastError(0xdeadbeef);
879         ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
880                             0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
881         if (!ret && GetLastError() == ERROR_HANDLE_EOF)
882         {
883             HeapFree(GetProcessHeap(), 0, buf);
884             break;
885         }
886         ok(!ret, "Expected failure\n");
887         ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
888            "Expected ERROR_INVALID_PARAMETER, got %d\n",GetLastError());
889
890         buf = HeapReAlloc(GetProcessHeap(), 0, buf, needed);
891         ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
892                             0, buf, needed, &read, &needed);
893         ok(ret, "Expected success: %d\n", GetLastError());
894
895         record = (EVENTLOGRECORD *)buf;
896
897         ok(record->Length == read,
898            "Expected %d, got %d\n", read, record->Length);
899         ok(record->Reserved == 0x654c664c,
900            "Expected 0x654c664c, got %d\n", record->Reserved);
901         ok(record->RecordNumber == i + 1 ||
902            (on_vista && (record->RecordNumber > i + 1)),
903            "Expected %d or higher, got %d\n", i + 1, record->RecordNumber);
904         ok(record->EventID == read_write[i].evt_id,
905            "Expected %d, got %d\n", read_write[i].evt_id, record->EventID);
906         ok(record->EventType == read_write[i].evt_type,
907            "Expected %d, got %d\n", read_write[i].evt_type, record->EventType);
908         ok(record->NumStrings == read_write[i].evt_numstrings,
909            "Expected %d, got %d\n", read_write[i].evt_numstrings, record->NumStrings);
910         ok(record->EventCategory == read_write[i].evt_cat,
911            "Expected %d, got %d\n", read_write[i].evt_cat, record->EventCategory);
912
913         sourcename = (char *)((BYTE *)buf + sizeof(EVENTLOGRECORD));
914         ok(!lstrcmpA(sourcename, read_write[i].evt_src), "Expected '%s', got '%s'\n",
915            read_write[i].evt_src, sourcename);
916
917         computername = (char *)((BYTE *)buf + sizeof(EVENTLOGRECORD) + lstrlenA(sourcename) + 1);
918         ok(!lstrcmpiA(computername, localcomputer), "Expected '%s', got '%s'\n",
919            localcomputer, computername);
920
921         /* Before Vista, UserSid was aligned on a DWORD boundary. Next to that if
922          * no padding was actually required a 0 DWORD was still used for padding. No
923          * application should be relying on the padding as we are working with offsets
924          * anyway.
925          */
926
927         if (!on_vista)
928         {
929             DWORD calculated_sidoffset = sizeof(EVENTLOGRECORD) + lstrlenA(sourcename) + 1 + lstrlenA(computername) + 1;
930
931             /* We are already DWORD aligned, there should still be some padding */
932             if ((((UINT_PTR)buf + calculated_sidoffset) % sizeof(DWORD)) == 0)
933                 ok(*(DWORD *)((BYTE *)buf + calculated_sidoffset) == 0, "Expected 0\n");
934
935             ok((((UINT_PTR)buf + record->UserSidOffset) % sizeof(DWORD)) == 0, "Expected DWORD alignment\n");
936         }
937
938         if (run_sidtests)
939         {
940             ok(record->UserSidLength == sidsize, "Expected %d, got %d\n", sidsize, record->UserSidLength);
941         }
942         else
943         {
944             ok(record->StringOffset == record->UserSidOffset, "Expected offsets to be the same\n");
945             ok(record->UserSidLength == 0, "Expected 0, got %d\n", record->UserSidLength);
946         }
947
948         ok(record->DataLength == 0, "Expected 0, got %d\n", record->DataLength);
949
950         ptr = (char *)((BYTE *)buf + record->StringOffset);
951         for (k = 0; k < record->NumStrings; k++)
952         {
953             ok(!lstrcmpA(ptr, two_strings[k]), "Expected '%s', got '%s'\n", two_strings[k], ptr);
954             ptr += lstrlenA(ptr) + 1;
955         }
956
957         ok(record->Length == *(DWORD *)((BYTE *)buf + record->Length - sizeof(DWORD)),
958            "Expected the closing DWORD to contain the length of the record\n");
959
960         HeapFree(GetProcessHeap(), 0, buf);
961         i++;
962     }
963     CloseEventLog(handle);
964
965     HeapFree(GetProcessHeap(), 0, user);
966
967     /* Test clearing a real eventlog */
968     handle = OpenEventLogA(NULL, eventlogname);
969
970     SetLastError(0xdeadbeef);
971     ret = ClearEventLogA(handle, NULL);
972     ok(ret, "Expected success\n");
973
974     count = 0xdeadbeef;
975     ret = GetNumberOfEventLogRecords(handle, &count);
976     ok(ret, "Expected success\n");
977     ok(count == 0, "Expected an empty eventlog, got %d records\n", count);
978
979     CloseEventLog(handle);
980 }
981
982 /* Before Vista:
983  *
984  * Creating an eventlog on Windows (via the registry) automatically leads
985  * to creation of a REG_MULTI_SZ named 'Sources'. This value lists all the
986  * potential event sources for this eventlog. 'Sources' is automatically
987  * updated when a new key (aka event source) is created.
988  *
989  * Although the updating of registry keys is almost instantaneously, we
990  * check it after some other tests to assure we are not querying the
991  * registry or file system to quickly.
992  *
993  * NT4 and higher:
994  *
995  * The eventlog file itself is also automatically created, even before we
996  * start writing events.
997  */
998 static char eventlogfile[MAX_PATH];
999 static void test_autocreation(void)
1000 {
1001     HKEY key, eventkey;
1002     DWORD type, size;
1003     LONG ret;
1004     int i;
1005     char *p;
1006     char sources[sizeof(eventsources)];
1007     char sysdir[MAX_PATH];
1008     void *redir = 0;
1009
1010     RegOpenKeyA(HKEY_LOCAL_MACHINE, eventlogsvc, &key);
1011     RegOpenKeyA(key, eventlogname, &eventkey);
1012
1013     size = sizeof(sources);
1014     sources[0] = 0;
1015     ret = RegQueryValueExA(eventkey, "Sources", NULL, &type, (LPBYTE)sources, &size);
1016     if (ret == ERROR_SUCCESS)
1017     {
1018         char sources_verify[sizeof(eventsources)];
1019
1020         ok(type == REG_MULTI_SZ, "Expected a REG_MULTI_SZ, got %d\n", type);
1021
1022         /* Build the expected string */
1023         memset(sources_verify, 0, sizeof(sources_verify));
1024         p = sources_verify;
1025         for (i = sizeof(eventsources)/sizeof(eventsources[0]); i > 0; i--)
1026         {
1027             lstrcpyA(p, eventsources[i - 1]);
1028             p += (lstrlenA(eventsources[i - 1]) + 1);
1029         }
1030         lstrcpyA(p, eventlogname);
1031
1032         ok(!memcmp(sources, sources_verify, size),
1033            "Expected a correct 'Sources' value (size : %d)\n", size);
1034     }
1035
1036     RegCloseKey(eventkey);
1037     RegCloseKey(key);
1038
1039     /* The directory that holds the eventlog files could be redirected */
1040     if (pWow64DisableWow64FsRedirection)
1041         pWow64DisableWow64FsRedirection(&redir);
1042
1043     /* On Windows we also automatically get an eventlog file */
1044     GetSystemDirectoryA(sysdir, sizeof(sysdir));
1045
1046     /* NT4 - W2K3 */
1047     lstrcpyA(eventlogfile, sysdir);
1048     lstrcatA(eventlogfile, "\\config\\");
1049     lstrcatA(eventlogfile, eventlogname);
1050     lstrcatA(eventlogfile, ".evt");
1051
1052     if (GetFileAttributesA(eventlogfile) == INVALID_FILE_ATTRIBUTES)
1053     {
1054         /* Vista+ */
1055         lstrcpyA(eventlogfile, sysdir);
1056         lstrcatA(eventlogfile, "\\winevt\\Logs\\");
1057         lstrcatA(eventlogfile, eventlogname);
1058         lstrcatA(eventlogfile, ".evtx");
1059     }
1060
1061     ok(GetFileAttributesA(eventlogfile) != INVALID_FILE_ATTRIBUTES,
1062        "Expected an eventlog file\n");
1063
1064     if (pWow64RevertWow64FsRedirection)
1065         pWow64RevertWow64FsRedirection(redir);
1066 }
1067
1068 static void cleanup_eventlog(void)
1069 {
1070     BOOL bret;
1071     LONG lret;
1072     HKEY key;
1073     int i;
1074     char winesvc[MAX_PATH];
1075
1076     /* Delete the registry tree */
1077     lstrcpyA(winesvc, eventlogsvc);
1078     lstrcatA(winesvc, "\\");
1079     lstrcatA(winesvc, eventlogname);
1080
1081     RegOpenKeyA(HKEY_LOCAL_MACHINE, winesvc, &key);
1082     for (i = 0; i < sizeof(eventsources)/sizeof(eventsources[0]); i++)
1083         RegDeleteKeyA(key, eventsources[i]);
1084     RegDeleteValueA(key, "Sources");
1085     RegCloseKey(key);
1086     lret = RegDeleteKeyA(HKEY_LOCAL_MACHINE, winesvc);
1087     todo_wine
1088     ok(lret == ERROR_SUCCESS, "Could not delete the registry tree : %d\n", lret);
1089
1090     /* A handle to the eventlog is locked by services.exe. We can only
1091      * delete the eventlog file after reboot.
1092      */
1093     bret = MoveFileExA(eventlogfile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
1094     todo_wine
1095     ok(bret, "Expected MoveFileEx to succeed: %d\n", GetLastError());
1096 }
1097
1098 START_TEST(eventlog)
1099 {
1100     SetLastError(0xdeadbeef);
1101     CloseEventLog(NULL);
1102     if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1103     {
1104         win_skip("Event log functions are not implemented\n");
1105         return;
1106     }
1107
1108     init_function_pointers();
1109
1110     /* Parameters only */
1111     test_open_close();
1112     test_info();
1113     test_count();
1114     test_oldest();
1115     test_backup();
1116     test_openbackup();
1117     test_read();
1118     test_clear();
1119
1120     /* Functional tests */
1121     if (create_new_eventlog())
1122     {
1123         test_readwrite();
1124         test_autocreation();
1125     }
1126     cleanup_eventlog();
1127 }