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.

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