// Read a single record from the event log. static DWORD ReadRecord(HANDLE hEventLog, PBYTE & pBuffer, DWORD dwRecordNumber, DWORD dwFlags) { DWORD status = ERROR_SUCCESS; DWORD dwBytesToRead = sizeof(EVENTLOGRECORD); DWORD dwBytesRead = 0; DWORD dwMinimumBytesToRead = 0; PBYTE pTemp = NULL; // The initial size of the buffer is not big enough to read a record, but ReadEventLog // requires a valid pointer. The ReadEventLog function will fail and return the required // buffer size; reallocate the buffer to the required size. pBuffer= (PBYTE)malloc(sizeof(EVENTLOGRECORD)); // Get the required buffer size, reallocate the buffer and then read the event record. if (!ReadEventLog(hEventLog, dwFlags, dwRecordNumber, pBuffer, dwBytesToRead, &dwBytesRead, &dwMinimumBytesToRead)) { status = GetLastError(); if (ERROR_INSUFFICIENT_BUFFER == status) { status = ERROR_SUCCESS; pTemp = (PBYTE)realloc(pBuffer, dwMinimumBytesToRead); if (NULL == pTemp) { wprintf(L"Failed to reallocate memory for the record buffer (%d bytes).\n", dwMinimumBytesToRead); goto cleanup; } pBuffer = pTemp; dwBytesToRead = dwMinimumBytesToRead; if (!ReadEventLog(hEventLog, dwFlags, dwRecordNumber, pBuffer, dwBytesToRead, &dwBytesRead, &dwMinimumBytesToRead)) { wprintf(L"Second ReadEventLog failed with %lu.\n", status = GetLastError()); goto cleanup; } } else { if (ERROR_HANDLE_EOF != status) { wprintf(L"ReadEventLog failed with %lu.\n", status); goto cleanup; } } } cleanup: return status; }
//------------------------------------------------- void EventScanAlgorithm::getEvent(const std::string& logName, EVENT_TYPE type) { HANDLE hEventLog; EVENTLOGRECORD* eventInfo; DWORD noteSize, nextNoteSize; BYTE buffer[BUFFER_SIZE]; static int eventLogCounter = 0; hEventLog = OpenEventLog(NULL, std::wstring(logName.begin(), logName.end()).c_str()); if(hEventLog == NULL) std::cout << "Could not open event log!"; eventInfo = (EVENTLOGRECORD*)&buffer; //GetOldestEventLogRecord(hEventLog, &eventLogCounter); while(ReadEventLog(hEventLog, EVENTLOG_FORWARDS_READ | EVENTLOG_SEQUENTIAL_READ, 0, eventInfo, BUFFER_SIZE, ¬eSize, &nextNoteSize)) { while(noteSize > 0) { // Show event that contains a specified type. if(eventInfo->EventType & type) { std::cout << eventLogCounter++; showEvent(eventInfo); } noteSize -= eventInfo->Length; eventInfo = (EVENTLOGRECORD*)((LPBYTE)eventInfo + eventInfo->Length); // Next record. } eventInfo = (EVENTLOGRECORD*)&buffer; } CloseHandle(hEventLog); }
bool CWfpNET::EventLog_get(void) { HANDLE h; EVENTLOGRECORD *pevlr; BYTE bBuffer[8192]; DWORD dwRead, dwNeeded, dwThisRecord = 0; CString tmp, event; char *cp; char *pSourceName; char *pComputerName; if((h = OpenEventLog(node.szComputerM, _T("Security"))) == NULL) { ErrorHandler("OpenEventLog", GetLastError()); return false; } pevlr = (EVENTLOGRECORD *)&bBuffer; // Opening the event log positions the file pointer for this // handle at the beginning of the log. Read the records // sequentially until there are no more. while(ReadEventLog(h, // event log handle EVENTLOG_FORWARDS_READ | // reads forward EVENTLOG_SEQUENTIAL_READ, // sequential read 0, // ignored for sequential reads pevlr, // pointer to buffer 8192, // size of buffer &dwRead, // number of bytes read &dwNeeded)) // bytes in next record { while(dwRead > 0) { // Print the event identifier, type, and source name. // The source name is just past the end of the // formal structure. tmp.Format(_T("\t%02d Event ID: 0x%08X "), dwThisRecord++, pevlr->EventID); event.operator +=(tmp); char buf[26]; ctime_s(buf, 26, (const time_t *)&pevlr->TimeGenerated); tmp.Format("Time Generated: %s", buf); event.operator +=(tmp); ctime_s(buf, 26, (const time_t *)&pevlr->TimeWritten); tmp.Format("Time Written: %s", buf); event.operator +=(tmp); switch(pevlr->EventType) { case EVENTLOG_ERROR_TYPE: event.operator +=("Error Event\n"); break; case EVENTLOG_WARNING_TYPE: event.operator +=("Warning Event\n"); break; case EVENTLOG_INFORMATION_TYPE: event.operator +=("Information Event\n"); break; case EVENTLOG_AUDIT_SUCCESS: event.operator +=("Success Audit Event\n"); break; case EVENTLOG_AUDIT_FAILURE: event.operator +=("Failure Audit Event\n"); break; default: event.operator +=("Unknown\n"); break; } cp = (char *)pevlr; cp += sizeof(EVENTLOGRECORD); pSourceName = cp; cp += strlen(cp)+1; pComputerName = cp; cp += strlen(cp)+1; tmp.Format("SourceName: %s\n", pSourceName); event.operator +=(tmp); tmp.Format("ComputerName: %s\n", pComputerName); event.operator +=(tmp); EventLog.Add(event); dwRead -= pevlr->Length; pevlr = (EVENTLOGRECORD *)((LPBYTE) pevlr + pevlr->Length); } pevlr = (EVENTLOGRECORD *) &bBuffer; } return(1); }
/** void readel(os_el *el) * Reads the event log. */ void readel(os_el *el, int printit) { DWORD _evtid = 65535; DWORD nstr; DWORD user_size; DWORD domain_size; DWORD read, needed; int size_left; int str_size; int id; char mbuffer[BUFFER_SIZE +1]; LPSTR sstr = NULL; char *tmp_str = NULL; char *category; char *source; char *computer_name; char *descriptive_msg; char el_user[OS_FLSIZE +1]; char el_domain[OS_FLSIZE +1]; char el_string[OS_MAXSTR +1]; char final_msg[OS_MAXSTR +1]; LPSTR el_sstring[OS_FLSIZE +1]; /* Er must point to the mbuffer */ el->er = (EVENTLOGRECORD *) &mbuffer; /* Zeroing the values */ el_string[OS_MAXSTR] = '\0'; el_user[OS_FLSIZE] = '\0'; el_domain[OS_FLSIZE] = '\0'; final_msg[OS_MAXSTR] = '\0'; el_sstring[0] = NULL; el_sstring[OS_FLSIZE] = NULL; /* Event log is not open */ if(!el->h) { return; } /* Reading the event log */ while(ReadEventLog(el->h, EVENTLOG_FORWARDS_READ | EVENTLOG_SEQUENTIAL_READ, 0, el->er, BUFFER_SIZE -1, &read, &needed)) { if(!printit) { /* Setting er to the beginning of the buffer */ el->er = (EVENTLOGRECORD *)&mbuffer; continue; } while(read > 0) { /* We need to initialize every variable before the loop */ category = el_getCategory(el->er->EventType); source = (LPSTR) ((LPBYTE) el->er + sizeof(EVENTLOGRECORD)); computer_name = source + strlen(source) + 1; descriptive_msg = NULL; /* Getting event id. */ id = (int)el->er->EventID & _evtid; /* Initialing domain/user size */ user_size = 255; domain_size = 255; el_domain[0] = '\0'; el_user[0] = '\0'; /* We must have some description */ if(el->er->NumStrings) { size_left = OS_MAXSTR - OS_SIZE_1024; sstr = (LPSTR)((LPBYTE)el->er + el->er->StringOffset); el_string[0] = '\0'; for (nstr = 0;nstr < el->er->NumStrings;nstr++) { str_size = strlen(sstr); if(size_left > 1) { strncat(el_string, sstr, size_left); } tmp_str = strchr(el_string, '\0'); if(tmp_str) { *tmp_str = ' '; tmp_str++; *tmp_str = '\0'; } else { merror("%s: Invalid application string (size+)", ARGV0); } size_left-=str_size + 2; if(nstr <= 92) { el_sstring[nstr] = (LPSTR)sstr; el_sstring[nstr +1] = NULL; } sstr = strchr( (LPSTR)sstr, '\0'); if(sstr) sstr++; else break; } /* Get a more descriptive message (if available) */ if(isVista && strcmp(el->name, "Security") == 0) { descriptive_msg = el_vista_getMessage(id, el_sstring); } else { descriptive_msg = el_getMessage(el->er, el->name, source, el_sstring); } if(descriptive_msg != NULL) { /* Remove any \n or \r */ /* Replace tabs from the argument field to spaces. * So whenever we have option:\tvalue\t, it will * become option: value\t */ tmp_str = descriptive_msg; while(*tmp_str != '\0') { if(*tmp_str == '\n') *tmp_str = ' '; else if(*tmp_str == '\r') *tmp_str = ' '; else if((*tmp_str == ':') && (tmp_str[1] == '\t')) { tmp_str[1] = ' '; tmp_str++; } tmp_str++; } } } else { strncpy(el_string, "(no message)", 128); } /* Getting username */ if(el->er->UserSidLength) { SID_NAME_USE account_type; if(!LookupAccountSid(NULL, (SID *)((LPSTR)el->er + el->er->UserSidOffset), el_user, &user_size, el_domain, &domain_size, &account_type)) { strncpy(el_user, "(no user)", 255); strncpy(el_domain, "no domain", 255); } } else if(isVista && strcmp(el->name, "Security") == 0) { int uid_array_id = -1; switch(id) { case 4624: uid_array_id = 5; break; case 4634: uid_array_id = 1; break; case 4647: uid_array_id = 1; break; case 4769: uid_array_id = 0; break; } if((uid_array_id >= 0) && el_sstring[uid_array_id] && el_sstring[uid_array_id +1]) { strncpy(el_user, el_sstring[uid_array_id], OS_FLSIZE); strncpy(el_domain, el_sstring[uid_array_id +1], OS_FLSIZE); } else { strncpy(el_user, "(no user)", 255); strncpy(el_domain, "no domain", 255); } } else { strncpy(el_user, "(no user)", 255); strncpy(el_domain, "no domain", 255); } if(printit) { DWORD _evtid = 65535; int id = (int)el->er->EventID & _evtid; final_msg[OS_MAXSTR - OS_LOG_HEADER] = '\0'; final_msg[OS_MAXSTR - OS_LOG_HEADER -1] = '\0'; snprintf(final_msg, OS_MAXSTR - OS_LOG_HEADER -1, "WinEvtLog: %s: %s(%d): %s: %s: %s: %s: %s", el->name, category, id, source, el_user, el_domain, computer_name, descriptive_msg != NULL?descriptive_msg:el_string); if(SendMSG(logr_queue, final_msg, "WinEvtLog", LOCALFILE_MQ) < 0) { merror(QUEUE_SEND, ARGV0); } } if(descriptive_msg != NULL) { LocalFree(descriptive_msg); } /* Changing the point to the er */ read -= el->er->Length; el->er = (EVENTLOGRECORD *)((LPBYTE) el->er + el->er->Length); } /* Setting er to the beginning of the buffer */ el->er = (EVENTLOGRECORD *)&mbuffer; } id = GetLastError(); if(id == ERROR_HANDLE_EOF) { return; } /* Event log was cleared. */ else if(id == ERROR_EVENTLOG_FILE_CHANGED) { char msg_alert[512 +1]; msg_alert[512] = '\0'; merror("%s: WARN: Event log cleared: '%s'", ARGV0, el->name); /* Send message about cleared */ snprintf(msg_alert, 512, "ossec: Event log cleared: '%s'", el->name); SendMSG(logr_queue, msg_alert, "WinEvtLog", LOCALFILE_MQ); /* Closing the event log and reopenning. */ CloseEventLog(el->h); el->h = NULL; /* Reopening. */ if(startEL(el->name, el) < 0) { merror("%s: ERROR: Unable to reopen event log '%s'", ARGV0, el->name); } } else { debug1("%s: WARN: Error reading event log: %d", ARGV0, id); } }
/* get Nth error from event log. 1 is the first. */ static int zbx_get_eventlog_message(const wchar_t *wsource, HANDLE eventlog_handle, DWORD which, char **out_source, char **out_message, unsigned short *out_severity, unsigned long *out_timestamp, unsigned long *out_eventid) { const char *__function_name = "zbx_get_eventlog_message"; int buffer_size = 512; EVENTLOGRECORD *pELR = NULL; DWORD dwRead, dwNeeded, dwErr; wchar_t *pEventMessageFile = NULL, *pParamMessageFile = NULL, *pFile = NULL, *pNextFile = NULL, *pCh, *aInsertStrings[MAX_INSERT_STRS]; HINSTANCE hLib = NULL, hParamLib = NULL; long i, err = 0; int ret = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In %s() lastlogsize:%lu", __function_name, which); *out_source = NULL; *out_message = NULL; *out_severity = 0; *out_timestamp = 0; *out_eventid = 0; memset(aInsertStrings, 0, sizeof(aInsertStrings)); pELR = (EVENTLOGRECORD *)zbx_malloc((void *)pELR, buffer_size); while (0 == ReadEventLog(eventlog_handle, EVENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ, which, pELR, buffer_size, &dwRead, &dwNeeded)) { if (ERROR_INSUFFICIENT_BUFFER != (dwErr = GetLastError())) { zabbix_log(LOG_LEVEL_DEBUG, "%s(): %s", __function_name, strerror_from_system(dwErr)); goto out; } buffer_size = dwNeeded; pELR = (EVENTLOGRECORD *)zbx_realloc((void *)pELR, buffer_size); } *out_severity = pELR->EventType; /* return event type */ *out_timestamp = pELR->TimeGenerated; /* return timestamp */ *out_eventid = pELR->EventID & 0xffff; *out_source = zbx_unicode_to_utf8((wchar_t *)(pELR + 1)); /* copy source name */ /* get message file names */ zbx_get_message_files(wsource, (wchar_t *)(pELR + 1), &pEventMessageFile, &pParamMessageFile); /* prepare insert string array */ if (0 < pELR->NumStrings) { pCh = (wchar_t *)((unsigned char *)pELR + pELR->StringOffset); for (i = 0; i < pELR->NumStrings && i < MAX_INSERT_STRS; i++) { aInsertStrings[i] = pCh; pCh += wcslen(pCh) + 1; } } err = FAIL; for (pFile = pEventMessageFile; NULL != pFile && err != SUCCEED; pFile = pNextFile) { if (NULL != (pNextFile = wcschr(pFile, TEXT(';')))) { *pNextFile = '\0'; pNextFile++; } if (NULL != (hLib = zbx_load_message_file(pFile))) { if (NULL != (*out_message = zbx_format_message(hLib, pELR->EventID, aInsertStrings))) { err = SUCCEED; if (NULL != (hParamLib = zbx_load_message_file(pParamMessageFile))) { zbx_translate_message_params(out_message, hParamLib); FreeLibrary(hParamLib); } } FreeLibrary(hLib); } } zbx_free(pEventMessageFile); zbx_free(pParamMessageFile); if (SUCCEED != err) { *out_message = zbx_strdcatf(*out_message, "The description for Event ID:%lu in Source:'%s'" " cannot be found. The local computer may not have the necessary registry" " information or message DLL files to display messages from a remote computer.", *out_eventid, NULL == *out_source ? "" : *out_source); if (0 < pELR->NumStrings) { char *buf; *out_message = zbx_strdcat(*out_message, " The following information is part of the event: "); for (i = 0, pCh = (wchar_t *)((unsigned char *)pELR + pELR->StringOffset); i < pELR->NumStrings; i++, pCh += wcslen(pCh) + 1) { if (0 < i) *out_message = zbx_strdcat(*out_message, "; "); buf = zbx_unicode_to_utf8(pCh); *out_message = zbx_strdcat(*out_message, buf); zbx_free(buf); } } } ret = SUCCEED; out: zbx_free(pELR); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
static void read_event_log(void) { DWORD status = ERROR_SUCCESS; DWORD bytes_to_read = 0; DWORD bytes_read = 0; DWORD minimum_bytes_to_read = 0; PBYTE temp = NULL; if (_record_buffer == NULL) { bytes_to_read = MAX_RECORD_BUFFER_SIZE; _record_buffer = (PBYTE)malloc(bytes_to_read); if (_record_buffer == NULL) { report_error("Could not allocate record buffer"); return; } } while (status == ERROR_SUCCESS) { if (!ReadEventLog(_event_log, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, _record_buffer, bytes_to_read, &bytes_read, &minimum_bytes_to_read)) { status = GetLastError(); if (status == ERROR_INSUFFICIENT_BUFFER) { status = ERROR_SUCCESS; temp = (PBYTE)realloc(_record_buffer, minimum_bytes_to_read); if (temp == NULL) { report_error("Could not reallocate record buffer to %u bytes", minimum_bytes_to_read); return; } _record_buffer = temp; bytes_to_read = minimum_bytes_to_read; } else if (status != ERROR_HANDLE_EOF) { report_error("Could not read event log: %s (%d)", get_error_name(status), status); return; } } else { PBYTE record = _record_buffer; PBYTE end_of_records = _record_buffer + bytes_read; char timestamp[MAX_TIMESTAMP_LENGTH]; const char *level; const char *source; const char *message; while (record < end_of_records) { if (strcmp((const char *)(record + sizeof(EVENTLOGRECORD)), "Brick Daemon") == 0) { format_timestamp(((PEVENTLOGRECORD)record)->TimeGenerated, -1, timestamp, sizeof(timestamp), "-", " ", ":"); switch (((PEVENTLOGRECORD)record)->EventType) { case EVENTLOG_ERROR_TYPE: level = "Error"; break; case EVENTLOG_WARNING_TYPE: level = "Warn"; break; case EVENTLOG_INFORMATION_TYPE: level = "Info"; break; case EVENTLOG_AUDIT_SUCCESS: level = "Audit Success"; break; case EVENTLOG_AUDIT_FAILURE: level = "Audit Failure"; break; default: level = "Unknown"; break; } switch (((PEVENTLOGRECORD)record)->EventID) { case BRICKD_GENERIC_WARNING: case BRICKD_GENERIC_ERROR: source = "Generic"; break; case BRICKD_LIBUSB_WARNING: case BRICKD_LIBUSB_ERROR: source = "Libusb"; break; default: source = "Unknown"; break; } if (((PEVENTLOGRECORD)record)->NumStrings > 0) { message = (const char *)(record + ((PEVENTLOGRECORD)record)->StringOffset); } else { message = "Unknown"; } append_event_item(timestamp, level, source, message); } record += ((PEVENTLOGRECORD)record)->Length; } } } }
/** void readel(os_el *el) * Reads the event log. */ void readel(os_el *el, int printit) { DWORD nstr; DWORD user_size; DWORD domain_size; DWORD read, needed; int size_left; int str_size; char mbuffer[BUFFER_SIZE]; LPSTR sstr = NULL; char *tmp_str = NULL; char *category; char *source; char *computer_name; char *descriptive_msg; char el_user[257]; char el_domain[257]; char el_string[1025]; char final_msg[1024]; LPSTR el_sstring[57]; /* Er must point to the mbuffer */ el->er = (EVENTLOGRECORD *) &mbuffer; /* Zeroing the last values */ el_string[1024] = '\0'; el_user[256] = '\0'; el_domain[256] = '\0'; final_msg[1023] = '\0'; el_sstring[56] = NULL; /* Reading the event log */ while(ReadEventLog(el->h, EVENTLOG_FORWARDS_READ | EVENTLOG_SEQUENTIAL_READ, 0, el->er, BUFFER_SIZE -1, &read, &needed)) { while(read > 0) { /* We need to initialize every variable before the loop */ category = el_getCategory(el->er->EventType); source = (LPSTR) ((LPBYTE) el->er + sizeof(EVENTLOGRECORD)); computer_name = source + strlen(source) + 1; descriptive_msg = NULL; /* Initialing domain/user size */ user_size = 255; domain_size = 255; el_domain[0] = '\0'; el_user[0] = '\0'; /* We must have some description */ if(el->er->NumStrings) { size_left = 1020; sstr = (LPSTR)((LPBYTE)el->er + el->er->StringOffset); el_string[0] = '\0'; for (nstr = 0;nstr < el->er->NumStrings;nstr++) { str_size = strlen(sstr); strncat(el_string, sstr, size_left); tmp_str= strchr(el_string, '\0'); if(tmp_str) { *tmp_str = ' '; tmp_str++; *tmp_str = '\0'; } size_left-=str_size + 1; if(nstr <= 54) el_sstring[nstr] = (LPSTR)sstr; sstr = strchr( (LPSTR)sstr, '\0'); sstr++; } /* Get a more descriptive message (if available) */ descriptive_msg = el_getMessage(el->er, el->name, source, el_sstring); if(descriptive_msg != NULL) { /* Remove any \n or \r */ tmp_str = descriptive_msg; while((tmp_str = strchr(tmp_str, '\n'))) { *tmp_str = ' '; tmp_str++; } tmp_str = descriptive_msg; while((tmp_str = strchr(tmp_str, '\r'))) { *tmp_str = ' '; tmp_str++; } } } else { strncpy(el_string, "(no message)", 1020); } /* Getting username */ if (el->er->UserSidLength) { SID_NAME_USE account_type; if(!LookupAccountSid(NULL, (SID *)((LPSTR)el->er + el->er->UserSidOffset), el_user, &user_size, el_domain, &domain_size, &account_type)) { strncpy(el_user, "(no user)", 255); strncpy(el_domain, "no domain", 255); } } else { strncpy(el_user, "(no user)", 255); strncpy(el_domain, "no domain", 255); } if(printit) { DWORD _evtid = 65535; int id = (int)el->er->EventID & _evtid; snprintf(final_msg, 1022, "%d WinEvtLog: %s: %s(%d): %s: %s(%s): %s", (int)el->er->TimeGenerated, el->name, category, id, source, el_user, el_domain, descriptive_msg != NULL?descriptive_msg:el_string); fprintf(fp, "%s\n", final_msg); } if(descriptive_msg != NULL) LocalFree(descriptive_msg); /* Changing the point to the er */ read -= el->er->Length; el->er = (EVENTLOGRECORD *)((LPBYTE) el->er + el->er->Length); } /* Setting er to the beginning of the buffer */ el->er = (EVENTLOGRECORD *)&mbuffer; } }
/* get Nth error from event log. 1 is the first. */ static int zbx_get_eventlog_message(LPCTSTR wsource, HANDLE eventlog_handle, long which, char **out_source, char **out_message, unsigned short *out_severity, unsigned long *out_timestamp, unsigned long *out_eventid) { const char *__function_name = "zbx_get_eventlog_message"; int buffer_size = 512; EVENTLOGRECORD *pELR = NULL; DWORD dwRead, dwNeeded, dwErr; TCHAR stat_buf[MAX_PATH], MsgDll[MAX_PATH]; HKEY hk = NULL; LPTSTR pFile = NULL, pNextFile = NULL; DWORD szData, Type; HINSTANCE hLib = NULL; /* handle to the messagetable DLL */ LPTSTR pCh, aInsertStrs[MAX_INSERT_STRS]; /* array of pointers to insert */ LPTSTR msgBuf = NULL; /* hold text of the error message */ char *buf = NULL; long i, err = 0; int ret = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In %s() which:%ld", __function_name, which); *out_source = NULL; *out_message = NULL; *out_severity = 0; *out_timestamp = 0; *out_eventid = 0; memset(aInsertStrs, 0, sizeof(aInsertStrs)); pELR = (EVENTLOGRECORD *)zbx_malloc((void *)pELR, buffer_size); retry: if (0 == ReadEventLog(eventlog_handle, EVENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ, which, pELR, buffer_size, &dwRead, &dwNeeded)) { dwErr = GetLastError(); if (dwErr == ERROR_INSUFFICIENT_BUFFER) { buffer_size = dwNeeded; pELR = (EVENTLOGRECORD *)zbx_realloc((void *)pELR, buffer_size); goto retry; } else { zabbix_log(LOG_LEVEL_DEBUG, "%s(): %s", __function_name, strerror_from_system(dwErr)); goto out; } } *out_severity = pELR->EventType; /* return event type */ *out_timestamp = pELR->TimeGenerated; /* return timestamp */ *out_eventid = pELR->EventID & 0xffff; *out_source = zbx_unicode_to_utf8((LPTSTR)(pELR + 1)); /* copy source name */ err = FAIL; /* prepare the array of insert strings for FormatMessage - the insert strings are in the log entry. */ for (i = 0, pCh = (LPTSTR)((LPBYTE)pELR + pELR->StringOffset); i < pELR->NumStrings && i < MAX_INSERT_STRS; i++, pCh += zbx_strlen(pCh) + 1) /* point to next string */ { aInsertStrs[i] = pCh; } /* Get path to message dll */ zbx_wsnprintf(stat_buf, MAX_PATH, EVENTLOG_REG_PATH TEXT("%s\\%s"), wsource, (LPTSTR)(pELR + 1)); if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, stat_buf, 0, KEY_READ, &hk)) { if (ERROR_SUCCESS == RegQueryValueEx(hk, TEXT("EventMessageFile"), NULL, &Type, NULL, &szData)) { buf = zbx_malloc(buf, szData); if (ERROR_SUCCESS == RegQueryValueEx(hk, TEXT("EventMessageFile"), NULL, &Type, (LPBYTE)buf, &szData)) pFile = (LPTSTR)buf; } RegCloseKey(hk); } err = FAIL; while (NULL != pFile && FAIL == err) { if (NULL != (pNextFile = zbx_strchr(pFile, ';'))) { *pNextFile = '\0'; pNextFile++; } if (ExpandEnvironmentStrings(pFile, MsgDll, MAX_PATH)) { if (NULL != (hLib = LoadLibraryEx(MsgDll, NULL, LOAD_LIBRARY_AS_DATAFILE))) { /* Format the message from the message DLL with the insert strings */ if (0 != FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK, /* do not generate new line breaks */ hLib, /* the messagetable DLL handle */ pELR->EventID, /* message ID */ MAKELANGID(LANG_NEUTRAL, SUBLANG_ENGLISH_US), /* language ID */ (LPTSTR)&msgBuf, /* address of pointer to buffer for message */ 0, (va_list *)aInsertStrs)) /* array of insert strings for the message */ { *out_message = zbx_unicode_to_utf8(msgBuf); zbx_rtrim(*out_message, "\r\n "); /* Free the buffer that FormatMessage allocated for us. */ LocalFree((HLOCAL)msgBuf); err = SUCCEED; } FreeLibrary(hLib); } } pFile = pNextFile; } zbx_free(buf); if (SUCCEED != err) { *out_message = zbx_strdcatf(*out_message, "The description for Event ID (%lu) in Source (%s) cannot be found." " The local computer may not have the necessary registry information or message DLL files to" " display messages from a remote computer.", *out_eventid, NULL == *out_source ? "" : *out_source); if (pELR->NumStrings) *out_message = zbx_strdcatf(*out_message, " The following information is part of the event: "); for (i = 0; i < pELR->NumStrings && i < MAX_INSERT_STRS; i++) { if (i > 0) *out_message = zbx_strdcatf(*out_message, "; "); if (aInsertStrs[i]) { buf = zbx_unicode_to_utf8(aInsertStrs[i]); *out_message = zbx_strdcatf(*out_message, "%s", buf); zbx_free(buf); } } } ret = SUCCEED; out: zbx_free(pELR); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/*--------------------------[ ernoReadEventLog ]-------------------------- * Wrapper to ReadEventLogm which increases buffer size if needed * * After this function call, record points to allocated structure. This function will handle any free operation needed, as record struct is static * * Returns: * error 0 - use GetLastError * success bytes read *----------------------------------------------------------------------------*/ int ernoReadEventLog(HANDLE hLog,DWORD flags,DWORD offset, DWORD *BytesRead,DWORD *BytesNeeded) { int Status, lastError; unsigned int multiple; //Allocate standard buffer if needed if (eventBuffer==NULL) { eventBuffer=(char*)malloc(EVENTLOG_BUFFER_LEN); //Standard size if (eventBuffer==NULL) { logger(Error,"Failed to allocate standard buffer of %d bytes of memory.",EVENTLOG_BUFFER_LEN); return 0; //Error } eventBufferSize=EVENTLOG_BUFFER_LEN; } record=(EVENTLOGRECORD *)eventBuffer; //Allocate bigger buffer if needed // //Executes until big enough memory has been allocated and used, or function fails. while (true){ Status=ReadEventLog(hLog, flags,offset, record, eventBufferSize, BytesRead, BytesNeeded); if (Status!=0) return Status; //We're done //Potential problem here lastError=GetLastError(); switch(lastError) { case ERROR_INSUFFICIENT_BUFFER: free(eventBuffer); record=NULL; eventBuffer=NULL; eventBufferSize=0; multiple=2; while(EVENTLOG_BUFFER_LEN*multiple<(*BytesNeeded)) { multiple=multiple*2; if(EVENTLOG_BUFFER_LEN*multiple>3000000) { logger(Error,"SyslogAgent rejected suggested needed memory allocation of %d bytes from system to process message. Possible permanent error",*BytesNeeded); return 0; } } eventBuffer=(char*)malloc(EVENTLOG_BUFFER_LEN*multiple); if (eventBuffer==NULL) { logger(Error,"Failed to allocate %d bytes of memory.",EVENTLOG_BUFFER_LEN*multiple); return 0; //Error } record=(EVENTLOGRECORD *)eventBuffer; eventBufferSize=EVENTLOG_BUFFER_LEN*multiple; continue; case ERROR_INVALID_PARAMETER: //read past the end - no more to read case ERROR_HANDLE_EOF: //read empty event log - no problems *BytesRead=0; return 0; default: DEBUGSERVICE(Message,"ReadEventLog failed with error code %d.",lastError); return 0; //Do not want to spam recipient. A better error reporting is needed first... } } return Status; }
/* イベントログの読み取り */ void ReadLog(void) { DWORD BufSize; DWORD ReadBytes; DWORD NextSize; BOOL bResult; DWORD i; char *cp; char *pSourceName; char *pComputerName; HANDLE hEventLog = NULL; EVENTLOGRECORD *pBuf = NULL; char **Args = NULL; /* イベントログのオープン */ hEventLog = OpenEventLog(NULL, "Application"); if(hEventLog == NULL) { printf("event log can not open.\n"); goto Exit; } for(;;) { /* イベントログのサイズ取得 */ BufSize = 1; pBuf = (EVENTLOGRECORD *)GlobalAlloc(GMEM_FIXED, BufSize); bResult = ReadEventLog( hEventLog, EVENTLOG_FORWARDS_READ | EVENTLOG_SEQUENTIAL_READ, 0, pBuf, BufSize, &ReadBytes, &NextSize); if(!bResult && GetLastError() != ERROR_INSUFFICIENT_BUFFER) break; GlobalFree(pBuf); pBuf = NULL; /* バッファ割り当て */ BufSize = NextSize; pBuf = (EVENTLOGRECORD *)GlobalAlloc(GMEM_FIXED, BufSize); /* イベントログの読み取り */ bResult = ReadEventLog( hEventLog, EVENTLOG_FORWARDS_READ | EVENTLOG_SEQUENTIAL_READ, 0, pBuf, BufSize, &ReadBytes, &NextSize); if(!bResult) break; eventlog_record rec( pBuf ); /* 読み取ったイベントの表示 */ printf("レコード番号: %d\n", rec.RecordNumber() ); time_t t = rec.TimeGenerated(); printf("生成時刻: %s", ctime( &t ) ); t = rec.TimeWritten(); printf("書き込み時刻: %s", ctime( &t ) ); printf("イベントID: %08x\n", rec.EventID() ); printf( "イベントの種別: %s\n", rec.EventTypeText().c_str() ); cp = (char *)pBuf; cp += sizeof(EVENTLOGRECORD); pSourceName = cp; cp += strlen(cp)+1; pComputerName = cp; cp += strlen(cp)+1; printf("ソース名: %s\n", rec.SourceName().c_str() ); printf("コンピュータ名: %s\n", rec.ComputerName().c_str() ); /* カテゴリの表示 */ printf("二次カテゴリ: ", pBuf->EventCategory); DispMessage(pSourceName, "CategoryMessageFile", NULL, pBuf->EventCategory); /* メッセージの表示 */ Args = GetArgs(pBuf); printf("メッセージ: "); DispMessage(pSourceName, "EventMessageFile", (const char **)Args, pBuf->EventID); if(Args != NULL) { GlobalFree(Args); Args = NULL; } /* 固有データの表示 */ if(pBuf->DataLength > 0) { printf("固有データ: "); for(i=0; i<pBuf->DataLength; i++) printf("%02x ", *(((unsigned char *)pBuf)+(pBuf->DataOffset)+i)); printf("\n"); } printf("\n"); /* バッファ解放 */ GlobalFree(pBuf); pBuf = NULL; } Exit: /* 後処理 */ if(pBuf != NULL) GlobalFree(pBuf); if(Args != NULL) GlobalFree(Args); if(hEventLog != NULL) CloseEventLog(hEventLog); }
/* * Reads one record from an event log * * TLVs: * * req: TLV_TYPE_EVENT_HANDLE - The event log handle * req: TLV_TYPE_EVENT_READFLAGS - The flags for the read operation * opt: TLV_TYPE_EVENT_RECORDOFFSET - The record offset for SEEK operations */ DWORD request_sys_eventlog_read(Remote * remote, Packet * packet) { Packet * response = packet_create_response(packet); HANDLE hEvent = NULL; DWORD readFlags = 0, recordOffset = 0, bytesRead, bytesNeeded; DWORD result = ERROR_SUCCESS; EVENTLOGRECORD * buf = NULL; BYTE * str = NULL; hEvent = (HANDLE)packet_get_tlv_value_qword(packet, TLV_TYPE_EVENT_HANDLE); readFlags = (DWORD)packet_get_tlv_value_uint(packet, TLV_TYPE_EVENT_READFLAGS); recordOffset = (DWORD)packet_get_tlv_value_uint(packet, TLV_TYPE_EVENT_RECORDOFFSET); do { if(!hEvent || !readFlags) { result = ERROR_INVALID_PARAMETER; break; } /* get the length of the next record, ghettoly */ if(ReadEventLog(hEvent, readFlags, recordOffset, &bytesRead, 0, &bytesRead, &bytesNeeded ) != 0 || GetLastError() != ERROR_INSUFFICIENT_BUFFER) { result = GetLastError(); // packet_add_raw(response, TLV_TYPE_EVENT_BYTESNEEDED) break; } if((buf = malloc(bytesNeeded)) == NULL) { result = ERROR_NOT_ENOUGH_MEMORY; break; } if(ReadEventLog(hEvent, readFlags, recordOffset, buf, bytesNeeded, &bytesRead, &bytesNeeded ) == 0) { result = GetLastError(); // packet_add_raw(response, TLV_TYPE_EVENT_BYTESNEEDED) break; } packet_add_tlv_uint(response, TLV_TYPE_EVENT_RECORDNUMBER, buf->RecordNumber); packet_add_tlv_uint(response, TLV_TYPE_EVENT_TIMEGENERATED, buf->TimeGenerated); packet_add_tlv_uint(response, TLV_TYPE_EVENT_TIMEWRITTEN, buf->TimeWritten); packet_add_tlv_uint(response, TLV_TYPE_EVENT_ID, buf->EventID); packet_add_tlv_uint(response, TLV_TYPE_EVENT_TYPE, buf->EventType); packet_add_tlv_uint(response, TLV_TYPE_EVENT_CATEGORY, buf->EventCategory); packet_add_tlv_raw(response, TLV_TYPE_EVENT_DATA, (BYTE *)buf + buf->DataOffset, buf->DataLength); str = (BYTE *)buf + buf->StringOffset; while(buf->NumStrings > 0) { packet_add_tlv_string(response, TLV_TYPE_EVENT_STRING, str); /* forward pass the null terminator */ while(*str++ != 0); buf->NumStrings--; } } while(0); packet_transmit_response(result, remote, response); if(buf) free(buf); return ERROR_SUCCESS; }
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; }
/* Get the next eventlog message */ char * EventlogNext(EventList ignore_list[MAX_IGNORED_EVENTS], int log, int * level) { BOOL reopen = FALSE; DWORD errnum; DWORD needed; DWORD loglevel; EVENTLOGRECORD * event; char * cp; char * current; char * formatted_string; char * message_file; char * source; char * string_array[EVENTLOG_ARRAY_SZ]; char * username; char hostname[HOSTNAME_SZ]; char defmsg[ERRMSG_SZ]; int event_id; int i; char *index; static char message[SYSLOG_DEF_SZ-17]; static char tstamped_message[SYSLOG_DEF_SZ]; /* Initialize array to prevent memory exceptions with bad message definitions */ for(i = 0; i < EVENTLOG_ARRAY_SZ; i++) string_array[i]="*"; /* Are there any records left in buffer */ while (EventlogList[log].pos == EventlogList[log].count) { /* Reset input position */ EventlogList[log].count = 0; EventlogList[log].pos = 0; /* Read a record */ needed = 0; if (ReadEventLog(EventlogList[log].handle, EVENTLOG_FORWARDS_READ | EVENTLOG_SEEK_READ, EventlogList[log].recnum, EventlogList[log].buffer, sizeof(EventlogList[log].buffer), &EventlogList[log].count, &needed) == 0) { /* Check error */ errnum = GetLastError(); switch (errnum) { /* Message too large... skip over */ case ERROR_INSUFFICIENT_BUFFER: Log(LOG_WARNING, "Eventlog message size too large: \"%s\": %u bytes", EventlogList[log].name, needed); EventlogList[log].recnum++; break; /* Eventlog corrupted (?)... Reopen */ case ERROR_EVENTLOG_FILE_CORRUPT: Log(LOG_INFO, "Eventlog was corrupted: \"%s\"", EventlogList[log].name); reopen = TRUE; break; /* Eventlog files are clearing... Reopen */ case ERROR_EVENTLOG_FILE_CHANGED: Log(LOG_INFO, "Eventlog was cleared: \"%s\"", EventlogList[log].name); reopen = TRUE; break; /* Record not available (yet) */ case ERROR_INVALID_PARAMETER: return NULL; /* Normal end of eventlog messages */ case ERROR_HANDLE_EOF: return NULL; /* Eventlog probably closing down */ case RPC_S_UNKNOWN_IF: return NULL; /* Unknown condition */ default: Log(LOG_ERROR|LOG_SYS, "Eventlog \"%s\" returned error: ", EventlogList[log].name); ServiceIsRunning = FALSE; return NULL; } /* Process reopen */ if (reopen) { EventlogClose(log); if (EventlogOpen(log)) { ServiceIsRunning = FALSE; return NULL; } reopen = FALSE; } } } /* Increase record number */ EventlogList[log].recnum++; /* Get position into buffer */ current = EventlogList[log].buffer + EventlogList[log].pos; /* Get pointer to current event record */ event = (EVENTLOGRECORD *) current; /* Advance position */ EventlogList[log].pos += event->Length; /* Get source and event id */ source = current + sizeof(*event); event_id = (int) HRESULT_CODE(event->EventID); /* Check Event Info Against Ignore List */ if (IgnoreSyslogEvent(ignore_list, source, event_id)) { if (LogInteractive) printf("IGNORING_EVENT: SOURCE=%s & ID=%i\n", source, event_id); return NULL; } /* Check number of strings */ if (event->NumStrings > COUNT_OF(string_array)) { /* Too many strings */ Log(LOG_WARNING, "Eventlog message has too many strings to print message: \"%s\": %u strings", EventlogList[log].name, event->NumStrings); formatted_string = NULL; } else { /* Convert strings to arrays */ cp = current + event->StringOffset; for (i = 0; i < event->NumStrings; i++) { string_array[i] = cp; while (*cp++ != '\0'); } message_file = LookupMessageFile(EventlogList[log].name, source, event->EventID); if (message_file == NULL) { /* Cannot load resources */ formatted_string = NULL; } else { /* Format eventlog message */ formatted_string = FormatLibraryMessage(message_file, event->EventID, string_array); } } /* Create a default message if resources or formatting didn't work */ if (formatted_string == NULL) { _snprintf_s(defmsg, sizeof(defmsg), _TRUNCATE, "(Facility: %u, Status: %s)", HRESULT_FACILITY(event->EventID), FAILED(event->EventID) ? "Failure" : "Success" ); formatted_string = defmsg; } /* replace every space in source by underscores */ index = source; while( *index ) { if( *index == ' ' ) { *index = '_'; } index++; } /* Format source and event ID number */ if(SyslogIncludeTag) { _snprintf_s(message, sizeof(message), _TRUNCATE, "%s: %s: %u: ", SyslogTag, source, HRESULT_CODE(event->EventID) ); } else { _snprintf_s(message, sizeof(message), _TRUNCATE, "%s: %u: ", source, HRESULT_CODE(event->EventID) ); } /* Convert user */ if (event->UserSidLength > 0) { username = GetUsername((SID *) (current + event->UserSidOffset)); if (username) { strncat_s(message, sizeof(message), username, _TRUNCATE); strncat_s(message, sizeof(message), ": ", _TRUNCATE); } } /* Add formatted string to base message */ strncat_s(message, sizeof(message), formatted_string, _TRUNCATE); /* Select syslog level */ switch (event->EventType) { case EVENTLOG_ERROR_TYPE: loglevel = SYSLOG_ERR; *level = SYSLOG_BUILD(SyslogFacility, loglevel); break; case EVENTLOG_WARNING_TYPE: loglevel = SYSLOG_WARNING; *level = SYSLOG_BUILD(SyslogFacility, loglevel); break; case EVENTLOG_INFORMATION_TYPE: loglevel = SYSLOG_NOTICE; *level = SYSLOG_BUILD(SyslogFacility, loglevel); break; case EVENTLOG_AUDIT_SUCCESS: strncat_s(message, sizeof(message), "AUDIT_SUCCESS ", _TRUNCATE); loglevel = SYSLOG_NOTICE; *level = SYSLOG_BUILD(SyslogFacility, loglevel); break; case EVENTLOG_AUDIT_FAILURE: strncat_s(message, sizeof(message), "AUDIT_FAILURE ", _TRUNCATE); loglevel = SYSLOG_ERR; *level = SYSLOG_BUILD(SyslogFacility, loglevel); break; /* Everything else */ case EVENTLOG_SUCCESS: default: loglevel = SYSLOG_NOTICE; *level = SYSLOG_BUILD(SyslogFacility, loglevel); break; } /* If event is not being ignored, make sure it is severe enough to be logged */ if (SyslogLogLevel != 0) if (SyslogLogLevel < loglevel-1) return NULL; /* Add hostname for RFC compliance (RFC 3164) */ /* if -a then use the fqdn bound to our IP address. If none, use the IP address */ if (ProgramUseIPAddress == TRUE) { strcpy_s(hostname, HOSTNAME_SZ, ProgramHostName); } else { if (ExpandEnvironmentStrings("%COMPUTERNAME%", hostname, COUNT_OF(hostname)) == 0) { strcpy_s(hostname, COUNT_OF(hostname), "HOSTNAME_ERR"); Log(LOG_ERROR|LOG_SYS, "Cannot expand %COMPUTERNAME%"); } } /* Query and Add timestamp from EventLog, add hostname, */ /* and finally the message to the string */ _snprintf_s(tstamped_message, sizeof(tstamped_message), _TRUNCATE, "%s %s %s", TimeToString(event->TimeGenerated), hostname, message ); /* Return formatted message */ return tstamped_message; }
int read_windows_sys_log::ReadSystemEventLog(const char *Src, Value &value) { value["t"] = "win_system_log"; DWORD read_len, next_len; char Buffer[256], Data[4096], *pchar; HANDLE Handle = OpenEventLog(NULL, Src); if (Handle==NULL) { CloseHandle(Handle); return -1; } while(ReadEventLog(Handle, EVENTLOG_FORWARDS_READ | EVENTLOG_SEQUENTIAL_READ,1, (EVENTLOGRECORD*)Data, sizeof(Data), &read_len, &next_len)) { Value log_object; for(short i=0; i<read_len;) { //printf("%d\n",read_len); EVENTLOGRECORD *ptr = (EVENTLOGRECORD*)(Data+i); switch(ptr->EventType) //事件类型 { case EVENTLOG_SUCCESS: pchar= "成功"; break; case EVENTLOG_ERROR_TYPE: pchar= "错误"; break; case EVENTLOG_WARNING_TYPE: pchar= "警告"; break; case EVENTLOG_INFORMATION_TYPE: pchar= "信息"; break; case EVENTLOG_AUDIT_SUCCESS: pchar= "审计成功"; break; case EVENTLOG_AUDIT_FAILURE: pchar= "审计失败"; break; default: continue; } //sprintf(Buffer, "事件\t%u\n", (short)(ptr->EventID)); //事件ID //Result += Buffer; log_object["事件"] = boost::lexical_cast<string>(ptr->EventID); /*sprintf(Buffer, "类型\t%s\n", pchar); Result += Buffer; */ log_object["类型"] = boost::lexical_cast<string>(pchar); //time_t timep; //struct tm *p; //time(&timep); //p = localtime(&timep); //tm *ptm = localtime(&timep); tm *ptm = localtime((const time_t *)(&(ptr->TimeWritten))); //取得当地时间 sprintf(Buffer, "%.4hd-%.2hd-%.2hd %.2hd:%.2hd:%.2hd", ptm->tm_year+1900, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec); //Result += Buffer; log_object["时间"] = Buffer; pchar = Data + sizeof(EVENTLOGRECORD); //pchar指向SourceName[] //sprintf(Buffer, "来源\t%s\n", pchar); //事件来源 //Result += Buffer; log_object["来源"] = pchar; //pchar += strlen(pchar) + 1; //pchar指向ComputerName[] //sprintf(Buffer, "计算机\t%s\n", pchar); //机器名 //Result += Buffer; log_object["计算机"] = pchar; pchar += strlen(pchar) + 1; // pchar指向UserSid if(ptr->UserSidLength > 0) { char Name[64]; DWORD Length = sizeof(SID), Length1 = sizeof(Buffer); SID_NAME_USE Type = SidTypeUser; SID *sid = (SID *)(Data + ptr->UserSidOffset); if(LookupAccountSid(NULL, sid, Name, &Length, Buffer, &Length1, &Type)) { //查找用户名 //sprintf(Buffer, "用户\t%s\n", Name); //用户名 //Result+=Buffer; log_object["用户"] = Name; } } if(ptr->DataOffset > ptr->StringOffset) //获取事件描述 { //Result += "[描述]\t"; pchar = Data + i + ptr->StringOffset; for(short j = 0; j < ptr->NumStrings; j++) { //Result += pchar; if(j < ptr->NumStrings-1) //Result += ' '; pchar += strlen(pchar) + 1; } //Result += '\n'; // Result+="[数据]/n"; log_object["[描述]"] = pchar; } //Result+='\n'; i+=ptr->Length; } value["System_log_array"].append(log_object); } //fwrite(Result.c_str(),Result.length(),1,pFile); CloseEventLog(Handle); return 0; }
void main() { HANDLE hEventLog; EVENTLOGRECORD* pEventLogRecord = 0; EVENTRECORD* pER = 0; CHAR szFilePath[_MAX_PATH]; CHAR szDate[9]; DWORD dwBytesRead, dwBytesNeeded; DWORD dwEventLogRecords, dwTemp; FILE* fp; // get current date GetCurrentDate(szDate); // get file path if (!(GetFilePath(szFilePath))) strcpy(szFilePath, ""); // format file name sprintf(szFileName, "%s%s%s", szFilePath, szDate, ".LOG"); // open security event log on local machine printf("Opening Security Event Log for Reading...\n"); if (!(hEventLog = OpenEventLog(NULL, "Security"))) { printf("Error Opening Event Log.\n"); return; } // open event file printf("Opening Event File %s for Writing...\n", szFileName); if ((fp = fopen(szFileName, "w+t")) == NULL) { printf("Error Opening Event File.\n"); return; } // find the number of event log records GetNumberOfEventLogRecords(hEventLog, &dwEventLogRecords); // read data and output to file printf("Writing Data To File...\n"); for (dwTemp = 1; dwTemp <= dwEventLogRecords; dwTemp++) { if (!(pEventLogRecord = (EVENTLOGRECORD*)malloc(16384))) return; // read records from event log if (!(ReadEventLog(hEventLog, // event log handle EVENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ, // get specified record dwTemp, pEventLogRecord, // buffer address 16384, // max size &dwBytesRead, // number of bytes read &dwBytesNeeded))) // number of bytes needed ShowError(); // read record information if (dwBytesRead) { if (ShouldWriteRecord(pEventLogRecord->TimeWritten)) { // allocate memory for event record if (!(pER = (EVENTRECORD*)malloc(sizeof(EVENTRECORD)))) { printf("Error allocating memory for record.\n"); if (pEventLogRecord) free (pEventLogRecord); return; } // set event record into structure SetEventRecord(pEventLogRecord, pER); // write data to file fprintf(fp, "%d\t%s\t%s\t%s\t%s\n%s\n", pER->EventID, pER->szEventDate, pER->szEventType, pER->szSourceName, pER->szComputerName, pER->pMessage); // free allocated memory if (pER) free(pER); } } // free allocated buffer if (pEventLogRecord) free (pEventLogRecord); } printf("Closing Files...\n"); // release event log handle CloseEventLog(hEventLog); // close event file _flushall(); fclose(fp); // send message printf("Sending messages...\n"); SendMail(); }
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; }