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.

1389 lines
43 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: selcert.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "global.hxx"
  11. #include <dbgdef.h>
  12. extern HINSTANCE HinstDll;
  13. extern HMODULE HmodRichEdit;
  14. #define MAX_SIZE_OF_COLUMNS 400
  15. static const HELPMAP helpmap[] = {
  16. {IDC_SELECTCERT_VIEWCERT_BUTTON,IDH_SELECTCERTIFICATE_VIEWCERT_BUTTON},
  17. {IDC_SELECTCERT_CERTLIST, IDH_SELECTCERTIFICATE_CERTIFICATE_LIST}
  18. };
  19. class CertContextList {
  20. public:
  21. CertContextList() : m_head(NULL) { }
  22. ~CertContextList();
  23. HRESULT Add(IN PCCERT_CONTEXT pCertContext,
  24. OUT BOOL *pfReplacedExisting) ;
  25. HRESULT SyncWithStore(HCERTSTORE hStore, DWORD dwFlags);
  26. private:
  27. typedef struct _CertContextListEle {
  28. PCCERT_CONTEXT pCertContext;
  29. struct _CertContextListEle * pNext;
  30. } CertContextListEle;
  31. CertContextListEle * m_head;
  32. };
  33. typedef struct _CERT_SELECT_HELPER
  34. {
  35. PCCRYPTUI_SELECTCERTIFICATE_STRUCTW pcsc;
  36. PCCERT_CONTEXT pSelectedCert;
  37. DWORD rgdwSortParam[6];
  38. BOOL fCertListDblClick;
  39. CertContextList *pCertsFromDS;
  40. } CERT_SELECT_HELPER, *PCERT_SELECT_HELPER;
  41. //////////////////////////////////////////////////////////////////////////////////////
  42. //
  43. //////////////////////////////////////////////////////////////////////////////////////
  44. static void AddCertToList(HWND hWndListView, PCERT_SELECT_HELPER pviewhelp, PCCERT_CONTEXT pCertContext, int itemIndex)
  45. {
  46. LPWSTR pwszText;
  47. DWORD cbText;
  48. WCHAR szText[CRYPTUI_MAX_STRING_SIZE];
  49. int subItemIndex;
  50. LV_ITEMW lvI;
  51. PCCRYPTUI_SELECTCERTIFICATE_STRUCTW pcsc;
  52. pcsc = pviewhelp->pcsc;
  53. //
  54. // set up the fields in the list view item
  55. //
  56. lvI.mask = LVIF_PARAM | LVIF_STATE | LVIF_IMAGE;
  57. lvI.state = 0;
  58. lvI.stateMask = 0;
  59. lvI.iSubItem = 0;
  60. lvI.iImage = 0;
  61. lvI.lParam = (LPARAM) CertDuplicateCertificateContext(pCertContext);
  62. lvI.iItem = itemIndex;
  63. ListView_InsertItemU(hWndListView, &lvI);
  64. subItemIndex = 0;
  65. //
  66. // issued to
  67. //
  68. if (!(pcsc->dwDontUseColumn & CRYPTUI_SELECT_ISSUEDTO_COLUMN))
  69. {
  70. CertGetNameStringW(
  71. pCertContext,
  72. CERT_NAME_SIMPLE_DISPLAY_TYPE,
  73. 0,//CERT_NAME_ISSUER_FLAG,
  74. NULL,
  75. szText,
  76. ARRAYSIZE(szText));
  77. ListView_SetItemTextU(hWndListView, itemIndex , subItemIndex++, szText);
  78. }
  79. //
  80. // issued by
  81. //
  82. if (!(pcsc->dwDontUseColumn & CRYPTUI_SELECT_ISSUEDBY_COLUMN))
  83. {
  84. CertGetNameStringW(
  85. pCertContext,
  86. CERT_NAME_SIMPLE_DISPLAY_TYPE,
  87. CERT_NAME_ISSUER_FLAG,
  88. NULL,
  89. szText,
  90. ARRAYSIZE(szText));
  91. ListView_SetItemTextU(hWndListView, itemIndex , subItemIndex++, szText);
  92. }
  93. //
  94. // intended use
  95. //
  96. if (!(pcsc->dwDontUseColumn & CRYPTUI_SELECT_INTENDEDUSE_COLUMN))
  97. {
  98. if (FormatEnhancedKeyUsageString(&pwszText, pCertContext, FALSE, FALSE))
  99. {
  100. ListView_SetItemTextU(hWndListView, itemIndex , subItemIndex, pwszText);
  101. free(pwszText);
  102. }
  103. subItemIndex++;
  104. }
  105. //
  106. // friendly name
  107. //
  108. if (!(pcsc->dwDontUseColumn & CRYPTUI_SELECT_FRIENDLYNAME_COLUMN))
  109. {
  110. cbText = 0;
  111. if (CertGetCertificateContextProperty( pCertContext,
  112. CERT_FRIENDLY_NAME_PROP_ID,
  113. NULL,
  114. &cbText) &&
  115. (NULL != (pwszText = (LPWSTR) malloc(cbText))))
  116. {
  117. CertGetCertificateContextProperty( pCertContext,
  118. CERT_FRIENDLY_NAME_PROP_ID,
  119. pwszText,
  120. &cbText);
  121. ListView_SetItemTextU(hWndListView, itemIndex , subItemIndex++, pwszText);
  122. free(pwszText);
  123. }
  124. else
  125. {
  126. LoadStringU(HinstDll, IDS_FRIENDLYNAME_NONE, szText, ARRAYSIZE(szText));
  127. ListView_SetItemTextU(hWndListView, itemIndex , subItemIndex++, szText);
  128. }
  129. }
  130. //
  131. // expiration
  132. //
  133. if (!(pcsc->dwDontUseColumn & CRYPTUI_SELECT_EXPIRATION_COLUMN))
  134. {
  135. if (!FormatDateString(&pwszText, pCertContext->pCertInfo->NotAfter, FALSE, FALSE, hWndListView))
  136. {
  137. LoadStringU(HinstDll, IDS_NOTAVAILABLE, szText, ARRAYSIZE(szText));
  138. ListView_SetItemTextU(hWndListView, itemIndex , subItemIndex++, szText);
  139. }
  140. else
  141. {
  142. ListView_SetItemTextU(hWndListView, itemIndex , subItemIndex++, pwszText);
  143. free(pwszText);
  144. }
  145. }
  146. //
  147. // location
  148. //
  149. if (!(pcsc->dwDontUseColumn & CRYPTUI_SELECT_LOCATION_COLUMN))
  150. {
  151. pwszText = (LPWSTR) GetStoreName(pCertContext->hCertStore, TRUE);
  152. if (pwszText == NULL)
  153. {
  154. LoadStringU(HinstDll, IDS_NOTAVAILABLE, szText, ARRAYSIZE(szText));
  155. ListView_SetItemTextU(hWndListView, itemIndex , subItemIndex++, szText);
  156. }
  157. else
  158. {
  159. ListView_SetItemTextU(hWndListView, itemIndex , subItemIndex++, pwszText);
  160. free(pwszText);
  161. }
  162. }
  163. }
  164. static int ReplaceCertInList(HWND hWndListView, PCERT_SELECT_HELPER pviewhelp, PCCERT_CONTEXT pCertContext)
  165. {
  166. int nIndex = -1;
  167. LV_ITEM lvitem;
  168. while (-1 != (nIndex = ListView_GetNextItem(hWndListView, nIndex, LVNI_ALL)))
  169. {
  170. //DSIE: Bug 420717
  171. memset(&lvitem, 0, sizeof(lvitem));
  172. lvitem.iItem = nIndex;
  173. lvitem.mask = LVIF_PARAM;
  174. if (ListView_GetItem(hWndListView, &lvitem))
  175. {
  176. PCCERT_CONTEXT pCurrent = (PCCERT_CONTEXT)lvitem.lParam;
  177. if (pCurrent->dwCertEncodingType == pCertContext->dwCertEncodingType)
  178. {
  179. if (CertCompareCertificate(pCertContext->dwCertEncodingType,
  180. pCertContext->pCertInfo,
  181. pCurrent->pCertInfo))
  182. {
  183. // Found a match, replace the certificate.
  184. CertFreeCertificateContext(pCurrent);
  185. ListView_DeleteItem(hWndListView, nIndex);
  186. // Now, add our new certificate at this index.
  187. AddCertToList(hWndListView, pviewhelp, pCertContext, nIndex);
  188. goto CommonReturn;
  189. }
  190. }
  191. }
  192. }
  193. // No match, nothing to replace, just append to the list.
  194. AddCertToList(hWndListView, pviewhelp, pCertContext, ListView_GetItemCount(hWndListView));
  195. CommonReturn:
  196. return nIndex;
  197. }
  198. // DSIE: Bug 207106
  199. BOOL SupportEncryptedFileSystem(PCCERT_CONTEXT pCertContext)
  200. {
  201. BOOL fSuccess = FALSE;
  202. DWORD cbUsage = 0;
  203. PCERT_ENHKEY_USAGE pUsage = NULL;
  204. if (!pCertContext)
  205. return FALSE;
  206. if (!CertGetEnhancedKeyUsage(pCertContext, 0, NULL, &cbUsage))
  207. goto CleanUp;
  208. if (NULL == (pUsage = (PCERT_ENHKEY_USAGE) malloc(cbUsage)))
  209. goto CleanUp;
  210. if (!CertGetEnhancedKeyUsage(pCertContext, 0, pUsage, &cbUsage))
  211. goto CleanUp;
  212. if (0 == pUsage->cUsageIdentifier)
  213. {
  214. if (CRYPT_E_NOT_FOUND == GetLastError())
  215. {
  216. fSuccess = TRUE;
  217. }
  218. }
  219. else
  220. {
  221. for (DWORD i = 0; i < pUsage->cUsageIdentifier; i++)
  222. {
  223. if (0 == strcmp(szOID_ENHANCED_KEY_USAGE, pUsage->rgpszUsageIdentifier[i]))
  224. {
  225. fSuccess = TRUE;
  226. goto CleanUp;
  227. }
  228. }
  229. }
  230. CleanUp:
  231. if (pUsage)
  232. free(pUsage);
  233. return fSuccess;
  234. }
  235. //DSIE: Bug 314005. Major change to switch over to use Object Picker.
  236. HRESULT AddFromDS(HWND hwndDlg, PCERT_SELECT_HELPER pviewhelp)
  237. {
  238. static const int SCOPE_INIT_COUNT = 1;
  239. IDsObjectPicker * pDsObjectPicker = NULL;
  240. IDataObject * pdo = NULL;
  241. DSOP_SCOPE_INIT_INFO aScopeInit[SCOPE_INIT_COUNT];
  242. DSOP_INIT_INFO InitInfo;
  243. UINT cfDsObjectPicker = RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
  244. HWND hWndListView = NULL;
  245. BOOL fGotStgMedium = FALSE;
  246. PDS_SELECTION_LIST pDsSelList = NULL;
  247. STGMEDIUM stgmedium = {TYMED_HGLOBAL, NULL, NULL};
  248. FORMATETC formatetc = {(CLIPFORMAT) cfDsObjectPicker, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  249. HRESULT hr;
  250. HCERTSTORE hDSCertStore = NULL;
  251. PCCERT_CONTEXT pCertContext = NULL;
  252. PCCERT_CONTEXT pCertContextPrev = NULL;
  253. CertContextList * pCertContextList = NULL;
  254. WCHAR errorString[512];
  255. WCHAR errorTitle[512];
  256. BOOL fInitialSelectedCert = FALSE;
  257. PCCRYPTUI_SELECTCERTIFICATE_STRUCTW pcsc = NULL;
  258. // Input validation:
  259. if (NULL == hwndDlg ||
  260. NULL == pviewhelp ||
  261. NULL == pviewhelp->pcsc ||
  262. NULL == pviewhelp->pCertsFromDS)
  263. return E_INVALIDARG;
  264. // Init:
  265. pcsc = pviewhelp->pcsc;
  266. pCertContextList = pviewhelp->pCertsFromDS;
  267. hWndListView = GetDlgItem(hwndDlg, IDC_SELECTCERT_CERTLIST);
  268. CoInitialize(NULL);
  269. hr = CoCreateInstance(CLSID_DsObjectPicker,
  270. NULL,
  271. CLSCTX_INPROC_SERVER,
  272. IID_IDsObjectPicker,
  273. (void **) &pDsObjectPicker);
  274. if (FAILED(hr) || NULL == pDsObjectPicker)
  275. goto ComError;
  276. // Initialize the DSOP_SCOPE_INIT_INFO array.
  277. ZeroMemory(aScopeInit, sizeof(DSOP_SCOPE_INIT_INFO) * SCOPE_INIT_COUNT);
  278. // Combine multiple scope types in a single array entry.
  279. aScopeInit[0].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  280. aScopeInit[0].flType = DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN
  281. | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN;
  282. // Set uplevel and downlevel filters to include only computer objects.
  283. // Uplevel filters apply to both mixed and native modes.
  284. // Notice that the uplevel and downlevel flags are different.
  285. aScopeInit[0].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_USERS;
  286. aScopeInit[0].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_USERS;
  287. // Initialize the DSOP_INIT_INFO structure.
  288. ZeroMemory(&InitInfo, sizeof(InitInfo));
  289. InitInfo.cbSize = sizeof(InitInfo);
  290. InitInfo.pwzTargetComputer = NULL; // Target is the local computer.
  291. InitInfo.cDsScopeInfos = SCOPE_INIT_COUNT;
  292. InitInfo.aDsScopeInfos = aScopeInit;
  293. //InitInfo.flOptions = DSOP_FLAG_MULTISELECT;
  294. // You can call Initialize multiple times; last call wins.
  295. // Note that object picker makes its own copy of InitInfo.
  296. hr = pDsObjectPicker->Initialize(&InitInfo);
  297. if (FAILED(hr))
  298. goto ComError;
  299. // Invoke the modal dialog.
  300. hr = pDsObjectPicker->InvokeDialog(hwndDlg, &pdo);
  301. if (FAILED(hr))
  302. goto ComError;
  303. // User pressed Cancel.
  304. if (hr == S_FALSE)
  305. {
  306. hr = E_ABORT;
  307. goto cleanup;
  308. }
  309. // Get the global memory block containing the user's selections.
  310. hr = pdo->GetData(&formatetc, &stgmedium);
  311. if (FAILED(hr))
  312. goto ComError;
  313. fGotStgMedium = TRUE;
  314. // Retrieve pointer to DS_SELECTION_LIST structure.
  315. pDsSelList = (PDS_SELECTION_LIST) GlobalLock(stgmedium.hGlobal);
  316. if (!pDsSelList)
  317. goto ComError;
  318. // Loop through DS_SELECTION array of selected objects.
  319. for (ULONG i = 0; i < pDsSelList->cItems; i++)
  320. {
  321. WCHAR pwszLdapUrl[2048];
  322. LPWSTR pTemp = pDsSelList->aDsSelection[i].pwzADsPath;
  323. BOOL fReplacedExisting;
  324. BOOL fHasEFSCerts = FALSE;
  325. // Now is the time to get the certificate
  326. LPCWSTR szCertAttr = L"?userCertificate";
  327. // Check if our buffer is too small to hold the query.
  328. if (wcslen(pTemp) + wcslen(szCertAttr) + 1 > (sizeof(pwszLdapUrl) / sizeof(pwszLdapUrl[0])))
  329. goto UnexpectedErr;
  330. wcscpy(pwszLdapUrl, pTemp);
  331. wcscat(pwszLdapUrl, szCertAttr);
  332. // Now open the DS store using LDAP provider.
  333. hDSCertStore = CertOpenStore(sz_CERT_STORE_PROV_LDAP,
  334. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  335. NULL,
  336. CERT_STORE_READONLY_FLAG,
  337. (void*) pwszLdapUrl);
  338. if (NULL == hDSCertStore)
  339. goto CertCliError;
  340. // We get the certificate store
  341. pCertContext = NULL;
  342. pCertContextPrev = NULL;
  343. int nItemIndex;
  344. while (NULL != (pCertContext = CertEnumCertificatesInStore(hDSCertStore, pCertContextPrev)))
  345. {
  346. // Apply our filter callback function to see if we should display this certificate.
  347. BOOL fAllowCert = FALSE;
  348. if (pcsc->pFilterCallback)
  349. fAllowCert = (*(pcsc->pFilterCallback))(pCertContext, &fInitialSelectedCert, pcsc->pvCallbackData);
  350. fAllowCert |= SupportEncryptedFileSystem(pCertContext);
  351. if (fAllowCert)
  352. {
  353. fHasEFSCerts = TRUE;
  354. if (S_OK != (hr = pCertContextList->Add(pCertContext, &fReplacedExisting)))
  355. goto ErrorReturn;
  356. nItemIndex = ReplaceCertInList(hWndListView, pviewhelp, pCertContext);
  357. // if the select cert dialog caller said that this should be the initially
  358. // selected cert then make it so.
  359. if (fInitialSelectedCert)
  360. ListView_SetItemState(hWndListView, nItemIndex, LVIS_SELECTED, LVIS_SELECTED);
  361. }
  362. pCertContextPrev = pCertContext;
  363. }
  364. // We didn't reach the end of the enumeration. This is an error.
  365. if (GetLastError() != CRYPT_E_NOT_FOUND)
  366. goto CertCliError;
  367. // We didn't find any EFS certs: display an error message and pop up the window again.
  368. if (!fHasEFSCerts)
  369. goto NoEfsError;
  370. }
  371. hr = S_OK;
  372. cleanup:
  373. if (hDSCertStore)
  374. {
  375. CertCloseStore(hDSCertStore, 0);
  376. }
  377. if (NULL != pCertContext)
  378. {
  379. CertFreeCertificateContext(pCertContext);
  380. }
  381. if (pDsSelList)
  382. {
  383. GlobalUnlock(stgmedium.hGlobal);
  384. }
  385. if (fGotStgMedium)
  386. {
  387. ReleaseStgMedium(&stgmedium);
  388. }
  389. if (pdo)
  390. {
  391. pdo->Release();
  392. }
  393. if (pDsObjectPicker)
  394. {
  395. pDsObjectPicker->Release();
  396. }
  397. CoUninitialize();
  398. return hr;
  399. ErrorReturn:
  400. {
  401. WCHAR wszText[MAX_STRING_SIZE];
  402. WCHAR errorTitle2[MAX_STRING_SIZE];
  403. LPWSTR pwszErrorMsg = NULL;
  404. //get the text string
  405. if(LoadStringU(HinstDll, IDS_INTERNAL_ERROR, wszText, sizeof(wszText) / sizeof(wszText[0])))
  406. {
  407. if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  408. FORMAT_MESSAGE_FROM_SYSTEM |
  409. FORMAT_MESSAGE_IGNORE_INSERTS,
  410. NULL,
  411. hr,
  412. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  413. (LPWSTR) &pwszErrorMsg,
  414. 0,
  415. NULL))
  416. {
  417. if (LoadStringU(HinstDll, IDS_SELECT_CERTIFICATE_TITLE, errorTitle2, ARRAYSIZE(errorTitle2))) {
  418. MessageBoxU(hwndDlg, pwszErrorMsg, errorTitle2, MB_ICONERROR|MB_OK|MB_APPLMODAL);
  419. }
  420. }
  421. }
  422. if (NULL != pwszErrorMsg) { LocalFree(pwszErrorMsg); }
  423. }
  424. goto cleanup;
  425. CertCliError:
  426. hr = HRESULT_FROM_WIN32(GetLastError());
  427. goto ErrorReturn;
  428. ComError:
  429. goto ErrorReturn;
  430. NoEfsError:
  431. LoadStringU(HinstDll, IDS_SELECT_CERT_NO_CERT_ERROR, errorString, ARRAYSIZE(errorString));
  432. if (pcsc->szTitle != NULL)
  433. {
  434. MessageBoxU(hwndDlg, errorString, pcsc->szTitle, MB_OK | MB_ICONWARNING);
  435. }
  436. else
  437. {
  438. LoadStringU(HinstDll, IDS_SELECT_CERTIFICATE_TITLE, errorTitle, ARRAYSIZE(errorTitle));
  439. MessageBoxU(hwndDlg, errorString, errorTitle, MB_OK | MB_ICONWARNING);
  440. }
  441. hr = AddFromDS(hwndDlg, pviewhelp);
  442. goto cleanup;
  443. UnexpectedErr:
  444. hr = E_UNEXPECTED;
  445. goto ErrorReturn;
  446. }
  447. //////////////////////////////////////////////////////////////////////////////////////
  448. //
  449. //////////////////////////////////////////////////////////////////////////////////////
  450. static void AddCertsToList(HWND hWndListView, PCERT_SELECT_HELPER pviewhelp)
  451. {
  452. DWORD i;
  453. PCCERT_CONTEXT pCertContext;
  454. int itemIndex = 0;
  455. PCCRYPTUI_SELECTCERTIFICATE_STRUCTW pcsc;
  456. BOOL fInitialSelectedCert = FALSE;
  457. pcsc = pviewhelp->pcsc;
  458. //
  459. // loop for each store and display the certs in each store
  460. //
  461. for (i=0; i<pcsc->cDisplayStores; i++)
  462. {
  463. //
  464. // loop for each cert in the store
  465. //
  466. pCertContext = NULL;
  467. while (NULL != (pCertContext = CertEnumCertificatesInStore(pcsc->rghDisplayStores[i], pCertContext)))
  468. {
  469. fInitialSelectedCert = FALSE;
  470. if ((pcsc->pFilterCallback == NULL) ||
  471. ((*(pcsc->pFilterCallback))(pCertContext, &fInitialSelectedCert, pcsc->pvCallbackData) == TRUE))
  472. {
  473. AddCertToList(hWndListView, pviewhelp, pCertContext, itemIndex);
  474. //
  475. // if the select cert dialog caller said that this should be the initially
  476. // selected cert then make it so.
  477. //
  478. if (fInitialSelectedCert)
  479. {
  480. ListView_SetItemState(hWndListView, itemIndex, LVIS_SELECTED, LVIS_SELECTED);
  481. }
  482. itemIndex++;
  483. }
  484. }
  485. }
  486. }
  487. //////////////////////////////////////////////////////////////////////////////////////
  488. //
  489. //////////////////////////////////////////////////////////////////////////////////////
  490. static int CalculateColumnWidth(DWORD dwDontUseColumn)
  491. {
  492. int numColumns = 0;
  493. if (!(dwDontUseColumn & CRYPTUI_SELECT_ISSUEDTO_COLUMN))
  494. {
  495. numColumns++;
  496. }
  497. if (!(dwDontUseColumn & CRYPTUI_SELECT_ISSUEDBY_COLUMN))
  498. {
  499. numColumns++;
  500. }
  501. if (!(dwDontUseColumn & CRYPTUI_SELECT_INTENDEDUSE_COLUMN))
  502. {
  503. numColumns++;
  504. }
  505. if (!(dwDontUseColumn & CRYPTUI_SELECT_FRIENDLYNAME_COLUMN))
  506. {
  507. numColumns++;
  508. }
  509. if (!(dwDontUseColumn & CRYPTUI_SELECT_EXPIRATION_COLUMN))
  510. {
  511. numColumns++;
  512. }
  513. if (!(dwDontUseColumn & CRYPTUI_SELECT_LOCATION_COLUMN))
  514. {
  515. numColumns++;
  516. }
  517. if (numColumns >= 2)
  518. {
  519. return (MAX_SIZE_OF_COLUMNS / numColumns);
  520. }
  521. else
  522. {
  523. return MAX_SIZE_OF_COLUMNS;
  524. }
  525. }
  526. //////////////////////////////////////////////////////////////////////////////////////
  527. //
  528. //////////////////////////////////////////////////////////////////////////////////////
  529. INT_PTR APIENTRY SelectCertDialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  530. {
  531. WCHAR szText[CRYPTUI_MAX_STRING_SIZE];
  532. HWND hWndListView;
  533. LV_COLUMNW lvC;
  534. int iCol = 0;
  535. LV_ITEMW lvI;
  536. int listIndex;
  537. LPNMLISTVIEW pnmv;
  538. PCERT_SELECT_HELPER pviewhelp;
  539. PCCRYPTUI_SELECTCERTIFICATE_STRUCTW pcsc;
  540. WCHAR errorString[CRYPTUI_MAX_STRING_SIZE];
  541. WCHAR errorTitle[CRYPTUI_MAX_STRING_SIZE];
  542. HWND hwnd;
  543. HIMAGELIST hIml;
  544. DWORD dwSortParam;
  545. int SortParamIndex;
  546. switch ( msg ) {
  547. case WM_INITDIALOG:
  548. pviewhelp = (PCERT_SELECT_HELPER) lParam;
  549. SetWindowLongPtr(hwndDlg, DWLP_USER, (DWORD_PTR) pviewhelp);
  550. pcsc = pviewhelp->pcsc;
  551. //
  552. // set the dialog title and the display string
  553. //
  554. if (pcsc->szTitle != NULL)
  555. {
  556. SetWindowTextU(hwndDlg, pcsc->szTitle);
  557. }
  558. if (pcsc->szDisplayString != NULL)
  559. {
  560. SetDlgItemTextU(hwndDlg, IDC_SELECTCERT_DISPLAYSTRING, pcsc->szDisplayString);
  561. }
  562. else
  563. {
  564. if (pcsc->dwFlags & CRYPTUI_SELECTCERT_MULTISELECT)
  565. {
  566. LoadStringU(HinstDll, IDS_SELECT_MULTIPLE_CERT_DEFAULT, szText, ARRAYSIZE(szText));
  567. }
  568. else
  569. {
  570. LoadStringU(HinstDll, IDS_SELECT_CERT_DEFAULT, szText, ARRAYSIZE(szText));
  571. }
  572. SetDlgItemTextU(hwndDlg, IDC_SELECTCERT_DISPLAYSTRING, szText);
  573. }
  574. hWndListView = GetDlgItem(hwndDlg, IDC_SELECTCERT_CERTLIST);
  575. //
  576. // initialize the image list for the list view
  577. //
  578. hIml = ImageList_LoadImage(HinstDll, MAKEINTRESOURCE(IDB_CERT), 0, 1, RGB(255,0,255), IMAGE_BITMAP, 0);
  579. ListView_SetImageList(hWndListView, hIml, LVSIL_SMALL);
  580. //
  581. // add the colums to the list view
  582. //
  583. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;// | LVCF_SUBITEM;
  584. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  585. lvC.pszText = szText; // The text for the column.
  586. lvC.cx = CalculateColumnWidth(pviewhelp->pcsc->dwDontUseColumn);
  587. memset(&(pviewhelp->rgdwSortParam[0]), 0, ARRAYSIZE(pviewhelp->rgdwSortParam));
  588. SortParamIndex = 0;
  589. if (!(pviewhelp->pcsc->dwDontUseColumn & CRYPTUI_SELECT_ISSUEDTO_COLUMN))
  590. {
  591. LoadStringU(HinstDll, IDS_ISSUEDTO2, szText, ARRAYSIZE(szText));
  592. if (ListView_InsertColumnU(hWndListView, iCol++, &lvC) == -1)
  593. {
  594. // error
  595. }
  596. pviewhelp->rgdwSortParam[SortParamIndex++] = SORT_COLUMN_SUBJECT | SORT_COLUMN_ASCEND;
  597. }
  598. if (!(pviewhelp->pcsc->dwDontUseColumn & CRYPTUI_SELECT_ISSUEDBY_COLUMN))
  599. {
  600. LoadStringU(HinstDll, IDS_ISSUEDBY2, szText, ARRAYSIZE(szText));
  601. if (ListView_InsertColumnU(hWndListView, iCol++, &lvC) == -1)
  602. {
  603. // error
  604. }
  605. pviewhelp->rgdwSortParam[SortParamIndex++] = SORT_COLUMN_ISSUER | SORT_COLUMN_DESCEND;
  606. }
  607. if (!(pviewhelp->pcsc->dwDontUseColumn & CRYPTUI_SELECT_INTENDEDUSE_COLUMN))
  608. {
  609. LoadStringU(HinstDll, IDS_INTENDED_PURPOSE, szText, ARRAYSIZE(szText));
  610. if (ListView_InsertColumnU(hWndListView, iCol++, &lvC) == -1)
  611. {
  612. // error
  613. }
  614. pviewhelp->rgdwSortParam[SortParamIndex++] =SORT_COLUMN_PURPOSE | SORT_COLUMN_DESCEND;
  615. }
  616. if (!(pviewhelp->pcsc->dwDontUseColumn & CRYPTUI_SELECT_FRIENDLYNAME_COLUMN))
  617. {
  618. LoadStringU(HinstDll, IDS_CERTIFICATE_NAME, szText, ARRAYSIZE(szText));
  619. if (ListView_InsertColumnU(hWndListView, iCol++, &lvC) == -1)
  620. {
  621. // error
  622. }
  623. pviewhelp->rgdwSortParam[SortParamIndex++] = SORT_COLUMN_NAME | SORT_COLUMN_DESCEND;
  624. }
  625. if (!(pviewhelp->pcsc->dwDontUseColumn & CRYPTUI_SELECT_EXPIRATION_COLUMN))
  626. {
  627. LoadStringU(HinstDll, IDS_EXPIRATION_DATE, szText, ARRAYSIZE(szText));
  628. if (ListView_InsertColumnU(hWndListView, iCol++, &lvC) == -1)
  629. {
  630. // error
  631. }
  632. pviewhelp->rgdwSortParam[SortParamIndex++] = SORT_COLUMN_EXPIRATION | SORT_COLUMN_DESCEND;
  633. }
  634. if (!(pviewhelp->pcsc->dwDontUseColumn & CRYPTUI_SELECT_LOCATION_COLUMN))
  635. {
  636. LoadStringU(HinstDll, IDS_LOCATION, szText, ARRAYSIZE(szText));
  637. if (ListView_InsertColumnU(hWndListView, iCol++, &lvC) == -1)
  638. {
  639. // error
  640. }
  641. pviewhelp->rgdwSortParam[SortParamIndex++] = SORT_COLUMN_LOCATION | SORT_COLUMN_DESCEND;
  642. }
  643. AddCertsToList(hWndListView, pviewhelp);
  644. //
  645. // if there is no cert selected initially disable the "view cert button"
  646. //
  647. if (ListView_GetSelectedCount(hWndListView) == 0)
  648. {
  649. EnableWindow(GetDlgItem(hwndDlg, IDC_SELECTCERT_VIEWCERT_BUTTON), FALSE);
  650. }
  651. //
  652. // set the style in the list view so that it highlights an entire line
  653. //
  654. SendMessageA(hWndListView, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
  655. #if (1) // DSIE: bug 338852.
  656. HWND hwndFindUser;
  657. if (hwndFindUser = GetDlgItem(hwndDlg, IDC_SELECTCERT_ADDFROMDS_BUTTON))
  658. {
  659. LPBYTE pDCName = NULL;
  660. DWORD dwError = NetGetDCName(NULL, NULL, &pDCName);
  661. if (NERR_Success == dwError)
  662. {
  663. NetApiBufferFree(pDCName);
  664. }
  665. else
  666. {
  667. EnableWindow(hwndFindUser, FALSE);
  668. }
  669. }
  670. #endif
  671. ListView_SetItemState(hWndListView,
  672. 0,
  673. LVIS_FOCUSED | LVIS_SELECTED,
  674. LVIS_FOCUSED | LVIS_SELECTED);
  675. SetFocus(hWndListView);
  676. break;
  677. case WM_NOTIFY:
  678. pviewhelp = (PCERT_SELECT_HELPER) GetWindowLongPtr(hwndDlg, DWLP_USER);
  679. pcsc = pviewhelp->pcsc;
  680. hWndListView = GetDlgItem(hwndDlg, IDC_SELECTCERT_CERTLIST);
  681. switch (((NMHDR FAR *) lParam)->code)
  682. {
  683. case NM_DBLCLK:
  684. switch (((NMHDR FAR *) lParam)->idFrom)
  685. {
  686. case IDC_SELECTCERT_CERTLIST:
  687. if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_SELECTCERT_VIEWCERT_BUTTON)))
  688. {
  689. pviewhelp->fCertListDblClick = TRUE;
  690. SendMessage(
  691. hwndDlg,
  692. WM_COMMAND,
  693. MAKELONG(IDC_SELECTCERT_VIEWCERT_BUTTON, BN_CLICKED),
  694. (LPARAM) GetDlgItem(hwndDlg, IDC_SELECTCERT_VIEWCERT_BUTTON));
  695. }
  696. break;
  697. }
  698. break;
  699. case LVN_ITEMCHANGING:
  700. pnmv = (LPNMLISTVIEW) lParam;
  701. switch (((NMHDR FAR *) lParam)->idFrom)
  702. {
  703. case IDC_SELECTCERT_CERTLIST:
  704. if (!(pcsc->dwFlags & CRYPTUI_SELECTCERT_MULTISELECT))
  705. {
  706. if (pnmv->uNewState & LVIS_SELECTED)
  707. {
  708. ListView_SetItemState(
  709. hWndListView,
  710. ListView_GetNextItem(hWndListView, -1, LVNI_SELECTED),
  711. ~LVIS_SELECTED,
  712. LVIS_SELECTED);
  713. EnableWindow(GetDlgItem(hwndDlg, IDC_SELECTCERT_VIEWCERT_BUTTON), TRUE);
  714. }
  715. }
  716. break;
  717. }
  718. break;
  719. case LVN_ITEMCHANGED:
  720. pnmv = (LPNMLISTVIEW) lParam;
  721. switch (((NMHDR FAR *) lParam)->idFrom)
  722. {
  723. case IDC_SELECTCERT_CERTLIST:
  724. if (ListView_GetSelectedCount(hWndListView) == 1)
  725. {
  726. EnableWindow(GetDlgItem(hwndDlg, IDC_SELECTCERT_VIEWCERT_BUTTON), TRUE);
  727. }
  728. else
  729. {
  730. EnableWindow(GetDlgItem(hwndDlg, IDC_SELECTCERT_VIEWCERT_BUTTON), FALSE);
  731. }
  732. }
  733. break;
  734. case NM_SETFOCUS:
  735. switch (((NMHDR FAR *) lParam)->idFrom)
  736. {
  737. case IDC_SELECTCERT_CERTLIST:
  738. hWndListView = GetDlgItem(hwndDlg, IDC_SELECTCERT_CERTLIST);
  739. if ((ListView_GetItemCount(hWndListView) != 0) &&
  740. (ListView_GetNextItem(hWndListView, -1, LVNI_SELECTED) == -1))
  741. {
  742. memset(&lvI, 0, sizeof(lvI));
  743. lvI.mask = LVIF_STATE;
  744. lvI.iItem = 0;
  745. lvI.state = LVIS_FOCUSED;
  746. lvI.stateMask = LVIS_FOCUSED;
  747. ListView_SetItem(hWndListView, &lvI);
  748. }
  749. break;
  750. }
  751. break;
  752. case LVN_COLUMNCLICK:
  753. pnmv = (NM_LISTVIEW FAR *) lParam;
  754. //
  755. // get the column number
  756. //
  757. dwSortParam = 0;
  758. switch (pnmv->iSubItem)
  759. {
  760. case 0:
  761. case 1:
  762. case 2:
  763. case 3:
  764. case 4:
  765. case 5:
  766. dwSortParam = pviewhelp->rgdwSortParam[pnmv->iSubItem];
  767. break;
  768. default:
  769. dwSortParam = 0;
  770. break;
  771. }
  772. if (0 != dwSortParam)
  773. {
  774. //
  775. // flip the ascend ording
  776. //
  777. if (dwSortParam & SORT_COLUMN_ASCEND)
  778. {
  779. dwSortParam &= 0x0000FFFF;
  780. dwSortParam |= SORT_COLUMN_DESCEND;
  781. }
  782. else
  783. {
  784. if (dwSortParam & SORT_COLUMN_DESCEND)
  785. {
  786. dwSortParam &= 0x0000FFFF;
  787. dwSortParam |= SORT_COLUMN_ASCEND;
  788. }
  789. }
  790. //
  791. // sort the column
  792. //
  793. SendDlgItemMessage(hwndDlg,
  794. IDC_SELECTCERT_CERTLIST,
  795. LVM_SORTITEMS,
  796. (WPARAM) (LPARAM) dwSortParam,
  797. (LPARAM) (PFNLVCOMPARE)CompareCertificate);
  798. pviewhelp->rgdwSortParam[pnmv->iSubItem] = dwSortParam;
  799. }
  800. break;
  801. }
  802. break;
  803. case WM_COMMAND:
  804. pviewhelp = (PCERT_SELECT_HELPER) GetWindowLongPtr(hwndDlg, DWLP_USER);
  805. pcsc = pviewhelp->pcsc;
  806. hWndListView = GetDlgItem(hwndDlg, IDC_SELECTCERT_CERTLIST);
  807. switch (LOWORD(wParam))
  808. {
  809. case IDC_SELECTCERT_ADDFROMDS_BUTTON:
  810. {
  811. HRESULT hr = AddFromDS(hwndDlg, pviewhelp);
  812. if (FAILED(hr))
  813. {
  814. // Error
  815. }
  816. break;
  817. }
  818. case IDC_SELECTCERT_VIEWCERT_BUTTON:
  819. CRYPTUI_VIEWCERTIFICATE_STRUCTW cvps;
  820. BOOL fPropertiesChanged;
  821. listIndex = ListView_GetNextItem(
  822. hWndListView,
  823. -1,
  824. LVNI_SELECTED
  825. );
  826. if (listIndex != -1)
  827. {
  828. memset(&lvI, 0, sizeof(lvI));
  829. lvI.iItem = listIndex;
  830. lvI.mask = LVIF_PARAM;
  831. if (ListView_GetItemU(hWndListView, &lvI))
  832. {
  833. //
  834. // if the caller handed in a callback call them to see if they
  835. // want to handle the display of the cert, otherwise display the cert
  836. //
  837. if ((pcsc->pDisplayCallback != NULL) &&
  838. ((*(pcsc->pDisplayCallback))((PCCERT_CONTEXT) lvI.lParam, hwndDlg, pcsc->pvCallbackData) == TRUE))
  839. {
  840. //
  841. // set the fPropertiesChanged bool to true so that the cert will
  842. // get refreshed in the display. this doesn't hurt anything even
  843. // if the cert didn't change
  844. //
  845. fPropertiesChanged = TRUE;
  846. }
  847. else
  848. {
  849. memset(&cvps, 0, sizeof(CRYPTUI_VIEWCERTIFICATE_STRUCTW));
  850. cvps.dwSize = sizeof(CRYPTUI_VIEWCERTIFICATE_STRUCTW);
  851. cvps.hwndParent = hwndDlg;
  852. cvps.pCertContext = (PCCERT_CONTEXT) lvI.lParam;
  853. cvps.cStores = pviewhelp->pcsc->cStores;
  854. cvps.rghStores = pviewhelp->pcsc->rghStores;
  855. cvps.cPropSheetPages = pviewhelp->pcsc->cPropSheetPages;
  856. cvps.rgPropSheetPages = pviewhelp->pcsc->rgPropSheetPages;
  857. CryptUIDlgViewCertificateW(&cvps, &fPropertiesChanged);
  858. }
  859. //
  860. // if the properties changed then refresh the cert in the list
  861. //
  862. if (fPropertiesChanged)
  863. {
  864. ListView_DeleteItem(hWndListView, listIndex);
  865. AddCertToList(hWndListView, pviewhelp, (PCCERT_CONTEXT) lvI.lParam, listIndex);
  866. ListView_SetItemState(hWndListView, listIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  867. }
  868. if (!pviewhelp->fCertListDblClick)
  869. {
  870. SetFocus(GetDlgItem(hwndDlg, IDC_SELECTCERT_VIEWCERT_BUTTON));
  871. }
  872. pviewhelp->fCertListDblClick = FALSE;
  873. }
  874. }
  875. break;
  876. case IDOK:
  877. listIndex = ListView_GetNextItem(
  878. hWndListView,
  879. -1,
  880. LVNI_SELECTED
  881. );
  882. if (listIndex != -1)
  883. {
  884. memset(&lvI, 0, sizeof(lvI));
  885. lvI.iItem = listIndex;
  886. lvI.mask = LVIF_PARAM;
  887. if (!(pcsc->dwFlags & CRYPTUI_SELECTCERT_MULTISELECT))
  888. {
  889. if (ListView_GetItemU(hWndListView, &lvI))
  890. {
  891. pviewhelp->pSelectedCert = CertDuplicateCertificateContext((PCCERT_CONTEXT) lvI.lParam);
  892. }
  893. }
  894. else
  895. {
  896. if (ListView_GetItemU(hWndListView, &lvI))
  897. {
  898. CertAddCertificateContextToStore(
  899. pcsc->hSelectedCertStore,
  900. (PCCERT_CONTEXT) lvI.lParam,
  901. CERT_STORE_ADD_ALWAYS,
  902. NULL);
  903. }
  904. while (-1 != (listIndex = ListView_GetNextItem(
  905. hWndListView,
  906. listIndex,
  907. LVNI_SELECTED
  908. )))
  909. {
  910. lvI.iItem = listIndex;
  911. if (ListView_GetItemU(hWndListView, &lvI))
  912. {
  913. CertAddCertificateContextToStore(
  914. pcsc->hSelectedCertStore,
  915. (PCCERT_CONTEXT) lvI.lParam,
  916. CERT_STORE_ADD_ALWAYS,
  917. NULL);
  918. }
  919. }
  920. }
  921. }
  922. else
  923. {
  924. LoadStringU(HinstDll, IDS_SELECT_CERT_ERROR, errorString, ARRAYSIZE(errorString));
  925. if (pcsc->szTitle != NULL)
  926. {
  927. MessageBoxU(hwndDlg, errorString, pcsc->szTitle, MB_OK | MB_ICONWARNING);
  928. }
  929. else
  930. {
  931. LoadStringU(HinstDll, IDS_SELECT_CERTIFICATE_TITLE, errorTitle, ARRAYSIZE(errorTitle));
  932. MessageBoxU(hwndDlg, errorString, errorTitle, MB_OK | MB_ICONWARNING);
  933. }
  934. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)TRUE);
  935. return TRUE;
  936. }
  937. EndDialog(hwndDlg, NULL);
  938. break;
  939. case IDCANCEL:
  940. EndDialog(hwndDlg, NULL);
  941. break;
  942. }
  943. break;
  944. case WM_DESTROY:
  945. pviewhelp = (PCERT_SELECT_HELPER) GetWindowLongPtr(hwndDlg, DWLP_USER);
  946. hWndListView = GetDlgItem(hwndDlg, IDC_SELECTCERT_CERTLIST);
  947. memset(&lvI, 0, sizeof(lvI));
  948. lvI.iItem = ListView_GetItemCount(hWndListView) - 1;
  949. lvI.mask = LVIF_PARAM;
  950. while (lvI.iItem >= 0)
  951. {
  952. if (ListView_GetItemU(hWndListView, &lvI))
  953. {
  954. CertFreeCertificateContext((PCCERT_CONTEXT) lvI.lParam);
  955. }
  956. lvI.iItem--;
  957. }
  958. break;
  959. case WM_HELP:
  960. case WM_CONTEXTMENU:
  961. if (msg == WM_HELP)
  962. {
  963. hwnd = GetDlgItem(hwndDlg, ((LPHELPINFO)lParam)->iCtrlId);
  964. }
  965. else
  966. {
  967. hwnd = (HWND) wParam;
  968. }
  969. if ((hwnd != GetDlgItem(hwndDlg, IDOK)) &&
  970. (hwnd != GetDlgItem(hwndDlg, IDCANCEL)) &&
  971. (hwnd != GetDlgItem(hwndDlg, IDC_SELECTCERT_VIEWCERT_BUTTON)) &&
  972. (hwnd != GetDlgItem(hwndDlg, IDC_SELECTCERT_CERTLIST)))
  973. {
  974. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)TRUE);
  975. return TRUE;
  976. }
  977. else
  978. {
  979. return OnContextHelp(hwndDlg, msg, wParam, lParam, helpmap);
  980. }
  981. }
  982. return FALSE;
  983. }
  984. //////////////////////////////////////////////////////////////////////////////////////
  985. //
  986. //////////////////////////////////////////////////////////////////////////////////////
  987. PCCERT_CONTEXT
  988. WINAPI
  989. CryptUIDlgSelectCertificateW(
  990. PCCRYPTUI_SELECTCERTIFICATE_STRUCTW pcsc
  991. )
  992. {
  993. CERT_SELECT_HELPER viewhelper;
  994. WORD wDialogID;
  995. if (CommonInit() == FALSE)
  996. {
  997. return NULL;
  998. }
  999. if ((pcsc->dwSize != sizeof(CRYPTUI_SELECTCERTIFICATE_STRUCTW)) &&
  1000. (pcsc->dwSize != offsetof(CRYPTUI_SELECTCERTIFICATE_STRUCTW, hSelectedCertStore))) {
  1001. SetLastError(E_INVALIDARG);
  1002. return FALSE;
  1003. }
  1004. wDialogID =
  1005. pcsc->dwFlags & CRYPTUI_SELECTCERT_ADDFROMDS ?
  1006. IDD_SELECTCERT_DIALOG_WITH_DSPICKER :
  1007. IDD_SELECTCERT_DIALOG;
  1008. viewhelper.pcsc = pcsc;
  1009. viewhelper.pSelectedCert = NULL;
  1010. viewhelper.fCertListDblClick = FALSE;
  1011. viewhelper.pCertsFromDS = new CertContextList;
  1012. if (NULL == viewhelper.pCertsFromDS)
  1013. {
  1014. SetLastError(E_OUTOFMEMORY);
  1015. return FALSE;
  1016. }
  1017. if (DialogBoxParamU(
  1018. HinstDll,
  1019. (LPWSTR) MAKEINTRESOURCE(wDialogID),
  1020. (pcsc->hwndParent != NULL) ? pcsc->hwndParent : GetDesktopWindow(),
  1021. SelectCertDialogProc,
  1022. (LPARAM) &viewhelper) != -1)
  1023. {
  1024. SetLastError(0);
  1025. }
  1026. delete viewhelper.pCertsFromDS;
  1027. if (pcsc->dwFlags & CRYPTUI_SELECTCERT_MULTISELECT)
  1028. {
  1029. return NULL;
  1030. }
  1031. else
  1032. {
  1033. return(viewhelper.pSelectedCert);
  1034. }
  1035. }
  1036. //////////////////////////////////////////////////////////////////////////////////////
  1037. //
  1038. //////////////////////////////////////////////////////////////////////////////////////
  1039. PCCERT_CONTEXT
  1040. WINAPI
  1041. CryptUIDlgSelectCertificateA(
  1042. PCCRYPTUI_SELECTCERTIFICATE_STRUCTA pcsc
  1043. )
  1044. {
  1045. CRYPTUI_SELECTCERTIFICATE_STRUCTW cscW;
  1046. PCCERT_CONTEXT pReturnCert = NULL;
  1047. memcpy(&cscW, pcsc, sizeof(cscW));
  1048. if (!ConvertToPropPageW(
  1049. pcsc->rgPropSheetPages,
  1050. pcsc->cPropSheetPages,
  1051. &(cscW.rgPropSheetPages)))
  1052. {
  1053. return NULL;
  1054. }
  1055. if (pcsc->szTitle)
  1056. {
  1057. cscW.szTitle = CertUIMkWStr(pcsc->szTitle);
  1058. }
  1059. if (pcsc->szDisplayString)
  1060. {
  1061. cscW.szDisplayString = CertUIMkWStr(pcsc->szDisplayString);
  1062. }
  1063. pReturnCert = CryptUIDlgSelectCertificateW(&cscW);
  1064. FreePropSheetPagesW((LPPROPSHEETPAGEW) cscW.rgPropSheetPages, cscW.cPropSheetPages);
  1065. if (cscW.szTitle)
  1066. {
  1067. free((void *) cscW.szTitle);
  1068. }
  1069. if (cscW.szDisplayString)
  1070. {
  1071. free((void *) cscW.szDisplayString);
  1072. }
  1073. return(pReturnCert);
  1074. }
  1075. ////////////////////////////////////////////////////////////
  1076. //
  1077. // Implementation of utility class: CertContextList
  1078. //
  1079. ////////////////////////////////////////////////////////////
  1080. CertContextList::~CertContextList()
  1081. {
  1082. CertContextListEle *pListEle;
  1083. CertContextListEle *pListEleNext;
  1084. for (pListEle = m_head; pListEle != NULL; pListEle = pListEleNext)
  1085. {
  1086. pListEleNext = pListEle->pNext;
  1087. if (pListEle->pCertContext != NULL) { CertFreeCertificateContext(pListEle->pCertContext); }
  1088. delete pListEle;
  1089. }
  1090. }
  1091. HRESULT CertContextList::Add(IN PCCERT_CONTEXT pCertContext,
  1092. OUT BOOL *pfReplacedExisting)
  1093. {
  1094. HRESULT hr = S_OK;
  1095. CertContextListEle *pListEle = NULL;
  1096. CertContextListEle *pListElePrev = NULL;
  1097. if (pCertContext == NULL || pfReplacedExisting == NULL)
  1098. return E_INVALIDARG;
  1099. for (pListEle = m_head; pListEle != NULL; pListEle = pListEle->pNext)
  1100. {
  1101. PCCERT_CONTEXT pCurrent = pListEle->pCertContext;
  1102. if (pCurrent->dwCertEncodingType == pCertContext->dwCertEncodingType)
  1103. {
  1104. if (CertCompareCertificate
  1105. (pCertContext->dwCertEncodingType,
  1106. pCertContext->pCertInfo,
  1107. pCurrent->pCertInfo))
  1108. {
  1109. // We're replacing an existing element.
  1110. *pfReplacedExisting = TRUE;
  1111. CertFreeCertificateContext(pListEle->pCertContext);
  1112. pListEle->pCertContext = CertDuplicateCertificateContext(pCertContext);
  1113. goto CommonReturn;
  1114. }
  1115. }
  1116. pListElePrev = pListEle;
  1117. }
  1118. // Didn't find the cert in the list, append it.
  1119. if (pListElePrev == NULL)
  1120. {
  1121. // Special case: this is the first cert we've added.
  1122. pListElePrev = new CertContextListEle;
  1123. if (pListElePrev == NULL)
  1124. goto MemoryErr;
  1125. pListEle = pListElePrev;
  1126. m_head = pListEle;
  1127. }
  1128. else
  1129. {
  1130. pListElePrev->pNext = new CertContextListEle;
  1131. if (pListElePrev->pNext == NULL)
  1132. goto MemoryErr;
  1133. pListEle = pListElePrev->pNext;
  1134. }
  1135. pListEle->pCertContext = CertDuplicateCertificateContext(pCertContext);
  1136. pListEle->pNext = NULL;
  1137. CommonReturn:
  1138. return hr;
  1139. MemoryErr:
  1140. hr = E_OUTOFMEMORY;
  1141. goto CommonReturn;
  1142. }
  1143. HRESULT CertContextList::SyncWithStore(HCERTSTORE hStore, DWORD dwFlags)
  1144. {
  1145. CertContextListEle * pListEle;
  1146. for (pListEle = m_head; pListEle != NULL; pListEle = pListEle->pNext)
  1147. {
  1148. if (!CertAddCertificateContextToStore
  1149. (hStore,
  1150. pListEle->pCertContext,
  1151. dwFlags,
  1152. NULL))
  1153. return HRESULT_FROM_WIN32(GetLastError());
  1154. }
  1155. return S_OK;
  1156. }