|
|
#include <objbase.h>
#include "rbdebug.h"
BOOL CRBDebug::_fInited = FALSE; DWORD CRBDebug::_dwFlags = 0; DWORD CRBDebug::_dwTraceFlags = 0; TCHAR* CRBDebug::_pszTraceFile = new TCHAR[MAX_PATH]; TCHAR* CRBDebug::_pszModuleName = new TCHAR[MAX_PATH]; HANDLE CRBDebug::_hfileTraceFile = INVALID_HANDLE_VALUE; TCHAR* CRBDebug::_pszTracePipe = new TCHAR[MAX_PATH]; TCHAR CRBDebug::_szFileAndLine[] = {0}; CRITICAL_SECTION CRBDebug::_cs = {0}; #define ARRAYSIZE(a) (sizeof((a))/sizeof((a)[0]))
HRESULT CRBDebug::_InitFile(HKEY hkeyRoot) { HRESULT hres = E_FAIL; HKEY hkeyFile;
if (ERROR_SUCCESS == RegOpenKeyEx(hkeyRoot, TEXT("File"), 0, MAXIMUM_ALLOWED, &hkeyFile)) { DWORD dwSize = MAX_PATH * sizeof(TCHAR);
if (ERROR_SUCCESS == RegQueryValueEx(hkeyFile, TEXT("FileName"), 0, NULL, (PBYTE)_pszTraceFile, &dwSize)) { _hfileTraceFile = CreateFile(_pszTraceFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE != _hfileTraceFile) { SetFilePointer(_hfileTraceFile, 0, 0, FILE_END);
hres = S_OK; } }
RegCloseKey(hkeyFile); }
return hres; }
HRESULT CRBDebug::_InitPipe(HKEY hkeyRoot) { HRESULT hres = S_OK; HKEY hkeyFile; TCHAR szMachineName[MAX_PATH]; TCHAR szPipeName[MAX_PATH];
if (ERROR_SUCCESS == RegOpenKeyEx(hkeyRoot, TEXT("Pipe"), 0, MAXIMUM_ALLOWED, &hkeyFile)) { DWORD dwSize = sizeof(szMachineName);
if (ERROR_SUCCESS != RegQueryValueEx(hkeyFile, TEXT("MachineName"), 0, NULL, (PBYTE)szMachineName, &dwSize)) { lstrcpy(szMachineName, TEXT(".")); }
dwSize = sizeof(szPipeName);
if (ERROR_SUCCESS != RegQueryValueEx(hkeyFile, TEXT("PipeName"), 0, NULL, (PBYTE)szPipeName, &dwSize)) { lstrcpy(szPipeName, _pszModuleName); }
RegCloseKey(hkeyFile); } else { // Defaults
lstrcpy(szMachineName, TEXT(".")); lstrcpy(szPipeName, _pszModuleName); }
wsprintf(_pszTracePipe, TEXT("\\\\%s\\pipe\\%s"), szMachineName, szPipeName);
return hres; }
// static
HRESULT CRBDebug::_Init() { HRESULT hres = S_FALSE;
if (!_fInited) { // Read the flags
WCHAR szKey[MAX_PATH]; WCHAR szModule[MAX_PATH]; BOOL fKeyExist = FALSE;
hres = E_FAIL;
InitializeCriticalSection(&_cs);
lstrcpy(szKey, L"Software\\Microsoft\\Debug\\");
if (GetModuleFileName(GetModuleHandle(NULL), szModule, MAX_PATH)) { HKEY hkey; LONG lSuccess; int c = lstrlen(szModule);
while (c && (L'\\' != szModule[c])) { --c; }
lstrcpy(_pszModuleName, szModule + c + 1); lstrcat(szKey, _pszModuleName);
lSuccess = RegOpenKeyEx(HKEY_CURRENT_USER, szKey, 0, MAXIMUM_ALLOWED, &hkey);
if (ERROR_SUCCESS != lSuccess) { lSuccess = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKey, 0, MAXIMUM_ALLOWED, &hkey); }
if (ERROR_SUCCESS == lSuccess) { DWORD dwSize = sizeof(DWORD); fKeyExist = TRUE;
if (ERROR_SUCCESS == RegQueryValueEx(hkey, L"RBD_FLAGS", 0, NULL, (PBYTE)&_dwFlags, &dwSize)) { if (_dwFlags & RBD_TRACE_OUTPUTDEBUG) { hres = S_OK; }
if ((_dwFlags & RBD_TRACE_TOFILE) || (_dwFlags & RBD_TRACE_TOFILEANSI)) { hres = _InitFile(hkey);
if (FAILED(hres)) { _dwFlags &= ~RBD_TRACE_TOFILE; } }
if (_dwFlags & RBD_TRACE_TOPIPE) { hres = _InitPipe(hkey);
if (FAILED(hres)) { _dwFlags &= ~RBD_TRACE_TOPIPE; } } } else { _dwFlags = RBD_TRACE_OUTPUTDEBUG | RBD_ASSERT_STOP;
hres = S_FALSE; }
if (ERROR_SUCCESS != RegQueryValueEx(hkey, L"TRACE_FLAGS", 0, NULL, (PBYTE)&_dwTraceFlags, &dwSize)) { // Default...
_dwTraceFlags = 0; }
RegCloseKey(hkey); } }
if (!fKeyExist) { // If we can't find a key for this app then we revert to default
// behavior
_dwFlags = RBD_TRACE_OUTPUTDEBUG | RBD_ASSERT_STOP;
hres = S_FALSE; }
if (SUCCEEDED(hres)) { _fInited = TRUE; } }
return hres; }
// static
void __cdecl CRBDebug::TraceMsg(DWORD dwFlags, LPTSTR pszMsg, ...) { HRESULT hres = S_OK;
if (!_fInited) { hres = _Init(); }
if (SUCCEEDED(hres)) { if ((_dwTraceFlags & dwFlags) && (TF_NOFILEANDLINE != (_dwTraceFlags & dwFlags))) { if (!((_dwTraceFlags & TF_NOFILEANDLINE) || (dwFlags & TF_NOFILEANDLINE))) { // File and line
_Trace(_szFileAndLine); } { TCHAR szBuf[4096]; va_list vArgs;
va_start(vArgs, pszMsg);
wvsprintf(szBuf, pszMsg, vArgs);
va_end(vArgs);
lstrcat(szBuf, TEXT("\r\n"));
_Trace(szBuf); } } }
LeaveCriticalSection(&_cs); }
// static
void CRBDebug::SetTraceFileAndLine(LPCSTR pszFile, const int iLine) { HRESULT hres = S_OK;
if (!_fInited) { hres = _Init(); }
EnterCriticalSection(&_cs);
if (SUCCEEDED(hres)) { LPTSTR pszFinal; WCHAR szwBuf[MAX_PATH + 12 + 17]; CHAR szBuf[MAX_PATH + 12 + 17]; int c = lstrlenA(pszFile); LPCSTR pszFileName; DWORD dwTimeOffset = 0;
while (c && ('\\' != *(pszFile + c))) { --c; }
pszFileName = pszFile + c + 1;
if (_dwTraceFlags & TF_TIME) { DWORD dwTick = GetTickCount(); DWORD dwMilliSec = dwTick % 1000;
dwTick -= dwMilliSec; dwTick /= 1000; DWORD dwSec = dwTick % 60;
dwTick -= dwSec; dwTick /= 60; DWORD dwMin = dwTick % 60;
dwTick -= dwMin; dwTick /= 60; DWORD dwHour = dwTick;
wsprintfA(szBuf, "{%04d:%02d:%02d.%03d}", dwHour, dwMin, dwSec, dwMilliSec);
dwTimeOffset = 16; }
if (_dwTraceFlags & TF_THREADID) { wsprintfA(szBuf + dwTimeOffset, "~0x%08X~[%s, %d]", GetCurrentThreadId(), pszFileName, iLine); } else { wsprintfA(szBuf + dwTimeOffset, "[%s, %d] ", pszFileName, iLine); } #ifdef UNICODE
pszFinal = szwBuf;
MultiByteToWideChar(CP_ACP, 0, szBuf, lstrlenA(szBuf) + 1, szwBuf, sizeof(szwBuf) / sizeof(WCHAR)); #else
pszFinal = szBuf; #endif
lstrcpyn(_szFileAndLine, pszFinal, ARRAYSIZE(_szFileAndLine)); } }
void CRBDebug::_Trace(LPTSTR pszMsg) { if (RBD_TRACE_OUTPUTDEBUG & _dwFlags) { OutputDebugString(pszMsg); }
#ifdef UNICODE
if (RBD_TRACE_TOFILE & _dwFlags) #else
if ((RBD_TRACE_TOFILE & _dwFlags) || (RBD_TRACE_TOFILEANSI & _dwFlags)) #endif
{ DWORD dwWritten = 0;
WriteFile(_hfileTraceFile, pszMsg, lstrlen(pszMsg) * sizeof(TCHAR), &dwWritten, NULL); } else { #ifdef UNICODE
if (RBD_TRACE_TOFILEANSI & _dwFlags) { CHAR szBuf[4096]; DWORD dwWritten = 0;
WideCharToMultiByte(CP_ACP, 0, pszMsg, (lstrlen(pszMsg) + 1) * sizeof(WCHAR), szBuf, sizeof(szBuf), NULL, NULL);
WriteFile(_hfileTraceFile, szBuf, lstrlenA(szBuf), &dwWritten, NULL); } #endif
}
if (RBD_TRACE_TOPIPE & _dwFlags) { CallNamedPipe(_pszTracePipe, pszMsg, lstrlen(pszMsg) * sizeof(TCHAR), NULL, 0, NULL, NMPWAIT_NOWAIT); } }
// static
HRESULT CRBDebug::Init() { return CRBDebug::_Init(); }
|