/*
 * 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 void init_function_pointers(void)
{
    HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");

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

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 or higher */
    int i;
    char localcomputer[MAX_COMPUTERNAME_LENGTH + 1];
    DWORD len = sizeof(localcomputer);

    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;
    }

    GetComputerNameA(localcomputer, &len);

    /* 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);

    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());

    /* This will clear the eventlog. The record numbering for new
     * events however differs on Vista+. Before Vista the first
     * event would be numbered 1, on Vista+ it's now 2 as we already
     * had one event.
     */
    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 == 2, /* Vista+ */
           "Expected oldest to be 1 or 2, got %d\n", oldest);
        if (oldest == 2)
            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");
        return;
    }

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

    /* 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 + 2)),
           "Expected %d or %d, got %d\n", i + 1, i + 2, 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_PTR *)((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_PTR *)((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);

    HeapFree(GetProcessHeap(), 0, user);

    /* 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);
}

/* 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];

    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\n");
    }

    RegCloseKey(eventkey);
    RegCloseKey(key);

    /* 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");
}

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();
}
