Leaked source code of windows server 2003
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.

624 lines
18 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1997-2002
  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 (
  76. LPTR, sizeof(CCertTemplate*)*m_Count);
  77. if(m_apCertTemplates == NULL)
  78. {
  79. hr = E_OUTOFMEMORY;
  80. goto error;
  81. }
  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. // security review 2/21/2002 BryanWal ok - worst case: wszTemplateName is "";
  97. wszType = (LPWSTR) ::LocalAlloc (LPTR, sizeof(WCHAR)*(wcslen(wszTemplateName)+1));
  98. if ( wszType == NULL )
  99. {
  100. hr = E_OUTOFMEMORY;
  101. goto error;
  102. }
  103. // security review 2/21/2002 BryanWal ok
  104. wcscpy (wszType, wszTemplateName);
  105. wszEnd = wcschr (wszType, L',');
  106. if ( wszEnd )
  107. {
  108. *wszEnd = 0;
  109. }
  110. m_apCertTemplates[index] = new CCertTemplate (0, wszType, wszTypeDN, false, true);
  111. LocalFree(wszType);
  112. wszType = NULL;
  113. }
  114. }
  115. ReleaseStgMedium(&medium);
  116. }
  117. }
  118. hr = S_OK; // success
  119. error:
  120. return hr;
  121. }
  122. STDMETHODIMP CCertTemplateShellExt::AddPages
  123. (
  124. IN LPFNADDPROPSHEETPAGE lpfnAddPage,
  125. IN LPARAM lParam
  126. )
  127. {
  128. HRESULT hr = S_OK;
  129. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  130. if(m_apCertTemplates[0] == NULL)
  131. {
  132. return E_UNEXPECTED;
  133. }
  134. DWORD dwType = m_apCertTemplates[0]->GetType ();
  135. switch (dwType)
  136. {
  137. case 1:
  138. hr = AddVersion1CertTemplatePropPages (m_apCertTemplates[0], lpfnAddPage, lParam);
  139. break;
  140. case 2:
  141. hr = AddVersion2CertTemplatePropPages (m_apCertTemplates[0], lpfnAddPage, lParam);
  142. break;
  143. default:
  144. _ASSERT (0);
  145. break;
  146. }
  147. /*
  148. CCertTemplateGeneralPage* pControlPage = new CCertTemplateGeneralPage(m_apCertTemplates[0]);
  149. if(pControlPage)
  150. {
  151. pBasePage = pControlPage;
  152. HPROPSHEETPAGE hPage = MyCreatePropertySheetPage(&pBasePage->m_psp);
  153. if (hPage == NULL)
  154. {
  155. delete (pControlPage);
  156. return E_UNEXPECTED;
  157. }
  158. lpfnAddPage(hPage, lParam);
  159. }
  160. */
  161. return hr;
  162. }
  163. HRESULT CCertTemplateShellExt::AddVersion1CertTemplatePropPages (CCertTemplate* pCertTemplate, LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam)
  164. {
  165. _TRACE (1, L"Entering CCertTemplateShellExt::AddVersion1CertTemplatePropPages\n");
  166. HRESULT hr = S_OK;
  167. _ASSERT (pCertTemplate && lpfnAddPage);
  168. if ( pCertTemplate && lpfnAddPage )
  169. {
  170. BOOL bResult = FALSE;
  171. _ASSERT (1 == pCertTemplate->GetType ());
  172. // Add General page
  173. CTemplateGeneralPropertyPage * pGeneralPage = new CTemplateGeneralPropertyPage (
  174. *pCertTemplate, 0);
  175. if ( pGeneralPage )
  176. {
  177. HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pGeneralPage->m_psp);
  178. _ASSERT (hPage);
  179. if ( hPage )
  180. {
  181. bResult = lpfnAddPage (hPage, lParam);
  182. _ASSERT (bResult);
  183. if ( !bResult )
  184. hr = E_FAIL;
  185. }
  186. else
  187. hr = E_FAIL;
  188. }
  189. else
  190. {
  191. hr = E_OUTOFMEMORY;
  192. }
  193. // Add Request page only if subject is not a CA
  194. if ( SUCCEEDED (hr) && !pCertTemplate->SubjectIsCA () )
  195. {
  196. CTemplateV1RequestPropertyPage * pRequestPage = new CTemplateV1RequestPropertyPage (*pCertTemplate);
  197. if ( pRequestPage )
  198. {
  199. HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pRequestPage->m_psp);
  200. _ASSERT (hPage);
  201. if ( hPage )
  202. {
  203. bResult = lpfnAddPage (hPage, lParam);
  204. _ASSERT (bResult);
  205. if ( !bResult )
  206. hr = E_FAIL;
  207. }
  208. else
  209. hr = E_FAIL;
  210. }
  211. else
  212. {
  213. hr = E_OUTOFMEMORY;
  214. }
  215. }
  216. // Add Subject Name page only if subject is not a CA
  217. if ( SUCCEEDED (hr) && !pCertTemplate->SubjectIsCA () )
  218. {
  219. CTemplateV1SubjectNamePropertyPage * pSubjectNamePage =
  220. new CTemplateV1SubjectNamePropertyPage (*pCertTemplate);
  221. if ( pSubjectNamePage )
  222. {
  223. HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pSubjectNamePage->m_psp);
  224. _ASSERT (hPage);
  225. if ( hPage )
  226. {
  227. bResult = lpfnAddPage (hPage, lParam);
  228. _ASSERT (bResult);
  229. if ( !bResult )
  230. hr = E_FAIL;
  231. }
  232. else
  233. hr = E_FAIL;
  234. }
  235. else
  236. {
  237. hr = E_OUTOFMEMORY;
  238. }
  239. }
  240. // Add extensions page
  241. if ( SUCCEEDED (hr) )
  242. {
  243. CTemplateExtensionsPropertyPage * pExtensionsPage =
  244. new CTemplateExtensionsPropertyPage (*pCertTemplate,
  245. pGeneralPage->m_bIsDirty);
  246. if ( pExtensionsPage )
  247. {
  248. HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pExtensionsPage->m_psp);
  249. _ASSERT (hPage);
  250. if ( hPage )
  251. {
  252. bResult = lpfnAddPage (hPage, lParam);
  253. _ASSERT (bResult);
  254. if ( !bResult )
  255. hr = E_FAIL;
  256. }
  257. else
  258. hr = E_FAIL;
  259. }
  260. else
  261. {
  262. hr = E_OUTOFMEMORY;
  263. }
  264. }
  265. // Add security page
  266. if ( SUCCEEDED (hr) )
  267. {
  268. // if error, don't display this page
  269. LPSECURITYINFO pCertTemplateSecurity = NULL;
  270. hr = CreateCertTemplateSecurityInfo (pCertTemplate,
  271. &pCertTemplateSecurity);
  272. if ( SUCCEEDED (hr) )
  273. {
  274. // save the pCASecurity pointer for later releasing
  275. pGeneralPage->SetAllocedSecurityInfo (pCertTemplateSecurity);
  276. HPROPSHEETPAGE hPage = CreateSecurityPage (pCertTemplateSecurity);
  277. if (hPage == NULL)
  278. {
  279. hr = HRESULT_FROM_WIN32 (GetLastError());
  280. _TRACE (0, L"CreateSecurityPage () failed: 0x%x\n", hr);
  281. }
  282. bResult = lpfnAddPage (hPage, lParam);
  283. _ASSERT (bResult);
  284. }
  285. }
  286. }
  287. _TRACE (-1, L"Leaving CCertTemplateShellExt::AddVersion1CertTemplatePropPages: 0x%x\n", hr);
  288. return hr;
  289. }
  290. HRESULT CCertTemplateShellExt::AddVersion2CertTemplatePropPages (CCertTemplate* pCertTemplate, LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam)
  291. {
  292. _TRACE (1, L"Entering CCertTemplateShellExt::AddVersion1CertTemplatePropPages\n");
  293. HRESULT hr = S_OK;
  294. BOOL bResult = FALSE;
  295. _ASSERT (pCertTemplate && lpfnAddPage);
  296. if ( pCertTemplate && lpfnAddPage )
  297. {
  298. _ASSERT (2 == pCertTemplate->GetType ());
  299. // Add General page
  300. CTemplateGeneralPropertyPage * pGeneralPage = new CTemplateGeneralPropertyPage (
  301. *pCertTemplate, 0);
  302. if ( pGeneralPage )
  303. {
  304. pGeneralPage->m_lNotifyHandle = 0; //lNotifyHandle;
  305. //m_lNotifyHandle = lNotifyHandle;
  306. HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pGeneralPage->m_psp);
  307. _ASSERT (hPage);
  308. if ( hPage )
  309. {
  310. bResult = lpfnAddPage (hPage, lParam);
  311. _ASSERT (bResult);
  312. if ( !bResult )
  313. hr = E_FAIL;
  314. }
  315. else
  316. hr = E_FAIL;
  317. }
  318. else
  319. {
  320. hr = E_OUTOFMEMORY;
  321. }
  322. // Add Request page only if subject is not a CA
  323. if ( SUCCEEDED (hr) && !pCertTemplate->SubjectIsCA () )
  324. {
  325. CTemplateV2RequestPropertyPage * pRequestPage =
  326. new CTemplateV2RequestPropertyPage (*pCertTemplate,
  327. pGeneralPage->m_bIsDirty);
  328. if ( pRequestPage )
  329. {
  330. HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pRequestPage->m_psp);
  331. _ASSERT (hPage);
  332. if ( hPage )
  333. {
  334. bResult = lpfnAddPage (hPage, lParam);
  335. _ASSERT (bResult);
  336. if ( !bResult )
  337. hr = E_FAIL;
  338. }
  339. else
  340. hr = E_FAIL;
  341. }
  342. else
  343. {
  344. hr = E_OUTOFMEMORY;
  345. }
  346. }
  347. // Add Subject Name page only if subject is not a CA
  348. if ( SUCCEEDED (hr) && !pCertTemplate->SubjectIsCA () )
  349. {
  350. CTemplateV2SubjectNamePropertyPage * pSubjectNamePage =
  351. new CTemplateV2SubjectNamePropertyPage (*pCertTemplate,
  352. pGeneralPage->m_bIsDirty);
  353. if ( pSubjectNamePage )
  354. {
  355. HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pSubjectNamePage->m_psp);
  356. _ASSERT (hPage);
  357. bResult = lpfnAddPage (hPage, lParam);
  358. _ASSERT (bResult);
  359. }
  360. else
  361. {
  362. hr = E_OUTOFMEMORY;
  363. }
  364. }
  365. // Add Authentication Name page
  366. if ( SUCCEEDED (hr) )
  367. {
  368. CTemplateV2AuthenticationPropertyPage * pAuthenticationPage =
  369. new CTemplateV2AuthenticationPropertyPage (*pCertTemplate,
  370. pGeneralPage->m_bIsDirty);
  371. if ( pAuthenticationPage )
  372. {
  373. HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pAuthenticationPage->m_psp);
  374. _ASSERT (hPage);
  375. if ( hPage )
  376. {
  377. bResult = lpfnAddPage (hPage, lParam);
  378. _ASSERT (bResult);
  379. if ( !bResult )
  380. hr = E_FAIL;
  381. }
  382. else
  383. hr = E_FAIL;
  384. }
  385. else
  386. {
  387. hr = E_OUTOFMEMORY;
  388. }
  389. }
  390. // Add Superceded page
  391. if ( SUCCEEDED (hr) )
  392. {
  393. CTemplateV2SupercedesPropertyPage * pSupercededPage =
  394. new CTemplateV2SupercedesPropertyPage (*pCertTemplate,
  395. pGeneralPage->m_bIsDirty, 0);
  396. if ( pSupercededPage )
  397. {
  398. HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pSupercededPage->m_psp);
  399. _ASSERT (hPage);
  400. if ( hPage )
  401. {
  402. bResult = lpfnAddPage (hPage, lParam);
  403. _ASSERT (bResult);
  404. if ( !bResult )
  405. hr = E_FAIL;
  406. }
  407. else
  408. hr = E_FAIL;
  409. }
  410. else
  411. {
  412. hr = E_OUTOFMEMORY;
  413. }
  414. }
  415. // Add extensions page
  416. if ( SUCCEEDED (hr) )
  417. {
  418. CTemplateExtensionsPropertyPage * pExtensionsPage =
  419. new CTemplateExtensionsPropertyPage (*pCertTemplate,
  420. pGeneralPage->m_bIsDirty);
  421. if ( pExtensionsPage )
  422. {
  423. HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pExtensionsPage->m_psp);
  424. _ASSERT (hPage);
  425. if ( hPage )
  426. {
  427. bResult = lpfnAddPage (hPage, lParam);
  428. _ASSERT (bResult);
  429. if ( !bResult )
  430. hr = E_FAIL;
  431. }
  432. else
  433. hr = E_FAIL;
  434. }
  435. else
  436. {
  437. hr = E_OUTOFMEMORY;
  438. }
  439. }
  440. // Add security page
  441. if ( SUCCEEDED (hr) )
  442. {
  443. // if error, don't display this page
  444. LPSECURITYINFO pCertTemplateSecurity = NULL;
  445. hr = CreateCertTemplateSecurityInfo (pCertTemplate,
  446. &pCertTemplateSecurity);
  447. if ( SUCCEEDED (hr) )
  448. {
  449. // save the pCertTemplateSecurity pointer for later releasing
  450. pGeneralPage->SetAllocedSecurityInfo (pCertTemplateSecurity);
  451. HPROPSHEETPAGE hPage = CreateSecurityPage (pCertTemplateSecurity);
  452. if (hPage == NULL)
  453. {
  454. hr = HRESULT_FROM_WIN32 (GetLastError());
  455. _TRACE (0, L"CreateSecurityPage () failed: 0x%x\n", hr);
  456. }
  457. bResult = lpfnAddPage (hPage, lParam);
  458. _ASSERT (bResult);
  459. }
  460. }
  461. }
  462. _TRACE (-1, L"Leaving CCertTemplateShellExt::AddVersion1CertTemplatePropPages: 0x%x\n", hr);
  463. return hr;
  464. }
  465. STDMETHODIMP CCertTemplateShellExt::ReplacePage
  466. (
  467. IN UINT /*uPageID*/,
  468. IN LPFNADDPROPSHEETPAGE /*lpfnReplaceWith*/,
  469. IN LPARAM /*lParam*/
  470. )
  471. {
  472. return E_FAIL;
  473. }
  474. // IContextMenu methods
  475. STDMETHODIMP CCertTemplateShellExt::GetCommandString
  476. (
  477. UINT_PTR idCmd,
  478. UINT uFlags,
  479. UINT* /*pwReserved*/,
  480. LPSTR pszName,
  481. UINT cchMax
  482. )
  483. {
  484. if((idCmd == m_uiEditId) && (m_uiEditId != 0))
  485. {
  486. if (uFlags == GCS_HELPTEXT)
  487. {
  488. LoadString(AfxGetResourceHandle( ), IDS_EDIT_HINT, (LPTSTR)pszName, cchMax);
  489. return S_OK;
  490. }
  491. }
  492. return E_NOTIMPL;
  493. }
  494. STDMETHODIMP CCertTemplateShellExt::InvokeCommand
  495. (
  496. LPCMINVOKECOMMANDINFO lpici
  497. )
  498. {
  499. if (!HIWORD(lpici->lpVerb))
  500. {
  501. UINT idCmd = LOWORD(lpici->lpVerb);
  502. switch(idCmd)
  503. {
  504. case 0: // Edit
  505. // InvokeCertTypeWizard(m_ahCertTemplates[0],
  506. // lpici->hwnd);
  507. return S_OK;
  508. }
  509. }
  510. return E_NOTIMPL;
  511. }
  512. STDMETHODIMP CCertTemplateShellExt::QueryContextMenu
  513. (
  514. HMENU hmenu,
  515. UINT indexMenu,
  516. UINT idCmdFirst,
  517. UINT /*idCmdLast*/,
  518. UINT /*uFlags*/
  519. )
  520. {
  521. CString szEdit;
  522. MENUITEMINFO mii;
  523. UINT idLastUsedCmd = idCmdFirst;
  524. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  525. // security review 2/21/2002 BryanWal ok
  526. ZeroMemory (&mii, sizeof (mii));
  527. if ( IsCerttypeEditingAllowed () )
  528. {
  529. mii.cbSize = sizeof(mii);
  530. mii.fMask = MIIM_TYPE | MIIM_ID;
  531. mii.fType = MFT_STRING;
  532. mii.wID = idCmdFirst;
  533. szEdit.LoadString(IDS_EDIT);
  534. mii.dwTypeData = (LPTSTR)(LPCTSTR)szEdit;
  535. mii.cch = szEdit.GetLength();
  536. // Add new menu items to the context menu. //
  537. ::InsertMenuItem(hmenu,
  538. indexMenu++,
  539. TRUE,
  540. &mii);
  541. }
  542. return ResultFromScode (MAKE_SCODE (SEVERITY_SUCCESS, 0,
  543. USHORT (idLastUsedCmd + 1)));
  544. }