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.

3133 lines
108 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. //DSIE: Bug 465438.
  956. if (pcsp->dwFlags & CRYPTUI_DISABLE_EDITPROPERTIES)
  957. {
  958. SendMessage(GetDlgItem(hwndDlg, IDC_CERTIFICATE_NAME), EM_SETREADONLY, (WPARAM) TRUE, (LPARAM) 0);
  959. SendMessage(GetDlgItem(hwndDlg, IDC_DESCRIPTION), EM_SETREADONLY, (WPARAM) TRUE, (LPARAM) 0);
  960. EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE_ALL_RADIO), FALSE);
  961. EnableWindow(GetDlgItem(hwndDlg, IDC_DISABLE_ALL_RADIO), FALSE);
  962. EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE_SELECT_RADIO), FALSE);
  963. EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), FALSE);
  964. EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTY_NEWOID), FALSE);
  965. }
  966. return TRUE;
  967. case WM_NOTIFY:
  968. pviewhelp = (PCERT_SETPROPERTIES_HELPER) GetWindowLongPtr(hwndDlg, DWLP_USER);
  969. pcsp = (PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) pviewhelp->pcsp;
  970. pccert = pcsp->pCertContext;
  971. switch (((NMHDR FAR *) lParam)->code) {
  972. case PSN_SETACTIVE:
  973. break;
  974. case PSN_APPLY:
  975. {
  976. BOOL fAllItemsChecked = TRUE;
  977. DWORD cbPropertyUsage = 0;
  978. PCERT_ENHKEY_USAGE pPropertyUsage = NULL;
  979. GETTEXTEX GetTextStruct;
  980. memset(&GetTextStruct, 0, sizeof(GetTextStruct));
  981. GetTextStruct.flags = GT_DEFAULT;
  982. GetTextStruct.codepage = 1200; //UNICODE
  983. //
  984. // Write back the Friendly name
  985. // and description if they have changed
  986. //
  987. //
  988. // Friendly Name
  989. //
  990. cch = (DWORD)SendDlgItemMessage(hwndDlg, IDC_CERTIFICATE_NAME,
  991. WM_GETTEXTLENGTH, 0, 0);
  992. pwsz = (LPWSTR) malloc((cch+1)*sizeof(WCHAR));
  993. if (pwsz != NULL)
  994. {
  995. memset(pwsz, 0, (cch+1)*sizeof(WCHAR));
  996. if (fRichedit20Exists && fRichedit20Usable(GetDlgItem(hwndDlg, IDC_HIDDEN_RICHEDIT)))
  997. {
  998. GetTextStruct.cb = (cch+1)*sizeof(WCHAR);
  999. SendDlgItemMessageA(
  1000. hwndDlg,
  1001. IDC_CERTIFICATE_NAME,
  1002. EM_GETTEXTEX,
  1003. (WPARAM) &GetTextStruct,
  1004. (LPARAM) pwsz);
  1005. }
  1006. else
  1007. {
  1008. GetDlgItemTextU(hwndDlg, IDC_CERTIFICATE_NAME, pwsz, cch+1);
  1009. }
  1010. //
  1011. // check for change
  1012. //
  1013. if (wcscmp(pviewhelp->pwszInitialCertName, pwsz) != 0)
  1014. {
  1015. if (wcscmp(pwsz, L"") == 0)
  1016. {
  1017. f = CertSetCertificateContextProperty(pccert,
  1018. CERT_FRIENDLY_NAME_PROP_ID, 0,
  1019. NULL);
  1020. }
  1021. else
  1022. {
  1023. CryptDataBlob.pbData = (LPBYTE) pwsz;
  1024. CryptDataBlob.cbData = (cch+1)*sizeof(WCHAR);
  1025. f = CertSetCertificateContextProperty(pccert,
  1026. CERT_FRIENDLY_NAME_PROP_ID, 0,
  1027. &CryptDataBlob);
  1028. }
  1029. if (pviewhelp->pfPropertiesChanged != NULL)
  1030. {
  1031. *(pviewhelp->pfPropertiesChanged) = TRUE;
  1032. }
  1033. pviewhelp->fPropertiesChanged = TRUE;
  1034. }
  1035. free(pwsz);
  1036. }
  1037. //
  1038. // Description
  1039. //
  1040. cch = (DWORD)SendDlgItemMessage(hwndDlg, IDC_DESCRIPTION,
  1041. WM_GETTEXTLENGTH, 0, 0);
  1042. pwsz = (LPWSTR) malloc((cch+1)*sizeof(WCHAR));
  1043. if (pwsz != NULL)
  1044. {
  1045. memset(pwsz, 0, (cch+1)*sizeof(WCHAR));
  1046. if (fRichedit20Exists && fRichedit20Usable(GetDlgItem(hwndDlg, IDC_HIDDEN_RICHEDIT)))
  1047. {
  1048. GetTextStruct.cb = (cch+1)*sizeof(WCHAR);
  1049. SendDlgItemMessageA(
  1050. hwndDlg,
  1051. IDC_DESCRIPTION,
  1052. EM_GETTEXTEX,
  1053. (WPARAM) &GetTextStruct,
  1054. (LPARAM) pwsz);
  1055. }
  1056. else
  1057. {
  1058. GetDlgItemTextU(hwndDlg, IDC_DESCRIPTION, pwsz, cch+1);
  1059. }
  1060. //
  1061. // check for change
  1062. //
  1063. if (wcscmp(pviewhelp->pwszInitialDescription, pwsz) != 0)
  1064. {
  1065. if (wcscmp(pwsz, L"") == 0)
  1066. {
  1067. f = CertSetCertificateContextProperty(pccert,
  1068. CERT_DESCRIPTION_PROP_ID, 0,
  1069. NULL);
  1070. }
  1071. else
  1072. {
  1073. CryptDataBlob.pbData = (LPBYTE) pwsz;
  1074. CryptDataBlob.cbData = (cch+1)*sizeof(WCHAR);
  1075. f = CertSetCertificateContextProperty(pccert,
  1076. CERT_DESCRIPTION_PROP_ID, 0,
  1077. &CryptDataBlob);
  1078. }
  1079. if (pviewhelp->pfPropertiesChanged != NULL)
  1080. {
  1081. *(pviewhelp->pfPropertiesChanged) = TRUE;
  1082. }
  1083. pviewhelp->fPropertiesChanged = TRUE;
  1084. }
  1085. free(pwsz);
  1086. }
  1087. hWndListView = GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST);
  1088. //
  1089. // check the radio buttons and the usages to see if any have changed,
  1090. // if so, then set the fPropertiesFlag in the CERT_VIEWCERT_STRUCT so the
  1091. // caller knows that something has changed
  1092. //
  1093. if ((pviewhelp->EKUPropertyState == PROPERTY_STATE_ALL_ENABLED) &&
  1094. (SendDlgItemMessage(hwndDlg, IDC_ENABLE_ALL_RADIO, BM_GETCHECK, 0, (LPARAM) 0) == BST_CHECKED))
  1095. {
  1096. //pviewhelp->fPropertiesChanged = FALSE;
  1097. }
  1098. else if ((pviewhelp->EKUPropertyState == PROPERTY_STATE_ALL_DISABLED) &&
  1099. (SendDlgItemMessage(hwndDlg, IDC_DISABLE_ALL_RADIO, BM_GETCHECK, 0, (LPARAM) 0) == BST_CHECKED))
  1100. {
  1101. //pviewhelp->fPropertiesChanged = FALSE;
  1102. }
  1103. else if ((pviewhelp->EKUPropertyState == PROPERTY_STATE_SELECT) &&
  1104. (SendDlgItemMessage(hwndDlg, IDC_ENABLE_SELECT_RADIO, BM_GETCHECK, 0, (LPARAM) 0) == BST_CHECKED) &&
  1105. (!StateChanged(hWndListView)))
  1106. {
  1107. //pviewhelp->fPropertiesChanged = FALSE;
  1108. }
  1109. else
  1110. {
  1111. pviewhelp->fPropertiesChanged = TRUE;
  1112. }
  1113. if (pviewhelp->pfPropertiesChanged != NULL)
  1114. {
  1115. *(pviewhelp->pfPropertiesChanged) |= pviewhelp->fPropertiesChanged;
  1116. }
  1117. if ((SendDlgItemMessage(hwndDlg, IDC_ENABLE_ALL_RADIO, BM_GETCHECK, 0, (LPARAM) 0) == BST_CHECKED) &&
  1118. pviewhelp->fPropertiesChanged)
  1119. {
  1120. CertSetEnhancedKeyUsage(pccert, NULL);
  1121. }
  1122. else if ((SendDlgItemMessage(hwndDlg, IDC_DISABLE_ALL_RADIO, BM_GETCHECK, 0, (LPARAM) 0) == BST_CHECKED) &&
  1123. pviewhelp->fPropertiesChanged)
  1124. {
  1125. CERT_ENHKEY_USAGE eku;
  1126. eku.cUsageIdentifier = 0;
  1127. eku.rgpszUsageIdentifier = NULL;
  1128. CertSetEnhancedKeyUsage(pccert, &eku);
  1129. }
  1130. else if ((SendDlgItemMessage(hwndDlg, IDC_ENABLE_SELECT_RADIO, BM_GETCHECK, 0, (LPARAM) 0) == BST_CHECKED) &&
  1131. pviewhelp->fPropertiesChanged)
  1132. {
  1133. if (NULL == (pPropertyUsage = (PCERT_ENHKEY_USAGE) malloc(sizeof(CERT_ENHKEY_USAGE))))
  1134. {
  1135. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)FALSE);
  1136. return FALSE;
  1137. }
  1138. pPropertyUsage->cUsageIdentifier = 0;
  1139. pPropertyUsage->rgpszUsageIdentifier = NULL;
  1140. //
  1141. // enumerate through all the items and add to the properties
  1142. // if checked
  1143. //
  1144. memset(&lvI, 0, sizeof(lvI));
  1145. lvI.mask = LVIF_PARAM;
  1146. lvI.lParam = (LPARAM)NULL;
  1147. lvI.iItem = ListView_GetItemCount(hWndListView) - 1;
  1148. lvI.iSubItem = 0;
  1149. while (lvI.iItem >= 0)
  1150. {
  1151. if (!ListView_GetItemU(hWndListView, &lvI))
  1152. {
  1153. lvI.iItem--;
  1154. continue;
  1155. }
  1156. state = MyGetCheckState(hWndListView, lvI.iItem);
  1157. if ((state == MY_CHECK_STATE_CHECKED) || (state == MY_CHECK_STATE_CHECKED_GRAYED))
  1158. {
  1159. //
  1160. // allocate space for a pointer to the usage OID string
  1161. //
  1162. if (pPropertyUsage->cUsageIdentifier++ == 0)
  1163. {
  1164. pPropertyUsage->rgpszUsageIdentifier = (LPSTR *) malloc (sizeof(LPSTR));
  1165. }
  1166. else
  1167. {
  1168. pTemp = realloc (pPropertyUsage->rgpszUsageIdentifier,
  1169. sizeof(LPSTR) * pPropertyUsage->cUsageIdentifier);
  1170. if (pTemp == NULL)
  1171. {
  1172. free(pPropertyUsage->rgpszUsageIdentifier);
  1173. pPropertyUsage->rgpszUsageIdentifier = NULL;
  1174. }
  1175. else
  1176. {
  1177. pPropertyUsage->rgpszUsageIdentifier = (LPSTR *) pTemp;
  1178. }
  1179. }
  1180. if (pPropertyUsage->rgpszUsageIdentifier == NULL)
  1181. {
  1182. free(pPropertyUsage);
  1183. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)FALSE);
  1184. return FALSE;
  1185. }
  1186. pPropertyUsage->rgpszUsageIdentifier[pPropertyUsage->cUsageIdentifier-1] =
  1187. AllocAndCopyMBStr(((PSETPROPERTIES_HELPER_STRUCT)lvI.lParam)->pszOID);
  1188. }
  1189. lvI.iItem--;
  1190. }
  1191. AddExistingPropertiesToUsage(pccert, pPropertyUsage, hWndListView);
  1192. CertSetEnhancedKeyUsage(pccert, pPropertyUsage);
  1193. for (i=0; i<pPropertyUsage->cUsageIdentifier; i++)
  1194. {
  1195. free(pPropertyUsage->rgpszUsageIdentifier[i]);
  1196. }
  1197. if (pPropertyUsage->rgpszUsageIdentifier)
  1198. free(pPropertyUsage->rgpszUsageIdentifier);
  1199. }
  1200. if (pPropertyUsage != NULL)
  1201. free(pPropertyUsage);
  1202. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)TRUE);
  1203. break;
  1204. }
  1205. case PSN_KILLACTIVE:
  1206. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)FALSE);
  1207. return TRUE;
  1208. case PSN_RESET:
  1209. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)FALSE);
  1210. break;
  1211. case PSN_QUERYCANCEL:
  1212. pviewhelp->fCancelled = TRUE;
  1213. return FALSE;
  1214. case PSN_HELP:
  1215. if (FIsWin95) {
  1216. //WinHelpA(hwndDlg, (LPSTR) pcsp->szHelpFileName,
  1217. // HELP_CONTEXT, pcsp->dwHelpId);
  1218. }
  1219. else {
  1220. // WinHelpW(hwndDlg, pcsp->szHelpFileName, HELP_CONTEXT,
  1221. // pcsp->dwHelpId);
  1222. }
  1223. return TRUE;
  1224. case LVN_ITEMCHANGING:
  1225. if (pviewhelp->fInserting)
  1226. {
  1227. return TRUE;
  1228. }
  1229. pnmv = (LPNMLISTVIEW) lParam;
  1230. hWndListView = GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST);
  1231. state = LVIS_STATEIMAGEMASK & pnmv->uOldState;
  1232. if ((state == MY_CHECK_STATE_CHECKED_GRAYED) || (state == MY_CHECK_STATE_UNCHECKED_GRAYED))
  1233. {
  1234. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)TRUE);
  1235. }
  1236. else if ((state == MY_CHECK_STATE_CHECKED) || (state == MY_CHECK_STATE_UNCHECKED))
  1237. {
  1238. pviewhelp->fInserting = TRUE;
  1239. if (state == MY_CHECK_STATE_CHECKED)
  1240. {
  1241. MySetCheckState(hWndListView, pnmv->iItem, MY_CHECK_STATE_UNCHECKED);
  1242. }
  1243. else
  1244. {
  1245. MySetCheckState(hWndListView, pnmv->iItem, MY_CHECK_STATE_CHECKED);
  1246. }
  1247. pviewhelp->fInserting = FALSE;
  1248. PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
  1249. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)TRUE);
  1250. }
  1251. return TRUE;
  1252. case NM_SETFOCUS:
  1253. switch (((NMHDR FAR *) lParam)->idFrom)
  1254. {
  1255. case IDC_KEY_USAGE_LIST:
  1256. hWndListView = GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST);
  1257. if ((ListView_GetItemCount(hWndListView) != 0) &&
  1258. (ListView_GetNextItem(hWndListView, -1, LVNI_SELECTED) == -1))
  1259. {
  1260. memset(&lvI, 0, sizeof(lvI));
  1261. lvI.mask = LVIF_STATE;
  1262. lvI.iItem = 0;
  1263. lvI.state = LVIS_FOCUSED | LVIS_SELECTED;
  1264. lvI.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
  1265. ListView_SetItem(hWndListView, &lvI);
  1266. }
  1267. break;
  1268. }
  1269. break;
  1270. }
  1271. break;
  1272. case WM_COMMAND:
  1273. pviewhelp = (PCERT_SETPROPERTIES_HELPER) GetWindowLongPtr(hwndDlg, DWLP_USER);
  1274. pcsp = (PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) pviewhelp->pcsp;
  1275. pccert = pcsp->pCertContext;
  1276. switch (LOWORD(wParam))
  1277. {
  1278. case IDHELP:
  1279. if (FIsWin95)
  1280. {
  1281. //WinHelpA(hwndDlg, (LPSTR) pcsp->szHelpFileName,
  1282. // HELP_CONTEXT, pcsp->dwHelpId);
  1283. }
  1284. else
  1285. {
  1286. //WinHelpW(hwndDlg, pcsp->szHelpFileName, HELP_CONTEXT,
  1287. // pcsp->dwHelpId);
  1288. }
  1289. return TRUE;
  1290. case IDC_CERTIFICATE_NAME:
  1291. if (HIWORD(wParam) == EN_SETFOCUS)
  1292. {
  1293. SendDlgItemMessageA(hwndDlg, IDC_CERTIFICATE_NAME, EM_SETSEL, 0, -1);
  1294. return TRUE;
  1295. }
  1296. else if (HIWORD(wParam) == EN_CHANGE)
  1297. {
  1298. PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
  1299. }
  1300. break;
  1301. case IDC_DESCRIPTION:
  1302. if (HIWORD(wParam) == EN_SETFOCUS)
  1303. {
  1304. SendDlgItemMessageA(hwndDlg, IDC_DESCRIPTION, EM_SETSEL, 0, -1);
  1305. return TRUE;
  1306. }
  1307. else if (HIWORD(wParam) == EN_CHANGE)
  1308. {
  1309. PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
  1310. }
  1311. break;
  1312. case IDC_ENABLE_ALL_RADIO:
  1313. if (HIWORD(wParam) == BN_CLICKED)
  1314. {
  1315. SetEnableStateForChecks(pviewhelp, GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), FALSE);
  1316. EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), FALSE);
  1317. EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTY_NEWOID), FALSE);
  1318. if (pviewhelp->dwRadioButtonState != IDC_ENABLE_ALL_RADIO)
  1319. {
  1320. PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
  1321. pviewhelp->dwRadioButtonState = IDC_ENABLE_ALL_RADIO;
  1322. }
  1323. }
  1324. break;
  1325. case IDC_DISABLE_ALL_RADIO:
  1326. if (HIWORD(wParam) == BN_CLICKED)
  1327. {
  1328. SetEnableStateForChecks(pviewhelp, GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), FALSE);
  1329. EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), FALSE);
  1330. EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTY_NEWOID), FALSE);
  1331. if (pviewhelp->dwRadioButtonState != IDC_DISABLE_ALL_RADIO)
  1332. {
  1333. PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
  1334. pviewhelp->dwRadioButtonState = IDC_DISABLE_ALL_RADIO;
  1335. }
  1336. }
  1337. break;
  1338. case IDC_ENABLE_SELECT_RADIO:
  1339. if (HIWORD(wParam) == BN_CLICKED)
  1340. {
  1341. EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), TRUE);
  1342. SetEnableStateForChecks(pviewhelp, GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), TRUE);
  1343. if (pviewhelp->fAddPurposeCanBeEnabled)
  1344. {
  1345. EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTY_NEWOID), TRUE);
  1346. }
  1347. else
  1348. {
  1349. EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTY_NEWOID), FALSE);
  1350. }
  1351. if (pviewhelp->dwRadioButtonState != IDC_ENABLE_SELECT_RADIO)
  1352. {
  1353. PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
  1354. pviewhelp->dwRadioButtonState = IDC_ENABLE_SELECT_RADIO;
  1355. }
  1356. }
  1357. break;
  1358. case IDC_PROPERTY_NEWOID:
  1359. pszNewOID = (LPSTR) DialogBoxU(
  1360. HinstDll,
  1361. (LPWSTR) MAKEINTRESOURCE(IDD_USER_PURPOSE),
  1362. hwndDlg,
  1363. NewOIDDialogProc);
  1364. if (pszNewOID != NULL)
  1365. {
  1366. DWORD chStores = 0;
  1367. HCERTSTORE *phStores = NULL;
  1368. //
  1369. // if the OID already existis then put up a message box and return
  1370. //
  1371. if (OIDAlreadyExist(pszNewOID, GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST)))
  1372. {
  1373. WCHAR errorString2[CRYPTUI_MAX_STRING_SIZE];
  1374. WCHAR errorTitle2[CRYPTUI_MAX_STRING_SIZE];
  1375. LoadStringU(HinstDll, IDS_OID_ALREADY_EXISTS_MESSAGE, errorString2, ARRAYSIZE(errorString2));
  1376. LoadStringU(HinstDll, IDS_CERTIFICATE_PROPERTIES, errorTitle2, ARRAYSIZE(errorTitle2));
  1377. MessageBoxU(hwndDlg, errorString2, errorTitle2, MB_OK | MB_ICONWARNING);
  1378. return FALSE;
  1379. }
  1380. //
  1381. // if the usage doesn't exist in the chain usages, then put up an error
  1382. //
  1383. /*if ((pviewhelp->cszValidUsages != -1) && //pviewhelp->cszValidUsages == -1 means all usages are ok
  1384. !OIDinArray(pszNewOID, pviewhelp->rgszValidChainUsages, pviewhelp->cszValidUsages))
  1385. {
  1386. LoadStringU(HinstDll, IDS_ERROR_INVALIDOID_CERT, errorString2, ARRAYSIZE(errorString2));
  1387. LoadStringU(HinstDll, IDS_CERTIFICATE_PROPERTIES, errorTitle2, ARRAYSIZE(errorTitle2));
  1388. MessageBoxU(hwndDlg, errorString2, errorTitle2, MB_OK | MB_ICONERROR);
  1389. return FALSE;
  1390. } */
  1391. pviewhelp->fInserting = TRUE;
  1392. AddUsageToList(GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), pszNewOID, MY_CHECK_STATE_CHECKED, TRUE);
  1393. pviewhelp->fInserting = FALSE;
  1394. PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
  1395. free(pszNewOID);
  1396. }
  1397. break;
  1398. }
  1399. break;
  1400. case WM_DESTROY:
  1401. pviewhelp = (PCERT_SETPROPERTIES_HELPER) GetWindowLongPtr(hwndDlg, DWLP_USER);
  1402. //
  1403. // get all the items in the list view and free the lParam
  1404. // associated with each of them (lParam is the helper sruct)
  1405. //
  1406. hWndListView = GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST);
  1407. memset(&lvI, 0, sizeof(lvI));
  1408. lvI.iItem = ListView_GetItemCount(hWndListView) - 1;
  1409. lvI.mask = LVIF_PARAM;
  1410. while (lvI.iItem >= 0)
  1411. {
  1412. if (ListView_GetItemU(hWndListView, &lvI))
  1413. {
  1414. free((void *) lvI.lParam);
  1415. }
  1416. lvI.iItem--;
  1417. }
  1418. //
  1419. // free the name and description if they exist
  1420. //
  1421. if (pviewhelp->pwszInitialCertName)
  1422. {
  1423. free (pviewhelp->pwszInitialCertName);
  1424. }
  1425. if (pviewhelp->pwszInitialDescription)
  1426. {
  1427. free (pviewhelp->pwszInitialDescription);
  1428. }
  1429. //
  1430. // free the usage array
  1431. //
  1432. if (pviewhelp->rgszValidChainUsages)
  1433. {
  1434. free(pviewhelp->rgszValidChainUsages);
  1435. }
  1436. //
  1437. // if the properties have changed, and there is a pMMCCallback
  1438. // then make the callback to MMC
  1439. //
  1440. if (pviewhelp->fPropertiesChanged &&
  1441. pviewhelp->fGetPagesCalled &&
  1442. (pviewhelp->pcsp->pMMCCallback != NULL) &&
  1443. (pviewhelp->fMMCCallbackMade != TRUE))
  1444. {
  1445. pviewhelp->fMMCCallbackMade = TRUE;
  1446. (*(pviewhelp->pcsp->pMMCCallback->pfnCallback))(
  1447. pviewhelp->pcsp->pMMCCallback->lNotifyHandle,
  1448. pviewhelp->pcsp->pMMCCallback->param);
  1449. }
  1450. break;
  1451. case WM_HELP:
  1452. case WM_CONTEXTMENU:
  1453. if (msg == WM_HELP)
  1454. {
  1455. hwnd = GetDlgItem(hwndDlg, ((LPHELPINFO)lParam)->iCtrlId);
  1456. }
  1457. else
  1458. {
  1459. hwnd = (HWND) wParam;
  1460. }
  1461. if ((hwnd != GetDlgItem(hwndDlg, IDC_CERTIFICATE_NAME)) &&
  1462. (hwnd != GetDlgItem(hwndDlg, IDC_DESCRIPTION)) &&
  1463. (hwnd != GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST)) &&
  1464. (hwnd != GetDlgItem(hwndDlg, IDC_ENABLE_ALL_RADIO)) &&
  1465. (hwnd != GetDlgItem(hwndDlg, IDC_DISABLE_ALL_RADIO)) &&
  1466. (hwnd != GetDlgItem(hwndDlg, IDC_ENABLE_SELECT_RADIO)) &&
  1467. (hwnd != GetDlgItem(hwndDlg, IDC_PROPERTY_NEWOID)))
  1468. {
  1469. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)TRUE);
  1470. return TRUE;
  1471. }
  1472. else
  1473. {
  1474. return OnContextHelp(hwndDlg, msg, wParam, lParam, helpmapGeneral);
  1475. }
  1476. break;
  1477. }
  1478. return FALSE;
  1479. }
  1480. //////////////////////////////////////////////////////////////////////////////////////
  1481. //
  1482. //////////////////////////////////////////////////////////////////////////////////////
  1483. #define MAX_DWORD_SIZE ((DWORD) 0xffffffff)
  1484. //////////////////////////////////////////////////////////////////////////////////////
  1485. //
  1486. //////////////////////////////////////////////////////////////////////////////////////
  1487. INT_PTR APIENTRY ViewPageSetPropertiesCrossCerts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  1488. {
  1489. BOOL f;
  1490. DWORD cch;
  1491. PCCERT_CONTEXT pccert;
  1492. PROPSHEETPAGE * ps;
  1493. LPWSTR pwsz;
  1494. WCHAR rgwch[CRYPTUI_MAX_STRING_SIZE];
  1495. CRYPT_DATA_BLOB CryptDataBlob;
  1496. HWND hWndListView;
  1497. HWND hwnd;
  1498. LVITEMW lvI;
  1499. LV_COLUMNW lvC;
  1500. LPNMLISTVIEW pnmv;
  1501. WCHAR errorString[CRYPTUI_MAX_STRING_SIZE];
  1502. WCHAR errorTitle[CRYPTUI_MAX_STRING_SIZE];
  1503. DWORD dw;
  1504. int i;
  1505. void *pTemp;
  1506. PCERT_SETPROPERTIES_HELPER pviewhelp;
  1507. PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW pcsp = NULL;
  1508. DWORD cb = 0;
  1509. BYTE *pb = NULL;
  1510. CROSS_CERT_DIST_POINTS_INFO *pCrossCertInfo = NULL;
  1511. CROSS_CERT_DIST_POINTS_INFO CrossCertInfo;
  1512. DWORD cbCrossCertInfo = 0;
  1513. LPWSTR pwszStringToAdd = NULL;
  1514. PCERT_ALT_NAME_INFO pAltNameInfo = NULL;
  1515. BOOL fChecked;
  1516. WCHAR wszText[CRYPTUI_MAX_STRING_SIZE];
  1517. DWORD dwNumUnits = 0;
  1518. LPWSTR pwszURL = NULL;
  1519. DWORD dwLength;
  1520. BOOL fTranslated;
  1521. PCERT_ALT_NAME_ENTRY rgAltEntry;
  1522. LONG_PTR PrevWndProc;
  1523. DWORD dwSecsPerUnit = 1;
  1524. HWND hwndControl=NULL;
  1525. int listIndex=0;
  1526. switch ( msg ) {
  1527. case WM_INITDIALOG:
  1528. //
  1529. // save the pviewhelp struct in DWL_USER so it can always be accessed
  1530. //
  1531. ps = (PROPSHEETPAGE *) lParam;
  1532. pviewhelp = (PCERT_SETPROPERTIES_HELPER) ps->lParam;
  1533. pcsp = (PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) pviewhelp->pcsp;
  1534. pccert = pcsp->pCertContext;
  1535. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR) pviewhelp);
  1536. pviewhelp->InWMInit = TRUE;
  1537. hWndListView = GetDlgItem(hwndDlg, IDC_URL_LIST);
  1538. SendDlgItemMessage(hwndDlg, IDC_NUMBEROFUNITS_EDIT, EM_LIMITTEXT, (WPARAM) 7, (LPARAM) 0);
  1539. SendDlgItemMessage(hwndDlg, IDC_NEWURL_EDIT, EM_LIMITTEXT, (WPARAM) 512, (LPARAM) 0);
  1540. //
  1541. // Initialize the combo box fields
  1542. //
  1543. LoadStringU(HinstDll, IDS_HOURS, wszText, ARRAYSIZE(wszText));
  1544. SendDlgItemMessageU(hwndDlg, IDC_UNITS_COMBO, CB_INSERTSTRING, 0, (LPARAM) wszText);
  1545. LoadStringU(HinstDll, IDS_DAYS, wszText, ARRAYSIZE(wszText));
  1546. SendDlgItemMessageU(hwndDlg, IDC_UNITS_COMBO, CB_INSERTSTRING, 1, (LPARAM) wszText);
  1547. SendDlgItemMessageU(hwndDlg, IDC_UNITS_COMBO, CB_SETCURSEL, 0, (LPARAM) NULL);
  1548. SetDlgItemTextU(hwndDlg, IDC_NUMBEROFUNITS_EDIT, L"0");
  1549. //
  1550. // Initialize the list view control
  1551. //
  1552. memset(&lvC, 0, sizeof(LV_COLUMNW));
  1553. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  1554. lvC.fmt = LVCFMT_LEFT;
  1555. lvC.cx = 150;
  1556. lvC.pszText = L"";
  1557. lvC.iSubItem=0;
  1558. if (ListView_InsertColumnU(GetDlgItem(hwndDlg, IDC_URL_LIST), 0, &lvC) == -1)
  1559. {
  1560. return FALSE;
  1561. }
  1562. //DSIE: Bug 465438.
  1563. if (pcsp->dwFlags & CRYPTUI_DISABLE_EDITPROPERTIES)
  1564. {
  1565. EnableWindow(GetDlgItem(hwndDlg, IDC_CHECKFORNEWCERTS_CHECK), FALSE);
  1566. SendMessage(GetDlgItem(hwndDlg, IDC_NUMBEROFUNITS_EDIT), EM_SETREADONLY, (WPARAM) TRUE, (LPARAM) 0);
  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. SendMessage(GetDlgItem(hwndDlg, IDC_NEWURL_EDIT), EM_SETREADONLY, (WPARAM) TRUE, (LPARAM) 0);
  1571. EnableWindow(GetDlgItem(hwndDlg, IDC_URL_LIST), FALSE);
  1572. EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVEURL_BUTTON), FALSE);
  1573. }
  1574. else
  1575. {
  1576. //
  1577. // try to get the CERT_CROSS_CERT_DIST_POINTS_PROP_ID property for this cert
  1578. //
  1579. if (!CertGetCertificateContextProperty(
  1580. pccert,
  1581. CERT_CROSS_CERT_DIST_POINTS_PROP_ID,
  1582. NULL,
  1583. &cb))
  1584. {
  1585. //
  1586. // The property doesn't exist
  1587. //
  1588. SendDlgItemMessage(hwndDlg, IDC_CHECKFORNEWCERTS_CHECK, BM_SETCHECK, BST_UNCHECKED, 0);
  1589. EnableWindow(GetDlgItem(hwndDlg, IDC_NUMBEROFUNITS_EDIT), FALSE);
  1590. EnableWindow(GetDlgItem(hwndDlg, IDC_UNITS_COMBO), FALSE);
  1591. EnableWindow(GetDlgItem(hwndDlg, IDC_USE_DEFAULT_BUTTON), FALSE);
  1592. EnableWindow(GetDlgItem(hwndDlg, IDC_ADDURL_BUTTON), FALSE);
  1593. EnableWindow(GetDlgItem(hwndDlg, IDC_NEWURL_EDIT), FALSE);
  1594. EnableWindow(hWndListView, FALSE);
  1595. EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVEURL_BUTTON), FALSE);
  1596. pviewhelp->InWMInit = FALSE;
  1597. return TRUE;
  1598. }
  1599. else
  1600. {
  1601. SendDlgItemMessage(hwndDlg, IDC_CHECKFORNEWCERTS_CHECK, BM_SETCHECK, BST_CHECKED, 0);
  1602. EnableWindow(GetDlgItem(hwndDlg, IDC_NUMBEROFUNITS_EDIT), TRUE);
  1603. EnableWindow(GetDlgItem(hwndDlg, IDC_UNITS_COMBO), TRUE);
  1604. EnableWindow(GetDlgItem(hwndDlg, IDC_USE_DEFAULT_BUTTON), TRUE);
  1605. EnableWindow(GetDlgItem(hwndDlg, IDC_ADDURL_BUTTON), TRUE);
  1606. EnableWindow(GetDlgItem(hwndDlg, IDC_NEWURL_EDIT), TRUE);
  1607. EnableWindow(hWndListView, TRUE);
  1608. EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVEURL_BUTTON), FALSE);
  1609. }
  1610. }
  1611. if (NULL == (pb = (BYTE *) malloc(cb)))
  1612. {
  1613. return FALSE;
  1614. }
  1615. if (!CertGetCertificateContextProperty(
  1616. pccert,
  1617. CERT_CROSS_CERT_DIST_POINTS_PROP_ID,
  1618. pb,
  1619. &cb))
  1620. {
  1621. free(pb);
  1622. return FALSE;
  1623. }
  1624. if (!CryptDecodeObject(
  1625. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  1626. X509_CROSS_CERT_DIST_POINTS,
  1627. pb,
  1628. cb,
  1629. 0,
  1630. NULL,
  1631. &cbCrossCertInfo))
  1632. {
  1633. free(pb);
  1634. return FALSE;
  1635. }
  1636. if (NULL == (pCrossCertInfo =
  1637. (CROSS_CERT_DIST_POINTS_INFO *) malloc(cbCrossCertInfo)))
  1638. {
  1639. free(pb);
  1640. return FALSE;
  1641. }
  1642. if (!CryptDecodeObject(
  1643. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  1644. X509_CROSS_CERT_DIST_POINTS,
  1645. pb,
  1646. cb,
  1647. 0,
  1648. pCrossCertInfo,
  1649. &cbCrossCertInfo))
  1650. {
  1651. free(pb);
  1652. return FALSE;
  1653. }
  1654. free(pb);
  1655. //
  1656. // Initialize the sync time controls
  1657. //
  1658. if (pCrossCertInfo->dwSyncDeltaTime == 0)
  1659. {
  1660. pCrossCertInfo->dwSyncDeltaTime = XCERT_DEFAULT_SYNC_DELTA_TIME;
  1661. }
  1662. if ((pCrossCertInfo->dwSyncDeltaTime % 86400) == 0)
  1663. {
  1664. //
  1665. // Days
  1666. //
  1667. dwNumUnits = pCrossCertInfo->dwSyncDeltaTime / 86400;
  1668. SendDlgItemMessageU(
  1669. hwndDlg,
  1670. IDC_UNITS_COMBO,
  1671. CB_SETCURSEL,
  1672. 1,
  1673. (LPARAM) NULL);
  1674. }
  1675. else
  1676. {
  1677. //
  1678. // Hours
  1679. //
  1680. dwNumUnits = pCrossCertInfo->dwSyncDeltaTime / 3600;
  1681. //
  1682. // Force to 1 if exisiting value is less than 1 hour.
  1683. //
  1684. if (0 == dwNumUnits)
  1685. {
  1686. dwNumUnits = 1;
  1687. }
  1688. SendDlgItemMessageU(
  1689. hwndDlg,
  1690. IDC_UNITS_COMBO,
  1691. CB_SETCURSEL,
  1692. 0,
  1693. (LPARAM) NULL);
  1694. }
  1695. SetDlgItemInt(
  1696. hwndDlg,
  1697. IDC_NUMBEROFUNITS_EDIT,
  1698. dwNumUnits,
  1699. FALSE);
  1700. //
  1701. // Add each dist point to the list view
  1702. //
  1703. memset(&lvI, 0, sizeof(lvI));
  1704. lvI.mask = LVIF_TEXT | LVIF_PARAM;
  1705. for (lvI.iItem=0; lvI.iItem< (int)pCrossCertInfo->cDistPoint; lvI.iItem++)
  1706. {
  1707. pAltNameInfo = &(pCrossCertInfo->rgDistPoint[lvI.iItem]);
  1708. if ((pAltNameInfo->cAltEntry == 0) ||
  1709. (pAltNameInfo->rgAltEntry[0].dwAltNameChoice != 7))
  1710. {
  1711. continue;
  1712. }
  1713. pwszURL = (LPWSTR)
  1714. malloc( (wcslen(pAltNameInfo->rgAltEntry[0].pwszURL) + 1) *
  1715. sizeof(WCHAR));
  1716. if (pwszURL == NULL)
  1717. {
  1718. continue;
  1719. }
  1720. wcscpy(pwszURL, pAltNameInfo->rgAltEntry[0].pwszURL);
  1721. lvI.pszText = pwszURL;
  1722. lvI.lParam = (LPARAM) pwszURL;
  1723. ListView_InsertItemU(hWndListView, &lvI);
  1724. }
  1725. ListView_SetColumnWidth(hWndListView, 0, LVSCW_AUTOSIZE);
  1726. ListView_SetColumnWidth(hWndListView, 1, LVSCW_AUTOSIZE);
  1727. free(pCrossCertInfo);
  1728. pviewhelp->InWMInit = FALSE;
  1729. return TRUE;
  1730. case WM_NOTIFY:
  1731. pviewhelp = (PCERT_SETPROPERTIES_HELPER) GetWindowLongPtr(hwndDlg, DWLP_USER);
  1732. pcsp = (PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) pviewhelp->pcsp;
  1733. pccert = pcsp->pCertContext;
  1734. switch (((NMHDR FAR *) lParam)->code) {
  1735. case PSN_SETACTIVE:
  1736. break;
  1737. case PSN_APPLY:
  1738. hWndListView = GetDlgItem(hwndDlg, IDC_URL_LIST);
  1739. if (BST_CHECKED != SendDlgItemMessage(
  1740. hwndDlg,
  1741. IDC_CHECKFORNEWCERTS_CHECK,
  1742. BM_GETCHECK,
  1743. 0,
  1744. 0))
  1745. {
  1746. CertSetCertificateContextProperty(
  1747. pccert,
  1748. CERT_CROSS_CERT_DIST_POINTS_PROP_ID,
  1749. 0,
  1750. NULL);
  1751. }
  1752. else
  1753. {
  1754. //
  1755. // Set the sync time
  1756. //
  1757. memset(&CrossCertInfo, 0, sizeof(CrossCertInfo));
  1758. dwNumUnits = GetDlgItemInt(
  1759. hwndDlg,
  1760. IDC_NUMBEROFUNITS_EDIT,
  1761. &fTranslated,
  1762. FALSE);
  1763. if (0 == SendDlgItemMessage(hwndDlg, IDC_UNITS_COMBO, CB_GETCURSEL, 0, NULL))
  1764. {
  1765. dwSecsPerUnit = 3600;
  1766. }
  1767. else
  1768. {
  1769. dwSecsPerUnit = 86400;
  1770. }
  1771. CrossCertInfo.dwSyncDeltaTime = dwNumUnits * dwSecsPerUnit;
  1772. //
  1773. // Set the dist points
  1774. //
  1775. CrossCertInfo.cDistPoint = ListView_GetItemCount(hWndListView);
  1776. CrossCertInfo.rgDistPoint = (CERT_ALT_NAME_INFO *)
  1777. malloc( CrossCertInfo.cDistPoint *
  1778. sizeof(CERT_ALT_NAME_INFO));
  1779. if (CrossCertInfo.rgDistPoint == NULL)
  1780. {
  1781. break;
  1782. }
  1783. // one AltEntry per DistPoint
  1784. rgAltEntry = (CERT_ALT_NAME_ENTRY *)
  1785. malloc(CrossCertInfo.cDistPoint * sizeof(CERT_ALT_NAME_ENTRY));
  1786. if (rgAltEntry == NULL)
  1787. {
  1788. free(CrossCertInfo.rgDistPoint);
  1789. break;
  1790. }
  1791. memset(&lvI, 0, sizeof(lvI));
  1792. lvI.mask = LVIF_PARAM;
  1793. for (dw=0; dw<CrossCertInfo.cDistPoint; dw++)
  1794. {
  1795. lvI.iItem = dw;
  1796. if (ListView_GetItemU(hWndListView, &lvI))
  1797. {
  1798. CrossCertInfo.rgDistPoint[dw].cAltEntry = 1;
  1799. CrossCertInfo.rgDistPoint[dw].rgAltEntry = &(rgAltEntry[dw]);
  1800. rgAltEntry[dw].dwAltNameChoice = 7;
  1801. rgAltEntry[dw].pwszURL = (LPWSTR) lvI.lParam;
  1802. }
  1803. }
  1804. //
  1805. // Now encode
  1806. //
  1807. CryptDataBlob.cbData = 0;
  1808. CryptDataBlob.pbData = NULL;
  1809. if (CryptEncodeObject(
  1810. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  1811. X509_CROSS_CERT_DIST_POINTS,
  1812. &CrossCertInfo,
  1813. NULL,
  1814. &CryptDataBlob.cbData))
  1815. {
  1816. if (NULL != (CryptDataBlob.pbData = (BYTE *)
  1817. malloc(CryptDataBlob.cbData)))
  1818. {
  1819. if (CryptEncodeObject(
  1820. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  1821. X509_CROSS_CERT_DIST_POINTS,
  1822. &CrossCertInfo,
  1823. CryptDataBlob.pbData,
  1824. &CryptDataBlob.cbData))
  1825. {
  1826. CertSetCertificateContextProperty(
  1827. pccert,
  1828. CERT_CROSS_CERT_DIST_POINTS_PROP_ID,
  1829. 0,
  1830. &CryptDataBlob);
  1831. }
  1832. free(CryptDataBlob.pbData);
  1833. }
  1834. }
  1835. free(rgAltEntry);
  1836. free(CrossCertInfo.rgDistPoint);
  1837. }
  1838. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)TRUE);
  1839. break;
  1840. case PSN_KILLACTIVE:
  1841. //
  1842. // DSIE: Bug 124468. Per PM JohnLa, we don't make any check until user applies.
  1843. //
  1844. if (BST_CHECKED == SendDlgItemMessage(hwndDlg,
  1845. IDC_CHECKFORNEWCERTS_CHECK,
  1846. BM_GETCHECK,
  1847. 0,
  1848. 0))
  1849. {
  1850. //
  1851. // Check the sync time
  1852. //
  1853. dwNumUnits = GetDlgItemInt(
  1854. hwndDlg,
  1855. IDC_NUMBEROFUNITS_EDIT,
  1856. &fTranslated,
  1857. FALSE);
  1858. if (0 == SendDlgItemMessage(hwndDlg, IDC_UNITS_COMBO, CB_GETCURSEL, 0, NULL))
  1859. {
  1860. dwSecsPerUnit = 3600;
  1861. }
  1862. else
  1863. {
  1864. dwSecsPerUnit = 86400;
  1865. }
  1866. if (!fTranslated || 0 == dwNumUnits || dwNumUnits > (MAX_DWORD_SIZE / dwSecsPerUnit))
  1867. {
  1868. WCHAR * pwszMessage = NULL;
  1869. DWORD dwMaxInterval = MAX_DWORD_SIZE / dwSecsPerUnit;
  1870. if (pwszMessage = FormatMessageUnicodeIds(IDS_INVALID_XCERT_INTERVAL, dwMaxInterval))
  1871. {
  1872. WCHAR wszTitle[CRYPTUI_MAX_STRING_SIZE] = L"";
  1873. LoadStringU(HinstDll, IDS_CERTIFICATE_PROPERTIES, wszTitle, ARRAYSIZE(wszTitle));
  1874. MessageBoxU(hwndDlg, pwszMessage, wszTitle, MB_OK | MB_ICONWARNING);
  1875. LocalFree((HLOCAL) pwszMessage);
  1876. }
  1877. SetFocus(GetDlgItem(hwndDlg, IDC_NUMBEROFUNITS_EDIT));
  1878. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT) TRUE);
  1879. return TRUE;
  1880. }
  1881. }
  1882. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)FALSE);
  1883. return TRUE;
  1884. case PSN_RESET:
  1885. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)FALSE);
  1886. break;
  1887. case PSN_QUERYCANCEL:
  1888. pviewhelp->fCancelled = TRUE;
  1889. return FALSE;
  1890. case PSN_HELP:
  1891. if (FIsWin95) {
  1892. //WinHelpA(hwndDlg, (LPSTR) pcsp->szHelpFileName,
  1893. // HELP_CONTEXT, pcsp->dwHelpId);
  1894. }
  1895. else {
  1896. // WinHelpW(hwndDlg, pcsp->szHelpFileName, HELP_CONTEXT,
  1897. // pcsp->dwHelpId);
  1898. }
  1899. return TRUE;
  1900. case LVN_ITEMCHANGED:
  1901. EnableWindow(
  1902. GetDlgItem(hwndDlg, IDC_REMOVEURL_BUTTON),
  1903. (ListView_GetSelectedCount(
  1904. GetDlgItem(hwndDlg,IDC_URL_LIST)) == 0) ? FALSE : TRUE);
  1905. return TRUE;
  1906. case NM_SETFOCUS:
  1907. //get the window handle of the url list view
  1908. if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_URL_LIST)))
  1909. break;
  1910. //get the selected cert
  1911. listIndex = ListView_GetNextItem(
  1912. hwndControl,
  1913. -1,
  1914. LVNI_FOCUSED
  1915. );
  1916. //select first item to show hilite.
  1917. if (listIndex == -1)
  1918. ListView_SetItemState(hwndControl,
  1919. 0,
  1920. LVIS_SELECTED | LVIS_FOCUSED,
  1921. LVIS_SELECTED | LVIS_FOCUSED);
  1922. return TRUE;
  1923. }
  1924. break;
  1925. case WM_COMMAND:
  1926. pviewhelp = (PCERT_SETPROPERTIES_HELPER) GetWindowLongPtr(hwndDlg, DWLP_USER);
  1927. pcsp = (PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) pviewhelp->pcsp;
  1928. pccert = pcsp->pCertContext;
  1929. switch (LOWORD(wParam))
  1930. {
  1931. case IDHELP:
  1932. return TRUE;
  1933. case IDC_CHECKFORNEWCERTS_CHECK:
  1934. if (HIWORD(wParam) == BN_CLICKED)
  1935. {
  1936. //
  1937. // Get current state of check, then enable/disable all
  1938. // controls accordingly
  1939. //
  1940. fChecked = (BST_CHECKED == SendDlgItemMessage(
  1941. hwndDlg,
  1942. IDC_CHECKFORNEWCERTS_CHECK,
  1943. BM_GETCHECK,
  1944. 0,
  1945. 0));
  1946. EnableWindow(GetDlgItem(hwndDlg, IDC_NUMBEROFUNITS_EDIT), fChecked);
  1947. EnableWindow(GetDlgItem(hwndDlg, IDC_UNITS_COMBO), fChecked);
  1948. EnableWindow(GetDlgItem(hwndDlg, IDC_USE_DEFAULT_BUTTON), fChecked);
  1949. EnableWindow(GetDlgItem(hwndDlg, IDC_ADDURL_BUTTON), fChecked);
  1950. EnableWindow(GetDlgItem(hwndDlg, IDC_NEWURL_EDIT), fChecked);
  1951. EnableWindow(GetDlgItem(hwndDlg, IDC_URL_LIST), fChecked);
  1952. if (fChecked)
  1953. {
  1954. //
  1955. // DSIE: Bug 124669.
  1956. //
  1957. dwNumUnits = GetDlgItemInt(
  1958. hwndDlg,
  1959. IDC_NUMBEROFUNITS_EDIT,
  1960. &fTranslated,
  1961. FALSE);
  1962. if (0 == dwNumUnits)
  1963. {
  1964. SendDlgItemMessageU(
  1965. hwndDlg,
  1966. IDC_UNITS_COMBO,
  1967. CB_SETCURSEL,
  1968. 0,
  1969. (LPARAM) NULL);
  1970. SetDlgItemInt(
  1971. hwndDlg,
  1972. IDC_NUMBEROFUNITS_EDIT,
  1973. XCERT_DEFAULT_DELTA_HOURS,
  1974. FALSE);
  1975. }
  1976. EnableWindow(
  1977. GetDlgItem(hwndDlg, IDC_REMOVEURL_BUTTON),
  1978. (ListView_GetSelectedCount(
  1979. GetDlgItem(hwndDlg,IDC_URL_LIST)) == 0) ? FALSE : TRUE);
  1980. }
  1981. else
  1982. {
  1983. EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVEURL_BUTTON), FALSE);
  1984. }
  1985. if (pviewhelp->pfPropertiesChanged != NULL)
  1986. {
  1987. *(pviewhelp->pfPropertiesChanged) = TRUE;
  1988. }
  1989. pviewhelp->fPropertiesChanged = TRUE;
  1990. PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
  1991. }
  1992. break;
  1993. case IDC_USE_DEFAULT_BUTTON:
  1994. if (HIWORD(wParam) == BN_CLICKED)
  1995. {
  1996. //
  1997. // Reset to default interval.
  1998. //
  1999. SendDlgItemMessageU(
  2000. hwndDlg,
  2001. IDC_UNITS_COMBO,
  2002. CB_SETCURSEL,
  2003. 0,
  2004. (LPARAM) NULL);
  2005. SetDlgItemInt(
  2006. hwndDlg,
  2007. IDC_NUMBEROFUNITS_EDIT,
  2008. XCERT_DEFAULT_DELTA_HOURS,
  2009. FALSE);
  2010. }
  2011. break;
  2012. case IDC_ADDURL_BUTTON:
  2013. if (HIWORD(wParam) == BN_CLICKED)
  2014. {
  2015. hWndListView = GetDlgItem(hwndDlg, IDC_URL_LIST);
  2016. dwLength = (DWORD) SendDlgItemMessage(
  2017. hwndDlg,
  2018. IDC_NEWURL_EDIT,
  2019. WM_GETTEXTLENGTH,
  2020. 0,
  2021. NULL);
  2022. if (dwLength == 0)
  2023. {
  2024. break;
  2025. }
  2026. pwszURL = (LPWSTR) malloc((dwLength + 1) * sizeof(WCHAR));
  2027. if (pwszURL == NULL)
  2028. {
  2029. break;
  2030. }
  2031. GetDlgItemTextU(
  2032. hwndDlg,
  2033. IDC_NEWURL_EDIT,
  2034. pwszURL,
  2035. dwLength + 1);
  2036. pwszURL[dwLength] = '\0';
  2037. if (!IsValidURL(pwszURL))
  2038. {
  2039. free(pwszURL);
  2040. LoadStringU(HinstDll, IDS_INVALID_URL_ERROR, errorString, ARRAYSIZE(errorString));
  2041. LoadStringU(HinstDll, IDS_CERTIFICATE_PROPERTIES, errorTitle, ARRAYSIZE(errorTitle));
  2042. MessageBoxU(hwndDlg, errorString, errorTitle, MB_OK | MB_ICONWARNING);
  2043. break;
  2044. }
  2045. memset(&lvI, 0, sizeof(lvI));
  2046. lvI.mask = LVIF_TEXT | LVIF_PARAM;
  2047. lvI.iItem = ListView_GetItemCount(hWndListView);
  2048. lvI.pszText = pwszURL;
  2049. lvI.lParam = (LPARAM) pwszURL;
  2050. ListView_InsertItemU(hWndListView, &lvI);
  2051. ListView_SetColumnWidth(hWndListView, 0, LVSCW_AUTOSIZE);
  2052. #if (0) //DSIE: Bug 434091
  2053. ListView_SetColumnWidth(hWndListView, 1, LVSCW_AUTOSIZE);
  2054. #endif
  2055. SetDlgItemTextU(hwndDlg, IDC_NEWURL_EDIT, L"");
  2056. if (pviewhelp->pfPropertiesChanged != NULL)
  2057. {
  2058. *(pviewhelp->pfPropertiesChanged) = TRUE;
  2059. }
  2060. pviewhelp->fPropertiesChanged = TRUE;
  2061. PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
  2062. }
  2063. break;
  2064. case IDC_REMOVEURL_BUTTON:
  2065. hWndListView = GetDlgItem(hwndDlg, IDC_URL_LIST);
  2066. memset(&lvI, 0, sizeof(lvI));
  2067. lvI.mask = LVIF_STATE | LVIF_PARAM;
  2068. lvI.stateMask = LVIS_SELECTED;
  2069. for (i=(ListView_GetItemCount(hWndListView) - 1); i >=0; i--)
  2070. {
  2071. lvI.iItem = i;
  2072. if (ListView_GetItemU(hWndListView, &lvI) &&
  2073. (lvI.state & LVIS_SELECTED))
  2074. {
  2075. free((void *) lvI.lParam);
  2076. ListView_DeleteItem(hWndListView, i);
  2077. }
  2078. }
  2079. ListView_SetColumnWidth(hWndListView, 0, LVSCW_AUTOSIZE);
  2080. #if (0) //DSIE: Bug 434091
  2081. ListView_SetColumnWidth(hWndListView, 1, LVSCW_AUTOSIZE);
  2082. #endif
  2083. if (pviewhelp->pfPropertiesChanged != NULL)
  2084. {
  2085. *(pviewhelp->pfPropertiesChanged) = TRUE;
  2086. }
  2087. pviewhelp->fPropertiesChanged = TRUE;
  2088. PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
  2089. if (0 == ListView_GetItemCount(hWndListView))
  2090. {
  2091. SetFocus(GetDlgItem(GetParent(hwndDlg), IDOK));
  2092. }
  2093. else
  2094. {
  2095. //get the selected cert
  2096. listIndex = ListView_GetNextItem(
  2097. hWndListView,
  2098. -1,
  2099. LVNI_FOCUSED
  2100. );
  2101. //select first item to show hilite.
  2102. if (listIndex == -1)
  2103. listIndex = 0;
  2104. ListView_SetItemState(hWndListView,
  2105. listIndex,
  2106. LVIS_SELECTED | LVIS_FOCUSED,
  2107. LVIS_SELECTED | LVIS_FOCUSED);
  2108. SetFocus(GetDlgItem(hwndDlg,IDC_REMOVEURL_BUTTON));
  2109. SendMessage(GetDlgItem(hwndDlg,IDC_REMOVEURL_BUTTON), BM_SETSTYLE, BS_DEFPUSHBUTTON, 0);
  2110. }
  2111. break;
  2112. case IDC_UNITS_COMBO:
  2113. if (HIWORD(wParam) == CBN_SELCHANGE)
  2114. {
  2115. if (!pviewhelp->InWMInit)
  2116. {
  2117. dwNumUnits = GetDlgItemInt(
  2118. hwndDlg,
  2119. IDC_NUMBEROFUNITS_EDIT,
  2120. &fTranslated,
  2121. FALSE);
  2122. if (0 == SendDlgItemMessage(hwndDlg, IDC_UNITS_COMBO, CB_GETCURSEL, 0, NULL))
  2123. {
  2124. dwSecsPerUnit = 3600;
  2125. }
  2126. else
  2127. {
  2128. dwSecsPerUnit = 86400;
  2129. }
  2130. if (dwNumUnits > (MAX_DWORD_SIZE / dwSecsPerUnit))
  2131. {
  2132. SetDlgItemInt(
  2133. hwndDlg,
  2134. IDC_NUMBEROFUNITS_EDIT,
  2135. (DWORD) (MAX_DWORD_SIZE / dwSecsPerUnit),
  2136. FALSE);
  2137. }
  2138. PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
  2139. }
  2140. }
  2141. break;
  2142. case IDC_NUMBEROFUNITS_EDIT:
  2143. if (HIWORD(wParam) == EN_CHANGE)
  2144. {
  2145. if (!pviewhelp->InWMInit)
  2146. {
  2147. PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
  2148. }
  2149. }
  2150. break;
  2151. }
  2152. break;
  2153. case WM_DESTROY:
  2154. pviewhelp = (PCERT_SETPROPERTIES_HELPER) GetWindowLongPtr(hwndDlg, DWLP_USER);
  2155. pcsp = (PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) pviewhelp->pcsp;
  2156. pccert = pcsp->pCertContext;
  2157. hWndListView = GetDlgItem(hwndDlg, IDC_URL_LIST);
  2158. memset(&lvI, 0, sizeof(lvI));
  2159. lvI.mask = LVIF_PARAM;
  2160. for (i=(ListView_GetItemCount(hWndListView) - 1); i >=0; i--)
  2161. {
  2162. lvI.iItem = i;
  2163. if (ListView_GetItemU(hWndListView, &lvI))
  2164. {
  2165. free((void *) lvI.lParam);
  2166. }
  2167. }
  2168. //
  2169. // if the properties have changed, and there is a pMMCCallback
  2170. // then make the callback to MMC
  2171. //
  2172. if (pviewhelp->fPropertiesChanged &&
  2173. pviewhelp->fGetPagesCalled &&
  2174. (pviewhelp->pcsp->pMMCCallback != NULL) &&
  2175. (pviewhelp->fMMCCallbackMade != TRUE))
  2176. {
  2177. pviewhelp->fMMCCallbackMade = TRUE;
  2178. (*(pviewhelp->pcsp->pMMCCallback->pfnCallback))(
  2179. pviewhelp->pcsp->pMMCCallback->lNotifyHandle,
  2180. pviewhelp->pcsp->pMMCCallback->param);
  2181. }
  2182. break;
  2183. case WM_HELP:
  2184. case WM_CONTEXTMENU:
  2185. if (msg == WM_HELP)
  2186. {
  2187. hwnd = GetDlgItem(hwndDlg, ((LPHELPINFO)lParam)->iCtrlId);
  2188. }
  2189. else
  2190. {
  2191. hwnd = (HWND) wParam;
  2192. }
  2193. if ((hwnd != GetDlgItem(hwndDlg, IDC_CHECKFORNEWCERTS_CHECK)) &&
  2194. (hwnd != GetDlgItem(hwndDlg, IDC_NUMBEROFUNITS_EDIT)) &&
  2195. (hwnd != GetDlgItem(hwndDlg, IDC_UNITS_COMBO)) &&
  2196. (hwnd != GetDlgItem(hwndDlg, IDC_USE_DEFAULT_BUTTON)) &&
  2197. (hwnd != GetDlgItem(hwndDlg, IDC_ADDURL_BUTTON)) &&
  2198. (hwnd != GetDlgItem(hwndDlg, IDC_NEWURL_EDIT)) &&
  2199. (hwnd != GetDlgItem(hwndDlg, IDC_URL_LIST)) &&
  2200. (hwnd != GetDlgItem(hwndDlg, IDC_REMOVEURL_BUTTON)))
  2201. {
  2202. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)TRUE);
  2203. return TRUE;
  2204. }
  2205. else
  2206. {
  2207. return OnContextHelp(hwndDlg, msg, wParam, lParam, helpmapCrossCert);
  2208. }
  2209. break;
  2210. }
  2211. return FALSE;
  2212. }
  2213. //////////////////////////////////////////////////////////////////////////////////////
  2214. //
  2215. //////////////////////////////////////////////////////////////////////////////////////
  2216. BOOL GetRegisteredClientPages(PROPSHEETPAGEW **ppClientPages, DWORD *pcClientPages, PCCERT_CONTEXT pCertContext)
  2217. {
  2218. HCRYPTOIDFUNCSET hCertPropPagesFuncSet;
  2219. void * pvFuncAddr = NULL;
  2220. HCRYPTOIDFUNCADDR hFuncAddr = NULL;
  2221. PROPSHEETPAGEW callbackPages[MAX_CLIENT_PAGES];
  2222. DWORD cCallbackPages = MAX_CLIENT_PAGES;
  2223. DWORD cChars = 0;
  2224. LPWSTR pwszDllNames = NULL;
  2225. BOOL fRet = TRUE;
  2226. LPWSTR pwszCurrentDll;
  2227. DWORD i;
  2228. void *pTemp;
  2229. //
  2230. // initialize incoming variables
  2231. //
  2232. *ppClientPages = NULL;
  2233. *pcClientPages = 0;
  2234. //
  2235. // get a handle to the function table
  2236. //
  2237. if (NULL == (hCertPropPagesFuncSet = CryptInitOIDFunctionSet(
  2238. CRYPTUILDLG_CERTPROP_PAGES_CALLBACK, 0)))
  2239. {
  2240. goto ErrorReturn;
  2241. }
  2242. //
  2243. // get the list of dlls that contain the callback functions
  2244. //
  2245. if (!CryptGetDefaultOIDDllList(
  2246. hCertPropPagesFuncSet,
  2247. 0,
  2248. NULL,
  2249. &cChars))
  2250. {
  2251. goto ErrorReturn;
  2252. }
  2253. if (NULL == (pwszDllNames = (LPWSTR) malloc(cChars * sizeof(WCHAR))))
  2254. {
  2255. SetLastError(E_OUTOFMEMORY);
  2256. goto ErrorReturn;
  2257. }
  2258. if (!CryptGetDefaultOIDDllList(
  2259. hCertPropPagesFuncSet,
  2260. 0,
  2261. pwszDllNames,
  2262. &cChars))
  2263. {
  2264. goto ErrorReturn;
  2265. }
  2266. //
  2267. // loop for each dll and call it to see if it has property pages for this cert
  2268. //
  2269. pwszCurrentDll = pwszDllNames;
  2270. while (pwszCurrentDll[0] != L'\0')
  2271. {
  2272. //
  2273. // try to get the function pointer
  2274. //
  2275. if (!CryptGetDefaultOIDFunctionAddress(
  2276. hCertPropPagesFuncSet,
  2277. 0,
  2278. pwszCurrentDll,
  2279. 0,
  2280. &pvFuncAddr,
  2281. &hFuncAddr))
  2282. {
  2283. DWORD dwErr = GetLastError();
  2284. pwszCurrentDll += wcslen(pwszCurrentDll) + 1;
  2285. continue;
  2286. }
  2287. //
  2288. // call the client to get the their pages
  2289. //
  2290. cCallbackPages = MAX_CLIENT_PAGES;
  2291. memset(callbackPages, 0, sizeof(callbackPages));
  2292. if (((PFN_CRYPTUIDLG_CERTPROP_PAGES_CALLBACK) pvFuncAddr)(pCertContext, callbackPages, &cCallbackPages))
  2293. {
  2294. //
  2295. // if they handed back pages then add them to the array
  2296. //
  2297. if (cCallbackPages >= 1)
  2298. {
  2299. if (*ppClientPages == NULL)
  2300. {
  2301. if (NULL == (*ppClientPages = (PROPSHEETPAGEW *) malloc(cCallbackPages * sizeof(PROPSHEETPAGEW))))
  2302. {
  2303. SetLastError(E_OUTOFMEMORY);
  2304. goto ErrorReturn;
  2305. }
  2306. }
  2307. else
  2308. {
  2309. if (NULL == (pTemp = realloc(*ppClientPages, (cCallbackPages + (*pcClientPages)) * sizeof(PROPSHEETPAGEW))))
  2310. {
  2311. SetLastError(E_OUTOFMEMORY);
  2312. goto ErrorReturn;
  2313. }
  2314. *ppClientPages = (PROPSHEETPAGEW *) pTemp;
  2315. }
  2316. memcpy(&((*ppClientPages)[(*pcClientPages)]), &(callbackPages[0]), cCallbackPages * sizeof(PROPSHEETPAGEW));
  2317. *pcClientPages += cCallbackPages;
  2318. }
  2319. }
  2320. //
  2321. // free the function that was just called, and move on to the next one in the string
  2322. //
  2323. CryptFreeOIDFunctionAddress(hFuncAddr, 0);
  2324. hFuncAddr = NULL;
  2325. pwszCurrentDll += wcslen(pwszCurrentDll) + 1;
  2326. }
  2327. CleanUp:
  2328. if (pwszDllNames != NULL)
  2329. {
  2330. free(pwszDllNames);
  2331. }
  2332. if (hFuncAddr != NULL)
  2333. {
  2334. CryptFreeOIDFunctionAddress(hFuncAddr, 0);
  2335. }
  2336. return fRet;
  2337. ErrorReturn:
  2338. fRet = FALSE;
  2339. goto CleanUp;
  2340. }
  2341. //////////////////////////////////////////////////////////////////////////////////////
  2342. // CertSetCertificateProperties
  2343. //
  2344. // Description:
  2345. // This routine will display and allow the user to edit certain properties of
  2346. // a certificate
  2347. //
  2348. //
  2349. //////////////////////////////////////////////////////////////////////////////////////
  2350. BOOL WINAPI CryptUIDlgViewCertificatePropertiesW(PCCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW pcsp,
  2351. BOOL *pfPropertiesChanged)
  2352. {
  2353. int cPages = 2;
  2354. BOOL fRetValue = FALSE;
  2355. HRESULT hr;
  2356. PROPSHEETPAGEW * ppage = NULL;
  2357. PROPSHEETPAGEW * pClientPages = NULL;
  2358. DWORD cClientPages = 0;
  2359. INT_PTR ret;
  2360. WCHAR rgwch[256];
  2361. char rgch[256];
  2362. CERT_SETPROPERTIES_HELPER viewhelper;
  2363. if (pcsp->dwSize != sizeof(CRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW)) {
  2364. SetLastError(E_INVALIDARG);
  2365. return FALSE;
  2366. }
  2367. if (!CommonInit())
  2368. {
  2369. return FALSE;
  2370. }
  2371. //
  2372. // initialize the helper struct
  2373. //
  2374. memset (&viewhelper, 0, sizeof(viewhelper));
  2375. viewhelper.pcsp = pcsp;
  2376. viewhelper.fSelfCleanup = FALSE;
  2377. viewhelper.pfPropertiesChanged = pfPropertiesChanged;
  2378. viewhelper.fGetPagesCalled = FALSE;
  2379. viewhelper.fMMCCallbackMade = FALSE;
  2380. //
  2381. // set the properties changed flag to FALSE initially, it will be set
  2382. // to TRUE if when the dialog exits anything has been changed
  2383. //
  2384. viewhelper.fPropertiesChanged = FALSE;
  2385. if (viewhelper.pfPropertiesChanged != NULL)
  2386. {
  2387. *(viewhelper.pfPropertiesChanged) = FALSE;
  2388. }
  2389. //
  2390. // get all the pages from registered clients
  2391. //
  2392. if (!GetRegisteredClientPages(&pClientPages, &cClientPages, pcsp->pCertContext))
  2393. {
  2394. return FALSE;
  2395. }
  2396. //
  2397. // Build up the list of pages we are going to use in the dialog
  2398. //
  2399. ppage = (PROPSHEETPAGEW *) malloc((cPages + pcsp->cPropSheetPages + cClientPages) * sizeof(PROPSHEETPAGEW));
  2400. if (ppage == NULL) {
  2401. goto Exit;
  2402. }
  2403. memset(ppage, 0, (cPages + pcsp->cPropSheetPages + cClientPages) * sizeof(PROPSHEETPAGEW));
  2404. ppage[0].dwSize = sizeof(ppage[0]);
  2405. ppage[0].dwFlags = 0;
  2406. ppage[0].hInstance = HinstDll;
  2407. ppage[0].pszTemplate = (LPWSTR) MAKEINTRESOURCE(IDD_CERTIFICATE_PROPERTIES_DIALOG);
  2408. ppage[0].hIcon = 0;
  2409. ppage[0].pszTitle = NULL;
  2410. ppage[0].pfnDlgProc = ViewPageSetPropertiesGeneral;
  2411. ppage[0].lParam = (LPARAM) &viewhelper;
  2412. ppage[0].pfnCallback = 0;
  2413. ppage[0].pcRefParent = NULL;
  2414. ppage[1].dwSize = sizeof(ppage[0]);
  2415. ppage[1].dwFlags = 0;
  2416. ppage[1].hInstance = HinstDll;
  2417. ppage[1].pszTemplate = (LPWSTR) MAKEINTRESOURCE(IDD_CERTIFICATE_PROPERTIES_CROSSCERTS_DIALOG);
  2418. ppage[1].hIcon = 0;
  2419. ppage[1].pszTitle = NULL;
  2420. ppage[1].pfnDlgProc = ViewPageSetPropertiesCrossCerts;
  2421. ppage[1].lParam = (LPARAM) &viewhelper;
  2422. ppage[1].pfnCallback = 0;
  2423. ppage[1].pcRefParent = NULL;
  2424. //
  2425. // copy over the users pages
  2426. //
  2427. memcpy(&ppage[cPages], pcsp->rgPropSheetPages, pcsp->cPropSheetPages * sizeof(PROPSHEETPAGEW));
  2428. cPages += pcsp->cPropSheetPages;
  2429. //
  2430. // copy over the registered client's pages
  2431. //
  2432. memcpy(&ppage[cPages], pClientPages, cClientPages * sizeof(PROPSHEETPAGEW));
  2433. cPages += cClientPages;
  2434. if (FIsWin95) {
  2435. PROPSHEETHEADERA hdr;
  2436. memset(&hdr, 0, sizeof(hdr));
  2437. hdr.dwSize = sizeof(hdr);
  2438. hdr.dwFlags = PSH_PROPSHEETPAGE;// | PSH_NOAPPLYNOW;
  2439. hdr.hwndParent = (pcsp->hwndParent != NULL) ? pcsp->hwndParent : GetDesktopWindow();
  2440. hdr.hInstance = HinstDll;
  2441. hdr.hIcon = NULL;
  2442. if (pcsp->szTitle != NULL)
  2443. {
  2444. hdr.pszCaption = CertUIMkMBStr(pcsp->szTitle);
  2445. }
  2446. else
  2447. {
  2448. LoadStringA(HinstDll, IDS_CERTIFICATE_PROPERTIES, (LPSTR) rgch, sizeof(rgch));
  2449. hdr.pszCaption = (LPSTR) rgch;
  2450. }
  2451. hdr.nPages = cPages;
  2452. hdr.nStartPage = 0;
  2453. hdr.ppsp = ConvertToPropPageA(ppage, cPages);
  2454. if (hdr.ppsp == NULL)
  2455. {
  2456. if ((pcsp->szTitle != NULL) && (hdr.pszCaption != NULL))
  2457. {
  2458. free((void *)hdr.pszCaption);
  2459. }
  2460. goto Exit;
  2461. }
  2462. hdr.pfnCallback = NULL;
  2463. ret = CryptUIPropertySheetA(&hdr);
  2464. if ((pcsp->szTitle != NULL) && (hdr.pszCaption != NULL))
  2465. {
  2466. free((void *)hdr.pszCaption);
  2467. }
  2468. FreePropSheetPagesA((PROPSHEETPAGEA *)hdr.ppsp, cPages);
  2469. }
  2470. else {
  2471. PROPSHEETHEADERW hdr;
  2472. memset(&hdr, 0, sizeof(hdr));
  2473. hdr.dwSize = sizeof(hdr);
  2474. hdr.dwFlags = PSH_PROPSHEETPAGE;// | PSH_NOAPPLYNOW;
  2475. hdr.hwndParent = (pcsp->hwndParent != NULL) ? pcsp->hwndParent : GetDesktopWindow();
  2476. hdr.hInstance = HinstDll;
  2477. hdr.hIcon = NULL;
  2478. if (pcsp->szTitle)
  2479. {
  2480. hdr.pszCaption = pcsp->szTitle;
  2481. }
  2482. else
  2483. {
  2484. LoadStringW(HinstDll, IDS_CERTIFICATE_PROPERTIES, rgwch, ARRAYSIZE(rgwch));
  2485. hdr.pszCaption = rgwch;
  2486. }
  2487. hdr.nPages = cPages;
  2488. hdr.nStartPage = 0;
  2489. hdr.ppsp = (PROPSHEETPAGEW *) ppage;
  2490. hdr.pfnCallback = NULL;
  2491. ret = CryptUIPropertySheetW(&hdr);
  2492. }
  2493. if (viewhelper.fCancelled)
  2494. {
  2495. SetLastError(ERROR_CANCELLED);
  2496. }
  2497. fRetValue = (ret >= 1);
  2498. Exit:
  2499. if (pClientPages)
  2500. free(pClientPages);
  2501. if (ppage)
  2502. free(ppage);
  2503. return fRetValue;
  2504. }
  2505. //////////////////////////////////////////////////////////////////////////////////////
  2506. //
  2507. //////////////////////////////////////////////////////////////////////////////////////
  2508. BOOL WINAPI CryptUIDlgViewCertificatePropertiesA(PCCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTA pcsp,
  2509. BOOL *pfPropertiesChanged)
  2510. {
  2511. BOOL fRet;
  2512. CRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW cspW;
  2513. memcpy(&cspW, pcsp, sizeof(cspW));
  2514. if (!ConvertToPropPageW(
  2515. pcsp->rgPropSheetPages,
  2516. pcsp->cPropSheetPages,
  2517. &(cspW.rgPropSheetPages)))
  2518. {
  2519. return FALSE;
  2520. }
  2521. cspW.szTitle = CertUIMkWStr(pcsp->szTitle);
  2522. fRet = CryptUIDlgViewCertificatePropertiesW(&cspW, pfPropertiesChanged);
  2523. if (cspW.szTitle)
  2524. free((void *)cspW.szTitle);
  2525. //DSIE: Prefix bug 428038.
  2526. if (cspW.rgPropSheetPages)
  2527. {
  2528. FreePropSheetPagesW((LPPROPSHEETPAGEW) cspW.rgPropSheetPages, cspW.cPropSheetPages);
  2529. }
  2530. return fRet;
  2531. }
  2532. //////////////////////////////////////////////////////////////////////////////////////
  2533. //
  2534. //////////////////////////////////////////////////////////////////////////////////////
  2535. UINT
  2536. CALLBACK
  2537. GetCertificatePropertiesPagesPropPageCallback(
  2538. HWND hWnd,
  2539. UINT uMsg,
  2540. LPPROPSHEETPAGEW ppsp)
  2541. {
  2542. CERT_SETPROPERTIES_HELPER *pviewhelp = (CERT_SETPROPERTIES_HELPER *) ppsp->lParam;
  2543. if (pviewhelp->pcsp->pPropPageCallback != NULL)
  2544. {
  2545. (*(pviewhelp->pcsp->pPropPageCallback))(hWnd, uMsg, pviewhelp->pcsp->pvCallbackData);
  2546. }
  2547. if (uMsg == PSPCB_RELEASE)
  2548. {
  2549. if (pviewhelp->fSelfCleanup)
  2550. {
  2551. FreeSetPropertiesStruct((PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) pviewhelp->pcsp);
  2552. free(pviewhelp);
  2553. }
  2554. }
  2555. return TRUE;
  2556. }
  2557. //////////////////////////////////////////////////////////////////////////////////////
  2558. //
  2559. //////////////////////////////////////////////////////////////////////////////////////
  2560. BOOL WINAPI CryptUIGetCertificatePropertiesPagesW(
  2561. PCCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW pcsp,
  2562. BOOL *pfPropertiesChanged,
  2563. PROPSHEETPAGEW **prghPropPages,
  2564. DWORD *pcPropPages
  2565. )
  2566. {
  2567. BOOL fRetValue = TRUE;
  2568. HRESULT hr;
  2569. WCHAR rgwch[CRYPTUI_MAX_STRING_SIZE];
  2570. char rgch[CRYPTUI_MAX_STRING_SIZE];
  2571. CERT_SETPROPERTIES_HELPER *pviewhelp = NULL;
  2572. PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW pNewcsp;
  2573. PROPSHEETPAGEW * pClientPages = NULL;
  2574. DWORD cClientPages = 0;
  2575. *prghPropPages = NULL;
  2576. *pcPropPages = 0;
  2577. if (NULL == (pNewcsp = AllocAndCopySetPropertiesStruct(pcsp)))
  2578. {
  2579. goto ErrorReturn;
  2580. }
  2581. if (NULL == (pviewhelp = (CERT_SETPROPERTIES_HELPER *) malloc(sizeof(CERT_SETPROPERTIES_HELPER))))
  2582. {
  2583. goto ErrorReturn;
  2584. }
  2585. *pcPropPages = 2;
  2586. if (!CommonInit())
  2587. {
  2588. goto ErrorReturn;
  2589. }
  2590. //
  2591. // initialize the helper struct
  2592. //
  2593. memset (pviewhelp, 0, sizeof(CERT_SETPROPERTIES_HELPER));
  2594. pviewhelp->pcsp = pNewcsp;
  2595. pviewhelp->fSelfCleanup = TRUE;
  2596. pviewhelp->pfPropertiesChanged = pfPropertiesChanged;
  2597. pviewhelp->fGetPagesCalled = TRUE;
  2598. pviewhelp->fMMCCallbackMade = FALSE;
  2599. //
  2600. // set the properties changed flag to FALSE initially, it will be set
  2601. // to TRUE if when the dialog exits anything has been changed
  2602. //
  2603. pviewhelp->fPropertiesChanged = FALSE;
  2604. if (pviewhelp->pfPropertiesChanged != NULL)
  2605. {
  2606. *(pviewhelp->pfPropertiesChanged) = FALSE;
  2607. }
  2608. //
  2609. // get all the pages from registered clients
  2610. //
  2611. if (!GetRegisteredClientPages(&pClientPages, &cClientPages, pcsp->pCertContext))
  2612. {
  2613. goto ErrorReturn;
  2614. }
  2615. //
  2616. // Build up the list of pages we are going to use in the dialog
  2617. //
  2618. *prghPropPages = (PROPSHEETPAGEW *) malloc(((*pcPropPages) + cClientPages) * sizeof(PROPSHEETPAGEW));
  2619. if (*prghPropPages == NULL) {
  2620. goto ErrorReturn;
  2621. }
  2622. memset(*prghPropPages, 0, ((*pcPropPages) + cClientPages) * sizeof(PROPSHEETPAGEW));
  2623. (*prghPropPages)[0].dwSize = sizeof((*prghPropPages)[0]);
  2624. (*prghPropPages)[0].dwFlags = PSP_USECALLBACK;
  2625. (*prghPropPages)[0].hInstance = HinstDll;
  2626. (*prghPropPages)[0].pszTemplate = (LPWSTR) MAKEINTRESOURCE(IDD_CERTIFICATE_PROPERTIES_DIALOG);
  2627. (*prghPropPages)[0].hIcon = 0;
  2628. (*prghPropPages)[0].pszTitle = NULL;
  2629. (*prghPropPages)[0].pfnDlgProc = ViewPageSetPropertiesGeneral;
  2630. (*prghPropPages)[0].lParam = (LPARAM) pviewhelp;
  2631. (*prghPropPages)[0].pfnCallback = GetCertificatePropertiesPagesPropPageCallback;
  2632. (*prghPropPages)[0].pcRefParent = NULL;
  2633. (*prghPropPages)[1].dwSize = sizeof((*prghPropPages)[0]);
  2634. (*prghPropPages)[1].dwFlags = PSP_USECALLBACK;
  2635. (*prghPropPages)[1].hInstance = HinstDll;
  2636. (*prghPropPages)[1].pszTemplate = (LPWSTR) MAKEINTRESOURCE(IDD_CERTIFICATE_PROPERTIES_CROSSCERTS_DIALOG);
  2637. (*prghPropPages)[1].hIcon = 0;
  2638. (*prghPropPages)[1].pszTitle = NULL;
  2639. (*prghPropPages)[1].pfnDlgProc = ViewPageSetPropertiesCrossCerts;
  2640. (*prghPropPages)[1].lParam = (LPARAM) pviewhelp;
  2641. (*prghPropPages)[1].pfnCallback = NULL;
  2642. (*prghPropPages)[1].pcRefParent = NULL;
  2643. //
  2644. // copy over the registered client's pages
  2645. //
  2646. memcpy(&((*prghPropPages)[*pcPropPages]), pClientPages, cClientPages * sizeof(PROPSHEETPAGEW));
  2647. (*pcPropPages) += cClientPages;
  2648. CommonReturn:
  2649. if (pClientPages != NULL)
  2650. {
  2651. free(pClientPages);
  2652. }
  2653. return fRetValue;
  2654. ErrorReturn:
  2655. if (pNewcsp != NULL)
  2656. {
  2657. free(pNewcsp);
  2658. }
  2659. if (pviewhelp != NULL)
  2660. {
  2661. free(pviewhelp);
  2662. }
  2663. if (*prghPropPages != NULL)
  2664. {
  2665. free(*prghPropPages);
  2666. *prghPropPages = NULL;
  2667. }
  2668. fRetValue = FALSE;
  2669. goto CommonReturn;
  2670. }
  2671. //////////////////////////////////////////////////////////////////////////////////////
  2672. //
  2673. //////////////////////////////////////////////////////////////////////////////////////
  2674. BOOL WINAPI CryptUIGetCertificatePropertiesPagesA(
  2675. PCCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTA pcsp,
  2676. BOOL *pfPropertiesChanged,
  2677. PROPSHEETPAGEA **prghPropPages,
  2678. DWORD *pcPropPages
  2679. )
  2680. {
  2681. return (CryptUIGetCertificatePropertiesPagesW(
  2682. (PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) pcsp,
  2683. pfPropertiesChanged,
  2684. (PROPSHEETPAGEW**) prghPropPages,
  2685. pcPropPages));
  2686. }
  2687. //////////////////////////////////////////////////////////////////////////////////////
  2688. //
  2689. //////////////////////////////////////////////////////////////////////////////////////
  2690. BOOL WINAPI CryptUIFreeCertificatePropertiesPagesW(
  2691. PROPSHEETPAGEW *rghPropPages,
  2692. DWORD cPropPages
  2693. )
  2694. {
  2695. free(rghPropPages);
  2696. return TRUE;
  2697. }
  2698. //////////////////////////////////////////////////////////////////////////////////////
  2699. //
  2700. //////////////////////////////////////////////////////////////////////////////////////
  2701. BOOL WINAPI CryptUIFreeCertificatePropertiesPagesA(
  2702. PROPSHEETPAGEA *rghPropPages,
  2703. DWORD cPropPages
  2704. )
  2705. {
  2706. return (CryptUIFreeCertificatePropertiesPagesW((PROPSHEETPAGEW *) rghPropPages, cPropPages));
  2707. }