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

1140 lines
35 KiB
C++

/////////////////////////////////////////////////////////////////////////////////
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 2000-2001.
//
// File: TemplateGeneralPropertyPage.cpp
//
// Contents: Implementation of CTemplateGeneralPropertyPage
//
//----------------------------------------------------------------------------
// TemplateGeneralPropertyPage.cpp : implementation file
//
#include "stdafx.h"
#include "CompData.h"
#include "TemplateGeneralPropertyPage.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CTemplateGeneralPropertyPage property page
CTemplateGeneralPropertyPage::CTemplateGeneralPropertyPage(
CCertTemplate& rCertTemplate,
const CCertTmplComponentData* pCompData) :
CHelpPropertyPage(CTemplateGeneralPropertyPage::IDD),
m_rCertTemplate (rCertTemplate),
m_strOriginalName (rCertTemplate.GetTemplateName ()),
m_pReleaseMe (0),
m_dwCurrentValidityUnits (PERIOD_TYPE_NONE),
m_dwCurrentRenewalUnits (PERIOD_TYPE_NONE),
m_lNotifyHandle (0),
m_bIsDirty (false),
m_nRenewalDays (0),
m_nValidityDays (0),
m_pCompData (pCompData),
m_nTemplateV2AuthPageNumber (-1),
m_nTemplateV2RequestPageNumber (-1)
{
_TRACE (1, L"Entering CTemplateGeneralPropertyPage::CTemplateGeneralPropertyPage ()\n");
//{{AFX_DATA_INIT(CTemplateGeneralPropertyPage)
m_strDisplayName = _T("");
m_strTemplateName = _T("");
//}}AFX_DATA_INIT
m_rCertTemplate.AddRef ();
_TRACE (-1, L"Leaving CTemplateGeneralPropertyPage::CTemplateGeneralPropertyPage ()\n");
}
CTemplateGeneralPropertyPage::~CTemplateGeneralPropertyPage()
{
_TRACE (1, L"Entering CTemplateGeneralPropertyPage::~CTemplateGeneralPropertyPage ()\n");
m_rCertTemplate.Release ();
if ( m_pReleaseMe )
{
m_pReleaseMe->Release ();
m_pReleaseMe = 0;
}
if ( m_lNotifyHandle )
{
MMCFreeNotifyHandle (m_lNotifyHandle);
m_lNotifyHandle = 0;
}
_TRACE (-1, L"Leaving CTemplateGeneralPropertyPage::~CTemplateGeneralPropertyPage ()\n");
}
void CTemplateGeneralPropertyPage::DoDataExchange(CDataExchange* pDX)
{
CHelpPropertyPage::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CTemplateGeneralPropertyPage)
DDX_Control(pDX, IDC_VALIDITY_UNITS, m_validityUnits);
DDX_Control(pDX, IDC_RENEWAL_UNITS, m_renewalUnits);
DDX_Text(pDX, IDC_DISPLAY_NAME, m_strDisplayName);
DDX_Text(pDX, IDC_TEMPLATE_NAME, m_strTemplateName);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CTemplateGeneralPropertyPage, CHelpPropertyPage)
//{{AFX_MSG_MAP(CTemplateGeneralPropertyPage)
ON_EN_CHANGE(IDC_DISPLAY_NAME, OnChangeDisplayName)
ON_CBN_SELCHANGE(IDC_RENEWAL_UNITS, OnSelchangeRenewalUnits)
ON_CBN_SELCHANGE(IDC_VALIDITY_UNITS, OnSelchangeValidityUnits)
ON_EN_CHANGE(IDC_RENEWAL_EDIT, OnChangeRenewalEdit)
ON_EN_CHANGE(IDC_VALIDITY_EDIT, OnChangeValidityEdit)
ON_BN_CLICKED(IDC_PUBLISH_TO_AD, OnPublishToAd)
ON_BN_CLICKED(IDC_USE_AD_CERT_FOR_REENROLLMENT, OnUseADCert)
ON_EN_CHANGE(IDC_TEMPLATE_NAME, OnChangeTemplateName)
ON_EN_KILLFOCUS(IDC_VALIDITY_EDIT, OnKillfocusValidityEdit)
ON_CBN_KILLFOCUS(IDC_VALIDITY_UNITS, OnKillfocusValidityUnits)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTemplateGeneralPropertyPage message handlers
BOOL CTemplateGeneralPropertyPage::OnInitDialog()
{
_TRACE (1, L"Entering CTemplateGeneralPropertyPage::OnInitDialog ()\n");
CHelpPropertyPage::OnInitDialog();
SendDlgItemMessage (IDC_VALIDITY_EDIT, EM_LIMITTEXT, 4, 0);
SendDlgItemMessage (IDC_RENEWAL_EDIT, EM_LIMITTEXT, 4, 0);
CString version;
if ( 1 == m_rCertTemplate.GetType () )
{
VERIFY (version.LoadString (IDS_WINDOWS_2000_AND_LATER));
}
else
{
VERIFY (version.LoadString (IDS_WINDOWS_2002_AND_LATER));
}
SetDlgItemText (IDC_TEMPLATE_VERSION, version);
if ( m_rCertTemplate.IsClone () )
{
GetDlgItem (IDC_CANT_CHANGE_TEMPLATE_NAME)->ShowWindow (SW_SHOW);
}
else
{
// The template name is only editable if the template is a clone. Since
// this is not a clone, disable the template name fields.
GetDlgItem (IDC_TEMPLATE_NAME)->EnableWindow (FALSE);
GetDlgItem (IDC_TEMPLATE_NAME_LABEL)->EnableWindow (FALSE);
// #NTRAID 360650: Cert Server: Cannot rename cert templates
GetDlgItem (IDC_DISPLAY_NAME)->EnableWindow (FALSE);
GetDlgItem (IDC_DISPLAY_NAME_LABEL)->EnableWindow (FALSE);
}
m_strTemplateName = m_rCertTemplate.GetTemplateName ();
m_strOriginalDisplayName = m_strDisplayName = m_rCertTemplate.GetDisplayName ();
// Get validity period, determine current units and then initialize drop down
HRESULT hr = m_rCertTemplate.GetValidityPeriod (m_nValidityDays);
if ( SUCCEEDED (hr) )
{
int nValue = m_nValidityDays;
if ( nValue % 365 == 0 )
{
nValue /= 365;
m_dwCurrentValidityUnits = PERIOD_TYPE_YEAR;
}
else if ( nValue % 30 == 0 )
{
nValue /= 30;
m_dwCurrentValidityUnits = PERIOD_TYPE_MONTH;
}
else if ( nValue % 7 == 0 )
{
nValue /= 7;
m_dwCurrentValidityUnits = PERIOD_TYPE_WEEK;
}
else
m_dwCurrentValidityUnits = PERIOD_TYPE_DAY;
SetDlgItemInt (IDC_VALIDITY_EDIT, (UINT) nValue, FALSE);
}
hr = m_rCertTemplate.GetRenewalPeriod (m_nRenewalDays);
if ( SUCCEEDED (hr) )
{
int nValue = m_nRenewalDays;
if ( nValue % 365 == 0 )
{
nValue /= 365;
m_dwCurrentRenewalUnits = PERIOD_TYPE_YEAR;
}
else if ( nValue % 30 == 0 )
{
nValue /= 30;
m_dwCurrentRenewalUnits = PERIOD_TYPE_MONTH;
}
else if ( nValue % 7 == 0 )
{
nValue /= 7;
m_dwCurrentRenewalUnits = PERIOD_TYPE_WEEK;
}
else
m_dwCurrentRenewalUnits = PERIOD_TYPE_DAY;
SetDlgItemInt (IDC_RENEWAL_EDIT, (UINT) nValue, FALSE);
}
// Now that we know what units the validity and renewal periods are
// to be displayed in, initialize the dropdowns and select the
// appropriate unit
// Initialize validity and renewal period dropdowns
CString text;
VERIFY (text.LoadString (IDS_DAYS));
int nIndex = m_validityUnits.AddString (text);
if ( nIndex >= 0 )
{
m_validityUnits.SetItemData (nIndex, PERIOD_TYPE_DAY);
if ( PERIOD_TYPE_DAY == m_dwCurrentValidityUnits )
m_validityUnits.SetCurSel (nIndex);
}
nIndex = m_renewalUnits.AddString (text);
if ( nIndex >= 0 )
{
m_renewalUnits.SetItemData (nIndex, PERIOD_TYPE_DAY);
if ( PERIOD_TYPE_DAY == m_dwCurrentRenewalUnits )
m_renewalUnits.SetCurSel (nIndex);
}
VERIFY (text.LoadString (IDS_WEEKS));
nIndex = m_validityUnits.AddString (text);
if ( nIndex >= 0 )
{
m_validityUnits.SetItemData (nIndex, PERIOD_TYPE_WEEK);
if ( PERIOD_TYPE_WEEK == m_dwCurrentValidityUnits )
m_validityUnits.SetCurSel (nIndex);
}
nIndex = m_renewalUnits.AddString (text);
if ( nIndex >= 0 )
{
m_renewalUnits.SetItemData (nIndex, PERIOD_TYPE_WEEK);
if ( PERIOD_TYPE_WEEK == m_dwCurrentRenewalUnits )
m_renewalUnits.SetCurSel (nIndex);
}
VERIFY (text.LoadString (IDS_MONTHS));
nIndex = m_validityUnits.AddString (text);
if ( nIndex >= 0 )
{
m_validityUnits.SetItemData (nIndex, PERIOD_TYPE_MONTH);
if ( PERIOD_TYPE_MONTH == m_dwCurrentValidityUnits )
m_validityUnits.SetCurSel (nIndex);
}
nIndex = m_renewalUnits.AddString (text);
if ( nIndex >= 0 )
{
m_renewalUnits.SetItemData (nIndex, PERIOD_TYPE_MONTH);
if ( PERIOD_TYPE_MONTH == m_dwCurrentRenewalUnits )
m_renewalUnits.SetCurSel (nIndex);
}
VERIFY (text.LoadString (IDS_YEARS));
nIndex = m_validityUnits.AddString (text);
if ( nIndex >= 0 )
{
m_validityUnits.SetItemData (nIndex, PERIOD_TYPE_YEAR);
if ( PERIOD_TYPE_YEAR == m_dwCurrentValidityUnits )
m_validityUnits.SetCurSel (nIndex);
}
nIndex = m_renewalUnits.AddString (text);
if ( nIndex >= 0 )
{
m_renewalUnits.SetItemData (nIndex, PERIOD_TYPE_YEAR);
if ( PERIOD_TYPE_YEAR == m_dwCurrentRenewalUnits )
m_renewalUnits.SetCurSel (nIndex);
}
if ( m_rCertTemplate.PublishToDS () )
SendDlgItemMessage (IDC_PUBLISH_TO_AD, BM_SETCHECK, BST_CHECKED);
if ( m_rCertTemplate.CheckDSCert () )
SendDlgItemMessage (IDC_USE_AD_CERT_FOR_REENROLLMENT, BM_SETCHECK, BST_CHECKED);
EnableControls ();
UpdateData (FALSE);
m_bIsDirty = false; // because SetDlgItemInt () sets it to true
if ( m_rCertTemplate.IsClone () )
{
SetModified ();
m_bIsDirty = true;
}
_TRACE (-1, L"Leaving CTemplateGeneralPropertyPage::OnInitDialog ()\n");
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CTemplateGeneralPropertyPage::EnableControls ()
{
if ( 1 == m_rCertTemplate.GetType () || m_rCertTemplate.ReadOnly () )
{
GetDlgItem (IDC_TEMPLATE_NAME)->EnableWindow (FALSE);
GetDlgItem (IDC_TEMPLATE_NAME_LABEL)->EnableWindow (FALSE);
GetDlgItem (IDC_DISPLAY_NAME)->EnableWindow (FALSE);
GetDlgItem (IDC_DISPLAY_NAME_LABEL)->EnableWindow (FALSE);
GetDlgItem (IDC_VALIDITY_UNITS)->EnableWindow (FALSE);
GetDlgItem (IDC_VALIDITY_EDIT)->EnableWindow (FALSE);
GetDlgItem (IDC_RENEWAL_UNITS)->EnableWindow (FALSE);
GetDlgItem (IDC_RENEWAL_EDIT)->EnableWindow (FALSE);
GetDlgItem (IDC_PUBLISH_TO_AD)->EnableWindow (FALSE);
GetDlgItem (IDC_USE_AD_CERT_FOR_REENROLLMENT)->EnableWindow (FALSE);
}
else if ( m_rCertTemplate.IsDefault () )
{
GetDlgItem (IDC_DISPLAY_NAME)->EnableWindow (FALSE);
}
else
{
if ( BST_CHECKED == SendDlgItemMessage (IDC_PUBLISH_TO_AD, BM_GETCHECK) )
GetDlgItem (IDC_USE_AD_CERT_FOR_REENROLLMENT)->EnableWindow (TRUE);
else
GetDlgItem (IDC_USE_AD_CERT_FOR_REENROLLMENT)->EnableWindow (FALSE);
}
}
void CTemplateGeneralPropertyPage::OnCancel()
{
if ( !m_rCertTemplate.IsClone () )
m_rCertTemplate.Cancel ();
CHelpPropertyPage::OnCancel ();
}
int CTemplateGeneralPropertyPage::SetRenewalPeriod (int nMaxRenewalDays, bool bSilent)
{
CThemeContextActivator activator;
CString caption;
CString text;
CString timeUnit;
int nAmount = 0;
VERIFY (caption.LoadString (IDS_CERTTMPL));
if ( nMaxRenewalDays % 365 == 0 )
{
nAmount = nMaxRenewalDays/365;
if ( 1 == nAmount )
VERIFY (timeUnit.LoadString (IDS_YEAR));
else
VERIFY (timeUnit.LoadString (IDS_YEARS));
}
else if ( nMaxRenewalDays % 30 == 0 )
{
nAmount = nMaxRenewalDays/30;
if ( 1 == nAmount )
VERIFY (timeUnit.LoadString (IDS_MONTH));
else
VERIFY (timeUnit.LoadString (IDS_MONTHS));
}
else if ( nMaxRenewalDays % 7 == 0 )
{
nAmount = nMaxRenewalDays/7;
if ( 1 == nAmount )
VERIFY (timeUnit.LoadString (IDS_WEEK));
else
VERIFY (timeUnit.LoadString (IDS_WEEKS));
}
else
{
nAmount = nMaxRenewalDays;
if ( 1 == nMaxRenewalDays )
VERIFY (timeUnit.LoadString (IDS_DAY));
else
VERIFY (timeUnit.LoadString (IDS_DAYS));
}
text.FormatMessage (IDS_RENEWAL_MUST_BE_LESS_THAN_VALIDITY,
nAmount, timeUnit);
int nRetVal = IDOK;
if ( !bSilent )
nRetVal = MessageBox (text, caption, MB_OKCANCEL);
if ( IDOK == nRetVal )
{
HRESULT hr = m_rCertTemplate.SetRenewalPeriod (nMaxRenewalDays);
if ( SUCCEEDED (hr) )
{
m_nRenewalDays = nMaxRenewalDays;
int nValue = m_nRenewalDays;
if ( nValue % 365 == 0 )
{
nValue /= 365;
m_dwCurrentRenewalUnits = PERIOD_TYPE_YEAR;
}
else if ( nValue % 30 == 0 )
{
nValue /= 30;
m_dwCurrentRenewalUnits = PERIOD_TYPE_MONTH;
}
else if ( nValue % 7 == 0 )
{
nValue /= 7;
m_dwCurrentRenewalUnits = PERIOD_TYPE_WEEK;
}
else
m_dwCurrentRenewalUnits = PERIOD_TYPE_DAY;
int nCnt = m_renewalUnits.GetCount ();
while (--nCnt >= 0)
{
if ( m_dwCurrentRenewalUnits == (PERIOD_TYPE) m_renewalUnits.GetItemData (nCnt) )
{
m_renewalUnits.SetCurSel (nCnt);
break;
}
}
// Must set this after the units
SetDlgItemInt (IDC_RENEWAL_EDIT, (UINT) nValue, FALSE);
SetModified ();
m_bIsDirty = true;
}
}
return nRetVal;
}
#define ILLEGAL_FAT_CHARS L"\"+,;<=>"
bool CTemplateGeneralPropertyPage::ValidateTemplateName(const CString& m_szTemplateName)
{
bool bRVal = true;
PCWSTR szInvalidCharSet = ILLEGAL_FAT_CHARS;
if ( -1 != m_szTemplateName.FindOneOf (szInvalidCharSet) )
{
bRVal = false;
CString text;
CString caption;
VERIFY (caption.LoadString (IDS_CERTTMPL));
CString charsWithSpaces;
UINT nIndex = 0;
while (szInvalidCharSet[nIndex])
{
charsWithSpaces += szInvalidCharSet[nIndex];
charsWithSpaces += L" ";
nIndex++;
}
text.FormatMessage (IDS_TEMPLATE_NAME_CONTAINS_INVALID_CHARS, charsWithSpaces);
MessageBox (text, caption, MB_OK);
GetDlgItem (IDC_TEMPLATE_NAME)->SetFocus ();
}
return bRVal;
}
BOOL CTemplateGeneralPropertyPage::OnApply()
{
UpdateData (TRUE);
if ( m_rCertTemplate.GetType () > 1 && m_bIsDirty )
{
HRESULT hr = S_OK;
if ( m_rCertTemplate.IssuancePoliciesRequired () )
{
CString text;
CString caption;
VERIFY (caption.LoadString (IDS_CERTTMPL));
VERIFY (text.LoadString (IDS_MUST_ADD_RA_ISSUANCE_POLICY));
MessageBox (text, caption, MB_OK);
if ( -1 != m_nTemplateV2AuthPageNumber )
{
CWnd* pParent = GetParent ();
if ( pParent )
{
pParent->SendMessage (PSM_SETCURSEL,
m_nTemplateV2AuthPageNumber);
}
}
return FALSE;
}
// NTRAID# 331178 Certtmpl: All Certificate Templates must enforce
// that the certificate Renewal Period < = 75% of the Validity Period
int nMaxRenewalDays = (m_nValidityDays * 3) / 4;
if ( nMaxRenewalDays < m_nRenewalDays )
{
if ( IDOK != SetRenewalPeriod (nMaxRenewalDays, false) )
{
CWnd* pParent = GetParent ();
if ( pParent )
pParent->SendMessage (PSM_SETCURSEL, 0);
GetDlgItem (IDC_VALIDITY_EDIT)->SetFocus ();
return FALSE;
}
}
// NTRAID# 353945: Certtmpl: Changing V2 certificate template validity
// period to 1 Day, automatically sets the renewal period to 0 years
if ( m_nValidityDays < 2 )
{
CString text;
CString caption;
VERIFY (caption.LoadString (IDS_CERTTMPL));
VERIFY (text.LoadString (IDS_2_DAY_SMALLEST_VALIDITY));
MessageBox (text, caption, MB_OK);
CWnd* pParent = GetParent ();
if ( pParent )
pParent->SendMessage (PSM_SETCURSEL, 0);
GetDlgItem (IDC_VALIDITY_EDIT)->SetFocus ();
return FALSE;
}
// Note: The CERTYPE_PROP_CN resets the CERTTYPE_PROP_FRIENDLY_NAME
// and so must be set before it.
bool bResetDisplayName = false;
if ( LocaleStrCmp (m_strTemplateName, m_rCertTemplate.GetTemplateName ()) )
{
bResetDisplayName = true;
// Check new name for invalid characters
m_strTemplateName.TrimLeft ();
m_strTemplateName.TrimRight ();
if ( !ValidateTemplateName (m_strTemplateName) )
return FALSE;
if ( _wcsicmp (m_strOriginalName, m_strTemplateName) ) // was renamed
{
// Ensure that the selected name is unique
HCERTTYPE hCertType = 0;
bool bFound = false;
hr = CAFindCertTypeByName (m_rCertTemplate.GetTemplateName (),
NULL,
CT_ENUM_MACHINE_TYPES | CT_ENUM_USER_TYPES | CT_FLAG_NO_CACHE_LOOKUP,
&hCertType);
if ( SUCCEEDED (hr) )
{
bFound = TRUE;
hr = CACloseCertType (hCertType);
if ( FAILED (hr) )
{
_TRACE (0, L"CACloseCertType () failed: 0x%x", hr);
}
}
else
{
if ( m_pCompData )
{
POSITION pos = 0;
for (pos = m_pCompData->m_globalTemplateNameList.GetHeadPosition (); pos;)
{
if ( !_wcsicmp (m_strTemplateName,
m_pCompData->m_globalTemplateNameList.GetNext (pos)) )
{
bFound = true;
break;
}
}
}
}
if ( bFound )
{
CString caption;
CString text;
VERIFY (caption.LoadString (IDS_CERTTMPL));
text.FormatMessage (IDS_ENTER_UNIQUE_TEMPLATE_NAME,
m_strTemplateName);
MessageBox (text, caption, MB_OK);
GetDlgItem (IDC_TEMPLATE_NAME)->SetFocus ();
return FALSE;
}
}
hr = m_rCertTemplate.SetTemplateName (m_strTemplateName);
if ( FAILED (hr) )
{
CString caption;
CString text;
VERIFY (caption.LoadString (IDS_CERTTMPL));
text.FormatMessage (IDS_CANNOT_CHANGE_TEMPLATE_NAME, hr);
MessageBox (text, caption, MB_OK | MB_ICONWARNING);
CWnd* pParent = GetParent ();
if ( pParent )
pParent->SendMessage (PSM_SETCURSEL, 0);
GetDlgItem (IDC_TEMPLATE_NAME)->SetFocus ();
return FALSE;
}
}
// Check if the display name has changed. Don't allow reuse of existing names.
if ( bResetDisplayName || _wcsicmp (m_strDisplayName, m_strOriginalDisplayName) )
{
bool bFound = false;
if ( m_pCompData )
{
POSITION pos = 0;
for (pos = m_pCompData->m_globalFriendlyNameList.GetHeadPosition (); pos;)
{
if ( !_wcsicmp (m_strDisplayName,
m_pCompData->m_globalFriendlyNameList.GetNext (pos)) )
{
bFound = true;
break;
}
}
}
else
{
// Generate list of templates and search for name. This should only be called
// from the shell extension because it doesn't build the list of templates
// beforehand
hr = FindFriendlyNameInEnterpriseTemplates (
m_strDisplayName,
bFound);
}
if ( bFound )
{
CString caption;
CString text;
VERIFY (caption.LoadString (IDS_CERTTMPL));
text.FormatMessage (IDS_FRIENDLY_NAME_ALREADY_USED, m_strDisplayName);
MessageBox (text, caption, MB_OK);
return FALSE;
}
else
{
hr = m_rCertTemplate.SetDisplayName (m_strDisplayName, true);
if ( FAILED (hr) )
{
CString caption;
CString text;
VERIFY (caption.LoadString (IDS_CERTTMPL));
text.FormatMessage (IDS_CANNOT_CHANGE_DISPLAY_NAME, hr);
MessageBox (text, caption, MB_OK | MB_ICONWARNING);
GetDlgItem (IDC_DISPLAY_NAME)->SetFocus ();
return FALSE;
}
}
}
// // NTRAID# 276180 Certificate Template Snap-in: Grey out "Allow
// // Autoenrollment" context menu based on properties of the template
// DWORD dwNumSignatures = 0;
// m_rCertTemplate.GetRANumSignaturesRequired (dwNumSignatures);
// if ( m_rCertTemplate.RequireSubjectInRequest () ||
// dwNumSignatures >= 2 && !m_rCertTemplate.ReenrollmentValidWithPreviousApproval () )
// {
// m_rCertTemplate.SetAutoEnrollment (false);
// }
hr = m_rCertTemplate.SaveChanges ();
if ( SUCCEEDED (hr) )
{
m_strOriginalName = m_strTemplateName;
hr = MMCPropertyChangeNotify (m_lNotifyHandle, // handle to a notification
(LPARAM) &m_rCertTemplate); // unique identifier
// Now that the template has been saved, never allow the internal
// name to be edited.
GetDlgItem (IDC_TEMPLATE_NAME)->EnableWindow (FALSE);
GetDlgItem (IDC_TEMPLATE_NAME_LABEL)->EnableWindow (FALSE);
// #NTRAID 360650: Cert Server: Cannot rename cert templates
GetDlgItem (IDC_DISPLAY_NAME)->EnableWindow (FALSE);
GetDlgItem (IDC_DISPLAY_NAME_LABEL)->EnableWindow (FALSE);
}
else
{
CString caption;
CString text;
VERIFY (caption.LoadString (IDS_CERTTMPL));
text.FormatMessage (IDS_UNABLE_TO_SAVE_CERT_TEMPLATE_CHANGES, GetSystemMessage (hr));
MessageBox (text, caption, MB_OK | MB_ICONWARNING);
return FALSE;
}
m_bIsDirty = false;
}
return CHelpPropertyPage::OnApply();
}
void CTemplateGeneralPropertyPage::OnChangeDisplayName()
{
SetModified ();
m_bIsDirty = true;
if ( m_rCertTemplate.IsClone () )
{
CString text;
GetDlgItemText (IDC_DISPLAY_NAME, text);
// strip out spaces
PCWSTR pszSrc = (PCWSTR) text;
const int LEN = text.GetLength () + 1;
PWSTR pszTgt = new WCHAR[LEN];
PWSTR pszTgtPtr = pszTgt;
::ZeroMemory (pszTgt, LEN * sizeof (WCHAR));
for (; *pszSrc; pszSrc++)
{
if ( !iswspace (*pszSrc) )
{
*pszTgtPtr = *pszSrc;
pszTgtPtr++;
}
}
SetDlgItemText (IDC_TEMPLATE_NAME, pszTgt);
delete [] pszTgt;
}
}
void CTemplateGeneralPropertyPage::OnChangeTemplateName()
{
UpdateData (TRUE);
SetModified ();
m_bIsDirty = true;
}
void CTemplateGeneralPropertyPage::OnSelchangeRenewalUnits()
{
OnChangeRenewalEdit ();
}
void CTemplateGeneralPropertyPage::OnSelchangeValidityUnits()
{
OnChangeValidityEdit ();
}
void CTemplateGeneralPropertyPage::OnChangeRenewalEdit()
{
HRESULT hr = S_OK;
int nCurSel = m_renewalUnits.GetCurSel ();
if ( nCurSel < 0 )
return;
int nCurVal = GetDlgItemInt (IDC_RENEWAL_EDIT);
DWORD dwRenewalUnits = (PERIOD_TYPE) m_renewalUnits.GetItemData (nCurSel);
// convert to days
switch ( dwRenewalUnits )
{
case PERIOD_TYPE_DAY:
break; // do nothing - is already days
case PERIOD_TYPE_WEEK:
nCurVal *= 7;
break;
case PERIOD_TYPE_MONTH:
nCurVal *= 30;
break;
case PERIOD_TYPE_YEAR:
nCurVal *= 365;
break;
case PERIOD_TYPE_NONE:
default:
_ASSERT (0);
hr = E_FAIL; //don't know what the units are
break;
}
if ( SUCCEEDED (hr) )
{
hr = m_rCertTemplate.SetRenewalPeriod (nCurVal);
if ( SUCCEEDED (hr) )
{
m_nRenewalDays = nCurVal;
SetModified ();
m_bIsDirty = true;
}
}
}
void CTemplateGeneralPropertyPage::OnChangeValidityEdit()
{
HRESULT hr = S_OK;
int nCurSel = m_validityUnits.GetCurSel ();
if ( nCurSel < 0 )
return;
int nCurVal = GetDlgItemInt (IDC_VALIDITY_EDIT);
DWORD dwValidityUnits = (PERIOD_TYPE) m_validityUnits.GetItemData (nCurSel);
// convert to days
switch ( dwValidityUnits )
{
case PERIOD_TYPE_DAY:
break; // do nothing - is already days
case PERIOD_TYPE_WEEK:
nCurVal *= 7;
break;
case PERIOD_TYPE_MONTH:
nCurVal *= 30;
break;
case PERIOD_TYPE_YEAR:
nCurVal *= 365;
break;
case PERIOD_TYPE_NONE:
default:
_ASSERT (0);
hr = E_FAIL; //don't know what the units are
break;
}
if ( SUCCEEDED (hr) )
{
hr = m_rCertTemplate.SetValidityPeriod (nCurVal);
if ( SUCCEEDED (hr) )
{
m_nValidityDays = nCurVal;
SetModified ();
m_bIsDirty = true;
}
}
}
void CTemplateGeneralPropertyPage::OnPublishToAd()
{
bool bPublishToAD = BST_CHECKED == SendDlgItemMessage (IDC_PUBLISH_TO_AD, BM_GETCHECK);
m_rCertTemplate.SetPublishToDS (bPublishToAD);
if ( !bPublishToAD )
{
SendDlgItemMessage (IDC_USE_AD_CERT_FOR_REENROLLMENT, BM_SETCHECK, BST_UNCHECKED);
m_rCertTemplate.SetCheckDSCert (false);
}
SetModified ();
m_bIsDirty = true;
EnableControls ();
}
void CTemplateGeneralPropertyPage::DoContextHelp (HWND hWndControl)
{
_TRACE(1, L"Entering CTemplateGeneralPropertyPage::DoContextHelp\n");
switch (::GetDlgCtrlID (hWndControl))
{
case IDC_STATIC:
break;
default:
// Display context help for a control
if ( !::WinHelp (
hWndControl,
GetContextHelpFile (),
HELP_WM_HELP,
(DWORD_PTR) g_aHelpIDs_IDD_TEMPLATE_GENERAL) )
{
_TRACE(0, L"WinHelp () failed: 0x%x\n", GetLastError ());
}
break;
}
_TRACE(-1, L"Leaving CTemplateGeneralPropertyPage::DoContextHelp\n");
}
void CTemplateGeneralPropertyPage::OnUseADCert()
{
bool bCheck = (BST_CHECKED == SendDlgItemMessage (IDC_USE_AD_CERT_FOR_REENROLLMENT, BM_GETCHECK) );
m_rCertTemplate.SetCheckDSCert (bCheck);
m_bIsDirty = true;
SetModified ();
}
HRESULT CTemplateGeneralPropertyPage::EnumerateTemplates (
IDirectoryObject* pTemplateContObj,
const CString& szFriendlyName,
bool& bFound)
{
_TRACE (1, L"Entering CTemplateGeneralPropertyPage::EnumerateTemplates\n");
CComPtr<IDirectorySearch> spDsSearch;
HRESULT hr = pTemplateContObj->QueryInterface (IID_PPV_ARG(IDirectorySearch, &spDsSearch));
if ( SUCCEEDED (hr) )
{
ASSERT (!!spDsSearch);
ADS_SEARCHPREF_INFO pSearchPref[1];
DWORD dwNumPref = 1;
pSearchPref[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
pSearchPref[0].vValue.dwType = ADSTYPE_INTEGER;
pSearchPref[0].vValue.Integer = ADS_SCOPE_ONELEVEL;
hr = spDsSearch->SetSearchPreference(
pSearchPref,
dwNumPref
);
if ( SUCCEEDED (hr) )
{
static const DWORD cAttrs = 1; //2;
static PWSTR rgszAttrList[cAttrs] = {L"displayName"}; //, L"cn"};
ADS_SEARCH_HANDLE hSearchHandle = 0;
wstring strQuery;
ADS_SEARCH_COLUMN Column;
Column.pszAttrName = 0;
strQuery = L"objectClass=pKICertificateTemplate";
hr = spDsSearch->ExecuteSearch(
const_cast <PWSTR>(strQuery.c_str ()),
rgszAttrList,
cAttrs,
&hSearchHandle
);
if ( SUCCEEDED (hr) )
{
while ((hr = spDsSearch->GetNextRow (hSearchHandle)) != S_ADS_NOMORE_ROWS )
{
if (FAILED(hr))
continue;
//
// Getting current row's information
//
hr = spDsSearch->GetColumn(
hSearchHandle,
rgszAttrList[0],
&Column
);
if ( SUCCEEDED (hr) )
{
CString strDisplayName = Column.pADsValues->CaseIgnoreString;
if ( !_wcsicmp (strDisplayName, szFriendlyName) )
{
bFound = true;
}
spDsSearch->FreeColumn (&Column);
if ( bFound )
break;
}
else if ( hr != E_ADS_COLUMN_NOT_SET )
{
break;
}
else
{
_TRACE (0, L"IDirectorySearch::GetColumn () failed: 0x%x\n", hr);
}
}
}
else
{
_TRACE (0, L"IDirectorySearch::ExecuteSearch () failed: 0x%x\n", hr);
}
spDsSearch->CloseSearchHandle(hSearchHandle);
}
else
{
_TRACE (0, L"IDirectorySearch::SetSearchPreference () failed: 0x%x\n", hr);
}
}
else
{
_TRACE (0, L"IDirectoryObject::QueryInterface (IDirectorySearch) failed: 0x%x\n", hr);
}
_TRACE (-1, L"Leaving CTemplateGeneralPropertyPage::EnumerateTemplates: 0x%x\n", hr);
return hr;
}
HRESULT CTemplateGeneralPropertyPage::FindFriendlyNameInEnterpriseTemplates (
const CString& szFriendlyName,
bool& bFound)
{
_TRACE (1, L"Entering CTemplateGeneralPropertyPage::FindFriendlyNameInEnterpriseTemplates\n");
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = S_OK;
CComPtr<IADsPathname> spPathname;
//
// Constructing the directory paths
//
hr = CoCreateInstance(
CLSID_Pathname,
NULL,
CLSCTX_ALL,
IID_PPV_ARG (IADsPathname, &spPathname));
if ( SUCCEEDED (hr) )
{
ASSERT (!!spPathname);
hr = spPathname->Set(const_cast <PWSTR> (CERTTMPL_LDAP),
ADS_SETTYPE_PROVIDER);
if ( SUCCEEDED (hr) )
{
//
// Open the root DSE object
//
hr = spPathname->AddLeafElement(const_cast <PWSTR> (CERTTMPL_ROOTDSE));
if ( SUCCEEDED (hr) )
{
BSTR bstrFullPath = 0;
hr = spPathname->Retrieve(ADS_FORMAT_X500, &bstrFullPath);
if ( SUCCEEDED (hr) )
{
CComPtr<IADs> spRootDSEObject;
VARIANT varNamingContext;
hr = ADsGetObject (
bstrFullPath,
IID_PPV_ARG (IADs, &spRootDSEObject));
if ( SUCCEEDED (hr) )
{
ASSERT (!!spRootDSEObject);
//
// Get the configuration naming context from the root DSE
//
hr = spRootDSEObject->Get(const_cast <PWSTR> (CERTTMPL_CONFIG_NAMING_CONTEXT),
&varNamingContext);
if ( SUCCEEDED (hr) )
{
hr = spPathname->Set(V_BSTR(&varNamingContext),
ADS_SETTYPE_DN);
if ( SUCCEEDED (hr) )
{
hr = spPathname->AddLeafElement (L"CN=Services");
if ( SUCCEEDED (hr) )
{
hr = spPathname->AddLeafElement (L"CN=Public Key Services");
if ( SUCCEEDED (hr) )
{
hr = spPathname->AddLeafElement (L"CN=Certificate Templates");
if ( SUCCEEDED (hr) )
{
BSTR bstrCertTemplatePath = 0;
hr = spPathname->Retrieve(ADS_FORMAT_X500, &bstrCertTemplatePath);
if ( SUCCEEDED (hr) )
{
CComPtr<IDirectoryObject> spTemplateContObj;
hr = ADsGetObject (
bstrCertTemplatePath,
IID_PPV_ARG (IDirectoryObject, &spTemplateContObj));
if ( SUCCEEDED (hr) )
{
hr = EnumerateTemplates (spTemplateContObj,
szFriendlyName, bFound);
}
else
{
_TRACE (0, L"ADsGetObject (%s) failed: 0x%x\n", bstrCertTemplatePath, hr);
}
SysFreeString (bstrCertTemplatePath);
}
}
}
}
}
}
else
{
_TRACE (0, L"IADs::Get (%s) failed: 0x%x\n", CERTTMPL_CONFIG_NAMING_CONTEXT, hr);
}
}
else
{
_TRACE (0, L"ADsGetObject (%s) failed: 0x%x\n", bstrFullPath, hr);
}
}
}
}
}
else
hr = E_POINTER;
_TRACE (-1, L"Leaving CTemplateGeneralPropertyPage::FindFriendlyNameInEnterpriseTemplates\n");
return hr;
}
void CTemplateGeneralPropertyPage::OnKillfocusValidityEdit()
{
// NTRAID# 331178 Certtmpl: All Certificate Templates must enforce
// that the certificate Renewal Period < = 75% of the Validity Period
int nMaxRenewalDays = (m_nValidityDays * 3) / 4;
if ( nMaxRenewalDays < m_nRenewalDays )
{
// change without confirmation
SetRenewalPeriod (nMaxRenewalDays, true);
GetDlgItem (IDC_VALIDITY_EDIT)->SetFocus ();
}
}
void CTemplateGeneralPropertyPage::OnKillfocusValidityUnits()
{
// NTRAID# 331178 Certtmpl: All Certificate Templates must enforce
// that the certificate Renewal Period < = 75% of the Validity Period
int nMaxRenewalDays = (m_nValidityDays * 3) / 4;
if ( nMaxRenewalDays < m_nRenewalDays )
{
// change without confirmation
SetRenewalPeriod (nMaxRenewalDays, true);
GetDlgItem (IDC_VALIDITY_EDIT)->SetFocus ();
}
}