⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 htrace.cpp

📁 A Windows CE API Inecptor Tools
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/********************************************************************
Module : HTrace.cpp  Implementation of tracing routines.
             Written 1998-2003 by Dmitri Leman
         for an article in C/C++ journal about a tracing framework.
Purpose: Tracing framework allows inserting HTRACE and HTRACEK
  tracing statements to applications and drivers.
  Tracing messages may redirected to various output streams 
  without rebuilding the whole application.
  To enable the trace, define TRACE_ in compiler settings.
  To compile for NT kernel mode driver, add TRACER_NTDRIVER 
  definition. To compile with Java JNI support, add TRACE_JNI.
  This file was compiled using Visual C++ 6.0 for WIN32 and NT
  kernel mode, 
  g++ version egcs-2.91 for Red Hat Linux 6.1  on Pentium
********************************************************************/
#if defined(TRACER_NTDRIVER)
extern "C"
{
#include "ntddk.h"
//If the compiler cannot find ntddk.h, 
//please download NT or 2000 DDK from www.microsoft.com/ddk
//and modify compiler settings to include ddk\inc directory

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#define HAVE_EXCEPTIONS
#define HAVE_FILE_OUTPUT
}
#elif defined(CE_KERNEL_DRV)

#include <windows.h>
#include "CeApiTraps.h"

#elif defined(_WIN32_WCE)

#include <windows.h>
#define WINAPP
#define HAVE_FILE_OUTPUT

#elif defined(WIN32)

#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <time.h>
#define WINAPP
#define HAVE_EXCEPTIONS
#define HAVE_FILE_OUTPUT

#elif defined(__linux__)

#if !defined(__i386__)
#error only Pentium supported
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "unistd.h"
#include <fcntl.h>
#include <time.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/sem.h>
#include <syslog.h>
#include <stdarg.h>
#define _vsnprintf vsnprintf

#define HAVE_FILE_OUTPUT

#else
#error "unknown platform"
#endif

#define TRACE_CPP
#include "HTrace.h"

#ifdef TRACE_JNI
#include "jni.h"
extern "C" void JNISetTotalMask
    (ULONG p_dwTotal, ULONG p_ulConsole);
#endif

#ifdef TRACE_ //{

const TCHAR g_szMemMapFileName[] = _T("TraceMemMapFile");
const int  g_iDefaultMemMapFileSize = 1024*1024;

#if !defined(_WIN32_WCE)
#pragma intrinsic(memset,memcpy,strlen,_tcscpy)
#endif

#if defined(__linux__)
long InterlockedExchangeAdd(long * p_plValue, long p_lAdd)
{
    long l_lResult;
    __asm__ __volatile__ (
    "push %%EBX;"    
    "movl %1, %%EBX;" 
    "movl %2, %%EAX;"
    "lock; xadd %%EAX, (%%EBX);"
    "inc %%EAX;"
    "mov %%EAX, %0;"
    "pop %%EBX"    
    : "=g"(l_lResult) : "g"(p_plValue), "g"(p_lAdd) );
    return l_lResult;
}

long InterlockedIncrement(long * p_plValue)
{
    long l_lResult;
    __asm__ __volatile__ (
    "push %%EBX;"    
    "movl %1, %%EBX;" 
    "movl $1, %%EAX;"
    "lock; xadd %%EAX, (%%EBX);"
    "inc %%EAX;"
    "mov %%EAX, %0;"
    "pop %%EBX"    
    : "=g"(l_lResult) : "g"(p_plValue) );
    return l_lResult;
}
long InterlockedDecrement(long * p_plValue)
{
    long l_lResult;
    __asm__ __volatile__ (
    "push %%EBX;"    
    "movl %1, %%EBX;" 
    "movl $-1, %%EAX;"
    "lock; xadd %%EAX, (%%EBX);"
    "inc %%EAX;"
    "mov %%EAX, %0;"
    "pop %%EBX"    
    : "=g"(l_lResult) : "g"(p_plValue) );
    return l_lResult;
}
static bool InterlockedExchangeAddUsingSemaphore(int p_iSemKey,
 int & p_riSemID, int   p_iAdd, int & p_riReturnPreviousValue);
#define __int64 long long
static ULONG GetTickCount()
{
    clock_t l_Clock = clock();
    HTRACE(16, "clock %d per sec %d", l_Clock, CLOCKS_PER_SEC);
    return (ULONG)(((__int64)l_Clock) * 1000 / CLOCKS_PER_SEC);
}
static void _itoa(int p_iValue, char * p_pStr, int p_iRadix)
{
    sprintf(p_pStr, (p_iRadix == 16)? "%x" : "%d", p_iValue);
}
#endif

#define countof(array) (sizeof(array)/sizeof(array[0]))

#if defined(_WIN32_WCE) && UNDER_CE < 400

long InterlockedExchangeAdd(long * p_plValue, long p_lAdd)
{
    while(1)
    {
        long lOld1 = *p_plValue;
        long lOld2 = InterlockedTestExchange
            (p_plValue, lOld1, lOld1 + p_lAdd);
        if(lOld1 == lOld2)
            return lOld1;
        //Some other thread interrupted us. Try again.
    }
}
#endif

#ifdef HAVE_FILE_OUTPUT //{
/*
class HTraceFileImpl is a wrapper around platform-specific 
routines to open,close, read and write a file
*/
class HTraceFileImpl
{
public:
    void Cleanup();
    
    ULONG OpenFile(LPCTSTR p_pszFileName, bool  p_bWrite,
        bool p_bPrependQuestionMarks,
        #if defined(TRACER_NTDRIVER)
            PUNICODE_STRING p_FileName
        #else
            void *
        #endif
        );

    ULONG CloseFile();

    bool  IsOpened();

    ULONG GetFileSize(OUT PLARGE_INTEGER  p_pReturnSize);

    ULONG ReadWriteFile(IN bool p_bWrite, 
        OUT     void *  p_lpBuffer,
        IN      ULONG   p_dwNumberOfBytes,
        IN  OUT PLARGE_INTEGER p_pByteOffset,
        OUT     ULONG*  p_pdwNumberOfBytesProcessed);

    ULONG FlushBuffers();
protected:
    HANDLE  m_hFileHandle;
};//class HTraceFileImpl

/*
class HTraceFileLocal is useful as a local object in functions,
which need to open a file and close it before exiting.
*/
class HTraceFileLocal : public HTraceFileImpl
{
public:
    HTraceFileLocal(){Cleanup();}
    ~HTraceFileLocal() {CloseFile();}
};//class HTraceFileLocal : public HTraceFileImpl

#endif //#ifdef HAVE_FILE_OUTPUT }

//T_TraceOutputStream is definition for trace output routines.
typedef bool T_TraceOutputStream
    (ULONG p_dwMask, LPCTSTR p_pszMessage, int p_iLenChars);
//TraceOutput keeps necessary data for a trace output stream
struct TraceOutput
{
    ULONG   m_dwOutputID;
    TCHAR * m_pszName;
    ULONG   m_dwEnabledGroups;
    char    m_szEnabledGroupsKeywords[256];
    ULONG   m_dwKeyWordModificationCounter;// equal to
    //s_dwKeyWordModifCounter at modification time
    T_TraceOutputStream * m_pOutputFunction;
};

//The following are various trace output functions.
//To add a new method of trace output just add a new constant 
//to enum TraceOutputs in htrace.h, add a new routine here of
//type T_TraceOutputStream and add new line in s_Outputs array
bool OutputDebugMonitor
    (ULONG p_dwMask, LPCTSTR p_pszMessage, int p_iLenChars);
bool OutputFile
    (ULONG p_dwMask, LPCTSTR p_pszMessage, int p_iLenChars);
bool AddToTraceBuffer
    (ULONG p_dwMask, LPCTSTR p_pszBuff, int p_iLenChars);

#if defined(TRACER_NTDRIVER)
bool AddToOutputLog
    (ULONG p_dwMask, LPCTSTR p_pszString, int p_iLenChars);
#else
bool TraceMessageBox
    (ULONG p_dwMask, LPCTSTR p_pszMessage,int p_iLenChars);
#if !defined(_WIN32_WCE)
bool OutputConsole
    (ULONG p_dwMask, LPCTSTR p_pszBuff, int p_iLenChars);
#endif
#endif

TraceOutput s_Outputs[] = {
{TO_DebugMonitor, _T("DebugMonitor"),0, "",-1, OutputDebugMonitor},
{TO_File        , _T("File")        ,0, "",-1, OutputFile        },
{TO_MemoryBuffer, _T("MemoryBuffer"),0, "",-1, AddToTraceBuffer  },
#if defined(TRACER_NTDRIVER)
{TO_OutputLog   , _T("OutputLog")   ,0, "",-1, AddToOutputLog    },
#else
{TO_MessageBox  , _T("MessageBox")  ,0, "",-1, TraceMessageBox   },
#if !defined(_WIN32_WCE)
{TO_Console     , _T("Console")     ,0, "",-1, OutputConsole     },
#endif
#endif
};//TraceOutput s_Outputs[]
#define NUM_STREAMS (countof(s_Outputs))
ULONG s_dwKeyWordModifCounter = 0;

static bool      s_bInitialized = false;
//struct TraceImpl is a holder for various trace settings, 
//current pointers to memory buffer, etc. Only one static 
//instance will be created called s_Impl.
struct TraceImpl
{
    void Clean()
    {
        m_BufferPointers.m_pGlobalHeader = NULL;
        m_BufferPointers.m_pTextArea = NULL;
        m_BufferPointers.m_dwTextAreaSize = 0;
        m_BufferPointers.m_pGlobalFooter = NULL;
        m_bBufferAllocated = false;

        #if defined(WINAPP)
        m_hFileMapping = NULL;
        m_bBufferMapped = false;

        m_hDeviceWithBuffer = INVALID_HANDLE_VALUE;
        m_bMappedDriverBuffer = false;
        m_iIOCTLToUnmapDriverBuffer = 0;
        #endif
        #if defined(__linux__)
        m_iMemMapFile = -1;
        m_iMappingSize = 0;
        m_iSemKey = *((long*)"HTMF");
        m_iSemID = 0;
        m_bBufferMapped = false;
        #endif
        
        #ifdef TRACER_NTDRIVER
        m_pDriverObject = NULL;
        #else
        #endif
        m_dwFlushFileMask         = 0;
        m_pdwTotalMask = &m_dwTotalMask;
        m_dwTotalMask = TG_Error;
        m_dwConsoleMask = 0;
        m_dwDebugMask = 0;

#ifdef HAVE_FILE_OUTPUT
        m_File.Cleanup();
        *m_szFileName = 0;
#endif

        m_bAddTime = false;
        m_bAddThread = false;
        s_bInitialized = false;
    }
    void Free()
    {
#ifdef HAVE_FILE_OUTPUT
        m_File.CloseFile();
#endif
        TraceFreeBuffer();
        Clean();
    }

    bool TraceAssignGroupsToStream
    (
        ULONG   p_dwTraceOutputs,
        ULONG   p_dwNewGroupFlags,
        ULONG   p_dwGroupFlagsToModify,
        char  * p_pszGroupKeyWord
    );

    bool TraceAllocateBuffer(int p_iSize);
    bool TraceSetExternalBuffer
        (GlobalTraceBufferHeader * p_pBuffer);
    void AssignTraceBufferPtr
        (GlobalTraceBufferHeader * p_pBuffer)
    {
        m_BufferPointers.m_dwTextAreaSize = (ULONG)
            ReadSize(p_pBuffer->m_cSizeTextArea);
        m_BufferPointers.m_pTextArea = (LPTSTR)(p_pBuffer+1);
        int l_iFooterAddr = (int)
            (((int)m_BufferPointers.m_pTextArea) + 
             m_BufferPointers.m_dwTextAreaSize);
        //Align on 4 byte boundary
        l_iFooterAddr += 3;
        l_iFooterAddr &= ~3;
        m_BufferPointers.m_pGlobalFooter = 
            (GlobalTraceBufferFooter *)l_iFooterAddr;
        m_BufferPointers.m_pGlobalHeader = p_pBuffer;
        
        //Start using shared mask:
        m_pdwTotalMask = &m_BufferPointers.m_pGlobalFooter->
            m_dwEnabledGroupsTotal;
    }
    static void SetTextAreaSizeHex
        (char p_pszString[12], int p_iSize)
    {
        p_pszString[0] = ' ';
        p_pszString[11] = '\n';
        for(int i = 0; i < 10; i++)
        {
            p_pszString[10-i] = (p_iSize % 10) + '0';
            p_iSize /= 10;
        }
    }

    /*
    ReadSize is a simplified version of atoi, which is only used 
    to read the size of the trace buffer stored in it's header.
    It is always positive decimal number. We don't use a regular 
    atoi, because it may not be available on some platforms.
    */
    static int ReadSize(char * p_pszString)
    {
	    int l_iNumber = 0;
        if(*p_pszString == ' ')
            p_pszString++;
	    while(1)
        {
            char c = *(p_pszString++);
            if(c < '0' || c > '9')
                break;
		    l_iNumber = 10 * l_iNumber + (c - '0');
	    }
        return l_iNumber;
    }


    #if defined(WINAPP)
    bool CreateAndMapFile(LPCTSTR  p_pszMemMapFilePath, 
        int     p_iFileSize);
    bool TraceAttachToNTDriverBuffer(LPCTSTR  p_pszDeviceName,
      int p_iIOCTLMapTraceBuffer, int p_iIOCTLUnMapTraceBuffer,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -