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.

1889 lines
48 KiB

  1. /*++
  2. Copyright (C) 1996-1999 Microsoft Corporation
  3. Module Name:
  4. ctrprop.cpp
  5. Abstract:
  6. This file contains the CCounterPropPage class and other routines
  7. to implement the counter property page.
  8. --*/
  9. #include <assert.h>
  10. #include <stdio.h>
  11. #include <math.h>
  12. #include <limits.h>
  13. #include "polyline.h"
  14. #include "ctrprop.h"
  15. #include "utils.h"
  16. #include "unihelpr.h"
  17. #include "winhelpr.h"
  18. #include "visuals.h"
  19. #include "strids.h"
  20. #include "winperf.h"
  21. #include "pdhmsg.h"
  22. #include "globals.h"
  23. #include "browser.h"
  24. #include "smonmsg.h"
  25. #define OWNER_DRAWN_ITEM 2
  26. #define OWNER_DRAW_FOCUS 1
  27. VOID static
  28. HandleSelectionState (
  29. IN LPDRAWITEMSTRUCT lpdis
  30. )
  31. /*++
  32. Routine Description:
  33. HandleSelectionState draws or erases a selection rectangle around an item
  34. in a combo box list.
  35. Arguments:
  36. lpdis - Pointer to DRAWITEMSTRUCT
  37. Return Value:
  38. None.
  39. --*/
  40. {
  41. HBRUSH hbr ;
  42. if ( NULL != lpdis ) {
  43. if (lpdis->itemState & ODS_SELECTED)
  44. hbr = (HBRUSH)GetStockObject(BLACK_BRUSH) ;
  45. else
  46. hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOW)) ;
  47. if ( NULL != hbr ) {
  48. FrameRect(lpdis->hDC, (LPRECT)&lpdis->rcItem, hbr) ;
  49. DeleteObject (hbr) ;
  50. }
  51. }
  52. }
  53. //***************************************************************************
  54. // *
  55. // FUNCTION : HandleFocusState(LPDRAWITEMSTRUCT) *
  56. // *
  57. // PURPOSE : Handle a change in item focus state. If an item gains the *
  58. // input focus, a gray rectangular frame is drawn around that *
  59. // item; if an item loses the input focus, the gray frame is *
  60. // removed. *
  61. // *
  62. // COMMENT : The gray focus frame is slightly smaller than the black *
  63. // selection frame so they won't paint over each other. *
  64. // *
  65. //***************************************************************************
  66. VOID static
  67. HandleFocusState (
  68. IN LPDRAWITEMSTRUCT lpdis
  69. )
  70. /*++
  71. Routine Description:
  72. HandleFocusState draws or erases a focus rectangle around an item in
  73. the pulldown list of a combo box. The reactngle is indented to not
  74. interfere with the selection rectangle.
  75. Arguments:
  76. lpdis - Pointer to DRAWITEMSTRUCT
  77. Return Value:
  78. None.
  79. --*/
  80. {
  81. RECT rc ;
  82. HBRUSH hbr ;
  83. if ( NULL != lpdis ) {
  84. // Resize rectangle to place focus frame between the selection
  85. // frame and the item.
  86. CopyRect ((LPRECT)&rc, (LPRECT)&lpdis->rcItem) ;
  87. InflateRect ((LPRECT)&rc, -OWNER_DRAW_FOCUS, -OWNER_DRAW_FOCUS) ;
  88. // Gray if has focus, background color if not
  89. if (lpdis->itemState & ODS_FOCUS)
  90. hbr = (HBRUSH)GetStockObject(GRAY_BRUSH) ;
  91. else
  92. hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOW)) ;
  93. if ( NULL != hbr ) {
  94. FrameRect(lpdis->hDC, (LPRECT)&rc, hbr) ;
  95. DeleteObject (hbr) ;
  96. }
  97. }
  98. }
  99. CCounterPropPage::CCounterPropPage ( void )
  100. : m_pInfoSel ( NULL ),
  101. m_pInfoDeleted ( NULL ),
  102. m_dwMaxHorizListExtent ( 0 ),
  103. m_nLastSelCount( 0 ),
  104. m_bAreModSelectedVisuals ( FALSE ),
  105. m_fHashTableSetup ( FALSE )
  106. /*++
  107. Routine Description:
  108. Creation routine for counter property page. Initializes the instance
  109. variables.
  110. Arguments:
  111. None.
  112. Return Value:
  113. None.
  114. --*/
  115. {
  116. m_uIDDialog = IDD_CTR_PROPP_DLG;
  117. m_uIDTitle = IDS_CTR_PROPP_TITLE;
  118. return;
  119. }
  120. CCounterPropPage::~CCounterPropPage (
  121. VOID
  122. )
  123. /*++
  124. Routine Description:
  125. Destructor for counter property page.
  126. Arguments:
  127. None.
  128. Return Value:
  129. None.
  130. --*/
  131. {
  132. ClearCountersHashTable();
  133. return;
  134. }
  135. void
  136. CCounterPropPage::DeinitControls ( void )
  137. {
  138. ISystemMonitor *pObj = NULL;
  139. CImpISystemMonitor *pPrivObj = NULL;
  140. HWND hwndList = NULL;
  141. INT iIndex = 0;
  142. INT iItemCnt = 0;
  143. PItemInfo pInfo = NULL;
  144. // Write the current visuals back to the control
  145. // Must be at least one control object and only the first is used
  146. if (m_cObjects != 0) {
  147. pObj = m_ppISysmon[0];
  148. if ( NULL != pObj ) {
  149. pPrivObj = (CImpISystemMonitor*)pObj;
  150. }
  151. }
  152. if ( NULL != pPrivObj ) {
  153. if ( AreModifiedSelectedVisuals() ) {
  154. IncrementLocalVisuals();
  155. }
  156. pPrivObj->SetVisuals(m_props.rgbColor, m_props.iColorIndex, m_props.iWidthIndex, m_props.iStyleIndex);
  157. }
  158. hwndList = DialogControl(m_hDlg, IDC_CTRLIST);
  159. if ( NULL != hwndList ) {
  160. iItemCnt = LBNumItems(hwndList);
  161. for (iIndex = 0; iIndex < iItemCnt; iIndex++ ) {
  162. pInfo = (PItemInfo)LBData(hwndList,iIndex);
  163. if ( NULL != pInfo ) {
  164. DeleteInfo(pInfo);
  165. }
  166. }
  167. }
  168. return;
  169. }
  170. INT
  171. CCounterPropPage::SelectMatchingItem (
  172. INT iColorIndex,
  173. COLORREF rgbCustomColor,
  174. INT iWidthIndex,
  175. INT iStyleIndex)
  176. /*++
  177. Routine Description:
  178. GetMatchingIndex selects the first counter item that matches the
  179. specified visual characteristics.
  180. Arguments:
  181. None.
  182. Return Value:
  183. Returns the index of the selected item on match. If none match, then
  184. returns -1.
  185. --*/
  186. {
  187. INT iReturn = -1;
  188. // Get number of items in list box
  189. HWND hwndList = DialogControl(m_hDlg, IDC_CTRLIST);
  190. INT iItemCnt = LBNumItems(hwndList);
  191. INT i;
  192. bool bMatch = false;
  193. // For each item
  194. for (i=0; !bMatch && i<iItemCnt; i++){
  195. PItemInfo pInfo = (PItemInfo)LBData(hwndList,i);
  196. LoadItemProps ( pInfo );
  197. if ( pInfo->Props.iColorIndex == iColorIndex ) {
  198. if ( NumStandardColorIndices() > iColorIndex ) {
  199. bMatch = true;
  200. } else {
  201. if ( pInfo->Props.rgbColor == rgbCustomColor )
  202. bMatch = true;
  203. }
  204. if ( bMatch ) {
  205. if ( ( iWidthIndex != pInfo->Props.iWidthIndex )
  206. || ( iStyleIndex != pInfo->Props.iStyleIndex ) ){
  207. bMatch = false;
  208. }
  209. }
  210. }
  211. }
  212. if ( bMatch ) {
  213. iReturn = i - 1;
  214. SelectItem ( iReturn );
  215. }
  216. return iReturn;
  217. }
  218. BOOL
  219. CCounterPropPage::GetProperties (
  220. VOID
  221. )
  222. /*++
  223. Routine Description:
  224. GetProperties initializes the dialog box for the property page. It then
  225. fetches an ICounterItem interface for each counter of the control being
  226. edited. Each interface pointer is placed in an ItemInfo structure which is
  227. then added to the dialog list box.
  228. The counter properties are not fetched until they are needed for display.
  229. The first counter fetched is selected to display its properties in the
  230. dialog box.
  231. Arguments:
  232. None.
  233. Return Value:
  234. Boolean status - TRUE = success
  235. --*/
  236. {
  237. ISystemMonitor *pObj = NULL;
  238. CImpISystemMonitor *pPrivObj = NULL;
  239. ICounterItem *pItem;
  240. ICounterItem *pSelectedItem = NULL;
  241. PItemInfo pInfo;
  242. INT nCtr;
  243. INT nSelCtr = LB_ERR;
  244. INT iIndex;
  245. INT nChar;
  246. BOOL bStat = TRUE;
  247. BSTR bstrPath;
  248. HRESULT dwResult;
  249. PPDH_COUNTER_PATH_ELEMENTS pCounter;
  250. InitDialog();
  251. // Must be at least one control object and only the first is used
  252. if (m_cObjects == 0) {
  253. bStat = FALSE;
  254. } else {
  255. pObj = m_ppISysmon[0];
  256. if ( NULL != pObj ) {
  257. pPrivObj = (CImpISystemMonitor*)pObj;
  258. }
  259. }
  260. if ( bStat && NULL != pObj && NULL != pPrivObj ) {
  261. // Request each counter from the control, stopping on failure
  262. nCtr = 0;
  263. pPrivObj->GetSelectedCounter( &pSelectedItem );
  264. while (SUCCEEDED(pObj->Counter(nCtr, &pItem))) {
  265. // Create ItemInfo to hold the counter
  266. pInfo = new ItemInfo;
  267. if (pInfo == NULL) {
  268. bStat = FALSE;
  269. break;
  270. }
  271. ZeroMemory(pInfo, sizeof(ItemInfo));
  272. pInfo->pItem = pItem;
  273. pItem->get_Path( &bstrPath );
  274. if (bstrPath != NULL) {
  275. nChar = lstrlen(bstrPath) + 1;
  276. pInfo->pszPath = new WCHAR [nChar];
  277. if (pInfo->pszPath == NULL) {
  278. delete pInfo;
  279. pInfo = NULL;
  280. SysFreeString(bstrPath);
  281. bStat = FALSE;
  282. break;
  283. }
  284. StringCchCopy(pInfo->pszPath, nChar, bstrPath);
  285. SysFreeString(bstrPath);
  286. }
  287. dwResult = InsertCounterToHashTable(pInfo->pszPath, &pCounter);
  288. if (dwResult == ERROR_SUCCESS) {
  289. //
  290. // Add the counter to the list box
  291. //
  292. iIndex = AddItemToList(pInfo);
  293. if ( LB_ERR == iIndex ) {
  294. RemoveCounterFromHashTable(pInfo->pszPath, pCounter);
  295. bStat = FALSE;
  296. DeleteInfo(pInfo);
  297. pInfo = NULL;
  298. break;
  299. } else {
  300. pInfo->pCounter = pCounter;
  301. if ( pSelectedItem == pItem ) {
  302. nSelCtr = iIndex;
  303. }
  304. }
  305. }
  306. else {
  307. bStat = FALSE;
  308. DeleteInfo(pInfo);
  309. pInfo = NULL;
  310. break;
  311. }
  312. nCtr++;
  313. }
  314. if ( NULL != pSelectedItem ) {
  315. pSelectedItem->Release();
  316. }
  317. // Get the current visuals fron the control
  318. // and initialize the property dialog
  319. pPrivObj->GetVisuals(&m_props.rgbColor, &m_props.iColorIndex, &m_props.iWidthIndex, &m_props.iStyleIndex);
  320. // If a counter matches the selected counter, select that item.
  321. // Else if the visuals match an existing item, select that item.
  322. // Else if there is at least one counter in the control, select the first counter.
  323. // Otherwise, set the display properties to the first counter to be added.
  324. if ( LB_ERR != nSelCtr ) {
  325. SelectItem ( nSelCtr );
  326. } else {
  327. if ( LB_ERR == SelectMatchingItem (
  328. m_props.iColorIndex,
  329. m_props.rgbColor,
  330. m_props.iWidthIndex,
  331. m_props.iStyleIndex ) )
  332. {
  333. if ( 0 < nCtr ) {
  334. SelectItem ( 0 );
  335. } else {
  336. // Init the scale factor to the default
  337. m_props.iScaleIndex = 0;
  338. // If nothing selected, ensure that the color index is set to
  339. // a standard color.
  340. if ( m_props.iColorIndex == NumStandardColorIndices() ) {
  341. m_props.iColorIndex -= 1;
  342. }
  343. CBSetSelection(DialogControl(m_hDlg, IDC_LINECOLOR), m_props.iColorIndex);
  344. CBSetSelection(DialogControl(m_hDlg, IDC_LINEWIDTH), m_props.iWidthIndex);
  345. CBSetSelection(DialogControl(m_hDlg, IDC_LINESTYLE), m_props.iStyleIndex);
  346. CBSetSelection(DialogControl(m_hDlg, IDC_LINESCALE), m_props.iScaleIndex);
  347. SetStyleComboEnable();
  348. }
  349. }
  350. }
  351. }
  352. return bStat;
  353. }
  354. INT
  355. CCounterPropPage::AddItemToList (
  356. IN PItemInfo pInfo
  357. )
  358. /*++
  359. Routine Description:
  360. AddItemToList adds a counter's path name to the dialog list box and
  361. attaches a pointer to the counter's ItemInfo structure as item data.
  362. It also adjusts the horizontal scroll of the list box.
  363. Arguments:
  364. pInfo - Pointer to counter's ItemInfo structure
  365. Return Value:
  366. List box index of added counter (LB_ERR on failure)
  367. --*/
  368. {
  369. INT iIndex;
  370. HWND hwndList = DialogControl(m_hDlg, IDC_CTRLIST);
  371. DWORD dwItemExtent = 0;
  372. HDC hDC = NULL;
  373. iIndex = (INT)LBAdd(hwndList, pInfo->pszPath);
  374. if ( LB_ERR != iIndex && LB_ERRSPACE != iIndex ) {
  375. LBSetData(hwndList, iIndex, pInfo);
  376. hDC = GetDC ( hwndList );
  377. if ( NULL != hDC ) {
  378. dwItemExtent = (DWORD)TextWidth ( hDC, pInfo->pszPath );
  379. if (dwItemExtent > m_dwMaxHorizListExtent) {
  380. m_dwMaxHorizListExtent = dwItemExtent;
  381. LBSetHorzExtent ( hwndList, dwItemExtent );
  382. }
  383. ReleaseDC (hwndList, hDC) ;
  384. }
  385. } else {
  386. iIndex = LB_ERR ;
  387. }
  388. return iIndex;
  389. }
  390. VOID
  391. CCounterPropPage::LoadItemProps (
  392. IN PItemInfo pInfo
  393. )
  394. /*++
  395. Routine Description:
  396. LoadItemProps loads the properties of the selected counter through the
  397. counter's interface into the ItemInfo structure, if not already loaded.
  398. Arguments:
  399. pInfo - pointer to item info
  400. Return Value:
  401. None.
  402. --*/
  403. {
  404. // If properties not loaded for this item, get them now
  405. if (pInfo->pItem && !pInfo->fLoaded) {
  406. INT iScaleFactor;
  407. INT iStyle;
  408. INT iWidth;
  409. pInfo->pItem->get_Color ( &pInfo->Props.rgbColor );
  410. pInfo->pItem->get_ScaleFactor ( &iScaleFactor );
  411. pInfo->pItem->get_Width ( &iWidth );
  412. pInfo->pItem->get_LineStyle ( &iStyle );
  413. // Translate to combo box indices
  414. pInfo->Props.iColorIndex = ColorToIndex ( pInfo->Props.rgbColor );
  415. pInfo->Props.iStyleIndex = StyleToIndex ( iStyle );
  416. pInfo->Props.iWidthIndex = WidthToIndex ( iWidth );
  417. pInfo->Props.iScaleIndex = ScaleFactorToIndex ( iScaleFactor );
  418. pInfo->fLoaded = TRUE;
  419. }
  420. return;
  421. }
  422. VOID
  423. CCounterPropPage::DisplayItemProps (
  424. IN PItemInfo pInfo
  425. )
  426. /*++
  427. Routine Description:
  428. DisplayItemProps displays the properties of the selected counter on the
  429. property page dialog. If the counter is being displayed for the first time
  430. the properties are obtained through the counter's interface and are loaded
  431. into the ItemInfo structure.
  432. Arguments:
  433. pInfo - pointer to item info
  434. Return Value:
  435. None.
  436. --*/
  437. {
  438. // Get number of items in color combo box
  439. HWND hWndColor = DialogControl(m_hDlg, IDC_LINECOLOR);
  440. INT iCurrentColorCnt = CBNumItems(hWndColor);
  441. // If properties not loaded for this item, get them now
  442. LoadItemProps ( pInfo );
  443. // Display the properties
  444. m_props = pInfo->Props;
  445. // Handle custom color
  446. if ( iCurrentColorCnt > NumStandardColorIndices() ) {
  447. // Delete the custom color item. It is stored at
  448. // the end of the list.
  449. CBDelete(hWndColor, iCurrentColorCnt - 1);
  450. }
  451. // If new custom color, add it at the end of the list.
  452. if ( NumStandardColorIndices() == m_props.iColorIndex )
  453. CBAdd( hWndColor, (INT_PTR)m_props.iColorIndex );
  454. CBSetSelection(hWndColor, m_props.iColorIndex);
  455. CBSetSelection(DialogControl(m_hDlg, IDC_LINEWIDTH), m_props.iWidthIndex);
  456. CBSetSelection(DialogControl(m_hDlg, IDC_LINESTYLE), m_props.iStyleIndex);
  457. CBSetSelection(DialogControl(m_hDlg, IDC_LINESCALE), m_props.iScaleIndex);
  458. SetStyleComboEnable();
  459. }
  460. BOOL
  461. CCounterPropPage::SetProperties (
  462. VOID
  463. )
  464. /*++
  465. Routine Description:
  466. SetProperties applies the counter changes the user has made. It calls the
  467. control's AddCounter and DeleteCounter to adjust the counter set. It calls
  468. the counter's property functions for all new and changed counters.
  469. The counters to be deleted are in the pInfoDeleted linked list. The other
  470. counters are obtained from the dialog list box.
  471. Arguments:
  472. None.
  473. Return Value:
  474. Boolean status - TRUE = success
  475. --*/
  476. {
  477. HWND hwndList;
  478. INT iItemCnt;
  479. INT i;
  480. PItemInfo pInfo, pInfoNext;
  481. ISystemMonitor *pObj;
  482. BSTR pBstr = NULL;
  483. // Apply changes to first control
  484. pObj = m_ppISysmon[0];
  485. if ( NULL != pObj ) {
  486. // For all items in the delete list
  487. pInfo = m_pInfoDeleted;
  488. while (pInfo) {
  489. // If this counter exists in the control
  490. if (pInfo->pItem != NULL) {
  491. // Tell control to remove it
  492. pObj->DeleteCounter(pInfo->pItem);
  493. }
  494. // Delete the Info structure and point to the next one
  495. pInfoNext = pInfo->pNextInfo;
  496. DeleteInfo(pInfo);
  497. pInfo = pInfoNext;
  498. }
  499. m_pInfoDeleted = NULL;
  500. // Get number of items in list box
  501. hwndList = DialogControl(m_hDlg, IDC_CTRLIST);
  502. iItemCnt = LBNumItems(hwndList);
  503. //assert( IsWindowUnicode(hwndList) );
  504. // For each item
  505. for (i=0; i<iItemCnt; i++) {
  506. pInfo = (PItemInfo)LBData(hwndList,i);
  507. // If new item, create it now
  508. if (pInfo->pItem == NULL) {
  509. #if UNICODE
  510. pBstr = SysAllocString(pInfo->pszPath);
  511. pObj->AddCounter(pBstr, &pInfo->pItem);
  512. #else
  513. INT nChar = lstrlen(pInfo->pszPath);
  514. LPWSTR pszPathW = new WCHAR [nChar + 1];
  515. if (pszPathW) {
  516. MultiByteToWideChar(CP_ACP, 0, pInfo->pszPath, nChar+1, pszPathW, nChar+1);
  517. pBstr = SysAllocString(pInfo->pszPath);
  518. pObj->AddCounter(pBstr, &pInfo->pItem);
  519. delete [] pszPathW;
  520. }
  521. #endif
  522. if (pBstr) {
  523. SysFreeString(pBstr);
  524. }
  525. }
  526. // If item has changed, put the new properties
  527. if (pInfo->pItem != NULL && pInfo->fChanged) {
  528. // iColorIndex is used to determine standard colors.
  529. if ( pInfo->Props.iColorIndex < NumStandardColorIndices() ) {
  530. pInfo->pItem->put_Color(IndexToStandardColor( pInfo->Props.iColorIndex) );
  531. } else {
  532. pInfo->pItem->put_Color(pInfo->Props.rgbColor);
  533. }
  534. pInfo->pItem->put_Width(IndexToWidth(pInfo->Props.iWidthIndex));
  535. pInfo->pItem->put_LineStyle(IndexToStyle(pInfo->Props.iStyleIndex));
  536. pInfo->pItem->put_ScaleFactor(IndexToScaleFactor( pInfo->Props.iScaleIndex ) );
  537. pInfo->fChanged = FALSE;
  538. }
  539. }
  540. // Tell graph to redraw itself
  541. pObj->UpdateGraph();
  542. } // else report internal error
  543. return TRUE;
  544. }
  545. VOID
  546. CCounterPropPage::InitDialog (
  547. VOID
  548. )
  549. /*++
  550. Routine Description:
  551. InitDialog loads each attribute combo box with its list of choices and
  552. selects the default choice. The graphical attributes are owner drawn, so
  553. their list items are just set to numerical indices. The scale attribute
  554. list is filled with numeric strings representing scale factors plus a
  555. default selection.
  556. Arguments:
  557. None.
  558. Return Value:
  559. None.
  560. --*/
  561. {
  562. HWND hWndColors;
  563. HWND hWndWidths;
  564. HWND hWndStyles;
  565. HWND hWndScales;
  566. INT i ;
  567. double ScaleFactor ;
  568. WCHAR tempBuff[MAX_VALUE_LEN] ;
  569. if (m_hDlg == NULL)
  570. return;
  571. //assert( IsWindowUnicode( m_hDlg ) );
  572. // Load the colors combobox, select the default color.
  573. hWndColors = DialogControl (m_hDlg, IDC_LINECOLOR) ;
  574. for (i = 0 ; i < NumStandardColorIndices () ; i++)
  575. CBAdd (hWndColors, (INT_PTR)1); // string pointer is unused. Fill with
  576. // arbitrary value.
  577. CBSetSelection (hWndColors, 0) ;
  578. // Load the widths combo box, select the default width.
  579. hWndWidths = DialogControl (m_hDlg, IDC_LINEWIDTH) ;
  580. for (i = 0 ; i < NumWidthIndices () ; i++)
  581. CBAdd (hWndWidths, (INT_PTR)1) ;
  582. CBSetSelection (hWndWidths, 0) ;
  583. // Load the styles combo box, select the default style.
  584. hWndStyles = DialogControl (m_hDlg, IDC_LINESTYLE) ;
  585. for (i = 0 ; i < NumStyleIndices () ; i++)
  586. CBAdd (hWndStyles, (INT_PTR)1) ;
  587. CBSetSelection (hWndStyles, 0) ;
  588. // Init the scale combo box.
  589. hWndScales = DialogControl (m_hDlg, IDC_LINESCALE) ;
  590. CBAdd (hWndScales, ResourceString(IDS_DEFAULT)) ;
  591. // Generate power of 10 scale factors
  592. ScaleFactor = pow (10.0f, (double)PDH_MIN_SCALE);
  593. for (i = PDH_MIN_SCALE ; i <= PDH_MAX_SCALE ; i++) {
  594. FormatNumber (
  595. ScaleFactor,
  596. tempBuff,
  597. MAX_VALUE_LEN,
  598. (i <= 0 ? (-1 * i) + 1 : i + 1),
  599. (i < 0 ? (-1 * i) : 1) );
  600. CBAdd (hWndScales, tempBuff) ;
  601. ScaleFactor *= (double) 10.0f ;
  602. }
  603. CBSetSelection (hWndScales, 0) ;
  604. ClearCountersHashTable();
  605. DialogEnable(m_hDlg, IDC_LINECOLOR, FALSE);
  606. DialogEnable(m_hDlg, IDC_LINEWIDTH, FALSE);
  607. DialogEnable(m_hDlg, IDC_LINESTYLE, FALSE);
  608. DialogEnable(m_hDlg, IDC_LINESCALE, FALSE);
  609. }
  610. void
  611. CCounterPropPage::IncrementLocalVisuals (
  612. void
  613. )
  614. {
  615. // Increment the visual indices in color, width, style order
  616. if (++m_props.iColorIndex >= NumStandardColorIndices()) {
  617. m_props.iColorIndex = 0;
  618. if (++m_props.iWidthIndex >= NumWidthIndices()) {
  619. m_props.iWidthIndex = 0;
  620. if (++m_props.iStyleIndex < NumStyleIndices()) {
  621. m_props.iStyleIndex = 0;
  622. }
  623. }
  624. }
  625. SetModifiedSelectedVisuals ( FALSE );
  626. return;
  627. }
  628. HRESULT
  629. CCounterPropPage::NewItem (
  630. IN LPWSTR pszPath,
  631. IN DWORD /* dwFlags */
  632. )
  633. /*++
  634. Routine Description:
  635. NewItem adds a new counter to the dialog's counter list box. It first
  636. creates a new ItemInfo structure and loads it with the counter pathname
  637. string. Then the ItemInfo is added to the dialog list box.
  638. Arguments:
  639. pszPath - Pointer to counter pathname string
  640. fGenerated - TRUE if path was generated from a wildcard path
  641. Return Value:
  642. Index of new item in counter list (-1 if failed to add)
  643. --*/
  644. {
  645. PItemInfo pInfo;
  646. HRESULT dwResult;
  647. BOOL bRet;
  648. PPDH_COUNTER_PATH_ELEMENTS pCounter;
  649. dwResult = InsertCounterToHashTable(pszPath, &pCounter);
  650. if (dwResult != ERROR_SUCCESS) {
  651. return dwResult;
  652. }
  653. // Allocate ItemInfo structure
  654. pInfo = NULL;
  655. pInfo = new ItemInfo;
  656. if (pInfo == NULL) {
  657. bRet = RemoveCounterFromHashTable(pszPath, pCounter);
  658. assert(bRet);
  659. return E_OUTOFMEMORY;
  660. }
  661. // Mark as loaded to prevent requesting attributes from control
  662. // Mark as changed so sttribute will be written
  663. pInfo->fLoaded = TRUE;
  664. pInfo->fChanged = TRUE;
  665. // Actual counter doesn't exist yet
  666. pInfo->pItem = NULL;
  667. // If a counter is selected, we're showing its visuals
  668. // so increment them for the new counter
  669. if (m_pInfoSel != NULL) {
  670. IncrementLocalVisuals();
  671. }
  672. else {
  673. // Point to the new item so the visuals are incremented
  674. // for the next one
  675. m_pInfoSel = pInfo;
  676. }
  677. // Set default scaling
  678. m_props.iScaleIndex = 0;
  679. // Color is non-standard only if user is able to build a color.
  680. if( m_props.iColorIndex < NumStandardColorIndices() )
  681. m_props.rgbColor = IndexToStandardColor( m_props.iColorIndex );
  682. else
  683. m_props.rgbColor = pInfo->Props.rgbColor;
  684. // Copy properties to new counter
  685. pInfo->Props = m_props;
  686. // Make own copy of path name string
  687. pInfo->pszPath = new WCHAR [lstrlen(pszPath) + 1];
  688. if (pInfo->pszPath == NULL)
  689. {
  690. bRet = RemoveCounterFromHashTable(pszPath, pCounter);
  691. assert(bRet);
  692. delete pInfo;
  693. return E_OUTOFMEMORY;
  694. }
  695. StringCchCopy(pInfo->pszPath, lstrlen(pszPath) + 1, pszPath);
  696. // Add to dialog's counter list
  697. pInfo->pCounter = pCounter;
  698. m_iAddIndex = AddItemToList(pInfo);
  699. return S_OK;
  700. }
  701. VOID
  702. CCounterPropPage::SelectItem (
  703. IN INT iItem
  704. )
  705. /*++
  706. Routine Description:
  707. SelectItem selects a specified counter item in the dialog counter list.
  708. It then displays the selected counter's properties and enables the
  709. "Delete Counter" button.
  710. SelectItem can be called with a -1 to deselect all counters and disable
  711. the delete button.
  712. The member variable, m_pInfoSel, is updated to point to the selected
  713. counter info.
  714. Arguments:
  715. iItem - List index of counter item to select, or -1 to deselect all
  716. Return Value:
  717. None.
  718. --*/
  719. {
  720. HWND hWnd;
  721. hWnd = DialogControl(m_hDlg, IDC_CTRLIST);
  722. // Translate index into item pointer
  723. if (iItem == -1) {
  724. m_pInfoSel = NULL;
  725. }
  726. else {
  727. m_pInfoSel = (PItemInfo)LBData(hWnd, iItem);
  728. if ((INT_PTR)m_pInfoSel == LB_ERR)
  729. m_pInfoSel = NULL;
  730. }
  731. // Select the item, display properties, and enable delete button
  732. if (m_pInfoSel != NULL) {
  733. INT nSelCount;
  734. LBSetSel(hWnd, TRUE, iItem);
  735. nSelCount = LBSelectCount(hWnd);
  736. if (nSelCount == 1) {
  737. DialogEnable(m_hDlg, IDC_LINECOLOR, TRUE);
  738. DialogEnable(m_hDlg, IDC_LINEWIDTH, TRUE);
  739. DialogEnable(m_hDlg, IDC_LINESTYLE, TRUE);
  740. DialogEnable(m_hDlg, IDC_LINESCALE, TRUE);
  741. }
  742. else {
  743. DialogEnable(m_hDlg, IDC_LINECOLOR, FALSE);
  744. DialogEnable(m_hDlg, IDC_LINEWIDTH, FALSE);
  745. DialogEnable(m_hDlg, IDC_LINESTYLE, FALSE);
  746. DialogEnable(m_hDlg, IDC_LINESCALE, FALSE);
  747. }
  748. m_nLastSelCount = nSelCount;
  749. DisplayItemProps(m_pInfoSel);
  750. DialogEnable(m_hDlg,IDC_DELCTR,1);
  751. }
  752. else {
  753. LBSetSel(hWnd, FALSE, -1);
  754. DialogEnable(m_hDlg,IDC_DELCTR, 0);
  755. DialogEnable(m_hDlg, IDC_LINECOLOR, FALSE);
  756. DialogEnable(m_hDlg, IDC_LINEWIDTH, FALSE);
  757. DialogEnable(m_hDlg, IDC_LINESTYLE, FALSE);
  758. DialogEnable(m_hDlg, IDC_LINESCALE, FALSE);
  759. m_nLastSelCount = 0;
  760. }
  761. }
  762. VOID
  763. CCounterPropPage::DeleteItem (
  764. VOID
  765. )
  766. /*++
  767. Routine Description:
  768. DeleteItem removes the currently selected counter from the dialog's counter
  769. listbox. It adds the item to the deletion list, so the actual counter can
  770. be deleted from the control when (and if) the changes are applied.
  771. The routine selects selects the next counter in the listbox if there is one.
  772. Arguments:
  773. None.
  774. Return Value:
  775. None.
  776. --*/
  777. {
  778. HWND hWnd;
  779. INT iIndex;
  780. PItemInfo pInfo;
  781. DWORD dwItemExtent = 0;
  782. HDC hDC = NULL;
  783. INT iStartIndex;
  784. INT iEndIndex;
  785. INT iSelectCount;
  786. INT iItemCount;
  787. INT iOrigCaret;
  788. // Get selected index
  789. hWnd = DialogControl(m_hDlg, IDC_CTRLIST);
  790. iSelectCount = LBSelectCount(hWnd);
  791. if (iSelectCount <= 0 ) {
  792. return;
  793. }
  794. else {
  795. iEndIndex = 0;
  796. iStartIndex = LBNumItems(hWnd) - 1;
  797. }
  798. //
  799. // We scan the whole list box to remove items
  800. // May use LB_GETSELITEMS (did not compare the performance)?
  801. //
  802. iOrigCaret = LBFocus(hWnd);
  803. for (iIndex = iStartIndex; iIndex >= iEndIndex; iIndex--) {
  804. if (!LBSelected(hWnd, iIndex)) {
  805. continue;
  806. }
  807. // Get selected item info
  808. pInfo = (PItemInfo)LBData(hWnd, iIndex);
  809. // Move it to the "Deleted" list.
  810. pInfo->pNextInfo = m_pInfoDeleted;
  811. m_pInfoDeleted = pInfo;
  812. // Remove the string from the list box.
  813. LBDelete(hWnd, iIndex);
  814. // Remove the counter from hash table
  815. RemoveCounterFromHashTable(pInfo->pszPath, pInfo->pCounter);
  816. }
  817. //
  818. // see how many entries are left and update the
  819. // caret position and the remove button state
  820. //
  821. iItemCount = LBNumItems(hWnd);
  822. if (iItemCount > 0) {
  823. // the update the caret
  824. if (iOrigCaret >= iItemCount) {
  825. iOrigCaret = iItemCount-1;
  826. } else {
  827. // caret should be within the list
  828. }
  829. SelectItem(iOrigCaret);
  830. } else {
  831. // the list is empty so remove caret, selection
  832. // disable the remove button and activate the
  833. // add button
  834. SelectItem(-1);
  835. }
  836. // Clear the max horizontal extent and recalculate
  837. m_dwMaxHorizListExtent = 0;
  838. hDC = GetDC ( hWnd );
  839. if ( NULL != hDC ) {
  840. for ( iIndex = 0; iIndex < (INT)LBNumItems ( hWnd ); iIndex++ ) {
  841. pInfo = (PItemInfo)LBData(hWnd, iIndex);
  842. dwItemExtent = (DWORD)TextWidth ( hDC, pInfo->pszPath );
  843. if (dwItemExtent > m_dwMaxHorizListExtent) {
  844. m_dwMaxHorizListExtent = dwItemExtent;
  845. }
  846. }
  847. ReleaseDC (hWnd, hDC) ;
  848. }
  849. LBSetHorzExtent ( hWnd, m_dwMaxHorizListExtent );
  850. // Set change flag to enable "Apply" button
  851. SetChange();
  852. }
  853. static HRESULT
  854. AddCallback (
  855. LPWSTR pszPathName,
  856. DWORD_PTR lpUserData,
  857. DWORD dwFlags
  858. )
  859. {
  860. CCounterPropPage* pObj = (CCounterPropPage*)lpUserData;
  861. return pObj->NewItem(pszPathName, dwFlags);
  862. }
  863. VOID
  864. CCounterPropPage::AddCounters (
  865. VOID
  866. )
  867. /*++
  868. Routine Description:
  869. AddCounters invokes the counter browser to select new counters.
  870. The browser calls the AddCallback function for each new counter.
  871. AddCallback passes the counter path on to the NewItem method.
  872. Arguments:
  873. None.
  874. Return Value:
  875. None.
  876. --*/
  877. {
  878. HRESULT hr = NOERROR;
  879. HLOG hDataSource;
  880. VARIANT_BOOL bMonitorDuplicateInstances = FALSE;
  881. ISystemMonitor *pObj = m_ppISysmon[0];
  882. CImpISystemMonitor *pPrivObj;
  883. eDataSourceTypeConstant eDataSource = sysmonNullDataSource;
  884. USES_CONVERSION
  885. pPrivObj = (CImpISystemMonitor*)pObj;
  886. m_iAddIndex = -1;
  887. // Browse counters (calling AddCallack for each selected counter)
  888. hr = pObj->get_MonitorDuplicateInstances(&bMonitorDuplicateInstances);
  889. if (SUCCEEDED(hr)) {
  890. hr = pObj->get_DataSourceType(& eDataSource);
  891. }
  892. if (SUCCEEDED(hr)) {
  893. // Cannot call pObj->BrowseCounter() because using callback method
  894. // private to this file.
  895. if ( sysmonLogFiles == eDataSource
  896. || sysmonSqlLog == eDataSource ) {
  897. hDataSource = pPrivObj->GetDataSourceHandle();
  898. assert ( NULL != hDataSource );
  899. } else {
  900. hDataSource = H_REALTIME_DATASOURCE;
  901. }
  902. if (SUCCEEDED(hr)) {
  903. BrowseCounters(
  904. hDataSource,
  905. PERF_DETAIL_WIZARD,
  906. m_hDlg,
  907. AddCallback,
  908. (LPVOID) this,
  909. (BOOL) bMonitorDuplicateInstances);
  910. }
  911. } else {
  912. // Todo: Error message
  913. }
  914. // if any items added, select the last one
  915. if (m_iAddIndex != -1) {
  916. SelectItem(-1);
  917. SelectItem(m_iAddIndex);
  918. m_iAddIndex = -1;
  919. // Set change to enable "Apply" button
  920. SetChange();
  921. }
  922. return;
  923. }
  924. VOID
  925. CCounterPropPage::DialogItemChange (
  926. IN WORD wId,
  927. IN WORD wMsg
  928. )
  929. /*++
  930. Routine Description:
  931. DialogItemChange processes window messages sent to any of the property
  932. page dialog controls. When the counter listbox selection changes, it
  933. selects the new counter item and displays its properties. When a change is
  934. made to a property combo box, it updates the property for the currently
  935. selected counter item. When the add or delete counter button is pressed,
  936. it calls the appropriate property page functions.
  937. Arguments:
  938. wID - Dialog control ID
  939. wMsg - Notification code
  940. Return Value:
  941. None.
  942. --*/
  943. {
  944. INT iIndex;
  945. INT iNewProp;
  946. HWND hWnd;
  947. // Case on control ID
  948. switch (wId) {
  949. case IDC_CTRLIST:
  950. // If selection changed
  951. if (wMsg == LBN_SELCHANGE) {
  952. INT nSelCount;
  953. // Get selected index
  954. hWnd = DialogControl(m_hDlg, IDC_CTRLIST);
  955. nSelCount = LBSelectCount(hWnd);
  956. if (nSelCount == 1) {
  957. if (m_nLastSelCount != 1) {
  958. DialogEnable(m_hDlg, IDC_LINECOLOR, TRUE);
  959. DialogEnable(m_hDlg, IDC_LINEWIDTH, TRUE);
  960. DialogEnable(m_hDlg, IDC_LINESTYLE, TRUE);
  961. DialogEnable(m_hDlg, IDC_LINESCALE, TRUE);
  962. }
  963. if (LBGetSelItems(hWnd, 1, &iIndex) == 1) {
  964. m_pInfoSel = (PItemInfo)LBData(hWnd, iIndex);
  965. DisplayItemProps(m_pInfoSel);
  966. DialogEnable(m_hDlg, IDC_DELCTR, 1);
  967. }
  968. }
  969. else {
  970. DialogEnable(m_hDlg, IDC_LINECOLOR, FALSE);
  971. DialogEnable(m_hDlg, IDC_LINEWIDTH, FALSE);
  972. DialogEnable(m_hDlg, IDC_LINESTYLE, FALSE);
  973. DialogEnable(m_hDlg, IDC_LINESCALE, FALSE);
  974. }
  975. m_nLastSelCount = nSelCount;
  976. }
  977. break;
  978. case IDC_LINECOLOR:
  979. case IDC_LINEWIDTH:
  980. case IDC_LINESTYLE:
  981. case IDC_LINESCALE:
  982. // If selection changed and a counter is selected
  983. if (wMsg == CBN_SELCHANGE) {
  984. hWnd = DialogControl(m_hDlg, wId);
  985. iNewProp = (INT)CBSelection(hWnd);
  986. // Store the new property selection
  987. switch (wId) {
  988. case IDC_LINECOLOR:
  989. m_props.iColorIndex = iNewProp;
  990. // If iColorIndex is for the custom color, the
  991. // custom color is already set in the properties.
  992. break;
  993. case IDC_LINEWIDTH:
  994. m_props.iWidthIndex = iNewProp;
  995. SetStyleComboEnable();
  996. break;
  997. case IDC_LINESTYLE:
  998. m_props.iStyleIndex = iNewProp;
  999. break;
  1000. case IDC_LINESCALE:
  1001. m_props.iScaleIndex = iNewProp;
  1002. break;
  1003. }
  1004. // If counter is selected, update its properties
  1005. if (m_pInfoSel != NULL) {
  1006. m_pInfoSel->Props = m_props;
  1007. // mark the counter as changed
  1008. m_pInfoSel->fChanged = TRUE;
  1009. SetChange();
  1010. SetModifiedSelectedVisuals( TRUE );
  1011. }
  1012. }
  1013. break;
  1014. case IDC_ADDCTR:
  1015. // Invoke counter browser to add to counter
  1016. AddCounters();
  1017. break;
  1018. case IDC_DELCTR:
  1019. // Delete the currently selected counter
  1020. DeleteItem();
  1021. break;
  1022. }
  1023. }
  1024. VOID
  1025. CCounterPropPage::MeasureItem (
  1026. OUT PMEASUREITEMSTRUCT pMI
  1027. )
  1028. {
  1029. pMI->CtlType = ODT_COMBOBOX ;
  1030. pMI->CtlID = IDC_LINECOLOR ;
  1031. pMI->itemData = 0 ;
  1032. pMI->itemWidth = 0 ;
  1033. pMI->itemHeight = 14 ;
  1034. }
  1035. VOID
  1036. CCounterPropPage::DrawItem (
  1037. IN PDRAWITEMSTRUCT pDI
  1038. )
  1039. /*++
  1040. Routine Description:
  1041. DrawItem draws a specified item in one of the graphical property combo
  1042. boxes. It is called to process WM_DRAWITEM messages.
  1043. Arguments:
  1044. pDI - Pointer to DRAWITEMSTRUCT
  1045. Return Value:
  1046. None.
  1047. --*/
  1048. {
  1049. HDC hDC ;
  1050. PRECT prect ;
  1051. INT itemID,
  1052. CtlID,
  1053. itemAction ;
  1054. HPEN hPen;
  1055. COLORREF rgbBk, rgbOldBk;
  1056. if ( NULL != pDI ) {
  1057. hDC = pDI->hDC ;
  1058. CtlID = pDI->CtlID ;
  1059. prect = &pDI->rcItem ;
  1060. itemID = pDI->itemID ;
  1061. itemAction = pDI->itemAction ;
  1062. // Case on drawing request
  1063. switch (itemAction) {
  1064. case ODA_SELECT:
  1065. // Draw/erase selection rect
  1066. HandleSelectionState(pDI);
  1067. break;
  1068. case ODA_FOCUS:
  1069. // Draw/erase focus rect
  1070. HandleFocusState (pDI);
  1071. break;
  1072. case ODA_DRAWENTIRE:
  1073. // Leave border space for focus rectangle
  1074. InflateRect (prect, -OWNER_DRAWN_ITEM, -OWNER_DRAWN_ITEM) ;
  1075. // Case on Control ID
  1076. switch (CtlID) {
  1077. case IDC_LINECOLOR:
  1078. // Draw filled rect of item's color
  1079. if ( itemID < NumStandardColorIndices() )
  1080. Fill(hDC, IndexToStandardColor(itemID), prect);
  1081. else
  1082. // Custom color item only exists if the currently
  1083. // selected item has a custom color defined.
  1084. Fill(hDC, m_pInfoSel->Props.rgbColor, prect);
  1085. break ;
  1086. case IDC_LINEWIDTH:
  1087. case IDC_LINESTYLE:
  1088. // Clear the item's area
  1089. rgbBk = GetSysColor(COLOR_WINDOW);
  1090. Fill(hDC, rgbBk, prect);
  1091. // Draw centered line showing item's width or style
  1092. if (CtlID == IDC_LINEWIDTH)
  1093. hPen = CreatePen (PS_SOLID, IndexToWidth(itemID), RGB (0,0,0));
  1094. else
  1095. hPen = CreatePen (IndexToStyle(itemID), 1, RGB (0,0,0));
  1096. if ( NULL != hPen ) {
  1097. // Set background to insure dashed lines show properly
  1098. rgbOldBk = SetBkColor (hDC, rgbBk) ;
  1099. if ( CLR_INVALID != rgbOldBk ) {
  1100. Line(hDC, (HPEN)hPen, prect->left + 8,
  1101. (prect->top + prect->bottom) / 2,
  1102. prect->right - 8,
  1103. (prect->top + prect->bottom) / 2);
  1104. SetBkColor (hDC, rgbOldBk) ;
  1105. }
  1106. DeleteObject (hPen) ;
  1107. }
  1108. break ;
  1109. }
  1110. // Restore original rect and draw focus/select rects
  1111. InflateRect (prect, OWNER_DRAWN_ITEM, OWNER_DRAWN_ITEM) ;
  1112. HandleSelectionState (pDI) ;
  1113. HandleFocusState (pDI) ;
  1114. }
  1115. }
  1116. }
  1117. INT
  1118. CCounterPropPage::ScaleFactorToIndex (
  1119. IN INT iScaleFactor
  1120. )
  1121. /*++
  1122. Routine Description:
  1123. ScaleFactorToIndex translates a CounterItem ScaleFactor value to
  1124. the appropriate scale factor combo box index.
  1125. Arguments:
  1126. iScaleFactor - CounterItem scale factor integer value.
  1127. Return Value:
  1128. Scale factor combo box index.
  1129. --*/
  1130. {
  1131. INT retValue;
  1132. if ( INT_MAX == iScaleFactor ) {
  1133. retValue = 0;
  1134. } else {
  1135. retValue = iScaleFactor - PDH_MIN_SCALE + 1;
  1136. }
  1137. return retValue;
  1138. }
  1139. INT
  1140. CCounterPropPage::IndexToScaleFactor (
  1141. IN INT iScaleIndex
  1142. )
  1143. /*++
  1144. Routine Description:
  1145. ScaleFactorToIndex translates a CounterItem ScaleFactor value to
  1146. the appropriate scale factor combo box index.
  1147. Arguments:
  1148. iScaleIndex - Scale factor combo box index.
  1149. Return Value:
  1150. CounterItem scale factor integer value.
  1151. --*/
  1152. {
  1153. INT retValue;
  1154. if ( 0 == iScaleIndex ) {
  1155. retValue = INT_MAX;
  1156. } else {
  1157. retValue = iScaleIndex - 1 + PDH_MIN_SCALE;
  1158. }
  1159. return retValue;
  1160. }
  1161. void
  1162. CCounterPropPage::SetStyleComboEnable (
  1163. )
  1164. /*++
  1165. Routine Description:
  1166. SetStyleComboEnable enables the style combo box if the width is 1,
  1167. disables it otherwise.
  1168. Arguments:
  1169. Return Value:
  1170. void
  1171. --*/
  1172. {
  1173. HWND hWnd;
  1174. hWnd = DialogControl(m_hDlg, IDC_CTRLIST);
  1175. DialogEnable (m_hDlg, IDC_LABEL_LINESTYLE, (0 == m_props.iWidthIndex) );
  1176. if (LBSelectCount(hWnd) == 1) {
  1177. DialogEnable (m_hDlg, IDC_LINESTYLE, (0 == m_props.iWidthIndex) );
  1178. }
  1179. }
  1180. HRESULT
  1181. CCounterPropPage::EditPropertyImpl( DISPID dispID )
  1182. {
  1183. HRESULT hr = E_NOTIMPL;
  1184. if ( DISPID_VALUE == dispID ) {
  1185. m_dwEditControl = IDC_ADDCTR;
  1186. hr = S_OK;
  1187. }
  1188. return hr;
  1189. }
  1190. ULONG
  1191. CCounterPropPage::HashCounter(
  1192. LPWSTR szCounterName
  1193. )
  1194. {
  1195. ULONG h = 0;
  1196. ULONG a = 31415; //a, b, k are primes
  1197. const ULONG k = 16381;
  1198. const ULONG b = 27183;
  1199. LPWSTR szThisChar;
  1200. WCHAR Char;
  1201. if (szCounterName) {
  1202. for (szThisChar = szCounterName; * szThisChar; szThisChar ++) {
  1203. Char = * szThisChar;
  1204. if (_istupper(Char) ) {
  1205. Char = _tolower(Char);
  1206. }
  1207. h = (a * h + ((ULONG) Char)) % k;
  1208. a = a * b % (k - 1);
  1209. }
  1210. }
  1211. return (h % eHashTableSize);
  1212. }
  1213. //++
  1214. // Description:
  1215. // Remove a counter path from hash table. One counter
  1216. // path must exactly match the given one in order to be
  1217. // removed, even it is one with wildcard
  1218. //
  1219. // Parameters:
  1220. // pItemInfo - Pointer to item info to be removed
  1221. //
  1222. // Return:
  1223. // Return TRUE if the counter path is removed, otherwis return FALSE
  1224. //--
  1225. BOOL
  1226. CCounterPropPage::RemoveCounterFromHashTable(
  1227. LPWSTR pszPath,
  1228. PPDH_COUNTER_PATH_ELEMENTS pCounter
  1229. )
  1230. {
  1231. ULONG lHashValue;
  1232. PHASH_ENTRY pEntry = NULL;
  1233. PHASH_ENTRY pPrev = NULL;
  1234. BOOL bReturn = FALSE;
  1235. LPWSTR pszFullPath = NULL;
  1236. SetLastError(ERROR_SUCCESS);
  1237. if (pszPath == NULL || pCounter == NULL) {
  1238. SetLastError(ERROR_INVALID_PARAMETER);
  1239. goto ErrorOut;
  1240. }
  1241. //
  1242. // If the counter path does not have machine name,
  1243. // add the machine name to compose a full path
  1244. //
  1245. if (*pszPath == L'\\' && (*(pszPath+1) == L'\\') ) {
  1246. lHashValue = HashCounter(pszPath);
  1247. }
  1248. else {
  1249. ULONG ulBufLen;
  1250. if (pCounter->szMachineName == NULL) {
  1251. SetLastError(ERROR_INVALID_PARAMETER);
  1252. goto ErrorOut;
  1253. }
  1254. ulBufLen = lstrlen(pCounter->szMachineName) + lstrlen(pszPath) + 1;
  1255. pszFullPath = new WCHAR [ ulBufLen];
  1256. if (pszFullPath == NULL) {
  1257. SetLastError(ERROR_OUTOFMEMORY);
  1258. goto ErrorOut;
  1259. }
  1260. StringCchCopy(pszFullPath, ulBufLen, pCounter->szMachineName);
  1261. StringCchCat(pszFullPath, ulBufLen, pszPath);
  1262. lHashValue = HashCounter(pszFullPath);
  1263. }
  1264. pEntry = m_HashTable[lHashValue];
  1265. //
  1266. // Check if there is a counter path which is exactly the same
  1267. // as the given one
  1268. //
  1269. while (pEntry) {
  1270. if (pEntry->pCounter == pCounter)
  1271. break;
  1272. pPrev = pEntry;
  1273. pEntry = pEntry->pNext;
  1274. }
  1275. //
  1276. // If we found it, remove it
  1277. //
  1278. if (pEntry) {
  1279. if (pPrev == NULL) {
  1280. m_HashTable[lHashValue] = pEntry->pNext;
  1281. }
  1282. else {
  1283. pPrev->pNext = pEntry->pNext;
  1284. }
  1285. assert (pEntry->pCounter);
  1286. delete(pEntry->pCounter);
  1287. delete(pEntry);
  1288. bReturn = TRUE;
  1289. }
  1290. ErrorOut:
  1291. if (pszFullPath != NULL) {
  1292. delete [] pszFullPath;
  1293. }
  1294. return bReturn;
  1295. }
  1296. //++
  1297. // Description:
  1298. // Insert a counter path into hash table.
  1299. //
  1300. // Parameters:
  1301. // PItemInfo - Pointer to the counter item info
  1302. //
  1303. // Return:
  1304. // Return the pointer to new inserted PDH_COUNTER_PATH_ELEMENTS structure
  1305. //--
  1306. DWORD
  1307. CCounterPropPage::InsertCounterToHashTable(
  1308. LPWSTR pszPath,
  1309. PPDH_COUNTER_PATH_ELEMENTS* ppCounter
  1310. )
  1311. {
  1312. ULONG lHashValue;
  1313. PHASH_ENTRY pEntry = NULL;
  1314. PHASH_ENTRY pPrev = NULL;
  1315. PDH_STATUS pdhStatus;
  1316. ULONG ulBufSize = 0;
  1317. PPDH_COUNTER_PATH_ELEMENTS pCounter = NULL;
  1318. LPWSTR pszFullPath = NULL;
  1319. BOOL bExisted = FALSE;
  1320. DWORD dwResult;
  1321. dwResult = ERROR_SUCCESS;
  1322. if (pszPath == NULL || ppCounter == NULL) {
  1323. dwResult = ERROR_INVALID_PARAMETER;
  1324. goto ErrorOut;
  1325. }
  1326. *ppCounter = NULL;
  1327. //
  1328. // Parse the counter path
  1329. //
  1330. pCounter = NULL;
  1331. do {
  1332. if (pCounter) {
  1333. delete [] (char*)pCounter;
  1334. pCounter = NULL;
  1335. }
  1336. else {
  1337. ulBufSize = sizeof(PDH_COUNTER_PATH_ELEMENTS) + sizeof(WCHAR) * PDH_MAX_COUNTER_PATH;
  1338. }
  1339. pCounter = (PPDH_COUNTER_PATH_ELEMENTS) new char [ ulBufSize ];
  1340. if (pCounter == NULL) {
  1341. dwResult = ERROR_OUTOFMEMORY;
  1342. goto ErrorOut;
  1343. }
  1344. pdhStatus = PdhParseCounterPath( pszPath, pCounter, & ulBufSize, 0);
  1345. } while (pdhStatus == PDH_INSUFFICIENT_BUFFER || pdhStatus == PDH_MORE_DATA);
  1346. if (pdhStatus != ERROR_SUCCESS) {
  1347. dwResult = pdhStatus;
  1348. goto ErrorOut;
  1349. }
  1350. //
  1351. // If the counter path does not have machine name,
  1352. // add the machine name to compose a full path
  1353. //
  1354. if (*pszPath == L'\\' && (*(pszPath+1) == L'\\') ) {
  1355. lHashValue = HashCounter(pszPath);
  1356. }
  1357. else {
  1358. ULONG ulBufLen;
  1359. ulBufLen = lstrlen(pCounter->szMachineName) + lstrlen(pszPath) + 1;
  1360. pszFullPath = new WCHAR [ulBufLen];
  1361. if (pszFullPath == NULL) {
  1362. dwResult = ERROR_OUTOFMEMORY;
  1363. goto ErrorOut;
  1364. }
  1365. StringCchCopy(pszFullPath, ulBufLen, pCounter->szMachineName);
  1366. StringCchCat(pszFullPath, ulBufLen, pszPath);
  1367. lHashValue = HashCounter(pszFullPath);
  1368. }
  1369. //
  1370. // Check if there is a counter path which is exactly the same
  1371. // as the given one
  1372. //
  1373. pEntry = m_HashTable[lHashValue];
  1374. while (pEntry) {
  1375. if ( AreSameCounterPath ( pEntry->pCounter, pCounter ) ) {
  1376. dwResult = SMON_STATUS_DUPL_COUNTER_PATH;
  1377. bExisted = TRUE;
  1378. *ppCounter = pEntry->pCounter;
  1379. break;
  1380. }
  1381. pPrev = pEntry;
  1382. pEntry = pEntry->pNext;
  1383. }
  1384. //
  1385. // Add the new counter path
  1386. //
  1387. if (bExisted == FALSE) {
  1388. pEntry = (PHASH_ENTRY) new HASH_ENTRY;
  1389. if (pEntry == NULL) {
  1390. dwResult = ERROR_OUTOFMEMORY;
  1391. goto ErrorOut;
  1392. }
  1393. pEntry->pCounter = pCounter;
  1394. pEntry->pNext = m_HashTable[lHashValue];
  1395. m_HashTable[lHashValue] = pEntry;
  1396. *ppCounter = pCounter;
  1397. }
  1398. if (pszFullPath != NULL) {
  1399. delete [] pszFullPath;
  1400. }
  1401. return dwResult;
  1402. ErrorOut:
  1403. if (pszFullPath != NULL) {
  1404. delete [] pszFullPath;
  1405. }
  1406. if (pCounter != NULL) {
  1407. delete [] ((char*) pCounter);
  1408. }
  1409. return dwResult;
  1410. }
  1411. //++
  1412. // Description:
  1413. // The function clears all the entries in hash table
  1414. // and set hash-table-not-set-up flag
  1415. //
  1416. // Parameters:
  1417. // None
  1418. //
  1419. // Return:
  1420. // None
  1421. //--
  1422. void
  1423. CCounterPropPage::ClearCountersHashTable( void )
  1424. {
  1425. ULONG i;
  1426. PHASH_ENTRY pEntry;
  1427. PHASH_ENTRY pNext;
  1428. if (m_fHashTableSetup) {
  1429. for (i = 0; i < eHashTableSize; i ++) {
  1430. pNext = m_HashTable[i];
  1431. while (pNext != NULL) {
  1432. pEntry = pNext;
  1433. pNext = pEntry->pNext;
  1434. assert( pEntry->pCounter);
  1435. delete pEntry->pCounter;
  1436. delete (pEntry);
  1437. }
  1438. }
  1439. }
  1440. else {
  1441. memset(&m_HashTable, 0, sizeof(m_HashTable));
  1442. }
  1443. m_fHashTableSetup = FALSE;
  1444. }
  1445. void CCounterPropPage::DeleteInfo(PItemInfo pInfo)
  1446. {
  1447. if (pInfo == NULL) {
  1448. return;
  1449. }
  1450. if (pInfo->pszPath != NULL) {
  1451. delete (pInfo->pszPath);
  1452. }
  1453. if ( pInfo->pItem != NULL ) {
  1454. pInfo->pItem->Release();
  1455. }
  1456. delete pInfo;
  1457. }