1810 lines
52 KiB
C++
1810 lines
52 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1997-2001.
|
|
//
|
|
// File: cmponent.cpp
|
|
//
|
|
// Contents: Implementation of CCertTmplComponent
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "dbg.h"
|
|
#include "compdata.h" // CCertTmplComponentData
|
|
#include "dataobj.h"
|
|
#include "cmponent.h" // CCertTmplComponent
|
|
#include "utils.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
DECLARE_INFOLEVEL(CertTmplSnapin)
|
|
|
|
USE_HANDLE_MACROS ("CERTTMPL (cmponent.cpp)")
|
|
|
|
#pragma warning(push,3)
|
|
#include "stdcmpnt.cpp" // CComponent
|
|
#pragma warning(pop)
|
|
|
|
UINT m_aColumnsSnapinSelected[CERT_TEMPLATES_NUM_COLS+1] =
|
|
{IDS_COLUMN_CERT_TEMPLATE_OBJECT,
|
|
IDS_COLUMN_CERT_TEMPLATE_TYPE,
|
|
IDS_COLUMN_CERT_TEMPLATE_VERSION,
|
|
IDS_COLUMN_CERT_TEMPLATE_AUTOENROLLMENT,
|
|
0};
|
|
|
|
UINT* m_Columns[CERTTMPL_NUMTYPES] =
|
|
{
|
|
m_aColumnsSnapinSelected, // CERTTMPL_SNAPIN (displays certificate templates in the result pane)
|
|
0
|
|
};
|
|
|
|
|
|
|
|
UINT** g_aColumns = 0; // for framework
|
|
int** g_aColumnWidths = 0; // for framework
|
|
const int SINGLE_COL_WIDTH = 300;
|
|
|
|
CCertTmplComponent::CCertTmplComponent ()
|
|
: m_pViewedCookie (NULL),
|
|
m_currResultNodeType (CERTTMPL_INVALID)
|
|
{
|
|
_TRACE (1, L"Entering CCertTmplComponent::CCertTmplComponent\n");
|
|
AFX_MANAGE_STATE (AfxGetStaticModuleState ( ));
|
|
|
|
::ZeroMemory (m_ColumnWidths, (sizeof (UINT*) * CERTTMPL_NUMTYPES));
|
|
|
|
m_ColumnWidths[CERTTMPL_SNAPIN] = new UINT[CERT_TEMPLATES_NUM_COLS];
|
|
if ( m_ColumnWidths[CERTTMPL_SNAPIN] )
|
|
{
|
|
m_ColumnWidths[CERTTMPL_SNAPIN][COLNUM_CERT_TEMPLATE_OBJECT] = 250;
|
|
m_ColumnWidths[CERTTMPL_SNAPIN][COLNUM_CERT_TEMPLATE_TYPE] = 150;
|
|
m_ColumnWidths[CERTTMPL_SNAPIN][COLNUM_CERT_TEMPLATE_VERSION] = 50;
|
|
m_ColumnWidths[CERTTMPL_SNAPIN][COLNUM_CERT_TEMPLATE_AUTOENROLL_STATUS] = 100;
|
|
}
|
|
|
|
_TRACE (-1, L"Leaving CCertTmplComponent::CCertTmplComponent\n");
|
|
}
|
|
|
|
CCertTmplComponent::~CCertTmplComponent ()
|
|
{
|
|
_TRACE (1, L"Entering CCertTmplComponent::~CCertTmplComponent\n");
|
|
VERIFY ( SUCCEEDED (ReleaseAll ()) );
|
|
|
|
for (int i = 0; i < CERTTMPL_NUMTYPES; i++)
|
|
{
|
|
if ( m_ColumnWidths[i] )
|
|
delete [] m_ColumnWidths[i];
|
|
}
|
|
_TRACE (-1, L"Leaving CCertTmplComponent::~CCertTmplComponent\n");
|
|
}
|
|
|
|
HRESULT CCertTmplComponent::ReleaseAll ()
|
|
{
|
|
return CComponent::ReleaseAll ();
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// IComponent Implementation
|
|
|
|
HRESULT CCertTmplComponent::LoadStrings ()
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CCertTmplComponent::LoadColumns ( CCertTmplCookie* pcookie )
|
|
{
|
|
AFX_MANAGE_STATE (AfxGetStaticModuleState ());
|
|
_TRACE (1, L"Entering CCertTmplComponent::LoadColumns\n");
|
|
HRESULT hr = S_OK;
|
|
|
|
|
|
hr = LoadColumnsFromArrays (pcookie->m_objecttype);
|
|
|
|
_TRACE (-1, L"Leaving CCertTmplComponent::LoadColumns\n");
|
|
return hr;
|
|
}
|
|
|
|
|
|
/* This is generated by UpdateAllViews () */
|
|
HRESULT CCertTmplComponent::OnViewChange (LPDATAOBJECT pDataObject, LPARAM /*data*/, LPARAM hint)
|
|
{
|
|
_TRACE (1, L"Entering CCertTmplComponent::OnViewChange\n");
|
|
ASSERT (pDataObject);
|
|
if ( !pDataObject )
|
|
return E_POINTER;
|
|
|
|
CCertTmplComponentData& compData = QueryComponentDataRef ();
|
|
HRESULT hr = S_OK;
|
|
|
|
if ( hint & UPDATE_HINT_ENUM_CERT_TEMPLATES )
|
|
{
|
|
hr = RefreshResultPane (false);
|
|
return hr;
|
|
}
|
|
|
|
hr = RefreshResultPane (false);
|
|
|
|
|
|
CCertTmplCookie* pCookie = compData.ConvertCookie (pDataObject);
|
|
if ( pCookie )
|
|
{
|
|
switch (pCookie->m_objecttype)
|
|
{
|
|
case CERTTMPL_CERT_TEMPLATE:
|
|
break;
|
|
|
|
case CERTTMPL_SNAPIN:
|
|
break;
|
|
|
|
default:
|
|
{
|
|
IConsole2* pConsole2 = 0;
|
|
hr = m_pConsole->QueryInterface (
|
|
IID_PPV_ARG(IConsole2, &pConsole2));
|
|
if (SUCCEEDED (hr))
|
|
{
|
|
hr = pConsole2->SetStatusText (L"");
|
|
if ( !SUCCEEDED (hr) )
|
|
{
|
|
_TRACE (0, L"IConsole2::SetStatusText () failed: %x", hr);
|
|
}
|
|
pConsole2->Release ();
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
_TRACE (-1, L"Leaving CCertTmplComponent::OnViewChange\n");
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CCertTmplComponent::Show (
|
|
CCookie* pcookie,
|
|
LPARAM arg,
|
|
HSCOPEITEM /*hScopeItem*/,
|
|
LPDATAOBJECT /*pDataObject*/)
|
|
{
|
|
AFX_MANAGE_STATE (AfxGetStaticModuleState ());
|
|
HRESULT hr = S_OK;
|
|
|
|
if ( !arg )
|
|
{
|
|
if ( !m_pResultData )
|
|
{
|
|
ASSERT ( FALSE );
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
m_pViewedCookie = dynamic_cast <CCertTmplCookie*> (pcookie);
|
|
ASSERT (m_pViewedCookie);
|
|
if ( m_pViewedCookie )
|
|
hr = SaveWidths (m_pViewedCookie);
|
|
m_pViewedCookie = 0;
|
|
return S_OK;
|
|
}
|
|
|
|
m_pViewedCookie = dynamic_cast <CCertTmplCookie*> (pcookie);
|
|
ASSERT (m_pViewedCookie);
|
|
if ( m_pViewedCookie )
|
|
{
|
|
// Load default columns and widths
|
|
LoadColumns (m_pViewedCookie);
|
|
|
|
// Restore persisted column widths
|
|
switch (m_pViewedCookie->m_objecttype)
|
|
{
|
|
case CERTTMPL_SNAPIN:
|
|
break;
|
|
|
|
case CERTTMPL_CERT_TEMPLATE: // not a scope pane item
|
|
ASSERT (0);
|
|
break;
|
|
|
|
default:
|
|
ASSERT (0);
|
|
break;
|
|
}
|
|
|
|
hr = PopulateListbox (m_pViewedCookie);
|
|
if ( FAILED (hr) )
|
|
{
|
|
CString caption;
|
|
CString text;
|
|
|
|
VERIFY (caption.LoadString (IDS_CERTTMPL));
|
|
|
|
text.FormatMessage (IDS_CANNOT_ENUM_CERT_TEMPLATES, GetSystemMessage (hr));
|
|
|
|
int iRetVal = 0;
|
|
VERIFY (SUCCEEDED (m_pConsole->MessageBox (text, caption,
|
|
MB_ICONWARNING | MB_OK, &iRetVal)));
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CCertTmplComponent::Show ( CCookie* pcookie, LPARAM arg, HSCOPEITEM hScopeItem)
|
|
{
|
|
ASSERT (0);
|
|
return Show (pcookie, arg, hScopeItem, 0);
|
|
}
|
|
|
|
|
|
HRESULT CCertTmplComponent::OnNotifyAddImages (LPDATAOBJECT /*pDataObject*/,
|
|
LPIMAGELIST lpImageList,
|
|
HSCOPEITEM /*hSelectedItem*/)
|
|
{
|
|
long lViewMode = 0;
|
|
|
|
ASSERT (m_pResultData);
|
|
QueryComponentDataRef ().SetResultData (m_pResultData);
|
|
|
|
HRESULT hr = m_pResultData->GetViewMode (&lViewMode);
|
|
ASSERT (SUCCEEDED (hr));
|
|
BOOL bLoadLargeIcons = (LVS_ICON == lViewMode);
|
|
|
|
return QueryComponentDataRef ().LoadIcons (lpImageList, bLoadLargeIcons);
|
|
}
|
|
|
|
|
|
HRESULT CCertTmplComponent::PopulateListbox (CCertTmplCookie* pCookie)
|
|
{
|
|
_TRACE (1, L"Entering CCertTmplComponent::PopulateListbox\n");
|
|
HRESULT hr = S_OK;
|
|
|
|
|
|
switch ( pCookie->m_objecttype )
|
|
{
|
|
case CERTTMPL_SNAPIN:
|
|
hr = AddEnterpriseTemplates ();
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
m_currResultNodeType = CERTTMPL_CERT_TEMPLATE;
|
|
}
|
|
break;
|
|
|
|
case CERTTMPL_CERT_TEMPLATE:
|
|
ASSERT (0);
|
|
break;
|
|
|
|
default:
|
|
ASSERT (0);
|
|
break;
|
|
}
|
|
|
|
_TRACE (-1, L"Leaving CCertTmplComponent::PopulateListbox\n");
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CCertTmplComponent::RefreshResultPane (const bool bSilent)
|
|
{
|
|
_TRACE (1, L"Entering CCertTmplComponent::RefreshResultPane\n");
|
|
HRESULT hr = S_OK;
|
|
|
|
ASSERT (NULL != m_pResultData);
|
|
if ( m_pResultData )
|
|
{
|
|
m_pResultData->DeleteAllRsltItems ();
|
|
}
|
|
else
|
|
hr = E_UNEXPECTED;
|
|
|
|
if ( m_pViewedCookie )
|
|
{
|
|
hr = PopulateListbox (m_pViewedCookie);
|
|
if ( FAILED (hr) && !bSilent )
|
|
{
|
|
CString caption;
|
|
CString text;
|
|
|
|
VERIFY (caption.LoadString (IDS_CERTTMPL));
|
|
|
|
text.FormatMessage (IDS_CANNOT_ENUM_CERT_TEMPLATES, GetSystemMessage (hr));
|
|
|
|
int iRetVal = 0;
|
|
VERIFY (SUCCEEDED (m_pConsole->MessageBox (text, caption,
|
|
MB_ICONWARNING | MB_OK, &iRetVal)));
|
|
}
|
|
}
|
|
|
|
_TRACE (-1, L"Leaving CCertTmplComponent::RefreshResultPane\n");
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CCertTmplComponent::GetDisplayInfo (RESULTDATAITEM * pResult)
|
|
{
|
|
AFX_MANAGE_STATE (AfxGetStaticModuleState ());
|
|
ASSERT (pResult);
|
|
HRESULT hr = S_OK;
|
|
|
|
|
|
if ( pResult && !pResult->bScopeItem ) //&& (pResult->mask & RDI_PARAM) )
|
|
{
|
|
CCookie* pResultCookie = reinterpret_cast<CCookie*> (pResult->lParam);
|
|
ASSERT (pResultCookie);
|
|
if ( !pResultCookie || IsBadWritePtr ((LPVOID) pResultCookie, sizeof (CCookie)) )
|
|
return E_UNEXPECTED;
|
|
|
|
CCookie* pActiveCookie = ActiveBaseCookie (pResultCookie);
|
|
ASSERT (pActiveCookie);
|
|
if ( !pActiveCookie || IsBadWritePtr ((LPVOID) pActiveCookie, sizeof (CCookie)) )
|
|
return E_UNEXPECTED;
|
|
|
|
CCertTmplCookie* pCookie = dynamic_cast <CCertTmplCookie*>(pActiveCookie);
|
|
ASSERT (pCookie);
|
|
switch (pCookie->m_objecttype)
|
|
{
|
|
case CERTTMPL_CERT_TEMPLATE:
|
|
{
|
|
CCertTemplate* pCertTemplate = reinterpret_cast <CCertTemplate*> (pCookie);
|
|
ASSERT (pCertTemplate);
|
|
if ( pCertTemplate )
|
|
{
|
|
if (pResult->mask & RDI_STR)
|
|
{
|
|
// Note: text is first stored in class variable so that the buffer is
|
|
// somewhat persistent. Copying the buffer pointer directly to the
|
|
// pResult->str would result in the buffer being freed before the pointer
|
|
// is used.
|
|
switch (pResult->nCol)
|
|
{
|
|
case COLNUM_CERT_TEMPLATE_OBJECT:
|
|
m_szDisplayInfoResult = pCertTemplate->GetDisplayName ();
|
|
break;
|
|
|
|
case COLNUM_CERT_TEMPLATE_TYPE:
|
|
{
|
|
DWORD dwVersion = pCertTemplate->GetType ();
|
|
switch (dwVersion)
|
|
{
|
|
case 1:
|
|
VERIFY (m_szDisplayInfoResult.LoadString (IDS_WINDOWS_2000_AND_LATER));
|
|
break;
|
|
|
|
case 2:
|
|
VERIFY (m_szDisplayInfoResult.LoadString (IDS_WINDOWS_2002_AND_LATER));
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case COLNUM_CERT_TEMPLATE_VERSION:
|
|
{
|
|
DWORD dwMajorVersion = 0;
|
|
DWORD dwMinorVersion = 0;
|
|
|
|
hr = pCertTemplate->GetMajorVersion (dwMajorVersion);
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
hr = pCertTemplate->GetMinorVersion (dwMinorVersion);
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
WCHAR str[32];
|
|
m_szDisplayInfoResult = _ultow (dwMajorVersion, str, 10);
|
|
m_szDisplayInfoResult += L".";
|
|
m_szDisplayInfoResult += _ultow (dwMinorVersion, str, 10);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case COLNUM_CERT_TEMPLATE_AUTOENROLL_STATUS:
|
|
if ( pCertTemplate->GoodForAutoEnrollment () )
|
|
VERIFY (m_szDisplayInfoResult.LoadString (IDS_VALID_FOR_AUTOENROLLMENT));
|
|
else
|
|
VERIFY (m_szDisplayInfoResult.LoadString (IDS_INVALID_FOR_AUTOENROLLMENT));
|
|
break;
|
|
|
|
default:
|
|
ASSERT (0);
|
|
break;
|
|
}
|
|
|
|
pResult->str = const_cast<LPWSTR> ( (LPCWSTR) m_szDisplayInfoResult);
|
|
}
|
|
if (pResult->mask & RDI_IMAGE)
|
|
{
|
|
if ( 1 == pCertTemplate->GetType () )
|
|
pResult->nImage = iIconCertTemplateV1;
|
|
else
|
|
pResult->nImage = iIconCertTemplateV2;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
ASSERT (0);
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
hr = CComponent::GetDisplayInfo (pResult);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// IExtendContextMenu implementation
|
|
//
|
|
STDMETHODIMP CCertTmplComponent::AddMenuItems (LPDATAOBJECT pDataObject,
|
|
LPCONTEXTMENUCALLBACK pContextMenuCallback,
|
|
long *pInsertionAllowed)
|
|
{
|
|
return QueryComponentDataRef ().AddMenuItems (pDataObject,
|
|
pContextMenuCallback, pInsertionAllowed);
|
|
}
|
|
|
|
|
|
STDMETHODIMP CCertTmplComponent::Command (long nCommandID, LPDATAOBJECT pDataObject)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = QueryComponentDataRef ().Command (nCommandID, pDataObject);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CCertTmplComponent::OnNotifyDblClick (LPDATAOBJECT pDataObject)
|
|
{
|
|
_TRACE (1, L"Entering CCertTmplComponent::OnNotifyDblClick\n");
|
|
HRESULT hr = S_OK;
|
|
ASSERT (pDataObject);
|
|
|
|
CCertTmplCookie* pParentCookie =
|
|
QueryComponentDataRef ().ConvertCookie (pDataObject);
|
|
if ( pParentCookie )
|
|
{
|
|
switch ( pParentCookie->m_objecttype )
|
|
{
|
|
case CERTTMPL_SNAPIN:
|
|
hr = S_FALSE;
|
|
break;
|
|
|
|
case CERTTMPL_CERT_TEMPLATE:
|
|
hr = S_FALSE;
|
|
break;
|
|
|
|
default:
|
|
_TRACE (0, L"CCertTmplComponentData::OnNotifyDblClick bad parent type\n");
|
|
ASSERT (FALSE);
|
|
hr = S_OK;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
hr = E_UNEXPECTED;
|
|
|
|
|
|
_TRACE (-1, L"Leaving CCertTmplComponent::OnNotifyDblClick\n");
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CCertTmplComponent::OnNotifySelect (LPDATAOBJECT pDataObject, BOOL /*fSelected*/)
|
|
{
|
|
ASSERT (m_pConsoleVerb && 0xdddddddd != (UINT_PTR) m_pConsoleVerb);
|
|
if ( !m_pConsoleVerb || 0xdddddddd == (UINT_PTR) m_pConsoleVerb )
|
|
return E_FAIL;
|
|
|
|
|
|
HRESULT hr = S_OK;
|
|
CCertTmplComponentData& compData = QueryComponentDataRef ();
|
|
|
|
|
|
switch (compData.GetObjectType (pDataObject))
|
|
{
|
|
case CERTTMPL_SNAPIN:
|
|
m_pConsoleVerb->SetVerbState (MMC_VERB_REFRESH, ENABLED, TRUE);
|
|
m_pConsoleVerb->SetDefaultVerb (MMC_VERB_OPEN);
|
|
DisplayRootNodeStatusBarText (m_pConsole);
|
|
break;
|
|
|
|
case CERTTMPL_CERT_TEMPLATE:
|
|
{
|
|
CCertTmplCookie* pCookie = ConvertCookie (pDataObject);
|
|
if ( pCookie )
|
|
{
|
|
CCertTemplate* pCertTemplate = dynamic_cast <CCertTemplate*> (pCookie);
|
|
if ( pCertTemplate )
|
|
{
|
|
if ( !pCertTemplate->IsDefault () )
|
|
m_pConsoleVerb->SetVerbState (MMC_VERB_DELETE, ENABLED, TRUE);
|
|
|
|
// #NTRAID 360650: Cert Server: Cannot rename cert templates
|
|
//if ( 1 != pCertTemplate->GetType () && !pCertTemplate->IsDefault () )
|
|
// m_pConsoleVerb->SetVerbState (MMC_VERB_RENAME, ENABLED, TRUE);
|
|
}
|
|
}
|
|
}
|
|
m_pConsoleVerb->SetVerbState (MMC_VERB_PROPERTIES, ENABLED, TRUE);
|
|
m_pConsoleVerb->SetDefaultVerb (MMC_VERB_PROPERTIES);
|
|
m_currResultNodeType = CERTTMPL_CERT_TEMPLATE;
|
|
DisplayObjectCountInStatusBar (m_pConsole,
|
|
QueryComponentDataRef ().m_dwNumCertTemplates);
|
|
break;
|
|
|
|
case CERTTMPL_MULTISEL:
|
|
m_pConsoleVerb->SetVerbState (MMC_VERB_DELETE, ENABLED, TRUE);
|
|
m_currResultNodeType = CERTTMPL_MULTISEL;
|
|
DisplayObjectCountInStatusBar (m_pConsole,
|
|
QueryComponentDataRef ().m_dwNumCertTemplates);
|
|
break;
|
|
|
|
default:
|
|
m_currResultNodeType = CERTTMPL_INVALID;
|
|
hr = E_UNEXPECTED;
|
|
break;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CCertTmplComponent::CreatePropertyPages (
|
|
LPPROPERTYSHEETCALLBACK pCallBack,
|
|
LONG_PTR handle, // This handle must be saved in the property page object to notify the parent when modified
|
|
LPDATAOBJECT pDataObject)
|
|
{
|
|
return QueryComponentDataRef ().CreatePropertyPages (pCallBack, handle, pDataObject);
|
|
}
|
|
|
|
STDMETHODIMP CCertTmplComponent::QueryPagesFor (LPDATAOBJECT pDataObject)
|
|
{
|
|
return QueryComponentDataRef ().QueryPagesFor (pDataObject);
|
|
}
|
|
|
|
|
|
HRESULT CCertTmplComponent::OnNotifyRefresh (LPDATAOBJECT pDataObject)
|
|
{
|
|
_TRACE (1, L"Entering CCertTmplComponent::OnNotifyRefresh\n");
|
|
ASSERT (pDataObject);
|
|
if ( !pDataObject )
|
|
return E_POINTER;
|
|
|
|
HRESULT hr = S_OK;
|
|
CWaitCursor waitCursor;
|
|
|
|
CCertTmplCookie* pCookie = ConvertCookie (pDataObject);
|
|
if ( !pCookie )
|
|
return E_UNEXPECTED;
|
|
|
|
CCertTmplComponentData& dataRef = QueryComponentDataRef ();
|
|
|
|
switch (pCookie->m_objecttype)
|
|
{
|
|
case CERTTMPL_SNAPIN:
|
|
{
|
|
// Delete all the scope items and force a reexpansion
|
|
hr = dataRef.DeleteScopeItems ();
|
|
hr = PopulateListbox (m_pViewedCookie);
|
|
if ( FAILED (hr) )
|
|
{
|
|
CString caption;
|
|
CString text;
|
|
|
|
VERIFY (caption.LoadString (IDS_CERTTMPL));
|
|
|
|
text.FormatMessage (IDS_CANNOT_ENUM_CERT_TEMPLATES, GetSystemMessage (hr));
|
|
|
|
int iRetVal = 0;
|
|
VERIFY (SUCCEEDED (m_pConsole->MessageBox (text, caption,
|
|
MB_ICONWARNING | MB_OK, &iRetVal)));
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CERTTMPL_CERT_TEMPLATE:
|
|
ASSERT (0);
|
|
break;
|
|
|
|
default:
|
|
ASSERT (0);
|
|
hr = E_UNEXPECTED;
|
|
break;
|
|
}
|
|
|
|
_TRACE (-1, L"Leaving CCertTmplComponent::OnNotifyRefresh\n");
|
|
return hr;
|
|
}
|
|
|
|
void CCertTmplComponent::SetTextNotAvailable ()
|
|
{
|
|
AFX_MANAGE_STATE (AfxGetStaticModuleState ());
|
|
m_szDisplayInfoResult.LoadString (IDS_NOT_AVAILABLE);
|
|
}
|
|
|
|
|
|
HRESULT CCertTmplComponent::DeleteCookie (CCertTmplCookie* pCookie, LPDATAOBJECT pDataObject, bool bRequestConfirmation, bool bIsMultipleSelect)
|
|
{
|
|
_TRACE (1, L"Entering CCertTmplComponent::DeleteCookie\n");
|
|
HRESULT hr = S_OK;
|
|
CString text;
|
|
CString caption;
|
|
int iRetVal = IDYES;
|
|
CWaitCursor waitCursor;
|
|
|
|
switch (pCookie->m_objecttype)
|
|
{
|
|
case CERTTMPL_CERT_TEMPLATE:
|
|
{
|
|
CCertTemplate* pCertTemplate = dynamic_cast <CCertTemplate*> (pCookie);
|
|
ASSERT (pCertTemplate);
|
|
if ( pCertTemplate )
|
|
{
|
|
if ( bRequestConfirmation )
|
|
{
|
|
if ( bIsMultipleSelect )
|
|
{
|
|
VERIFY (text.LoadString (IDS_CONFIRM_DELETE_CERT_TEMPLATE_MULTI));
|
|
}
|
|
else
|
|
VERIFY (text.LoadString (IDS_CONFIRM_DELETE_CERT_TEMPLATE));
|
|
VERIFY (caption.LoadString (IDS_CERTTMPL));
|
|
hr = m_pConsole->MessageBox (text, caption, MB_ICONWARNING | MB_YESNO, &iRetVal);
|
|
ASSERT (SUCCEEDED (hr));
|
|
}
|
|
|
|
if ( IDYES == iRetVal )
|
|
{
|
|
hr = DeleteCertTemplateFromResultPane (pCertTemplate, pDataObject);
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
ASSERT (0);
|
|
hr = E_UNEXPECTED;
|
|
break;
|
|
}
|
|
|
|
_TRACE (-1, L"Leaving CCertTmplComponent::DeleteCookie\n");
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
HRESULT CCertTmplComponent::DeleteCertTemplateFromResultPane (CCertTemplate* pCertTemplate, LPDATAOBJECT /*pDataObject*/)
|
|
{
|
|
_TRACE (1, L"Entering CCertTmplComponent::DeleteCertTemplateFromResultPane\n");
|
|
HRESULT hr = S_OK;
|
|
hr = pCertTemplate->Delete ();
|
|
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
CCertTmplComponentData& dataref = QueryComponentDataRef ();
|
|
|
|
POSITION prevPos = 0;
|
|
POSITION pos = 0;
|
|
for (pos = dataref.m_globalFriendlyNameList.GetHeadPosition (); pos;)
|
|
{
|
|
prevPos = pos;
|
|
if ( pCertTemplate->GetDisplayName () ==
|
|
dataref.m_globalFriendlyNameList.GetNext (pos) )
|
|
{
|
|
dataref.m_globalFriendlyNameList.RemoveAt (prevPos);
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (pos = dataref.m_globalTemplateNameList.GetHeadPosition (); pos;)
|
|
{
|
|
prevPos = pos;
|
|
if ( pCertTemplate->GetTemplateName () ==
|
|
dataref.m_globalTemplateNameList.GetNext (pos) )
|
|
{
|
|
dataref.m_globalTemplateNameList.RemoveAt (prevPos);
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
CString caption;
|
|
CString text;
|
|
|
|
VERIFY (caption.LoadString (IDS_CERTTMPL));
|
|
text.FormatMessage (IDS_CANNOT_DELETE_CERT_TEMPLATE, GetSystemMessage (hr));
|
|
|
|
int iRetVal = 0;
|
|
VERIFY (SUCCEEDED (m_pConsole->MessageBox (text, caption,
|
|
MB_ICONWARNING | MB_OK, &iRetVal)));
|
|
}
|
|
_TRACE (-1, L"Leaving CCertTmplComponent::DeleteCertTemplateFromResultPane\n");
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CCertTmplComponent::OnNotifyDelete (LPDATAOBJECT pDataObject)
|
|
{
|
|
ASSERT (pDataObject);
|
|
if ( !pDataObject )
|
|
return E_POINTER;
|
|
|
|
HRESULT hr = S_OK;
|
|
long hint = 0;
|
|
CWaitCursor waitCursor;
|
|
|
|
CCertTmplCookie* pCookie =
|
|
QueryComponentDataRef ().ConvertCookie (pDataObject);
|
|
if ( pCookie )
|
|
{
|
|
if ( ((CCertTmplCookie*) MMC_MULTI_SELECT_COOKIE) == pCookie )
|
|
{
|
|
|
|
// Is multiple select, get all selected items and paste each one
|
|
CCertTemplatesDataObject* pDO = dynamic_cast <CCertTemplatesDataObject*>(pDataObject);
|
|
ASSERT (pDO);
|
|
if ( pDO )
|
|
{
|
|
// Is multiple select, get all selected items and delete - confirm
|
|
// first deletion only.
|
|
bool bRequestConfirmation = true;
|
|
pDO->Reset();
|
|
while (pDO->Next(1, reinterpret_cast<MMC_COOKIE*>(&pCookie), NULL) != S_FALSE &&
|
|
SUCCEEDED (hr) )
|
|
{
|
|
hr = DeleteCookie (pCookie, pDataObject, bRequestConfirmation, true);
|
|
bRequestConfirmation = false;
|
|
}
|
|
|
|
hr = m_pConsole->UpdateAllViews (pDataObject, 0, hint);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
// In that event, we don't want a confirmation message.
|
|
hr = DeleteCookie (pCookie, pDataObject, true, false);
|
|
if ( SUCCEEDED (hr) )
|
|
hr = m_pConsole->UpdateAllViews (pDataObject, 0, hint);
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
// This compare is used to sort the items in the listview
|
|
//
|
|
// Parameters:
|
|
//
|
|
// lUserParam - user param passed in when IResultData::Sort () was called
|
|
// cookieA - first item to compare
|
|
// cookieB - second item to compare
|
|
// pnResult [in, out]- contains the col on entry,
|
|
// -1, 0, 1 based on comparison for return value.
|
|
//
|
|
// Note: Assume sort is ascending when comparing.
|
|
|
|
STDMETHODIMP CCertTmplComponent::Compare (RDCOMPARE* prdc, int* pnResult)
|
|
{
|
|
// _TRACE (1, L"Entering CCertTmplComponent::Compare\n");
|
|
if ( !prdc || !pnResult )
|
|
return E_POINTER;
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if ( RDCI_ScopeItem & prdc->prdch1->dwFlags )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
CCertTmplCookie* pCookie = reinterpret_cast <CCertTmplCookie*> (prdc->prdch1->cookie);
|
|
ASSERT (pCookie);
|
|
if ( !pCookie )
|
|
return E_UNEXPECTED;
|
|
|
|
switch (pCookie->m_objecttype)
|
|
{
|
|
case CERTTMPL_CERT_TEMPLATE:
|
|
{
|
|
CCertTemplate* pCertTemplateA = reinterpret_cast <CCertTemplate*> (prdc->prdch1->cookie);
|
|
CCertTemplate* pCertTemplateB = reinterpret_cast <CCertTemplate*> (prdc->prdch2->cookie);
|
|
switch ( prdc->nColumn )
|
|
{
|
|
case COLNUM_CERT_TEMPLATE_OBJECT:
|
|
*pnResult = LocaleStrCmp (pCertTemplateA->GetDisplayName (), pCertTemplateB->GetDisplayName ());
|
|
break;
|
|
|
|
case COLNUM_CERT_TEMPLATE_TYPE:
|
|
if ( pCertTemplateA->GetType () == pCertTemplateB->GetType () )
|
|
*pnResult = 0;
|
|
else if ( pCertTemplateA->GetType () > pCertTemplateB->GetType () )
|
|
*pnResult = 1;
|
|
else
|
|
*pnResult = -1;
|
|
break;
|
|
|
|
case COLNUM_CERT_TEMPLATE_VERSION:
|
|
{
|
|
// Sort first on major version, then on minor version
|
|
*pnResult = 0;
|
|
DWORD dwMajorVersionA = 0;
|
|
hr = pCertTemplateA->GetMajorVersion (dwMajorVersionA);
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
DWORD dwMajorVersionB = 0;
|
|
hr = pCertTemplateB->GetMajorVersion (dwMajorVersionB);
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
if ( dwMajorVersionA == dwMajorVersionB )
|
|
{
|
|
DWORD dwMinorVersionA = 0;
|
|
hr = pCertTemplateA->GetMinorVersion (dwMinorVersionA);
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
DWORD dwMinorVersionB = 0;
|
|
hr = pCertTemplateB->GetMinorVersion (dwMinorVersionB);
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
if ( dwMinorVersionA == dwMinorVersionB )
|
|
*pnResult = 0;
|
|
else if ( dwMinorVersionA > dwMinorVersionB )
|
|
*pnResult = 1;
|
|
else
|
|
*pnResult = -1;
|
|
}
|
|
}
|
|
}
|
|
else if ( dwMajorVersionA > dwMajorVersionB )
|
|
*pnResult = 1;
|
|
else
|
|
*pnResult = -1;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case COLNUM_CERT_TEMPLATE_AUTOENROLL_STATUS:
|
|
if ( pCertTemplateA->GoodForAutoEnrollment () &&
|
|
pCertTemplateB->GoodForAutoEnrollment () )
|
|
{
|
|
*pnResult = 0;
|
|
}
|
|
else if ( pCertTemplateA->GoodForAutoEnrollment () &&
|
|
!pCertTemplateB->GoodForAutoEnrollment () )
|
|
{
|
|
*pnResult = 1;
|
|
}
|
|
else
|
|
*pnResult = 0;
|
|
break;
|
|
|
|
default:
|
|
ASSERT (0);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
ASSERT (0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// _TRACE (-1, L"Leaving CCertTmplComponent::Compare\n");
|
|
return hr;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// Virtual function called by CComponent::IComponent::Notify (MMCN_COLUMN_CLICK)
|
|
HRESULT CCertTmplComponent::OnNotifyColumnClick (LPDATAOBJECT /*pDataObject*/, LPARAM iColumn, LPARAM uFlags)
|
|
{
|
|
_TRACE (1, L"Entering CCertTmplComponent::OnNotifyColumnClick\n");
|
|
|
|
IResultData* pResultData = 0;
|
|
HRESULT hr = m_pConsole->QueryInterface (
|
|
IID_PPV_ARG (IResultData, &pResultData));
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
hr = pResultData->Sort ((DWORD)iColumn, (DWORD)uFlags, 0);
|
|
_TRACE (0, L"IResultData::Sort () returned: 0x%x\n", hr);
|
|
|
|
pResultData->Release ();
|
|
}
|
|
|
|
_TRACE (-1, L"Leaving CCertTmplComponent::OnNotifyColumnClick\n");
|
|
return hr;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CCertTmplComponent::Notify (LPDATAOBJECT pDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
switch (event)
|
|
{
|
|
case MMCN_CUTORMOVE:
|
|
hr = OnNotifyCutOrMove (arg);
|
|
break;
|
|
|
|
case MMCN_QUERY_PASTE:
|
|
hr = OnNotifyQueryPaste (pDataObject, arg, param);
|
|
break;
|
|
|
|
case MMCN_PASTE:
|
|
hr = OnNotifyPaste (pDataObject, arg, param);
|
|
break;
|
|
|
|
case MMCN_SHOW:
|
|
{
|
|
CCookie* pCookie = NULL;
|
|
hr = ::ExtractData (pDataObject,
|
|
CDataObject::m_CFRawCookie,
|
|
&pCookie,
|
|
sizeof(pCookie));
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
hr = Show (ActiveBaseCookie (pCookie), arg,
|
|
(HSCOPEITEM) param, pDataObject);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case MMCN_RENAME:
|
|
hr = OnNotifyRename (pDataObject, arg, param);
|
|
break;
|
|
|
|
default:
|
|
hr = CComponent::Notify (pDataObject, event, arg, param);
|
|
break;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CCertTmplComponent::OnNotifySnapinHelp (LPDATAOBJECT pDataObject)
|
|
{
|
|
_TRACE (1, L"Entering CCertTmplComponent::OnNotifySnapinHelp\n");
|
|
AFX_MANAGE_STATE (AfxGetStaticModuleState ( ));
|
|
|
|
CComQIPtr<IDisplayHelp,&IID_IDisplayHelp> spDisplayHelp = m_pConsole;
|
|
if ( !spDisplayHelp )
|
|
{
|
|
ASSERT(FALSE);
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
CString strHelpTopic;
|
|
|
|
UINT nLen = ::GetSystemWindowsDirectory (strHelpTopic.GetBufferSetLength(2 * MAX_PATH), 2 * MAX_PATH);
|
|
strHelpTopic.ReleaseBuffer();
|
|
if (0 == nLen)
|
|
{
|
|
ASSERT(FALSE);
|
|
return E_FAIL;
|
|
}
|
|
|
|
strHelpTopic += CERTTMPL_HELP_PATH;
|
|
strHelpTopic += CERTTMPL_HTML_HELP_FILE;
|
|
strHelpTopic += L"::/";
|
|
|
|
CCertTmplComponentData& compData = QueryComponentDataRef ();
|
|
CCertTmplCookie* pCookie = compData.ConvertCookie (pDataObject);
|
|
if ( pCookie )
|
|
{
|
|
switch (pCookie->m_objecttype)
|
|
{
|
|
case CERTTMPL_SNAPIN:
|
|
case CERTTMPL_CERT_TEMPLATE:
|
|
default:
|
|
strHelpTopic += CERTTMPL_HTML_TOP_NODE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
HRESULT hr = spDisplayHelp->ShowTopic (T2OLE ((PWSTR)(PCWSTR) strHelpTopic));
|
|
if ( FAILED (hr) )
|
|
{
|
|
CString caption;
|
|
CString text;
|
|
|
|
VERIFY (caption.LoadString (IDS_CERTTMPL));
|
|
|
|
text.FormatMessage (IDS_CANT_DISPLAY_SNAPIN_HELP_TOPIC, strHelpTopic,
|
|
GetSystemMessage (hr));
|
|
|
|
int iRetVal = 0;
|
|
VERIFY (SUCCEEDED (m_pConsole->MessageBox (text, caption,
|
|
MB_ICONWARNING | MB_OK, &iRetVal)));
|
|
}
|
|
|
|
|
|
_TRACE (-1, L"Leaving CCertTmplComponent::OnNotifySnapinHelp\n");
|
|
return hr;
|
|
}
|
|
|
|
void CCertTmplComponent::DisplayAccessDenied ()
|
|
{
|
|
DWORD dwErr = GetLastError ();
|
|
ASSERT (E_ACCESSDENIED == dwErr);
|
|
if ( E_ACCESSDENIED == dwErr )
|
|
{
|
|
LPVOID lpMsgBuf;
|
|
|
|
FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
|
NULL,
|
|
GetLastError (),
|
|
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
|
(PWSTR) &lpMsgBuf, 0, NULL );
|
|
|
|
// Display the string.
|
|
CString caption;
|
|
VERIFY (caption.LoadString (IDS_CERTTMPL));
|
|
int iRetVal = 0;
|
|
VERIFY (SUCCEEDED (m_pConsole->MessageBox ( (PWSTR) lpMsgBuf, caption,
|
|
MB_ICONWARNING | MB_OK, &iRetVal)));
|
|
|
|
// Free the buffer.
|
|
LocalFree (lpMsgBuf);
|
|
}
|
|
}
|
|
|
|
HRESULT CCertTmplComponent::OnNotifyPaste (LPDATAOBJECT /*pDataObject*/, LPARAM /*arg*/, LPARAM /*param*/)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
HRESULT CCertTmplComponent::OnNotifyQueryPaste(LPDATAOBJECT /*pDataObject*/, LPARAM /*arg*/, LPARAM /*param*/)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CCertTmplComponent::GetResultViewType(MMC_COOKIE cookie,
|
|
BSTR* ppViewType,
|
|
long* pViewOptions)
|
|
{
|
|
CCertTmplCookie* pScopeCookie = reinterpret_cast <CCertTmplCookie*> (cookie);
|
|
if ( pScopeCookie )
|
|
{
|
|
switch (pScopeCookie->m_objecttype)
|
|
{
|
|
case CERTTMPL_SNAPIN:
|
|
*pViewOptions |= MMC_VIEW_OPTIONS_MULTISELECT;
|
|
break;
|
|
|
|
case CERTTMPL_CERT_TEMPLATE:
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
*pViewOptions |= MMC_VIEW_OPTIONS_MULTISELECT;
|
|
|
|
*ppViewType = NULL;
|
|
return S_FALSE;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CCertTmplComponent::Initialize(LPCONSOLE lpConsole)
|
|
{
|
|
_TRACE (1, L"Entering CCertTmplComponent::Initialize\n");
|
|
HRESULT hr = CComponent::Initialize (lpConsole);
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
ASSERT (m_pHeader);
|
|
QueryComponentDataRef ().m_pHeader = m_pHeader;
|
|
|
|
if ( lpConsole )
|
|
{
|
|
if ( QueryComponentDataRef ().m_pComponentConsole )
|
|
SAFE_RELEASE (QueryComponentDataRef ().m_pComponentConsole);
|
|
QueryComponentDataRef ().m_pComponentConsole = m_pConsole;
|
|
QueryComponentDataRef ().m_pComponentConsole->AddRef ();
|
|
}
|
|
}
|
|
|
|
_TRACE (-1, L"Leaving CCertTmplComponent::Initialize\n");
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CCertTmplComponent::LoadColumnsFromArrays (CertTmplObjectType objecttype )
|
|
{
|
|
_TRACE (1, L"Entering CCertTmplComponent::LoadColumnsFromArrays\n");
|
|
ASSERT (m_pHeader);
|
|
|
|
CString str;
|
|
for ( INT i = 0; 0 != m_Columns[objecttype][i]; i++)
|
|
{
|
|
VERIFY(str.LoadString (m_Columns[objecttype][i]));
|
|
m_pHeader->InsertColumn(i, const_cast<PWSTR>((PCWSTR)str), LVCFMT_LEFT,
|
|
m_ColumnWidths[objecttype][i]);
|
|
}
|
|
|
|
_TRACE (-1, L"Leaving CCertTmplComponent::LoadColumnsFromArrays\n");
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CCertTmplComponent::SaveWidths(CCertTmplCookie * pCookie)
|
|
{
|
|
_TRACE (1, L"Entering CCertTmplComponent::SaveWidths\n");
|
|
HRESULT hr = S_OK;
|
|
|
|
m_fDirty = TRUE;
|
|
|
|
ASSERT (pCookie);
|
|
if ( pCookie )
|
|
{
|
|
switch (m_pViewedCookie->m_objecttype)
|
|
{
|
|
case CERTTMPL_SNAPIN:
|
|
{
|
|
const UINT* pColumns = m_Columns[m_pViewedCookie->m_objecttype];
|
|
ASSERT(pColumns);
|
|
int nWidth = 0;
|
|
|
|
for (UINT iIndex = 0; iIndex < pColumns[iIndex]; iIndex++)
|
|
{
|
|
hr = m_pHeader->GetColumnWidth ((int) iIndex, &nWidth);
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
m_ColumnWidths[m_pViewedCookie->m_objecttype][iIndex] =
|
|
(UINT) nWidth;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
ASSERT (0);
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
hr = E_POINTER;
|
|
|
|
_TRACE (-1, L"Leaving CCertTmplComponent::SaveWidths\n");
|
|
return hr;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
#define _dwMagicword 10000 // Internal version number
|
|
STDMETHODIMP CCertTmplComponent::Load(IStream __RPC_FAR *pIStream)
|
|
{
|
|
_TRACE (1, L"Entering CCertTmplComponent::Load\n");
|
|
HRESULT hr = S_OK;
|
|
|
|
#ifndef DONT_PERSIST
|
|
ASSERT (pIStream);
|
|
XSafeInterfacePtr<IStream> pIStreamSafePtr( pIStream );
|
|
|
|
// Read the magic word from the stream
|
|
DWORD dwMagicword = 0;
|
|
hr = pIStream->Read (&dwMagicword, sizeof(dwMagicword), NULL);
|
|
if ( FAILED(hr) )
|
|
{
|
|
ASSERT( FALSE );
|
|
return hr;
|
|
}
|
|
if (dwMagicword != _dwMagicword)
|
|
{
|
|
// We have a version mismatch
|
|
_TRACE(0, L"INFO: CCertTmplComponentData::Load() - Wrong Magicword. You need to re-save your .msc file.\n");
|
|
return E_FAIL;
|
|
}
|
|
|
|
int numCols = 0;
|
|
|
|
for (int iIndex = 0; iIndex < CERTTMPL_NUMTYPES && SUCCEEDED (hr); iIndex++)
|
|
{
|
|
switch (iIndex)
|
|
{
|
|
case CERTTMPL_SNAPIN:
|
|
numCols = CERT_TEMPLATES_NUM_COLS;
|
|
break;;
|
|
|
|
case CERTTMPL_CERT_TEMPLATE:
|
|
continue;
|
|
|
|
default:
|
|
ASSERT (0);
|
|
break;
|
|
}
|
|
|
|
for (int colNum = 0; colNum < numCols; colNum++)
|
|
{
|
|
hr = pIStream->Read (&(m_ColumnWidths[iIndex][colNum]),
|
|
sizeof (UINT), NULL);
|
|
ASSERT (SUCCEEDED (hr));
|
|
if ( FAILED(hr) )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
_TRACE (-1, L"Leaving CCertTmplComponent::Load\n");
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP CCertTmplComponent::Save(IStream __RPC_FAR *pIStream, BOOL /*fSameAsLoad*/)
|
|
{
|
|
_TRACE (1, L"Entering CCertTmplComponent::Save\n");
|
|
HRESULT hr = S_OK;
|
|
|
|
|
|
#ifndef DONT_PERSIST
|
|
ASSERT (pIStream);
|
|
XSafeInterfacePtr<IStream> pIStreamSafePtr (pIStream);
|
|
|
|
// Store the magic word to the stream
|
|
DWORD dwMagicword = _dwMagicword;
|
|
hr = pIStream->Write (&dwMagicword, sizeof(dwMagicword), NULL);
|
|
ASSERT (SUCCEEDED (hr));
|
|
if ( FAILED (hr) )
|
|
return hr;
|
|
|
|
|
|
int numCols = 0;
|
|
|
|
for (int iIndex = 0; iIndex < CERTTMPL_NUMTYPES && SUCCEEDED (hr); iIndex++)
|
|
{
|
|
switch (iIndex)
|
|
{
|
|
case CERTTMPL_SNAPIN:
|
|
numCols = CERT_TEMPLATES_NUM_COLS;
|
|
break;;
|
|
|
|
case CERTTMPL_CERT_TEMPLATE:
|
|
continue;
|
|
|
|
default:
|
|
ASSERT (0);
|
|
break;
|
|
}
|
|
|
|
for (int colNum = 0; colNum < numCols; colNum++)
|
|
{
|
|
hr = pIStream->Write (&(m_ColumnWidths[iIndex][colNum]),
|
|
sizeof (UINT), NULL);
|
|
ASSERT (SUCCEEDED (hr));
|
|
if ( FAILED(hr) )
|
|
{
|
|
ASSERT (FALSE);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
_TRACE (-1, L"Leaving CCertTmplComponent::Save\n");
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CCertTmplComponent::OnNotifyCutOrMove(LPARAM arg)
|
|
{
|
|
_TRACE (1, L"Entering CCertTmplComponent::OnNotifyCutOrMove\n");
|
|
if ( !arg )
|
|
return E_POINTER;
|
|
|
|
LPDATAOBJECT pDataObject = reinterpret_cast <IDataObject*> (arg);
|
|
ASSERT (pDataObject);
|
|
if ( !pDataObject )
|
|
return E_UNEXPECTED;
|
|
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
CCertTmplCookie* pCookie =
|
|
QueryComponentDataRef ().ConvertCookie (pDataObject);
|
|
if ( pCookie )
|
|
{
|
|
if ( ((CCertTmplCookie*) MMC_MULTI_SELECT_COOKIE) == pCookie )
|
|
{
|
|
CCertTemplatesDataObject* pDO = dynamic_cast <CCertTemplatesDataObject*>(pDataObject);
|
|
ASSERT (pDO);
|
|
if ( pDO )
|
|
{
|
|
pDO->Reset();
|
|
while (pDO->Next(1, reinterpret_cast<MMC_COOKIE*>(&pCookie), NULL) != S_FALSE)
|
|
{
|
|
hr = DeleteCookie (pCookie, pDataObject, false, true);
|
|
}
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
}
|
|
else
|
|
{
|
|
hr = DeleteCookie (pCookie, pDataObject, false, false);
|
|
}
|
|
if ( SUCCEEDED (hr) )
|
|
RefreshResultPane (false);
|
|
}
|
|
|
|
_TRACE (-1, L"Leaving CCertTmplComponent::OnNotifyCutOrMove\n");
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
CCertTmplCookie* CCertTmplComponent::ConvertCookie(LPDATAOBJECT pDataObject)
|
|
{
|
|
return QueryComponentDataRef ().ConvertCookie (pDataObject);
|
|
}
|
|
|
|
|
|
|
|
HRESULT CCertTmplComponent::RefreshResultItem (CCertTmplCookie* pCookie)
|
|
{
|
|
_TRACE (1, L"Entering CCertTmplComponent::RefreshResultItem\n");
|
|
ASSERT (pCookie);
|
|
if ( !pCookie )
|
|
return E_POINTER;
|
|
|
|
HRESULT hr = S_OK;
|
|
HRESULTITEM itemID = 0;
|
|
|
|
ASSERT (m_pResultData);
|
|
if ( m_pResultData )
|
|
{
|
|
pCookie->Refresh ();
|
|
hr = m_pResultData->FindItemByLParam ( (LPARAM) pCookie, &itemID);
|
|
ASSERT (SUCCEEDED (hr));
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
hr = m_pResultData->UpdateItem (itemID);
|
|
ASSERT (SUCCEEDED (hr));
|
|
}
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
|
|
_TRACE (-1, L"Leaving CCertTmplComponent::RefreshResultItem\n");
|
|
return hr;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// Virtual function called by CComponent::IComponent::Notify(MMCN_PROPERTY_CHANGE)
|
|
// OnPropertyChange() is generated by MMCPropertyChangeNotify( param )
|
|
HRESULT CCertTmplComponent::OnPropertyChange (LPARAM param)
|
|
{
|
|
return QueryComponentDataRef ().OnPropertyChange (param);
|
|
}
|
|
|
|
HRESULT CCertTmplComponent::AddEnterpriseTemplates ()
|
|
{
|
|
_TRACE (1, L"Entering CCertTmplComponent::AddEnterpriseTemplates\n");
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
|
HRESULT hr = S_OK;
|
|
CWaitCursor cursor;
|
|
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, bstrCertTemplatePath);
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
m_currResultNodeType = CERTTMPL_CERT_TEMPLATE;
|
|
hr = m_pResultData->Sort (COLNUM_CERT_TEMPLATE_OBJECT, 0, 0);
|
|
}
|
|
}
|
|
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 CCertTmplComponent::AddEnterpriseTemplates\n");
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CCertTmplComponent::EnumerateTemplates (
|
|
IDirectoryObject* pTemplateContObj,
|
|
const BSTR bszTemplateContainerPath)
|
|
{
|
|
_TRACE (1, L"Entering CCertTmplComponent::EnumerateTemplates\n");
|
|
CCertTmplComponentData& dataRef = QueryComponentDataRef ();
|
|
CWaitCursor cursor;
|
|
|
|
dataRef.m_fUseCache = false;
|
|
|
|
// Bug 243609 CertServer: Wrong count of templates displayed in the MMC
|
|
dataRef.m_dwNumCertTemplates = 0;
|
|
dataRef.m_globalTemplateNameList.RemoveAll ();
|
|
dataRef.m_globalFriendlyNameList.RemoveAll ();
|
|
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 = 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) )
|
|
{
|
|
CCookie& rootCookie = dataRef.QueryBaseRootCookie ();
|
|
|
|
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;
|
|
|
|
spDsSearch->FreeColumn (&Column);
|
|
Column.pszAttrName = NULL;
|
|
|
|
hr = spDsSearch->GetColumn(
|
|
hSearchHandle,
|
|
rgszAttrList[1],
|
|
&Column
|
|
);
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
CString strTemplateName = Column.pADsValues->CaseIgnoreString;
|
|
|
|
spDsSearch->FreeColumn (&Column);
|
|
Column.pszAttrName = NULL;
|
|
|
|
|
|
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> (bszTemplateContainerPath),
|
|
ADS_SETTYPE_FULL);
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
//
|
|
// Open the root DSE object
|
|
//
|
|
hr = spPathname->AddLeafElement(const_cast <PWSTR> ((PCWSTR) strTemplateName));
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
BSTR bstrFullPath = 0;
|
|
hr = spPathname->Retrieve(ADS_FORMAT_X500, &bstrFullPath);
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
CCertTemplate* pCertTemplate =
|
|
new CCertTemplate (strDisplayName, strTemplateName,
|
|
bstrFullPath, false,
|
|
dataRef.m_fUseCache);
|
|
if ( pCertTemplate )
|
|
{
|
|
dataRef.m_fUseCache = true;
|
|
|
|
rootCookie.m_listResultCookieBlocks.AddHead (pCertTemplate);
|
|
|
|
RESULTDATAITEM rdItem;
|
|
::ZeroMemory (&rdItem, sizeof (rdItem));
|
|
rdItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
|
|
rdItem.nCol = 0;
|
|
rdItem.str = MMC_CALLBACK;
|
|
if ( 1 == pCertTemplate->GetType () )
|
|
rdItem.nImage = iIconCertTemplateV1;
|
|
else
|
|
rdItem.nImage = iIconCertTemplateV2;
|
|
rdItem.lParam = (LPARAM) pCertTemplate;
|
|
pCertTemplate->m_resultDataID = m_pResultData;
|
|
hr = m_pResultData->InsertItem (&rdItem);
|
|
if ( FAILED (hr) )
|
|
{
|
|
_TRACE (0, L"IResultData::InsertItem failed: 0x%x\n", hr);
|
|
hr = S_OK;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
dataRef.m_dwNumCertTemplates++;
|
|
dataRef.m_globalTemplateNameList.AddTail (strTemplateName);
|
|
dataRef.m_globalFriendlyNameList.AddHead (
|
|
pCertTemplate->GetDisplayName ());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
|
|
SysFreeString (bstrFullPath);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
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 CCertTmplComponent::EnumerateTemplates: 0x%x\n", hr);
|
|
dataRef.m_fUseCache = false;
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CCertTmplComponent::OnNotifyRename(LPDATAOBJECT pDataObject, LPARAM /*arg*/, LPARAM param)
|
|
{
|
|
_TRACE (1, L"Entering CCertTmplComponent::OnNotifyRename\n");
|
|
AFX_MANAGE_STATE (AfxGetStaticModuleState ());
|
|
HRESULT hr = S_FALSE;
|
|
|
|
CCertTmplCookie* pCookie = ConvertCookie (pDataObject);
|
|
if ( pCookie )
|
|
{
|
|
switch (pCookie->m_objecttype)
|
|
{
|
|
case CERTTMPL_CERT_TEMPLATE:
|
|
{
|
|
CString newName = (LPOLESTR) param;
|
|
|
|
newName.TrimLeft ();
|
|
newName.TrimRight ();
|
|
|
|
if ( !newName.IsEmpty () )
|
|
{
|
|
CCertTmplComponentData& dataref = QueryComponentDataRef ();
|
|
POSITION pos = 0;
|
|
bool bFound = false;
|
|
for (pos = dataref.m_globalFriendlyNameList.GetHeadPosition (); pos;)
|
|
{
|
|
if ( !_wcsicmp (newName, dataref.m_globalFriendlyNameList.GetNext (pos)) )
|
|
{
|
|
CString caption;
|
|
CString text;
|
|
|
|
VERIFY (caption.LoadString (IDS_CERTTMPL));
|
|
text.FormatMessage (IDS_FRIENDLY_NAME_ALREADY_USED, newName);
|
|
|
|
int iRetVal = 0;
|
|
VERIFY (SUCCEEDED (m_pConsole->MessageBox (text, caption,
|
|
MB_OK, &iRetVal)));
|
|
bFound = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( !bFound )
|
|
{
|
|
CCertTemplate* pCertTemplate = dynamic_cast<CCertTemplate*> (pCookie);
|
|
if ( pCertTemplate )
|
|
{
|
|
hr = pCertTemplate->SetDisplayName (newName);
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
hr = pCertTemplate->SaveChanges ();
|
|
if ( FAILED (hr) )
|
|
{
|
|
CString caption;
|
|
CString text;
|
|
|
|
VERIFY (caption.LoadString (IDS_CERTTMPL));
|
|
text.FormatMessage (IDS_UNABLE_TO_SAVE_CERT_TEMPLATE_CHANGES, GetSystemMessage (hr));
|
|
|
|
int iRetVal = 0;
|
|
VERIFY (SUCCEEDED (m_pConsole->MessageBox (text, caption,
|
|
MB_ICONWARNING | MB_OK, &iRetVal)));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CString caption;
|
|
CString text;
|
|
|
|
VERIFY (caption.LoadString (IDS_CERTTMPL));
|
|
text.FormatMessage (IDS_CANNOT_CHANGE_DISPLAY_NAME, hr);
|
|
|
|
int iRetVal = 0;
|
|
VERIFY (SUCCEEDED (m_pConsole->MessageBox (text, caption,
|
|
MB_ICONWARNING | MB_OK, &iRetVal)));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CString caption;
|
|
CString text;
|
|
|
|
VERIFY (caption.LoadString (IDS_CERTTMPL));
|
|
VERIFY (text.LoadString (IDS_MUST_TYPE_TEMPLATE_DISPLAY_NAME));
|
|
int iRetVal = 0;
|
|
VERIFY (SUCCEEDED (m_pConsole->MessageBox (text, caption,
|
|
MB_ICONWARNING | MB_OK, &iRetVal)));
|
|
hr = S_FALSE;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( !SUCCEEDED (hr) )
|
|
hr = S_FALSE;
|
|
|
|
_TRACE(-1, L"Leaving CCertTmplComponent::OnNotifyRename: 0x%x\n", hr);
|
|
return hr;
|
|
}
|
|
|