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.

3920 lines
125 KiB

  1. //-------------------------------------------------------------
  2. // Copyright (C) Microsoft Corporation, 1996 - 1999
  3. //
  4. // File: mgrcert.cpp
  5. //
  6. // Contents: The cpp file to implement cert mgr dialogue
  7. //
  8. // History: Feb-26-98 xiaohs created
  9. //
  10. //--------------------------------------------------------------
  11. #include "wzrdpvk.h"
  12. #include "winuser.h" //need this file for VK_DELETE
  13. #include "mgrcert.h"
  14. //context sensitive help for the main dialogue
  15. static const HELPMAP CertMgrMainHelpMap[] = {
  16. {IDC_CERTMGR_LIST, IDH_CERTMGR_LIST},
  17. {IDC_CERTMGR_PURPOSE_COMBO, IDH_CERTMGR_PURPOSE_COMBO},
  18. {IDC_CERTMGR_IMPORT, IDH_CERTMGR_IMPORT},
  19. {IDC_CERTMGR_EXPORT, IDH_CERTMGR_EXPORT},
  20. {IDC_CERTMGR_VIEW, IDH_CERTMGR_VIEW},
  21. {IDC_CERTMGR_REMOVE, IDH_CERTMGR_REMOVE},
  22. {IDC_CERTMGR_ADVANCE, IDH_CERTMGR_ADVANCE},
  23. {IDC_CERTMGR_PURPOSE, IDH_CERTMGR_FIELD_PURPOSE},
  24. };
  25. //context sensitive help for the main dialogue
  26. static const HELPMAP CertMgrAdvHelpMap[] = {
  27. {IDC_CERTMGR_ADV_LIST, IDH_CERTMGR_ADV_LIST},
  28. {IDC_CERTMGR_EXPORT_COMBO, IDH_CERTMGR_EXPORT_COMBO},
  29. {IDC_CERTMGR_EXPORT_CHECK, IDH_CERTMGR_EXPORT_CHECK},
  30. };
  31. // Primary store associated with each tab. Store to be imported into.
  32. static const LPCWSTR rgpwszTabStoreName[] = {
  33. L"My", // 0
  34. L"AddressBook", // 1
  35. L"Ca", // 2
  36. L"Root", // 3
  37. L"TrustedPublisher", // 4
  38. };
  39. #define TAB_STORE_NAME_CNT (sizeof(rgpwszTabStoreName) / \
  40. sizeof(rgpwszTabStoreName[0]))
  41. /*
  42. // The following code is obsolete due to new cert chain building code
  43. //----------------------------------------------------------------------------
  44. // AddCertChainToStore
  45. //----------------------------------------------------------------------------
  46. BOOL AddCertChainToStore(HCERTSTORE hStore,
  47. PCCERT_CONTEXT pCertContext)
  48. {
  49. BOOL fResult=FALSE;
  50. HCERTSTORE rghCertStores[20];
  51. DWORD chStores;
  52. PCCERT_CONTEXT pChildCert;
  53. PCCERT_CONTEXT pParentCert;
  54. FILETIME fileTime;
  55. DWORD i;
  56. if(!hStore || !pCertContext)
  57. goto InvalidArgErr;
  58. GetSystemTimeAsFileTime(&fileTime);
  59. if (!TrustOpenStores(NULL, &chStores, rghCertStores, 0))
  60. goto TraceErr;
  61. pChildCert = pCertContext;
  62. while (NULL != (pParentCert = TrustFindIssuerCertificate(
  63. pChildCert,
  64. pChildCert->dwCertEncodingType,
  65. chStores,
  66. rghCertStores,
  67. &fileTime,
  68. NULL,
  69. NULL,
  70. 0)))
  71. {
  72. CertAddCertificateContextToStore(hStore, pParentCert, CERT_STORE_ADD_NEW, NULL);
  73. if (pChildCert != pCertContext)
  74. {
  75. CertFreeCertificateContext(pChildCert);
  76. }
  77. pChildCert = pParentCert;
  78. }
  79. if (pChildCert != pCertContext)
  80. {
  81. CertFreeCertificateContext(pChildCert);
  82. }
  83. for (i=0; i<chStores; i++)
  84. {
  85. CertCloseStore(rghCertStores[i], 0);
  86. }
  87. fResult=TRUE;
  88. CommonReturn:
  89. return fResult;
  90. ErrorReturn:
  91. fResult=FALSE;
  92. goto CommonReturn;
  93. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  94. TRACE_ERROR(TraceErr);
  95. } */
  96. int WINAPI TabCtrl_InsertItemU(
  97. HWND hwnd,
  98. int iItem,
  99. const LPTCITEMW pitem
  100. )
  101. {
  102. TCITEMA TCItemA;
  103. int iRet;
  104. DWORD cb = 0;
  105. if (FIsWinNT())
  106. {
  107. return ((int)SendMessage(hwnd, TCM_INSERTITEMW, iItem, (LPARAM) pitem));
  108. }
  109. memcpy(&TCItemA, pitem, sizeof(TCITEMA));
  110. cb = WideCharToMultiByte(
  111. 0, // codepage
  112. 0, // dwFlags
  113. pitem->pszText,
  114. -1,
  115. NULL,
  116. 0,
  117. NULL,
  118. NULL);
  119. if ((0 == cb) || (NULL == (TCItemA.pszText = (LPSTR) WizardAlloc(cb))))
  120. {
  121. return -1; // this is the unsuccessful return code for this call
  122. }
  123. if( 0 == (WideCharToMultiByte(
  124. 0,
  125. 0,
  126. pitem->pszText,
  127. -1,
  128. TCItemA.pszText,
  129. cb,
  130. NULL,
  131. NULL)))
  132. {
  133. WizardFree(TCItemA.pszText);
  134. return -1;
  135. }
  136. iRet = (int)SendMessage(hwnd, TCM_INSERTITEMA, iItem, (LPARAM) &TCItemA);
  137. WizardFree(TCItemA.pszText);
  138. return iRet;
  139. }
  140. //----------------------------------------------------------------------------
  141. // This is the rundll32 entry point for start menu, administartive tools,
  142. // CertMgr.
  143. //----------------------------------------------------------------------------
  144. STDAPI CryptUIStartCertMgr(HINSTANCE hinst, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
  145. {
  146. CRYPTUI_CERT_MGR_STRUCT CertMgrStruct;
  147. memset(&CertMgrStruct, 0, sizeof(CRYPTUI_CERT_MGR_STRUCT));
  148. CertMgrStruct.dwSize=sizeof(CRYPTUI_CERT_MGR_STRUCT);
  149. CryptUIDlgCertMgr(&CertMgrStruct);
  150. return S_OK;
  151. }
  152. //----------------------------------------------------------------------------
  153. // GetFileContentFromCert
  154. //----------------------------------------------------------------------------
  155. BOOL GetFileContentFromCert(DWORD dwExportFormat,
  156. BOOL fExportChain,
  157. PCCERT_CONTEXT pCertContext,
  158. BYTE **ppBlob,
  159. DWORD *pdwSize)
  160. {
  161. BOOL fResult=FALSE;
  162. void *pData=NULL;
  163. DWORD dwSize=0;
  164. HCERTSTORE hMemoryStore=NULL;
  165. CRYPT_DATA_BLOB Blob;
  166. HRESULT hr=E_INVALIDARG;
  167. if(!ppBlob || !pdwSize || !pCertContext)
  168. goto InvalidArgErr;
  169. *ppBlob=NULL;
  170. *pdwSize=0;
  171. switch(dwExportFormat)
  172. {
  173. case CRYPTUI_WIZ_EXPORT_FORMAT_DER:
  174. dwSize=pCertContext->cbCertEncoded;
  175. pData=WizardAlloc(dwSize);
  176. if(!pData)
  177. goto MemoryErr;
  178. memcpy(pData, pCertContext->pbCertEncoded, dwSize);
  179. break;
  180. case CRYPTUI_WIZ_EXPORT_FORMAT_BASE64:
  181. //base 64 encode the BLOB
  182. if(!CryptBinaryToStringA(
  183. pCertContext->pbCertEncoded,
  184. pCertContext->cbCertEncoded,
  185. CRYPT_STRING_BASE64,
  186. NULL,
  187. &dwSize))
  188. {
  189. hr = GetLastError();
  190. goto SetErrVar;
  191. }
  192. pData=WizardAlloc(dwSize * sizeof(CHAR));
  193. if(!pData)
  194. goto MemoryErr;
  195. if(!CryptBinaryToStringA(
  196. pCertContext->pbCertEncoded,
  197. pCertContext->cbCertEncoded,
  198. CRYPT_STRING_BASE64,
  199. (char *)pData,
  200. &dwSize))
  201. {
  202. hr = GetLastError();
  203. goto SetErrVar;
  204. }
  205. break;
  206. case CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7:
  207. //open a memory store
  208. hMemoryStore=CertOpenStore(
  209. CERT_STORE_PROV_MEMORY,
  210. g_dwMsgAndCertEncodingType,
  211. NULL,
  212. 0,
  213. NULL);
  214. if(!hMemoryStore)
  215. goto TraceErr;
  216. if(FALSE == fExportChain)
  217. {
  218. if(!CertAddCertificateContextToStore(
  219. hMemoryStore,
  220. pCertContext,
  221. CERT_STORE_ADD_REPLACE_EXISTING,
  222. NULL))
  223. goto TraceErr;
  224. }
  225. else
  226. {
  227. if(!AddChainToStore(
  228. hMemoryStore,
  229. pCertContext,
  230. 0,
  231. NULL,
  232. FALSE,
  233. NULL))
  234. goto TraceErr;
  235. }
  236. //save the store to a PKCS#7
  237. Blob.cbData=0;
  238. Blob.pbData=NULL;
  239. if(!CertSaveStore(hMemoryStore,
  240. g_dwMsgAndCertEncodingType,
  241. CERT_STORE_SAVE_AS_PKCS7,
  242. CERT_STORE_SAVE_TO_MEMORY,
  243. &Blob,
  244. 0))
  245. goto TraceErr;
  246. dwSize=Blob.cbData;
  247. pData=WizardAlloc(dwSize);
  248. if(!pData)
  249. goto MemoryErr;
  250. Blob.pbData=(BYTE *)pData;
  251. if(!CertSaveStore(hMemoryStore,
  252. g_dwMsgAndCertEncodingType,
  253. CERT_STORE_SAVE_AS_PKCS7,
  254. CERT_STORE_SAVE_TO_MEMORY,
  255. &Blob,
  256. 0))
  257. goto TraceErr;
  258. break;
  259. default:
  260. goto InvalidArgErr;
  261. break;
  262. }
  263. //set up the return value
  264. *pdwSize=dwSize;
  265. *ppBlob=(BYTE *)pData;
  266. pData=NULL;
  267. fResult=TRUE;
  268. CommonReturn:
  269. if(hMemoryStore)
  270. CertCloseStore(hMemoryStore, 0);
  271. return fResult;
  272. ErrorReturn:
  273. if(pData)
  274. WizardFree(pData);
  275. fResult=FALSE;
  276. goto CommonReturn;
  277. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  278. SET_ERROR(MemoryErr, E_OUTOFMEMORY);
  279. SET_ERROR_VAR(SetErrVar, hr);
  280. TRACE_ERROR(TraceErr);
  281. }
  282. //----------------------------------------------------------------------------
  283. // FreeFileNameAndContent
  284. //----------------------------------------------------------------------------
  285. BOOL FreeFileNameAndContent( DWORD dwCount,
  286. LPWSTR *prgwszFileName,
  287. BYTE **prgBlob,
  288. DWORD *prgdwSize)
  289. {
  290. DWORD dwIndex=0;
  291. if(prgwszFileName)
  292. {
  293. for(dwIndex=0; dwIndex < dwCount; dwIndex++)
  294. {
  295. if(prgwszFileName[dwIndex])
  296. WizardFree(prgwszFileName[dwIndex]);
  297. }
  298. WizardFree(prgwszFileName);
  299. }
  300. if(prgBlob)
  301. {
  302. for(dwIndex=0; dwIndex < dwCount; dwIndex++)
  303. {
  304. if(prgBlob[dwIndex])
  305. WizardFree(prgBlob[dwIndex]);
  306. }
  307. WizardFree(prgBlob);
  308. }
  309. if(prgdwSize)
  310. WizardFree(prgdwSize);
  311. return TRUE;
  312. }
  313. //----------------------------------------------------------------------------
  314. // Get a valid friendly name of the certificate
  315. //----------------------------------------------------------------------------
  316. BOOL GetValidFriendlyName(PCCERT_CONTEXT pCertContext,
  317. LPWSTR *ppwszName)
  318. {
  319. BOOL fResult=FALSE;
  320. DWORD dwChar=0;
  321. LPWSTR pwsz=NULL;
  322. DWORD dwIndex=0;
  323. if(!pCertContext || !ppwszName)
  324. return FALSE;
  325. //init
  326. *ppwszName=NULL;
  327. dwChar=0;
  328. if(CertGetCertificateContextProperty(
  329. pCertContext,
  330. CERT_FRIENDLY_NAME_PROP_ID,
  331. NULL,
  332. &dwChar) && (0!=dwChar))
  333. {
  334. pwsz=(LPWSTR)WizardAlloc(dwChar * sizeof(WCHAR));
  335. if(pwsz)
  336. {
  337. CertGetCertificateContextProperty(
  338. pCertContext,
  339. CERT_FRIENDLY_NAME_PROP_ID,
  340. pwsz,
  341. &dwChar);
  342. }
  343. }
  344. if(NULL==pwsz)
  345. goto CLEANUP;
  346. //make sure pwsz is a valid name
  347. if(0 == (dwChar=wcslen(pwsz)))
  348. goto CLEANUP;
  349. //the friendly name can not be spaces all the time
  350. for(dwIndex=0; dwIndex<dwChar; dwIndex++)
  351. {
  352. if(L' '!=pwsz[dwIndex])
  353. break;
  354. }
  355. if(dwIndex==dwChar)
  356. goto CLEANUP;
  357. *ppwszName=WizardAllocAndCopyWStr(pwsz);
  358. if(NULL == (*ppwszName))
  359. goto CLEANUP;
  360. fResult=TRUE;
  361. CLEANUP:
  362. if(pwsz)
  363. WizardFree(pwsz);
  364. return fResult;
  365. }
  366. //----------------------------------------------------------------------------
  367. // InvalidFileNameWch
  368. //----------------------------------------------------------------------------
  369. BOOL InvalidFileNameWch(WCHAR wChar)
  370. {
  371. if((wChar == L'\\') || (wChar == L':') || (wChar == L'/') || (wChar == L'*') || (wChar == L'|') || (wChar == L';'))
  372. return TRUE;
  373. return FALSE;
  374. }
  375. //----------------------------------------------------------------------------
  376. // Build the filenames and their content based on the export selection
  377. //----------------------------------------------------------------------------
  378. BOOL GetFileNameFromCert(DWORD dwExportFormat,
  379. PCCERT_CONTEXT pCertContext,
  380. LPWSTR pwszFileName)
  381. {
  382. BOOL fResult=FALSE;
  383. WCHAR wszCertificate[MAX_TITLE_LENGTH];
  384. WCHAR wszExt[MAX_TITLE_LENGTH];
  385. LPWSTR pwszName=NULL;
  386. DWORD dwChar=0;
  387. UINT idsExt=0;
  388. LPWSTR pwszFirstPart=NULL;
  389. LPWSTR pwszFriendlyName=NULL;
  390. DWORD dwIndex=0;
  391. if(!pCertContext || !pwszFileName)
  392. goto InvalidArgErr;
  393. //init
  394. *pwszFileName='\0';
  395. //get the friendly name for the certificate
  396. if(!GetValidFriendlyName(pCertContext,&pwszFriendlyName))
  397. {
  398. //if failed, we use subject
  399. //Subject
  400. dwChar=CertGetNameStringW(
  401. pCertContext,
  402. CERT_NAME_SIMPLE_DISPLAY_TYPE,
  403. 0,
  404. NULL,
  405. NULL,
  406. 0);
  407. if ((dwChar > 1) && (NULL != (pwszName = (LPWSTR)WizardAlloc(dwChar * sizeof(WCHAR)))))
  408. {
  409. if(!CertGetNameStringW(
  410. pCertContext,
  411. CERT_NAME_SIMPLE_DISPLAY_TYPE,
  412. 0,
  413. NULL,
  414. pwszName,
  415. dwChar))
  416. goto GetNameErr;
  417. pwszFirstPart=pwszName;
  418. }
  419. else
  420. {
  421. //load the string for Certificate
  422. if(!LoadStringU(g_hmodThisDll, IDS_CERTIFICATE, wszCertificate, MAX_TITLE_LENGTH))
  423. goto LoadStringErr;
  424. pwszFirstPart=wszCertificate;
  425. }
  426. }
  427. else
  428. pwszFirstPart=pwszFriendlyName;
  429. //determine the extension for the file
  430. switch(dwExportFormat)
  431. {
  432. case CRYPTUI_WIZ_EXPORT_FORMAT_DER:
  433. idsExt=IDS_CER;
  434. break;
  435. case CRYPTUI_WIZ_EXPORT_FORMAT_BASE64:
  436. idsExt=IDS_CER;
  437. break;
  438. case CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7:
  439. idsExt=IDS_P7C;
  440. break;
  441. default:
  442. idsExt=IDS_CER;
  443. break;
  444. }
  445. //load the string for Certificate
  446. if(!LoadStringU(g_hmodThisDll, idsExt, wszExt, MAX_TITLE_LENGTH))
  447. goto LoadStringErr;
  448. //determine the max length of the file name
  449. dwChar = wcslen(pwszFirstPart) > (CERTMGR_MAX_FILE_NAME - wcslen(wszExt) -1) ?
  450. (CERTMGR_MAX_FILE_NAME - wcslen(wszExt) -1) : wcslen(pwszFirstPart);
  451. wcsncpy(pwszFileName, pwszFirstPart, dwChar);
  452. *(pwszFileName + dwChar)=L'\0';
  453. wcscat(pwszFileName, wszExt);
  454. //now, we replace the invalid file characters : ; / \
  455. //with space
  456. dwChar = wcslen(pwszFileName);
  457. for(dwIndex =0; dwIndex<dwChar; dwIndex++)
  458. {
  459. if(InvalidFileNameWch(pwszFileName[dwIndex]))
  460. pwszFileName[dwIndex]=L'_';
  461. }
  462. fResult=TRUE;
  463. CommonReturn:
  464. if(pwszName)
  465. WizardFree(pwszName);
  466. if(pwszFriendlyName)
  467. WizardFree(pwszFriendlyName);
  468. return fResult;
  469. ErrorReturn:
  470. fResult=FALSE;
  471. goto CommonReturn;
  472. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  473. TRACE_ERROR(GetNameErr);
  474. TRACE_ERROR(LoadStringErr);
  475. }
  476. //----------------------------------------------------------------------------
  477. // Build the filenames and their content based on the export selection
  478. //----------------------------------------------------------------------------
  479. BOOL GetFileNameAndContent(LPNMLISTVIEW pvmn,
  480. HWND hwndControl,
  481. DWORD dwExportFormat,
  482. BOOL fExportChain,
  483. DWORD *pdwCount,
  484. LPWSTR **pprgwszFileName,
  485. BYTE ***pprgBlob,
  486. DWORD **pprgdwSize)
  487. {
  488. BOOL fResult=FALSE;
  489. DWORD dwCount=0;
  490. DWORD dwIndex=0;
  491. LVITEM lvItem;
  492. int iIndex=0;
  493. PCCERT_CONTEXT pCertContext=NULL;
  494. if(!pvmn || !hwndControl || !pdwCount || !pprgwszFileName || !pprgBlob || !pprgdwSize)
  495. goto InvalidArgErr;
  496. //init
  497. *pdwCount=0;
  498. *pprgwszFileName=NULL;
  499. *pprgBlob=NULL;
  500. *pprgdwSize=NULL;
  501. //get the count of selected certificates
  502. dwCount=ListView_GetSelectedCount(hwndControl);
  503. if( 0 == dwCount)
  504. goto InvalidArgErr;
  505. //allocate memory
  506. if((*pprgwszFileName)=(LPWSTR *)WizardAlloc(sizeof(LPWSTR) * dwCount))
  507. memset(*pprgwszFileName, 0, sizeof(LPWSTR) * dwCount);
  508. if((*pprgBlob)=(BYTE **)WizardAlloc(sizeof(BYTE *)* dwCount))
  509. memset(*pprgBlob, 0, sizeof(BYTE *)* dwCount);
  510. if((*pprgdwSize)=(DWORD *)WizardAlloc(sizeof(DWORD) * dwCount))
  511. memset(*pprgdwSize, 0, sizeof(DWORD) * dwCount);
  512. if(!(*pprgwszFileName) || !(*pprgBlob) || !(*pprgdwSize))
  513. goto MemoryErr;
  514. //get the selected certificate
  515. memset(&lvItem, 0, sizeof(LV_ITEM));
  516. lvItem.mask=LVIF_PARAM;
  517. iIndex=-1;
  518. for(dwIndex=0; dwIndex < dwCount; dwIndex++)
  519. {
  520. iIndex=ListView_GetNextItem(hwndControl,
  521. iIndex,
  522. LVNI_SELECTED);
  523. if(-1 == iIndex)
  524. break;
  525. lvItem.iItem=iIndex;
  526. if(!ListView_GetItem(hwndControl,
  527. &lvItem))
  528. goto ListViewErr;
  529. pCertContext=(PCCERT_CONTEXT)(lvItem.lParam);
  530. if(!pCertContext)
  531. goto InvalidArgErr;
  532. //get the file name of the ceritificate
  533. (*pprgwszFileName)[dwIndex]=(LPWSTR)WizardAlloc(sizeof(WCHAR) * CERTMGR_MAX_FILE_NAME);
  534. if(!((*pprgwszFileName)[dwIndex]))
  535. goto MemoryErr;
  536. if(!GetFileNameFromCert(dwExportFormat,
  537. pCertContext,
  538. (*pprgwszFileName)[dwIndex]))
  539. goto TraceErr;
  540. //get the BLOB for the certificate
  541. if(!GetFileContentFromCert(dwExportFormat, fExportChain, pCertContext,
  542. &((*pprgBlob)[dwIndex]),
  543. &((*pprgdwSize)[dwIndex])))
  544. goto TraceErr;
  545. }
  546. *pdwCount=dwIndex;
  547. fResult=TRUE;
  548. CommonReturn:
  549. return fResult;
  550. ErrorReturn:
  551. if(pdwCount && pprgwszFileName && pprgBlob && pprgdwSize)
  552. {
  553. FreeFileNameAndContent(*pdwCount, *pprgwszFileName, *pprgBlob, *pprgdwSize);
  554. *pdwCount=0;
  555. *pprgwszFileName=NULL;
  556. *pprgBlob=NULL;
  557. *pprgdwSize=NULL;
  558. }
  559. fResult=FALSE;
  560. goto CommonReturn;
  561. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  562. SET_ERROR(MemoryErr, E_OUTOFMEMORY);
  563. TRACE_ERROR(ListViewErr);
  564. TRACE_ERROR(TraceErr);
  565. }
  566. //----------------------------------------------------------------------------
  567. // Get all the selected certificates and do some work vased on dwFlag
  568. //----------------------------------------------------------------------------
  569. BOOL GetAllSelectedItem(HWND hWndControl,
  570. DWORD dwFlag,
  571. void *pData)
  572. {
  573. BOOL fResult=FALSE;
  574. BOOL fCanDelete=TRUE;
  575. HCERTSTORE *phCertStore=NULL;
  576. PCCERT_CONTEXT pCertContext=NULL;
  577. int iIndex=0;
  578. LVITEM lvItem;
  579. DWORD dwData=0;
  580. DWORD dwAccessFlag=0;
  581. if(!hWndControl)
  582. goto CLEANUP;
  583. if((ALL_SELECTED_CAN_DELETE == dwFlag) ||
  584. (ALL_SELECTED_COPY == dwFlag))
  585. {
  586. if(NULL == pData)
  587. goto CLEANUP;
  588. }
  589. //get the selected certificate
  590. memset(&lvItem, 0, sizeof(LV_ITEM));
  591. lvItem.mask=LVIF_PARAM;
  592. iIndex=-1;
  593. //loop through all the selected items
  594. while(-1 != (iIndex=ListView_GetNextItem(
  595. hWndControl,
  596. iIndex,
  597. LVNI_SELECTED
  598. )))
  599. {
  600. lvItem.iItem=iIndex;
  601. if(!ListView_GetItem(hWndControl,
  602. &lvItem))
  603. goto CLEANUP;
  604. pCertContext=(PCCERT_CONTEXT)(lvItem.lParam);
  605. if(!pCertContext)
  606. goto CLEANUP;
  607. switch(dwFlag)
  608. {
  609. case ALL_SELECTED_CAN_DELETE:
  610. dwData=sizeof(dwAccessFlag);
  611. //as far as one of the selected items can not be deleted,
  612. //the whole selection can not be deleted
  613. if( CertGetCertificateContextProperty(
  614. pCertContext,
  615. CERT_ACCESS_STATE_PROP_ID,
  616. &dwAccessFlag,
  617. &dwData))
  618. {
  619. if(0==(CERT_ACCESS_STATE_WRITE_PERSIST_FLAG & dwAccessFlag))
  620. fCanDelete=FALSE;
  621. }
  622. break;
  623. case ALL_SELECTED_DELETE:
  624. CertDeleteCertificateFromStore(
  625. CertDuplicateCertificateContext(pCertContext));
  626. break;
  627. case ALL_SELECTED_COPY:
  628. CertAddCertificateContextToStore(
  629. *((HCERTSTORE *)pData),
  630. pCertContext,
  631. CERT_STORE_ADD_ALWAYS,
  632. NULL);
  633. break;
  634. default:
  635. goto CLEANUP;
  636. break;
  637. }
  638. }
  639. //copy the can delete flag
  640. if(ALL_SELECTED_CAN_DELETE == dwFlag)
  641. *((BOOL *)pData)=fCanDelete;
  642. fResult=TRUE;
  643. CLEANUP:
  644. return fResult;
  645. }
  646. //----------------------------------------------------------------------------
  647. // Check to see if <advanced> is selected
  648. //----------------------------------------------------------------------------
  649. BOOL IsAdvancedSelected(HWND hwndDlg)
  650. {
  651. BOOL fSelected=FALSE;
  652. int iIndex=0;
  653. LPWSTR pwszOIDName=NULL;
  654. WCHAR wszText[MAX_STRING_SIZE];
  655. if(!hwndDlg)
  656. goto CLEANUP;
  657. //get the selected string from the combo box
  658. iIndex=(int)SendDlgItemMessage(hwndDlg, IDC_CERTMGR_PURPOSE_COMBO,
  659. CB_GETCURSEL, 0, 0);
  660. if(CB_ERR==iIndex)
  661. goto CLEANUP;
  662. //get the selected purpose name
  663. if(CB_ERR == SendDlgItemMessageU_GETLBTEXT(hwndDlg,
  664. IDC_CERTMGR_PURPOSE_COMBO,
  665. iIndex, &pwszOIDName))
  666. goto CLEANUP;
  667. //check to see if <advanced> is selected
  668. if(!LoadStringU(g_hmodThisDll, IDS_OID_ADVANCED,
  669. wszText, MAX_STRING_SIZE))
  670. goto CLEANUP;
  671. //check if advanced option is selected
  672. if(0 == _wcsicmp(pwszOIDName, wszText))
  673. fSelected=TRUE;
  674. CLEANUP:
  675. if(pwszOIDName)
  676. WizardFree(pwszOIDName);
  677. return fSelected;
  678. }
  679. //----------------------------------------------------------------------------
  680. // Update the window title based on the tab that user has selected
  681. //----------------------------------------------------------------------------
  682. BOOL RefreshWindowTitle(HWND hwndDlg,
  683. PCRYPTUI_CERT_MGR_STRUCT pCertMgrStruct)
  684. {
  685. BOOL fResult=FALSE;
  686. WCHAR wszTitle[MAX_TITLE_LENGTH];
  687. WCHAR wszText[MAX_TITLE_LENGTH];
  688. LPWSTR pwszTitle=NULL;
  689. LPWSTR pwszText=NULL;
  690. UINT ids=0;
  691. DWORD dwTabIndex=0;
  692. if(!hwndDlg || !pCertMgrStruct)
  693. goto CLEANUP;
  694. //get the string ids based on the tab selected
  695. if (pCertMgrStruct->dwFlags & CRYPTUI_CERT_MGR_SINGLE_TAB_FLAG)
  696. dwTabIndex = pCertMgrStruct->dwFlags & CRYPTUI_CERT_MGR_TAB_MASK;
  697. else if(-1 == (dwTabIndex=TabCtrl_GetCurSel(GetDlgItem(hwndDlg, IDC_CERTMGR_TAB))))
  698. goto CLEANUP;
  699. //open the correct store based on the tab selected
  700. switch (dwTabIndex)
  701. {
  702. case 0:
  703. ids=IDS_TAB_PERSONAL;
  704. break;
  705. case 1:
  706. ids=IDS_TAB_OTHER;
  707. break;
  708. case 2:
  709. ids=IDS_TAB_CA;
  710. break;
  711. case 3:
  712. ids=IDS_TAB_ROOT;
  713. break;
  714. case 4:
  715. ids=IDS_TAB_PUBLISHER;
  716. break;
  717. default:
  718. goto CLEANUP;
  719. break;
  720. }
  721. //load the string for tabs
  722. if(!LoadStringU(g_hmodThisDll, ids, wszText, MAX_TITLE_LENGTH))
  723. goto CLEANUP;
  724. //get the window string
  725. if(pCertMgrStruct->pwszTitle)
  726. pwszTitle=(LPWSTR)(pCertMgrStruct->pwszTitle);
  727. else
  728. {
  729. if(!LoadStringU(g_hmodThisDll, IDS_CERT_MGR_TITLE, wszTitle, MAX_TITLE_LENGTH))
  730. goto CLEANUP;
  731. pwszTitle=wszTitle;
  732. }
  733. pwszText=(LPWSTR)WizardAlloc(sizeof(WCHAR) * (
  734. wcslen(pwszTitle) + wcslen(wszText) + wcslen(L" - ") +1));
  735. if(!pwszText)
  736. goto CLEANUP;
  737. //concatenate the window title as: "Certifiate Manager - Personal"
  738. *pwszText=L'\0';
  739. wcscat(pwszText, pwszTitle);
  740. wcscat(pwszText, L" - ");
  741. wcscat(pwszText, wszText);
  742. //set the window text
  743. SetWindowTextU(hwndDlg, pwszText);
  744. fResult=TRUE;
  745. CLEANUP:
  746. if(pwszText)
  747. WizardFree(pwszText);
  748. return fResult;
  749. }
  750. //----------------------------------------------------------------------------
  751. // Check to see if the certificate's key usage is the same as
  752. // the one selected on the combo box
  753. //
  754. //----------------------------------------------------------------------------
  755. BOOL IsValidUsage(PCCERT_CONTEXT pCertContext,
  756. HWND hwndDlg,
  757. CERT_MGR_INFO *pCertMgrInfo)
  758. {
  759. BOOL fValidUsage=FALSE;
  760. int iIndex=0;
  761. LPWSTR pwszOIDName=NULL;
  762. LPSTR pszOID=NULL;
  763. WCHAR wszText[MAX_STRING_SIZE];
  764. BOOL fAdvanced=FALSE;
  765. DWORD dwIndex=0;
  766. DWORD dwAdvIndex=0;
  767. int cNumOID=0;
  768. LPSTR *rgOID=NULL;
  769. DWORD cbOID=0;
  770. //input check
  771. if(!pCertContext || !hwndDlg || !pCertMgrInfo)
  772. return FALSE;
  773. //get the selected string from the combo box
  774. iIndex=(int)SendDlgItemMessage(hwndDlg, IDC_CERTMGR_PURPOSE_COMBO,
  775. CB_GETCURSEL, 0, 0);
  776. if(CB_ERR==iIndex)
  777. goto CLEANUP;
  778. //get the selected purpose name
  779. if(CB_ERR == SendDlgItemMessageU_GETLBTEXT(hwndDlg,
  780. IDC_CERTMGR_PURPOSE_COMBO,
  781. iIndex, &pwszOIDName))
  782. goto CLEANUP;
  783. //check to see if <all> is selected
  784. if(!LoadStringU(g_hmodThisDll, IDS_OID_ALL,
  785. wszText, MAX_STRING_SIZE))
  786. goto CLEANUP;
  787. if(0 == _wcsicmp(pwszOIDName, wszText))
  788. {
  789. fValidUsage=TRUE;
  790. goto CLEANUP;
  791. }
  792. //check to see if <advanced> is selected
  793. if(!LoadStringU(g_hmodThisDll, IDS_OID_ADVANCED,
  794. wszText, MAX_STRING_SIZE))
  795. goto CLEANUP;
  796. //check if advanced option is selected
  797. if(0 == _wcsicmp(pwszOIDName, wszText))
  798. fAdvanced=TRUE;
  799. if(FALSE==fAdvanced)
  800. {
  801. //determin the OID for the selected usage name
  802. for(dwIndex=0; dwIndex<pCertMgrInfo->dwOIDInfo; dwIndex++)
  803. {
  804. if(0==_wcsicmp(pwszOIDName,
  805. (pCertMgrInfo->rgOIDInfo[dwIndex]).pwszName))
  806. pszOID=(pCertMgrInfo->rgOIDInfo[dwIndex]).pszOID;
  807. }
  808. //we are in trouble if we can not find the maching OID based on
  809. //the name selected
  810. if(NULL==pszOID)
  811. goto CLEANUP;
  812. }
  813. //get the certificate's list of usage OIDs
  814. //get the OIDs from the cert
  815. if(!CertGetValidUsages(
  816. 1,
  817. &pCertContext,
  818. &cNumOID,
  819. NULL,
  820. &cbOID))
  821. goto CLEANUP;
  822. rgOID=(LPSTR *)WizardAlloc(cbOID);
  823. if(NULL==rgOID)
  824. goto CLEANUP;
  825. if(!CertGetValidUsages(
  826. 1,
  827. &pCertContext,
  828. &cNumOID,
  829. rgOID,
  830. &cbOID))
  831. goto CLEANUP;
  832. //-1 means the certiifcate is good for everything
  833. if(-1==cNumOID)
  834. {
  835. fValidUsage=TRUE;
  836. goto CLEANUP;
  837. }
  838. //we need to decide if the certificate include the selected
  839. //usage
  840. if(FALSE==fAdvanced)
  841. {
  842. for(dwIndex=0; dwIndex<(DWORD)cNumOID; dwIndex++)
  843. {
  844. if(0==_stricmp(pszOID,
  845. rgOID[dwIndex]))
  846. {
  847. fValidUsage=TRUE;
  848. goto CLEANUP;
  849. }
  850. }
  851. }
  852. else
  853. {
  854. //the certificates have to have advanced OIDs
  855. for(dwAdvIndex=0; dwAdvIndex<pCertMgrInfo->dwOIDInfo; dwAdvIndex++)
  856. {
  857. //only interested in the OIDs with advanced marked
  858. if(TRUE==(pCertMgrInfo->rgOIDInfo[dwAdvIndex]).fSelected)
  859. {
  860. for(dwIndex=0; dwIndex<(DWORD)cNumOID; dwIndex++)
  861. {
  862. if(0==_stricmp((pCertMgrInfo->rgOIDInfo[dwAdvIndex]).pszOID,
  863. rgOID[dwIndex]))
  864. {
  865. fValidUsage=TRUE;
  866. goto CLEANUP;
  867. }
  868. }
  869. }
  870. }
  871. }
  872. //now, we have examed all the possibilities
  873. fValidUsage=FALSE;
  874. CLEANUP:
  875. if(pwszOIDName)
  876. WizardFree(pwszOIDName);
  877. if(rgOID)
  878. WizardFree(rgOID);
  879. return fValidUsage;
  880. }
  881. //----------------------------------------------------------------------------
  882. // Check to see if the certificate is an end-entity cert
  883. //
  884. //----------------------------------------------------------------------------
  885. BOOL IsCertificateEndEntity(PCCERT_CONTEXT pCertContext)
  886. {
  887. PCERT_EXTENSION pCertExt=NULL;
  888. BOOL fEndEntity=FALSE;
  889. DWORD cbData=0;
  890. PCERT_BASIC_CONSTRAINTS_INFO pBasicInfo=NULL;
  891. PCERT_BASIC_CONSTRAINTS2_INFO pBasicInfo2=NULL;
  892. if(!pCertContext)
  893. return FALSE;
  894. //get the extension szOID_BASIC_CONSTRAINTS2
  895. pCertExt=CertFindExtension(
  896. szOID_BASIC_CONSTRAINTS2,
  897. pCertContext->pCertInfo->cExtension,
  898. pCertContext->pCertInfo->rgExtension);
  899. if(pCertExt)
  900. {
  901. //deocde the extension
  902. cbData=0;
  903. if(!CryptDecodeObject(
  904. X509_ASN_ENCODING,
  905. X509_BASIC_CONSTRAINTS2,
  906. pCertExt->Value.pbData,
  907. pCertExt->Value.cbData,
  908. 0,
  909. NULL,
  910. &cbData))
  911. goto CLEANUP;
  912. pBasicInfo2=(PCERT_BASIC_CONSTRAINTS2_INFO)WizardAlloc(cbData);
  913. if(NULL==pBasicInfo2)
  914. goto CLEANUP;
  915. if(!CryptDecodeObject(
  916. X509_ASN_ENCODING,
  917. X509_BASIC_CONSTRAINTS2,
  918. pCertExt->Value.pbData,
  919. pCertExt->Value.cbData,
  920. 0,
  921. pBasicInfo2,
  922. &cbData))
  923. goto CLEANUP;
  924. if(pBasicInfo2->fCA)
  925. fEndEntity=FALSE;
  926. else
  927. fEndEntity=TRUE;
  928. }
  929. else
  930. {
  931. //get the extension szOID_BASIC_CONSTRAINTS
  932. pCertExt=CertFindExtension(
  933. szOID_BASIC_CONSTRAINTS,
  934. pCertContext->pCertInfo->cExtension,
  935. pCertContext->pCertInfo->rgExtension);
  936. if(pCertExt)
  937. {
  938. //deocde the extension
  939. cbData=0;
  940. if(!CryptDecodeObject(
  941. X509_ASN_ENCODING,
  942. X509_BASIC_CONSTRAINTS,
  943. pCertExt->Value.pbData,
  944. pCertExt->Value.cbData,
  945. 0,
  946. NULL,
  947. &cbData))
  948. goto CLEANUP;
  949. pBasicInfo=(PCERT_BASIC_CONSTRAINTS_INFO)WizardAlloc(cbData);
  950. if(NULL==pBasicInfo)
  951. goto CLEANUP;
  952. if(!CryptDecodeObject(
  953. X509_ASN_ENCODING,
  954. X509_BASIC_CONSTRAINTS,
  955. pCertExt->Value.pbData,
  956. pCertExt->Value.cbData,
  957. 0,
  958. pBasicInfo,
  959. &cbData))
  960. goto CLEANUP;
  961. if(0 == pBasicInfo->SubjectType.cbData)
  962. {
  963. fEndEntity=FALSE;
  964. }
  965. else
  966. {
  967. if(CERT_END_ENTITY_SUBJECT_FLAG & (pBasicInfo->SubjectType.pbData[0]))
  968. fEndEntity=TRUE;
  969. else
  970. {
  971. if(CERT_CA_SUBJECT_FLAG & (pBasicInfo->SubjectType.pbData[0]))
  972. fEndEntity=FALSE;
  973. }
  974. }
  975. }
  976. }
  977. CLEANUP:
  978. if(pBasicInfo)
  979. WizardFree(pBasicInfo);
  980. if(pBasicInfo2)
  981. WizardFree(pBasicInfo2);
  982. return fEndEntity;
  983. }
  984. //----------------------------------------------------------------------------
  985. // Add certificate to the pCertMgrInfo
  986. //
  987. //----------------------------------------------------------------------------
  988. BOOL AddCertToCertMgrInfo(PCCERT_CONTEXT pCertContext,
  989. CERT_MGR_INFO *pCertMgrInfo)
  990. {
  991. pCertMgrInfo->prgCertContext=(PCCERT_CONTEXT *)WizardRealloc(
  992. pCertMgrInfo->prgCertContext,
  993. sizeof(PCCERT_CONTEXT *)*(pCertMgrInfo->dwCertCount +1));
  994. if(NULL==pCertMgrInfo->prgCertContext)
  995. {
  996. pCertMgrInfo->dwCertCount=0;
  997. return FALSE;
  998. }
  999. pCertMgrInfo->prgCertContext[pCertMgrInfo->dwCertCount]=pCertContext;
  1000. pCertMgrInfo->dwCertCount++;
  1001. return TRUE;
  1002. }
  1003. //----------------------------------------------------------------------------
  1004. // Once a certificate is selected, refresh the static windows that display
  1005. // the details of the certificate
  1006. //
  1007. //----------------------------------------------------------------------------
  1008. BOOL RefreshCertDetails(HWND hwndDlg,
  1009. PCCERT_CONTEXT pCertContext)
  1010. {
  1011. BOOL fResult=FALSE;
  1012. DWORD dwChar=0;
  1013. WCHAR wszNone[MAX_TITLE_LENGTH];
  1014. LPWSTR pwszName=NULL;
  1015. if(!hwndDlg || !pCertContext)
  1016. return FALSE;
  1017. //load the string for NONE
  1018. if(!LoadStringU(g_hmodThisDll, IDS_NONE, wszNone, MAX_TITLE_LENGTH))
  1019. wszNone[0]=L'\0';
  1020. //Subject
  1021. /* dwChar=CertGetNameStringW(
  1022. pCertContext,
  1023. CERT_NAME_SIMPLE_DISPLAY_TYPE,
  1024. 0,
  1025. NULL,
  1026. NULL,
  1027. 0);
  1028. if ((dwChar != 0) && (NULL != (pwszName = (LPWSTR)WizardAlloc(dwChar * sizeof(WCHAR)))))
  1029. {
  1030. CertGetNameStringW(
  1031. pCertContext,
  1032. CERT_NAME_SIMPLE_DISPLAY_TYPE,
  1033. 0,
  1034. NULL,
  1035. pwszName,
  1036. dwChar);
  1037. SetDlgItemTextU(hwndDlg, IDC_CERTMGR_SUBJECT, pwszName);
  1038. }
  1039. else
  1040. {
  1041. SetDlgItemTextU(hwndDlg, IDC_CERTMGR_SUBJECT, wszNone);
  1042. }
  1043. //WizardFree the memory
  1044. if(pwszName)
  1045. {
  1046. WizardFree(pwszName);
  1047. pwszName=NULL;
  1048. }
  1049. //Issuer
  1050. dwChar=CertGetNameStringW(
  1051. pCertContext,
  1052. CERT_NAME_SIMPLE_DISPLAY_TYPE,
  1053. CERT_NAME_ISSUER_FLAG,
  1054. NULL,
  1055. NULL,
  1056. 0);
  1057. if ((dwChar != 0) && (NULL != (pwszName = (LPWSTR)WizardAlloc(dwChar * sizeof(WCHAR)))))
  1058. {
  1059. CertGetNameStringW(
  1060. pCertContext,
  1061. CERT_NAME_SIMPLE_DISPLAY_TYPE,
  1062. CERT_NAME_ISSUER_FLAG,
  1063. NULL,
  1064. pwszName,
  1065. dwChar);
  1066. SetDlgItemTextU(hwndDlg, IDC_CERTMGR_ISSUER, pwszName);
  1067. }
  1068. else
  1069. SetDlgItemTextU(hwndDlg, IDC_CERTMGR_ISSUER, wszNone);
  1070. //free the memory
  1071. if(pwszName)
  1072. {
  1073. WizardFree(pwszName);
  1074. pwszName=NULL;
  1075. }
  1076. //Expiration
  1077. if(WizardFormatDateString(&pwszName,pCertContext->pCertInfo->NotAfter, FALSE))
  1078. SetDlgItemTextU(hwndDlg, IDC_CERTMGR_EXPIRE, pwszName);
  1079. else
  1080. SetDlgItemTextU(hwndDlg, IDC_CERTMGR_EXPIRE, wszNone);
  1081. //free the memory
  1082. if(pwszName)
  1083. {
  1084. WizardFree(pwszName);
  1085. pwszName=NULL;
  1086. } */
  1087. //purpose
  1088. if(MyFormatEnhancedKeyUsageString(&pwszName,pCertContext, FALSE, FALSE))
  1089. {
  1090. SetDlgItemTextU(hwndDlg, IDC_CERTMGR_PURPOSE, pwszName);
  1091. }
  1092. //free the memory
  1093. if(pwszName)
  1094. {
  1095. WizardFree(pwszName);
  1096. pwszName=NULL;
  1097. }
  1098. //friendly name
  1099. /* dwChar=0;
  1100. if(CertGetCertificateContextProperty(
  1101. pCertContext,
  1102. CERT_FRIENDLY_NAME_PROP_ID,
  1103. NULL,
  1104. &dwChar) && (0!=dwChar))
  1105. {
  1106. pwszName = (LPWSTR)WizardAlloc(dwChar * sizeof(WCHAR));
  1107. if(pwszName)
  1108. {
  1109. CertGetCertificateContextProperty(
  1110. pCertContext,
  1111. CERT_FRIENDLY_NAME_PROP_ID,
  1112. pwszName,
  1113. &dwChar);
  1114. SetDlgItemTextU(hwndDlg, IDC_CERTMGR_NAME, pwszName);
  1115. }
  1116. else
  1117. SetDlgItemTextU(hwndDlg, IDC_CERTMGR_NAME, wszNone);
  1118. }
  1119. else
  1120. SetDlgItemTextU(hwndDlg, IDC_CERTMGR_NAME, wszNone);
  1121. //free the memory
  1122. if(pwszName)
  1123. {
  1124. WizardFree(pwszName);
  1125. pwszName=NULL;
  1126. } */
  1127. return TRUE;
  1128. }
  1129. //----------------------------------------------------------------------------
  1130. // Add certificate to the ListView
  1131. //
  1132. //----------------------------------------------------------------------------
  1133. BOOL AddCertToListView(HWND hwndControl,
  1134. PCCERT_CONTEXT pCertContext,
  1135. int iItem)
  1136. {
  1137. BOOL fResult=FALSE;
  1138. LV_ITEMW lvItem;
  1139. DWORD dwChar=0;
  1140. WCHAR wszNone[MAX_TITLE_LENGTH];
  1141. LPWSTR pwszName=NULL;
  1142. if(!hwndControl || !pCertContext)
  1143. return FALSE;
  1144. // set up the fields in the list view item struct that don't change from item to item
  1145. lvItem.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE |LVIF_PARAM ;
  1146. lvItem.state = 0;
  1147. lvItem.stateMask = 0;
  1148. lvItem.iItem=iItem;
  1149. lvItem.iSubItem=0;
  1150. lvItem.iImage = 0;
  1151. lvItem.lParam = (LPARAM)pCertContext;
  1152. //load the string for NONE
  1153. if(!LoadStringU(g_hmodThisDll, IDS_NONE, wszNone, MAX_TITLE_LENGTH))
  1154. wszNone[0]=L'\0';
  1155. //Subject
  1156. if (NULL == (pwszName = GetDisplayNameString(pCertContext, 0)))
  1157. {
  1158. lvItem.pszText=wszNone;
  1159. ListView_InsertItemU(hwndControl, &lvItem);
  1160. }
  1161. else
  1162. {
  1163. lvItem.pszText=pwszName;
  1164. ListView_InsertItemU(hwndControl, &lvItem);
  1165. free(pwszName);
  1166. pwszName = NULL;
  1167. }
  1168. //Issuer
  1169. lvItem.iSubItem++;
  1170. if (NULL == (pwszName = GetDisplayNameString(pCertContext, CERT_NAME_ISSUER_FLAG)))
  1171. {
  1172. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem, wszNone);
  1173. }
  1174. else
  1175. {
  1176. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem, pwszName);
  1177. free(pwszName);
  1178. pwszName = NULL;
  1179. }
  1180. //Expiration
  1181. lvItem.iSubItem++;
  1182. if(WizardFormatDateString(&pwszName,pCertContext->pCertInfo->NotAfter, FALSE))
  1183. {
  1184. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
  1185. pwszName);
  1186. }
  1187. else
  1188. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
  1189. wszNone);
  1190. //free the memory
  1191. if(pwszName)
  1192. {
  1193. WizardFree(pwszName);
  1194. pwszName=NULL;
  1195. }
  1196. //purpose
  1197. /*lvItem.iSubItem++;
  1198. if(WizardFormatEnhancedKeyUsageString(&pwszName,pCertContext, FALSE, FALSE) &&
  1199. L'\0' != *pwszName)
  1200. {
  1201. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
  1202. pwszName);
  1203. }
  1204. else
  1205. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
  1206. wszNone);
  1207. //free the memory
  1208. if(pwszName)
  1209. {
  1210. WizardFree(pwszName);
  1211. pwszName=NULL;
  1212. } */
  1213. //friendly name
  1214. lvItem.iSubItem++;
  1215. dwChar=0;
  1216. if(CertGetCertificateContextProperty(
  1217. pCertContext,
  1218. CERT_FRIENDLY_NAME_PROP_ID,
  1219. NULL,
  1220. &dwChar) && (0!=dwChar))
  1221. {
  1222. pwszName = (LPWSTR)WizardAlloc(dwChar * sizeof(WCHAR));
  1223. if(pwszName)
  1224. {
  1225. CertGetCertificateContextProperty(
  1226. pCertContext,
  1227. CERT_FRIENDLY_NAME_PROP_ID,
  1228. pwszName,
  1229. &dwChar);
  1230. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
  1231. pwszName);
  1232. }
  1233. else
  1234. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
  1235. wszNone);
  1236. }
  1237. else
  1238. {
  1239. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
  1240. wszNone);
  1241. }
  1242. //free the memory
  1243. if(pwszName)
  1244. {
  1245. WizardFree(pwszName);
  1246. pwszName=NULL;
  1247. }
  1248. return TRUE;
  1249. }
  1250. //-----------------------------------------------------------------------
  1251. // Based on the tab(store) and the intended purpose selected,
  1252. // find the correct certificates and refresh the list view
  1253. // Criteria:
  1254. // Tab 0: My Store with private key
  1255. // Tab 1: Ca Store's end-entity cert and the "ADDRESSBOOK" store
  1256. // Tab 2: Ca Store's CA certs
  1257. // Tab 3: Root store's self signed certs
  1258. // Tab 4: Trusted publisher certs
  1259. //-----------------------------------------------------------------------
  1260. void RefreshCertListView(HWND hwndDlg,
  1261. CERT_MGR_INFO *pCertMgrInfo)
  1262. {
  1263. HWND hwndControl=NULL;
  1264. DWORD dwIndex=0;
  1265. DWORD dwTabIndex=0;
  1266. HCERTSTORE rghCertStore[]={NULL, NULL};
  1267. DWORD dwStoreCount=0;
  1268. PCCERT_CONTEXT pCurCertContext=NULL;
  1269. PCCERT_CONTEXT pPreCertContext=NULL;
  1270. BOOL fValidCert=FALSE;
  1271. DWORD cbData=0;
  1272. DWORD dwSortParam=0;
  1273. PCCRYPTUI_CERT_MGR_STRUCT pCertMgrStruct = NULL;
  1274. HCURSOR hPreCursor=NULL;
  1275. HCURSOR hWinPreCursor=NULL;
  1276. if(!hwndDlg || !pCertMgrInfo)
  1277. return;
  1278. pCertMgrStruct = pCertMgrInfo->pCertMgrStruct;
  1279. if(!pCertMgrStruct)
  1280. return;
  1281. //overwrite the cursor for this window class
  1282. hWinPreCursor=(HCURSOR)SetClassLongPtr(hwndDlg, GCLP_HCURSOR, NULL);
  1283. hPreCursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
  1284. //free all the original certificates
  1285. hwndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_LIST);
  1286. if(!hwndControl)
  1287. goto CLEANUP;
  1288. FreeCerts(pCertMgrInfo);
  1289. //deletel all the certs from the listView
  1290. ListView_DeleteAllItems(hwndControl);
  1291. //clear the ceritificate details group box
  1292. SetDlgItemTextU(hwndDlg, IDC_CERTMGR_PURPOSE, L" ");
  1293. //get the tab that is selected
  1294. if (pCertMgrStruct->dwFlags & CRYPTUI_CERT_MGR_SINGLE_TAB_FLAG)
  1295. dwTabIndex = pCertMgrStruct->dwFlags & CRYPTUI_CERT_MGR_TAB_MASK;
  1296. else if(-1 == (dwTabIndex=TabCtrl_GetCurSel(GetDlgItem(hwndDlg, IDC_CERTMGR_TAB))))
  1297. goto CLEANUP;
  1298. //open the correct store based on the tab selected
  1299. switch (dwTabIndex)
  1300. {
  1301. case 0:
  1302. //open my store
  1303. if(rghCertStore[dwStoreCount]=CertOpenStore(
  1304. CERT_STORE_PROV_SYSTEM_W,
  1305. g_dwMsgAndCertEncodingType,
  1306. NULL,
  1307. CERT_STORE_MAXIMUM_ALLOWED_FLAG |
  1308. CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG |
  1309. CERT_SYSTEM_STORE_CURRENT_USER,
  1310. (LPWSTR)L"my"))
  1311. dwStoreCount++;
  1312. else
  1313. goto CLEANUP;
  1314. break;
  1315. case 1:
  1316. //open ca store
  1317. if(rghCertStore[dwStoreCount]=CertOpenStore(
  1318. CERT_STORE_PROV_SYSTEM_W,
  1319. g_dwMsgAndCertEncodingType,
  1320. NULL,
  1321. CERT_STORE_MAXIMUM_ALLOWED_FLAG |
  1322. CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG |
  1323. CERT_SYSTEM_STORE_CURRENT_USER,
  1324. (LPWSTR)L"ca"))
  1325. dwStoreCount++;
  1326. else
  1327. goto CLEANUP;
  1328. //open the "AddressBook" store
  1329. if(rghCertStore[dwStoreCount]=CertOpenStore(
  1330. CERT_STORE_PROV_SYSTEM_W,
  1331. g_dwMsgAndCertEncodingType,
  1332. NULL,
  1333. CERT_STORE_MAXIMUM_ALLOWED_FLAG |
  1334. CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG |
  1335. CERT_SYSTEM_STORE_CURRENT_USER |
  1336. CERT_STORE_OPEN_EXISTING_FLAG,
  1337. (LPWSTR)L"ADDRESSBOOK"))
  1338. dwStoreCount++;
  1339. else
  1340. {
  1341. //it is OK that user does not have "AddressBook" store
  1342. rghCertStore[dwStoreCount]=NULL;
  1343. }
  1344. break;
  1345. case 2:
  1346. //open CA store
  1347. if(rghCertStore[dwStoreCount]=CertOpenStore(
  1348. CERT_STORE_PROV_SYSTEM_W,
  1349. g_dwMsgAndCertEncodingType,
  1350. NULL,
  1351. CERT_STORE_MAXIMUM_ALLOWED_FLAG |
  1352. CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG |
  1353. CERT_SYSTEM_STORE_CURRENT_USER,
  1354. (LPWSTR)L"ca"))
  1355. dwStoreCount++;
  1356. else
  1357. goto CLEANUP;
  1358. break;
  1359. case 3:
  1360. //open root store
  1361. if(rghCertStore[dwStoreCount]=CertOpenStore(
  1362. CERT_STORE_PROV_SYSTEM_W,
  1363. g_dwMsgAndCertEncodingType,
  1364. NULL,
  1365. CERT_STORE_MAXIMUM_ALLOWED_FLAG |
  1366. CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG |
  1367. CERT_SYSTEM_STORE_CURRENT_USER,
  1368. (LPWSTR)L"root"))
  1369. dwStoreCount++;
  1370. else
  1371. goto CLEANUP;
  1372. break;
  1373. case 4:
  1374. //open trusted publisher store
  1375. if(rghCertStore[dwStoreCount]=CertOpenStore(
  1376. CERT_STORE_PROV_SYSTEM_W,
  1377. g_dwMsgAndCertEncodingType,
  1378. NULL,
  1379. CERT_STORE_MAXIMUM_ALLOWED_FLAG |
  1380. CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG |
  1381. CERT_SYSTEM_STORE_CURRENT_USER,
  1382. (LPWSTR)L"TrustedPublisher"))
  1383. dwStoreCount++;
  1384. else
  1385. goto CLEANUP;
  1386. break;
  1387. default:
  1388. goto CLEANUP;
  1389. break;
  1390. }
  1391. //gather new certificates from the store opened
  1392. for(dwIndex=0; dwIndex < dwStoreCount; dwIndex++)
  1393. {
  1394. pPreCertContext=NULL;
  1395. while(pCurCertContext=CertEnumCertificatesInStore(
  1396. rghCertStore[dwIndex],
  1397. pPreCertContext))
  1398. {
  1399. //make sure the certificate has the correct usage oid
  1400. if(IsValidUsage(pCurCertContext,
  1401. hwndDlg,
  1402. pCertMgrInfo))
  1403. {
  1404. switch (dwTabIndex)
  1405. {
  1406. case 0:
  1407. //certificate has to have private key associated
  1408. //with it
  1409. cbData=0;
  1410. if(
  1411. (CertGetCertificateContextProperty(
  1412. pCurCertContext,
  1413. CERT_KEY_PROV_INFO_PROP_ID,
  1414. NULL,
  1415. &cbData) && (0!=cbData)) ||
  1416. (CertGetCertificateContextProperty(
  1417. pCurCertContext,
  1418. CERT_PVK_FILE_PROP_ID,
  1419. NULL,
  1420. &cbData) && (0!=cbData))
  1421. )
  1422. fValidCert=TRUE;
  1423. break;
  1424. case 1:
  1425. //the certificate has to be end entity cert for CA cert
  1426. if(0 == dwIndex)
  1427. {
  1428. if(IsCertificateEndEntity(pCurCertContext))
  1429. fValidCert=TRUE;
  1430. }
  1431. //we display everything in the addressbook store
  1432. if(1==dwIndex)
  1433. fValidCert=TRUE;
  1434. break;
  1435. case 2:
  1436. //for certificate in CA store, has to be CA cert
  1437. if(!IsCertificateEndEntity(pCurCertContext))
  1438. fValidCert=TRUE;
  1439. break;
  1440. case 4:
  1441. fValidCert=TRUE;
  1442. break;
  1443. case 3:
  1444. default:
  1445. //the certificate has to be self-signed
  1446. if(TrustIsCertificateSelfSigned(
  1447. pCurCertContext,
  1448. pCurCertContext->dwCertEncodingType, 0))
  1449. fValidCert=TRUE;
  1450. break;
  1451. }
  1452. if(fValidCert)
  1453. {
  1454. AddCertToCertMgrInfo(
  1455. CertDuplicateCertificateContext(pCurCertContext),
  1456. pCertMgrInfo);
  1457. }
  1458. fValidCert=FALSE;
  1459. }
  1460. pPreCertContext=pCurCertContext;
  1461. pCurCertContext=NULL;
  1462. }
  1463. }
  1464. //put the certificate in the listView
  1465. for(dwIndex=0; dwIndex<pCertMgrInfo->dwCertCount; dwIndex++)
  1466. AddCertToListView(hwndControl,
  1467. (pCertMgrInfo->prgCertContext)[dwIndex],
  1468. dwIndex);
  1469. // if there is no cert selected initially disable the
  1470. // "view cert button", "export" and "remove" button
  1471. if (ListView_GetSelectedCount(hwndControl) == 0)
  1472. {
  1473. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_VIEW), FALSE);
  1474. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT), FALSE);
  1475. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_REMOVE), FALSE);
  1476. }
  1477. //we sort by the 1st column
  1478. dwSortParam=pCertMgrInfo->rgdwSortParam[pCertMgrInfo->iColumn];
  1479. if(0!=dwSortParam)
  1480. {
  1481. //sort the 1st column
  1482. SendDlgItemMessage(hwndDlg,
  1483. IDC_CERTMGR_LIST,
  1484. LVM_SORTITEMS,
  1485. (WPARAM) (LPARAM) dwSortParam,
  1486. (LPARAM) (PFNLVCOMPARE)CompareCertificate);
  1487. }
  1488. CLEANUP:
  1489. //close all the certificate stores
  1490. for(dwIndex=0; dwIndex<dwStoreCount; dwIndex++)
  1491. CertCloseStore(rghCertStore[dwIndex], 0);
  1492. //set the cursor back
  1493. SetCursor(hPreCursor);
  1494. SetWindowLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)hWinPreCursor);
  1495. return;
  1496. }
  1497. //-----------------------------------------------------------------------
  1498. // Check if the input OID is considered to be the advanced OID
  1499. //-----------------------------------------------------------------------
  1500. BOOL IsAdvancedOID(CERT_ENHKEY_USAGE *pKeyUsage,
  1501. LPCSTR pszOID)
  1502. {
  1503. DWORD dwIndex=0;
  1504. for(dwIndex=0; dwIndex<pKeyUsage->cUsageIdentifier; dwIndex++)
  1505. {
  1506. if(0 == _stricmp(pKeyUsage->rgpszUsageIdentifier[dwIndex], pszOID))
  1507. return FALSE;
  1508. }
  1509. return TRUE;
  1510. }
  1511. //-----------------------------------------------------------------------
  1512. //The call back function for enum
  1513. //-----------------------------------------------------------------------
  1514. static BOOL WINAPI EnumOidCallback(
  1515. IN PCCRYPT_OID_INFO pInfo,
  1516. IN void *pvArg
  1517. )
  1518. {
  1519. PURPOSE_OID_CALL_BACK *pCallBackInfo=NULL;
  1520. BOOL fResult=FALSE;
  1521. pCallBackInfo=(PURPOSE_OID_CALL_BACK *)pvArg;
  1522. if(NULL==pvArg || NULL==pInfo)
  1523. goto InvalidArgErr;
  1524. //increment the oid list
  1525. (*(pCallBackInfo->pdwOIDCount))++;
  1526. //get more memory for the pointer list
  1527. *(pCallBackInfo->pprgOIDInfo)=(PURPOSE_OID_INFO *)WizardRealloc(*(pCallBackInfo->pprgOIDInfo),
  1528. (*(pCallBackInfo->pdwOIDCount)) * sizeof(PURPOSE_OID_INFO));
  1529. if(NULL==*(pCallBackInfo->pprgOIDInfo))
  1530. goto MemoryErr;
  1531. //memset
  1532. memset(&((*(pCallBackInfo->pprgOIDInfo))[*(pCallBackInfo->pdwOIDCount)-1]), 0, sizeof(PURPOSE_OID_INFO));
  1533. (*(pCallBackInfo->pprgOIDInfo))[*(pCallBackInfo->pdwOIDCount)-1].pszOID=WizardAllocAndCopyStr((LPSTR)(pInfo->pszOID));
  1534. (*(pCallBackInfo->pprgOIDInfo))[*(pCallBackInfo->pdwOIDCount)-1].pwszName=WizardAllocAndCopyWStr((LPWSTR)(pInfo->pwszName));
  1535. (*(pCallBackInfo->pprgOIDInfo))[*(pCallBackInfo->pdwOIDCount)-1].fSelected=FALSE;
  1536. if(NULL==(*(pCallBackInfo->pprgOIDInfo))[*(pCallBackInfo->pdwOIDCount)-1].pszOID ||
  1537. NULL==(*(pCallBackInfo->pprgOIDInfo))[*(pCallBackInfo->pdwOIDCount)-1].pwszName)
  1538. goto MemoryErr;
  1539. fResult=TRUE;
  1540. CommonReturn:
  1541. return fResult;
  1542. ErrorReturn:
  1543. fResult=FALSE;
  1544. goto CommonReturn;
  1545. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  1546. SET_ERROR(MemoryErr, E_OUTOFMEMORY);
  1547. }
  1548. //----------------------------------------------------------------------------
  1549. // Get the list of supported enhanced key OIDs
  1550. //----------------------------------------------------------------------------
  1551. BOOL InitPurposeOID(LPCSTR pszInitUsageOID,
  1552. DWORD *pdwOIDInfo,
  1553. PURPOSE_OID_INFO **pprgOIDInfo)
  1554. {
  1555. BOOL fResult=FALSE;
  1556. DWORD dwIndex=0;
  1557. PURPOSE_OID_CALL_BACK OidInfoCallBack;
  1558. DWORD dwOIDRequested=0;
  1559. LPWSTR pwszName=NULL;
  1560. if(!pdwOIDInfo || !pprgOIDInfo)
  1561. goto InvalidArgErr;
  1562. //init
  1563. *pdwOIDInfo=0;
  1564. *pprgOIDInfo=NULL;
  1565. OidInfoCallBack.pdwOIDCount=pdwOIDInfo;
  1566. OidInfoCallBack.pprgOIDInfo=pprgOIDInfo;
  1567. //enum all the enhanced key usages
  1568. if(!CryptEnumOIDInfo(
  1569. CRYPT_ENHKEY_USAGE_OID_GROUP_ID,
  1570. 0,
  1571. &OidInfoCallBack,
  1572. EnumOidCallback))
  1573. goto TraceErr;
  1574. fResult=TRUE;
  1575. CommonReturn:
  1576. //free the memory
  1577. return fResult;
  1578. ErrorReturn:
  1579. FreeUsageOID(*pdwOIDInfo,*pprgOIDInfo);
  1580. *pdwOIDInfo=0;
  1581. *pprgOIDInfo=NULL;
  1582. fResult=FALSE;
  1583. goto CommonReturn;
  1584. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  1585. TRACE_ERROR(TraceErr);
  1586. }
  1587. //-----------------------------------------------------------------------
  1588. // Initialize the tab control
  1589. //-----------------------------------------------------------------------
  1590. void InitTabControl(HWND hWndControl,
  1591. PCCRYPTUI_CERT_MGR_STRUCT pCertMgrStruct)
  1592. {
  1593. DWORD dwIndex=0;
  1594. DWORD dwCount=0;
  1595. WCHAR wszText[MAX_STRING_SIZE];
  1596. UINT rgIDS[]={IDS_TAB_PERSONAL,
  1597. IDS_TAB_OTHER,
  1598. IDS_TAB_CA,
  1599. IDS_TAB_ROOT,
  1600. IDS_TAB_PUBLISHER,
  1601. };
  1602. TCITEMW tcItem;
  1603. if(!hWndControl)
  1604. return;
  1605. memset(&tcItem, 0, sizeof(TCITEM));
  1606. tcItem.mask=TCIF_TEXT;
  1607. tcItem.pszText=wszText;
  1608. if (pCertMgrStruct->dwFlags & CRYPTUI_CERT_MGR_SINGLE_TAB_FLAG)
  1609. {
  1610. dwIndex = pCertMgrStruct->dwFlags & CRYPTUI_CERT_MGR_TAB_MASK;
  1611. //get the column header
  1612. wszText[0]=L'\0';
  1613. LoadStringU(g_hmodThisDll, rgIDS[dwIndex], wszText, MAX_STRING_SIZE);
  1614. TabCtrl_InsertItemU(hWndControl,
  1615. 0,
  1616. &tcItem);
  1617. } else
  1618. {
  1619. dwCount=sizeof(rgIDS)/sizeof(rgIDS[0]);
  1620. //insert the tabs one at a time
  1621. for(dwIndex=0; dwIndex<dwCount; dwIndex++)
  1622. {
  1623. //get the column header
  1624. wszText[0]=L'\0';
  1625. LoadStringU(g_hmodThisDll, rgIDS[dwIndex], wszText, MAX_STRING_SIZE);
  1626. TabCtrl_InsertItemU(hWndControl,
  1627. dwIndex,
  1628. &tcItem);
  1629. }
  1630. }
  1631. return;
  1632. }
  1633. //----------------------------------------------------------------------------
  1634. //
  1635. // Free the array of usage OID info
  1636. //
  1637. //----------------------------------------------------------------------------
  1638. BOOL FreeUsageOID(DWORD dwOIDInfo,
  1639. PURPOSE_OID_INFO *pOIDInfo)
  1640. {
  1641. DWORD dwIndex=0;
  1642. if(pOIDInfo)
  1643. {
  1644. for(dwIndex=0; dwIndex < dwOIDInfo; dwIndex++)
  1645. {
  1646. if(pOIDInfo[dwIndex].pszOID)
  1647. WizardFree(pOIDInfo[dwIndex].pszOID);
  1648. if(pOIDInfo[dwIndex].pwszName)
  1649. WizardFree(pOIDInfo[dwIndex].pwszName);
  1650. }
  1651. WizardFree(pOIDInfo);
  1652. }
  1653. return TRUE;
  1654. }
  1655. //-----------------------------------------------------------------------
  1656. // Free the Certificates array
  1657. //-----------------------------------------------------------------------
  1658. void FreeCerts(CERT_MGR_INFO *pCertMgrInfo)
  1659. {
  1660. DWORD dwIndex=0;
  1661. if(!pCertMgrInfo)
  1662. return;
  1663. if(pCertMgrInfo->prgCertContext)
  1664. {
  1665. for(dwIndex=0; dwIndex<pCertMgrInfo->dwCertCount; dwIndex++)
  1666. {
  1667. if(pCertMgrInfo->prgCertContext[dwIndex])
  1668. CertFreeCertificateContext(pCertMgrInfo->prgCertContext[dwIndex]);
  1669. }
  1670. WizardFree(pCertMgrInfo->prgCertContext);
  1671. }
  1672. pCertMgrInfo->dwCertCount=0;
  1673. pCertMgrInfo->prgCertContext=NULL;
  1674. return;
  1675. }
  1676. //--------------------------------------------------------------
  1677. // Initialize the Purpose Combo
  1678. //--------------------------------------------------------------
  1679. void InitPurposeCombo(HWND hwndDlg,
  1680. CERT_MGR_INFO *pCertMgrInfo)
  1681. {
  1682. DWORD dwIndex=0;
  1683. DWORD dwCount=0;
  1684. WCHAR wszText[MAX_STRING_SIZE];
  1685. UINT rgIDS[]={IDS_OID_ADVANCED,
  1686. IDS_OID_ALL};
  1687. LPWSTR pwszInitOIDName=NULL;
  1688. CRYPTUI_CERT_MGR_STRUCT *pCertMgrStruct=NULL;
  1689. int iIndex=0;
  1690. if(!hwndDlg || !pCertMgrInfo)
  1691. return;
  1692. pCertMgrStruct=(CRYPTUI_CERT_MGR_STRUCT *)(pCertMgrInfo->pCertMgrStruct);
  1693. //delete all the entries in the comobox
  1694. SendDlgItemMessage(hwndDlg, IDC_CERTMGR_PURPOSE_COMBO,
  1695. CB_RESETCONTENT, 0, 0);
  1696. //copy all the basic OIDs to the comobox
  1697. for(dwIndex=0; dwIndex<pCertMgrInfo->dwOIDInfo; dwIndex++)
  1698. {
  1699. if(FALSE == (pCertMgrInfo->rgOIDInfo[dwIndex].fSelected))
  1700. {
  1701. SendDlgItemMessageU(hwndDlg, IDC_CERTMGR_PURPOSE_COMBO,
  1702. CB_ADDSTRING,
  1703. 0, (LPARAM)(pCertMgrInfo->rgOIDInfo[dwIndex].pwszName));
  1704. //looking for the initial OID
  1705. if(pCertMgrStruct->pszInitUsageOID)
  1706. {
  1707. if(0 == _stricmp(pCertMgrStruct->pszInitUsageOID,
  1708. pCertMgrInfo->rgOIDInfo[dwIndex].pszOID))
  1709. pwszInitOIDName=pCertMgrInfo->rgOIDInfo[dwIndex].pwszName;
  1710. }
  1711. }
  1712. }
  1713. //copy <advanced> and <all> to the list
  1714. dwCount=sizeof(rgIDS)/sizeof(rgIDS[0]);
  1715. //insert the column one at a time
  1716. for(dwIndex=0; dwIndex<dwCount; dwIndex++)
  1717. {
  1718. //get the column header
  1719. wszText[0]=L'\0';
  1720. LoadStringU(g_hmodThisDll, rgIDS[dwIndex], wszText, MAX_STRING_SIZE);
  1721. SendDlgItemMessageU(hwndDlg, IDC_CERTMGR_PURPOSE_COMBO,
  1722. CB_INSERTSTRING,
  1723. -1, (LPARAM)wszText);
  1724. }
  1725. //initialize the combo box
  1726. //use <advanced> is what user specify is not either
  1727. //client auth or secure e-mail
  1728. if(pCertMgrStruct->pszInitUsageOID)
  1729. {
  1730. if(NULL==pwszInitOIDName)
  1731. {
  1732. wszText[0]=L'\0';
  1733. LoadStringU(g_hmodThisDll, IDS_OID_ADVANCED, wszText, MAX_STRING_SIZE);
  1734. pwszInitOIDName=wszText;
  1735. }
  1736. }
  1737. //use <all> when NULL==pCertMgrStruct->pszInitUsageOID
  1738. if(NULL==pwszInitOIDName)
  1739. {
  1740. //use <all> as the initial case
  1741. wszText[0]=L'\0';
  1742. LoadStringU(g_hmodThisDll, IDS_OID_ALL, wszText, MAX_STRING_SIZE);
  1743. pwszInitOIDName=wszText;
  1744. }
  1745. iIndex=(int)SendDlgItemMessageU(
  1746. hwndDlg,
  1747. IDC_CERTMGR_PURPOSE_COMBO,
  1748. CB_FINDSTRINGEXACT,
  1749. -1,
  1750. (LPARAM)pwszInitOIDName);
  1751. if(CB_ERR == iIndex)
  1752. return;
  1753. //set the selection
  1754. SendDlgItemMessageU(hwndDlg, IDC_CERTMGR_PURPOSE_COMBO, CB_SETCURSEL, iIndex,0);
  1755. return;
  1756. }
  1757. //--------------------------------------------------------------
  1758. // Initialize the Purpose Combo
  1759. //--------------------------------------------------------------
  1760. void RepopulatePurposeCombo(HWND hwndDlg,
  1761. CERT_MGR_INFO *pCertMgrInfo)
  1762. {
  1763. LPWSTR pwszSelectedOIDName=NULL;
  1764. int iIndex=0;
  1765. if(!hwndDlg || !pCertMgrInfo)
  1766. return;
  1767. //get the selected string from the combo box
  1768. iIndex=(int)SendDlgItemMessage(hwndDlg, IDC_CERTMGR_PURPOSE_COMBO,
  1769. CB_GETCURSEL, 0, 0);
  1770. if(CB_ERR==iIndex)
  1771. return;
  1772. //get the selected purpose
  1773. if(CB_ERR == SendDlgItemMessageU_GETLBTEXT(hwndDlg,
  1774. IDC_CERTMGR_PURPOSE_COMBO,
  1775. iIndex, &pwszSelectedOIDName))
  1776. goto CLEANUP;
  1777. InitPurposeCombo(hwndDlg, pCertMgrInfo);
  1778. iIndex=(int)SendDlgItemMessageU(
  1779. hwndDlg,
  1780. IDC_CERTMGR_PURPOSE_COMBO,
  1781. CB_FINDSTRINGEXACT,
  1782. -1,
  1783. (LPARAM)pwszSelectedOIDName);
  1784. if(CB_ERR == iIndex)
  1785. goto CLEANUP;
  1786. //set the selection
  1787. SendDlgItemMessageU(hwndDlg, IDC_CERTMGR_PURPOSE_COMBO, CB_SETCURSEL, iIndex,0);
  1788. CLEANUP:
  1789. if(pwszSelectedOIDName)
  1790. WizardFree(pwszSelectedOIDName);
  1791. return;
  1792. }
  1793. //--------------------------------------------------------------
  1794. // The winProc for the advanced option diagloue for certMgr UI
  1795. //--------------------------------------------------------------
  1796. INT_PTR APIENTRY CertMgrAdvancedProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  1797. {
  1798. CERT_MGR_INFO *pCertMgrInfo=NULL;
  1799. PCCRYPTUI_CERT_MGR_STRUCT pCertMgrStruct=NULL;
  1800. UINT rgIDS[]={IDS_CERTMGR_DER,
  1801. IDS_CERTMGR_BASE64,
  1802. IDS_CERTMGR_PKCS7};
  1803. WCHAR wszText[MAX_STRING_SIZE];
  1804. DWORD dwCount=0;
  1805. DWORD dwIndex=0;
  1806. DWORD dwSelectedIndex=0;
  1807. LV_ITEMW lvItem;
  1808. LV_COLUMNW lvC;
  1809. HWND hwndControl=NULL;
  1810. int iIndex=0;
  1811. int listIndex=0;
  1812. NM_LISTVIEW FAR * pnmv=NULL;
  1813. HWND hwnd=NULL;
  1814. switch ( msg )
  1815. {
  1816. case WM_INITDIALOG:
  1817. pCertMgrInfo = (CERT_MGR_INFO *) lParam;
  1818. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR) pCertMgrInfo);
  1819. pCertMgrStruct=pCertMgrInfo->pCertMgrStruct;
  1820. if(NULL == pCertMgrStruct)
  1821. break;
  1822. //init the export format control
  1823. dwCount=sizeof(rgIDS)/sizeof(rgIDS[0]);
  1824. for(dwIndex=0; dwIndex < dwCount; dwIndex++)
  1825. {
  1826. LoadStringU(g_hmodThisDll,
  1827. rgIDS[dwIndex],
  1828. wszText,
  1829. MAX_STRING_SIZE);
  1830. SendDlgItemMessageU(hwndDlg,
  1831. IDC_CERTMGR_EXPORT_COMBO,
  1832. CB_INSERTSTRING,
  1833. -1,
  1834. (LPARAM)wszText);
  1835. }
  1836. //select the export format based on the selection
  1837. switch (pCertMgrInfo->dwExportFormat)
  1838. {
  1839. case CRYPTUI_WIZ_EXPORT_FORMAT_DER:
  1840. dwSelectedIndex=0;
  1841. break;
  1842. case CRYPTUI_WIZ_EXPORT_FORMAT_BASE64:
  1843. dwSelectedIndex=1;
  1844. break;
  1845. case CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7:
  1846. dwSelectedIndex=2;
  1847. break;
  1848. default:
  1849. dwSelectedIndex=0;
  1850. }
  1851. SendDlgItemMessageU(hwndDlg, IDC_CERTMGR_EXPORT_COMBO,
  1852. CB_SETCURSEL, (WPARAM)dwSelectedIndex,0);
  1853. //init the chain check-box
  1854. if(pCertMgrInfo->fExportChain)
  1855. SendDlgItemMessage(hwndDlg, IDC_CERTMGR_EXPORT_CHECK, BM_SETCHECK, 1, 0);
  1856. else
  1857. SendDlgItemMessage(hwndDlg, IDC_CERTMGR_EXPORT_CHECK, BM_SETCHECK, 0, 0);
  1858. if(dwSelectedIndex != 2)
  1859. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT_CHECK), FALSE);
  1860. else
  1861. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT_CHECK), TRUE);
  1862. //init the advanced OID list
  1863. hwndControl = GetDlgItem(hwndDlg, IDC_CERTMGR_ADV_LIST);
  1864. //mark the list is selected by a check box
  1865. ListView_SetExtendedListViewStyle(hwndControl, LVS_EX_CHECKBOXES);
  1866. //insert a column into the list view
  1867. memset(&lvC, 0, sizeof(LV_COLUMNW));
  1868. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  1869. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  1870. lvC.cx =10; // (dwMaxSize+2)*7; // Width of the column, in pixels.
  1871. lvC.pszText = L""; // The text for the column.
  1872. lvC.iSubItem=0;
  1873. if (ListView_InsertColumnU(hwndControl, 0, &lvC) == -1)
  1874. break;
  1875. //populate the list
  1876. memset(&lvItem, 0, sizeof(LV_ITEMW));
  1877. lvItem.mask=LVIF_TEXT | LVIF_STATE;
  1878. for(dwIndex=0; dwIndex<pCertMgrInfo->dwOIDInfo; dwIndex++)
  1879. {
  1880. lvItem.iItem=dwIndex;
  1881. lvItem.pszText=(pCertMgrInfo->rgOIDInfo[dwIndex]).pwszName;
  1882. lvItem.cchTextMax=sizeof(WCHAR)*(1+wcslen((pCertMgrInfo->rgOIDInfo[dwIndex]).pwszName));
  1883. lvItem.stateMask = LVIS_STATEIMAGEMASK;
  1884. lvItem.state = (pCertMgrInfo->rgOIDInfo[dwIndex]).fSelected ? 0x00002000 : 0x00001000;
  1885. // insert and set state
  1886. ListView_SetItemState(hwndControl,
  1887. ListView_InsertItemU(hwndControl, &lvItem),
  1888. (pCertMgrInfo->rgOIDInfo[dwIndex]).fSelected ? 0x00002000 : 0x00001000,
  1889. LVIS_STATEIMAGEMASK);
  1890. }
  1891. //autosize the column
  1892. ListView_SetColumnWidth(hwndControl, 0, LVSCW_AUTOSIZE);
  1893. #if (1) // DSIE: bug 282268.
  1894. ListView_SetItemState(hwndControl,
  1895. 0,
  1896. LVIS_FOCUSED | LVIS_SELECTED,
  1897. LVIS_FOCUSED | LVIS_SELECTED);
  1898. #endif
  1899. break;
  1900. case WM_NOTIFY:
  1901. pCertMgrInfo = (CERT_MGR_INFO *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  1902. if(NULL == pCertMgrInfo)
  1903. break;
  1904. pCertMgrStruct=pCertMgrInfo->pCertMgrStruct;
  1905. if(NULL == pCertMgrStruct)
  1906. break;
  1907. switch (((NMHDR FAR *) lParam)->code)
  1908. {
  1909. case LVN_ITEMCHANGED:
  1910. //if the state of the advanced OID check box
  1911. //has been changed, mark the flag
  1912. pnmv = (NM_LISTVIEW FAR *) lParam;
  1913. if(NULL==pnmv)
  1914. break;
  1915. //see if the new item is de-selected
  1916. if(pnmv->uChanged & LVIF_STATE)
  1917. pCertMgrInfo->fAdvOIDChanged=TRUE;
  1918. break;
  1919. }
  1920. break;
  1921. case WM_DESTROY:
  1922. break;
  1923. case WM_HELP:
  1924. case WM_CONTEXTMENU:
  1925. if (msg == WM_HELP)
  1926. {
  1927. hwnd = GetDlgItem(hwndDlg, ((LPHELPINFO)lParam)->iCtrlId);
  1928. }
  1929. else
  1930. {
  1931. hwnd = (HWND) wParam;
  1932. }
  1933. if ((hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_ADV_LIST)) &&
  1934. (hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT_COMBO)) &&
  1935. (hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT_CHECK)) &&
  1936. (hwnd != GetDlgItem(hwndDlg, IDOK)) &&
  1937. (hwnd != GetDlgItem(hwndDlg, IDCANCEL)))
  1938. {
  1939. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
  1940. return TRUE;
  1941. }
  1942. else
  1943. {
  1944. return OnContextHelp(hwndDlg, msg, wParam, lParam, CertMgrAdvHelpMap);
  1945. }
  1946. break;
  1947. case WM_COMMAND:
  1948. pCertMgrInfo = (CERT_MGR_INFO *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  1949. if(NULL == pCertMgrInfo)
  1950. break;
  1951. pCertMgrStruct=pCertMgrInfo->pCertMgrStruct;
  1952. if(NULL == pCertMgrStruct)
  1953. break;
  1954. //a control is clicked
  1955. if(HIWORD(wParam) == BN_CLICKED)
  1956. {
  1957. switch (LOWORD(wParam))
  1958. {
  1959. case IDCANCEL:
  1960. pCertMgrInfo->fAdvOIDChanged=FALSE;
  1961. EndDialog(hwndDlg, DIALOGUE_CANCEL);
  1962. break;
  1963. case IDOK:
  1964. //the OK button is selected
  1965. //get the default export format
  1966. iIndex=(int)SendDlgItemMessage(hwndDlg,
  1967. IDC_CERTMGR_EXPORT_COMBO,
  1968. CB_GETCURSEL, 0, 0);
  1969. if(CB_ERR==iIndex)
  1970. break;
  1971. switch(iIndex)
  1972. {
  1973. case 0:
  1974. pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_DER;
  1975. break;
  1976. case 1:
  1977. pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_BASE64;
  1978. break;
  1979. case 2:
  1980. pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7;
  1981. break;
  1982. default:
  1983. pCertMgrInfo->dwExportFormat=0;
  1984. break;
  1985. }
  1986. if(TRUE==SendDlgItemMessage(
  1987. hwndDlg,
  1988. IDC_CERTMGR_EXPORT_CHECK,
  1989. BM_GETCHECK,
  1990. 0,0))
  1991. pCertMgrInfo->fExportChain=TRUE;
  1992. else
  1993. pCertMgrInfo->fExportChain=FALSE;
  1994. //get the list of advanded OIDs
  1995. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_ADV_LIST)))
  1996. break;
  1997. //get the count of selected OIDs and mark them
  1998. for(dwIndex=0; dwIndex<pCertMgrInfo->dwOIDInfo; dwIndex++)
  1999. {
  2000. //mark the selected OIDS. Keep track of
  2001. //if the OID selections have been changed
  2002. if(ListView_GetCheckState(hwndControl, dwIndex))
  2003. {
  2004. ((pCertMgrInfo->rgOIDInfo)[dwIndex]).fSelected=TRUE;
  2005. }
  2006. else
  2007. {
  2008. ((pCertMgrInfo->rgOIDInfo)[dwIndex]).fSelected=FALSE;
  2009. }
  2010. }
  2011. //save the advanced options to the registry
  2012. SaveAdvValueToReg(pCertMgrInfo);
  2013. EndDialog(hwndDlg, DIALOGUE_OK);
  2014. break;
  2015. }
  2016. }
  2017. //a combo box's selection has been changed
  2018. if(HIWORD(wParam) == CBN_SELCHANGE)
  2019. {
  2020. switch(LOWORD(wParam))
  2021. {
  2022. case IDC_CERTMGR_EXPORT_COMBO:
  2023. //the export format combo box has been changed
  2024. //get the selected item index
  2025. iIndex=(int)SendDlgItemMessage(hwndDlg,
  2026. IDC_CERTMGR_EXPORT_COMBO,
  2027. CB_GETCURSEL, 0, 0);
  2028. if(CB_ERR==iIndex)
  2029. break;
  2030. //enable the check box for the chain if
  2031. //PKCS#7 option is selected
  2032. if(2 == iIndex)
  2033. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT_CHECK), TRUE);
  2034. else
  2035. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT_CHECK), FALSE);
  2036. break;
  2037. }
  2038. }
  2039. break;
  2040. }
  2041. return FALSE;
  2042. }
  2043. //--------------------------------------------------------------
  2044. // The winProc for CertMgrDialogProc
  2045. //--------------------------------------------------------------
  2046. INT_PTR APIENTRY CertMgrDialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  2047. {
  2048. CERT_MGR_INFO *pCertMgrInfo=NULL;
  2049. PCCRYPTUI_CERT_MGR_STRUCT pCertMgrStruct=NULL;
  2050. HWND hWndListView=NULL;
  2051. HWND hWndControl=NULL;
  2052. DWORD dwIndex=0;
  2053. DWORD dwCount=0;
  2054. WCHAR wszText[MAX_STRING_SIZE];
  2055. BOOL fCanDelete=FALSE;
  2056. UINT rgIDS[]={IDS_COLUMN_SUBJECT,
  2057. IDS_COLUMN_ISSUER,
  2058. IDS_COLUMN_EXPIRE,
  2059. IDS_COLUMN_NAME};
  2060. NM_LISTVIEW FAR * pnmv=NULL;
  2061. LPNMLVKEYDOWN pnkd=NULL;
  2062. LV_COLUMNW lvC;
  2063. int listIndex=0;
  2064. LV_ITEM lvItem;
  2065. BOOL fPropertyChanged=FALSE;
  2066. HIMAGELIST hIml=NULL;
  2067. CRYPTUI_VIEWCERTIFICATE_STRUCT CertViewStruct;
  2068. CRYPTUI_WIZ_EXPORT_INFO CryptUIWizExportInfo;
  2069. UINT idsDeleteConfirm=0;
  2070. int iIndex=0;
  2071. DWORD dwSortParam=0;
  2072. HCERTSTORE hCertStore=NULL;
  2073. HWND hwnd=NULL;
  2074. DWORD cbData=0;
  2075. switch ( msg )
  2076. {
  2077. case WM_INITDIALOG:
  2078. pCertMgrInfo = (CERT_MGR_INFO *) lParam;
  2079. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR) pCertMgrInfo);
  2080. pCertMgrStruct=pCertMgrInfo->pCertMgrStruct;
  2081. if(NULL == pCertMgrStruct)
  2082. break;
  2083. //
  2084. // set the dialog title
  2085. //
  2086. if (pCertMgrStruct->pwszTitle)
  2087. {
  2088. SetWindowTextU(hwndDlg, pCertMgrStruct->pwszTitle);
  2089. }
  2090. //create the image list
  2091. hIml = ImageList_LoadImage(g_hmodThisDll, MAKEINTRESOURCE(IDB_CERT), 0, 1, RGB(255,0,255), IMAGE_BITMAP, 0);
  2092. //
  2093. // add the colums to the list view
  2094. //
  2095. hWndListView = GetDlgItem(hwndDlg, IDC_CERTMGR_LIST);
  2096. if(NULL==hWndListView)
  2097. break;
  2098. //set the image list
  2099. if (hIml != NULL)
  2100. {
  2101. ListView_SetImageList(hWndListView, hIml, LVSIL_SMALL);
  2102. }
  2103. dwCount=sizeof(rgIDS)/sizeof(rgIDS[0]);
  2104. //set up the common info for the column
  2105. memset(&lvC, 0, sizeof(LV_COLUMNW));
  2106. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  2107. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  2108. lvC.cx = 80; // Width of the column, in pixels.
  2109. lvC.iSubItem=0;
  2110. lvC.pszText = wszText; // The text for the column.
  2111. //inser the column one at a time
  2112. for(dwIndex=0; dwIndex<dwCount; dwIndex++)
  2113. {
  2114. //get the column header
  2115. wszText[0]=L'\0';
  2116. //set the column width. 1st and 2nd to 100,
  2117. //and the expiration to 75, the rest to 80
  2118. if( dwIndex < 2)
  2119. lvC.cx=130;
  2120. else
  2121. {
  2122. if( 2 == dwIndex)
  2123. lvC.cx=70;
  2124. else
  2125. lvC.cx=105;
  2126. }
  2127. LoadStringU(g_hmodThisDll, rgIDS[dwIndex], wszText, MAX_STRING_SIZE);
  2128. ListView_InsertColumnU(hWndListView, dwIndex, &lvC);
  2129. }
  2130. // set the style in the list view so that it highlights an entire line
  2131. SendMessageA(hWndListView, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
  2132. //Init tabs to the tab control.
  2133. hWndControl = GetDlgItem(hwndDlg, IDC_CERTMGR_TAB);
  2134. if(NULL==hWndControl)
  2135. break;
  2136. //add the tabs to the tabl control
  2137. InitTabControl(hWndControl, pCertMgrStruct);
  2138. // If CRYPTUI_CERT_MGR_PUBLISHER_TAB was set, then,
  2139. // select the 5th tab: Trusted Publishers, otherwise,
  2140. // select the 1st tab: Personal Certificate
  2141. TabCtrl_SetCurSel(
  2142. hWndControl,
  2143. (CRYPTUI_CERT_MGR_PUBLISHER_TAB ==
  2144. (pCertMgrStruct->dwFlags &
  2145. (CRYPTUI_CERT_MGR_TAB_MASK |
  2146. CRYPTUI_CERT_MGR_SINGLE_TAB_FLAG) )) ? 4 : 0
  2147. );
  2148. //Init the purpose combo box
  2149. InitPurposeCombo(hwndDlg,pCertMgrInfo);
  2150. //Init the certificates in the list view based on the tab selected
  2151. //and the purpose selected
  2152. RefreshCertListView(hwndDlg, pCertMgrInfo);
  2153. //Set the correct window title based on the tab selection
  2154. // RefreshWindowTitle(hwndDlg, (CRYPTUI_CERT_MGR_STRUCT *)pCertMgrStruct);
  2155. //register the listView window as the drop desitination
  2156. if(S_OK == CCertMgrDropTarget_CreateInstance(
  2157. hwndDlg,
  2158. pCertMgrInfo,
  2159. &(pCertMgrInfo->pIDropTarget)))
  2160. {
  2161. __try {
  2162. RegisterDragDrop(hWndListView, pCertMgrInfo->pIDropTarget);
  2163. } __except(EXCEPTION_EXECUTE_HANDLER) {
  2164. }
  2165. }
  2166. break;
  2167. case WM_NOTIFY:
  2168. pCertMgrInfo = (CERT_MGR_INFO *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  2169. if(NULL == pCertMgrInfo)
  2170. break;
  2171. pCertMgrStruct=pCertMgrInfo->pCertMgrStruct;
  2172. if(NULL == pCertMgrStruct)
  2173. break;
  2174. switch (((NMHDR FAR *) lParam)->code)
  2175. {
  2176. //the delete key has been pressed
  2177. case LVN_KEYDOWN:
  2178. pnkd = (LPNMLVKEYDOWN) lParam;
  2179. if(VK_DELETE == pnkd->wVKey)
  2180. {
  2181. if(NULL==(hWndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)))
  2182. break;
  2183. GetAllSelectedItem(hWndControl,
  2184. ALL_SELECTED_CAN_DELETE,
  2185. &fCanDelete);
  2186. if(!fCanDelete)
  2187. {
  2188. I_MessageBox(
  2189. hwndDlg,
  2190. IDS_CANNOT_DELETE_CERTS,
  2191. IDS_CERT_MGR_TITLE,
  2192. pCertMgrStruct->pwszTitle,
  2193. MB_ICONEXCLAMATION|MB_OK|MB_APPLMODAL);
  2194. }
  2195. else
  2196. {
  2197. //same action as user has click on the DELETE button
  2198. SendDlgItemMessage(hwndDlg,
  2199. IDC_CERTMGR_REMOVE,
  2200. BM_CLICK,
  2201. 0,0);
  2202. }
  2203. }
  2204. break;
  2205. //drag drop operation has begun
  2206. case LVN_BEGINDRAG:
  2207. case LVN_BEGINRDRAG:
  2208. pnmv = (LPNMLISTVIEW) lParam;
  2209. if(!pnmv)
  2210. break;
  2211. if(NULL==(hWndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)))
  2212. break;
  2213. listIndex = ListView_GetNextItem(
  2214. hWndControl,
  2215. -1,
  2216. LVNI_SELECTED
  2217. );
  2218. if(listIndex != -1)
  2219. //start the drag and drop
  2220. CertMgrUIStartDragDrop(pnmv, hWndControl,
  2221. pCertMgrInfo->dwExportFormat,
  2222. pCertMgrInfo->fExportChain);
  2223. break;
  2224. //the item has been selected
  2225. case LVN_ITEMCHANGED:
  2226. if(NULL==(hWndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)))
  2227. break;
  2228. pnmv = (LPNMLISTVIEW) lParam;
  2229. if(NULL==pnmv)
  2230. break;
  2231. if (pnmv->uNewState & LVIS_SELECTED)
  2232. {
  2233. //enable the export buttons
  2234. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT), TRUE);
  2235. //if more than one certificates are selected, diable the view button
  2236. if(ListView_GetSelectedCount(hWndControl) > 1)
  2237. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_VIEW), FALSE);
  2238. else
  2239. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_VIEW), TRUE);
  2240. //enable the delete window only if the certificate is deletable
  2241. GetAllSelectedItem(hWndControl,
  2242. ALL_SELECTED_CAN_DELETE,
  2243. &fCanDelete);
  2244. if(fCanDelete)
  2245. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_REMOVE), TRUE);
  2246. else
  2247. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_REMOVE), FALSE);
  2248. //display the details of the certificate if
  2249. //only 1 cert is selected
  2250. if(1 == ListView_GetSelectedCount(hWndControl))
  2251. {
  2252. RefreshCertDetails(hwndDlg, (PCCERT_CONTEXT)(pnmv->lParam));
  2253. }
  2254. else
  2255. {
  2256. //clear the ceritificate details group box
  2257. SetDlgItemTextU(hwndDlg, IDC_CERTMGR_PURPOSE, L" ");
  2258. }
  2259. }
  2260. else
  2261. {
  2262. //if the state is deselection
  2263. if(0 == ListView_GetSelectedCount(hWndControl))
  2264. {
  2265. //we diable the buttons if no certificate is selected
  2266. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_VIEW), FALSE);
  2267. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT), FALSE);
  2268. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_REMOVE), FALSE);
  2269. //clear the ceritificate details group box
  2270. SetDlgItemTextU(hwndDlg, IDC_CERTMGR_PURPOSE, L" ");
  2271. }
  2272. }
  2273. break;
  2274. //the column has been changed
  2275. case LVN_COLUMNCLICK:
  2276. pnmv = (NM_LISTVIEW FAR *) lParam;
  2277. //get the column number
  2278. dwSortParam=0;
  2279. switch(pnmv->iSubItem)
  2280. {
  2281. case 0:
  2282. case 1:
  2283. case 2:
  2284. case 3:
  2285. case 4:
  2286. dwSortParam=pCertMgrInfo->rgdwSortParam[pnmv->iSubItem];
  2287. break;
  2288. default:
  2289. dwSortParam=0;
  2290. break;
  2291. }
  2292. if(0!=dwSortParam)
  2293. {
  2294. //remember to flip the ascend ording
  2295. if(dwSortParam & SORT_COLUMN_ASCEND)
  2296. {
  2297. dwSortParam &= 0x0000FFFF;
  2298. dwSortParam |= SORT_COLUMN_DESCEND;
  2299. }
  2300. else
  2301. {
  2302. if(dwSortParam & SORT_COLUMN_DESCEND)
  2303. {
  2304. dwSortParam &= 0x0000FFFF;
  2305. dwSortParam |= SORT_COLUMN_ASCEND;
  2306. }
  2307. }
  2308. //sort the column
  2309. SendDlgItemMessage(hwndDlg,
  2310. IDC_CERTMGR_LIST,
  2311. LVM_SORTITEMS,
  2312. (WPARAM) (LPARAM) dwSortParam,
  2313. (LPARAM) (PFNLVCOMPARE)CompareCertificate);
  2314. pCertMgrInfo->rgdwSortParam[pnmv->iSubItem]=dwSortParam;
  2315. //remember the column number
  2316. pCertMgrInfo->iColumn=pnmv->iSubItem;
  2317. }
  2318. break;
  2319. //the tab has been changed
  2320. case TCN_SELCHANGE:
  2321. //we need to refresh the column sorting state
  2322. pCertMgrInfo->rgdwSortParam[0]=SORT_COLUMN_SUBJECT | SORT_COLUMN_ASCEND;
  2323. pCertMgrInfo->rgdwSortParam[1]=SORT_COLUMN_ISSUER | SORT_COLUMN_DESCEND;
  2324. pCertMgrInfo->rgdwSortParam[2]=SORT_COLUMN_EXPIRATION | SORT_COLUMN_DESCEND;
  2325. pCertMgrInfo->rgdwSortParam[3]=SORT_COLUMN_NAME | SORT_COLUMN_DESCEND;
  2326. pCertMgrInfo->rgdwSortParam[4]=SORT_COLUMN_NAME | SORT_COLUMN_DESCEND;
  2327. pCertMgrInfo->iColumn=0;
  2328. //if the tab is changed, we need to
  2329. //refresh the list view and certificate's
  2330. //detailed view
  2331. RefreshCertListView(hwndDlg, pCertMgrInfo);
  2332. //we also we to update the window title
  2333. //based on the tabl selection
  2334. //RefreshWindowTitle(hwndDlg, (CRYPTUI_CERT_MGR_STRUCT *)pCertMgrStruct);
  2335. break;
  2336. //double-click on the list view of the certificates
  2337. case NM_DBLCLK:
  2338. {
  2339. switch (((NMHDR FAR *) lParam)->idFrom)
  2340. {
  2341. case IDC_CERTMGR_LIST:
  2342. {
  2343. //get the window handle of the cert list view
  2344. if(NULL==(hWndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)))
  2345. break;
  2346. //get the selected cert
  2347. listIndex = ListView_GetNextItem(
  2348. hWndControl,
  2349. -1,
  2350. LVNI_SELECTED
  2351. );
  2352. if (listIndex != -1)
  2353. {
  2354. //get the selected certificate
  2355. memset(&lvItem, 0, sizeof(LV_ITEM));
  2356. lvItem.mask=LVIF_PARAM;
  2357. lvItem.iItem=listIndex;
  2358. if(ListView_GetItem(hWndControl, &lvItem))
  2359. {
  2360. //view certiificate
  2361. if(pCertMgrInfo->dwCertCount > (DWORD)listIndex)
  2362. {
  2363. memset(&CertViewStruct, 0, sizeof(CRYPTUI_VIEWCERTIFICATE_STRUCT));
  2364. CertViewStruct.dwSize=sizeof(CRYPTUI_VIEWCERTIFICATE_STRUCT);
  2365. CertViewStruct.pCertContext=(PCCERT_CONTEXT)(lvItem.lParam);
  2366. CertViewStruct.hwndParent=hwndDlg;
  2367. fPropertyChanged=FALSE;
  2368. CryptUIDlgViewCertificate(&CertViewStruct, &fPropertyChanged);
  2369. if(fPropertyChanged)
  2370. {
  2371. RefreshCertListView(hwndDlg, pCertMgrInfo);
  2372. //we reselect the one
  2373. ListView_SetItemState(
  2374. hWndControl,
  2375. listIndex,
  2376. LVIS_SELECTED,
  2377. LVIS_SELECTED);
  2378. }
  2379. }
  2380. }
  2381. }
  2382. break;
  2383. }
  2384. }
  2385. break;
  2386. }
  2387. #if (1) //DSIE: bug 264568.
  2388. case NM_SETFOCUS:
  2389. {
  2390. //get the window handle of the cert list view
  2391. if(NULL==(hWndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)))
  2392. break;
  2393. //get the selected cert
  2394. listIndex = ListView_GetNextItem(
  2395. hWndControl,
  2396. -1,
  2397. LVNI_FOCUSED
  2398. );
  2399. //select first item to show hilite.
  2400. if (listIndex == -1)
  2401. ListView_SetItemState(hWndControl,
  2402. 0,
  2403. LVIS_FOCUSED | LVIS_SELECTED,
  2404. LVIS_FOCUSED | LVIS_SELECTED);
  2405. break;
  2406. }
  2407. #endif
  2408. }
  2409. break;
  2410. case WM_DESTROY:
  2411. __try {
  2412. //revoke drag drop
  2413. RevokeDragDrop(GetDlgItem(hwndDlg, IDC_CERTMGR_LIST));
  2414. } __except(EXCEPTION_EXECUTE_HANDLER) {
  2415. }
  2416. pCertMgrInfo = (CERT_MGR_INFO *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  2417. if(pCertMgrInfo)
  2418. {
  2419. if(pCertMgrInfo->pIDropTarget)
  2420. pCertMgrInfo->pIDropTarget->Release();
  2421. }
  2422. // destroy the image list in the list view //
  2423. hWndListView = GetDlgItem(hwndDlg, IDC_CERTMGR_LIST);
  2424. if(NULL==hWndListView)
  2425. break;
  2426. //no need to destroy the image list. Handled by ListView
  2427. //ImageList_Destroy(ListView_GetImageList(hWndListView, LVSIL_SMALL));
  2428. break;
  2429. case WM_HELP:
  2430. case WM_CONTEXTMENU:
  2431. if (msg == WM_HELP)
  2432. {
  2433. hwnd = GetDlgItem(hwndDlg, ((LPHELPINFO)lParam)->iCtrlId);
  2434. }
  2435. else
  2436. {
  2437. hwnd = (HWND) wParam;
  2438. }
  2439. if ((hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)) &&
  2440. (hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_PURPOSE_COMBO)) &&
  2441. (hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_IMPORT)) &&
  2442. (hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT)) &&
  2443. (hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_VIEW)) &&
  2444. (hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_REMOVE)) &&
  2445. (hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_ADVANCE)) &&
  2446. (hwnd != GetDlgItem(hwndDlg, IDOK)) &&
  2447. (hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_PURPOSE)))
  2448. {
  2449. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
  2450. return TRUE;
  2451. }
  2452. else
  2453. {
  2454. return OnContextHelp(hwndDlg, msg, wParam, lParam, CertMgrMainHelpMap);
  2455. }
  2456. break;
  2457. case WM_COMMAND:
  2458. pCertMgrInfo = (CERT_MGR_INFO *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  2459. if(NULL == pCertMgrInfo)
  2460. break;
  2461. pCertMgrStruct=pCertMgrInfo->pCertMgrStruct;
  2462. if(NULL == pCertMgrStruct)
  2463. break;
  2464. //a control is clicked
  2465. if(HIWORD(wParam) == BN_CLICKED)
  2466. {
  2467. switch (LOWORD(wParam))
  2468. {
  2469. case IDC_CERTMGR_ADVANCE:
  2470. //lauch the advanced dialogue
  2471. if(DIALOGUE_OK == DialogBoxParamU(
  2472. g_hmodThisDll,
  2473. (LPCWSTR)(MAKEINTRESOURCE(IDD_CERTMGR_ADVANCED)),
  2474. hwndDlg,
  2475. CertMgrAdvancedProc,
  2476. (LPARAM) pCertMgrInfo))
  2477. {
  2478. //if the advanced OIDs' list has been changed,
  2479. //we need to refresh the list window
  2480. if(TRUE == pCertMgrInfo->fAdvOIDChanged)
  2481. {
  2482. //mark the flag
  2483. pCertMgrInfo->fAdvOIDChanged=FALSE;
  2484. //repopulate the combo box based on
  2485. //the new selection
  2486. RepopulatePurposeCombo(hwndDlg,
  2487. pCertMgrInfo);
  2488. //refresh the list window only if
  2489. //<advanced> is selected
  2490. if(IsAdvancedSelected(hwndDlg))
  2491. RefreshCertListView(hwndDlg, pCertMgrInfo);
  2492. }
  2493. }
  2494. break;
  2495. case IDC_CERTMGR_REMOVE:
  2496. //get the selected certificate
  2497. if(NULL==(hWndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)))
  2498. break;
  2499. //get the selected cert
  2500. listIndex = ListView_GetNextItem(
  2501. hWndControl,
  2502. -1,
  2503. LVNI_SELECTED
  2504. );
  2505. if (listIndex != -1)
  2506. {
  2507. //get the selected tab
  2508. if (pCertMgrStruct->dwFlags & CRYPTUI_CERT_MGR_SINGLE_TAB_FLAG)
  2509. iIndex = pCertMgrStruct->dwFlags & CRYPTUI_CERT_MGR_TAB_MASK;
  2510. else
  2511. iIndex=TabCtrl_GetCurSel(GetDlgItem(hwndDlg, IDC_CERTMGR_TAB));
  2512. if(-1==iIndex)
  2513. break;
  2514. //delete confirmation
  2515. switch(iIndex)
  2516. {
  2517. case 0:
  2518. idsDeleteConfirm=IDS_CERTMGR_PERSONAL_REMOVE;
  2519. break;
  2520. case 1:
  2521. idsDeleteConfirm=IDS_CERTMGR_OTHER_REMOVE;
  2522. break;
  2523. case 2:
  2524. idsDeleteConfirm=IDS_CERTMGR_CA_REMOVE;
  2525. break;
  2526. case 3:
  2527. idsDeleteConfirm=IDS_CERTMGR_ROOT_REMOVE;
  2528. break;
  2529. case 4:
  2530. idsDeleteConfirm=IDS_CERTMGR_PUBLISHER_REMOVE;
  2531. break;
  2532. default:
  2533. idsDeleteConfirm=IDS_CERTMGR_PERSONAL_REMOVE;
  2534. break;
  2535. }
  2536. iIndex=I_MessageBox(hwndDlg,
  2537. idsDeleteConfirm,
  2538. IDS_CERT_MGR_TITLE,
  2539. pCertMgrStruct->pwszTitle,
  2540. MB_ICONEXCLAMATION|MB_YESNO|MB_APPLMODAL);
  2541. if(IDYES == iIndex)
  2542. {
  2543. //delete all the selected certificates
  2544. GetAllSelectedItem(hWndControl,
  2545. ALL_SELECTED_DELETE,
  2546. NULL);
  2547. //refresh the list view since some certificates
  2548. //might be deleted
  2549. //send the tab control
  2550. SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM) 0, (LPARAM) NULL);
  2551. RefreshCertListView(hwndDlg, pCertMgrInfo);
  2552. }
  2553. }
  2554. else
  2555. {
  2556. //output the message
  2557. I_MessageBox(hwndDlg, IDS_HAS_TO_SELECT_CERT,
  2558. IDS_CERT_MGR_TITLE,
  2559. pCertMgrStruct->pwszTitle,
  2560. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  2561. }
  2562. break;
  2563. case IDC_CERTMGR_IMPORT:
  2564. {
  2565. DWORD dwTabIndex;
  2566. HCERTSTORE hTabStore = NULL;
  2567. // Import into the store associated with the
  2568. // currently selected tab
  2569. if (pCertMgrStruct->dwFlags & CRYPTUI_CERT_MGR_SINGLE_TAB_FLAG)
  2570. dwTabIndex = pCertMgrStruct->dwFlags & CRYPTUI_CERT_MGR_TAB_MASK;
  2571. else
  2572. dwTabIndex = TabCtrl_GetCurSel(
  2573. GetDlgItem(hwndDlg, IDC_CERTMGR_TAB));
  2574. if (TAB_STORE_NAME_CNT > dwTabIndex) {
  2575. hTabStore = CertOpenStore(
  2576. CERT_STORE_PROV_SYSTEM_W,
  2577. g_dwMsgAndCertEncodingType,
  2578. NULL,
  2579. CERT_STORE_MAXIMUM_ALLOWED_FLAG |
  2580. CERT_STORE_SET_LOCALIZED_NAME_FLAG |
  2581. CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG |
  2582. CERT_SYSTEM_STORE_CURRENT_USER,
  2583. rgpwszTabStoreName[dwTabIndex]
  2584. );
  2585. }
  2586. //call the certificate import wizard
  2587. CryptUIWizImport(
  2588. 0,
  2589. hwndDlg,
  2590. NULL,
  2591. NULL,
  2592. hTabStore);
  2593. if (hTabStore)
  2594. CertCloseStore(hTabStore, 0);
  2595. //refresh the list view since new certificates
  2596. //might be added
  2597. RefreshCertListView(hwndDlg, pCertMgrInfo);
  2598. }
  2599. break;
  2600. case IDC_CERTMGR_EXPORT:
  2601. //get the selected certificate
  2602. if(NULL==(hWndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)))
  2603. break;
  2604. //get the selected cert
  2605. listIndex = ListView_GetNextItem(
  2606. hWndControl,
  2607. -1,
  2608. LVNI_SELECTED
  2609. );
  2610. if (listIndex != -1)
  2611. {
  2612. //we call the export wizard differently based
  2613. //on single or multiple selection
  2614. if(ListView_GetSelectedCount(hWndControl) > 1)
  2615. {
  2616. //open a memory store
  2617. hCertStore=CertOpenStore(
  2618. CERT_STORE_PROV_MEMORY,
  2619. g_dwMsgAndCertEncodingType,
  2620. NULL,
  2621. 0,
  2622. NULL);
  2623. if(hCertStore)
  2624. {
  2625. GetAllSelectedItem(hWndControl,
  2626. ALL_SELECTED_COPY,
  2627. &hCertStore);
  2628. //call the export wizard
  2629. memset(&CryptUIWizExportInfo, 0, sizeof(CRYPTUI_WIZ_EXPORT_INFO));
  2630. CryptUIWizExportInfo.dwSize=sizeof(CRYPTUI_WIZ_EXPORT_INFO);
  2631. CryptUIWizExportInfo.dwSubjectChoice=CRYPTUI_WIZ_EXPORT_CERT_STORE_CERTIFICATES_ONLY;
  2632. CryptUIWizExportInfo.hCertStore=hCertStore;
  2633. CryptUIWizExport(0,
  2634. hwndDlg,
  2635. NULL,
  2636. &CryptUIWizExportInfo,
  2637. NULL);
  2638. CertCloseStore(hCertStore, 0);
  2639. hCertStore=NULL;
  2640. }
  2641. }
  2642. else
  2643. {
  2644. memset(&lvItem, 0, sizeof(LV_ITEM));
  2645. lvItem.mask=LVIF_PARAM;
  2646. lvItem.iItem=listIndex;
  2647. if(ListView_GetItem(hWndControl,
  2648. &lvItem))
  2649. {
  2650. if(pCertMgrInfo->dwCertCount > (DWORD)listIndex)
  2651. {
  2652. //call the export wizard
  2653. memset(&CryptUIWizExportInfo, 0, sizeof(CRYPTUI_WIZ_EXPORT_INFO));
  2654. CryptUIWizExportInfo.dwSize=sizeof(CRYPTUI_WIZ_EXPORT_INFO);
  2655. CryptUIWizExportInfo.dwSubjectChoice=CRYPTUI_WIZ_EXPORT_CERT_CONTEXT;
  2656. CryptUIWizExportInfo.pCertContext=(PCCERT_CONTEXT)(lvItem.lParam);
  2657. CryptUIWizExport(0,
  2658. hwndDlg,
  2659. NULL,
  2660. &CryptUIWizExportInfo,
  2661. NULL);
  2662. }
  2663. }
  2664. }
  2665. }
  2666. else
  2667. //output the message
  2668. I_MessageBox(hwndDlg, IDS_HAS_TO_SELECT_CERT,
  2669. IDS_CERT_MGR_TITLE,
  2670. pCertMgrStruct->pwszTitle,
  2671. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  2672. break;
  2673. case IDC_CERTMGR_VIEW:
  2674. //get the selected certificate
  2675. if(NULL==(hWndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)))
  2676. break;
  2677. //get the selected cert
  2678. listIndex = ListView_GetNextItem(
  2679. hWndControl,
  2680. -1,
  2681. LVNI_SELECTED
  2682. );
  2683. if (listIndex != -1)
  2684. {
  2685. //view certiificate
  2686. if(pCertMgrInfo->dwCertCount > (DWORD)listIndex)
  2687. {
  2688. memset(&lvItem, 0, sizeof(LV_ITEM));
  2689. lvItem.mask=LVIF_PARAM;
  2690. lvItem.iItem=listIndex;
  2691. if(ListView_GetItem(hWndControl,
  2692. &lvItem))
  2693. {
  2694. memset(&CertViewStruct, 0, sizeof(CRYPTUI_VIEWCERTIFICATE_STRUCT));
  2695. CertViewStruct.dwSize=sizeof(CRYPTUI_VIEWCERTIFICATE_STRUCT);
  2696. CertViewStruct.pCertContext=(PCCERT_CONTEXT)(lvItem.lParam);
  2697. CertViewStruct.hwndParent=hwndDlg;
  2698. fPropertyChanged=FALSE;
  2699. CryptUIDlgViewCertificate(&CertViewStruct, &fPropertyChanged);
  2700. if(fPropertyChanged)
  2701. {
  2702. RefreshCertListView(hwndDlg, pCertMgrInfo);
  2703. //we reselect the one
  2704. ListView_SetItemState(
  2705. hWndControl,
  2706. listIndex,
  2707. LVIS_SELECTED,
  2708. LVIS_SELECTED);
  2709. }
  2710. }
  2711. }
  2712. }
  2713. else
  2714. //output the message
  2715. I_MessageBox(hwndDlg, IDS_HAS_TO_SELECT_CERT,
  2716. IDS_CERT_MGR_TITLE,
  2717. pCertMgrStruct->pwszTitle,
  2718. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  2719. break;
  2720. case IDOK:
  2721. case IDCANCEL:
  2722. EndDialog(hwndDlg, NULL);
  2723. break;
  2724. default:
  2725. break;
  2726. }
  2727. }
  2728. //a combo box's selection has been changed
  2729. if(HIWORD(wParam) == CBN_SELCHANGE)
  2730. {
  2731. switch(LOWORD(wParam))
  2732. {
  2733. case IDC_CERTMGR_PURPOSE_COMBO:
  2734. //if the purpose is changed, we need to
  2735. //refresh the list view and certificate's
  2736. //detailed view
  2737. RefreshCertListView(hwndDlg, pCertMgrInfo);
  2738. break;
  2739. }
  2740. }
  2741. break;
  2742. }
  2743. return FALSE;
  2744. }
  2745. //--------------------------------------------------------------
  2746. //
  2747. // Save the advanced option from the registry
  2748. //--------------------------------------------------------------
  2749. void SaveAdvValueToReg(CERT_MGR_INFO *pCertMgrInfo)
  2750. {
  2751. HKEY hKeyExport=NULL;
  2752. HKEY hKeyPurpose=NULL;
  2753. DWORD dwDisposition=0;
  2754. DWORD dwExportFormat=0;
  2755. DWORD dwIndex=0;
  2756. LPSTR pszDefaultOID=NULL;
  2757. LPSTR pszOID=NULL;
  2758. if(NULL==pCertMgrInfo)
  2759. return;
  2760. //open a registry entry for the export format under HKEY_CURRENT_USER
  2761. if (ERROR_SUCCESS == RegCreateKeyExU(
  2762. HKEY_CURRENT_USER,
  2763. WSZCertMgrExportRegLocation,
  2764. 0,
  2765. NULL,
  2766. REG_OPTION_NON_VOLATILE,
  2767. KEY_ALL_ACCESS,
  2768. NULL,
  2769. &hKeyExport,
  2770. &dwDisposition))
  2771. {
  2772. //set the value
  2773. switch(pCertMgrInfo->dwExportFormat)
  2774. {
  2775. case CRYPTUI_WIZ_EXPORT_FORMAT_DER:
  2776. if(pCertMgrInfo->fExportChain)
  2777. dwExportFormat=4;
  2778. else
  2779. dwExportFormat=1;
  2780. break;
  2781. case CRYPTUI_WIZ_EXPORT_FORMAT_BASE64:
  2782. if(pCertMgrInfo->fExportChain)
  2783. dwExportFormat=5;
  2784. else
  2785. dwExportFormat=2;
  2786. break;
  2787. case CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7:
  2788. if(pCertMgrInfo->fExportChain)
  2789. dwExportFormat=6;
  2790. else
  2791. dwExportFormat=3;
  2792. break;
  2793. default:
  2794. break;
  2795. }
  2796. if(0 != dwExportFormat)
  2797. {
  2798. //set the value
  2799. RegSetValueExU(
  2800. hKeyExport,
  2801. WSZCertMgrExportName,
  2802. 0, // dwReserved
  2803. REG_DWORD,
  2804. (BYTE *) &dwExportFormat,
  2805. sizeof(dwExportFormat));
  2806. }
  2807. }
  2808. //open the registry entry for the advanced OIDs
  2809. dwDisposition=0;
  2810. if (ERROR_SUCCESS == RegCreateKeyExU(
  2811. HKEY_CURRENT_USER,
  2812. WSZCertMgrPurposeRegLocation,
  2813. 0,
  2814. NULL,
  2815. REG_OPTION_NON_VOLATILE,
  2816. KEY_ALL_ACCESS,
  2817. NULL,
  2818. &hKeyPurpose,
  2819. &dwDisposition))
  2820. {
  2821. //build a char "," seperated string for simple OID
  2822. pszDefaultOID=(LPSTR)WizardAlloc(sizeof(CHAR));
  2823. if(NULL == pszDefaultOID)
  2824. goto CLEANUP;
  2825. *pszDefaultOID=L'\0';
  2826. for(dwIndex=0; dwIndex<pCertMgrInfo->dwOIDInfo; dwIndex++)
  2827. {
  2828. if(FALSE==(pCertMgrInfo->rgOIDInfo)[dwIndex].fSelected)
  2829. {
  2830. if(strlen(pszDefaultOID)!=0)
  2831. strcat(pszDefaultOID, ",");
  2832. pszOID=(pCertMgrInfo->rgOIDInfo)[dwIndex].pszOID;
  2833. pszDefaultOID=(LPSTR)WizardRealloc(pszDefaultOID,
  2834. sizeof(CHAR)*(strlen(pszDefaultOID)+strlen(pszOID)+strlen(",")+1));
  2835. if(NULL==pszDefaultOID)
  2836. goto CLEANUP;
  2837. strcat(pszDefaultOID,pszOID);
  2838. }
  2839. }
  2840. //set the value
  2841. RegSetValueEx(
  2842. hKeyPurpose,
  2843. SZCertMgrPurposeName,
  2844. 0,
  2845. REG_SZ,
  2846. (BYTE *)(pszDefaultOID),
  2847. (strlen(pszDefaultOID) + 1) * sizeof(CHAR));
  2848. }
  2849. CLEANUP:
  2850. if(pszDefaultOID)
  2851. WizardFree(pszDefaultOID);
  2852. //close the registry keys
  2853. if(hKeyExport)
  2854. RegCloseKey(hKeyExport);
  2855. if(hKeyPurpose)
  2856. RegCloseKey(hKeyPurpose);
  2857. }
  2858. //--------------------------------------------------------------
  2859. //
  2860. // Get init value from the registry
  2861. //--------------------------------------------------------------
  2862. void GetInitValueFromReg(CERT_MGR_INFO *pCertMgrInfo)
  2863. {
  2864. HKEY hKeyExport=NULL;
  2865. HKEY hKeyPurpose=NULL;
  2866. DWORD dwType=0;
  2867. DWORD dwExportFormat=0;
  2868. DWORD cbExportFormat=0;
  2869. LPSTR pszDefaultOID=NULL;
  2870. DWORD cbDefaultOID=0;
  2871. LPSTR pszTok=NULL;
  2872. DWORD cTok = 0;
  2873. DWORD cCount=0;
  2874. CERT_ENHKEY_USAGE KeyUsage;
  2875. LPSTR rgBasicOID[]={szOID_PKIX_KP_CLIENT_AUTH,
  2876. szOID_PKIX_KP_EMAIL_PROTECTION};
  2877. BOOL fNoRegData=FALSE;
  2878. if(NULL==pCertMgrInfo)
  2879. return;
  2880. //memset
  2881. memset(&KeyUsage,0,sizeof(CERT_ENHKEY_USAGE));
  2882. //open the registry key if user has saved the advaced options
  2883. if(ERROR_SUCCESS == RegOpenKeyExU(HKEY_CURRENT_USER,
  2884. WSZCertMgrExportRegLocation,
  2885. 0,
  2886. KEY_READ,
  2887. &hKeyExport))
  2888. {
  2889. //get the data
  2890. cbExportFormat=sizeof(dwExportFormat);
  2891. if(ERROR_SUCCESS == RegQueryValueExU(
  2892. hKeyExport,
  2893. WSZCertMgrExportName,
  2894. NULL,
  2895. &dwType,
  2896. (BYTE *)&dwExportFormat,
  2897. &cbExportFormat))
  2898. {
  2899. // added check for reg_binary because on WIN95 OSR2 when the machine is changed
  2900. // from mutli-user profiles to single user profile, the registry DWORD values
  2901. // change to BINARY
  2902. //
  2903. if ((dwType == REG_DWORD) ||
  2904. (dwType == REG_BINARY))
  2905. {
  2906. switch(dwExportFormat)
  2907. {
  2908. case 1:
  2909. pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_DER;
  2910. pCertMgrInfo->fExportChain=FALSE;
  2911. break;
  2912. case 2:
  2913. pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_BASE64;
  2914. pCertMgrInfo->fExportChain=FALSE;
  2915. break;
  2916. case 3:
  2917. pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7;
  2918. pCertMgrInfo->fExportChain=FALSE;
  2919. break;
  2920. case 4:
  2921. pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_DER;
  2922. pCertMgrInfo->fExportChain=TRUE;
  2923. break;
  2924. case 5:
  2925. pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_BASE64;
  2926. pCertMgrInfo->fExportChain=TRUE;
  2927. break;
  2928. case 6:
  2929. pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7;
  2930. pCertMgrInfo->fExportChain=TRUE;
  2931. break;
  2932. default:
  2933. break;
  2934. }
  2935. }
  2936. }
  2937. }
  2938. //get the advanced purposed
  2939. if(ERROR_SUCCESS == RegOpenKeyExU(HKEY_CURRENT_USER,
  2940. WSZCertMgrPurposeRegLocation,
  2941. 0,
  2942. KEY_READ,
  2943. &hKeyPurpose))
  2944. {
  2945. dwType=0;
  2946. cbDefaultOID=0;
  2947. if((ERROR_SUCCESS == RegQueryValueEx(
  2948. hKeyPurpose,
  2949. SZCertMgrPurposeName,
  2950. NULL,
  2951. &dwType,
  2952. NULL,
  2953. &cbDefaultOID))&&(cbDefaultOID!=0))
  2954. {
  2955. pszDefaultOID=(LPSTR)WizardAlloc(cbDefaultOID);
  2956. if(NULL==pszDefaultOID)
  2957. goto CLEANUP;
  2958. if(ERROR_SUCCESS != RegQueryValueEx(
  2959. hKeyPurpose,
  2960. SZCertMgrPurposeName,
  2961. NULL,
  2962. &dwType,
  2963. (BYTE *)pszDefaultOID,
  2964. &cbDefaultOID))
  2965. goto CLEANUP;
  2966. //
  2967. // Count the number of OIDs as well as converting from comma delimited
  2968. // to NULL character delimited
  2969. //
  2970. if(0==strlen(pszDefaultOID))
  2971. fNoRegData=TRUE;
  2972. else
  2973. {
  2974. pszTok = strtok(pszDefaultOID, ",");
  2975. while ( pszTok != NULL )
  2976. {
  2977. cTok++;
  2978. pszTok = strtok(NULL, ",");
  2979. }
  2980. //
  2981. // Allocate a cert enhanced key usage structure and fill it in with
  2982. // the string tokens
  2983. //
  2984. pszTok = pszDefaultOID;
  2985. KeyUsage.cUsageIdentifier = cTok;
  2986. KeyUsage.rgpszUsageIdentifier = (LPSTR *)WizardAlloc(cTok * sizeof(LPSTR));
  2987. if(NULL==KeyUsage.rgpszUsageIdentifier)
  2988. goto CLEANUP;
  2989. for ( cCount = 0; cCount < cTok; cCount++ )
  2990. {
  2991. KeyUsage.rgpszUsageIdentifier[cCount] = pszTok;
  2992. pszTok = pszTok+strlen(pszTok)+1;
  2993. }
  2994. }
  2995. }
  2996. }
  2997. //set up the default OIDs if the registry is empty
  2998. if(0 == KeyUsage.cUsageIdentifier && TRUE != fNoRegData)
  2999. {
  3000. KeyUsage.cUsageIdentifier=2;
  3001. KeyUsage.rgpszUsageIdentifier=rgBasicOID;
  3002. }
  3003. //mark the OIDs as advanced for basic
  3004. for(cCount=0; cCount<pCertMgrInfo->dwOIDInfo; cCount++)
  3005. {
  3006. if(IsAdvancedOID(&KeyUsage,
  3007. (pCertMgrInfo->rgOIDInfo)[cCount].pszOID))
  3008. (pCertMgrInfo->rgOIDInfo)[cCount].fSelected=TRUE;
  3009. }
  3010. CLEANUP:
  3011. //free memory
  3012. if(pszDefaultOID)
  3013. {
  3014. WizardFree(pszDefaultOID);
  3015. if(KeyUsage.rgpszUsageIdentifier)
  3016. WizardFree(KeyUsage.rgpszUsageIdentifier);
  3017. }
  3018. //close the registry keys
  3019. if(hKeyExport)
  3020. RegCloseKey(hKeyExport);
  3021. if(hKeyPurpose)
  3022. RegCloseKey(hKeyPurpose);
  3023. return;
  3024. }
  3025. //--------------------------------------------------------------
  3026. //
  3027. // Parameters:
  3028. // pCryptUICertMgr IN Required
  3029. //
  3030. //
  3031. //--------------------------------------------------------------
  3032. BOOL
  3033. WINAPI
  3034. CryptUIDlgCertMgr(
  3035. IN PCCRYPTUI_CERT_MGR_STRUCT pCryptUICertMgr)
  3036. {
  3037. BOOL fResult=FALSE;
  3038. CERT_MGR_INFO CertMgrInfo;
  3039. HRESULT hr=S_OK;
  3040. DWORD dwException=0;
  3041. //check the input parameter
  3042. if(NULL==pCryptUICertMgr)
  3043. goto InvalidArgErr;
  3044. if(sizeof(CRYPTUI_CERT_MGR_STRUCT) != pCryptUICertMgr->dwSize)
  3045. goto InvalidArgErr;
  3046. if ((pCryptUICertMgr->dwFlags & CRYPTUI_CERT_MGR_TAB_MASK) >
  3047. CRYPTUI_CERT_MGR_PUBLISHER_TAB)
  3048. goto InvalidArgErr;
  3049. if (!WizardInit())
  3050. {
  3051. goto InitOIDErr;
  3052. }
  3053. //init struct
  3054. memset(&CertMgrInfo, 0, sizeof(CertMgrInfo));
  3055. CertMgrInfo.pCertMgrStruct=pCryptUICertMgr;
  3056. //get all the enhanced key usage OIDs
  3057. if(!InitPurposeOID(pCryptUICertMgr->pszInitUsageOID,
  3058. &(CertMgrInfo.dwOIDInfo),
  3059. &(CertMgrInfo.rgOIDInfo)))
  3060. goto InitOIDErr;
  3061. //init the column sort
  3062. CertMgrInfo.rgdwSortParam[0]=SORT_COLUMN_SUBJECT | SORT_COLUMN_ASCEND;
  3063. CertMgrInfo.rgdwSortParam[1]=SORT_COLUMN_ISSUER | SORT_COLUMN_DESCEND;
  3064. CertMgrInfo.rgdwSortParam[2]=SORT_COLUMN_EXPIRATION | SORT_COLUMN_DESCEND;
  3065. CertMgrInfo.rgdwSortParam[3]=SORT_COLUMN_NAME | SORT_COLUMN_DESCEND;
  3066. CertMgrInfo.rgdwSortParam[4]=SORT_COLUMN_NAME | SORT_COLUMN_DESCEND;
  3067. //we sort the 1st column
  3068. CertMgrInfo.iColumn=0;
  3069. //init the export format
  3070. CertMgrInfo.dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_DER;
  3071. CertMgrInfo.fExportChain=FALSE;
  3072. CertMgrInfo.fAdvOIDChanged=FALSE;
  3073. //init the OLE library
  3074. __try {
  3075. if(!SUCCEEDED(hr=OleInitialize(NULL)))
  3076. goto OLEInitErr;
  3077. //get the initialization from the registry
  3078. GetInitValueFromReg(&CertMgrInfo);
  3079. //call the dialog box
  3080. if (DialogBoxParamU(
  3081. g_hmodThisDll,
  3082. (LPCWSTR)(MAKEINTRESOURCE(IDD_CERTMGR_MAIN)),
  3083. (pCryptUICertMgr->hwndParent != NULL) ? pCryptUICertMgr->hwndParent : GetDesktopWindow(),
  3084. CertMgrDialogProc,
  3085. (LPARAM) &CertMgrInfo) == -1)
  3086. {
  3087. OleUninitialize();
  3088. goto DialogBoxErr;
  3089. }
  3090. OleUninitialize();
  3091. } __except(EXCEPTION_EXECUTE_HANDLER) {
  3092. dwException = GetExceptionCode();
  3093. goto ExceptionErr;
  3094. }
  3095. fResult=TRUE;
  3096. CommonReturn:
  3097. //free the cert arrays
  3098. FreeCerts(&CertMgrInfo);
  3099. //free the usage OID array
  3100. FreeUsageOID(CertMgrInfo.dwOIDInfo,
  3101. CertMgrInfo.rgOIDInfo);
  3102. return fResult;
  3103. ErrorReturn:
  3104. fResult=FALSE;
  3105. goto CommonReturn;
  3106. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  3107. TRACE_ERROR(DialogBoxErr);
  3108. TRACE_ERROR(InitOIDErr);
  3109. SET_ERROR_VAR(OLEInitErr, hr);
  3110. SET_ERROR_VAR(ExceptionErr, dwException)
  3111. }