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

📄 htrace.cpp

📁 A Windows CE API Inecptor Tools
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        if(s_Impl.m_File.OpenFile(p_pszFileName, 
            true, true, NULL))
        {
            p_dwNewGroupFlags = 0;
            p_dwGroupFlagsToModify = (ULONG)-1;
        }
    }
    memcpy(s_Impl.m_szFileName, p_pszFileName, iLen);

    s_Impl.TraceAssignGroupsToStream(TO_File, 
        p_dwNewGroupFlags, p_dwGroupFlagsToModify, NULL);
    s_Impl.TraceAssignGroupsToStream(TO_FlushFile, 
        p_dwNewFlushBits, p_dwFlushBitsToModify, NULL);

    return true;
}//void TraceSetOutputToFile

LPCTSTR TraceGetCurTraceFileName()
{
    return s_Impl.m_szFileName;
}
#endif

/*-------------------------------------------------------------
   FUNCTION: TraceImpl::TraceSetExternalBuffer
   PURPOSE:  Start using an externally allocated trace buffer.
-------------------------------------------------------------*/
bool TraceImpl::TraceSetExternalBuffer
(
    GlobalTraceBufferHeader * p_pBufferHeader
)
{
    if(m_BufferPointers.m_pGlobalHeader)
        return false;//Another buffer is already in use
    #ifdef HAVE_EXCEPTIONS
    __try
    {
    #endif    
        if(!p_pBufferHeader || p_pBufferHeader->m_dwSignature!=
            TRACE_BUFFER_SIGNATURE)
        {
            HTRACE(TG_Error, 
            _T("ERROR: TraceSetExternalBuffer(%x) invalid buffer"),
                    p_pBufferHeader);
            return false;
        }
        AssignTraceBufferPtr(p_pBufferHeader);
        m_bBufferAllocated = false;
        return true;
    #ifdef HAVE_EXCEPTIONS
    }
    __except(1)
    {
        HTRACE(TG_Error, 
            _T("ERROR: Exception in TraceSetExternalBuffer(%x)"),
                p_pBufferHeader);
        return false;
    }
    #endif
}//bool TraceImpl::TraceSetExternalBuffer

/*-------------------------------------------------------------
   FUNCTION: TraceSetExternalBuffer
   PURPOSE:  Start using an externally allocated trace buffer
    and enable trace groups for that output.
-------------------------------------------------------------*/
bool TraceSetExternalBuffer(
    GlobalTraceBufferHeader * p_pBufferHeader,
    ULONG   p_dwNewGroupFlags, ULONG   p_dwGroupFlagsToModify)
{
    ChangeLock l_ChangeLock;
    if(!l_ChangeLock.isFirst())
        return false;

    if(!s_Impl.TraceSetExternalBuffer(p_pBufferHeader))
    {
        s_Impl.TraceAssignGroupsToStream
            (TO_MemoryBuffer, 0, (ULONG)-1, NULL);
        return false;
    }
    s_Impl.TraceAssignGroupsToStream
        (TO_MemoryBuffer, p_dwNewGroupFlags, 
        p_dwGroupFlagsToModify, NULL);
    return true;
}

/*-------------------------------------------------------------
   FUNCTION: TraceImpl::TraceAllocateBuffer
   PURPOSE:  Allocate trace buffer of the given size
-------------------------------------------------------------*/
bool TraceImpl::TraceAllocateBuffer
(
    int p_iSizeTextArea
)
{
    if(m_BufferPointers.m_pGlobalHeader)
    {
        HTRACE(TG_Error, 
            _T("ERROR: cannot allocate a new buffer because ")
            _T("another one is in use"));
        return false;//Another buffer is already in use
    }

    int l_iTotalSize =TRACE_BUFFER_EXTRA_SIZE+p_iSizeTextArea;

    GlobalTraceBufferHeader * l_pBufferHeader = NULL;
    #ifdef TRACER_NTDRIVER 
        l_pBufferHeader = (GlobalTraceBufferHeader*) 
            ExAllocatePool(NonPagedPool, l_iTotalSize);
    #elif defined(CE_KERNEL_DRV)
        l_pBufferHeader = (GlobalTraceBufferHeader*) VirtualAlloc
            (NULL, l_iTotalSize, MEM_COMMIT, PAGE_READWRITE);
    #else 
        l_pBufferHeader = 
            (GlobalTraceBufferHeader*) malloc(l_iTotalSize);
    #endif
    if(!l_pBufferHeader)
    {
        HTRACE(TG_Error, 
            _T("ERROR: cannot allocate trace buffer of size %d"),
            l_iTotalSize);
        return false;
    }
    l_pBufferHeader->m_dwSignature = TRACE_BUFFER_SIGNATURE;

    SetTextAreaSizeHex(l_pBufferHeader->m_cSizeTextArea, 
        p_iSizeTextArea);

    AssignTraceBufferPtr(l_pBufferHeader);
    m_BufferPointers.m_pGlobalFooter->m_dwNumBytesWritten = 0;
    m_BufferPointers.m_pGlobalFooter->m_dwStopAfterThreshold 
        = (ULONG)-1;
    m_BufferPointers.m_pGlobalFooter->m_dwFrozen = 0;
    m_bBufferAllocated = true;
    return true;
}//bool TraceAllocateBuffer

/*-------------------------------------------------------------
   FUNCTION: TraceAllocateBuffer
   PURPOSE:  Allocate trace buffer of the given size
    and enable trace groups for that output.
-------------------------------------------------------------*/
bool TraceAllocateBuffer(int p_iSize,
    ULONG   p_dwNewGroupFlags, ULONG   p_dwGroupFlagsToModify)
{
    ChangeLock l_ChangeLock;
    if(!l_ChangeLock.isFirst())
        return false;

    if(!s_Impl.TraceAllocateBuffer(p_iSize))
    {
        if(!s_Impl.m_BufferPointers.m_pGlobalHeader)
        {
            s_Impl.TraceAssignGroupsToStream
                (TO_MemoryBuffer, 0, (ULONG)-1, NULL);
        }
        return false;
    }
    s_Impl.TraceAssignGroupsToStream
        (TO_MemoryBuffer, p_dwNewGroupFlags, 
        p_dwGroupFlagsToModify, NULL);
    return true;
}

/*-------------------------------------------------------------
   FUNCTION: TraceImpl::TraceFreeBuffer
   PURPOSE:  Free the trace buffer if allocated or mapped
-------------------------------------------------------------*/
bool TraceImpl::TraceFreeBuffer()
{
    if(m_BufferPointers.m_pGlobalHeader)
    {
        m_pdwTotalMask = &m_dwTotalMask;

        GlobalTraceBufferHeader * l_pBufferHeader = 
            m_BufferPointers.m_pGlobalHeader;
        m_BufferPointers.m_pGlobalHeader = NULL;

        if(m_bBufferAllocated)
        {
            #ifdef TRACER_NTDRIVER 
                ExFreePool(l_pBufferHeader);
            #elif defined(CE_KERNEL_DRV)
                VirtualFree(l_pBufferHeader, 0, MEM_RELEASE);
            #else
                free(l_pBufferHeader);
            #endif
            m_bBufferAllocated = false;
        }

        #if defined(WINAPP)
        if(m_bBufferMapped)
        {
            UnmapViewOfFile(l_pBufferHeader);
            m_bBufferMapped = false;
            l_pBufferHeader = NULL;
        }

        if(m_bMappedDriverBuffer &&
           m_hDeviceWithBuffer != INVALID_HANDLE_VALUE)
        {
            DWORD l_dwBytesReturned = 0;
            if(!DeviceIoControl(m_hDeviceWithBuffer, 
                m_iIOCTLToUnmapDriverBuffer, 
                &l_pBufferHeader, sizeof(l_pBufferHeader), 
                NULL, 0, &l_dwBytesReturned, NULL))
            {
                HTRACE(TG_Error, 
                    _T("ERROR: DeviceIoControl")
                    _T("(IOCTL_TRACER_UNMAP_BUFFER) failed - %s"), 
                    ERR_EXPL(GetLastError()));
            }
            m_bMappedDriverBuffer = false;
        }
        #endif//defined(WINAPP)
        #if defined(__linux__)
        if(m_bBufferMapped)
        {
            if(munmap(l_pBufferHeader, m_iMappingSize) != 0)
            {
                HTRACE(TG_Error, 
                 "ERROR: munmap failed. %s", strerror(errno));
            }
            m_bBufferMapped = false;
            l_pBufferHeader = NULL;
        }
        #endif
    }//if(m_pTraceBuffer)
    #if defined(WINAPP)
    if(m_hFileMapping != NULL)
    {
        CloseHandle(m_hFileMapping);
        m_hFileMapping = NULL;
    }

    if(m_hDeviceWithBuffer != INVALID_HANDLE_VALUE)
    {
        CloseHandle(m_hDeviceWithBuffer);
        m_hDeviceWithBuffer = INVALID_HANDLE_VALUE;
    }
    #endif
    #if defined(__linux__)
    if(m_iMemMapFile >= 0)
    {
        close(m_iMemMapFile);
        m_iMemMapFile = -1;
        int l_iPrevValue = 0;
        if(!InterlockedExchangeAddUsingSemaphore(m_iSemKey, 
            m_iSemID, -1, l_iPrevValue))
        {
             HTRACE(TG_Error, 
               "InterlockedExchangeAddUsingSemaphore failed");
        }
    }
    #endif
    return true;
}//bool TraceFreeBuffer()

bool TraceFreeBuffer()
{
    ChangeLock l_ChangeLock;
    if(!l_ChangeLock.isFirst())
        return false;
    return s_Impl.TraceFreeBuffer();
}

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

   FUNCTION: WriteCircularBufferToFile

   PURPOSE:  Used to dump trace memory buffer to a file.
    The memory buffer has a circular structure. The oldest data
    starts right after the most recent data. This position can
    be calculated by dividing the total number of bytes written
    by the size of the buffer. This function starts dumping the
    oldest data up to the end of the buffer and then continues
    from the beginning of the buffer.
    This function is available for applications and drivers.
   PARAMETERS:
   const char * p_pszFileName     name of the file
   LocalTraceBufferPointers * p_pBufferPointers - pointers to
                                  the trace buffer
   ULONG * p_pdwReturnStatus      in case of error return Win32
            error (result of GetLastError) or NT kernel status.

   RETURN VALUE:
      bool      true on success, false on failure
-------------------------------------------------------------*/
bool WriteCircularBufferToFile
(
    LPCTSTR      p_pszFileName,
    LocalTraceBufferPointers * p_pBufferPointers,
    ULONG      * p_pdwReturnStatus
)
{
#ifdef HAVE_FILE_OUTPUT
    HTraceFileLocal l_File;
    if(l_File.OpenFile(p_pszFileName, true, true, NULL))
        return false;

    ULONG l_dwWritten = 0;
    
    LARGE_INTEGER l_FileOffset;
    LARGE_INTEGER * l_pOffset = NULL;
    l_FileOffset.QuadPart = 0;
    #if defined(TRACER_NTDRIVER)
    l_pOffset = &l_FileOffset;
    #endif

    if(!p_pBufferPointers->m_pGlobalHeader ||
       !p_pBufferPointers->m_pGlobalFooter)
    {
        char * l_pszString = "Debug memory is NULL";
        l_File.ReadWriteFile(true, 
            l_pszString, strlen(l_pszString)+1,
            l_pOffset, NULL);
        l_File.CloseFile();
        #if defined(TRACER_NTDRIVER)
        if(p_pdwReturnStatus)
            *p_pdwReturnStatus = STATUS_UNSUCCESSFUL;
        #endif
        return false;
    }
    //Our buffer is circular. 
    //We need to write the tail first, then the beginning
    ULONG l_dwTextAreaSize = p_pBufferPointers->m_dwTextAreaSize;
    ULONG l_dwNumBytesWritten = 
        p_pBufferPointers->m_pGlobalFooter->m_dwNumBytesWritten;
    char * l_pszTextArea = (char*)p_pBufferPointers->m_pTextArea;

    int l_iLastAddedByte = l_dwNumBytesWritten % 
                           l_dwTextAreaSize;

    if(l_dwNumBytesWritten > l_dwTextAreaSize)
        l_File.ReadWriteFile(true, 
            l_pszTextArea + l_iLastAddedByte, 
            l_dwTextAreaSize - l_iLastAddedByte,
            l_pOffset, NULL);

    l_File.ReadWriteFile(true, l_pszTextArea, l_iLastAddedByte,
        l_pOffset, NULL);
    
    l_File.CloseFile();
    return true;
#else
    return false;
#endif
}//bool WriteCircularBufferToFile

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

   FUNCTION: TraceImpl::TraceDumpBufferToFile

   PURPOSE:  Print the accumulated messages from the 
    trace memory buffer to a file.
    This function is available for applications and drivers.
      
   PARAMETERS:                   .
    const char * p_pszFileName   File name.
-------------------------------------------------------------*/
bool TraceImpl::TraceDumpBufferToFile
(
    LPCTSTR p_pszFileName
)
{
    if(!WriteCircularBufferToFile(p_pszFileName, 
        &m_BufferPointers, NULL))
        return false;
    return true;
}//bool TraceDumpBufferToFile

bool TraceDumpBufferToFile(LPCTSTR p_pszFileName)
{
    ChangeLock l_ChangeLock;
    if(!l_ChangeLock.isFirst())
        return false;
    return s_Impl.TraceDumpBufferToFile(p_pszFileName);
}

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

   FUNCTION: AddToTraceBuffer

   PURPOSE:  Add the given message to the trace memory buffer.
       This function is available for applications and drivers.
      
   PARAMETERS:                   .

    LPCTSTR p_pszMessage,  Message - 0-terminated string
    int     p_iLen         Number of characters in the string
-------------------------------------------------------------*/
bool AddToTraceBuffer
(
    ULONG,
    LPCTSTR p_pszString, 
    int     p_iLenChars
)
{
    int l_iLenBytes = p_iLenChars * sizeof(TCHAR);
    if(!s_Impl.m_BufferPointers.m_pGlobalHeader)
    {        return false;

⌨️ 快捷键说明

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