mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
362 lines
8.7 KiB
362 lines
8.7 KiB
#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();
|
|
}
|