📄 htrace.cpp
字号:
}
}
if(p_dwTraceOutputs & TO_FlushFile)
{
l_ulResult |= s_Impl.m_dwFlushFileMask;
}
return l_ulResult;
}//ULONG TraceGetAssignedGroupsToStream
/*-------------------------------------------------------------
FUNCTION: TraceGetAssignedGroupKeyWordsToStream
PURPOSE: Return keyword mask, which is assigned to the
specified output stream
-------------------------------------------------------------*/
LPCSTR TraceGetAssignedGroupKeyWordsToStream
(
ULONG p_dwTraceOutput
)
{
ULONG l_ulResult = 0;
for(int i = 0; i < NUM_STREAMS;i++)
{
TraceOutput & l_rOutput = s_Outputs[i];
if(l_rOutput.m_dwOutputID == p_dwTraceOutput)
{
return l_rOutput.m_szEnabledGroupsKeywords;
}
}
return NULL;
}//LPCSTR TraceGetAssignedGroupKeyWordsToStream
void SetTraceTimeAndThreadID
(
bool p_bAddTime,
bool p_bAddThread
)
{
s_Impl.m_bAddTime = p_bAddTime;
s_Impl.m_bAddThread = p_bAddThread;
}
#if defined(WINAPP) //{
/*-------------------------------------------------------------
FUNCTION: ReadWriteSetting
PURPOSE: Read or write a single value (string or DWORD)
from/to a registry value or an INI file field.
Used by TraceReadWriteSettings.
PARAMETERS: .
BOOL p_bRegistry - TRUE for registry, FALSE - for INI
BOOL p_bWrite - TRUE to write, FALSE - read
BOOL p_bString - TRUE for string, FALSE - DWORD
HKEY p_hKey - registry key. Used only if
p_bRegistry == TRUE. May be NULL for Read operation -
in that case 0 or an empty string will be returned.
LPCTSTR p_pszPath - INI file path. Used if
p_bRegistry == FALSE.
LPCTSTR p_pszEntryName - registry entry or INI field.
LPVOID p_pExistingValue - pointer to the value to write.
Used only if p_bWrite == TRUE. Must not be NULL.
LPVOID p_pReadValue - pointer to the value to read
Used only if p_bWrite == FALSE. Must not be NULL.
DWORD p_dwSizeBytes - size of the string (in bytes,
not characters) or sizeof(DWORD)
RETURN:
TRUE if write successful
FALSE if write failed, if read failed (including
missing entry) or if the string does not fit the buffer.
-------------------------------------------------------------*/
BOOL ReadWriteSetting
(
BOOL p_bRegistry,
BOOL p_bWrite,
BOOL p_bString,
HKEY p_hKey,
LPCTSTR p_pszPath,
LPCTSTR p_pszEntryName,
LPVOID p_pExistingValue,
LPVOID p_pReadValue,
DWORD p_dwSizeBytes
)
{
BOOL l_bResult = FALSE;
TCHAR l_szEntryValue[512], * l_pszReadTo;
DWORD l_dwReadSize;
if(p_bRegistry)
{
if(!p_bWrite)
{//Read string directly to user supplied buffer
l_pszReadTo = (LPTSTR)p_pReadValue;
l_dwReadSize = p_dwSizeBytes;
}
else
{
l_pszReadTo = l_szEntryValue;
l_dwReadSize = sizeof(l_szEntryValue);
}
DWORD l_dwType = 0;
long l_lResult = RegQueryValueEx(p_hKey, p_pszEntryName, 0,
&l_dwType, (LPBYTE)l_pszReadTo, &l_dwReadSize);
if(l_lResult == ERROR_SUCCESS)
{
l_bResult = TRUE;
}
else
{
if(p_bString)
{
*(LPTSTR)l_pszReadTo = 0;
l_dwReadSize = sizeof(TCHAR);
}
else
{
*(LPDWORD)l_pszReadTo = 0;
}
}
if(p_bWrite)
{
l_bResult = FALSE;
if(p_bString)
{
p_dwSizeBytes = (_tcslen
((LPTSTR)p_pExistingValue)+1)*sizeof(TCHAR);
}
if(l_dwReadSize != p_dwSizeBytes ||
memcmp(p_pExistingValue, l_pszReadTo, p_dwSizeBytes))
{
long l_lResult = RegSetValueEx(p_hKey,
p_pszEntryName, 0, p_bString? REG_SZ : REG_DWORD,
(LPBYTE)p_pExistingValue, p_dwSizeBytes);
if(l_lResult != ERROR_SUCCESS)
{
HTRACE(TG_Error,
_T("ERROR: RegSetValueEx(%s)")
_T(" failed - %s"),
p_pszEntryName, ERR_EXPL(l_lResult));
}
else
{
l_bResult = TRUE;
}
}
}
}
#if !defined(_WIN32_WCE)
else
{
DWORD l_dwReadBuffNumChars;
if(!p_bWrite && p_bString)
{//Read string directly to user supplied buffer
l_pszReadTo = (LPTSTR)p_pReadValue;
l_dwReadBuffNumChars = p_dwSizeBytes/sizeof(TCHAR);
}
else
{
l_pszReadTo = l_szEntryValue;
l_dwReadBuffNumChars = countof(l_szEntryValue);
}
GetPrivateProfileString("Trace", p_pszEntryName, "~",
l_pszReadTo, l_dwReadBuffNumChars, p_pszPath);
if(p_bString)
{
if(p_bWrite)
{
if(_tcscmp(l_szEntryValue, (LPTSTR)p_pExistingValue))
{
WritePrivateProfileString("Trace", l_szEntryName,
(LPTSTR)p_pExistingValue, p_pszPath);
}
l_bResult = TRUE;
}
else
{
if(*p_pReadValue != '~')
{
l_bResult = TRUE;
}
}
}
else
{
DWORD l_dwCurValue = 0;
DWORD l_dwNewValue = *(LPDWORD)p_pExistingValue;
if(*l_szEntryValue != '~')
{
l_dwCurValue = strtoul(l_szEntryValue, NULL, 0);
l_bResult = TRUE;
}
if(p_bWrite)
{
if(l_dwNewValue != l_dwCurValue)
{
sprintf(l_szEntryValue, "0x%x", l_dwNewValue);
WritePrivateProfileString("Trace",p_pszEntryName,
l_szEntryValue, p_pszPath);
}
l_bResult = TRUE;
}
else
{
*(LPDWORD)p_pReadValue = l_dwCurValue;
}
}
}
#endif//!_WIN32_WCE
if(!p_bWrite && !l_bResult)
{//Set default
if(p_bString)
{
*(LPTSTR)p_pReadValue = 0;
}
else
{
*(LPDWORD)p_pReadValue = 0;
}
}
return l_bResult;
}//BOOL ReadWriteSetting
/*-------------------------------------------------------------
FUNCTION: TraceReadWriteSettings
PURPOSE: Read or write group masks and keywords for some or
all output streams to/from either registry or .INI file.
PARAMETERS: .
HKEY p_hKeyRoot root registry key (for example
HKEY_CURRENT_USER). May be NULL - in that case p_pszPath
should be a path to .INI file (if platform supports it).
LPCSTR p_pszPath if p_hKeyRoot != NULL - registry path
if p_hKeyRoot == NULL - INI file path
bool p_bWrite true to write, false to read
ULONG p_ulOutputsToProcess flags from TraceOutputs -
chose which stream settings to read/write
-------------------------------------------------------------*/
bool TraceReadWriteSettings
(
HKEY p_hKeyRoot,
LPCTSTR p_pszPath,
bool p_bWrite,
ULONG p_ulOutputsToProcess
)
{
#if defined(_WIN32_WCE)
if(p_hKeyRoot == NULL)
return false;
#endif
ChangeLock l_ChangeLock;
if(!l_ChangeLock.isFirst())
return false;
HKEY l_hKey = NULL;
LRESULT l_lResult;
BOOL l_bRegistry = FALSE;
if(p_hKeyRoot)
{
l_bRegistry = TRUE;
if(p_bWrite)
{
l_lResult = RegCreateKeyEx(p_hKeyRoot, p_pszPath,
0, NULL, 0, NULL, NULL, &l_hKey, NULL);
if(l_lResult != ERROR_SUCCESS)
{
HTRACE(TG_Error,
_T("ERROR: RegCreateKeyEx(%s)")
_T(" failed - %s"),
p_pszPath, ERR_EXPL(l_lResult));
return false;
}
}
else
{
l_lResult = RegOpenKeyEx(p_hKeyRoot, p_pszPath,
0, NULL, &l_hKey);
//Don't report this as an error since the key
//may be absent until we create it later.
//Also don't return on error - continue and
//use defaults instead of registry values.
}
}
ULONG l_ulResult = 0;
for(int i = 0; i < NUM_STREAMS;i++)
{
TraceOutput & l_rOutput = s_Outputs[i];
if(!(l_rOutput.m_dwOutputID & p_ulOutputsToProcess))
continue;
TCHAR l_szEntryName[512];
DWORD l_dwNewGroupMask = l_rOutput.m_dwEnabledGroups;
DWORD l_dwModifyGroupMask = 0;
TCHAR l_szKeywordMask[256] = _T("");
char *l_pszNewKeywordMask = NULL;
_stprintf(l_szEntryName, _T("%s_GroupMask"),
l_rOutput.m_pszName);
if(ReadWriteSetting(l_bRegistry, p_bWrite, FALSE,
l_hKey, p_pszPath, l_szEntryName,
&l_rOutput.m_dwEnabledGroups,
&l_dwNewGroupMask, sizeof(l_dwNewGroupMask)))
{
l_dwModifyGroupMask = -1;
}
_stprintf(l_szEntryName,
_T("%s_GroupKeyWords"), l_rOutput.m_pszName);
if(ReadWriteSetting(l_bRegistry, p_bWrite, TRUE,
l_hKey, p_pszPath, l_szEntryName,
l_rOutput.m_szEnabledGroupsKeywords,
l_szKeywordMask, sizeof(l_szKeywordMask)))
{
l_pszNewKeywordMask = (char*)l_szKeywordMask;
#ifdef UNICODE
//simple conversion Unicode to single byte
for(int j = 0; ; j++)
{
l_pszNewKeywordMask[j] = (char)l_szKeywordMask[j];
if(l_szKeywordMask[j])
break;
}
#endif
}
if(l_rOutput.m_dwOutputID == TO_File)
{
_stprintf(l_szEntryName, _T("%s_Path"),
l_rOutput.m_pszName);
TCHAR l_szFilePath[_MAX_PATH] = _T("");
ReadWriteSetting(l_bRegistry, p_bWrite, TRUE,
l_hKey, p_pszPath, l_szEntryName,
s_Impl.m_szFileName,
l_szFilePath, sizeof(l_szFilePath));
if(!p_bWrite)
{
if(*l_szFilePath == 0)
{
s_Impl.m_File.CloseFile();
}
else
{
TraceSetOutputToFile(l_szFilePath,
0,0,0,0);
}
}
}//if(l_rOutput.m_dwOutputID == TO_File)
if(!p_bWrite)
{
s_Impl.TraceAssignGroupsToStream(
l_rOutput.m_dwOutputID,
l_dwNewGroupMask, l_dwModifyGroupMask,
l_pszNewKeywordMask);
}
}//for(int i = 0; i < NUM_STREAMS;i++)
if(l_hKey)
{
RegCloseKey(l_hKey);
}
return true;
}//ULONG TraceReadWriteSettings
#endif //#if defined(WINAPP) }
#if defined(WINAPP) || defined(__linux__) //{
/*-------------------------------------------------------------
FUNCTION: TraceSetOutputToFile
PURPOSE: Enable tracing to a file. Unlike memory-mapped
file, output to a file will directly print trace messages
to a file, which allows an unlimited size, but may be
slower. This function accepts 2 masks: p_dwNewGroupFlags
to decide which trace statements should be printed to file
and p_dwNewFlushBits to determine which trace statements
should also flush the file. Flushing the file allows to
preserve the trace if an application crashes, but is much
slower.
PARAMETERS: .
LPCTSTR p_pszFileName - file name to print traces to
ULONG p_dwNewGroupFlags -new trace groups flags
ULONG p_dwGroupFlagsToModify-trace groups flags to change
ULONG p_dwNewFlushBits - new trace flags for flushing
ULONG p_dwFlushBitsToModify - trace flags to change
-------------------------------------------------------------*/
bool TraceSetOutputToFile
(
LPCTSTR p_pszFileName,
ULONG p_dwNewGroupFlags ,
ULONG p_dwGroupFlagsToModify,
ULONG p_dwNewFlushBits ,
ULONG p_dwFlushBitsToModify
)
{
int iLen = _tcslen(p_pszFileName);
if(iLen >= countof(s_Impl.m_szFileName))
return false;//too long name
iLen = (iLen+1)*sizeof(TCHAR);
ChangeLock l_ChangeLock;
if(!l_ChangeLock.isFirst())
return false;
if(p_dwNewGroupFlags && (
memcmp(s_Impl.m_szFileName, p_pszFileName, iLen) ||
!s_Impl.m_File.IsOpened()))
{
s_Impl.m_File.CloseFile();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -