I have written a programme that reads Windows ETW data from an ETL file produced by the netsh trace utility. I'm using standard Windows Event Tracing libraries to do this which require that I do some initial setup work, register a callback function (using PEVENT_RECORD_CALLBACK) and then call a function called ProcessTrace(...).
This worked fine as static functions but, for a few reasons, I needed to move the code into a netsh reader class (NetshReader). I'm having problems defining the callback function. If I run the example code below I get an Access Violation as soon as the ProcessTrace(...) function is called.
I suspect the problem is that the callback function must be static, but I thought I would check with wiser heads.
Can I define the ProcessTrace(...) callback as a member function?
Thanks in advance...Paul
#pragma once
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <evntrace.h>
#include <tdh.h>
#pragma comment(lib, "tdh.lib")
using namespace std;
class NetshReader
{
public:
void processNetshTrace();
void WINAPI processFirstPass(PEVENT_RECORD pEvent);
};
void WINAPI NetshReader::processFirstPass(PEVENT_RECORD pEvent)
{
std::wcout << "In callback function" << std::endl;
}
void NetshReader::processNetshTrace()
{
std::wstring stemp = L"C:\\traces\\a7-netsh.etl";
EVENT_TRACE_LOGFILE trace;
TRACE_LOGFILE_HEADER* pHeader = &trace.LogfileHeader;
TRACEHANDLE g_hTrace = 0; // Handle to the trace file that you opened.
ZeroMemory(&trace, sizeof(EVENT_TRACE_LOGFILE));
trace.LogFileName = &stemp[0];
trace.EventRecordCallback = (PEVENT_RECORD_CALLBACK)(&NetshReader::processFirstPass, this);
trace.ProcessTraceMode = PROCESS_TRACE_MODE_EVENT_RECORD;
g_hTrace = OpenTrace(&trace);
if (INVALID_PROCESSTRACE_HANDLE == g_hTrace)
std::wcout << "OpenTrace failed" << std::endl;
ProcessTrace(&g_hTrace, 1, 0, 0); // <<=== Access violation here because tries to
// callback to NetshReader object address
// (i.e. "this")
}
int wmain(int argc, wchar_t** argv)
{
NetshReader* rdr = new NetshReader();
rdr->processNetshTrace();
return(0);
}
The ETL file I have been using for testing is here: https://a7pub.s3-eu-west-1.amazonaws.com/a7-netsh.etl