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.

1005 lines
27 KiB

  1. /*++
  2. Copyright (C) 1998-1999 Microsoft Corporation
  3. Module Name:
  4. smtraceq.cpp
  5. Abstract:
  6. Implementation of the trace log query class.
  7. --*/
  8. #include "Stdafx.h"
  9. #include <pdh.h> // for MIN_TIME_VALUE, MAX_TIME_VALUE
  10. #include "smcfgmsg.h"
  11. #include "smtprov.h"
  12. #include "smtracsv.h"
  13. #include "smtraceq.h"
  14. USE_HANDLE_MACROS("SMLOGCFG(smtraceq.cpp)");
  15. #define TRACE_DEFAULT_BUFFER_SIZE ((DWORD)0x00000004)
  16. #define TRACE_DEFAULT_MIN_COUNT ((DWORD)0x00000003)
  17. #define TRACE_DEFAULT_MAX_COUNT ((DWORD)0x00000019)
  18. #define TRACE_DEFAULT_BUFFER_FLUSH_INT ((DWORD)0)
  19. #define TRACE_DEFAULT_FLAGS ((DWORD)0)
  20. //
  21. // Constructor
  22. CSmTraceLogQuery::CSmTraceLogQuery( CSmLogService* pLogService )
  23. : CSmLogQuery( pLogService ),
  24. m_dwInQueryProviderListLength ( 0 ),
  25. m_szNextInQueryProvider ( NULL ),
  26. mr_szInQueryProviderList ( NULL ),
  27. m_iNextInactiveIndex ( -1 ),
  28. m_dwKernelFlags (0)
  29. {
  30. // initialize member variables
  31. memset (&mr_stlInfo, 0, sizeof(mr_stlInfo));
  32. return;
  33. }
  34. //
  35. // Destructor
  36. CSmTraceLogQuery::~CSmTraceLogQuery()
  37. {
  38. return;
  39. }
  40. //
  41. // Open function. either opens an existing log query entry
  42. // or creates a new one
  43. //
  44. DWORD
  45. CSmTraceLogQuery::Open ( const CString& rstrName, HKEY hKeyQuery, BOOL bReadOnly)
  46. {
  47. DWORD dwStatus = ERROR_SUCCESS;
  48. ASSERT ( SLQ_TRACE_LOG == GetLogType() );
  49. dwStatus = CSmLogQuery::Open ( rstrName, hKeyQuery, bReadOnly );
  50. return dwStatus;
  51. }
  52. //
  53. // Close Function
  54. // closes registry handles and frees allocated memory
  55. //
  56. DWORD
  57. CSmTraceLogQuery::Close ()
  58. {
  59. DWORD dwStatus;
  60. LOCALTRACE (L"Closing Query\n");
  61. if (mr_szInQueryProviderList != NULL) {
  62. delete (mr_szInQueryProviderList);
  63. mr_szInQueryProviderList = NULL;
  64. }
  65. dwStatus = CSmLogQuery::Close();
  66. return dwStatus;
  67. }
  68. //
  69. // UpdateRegistry function.
  70. // copies the current settings to the registry where they
  71. // are read by the log service
  72. //
  73. DWORD
  74. CSmTraceLogQuery::UpdateRegistry() {
  75. DWORD dwStatus = ERROR_SUCCESS;
  76. DWORD dwBufferSize = 0;
  77. DWORD dwTraceFlags = 0;
  78. if ( IsModifiable() ) {
  79. // get trace log values
  80. dwStatus = WriteRegistryDwordValue (
  81. m_hKeyQuery,
  82. IDS_REG_TRACE_BUFFER_SIZE,
  83. &mr_stlInfo.dwBufferSize);
  84. if ( ERROR_SUCCESS == dwStatus ) {
  85. dwStatus = WriteRegistryDwordValue (
  86. m_hKeyQuery,
  87. IDS_REG_TRACE_BUFFER_MIN_COUNT,
  88. &mr_stlInfo.dwMinimumBuffers);
  89. }
  90. if ( ERROR_SUCCESS == dwStatus ) {
  91. dwStatus = WriteRegistryDwordValue (
  92. m_hKeyQuery,
  93. IDS_REG_TRACE_BUFFER_MAX_COUNT,
  94. &mr_stlInfo.dwMaximumBuffers);
  95. }
  96. if ( ERROR_SUCCESS == dwStatus ) {
  97. dwStatus = WriteRegistryDwordValue (
  98. m_hKeyQuery,
  99. IDS_REG_TRACE_BUFFER_FLUSH_INT,
  100. &mr_stlInfo.dwBufferFlushInterval);
  101. }
  102. if ( ERROR_SUCCESS == dwStatus ) {
  103. dwTraceFlags = m_dwKernelFlags | mr_stlInfo.dwBufferFlags;
  104. dwStatus = WriteRegistryDwordValue (
  105. m_hKeyQuery,
  106. IDS_REG_TRACE_FLAGS,
  107. &dwTraceFlags);
  108. }
  109. if ( ERROR_SUCCESS == dwStatus ) {
  110. LPTSTR pszStringBuffer = NULL;
  111. pszStringBuffer = mr_szInQueryProviderList;
  112. dwBufferSize = m_dwInQueryProviderListLength * sizeof (TCHAR);
  113. if ( NULL != pszStringBuffer ) {
  114. dwStatus = WriteRegistryStringValue (
  115. m_hKeyQuery,
  116. IDS_REG_TRACE_PROVIDER_LIST,
  117. REG_MULTI_SZ,
  118. pszStringBuffer,
  119. &dwBufferSize);
  120. }
  121. }
  122. if ( ERROR_SUCCESS == dwStatus ) {
  123. dwStatus = CSmLogQuery::UpdateRegistry ();
  124. }
  125. } else {
  126. dwStatus = ERROR_ACCESS_DENIED;
  127. }
  128. return dwStatus;
  129. }
  130. //
  131. // InitGenProvidersArray()
  132. // reads the current values for this query from the registry
  133. // and WMI configuration and reloads the internal values to match
  134. //
  135. DWORD
  136. CSmTraceLogQuery::InitGenProvidersArray( void )
  137. {
  138. DWORD dwStatus = ERROR_SUCCESS;
  139. CSmTraceProviders* pProvList = NULL;
  140. int iIndex;
  141. int iCount;
  142. LPCTSTR pstrGuid;
  143. ASSERT ( m_pLogService->CastToTraceLogService() );
  144. pProvList = ( m_pLogService->CastToTraceLogService())->GetProviders();
  145. ASSERT ( NULL != pProvList );
  146. iCount = pProvList->GetGenProvCount();
  147. m_arrGenProviders.SetSize ( iCount );
  148. for ( iIndex = 0; iIndex < iCount; iIndex++ ) {
  149. m_arrGenProviders[iIndex] = eNotInQuery;
  150. }
  151. for ( pstrGuid = GetFirstInQueryProvider ( );
  152. NULL != pstrGuid;
  153. pstrGuid = GetNextInQueryProvider ( ) ) {
  154. iIndex = pProvList->IndexFromGuid ( pstrGuid );
  155. if ( -1 == iIndex ) {
  156. CString strEmptyDesc;
  157. CString strNonConstGuid;
  158. eProviderState eAddInQuery = eInQuery;
  159. MFC_TRY
  160. strNonConstGuid = pstrGuid;
  161. MFC_CATCH_DWSTATUS
  162. // Todo: handle string alloc error
  163. // The Guid is probably from another system.
  164. // Add the unknown Guid to the session-wide provider list.
  165. dwStatus = pProvList->AddProvider (
  166. strEmptyDesc,
  167. strNonConstGuid,
  168. FALSE,
  169. FALSE );
  170. // Update the local array to match the session-wide list.
  171. m_arrGenProviders.SetAtGrow( iCount, eAddInQuery );
  172. iIndex = iCount;
  173. VERIFY( ++iCount == pProvList->GetGenProvCount() );
  174. } else {
  175. ASSERT ( iIndex < iCount );
  176. m_arrGenProviders[iIndex] = eInQuery;
  177. }
  178. if ( !IsActiveProvider ( iIndex ) ) {
  179. dwStatus = SMCFG_INACTIVE_PROVIDER;
  180. }
  181. }
  182. // dwStatus is not ERROR_SUCCESS if at least one provider is not currently active on the system.
  183. return dwStatus;
  184. }
  185. //
  186. // SyncWithRegistry()
  187. // reads the current values for this query from the registry
  188. // and WMI and reloads the internal values to match
  189. //
  190. DWORD
  191. CSmTraceLogQuery::SyncWithRegistry()
  192. {
  193. DWORD dwBufferSize = 0;
  194. DWORD dwStatus = ERROR_SUCCESS;
  195. DWORD dwTraceFlags;
  196. DWORD dwKernelTraceFlagMask;
  197. ASSERT (m_hKeyQuery != NULL);
  198. // load Provider string list
  199. // Get Provider List
  200. dwStatus = ReadRegistryStringValue (
  201. m_hKeyQuery,
  202. IDS_REG_TRACE_PROVIDER_LIST,
  203. NULL,
  204. &mr_szInQueryProviderList,
  205. &dwBufferSize);
  206. if (dwStatus != ERROR_SUCCESS) {
  207. m_szNextInQueryProvider = NULL; //re-initialize
  208. m_dwInQueryProviderListLength = 0;
  209. } else {
  210. // convert buffersize to chars from bytes
  211. m_dwInQueryProviderListLength = dwBufferSize / sizeof(TCHAR);
  212. }
  213. // get trace log values
  214. dwStatus = ReadRegistryDwordValue (
  215. m_hKeyQuery,
  216. IDS_REG_TRACE_BUFFER_SIZE,
  217. TRACE_DEFAULT_BUFFER_SIZE,
  218. &mr_stlInfo.dwBufferSize);
  219. ASSERT (dwStatus == ERROR_SUCCESS);
  220. dwStatus = ReadRegistryDwordValue (
  221. m_hKeyQuery,
  222. IDS_REG_TRACE_BUFFER_MIN_COUNT,
  223. TRACE_DEFAULT_MIN_COUNT,
  224. &mr_stlInfo.dwMinimumBuffers);
  225. ASSERT (dwStatus == ERROR_SUCCESS);
  226. // Windows XP the minimum buffer count has changed from 2 to 3.
  227. if ( TRACE_DEFAULT_MIN_COUNT > mr_stlInfo.dwMinimumBuffers ) {
  228. mr_stlInfo.dwMinimumBuffers = TRACE_DEFAULT_MIN_COUNT;
  229. }
  230. dwStatus = ReadRegistryDwordValue (
  231. m_hKeyQuery,
  232. IDS_REG_TRACE_BUFFER_MAX_COUNT,
  233. TRACE_DEFAULT_MAX_COUNT,
  234. &mr_stlInfo.dwMaximumBuffers);
  235. ASSERT (dwStatus == ERROR_SUCCESS);
  236. // Windows XP the minimum buffer count has changed from 2 to 3.
  237. if ( TRACE_DEFAULT_MIN_COUNT > mr_stlInfo.dwMaximumBuffers ) {
  238. mr_stlInfo.dwMaximumBuffers = TRACE_DEFAULT_MIN_COUNT;
  239. }
  240. dwStatus = ReadRegistryDwordValue (
  241. m_hKeyQuery,
  242. IDS_REG_TRACE_BUFFER_FLUSH_INT,
  243. TRACE_DEFAULT_BUFFER_FLUSH_INT,
  244. &mr_stlInfo.dwBufferFlushInterval);
  245. ASSERT (dwStatus == ERROR_SUCCESS);
  246. dwTraceFlags = TRACE_DEFAULT_FLAGS; // Eliminate Prefix warning.
  247. dwStatus = ReadRegistryDwordValue (
  248. m_hKeyQuery,
  249. IDS_REG_TRACE_FLAGS,
  250. TRACE_DEFAULT_FLAGS,
  251. &dwTraceFlags);
  252. ASSERT (dwStatus == ERROR_SUCCESS);
  253. if ( 0 != (dwTraceFlags & SLQ_TLI_ENABLE_BUFFER_FLUSH) ) {
  254. mr_stlInfo.dwBufferFlags = SLQ_TLI_ENABLE_BUFFER_FLUSH;
  255. }
  256. dwKernelTraceFlagMask = SLQ_TLI_ENABLE_KERNEL_TRACE
  257. | SLQ_TLI_ENABLE_PROCESS_TRACE
  258. | SLQ_TLI_ENABLE_THREAD_TRACE
  259. | SLQ_TLI_ENABLE_DISKIO_TRACE
  260. | SLQ_TLI_ENABLE_NETWORK_TCPIP_TRACE
  261. | SLQ_TLI_ENABLE_MEMMAN_TRACE
  262. | SLQ_TLI_ENABLE_FILEIO_TRACE;
  263. m_dwKernelFlags = dwKernelTraceFlagMask & dwTraceFlags;
  264. // Call parent class last, to set shared data.
  265. dwStatus = CSmLogQuery::SyncWithRegistry();
  266. return dwStatus;
  267. }
  268. //
  269. // Get first Provider in list of providers in use
  270. //
  271. LPCTSTR
  272. CSmTraceLogQuery::GetFirstInQueryProvider()
  273. {
  274. LPTSTR szReturn;
  275. szReturn = mr_szInQueryProviderList;
  276. if (szReturn != NULL) {
  277. if (*szReturn == 0) {
  278. // then it's an empty string
  279. szReturn = NULL;
  280. m_szNextInQueryProvider = NULL;
  281. } else {
  282. m_szNextInQueryProvider = szReturn + lstrlen(szReturn) + 1;
  283. if (*m_szNextInQueryProvider == 0) {
  284. // end of list reached so set pointer to NULL
  285. m_szNextInQueryProvider = NULL;
  286. }
  287. }
  288. } else {
  289. // no buffer allocated yet
  290. m_szNextInQueryProvider = NULL;
  291. }
  292. return (LPCTSTR)szReturn;
  293. }
  294. //
  295. // Get next Provider in list of providers in use.
  296. // NULL pointer means no more Providers in list.
  297. //
  298. LPCTSTR
  299. CSmTraceLogQuery::GetNextInQueryProvider()
  300. {
  301. LPTSTR szReturn;
  302. szReturn = m_szNextInQueryProvider;
  303. if (m_szNextInQueryProvider != NULL) {
  304. m_szNextInQueryProvider += lstrlen(szReturn) + 1;
  305. if (*m_szNextInQueryProvider == 0) {
  306. // end of list reached so set pointer to NULL
  307. m_szNextInQueryProvider = NULL;
  308. }
  309. } else {
  310. // already at the end of the list so nothing to do
  311. }
  312. return (LPCTSTR)szReturn;
  313. }
  314. //
  315. // clear out the Provider list
  316. //
  317. VOID
  318. CSmTraceLogQuery::ResetInQueryProviderList()
  319. {
  320. if (mr_szInQueryProviderList != NULL) {
  321. delete (mr_szInQueryProviderList);
  322. m_szNextInQueryProvider = NULL;
  323. mr_szInQueryProviderList = NULL;
  324. }
  325. m_dwInQueryProviderListLength = sizeof(TCHAR); // sizeof MSZ Null
  326. try {
  327. mr_szInQueryProviderList = new TCHAR [m_dwInQueryProviderListLength];
  328. mr_szInQueryProviderList[0] = 0;
  329. } catch ( ... ) {
  330. m_dwInQueryProviderListLength = 0;
  331. }
  332. }
  333. //
  334. // Sync the stored provider list with WMI database.
  335. //
  336. HRESULT
  337. CSmTraceLogQuery::SyncGenProviders( void )
  338. {
  339. HRESULT hr;
  340. CSmTraceProviders* pProvList;
  341. ASSERT ( m_pLogService->CastToTraceLogService() );
  342. pProvList = ( m_pLogService->CastToTraceLogService())->GetProviders();
  343. hr = pProvList->SyncWithConfiguration();
  344. return hr;
  345. }
  346. //
  347. // Update the provided InQuery array to match the stored version.
  348. //
  349. DWORD
  350. CSmTraceLogQuery::GetInQueryProviders( CArray<eProviderState, eProviderState&>& rarrOut )
  351. {
  352. DWORD dwStatus = ERROR_SUCCESS;
  353. int iIndex;
  354. rarrOut.RemoveAll();
  355. rarrOut.SetSize( m_arrGenProviders.GetSize() );
  356. for ( iIndex = 0; iIndex < (INT)rarrOut.GetSize(); iIndex++ ) {
  357. rarrOut[iIndex] = m_arrGenProviders[iIndex];
  358. }
  359. return dwStatus;
  360. }
  361. //
  362. // Return the description for the trace provider specified by
  363. // InQuery array index.
  364. //
  365. LPCTSTR
  366. CSmTraceLogQuery::GetProviderDescription( INT iProvIndex )
  367. {
  368. LPCTSTR pReturn = NULL;
  369. ASSERT ( NULL != m_pLogService );
  370. if ( NULL != m_pLogService ) {
  371. CSmTraceProviders* pProvList;
  372. ASSERT ( m_pLogService->CastToTraceLogService() );
  373. pProvList = ( m_pLogService->CastToTraceLogService())->GetProviders();
  374. ASSERT ( NULL != pProvList );
  375. if ( NULL != pProvList ) {
  376. SLQ_TRACE_PROVIDER* pslqProvider = pProvList->GetProviderInfo( iProvIndex );
  377. pReturn = pslqProvider->strDescription;
  378. }
  379. }
  380. return pReturn;
  381. }
  382. LPCTSTR
  383. CSmTraceLogQuery::GetProviderGuid( INT iProvIndex )
  384. {
  385. LPCTSTR pReturn = NULL;
  386. ASSERT ( NULL != m_pLogService );
  387. if ( NULL != m_pLogService ) {
  388. CSmTraceProviders* pProvList;
  389. ASSERT ( m_pLogService->CastToTraceLogService() );
  390. pProvList = ( m_pLogService->CastToTraceLogService())->GetProviders();
  391. ASSERT ( NULL != pProvList );
  392. if ( NULL != pProvList ) {
  393. SLQ_TRACE_PROVIDER* pslqProvider = pProvList->GetProviderInfo( iProvIndex );
  394. pReturn = pslqProvider->strGuid;
  395. }
  396. }
  397. return pReturn;
  398. }
  399. BOOL
  400. CSmTraceLogQuery::IsEnabledProvider( INT iIndex )
  401. {
  402. BOOL bReturn = FALSE;
  403. ASSERT ( NULL != m_pLogService );
  404. if ( NULL != m_pLogService ) {
  405. CSmTraceProviders* pProvList;
  406. ASSERT ( m_pLogService->CastToTraceLogService() );
  407. pProvList = ( m_pLogService->CastToTraceLogService())->GetProviders();
  408. ASSERT ( NULL != pProvList );
  409. if ( NULL != pProvList ) {
  410. SLQ_TRACE_PROVIDER* pslqProvider = pProvList->GetProviderInfo( iIndex );
  411. bReturn = ( 1 == pslqProvider->iIsEnabled );
  412. }
  413. }
  414. return bReturn;
  415. }
  416. BOOL
  417. CSmTraceLogQuery::IsActiveProvider( INT iIndex )
  418. {
  419. BOOL bReturn = FALSE;
  420. ASSERT ( NULL != m_pLogService );
  421. if ( NULL != m_pLogService ) {
  422. CSmTraceProviders* pProvList;
  423. ASSERT ( m_pLogService->CastToTraceLogService() );
  424. pProvList = ( m_pLogService->CastToTraceLogService())->GetProviders();
  425. ASSERT ( NULL != pProvList );
  426. if ( NULL != pProvList ) {
  427. SLQ_TRACE_PROVIDER* pslqProvider = pProvList->GetProviderInfo( iIndex );
  428. bReturn = ( 1 == pslqProvider->iIsActive );
  429. }
  430. }
  431. return bReturn;
  432. }
  433. LPCTSTR
  434. CSmTraceLogQuery::GetKernelProviderDescription( void )
  435. {
  436. LPCTSTR pReturn = NULL;
  437. ASSERT ( NULL != m_pLogService );
  438. if ( NULL != m_pLogService ) {
  439. CSmTraceProviders* pProvList;
  440. ASSERT ( m_pLogService->CastToTraceLogService() );
  441. pProvList = ( m_pLogService->CastToTraceLogService())->GetProviders();
  442. ASSERT ( NULL != pProvList );
  443. if ( NULL != pProvList ) {
  444. SLQ_TRACE_PROVIDER* pslqProvider = pProvList->GetKernelProviderInfo( );
  445. pReturn = pslqProvider->strDescription;
  446. }
  447. }
  448. return pReturn;
  449. }
  450. BOOL
  451. CSmTraceLogQuery::GetKernelProviderEnabled( void )
  452. {
  453. BOOL bReturn = FALSE;
  454. ASSERT ( NULL != m_pLogService );
  455. if ( NULL != m_pLogService ) {
  456. CSmTraceProviders* pProvList;
  457. ASSERT ( m_pLogService->CastToTraceLogService() );
  458. pProvList = ( m_pLogService->CastToTraceLogService())->GetProviders();
  459. ASSERT ( NULL != pProvList );
  460. if ( NULL != pProvList ) {
  461. SLQ_TRACE_PROVIDER* pslqProvider = pProvList->GetKernelProviderInfo();
  462. bReturn = ( 1 == pslqProvider->iIsEnabled );
  463. }
  464. }
  465. return bReturn;
  466. }
  467. DWORD
  468. CSmTraceLogQuery::GetGenProviderCount( INT& iCount )
  469. {
  470. DWORD dwStatus = ERROR_SUCCESS;
  471. ASSERT ( NULL != m_pLogService );
  472. iCount = 0;
  473. if ( NULL != m_pLogService ) {
  474. CSmTraceProviders* pProvList;
  475. ASSERT ( m_pLogService->CastToTraceLogService() );
  476. pProvList = ( m_pLogService->CastToTraceLogService())->GetProviders();
  477. ASSERT ( NULL != pProvList );
  478. if ( NULL != pProvList ) {
  479. iCount = pProvList->GetGenProvCount();
  480. }
  481. }
  482. return dwStatus;
  483. }
  484. //
  485. // Update the stored InQuery providers list and array
  486. // to match the provided version.
  487. //
  488. DWORD
  489. CSmTraceLogQuery::SetInQueryProviders( CArray<eProviderState, eProviderState&>& rarrIn )
  490. {
  491. DWORD dwStatus = ERROR_SUCCESS;
  492. int iProvIndex;
  493. CSmTraceProviders* pProvList;
  494. m_arrGenProviders.RemoveAll();
  495. m_arrGenProviders.SetSize( rarrIn.GetSize() );
  496. for ( iProvIndex = 0; iProvIndex < (INT)m_arrGenProviders.GetSize(); iProvIndex++ ) {
  497. m_arrGenProviders[iProvIndex] = rarrIn[iProvIndex];
  498. }
  499. ResetInQueryProviderList();
  500. ASSERT ( NULL != m_pLogService );
  501. ASSERT ( m_pLogService->CastToTraceLogService() );
  502. pProvList = ( m_pLogService->CastToTraceLogService())->GetProviders();
  503. ASSERT ( NULL != pProvList );
  504. for ( iProvIndex = 0; iProvIndex < (INT)m_arrGenProviders.GetSize(); iProvIndex++ ) {
  505. if ( eInQuery == m_arrGenProviders[iProvIndex] ) {
  506. SLQ_TRACE_PROVIDER* pslqProvider = pProvList->GetProviderInfo( iProvIndex );
  507. AddInQueryProvider ( pslqProvider->strGuid );
  508. }
  509. }
  510. return dwStatus;
  511. }
  512. //
  513. // Add this Provider string to the internal list
  514. //
  515. BOOL
  516. CSmTraceLogQuery::AddInQueryProvider(LPCTSTR szProviderPath)
  517. {
  518. DWORD dwNewSize;
  519. LPTSTR szNewString;
  520. LPTSTR szNextString;
  521. ASSERT (szProviderPath != NULL);
  522. if (szProviderPath == NULL) return FALSE;
  523. dwNewSize = lstrlen(szProviderPath) + 1;
  524. if (m_dwInQueryProviderListLength <= 2) {
  525. dwNewSize += 1; // add room for the MSZ null
  526. // then this is the first string to go in the list
  527. try {
  528. szNewString = new TCHAR [dwNewSize];
  529. } catch ( ... ) {
  530. return FALSE; // leave now
  531. }
  532. szNextString = szNewString;
  533. } else {
  534. dwNewSize += m_dwInQueryProviderListLength;
  535. // this is the nth string to go in the list
  536. try {
  537. szNewString = new TCHAR [dwNewSize];
  538. } catch ( ... ) {
  539. return FALSE; // leave now
  540. }
  541. memcpy (szNewString, mr_szInQueryProviderList,
  542. (m_dwInQueryProviderListLength * sizeof(TCHAR)));
  543. szNextString = szNewString;
  544. szNextString += m_dwInQueryProviderListLength - 1;
  545. }
  546. lstrcpyW (szNextString, szProviderPath);
  547. szNextString = szNewString;
  548. szNextString += dwNewSize - 1;
  549. *szNextString = 0; // MSZ Null
  550. if (mr_szInQueryProviderList != NULL) delete (mr_szInQueryProviderList);
  551. mr_szInQueryProviderList = szNewString;
  552. m_szNextInQueryProvider = szNewString;
  553. m_dwInQueryProviderListLength = dwNewSize;
  554. return TRUE;
  555. }
  556. //
  557. // Get index of first inactive provider in list of providers for this query.
  558. // -1 indicates no inactive providers in the list.
  559. INT
  560. CSmTraceLogQuery::GetFirstInactiveIndex( void )
  561. {
  562. INT iIndex;
  563. INT iCount;
  564. iCount = (INT)m_arrGenProviders.GetSize();
  565. if ( 0 < iCount ) {
  566. m_iNextInactiveIndex = 0;
  567. iIndex = GetNextInactiveIndex();
  568. } else {
  569. m_iNextInactiveIndex = -1;
  570. iIndex = -1;
  571. }
  572. // szReturn is -1 if no inactive providers.
  573. return iIndex;
  574. }
  575. //
  576. // Get next inactive provider in list of providers for this query.
  577. // -1 indicates no more inactive providers in the list.
  578. //
  579. INT
  580. CSmTraceLogQuery::GetNextInactiveIndex()
  581. {
  582. INT iIndex;
  583. iIndex = m_iNextInactiveIndex;
  584. if ( -1 != iIndex ) {
  585. INT iCount;
  586. iCount = (INT)m_arrGenProviders.GetSize();
  587. for ( ; iIndex < iCount; iIndex++ ) {
  588. if ( !IsActiveProvider ( iIndex ) ) {
  589. break;
  590. }
  591. }
  592. if ( iIndex >= iCount ) {
  593. iIndex = -1;
  594. m_iNextInactiveIndex = -1;
  595. } else {
  596. m_iNextInactiveIndex = iIndex + 1;
  597. ( m_iNextInactiveIndex < iCount ) ? TRUE : m_iNextInactiveIndex = -1;
  598. }
  599. } // else already at the end of the list so nothing to do
  600. return iIndex;
  601. }
  602. //
  603. // Return TRUE if at least one active provider exists on the system.
  604. //
  605. BOOL
  606. CSmTraceLogQuery::ActiveProviderExists()
  607. {
  608. BOOL bActiveExists = FALSE;
  609. INT iCount;
  610. INT iIndex;
  611. iCount = (INT)m_arrGenProviders.GetSize();
  612. for ( iIndex = 0; iIndex < iCount; iIndex++ ) {
  613. if ( IsActiveProvider ( iIndex ) ) {
  614. bActiveExists = TRUE;
  615. break;
  616. }
  617. }
  618. return bActiveExists;
  619. }
  620. BOOL
  621. CSmTraceLogQuery::GetTraceLogInfo (PSLQ_TRACE_LOG_INFO pptlInfo)
  622. {
  623. if (pptlInfo != NULL) {
  624. *pptlInfo = mr_stlInfo;
  625. return TRUE;
  626. } else {
  627. return FALSE;
  628. }
  629. }
  630. BOOL
  631. CSmTraceLogQuery::SetTraceLogInfo (PSLQ_TRACE_LOG_INFO pptlInfo )
  632. {
  633. if (pptlInfo != NULL) {
  634. mr_stlInfo = *pptlInfo;
  635. return TRUE;
  636. } else {
  637. return FALSE;
  638. }
  639. }
  640. BOOL
  641. CSmTraceLogQuery::GetKernelFlags ( DWORD& rdwFlags )
  642. {
  643. rdwFlags = m_dwKernelFlags;
  644. return TRUE;
  645. }
  646. BOOL
  647. CSmTraceLogQuery::SetKernelFlags ( DWORD dwFlags )
  648. {
  649. m_dwKernelFlags = dwFlags;
  650. return TRUE;
  651. }
  652. BOOL
  653. CSmTraceLogQuery::GetLogTime(PSLQ_TIME_INFO pTimeInfo, DWORD dwFlags)
  654. {
  655. BOOL bStatus;
  656. ASSERT ( ( SLQ_TT_TTYPE_START == dwFlags )
  657. || ( SLQ_TT_TTYPE_STOP == dwFlags )
  658. || ( SLQ_TT_TTYPE_RESTART == dwFlags ));
  659. bStatus = CSmLogQuery::GetLogTime( pTimeInfo, dwFlags );
  660. return bStatus;
  661. }
  662. BOOL
  663. CSmTraceLogQuery::SetLogTime(PSLQ_TIME_INFO pTimeInfo, const DWORD dwFlags)
  664. {
  665. BOOL bStatus;
  666. ASSERT ( ( SLQ_TT_TTYPE_START == dwFlags )
  667. || ( SLQ_TT_TTYPE_STOP == dwFlags )
  668. || ( SLQ_TT_TTYPE_RESTART == dwFlags ));
  669. bStatus = CSmLogQuery::SetLogTime( pTimeInfo, dwFlags );
  670. return bStatus;
  671. }
  672. BOOL
  673. CSmTraceLogQuery::GetDefaultLogTime(SLQ_TIME_INFO& rTimeInfo, DWORD dwFlags)
  674. {
  675. ASSERT ( ( SLQ_TT_TTYPE_START == dwFlags )
  676. || ( SLQ_TT_TTYPE_STOP == dwFlags ) );
  677. rTimeInfo.wTimeType = (WORD)dwFlags;
  678. rTimeInfo.wDataType = SLQ_TT_DTYPE_DATETIME;
  679. if ( SLQ_TT_TTYPE_START == dwFlags ) {
  680. SYSTEMTIME stLocalTime;
  681. FILETIME ftLocalTime;
  682. // Milliseconds set to 0 for Schedule times
  683. GetLocalTime (&stLocalTime);
  684. stLocalTime.wMilliseconds = 0;
  685. SystemTimeToFileTime (&stLocalTime, &ftLocalTime);
  686. rTimeInfo.dwAutoMode = SLQ_AUTO_MODE_AT;
  687. rTimeInfo.llDateTime = *(LONGLONG *)&ftLocalTime;
  688. } else {
  689. // Default stop values
  690. rTimeInfo.dwAutoMode = SLQ_AUTO_MODE_NONE;
  691. rTimeInfo.llDateTime = MAX_TIME_VALUE;
  692. }
  693. return TRUE;
  694. }
  695. DWORD
  696. CSmTraceLogQuery::GetLogType()
  697. {
  698. return ( SLQ_TRACE_LOG );
  699. }
  700. HRESULT
  701. CSmTraceLogQuery::LoadFromPropertyBag (
  702. IPropertyBag* pPropBag,
  703. IErrorLog* pIErrorLog )
  704. {
  705. HRESULT hr = S_OK;
  706. CString strParamName;
  707. DWORD dwCount = 0;
  708. DWORD dwIndex;
  709. DWORD dwTraceFlags;
  710. DWORD dwKernelTraceFlagMask;
  711. // Continue even if error, using defaults for missing values.
  712. // Load trace providers
  713. hr = DwordFromPropertyBag (
  714. pPropBag,
  715. pIErrorLog,
  716. IDS_HTML_TRACE_PROVIDER_COUNT,
  717. 0,
  718. dwCount);
  719. for ( dwIndex = 1; dwIndex <= dwCount; dwIndex++ ) {
  720. LPTSTR szProviderGuid = NULL;
  721. DWORD dwBufSize = 0;
  722. strParamName.Format ( IDS_HTML_TRACE_PROVIDER_GUID, dwIndex );
  723. hr = StringFromPropertyBag (
  724. pPropBag,
  725. pIErrorLog,
  726. strParamName,
  727. L"",
  728. &szProviderGuid,
  729. &dwBufSize );
  730. if (dwBufSize > sizeof(TCHAR)) {
  731. AddInQueryProvider ( szProviderGuid );
  732. }
  733. delete (szProviderGuid);
  734. }
  735. // Load trace buffer properties
  736. hr = DwordFromPropertyBag (
  737. pPropBag,
  738. pIErrorLog,
  739. IDS_HTML_TRACE_BUFFER_SIZE,
  740. TRACE_DEFAULT_BUFFER_SIZE,
  741. mr_stlInfo.dwBufferSize);
  742. hr = DwordFromPropertyBag (
  743. pPropBag,
  744. pIErrorLog,
  745. IDS_HTML_TRACE_BUFFER_MIN_COUNT,
  746. TRACE_DEFAULT_MIN_COUNT,
  747. mr_stlInfo.dwMinimumBuffers);
  748. hr = DwordFromPropertyBag (
  749. pPropBag,
  750. pIErrorLog,
  751. IDS_HTML_TRACE_BUFFER_MAX_COUNT,
  752. TRACE_DEFAULT_MAX_COUNT,
  753. mr_stlInfo.dwMaximumBuffers);
  754. hr = DwordFromPropertyBag (
  755. pPropBag,
  756. pIErrorLog,
  757. IDS_HTML_TRACE_BUFFER_FLUSH_INT,
  758. TRACE_DEFAULT_BUFFER_FLUSH_INT,
  759. mr_stlInfo.dwBufferFlushInterval);
  760. hr = DwordFromPropertyBag (
  761. pPropBag,
  762. pIErrorLog,
  763. IDS_HTML_TRACE_FLAGS,
  764. TRACE_DEFAULT_FLAGS,
  765. dwTraceFlags);
  766. if ( 0 != (dwTraceFlags & SLQ_TLI_ENABLE_BUFFER_FLUSH) ) {
  767. mr_stlInfo.dwBufferFlags = SLQ_TLI_ENABLE_BUFFER_FLUSH;
  768. }
  769. dwKernelTraceFlagMask = SLQ_TLI_ENABLE_KERNEL_TRACE
  770. | SLQ_TLI_ENABLE_PROCESS_TRACE
  771. | SLQ_TLI_ENABLE_THREAD_TRACE
  772. | SLQ_TLI_ENABLE_DISKIO_TRACE
  773. | SLQ_TLI_ENABLE_NETWORK_TCPIP_TRACE
  774. | SLQ_TLI_ENABLE_MEMMAN_TRACE
  775. | SLQ_TLI_ENABLE_FILEIO_TRACE;
  776. m_dwKernelFlags = dwKernelTraceFlagMask & dwTraceFlags;
  777. hr = CSmLogQuery::LoadFromPropertyBag( pPropBag, pIErrorLog );
  778. // The GenProviders array is synched with the registry when a properties dialog is opened.
  779. // If no dialog is opened, there is no reason to synchronize it.
  780. return hr;
  781. }
  782. HRESULT
  783. CSmTraceLogQuery::SaveToPropertyBag (
  784. IPropertyBag* pPropBag,
  785. BOOL fSaveAllProps )
  786. {
  787. HRESULT hr = NOERROR;
  788. CString strParamName;
  789. LPCTSTR pszProviderGuid;
  790. DWORD dwTraceFlags;
  791. DWORD dwIndex = 0;
  792. // Save provider Guids
  793. pszProviderGuid = GetFirstInQueryProvider();
  794. MFC_TRY
  795. // Passing sz ( TCHAR[n] ) causes memory alloc, which might throw an exception
  796. while ( NULL != pszProviderGuid ) {
  797. // Provider count starts at 1.
  798. strParamName.Format ( IDS_HTML_TRACE_PROVIDER_GUID, ++dwIndex );
  799. hr = StringToPropertyBag ( pPropBag, strParamName, pszProviderGuid );
  800. pszProviderGuid = GetNextInQueryProvider();
  801. }
  802. hr = DwordToPropertyBag ( pPropBag, IDS_HTML_TRACE_PROVIDER_COUNT, dwIndex );
  803. MFC_CATCH_HR
  804. // Todo: Handle error
  805. // Save trace buffer properties
  806. hr = DwordToPropertyBag ( pPropBag, IDS_HTML_TRACE_BUFFER_SIZE, mr_stlInfo.dwBufferSize );
  807. hr = DwordToPropertyBag ( pPropBag, IDS_HTML_TRACE_BUFFER_MIN_COUNT, mr_stlInfo.dwMinimumBuffers );
  808. hr = DwordToPropertyBag ( pPropBag, IDS_HTML_TRACE_BUFFER_MAX_COUNT, mr_stlInfo.dwMaximumBuffers );
  809. hr = DwordToPropertyBag ( pPropBag, IDS_HTML_TRACE_BUFFER_FLUSH_INT, mr_stlInfo.dwBufferFlushInterval );
  810. dwTraceFlags = m_dwKernelFlags | mr_stlInfo.dwBufferFlags;
  811. hr = DwordToPropertyBag ( pPropBag, IDS_HTML_TRACE_FLAGS, dwTraceFlags );
  812. hr = CSmLogQuery::SaveToPropertyBag( pPropBag, fSaveAllProps );
  813. return hr;
  814. }