123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636 |
- /*******************************************************************************
- * SPDebug.h *
- *-----------*
- * Description:
- * This header file contains debug output services for SAPI5
- *-------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- *******************************************************************************/
- #pragma once
- #include <TCHAR.h>
- #include <crtdbg.h>
- #ifdef ASSERT_WITH_STACK
- #include "AssertWithStack.h"
- #endif
- const TCHAR g_szSpDebugKey[] = _T("SPDebug");
- const TCHAR g_szSpDebugFuncTraceReportMode[] = _T("FuncTraceMode");
- const TCHAR g_szSpDebugFuncTraceReportFile[] = _T("FuncTraceFile");
- const TCHAR g_szSpDebugParamInfoReportMode[] = _T("ParamInfoMode");
- const TCHAR g_szSpDebugParamInfoReportFile[] = _T("ParamInfoFile");
- const TCHAR g_szSpDebugDumpInfoReportMode[] = _T("DumpInfoMode");
- const TCHAR g_szSpDebugDumpInfoReportFile[] = _T("DumpInfoFile");
- const TCHAR g_szSpDebugAssertReportMode[] = _T("AssertMode");
- const TCHAR g_szSpDebugAssertReportFile[] = _T("AssertFile");
- const TCHAR g_szSpDebugHRFailReportMode[] = _T("HRFailMode");
- const TCHAR g_szSpDebugHRFailReportFile[] = _T("HRFailFile");
- const TCHAR g_szSpDebugAssertSettingsReReadEachTime[] = _T("AssertSettingsReReadEachTime");
- const TCHAR g_szSpDebugServerOnStart[] = _T("DebugServerOnStart");
- const TCHAR g_szSpDebugClientOnStart[] = _T("DebugClientOnStart");
- const TCHAR g_szSpDebugLog[] = _T("c:\\spdebug.log");
- #ifdef _DEBUG
- class CSpDebug
- {
- public:
-
- CSpDebug()
- {
- m_mutex = NULL;
- m_reportModePrev = -1;
- m_hfilePrev = NULL;
- Read();
- }
- ~CSpDebug()
- {
- if (m_mutex != NULL)
- {
- CloseHandle(m_mutex);
- }
- }
-
- BOOL FuncTrace(BOOL fEnter = TRUE)
- {
- return fEnter
- ? Enter(_CRT_WARN, m_FuncTraceMode, m_szFuncTraceFile)
- : Leave();
- }
-
- BOOL ParamInfo(BOOL fEnter = TRUE)
- {
- return fEnter
- ? Enter(_CRT_WARN, m_ParamInfoMode, m_szParamInfoFile)
- : Leave();
- }
-
- BOOL DumpInfo(BOOL fEnter = TRUE)
- {
- return fEnter
- ? Enter(_CRT_WARN, m_DumpInfoMode, m_szDumpInfoFile)
- : Leave();
- }
-
- BOOL Assert(BOOL fEnter = TRUE)
- {
- if (m_fAssertSettingsReReadEachTime)
- Read();
- return fEnter
- ? Enter(_CRT_ASSERT, m_AssertMode, m_szAssertFile)
- : Leave();
- }
-
- BOOL HRFail(BOOL fEnter = TRUE)
- {
- return fEnter
- ? Enter(_CRT_WARN, m_HRFailMode, m_szHRFailFile)
- : Leave();
- }
-
- BOOL DebugServerOnStart()
- {
- return m_fDebugServerOnStart;
- }
-
- BOOL DebugClientOnStart()
- {
- return m_fDebugClientOnStart;
- }
-
- private:
- void Read()
- {
- HKEY hkeyDebug;
- RegCreateKeyEx(
- HKEY_CLASSES_ROOT,
- g_szSpDebugKey,
- 0,
- NULL,
- 0,
- KEY_READ | KEY_WRITE,
- NULL,
- &hkeyDebug,
- NULL);
- if (hkeyDebug == NULL)
- {
- RegCreateKeyEx(
- HKEY_CLASSES_ROOT,
- g_szSpDebugKey,
- 0,
- NULL,
- 0,
- KEY_READ,
- NULL,
- &hkeyDebug,
- NULL);
- }
-
- DWORD dw = sizeof(m_fAssertSettingsReReadEachTime);
- if (RegQueryValueEx(
- hkeyDebug,
- g_szSpDebugAssertSettingsReReadEachTime,
- NULL,
- NULL,
- LPBYTE(&m_fAssertSettingsReReadEachTime),
- &dw) != ERROR_SUCCESS)
- {
- m_fAssertSettingsReReadEachTime = FALSE;
- RegSetValueEx(
- hkeyDebug,
- g_szSpDebugAssertSettingsReReadEachTime,
- NULL,
- REG_DWORD,
- LPBYTE(&m_fAssertSettingsReReadEachTime),
- sizeof(m_fAssertSettingsReReadEachTime));
- }
-
- ReadFor(
- hkeyDebug,
- g_szSpDebugFuncTraceReportMode,
- g_szSpDebugFuncTraceReportFile,
- &m_FuncTraceMode,
- m_szFuncTraceFile,
- 0,
- g_szSpDebugLog);
- ReadFor(
- hkeyDebug,
- g_szSpDebugParamInfoReportMode,
- g_szSpDebugParamInfoReportFile,
- &m_ParamInfoMode,
- m_szParamInfoFile,
- 0,
- g_szSpDebugLog);
- ReadFor(
- hkeyDebug,
- g_szSpDebugDumpInfoReportMode,
- g_szSpDebugDumpInfoReportFile,
- &m_DumpInfoMode,
- m_szDumpInfoFile,
- _CRTDBG_MODE_DEBUG,
- g_szSpDebugLog);
- ReadFor(
- hkeyDebug,
- g_szSpDebugAssertReportMode,
- g_szSpDebugAssertReportFile,
- &m_AssertMode,
- m_szAssertFile,
- _CRTDBG_MODE_WNDW,
- g_szSpDebugLog);
- ReadFor(
- hkeyDebug,
- g_szSpDebugHRFailReportMode,
- g_szSpDebugHRFailReportFile,
- &m_HRFailMode,
- m_szHRFailFile,
- _CRTDBG_MODE_DEBUG,
- g_szSpDebugLog);
-
- dw = sizeof(m_fDebugServerOnStart);
- if (RegQueryValueEx(
- hkeyDebug,
- g_szSpDebugServerOnStart,
- NULL,
- NULL,
- LPBYTE(&m_fDebugServerOnStart),
- &dw) != ERROR_SUCCESS)
- {
- m_fDebugServerOnStart = FALSE;
- RegSetValueEx(
- hkeyDebug,
- g_szSpDebugServerOnStart,
- NULL,
- REG_DWORD,
- LPBYTE(&m_fDebugServerOnStart),
- sizeof(m_fDebugServerOnStart));
- }
-
- dw = sizeof(m_fDebugClientOnStart);
- if (RegQueryValueEx(
- hkeyDebug,
- g_szSpDebugClientOnStart,
- NULL,
- NULL,
- LPBYTE(&m_fDebugClientOnStart),
- &dw) != ERROR_SUCCESS)
- {
- m_fDebugClientOnStart = FALSE;
- RegSetValueEx(
- hkeyDebug,
- g_szSpDebugClientOnStart,
- NULL,
- REG_DWORD,
- LPBYTE(&m_fDebugClientOnStart),
- sizeof(m_fDebugClientOnStart));
- }
-
- RegCloseKey(hkeyDebug);
- }
- void ReadFor(
- HKEY hkey,
- const TCHAR * pszModeValueName,
- const TCHAR * pszFileValueName,
- DWORD * pdwModeValue,
- TCHAR * pszFileValue,
- DWORD dwDefaultModeValue,
- const TCHAR * pszDefaultFileValue)
- {
- DWORD dw = sizeof(*pdwModeValue);
- if (RegQueryValueEx(
- hkey,
- pszModeValueName,
- NULL,
- NULL,
- LPBYTE(pdwModeValue),
- &dw) != ERROR_SUCCESS)
- {
- *pdwModeValue = dwDefaultModeValue;
- RegSetValueEx(
- hkey,
- pszModeValueName,
- NULL,
- REG_DWORD,
- LPBYTE(pdwModeValue),
- sizeof(*pdwModeValue));
- }
-
- dw = MAX_PATH;
- if (RegQueryValueEx(
- hkey,
- pszFileValueName,
- NULL,
- NULL,
- LPBYTE(pszFileValue),
- &dw) != ERROR_SUCCESS)
- {
- _tcscpy(pszFileValue, pszDefaultFileValue);
- RegSetValueEx(
- hkey,
- pszFileValueName,
- NULL,
- REG_SZ,
- LPBYTE(pszFileValue),
- MAX_PATH);
- }
- }
- BOOL Enter(int reportType, DWORD &reportMode, TCHAR * pszFile)
- {
- if (reportMode != 0)
- {
- // We'll hold the mutex, until the caller also calls Leave
- if (m_mutex == NULL)
- {
- m_mutex = CreateMutex(NULL, FALSE, _T("SpDebug"));
- }
- WaitForSingleObject(m_mutex, INFINITE);
-
- m_reportType = reportType;
- m_reportModePrev = _CrtSetReportMode(reportType, reportMode);
- if (reportMode & _CRTDBG_MODE_FILE)
- {
- HANDLE hfile = CreateFile(
- pszFile,
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ,
- NULL,
- OPEN_ALWAYS,
- 0,
- NULL);
- SetFilePointer(hfile, 0, NULL, FILE_END);
- m_hfilePrev = (_HFILE)_CrtSetReportFile(reportType, (_HFILE)hfile);
- }
-
- return TRUE;
- }
- return FALSE;
- }
- BOOL Leave()
- {
- int reportMode = _CrtSetReportMode(m_reportType, m_reportModePrev);
- if (reportMode & _CRTDBG_MODE_FILE)
- {
- CloseHandle((_HFILE)_CrtSetReportFile(m_reportType, (_HFILE)m_hfilePrev));
- }
-
- ReleaseMutex(m_mutex);
- return TRUE;
- }
-
- private:
- HANDLE m_mutex;
-
- int m_reportType;
- int m_reportModePrev;
- _HFILE m_hfilePrev;
-
- BOOL m_fAssertSettingsReReadEachTime;
-
- DWORD m_FuncTraceMode;
- TCHAR m_szFuncTraceFile[MAX_PATH + 1];
- DWORD m_ParamInfoMode;
- TCHAR m_szParamInfoFile[MAX_PATH + 1];
- DWORD m_DumpInfoMode;
- TCHAR m_szDumpInfoFile[MAX_PATH + 1];
- DWORD m_AssertMode;
- TCHAR m_szAssertFile[MAX_PATH + 1];
- DWORD m_HRFailMode;
- TCHAR m_szHRFailFile[MAX_PATH + 1];
-
- BOOL m_fDebugServerOnStart;
- BOOL m_fDebugClientOnStart;
- };
- inline CSpDebug *PSpDebug()
- {
- static CSpDebug debug;
- return &debug;
- }
- class CSpFuncTrace
- {
- public:
-
- CSpFuncTrace(PCHAR pFuncName)
- {
- m_pFuncName = pFuncName;
- if (PSpDebug()->FuncTrace())
- {
- _RPT1( _CRT_WARN, "\nEntering Function: %s\n", m_pFuncName );
- PSpDebug()->FuncTrace(FALSE);
- }
- }
-
- ~CSpFuncTrace()
- {
- if (PSpDebug()->FuncTrace())
- {
- _RPT1( _CRT_WARN, "Leaving Function: %s\n", m_pFuncName );
- PSpDebug()->FuncTrace(FALSE);
- }
- }
-
- private:
- PCHAR m_pFuncName;
- };
- #endif // _DEBUG
- //=== User macros ==============================================================
- #ifdef _DEBUG
- #define SPDBG_FUNC(name) \
- CSpFuncTrace functrace(name)
- #if defined(ASSERT_WITH_STACK) && !defined(_WIN64)
- #define SPDBG_REPORT_ON_FAIL(hr) \
- do \
- { \
- HRESULT _hr = (hr); \
- if (FAILED(_hr) && PSpDebug()->HRFail()) \
- { \
- SYSTEMTIME sysTime; \
- GetLocalTime(&sysTime); \
- CHAR pszHrWithTime[100]; \
- sprintf(pszHrWithTime, "%lX\n\n%d.%d.%d %02d:%02d:%02d", \
- _hr, \
- sysTime.wMonth,sysTime.wDay,sysTime.wYear, \
- sysTime.wHour,sysTime.wMinute,sysTime.wSecond); \
- PCHAR pszStack = \
- (PCHAR)_alloca( \
- cchMaxAssertStackLevelStringLen * \
- cfrMaxAssertStackLevels + 1); \
- GetStringFromStackLevels(0, 10, pszStack); \
- _RPT4(_CRT_WARN, \
- "%s(%d): Failed HR = %s\n\n%s\n", \
- __FILE__, \
- __LINE__, \
- pszHrWithTime, \
- pszStack); \
- PSpDebug()->HRFail(FALSE); \
- } \
- } while (0)
- #else // ASSERT_WITH_STACK & !_WIN64
- #define SPDBG_REPORT_ON_FAIL(hr) \
- do \
- { \
- HRESULT _hr = (hr); \
- if (FAILED(_hr) && PSpDebug()->HRFail()) \
- { \
- _RPT3(_CRT_WARN, "%s(%d): Failed HR = %lX\n", __FILE__, __LINE__, (_hr) );\
- PSpDebug()->HRFail(FALSE); \
- } \
- } while (0)
- #endif // ASSERT_WITH_STACK
- #define SPDBG_ASSERT(expr) \
- do \
- { \
- if (!(expr)) \
- { \
- if (PSpDebug()->Assert()) \
- { \
- _ASSERTE( expr ); \
- PSpDebug()->Assert(FALSE); \
- } \
- } \
- } \
- while (0)
- #define SPDBG_VERIFY(expr) \
- SPDBG_ASSERT(expr)
- #define SPDBG_PMSG0(format) \
- do \
- { \
- if (PSpDebug()->ParamInfo()) \
- { \
- _RPT0(_CRT_WARN, format); \
- PSpDebug()->ParamInfo(FALSE); \
- } \
- } while (0)
- #define SPDBG_PMSG1(format, arg1) \
- do \
- { \
- if (PSpDebug()->ParamInfo()) \
- { \
- _RPT1(_CRT_WARN, format, arg1); \
- PSpDebug()->ParamInfo(FALSE); \
- } \
- } while (0)
- #define SPDBG_PMSG2(format, arg1, arg2) \
- do \
- { \
- if (PSpDebug()->ParamInfo()) \
- { \
- _RPT2(_CRT_WARN, format, arg1, arg2); \
- PSpDebug()->ParamInfo(FALSE); \
- } \
- } while (0)
- #define SPDBG_PMSG3(format, arg1, arg2, arg3) \
- do \
- { \
- if (PSpDebug()->ParamInfo()) \
- { \
- _RPT3(_CRT_WARN, format, arg1, arg2, arg3); \
- PSpDebug()->ParamInfo(FALSE); \
- } \
- } while (0)
- #define SPDBG_PMSG4(format, arg1, arg2, arg3, arg4) \
- do \
- { \
- if (PSpDebug()->ParamInfo()) \
- { \
- _RPT4(_CRT_WARN, format, arg1, arg2, arg3, arg4); \
- PSpDebug()->ParamInfo(FALSE); \
- } \
- } while (0)
-
- #define SPDBG_DMSG0(format) \
- do \
- { \
- if (PSpDebug()->DumpInfo()) \
- { \
- _RPT0(_CRT_WARN, format); \
- PSpDebug()->DumpInfo(FALSE); \
- } \
- } while (0)
- #define SPDBG_DMSG1(format, arg1) \
- do \
- { \
- if (PSpDebug()->DumpInfo()) \
- { \
- _RPT1(_CRT_WARN, format, arg1); \
- PSpDebug()->DumpInfo(FALSE); \
- } \
- } while (0)
- #define SPDBG_DMSG2(format, arg1, arg2) \
- do \
- { \
- if (PSpDebug()->DumpInfo()) \
- { \
- _RPT2(_CRT_WARN, format, arg1, arg2); \
- PSpDebug()->DumpInfo(FALSE); \
- } \
- } while (0)
- #define SPDBG_DMSG3(format, arg1, arg2, arg3) \
- do \
- { \
- if (PSpDebug()->DumpInfo()) \
- { \
- _RPT3(_CRT_WARN, format, arg1, arg2, arg3); \
- PSpDebug()->DumpInfo(FALSE); \
- } \
- } while (0)
- #define SPDBG_DMSG4(format, arg1, arg2, arg3, arg4) \
- do \
- { \
- if (PSpDebug()->DumpInfo()) \
- { \
- _RPT4(_CRT_WARN, format, arg1, arg2, arg3, arg4); \
- PSpDebug()->DumpInfo(FALSE); \
- } \
- } while (0)
- #define SPDBG_RETURN(hr) \
- { \
- HRESULT __hr = (hr); \
- if (FAILED(__hr)) \
- { \
- SPDBG_REPORT_ON_FAIL(__hr); \
- } \
- return __hr; \
- }
- #define SPDBG_DEBUG_SERVER_ON_START() \
- { \
- if (PSpDebug()->DebugServerOnStart()) \
- { \
- if (MessageBox( \
- GetDesktopWindow(), \
- _T("Attach Debugger to the SAPI Server process?"), \
- _T("SAPI"), \
- MB_YESNO) == IDYES) \
- { \
- USES_CONVERSION; \
- TCHAR szCommand[MAX_PATH + 1]; \
- wsprintf( \
- szCommand, \
- _T("msdev -p %d"), \
- GetCurrentProcessId()); \
- system(T2A(szCommand)); \
- } \
- } \
- }
- #define SPDBG_DEBUG_CLIENT_ON_START() \
- { \
- if (PSpDebug()->DebugClientOnStart()) \
- { \
- TCHAR szModule[MAX_PATH + 1]; \
- szModule[0] = '\0'; \
- TCHAR * pszSapiServer = \
- _T("sapisvr.exe"); \
- GetModuleFileName( \
- NULL, \
- szModule, \
- MAX_PATH); \
- if ((_tcslen(szModule) <= \
- _tcslen(pszSapiServer) || \
- _tcsicmp( \
- szModule + \
- _tcslen(szModule) - \
- _tcslen(pszSapiServer), \
- pszSapiServer) != 0) && \
- MessageBox( \
- GetDesktopWindow(), \
- _T("Attach Debugger to the SAPI Client process?"), \
- _T("SAPI"), \
- MB_YESNO) == IDYES) \
- { \
- USES_CONVERSION; \
- TCHAR szCommand[MAX_PATH + 1]; \
- wsprintf( \
- szCommand, \
- _T("msdev -p %d"), \
- GetCurrentProcessId()); \
- system(T2A(szCommand)); \
- } \
- } \
- }
-
- #else // _DEBUG
- #define SPDBG_FUNC(name)
- #define SPDBG_REPORT_ON_FAIL(hr)
- #define SPDBG_ASSERT(expr)
- #define SPDBG_VERIFY(expr) (expr)
- #define SPDBG_PMSG0(format)
- #define SPDBG_PMSG1(format, arg1)
- #define SPDBG_PMSG2(format, arg1, arg2)
- #define SPDBG_PMSG3(format, arg1, arg2, arg3)
- #define SPDBG_PMSG4(format, arg1, arg2, arg3, arg4)
- #define SPDBG_DMSG0(format)
- #define SPDBG_DMSG1(format, arg1)
- #define SPDBG_DMSG2(format, arg1, arg2)
- #define SPDBG_DMSG3(format, arg1, arg2, arg3)
- #define SPDBG_DMSG4(format, arg1, arg2, arg3, arg4)
- #define SPDBG_RETURN(hr) return (hr)
- #define SPDBG_DEBUG_SERVER_ON_START()
- #define SPDBG_DEBUG_CLIENT_ON_START()
- #endif // _DEBUG
|