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.

759 lines
20 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1997.
  5. //
  6. // File: mylog.cxx
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // Coupling:
  15. //
  16. // Notes:
  17. //
  18. // History: 10-15-1996 ericne Created
  19. //
  20. //----------------------------------------------------------------------------
  21. #include "pch.cxx"
  22. #include <time.h>
  23. #include "clog.hxx"
  24. #include "mydebug.hxx"
  25. // These functions are the same regardless of whether NO_NTLOG is defined or not
  26. //+---------------------------------------------------------------------------
  27. //
  28. // Member: CLog::Log
  29. //
  30. // Synopsis: Log a message. This function creates a va_list object and calls
  31. // the appropriate method to send the message to the log file
  32. //
  33. // Arguments: [dwStyle] -- Style of this message
  34. // [szFileName] -- Name of source file containing this call
  35. // [iLine] -- Line number of this method call
  36. // [szFormat] -- Format string of message
  37. // [ ... ] -- Variable argument list
  38. //
  39. // Returns: TRUE if successful, FALSE otherwise
  40. //
  41. // History: 10-17-1996 ericne Created
  42. //
  43. // Notes:
  44. //
  45. //----------------------------------------------------------------------------
  46. BOOL CLog::Log( DWORD dwStyle, // Flags to be applied to this message
  47. LPTSTR szFileName, // Name of file containing function call
  48. int iLine, // Line number of function call
  49. LPCTSTR szFormat, // Format of the message
  50. ... ) // other arguments
  51. {
  52. BOOL fRetVal = FALSE;
  53. va_list va;
  54. __try
  55. {
  56. va_start( va, szFormat );
  57. fRetVal = vLog( dwStyle, szFileName, iLine, szFormat, va );
  58. }
  59. __finally
  60. {
  61. va_end( va );
  62. }
  63. return( fRetVal );
  64. } //CLog::Log
  65. void CLog::Disable()
  66. {
  67. m_fEnabled = FALSE;
  68. }
  69. void CLog::Enable()
  70. {
  71. m_fEnabled = TRUE;
  72. }
  73. void CLog::SetThreshold( DWORD dwThreshold )
  74. {
  75. m_dwThreshold = dwThreshold;
  76. }
  77. //
  78. // If NO_NTLOG is defined ...
  79. //
  80. #ifdef NO_NTLOG
  81. #include "memsnap.hxx"
  82. // Don't re-order this list!
  83. LPCTSTR szMessageLevel[ cMessageLevels ] = { _T("ABORT"),
  84. _T("SEV1"),
  85. _T("SEV2"),
  86. _T("SEV3"),
  87. _T("WARN"),
  88. _T("PASS"),
  89. _T("CALLTREE"),
  90. _T("SYSTEM"),
  91. _T("TEST"),
  92. _T("VARIATION"),
  93. _T("BLOCK"),
  94. _T("BREAK"),
  95. _T("TESTDEBUG"),
  96. _T("INFO"),
  97. _T(""),
  98. _T("") };
  99. //+---------------------------------------------------------------------------
  100. //
  101. // Member: ::CLog
  102. //
  103. // Synopsis:
  104. //
  105. // Arguments: (none)
  106. //
  107. // Returns:
  108. //
  109. // History: 10-16-1996 ericne Created
  110. //
  111. // Notes:
  112. //
  113. //----------------------------------------------------------------------------
  114. CLog::CLog( )
  115. : m_pLogFile( NULL ),
  116. m_dwLogStyle( 0 ),
  117. m_fEnabled( TRUE ),
  118. m_dwThreshold( dwThresholdMask )
  119. {
  120. InitializeCriticalSection( &m_CriticalSection );
  121. for( int iLoop = 0; iLoop < cMessageLevels; iLoop++ )
  122. m_ulNbrMessages[ iLoop ] = ( ULONG ) 0;
  123. } //::CLog
  124. //+---------------------------------------------------------------------------
  125. //
  126. // Member: ::~CLog
  127. //
  128. // Synopsis:
  129. //
  130. // Arguments: (none)
  131. //
  132. // Returns:
  133. //
  134. // History: 10-16-1996 ericne Created
  135. //
  136. // Notes:
  137. //
  138. //----------------------------------------------------------------------------
  139. CLog::~CLog( )
  140. {
  141. struct tm *newtime;
  142. time_t aclock;
  143. if( m_fEnabled && NULL != m_pLogFile )
  144. {
  145. // Put a blank line between the stats and the memory snapshot
  146. _ftprintf( m_pLogFile, _T("\n****\n") );
  147. // Display a snapshot of the memory
  148. memsnap( m_pLogFile );
  149. // Get time in seconds
  150. time( &aclock );
  151. // Convert time to struct
  152. newtime = localtime( &aclock );
  153. // Display the time of completion
  154. _ftprintf( m_pLogFile, _T("\n**** LOG TERMINATED %s\n"),
  155. _tasctime( newtime ) );
  156. }
  157. // Close the file stream
  158. if( NULL != m_pLogFile && stdout != m_pLogFile )
  159. fclose( m_pLogFile );
  160. m_pLogFile = NULL;
  161. // Delete the critical section
  162. DeleteCriticalSection( &m_CriticalSection );
  163. } //::~CLog
  164. //+---------------------------------------------------------------------------
  165. //
  166. // Member: ::InitLog
  167. //
  168. // Synopsis:
  169. //
  170. // Arguments: [szFileName] --
  171. // [dwStyle] --
  172. //
  173. // Returns:
  174. //
  175. // History: 10-16-1996 ericne Created
  176. //
  177. // Notes:
  178. //
  179. //----------------------------------------------------------------------------
  180. BOOL CLog::InitLog( LPCTSTR szFileName, DWORD dwStyle )
  181. {
  182. LPCTSTR szMode = _T("w");
  183. struct tm *newtime;
  184. time_t aclock;
  185. // If the log has been initialized already, don't reinitialize it
  186. if( NULL != m_pLogFile )
  187. return( FALSE );
  188. m_dwLogStyle = dwStyle;
  189. // If the file name is null, send output to stdout
  190. if( NULL == szFileName )
  191. m_pLogFile = stdout;
  192. else
  193. m_pLogFile = _tfopen( szFileName, szMode );
  194. // If the log file failed to open, return FALSE
  195. if( NULL == m_pLogFile )
  196. {
  197. _RPT1( _CRT_WARN, "CLog::InitLog - Unable to open log file %s\n",
  198. ( szFileName ? szFileName : _T("<standard output") ) );
  199. return( FALSE );
  200. }
  201. // Get time in seconds
  202. time( &aclock );
  203. // Convert time to struct
  204. newtime = localtime( &aclock );
  205. // Display a rudimentary header
  206. _ftprintf( m_pLogFile, _T("**** LOG INITIATED : %s"),
  207. _tasctime( newtime ) );
  208. _ftprintf( m_pLogFile, _T("**** LAST COMPILED : %s %s\n"),
  209. _T(__DATE__), _T(__TIME__) );
  210. _ftprintf( m_pLogFile, _T("**** COMMAND LINE : %s\n"),
  211. GetCommandLine( ) );
  212. _ftprintf( m_pLogFile, _T("\n") );
  213. // Display a snapshot of the memory
  214. memsnap( m_pLogFile );
  215. // Print a blank line
  216. _ftprintf( m_pLogFile, _T("\n****\n") );
  217. return( TRUE );
  218. } //::InitLog
  219. //+---------------------------------------------------------------------------
  220. //
  221. // Member: CLog::AddParticipant
  222. //
  223. // Synopsis:
  224. //
  225. // Arguments: (none)
  226. //
  227. // Returns:
  228. //
  229. // History: 2-05-1997 ericne Created
  230. //
  231. // Notes:
  232. //
  233. //----------------------------------------------------------------------------
  234. BOOL CLog::AddParticipant()
  235. {
  236. if( NULL == m_pLogFile )
  237. return( FALSE );
  238. return( TRUE );
  239. } //CLog::AddParticipant
  240. //+---------------------------------------------------------------------------
  241. //
  242. // Member: CLog::RemoveParticipant
  243. //
  244. // Synopsis:
  245. //
  246. // Arguments: (none)
  247. //
  248. // Returns:
  249. //
  250. // History: 2-05-1997 ericne Created
  251. //
  252. // Notes:
  253. //
  254. //----------------------------------------------------------------------------
  255. BOOL CLog::RemoveParticipant()
  256. {
  257. if( NULL == m_pLogFile )
  258. return( FALSE );
  259. return( TRUE );
  260. } //CLog::RemoveParticipant
  261. //+---------------------------------------------------------------------------
  262. //
  263. // Member: ::Log
  264. //
  265. // Synopsis:
  266. //
  267. // Arguments: [dwStyle] --
  268. // [szFile] --
  269. // [iLine] --
  270. // [szFormat] --
  271. //
  272. // Returns:
  273. //
  274. // History: 10-16-1996 ericne Created
  275. //
  276. // Notes:
  277. //
  278. //----------------------------------------------------------------------------
  279. BOOL CLog::vLog( DWORD dwStyle, // Flags to be applied to this message
  280. LPTSTR szFileName, // Name of file containing function call
  281. int iLine, // Line number of function call
  282. LPCTSTR szFormat, // Format of the message to be logged
  283. va_list va ) // other arguments
  284. {
  285. int iLoop = 0; // Loop counter
  286. BOOL fIsLegalTestType = FALSE; // Flag to determine output style
  287. DWORD dwBitMask = 1L; // Used to isolate flags in dwStyle
  288. TCHAR szMessage[ MaxLogLineLength ]; // Formatted message
  289. BOOL fSuccessful = TRUE; // Return value
  290. // If the log has been disabled, return
  291. if( ! m_fEnabled )
  292. return( TRUE );
  293. // If the log has not been initialized, return FALSE
  294. if( NULL == m_pLogFile )
  295. return( FALSE );
  296. // If the style exceeds the threshold, don't log this message
  297. if( m_dwThreshold < ( dwStyle & dwThresholdMask ) )
  298. return( TRUE );
  299. // Try-finally block ensures that the critical section will be released
  300. __try
  301. {
  302. // Acquire critical section
  303. EnterCriticalSection( &m_CriticalSection );
  304. // If dwStyle is TLS_BREAK, call DebugBreak
  305. if( dwStyle & TLS_BREAK )
  306. DebugBreak( );
  307. // If the current dwStyle does not have a displayable type, return
  308. if( ! ( dwStyle & m_dwLogStyle & dwMessageTypesMask ) )
  309. __leave;
  310. if( -1 == _vsntprintf( szMessage, MaxLogLineLength, szFormat, va ) )
  311. {
  312. // BUGBUG The actual message length excees the maximum length per
  313. // line. Just display MaxLogLineLength characters.
  314. }
  315. // Display the current thread id
  316. if( 0 > _ftprintf( m_pLogFile, _T("%d.%d : "),
  317. GetCurrentProcessId(), GetCurrentThreadId() ) )
  318. {
  319. fSuccessful = FALSE;
  320. __leave;
  321. }
  322. // Display the test types that should be applied to this message
  323. // (TEST, VARIATION,...)
  324. for( iLoop = 0, dwBitMask = 1L;
  325. iLoop < cMessageLevels;
  326. iLoop++, dwBitMask <<= 1L )
  327. {
  328. // Display the type of test this is
  329. if( dwStyle & m_dwLogStyle & dwTestTypesMask & dwBitMask )
  330. {
  331. if( 0 > _ftprintf( m_pLogFile, _T("+%s"),
  332. szMessageLevel[ iLoop ] ) )
  333. {
  334. fSuccessful = FALSE;
  335. __leave;
  336. }
  337. ++m_ulNbrMessages[ iLoop ];
  338. fIsLegalTestType = TRUE;
  339. break;
  340. }
  341. }
  342. // If this is an illegal test type, display the Filename and Line number
  343. if( ! fIsLegalTestType )
  344. {
  345. if( 0 > _ftprintf( m_pLogFile, _T("+FILE : %s +LINE : %d"),
  346. szFileName, iLine ) )
  347. {
  348. fSuccessful = FALSE;
  349. __leave;
  350. }
  351. }
  352. // Display the type of this message (PASS, SEV1, etc..)
  353. for( iLoop = 0, dwBitMask = 1L;
  354. iLoop < cMessageLevels && fIsLegalTestType;
  355. iLoop++, dwBitMask <<= 1L )
  356. {
  357. // Display the type of message this is
  358. if( dwStyle & m_dwLogStyle & dwMessageTypesMask & dwBitMask )
  359. {
  360. if( 0 > _ftprintf( m_pLogFile, _T("+%s"),
  361. szMessageLevel[ iLoop ] ) )
  362. {
  363. fSuccessful = FALSE;
  364. __leave;
  365. }
  366. ++m_ulNbrMessages[ iLoop ];
  367. break;
  368. }
  369. }
  370. if( 0 > _ftprintf( m_pLogFile, _T(" \t%s\n"), szMessage ) )
  371. {
  372. fSuccessful = FALSE;
  373. __leave;
  374. }
  375. } // __try
  376. __finally
  377. {
  378. // Release ownership of critical section
  379. LeaveCriticalSection( &m_CriticalSection );
  380. }
  381. return( fSuccessful );
  382. } //::Log
  383. //+---------------------------------------------------------------------------
  384. //
  385. // Member: CLog::ReportStats
  386. //
  387. // Synopsis:
  388. //
  389. // Arguments: (none)
  390. //
  391. // Returns:
  392. //
  393. // History: 10-18-1996 ericne Created
  394. //
  395. // Notes:
  396. //
  397. //----------------------------------------------------------------------------
  398. void CLog::ReportStats( )
  399. {
  400. // Total tests is number of tests plus number of variations
  401. ULONG ulNbrTests = 0;
  402. if( ! m_fEnabled || NULL == m_pLogFile )
  403. return;
  404. __try
  405. {
  406. EnterCriticalSection( &m_CriticalSection );
  407. ulNbrTests = m_ulNbrMessages[ 0 ] + m_ulNbrMessages[ 1 ] +
  408. m_ulNbrMessages[ 2 ] + m_ulNbrMessages[ 3 ] +
  409. m_ulNbrMessages[ 4 ] + m_ulNbrMessages[ 5 ] +
  410. m_ulNbrMessages[ 10 ];
  411. _ftprintf( m_pLogFile, _T("\n") );
  412. _ftprintf( m_pLogFile, _T("LOG REPORT---------------------------\n") );
  413. _ftprintf( m_pLogFile, _T(" Total Tests : %5d\n"), ulNbrTests );
  414. _ftprintf( m_pLogFile, _T("-------------------------------------\n") );
  415. _ftprintf( m_pLogFile, _T(" Tests Passed %5d %3d%%\n"),
  416. m_ulNbrMessages[ 5 ],
  417. (ulNbrTests ? m_ulNbrMessages[ 5 ] * 100 / ulNbrTests : 0 ) );
  418. _ftprintf( m_pLogFile, _T(" Tests Warned %5d %3d%%\n"),
  419. m_ulNbrMessages[ 4 ],
  420. (ulNbrTests ? m_ulNbrMessages[ 4 ] * 100 / ulNbrTests : 0 ) );
  421. _ftprintf( m_pLogFile, _T(" Tests Failed SEV3 %5d %3d%%\n"),
  422. m_ulNbrMessages[ 3 ],
  423. (ulNbrTests ? m_ulNbrMessages[ 3 ] * 100 / ulNbrTests : 0 ) );
  424. _ftprintf( m_pLogFile, _T(" Tests Failed SEV2 %5d %3d%%\n"),
  425. m_ulNbrMessages[ 2 ],
  426. (ulNbrTests ? m_ulNbrMessages[ 2 ] * 100 / ulNbrTests : 0 ) );
  427. _ftprintf( m_pLogFile, _T(" Tests Failed SEV1 %5d %3d%%\n"),
  428. m_ulNbrMessages[ 1 ],
  429. (ulNbrTests ? m_ulNbrMessages[ 1 ] * 100 / ulNbrTests : 0 ) );
  430. _ftprintf( m_pLogFile, _T(" Tests Blocked %5d %3d%%\n"),
  431. m_ulNbrMessages[ 11 ],
  432. (ulNbrTests ? m_ulNbrMessages[ 11 ] * 100 / ulNbrTests : 0 ));
  433. _ftprintf( m_pLogFile, _T(" Tests Aborted %5d %3d%%\n"),
  434. m_ulNbrMessages[ 0 ],
  435. (ulNbrTests ? m_ulNbrMessages[ 0 ] * 100 / ulNbrTests : 0 ) );
  436. _ftprintf( m_pLogFile, _T("-------------------------------------\n") );
  437. } // __try
  438. __finally
  439. {
  440. LeaveCriticalSection( &m_CriticalSection );
  441. }
  442. } //CLog::ReportStats
  443. //
  444. // NO_NTLOG has not been defined. OK to use NTLOG mechanism
  445. //
  446. #else // NO_NTLOG has not been defined
  447. //+---------------------------------------------------------------------------
  448. //
  449. // Member: ::CLog
  450. //
  451. // Synopsis:
  452. //
  453. // Arguments: (none)
  454. //
  455. // Returns:
  456. //
  457. // History: 10-15-1996 ericne Created
  458. //
  459. // Notes:
  460. //
  461. //----------------------------------------------------------------------------
  462. CLog::CLog( )
  463. : m_hLog( NULL ),
  464. m_fEnabled( TRUE ),
  465. m_dwThreshold( dwThresholdMask )
  466. {
  467. } //::CLog
  468. //+---------------------------------------------------------------------------
  469. //
  470. // Member: ::~CLog
  471. //
  472. // Synopsis:
  473. //
  474. // Arguments: (none)
  475. //
  476. // Returns:
  477. //
  478. // History: 10-15-1996 ericne Created
  479. //
  480. // Notes:
  481. //
  482. //----------------------------------------------------------------------------
  483. CLog::~CLog()
  484. {
  485. if( NULL != m_hLog )
  486. {
  487. if( ! tlDestroyLog( m_hLog ) )
  488. {
  489. _RPT0( _CRT_WARN, "CLog::~CLog : tlDestroyLog failed.\n" );
  490. }
  491. m_hLog = NULL;
  492. }
  493. } //::~CLog
  494. //+---------------------------------------------------------------------------
  495. //
  496. // Member: CLog::ReportStats
  497. //
  498. // Synopsis:
  499. //
  500. // Arguments: (none)
  501. //
  502. // Returns:
  503. //
  504. // History: 2-06-1997 ericne Created
  505. //
  506. // Notes:
  507. //
  508. //----------------------------------------------------------------------------
  509. void CLog::ReportStats( )
  510. {
  511. if( ! m_fEnabled || NULL == m_hLog )
  512. return;
  513. tlReportStats( m_hLog );
  514. } //CLog::ReportStats
  515. //+---------------------------------------------------------------------------
  516. //
  517. // Member: ::InitLog
  518. //
  519. // Synopsis: used ntlog!tlCreateLog and tlAddParticipant to initialize the
  520. // log flie
  521. //
  522. // Arguments: [szFileName] -- namme of the log file
  523. // [dwStyle] -- Style of the log file
  524. //
  525. // Returns: TRUE if successful, FALSE otherwise
  526. //
  527. // History: 10-15-1996 ericne Created
  528. //
  529. // Notes:
  530. //
  531. //----------------------------------------------------------------------------
  532. BOOL CLog::InitLog( LPCTSTR szFileName, DWORD dwStyle )
  533. {
  534. // If the file name is null, log to the monitor
  535. DWORD dwMonitor = ( szFileName ? 0L : TLS_MONITOR );
  536. // If the log has been initialized already, return FASLE
  537. if( NULL != m_hLog )
  538. return( FALSE );
  539. // Create the log
  540. m_hLog = tlCreateLog( szFileName, dwStyle | dwMonitor );
  541. // See if the file was opened correctly
  542. if( NULL == m_hLog )
  543. {
  544. _RPT1( _CRT_WARN, "CLog::InitLog - Could not open log file %s\n",
  545. ( szFileName ? szFileName : _T("<standard output>") ) );
  546. return( FALSE );
  547. }
  548. return( TRUE );
  549. } //::InitLog
  550. //+---------------------------------------------------------------------------
  551. //
  552. // Member: CLog::AddParticipant
  553. //
  554. // Synopsis:
  555. //
  556. // Arguments: (none)
  557. //
  558. // Returns:
  559. //
  560. // History: 2-05-1997 ericne Created
  561. //
  562. // Notes:
  563. //
  564. //----------------------------------------------------------------------------
  565. BOOL CLog::AddParticipant()
  566. {
  567. // If m_hLog is NULL, the log has not been created
  568. if( NULL == m_hLog )
  569. return( FALSE );
  570. // Add a participant
  571. return( tlAddParticipant( m_hLog, ( DWORD )0, ( int )0 ) );
  572. } //CLog::AddParticipant
  573. //+---------------------------------------------------------------------------
  574. //
  575. // Member: CLog::RemoveParticipant
  576. //
  577. // Synopsis:
  578. //
  579. // Arguments: (none)
  580. //
  581. // Returns:
  582. //
  583. // History: 2-05-1997 ericne Created
  584. //
  585. // Notes:
  586. //
  587. //----------------------------------------------------------------------------
  588. BOOL CLog::RemoveParticipant()
  589. {
  590. // Bad call if m_hLog is NULL
  591. if( NULL == m_hLog )
  592. return( FALSE );
  593. return( tlRemoveParticipant( m_hLog ) );
  594. } //CLog::RemoveParticipant
  595. //+---------------------------------------------------------------------------
  596. //
  597. // Member: CLog::vLog
  598. //
  599. // Synopsis: Uses ntlog!tlLog to send a message to the log file
  600. //
  601. // Arguments: [dwStyle] -- style of message
  602. // [szFileName] -- name of file containing the function call
  603. // [iLine] -- line number of function call
  604. // [szFormat] -- format string
  605. // [va] -- variable argument list
  606. //
  607. // Returns: TRUE if successful, false otherwise
  608. //
  609. // History: 1-15-1997 ericne Created
  610. //
  611. // Notes:
  612. //
  613. //----------------------------------------------------------------------------
  614. BOOL CLog::vLog( DWORD dwStyle, // Flags to be applied to this message
  615. LPTSTR szFileName, // Name of file containing function call
  616. int iLine, // Line number of function call
  617. LPCTSTR szFormat, // Format of the message
  618. va_list va ) // other arguments
  619. {
  620. TCHAR szMessage[ MaxLogLineLength ];
  621. BOOL fReturnValue = TRUE;
  622. if( ! m_fEnabled )
  623. return( TRUE );
  624. if( NULL == m_hLog )
  625. return( FALSE );
  626. // If the style exceeds the threshold, don't log this message
  627. if( m_dwThreshold < ( dwStyle & dwThresholdMask ) )
  628. return( TRUE );
  629. if( -1 == _vsntprintf( szMessage, MaxLogLineLength, szFormat, va ) )
  630. {
  631. // Only display the first MaxLogLineLength characters of this message
  632. }
  633. return( tlLog( m_hLog, dwStyle, szFileName, iLine, szMessage ) );
  634. } //CLog::Log
  635. #endif