Skip to content

Instantly share code, notes, and snippets.

@mattpodwysocki
Last active July 13, 2016 21:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattpodwysocki/f2c9b0870b158f448526f416aa2f74ad to your computer and use it in GitHub Desktop.
Save mattpodwysocki/f2c9b0870b158f448526f416aa2f74ad to your computer and use it in GitHub Desktop.
// ConsoleApplication1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <Windows.h>
#include <Evntrace.h>
#pragma once
struct ITraceConsumer {
virtual void OnEventRecord(PEVENT_RECORD eventPointer) = 0;
};
class TraceSession
{
public:
TraceSession(LPCTSTR szSessionName);
~TraceSession();
public:
bool Start();
bool EnableProvider(const GUID& providerId, UCHAR level, ULONGLONG anyKeyword = 0, ULONGLONG allKeyword = 0);
bool OpenTrace(ITraceConsumer *pConsumer);
bool Process();
bool CloseTrace();
bool DisableProvider(const GUID& providerId);
bool Stop();
ULONG Status() const;
LONGLONG PerfFreq() const;
private:
LPTSTR _szSessionName;
ULONG _status;
EVENT_TRACE_PROPERTIES* _pSessionProperties;
TRACEHANDLE hSession;
EVENT_TRACE_LOGFILE _logFile;
TRACEHANDLE _hTrace;
};
TraceSession::TraceSession(LPCTSTR szSessionName) : _szSessionName(_tcsdup(szSessionName))
{
}
TraceSession::~TraceSession(void)
{
delete[]_szSessionName;
delete _pSessionProperties;
}
bool TraceSession::Start()
{
if (!_pSessionProperties) {
const size_t buffSize = sizeof(EVENT_TRACE_PROPERTIES) + (_tcslen(_szSessionName) + 1) * sizeof(TCHAR);
_pSessionProperties = reinterpret_cast<EVENT_TRACE_PROPERTIES *>(malloc(buffSize));
ZeroMemory(_pSessionProperties, buffSize);
_pSessionProperties->Wnode.BufferSize = buffSize;
_pSessionProperties->Wnode.ClientContext = 1;
_pSessionProperties->LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
_pSessionProperties->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
}
// Create the trace session.
_status = StartTrace(&hSession, _szSessionName, _pSessionProperties);
return (_status == ERROR_SUCCESS);
}
bool TraceSession::EnableProvider(const GUID& providerId, UCHAR level, ULONGLONG anyKeyword, ULONGLONG allKeyword)
{
_status = EnableTraceEx2(hSession, &providerId, EVENT_CONTROL_CODE_ENABLE_PROVIDER, level, anyKeyword, allKeyword, 0, NULL);
return (_status == ERROR_SUCCESS);
}
VOID WINAPI EventRecordCallback(_In_ PEVENT_RECORD pEventRecord)
{
reinterpret_cast<ITraceConsumer *>(pEventRecord->UserContext)->OnEventRecord(pEventRecord);
}
bool TraceSession::OpenTrace(ITraceConsumer *pConsumer)
{
if (!pConsumer)
return false;
ZeroMemory(&_logFile, sizeof(EVENT_TRACE_LOGFILE));
_logFile.LoggerName = _szSessionName;
_logFile.LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
_logFile.EventRecordCallback = &EventRecordCallback;
_logFile.Context = pConsumer;
_hTrace = ::OpenTrace(&_logFile);
return (_hTrace != 0);
}
bool TraceSession::Process()
{
_status = ProcessTrace(&_hTrace, 1, NULL, NULL);
return (_status == ERROR_SUCCESS);
}
bool TraceSession::CloseTrace()
{
_status = ::CloseTrace(_hTrace);
return (_status == ERROR_SUCCESS);
}
bool TraceSession::DisableProvider(const GUID& providerId)
{
_status = EnableTraceEx2(hSession, &providerId, EVENT_CONTROL_CODE_DISABLE_PROVIDER, 0, 0, 0, 0, NULL);
return (_status == ERROR_SUCCESS);
}
bool TraceSession::Stop()
{
_status = ControlTrace(hSession, _szSessionName, _pSessionProperties, EVENT_TRACE_CONTROL_STOP);
delete _pSessionProperties;
_pSessionProperties = NULL;
return (_status == ERROR_SUCCESS);
}
ULONG TraceSession::Status() const
{
return _status;
}
LONGLONG TraceSession::PerfFreq() const
{
return _logFile.LogfileHeader.PerfFreq.QuadPart;
}
int main()
{
GUID nodeGuid;
LPTSTR szSessionName = L"SampleTracer";
ZeroMemory(&nodeGuid, sizeof(GUID));
if (IIDFromString(L"{77754E9B-264B-4D8D-B981-E4135C1ECB0C}", &nodeGuid) != S_OK)
{
wprintf(L"Failed to get GUID from string");
return 1;
}
/*
const size_t buffSize = sizeof(EVENT_TRACE_PROPERTIES) + (_tcslen(szSessionName) + 1) * sizeof(TCHAR);
pSessionProperties = reinterpret_cast<EVENT_TRACE_PROPERTIES *>(malloc(buffSize));
ZeroMemory(pSessionProperties, buffSize);
pSessionProperties->Wnode.BufferSize = buffSize;
pSessionProperties->Wnode.ClientContext = 1;
pSessionProperties->LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
pSessionProperties->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
status = StartTrace(&hTrace, szSessionName, pSessionProperties);
if (status != ERROR_SUCCESS && status != ERROR_CANCELLED)
{
wprintf(L"StartTrace failed with %lu\n", status);
goto cleanup;
}
*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment