Спрашивающий
Opening a Trace Session and Processing Events

Вопрос
-
Есть класс, предназначенный для чтения лог-файла или в режимер реального времени.
Не могу понять, как можно из callback функции CTraceReaderData::OnEventCallback получить указатель на свой класс CTraceReaderData.?
Callback функция static, поэтому невозможно работать с членами класса за неимением this, a данных, которые я получаю через параметр, явно недостаточно. Также я не нашел чтобы можно было передавать в функцию ::OpenTrace() мой контекст выполнения.
Код класса привожу ниже (не полностью, но идею понять можно)
//*************************************************************************************
//
// Types
//
//*************************************************************************************
#pragma pack( push, 1 )
typedef struct {
LONG EventCode;
WCHAR Message[1];
} EVENT_DATA, *PEVENT_DATA;
#pragma pack( pop )//*************************************************************************************
//
// CTraceReaderData
//
//*************************************************************************************
class RTSTDAPI CTraceReaderData : private EVENT_TRACE_LOGFILE, public CThread
{
CTraceReaderData(CTraceReader *pOwner);
public:
~CTraceReaderData();// Creation / Destruction
static CTraceReaderData *CreateLogFile(CTraceReader *pOwner, LPCTSTR lpszLogFile);
static CTraceReaderData *CreateRealtime(CTraceReader *pOwner, LPCTSTR lpszLoggerName);
static void Destroy(CTraceReaderData *pData);// Calback Functions
static ULONG WINAPI OnBufferCallback(IN PEVENT_TRACE_LOGFILE pBuffer);
static VOID WINAPI OnEventCallback (IN PEVENT_TRACE pEvent);friend class CTraceReader;
private:
// Realtime processing function
virtual UINT DoExecuteThread();public:
TRACEHANDLE m_Loghandle;
BOOL m_bProcessing;
LPTSTR m_LoggerName;
ULONG m_TotalBuffersRead;CTraceReader *m_pOwner;
};//*************************************************************************************
//
// CTraceReader
//
//*************************************************************************************
CTraceReader::CTraceReader()
: m_pData(NULL)
{
}CTraceReader::~CTraceReader()
{
Close();
}ULONG CTraceReader::OpenLogFile(LPCTSTR lpszLogFile)
{
ULONG lResult;
if( NULL != m_pData ) {
_RPT0(_CRT_WARN, "Trace reader already open!\n");
return ERROR_ALREADY_INITIALIZED;
}
m_pData = CTraceReaderData::CreateLogFile( this, lpszLogFile );
if( NULL == m_pData ) {
return ERROR_OUTOFMEMORY;
}m_pData->m_Loghandle =::OpenTrace( m_pData );
if( NULL == m_pData->m_Loghandle ) {
lResult = GetLastError();
_RPT1( _CRT_WARN, "Error Opening Trace with status=%d\n", lResult );
return lResult;
}return ERROR_SUCCESS;
}ULONG CTraceReader::OpenRealtime(LPCTSTR lpLoggerName)
{
ULONG lResult;
if( NULL != m_pData ) {
_RPT0(_CRT_WARN, "Trace reader already open!\n");
return ERROR_ALREADY_INITIALIZED;
}
m_pData = CTraceReaderData::CreateRealtime( this, lpLoggerName );
if( NULL == m_pData ) {
return ERROR_OUTOFMEMORY;
}m_pData->m_Loghandle =::OpenTrace( m_pData );
if( NULL == m_pData->m_Loghandle ) {
lResult = GetLastError();
_RPT1( _CRT_WARN, "Error Opening Trace with status=%d\n", lResult );
return lResult;
}return ERROR_SUCCESS;
}ULONG CTraceReader::Process()
{
ULONG lResult;
if( NULL == m_pData ) {
_RPT0( _CRT_WARN, "Trace is not open!\n" );
return ERROR_SUCCESS;
}
if( m_pData->m_bProcessing ) {
return ERROR_SUCCESS;
}lResult = m_pData->CThread::StartThread();
if( lResult != ERROR_SUCCESS ) {
_RPT1( _CRT_WARN, "Error starting processing thread with status=%d\n", lResult );
return lResult;
}m_pData->m_bProcessing = TRUE;
return ERROR_SUCCESS;
}
ULONG CTraceReader::Close()
{
ULONG lResult;
if( NULL == m_pData ) {
_RPT0(_CRT_WARN, "Trace is not open!\n");
return ERROR_SUCCESS;
}if( m_pData->m_Loghandle != 0 ) {
lResult =::CloseTrace( m_pData->m_Loghandle );if( lResult != ERROR_SUCCESS ) {
_RPT1( _CRT_WARN, "Error closing with status=%d\n", lResult );
return lResult;
}
}CTraceReaderData::Destroy( m_pData );
m_pData = NULL;return ERROR_SUCCESS;
}//*************************************************************************************
//
// CTraceReaderData
//
//*************************************************************************************
CTraceReaderData::CTraceReaderData(CTraceReader *pOwner)
: m_pOwner(pOwner)
, m_Loghandle(0)
, m_TotalBuffersRead(0)
, m_LoggerName(NULL)
, m_bProcessing(FALSE)
{
ZeroMemory(static_cast<PEVENT_TRACE_LOGFILE>(this), sizeof(EVENT_TRACE_LOGFILE));
}CTraceReaderData::~CTraceReaderData()
{
CHeapAllocT< TCHAR >::Free(LogFileName);
CHeapAllocT< TCHAR >::Free(LoggerName);
}CTraceReaderData *CTraceReaderData::CreateLogFile(CTraceReader *pOwner, LPCTSTR lpszLogFile)
{
CTraceReaderData *pData= new CTraceReaderData(pOwner);
if( NULL == pData )
return NULL;pData->LogFileName = CHeapAllocT< TCHAR >::Alloc( MAXSTR,TRUE );
if( NULL == pData->LogFileName ) {
delete pData;
return NULL;
}StringCchCopy( pData->LogFileName, MAXSTR, lpszLogFile );
pData->BufferCallback = CTraceReaderData::OnBufferCallback;
pData->EventCallback = CTraceReaderData::OnEventCallback;return pData;
}
CTraceReaderData *CTraceReaderData::CreateRealtime(CTraceReader *pOwner, LPCTSTR lpszLoggerName)
{
CTraceReaderData *pData= new CTraceReaderData( pOwner );
if( NULL == pData )
return NULL;pData->LoggerName = CHeapAllocT< TCHAR >::Alloc( MAXSTR,TRUE );
if( NULL == pData->LoggerName ) {
delete pData;
return NULL;
}StringCchCopy( pData->LoggerName, MAXSTR, lpszLoggerName );
pData->ProcessTraceMode = EVENT_TRACE_REAL_TIME_MODE;pData->BufferCallback = CTraceReaderData::OnBufferCallback;
pData->EventCallback = CTraceReaderData::OnEventCallback;return pData;
}
void CTraceReaderData::Destroy(CTraceReaderData *pData)
{
delete pData;
}UINT CTraceReaderData::DoExecuteThread()
{
ULONG lResult;// Actual processing takes place here. EventCallback function will be invoked
// for each event.
lResult =::ProcessTrace( &m_Loghandle, 1, NULL, NULL );m_bProcessing = FALSE;
if( lResult != ERROR_SUCCESS &&
lResult != ERROR_CANCELLED ) {
_RPT1( _CRT_WARN, "Error processing with status=%d\n", lResult );
return lResult;
}return 0;
}ULONG WINAPI CTraceReaderData::OnBufferCallback(PEVENT_TRACE_LOGFILE pBuffer)
{
return TRUE;}
VOID WINAPI CTraceReaderData::OnEventCallback(PEVENT_TRACE pEvent)
{
PEVENT_TRACE_HEADER pHeader;
pHeader = (PEVENT_TRACE_HEADER) &pEvent->Header;
// Extrace log file information if the event is a log file header.
if( IsEqualGUID( pHeader->Guid, EventTraceGuid ) &&
pEvent->Header.Class.Type == EVENT_TRACE_TYPE_INFO ) {PTRACE_LOGFILE_HEADER pLogfile = (PTRACE_LOGFILE_HEADER)pEvent->MofData;
if ( NULL != pLogfile ) {FILETIME ftStart = {
pLogfile->StartTime.LowPart,
pLogfile->StartTime.HighPart
},
ftEnd = {
pLogfile->EndTime.LowPart,
pLogfile->EndTime.HighPart
};
SYSTEMTIME stStart,stEnd;
FileTimeToSystemTime(&ftStart,&stStart);
FileTimeToSystemTime(&ftEnd, &stEnd);LPCTSTR lpLoggerName;
lpLoggerName = (LPCTSTR)((BYTE*)pEvent->MofData + sizeof(TRACE_LOGFILE_HEADER));}
return;
}PEVENT_DATA pEventData = (PEVENT_DATA) pEvent->MofData;
FILETIME ftStamp = {
pHeader->TimeStamp.LowPart,
pHeader->TimeStamp.HighPart,
};
SYSTEMTIME stStamp;
FileTimeToSystemTime(&ftStamp,&stStamp);CTraceEvent traceEvent( &stStamp,
pHeader->Guid,
(TRACELEVEL) pHeader->Class.Level,
(TRACEEVENT) pHeader->Class.Type,
pHeader->ProcessId,
pHeader->ThreadId,
pEventData->EventCode,
pEventData->Message );}
- Перемещено Tagore Bandlamudi 2 октября 2010 г. 21:11 MSDN Forums consolidation (От:Разработка Windows-приложений)
29 сентября 2010 г. 16:57