https://docs.microsoft.com/zh-cn/windows/desktop/EventLog/querying-for-event-source-messages

#include <windows.h>
#include <stdio.h>
#include <strsafe.h> #define PROVIDER_NAME L"MyEventProvider"
#define RESOURCE_DLL L"<path>\\Provider.dll"
#define MAX_TIMESTAMP_LEN 23 + 1 // mm/dd/yyyy hh:mm:ss.mmm
#define MAX_RECORD_BUFFER_SIZE 0x10000 // 64K HANDLE GetMessageResources();
DWORD DumpRecordsInBuffer(PBYTE pBuffer, DWORD dwBytesRead);
DWORD GetEventTypeName(DWORD EventType);
LPWSTR GetMessageString(DWORD Id, DWORD argc, LPWSTR args);
void GetTimestamp(const DWORD Time, WCHAR DisplayString[]);
DWORD ApplyParameterStringsToMessage(CONST LPCWSTR pMessage, LPWSTR & pFinalMessage); CONST LPWSTR pEventTypeNames[] = {L"Error", L"Warning", L"Informational", L"Audit Success", L"Audit Failure"}; HANDLE g_hResources = NULL; void wmain(void)
{
HANDLE hEventLog = NULL;
DWORD status = ERROR_SUCCESS;
DWORD dwBytesToRead = ;
DWORD dwBytesRead = ;
DWORD dwMinimumBytesToRead = ;
PBYTE pBuffer = NULL;
PBYTE pTemp = NULL; // The source name (provider) must exist as a subkey of Application.
hEventLog = OpenEventLog(NULL, PROVIDER_NAME);
if (NULL == hEventLog)
{
wprintf(L"OpenEventLog failed with 0x%x.\n", GetLastError());
goto cleanup;
} // Get the DLL that contains the string resources for the provider.
g_hResources = GetMessageResources();
if (NULL == g_hResources)
{
wprintf(L"GetMessageResources failed.\n");
goto cleanup;
} // Allocate an initial block of memory used to read event records. The number
// of records read into the buffer will vary depending on the size of each event.
// The size of each event will vary based on the size of the user-defined
// data included with each event, the number and length of insertion
// strings, and other data appended to the end of the event record.
dwBytesToRead = MAX_RECORD_BUFFER_SIZE;
pBuffer = (PBYTE)malloc(dwBytesToRead);
if (NULL == pBuffer)
{
wprintf(L"Failed to allocate the initial memory for the record buffer.\n");
goto cleanup;
} // Read blocks of records until you reach the end of the log or an
// error occurs. The records are read from newest to oldest. If the buffer
// is not big enough to hold a complete event record, reallocate the buffer.
while (ERROR_SUCCESS == status)
{
if (!ReadEventLog(hEventLog,
EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ,
,
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 the memory for the record buffer (%d bytes).\n", dwMinimumBytesToRead);
goto cleanup;
} pBuffer = pTemp;
dwBytesToRead = dwMinimumBytesToRead;
}
else
{
if (ERROR_HANDLE_EOF != status)
{
wprintf(L"ReadEventLog failed with %lu.\n", status);
goto cleanup;
}
}
}
else
{
// Print the contents of each record in the buffer.
DumpRecordsInBuffer(pBuffer, dwBytesRead);
}
} cleanup: if (hEventLog)
CloseEventLog(hEventLog); if (pBuffer)
free(pBuffer);
} // Get the provider DLL that contains the string resources for the
// category strings, event message strings, and parameter insert strings.
// For this example, the path to the DLL is hardcoded but typically,
// you would read the CategoryMessageFile, EventMessageFile, and
// ParameterMessageFile registry values under the source's registry key located
// under \SYSTEM\CurrentControlSet\Services\Eventlog\Application in
// the HKLM registry hive. In this example, all resources are included in
// the same resource-only DLL.
HANDLE GetMessageResources()
{
HANDLE hResources = NULL; hResources = LoadLibraryEx(RESOURCE_DLL, NULL, LOAD_LIBRARY_AS_IMAGE_RESOURCE | LOAD_LIBRARY_AS_DATAFILE);
if (NULL == hResources)
{
wprintf(L"LoadLibrary failed with %lu.\n", GetLastError());
} return hResources;
} // Loop through the buffer and print the contents of each record
// in the buffer.
DWORD DumpRecordsInBuffer(PBYTE pBuffer, DWORD dwBytesRead)
{
DWORD status = ERROR_SUCCESS;
PBYTE pRecord = pBuffer;
PBYTE pEndOfRecords = pBuffer + dwBytesRead;
LPWSTR pMessage = NULL;
LPWSTR pFinalMessage = NULL;
WCHAR TimeStamp[MAX_TIMESTAMP_LEN]; while (pRecord < pEndOfRecords)
{
// If the event was written by our provider, write the contents of the event.
if ( == wcscmp(PROVIDER_NAME, (LPWSTR)(pRecord + sizeof(EVENTLOGRECORD))))
{
GetTimestamp(((PEVENTLOGRECORD)pRecord)->TimeGenerated, TimeStamp);
wprintf(L"Time stamp: %s\n", TimeStamp);
wprintf(L"record number: %lu\n", ((PEVENTLOGRECORD)pRecord)->RecordNumber);
wprintf(L"status code: %d\n", ((PEVENTLOGRECORD)pRecord)->EventID & 0xFFFF);
wprintf(L"event type: %s\n", pEventTypeNames[GetEventTypeName(((PEVENTLOGRECORD)pRecord)->EventType)]); pMessage = GetMessageString(((PEVENTLOGRECORD)pRecord)->EventCategory, , NULL); if (pMessage)
{
wprintf(L"event category: %s", pMessage);
LocalFree(pMessage);
pMessage = NULL;
} pMessage = GetMessageString(((PEVENTLOGRECORD)pRecord)->EventID,
((PEVENTLOGRECORD)pRecord)->NumStrings, (LPWSTR)(pRecord + ((PEVENTLOGRECORD)pRecord)->StringOffset)); if (pMessage)
{
status = ApplyParameterStringsToMessage(pMessage, pFinalMessage); wprintf(L"event message: %s", (pFinalMessage) ? pFinalMessage : pMessage);
LocalFree(pMessage);
pMessage = NULL; if (pFinalMessage)
{
free(pFinalMessage);
pFinalMessage = NULL;
}
} // To write the event data, you need to know the format of the data. In
// this example, we know that the event data is a null-terminated string.
if (((PEVENTLOGRECORD)pRecord)->DataLength > )
{
wprintf(L"event data: %s\n", (LPWSTR)(pRecord + ((PEVENTLOGRECORD)pRecord)->DataOffset));
} wprintf(L"\n");
} pRecord += ((PEVENTLOGRECORD)pRecord)->Length;
} return status;
} // Get an index value to the pEventTypeNames array based on
// the event type value.
DWORD GetEventTypeName(DWORD EventType)
{
DWORD index = ; switch (EventType)
{
case EVENTLOG_ERROR_TYPE:
index = ;
break;
case EVENTLOG_WARNING_TYPE:
index = ;
break;
case EVENTLOG_INFORMATION_TYPE:
index = ;
break;
case EVENTLOG_AUDIT_SUCCESS:
index = ;
break;
case EVENTLOG_AUDIT_FAILURE:
index = ;
break;
} return index;
} // Formats the specified message. If the message uses inserts, build
// the argument list to pass to FormatMessage.
LPWSTR GetMessageString(DWORD MessageId, DWORD argc, LPWSTR argv)
{
LPWSTR pMessage = NULL;
DWORD dwFormatFlags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER;
DWORD_PTR* pArgs = NULL;
LPWSTR pString = argv; // The insertion strings appended to the end of the event record
// are an array of strings; however, FormatMessage requires
// an array of addresses. Create an array of DWORD_PTRs based on
// the count of strings. Assign the address of each string
// to an element in the array (maintaining the same order).
if (argc > )
{
pArgs = (DWORD_PTR*)malloc(sizeof(DWORD_PTR) * argc);
if (pArgs)
{
dwFormatFlags |= FORMAT_MESSAGE_ARGUMENT_ARRAY; for (DWORD i = ; i < argc; i++)
{
pArgs[i] = (DWORD_PTR)pString;
pString += wcslen(pString) + ;
}
}
else
{
dwFormatFlags |= FORMAT_MESSAGE_IGNORE_INSERTS;
wprintf(L"Failed to allocate memory for the insert string array.\n");
}
} if (!FormatMessage(dwFormatFlags,
g_hResources,
MessageId,
,
(LPWSTR)&pMessage,
,
(va_list*)pArgs))
{
wprintf(L"Format message failed with %lu\n", GetLastError());
} if (pArgs)
free(pArgs); return pMessage;
} // If the message string contains parameter insertion strings (for example, %%4096),
// you must perform the parameter substitution yourself. To get the parameter message
// string, call FormatMessage with the message identifier found in the parameter insertion
// string (for example, 4096 is the message identifier if the parameter insertion string
// is %%4096). You then substitute the parameter insertion string in the message
// string with the actual parameter message string.
DWORD ApplyParameterStringsToMessage(CONST LPCWSTR pMessage, LPWSTR & pFinalMessage)
{
DWORD status = ERROR_SUCCESS;
DWORD dwParameterCount = ; // Number of insertion strings found in pMessage
size_t cbBuffer = ; // Size of the buffer in bytes
size_t cchBuffer = ; // Size of the buffer in characters
size_t cchParameters = ; // Number of characters in all the parameter strings
size_t cch = ;
DWORD i = ;
LPWSTR* pStartingAddresses = NULL; // Array of pointers to the beginning of each parameter string in pMessage
LPWSTR* pEndingAddresses = NULL; // Array of pointers to the end of each parameter string in pMessage
DWORD* pParameterIDs = NULL; // Array of parameter identifiers found in pMessage
LPWSTR* pParameters = NULL; // Array of the actual parameter strings
LPWSTR pTempMessage = (LPWSTR)pMessage;
LPWSTR pTempFinalMessage = NULL; // Determine the number of parameter insertion strings in pMessage.
while (pTempMessage = wcschr(pTempMessage, L'%'))
{
dwParameterCount++;
pTempMessage++;
} // If there are no parameter insertion strings in pMessage, return.
if ( == dwParameterCount)
{
pFinalMessage = NULL;
goto cleanup;
} // Allocate an array of pointers that will contain the beginning address
// of each parameter insertion string.
cbBuffer = sizeof(LPWSTR) * dwParameterCount;
pStartingAddresses = (LPWSTR*)malloc(cbBuffer);
if (NULL == pStartingAddresses)
{
wprintf(L"Failed to allocate memory for pStartingAddresses.\n");
status = ERROR_OUTOFMEMORY;
goto cleanup;
} RtlZeroMemory(pStartingAddresses, cbBuffer); // Allocate an array of pointers that will contain the ending address (one
// character past the of the identifier) of the each parameter insertion string.
pEndingAddresses = (LPWSTR*)malloc(cbBuffer);
if (NULL == pEndingAddresses)
{
wprintf(L"Failed to allocate memory for pEndingAddresses.\n");
status = ERROR_OUTOFMEMORY;
goto cleanup;
} RtlZeroMemory(pEndingAddresses, cbBuffer); // Allocate an array of pointers that will contain pointers to the actual
// parameter strings.
pParameters = (LPWSTR*)malloc(cbBuffer);
if (NULL == pParameters)
{
wprintf(L"Failed to allocate memory for pEndingAddresses.\n");
status = ERROR_OUTOFMEMORY;
goto cleanup;
} RtlZeroMemory(pParameters, cbBuffer); // Allocate an array of DWORDs that will contain the message identifier
// for each parameter.
pParameterIDs = (DWORD*)malloc(cbBuffer);
if (NULL == pParameterIDs)
{
wprintf(L"Failed to allocate memory for pParameterIDs.\n");
status = ERROR_OUTOFMEMORY;
goto cleanup;
} RtlZeroMemory(pParameterIDs, cbBuffer); // Find each parameter in pMessage and get the pointer to the
// beginning of the insertion string, the end of the insertion string,
// and the message identifier of the parameter.
pTempMessage = (LPWSTR)pMessage;
while (pTempMessage = wcschr(pTempMessage, L'%'))
{
if (isdigit(*(pTempMessage+)))
{
pStartingAddresses[i] = pTempMessage; pTempMessage++;
pParameterIDs[i] = (DWORD)_wtoi(pTempMessage); while (isdigit(*++pTempMessage))
; pEndingAddresses[i] = pTempMessage; i++;
}
} // For each parameter, use the message identifier to get the
// actual parameter string.
for (DWORD i = ; i < dwParameterCount; i++)
{
pParameters[i] = GetMessageString(pParameterIDs[i], , NULL);
if (NULL == pParameters[i])
{
wprintf(L"GetMessageString could not find parameter string for insert %lu.\n", i);
status = ERROR_INVALID_PARAMETER;
goto cleanup;
} cchParameters += wcslen(pParameters[i]);
} // Allocate enough memory for pFinalMessage based on the length of pMessage
// and the length of each parameter string. The pFinalMessage buffer will contain
// the completed parameter substitution.
pTempMessage = (LPWSTR)pMessage;
cbBuffer = (wcslen(pMessage) + cchParameters + ) * sizeof(WCHAR);
pFinalMessage = (LPWSTR)malloc(cbBuffer);
if (NULL == pFinalMessage)
{
wprintf(L"Failed to allocate memory for pFinalMessage.\n");
status = ERROR_OUTOFMEMORY;
goto cleanup;
} RtlZeroMemory(pFinalMessage, cbBuffer);
cchBuffer = cbBuffer / sizeof(WCHAR);
pTempFinalMessage = pFinalMessage; // Build the final message string.
for (DWORD i = ; i < dwParameterCount; i++)
{
// Append the segment from pMessage. In the first iteration, this is "8 " and in the
// second iteration, this is " = 2 ".
wcsncpy_s(pTempFinalMessage, cchBuffer, pTempMessage, cch = (pStartingAddresses[i] - pTempMessage));
pTempMessage = pEndingAddresses[i];
cchBuffer -= cch; // Append the parameter string. In the first iteration, this is "quarts" and in the
// second iteration, this is "gallons"
pTempFinalMessage += cch;
wcscpy_s(pTempFinalMessage, cchBuffer, pParameters[i]);
cchBuffer -= cch = wcslen(pParameters[i]); pTempFinalMessage += cch;
} // Append the last segment from pMessage, which is ".".
wcscpy_s(pTempFinalMessage, cchBuffer, pTempMessage); cleanup: if (ERROR_SUCCESS != status)
pFinalMessage = (LPWSTR)pMessage; if (pStartingAddresses)
free(pStartingAddresses); if (pEndingAddresses)
free(pEndingAddresses); if (pParameterIDs)
free(pParameterIDs); for (DWORD i = ; i < dwParameterCount; i++)
{
if (pParameters[i])
LocalFree(pParameters[i]);
} return status;
} // Get a string that contains the time stamp of when the event
// was generated.
void GetTimestamp(const DWORD Time, WCHAR DisplayString[])
{
ULONGLONG ullTimeStamp = ;
ULONGLONG SecsTo1970 = ;
SYSTEMTIME st;
FILETIME ft, ftLocal; ullTimeStamp = Int32x32To64(Time, ) + SecsTo1970;
ft.dwHighDateTime = (DWORD)((ullTimeStamp >> ) & 0xFFFFFFFF);
ft.dwLowDateTime = (DWORD)(ullTimeStamp & 0xFFFFFFFF); FileTimeToLocalFileTime(&ft, &ftLocal);
FileTimeToSystemTime(&ftLocal, &st);
StringCchPrintf(DisplayString, MAX_TIMESTAMP_LEN, L"%d/%d/%d %.2d:%.2d:%.2d",
st.wMonth, st.wDay, st.wYear, st.wHour, st.wMinute, st.wSecond);
}

Querying for Event Information的更多相关文章

  1. Event Sourcing Pattern 事件源模式

    Use an append-only store to record the full series of events that describe actions taken on data in ...

  2. Event Sourcing pattern

    Event Sourcing pattern Instead of storing just the current state of the data in a domain, use an app ...

  3. Event List 2

    The list of events can be found in src/switch_event.c in a char array called EVENT_NAMES and is summ ...

  4. Event List

    Created by John Boteler on 2015.01.16 Go to start of metadata   About The current up-to-date list of ...

  5. javascript 中event是全局变量

    The only thing I can think of is that event is in fact window.event and it makes itself available wh ...

  6. 《NVM-Express-1_4-2019.06.10-Ratified》学习笔记(5.2)-- Asynchronous Event Request command

    5.2 异步事件请求命令 异步事件用于当状态.错误.健康信息这些事件发生时通知主机软件.为了使能这个controller报告的异步事件,主机软件需要提交一个或多个异步事件请求命令到controller ...

  7. Java性能提示(全)

    http://www.onjava.com/pub/a/onjava/2001/05/30/optimization.htmlComparing the performance of LinkedLi ...

  8. 基于ACIS/HOOPS的3D应用开发简介 【转】

    (整理) 平台:                造型引擎——ACIS         显示引擎——Direct3D/OpenGL/GDI         应用框架——HOOPS   组件关系图     ...

  9. Residential Gateway System for Home Network Service

    Disclosed herein is a Residential Gateway (RG) system for home network service. The RG system receiv ...

随机推荐

  1. P1345 [USACO5.4]奶牛的电信(点拆边 + 网络最小割)

    题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流.这些机器用如下的方式发送电邮:如果存在一个由c台电脑组成的序列a1,a2,-,a©,且a1与a2相连,a2 ...

  2. block 的内存结构衍生出来的面试题

    今天在群里看到大佬们在讨论一个面试题,问如下代码在 32bit 和 64bit 系统上分别报什么错误: #import <Foundation/Foundation.h> int main ...

  3. Git创建本地仓库&把pycharm项目添加GitHub仓库上

    一.创建本地仓库 1.1.下载Git地址:https://git-scm.com/downloads 下载完,一路next就可以 1.2.打开Git Bash输入: #创建一个learngit目录 $ ...

  4. 深入解读ES6系列(四)

    来自老曾es6的前言: 哈喽小伙伴们,爱说'废'话的Z又回来了,欢迎来到Super IT曾的博客时间,上一节说了字符串,面向对象以及json的知识,这一节我们继续我们知识的海洋,一起奋斗不秃头!不足的 ...

  5. C++ 模板和 C# 泛型的区别

    C# Generics and C++ templates are both language features that provide support for parameterized type ...

  6. Shell:Day05.笔记

    交互输入与for语句 1.交互输入 read  Python中用input()函数,进行输入:  read命令同时可以定义多个变量值:而输入的内容默认以空格为分隔符,将值输入到对应的变量中: 如果默认 ...

  7. 【数据库】MySQL数据库(五)

    一.DCL语句 1.添加权限: '; 注:sakili为数据库名,z1为新创建的数据库用户,123为密码 数据库添加权限 2.权限收回: revoke insert on sakila.* from ...

  8. MTK Android Driver :Camera

    MTK Android Driver :camera 1.相关代码位置:mediatek\config\XXXX(红色字为具体的项目名) 文件:ProjectConfig.mk CUSTOM_KERN ...

  9. Solr复杂查询一:函数查询

    一.简介 Solr的函数可以动态计算每个文档的值,而不是返回在索引阶段对应字段的静态数值集.函数查询是一类特殊的查询,它可以像关键词一样添加到查询中,对所有文档进行匹配并返回它们的函数计算值作为文档得 ...

  10. awk线程号

    for i in `ps|grep [a]out|awk '{print $1}'` do kill -9 "$i" done