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.

625 lines
18 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1997-2001
  3. Module Name:
  4. ShellExt.cpp
  5. Abstract:
  6. This is the implementation file for Dfs Shell Extension object which implements
  7. IShellIExtInit and IShellPropSheetExt.
  8. Author:
  9. Constancio Fernandes (ferns@qspl.stpp.soft.net) 12-Jan-1998
  10. Environment:
  11. NT only.
  12. */
  13. #include "stdafx.h"
  14. #include <dsclient.h>
  15. #include "ShellExt.h"
  16. #include "TemplateGeneralPropertyPage.h"
  17. #include "TemplateV1RequestPropertyPage.h"
  18. #include "TemplateV2RequestPropertyPage.h"
  19. #include "TemplateV1SubjectNamePropertyPage.h"
  20. #include "TemplateV2SubjectNamePropertyPage.h"
  21. #include "TemplateV2AuthenticationPropertyPage.h"
  22. #include "TemplateV2SupercedesPropertyPage.h"
  23. #include "TemplateExtensionsPropertyPage.h"
  24. #include "SecurityPropertyPage.h"
  25. #include "PolicyOID.h"
  26. #define ByteOffset(base, offset) (((LPBYTE)base)+offset)
  27. /*----------------------------------------------------------------------
  28. IShellExtInit Implementation.
  29. ------------------------------------------------------------------------*/
  30. CCertTemplateShellExt::CCertTemplateShellExt()
  31. : m_Count (0),
  32. m_apCertTemplates (0),
  33. m_uiEditId (0)
  34. {
  35. }
  36. CCertTemplateShellExt::~CCertTemplateShellExt()
  37. {
  38. if ( m_apCertTemplates )
  39. {
  40. for (int nIndex = 0; nIndex < m_Count; nIndex++)
  41. {
  42. if ( m_apCertTemplates[nIndex] )
  43. m_apCertTemplates[nIndex]->Release ();
  44. }
  45. }
  46. }
  47. STDMETHODIMP CCertTemplateShellExt::Initialize
  48. (
  49. IN LPCITEMIDLIST /*pidlFolder*/, // Points to an ITEMIDLIST structure
  50. IN LPDATAOBJECT pDataObj, // Points to an IDataObject interface
  51. IN HKEY /*hkeyProgID*/ // Registry key for the file object or folder type
  52. )
  53. {
  54. HRESULT hr = 0;
  55. FORMATETC fmte = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  56. STGMEDIUM medium = { TYMED_NULL };
  57. LPDSOBJECTNAMES pDsObjects;
  58. CString csClass, csPath;
  59. USES_CONVERSION;
  60. PWSTR wszTypeDN = 0;
  61. PWSTR wszTemplateName = 0;
  62. PWSTR wszType = 0;
  63. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  64. // if we have a pDataObj then try and get the first name from it
  65. if ( pDataObj )
  66. {
  67. // get path and class
  68. fmte.cfFormat = (CLIPFORMAT) RegisterClipboardFormat(CFSTR_DSOBJECTNAMES);
  69. if ( SUCCEEDED(pDataObj->GetData(&fmte, &medium)) )
  70. {
  71. pDsObjects = (LPDSOBJECTNAMES)medium.hGlobal;
  72. m_Count = pDsObjects->cItems;
  73. if(m_Count > 0)
  74. {
  75. m_apCertTemplates = (CCertTemplate **)LocalAlloc(LMEM_FIXED, sizeof(CCertTemplate*)*m_Count);
  76. if(m_apCertTemplates == NULL)
  77. {
  78. hr = E_OUTOFMEMORY;
  79. goto error;
  80. }
  81. ZeroMemory(m_apCertTemplates, sizeof(CCertTemplate*)*m_Count);
  82. for (UINT index = 0; index < m_Count ; index++)
  83. {
  84. LPWSTR wszEnd = NULL;
  85. wszTypeDN = (LPWSTR)ByteOffset(pDsObjects, pDsObjects->aObjects[index].offsetName);
  86. if(wszTypeDN == NULL)
  87. {
  88. continue;
  89. }
  90. wszTemplateName = wcsstr(wszTypeDN, L"CN=");
  91. if(wszTemplateName == NULL)
  92. {
  93. continue;
  94. }
  95. wszTemplateName += 3;
  96. wszType = (LPWSTR)LocalAlloc(LMEM_FIXED, sizeof(WCHAR)*(wcslen(wszTemplateName)+1));
  97. if(wszType == NULL)
  98. {
  99. hr = E_OUTOFMEMORY;
  100. goto error;
  101. }
  102. wcscpy(wszType, wszTemplateName);
  103. wszEnd = wcschr(wszType, L',');
  104. if(wszEnd)
  105. {
  106. *wszEnd = 0;
  107. }
  108. m_apCertTemplates[index] = new CCertTemplate (0, wszType, wszTypeDN, false, true);
  109. // hr = CAFindCertTypeByName(wszType, NULL, CT_ENUM_MACHINE_TYPES |
  110. // CT_ENUM_USER_TYPES |
  111. // CT_FLAG_NO_CACHE_LOOKUP,
  112. // &m_apCertTemplates[index]);
  113. LocalFree(wszType);
  114. wszType = NULL;
  115. }
  116. }
  117. ReleaseStgMedium(&medium);
  118. }
  119. }
  120. hr = S_OK; // success
  121. error:
  122. return hr;
  123. }
  124. STDMETHODIMP CCertTemplateShellExt::AddPages
  125. (
  126. IN LPFNADDPROPSHEETPAGE lpfnAddPage,
  127. IN LPARAM lParam
  128. )
  129. {
  130. HRESULT hr = S_OK;
  131. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  132. if(m_apCertTemplates[0] == NULL)
  133. {
  134. return E_UNEXPECTED;
  135. }
  136. DWORD dwType = m_apCertTemplates[0]->GetType ();
  137. switch (dwType)
  138. {
  139. case 1:
  140. hr = AddVersion1CertTemplatePropPages (m_apCertTemplates[0], lpfnAddPage, lParam);
  141. break;
  142. case 2:
  143. hr = AddVersion2CertTemplatePropPages (m_apCertTemplates[0], lpfnAddPage, lParam);
  144. break;
  145. default:
  146. _ASSERT (0);
  147. break;
  148. }
  149. /*
  150. CCertTemplateGeneralPage* pControlPage = new CCertTemplateGeneralPage(m_apCertTemplates[0]);
  151. if(pControlPage)
  152. {
  153. pBasePage = pControlPage;
  154. HPROPSHEETPAGE hPage = MyCreatePropertySheetPage(&pBasePage->m_psp);
  155. if (hPage == NULL)
  156. {
  157. delete (pControlPage);
  158. return E_UNEXPECTED;
  159. }
  160. lpfnAddPage(hPage, lParam);
  161. }
  162. */
  163. return hr;
  164. }
  165. HRESULT CCertTemplateShellExt::AddVersion1CertTemplatePropPages (CCertTemplate* pCertTemplate, LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam)
  166. {
  167. _TRACE (1, L"Entering CCertTemplateShellExt::AddVersion1CertTemplatePropPages\n");
  168. HRESULT hr = S_OK;
  169. _ASSERT (pCertTemplate && lpfnAddPage);
  170. if ( pCertTemplate && lpfnAddPage )
  171. {
  172. BOOL bResult = FALSE;
  173. _ASSERT (1 == pCertTemplate->GetType ());
  174. // Add General page
  175. CTemplateGeneralPropertyPage * pGeneralPage = new CTemplateGeneralPropertyPage (
  176. *pCertTemplate, 0);
  177. if ( pGeneralPage )
  178. {
  179. HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pGeneralPage->m_psp);
  180. _ASSERT (hPage);
  181. if ( hPage )
  182. {
  183. bResult = lpfnAddPage (hPage, lParam);
  184. _ASSERT (bResult);
  185. if ( !bResult )
  186. hr = E_FAIL;
  187. }
  188. else
  189. hr = E_FAIL;
  190. }
  191. else
  192. {
  193. hr = E_OUTOFMEMORY;
  194. }
  195. // Add Request page only if subject is not a CA
  196. if ( SUCCEEDED (hr) && !pCertTemplate->SubjectIsCA () )
  197. {
  198. CTemplateV1RequestPropertyPage * pRequestPage = new CTemplateV1RequestPropertyPage (*pCertTemplate);
  199. if ( pRequestPage )
  200. {
  201. HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pRequestPage->m_psp);
  202. _ASSERT (hPage);
  203. if ( hPage )
  204. {
  205. bResult = lpfnAddPage (hPage, lParam);
  206. _ASSERT (bResult);
  207. if ( !bResult )
  208. hr = E_FAIL;
  209. }
  210. else
  211. hr = E_FAIL;
  212. }
  213. else
  214. {
  215. hr = E_OUTOFMEMORY;
  216. }
  217. }
  218. // Add Subject Name page only if subject is not a CA
  219. if ( SUCCEEDED (hr) && !pCertTemplate->SubjectIsCA () )
  220. {
  221. CTemplateV1SubjectNamePropertyPage * pSubjectNamePage =
  222. new CTemplateV1SubjectNamePropertyPage (*pCertTemplate);
  223. if ( pSubjectNamePage )
  224. {
  225. HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pSubjectNamePage->m_psp);
  226. _ASSERT (hPage);
  227. if ( hPage )
  228. {
  229. bResult = lpfnAddPage (hPage, lParam);
  230. _ASSERT (bResult);
  231. if ( !bResult )
  232. hr = E_FAIL;
  233. }
  234. else
  235. hr = E_FAIL;
  236. }
  237. else
  238. {
  239. hr = E_OUTOFMEMORY;
  240. }
  241. }
  242. // Add extensions page
  243. if ( SUCCEEDED (hr) )
  244. {
  245. CTemplateExtensionsPropertyPage * pExtensionsPage =
  246. new CTemplateExtensionsPropertyPage (*pCertTemplate,
  247. pGeneralPage->m_bIsDirty);
  248. if ( pExtensionsPage )
  249. {
  250. HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pExtensionsPage->m_psp);
  251. _ASSERT (hPage);
  252. if ( hPage )
  253. {
  254. bResult = lpfnAddPage (hPage, lParam);
  255. _ASSERT (bResult);
  256. if ( !bResult )
  257. hr = E_FAIL;
  258. }
  259. else
  260. hr = E_FAIL;
  261. }
  262. else
  263. {
  264. hr = E_OUTOFMEMORY;
  265. }
  266. }
  267. // Add security page
  268. if ( SUCCEEDED (hr) )
  269. {
  270. // if error, don't display this page
  271. LPSECURITYINFO pCertTemplateSecurity = NULL;
  272. hr = CreateCertTemplateSecurityInfo (pCertTemplate,
  273. &pCertTemplateSecurity);
  274. if ( SUCCEEDED (hr) )
  275. {
  276. // save the pCASecurity pointer for later releasing
  277. pGeneralPage->SetAllocedSecurityInfo (pCertTemplateSecurity);
  278. HPROPSHEETPAGE hPage = CreateSecurityPage (pCertTemplateSecurity);
  279. if (hPage == NULL)
  280. {
  281. hr = HRESULT_FROM_WIN32 (GetLastError());
  282. _TRACE (0, L"CreateSecurityPage () failed: 0x%x\n", hr);
  283. }
  284. bResult = lpfnAddPage (hPage, lParam);
  285. _ASSERT (bResult);
  286. }
  287. }
  288. }
  289. _TRACE (-1, L"Leaving CCertTemplateShellExt::AddVersion1CertTemplatePropPages: 0x%x\n", hr);
  290. return hr;
  291. }
  292. HRESULT CCertTemplateShellExt::AddVersion2CertTemplatePropPages (CCertTemplate* pCertTemplate, LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam)
  293. {
  294. _TRACE (1, L"Entering CCertTemplateShellExt::AddVersion1CertTemplatePropPages\n");
  295. HRESULT hr = S_OK;
  296. BOOL bResult = FALSE;
  297. _ASSERT (pCertTemplate && lpfnAddPage);
  298. if ( pCertTemplate && lpfnAddPage )
  299. {
  300. _ASSERT (2 == pCertTemplate->GetType ());
  301. // Add General page
  302. CTemplateGeneralPropertyPage * pGeneralPage = new CTemplateGeneralPropertyPage (
  303. *pCertTemplate, 0);
  304. if ( pGeneralPage )
  305. {
  306. pGeneralPage->m_lNotifyHandle = 0; //lNotifyHandle;
  307. //m_lNotifyHandle = lNotifyHandle;
  308. HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pGeneralPage->m_psp);
  309. _ASSERT (hPage);
  310. if ( hPage )
  311. {
  312. bResult = lpfnAddPage (hPage, lParam);
  313. _ASSERT (bResult);
  314. if ( !bResult )
  315. hr = E_FAIL;
  316. }
  317. else
  318. hr = E_FAIL;
  319. }
  320. else
  321. {
  322. hr = E_OUTOFMEMORY;
  323. }
  324. // Add Request page only if subject is not a CA
  325. if ( SUCCEEDED (hr) && !pCertTemplate->SubjectIsCA () )
  326. {
  327. CTemplateV2RequestPropertyPage * pRequestPage =
  328. new CTemplateV2RequestPropertyPage (*pCertTemplate,
  329. pGeneralPage->m_bIsDirty);
  330. if ( pRequestPage )
  331. {
  332. HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pRequestPage->m_psp);
  333. _ASSERT (hPage);
  334. if ( hPage )
  335. {
  336. bResult = lpfnAddPage (hPage, lParam);
  337. _ASSERT (bResult);
  338. if ( !bResult )
  339. hr = E_FAIL;
  340. }
  341. else
  342. hr = E_FAIL;
  343. }
  344. else
  345. {
  346. hr = E_OUTOFMEMORY;
  347. }
  348. }
  349. // Add Subject Name page only if subject is not a CA
  350. if ( SUCCEEDED (hr) && !pCertTemplate->SubjectIsCA () )
  351. {
  352. CTemplateV2SubjectNamePropertyPage * pSubjectNamePage =
  353. new CTemplateV2SubjectNamePropertyPage (*pCertTemplate,
  354. pGeneralPage->m_bIsDirty);
  355. if ( pSubjectNamePage )
  356. {
  357. HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pSubjectNamePage->m_psp);
  358. _ASSERT (hPage);
  359. bResult = lpfnAddPage (hPage, lParam);
  360. _ASSERT (bResult);
  361. }
  362. else
  363. {
  364. hr = E_OUTOFMEMORY;
  365. }
  366. }
  367. // Add Authentication Name page
  368. if ( SUCCEEDED (hr) )
  369. {
  370. CTemplateV2AuthenticationPropertyPage * pAuthenticationPage =
  371. new CTemplateV2AuthenticationPropertyPage (*pCertTemplate,
  372. pGeneralPage->m_bIsDirty);
  373. if ( pAuthenticationPage )
  374. {
  375. HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pAuthenticationPage->m_psp);
  376. _ASSERT (hPage);
  377. if ( hPage )
  378. {
  379. bResult = lpfnAddPage (hPage, lParam);
  380. _ASSERT (bResult);
  381. if ( !bResult )
  382. hr = E_FAIL;
  383. }
  384. else
  385. hr = E_FAIL;
  386. }
  387. else
  388. {
  389. hr = E_OUTOFMEMORY;
  390. }
  391. }
  392. // Add Superceded page
  393. if ( SUCCEEDED (hr) )
  394. {
  395. CTemplateV2SupercedesPropertyPage * pSupercededPage =
  396. new CTemplateV2SupercedesPropertyPage (*pCertTemplate,
  397. pGeneralPage->m_bIsDirty, 0);
  398. if ( pSupercededPage )
  399. {
  400. HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pSupercededPage->m_psp);
  401. _ASSERT (hPage);
  402. if ( hPage )
  403. {
  404. bResult = lpfnAddPage (hPage, lParam);
  405. _ASSERT (bResult);
  406. if ( !bResult )
  407. hr = E_FAIL;
  408. }
  409. else
  410. hr = E_FAIL;
  411. }
  412. else
  413. {
  414. hr = E_OUTOFMEMORY;
  415. }
  416. }
  417. // Add extensions page
  418. if ( SUCCEEDED (hr) )
  419. {
  420. CTemplateExtensionsPropertyPage * pExtensionsPage =
  421. new CTemplateExtensionsPropertyPage (*pCertTemplate,
  422. pGeneralPage->m_bIsDirty);
  423. if ( pExtensionsPage )
  424. {
  425. HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pExtensionsPage->m_psp);
  426. _ASSERT (hPage);
  427. if ( hPage )
  428. {
  429. bResult = lpfnAddPage (hPage, lParam);
  430. _ASSERT (bResult);
  431. if ( !bResult )
  432. hr = E_FAIL;
  433. }
  434. else
  435. hr = E_FAIL;
  436. }
  437. else
  438. {
  439. hr = E_OUTOFMEMORY;
  440. }
  441. }
  442. // Add security page
  443. if ( SUCCEEDED (hr) )
  444. {
  445. // if error, don't display this page
  446. LPSECURITYINFO pCertTemplateSecurity = NULL;
  447. hr = CreateCertTemplateSecurityInfo (pCertTemplate,
  448. &pCertTemplateSecurity);
  449. if ( SUCCEEDED (hr) )
  450. {
  451. // save the pCertTemplateSecurity pointer for later releasing
  452. pGeneralPage->SetAllocedSecurityInfo (pCertTemplateSecurity);
  453. HPROPSHEETPAGE hPage = CreateSecurityPage (pCertTemplateSecurity);
  454. if (hPage == NULL)
  455. {
  456. hr = HRESULT_FROM_WIN32 (GetLastError());
  457. _TRACE (0, L"CreateSecurityPage () failed: 0x%x\n", hr);
  458. }
  459. bResult = lpfnAddPage (hPage, lParam);
  460. _ASSERT (bResult);
  461. }
  462. }
  463. }
  464. _TRACE (-1, L"Leaving CCertTemplateShellExt::AddVersion1CertTemplatePropPages: 0x%x\n", hr);
  465. return hr;
  466. }
  467. STDMETHODIMP CCertTemplateShellExt::ReplacePage
  468. (
  469. IN UINT /*uPageID*/,
  470. IN LPFNADDPROPSHEETPAGE /*lpfnReplaceWith*/,
  471. IN LPARAM /*lParam*/
  472. )
  473. {
  474. return E_FAIL;
  475. }
  476. // IContextMenu methods
  477. STDMETHODIMP CCertTemplateShellExt::GetCommandString
  478. (
  479. UINT_PTR idCmd,
  480. UINT uFlags,
  481. UINT* /*pwReserved*/,
  482. LPSTR pszName,
  483. UINT cchMax
  484. )
  485. {
  486. if((idCmd == m_uiEditId) && (m_uiEditId != 0))
  487. {
  488. if (uFlags == GCS_HELPTEXT)
  489. {
  490. LoadString(AfxGetResourceHandle( ), IDS_EDIT_HINT, (LPTSTR)pszName, cchMax);
  491. return S_OK;
  492. }
  493. }
  494. return E_NOTIMPL;
  495. }
  496. STDMETHODIMP CCertTemplateShellExt::InvokeCommand
  497. (
  498. LPCMINVOKECOMMANDINFO lpici
  499. )
  500. {
  501. if (!HIWORD(lpici->lpVerb))
  502. {
  503. UINT idCmd = LOWORD(lpici->lpVerb);
  504. switch(idCmd)
  505. {
  506. case 0: // Edit
  507. // InvokeCertTypeWizard(m_ahCertTemplates[0],
  508. // lpici->hwnd);
  509. return S_OK;
  510. }
  511. }
  512. return E_NOTIMPL;
  513. }
  514. STDMETHODIMP CCertTemplateShellExt::QueryContextMenu
  515. (
  516. HMENU hmenu,
  517. UINT indexMenu,
  518. UINT idCmdFirst,
  519. UINT /*idCmdLast*/,
  520. UINT /*uFlags*/
  521. )
  522. {
  523. CString szEdit;
  524. MENUITEMINFO mii;
  525. UINT idLastUsedCmd = idCmdFirst;
  526. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  527. ZeroMemory(&mii, sizeof(mii));
  528. if(IsCerttypeEditingAllowed())
  529. {
  530. mii.cbSize = sizeof(mii);
  531. mii.fMask = MIIM_TYPE | MIIM_ID;
  532. mii.fType = MFT_STRING;
  533. mii.wID = idCmdFirst;
  534. szEdit.LoadString(IDS_EDIT);
  535. mii.dwTypeData = (LPTSTR)(LPCTSTR)szEdit;
  536. mii.cch = szEdit.GetLength();
  537. // Add new menu items to the context menu. //
  538. ::InsertMenuItem(hmenu,
  539. indexMenu++,
  540. TRUE,
  541. &mii);
  542. }
  543. return ResultFromScode (MAKE_SCODE (SEVERITY_SUCCESS, 0,
  544. USHORT (idLastUsedCmd + 1)));
  545. }