//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation 1996-2001. // // File: cnumber.cpp // // Contents: implementation of CConfigNumber // //---------------------------------------------------------------------------- #include "stdafx.h" #include "wsecmgr.h" #include "CNumber.h" #include "util.h" #include "ANumber.h" #include "DDWarn.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CConfigNumber dialog CConfigNumber::CConfigNumber(UINT nTemplateID) : CAttribute(nTemplateID ? nTemplateID : IDD), m_cMinutes(0), m_nLow(0), m_nHigh(999), m_nSave(0) { //{{AFX_DATA_INIT(CConfigNumber) m_strUnits = _T(""); m_strValue = _T(""); m_strStatic = _T(""); m_strError = _T(""); //}}AFX_DATA_INIT m_pHelpIDs = (DWORD_PTR)a181HelpIDs; m_uTemplateResID = IDD; } void CConfigNumber::DoDataExchange(CDataExchange* pDX) { CAttribute::DoDataExchange(pDX); //{{AFX_DATA_MAP(CConfigNumber) DDX_Control(pDX, IDC_SPIN, m_SpinValue); DDX_Text(pDX, IDC_UNITS, m_strUnits); DDX_Text(pDX, IDC_VALUE, m_strValue); DDX_Text(pDX, IDC_HEADER,m_strStatic); DDX_Text(pDX, IDC_RANGEERROR,m_strError); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CConfigNumber, CAttribute) //{{AFX_MSG_MAP(CConfigNumber) // ON_EN_KILLFOCUS(IDC_VALUE, OnKillFocus) ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN, OnDeltaposSpin) ON_EN_UPDATE(IDC_VALUE, OnUpdateValue) ON_BN_CLICKED(IDC_CONFIGURE,OnConfigure) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CConfigNumber message handlers void CConfigNumber::OnDeltaposSpin( NMHDR* pNMHDR, LRESULT* pResult ) { NM_UPDOWN FAR *pnmud; pnmud = (NM_UPDOWN FAR *)pNMHDR; SetModified(TRUE); if ( pnmud ) { // // get current value // long lVal = CurrentEditValue(); if (SCE_FOREVER_VALUE == lVal) { if (pnmud->iDelta > 0) { if (m_cMinutes & DW_VALUE_OFF) { lVal = SCE_KERBEROS_OFF_VALUE; } else { lVal = m_nHigh; } } else { lVal = m_nLow; } } else if (SCE_KERBEROS_OFF_VALUE == lVal) { if (pnmud->iDelta < 0) { if (m_cMinutes & DW_VALUE_FOREVER) { lVal = SCE_FOREVER_VALUE; } else { lVal = m_nLow; } } else { lVal = m_nHigh; } } else { lVal -= (LONG)(m_iAccRate*pnmud->iDelta); if ( lVal > m_nHigh ) { // if it is overflow, go back to low if ( m_cMinutes & DW_VALUE_OFF ) { lVal = SCE_KERBEROS_OFF_VALUE; } else if (m_cMinutes & DW_VALUE_FOREVER) { lVal = SCE_FOREVER_VALUE; } else { lVal = m_nLow; } } else if ( (lVal < m_nLow) && ((lVal != SCE_KERBEROS_OFF_VALUE) || !(m_cMinutes & DW_VALUE_OFF)) && ((lVal != SCE_FOREVER_VALUE) || !(m_cMinutes & DW_VALUE_FOREVER))) { // if it is underflow, go back to high if ( (m_cMinutes & DW_VALUE_FOREVER) && (lVal != SCE_FOREVER_VALUE)) { lVal = SCE_FOREVER_VALUE; } else if ((m_cMinutes & DW_VALUE_OFF) && (lVal != SCE_KERBEROS_OFF_VALUE)) { lVal = SCE_KERBEROS_OFF_VALUE; } else { lVal = m_nHigh; } } if ( 0 == lVal && (m_cMinutes & DW_VALUE_NOZERO) ) { // zero is not allowed if ( m_nLow > 0 ) { lVal = m_nLow; } else { lVal = 1; } } } SetValueToEdit(lVal); } *pResult = 0; } void CConfigNumber::OnKillFocus() { LONG lVal = CurrentEditValue(); SetValueToEdit(lVal); } void CConfigNumber::SetValueToEdit(LONG lVal) { CString strNew; SetModified(TRUE); if ( m_iStaticId ) m_strStatic.LoadString(m_iStaticId); else m_strStatic = _T(""); if ( 0 == lVal ) { strNew.Format(TEXT("%d"),lVal); if ( m_cMinutes & DW_VALUE_NEVER && m_iNeverId > 0 ) { // change to never m_strStatic.LoadString(m_iNeverId); } } else if ( SCE_FOREVER_VALUE == lVal ) { strNew.LoadString(IDS_FOREVER); if ( m_iNeverId ) { m_strStatic.LoadString(m_iNeverId); } } else if (SCE_KERBEROS_OFF_VALUE == lVal) { strNew.LoadString(IDS_OFF); if ( m_iNeverId ) { m_strStatic.LoadString(m_iNeverId); } } else { strNew.Format(TEXT("%d"),lVal); } m_nSave = lVal; SetDlgItemText(IDC_VALUE,strNew); SetDlgItemText(IDC_HEADER,m_strStatic); } LONG CConfigNumber::CurrentEditValue() { UINT uiVal = 0; LONG lVal = 0; BOOL bTrans = FALSE; int length = m_strValue.GetLength(); while( lVal < length && m_strValue.GetAt(lVal) == L'0' ) //Raid #463904, Yang Gao, 9/6/2001. { lVal++; } if( lVal > 0 && lVal < length ) { m_strValue.Delete(0, lVal); SetDlgItemText(IDC_VALUE, m_strValue); } uiVal = GetDlgItemInt(IDC_VALUE,&bTrans,TRUE); lVal = uiVal; if ( !bTrans ) { CString str; if (m_cMinutes & DW_VALUE_FOREVER) { str.LoadString(IDS_FOREVER); if (str == m_strValue) { return SCE_FOREVER_VALUE; } } lVal = _ttol((LPCTSTR)m_strValue); if ( lVal == 0 ) { // nonnumeric lVal = (LONG) m_nSave; return lVal; } } if ( m_iAccRate > 1 && lVal > 0 ) { // for log max size, make it multiples of m_iAccRate int nCount = lVal % m_iAccRate; if ( nCount > 0 ) { lVal = ((LONG)(lVal/m_iAccRate))*m_iAccRate; } } if ( lVal > m_nHigh ) { // if it is overflow, go back to low if ( m_cMinutes & DW_VALUE_FOREVER ) { lVal = SCE_FOREVER_VALUE; } else if (m_cMinutes & DW_VALUE_OFF) { lVal = SCE_KERBEROS_OFF_VALUE; } else { // Leave alone and let the OnKillActive catch it } } if ( (lVal < m_nLow) && (lVal != SCE_KERBEROS_OFF_VALUE) && (lVal != SCE_FOREVER_VALUE) ) { // if it is underflow, go back to high if (m_cMinutes & DW_VALUE_OFF) { lVal = SCE_KERBEROS_OFF_VALUE; } else if ( m_cMinutes & DW_VALUE_FOREVER) { lVal = SCE_FOREVER_VALUE; } else { // Leave alone and let the OnKillActive catch it } } if ( 0 == lVal && (m_cMinutes & DW_VALUE_NOZERO) ) { // zero is not allowed if ( m_nLow > 0 ) { lVal = m_nLow; } else { lVal = 1; } } return lVal; } void CConfigNumber::OnConfigure() { UpdateData(TRUE); CAttribute::OnConfigure(); CWnd* cwnd = GetDlgItem(IDOK); if(cwnd) { if(!m_bConfigure) cwnd->EnableWindow(TRUE); else OnUpdateValue(); } } BOOL CConfigNumber::OnInitDialog() { CAttribute::OnInitDialog(); AddUserControl(IDC_VALUE); AddUserControl(IDC_SPIN); AddUserControl(IDC_UNITS); UpdateData(TRUE); OnConfigure(); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } BOOL CConfigNumber::OnApply() { if ( !m_bReadOnly ) { BOOL bSet = FALSE; LONG_PTR dw = 0; CString strForever; CString strOff; UpdateData(TRUE); if (!m_bConfigure) dw = (LONG_PTR)ULongToPtr(SCE_NO_VALUE); else dw = CurrentEditValue(); CEditTemplate *petSave = m_pData->GetBaseProfile(); //Raid #715992, yanggao, 10/17/2002. //for compitability with template that has SCE_FOREVER_VALUE value. if( SCE_NO_VALUE == dw && SCE_FOREVER_VALUE == m_pData->GetBase() && IDS_KERBEROS_RENEWAL == m_pData->GetID() ) { dw = SCE_FOREVER_VALUE; } // // Check dependecies for this item. // if( IDS_KERBEROS_RENEWAL != m_pData->GetID() ) { if(DDWarn.CheckDependencies((DWORD)dw) == ERROR_MORE_DATA ) { // // If it fails and the user presses cancel then we will exit and do nothing. // CThemeContextActivator activator; if( DDWarn.DoModal() != IDOK) return FALSE; // // If the user presses autoset then we set the item and update the result panes. // for(int i = 0; i < DDWarn.GetFailedCount(); i++) { PDEPENDENCYFAILED pItem = DDWarn.GetFailedInfo(i); if(pItem && pItem->pResult ) { pItem->pResult->SetBase( pItem->dwSuggested ); SetProfileInfo( pItem->pResult->GetID(), pItem->dwSuggested, pItem->pResult->GetBaseProfile()); pItem->pResult->Update(m_pSnapin, FALSE); } } } } // // Update this items profile. // m_pData->SetBase(dw); SetProfileInfo(m_pData->GetID(),dw,m_pData->GetBaseProfile()); m_pData->Update(m_pSnapin, false); if( m_bConfigure ) //Raid #460370, Yang Gao, 8/22/2001 { LPTSTR pszAlloc = NULL; //Raid #402030 m_pData->GetBaseNoUnit(pszAlloc); if(pszAlloc) { SetDlgItemText(IDC_VALUE,pszAlloc); delete [] pszAlloc; } } } return CAttribute::OnApply(); } void CConfigNumber::Initialize(CResult * pResult) { LONG_PTR dw=0; CAttribute::Initialize(pResult); m_strUnits = pResult->GetUnits(); DDWarn.InitializeDependencies(m_pSnapin,pResult); m_cMinutes = DW_VALUE_NOZERO; m_nLow = 0; m_nHigh = 999; m_nSave = 0; m_iNeverId = 0; m_iAccRate = 1; m_iStaticId = 0; m_fZero = FALSE; //Raid 482866, Yanggao, 10/25/2001, make sure zero is a useful value. BOOL fZerocompatible = FALSE; CEditTemplate *pTemplate = pResult->GetBaseProfile(); switch (pResult->GetID()) { // below no zero value case IDS_LOCK_DURATION: m_cMinutes = DW_VALUE_FOREVER | DW_VALUE_NOZERO; m_nHigh = 99999; m_iStaticId = IDS_DURATION; m_iNeverId = IDS_LOCKOUT_FOREVER; break; case IDS_MIN_PAS_AGE: m_cMinutes = DW_VALUE_NEVER; m_iNeverId = IDS_CHANGE_IMMEDIATELY; m_iStaticId = IDS_PASSWORD_CHANGE; m_nHigh = 998; break; case IDS_MAX_PAS_AGE: m_cMinutes = DW_VALUE_FOREVER | DW_VALUE_NOZERO; m_iStaticId = IDS_PASSWORD_EXPIRE; m_iNeverId = IDS_PASSWORD_FOREVER; break; // below zero value means differently case IDS_LOCK_COUNT: m_cMinutes = DW_VALUE_NEVER; m_iNeverId = IDS_NO_LOCKOUT; m_iStaticId = IDS_LOCKOUT_AFTER; break; case IDS_MIN_PAS_LEN: m_cMinutes = DW_VALUE_NEVER; m_nHigh = 14; m_iNeverId = IDS_PERMIT_BLANK; m_iStaticId = IDS_PASSWORD_LEN; break; case IDS_PAS_UNIQUENESS: m_cMinutes = DW_VALUE_NEVER; m_nHigh = 24; m_iNeverId = IDS_NO_HISTORY; m_iStaticId = IDS_PASSWORD_REMEMBER; break; // below there is no zero values case IDS_LOCK_RESET_COUNT: m_nLow = 1; m_nHigh = 99999; m_iStaticId = IDS_RESET_COUNT; //Raid #489966, yanggao, new static string. break; case IDS_SYS_LOG_MAX: case IDS_SEC_LOG_MAX: case IDS_APP_LOG_MAX: m_nLow = 64; m_nHigh = 4194240; m_iAccRate = 64; // no static text break; case IDS_SYS_LOG_DAYS: case IDS_SEC_LOG_DAYS: case IDS_APP_LOG_DAYS: m_nHigh = 365; m_nLow = 1; m_iStaticId = IDS_OVERWRITE_EVENT; break; case IDS_KERBEROS_MAX_AGE: m_cMinutes = DW_VALUE_FOREVER | DW_VALUE_NOZERO; m_iStaticId = IDS_TICKET_EXPIRE; m_iNeverId = IDS_TICKET_FOREVER; m_nHigh = 99999; m_fZero = TRUE; //Raid 482866, Yanggao break; case IDS_KERBEROS_RENEWAL: m_cMinutes = DW_VALUE_FOREVER; m_iStaticId = IDS_TICKET_RENEWAL_EXPIRE; m_iNeverId = IDS_TICKET_RENEWAL_FOREVER; m_nHigh = 99999; m_fZero = TRUE; //Raid 482866, Yanggao break; case IDS_KERBEROS_MAX_SERVICE: m_nLow = 10; m_cMinutes = DW_VALUE_FOREVER | DW_VALUE_NOZERO; m_iStaticId = IDS_TICKET_EXPIRE; m_iNeverId = IDS_TICKET_FOREVER; m_nHigh = 99999; m_fZero = TRUE; //Raid 482866, Yanggao break; case IDS_KERBEROS_MAX_CLOCK: m_cMinutes = DW_VALUE_NOZERO; m_iStaticId = IDS_MAX_TOLERANCE; m_iNeverId = IDS_NO_MAX_TOLERANCE; m_nHigh = 99999; m_nLow = 1; //Raid #678207,yanggao,9/5/2002 fZerocompatible = TRUE; break; } if ((m_cMinutes & DW_VALUE_NOZERO) && (0 == m_nLow)) { m_nLow = 1; } m_strStatic = _T(""); dw = pResult->GetBase(); //Raid #715992, yanggao, 10/17/2002. //for compitability with template that has SCE_FOREVER_VALUE value. if ((LONG_PTR)ULongToPtr(SCE_NO_VALUE) == dw || (IDS_KERBEROS_RENEWAL == pResult->GetID() && SCE_FOREVER_VALUE == dw) ) { m_bConfigure = FALSE; } else { m_bConfigure = TRUE; SetInitialValue (dw); //In order to handle existing template files with IDS_KERBEROS_MAX_CLOCK being set to "0", //UI will display them as what they are only. if( fZerocompatible && 0 == (DWORD)dw ) { m_strValue.Format(TEXT("%d"),dw); m_nSave = dw; } } } void CConfigNumber::SetInitialValue(DWORD_PTR dw) { // // Don't overwrite an already set value. // if (!m_strValue.IsEmpty()) { return; } //Raid 665368, yanggao, 8/9/2002. if (SCE_FOREVER_VALUE == (DWORD)dw) { // forever value m_strValue.LoadString(IDS_FOREVER); if ( (m_cMinutes & DW_VALUE_FOREVER) && m_iNeverId > 0 ) { m_strStatic.LoadString(m_iNeverId); } m_nSave = SCE_FOREVER_VALUE; } else if (SCE_KERBEROS_OFF_VALUE == (DWORD)dw) { // off value m_strValue.LoadString(IDS_OFF); if ( (m_cMinutes & DW_VALUE_OFF) && m_iNeverId > 0 ) { m_strStatic.LoadString(m_iNeverId); } m_nSave = SCE_KERBEROS_OFF_VALUE; } else { if ( 0 == (DWORD)dw && (m_cMinutes & DW_VALUE_NOZERO) ) { // no zero vallue is allowed if ( m_nLow > 0 ) { dw = m_nLow; } else { dw = 1; } } //Raid #652193 //If this reg value is a string, it should be converted to number because this is a number dialog. RESULT_TYPES resultType = m_pData->GetType(); if( ITEM_PROF_REGVALUE == resultType || ITEM_REGVALUE == resultType || ITEM_LOCALPOL_REGVALUE == resultType ) { PSCE_REGISTRY_VALUE_INFO regThis = (PSCE_REGISTRY_VALUE_INFO)m_pData->GetBase(); if( regThis && (regThis->ValueType == REG_MULTI_SZ || regThis->ValueType == REG_SZ || regThis->ValueType == REG_EXPAND_SZ) ) { dw = (DWORD)StrToLong((LPWSTR)dw); } } m_strValue.Format(TEXT("%d"),dw); m_nSave = dw; if ( 0 == (DWORD)dw && (m_cMinutes & DW_VALUE_NEVER) && m_iNeverId > 0 ) { // zero means different values m_strStatic.LoadString(m_iNeverId); } else if ( m_iStaticId > 0 ) { if( IDS_KERBEROS_RENEWAL == m_pData->GetID() && 0 == dw && m_iNeverId > 0 ) //Raid #730485, 12/18/2002. { m_strStatic.LoadString(m_iNeverId); } else { m_strStatic.LoadString(m_iStaticId); } } } } void CConfigNumber::OnUpdateValue() { DWORD dwRes = 0; UpdateData(TRUE); SetModified(TRUE); CString sNum; CEdit *pEdit = (CEdit *)GetDlgItem(IDC_VALUE); CWnd *pOK = GetDlgItem(IDOK); DWORD dwValue = _ttoi(m_strValue); // // Don't do anything if the string is equal to predefined strings. // sNum.LoadString(IDS_FOREVER); if (m_strValue.IsEmpty()) { if (pOK) { pOK->EnableWindow(FALSE); } } else if(m_strValue == sNum){ if(pOK && !QueryReadOnly()){ pOK->EnableWindow(TRUE); } } else { if((LONG)dwValue < m_nLow){ // // Disable the OK button. // if( pOK ){ pOK->EnableWindow(FALSE); } if(pEdit){ // // We will only force a select if edit text length >= // minimum text length // sNum.Format(TEXT("%d"), m_nLow); dwValue = m_nLow; if(sNum.GetLength() < m_strValue.GetLength()){ pEdit->SetSel(0, -1); } } } else if( (LONG)dwValue > m_nHigh ) { if(!QueryReadOnly() && pOK){ pOK->EnableWindow(TRUE); } if(pEdit){ if(m_cMinutes & DW_VALUE_FOREVER){ sNum.LoadString(IDS_FOREVER); dwValue = 0; } else { sNum.Format(TEXT("%d"), m_nHigh); dwValue = m_nHigh; } m_strValue = sNum; UpdateData(FALSE); pEdit->SetSel(0, -1); } } else if(!QueryReadOnly() && pOK){ // // Enable the OK button. // if (pOK) { pOK->EnableWindow(TRUE); } } } // // Load the description for this string. // if ((dwValue <= 0) && (m_iNeverId != 0)) { m_strStatic.LoadString(m_iNeverId); } else { m_strStatic.LoadString(m_iStaticId); } GetDlgItem(IDC_HEADER)->SetWindowText(m_strStatic); } BOOL CConfigNumber::OnKillActive() { UINT uiVal = 0; LONG lVal = 0; BOOL bTrans = FALSE; CString strRange; int lMin = m_nLow; UpdateData(TRUE); if (!m_bConfigure) { return TRUE; } if ((m_cMinutes & DW_VALUE_NOZERO) && !(m_cMinutes & DW_VALUE_FOREVER) && lMin == 0) { lMin = 1; } CString strFormat; strFormat.LoadString(IDS_RANGE); strRange.Format(strFormat,lMin,m_nHigh); int length = m_strValue.GetLength(); while( lVal < length && m_strValue.GetAt(lVal) == L'0' ) //Raid #463904, Yang Gao, 9/6/2001. { lVal++; } if( lVal > 0 && lVal < length ) { m_strValue.Delete(0, lVal); SetDlgItemText(IDC_VALUE, m_strValue); } uiVal = GetDlgItemInt(IDC_VALUE, &bTrans, TRUE); lVal = uiVal; if (!bTrans) //invalid numeric string, Raid #529933, yanggao { CString str; if (m_cMinutes & DW_VALUE_FOREVER) { str.LoadString(IDS_FOREVER); if (str == m_strValue) { return TRUE; } } // nonnumeric lVal = (LONG) m_nSave; if( m_fZero ) //Raid 482866, Yanggao, 10/25/2001 { strFormat.LoadString(IDS_ADDITIONAL_RANGE); strRange.Format(strFormat,lMin,m_nHigh); m_strError = strRange; } m_strError = strRange; UpdateData(FALSE); return FALSE; } if (m_iAccRate > 1 && lVal > 0) { // for log max size, make it multiples of m_iAccRate int nCount = lVal % m_iAccRate; if ( nCount > 0 ) { lVal = ((LONG)(lVal/m_iAccRate))*m_iAccRate; } } if (lVal > m_nHigh) { m_strError = strRange; UpdateData(FALSE); return FALSE; } if ((lVal < m_nLow) && (lVal != SCE_KERBEROS_OFF_VALUE) && (lVal != SCE_FOREVER_VALUE)) { // if it is underflow, go back to high if (m_cMinutes & DW_VALUE_OFF) { lVal = SCE_KERBEROS_OFF_VALUE; } else if (m_cMinutes & DW_VALUE_FOREVER) { lVal = SCE_FOREVER_VALUE; } else { // Leave alone and let the OnKillActive catch it } } if ((lVal < m_nLow) && (lVal != SCE_KERBEROS_OFF_VALUE) && (lVal != SCE_FOREVER_VALUE)) { // if it is underflow, go back to high m_strError = strRange; UpdateData(FALSE); return FALSE; } if (0 == lVal && (m_cMinutes & DW_VALUE_NOZERO)) { // zero is not allowed m_strError = strRange; UpdateData(FALSE); return FALSE; } return CAttribute::OnKillActive(); }