I want to create a program that will trace event logs from the provider "Microsoft-Windows-RPC".
The program logman.exe
by Microsoft is doing it like that:
logman start RPC_ONLY -p Microsoft-Windows-RPC -ets
When done, you can capture the logs like that:
tracerpt RPC_ONLY.etl -o RPC_ONLY.evtx -of EVTX
logman stop RPC_ONLY -ets
I want my program to be able to trace it like logman
does but I didn't understand how.
Is there a function that I can "tell" windows that I want it to start tracing events related to Microsoft-Windows-RPC
?
According to Example that Creates a Session and Enables a Manifest-based or Classic Provider, I have traced Microsoft-Windows-RPC
events successfully with some changes. With log.etl
, you can then Retrieve Event Data.
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <strsafe.h>
#include <wmistr.h>
#include <evntrace.h>
#define LOGFILE_PATH L"C:\\log.etl"
#define LOGSESSION_NAME L"My Event Trace Session"
// GUID that identifies your trace session.
// Remember to create your own session GUID.
// {AE44CB98-BD11-4069-8093-770EC9258A12}
//static const GUID SessionGuid = { 0xae44cb98, 0xbd11, 0x4069, { 0x80, 0x93, 0x77, 0xe, 0xc9, 0x25, 0x8a, 0x12 } };
// GUID that identifies the provider that you want
// to enable to your session.
// {D8909C24-5BE9-4502-98CA-AB7BDC24899D}
/*
name: Microsoft-Windows-RPC
guid: 6ad52b32-d609-4be9-ae07-ce8dae937e39
*/
static const GUID ProviderGuid =
{ 0x6ad52b32, 0xd609, 0x4be9, {0xae, 0x07, 0xce, 0x8d, 0xae, 0x93, 0x7e, 0x39 } };
void wmain(void)
{
ULONG status = ERROR_SUCCESS;
TRACEHANDLE SessionHandle = 0;
EVENT_TRACE_PROPERTIES* pSessionProperties = NULL;
ULONG BufferSize = 0;
BOOL TraceOn = TRUE;
// Allocate memory for the session properties. The memory must
// be large enough to include the log file name and session name,
// which get appended to the end of the session properties structure.
BufferSize = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(LOGFILE_PATH) + sizeof(LOGSESSION_NAME);
pSessionProperties = (EVENT_TRACE_PROPERTIES*)malloc(BufferSize);
if (NULL == pSessionProperties)
{
wprintf(L"Unable to allocate %d bytes for properties structure.\n", BufferSize);
goto cleanup;
}
// Set the session properties. You only append the log file name
// to the properties structure; the StartTrace function appends
// the session name for you.
ZeroMemory(pSessionProperties, BufferSize);
pSessionProperties->Wnode.BufferSize = BufferSize;
pSessionProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
pSessionProperties->Wnode.ClientContext = 1; //QPC clock resolution
//pSessionProperties->Wnode.Guid = SessionGuid;
pSessionProperties->Wnode.Guid = {};
pSessionProperties->LogFileMode = EVENT_TRACE_FILE_MODE_SEQUENTIAL;
pSessionProperties->MaximumFileSize = 1; // 1 MB
pSessionProperties->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
pSessionProperties->LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(LOGSESSION_NAME);
StringCbCopy((LPWSTR)((char*)pSessionProperties + pSessionProperties->LogFileNameOffset), sizeof(LOGFILE_PATH), LOGFILE_PATH);
// Create the trace session.
status = StartTrace((PTRACEHANDLE)&SessionHandle, LOGSESSION_NAME, pSessionProperties);
if (ERROR_SUCCESS != status)
{
wprintf(L"StartTrace() failed with %lu\n", status);
goto cleanup;
}
// Enable the providers that you want to log events to your session.
status = EnableTraceEx2(
SessionHandle,
(LPCGUID)&ProviderGuid,
EVENT_CONTROL_CODE_ENABLE_PROVIDER,
TRACE_LEVEL_INFORMATION,
0,
0,
0,
NULL
);
if (ERROR_SUCCESS != status)
{
wprintf(L"EnableTrace() failed with %lu\n", status);
TraceOn = FALSE;
goto cleanup;
}
wprintf(L"Run the provider application. Then hit any key to stop the session.\n");
_getch();
cleanup:
if (SessionHandle)
{
if (TraceOn)
{
status = EnableTraceEx2(
SessionHandle,
(LPCGUID)&ProviderGuid,
EVENT_CONTROL_CODE_DISABLE_PROVIDER,
TRACE_LEVEL_INFORMATION,
0,
0,
0,
NULL
);
}
status = ControlTrace(SessionHandle, LOGSESSION_NAME, pSessionProperties, EVENT_TRACE_CONTROL_STOP);
if (ERROR_SUCCESS != status)
{
wprintf(L"ControlTrace(stop) failed with %lu\n", status);
}
}
if (pSessionProperties)
{
free(pSessionProperties);
pSessionProperties = NULL;
}
}