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.

1910 lines
65 KiB

  1. /*++
  2. Copyright (C) 1996-1999 Microsoft Corporation
  3. Module Name:
  4. srcprop.cpp
  5. Abstract:
  6. Implementation of the source property page.
  7. --*/
  8. #include "polyline.h"
  9. #include <limits.h>
  10. #include <strsafe.h>
  11. #include <assert.h>
  12. #include <sql.h>
  13. #include <pdhmsg.h>
  14. #include <pdhp.h>
  15. #include "utils.h"
  16. #include "smonmsg.h"
  17. #include "unihelpr.h"
  18. #include "winhelpr.h"
  19. #include "odbcinst.h"
  20. #include "smonid.h"
  21. #include "srcprop.h"
  22. CSourcePropPage::CSourcePropPage()
  23. : m_pTimeRange ( NULL ),
  24. m_eDataSourceType ( sysmonCurrentActivity ),
  25. m_hDataSource(H_REALTIME_DATASOURCE),
  26. m_pInfoDeleted ( NULL ),
  27. m_bLogFileChg ( FALSE ),
  28. m_bSqlDsnChg ( FALSE ),
  29. m_bSqlLogSetChg ( FALSE ),
  30. m_bRangeChg ( FALSE ),
  31. m_bDataSourceChg ( FALSE )
  32. {
  33. m_uIDDialog = IDD_SRC_PROPP_DLG;
  34. m_uIDTitle = IDS_SRC_PROPP_TITLE;
  35. m_szSqlDsnName[0] = L'\0';
  36. m_szSqlLogSetName[0] = L'\0';
  37. }
  38. CSourcePropPage::~CSourcePropPage(
  39. void
  40. )
  41. {
  42. return;
  43. }
  44. /*
  45. * CSourcePropPage::Init
  46. *
  47. * Purpose:
  48. * Performs initialization operations that might fail.
  49. *
  50. * Parameters:
  51. * None
  52. *
  53. * Return Value:
  54. * BOOL TRUE if initialization successful, FALSE
  55. * otherwise.
  56. */
  57. BOOL
  58. CSourcePropPage::Init(void)
  59. {
  60. BOOL bResult;
  61. bResult = RegisterTimeRangeClass();
  62. return bResult;
  63. }
  64. BOOL
  65. CSourcePropPage::InitControls ( void )
  66. {
  67. BOOL bResult = FALSE;
  68. HWND hwndTimeRange;
  69. // create time range object attached to dialog control
  70. hwndTimeRange = GetDlgItem(m_hDlg, IDC_TIMERANGE);
  71. if ( NULL != hwndTimeRange ) {
  72. m_pTimeRange = new CTimeRange(hwndTimeRange);
  73. if (m_pTimeRange) {
  74. bResult = m_pTimeRange->Init();
  75. if ( FALSE == bResult ) {
  76. delete m_pTimeRange;
  77. m_pTimeRange = NULL;
  78. }
  79. }
  80. }
  81. return bResult;
  82. }
  83. void
  84. CSourcePropPage::DeinitControls ( void )
  85. {
  86. HWND hwndLogFileList = NULL;
  87. INT iIndex;
  88. INT iLogFileCnt = 0;;
  89. PLogItemInfo pInfo = NULL;
  90. ISystemMonitor *pObj;
  91. CImpISystemMonitor *pPrivObj;
  92. pObj = m_ppISysmon[0];
  93. pPrivObj = (CImpISystemMonitor*)pObj;
  94. // Hide the log view start and stop bars on the graph
  95. pPrivObj->SetLogViewTempRange( MIN_TIME_VALUE, MAX_TIME_VALUE );
  96. // delete time range object attached to dialog control
  97. if (m_pTimeRange != NULL) {
  98. delete m_pTimeRange;
  99. m_pTimeRange = NULL;
  100. }
  101. hwndLogFileList = DialogControl(m_hDlg, IDC_LIST_LOGFILENAME);
  102. if ( NULL != hwndLogFileList ) {
  103. iLogFileCnt = LBNumItems(hwndLogFileList);
  104. for (iIndex = 0; iIndex < iLogFileCnt; iIndex++ ) {
  105. pInfo = (PLogItemInfo)LBData(hwndLogFileList,iIndex);
  106. if ( NULL != pInfo ) {
  107. if ( NULL != pInfo->pItem ) {
  108. pInfo->pItem->Release();
  109. }
  110. if (NULL != pInfo->pszPath ) {
  111. delete [] pInfo->pszPath;
  112. }
  113. delete pInfo;
  114. }
  115. }
  116. }
  117. return;
  118. }
  119. /*
  120. * CSourcePropPage::GetProperties
  121. *
  122. */
  123. BOOL CSourcePropPage::GetProperties(void)
  124. {
  125. BOOL bReturn = TRUE;
  126. DWORD dwStatus = ERROR_SUCCESS;
  127. ISystemMonitor *pObj = NULL;
  128. CImpISystemMonitor *pPrivObj = NULL;
  129. BSTR bstrPath;
  130. DATE date;
  131. LPWSTR szLogFileList = NULL;
  132. ULONG ulLogListBufLen = 0;
  133. BOOL bIsValidLogFile = FALSE;
  134. BOOL bIsValidLogFileRange = TRUE;
  135. ILogFileItem *pItem = NULL;
  136. PLogItemInfo pInfo = NULL;
  137. BSTR bstrTemp = NULL;
  138. INT iLogFile = 0;
  139. INT iIndex = 0;
  140. INT nChar = 0;
  141. if (m_cObjects == 0) {
  142. bReturn = FALSE;
  143. } else {
  144. pObj = m_ppISysmon[0];
  145. // Get pointer to actual object for internal methods
  146. pPrivObj = (CImpISystemMonitor*)pObj;
  147. }
  148. if ( NULL == pObj || NULL == pPrivObj ) {
  149. bReturn = FALSE;
  150. } else {
  151. // Set the data source type
  152. pObj->get_DataSourceType (&m_eDataSourceType);
  153. CheckRadioButton(
  154. m_hDlg, IDC_SRC_REALTIME, IDC_SRC_SQL,
  155. IDC_SRC_REALTIME + m_eDataSourceType - 1);
  156. SetSourceControlStates();
  157. while (SUCCEEDED(pPrivObj->LogFile(iLogFile, &pItem))) {
  158. // Create LogItemInfo to hold the log file item and path
  159. pInfo = new LogItemInfo;
  160. if ( NULL == pInfo ) {
  161. bReturn = FALSE;
  162. break;
  163. }
  164. ZeroMemory ( pInfo, sizeof(LogItemInfo) );
  165. pInfo->pItem = pItem;
  166. if ( FAILED ( pItem->get_Path( &bstrPath ) ) ) {
  167. bReturn = FALSE;
  168. delete pInfo;
  169. break;
  170. } else {
  171. nChar = lstrlen(bstrPath) + 1;
  172. pInfo->pszPath = new WCHAR [nChar];
  173. if ( NULL == pInfo->pszPath ) {
  174. delete pInfo;
  175. SysFreeString(bstrPath);
  176. bReturn = FALSE;
  177. break;
  178. }
  179. StringCchCopy(pInfo->pszPath, nChar, bstrPath);
  180. SysFreeString(bstrPath);
  181. }
  182. // Add the log file name to the list box
  183. iIndex = AddItemToFileListBox(pInfo);
  184. if ( LB_ERR == iIndex ) {
  185. bReturn = FALSE;
  186. delete [] pInfo->pszPath;
  187. delete pInfo;
  188. break;
  189. }
  190. iLogFile++;
  191. }
  192. // Get SQL DSN name, populate list box.
  193. pObj->get_SqlDsnName(&bstrTemp);
  194. memset ( m_szSqlDsnName, 0, sizeof (m_szSqlDsnName) );
  195. if ( NULL != bstrTemp ) {
  196. if ( bstrTemp[0] != L'\0' ) {
  197. lstrcpyn (
  198. m_szSqlDsnName,
  199. bstrTemp, min(SQL_MAX_DSN_LENGTH + 1, lstrlen (bstrTemp)+1) );
  200. }
  201. SysFreeString (bstrTemp);
  202. bstrTemp = NULL;
  203. }
  204. InitSqlDsnList();
  205. // Get SQL log set name, populate list box.
  206. pObj->get_SqlLogSetName(&bstrTemp);
  207. memset ( m_szSqlLogSetName, 0, sizeof (m_szSqlLogSetName) );
  208. if ( NULL != bstrTemp ) {
  209. if ( bstrTemp[0] != L'\0' ) {
  210. lstrcpyn (
  211. m_szSqlLogSetName,
  212. bstrTemp, min(SLQ_MAX_LOG_SET_NAME_LEN+1, lstrlen (bstrTemp)+1) );
  213. }
  214. SysFreeString (bstrTemp);
  215. }
  216. InitSqlLogSetList();
  217. if ( m_eDataSourceType == sysmonLogFiles
  218. || m_eDataSourceType == sysmonSqlLog) {
  219. pPrivObj->GetLogFileRange(&m_llBegin, &m_llEnd);
  220. m_pTimeRange->SetBeginEnd(m_llBegin, m_llEnd);
  221. pObj->get_LogViewStart(&date);
  222. VariantDateToLLTime(date, &m_llStart);
  223. pObj->get_LogViewStop(&date);
  224. VariantDateToLLTime(date, &m_llStop);
  225. m_pTimeRange->SetStartStop(m_llStart, m_llStop);
  226. // OpenLogFile sets BeginEnd, StartStop values in the
  227. // time range control, if the file and range are valid.
  228. dwStatus = OpenLogFile ();
  229. if ( ERROR_SUCCESS == dwStatus ) {
  230. bIsValidLogFile = TRUE;
  231. bIsValidLogFileRange = TRUE;
  232. } else {
  233. bIsValidLogFile = FALSE;
  234. bIsValidLogFileRange = FALSE;
  235. m_llStart = MIN_TIME_VALUE;
  236. m_llStop = MAX_TIME_VALUE;
  237. if ( sysmonLogFiles == m_eDataSourceType ) {
  238. BuildLogFileList ( m_hDlg, NULL, &ulLogListBufLen );
  239. szLogFileList = new WCHAR[ulLogListBufLen];
  240. if ( NULL != szLogFileList ) {
  241. BuildLogFileList ( m_hDlg, szLogFileList, &ulLogListBufLen );
  242. }
  243. }
  244. if ( NULL != szLogFileList || sysmonSqlLog == m_eDataSourceType ) {
  245. DisplayDataSourceError (
  246. m_hDlg,
  247. dwStatus,
  248. m_eDataSourceType,
  249. szLogFileList,
  250. m_szSqlDsnName,
  251. m_szSqlLogSetName );
  252. if ( NULL != szLogFileList ) {
  253. delete [] szLogFileList;
  254. szLogFileList = NULL;
  255. ulLogListBufLen = 0;
  256. }
  257. }
  258. }
  259. } else {
  260. bIsValidLogFile = FALSE;
  261. bIsValidLogFileRange = FALSE;
  262. m_llStart = MIN_TIME_VALUE;
  263. m_llStop = MAX_TIME_VALUE;
  264. }
  265. // Set the start and stop time bars invisible or not, depending on time range
  266. pPrivObj->SetLogViewTempRange( m_llStart, m_llStop );
  267. SetTimeRangeCtrlState ( bIsValidLogFile, bIsValidLogFileRange );
  268. // Clear change flags
  269. m_bInitialTimeRangePending = !bIsValidLogFileRange;
  270. m_bLogFileChg = FALSE;
  271. m_bSqlDsnChg = FALSE;
  272. m_bSqlLogSetChg = FALSE;
  273. m_bRangeChg = FALSE;
  274. m_bDataSourceChg = FALSE;
  275. bReturn = TRUE;
  276. }
  277. return bReturn;
  278. }
  279. /*
  280. * CSourcePropPage::SetProperties
  281. *
  282. */
  283. BOOL CSourcePropPage::SetProperties(void)
  284. {
  285. ISystemMonitor* pObj = NULL;
  286. CImpISystemMonitor* pPrivObj = NULL;
  287. BOOL bIsValidLogFile = TRUE;
  288. BOOL bIsValidLogFileRange = TRUE;
  289. DWORD dwStatus = ERROR_SUCCESS;
  290. LPWSTR szLogFileList = NULL;
  291. ULONG ulLogListBufLen = 0;
  292. PLogItemInfo pInfo = NULL;
  293. PLogItemInfo pInfoNext = NULL;
  294. DATE date;
  295. BOOL bReturn = TRUE;
  296. HWND hwndLogFileList = NULL;
  297. INT iLogFileCnt = 0;
  298. INT i;
  299. UINT uiMessage = 0;
  300. HRESULT hr = NOERROR;
  301. BOOL bNewFileIsValid = TRUE;
  302. BSTR bstrTemp = NULL;
  303. USES_CONVERSION
  304. hwndLogFileList = DialogControl(m_hDlg, IDC_LIST_LOGFILENAME);
  305. if ( 0 != m_cObjects ) {
  306. pObj = m_ppISysmon[0];
  307. // Get pointer to actual object for internal methods
  308. pPrivObj = (CImpISystemMonitor*)pObj;
  309. }
  310. if (pObj == NULL || pPrivObj == NULL) {
  311. return FALSE;
  312. }
  313. if ( NULL != hwndLogFileList) {
  314. iLogFileCnt = LBNumItems(hwndLogFileList);
  315. // Validate properties
  316. if (m_eDataSourceType == sysmonLogFiles ) {
  317. if ( 0 == iLogFileCnt ) {
  318. uiMessage = IDS_NOLOGFILE_ERR;
  319. } else {
  320. // Check validity of existing files.
  321. // LogFilesAreValid displays any errors.
  322. LogFilesAreValid ( NULL, bNewFileIsValid, bReturn );
  323. }
  324. } else if ( m_eDataSourceType == sysmonSqlLog ){
  325. if ( L'\0' == m_szSqlDsnName[0] ) {
  326. uiMessage = IDS_NO_SQL_DSN_ERR;
  327. } else if ( L'\0' == m_szSqlLogSetName[0] ) {
  328. uiMessage = IDS_NO_SQL_LOG_SET_ERR;
  329. }
  330. }
  331. if ( 0 != uiMessage ) {
  332. MessageBox(m_hDlg, ResourceString(uiMessage), ResourceString(IDS_APP_NAME), MB_OK | MB_ICONEXCLAMATION);
  333. bReturn = FALSE;
  334. }
  335. if ( !bReturn ) {
  336. bIsValidLogFile = FALSE;
  337. // Todo: Set log file time range?
  338. }
  339. if ( m_eDataSourceType == sysmonLogFiles
  340. || m_eDataSourceType == sysmonSqlLog) {
  341. if ( bReturn && m_bInitialTimeRangePending ) {
  342. // If log file or SQL specified, but range has not been determined
  343. // Try to open it now and get the range
  344. dwStatus = OpenLogFile();
  345. if ( ERROR_SUCCESS == dwStatus ) {
  346. bIsValidLogFile = TRUE;
  347. bIsValidLogFileRange = TRUE;
  348. m_bInitialTimeRangePending = FALSE;
  349. } else {
  350. bReturn = FALSE;
  351. bIsValidLogFile = FALSE;
  352. bIsValidLogFileRange = FALSE;
  353. m_llStart = MIN_TIME_VALUE;
  354. m_llStop = MAX_TIME_VALUE;
  355. if ( sysmonLogFiles == m_eDataSourceType ) {
  356. BuildLogFileList ( m_hDlg, NULL, &ulLogListBufLen );
  357. szLogFileList = (LPWSTR) new WCHAR [ulLogListBufLen];
  358. if ( NULL != szLogFileList ) {
  359. BuildLogFileList ( m_hDlg, szLogFileList, &ulLogListBufLen );
  360. }
  361. }
  362. if ( NULL != szLogFileList || sysmonSqlLog == m_eDataSourceType ) {
  363. DisplayDataSourceError (
  364. m_hDlg,
  365. dwStatus,
  366. m_eDataSourceType,
  367. szLogFileList,
  368. m_szSqlDsnName,
  369. m_szSqlLogSetName );
  370. if ( NULL != szLogFileList ) {
  371. delete [] szLogFileList;
  372. szLogFileList = NULL;
  373. ulLogListBufLen = 0;
  374. }
  375. }
  376. }
  377. }
  378. // Set the start and stop time bars invisible or not, depending on time range
  379. pPrivObj->SetLogViewTempRange( m_llStart, m_llStop );
  380. SetTimeRangeCtrlState ( bIsValidLogFile, bIsValidLogFileRange );
  381. }
  382. }
  383. // Remove all deleted log files from the control.
  384. // Get first object
  385. if ( bReturn ) {
  386. if (m_bLogFileChg || m_bSqlDsnChg || m_bSqlLogSetChg ) {
  387. // Always set the log source to null data source before modifying the log file list
  388. // or database fields.
  389. // TodoLogFiles: This can leave the user with state different than before, in the
  390. // case of log file load failure.
  391. pObj->put_DataSourceType ( sysmonNullDataSource );
  392. m_bDataSourceChg = TRUE;
  393. }
  394. if ( m_bSqlDsnChg) {
  395. bstrTemp = SysAllocString(m_szSqlDsnName);
  396. if ( NULL != bstrTemp ) {
  397. hr = pObj->put_SqlDsnName(bstrTemp);
  398. } else {
  399. hr = E_OUTOFMEMORY;
  400. }
  401. SysFreeString (bstrTemp);
  402. bstrTemp = NULL;
  403. bReturn = SUCCEEDED ( hr );
  404. }
  405. if ( bReturn && m_bSqlLogSetChg) {
  406. bstrTemp = SysAllocString(m_szSqlLogSetName);
  407. if ( NULL != bstrTemp ) {
  408. hr = pObj->put_SqlLogSetName(bstrTemp);
  409. } else {
  410. hr = E_OUTOFMEMORY;
  411. }
  412. SysFreeString (bstrTemp);
  413. bstrTemp = NULL;
  414. bReturn = SUCCEEDED ( hr );
  415. }
  416. if (m_bLogFileChg) {
  417. // Remove all items in the delete list from the control.
  418. pInfo = m_pInfoDeleted;
  419. while ( NULL != pInfo ) {
  420. // If this counter exists in the control
  421. if ( NULL != pInfo->pItem ) {
  422. // Tell control to remove it
  423. // Always set the log source to CurrentActivity before modifying the log file list.
  424. pPrivObj->DeleteLogFile(pInfo->pItem);
  425. // Release the local reference
  426. pInfo->pItem->Release();
  427. }
  428. // Free the path string
  429. delete [] pInfo->pszPath;
  430. // Delete the Info structure and point to the next one
  431. pInfoNext = pInfo->pNextInfo;
  432. delete pInfo;
  433. pInfo = pInfoNext;
  434. }
  435. m_pInfoDeleted = NULL;
  436. // For each item
  437. for (i=0; i<iLogFileCnt; i++) {
  438. pInfo = (PLogItemInfo)LBData(hwndLogFileList,i);
  439. // If new item, create it now
  440. if (pInfo->pItem == NULL) {
  441. // The following code inits the pItem field of pInfo.
  442. bstrTemp = SysAllocString(pInfo->pszPath);
  443. if ( NULL != bstrTemp ) {
  444. hr = pPrivObj->AddLogFile(bstrTemp, &pInfo->pItem);
  445. SysFreeString (bstrTemp);
  446. bstrTemp = NULL;
  447. } else {
  448. hr = E_OUTOFMEMORY;
  449. }
  450. }
  451. if ( FAILED ( hr) ) {
  452. break;
  453. }
  454. }
  455. bReturn = SUCCEEDED ( hr );
  456. }
  457. if ( bReturn && m_bDataSourceChg ) {
  458. // This covers CurrentActivity as well as log files, database
  459. hr = pObj->put_DataSourceType(m_eDataSourceType);
  460. bReturn = SUCCEEDED ( hr );
  461. if ( SUCCEEDED ( hr ) ) {
  462. m_bDataSourceChg = FALSE;
  463. m_bLogFileChg = FALSE;
  464. m_bSqlDsnChg = FALSE;
  465. m_bSqlLogSetChg = FALSE;
  466. } else {
  467. if ( sysmonLogFiles == m_eDataSourceType
  468. || sysmonSqlLog == m_eDataSourceType ) {
  469. // Display error messages, then retry in
  470. // Current Activity data source type.
  471. // TodoLogFiles: Message re: data source set to CurrentActivity if
  472. // put_DataSourceType failed.
  473. if ( sysmonLogFiles == m_eDataSourceType ) {
  474. BuildLogFileList ( m_hDlg, NULL, &ulLogListBufLen );
  475. szLogFileList = new WCHAR [ulLogListBufLen];
  476. if ( NULL != szLogFileList ) {
  477. BuildLogFileList ( m_hDlg, szLogFileList, &ulLogListBufLen );
  478. }
  479. }
  480. if ( NULL != szLogFileList || sysmonSqlLog == m_eDataSourceType ) {
  481. DisplayDataSourceError (
  482. m_hDlg,
  483. (DWORD)hr,
  484. m_eDataSourceType,
  485. szLogFileList,
  486. m_szSqlDsnName,
  487. m_szSqlLogSetName );
  488. if ( NULL != szLogFileList ) {
  489. delete [] szLogFileList;
  490. szLogFileList = NULL;
  491. ulLogListBufLen = 0;
  492. }
  493. }
  494. }
  495. // m_hDataSource should always be cleared unless in OpenLogFile method.
  496. assert ( H_REALTIME_DATASOURCE == m_hDataSource );
  497. // TodoLogFiles: Need separate method to handle all changes necesary
  498. // when the log source type changes.
  499. if ( sysmonCurrentActivity != m_eDataSourceType ) {
  500. m_eDataSourceType = sysmonCurrentActivity;
  501. CheckRadioButton(
  502. m_hDlg, IDC_SRC_REALTIME, IDC_SRC_SQL,
  503. IDC_SRC_REALTIME + m_eDataSourceType - 1);
  504. m_bDataSourceChg = TRUE;
  505. SetSourceControlStates();
  506. SetTimeRangeCtrlState (
  507. FALSE,
  508. FALSE );
  509. hr = pObj->put_DataSourceType ( m_eDataSourceType );
  510. bReturn = SUCCEEDED ( hr );
  511. m_bDataSourceChg = FALSE;
  512. m_bLogFileChg = FALSE;
  513. m_bSqlDsnChg = FALSE;
  514. m_bSqlLogSetChg = FALSE;
  515. } // else setting to Current Activity failed.
  516. }
  517. }
  518. if ( bReturn ) {
  519. if (m_eDataSourceType == sysmonLogFiles || m_eDataSourceType == sysmonSqlLog)
  520. pPrivObj->SetLogFileRange(m_llBegin, m_llEnd);
  521. else
  522. pObj->UpdateGraph();
  523. } else {
  524. SetFocus(GetDlgItem(m_hDlg, IDC_ADDFILE));
  525. }
  526. if (bReturn && m_bRangeChg
  527. && ( m_eDataSourceType == sysmonLogFiles
  528. || m_eDataSourceType == sysmonSqlLog)) {
  529. // With active logs, the begin/end points might have changed.
  530. pPrivObj->SetLogFileRange(m_llBegin, m_llEnd);
  531. // Always set Stop time first, to handle live logs.
  532. LLTimeToVariantDate(m_llStop, &date);
  533. pObj->put_LogViewStop(date);
  534. LLTimeToVariantDate(m_llStart, &date);
  535. pObj->put_LogViewStart(date);
  536. // Set the start and stop time bars visible in the graph
  537. pPrivObj->SetLogViewTempRange( m_llStart, m_llStop );
  538. m_bRangeChg = FALSE;
  539. }
  540. } else {
  541. bReturn = FALSE;
  542. }
  543. return bReturn;
  544. }
  545. void
  546. CSourcePropPage::LogFilesAreValid (
  547. PLogItemInfo pNewInfo,
  548. BOOL& rbNewIsValid,
  549. BOOL& rbExistingIsValid )
  550. {
  551. DWORD dwStatus = ERROR_SUCCESS;
  552. INT iIndex;
  553. INT iLogFileCnt = 0;
  554. HWND hwndLogFileList = NULL;
  555. WCHAR szLogFile[MAX_PATH + 1];
  556. LPCWSTR pszTestFile = NULL;
  557. PLogItemInfo pInfo = NULL;
  558. WCHAR* pszMessage = NULL;
  559. WCHAR szSystemMessage[MAX_PATH + 1];
  560. DWORD dwType = PDH_LOG_TYPE_BINARY;
  561. UINT uiErrorMessageID = 0;
  562. rbNewIsValid = TRUE;
  563. rbExistingIsValid = TRUE;
  564. hwndLogFileList = DialogControl(m_hDlg, IDC_LIST_LOGFILENAME);
  565. if ( NULL != hwndLogFileList ) {
  566. iLogFileCnt = LBNumItems(hwndLogFileList);
  567. }
  568. if ( NULL != pNewInfo && NULL != hwndLogFileList ) {
  569. if ( NULL != pNewInfo->pszPath ) {
  570. // Check for duplicates.
  571. for (iIndex = 0; iIndex < iLogFileCnt; iIndex++ ) {
  572. LBGetText(hwndLogFileList, iIndex, szLogFile);
  573. if ( 0 == lstrcmpi ( pNewInfo->pszPath, szLogFile ) ) {
  574. MessageBox(
  575. m_hDlg,
  576. ResourceString(IDS_DUPL_LOGFILE_ERR),
  577. ResourceString(IDS_APP_NAME),
  578. MB_OK | MB_ICONWARNING);
  579. iIndex = LB_ERR;
  580. rbNewIsValid = FALSE;
  581. break;
  582. }
  583. }
  584. // Validate added log file type if multiple log files
  585. if ( rbNewIsValid && 0 < iLogFileCnt ) {
  586. // Validate the new file
  587. dwType = PDH_LOG_TYPE_BINARY;
  588. pszTestFile = pNewInfo->pszPath;
  589. if ( NULL != pszTestFile ) {
  590. dwStatus = PdhGetLogFileType (
  591. pszTestFile,
  592. &dwType );
  593. if ( ERROR_SUCCESS == dwStatus ) {
  594. if ( PDH_LOG_TYPE_BINARY != dwType ) {
  595. if ( (DWORD)ePdhLogTypeRetiredBinary == dwType ) {
  596. uiErrorMessageID = IDS_MULTILOG_BIN_TYPE_ADD_ERR;
  597. } else {
  598. uiErrorMessageID = IDS_MULTILOG_TEXT_TYPE_ADD_ERR;
  599. }
  600. rbNewIsValid = FALSE;
  601. }
  602. } else {
  603. // bad dwStatus error message handled below
  604. rbNewIsValid = FALSE;
  605. }
  606. }
  607. }
  608. } else {
  609. rbNewIsValid = FALSE;
  610. assert ( FALSE );
  611. }
  612. }
  613. // Validate existing files if the new count will be > 1
  614. if ( rbNewIsValid
  615. && ( NULL != pNewInfo || iLogFileCnt > 1 ) )
  616. {
  617. dwType = PDH_LOG_TYPE_BINARY;
  618. for (iIndex=0; iIndex<iLogFileCnt; iIndex++) {
  619. pInfo = (PLogItemInfo)LBData(hwndLogFileList,iIndex);
  620. if ( NULL != pInfo ) {
  621. pszTestFile = pInfo->pszPath;
  622. if ( NULL != pszTestFile ) {
  623. dwStatus = PdhGetLogFileType (
  624. pszTestFile,
  625. &dwType );
  626. if ( PDH_LOG_TYPE_BINARY != dwType ) {
  627. rbExistingIsValid = FALSE;
  628. break;
  629. }
  630. }
  631. }
  632. }
  633. if ( ERROR_SUCCESS == dwStatus ) {
  634. if ( PDH_LOG_TYPE_BINARY != dwType ) {
  635. if ( (DWORD)ePdhLogTypeRetiredBinary == dwType ) {
  636. uiErrorMessageID = IDS_MULTILOG_BIN_TYPE_ERR;
  637. } else {
  638. uiErrorMessageID = IDS_MULTILOG_TEXT_TYPE_ERR;
  639. }
  640. rbExistingIsValid = FALSE;
  641. }
  642. } else {
  643. rbExistingIsValid = FALSE;
  644. }
  645. }
  646. if ( ( !rbNewIsValid || !rbExistingIsValid )
  647. && NULL != pszTestFile )
  648. {
  649. iIndex = LB_ERR;
  650. // Check dwStatus of PdhGetLogFileType call.
  651. if ( ERROR_SUCCESS == dwStatus ) {
  652. if ( PDH_LOG_TYPE_BINARY != dwType ) {
  653. assert ( 0 != uiErrorMessageID );
  654. pszMessage = new WCHAR [ ( 2*lstrlen(pszTestFile) ) + RESOURCE_STRING_BUF_LEN + 1];
  655. if ( NULL != pszMessage ) {
  656. StringCchPrintf(pszMessage,
  657. ( 2*lstrlen(pszTestFile) ) + RESOURCE_STRING_BUF_LEN + 1,
  658. ResourceString(uiErrorMessageID),
  659. pszTestFile,
  660. pszTestFile );
  661. MessageBox (
  662. m_hDlg,
  663. pszMessage,
  664. ResourceString(IDS_APP_NAME),
  665. MB_OK | MB_ICONSTOP );
  666. delete [] pszMessage;
  667. }
  668. }
  669. } else {
  670. pszMessage = new WCHAR [lstrlen(pszTestFile) + MAX_PATH + RESOURCE_STRING_BUF_LEN+1];
  671. if ( NULL != pszMessage ) {
  672. StringCchPrintf( pszMessage,
  673. lstrlen(pszTestFile) + MAX_PATH + RESOURCE_STRING_BUF_LEN + 1,
  674. ResourceString(IDS_MULTILOG_CHECKTYPE_ERR),
  675. pszTestFile );
  676. FormatSystemMessage (
  677. dwStatus, szSystemMessage, MAX_PATH );
  678. StringCchCat(pszMessage,
  679. lstrlen(pszTestFile) + MAX_PATH + RESOURCE_STRING_BUF_LEN + 1,
  680. szSystemMessage );
  681. MessageBox (
  682. m_hDlg,
  683. pszMessage,
  684. ResourceString(IDS_APP_NAME),
  685. MB_OK | MB_ICONSTOP);
  686. delete [] pszMessage;
  687. }
  688. }
  689. }
  690. return;
  691. }
  692. INT
  693. CSourcePropPage::AddItemToFileListBox (
  694. IN PLogItemInfo pNewInfo )
  695. /*++
  696. Routine Description:
  697. AddItemToFileListBox adds a log file's path name to the dialog list box and
  698. attaches a pointer to the log file's LogItemInfo structure as item data.
  699. It also adjusts the horizontal scroll of the list box.
  700. Arguments:
  701. pInfo - Pointer to log file's LogItemInfo structure
  702. Return Value:
  703. List box index of added log file (LB_ERR on failure)
  704. --*/
  705. {
  706. INT iIndex = LB_ERR;
  707. HWND hwndLogFileList = NULL;
  708. DWORD dwItemExtent = 0;
  709. HDC hDC = NULL;
  710. BOOL bNewIsValid;
  711. BOOL bExistingAreValid;
  712. hwndLogFileList = DialogControl(m_hDlg, IDC_LIST_LOGFILENAME);
  713. if ( NULL != pNewInfo && NULL != hwndLogFileList ) {
  714. LogFilesAreValid ( pNewInfo, bNewIsValid, bExistingAreValid );
  715. if ( bNewIsValid && NULL != pNewInfo->pszPath ) {
  716. iIndex = (INT)LBAdd ( hwndLogFileList, pNewInfo->pszPath );
  717. LBSetSelection( hwndLogFileList, iIndex);
  718. if ( LB_ERR != iIndex && LB_ERRSPACE != iIndex ) {
  719. LBSetData(hwndLogFileList, iIndex, pNewInfo);
  720. hDC = GetDC ( hwndLogFileList );
  721. if ( NULL != hDC ) {
  722. dwItemExtent = (DWORD)TextWidth ( hDC, pNewInfo->pszPath );
  723. if (dwItemExtent > m_dwMaxHorizListExtent) {
  724. m_dwMaxHorizListExtent = dwItemExtent;
  725. LBSetHorzExtent ( hwndLogFileList, dwItemExtent );
  726. }
  727. ReleaseDC ( hwndLogFileList, hDC );
  728. }
  729. OnLogFileChange();
  730. } else {
  731. iIndex = LB_ERR ;
  732. }
  733. }
  734. }
  735. return iIndex;
  736. }
  737. BOOL
  738. CSourcePropPage::RemoveItemFromFileListBox (
  739. void )
  740. /*++
  741. Routine Description:
  742. RemoveItemFromFileListBox removes the currently selected log file from
  743. the dialog's log file name listbox. It adds the item to the deletion
  744. list, so the actual log file can be deleted from the control when
  745. (and if) the changes are applied.
  746. The routine selects selects the next log file in the listbox if there
  747. is one, and adjusts the horizontal scroll appropriately.
  748. Arguments:
  749. None.
  750. Return Value:
  751. None.
  752. --*/
  753. {
  754. BOOL bChanged = FALSE;
  755. HWND hWnd;
  756. INT iIndex;
  757. PLogItemInfo pInfo = NULL;
  758. LPWSTR szBuffer = NULL;
  759. DWORD dwItemExtent = 0;
  760. INT iCurrentBufLen = 0;
  761. INT iTextLen;
  762. HDC hDC = NULL;
  763. // Get selected index
  764. hWnd = DialogControl(m_hDlg, IDC_LIST_LOGFILENAME);
  765. iIndex = LBSelection(hWnd);
  766. if ( LB_ERR != iIndex ) {
  767. // Get selected item info
  768. pInfo = (PLogItemInfo)LBData(hWnd, iIndex);
  769. // Move it to the "Deleted" list.
  770. pInfo->pNextInfo = m_pInfoDeleted;
  771. m_pInfoDeleted = pInfo;
  772. // Remove the string from the list box.
  773. LBDelete(hWnd, iIndex);
  774. // Select next item if possible, else the previous
  775. if (iIndex == LBNumItems(hWnd)) {
  776. iIndex--;
  777. }
  778. LBSetSelection( hWnd, iIndex);
  779. hDC = GetDC ( hWnd );
  780. if ( NULL != hDC ) {
  781. // Clear the max horizontal extent and recalculate
  782. m_dwMaxHorizListExtent = 0;
  783. for ( iIndex = 0; iIndex < (INT)LBNumItems ( hWnd ); iIndex++ ) {
  784. iTextLen = (INT)LBGetTextLen ( hWnd, iIndex );
  785. if ( iTextLen >= iCurrentBufLen ) {
  786. if ( NULL != szBuffer ) {
  787. delete [] szBuffer;
  788. szBuffer = NULL;
  789. }
  790. iCurrentBufLen = iTextLen + 1;
  791. szBuffer = new WCHAR [iCurrentBufLen];
  792. }
  793. if ( NULL != szBuffer ) {
  794. LBGetText ( hWnd, iIndex, szBuffer );
  795. dwItemExtent = (DWORD)TextWidth ( hDC, szBuffer );
  796. if (dwItemExtent > m_dwMaxHorizListExtent) {
  797. m_dwMaxHorizListExtent = dwItemExtent;
  798. }
  799. }
  800. }
  801. LBSetHorzExtent ( hWnd, m_dwMaxHorizListExtent );
  802. ReleaseDC ( hWnd, hDC );
  803. }
  804. if ( NULL != szBuffer ) {
  805. delete [] szBuffer;
  806. }
  807. bChanged = TRUE;
  808. OnLogFileChange();
  809. }
  810. return bChanged;
  811. }
  812. void
  813. CSourcePropPage::OnLogFileChange ( void )
  814. {
  815. HWND hwndLogFileList = NULL;
  816. INT iLogFileCnt = 0;
  817. BOOL bIsValidDataSource = FALSE;
  818. m_bLogFileChg = TRUE;
  819. m_bInitialTimeRangePending = TRUE;
  820. hwndLogFileList = DialogControl(m_hDlg, IDC_LIST_LOGFILENAME);
  821. if ( NULL != hwndLogFileList ) {
  822. iLogFileCnt = LBNumItems(hwndLogFileList);
  823. }
  824. bIsValidDataSource = (iLogFileCnt > 0);
  825. if (m_eDataSourceType == sysmonLogFiles) {
  826. DialogEnable(m_hDlg, IDC_REMOVEFILE, ( bIsValidDataSource ) );
  827. }
  828. SetTimeRangeCtrlState( bIsValidDataSource, FALSE );
  829. }
  830. void
  831. CSourcePropPage::OnSqlDataChange ( void )
  832. {
  833. BOOL bIsValidDataSource = FALSE;
  834. assert ( sysmonSqlLog == m_eDataSourceType );
  835. m_bInitialTimeRangePending = TRUE;
  836. bIsValidDataSource = 0 < lstrlen ( m_szSqlDsnName ) && 0 < lstrlen ( m_szSqlLogSetName );
  837. SetTimeRangeCtrlState( bIsValidDataSource, FALSE );
  838. }
  839. void
  840. CSourcePropPage::DialogItemChange(WORD wID, WORD wMsg)
  841. {
  842. ISystemMonitor *pObj = NULL;
  843. CImpISystemMonitor *pPrivObj = NULL;
  844. HWND hwndCtrl = NULL;
  845. BOOL fChange = FALSE;
  846. DataSourceTypeConstants eNewDataSourceType;
  847. HWND hwndLogFileList = NULL;
  848. INT iLogFileCnt = 0;;
  849. BOOL bIsValidDataSource;
  850. switch(wID) {
  851. case IDC_SRC_REALTIME:
  852. case IDC_SRC_LOGFILE:
  853. case IDC_SRC_SQL:
  854. // Check which button is involved
  855. eNewDataSourceType = (DataSourceTypeConstants)(wID - IDC_SRC_REALTIME + 1);
  856. // If state changed
  857. if ( wMsg == BN_CLICKED
  858. && eNewDataSourceType != m_eDataSourceType) {
  859. // Set change flags and update the radio button
  860. m_bDataSourceChg = TRUE;
  861. fChange = TRUE;
  862. m_eDataSourceType = eNewDataSourceType;
  863. CheckRadioButton(
  864. m_hDlg, IDC_SRC_REALTIME, IDC_SRC_SQL,
  865. IDC_SRC_REALTIME + m_eDataSourceType - 1);
  866. SetSourceControlStates();
  867. pObj = m_ppISysmon[0];
  868. if ( NULL != m_ppISysmon[0] ) {
  869. pPrivObj = (CImpISystemMonitor*) pObj;
  870. }
  871. if ( NULL != pPrivObj ) {
  872. bIsValidDataSource = FALSE;
  873. hwndLogFileList = DialogControl(m_hDlg, IDC_LIST_LOGFILENAME);
  874. if ( NULL != hwndLogFileList ) {
  875. iLogFileCnt = LBNumItems(hwndLogFileList);
  876. }
  877. if ( sysmonLogFiles == m_eDataSourceType && iLogFileCnt > 0) {
  878. bIsValidDataSource = (iLogFileCnt > 0);
  879. if ( bIsValidDataSource ) {
  880. SetFocus(GetDlgItem(m_hDlg, IDC_ADDFILE));
  881. }
  882. } else if ( sysmonSqlLog == m_eDataSourceType ) {
  883. bIsValidDataSource = ( 0 < lstrlen ( m_szSqlDsnName ) )
  884. && ( 0 < lstrlen ( m_szSqlLogSetName ) );
  885. } // else current activity, so no valid data source
  886. if ( bIsValidDataSource ) {
  887. // Set the start and stop time bars visible in the graph
  888. pPrivObj->SetLogViewTempRange( m_llStart, m_llStop );
  889. } else {
  890. // Set the start and stop time bars invisible in the graph
  891. pPrivObj->SetLogViewTempRange( MIN_TIME_VALUE, MAX_TIME_VALUE );
  892. }
  893. }
  894. m_bDataSourceChg = TRUE;
  895. }
  896. break;
  897. case IDC_REMOVEFILE:
  898. fChange = RemoveItemFromFileListBox();
  899. break;
  900. case IDC_ADDFILE:
  901. {
  902. WCHAR szDefaultFolderBuff[MAX_PATH + 1];
  903. LPWSTR szBrowseBuffer = NULL;
  904. INT iFolderBufLen;
  905. PDH_STATUS pdhstat;
  906. LogItemInfo* pInfo = NULL;
  907. DWORD cchLen = 0;
  908. DWORD cchBrowseBuffer = 0;
  909. szDefaultFolderBuff[0] = L'\0';
  910. iFolderBufLen = MAX_PATH;
  911. if ( ERROR_SUCCESS != LoadDefaultLogFileFolder(szDefaultFolderBuff, &iFolderBufLen ) ) {
  912. StringCchCopy(szDefaultFolderBuff,
  913. MAX_PATH + 1,
  914. ResourceString ( IDS_DEFAULT_LOG_FILE_FOLDER ) );
  915. }
  916. //
  917. // Expand environment strings.
  918. //
  919. cchLen = ExpandEnvironmentStrings ( szDefaultFolderBuff, NULL, 0 );
  920. if ( 0 < cchLen ) {
  921. //
  922. // cchLen includes space for null.
  923. //
  924. cchBrowseBuffer = max ( cchLen, MAX_PATH + 1 );
  925. szBrowseBuffer = new WCHAR [ cchBrowseBuffer ];
  926. szBrowseBuffer[0] = L'\0';
  927. if ( NULL != szBrowseBuffer ) {
  928. cchLen = ExpandEnvironmentStrings (
  929. szDefaultFolderBuff,
  930. szBrowseBuffer,
  931. cchBrowseBuffer );
  932. if ( 0 < cchLen && cchLen <= cchBrowseBuffer ) {
  933. SetCurrentDirectory(szBrowseBuffer);
  934. }
  935. }
  936. }
  937. if ( NULL != szBrowseBuffer ) {
  938. szBrowseBuffer[0] = L'\0';
  939. pdhstat = PdhSelectDataSource(
  940. m_hDlg,
  941. PDH_FLAGS_FILE_BROWSER_ONLY,
  942. szBrowseBuffer,
  943. &cchBrowseBuffer);
  944. // Todo: Error message if file name is too long.
  945. if ( (ERROR_SUCCESS != pdhstat)
  946. || szBrowseBuffer [0] == L'\0' ) {
  947. delete [] szBrowseBuffer;
  948. szBrowseBuffer = NULL;
  949. break;
  950. }
  951. // Load file name into edit control
  952. pInfo = new LogItemInfo;
  953. if ( NULL != pInfo ) {
  954. ZeroMemory ( pInfo, sizeof(LogItemInfo) );
  955. //
  956. // Make own copy of path name string
  957. //
  958. pInfo->pszPath = new WCHAR [lstrlen( szBrowseBuffer ) + 1];
  959. if ( NULL != pInfo->pszPath ) {
  960. INT iIndex = 0;
  961. StringCchCopy(pInfo->pszPath, lstrlen( szBrowseBuffer ) + 1, szBrowseBuffer);
  962. iIndex = AddItemToFileListBox ( pInfo );
  963. fChange = ( LB_ERR != iIndex );
  964. if (!fChange) {
  965. // Todo: error message
  966. delete [] pInfo->pszPath;
  967. delete pInfo;
  968. }
  969. } else {
  970. // Todo: error message
  971. delete pInfo;
  972. }
  973. }
  974. // Todo: error message
  975. }
  976. if ( NULL != szBrowseBuffer ) {
  977. delete [] szBrowseBuffer;
  978. }
  979. break;
  980. }
  981. /*
  982. // Doesn't do anything
  983. case IDC_LIST_LOGFILENAME:
  984. // If selection changed
  985. if (wMsg == LBN_SELCHANGE) {
  986. // TodoLogFiles: Selection change won't matter when multi-file support
  987. fChange = TRUE;
  988. OnLogFileChange();
  989. // Get selected index
  990. hwndCtrl = DialogControl(m_hDlg, IDC_LIST_LOGFILENAME);
  991. iIndex = LBSelection(hwndCtrl);
  992. }
  993. break;
  994. */
  995. case IDC_DSN_COMBO:
  996. {
  997. WCHAR* szDsnName = NULL;
  998. INT iSel;
  999. HWND hDsnCombo;
  1000. LRESULT lresultDsnLen;
  1001. if (wMsg == CBN_CLOSEUP) {
  1002. hDsnCombo = GetDlgItem ( m_hDlg, IDC_DSN_COMBO);
  1003. if ( NULL != hDsnCombo ) {
  1004. iSel = (INT)CBSelection ( hDsnCombo );
  1005. if ( LB_ERR != iSel ) {
  1006. lresultDsnLen = (INT)CBStringLen ( hDsnCombo, iSel );
  1007. if ( lresultDsnLen < INT_MAX ) {
  1008. szDsnName = new WCHAR[lresultDsnLen+1];
  1009. if ( NULL != szDsnName ) {
  1010. szDsnName[0] = L'\0';
  1011. CBString( hDsnCombo, iSel, szDsnName);
  1012. szDsnName[lresultDsnLen] = L'\0';
  1013. if ( 0 != lstrcmpi ( m_szSqlDsnName, szDsnName ) ) {
  1014. lstrcpyn (
  1015. m_szSqlDsnName,
  1016. szDsnName,
  1017. min ( SQL_MAX_DSN_LENGTH+1, lstrlen(szDsnName)+1 ) );
  1018. m_bSqlDsnChg = TRUE;
  1019. InitSqlLogSetList();
  1020. OnSqlDataChange();
  1021. fChange = TRUE;
  1022. }
  1023. delete [] szDsnName;
  1024. }
  1025. }
  1026. }
  1027. }
  1028. }
  1029. break;
  1030. }
  1031. case IDC_LOGSET_COMBO:
  1032. {
  1033. WCHAR* szLogSetName = NULL;
  1034. INT iSel;
  1035. HWND hLogSetCombo;
  1036. LRESULT lresultLogSetLen;
  1037. if (wMsg == CBN_CLOSEUP) {
  1038. hLogSetCombo = GetDlgItem ( m_hDlg, IDC_LOGSET_COMBO);
  1039. if ( NULL != hLogSetCombo ) {
  1040. iSel = (INT)CBSelection ( hLogSetCombo );
  1041. if ( LB_ERR != iSel ) {
  1042. lresultLogSetLen = CBStringLen ( hLogSetCombo, iSel );
  1043. if ( lresultLogSetLen < INT_MAX ) {
  1044. szLogSetName = new WCHAR[lresultLogSetLen+1];
  1045. if ( NULL != szLogSetName ) {
  1046. szLogSetName[0] = L'\0';
  1047. CBString ( hLogSetCombo, iSel, szLogSetName );
  1048. szLogSetName[lresultLogSetLen] = L'\0';
  1049. if ( ( 0 != lstrcmpi ( m_szSqlLogSetName, szLogSetName ) )
  1050. && ( 0 != lstrcmpi ( szLogSetName, ResourceString ( IDS_LOGSET_NOT_FOUND ) ) ) ) {
  1051. lstrcpyn ( m_szSqlLogSetName,
  1052. szLogSetName,
  1053. min ( SLQ_MAX_LOG_SET_NAME_LEN + 1, lstrlen(szLogSetName)+1 ) );
  1054. m_bSqlLogSetChg = TRUE;
  1055. OnSqlDataChange();
  1056. fChange = TRUE;
  1057. }
  1058. delete [] szLogSetName;
  1059. }
  1060. }
  1061. }
  1062. }
  1063. }
  1064. break;
  1065. }
  1066. case IDC_TIMESELECTBTN:
  1067. {
  1068. DWORD dwStatus = ERROR_SUCCESS;
  1069. BOOL bAttemptedReload = FALSE;
  1070. hwndCtrl = DialogControl(m_hDlg, IDC_LIST_LOGFILENAME);
  1071. if ( NULL != hwndCtrl ) {
  1072. {
  1073. CWaitCursor cursorWait;
  1074. dwStatus = OpenLogFile ();
  1075. }
  1076. if ( SMON_STATUS_LOG_FILE_SIZE_LIMIT == dwStatus ) {
  1077. WCHAR szMessage[RESOURCE_STRING_BUF_LEN + 1];
  1078. BSTR bstrPath;
  1079. int iResult;
  1080. pObj = m_ppISysmon[0];
  1081. pObj->get_LogFileName ( &bstrPath );
  1082. if ( bstrPath ) {
  1083. if ( bstrPath[0] ) {
  1084. StringCchCopy(szMessage,
  1085. RESOURCE_STRING_BUF_LEN+1,
  1086. ResourceString(IDS_LARGE_LOG_FILE_RELOAD) );
  1087. iResult = MessageBox(
  1088. m_hDlg,
  1089. szMessage,
  1090. ResourceString(IDS_APP_NAME),
  1091. MB_YESNO | MB_ICONEXCLAMATION);
  1092. if ( IDYES == iResult ) {
  1093. CWaitCursor cursorWait;
  1094. dwStatus = OpenLogFile ();
  1095. bAttemptedReload = TRUE;
  1096. }
  1097. }
  1098. SysFreeString(bstrPath);
  1099. }
  1100. }
  1101. if ( ERROR_SUCCESS == dwStatus ) {
  1102. m_bInitialTimeRangePending = FALSE;
  1103. // Show graph log view start/stop time bars
  1104. pObj = m_ppISysmon[0];
  1105. pPrivObj = (CImpISystemMonitor*)pObj;
  1106. pPrivObj->SetLogViewTempRange( m_llStart, m_llStop );
  1107. SetTimeRangeCtrlState (
  1108. TRUE,
  1109. TRUE );
  1110. m_bRangeChg = TRUE;
  1111. fChange = TRUE;
  1112. } else { // OpenLogFile failure
  1113. if ( ( SMON_STATUS_LOG_FILE_SIZE_LIMIT == dwStatus ) && !bAttemptedReload ) {
  1114. // Message already displayed, user chose not to continue.
  1115. } else {
  1116. LPWSTR szLogFileList = NULL;
  1117. ULONG ulLogListBufLen = 0;
  1118. if ( sysmonLogFiles == m_eDataSourceType ) {
  1119. BuildLogFileList (
  1120. m_hDlg,
  1121. NULL,
  1122. &ulLogListBufLen );
  1123. szLogFileList = new WCHAR[ulLogListBufLen];
  1124. if ( NULL != szLogFileList ) {
  1125. BuildLogFileList (
  1126. m_hDlg,
  1127. szLogFileList,
  1128. &ulLogListBufLen );
  1129. }
  1130. }
  1131. if ( NULL != szLogFileList || sysmonSqlLog == m_eDataSourceType ) {
  1132. DisplayDataSourceError (
  1133. m_hDlg,
  1134. dwStatus,
  1135. m_eDataSourceType,
  1136. szLogFileList,
  1137. m_szSqlDsnName,
  1138. m_szSqlLogSetName );
  1139. if ( NULL != szLogFileList ) {
  1140. delete [] szLogFileList;
  1141. szLogFileList = NULL;
  1142. ulLogListBufLen = 0;
  1143. }
  1144. }
  1145. }
  1146. }
  1147. }
  1148. break;
  1149. }
  1150. case IDC_TIMERANGE:
  1151. {
  1152. m_llStart = m_pTimeRange->GetStart();
  1153. m_llStop = m_pTimeRange->GetStop();
  1154. // Show graph log view start/stop time bars
  1155. pObj = m_ppISysmon[0];
  1156. pPrivObj = (CImpISystemMonitor*)pObj;
  1157. pPrivObj->SetLogViewTempRange( m_llStart, m_llStop );
  1158. fChange = TRUE;
  1159. m_bRangeChg = TRUE;
  1160. break;
  1161. }
  1162. }
  1163. if (fChange)
  1164. SetChange();
  1165. }
  1166. DWORD
  1167. CSourcePropPage::OpenLogFile (void)
  1168. {
  1169. DWORD dwStatus = ERROR_SUCCESS;
  1170. DWORD nBufSize;
  1171. DWORD nLogEntries = 0;
  1172. PDH_TIME_INFO TimeInfo;
  1173. LPWSTR szLogFileList = NULL;
  1174. LPWSTR szCurrentLogFile;
  1175. ULONG LogFileListSize = 0;
  1176. HWND hwndLogFileList = NULL;
  1177. INT iLogFileCount = 0;
  1178. INT iLogFileIndex;
  1179. PLogItemInfo pInfo;
  1180. BOOLEAN bSqlLogSet =
  1181. (BST_CHECKED == IsDlgButtonChecked(m_hDlg,IDC_SRC_SQL));
  1182. WCHAR* szDsnName = NULL;
  1183. WCHAR* szLogSetName = NULL;
  1184. INT iSel;
  1185. HWND hDsnCombo;
  1186. HWND hLogSetCombo;
  1187. memset (&TimeInfo, 0, sizeof(TimeInfo));
  1188. hwndLogFileList = DialogControl(m_hDlg, IDC_LIST_LOGFILENAME);
  1189. if ( NULL != hwndLogFileList ) {
  1190. iLogFileCount = LBNumItems(hwndLogFileList);
  1191. }
  1192. if (bSqlLogSet) {
  1193. LogFileListSize = 0;
  1194. szDsnName = new WCHAR[SQL_MAX_DSN_LENGTH+1];
  1195. szLogSetName = new WCHAR[SLQ_MAX_LOG_SET_NAME_LEN+1];
  1196. hDsnCombo = GetDlgItem ( m_hDlg, IDC_DSN_COMBO);
  1197. hLogSetCombo = GetDlgItem ( m_hDlg, IDC_LOGSET_COMBO);
  1198. if ( NULL != szDsnName && NULL != szLogSetName
  1199. && NULL != hDsnCombo && NULL != hLogSetCombo ) {
  1200. szDsnName[0] = L'\0';
  1201. szLogSetName[0] = L'\0';
  1202. iSel = (INT)CBSelection ( hDsnCombo );
  1203. if ( LB_ERR != iSel ) {
  1204. if ( SQL_MAX_DSN_LENGTH >= CBStringLen( hDsnCombo, iSel ) ) {
  1205. CBString ( hDsnCombo, iSel, szDsnName);
  1206. iSel = (INT)CBSelection ( hLogSetCombo );
  1207. if ( LB_ERR != iSel ) {
  1208. if ( SLQ_MAX_LOG_SET_NAME_LEN >= CBStringLen( hLogSetCombo, iSel ) ) {
  1209. CBString( hLogSetCombo, iSel, szLogSetName);
  1210. // Size includes 5 characters "SQL:" "!"and 2 nulls
  1211. LogFileListSize = lstrlen(szDsnName) + lstrlen(szLogSetName) + 7;
  1212. }
  1213. }
  1214. }
  1215. }
  1216. }
  1217. } else {
  1218. if ( NULL != hwndLogFileList ) {
  1219. for (iLogFileIndex = 0; iLogFileIndex < iLogFileCount; iLogFileIndex ++) {
  1220. pInfo = (PLogItemInfo) LBData(hwndLogFileList, iLogFileIndex);
  1221. if (pInfo && pInfo->pszPath) {
  1222. LogFileListSize += (lstrlen(pInfo->pszPath) + 1);
  1223. }
  1224. }
  1225. LogFileListSize ++;
  1226. }
  1227. }
  1228. szLogFileList = (LPWSTR) malloc(LogFileListSize * sizeof(WCHAR));
  1229. if (szLogFileList) {
  1230. if (bSqlLogSet) {
  1231. ZeroMemory(szLogFileList, LogFileListSize * sizeof(WCHAR));
  1232. StringCchPrintf(szLogFileList, LogFileListSize, L"SQL:%s!%s", szDsnName, szLogSetName);
  1233. } else {
  1234. if ( NULL != hwndLogFileList ) {
  1235. szCurrentLogFile = szLogFileList;
  1236. for (iLogFileIndex = 0;
  1237. iLogFileIndex < iLogFileCount;
  1238. iLogFileIndex ++) {
  1239. pInfo = (PLogItemInfo) LBData(hwndLogFileList, iLogFileIndex);
  1240. if (pInfo && pInfo->pszPath) {
  1241. StringCchCopy(szCurrentLogFile,lstrlen(pInfo->pszPath) + 1, pInfo->pszPath);
  1242. szCurrentLogFile += lstrlen(pInfo->pszPath);
  1243. * szCurrentLogFile = L'\0';
  1244. szCurrentLogFile ++;
  1245. }
  1246. }
  1247. * szCurrentLogFile = L'\0';
  1248. }
  1249. }
  1250. if ( m_hDataSource != H_REALTIME_DATASOURCE
  1251. && m_hDataSource != H_WBEM_DATASOURCE)
  1252. {
  1253. PdhCloseLog(m_hDataSource, 0);
  1254. m_hDataSource = H_REALTIME_DATASOURCE;
  1255. }
  1256. dwStatus = PdhBindInputDataSource(& m_hDataSource, szLogFileList);
  1257. if ( ERROR_SUCCESS == dwStatus ) {
  1258. // Get time and sample count info
  1259. nBufSize = sizeof(TimeInfo);
  1260. dwStatus = PdhGetDataSourceTimeRangeH(
  1261. m_hDataSource, &nLogEntries, &TimeInfo, & nBufSize);
  1262. PdhCloseLog(m_hDataSource, 0);
  1263. m_hDataSource = H_REALTIME_DATASOURCE;
  1264. }
  1265. free(szLogFileList);
  1266. szLogFileList = NULL;
  1267. } else {
  1268. dwStatus = ERROR_NOT_ENOUGH_MEMORY;
  1269. }
  1270. if (ERROR_NOT_ENOUGH_MEMORY == dwStatus ) {
  1271. dwStatus = SMON_STATUS_LOG_FILE_SIZE_LIMIT;
  1272. }
  1273. if ( ERROR_SUCCESS == dwStatus ) {
  1274. // Check that at least 2 samples exist:
  1275. // If 0 samples, StartTime is 0, EndTime is 0
  1276. // If 1 sample, StartTime == EndTime
  1277. if ( ( TimeInfo.StartTime < TimeInfo.EndTime )
  1278. && ( 1 < TimeInfo.SampleCount ) ){
  1279. // Load log time range into time range control
  1280. m_llBegin = TimeInfo.StartTime;
  1281. m_llEnd = TimeInfo.EndTime;
  1282. // Limit view range to actual log file range
  1283. if (m_llStop > m_llEnd ) {
  1284. m_llStop = m_llEnd;
  1285. } else if (m_llStop < m_llBegin ) {
  1286. m_llStop = m_llBegin;
  1287. }
  1288. if (m_llStart < m_llBegin)
  1289. m_llStart = m_llBegin;
  1290. if (m_llStart > m_llStop)
  1291. m_llStart = m_llStop;
  1292. m_pTimeRange->SetBeginEnd(m_llBegin, m_llEnd);
  1293. m_pTimeRange->SetStartStop(m_llStart, m_llStop);
  1294. } else {
  1295. dwStatus = SMON_STATUS_TOO_FEW_SAMPLES;
  1296. }
  1297. }
  1298. if ( NULL != szDsnName ) {
  1299. delete [] szDsnName;
  1300. }
  1301. if ( NULL != szLogSetName ) {
  1302. delete [] szLogSetName;
  1303. }
  1304. return dwStatus;
  1305. }
  1306. void
  1307. CSourcePropPage::SetTimeRangeCtrlState (
  1308. BOOL bIsValidLogFile,
  1309. BOOL bIsValidLogFileRange )
  1310. {
  1311. // Enable time range button if valid log file, even if log data is invalid.
  1312. DialogEnable ( m_hDlg, IDC_TIMESELECTBTN, bIsValidLogFile );
  1313. // Set time range controls visible or not, depending on valid log file and data.
  1314. DialogEnable ( m_hDlg, IDC_TIMERANGE, bIsValidLogFile && bIsValidLogFileRange );
  1315. DialogEnable ( m_hDlg, IDC_STATIC_TOTAL, bIsValidLogFile && bIsValidLogFileRange );
  1316. DialogEnable ( m_hDlg, IDC_STATIC_SELECTED, bIsValidLogFile && bIsValidLogFileRange );
  1317. }
  1318. void
  1319. CSourcePropPage::InitSqlDsnList(void)
  1320. {
  1321. HENV henv;
  1322. RETCODE retcode;
  1323. INT DsnCount = 0;
  1324. HWND hWnd = NULL;
  1325. WCHAR* szTmpName = NULL;
  1326. hWnd = GetDlgItem(m_hDlg, IDC_DSN_COMBO);
  1327. szTmpName = new WCHAR[SQL_MAX_DSN_LENGTH + 1];
  1328. if ( NULL != hWnd && NULL != szTmpName ) {
  1329. if (SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_ENV, NULL, & henv))) {
  1330. (void) SQLSetEnvAttr(henv,
  1331. SQL_ATTR_ODBC_VERSION,
  1332. (SQLPOINTER) SQL_OV_ODBC3,
  1333. SQL_IS_INTEGER);
  1334. // Todo: NULL hWnd
  1335. CBReset(hWnd);
  1336. ZeroMemory ( szTmpName, sizeof(szTmpName) );
  1337. retcode = SQLDataSources(henv,
  1338. SQL_FETCH_FIRST_SYSTEM,
  1339. szTmpName,
  1340. (SQL_MAX_DSN_LENGTH+1),
  1341. NULL,
  1342. NULL,
  1343. 0,
  1344. NULL);
  1345. while (SQL_SUCCEEDED(retcode)) {
  1346. CBAdd(hWnd, szTmpName);
  1347. ZeroMemory ( szTmpName, sizeof(szTmpName) );
  1348. retcode = SQLDataSources(henv,
  1349. SQL_FETCH_NEXT,
  1350. szTmpName,
  1351. (SQL_MAX_DSN_LENGTH+1),
  1352. NULL,
  1353. NULL,
  1354. 0,
  1355. NULL);
  1356. }
  1357. DsnCount = CBNumItems(hWnd) - 1;
  1358. if (DsnCount >= 0) {
  1359. if ( m_szSqlDsnName[0] != L'\0') {
  1360. while (DsnCount >= 0) {
  1361. CBString(hWnd, DsnCount, szTmpName);
  1362. if (lstrcmpi(m_szSqlDsnName, szTmpName) == 0) {
  1363. CBSetSelection(hWnd, DsnCount);
  1364. break;
  1365. }
  1366. else {
  1367. DsnCount --;
  1368. }
  1369. }
  1370. // Todo: Clear m_szSqlDsnName if not in list?
  1371. }
  1372. else {
  1373. DsnCount = -1;
  1374. }
  1375. }
  1376. SQLFreeHandle(SQL_HANDLE_ENV, henv);
  1377. }
  1378. }
  1379. if ( NULL!= szTmpName ) {
  1380. delete [] szTmpName;
  1381. }
  1382. }
  1383. void
  1384. CSourcePropPage::InitSqlLogSetList(void)
  1385. {
  1386. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  1387. INT iLogSetIndex = 0;
  1388. LPWSTR pLogSetList = NULL;
  1389. DWORD dwBufferLen = 0;
  1390. LPWSTR pLogSetPtr = NULL;
  1391. HWND hwndLogSetCombo = NULL;
  1392. LPWSTR szTmpName = NULL;
  1393. INT iBufAllocCount = 0;
  1394. INT iMaxNameLen = 0;
  1395. INT iCurrentNameLen = 0;
  1396. if ( L'\0' == m_szSqlDsnName[0] ) {
  1397. goto Cleanup;
  1398. }
  1399. hwndLogSetCombo = GetDlgItem(m_hDlg, IDC_LOGSET_COMBO);
  1400. if ( NULL == hwndLogSetCombo ) {
  1401. goto Cleanup;
  1402. }
  1403. do {
  1404. pdhStatus = PdhEnumLogSetNames(
  1405. m_szSqlDsnName, pLogSetList, & dwBufferLen);
  1406. if (pdhStatus == PDH_INSUFFICIENT_BUFFER || pdhStatus == PDH_MORE_DATA)
  1407. {
  1408. iBufAllocCount += 1;
  1409. if (pLogSetList) {
  1410. delete [] pLogSetList;
  1411. pLogSetList = NULL;
  1412. }
  1413. pLogSetList = (LPWSTR) new WCHAR[dwBufferLen];
  1414. if (pLogSetList == NULL) {
  1415. pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
  1416. }
  1417. }
  1418. }
  1419. while ( ( PDH_INSUFFICIENT_BUFFER == pdhStatus || PDH_MORE_DATA == pdhStatus )
  1420. && iBufAllocCount < 10 );
  1421. if (pdhStatus == ERROR_SUCCESS && pLogSetList != NULL) {
  1422. CBReset(hwndLogSetCombo);
  1423. for ( pLogSetPtr = pLogSetList;
  1424. * pLogSetPtr != L'\0';
  1425. pLogSetPtr += ( iCurrentNameLen + 1))
  1426. {
  1427. iCurrentNameLen = lstrlen(pLogSetPtr);
  1428. // Ignore log set names that longer than the max allowed length.
  1429. if ( iCurrentNameLen <= SLQ_MAX_LOG_SET_NAME_LEN ) {
  1430. CBAdd(hwndLogSetCombo, pLogSetPtr);
  1431. if ( iMaxNameLen < iCurrentNameLen ) {
  1432. iMaxNameLen = iCurrentNameLen;
  1433. }
  1434. }
  1435. }
  1436. iLogSetIndex = CBNumItems(hwndLogSetCombo) - 1;
  1437. if (iLogSetIndex >= 0) {
  1438. if ( m_szSqlLogSetName[0] != L'\0') {
  1439. szTmpName = new WCHAR[iMaxNameLen+1];
  1440. if ( NULL != szTmpName ) {
  1441. while (iLogSetIndex >= 0) {
  1442. CBString(hwndLogSetCombo, iLogSetIndex, szTmpName);
  1443. if (lstrcmpi( m_szSqlLogSetName, szTmpName) == 0) {
  1444. CBSetSelection(hwndLogSetCombo, iLogSetIndex);
  1445. break;
  1446. }
  1447. else {
  1448. iLogSetIndex --;
  1449. }
  1450. }
  1451. } else {
  1452. iLogSetIndex = -1;
  1453. }
  1454. } else {
  1455. iLogSetIndex = -1;
  1456. }
  1457. // Todo: Clear m_szSqlLogSetName if not in list?
  1458. } else {
  1459. if ( 0 == CBNumItems(hwndLogSetCombo) ) {
  1460. iMaxNameLen = lstrlen ( ResourceString(IDS_LOGSET_NOT_FOUND) );
  1461. szTmpName = new WCHAR[iMaxNameLen+1];
  1462. if ( NULL != szTmpName ) {
  1463. StringCchCopy(szTmpName, iMaxNameLen+1, ResourceString(IDS_LOGSET_NOT_FOUND));
  1464. CBReset(hwndLogSetCombo);
  1465. iLogSetIndex = (INT)CBAdd(hwndLogSetCombo, szTmpName);
  1466. CBSetSelection( hwndLogSetCombo, iLogSetIndex);
  1467. }
  1468. }
  1469. }
  1470. } else {
  1471. if ( 0 == CBNumItems(hwndLogSetCombo) ) {
  1472. iMaxNameLen = lstrlen ( ResourceString(IDS_LOGSET_NOT_FOUND) );
  1473. szTmpName = new WCHAR[iMaxNameLen+1];
  1474. if ( NULL != szTmpName ) {
  1475. StringCchCopy(szTmpName, iMaxNameLen+1, ResourceString(IDS_LOGSET_NOT_FOUND));
  1476. CBReset(hwndLogSetCombo);
  1477. iLogSetIndex = (INT)CBAdd(hwndLogSetCombo, szTmpName);
  1478. CBSetSelection( hwndLogSetCombo, iLogSetIndex);
  1479. }
  1480. }
  1481. }
  1482. Cleanup:
  1483. if (pLogSetList) {
  1484. delete [] pLogSetList;
  1485. }
  1486. if ( szTmpName ) {
  1487. delete [] szTmpName;
  1488. }
  1489. return;
  1490. }
  1491. HRESULT
  1492. CSourcePropPage::EditPropertyImpl( DISPID dispID )
  1493. {
  1494. HRESULT hr = E_NOTIMPL;
  1495. if ( DISPID_SYSMON_DATASOURCETYPE == dispID ) {
  1496. if ( sysmonCurrentActivity == m_eDataSourceType ) {
  1497. m_dwEditControl = IDC_SRC_REALTIME;
  1498. } else if ( sysmonLogFiles == m_eDataSourceType ) {
  1499. m_dwEditControl = IDC_SRC_LOGFILE;
  1500. } else if ( sysmonSqlLog == m_eDataSourceType ) {
  1501. m_dwEditControl = IDC_SRC_SQL;
  1502. }
  1503. hr = S_OK;
  1504. }
  1505. return hr;
  1506. }
  1507. void
  1508. CSourcePropPage::SetSourceControlStates ( void )
  1509. {
  1510. HWND hwndLogFileList = NULL;
  1511. INT iLogFileCnt = 0;
  1512. BOOL bIsValidDataSource = FALSE;
  1513. if ( sysmonCurrentActivity == m_eDataSourceType ) {
  1514. DialogEnable(m_hDlg, IDC_ADDFILE, FALSE);
  1515. DialogEnable(m_hDlg, IDC_REMOVEFILE, FALSE);
  1516. DialogEnable(m_hDlg, IDC_STATIC_DSN, FALSE);
  1517. DialogEnable(m_hDlg, IDC_DSN_COMBO, FALSE);
  1518. DialogEnable(m_hDlg, IDC_STATIC_LOGSET, FALSE);
  1519. DialogEnable(m_hDlg, IDC_LOGSET_COMBO, FALSE);
  1520. bIsValidDataSource = FALSE;
  1521. } else if ( sysmonLogFiles == m_eDataSourceType ) {
  1522. DialogEnable(m_hDlg, IDC_ADDFILE, TRUE);
  1523. DialogEnable(m_hDlg, IDC_STATIC_DSN, FALSE);
  1524. DialogEnable(m_hDlg, IDC_DSN_COMBO, FALSE);
  1525. DialogEnable(m_hDlg, IDC_STATIC_LOGSET, FALSE);
  1526. DialogEnable(m_hDlg, IDC_LOGSET_COMBO, FALSE);
  1527. hwndLogFileList = DialogControl(m_hDlg, IDC_LIST_LOGFILENAME);
  1528. if ( NULL != hwndLogFileList ) {
  1529. iLogFileCnt = LBNumItems(hwndLogFileList);
  1530. }
  1531. bIsValidDataSource = (iLogFileCnt > 0);
  1532. DialogEnable(m_hDlg, IDC_REMOVEFILE, ( bIsValidDataSource ) );
  1533. } else {
  1534. assert ( sysmonSqlLog == m_eDataSourceType );
  1535. DialogEnable(m_hDlg, IDC_ADDFILE, FALSE);
  1536. DialogEnable(m_hDlg, IDC_REMOVEFILE, FALSE);
  1537. DialogEnable(m_hDlg, IDC_STATIC_DSN, TRUE);
  1538. DialogEnable(m_hDlg, IDC_DSN_COMBO, TRUE);
  1539. DialogEnable(m_hDlg, IDC_STATIC_LOGSET, TRUE);
  1540. DialogEnable(m_hDlg, IDC_LOGSET_COMBO, TRUE);
  1541. bIsValidDataSource = 0 < lstrlen ( m_szSqlDsnName ) && 0 < lstrlen ( m_szSqlLogSetName );
  1542. }
  1543. m_bInitialTimeRangePending = TRUE;
  1544. SetTimeRangeCtrlState( bIsValidDataSource, FALSE );
  1545. }
  1546. DWORD
  1547. CSourcePropPage::BuildLogFileList (
  1548. HWND /*hwndDlg*/,
  1549. LPWSTR szLogFileList,
  1550. ULONG* pulBufLen )
  1551. {
  1552. DWORD dwStatus = ERROR_SUCCESS;
  1553. ULONG ulListLen;
  1554. HWND hwndLogFileList = NULL;
  1555. INT iLogFileCount;
  1556. INT iLogFileIndex;
  1557. PLogItemInfo pInfo = NULL;
  1558. LPCWSTR szThisLogFile = NULL;
  1559. LPWSTR szLogFileCurrent = NULL;
  1560. WCHAR cwComma = L',';
  1561. if ( NULL != pulBufLen ) {
  1562. ulListLen = 0;
  1563. hwndLogFileList = DialogControl(m_hDlg, IDC_LIST_LOGFILENAME);
  1564. if ( NULL != hwndLogFileList ) {
  1565. iLogFileCount = LBNumItems(hwndLogFileList);
  1566. if ( 0 < iLogFileCount ) {
  1567. for ( iLogFileIndex = 0; iLogFileIndex < iLogFileCount; iLogFileIndex++ ) {
  1568. pInfo = (PLogItemInfo)LBData(hwndLogFileList,iLogFileIndex);
  1569. szThisLogFile = pInfo->pszPath;
  1570. ulListLen += (lstrlen(szThisLogFile) + 1);
  1571. }
  1572. ulListLen ++; // for the single final NULL character.
  1573. if ( ulListLen <= *pulBufLen ) {
  1574. if ( NULL != szLogFileList ) {
  1575. ZeroMemory(szLogFileList, (ulListLen * sizeof(WCHAR)));
  1576. szLogFileCurrent = (LPWSTR) szLogFileList;
  1577. for ( iLogFileIndex = 0; iLogFileIndex < iLogFileCount; iLogFileIndex++ ) {
  1578. pInfo = (PLogItemInfo)LBData(hwndLogFileList,iLogFileIndex);
  1579. szThisLogFile = pInfo->pszPath;
  1580. StringCchCopy(szLogFileCurrent, lstrlen(szThisLogFile) + 1, szThisLogFile);
  1581. szLogFileCurrent += lstrlen(szThisLogFile);
  1582. *szLogFileCurrent = L'\0';
  1583. if ( (iLogFileIndex + 1) < iLogFileCount ) {
  1584. // If comma delimited, replace the NULL char with a comma
  1585. *szLogFileCurrent = cwComma;
  1586. }
  1587. szLogFileCurrent ++;
  1588. }
  1589. }
  1590. } else if ( NULL != szLogFileList ) {
  1591. dwStatus = ERROR_MORE_DATA;
  1592. }
  1593. }
  1594. }
  1595. *pulBufLen = ulListLen;
  1596. } else {
  1597. dwStatus = ERROR_INVALID_PARAMETER;
  1598. assert ( FALSE );
  1599. }
  1600. return dwStatus;
  1601. }