Source code of Windows XP (NT5)
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.

540 lines
14 KiB

  1. // This is a part of the Active Template Library.
  2. // Copyright (C) 1996-2001 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Active Template Library Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Active Template Library product.
  10. #include "StdAfx.h"
  11. #include "Common.h"
  12. #include "AtlTraceModuleManager.h"
  13. namespace ATL
  14. {
  15. static bool ShouldTraceOutput(DWORD_PTR dwModule,
  16. DWORD_PTR dwCategory,
  17. UINT nLevel,
  18. const CAtlTraceCategory **ppCategory,
  19. CAtlTraceModule::fnCrtDbgReport_t *pfnCrtDbgReport);
  20. void NotifyTool()
  21. {
  22. HANDLE hEvent;
  23. hEvent = OpenEventA(EVENT_MODIFY_STATE, FALSE, g_pszUpdateEventName);
  24. if(hEvent)
  25. {
  26. SetEvent(hEvent);
  27. CloseHandle(hEvent);
  28. }
  29. }
  30. // API
  31. DWORD_PTR __stdcall AtlTraceRegister(HINSTANCE hInst,
  32. int (__cdecl *fnCrtDbgReport)(int,const char *,int,const char *,const char *,...))
  33. {
  34. int iModule = g_Allocator.AddModule(hInst);
  35. CAtlTraceModule* pModule = g_Allocator.GetModule(iModule);
  36. ATLASSERT(pModule != NULL);
  37. if(pModule != NULL)
  38. {
  39. pModule->CrtDbgReport(fnCrtDbgReport);
  40. NotifyTool();
  41. }
  42. return( DWORD_PTR( iModule )+1 );
  43. }
  44. BOOL __stdcall AtlTraceUnregister(DWORD_PTR dwModule)
  45. {
  46. int iModule = int( dwModule-1 );
  47. g_Allocator.RemoveModule( iModule );
  48. NotifyTool();
  49. return TRUE;
  50. }
  51. DWORD_PTR __stdcall AtlTraceRegisterCategoryA(DWORD_PTR dwModule, const CHAR szCategoryName[ATL_TRACE_MAX_NAME_SIZE])
  52. {
  53. USES_CONVERSION;
  54. return AtlTraceRegisterCategoryU(dwModule, A2W(szCategoryName));
  55. }
  56. DWORD_PTR __stdcall AtlTraceRegisterCategoryU(DWORD_PTR dwModule, const WCHAR szCategoryName[ATL_TRACE_MAX_NAME_SIZE])
  57. {
  58. int iModule = int( dwModule-1 );
  59. int iCategory = g_Allocator.AddCategory(iModule, szCategoryName);
  60. NotifyTool();
  61. return( DWORD_PTR( iCategory )+1 );
  62. }
  63. BOOL __stdcall AtlTraceModifyProcess(DWORD_PTR dwProcess, UINT nLevel, BOOL bEnabled,
  64. BOOL bFuncAndCategoryNames, BOOL bFileNameAndLineNo)
  65. {
  66. CAtlAllocator* pAllocator = reinterpret_cast< CAtlAllocator* >( dwProcess );
  67. #ifdef _DEBUG
  68. if( pAllocator == NULL )
  69. {
  70. pAllocator = &g_Allocator;
  71. }
  72. #endif // _DEBUG
  73. CAtlTraceProcess* pProcess = pAllocator->GetProcess();
  74. ATLASSERT(pProcess != NULL);
  75. if(pProcess != NULL)
  76. {
  77. pProcess->m_nLevel = nLevel;
  78. pProcess->m_bEnabled = 0 != bEnabled;
  79. pProcess->m_bFuncAndCategoryNames = 0 != bFuncAndCategoryNames;
  80. pProcess->m_bFileNameAndLineNo = 0 != bFileNameAndLineNo;
  81. }
  82. return( TRUE );
  83. }
  84. BOOL __stdcall AtlTraceModifyModule(DWORD_PTR dwProcess, DWORD_PTR dwModule, UINT nLevel, ATLTRACESTATUS eStatus)
  85. {
  86. CAtlAllocator* pAllocator = reinterpret_cast< CAtlAllocator* >( dwProcess );
  87. #ifdef _DEBUG
  88. if( pAllocator == NULL )
  89. {
  90. pAllocator = &g_Allocator;
  91. }
  92. #endif // _DEBUG
  93. int iModule = int( dwModule-1 );
  94. CAtlTraceModule* pModule = pAllocator->GetModule(iModule);
  95. ATLASSERT(pModule != NULL);
  96. if(pModule != NULL)
  97. {
  98. switch(eStatus)
  99. {
  100. case ATLTRACESTATUS_INHERIT:
  101. pModule->m_eStatus = CAtlTraceSettings::Inherit;
  102. break;
  103. case ATLTRACESTATUS_ENABLED:
  104. pModule->m_eStatus = CAtlTraceSettings::Enabled;
  105. break;
  106. case ATLTRACESTATUS_DISABLED:
  107. pModule->m_eStatus = CAtlTraceSettings::Disabled;
  108. break;
  109. default:
  110. ATLASSERT( false );
  111. break;
  112. }
  113. pModule->m_nLevel = nLevel;
  114. }
  115. return( TRUE );
  116. }
  117. BOOL __stdcall AtlTraceModifyCategory(DWORD_PTR dwProcess, DWORD_PTR dwCategory,
  118. UINT nLevel, ATLTRACESTATUS eStatus)
  119. {
  120. CAtlAllocator* pAllocator = reinterpret_cast< CAtlAllocator* >( dwProcess );
  121. #ifdef _DEBUG
  122. if( pAllocator == NULL )
  123. {
  124. pAllocator = &g_Allocator;
  125. }
  126. #endif // _DEBUG
  127. int iCategory = int( dwCategory-1 );
  128. CAtlTraceCategory *pCategory = pAllocator->GetCategory( iCategory );
  129. if(pCategory != NULL)
  130. {
  131. switch(eStatus)
  132. {
  133. case ATLTRACESTATUS_INHERIT:
  134. pCategory->m_eStatus = CAtlTraceSettings::Inherit;
  135. break;
  136. case ATLTRACESTATUS_ENABLED:
  137. pCategory->m_eStatus = CAtlTraceSettings::Enabled;
  138. break;
  139. case ATLTRACESTATUS_DISABLED:
  140. pCategory->m_eStatus = CAtlTraceSettings::Disabled;
  141. break;
  142. default:
  143. ATLASSERT(false);
  144. break;
  145. }
  146. pCategory->m_nLevel = nLevel;
  147. }
  148. return TRUE;
  149. }
  150. BOOL __stdcall AtlTraceGetProcess(DWORD_PTR dwProcess, UINT *pnLevel, BOOL *pbEnabled,
  151. BOOL *pbFuncAndCategoryNames, BOOL *pbFileNameAndLineNo)
  152. {
  153. CAtlAllocator* pAllocator = reinterpret_cast< CAtlAllocator* >( dwProcess );
  154. #ifdef _DEBUG
  155. if( pAllocator == NULL )
  156. {
  157. pAllocator = &g_Allocator;
  158. }
  159. #endif // _DEBUG
  160. CAtlTraceProcess* pProcess = pAllocator->GetProcess();
  161. ATLASSERT(pProcess != NULL);
  162. if(pProcess != NULL)
  163. {
  164. if(pnLevel)
  165. *pnLevel = pProcess->m_nLevel;
  166. if(pbEnabled)
  167. *pbEnabled = pProcess->m_bEnabled;
  168. if(pbFuncAndCategoryNames)
  169. *pbFuncAndCategoryNames = pProcess->m_bFuncAndCategoryNames;
  170. if(pbFileNameAndLineNo)
  171. *pbFileNameAndLineNo = pProcess->m_bFileNameAndLineNo;
  172. }
  173. return( TRUE );
  174. }
  175. BOOL __stdcall AtlTraceGetModule(DWORD_PTR dwProcess, DWORD_PTR dwModule, UINT *pnLevel, ATLTRACESTATUS *peStatus)
  176. {
  177. CAtlAllocator* pAllocator = reinterpret_cast< CAtlAllocator* >( dwProcess );
  178. #ifdef _DEBUG
  179. if( pAllocator == NULL )
  180. {
  181. pAllocator = &g_Allocator;
  182. }
  183. #endif // _DEBUG
  184. int iModule = int( dwModule-1 );
  185. CAtlTraceModule *pModule = pAllocator->GetModule(iModule);
  186. ATLASSERT(pModule != NULL);
  187. if(pModule != NULL)
  188. {
  189. if(pnLevel != NULL)
  190. {
  191. *pnLevel = pModule->m_nLevel;
  192. }
  193. if(peStatus != NULL)
  194. {
  195. switch(pModule->m_eStatus)
  196. {
  197. case CAtlTraceSettings::Inherit:
  198. *peStatus = ATLTRACESTATUS_INHERIT;
  199. break;
  200. case CAtlTraceSettings::Enabled:
  201. *peStatus = ATLTRACESTATUS_ENABLED;
  202. break;
  203. case CAtlTraceSettings::Disabled:
  204. *peStatus = ATLTRACESTATUS_DISABLED;
  205. break;
  206. default:
  207. ATLASSERT(false);
  208. break;
  209. }
  210. }
  211. }
  212. return TRUE;
  213. }
  214. BOOL __stdcall AtlTraceGetCategory(DWORD_PTR dwProcess, DWORD_PTR dwCategory, UINT *pnLevel,
  215. ATLTRACESTATUS *peStatus)
  216. {
  217. CAtlAllocator* pAllocator = reinterpret_cast< CAtlAllocator* >( dwProcess );
  218. #ifdef _DEBUG
  219. if( pAllocator == NULL )
  220. {
  221. pAllocator = &g_Allocator;
  222. }
  223. #endif // _DEBUG
  224. int iCategory = int( dwCategory-1 );
  225. CAtlTraceCategory* pCategory = pAllocator->GetCategory( iCategory );
  226. ATLASSERT(pCategory != NULL);
  227. if(pCategory != NULL)
  228. {
  229. if(pnLevel != NULL)
  230. {
  231. *pnLevel = pCategory->m_nLevel;
  232. }
  233. if(peStatus != NULL)
  234. {
  235. switch(pCategory->m_eStatus)
  236. {
  237. case CAtlTraceSettings::Inherit:
  238. *peStatus = ATLTRACESTATUS_INHERIT;
  239. break;
  240. case CAtlTraceSettings::Enabled:
  241. *peStatus = ATLTRACESTATUS_ENABLED;
  242. break;
  243. case CAtlTraceSettings::Disabled:
  244. *peStatus = ATLTRACESTATUS_DISABLED;
  245. break;
  246. }
  247. }
  248. }
  249. return( TRUE );
  250. }
  251. void __stdcall AtlTraceGetUpdateEventNameA(CHAR *pszEventName)
  252. {
  253. lstrcpyA(pszEventName, g_pszUpdateEventName);
  254. }
  255. void __stdcall AtlTraceGetUpdateEventNameU(WCHAR *pszEventName)
  256. {
  257. USES_CONVERSION;
  258. lstrcpyW(pszEventName, A2W(g_pszUpdateEventName));
  259. }
  260. void __cdecl AtlTraceVA(DWORD_PTR dwModule, const char *pszFileName, int nLine,
  261. DWORD_PTR dwCategory, UINT nLevel, const CHAR *pszFormat, va_list ptr)
  262. {
  263. const CAtlTraceCategory *pCategory;
  264. CAtlTraceModule::fnCrtDbgReport_t pfnCrtDbgReport = NULL;
  265. static const int nCount = 1024;
  266. CHAR szBuf[nCount] = {'\0'};
  267. int nLen = 0;
  268. if(ShouldTraceOutput(dwModule, dwCategory, nLevel, &pCategory, &pfnCrtDbgReport))
  269. {
  270. if(g_Allocator.GetProcess()->m_bFileNameAndLineNo)
  271. nLen += _snprintf(szBuf + nLen, nCount - nLen, "%s(%d) : ", pszFileName, nLine);
  272. if(pCategory && g_Allocator.GetProcess()->m_bFuncAndCategoryNames)
  273. nLen += _snprintf(szBuf + nLen, nCount - nLen, "%S: ", pCategory->Name());
  274. _vsnprintf(szBuf + nLen, nCount - nLen, pszFormat, ptr);
  275. if(pfnCrtDbgReport != NULL)
  276. pfnCrtDbgReport(_CRT_WARN, NULL, 0, NULL, "%s", szBuf);
  277. else
  278. OutputDebugStringA(szBuf);
  279. }
  280. }
  281. void __cdecl AtlTraceVU(DWORD_PTR dwModule, const char *pszFileName, int nLine,
  282. DWORD_PTR dwCategory, UINT nLevel, const WCHAR *pszFormat, va_list ptr)
  283. {
  284. const CAtlTraceCategory *pCategory;
  285. CAtlTraceModule::fnCrtDbgReport_t pfnCrtDbgReport = NULL;
  286. const int nCount = 1024;
  287. WCHAR szBuf[nCount] = {L'\0'};
  288. int nLen = 0;
  289. if(ShouldTraceOutput(dwModule, dwCategory, nLevel, &pCategory, &pfnCrtDbgReport))
  290. {
  291. if(g_Allocator.GetProcess()->m_bFileNameAndLineNo)
  292. nLen += _snwprintf(szBuf + nLen, nCount - nLen, L"%S(%d) : ", pszFileName, nLine);
  293. if(pCategory && g_Allocator.GetProcess()->m_bFuncAndCategoryNames)
  294. nLen += _snwprintf(szBuf + nLen, nCount - nLen, L"%s: ", pCategory->Name());
  295. _vsnwprintf(szBuf + nLen, nCount - nLen, pszFormat, ptr);
  296. if(pfnCrtDbgReport)
  297. pfnCrtDbgReport(_CRT_WARN, NULL, 0, NULL, "%S", szBuf);
  298. else
  299. OutputDebugStringW(szBuf);
  300. }
  301. }
  302. // REVIEW: Necessary?
  303. /*void __cdecl AtlTraceU(HINSTANCE hInst, UINT nCategory, UINT nLevel, const WCHAR *szFormat, ...)
  304. {
  305. va_list ptr;
  306. va_start(ptr, szFormat);
  307. AtlTraceVU(hInst, nCategory, nLevel, szFormat, ptr);
  308. va_end(ptr);
  309. }
  310. void __cdecl AtlTraceA(HINSTANCE hInst, UINT nCategory, UINT nLevel, const CHAR *szFormat, ...)
  311. {
  312. va_list ptr;
  313. va_start(ptr, szFormat);
  314. AtlTraceVA(hInst, nCategory, nLevel, szFormat, ptr);
  315. va_end(ptr);
  316. }*/
  317. DWORD_PTR __stdcall AtlTraceOpenProcess(DWORD idProcess)
  318. {
  319. CAtlAllocator* pAllocator = new CAtlAllocator;
  320. char szBuf[64];
  321. sprintf(szBuf, g_pszKernelObjFmt, g_pszAllocFileMapName, idProcess);
  322. if( !pAllocator->Open(szBuf) )
  323. {
  324. delete pAllocator;
  325. return( 0 );
  326. }
  327. return( reinterpret_cast< DWORD_PTR >( pAllocator ) );
  328. }
  329. void __stdcall AtlTraceCloseProcess( DWORD_PTR dwProcess )
  330. {
  331. CAtlAllocator* pAllocator = reinterpret_cast< CAtlAllocator* >( dwProcess );
  332. pAllocator->Close( true );
  333. delete pAllocator;
  334. }
  335. void __stdcall AtlTraceSnapshotProcess( DWORD_PTR dwProcess )
  336. {
  337. CAtlAllocator* pAllocator = reinterpret_cast< CAtlAllocator* >( dwProcess );
  338. pAllocator->TakeSnapshot();
  339. }
  340. BOOL __stdcall AtlTraceGetProcessInfo(DWORD_PTR dwProcess, ATLTRACEPROCESSINFO* pProcessInfo)
  341. {
  342. ATLASSERT(pProcessInfo != NULL);
  343. CAtlAllocator* pAllocator = reinterpret_cast< CAtlAllocator* >( dwProcess );
  344. ATLASSERT(pAllocator->m_bSnapshot);
  345. CAtlTraceProcess *pProcess = pAllocator->GetProcess();
  346. ATLASSERT(pProcess != NULL);
  347. if(pProcess)
  348. {
  349. lstrcpyW(pProcessInfo->szName, pProcess->Name());
  350. lstrcpyW(pProcessInfo->szPath, pProcess->Path());
  351. pProcessInfo->dwId = pProcess->Id();
  352. pProcessInfo->settings.nLevel = pProcess->m_nLevel;
  353. pProcessInfo->settings.bEnabled = pProcess->m_bEnabled;
  354. pProcessInfo->settings.bFuncAndCategoryNames = pProcess->m_bFuncAndCategoryNames;
  355. pProcessInfo->settings.bFileNameAndLineNo = pProcess->m_bFileNameAndLineNo;
  356. pProcessInfo->nModules = pAllocator->m_snapshot.m_aModules.GetSize();
  357. }
  358. return( TRUE );
  359. }
  360. void __stdcall AtlTraceGetModuleInfo(DWORD_PTR dwProcess, int iModule, ATLTRACEMODULEINFO* pModuleInfo)
  361. {
  362. ATLASSERT(pModuleInfo != NULL);
  363. CAtlAllocator* pAllocator = reinterpret_cast< CAtlAllocator* >( dwProcess );
  364. ATLASSERT(pAllocator->m_bSnapshot);
  365. DWORD_PTR dwModule = pAllocator->m_snapshot.m_aModules[iModule].m_dwModule;
  366. CAtlTraceModule* pModule = pAllocator->GetModule(int(dwModule-1));
  367. lstrcpyW(pModuleInfo->szName, pModule->Name());
  368. lstrcpyW(pModuleInfo->szPath, pModule->Path());
  369. pModuleInfo->nCategories = pModule->m_nCategories;
  370. pModuleInfo->settings.nLevel = pModule->m_nLevel;
  371. pModuleInfo->dwModule = dwModule;
  372. switch(pModule->m_eStatus)
  373. {
  374. default:
  375. case CAtlTraceSettings::Inherit:
  376. pModuleInfo->settings.eStatus = ATLTRACESTATUS_INHERIT;
  377. break;
  378. case CAtlTraceSettings::Enabled:
  379. pModuleInfo->settings.eStatus = ATLTRACESTATUS_ENABLED;
  380. break;
  381. case CAtlTraceSettings::Disabled:
  382. pModuleInfo->settings.eStatus = ATLTRACESTATUS_DISABLED;
  383. break;
  384. }
  385. }
  386. void __stdcall AtlTraceGetCategoryInfo(DWORD_PTR dwProcess, DWORD_PTR dwModule, int iCategory, ATLTRACECATEGORYINFO* pCategoryInfo)
  387. {
  388. ATLASSERT(pCategoryInfo != NULL);
  389. CAtlAllocator* pAllocator = reinterpret_cast< CAtlAllocator* >( dwProcess );
  390. ATLASSERT(pAllocator->m_bSnapshot);
  391. int iModule = int( dwModule-1 );
  392. CAtlTraceModule* pModule = pAllocator->GetModule( iModule );
  393. CAtlTraceCategory* pCategory = pAllocator->GetCategory( pModule->m_iFirstCategory );
  394. for( int iCategoryIndex = 0; iCategoryIndex < iCategory; iCategoryIndex++ )
  395. {
  396. pCategory = pAllocator->GetCategory( pCategory->m_iNextCategory );
  397. }
  398. lstrcpyW(pCategoryInfo->szName, pCategory->Name());
  399. pCategoryInfo->settings.nLevel = pCategory->m_nLevel;
  400. pCategoryInfo->dwCategory = DWORD_PTR( iCategory )+1;
  401. switch(pCategory->m_eStatus)
  402. {
  403. case CAtlTraceSettings::Inherit:
  404. pCategoryInfo->settings.eStatus = ATLTRACESTATUS_INHERIT;
  405. break;
  406. case CAtlTraceSettings::Enabled:
  407. pCategoryInfo->settings.eStatus = ATLTRACESTATUS_ENABLED;
  408. break;
  409. case CAtlTraceSettings::Disabled:
  410. pCategoryInfo->settings.eStatus = ATLTRACESTATUS_DISABLED;
  411. break;
  412. default:
  413. ATLASSERT( false );
  414. break;
  415. }
  416. }
  417. static bool ShouldTraceOutput(DWORD_PTR dwModule,
  418. DWORD_PTR dwCategory,
  419. UINT nLevel,
  420. const CAtlTraceCategory **ppCategory,
  421. CAtlTraceModule::fnCrtDbgReport_t *pfnCrtDbgReport)
  422. {
  423. bool bFound = false;
  424. ATLASSERT(ppCategory && pfnCrtDbgReport);
  425. *ppCategory = NULL;
  426. *pfnCrtDbgReport = NULL;
  427. CAtlTraceProcess *pProcess = g_Allocator.GetProcess();
  428. ATLASSERT(pProcess);
  429. CAtlTraceModule *pModule = g_Allocator.GetModule( int( dwModule-1 ) );
  430. ATLASSERT(pModule != NULL);
  431. if(pModule != NULL)
  432. {
  433. *pfnCrtDbgReport = pModule->CrtDbgReport();
  434. CAtlTraceCategory *pCategory = g_Allocator.GetCategory( int( dwCategory ) );
  435. if( pCategory != NULL )
  436. {
  437. bFound = true;
  438. bool bOut = false;
  439. if(pProcess->m_bEnabled &&
  440. pModule->m_eStatus == CAtlTraceSettings::Inherit &&
  441. pCategory->m_eStatus == CAtlTraceSettings::Inherit &&
  442. nLevel <= pProcess->m_nLevel)
  443. {
  444. bOut = true;
  445. }
  446. else if(pModule->m_eStatus == CAtlTraceSettings::Enabled &&
  447. pCategory->m_eStatus == CAtlTraceSettings::Inherit &&
  448. nLevel <= pModule->m_nLevel)
  449. {
  450. bOut = true;
  451. }
  452. else if(pCategory->m_eStatus == CAtlTraceSettings::Enabled &&
  453. nLevel <= pCategory->m_nLevel)
  454. {
  455. bOut = true;
  456. }
  457. if(bOut)
  458. {
  459. *ppCategory = pProcess->m_bFuncAndCategoryNames ? pCategory : NULL;
  460. return true;
  461. }
  462. }
  463. }
  464. return false;
  465. }
  466. }; // namespace ATL