Я пытаюсь получить базовую строку в DLL с помощью EvtFormatMessage, но независимо от того, что я делаю, он не работает. Страница справки Windows показала, что вы можете использовать значения и параметры valuecount, чтобы изменить поведение по умолчанию, но при их изменении ничего не печатается.
Еще одна попытка, которую я предпринял, состояла в том, чтобы просмотреть метаданные издателей и сопоставить их с правильным идентификатором события и версией, но в EvtOpenEventMetadatEnum нет элементов, которые можно было бы перебрать для всех издателей событий. Это работает для событий изменения времени, но не для других событий.
Это код, который я должен вернуть строку сообщения. hMetadata — это метаданные издателя, а hEvent — это метаданные события.
LPWSTR GetMessageString(EVT_HANDLE hMetadata, EVT_HANDLE hEvent, EVT_FORMAT_MESSAGE_FLAGS FormatId, DWORD MsgID)
{
LPWSTR pBuffer = NULL;
DWORD dwBufferSize = 0;
DWORD dwBufferUsed = 0;
DWORD status = ERROR_SUCCESS;
if (!fpEvtFormatMessage(hMetadata, hEvent, MsgID, 0, NULL, FormatId, dwBufferSize, pBuffer, &dwBufferUsed))
{
status = GetLastError();
if (ERROR_INSUFFICIENT_BUFFER == status)
{
// An event can contain one or more keywords. The function returns keywords
// as a list of keyword strings. To process the list, you need to know the
// size of the buffer, so you know when you have read the last string, or you
// can terminate the list of strings with a second null terminator character
// as this example does.
if ((EvtFormatMessageKeyword == FormatId))
pBuffer[dwBufferSize - 1] = L'\0';
else
dwBufferSize = dwBufferUsed;
pBuffer = (LPWSTR)malloc(dwBufferSize * sizeof(WCHAR));
if (pBuffer)
{
fpEvtFormatMessage(hMetadata, hEvent, MsgID, 0, NULL, FormatId, dwBufferSize, pBuffer, &dwBufferUsed);
// Add the second null terminator character.
if ((EvtFormatMessageKeyword == FormatId))
pBuffer[dwBufferUsed - 1] = L'\0';
}
else
{
TRACE5(_T("malloc failed\n"));
}
}
else if (ERROR_EVT_MESSAGE_NOT_FOUND == status || ERROR_EVT_MESSAGE_ID_NOT_FOUND == status)
;
else
{
TRACE5(_T("EvtFormatMessage failed with %u\n"), status);
}
}
Это код, который должен соответствовать событию у меня с событием шаблона в DLL
hEvents = fpEvtOpenEventMetadataEnum(g_hMetadata, 0);
if (NULL == hEvents)
{
TRACE5(_T("EvtOpenEventMetadataEnum failed with %lu\n"), GetLastError());
goto cleanup;
}
// Enumerate the events and print each event's metadata.
while (run)
{
hEvent = fpEvtNextEventMetadata(hEvents, 0);
if (NULL == hEvent)
{
if (ERROR_NO_MORE_ITEMS != (status = GetLastError()))
{
TRACE5(_T("EvtNextEventMetadata failed with %lu\n"), status);
}
break;
}
msgId = getEventID(g_hMetadata, hEvent, &tempVersion);
if (dwMsgID == msgId && tempVersion == version) {
PEVT_VARIANT pProperty = NULL; // Contains a metadata value
PEVT_VARIANT pTemp = NULL;
DWORD dwBufferSize = 0;
DWORD dwBufferUsed = 0;
DWORD status2 = ERROR_SUCCESS;
if (!fpEvtGetEventMetadataProperty(hEvent, EventMetadataEventMessageID, 0, dwBufferSize, pProperty, &dwBufferUsed))
{
status2 = GetLastError();
if (ERROR_INSUFFICIENT_BUFFER == status2)
{
dwBufferSize = dwBufferUsed;
pTemp = (PEVT_VARIANT)realloc(pProperty, dwBufferSize);
if (pTemp)
{
pProperty = pTemp;
pTemp = NULL;
fpEvtGetEventMetadataProperty(hEvent, EventMetadataEventMessageID, 0, dwBufferSize, pProperty, &dwBufferUsed);
}
else
{
TRACE5(_T("realloc failed\n"));
status2 = ERROR_OUTOFMEMORY;
goto cleanup;
}
}
if (ERROR_SUCCESS != (status2 = GetLastError()))
{
TRACE5(_T("EvtGetEventMetadataProperty failed with %d\n"), GetLastError());
goto cleanup;
}
}
if (-1 == pProperty->UInt32Val)
{
*pStrNonExpLibMsg = "Message string: \n";
}
else
{
*pStrNonExpLibMsg = GetMessageString(g_hMetadata, NULL, EvtFormatMessageId, pProperty->UInt32Val);
if (pMessage)
{
free(pMessage);
}
}
run = false;
break;
}
fpEvtClose(hEvent);
hEvent = NULL;
}cleanup:
if (hEvents)
fpEvtClose(hEvents);
if (hEvent)
fpEvtClose(hEvent);
return status;
}
DWORD getEventID(EVT_HANDLE g_hMetadata, EVT_HANDLE hEvent, DWORD *evtVersion)
{
PEVT_VARIANT pProperty = NULL; // Contains a metadata value
PEVT_VARIANT pTemp = NULL;
DWORD dwBufferSize = 0;
DWORD dwBufferUsed = 0;
DWORD status = ERROR_SUCCESS;
DWORD retValue = NULL;
// Get the specified metadata property. If the pProperty buffer is not big enough, reallocate the buffer.
for (int i = 0; i < 2; i++)
{
if (!fpEvtGetEventMetadataProperty(hEvent, (EVT_EVENT_METADATA_PROPERTY_ID)i, 0, dwBufferSize, pProperty, &dwBufferUsed))
{
status = GetLastError();
if (ERROR_INSUFFICIENT_BUFFER == status)
{
dwBufferSize = dwBufferUsed;
pTemp = (PEVT_VARIANT)realloc(pProperty, dwBufferSize);
if (pTemp)
{
pProperty = pTemp;
pTemp = NULL;
fpEvtGetEventMetadataProperty(hEvent, (EVT_EVENT_METADATA_PROPERTY_ID)i, 0, dwBufferSize, pProperty, &dwBufferUsed);
}
else
{
TRACE5(_T("realloc failed\n"));
status = ERROR_OUTOFMEMORY;
goto cleanup;
}
}
if (ERROR_SUCCESS != (status = GetLastError()))
{
TRACE5(_T("EvtGetEventMetadataProperty failed with %d\n"), GetLastError());
goto cleanup;
}
}
if (i == 0)
{
retValue = pProperty->UInt32Val;
}
else
{
*evtVersion = pProperty->UInt32Val;
}
RtlZeroMemory(pProperty, dwBufferUsed);
}
Задача ещё не решена.
Других решений пока нет …