///////////////////////////////////////////////////////////////////////////////// // // 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 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 (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 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 (CERTTMPL_LDAP), ADS_SETTYPE_PROVIDER); if ( SUCCEEDED (hr) ) { // // Open the root DSE object // hr = spPathname->AddLeafElement(const_cast (CERTTMPL_ROOTDSE)); if ( SUCCEEDED (hr) ) { BSTR bstrFullPath = 0; hr = spPathname->Retrieve(ADS_FORMAT_X500, &bstrFullPath); if ( SUCCEEDED (hr) ) { CComPtr 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 (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 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 (); } }