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

📄 htrace.cpp

📁 A Windows CE API Inecptor Tools
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        bool    p_bDontComplainIfDeviceAbsent);
    #endif
    #if defined(__linux__)
    bool CreateAndMapFile(const char *  p_pszMemMapFilePath, 
        int     p_iFileSize);
    #endif

    bool TraceFreeBuffer();
    bool TraceDumpBufferToFile(LPCTSTR p_pszFileName);

    LocalTraceBufferPointers m_BufferPointers;
    bool                m_bBufferAllocated;

    #if defined(WINAPP)
    HANDLE              m_hFileMapping;
    bool                m_bBufferMapped;

    HANDLE              m_hDeviceWithBuffer;
    bool                m_bMappedDriverBuffer;
    int                 m_iIOCTLToUnmapDriverBuffer;
    #endif
    #if defined(__linux__)
    int                 m_iMemMapFile;
    int                 m_iMappingSize;
    int                 m_iSemKey;
    int                 m_iSemID;
    bool                m_bBufferMapped;
    #endif
    
    #ifdef TRACER_NTDRIVER
    PDRIVER_OBJECT m_pDriverObject;
    FAST_MUTEX     m_FastMutexToProtectMemMap;
    #else
    #endif
    ULONG m_dwFlushFileMask;

    ULONG m_dwTotalMask;
    ULONG*m_pdwTotalMask;
    ULONG m_dwConsoleMask;
    ULONG m_dwDebugMask;

#ifdef HAVE_FILE_OUTPUT
    HTraceFileImpl m_File;
    TCHAR           m_szFileName[_MAX_PATH];
#endif
    
    bool            m_bAddTime;
    bool            m_bAddThread;
};//struct TraceImpl

static TraceImpl s_Impl;
static long      s_lChangeLock = -1;
/*
Current implementation does not allow simultaneous modification
of trace parameters by multiple threads. Ideally, a process 
should initialize trace from the beginning and, may be, 
update trace parameters from a single thread.
Functions, which generate trace, such as HTraceImpl and 
OutputTraceString can be called by any thread at any time(after
the trace is initialized by TraceInitialize.
*/

//We will use s_lChangeLock and class ChangeLock
//to protect all functions, which can modify trace settings,
//from simultaneous calls from several threads.
class ChangeLock
{
public:
    ChangeLock()
    {
        m_lChangeLock = InterlockedIncrement(&s_lChangeLock);
    }
    ~ChangeLock()
    {
        InterlockedDecrement(&s_lChangeLock);
    }
    bool isFirst() 
    {
        return (m_lChangeLock == 0)? true : false;
    }
    long m_lChangeLock;
};//class ChangeLock

/*-------------------------------------------------------------
   FUNCTION: TraceInitialize
   PURPOSE:  Initialize the trace. Must be called before any 
    other trace routine. We cannot use constructor in class 
    TraceImpl, because constructors in static classes require 
    presence of a C++ library, which is not always available.
-------------------------------------------------------------*/
bool TraceInitialize()
{
    ChangeLock l_ChangeLock;
    if(!l_ChangeLock.isFirst())
        return false;
    if(s_bInitialized)
        return true;
    s_Impl.Clean();
    s_bInitialized = true;
    #ifdef TRACER_NTDRIVER
    ExInitializeFastMutex(&s_Impl.m_FastMutexToProtectMemMap);
    #endif
    return true;
}

/*-------------------------------------------------------------
   FUNCTION: TraceUnInitialize
   PURPOSE:  Uninitialize the trace. Must be called before 
    application or driver terminates. We cannot use destructor 
    in class TraceImpl, because constructors in static classes 
    require presence of C++ library, which may not be available
-------------------------------------------------------------*/
bool TraceUnInitialize()
{
    ChangeLock l_ChangeLock;
    if(!l_ChangeLock.isFirst())
        return false;
    s_Impl.Free();
    return true;
}

#ifndef TRACER_NTDRIVER
#ifdef  TRACE_ADD_DLLMAIN
/*-------------------------------------------------------------
   FUNCTION: DllMain
   PURPOSE:  If the HTrace.cpp is built into a stand-alone DLL,
    such as HTrcJni.DLL, we will use standard Win32 DllMain to
    initialize and uninitialize the trace.
-------------------------------------------------------------*/
BOOL WINAPI DllMain
(
    HINSTANCE   p_hInstDLL, 
    DWORD       p_dwReason, 
    LPVOID      p_lpvReserved
)
{
    switch (p_dwReason)
    {
        case DLL_PROCESS_ATTACH:
        {
            TraceInitialize();

            //By default, show errors and warnings on the
            //debugger's log window and in message boxes.
            TraceAssignGroupsToStream(
                TO_DebugMonitor | TO_MessageBox,
                TG_MessageBox | TG_Error, (DWORD)-1);
    
            //Print bank account and thread swaps(if the 
            //driver is loaded) to the memory buffer
            TraceAssignGroupsToStream(TO_MemoryBuffer,
                TG_BankAccount | TG_ThreadSwaps, (DWORD)-1);

            char l_szFullINIPath[_MAX_PATH];
            GetFullPathName("HTrace.ini", 
                sizeof(l_szFullINIPath), l_szFullINIPath,NULL);

            //Read state of all streams. This can override the 
            //assignments made in the preceding calls.
            TraceReadWriteSettings(NULL, l_szFullINIPath,
                false, (DWORD)-1);
        }
        break;
        case DLL_PROCESS_DETACH:
            TraceUnInitialize();
        break;
    }
    return TRUE;
}
#endif//  TRACE_ADD_DLLMAIN
#endif

void SetOneTraceMask
(
    PULONG   p_pdwMask,
    ULONG    p_dwNewGroupFlags,
    ULONG    p_dwGroupFlagsToModify
)
{
    *p_pdwMask =  (*p_pdwMask  & ~p_dwGroupFlagsToModify) |
              (p_dwNewGroupFlags &  p_dwGroupFlagsToModify);
}

/*-------------------------------------------------------------

   FUNCTION: TraceImpl::TraceAssignGroupsToStream

   PURPOSE:  This function allows to enable/disable output
    of the specified groups of HTRACE operators to
    the specified output stream.
    Each HTRACE operator has a bit mask as a first parameter.
    This mask will be matched against a mask for a particular
    device to decide whether to allow output or not.
      
   PARAMETERS:                   .
    
   ULONG    p_dwTraceOutputs       flags from TraceOutputs.
   ULONG    p_dwNewGroupFlags      new bits to set or reset
   ULONG    p_dwGroupFlagsToModify which bits can be modified
   char  *  p_pszGroupKeyWord      new keyword mask
-------------------------------------------------------------*/
bool TraceImpl::TraceAssignGroupsToStream
(
    ULONG   p_dwTraceOutputs,
    ULONG   p_dwNewGroupFlags,
    ULONG   p_dwGroupFlagsToModify,
    char  * p_pszGroupKeyWord
)
{
    m_dwTotalMask = 0;
    m_dwConsoleMask = 0;
    m_dwDebugMask = 0;
    //Loop for all available output streams
    for(int i = 0; i < NUM_STREAMS; i++)
    {
        TraceOutput & l_rOutput = s_Outputs[i];
        //Check whether we are asked to modify this stream
        if(l_rOutput.m_dwOutputID & p_dwTraceOutputs)
        {
            //Update bits in the group mask of this stream
            SetOneTraceMask(&l_rOutput.m_dwEnabledGroups,
                p_dwNewGroupFlags, p_dwGroupFlagsToModify);
            if(p_pszGroupKeyWord)
            {
                //We are asked to update the stream keyword
                int l_iLen = strlen(p_pszGroupKeyWord);
                if(l_iLen >= 
                   sizeof(l_rOutput.m_szEnabledGroupsKeywords))
                {
                    HTRACE(TG_Error, 
                      _T("ERROR: not enough space for keyword %s"),
                        p_pszGroupKeyWord);
                }
                else if(memcmp(
                        l_rOutput.m_szEnabledGroupsKeywords,
                        p_pszGroupKeyWord, l_iLen+1))
                {//need to change the keyword
                    memcpy(l_rOutput.m_szEnabledGroupsKeywords,
                        p_pszGroupKeyWord, l_iLen+1);
                    //Increment modification counter, 
                    //store its value to force all HTRACEK 
                    //macros to check whether they match the
                    //new keyword on the next call.
                    l_rOutput.m_dwKeyWordModificationCounter = 
                        ++s_dwKeyWordModifCounter;
                }
            }

            if(l_rOutput.m_dwOutputID == TO_MemoryBuffer)
            {
                //Some additional processing for memory buffer
                if(l_rOutput.m_dwEnabledGroups ||
                  *l_rOutput.m_szEnabledGroupsKeywords)
                {
                    #if defined(WINAPP)
                    //If we have no buffer,try first to connect
                    //to our driver and if not successful, try
                    //to map to a mem-map file
                    if(!m_BufferPointers.m_pGlobalHeader)
                    {
                        TraceAttachToNTDriverBuffer(
                            NULL, -1, -1, true);
                    }
                    #endif
                    #if defined(WINAPP) || defined(__linux__)
                    if(!m_BufferPointers.m_pGlobalHeader)
                    {
                        CreateAndMapFile(NULL, -1);
                    }
                    #endif
                }
                if(m_BufferPointers.m_pGlobalFooter != NULL)
                {
                    //If the buffer is present, 
                    //copy the mask to it, so it will 
                    //immediately affect other applications,
                    //which share the buffer with us.
                    GlobalTraceBufferFooter * l_Footer = 
                        m_BufferPointers.m_pGlobalFooter;
                    l_Footer->m_dwEnabledGroups = 
                        l_rOutput.m_dwEnabledGroups;
                    strcpy(l_Footer->m_szKeyWordMask,
                        l_rOutput.m_szEnabledGroupsKeywords);
                    l_Footer->m_dwKeyWordModificationCounter = 
                       l_rOutput.m_dwKeyWordModificationCounter;
                    //Start using shared mask:
                    m_pdwTotalMask = 
                        &l_Footer->m_dwEnabledGroupsTotal;
                }
            }//if(l_rOutput.m_dwOutputID == TO_MemoryBuffer)

            #ifndef CE_KERNEL_DRV
            if(l_rOutput.m_dwOutputID == TO_File &&
               (l_rOutput.m_dwEnabledGroups ||
               *l_rOutput.m_szEnabledGroupsKeywords) &&
               !m_File.IsOpened())
            {//We need to open the file
                if(m_File.OpenFile
                    (m_szFileName, true, true, NULL))
                {
                    //Cannot open the file. Need to 
                    //disable the trace
                    l_rOutput.m_dwEnabledGroups = 0;
                    *l_rOutput.m_szEnabledGroupsKeywords = 0;
                }
            }
            #endif
            #if defined(WINAPP) && !defined(_WIN32_WCE)
            if(l_rOutput.m_dwOutputID == TO_Console  &&
              (l_rOutput.m_dwEnabledGroups ||
              *l_rOutput.m_szEnabledGroupsKeywords))
            {
                AllocConsole();
            }
            #endif
        }//if(l_rOutput.m_dwOutputID & p_dwTraceOutputs)
        m_dwTotalMask |= l_rOutput.m_dwEnabledGroups;
        if(l_rOutput.m_dwOutputID == TO_Console)
        {   //Keep the console mask separately for Java sake.
            m_dwConsoleMask = l_rOutput.m_dwEnabledGroups;
        }
        if(l_rOutput.m_dwOutputID == TO_DebugMonitor)
        {
            m_dwDebugMask = l_rOutput.m_dwEnabledGroups;
        }
    }//for(int i = 0; i < NUM_STREAMS;

    //Treat TO_FlushFile separately, because it is not a 
    //separate output stream, but modification of TO_File
    if(p_dwTraceOutputs  & TO_FlushFile)
    {
        SetOneTraceMask(&m_dwFlushFileMask,
            p_dwNewGroupFlags, p_dwGroupFlagsToModify);
    }
    *m_pdwTotalMask = m_dwTotalMask;
    #ifdef TRACE_JNI
    //Inform Java class about new masks
    JNISetTotalMask(*m_pdwTotalMask, m_dwConsoleMask);
    #endif
    return true;
}//bool TraceImpl::TraceAssignGroupsToStream

/*-------------------------------------------------------------
   FUNCTION: TraceAssignGroupsToStream
   PURPOSE:  The same as TraceImpl::TraceAssignGroupsToStream.
    It accepts only integer group bitmap.
    Use TraceAssignGroupKeyWordToStream to change keyword masks
    Increment lock counter to prevent multiple threads from 
    simultaneous access.
-------------------------------------------------------------*/
bool TraceAssignGroupsToStream
(
    ULONG   p_dwTraceOutputs,
    ULONG   p_dwNewGroupFlags,
    ULONG   p_dwGroupFlagsToModify
)
{
    ChangeLock l_ChangeLock;
    if(!l_ChangeLock.isFirst())
        return false;
    return s_Impl.TraceAssignGroupsToStream(p_dwTraceOutputs, 
            p_dwNewGroupFlags, p_dwGroupFlagsToModify, NULL);
}//bool TraceAssignGroupsToStream

/*-------------------------------------------------------------
   FUNCTION: TraceAssignGroupKeyWordToStream
   PURPOSE:  The same as TraceImpl::TraceAssignGroupsToStream.
    It accepts only string keyword masks.
    Use TraceAssignGroupsToStream to change integer group mask.
    Increment lock counter to prevent multiple threads from 
    simultaneous access.
-------------------------------------------------------------*/
bool TraceAssignGroupKeyWordToStream
(
    ULONG   p_dwTraceOutputs,
    char  * p_pszGroupKeyWord
)
{
    ChangeLock l_ChangeLock;
    if(!l_ChangeLock.isFirst())
        return false;
    return s_Impl.TraceAssignGroupsToStream(p_dwTraceOutputs, 
            0, 0, p_pszGroupKeyWord);
}//bool TraceAssignGroupsToStream

/*-------------------------------------------------------------
   FUNCTION: TraceGetAssignedGroupsToStream
   PURPOSE:  Return all group flags, which are enabled for the 
    specified output stream(s)
-------------------------------------------------------------*/
ULONG TraceGetAssignedGroupsToStream
(
    ULONG   p_dwTraceOutputs
)
{
    ULONG l_ulResult = 0;
    for(int i = 0; i < NUM_STREAMS;i++)
    {
        TraceOutput & l_rOutput = s_Outputs[i];
        if(l_rOutput.m_dwOutputID & p_dwTraceOutputs)
        {
            l_ulResult |= l_rOutput.m_dwEnabledGroups;

⌨️ 快捷键说明

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