Querying for Event Information
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的更多相关文章
- Event Sourcing Pattern 事件源模式
Use an append-only store to record the full series of events that describe actions taken on data in ...
- Event Sourcing pattern
Event Sourcing pattern Instead of storing just the current state of the data in a domain, use an app ...
- 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 ...
- Event List
Created by John Boteler on 2015.01.16 Go to start of metadata About The current up-to-date list of ...
- javascript 中event是全局变量
The only thing I can think of is that event is in fact window.event and it makes itself available wh ...
- 《NVM-Express-1_4-2019.06.10-Ratified》学习笔记(5.2)-- Asynchronous Event Request command
5.2 异步事件请求命令 异步事件用于当状态.错误.健康信息这些事件发生时通知主机软件.为了使能这个controller报告的异步事件,主机软件需要提交一个或多个异步事件请求命令到controller ...
- Java性能提示(全)
http://www.onjava.com/pub/a/onjava/2001/05/30/optimization.htmlComparing the performance of LinkedLi ...
- 基于ACIS/HOOPS的3D应用开发简介 【转】
(整理) 平台: 造型引擎——ACIS 显示引擎——Direct3D/OpenGL/GDI 应用框架——HOOPS 组件关系图 ...
- Residential Gateway System for Home Network Service
Disclosed herein is a Residential Gateway (RG) system for home network service. The RG system receiv ...
随机推荐
- 9.Metasploit制作木马后门
01木马与后门 木马?后门? 木马和后门都有害,尤其是木马,它由攻击者主动发起,稍不留心就会被利用:后门原来是留给自己方便用的,但也有可能被非法利用,这两种程序都会给用户带来损失. 木马是指潜伏在 ...
- 深入解读ES6系列(二)
ES6函数 哈喽小伙伴们,爱说'废'话的Z又回来了,欢迎来到Super IT曾的博客时间,上一节说了es6的历史,变量,以及闭包,这一节我们继续我们知识的海洋,一起奋斗不秃头!不足的欢迎提问留言. 今 ...
- 逃生 HDU 4857(反向建图 + 拓扑排序)
逃生 链接 Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必 ...
- M - 诡异的楼梯 HDU - 1180(BFS + 在某个点等待一下 / 重复走该点)
M - 诡异的楼梯 HDU - 1180 Hogwarts正式开学以后,Harry发现在Hogwarts里,某些楼梯并不是静止不动的,相反,他们每隔一分钟就变动一次方向. 比如下面的例子里,一开始楼梯 ...
- H、Magic necklace
链接:https://ac.nowcoder.com/acm/contest/3570/H 来源:牛客网 题目描述 There was a magic necklace. The necklace i ...
- Rust入坑指南:万物初始
有没有同学记得我们一起挖了多少个坑?嗯-其实我自己也不记得了,今天我们再来挖一个特殊的坑,这个坑可以说是挖到根源了--元编程. 元编程是编程领域的一个重要概念,它允许程序将代码作为数据,在运行时对代码 ...
- Light of future-冲刺Day 3
目录 1.SCRUM部分: 每个成员进度 SCRUM 会议的照片 签入记录 代码运行截图 发布界面 用户浏览界面 管理员浏览界面 2.PM 报告: 时间表 燃尽图 任务总量变化曲线 每名成员的贡献比 ...
- C++不被继承的内容
C++不被继承的内容 派生类会继承基类所有的方法和变量,除了: 构造函数,析构函数 重载运算符 友元函数 注意,私有成员是被继承了的,只是无法访问.我们可以通过sizeof判断出来.下面附一张清晰的图
- 如何将icon图标库引入自己的项目中
---恢复内容开始--- 今天是18年的国庆,趁着国庆的这股开心劲儿,开开心心的写点东西: 第一篇:关于如何将icon图标库引入自己的项目(此方法Taro,微信小程序,支付宝小程序等均适用,不会存在不 ...
- Tkinter布局管理器
Layout management in Tkinter 原英文教程地址:zetcode.com In this part of the Tkinter tutorial, we introduce ...