Last active
July 13, 2016 21:19
-
-
Save mattpodwysocki/f2c9b0870b158f448526f416aa2f74ad to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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