/*
 * Unit tests for Event Logging functions
 *
 * Copyright (c) 2009 Paul Vriens
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "winnt.h"
#include "winreg.h"
#include "sddl.h"

#include "wine/test.h"

static BOOL (WINAPI *pCreateWellKnownSid)(WELL_KNOWN_SID_TYPE,PSID,PSID,DWORD*);
static BOOL (WINAPI *pGetEventLogInformation)(HANDLE,DWORD,LPVOID,DWORD,LPDWORD);

static BOOL (WINAPI *pGetComputerNameExA)(COMPUTER_NAME_FORMAT,LPSTR,LPDWORD);
static BOOL (WINAPI *pWow64DisableWow64FsRedirection)(PVOID *);
static BOOL (WINAPI *pWow64RevertWow64FsRedirection)(PVOID);

static void init_function_pointers(void)
{
    HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
    HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");

    pCreateWellKnownSid = (void*)GetProcAddress(hadvapi32, "CreateWellKnownSid");
    pGetEventLogInformation = (void*)GetProcAddress(hadvapi32, "GetEventLogInformation");

    pGetComputerNameExA = (void*)GetProcAddress(hkernel32, "GetComputerNameExA");
    pWow64DisableWow64FsRedirection = (void*)GetProcAddress(hkernel32, "Wow64DisableWow64FsRedirection");
    pWow64RevertWow64FsRedirection = (void*)GetProcAddress(hkernel32, "Wow64RevertWow64FsRedirection");
}

static void create_backup(const char *filename)
{
    HANDLE handle;

    DeleteFileA(filename);
    handle = OpenEventLogA(NULL, "Application");
    BackupEventLogA(handle, filename);
    CloseEventLog(handle);

    todo_wine
    ok(GetFileAttributesA(filename) != INVALID_FILE_ATTRIBUTES, "Expected a backup file\n");
}

static void test_open_close(void)
{
    HANDLE handle;
    BOOL ret;

    SetLastError(0xdeadbeef);
    ret = CloseEventLog(NULL);
    ok(!ret, "Expected failure\n");
    ok(GetLastError() == ERROR_INVALID_HANDLE ||
       GetLastError() == ERROR_NOACCESS, /* W2K */
       "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());

    SetLastError(0xdeadbeef);
    handle = OpenEventLogA(NULL, NULL);
    ok(handle == NULL, "Didn't expect a handle\n");
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());

    SetLastError(0xdeadbeef);
    handle = OpenEventLogA("IDontExist", NULL);
    ok(handle == NULL, "Didn't expect a handle\n");
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());

    SetLastError(0xdeadbeef);
    handle = OpenEventLogA("IDontExist", "deadbeef");
    ok(handle == NULL, "Didn't expect a handle\n");
    ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE ||
       GetLastError() == RPC_S_INVALID_NET_ADDR, /* Some Vista and Win7 */
       "Expected RPC_S_SERVER_UNAVAILABLE, got %d\n", GetLastError());

    /* This one opens the Application log */
    handle = OpenEventLogA(NULL, "deadbeef");
    ok(handle != NULL, "Expected a handle\n");
    ret = CloseEventLog(handle);
    ok(ret, "Expected success\n");
    /* Close a second time */
    SetLastError(0xdeadbeef);
    ret = CloseEventLog(handle);
    todo_wine
    {
    ok(!ret, "Expected failure\n");
    ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
    }

    /* Empty servername should be read as local server */
    handle = OpenEventLogA("", "Application");
    ok(handle != NULL, "Expected a handle\n");
    CloseEventLog(handle);

    handle = OpenEventLogA(NULL, "Application");
    ok(handle != NULL, "Expected a handle\n");
    CloseEventLog(handle);
}

static void test_info(void)
{
    HANDLE handle;
    BOOL ret;
    DWORD needed;
    EVENTLOG_FULL_INFORMATION efi;

    if (!pGetEventLogInformation)
    {
        /* NT4 */
        win_skip("GetEventLogInformation is not available\n");
        return;
    }
    SetLastError(0xdeadbeef);
    ret = pGetEventLogInformation(NULL, 1, NULL, 0, NULL);
    ok(!ret, "Expected failure\n");
    ok(GetLastError() == ERROR_INVALID_LEVEL, "Expected ERROR_INVALID_LEVEL, got %d\n", GetLastError());

    SetLastError(0xdeadbeef);
    ret = pGetEventLogInformation(NULL, EVENTLOG_FULL_INFO, NULL, 0, NULL);
    ok(!ret, "Expected failure\n");
    ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());

    handle = OpenEventLogA(NULL, "Application");

    SetLastError(0xdeadbeef);
    ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, NULL, 0, NULL);
    ok(!ret, "Expected failure\n");
    ok(GetLastError() == RPC_X_NULL_REF_POINTER, "Expected RPC_X_NULL_REF_POINTER, got %d\n", GetLastError());

    SetLastError(0xdeadbeef);
    ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, NULL, 0, &needed);
    ok(!ret, "Expected failure\n");
    ok(GetLastError() == RPC_X_NULL_REF_POINTER, "Expected RPC_X_NULL_REF_POINTER, got %d\n", GetLastError());

    SetLastError(0xdeadbeef);
    ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, (LPVOID)&efi, 0, NULL);
    ok(!ret, "Expected failure\n");
    ok(GetLastError() == RPC_X_NULL_REF_POINTER, "Expected RPC_X_NULL_REF_POINTER, got %d\n", GetLastError());

    SetLastError(0xdeadbeef);
    needed = 0xdeadbeef;
    efi.dwFull = 0xdeadbeef;
    ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, (LPVOID)&efi, 0, &needed);
    ok(!ret, "Expected failure\n");
    ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
    ok(needed == sizeof(EVENTLOG_FULL_INFORMATION), "Expected sizeof(EVENTLOG_FULL_INFORMATION), got %d\n", needed);
    ok(efi.dwFull == 0xdeadbeef, "Expected no change to the dwFull member\n");

    /* Not that we care, but on success last error is set to ERROR_IO_PENDING */
    efi.dwFull = 0xdeadbeef;
    needed *= 2;
    ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, (LPVOID)&efi, needed, &needed);
    ok(ret, "Expected success\n");
    ok(needed == sizeof(EVENTLOG_FULL_INFORMATION), "Expected sizeof(EVENTLOG_FULL_INFORMATION), got %d\n", needed);
    ok(efi.dwFull == 0 || efi.dwFull == 1, "Expected 0 (not full) or 1 (full), got %d\n", efi.dwFull);

    CloseEventLog(handle);
}

static void test_count(void)
{
    HANDLE handle;
    BOOL ret;
    DWORD count;
    const char backup[] = "backup.evt";

    SetLastError(0xdeadbeef);
    ret = GetNumberOfEventLogRecords(NULL, NULL);
    ok(!ret, "Expected failure\n");
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());

    SetLastError(0xdeadbeef);
    count = 0xdeadbeef;
    ret = GetNumberOfEventLogRecords(NULL, &count);
    ok(!ret, "Expected failure\n");
    ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
    ok(count == 0xdeadbeef, "Expected count to stay unchanged\n");

    handle = OpenEventLogA(NULL, "Application");

    SetLastError(0xdeadbeef);
    ret = GetNumberOfEventLogRecords(handle, NULL);
    ok(!ret, "Expected failure\n");
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());

    count = 0xdeadbeef;
    ret = GetNumberOfEventLogRecords(handle, &count);
    ok(ret, "Expected success\n");
    ok(count != 0xdeadbeef, "Expected the number of records\n");

    CloseEventLog(handle);

    /* Make a backup eventlog to work with */
    create_backup(backup);

    handle = OpenBackupEventLogA(NULL, backup);
    todo_wine
    ok(handle != NULL, "Expected a handle\n");

    /* Does GetNumberOfEventLogRecords work with backup eventlogs? */
    count = 0xdeadbeef;
    ret = GetNumberOfEventLogRecords(handle, &count);
    todo_wine
    {
    ok(ret, "Expected success\n");
    ok(count != 0xdeadbeef, "Expected the number of records\n");
    }

    CloseEventLog(handle);
    DeleteFileA(backup);
}

static void test_oldest(void)
{
    HANDLE handle;
    BOOL ret;
    DWORD oldest;
    const char backup[] = "backup.evt";

    SetLastError(0xdeadbeef);
    ret = GetOldestEventLogRecord(NULL, NULL);
    ok(!ret, "Expected failure\n");
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());

    SetLastError(0xdeadbeef);
    oldest = 0xdeadbeef;
    ret = GetOldestEventLogRecord(NULL, &oldest);
    ok(!ret, "Expected failure\n");
    ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
    ok(oldest == 0xdeadbeef, "Expected oldest to stay unchanged\n");

    handle = OpenEventLogA(NULL, "Application");

    SetLastError(0xdeadbeef);
    ret = GetOldestEventLogRecord(handle, NULL);
    ok(!ret, "Expected failure\n");
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());

    oldest = 0xdeadbeef;
    ret = GetOldestEventLogRecord(handle, &oldest);
    ok(ret, "Expected success\n");
    ok(oldest != 0xdeadbeef, "Expected the number of the oldest record\n");

    CloseEventLog(handle);

    /* Make a backup eventlog to work with */
    create_backup(backup);

    handle = OpenBackupEventLogA(NULL, backup);
    todo_wine
    ok(handle != NULL, "Expected a handle\n");

    /* Does GetOldestEventLogRecord work with backup eventlogs? */
    oldest = 0xdeadbeef;
    ret = GetOldestEventLogRecord(handle, &oldest);
    todo_wine
    {
    ok(ret, "Expected success\n");
    ok(oldest != 0xdeadbeef, "Expected the number of the oldest record\n");
    }

    CloseEventLog(handle);
    DeleteFileA(backup);
}

static void test_backup(void)
{
    HANDLE handle;
    BOOL ret;
    const char backup[] = "backup.evt";
    const char backup2[] = "backup2.evt";

    SetLastError(0xdeadbeef);
    ret = BackupEventLogA(NULL, NULL);
    ok(!ret, "Expected failure\n");
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());

    SetLastError(0xdeadbeef);
    ret = BackupEventLogA(NULL, backup);
    ok(!ret, "Expected failure\n");
    ok(GetFileAttributesA(backup) == INVALID_FILE_ATTRIBUTES, "Expected no backup file\n");

    handle = OpenEventLogA(NULL, "Application");

    SetLastError(0xdeadbeef);
    ret = BackupEventLogA(handle, NULL);
    ok(!ret, "Expected failure\n");
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());

    ret = BackupEventLogA(handle, backup);
    ok(ret, "Expected success\n");
    todo_wine
    ok(GetFileAttributesA(backup) != INVALID_FILE_ATTRIBUTES, "Expected a backup file\n");

    /* Try to overwrite */
    SetLastError(0xdeadbeef);
    ret = BackupEventLogA(handle, backup);
    todo_wine
    {
    ok(!ret, "Expected failure\n");
    ok(GetLastError() == ERROR_ALREADY_EXISTS, "Expected ERROR_ALREADY_EXISTS, got %d\n", GetLastError());
    }

    CloseEventLog(handle);

    /* Can we make a backup of a backup? */
    handle = OpenBackupEventLogA(NULL, backup);
    todo_wine
    ok(handle != NULL, "Expected a handle\n");

    ret = BackupEventLogA(handle, backup2);
    todo_wine
    {
    ok(ret, "Expected success\n");
    ok(GetFileAttributesA(backup2) != INVALID_FILE_ATTRIBUTES, "Expected a backup file\n");
    }

    CloseEventLog(handle);
    DeleteFileA(backup);
    DeleteFileA(backup2);
}

static void test_read(void)
{
    HANDLE handle;
    BOOL ret;
    DWORD count, toread, read, needed;
    void *buf;

    SetLastError(0xdeadbeef);
    ret = ReadEventLogA(NULL, 0, 0, NULL, 0, NULL, NULL);
    ok(!ret, "Expected failure\n");
    todo_wine
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());

    read = 0xdeadbeef;
    SetLastError(0xdeadbeef);
    ret = ReadEventLogA(NULL, 0, 0, NULL, 0, &read, NULL);
    ok(!ret, "Expected failure\n");
    ok(read == 0xdeadbeef, "Expected 'read' parameter to remain unchanged\n");
    todo_wine
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());

    needed = 0xdeadbeef;
    SetLastError(0xdeadbeef);
    ret = ReadEventLogA(NULL, 0, 0, NULL, 0, NULL, &needed);
    ok(!ret, "Expected failure\n");
    ok(needed == 0xdeadbeef, "Expected 'needed' parameter to remain unchanged\n");
    todo_wine
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());

    /* 'read' and 'needed' are only filled when the needed buffer size is passed back or when the call succeeds */
    SetLastError(0xdeadbeef);
    ret = ReadEventLogA(NULL, 0, 0, NULL, 0, &read, &needed);
    ok(!ret, "Expected failure\n");
    todo_wine
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());

    SetLastError(0xdeadbeef);
    ret = ReadEventLogA(NULL, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, NULL, 0, NULL, NULL);
    ok(!ret, "Expected failure\n");
    todo_wine
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());

    SetLastError(0xdeadbeef);
    ret = ReadEventLogA(NULL, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, NULL, 0, &read, &needed);
    ok(!ret, "Expected failure\n");
    todo_wine
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());

    buf = NULL;
    SetLastError(0xdeadbeef);
    ret = ReadEventLogA(NULL, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
                        0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
    ok(!ret, "Expected failure\n");
    todo_wine
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());

    buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD));
    SetLastError(0xdeadbeef);
    ret = ReadEventLogA(NULL, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
                        0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
    ok(!ret, "Expected failure\n");
    todo_wine
    ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
    HeapFree(GetProcessHeap(), 0, buf);

    handle = OpenEventLogA(NULL, "Application");

    /* Show that we need the proper dwFlags with a (for the rest) proper call */
    buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD));

    SetLastError(0xdeadbeef);
    ret = ReadEventLogA(handle, 0, 0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
    ok(!ret, "Expected failure\n");
    todo_wine
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());

    SetLastError(0xdeadbeef);
    ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ, 0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
    ok(!ret, "Expected failure\n");
    todo_wine
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());

    SetLastError(0xdeadbeef);
    ret = ReadEventLogA(handle, EVENTLOG_SEEK_READ, 0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
    ok(!ret, "Expected failure\n");
    todo_wine
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());

    SetLastError(0xdeadbeef);
    ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ | EVENTLOG_BACKWARDS_READ,
                        0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
    ok(!ret, "Expected failure\n");
    todo_wine
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());

    SetLastError(0xdeadbeef);
    ret = ReadEventLogA(handle, EVENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ | EVENTLOG_BACKWARDS_READ,
                        0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
    ok(!ret, "Expected failure\n");
    todo_wine
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());

    SetLastError(0xdeadbeef);
    ret = ReadEventLogA(handle, EVENTLOG_SEEK_READ | EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
                        0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
    ok(!ret, "Expected failure\n");
    todo_wine
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());

    HeapFree(GetProcessHeap(), 0, buf);

    /* First check if there are any records (in practice only on Wine: FIXME) */
    count = 0;
    GetNumberOfEventLogRecords(handle, &count);
    if (!count)
    {
        skip("No records in the 'Application' log\n");
        CloseEventLog(handle);
        return;
    }

    /* Get the buffer size for the first record */
    buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD));
    read = needed = 0xdeadbeef;
    SetLastError(0xdeadbeef);
    ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
                        0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
    ok(!ret, "Expected failure\n");
    ok(read == 0, "Expected no bytes read\n");
    ok(needed > sizeof(EVENTLOGRECORD), "Expected the needed buffersize to be bigger than sizeof(EVENTLOGRECORD)\n");
    ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());

    /* Read the first record */
    toread = needed;
    buf = HeapReAlloc(GetProcessHeap(), 0, buf, toread);
    read = needed = 0xdeadbeef;
    SetLastError(0xdeadbeef);
    ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, buf, toread, &read, &needed);
    ok(ret, "Expected success\n");
    ok(read == toread ||
       broken(read < toread), /* NT4 wants a buffer size way bigger than just 1 record */
       "Expected the requested size to be read\n");
    ok(needed == 0, "Expected no extra bytes to be read\n");
    HeapFree(GetProcessHeap(), 0, buf);

    CloseEventLog(handle);
}

static void test_openbackup(void)
{
    HANDLE handle, handle2, file;
    DWORD written;
    const char backup[] = "backup.evt";
    const char text[] = "Just some text";

    SetLastError(0xdeadbeef);
    handle = OpenBackupEventLogA(NULL, NULL);
    ok(handle == NULL, "Didn't expect a handle\n");
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());

    SetLastError(0xdeadbeef);
    handle = OpenBackupEventLogA(NULL, "idontexist.evt");
    ok(handle == NULL, "Didn't expect a handle\n");
    ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());

    SetLastError(0xdeadbeef);
    handle = OpenBackupEventLogA("IDontExist", NULL);
    ok(handle == NULL, "Didn't expect a handle\n");
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());

    SetLastError(0xdeadbeef);
    handle = OpenBackupEventLogA("IDontExist", "idontexist.evt");
    ok(handle == NULL, "Didn't expect a handle\n");
    ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE ||
       GetLastError() == RPC_S_INVALID_NET_ADDR, /* Some Vista and Win7 */
       "Expected RPC_S_SERVER_UNAVAILABLE, got %d\n", GetLastError());

    /* Make a backup eventlog to work with */
    create_backup(backup);

    /* FIXME: Wine stops here */
    if (GetFileAttributesA(backup) == INVALID_FILE_ATTRIBUTES)
    {
        skip("We don't have a backup eventlog to work with\n");
        return;
    }

    SetLastError(0xdeadbeef);
    handle = OpenBackupEventLogA("IDontExist", backup);
    ok(handle == NULL, "Didn't expect a handle\n");
    ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE ||
       GetLastError() == RPC_S_INVALID_NET_ADDR, /* Some Vista and Win7 */
       "Expected RPC_S_SERVER_UNAVAILABLE, got %d\n", GetLastError());

    /* Empty servername should be read as local server */
    handle = OpenBackupEventLogA("", backup);
    ok(handle != NULL, "Expected a handle\n");
    CloseEventLog(handle);

    handle = OpenBackupEventLogA(NULL, backup);
    ok(handle != NULL, "Expected a handle\n");

    /* Can we open that same backup eventlog more than once? */
    handle2 = OpenBackupEventLogA(NULL, backup);
    ok(handle2 != NULL, "Expected a handle\n");
    ok(handle2 != handle, "Didn't expect the same handle\n");
    CloseEventLog(handle2);

    CloseEventLog(handle);
    DeleteFileA(backup);

    /* Is there any content checking done? */
    file = CreateFileA(backup, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL);
    CloseHandle(file);
    SetLastError(0xdeadbeef);
    handle = OpenBackupEventLogA(NULL, backup);
    ok(handle == NULL, "Didn't expect a handle\n");
    ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY ||
       GetLastError() == ERROR_EVENTLOG_FILE_CORRUPT, /* Vista and Win7 */
       "Expected ERROR_NOT_ENOUGH_MEMORY, got %d\n", GetLastError());
    CloseEventLog(handle);
    DeleteFileA(backup);

    file = CreateFileA(backup, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL);
    WriteFile(file, text, sizeof(text), &written, NULL);
    CloseHandle(file);
    SetLastError(0xdeadbeef);
    handle = OpenBackupEventLogA(NULL, backup);
    ok(handle == NULL, "Didn't expect a handle\n");
    ok(GetLastError() == ERROR_EVENTLOG_FILE_CORRUPT, "Expected ERROR_EVENTLOG_FILE_CORRUPT, got %d\n", GetLastError());
    CloseEventLog(handle);
    DeleteFileA(backup);
}

static void test_clear(void)
{
    HANDLE handle;
    BOOL ret;
    const char backup[] = "backup.evt";
    const char backup2[] = "backup2.evt";

    SetLastError(0xdeadbeef);
    ret = ClearEventLogA(NULL, NULL);
    ok(!ret, "Expected failure\n");
    ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());

    /* Make a backup eventlog to work with */
    create_backup(backup);

    SetLastError(0xdeadbeef);
    ret = ClearEventLogA(NULL, backup);
    ok(!ret, "Expected failure\n");
    ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());

    handle = OpenBackupEventLogA(NULL, backup);
    todo_wine
    ok(handle != NULL, "Expected a handle\n");

    /* A real eventlog would fail with ERROR_ALREADY_EXISTS */
    SetLastError(0xdeadbeef);
    ret = ClearEventLogA(handle, backup);
    ok(!ret, "Expected failure\n");
    /* The eventlog service runs under an account that doesn't have the necessary
     * permissions on the users home directory on a default Vista+ system.
     */
    ok(GetLastError() == ERROR_INVALID_HANDLE ||
       GetLastError() == ERROR_ACCESS_DENIED, /* Vista+ */
       "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());

    /* Show that ClearEventLog only works for real eventlogs. */
    SetLastError(0xdeadbeef);
    ret = ClearEventLogA(handle, backup2);
    ok(!ret, "Expected failure\n");
    ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
    ok(GetFileAttributesA(backup2) == INVALID_FILE_ATTRIBUTES, "Expected no backup file\n");

    SetLastError(0xdeadbeef);
    ret = ClearEventLogA(handle, NULL);
    ok(!ret, "Expected failure\n");
    ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());

    CloseEventLog(handle);
    todo_wine
    ok(DeleteFileA(backup), "Could not delete the backup file\n");
}

static const char eventlogsvc[] = "SYSTEM\\CurrentControlSet\\Services\\Eventlog";
static const char eventlogname[] = "Wine";
static const char eventsources[][11] = { "WineSrc", "WineSrc1", "WineSrc20", "WineSrc300" };

static BOOL create_new_eventlog(void)
{
    HKEY key, eventkey;
    BOOL bret = FALSE;
    LONG lret;
    int i;

    /* First create our eventlog */
    lret = RegOpenKeyA(HKEY_LOCAL_MACHINE, eventlogsvc, &key);
     /* FIXME: Wine stops here */
    if (lret != ERROR_SUCCESS)
    {
        skip("Could not open the EventLog service registry key\n");
        return FALSE;
    }
    lret = RegCreateKeyA(key, eventlogname, &eventkey);
    if (lret != ERROR_SUCCESS)
    {
        skip("Could not create the eventlog '%s' registry key\n", eventlogname);
        goto cleanup;
    }

    /* Create some event sources, the registry value 'Sources' is updated automatically */
    for (i = 0; i < sizeof(eventsources)/sizeof(eventsources[0]); i++)
    {
        HKEY srckey;

        lret = RegCreateKeyA(eventkey, eventsources[i], &srckey);
        if (lret != ERROR_SUCCESS)
        {
            skip("Could not create the eventsource '%s' registry key\n", eventsources[i]);
            goto cleanup;
        }
        RegFlushKey(srckey);
        RegCloseKey(srckey);
    }

    bret = TRUE;

    /* The flushing of the registry (here and above) gives us some assurance
     * that we are not to quickly writing events as 'Sources' could still be
     * not updated.
     */
    RegFlushKey(eventkey);
cleanup:
    RegCloseKey(eventkey);
    RegCloseKey(key);

    return bret;
}

static const char *one_string[] = { "First string" };
static const char *two_strings[] = { "First string", "Second string" };
static const struct
{
    const char  *evt_src;
    WORD         evt_type;
    WORD         evt_cat;
    DWORD        evt_id;
    BOOL         evt_sid;
    WORD         evt_numstrings;
    const char **evt_strings;
} read_write [] =
{
    { eventlogname,    EVENTLOG_INFORMATION_TYPE, 1, 1,  FALSE, 1, one_string },
    { eventsources[0], EVENTLOG_WARNING_TYPE,     1, 2,  FALSE, 0, NULL },
    { eventsources[1], EVENTLOG_AUDIT_FAILURE,    1, 3,  FALSE, 2, two_strings },
    { eventsources[2], EVENTLOG_ERROR_TYPE,       1, 4,  FALSE, 0, NULL },
    { eventsources[3], EVENTLOG_WARNING_TYPE,     1, 5,  FALSE, 1, one_string },
    { eventlogname,    EVENTLOG_SUCCESS,          2, 6,  TRUE,  2, two_strings },
    { eventsources[0], EVENTLOG_AUDIT_FAILURE,    2, 7,  TRUE,  0, NULL },
    { eventsources[1], EVENTLOG_AUDIT_SUCCESS,    2, 8,  TRUE,  2, two_strings },
    { eventsources[2], EVENTLOG_WARNING_TYPE,     2, 9,  TRUE,  0, NULL },
    { eventsources[3], EVENTLOG_ERROR_TYPE,       2, 10, TRUE,  1, one_string }
};

static void test_readwrite(void)
{
    HANDLE handle;
    PSID user;
    DWORD sidsize, count;
    BOOL ret, sidavailable;
    BOOL on_vista = FALSE; /* Used to indicate Vista, W2K8 or Win7 */
    int i;
    char *localcomputer = NULL;
    DWORD size;

    if (pCreateWellKnownSid)
    {
        sidsize = SECURITY_MAX_SID_SIZE;
        user = HeapAlloc(GetProcessHeap(), 0, sidsize);
        SetLastError(0xdeadbeef);
        pCreateWellKnownSid(WinInteractiveSid, NULL, user, &sidsize);
        sidavailable = TRUE;
    }
    else
    {
        win_skip("Skipping some SID related tests\n");
        sidavailable = FALSE;
        user = NULL;
    }

    /* Write an event with an incorrect event type. This will fail on Windows 7
     * but succeed on all others, hence it's not part of the struct.
     */
    handle = OpenEventLogA(NULL, eventlogname);
    if (!handle)
    {
        /* Intermittently seen on NT4 when tests are run immediately after boot */
        win_skip("Could not get a handle to the eventlog\n");
        goto cleanup;
    }

    count = 0xdeadbeef;
    GetNumberOfEventLogRecords(handle, &count);
    if (count != 0)
    {
        /* Needed for W2K3 without a service pack */
        win_skip("We most likely opened the Application eventlog\n");
        CloseEventLog(handle);
        Sleep(2000);

        handle = OpenEventLogA(NULL, eventlogname);
        count = 0xdeadbeef;
        GetNumberOfEventLogRecords(handle, &count);
        if (count != 0)
        {
            win_skip("We didn't open our new eventlog\n");
            CloseEventLog(handle);
            goto cleanup;
        }
    }

    SetLastError(0xdeadbeef);
    ret = ReportEvent(handle, 0x20, 0, 0, NULL, 0, 0, NULL, NULL);
    if (!ret && GetLastError() == ERROR_CRC)
    {
        win_skip("Win7 fails when using incorrect event types\n");
        ret = ReportEvent(handle, 0, 0, 0, NULL, 0, 0, NULL, NULL);
        ok(ret, "Expected success : %d\n", GetLastError());
    }
    else
    {
        void *buf;
        DWORD read, needed = 0;
        EVENTLOGRECORD *record;

        ok(ret, "Expected success : %d\n", GetLastError());

        /* Needed to catch earlier Vista (with no ServicePack for example) */
        buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD));
        if (!(ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
                                  0, buf, sizeof(EVENTLOGRECORD), &read, &needed)) &&
            GetLastError() == ERROR_INSUFFICIENT_BUFFER)
        {
            buf = HeapReAlloc(GetProcessHeap(), 0, buf, needed);
            ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
                                0, buf, needed, &read, &needed);
        }
        if (ret)
        {
            record = (EVENTLOGRECORD *)buf;

            /* Vista and W2K8 return EVENTLOG_SUCCESS, Windows versions before return
             * the written eventtype (0x20 in this case).
             */
            if (record->EventType == EVENTLOG_SUCCESS)
                on_vista = TRUE;
        }
        HeapFree(GetProcessHeap(), 0, buf);
    }

    /* This will clear the eventlog. The record numbering for new
     * events however differs on Vista SP1+. Before Vista the first
     * event would be numbered 1, on Vista SP1+ it's higher as we already
     * had at least one event (more in case of multiple test runs without
     * a reboot).
     */
    ClearEventLogA(handle, NULL);
    CloseEventLog(handle);

    /* Write a bunch of events while using different event sources */
    for (i = 0; i < sizeof(read_write)/sizeof(read_write[0]); i++)
    {
        DWORD oldest;
        BOOL run_sidtests = read_write[i].evt_sid & sidavailable;

        /* We don't need to use RegisterEventSource to report events */
        if (i % 2)
            handle = OpenEventLogA(NULL, read_write[i].evt_src);
        else
            handle = RegisterEventSourceA(NULL, read_write[i].evt_src);
        ok(handle != NULL, "Expected a handle\n");

        SetLastError(0xdeadbeef);
        ret = ReportEvent(handle, read_write[i].evt_type, read_write[i].evt_cat,
                          read_write[i].evt_id, run_sidtests ? user : NULL,
                          read_write[i].evt_numstrings, 0, read_write[i].evt_strings, NULL);

        count = 0xdeadbeef;
        ret = GetNumberOfEventLogRecords(handle, &count);
        ok(ret, "Expected success\n");
        ok(count == (i + 1), "Expected %d records, got %d\n", i + 1, count);

        oldest = 0xdeadbeef;
        ret = GetOldestEventLogRecord(handle, &oldest);
        ok(ret, "Expected success\n");
        ok(oldest == 1 ||
           (oldest > 1 && oldest != 0xdeadbeef), /* Vista SP1+, W2K8 and Win7 */
           "Expected oldest to be 1 or higher, got %d\n", oldest);
        if (oldest > 1 && oldest != 0xdeadbeef)
            on_vista = TRUE;

        if (i % 2)
            ret = CloseEventLog(handle);
        else
            ret = DeregisterEventSource(handle);
        ok(ret, "Expected success : %d\n", GetLastError());
    }

    handle = OpenEventLogA(NULL, eventlogname);
    count = 0xdeadbeef;
    ret = GetNumberOfEventLogRecords(handle, &count);
    ok(ret, "Expected success\n");
    ok(count == i, "Expected %d records, got %d\n", i, count);
    CloseEventLog(handle);

    if (count == 0)
    {
        skip("No events were written to the eventlog\n");
        goto cleanup;
    }

    /* Report only once */
    if (on_vista)
        skip("There is no DWORD alignment enforced for UserSid on Vista, W2K8 or Win7\n");

    if (on_vista && pGetComputerNameExA)
    {
        /* New Vista+ behavior */
        size = 0;
        SetLastError(0xdeadbeef);
        pGetComputerNameExA(ComputerNameDnsFullyQualified, NULL, &size);
        localcomputer = HeapAlloc(GetProcessHeap(), 0, size);
        pGetComputerNameExA(ComputerNameDnsFullyQualified, localcomputer, &size);
    }
    else
    {
        size = MAX_COMPUTERNAME_LENGTH + 1;
        localcomputer = HeapAlloc(GetProcessHeap(), 0, size);
        GetComputerNameA(localcomputer, &size);
    }

    /* Read all events from our created eventlog, one by one */
    handle = OpenEventLogA(NULL, eventlogname);
    i = 0;
    for (;;)
    {
        void *buf;
        DWORD read, needed;
        EVENTLOGRECORD *record;
        char *sourcename, *computername;
        int k;
        char *ptr;
        BOOL run_sidtests = read_write[i].evt_sid & sidavailable;

        buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD));
        SetLastError(0xdeadbeef);
        ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
                            0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
        if (!ret && GetLastError() == ERROR_HANDLE_EOF)
        {
            HeapFree(GetProcessHeap(), 0, buf);
            break;
        }
        ok(!ret, "Expected failure\n");
        ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
           "Expected ERROR_INVALID_PARAMETER, got %d\n",GetLastError());

        buf = HeapReAlloc(GetProcessHeap(), 0, buf, needed);
        ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
                            0, buf, needed, &read, &needed);
        ok(ret, "Expected success: %d\n", GetLastError());

        record = (EVENTLOGRECORD *)buf;

        ok(record->Length == read,
           "Expected %d, got %d\n", read, record->Length);
        ok(record->Reserved == 0x654c664c,
           "Expected 0x654c664c, got %d\n", record->Reserved);
        ok(record->RecordNumber == i + 1 ||
           (on_vista && (record->RecordNumber > i + 1)),
           "Expected %d or higher, got %d\n", i + 1, record->RecordNumber);
        ok(record->EventID == read_write[i].evt_id,
           "Expected %d, got %d\n", read_write[i].evt_id, record->EventID);
        ok(record->EventType == read_write[i].evt_type,
           "Expected %d, got %d\n", read_write[i].evt_type, record->EventType);
        ok(record->NumStrings == read_write[i].evt_numstrings,
           "Expected %d, got %d\n", read_write[i].evt_numstrings, record->NumStrings);
        ok(record->EventCategory == read_write[i].evt_cat,
           "Expected %d, got %d\n", read_write[i].evt_cat, record->EventCategory);

        sourcename = (char *)((BYTE *)buf + sizeof(EVENTLOGRECORD));
        ok(!lstrcmpA(sourcename, read_write[i].evt_src), "Expected '%s', got '%s'\n",
           read_write[i].evt_src, sourcename);

        computername = (char *)((BYTE *)buf + sizeof(EVENTLOGRECORD) + lstrlenA(sourcename) + 1);
        ok(!lstrcmpiA(computername, localcomputer), "Expected '%s', got '%s'\n",
           localcomputer, computername);

        /* Before Vista, UserSid was aligned on a DWORD boundary. Next to that if
         * no padding was actually required a 0 DWORD was still used for padding. No
         * application should be relying on the padding as we are working with offsets
         * anyway.
         */

        if (!on_vista)
        {
            DWORD calculated_sidoffset = sizeof(EVENTLOGRECORD) + lstrlenA(sourcename) + 1 + lstrlenA(computername) + 1;

            /* We are already DWORD aligned, there should still be some padding */
            if ((((UINT_PTR)buf + calculated_sidoffset) % sizeof(DWORD)) == 0)
                ok(*(DWORD *)((BYTE *)buf + calculated_sidoffset) == 0, "Expected 0\n");

            ok((((UINT_PTR)buf + record->UserSidOffset) % sizeof(DWORD)) == 0, "Expected DWORD alignment\n");
        }

        if (run_sidtests)
        {
            ok(record->UserSidLength == sidsize, "Expected %d, got %d\n", sidsize, record->UserSidLength);
        }
        else
        {
            ok(record->StringOffset == record->UserSidOffset, "Expected offsets to be the same\n");
            ok(record->UserSidLength == 0, "Expected 0, got %d\n", record->UserSidLength);
        }

        ok(record->DataLength == 0, "Expected 0, got %d\n", record->DataLength);

        ptr = (char *)((BYTE *)buf + record->StringOffset);
        for (k = 0; k < record->NumStrings; k++)
        {
            ok(!lstrcmpA(ptr, two_strings[k]), "Expected '%s', got '%s'\n", two_strings[k], ptr);
            ptr += lstrlenA(ptr) + 1;
        }

        ok(record->Length == *(DWORD *)((BYTE *)buf + record->Length - sizeof(DWORD)),
           "Expected the closing DWORD to contain the length of the record\n");

        HeapFree(GetProcessHeap(), 0, buf);
        i++;
    }
    CloseEventLog(handle);

    /* Test clearing a real eventlog */
    handle = OpenEventLogA(NULL, eventlogname);

    SetLastError(0xdeadbeef);
    ret = ClearEventLogA(handle, NULL);
    ok(ret, "Expected success\n");

    count = 0xdeadbeef;
    ret = GetNumberOfEventLogRecords(handle, &count);
    ok(ret, "Expected success\n");
    ok(count == 0, "Expected an empty eventlog, got %d records\n", count);

    CloseEventLog(handle);

cleanup:
    HeapFree(GetProcessHeap(), 0, localcomputer);
    HeapFree(GetProcessHeap(), 0, user);
}

/* Before Vista:
 *
 * Creating an eventlog on Windows (via the registry) automatically leads
 * to creation of a REG_MULTI_SZ named 'Sources'. This value lists all the
 * potential event sources for this eventlog. 'Sources' is automatically
 * updated when a new key (aka event source) is created.
 *
 * Although the updating of registry keys is almost instantaneously, we
 * check it after some other tests to assure we are not querying the
 * registry or file system to quickly.
 *
 * NT4 and higher:
 *
 * The eventlog file itself is also automatically created, even before we
 * start writing events.
 */
static char eventlogfile[MAX_PATH];
static void test_autocreation(void)
{
    HKEY key, eventkey;
    DWORD type, size;
    LONG ret;
    int i;
    char *p;
    char sources[sizeof(eventsources)];
    char sysdir[MAX_PATH];
    void *redir = 0;

    RegOpenKeyA(HKEY_LOCAL_MACHINE, eventlogsvc, &key);
    RegOpenKeyA(key, eventlogname, &eventkey);

    size = sizeof(sources);
    sources[0] = 0;
    ret = RegQueryValueExA(eventkey, "Sources", NULL, &type, (LPBYTE)sources, &size);
    if (ret == ERROR_SUCCESS)
    {
        char sources_verify[sizeof(eventsources)];

        ok(type == REG_MULTI_SZ, "Expected a REG_MULTI_SZ, got %d\n", type);

        /* Build the expected string */
        memset(sources_verify, 0, sizeof(sources_verify));
        p = sources_verify;
        for (i = sizeof(eventsources)/sizeof(eventsources[0]); i > 0; i--)
        {
            lstrcpyA(p, eventsources[i - 1]);
            p += (lstrlenA(eventsources[i - 1]) + 1);
        }
        lstrcpyA(p, eventlogname);

        ok(!memcmp(sources, sources_verify, size),
           "Expected a correct 'Sources' value (size : %d)\n", size);
    }

    RegCloseKey(eventkey);
    RegCloseKey(key);

    /* The directory that holds the eventlog files could be redirected */
    if (pWow64DisableWow64FsRedirection)
        pWow64DisableWow64FsRedirection(&redir);

    /* On Windows we also automatically get an eventlog file */
    GetSystemDirectoryA(sysdir, sizeof(sysdir));

    /* NT4 - W2K3 */
    lstrcpyA(eventlogfile, sysdir);
    lstrcatA(eventlogfile, "\\config\\");
    lstrcatA(eventlogfile, eventlogname);
    lstrcatA(eventlogfile, ".evt");

    if (GetFileAttributesA(eventlogfile) == INVALID_FILE_ATTRIBUTES)
    {
        /* Vista+ */
        lstrcpyA(eventlogfile, sysdir);
        lstrcatA(eventlogfile, "\\winevt\\Logs\\");
        lstrcatA(eventlogfile, eventlogname);
        lstrcatA(eventlogfile, ".evtx");
    }

    ok(GetFileAttributesA(eventlogfile) != INVALID_FILE_ATTRIBUTES,
       "Expected an eventlog file\n");

    if (pWow64RevertWow64FsRedirection)
        pWow64RevertWow64FsRedirection(redir);
}

static void cleanup_eventlog(void)
{
    BOOL bret;
    LONG lret;
    HKEY key;
    int i;
    char winesvc[MAX_PATH];

    /* Delete the registry tree */
    lstrcpyA(winesvc, eventlogsvc);
    lstrcatA(winesvc, "\\");
    lstrcatA(winesvc, eventlogname);

    RegOpenKeyA(HKEY_LOCAL_MACHINE, winesvc, &key);
    for (i = 0; i < sizeof(eventsources)/sizeof(eventsources[0]); i++)
        RegDeleteKeyA(key, eventsources[i]);
    RegDeleteValueA(key, "Sources");
    RegCloseKey(key);
    lret = RegDeleteKeyA(HKEY_LOCAL_MACHINE, winesvc);
    todo_wine
    ok(lret == ERROR_SUCCESS, "Could not delete the registry tree : %d\n", lret);

    /* A handle to the eventlog is locked by services.exe. We can only
     * delete the eventlog file after reboot.
     */
    bret = MoveFileExA(eventlogfile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
    todo_wine
    ok(bret, "Expected MoveFileEx to succeed: %d\n", GetLastError());
}

START_TEST(eventlog)
{
    SetLastError(0xdeadbeef);
    CloseEventLog(NULL);
    if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
    {
        win_skip("Event log functions are not implemented\n");
        return;
    }

    init_function_pointers();

    /* Parameters only */
    test_open_close();
    test_info();
    test_count();
    test_oldest();
    test_backup();
    test_openbackup();
    test_read();
    test_clear();

    /* Functional tests */
    if (create_new_eventlog())
    {
        test_readwrite();
        test_autocreation();
    }
    cleanup_eventlog();
}
