void win_start_event_channel(char *evt_log, char future, char *query) { wchar_t *wchannel = NULL; wchar_t *wquery = NULL; os_channel *channel = NULL; DWORD flags = EvtSubscribeToFutureEvents; EVT_HANDLE bookmark = NULL; EVT_HANDLE result = NULL; int status = 0; if ((channel = calloc(1, sizeof(os_channel))) == NULL) { log2file( "%s: ERROR: Could not calloc() memory for channel to start reading (%s) which returned [(%d)-(%s)]", ARGV0, evt_log, errno, strerror(errno)); goto cleanup; } channel->evt_log = evt_log; /* Create copy of event log string */ if ((channel->bookmark_name = strdup(channel->evt_log)) == NULL) { log2file( "%s: ERROR: Could not strdup() event log name to start reading (%s) which returned [(%d)-(%s)]", ARGV0, channel->evt_log, errno, strerror(errno)); goto cleanup; } /* Replace '/' with '_' */ if (strchr(channel->bookmark_name, '/')) { *(strrchr(channel->bookmark_name, '/')) = '_'; } /* Convert evt_log to Windows string */ if ((wchannel = convert_unix_string(channel->evt_log)) == NULL) { log2file( "%s: ERROR: Could not convert_unix_string() evt_log for (%s) which returned [(%d)-(%s)]", ARGV0, channel->evt_log, errno, strerror(errno)); goto cleanup; } /* Convert query to Windows string */ if (query) { if ((wquery = convert_unix_string(query)) == NULL) { log2file( "%s: ERROR: Could not convert_unix_string() query for (%s) which returned [(%d)-(%s)]", ARGV0, channel->evt_log, errno, strerror(errno)); goto cleanup; } } channel->bookmark_enabled = !future; if (channel->bookmark_enabled) { /* Create bookmark file name */ snprintf(channel->bookmark_filename, sizeof(channel->bookmark_filename), "%s/%s", BOOKMARKS_DIR, channel->bookmark_name); /* Try to read existing bookmark */ if ((bookmark = read_bookmark(channel)) != NULL) { flags = EvtSubscribeStartAfterBookmark; } } result = EvtSubscribe(NULL, NULL, wchannel, wquery, bookmark, channel, (EVT_SUBSCRIBE_CALLBACK)event_channel_callback, flags); if (result == NULL && flags == EvtSubscribeStartAfterBookmark) { result = EvtSubscribe(NULL, NULL, wchannel, wquery, NULL, channel, (EVT_SUBSCRIBE_CALLBACK)event_channel_callback, EvtSubscribeToFutureEvents); } if (result == NULL) { log2file( "%s: ERROR: Could not EvtSubscribe() for (%s) which returned (%lu)", ARGV0, channel->evt_log, GetLastError()); goto cleanup; } /* Success */ status = 1; cleanup: free(wchannel); free(wquery); if (status == 0) { free(channel->bookmark_name); free(channel); if (result != NULL) { EvtClose(result); } } if (bookmark != NULL) { EvtClose(bookmark); } return; }
/* Subscribe to new events */ DWORD WinEventSubscribe(XPathList * xpathQueries, int queryCount) { LPWSTR error_msg = NULL; WCHAR * pQueryL; DWORD used; DWORD status = ERROR_SUCCESS; pQueryL = (WCHAR*)malloc(QUERY_LIST_SZ); CreateQueryString(pQueryL, xpathQueries, queryCount); WinEventSub = EvtSubscribe(NULL, NULL, NULL, pQueryL, NULL, NULL, (EVT_SUBSCRIBE_CALLBACK)WinEventCallback, EvtSubscribeToFutureEvents); error_msg = (LPWSTR)malloc(SYSLOG_DEF_SZ*sizeof(WCHAR)); if (WinEventSub == NULL) { status = GetLastError(); if (ERROR_EVT_CHANNEL_NOT_FOUND == status) Log(LOG_WARNING, "Channel %s was not found.\n", "Unknown"); else if (ERROR_EVT_INVALID_QUERY == status) { Log(LOG_ERROR, "The query \"%S\" is not valid.\n", pQueryL); if (EvtGetExtendedStatus(SYSLOG_DEF_SZ, error_msg, &used) == ERROR_SUCCESS) Log(LOG_ERROR, "%S", error_msg); } else Log(LOG_ERROR | LOG_SYS, "EvtSubscribe failed with %lu.\n", status); WinEventCancelSubscribes(); status = ERR_FAIL; } if (pQueryL != NULL) free(pQueryL); return status; }