Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1336 lines
37 KiB

  1. /*++
  2. Copyright (C) 1998-1999 Microsoft Corporation
  3. Module Name:
  4. smalrtq.cpp
  5. Abstract:
  6. Implementation of the alert query class
  7. --*/
  8. #include "Stdafx.h"
  9. #include <pdhp.h> // for MIN_TIME_VALUE, MAX_TIME_VALUE
  10. #include <pdhmsg.h>
  11. #include "smlogs.h"
  12. #include "common.h"
  13. #include "smalrtq.h"
  14. USE_HANDLE_MACROS("SMLOGCFG(smalrtq.cpp)");
  15. #define ALRT_DEFAULT_COMMAND_FILE L""
  16. #define ALRT_DEFAULT_NETWORK_NAME L""
  17. #define ALRT_DEFAULT_USER_TEXT L""
  18. #define ALRT_DEFAULT_PERF_LOG_NAME L""
  19. //
  20. // Constructor
  21. CSmAlertQuery::CSmAlertQuery( CSmLogService* pLogService )
  22. : CSmLogQuery( pLogService ),
  23. m_dwCounterListLength ( 0 ),
  24. m_szNextCounter ( NULL ),
  25. mr_szCounterList ( NULL ),
  26. mr_dwActionFlags ( ALRT_DEFAULT_ACTION )
  27. {
  28. memset (&mr_stiSampleInterval, 0, sizeof(mr_stiSampleInterval));
  29. return;
  30. }
  31. //
  32. // Destructor
  33. CSmAlertQuery::~CSmAlertQuery()
  34. {
  35. return;
  36. }
  37. //
  38. // Open function. either opens an existing log query entry
  39. // or creates a new one
  40. //
  41. DWORD
  42. CSmAlertQuery::Open ( const CString& rstrName, HKEY hKeyQuery, BOOL bReadOnly)
  43. {
  44. DWORD dwStatus = ERROR_SUCCESS;
  45. ASSERT ( SLQ_ALERT == GetLogType() );
  46. dwStatus = CSmLogQuery::Open ( rstrName, hKeyQuery, bReadOnly );
  47. return dwStatus;
  48. }
  49. //
  50. // Close Function
  51. // closes registry handles and frees allocated memory
  52. //
  53. DWORD
  54. CSmAlertQuery::Close ()
  55. {
  56. DWORD dwStatus;
  57. LOCALTRACE (L"Closing Query\n");
  58. if (mr_szCounterList != NULL) {
  59. delete (mr_szCounterList);
  60. mr_szCounterList = NULL;
  61. }
  62. mr_strNetName.Empty();
  63. mr_strCmdFileName.Empty();
  64. mr_strCmdUserText.Empty();
  65. mr_strCmdUserTextIndirect.Empty();
  66. mr_strPerfLogName.Empty();
  67. dwStatus = CSmLogQuery::Close();
  68. return dwStatus;
  69. }
  70. //
  71. // UpdateRegistry function.
  72. // copies the current settings to the registry where they
  73. // are read by the log service
  74. //
  75. DWORD
  76. CSmAlertQuery::UpdateRegistry()
  77. {
  78. DWORD dwStatus = ERROR_SUCCESS;
  79. DWORD dwBufferSize = 0;
  80. LPTSTR szNewCounterList = NULL;
  81. if ( IsModifiable() ) {
  82. dwBufferSize = 0;
  83. //
  84. // Translate the counter list into English
  85. //
  86. dwStatus = TranslateMSZAlertCounterList(mr_szCounterList,
  87. NULL,
  88. &dwBufferSize,
  89. FALSE);
  90. if (dwStatus == ERROR_NOT_ENOUGH_MEMORY) {
  91. szNewCounterList = (LPTSTR) new char [dwBufferSize];
  92. if (szNewCounterList != NULL) {
  93. dwStatus = TranslateMSZAlertCounterList(mr_szCounterList,
  94. szNewCounterList,
  95. &dwBufferSize,
  96. FALSE);
  97. }
  98. }
  99. if (dwStatus == ERROR_SUCCESS && szNewCounterList != NULL) {
  100. dwStatus = WriteRegistryStringValue (
  101. m_hKeyQuery,
  102. IDS_REG_COUNTER_LIST,
  103. REG_MULTI_SZ,
  104. szNewCounterList,
  105. &dwBufferSize);
  106. }
  107. else {
  108. dwBufferSize = m_dwCounterListLength * sizeof(TCHAR);
  109. dwStatus = WriteRegistryStringValue (
  110. m_hKeyQuery,
  111. IDS_REG_COUNTER_LIST,
  112. REG_MULTI_SZ,
  113. mr_szCounterList,
  114. &dwBufferSize);
  115. }
  116. // Schedule
  117. if ( ERROR_SUCCESS == dwStatus ) {
  118. dwStatus = WriteRegistrySlqTime (
  119. m_hKeyQuery,
  120. IDS_REG_SAMPLE_INTERVAL,
  121. &mr_stiSampleInterval);
  122. }
  123. if ( ERROR_SUCCESS == dwStatus ) {
  124. if ( !mr_strCmdFileName.IsEmpty() ) {
  125. dwBufferSize = mr_strCmdFileName.GetLength() + 1;
  126. dwBufferSize *= sizeof(TCHAR);
  127. } else {
  128. dwBufferSize = 0;
  129. }
  130. dwStatus = WriteRegistryStringValue (
  131. m_hKeyQuery,
  132. IDS_REG_COMMAND_FILE,
  133. REG_SZ,
  134. mr_strCmdFileName,
  135. &dwBufferSize);
  136. }
  137. if ( ERROR_SUCCESS == dwStatus ) {
  138. if ( !mr_strNetName.IsEmpty() ) {
  139. dwBufferSize = mr_strNetName.GetLength() + 1;
  140. dwBufferSize *= sizeof(TCHAR);
  141. } else {
  142. dwBufferSize = 0;
  143. }
  144. dwStatus = WriteRegistryStringValue (
  145. m_hKeyQuery,
  146. IDS_REG_NETWORK_NAME,
  147. REG_SZ,
  148. mr_strNetName,
  149. &dwBufferSize);
  150. }
  151. if ( ERROR_SUCCESS == dwStatus ) {
  152. if ( !mr_strCmdUserText.IsEmpty() ) {
  153. dwBufferSize = mr_strCmdUserText.GetLength() + 1;
  154. dwBufferSize *= sizeof(TCHAR);
  155. } else {
  156. dwBufferSize = 0;
  157. }
  158. dwStatus = WriteRegistryStringValue (
  159. m_hKeyQuery,
  160. IDS_REG_USER_TEXT,
  161. REG_SZ,
  162. mr_strCmdUserText,
  163. &dwBufferSize);
  164. }
  165. if ( ERROR_SUCCESS == dwStatus && !mr_strCmdUserTextIndirect.IsEmpty() ) {
  166. dwBufferSize = mr_strCmdUserTextIndirect.GetLength() + 1;
  167. dwBufferSize *= sizeof(TCHAR);
  168. dwStatus = WriteRegistryStringValue (
  169. m_hKeyQuery,
  170. IDS_REG_USER_TEXT,
  171. REG_SZ,
  172. mr_strCmdUserTextIndirect,
  173. &dwBufferSize);
  174. }
  175. if ( ERROR_SUCCESS == dwStatus ) {
  176. if ( !mr_strPerfLogName.IsEmpty() ) {
  177. dwBufferSize = mr_strPerfLogName.GetLength() + 1;
  178. dwBufferSize *= sizeof(TCHAR);
  179. } else {
  180. dwBufferSize = 0;
  181. }
  182. dwStatus = WriteRegistryStringValue (
  183. m_hKeyQuery,
  184. IDS_REG_PERF_LOG_NAME,
  185. REG_SZ,
  186. mr_strPerfLogName,
  187. &dwBufferSize);
  188. }
  189. if ( ERROR_SUCCESS == dwStatus ) {
  190. dwStatus = WriteRegistryDwordValue(
  191. m_hKeyQuery,
  192. IDS_REG_ACTION_FLAGS,
  193. &mr_dwActionFlags,
  194. REG_DWORD);
  195. }
  196. if ( ERROR_SUCCESS == dwStatus ) {
  197. dwStatus = CSmLogQuery::UpdateRegistry ();
  198. }
  199. } else {
  200. dwStatus = ERROR_ACCESS_DENIED;
  201. }
  202. return dwStatus;
  203. }
  204. //
  205. // SyncWithRegistry()
  206. // reads the current values for this query from the registry
  207. // and reloads the internal values to match
  208. //
  209. DWORD
  210. CSmAlertQuery::SyncWithRegistry()
  211. {
  212. DWORD dwBufferSize = 0;
  213. DWORD dwStatus = ERROR_SUCCESS;
  214. SLQ_TIME_INFO stiDefault;
  215. LPTSTR pszTemp = NULL;
  216. LPWSTR szIndTemp = NULL;
  217. UINT uiBufferLen = 0;
  218. CString strValueName;
  219. LPTSTR szNewCounterList = NULL;
  220. ASSERT (m_hKeyQuery != NULL);
  221. // load counter string list
  222. // Get Counter List
  223. dwStatus = ReadRegistryStringValue (
  224. m_hKeyQuery,
  225. IDS_REG_COUNTER_LIST,
  226. NULL,
  227. &mr_szCounterList,
  228. &dwBufferSize);
  229. if (dwStatus != ERROR_SUCCESS) {
  230. m_szNextCounter = NULL; //re-initialize
  231. m_dwCounterListLength = 0;
  232. } else {
  233. // convert buffersize to chars from bytes
  234. m_dwCounterListLength = dwBufferSize / sizeof(TCHAR);
  235. //
  236. // Translate the counter list into Locale
  237. //
  238. dwBufferSize = 0;
  239. dwStatus = TranslateMSZAlertCounterList(
  240. mr_szCounterList,
  241. NULL,
  242. &dwBufferSize,
  243. TRUE);
  244. if (dwStatus == ERROR_NOT_ENOUGH_MEMORY) {
  245. szNewCounterList = (LPTSTR) new char [dwBufferSize];
  246. if (szNewCounterList != NULL) {
  247. //
  248. // Translate the counter list into Locale
  249. //
  250. dwStatus = TranslateMSZAlertCounterList(
  251. mr_szCounterList,
  252. szNewCounterList,
  253. &dwBufferSize,
  254. TRUE);
  255. if (dwStatus == ERROR_SUCCESS) {
  256. m_dwCounterListLength = dwBufferSize / sizeof(TCHAR);
  257. //
  258. // Remove the old
  259. //
  260. delete (mr_szCounterList);
  261. m_szNextCounter = NULL;
  262. mr_szCounterList = szNewCounterList;
  263. }
  264. }
  265. }
  266. }
  267. // Schedule
  268. stiDefault.wDataType = SLQ_TT_DTYPE_UNITS;
  269. stiDefault.wTimeType = SLQ_TT_TTYPE_SAMPLE;
  270. stiDefault.dwAutoMode = SLQ_AUTO_MODE_AFTER;
  271. stiDefault.dwValue = 5; // default interval;
  272. stiDefault.dwUnitType = SLQ_TT_UTYPE_SECONDS;
  273. dwStatus = ReadRegistrySlqTime (
  274. m_hKeyQuery,
  275. IDS_REG_SAMPLE_INTERVAL,
  276. &stiDefault,
  277. &mr_stiSampleInterval);
  278. ASSERT (dwStatus == ERROR_SUCCESS);
  279. dwBufferSize = 0;
  280. dwStatus = ReadRegistryStringValue (
  281. m_hKeyQuery,
  282. IDS_REG_COMMAND_FILE,
  283. ALRT_DEFAULT_COMMAND_FILE,
  284. &pszTemp,
  285. &dwBufferSize);
  286. ASSERT (dwStatus == ERROR_SUCCESS);
  287. mr_strCmdFileName.Empty();
  288. if ( dwBufferSize > sizeof(TCHAR) ) {
  289. ASSERT ( NULL != pszTemp );
  290. ASSERT ( 0 != *pszTemp );
  291. mr_strCmdFileName = pszTemp;
  292. }
  293. delete ( pszTemp );
  294. pszTemp = NULL;
  295. dwBufferSize = 0;
  296. dwStatus = ReadRegistryStringValue (
  297. m_hKeyQuery,
  298. IDS_REG_NETWORK_NAME,
  299. ALRT_DEFAULT_NETWORK_NAME,
  300. &pszTemp,
  301. &dwBufferSize);
  302. ASSERT (dwStatus == ERROR_SUCCESS);
  303. mr_strNetName.Empty();
  304. if ( dwBufferSize > sizeof(TCHAR) ) {
  305. ASSERT ( NULL != pszTemp );
  306. ASSERT ( 0 != *pszTemp );
  307. mr_strNetName = pszTemp;
  308. }
  309. delete ( pszTemp );
  310. pszTemp = NULL;
  311. dwBufferSize = 0;
  312. // User text field can be indirect
  313. MFC_TRY
  314. strValueName.LoadString ( IDS_REG_USER_TEXT );
  315. MFC_CATCH_DWSTATUS;
  316. if ( ERROR_SUCCESS == dwStatus ) {
  317. dwStatus = SmReadRegistryIndirectStringValue (
  318. m_hKeyQuery,
  319. strValueName,
  320. ALRT_DEFAULT_USER_TEXT,
  321. &szIndTemp,
  322. &uiBufferLen );
  323. }
  324. mr_strCmdUserText.Empty();
  325. if ( NULL != szIndTemp ) {
  326. if ( _T('\0') != *szIndTemp ) {
  327. mr_strCmdUserText = szIndTemp;
  328. }
  329. }
  330. if ( NULL != szIndTemp ) {
  331. G_FREE ( szIndTemp );
  332. szIndTemp = NULL;
  333. }
  334. uiBufferLen = 0;
  335. dwStatus = ReadRegistryStringValue (
  336. m_hKeyQuery,
  337. IDS_REG_PERF_LOG_NAME,
  338. ALRT_DEFAULT_PERF_LOG_NAME,
  339. &pszTemp,
  340. &dwBufferSize);
  341. ASSERT (dwStatus == ERROR_SUCCESS);
  342. mr_strPerfLogName.Empty();
  343. if ( dwBufferSize > sizeof(TCHAR) ) {
  344. ASSERT ( NULL != pszTemp );
  345. ASSERT ( 0 != *pszTemp );
  346. mr_strPerfLogName = pszTemp;
  347. }
  348. delete ( pszTemp );
  349. pszTemp = NULL;
  350. dwBufferSize = 0;
  351. dwStatus = ReadRegistryDwordValue (
  352. m_hKeyQuery,
  353. IDS_REG_ACTION_FLAGS,
  354. ALRT_DEFAULT_ACTION,
  355. &mr_dwActionFlags);
  356. ASSERT ( ERROR_SUCCESS == dwStatus );
  357. // Call parent class last to update shared values.
  358. dwStatus = CSmLogQuery::SyncWithRegistry();
  359. ASSERT (dwStatus == ERROR_SUCCESS);
  360. return dwStatus;
  361. }
  362. BOOL
  363. CSmAlertQuery::GetLogTime ( PSLQ_TIME_INFO pTimeInfo, DWORD dwFlags )
  364. {
  365. BOOL bStatus;
  366. ASSERT ( ( SLQ_TT_TTYPE_START == dwFlags )
  367. || ( SLQ_TT_TTYPE_STOP == dwFlags )
  368. || ( SLQ_TT_TTYPE_RESTART == dwFlags )
  369. || ( SLQ_TT_TTYPE_SAMPLE == dwFlags ) );
  370. bStatus = CSmLogQuery::GetLogTime( pTimeInfo, dwFlags );
  371. return bStatus;
  372. }
  373. BOOL
  374. CSmAlertQuery::SetLogTime ( PSLQ_TIME_INFO pTimeInfo, const DWORD dwFlags )
  375. {
  376. BOOL bStatus;
  377. ASSERT ( ( SLQ_TT_TTYPE_START == dwFlags )
  378. || ( SLQ_TT_TTYPE_STOP == dwFlags )
  379. || ( SLQ_TT_TTYPE_RESTART == dwFlags )
  380. || ( SLQ_TT_TTYPE_SAMPLE == dwFlags ) );
  381. bStatus = CSmLogQuery::SetLogTime( pTimeInfo, dwFlags );
  382. return bStatus;
  383. }
  384. BOOL
  385. CSmAlertQuery::GetDefaultLogTime(SLQ_TIME_INFO& rTimeInfo, DWORD dwFlags )
  386. {
  387. ASSERT ( ( SLQ_TT_TTYPE_START == dwFlags )
  388. || ( SLQ_TT_TTYPE_STOP == dwFlags ) );
  389. rTimeInfo.wTimeType = (WORD)dwFlags;
  390. rTimeInfo.wDataType = SLQ_TT_DTYPE_DATETIME;
  391. if ( SLQ_TT_TTYPE_START == dwFlags ) {
  392. SYSTEMTIME stLocalTime;
  393. FILETIME ftLocalTime;
  394. // Milliseconds set to 0 for Schedule times
  395. GetLocalTime (&stLocalTime);
  396. stLocalTime.wMilliseconds = 0;
  397. SystemTimeToFileTime (&stLocalTime, &ftLocalTime);
  398. rTimeInfo.dwAutoMode = SLQ_AUTO_MODE_AT;
  399. rTimeInfo.llDateTime = *(LONGLONG *)&ftLocalTime;
  400. } else {
  401. // Default stop values
  402. rTimeInfo.dwAutoMode = SLQ_AUTO_MODE_NONE;
  403. rTimeInfo.llDateTime = MAX_TIME_VALUE;
  404. }
  405. return TRUE;
  406. }
  407. BOOL
  408. CSmAlertQuery::GetActionInfo( PALERT_ACTION_INFO pInfo, LPDWORD pdwInfoBufSize)
  409. {
  410. DWORD dwSizeRequired = sizeof (ALERT_ACTION_INFO);
  411. BOOL bReturn = FALSE;
  412. LPWSTR szNextString;
  413. // compute required size
  414. if (pdwInfoBufSize == NULL) {
  415. return FALSE;
  416. }
  417. if ( !mr_strNetName.IsEmpty() ) {
  418. dwSizeRequired += ( mr_strNetName.GetLength() + 1 ) * sizeof(TCHAR);
  419. }
  420. if ( !mr_strCmdFileName.IsEmpty() ) {
  421. dwSizeRequired += ( mr_strCmdFileName.GetLength() + 1 ) * sizeof(TCHAR);
  422. }
  423. if ( !mr_strCmdUserText.IsEmpty() ) {
  424. dwSizeRequired += ( mr_strCmdUserText.GetLength() + 1 ) * sizeof(TCHAR);
  425. }
  426. if ( !mr_strPerfLogName.IsEmpty() ) {
  427. dwSizeRequired += ( mr_strPerfLogName.GetLength() + 1 ) * sizeof(TCHAR);
  428. }
  429. if (dwSizeRequired <= *pdwInfoBufSize) {
  430. // clear the caller's buffer before we start filling it
  431. if (pInfo != NULL) {
  432. memset (pInfo, 0, *pdwInfoBufSize);
  433. pInfo->dwSize = dwSizeRequired;
  434. pInfo->dwActionFlags = mr_dwActionFlags;
  435. szNextString = (LPWSTR)&pInfo[1];
  436. if ( !mr_strNetName.IsEmpty() ) {
  437. pInfo->szNetName = szNextString;
  438. lstrcpyW(szNextString, mr_strNetName);
  439. szNextString += lstrlen(szNextString) + 1;
  440. }
  441. if ( !mr_strCmdFileName.IsEmpty() ) {
  442. pInfo->szCmdFilePath = szNextString;
  443. lstrcpyW(szNextString, mr_strCmdFileName);
  444. szNextString += lstrlen(szNextString) + 1;
  445. }
  446. if ( !mr_strCmdUserText.IsEmpty() ) {
  447. pInfo->szUserText = szNextString;
  448. lstrcpyW(szNextString, mr_strCmdUserText);
  449. szNextString += lstrlen(szNextString) + 1;
  450. }
  451. if ( !mr_strPerfLogName.IsEmpty() ) {
  452. pInfo->szLogName = szNextString;
  453. lstrcpyW(szNextString, mr_strPerfLogName);
  454. szNextString += lstrlen(szNextString) + 1;
  455. }
  456. bReturn = TRUE;
  457. }
  458. }
  459. *pdwInfoBufSize = dwSizeRequired;
  460. return bReturn;
  461. }
  462. DWORD
  463. CSmAlertQuery::SetActionInfo( PALERT_ACTION_INFO pInfo )
  464. {
  465. DWORD dwStatus = ERROR_SUCCESS;
  466. if (pInfo != NULL) {
  467. // Update action values with those from the structure
  468. MFC_TRY
  469. mr_dwActionFlags = pInfo->dwActionFlags;
  470. mr_strNetName.Empty();
  471. if ( NULL != pInfo->szNetName ) {
  472. mr_strNetName = pInfo->szNetName;
  473. }
  474. mr_strCmdFileName.Empty();
  475. if ( NULL != pInfo->szCmdFilePath ) {
  476. mr_strCmdFileName = pInfo->szCmdFilePath;
  477. }
  478. mr_strCmdUserText.Empty();
  479. if ( NULL != pInfo->szUserText ) {
  480. mr_strCmdUserText = pInfo->szUserText;
  481. }
  482. mr_strPerfLogName.Empty();
  483. if ( NULL != pInfo->szLogName ) {
  484. mr_strPerfLogName = pInfo->szLogName;
  485. }
  486. MFC_CATCH_DWSTATUS
  487. } else {
  488. dwStatus = ERROR_INVALID_PARAMETER;
  489. }
  490. // Todo: Handle return status
  491. return dwStatus;
  492. }
  493. //
  494. // Get first counter in counter list
  495. //
  496. LPCWSTR
  497. CSmAlertQuery::GetFirstCounter()
  498. {
  499. LPWSTR szReturn;
  500. szReturn = mr_szCounterList;
  501. if (szReturn != NULL) {
  502. if (*szReturn == 0) {
  503. // then it's an empty string
  504. szReturn = NULL;
  505. m_szNextCounter = NULL;
  506. } else {
  507. m_szNextCounter = szReturn + lstrlen(szReturn) + 1;
  508. if (*m_szNextCounter == 0) {
  509. // end of list reached so set pointer to NULL
  510. m_szNextCounter = NULL;
  511. }
  512. }
  513. } else {
  514. // no buffer allocated yet
  515. m_szNextCounter = NULL;
  516. }
  517. return (LPCWSTR)szReturn;
  518. }
  519. //
  520. // Get next counter in counter list
  521. // NULL pointer means no more counters in list
  522. //
  523. LPCWSTR
  524. CSmAlertQuery::GetNextCounter()
  525. {
  526. LPWSTR szReturn;
  527. szReturn = m_szNextCounter;
  528. if (m_szNextCounter != NULL) {
  529. m_szNextCounter += lstrlen(szReturn) + 1;
  530. if (*m_szNextCounter == 0) {
  531. // end of list reached so set pointer to NULL
  532. m_szNextCounter = NULL;
  533. }
  534. } else {
  535. // already at the end of the list so nothing to do
  536. }
  537. return (LPCWSTR)szReturn;
  538. }
  539. //
  540. // clear out the counter list
  541. //
  542. VOID
  543. CSmAlertQuery::ResetCounterList()
  544. {
  545. if (mr_szCounterList != NULL) {
  546. delete (mr_szCounterList);
  547. m_szNextCounter = NULL;
  548. mr_szCounterList = NULL;
  549. }
  550. m_dwCounterListLength = sizeof(WCHAR); // sizeof MSZ Null
  551. try {
  552. mr_szCounterList = new WCHAR [m_dwCounterListLength];
  553. mr_szCounterList[0] = 0;
  554. } catch ( ... ) {
  555. m_dwCounterListLength = 0;
  556. }
  557. }
  558. //
  559. // Add this counter string to the internal list
  560. //
  561. BOOL
  562. CSmAlertQuery::AddCounter(LPCWSTR szCounterPath)
  563. {
  564. DWORD dwNewSize;
  565. LPWSTR szNewString;
  566. LPWSTR szNextString;
  567. ASSERT (szCounterPath != NULL);
  568. if (szCounterPath == NULL) return FALSE;
  569. dwNewSize = lstrlen(szCounterPath) + 1;
  570. if (m_dwCounterListLength <= 2) {
  571. dwNewSize += 1; // add room for the MSZ null
  572. // then this is the first string to go in the list
  573. try {
  574. szNewString = new TCHAR [dwNewSize];
  575. } catch ( ... ) {
  576. return FALSE; // leave now
  577. }
  578. szNextString = szNewString;
  579. } else {
  580. dwNewSize += m_dwCounterListLength;
  581. // this is the nth string to go in the list
  582. try {
  583. szNewString = new TCHAR [dwNewSize];
  584. } catch ( ... ) {
  585. return FALSE; // leave now
  586. }
  587. memcpy (szNewString, mr_szCounterList,
  588. (m_dwCounterListLength * sizeof(TCHAR)));
  589. szNextString = szNewString;
  590. szNextString += m_dwCounterListLength - 1;
  591. }
  592. lstrcpyW (szNextString, szCounterPath);
  593. szNextString = szNewString;
  594. szNextString += dwNewSize - 1;
  595. *szNextString = 0; // MSZ Null
  596. if (mr_szCounterList != NULL) delete (mr_szCounterList);
  597. mr_szCounterList = szNewString;
  598. m_szNextCounter = szNewString;
  599. m_dwCounterListLength = dwNewSize;
  600. return TRUE;
  601. }
  602. DWORD
  603. CSmAlertQuery::GetLogType()
  604. {
  605. return ( SLQ_ALERT );
  606. }
  607. BOOL
  608. CSmAlertQuery::SetLogFileType ( const DWORD /* dwType */)
  609. {
  610. // No alert log file type
  611. return FALSE;
  612. }
  613. //
  614. // Get log file type and return as a string
  615. //
  616. //
  617. const CString&
  618. CSmAlertQuery::GetLogFileType ( )
  619. {
  620. return cstrEmpty;
  621. }
  622. void
  623. CSmAlertQuery::GetLogFileType ( DWORD& rdwFileType )
  624. {
  625. // Log file type should default in property bags.
  626. ASSERT ( FALSE );
  627. rdwFileType = ((DWORD)0xFFFFFFFF);
  628. return;
  629. }
  630. LPCWSTR
  631. CSmAlertQuery::GetCounterList( LPDWORD pcchListSize)
  632. {
  633. if (pcchListSize != NULL) *pcchListSize = m_dwCounterListLength;
  634. return mr_szCounterList;
  635. }
  636. BOOL CSmAlertQuery::SetCounterList( LPCWSTR mszCounterList, DWORD cchListSize)
  637. {
  638. BOOL bReturn = TRUE;
  639. if (mr_szCounterList != NULL) {
  640. delete (mr_szCounterList);
  641. mr_szCounterList = NULL;
  642. m_dwCounterListLength = 0;
  643. }
  644. try {
  645. mr_szCounterList = new TCHAR [cchListSize];
  646. memcpy (mr_szCounterList, mszCounterList, (cchListSize * sizeof(TCHAR)));
  647. m_dwCounterListLength = cchListSize;
  648. } catch ( ... ) {
  649. bReturn = FALSE;
  650. }
  651. return bReturn;
  652. }
  653. const CString&
  654. CSmAlertQuery::GetLogFileName( BOOL )
  655. {
  656. // 2000.1 return empty string so that empty string is written to HTML file for alerts.
  657. return cstrEmpty;
  658. }
  659. HRESULT
  660. CSmAlertQuery::LoadCountersFromPropertyBag (
  661. IPropertyBag* pPropBag,
  662. IErrorLog* pIErrorLog )
  663. {
  664. HRESULT hr = S_OK;
  665. PDH_STATUS pdhStatus;
  666. DWORD dwCount;
  667. DWORD dwIndex;
  668. CString strParamName;
  669. LPTSTR szLocaleBuf = NULL;
  670. DWORD dwLocaleBufSize = 0;
  671. LPTSTR pszPath;
  672. PALERT_INFO_BLOCK paibInfo = NULL;
  673. hr = DwordFromPropertyBag (
  674. pPropBag,
  675. pIErrorLog,
  676. IDS_HTML_SYSMON_COUNTERCOUNT,
  677. 0,
  678. dwCount);
  679. for ( dwIndex = 1; dwIndex <= dwCount; dwIndex++ ) {
  680. LPTSTR szCounterPath = NULL;
  681. DWORD dwBufSize = 0;
  682. DWORD dwByteCount = 0;
  683. DWORD dwOverUnder;
  684. DOUBLE dThreshold;
  685. LPTSTR pNewBuf;
  686. strParamName.Format ( IDS_HTML_SYSMON_COUNTERPATH, dwIndex );
  687. hr = StringFromPropertyBag (
  688. pPropBag,
  689. pIErrorLog,
  690. strParamName,
  691. L"",
  692. &szCounterPath,
  693. &dwBufSize );
  694. pszPath = szCounterPath;
  695. if (dwBufSize > sizeof(TCHAR)) {
  696. //
  697. // Initialize the locale path buffer
  698. //
  699. if (dwLocaleBufSize == 0) {
  700. dwLocaleBufSize = (MAX_PATH + 1) * sizeof(TCHAR);
  701. szLocaleBuf = (LPTSTR) G_ALLOC(dwLocaleBufSize);
  702. if (szLocaleBuf == NULL) {
  703. dwLocaleBufSize = 0;
  704. }
  705. }
  706. if (szLocaleBuf != NULL) {
  707. //
  708. // Translate counter name from English to Localization
  709. //
  710. dwBufSize = dwLocaleBufSize;
  711. pdhStatus = PdhTranslateLocaleCounter(
  712. szCounterPath,
  713. szLocaleBuf,
  714. &dwBufSize);
  715. if (pdhStatus == PDH_MORE_DATA) {
  716. pNewBuf = (LPTSTR) G_REALLOC(szLocaleBuf, dwBufSize);
  717. if (pNewBuf != NULL) {
  718. szLocaleBuf = pNewBuf;
  719. dwLocaleBufSize = dwBufSize;
  720. pdhStatus = PdhTranslateLocaleCounter(
  721. szCounterPath,
  722. szLocaleBuf,
  723. &dwBufSize);
  724. }
  725. }
  726. if (pdhStatus == ERROR_SUCCESS) {
  727. pszPath = szLocaleBuf;
  728. }
  729. }
  730. }
  731. strParamName.Format ( IDS_HTML_ALERT_OVER_UNDER, dwIndex );
  732. hr = DwordFromPropertyBag (
  733. pPropBag,
  734. pIErrorLog,
  735. strParamName,
  736. AIBF_UNDER,
  737. dwOverUnder);
  738. strParamName.Format ( IDS_HTML_ALERT_THRESHOLD, dwIndex );
  739. hr = DoubleFromPropertyBag (
  740. pPropBag,
  741. pIErrorLog,
  742. strParamName,
  743. ((DOUBLE)0.0),
  744. dThreshold);
  745. dwByteCount = sizeof (ALERT_INFO_BLOCK) + ((lstrlen(pszPath) + 3 + 20 + 1) * sizeof(TCHAR));
  746. MFC_TRY
  747. LPTSTR szString = NULL;
  748. paibInfo = (PALERT_INFO_BLOCK) new CHAR[dwByteCount];
  749. ZeroMemory ( paibInfo, dwByteCount );
  750. // 1 = size of "<"
  751. // 20 = size of threshold value
  752. // 1 = size of null terminator
  753. szString = new TCHAR[lstrlen(pszPath) + 3 + 20 + 1];
  754. paibInfo->dwSize = dwByteCount;
  755. paibInfo->szCounterPath = pszPath;
  756. paibInfo->dwFlags = dwOverUnder;
  757. paibInfo->dLimit = dThreshold;
  758. if ( MakeStringFromInfo( paibInfo, szString, &dwByteCount ) ) {
  759. AddCounter ( szString );
  760. }
  761. delete szString;
  762. MFC_CATCH_HR
  763. delete szCounterPath;
  764. delete paibInfo;
  765. }
  766. if (szLocaleBuf != NULL) {
  767. G_FREE(szLocaleBuf);
  768. }
  769. // Return good status regardless.
  770. return S_OK;
  771. }
  772. HRESULT
  773. CSmAlertQuery::LoadFromPropertyBag (
  774. IPropertyBag* pPropBag,
  775. IErrorLog* pIErrorLog )
  776. {
  777. HRESULT hr = S_OK;
  778. SLQ_TIME_INFO stiDefault;
  779. LPTSTR pszTemp = NULL;
  780. DWORD dwBufSize;
  781. // Continue even if error, using defaults for missing values.
  782. hr = LoadCountersFromPropertyBag ( pPropBag, pIErrorLog );
  783. stiDefault.wTimeType = SLQ_TT_TTYPE_SAMPLE;
  784. stiDefault.dwAutoMode = SLQ_AUTO_MODE_AFTER;
  785. stiDefault.wDataType = SLQ_TT_DTYPE_UNITS;
  786. stiDefault.dwUnitType = SLQ_TT_UTYPE_SECONDS;
  787. stiDefault.dwValue = 5;
  788. hr = SlqTimeFromPropertyBag (
  789. pPropBag,
  790. pIErrorLog,
  791. SLQ_TT_TTYPE_SAMPLE,
  792. &stiDefault,
  793. &mr_stiSampleInterval );
  794. mr_strCmdFileName.Empty();
  795. dwBufSize = 0;
  796. hr = StringFromPropertyBag (
  797. pPropBag,
  798. pIErrorLog,
  799. IDS_HTML_COMMAND_FILE,
  800. ALRT_DEFAULT_COMMAND_FILE,
  801. &pszTemp,
  802. &dwBufSize );
  803. if ( sizeof(TCHAR) < dwBufSize ) {
  804. ASSERT ( NULL != pszTemp );
  805. ASSERT ( 0 != * pszTemp );
  806. mr_strCmdFileName = pszTemp;
  807. }
  808. delete (pszTemp);
  809. pszTemp = NULL;
  810. mr_strNetName.Empty();
  811. dwBufSize = 0;
  812. hr = StringFromPropertyBag (
  813. pPropBag,
  814. pIErrorLog,
  815. IDS_HTML_NETWORK_NAME,
  816. ALRT_DEFAULT_NETWORK_NAME,
  817. &pszTemp,
  818. &dwBufSize );
  819. if ( sizeof(TCHAR) < dwBufSize ) {
  820. ASSERT ( NULL != pszTemp );
  821. ASSERT ( 0 != * pszTemp );
  822. mr_strNetName = pszTemp;
  823. }
  824. delete (pszTemp);
  825. pszTemp = NULL;
  826. mr_strCmdUserText.Empty();
  827. dwBufSize = 0;
  828. hr = StringFromPropertyBag (
  829. pPropBag,
  830. pIErrorLog,
  831. IDS_HTML_USER_TEXT,
  832. ALRT_DEFAULT_USER_TEXT,
  833. &pszTemp,
  834. &dwBufSize );
  835. if ( sizeof(TCHAR) < dwBufSize ) {
  836. ASSERT ( NULL != pszTemp );
  837. ASSERT ( 0 != * pszTemp );
  838. mr_strCmdUserText = pszTemp;
  839. }
  840. delete (pszTemp);
  841. pszTemp = NULL;
  842. mr_strPerfLogName.Empty();
  843. dwBufSize = 0;
  844. hr = StringFromPropertyBag (
  845. pPropBag,
  846. pIErrorLog,
  847. IDS_HTML_PERF_LOG_NAME,
  848. ALRT_DEFAULT_PERF_LOG_NAME,
  849. &pszTemp,
  850. &dwBufSize );
  851. if ( sizeof(TCHAR) < dwBufSize ) {
  852. ASSERT ( NULL != pszTemp );
  853. ASSERT ( 0 != * pszTemp );
  854. mr_strPerfLogName = pszTemp;
  855. }
  856. delete (pszTemp);
  857. pszTemp = NULL;
  858. hr = DwordFromPropertyBag (
  859. pPropBag,
  860. pIErrorLog,
  861. IDS_HTML_ACTION_FLAGS,
  862. ALRT_DEFAULT_ACTION,
  863. mr_dwActionFlags);
  864. hr = CSmLogQuery::LoadFromPropertyBag( pPropBag, pIErrorLog );
  865. return hr;
  866. }
  867. HRESULT
  868. CSmAlertQuery::SaveCountersToPropertyBag (
  869. IPropertyBag* pPropBag )
  870. {
  871. HRESULT hr = NOERROR;
  872. LPCTSTR szString;
  873. CString strParamName;
  874. DWORD dwIndex = 0;
  875. LPTSTR szEnglishBuf = NULL;
  876. DWORD dwEnglishBufSize = 0;
  877. LPTSTR pszPath = NULL;
  878. PDH_STATUS pdhStatus;
  879. PALERT_INFO_BLOCK paibInfo = NULL;
  880. szString = GetFirstCounter();
  881. // Todo: Stop processing on failure?
  882. while ( NULL != szString ) {
  883. LPTSTR pNewBuf;
  884. DWORD dwBufSize;
  885. dwBufSize = sizeof (ALERT_INFO_BLOCK) + (lstrlen(szString) + 1) * sizeof(TCHAR);
  886. MFC_TRY
  887. paibInfo = (PALERT_INFO_BLOCK) new CHAR[dwBufSize];
  888. if ( MakeInfoFromString( szString, paibInfo, &dwBufSize ) ) {
  889. dwIndex++;
  890. strParamName.Format ( IDS_HTML_SYSMON_COUNTERPATH, dwIndex );
  891. pszPath = paibInfo->szCounterPath;
  892. //
  893. // Initialize the locale path buffer
  894. //
  895. if (dwEnglishBufSize == 0) {
  896. dwEnglishBufSize = (MAX_PATH + 1) * sizeof(TCHAR);
  897. szEnglishBuf = (LPTSTR) G_ALLOC(dwEnglishBufSize);
  898. if (szEnglishBuf == NULL) {
  899. dwEnglishBufSize = 0;
  900. }
  901. }
  902. if (szEnglishBuf != NULL) {
  903. //
  904. // Translate counter name from Localization into English
  905. //
  906. dwBufSize = dwEnglishBufSize;
  907. pdhStatus = PdhTranslate009Counter(
  908. paibInfo->szCounterPath,
  909. szEnglishBuf,
  910. &dwBufSize);
  911. if (pdhStatus == PDH_MORE_DATA) {
  912. pNewBuf = (LPTSTR)G_REALLOC(szEnglishBuf, dwBufSize);
  913. if (pNewBuf != NULL) {
  914. szEnglishBuf = pNewBuf;
  915. dwEnglishBufSize = dwBufSize;
  916. pdhStatus = PdhTranslate009Counter(
  917. paibInfo->szCounterPath,
  918. szEnglishBuf,
  919. &dwBufSize);
  920. }
  921. }
  922. if (pdhStatus == ERROR_SUCCESS) {
  923. pszPath = szEnglishBuf;
  924. }
  925. }
  926. //
  927. // Passing sz. ( TCHAR[n] ) causes memory alloc, which might throw an exception
  928. //
  929. hr = StringToPropertyBag ( pPropBag, strParamName, pszPath);
  930. strParamName.Format ( IDS_HTML_ALERT_OVER_UNDER, dwIndex );
  931. hr = DwordToPropertyBag ( pPropBag, strParamName, paibInfo->dwFlags );
  932. strParamName.Format ( IDS_HTML_ALERT_THRESHOLD, dwIndex );
  933. hr = DoubleToPropertyBag ( pPropBag, strParamName, paibInfo->dLimit );
  934. }
  935. MFC_CATCH_HR
  936. if ( NULL != paibInfo ) {
  937. delete paibInfo;
  938. paibInfo = NULL;
  939. }
  940. szString = GetNextCounter();
  941. }
  942. hr = DwordToPropertyBag ( pPropBag, IDS_HTML_SYSMON_COUNTERCOUNT, dwIndex );
  943. if (szEnglishBuf != NULL) {
  944. G_FREE(szEnglishBuf);
  945. }
  946. // Todo: Caller handle error
  947. return hr;
  948. }
  949. HRESULT
  950. CSmAlertQuery::SaveToPropertyBag (
  951. IPropertyBag* pPropBag,
  952. BOOL fSaveAllProps )
  953. {
  954. HRESULT hr = NOERROR;
  955. hr = SaveCountersToPropertyBag ( pPropBag );
  956. hr = SlqTimeToPropertyBag ( pPropBag, SLQ_TT_TTYPE_SAMPLE, &mr_stiSampleInterval );
  957. hr = StringToPropertyBag ( pPropBag, IDS_HTML_COMMAND_FILE, mr_strCmdFileName );
  958. hr = StringToPropertyBag ( pPropBag, IDS_HTML_NETWORK_NAME, mr_strNetName );
  959. hr = StringToPropertyBag ( pPropBag, IDS_HTML_USER_TEXT, mr_strCmdUserText );
  960. hr = StringToPropertyBag ( pPropBag, IDS_HTML_PERF_LOG_NAME, mr_strPerfLogName );
  961. hr = DwordToPropertyBag ( pPropBag, IDS_HTML_ACTION_FLAGS, mr_dwActionFlags );
  962. hr = CSmLogQuery::SaveToPropertyBag( pPropBag, fSaveAllProps );
  963. return hr;
  964. }
  965. HRESULT
  966. CSmAlertQuery::TranslateMSZAlertCounterList(
  967. LPTSTR pszCounterList,
  968. LPTSTR pBuffer,
  969. LPDWORD pdwBufferSize,
  970. BOOL bFlag
  971. )
  972. {
  973. LPTSTR pTmpBuf = NULL;
  974. DWORD dwTmpBufSize = 0;
  975. DWORD dwSize = 0;
  976. LPTSTR pNewBuf = NULL;
  977. LPTSTR pOriginPath = NULL;
  978. LPTSTR pszCounterPathToAdd = NULL;
  979. LPTSTR pNextStringPosition = NULL;
  980. BOOL bNotEnoughBuffer = FALSE;
  981. DWORD dwNewCounterListLen = 0;
  982. DWORD dwCounterPathLen = 0;
  983. PDH_STATUS Status = ERROR_SUCCESS;
  984. LPTSTR pData = NULL;
  985. LPTSTR pszBackupPath = NULL;
  986. int nBackupLen = 0;
  987. if (pszCounterList == NULL || pdwBufferSize == NULL) {
  988. Status = ERROR_INVALID_PARAMETER;
  989. goto ErrorOut;
  990. }
  991. if (pBuffer == NULL || *pdwBufferSize == 0) {
  992. bNotEnoughBuffer = TRUE;
  993. }
  994. //
  995. // Probe parameters
  996. //
  997. __try {
  998. if (* pdwBufferSize != 0 && pBuffer != NULL) {
  999. *pBuffer = 0;
  1000. * (LPTSTR) ( ((LPBYTE) pBuffer)
  1001. + ((* pdwBufferSize) - sizeof(*pBuffer)) ) = 0;
  1002. }
  1003. pOriginPath = pszCounterList;
  1004. while (*pOriginPath) {
  1005. //
  1006. // Locate the position where the data description begins
  1007. //
  1008. pData = pOriginPath;
  1009. while (*pData != _T('\0') && *pData != _T('<') && *pData != _T('>')) {
  1010. pData++;
  1011. }
  1012. //
  1013. // Backup the counter path
  1014. //
  1015. //
  1016. if (pszBackupPath == NULL) {
  1017. nBackupLen = MAX_PATH + 1;
  1018. pszBackupPath = (LPTSTR) G_ALLOC(nBackupLen * sizeof(TCHAR));
  1019. if (pszBackupPath == NULL) {
  1020. Status = ERROR_OUTOFMEMORY;
  1021. goto ErrorOut;
  1022. }
  1023. }
  1024. if (lstrlen(pOriginPath) + 1 > nBackupLen) {
  1025. nBackupLen = lstrlen(pOriginPath) + 1;
  1026. pNewBuf = (LPTSTR) G_REALLOC(pszBackupPath, nBackupLen * sizeof(TCHAR) );
  1027. if (pNewBuf == NULL) {
  1028. Status = ERROR_OUTOFMEMORY;
  1029. goto ErrorOut;
  1030. }
  1031. pszBackupPath = pNewBuf;
  1032. }
  1033. lstrcpyn(pszBackupPath, pOriginPath, (int)(pData - pOriginPath + 1));
  1034. pszCounterPathToAdd = pszBackupPath;
  1035. //
  1036. // Initialize the buffer used for translating counter path
  1037. // called only once
  1038. //
  1039. if (pTmpBuf == NULL) {
  1040. dwTmpBufSize = (MAX_PATH + 1) * sizeof(TCHAR);
  1041. pTmpBuf = (LPTSTR) G_ALLOC(dwTmpBufSize);
  1042. if (pTmpBuf == NULL) {
  1043. dwTmpBufSize = 0;
  1044. }
  1045. }
  1046. if (pTmpBuf != NULL) {
  1047. dwSize = dwTmpBufSize;
  1048. if (bFlag) {
  1049. Status = PdhTranslateLocaleCounter(
  1050. pszBackupPath,
  1051. pTmpBuf,
  1052. &dwSize);
  1053. }
  1054. else {
  1055. Status = PdhTranslate009Counter(
  1056. pszBackupPath,
  1057. pTmpBuf,
  1058. &dwSize);
  1059. }
  1060. if (Status == PDH_MORE_DATA) {
  1061. pNewBuf = (LPTSTR) G_REALLOC(pTmpBuf, dwSize);
  1062. if (pNewBuf == NULL) {
  1063. Status = ERROR_OUTOFMEMORY;
  1064. goto ErrorOut;
  1065. }
  1066. pTmpBuf = pNewBuf;
  1067. dwTmpBufSize = dwSize;
  1068. //
  1069. // Try second time
  1070. //
  1071. if (bFlag) {
  1072. Status = PdhTranslateLocaleCounter(
  1073. pszBackupPath,
  1074. pTmpBuf,
  1075. &dwSize);
  1076. }
  1077. else {
  1078. Status = PdhTranslate009Counter(
  1079. pszBackupPath,
  1080. pTmpBuf,
  1081. &dwSize);
  1082. }
  1083. }
  1084. if (Status == ERROR_SUCCESS) {
  1085. pszCounterPathToAdd = pTmpBuf;
  1086. }
  1087. }
  1088. //
  1089. // Add the translated counter path(it is the original
  1090. // counter path if translation failed) to the new counter
  1091. // path list
  1092. //
  1093. dwCounterPathLen = lstrlen(pszCounterPathToAdd) + 1;
  1094. dwNewCounterListLen += dwCounterPathLen;
  1095. if (! bNotEnoughBuffer) {
  1096. if ( (dwNewCounterListLen + lstrlen(pData) + 1) * sizeof(TCHAR) <= *pdwBufferSize) {
  1097. //
  1098. // Set up the copy position
  1099. //
  1100. pNextStringPosition = pBuffer + dwNewCounterListLen - dwCounterPathLen;
  1101. lstrcpy(pNextStringPosition, pszCounterPathToAdd);
  1102. lstrcat(pNextStringPosition, pData);
  1103. }
  1104. else {
  1105. bNotEnoughBuffer = TRUE;
  1106. }
  1107. }
  1108. dwNewCounterListLen += lstrlen(pData);
  1109. //
  1110. // Continue processing next counter path
  1111. //
  1112. pOriginPath += lstrlen(pOriginPath) + 1;
  1113. }
  1114. dwNewCounterListLen ++;
  1115. if (! bNotEnoughBuffer) {
  1116. //
  1117. // Append the terminating 0
  1118. //
  1119. pBuffer[dwNewCounterListLen - 1] = _T('\0');
  1120. }
  1121. else {
  1122. Status = ERROR_NOT_ENOUGH_MEMORY;
  1123. }
  1124. *pdwBufferSize = dwNewCounterListLen * sizeof(TCHAR);
  1125. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1126. Status = ERROR_INVALID_PARAMETER;
  1127. }
  1128. ErrorOut:
  1129. if (pszBackupPath != NULL) {
  1130. G_FREE(pszBackupPath);
  1131. }
  1132. if (pTmpBuf != NULL) {
  1133. G_FREE(pTmpBuf);
  1134. }
  1135. return Status;
  1136. }