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

502 lines
14 KiB

  1. // DPPerfMonPage.cpp : implementation file
  2. //
  3. // 03/05/00 v-marfin bug 59643 : Make this the default starting page.
  4. // 03/20/00 v-marfin bug 61372 : Display error message if user attempts to close
  5. // dialog with no counters present in the list.
  6. // 03/22/00 v-marfin bug 62317 : Display error message if user attempts to close
  7. // dialog with no counters selected in the list.
  8. // 03/22/00 v-marfin bug 60766 : Set proper dlg title for object being browsed.
  9. // 03/29/00 v-marfin bug 62585 : Set new Data collector's ENABLED to TRUE if user presses OK.
  10. // 03/30/00 v-marfin bug 59237 : If user does not change the default name of the data
  11. // collector when they first create it, change it for
  12. // them to a more meaningful name based on the data
  13. // they select in the property pages.
  14. #include "stdafx.h"
  15. #include "snapin.h"
  16. #include "DPPerfMonPage.h"
  17. #include "HMObject.h"
  18. #include "WmiBrowseDlg.h"
  19. #include "WmiPropertyBrowseDlg.h"
  20. #include "DataElement.h"
  21. #include "DataGroup.h"
  22. #ifdef _DEBUG
  23. #define new DEBUG_NEW
  24. #undef THIS_FILE
  25. static char THIS_FILE[] = __FILE__;
  26. #endif
  27. /////////////////////////////////////////////////////////////////////////////
  28. // CDPPerfMonPage property page
  29. IMPLEMENT_DYNCREATE(CDPPerfMonPage, CHMPropertyPage)
  30. CDPPerfMonPage::CDPPerfMonPage() : CHMPropertyPage(CDPPerfMonPage::IDD)
  31. {
  32. EnableAutomation();
  33. //{{AFX_DATA_INIT(CDPPerfMonPage)
  34. m_bRequireReset = FALSE;
  35. m_sInstance = _T("");
  36. m_sObject = _T("");
  37. //}}AFX_DATA_INIT
  38. m_bNT5Perfdata = false;
  39. m_sHelpTopic = _T("HMon21.chm::/dDEperf.htm");
  40. }
  41. CDPPerfMonPage::~CDPPerfMonPage()
  42. {
  43. }
  44. void CDPPerfMonPage::OnFinalRelease()
  45. {
  46. // When the last reference for an automation object is released
  47. // OnFinalRelease is called. The base class will automatically
  48. // deletes the object. Add additional cleanup required for your
  49. // object before calling the base class.
  50. CHMPropertyPage::OnFinalRelease();
  51. }
  52. void CDPPerfMonPage::UpdateProperties()
  53. {
  54. m_Properties.DeleteAllItems();
  55. if( m_sObject.IsEmpty() )
  56. {
  57. return;
  58. }
  59. CWbemClassObject classobject;
  60. classobject.SetNamespace(_T("\\\\") + GetObjectPtr()->GetSystemName() + _T("\\") + m_sNamespace);
  61. HRESULT hr = classobject.GetObject(m_sObject);
  62. if( hr != S_OK )
  63. {
  64. return;
  65. }
  66. CStringArray saNames;
  67. classobject.GetPropertyNames(saNames);
  68. classobject.Destroy();
  69. for( int i = 0; i < saNames.GetSize(); i++ )
  70. {
  71. m_Properties.InsertItem(0,saNames[i]);
  72. }
  73. m_Properties.SetColumnWidth(0,LVSCW_AUTOSIZE);
  74. }
  75. void CDPPerfMonPage::DoDataExchange(CDataExchange* pDX)
  76. {
  77. CHMPropertyPage::DoDataExchange(pDX);
  78. //{{AFX_DATA_MAP(CDPPerfMonPage)
  79. DDX_Control(pDX, IDC_LIST_PROPERTIES, m_Properties);
  80. DDX_Check(pDX, IDC_CHECK_REQUIRE_RESET, m_bRequireReset);
  81. DDX_Text(pDX, IDC_EDIT_INSTANCE, m_sInstance);
  82. DDX_Text(pDX, IDC_EDIT_OBJECT, m_sObject);
  83. //}}AFX_DATA_MAP
  84. }
  85. BEGIN_MESSAGE_MAP(CDPPerfMonPage, CHMPropertyPage)
  86. //{{AFX_MSG_MAP(CDPPerfMonPage)
  87. ON_WM_DESTROY()
  88. ON_BN_CLICKED(IDC_BUTTON_BROWSE_INSTANCE, OnButtonBrowseInstance)
  89. ON_BN_CLICKED(IDC_BUTTON_BROWSE_OBJECT, OnButtonBrowseObject)
  90. ON_BN_CLICKED(IDC_CHECK_REQUIRE_RESET, OnCheckRequireReset)
  91. ON_EN_CHANGE(IDC_EDIT_INSTANCE, OnChangeEditInstance)
  92. ON_EN_CHANGE(IDC_EDIT_OBJECT, OnChangeEditObject)
  93. ON_NOTIFY(NM_CLICK, IDC_LIST_PROPERTIES, OnClickListProperties)
  94. //}}AFX_MSG_MAP
  95. END_MESSAGE_MAP()
  96. BEGIN_DISPATCH_MAP(CDPPerfMonPage, CHMPropertyPage)
  97. //{{AFX_DISPATCH_MAP(CDPPerfMonPage)
  98. // NOTE - the ClassWizard will add and remove mapping macros here.
  99. //}}AFX_DISPATCH_MAP
  100. END_DISPATCH_MAP()
  101. // Note: we add support for IID_IDPPerfMonPage to support typesafe binding
  102. // from VBA. This IID must match the GUID that is attached to the
  103. // dispinterface in the .ODL file.
  104. // {52566158-C9D1-11D2-BD8D-0000F87A3912}
  105. static const IID IID_IDPPerfMonPage =
  106. { 0x52566158, 0xc9d1, 0x11d2, { 0xbd, 0x8d, 0x0, 0x0, 0xf8, 0x7a, 0x39, 0x12 } };
  107. BEGIN_INTERFACE_MAP(CDPPerfMonPage, CHMPropertyPage)
  108. INTERFACE_PART(CDPPerfMonPage, IID_IDPPerfMonPage, Dispatch)
  109. END_INTERFACE_MAP()
  110. /////////////////////////////////////////////////////////////////////////////
  111. // CDPPerfMonPage message handlers
  112. BOOL CDPPerfMonPage::OnInitDialog()
  113. {
  114. // v-marfin : bug 59643 : This will be the default starting page for the property
  115. // sheet so call CnxPropertyPageCreate() to unmarshal the
  116. // connection for this thread. This function must be called
  117. // by the first page of the property sheet. It used to
  118. // be called by the "General" page and its call still remains
  119. // there as well in case the general page is loaded by a
  120. // different code path that does not also load this page.
  121. // The CnxPropertyPageCreate function has been safeguarded
  122. // to simply return if the required call has already been made.
  123. // CnxPropertyPageDestory() must be called from this page's
  124. // OnDestroy function.
  125. // unmarshal connmgr
  126. CnxPropertyPageCreate();
  127. CHMPropertyPage::OnInitDialog();
  128. // initialize the list view
  129. m_Properties.SetExtendedStyle(LVS_EX_CHECKBOXES);
  130. CString sColumnTitle;
  131. sColumnTitle.LoadString(IDS_STRING_NAME);
  132. m_Properties.InsertColumn(0,sColumnTitle);
  133. m_sNamespace = _T("root\\cimv2\\MicrosoftHealthmonitor");
  134. CWbemClassObject* pClassObject = GetObjectPtr()->GetClassObject();
  135. if( ! GfxCheckObjPtr(pClassObject,CWbemClassObject) )
  136. {
  137. return TRUE;
  138. }
  139. //-------------------------------------------------------------------------
  140. // v-marfin 59237 : Store original name in case this data collector is
  141. // just being created. When they save, we will modify the
  142. // name if they haven't.
  143. pClassObject->GetProperty(IDS_STRING_MOF_NAME,m_sOriginalName);
  144. //-------------------------------------------------------------------------
  145. pClassObject->GetProperty(IDS_STRING_MOF_PATH,m_sObject);
  146. int iIndex = -1;
  147. if( (iIndex = m_sObject.Find(_T("."))) != -1 )
  148. {
  149. m_sInstance = m_sObject;
  150. m_sObject = m_sObject.Left(iIndex);
  151. }
  152. bool bReset;
  153. pClassObject->GetProperty(IDS_STRING_MOF_REQUIRERESET,bReset);
  154. m_bRequireReset = bReset;
  155. UpdateProperties();
  156. CStringArray saCounters;
  157. pClassObject->GetProperty(IDS_STRING_MOF_STATISTICSPROPERTYNAMES,saCounters);
  158. for( int i=0; i < saCounters.GetSize(); i++ )
  159. {
  160. LVFINDINFO lvfi;
  161. ZeroMemory(&lvfi,sizeof(LVFINDINFO));
  162. lvfi.flags = LVFI_WRAP|LVFI_STRING;
  163. lvfi.psz = saCounters[i];
  164. int iListIndex = m_Properties.FindItem(&lvfi);
  165. if( iListIndex >= 0 )
  166. {
  167. m_Properties.SetCheck(iListIndex);
  168. }
  169. }
  170. delete pClassObject;
  171. UpdateData(FALSE);
  172. return TRUE; // return TRUE unless you set the focus to a control
  173. // EXCEPTION: OCX Property Pages should return FALSE
  174. }
  175. void CDPPerfMonPage::OnDestroy()
  176. {
  177. // v-marfin 62585 : For this new data collector, set its Enabled property to TRUE, but
  178. // only if the user is not cancelling these property pages.
  179. if (m_bOnApplyUsed)
  180. {
  181. ClearStatistics(); // 62548
  182. CDataElement* pElement = (CDataElement*)GetObjectPtr();
  183. if (pElement && pElement->IsStateSetToEnabledOnOK())
  184. {
  185. TRACE(_T("CDPPerfMonPage::OnDestroy - New Perfmon Collector: Setting to Enabled\n"));
  186. pElement->SetStateToEnabledOnOK(FALSE); // don't do this again
  187. CWbemClassObject* pClassObject = GetObjectPtr()->GetClassObject();
  188. if( ! GfxCheckObjPtr(pClassObject,CWbemClassObject) )
  189. {
  190. TRACE(_T("ERROR: CDPPerfMonPage::OnOK - Failed to GetClassObject()\n"));
  191. return;
  192. }
  193. // Set the new collector to enabled.
  194. BOOL bEnabled=TRUE;
  195. HRESULT hr = pClassObject->GetProperty(IDS_STRING_MOF_ENABLE,bEnabled);
  196. hr = pClassObject->SetProperty(IDS_STRING_MOF_ENABLE,TRUE);
  197. if (!CHECKHRESULT(hr))
  198. {
  199. TRACE(_T("ERROR: CDPPerfMonPage::OnDestroy - Failed to set ENABLED property on new collector\n"));
  200. }
  201. //-------------------------------------------------------------------
  202. // v-marfin 59237 : If the user has not changed the original default
  203. // name, do so for them. Compare against original
  204. // name we fetched during OnInitDialog.
  205. CString sName;
  206. pClassObject->GetProperty(IDS_STRING_MOF_NAME,sName);
  207. // Did the user change the default name?
  208. if (m_sOriginalName.CompareNoCase(sName)==0)
  209. {
  210. // No, so set the new name
  211. if (!m_sObject.IsEmpty())
  212. {
  213. // Use parent to ensure name is unique
  214. //CDataGroup* pParent = (CDataGroup*) pElement->GetCollectorsParentClassObject();
  215. if(pElement->GetScopeItemCount())
  216. {
  217. CDataElementScopeItem* pItem = (CDataElementScopeItem*)pElement->GetScopeItem(0);
  218. if( pItem )
  219. {
  220. CDataGroupScopeItem* pDGItem = (CDataGroupScopeItem*)pItem->GetParent();
  221. sName = pDGItem->GetUniqueDisplayName(m_sObject);
  222. }
  223. }
  224. // Set the local element's object data
  225. pElement->SetName(sName);
  226. // Set its WMI property
  227. pClassObject->SetProperty(IDS_STRING_MOF_NAME,sName);
  228. // Refresh to show the new name in the IU
  229. //pElement->Refresh(); // 63005
  230. pElement->UpdateStatus(); // 63005
  231. }
  232. }
  233. //-------------------------------------------------------------------
  234. pClassObject->SaveAllProperties();
  235. delete pClassObject;
  236. } // if (pElement && pElement->IsStateSetToEnabledOnOK())
  237. } // if (m_bOnApplyUsed)
  238. CHMPropertyPage::OnDestroy();
  239. // v-marfin : bug 59643 : CnxPropertyPageDestory() must be called from this page's
  240. // OnDestroy function.
  241. CnxPropertyPageDestroy();
  242. }
  243. void CDPPerfMonPage::OnOK()
  244. {
  245. CHMPropertyPage::OnOK();
  246. }
  247. void CDPPerfMonPage::OnButtonBrowseInstance()
  248. {
  249. CWmiInstanceBrowseDlg dlg;
  250. // set the dialog window title
  251. CString sItem;
  252. sItem.LoadString(IDS_STRING_INSTANCES);
  253. dlg.m_sDlgTitle.Format(IDS_STRING_WMI_BROWSE_TITLE,sItem,GetObjectPtr()->GetSystemName());
  254. // create the instance enumerator
  255. if( ! CHECKHRESULT(dlg.m_ClassObject.Create(GetObjectPtr()->GetSystemName())) )
  256. {
  257. return;
  258. }
  259. CString sTemp;
  260. sTemp.Format(_T("\\\\%s\\%s"),GetObjectPtr()->GetSystemName(),m_sNamespace);
  261. dlg.m_ClassObject.SetNamespace(sTemp);
  262. BSTR bsTemp = m_sObject.AllocSysString();
  263. if( ! CHECKHRESULT(dlg.m_ClassObject.CreateEnumerator(bsTemp)) )
  264. {
  265. ::SysFreeString(bsTemp);
  266. return;
  267. }
  268. ::SysFreeString(bsTemp);
  269. // set the listbox title
  270. dlg.m_sTitle = m_sNamespace;
  271. // display the dialog
  272. if( dlg.DoModal() == IDOK )
  273. {
  274. m_sInstance = dlg.m_sSelectedItem;
  275. UpdateData(FALSE);
  276. SetModified();
  277. }
  278. }
  279. void CDPPerfMonPage::OnButtonBrowseObject()
  280. {
  281. CWmiClassBrowseDlg dlg;
  282. // v-marfin 60766 : Set proper dlg title for object being browsed
  283. // set the dialog window title
  284. CString sItem;
  285. sItem.LoadString(IDS_STRING_OBJECTS);
  286. dlg.m_sDlgTitle.Format(IDS_STRING_WMI_BROWSE_TITLE,sItem,GetObjectPtr()->GetSystemName());
  287. // create the class enumerator
  288. if( ! CHECKHRESULT(dlg.m_ClassObject.Create(GetObjectPtr()->GetSystemName())) )
  289. {
  290. return;
  291. }
  292. CString sTemp;
  293. sTemp.Format(_T("\\\\%s\\%s"),GetObjectPtr()->GetSystemName(),m_sNamespace);
  294. dlg.m_ClassObject.SetNamespace(sTemp);
  295. sTemp = _T("Win32_PerfFormattedData");
  296. BSTR bsTemp = sTemp.AllocSysString();
  297. if( ! CHECKHRESULT(dlg.m_ClassObject.CreateClassEnumerator(bsTemp)) )
  298. {
  299. ::SysFreeString(bsTemp);
  300. return;
  301. }
  302. ::SysFreeString(bsTemp);
  303. // set the listbox title
  304. dlg.m_sTitle = m_sNamespace;
  305. // display the dialog
  306. if( dlg.DoModal() == IDOK )
  307. {
  308. m_sObject = dlg.m_sSelectedItem;
  309. m_sInstance.Empty();
  310. UpdateData(FALSE);
  311. UpdateProperties();
  312. SetModified();
  313. }
  314. }
  315. BOOL CDPPerfMonPage::OnApply()
  316. {
  317. if( ! CHMPropertyPage::OnApply() )
  318. {
  319. return FALSE;
  320. }
  321. // v-marfin 62585 : So we can set the collector's state to enabled when OK pressed.
  322. m_bOnApplyUsed=TRUE;
  323. UpdateData();
  324. if( m_Properties.GetItemCount() <= 0 )
  325. {
  326. // v-marfin 61372 : Add err msg so user knows what is going on.
  327. AfxMessageBox(IDS_ERR_MUST_CREATE_ATLEAST_ONE_COUNTER);
  328. return FALSE;
  329. }
  330. CStringArray saCounters;
  331. for( int i = 0; i < m_Properties.GetItemCount(); i++ )
  332. {
  333. if( m_Properties.GetCheck(i) )
  334. {
  335. saCounters.Add(m_Properties.GetItemText(i,0));
  336. }
  337. }
  338. if( ! saCounters.GetSize() )
  339. {
  340. // v-marfin 62317 : Add err msg so user knows what is going on.
  341. AfxMessageBox(IDS_ERR_MUST_SELECT_ATLEAST_ONE_COUNTER);
  342. return FALSE;
  343. }
  344. CWbemClassObject* pClassObject = GetObjectPtr()->GetClassObject();
  345. if( ! GfxCheckObjPtr(pClassObject,CWbemClassObject) )
  346. {
  347. return FALSE;
  348. }
  349. pClassObject->SetProperty(IDS_STRING_MOF_TARGETNAMESPACE,m_sNamespace);
  350. if( m_sInstance.IsEmpty() )
  351. {
  352. pClassObject->SetProperty(IDS_STRING_MOF_PATH,m_sObject);
  353. }
  354. else
  355. {
  356. pClassObject->SetProperty(IDS_STRING_MOF_PATH,m_sInstance);
  357. }
  358. pClassObject->SetProperty(IDS_STRING_MOF_STATISTICSPROPERTYNAMES,saCounters);
  359. bool bReset = m_bRequireReset ? true : false;
  360. pClassObject->SetProperty(IDS_STRING_MOF_REQUIRERESET,bReset);
  361. pClassObject->SaveAllProperties();
  362. delete pClassObject;
  363. SetModified(FALSE);
  364. return TRUE;
  365. }
  366. void CDPPerfMonPage::OnCheckRequireReset()
  367. {
  368. UpdateData();
  369. SetModified();
  370. }
  371. void CDPPerfMonPage::OnChangeEditInstance()
  372. {
  373. // TODO: If this is a RICHEDIT control, the control will not
  374. // send this notification unless you override the CHMPropertyPage::OnInitDialog()
  375. // function and call CRichEditCtrl().SetEventMask()
  376. // with the ENM_CHANGE flag ORed into the mask.
  377. UpdateData();
  378. SetModified();
  379. }
  380. void CDPPerfMonPage::OnChangeEditObject()
  381. {
  382. // TODO: If this is a RICHEDIT control, the control will not
  383. // send this notification unless you override the CHMPropertyPage::OnInitDialog()
  384. // function and call CRichEditCtrl().SetEventMask()
  385. // with the ENM_CHANGE flag ORed into the mask.
  386. UpdateData();
  387. SetModified();
  388. UpdateProperties();
  389. }
  390. void CDPPerfMonPage::OnClickListProperties(NMHDR* pNMHDR, LRESULT* pResult)
  391. {
  392. SetModified();
  393. *pResult = 0;
  394. }