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.

1615 lines
37 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Windows NT Directory Service Property Pages
  4. //
  5. // Microsoft Windows
  6. // Copyright (C) Microsoft Corporation, 1992 - 1999
  7. //
  8. // File: UserCert.cxx
  9. //
  10. // Contents:
  11. //
  12. // History: 12-November-97 BryanWal created
  13. //
  14. //-----------------------------------------------------------------------------
  15. #include "stdafx.h"
  16. #include "certca.h"
  17. #include "tfcprop.h"
  18. #include "genpage.h"
  19. #include "commdlg.h"
  20. #include "caprop.h"
  21. #define ByteOffset(base, offset) (((LPBYTE)base)+offset)
  22. //+----------------------------------------------------------------------------
  23. //
  24. // Member: CDsCACertPage::CDsCACertPage
  25. //
  26. //-----------------------------------------------------------------------------
  27. CDsCACertPage::CDsCACertPage(LPWSTR wszObjectDN, UINT uIDD) : CAutoDeletePropPage(uIDD),
  28. m_strObjectDN(wszObjectDN),
  29. m_hCertStore (0),
  30. m_hImageList (0),
  31. m_hbmCert (0),
  32. m_nCertImageIndex (0)
  33. {
  34. ::ZeroMemory (&m_selCertStruct, sizeof (m_selCertStruct));
  35. }
  36. //+----------------------------------------------------------------------------
  37. //
  38. // Member: CDsCACertPage::~CDsCACertPage
  39. //
  40. //-----------------------------------------------------------------------------
  41. CDsCACertPage::~CDsCACertPage()
  42. {
  43. // Clean up enumerated store list
  44. for (DWORD dwIndex = 0; dwIndex < m_selCertStruct.cDisplayStores; dwIndex++)
  45. {
  46. ASSERT (m_selCertStruct.rghDisplayStores);
  47. ::CertCloseStore (m_selCertStruct.rghDisplayStores[dwIndex], CERT_CLOSE_STORE_FORCE_FLAG);
  48. }
  49. if ( m_selCertStruct.rghDisplayStores )
  50. delete [] m_selCertStruct.rghDisplayStores;
  51. if ( m_hImageList )
  52. ImageList_Destroy (m_hImageList);
  53. if ( m_hbmCert )
  54. DeleteObject (m_hbmCert);
  55. }
  56. typedef struct _ENUM_ARG {
  57. DWORD dwFlags;
  58. DWORD* pcDisplayStores;
  59. HCERTSTORE ** prghDisplayStores;
  60. } ENUM_ARG, *PENUM_ARG;
  61. static BOOL WINAPI EnumStoresSysCallback(
  62. IN const void* pwszSystemStore,
  63. IN DWORD dwFlags,
  64. IN PCERT_SYSTEM_STORE_INFO pStoreInfo,
  65. IN OPTIONAL void *pvReserved,
  66. IN OPTIONAL void *pvArg
  67. )
  68. {
  69. PENUM_ARG pEnumArg = (PENUM_ARG) pvArg;
  70. void* pvPara = (void*)pwszSystemStore;
  71. HCERTSTORE hNewStore = ::CertOpenStore (CERT_STORE_PROV_SYSTEM,
  72. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL,
  73. CERT_SYSTEM_STORE_CURRENT_USER, pvPara);
  74. if ( !hNewStore )
  75. {
  76. hNewStore = ::CertOpenStore (CERT_STORE_PROV_SYSTEM,
  77. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL,
  78. CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG, pvPara);
  79. }
  80. if ( hNewStore )
  81. {
  82. DWORD dwCnt = *(pEnumArg->pcDisplayStores);
  83. HCERTSTORE* phStores = 0;
  84. phStores = new HCERTSTORE[dwCnt+1];
  85. if ( phStores )
  86. {
  87. DWORD dwIndex = 0;
  88. if ( *(pEnumArg->prghDisplayStores) )
  89. {
  90. for (; dwIndex < dwCnt; dwIndex++)
  91. {
  92. phStores[dwIndex] = (*(pEnumArg->prghDisplayStores))[dwIndex];
  93. }
  94. delete [] (*(pEnumArg->prghDisplayStores));
  95. }
  96. (*(pEnumArg->pcDisplayStores))++;
  97. (*(pEnumArg->prghDisplayStores)) = phStores;
  98. (*(pEnumArg->prghDisplayStores))[dwIndex] = hNewStore;
  99. }
  100. else
  101. {
  102. SetLastError (ERROR_NOT_ENOUGH_MEMORY);
  103. return FALSE;
  104. }
  105. }
  106. return TRUE;
  107. }
  108. //+----------------------------------------------------------------------------
  109. //
  110. // Method: CDsCACertPage::OnInitDialog
  111. //
  112. // Synopsis: Set the initial control values from the corresponding DS
  113. // attributes.
  114. //
  115. //-----------------------------------------------------------------------------
  116. BOOL CDsCACertPage::OnInitDialog(void)
  117. {
  118. HRESULT hResult = S_OK;
  119. CWaitCursor WaitCursor;
  120. const LPWSTR CERT_PROPERTY_EXT = L"?cACertificate?base?objectclass=certificationAuthority";
  121. // Get the object name and open its Published Certificate store
  122. ASSERT (m_strObjectDN);
  123. if ( m_strObjectDN )
  124. {
  125. LPWSTR pvPara = new WCHAR[wcslen (m_strObjectDN) +
  126. wcslen (CERT_PROPERTY_EXT) + 1];
  127. if ( pvPara )
  128. {
  129. wcscpy (pvPara, m_strObjectDN);
  130. wcscat (pvPara, CERT_PROPERTY_EXT);
  131. m_hCertStore = ::CertOpenStore ("LDAP",
  132. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL,
  133. 0,
  134. (void*) pvPara);
  135. if ( !m_hCertStore )
  136. {
  137. MessageBox (IDS_USER_TITLE_PUBLISHED_CERTS, IDS_CANT_OPEN_STORE,
  138. MB_ICONINFORMATION | MB_OK);
  139. hResult = E_FAIL;
  140. ::EnableWindow (GetDlgItem (m_hWnd, IDC_ADD_FROM_STORE), FALSE);
  141. ::EnableWindow (GetDlgItem (m_hWnd, IDC_ADD_FROM_FILE), FALSE);
  142. }
  143. }
  144. }
  145. // Set up result list view
  146. COLORREF crMask = RGB (255, 0, 255);
  147. m_hImageList = ImageList_Create (16, 16, ILC_MASK, 10, 10);
  148. ASSERT (m_hImageList);
  149. if ( m_hImageList )
  150. {
  151. m_hbmCert = ::LoadBitmap (g_hInstance, MAKEINTRESOURCE (IDB_CERTIFICATE));
  152. ASSERT (m_hbmCert);
  153. if ( m_hbmCert )
  154. {
  155. m_nCertImageIndex = ImageList_AddMasked (m_hImageList, m_hbmCert,
  156. crMask);
  157. ASSERT (m_nCertImageIndex != -1);
  158. if ( m_nCertImageIndex != -1 )
  159. {
  160. ListView_SetImageList (::GetDlgItem (m_hWnd, IDC_CERT_LIST),
  161. m_hImageList, LVSIL_SMALL);
  162. }
  163. }
  164. }
  165. hResult = AddListViewColumns ();
  166. if ( SUCCEEDED (hResult) && m_hCertStore )
  167. hResult = PopulateListView ();
  168. EnableControls ();
  169. // Enumerate User's certificate stores for use in selecting certificates
  170. // from stores.
  171. ENUM_ARG EnumArg;
  172. m_selCertStruct.dwSize = sizeof (CRYPTUI_SELECTCERTIFICATE_STRUCT);
  173. m_selCertStruct.hwndParent = m_hWnd;
  174. EnumArg.pcDisplayStores = &m_selCertStruct.cDisplayStores;
  175. EnumArg.prghDisplayStores = &m_selCertStruct.rghDisplayStores;
  176. ::CertEnumSystemStore (CERT_SYSTEM_STORE_CURRENT_USER, 0, &EnumArg,
  177. EnumStoresSysCallback);
  178. return (hResult == S_OK);
  179. }
  180. //+----------------------------------------------------------------------------
  181. //
  182. // Method: CDsCACertPage::OnApply
  183. //
  184. // Synopsis: Handles the Apply notification.
  185. //
  186. //-----------------------------------------------------------------------------
  187. BOOL CDsCACertPage::OnApply(void)
  188. {
  189. HRESULT hResult = S_OK;
  190. CWaitCursor WaitCursor;
  191. if ( m_hCertStore )
  192. {
  193. BOOL bResult = ::CertControlStore (m_hCertStore, 0,
  194. CERT_STORE_CTRL_COMMIT, NULL);
  195. if ( !bResult )
  196. {
  197. DWORD dwErr = GetLastError ();
  198. ASSERT (dwErr == ERROR_NOT_SUPPORTED);
  199. if ( dwErr != ERROR_NOT_SUPPORTED )
  200. {
  201. MessageBox (IDS_USER_TITLE_PUBLISHED_CERTS, IDS_CANT_SAVE_STORE,
  202. MB_ICONINFORMATION | MB_OK);
  203. hResult = E_FAIL;
  204. }
  205. }
  206. }
  207. if(SUCCEEDED(hResult))
  208. {
  209. return CAutoDeletePropPage::OnApply();
  210. }
  211. else
  212. {
  213. return FALSE;
  214. }
  215. }
  216. //+----------------------------------------------------------------------------
  217. //
  218. // Method: CDsCACertPage::OnCommand
  219. //
  220. // Synopsis: Handle control notifications.
  221. //
  222. //-----------------------------------------------------------------------------
  223. BOOL CDsCACertPage::OnCommand(WPARAM wParam, LPARAM lParam)
  224. {
  225. switch (HIWORD(wParam))
  226. {
  227. case BN_CLICKED:
  228. switch (LOWORD(wParam))
  229. {
  230. case IDC_VIEW_CERT:
  231. return S_OK == OnClickedViewCert ();
  232. break;
  233. case IDC_ADD_FROM_STORE:
  234. return S_OK == OnClickedAddFromStore ();
  235. break;
  236. case IDC_ADD_FROM_FILE:
  237. return S_OK == OnClickedAddFromFile ();
  238. break;
  239. case IDC_REMOVE:
  240. return S_OK == OnClickedRemove ();
  241. break;
  242. case IDC_COPY_TO_FILE:
  243. return S_OK == OnClickedCopyToFile ();
  244. break;
  245. default:
  246. _ASSERT (0);
  247. return FALSE;
  248. break;
  249. }
  250. break;
  251. default:
  252. break;
  253. }
  254. return TRUE;
  255. }
  256. //+----------------------------------------------------------------------------
  257. //
  258. // Method: CDsCACertPage::OnNotify
  259. //
  260. // Synopsis:
  261. //
  262. //-----------------------------------------------------------------------------
  263. BOOL
  264. CDsCACertPage::OnNotify(UINT idCtrl, NMHDR* pNMHdr)
  265. {
  266. if ( !pNMHdr )
  267. return FALSE;
  268. switch (pNMHdr->code)
  269. {
  270. case NM_DBLCLK:
  271. if ( idCtrl == IDC_CERT_LIST )
  272. return S_OK == OnDblClkCertList (pNMHdr);
  273. break;
  274. case LVN_COLUMNCLICK:
  275. if ( idCtrl == IDC_CERT_LIST )
  276. return S_OK == OnColumnClickCertList (pNMHdr);
  277. break;
  278. case LVN_DELETEALLITEMS:
  279. if ( idCtrl == IDC_CERT_LIST )
  280. return FALSE; // Do not suppress LVN_DELETEITEM messages
  281. break;
  282. case LVN_DELETEITEM:
  283. if ( idCtrl == IDC_CERT_LIST )
  284. return S_OK == OnDeleteItemCertList ((LPNMLISTVIEW)pNMHdr);
  285. break;
  286. case LVN_ODSTATECHANGED:
  287. OnNotifyStateChanged ((LPNMLVODSTATECHANGE)pNMHdr);
  288. return TRUE;
  289. case LVN_ITEMCHANGED:
  290. OnNotifyItemChanged ((LPNMLISTVIEW)pNMHdr);
  291. return TRUE;
  292. default:
  293. return FALSE;
  294. break;
  295. }
  296. return TRUE;
  297. }
  298. //+----------------------------------------------------------------------------
  299. //
  300. // Method: CDsCACertPage::OnDestroy
  301. //
  302. // Synopsis: Exit cleanup
  303. //
  304. //-----------------------------------------------------------------------------
  305. void CDsCACertPage::OnDestroy(void)
  306. {
  307. ListView_DeleteAllItems (::GetDlgItem (m_hWnd, IDC_CERT_LIST));
  308. if ( m_hCertStore )
  309. {
  310. // Back out of uncommitted changes before closing the store.
  311. BOOL bResult = ::CertControlStore (m_hCertStore,
  312. CERT_STORE_CTRL_COMMIT_CLEAR_FLAG,
  313. CERT_STORE_CTRL_COMMIT, NULL);
  314. if ( !bResult )
  315. {
  316. DWORD dwErr = GetLastError ();
  317. ASSERT (dwErr != ERROR_NOT_SUPPORTED && dwErr != ERROR_CALL_NOT_IMPLEMENTED);
  318. }
  319. ::CertCloseStore (m_hCertStore, 0);
  320. m_hCertStore = 0;
  321. }
  322. // If an application processes this message, it should return zero.
  323. CAutoDeletePropPage::OnDestroy();
  324. }
  325. HRESULT CDsCACertPage::AddListViewColumns()
  326. {
  327. // Add list view columns
  328. LVCOLUMN lvCol;
  329. ::ZeroMemory (&lvCol, sizeof (lvCol));
  330. CString strTemp;
  331. VERIFY(strTemp.LoadString (IDS_CERTCOL_ISSUED_TO) );
  332. lvCol.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  333. lvCol.fmt = LVCFMT_LEFT;
  334. lvCol.cx = 90;
  335. lvCol.pszText = const_cast<LPWSTR>((LPCWSTR)strTemp);
  336. lvCol.iSubItem = CERTCOL_ISSUED_TO;
  337. HWND hWndList = ::GetDlgItem (m_hWnd, IDC_CERT_LIST);
  338. int nIndex = ListView_InsertColumn (hWndList, CERTCOL_ISSUED_TO, &lvCol);
  339. _ASSERT (nIndex != -1);
  340. if ( nIndex == -1 )
  341. return E_UNEXPECTED;
  342. VERIFY(strTemp.LoadString (IDS_CERTCOL_ISSUED_BY) );
  343. lvCol.cx = 90;
  344. lvCol.pszText = const_cast<LPWSTR>((LPCWSTR)strTemp);
  345. lvCol.iSubItem = CERTCOL_ISSUED_BY;
  346. nIndex = ListView_InsertColumn (hWndList, IDS_CERTCOL_ISSUED_BY, &lvCol);
  347. _ASSERT (nIndex != -1);
  348. if ( nIndex == -1 )
  349. return E_UNEXPECTED;
  350. VERIFY(strTemp.LoadString (IDS_CERTCOL_PURPOSES) );
  351. lvCol.cx = 125;
  352. lvCol.pszText = const_cast<LPWSTR>((LPCWSTR)strTemp);
  353. lvCol.iSubItem = CERTCOL_PURPOSES;
  354. nIndex = ListView_InsertColumn (hWndList, IDS_CERTCOL_PURPOSES, &lvCol);
  355. _ASSERT (nIndex != -1);
  356. if ( nIndex == -1 )
  357. return E_UNEXPECTED;
  358. VERIFY(strTemp.LoadString (IDS_CERTCOL_EXP_DATE) );
  359. lvCol.cx = 125;
  360. lvCol.pszText = const_cast<LPWSTR>((LPCWSTR)strTemp);
  361. lvCol.iSubItem = CERTCOL_EXP_DATE;
  362. nIndex = ListView_InsertColumn (hWndList, IDS_CERTCOL_EXP_DATE, &lvCol);
  363. _ASSERT (nIndex != -1);
  364. if ( nIndex == -1 )
  365. return E_UNEXPECTED;
  366. return S_OK;
  367. }
  368. HRESULT CDsCACertPage::OnClickedViewCert()
  369. {
  370. HRESULT hResult = S_OK;
  371. int nSelItem = -1;
  372. CCertificate* pCert = GetSelectedCertificate (nSelItem);
  373. if ( pCert )
  374. {
  375. CRYPTUI_VIEWCERTIFICATE_STRUCT vcs;
  376. HCERTSTORE hCertStore = ::CertDuplicateStore (pCert->GetCertStore ());
  377. ::ZeroMemory (&vcs, sizeof (vcs));
  378. vcs.dwSize = sizeof (vcs);
  379. vcs.hwndParent = m_hWnd;
  380. vcs.dwFlags = 0;
  381. vcs.cStores = 1;
  382. vcs.rghStores = &hCertStore;
  383. vcs.pCertContext = pCert->GetCertContext ();
  384. BOOL fPropertiesChanged = FALSE;
  385. BOOL bResult = ::CryptUIDlgViewCertificate (&vcs, &fPropertiesChanged);
  386. if ( bResult )
  387. {
  388. if ( fPropertiesChanged )
  389. {
  390. pCert->Refresh ();
  391. RefreshItemInList (pCert, nSelItem);
  392. }
  393. }
  394. ::CertCloseStore (hCertStore, 0);
  395. }
  396. ::SetFocus (::GetDlgItem (m_hWnd, IDC_CERT_LIST));
  397. return hResult;
  398. }
  399. HRESULT CDsCACertPage::OnClickedAddFromStore()
  400. {
  401. HRESULT hResult = S_OK;
  402. PCCERT_CONTEXT pCertContext = ::CryptUIDlgSelectCertificate (&m_selCertStruct);
  403. if ( pCertContext )
  404. {
  405. hResult = AddCertToStore (pCertContext);
  406. SetModified();
  407. }
  408. ::SetFocus (::GetDlgItem (m_hWnd, IDC_CERT_LIST));
  409. return hResult;
  410. }
  411. HRESULT CDsCACertPage::OnClickedAddFromFile()
  412. {
  413. HRESULT hResult = S_OK;
  414. HWND hwndList = ::GetDlgItem (m_hWnd, IDC_CERT_LIST);
  415. CString strFilter;
  416. CString strDlgTitle;
  417. VERIFY(strFilter.LoadString (IDS_CERT_SAVE_FILTER));
  418. VERIFY(strDlgTitle.LoadString (IDS_OPEN_FILE_DLG_TITLE));
  419. {
  420. LPWSTR pszDefExt = _T("cer");
  421. OPENFILENAME ofn;
  422. WCHAR szFile[MAX_PATH];
  423. ::ZeroMemory (szFile, MAX_PATH * sizeof (WCHAR));
  424. ::ZeroMemory (&ofn, sizeof (ofn));
  425. ofn.lStructSize = sizeof (OPENFILENAME);
  426. ofn.hwndOwner = m_hWnd;
  427. ofn.lpstrFilter = const_cast<LPWSTR>((LPCWSTR)strFilter);
  428. ofn.lpstrFile = szFile;
  429. ofn.nMaxFile = MAX_PATH;
  430. ofn.lpstrTitle = const_cast<LPWSTR>((LPCWSTR)strDlgTitle);
  431. ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
  432. ofn.lpstrDefExt = pszDefExt;
  433. BOOL bResult = GetOpenFileName (&ofn);
  434. if ( bResult )
  435. {
  436. DWORD dwMsgAndCertEncodingType = 0;
  437. DWORD dwContentType = 0;
  438. DWORD dwFormatType = 0;
  439. PCERT_CONTEXT pCertContext = 0;
  440. bResult = ::CryptQueryObject (
  441. CERT_QUERY_OBJECT_FILE,
  442. (void *) ofn.lpstrFile,
  443. CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT |
  444. CERT_QUERY_CONTENT_FLAG_CERT |
  445. CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED |
  446. CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED |
  447. CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
  448. CERT_QUERY_FORMAT_FLAG_ALL,
  449. 0,
  450. &dwMsgAndCertEncodingType,
  451. &dwContentType,
  452. &dwFormatType,
  453. NULL,
  454. NULL,
  455. (const void **) &pCertContext);
  456. if ( bResult && pCertContext )
  457. {
  458. hResult = AddCertToStore (pCertContext);
  459. // ::CertFreeCertificateContext (pCertContext);
  460. SetModified();
  461. }
  462. else
  463. {
  464. MessageBox (IDS_UNKNOWN_CERT_FILE_TYPE, IDS_OPEN_FILE_DLG_TITLE, MB_ICONWARNING | MB_OK);
  465. }
  466. }
  467. }
  468. ::SetFocus (hwndList);
  469. return hResult;
  470. }
  471. HRESULT CDsCACertPage::OnClickedRemove()
  472. {
  473. HRESULT hResult = S_OK;
  474. int nSelItem = -1;
  475. HWND hwndList = ::GetDlgItem (m_hWnd, IDC_CERT_LIST);
  476. bool bConfirmationRequested = false;
  477. int iResult = 0;
  478. int nSelCnt = ListView_GetSelectedCount (hwndList);
  479. if ( nSelCnt < 1 )
  480. return E_FAIL;
  481. while (1)
  482. {
  483. CCertificate* pCert = GetSelectedCertificate (nSelItem);
  484. if ( pCert )
  485. {
  486. if ( !bConfirmationRequested )
  487. {
  488. CString strCaption;
  489. CString strMsg;
  490. int textId = 0;
  491. iResult = MessageBox (( 1 == nSelCnt )?IDS_CONFIRM_DELETE_CERT:IDS_CONFIRM_DELETE_CERTS, IDS_REMOVE_CERT,
  492. MB_YESNO);
  493. bConfirmationRequested = true;
  494. if ( IDYES != iResult )
  495. break;
  496. }
  497. BOOL bResult = pCert->DeleteFromStore ();
  498. ASSERT (bResult);
  499. if ( bResult )
  500. {
  501. bResult = ListView_DeleteItem (
  502. hwndList,
  503. nSelItem);
  504. ASSERT (bResult);
  505. if ( bResult )
  506. SetModified();
  507. else
  508. hResult = E_FAIL;
  509. }
  510. else
  511. {
  512. DWORD dwErr = GetLastError ();
  513. DisplaySystemError (dwErr, IDS_REMOVE_CERT);
  514. hResult = HRESULT_FROM_WIN32 (dwErr);
  515. break;
  516. }
  517. }
  518. else
  519. break;
  520. }
  521. ::SetFocus (hwndList);
  522. EnableControls ();
  523. return hResult;
  524. }
  525. HRESULT CDsCACertPage::OnClickedCopyToFile()
  526. {
  527. HRESULT hResult = S_OK;
  528. CString strFilter;
  529. CString strDlgTitle;
  530. VERIFY(strFilter.LoadString (IDS_CERT_SAVE_FILTER));
  531. VERIFY(strDlgTitle.LoadString (IDS_SAVE_FILE_DLG_TITLE));
  532. {
  533. LPWSTR pszDefExt = _T("cer");
  534. OPENFILENAME ofn;
  535. WCHAR szFile[MAX_PATH];
  536. ::ZeroMemory (szFile, MAX_PATH * sizeof (WCHAR));
  537. ::ZeroMemory (&ofn, sizeof (ofn));
  538. ofn.lStructSize = sizeof (OPENFILENAME);
  539. ofn.hwndOwner = m_hWnd;
  540. ofn.lpstrFilter = const_cast<LPWSTR>((LPCWSTR)strFilter);
  541. ofn.lpstrFile = szFile;
  542. ofn.nMaxFile = MAX_PATH;
  543. ofn.lpstrTitle = const_cast<LPWSTR>((LPCWSTR)strDlgTitle);
  544. ofn.Flags = OFN_PATHMUSTEXIST | OFN_CREATEPROMPT | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY;
  545. ofn.lpstrDefExt = pszDefExt;
  546. BOOL bResult = ::GetSaveFileName (&ofn);
  547. if ( bResult )
  548. {
  549. if ( wcsstr (_wcsupr (ofn.lpstrFile), _T(".CER")) )
  550. {
  551. HANDLE hFile = ::CreateFile (ofn.lpstrFile, // pointer to name of the file
  552. GENERIC_READ | GENERIC_WRITE, // access (read-write) mode
  553. 0, // share mode
  554. NULL, // pointer to security attributes
  555. CREATE_ALWAYS, // how to create
  556. FILE_ATTRIBUTE_NORMAL, // file attributes
  557. NULL); // handle to file with attributes to copy
  558. ASSERT (hFile != INVALID_HANDLE_VALUE);
  559. if ( hFile != INVALID_HANDLE_VALUE )
  560. {
  561. int iSelItem = -1;
  562. CCertificate* pCert = GetSelectedCertificate (iSelItem);
  563. ASSERT (pCert);
  564. if ( pCert )
  565. {
  566. // To cer file -> put out encoded blob
  567. // pbEncodedCert
  568. hResult = pCert->WriteToFile (hFile);
  569. if ( !SUCCEEDED (hResult) )
  570. DisplaySystemError (GetLastError (), IDS_COPY_TO_FILE);
  571. }
  572. if ( !CloseHandle (hFile) )
  573. {
  574. ASSERT (0);
  575. DisplaySystemError (GetLastError (), IDS_COPY_TO_FILE);
  576. }
  577. }
  578. else
  579. DisplaySystemError (GetLastError (), IDS_COPY_TO_FILE);
  580. }
  581. else
  582. {
  583. void* pvSaveToPara = (void*) ofn.lpstrFile;
  584. HCERTSTORE hCertStore = ::CertOpenStore (CERT_STORE_PROV_MEMORY,
  585. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL,
  586. CERT_FILE_STORE_COMMIT_ENABLE_FLAG, 0);
  587. if ( hCertStore )
  588. {
  589. int iSelItem = -1;
  590. CCertificate* pCert = GetSelectedCertificate (iSelItem);
  591. ASSERT (pCert);
  592. if ( pCert )
  593. {
  594. bResult = ::CertAddCertificateContextToStore (
  595. hCertStore,
  596. ::CertDuplicateCertificateContext (pCert->GetCertContext ()),
  597. CERT_STORE_ADD_ALWAYS,
  598. NULL);
  599. ASSERT (bResult);
  600. if ( bResult )
  601. {
  602. bResult = ::CertSaveStore (
  603. hCertStore,
  604. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  605. CERT_STORE_SAVE_AS_PKCS7,
  606. CERT_STORE_SAVE_TO_FILENAME,
  607. pvSaveToPara,
  608. 0);
  609. ASSERT (bResult);
  610. if ( !bResult )
  611. DisplaySystemError (GetLastError (), IDS_COPY_TO_FILE);
  612. }
  613. else
  614. DisplaySystemError (GetLastError (), IDS_COPY_TO_FILE);
  615. }
  616. ::CertCloseStore (hCertStore, 0);
  617. }
  618. }
  619. }
  620. }
  621. ::SetFocus (::GetDlgItem (m_hWnd, IDC_CERT_LIST));
  622. return hResult;
  623. }
  624. HRESULT CDsCACertPage::OnDblClkCertList(LPNMHDR pNMHdr)
  625. {
  626. HRESULT hResult = S_OK;
  627. hResult = OnClickedViewCert ();
  628. return hResult;
  629. }
  630. HRESULT CDsCACertPage::OnColumnClickCertList(LPNMHDR pNMHdr)
  631. {
  632. HRESULT hResult = S_OK;
  633. return hResult;
  634. }
  635. HRESULT CDsCACertPage::OnDeleteItemCertList (LPNMLISTVIEW pNMListView)
  636. {
  637. HRESULT hResult = S_OK;
  638. ASSERT (pNMListView);
  639. if ( pNMListView )
  640. {
  641. LVITEM lvItem;
  642. ::ZeroMemory (&lvItem, sizeof (lvItem));
  643. lvItem.mask = LVIF_PARAM;
  644. lvItem.iItem = pNMListView->iItem;
  645. if ( ListView_GetItem (::GetDlgItem (m_hWnd, IDC_CERT_LIST), &lvItem) )
  646. {
  647. CCertificate* pCert = (CCertificate*) lvItem.lParam;
  648. ASSERT (pCert);
  649. if ( pCert )
  650. {
  651. delete pCert;
  652. }
  653. else
  654. hResult = E_UNEXPECTED;
  655. }
  656. else
  657. hResult = E_UNEXPECTED;
  658. }
  659. else
  660. hResult = E_POINTER;
  661. return hResult;
  662. }
  663. HRESULT CDsCACertPage::PopulateListView()
  664. {
  665. CWaitCursor cursor;
  666. PCCERT_CONTEXT pCertContext = 0;
  667. HRESULT hResult = S_OK;
  668. CCertificate* pCert = 0;
  669. // Iterate through the list of certificates in the system store,
  670. // allocate new certificates with the CERT_CONTEXT returned,
  671. // and store them in the certificate list.
  672. int nIndex = 0;
  673. int nItem = -1;
  674. while ( SUCCEEDED (hResult) )
  675. {
  676. pCertContext = ::CertEnumCertificatesInStore (m_hCertStore, pCertContext);
  677. if ( !pCertContext )
  678. break;
  679. pCert = new CCertificate (pCertContext, m_hCertStore);
  680. if ( pCert )
  681. {
  682. nItem++;
  683. hResult = InsertCertInList (pCert, nItem);
  684. if ( !SUCCEEDED (hResult) )
  685. delete pCert;
  686. }
  687. else
  688. {
  689. hResult = E_OUTOFMEMORY;
  690. }
  691. }
  692. return hResult;
  693. }
  694. // Get the first selected certificate, starting at the end of the list
  695. // and previous to the passed in nSelItem. Pass in a -1 to search
  696. // the entire list
  697. CCertificate* CDsCACertPage::GetSelectedCertificate (int& nSelItem)
  698. {
  699. HWND hWndList = ::GetDlgItem (m_hWnd, IDC_CERT_LIST);
  700. int nCnt = ListView_GetItemCount (hWndList);
  701. CCertificate* pCert = 0;
  702. PCCERT_CONTEXT pCertContext = 0;
  703. int nSelCnt = ListView_GetSelectedCount (hWndList);
  704. LVITEM lvItem;
  705. ::ZeroMemory (&lvItem, sizeof (lvItem));
  706. lvItem.mask = LVIF_PARAM;
  707. if ( nSelCnt >= 1 )
  708. {
  709. if ( -1 != nSelItem )
  710. nCnt = nSelItem;
  711. while (--nCnt >= 0)
  712. {
  713. UINT flag = ListView_GetItemState (hWndList,
  714. nCnt, LVIS_SELECTED);
  715. if ( flag & LVNI_SELECTED )
  716. {
  717. lvItem.iItem = nCnt;
  718. if ( ListView_GetItem (::GetDlgItem (m_hWnd,
  719. IDC_CERT_LIST),
  720. &lvItem) )
  721. {
  722. pCert = (CCertificate*) lvItem.lParam;
  723. ASSERT (pCert);
  724. if ( pCert )
  725. {
  726. nSelItem = nCnt;
  727. }
  728. }
  729. else
  730. {
  731. ASSERT (0);
  732. }
  733. break;
  734. }
  735. }
  736. }
  737. return pCert;
  738. }
  739. void CDsCACertPage::RefreshItemInList (CCertificate * pCert, int nItem)
  740. {
  741. HWND hWndList = ::GetDlgItem (m_hWnd, IDC_CERT_LIST);
  742. BOOL bResult = (BOOL)::SendMessage (hWndList, LVM_DELETEITEM, nItem, 0);
  743. ASSERT (bResult);
  744. HRESULT hResult = InsertCertInList (pCert, nItem);
  745. if ( SUCCEEDED (hResult) )
  746. {
  747. bResult = ListView_Update (hWndList, nItem);
  748. ASSERT (bResult);
  749. }
  750. else
  751. delete pCert;
  752. }
  753. HRESULT CDsCACertPage::InsertCertInList(CCertificate * pCert, int nItem)
  754. {
  755. HRESULT hResult = S_OK;
  756. HWND hWndList = ::GetDlgItem (m_hWnd, IDC_CERT_LIST);
  757. LVITEM lvItem;
  758. PWSTR pszText = 0;
  759. BOOL bResult = FALSE;
  760. int nIndex = 0;
  761. // Insert icon and subject name
  762. ::ZeroMemory (&lvItem, sizeof (lvItem));
  763. lvItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
  764. lvItem.iItem = nItem;
  765. lvItem.iSubItem = CERTCOL_ISSUED_TO;
  766. lvItem.iImage = m_nCertImageIndex;
  767. lvItem.lParam = (LPARAM) pCert;
  768. hResult = pCert->GetSubjectName (&pszText);
  769. if ( SUCCEEDED (hResult) )
  770. lvItem.pszText = pszText;
  771. else
  772. {
  773. hResult = pCert->GetAlternateSubjectName (&pszText);
  774. if ( SUCCEEDED (hResult) )
  775. lvItem.pszText = pszText;
  776. }
  777. if ( SUCCEEDED (hResult) )
  778. {
  779. nIndex = ListView_InsertItem (hWndList, &lvItem);
  780. _ASSERT (nIndex != -1);
  781. if ( nIndex == -1 )
  782. {
  783. delete pCert;
  784. hResult = E_UNEXPECTED;
  785. }
  786. }
  787. else
  788. {
  789. delete pCert;
  790. hResult = E_UNEXPECTED;
  791. }
  792. if ( SUCCEEDED (hResult) )
  793. {
  794. // Insert issuer name
  795. ::ZeroMemory (&lvItem, sizeof (lvItem));
  796. HRESULT hResult1 = pCert->GetIssuerName (&pszText);
  797. if ( !SUCCEEDED (hResult1) )
  798. {
  799. hResult1 = pCert->GetAlternateIssuerName (&pszText);
  800. }
  801. if ( SUCCEEDED (hResult1) )
  802. {
  803. ListView_SetItemText (hWndList, nIndex, CERTCOL_ISSUED_BY, pszText);
  804. }
  805. }
  806. // Insert intended purpose
  807. if ( SUCCEEDED (hResult) )
  808. {
  809. HRESULT hResult1 = pCert->GetEnhancedKeyUsage (&pszText);
  810. if ( SUCCEEDED (hResult1) && pszText )
  811. {
  812. ListView_SetItemText (hWndList, nIndex, CERTCOL_PURPOSES, pszText);
  813. }
  814. }
  815. // Insert expiration date
  816. if ( SUCCEEDED (hResult) )
  817. {
  818. HRESULT hResult1 = pCert->GetValidNotAfter (&pszText);
  819. if ( SUCCEEDED (hResult1) )
  820. {
  821. ListView_SetItemText (hWndList, nIndex, CERTCOL_EXP_DATE, pszText);
  822. }
  823. }
  824. if ( pszText )
  825. delete [] pszText;
  826. return hResult;
  827. }
  828. void CDsCACertPage::DisplaySystemError(DWORD dwErr, int iCaptionText)
  829. {
  830. LPVOID lpMsgBuf = 0;
  831. if (0 != FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  832. NULL,
  833. dwErr,
  834. MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  835. (LPTSTR) &lpMsgBuf, 0, NULL))
  836. {
  837. // Display the string.
  838. CString strCaption;
  839. VERIFY(strCaption.LoadString(iCaptionText));
  840. ::MessageBox (m_hWnd, (LPWSTR) lpMsgBuf, strCaption, MB_ICONWARNING | MB_OK);
  841. // Free the buffer.
  842. LocalFree (lpMsgBuf);
  843. }
  844. }
  845. void CDsCACertPage::EnableControls()
  846. {
  847. HWND hWndDlg = m_hWnd;
  848. HWND hWndList = ::GetDlgItem (hWndDlg, IDC_CERT_LIST);
  849. int nSelCnt = ListView_GetSelectedCount (hWndList);
  850. int nSelItem = -1;
  851. bool bCanDelete = true;
  852. while (bCanDelete)
  853. {
  854. CCertificate* pCert = GetSelectedCertificate (nSelItem);
  855. if ( pCert )
  856. bCanDelete = pCert->CanDelete ();
  857. else
  858. break;
  859. }
  860. ::EnableWindow (::GetDlgItem (hWndDlg, IDC_REMOVE), bCanDelete && nSelCnt > 0);
  861. ::EnableWindow (::GetDlgItem (hWndDlg, IDC_COPY_TO_FILE), nSelCnt == 1);
  862. ::EnableWindow (::GetDlgItem (hWndDlg, IDC_VIEW_CERT), nSelCnt == 1);
  863. }
  864. void CDsCACertPage::OnNotifyStateChanged(LPNMLVODSTATECHANGE pStateChange)
  865. {
  866. EnableControls ();
  867. }
  868. void CDsCACertPage::OnNotifyItemChanged (LPNMLISTVIEW pnmv)
  869. {
  870. EnableControls ();
  871. }
  872. HRESULT CDsCACertPage::AddCertToStore(PCCERT_CONTEXT pCertContext)
  873. {
  874. HRESULT hResult = S_OK;
  875. BOOL bResult = ::CertAddCertificateContextToStore (
  876. m_hCertStore,
  877. pCertContext,
  878. CERT_STORE_ADD_NEW,
  879. 0);
  880. if ( bResult )
  881. {
  882. CCertificate* pCert = new CCertificate (pCertContext, m_hCertStore);
  883. if ( pCert )
  884. {
  885. hResult = InsertCertInList (pCert,
  886. ListView_GetItemCount (
  887. ::GetDlgItem (m_hWnd, IDC_CERT_LIST)));
  888. if ( !SUCCEEDED (hResult) )
  889. delete pCert;
  890. }
  891. else
  892. {
  893. hResult = E_OUTOFMEMORY;
  894. }
  895. }
  896. else
  897. {
  898. DWORD dwErr = GetLastError ();
  899. if ( dwErr == CRYPT_E_EXISTS )
  900. {
  901. MessageBox (IDS_DUPLICATE_CERT, IDS_ADD_FROM_STORE,
  902. MB_ICONINFORMATION | MB_OK);
  903. hResult = E_FAIL;
  904. }
  905. else
  906. {
  907. DisplaySystemError (dwErr, IDS_ADD_FROM_STORE);
  908. hResult = HRESULT_FROM_WIN32 (dwErr);
  909. }
  910. }
  911. return hResult;
  912. }
  913. int CDsCACertPage::MessageBox(int caption, int text, UINT flags)
  914. {
  915. int iReturn = -1;
  916. CString strCaption;
  917. CString strMsg;
  918. VERIFY(strCaption.LoadString (caption));
  919. VERIFY(strMsg.LoadString (text));
  920. iReturn = ::MessageBox (m_hWnd, strMsg, strCaption, flags);
  921. return iReturn;
  922. }
  923. /*----------------------------------------------------------------------
  924. IShellExtInit Implementation.
  925. ------------------------------------------------------------------------*/
  926. STDMETHODIMP CCAShellExt::Initialize
  927. (
  928. IN LPCITEMIDLIST pidlFolder, // Points to an ITEMIDLIST structure
  929. IN LPDATAOBJECT pDataObj, // Points to an IDataObject interface
  930. IN HKEY hkeyProgID // Registry key for the file object or folder type
  931. )
  932. {
  933. HRESULT hr = 0;
  934. FORMATETC fmte = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  935. STGMEDIUM medium = { TYMED_NULL };
  936. CString csClass, csPath;
  937. USES_CONVERSION;
  938. LPWSTR wszTypeDN = NULL, wszType = NULL;
  939. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  940. // if we have a pDataObj then try and get the first name from it
  941. if ( pDataObj )
  942. {
  943. // get path and class
  944. fmte.cfFormat = (CLIPFORMAT) RegisterClipboardFormat(CFSTR_DSOBJECTNAMES);
  945. if ( SUCCEEDED(pDataObj->GetData(&fmte, &medium)) )
  946. {
  947. // Note: We take ownership of the HGLOBAL, so it needs to be freed with a GlobalFree.
  948. m_Names = (LPDSOBJECTNAMES)medium.hGlobal;
  949. }
  950. }
  951. hr = S_OK; // success
  952. return hr;
  953. }
  954. STDMETHODIMP CCAShellExt::AddPages
  955. (
  956. IN LPFNADDPROPSHEETPAGE lpfnAddPage,
  957. IN LPARAM lParam
  958. )
  959. {
  960. PropertyPage* pBasePage;
  961. LPWSTR wszClassType = NULL;
  962. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  963. if(m_Names->cItems != 1)
  964. {
  965. // Don't add the properties page if we have no or many objects selected
  966. return S_OK;
  967. }
  968. if(m_Names->aObjects[0].offsetName == 0)
  969. {
  970. return E_UNEXPECTED;
  971. }
  972. if(m_Names->aObjects[0].offsetClass)
  973. {
  974. wszClassType = (LPWSTR)ByteOffset(m_Names, m_Names->aObjects[0].offsetClass);
  975. }
  976. if(wszClassType == NULL)
  977. {
  978. return S_OK;
  979. }
  980. if(_wcsicmp(wszClassType, L"certificationAuthority") == 0)
  981. {
  982. CDsCACertPage* pControlPage = new CDsCACertPage((LPWSTR)ByteOffset(m_Names, m_Names->aObjects[0].offsetName));
  983. if(pControlPage)
  984. {
  985. pBasePage = pControlPage;
  986. HPROPSHEETPAGE hPage = CreatePropertySheetPage(&pBasePage->m_psp);
  987. if (hPage == NULL)
  988. {
  989. delete (pControlPage);
  990. return E_UNEXPECTED;
  991. }
  992. lpfnAddPage(hPage, lParam);
  993. }
  994. }
  995. return S_OK;
  996. }
  997. STDMETHODIMP CCAShellExt::ReplacePage
  998. (
  999. IN UINT uPageID,
  1000. IN LPFNADDPROPSHEETPAGE lpfnReplaceWith,
  1001. IN LPARAM lParam
  1002. )
  1003. {
  1004. return E_FAIL;
  1005. }
  1006. // IContextMenu methods
  1007. STDMETHODIMP CCAShellExt::GetCommandString
  1008. (
  1009. UINT_PTR idCmd,
  1010. UINT uFlags,
  1011. UINT *pwReserved,
  1012. LPSTR pszName,
  1013. UINT cchMax
  1014. )
  1015. {
  1016. return E_NOTIMPL;
  1017. }
  1018. STDMETHODIMP CCAShellExt::InvokeCommand
  1019. (
  1020. LPCMINVOKECOMMANDINFO lpici
  1021. )
  1022. {
  1023. HRESULT hr = S_OK;
  1024. LPWSTR wszClassType = NULL;
  1025. if(m_Names->cItems != 1)
  1026. {
  1027. // Don't add the properties page if we have no or many objects selected
  1028. return S_OK;
  1029. }
  1030. if(m_Names->aObjects[0].offsetName == 0)
  1031. {
  1032. return E_UNEXPECTED;
  1033. }
  1034. if(m_Names->aObjects[0].offsetClass)
  1035. {
  1036. wszClassType = (LPWSTR)ByteOffset(m_Names, m_Names->aObjects[0].offsetClass);
  1037. }
  1038. if(wszClassType == NULL)
  1039. {
  1040. return S_OK;
  1041. }
  1042. if (!HIWORD(lpici->lpVerb))
  1043. {
  1044. UINT idCmd = LOWORD(lpici->lpVerb);
  1045. if(_wcsicmp(wszClassType, L"pKIEnrollmentService") == 0)
  1046. {
  1047. if(idCmd == m_idManage)
  1048. {
  1049. return _SpawnCertServerSnapin((LPWSTR)ByteOffset(m_Names, m_Names->aObjects[0].offsetName));
  1050. }
  1051. }
  1052. else if(_wcsicmp(wszClassType, L"cRLDistributionPoint") == 0)
  1053. {
  1054. PCCRL_CONTEXT pCRL = NULL;
  1055. _CRLFromDN((LPWSTR)ByteOffset(m_Names, m_Names->aObjects[0].offsetName),
  1056. &pCRL);
  1057. if(pCRL)
  1058. {
  1059. if(idCmd == m_idOpen)
  1060. {
  1061. hr = _LaunchCRLDialog(pCRL);
  1062. }
  1063. else if(idCmd == m_idExport)
  1064. {
  1065. hr = _OnExportCRL(pCRL);
  1066. }
  1067. CertFreeCRLContext(pCRL);
  1068. return hr;
  1069. }
  1070. }
  1071. }
  1072. return E_NOTIMPL;
  1073. }
  1074. STDMETHODIMP CCAShellExt::_SpawnCertServerSnapin(LPWSTR wszServiceDN)
  1075. {
  1076. // Determine the config string. Strinp the CN out of the service DN, look it up via certca.h api's.
  1077. HRESULT hr = S_OK;
  1078. HCAINFO hCAInfo = NULL;
  1079. LPWSTR wszTypeDN;
  1080. LPWSTR *awszDNSName = NULL;
  1081. LPWSTR wszArgs = NULL;
  1082. LPWSTR wszCN= NULL;
  1083. wszTypeDN = wcsstr(wszServiceDN, L"CN=");
  1084. if(wszTypeDN == NULL)
  1085. {
  1086. return E_UNEXPECTED;
  1087. }
  1088. wszTypeDN += 3;
  1089. wszCN = (LPWSTR)LocalAlloc(LMEM_FIXED, sizeof(WCHAR)*(wcslen(wszTypeDN)+1));
  1090. if(wszCN == NULL)
  1091. {
  1092. return E_OUTOFMEMORY;
  1093. }
  1094. wcscpy(wszCN, wszTypeDN);
  1095. wszTypeDN = wcschr(wszCN, L',');
  1096. if(wszTypeDN)
  1097. {
  1098. *wszTypeDN = 0;
  1099. }
  1100. hr = CAFindByName(
  1101. wszCN,
  1102. NULL,
  1103. CA_FIND_INCLUDE_UNTRUSTED | CA_FIND_INCLUDE_NON_TEMPLATE_CA,
  1104. &hCAInfo);
  1105. if(hr != S_OK)
  1106. {
  1107. goto error;
  1108. }
  1109. hr = CAGetCAProperty(hCAInfo, CA_PROP_DNSNAME, &awszDNSName);
  1110. if(hr != S_OK)
  1111. {
  1112. goto error;
  1113. }
  1114. if((awszDNSName == NULL) || (awszDNSName[0] == NULL))
  1115. {
  1116. hr = E_UNEXPECTED;
  1117. goto error;
  1118. }
  1119. wszArgs = (LPWSTR) LocalAlloc (LMEM_FIXED, (wcslen (awszDNSName[0]) + wcslen(wszCN) + 30) * sizeof(WCHAR));
  1120. if (!wszArgs)
  1121. {
  1122. hr = E_OUTOFMEMORY;
  1123. goto error;
  1124. }
  1125. //
  1126. // Build the command line arguments
  1127. //
  1128. wsprintf (wszArgs, L"/s /machine:%s", awszDNSName[0]);
  1129. ShellExecute (NULL, TEXT("open"), TEXT("certsrv.msc"), wszArgs,
  1130. NULL, SW_SHOWNORMAL);
  1131. error:
  1132. if(wszArgs)
  1133. {
  1134. LocalFree(wszArgs);
  1135. }
  1136. if(wszCN)
  1137. {
  1138. LocalFree(wszCN);
  1139. }
  1140. if(hCAInfo)
  1141. {
  1142. if(awszDNSName)
  1143. {
  1144. CAFreeCAProperty(hCAInfo, awszDNSName);
  1145. }
  1146. CACloseCA(hCAInfo);
  1147. }
  1148. return hr;
  1149. }
  1150. STDMETHODIMP CCAShellExt::_CRLFromDN(LPWSTR wszCDPDN, PCCRL_CONTEXT *ppCRL)
  1151. {
  1152. HCERTSTORE hStore = NULL;
  1153. HRESULT hResult = S_OK;
  1154. const LPWSTR CDP_PROPERTY_EXT = L"?certificateRevocationList?base?objectclass=cRLDistributionPoint";
  1155. LPWSTR pvPara = NULL;
  1156. ASSERT (wszCDPDN);
  1157. *ppCRL = NULL;
  1158. if ( wszCDPDN )
  1159. {
  1160. pvPara = new WCHAR[wcslen (wszCDPDN) +
  1161. wcslen (CDP_PROPERTY_EXT) + 1];
  1162. if ( pvPara )
  1163. {
  1164. wcscpy (pvPara, wszCDPDN);
  1165. wcscat (pvPara, CDP_PROPERTY_EXT);
  1166. hStore = ::CertOpenStore ("LDAP",
  1167. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL,
  1168. 0,
  1169. (void*) pvPara);
  1170. if ( !hStore )
  1171. {
  1172. hResult = E_FAIL;
  1173. goto error;
  1174. }
  1175. }
  1176. }
  1177. if (NULL != hStore)
  1178. {
  1179. *ppCRL = CertFindCRLInStore(hStore,
  1180. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  1181. 0,
  1182. CRL_FIND_ANY,
  1183. NULL,
  1184. NULL);
  1185. }
  1186. error:
  1187. if(hStore)
  1188. {
  1189. CertCloseStore(hStore, 0);
  1190. }
  1191. if(pvPara)
  1192. {
  1193. LocalFree(pvPara);
  1194. }
  1195. return hResult;
  1196. }
  1197. STDMETHODIMP CCAShellExt::_LaunchCRLDialog(PCCRL_CONTEXT pCRL)
  1198. {
  1199. CRYPTUI_VIEWCRL_STRUCT vcs;
  1200. HWND hwndParent = NULL;
  1201. HRESULT hr = S_OK;
  1202. ::ZeroMemory (&vcs, sizeof (vcs));
  1203. vcs.dwSize = sizeof (vcs);
  1204. vcs.hwndParent = hwndParent;
  1205. vcs.dwFlags = 0;
  1206. vcs.pCRLContext = pCRL;
  1207. if(!::CryptUIDlgViewCRL (&vcs))
  1208. {
  1209. hr = GetLastError();
  1210. hr = HRESULT_FROM_WIN32(hr);
  1211. }
  1212. return hr;
  1213. }
  1214. HRESULT CCAShellExt::_OnExportCRL (PCCRL_CONTEXT pCRL)
  1215. {
  1216. AFX_MANAGE_STATE (AfxGetStaticModuleState ());
  1217. HRESULT hr = S_OK;
  1218. CRYPTUI_WIZ_EXPORT_INFO cwi;
  1219. HWND hwndParent = 0;
  1220. ::ZeroMemory (&cwi, sizeof (cwi));
  1221. cwi.dwSize = sizeof (cwi);
  1222. cwi.dwSubjectChoice = CRYPTUI_WIZ_EXPORT_CRL_CONTEXT;
  1223. ASSERT (pCRL);
  1224. if ( pCRL )
  1225. cwi.pCRLContext = pCRL;
  1226. else
  1227. return E_UNEXPECTED;
  1228. if(!::CryptUIWizExport (
  1229. 0,
  1230. hwndParent,
  1231. 0,
  1232. &cwi,
  1233. NULL))
  1234. {
  1235. hr = GetLastError();
  1236. hr = HRESULT_FROM_WIN32(hr);
  1237. }
  1238. return hr;
  1239. }
  1240. STDMETHODIMP CCAShellExt::QueryContextMenu
  1241. (
  1242. HMENU hmenu,
  1243. UINT indexMenu,
  1244. UINT idCmdFirst,
  1245. UINT idCmdLast,
  1246. UINT uFlags
  1247. )
  1248. {
  1249. LPWSTR wszClassType = NULL;
  1250. if(m_Names->cItems != 1)
  1251. {
  1252. // Don't add the properties page if we have no or many objects selected
  1253. return S_OK;
  1254. }
  1255. if(m_Names->aObjects[0].offsetName == 0)
  1256. {
  1257. return E_UNEXPECTED;
  1258. }
  1259. if(m_Names->aObjects[0].offsetClass)
  1260. {
  1261. wszClassType = (LPWSTR)ByteOffset(m_Names, m_Names->aObjects[0].offsetClass);
  1262. }
  1263. if(wszClassType == NULL)
  1264. {
  1265. return S_OK;
  1266. }
  1267. if(((m_Names->aObjects[0].dwProviderFlags & DSPROVIDER_ADVANCED) != 0) &&
  1268. (_wcsicmp(wszClassType, L"pKIEnrollmentService") == 0))
  1269. {
  1270. // Add a "manage" option
  1271. CString szEdit;
  1272. MENUITEMINFO mii;
  1273. UINT idLastUsedCmd = idCmdFirst;
  1274. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1275. ZeroMemory(&mii, sizeof(mii));
  1276. mii.cbSize = sizeof(mii);
  1277. mii.fMask = MIIM_TYPE | MIIM_ID;
  1278. mii.fType = MFT_STRING;
  1279. mii.wID = idLastUsedCmd;
  1280. szEdit.LoadString(IDS_MANAGE);
  1281. mii.dwTypeData = (LPTSTR)(LPCTSTR)szEdit;
  1282. mii.cch = szEdit.GetLength();
  1283. m_idManage = indexMenu;
  1284. // Add new menu items to the context menu. //
  1285. ::InsertMenuItem(hmenu,
  1286. indexMenu++,
  1287. TRUE,
  1288. &mii);
  1289. idLastUsedCmd++;
  1290. return ResultFromScode (MAKE_SCODE (SEVERITY_SUCCESS, 0,
  1291. USHORT (idLastUsedCmd )));
  1292. }
  1293. else if(((m_Names->aObjects[0].dwProviderFlags & DSPROVIDER_ADVANCED) != 0) &&
  1294. (_wcsicmp(wszClassType, L"cRLDistributionPoint") == 0))
  1295. {
  1296. // Add a "manage" option
  1297. CString szName;
  1298. MENUITEMINFO mii;
  1299. UINT idLastUsedCmd = idCmdFirst;
  1300. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1301. ZeroMemory(&mii, sizeof(mii));
  1302. mii.cbSize = sizeof(mii);
  1303. mii.fMask = MIIM_TYPE | MIIM_ID;
  1304. mii.fType = MFT_STRING;
  1305. mii.wID = idLastUsedCmd;
  1306. szName.LoadString(IDS_OPEN);
  1307. mii.dwTypeData = (LPTSTR)(LPCTSTR)szName;
  1308. mii.cch = szName.GetLength();
  1309. m_idOpen = indexMenu;
  1310. // Add new menu items to the context menu. //
  1311. ::InsertMenuItem(hmenu,
  1312. indexMenu++,
  1313. TRUE,
  1314. &mii);
  1315. idLastUsedCmd++;
  1316. ZeroMemory(&mii, sizeof(mii));
  1317. mii.cbSize = sizeof(mii);
  1318. mii.fMask = MIIM_TYPE | MIIM_ID;
  1319. mii.fType = MFT_STRING;
  1320. mii.wID = idLastUsedCmd;
  1321. szName.LoadString(IDS_EXPORT);
  1322. mii.dwTypeData = (LPTSTR)(LPCTSTR)szName;
  1323. mii.cch = szName.GetLength();
  1324. m_idExport = indexMenu;
  1325. // Add new menu items to the context menu. //
  1326. ::InsertMenuItem(hmenu,
  1327. indexMenu++,
  1328. TRUE,
  1329. &mii);
  1330. idLastUsedCmd++;
  1331. return ResultFromScode (MAKE_SCODE (SEVERITY_SUCCESS, 0,
  1332. USHORT (idLastUsedCmd)));
  1333. }
  1334. return S_OK;
  1335. }