Example #1
0
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 */
    if (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);
    }
}
Example #2
0
/* Start the event logging for each el */
int startEL(char *app, os_el *el)
{
    DWORD NumberOfRecords = 0;

    /* Open the event log */
    el->h = OpenEventLog(NULL, app);
    if (!el->h) {
        merror(EVTLOG_OPEN, ARGV0, app);
        return (-1);
    }

    el->name = app;
    if (GetOldestEventLogRecord(el->h, &el->record) == 0) {
        /* Unable to read oldest event log record */
        merror(EVTLOG_GETLAST, ARGV0, app);
        CloseEventLog(el->h);
        el->h = NULL;
        return (-1);
    }

    if (GetNumberOfEventLogRecords(el->h, &NumberOfRecords) == 0) {
        merror(EVTLOG_GETLAST, ARGV0, app);
        CloseEventLog(el->h);
        el->h = NULL;
        return (-1);
    }

    if (NumberOfRecords <= 0) {
        return (0);
    }

    return ((int)NumberOfRecords);
}
Example #3
0
/** int startEL(char *app, os_el *el)
 * Starts the event logging for each el
 */
int startEL(char *app, os_el *el)
{
    /* Opening the event log */
    el->h = OpenEventLog(NULL, app);
    if(!el->h)
    {
        return(0);	
    }

    el->name = app;
    GetOldestEventLogRecord(el->h, &el->record);

    return(1);
}
/*
 * Returns the record number of the oldest record (not necessarily 1).
 *
 * TLVs:
 *
 * req: TLV_TYPE_EVENT_HANDLE        - The event log handle
 */
DWORD request_sys_eventlog_oldest(Remote * remote, Packet * packet)
{
	Packet * response = packet_create_response(packet);
	DWORD result = ERROR_SUCCESS;
	HANDLE hEvent = (HANDLE)packet_get_tlv_value_qword(packet, TLV_TYPE_EVENT_HANDLE);
	DWORD oldest;

	if(GetOldestEventLogRecord(hEvent, &oldest) == 0) {
		result = GetLastError();
	}
	else {
		packet_add_tlv_uint(response, TLV_TYPE_EVENT_RECORDNUMBER, oldest);
	}

	packet_transmit_response(result, remote, response);

	return ERROR_SUCCESS;
}
Example #5
0
/* open event logger and return number of records */
static int	zbx_open_eventlog(LPCTSTR wsource, HANDLE *eventlog_handle, zbx_uint64_t *FirstID,
		zbx_uint64_t *LastID)
{
	const char	*__function_name = "zbx_open_eventlog";
	wchar_t		reg_path[MAX_PATH];
	HKEY		hk = NULL;
	DWORD		dwNumRecords, dwOldestRecord;
	int		ret = FAIL;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	*eventlog_handle = NULL;

	/* Get path to eventlog */
	StringCchPrintf(reg_path, MAX_PATH, EVENTLOG_REG_PATH TEXT("%s"), wsource);

	if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, reg_path, 0, KEY_READ, &hk))
		goto out;

	RegCloseKey(hk);

	if (NULL == (*eventlog_handle = OpenEventLog(NULL, wsource)))	/* open log file */
		goto out;

	if (0 == GetNumberOfEventLogRecords(*eventlog_handle, &dwNumRecords) ||
			0 == GetOldestEventLogRecord(*eventlog_handle, &dwOldestRecord))
	{
		CloseEventLog(*eventlog_handle);
		*eventlog_handle = NULL;
		goto out;
	}

	*FirstID = dwOldestRecord;
	*LastID = dwOldestRecord + dwNumRecords - 1;

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s FirstID:" ZBX_FS_UI64 " LastID:" ZBX_FS_UI64 " numIDs:%lu",
			__function_name, zbx_result_string(ret), *FirstID, *LastID, dwNumRecords);

	ret = SUCCEED;
out:
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));

	return ret;
}
Example #6
0
/* open event logger and return number of records */
static int    zbx_open_eventlog(LPCTSTR wsource, HANDLE *eventlog_handle, long *pNumRecords, long *pLatestRecord)
{
	const char	*__function_name = "zbx_open_eventlog";
	TCHAR		reg_path[MAX_PATH];
	HKEY		hk = NULL;
	int		ret = FAIL;

	assert(eventlog_handle);
	assert(pNumRecords);
	assert(pLatestRecord);

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	*eventlog_handle = NULL;
	*pNumRecords = 0;
	*pLatestRecord = 0;

	/* Get path to eventlog */
	zbx_wsnprintf(reg_path, MAX_PATH, EVENTLOG_REG_PATH TEXT("%s"), wsource);

	if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, reg_path, 0, KEY_READ, &hk))
		goto out;

	RegCloseKey(hk);

	if (NULL == (*eventlog_handle = OpenEventLog(NULL, wsource)))	/* open log file */
		goto out;

	if (0 == GetNumberOfEventLogRecords(*eventlog_handle, (unsigned long*)pNumRecords))	/* get number of records */
		goto out;

	if (0 == GetOldestEventLogRecord(*eventlog_handle, (unsigned long*)pLatestRecord))
		goto out;

	zabbix_log(LOG_LEVEL_DEBUG, "%s() pNumRecords:%ld pLatestRecord:%ld",
			__function_name, *pNumRecords, *pLatestRecord);

	ret = SUCCEED;
out:
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret));

	return ret;
}
Example #7
0
/* Open event log */
static int EventlogOpen(int log)
{
	DWORD count;
	DWORD oldest;

	/* Reset all indicators */
	EventlogList[log].count = 0;
	EventlogList[log].pos = 0;
	EventlogList[log].recnum = 1;

	/* Open log */
	EventlogList[log].handle = OpenEventLog(NULL, EventlogList[log].name);
	if (EventlogList[log].handle == NULL) {
		Log(LOG_ERROR|LOG_SYS, "Cannot open event log: \"%s\"", EventlogList[log].name);
		return 1;
	}

	/* Get number of records to skip */
	if (GetNumberOfEventLogRecords(EventlogList[log].handle, &count) == 0) {
		Log(LOG_ERROR|LOG_SYS, "Cannot get record count for event log: \"%s\"", EventlogList[log].name);
		return 1;
	}

	/* Get oldest record number */
	if (GetOldestEventLogRecord(EventlogList[log].handle, &oldest) == 0 && count != 0) {
		Log(LOG_ERROR|LOG_SYS, "Cannot get oldest record number for event log: \"%s\"", EventlogList[log].name);
		return 1;
	}

	/* Store record of next event */
	EventlogList[log].recnum = oldest + count;
	if (EventlogList[log].recnum == 0)
		EventlogList[log].recnum = 1; /* ?? */

	/* Success */
	return 0;
}
Example #8
0
// Get the record number to the last record in the log file.
static DWORD GetLastRecordNumber(HANDLE hEventLog, DWORD* pdwRecordNumber)
{
	DWORD status = ERROR_SUCCESS;
	DWORD OldestRecordNumber = 0;
	DWORD NumberOfRecords = 0;

	if (!GetOldestEventLogRecord(hEventLog, &OldestRecordNumber))
	{
		wprintf(L"GetOldestEventLogRecord failed with %lu.\n", status = GetLastError());
		goto cleanup;
	}

	if (!GetNumberOfEventLogRecords(hEventLog, &NumberOfRecords))
	{
		wprintf(L"GetOldestEventLogRecord failed with %lu.\n", status = GetLastError());
		goto cleanup;
	}

	*pdwRecordNumber = OldestRecordNumber + NumberOfRecords - 1;

cleanup:

	return status;
}
Example #9
0
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 */
    DWORD 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 = ReportEventA(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 = ReportEventA(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 = ReportEventA(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);
        ok(ret, "Expected ReportEvent success : %d\n", GetLastError());

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

        oldest = 0xdeadbeef;
        ret = GetOldestEventLogRecord(handle, &oldest);
        ok(ret, "Expected GetOldestEventLogRecord success : %d\n", GetLastError());
        todo_wine
        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;

        SetLastError(0xdeadbeef);
        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");
    todo_wine
    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);
    ok(handle != NULL, "Failed to open Event Log, got %d\n", GetLastError());
    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);
        ok(!ret, "Expected failure\n");
        if (!ret && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
        {
            HeapFree(GetProcessHeap(), 0, buf);
            ok(GetLastError() == ERROR_HANDLE_EOF, "record %d, got %d\n", i, GetLastError());
            break;
        }

        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);
    ok(handle != NULL, "Failed to open Event Log, got %d\n", GetLastError());

    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);
}
Example #10
0
BOOL
QueryEventMessages(LPWSTR lpMachineName,
                   LPWSTR lpLogName)
{
    HWND hwndDlg = NULL;
    HANDLE hEventLog;
    EVENTLOGRECORD *pevlr;
    DWORD dwRead, dwNeeded, dwThisRecord, dwTotalRecords = 0, dwCurrentRecord = 0, dwRecordsToRead = 0, dwFlags, dwMaxLength;
    size_t cchRemaining;
    LPWSTR lpSourceName;
    LPWSTR lpComputerName;
    LPSTR lpData;
    BOOL bResult = TRUE; /* Read succeeded. */

    WCHAR szWindowTitle[MAX_PATH];
    WCHAR szStatusText[MAX_PATH];
    WCHAR szLocalDate[MAX_PATH];
    WCHAR szLocalTime[MAX_PATH];
    WCHAR szEventID[MAX_PATH];
    WCHAR szEventTypeText[MAX_LOADSTRING];
    WCHAR szCategoryID[MAX_PATH];
    WCHAR szUsername[MAX_PATH];
    WCHAR szEventText[EVENT_MESSAGE_FILE_BUFFER];
    WCHAR szCategory[MAX_PATH];
    WCHAR szData[MAX_PATH];
    PWCHAR lpTitleTemplateEnd;

    SYSTEMTIME time;
    LVITEMW lviEventItem;

    dwFlags = EVENTLOG_FORWARDS_READ | EVENTLOG_SEQUENTIAL_READ;

    /* Open the event log. */
    hEventLog = OpenEventLogW(lpMachineName,
                             lpLogName);
    if (hEventLog == NULL)
    {
        ShowLastWin32Error();
        return FALSE;
    }

    lpSourceLogName = lpLogName;
    lpComputerName = lpMachineName;

    /* Disable listview redraw */
    SendMessage(hwndListView, WM_SETREDRAW, FALSE, 0);

    /* Clear the list view */
    (void)ListView_DeleteAllItems (hwndListView);
    FreeRecords();

    GetOldestEventLogRecord(hEventLog, &dwThisRecord);

    /* Get the total number of event log records. */
    GetNumberOfEventLogRecords (hEventLog , &dwTotalRecords);
    g_TotalRecords = dwTotalRecords;

    if (dwTotalRecords > 0)
    {
        EnableMenuItem(hMainMenu, IDM_CLEAR_EVENTS, MF_BYCOMMAND | MF_ENABLED);
        EnableMenuItem(hMainMenu, IDM_SAVE_PROTOCOL, MF_BYCOMMAND | MF_ENABLED);
    }
    else
    {
        EnableMenuItem(hMainMenu, IDM_CLEAR_EVENTS, MF_BYCOMMAND | MF_GRAYED);
        EnableMenuItem(hMainMenu, IDM_SAVE_PROTOCOL, MF_BYCOMMAND | MF_GRAYED);
    }

    g_RecordPtrs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwTotalRecords * sizeof(PVOID));

    /* If we have at least 1000 records show the waiting dialog */
    if (dwTotalRecords > 1000)
    {
        CloseHandle(CreateThread(NULL,
                                 0,
                                 ShowStatusMessageThread,
                                 (LPVOID)&hwndDlg,
                                 0,
                                 NULL));
    }

    while (dwCurrentRecord < dwTotalRecords)
    {
        pevlr = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD));
        g_RecordPtrs[dwCurrentRecord] = pevlr;

        bResult = ReadEventLog(hEventLog,  // Event log handle
                               dwFlags,    // Sequential read
                               0,          // Ignored for sequential read
                               pevlr,      // Pointer to buffer
                               sizeof(EVENTLOGRECORD),   // Size of buffer
                               &dwRead,    // Number of bytes read
                               &dwNeeded); // Bytes in the next record
        if((!bResult) && (GetLastError () == ERROR_INSUFFICIENT_BUFFER))
        {
            HeapFree(GetProcessHeap(), 0, pevlr);
            pevlr = HeapAlloc(GetProcessHeap(), 0, dwNeeded);
            g_RecordPtrs[dwCurrentRecord] = pevlr;

            ReadEventLogW(hEventLog,  // event log handle
                         dwFlags,    // read flags
                         0,          // offset; default is 0
                         pevlr,      // pointer to buffer
                         dwNeeded,   // size of buffer
                         &dwRead,    // number of bytes read
                         &dwNeeded); // bytes in next record
        }

        while (dwRead > 0)
        {
            LoadStringW(hInst, IDS_NOT_AVAILABLE, szUsername, MAX_PATH);
            LoadStringW(hInst, IDS_NOT_AVAILABLE, szEventText, MAX_PATH);
            LoadStringW(hInst, IDS_NONE, szCategory, MAX_PATH);

            // Get the event source name.
            lpSourceName = (LPWSTR)((LPBYTE)pevlr + sizeof(EVENTLOGRECORD));

            // Get the computer name
            lpComputerName = (LPWSTR)((LPBYTE)pevlr + sizeof(EVENTLOGRECORD) + (wcslen(lpSourceName) + 1) * sizeof(WCHAR));

            // This ist the data section of the current event
            lpData = (LPSTR)((LPBYTE)pevlr + pevlr->DataOffset);

            // Compute the event type
            EventTimeToSystemTime(pevlr->TimeWritten, &time);

            // Get the username that generated the event
            GetEventUserName(pevlr, szUsername);

            GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &time, NULL, szLocalDate, MAX_PATH);
            GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &time, NULL, szLocalTime, MAX_PATH);

            GetEventType(pevlr->EventType, szEventTypeText);
            GetEventCategory(lpLogName, lpSourceName, pevlr, szCategory);

            StringCbPrintfW(szEventID, sizeof(szEventID), L"%u", (pevlr->EventID & 0xFFFF));
            StringCbPrintfW(szCategoryID, sizeof(szCategoryID), L"%u", pevlr->EventCategory);

            lviEventItem.mask = LVIF_IMAGE | LVIF_TEXT | LVIF_PARAM;
            lviEventItem.iItem = 0;
            lviEventItem.iSubItem = 0;
            lviEventItem.lParam = (LPARAM)pevlr;
            lviEventItem.pszText = szEventTypeText;

            switch (pevlr->EventType)
            {
                case EVENTLOG_ERROR_TYPE:
                    lviEventItem.iImage = 2;
                    break;

                case EVENTLOG_AUDIT_FAILURE:
                    lviEventItem.iImage = 2;
                    break;

                case EVENTLOG_WARNING_TYPE:
                    lviEventItem.iImage = 1;
                    break;

                case EVENTLOG_INFORMATION_TYPE:
                    lviEventItem.iImage = 0;
                    break;

                case EVENTLOG_AUDIT_SUCCESS:
                    lviEventItem.iImage = 0;
                    break;

                case EVENTLOG_SUCCESS:
                    lviEventItem.iImage = 0;
                    break;
            }

            lviEventItem.iItem = ListView_InsertItem(hwndListView, &lviEventItem);

            ListView_SetItemText(hwndListView, lviEventItem.iItem, 1, szLocalDate);
            ListView_SetItemText(hwndListView, lviEventItem.iItem, 2, szLocalTime);
            ListView_SetItemText(hwndListView, lviEventItem.iItem, 3, lpSourceName);
            ListView_SetItemText(hwndListView, lviEventItem.iItem, 4, szCategory);
            ListView_SetItemText(hwndListView, lviEventItem.iItem, 5, szEventID);
            ListView_SetItemText(hwndListView, lviEventItem.iItem, 6, szUsername); //User
            ListView_SetItemText(hwndListView, lviEventItem.iItem, 7, lpComputerName); //Computer
            MultiByteToWideChar(CP_ACP,
                                0,
                                lpData,
                                pevlr->DataLength,
                                szData,
                                MAX_PATH);
            ListView_SetItemText(hwndListView, lviEventItem.iItem, 8, szData); //Event Text

            dwRead -= pevlr->Length;
            pevlr = (EVENTLOGRECORD *)((LPBYTE) pevlr + pevlr->Length);
        }

        dwRecordsToRead--;
        dwCurrentRecord++;
    }

    // All events loaded
    if(hwndDlg)
        EndDialog(hwndDlg, 0);

    StringCchPrintfExW(szWindowTitle,
                       sizeof(szWindowTitle) / sizeof(WCHAR),
                       &lpTitleTemplateEnd,
                       &cchRemaining,
                       0,
                       szTitleTemplate, szTitle, lpLogName); /* i = number of characters written */
    /* lpComputerName can be NULL here if no records was read */
    dwMaxLength = (DWORD)cchRemaining;
    if (!lpComputerName)
        GetComputerNameW(lpTitleTemplateEnd, &dwMaxLength);
    else
        StringCchCopyW(lpTitleTemplateEnd, dwMaxLength, lpComputerName);

    StringCbPrintfW(szStatusText, sizeof(szStatusText), szStatusBarTemplate, lpLogName, dwTotalRecords);

    // Update the status bar
    SendMessageW(hwndStatus, SB_SETTEXT, (WPARAM)0, (LPARAM)szStatusText);

    // Set the window title
    SetWindowTextW(hwndMainWindow, szWindowTitle);

    // Resume list view redraw
    SendMessageW(hwndListView, WM_SETREDRAW, TRUE, 0);

    // Close the event log.
    CloseEventLog(hEventLog);

    return TRUE;
}
Example #11
0
DWORD WINAPI
eventLogMonitorThreadProc(LPVOID elm_info_param)
{
    EVENTLOGRECORD *pevlr; 
    BYTE bBuffer[BUFFER_SIZE] = { 0 }; 
    DWORD dwRead, dwNeeded, res;
    DWORD reported_next_record, num_records;
    BOOL skip_first = FALSE;
    HANDLE log = NULL, event = NULL;
    WCHAR msgbuf[BUFFER_SIZE];

    eventlogmon_info *elm_info = (eventlogmon_info *) elm_info_param;
  
    control = 0;

    log = OpenEventLog(NULL, L_COMPANY_NAME);
    if (log == NULL) {
        (*elm_info->cb_err)(ELM_ERR_FATAL, 
                            L"Could not open the " L_COMPANY_NAME L" event log."); 
        goto exit_elm_thread_error;
    }
    
    event = CreateEvent(NULL, FALSE, FALSE, NULL);
    NotifyChangeEventLog(log, event);   
    
    pevlr = (EVENTLOGRECORD *) &bBuffer; 

    if (!GetNumberOfEventLogRecords(log, &num_records) ||
        !GetOldestEventLogRecord(log, &reported_next_record)) {
        _snwprintf(msgbuf, BUFFER_SIZE_ELEMENTS(msgbuf),
                   L"error %d getting eventlog info", GetLastError());
        (*elm_info->cb_err)(ELM_ERR_FATAL, msgbuf);
        goto exit_elm_thread_error;
    }

    /* FIXME: we don't handle the situation when the eventlog was cleared,
     *  but our pointer is less than the number of new records. for this
     *  we'll probably have to store a timestamp, and compare against the
     *  event record at next_record. */
    if (((int)elm_info->next_record) < 0) {
        elm_info->next_record = reported_next_record;
    } 
    else if (elm_info->next_record > (reported_next_record + num_records + 1)) {
        /* looks like the eventlog was cleared since we last checked
         *  it. issue a warning and reset */
        elm_info->next_record = reported_next_record;
        (*elm_info->cb_err)(ELM_ERR_CLEARED, L"Eventlog was cleared!\n");
    }
    else {
        /* we need to ensure we SEEK to a valid record; but since
         * it's already been reported, don't report it again. */
        elm_info->next_record--;
        skip_first = TRUE;
    }

    /* first seek to the last record 
     * EVENTLOG_FORWARDS_READ indicates we will get messages in
     *  chronological order.
     * FIXME: test to make sure that this works properly on
     *  overwrite-wrapped logs */
    if (!ReadEventLog(log,                
                      EVENTLOG_FORWARDS_READ | EVENTLOG_SEEK_READ,
                      elm_info->next_record,
                      pevlr,
                      BUFFER_SIZE,
                      &dwRead,
                      &dwNeeded)) {
        dwRead = 0;
        dwNeeded = 0;
    }

    for(;;) {        
        do {
            /* case 5813: if pevlr->Length is 0, we'll have an infinite
             * loop. this could possibly happen if drive is full?
             * just abort if we detect it. */
            while (dwRead > 0 && pevlr->Length > 0) {
                
                if (format_messages && !skip_first) {

                    res = get_formatted_message(pevlr, msgbuf, BUFFER_SIZE);
                    if (res != ERROR_SUCCESS) {
                        _snwprintf(msgbuf, BUFFER_SIZE_ELEMENTS(msgbuf),
                                   L"FormatMessage error %d\n", res);
                        (*elm_info->cb_err)(ELM_ERR_WARN, msgbuf);
                    }
                    else {
                        /* invoke the callback */
                        (*elm_info->cb_format)(pevlr->RecordNumber, 
                                               pevlr->EventType, 
                                               msgbuf, pevlr->TimeGenerated);
                    }
                } else if(!skip_first) {
                    /* xref case 3065: insurance */
                    if (pevlr->RecordNumber != 0 ||
                        pevlr->TimeGenerated != 0) {
                        /* raw callback */
                        (*elm_info->cb_raw)(pevlr);
                    }
                } else {
                    skip_first = FALSE;
                }

                dwRead -= pevlr->Length; 
                pevlr = (EVENTLOGRECORD *) ((LPBYTE) pevlr + pevlr->Length); 
            }
            
            pevlr = (EVENTLOGRECORD *) &bBuffer; 
        } while (ReadEventLog(log,                
                              EVENTLOG_FORWARDS_READ |  
                              EVENTLOG_SEQUENTIAL_READ, 
                              0,            
                              pevlr,        
                              BUFFER_SIZE,  
                              &dwRead,      
                              &dwNeeded));
        
        if((res = GetLastError()) != ERROR_HANDLE_EOF) {
            //FIXME: assert GetLastError() is appropriate
            _snwprintf(msgbuf, BUFFER_SIZE_ELEMENTS(msgbuf),
                       L"Unexpected error %d reading event log\n", res);
            (*elm_info->cb_err)(ELM_ERR_WARN, msgbuf);
        }

        if (do_once)
            break;

        /* the event is auto-reset.
           timeout because NotifyChangeEventLog is not reliable. */
        WaitForSingleObject(event, MINIPULSE);

        if(control)
            break;
    }
    
exit_elm_thread_error:

    if (log != NULL)
        CloseEventLog(log); 

    if (event != NULL)
        CloseHandle(event);

    free(elm_info);

    /* FIXME: need ExitThread()? */
    return 0;
}