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.

3453 lines
94 KiB

  1. /*++
  2. Copyright (C) 1998-1999 Microsoft Corporation
  3. Module Name:
  4. smlogqry.cpp
  5. Abstract:
  6. Implementation of the CSmLogQuery base class. This object
  7. is used to represent performance data log queries (a.k.a.
  8. sysmon log queries).
  9. --*/
  10. #include "Stdafx.h"
  11. #include <pdh.h> // for MIN_TIME_VALUE, MAX_TIME_VALUE
  12. #include <pdhmsg.h> // for PDH status values
  13. #include <pdhp.h> // for PLA methods
  14. #include "ipropbag.h"
  15. #include "smlogs.h"
  16. #include "smcfgmsg.h"
  17. #include "smproppg.h"
  18. #include "smlogqry.h"
  19. USE_HANDLE_MACROS("SMLOGCFG(smlogqry.cpp)");
  20. #define DEFAULT_LOG_FILE_SERIAL_NUMBER ((DWORD)0x00000001)
  21. #define DEFAULT_LOG_FILE_MAX_SIZE ((DWORD)-1)
  22. #define DEFAULT_CTR_LOG_FILE_TYPE (SLF_BIN_FILE)
  23. #define DEFAULT_TRACE_LOG_FILE_TYPE (SLF_SEQ_TRACE_FILE)
  24. #define DEFAULT_LOG_FILE_AUTO_FORMAT SLF_NAME_NNNNNN
  25. #define DEFAULT_CURRENT_STATE SLQ_QUERY_STOPPED
  26. #define DEFAULT_EXECUTE_ONLY 0
  27. #define DEFAULT_EOF_COMMAND_FILE L""
  28. #define DEFAULT_RESTART_VALUE ((DWORD)0)
  29. #define DEFAULT_COMMENT L""
  30. #define DEFAULT_SQL_LOG_BASE_NAME L""
  31. #pragma warning ( disable : 4201)
  32. typedef union {
  33. struct {
  34. SHORT iMajor;
  35. SHORT iMinor;
  36. };
  37. DWORD dwVersion;
  38. } SMONCTRL_VERSION_DATA;
  39. #pragma warning ( default : 4201 )
  40. #define SMONCTRL_MAJ_VERSION 3
  41. #define SMONCTRL_MIN_VERSION 3
  42. DWORD g_dwRealTimeQuery = DATA_SOURCE_REGISTRY;
  43. const CString CSmLogQuery::cstrEmpty;
  44. //
  45. // Constructor
  46. CSmLogQuery::CSmLogQuery( CSmLogService* pLogService )
  47. : m_pLogService ( pLogService ),
  48. m_bReadOnly ( FALSE ),
  49. m_bIsModified ( FALSE ),
  50. m_bIsNew ( FALSE ),
  51. m_bExecuteOnly ( FALSE ),
  52. m_pActivePropPage ( NULL ),
  53. mr_dwCurrentState ( SLQ_QUERY_STOPPED ),
  54. mr_dwMaxSize ( 0 ),
  55. mr_dwFileSizeUnits ( 0 ),
  56. mr_dwAppendMode ( 0 ),
  57. mr_dwLogAutoFormat ( 0 ),
  58. mr_dwLogFileType ( 0 )
  59. {
  60. // initialize member variables
  61. memset (&mr_stiStart, 0, sizeof(mr_stiStart));
  62. memset (&mr_stiStop, 0, sizeof(mr_stiStop));
  63. memset (&m_PropData.stiSampleTime, 0, sizeof(m_PropData.stiSampleTime));
  64. m_PropData.dwMaxFileSize = 0;
  65. m_PropData.dwLogFileType = 0;
  66. m_PropData.dwSuffix = 0;
  67. m_PropData.dwSerialNumber = 0;
  68. mr_dwRealTimeQuery = g_dwRealTimeQuery;
  69. m_fDirtyPassword = PASSWORD_CLEAN;
  70. // All CString variables are empty on construction
  71. return;
  72. }
  73. //
  74. // Destructor
  75. CSmLogQuery::~CSmLogQuery()
  76. {
  77. // make sure Close method was called first!
  78. ASSERT ( NULL == m_hKeyQuery );
  79. ASSERT ( m_strName.IsEmpty() );
  80. ASSERT ( mr_strComment.IsEmpty() );
  81. ASSERT ( mr_strCommentIndirect.IsEmpty() );
  82. ASSERT ( mr_strBaseFileName.IsEmpty() );
  83. ASSERT ( mr_strBaseFileNameIndirect.IsEmpty() );
  84. ASSERT ( mr_strSqlName.IsEmpty() );
  85. ASSERT ( mr_strDefaultDirectory.IsEmpty() );
  86. return;
  87. }
  88. //
  89. // helper functions
  90. //
  91. LONG
  92. CSmLogQuery::WriteRegistryStringValue (
  93. HKEY hKey,
  94. UINT uiValueName,
  95. DWORD dwType,
  96. LPCTSTR pszBuffer,
  97. LPDWORD pdwBufSize
  98. )
  99. // writes the contents of pszBuffer to szValue under hKey
  100. {
  101. LONG dwStatus = ERROR_SUCCESS;
  102. DWORD dwLclSize;
  103. CONST BYTE *pLclBuffer = NULL;
  104. CString strValueName;
  105. ResourceStateManager rsm;
  106. if ( NULL != hKey ) {
  107. MFC_TRY
  108. strValueName.LoadString ( uiValueName );
  109. MFC_CATCH_DWSTATUS;
  110. if ( ERROR_SUCCESS == dwStatus ) {
  111. ASSERT ((dwType == REG_SZ) ||
  112. (dwType == REG_MULTI_SZ) ||
  113. (dwType == REG_EXPAND_SZ));
  114. if ( NULL == pszBuffer ) {
  115. // substitute an empty string
  116. pLclBuffer = (CONST BYTE *)L"\0";
  117. dwLclSize = sizeof(WCHAR);
  118. } else {
  119. // use args passed in
  120. pLclBuffer = (CONST BYTE *)pszBuffer;
  121. if ( NULL != pdwBufSize ) {
  122. if( 0 == *pdwBufSize ){
  123. dwLclSize = lstrlen( pszBuffer );
  124. if ( 0 < dwLclSize ) {
  125. dwLclSize *= sizeof(WCHAR);
  126. } else {
  127. dwLclSize = sizeof(WCHAR);
  128. }
  129. } else {
  130. dwLclSize = *pdwBufSize;
  131. }
  132. } else {
  133. dwLclSize = lstrlen( pszBuffer );
  134. dwLclSize *= sizeof(WCHAR);
  135. }
  136. }
  137. dwStatus = RegSetValueEx (hKey,
  138. strValueName,
  139. 0L,
  140. dwType,
  141. (CONST BYTE *)pLclBuffer,
  142. dwLclSize);
  143. }
  144. } else {
  145. dwStatus = ERROR_INVALID_PARAMETER;
  146. }
  147. return dwStatus;
  148. }
  149. LONG
  150. CSmLogQuery::WriteRegistryDwordValue (
  151. HKEY hKey,
  152. UINT uiValueName,
  153. LPDWORD pdwValue,
  154. DWORD dwType
  155. )
  156. {
  157. LONG dwStatus = ERROR_SUCCESS;
  158. DWORD dwSize = sizeof(DWORD);
  159. CString strValueName;
  160. ResourceStateManager rsm;
  161. if ( NULL != pdwValue && NULL != hKey ) {
  162. MFC_TRY
  163. strValueName.LoadString ( uiValueName );
  164. MFC_CATCH_DWSTATUS;
  165. if ( ERROR_SUCCESS == dwStatus ) {
  166. ASSERT ((dwType == REG_DWORD) ||
  167. (dwType == REG_BINARY));
  168. dwStatus = RegSetValueEx (
  169. hKey, strValueName, 0L,
  170. dwType,
  171. (CONST BYTE *)pdwValue,
  172. dwSize);
  173. }
  174. } else {
  175. ASSERT ( FALSE );
  176. dwStatus = ERROR_INVALID_PARAMETER;
  177. }
  178. return dwStatus;
  179. }
  180. LONG
  181. CSmLogQuery::WriteRegistrySlqTime (
  182. HKEY hKey,
  183. UINT uiValueName,
  184. PSLQ_TIME_INFO pSlqTime
  185. )
  186. {
  187. LONG dwStatus = ERROR_SUCCESS;
  188. DWORD dwValue = sizeof(SLQ_TIME_INFO);
  189. CString strValueName;
  190. ResourceStateManager rsm;
  191. if ( NULL != pSlqTime && NULL != hKey ) {
  192. MFC_TRY
  193. strValueName.LoadString ( uiValueName );
  194. MFC_CATCH_DWSTATUS;
  195. if ( ERROR_SUCCESS == dwStatus ) {
  196. dwStatus = RegSetValueEx (
  197. hKey, strValueName, 0L,
  198. REG_BINARY,
  199. (CONST BYTE *)pSlqTime,
  200. dwValue);
  201. }
  202. } else {
  203. ASSERT ( FALSE );
  204. dwStatus = ERROR_INVALID_PARAMETER;
  205. }
  206. return dwStatus;
  207. }
  208. LONG
  209. CSmLogQuery::ReadRegistryStringValue (
  210. HKEY hKey,
  211. UINT uiValueName,
  212. LPCTSTR szDefault,
  213. LPTSTR *pszBuffer,
  214. LPDWORD pdwBufferSize
  215. )
  216. //
  217. // reads the string value from key (name based on resource
  218. // uiValueName) under hKey and
  219. // frees any existing buffer referenced by szInBuffer,
  220. // then allocates a new buffer returning it with the
  221. // string value read from the registry and the size of the
  222. // buffer (in bytes)
  223. //
  224. {
  225. DWORD dwStatus = ERROR_SUCCESS;
  226. DWORD dwType = 0;
  227. DWORD dwBufferSize = 0;
  228. TCHAR* szNewStringBuffer = NULL;
  229. CString strValueName;
  230. ResourceStateManager rsm;
  231. if ( NULL != hKey ) {
  232. MFC_TRY
  233. strValueName.LoadString ( uiValueName );
  234. MFC_CATCH_DWSTATUS;
  235. ASSERT (!strValueName.IsEmpty());
  236. if ( ERROR_SUCCESS == dwStatus && hKey != NULL) {
  237. // then there should be something to read
  238. // find out the size of the required buffer
  239. dwStatus = RegQueryValueExW (
  240. hKey,
  241. strValueName,
  242. NULL,
  243. &dwType,
  244. NULL,
  245. &dwBufferSize);
  246. if (dwStatus == ERROR_SUCCESS) {
  247. // NULL character size is 2 bytes
  248. if (dwBufferSize > 2) {
  249. // then there's something to read
  250. MFC_TRY
  251. szNewStringBuffer = new TCHAR[dwBufferSize/sizeof(TCHAR)];
  252. dwType = 0;
  253. dwStatus = RegQueryValueExW (
  254. hKey,
  255. strValueName,
  256. NULL,
  257. &dwType,
  258. (LPBYTE)szNewStringBuffer,
  259. &dwBufferSize);
  260. MFC_CATCH_DWSTATUS
  261. } else {
  262. // nothing to read
  263. dwStatus = ERROR_NO_DATA;
  264. }
  265. } else {
  266. // unable to read buffer
  267. // dwStatus has error
  268. }
  269. } else {
  270. // null key
  271. dwStatus = ERROR_BADKEY;
  272. }
  273. if (dwStatus != ERROR_SUCCESS) {
  274. if (szNewStringBuffer != NULL) {
  275. delete (szNewStringBuffer);
  276. szNewStringBuffer = NULL;
  277. }
  278. // apply default
  279. if (szDefault != NULL) {
  280. dwBufferSize = lstrlen(szDefault) + 1;
  281. dwBufferSize *= sizeof (TCHAR);
  282. MFC_TRY
  283. szNewStringBuffer = new TCHAR[dwBufferSize];
  284. lstrcpy (
  285. szNewStringBuffer,
  286. szDefault);
  287. dwStatus = ERROR_SUCCESS;
  288. MFC_CATCH_DWSTATUS
  289. } else {
  290. // no default so no data returned
  291. }
  292. }
  293. if (dwStatus == ERROR_SUCCESS) {
  294. // then delete the old buffer and replace it with
  295. // the new one
  296. if ( NULL != *pszBuffer ) {
  297. delete (*pszBuffer );
  298. }
  299. *pszBuffer = szNewStringBuffer;
  300. if ( NULL != pdwBufferSize ) {
  301. *pdwBufferSize = dwBufferSize;
  302. }
  303. } else {
  304. // if error then delete the buffer
  305. if (szNewStringBuffer != NULL) {
  306. delete (szNewStringBuffer);
  307. }
  308. }
  309. } else {
  310. ASSERT ( FALSE );
  311. dwStatus = ERROR_INVALID_PARAMETER;
  312. }
  313. return dwStatus;
  314. }
  315. LONG
  316. CSmLogQuery::ReadRegistrySlqTime (
  317. HKEY hKey,
  318. UINT uiValueName,
  319. PSLQ_TIME_INFO pstiDefault,
  320. PSLQ_TIME_INFO pSlqValue
  321. )
  322. //
  323. // reads the time value "szValueName" from under hKey and
  324. // returns it in the Value buffer
  325. //
  326. {
  327. DWORD dwStatus = ERROR_SUCCESS;
  328. DWORD dwType = 0;
  329. DWORD dwBufferSize = 0;
  330. SLQ_TIME_INFO slqLocal;
  331. CString strValueName;
  332. ResourceStateManager rsm;
  333. if ( NULL != pSlqValue && NULL != hKey ) {
  334. MFC_TRY
  335. strValueName.LoadString ( uiValueName );
  336. MFC_CATCH_DWSTATUS;
  337. ASSERT (!strValueName.IsEmpty());
  338. if ( ERROR_SUCCESS == dwStatus ) {
  339. memset (&slqLocal, 0, sizeof(SLQ_TIME_INFO));
  340. if (hKey != NULL) {
  341. // then there should be something to read
  342. // find out the size of the required buffer
  343. dwStatus = RegQueryValueExW (
  344. hKey,
  345. strValueName,
  346. NULL,
  347. &dwType,
  348. NULL,
  349. &dwBufferSize);
  350. if (dwStatus == ERROR_SUCCESS) {
  351. if ((dwBufferSize == sizeof(SLQ_TIME_INFO)) && (dwType == REG_BINARY)) {
  352. // then there's something to read
  353. dwType = 0;
  354. dwStatus = RegQueryValueExW (
  355. hKey,
  356. strValueName,
  357. NULL,
  358. &dwType,
  359. (LPBYTE)&slqLocal,
  360. &dwBufferSize);
  361. } else {
  362. // nothing to read
  363. dwStatus = ERROR_NO_DATA;
  364. }
  365. } else {
  366. // unable to read buffer
  367. // dwStatus has error
  368. }
  369. } else {
  370. // null key
  371. dwStatus = ERROR_BADKEY;
  372. }
  373. if (dwStatus == ERROR_SUCCESS) {
  374. *pSlqValue = slqLocal;
  375. } else {
  376. // apply default if it exists
  377. if (pstiDefault != NULL) {
  378. *pSlqValue = *pstiDefault;
  379. dwStatus = ERROR_SUCCESS;
  380. }
  381. }
  382. }
  383. } else {
  384. ASSERT ( FALSE );
  385. dwStatus = ERROR_INVALID_PARAMETER;
  386. }
  387. return dwStatus;
  388. }
  389. LONG
  390. CSmLogQuery::ReadRegistryDwordValue (
  391. HKEY hKey,
  392. UINT uiValueName,
  393. DWORD dwDefault,
  394. LPDWORD pdwValue
  395. )
  396. //
  397. // reads the DWORD value "szValueName" from under hKey and
  398. // returns it in the Value buffer
  399. //
  400. {
  401. DWORD dwStatus = ERROR_SUCCESS;
  402. DWORD dwType = 0;
  403. DWORD dwBufferSize = 0;
  404. DWORD dwRegValue = 0;
  405. CString strValueName;
  406. ResourceStateManager rsm;
  407. if ( NULL != pdwValue && NULL != hKey ) {
  408. MFC_TRY
  409. strValueName.LoadString ( uiValueName );
  410. MFC_CATCH_DWSTATUS;
  411. ASSERT (!strValueName.IsEmpty());
  412. if ( ERROR_SUCCESS == dwStatus ) {
  413. if (hKey != NULL) {
  414. // then there should be something to read
  415. // find out the size of the required buffer
  416. dwStatus = RegQueryValueExW (
  417. hKey,
  418. strValueName,
  419. NULL,
  420. &dwType,
  421. NULL,
  422. &dwBufferSize);
  423. if (dwStatus == ERROR_SUCCESS) {
  424. if ( (dwBufferSize == sizeof(DWORD))
  425. && ( (REG_DWORD == dwType) || ( REG_BINARY == dwType) ) ) {
  426. // then there's something to read
  427. dwType = 0;
  428. dwStatus = RegQueryValueExW (
  429. hKey,
  430. strValueName,
  431. NULL,
  432. &dwType,
  433. (LPBYTE)&dwRegValue,
  434. &dwBufferSize);
  435. } else {
  436. // nothing to read
  437. dwStatus = ERROR_NO_DATA;
  438. }
  439. } else {
  440. // unable to read buffer
  441. // dwStatus has error
  442. }
  443. } else {
  444. // null key
  445. dwStatus = ERROR_BADKEY;
  446. }
  447. if (dwStatus == ERROR_SUCCESS) {
  448. *pdwValue = dwRegValue;
  449. } else {
  450. *pdwValue = dwDefault;
  451. dwStatus = ERROR_SUCCESS;
  452. }
  453. }
  454. } else {
  455. ASSERT ( FALSE );
  456. dwStatus = ERROR_INVALID_PARAMETER;
  457. }
  458. return dwStatus;
  459. }
  460. HRESULT
  461. CSmLogQuery::StringToPropertyBag (
  462. IPropertyBag* pPropBag,
  463. UINT uiPropName,
  464. const CString& rstrData )
  465. {
  466. HRESULT hr = NOERROR;
  467. CString strPropName;
  468. ResourceStateManager rsm;
  469. MFC_TRY
  470. strPropName.LoadString ( uiPropName );
  471. hr = StringToPropertyBag ( pPropBag, strPropName, rstrData );
  472. MFC_CATCH_HR
  473. return hr;
  474. }
  475. typedef struct _HTML_ENTITIES {
  476. LPTSTR szHTML;
  477. LPTSTR szEntity;
  478. } HTML_ENTITIES;
  479. HTML_ENTITIES g_htmlentities[] = {
  480. _T("&"), _T("&amp;"),
  481. _T("\""), _T("&quot;"),
  482. _T("<"), _T("&lt;"),
  483. _T(">"), _T("&gt;"),
  484. NULL, NULL
  485. };
  486. HRESULT
  487. CSmLogQuery::StringToPropertyBag (
  488. IPropertyBag* pIPropBag,
  489. const CString& rstrPropName,
  490. const CString& rstrData )
  491. {
  492. VARIANT vValue;
  493. HRESULT hr = NOERROR;
  494. LPTSTR szTrans = NULL;
  495. BOOL bAllocated = FALSE;
  496. int i;
  497. ULONG lSize = 0;
  498. LPTSTR szScan = NULL;
  499. if ( NULL != pIPropBag ) {
  500. VariantInit( &vValue );
  501. vValue.vt = VT_BSTR;
  502. vValue.bstrVal = NULL;
  503. if ( !rstrData.IsEmpty() ) {
  504. MFC_TRY
  505. for( i=0 ;g_htmlentities[i].szHTML != NULL; i++ ){
  506. // rstrData is const
  507. szScan = ((CString)rstrData).GetBuffer ( rstrData.GetLength() );
  508. while( *szScan != _T('\0') ){
  509. if( *szScan == *g_htmlentities[i].szHTML ){
  510. lSize += (6*sizeof(TCHAR));
  511. }
  512. szScan++;
  513. }
  514. ((CString)rstrData).ReleaseBuffer();
  515. }
  516. if( lSize > 0 ){
  517. szTrans = (LPTSTR)malloc(lSize);
  518. if( szTrans != NULL ){
  519. bAllocated = TRUE;
  520. ZeroMemory( szTrans, lSize );
  521. szScan = ((CString)rstrData).GetBuffer ( rstrData.GetLength() );
  522. while( *szScan != _T('\0') ){
  523. BOOL bEntity = FALSE;
  524. for( i=0; g_htmlentities[i].szHTML != NULL; i++ ){
  525. if( *szScan == *g_htmlentities[i].szHTML ){
  526. bEntity = TRUE;
  527. _tcscat( szTrans, g_htmlentities[i].szEntity );
  528. break;
  529. }
  530. }
  531. if( !bEntity ){
  532. _tcsncat( szTrans, szScan, 1 );
  533. }
  534. szScan++;
  535. }
  536. }
  537. }else{
  538. szTrans = ((CString)rstrData).GetBuffer ( rstrData.GetLength() );
  539. }
  540. vValue.bstrVal = ::SysAllocString ( T2W( szTrans ) );
  541. hr = pIPropBag->Write ( rstrPropName, &vValue );
  542. VariantClear ( &vValue );
  543. ((CString)rstrData).ReleaseBuffer();
  544. MFC_CATCH_HR
  545. } else {
  546. hr = pIPropBag->Write(rstrPropName, &vValue );
  547. }
  548. }
  549. if( NULL != szTrans && bAllocated ){
  550. free( szTrans );
  551. }
  552. return hr;
  553. }
  554. HRESULT
  555. CSmLogQuery::DwordToPropertyBag (
  556. IPropertyBag* pPropBag,
  557. UINT uiPropName,
  558. DWORD dwData )
  559. {
  560. HRESULT hr;
  561. CString strPropName;
  562. ResourceStateManager rsm;
  563. strPropName.LoadString ( uiPropName );
  564. hr = DwordToPropertyBag (
  565. pPropBag,
  566. strPropName,
  567. dwData );
  568. return hr;
  569. }
  570. HRESULT
  571. CSmLogQuery::DwordToPropertyBag (
  572. IPropertyBag* pPropBag,
  573. const CString& rstrPropName,
  574. DWORD dwData )
  575. {
  576. VARIANT vValue;
  577. HRESULT hr;
  578. VariantInit( &vValue );
  579. vValue.vt = VT_I4;
  580. vValue.lVal = (INT)dwData;
  581. hr = pPropBag->Write(rstrPropName, &vValue );
  582. VariantClear ( &vValue );
  583. return hr;
  584. }
  585. HRESULT
  586. CSmLogQuery::DoubleToPropertyBag (
  587. IPropertyBag* pPropBag,
  588. UINT uiPropName,
  589. DOUBLE dData )
  590. {
  591. HRESULT hr;
  592. CString strPropName;
  593. ResourceStateManager rsm;
  594. MFC_TRY
  595. strPropName.LoadString ( uiPropName );
  596. hr = DoubleToPropertyBag (
  597. pPropBag,
  598. strPropName,
  599. dData );
  600. MFC_CATCH_HR
  601. return hr;
  602. }
  603. HRESULT
  604. CSmLogQuery::DoubleToPropertyBag (
  605. IPropertyBag* pPropBag,
  606. const CString& rstrPropName,
  607. DOUBLE dData )
  608. {
  609. VARIANT vValue;
  610. HRESULT hr;
  611. VariantInit( &vValue );
  612. vValue.vt = VT_R8;
  613. vValue.dblVal = dData;
  614. hr = pPropBag->Write(rstrPropName, &vValue );
  615. VariantClear ( &vValue );
  616. return hr;
  617. }
  618. HRESULT
  619. CSmLogQuery::FloatToPropertyBag (
  620. IPropertyBag* pPropBag,
  621. UINT uiPropName,
  622. FLOAT fData )
  623. {
  624. HRESULT hr;
  625. CString strPropName;
  626. ResourceStateManager rsm;
  627. MFC_TRY
  628. strPropName.LoadString ( uiPropName );
  629. hr = FloatToPropertyBag (
  630. pPropBag,
  631. strPropName,
  632. fData );
  633. MFC_CATCH_HR
  634. return hr;
  635. }
  636. HRESULT
  637. CSmLogQuery::FloatToPropertyBag (
  638. IPropertyBag* pPropBag,
  639. const CString& rstrPropName,
  640. FLOAT fData )
  641. {
  642. VARIANT vValue;
  643. HRESULT hr;
  644. VariantInit( &vValue );
  645. vValue.vt = VT_R4;
  646. vValue.fltVal = fData;
  647. hr = pPropBag->Write(rstrPropName, &vValue );
  648. VariantClear ( &vValue );
  649. return hr;
  650. }
  651. HRESULT
  652. CSmLogQuery::LLTimeToPropertyBag (
  653. IPropertyBag* pIPropBag,
  654. UINT uiPropName,
  655. LONGLONG& rllData )
  656. {
  657. HRESULT hr;
  658. VARIANT vValue;
  659. CString strPropName;
  660. ResourceStateManager rsm;
  661. MFC_TRY
  662. strPropName.LoadString ( uiPropName );
  663. VariantInit( &vValue );
  664. vValue.vt = VT_DATE;
  665. if ( LLTimeToVariantDate ( rllData, &vValue.date ) ) {
  666. hr = pIPropBag->Write(strPropName, &vValue );
  667. VariantClear ( &vValue );
  668. } else {
  669. hr = E_FAIL;
  670. }
  671. MFC_CATCH_HR
  672. return hr;
  673. }
  674. HRESULT
  675. CSmLogQuery::SlqTimeToPropertyBag (
  676. IPropertyBag* pPropBag,
  677. DWORD dwFlags,
  678. PSLQ_TIME_INFO pSlqData )
  679. {
  680. HRESULT hr = NOERROR;
  681. ASSERT ( NULL != pSlqData );
  682. switch (dwFlags) {
  683. case SLQ_TT_TTYPE_START:
  684. ASSERT ( SLQ_TT_TTYPE_START == pSlqData->wTimeType );
  685. hr = DwordToPropertyBag ( pPropBag, IDS_HTML_START_MODE, pSlqData->dwAutoMode );
  686. if ( SLQ_AUTO_MODE_AT == pSlqData->dwAutoMode ) {
  687. ASSERT ( SLQ_TT_DTYPE_DATETIME == pSlqData->wDataType );
  688. hr = LLTimeToPropertyBag ( pPropBag, IDS_HTML_START_AT_TIME, pSlqData->llDateTime );
  689. }
  690. break;
  691. case SLQ_TT_TTYPE_STOP:
  692. ASSERT ( SLQ_TT_TTYPE_STOP == pSlqData->wTimeType );
  693. hr = DwordToPropertyBag ( pPropBag, IDS_HTML_STOP_MODE, pSlqData->dwAutoMode );
  694. if ( SLQ_AUTO_MODE_AT == pSlqData->dwAutoMode ) {
  695. ASSERT ( SLQ_TT_DTYPE_DATETIME == pSlqData->wDataType );
  696. hr = LLTimeToPropertyBag ( pPropBag, IDS_HTML_STOP_AT_TIME, pSlqData->llDateTime );
  697. } else if ( SLQ_AUTO_MODE_AFTER == pSlqData->dwAutoMode ) {
  698. ASSERT ( SLQ_TT_DTYPE_UNITS == pSlqData->wDataType );
  699. hr = DwordToPropertyBag (
  700. pPropBag,
  701. IDS_HTML_STOP_AFTER_UNIT_TYPE,
  702. pSlqData->dwUnitType );
  703. hr = DwordToPropertyBag (
  704. pPropBag,
  705. IDS_HTML_STOP_AFTER_VALUE,
  706. pSlqData->dwValue );
  707. }
  708. break;
  709. case SLQ_TT_TTYPE_SAMPLE:
  710. {
  711. LONGLONG llMillisecondSampleInt;
  712. FLOAT fSampleIntSeconds;
  713. ASSERT ( SLQ_TT_TTYPE_SAMPLE == pSlqData->wTimeType );
  714. ASSERT ( SLQ_TT_DTYPE_UNITS == pSlqData->wDataType );
  715. // ASSERT ( SLQ_AUTO_MODE_AFTER == pSlqData->dwAutoMode );
  716. // Write best approximation of sample time to Sysmon property.
  717. TimeInfoToMilliseconds ( pSlqData, &llMillisecondSampleInt );
  718. // Ensure that the millisecond sample interval fits in a DWORD.
  719. ASSERT ( llMillisecondSampleInt < ULONG_MAX );
  720. fSampleIntSeconds = (FLOAT)(llMillisecondSampleInt / 1000);
  721. hr = FloatToPropertyBag (
  722. pPropBag,
  723. IDS_HTML_SYSMON_UPDATEINTERVAL,
  724. fSampleIntSeconds );
  725. hr = DwordToPropertyBag ( pPropBag, IDS_HTML_SAMPLE_INT_UNIT_TYPE, pSlqData->dwUnitType );
  726. hr = DwordToPropertyBag ( pPropBag, IDS_HTML_SAMPLE_INT_VALUE, pSlqData->dwValue );
  727. break;
  728. }
  729. // Restart mode stored as a single DWORD
  730. case SLQ_TT_TTYPE_RESTART:
  731. default:
  732. hr = E_INVALIDARG;
  733. break;
  734. }
  735. return hr;
  736. }
  737. HRESULT
  738. CSmLogQuery::StringFromPropertyBag (
  739. IPropertyBag* pPropBag,
  740. IErrorLog* pIErrorLog,
  741. UINT uiPropName,
  742. const CString& rstrDefault,
  743. LPTSTR *pszBuffer,
  744. LPDWORD pdwLength )
  745. {
  746. HRESULT hr;
  747. CString strPropName;
  748. ResourceStateManager rsm;
  749. //
  750. // reads the string value from property bag and
  751. // frees any existing buffer referenced by szData,
  752. // then allocates a new buffer returning it with the
  753. // string value read from the property bag and the size of the
  754. // buffer (in bytes)
  755. //
  756. MFC_TRY
  757. strPropName.LoadString ( uiPropName );
  758. hr = StringFromPropertyBag (
  759. pPropBag,
  760. pIErrorLog,
  761. strPropName,
  762. rstrDefault,
  763. pszBuffer,
  764. pdwLength );
  765. MFC_CATCH_HR
  766. return hr;
  767. }
  768. HRESULT
  769. CSmLogQuery::StringFromPropertyBag (
  770. IPropertyBag* pPropBag,
  771. IErrorLog* pIErrorLog,
  772. const CString& rstrPropName,
  773. const CString& rstrDefault,
  774. LPTSTR *pszBuffer,
  775. LPDWORD pdwLength )
  776. {
  777. VARIANT vValue;
  778. HRESULT hr;
  779. DWORD dwNewBufSize = 0;
  780. LPTSTR szNewStringBuffer = NULL;
  781. LPTSTR szTrans = NULL;
  782. LPTSTR szScan = NULL;
  783. //
  784. // Reads the string value from property bag and
  785. // frees any existing buffer referenced by szData,
  786. // then allocates a new buffer returning it with the
  787. // string value read from the property bag and the size of the
  788. // buffer (in bytes)
  789. //
  790. ASSERT (pdwLength!= NULL);
  791. ASSERT (pszBuffer != NULL);
  792. *pdwLength = 0;
  793. VariantInit( &vValue );
  794. vValue.vt = VT_BSTR;
  795. vValue.bstrVal = NULL;
  796. MFC_TRY
  797. hr = pPropBag->Read(rstrPropName, &vValue, pIErrorLog );
  798. if ( SUCCEEDED(hr) && NULL != vValue.bstrVal ) {
  799. dwNewBufSize = SysStringLen(vValue.bstrVal) + sizeof(TCHAR);
  800. if ( dwNewBufSize > sizeof(TCHAR) ) {
  801. // then there's something to read
  802. szTrans = new TCHAR[dwNewBufSize];
  803. szNewStringBuffer = new TCHAR[dwNewBufSize];
  804. lstrcpy ( szNewStringBuffer, W2T( vValue.bstrVal) );
  805. for( int i=0;g_htmlentities[i].szHTML != NULL;i++ ){
  806. LPTSTR szScan = NULL;
  807. while( szScan = _tcsstr( szNewStringBuffer, g_htmlentities[i].szEntity ) ){
  808. *szScan = _T('\0');
  809. _tcscpy( szTrans, szNewStringBuffer );
  810. _tcscat( szTrans, g_htmlentities[i].szHTML );
  811. szScan += _tcslen( g_htmlentities[i].szEntity);
  812. _tcscat( szTrans, szScan );
  813. _tcscpy( szNewStringBuffer, szTrans );
  814. }
  815. }
  816. delete szTrans;
  817. szTrans = NULL;
  818. } else if ( 0 != rstrDefault.GetLength() ) {
  819. // Missing data in the property bag, so apply the default.
  820. dwNewBufSize = rstrDefault.GetLength() + sizeof(TCHAR);
  821. szNewStringBuffer = new TCHAR[dwNewBufSize];
  822. lstrcpy ( szNewStringBuffer, rstrDefault );
  823. hr = S_OK;
  824. } else {
  825. // Property not found, no default provided.
  826. hr = E_INVALIDARG;
  827. }
  828. } else if ( 0 != rstrDefault.GetLength() ) {
  829. // Missing data in the property bag, so apply the default.
  830. dwNewBufSize = rstrDefault.GetLength() + sizeof(TCHAR);
  831. szNewStringBuffer = new TCHAR[dwNewBufSize];
  832. lstrcpy ( szNewStringBuffer, rstrDefault );
  833. hr = S_OK;
  834. }
  835. MFC_CATCH_HR
  836. if ( SUCCEEDED(hr)) {
  837. // then delete the old buffer and replace it with
  838. // the new one
  839. if (*pszBuffer != NULL) {
  840. delete (*pszBuffer );
  841. }
  842. *pszBuffer = (LPTSTR)szNewStringBuffer;
  843. *pdwLength = dwNewBufSize;
  844. } else {
  845. // if error then delete the buffer
  846. if ( NULL != szNewStringBuffer ) {
  847. delete szNewStringBuffer;
  848. }
  849. }
  850. if ( NULL != szTrans ) {
  851. delete szTrans;
  852. }
  853. return hr;
  854. }
  855. HRESULT
  856. CSmLogQuery::DwordFromPropertyBag (
  857. IPropertyBag* pPropBag,
  858. IErrorLog* pIErrorLog,
  859. UINT uiPropName,
  860. DWORD dwDefault,
  861. DWORD& rdwData )
  862. {
  863. HRESULT hr;
  864. CString strPropName;
  865. ResourceStateManager rsm;
  866. MFC_TRY
  867. strPropName.LoadString ( uiPropName );
  868. hr = DwordFromPropertyBag (
  869. pPropBag,
  870. pIErrorLog,
  871. strPropName,
  872. dwDefault,
  873. rdwData );
  874. MFC_CATCH_HR
  875. return hr;
  876. }
  877. HRESULT
  878. CSmLogQuery::DwordFromPropertyBag (
  879. IPropertyBag* pPropBag,
  880. IErrorLog* pIErrorLog,
  881. const CString& rstrPropName,
  882. DWORD dwDefault,
  883. DWORD& rdwData )
  884. {
  885. VARIANT vValue;
  886. HRESULT hr;
  887. rdwData = dwDefault;
  888. VariantInit( &vValue );
  889. vValue.vt = VT_I4;
  890. vValue.lVal = 0;
  891. hr = pPropBag->Read(rstrPropName, &vValue, pIErrorLog );
  892. if ( E_INVALIDARG != hr ) {
  893. rdwData = (DWORD)vValue.lVal;
  894. } else {
  895. hr = S_OK;
  896. }
  897. return hr;
  898. }
  899. HRESULT
  900. CSmLogQuery::DoubleFromPropertyBag (
  901. IPropertyBag* pPropBag,
  902. IErrorLog* pIErrorLog,
  903. UINT uiPropName,
  904. DOUBLE dDefault,
  905. DOUBLE& rdData )
  906. {
  907. HRESULT hr;
  908. CString strPropName;
  909. ResourceStateManager rsm;
  910. MFC_TRY
  911. strPropName.LoadString ( uiPropName );
  912. hr = DoubleFromPropertyBag (
  913. pPropBag,
  914. pIErrorLog,
  915. strPropName,
  916. dDefault,
  917. rdData );
  918. MFC_CATCH_HR
  919. return hr;
  920. }
  921. HRESULT
  922. CSmLogQuery::DoubleFromPropertyBag (
  923. IPropertyBag* pPropBag,
  924. IErrorLog* pIErrorLog,
  925. const CString& rstrPropName,
  926. DOUBLE dDefault,
  927. DOUBLE& rdData )
  928. {
  929. VARIANT vValue;
  930. HRESULT hr;
  931. rdData = dDefault;
  932. VariantInit( &vValue );
  933. vValue.vt = VT_R8;
  934. vValue.dblVal = 0;
  935. hr = pPropBag->Read(rstrPropName, &vValue, pIErrorLog );
  936. if ( E_INVALIDARG != hr ) {
  937. rdData = vValue.dblVal;
  938. } else {
  939. hr = S_OK;
  940. }
  941. return hr;
  942. }
  943. HRESULT
  944. CSmLogQuery::FloatFromPropertyBag (
  945. IPropertyBag* pPropBag,
  946. IErrorLog* pIErrorLog,
  947. UINT uiPropName,
  948. FLOAT fDefault,
  949. FLOAT& rfData )
  950. {
  951. HRESULT hr;
  952. CString strPropName;
  953. ResourceStateManager rsm;
  954. strPropName.LoadString ( uiPropName );
  955. hr = FloatFromPropertyBag (
  956. pPropBag,
  957. pIErrorLog,
  958. strPropName,
  959. fDefault,
  960. rfData );
  961. return hr;
  962. }
  963. HRESULT
  964. CSmLogQuery::FloatFromPropertyBag (
  965. IPropertyBag* pPropBag,
  966. IErrorLog* pIErrorLog,
  967. const CString& rstrPropName,
  968. FLOAT fDefault,
  969. FLOAT& rfData )
  970. {
  971. VARIANT vValue;
  972. HRESULT hr;
  973. rfData = fDefault;
  974. VariantInit( &vValue );
  975. vValue.vt = VT_R4;
  976. vValue.fltVal = 0;
  977. hr = pPropBag->Read(rstrPropName, &vValue, pIErrorLog );
  978. if ( E_INVALIDARG != hr ) {
  979. rfData = vValue.fltVal;
  980. } else {
  981. hr = S_OK;
  982. }
  983. return hr;
  984. }
  985. HRESULT
  986. CSmLogQuery::LLTimeFromPropertyBag (
  987. IPropertyBag* pIPropBag,
  988. IErrorLog* pIErrorLog,
  989. UINT uiPropName,
  990. LONGLONG& rllDefault,
  991. LONGLONG& rllData )
  992. {
  993. HRESULT hr = NOERROR;
  994. CString strPropName;
  995. VARIANT vValue;
  996. ResourceStateManager rsm;
  997. strPropName.LoadString ( uiPropName );
  998. rllData = rllDefault;
  999. VariantInit( &vValue );
  1000. vValue.vt = VT_DATE;
  1001. hr = pIPropBag->Read(strPropName, &vValue, pIErrorLog );
  1002. // If parameter not missing, translate and return. Otherwise,
  1003. // return the default.
  1004. if ( E_INVALIDARG != hr ) {
  1005. if ( !VariantDateToLLTime ( vValue.date, &rllData ) ) {
  1006. hr = E_FAIL;
  1007. }
  1008. VariantClear( &vValue );
  1009. } else {
  1010. hr = S_OK;
  1011. }
  1012. return hr;
  1013. }
  1014. HRESULT
  1015. CSmLogQuery::SlqTimeFromPropertyBag (
  1016. IPropertyBag* pPropBag,
  1017. IErrorLog* pIErrorLog,
  1018. DWORD dwFlags,
  1019. PSLQ_TIME_INFO pSlqDefault,
  1020. PSLQ_TIME_INFO pSlqData )
  1021. {
  1022. HRESULT hr = NOERROR;
  1023. ASSERT ( NULL != pSlqData );
  1024. switch (dwFlags) {
  1025. case SLQ_TT_TTYPE_START:
  1026. pSlqData->wTimeType = SLQ_TT_TTYPE_START;
  1027. pSlqData->wDataType = SLQ_TT_DTYPE_DATETIME;
  1028. hr = DwordFromPropertyBag (
  1029. pPropBag,
  1030. pIErrorLog,
  1031. IDS_HTML_START_MODE,
  1032. pSlqDefault->dwAutoMode,
  1033. pSlqData->dwAutoMode );
  1034. if ( SLQ_AUTO_MODE_AT == pSlqData->dwAutoMode ) {
  1035. hr = LLTimeFromPropertyBag (
  1036. pPropBag,
  1037. pIErrorLog,
  1038. IDS_HTML_START_AT_TIME,
  1039. pSlqDefault->llDateTime,
  1040. pSlqData->llDateTime );
  1041. } else {
  1042. // Original state is stopped.
  1043. ASSERT ( SLQ_AUTO_MODE_NONE == pSlqData->dwAutoMode );
  1044. pSlqData->llDateTime = MAX_TIME_VALUE;
  1045. }
  1046. break;
  1047. case SLQ_TT_TTYPE_STOP:
  1048. pSlqData->wTimeType = SLQ_TT_TTYPE_STOP;
  1049. hr = DwordFromPropertyBag (
  1050. pPropBag,
  1051. pIErrorLog,
  1052. IDS_HTML_STOP_MODE,
  1053. pSlqDefault->dwAutoMode,
  1054. pSlqData->dwAutoMode );
  1055. if ( SLQ_AUTO_MODE_AT == pSlqData->dwAutoMode ) {
  1056. pSlqData->wDataType = SLQ_TT_DTYPE_DATETIME;
  1057. hr = LLTimeFromPropertyBag (
  1058. pPropBag,
  1059. pIErrorLog,
  1060. IDS_HTML_STOP_AT_TIME,
  1061. pSlqDefault->llDateTime,
  1062. pSlqData->llDateTime );
  1063. } else if ( SLQ_AUTO_MODE_AFTER == pSlqData->dwAutoMode ) {
  1064. pSlqData->wDataType = SLQ_TT_DTYPE_UNITS;
  1065. hr = DwordFromPropertyBag (
  1066. pPropBag,
  1067. pIErrorLog,
  1068. IDS_HTML_STOP_AFTER_UNIT_TYPE,
  1069. pSlqDefault->dwUnitType,
  1070. pSlqData->dwUnitType );
  1071. hr = DwordFromPropertyBag (
  1072. pPropBag,
  1073. pIErrorLog,
  1074. IDS_HTML_STOP_AFTER_VALUE,
  1075. pSlqDefault->dwValue,
  1076. pSlqData->dwValue );
  1077. } else {
  1078. // Original state is stopped.
  1079. ASSERT ( SLQ_AUTO_MODE_NONE == pSlqData->dwAutoMode );
  1080. pSlqData->wDataType = SLQ_TT_DTYPE_DATETIME;
  1081. pSlqData->llDateTime = MIN_TIME_VALUE;
  1082. }
  1083. break;
  1084. case SLQ_TT_TTYPE_SAMPLE:
  1085. {
  1086. DWORD dwNullDefault = (DWORD)(-1);
  1087. BOOL bUnitTypeMissing = FALSE;
  1088. BOOL bUnitValueMissing = FALSE;
  1089. hr = DwordFromPropertyBag (
  1090. pPropBag,
  1091. pIErrorLog,
  1092. IDS_HTML_SAMPLE_INT_UNIT_TYPE,
  1093. dwNullDefault,
  1094. pSlqData->dwUnitType );
  1095. if ( (DWORD)(-1) == pSlqData->dwUnitType ) {
  1096. pSlqData->dwUnitType = pSlqDefault->dwUnitType;
  1097. bUnitTypeMissing = TRUE;
  1098. }
  1099. hr = DwordFromPropertyBag (
  1100. pPropBag,
  1101. pIErrorLog,
  1102. IDS_HTML_SAMPLE_INT_VALUE,
  1103. dwNullDefault,
  1104. pSlqData->dwValue );
  1105. if ( (DWORD)(-1) == pSlqData->dwValue ) {
  1106. pSlqData->dwValue = pSlqDefault->dwValue;
  1107. bUnitValueMissing = TRUE;
  1108. }
  1109. if ( bUnitTypeMissing || bUnitValueMissing ) {
  1110. FLOAT fDefaultUpdateInterval;
  1111. FLOAT fUpdateInterval;
  1112. // If unit type or unit count missing from the property bag,
  1113. // look for "UpdateInterval" value, from the Sysmon control object,
  1114. // and use it to approximate the sample time.
  1115. fDefaultUpdateInterval = (FLOAT)(pSlqDefault->dwValue);
  1116. hr = FloatFromPropertyBag (
  1117. pPropBag,
  1118. pIErrorLog,
  1119. IDS_HTML_SYSMON_UPDATEINTERVAL,
  1120. fDefaultUpdateInterval,
  1121. fUpdateInterval );
  1122. if ( SUCCEEDED ( hr ) ) {
  1123. pSlqData->dwValue = (DWORD)(fUpdateInterval);
  1124. pSlqData->dwUnitType = SLQ_TT_UTYPE_SECONDS;
  1125. }
  1126. }
  1127. break;
  1128. }
  1129. // Restart mode stored as a single DWORD
  1130. case SLQ_TT_TTYPE_RESTART:
  1131. default:
  1132. hr = E_INVALIDARG;
  1133. break;
  1134. }
  1135. return hr;
  1136. }
  1137. //
  1138. // Open function. either opens an existing log query entry
  1139. // or creates a new one
  1140. //
  1141. DWORD
  1142. CSmLogQuery::Open ( const CString& rstrName, HKEY hKeyQuery, BOOL bReadOnly )
  1143. {
  1144. DWORD dwStatus = ERROR_SUCCESS;
  1145. //open the subkey for this log query
  1146. m_hKeyQuery = hKeyQuery;
  1147. m_bReadOnly = bReadOnly;
  1148. m_bIsModified = FALSE;
  1149. MFC_TRY
  1150. m_strName = rstrName;
  1151. dwStatus = SyncWithRegistry();
  1152. MFC_CATCH_DWSTATUS
  1153. return dwStatus;
  1154. }
  1155. //
  1156. // Close Function
  1157. // closes registry handles and frees allocated memory
  1158. //
  1159. DWORD
  1160. CSmLogQuery::Close ()
  1161. {
  1162. LOCALTRACE (L"Closing Query\n");
  1163. m_strName.Empty();
  1164. mr_strComment.Empty();
  1165. mr_strCommentIndirect.Empty();
  1166. mr_strBaseFileName.Empty();
  1167. mr_strBaseFileNameIndirect.Empty();
  1168. mr_strDefaultDirectory.Empty();
  1169. mr_strSqlName.Empty();
  1170. // close any open registry keys
  1171. if (m_hKeyQuery != NULL) {
  1172. RegCloseKey (m_hKeyQuery);
  1173. m_hKeyQuery = NULL;
  1174. }
  1175. return ERROR_SUCCESS;
  1176. }
  1177. //
  1178. // ManualStart function.
  1179. // Sets the start mode to manual and starts the query.
  1180. //
  1181. DWORD
  1182. CSmLogQuery::ManualStart ()
  1183. {
  1184. DWORD dwStatus = ERROR_SUCCESS;
  1185. SLQ_TIME_INFO slqTime;
  1186. BOOL bSetStopToMax;
  1187. BOOL bStarted = FALSE;
  1188. DWORD dwTimeout = 10;
  1189. BOOL bRegistryUpdated;
  1190. memset (&slqTime, 0, sizeof(slqTime));
  1191. slqTime.wTimeType = SLQ_TT_TTYPE_START;
  1192. slqTime.wDataType = SLQ_TT_DTYPE_DATETIME;
  1193. slqTime.dwAutoMode = SLQ_AUTO_MODE_NONE;
  1194. slqTime.llDateTime = MIN_TIME_VALUE;
  1195. SetLogTime ( &slqTime, SLQ_TT_TTYPE_START );
  1196. // If stop time mode set to manual, or StopAt with time before Now,
  1197. // set the mode to Manual, value to MAX_TIME_VALUE
  1198. bSetStopToMax = FALSE;
  1199. GetLogTime ( &slqTime, SLQ_TT_TTYPE_STOP );
  1200. if ( SLQ_AUTO_MODE_NONE == slqTime.dwAutoMode ) {
  1201. bSetStopToMax = TRUE;
  1202. } else if ( SLQ_AUTO_MODE_AT == slqTime.dwAutoMode ) {
  1203. SYSTEMTIME stLocalTime;
  1204. FILETIME ftLocalTime;
  1205. LONGLONG llLocalTime;
  1206. // get local time
  1207. // Milliseconds set to 0 for Schedule times
  1208. GetLocalTime (&stLocalTime);
  1209. stLocalTime.wMilliseconds = 0;
  1210. SystemTimeToFileTime (&stLocalTime, &ftLocalTime);
  1211. llLocalTime = *(LONGLONG*)&ftLocalTime;
  1212. if ( llLocalTime >= slqTime.llDateTime ) {
  1213. bSetStopToMax = TRUE;
  1214. }
  1215. }
  1216. if ( bSetStopToMax ) {
  1217. ASSERT( SLQ_TT_DTYPE_DATETIME == slqTime.wDataType );
  1218. slqTime.dwAutoMode = SLQ_AUTO_MODE_NONE;
  1219. slqTime.llDateTime = MAX_TIME_VALUE;
  1220. SetLogTime ( &slqTime, SLQ_TT_TTYPE_STOP );
  1221. }
  1222. // Service needs to distinguish between Running and Start Pending
  1223. // at service startup, so always set state to start pending.
  1224. SetState ( SLQ_QUERY_START_PENDING );
  1225. dwStatus = UpdateServiceSchedule( bRegistryUpdated );
  1226. if ( bRegistryUpdated ) {
  1227. while (--dwTimeout && !bStarted ) {
  1228. bStarted = IsRunning();
  1229. }
  1230. if ( !bStarted ) {
  1231. dwStatus = SMCFG_START_TIMED_OUT;
  1232. }
  1233. }
  1234. SyncPropPageSharedData(); // Sync the start time and stop auto mode
  1235. return dwStatus;
  1236. }
  1237. //
  1238. // ManualStop function.
  1239. //
  1240. // Clears the restart bit, sets the stop mode to manual and stops the query.
  1241. //
  1242. DWORD
  1243. CSmLogQuery::ManualStop ( )
  1244. {
  1245. DWORD dwStatus = ERROR_SUCCESS;
  1246. SLQ_TIME_INFO slqTime;
  1247. BOOL bRegistryUpdated;
  1248. if ( IsAutoRestart() ) {
  1249. mr_dwAutoRestartMode = SLQ_AUTO_MODE_NONE;
  1250. }
  1251. memset (&slqTime, 0, sizeof(slqTime));
  1252. slqTime.wTimeType = SLQ_TT_TTYPE_STOP;
  1253. slqTime.wDataType = SLQ_TT_DTYPE_DATETIME;
  1254. slqTime.dwAutoMode = SLQ_AUTO_MODE_NONE;
  1255. slqTime.llDateTime = MIN_TIME_VALUE;
  1256. SetLogTime ( &slqTime, SLQ_TT_TTYPE_STOP );
  1257. // If start time mode set to manual, set the value to MAX_TIME_VALUE
  1258. GetLogTime ( &slqTime, SLQ_TT_TTYPE_START );
  1259. if ( SLQ_AUTO_MODE_NONE == slqTime.dwAutoMode ) {
  1260. ASSERT( SLQ_TT_DTYPE_DATETIME == slqTime.wDataType );
  1261. slqTime.llDateTime = MAX_TIME_VALUE;
  1262. SetLogTime ( &slqTime, SLQ_TT_TTYPE_START );
  1263. }
  1264. dwStatus = UpdateServiceSchedule ( bRegistryUpdated );
  1265. if ( bRegistryUpdated ) {
  1266. DWORD dwTimeout = 25;
  1267. BOOL bStopped = FALSE;
  1268. while ( dwTimeout-- && !bStopped ) {
  1269. // IsRunning implements no delay if the current state is not
  1270. // SLQ_QUERY_START_PENDING, so add a delay for the registry
  1271. // change to be written.
  1272. bStopped = !IsRunning();
  1273. Sleep ( 200 );
  1274. }
  1275. if ( !bStopped ) {
  1276. dwStatus = SMCFG_STOP_TIMED_OUT;
  1277. }
  1278. }
  1279. SyncPropPageSharedData(); // Sync the start time and stop auto mode
  1280. return dwStatus;
  1281. }
  1282. //
  1283. // SaveAs function.
  1284. // Saves the query properties as a System Monitor ActiveX object
  1285. // in an HTML file.
  1286. //
  1287. DWORD
  1288. CSmLogQuery::SaveAs ( const CString& rstrPathName )
  1289. {
  1290. DWORD dwStatus = ERROR_SUCCESS;
  1291. CString strNonConstPathName = rstrPathName;
  1292. ResourceStateManager rsm;
  1293. // Create a file.
  1294. HANDLE hFile;
  1295. hFile = CreateFile (
  1296. strNonConstPathName,
  1297. GENERIC_READ | GENERIC_WRITE,
  1298. 0, // Not shared
  1299. NULL, // Security attributes
  1300. CREATE_ALWAYS, // The user has already decided to override any existing file.
  1301. FILE_ATTRIBUTE_NORMAL,
  1302. NULL );
  1303. if ( INVALID_HANDLE_VALUE != hFile ) {
  1304. // Save the current configuration to the file.
  1305. CString strTemp;
  1306. DWORD dwTempLength;
  1307. BOOL bStatus;
  1308. WCHAR szByteOrderMark[2];
  1309. szByteOrderMark[0] = 0xFEFF;
  1310. szByteOrderMark[1] = 0;
  1311. bStatus = FileWrite ( hFile, szByteOrderMark, sizeof(WCHAR) );
  1312. if ( bStatus ) {
  1313. strTemp.LoadString( IDS_HTML_FILE_HEADER1 );
  1314. dwTempLength = strTemp.GetLength() * sizeof(TCHAR);
  1315. bStatus = FileWrite ( hFile, (void *)(LPCTSTR)strTemp, dwTempLength );
  1316. }
  1317. if ( bStatus ) {
  1318. strTemp.LoadString( IDS_HTML_FILE_HEADER2 );
  1319. dwTempLength = strTemp.GetLength() * sizeof(TCHAR);
  1320. bStatus = FileWrite ( hFile, (void *)(LPCTSTR)strTemp, dwTempLength );
  1321. }
  1322. if ( bStatus ) {
  1323. DWORD dwByteCount;
  1324. LPTSTR pszData = NULL;
  1325. HRESULT hr = CopyToBuffer ( pszData, dwByteCount );
  1326. if ( SUCCEEDED ( hr ) ) {
  1327. ASSERT ( NULL != pszData );
  1328. ASSERT ( 0 != dwByteCount );
  1329. bStatus = FileWrite ( hFile, pszData, dwByteCount );
  1330. delete pszData;
  1331. } else {
  1332. bStatus = FALSE;
  1333. }
  1334. }
  1335. if ( bStatus ) {
  1336. strTemp.LoadString( IDS_HTML_FILE_FOOTER );
  1337. dwTempLength = strTemp.GetLength() * sizeof(TCHAR);
  1338. bStatus = FileWrite ( hFile, (void *)(LPCTSTR)strTemp, dwTempLength );
  1339. }
  1340. bStatus = CloseHandle ( hFile );
  1341. }
  1342. return dwStatus;
  1343. }
  1344. DWORD
  1345. CSmLogQuery::UpdateService( BOOL& rbRegistryUpdated ) {
  1346. DWORD dwStatus;
  1347. rbRegistryUpdated = FALSE;
  1348. dwStatus = UpdateRegistry();
  1349. if ( ERROR_SUCCESS == dwStatus ) {
  1350. rbRegistryUpdated = TRUE;
  1351. dwStatus = m_pLogService->Synchronize();
  1352. }
  1353. if ( ERROR_SUCCESS == dwStatus ) {
  1354. m_bIsModified = TRUE;
  1355. }
  1356. return dwStatus;
  1357. }
  1358. //
  1359. // UpdateServiceSchedule function.
  1360. // copies the current schedule settings to the registry
  1361. // and synchs the log service
  1362. //
  1363. DWORD
  1364. CSmLogQuery::UpdateServiceSchedule( BOOL& rbRegistryUpdated ) {
  1365. LONG dwStatus = ERROR_SUCCESS;
  1366. rbRegistryUpdated = FALSE;
  1367. if (!m_bReadOnly) {
  1368. dwStatus = UpdateRegistryScheduleValues();
  1369. if ( ERROR_SUCCESS == dwStatus ) {
  1370. dwStatus = UpdateRegistryLastModified();
  1371. }
  1372. if ( ERROR_SUCCESS == dwStatus ) {
  1373. rbRegistryUpdated = TRUE;
  1374. dwStatus = m_pLogService->Synchronize();
  1375. }
  1376. if ( ERROR_SUCCESS == dwStatus ) {
  1377. m_bIsModified = TRUE;
  1378. }
  1379. } else {
  1380. dwStatus = ERROR_ACCESS_DENIED;
  1381. }
  1382. return dwStatus;
  1383. }
  1384. //
  1385. // UpdateRegistryLastModified function.
  1386. // Copies the current "last modified date" to the registry where
  1387. // it is read by the log service
  1388. //
  1389. DWORD
  1390. CSmLogQuery::UpdateRegistryLastModified()
  1391. {
  1392. LONG dwStatus = ERROR_SUCCESS;
  1393. if (!m_bReadOnly) {
  1394. SLQ_TIME_INFO plqLastModified;
  1395. FILETIME ftModified;
  1396. SYSTEMTIME stLocalTime;
  1397. RegFlushKey( m_hKeyQuery );
  1398. dwStatus = RegQueryInfoKey (
  1399. m_hKeyQuery,
  1400. NULL, // Class buffer
  1401. NULL, // Size of class buffer
  1402. NULL, // Reserved
  1403. NULL, // Subkey count
  1404. NULL, // Length of longest subkey name
  1405. NULL, // Longest subkey class
  1406. NULL, // Value count
  1407. NULL, // Length of longest value name
  1408. NULL, // Length of longest value
  1409. NULL, // Security descriptor
  1410. &ftModified );
  1411. if (ERROR_SUCCESS != dwStatus ) {
  1412. // Get local time for last modified value, if the
  1413. // registry doesn't return the last written time.
  1414. GetLocalTime (&stLocalTime);
  1415. SystemTimeToFileTime (&stLocalTime, &ftModified);
  1416. }
  1417. plqLastModified.wDataType = SLQ_TT_DTYPE_DATETIME;
  1418. plqLastModified.wTimeType = SLQ_TT_TTYPE_LAST_MODIFIED;
  1419. plqLastModified.dwAutoMode = SLQ_AUTO_MODE_NONE; // not used.
  1420. plqLastModified.llDateTime = *(LONGLONG *)&ftModified;
  1421. dwStatus = WriteRegistrySlqTime (
  1422. m_hKeyQuery,
  1423. IDS_REG_LAST_MODIFIED,
  1424. &plqLastModified);
  1425. } else {
  1426. dwStatus = ERROR_ACCESS_DENIED;
  1427. }
  1428. return dwStatus;
  1429. }
  1430. //
  1431. // UpdateRegistryScheduleValues function.
  1432. // copies the current schedule settings to the registry where they
  1433. // are read by the log service
  1434. //
  1435. DWORD
  1436. CSmLogQuery::UpdateRegistryScheduleValues()
  1437. {
  1438. LONG dwStatus = ERROR_SUCCESS;
  1439. if (!m_bReadOnly) {
  1440. // Stop and start times
  1441. if ( ERROR_SUCCESS == dwStatus ) {
  1442. ASSERT (mr_stiStart.wTimeType == SLQ_TT_TTYPE_START);
  1443. dwStatus = WriteRegistrySlqTime (
  1444. m_hKeyQuery,
  1445. IDS_REG_START_TIME,
  1446. &mr_stiStart);
  1447. }
  1448. if ( ERROR_SUCCESS == dwStatus ) {
  1449. ASSERT (mr_stiStop.wTimeType == SLQ_TT_TTYPE_STOP);
  1450. dwStatus = WriteRegistrySlqTime (
  1451. m_hKeyQuery,
  1452. IDS_REG_STOP_TIME,
  1453. &mr_stiStop);
  1454. }
  1455. // Auto restart value is "immediately on log file close" only.
  1456. // Use binary for future enhancements.
  1457. if ( ERROR_SUCCESS == dwStatus ) {
  1458. dwStatus = WriteRegistryDwordValue (
  1459. m_hKeyQuery,
  1460. IDS_REG_RESTART,
  1461. &mr_dwAutoRestartMode,
  1462. REG_BINARY);
  1463. }
  1464. // Only write the state when requesting the service to
  1465. // start a query.
  1466. if ( SLQ_QUERY_START_PENDING == mr_dwCurrentState ) {
  1467. dwStatus = WriteRegistryDwordValue (
  1468. m_hKeyQuery,
  1469. IDS_REG_CURRENT_STATE,
  1470. &mr_dwCurrentState);
  1471. }
  1472. } else {
  1473. dwStatus = ERROR_ACCESS_DENIED;
  1474. }
  1475. return dwStatus;
  1476. }
  1477. //
  1478. // UpdateRegistry function.
  1479. // copies the current settings to the registry where they
  1480. // are read by the log service
  1481. //
  1482. DWORD
  1483. CSmLogQuery::UpdateRegistry()
  1484. {
  1485. LONG dwStatus = ERROR_SUCCESS;
  1486. DWORD dwBufferSize = 0;
  1487. DWORD dwLogType;
  1488. DWORD dwLogFileType = 0;
  1489. DWORD dwTempFileSizeUnits;
  1490. DWORD dwTempDataStoreAttributes = 0;
  1491. DWORD dwTempMaxFileSize;
  1492. DWORD dwTempAppendMode;
  1493. if ( IsModifiable() ) {
  1494. if ( !mr_strComment.IsEmpty() ) {
  1495. dwBufferSize = mr_strComment.GetLength() + 1;
  1496. dwBufferSize *= sizeof(TCHAR);
  1497. } else {
  1498. dwBufferSize = 0;
  1499. }
  1500. dwStatus = WriteRegistryStringValue (
  1501. m_hKeyQuery,
  1502. IDS_REG_COMMENT,
  1503. REG_SZ,
  1504. (LPCTSTR)mr_strComment,
  1505. &dwBufferSize);
  1506. if ( ERROR_SUCCESS == dwStatus && !mr_strCommentIndirect.IsEmpty() ) {
  1507. dwBufferSize = mr_strCommentIndirect.GetLength() + 1;
  1508. dwBufferSize *= sizeof(TCHAR);
  1509. dwStatus = WriteRegistryStringValue (
  1510. m_hKeyQuery,
  1511. IDS_REG_COMMENT_INDIRECT,
  1512. REG_SZ,
  1513. (LPCTSTR)mr_strCommentIndirect,
  1514. &dwBufferSize);
  1515. }
  1516. if ( ERROR_SUCCESS == dwStatus ) {
  1517. dwLogType = GetLogType();
  1518. dwStatus = WriteRegistryDwordValue (
  1519. m_hKeyQuery,
  1520. IDS_REG_LOG_TYPE,
  1521. &dwLogType);
  1522. }
  1523. if ( ERROR_SUCCESS == dwStatus ) {
  1524. dwStatus = WriteRegistryDwordValue (
  1525. m_hKeyQuery,
  1526. IDS_REG_REALTIME_DATASOURCE,
  1527. & mr_dwRealTimeQuery);
  1528. }
  1529. // Files
  1530. if ( ERROR_SUCCESS == dwStatus ) {
  1531. // Within the app, counter data store size units are in MB.
  1532. // Translate to back to KB when write to registry
  1533. dwTempFileSizeUnits = GetDataStoreSizeUnits();
  1534. dwTempMaxFileSize = mr_dwMaxSize;
  1535. GetLogFileType ( dwLogFileType );
  1536. if ( SLQ_COUNTER_LOG == GetLogType()
  1537. && SLF_SQL_LOG != dwLogFileType )
  1538. {
  1539. if ( ONE_MB == dwTempFileSizeUnits ) {
  1540. dwTempFileSizeUnits = ONE_KB;
  1541. // Round up to next MB
  1542. if ( SLQ_DISK_MAX_SIZE != mr_dwMaxSize ) {
  1543. dwTempMaxFileSize *= dwTempFileSizeUnits;
  1544. }
  1545. }
  1546. }
  1547. dwStatus = WriteRegistryDwordValue (
  1548. m_hKeyQuery,
  1549. IDS_REG_LOG_FILE_MAX_SIZE,
  1550. &dwTempMaxFileSize);
  1551. }
  1552. if ( ERROR_SUCCESS == dwStatus ) {
  1553. // Data store size units
  1554. if ( ONE_MB == dwTempFileSizeUnits ) {
  1555. dwTempDataStoreAttributes = SLF_DATA_STORE_SIZE_ONE_MB;
  1556. } else if ( ONE_KB == dwTempFileSizeUnits ) {
  1557. dwTempDataStoreAttributes = SLF_DATA_STORE_SIZE_ONE_KB;
  1558. } else if ( ONE_RECORD == dwTempFileSizeUnits ) {
  1559. dwTempDataStoreAttributes = SLF_DATA_STORE_SIZE_ONE_RECORD;
  1560. }
  1561. // Data store append mode
  1562. GetDataStoreAppendMode( dwTempAppendMode );
  1563. dwTempDataStoreAttributes |= dwTempAppendMode;
  1564. dwStatus = WriteRegistryDwordValue (
  1565. m_hKeyQuery,
  1566. IDS_REG_DATA_STORE_ATTRIBUTES,
  1567. &dwTempDataStoreAttributes);
  1568. }
  1569. if ( !mr_strBaseFileName.IsEmpty() ) {
  1570. dwBufferSize = mr_strBaseFileName.GetLength() + 1;
  1571. dwBufferSize *= sizeof(TCHAR);
  1572. } else {
  1573. dwBufferSize = 0;
  1574. }
  1575. if ( ERROR_SUCCESS == dwStatus ) {
  1576. dwStatus = WriteRegistryStringValue (
  1577. m_hKeyQuery,
  1578. IDS_REG_LOG_FILE_BASE_NAME,
  1579. REG_SZ,
  1580. (LPCTSTR)mr_strBaseFileName,
  1581. &dwBufferSize);
  1582. }
  1583. if ( ERROR_SUCCESS == dwStatus && !mr_strBaseFileNameIndirect.IsEmpty() ) {
  1584. dwBufferSize = mr_strBaseFileNameIndirect.GetLength() + 1;
  1585. dwBufferSize *= sizeof(TCHAR);
  1586. dwStatus = WriteRegistryStringValue (
  1587. m_hKeyQuery,
  1588. IDS_REG_LOG_FILE_BASE_NAME_IND,
  1589. REG_SZ,
  1590. (LPCTSTR)mr_strBaseFileNameIndirect,
  1591. &dwBufferSize);
  1592. }
  1593. if ( !mr_strSqlName.IsEmpty() ) {
  1594. dwBufferSize = mr_strSqlName.GetLength() + 1;
  1595. dwBufferSize *= sizeof(TCHAR);
  1596. } else {
  1597. dwBufferSize = 0;
  1598. }
  1599. if ( ERROR_SUCCESS == dwStatus ) {
  1600. dwStatus = WriteRegistryStringValue (
  1601. m_hKeyQuery,
  1602. IDS_REG_SQL_LOG_BASE_NAME,
  1603. REG_SZ,
  1604. (LPCTSTR)mr_strSqlName,
  1605. &dwBufferSize);
  1606. }
  1607. if ( ERROR_SUCCESS == dwStatus ) {
  1608. dwStatus = WriteRegistryDwordValue (
  1609. m_hKeyQuery,
  1610. IDS_REG_LOG_FILE_SERIAL_NUMBER,
  1611. &mr_dwCurrentSerialNumber );
  1612. }
  1613. if ( !mr_strDefaultDirectory.IsEmpty() ) {
  1614. dwBufferSize = mr_strDefaultDirectory.GetLength() + 1;
  1615. dwBufferSize *= sizeof(TCHAR);
  1616. } else {
  1617. dwBufferSize = 0;
  1618. }
  1619. if ( ERROR_SUCCESS == dwStatus ) {
  1620. dwStatus = WriteRegistryStringValue (
  1621. m_hKeyQuery,
  1622. IDS_REG_LOG_FILE_FOLDER,
  1623. REG_SZ,
  1624. (LPCTSTR)mr_strDefaultDirectory,
  1625. &dwBufferSize);
  1626. }
  1627. if ( ERROR_SUCCESS == dwStatus ) {
  1628. dwStatus = WriteRegistryDwordValue (
  1629. m_hKeyQuery,
  1630. IDS_REG_LOG_FILE_AUTO_FORMAT,
  1631. &mr_dwLogAutoFormat);
  1632. }
  1633. if ( ERROR_SUCCESS == dwStatus ) {
  1634. dwStatus = WriteRegistryDwordValue (
  1635. m_hKeyQuery,
  1636. IDS_REG_LOG_FILE_TYPE,
  1637. &mr_dwLogFileType);
  1638. }
  1639. // Schedule
  1640. // Eof command is used for counter and trace logs only.
  1641. if ( ERROR_SUCCESS == dwStatus ) {
  1642. if ( SLQ_COUNTER_LOG == GetLogType()
  1643. || SLQ_TRACE_LOG == GetLogType() ) {
  1644. dwBufferSize = mr_strEofCmdFile.GetLength() + 1;
  1645. dwBufferSize *= sizeof(TCHAR);
  1646. dwStatus = WriteRegistryStringValue (
  1647. m_hKeyQuery,
  1648. IDS_REG_EOF_COMMAND_FILE,
  1649. REG_SZ,
  1650. (LPCWSTR)mr_strEofCmdFile,
  1651. &dwBufferSize);
  1652. }
  1653. }
  1654. if ( ERROR_SUCCESS == dwStatus ) {
  1655. dwStatus = UpdateRegistryScheduleValues();
  1656. }
  1657. // This must be the last registry value updated.
  1658. if ( ERROR_SUCCESS == dwStatus ) {
  1659. dwStatus = UpdateRegistryLastModified();
  1660. }
  1661. } else {
  1662. dwStatus = ERROR_ACCESS_DENIED;
  1663. }
  1664. return dwStatus;
  1665. }
  1666. //
  1667. // SyncSerialNumberWithRegistry()
  1668. // reads the current value for the serial number
  1669. // from the registry and reloads the internal value
  1670. // to match
  1671. //
  1672. DWORD
  1673. CSmLogQuery::SyncSerialNumberWithRegistry()
  1674. {
  1675. DWORD dwStatus = ERROR_SUCCESS;
  1676. ASSERT (m_hKeyQuery != NULL);
  1677. // Get starting serial number for serial suffix.
  1678. dwStatus = ReadRegistryDwordValue (
  1679. m_hKeyQuery,
  1680. IDS_REG_LOG_FILE_SERIAL_NUMBER,
  1681. DEFAULT_LOG_FILE_SERIAL_NUMBER,
  1682. &mr_dwCurrentSerialNumber );
  1683. ASSERT (dwStatus == ERROR_SUCCESS);
  1684. return dwStatus;
  1685. }
  1686. //
  1687. // SyncWithRegistry()
  1688. // reads the current values for this query from the registry
  1689. // and reloads the internal values to match
  1690. //
  1691. DWORD
  1692. CSmLogQuery::SyncWithRegistry()
  1693. {
  1694. DWORD dwBufferSize = 0;
  1695. DWORD dwStatus = ERROR_SUCCESS;
  1696. SLQ_TIME_INFO stiDefault;
  1697. WCHAR szDefault[MAX_PATH + 1];
  1698. LPTSTR szTemp = NULL;
  1699. DWORD dwDefault;
  1700. DWORD dwTemp;
  1701. LPWSTR szIndTemp = NULL;
  1702. UINT uiBufferLen = 0;
  1703. CString strValueName;
  1704. LPTSTR szEofCmd = NULL;
  1705. ResourceStateManager rsm;
  1706. ASSERT (m_hKeyQuery != NULL);
  1707. MFC_TRY
  1708. // Modify bit
  1709. dwTemp = DEFAULT_EXECUTE_ONLY;
  1710. dwStatus = ReadRegistryDwordValue (
  1711. m_hKeyQuery,
  1712. IDS_REG_EXECUTE_ONLY,
  1713. DEFAULT_EXECUTE_ONLY,
  1714. &dwTemp);
  1715. ASSERT ( ERROR_SUCCESS == dwStatus );
  1716. if ( 0 == dwTemp ) {
  1717. m_bExecuteOnly = FALSE;
  1718. } else {
  1719. m_bExecuteOnly = TRUE;
  1720. }
  1721. // File attributes
  1722. // Comment field can be indirect
  1723. strValueName.LoadString ( IDS_REG_COMMENT );
  1724. dwStatus = SmReadRegistryIndirectStringValue (
  1725. m_hKeyQuery,
  1726. strValueName,
  1727. DEFAULT_COMMENT,
  1728. &szIndTemp,
  1729. &uiBufferLen );
  1730. mr_strComment.Empty();
  1731. if ( NULL != szIndTemp ) {
  1732. if ( _T('\0') != *szIndTemp ) {
  1733. mr_strComment = szIndTemp;
  1734. }
  1735. }
  1736. if ( NULL != szIndTemp ) {
  1737. G_FREE ( szIndTemp );
  1738. szIndTemp = NULL;
  1739. }
  1740. uiBufferLen = 0;
  1741. dwStatus = ReadRegistryDwordValue (
  1742. m_hKeyQuery,
  1743. IDS_REG_LOG_FILE_MAX_SIZE,
  1744. DEFAULT_LOG_FILE_MAX_SIZE,
  1745. &mr_dwMaxSize );
  1746. ASSERT ( ERROR_SUCCESS == dwStatus );
  1747. if ( SLQ_TRACE_LOG == GetLogType() ) {
  1748. dwStatus = ReadRegistryDwordValue (
  1749. m_hKeyQuery,
  1750. IDS_REG_LOG_FILE_TYPE,
  1751. DEFAULT_TRACE_LOG_FILE_TYPE,
  1752. &mr_dwLogFileType);
  1753. ASSERT ( ERROR_SUCCESS == dwStatus );
  1754. } else {
  1755. dwStatus = ReadRegistryDwordValue (
  1756. m_hKeyQuery,
  1757. IDS_REG_LOG_FILE_TYPE,
  1758. DEFAULT_CTR_LOG_FILE_TYPE,
  1759. &mr_dwLogFileType);
  1760. ASSERT ( ERROR_SUCCESS == dwStatus );
  1761. }
  1762. // Data store attributes must be read after log file type and log file max size.
  1763. dwDefault = 0; // Eliminate PREFIX warning
  1764. InitDataStoreAttributesDefault ( mr_dwLogFileType, dwDefault );
  1765. dwStatus = ReadRegistryDwordValue (
  1766. m_hKeyQuery,
  1767. IDS_REG_DATA_STORE_ATTRIBUTES,
  1768. dwDefault,
  1769. &dwTemp );
  1770. ProcessLoadedDataStoreAttributes ( dwTemp );
  1771. //
  1772. // Default to query name.
  1773. // Log file base name field can be indirect.
  1774. //
  1775. lstrcpynW ( szDefault, m_strName , min ( MAX_PATH + 1, m_strName.GetLength() + 1 ) );
  1776. szDefault[MAX_PATH] = L'\0';
  1777. strValueName.LoadString ( IDS_REG_LOG_FILE_BASE_NAME );
  1778. dwStatus = SmReadRegistryIndirectStringValue (
  1779. m_hKeyQuery,
  1780. strValueName,
  1781. szDefault,
  1782. &szIndTemp,
  1783. &uiBufferLen );
  1784. ASSERT ( ERROR_SUCCESS == dwStatus );
  1785. mr_strBaseFileName.Empty();
  1786. if ( NULL != szIndTemp ) {
  1787. if ( _T('\0') != *szIndTemp ) {
  1788. ReplaceBlanksWithUnderscores ( szIndTemp );
  1789. mr_strBaseFileName = szIndTemp;
  1790. }
  1791. }
  1792. if ( NULL != szIndTemp ) {
  1793. G_FREE ( szIndTemp );
  1794. szIndTemp = NULL;
  1795. }
  1796. uiBufferLen = 0;
  1797. dwStatus = ReadRegistryStringValue (
  1798. m_hKeyQuery,
  1799. IDS_REG_LOG_FILE_FOLDER,
  1800. m_pLogService->GetDefaultLogFileFolder(),
  1801. &szTemp,
  1802. &dwBufferSize);
  1803. ASSERT ( ERROR_SUCCESS == dwStatus );
  1804. mr_strDefaultDirectory.Empty();
  1805. if ( dwBufferSize > sizeof(TCHAR) ) {
  1806. ASSERT ( NULL != szTemp );
  1807. ASSERT ( 0 != *szTemp );
  1808. mr_strDefaultDirectory = szTemp;
  1809. }
  1810. delete ( szTemp );
  1811. szTemp = NULL;
  1812. dwBufferSize = 0;
  1813. // Default log set name to log name
  1814. if ( MAX_PATH + 1 > m_strName.GetLength() + 5 ) {
  1815. swprintf ( szDefault, L"SQL:!%s", m_strName );
  1816. } else {
  1817. lstrcpyW ( szDefault, L"SQL:!" );
  1818. }
  1819. dwStatus = ReadRegistryStringValue (
  1820. m_hKeyQuery,
  1821. IDS_REG_SQL_LOG_BASE_NAME,
  1822. szDefault,
  1823. &szTemp,
  1824. &dwBufferSize);
  1825. ASSERT ( ERROR_SUCCESS == dwStatus );
  1826. mr_strSqlName.Empty();
  1827. if ( dwBufferSize > sizeof(TCHAR) ) {
  1828. ASSERT ( NULL != szTemp );
  1829. ASSERT ( 0 != *szTemp );
  1830. mr_strSqlName = szTemp;
  1831. }
  1832. delete ( szTemp );
  1833. szTemp = NULL;
  1834. dwBufferSize = 0;
  1835. dwStatus = ReadRegistryDwordValue(
  1836. m_hKeyQuery,
  1837. IDS_REG_REALTIME_DATASOURCE,
  1838. g_dwRealTimeQuery,
  1839. & mr_dwRealTimeQuery);
  1840. ASSERT ( ERROR_SUCCESS == dwStatus );
  1841. dwStatus = ReadRegistryDwordValue (
  1842. m_hKeyQuery,
  1843. IDS_REG_LOG_FILE_AUTO_FORMAT,
  1844. DEFAULT_LOG_FILE_AUTO_FORMAT,
  1845. &mr_dwLogAutoFormat);
  1846. ASSERT ( ERROR_SUCCESS == dwStatus );
  1847. // Get starting serial number for serial suffix.
  1848. dwStatus = SyncSerialNumberWithRegistry ();
  1849. ASSERT ( ERROR_SUCCESS == dwStatus );
  1850. dwStatus = ReadRegistryDwordValue (
  1851. m_hKeyQuery,
  1852. IDS_REG_CURRENT_STATE,
  1853. DEFAULT_CURRENT_STATE,
  1854. &mr_dwCurrentState);
  1855. ASSERT ( ERROR_SUCCESS == dwStatus );
  1856. // Start, stop and restart values
  1857. VERIFY ( GetDefaultLogTime (stiDefault, SLQ_TT_TTYPE_START ) );
  1858. dwStatus = ReadRegistrySlqTime (
  1859. m_hKeyQuery, IDS_REG_START_TIME,
  1860. &stiDefault, &mr_stiStart);
  1861. ASSERT ( ERROR_SUCCESS == dwStatus );
  1862. ASSERT (mr_stiStart.wTimeType == SLQ_TT_TTYPE_START);
  1863. VERIFY ( GetDefaultLogTime (stiDefault, SLQ_TT_TTYPE_STOP ) );
  1864. dwStatus = ReadRegistrySlqTime (
  1865. m_hKeyQuery, IDS_REG_STOP_TIME,
  1866. &stiDefault, &mr_stiStop);
  1867. ASSERT ( ERROR_SUCCESS == dwStatus );
  1868. ASSERT (mr_stiStop.wTimeType == SLQ_TT_TTYPE_STOP);
  1869. dwStatus = ReadRegistryDwordValue (
  1870. m_hKeyQuery,
  1871. IDS_REG_RESTART,
  1872. DEFAULT_RESTART_VALUE,
  1873. &mr_dwAutoRestartMode);
  1874. ASSERT ( ERROR_SUCCESS == dwStatus );
  1875. // Eof command is used by Counter and Trace logs only.
  1876. if ( SLQ_COUNTER_LOG == GetLogType()
  1877. || SLQ_TRACE_LOG == GetLogType() ) {
  1878. dwStatus = ReadRegistryStringValue (
  1879. m_hKeyQuery,
  1880. IDS_REG_EOF_COMMAND_FILE,
  1881. DEFAULT_EOF_COMMAND_FILE,
  1882. &szEofCmd,
  1883. &dwBufferSize);
  1884. ASSERT ( ERROR_SUCCESS == dwStatus );
  1885. if (dwBufferSize > sizeof(TCHAR)) {
  1886. mr_strEofCmdFile = szEofCmd;
  1887. } else {
  1888. mr_strEofCmdFile.Empty();
  1889. }
  1890. }
  1891. MFC_CATCH_DWSTATUS;
  1892. if ( NULL != szTemp ) {
  1893. delete szTemp;
  1894. }
  1895. if ( NULL != szIndTemp ) {
  1896. G_FREE ( szIndTemp );
  1897. }
  1898. if ( NULL != szEofCmd ) {
  1899. delete szEofCmd;
  1900. }
  1901. SyncPropPageSharedData();
  1902. return dwStatus;
  1903. }
  1904. CSmLogService*
  1905. CSmLogQuery::GetLogService ( void )
  1906. {
  1907. return m_pLogService;
  1908. }
  1909. DWORD
  1910. CSmLogQuery::GetMachineDisplayName ( CString& rstrMachineName )
  1911. {
  1912. DWORD dwStatus = ERROR_SUCCESS;
  1913. // rstrMachineName is writable. CString copy-on-write
  1914. // semantics will support a writable string created from read-only.
  1915. // A new string data buffer is allocated the first time that
  1916. // it is modified.
  1917. MFC_TRY
  1918. rstrMachineName = m_pLogService->GetMachineDisplayName();
  1919. MFC_CATCH_DWSTATUS
  1920. return dwStatus;
  1921. }
  1922. //
  1923. // Get log file type and return as a string
  1924. //
  1925. //
  1926. const CString&
  1927. CSmLogQuery::GetLogFileType( void )
  1928. {
  1929. int nStringIdx;
  1930. ResourceStateManager rsm;
  1931. m_strLogFileType.Empty();
  1932. switch (LOWORD(mr_dwLogFileType)) {
  1933. case SLF_CSV_FILE:
  1934. nStringIdx = IDS_FT_CSV;
  1935. break;
  1936. case SLF_TSV_FILE:
  1937. nStringIdx = IDS_FT_TSV;
  1938. break;
  1939. case SLF_BIN_FILE:
  1940. nStringIdx = IDS_FT_BINARY;
  1941. break;
  1942. case SLF_BIN_CIRC_FILE:
  1943. nStringIdx = IDS_FT_BINARY_CIRCULAR;
  1944. break;
  1945. case SLF_SEQ_TRACE_FILE:
  1946. nStringIdx = IDS_FT_SEQUENTIAL_TRACE;
  1947. break;
  1948. case SLF_CIRC_TRACE_FILE:
  1949. nStringIdx = IDS_FT_CIRCULAR_TRACE;
  1950. break;
  1951. case SLF_SQL_LOG:
  1952. nStringIdx = IDS_FT_SQL;
  1953. break;
  1954. default:
  1955. nStringIdx = IDS_FT_UNKNOWN;
  1956. break;
  1957. }
  1958. MFC_TRY
  1959. m_strLogFileType.LoadString ( nStringIdx );
  1960. MFC_CATCH_MINIMUM
  1961. return m_strLogFileType;
  1962. }
  1963. void
  1964. CSmLogQuery::GetLogFileType ( DWORD& rdwFileType )
  1965. {
  1966. rdwFileType = LOWORD(mr_dwLogFileType);
  1967. return;
  1968. }
  1969. void
  1970. CSmLogQuery::GetDataStoreAppendMode(DWORD &rdwAppend)
  1971. {
  1972. rdwAppend = mr_dwAppendMode;
  1973. return;
  1974. }
  1975. void
  1976. CSmLogQuery::SetDataStoreAppendMode(DWORD dwAppend)
  1977. {
  1978. mr_dwAppendMode = dwAppend;
  1979. return;
  1980. }
  1981. //
  1982. // Get log file name currently in use
  1983. //
  1984. //
  1985. const CString&
  1986. CSmLogQuery::GetLogFileName ( BOOL bLatestRunning )
  1987. {
  1988. HRESULT hr = NOERROR;
  1989. PPDH_PLA_INFO pInfo = NULL;
  1990. DWORD dwStrBufLen = 0;
  1991. DWORD dwFlags = 0;
  1992. CString strMachineName;
  1993. m_strFileName.Empty();
  1994. MFC_TRY
  1995. strMachineName = m_pLogService->GetMachineName();
  1996. MFC_CATCH_HR;
  1997. // Todo: dwStatus or hr?
  1998. if ( SUCCEEDED ( hr ) ) {
  1999. if ( bLatestRunning ) {
  2000. dwFlags = PLA_FILENAME_CURRENTLOG; // Latest running log
  2001. }
  2002. hr = PdhPlaGetLogFileName (
  2003. (LPTSTR)(LPCTSTR)GetLogName(),
  2004. (LPTSTR)(LPCTSTR)strMachineName,
  2005. NULL,
  2006. dwFlags,
  2007. &dwStrBufLen,
  2008. NULL );
  2009. if ( SUCCEEDED ( hr ) || PDH_INSUFFICIENT_BUFFER == hr ) {
  2010. if ( bLatestRunning ) {
  2011. dwFlags = PLA_FILENAME_CURRENTLOG; // Latest running log
  2012. }
  2013. hr = PdhPlaGetLogFileName (
  2014. (LPTSTR)(LPCTSTR)GetLogName(),
  2015. (LPTSTR)(LPCTSTR)strMachineName,
  2016. NULL,
  2017. dwFlags,
  2018. &dwStrBufLen,
  2019. m_strFileName.GetBufferSetLength ( dwStrBufLen ) );
  2020. m_strFileName.ReleaseBuffer();
  2021. }
  2022. }
  2023. SetLastError ( hr );
  2024. return m_strFileName;
  2025. }
  2026. //
  2027. // Get log file name currently in use
  2028. //
  2029. //
  2030. DWORD
  2031. CSmLogQuery::GetLogFileName ( CString& rstrLogFileName )
  2032. {
  2033. DWORD dwStatus = ERROR_SUCCESS;
  2034. MFC_TRY
  2035. rstrLogFileName = GetLogFileName();
  2036. MFC_CATCH_DWSTATUS
  2037. return dwStatus;
  2038. }
  2039. DWORD
  2040. CSmLogQuery::GetLogType ( void )
  2041. {
  2042. // Subclass must override
  2043. ASSERT ( FALSE );
  2044. return ((DWORD)-1);
  2045. }
  2046. BOOL
  2047. CSmLogQuery::SetLogFileType ( const DWORD dwType )
  2048. {
  2049. DWORD dwLogFileType = LOWORD(dwType);
  2050. if (dwLogFileType < (SLF_FIRST_FILE_TYPE + SLF_NUM_FILE_TYPES)) {
  2051. mr_dwLogFileType = dwLogFileType;
  2052. return TRUE;
  2053. } else {
  2054. return FALSE;
  2055. }
  2056. }
  2057. const CString&
  2058. CSmLogQuery::GetLogName()
  2059. {
  2060. return m_strName;
  2061. }
  2062. DWORD
  2063. CSmLogQuery::GetLogName ( CString& rstrLogName )
  2064. {
  2065. DWORD dwStatus = ERROR_SUCCESS;
  2066. MFC_TRY
  2067. rstrLogName = GetLogName();
  2068. MFC_CATCH_DWSTATUS
  2069. return dwStatus;
  2070. }
  2071. DWORD
  2072. CSmLogQuery::SetLogName ( const CString& rstrLogName )
  2073. {
  2074. DWORD dwStatus = ERROR_SUCCESS;
  2075. MFC_TRY
  2076. m_strName = rstrLogName;
  2077. MFC_CATCH_DWSTATUS
  2078. return dwStatus;
  2079. }
  2080. const CString&
  2081. CSmLogQuery::GetLogKeyName()
  2082. {
  2083. return mr_strLogKeyName;
  2084. }
  2085. DWORD
  2086. CSmLogQuery::GetLogKeyName ( CString& rstrLogKeyName )
  2087. {
  2088. DWORD dwStatus = ERROR_SUCCESS;
  2089. MFC_TRY
  2090. rstrLogKeyName = GetLogKeyName();
  2091. MFC_CATCH_DWSTATUS
  2092. return dwStatus;
  2093. }
  2094. DWORD
  2095. CSmLogQuery::SetLogKeyName ( const CString& rstrLogKeyName )
  2096. {
  2097. DWORD dwStatus = ERROR_SUCCESS;
  2098. MFC_TRY
  2099. mr_strLogKeyName = rstrLogKeyName;
  2100. MFC_CATCH_DWSTATUS
  2101. return dwStatus;
  2102. }
  2103. DWORD
  2104. CSmLogQuery::GetEofCommand ( CString& rstrCmdString)
  2105. {
  2106. DWORD dwStatus = ERROR_SUCCESS;
  2107. MFC_TRY
  2108. rstrCmdString = mr_strEofCmdFile;
  2109. MFC_CATCH_DWSTATUS
  2110. return dwStatus;
  2111. }
  2112. DWORD
  2113. CSmLogQuery::SetEofCommand ( const CString& rstrCmdString )
  2114. {
  2115. DWORD dwStatus = ERROR_SUCCESS;
  2116. MFC_TRY
  2117. mr_strEofCmdFile = rstrCmdString;
  2118. MFC_CATCH_DWSTATUS
  2119. return dwStatus;
  2120. }
  2121. const CString&
  2122. CSmLogQuery::GetLogComment()
  2123. {
  2124. return mr_strComment;
  2125. }
  2126. DWORD
  2127. CSmLogQuery::GetLogComment ( CString& rstrLogComment )
  2128. {
  2129. DWORD dwStatus = ERROR_SUCCESS;
  2130. MFC_TRY
  2131. rstrLogComment = GetLogComment();
  2132. MFC_CATCH_DWSTATUS
  2133. return dwStatus;
  2134. }
  2135. DWORD
  2136. CSmLogQuery::SetLogComment ( const CString& rstrComment )
  2137. {
  2138. DWORD dwStatus = ERROR_SUCCESS;
  2139. MFC_TRY
  2140. mr_strComment = rstrComment;
  2141. MFC_CATCH_DWSTATUS
  2142. return dwStatus;
  2143. }
  2144. DWORD
  2145. CSmLogQuery::SetLogCommentIndirect ( const CString& rstrComment )
  2146. {
  2147. DWORD dwStatus = ERROR_SUCCESS;
  2148. MFC_TRY
  2149. mr_strCommentIndirect = rstrComment;
  2150. MFC_CATCH_DWSTATUS
  2151. return dwStatus;
  2152. }
  2153. DWORD
  2154. CSmLogQuery::SetLogFileName ( const CString& rstrFileName )
  2155. {
  2156. DWORD dwStatus = ERROR_SUCCESS;
  2157. MFC_TRY
  2158. mr_strBaseFileName = rstrFileName;
  2159. MFC_CATCH_DWSTATUS
  2160. return dwStatus;
  2161. }
  2162. DWORD
  2163. CSmLogQuery::SetLogFileNameIndirect ( const CString& rstrFileName )
  2164. {
  2165. DWORD dwStatus = ERROR_SUCCESS;
  2166. MFC_TRY
  2167. mr_strBaseFileNameIndirect = rstrFileName;
  2168. MFC_CATCH_DWSTATUS
  2169. return dwStatus;
  2170. }
  2171. DWORD
  2172. CSmLogQuery::SetFileNameParts ( const CString& rstrFolder, const CString& rstrName )
  2173. {
  2174. DWORD dwStatus = ERROR_SUCCESS;
  2175. MFC_TRY
  2176. mr_strBaseFileName = rstrFolder;
  2177. mr_strDefaultDirectory = rstrName;
  2178. MFC_CATCH_DWSTATUS
  2179. return dwStatus;
  2180. }
  2181. DWORD
  2182. CSmLogQuery::GetMaxSize()
  2183. {
  2184. return mr_dwMaxSize;
  2185. }
  2186. BOOL
  2187. CSmLogQuery::SetMaxSize ( const DWORD dwMaxSize )
  2188. {
  2189. mr_dwMaxSize = dwMaxSize;
  2190. return TRUE;
  2191. }
  2192. HKEY
  2193. CSmLogQuery::GetQueryKey ( void )
  2194. {
  2195. return m_hKeyQuery;
  2196. }
  2197. const CString&
  2198. CSmLogQuery::GetSqlName()
  2199. {
  2200. return mr_strSqlName;
  2201. }
  2202. DWORD
  2203. CSmLogQuery::GetSqlName ( CString& rstrSqlName )
  2204. {
  2205. DWORD dwStatus = ERROR_SUCCESS;
  2206. MFC_TRY
  2207. rstrSqlName = GetSqlName();
  2208. MFC_CATCH_DWSTATUS
  2209. return dwStatus;
  2210. }
  2211. DWORD
  2212. CSmLogQuery::SetSqlName ( const CString& rstrSqlName )
  2213. {
  2214. DWORD dwStatus = ERROR_SUCCESS;
  2215. MFC_TRY
  2216. mr_strSqlName = rstrSqlName;
  2217. MFC_CATCH_DWSTATUS
  2218. return dwStatus;
  2219. }
  2220. //
  2221. // return: 1 if the log is currently active or
  2222. // 0 if the log is not running
  2223. //
  2224. BOOL
  2225. CSmLogQuery::IsRunning()
  2226. {
  2227. DWORD dwCurrentState = SLQ_QUERY_START_PENDING;
  2228. DWORD dwTimeout = 20;
  2229. while (--dwTimeout) {
  2230. dwCurrentState = GetState();
  2231. if ( SLQ_QUERY_START_PENDING == dwCurrentState ) {
  2232. Sleep(100);
  2233. } else {
  2234. break;
  2235. }
  2236. }
  2237. return ( SLQ_QUERY_RUNNING == dwCurrentState );
  2238. }
  2239. BOOL
  2240. CSmLogQuery::IsAutoStart()
  2241. {
  2242. return ( SLQ_AUTO_MODE_NONE != mr_stiStart.dwAutoMode );
  2243. }
  2244. BOOL
  2245. CSmLogQuery::IsAutoRestart()
  2246. {
  2247. return ( SLQ_AUTO_MODE_AFTER == mr_dwAutoRestartMode );
  2248. }
  2249. DWORD
  2250. CSmLogQuery::GetFileNameParts( CString& rstrFolder, CString& rstrName)
  2251. {
  2252. DWORD dwStatus = ERROR_SUCCESS;
  2253. MFC_TRY
  2254. rstrFolder = mr_strDefaultDirectory;
  2255. rstrName = mr_strBaseFileName;
  2256. MFC_CATCH_DWSTATUS
  2257. return dwStatus;
  2258. }
  2259. DWORD
  2260. CSmLogQuery::GetFileNameAutoFormat()
  2261. {
  2262. return mr_dwLogAutoFormat;
  2263. }
  2264. BOOL
  2265. CSmLogQuery::SetFileNameAutoFormat ( const DWORD dwFileSuffix )
  2266. {
  2267. if ((dwFileSuffix < ( SLF_NAME_FIRST_AUTO + SLF_NUM_AUTO_NAME_TYPES)) ||
  2268. (dwFileSuffix == SLF_NAME_NONE)) {
  2269. mr_dwLogAutoFormat = dwFileSuffix;
  2270. return TRUE;
  2271. }
  2272. return FALSE;
  2273. }
  2274. DWORD
  2275. CSmLogQuery::GetFileSerialNumber( void )
  2276. {
  2277. SyncSerialNumberWithRegistry();
  2278. return mr_dwCurrentSerialNumber;
  2279. }
  2280. BOOL
  2281. CSmLogQuery::SetFileSerialNumber ( const DWORD dwSerial )
  2282. {
  2283. mr_dwCurrentSerialNumber = dwSerial;
  2284. return TRUE;
  2285. }
  2286. DWORD
  2287. CSmLogQuery::GetState()
  2288. {
  2289. DWORD dwCurrentState = SLQ_QUERY_STOPPED;
  2290. // If the service is running, get the value from the registry.
  2291. if ( m_pLogService->IsRunning() ) {
  2292. DWORD dwStatus;
  2293. dwStatus = ReadRegistryDwordValue (
  2294. m_hKeyQuery,
  2295. IDS_REG_CURRENT_STATE,
  2296. SLQ_QUERY_STOPPED,
  2297. &mr_dwCurrentState);
  2298. ASSERT (dwStatus == ERROR_SUCCESS);
  2299. dwCurrentState = mr_dwCurrentState;
  2300. }
  2301. return dwCurrentState;
  2302. }
  2303. BOOL
  2304. CSmLogQuery::SetState ( const DWORD dwNewState )
  2305. {
  2306. // Only use this to set the start state. This is necessary
  2307. // so that the service, at service startup, can differentiate
  2308. // between previously running queries and newly requested query starts.
  2309. ASSERT ( SLQ_QUERY_START_PENDING == dwNewState );
  2310. // Set the local variable if it is different.
  2311. if ( mr_dwCurrentState != dwNewState ) {
  2312. mr_dwCurrentState = dwNewState;
  2313. }
  2314. return TRUE;
  2315. }
  2316. BOOL
  2317. CSmLogQuery::GetLogTime(PSLQ_TIME_INFO pTimeInfo, DWORD dwFlags)
  2318. {
  2319. switch (dwFlags) {
  2320. case SLQ_TT_TTYPE_START:
  2321. *pTimeInfo = mr_stiStart;
  2322. return TRUE;
  2323. case SLQ_TT_TTYPE_STOP:
  2324. *pTimeInfo = mr_stiStop;
  2325. return TRUE;
  2326. case SLQ_TT_TTYPE_RESTART:
  2327. pTimeInfo->wTimeType = SLQ_TT_TTYPE_RESTART;
  2328. pTimeInfo->dwAutoMode = mr_dwAutoRestartMode;
  2329. pTimeInfo->wDataType = SLQ_TT_DTYPE_UNITS; // not used
  2330. pTimeInfo->dwUnitType = SLQ_TT_UTYPE_MINUTES; // not used
  2331. pTimeInfo->dwValue = 0; // not used
  2332. return TRUE;
  2333. case SLQ_TT_TTYPE_SAMPLE:
  2334. *pTimeInfo = mr_stiSampleInterval;
  2335. return TRUE;
  2336. default:
  2337. return FALSE;
  2338. }
  2339. }
  2340. BOOL
  2341. CSmLogQuery::SetLogTime(PSLQ_TIME_INFO pTimeInfo, const DWORD dwFlags)
  2342. {
  2343. ASSERT (pTimeInfo->wTimeType == dwFlags);
  2344. switch (dwFlags) {
  2345. case SLQ_TT_TTYPE_START:
  2346. mr_stiStart = *pTimeInfo ;
  2347. return TRUE;
  2348. case SLQ_TT_TTYPE_STOP:
  2349. mr_stiStop = *pTimeInfo;
  2350. return TRUE;
  2351. case SLQ_TT_TTYPE_RESTART:
  2352. mr_dwAutoRestartMode = pTimeInfo->dwAutoMode;
  2353. return TRUE;
  2354. case SLQ_TT_TTYPE_SAMPLE:
  2355. mr_stiSampleInterval = *pTimeInfo;
  2356. return TRUE;
  2357. default:
  2358. return FALSE;
  2359. }
  2360. }
  2361. BOOL
  2362. CSmLogQuery::GetDefaultLogTime(SLQ_TIME_INFO& /*rTimeInfo*/, DWORD /*dwFlags*/)
  2363. {
  2364. // Subclass must override
  2365. ASSERT( FALSE );
  2366. return FALSE;
  2367. }
  2368. void
  2369. CSmLogQuery::SyncPropPageSharedData ( void )
  2370. {
  2371. // Sync the data shared between property pages
  2372. // from registry values.
  2373. MFC_TRY
  2374. m_PropData.dwMaxFileSize = mr_dwMaxSize;
  2375. m_PropData.dwLogFileType = LOWORD(mr_dwLogFileType);
  2376. m_PropData.strFolderName = mr_strDefaultDirectory;
  2377. m_PropData.strFileBaseName = mr_strBaseFileName;
  2378. m_PropData.strSqlName = mr_strSqlName;
  2379. m_PropData.dwSuffix = mr_dwLogAutoFormat;
  2380. SyncSerialNumberWithRegistry();
  2381. m_PropData.dwSerialNumber = mr_dwCurrentSerialNumber;
  2382. m_PropData.stiStartTime = mr_stiStart;
  2383. m_PropData.stiStopTime = mr_stiStop;
  2384. m_PropData.stiSampleTime = mr_stiSampleInterval;
  2385. MFC_CATCH_MINIMUM
  2386. // Todo: Return and use status
  2387. }
  2388. void
  2389. CSmLogQuery::UpdatePropPageSharedData ( void )
  2390. {
  2391. // Update the registry values for data shared between property pages.
  2392. // Note: This is called by the property page OnApply code. It is assumed
  2393. // that OnApply is called for all property pages, so the shared data is valid.
  2394. // This method handles the problem where default Start mode and time was
  2395. // written to the registry by the counter page OnApply before the
  2396. // schedule page OnApply modified the value.
  2397. MFC_TRY
  2398. mr_dwMaxSize = m_PropData.dwMaxFileSize;
  2399. mr_dwLogFileType = m_PropData.dwLogFileType;
  2400. mr_dwLogAutoFormat = m_PropData.dwSuffix;
  2401. mr_dwCurrentSerialNumber = m_PropData.dwSerialNumber;
  2402. mr_stiStart = m_PropData.stiStartTime;
  2403. mr_stiStop = m_PropData.stiStopTime;
  2404. mr_stiSampleInterval = m_PropData.stiSampleTime;
  2405. mr_strBaseFileName = m_PropData.strFileBaseName;
  2406. mr_strDefaultDirectory = m_PropData.strFolderName;
  2407. mr_strSqlName = m_PropData.strSqlName;
  2408. MFC_CATCH_MINIMUM
  2409. // Todo: Return and use status
  2410. }
  2411. BOOL
  2412. CSmLogQuery::GetPropPageSharedData (PSLQ_PROP_PAGE_SHARED pData)
  2413. {
  2414. BOOL bReturn = FALSE;
  2415. if ( NULL != pData ) {
  2416. MFC_TRY
  2417. pData->dwLogFileType = m_PropData.dwLogFileType;
  2418. pData->dwMaxFileSize = m_PropData.dwMaxFileSize;
  2419. pData->strFileBaseName = m_PropData.strFileBaseName;
  2420. pData->strFolderName = m_PropData.strFolderName;
  2421. pData->strSqlName = m_PropData.strSqlName;
  2422. pData->dwLogFileType = m_PropData.dwLogFileType;
  2423. pData->dwSuffix = m_PropData.dwSuffix;
  2424. pData->dwSerialNumber = m_PropData.dwSerialNumber;
  2425. pData->stiStartTime = m_PropData.stiStartTime;
  2426. pData->stiStopTime = m_PropData.stiStopTime;
  2427. pData->stiSampleTime = m_PropData.stiSampleTime;
  2428. bReturn = TRUE;
  2429. MFC_CATCH_MINIMUM
  2430. }
  2431. // Todo: Return and use status
  2432. return bReturn;
  2433. }
  2434. BOOL
  2435. CSmLogQuery::SetPropPageSharedData (PSLQ_PROP_PAGE_SHARED pData)
  2436. {
  2437. BOOL bReturn = FALSE;
  2438. if ( NULL != pData ) {
  2439. MFC_TRY
  2440. m_PropData.dwLogFileType = pData->dwLogFileType;
  2441. m_PropData.dwMaxFileSize = pData->dwMaxFileSize;
  2442. m_PropData.strFileBaseName = pData->strFileBaseName;
  2443. m_PropData.strFolderName = pData->strFolderName;
  2444. m_PropData.strSqlName = pData->strSqlName;
  2445. m_PropData.dwLogFileType = pData->dwLogFileType;
  2446. m_PropData.dwSuffix = pData->dwSuffix;
  2447. m_PropData.dwSerialNumber = pData->dwSerialNumber;
  2448. m_PropData.stiStartTime = pData->stiStartTime;
  2449. m_PropData.stiStopTime = pData->stiStopTime;
  2450. m_PropData.stiSampleTime = pData->stiSampleTime;
  2451. MFC_CATCH_MINIMUM
  2452. }
  2453. // Todo: Return and use status
  2454. return bReturn;
  2455. }
  2456. void
  2457. CSmLogQuery::InitDataStoreAttributesDefault (
  2458. const DWORD dwRegLogFileType,
  2459. DWORD& rdwDefault )
  2460. {
  2461. DWORD dwBeta1AppendFlags;
  2462. DWORD dwLogFileType;
  2463. // Append vs. Overwrite
  2464. // Win2000 files defaulted to OVERWRITE.
  2465. // The Append mode flags did not exist.
  2466. // Convert the settings to use new flags.
  2467. // Whistler Beta 1 append mode was stored in high word of log file type
  2468. dwBeta1AppendFlags = dwRegLogFileType & 0x00FF0000;
  2469. rdwDefault = 0;
  2470. GetLogFileType ( dwLogFileType );
  2471. if ( SLF_FILE_APPEND == dwBeta1AppendFlags ) {
  2472. mr_dwAppendMode = SLF_DATA_STORE_APPEND;
  2473. rdwDefault = SLF_DATA_STORE_APPEND;
  2474. } else if ( SLF_FILE_OVERWRITE == dwBeta1AppendFlags ) {
  2475. mr_dwAppendMode = SLF_DATA_STORE_OVERWRITE;
  2476. rdwDefault = SLF_DATA_STORE_OVERWRITE;
  2477. } else if ( 0 == dwBeta1AppendFlags ) {
  2478. if ( SLF_SQL_LOG == dwLogFileType ) {
  2479. mr_dwAppendMode = SLF_DATA_STORE_APPEND;
  2480. } else {
  2481. // Default for Win2K is overwrite.
  2482. // For Whistler, mode is stored in Data Store Attributes
  2483. mr_dwAppendMode = SLF_DATA_STORE_OVERWRITE;
  2484. }
  2485. }
  2486. // Append vs. overwrite flag
  2487. if ( 0 == rdwDefault ) {
  2488. if ( SLF_BIN_FILE == dwLogFileType
  2489. || SLF_SEQ_TRACE_FILE == dwLogFileType
  2490. || SLF_SQL_LOG == dwLogFileType )
  2491. {
  2492. rdwDefault = SLF_DATA_STORE_APPEND;
  2493. } else {
  2494. rdwDefault = SLF_DATA_STORE_OVERWRITE;
  2495. }
  2496. }
  2497. // File size units flag
  2498. if ( SLQ_COUNTER_LOG == GetLogType() ) {
  2499. if ( SLF_SQL_LOG != dwLogFileType ) {
  2500. rdwDefault |= SLF_DATA_STORE_SIZE_ONE_KB;
  2501. } else {
  2502. rdwDefault |= SLF_DATA_STORE_SIZE_ONE_RECORD;
  2503. }
  2504. } else if ( SLQ_TRACE_LOG == GetLogType() ){
  2505. rdwDefault |= SLF_DATA_STORE_SIZE_ONE_MB;
  2506. }
  2507. }
  2508. void
  2509. CSmLogQuery::ProcessLoadedDataStoreAttributes (
  2510. DWORD dwDataStoreAttributes )
  2511. {
  2512. DWORD dwLogFileType = 0;
  2513. if ( dwDataStoreAttributes & SLF_DATA_STORE_SIZE_ONE_MB ) {
  2514. mr_dwFileSizeUnits = ONE_MB;
  2515. } else if ( dwDataStoreAttributes & SLF_DATA_STORE_SIZE_ONE_KB ) {
  2516. mr_dwFileSizeUnits = ONE_KB;
  2517. } else if ( dwDataStoreAttributes & SLF_DATA_STORE_SIZE_ONE_RECORD ) {
  2518. mr_dwFileSizeUnits = ONE_RECORD;
  2519. }
  2520. // Within the app, counter data store size units are in MB.
  2521. // Translate to MB here, back to KB when write to registry.
  2522. GetLogFileType( dwLogFileType );
  2523. if ( SLQ_COUNTER_LOG == GetLogType()
  2524. && SLF_SQL_LOG != dwLogFileType )
  2525. {
  2526. ASSERT ( ONE_KB == GetDataStoreSizeUnits() );
  2527. if ( ONE_KB == GetDataStoreSizeUnits() ) {
  2528. mr_dwFileSizeUnits = ONE_MB;
  2529. if ( SLQ_DISK_MAX_SIZE != mr_dwMaxSize ) {
  2530. // Round up to next MB
  2531. mr_dwMaxSize = ( mr_dwMaxSize + (ONE_KB - 1) ) / ONE_KB;
  2532. }
  2533. }
  2534. }
  2535. // Data store append mode
  2536. ASSERT ( dwDataStoreAttributes & SLF_DATA_STORE_APPEND_MASK );
  2537. // Todo: Does defalt value setting overwrite the Whistler Beta 1 setting?
  2538. if ( dwDataStoreAttributes & SLF_DATA_STORE_APPEND ) {
  2539. mr_dwAppendMode = SLF_DATA_STORE_APPEND;
  2540. } else if ( dwDataStoreAttributes & SLF_DATA_STORE_OVERWRITE ) {
  2541. mr_dwAppendMode = SLF_DATA_STORE_OVERWRITE;
  2542. }
  2543. }
  2544. HRESULT
  2545. CSmLogQuery::LoadFromPropertyBag (
  2546. IPropertyBag* pPropBag,
  2547. IErrorLog* pIErrorLog )
  2548. {
  2549. HRESULT hr = S_OK;
  2550. DWORD dwBufSize;
  2551. SLQ_TIME_INFO stiDefault;
  2552. LPTSTR pszTemp = NULL;
  2553. DWORD dwTemp;
  2554. DWORD dwDefault;
  2555. TCHAR szDefault[MAX_PATH + 1];
  2556. LPTSTR szEofCmd = NULL;
  2557. // Subclass must call this method at the end of their override, to sync the
  2558. // property page shared data.
  2559. // Continue even if error, using defaults for missing values.
  2560. mr_strComment.Empty();
  2561. dwBufSize = 0;
  2562. hr = StringFromPropertyBag ( pPropBag, pIErrorLog, IDS_HTML_COMMENT, DEFAULT_COMMENT, &pszTemp, &dwBufSize );
  2563. if ( sizeof(TCHAR) < dwBufSize ) {
  2564. ASSERT ( NULL != pszTemp );
  2565. ASSERT ( 0 != *pszTemp );
  2566. mr_strComment = pszTemp;
  2567. }
  2568. delete ( pszTemp );
  2569. pszTemp = NULL;
  2570. lstrcpynW ( szDefault, m_strName , min ( MAX_PATH + 1, m_strName.GetLength() + 1 ) );
  2571. szDefault[MAX_PATH] = L'\0';
  2572. ReplaceBlanksWithUnderscores ( szDefault );
  2573. mr_strBaseFileName.Empty();
  2574. dwBufSize = 0;
  2575. hr = StringFromPropertyBag (
  2576. pPropBag,
  2577. pIErrorLog,
  2578. IDS_HTML_LOG_FILE_BASE_NAME,
  2579. szDefault,
  2580. &pszTemp,
  2581. &dwBufSize );
  2582. if ( sizeof(TCHAR) < dwBufSize ) {
  2583. ASSERT ( NULL != pszTemp );
  2584. ASSERT ( 0 != *pszTemp );
  2585. mr_strBaseFileName = pszTemp;
  2586. }
  2587. delete ( pszTemp );
  2588. pszTemp = NULL;
  2589. mr_strDefaultDirectory.Empty();
  2590. dwBufSize = 0;
  2591. hr = StringFromPropertyBag (
  2592. pPropBag,
  2593. pIErrorLog,
  2594. IDS_HTML_LOG_FILE_FOLDER,
  2595. m_pLogService->GetDefaultLogFileFolder(),
  2596. &pszTemp,
  2597. &dwBufSize );
  2598. if ( sizeof(TCHAR) < dwBufSize ) {
  2599. ASSERT ( NULL != pszTemp );
  2600. ASSERT ( 0 != *pszTemp );
  2601. mr_strDefaultDirectory = pszTemp;
  2602. }
  2603. delete ( pszTemp );
  2604. pszTemp = NULL;
  2605. mr_strSqlName.Empty();
  2606. dwBufSize = 0;
  2607. hr = StringFromPropertyBag (
  2608. pPropBag,
  2609. pIErrorLog,
  2610. IDS_HTML_SQL_LOG_BASE_NAME,
  2611. DEFAULT_SQL_LOG_BASE_NAME,
  2612. &pszTemp,
  2613. &dwBufSize );
  2614. if ( sizeof(TCHAR) < dwBufSize ) {
  2615. ASSERT ( NULL != pszTemp );
  2616. ASSERT ( 0 != *pszTemp );
  2617. mr_strSqlName = pszTemp;
  2618. }
  2619. delete ( pszTemp );
  2620. pszTemp = NULL;
  2621. hr = DwordFromPropertyBag ( pPropBag, pIErrorLog, IDS_HTML_REALTIME_DATASOURCE, g_dwRealTimeQuery, mr_dwRealTimeQuery );
  2622. hr = DwordFromPropertyBag ( pPropBag, pIErrorLog, IDS_HTML_LOG_FILE_MAX_SIZE, DEFAULT_LOG_FILE_MAX_SIZE, mr_dwMaxSize );
  2623. if ( SLQ_COUNTER_LOG == GetLogType() ) {
  2624. hr = DwordFromPropertyBag ( pPropBag, pIErrorLog, IDS_HTML_LOG_FILE_TYPE, DEFAULT_CTR_LOG_FILE_TYPE, dwTemp );
  2625. } else {
  2626. // Read only for counter and trace logs, not for alerts?
  2627. hr = DwordFromPropertyBag ( pPropBag, pIErrorLog, IDS_HTML_LOG_FILE_TYPE, DEFAULT_TRACE_LOG_FILE_TYPE, dwTemp );
  2628. }
  2629. SetLogFileType ( dwTemp );
  2630. // Data store attributes must be read after log file type and log file max size.
  2631. InitDataStoreAttributesDefault ( dwTemp, dwDefault );
  2632. // If file size unit value is missing, default to Win2000 values
  2633. hr = DwordFromPropertyBag ( pPropBag, pIErrorLog, IDS_HTML_DATA_STORE_ATTRIBUTES, dwDefault, dwTemp );
  2634. ProcessLoadedDataStoreAttributes ( dwTemp );
  2635. hr = DwordFromPropertyBag ( pPropBag, pIErrorLog, IDS_HTML_LOG_FILE_AUTO_FORMAT, DEFAULT_LOG_FILE_AUTO_FORMAT, mr_dwLogAutoFormat );
  2636. hr = DwordFromPropertyBag ( pPropBag, pIErrorLog, IDS_HTML_LOG_FILE_SERIAL_NUMBER, DEFAULT_LOG_FILE_SERIAL_NUMBER, mr_dwCurrentSerialNumber );
  2637. // Do not load "Current State", since a new query is always stopped when created.
  2638. // Start and Stop values.
  2639. VERIFY ( GetDefaultLogTime (stiDefault, SLQ_TT_TTYPE_START ) );
  2640. hr = SlqTimeFromPropertyBag ( pPropBag, pIErrorLog, SLQ_TT_TTYPE_START, &stiDefault, &mr_stiStart );
  2641. VERIFY ( GetDefaultLogTime (stiDefault, SLQ_TT_TTYPE_STOP ) );
  2642. hr = SlqTimeFromPropertyBag ( pPropBag, pIErrorLog, SLQ_TT_TTYPE_STOP, &stiDefault, &mr_stiStop );
  2643. hr = DwordFromPropertyBag ( pPropBag, pIErrorLog, IDS_HTML_RESTART_MODE, DEFAULT_RESTART_VALUE, mr_dwAutoRestartMode);
  2644. // Eof command file for counter and trace logs only.
  2645. if ( SLQ_COUNTER_LOG == GetLogType()
  2646. || SLQ_TRACE_LOG == GetLogType() ) {
  2647. mr_strEofCmdFile.Empty();
  2648. dwBufSize = 0;
  2649. hr = StringFromPropertyBag (
  2650. pPropBag,
  2651. pIErrorLog,
  2652. IDS_HTML_EOF_COMMAND_FILE,
  2653. DEFAULT_EOF_COMMAND_FILE,
  2654. &szEofCmd,
  2655. &dwBufSize );
  2656. if ( sizeof(TCHAR) < dwBufSize ) {
  2657. ASSERT ( NULL != szEofCmd );
  2658. MFC_TRY
  2659. mr_strEofCmdFile = szEofCmd;
  2660. MFC_CATCH_MINIMUM
  2661. }
  2662. if ( NULL != szEofCmd ) {
  2663. delete (szEofCmd);
  2664. }
  2665. }
  2666. SyncPropPageSharedData();
  2667. return hr;
  2668. }
  2669. HRESULT
  2670. CSmLogQuery::SaveToPropertyBag (
  2671. IPropertyBag* pPropBag,
  2672. BOOL /* fSaveAllProps */ )
  2673. {
  2674. HRESULT hr = NOERROR;
  2675. SMONCTRL_VERSION_DATA VersData;
  2676. DWORD dwTemp;
  2677. DWORD dwTempFileSizeUnits;
  2678. DWORD dwTempDataStoreAttributes = 0;
  2679. DWORD dwTempMaxFileSize;
  2680. DWORD dwTempAppendMode;
  2681. DWORD dwLogFileType = 0;
  2682. VersData.iMajor = SMONCTRL_MAJ_VERSION;
  2683. VersData.iMinor = SMONCTRL_MIN_VERSION;
  2684. hr = DwordToPropertyBag ( pPropBag, IDS_HTML_SYSMON_VERSION, VersData.dwVersion );
  2685. if ( SLQ_ALERT == GetLogType() ) {
  2686. hr = StringToPropertyBag ( pPropBag, IDS_HTML_ALERT_NAME, m_strName );
  2687. } else {
  2688. hr = StringToPropertyBag ( pPropBag, IDS_HTML_LOG_NAME, m_strName );
  2689. }
  2690. hr = StringToPropertyBag ( pPropBag, IDS_HTML_COMMENT, mr_strComment );
  2691. hr = DwordToPropertyBag ( pPropBag, IDS_HTML_LOG_TYPE, GetLogType() );
  2692. // Save current state. It can be used to determine the validity of the logfilename.
  2693. hr = DwordToPropertyBag ( pPropBag, IDS_HTML_CURRENT_STATE, mr_dwCurrentState );
  2694. hr = DwordToPropertyBag ( pPropBag, IDS_HTML_REALTIME_DATASOURCE, mr_dwRealTimeQuery );
  2695. // Within the app, counter data store size units are in MB.
  2696. // Translate to back to KB when write to registry
  2697. dwTempFileSizeUnits = GetDataStoreSizeUnits();
  2698. dwTempMaxFileSize = mr_dwMaxSize;
  2699. GetLogFileType ( dwLogFileType );
  2700. if ( SLQ_COUNTER_LOG == GetLogType()
  2701. && SLF_SQL_LOG != dwLogFileType )
  2702. {
  2703. if ( ONE_MB == dwTempFileSizeUnits ) {
  2704. dwTempFileSizeUnits = ONE_KB;
  2705. // Round up to next MB
  2706. if ( SLQ_DISK_MAX_SIZE != mr_dwMaxSize ) {
  2707. dwTempMaxFileSize *= dwTempFileSizeUnits;
  2708. }
  2709. }
  2710. }
  2711. hr = DwordToPropertyBag ( pPropBag, IDS_HTML_LOG_FILE_MAX_SIZE, dwTempMaxFileSize );
  2712. // Data store size units
  2713. if ( ONE_MB == dwTempFileSizeUnits ) {
  2714. dwTempDataStoreAttributes = SLF_DATA_STORE_SIZE_ONE_MB;
  2715. } else if ( ONE_KB == dwTempFileSizeUnits ) {
  2716. dwTempDataStoreAttributes = SLF_DATA_STORE_SIZE_ONE_KB;
  2717. } else if ( ONE_RECORD == dwTempFileSizeUnits ) {
  2718. dwTempDataStoreAttributes = SLF_DATA_STORE_SIZE_ONE_RECORD;
  2719. }
  2720. // Data store append mode
  2721. GetDataStoreAppendMode( dwTempAppendMode );
  2722. dwTempDataStoreAttributes |= dwTempAppendMode;
  2723. hr = DwordToPropertyBag ( pPropBag, IDS_HTML_DATA_STORE_ATTRIBUTES, dwTempDataStoreAttributes );
  2724. hr = StringToPropertyBag ( pPropBag, IDS_HTML_LOG_FILE_BASE_NAME, mr_strBaseFileName );
  2725. hr = DwordToPropertyBag ( pPropBag, IDS_HTML_LOG_FILE_SERIAL_NUMBER, mr_dwCurrentSerialNumber );
  2726. hr = StringToPropertyBag ( pPropBag, IDS_HTML_LOG_FILE_FOLDER, mr_strDefaultDirectory );
  2727. hr = StringToPropertyBag ( pPropBag, IDS_HTML_SQL_LOG_BASE_NAME, mr_strSqlName );
  2728. hr = DwordToPropertyBag ( pPropBag, IDS_HTML_LOG_FILE_AUTO_FORMAT, mr_dwLogAutoFormat );
  2729. // Write only for counter and trace logs, not for alerts?
  2730. // Log file type for Alerts is -1, so the new query will keep its default value.
  2731. GetLogFileType ( dwTemp );
  2732. hr = DwordToPropertyBag ( pPropBag, IDS_HTML_LOG_FILE_TYPE, dwTemp );
  2733. hr = SlqTimeToPropertyBag ( pPropBag, SLQ_TT_TTYPE_START, &mr_stiStart );
  2734. hr = SlqTimeToPropertyBag ( pPropBag, SLQ_TT_TTYPE_STOP, &mr_stiStop );
  2735. hr = DwordToPropertyBag ( pPropBag, IDS_HTML_RESTART_MODE, mr_dwAutoRestartMode );
  2736. hr = StringToPropertyBag ( pPropBag, IDS_HTML_SYSMON_LOGFILENAME, GetLogFileName(TRUE) );
  2737. // Eof command file for counter and trace logs only.
  2738. if ( SLQ_COUNTER_LOG == GetLogType()
  2739. || SLQ_TRACE_LOG == GetLogType() ) {
  2740. hr = StringToPropertyBag ( pPropBag, IDS_HTML_EOF_COMMAND_FILE, mr_strEofCmdFile );
  2741. }
  2742. return hr;
  2743. }
  2744. HRESULT
  2745. CSmLogQuery::CopyToBuffer ( LPTSTR& rpszData, DWORD& rdwBufferSize )
  2746. {
  2747. HRESULT hr;
  2748. CString strHeader;
  2749. CString strFooter;
  2750. CImpIPropertyBag IPropBag;
  2751. DWORD dwBufferLength = 0;
  2752. LPTSTR pszConfig = NULL;
  2753. ResourceStateManager rsm;
  2754. ASSERT ( NULL == rpszData );
  2755. rdwBufferSize = 0;
  2756. hr = SaveToPropertyBag (&IPropBag, TRUE );
  2757. if ( SUCCEEDED ( hr ) ) {
  2758. MFC_TRY
  2759. pszConfig = IPropBag.GetData();
  2760. if ( NULL != pszConfig ) {
  2761. strHeader.LoadString ( IDS_HTML_OBJECT_HEADER );
  2762. strFooter.LoadString ( IDS_HTML_OBJECT_FOOTER );
  2763. dwBufferLength = strHeader.GetLength() + strFooter.GetLength() + lstrlen ( pszConfig ) + 1;
  2764. rpszData = new TCHAR[dwBufferLength];
  2765. } else {
  2766. hr = E_UNEXPECTED;
  2767. }
  2768. MFC_CATCH_HR
  2769. if ( SUCCEEDED ( hr ) ) {
  2770. rdwBufferSize = dwBufferLength * sizeof(TCHAR);
  2771. lstrcpy ( rpszData, strHeader );
  2772. lstrcat ( rpszData, pszConfig );
  2773. lstrcat ( rpszData, strFooter );
  2774. }
  2775. }
  2776. return hr;
  2777. }
  2778. BOOL
  2779. CSmLogQuery::LLTimeToVariantDate (
  2780. IN LONGLONG llTime,
  2781. OUT DATE *pdate
  2782. )
  2783. {
  2784. SYSTEMTIME SystemTime;
  2785. if (!FileTimeToSystemTime((FILETIME*)&llTime, &SystemTime))
  2786. return FALSE;
  2787. if (FAILED(SystemTimeToVariantTime(&SystemTime, pdate)))
  2788. return FALSE;
  2789. return TRUE;
  2790. }
  2791. BOOL
  2792. CSmLogQuery::VariantDateToLLTime (
  2793. IN DATE date,
  2794. OUT LONGLONG *pllTime
  2795. )
  2796. {
  2797. SYSTEMTIME SystemTime;
  2798. if (FAILED(VariantTimeToSystemTime(date, &SystemTime)))
  2799. return FALSE;
  2800. if (!SystemTimeToFileTime(&SystemTime,(FILETIME*)pllTime))
  2801. return FALSE;
  2802. return TRUE;
  2803. }
  2804. DWORD
  2805. CSmLogQuery::UpdateExecuteOnly( void )
  2806. {
  2807. DWORD dwStatus = ERROR_SUCCESS;
  2808. if (!m_bReadOnly) {
  2809. DWORD dwExecuteOnly;
  2810. dwExecuteOnly = 1; // TRUE
  2811. dwStatus = WriteRegistryDwordValue (
  2812. m_hKeyQuery,
  2813. IDS_REG_EXECUTE_ONLY,
  2814. &dwExecuteOnly);
  2815. ASSERT ( ERROR_SUCCESS == dwStatus );
  2816. if ( ERROR_SUCCESS == dwStatus ) {
  2817. dwStatus = m_pLogService->Synchronize();
  2818. }
  2819. } else {
  2820. dwStatus = ERROR_ACCESS_DENIED;
  2821. }
  2822. return dwStatus;
  2823. }
  2824. CWnd*
  2825. CSmLogQuery::GetActivePropertySheet( void )
  2826. {
  2827. CWnd* pwndReturn = NULL;
  2828. if ( NULL != m_pActivePropPage ) {
  2829. pwndReturn = m_pActivePropPage->GetParentOwner();
  2830. }
  2831. return pwndReturn;
  2832. }
  2833. void
  2834. CSmLogQuery::SetActivePropertyPage( CSmPropertyPage* pPage)
  2835. {
  2836. // The first property page of each property sheet sets
  2837. // and clears this member variable.
  2838. // It is assumed that the first page is always created.
  2839. m_pActivePropPage = pPage;
  2840. return;
  2841. }
  2842. BOOL
  2843. CSmLogQuery::IsFirstModification( void )
  2844. {
  2845. BOOL bIsFirstModification = FALSE;
  2846. bIsFirstModification = ( m_bIsModified && m_bIsNew );
  2847. if ( bIsFirstModification ) {
  2848. m_bIsNew = FALSE;
  2849. }
  2850. return bIsFirstModification;
  2851. }