/* This function is called whenever a matching event is triggered */ DWORD WINAPI WinEventCallback(EVT_SUBSCRIBE_NOTIFY_ACTION action, PVOID context, EVT_HANDLE hEvent) { DWORD status = ERROR_SUCCESS; switch(action) { case EvtSubscribeActionError: if (ERROR_EVT_QUERY_RESULT_STALE == (DWORD)hEvent) { Log(LOG_WARNING, "The subscription callback was notified that event records are missing."); } else { Log(LOG_WARNING | LOG_SYS, "The subscription callback received the following Win32 error: %lu", (DWORD)hEvent); } break; case EvtSubscribeActionDeliver: status = ProcessEvent(hEvent); break; default: Log(LOG_WARNING, "SubscriptionCallback: Unknown action."); } if (status == ERR_FAIL) { Log(LOG_ERROR | LOG_SYS, "Error sending log message"); WinEventCancelSubscribes(); ServiceIsRunning = FALSE; } return status; // The service ignores the returned status. }
/* Main eventlog monitoring loop */ int MainLoop() { char * output = NULL; EventList IgnoredEvents[MAX_IGNORED_EVENTS]; HKEY hkey = NULL; int level; int log, rv; int stat_counter = 0; BOOL winEvents; FILE *fp = NULL; /* Check for new Crimson Log Service */ winEvents = CheckForWindowsEvents(); /* Grab Ignore List From File */ if (CheckSyslogIgnoreFile(IgnoredEvents, CONFIG_FILE) < 0) return 1; /* Determine whether Tag is set */ if (strlen(SyslogTag) > 0) SyslogIncludeTag = TRUE; /* Gather eventlog names */ if (RegistryGather(winEvents)) return 1; /* Open all eventlogs */ if (winEvents == FALSE) { if (EventlogsOpen()) return 1; } /* Service is now running */ Log(LOG_INFO, "Eventlog to Syslog Service Started: Version %s (%s-bit)", VERSION, #ifdef _WIN64 "64" #else "32" #endif ); Log(LOG_INFO, "Flags: LogLevel=%u, IncludeOnly=%s, EnableTcp=%s, IncludeTag=%s, StatusInterval=%u", SyslogLogLevel, SyslogIncludeOnly ? "True" : "False", SyslogEnableTcp ? "True" : "False", SyslogIncludeTag ? "True" : "False", SyslogStatusInterval ); if (winEvents) { if((rv = WinEventSubscribe(IgnoredEvents)) != ERROR_SUCCESS) { ServiceIsRunning = FALSE; } } /* Loop while service is running */ while (ServiceIsRunning) { /* Process records */ if (winEvents == FALSE) { for (log = 0; log < EventlogCount; log++) { /* Loop for all messages */ while ((output = EventlogNext(IgnoredEvents, log, &level))) { if (output != NULL) { if (SyslogSend(output, level)) { ServiceIsRunning = FALSE; break; } } } } } /* Send status message to inform server that client is active */ if (SyslogStatusInterval != 0) { if (++stat_counter == SyslogStatusInterval*12) { // Because the service loops ~12 times/min stat_counter = 0; /* Reset Counter */ Log(LOG_INFO, "Eventlog to Syslog Service Running"); } } /* Sleep five seconds */ Sleep(5000); } /* Service is stopped */ Log(LOG_INFO, "Eventlog to Syslog Service Stopped"); /* Close eventlogs */ if (winEvents) WinEventCancelSubscribes(); EventlogsClose(); SyslogClose(); /* Success */ return 0; }
/* 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; }