Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1809 lines
52 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997-2001.
  5. //
  6. // File: cmponent.cpp
  7. //
  8. // Contents: Implementation of CCertTmplComponent
  9. //
  10. //----------------------------------------------------------------------------
  11. #include "stdafx.h"
  12. #include "dbg.h"
  13. #include "compdata.h" // CCertTmplComponentData
  14. #include "dataobj.h"
  15. #include "cmponent.h" // CCertTmplComponent
  16. #include "utils.h"
  17. #ifdef _DEBUG
  18. #define new DEBUG_NEW
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22. DECLARE_INFOLEVEL(CertTmplSnapin)
  23. USE_HANDLE_MACROS ("CERTTMPL (cmponent.cpp)")
  24. #pragma warning(push,3)
  25. #include "stdcmpnt.cpp" // CComponent
  26. #pragma warning(pop)
  27. UINT m_aColumnsSnapinSelected[CERT_TEMPLATES_NUM_COLS+1] =
  28. {IDS_COLUMN_CERT_TEMPLATE_OBJECT,
  29. IDS_COLUMN_CERT_TEMPLATE_TYPE,
  30. IDS_COLUMN_CERT_TEMPLATE_VERSION,
  31. IDS_COLUMN_CERT_TEMPLATE_AUTOENROLLMENT,
  32. 0};
  33. UINT* m_Columns[CERTTMPL_NUMTYPES] =
  34. {
  35. m_aColumnsSnapinSelected, // CERTTMPL_SNAPIN (displays certificate templates in the result pane)
  36. 0
  37. };
  38. UINT** g_aColumns = 0; // for framework
  39. int** g_aColumnWidths = 0; // for framework
  40. const int SINGLE_COL_WIDTH = 300;
  41. CCertTmplComponent::CCertTmplComponent ()
  42. : m_pViewedCookie (NULL),
  43. m_currResultNodeType (CERTTMPL_INVALID)
  44. {
  45. _TRACE (1, L"Entering CCertTmplComponent::CCertTmplComponent\n");
  46. AFX_MANAGE_STATE (AfxGetStaticModuleState ( ));
  47. ::ZeroMemory (m_ColumnWidths, (sizeof (UINT*) * CERTTMPL_NUMTYPES));
  48. m_ColumnWidths[CERTTMPL_SNAPIN] = new UINT[CERT_TEMPLATES_NUM_COLS];
  49. if ( m_ColumnWidths[CERTTMPL_SNAPIN] )
  50. {
  51. m_ColumnWidths[CERTTMPL_SNAPIN][COLNUM_CERT_TEMPLATE_OBJECT] = 250;
  52. m_ColumnWidths[CERTTMPL_SNAPIN][COLNUM_CERT_TEMPLATE_TYPE] = 150;
  53. m_ColumnWidths[CERTTMPL_SNAPIN][COLNUM_CERT_TEMPLATE_VERSION] = 50;
  54. m_ColumnWidths[CERTTMPL_SNAPIN][COLNUM_CERT_TEMPLATE_AUTOENROLL_STATUS] = 100;
  55. }
  56. _TRACE (-1, L"Leaving CCertTmplComponent::CCertTmplComponent\n");
  57. }
  58. CCertTmplComponent::~CCertTmplComponent ()
  59. {
  60. _TRACE (1, L"Entering CCertTmplComponent::~CCertTmplComponent\n");
  61. VERIFY ( SUCCEEDED (ReleaseAll ()) );
  62. for (int i = 0; i < CERTTMPL_NUMTYPES; i++)
  63. {
  64. if ( m_ColumnWidths[i] )
  65. delete [] m_ColumnWidths[i];
  66. }
  67. _TRACE (-1, L"Leaving CCertTmplComponent::~CCertTmplComponent\n");
  68. }
  69. HRESULT CCertTmplComponent::ReleaseAll ()
  70. {
  71. return CComponent::ReleaseAll ();
  72. }
  73. /////////////////////////////////////////////////////////////////////////////
  74. // IComponent Implementation
  75. HRESULT CCertTmplComponent::LoadStrings ()
  76. {
  77. return S_OK;
  78. }
  79. HRESULT CCertTmplComponent::LoadColumns ( CCertTmplCookie* pcookie )
  80. {
  81. AFX_MANAGE_STATE (AfxGetStaticModuleState ());
  82. _TRACE (1, L"Entering CCertTmplComponent::LoadColumns\n");
  83. HRESULT hr = S_OK;
  84. hr = LoadColumnsFromArrays (pcookie->m_objecttype);
  85. _TRACE (-1, L"Leaving CCertTmplComponent::LoadColumns\n");
  86. return hr;
  87. }
  88. /* This is generated by UpdateAllViews () */
  89. HRESULT CCertTmplComponent::OnViewChange (LPDATAOBJECT pDataObject, LPARAM /*data*/, LPARAM hint)
  90. {
  91. _TRACE (1, L"Entering CCertTmplComponent::OnViewChange\n");
  92. ASSERT (pDataObject);
  93. if ( !pDataObject )
  94. return E_POINTER;
  95. CCertTmplComponentData& compData = QueryComponentDataRef ();
  96. HRESULT hr = S_OK;
  97. if ( hint & UPDATE_HINT_ENUM_CERT_TEMPLATES )
  98. {
  99. hr = RefreshResultPane (false);
  100. return hr;
  101. }
  102. hr = RefreshResultPane (false);
  103. CCertTmplCookie* pCookie = compData.ConvertCookie (pDataObject);
  104. if ( pCookie )
  105. {
  106. switch (pCookie->m_objecttype)
  107. {
  108. case CERTTMPL_CERT_TEMPLATE:
  109. break;
  110. case CERTTMPL_SNAPIN:
  111. break;
  112. default:
  113. {
  114. IConsole2* pConsole2 = 0;
  115. hr = m_pConsole->QueryInterface (
  116. IID_PPV_ARG(IConsole2, &pConsole2));
  117. if (SUCCEEDED (hr))
  118. {
  119. hr = pConsole2->SetStatusText (L"");
  120. if ( !SUCCEEDED (hr) )
  121. {
  122. _TRACE (0, L"IConsole2::SetStatusText () failed: %x", hr);
  123. }
  124. pConsole2->Release ();
  125. }
  126. }
  127. break;
  128. }
  129. }
  130. _TRACE (-1, L"Leaving CCertTmplComponent::OnViewChange\n");
  131. return hr;
  132. }
  133. HRESULT CCertTmplComponent::Show (
  134. CCookie* pcookie,
  135. LPARAM arg,
  136. HSCOPEITEM /*hScopeItem*/,
  137. LPDATAOBJECT /*pDataObject*/)
  138. {
  139. AFX_MANAGE_STATE (AfxGetStaticModuleState ());
  140. HRESULT hr = S_OK;
  141. if ( !arg )
  142. {
  143. if ( !m_pResultData )
  144. {
  145. ASSERT ( FALSE );
  146. return E_UNEXPECTED;
  147. }
  148. m_pViewedCookie = dynamic_cast <CCertTmplCookie*> (pcookie);
  149. ASSERT (m_pViewedCookie);
  150. if ( m_pViewedCookie )
  151. hr = SaveWidths (m_pViewedCookie);
  152. m_pViewedCookie = 0;
  153. return S_OK;
  154. }
  155. m_pViewedCookie = dynamic_cast <CCertTmplCookie*> (pcookie);
  156. ASSERT (m_pViewedCookie);
  157. if ( m_pViewedCookie )
  158. {
  159. // Load default columns and widths
  160. LoadColumns (m_pViewedCookie);
  161. // Restore persisted column widths
  162. switch (m_pViewedCookie->m_objecttype)
  163. {
  164. case CERTTMPL_SNAPIN:
  165. break;
  166. case CERTTMPL_CERT_TEMPLATE: // not a scope pane item
  167. ASSERT (0);
  168. break;
  169. default:
  170. ASSERT (0);
  171. break;
  172. }
  173. hr = PopulateListbox (m_pViewedCookie);
  174. if ( FAILED (hr) )
  175. {
  176. CString caption;
  177. CString text;
  178. VERIFY (caption.LoadString (IDS_CERTTMPL));
  179. text.FormatMessage (IDS_CANNOT_ENUM_CERT_TEMPLATES, GetSystemMessage (hr));
  180. int iRetVal = 0;
  181. VERIFY (SUCCEEDED (m_pConsole->MessageBox (text, caption,
  182. MB_ICONWARNING | MB_OK, &iRetVal)));
  183. }
  184. }
  185. return hr;
  186. }
  187. HRESULT CCertTmplComponent::Show ( CCookie* pcookie, LPARAM arg, HSCOPEITEM hScopeItem)
  188. {
  189. ASSERT (0);
  190. return Show (pcookie, arg, hScopeItem, 0);
  191. }
  192. HRESULT CCertTmplComponent::OnNotifyAddImages (LPDATAOBJECT /*pDataObject*/,
  193. LPIMAGELIST lpImageList,
  194. HSCOPEITEM /*hSelectedItem*/)
  195. {
  196. long lViewMode = 0;
  197. ASSERT (m_pResultData);
  198. QueryComponentDataRef ().SetResultData (m_pResultData);
  199. HRESULT hr = m_pResultData->GetViewMode (&lViewMode);
  200. ASSERT (SUCCEEDED (hr));
  201. BOOL bLoadLargeIcons = (LVS_ICON == lViewMode);
  202. return QueryComponentDataRef ().LoadIcons (lpImageList, bLoadLargeIcons);
  203. }
  204. HRESULT CCertTmplComponent::PopulateListbox (CCertTmplCookie* pCookie)
  205. {
  206. _TRACE (1, L"Entering CCertTmplComponent::PopulateListbox\n");
  207. HRESULT hr = S_OK;
  208. switch ( pCookie->m_objecttype )
  209. {
  210. case CERTTMPL_SNAPIN:
  211. hr = AddEnterpriseTemplates ();
  212. if ( SUCCEEDED (hr) )
  213. {
  214. m_currResultNodeType = CERTTMPL_CERT_TEMPLATE;
  215. }
  216. break;
  217. case CERTTMPL_CERT_TEMPLATE:
  218. ASSERT (0);
  219. break;
  220. default:
  221. ASSERT (0);
  222. break;
  223. }
  224. _TRACE (-1, L"Leaving CCertTmplComponent::PopulateListbox\n");
  225. return hr;
  226. }
  227. HRESULT CCertTmplComponent::RefreshResultPane (const bool bSilent)
  228. {
  229. _TRACE (1, L"Entering CCertTmplComponent::RefreshResultPane\n");
  230. HRESULT hr = S_OK;
  231. ASSERT (NULL != m_pResultData);
  232. if ( m_pResultData )
  233. {
  234. m_pResultData->DeleteAllRsltItems ();
  235. }
  236. else
  237. hr = E_UNEXPECTED;
  238. if ( m_pViewedCookie )
  239. {
  240. hr = PopulateListbox (m_pViewedCookie);
  241. if ( FAILED (hr) && !bSilent )
  242. {
  243. CString caption;
  244. CString text;
  245. VERIFY (caption.LoadString (IDS_CERTTMPL));
  246. text.FormatMessage (IDS_CANNOT_ENUM_CERT_TEMPLATES, GetSystemMessage (hr));
  247. int iRetVal = 0;
  248. VERIFY (SUCCEEDED (m_pConsole->MessageBox (text, caption,
  249. MB_ICONWARNING | MB_OK, &iRetVal)));
  250. }
  251. }
  252. _TRACE (-1, L"Leaving CCertTmplComponent::RefreshResultPane\n");
  253. return hr;
  254. }
  255. STDMETHODIMP CCertTmplComponent::GetDisplayInfo (RESULTDATAITEM * pResult)
  256. {
  257. AFX_MANAGE_STATE (AfxGetStaticModuleState ());
  258. ASSERT (pResult);
  259. HRESULT hr = S_OK;
  260. if ( pResult && !pResult->bScopeItem ) //&& (pResult->mask & RDI_PARAM) )
  261. {
  262. CCookie* pResultCookie = reinterpret_cast<CCookie*> (pResult->lParam);
  263. ASSERT (pResultCookie);
  264. if ( !pResultCookie || IsBadWritePtr ((LPVOID) pResultCookie, sizeof (CCookie)) )
  265. return E_UNEXPECTED;
  266. CCookie* pActiveCookie = ActiveBaseCookie (pResultCookie);
  267. ASSERT (pActiveCookie);
  268. if ( !pActiveCookie || IsBadWritePtr ((LPVOID) pActiveCookie, sizeof (CCookie)) )
  269. return E_UNEXPECTED;
  270. CCertTmplCookie* pCookie = dynamic_cast <CCertTmplCookie*>(pActiveCookie);
  271. ASSERT (pCookie);
  272. switch (pCookie->m_objecttype)
  273. {
  274. case CERTTMPL_CERT_TEMPLATE:
  275. {
  276. CCertTemplate* pCertTemplate = reinterpret_cast <CCertTemplate*> (pCookie);
  277. ASSERT (pCertTemplate);
  278. if ( pCertTemplate )
  279. {
  280. if (pResult->mask & RDI_STR)
  281. {
  282. // Note: text is first stored in class variable so that the buffer is
  283. // somewhat persistent. Copying the buffer pointer directly to the
  284. // pResult->str would result in the buffer being freed before the pointer
  285. // is used.
  286. switch (pResult->nCol)
  287. {
  288. case COLNUM_CERT_TEMPLATE_OBJECT:
  289. m_szDisplayInfoResult = pCertTemplate->GetDisplayName ();
  290. break;
  291. case COLNUM_CERT_TEMPLATE_TYPE:
  292. {
  293. DWORD dwVersion = pCertTemplate->GetType ();
  294. switch (dwVersion)
  295. {
  296. case 1:
  297. VERIFY (m_szDisplayInfoResult.LoadString (IDS_WINDOWS_2000_AND_LATER));
  298. break;
  299. case 2:
  300. VERIFY (m_szDisplayInfoResult.LoadString (IDS_WINDOWS_2002_AND_LATER));
  301. break;
  302. default:
  303. break;
  304. }
  305. }
  306. break;
  307. case COLNUM_CERT_TEMPLATE_VERSION:
  308. {
  309. DWORD dwMajorVersion = 0;
  310. DWORD dwMinorVersion = 0;
  311. hr = pCertTemplate->GetMajorVersion (dwMajorVersion);
  312. if ( SUCCEEDED (hr) )
  313. {
  314. hr = pCertTemplate->GetMinorVersion (dwMinorVersion);
  315. if ( SUCCEEDED (hr) )
  316. {
  317. WCHAR str[32];
  318. m_szDisplayInfoResult = _ultow (dwMajorVersion, str, 10);
  319. m_szDisplayInfoResult += L".";
  320. m_szDisplayInfoResult += _ultow (dwMinorVersion, str, 10);
  321. }
  322. }
  323. }
  324. break;
  325. case COLNUM_CERT_TEMPLATE_AUTOENROLL_STATUS:
  326. if ( pCertTemplate->GoodForAutoEnrollment () )
  327. VERIFY (m_szDisplayInfoResult.LoadString (IDS_VALID_FOR_AUTOENROLLMENT));
  328. else
  329. VERIFY (m_szDisplayInfoResult.LoadString (IDS_INVALID_FOR_AUTOENROLLMENT));
  330. break;
  331. default:
  332. ASSERT (0);
  333. break;
  334. }
  335. pResult->str = const_cast<LPWSTR> ( (LPCWSTR) m_szDisplayInfoResult);
  336. }
  337. if (pResult->mask & RDI_IMAGE)
  338. {
  339. if ( 1 == pCertTemplate->GetType () )
  340. pResult->nImage = iIconCertTemplateV1;
  341. else
  342. pResult->nImage = iIconCertTemplateV2;
  343. }
  344. }
  345. }
  346. break;
  347. default:
  348. ASSERT (0);
  349. break;
  350. }
  351. }
  352. else
  353. hr = CComponent::GetDisplayInfo (pResult);
  354. return hr;
  355. }
  356. ///////////////////////////////////////////////////////////////////////////////
  357. // IExtendContextMenu implementation
  358. //
  359. STDMETHODIMP CCertTmplComponent::AddMenuItems (LPDATAOBJECT pDataObject,
  360. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  361. long *pInsertionAllowed)
  362. {
  363. return QueryComponentDataRef ().AddMenuItems (pDataObject,
  364. pContextMenuCallback, pInsertionAllowed);
  365. }
  366. STDMETHODIMP CCertTmplComponent::Command (long nCommandID, LPDATAOBJECT pDataObject)
  367. {
  368. HRESULT hr = S_OK;
  369. hr = QueryComponentDataRef ().Command (nCommandID, pDataObject);
  370. return hr;
  371. }
  372. HRESULT CCertTmplComponent::OnNotifyDblClick (LPDATAOBJECT pDataObject)
  373. {
  374. _TRACE (1, L"Entering CCertTmplComponent::OnNotifyDblClick\n");
  375. HRESULT hr = S_OK;
  376. ASSERT (pDataObject);
  377. CCertTmplCookie* pParentCookie =
  378. QueryComponentDataRef ().ConvertCookie (pDataObject);
  379. if ( pParentCookie )
  380. {
  381. switch ( pParentCookie->m_objecttype )
  382. {
  383. case CERTTMPL_SNAPIN:
  384. hr = S_FALSE;
  385. break;
  386. case CERTTMPL_CERT_TEMPLATE:
  387. hr = S_FALSE;
  388. break;
  389. default:
  390. _TRACE (0, L"CCertTmplComponentData::OnNotifyDblClick bad parent type\n");
  391. ASSERT (FALSE);
  392. hr = S_OK;
  393. break;
  394. }
  395. }
  396. else
  397. hr = E_UNEXPECTED;
  398. _TRACE (-1, L"Leaving CCertTmplComponent::OnNotifyDblClick\n");
  399. return hr;
  400. }
  401. HRESULT CCertTmplComponent::OnNotifySelect (LPDATAOBJECT pDataObject, BOOL /*fSelected*/)
  402. {
  403. ASSERT (m_pConsoleVerb && 0xdddddddd != (UINT_PTR) m_pConsoleVerb);
  404. if ( !m_pConsoleVerb || 0xdddddddd == (UINT_PTR) m_pConsoleVerb )
  405. return E_FAIL;
  406. HRESULT hr = S_OK;
  407. CCertTmplComponentData& compData = QueryComponentDataRef ();
  408. switch (compData.GetObjectType (pDataObject))
  409. {
  410. case CERTTMPL_SNAPIN:
  411. m_pConsoleVerb->SetVerbState (MMC_VERB_REFRESH, ENABLED, TRUE);
  412. m_pConsoleVerb->SetDefaultVerb (MMC_VERB_OPEN);
  413. DisplayRootNodeStatusBarText (m_pConsole);
  414. break;
  415. case CERTTMPL_CERT_TEMPLATE:
  416. {
  417. CCertTmplCookie* pCookie = ConvertCookie (pDataObject);
  418. if ( pCookie )
  419. {
  420. CCertTemplate* pCertTemplate = dynamic_cast <CCertTemplate*> (pCookie);
  421. if ( pCertTemplate )
  422. {
  423. if ( !pCertTemplate->IsDefault () )
  424. m_pConsoleVerb->SetVerbState (MMC_VERB_DELETE, ENABLED, TRUE);
  425. // #NTRAID 360650: Cert Server: Cannot rename cert templates
  426. //if ( 1 != pCertTemplate->GetType () && !pCertTemplate->IsDefault () )
  427. // m_pConsoleVerb->SetVerbState (MMC_VERB_RENAME, ENABLED, TRUE);
  428. }
  429. }
  430. }
  431. m_pConsoleVerb->SetVerbState (MMC_VERB_PROPERTIES, ENABLED, TRUE);
  432. m_pConsoleVerb->SetDefaultVerb (MMC_VERB_PROPERTIES);
  433. m_currResultNodeType = CERTTMPL_CERT_TEMPLATE;
  434. DisplayObjectCountInStatusBar (m_pConsole,
  435. QueryComponentDataRef ().m_dwNumCertTemplates);
  436. break;
  437. case CERTTMPL_MULTISEL:
  438. m_pConsoleVerb->SetVerbState (MMC_VERB_DELETE, ENABLED, TRUE);
  439. m_currResultNodeType = CERTTMPL_MULTISEL;
  440. DisplayObjectCountInStatusBar (m_pConsole,
  441. QueryComponentDataRef ().m_dwNumCertTemplates);
  442. break;
  443. default:
  444. m_currResultNodeType = CERTTMPL_INVALID;
  445. hr = E_UNEXPECTED;
  446. break;
  447. }
  448. return hr;
  449. }
  450. STDMETHODIMP CCertTmplComponent::CreatePropertyPages (
  451. LPPROPERTYSHEETCALLBACK pCallBack,
  452. LONG_PTR handle, // This handle must be saved in the property page object to notify the parent when modified
  453. LPDATAOBJECT pDataObject)
  454. {
  455. return QueryComponentDataRef ().CreatePropertyPages (pCallBack, handle, pDataObject);
  456. }
  457. STDMETHODIMP CCertTmplComponent::QueryPagesFor (LPDATAOBJECT pDataObject)
  458. {
  459. return QueryComponentDataRef ().QueryPagesFor (pDataObject);
  460. }
  461. HRESULT CCertTmplComponent::OnNotifyRefresh (LPDATAOBJECT pDataObject)
  462. {
  463. _TRACE (1, L"Entering CCertTmplComponent::OnNotifyRefresh\n");
  464. ASSERT (pDataObject);
  465. if ( !pDataObject )
  466. return E_POINTER;
  467. HRESULT hr = S_OK;
  468. CWaitCursor waitCursor;
  469. CCertTmplCookie* pCookie = ConvertCookie (pDataObject);
  470. if ( !pCookie )
  471. return E_UNEXPECTED;
  472. CCertTmplComponentData& dataRef = QueryComponentDataRef ();
  473. switch (pCookie->m_objecttype)
  474. {
  475. case CERTTMPL_SNAPIN:
  476. {
  477. // Delete all the scope items and force a reexpansion
  478. hr = dataRef.DeleteScopeItems ();
  479. hr = PopulateListbox (m_pViewedCookie);
  480. if ( FAILED (hr) )
  481. {
  482. CString caption;
  483. CString text;
  484. VERIFY (caption.LoadString (IDS_CERTTMPL));
  485. text.FormatMessage (IDS_CANNOT_ENUM_CERT_TEMPLATES, GetSystemMessage (hr));
  486. int iRetVal = 0;
  487. VERIFY (SUCCEEDED (m_pConsole->MessageBox (text, caption,
  488. MB_ICONWARNING | MB_OK, &iRetVal)));
  489. }
  490. }
  491. break;
  492. case CERTTMPL_CERT_TEMPLATE:
  493. ASSERT (0);
  494. break;
  495. default:
  496. ASSERT (0);
  497. hr = E_UNEXPECTED;
  498. break;
  499. }
  500. _TRACE (-1, L"Leaving CCertTmplComponent::OnNotifyRefresh\n");
  501. return hr;
  502. }
  503. void CCertTmplComponent::SetTextNotAvailable ()
  504. {
  505. AFX_MANAGE_STATE (AfxGetStaticModuleState ());
  506. m_szDisplayInfoResult.LoadString (IDS_NOT_AVAILABLE);
  507. }
  508. HRESULT CCertTmplComponent::DeleteCookie (CCertTmplCookie* pCookie, LPDATAOBJECT pDataObject, bool bRequestConfirmation, bool bIsMultipleSelect)
  509. {
  510. _TRACE (1, L"Entering CCertTmplComponent::DeleteCookie\n");
  511. HRESULT hr = S_OK;
  512. CString text;
  513. CString caption;
  514. int iRetVal = IDYES;
  515. CWaitCursor waitCursor;
  516. switch (pCookie->m_objecttype)
  517. {
  518. case CERTTMPL_CERT_TEMPLATE:
  519. {
  520. CCertTemplate* pCertTemplate = dynamic_cast <CCertTemplate*> (pCookie);
  521. ASSERT (pCertTemplate);
  522. if ( pCertTemplate )
  523. {
  524. if ( bRequestConfirmation )
  525. {
  526. if ( bIsMultipleSelect )
  527. {
  528. VERIFY (text.LoadString (IDS_CONFIRM_DELETE_CERT_TEMPLATE_MULTI));
  529. }
  530. else
  531. VERIFY (text.LoadString (IDS_CONFIRM_DELETE_CERT_TEMPLATE));
  532. VERIFY (caption.LoadString (IDS_CERTTMPL));
  533. hr = m_pConsole->MessageBox (text, caption, MB_ICONWARNING | MB_YESNO, &iRetVal);
  534. ASSERT (SUCCEEDED (hr));
  535. }
  536. if ( IDYES == iRetVal )
  537. {
  538. hr = DeleteCertTemplateFromResultPane (pCertTemplate, pDataObject);
  539. }
  540. else
  541. hr = E_FAIL;
  542. }
  543. }
  544. break;
  545. default:
  546. ASSERT (0);
  547. hr = E_UNEXPECTED;
  548. break;
  549. }
  550. _TRACE (-1, L"Leaving CCertTmplComponent::DeleteCookie\n");
  551. return hr;
  552. }
  553. HRESULT CCertTmplComponent::DeleteCertTemplateFromResultPane (CCertTemplate* pCertTemplate, LPDATAOBJECT /*pDataObject*/)
  554. {
  555. _TRACE (1, L"Entering CCertTmplComponent::DeleteCertTemplateFromResultPane\n");
  556. HRESULT hr = S_OK;
  557. hr = pCertTemplate->Delete ();
  558. if ( SUCCEEDED (hr) )
  559. {
  560. CCertTmplComponentData& dataref = QueryComponentDataRef ();
  561. POSITION prevPos = 0;
  562. POSITION pos = 0;
  563. for (pos = dataref.m_globalFriendlyNameList.GetHeadPosition (); pos;)
  564. {
  565. prevPos = pos;
  566. if ( pCertTemplate->GetDisplayName () ==
  567. dataref.m_globalFriendlyNameList.GetNext (pos) )
  568. {
  569. dataref.m_globalFriendlyNameList.RemoveAt (prevPos);
  570. break;
  571. }
  572. }
  573. for (pos = dataref.m_globalTemplateNameList.GetHeadPosition (); pos;)
  574. {
  575. prevPos = pos;
  576. if ( pCertTemplate->GetTemplateName () ==
  577. dataref.m_globalTemplateNameList.GetNext (pos) )
  578. {
  579. dataref.m_globalTemplateNameList.RemoveAt (prevPos);
  580. break;
  581. }
  582. }
  583. }
  584. else
  585. {
  586. CString caption;
  587. CString text;
  588. VERIFY (caption.LoadString (IDS_CERTTMPL));
  589. text.FormatMessage (IDS_CANNOT_DELETE_CERT_TEMPLATE, GetSystemMessage (hr));
  590. int iRetVal = 0;
  591. VERIFY (SUCCEEDED (m_pConsole->MessageBox (text, caption,
  592. MB_ICONWARNING | MB_OK, &iRetVal)));
  593. }
  594. _TRACE (-1, L"Leaving CCertTmplComponent::DeleteCertTemplateFromResultPane\n");
  595. return hr;
  596. }
  597. HRESULT CCertTmplComponent::OnNotifyDelete (LPDATAOBJECT pDataObject)
  598. {
  599. ASSERT (pDataObject);
  600. if ( !pDataObject )
  601. return E_POINTER;
  602. HRESULT hr = S_OK;
  603. long hint = 0;
  604. CWaitCursor waitCursor;
  605. CCertTmplCookie* pCookie =
  606. QueryComponentDataRef ().ConvertCookie (pDataObject);
  607. if ( pCookie )
  608. {
  609. if ( ((CCertTmplCookie*) MMC_MULTI_SELECT_COOKIE) == pCookie )
  610. {
  611. // Is multiple select, get all selected items and paste each one
  612. CCertTemplatesDataObject* pDO = dynamic_cast <CCertTemplatesDataObject*>(pDataObject);
  613. ASSERT (pDO);
  614. if ( pDO )
  615. {
  616. // Is multiple select, get all selected items and delete - confirm
  617. // first deletion only.
  618. bool bRequestConfirmation = true;
  619. pDO->Reset();
  620. while (pDO->Next(1, reinterpret_cast<MMC_COOKIE*>(&pCookie), NULL) != S_FALSE &&
  621. SUCCEEDED (hr) )
  622. {
  623. hr = DeleteCookie (pCookie, pDataObject, bRequestConfirmation, true);
  624. bRequestConfirmation = false;
  625. }
  626. hr = m_pConsole->UpdateAllViews (pDataObject, 0, hint);
  627. }
  628. }
  629. else
  630. {
  631. // In that event, we don't want a confirmation message.
  632. hr = DeleteCookie (pCookie, pDataObject, true, false);
  633. if ( SUCCEEDED (hr) )
  634. hr = m_pConsole->UpdateAllViews (pDataObject, 0, hint);
  635. }
  636. }
  637. return hr;
  638. }
  639. // This compare is used to sort the items in the listview
  640. //
  641. // Parameters:
  642. //
  643. // lUserParam - user param passed in when IResultData::Sort () was called
  644. // cookieA - first item to compare
  645. // cookieB - second item to compare
  646. // pnResult [in, out]- contains the col on entry,
  647. // -1, 0, 1 based on comparison for return value.
  648. //
  649. // Note: Assume sort is ascending when comparing.
  650. STDMETHODIMP CCertTmplComponent::Compare (RDCOMPARE* prdc, int* pnResult)
  651. {
  652. // _TRACE (1, L"Entering CCertTmplComponent::Compare\n");
  653. if ( !prdc || !pnResult )
  654. return E_POINTER;
  655. HRESULT hr = S_OK;
  656. if ( RDCI_ScopeItem & prdc->prdch1->dwFlags )
  657. {
  658. }
  659. else
  660. {
  661. CCertTmplCookie* pCookie = reinterpret_cast <CCertTmplCookie*> (prdc->prdch1->cookie);
  662. ASSERT (pCookie);
  663. if ( !pCookie )
  664. return E_UNEXPECTED;
  665. switch (pCookie->m_objecttype)
  666. {
  667. case CERTTMPL_CERT_TEMPLATE:
  668. {
  669. CCertTemplate* pCertTemplateA = reinterpret_cast <CCertTemplate*> (prdc->prdch1->cookie);
  670. CCertTemplate* pCertTemplateB = reinterpret_cast <CCertTemplate*> (prdc->prdch2->cookie);
  671. switch ( prdc->nColumn )
  672. {
  673. case COLNUM_CERT_TEMPLATE_OBJECT:
  674. *pnResult = LocaleStrCmp (pCertTemplateA->GetDisplayName (), pCertTemplateB->GetDisplayName ());
  675. break;
  676. case COLNUM_CERT_TEMPLATE_TYPE:
  677. if ( pCertTemplateA->GetType () == pCertTemplateB->GetType () )
  678. *pnResult = 0;
  679. else if ( pCertTemplateA->GetType () > pCertTemplateB->GetType () )
  680. *pnResult = 1;
  681. else
  682. *pnResult = -1;
  683. break;
  684. case COLNUM_CERT_TEMPLATE_VERSION:
  685. {
  686. // Sort first on major version, then on minor version
  687. *pnResult = 0;
  688. DWORD dwMajorVersionA = 0;
  689. hr = pCertTemplateA->GetMajorVersion (dwMajorVersionA);
  690. if ( SUCCEEDED (hr) )
  691. {
  692. DWORD dwMajorVersionB = 0;
  693. hr = pCertTemplateB->GetMajorVersion (dwMajorVersionB);
  694. if ( SUCCEEDED (hr) )
  695. {
  696. if ( dwMajorVersionA == dwMajorVersionB )
  697. {
  698. DWORD dwMinorVersionA = 0;
  699. hr = pCertTemplateA->GetMinorVersion (dwMinorVersionA);
  700. if ( SUCCEEDED (hr) )
  701. {
  702. DWORD dwMinorVersionB = 0;
  703. hr = pCertTemplateB->GetMinorVersion (dwMinorVersionB);
  704. if ( SUCCEEDED (hr) )
  705. {
  706. if ( dwMinorVersionA == dwMinorVersionB )
  707. *pnResult = 0;
  708. else if ( dwMinorVersionA > dwMinorVersionB )
  709. *pnResult = 1;
  710. else
  711. *pnResult = -1;
  712. }
  713. }
  714. }
  715. else if ( dwMajorVersionA > dwMajorVersionB )
  716. *pnResult = 1;
  717. else
  718. *pnResult = -1;
  719. }
  720. }
  721. }
  722. break;
  723. case COLNUM_CERT_TEMPLATE_AUTOENROLL_STATUS:
  724. if ( pCertTemplateA->GoodForAutoEnrollment () &&
  725. pCertTemplateB->GoodForAutoEnrollment () )
  726. {
  727. *pnResult = 0;
  728. }
  729. else if ( pCertTemplateA->GoodForAutoEnrollment () &&
  730. !pCertTemplateB->GoodForAutoEnrollment () )
  731. {
  732. *pnResult = 1;
  733. }
  734. else
  735. *pnResult = 0;
  736. break;
  737. default:
  738. ASSERT (0);
  739. break;
  740. }
  741. }
  742. break;
  743. default:
  744. ASSERT (0);
  745. break;
  746. }
  747. }
  748. // _TRACE (-1, L"Leaving CCertTmplComponent::Compare\n");
  749. return hr;
  750. }
  751. /////////////////////////////////////////////////////////////////////
  752. // Virtual function called by CComponent::IComponent::Notify (MMCN_COLUMN_CLICK)
  753. HRESULT CCertTmplComponent::OnNotifyColumnClick (LPDATAOBJECT /*pDataObject*/, LPARAM iColumn, LPARAM uFlags)
  754. {
  755. _TRACE (1, L"Entering CCertTmplComponent::OnNotifyColumnClick\n");
  756. IResultData* pResultData = 0;
  757. HRESULT hr = m_pConsole->QueryInterface (
  758. IID_PPV_ARG (IResultData, &pResultData));
  759. if ( SUCCEEDED (hr) )
  760. {
  761. hr = pResultData->Sort ((DWORD)iColumn, (DWORD)uFlags, 0);
  762. _TRACE (0, L"IResultData::Sort () returned: 0x%x\n", hr);
  763. pResultData->Release ();
  764. }
  765. _TRACE (-1, L"Leaving CCertTmplComponent::OnNotifyColumnClick\n");
  766. return hr;
  767. }
  768. STDMETHODIMP CCertTmplComponent::Notify (LPDATAOBJECT pDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
  769. {
  770. HRESULT hr = S_OK;
  771. switch (event)
  772. {
  773. case MMCN_CUTORMOVE:
  774. hr = OnNotifyCutOrMove (arg);
  775. break;
  776. case MMCN_QUERY_PASTE:
  777. hr = OnNotifyQueryPaste (pDataObject, arg, param);
  778. break;
  779. case MMCN_PASTE:
  780. hr = OnNotifyPaste (pDataObject, arg, param);
  781. break;
  782. case MMCN_SHOW:
  783. {
  784. CCookie* pCookie = NULL;
  785. hr = ::ExtractData (pDataObject,
  786. CDataObject::m_CFRawCookie,
  787. &pCookie,
  788. sizeof(pCookie));
  789. if ( SUCCEEDED (hr) )
  790. {
  791. hr = Show (ActiveBaseCookie (pCookie), arg,
  792. (HSCOPEITEM) param, pDataObject);
  793. }
  794. }
  795. break;
  796. case MMCN_RENAME:
  797. hr = OnNotifyRename (pDataObject, arg, param);
  798. break;
  799. default:
  800. hr = CComponent::Notify (pDataObject, event, arg, param);
  801. break;
  802. }
  803. return hr;
  804. }
  805. HRESULT CCertTmplComponent::OnNotifySnapinHelp (LPDATAOBJECT pDataObject)
  806. {
  807. _TRACE (1, L"Entering CCertTmplComponent::OnNotifySnapinHelp\n");
  808. AFX_MANAGE_STATE (AfxGetStaticModuleState ( ));
  809. CComQIPtr<IDisplayHelp,&IID_IDisplayHelp> spDisplayHelp = m_pConsole;
  810. if ( !spDisplayHelp )
  811. {
  812. ASSERT(FALSE);
  813. return E_UNEXPECTED;
  814. }
  815. CString strHelpTopic;
  816. UINT nLen = ::GetSystemWindowsDirectory (strHelpTopic.GetBufferSetLength(2 * MAX_PATH), 2 * MAX_PATH);
  817. strHelpTopic.ReleaseBuffer();
  818. if (0 == nLen)
  819. {
  820. ASSERT(FALSE);
  821. return E_FAIL;
  822. }
  823. strHelpTopic += CERTTMPL_HELP_PATH;
  824. strHelpTopic += CERTTMPL_HTML_HELP_FILE;
  825. strHelpTopic += L"::/";
  826. CCertTmplComponentData& compData = QueryComponentDataRef ();
  827. CCertTmplCookie* pCookie = compData.ConvertCookie (pDataObject);
  828. if ( pCookie )
  829. {
  830. switch (pCookie->m_objecttype)
  831. {
  832. case CERTTMPL_SNAPIN:
  833. case CERTTMPL_CERT_TEMPLATE:
  834. default:
  835. strHelpTopic += CERTTMPL_HTML_TOP_NODE;
  836. break;
  837. }
  838. }
  839. HRESULT hr = spDisplayHelp->ShowTopic (T2OLE ((PWSTR)(PCWSTR) strHelpTopic));
  840. if ( FAILED (hr) )
  841. {
  842. CString caption;
  843. CString text;
  844. VERIFY (caption.LoadString (IDS_CERTTMPL));
  845. text.FormatMessage (IDS_CANT_DISPLAY_SNAPIN_HELP_TOPIC, strHelpTopic,
  846. GetSystemMessage (hr));
  847. int iRetVal = 0;
  848. VERIFY (SUCCEEDED (m_pConsole->MessageBox (text, caption,
  849. MB_ICONWARNING | MB_OK, &iRetVal)));
  850. }
  851. _TRACE (-1, L"Leaving CCertTmplComponent::OnNotifySnapinHelp\n");
  852. return hr;
  853. }
  854. void CCertTmplComponent::DisplayAccessDenied ()
  855. {
  856. DWORD dwErr = GetLastError ();
  857. ASSERT (E_ACCESSDENIED == dwErr);
  858. if ( E_ACCESSDENIED == dwErr )
  859. {
  860. LPVOID lpMsgBuf;
  861. FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  862. NULL,
  863. GetLastError (),
  864. MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  865. (PWSTR) &lpMsgBuf, 0, NULL );
  866. // Display the string.
  867. CString caption;
  868. VERIFY (caption.LoadString (IDS_CERTTMPL));
  869. int iRetVal = 0;
  870. VERIFY (SUCCEEDED (m_pConsole->MessageBox ( (PWSTR) lpMsgBuf, caption,
  871. MB_ICONWARNING | MB_OK, &iRetVal)));
  872. // Free the buffer.
  873. LocalFree (lpMsgBuf);
  874. }
  875. }
  876. HRESULT CCertTmplComponent::OnNotifyPaste (LPDATAOBJECT /*pDataObject*/, LPARAM /*arg*/, LPARAM /*param*/)
  877. {
  878. return E_NOTIMPL;
  879. }
  880. HRESULT CCertTmplComponent::OnNotifyQueryPaste(LPDATAOBJECT /*pDataObject*/, LPARAM /*arg*/, LPARAM /*param*/)
  881. {
  882. return E_NOTIMPL;
  883. }
  884. STDMETHODIMP CCertTmplComponent::GetResultViewType(MMC_COOKIE cookie,
  885. BSTR* ppViewType,
  886. long* pViewOptions)
  887. {
  888. CCertTmplCookie* pScopeCookie = reinterpret_cast <CCertTmplCookie*> (cookie);
  889. if ( pScopeCookie )
  890. {
  891. switch (pScopeCookie->m_objecttype)
  892. {
  893. case CERTTMPL_SNAPIN:
  894. *pViewOptions |= MMC_VIEW_OPTIONS_MULTISELECT;
  895. break;
  896. case CERTTMPL_CERT_TEMPLATE:
  897. default:
  898. break;
  899. }
  900. }
  901. else
  902. *pViewOptions |= MMC_VIEW_OPTIONS_MULTISELECT;
  903. *ppViewType = NULL;
  904. return S_FALSE;
  905. }
  906. STDMETHODIMP CCertTmplComponent::Initialize(LPCONSOLE lpConsole)
  907. {
  908. _TRACE (1, L"Entering CCertTmplComponent::Initialize\n");
  909. HRESULT hr = CComponent::Initialize (lpConsole);
  910. if ( SUCCEEDED (hr) )
  911. {
  912. ASSERT (m_pHeader);
  913. QueryComponentDataRef ().m_pHeader = m_pHeader;
  914. if ( lpConsole )
  915. {
  916. if ( QueryComponentDataRef ().m_pComponentConsole )
  917. SAFE_RELEASE (QueryComponentDataRef ().m_pComponentConsole);
  918. QueryComponentDataRef ().m_pComponentConsole = m_pConsole;
  919. QueryComponentDataRef ().m_pComponentConsole->AddRef ();
  920. }
  921. }
  922. _TRACE (-1, L"Leaving CCertTmplComponent::Initialize\n");
  923. return hr;
  924. }
  925. HRESULT CCertTmplComponent::LoadColumnsFromArrays (CertTmplObjectType objecttype )
  926. {
  927. _TRACE (1, L"Entering CCertTmplComponent::LoadColumnsFromArrays\n");
  928. ASSERT (m_pHeader);
  929. CString str;
  930. for ( INT i = 0; 0 != m_Columns[objecttype][i]; i++)
  931. {
  932. VERIFY(str.LoadString (m_Columns[objecttype][i]));
  933. m_pHeader->InsertColumn(i, const_cast<PWSTR>((PCWSTR)str), LVCFMT_LEFT,
  934. m_ColumnWidths[objecttype][i]);
  935. }
  936. _TRACE (-1, L"Leaving CCertTmplComponent::LoadColumnsFromArrays\n");
  937. return S_OK;
  938. }
  939. HRESULT CCertTmplComponent::SaveWidths(CCertTmplCookie * pCookie)
  940. {
  941. _TRACE (1, L"Entering CCertTmplComponent::SaveWidths\n");
  942. HRESULT hr = S_OK;
  943. m_fDirty = TRUE;
  944. ASSERT (pCookie);
  945. if ( pCookie )
  946. {
  947. switch (m_pViewedCookie->m_objecttype)
  948. {
  949. case CERTTMPL_SNAPIN:
  950. {
  951. const UINT* pColumns = m_Columns[m_pViewedCookie->m_objecttype];
  952. ASSERT(pColumns);
  953. int nWidth = 0;
  954. for (UINT iIndex = 0; iIndex < pColumns[iIndex]; iIndex++)
  955. {
  956. hr = m_pHeader->GetColumnWidth ((int) iIndex, &nWidth);
  957. if ( SUCCEEDED (hr) )
  958. {
  959. m_ColumnWidths[m_pViewedCookie->m_objecttype][iIndex] =
  960. (UINT) nWidth;
  961. }
  962. else
  963. break;
  964. }
  965. }
  966. break;
  967. default:
  968. ASSERT (0);
  969. break;
  970. }
  971. }
  972. else
  973. hr = E_POINTER;
  974. _TRACE (-1, L"Leaving CCertTmplComponent::SaveWidths\n");
  975. return hr;
  976. }
  977. ///////////////////////////////////////////////////////////////////////////////
  978. #define _dwMagicword 10000 // Internal version number
  979. STDMETHODIMP CCertTmplComponent::Load(IStream __RPC_FAR *pIStream)
  980. {
  981. _TRACE (1, L"Entering CCertTmplComponent::Load\n");
  982. HRESULT hr = S_OK;
  983. #ifndef DONT_PERSIST
  984. ASSERT (pIStream);
  985. XSafeInterfacePtr<IStream> pIStreamSafePtr( pIStream );
  986. // Read the magic word from the stream
  987. DWORD dwMagicword = 0;
  988. hr = pIStream->Read (&dwMagicword, sizeof(dwMagicword), NULL);
  989. if ( FAILED(hr) )
  990. {
  991. ASSERT( FALSE );
  992. return hr;
  993. }
  994. if (dwMagicword != _dwMagicword)
  995. {
  996. // We have a version mismatch
  997. _TRACE(0, L"INFO: CCertTmplComponentData::Load() - Wrong Magicword. You need to re-save your .msc file.\n");
  998. return E_FAIL;
  999. }
  1000. int numCols = 0;
  1001. for (int iIndex = 0; iIndex < CERTTMPL_NUMTYPES && SUCCEEDED (hr); iIndex++)
  1002. {
  1003. switch (iIndex)
  1004. {
  1005. case CERTTMPL_SNAPIN:
  1006. numCols = CERT_TEMPLATES_NUM_COLS;
  1007. break;;
  1008. case CERTTMPL_CERT_TEMPLATE:
  1009. continue;
  1010. default:
  1011. ASSERT (0);
  1012. break;
  1013. }
  1014. for (int colNum = 0; colNum < numCols; colNum++)
  1015. {
  1016. hr = pIStream->Read (&(m_ColumnWidths[iIndex][colNum]),
  1017. sizeof (UINT), NULL);
  1018. ASSERT (SUCCEEDED (hr));
  1019. if ( FAILED(hr) )
  1020. {
  1021. break;
  1022. }
  1023. }
  1024. }
  1025. #endif
  1026. _TRACE (-1, L"Leaving CCertTmplComponent::Load\n");
  1027. return S_OK;
  1028. }
  1029. ///////////////////////////////////////////////////////////////////////////////
  1030. STDMETHODIMP CCertTmplComponent::Save(IStream __RPC_FAR *pIStream, BOOL /*fSameAsLoad*/)
  1031. {
  1032. _TRACE (1, L"Entering CCertTmplComponent::Save\n");
  1033. HRESULT hr = S_OK;
  1034. #ifndef DONT_PERSIST
  1035. ASSERT (pIStream);
  1036. XSafeInterfacePtr<IStream> pIStreamSafePtr (pIStream);
  1037. // Store the magic word to the stream
  1038. DWORD dwMagicword = _dwMagicword;
  1039. hr = pIStream->Write (&dwMagicword, sizeof(dwMagicword), NULL);
  1040. ASSERT (SUCCEEDED (hr));
  1041. if ( FAILED (hr) )
  1042. return hr;
  1043. int numCols = 0;
  1044. for (int iIndex = 0; iIndex < CERTTMPL_NUMTYPES && SUCCEEDED (hr); iIndex++)
  1045. {
  1046. switch (iIndex)
  1047. {
  1048. case CERTTMPL_SNAPIN:
  1049. numCols = CERT_TEMPLATES_NUM_COLS;
  1050. break;;
  1051. case CERTTMPL_CERT_TEMPLATE:
  1052. continue;
  1053. default:
  1054. ASSERT (0);
  1055. break;
  1056. }
  1057. for (int colNum = 0; colNum < numCols; colNum++)
  1058. {
  1059. hr = pIStream->Write (&(m_ColumnWidths[iIndex][colNum]),
  1060. sizeof (UINT), NULL);
  1061. ASSERT (SUCCEEDED (hr));
  1062. if ( FAILED(hr) )
  1063. {
  1064. ASSERT (FALSE);
  1065. break;
  1066. }
  1067. }
  1068. }
  1069. #endif
  1070. _TRACE (-1, L"Leaving CCertTmplComponent::Save\n");
  1071. return S_OK;
  1072. }
  1073. HRESULT CCertTmplComponent::OnNotifyCutOrMove(LPARAM arg)
  1074. {
  1075. _TRACE (1, L"Entering CCertTmplComponent::OnNotifyCutOrMove\n");
  1076. if ( !arg )
  1077. return E_POINTER;
  1078. LPDATAOBJECT pDataObject = reinterpret_cast <IDataObject*> (arg);
  1079. ASSERT (pDataObject);
  1080. if ( !pDataObject )
  1081. return E_UNEXPECTED;
  1082. HRESULT hr = S_OK;
  1083. CCertTmplCookie* pCookie =
  1084. QueryComponentDataRef ().ConvertCookie (pDataObject);
  1085. if ( pCookie )
  1086. {
  1087. if ( ((CCertTmplCookie*) MMC_MULTI_SELECT_COOKIE) == pCookie )
  1088. {
  1089. CCertTemplatesDataObject* pDO = dynamic_cast <CCertTemplatesDataObject*>(pDataObject);
  1090. ASSERT (pDO);
  1091. if ( pDO )
  1092. {
  1093. pDO->Reset();
  1094. while (pDO->Next(1, reinterpret_cast<MMC_COOKIE*>(&pCookie), NULL) != S_FALSE)
  1095. {
  1096. hr = DeleteCookie (pCookie, pDataObject, false, true);
  1097. }
  1098. }
  1099. else
  1100. hr = E_FAIL;
  1101. }
  1102. else
  1103. {
  1104. hr = DeleteCookie (pCookie, pDataObject, false, false);
  1105. }
  1106. if ( SUCCEEDED (hr) )
  1107. RefreshResultPane (false);
  1108. }
  1109. _TRACE (-1, L"Leaving CCertTmplComponent::OnNotifyCutOrMove\n");
  1110. return hr;
  1111. }
  1112. CCertTmplCookie* CCertTmplComponent::ConvertCookie(LPDATAOBJECT pDataObject)
  1113. {
  1114. return QueryComponentDataRef ().ConvertCookie (pDataObject);
  1115. }
  1116. HRESULT CCertTmplComponent::RefreshResultItem (CCertTmplCookie* pCookie)
  1117. {
  1118. _TRACE (1, L"Entering CCertTmplComponent::RefreshResultItem\n");
  1119. ASSERT (pCookie);
  1120. if ( !pCookie )
  1121. return E_POINTER;
  1122. HRESULT hr = S_OK;
  1123. HRESULTITEM itemID = 0;
  1124. ASSERT (m_pResultData);
  1125. if ( m_pResultData )
  1126. {
  1127. pCookie->Refresh ();
  1128. hr = m_pResultData->FindItemByLParam ( (LPARAM) pCookie, &itemID);
  1129. ASSERT (SUCCEEDED (hr));
  1130. if ( SUCCEEDED (hr) )
  1131. {
  1132. hr = m_pResultData->UpdateItem (itemID);
  1133. ASSERT (SUCCEEDED (hr));
  1134. }
  1135. }
  1136. else
  1137. hr = E_FAIL;
  1138. _TRACE (-1, L"Leaving CCertTmplComponent::RefreshResultItem\n");
  1139. return hr;
  1140. }
  1141. /////////////////////////////////////////////////////////////////////
  1142. // Virtual function called by CComponent::IComponent::Notify(MMCN_PROPERTY_CHANGE)
  1143. // OnPropertyChange() is generated by MMCPropertyChangeNotify( param )
  1144. HRESULT CCertTmplComponent::OnPropertyChange (LPARAM param)
  1145. {
  1146. return QueryComponentDataRef ().OnPropertyChange (param);
  1147. }
  1148. HRESULT CCertTmplComponent::AddEnterpriseTemplates ()
  1149. {
  1150. _TRACE (1, L"Entering CCertTmplComponent::AddEnterpriseTemplates\n");
  1151. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1152. HRESULT hr = S_OK;
  1153. CWaitCursor cursor;
  1154. CComPtr<IADsPathname> spPathname;
  1155. //
  1156. // Constructing the directory paths
  1157. //
  1158. hr = CoCreateInstance(
  1159. CLSID_Pathname,
  1160. NULL,
  1161. CLSCTX_ALL,
  1162. IID_PPV_ARG (IADsPathname, &spPathname));
  1163. if ( SUCCEEDED (hr) )
  1164. {
  1165. ASSERT (!!spPathname);
  1166. hr = spPathname->Set(const_cast <PWSTR> (CERTTMPL_LDAP),
  1167. ADS_SETTYPE_PROVIDER);
  1168. if ( SUCCEEDED (hr) )
  1169. {
  1170. //
  1171. // Open the root DSE object
  1172. //
  1173. hr = spPathname->AddLeafElement(const_cast <PWSTR> (CERTTMPL_ROOTDSE));
  1174. if ( SUCCEEDED (hr) )
  1175. {
  1176. BSTR bstrFullPath = 0;
  1177. hr = spPathname->Retrieve(ADS_FORMAT_X500, &bstrFullPath);
  1178. if ( SUCCEEDED (hr) )
  1179. {
  1180. CComPtr<IADs> spRootDSEObject;
  1181. VARIANT varNamingContext;
  1182. hr = ADsGetObject (
  1183. bstrFullPath,
  1184. IID_PPV_ARG (IADs, &spRootDSEObject));
  1185. if ( SUCCEEDED (hr) )
  1186. {
  1187. ASSERT (!!spRootDSEObject);
  1188. //
  1189. // Get the configuration naming context from the root DSE
  1190. //
  1191. hr = spRootDSEObject->Get(const_cast <PWSTR> (CERTTMPL_CONFIG_NAMING_CONTEXT),
  1192. &varNamingContext);
  1193. if ( SUCCEEDED (hr) )
  1194. {
  1195. hr = spPathname->Set(V_BSTR(&varNamingContext),
  1196. ADS_SETTYPE_DN);
  1197. if ( SUCCEEDED (hr) )
  1198. {
  1199. hr = spPathname->AddLeafElement (L"CN=Services");
  1200. if ( SUCCEEDED (hr) )
  1201. {
  1202. hr = spPathname->AddLeafElement (L"CN=Public Key Services");
  1203. if ( SUCCEEDED (hr) )
  1204. {
  1205. hr = spPathname->AddLeafElement (L"CN=Certificate Templates");
  1206. if ( SUCCEEDED (hr) )
  1207. {
  1208. BSTR bstrCertTemplatePath = 0;
  1209. hr = spPathname->Retrieve(ADS_FORMAT_X500, &bstrCertTemplatePath);
  1210. if ( SUCCEEDED (hr) )
  1211. {
  1212. CComPtr<IDirectoryObject> spTemplateContObj;
  1213. hr = ADsGetObject (
  1214. bstrCertTemplatePath,
  1215. IID_PPV_ARG (IDirectoryObject, &spTemplateContObj));
  1216. if ( SUCCEEDED (hr) )
  1217. {
  1218. hr = EnumerateTemplates (spTemplateContObj, bstrCertTemplatePath);
  1219. if ( SUCCEEDED (hr) )
  1220. {
  1221. m_currResultNodeType = CERTTMPL_CERT_TEMPLATE;
  1222. hr = m_pResultData->Sort (COLNUM_CERT_TEMPLATE_OBJECT, 0, 0);
  1223. }
  1224. }
  1225. else
  1226. {
  1227. _TRACE (0, L"ADsGetObject (%s) failed: 0x%x\n", bstrCertTemplatePath, hr);
  1228. }
  1229. SysFreeString (bstrCertTemplatePath);
  1230. }
  1231. }
  1232. }
  1233. }
  1234. }
  1235. }
  1236. else
  1237. {
  1238. _TRACE (0, L"IADs::Get (%s) failed: 0x%x\n", CERTTMPL_CONFIG_NAMING_CONTEXT, hr);
  1239. }
  1240. }
  1241. else
  1242. {
  1243. _TRACE (0, L"ADsGetObject (%s) failed: 0x%x\n", bstrFullPath, hr);
  1244. }
  1245. }
  1246. }
  1247. }
  1248. }
  1249. else
  1250. hr = E_POINTER;
  1251. _TRACE (-1, L"Leaving CCertTmplComponent::AddEnterpriseTemplates\n");
  1252. return hr;
  1253. }
  1254. HRESULT CCertTmplComponent::EnumerateTemplates (
  1255. IDirectoryObject* pTemplateContObj,
  1256. const BSTR bszTemplateContainerPath)
  1257. {
  1258. _TRACE (1, L"Entering CCertTmplComponent::EnumerateTemplates\n");
  1259. CCertTmplComponentData& dataRef = QueryComponentDataRef ();
  1260. CWaitCursor cursor;
  1261. dataRef.m_fUseCache = false;
  1262. // Bug 243609 CertServer: Wrong count of templates displayed in the MMC
  1263. dataRef.m_dwNumCertTemplates = 0;
  1264. dataRef.m_globalTemplateNameList.RemoveAll ();
  1265. dataRef.m_globalFriendlyNameList.RemoveAll ();
  1266. CComPtr<IDirectorySearch> spDsSearch;
  1267. HRESULT hr = pTemplateContObj->QueryInterface (IID_PPV_ARG(IDirectorySearch, &spDsSearch));
  1268. if ( SUCCEEDED (hr) )
  1269. {
  1270. ASSERT (!!spDsSearch);
  1271. ADS_SEARCHPREF_INFO pSearchPref[1];
  1272. DWORD dwNumPref = 1;
  1273. pSearchPref[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
  1274. pSearchPref[0].vValue.dwType = ADSTYPE_INTEGER;
  1275. pSearchPref[0].vValue.Integer = ADS_SCOPE_ONELEVEL;
  1276. hr = spDsSearch->SetSearchPreference(
  1277. pSearchPref,
  1278. dwNumPref
  1279. );
  1280. if ( SUCCEEDED (hr) )
  1281. {
  1282. static const DWORD cAttrs = 2;
  1283. static PWSTR rgszAttrList[cAttrs] = {L"displayName", L"cn"};
  1284. ADS_SEARCH_HANDLE hSearchHandle = 0;
  1285. wstring strQuery;
  1286. ADS_SEARCH_COLUMN Column;
  1287. Column.pszAttrName = 0;
  1288. strQuery = L"objectClass=pKICertificateTemplate";
  1289. hr = spDsSearch->ExecuteSearch(
  1290. const_cast <PWSTR>(strQuery.c_str ()),
  1291. rgszAttrList,
  1292. cAttrs,
  1293. &hSearchHandle
  1294. );
  1295. if ( SUCCEEDED (hr) )
  1296. {
  1297. CCookie& rootCookie = dataRef.QueryBaseRootCookie ();
  1298. while ((hr = spDsSearch->GetNextRow (hSearchHandle)) != S_ADS_NOMORE_ROWS )
  1299. {
  1300. if (FAILED(hr))
  1301. continue;
  1302. //
  1303. // Getting current row's information
  1304. //
  1305. hr = spDsSearch->GetColumn(
  1306. hSearchHandle,
  1307. rgszAttrList[0],
  1308. &Column
  1309. );
  1310. if ( SUCCEEDED (hr) )
  1311. {
  1312. CString strDisplayName = Column.pADsValues->CaseIgnoreString;
  1313. spDsSearch->FreeColumn (&Column);
  1314. Column.pszAttrName = NULL;
  1315. hr = spDsSearch->GetColumn(
  1316. hSearchHandle,
  1317. rgszAttrList[1],
  1318. &Column
  1319. );
  1320. if ( SUCCEEDED (hr) )
  1321. {
  1322. CString strTemplateName = Column.pADsValues->CaseIgnoreString;
  1323. spDsSearch->FreeColumn (&Column);
  1324. Column.pszAttrName = NULL;
  1325. CComPtr<IADsPathname> spPathname;
  1326. //
  1327. // Constructing the directory paths
  1328. //
  1329. hr = CoCreateInstance(
  1330. CLSID_Pathname,
  1331. NULL,
  1332. CLSCTX_ALL,
  1333. IID_PPV_ARG (IADsPathname, &spPathname));
  1334. if ( SUCCEEDED (hr) )
  1335. {
  1336. ASSERT (!!spPathname);
  1337. hr = spPathname->Set(const_cast <PWSTR> (bszTemplateContainerPath),
  1338. ADS_SETTYPE_FULL);
  1339. if ( SUCCEEDED (hr) )
  1340. {
  1341. //
  1342. // Open the root DSE object
  1343. //
  1344. hr = spPathname->AddLeafElement(const_cast <PWSTR> ((PCWSTR) strTemplateName));
  1345. if ( SUCCEEDED (hr) )
  1346. {
  1347. BSTR bstrFullPath = 0;
  1348. hr = spPathname->Retrieve(ADS_FORMAT_X500, &bstrFullPath);
  1349. if ( SUCCEEDED (hr) )
  1350. {
  1351. CCertTemplate* pCertTemplate =
  1352. new CCertTemplate (strDisplayName, strTemplateName,
  1353. bstrFullPath, false,
  1354. dataRef.m_fUseCache);
  1355. if ( pCertTemplate )
  1356. {
  1357. dataRef.m_fUseCache = true;
  1358. rootCookie.m_listResultCookieBlocks.AddHead (pCertTemplate);
  1359. RESULTDATAITEM rdItem;
  1360. ::ZeroMemory (&rdItem, sizeof (rdItem));
  1361. rdItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
  1362. rdItem.nCol = 0;
  1363. rdItem.str = MMC_CALLBACK;
  1364. if ( 1 == pCertTemplate->GetType () )
  1365. rdItem.nImage = iIconCertTemplateV1;
  1366. else
  1367. rdItem.nImage = iIconCertTemplateV2;
  1368. rdItem.lParam = (LPARAM) pCertTemplate;
  1369. pCertTemplate->m_resultDataID = m_pResultData;
  1370. hr = m_pResultData->InsertItem (&rdItem);
  1371. if ( FAILED (hr) )
  1372. {
  1373. _TRACE (0, L"IResultData::InsertItem failed: 0x%x\n", hr);
  1374. hr = S_OK;
  1375. break;
  1376. }
  1377. else
  1378. {
  1379. dataRef.m_dwNumCertTemplates++;
  1380. dataRef.m_globalTemplateNameList.AddTail (strTemplateName);
  1381. dataRef.m_globalFriendlyNameList.AddHead (
  1382. pCertTemplate->GetDisplayName ());
  1383. }
  1384. }
  1385. else
  1386. {
  1387. hr = E_OUTOFMEMORY;
  1388. break;
  1389. }
  1390. SysFreeString (bstrFullPath);
  1391. }
  1392. }
  1393. }
  1394. }
  1395. }
  1396. }
  1397. else if ( hr != E_ADS_COLUMN_NOT_SET )
  1398. {
  1399. break;
  1400. }
  1401. else
  1402. {
  1403. _TRACE (0, L"IDirectorySearch::GetColumn () failed: 0x%x\n", hr);
  1404. }
  1405. }
  1406. }
  1407. else
  1408. {
  1409. _TRACE (0, L"IDirectorySearch::ExecuteSearch () failed: 0x%x\n", hr);
  1410. }
  1411. spDsSearch->CloseSearchHandle(hSearchHandle);
  1412. }
  1413. else
  1414. {
  1415. _TRACE (0, L"IDirectorySearch::SetSearchPreference () failed: 0x%x\n", hr);
  1416. }
  1417. }
  1418. else
  1419. {
  1420. _TRACE (0, L"IDirectoryObject::QueryInterface (IDirectorySearch) failed: 0x%x\n", hr);
  1421. }
  1422. _TRACE (-1, L"Leaving CCertTmplComponent::EnumerateTemplates: 0x%x\n", hr);
  1423. dataRef.m_fUseCache = false;
  1424. return hr;
  1425. }
  1426. HRESULT CCertTmplComponent::OnNotifyRename(LPDATAOBJECT pDataObject, LPARAM /*arg*/, LPARAM param)
  1427. {
  1428. _TRACE (1, L"Entering CCertTmplComponent::OnNotifyRename\n");
  1429. AFX_MANAGE_STATE (AfxGetStaticModuleState ());
  1430. HRESULT hr = S_FALSE;
  1431. CCertTmplCookie* pCookie = ConvertCookie (pDataObject);
  1432. if ( pCookie )
  1433. {
  1434. switch (pCookie->m_objecttype)
  1435. {
  1436. case CERTTMPL_CERT_TEMPLATE:
  1437. {
  1438. CString newName = (LPOLESTR) param;
  1439. newName.TrimLeft ();
  1440. newName.TrimRight ();
  1441. if ( !newName.IsEmpty () )
  1442. {
  1443. CCertTmplComponentData& dataref = QueryComponentDataRef ();
  1444. POSITION pos = 0;
  1445. bool bFound = false;
  1446. for (pos = dataref.m_globalFriendlyNameList.GetHeadPosition (); pos;)
  1447. {
  1448. if ( !_wcsicmp (newName, dataref.m_globalFriendlyNameList.GetNext (pos)) )
  1449. {
  1450. CString caption;
  1451. CString text;
  1452. VERIFY (caption.LoadString (IDS_CERTTMPL));
  1453. text.FormatMessage (IDS_FRIENDLY_NAME_ALREADY_USED, newName);
  1454. int iRetVal = 0;
  1455. VERIFY (SUCCEEDED (m_pConsole->MessageBox (text, caption,
  1456. MB_OK, &iRetVal)));
  1457. bFound = true;
  1458. break;
  1459. }
  1460. }
  1461. if ( !bFound )
  1462. {
  1463. CCertTemplate* pCertTemplate = dynamic_cast<CCertTemplate*> (pCookie);
  1464. if ( pCertTemplate )
  1465. {
  1466. hr = pCertTemplate->SetDisplayName (newName);
  1467. if ( SUCCEEDED (hr) )
  1468. {
  1469. hr = pCertTemplate->SaveChanges ();
  1470. if ( FAILED (hr) )
  1471. {
  1472. CString caption;
  1473. CString text;
  1474. VERIFY (caption.LoadString (IDS_CERTTMPL));
  1475. text.FormatMessage (IDS_UNABLE_TO_SAVE_CERT_TEMPLATE_CHANGES, GetSystemMessage (hr));
  1476. int iRetVal = 0;
  1477. VERIFY (SUCCEEDED (m_pConsole->MessageBox (text, caption,
  1478. MB_ICONWARNING | MB_OK, &iRetVal)));
  1479. }
  1480. }
  1481. else
  1482. {
  1483. CString caption;
  1484. CString text;
  1485. VERIFY (caption.LoadString (IDS_CERTTMPL));
  1486. text.FormatMessage (IDS_CANNOT_CHANGE_DISPLAY_NAME, hr);
  1487. int iRetVal = 0;
  1488. VERIFY (SUCCEEDED (m_pConsole->MessageBox (text, caption,
  1489. MB_ICONWARNING | MB_OK, &iRetVal)));
  1490. }
  1491. }
  1492. }
  1493. }
  1494. else
  1495. {
  1496. CString caption;
  1497. CString text;
  1498. VERIFY (caption.LoadString (IDS_CERTTMPL));
  1499. VERIFY (text.LoadString (IDS_MUST_TYPE_TEMPLATE_DISPLAY_NAME));
  1500. int iRetVal = 0;
  1501. VERIFY (SUCCEEDED (m_pConsole->MessageBox (text, caption,
  1502. MB_ICONWARNING | MB_OK, &iRetVal)));
  1503. hr = S_FALSE;
  1504. }
  1505. }
  1506. break;
  1507. default:
  1508. break;
  1509. }
  1510. }
  1511. if ( !SUCCEEDED (hr) )
  1512. hr = S_FALSE;
  1513. _TRACE(-1, L"Leaving CCertTmplComponent::OnNotifyRename: 0x%x\n", hr);
  1514. return hr;
  1515. }