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
