Windows 7 如果(hEventLog) 关闭事件日志(hEventLog); if(pBuffer) 免费(pBuffer); } //获取包含的字符串资源的提供程序DLL //类别字符串、事件消息字符串和参数插入字符串。 //对于本例,DLL的路径是硬编码的,但通常

Windows 7 如果(hEventLog) 关闭事件日志(hEventLog); if(pBuffer) 免费(pBuffer); } //获取包含的字符串资源的提供程序DLL //类别字符串、事件消息字符串和参数插入字符串。 //对于本例,DLL的路径是硬编码的,但通常,windows-7,message,extract,event-log,Windows 7,Message,Extract,Event Log,如果(hEventLog) 关闭事件日志(hEventLog); if(pBuffer) 免费(pBuffer); } //获取包含的字符串资源的提供程序DLL //类别字符串、事件消息字符串和参数插入字符串。 //对于本例,DLL的路径是硬编码的,但通常, //您将读取CategoryMessageFile、EventMessageFile和 //位于源注册表项下的ParameterMessageFile注册表值 //在中的\SYSTEM\CurrentControlSet\Services\

如果(hEventLog) 关闭事件日志(hEventLog); if(pBuffer) 免费(pBuffer); } //获取包含的字符串资源的提供程序DLL //类别字符串、事件消息字符串和参数插入字符串。 //对于本例,DLL的路径是硬编码的,但通常, //您将读取CategoryMessageFile、EventMessageFile和 //位于源注册表项下的ParameterMessageFile注册表值 //在中的\SYSTEM\CurrentControlSet\Services\Eventlog\Application下 //HKLM注册表配置单元。在本例中,所有资源都包含在 //同一个资源只有DLL。 句柄GetMessageResources() { 句柄hResources=NULL; hResources=LoadLibraryEx(RESOURCE_DLL,NULL,将_LIBRARY_加载为_IMAGE_RESOURCE |将_LIBRARY_加载为_数据文件); if(NULL==hResources) { wprintf(L“LoadLibrary失败,错误为%lu。\n”,GetLastError()); } 返回资源; } //循环遍历缓冲区并打印每条记录的内容 //在缓冲区中。 DWORD DumpRecordsInBuffer(PBYTE pBuffer,DWORD dwBytesRead) { DWORD状态=错误\成功; PBYTE-pRecord=pBuffer; PBYTE pEndOfRecords=pBuffer+dwBytesRead; LPWSTR pMessage=NULL; LPWSTR pFinalMessage=NULL; WCHAR时间戳[最大时间戳]; while(预编码<待记录) { //如果事件是由我们的提供者编写的,请编写事件的内容。 if(0==wcscmp(提供者名称,(LPWSTR)(预编码+sizeof(事件日志记录))) { GetTimestamp(((PEVENTLOGRECORD)pRecord)->TimeGenerated,TimeStamp); wprintf(L“时间戳:%s\n”,时间戳); wprintf(L“记录编号:%lu\n”,((PEVENTLOGRECORD)pRecord)->记录编号); wprintf(L“状态代码:%d\n”,((PEVENTLOGRECORD)pRecord)->EventID&0xFFFF); wprintf(L“事件类型:%s\n”,pEventTypeNames[GetEventTypeName(((PEVENTLOGRECORD)pRecord)->EventType)]; pMessage=GetMessageString(((PEVENTLOGRECORD)pRecord)->EventCategory,0,NULL); if(pMessage) { wprintf(L“事件类别:%s”,pMessage); 本地免费(pMessage); pMessage=NULL; } pMessage=GetMessageString(((PEVENTLOGRECORD)pRecord)->EventID, ((PEVENTLOGRECORD)pRecord)->NumStrings,(LPWSTR)(pRecord+((PEVENTLOGRECORD)pRecord)->StringOffset)); if(pMessage) { 状态=ApplyParameterStringsToMessage(pMessage,pFinalMessage); wprintf(L“事件消息:%s”,(pFinalMessage)?pFinalMessage:pMessage); 本地免费(pMessage); pMessage=NULL; 如果(pFinalMessage) { 免费(pFinalMessage); pFinalMessage=NULL; } } //要写入事件数据,您需要知道数据的格式 //在本例中,我们知道事件数据是以null结尾的字符串。 if(((PEVENTLOGRECORD)pRecord)->DataLength>0) { wprintf(L“事件数据:%s\n”,(LPWSTR)(pRecord+((PEVENTLOGRECORD)pRecord)->DataOffset)); } wprintf(L“\n”); } pRecord+=((PEVENTLOGRECORD)pRecord)->长度; } 返回状态; } //根据获取pEventTypeNames数组的索引值 //事件类型值。 DWORD GetEventTypeName(DWORD EventType) { 德沃德指数=0; 开关(事件类型) { 案例事件日志\u错误\u类型: 指数=0; 打破 案例事件日志\警告\类型: 指数=1; 打破 案例事件日志\信息\类型: 指数=2; 打破 案例事件日志\u审核\u成功: 指数=3; 打破 案例事件日志\u审核\u失败: 指数=4; 打破 } 收益指数; } //格式化指定的消息。如果消息使用insert,则生成 //要传递给FormatMessage的参数列表。 LPWSTR GetMessageString(DWORD消息ID、DWORD argc、LPWSTR argv) { LPWSTR pMessage=NULL; DWORD dwFormatFlags=来自系统的格式化消息|来自模块的格式化消息|分配缓冲区的格式化消息|; DWORD_PTR*pArgs=NULL; LPWSTR pString=argv; //附加到事件记录末尾的插入字符串 //是字符串数组;但是,FormatMessage需要 //地址数组。根据创建DWORD_PTR数组 //字符串的计数。指定每个字符串的地址 //到数组中的元素(保持相同的顺序)。 如果(argc>0) { pArgs=(DWORD_PTR*)malloc(sizeof(DWORD_PTR)*argc); if(pArgs) { dwFormatFlags |=格式_消息_参数_数组; 对于(DWORD i=0;i #include "stdafx.h" #include <windows.h> #include <stdio.h> #include <strsafe.h> #define PROVIDER_NAME L"SceCli" #define RESOURCE_DLL L"C:\\Windows\\System32\\scecli.dll" #define MESSAGE_LANGUAGE 0x0409 // En-Us #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 = 0; DWORD dwBytesRead = 0; DWORD dwMinimumBytesToRead = 0; 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, 0, 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); } } getchar(); 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 (0 == 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, 0, 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 > 0) { 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 = 0; switch (EventType) { case EVENTLOG_ERROR_TYPE: index = 0; break; case EVENTLOG_WARNING_TYPE: index = 1; break; case EVENTLOG_INFORMATION_TYPE: index = 2; break; case EVENTLOG_AUDIT_SUCCESS: index = 3; break; case EVENTLOG_AUDIT_FAILURE: index = 4; 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 > 0) { pArgs = (DWORD_PTR*)malloc(sizeof(DWORD_PTR) * argc); if (pArgs) { dwFormatFlags |= FORMAT_MESSAGE_ARGUMENT_ARRAY; for (DWORD i = 0; i < argc; i++) { pArgs[i] = (DWORD_PTR)pString; pString += wcslen(pString) + 1; } } else { dwFormatFlags |= FORMAT_MESSAGE_IGNORE_INSERTS; wprintf(L"Failed to allocate memory for the insert string array.\n"); } } if (!FormatMessage(dwFormatFlags, g_hResources, MessageId, MESSAGE_LANGUAGE, (LPWSTR)&pMessage, 0, (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 = 0; // Number of insertion strings found in pMessage size_t cbBuffer = 0; // Size of the buffer in bytes size_t cchBuffer = 0; // Size of the buffer in characters size_t cchParameters = 0; // Number of characters in all the parameter strings size_t cch = 0; DWORD i = 0; 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 (0 == 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+1))) { 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 = 0; i < dwParameterCount; i++) { pParameters[i] = GetMessageString(pParameterIDs[i], 0, 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 + 1) * 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 = 0; 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 = 0; 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 = 0; ULONGLONG SecsTo1970 = 116444736000000000; SYSTEMTIME st; FILETIME ft, ftLocal; ullTimeStamp = Int32x32To64(Time, 10000000) + SecsTo1970; ft.dwHighDateTime = (DWORD)((ullTimeStamp >> 32) & 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); }