// THExpressionPage.cpp : implementation file // // Copyright (c) 2000 Microsoft Corporation // // 03/05/00 v-marfin bug 59643 : Make this the default starting page. // 03/20/00 v-marfin bug 61162 : Changed default rule to "The status changes to Critical" // 03/27/00 v-marfin bug 60494 : Set correct value for dropdown combo box. // 03/30/00 v-marfin bug 62674 : Fix to allow editing of string properties. // 04/07/00 v-marfin bug 62685 : Do not accept empty property names in OnInitDialog. // // // #include "stdafx.h" #include "snapin.h" #include "THExpressionPage.h" #include "HMObject.h" #include "HMRuleConfiguration.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CTHExpressionPage property page IMPLEMENT_DYNCREATE(CTHExpressionPage, CHMPropertyPage) CTHExpressionPage::CTHExpressionPage() : CHMPropertyPage(CTHExpressionPage::IDD) { //{{AFX_DATA_INIT(CTHExpressionPage) m_sMeasure = _T(""); m_sRuleType = _T(""); m_sCompareTo = _T(""); m_sDataElement = _T(""); m_sDuration = _T(""); m_iComparison = -1; m_iDurationType = -1; m_iFunctionType = -1; m_iCompareTo = -1; m_sNumericCompareTo = _T(""); m_sTime = _T(""); //}}AFX_DATA_INIT m_iIntervalMultiple = -1; m_sHelpTopic = _T("HMon21.chm::/dTHexp.htm"); } CTHExpressionPage::~CTHExpressionPage() { } void CTHExpressionPage::DoDataExchange(CDataExchange* pDX) { CHMPropertyPage::DoDataExchange(pDX); //{{AFX_DATA_MAP(CTHExpressionPage) DDX_Control(pDX, IDC_COMBO_FUNCTION, m_FunctionType); DDX_Control(pDX, IDC_COMBO_RULE_TYPE, m_RuleType); DDX_Control(pDX, IDC_COMBO_MEASURE, m_Measure); DDX_Control(pDX, IDC_COMBO_COMPARISON, m_Comparison); DDX_CBString(pDX, IDC_COMBO_MEASURE, m_sMeasure); DDX_CBString(pDX, IDC_COMBO_RULE_TYPE, m_sRuleType); DDX_Text(pDX, IDC_EDIT_COMPARE_TO, m_sCompareTo); DDX_Text(pDX, IDC_EDIT_DATA_ELEMENT, m_sDataElement); DDX_Text(pDX, IDC_EDIT_DURATION, m_sDuration); DDX_CBIndex(pDX, IDC_COMBO_COMPARISON, m_iComparison); DDX_Radio(pDX, IDC_RADIO_DURATION_ANY, m_iDurationType); DDX_CBIndex(pDX, IDC_COMBO_FUNCTION, m_iFunctionType); DDX_CBIndex(pDX, IDC_COMBO_COMPARE_BOOLEAN, m_iCompareTo); DDX_Text(pDX, IDC_EDIT_COMPARE_NUMERIC, m_sNumericCompareTo); DDX_Text(pDX, IDC_STATIC_TIME, m_sTime); //}}AFX_DATA_MAP if( m_iComparison == 8 ) { GetDlgItem(IDC_EDIT_DURATION)->EnableWindow(FALSE); GetDlgItem(IDC_SPIN1)->EnableWindow(FALSE); GetDlgItem(IDC_RADIO_DURATION)->EnableWindow(FALSE); GetDlgItem(IDC_RADIO_DURATION_ANY)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT_COMPARE_TO)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO_MEASURE)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO_FUNCTION)->EnableWindow(FALSE); } else { if( m_iDurationType == 1 ) { GetDlgItem(IDC_EDIT_DURATION)->EnableWindow(); GetDlgItem(IDC_SPIN1)->EnableWindow(); } else { GetDlgItem(IDC_EDIT_DURATION)->EnableWindow(FALSE); GetDlgItem(IDC_SPIN1)->EnableWindow(FALSE); } GetDlgItem(IDC_RADIO_DURATION)->EnableWindow(); GetDlgItem(IDC_RADIO_DURATION_ANY)->EnableWindow(); GetDlgItem(IDC_EDIT_COMPARE_TO)->EnableWindow(); GetDlgItem(IDC_COMBO_MEASURE)->EnableWindow(); GetDlgItem(IDC_COMBO_FUNCTION)->EnableWindow(); } int iCurSel = m_Measure.GetCurSel(); if( iCurSel == -1 || m_dwaPropertyTypes.GetSize() == 0 ) { return; } if( iCurSel >= m_dwaPropertyTypes.GetSize() ) { GetDlgItem(IDC_COMBO_COMPARE_BOOLEAN)->ShowWindow(SW_HIDE); GetDlgItem(IDC_EDIT_COMPARE_NUMERIC)->ShowWindow(SW_SHOW); GetDlgItem(IDC_SPIN2)->ShowWindow(SW_SHOW); GetDlgItem(IDC_EDIT_COMPARE_TO)->ShowWindow(SW_HIDE); return; } switch( m_dwaPropertyTypes[iCurSel] ) { case CIM_SINT8: case CIM_SINT16: case CIM_SINT32: case CIM_SINT64: case CIM_UINT8: case CIM_UINT16: case CIM_UINT32: case CIM_UINT64: case CIM_REAL32: case CIM_REAL64: { GetDlgItem(IDC_COMBO_COMPARE_BOOLEAN)->ShowWindow(SW_HIDE); GetDlgItem(IDC_EDIT_COMPARE_NUMERIC)->ShowWindow(SW_SHOW); GetDlgItem(IDC_SPIN2)->ShowWindow(SW_SHOW); GetDlgItem(IDC_EDIT_COMPARE_TO)->ShowWindow(SW_HIDE); m_CurrentType = Numeric; } break; case CIM_BOOLEAN: { GetDlgItem(IDC_COMBO_COMPARE_BOOLEAN)->ShowWindow(SW_SHOW); GetDlgItem(IDC_EDIT_COMPARE_NUMERIC)->ShowWindow(SW_HIDE); GetDlgItem(IDC_SPIN2)->ShowWindow(SW_HIDE); GetDlgItem(IDC_EDIT_COMPARE_TO)->ShowWindow(SW_HIDE); m_CurrentType = Boolean; } break; case CIM_STRING: case CIM_DATETIME: case CIM_REFERENCE: case CIM_CHAR16: case CIM_OBJECT: { GetDlgItem(IDC_COMBO_COMPARE_BOOLEAN)->ShowWindow(SW_HIDE); GetDlgItem(IDC_EDIT_COMPARE_NUMERIC)->ShowWindow(SW_HIDE); GetDlgItem(IDC_SPIN2)->ShowWindow(SW_HIDE); GetDlgItem(IDC_EDIT_COMPARE_TO)->ShowWindow(SW_SHOW); m_CurrentType = String; } break; default: { GetDlgItem(IDC_COMBO_COMPARE_BOOLEAN)->ShowWindow(SW_HIDE); GetDlgItem(IDC_EDIT_COMPARE_NUMERIC)->ShowWindow(SW_HIDE); GetDlgItem(IDC_SPIN2)->ShowWindow(SW_HIDE); GetDlgItem(IDC_EDIT_COMPARE_TO)->ShowWindow(SW_SHOW); m_CurrentType = String; } } int iTotalSeconds = m_iIntervalMultiple*_ttoi(m_sDuration); int iHours = iTotalSeconds/3600; int iMinutes = (iTotalSeconds/60)%60; int iSeconds = iTotalSeconds%60; m_sTime.Empty(); if( iHours ) { CString sHrs; sHrs.Format(IDS_STRING_TIME_HOURS_FORMAT,iHours); m_sTime += sHrs; } if( iMinutes ) { CString sMins; sMins.Format(IDS_STRING_TIME_MINUTES_FORMAT,iMinutes); m_sTime += sMins; } if( iSeconds ) { CString sSecs; sSecs.Format(IDS_STRING_TIME_SECONDS_FORMAT,iSeconds); m_sTime += sSecs; } m_sTime.TrimRight(_T(", ")); m_sTime = _T("(") + m_sTime + _T(")"); GetDlgItem(IDC_STATIC_TIME)->SetWindowText(m_sTime); } BEGIN_MESSAGE_MAP(CTHExpressionPage, CHMPropertyPage) //{{AFX_MSG_MAP(CTHExpressionPage) ON_CBN_EDITCHANGE(IDC_COMBO_COMPARISON, OnEditchangeComboComparison) ON_CBN_EDITCHANGE(IDC_COMBO_MEASURE, OnEditchangeComboMeasure) ON_CBN_EDITCHANGE(IDC_COMBO_RULE_TYPE, OnEditchangeComboRuleType) ON_EN_CHANGE(IDC_EDIT_COMPARE_TO, OnChangeEditCompareTo) ON_EN_CHANGE(IDC_EDIT_DATA_ELEMENT, OnChangeEditDataElement) ON_EN_CHANGE(IDC_EDIT_DURATION, OnChangeEditDuration) ON_CBN_SELENDOK(IDC_COMBO_COMPARISON, OnSelendokComboComparison) ON_CBN_SELENDOK(IDC_COMBO_MEASURE, OnSelendokComboMeasure) ON_CBN_SELENDOK(IDC_COMBO_RULE_TYPE, OnSelendokComboRuleType) ON_CBN_EDITCHANGE(IDC_COMBO_FUNCTION, OnEditchangeComboFunction) ON_CBN_SELENDOK(IDC_COMBO_FUNCTION, OnSelendokComboFunction) ON_BN_CLICKED(IDC_RADIO_DURATION, OnRadioDuration) ON_BN_CLICKED(IDC_RADIO_DURATION_ANY, OnRadioDurationAny) ON_EN_CHANGE(IDC_EDIT_COMPARE_NUMERIC, OnChangeEditCompareNumeric) ON_CBN_SELENDOK(IDC_COMBO_COMPARE_BOOLEAN, OnSelendokComboCompareBoolean) ON_WM_DESTROY() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CTHExpressionPage message handlers BOOL CTHExpressionPage::OnInitDialog() { // v-marfin : bug 59643 : This will be the default starting page for the property // sheet so call CnxPropertyPageCreate() to unmarshal the // connection for this thread. This function must be called // by the first page of the property sheet. It used to // be called by the "General" page and its call still remains // there as well in case the general page is loaded by a // different code path that does not also load this page. // The CnxPropertyPageCreate function has been safeguarded // to simply return if the required call has already been made. // CnxPropertyPageDestory() must be called from this page's // OnDestroy function. // unmarshal connmgr CnxPropertyPageCreate(); CHMPropertyPage::OnInitDialog(); GetDlgItem(IDC_COMBO_COMPARE_BOOLEAN)->ShowWindow(SW_HIDE); GetDlgItem(IDC_EDIT_COMPARE_NUMERIC)->ShowWindow(SW_HIDE); GetDlgItem(IDC_SPIN2)->ShowWindow(SW_HIDE); GetDlgItem(IDC_EDIT_COMPARE_TO)->ShowWindow(SW_SHOW); CHMObject* pObject = GetObjectPtr(); if( ! pObject ) { return FALSE; } CHMRuleConfiguration rc; rc.Create(pObject->GetSystemName()); rc.GetObject(pObject->GetObjectPath()); rc.GetAllProperties(); switch( rc.m_iState ) { case 9: { m_RuleType.SetCurSel(0); // critical } break; case 8: { m_RuleType.SetCurSel(1); } break; case 3: { m_RuleType.SetCurSel(2); } break; case 1: // v-marfin 60494 { m_RuleType.SetCurSel(3); } break; case 0: { // v-marfin bug 61162 m_RuleType.SetCurSel(3); // default rule for threshold should be "The status changes to critical" m_RuleType.SetCurSel(0); } break; } m_Comparison.SetCurSel(rc.m_iRuleCondition); UpdateData(); // get parent object to fill in the data element field CWbemClassObject* pClassObject = pObject->GetParentClassObject(); if( ! pClassObject ) { return FALSE; } CString sNamespace; CString sClass; CStringArray saPropertyNames; m_iIntervalMultiple = 0; pClassObject->GetLocaleStringProperty(IDS_STRING_MOF_NAME,m_sDataElement); pClassObject->GetProperty(IDS_STRING_MOF_TARGETNAMESPACE,sNamespace); pClassObject->GetProperty(IDS_STRING_MOF_PATH,sClass); //--------------------------------------------------------------------------------- // 62685 : Do not accept empty property names pClassObject->GetProperty(IDS_STRING_MOF_STATISTICSPROPERTYNAMES,saPropertyNames); int nSize = (int)saPropertyNames.GetSize()-1; for (int x=nSize; x>=0; x--) { if (saPropertyNames[x].IsEmpty()) { saPropertyNames.RemoveAt(x); } } // // This is really a larger problem: When some data collectors are created, they // have default properties automatically created via the mof. But upon initial // creation, if the user changes the CLASS or INSTANCE for example on the property // page and selects different properties, the old properties are not removed. This // causes problems when new thresholds are created for the data collector. The solution // is to ensure that in the data collector property page, when key data such as CLASS // or INSTANCE changes, the existing properties are removed. // For now (beta) just remove the empty names from the array. //--------------------------------------------------------------------------------- // pClassObject->GetProperty(IDS_STRING_MOF_COLLECTIONINTERVAL,m_iIntervalMultiple); if( ! sClass.IsEmpty() ) { int iIndex = -1; if( (iIndex = sClass.Find(_T("."))) != -1 ) { sClass = sClass.Left(iIndex); } } CString sQuery; pClassObject->GetProperty(IDS_STRING_MOF_QUERY,sQuery); if( sClass.IsEmpty() && !sQuery.IsEmpty() ) { sQuery.MakeUpper(); int iIndex = -1; if( (iIndex = sQuery.Find(_T("ISA"))) != -1 ) { sClass = sQuery.Right(sQuery.GetLength()-iIndex-4); iIndex = sClass.Find(_T(" ")); if( iIndex != -1 ) { sClass = sClass.Left(iIndex); } sClass.TrimLeft(_T("\"")); sClass.TrimRight(_T("\"")); } else { iIndex = sQuery.Find(_T("SELECT * FROM ")); if( iIndex != -1 ) { sClass = sQuery.Right(sQuery.GetLength()-iIndex-14); iIndex = sClass.Find(_T(" ")); if( iIndex != -1 ) { sClass = sClass.Left(iIndex); } } } } delete pClassObject; pClassObject = NULL; m_iFunctionType = rc.m_iUseFlag; if( rc.m_iRuleDuration ) { m_sDuration.Format(_T("%d"),rc.m_iRuleDuration); m_iDurationType = 1; GetDlgItem(IDC_EDIT_DURATION)->EnableWindow(); } else { m_iDurationType = 0; } // we need to get the WMI class object that the data element is pointing to // so that we can read in the type of each property pClassObject = new CWbemClassObject; pClassObject->SetNamespace(_T("\\\\") + pObject->GetSystemName() + _T("\\") + sNamespace); HRESULT hr = pClassObject->GetObject(sClass); pClassObject->GetPropertyNames(saPropertyNames); for( int i = 0; i < saPropertyNames.GetSize(); i++ ) { CString sType; if( hr == S_OK ) { long lType; pClassObject->GetPropertyType(saPropertyNames[i],sType); pClassObject->GetPropertyType(saPropertyNames[i],lType); // m_dwaPropertyTypes.Add(lType); // v-marfin 62674 // v-marfin 61636 // Send to function that will check first for dup entries and not add // if duplicated. // m_Measure.AddString(_T("[") + sType + _T("] ") + saPropertyNames[i]); if (AddToMeasureCombo(sType,saPropertyNames[i])) // v-marfin 61811 Check to see if we added the item first { m_dwaPropertyTypes.Add(lType); // v-marfin 62674 Only add if it passed above check if( saPropertyNames[i].CompareNoCase(rc.m_sPropertyName) == 0 ) { if( lType == CIM_BOOLEAN ) { if( rc.m_sRuleValue == _T("1") ) { m_iCompareTo = 1; } else { m_iCompareTo = 0; } } else { m_sCompareTo = rc.m_sRuleValue; m_sNumericCompareTo = rc.m_sRuleValue; } } } // if (AddToMeasureCombo(sType,saPropertyNames[i])) } else { m_Measure.AddString(saPropertyNames[i]); } } m_Measure.AddString(_T("HMNumInstancesCollected")); if( hr == S_OK ) { CString sType; pClassObject->GetPropertyType(rc.m_sPropertyName,sType); m_sMeasure = _T("[") + sType + _T("] ") + rc.m_sPropertyName; } else { m_sMeasure = rc.m_sPropertyName; m_sCompareTo = rc.m_sRuleValue; } delete pClassObject; pClassObject = NULL; UpdateData(FALSE); SendDlgItemMessage(IDC_SPIN1,UDM_SETRANGE32,0,INT_MAX-1); SendDlgItemMessage(IDC_SPIN2,UDM_SETRANGE32,0,INT_MAX-1); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CTHExpressionPage::OnOK() { CHMPropertyPage::OnOK(); } BOOL CTHExpressionPage::OnApply() { if( ! CHMPropertyPage::OnApply() ) { return FALSE; } UpdateData(); CWbemClassObject* pClassObject = GetObjectPtr()->GetClassObject(); if( ! pClassObject ) { return FALSE; } HRESULT hr = S_OK; int iIndex = -1; if( (iIndex = m_sMeasure.Find(_T("] "))) != -1 ) { m_sMeasure = m_sMeasure.Right(m_sMeasure.GetLength()-(iIndex+2)); } if( m_CurrentType == String ) { hr = pClassObject->SetProperty(IDS_STRING_MOF_RULEVALUE,m_sCompareTo); } else if( m_CurrentType == Numeric ) { hr = pClassObject->SetProperty(IDS_STRING_MOF_RULEVALUE,m_sNumericCompareTo); } else if( m_CurrentType == Boolean ) { CString sValue; sValue.Format(_T("%d"),m_iCompareTo); hr = pClassObject->SetProperty(IDS_STRING_MOF_RULEVALUE,sValue); } switch( m_RuleType.GetCurSel() ) { case 0: { hr = pClassObject->SetProperty(IDS_STRING_MOF_STATE,9); } break; case 1: { hr = pClassObject->SetProperty(IDS_STRING_MOF_STATE,8); } break; case 2: { hr = pClassObject->SetProperty(IDS_STRING_MOF_STATE,3); } break; case 3: { // v-marfin 60494 : Set correct value hr = pClassObject->SetProperty(IDS_STRING_MOF_STATE,1); // 0 } break; } hr = pClassObject->SetProperty(IDS_STRING_MOF_RULECONDITION,m_Comparison.GetCurSel()); hr = pClassObject->SetProperty(IDS_STRING_MOF_PROPERTYNAME,m_sMeasure); hr = pClassObject->SetProperty(IDS_STRING_MOF_USEFLAG,m_iFunctionType); int iDuration; if( m_iDurationType == 1 ) { iDuration = _ttoi(m_sDuration); } else { iDuration = 0; } hr = pClassObject->SetProperty(IDS_STRING_MOF_RULEDURATION,iDuration); pClassObject->SaveAllProperties(); CString sName; pClassObject->GetProperty(IDS_STRING_MOF_NAME,sName); delete pClassObject; CStringArray saPropertyNames; CWbemClassObject* pParentObject = GetObjectPtr()->GetParentClassObject(); if( pParentObject ) { pParentObject->GetProperty(IDS_STRING_MOF_STATISTICSPROPERTYNAMES,saPropertyNames); bool bFound = false; for( int i = 0; i < saPropertyNames.GetSize(); i++ ) { if( saPropertyNames[i] == m_sMeasure ) { bFound = true; break; } } if( ! bFound ) { saPropertyNames.Add(m_sMeasure); pParentObject->SetProperty(IDS_STRING_MOF_STATISTICSPROPERTYNAMES,saPropertyNames); pParentObject->SaveAllProperties(); } delete pParentObject; } SetModified(FALSE); GetObjectPtr()->Rename(sName); return TRUE; } void CTHExpressionPage::OnEditchangeComboComparison() { if( m_FunctionType.GetSafeHwnd() == NULL ) { return; } UpdateData(); SetModified(); } void CTHExpressionPage::OnEditchangeComboMeasure() { if( m_FunctionType.GetSafeHwnd() == NULL ) { return; } UpdateData(); SetModified(); } void CTHExpressionPage::OnEditchangeComboRuleType() { if( m_FunctionType.GetSafeHwnd() == NULL ) { return; } UpdateData(); SetModified(); } void CTHExpressionPage::OnChangeEditCompareTo() { // TODO: If this is a RICHEDIT control, the control will not // send this notification unless you override the CHMPropertyPage::OnInitDialog() // function and call CRichEditCtrl().SetEventMask() // with the ENM_CHANGE flag ORed into the mask. if( m_FunctionType.GetSafeHwnd() == NULL ) { return; } UpdateData(); SetModified(); } void CTHExpressionPage::OnChangeEditDataElement() { // TODO: If this is a RICHEDIT control, the control will not // send this notification unless you override the CHMPropertyPage::OnInitDialog() // function and call CRichEditCtrl().SetEventMask() // with the ENM_CHANGE flag ORed into the mask. if( m_FunctionType.GetSafeHwnd() == NULL ) { return; } UpdateData(); SetModified(); } void CTHExpressionPage::OnChangeEditDuration() { // TODO: If this is a RICHEDIT control, the control will not // send this notification unless you override the CHMPropertyPage::OnInitDialog() // function and call CRichEditCtrl().SetEventMask() // with the ENM_CHANGE flag ORed into the mask. if( m_FunctionType.GetSafeHwnd() == NULL ) { return; } UpdateData(); SetModified(); } void CTHExpressionPage::OnChangeEditCompareNumeric() { // TODO: If this is a RICHEDIT control, the control will not // send this notification unless you override the CHMPropertyPage::OnInitDialog() // function and call CRichEditCtrl().SetEventMask() // with the ENM_CHANGE flag ORed into the mask. if( m_FunctionType.GetSafeHwnd() == NULL ) { return; } UpdateData(); SetModified(); } void CTHExpressionPage::OnSelendokComboComparison() { if( m_FunctionType.GetSafeHwnd() == NULL ) { return; } UpdateData(); SetModified(); } void CTHExpressionPage::OnSelendokComboMeasure() { if( m_FunctionType.GetSafeHwnd() == NULL ) { return; } UpdateData(); SetModified(); } void CTHExpressionPage::OnSelendokComboRuleType() { if( m_FunctionType.GetSafeHwnd() == NULL ) { return; } UpdateData(); SetModified(); } void CTHExpressionPage::OnEditchangeComboFunction() { if( m_FunctionType.GetSafeHwnd() == NULL ) { return; } UpdateData(); SetModified(); } void CTHExpressionPage::OnSelendokComboFunction() { if( m_FunctionType.GetSafeHwnd() == NULL ) { return; } UpdateData(); SetModified(); } void CTHExpressionPage::OnRadioDuration() { if( m_FunctionType.GetSafeHwnd() == NULL ) { return; } UpdateData(); SetModified(); } void CTHExpressionPage::OnRadioDurationAny() { if( m_FunctionType.GetSafeHwnd() == NULL ) { return; } UpdateData(); SetModified(); } void CTHExpressionPage::OnSelendokComboCompareBoolean() { if( m_FunctionType.GetSafeHwnd() == NULL ) { return; } UpdateData(); SetModified(); } //*********************************************************************** // AddToMeasureCombo v-marfin bug 61636 //*********************************************************************** BOOL CTHExpressionPage::AddToMeasureCombo(CString &sType, CString &sName) { // Check for duplicate before adding. // Format it for display CString sEntry = _T("[") + sType + _T("] ") + sName; // Does it already exist? -1 = search entire combo if (m_Measure.FindStringExact(-1, (LPCTSTR)sEntry ) != CB_ERR) return FALSE; // v-marfin 61811 : FALSE means we did not add it // Add it m_Measure.AddString(sEntry); return TRUE; } void CTHExpressionPage::OnDestroy() { CHMPropertyPage::OnDestroy(); // v-marfin : bug 59643 : CnxPropertyPageDestory() must be called from this page's // OnDestroy function. CnxPropertyPageDestroy(); }