Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3105 lines
104 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: property.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "global.hxx"
  11. #include <dbgdef.h>
  12. #include <wininet.h>
  13. #include <crypthlp.h> //DSIE: For XCERT_MIN_SYNC_DELTA_TIME and
  14. // XCERT_MIN_SYNC_DELTA_TIME
  15. extern HINSTANCE HinstDll;
  16. extern HMODULE HmodRichEdit;
  17. static const HELPMAP helpmapGeneral[] = {
  18. {IDC_CERTIFICATE_NAME, IDH_CERTPROPERTIES_CERTIFICATENAME},
  19. {IDC_DESCRIPTION, IDH_CERTPROPERTIES_DESCRIPTION},
  20. {IDC_KEY_USAGE_LIST, IDH_CERTPROPERTIES_USAGE_LIST},
  21. {IDC_PROPERTY_NEWOID, IDH_CERTPROPERTIES_ADDPURPOSE_BUTTON},
  22. {IDC_ENABLE_ALL_RADIO, IDH_CERTPROPERTIES_ENABLE_ALL_RADIO},
  23. {IDC_DISABLE_ALL_RADIO, IDH_CERTPROPERTIES_DISABLE_ALL_RADIO},
  24. {IDC_ENABLE_SELECT_RADIO, IDH_CERTPROPERTIES_ENABLE_CUSTOM_RADIO}
  25. };
  26. static const HELPMAP helpmapCrossCert[] = {
  27. {IDC_CHECKFORNEWCERTS_CHECK, IDH_CHECKFORNEWCERTS_CHECK},
  28. {IDC_NUMBEROFUNITS_EDIT, IDH_NUMBEROFUNITS_EDIT},
  29. {IDC_UNITS_COMBO, IDH_UNITS_COMBO},
  30. {IDC_USE_DEFAULT_BUTTON, IDH_USE_DEFAULT_BUTTON},
  31. {IDC_ADDURL_BUTTON, IDH_ADDURL_BUTTON},
  32. {IDC_NEWURL_EDIT, IDH_NEWURL_EDIT},
  33. {IDC_URL_LIST, IDH_URL_LIST},
  34. {IDC_REMOVEURL_BUTTON, IDH_REMOVEURL_BUTTON}
  35. };
  36. #define MY_CHECK_STATE_CHECKED (INDEXTOSTATEIMAGEMASK(1))
  37. #define MY_CHECK_STATE_UNCHECKED (INDEXTOSTATEIMAGEMASK(2))
  38. #define MY_CHECK_STATE_CHECKED_GRAYED (INDEXTOSTATEIMAGEMASK(3))
  39. #define MY_CHECK_STATE_UNCHECKED_GRAYED (INDEXTOSTATEIMAGEMASK(4))
  40. #define PROPERTY_STATE_ALL_ENABLED 1
  41. #define PROPERTY_STATE_ALL_DISABLED 2
  42. #define PROPERTY_STATE_SELECT 3
  43. typedef struct {
  44. LPSTR pszOID;
  45. DWORD initialState;
  46. } SETPROPERTIES_HELPER_STRUCT, *PSETPROPERTIES_HELPER_STRUCT;
  47. //DSIE: Bug 154609
  48. #define XCERT_DEFAULT_DELTA_HOURS (XCERT_DEFAULT_SYNC_DELTA_TIME / (60 * 60)) // Default interval is 8 hours.
  49. //////////////////////////////////////////////////////////////////////////////////////
  50. //
  51. //////////////////////////////////////////////////////////////////////////////////////
  52. INT_PTR APIENTRY NewOIDDialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  53. {
  54. DWORD i;
  55. char szText[256];
  56. WCHAR errorString[CRYPTUI_MAX_STRING_SIZE];
  57. WCHAR errorTitle[CRYPTUI_MAX_STRING_SIZE];
  58. LPSTR pszText = NULL;
  59. switch ( msg ) {
  60. case WM_INITDIALOG:
  61. SendDlgItemMessage(hwndDlg, IDC_EDIT1, EM_EXLIMITTEXT, 0, (LPARAM) 255);
  62. SetDlgItemTextU(hwndDlg, IDC_EDIT1, L"");
  63. SetFocus(GetDlgItem(hwndDlg, IDC_EDIT1));
  64. break;
  65. case WM_COMMAND:
  66. switch (LOWORD(wParam))
  67. {
  68. case IDOK:
  69. if (GetDlgItemTextA(
  70. hwndDlg,
  71. IDC_EDIT1,
  72. szText,
  73. ARRAYSIZE(szText)))
  74. {
  75. BOOL fError = FALSE;
  76. CERT_ENHKEY_USAGE KeyUsage;
  77. DWORD cbData = 0;
  78. LPSTR pszCheckOID;
  79. //
  80. // make sure there are not weird characters
  81. //
  82. for (i=0; i<(DWORD)strlen(szText); i++)
  83. {
  84. if (((szText[i] < '0') || (szText[i] > '9')) && (szText[i] != '.'))
  85. {
  86. fError = TRUE;
  87. break;
  88. }
  89. }
  90. //
  91. // check the first and last chars, and for the empty string
  92. //
  93. if (!fError)
  94. {
  95. if ((szText[0] == '.') || (szText[strlen(szText)-1] == '.') || (strcmp(szText, "") == 0))
  96. {
  97. fError = TRUE;
  98. }
  99. }
  100. //
  101. // finally, make sure that it encodes properly
  102. //
  103. if (!fError)
  104. {
  105. pszCheckOID = szText;
  106. KeyUsage.rgpszUsageIdentifier = &pszCheckOID;
  107. KeyUsage.cUsageIdentifier = 1;
  108. if (!CryptEncodeObject(
  109. X509_ASN_ENCODING,
  110. szOID_ENHANCED_KEY_USAGE,
  111. &KeyUsage,
  112. NULL,
  113. &cbData))
  114. {
  115. fError = TRUE;
  116. }
  117. }
  118. //
  119. // if an error has occurred then display error
  120. //
  121. if (fError)
  122. {
  123. LoadStringU(HinstDll, IDS_ERRORINOID, errorString, ARRAYSIZE(errorString));
  124. LoadStringU(HinstDll, IDS_CERTIFICATE_PROPERTIES, errorTitle, ARRAYSIZE(errorTitle));
  125. MessageBoxU(hwndDlg, errorString, errorTitle, MB_OK | MB_ICONERROR);
  126. SendDlgItemMessage(hwndDlg, IDC_EDIT1, EM_SETSEL, 0, -1);
  127. SetFocus(GetDlgItem(hwndDlg, IDC_EDIT1));
  128. return FALSE;
  129. }
  130. //
  131. // allocate space for the string and pass the string back
  132. //
  133. pszText = (LPSTR) malloc(strlen(szText)+1);
  134. if (pszText != NULL)
  135. {
  136. strcpy(pszText, szText);
  137. }
  138. }
  139. EndDialog(hwndDlg, (INT_PTR)pszText);
  140. break;
  141. case IDCANCEL:
  142. EndDialog(hwndDlg, 0);
  143. break;
  144. }
  145. break;
  146. }
  147. return FALSE;
  148. }
  149. //////////////////////////////////////////////////////////////////////////////////////
  150. //
  151. //////////////////////////////////////////////////////////////////////////////////////
  152. DWORD MyGetCheckState(HWND hWndListView, int listIndex)
  153. {
  154. LVITEMW lvI;
  155. memset(&lvI, 0, sizeof(lvI));
  156. lvI.mask = LVIF_STATE;
  157. lvI.iItem = listIndex;
  158. lvI.state = 0;
  159. lvI.stateMask = LVIS_STATEIMAGEMASK;
  160. ListView_GetItem(hWndListView, &lvI);
  161. return (lvI.state);
  162. }
  163. //////////////////////////////////////////////////////////////////////////////////////
  164. //
  165. //////////////////////////////////////////////////////////////////////////////////////
  166. void MySetCheckState(HWND hWndListView, int listIndex, DWORD dwImage)
  167. {
  168. LVITEMW lvI;
  169. memset(&lvI, 0, sizeof(lvI));
  170. lvI.mask = LVIF_STATE;
  171. lvI.stateMask = LVIS_STATEIMAGEMASK;
  172. lvI.iItem = listIndex;
  173. lvI.state = dwImage;
  174. SendMessage(hWndListView, LVM_SETITEM, (WPARAM) 0, (LPARAM) &lvI);
  175. }
  176. //////////////////////////////////////////////////////////////////////////////////////
  177. //
  178. //////////////////////////////////////////////////////////////////////////////////////
  179. static void SetEnableStateForChecks(PCERT_SETPROPERTIES_HELPER pviewhelp, HWND hWndListView, BOOL fEnabled)
  180. {
  181. int i;
  182. DWORD dwState;
  183. pviewhelp->fInserting = TRUE;
  184. for (i=0; i<ListView_GetItemCount(hWndListView); i++)
  185. {
  186. dwState = MyGetCheckState(hWndListView, i);
  187. if ((dwState == MY_CHECK_STATE_CHECKED_GRAYED) ||
  188. (dwState == MY_CHECK_STATE_UNCHECKED_GRAYED))
  189. {
  190. if (fEnabled)
  191. {
  192. MySetCheckState(
  193. hWndListView,
  194. i,
  195. (dwState == MY_CHECK_STATE_CHECKED_GRAYED) ? MY_CHECK_STATE_CHECKED : MY_CHECK_STATE_UNCHECKED);
  196. }
  197. }
  198. else
  199. {
  200. if (!fEnabled)
  201. {
  202. MySetCheckState(
  203. hWndListView,
  204. i,
  205. (dwState == MY_CHECK_STATE_CHECKED) ? MY_CHECK_STATE_CHECKED_GRAYED : MY_CHECK_STATE_UNCHECKED_GRAYED);
  206. }
  207. }
  208. }
  209. pviewhelp->fInserting = FALSE;
  210. }
  211. //////////////////////////////////////////////////////////////////////////////////////
  212. //
  213. //////////////////////////////////////////////////////////////////////////////////////
  214. static void AddUsageToList(
  215. HWND hWndListView,
  216. LPSTR pszOID,
  217. DWORD dwImage,
  218. BOOL fDirty)
  219. {
  220. WCHAR szText[CRYPTUI_MAX_STRING_SIZE];
  221. LV_ITEMW lvI;
  222. SETPROPERTIES_HELPER_STRUCT *pHelperStruct;
  223. //
  224. // set up the fields in the list view item struct that don't change from item to item
  225. //
  226. memset(&lvI, 0, sizeof(lvI));
  227. lvI.mask = LVIF_TEXT | LVIF_PARAM;
  228. lvI.pszText = szText;
  229. lvI.iSubItem = 0;
  230. lvI.lParam = (LPARAM)NULL;
  231. lvI.iItem = ListView_GetItemCount(hWndListView);
  232. // get the display string for the usage
  233. if (!MyGetOIDInfo(szText, ARRAYSIZE(szText), pszOID))
  234. {
  235. return;
  236. }
  237. lvI.cchTextMax = wcslen(szText);
  238. // set the lParam field the helper struct so that we always have access the oid and
  239. // the initial check state
  240. pHelperStruct = NULL;
  241. pHelperStruct =
  242. (SETPROPERTIES_HELPER_STRUCT *) malloc(sizeof(SETPROPERTIES_HELPER_STRUCT) + (strlen(pszOID)+1));
  243. if (pHelperStruct != NULL)
  244. {
  245. pHelperStruct->pszOID = (LPSTR) (((LPBYTE)pHelperStruct) + sizeof(SETPROPERTIES_HELPER_STRUCT));
  246. lvI.lParam = (LPARAM) pHelperStruct;
  247. strcpy(pHelperStruct->pszOID, pszOID);
  248. //
  249. // if the dirty flag was passed in, then set the initial image to iImage+1
  250. // so that when we are checking to see if anything has changed on shutdown
  251. // we know this is a usage that was added after the dialog was brought up.
  252. //
  253. if (fDirty)
  254. {
  255. pHelperStruct->initialState = dwImage+1;
  256. }
  257. else
  258. {
  259. pHelperStruct->initialState = dwImage;
  260. }
  261. }
  262. else
  263. {
  264. return;
  265. }
  266. ListView_InsertItemU(hWndListView, &lvI);
  267. //
  268. // for some reason you can't set the state image when inserting the
  269. // item, so set the state image after it has been inserted
  270. //
  271. MySetCheckState(hWndListView, lvI.iItem, dwImage);
  272. }
  273. //////////////////////////////////////////////////////////////////////////////////////
  274. //
  275. //////////////////////////////////////////////////////////////////////////////////////
  276. static void DisplayKeyUsages(
  277. HWND hWndListView,
  278. PCERT_SETPROPERTIES_HELPER pviewhelp)
  279. {
  280. DWORD i;
  281. LPSTR *pszOIDs = NULL;
  282. DWORD numOIDs = 0;
  283. DWORD cbPropertyUsage = 0;
  284. PCERT_ENHKEY_USAGE pPropertyUsage = NULL;
  285. DWORD cbEKUExtensionUsage = 0;
  286. PCERT_ENHKEY_USAGE pEKUExtensionUsage = NULL;
  287. DWORD dwImage;
  288. DWORD displayState;
  289. int j;
  290. PCCERT_CONTEXT pCertContext = pviewhelp->pcsp->pCertContext;
  291. LVITEMW lvI;
  292. //
  293. // get the property usages that are currently tagged to this cert
  294. //
  295. if(!CertGetEnhancedKeyUsage (
  296. pCertContext,
  297. CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG,
  298. NULL,
  299. &cbPropertyUsage
  300. ) ||
  301. (pPropertyUsage = (PCERT_ENHKEY_USAGE) malloc(cbPropertyUsage)) == NULL ||
  302. !CertGetEnhancedKeyUsage (
  303. pCertContext,
  304. CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG,
  305. pPropertyUsage,
  306. &cbPropertyUsage
  307. ) )
  308. {
  309. if (GetLastError() == CRYPT_E_NOT_FOUND)
  310. {
  311. if (pPropertyUsage != NULL)
  312. free(pPropertyUsage);
  313. pPropertyUsage = NULL;
  314. }
  315. else
  316. {
  317. goto CleanUp;
  318. }
  319. }
  320. //
  321. // get the EKU usages that are in the cert
  322. //
  323. if(!CertGetEnhancedKeyUsage (
  324. pCertContext,
  325. CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG,
  326. NULL,
  327. &cbEKUExtensionUsage
  328. ) ||
  329. (pEKUExtensionUsage = (PCERT_ENHKEY_USAGE) malloc(cbEKUExtensionUsage)) == NULL ||
  330. !CertGetEnhancedKeyUsage (
  331. pCertContext,
  332. CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG,
  333. pEKUExtensionUsage,
  334. &cbEKUExtensionUsage
  335. ) )
  336. {
  337. if (GetLastError() == CRYPT_E_NOT_FOUND)
  338. {
  339. if (pEKUExtensionUsage != NULL)
  340. free(pEKUExtensionUsage);
  341. pEKUExtensionUsage = NULL;
  342. }
  343. else
  344. {
  345. goto CleanUp;
  346. }
  347. }
  348. //
  349. // set the property state so the INIT_DIALOG can set the correct state
  350. //
  351. if (pPropertyUsage == NULL)
  352. {
  353. pviewhelp->EKUPropertyState = PROPERTY_STATE_ALL_ENABLED;
  354. }
  355. else if (fPropertiesDisabled(pPropertyUsage))
  356. {
  357. pviewhelp->EKUPropertyState = PROPERTY_STATE_ALL_DISABLED;
  358. }
  359. else
  360. {
  361. pviewhelp->EKUPropertyState = PROPERTY_STATE_SELECT;
  362. }
  363. //
  364. // there are four different cases that the cert can be in
  365. // 1) cert has property EKU only
  366. // 2) cert has neither
  367. // 3) cert has extension EKU only
  368. // 4) cert has both property EKU and extension EKU
  369. //
  370. if (pEKUExtensionUsage == NULL)
  371. {
  372. //
  373. // if we are in case 1 or 2, then all the usage that are valid
  374. // for the chain are entered into the list view, unless the chain
  375. // is good for everything, in which case the current certs valid
  376. // usages are entered
  377. //
  378. if (pviewhelp->cszValidUsages != -1)
  379. {
  380. for (i=0; i<(DWORD)pviewhelp->cszValidUsages; i++)
  381. {
  382. if ((pPropertyUsage == NULL) || OIDInUsages(pPropertyUsage, pviewhelp->rgszValidChainUsages[i]))
  383. {
  384. dwImage = MY_CHECK_STATE_CHECKED;
  385. }
  386. else
  387. {
  388. dwImage = MY_CHECK_STATE_UNCHECKED;
  389. }
  390. AddUsageToList(hWndListView, pviewhelp->rgszValidChainUsages[i], dwImage, FALSE);
  391. }
  392. }
  393. else
  394. {
  395. AllocAndReturnEKUList(pCertContext, &pszOIDs, &numOIDs);
  396. for (i=0; i<numOIDs; i++)
  397. {
  398. //
  399. // if there are no property usages, or if this usage is in the list of
  400. // property usages, then set the state to checked
  401. //
  402. if ((pPropertyUsage == NULL) || OIDInUsages(pPropertyUsage, pszOIDs[i]))
  403. {
  404. dwImage = MY_CHECK_STATE_CHECKED;
  405. }
  406. else
  407. {
  408. dwImage = MY_CHECK_STATE_UNCHECKED;
  409. }
  410. AddUsageToList(hWndListView, pszOIDs[i], dwImage, FALSE);
  411. }
  412. FreeEKUList(pszOIDs, numOIDs);
  413. }
  414. }
  415. else
  416. {
  417. //
  418. // for cases 3 and 4, the list view is populated with only the EKU extension,
  419. // and is further restricted that the EKU must be in the chain valid usages
  420. //
  421. for (i=0; i<pEKUExtensionUsage->cUsageIdentifier; i++)
  422. {
  423. //
  424. // if the EKU is not valid up the chain then skip the display
  425. //
  426. if ((pviewhelp->cszValidUsages != -1) &&
  427. !OIDinArray(pEKUExtensionUsage->rgpszUsageIdentifier[i],
  428. pviewhelp->rgszValidChainUsages,
  429. pviewhelp->cszValidUsages))
  430. {
  431. continue;
  432. }
  433. //
  434. // if there are no properties or the usage is in the properties then
  435. // the usage should be checked
  436. //
  437. if ((pPropertyUsage == NULL) || OIDInUsages(pPropertyUsage, pEKUExtensionUsage->rgpszUsageIdentifier[i]))
  438. {
  439. dwImage = MY_CHECK_STATE_CHECKED;
  440. }
  441. else
  442. {
  443. dwImage = MY_CHECK_STATE_UNCHECKED;
  444. }
  445. AddUsageToList(hWndListView, pEKUExtensionUsage->rgpszUsageIdentifier[i], dwImage, FALSE);
  446. }
  447. }
  448. CleanUp:
  449. if (pPropertyUsage != NULL)
  450. free(pPropertyUsage);
  451. if (pEKUExtensionUsage != NULL)
  452. free(pEKUExtensionUsage);
  453. }
  454. //////////////////////////////////////////////////////////////////////////////////////
  455. //
  456. //////////////////////////////////////////////////////////////////////////////////////
  457. static BOOL StateChanged(HWND hWndListView)
  458. {
  459. int listIndex;
  460. LVITEMW lvI;
  461. memset(&lvI, 0, sizeof(lvI));
  462. lvI.mask = LVIF_STATE | LVIF_PARAM;
  463. lvI.stateMask = LVIS_STATEIMAGEMASK;
  464. listIndex = ListView_GetItemCount(hWndListView) - 1;
  465. while (listIndex >= 0)
  466. {
  467. lvI.iItem = listIndex--;
  468. lvI.state = 0;
  469. lvI.lParam = 0;
  470. ListView_GetItem(hWndListView, &lvI);
  471. if (lvI.state != ((PSETPROPERTIES_HELPER_STRUCT)lvI.lParam)->initialState)
  472. {
  473. return TRUE;
  474. }
  475. }
  476. return FALSE;
  477. }
  478. //////////////////////////////////////////////////////////////////////////////////////
  479. //
  480. //////////////////////////////////////////////////////////////////////////////////////
  481. static
  482. PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW
  483. AllocAndCopySetPropertiesStruct(PCCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW pcsp)
  484. {
  485. PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW pStruct;
  486. DWORD i;
  487. if (NULL == (pStruct = (PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW)
  488. malloc(sizeof(CRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW))))
  489. {
  490. return NULL;
  491. }
  492. memcpy(pStruct, pcsp, sizeof(CRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW));
  493. if (NULL == (pStruct->rghStores = (HCERTSTORE *) malloc(sizeof(HCERTSTORE)*pcsp->cStores)))
  494. {
  495. free(pStruct);
  496. return NULL;
  497. }
  498. pStruct->cPropSheetPages = 0;
  499. pStruct->rgPropSheetPages = NULL;
  500. pStruct->pCertContext = CertDuplicateCertificateContext(pcsp->pCertContext);
  501. for (i=0; i<pcsp->cStores; i++)
  502. {
  503. pStruct->rghStores[i] = CertDuplicateStore(pcsp->rghStores[i]);
  504. }
  505. return pStruct;
  506. }
  507. //////////////////////////////////////////////////////////////////////////////////////
  508. //
  509. //////////////////////////////////////////////////////////////////////////////////////
  510. static void FreeSetPropertiesStruct(PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW pcsp)
  511. {
  512. DWORD i;
  513. CertFreeCertificateContext(pcsp->pCertContext);
  514. for (i=0; i<pcsp->cStores; i++)
  515. {
  516. CertCloseStore(pcsp->rghStores[i], 0);
  517. }
  518. free(pcsp->rghStores);
  519. free(pcsp);
  520. }
  521. //////////////////////////////////////////////////////////////////////////////////////
  522. //
  523. //////////////////////////////////////////////////////////////////////////////////////
  524. static BOOL OIDAlreadyExist(LPSTR pszNewOID, HWND hWndListView)
  525. {
  526. LVITEMW lvI;
  527. PSETPROPERTIES_HELPER_STRUCT pHelperStruct;
  528. memset(&lvI, 0, sizeof(lvI));
  529. lvI.iItem = ListView_GetItemCount(hWndListView) - 1;
  530. lvI.mask = LVIF_PARAM;
  531. while (lvI.iItem >= 0)
  532. {
  533. if (ListView_GetItemU(hWndListView, &lvI))
  534. {
  535. pHelperStruct = (PSETPROPERTIES_HELPER_STRUCT) lvI.lParam;
  536. if (strcmp(pHelperStruct->pszOID, pszNewOID) == 0)
  537. {
  538. return TRUE;
  539. }
  540. }
  541. lvI.iItem--;
  542. }
  543. return FALSE;
  544. }
  545. //////////////////////////////////////////////////////////////////////////////////////
  546. //
  547. //////////////////////////////////////////////////////////////////////////////////////
  548. static BOOL CertHasEKU(PCCERT_CONTEXT pccert)
  549. {
  550. DWORD i;
  551. i = 0;
  552. while (i < pccert->pCertInfo->cExtension)
  553. {
  554. if (strcmp(pccert->pCertInfo->rgExtension[i].pszObjId, szOID_ENHANCED_KEY_USAGE) == 0)
  555. {
  556. return TRUE;
  557. }
  558. i++;
  559. }
  560. return FALSE;
  561. }
  562. //////////////////////////////////////////////////////////////////////////////////////
  563. //
  564. //////////////////////////////////////////////////////////////////////////////////////
  565. static BOOL BuildChainEKUList(PCERT_SETPROPERTIES_HELPER pviewhelp)
  566. {
  567. WINTRUST_DATA WTD;
  568. WINTRUST_CERT_INFO WTCI;
  569. CRYPT_PROVIDER_DATA const * pProvData = NULL;
  570. CRYPT_PROVIDER_SGNR * pProvSigner = NULL;
  571. PCRYPT_PROVIDER_CERT pProvCert = NULL;
  572. PCCERT_CONTEXT *rgpCertContext = NULL;
  573. DWORD i;
  574. BOOL fRet = TRUE;
  575. DWORD cbOIDs = 0;
  576. DWORD dwCertsForUsageCheck = 0;
  577. GUID defaultProviderGUID = WINTRUST_ACTION_GENERIC_CERT_VERIFY;
  578. pviewhelp->cszValidUsages = 0;
  579. //
  580. // initialize structs that are used with WinVerifyTrust()
  581. //
  582. memset(&WTD, 0x00, sizeof(WINTRUST_DATA));
  583. WTD.cbStruct = sizeof(WINTRUST_DATA);
  584. WTD.dwUIChoice = WTD_UI_NONE;
  585. WTD.dwUnionChoice = WTD_CHOICE_CERT;
  586. WTD.pCert = &WTCI;
  587. WTD.dwProvFlags = WTD_NO_POLICY_USAGE_FLAG | WTD_REVOCATION_CHECK_NONE;
  588. memset(&WTCI, 0x00, sizeof(WINTRUST_CERT_INFO));
  589. WTCI.cbStruct = sizeof(WINTRUST_CERT_INFO);
  590. WTCI.pcwszDisplayName = L"CryptUI";
  591. WTCI.psCertContext = (CERT_CONTEXT *)pviewhelp->pcsp->pCertContext;
  592. WTCI.chStores = pviewhelp->pcsp->cStores;
  593. WTCI.pahStores = pviewhelp->pcsp->rghStores;
  594. WTCI.dwFlags = 0;
  595. WTD.dwStateAction = WTD_STATEACTION_VERIFY;
  596. //
  597. // the default default provider requires the policycallback data to point
  598. // to the usage oid you are validating for, so set it to the usage passed in
  599. //
  600. WinVerifyTrustEx(NULL, &defaultProviderGUID, &WTD);
  601. pProvData = WTHelperProvDataFromStateData(WTD.hWVTStateData);
  602. pProvSigner = WTHelperGetProvSignerFromChain((PCRYPT_PROVIDER_DATA) pProvData, 0, FALSE, 0);
  603. if (pProvSigner == NULL)
  604. {
  605. goto Error;
  606. }
  607. //
  608. // build up the array of PCCERT_CONTEXTs
  609. //
  610. rgpCertContext = (PCCERT_CONTEXT *) malloc((pProvSigner->csCertChain-1) * sizeof(PCCERT_CONTEXT));
  611. if (rgpCertContext == NULL)
  612. {
  613. goto Error;
  614. }
  615. for (i=1; i<pProvSigner->csCertChain; i++)
  616. {
  617. pProvCert = WTHelperGetProvCertFromChain(pProvSigner, i);
  618. rgpCertContext[i-1] = pProvCert->pCert;
  619. dwCertsForUsageCheck++;
  620. //
  621. // if there is a CTL context that contains this cert, then the usage
  622. // changes for certs above the CTL in the chain, so stop with this
  623. // cert when calculating valid usages
  624. //
  625. if (pProvCert->pCtlContext != NULL)
  626. {
  627. break;
  628. }
  629. }
  630. //
  631. // now, get the usages array
  632. //
  633. if (!CertGetValidUsages(dwCertsForUsageCheck, rgpCertContext, &(pviewhelp->cszValidUsages), NULL, &cbOIDs))
  634. {
  635. goto Error;
  636. }
  637. if (NULL == (pviewhelp->rgszValidChainUsages = (LPSTR *) malloc(cbOIDs)))
  638. {
  639. goto Error;
  640. }
  641. if (!CertGetValidUsages(dwCertsForUsageCheck, rgpCertContext, &(pviewhelp->cszValidUsages), pviewhelp->rgszValidChainUsages, &cbOIDs))
  642. {
  643. free(pviewhelp->rgszValidChainUsages);
  644. pviewhelp->rgszValidChainUsages = NULL;
  645. goto Error;
  646. }
  647. CleanUp:
  648. WTD.dwStateAction = WTD_STATEACTION_CLOSE;
  649. WinVerifyTrustEx(NULL, &defaultProviderGUID, &WTD);
  650. if (rgpCertContext != NULL)
  651. {
  652. free(rgpCertContext);
  653. }
  654. return fRet;
  655. Error:
  656. fRet = FALSE;
  657. goto CleanUp;
  658. }
  659. //////////////////////////////////////////////////////////////////////////////////////
  660. //
  661. //////////////////////////////////////////////////////////////////////////////////////
  662. static void AddExistingPropertiesToUsage(
  663. PCCERT_CONTEXT pccert,
  664. PCERT_ENHKEY_USAGE pPropertyUsage,
  665. HWND hWndListView)
  666. {
  667. PCERT_ENHKEY_USAGE pExistingPropUsage = NULL;
  668. DWORD cbExistingPropUsage = 0;
  669. DWORD i;
  670. BOOL fSkip = FALSE;
  671. LVITEMW lvI;
  672. DWORD state;
  673. void *pTemp;
  674. //
  675. // get the property usages that are currently tagged to this cert
  676. //
  677. if(!CertGetEnhancedKeyUsage (
  678. pccert,
  679. CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG,
  680. NULL,
  681. &cbExistingPropUsage
  682. ) ||
  683. (pExistingPropUsage = (PCERT_ENHKEY_USAGE) malloc(cbExistingPropUsage)) == NULL ||
  684. !CertGetEnhancedKeyUsage (
  685. pccert,
  686. CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG,
  687. pExistingPropUsage,
  688. &cbExistingPropUsage
  689. ) )
  690. {
  691. if (pExistingPropUsage != NULL)
  692. {
  693. free(pExistingPropUsage);
  694. }
  695. return;
  696. }
  697. //
  698. // loop for each usage, and add it if it does not already exist in the list,
  699. // AND it is not already in the list view unchecked
  700. //
  701. for (i=0; i<pExistingPropUsage->cUsageIdentifier; i++)
  702. {
  703. if (!OIDInUsages(pPropertyUsage, pExistingPropUsage->rgpszUsageIdentifier[i]))
  704. {
  705. fSkip = FALSE;
  706. //
  707. // if the property is unchecked in the list view then skip it
  708. //
  709. memset(&lvI, 0, sizeof(lvI));
  710. lvI.mask = LVIF_PARAM;
  711. lvI.lParam = (LPARAM)NULL;
  712. lvI.iItem = ListView_GetItemCount(hWndListView) - 1;
  713. lvI.iSubItem = 0;
  714. while (lvI.iItem >= 0)
  715. {
  716. if (ListView_GetItemU(hWndListView, &lvI))
  717. {
  718. if (strcmp(((PSETPROPERTIES_HELPER_STRUCT)lvI.lParam)->pszOID,
  719. pExistingPropUsage->rgpszUsageIdentifier[i]) == 0)
  720. {
  721. state = MyGetCheckState(hWndListView, lvI.iItem);
  722. if ((state == MY_CHECK_STATE_UNCHECKED) || (state == MY_CHECK_STATE_UNCHECKED_GRAYED))
  723. {
  724. fSkip = TRUE;
  725. break;
  726. }
  727. }
  728. }
  729. lvI.iItem--;
  730. }
  731. if (fSkip)
  732. {
  733. continue;
  734. }
  735. //
  736. // allocate space for a pointer to the usage OID string
  737. //
  738. if (pPropertyUsage->cUsageIdentifier++ == 0)
  739. {
  740. pPropertyUsage->rgpszUsageIdentifier = (LPSTR *) malloc (sizeof(LPSTR));
  741. }
  742. else
  743. {
  744. pTemp = realloc (pPropertyUsage->rgpszUsageIdentifier,
  745. sizeof(LPSTR) * pPropertyUsage->cUsageIdentifier);
  746. if (pTemp == NULL)
  747. {
  748. free(pPropertyUsage->rgpszUsageIdentifier);
  749. pPropertyUsage->rgpszUsageIdentifier = NULL;
  750. }
  751. else
  752. {
  753. pPropertyUsage->rgpszUsageIdentifier = (LPSTR *) pTemp;
  754. }
  755. }
  756. if (pPropertyUsage->rgpszUsageIdentifier == NULL)
  757. {
  758. pPropertyUsage->cUsageIdentifier = 0;
  759. return;
  760. }
  761. pPropertyUsage->rgpszUsageIdentifier[pPropertyUsage->cUsageIdentifier-1] =
  762. AllocAndCopyMBStr(pExistingPropUsage->rgpszUsageIdentifier[i]);
  763. }
  764. }
  765. if (pExistingPropUsage != NULL)
  766. {
  767. free(pExistingPropUsage);
  768. }
  769. }
  770. //////////////////////////////////////////////////////////////////////////////////////
  771. //
  772. //////////////////////////////////////////////////////////////////////////////////////
  773. INT_PTR APIENTRY ViewPageSetPropertiesGeneral(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  774. {
  775. BOOL f;
  776. DWORD cch;
  777. PCCERT_CONTEXT pccert;
  778. PROPSHEETPAGE * ps;
  779. LPWSTR pwsz;
  780. WCHAR rgwch[CRYPTUI_MAX_STRING_SIZE];
  781. CRYPT_DATA_BLOB CryptDataBlob;
  782. DWORD cbpwsz;
  783. HIMAGELIST hIml;
  784. HWND hWndListView;
  785. HWND hwnd;
  786. LV_COLUMNW lvC;
  787. LVITEMW lvI;
  788. LPNMLISTVIEW pnmv;
  789. DWORD state;
  790. LPSTR pszNewOID;
  791. WCHAR errorString[CRYPTUI_MAX_STRING_SIZE];
  792. WCHAR errorTitle[CRYPTUI_MAX_STRING_SIZE];
  793. int j;
  794. DWORD i;
  795. void *pTemp;
  796. PCERT_SETPROPERTIES_HELPER pviewhelp;
  797. PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW pcsp = NULL;
  798. switch ( msg ) {
  799. case WM_INITDIALOG:
  800. //
  801. // save the pviewhelp struct in DWL_USER so it can always be accessed
  802. //
  803. ps = (PROPSHEETPAGE *) lParam;
  804. pviewhelp = (PCERT_SETPROPERTIES_HELPER) ps->lParam;
  805. pcsp = (PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) pviewhelp->pcsp;
  806. pccert = pcsp->pCertContext;
  807. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR) pviewhelp);
  808. fRichedit20Usable(GetDlgItem(hwndDlg, IDC_HIDDEN_RICHEDIT));
  809. ShowWindow(GetDlgItem(hwndDlg, IDC_HIDDEN_RICHEDIT), SW_HIDE);
  810. //
  811. // Set the Certificate Name (friendly name) and Description fields in the dialog box
  812. //
  813. cbpwsz = 0;
  814. if (CertGetCertificateContextProperty( pccert,
  815. CERT_FRIENDLY_NAME_PROP_ID,
  816. NULL,
  817. &cbpwsz))
  818. {
  819. //
  820. // The Certificate Name (friendly name) property exists, so display it
  821. //
  822. pviewhelp->pwszInitialCertName = (LPWSTR) malloc(cbpwsz);
  823. if (pviewhelp->pwszInitialCertName != NULL)
  824. {
  825. CertGetCertificateContextProperty( pccert,
  826. CERT_FRIENDLY_NAME_PROP_ID,
  827. pviewhelp->pwszInitialCertName,
  828. &cbpwsz);
  829. CryptUISetRicheditTextW(hwndDlg, IDC_CERTIFICATE_NAME, pviewhelp->pwszInitialCertName);
  830. }
  831. }
  832. else
  833. {
  834. //
  835. // The Certificate Name (friendly name) property did not exist, so display the default
  836. //
  837. //LoadStringU(HinstDll, IDS_DEFAULT_CERTIFICATE_NAME, rgwch, ARRAYSIZE(rgwch));
  838. CryptUISetRicheditTextW(hwndDlg, IDC_CERTIFICATE_NAME, L"");
  839. pviewhelp->pwszInitialCertName = AllocAndCopyWStr(L"");
  840. }
  841. // DSIE: IE 6 bug #13676.
  842. SendDlgItemMessage(hwndDlg, IDC_CERTIFICATE_NAME, EM_EXLIMITTEXT, 0, (LPARAM) 40);
  843. cbpwsz = 0;
  844. if (CertGetCertificateContextProperty( pccert,
  845. CERT_DESCRIPTION_PROP_ID,
  846. NULL,
  847. &cbpwsz))
  848. {
  849. //
  850. // The Description property exists, so display it
  851. //
  852. pviewhelp->pwszInitialDescription = (LPWSTR) malloc(cbpwsz);
  853. if (pviewhelp->pwszInitialDescription != NULL)
  854. {
  855. CertGetCertificateContextProperty( pccert,
  856. CERT_DESCRIPTION_PROP_ID,
  857. pviewhelp->pwszInitialDescription,
  858. &cbpwsz);
  859. CryptUISetRicheditTextW(hwndDlg, IDC_DESCRIPTION, pviewhelp->pwszInitialDescription);
  860. }
  861. }
  862. else
  863. {
  864. //
  865. // The Description property did not exist, so display the default
  866. //
  867. //LoadStringU(HinstDll, IDS_DEFAULT_DESCRIPTION, rgwch, ARRAYSIZE(rgwch));
  868. CryptUISetRicheditTextW(hwndDlg, IDC_DESCRIPTION, L"");
  869. pviewhelp->pwszInitialDescription = AllocAndCopyWStr(L"");
  870. }
  871. // DSIE: IE 6 bug #13676.
  872. SendDlgItemMessage(hwndDlg, IDC_DESCRIPTION, EM_EXLIMITTEXT, 0, (LPARAM) 255);
  873. //
  874. // get the handle of the list view control
  875. //
  876. hWndListView = GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST);
  877. //
  878. // initialize the image list for the list view, load the icons,
  879. // then add the image list to the list view
  880. //
  881. ListView_SetExtendedListViewStyle(hWndListView, LVS_EX_CHECKBOXES);
  882. hIml = ImageList_LoadImage(HinstDll, MAKEINTRESOURCE(IDB_CHECKLIST), 0, 4, RGB(255,0,255), IMAGE_BITMAP, 0);
  883. if (hIml != NULL)
  884. {
  885. ListView_SetImageList(hWndListView, hIml, LVSIL_STATE);
  886. }
  887. //
  888. // initialize the columns in the list view
  889. //
  890. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  891. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  892. lvC.cx = 330; // Width of the column, in pixels.
  893. lvC.pszText = L""; // The text for the column.
  894. if (ListView_InsertColumnU(hWndListView, 0, &lvC) == -1)
  895. {
  896. // error
  897. }
  898. BuildChainEKUList(pviewhelp);
  899. pviewhelp->fInserting = TRUE;
  900. DisplayKeyUsages(hWndListView, pviewhelp);
  901. pviewhelp->fInserting = FALSE;
  902. //
  903. // set the flag noting whether the add purposes button can be
  904. // enabled based on wether there are EKU's in the cert, and if
  905. // the chain is NOT valid for all usages
  906. //
  907. if (CertHasEKU(pccert) || (pviewhelp->cszValidUsages != -1))
  908. {
  909. pviewhelp->fAddPurposeCanBeEnabled = FALSE;
  910. }
  911. else
  912. {
  913. pviewhelp->fAddPurposeCanBeEnabled = TRUE;
  914. }
  915. //
  916. // set the state of the property editing controls based on the
  917. // state of the eku PROPERTY
  918. //
  919. if (pviewhelp->EKUPropertyState == PROPERTY_STATE_ALL_ENABLED)
  920. {
  921. SendDlgItemMessage(hwndDlg, IDC_ENABLE_ALL_RADIO, BM_SETCHECK, BST_CHECKED, (LPARAM) 0);
  922. SetEnableStateForChecks(pviewhelp, GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), FALSE);
  923. EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), FALSE);
  924. EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTY_NEWOID), FALSE);
  925. pviewhelp->dwRadioButtonState = IDC_ENABLE_ALL_RADIO;
  926. }
  927. else if (pviewhelp->EKUPropertyState == PROPERTY_STATE_ALL_DISABLED)
  928. {
  929. SendDlgItemMessage(hwndDlg, IDC_DISABLE_ALL_RADIO, BM_SETCHECK, BST_CHECKED, (LPARAM) 0);
  930. SetEnableStateForChecks(pviewhelp, GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), FALSE);
  931. EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), FALSE);
  932. EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTY_NEWOID), FALSE);
  933. pviewhelp->dwRadioButtonState = IDC_DISABLE_ALL_RADIO;
  934. }
  935. else if (pviewhelp->EKUPropertyState == PROPERTY_STATE_SELECT)
  936. {
  937. SendDlgItemMessage(hwndDlg, IDC_ENABLE_SELECT_RADIO, BM_SETCHECK, BST_CHECKED, (LPARAM) 0);
  938. EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), TRUE);
  939. SetEnableStateForChecks(pviewhelp, GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), TRUE);
  940. if (pviewhelp->fAddPurposeCanBeEnabled)
  941. {
  942. EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTY_NEWOID), TRUE);
  943. }
  944. else
  945. {
  946. EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTY_NEWOID), FALSE);
  947. }
  948. pviewhelp->dwRadioButtonState = IDC_ENABLE_SELECT_RADIO;
  949. }
  950. //
  951. // make sure we get change notifications from the richedit controls
  952. //
  953. SendDlgItemMessageA(hwndDlg, IDC_CERTIFICATE_NAME, EM_SETEVENTMASK, 0, (LPARAM) ENM_CHANGE);
  954. SendDlgItemMessageA(hwndDlg, IDC_DESCRIPTION, EM_SETEVENTMASK, 0, (LPARAM) ENM_CHANGE);
  955. return TRUE;
  956. case WM_NOTIFY:
  957. pviewhelp = (PCERT_SETPROPERTIES_HELPER) GetWindowLongPtr(hwndDlg, DWLP_USER);
  958. pcsp = (PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) pviewhelp->pcsp;
  959. pccert = pcsp->pCertContext;
  960. switch (((NMHDR FAR *) lParam)->code) {
  961. case PSN_SETACTIVE:
  962. break;
  963. case PSN_APPLY:
  964. {
  965. BOOL fAllItemsChecked = TRUE;
  966. DWORD cbPropertyUsage = 0;
  967. PCERT_ENHKEY_USAGE pPropertyUsage = NULL;
  968. GETTEXTEX GetTextStruct;
  969. memset(&GetTextStruct, 0, sizeof(GetTextStruct));
  970. GetTextStruct.flags = GT_DEFAULT;
  971. GetTextStruct.codepage = 1200; //UNICODE
  972. //
  973. // Write back the Friendly name
  974. // and description if they have changed
  975. //
  976. //
  977. // Friendly Name
  978. //
  979. cch = (DWORD)SendDlgItemMessage(hwndDlg, IDC_CERTIFICATE_NAME,
  980. WM_GETTEXTLENGTH, 0, 0);
  981. pwsz = (LPWSTR) malloc((cch+1)*sizeof(WCHAR));
  982. if (pwsz != NULL)
  983. {
  984. memset(pwsz, 0, (cch+1)*sizeof(WCHAR));
  985. if (fRichedit20Exists && fRichedit20Usable(GetDlgItem(hwndDlg, IDC_HIDDEN_RICHEDIT)))
  986. {
  987. GetTextStruct.cb = (cch+1)*sizeof(WCHAR);
  988. SendDlgItemMessageA(
  989. hwndDlg,
  990. IDC_CERTIFICATE_NAME,
  991. EM_GETTEXTEX,
  992. (WPARAM) &GetTextStruct,
  993. (LPARAM) pwsz);
  994. }
  995. else
  996. {
  997. GetDlgItemTextU(hwndDlg, IDC_CERTIFICATE_NAME, pwsz, cch+1);
  998. }
  999. //
  1000. // check for change
  1001. //
  1002. if (wcscmp(pviewhelp->pwszInitialCertName, pwsz) != 0)
  1003. {
  1004. if (wcscmp(pwsz, L"") == 0)
  1005. {
  1006. f = CertSetCertificateContextProperty(pccert,
  1007. CERT_FRIENDLY_NAME_PROP_ID, 0,
  1008. NULL);
  1009. }
  1010. else
  1011. {
  1012. CryptDataBlob.pbData = (LPBYTE) pwsz;
  1013. CryptDataBlob.cbData = (cch+1)*sizeof(WCHAR);
  1014. f = CertSetCertificateContextProperty(pccert,
  1015. CERT_FRIENDLY_NAME_PROP_ID, 0,
  1016. &CryptDataBlob);
  1017. }
  1018. if (pviewhelp->pfPropertiesChanged != NULL)
  1019. {
  1020. *(pviewhelp->pfPropertiesChanged) = TRUE;
  1021. }
  1022. pviewhelp->fPropertiesChanged = TRUE;
  1023. }
  1024. free(pwsz);
  1025. }
  1026. //
  1027. // Description
  1028. //
  1029. cch = (DWORD)SendDlgItemMessage(hwndDlg, IDC_DESCRIPTION,
  1030. WM_GETTEXTLENGTH, 0, 0);
  1031. pwsz = (LPWSTR) malloc((cch+1)*sizeof(WCHAR));
  1032. if (pwsz != NULL)
  1033. {
  1034. memset(pwsz, 0, (cch+1)*sizeof(WCHAR));
  1035. if (fRichedit20Exists && fRichedit20Usable(GetDlgItem(hwndDlg, IDC_HIDDEN_RICHEDIT)))
  1036. {
  1037. GetTextStruct.cb = (cch+1)*sizeof(WCHAR);
  1038. SendDlgItemMessageA(
  1039. hwndDlg,
  1040. IDC_DESCRIPTION,
  1041. EM_GETTEXTEX,
  1042. (WPARAM) &GetTextStruct,
  1043. (LPARAM) pwsz);
  1044. }
  1045. else
  1046. {
  1047. GetDlgItemTextU(hwndDlg, IDC_DESCRIPTION, pwsz, cch+1);
  1048. }
  1049. //
  1050. // check for change
  1051. //
  1052. if (wcscmp(pviewhelp->pwszInitialDescription, pwsz) != 0)
  1053. {
  1054. if (wcscmp(pwsz, L"") == 0)
  1055. {
  1056. f = CertSetCertificateContextProperty(pccert,
  1057. CERT_DESCRIPTION_PROP_ID, 0,
  1058. NULL);
  1059. }
  1060. else
  1061. {
  1062. CryptDataBlob.pbData = (LPBYTE) pwsz;
  1063. CryptDataBlob.cbData = (cch+1)*sizeof(WCHAR);
  1064. f = CertSetCertificateContextProperty(pccert,
  1065. CERT_DESCRIPTION_PROP_ID, 0,
  1066. &CryptDataBlob);
  1067. }
  1068. if (pviewhelp->pfPropertiesChanged != NULL)
  1069. {
  1070. *(pviewhelp->pfPropertiesChanged) = TRUE;
  1071. }
  1072. pviewhelp->fPropertiesChanged = TRUE;
  1073. }
  1074. free(pwsz);
  1075. }
  1076. hWndListView = GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST);
  1077. //
  1078. // check the radio buttons and the usages to see if any have changed,
  1079. // if so, then set the fPropertiesFlag in the CERT_VIEWCERT_STRUCT so the
  1080. // caller knows that something has changed
  1081. //
  1082. if ((pviewhelp->EKUPropertyState == PROPERTY_STATE_ALL_ENABLED) &&
  1083. (SendDlgItemMessage(hwndDlg, IDC_ENABLE_ALL_RADIO, BM_GETCHECK, 0, (LPARAM) 0) == BST_CHECKED))
  1084. {
  1085. //pviewhelp->fPropertiesChanged = FALSE;
  1086. }
  1087. else if ((pviewhelp->EKUPropertyState == PROPERTY_STATE_ALL_DISABLED) &&
  1088. (SendDlgItemMessage(hwndDlg, IDC_DISABLE_ALL_RADIO, BM_GETCHECK, 0, (LPARAM) 0) == BST_CHECKED))
  1089. {
  1090. //pviewhelp->fPropertiesChanged = FALSE;
  1091. }
  1092. else if ((pviewhelp->EKUPropertyState == PROPERTY_STATE_SELECT) &&
  1093. (SendDlgItemMessage(hwndDlg, IDC_ENABLE_SELECT_RADIO, BM_GETCHECK, 0, (LPARAM) 0) == BST_CHECKED) &&
  1094. (!StateChanged(hWndListView)))
  1095. {
  1096. //pviewhelp->fPropertiesChanged = FALSE;
  1097. }
  1098. else
  1099. {
  1100. pviewhelp->fPropertiesChanged = TRUE;
  1101. }
  1102. if (pviewhelp->pfPropertiesChanged != NULL)
  1103. {
  1104. *(pviewhelp->pfPropertiesChanged) |= pviewhelp->fPropertiesChanged;
  1105. }
  1106. if ((SendDlgItemMessage(hwndDlg, IDC_ENABLE_ALL_RADIO, BM_GETCHECK, 0, (LPARAM) 0) == BST_CHECKED) &&
  1107. pviewhelp->fPropertiesChanged)
  1108. {
  1109. CertSetEnhancedKeyUsage(pccert, NULL);
  1110. }
  1111. else if ((SendDlgItemMessage(hwndDlg, IDC_DISABLE_ALL_RADIO, BM_GETCHECK, 0, (LPARAM) 0) == BST_CHECKED) &&
  1112. pviewhelp->fPropertiesChanged)
  1113. {
  1114. CERT_ENHKEY_USAGE eku;
  1115. eku.cUsageIdentifier = 0;
  1116. eku.rgpszUsageIdentifier = NULL;
  1117. CertSetEnhancedKeyUsage(pccert, &eku);
  1118. }
  1119. else if ((SendDlgItemMessage(hwndDlg, IDC_ENABLE_SELECT_RADIO, BM_GETCHECK, 0, (LPARAM) 0) == BST_CHECKED) &&
  1120. pviewhelp->fPropertiesChanged)
  1121. {
  1122. if (NULL == (pPropertyUsage = (PCERT_ENHKEY_USAGE) malloc(sizeof(CERT_ENHKEY_USAGE))))
  1123. {
  1124. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)FALSE);
  1125. return FALSE;
  1126. }
  1127. pPropertyUsage->cUsageIdentifier = 0;
  1128. pPropertyUsage->rgpszUsageIdentifier = NULL;
  1129. //
  1130. // enumerate through all the items and add to the properties
  1131. // if checked
  1132. //
  1133. memset(&lvI, 0, sizeof(lvI));
  1134. lvI.mask = LVIF_PARAM;
  1135. lvI.lParam = (LPARAM)NULL;
  1136. lvI.iItem = ListView_GetItemCount(hWndListView) - 1;
  1137. lvI.iSubItem = 0;
  1138. while (lvI.iItem >= 0)
  1139. {
  1140. if (!ListView_GetItemU(hWndListView, &lvI))
  1141. {
  1142. lvI.iItem--;
  1143. continue;
  1144. }
  1145. state = MyGetCheckState(hWndListView, lvI.iItem);
  1146. if ((state == MY_CHECK_STATE_CHECKED) || (state == MY_CHECK_STATE_CHECKED_GRAYED))
  1147. {
  1148. //
  1149. // allocate space for a pointer to the usage OID string
  1150. //
  1151. if (pPropertyUsage->cUsageIdentifier++ == 0)
  1152. {
  1153. pPropertyUsage->rgpszUsageIdentifier = (LPSTR *) malloc (sizeof(LPSTR));
  1154. }
  1155. else
  1156. {
  1157. pTemp = realloc (pPropertyUsage->rgpszUsageIdentifier,
  1158. sizeof(LPSTR) * pPropertyUsage->cUsageIdentifier);
  1159. if (pTemp == NULL)
  1160. {
  1161. free(pPropertyUsage->rgpszUsageIdentifier);
  1162. pPropertyUsage->rgpszUsageIdentifier = NULL;
  1163. }
  1164. else
  1165. {
  1166. pPropertyUsage->rgpszUsageIdentifier = (LPSTR *) pTemp;
  1167. }
  1168. }
  1169. if (pPropertyUsage->rgpszUsageIdentifier == NULL)
  1170. {
  1171. free(pPropertyUsage);
  1172. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)FALSE);
  1173. return FALSE;
  1174. }
  1175. pPropertyUsage->rgpszUsageIdentifier[pPropertyUsage->cUsageIdentifier-1] =
  1176. AllocAndCopyMBStr(((PSETPROPERTIES_HELPER_STRUCT)lvI.lParam)->pszOID);
  1177. }
  1178. lvI.iItem--;
  1179. }
  1180. AddExistingPropertiesToUsage(pccert, pPropertyUsage, hWndListView);
  1181. CertSetEnhancedKeyUsage(pccert, pPropertyUsage);
  1182. for (i=0; i<pPropertyUsage->cUsageIdentifier; i++)
  1183. {
  1184. free(pPropertyUsage->rgpszUsageIdentifier[i]);
  1185. }
  1186. if (pPropertyUsage->rgpszUsageIdentifier)
  1187. free(pPropertyUsage->rgpszUsageIdentifier);
  1188. }
  1189. if (pPropertyUsage != NULL)
  1190. free(pPropertyUsage);
  1191. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)TRUE);
  1192. break;
  1193. }
  1194. case PSN_KILLACTIVE:
  1195. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)FALSE);
  1196. return TRUE;
  1197. case PSN_RESET:
  1198. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)FALSE);
  1199. break;
  1200. case PSN_QUERYCANCEL:
  1201. pviewhelp->fCancelled = TRUE;
  1202. return FALSE;
  1203. case PSN_HELP:
  1204. if (FIsWin95) {
  1205. //WinHelpA(hwndDlg, (LPSTR) pcsp->szHelpFileName,
  1206. // HELP_CONTEXT, pcsp->dwHelpId);
  1207. }
  1208. else {
  1209. // WinHelpW(hwndDlg, pcsp->szHelpFileName, HELP_CONTEXT,
  1210. // pcsp->dwHelpId);
  1211. }
  1212. return TRUE;
  1213. case LVN_ITEMCHANGING:
  1214. if (pviewhelp->fInserting)
  1215. {
  1216. return TRUE;
  1217. }
  1218. pnmv = (LPNMLISTVIEW) lParam;
  1219. hWndListView = GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST);
  1220. state = LVIS_STATEIMAGEMASK & pnmv->uOldState;
  1221. if ((state == MY_CHECK_STATE_CHECKED_GRAYED) || (state == MY_CHECK_STATE_UNCHECKED_GRAYED))
  1222. {
  1223. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)TRUE);
  1224. }
  1225. else if ((state == MY_CHECK_STATE_CHECKED) || (state == MY_CHECK_STATE_UNCHECKED))
  1226. {
  1227. pviewhelp->fInserting = TRUE;
  1228. if (state == MY_CHECK_STATE_CHECKED)
  1229. {
  1230. MySetCheckState(hWndListView, pnmv->iItem, MY_CHECK_STATE_UNCHECKED);
  1231. }
  1232. else
  1233. {
  1234. MySetCheckState(hWndListView, pnmv->iItem, MY_CHECK_STATE_CHECKED);
  1235. }
  1236. pviewhelp->fInserting = FALSE;
  1237. PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
  1238. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)TRUE);
  1239. }
  1240. return TRUE;
  1241. case NM_SETFOCUS:
  1242. switch (((NMHDR FAR *) lParam)->idFrom)
  1243. {
  1244. case IDC_KEY_USAGE_LIST:
  1245. hWndListView = GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST);
  1246. if ((ListView_GetItemCount(hWndListView) != 0) &&
  1247. (ListView_GetNextItem(hWndListView, -1, LVNI_SELECTED) == -1))
  1248. {
  1249. memset(&lvI, 0, sizeof(lvI));
  1250. lvI.mask = LVIF_STATE;
  1251. lvI.iItem = 0;
  1252. lvI.state = LVIS_FOCUSED | LVIS_SELECTED;
  1253. lvI.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
  1254. ListView_SetItem(hWndListView, &lvI);
  1255. }
  1256. break;
  1257. }
  1258. break;
  1259. }
  1260. break;
  1261. case WM_COMMAND:
  1262. pviewhelp = (PCERT_SETPROPERTIES_HELPER) GetWindowLongPtr(hwndDlg, DWLP_USER);
  1263. pcsp = (PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) pviewhelp->pcsp;
  1264. pccert = pcsp->pCertContext;
  1265. switch (LOWORD(wParam))
  1266. {
  1267. case IDHELP:
  1268. if (FIsWin95)
  1269. {
  1270. //WinHelpA(hwndDlg, (LPSTR) pcsp->szHelpFileName,
  1271. // HELP_CONTEXT, pcsp->dwHelpId);
  1272. }
  1273. else
  1274. {
  1275. //WinHelpW(hwndDlg, pcsp->szHelpFileName, HELP_CONTEXT,
  1276. // pcsp->dwHelpId);
  1277. }
  1278. return TRUE;
  1279. case IDC_CERTIFICATE_NAME:
  1280. if (HIWORD(wParam) == EN_SETFOCUS)
  1281. {
  1282. SendDlgItemMessageA(hwndDlg, IDC_CERTIFICATE_NAME, EM_SETSEL,
  1283. 0, -1);
  1284. return TRUE;
  1285. }
  1286. else if (HIWORD(wParam) == EN_CHANGE)
  1287. {
  1288. PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
  1289. }
  1290. break;
  1291. case IDC_DESCRIPTION:
  1292. if (HIWORD(wParam) == EN_SETFOCUS)
  1293. {
  1294. SendDlgItemMessageA(hwndDlg, IDC_DESCRIPTION, EM_SETSEL,
  1295. 0, -1);
  1296. return TRUE;
  1297. }
  1298. else if (HIWORD(wParam) == EN_CHANGE)
  1299. {
  1300. PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
  1301. }
  1302. break;
  1303. case IDC_ENABLE_ALL_RADIO:
  1304. if (HIWORD(wParam) == BN_CLICKED)
  1305. {
  1306. SetEnableStateForChecks(pviewhelp, GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), FALSE);
  1307. EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), FALSE);
  1308. EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTY_NEWOID), FALSE);
  1309. if (pviewhelp->dwRadioButtonState != IDC_ENABLE_ALL_RADIO)
  1310. {
  1311. PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
  1312. pviewhelp->dwRadioButtonState = IDC_ENABLE_ALL_RADIO;
  1313. }
  1314. }
  1315. break;
  1316. case IDC_DISABLE_ALL_RADIO:
  1317. if (HIWORD(wParam) == BN_CLICKED)
  1318. {
  1319. SetEnableStateForChecks(pviewhelp, GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), FALSE);
  1320. EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), FALSE);
  1321. EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTY_NEWOID), FALSE);
  1322. if (pviewhelp->dwRadioButtonState != IDC_DISABLE_ALL_RADIO)
  1323. {
  1324. PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
  1325. pviewhelp->dwRadioButtonState = IDC_DISABLE_ALL_RADIO;
  1326. }
  1327. }
  1328. break;
  1329. case IDC_ENABLE_SELECT_RADIO:
  1330. if (HIWORD(wParam) == BN_CLICKED)
  1331. {
  1332. EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), TRUE);
  1333. SetEnableStateForChecks(pviewhelp, GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), TRUE);
  1334. if (pviewhelp->fAddPurposeCanBeEnabled)
  1335. {
  1336. EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTY_NEWOID), TRUE);
  1337. }
  1338. else
  1339. {
  1340. EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTY_NEWOID), FALSE);
  1341. }
  1342. if (pviewhelp->dwRadioButtonState != IDC_ENABLE_SELECT_RADIO)
  1343. {
  1344. PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
  1345. pviewhelp->dwRadioButtonState = IDC_ENABLE_SELECT_RADIO;
  1346. }
  1347. }
  1348. break;
  1349. case IDC_PROPERTY_NEWOID:
  1350. pszNewOID = (LPSTR) DialogBoxU(
  1351. HinstDll,
  1352. (LPWSTR) MAKEINTRESOURCE(IDD_USER_PURPOSE),
  1353. hwndDlg,
  1354. NewOIDDialogProc);
  1355. if (pszNewOID != NULL)
  1356. {
  1357. DWORD chStores = 0;
  1358. HCERTSTORE *phStores = NULL;
  1359. //
  1360. // if the OID already existis then put up a message box and return
  1361. //
  1362. if (OIDAlreadyExist(pszNewOID, GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST)))
  1363. {
  1364. WCHAR errorString2[CRYPTUI_MAX_STRING_SIZE];
  1365. WCHAR errorTitle2[CRYPTUI_MAX_STRING_SIZE];
  1366. LoadStringU(HinstDll, IDS_OID_ALREADY_EXISTS_MESSAGE, errorString2, ARRAYSIZE(errorString2));
  1367. LoadStringU(HinstDll, IDS_CERTIFICATE_PROPERTIES, errorTitle2, ARRAYSIZE(errorTitle2));
  1368. MessageBoxU(hwndDlg, errorString2, errorTitle2, MB_OK | MB_ICONWARNING);
  1369. return FALSE;
  1370. }
  1371. //
  1372. // if the usage doesn't exist in the chain usages, then put up an error
  1373. //
  1374. /*if ((pviewhelp->cszValidUsages != -1) && //pviewhelp->cszValidUsages == -1 means all usages are ok
  1375. !OIDinArray(pszNewOID, pviewhelp->rgszValidChainUsages, pviewhelp->cszValidUsages))
  1376. {
  1377. LoadStringU(HinstDll, IDS_ERROR_INVALIDOID_CERT, errorString2, ARRAYSIZE(errorString2));
  1378. LoadStringU(HinstDll, IDS_CERTIFICATE_PROPERTIES, errorTitle2, ARRAYSIZE(errorTitle2));
  1379. MessageBoxU(hwndDlg, errorString2, errorTitle2, MB_OK | MB_ICONERROR);
  1380. return FALSE;
  1381. } */
  1382. pviewhelp->fInserting = TRUE;
  1383. AddUsageToList(GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), pszNewOID, MY_CHECK_STATE_CHECKED, TRUE);
  1384. pviewhelp->fInserting = FALSE;
  1385. PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
  1386. free(pszNewOID);
  1387. }
  1388. break;
  1389. }
  1390. break;
  1391. case WM_DESTROY:
  1392. pviewhelp = (PCERT_SETPROPERTIES_HELPER) GetWindowLongPtr(hwndDlg, DWLP_USER);
  1393. //
  1394. // get all the items in the list view and free the lParam
  1395. // associated with each of them (lParam is the helper sruct)
  1396. //
  1397. hWndListView = GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST);
  1398. memset(&lvI, 0, sizeof(lvI));
  1399. lvI.iItem = ListView_GetItemCount(hWndListView) - 1;
  1400. lvI.mask = LVIF_PARAM;
  1401. while (lvI.iItem >= 0)
  1402. {
  1403. if (ListView_GetItemU(hWndListView, &lvI))
  1404. {
  1405. free((void *) lvI.lParam);
  1406. }
  1407. lvI.iItem--;
  1408. }
  1409. //
  1410. // free the name and description if they exist
  1411. //
  1412. if (pviewhelp->pwszInitialCertName)
  1413. {
  1414. free (pviewhelp->pwszInitialCertName);
  1415. }
  1416. if (pviewhelp->pwszInitialDescription)
  1417. {
  1418. free (pviewhelp->pwszInitialDescription);
  1419. }
  1420. //
  1421. // free the usage array
  1422. //
  1423. if (pviewhelp->rgszValidChainUsages)
  1424. {
  1425. free(pviewhelp->rgszValidChainUsages);
  1426. }
  1427. //
  1428. // if the properties have changed, and there is a pMMCCallback
  1429. // then make the callback to MMC
  1430. //
  1431. if (pviewhelp->fPropertiesChanged &&
  1432. pviewhelp->fGetPagesCalled &&
  1433. (pviewhelp->pcsp->pMMCCallback != NULL) &&
  1434. (pviewhelp->fMMCCallbackMade != TRUE))
  1435. {
  1436. pviewhelp->fMMCCallbackMade = TRUE;
  1437. (*(pviewhelp->pcsp->pMMCCallback->pfnCallback))(
  1438. pviewhelp->pcsp->pMMCCallback->lNotifyHandle,
  1439. pviewhelp->pcsp->pMMCCallback->param);
  1440. }
  1441. break;
  1442. case WM_HELP:
  1443. case WM_CONTEXTMENU:
  1444. if (msg == WM_HELP)
  1445. {
  1446. hwnd = GetDlgItem(hwndDlg, ((LPHELPINFO)lParam)->iCtrlId);
  1447. }
  1448. else
  1449. {
  1450. hwnd = (HWND) wParam;
  1451. }
  1452. if ((hwnd != GetDlgItem(hwndDlg, IDC_CERTIFICATE_NAME)) &&
  1453. (hwnd != GetDlgItem(hwndDlg, IDC_DESCRIPTION)) &&
  1454. (hwnd != GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST)) &&
  1455. (hwnd != GetDlgItem(hwndDlg, IDC_ENABLE_ALL_RADIO)) &&
  1456. (hwnd != GetDlgItem(hwndDlg, IDC_DISABLE_ALL_RADIO)) &&
  1457. (hwnd != GetDlgItem(hwndDlg, IDC_ENABLE_SELECT_RADIO)) &&
  1458. (hwnd != GetDlgItem(hwndDlg, IDC_PROPERTY_NEWOID)))
  1459. {
  1460. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)TRUE);
  1461. return TRUE;
  1462. }
  1463. else
  1464. {
  1465. return OnContextHelp(hwndDlg, msg, wParam, lParam, helpmapGeneral);
  1466. }
  1467. break;
  1468. }
  1469. return FALSE;
  1470. }
  1471. //////////////////////////////////////////////////////////////////////////////////////
  1472. //
  1473. //////////////////////////////////////////////////////////////////////////////////////
  1474. #define MAX_DWORD_SIZE ((DWORD) 0xffffffff)
  1475. //////////////////////////////////////////////////////////////////////////////////////
  1476. //
  1477. //////////////////////////////////////////////////////////////////////////////////////
  1478. INT_PTR APIENTRY ViewPageSetPropertiesCrossCerts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  1479. {
  1480. BOOL f;
  1481. DWORD cch;
  1482. PCCERT_CONTEXT pccert;
  1483. PROPSHEETPAGE * ps;
  1484. LPWSTR pwsz;
  1485. WCHAR rgwch[CRYPTUI_MAX_STRING_SIZE];
  1486. CRYPT_DATA_BLOB CryptDataBlob;
  1487. HWND hWndListView;
  1488. HWND hwnd;
  1489. LVITEMW lvI;
  1490. LV_COLUMNW lvC;
  1491. LPNMLISTVIEW pnmv;
  1492. WCHAR errorString[CRYPTUI_MAX_STRING_SIZE];
  1493. WCHAR errorTitle[CRYPTUI_MAX_STRING_SIZE];
  1494. DWORD dw;
  1495. int i;
  1496. void *pTemp;
  1497. PCERT_SETPROPERTIES_HELPER pviewhelp;
  1498. PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW pcsp = NULL;
  1499. DWORD cb = 0;
  1500. BYTE *pb = NULL;
  1501. CROSS_CERT_DIST_POINTS_INFO *pCrossCertInfo = NULL;
  1502. CROSS_CERT_DIST_POINTS_INFO CrossCertInfo;
  1503. DWORD cbCrossCertInfo = 0;
  1504. LPWSTR pwszStringToAdd = NULL;
  1505. PCERT_ALT_NAME_INFO pAltNameInfo = NULL;
  1506. BOOL fChecked;
  1507. WCHAR wszText[CRYPTUI_MAX_STRING_SIZE];
  1508. DWORD dwNumUnits = 0;
  1509. LPWSTR pwszURL = NULL;
  1510. DWORD dwLength;
  1511. BOOL fTranslated;
  1512. PCERT_ALT_NAME_ENTRY rgAltEntry;
  1513. LONG_PTR PrevWndProc;
  1514. DWORD dwSecsPerUnit = 1;
  1515. HWND hwndControl=NULL;
  1516. int listIndex=0;
  1517. switch ( msg ) {
  1518. case WM_INITDIALOG:
  1519. //
  1520. // save the pviewhelp struct in DWL_USER so it can always be accessed
  1521. //
  1522. ps = (PROPSHEETPAGE *) lParam;
  1523. pviewhelp = (PCERT_SETPROPERTIES_HELPER) ps->lParam;
  1524. pcsp = (PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) pviewhelp->pcsp;
  1525. pccert = pcsp->pCertContext;
  1526. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR) pviewhelp);
  1527. pviewhelp->InWMInit = TRUE;
  1528. hWndListView = GetDlgItem(hwndDlg, IDC_URL_LIST);
  1529. SendDlgItemMessage(hwndDlg, IDC_NUMBEROFUNITS_EDIT, EM_LIMITTEXT, (WPARAM) 7, (LPARAM) 0);
  1530. SendDlgItemMessage(hwndDlg, IDC_NEWURL_EDIT, EM_LIMITTEXT, (WPARAM) 512, (LPARAM) 0);
  1531. //
  1532. // Initialize the combo box fields
  1533. //
  1534. LoadStringU(HinstDll, IDS_HOURS, wszText, ARRAYSIZE(wszText));
  1535. SendDlgItemMessageU(hwndDlg, IDC_UNITS_COMBO, CB_INSERTSTRING, 0, (LPARAM) wszText);
  1536. LoadStringU(HinstDll, IDS_DAYS, wszText, ARRAYSIZE(wszText));
  1537. SendDlgItemMessageU(hwndDlg, IDC_UNITS_COMBO, CB_INSERTSTRING, 1, (LPARAM) wszText);
  1538. SendDlgItemMessageU(hwndDlg, IDC_UNITS_COMBO, CB_SETCURSEL, 0, (LPARAM) NULL);
  1539. SetDlgItemTextU(hwndDlg, IDC_NUMBEROFUNITS_EDIT, L"0");
  1540. //
  1541. // Initialize the list view control
  1542. //
  1543. memset(&lvC, 0, sizeof(LV_COLUMNW));
  1544. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  1545. lvC.fmt = LVCFMT_LEFT;
  1546. lvC.cx = 150;
  1547. lvC.pszText = L"";
  1548. lvC.iSubItem=0;
  1549. if (ListView_InsertColumnU(GetDlgItem(hwndDlg, IDC_URL_LIST), 0, &lvC) == -1)
  1550. {
  1551. return FALSE;
  1552. }
  1553. //
  1554. // try to get the CERT_CROSS_CERT_DIST_POINTS_PROP_ID property for this cert
  1555. //
  1556. if (!CertGetCertificateContextProperty(
  1557. pccert,
  1558. CERT_CROSS_CERT_DIST_POINTS_PROP_ID,
  1559. NULL,
  1560. &cb))
  1561. {
  1562. //
  1563. // The property doesn't exist
  1564. //
  1565. SendDlgItemMessage(hwndDlg, IDC_CHECKFORNEWCERTS_CHECK, BM_SETCHECK, BST_UNCHECKED, 0);
  1566. EnableWindow(GetDlgItem(hwndDlg, IDC_NUMBEROFUNITS_EDIT), FALSE);
  1567. EnableWindow(GetDlgItem(hwndDlg, IDC_UNITS_COMBO), FALSE);
  1568. EnableWindow(GetDlgItem(hwndDlg, IDC_USE_DEFAULT_BUTTON), FALSE);
  1569. EnableWindow(GetDlgItem(hwndDlg, IDC_ADDURL_BUTTON), FALSE);
  1570. EnableWindow(GetDlgItem(hwndDlg, IDC_NEWURL_EDIT), FALSE);
  1571. EnableWindow(hWndListView, FALSE);
  1572. EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVEURL_BUTTON), FALSE);
  1573. pviewhelp->InWMInit = FALSE;
  1574. return TRUE;
  1575. }
  1576. else
  1577. {
  1578. SendDlgItemMessage(hwndDlg, IDC_CHECKFORNEWCERTS_CHECK, BM_SETCHECK, BST_CHECKED, 0);
  1579. EnableWindow(GetDlgItem(hwndDlg, IDC_NUMBEROFUNITS_EDIT), TRUE);
  1580. EnableWindow(GetDlgItem(hwndDlg, IDC_UNITS_COMBO), TRUE);
  1581. EnableWindow(GetDlgItem(hwndDlg, IDC_USE_DEFAULT_BUTTON), TRUE);
  1582. EnableWindow(GetDlgItem(hwndDlg, IDC_ADDURL_BUTTON), TRUE);
  1583. EnableWindow(GetDlgItem(hwndDlg, IDC_NEWURL_EDIT), TRUE);
  1584. EnableWindow(hWndListView, TRUE);
  1585. EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVEURL_BUTTON), FALSE);
  1586. }
  1587. if (NULL == (pb = (BYTE *) malloc(cb)))
  1588. {
  1589. return FALSE;
  1590. }
  1591. if (!CertGetCertificateContextProperty(
  1592. pccert,
  1593. CERT_CROSS_CERT_DIST_POINTS_PROP_ID,
  1594. pb,
  1595. &cb))
  1596. {
  1597. free(pb);
  1598. return FALSE;
  1599. }
  1600. if (!CryptDecodeObject(
  1601. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  1602. X509_CROSS_CERT_DIST_POINTS,
  1603. pb,
  1604. cb,
  1605. 0,
  1606. NULL,
  1607. &cbCrossCertInfo))
  1608. {
  1609. free(pb);
  1610. return FALSE;
  1611. }
  1612. if (NULL == (pCrossCertInfo =
  1613. (CROSS_CERT_DIST_POINTS_INFO *) malloc(cbCrossCertInfo)))
  1614. {
  1615. free(pb);
  1616. return FALSE;
  1617. }
  1618. if (!CryptDecodeObject(
  1619. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  1620. X509_CROSS_CERT_DIST_POINTS,
  1621. pb,
  1622. cb,
  1623. 0,
  1624. pCrossCertInfo,
  1625. &cbCrossCertInfo))
  1626. {
  1627. free(pb);
  1628. return FALSE;
  1629. }
  1630. free(pb);
  1631. //
  1632. // Initialize the sync time controls
  1633. //
  1634. if (pCrossCertInfo->dwSyncDeltaTime == 0)
  1635. {
  1636. pCrossCertInfo->dwSyncDeltaTime = XCERT_DEFAULT_SYNC_DELTA_TIME;
  1637. }
  1638. if ((pCrossCertInfo->dwSyncDeltaTime % 86400) == 0)
  1639. {
  1640. //
  1641. // Days
  1642. //
  1643. dwNumUnits = pCrossCertInfo->dwSyncDeltaTime / 86400;
  1644. SendDlgItemMessageU(
  1645. hwndDlg,
  1646. IDC_UNITS_COMBO,
  1647. CB_SETCURSEL,
  1648. 1,
  1649. (LPARAM) NULL);
  1650. }
  1651. else
  1652. {
  1653. //
  1654. // Hours
  1655. //
  1656. dwNumUnits = pCrossCertInfo->dwSyncDeltaTime / 3600;
  1657. //
  1658. // Force to 1 if exisiting value is less than 1 hour.
  1659. //
  1660. if (0 == dwNumUnits)
  1661. {
  1662. dwNumUnits = 1;
  1663. }
  1664. SendDlgItemMessageU(
  1665. hwndDlg,
  1666. IDC_UNITS_COMBO,
  1667. CB_SETCURSEL,
  1668. 0,
  1669. (LPARAM) NULL);
  1670. }
  1671. SetDlgItemInt(
  1672. hwndDlg,
  1673. IDC_NUMBEROFUNITS_EDIT,
  1674. dwNumUnits,
  1675. FALSE);
  1676. //
  1677. // Add each dist point to the list view
  1678. //
  1679. memset(&lvI, 0, sizeof(lvI));
  1680. lvI.mask = LVIF_TEXT | LVIF_PARAM;
  1681. for (lvI.iItem=0; lvI.iItem< (int)pCrossCertInfo->cDistPoint; lvI.iItem++)
  1682. {
  1683. pAltNameInfo = &(pCrossCertInfo->rgDistPoint[lvI.iItem]);
  1684. if ((pAltNameInfo->cAltEntry == 0) ||
  1685. (pAltNameInfo->rgAltEntry[0].dwAltNameChoice != 7))
  1686. {
  1687. continue;
  1688. }
  1689. pwszURL = (LPWSTR)
  1690. malloc( (wcslen(pAltNameInfo->rgAltEntry[0].pwszURL) + 1) *
  1691. sizeof(WCHAR));
  1692. if (pwszURL == NULL)
  1693. {
  1694. continue;
  1695. }
  1696. wcscpy(pwszURL, pAltNameInfo->rgAltEntry[0].pwszURL);
  1697. lvI.pszText = pwszURL;
  1698. lvI.lParam = (LPARAM) pwszURL;
  1699. ListView_InsertItemU(hWndListView, &lvI);
  1700. }
  1701. ListView_SetColumnWidth(hWndListView, 0, LVSCW_AUTOSIZE);
  1702. ListView_SetColumnWidth(hWndListView, 1, LVSCW_AUTOSIZE);
  1703. free(pCrossCertInfo);
  1704. pviewhelp->InWMInit = FALSE;
  1705. return TRUE;
  1706. case WM_NOTIFY:
  1707. pviewhelp = (PCERT_SETPROPERTIES_HELPER) GetWindowLongPtr(hwndDlg, DWLP_USER);
  1708. pcsp = (PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) pviewhelp->pcsp;
  1709. pccert = pcsp->pCertContext;
  1710. switch (((NMHDR FAR *) lParam)->code) {
  1711. case PSN_SETACTIVE:
  1712. break;
  1713. case PSN_APPLY:
  1714. hWndListView = GetDlgItem(hwndDlg, IDC_URL_LIST);
  1715. if (BST_CHECKED != SendDlgItemMessage(
  1716. hwndDlg,
  1717. IDC_CHECKFORNEWCERTS_CHECK,
  1718. BM_GETCHECK,
  1719. 0,
  1720. 0))
  1721. {
  1722. CertSetCertificateContextProperty(
  1723. pccert,
  1724. CERT_CROSS_CERT_DIST_POINTS_PROP_ID,
  1725. 0,
  1726. NULL);
  1727. }
  1728. else
  1729. {
  1730. //
  1731. // Set the sync time
  1732. //
  1733. memset(&CrossCertInfo, 0, sizeof(CrossCertInfo));
  1734. dwNumUnits = GetDlgItemInt(
  1735. hwndDlg,
  1736. IDC_NUMBEROFUNITS_EDIT,
  1737. &fTranslated,
  1738. FALSE);
  1739. if (0 == SendDlgItemMessage(hwndDlg, IDC_UNITS_COMBO, CB_GETCURSEL, 0, NULL))
  1740. {
  1741. dwSecsPerUnit = 3600;
  1742. }
  1743. else
  1744. {
  1745. dwSecsPerUnit = 86400;
  1746. }
  1747. CrossCertInfo.dwSyncDeltaTime = dwNumUnits * dwSecsPerUnit;
  1748. //
  1749. // Set the dist points
  1750. //
  1751. CrossCertInfo.cDistPoint = ListView_GetItemCount(hWndListView);
  1752. CrossCertInfo.rgDistPoint = (CERT_ALT_NAME_INFO *)
  1753. malloc( CrossCertInfo.cDistPoint *
  1754. sizeof(CERT_ALT_NAME_INFO));
  1755. if (CrossCertInfo.rgDistPoint == NULL)
  1756. {
  1757. break;
  1758. }
  1759. // one AltEntry per DistPoint
  1760. rgAltEntry = (CERT_ALT_NAME_ENTRY *)
  1761. malloc(CrossCertInfo.cDistPoint * sizeof(CERT_ALT_NAME_ENTRY));
  1762. if (rgAltEntry == NULL)
  1763. {
  1764. free(CrossCertInfo.rgDistPoint);
  1765. break;
  1766. }
  1767. memset(&lvI, 0, sizeof(lvI));
  1768. lvI.mask = LVIF_PARAM;
  1769. for (dw=0; dw<CrossCertInfo.cDistPoint; dw++)
  1770. {
  1771. lvI.iItem = dw;
  1772. if (ListView_GetItemU(hWndListView, &lvI))
  1773. {
  1774. CrossCertInfo.rgDistPoint[dw].cAltEntry = 1;
  1775. CrossCertInfo.rgDistPoint[dw].rgAltEntry = &(rgAltEntry[dw]);
  1776. rgAltEntry[dw].dwAltNameChoice = 7;
  1777. rgAltEntry[dw].pwszURL = (LPWSTR) lvI.lParam;
  1778. }
  1779. }
  1780. //
  1781. // Now encode
  1782. //
  1783. CryptDataBlob.cbData = 0;
  1784. CryptDataBlob.pbData = NULL;
  1785. if (CryptEncodeObject(
  1786. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  1787. X509_CROSS_CERT_DIST_POINTS,
  1788. &CrossCertInfo,
  1789. NULL,
  1790. &CryptDataBlob.cbData))
  1791. {
  1792. if (NULL != (CryptDataBlob.pbData = (BYTE *)
  1793. malloc(CryptDataBlob.cbData)))
  1794. {
  1795. if (CryptEncodeObject(
  1796. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  1797. X509_CROSS_CERT_DIST_POINTS,
  1798. &CrossCertInfo,
  1799. CryptDataBlob.pbData,
  1800. &CryptDataBlob.cbData))
  1801. {
  1802. CertSetCertificateContextProperty(
  1803. pccert,
  1804. CERT_CROSS_CERT_DIST_POINTS_PROP_ID,
  1805. 0,
  1806. &CryptDataBlob);
  1807. }
  1808. free(CryptDataBlob.pbData);
  1809. }
  1810. }
  1811. free(rgAltEntry);
  1812. free(CrossCertInfo.rgDistPoint);
  1813. }
  1814. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)TRUE);
  1815. break;
  1816. case PSN_KILLACTIVE:
  1817. //
  1818. // DSIE: Bug 124468. Per PM JohnLa, we don't make any check until user applies.
  1819. //
  1820. if (BST_CHECKED == SendDlgItemMessage(hwndDlg,
  1821. IDC_CHECKFORNEWCERTS_CHECK,
  1822. BM_GETCHECK,
  1823. 0,
  1824. 0))
  1825. {
  1826. //
  1827. // Check the sync time
  1828. //
  1829. dwNumUnits = GetDlgItemInt(
  1830. hwndDlg,
  1831. IDC_NUMBEROFUNITS_EDIT,
  1832. &fTranslated,
  1833. FALSE);
  1834. if (0 == SendDlgItemMessage(hwndDlg, IDC_UNITS_COMBO, CB_GETCURSEL, 0, NULL))
  1835. {
  1836. dwSecsPerUnit = 3600;
  1837. }
  1838. else
  1839. {
  1840. dwSecsPerUnit = 86400;
  1841. }
  1842. if (!fTranslated || 0 == dwNumUnits || dwNumUnits > (MAX_DWORD_SIZE / dwSecsPerUnit))
  1843. {
  1844. WCHAR * pwszMessage = NULL;
  1845. DWORD dwMaxInterval = MAX_DWORD_SIZE / dwSecsPerUnit;
  1846. if (pwszMessage = FormatMessageUnicodeIds(IDS_INVALID_XCERT_INTERVAL, dwMaxInterval))
  1847. {
  1848. WCHAR wszTitle[CRYPTUI_MAX_STRING_SIZE] = L"";
  1849. LoadStringU(HinstDll, IDS_CERTIFICATE_PROPERTIES, wszTitle, ARRAYSIZE(wszTitle));
  1850. MessageBoxU(hwndDlg, pwszMessage, wszTitle, MB_OK | MB_ICONWARNING);
  1851. LocalFree((HLOCAL) pwszMessage);
  1852. }
  1853. SetFocus(GetDlgItem(hwndDlg, IDC_NUMBEROFUNITS_EDIT));
  1854. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT) TRUE);
  1855. return TRUE;
  1856. }
  1857. }
  1858. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)FALSE);
  1859. return TRUE;
  1860. case PSN_RESET:
  1861. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)FALSE);
  1862. break;
  1863. case PSN_QUERYCANCEL:
  1864. pviewhelp->fCancelled = TRUE;
  1865. return FALSE;
  1866. case PSN_HELP:
  1867. if (FIsWin95) {
  1868. //WinHelpA(hwndDlg, (LPSTR) pcsp->szHelpFileName,
  1869. // HELP_CONTEXT, pcsp->dwHelpId);
  1870. }
  1871. else {
  1872. // WinHelpW(hwndDlg, pcsp->szHelpFileName, HELP_CONTEXT,
  1873. // pcsp->dwHelpId);
  1874. }
  1875. return TRUE;
  1876. case LVN_ITEMCHANGED:
  1877. EnableWindow(
  1878. GetDlgItem(hwndDlg, IDC_REMOVEURL_BUTTON),
  1879. (ListView_GetSelectedCount(
  1880. GetDlgItem(hwndDlg,IDC_URL_LIST)) == 0) ? FALSE : TRUE);
  1881. return TRUE;
  1882. #if (1) //DSIE: bug 283659.
  1883. case NM_SETFOCUS:
  1884. //get the window handle of the url list view
  1885. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_URL_LIST)))
  1886. break;
  1887. //get the selected cert
  1888. listIndex = ListView_GetNextItem(
  1889. hwndControl,
  1890. -1,
  1891. LVNI_FOCUSED
  1892. );
  1893. //select first item to show hilite.
  1894. if (listIndex == -1)
  1895. ListView_SetItemState(hwndControl,
  1896. 0,
  1897. LVIS_FOCUSED | LVIS_SELECTED,
  1898. LVIS_FOCUSED | LVIS_SELECTED);
  1899. return TRUE;
  1900. #endif
  1901. }
  1902. break;
  1903. case WM_COMMAND:
  1904. pviewhelp = (PCERT_SETPROPERTIES_HELPER) GetWindowLongPtr(hwndDlg, DWLP_USER);
  1905. pcsp = (PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) pviewhelp->pcsp;
  1906. pccert = pcsp->pCertContext;
  1907. switch (LOWORD(wParam))
  1908. {
  1909. case IDHELP:
  1910. return TRUE;
  1911. case IDC_CHECKFORNEWCERTS_CHECK:
  1912. if (HIWORD(wParam) == BN_CLICKED)
  1913. {
  1914. //
  1915. // Get current state of check, then enable/disable all
  1916. // controls accordingly
  1917. //
  1918. fChecked = (BST_CHECKED == SendDlgItemMessage(
  1919. hwndDlg,
  1920. IDC_CHECKFORNEWCERTS_CHECK,
  1921. BM_GETCHECK,
  1922. 0,
  1923. 0));
  1924. EnableWindow(GetDlgItem(hwndDlg, IDC_NUMBEROFUNITS_EDIT), fChecked);
  1925. EnableWindow(GetDlgItem(hwndDlg, IDC_UNITS_COMBO), fChecked);
  1926. EnableWindow(GetDlgItem(hwndDlg, IDC_USE_DEFAULT_BUTTON), fChecked);
  1927. EnableWindow(GetDlgItem(hwndDlg, IDC_ADDURL_BUTTON), fChecked);
  1928. EnableWindow(GetDlgItem(hwndDlg, IDC_NEWURL_EDIT), fChecked);
  1929. EnableWindow(GetDlgItem(hwndDlg, IDC_URL_LIST), fChecked);
  1930. if (fChecked)
  1931. {
  1932. //
  1933. // DSIE: Bug 124669.
  1934. //
  1935. dwNumUnits = GetDlgItemInt(
  1936. hwndDlg,
  1937. IDC_NUMBEROFUNITS_EDIT,
  1938. &fTranslated,
  1939. FALSE);
  1940. if (0 == dwNumUnits)
  1941. {
  1942. SendDlgItemMessageU(
  1943. hwndDlg,
  1944. IDC_UNITS_COMBO,
  1945. CB_SETCURSEL,
  1946. 0,
  1947. (LPARAM) NULL);
  1948. SetDlgItemInt(
  1949. hwndDlg,
  1950. IDC_NUMBEROFUNITS_EDIT,
  1951. XCERT_DEFAULT_DELTA_HOURS,
  1952. FALSE);
  1953. }
  1954. EnableWindow(
  1955. GetDlgItem(hwndDlg, IDC_REMOVEURL_BUTTON),
  1956. (ListView_GetSelectedCount(
  1957. GetDlgItem(hwndDlg,IDC_URL_LIST)) == 0) ? FALSE : TRUE);
  1958. }
  1959. else
  1960. {
  1961. EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVEURL_BUTTON), FALSE);
  1962. }
  1963. if (pviewhelp->pfPropertiesChanged != NULL)
  1964. {
  1965. *(pviewhelp->pfPropertiesChanged) = TRUE;
  1966. }
  1967. pviewhelp->fPropertiesChanged = TRUE;
  1968. PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
  1969. }
  1970. break;
  1971. case IDC_USE_DEFAULT_BUTTON:
  1972. if (HIWORD(wParam) == BN_CLICKED)
  1973. {
  1974. //
  1975. // Reset to default interval.
  1976. //
  1977. SendDlgItemMessageU(
  1978. hwndDlg,
  1979. IDC_UNITS_COMBO,
  1980. CB_SETCURSEL,
  1981. 0,
  1982. (LPARAM) NULL);
  1983. SetDlgItemInt(
  1984. hwndDlg,
  1985. IDC_NUMBEROFUNITS_EDIT,
  1986. XCERT_DEFAULT_DELTA_HOURS,
  1987. FALSE);
  1988. }
  1989. break;
  1990. case IDC_ADDURL_BUTTON:
  1991. if (HIWORD(wParam) == BN_CLICKED)
  1992. {
  1993. hWndListView = GetDlgItem(hwndDlg, IDC_URL_LIST);
  1994. dwLength = (DWORD) SendDlgItemMessage(
  1995. hwndDlg,
  1996. IDC_NEWURL_EDIT,
  1997. WM_GETTEXTLENGTH,
  1998. 0,
  1999. NULL);
  2000. if (dwLength == 0)
  2001. {
  2002. break;
  2003. }
  2004. pwszURL = (LPWSTR) malloc((dwLength + 1) * sizeof(WCHAR));
  2005. if (pwszURL == NULL)
  2006. {
  2007. break;
  2008. }
  2009. GetDlgItemTextU(
  2010. hwndDlg,
  2011. IDC_NEWURL_EDIT,
  2012. pwszURL,
  2013. dwLength + 1);
  2014. pwszURL[dwLength] = '\0';
  2015. if (!IsValidURL(pwszURL))
  2016. {
  2017. free(pwszURL);
  2018. LoadStringU(HinstDll, IDS_INVALID_URL_ERROR, errorString, ARRAYSIZE(errorString));
  2019. LoadStringU(HinstDll, IDS_CERTIFICATE_PROPERTIES, errorTitle, ARRAYSIZE(errorTitle));
  2020. MessageBoxU(hwndDlg, errorString, errorTitle, MB_OK | MB_ICONWARNING);
  2021. break;
  2022. }
  2023. memset(&lvI, 0, sizeof(lvI));
  2024. lvI.mask = LVIF_TEXT | LVIF_PARAM;
  2025. lvI.iItem = ListView_GetItemCount(hWndListView);
  2026. lvI.pszText = pwszURL;
  2027. lvI.lParam = (LPARAM) pwszURL;
  2028. ListView_InsertItemU(hWndListView, &lvI);
  2029. ListView_SetColumnWidth(hWndListView, 0, LVSCW_AUTOSIZE);
  2030. ListView_SetColumnWidth(hWndListView, 1, LVSCW_AUTOSIZE);
  2031. SetDlgItemTextU(hwndDlg, IDC_NEWURL_EDIT, L"");
  2032. if (pviewhelp->pfPropertiesChanged != NULL)
  2033. {
  2034. *(pviewhelp->pfPropertiesChanged) = TRUE;
  2035. }
  2036. pviewhelp->fPropertiesChanged = TRUE;
  2037. PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
  2038. }
  2039. break;
  2040. case IDC_REMOVEURL_BUTTON:
  2041. hWndListView = GetDlgItem(hwndDlg, IDC_URL_LIST);
  2042. memset(&lvI, 0, sizeof(lvI));
  2043. lvI.mask = LVIF_STATE | LVIF_PARAM;
  2044. lvI.stateMask = LVIS_SELECTED;
  2045. for (i=(ListView_GetItemCount(hWndListView) - 1); i >=0; i--)
  2046. {
  2047. lvI.iItem = i;
  2048. if (ListView_GetItemU(hWndListView, &lvI) &&
  2049. (lvI.state & LVIS_SELECTED))
  2050. {
  2051. free((void *) lvI.lParam);
  2052. ListView_DeleteItem(hWndListView, i);
  2053. }
  2054. }
  2055. ListView_SetColumnWidth(hWndListView, 0, LVSCW_AUTOSIZE);
  2056. ListView_SetColumnWidth(hWndListView, 1, LVSCW_AUTOSIZE);
  2057. if (pviewhelp->pfPropertiesChanged != NULL)
  2058. {
  2059. *(pviewhelp->pfPropertiesChanged) = TRUE;
  2060. }
  2061. pviewhelp->fPropertiesChanged = TRUE;
  2062. PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
  2063. #if (1) //DSIE: bug 313918.
  2064. if (0 == ListView_GetItemCount(hWndListView))
  2065. {
  2066. SetFocus(GetDlgItem(GetParent(hwndDlg), IDOK));
  2067. }
  2068. else
  2069. {
  2070. //get the selected cert
  2071. listIndex = ListView_GetNextItem(
  2072. hWndListView,
  2073. -1,
  2074. LVNI_FOCUSED
  2075. );
  2076. //select first item to show hilite.
  2077. if (listIndex == -1)
  2078. listIndex = 0;
  2079. ListView_SetItemState(hWndListView,
  2080. listIndex,
  2081. LVIS_FOCUSED | LVIS_SELECTED,
  2082. LVIS_FOCUSED | LVIS_SELECTED);
  2083. }
  2084. #endif
  2085. break;
  2086. case IDC_UNITS_COMBO:
  2087. if (HIWORD(wParam) == CBN_SELCHANGE)
  2088. {
  2089. if (!pviewhelp->InWMInit)
  2090. {
  2091. dwNumUnits = GetDlgItemInt(
  2092. hwndDlg,
  2093. IDC_NUMBEROFUNITS_EDIT,
  2094. &fTranslated,
  2095. FALSE);
  2096. if (0 == SendDlgItemMessage(hwndDlg, IDC_UNITS_COMBO, CB_GETCURSEL, 0, NULL))
  2097. {
  2098. dwSecsPerUnit = 3600;
  2099. }
  2100. else
  2101. {
  2102. dwSecsPerUnit = 86400;
  2103. }
  2104. if (dwNumUnits > (MAX_DWORD_SIZE / dwSecsPerUnit))
  2105. {
  2106. SetDlgItemInt(
  2107. hwndDlg,
  2108. IDC_NUMBEROFUNITS_EDIT,
  2109. (DWORD) (MAX_DWORD_SIZE / dwSecsPerUnit),
  2110. FALSE);
  2111. }
  2112. PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
  2113. }
  2114. }
  2115. break;
  2116. case IDC_NUMBEROFUNITS_EDIT:
  2117. if (HIWORD(wParam) == EN_CHANGE)
  2118. {
  2119. if (!pviewhelp->InWMInit)
  2120. {
  2121. PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
  2122. }
  2123. }
  2124. break;
  2125. }
  2126. break;
  2127. case WM_DESTROY:
  2128. pviewhelp = (PCERT_SETPROPERTIES_HELPER) GetWindowLongPtr(hwndDlg, DWLP_USER);
  2129. pcsp = (PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) pviewhelp->pcsp;
  2130. pccert = pcsp->pCertContext;
  2131. hWndListView = GetDlgItem(hwndDlg, IDC_URL_LIST);
  2132. memset(&lvI, 0, sizeof(lvI));
  2133. lvI.mask = LVIF_PARAM;
  2134. for (i=(ListView_GetItemCount(hWndListView) - 1); i >=0; i--)
  2135. {
  2136. lvI.iItem = i;
  2137. if (ListView_GetItemU(hWndListView, &lvI))
  2138. {
  2139. free((void *) lvI.lParam);
  2140. }
  2141. }
  2142. //
  2143. // if the properties have changed, and there is a pMMCCallback
  2144. // then make the callback to MMC
  2145. //
  2146. if (pviewhelp->fPropertiesChanged &&
  2147. pviewhelp->fGetPagesCalled &&
  2148. (pviewhelp->pcsp->pMMCCallback != NULL) &&
  2149. (pviewhelp->fMMCCallbackMade != TRUE))
  2150. {
  2151. pviewhelp->fMMCCallbackMade = TRUE;
  2152. (*(pviewhelp->pcsp->pMMCCallback->pfnCallback))(
  2153. pviewhelp->pcsp->pMMCCallback->lNotifyHandle,
  2154. pviewhelp->pcsp->pMMCCallback->param);
  2155. }
  2156. break;
  2157. case WM_HELP:
  2158. case WM_CONTEXTMENU:
  2159. if (msg == WM_HELP)
  2160. {
  2161. hwnd = GetDlgItem(hwndDlg, ((LPHELPINFO)lParam)->iCtrlId);
  2162. }
  2163. else
  2164. {
  2165. hwnd = (HWND) wParam;
  2166. }
  2167. if ((hwnd != GetDlgItem(hwndDlg, IDC_CHECKFORNEWCERTS_CHECK)) &&
  2168. (hwnd != GetDlgItem(hwndDlg, IDC_NUMBEROFUNITS_EDIT)) &&
  2169. (hwnd != GetDlgItem(hwndDlg, IDC_UNITS_COMBO)) &&
  2170. (hwnd != GetDlgItem(hwndDlg, IDC_USE_DEFAULT_BUTTON)) &&
  2171. (hwnd != GetDlgItem(hwndDlg, IDC_ADDURL_BUTTON)) &&
  2172. (hwnd != GetDlgItem(hwndDlg, IDC_NEWURL_EDIT)) &&
  2173. (hwnd != GetDlgItem(hwndDlg, IDC_URL_LIST)) &&
  2174. (hwnd != GetDlgItem(hwndDlg, IDC_REMOVEURL_BUTTON)))
  2175. {
  2176. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)TRUE);
  2177. return TRUE;
  2178. }
  2179. else
  2180. {
  2181. return OnContextHelp(hwndDlg, msg, wParam, lParam, helpmapCrossCert);
  2182. }
  2183. break;
  2184. }
  2185. return FALSE;
  2186. }
  2187. //////////////////////////////////////////////////////////////////////////////////////
  2188. //
  2189. //////////////////////////////////////////////////////////////////////////////////////
  2190. BOOL GetRegisteredClientPages(PROPSHEETPAGEW **ppClientPages, DWORD *pcClientPages, PCCERT_CONTEXT pCertContext)
  2191. {
  2192. HCRYPTOIDFUNCSET hCertPropPagesFuncSet;
  2193. void * pvFuncAddr = NULL;
  2194. HCRYPTOIDFUNCADDR hFuncAddr = NULL;
  2195. PROPSHEETPAGEW callbackPages[MAX_CLIENT_PAGES];
  2196. DWORD cCallbackPages = MAX_CLIENT_PAGES;
  2197. DWORD cChars = 0;
  2198. LPWSTR pwszDllNames = NULL;
  2199. BOOL fRet = TRUE;
  2200. LPWSTR pwszCurrentDll;
  2201. DWORD i;
  2202. void *pTemp;
  2203. //
  2204. // initialize incoming variables
  2205. //
  2206. *ppClientPages = NULL;
  2207. *pcClientPages = 0;
  2208. //
  2209. // get a handle to the function table
  2210. //
  2211. if (NULL == (hCertPropPagesFuncSet = CryptInitOIDFunctionSet(
  2212. CRYPTUILDLG_CERTPROP_PAGES_CALLBACK, 0)))
  2213. {
  2214. goto ErrorReturn;
  2215. }
  2216. //
  2217. // get the list of dlls that contain the callback functions
  2218. //
  2219. if (!CryptGetDefaultOIDDllList(
  2220. hCertPropPagesFuncSet,
  2221. 0,
  2222. NULL,
  2223. &cChars))
  2224. {
  2225. goto ErrorReturn;
  2226. }
  2227. if (NULL == (pwszDllNames = (LPWSTR) malloc(cChars * sizeof(WCHAR))))
  2228. {
  2229. SetLastError(E_OUTOFMEMORY);
  2230. goto ErrorReturn;
  2231. }
  2232. if (!CryptGetDefaultOIDDllList(
  2233. hCertPropPagesFuncSet,
  2234. 0,
  2235. pwszDllNames,
  2236. &cChars))
  2237. {
  2238. goto ErrorReturn;
  2239. }
  2240. //
  2241. // loop for each dll and call it to see if it has property pages for this cert
  2242. //
  2243. pwszCurrentDll = pwszDllNames;
  2244. while (pwszCurrentDll[0] != L'\0')
  2245. {
  2246. //
  2247. // try to get the function pointer
  2248. //
  2249. if (!CryptGetDefaultOIDFunctionAddress(
  2250. hCertPropPagesFuncSet,
  2251. 0,
  2252. pwszCurrentDll,
  2253. 0,
  2254. &pvFuncAddr,
  2255. &hFuncAddr))
  2256. {
  2257. DWORD dwErr = GetLastError();
  2258. pwszCurrentDll += wcslen(pwszCurrentDll) + 1;
  2259. continue;
  2260. }
  2261. //
  2262. // call the client to get the their pages
  2263. //
  2264. cCallbackPages = MAX_CLIENT_PAGES;
  2265. memset(callbackPages, 0, sizeof(callbackPages));
  2266. if (((PFN_CRYPTUIDLG_CERTPROP_PAGES_CALLBACK) pvFuncAddr)(pCertContext, callbackPages, &cCallbackPages))
  2267. {
  2268. //
  2269. // if they handed back pages then add them to the array
  2270. //
  2271. if (cCallbackPages >= 1)
  2272. {
  2273. if (*ppClientPages == NULL)
  2274. {
  2275. if (NULL == (*ppClientPages = (PROPSHEETPAGEW *) malloc(cCallbackPages * sizeof(PROPSHEETPAGEW))))
  2276. {
  2277. SetLastError(E_OUTOFMEMORY);
  2278. goto ErrorReturn;
  2279. }
  2280. }
  2281. else
  2282. {
  2283. if (NULL == (pTemp = realloc(*ppClientPages, (cCallbackPages + (*pcClientPages)) * sizeof(PROPSHEETPAGEW))))
  2284. {
  2285. SetLastError(E_OUTOFMEMORY);
  2286. goto ErrorReturn;
  2287. }
  2288. *ppClientPages = (PROPSHEETPAGEW *) pTemp;
  2289. }
  2290. memcpy(&((*ppClientPages)[(*pcClientPages)]), &(callbackPages[0]), cCallbackPages * sizeof(PROPSHEETPAGEW));
  2291. *pcClientPages += cCallbackPages;
  2292. }
  2293. }
  2294. //
  2295. // free the function that was just called, and move on to the next one in the string
  2296. //
  2297. CryptFreeOIDFunctionAddress(hFuncAddr, 0);
  2298. hFuncAddr = NULL;
  2299. pwszCurrentDll += wcslen(pwszCurrentDll) + 1;
  2300. }
  2301. CleanUp:
  2302. if (pwszDllNames != NULL)
  2303. {
  2304. free(pwszDllNames);
  2305. }
  2306. if (hFuncAddr != NULL)
  2307. {
  2308. CryptFreeOIDFunctionAddress(hFuncAddr, 0);
  2309. }
  2310. return fRet;
  2311. ErrorReturn:
  2312. fRet = FALSE;
  2313. goto CleanUp;
  2314. }
  2315. //////////////////////////////////////////////////////////////////////////////////////
  2316. // CertSetCertificateProperties
  2317. //
  2318. // Description:
  2319. // This routine will display and allow the user to edit certain properties of
  2320. // a certificate
  2321. //
  2322. //
  2323. //////////////////////////////////////////////////////////////////////////////////////
  2324. BOOL WINAPI CryptUIDlgViewCertificatePropertiesW(PCCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW pcsp,
  2325. BOOL *pfPropertiesChanged)
  2326. {
  2327. int cPages = 2;
  2328. BOOL fRetValue = FALSE;
  2329. HRESULT hr;
  2330. PROPSHEETPAGEW * ppage = NULL;
  2331. PROPSHEETPAGEW * pClientPages = NULL;
  2332. DWORD cClientPages = 0;
  2333. INT_PTR ret;
  2334. WCHAR rgwch[256];
  2335. char rgch[256];
  2336. CERT_SETPROPERTIES_HELPER viewhelper;
  2337. if (pcsp->dwSize != sizeof(CRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW)) {
  2338. SetLastError(E_INVALIDARG);
  2339. return FALSE;
  2340. }
  2341. if (!CommonInit())
  2342. {
  2343. return FALSE;
  2344. }
  2345. //
  2346. // initialize the helper struct
  2347. //
  2348. memset (&viewhelper, 0, sizeof(viewhelper));
  2349. viewhelper.pcsp = pcsp;
  2350. viewhelper.fSelfCleanup = FALSE;
  2351. viewhelper.pfPropertiesChanged = pfPropertiesChanged;
  2352. viewhelper.fGetPagesCalled = FALSE;
  2353. viewhelper.fMMCCallbackMade = FALSE;
  2354. //
  2355. // set the properties changed flag to FALSE initially, it will be set
  2356. // to TRUE if when the dialog exits anything has been changed
  2357. //
  2358. viewhelper.fPropertiesChanged = FALSE;
  2359. if (viewhelper.pfPropertiesChanged != NULL)
  2360. {
  2361. *(viewhelper.pfPropertiesChanged) = FALSE;
  2362. }
  2363. //
  2364. // get all the pages from registered clients
  2365. //
  2366. if (!GetRegisteredClientPages(&pClientPages, &cClientPages, pcsp->pCertContext))
  2367. {
  2368. return FALSE;
  2369. }
  2370. //
  2371. // Build up the list of pages we are going to use in the dialog
  2372. //
  2373. ppage = (PROPSHEETPAGEW *) malloc((cPages + pcsp->cPropSheetPages + cClientPages) * sizeof(PROPSHEETPAGEW));
  2374. if (ppage == NULL) {
  2375. goto Exit;
  2376. }
  2377. memset(ppage, 0, (cPages + pcsp->cPropSheetPages + cClientPages) * sizeof(PROPSHEETPAGEW));
  2378. ppage[0].dwSize = sizeof(ppage[0]);
  2379. ppage[0].dwFlags = 0;
  2380. ppage[0].hInstance = HinstDll;
  2381. ppage[0].pszTemplate = (LPWSTR) MAKEINTRESOURCE(IDD_CERTIFICATE_PROPERTIES_DIALOG);
  2382. ppage[0].hIcon = 0;
  2383. ppage[0].pszTitle = NULL;
  2384. ppage[0].pfnDlgProc = ViewPageSetPropertiesGeneral;
  2385. ppage[0].lParam = (LPARAM) &viewhelper;
  2386. ppage[0].pfnCallback = 0;
  2387. ppage[0].pcRefParent = NULL;
  2388. ppage[1].dwSize = sizeof(ppage[0]);
  2389. ppage[1].dwFlags = 0;
  2390. ppage[1].hInstance = HinstDll;
  2391. ppage[1].pszTemplate = (LPWSTR) MAKEINTRESOURCE(IDD_CERTIFICATE_PROPERTIES_CROSSCERTS_DIALOG);
  2392. ppage[1].hIcon = 0;
  2393. ppage[1].pszTitle = NULL;
  2394. ppage[1].pfnDlgProc = ViewPageSetPropertiesCrossCerts;
  2395. ppage[1].lParam = (LPARAM) &viewhelper;
  2396. ppage[1].pfnCallback = 0;
  2397. ppage[1].pcRefParent = NULL;
  2398. //
  2399. // copy over the users pages
  2400. //
  2401. memcpy(&ppage[cPages], pcsp->rgPropSheetPages, pcsp->cPropSheetPages * sizeof(PROPSHEETPAGEW));
  2402. cPages += pcsp->cPropSheetPages;
  2403. //
  2404. // copy over the registered client's pages
  2405. //
  2406. memcpy(&ppage[cPages], pClientPages, cClientPages * sizeof(PROPSHEETPAGEW));
  2407. cPages += cClientPages;
  2408. if (FIsWin95) {
  2409. PROPSHEETHEADERA hdr;
  2410. memset(&hdr, 0, sizeof(hdr));
  2411. hdr.dwSize = sizeof(hdr);
  2412. hdr.dwFlags = PSH_PROPSHEETPAGE;// | PSH_NOAPPLYNOW;
  2413. hdr.hwndParent = (pcsp->hwndParent != NULL) ? pcsp->hwndParent : GetDesktopWindow();
  2414. hdr.hInstance = HinstDll;
  2415. hdr.hIcon = NULL;
  2416. if (pcsp->szTitle != NULL)
  2417. {
  2418. hdr.pszCaption = CertUIMkMBStr(pcsp->szTitle);
  2419. }
  2420. else
  2421. {
  2422. LoadStringA(HinstDll, IDS_CERTIFICATE_PROPERTIES, (LPSTR) rgch, sizeof(rgch));
  2423. hdr.pszCaption = (LPSTR) rgch;
  2424. }
  2425. hdr.nPages = cPages;
  2426. hdr.nStartPage = 0;
  2427. hdr.ppsp = ConvertToPropPageA(ppage, cPages);
  2428. if (hdr.ppsp == NULL)
  2429. {
  2430. if ((pcsp->szTitle != NULL) && (hdr.pszCaption != NULL))
  2431. {
  2432. free((void *)hdr.pszCaption);
  2433. }
  2434. goto Exit;
  2435. }
  2436. hdr.pfnCallback = NULL;
  2437. ret = CryptUIPropertySheetA(&hdr);
  2438. if ((pcsp->szTitle != NULL) && (hdr.pszCaption != NULL))
  2439. {
  2440. free((void *)hdr.pszCaption);
  2441. }
  2442. FreePropSheetPagesA((PROPSHEETPAGEA *)hdr.ppsp, cPages);
  2443. }
  2444. else {
  2445. PROPSHEETHEADERW hdr;
  2446. memset(&hdr, 0, sizeof(hdr));
  2447. hdr.dwSize = sizeof(hdr);
  2448. hdr.dwFlags = PSH_PROPSHEETPAGE;// | PSH_NOAPPLYNOW;
  2449. hdr.hwndParent = (pcsp->hwndParent != NULL) ? pcsp->hwndParent : GetDesktopWindow();
  2450. hdr.hInstance = HinstDll;
  2451. hdr.hIcon = NULL;
  2452. if (pcsp->szTitle)
  2453. {
  2454. hdr.pszCaption = pcsp->szTitle;
  2455. }
  2456. else
  2457. {
  2458. LoadStringW(HinstDll, IDS_CERTIFICATE_PROPERTIES, rgwch, ARRAYSIZE(rgwch));
  2459. hdr.pszCaption = rgwch;
  2460. }
  2461. hdr.nPages = cPages;
  2462. hdr.nStartPage = 0;
  2463. hdr.ppsp = (PROPSHEETPAGEW *) ppage;
  2464. hdr.pfnCallback = NULL;
  2465. ret = CryptUIPropertySheetW(&hdr);
  2466. }
  2467. if (viewhelper.fCancelled)
  2468. {
  2469. SetLastError(ERROR_CANCELLED);
  2470. }
  2471. fRetValue = (ret >= 1);
  2472. Exit:
  2473. if (pClientPages)
  2474. free(pClientPages);
  2475. if (ppage)
  2476. free(ppage);
  2477. return fRetValue;
  2478. }
  2479. //////////////////////////////////////////////////////////////////////////////////////
  2480. //
  2481. //////////////////////////////////////////////////////////////////////////////////////
  2482. BOOL WINAPI CryptUIDlgViewCertificatePropertiesA(PCCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTA pcsp,
  2483. BOOL *pfPropertiesChanged)
  2484. {
  2485. BOOL fRet;
  2486. CRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW cspW;
  2487. memcpy(&cspW, pcsp, sizeof(cspW));
  2488. if (!ConvertToPropPageW(
  2489. pcsp->rgPropSheetPages,
  2490. pcsp->cPropSheetPages,
  2491. &(cspW.rgPropSheetPages)))
  2492. {
  2493. return FALSE;
  2494. }
  2495. cspW.szTitle = CertUIMkWStr(pcsp->szTitle);
  2496. fRet = CryptUIDlgViewCertificatePropertiesW(&cspW, pfPropertiesChanged);
  2497. if (cspW.szTitle)
  2498. free((void *)cspW.szTitle);
  2499. //DSIE: Prefix bug 428038.
  2500. if (cspW.rgPropSheetPages)
  2501. {
  2502. FreePropSheetPagesW((LPPROPSHEETPAGEW) cspW.rgPropSheetPages, cspW.cPropSheetPages);
  2503. }
  2504. return fRet;
  2505. }
  2506. //////////////////////////////////////////////////////////////////////////////////////
  2507. //
  2508. //////////////////////////////////////////////////////////////////////////////////////
  2509. UINT
  2510. CALLBACK
  2511. GetCertificatePropertiesPagesPropPageCallback(
  2512. HWND hWnd,
  2513. UINT uMsg,
  2514. LPPROPSHEETPAGEW ppsp)
  2515. {
  2516. CERT_SETPROPERTIES_HELPER *pviewhelp = (CERT_SETPROPERTIES_HELPER *) ppsp->lParam;
  2517. if (pviewhelp->pcsp->pPropPageCallback != NULL)
  2518. {
  2519. (*(pviewhelp->pcsp->pPropPageCallback))(hWnd, uMsg, pviewhelp->pcsp->pvCallbackData);
  2520. }
  2521. if (uMsg == PSPCB_RELEASE)
  2522. {
  2523. if (pviewhelp->fSelfCleanup)
  2524. {
  2525. FreeSetPropertiesStruct((PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) pviewhelp->pcsp);
  2526. free(pviewhelp);
  2527. }
  2528. }
  2529. return TRUE;
  2530. }
  2531. //////////////////////////////////////////////////////////////////////////////////////
  2532. //
  2533. //////////////////////////////////////////////////////////////////////////////////////
  2534. BOOL WINAPI CryptUIGetCertificatePropertiesPagesW(
  2535. PCCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW pcsp,
  2536. BOOL *pfPropertiesChanged,
  2537. PROPSHEETPAGEW **prghPropPages,
  2538. DWORD *pcPropPages
  2539. )
  2540. {
  2541. BOOL fRetValue = TRUE;
  2542. HRESULT hr;
  2543. WCHAR rgwch[CRYPTUI_MAX_STRING_SIZE];
  2544. char rgch[CRYPTUI_MAX_STRING_SIZE];
  2545. CERT_SETPROPERTIES_HELPER *pviewhelp = NULL;
  2546. PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW pNewcsp;
  2547. PROPSHEETPAGEW * pClientPages = NULL;
  2548. DWORD cClientPages = 0;
  2549. *prghPropPages = NULL;
  2550. *pcPropPages = 0;
  2551. if (NULL == (pNewcsp = AllocAndCopySetPropertiesStruct(pcsp)))
  2552. {
  2553. goto ErrorReturn;
  2554. }
  2555. if (NULL == (pviewhelp = (CERT_SETPROPERTIES_HELPER *) malloc(sizeof(CERT_SETPROPERTIES_HELPER))))
  2556. {
  2557. goto ErrorReturn;
  2558. }
  2559. *pcPropPages = 2;
  2560. if (!CommonInit())
  2561. {
  2562. goto ErrorReturn;
  2563. }
  2564. //
  2565. // initialize the helper struct
  2566. //
  2567. memset (pviewhelp, 0, sizeof(CERT_SETPROPERTIES_HELPER));
  2568. pviewhelp->pcsp = pNewcsp;
  2569. pviewhelp->fSelfCleanup = TRUE;
  2570. pviewhelp->pfPropertiesChanged = pfPropertiesChanged;
  2571. pviewhelp->fGetPagesCalled = TRUE;
  2572. pviewhelp->fMMCCallbackMade = FALSE;
  2573. //
  2574. // set the properties changed flag to FALSE initially, it will be set
  2575. // to TRUE if when the dialog exits anything has been changed
  2576. //
  2577. pviewhelp->fPropertiesChanged = FALSE;
  2578. if (pviewhelp->pfPropertiesChanged != NULL)
  2579. {
  2580. *(pviewhelp->pfPropertiesChanged) = FALSE;
  2581. }
  2582. //
  2583. // get all the pages from registered clients
  2584. //
  2585. if (!GetRegisteredClientPages(&pClientPages, &cClientPages, pcsp->pCertContext))
  2586. {
  2587. goto ErrorReturn;
  2588. }
  2589. //
  2590. // Build up the list of pages we are going to use in the dialog
  2591. //
  2592. *prghPropPages = (PROPSHEETPAGEW *) malloc(((*pcPropPages) + cClientPages) * sizeof(PROPSHEETPAGEW));
  2593. if (*prghPropPages == NULL) {
  2594. goto ErrorReturn;
  2595. }
  2596. memset(*prghPropPages, 0, (*pcPropPages) * sizeof(PROPSHEETPAGEW));
  2597. (*prghPropPages)[0].dwSize = sizeof((*prghPropPages)[0]);
  2598. (*prghPropPages)[0].dwFlags = PSP_USECALLBACK;
  2599. (*prghPropPages)[0].hInstance = HinstDll;
  2600. (*prghPropPages)[0].pszTemplate = (LPWSTR) MAKEINTRESOURCE(IDD_CERTIFICATE_PROPERTIES_DIALOG);
  2601. (*prghPropPages)[0].hIcon = 0;
  2602. (*prghPropPages)[0].pszTitle = NULL;
  2603. (*prghPropPages)[0].pfnDlgProc = ViewPageSetPropertiesGeneral;
  2604. (*prghPropPages)[0].lParam = (LPARAM) pviewhelp;
  2605. (*prghPropPages)[0].pfnCallback = GetCertificatePropertiesPagesPropPageCallback;
  2606. (*prghPropPages)[0].pcRefParent = NULL;
  2607. (*prghPropPages)[1].dwSize = sizeof((*prghPropPages)[0]);
  2608. (*prghPropPages)[1].dwFlags = PSP_USECALLBACK;
  2609. (*prghPropPages)[1].hInstance = HinstDll;
  2610. (*prghPropPages)[1].pszTemplate = (LPWSTR) MAKEINTRESOURCE(IDD_CERTIFICATE_PROPERTIES_CROSSCERTS_DIALOG);
  2611. (*prghPropPages)[1].hIcon = 0;
  2612. (*prghPropPages)[1].pszTitle = NULL;
  2613. (*prghPropPages)[1].pfnDlgProc = ViewPageSetPropertiesCrossCerts;
  2614. (*prghPropPages)[1].lParam = (LPARAM) pviewhelp;
  2615. (*prghPropPages)[1].pfnCallback = NULL;
  2616. (*prghPropPages)[1].pcRefParent = NULL;
  2617. //
  2618. // copy over the registered client's pages
  2619. //
  2620. memcpy(&((*prghPropPages)[*pcPropPages]), pClientPages, cClientPages * sizeof(PROPSHEETPAGEW));
  2621. (*pcPropPages) += cClientPages;
  2622. CommonReturn:
  2623. if (pClientPages != NULL)
  2624. {
  2625. free(pClientPages);
  2626. }
  2627. return fRetValue;
  2628. ErrorReturn:
  2629. if (pNewcsp != NULL)
  2630. {
  2631. free(pNewcsp);
  2632. }
  2633. if (pviewhelp != NULL)
  2634. {
  2635. free(pviewhelp);
  2636. }
  2637. if (*prghPropPages != NULL)
  2638. {
  2639. free(*prghPropPages);
  2640. *prghPropPages = NULL;
  2641. }
  2642. fRetValue = FALSE;
  2643. goto CommonReturn;
  2644. }
  2645. //////////////////////////////////////////////////////////////////////////////////////
  2646. //
  2647. //////////////////////////////////////////////////////////////////////////////////////
  2648. BOOL WINAPI CryptUIGetCertificatePropertiesPagesA(
  2649. PCCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTA pcsp,
  2650. BOOL *pfPropertiesChanged,
  2651. PROPSHEETPAGEA **prghPropPages,
  2652. DWORD *pcPropPages
  2653. )
  2654. {
  2655. return (CryptUIGetCertificatePropertiesPagesW(
  2656. (PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) pcsp,
  2657. pfPropertiesChanged,
  2658. (PROPSHEETPAGEW**) prghPropPages,
  2659. pcPropPages));
  2660. }
  2661. //////////////////////////////////////////////////////////////////////////////////////
  2662. //
  2663. //////////////////////////////////////////////////////////////////////////////////////
  2664. BOOL WINAPI CryptUIFreeCertificatePropertiesPagesW(
  2665. PROPSHEETPAGEW *rghPropPages,
  2666. DWORD cPropPages
  2667. )
  2668. {
  2669. free(rghPropPages);
  2670. return TRUE;
  2671. }
  2672. //////////////////////////////////////////////////////////////////////////////////////
  2673. //
  2674. //////////////////////////////////////////////////////////////////////////////////////
  2675. BOOL WINAPI CryptUIFreeCertificatePropertiesPagesA(
  2676. PROPSHEETPAGEA *rghPropPages,
  2677. DWORD cPropPages
  2678. )
  2679. {
  2680. return (CryptUIFreeCertificatePropertiesPagesW((PROPSHEETPAGEW *) rghPropPages, cPropPages));
  2681. }