none
Opening a Trace Session and Processing Events RRS feed

  • Вопрос

  • Есть класс, предназначенный для чтения лог-файла или в режимер реального времени.

    Не могу понять, как можно из 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