Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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