Peristiwa Penyajian
Untuk menampilkan peristiwa, Anda harus memanggil fungsi EvtRender untuk merendernya dalam bentuk yang dapat ditampilkan. Anda dapat merender peristiwa sebagai string XML atau Anda dapat merender satu atau beberapa nilai dari peristiwa tersebut. Peristiwa juga dapat berisi string pesan (misalnya, string pesan peristiwa, string pesan saluran, atau string pesan penyedia). Untuk mendapatkan salah satu string pesan dari peristiwa, panggil fungsi EvtFormatMessage . Untuk detail selengkapnya tentang mendapatkan string pesan dari peristiwa, lihat Memformat Pesan Peristiwa.
Untuk merender peristiwa sebagai string XML, panggil fungsi EvtRender . Namun, jika Anda ingin merender bagian tertentu dari peristiwa, Anda harus terlebih dahulu memanggil EvtCreateRenderContext untuk menentukan potongan peristiwa yang ingin Anda render. Anda dapat merender nilai tertentu dari peristiwa, nilai dari data pengguna atau bagian data peristiwa dari peristiwa, atau nilai dari properti peristiwa terkait sistem. Untuk detail tentang komponen peristiwa, lihat Skema Peristiwa.
Contoh berikut menunjukkan cara merender peristiwa sebagai string XML.
DWORD PrintEvent(EVT_HANDLE hEvent)
{
DWORD status = ERROR_SUCCESS;
DWORD dwBufferSize = 0;
DWORD dwBufferUsed = 0;
DWORD dwPropertyCount = 0;
LPWSTR pRenderedContent = NULL;
// The EvtRenderEventXml flag tells EvtRender to render the event as an XML string.
if (!EvtRender(NULL, hEvent, EvtRenderEventXml, dwBufferSize, pRenderedContent, &dwBufferUsed, &dwPropertyCount))
{
if (ERROR_INSUFFICIENT_BUFFER == (status = GetLastError()))
{
dwBufferSize = dwBufferUsed;
pRenderedContent = (LPWSTR)malloc(dwBufferSize);
if (pRenderedContent)
{
EvtRender(NULL, hEvent, EvtRenderEventXml, dwBufferSize, pRenderedContent, &dwBufferUsed, &dwPropertyCount);
}
else
{
wprintf(L"malloc failed\n");
status = ERROR_OUTOFMEMORY;
goto cleanup;
}
}
if (ERROR_SUCCESS != (status = GetLastError()))
{
wprintf(L"EvtRender failed with %d\n", GetLastError());
goto cleanup;
}
}
wprintf(L"\n\n%s", pRenderedContent);
cleanup:
if (pRenderedContent)
free(pRenderedContent);
return status;
}
Contoh berikut menunjukkan cara merender nilai properti dari bagian sistem peristiwa. Untuk merender data pengguna atau properti data kejadian, ganti bendera EvtRenderContextSystem dengan bendera EvtRenderContextUser saat membuat konteks penyajian.
DWORD PrintEventSystemData(EVT_HANDLE hEvent)
{
DWORD status = ERROR_SUCCESS;
EVT_HANDLE hContext = NULL;
DWORD dwBufferSize = 0;
DWORD dwBufferUsed = 0;
DWORD dwPropertyCount = 0;
PEVT_VARIANT pRenderedValues = NULL;
WCHAR wsGuid[50];
LPWSTR pwsSid = NULL;
ULONGLONG ullTimeStamp = 0;
ULONGLONG ullNanoseconds = 0;
SYSTEMTIME st;
FILETIME ft;
// Identify the components of the event that you want to render. In this case,
// render the system section of the event.
hContext = EvtCreateRenderContext(0, NULL, EvtRenderContextSystem);
if (NULL == hContext)
{
wprintf(L"EvtCreateRenderContext failed with %lu\n", status = GetLastError());
goto cleanup;
}
// When you render the user data or system section of the event, you must specify
// the EvtRenderEventValues flag. The function returns an array of variant values
// for each element in the user data or system section of the event. For user data
// or event data, the values are returned in the same order as the elements are
// defined in the event. For system data, the values are returned in the order defined
// in the EVT_SYSTEM_PROPERTY_ID enumeration.
if (!EvtRender(hContext, hEvent, EvtRenderEventValues, dwBufferSize, pRenderedValues, &dwBufferUsed, &dwPropertyCount))
{
if (ERROR_INSUFFICIENT_BUFFER == (status = GetLastError()))
{
dwBufferSize = dwBufferUsed;
pRenderedValues = (PEVT_VARIANT)malloc(dwBufferSize);
if (pRenderedValues)
{
EvtRender(hContext, hEvent, EvtRenderEventValues, dwBufferSize, pRenderedValues, &dwBufferUsed, &dwPropertyCount);
}
else
{
wprintf(L"malloc failed\n");
status = ERROR_OUTOFMEMORY;
goto cleanup;
}
}
if (ERROR_SUCCESS != (status = GetLastError()))
{
wprintf(L"EvtRender failed with %d\n", GetLastError());
goto cleanup;
}
}
// Print the values from the System section of the element.
wprintf(L"Provider Name: %s\n", pRenderedValues[EvtSystemProviderName].StringVal);
if (NULL != pRenderedValues[EvtSystemProviderGuid].GuidVal)
{
StringFromGUID2(*(pRenderedValues[EvtSystemProviderGuid].GuidVal), wsGuid, sizeof(wsGuid)/sizeof(WCHAR));
wprintf(L"Provider Guid: %s\n", wsGuid);
}
else
{
wprintf(L"Provider Guid: NULL");
}
DWORD EventID = pRenderedValues[EvtSystemEventID].UInt16Val;
if (EvtVarTypeNull != pRenderedValues[EvtSystemQualifiers].Type)
{
EventID = MAKELONG(pRenderedValues[EvtSystemEventID].UInt16Val, pRenderedValues[EvtSystemQualifiers].UInt16Val);
}
wprintf(L"EventID: %lu\n", EventID);
wprintf(L"Version: %u\n", (EvtVarTypeNull == pRenderedValues[EvtSystemVersion].Type) ? 0 : pRenderedValues[EvtSystemVersion].ByteVal);
wprintf(L"Level: %u\n", (EvtVarTypeNull == pRenderedValues[EvtSystemLevel].Type) ? 0 : pRenderedValues[EvtSystemLevel].ByteVal);
wprintf(L"Task: %hu\n", (EvtVarTypeNull == pRenderedValues[EvtSystemTask].Type) ? 0 : pRenderedValues[EvtSystemTask].UInt16Val);
wprintf(L"Opcode: %u\n", (EvtVarTypeNull == pRenderedValues[EvtSystemOpcode].Type) ? 0 : pRenderedValues[EvtSystemOpcode].ByteVal);
wprintf(L"Keywords: 0x%I64x\n", pRenderedValues[EvtSystemKeywords].UInt64Val);
ullTimeStamp = pRenderedValues[EvtSystemTimeCreated].FileTimeVal;
ft.dwHighDateTime = (DWORD)((ullTimeStamp >> 32) & 0xFFFFFFFF);
ft.dwLowDateTime = (DWORD)(ullTimeStamp & 0xFFFFFFFF);
FileTimeToSystemTime(&ft, &st);
ullNanoseconds = (ullTimeStamp % 10000000) * 100; // Display nanoseconds instead of milliseconds for higher resolution
wprintf(L"TimeCreated SystemTime: %02d/%02d/%02d %02d:%02d:%02d.%I64u)\n",
st.wMonth, st.wDay, st.wYear, st.wHour, st.wMinute, st.wSecond, ullNanoseconds);
wprintf(L"EventRecordID: %I64u\n", pRenderedValues[EvtSystemEventRecordId].UInt64Val);
if (EvtVarTypeNull != pRenderedValues[EvtSystemActivityID].Type)
{
StringFromGUID2(*(pRenderedValues[EvtSystemActivityID].GuidVal), wsGuid, sizeof(wsGuid)/sizeof(WCHAR));
wprintf(L"Correlation ActivityID: %s\n", wsGuid);
}
if (EvtVarTypeNull != pRenderedValues[EvtSystemRelatedActivityID].Type)
{
StringFromGUID2(*(pRenderedValues[EvtSystemRelatedActivityID].GuidVal), wsGuid, sizeof(wsGuid)/sizeof(WCHAR));
wprintf(L"Correlation RelatedActivityID: %s\n", wsGuid);
}
wprintf(L"Execution ProcessID: %lu\n", pRenderedValues[EvtSystemProcessID].UInt32Val);
wprintf(L"Execution ThreadID: %lu\n", pRenderedValues[EvtSystemThreadID].UInt32Val);
wprintf(L"Channel: %s\n", (EvtVarTypeNull == pRenderedValues[EvtSystemChannel].Type) ? L"" : pRenderedValues[EvtSystemChannel].StringVal);
wprintf(L"Computer: %s\n", pRenderedValues[EvtSystemComputer].StringVal);
if (EvtVarTypeNull != pRenderedValues[EvtSystemUserID].Type)
{
if (ConvertSidToStringSid(pRenderedValues[EvtSystemUserID].SidVal, &pwsSid))
{
wprintf(L"Security UserID: %s\n", pwsSid);
LocalFree(pwsSid);
}
}
cleanup:
if (hContext)
EvtClose(hContext);
if (pRenderedValues)
free(pRenderedValues);
return status;
}
Contoh berikut menunjukkan cara merender nilai tertentu dari peristiwa. Gunakan ekspresi JalurX untuk menentukan simpul atau atribut tertentu untuk diambil. Anda dapat menentukan satu atau beberapa ekspresi untuk mengambil satu atau beberapa nilai.
DWORD PrintEventValues(EVT_HANDLE hEvent)
{
DWORD status = ERROR_SUCCESS;
EVT_HANDLE hContext = NULL;
DWORD dwBufferSize = 0;
DWORD dwBufferUsed = 0;
DWORD dwPropertyCount = 0;
PEVT_VARIANT pRenderedValues = NULL;
LPWSTR ppValues[] = {L"Event/System/Provider/@Name", L"Event/System/Channel"};
DWORD count = sizeof(ppValues)/sizeof(LPWSTR);
// Identify the components of the event that you want to render. In this case,
// render the provider's name and channel from the system section of the event.
// To get user data from the event, you can specify an expression such as
// L"Event/EventData/Data[@Name=\"<data name goes here>\"]".
hContext = EvtCreateRenderContext(count, (LPCWSTR*)ppValues, EvtRenderContextValues);
if (NULL == hContext)
{
wprintf(L"EvtCreateRenderContext failed with %lu\n", status = GetLastError());
goto cleanup;
}
// The function returns an array of variant values for each element or attribute that
// you want to retrieve from the event. The values are returned in the same order as
// you requested them.
if (!EvtRender(hContext, hEvent, EvtRenderEventValues, dwBufferSize, pRenderedValues, &dwBufferUsed, &dwPropertyCount))
{
if (ERROR_INSUFFICIENT_BUFFER == (status = GetLastError()))
{
dwBufferSize = dwBufferUsed;
pRenderedValues = (PEVT_VARIANT)malloc(dwBufferSize);
if (pRenderedValues)
{
EvtRender(hContext, hEvent, EvtRenderEventValues, dwBufferSize, pRenderedValues, &dwBufferUsed, &dwPropertyCount);
}
else
{
wprintf(L"malloc failed\n");
status = ERROR_OUTOFMEMORY;
goto cleanup;
}
}
if (ERROR_SUCCESS != (status = GetLastError()))
{
wprintf(L"EvtRender failed with %d\n", GetLastError());
goto cleanup;
}
}
// Print the selected values.
wprintf(L"\nProvider Name: %s\n", pRenderedValues[0].StringVal);
wprintf(L"Channel: %s\n", (EvtVarTypeNull == pRenderedValues[1].Type) ? L"" : pRenderedValues[1].StringVal);
cleanup:
if (hContext)
EvtClose(hContext);
if (pRenderedValues)
free(pRenderedValues);
return status;
}