Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3919 lines
129 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. {
  1574. FreeUsageOID(*pdwOIDInfo,*pprgOIDInfo);
  1575. *pdwOIDInfo=0;
  1576. *pprgOIDInfo=NULL;
  1577. goto TraceErr;
  1578. }
  1579. fResult=TRUE;
  1580. CommonReturn:
  1581. //free the memory
  1582. return fResult;
  1583. ErrorReturn:
  1584. fResult=FALSE;
  1585. goto CommonReturn;
  1586. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  1587. TRACE_ERROR(TraceErr);
  1588. }
  1589. //-----------------------------------------------------------------------
  1590. // Initialize the tab control
  1591. //-----------------------------------------------------------------------
  1592. void InitTabControl(HWND hWndControl,
  1593. PCCRYPTUI_CERT_MGR_STRUCT pCertMgrStruct)
  1594. {
  1595. DWORD dwIndex=0;
  1596. DWORD dwCount=0;
  1597. WCHAR wszText[MAX_STRING_SIZE];
  1598. UINT rgIDS[]={IDS_TAB_PERSONAL,
  1599. IDS_TAB_OTHER,
  1600. IDS_TAB_CA,
  1601. IDS_TAB_ROOT,
  1602. IDS_TAB_PUBLISHER,
  1603. };
  1604. TCITEMW tcItem;
  1605. if(!hWndControl)
  1606. return;
  1607. memset(&tcItem, 0, sizeof(TCITEM));
  1608. tcItem.mask=TCIF_TEXT;
  1609. tcItem.pszText=wszText;
  1610. if (pCertMgrStruct->dwFlags & CRYPTUI_CERT_MGR_SINGLE_TAB_FLAG)
  1611. {
  1612. dwIndex = pCertMgrStruct->dwFlags & CRYPTUI_CERT_MGR_TAB_MASK;
  1613. //get the column header
  1614. wszText[0]=L'\0';
  1615. LoadStringU(g_hmodThisDll, rgIDS[dwIndex], wszText, MAX_STRING_SIZE);
  1616. TabCtrl_InsertItemU(hWndControl,
  1617. 0,
  1618. &tcItem);
  1619. } else
  1620. {
  1621. dwCount=sizeof(rgIDS)/sizeof(rgIDS[0]);
  1622. //insert the tabs one at a time
  1623. for(dwIndex=0; dwIndex<dwCount; dwIndex++)
  1624. {
  1625. //get the column header
  1626. wszText[0]=L'\0';
  1627. LoadStringU(g_hmodThisDll, rgIDS[dwIndex], wszText, MAX_STRING_SIZE);
  1628. TabCtrl_InsertItemU(hWndControl,
  1629. dwIndex,
  1630. &tcItem);
  1631. }
  1632. }
  1633. return;
  1634. }
  1635. //----------------------------------------------------------------------------
  1636. //
  1637. // Free the array of usage OID info
  1638. //
  1639. //----------------------------------------------------------------------------
  1640. BOOL FreeUsageOID(DWORD dwOIDInfo,
  1641. PURPOSE_OID_INFO *pOIDInfo)
  1642. {
  1643. DWORD dwIndex=0;
  1644. if(pOIDInfo)
  1645. {
  1646. for(dwIndex=0; dwIndex < dwOIDInfo; dwIndex++)
  1647. {
  1648. if(pOIDInfo[dwIndex].pszOID)
  1649. WizardFree(pOIDInfo[dwIndex].pszOID);
  1650. if(pOIDInfo[dwIndex].pwszName)
  1651. WizardFree(pOIDInfo[dwIndex].pwszName);
  1652. }
  1653. WizardFree(pOIDInfo);
  1654. }
  1655. return TRUE;
  1656. }
  1657. //-----------------------------------------------------------------------
  1658. // Free the Certificates array
  1659. //-----------------------------------------------------------------------
  1660. void FreeCerts(CERT_MGR_INFO *pCertMgrInfo)
  1661. {
  1662. DWORD dwIndex=0;
  1663. if(!pCertMgrInfo)
  1664. return;
  1665. if(pCertMgrInfo->prgCertContext)
  1666. {
  1667. for(dwIndex=0; dwIndex<pCertMgrInfo->dwCertCount; dwIndex++)
  1668. {
  1669. if(pCertMgrInfo->prgCertContext[dwIndex])
  1670. CertFreeCertificateContext(pCertMgrInfo->prgCertContext[dwIndex]);
  1671. }
  1672. WizardFree(pCertMgrInfo->prgCertContext);
  1673. }
  1674. pCertMgrInfo->dwCertCount=0;
  1675. pCertMgrInfo->prgCertContext=NULL;
  1676. return;
  1677. }
  1678. //--------------------------------------------------------------
  1679. // Initialize the Purpose Combo
  1680. //--------------------------------------------------------------
  1681. void InitPurposeCombo(HWND hwndDlg,
  1682. CERT_MGR_INFO *pCertMgrInfo)
  1683. {
  1684. DWORD dwIndex=0;
  1685. DWORD dwCount=0;
  1686. WCHAR wszText[MAX_STRING_SIZE];
  1687. UINT rgIDS[]={IDS_OID_ADVANCED,
  1688. IDS_OID_ALL};
  1689. LPWSTR pwszInitOIDName=NULL;
  1690. CRYPTUI_CERT_MGR_STRUCT *pCertMgrStruct=NULL;
  1691. int iIndex=0;
  1692. if(!hwndDlg || !pCertMgrInfo)
  1693. return;
  1694. pCertMgrStruct=(CRYPTUI_CERT_MGR_STRUCT *)(pCertMgrInfo->pCertMgrStruct);
  1695. //delete all the entries in the comobox
  1696. SendDlgItemMessage(hwndDlg, IDC_CERTMGR_PURPOSE_COMBO,
  1697. CB_RESETCONTENT, 0, 0);
  1698. //copy all the basic OIDs to the comobox
  1699. for(dwIndex=0; dwIndex<pCertMgrInfo->dwOIDInfo; dwIndex++)
  1700. {
  1701. if(FALSE == (pCertMgrInfo->rgOIDInfo[dwIndex].fSelected))
  1702. {
  1703. SendDlgItemMessageU(hwndDlg, IDC_CERTMGR_PURPOSE_COMBO,
  1704. CB_ADDSTRING,
  1705. 0, (LPARAM)(pCertMgrInfo->rgOIDInfo[dwIndex].pwszName));
  1706. //looking for the initial OID
  1707. if(pCertMgrStruct->pszInitUsageOID)
  1708. {
  1709. if(0 == _stricmp(pCertMgrStruct->pszInitUsageOID,
  1710. pCertMgrInfo->rgOIDInfo[dwIndex].pszOID))
  1711. pwszInitOIDName=pCertMgrInfo->rgOIDInfo[dwIndex].pwszName;
  1712. }
  1713. }
  1714. }
  1715. //copy <advanced> and <all> to the list
  1716. dwCount=sizeof(rgIDS)/sizeof(rgIDS[0]);
  1717. //insert the column one at a time
  1718. for(dwIndex=0; dwIndex<dwCount; dwIndex++)
  1719. {
  1720. //get the column header
  1721. wszText[0]=L'\0';
  1722. LoadStringU(g_hmodThisDll, rgIDS[dwIndex], wszText, MAX_STRING_SIZE);
  1723. SendDlgItemMessageU(hwndDlg, IDC_CERTMGR_PURPOSE_COMBO,
  1724. CB_INSERTSTRING,
  1725. -1, (LPARAM)wszText);
  1726. }
  1727. //initialize the combo box
  1728. //use <advanced> is what user specify is not either
  1729. //client auth or secure e-mail
  1730. if(pCertMgrStruct->pszInitUsageOID)
  1731. {
  1732. if(NULL==pwszInitOIDName)
  1733. {
  1734. wszText[0]=L'\0';
  1735. LoadStringU(g_hmodThisDll, IDS_OID_ADVANCED, wszText, MAX_STRING_SIZE);
  1736. pwszInitOIDName=wszText;
  1737. }
  1738. }
  1739. //use <all> when NULL==pCertMgrStruct->pszInitUsageOID
  1740. if(NULL==pwszInitOIDName)
  1741. {
  1742. //use <all> as the initial case
  1743. wszText[0]=L'\0';
  1744. LoadStringU(g_hmodThisDll, IDS_OID_ALL, wszText, MAX_STRING_SIZE);
  1745. pwszInitOIDName=wszText;
  1746. }
  1747. iIndex=(int)SendDlgItemMessageU(
  1748. hwndDlg,
  1749. IDC_CERTMGR_PURPOSE_COMBO,
  1750. CB_FINDSTRINGEXACT,
  1751. -1,
  1752. (LPARAM)pwszInitOIDName);
  1753. if(CB_ERR == iIndex)
  1754. return;
  1755. //set the selection
  1756. SendDlgItemMessageU(hwndDlg, IDC_CERTMGR_PURPOSE_COMBO, CB_SETCURSEL, iIndex,0);
  1757. return;
  1758. }
  1759. //--------------------------------------------------------------
  1760. // Initialize the Purpose Combo
  1761. //--------------------------------------------------------------
  1762. void RepopulatePurposeCombo(HWND hwndDlg,
  1763. CERT_MGR_INFO *pCertMgrInfo)
  1764. {
  1765. LPWSTR pwszSelectedOIDName=NULL;
  1766. int iIndex=0;
  1767. if(!hwndDlg || !pCertMgrInfo)
  1768. return;
  1769. //get the selected string from the combo box
  1770. iIndex=(int)SendDlgItemMessage(hwndDlg, IDC_CERTMGR_PURPOSE_COMBO,
  1771. CB_GETCURSEL, 0, 0);
  1772. if(CB_ERR==iIndex)
  1773. return;
  1774. //get the selected purpose
  1775. if(CB_ERR == SendDlgItemMessageU_GETLBTEXT(hwndDlg,
  1776. IDC_CERTMGR_PURPOSE_COMBO,
  1777. iIndex, &pwszSelectedOIDName))
  1778. goto CLEANUP;
  1779. InitPurposeCombo(hwndDlg, pCertMgrInfo);
  1780. iIndex=(int)SendDlgItemMessageU(
  1781. hwndDlg,
  1782. IDC_CERTMGR_PURPOSE_COMBO,
  1783. CB_FINDSTRINGEXACT,
  1784. -1,
  1785. (LPARAM)pwszSelectedOIDName);
  1786. if(CB_ERR == iIndex)
  1787. goto CLEANUP;
  1788. //set the selection
  1789. SendDlgItemMessageU(hwndDlg, IDC_CERTMGR_PURPOSE_COMBO, CB_SETCURSEL, iIndex,0);
  1790. CLEANUP:
  1791. if(pwszSelectedOIDName)
  1792. WizardFree(pwszSelectedOIDName);
  1793. return;
  1794. }
  1795. //--------------------------------------------------------------
  1796. // The winProc for the advanced option diagloue for certMgr UI
  1797. //--------------------------------------------------------------
  1798. INT_PTR APIENTRY CertMgrAdvancedProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  1799. {
  1800. CERT_MGR_INFO *pCertMgrInfo=NULL;
  1801. PCCRYPTUI_CERT_MGR_STRUCT pCertMgrStruct=NULL;
  1802. UINT rgIDS[]={IDS_CERTMGR_DER,
  1803. IDS_CERTMGR_BASE64,
  1804. IDS_CERTMGR_PKCS7};
  1805. WCHAR wszText[MAX_STRING_SIZE];
  1806. DWORD dwCount=0;
  1807. DWORD dwIndex=0;
  1808. DWORD dwSelectedIndex=0;
  1809. LV_ITEMW lvItem;
  1810. LV_COLUMNW lvC;
  1811. HWND hwndControl=NULL;
  1812. int iIndex=0;
  1813. int listIndex=0;
  1814. NM_LISTVIEW FAR * pnmv=NULL;
  1815. HWND hwnd=NULL;
  1816. switch ( msg )
  1817. {
  1818. case WM_INITDIALOG:
  1819. pCertMgrInfo = (CERT_MGR_INFO *) lParam;
  1820. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR) pCertMgrInfo);
  1821. pCertMgrStruct=pCertMgrInfo->pCertMgrStruct;
  1822. if(NULL == pCertMgrStruct)
  1823. break;
  1824. //init the export format control
  1825. dwCount=sizeof(rgIDS)/sizeof(rgIDS[0]);
  1826. for(dwIndex=0; dwIndex < dwCount; dwIndex++)
  1827. {
  1828. LoadStringU(g_hmodThisDll,
  1829. rgIDS[dwIndex],
  1830. wszText,
  1831. MAX_STRING_SIZE);
  1832. SendDlgItemMessageU(hwndDlg,
  1833. IDC_CERTMGR_EXPORT_COMBO,
  1834. CB_INSERTSTRING,
  1835. -1,
  1836. (LPARAM)wszText);
  1837. }
  1838. //select the export format based on the selection
  1839. switch (pCertMgrInfo->dwExportFormat)
  1840. {
  1841. case CRYPTUI_WIZ_EXPORT_FORMAT_DER:
  1842. dwSelectedIndex=0;
  1843. break;
  1844. case CRYPTUI_WIZ_EXPORT_FORMAT_BASE64:
  1845. dwSelectedIndex=1;
  1846. break;
  1847. case CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7:
  1848. dwSelectedIndex=2;
  1849. break;
  1850. default:
  1851. dwSelectedIndex=0;
  1852. }
  1853. SendDlgItemMessageU(hwndDlg, IDC_CERTMGR_EXPORT_COMBO,
  1854. CB_SETCURSEL, (WPARAM)dwSelectedIndex,0);
  1855. //init the chain check-box
  1856. if(pCertMgrInfo->fExportChain)
  1857. SendDlgItemMessage(hwndDlg, IDC_CERTMGR_EXPORT_CHECK, BM_SETCHECK, 1, 0);
  1858. else
  1859. SendDlgItemMessage(hwndDlg, IDC_CERTMGR_EXPORT_CHECK, BM_SETCHECK, 0, 0);
  1860. if(dwSelectedIndex != 2)
  1861. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT_CHECK), FALSE);
  1862. else
  1863. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT_CHECK), TRUE);
  1864. //init the advanced OID list
  1865. hwndControl = GetDlgItem(hwndDlg, IDC_CERTMGR_ADV_LIST);
  1866. //mark the list is selected by a check box
  1867. ListView_SetExtendedListViewStyle(hwndControl, LVS_EX_CHECKBOXES);
  1868. //insert a column into the list view
  1869. memset(&lvC, 0, sizeof(LV_COLUMNW));
  1870. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  1871. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  1872. lvC.cx =10; // (dwMaxSize+2)*7; // Width of the column, in pixels.
  1873. lvC.pszText = L""; // The text for the column.
  1874. lvC.iSubItem=0;
  1875. if (ListView_InsertColumnU(hwndControl, 0, &lvC) == -1)
  1876. break;
  1877. //populate the list
  1878. memset(&lvItem, 0, sizeof(LV_ITEMW));
  1879. lvItem.mask=LVIF_TEXT | LVIF_STATE;
  1880. for(dwIndex=0; dwIndex<pCertMgrInfo->dwOIDInfo; dwIndex++)
  1881. {
  1882. lvItem.iItem=dwIndex;
  1883. lvItem.pszText=(pCertMgrInfo->rgOIDInfo[dwIndex]).pwszName;
  1884. lvItem.cchTextMax=sizeof(WCHAR)*(1+wcslen((pCertMgrInfo->rgOIDInfo[dwIndex]).pwszName));
  1885. lvItem.stateMask = LVIS_STATEIMAGEMASK;
  1886. lvItem.state = (pCertMgrInfo->rgOIDInfo[dwIndex]).fSelected ? 0x00002000 : 0x00001000;
  1887. // insert and set state
  1888. ListView_SetItemState(hwndControl,
  1889. ListView_InsertItemU(hwndControl, &lvItem),
  1890. (pCertMgrInfo->rgOIDInfo[dwIndex]).fSelected ? 0x00002000 : 0x00001000,
  1891. LVIS_STATEIMAGEMASK);
  1892. }
  1893. //autosize the column
  1894. ListView_SetColumnWidth(hwndControl, 0, LVSCW_AUTOSIZE);
  1895. #if (1) // DSIE: bug 282268.
  1896. ListView_SetItemState(hwndControl,
  1897. 0,
  1898. LVIS_FOCUSED | LVIS_SELECTED,
  1899. LVIS_FOCUSED | LVIS_SELECTED);
  1900. #endif
  1901. break;
  1902. case WM_NOTIFY:
  1903. pCertMgrInfo = (CERT_MGR_INFO *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  1904. if(NULL == pCertMgrInfo)
  1905. break;
  1906. pCertMgrStruct=pCertMgrInfo->pCertMgrStruct;
  1907. if(NULL == pCertMgrStruct)
  1908. break;
  1909. switch (((NMHDR FAR *) lParam)->code)
  1910. {
  1911. case LVN_ITEMCHANGED:
  1912. //if the state of the advanced OID check box
  1913. //has been changed, mark the flag
  1914. pnmv = (NM_LISTVIEW FAR *) lParam;
  1915. if(NULL==pnmv)
  1916. break;
  1917. //see if the new item is de-selected
  1918. if(pnmv->uChanged & LVIF_STATE)
  1919. pCertMgrInfo->fAdvOIDChanged=TRUE;
  1920. break;
  1921. }
  1922. break;
  1923. case WM_DESTROY:
  1924. break;
  1925. case WM_HELP:
  1926. case WM_CONTEXTMENU:
  1927. if (msg == WM_HELP)
  1928. {
  1929. hwnd = GetDlgItem(hwndDlg, ((LPHELPINFO)lParam)->iCtrlId);
  1930. }
  1931. else
  1932. {
  1933. hwnd = (HWND) wParam;
  1934. }
  1935. if ((hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_ADV_LIST)) &&
  1936. (hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT_COMBO)) &&
  1937. (hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT_CHECK)) &&
  1938. (hwnd != GetDlgItem(hwndDlg, IDOK)) &&
  1939. (hwnd != GetDlgItem(hwndDlg, IDCANCEL)))
  1940. {
  1941. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
  1942. return TRUE;
  1943. }
  1944. else
  1945. {
  1946. return OnContextHelp(hwndDlg, msg, wParam, lParam, CertMgrAdvHelpMap);
  1947. }
  1948. break;
  1949. case WM_COMMAND:
  1950. pCertMgrInfo = (CERT_MGR_INFO *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  1951. if(NULL == pCertMgrInfo)
  1952. break;
  1953. pCertMgrStruct=pCertMgrInfo->pCertMgrStruct;
  1954. if(NULL == pCertMgrStruct)
  1955. break;
  1956. //a control is clicked
  1957. if(HIWORD(wParam) == BN_CLICKED)
  1958. {
  1959. switch (LOWORD(wParam))
  1960. {
  1961. case IDCANCEL:
  1962. pCertMgrInfo->fAdvOIDChanged=FALSE;
  1963. EndDialog(hwndDlg, DIALOGUE_CANCEL);
  1964. break;
  1965. case IDOK:
  1966. //the OK button is selected
  1967. //get the default export format
  1968. iIndex=(int)SendDlgItemMessage(hwndDlg,
  1969. IDC_CERTMGR_EXPORT_COMBO,
  1970. CB_GETCURSEL, 0, 0);
  1971. if(CB_ERR==iIndex)
  1972. break;
  1973. switch(iIndex)
  1974. {
  1975. case 0:
  1976. pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_DER;
  1977. break;
  1978. case 1:
  1979. pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_BASE64;
  1980. break;
  1981. case 2:
  1982. pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7;
  1983. break;
  1984. default:
  1985. pCertMgrInfo->dwExportFormat=0;
  1986. break;
  1987. }
  1988. if(TRUE==SendDlgItemMessage(
  1989. hwndDlg,
  1990. IDC_CERTMGR_EXPORT_CHECK,
  1991. BM_GETCHECK,
  1992. 0,0))
  1993. pCertMgrInfo->fExportChain=TRUE;
  1994. else
  1995. pCertMgrInfo->fExportChain=FALSE;
  1996. //get the list of advanded OIDs
  1997. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_ADV_LIST)))
  1998. break;
  1999. //get the count of selected OIDs and mark them
  2000. for(dwIndex=0; dwIndex<pCertMgrInfo->dwOIDInfo; dwIndex++)
  2001. {
  2002. //mark the selected OIDS. Keep track of
  2003. //if the OID selections have been changed
  2004. if(ListView_GetCheckState(hwndControl, dwIndex))
  2005. {
  2006. ((pCertMgrInfo->rgOIDInfo)[dwIndex]).fSelected=TRUE;
  2007. }
  2008. else
  2009. {
  2010. ((pCertMgrInfo->rgOIDInfo)[dwIndex]).fSelected=FALSE;
  2011. }
  2012. }
  2013. //save the advanced options to the registry
  2014. SaveAdvValueToReg(pCertMgrInfo);
  2015. EndDialog(hwndDlg, DIALOGUE_OK);
  2016. break;
  2017. }
  2018. }
  2019. //a combo box's selection has been changed
  2020. if(HIWORD(wParam) == CBN_SELCHANGE)
  2021. {
  2022. switch(LOWORD(wParam))
  2023. {
  2024. case IDC_CERTMGR_EXPORT_COMBO:
  2025. //the export format combo box has been changed
  2026. //get the selected item index
  2027. iIndex=(int)SendDlgItemMessage(hwndDlg,
  2028. IDC_CERTMGR_EXPORT_COMBO,
  2029. CB_GETCURSEL, 0, 0);
  2030. if(CB_ERR==iIndex)
  2031. break;
  2032. //enable the check box for the chain if
  2033. //PKCS#7 option is selected
  2034. if(2 == iIndex)
  2035. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT_CHECK), TRUE);
  2036. else
  2037. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT_CHECK), FALSE);
  2038. break;
  2039. }
  2040. }
  2041. break;
  2042. }
  2043. return FALSE;
  2044. }
  2045. //--------------------------------------------------------------
  2046. // The winProc for CertMgrDialogProc
  2047. //--------------------------------------------------------------
  2048. INT_PTR APIENTRY CertMgrDialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  2049. {
  2050. CERT_MGR_INFO *pCertMgrInfo=NULL;
  2051. PCCRYPTUI_CERT_MGR_STRUCT pCertMgrStruct=NULL;
  2052. HWND hWndListView=NULL;
  2053. HWND hWndControl=NULL;
  2054. DWORD dwIndex=0;
  2055. DWORD dwCount=0;
  2056. WCHAR wszText[MAX_STRING_SIZE];
  2057. BOOL fCanDelete=FALSE;
  2058. UINT rgIDS[]={IDS_COLUMN_SUBJECT,
  2059. IDS_COLUMN_ISSUER,
  2060. IDS_COLUMN_EXPIRE,
  2061. IDS_COLUMN_NAME};
  2062. NM_LISTVIEW FAR * pnmv=NULL;
  2063. LPNMLVKEYDOWN pnkd=NULL;
  2064. LV_COLUMNW lvC;
  2065. int listIndex=0;
  2066. LV_ITEM lvItem;
  2067. BOOL fPropertyChanged=FALSE;
  2068. HIMAGELIST hIml=NULL;
  2069. CRYPTUI_VIEWCERTIFICATE_STRUCT CertViewStruct;
  2070. CRYPTUI_WIZ_EXPORT_INFO CryptUIWizExportInfo;
  2071. UINT idsDeleteConfirm=0;
  2072. int iIndex=0;
  2073. DWORD dwSortParam=0;
  2074. HCERTSTORE hCertStore=NULL;
  2075. HWND hwnd=NULL;
  2076. DWORD cbData=0;
  2077. switch ( msg )
  2078. {
  2079. case WM_INITDIALOG:
  2080. pCertMgrInfo = (CERT_MGR_INFO *) lParam;
  2081. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR) pCertMgrInfo);
  2082. pCertMgrStruct=pCertMgrInfo->pCertMgrStruct;
  2083. if(NULL == pCertMgrStruct)
  2084. break;
  2085. //
  2086. // set the dialog title
  2087. //
  2088. if (pCertMgrStruct->pwszTitle)
  2089. {
  2090. SetWindowTextU(hwndDlg, pCertMgrStruct->pwszTitle);
  2091. }
  2092. //create the image list
  2093. hIml = ImageList_LoadImage(g_hmodThisDll, MAKEINTRESOURCE(IDB_CERT), 0, 1, RGB(255,0,255), IMAGE_BITMAP, 0);
  2094. //
  2095. // add the colums to the list view
  2096. //
  2097. hWndListView = GetDlgItem(hwndDlg, IDC_CERTMGR_LIST);
  2098. if(NULL==hWndListView)
  2099. break;
  2100. //set the image list
  2101. if (hIml != NULL)
  2102. {
  2103. ListView_SetImageList(hWndListView, hIml, LVSIL_SMALL);
  2104. }
  2105. dwCount=sizeof(rgIDS)/sizeof(rgIDS[0]);
  2106. //set up the common info for the column
  2107. memset(&lvC, 0, sizeof(LV_COLUMNW));
  2108. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  2109. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  2110. lvC.cx = 80; // Width of the column, in pixels.
  2111. lvC.iSubItem=0;
  2112. lvC.pszText = wszText; // The text for the column.
  2113. //inser the column one at a time
  2114. for(dwIndex=0; dwIndex<dwCount; dwIndex++)
  2115. {
  2116. //get the column header
  2117. wszText[0]=L'\0';
  2118. //set the column width. 1st and 2nd to 100,
  2119. //and the expiration to 75, the rest to 80
  2120. if( dwIndex < 2)
  2121. lvC.cx=130;
  2122. else
  2123. {
  2124. if( 2 == dwIndex)
  2125. lvC.cx=70;
  2126. else
  2127. lvC.cx=105;
  2128. }
  2129. LoadStringU(g_hmodThisDll, rgIDS[dwIndex], wszText, MAX_STRING_SIZE);
  2130. ListView_InsertColumnU(hWndListView, dwIndex, &lvC);
  2131. }
  2132. // set the style in the list view so that it highlights an entire line
  2133. SendMessageA(hWndListView, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
  2134. //Init tabs to the tab control.
  2135. hWndControl = GetDlgItem(hwndDlg, IDC_CERTMGR_TAB);
  2136. if(NULL==hWndControl)
  2137. break;
  2138. //add the tabs to the tabl control
  2139. InitTabControl(hWndControl, pCertMgrStruct);
  2140. // If CRYPTUI_CERT_MGR_PUBLISHER_TAB was set, then,
  2141. // select the 5th tab: Trusted Publishers, otherwise,
  2142. // select the 1st tab: Personal Certificate
  2143. TabCtrl_SetCurSel(
  2144. hWndControl,
  2145. (CRYPTUI_CERT_MGR_PUBLISHER_TAB ==
  2146. (pCertMgrStruct->dwFlags &
  2147. (CRYPTUI_CERT_MGR_TAB_MASK |
  2148. CRYPTUI_CERT_MGR_SINGLE_TAB_FLAG) )) ? 4 : 0
  2149. );
  2150. //Init the purpose combo box
  2151. InitPurposeCombo(hwndDlg,pCertMgrInfo);
  2152. //Init the certificates in the list view based on the tab selected
  2153. //and the purpose selected
  2154. RefreshCertListView(hwndDlg, pCertMgrInfo);
  2155. //Set the correct window title based on the tab selection
  2156. // RefreshWindowTitle(hwndDlg, (CRYPTUI_CERT_MGR_STRUCT *)pCertMgrStruct);
  2157. //register the listView window as the drop desitination
  2158. if(S_OK == CCertMgrDropTarget_CreateInstance(
  2159. hwndDlg,
  2160. pCertMgrInfo,
  2161. &(pCertMgrInfo->pIDropTarget)))
  2162. {
  2163. __try {
  2164. RegisterDragDrop(hWndListView, pCertMgrInfo->pIDropTarget);
  2165. } __except(EXCEPTION_EXECUTE_HANDLER) {
  2166. }
  2167. }
  2168. break;
  2169. case WM_NOTIFY:
  2170. pCertMgrInfo = (CERT_MGR_INFO *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  2171. if(NULL == pCertMgrInfo)
  2172. break;
  2173. pCertMgrStruct=pCertMgrInfo->pCertMgrStruct;
  2174. if(NULL == pCertMgrStruct)
  2175. break;
  2176. switch (((NMHDR FAR *) lParam)->code)
  2177. {
  2178. //the delete key has been pressed
  2179. case LVN_KEYDOWN:
  2180. pnkd = (LPNMLVKEYDOWN) lParam;
  2181. if(VK_DELETE == pnkd->wVKey)
  2182. {
  2183. if(NULL==(hWndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)))
  2184. break;
  2185. GetAllSelectedItem(hWndControl,
  2186. ALL_SELECTED_CAN_DELETE,
  2187. &fCanDelete);
  2188. if(!fCanDelete)
  2189. {
  2190. I_MessageBox(
  2191. hwndDlg,
  2192. IDS_CANNOT_DELETE_CERTS,
  2193. IDS_CERT_MGR_TITLE,
  2194. pCertMgrStruct->pwszTitle,
  2195. MB_ICONEXCLAMATION|MB_OK|MB_APPLMODAL);
  2196. }
  2197. else
  2198. {
  2199. //same action as user has click on the DELETE button
  2200. SendDlgItemMessage(hwndDlg,
  2201. IDC_CERTMGR_REMOVE,
  2202. BM_CLICK,
  2203. 0,0);
  2204. }
  2205. }
  2206. break;
  2207. //drag drop operation has begun
  2208. case LVN_BEGINDRAG:
  2209. case LVN_BEGINRDRAG:
  2210. pnmv = (LPNMLISTVIEW) lParam;
  2211. if(!pnmv)
  2212. break;
  2213. if(NULL==(hWndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)))
  2214. break;
  2215. listIndex = ListView_GetNextItem(
  2216. hWndControl,
  2217. -1,
  2218. LVNI_SELECTED
  2219. );
  2220. if(listIndex != -1)
  2221. //start the drag and drop
  2222. CertMgrUIStartDragDrop(pnmv, hWndControl,
  2223. pCertMgrInfo->dwExportFormat,
  2224. pCertMgrInfo->fExportChain);
  2225. break;
  2226. //the item has been selected
  2227. case LVN_ITEMCHANGED:
  2228. if(NULL==(hWndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)))
  2229. break;
  2230. pnmv = (LPNMLISTVIEW) lParam;
  2231. if(NULL==pnmv)
  2232. break;
  2233. if (pnmv->uNewState & LVIS_SELECTED)
  2234. {
  2235. //enable the export buttons
  2236. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT), TRUE);
  2237. //if more than one certificates are selected, diable the view button
  2238. if(ListView_GetSelectedCount(hWndControl) > 1)
  2239. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_VIEW), FALSE);
  2240. else
  2241. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_VIEW), TRUE);
  2242. //enable the delete window only if the certificate is deletable
  2243. GetAllSelectedItem(hWndControl,
  2244. ALL_SELECTED_CAN_DELETE,
  2245. &fCanDelete);
  2246. if(fCanDelete)
  2247. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_REMOVE), TRUE);
  2248. else
  2249. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_REMOVE), FALSE);
  2250. //display the details of the certificate if
  2251. //only 1 cert is selected
  2252. if(1 == ListView_GetSelectedCount(hWndControl))
  2253. {
  2254. RefreshCertDetails(hwndDlg, (PCCERT_CONTEXT)(pnmv->lParam));
  2255. }
  2256. else
  2257. {
  2258. //clear the ceritificate details group box
  2259. SetDlgItemTextU(hwndDlg, IDC_CERTMGR_PURPOSE, L" ");
  2260. }
  2261. }
  2262. else
  2263. {
  2264. //if the state is deselection
  2265. if(0 == ListView_GetSelectedCount(hWndControl))
  2266. {
  2267. //we diable the buttons if no certificate is selected
  2268. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_VIEW), FALSE);
  2269. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT), FALSE);
  2270. EnableWindow(GetDlgItem(hwndDlg, IDC_CERTMGR_REMOVE), FALSE);
  2271. //clear the ceritificate details group box
  2272. SetDlgItemTextU(hwndDlg, IDC_CERTMGR_PURPOSE, L" ");
  2273. }
  2274. }
  2275. break;
  2276. //the column has been changed
  2277. case LVN_COLUMNCLICK:
  2278. pnmv = (NM_LISTVIEW FAR *) lParam;
  2279. //get the column number
  2280. dwSortParam=0;
  2281. switch(pnmv->iSubItem)
  2282. {
  2283. case 0:
  2284. case 1:
  2285. case 2:
  2286. case 3:
  2287. case 4:
  2288. dwSortParam=pCertMgrInfo->rgdwSortParam[pnmv->iSubItem];
  2289. break;
  2290. default:
  2291. dwSortParam=0;
  2292. break;
  2293. }
  2294. if(0!=dwSortParam)
  2295. {
  2296. //remember to flip the ascend ording
  2297. if(dwSortParam & SORT_COLUMN_ASCEND)
  2298. {
  2299. dwSortParam &= 0x0000FFFF;
  2300. dwSortParam |= SORT_COLUMN_DESCEND;
  2301. }
  2302. else
  2303. {
  2304. if(dwSortParam & SORT_COLUMN_DESCEND)
  2305. {
  2306. dwSortParam &= 0x0000FFFF;
  2307. dwSortParam |= SORT_COLUMN_ASCEND;
  2308. }
  2309. }
  2310. //sort the column
  2311. SendDlgItemMessage(hwndDlg,
  2312. IDC_CERTMGR_LIST,
  2313. LVM_SORTITEMS,
  2314. (WPARAM) (LPARAM) dwSortParam,
  2315. (LPARAM) (PFNLVCOMPARE)CompareCertificate);
  2316. pCertMgrInfo->rgdwSortParam[pnmv->iSubItem]=dwSortParam;
  2317. //remember the column number
  2318. pCertMgrInfo->iColumn=pnmv->iSubItem;
  2319. }
  2320. break;
  2321. //the tab has been changed
  2322. case TCN_SELCHANGE:
  2323. //we need to refresh the column sorting state
  2324. pCertMgrInfo->rgdwSortParam[0]=SORT_COLUMN_SUBJECT | SORT_COLUMN_ASCEND;
  2325. pCertMgrInfo->rgdwSortParam[1]=SORT_COLUMN_ISSUER | SORT_COLUMN_DESCEND;
  2326. pCertMgrInfo->rgdwSortParam[2]=SORT_COLUMN_EXPIRATION | SORT_COLUMN_DESCEND;
  2327. pCertMgrInfo->rgdwSortParam[3]=SORT_COLUMN_NAME | SORT_COLUMN_DESCEND;
  2328. pCertMgrInfo->rgdwSortParam[4]=SORT_COLUMN_NAME | SORT_COLUMN_DESCEND;
  2329. pCertMgrInfo->iColumn=0;
  2330. //if the tab is changed, we need to
  2331. //refresh the list view and certificate's
  2332. //detailed view
  2333. RefreshCertListView(hwndDlg, pCertMgrInfo);
  2334. //we also we to update the window title
  2335. //based on the tabl selection
  2336. //RefreshWindowTitle(hwndDlg, (CRYPTUI_CERT_MGR_STRUCT *)pCertMgrStruct);
  2337. break;
  2338. //double-click on the list view of the certificates
  2339. case NM_DBLCLK:
  2340. {
  2341. switch (((NMHDR FAR *) lParam)->idFrom)
  2342. {
  2343. case IDC_CERTMGR_LIST:
  2344. {
  2345. //get the window handle of the cert list view
  2346. if(NULL==(hWndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)))
  2347. break;
  2348. //get the selected cert
  2349. listIndex = ListView_GetNextItem(
  2350. hWndControl,
  2351. -1,
  2352. LVNI_SELECTED
  2353. );
  2354. if (listIndex != -1)
  2355. {
  2356. //get the selected certificate
  2357. memset(&lvItem, 0, sizeof(LV_ITEM));
  2358. lvItem.mask=LVIF_PARAM;
  2359. lvItem.iItem=listIndex;
  2360. if(ListView_GetItem(hWndControl, &lvItem))
  2361. {
  2362. //view certiificate
  2363. if(pCertMgrInfo->dwCertCount > (DWORD)listIndex)
  2364. {
  2365. memset(&CertViewStruct, 0, sizeof(CRYPTUI_VIEWCERTIFICATE_STRUCT));
  2366. CertViewStruct.dwSize=sizeof(CRYPTUI_VIEWCERTIFICATE_STRUCT);
  2367. CertViewStruct.pCertContext=(PCCERT_CONTEXT)(lvItem.lParam);
  2368. CertViewStruct.hwndParent=hwndDlg;
  2369. fPropertyChanged=FALSE;
  2370. CryptUIDlgViewCertificate(&CertViewStruct, &fPropertyChanged);
  2371. if(fPropertyChanged)
  2372. {
  2373. RefreshCertListView(hwndDlg, pCertMgrInfo);
  2374. //we reselect the one
  2375. ListView_SetItemState(
  2376. hWndControl,
  2377. listIndex,
  2378. LVIS_SELECTED,
  2379. LVIS_SELECTED);
  2380. }
  2381. }
  2382. }
  2383. }
  2384. break;
  2385. }
  2386. }
  2387. break;
  2388. }
  2389. #if (1) //DSIE: bug 264568.
  2390. case NM_SETFOCUS:
  2391. {
  2392. //get the window handle of the cert list view
  2393. if(NULL==(hWndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)))
  2394. break;
  2395. //get the selected cert
  2396. listIndex = ListView_GetNextItem(
  2397. hWndControl,
  2398. -1,
  2399. LVNI_FOCUSED
  2400. );
  2401. //select first item to show hilite.
  2402. if (listIndex == -1)
  2403. ListView_SetItemState(hWndControl,
  2404. 0,
  2405. LVIS_FOCUSED | LVIS_SELECTED,
  2406. LVIS_FOCUSED | LVIS_SELECTED);
  2407. break;
  2408. }
  2409. #endif
  2410. }
  2411. break;
  2412. case WM_DESTROY:
  2413. __try {
  2414. //revoke drag drop
  2415. RevokeDragDrop(GetDlgItem(hwndDlg, IDC_CERTMGR_LIST));
  2416. } __except(EXCEPTION_EXECUTE_HANDLER) {
  2417. }
  2418. pCertMgrInfo = (CERT_MGR_INFO *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  2419. if(pCertMgrInfo)
  2420. {
  2421. if(pCertMgrInfo->pIDropTarget)
  2422. pCertMgrInfo->pIDropTarget->Release();
  2423. }
  2424. // destroy the image list in the list view //
  2425. hWndListView = GetDlgItem(hwndDlg, IDC_CERTMGR_LIST);
  2426. if(NULL==hWndListView)
  2427. break;
  2428. //no need to destroy the image list. Handled by ListView
  2429. //ImageList_Destroy(ListView_GetImageList(hWndListView, LVSIL_SMALL));
  2430. break;
  2431. case WM_HELP:
  2432. case WM_CONTEXTMENU:
  2433. if (msg == WM_HELP)
  2434. {
  2435. hwnd = GetDlgItem(hwndDlg, ((LPHELPINFO)lParam)->iCtrlId);
  2436. }
  2437. else
  2438. {
  2439. hwnd = (HWND) wParam;
  2440. }
  2441. if ((hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)) &&
  2442. (hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_PURPOSE_COMBO)) &&
  2443. (hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_IMPORT)) &&
  2444. (hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_EXPORT)) &&
  2445. (hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_VIEW)) &&
  2446. (hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_REMOVE)) &&
  2447. (hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_ADVANCE)) &&
  2448. (hwnd != GetDlgItem(hwndDlg, IDOK)) &&
  2449. (hwnd != GetDlgItem(hwndDlg, IDC_CERTMGR_PURPOSE)))
  2450. {
  2451. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
  2452. return TRUE;
  2453. }
  2454. else
  2455. {
  2456. return OnContextHelp(hwndDlg, msg, wParam, lParam, CertMgrMainHelpMap);
  2457. }
  2458. break;
  2459. case WM_COMMAND:
  2460. pCertMgrInfo = (CERT_MGR_INFO *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  2461. if(NULL == pCertMgrInfo)
  2462. break;
  2463. pCertMgrStruct=pCertMgrInfo->pCertMgrStruct;
  2464. if(NULL == pCertMgrStruct)
  2465. break;
  2466. //a control is clicked
  2467. if(HIWORD(wParam) == BN_CLICKED)
  2468. {
  2469. switch (LOWORD(wParam))
  2470. {
  2471. case IDC_CERTMGR_ADVANCE:
  2472. //lauch the advanced dialogue
  2473. if(DIALOGUE_OK == DialogBoxParamU(
  2474. g_hmodThisDll,
  2475. (LPCWSTR)(MAKEINTRESOURCE(IDD_CERTMGR_ADVANCED)),
  2476. hwndDlg,
  2477. CertMgrAdvancedProc,
  2478. (LPARAM) pCertMgrInfo))
  2479. {
  2480. //if the advanced OIDs' list has been changed,
  2481. //we need to refresh the list window
  2482. if(TRUE == pCertMgrInfo->fAdvOIDChanged)
  2483. {
  2484. //mark the flag
  2485. pCertMgrInfo->fAdvOIDChanged=FALSE;
  2486. //repopulate the combo box based on
  2487. //the new selection
  2488. RepopulatePurposeCombo(hwndDlg,
  2489. pCertMgrInfo);
  2490. //refresh the list window only if
  2491. //<advanced> is selected
  2492. if(IsAdvancedSelected(hwndDlg))
  2493. RefreshCertListView(hwndDlg, pCertMgrInfo);
  2494. }
  2495. }
  2496. break;
  2497. case IDC_CERTMGR_REMOVE:
  2498. //get the selected certificate
  2499. if(NULL==(hWndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)))
  2500. break;
  2501. //get the selected cert
  2502. listIndex = ListView_GetNextItem(
  2503. hWndControl,
  2504. -1,
  2505. LVNI_SELECTED
  2506. );
  2507. if (listIndex != -1)
  2508. {
  2509. //get the selected tab
  2510. if (pCertMgrStruct->dwFlags & CRYPTUI_CERT_MGR_SINGLE_TAB_FLAG)
  2511. iIndex = pCertMgrStruct->dwFlags & CRYPTUI_CERT_MGR_TAB_MASK;
  2512. else
  2513. iIndex=TabCtrl_GetCurSel(GetDlgItem(hwndDlg, IDC_CERTMGR_TAB));
  2514. if(-1==iIndex)
  2515. break;
  2516. //delete confirmation
  2517. switch(iIndex)
  2518. {
  2519. case 0:
  2520. idsDeleteConfirm=IDS_CERTMGR_PERSONAL_REMOVE;
  2521. break;
  2522. case 1:
  2523. idsDeleteConfirm=IDS_CERTMGR_OTHER_REMOVE;
  2524. break;
  2525. case 2:
  2526. idsDeleteConfirm=IDS_CERTMGR_CA_REMOVE;
  2527. break;
  2528. case 3:
  2529. idsDeleteConfirm=IDS_CERTMGR_ROOT_REMOVE;
  2530. break;
  2531. case 4:
  2532. idsDeleteConfirm=IDS_CERTMGR_PUBLISHER_REMOVE;
  2533. break;
  2534. default:
  2535. idsDeleteConfirm=IDS_CERTMGR_PERSONAL_REMOVE;
  2536. break;
  2537. }
  2538. iIndex=I_MessageBox(hwndDlg,
  2539. idsDeleteConfirm,
  2540. IDS_CERT_MGR_TITLE,
  2541. pCertMgrStruct->pwszTitle,
  2542. MB_ICONEXCLAMATION|MB_YESNO|MB_APPLMODAL);
  2543. if(IDYES == iIndex)
  2544. {
  2545. //delete all the selected certificates
  2546. GetAllSelectedItem(hWndControl,
  2547. ALL_SELECTED_DELETE,
  2548. NULL);
  2549. //refresh the list view since some certificates
  2550. //might be deleted
  2551. //send the tab control
  2552. SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM) 0, (LPARAM) NULL);
  2553. RefreshCertListView(hwndDlg, pCertMgrInfo);
  2554. }
  2555. }
  2556. else
  2557. {
  2558. //output the message
  2559. I_MessageBox(hwndDlg, IDS_HAS_TO_SELECT_CERT,
  2560. IDS_CERT_MGR_TITLE,
  2561. pCertMgrStruct->pwszTitle,
  2562. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  2563. }
  2564. break;
  2565. case IDC_CERTMGR_IMPORT:
  2566. {
  2567. DWORD dwTabIndex;
  2568. HCERTSTORE hTabStore = NULL;
  2569. // Import into the store associated with the
  2570. // currently selected tab
  2571. if (pCertMgrStruct->dwFlags & CRYPTUI_CERT_MGR_SINGLE_TAB_FLAG)
  2572. dwTabIndex = pCertMgrStruct->dwFlags & CRYPTUI_CERT_MGR_TAB_MASK;
  2573. else
  2574. dwTabIndex = TabCtrl_GetCurSel(
  2575. GetDlgItem(hwndDlg, IDC_CERTMGR_TAB));
  2576. if (TAB_STORE_NAME_CNT > dwTabIndex) {
  2577. hTabStore = CertOpenStore(
  2578. CERT_STORE_PROV_SYSTEM_W,
  2579. g_dwMsgAndCertEncodingType,
  2580. NULL,
  2581. CERT_STORE_MAXIMUM_ALLOWED_FLAG |
  2582. CERT_STORE_SET_LOCALIZED_NAME_FLAG |
  2583. CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG |
  2584. CERT_SYSTEM_STORE_CURRENT_USER,
  2585. rgpwszTabStoreName[dwTabIndex]
  2586. );
  2587. }
  2588. //call the certificate import wizard
  2589. CryptUIWizImport(
  2590. 0,
  2591. hwndDlg,
  2592. NULL,
  2593. NULL,
  2594. hTabStore);
  2595. if (hTabStore)
  2596. CertCloseStore(hTabStore, 0);
  2597. //refresh the list view since new certificates
  2598. //might be added
  2599. RefreshCertListView(hwndDlg, pCertMgrInfo);
  2600. }
  2601. break;
  2602. case IDC_CERTMGR_EXPORT:
  2603. //get the selected certificate
  2604. if(NULL==(hWndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)))
  2605. break;
  2606. //get the selected cert
  2607. listIndex = ListView_GetNextItem(
  2608. hWndControl,
  2609. -1,
  2610. LVNI_SELECTED
  2611. );
  2612. if (listIndex != -1)
  2613. {
  2614. //we call the export wizard differently based
  2615. //on single or multiple selection
  2616. if(ListView_GetSelectedCount(hWndControl) > 1)
  2617. {
  2618. //open a memory store
  2619. hCertStore=CertOpenStore(
  2620. CERT_STORE_PROV_MEMORY,
  2621. g_dwMsgAndCertEncodingType,
  2622. NULL,
  2623. 0,
  2624. NULL);
  2625. if(hCertStore)
  2626. {
  2627. GetAllSelectedItem(hWndControl,
  2628. ALL_SELECTED_COPY,
  2629. &hCertStore);
  2630. //call the export wizard
  2631. memset(&CryptUIWizExportInfo, 0, sizeof(CRYPTUI_WIZ_EXPORT_INFO));
  2632. CryptUIWizExportInfo.dwSize=sizeof(CRYPTUI_WIZ_EXPORT_INFO);
  2633. CryptUIWizExportInfo.dwSubjectChoice=CRYPTUI_WIZ_EXPORT_CERT_STORE_CERTIFICATES_ONLY;
  2634. CryptUIWizExportInfo.hCertStore=hCertStore;
  2635. CryptUIWizExport(0,
  2636. hwndDlg,
  2637. NULL,
  2638. &CryptUIWizExportInfo,
  2639. NULL);
  2640. CertCloseStore(hCertStore, 0);
  2641. hCertStore=NULL;
  2642. }
  2643. }
  2644. else
  2645. {
  2646. memset(&lvItem, 0, sizeof(LV_ITEM));
  2647. lvItem.mask=LVIF_PARAM;
  2648. lvItem.iItem=listIndex;
  2649. if(ListView_GetItem(hWndControl,
  2650. &lvItem))
  2651. {
  2652. if(pCertMgrInfo->dwCertCount > (DWORD)listIndex)
  2653. {
  2654. //call the export wizard
  2655. memset(&CryptUIWizExportInfo, 0, sizeof(CRYPTUI_WIZ_EXPORT_INFO));
  2656. CryptUIWizExportInfo.dwSize=sizeof(CRYPTUI_WIZ_EXPORT_INFO);
  2657. CryptUIWizExportInfo.dwSubjectChoice=CRYPTUI_WIZ_EXPORT_CERT_CONTEXT;
  2658. CryptUIWizExportInfo.pCertContext=(PCCERT_CONTEXT)(lvItem.lParam);
  2659. CryptUIWizExport(0,
  2660. hwndDlg,
  2661. NULL,
  2662. &CryptUIWizExportInfo,
  2663. NULL);
  2664. }
  2665. }
  2666. }
  2667. }
  2668. else
  2669. //output the message
  2670. I_MessageBox(hwndDlg, IDS_HAS_TO_SELECT_CERT,
  2671. IDS_CERT_MGR_TITLE,
  2672. pCertMgrStruct->pwszTitle,
  2673. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  2674. break;
  2675. case IDC_CERTMGR_VIEW:
  2676. //get the selected certificate
  2677. if(NULL==(hWndControl=GetDlgItem(hwndDlg, IDC_CERTMGR_LIST)))
  2678. break;
  2679. //get the selected cert
  2680. listIndex = ListView_GetNextItem(
  2681. hWndControl,
  2682. -1,
  2683. LVNI_SELECTED
  2684. );
  2685. if (listIndex != -1)
  2686. {
  2687. //view certiificate
  2688. if(pCertMgrInfo->dwCertCount > (DWORD)listIndex)
  2689. {
  2690. memset(&lvItem, 0, sizeof(LV_ITEM));
  2691. lvItem.mask=LVIF_PARAM;
  2692. lvItem.iItem=listIndex;
  2693. if(ListView_GetItem(hWndControl,
  2694. &lvItem))
  2695. {
  2696. memset(&CertViewStruct, 0, sizeof(CRYPTUI_VIEWCERTIFICATE_STRUCT));
  2697. CertViewStruct.dwSize=sizeof(CRYPTUI_VIEWCERTIFICATE_STRUCT);
  2698. CertViewStruct.pCertContext=(PCCERT_CONTEXT)(lvItem.lParam);
  2699. CertViewStruct.hwndParent=hwndDlg;
  2700. fPropertyChanged=FALSE;
  2701. CryptUIDlgViewCertificate(&CertViewStruct, &fPropertyChanged);
  2702. if(fPropertyChanged)
  2703. {
  2704. RefreshCertListView(hwndDlg, pCertMgrInfo);
  2705. //we reselect the one
  2706. ListView_SetItemState(
  2707. hWndControl,
  2708. listIndex,
  2709. LVIS_SELECTED,
  2710. LVIS_SELECTED);
  2711. }
  2712. }
  2713. }
  2714. }
  2715. else
  2716. //output the message
  2717. I_MessageBox(hwndDlg, IDS_HAS_TO_SELECT_CERT,
  2718. IDS_CERT_MGR_TITLE,
  2719. pCertMgrStruct->pwszTitle,
  2720. MB_ICONERROR|MB_OK|MB_APPLMODAL);
  2721. break;
  2722. case IDOK:
  2723. case IDCANCEL:
  2724. EndDialog(hwndDlg, NULL);
  2725. break;
  2726. default:
  2727. break;
  2728. }
  2729. }
  2730. //a combo box's selection has been changed
  2731. if(HIWORD(wParam) == CBN_SELCHANGE)
  2732. {
  2733. switch(LOWORD(wParam))
  2734. {
  2735. case IDC_CERTMGR_PURPOSE_COMBO:
  2736. //if the purpose is changed, we need to
  2737. //refresh the list view and certificate's
  2738. //detailed view
  2739. RefreshCertListView(hwndDlg, pCertMgrInfo);
  2740. break;
  2741. }
  2742. }
  2743. break;
  2744. }
  2745. return FALSE;
  2746. }
  2747. //--------------------------------------------------------------
  2748. //
  2749. // Save the advanced option from the registry
  2750. //--------------------------------------------------------------
  2751. void SaveAdvValueToReg(CERT_MGR_INFO *pCertMgrInfo)
  2752. {
  2753. HKEY hKeyExport=NULL;
  2754. HKEY hKeyPurpose=NULL;
  2755. DWORD dwDisposition=0;
  2756. DWORD dwExportFormat=0;
  2757. DWORD dwIndex=0;
  2758. LPSTR pszDefaultOID=NULL;
  2759. LPSTR pszOID=NULL;
  2760. if(NULL==pCertMgrInfo)
  2761. return;
  2762. //open a registry entry for the export format under HKEY_CURRENT_USER
  2763. if (ERROR_SUCCESS == RegCreateKeyExU(
  2764. HKEY_CURRENT_USER,
  2765. WSZCertMgrExportRegLocation,
  2766. 0,
  2767. NULL,
  2768. REG_OPTION_NON_VOLATILE,
  2769. KEY_ALL_ACCESS,
  2770. NULL,
  2771. &hKeyExport,
  2772. &dwDisposition))
  2773. {
  2774. //set the value
  2775. switch(pCertMgrInfo->dwExportFormat)
  2776. {
  2777. case CRYPTUI_WIZ_EXPORT_FORMAT_DER:
  2778. if(pCertMgrInfo->fExportChain)
  2779. dwExportFormat=4;
  2780. else
  2781. dwExportFormat=1;
  2782. break;
  2783. case CRYPTUI_WIZ_EXPORT_FORMAT_BASE64:
  2784. if(pCertMgrInfo->fExportChain)
  2785. dwExportFormat=5;
  2786. else
  2787. dwExportFormat=2;
  2788. break;
  2789. case CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7:
  2790. if(pCertMgrInfo->fExportChain)
  2791. dwExportFormat=6;
  2792. else
  2793. dwExportFormat=3;
  2794. break;
  2795. default:
  2796. break;
  2797. }
  2798. if(0 != dwExportFormat)
  2799. {
  2800. //set the value
  2801. RegSetValueExU(
  2802. hKeyExport,
  2803. WSZCertMgrExportName,
  2804. 0, // dwReserved
  2805. REG_DWORD,
  2806. (BYTE *) &dwExportFormat,
  2807. sizeof(dwExportFormat));
  2808. }
  2809. }
  2810. //open the registry entry for the advanced OIDs
  2811. dwDisposition=0;
  2812. if (ERROR_SUCCESS == RegCreateKeyExU(
  2813. HKEY_CURRENT_USER,
  2814. WSZCertMgrPurposeRegLocation,
  2815. 0,
  2816. NULL,
  2817. REG_OPTION_NON_VOLATILE,
  2818. KEY_ALL_ACCESS,
  2819. NULL,
  2820. &hKeyPurpose,
  2821. &dwDisposition))
  2822. {
  2823. //build a char "," seperated string for simple OID
  2824. pszDefaultOID=(LPSTR)WizardAlloc(sizeof(CHAR));
  2825. if(NULL == pszDefaultOID)
  2826. goto CLEANUP;
  2827. *pszDefaultOID=L'\0';
  2828. for(dwIndex=0; dwIndex<pCertMgrInfo->dwOIDInfo; dwIndex++)
  2829. {
  2830. if(FALSE==(pCertMgrInfo->rgOIDInfo)[dwIndex].fSelected)
  2831. {
  2832. if(strlen(pszDefaultOID)!=0)
  2833. strcat(pszDefaultOID, ",");
  2834. pszOID=(pCertMgrInfo->rgOIDInfo)[dwIndex].pszOID;
  2835. pszDefaultOID=(LPSTR)WizardRealloc(pszDefaultOID,
  2836. sizeof(CHAR)*(strlen(pszDefaultOID)+strlen(pszOID)+strlen(",")+1));
  2837. if(NULL==pszDefaultOID)
  2838. goto CLEANUP;
  2839. strcat(pszDefaultOID,pszOID);
  2840. }
  2841. }
  2842. //set the value
  2843. RegSetValueEx(
  2844. hKeyPurpose,
  2845. SZCertMgrPurposeName,
  2846. 0,
  2847. REG_SZ,
  2848. (BYTE *)(pszDefaultOID),
  2849. (strlen(pszDefaultOID) + 1) * sizeof(CHAR));
  2850. }
  2851. CLEANUP:
  2852. if(pszDefaultOID)
  2853. WizardFree(pszDefaultOID);
  2854. //close the registry keys
  2855. if(hKeyExport)
  2856. RegCloseKey(hKeyExport);
  2857. if(hKeyPurpose)
  2858. RegCloseKey(hKeyPurpose);
  2859. }
  2860. //--------------------------------------------------------------
  2861. //
  2862. // Get init value from the registry
  2863. //--------------------------------------------------------------
  2864. void GetInitValueFromReg(CERT_MGR_INFO *pCertMgrInfo)
  2865. {
  2866. HKEY hKeyExport=NULL;
  2867. HKEY hKeyPurpose=NULL;
  2868. DWORD dwType=0;
  2869. DWORD dwExportFormat=0;
  2870. DWORD cbExportFormat=0;
  2871. LPSTR pszDefaultOID=NULL;
  2872. DWORD cbDefaultOID=0;
  2873. LPSTR pszTok=NULL;
  2874. DWORD cTok = 0;
  2875. DWORD cCount=0;
  2876. CERT_ENHKEY_USAGE KeyUsage;
  2877. LPSTR rgBasicOID[]={szOID_PKIX_KP_CLIENT_AUTH,
  2878. szOID_PKIX_KP_EMAIL_PROTECTION};
  2879. BOOL fNoRegData=FALSE;
  2880. if(NULL==pCertMgrInfo)
  2881. return;
  2882. //memset
  2883. memset(&KeyUsage,0,sizeof(CERT_ENHKEY_USAGE));
  2884. //open the registry key if user has saved the advaced options
  2885. if(ERROR_SUCCESS == RegOpenKeyExU(HKEY_CURRENT_USER,
  2886. WSZCertMgrExportRegLocation,
  2887. 0,
  2888. KEY_READ,
  2889. &hKeyExport))
  2890. {
  2891. //get the data
  2892. cbExportFormat=sizeof(dwExportFormat);
  2893. if(ERROR_SUCCESS == RegQueryValueExU(
  2894. hKeyExport,
  2895. WSZCertMgrExportName,
  2896. NULL,
  2897. &dwType,
  2898. (BYTE *)&dwExportFormat,
  2899. &cbExportFormat))
  2900. {
  2901. // added check for reg_binary because on WIN95 OSR2 when the machine is changed
  2902. // from mutli-user profiles to single user profile, the registry DWORD values
  2903. // change to BINARY
  2904. //
  2905. if ((dwType == REG_DWORD) ||
  2906. (dwType == REG_BINARY))
  2907. {
  2908. switch(dwExportFormat)
  2909. {
  2910. case 1:
  2911. pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_DER;
  2912. pCertMgrInfo->fExportChain=FALSE;
  2913. break;
  2914. case 2:
  2915. pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_BASE64;
  2916. pCertMgrInfo->fExportChain=FALSE;
  2917. break;
  2918. case 3:
  2919. pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7;
  2920. pCertMgrInfo->fExportChain=FALSE;
  2921. break;
  2922. case 4:
  2923. pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_DER;
  2924. pCertMgrInfo->fExportChain=TRUE;
  2925. break;
  2926. case 5:
  2927. pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_BASE64;
  2928. pCertMgrInfo->fExportChain=TRUE;
  2929. break;
  2930. case 6:
  2931. pCertMgrInfo->dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7;
  2932. pCertMgrInfo->fExportChain=TRUE;
  2933. break;
  2934. default:
  2935. break;
  2936. }
  2937. }
  2938. }
  2939. }
  2940. //get the advanced purposed
  2941. if(ERROR_SUCCESS == RegOpenKeyExU(HKEY_CURRENT_USER,
  2942. WSZCertMgrPurposeRegLocation,
  2943. 0,
  2944. KEY_READ,
  2945. &hKeyPurpose))
  2946. {
  2947. dwType=0;
  2948. cbDefaultOID=0;
  2949. if((ERROR_SUCCESS == RegQueryValueEx(
  2950. hKeyPurpose,
  2951. SZCertMgrPurposeName,
  2952. NULL,
  2953. &dwType,
  2954. NULL,
  2955. &cbDefaultOID))&&(cbDefaultOID!=0))
  2956. {
  2957. pszDefaultOID=(LPSTR)WizardAlloc(cbDefaultOID);
  2958. if(NULL==pszDefaultOID)
  2959. goto CLEANUP;
  2960. if(ERROR_SUCCESS != RegQueryValueEx(
  2961. hKeyPurpose,
  2962. SZCertMgrPurposeName,
  2963. NULL,
  2964. &dwType,
  2965. (BYTE *)pszDefaultOID,
  2966. &cbDefaultOID))
  2967. goto CLEANUP;
  2968. //
  2969. // Count the number of OIDs as well as converting from comma delimited
  2970. // to NULL character delimited
  2971. //
  2972. if(0==strlen(pszDefaultOID))
  2973. fNoRegData=TRUE;
  2974. else
  2975. {
  2976. pszTok = strtok(pszDefaultOID, ",");
  2977. while ( pszTok != NULL )
  2978. {
  2979. cTok++;
  2980. pszTok = strtok(NULL, ",");
  2981. }
  2982. //
  2983. // Allocate a cert enhanced key usage structure and fill it in with
  2984. // the string tokens
  2985. //
  2986. pszTok = pszDefaultOID;
  2987. KeyUsage.cUsageIdentifier = cTok;
  2988. KeyUsage.rgpszUsageIdentifier = (LPSTR *)WizardAlloc(cTok * sizeof(LPSTR));
  2989. if(NULL==KeyUsage.rgpszUsageIdentifier)
  2990. goto CLEANUP;
  2991. for ( cCount = 0; cCount < cTok; cCount++ )
  2992. {
  2993. KeyUsage.rgpszUsageIdentifier[cCount] = pszTok;
  2994. pszTok = pszTok+strlen(pszTok)+1;
  2995. }
  2996. }
  2997. }
  2998. }
  2999. //set up the default OIDs if the registry is empty
  3000. if(0 == KeyUsage.cUsageIdentifier && TRUE != fNoRegData)
  3001. {
  3002. KeyUsage.cUsageIdentifier=2;
  3003. KeyUsage.rgpszUsageIdentifier=rgBasicOID;
  3004. }
  3005. //mark the OIDs as advanced for basic
  3006. for(cCount=0; cCount<pCertMgrInfo->dwOIDInfo; cCount++)
  3007. {
  3008. if(IsAdvancedOID(&KeyUsage,
  3009. (pCertMgrInfo->rgOIDInfo)[cCount].pszOID))
  3010. (pCertMgrInfo->rgOIDInfo)[cCount].fSelected=TRUE;
  3011. }
  3012. CLEANUP:
  3013. //free memory
  3014. if(pszDefaultOID)
  3015. {
  3016. WizardFree(pszDefaultOID);
  3017. if(KeyUsage.rgpszUsageIdentifier)
  3018. WizardFree(KeyUsage.rgpszUsageIdentifier);
  3019. }
  3020. //close the registry keys
  3021. if(hKeyExport)
  3022. RegCloseKey(hKeyExport);
  3023. if(hKeyPurpose)
  3024. RegCloseKey(hKeyPurpose);
  3025. return;
  3026. }
  3027. //--------------------------------------------------------------
  3028. //
  3029. // Parameters:
  3030. // pCryptUICertMgr IN Required
  3031. //
  3032. //
  3033. //--------------------------------------------------------------
  3034. BOOL
  3035. WINAPI
  3036. CryptUIDlgCertMgr(
  3037. IN PCCRYPTUI_CERT_MGR_STRUCT pCryptUICertMgr)
  3038. {
  3039. BOOL fResult=FALSE;
  3040. CERT_MGR_INFO CertMgrInfo;
  3041. HRESULT hr=S_OK;
  3042. DWORD dwException=0;
  3043. //check the input parameter
  3044. if(NULL==pCryptUICertMgr)
  3045. goto InvalidArgErr;
  3046. if(sizeof(CRYPTUI_CERT_MGR_STRUCT) != pCryptUICertMgr->dwSize)
  3047. goto InvalidArgErr;
  3048. if ((pCryptUICertMgr->dwFlags & CRYPTUI_CERT_MGR_TAB_MASK) >
  3049. CRYPTUI_CERT_MGR_PUBLISHER_TAB)
  3050. goto InvalidArgErr;
  3051. if (!WizardInit())
  3052. {
  3053. goto InitOIDErr;
  3054. }
  3055. //init struct
  3056. memset(&CertMgrInfo, 0, sizeof(CertMgrInfo));
  3057. CertMgrInfo.pCertMgrStruct=pCryptUICertMgr;
  3058. //get all the enhanced key usage OIDs
  3059. if(!InitPurposeOID(pCryptUICertMgr->pszInitUsageOID,
  3060. &(CertMgrInfo.dwOIDInfo),
  3061. &(CertMgrInfo.rgOIDInfo)))
  3062. goto InitOIDErr;
  3063. //init the column sort
  3064. CertMgrInfo.rgdwSortParam[0]=SORT_COLUMN_SUBJECT | SORT_COLUMN_ASCEND;
  3065. CertMgrInfo.rgdwSortParam[1]=SORT_COLUMN_ISSUER | SORT_COLUMN_DESCEND;
  3066. CertMgrInfo.rgdwSortParam[2]=SORT_COLUMN_EXPIRATION | SORT_COLUMN_DESCEND;
  3067. CertMgrInfo.rgdwSortParam[3]=SORT_COLUMN_NAME | SORT_COLUMN_DESCEND;
  3068. CertMgrInfo.rgdwSortParam[4]=SORT_COLUMN_NAME | SORT_COLUMN_DESCEND;
  3069. //we sort the 1st column
  3070. CertMgrInfo.iColumn=0;
  3071. //init the export format
  3072. CertMgrInfo.dwExportFormat=CRYPTUI_WIZ_EXPORT_FORMAT_DER;
  3073. CertMgrInfo.fExportChain=FALSE;
  3074. CertMgrInfo.fAdvOIDChanged=FALSE;
  3075. //init the OLE library
  3076. __try {
  3077. if(!SUCCEEDED(hr=OleInitialize(NULL)))
  3078. goto OLEInitErr;
  3079. //get the initialization from the registry
  3080. GetInitValueFromReg(&CertMgrInfo);
  3081. //call the dialog box
  3082. if (DialogBoxParamU(
  3083. g_hmodThisDll,
  3084. (LPCWSTR)(MAKEINTRESOURCE(IDD_CERTMGR_MAIN)),
  3085. (pCryptUICertMgr->hwndParent != NULL) ? pCryptUICertMgr->hwndParent : GetDesktopWindow(),
  3086. CertMgrDialogProc,
  3087. (LPARAM) &CertMgrInfo) == -1)
  3088. {
  3089. OleUninitialize();
  3090. goto DialogBoxErr;
  3091. }
  3092. OleUninitialize();
  3093. } __except(EXCEPTION_EXECUTE_HANDLER) {
  3094. dwException = GetExceptionCode();
  3095. goto ExceptionErr;
  3096. }
  3097. fResult=TRUE;
  3098. CommonReturn:
  3099. //free the cert arrays
  3100. FreeCerts(&CertMgrInfo);
  3101. //free the usage OID array
  3102. FreeUsageOID(CertMgrInfo.dwOIDInfo,
  3103. CertMgrInfo.rgOIDInfo);
  3104. return fResult;
  3105. ErrorReturn:
  3106. fResult=FALSE;
  3107. goto CommonReturn;
  3108. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  3109. TRACE_ERROR(DialogBoxErr);
  3110. TRACE_ERROR(InitOIDErr);
  3111. SET_ERROR_VAR(OLEInitErr, hr);
  3112. SET_ERROR_VAR(ExceptionErr, dwException)
  3113. }