📄 htrace.cpp
字号:
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 + -