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.

996 lines
23 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. LogWrappers.h
  5. Abstract:
  6. Helper classes for logging APIs
  7. Author:
  8. Hakki T. Bostanci (hakkib) 06-Apr-2000
  9. Revision History:
  10. --*/
  11. #ifndef LOGWRAPPERS_H
  12. #define LOGWRAPPERS_H
  13. #include <map>
  14. #include "LogWindow.h"
  15. //////////////////////////////////////////////////////////////////////////
  16. //
  17. //
  18. //
  19. #define TLS_NOCONSOLE 0x04000000L
  20. //////////////////////////////////////////////////////////////////////////
  21. //
  22. //
  23. //
  24. #define LOG_LEVELS 0x0000FFFFL // These are used to mask out the
  25. #define LOG_STYLES 0xFFFF0000L // styles or levels from log object.
  26. #define TLS_LOGALL 0x0000FFFFL // Log output. Logs all the time.
  27. #define TLS_LOG 0x00000000L // Log output. Logs all the time.
  28. #define TLS_INFO 0x00002000L // Log information.
  29. #define TLS_ABORT 0x00000001L // Log Abort, then kill process.
  30. #define TLS_SEV1 0x00000002L // Log at Severity 1 level
  31. #define TLS_SEV2 0x00000004L // Log at Severity 2 level
  32. #define TLS_SEV3 0x00000008L // Log at Severity 3 level
  33. #define TLS_WARN 0x00000010L // Log at Warn level
  34. #define TLS_PASS 0x00000020L // Log at Pass level
  35. #define TLS_BLOCK 0x00000400L // Block the variation.
  36. #define TLS_BREAK 0x00000800L // Debugger break;
  37. #define TLS_CALLTREE 0x00000040L // Log call-tree (function tracking).
  38. #define TLS_SYSTEM 0x00000080L // Log System debug.
  39. #define TLS_TESTDEBUG 0x00001000L // Debug level.
  40. #define TLS_TEST 0x00000100L // Log Test information (user).
  41. #define TLS_VARIATION 0x00000200L // Log testcase level.
  42. #define TLS_REFRESH 0x00010000L // Create new file || trunc to zero.
  43. #define TLS_SORT 0x00020000L // Sort file output by instance.
  44. #define TLS_DEBUG 0x00040000L // Output to debug (com) monitor).
  45. #define TLS_MONITOR 0x00080000L // Output to 2nd screen.
  46. #define TLS_PROLOG 0x00200000L // Prolog line information.
  47. #define TLS_WINDOW 0x00400000L // Log to windows.
  48. #define TLS_ACCESSON 0x00800000L // Keep log-file open.
  49. #define TLS_DIFFABLE 0x01000000L // make log file windiff'able (no dates..)
  50. #define TLS_NOHEADER 0x02000000L // suppress headers so it is more diffable
  51. #define TL_LOG TLS_LOG ,_T(__FILE__),(int)__LINE__
  52. #define TL_ABORT TLS_ABORT ,_T(__FILE__),(int)__LINE__
  53. #define TL_SEV1 TLS_SEV1 ,_T(__FILE__),(int)__LINE__
  54. #define TL_SEV2 TLS_SEV2 ,_T(__FILE__),(int)__LINE__
  55. #define TL_SEV3 TLS_SEV3 ,_T(__FILE__),(int)__LINE__
  56. #define TL_WARN TLS_WARN ,_T(__FILE__),(int)__LINE__
  57. #define TL_PASS TLS_PASS ,_T(__FILE__),(int)__LINE__
  58. #define TL_BLOCK TLS_BLOCK ,_T(__FILE__),(int)__LINE__
  59. #define TL_INFO TLS_INFO ,_T(__FILE__),(int)__LINE__
  60. #define TL_BREAK TLS_BREAK ,_T(__FILE__),(int)__LINE__
  61. #define TL_CALLTREE TLS_CALLTREE ,_T(__FILE__),(int)__LINE__
  62. #define TL_SYSTEM TLS_SYSTEM ,_T(__FILE__),(int)__LINE__
  63. #define TL_TESTDEBUG TLS_TESTDEBUG,_T(__FILE__),(int)__LINE__
  64. #define TL_TEST TLS_TEST ,_T(__FILE__),(int)__LINE__
  65. #define TL_VARIATION TLS_VARIATION,_T(__FILE__),(int)__LINE__
  66. //////////////////////////////////////////////////////////////////////////
  67. //
  68. //
  69. //
  70. class CLog
  71. {
  72. protected:
  73. struct CResults
  74. {
  75. UINT nTotal;
  76. UINT nPassed;
  77. UINT nWarned;
  78. UINT nFailedSev3;
  79. UINT nFailedSev2;
  80. UINT nFailedSev1;
  81. UINT nBlocked;
  82. UINT nAborted;
  83. DWORD dwStartTime;
  84. CResults()
  85. {
  86. ZeroMemory(this, sizeof(*this));
  87. dwStartTime = GetTickCount();
  88. }
  89. void Update(DWORD dwLogLevel)
  90. {
  91. if (dwLogLevel & TLS_PASS) ++nPassed;
  92. if (dwLogLevel & TLS_WARN) ++nWarned;
  93. if (dwLogLevel & TLS_SEV3) ++nFailedSev3;
  94. if (dwLogLevel & TLS_SEV2) ++nFailedSev2;
  95. if (dwLogLevel & TLS_SEV1) ++nFailedSev1;
  96. if (dwLogLevel & TLS_BLOCK) ++nBlocked;
  97. if (dwLogLevel & TLS_ABORT) ++nAborted;
  98. }
  99. PCTSTR Report(PTSTR pBuffer, SIZE_T nBufferLen) const
  100. {
  101. DWORD dwUpTime = GetTickCount() - dwStartTime;
  102. _sntprintf(
  103. pBuffer,
  104. nBufferLen,
  105. _T("%d total, ")
  106. _T("%d passed, ")
  107. _T("%d warned, ")
  108. _T("%d failed sev1, ")
  109. _T("%d failed sev2, ")
  110. _T("%d failed sev3, ")
  111. _T("%d blocked, ")
  112. _T("%d aborted tests in ")
  113. _T("%d hours, ")
  114. _T("%d mins, ")
  115. _T("%d secs"),
  116. nTotal,
  117. nPassed,
  118. nWarned,
  119. nFailedSev3,
  120. nFailedSev2,
  121. nFailedSev1,
  122. nBlocked,
  123. nAborted,
  124. dwUpTime / (1000 * 60 * 60),
  125. (dwUpTime / (1000 * 60)) % 60,
  126. (dwUpTime / 1000) % 60
  127. );
  128. return pBuffer;
  129. }
  130. PCTSTR Summary() const
  131. {
  132. if (nAborted)
  133. {
  134. return _T("TIMEOUT");
  135. }
  136. if (nBlocked)
  137. {
  138. return _T("NOCONFIG");
  139. }
  140. if (nFailedSev3 || nFailedSev2 || nFailedSev1)
  141. {
  142. return _T("FAIL");
  143. }
  144. return _T("PASS");
  145. }
  146. };
  147. public:
  148. CLog()
  149. {
  150. m_pLogWindow = 0;
  151. m_bMute = false;
  152. }
  153. virtual ~CLog()
  154. {
  155. }
  156. VOID
  157. SetLogWindow(
  158. CLogWindow *pLogWindow
  159. )
  160. {
  161. m_pLogWindow = pLogWindow;
  162. }
  163. VOID
  164. Mute(bool bMute = true)
  165. {
  166. m_bMute = bMute;
  167. }
  168. PCTSTR
  169. __cdecl
  170. Log(
  171. DWORD dwLogLevel,
  172. PCTSTR pFile,
  173. int nLine,
  174. PCTSTR pFormat,
  175. ...
  176. )
  177. {
  178. va_list arglist;
  179. va_start(arglist, pFormat);
  180. return LogV(dwLogLevel, pFile, nLine, pFormat, arglist);
  181. }
  182. PCTSTR
  183. LogV(
  184. DWORD dwLogLevel,
  185. PCTSTR pFile,
  186. int nLine,
  187. PCTSTR pFormat,
  188. va_list arglist
  189. )
  190. {
  191. CCppMem<TCHAR> pszStr(bufvprintf(pFormat, arglist));
  192. PCTSTR pszComment = _T("");
  193. if (!m_bMute)
  194. {
  195. if (dwLogLevel & TLS_TEST)
  196. {
  197. m_TestResults.Update(dwLogLevel);
  198. }
  199. if (dwLogLevel & TLS_VARIATION)
  200. {
  201. if (dwLogLevel & (TLS_WARN | TLS_SEV1 | TLS_SEV2 | TLS_SEV3 | TLS_ABORT))
  202. {
  203. DWORD &rResult = m_ThreadResult[GetCurrentThreadId()];
  204. if (rResult < dwLogLevel)
  205. {
  206. rResult = dwLogLevel;
  207. }
  208. }
  209. }
  210. if (dwLogLevel & TLS_NOCONSOLE)
  211. {
  212. dwLogLevel &= ~TLS_NOCONSOLE;
  213. }
  214. else
  215. {
  216. if (dwLogLevel & TLS_DEBUG)
  217. {
  218. if (pFile)
  219. {
  220. OutputDebugString(pFile);
  221. OutputDebugString(_T(" "));
  222. }
  223. OutputDebugString(pszStr);
  224. OutputDebugString(_T("\n")); //bugbug: talk about inefficiency...
  225. dwLogLevel &= ~TLS_DEBUG;
  226. }
  227. if (m_pLogWindow)
  228. {
  229. TCHAR Buffer[1024];
  230. pszComment = m_pLogWindow->Log(
  231. dwLogLevel,
  232. pFile,
  233. nLine,
  234. pszStr,
  235. m_VarResults.Report(Buffer, COUNTOF(Buffer))
  236. );
  237. }
  238. else
  239. {
  240. _ftprintf(
  241. dwLogLevel & TLS_INFO ? stdout : stderr,
  242. _T("%s\n"),
  243. pszStr
  244. );
  245. }
  246. }
  247. LogStr(
  248. dwLogLevel,
  249. pFile,
  250. nLine,
  251. pszStr,
  252. pszComment
  253. );
  254. }
  255. return pszComment;
  256. }
  257. virtual
  258. VOID
  259. LogStr(
  260. DWORD dwLogLevel,
  261. PCTSTR pFile,
  262. int nLine,
  263. PCTSTR pStr,
  264. PCTSTR pComment
  265. )
  266. {
  267. }
  268. virtual
  269. VOID
  270. StartVariation()
  271. {
  272. ++m_VarResults.nTotal;
  273. m_ThreadResult[GetCurrentThreadId()] = TLS_PASS;
  274. }
  275. virtual
  276. DWORD
  277. EndVariation()
  278. {
  279. DWORD dwResult = m_ThreadResult[GetCurrentThreadId()];
  280. m_VarResults.Update(dwResult);
  281. return dwResult;
  282. }
  283. virtual
  284. VOID
  285. InitThread()
  286. {
  287. }
  288. virtual
  289. VOID
  290. DoneThread()
  291. {
  292. }
  293. virtual
  294. VOID
  295. StartBlock(PCTSTR pBlockName, BOOL bStamp = TRUE)
  296. {
  297. }
  298. virtual
  299. VOID
  300. EndBlock(PCTSTR pBlockName, BOOL bStamp = TRUE)
  301. {
  302. }
  303. private:
  304. CLogWindow *m_pLogWindow;
  305. bool m_bMute;
  306. protected:
  307. CResults m_TestResults;
  308. CResults m_VarResults;
  309. std::map<DWORD, DWORD> m_ThreadResult;
  310. };
  311. //////////////////////////////////////////////////////////////////////////
  312. //
  313. //
  314. //
  315. class CNtLog : public CHandle<HANDLE, CNtLog>, public CLog
  316. {
  317. typedef CHandle<HANDLE, CNtLog> handle_type;
  318. public:
  319. CNtLog()
  320. {
  321. }
  322. CNtLog(
  323. PCTSTR pszLogFile,
  324. DWORD dwLogInfo,
  325. LPSECURITY_ATTRIBUTES lpSecAttrs = 0
  326. ) :
  327. handle_type((*m_Dll.CreateLogEx)(
  328. pszLogFile,
  329. dwLogInfo,
  330. lpSecAttrs
  331. ))
  332. {
  333. InitThread();
  334. }
  335. void Destroy()
  336. {
  337. (*m_Dll.ReportStats)(*this);
  338. (*m_Dll.RemoveParticipant)(*this);
  339. (*m_Dll.DestroyLog)(*this);
  340. }
  341. bool IsValid()
  342. {
  343. return (HANDLE) *this != INVALID_HANDLE_VALUE;
  344. }
  345. VOID
  346. InitThread()
  347. {
  348. AddParticipant();
  349. }
  350. VOID
  351. DoneThread()
  352. {
  353. RemoveParticipant();
  354. }
  355. VOID
  356. AddParticipant(
  357. DWORD dwLevels = 0,
  358. int nMachineID = 0
  359. ) const
  360. {
  361. (*m_Dll.AddParticipant)(
  362. *this,
  363. dwLevels,
  364. nMachineID
  365. );
  366. }
  367. VOID
  368. RemoveParticipant() const
  369. {
  370. (*m_Dll.RemoveParticipant)(*this);
  371. }
  372. static
  373. DWORD
  374. ParseCmdLine(
  375. PCTSTR pszCmdLine
  376. )
  377. {
  378. return (*m_Dll.ParseCmdLine)(pszCmdLine);
  379. }
  380. int
  381. GetLogFileName(
  382. PTSTR pszFileName
  383. ) const
  384. {
  385. return (*m_Dll.GetLogFileName)(*this, pszFileName);
  386. }
  387. VOID
  388. SetLogFileName(
  389. PTSTR pszFileName
  390. ) const
  391. {
  392. (*m_Dll.SetLogFileName)(*this, pszFileName);
  393. }
  394. DWORD
  395. GetLogInfo() const
  396. {
  397. return (*m_Dll.GetLogInfo)(*this);
  398. }
  399. DWORD
  400. SetLogInfo(
  401. DWORD dwInfo
  402. ) const
  403. {
  404. return (*m_Dll.SetLogInfo)(*this, dwInfo);
  405. }
  406. VOID
  407. PromptLog(
  408. HWND hWnd = 0
  409. ) const
  410. {
  411. (*m_Dll.PromptLog)(hWnd, *this);
  412. }
  413. int
  414. GetTestStat(
  415. DWORD dwLevel
  416. ) const
  417. {
  418. return (*m_Dll.GetTestStat)(*this, dwLevel);
  419. }
  420. int
  421. GetVariationStat(
  422. DWORD dwLevel
  423. ) const
  424. {
  425. return (*m_Dll.GetVariationStat)(*this, dwLevel);
  426. }
  427. VOID
  428. ClearTestStats() const
  429. {
  430. (*m_Dll.ClearTestStats)(*this);
  431. }
  432. VOID
  433. ClearVariationStats() const
  434. {
  435. (*m_Dll.ClearVariationStats)(*this);
  436. }
  437. VOID
  438. StartVariation()
  439. {
  440. CLog::StartVariation();
  441. (*m_Dll.StartVariation)(*this);
  442. }
  443. DWORD
  444. EndVariation()
  445. {
  446. CLog::EndVariation();
  447. return (*m_Dll.EndVariation)(*this);
  448. }
  449. VOID
  450. ReportStats() const
  451. {
  452. (*m_Dll.ReportStats)(*this);
  453. }
  454. VOID
  455. LogStr(
  456. DWORD dwLogLevel,
  457. PCTSTR pFile,
  458. int nLine,
  459. PCTSTR pStr,
  460. PCTSTR pComment
  461. )
  462. {
  463. (*m_Dll.Log)(
  464. *this,
  465. dwLogLevel,
  466. pFile,
  467. nLine,
  468. pComment && *pComment ? _T("%s (%s)") : _T("%s"),
  469. pStr,
  470. pComment
  471. );
  472. }
  473. private:
  474. class CNtLogDLL
  475. {
  476. public:
  477. CNtLogDLL()
  478. {
  479. try
  480. {
  481. m_NtLog = CLibrary(_T("ntlog.dll"));
  482. CreateLog = CCreateLog (m_NtLog, "tlCreateLog_"_AW);
  483. CreateLogEx = CCreateLogEx (m_NtLog, "tlCreateLogEx_"_AW);
  484. ParseCmdLine = CParseCmdLine (m_NtLog, "tlParseCmdLine_"_AW);
  485. GetLogFileName = CGetLogFileName (m_NtLog, "tlGetLogFileName_"_AW);
  486. SetLogFileName = CSetLogFileName (m_NtLog, "tlSetLogFileName_"_AW);
  487. LogX = CLogX (m_NtLog, "tlLogX_"_AW);
  488. Log = CLog (m_NtLog, "tlLog_"_AW);
  489. DestroyLog = CDestroyLog (m_NtLog, "tlDestroyLog");
  490. AddParticipant = CAddParticipant (m_NtLog, "tlAddParticipant");
  491. RemoveParticipant = CRemoveParticipant (m_NtLog, "tlRemoveParticipant");
  492. GetLogInfo = CGetLogInfo (m_NtLog, "tlGetLogInfo");
  493. SetLogInfo = CSetLogInfo (m_NtLog, "tlSetLogInfo");
  494. PromptLog = CPromptLog (m_NtLog, "tlPromptLog");
  495. GetTestStat = CGetTestStat (m_NtLog, "tlGetTestStat");
  496. GetVariationStat = CGetVariationStat (m_NtLog, "tlGetVariationStat");
  497. ClearTestStats = CClearTestStats (m_NtLog, "tlClearTestStats");
  498. ClearVariationStats = CClearVariationStats(m_NtLog, "tlClearVariationStats");
  499. StartVariation = CStartVariation (m_NtLog, "tlStartVariation");
  500. EndVariation = CEndVariation (m_NtLog, "tlEndVariation");
  501. ReportStats = CReportStats (m_NtLog, "tlReportStats");
  502. }
  503. catch (...)
  504. {
  505. //_tprintf(_T("*** Cannot load NTLOG.DLL, no log file will be generated ***\n"));
  506. }
  507. }
  508. private:
  509. CLibrary m_NtLog;
  510. public:
  511. DECL_CWINAPI(HANDLE, APIENTRY, CreateLog, (LPCTSTR, DWORD));
  512. DECL_CWINAPI(HANDLE, APIENTRY, CreateLogEx, (LPCTSTR, DWORD, LPSECURITY_ATTRIBUTES));
  513. DECL_CWINAPI(DWORD, APIENTRY, ParseCmdLine, (LPCTSTR));
  514. DECL_CWINAPI(int, APIENTRY, GetLogFileName, (HANDLE, LPTSTR));
  515. DECL_CWINAPI(BOOL, APIENTRY, SetLogFileName, (HANDLE, LPCTSTR));
  516. DECL_CWINAPI(BOOL, APIENTRY, LogX, (HANDLE, DWORD, LPCTSTR, int, LPCTSTR));
  517. DECL_CWINAPI(BOOL, __cdecl, Log, (HANDLE, DWORD, LPCTSTR, int, LPCTSTR, ...));
  518. DECL_CWINAPI(BOOL, APIENTRY, DestroyLog, (HANDLE));
  519. DECL_CWINAPI(BOOL, APIENTRY, AddParticipant, (HANDLE, DWORD, int));
  520. DECL_CWINAPI(BOOL, APIENTRY, RemoveParticipant, (HANDLE));
  521. DECL_CWINAPI(DWORD, APIENTRY, GetLogInfo, (HANDLE));
  522. DECL_CWINAPI(DWORD, APIENTRY, SetLogInfo, (HANDLE, DWORD));
  523. DECL_CWINAPI(HANDLE, APIENTRY, PromptLog, (HWND, HANDLE));
  524. DECL_CWINAPI(int, APIENTRY, GetTestStat, (HANDLE, DWORD));
  525. DECL_CWINAPI(int, APIENTRY, GetVariationStat, (HANDLE, DWORD));
  526. DECL_CWINAPI(BOOL, APIENTRY, ClearTestStats, (HANDLE));
  527. DECL_CWINAPI(BOOL, APIENTRY, ClearVariationStats, (HANDLE));
  528. DECL_CWINAPI(BOOL, APIENTRY, StartVariation, (HANDLE));
  529. DECL_CWINAPI(DWORD, APIENTRY, EndVariation, (HANDLE));
  530. DECL_CWINAPI(BOOL, APIENTRY, ReportStats, (HANDLE));
  531. };
  532. private:
  533. static CNtLogDLL m_Dll;
  534. };
  535. //////////////////////////////////////////////////////////////////////////
  536. //
  537. //
  538. //
  539. // Invalid Log handle define
  540. #define INVALID_LOGHANDLE -1
  541. // Log file and debug output flags
  542. #define NO_LOG 0x000000
  543. #define STAT_LOG 0x000001 // Local logging operation
  544. #define SUM_LOG 0x000002
  545. #define ERR_LOG 0x000004
  546. #define DBG_LOG 0x000008
  547. #define SVR_STAT_LOG 0x010000
  548. #define SVR_SUM_LOG 0x020000 // Lormaster Server logging operation
  549. #define SVR_ERR_LOG 0x040000
  550. #define SVR_DBG_LOG 0x080000
  551. #define SVR_SQL_LOG 0x100000 // Perform SQL logging
  552. // LogFile Creation flags
  553. #define LOG_NEW 0x001
  554. #define LOG_APPEND 0x002
  555. #define LOG_NOCREATE 0x004
  556. // Test result type
  557. #define RESULT_INFO 0
  558. #define RESULT_TESTPASS 1
  559. #define RESULT_TESTFAIL 2
  560. #define RESULT_TESTNA 3
  561. #define RESULT_SUMMARY 4
  562. #define RESULT_DEBUG 5
  563. #define RESULT_ERRINFO 6
  564. //////////////////////////////////////////////////////////////////////////
  565. //
  566. //
  567. //
  568. class CLorLog : public CHandle<unsigned long, CLorLog>, public CLog
  569. {
  570. typedef CHandle<unsigned long, CLorLog> handle_type;
  571. public:
  572. CLorLog()
  573. {
  574. }
  575. CLorLog(
  576. const char *pTest_Name,
  577. const char *pLog_Path,
  578. unsigned long dwCreate_Flags,
  579. unsigned long dwLog_Flags,
  580. unsigned long dwDebug_Flags
  581. ) :
  582. handle_type((*m_Dll.RegisterTest)(
  583. pTest_Name,
  584. pLog_Path,
  585. dwCreate_Flags,
  586. dwLog_Flags,
  587. dwDebug_Flags
  588. ))
  589. {
  590. }
  591. CLorLog(
  592. const char *pTest_Name,
  593. const char *pLog_Path,
  594. DWORD Create_Flags,
  595. DWORD Log_Flags,
  596. DWORD Debug_Flags,
  597. DWORD dwProcessID
  598. ) :
  599. handle_type((*m_Dll.RegisterTest_ProcID)(
  600. pTest_Name,
  601. pLog_Path,
  602. Create_Flags,
  603. Log_Flags,
  604. Debug_Flags,
  605. dwProcessID
  606. ))
  607. {
  608. }
  609. void Destroy()
  610. {
  611. (*m_Dll.UnRegisterTest)(*this);
  612. }
  613. bool IsValid()
  614. {
  615. return *this != INVALID_LOGHANDLE;
  616. }
  617. VOID
  618. LogStr(
  619. DWORD dwLogLevel,
  620. PCTSTR pFile,
  621. int nLine,
  622. PCTSTR pStr,
  623. PCTSTR pComment
  624. )
  625. {
  626. DWORD dwType;
  627. if (dwLogLevel & TLS_INFO)
  628. {
  629. dwType = RESULT_INFO;
  630. }
  631. else if (dwLogLevel & (TLS_WARN | TLS_SEV1 | TLS_SEV2 | TLS_SEV3 | TLS_ABORT))
  632. {
  633. dwType = RESULT_ERRINFO;
  634. }
  635. else
  636. {
  637. dwType = RESULT_INFO;
  638. }
  639. USES_CONVERSION;
  640. (*m_Dll.TestResultEx)(
  641. *this,
  642. dwType,
  643. pComment && *pComment ? "%1: %2!d!: %3 (%4)" : "%1: %2!d!: %3",
  644. T2A(pFile),
  645. nLine,
  646. T2A(pStr),
  647. T2A(pComment)
  648. );
  649. }
  650. private:
  651. class CLorLogDLL
  652. {
  653. public:
  654. CLorLogDLL()
  655. {
  656. try
  657. {
  658. m_LorLog = CLibrary(_T("loglog32.dll"));
  659. RegisterTest = CRegisterTest (m_LorLog, "RegisterTest");
  660. RegisterTest_ProcID = CRegisterTest_ProcID(m_LorLog, "RegisterTest_ProcID");
  661. TestResult = CTestResult (m_LorLog, "TestResult");
  662. TestResultEx = CTestResultEx (m_LorLog, "TestResultEx");
  663. UnRegisterTest = CUnRegisterTest (m_LorLog, "UnRegisterTest");
  664. QueryTestResults = CQueryTestResults (m_LorLog, "QueryTestResults");
  665. }
  666. catch (...)
  667. {
  668. //_tprintf(_T("*** Cannot load LORLOG32.DLL, no log file will be generated ***\n"));
  669. }
  670. }
  671. private:
  672. CLibrary m_LorLog;
  673. public:
  674. DECL_CWINAPI(unsigned long, WINAPI, RegisterTest, (const char *, const char *, unsigned long, unsigned long, unsigned long));
  675. DECL_CWINAPI(unsigned long, WINAPI, RegisterTest_ProcID, (const char *, const char *, DWORD, DWORD, DWORD, DWORD));
  676. DECL_CWINAPI(int, WINAPI, TestResult, (unsigned long, unsigned long, const char *));
  677. DECL_CWINAPI(int, __cdecl, TestResultEx, (unsigned long, unsigned long, const char *, ...));
  678. DECL_CWINAPI(int, WINAPI, UnRegisterTest, (unsigned long));
  679. DECL_CWINAPI(int, WINAPI, QueryTestResults, (unsigned long, unsigned long *, unsigned long *, unsigned long *));
  680. };
  681. private:
  682. static CLorLogDLL m_Dll;
  683. };
  684. //////////////////////////////////////////////////////////////////////////
  685. //
  686. //
  687. //
  688. #define TIME_TO_STR_FORMAT \
  689. _T("%d/%d/%02d %d:%02d:%02d %cM")
  690. #define TIME_TO_STR_ARGS(st) \
  691. st.wMonth, \
  692. st.wDay, \
  693. st.wYear % 100, \
  694. st.wHour % 12, \
  695. st.wMinute, \
  696. st.wSecond, \
  697. st.wHour / 12 ? _T('P') : _T('A') \
  698. //////////////////////////////////////////////////////////////////////////
  699. //
  700. //
  701. //
  702. class CBvtLog : public CLog
  703. {
  704. public:
  705. struct COwners
  706. {
  707. PCTSTR pTestName;
  708. PCTSTR pContactName;
  709. PCTSTR pMgrName;
  710. PCTSTR pDevPrimeName;
  711. PCTSTR pDevAltName;
  712. PCTSTR pTestPrimeName;
  713. PCTSTR pTestAltName;
  714. };
  715. public:
  716. CBvtLog()
  717. {
  718. }
  719. CBvtLog(
  720. COwners *pOwners,
  721. PCTSTR filename,
  722. PCTSTR mode = _T("at"),
  723. int shflag = _SH_DENYWR
  724. ) :
  725. m_nIntent(0),
  726. m_nBlock(0),
  727. m_pOwners(pOwners),
  728. m_LogFile(filename, mode, shflag)
  729. {
  730. setvbuf(m_LogFile, 0, _IONBF, 0);
  731. GetLocalTime(&m_StartTime);
  732. StartBlock(_T("TESTRESULT"), FALSE);
  733. }
  734. ~CBvtLog()
  735. {
  736. GetLocalTime(&m_EndTime);
  737. ReportStats();
  738. EndBlock(_T("TESTRESULT"), FALSE);
  739. }
  740. VOID
  741. ReportStats() const
  742. {
  743. _ftprintf(
  744. m_LogFile,
  745. _T("\n")
  746. _T("%*sTEST: %s\n")
  747. _T("%*sRESULT: %s\n")
  748. _T("%*sBUILD: %d\n")
  749. _T("%*sMACHINE: %s\n")
  750. _T("%*sCONTACT: %s\n")
  751. _T("%*sMGR CONTACT: %s\n")
  752. _T("%*sDEV PRIME: %s\n")
  753. _T("%*sDEV ALT: %s\n")
  754. _T("%*sTEST PRIME: %s\n")
  755. _T("%*sTEST ALT: %s\n")
  756. _T("%*sSTART TIME: ") TIME_TO_STR_FORMAT _T("\n")
  757. _T("%*sEND TIME: ") TIME_TO_STR_FORMAT _T("\n")
  758. _T("\n"),
  759. m_nIntent, _T(""), m_pOwners->pTestName,
  760. m_nIntent, _T(""), m_VarResults.Summary(), //bugbug
  761. m_nIntent, _T(""), COSVersionInfo().dwBuildNumber,
  762. m_nIntent, _T(""), (PCTSTR) CComputerName(TRUE),
  763. m_nIntent, _T(""), m_pOwners->pContactName,
  764. m_nIntent, _T(""), m_pOwners->pMgrName,
  765. m_nIntent, _T(""), m_pOwners->pDevPrimeName,
  766. m_nIntent, _T(""), m_pOwners->pDevAltName,
  767. m_nIntent, _T(""), m_pOwners->pTestPrimeName,
  768. m_nIntent, _T(""), m_pOwners->pTestAltName,
  769. m_nIntent, _T(""), TIME_TO_STR_ARGS(m_StartTime),
  770. m_nIntent, _T(""), TIME_TO_STR_ARGS(m_EndTime)
  771. );
  772. }
  773. VOID
  774. LogStr(
  775. DWORD dwLogLevel,
  776. PCTSTR pFile,
  777. int nLine,
  778. PCTSTR pStr,
  779. PCTSTR pComment
  780. )
  781. {
  782. PCTSTR pszText;
  783. int iImage;
  784. CLogWindow::FindNtLogLevel(dwLogLevel, &pszText, &iImage);
  785. _ftprintf(
  786. m_LogFile,
  787. pComment && *pComment ? _T("%*s%s: %s (%s)\n") : _T("%*s%s: %s\n"),
  788. m_nIntent, _T(""),
  789. pszText,
  790. pStr,
  791. pComment
  792. );
  793. }
  794. VOID
  795. StartBlock(PCTSTR pBlockName, BOOL bStamp /*= TRUE*/)
  796. {
  797. SYSTEMTIME st;
  798. GetLocalTime(&st);
  799. _ftprintf(
  800. m_LogFile,
  801. bStamp ? _T("%*s[%s %d - ") TIME_TO_STR_FORMAT _T("]\n") : _T("%*s[%s]\n"),
  802. m_nIntent, _T(""), pBlockName,
  803. InterlockedIncrement(&m_nBlock),
  804. TIME_TO_STR_ARGS(st)
  805. );
  806. m_nIntent += 4;
  807. }
  808. VOID
  809. EndBlock(PCTSTR pBlockName, BOOL bStamp /*= TRUE*/)
  810. {
  811. m_nIntent -= 4;
  812. SYSTEMTIME st;
  813. GetLocalTime(&st);
  814. _ftprintf(
  815. m_LogFile,
  816. bStamp ? _T("%*s[/%s - ") TIME_TO_STR_FORMAT _T("]\n\n") : _T("%*s[/%s]\n\n"),
  817. m_nIntent, _T(""), pBlockName,
  818. TIME_TO_STR_ARGS(st)
  819. );
  820. }
  821. private:
  822. public:
  823. COwners *m_pOwners;
  824. CCFile m_LogFile;
  825. SYSTEMTIME m_StartTime;
  826. SYSTEMTIME m_EndTime;
  827. int m_nIntent; //bugbug
  828. LONG m_nBlock;
  829. };
  830. //////////////////////////////////////////////////////////////////////////
  831. //
  832. //
  833. //
  834. extern CCppMem<CLog> g_pLog;
  835. //////////////////////////////////////////////////////////////////////////
  836. //
  837. //
  838. //
  839. template <DWORD dwLogLevel>
  840. struct CLogHelper
  841. {
  842. PCTSTR
  843. __cdecl
  844. operator ()(
  845. PCTSTR pFormat,
  846. ...
  847. )
  848. {
  849. va_list arglist;
  850. va_start(arglist, pFormat);
  851. return g_pLog->LogV(dwLogLevel, _T(""), 0, pFormat, arglist);
  852. }
  853. };
  854. #endif LOGWRAPPERS_H