windows-nt/Source/XPSP1/NT/admin/snapin/wsecmgr/cnumber.cpp
2020-09-26 16:20:57 +08:00

726 lines
18 KiB
C++

//+---------------------------------------------------------------------------
//
// 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;
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();
//
// Check dependecies for this item.
//
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);
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;
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_LOCK_RESET_COUNT;
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;
break;
case IDS_KERBEROS_RENEWAL:
m_cMinutes = DW_VALUE_FOREVER | DW_VALUE_NOZERO; // | DW_VALUE_OFF;
m_iStaticId = IDS_TICKET_RENEWAL_EXPIRE;
m_iNeverId = IDS_TICKET_RENEWAL_FOREVER;
m_nHigh = 99999;
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;
break;
case IDS_KERBEROS_MAX_CLOCK:
m_cMinutes = DW_VALUE_FOREVER;
m_iStaticId = IDS_MAX_TOLERANCE;
m_iNeverId = IDS_NO_MAX_TOLERANCE;
m_nHigh = 99999;
break;
}
if ((m_cMinutes & DW_VALUE_NOZERO) && (0 == m_nLow)) {
m_nLow = 1;
}
m_strStatic = _T("");
dw = pResult->GetBase();
if ((LONG_PTR)ULongToPtr(SCE_NO_VALUE) == dw)
{
m_bConfigure = FALSE;
}
else
{
m_bConfigure = TRUE;
SetInitialValue (dw);
}
}
void CConfigNumber::SetInitialValue(DWORD_PTR dw)
{
//
// Don't overwrite an already set value.
//
if (!m_strValue.IsEmpty())
{
return;
}
if (SCE_FOREVER_VALUE == 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 == 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 == dw && (m_cMinutes & DW_VALUE_NOZERO) ) {
// no zero vallue is allowed
if ( m_nLow > 0 ) {
dw = m_nLow;
} else {
dw = 1;
}
}
m_strValue.Format(TEXT("%d"),dw);
m_nSave = dw;
if ( 0 == dw && (m_cMinutes & DW_VALUE_NEVER) &&
m_iNeverId > 0 ) {
// zero means different values
m_strStatic.LoadString(m_iNeverId);
} else if ( m_iStaticId > 0 ) {
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);
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 TRUE;
}
}
lVal = _ttol((LPCTSTR)m_strValue);
if (lVal == 0)
{
// nonnumeric
lVal = (LONG) m_nSave;
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();
}