Leaked source code of windows server 2003
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.

850 lines
26 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 1998
  4. *
  5. * TITLE: WIADBGCL.CPP
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: ShaunIv
  10. *
  11. * DATE: 9/4/1999
  12. *
  13. * DESCRIPTION: Debug client. Linked statically.
  14. *
  15. *******************************************************************************/
  16. #include "precomp.h"
  17. #pragma hdrstop
  18. #include <windows.h>
  19. #include "simreg.h"
  20. #include "wiadebug.h"
  21. #include "tchar.h"
  22. #define DOESNT_MATTER_WHAT_THIS_IS ((UINT)7)
  23. #define BACK_SLASH TEXT("\\")
  24. //
  25. // Static class data members
  26. //
  27. CWiaDebugClient g_TheDebugClient;
  28. //
  29. // Sole constructor
  30. //
  31. CWiaDebugClient::CWiaDebugClient(void)
  32. : m_hDebugModule(NULL),
  33. m_hCurrentModuleInstance(NULL),
  34. m_pfnIncrementDebugIndentLevel(NULL),
  35. m_pfnDecrementDebugIndentLevel(NULL),
  36. m_pfnPrintDebugMessageW(NULL),
  37. m_pfnPrintDebugMessageA(NULL),
  38. m_pfnGetDebugMask(NULL),
  39. m_pfnSetDebugMask(NULL),
  40. m_pfnAllocateDebugColor(NULL),
  41. m_pfnGetStringFromGuidA(NULL),
  42. m_pfnGetStringFromGuidW(NULL),
  43. m_pfnDoRecordAllocation(NULL),
  44. m_pfnDoRecordFree(NULL),
  45. m_pfnDoReportLeaks(NULL),
  46. m_crForegroundColor(DEFAULT_DEBUG_COLOR),
  47. m_dwModuleDebugMask(0),
  48. m_bHaveModuleInformation(false),
  49. m_bDebugLibLoadAttempted(false),
  50. m_pfnGetStringFromMsgA(NULL),
  51. m_pfnGetStringFromMsgW(NULL)
  52. {
  53. CAutoCriticalSection cs(m_CriticalSection);
  54. m_szModuleNameW[0] = 0;
  55. m_szModuleNameA[0] = 0;
  56. if (LoadWiaDebugExports())
  57. {
  58. InitializeModuleInfo();
  59. }
  60. }
  61. template <class T>
  62. static T GetProc( HINSTANCE hModule, LPCSTR pszFunctionName )
  63. {
  64. return reinterpret_cast<T>(GetProcAddress( hModule, pszFunctionName ));
  65. }
  66. bool CWiaDebugClient::LoadWiaDebugExports()
  67. {
  68. CAutoCriticalSection cs(m_CriticalSection);
  69. //
  70. // No need to call this more than once, so return true if the
  71. // load was successful, false if it was not
  72. //
  73. if (m_bDebugLibLoadAttempted)
  74. {
  75. return (NULL != m_hDebugModule);
  76. }
  77. //
  78. // Prevent future loading attempts
  79. //
  80. m_bDebugLibLoadAttempted = true;
  81. //
  82. // Assume failure
  83. //
  84. bool bResult = false;
  85. //
  86. // Get the system directory path
  87. //
  88. TCHAR szDllName[MAX_PATH] = {0};
  89. if (GetSystemDirectory( szDllName, ARRAYSIZE(szDllName)))
  90. {
  91. //
  92. // Make sure our string can hold the full path to the DLL
  93. //
  94. if ((lstrlen(szDllName) + lstrlen(DEBUG_DLL_NAME) + lstrlen(BACK_SLASH)) < ARRAYSIZE(szDllName))
  95. {
  96. //
  97. // Construct the full path to the DLL
  98. //
  99. lstrcat( szDllName, BACK_SLASH );
  100. lstrcat( szDllName, DEBUG_DLL_NAME );
  101. //
  102. // Load the library
  103. //
  104. m_hDebugModule = LoadLibrary( DEBUG_DLL_NAME );
  105. if (m_hDebugModule)
  106. {
  107. m_pfnIncrementDebugIndentLevel = GetProc<IncrementDebugIndentLevelProc>( m_hDebugModule, INCREMENT_DEBUG_INDENT_LEVEL_NAME );
  108. m_pfnDecrementDebugIndentLevel = GetProc<DecrementDebugIndentLevelProc>( m_hDebugModule, DECREMENT_DEBUG_INDENT_LEVEL_NAME );
  109. m_pfnPrintDebugMessageA = GetProc<PrintDebugMessageAProc>( m_hDebugModule, PRINT_DEBUG_MESSAGE_NAMEA );
  110. m_pfnPrintDebugMessageW = GetProc<PrintDebugMessageWProc>( m_hDebugModule, PRINT_DEBUG_MESSAGE_NAMEW );
  111. m_pfnGetDebugMask = GetProc<GetDebugMaskProc>( m_hDebugModule, GET_DEBUG_MASK_NAME );
  112. m_pfnSetDebugMask = GetProc<SetDebugMaskProc>( m_hDebugModule, SET_DEBUG_MASK_NAME );
  113. m_pfnAllocateDebugColor = GetProc<AllocateDebugColorProc>( m_hDebugModule, ALLOCATE_DEBUG_COLOR_NAME );
  114. m_pfnGetStringFromGuidA = GetProc<GetStringFromGuidAProc>( m_hDebugModule, GET_STRING_FROM_GUID_NAMEA );
  115. m_pfnGetStringFromGuidW = GetProc<GetStringFromGuidWProc>( m_hDebugModule, GET_STRING_FROM_GUID_NAMEW );
  116. m_pfnDoRecordAllocation = GetProc<DoRecordAllocationProc>( m_hDebugModule, DO_RECORD_ALLOCATION );
  117. m_pfnDoRecordFree = GetProc<DoRecordFreeProc>( m_hDebugModule, DO_RECORD_FREE );
  118. m_pfnDoReportLeaks = GetProc<DoReportLeaksProc>( m_hDebugModule, DO_REPORT_LEAKS );
  119. m_pfnGetStringFromMsgA = GetProc<GetStringFromMsgAProc>( m_hDebugModule, GET_STRING_FROM_MSGA );
  120. m_pfnGetStringFromMsgW = GetProc<GetStringFromMsgWProc>( m_hDebugModule, GET_STRING_FROM_MSGW );
  121. bResult = (m_pfnIncrementDebugIndentLevel &&
  122. m_pfnDecrementDebugIndentLevel &&
  123. m_pfnPrintDebugMessageA &&
  124. m_pfnPrintDebugMessageW &&
  125. m_pfnGetDebugMask &&
  126. m_pfnSetDebugMask &&
  127. m_pfnAllocateDebugColor &&
  128. m_pfnGetStringFromGuidA &&
  129. m_pfnGetStringFromGuidW &&
  130. m_pfnDoRecordAllocation &&
  131. m_pfnDoRecordFree &&
  132. m_pfnDoReportLeaks &&
  133. m_pfnGetStringFromMsgA &&
  134. m_pfnGetStringFromMsgW);
  135. }
  136. }
  137. }
  138. return bResult;
  139. }
  140. bool CWiaDebugClient::IsInitialized()
  141. {
  142. bool bResult = false;
  143. CAutoCriticalSection cs(m_CriticalSection);
  144. if (LoadWiaDebugExports())
  145. {
  146. bResult = InitializeModuleInfo();
  147. }
  148. return bResult;
  149. }
  150. LPTSTR CWiaDebugClient::GetJustTheFileName( LPCTSTR pszPath, LPTSTR pszFileName, int nMaxLen )
  151. {
  152. //
  153. // Make sure we have valid arguments
  154. //
  155. if (!pszPath || !pszFileName || !nMaxLen)
  156. {
  157. return NULL;
  158. }
  159. //
  160. // Initialize the return string
  161. //
  162. lstrcpy( pszFileName, TEXT("") );
  163. //
  164. // Loop through the filename, looking for the last \
  165. //
  166. LPCTSTR pszLastBackslash = NULL;
  167. for (LPCTSTR pszCurr=pszPath;pszCurr && *pszCurr;pszCurr = CharNext(pszCurr))
  168. {
  169. if (TEXT('\\') == *pszCurr)
  170. {
  171. pszLastBackslash = pszCurr;
  172. }
  173. }
  174. //
  175. // If we found any \'s, point to the next character
  176. //
  177. if (pszLastBackslash)
  178. {
  179. pszLastBackslash = CharNext(pszLastBackslash);
  180. }
  181. //
  182. // Otherwise, we will copy the entire path
  183. //
  184. else
  185. {
  186. pszLastBackslash = pszPath;
  187. }
  188. //
  189. // If we have a valid starting point, copy the string to the target buffer and terminate it
  190. //
  191. if (pszLastBackslash)
  192. {
  193. lstrcpyn( pszFileName, pszLastBackslash, nMaxLen-1 );
  194. pszFileName[nMaxLen-1] = TEXT('\0');
  195. }
  196. return pszFileName;
  197. }
  198. bool CWiaDebugClient::InitializeModuleInfo()
  199. {
  200. CAutoCriticalSection cs(m_CriticalSection);
  201. //
  202. // If we've already been initialized, return true
  203. //
  204. if (m_bHaveModuleInformation)
  205. {
  206. return true;
  207. }
  208. //
  209. // If we haven't got a valid HINSTANCE, return false
  210. //
  211. if (!m_hCurrentModuleInstance)
  212. {
  213. return false;
  214. }
  215. //
  216. // Make sure we start out with empty module name strings
  217. //
  218. m_szModuleNameW[0] = 0;
  219. m_szModuleNameA[0] = 0;
  220. //
  221. // Get default debug setting
  222. //
  223. m_dwModuleDebugMask = CSimpleReg( HKEY_LOCAL_MACHINE, DEBUG_REGISTRY_PATH, false, KEY_READ ).Query( DEBUG_REGISTRY_DEFAULT_FLAGS, 0 );
  224. //
  225. // Initialize the module name, in case we can't determine it. It is OK
  226. // that wsprintfW will return ERROR_NOT_IMPLEMENTED under win9x, since
  227. // we won't be using this variable at all on this OS
  228. //
  229. wsprintfW( m_szModuleNameW, L"0x%08X", GetCurrentProcessId() );
  230. wsprintfA( m_szModuleNameA, "0x%08X", GetCurrentProcessId() );
  231. //
  232. // Get the next available color
  233. //
  234. m_crForegroundColor = m_pfnAllocateDebugColor();
  235. //
  236. // Get the module name
  237. //
  238. TCHAR szModulePathName[MAX_PATH] = TEXT("");
  239. if (GetModuleFileName( m_hCurrentModuleInstance, szModulePathName, ARRAYSIZE(szModulePathName)))
  240. {
  241. //
  242. // Get rid of the path
  243. //
  244. TCHAR szFilename[MAX_PATH] = TEXT("");
  245. GetJustTheFileName( szModulePathName, szFilename, ARRAYSIZE(szFilename) );
  246. //
  247. // Make sure we have a valid filename
  248. //
  249. if (lstrlen(szFilename))
  250. {
  251. m_dwModuleDebugMask = CSimpleReg( HKEY_LOCAL_MACHINE, DEBUG_REGISTRY_PATH_FLAGS, false, KEY_READ ).Query( szFilename, 0 );
  252. //
  253. // Save the ANSI and UNICODE versions of the module name
  254. //
  255. #ifdef UNICODE
  256. WideCharToMultiByte( CP_ACP, 0, szFilename, -1, m_szModuleNameA, ARRAYSIZE(m_szModuleNameA), NULL, NULL );
  257. lstrcpynW( m_szModuleNameW, szFilename, ARRAYSIZE(m_szModuleNameW) );
  258. #else
  259. MultiByteToWideChar( CP_ACP, 0, szFilename, -1, m_szModuleNameW, ARRAYSIZE(m_szModuleNameW) );
  260. lstrcpynA( m_szModuleNameA, szFilename, ARRAYSIZE(m_szModuleNameA) );
  261. #endif
  262. //
  263. // Success!
  264. //
  265. m_bHaveModuleInformation = true;
  266. //
  267. // Tell the debugger we're here. This way, the user can get the expected module name correct.
  268. //
  269. m_pfnPrintDebugMessageA( WiaDebugSeverityNormal, 0xFFFFFFFF, RGB(0xFF,0xFF,0xFF), RGB(0x00,0x00,0x00), m_szModuleNameA, "Created debug client" );
  270. }
  271. }
  272. return m_bHaveModuleInformation;
  273. }
  274. void CWiaDebugClient::Destroy(void)
  275. {
  276. CAutoCriticalSection cs(m_CriticalSection);
  277. //
  278. // NULL out all of the function pointers
  279. //
  280. m_pfnIncrementDebugIndentLevel = NULL;
  281. m_pfnDecrementDebugIndentLevel = NULL;
  282. m_pfnPrintDebugMessageA = NULL;
  283. m_pfnPrintDebugMessageW = NULL;
  284. m_pfnGetDebugMask = NULL;
  285. m_pfnSetDebugMask = NULL;
  286. m_pfnAllocateDebugColor = NULL;
  287. m_pfnGetStringFromGuidW = NULL;
  288. m_pfnGetStringFromGuidA = NULL;
  289. m_pfnDoRecordAllocation = NULL;
  290. m_pfnDoRecordFree = NULL;
  291. m_pfnDoReportLeaks = NULL;
  292. m_pfnGetStringFromMsgA = NULL;
  293. m_pfnGetStringFromMsgW = NULL;
  294. //
  295. // Unload the DLL
  296. //
  297. if (m_hDebugModule)
  298. {
  299. FreeLibrary( m_hDebugModule );
  300. m_hDebugModule = NULL;
  301. }
  302. m_bHaveModuleInformation = false;
  303. m_bDebugLibLoadAttempted = false;
  304. }
  305. CWiaDebugClient::~CWiaDebugClient(void)
  306. {
  307. CAutoCriticalSection cs(m_CriticalSection);
  308. Destroy();
  309. }
  310. DWORD CWiaDebugClient::GetDebugMask(void)
  311. {
  312. CAutoCriticalSection cs(m_CriticalSection);
  313. if (IsInitialized())
  314. {
  315. return m_pfnGetDebugMask();
  316. }
  317. return 0;
  318. }
  319. DWORD CWiaDebugClient::SetDebugMask( DWORD dwNewMask )
  320. {
  321. CAutoCriticalSection cs(m_CriticalSection);
  322. if (IsInitialized())
  323. {
  324. return m_pfnSetDebugMask( dwNewMask );
  325. }
  326. return 0;
  327. }
  328. int CWiaDebugClient::IncrementIndentLevel(void)
  329. {
  330. CAutoCriticalSection cs(m_CriticalSection);
  331. if (IsInitialized())
  332. {
  333. return m_pfnIncrementDebugIndentLevel();
  334. }
  335. return 0;
  336. }
  337. int CWiaDebugClient::DecrementIndentLevel(void)
  338. {
  339. CAutoCriticalSection cs(m_CriticalSection);
  340. if (IsInitialized())
  341. {
  342. return m_pfnDecrementDebugIndentLevel();
  343. }
  344. return 0;
  345. }
  346. void CWiaDebugClient::RecordAllocation( LPVOID pv, size_t Size )
  347. {
  348. CAutoCriticalSection cs(m_CriticalSection);
  349. if (IsInitialized())
  350. {
  351. m_pfnDoRecordAllocation( pv, Size );
  352. }
  353. }
  354. void CWiaDebugClient::RecordFree( LPVOID pv )
  355. {
  356. CAutoCriticalSection cs(m_CriticalSection);
  357. if (IsInitialized())
  358. {
  359. m_pfnDoRecordFree( pv );
  360. }
  361. }
  362. void CWiaDebugClient::ReportLeaks( VOID )
  363. {
  364. CAutoCriticalSection cs(m_CriticalSection);
  365. if (IsInitialized())
  366. {
  367. #ifdef UNICODE
  368. m_pfnDoReportLeaks(m_szModuleNameW);
  369. #else
  370. m_pfnDoReportLeaks(m_szModuleNameA);
  371. #endif
  372. }
  373. }
  374. CPushTraceMask::CPushTraceMask( DWORD dwTraceMask )
  375. : m_dwOldMask(0)
  376. {
  377. CAutoCriticalSection cs( g_TheDebugClient.m_CriticalSection );
  378. g_TheDebugClient.SetDebugMask( dwTraceMask );
  379. }
  380. CPushTraceMask::~CPushTraceMask(void)
  381. {
  382. CAutoCriticalSection cs( g_TheDebugClient.m_CriticalSection );
  383. g_TheDebugClient.SetDebugMask( m_dwOldMask );
  384. }
  385. CPushIndentLevel::CPushIndentLevel( LPCTSTR pszFmt, ... )
  386. : m_nIndentLevel(0)
  387. {
  388. CAutoCriticalSection cs( g_TheDebugClient.m_CriticalSection );
  389. m_nIndentLevel = g_TheDebugClient.IncrementIndentLevel();
  390. TCHAR szMsg[1024] = {0};
  391. va_list arglist;
  392. va_start( arglist, pszFmt );
  393. _vsntprintf( szMsg, ARRAYSIZE(szMsg)-1, pszFmt, arglist );
  394. va_end( arglist );
  395. g_TheDebugClient.PrintTraceMessage( TEXT("Entering function %s [Level %d]"), szMsg, m_nIndentLevel );
  396. }
  397. CPushIndentLevel::~CPushIndentLevel(void)
  398. {
  399. CAutoCriticalSection cs( g_TheDebugClient.m_CriticalSection );
  400. if (m_nIndentLevel)
  401. {
  402. g_TheDebugClient.DecrementIndentLevel();
  403. g_TheDebugClient.PrintTraceMessage( TEXT("") );
  404. }
  405. }
  406. CPushTraceMaskAndIndentLevel::CPushTraceMaskAndIndentLevel( DWORD dwTraceMask, LPCTSTR pszFmt, ... )
  407. : m_dwOldMask(0), m_nIndentLevel(0)
  408. {
  409. CAutoCriticalSection cs( g_TheDebugClient.m_CriticalSection );
  410. m_dwOldMask = g_TheDebugClient.SetDebugMask( dwTraceMask );
  411. m_nIndentLevel = g_TheDebugClient.IncrementIndentLevel();
  412. TCHAR szMsg[1024] = {0};
  413. va_list arglist;
  414. va_start( arglist, pszFmt );
  415. _vsntprintf( szMsg, ARRAYSIZE(szMsg)-1, pszFmt, arglist );
  416. va_end( arglist );
  417. g_TheDebugClient.PrintTraceMessage( TEXT("Entering function %s [Level %d]"), szMsg, m_nIndentLevel );
  418. }
  419. CPushTraceMaskAndIndentLevel::~CPushTraceMaskAndIndentLevel(void)
  420. {
  421. CAutoCriticalSection cs( g_TheDebugClient.m_CriticalSection );
  422. if (m_nIndentLevel)
  423. {
  424. g_TheDebugClient.DecrementIndentLevel();
  425. g_TheDebugClient.PrintTraceMessage( TEXT("") );
  426. g_TheDebugClient.SetDebugMask( m_dwOldMask );
  427. }
  428. }
  429. ////////////////////////////////////////////////////////////////
  430. // UNICODE Versions of the output functions
  431. ////////////////////////////////////////////////////////////////
  432. void CWiaDebugClient::PrintWarningMessage( LPCWSTR pszFmt, ... )
  433. {
  434. CAutoCriticalSection cs(m_CriticalSection);
  435. if (IsInitialized())
  436. {
  437. WCHAR szMsg[1024] = {0};
  438. va_list arglist;
  439. va_start( arglist, pszFmt );
  440. _vsnwprintf( szMsg, ARRAYSIZE(szMsg)-1, pszFmt, arglist );
  441. va_end( arglist );
  442. m_pfnPrintDebugMessageW( WiaDebugSeverityWarning, m_dwModuleDebugMask, WARNING_FOREGROUND_COLOR, WARNING_BACKGROUND_COLOR, m_szModuleNameW, szMsg );
  443. }
  444. }
  445. void CWiaDebugClient::PrintErrorMessage( LPCWSTR pszFmt, ... )
  446. {
  447. CAutoCriticalSection cs(m_CriticalSection);
  448. if (IsInitialized())
  449. {
  450. WCHAR szMsg[1024] = {0};
  451. va_list arglist;
  452. va_start( arglist, pszFmt );
  453. _vsnwprintf( szMsg, ARRAYSIZE(szMsg)-1, pszFmt, arglist );
  454. va_end( arglist );
  455. m_pfnPrintDebugMessageW( WiaDebugSeverityError, m_dwModuleDebugMask, ERROR_FOREGROUND_COLOR, ERROR_BACKGROUND_COLOR, m_szModuleNameW, szMsg );
  456. }
  457. }
  458. void CWiaDebugClient::PrintTraceMessage( LPCWSTR pszFmt, ... )
  459. {
  460. CAutoCriticalSection cs(m_CriticalSection);
  461. if (IsInitialized())
  462. {
  463. WCHAR szMsg[1024] = {0};
  464. va_list arglist;
  465. va_start( arglist, pszFmt );
  466. _vsnwprintf( szMsg, ARRAYSIZE(szMsg)-1, pszFmt, arglist );
  467. va_end( arglist );
  468. m_pfnPrintDebugMessageW( WiaDebugSeverityNormal, m_dwModuleDebugMask, m_crForegroundColor, DEFAULT_DEBUG_COLOR, m_szModuleNameW, szMsg );
  469. }
  470. }
  471. void CWiaDebugClient::PrintMessage( DWORD dwSeverity, COLORREF crForegroundColor, COLORREF crBackgroundColor, LPCWSTR pszFmt, ... )
  472. {
  473. CAutoCriticalSection cs(m_CriticalSection);
  474. if (IsInitialized())
  475. {
  476. WCHAR szMsg[1024] = {0};
  477. va_list arglist;
  478. va_start( arglist, pszFmt );
  479. _vsnwprintf( szMsg, ARRAYSIZE(szMsg)-1, pszFmt, arglist );
  480. va_end( arglist );
  481. m_pfnPrintDebugMessageW( dwSeverity, m_dwModuleDebugMask, crForegroundColor, crBackgroundColor, m_szModuleNameW, szMsg );
  482. }
  483. }
  484. void CWiaDebugClient::PrintHResult( HRESULT hr, LPCWSTR pszFmt, ... )
  485. {
  486. CAutoCriticalSection cs(m_CriticalSection);
  487. if (IsInitialized())
  488. {
  489. WCHAR szMsg[1024] = {0};
  490. va_list arglist;
  491. va_start( arglist, pszFmt );
  492. _vsnwprintf( szMsg, ARRAYSIZE(szMsg)-1, pszFmt, arglist );
  493. va_end( arglist );
  494. DWORD dwLen = 0;
  495. LPTSTR pMsgBuf = NULL;
  496. dwLen = ::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
  497. NULL, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  498. (LPWSTR)&pMsgBuf, 0, NULL);
  499. COLORREF crForegroundColor;
  500. COLORREF crBackgroundColor;
  501. DWORD dwSeverity;
  502. if (FAILED(hr))
  503. {
  504. crForegroundColor = ERROR_FOREGROUND_COLOR;
  505. crBackgroundColor = ERROR_BACKGROUND_COLOR;
  506. dwSeverity = WiaDebugSeverityError;
  507. }
  508. else if (S_OK == hr)
  509. {
  510. crForegroundColor = m_crForegroundColor;
  511. crBackgroundColor = DEFAULT_DEBUG_COLOR;
  512. dwSeverity = WiaDebugSeverityNormal;
  513. }
  514. else
  515. {
  516. crForegroundColor = WARNING_FOREGROUND_COLOR;
  517. crBackgroundColor = WARNING_BACKGROUND_COLOR;
  518. dwSeverity = WiaDebugSeverityWarning;
  519. }
  520. if (dwLen)
  521. {
  522. PrintMessage( dwSeverity, crForegroundColor, crBackgroundColor, TEXT("%ws: [0x%08X] %ws"), szMsg, hr, pMsgBuf );
  523. LocalFree(pMsgBuf);
  524. }
  525. else
  526. {
  527. PrintMessage( dwSeverity, crForegroundColor, crBackgroundColor, TEXT("%ws: Unable to format message [0x%08X]"), szMsg, hr );
  528. }
  529. }
  530. }
  531. void CWiaDebugClient::PrintGuid( const IID &iid, LPCWSTR pszFmt, ... )
  532. {
  533. CAutoCriticalSection cs(m_CriticalSection);
  534. if (IsInitialized())
  535. {
  536. WCHAR szMsg[1024]=L"";
  537. va_list arglist;
  538. va_start( arglist, pszFmt );
  539. ::wvsprintfW( szMsg, pszFmt, arglist );
  540. va_end( arglist );
  541. WCHAR szGuid[MAX_PATH]=L"";
  542. if (m_pfnGetStringFromGuidW( &iid, szGuid, sizeof(szGuid)/sizeof(szGuid[0]) ) )
  543. {
  544. PrintMessage( 0, m_crForegroundColor, DEFAULT_DEBUG_COLOR, TEXT("%ws: %ws"), szMsg, szGuid );
  545. }
  546. }
  547. }
  548. void CWiaDebugClient::PrintWindowMessage( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LPCWSTR szMessage )
  549. {
  550. CAutoCriticalSection cs(m_CriticalSection);
  551. if (IsInitialized())
  552. {
  553. WCHAR szWindowMessage[MAX_PATH]=L"";
  554. if (m_pfnGetStringFromMsgW( uMsg, szWindowMessage, sizeof(szWindowMessage)/sizeof(szWindowMessage[0]) ) )
  555. {
  556. PrintMessage( 0, m_crForegroundColor, DEFAULT_DEBUG_COLOR, TEXT("0x%p, %-30ws, 0x%p, 0x%p%ws%ws"), hWnd, szWindowMessage, wParam, lParam, (szMessage && lstrlenW(szMessage)) ? L" : " : L"", (szMessage && lstrlenW(szMessage)) ? szMessage : L"" );
  557. }
  558. }
  559. }
  560. ////////////////////////////////////////////////////////////////
  561. // ANSI Versions of the output functions
  562. ////////////////////////////////////////////////////////////////
  563. void CWiaDebugClient::PrintWarningMessage( LPCSTR pszFmt, ... )
  564. {
  565. CAutoCriticalSection cs(m_CriticalSection);
  566. if (IsInitialized())
  567. {
  568. CHAR szMsg[1024] = {0};
  569. va_list arglist;
  570. va_start( arglist, pszFmt );
  571. _vsnprintf( szMsg, ARRAYSIZE(szMsg)-1, pszFmt, arglist );
  572. va_end( arglist );
  573. m_pfnPrintDebugMessageA( WiaDebugSeverityWarning, m_dwModuleDebugMask, WARNING_FOREGROUND_COLOR, WARNING_BACKGROUND_COLOR, m_szModuleNameA, szMsg );
  574. }
  575. }
  576. void CWiaDebugClient::PrintErrorMessage( LPCSTR pszFmt, ... )
  577. {
  578. CAutoCriticalSection cs(m_CriticalSection);
  579. if (IsInitialized())
  580. {
  581. CHAR szMsg[1024] = {0};
  582. va_list arglist;
  583. va_start( arglist, pszFmt );
  584. _vsnprintf( szMsg, ARRAYSIZE(szMsg)-1, pszFmt, arglist );
  585. va_end( arglist );
  586. m_pfnPrintDebugMessageA( WiaDebugSeverityError, m_dwModuleDebugMask, ERROR_FOREGROUND_COLOR, ERROR_BACKGROUND_COLOR, m_szModuleNameA, szMsg );
  587. }
  588. }
  589. void CWiaDebugClient::PrintTraceMessage( LPCSTR pszFmt, ... )
  590. {
  591. CAutoCriticalSection cs(m_CriticalSection);
  592. if (IsInitialized())
  593. {
  594. CHAR szMsg[1024] = {0};
  595. va_list arglist;
  596. va_start( arglist, pszFmt );
  597. _vsnprintf( szMsg, ARRAYSIZE(szMsg)-1, pszFmt, arglist );
  598. va_end( arglist );
  599. m_pfnPrintDebugMessageA( WiaDebugSeverityNormal, m_dwModuleDebugMask, m_crForegroundColor, DEFAULT_DEBUG_COLOR, m_szModuleNameA, szMsg );
  600. }
  601. }
  602. void CWiaDebugClient::PrintMessage( DWORD dwSeverity, COLORREF crForegroundColor, COLORREF crBackgroundColor, LPCSTR pszFmt, ... )
  603. {
  604. CAutoCriticalSection cs(m_CriticalSection);
  605. if (IsInitialized())
  606. {
  607. CHAR szMsg[1024] = {0};
  608. va_list arglist;
  609. va_start( arglist, pszFmt );
  610. _vsnprintf( szMsg, ARRAYSIZE(szMsg)-1, pszFmt, arglist );
  611. va_end( arglist );
  612. m_pfnPrintDebugMessageA( dwSeverity, m_dwModuleDebugMask, crForegroundColor, crBackgroundColor, m_szModuleNameA, szMsg );
  613. }
  614. }
  615. void CWiaDebugClient::PrintHResult( HRESULT hr, LPCSTR pszFmt, ... )
  616. {
  617. CAutoCriticalSection cs(m_CriticalSection);
  618. if (IsInitialized())
  619. {
  620. CHAR szMsg[1024] = {0};
  621. va_list arglist;
  622. va_start( arglist, pszFmt );
  623. _vsnprintf( szMsg, ARRAYSIZE(szMsg)-1, pszFmt, arglist );
  624. va_end( arglist );
  625. DWORD dwLen = 0;
  626. LPTSTR pMsgBuf = NULL;
  627. dwLen = ::FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
  628. NULL, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  629. (LPSTR)&pMsgBuf, 0, NULL);
  630. COLORREF crForegroundColor;
  631. COLORREF crBackgroundColor;
  632. DWORD dwSeverity;
  633. if (FAILED(hr))
  634. {
  635. crForegroundColor = ERROR_FOREGROUND_COLOR;
  636. crBackgroundColor = ERROR_BACKGROUND_COLOR;
  637. dwSeverity = WiaDebugSeverityError;
  638. }
  639. else if (S_OK == hr)
  640. {
  641. crForegroundColor = m_crForegroundColor;
  642. crBackgroundColor = DEFAULT_DEBUG_COLOR;
  643. dwSeverity = WiaDebugSeverityNormal;
  644. }
  645. else
  646. {
  647. crForegroundColor = WARNING_FOREGROUND_COLOR;
  648. crBackgroundColor = WARNING_BACKGROUND_COLOR;
  649. dwSeverity = WiaDebugSeverityWarning;
  650. }
  651. if (dwLen)
  652. {
  653. PrintMessage( dwSeverity, crForegroundColor, crBackgroundColor, TEXT("%hs: [0x%08X] %hs"), szMsg, hr, pMsgBuf );
  654. LocalFree(pMsgBuf);
  655. }
  656. else
  657. {
  658. PrintMessage( dwSeverity, crForegroundColor, crBackgroundColor, TEXT("%hs: Unable to format message [0x%08X]"), szMsg, hr );
  659. }
  660. }
  661. }
  662. void CWiaDebugClient::PrintGuid( const IID &iid, LPCSTR pszFmt, ... )
  663. {
  664. CAutoCriticalSection cs(m_CriticalSection);
  665. if (IsInitialized())
  666. {
  667. CHAR szMsg[1024] = {0};
  668. va_list arglist;
  669. va_start( arglist, pszFmt );
  670. _vsnprintf( szMsg, ARRAYSIZE(szMsg)-1, pszFmt, arglist );
  671. va_end( arglist );
  672. CHAR szGuid[MAX_PATH]="";
  673. if (m_pfnGetStringFromGuidA( &iid, szGuid, sizeof(szGuid)/sizeof(szGuid[0]) ) )
  674. {
  675. PrintMessage( 0, m_crForegroundColor, DEFAULT_DEBUG_COLOR, TEXT("%hs: %hs"), szMsg, szGuid );
  676. }
  677. }
  678. }
  679. void CWiaDebugClient::PrintWindowMessage( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LPCSTR szMessage )
  680. {
  681. CAutoCriticalSection cs(m_CriticalSection);
  682. if (IsInitialized())
  683. {
  684. CHAR szWindowMessage[MAX_PATH]="";
  685. if (m_pfnGetStringFromMsgA( uMsg, szWindowMessage, sizeof(szWindowMessage)/sizeof(szWindowMessage[0]) ) )
  686. {
  687. PrintMessage( 0, m_crForegroundColor, DEFAULT_DEBUG_COLOR, TEXT("0x%p, %-30hs, 0x%p, 0x%p%hs%hs"), hWnd, szWindowMessage, wParam, lParam, (szMessage && lstrlenA(szMessage)) ? " : " : "", (szMessage && lstrlenA(szMessage)) ? szMessage : "" );
  688. }
  689. }
  690. }
  691. void CWiaDebugClient::SetInstance( HINSTANCE hInstance )
  692. {
  693. m_hCurrentModuleInstance = hInstance;
  694. }
  695. static CSimpleString ForceFailureProgramKey( LPCTSTR pszProgramName )
  696. {
  697. CSimpleString strAppKey( REGSTR_FORCEERR_KEY );
  698. strAppKey += TEXT("\\");
  699. strAppKey += pszProgramName;
  700. return strAppKey;
  701. }
  702. DWORD CWiaDebugClient::GetForceFailurePoint( LPCTSTR pszProgramName )
  703. {
  704. return CSimpleReg( HKEY_FORCEERROR, ForceFailureProgramKey(pszProgramName) ).Query( REGSTR_ERROR_POINT, 0 );
  705. }
  706. HRESULT CWiaDebugClient::GetForceFailureValue( LPCTSTR pszProgramName, bool bPrintWarning )
  707. {
  708. HRESULT hr = HRESULT_FROM_WIN32(CSimpleReg( HKEY_FORCEERROR, ForceFailureProgramKey(pszProgramName) ).Query( REGSTR_ERROR_VALUE, 0 ));
  709. if (bPrintWarning)
  710. {
  711. g_TheDebugClient.PrintHResult( hr, TEXT("FORCEERR: Forcing error return for program %s"), pszProgramName );
  712. }
  713. return hr;
  714. }
  715. void CWiaDebugClient::SetForceFailurePoint( LPCTSTR pszProgramName, DWORD dwErrorPoint )
  716. {
  717. CSimpleReg( HKEY_FORCEERROR, ForceFailureProgramKey(pszProgramName), true ).Set( REGSTR_ERROR_POINT, dwErrorPoint );
  718. }
  719. void CWiaDebugClient::SetForceFailureValue( LPCTSTR pszProgramName, HRESULT hr )
  720. {
  721. CSimpleReg( HKEY_FORCEERROR, ForceFailureProgramKey(pszProgramName), true ).Set( REGSTR_ERROR_VALUE, hr );
  722. }