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

1318 lines
47 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: cvgen.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "global.hxx"
  11. #include <dbgdef.h>
  12. extern HINSTANCE HinstDll;
  13. extern HMODULE HmodRichEdit;
  14. static const HELPMAP helpmap[] = {
  15. {IDC_SUBJECT_EDIT, IDH_CERTVIEW_GENERAL_SUBJECT_EDIT},
  16. {IDC_CERT_GENERAL_ISSUEDTO_HEADER, IDH_CERTVIEW_GENERAL_SUBJECT_EDIT},
  17. {IDC_ISSUER_EDIT, IDH_CERTVIEW_GENERAL_ISSUER_EDIT},
  18. {IDC_CERT_GENERAL_ISSUEDBY_HEADER, IDH_CERTVIEW_GENERAL_ISSUER_EDIT},
  19. {IDC_ADD_TO_STORE_BUTTON, IDH_CERTVIEW_GENERAL_INSTALLCERT_BUTTON},
  20. {IDC_DISCLAIMER_BUTTON, IDH_CERTVIEW_GENERAL_DISCLAIMER_BUTTON},
  21. {IDC_ACCEPT_BUTTON, IDH_CERTVIEW_GENERAL_ACCEPT_BUTTON},
  22. {IDC_DECLINE_BUTTON, IDH_CERTVIEW_GENERAL_DECLINE_BUTTON},
  23. {IDC_GOODFOR_EDIT, IDH_CERTVIEW_GENERAL_GOODFOR_EDIT},
  24. {IDC_CERT_GENERAL_GOODFOR_HEADER, IDH_CERTVIEW_GENERAL_GOODFOR_EDIT},
  25. {IDC_CERT_GENERAL_VALID_EDIT, IDH_CERTVIEW_GENERAL_VALID_EDIT},
  26. {IDC_CERT_PRIVATE_KEY_EDIT, IDH_CERTVIEW_GENERAL_PRIVATE_KEY_INFO}
  27. };
  28. typedef struct {
  29. void * pszString;
  30. int offset;
  31. BOOL fUnicode;
  32. } STREAMIN_HELP_STRUCT;
  33. //////////////////////////////////////////////////////////////////////////////////////
  34. //
  35. //////////////////////////////////////////////////////////////////////////////////////
  36. DWORD CALLBACK MyEditStreamCallback(
  37. DWORD_PTR dwCookie, // application-defined value
  38. LPBYTE pbBuff, // pointer to a buffer
  39. LONG cb, // number of bytes to read or write
  40. LONG *pcb // pointer to number of bytes transferred
  41. )
  42. {
  43. BYTE *pByte;
  44. DWORD cbResource;
  45. STREAMIN_HELP_STRUCT *pHelpStruct;
  46. pHelpStruct = (STREAMIN_HELP_STRUCT *) dwCookie;
  47. pByte = (BYTE *)pHelpStruct->pszString;
  48. if (pHelpStruct->fUnicode)
  49. {
  50. cbResource = wcslen((LPWSTR) pHelpStruct->pszString) * sizeof(WCHAR);
  51. }
  52. else
  53. {
  54. cbResource = strlen((LPSTR) pHelpStruct->pszString);
  55. }
  56. if (pHelpStruct->offset == (int) cbResource)
  57. {
  58. *pcb = 0;
  59. }
  60. else if ((cb >= (int) cbResource) && (pHelpStruct->offset == 0))
  61. {
  62. memcpy(pbBuff, pByte, cbResource);
  63. *pcb = cbResource;
  64. pHelpStruct->offset = cbResource;
  65. }
  66. else if (cb >= (((int)cbResource) - pHelpStruct->offset))
  67. {
  68. memcpy(pbBuff, pByte + pHelpStruct->offset, cbResource - pHelpStruct->offset);
  69. *pcb = cbResource - pHelpStruct->offset;
  70. }
  71. else
  72. {
  73. memcpy(pbBuff, pByte + pHelpStruct->offset, cb);
  74. *pcb = cb;
  75. pHelpStruct->offset += cb;
  76. }
  77. return 0;
  78. }
  79. //////////////////////////////////////////////////////////////////////////////////////
  80. //
  81. //////////////////////////////////////////////////////////////////////////////////////
  82. static LRESULT StreamInWrapper(HWND hwndEdit, void * pszString, BOOL fUnicode)
  83. {
  84. EDITSTREAM editStream;
  85. char szBuffer[2048];
  86. STREAMIN_HELP_STRUCT helpStruct;
  87. LRESULT ret;
  88. BOOL fOKToUseRichEdit20 = fRichedit20Usable(hwndEdit);
  89. memset(&editStream, 0, sizeof(EDITSTREAM));
  90. editStream.pfnCallback = MyEditStreamCallback;
  91. editStream.dwCookie = (DWORD_PTR) &helpStruct;
  92. SendMessageA(hwndEdit, EM_SETSEL, 0, -1);
  93. SendMessageA(hwndEdit, EM_SETSEL, -1, 0);
  94. if (fUnicode && fRichedit20Exists && fOKToUseRichEdit20)
  95. {
  96. helpStruct.pszString = pszString;
  97. helpStruct.offset = 0;
  98. helpStruct.fUnicode = TRUE;
  99. return (SendMessage(hwndEdit, EM_STREAMIN, SF_TEXT | SFF_SELECTION | SF_UNICODE, (LPARAM) &editStream));
  100. }
  101. else if (fUnicode)
  102. {
  103. LPSTR psz = CertUIMkMBStr((LPWSTR) pszString);
  104. helpStruct.pszString = psz;
  105. helpStruct.offset = 0;
  106. helpStruct.fUnicode = FALSE;
  107. ret = (SendMessage(hwndEdit, EM_STREAMIN, SF_TEXT | SFF_SELECTION, (LPARAM) &editStream));
  108. free(psz);
  109. return (ret);
  110. }
  111. else
  112. {
  113. helpStruct.pszString = pszString;
  114. helpStruct.offset = 0;
  115. helpStruct.fUnicode = FALSE;
  116. return (SendMessage(hwndEdit, EM_STREAMIN, SF_TEXT | SFF_SELECTION, (LPARAM) &editStream));
  117. }
  118. }
  119. //////////////////////////////////////////////////////////////////////////////////////
  120. //
  121. //////////////////////////////////////////////////////////////////////////////////////
  122. static void LoadAndDisplayString(HWND hWndEditGoodFor, UINT nId, BOOL *pfFirst)
  123. {
  124. WCHAR rgwch[CRYPTUI_MAX_STRING_SIZE];
  125. LoadStringU(HinstDll, nId, rgwch, ARRAYSIZE(rgwch));
  126. if (*pfFirst)
  127. {
  128. *pfFirst = FALSE;
  129. }
  130. else
  131. {
  132. StreamInWrapper(hWndEditGoodFor, "\n", FALSE);
  133. }
  134. StreamInWrapper(hWndEditGoodFor, rgwch, TRUE);
  135. }
  136. //////////////////////////////////////////////////////////////////////////////////////
  137. //
  138. //////////////////////////////////////////////////////////////////////////////////////
  139. static void AddUsagesToEditBox(HWND hWndEditGoodFor, CERT_VIEW_HELPER *pviewhelp)
  140. {
  141. BOOL fIndividualCodeSigning = FALSE;
  142. BOOL fCommercialCodeSigning = FALSE;
  143. BOOL fVirusString = FALSE;
  144. BOOL fTimeStamping = FALSE;
  145. BOOL fSGC = FALSE;
  146. BOOL fIPSec = FALSE;
  147. int goodForIndex = 0;
  148. DWORD i;
  149. BOOL *rgfOIDProcessed;
  150. PARAFORMAT paraFormat;
  151. PCCRYPT_OID_INFO pOIDInfo;
  152. BOOL fFirst = TRUE;
  153. if (NULL == (rgfOIDProcessed = (BOOL *) malloc(pviewhelp->cUsages * sizeof(BOOL))))
  154. {
  155. return;
  156. }
  157. for (i=0; i<pviewhelp->cUsages; i++)
  158. {
  159. rgfOIDProcessed[i] = FALSE;
  160. }
  161. //
  162. // clear the window
  163. //
  164. SetWindowTextU(hWndEditGoodFor, NULL);
  165. //
  166. // go through all the oids that this certificate was validated for and
  167. // add usage bullets to the list boxes, OR, if it was not validated for any
  168. // usages then put up the nousages string
  169. //
  170. for (i=0; i<pviewhelp->cUsages; i++)
  171. {
  172. if ((strcmp(szOID_SERVER_GATED_CRYPTO, pviewhelp->rgUsages[i]) == 0) ||
  173. (strcmp(szOID_SGC_NETSCAPE, pviewhelp->rgUsages[i]) == 0))
  174. {
  175. if (!fSGC)
  176. {
  177. LoadAndDisplayString(hWndEditGoodFor, ID_RTF_SGC, &fFirst);
  178. fSGC = TRUE;
  179. }
  180. rgfOIDProcessed[i] = TRUE;
  181. }
  182. else if ((strcmp(szOID_PKIX_KP_TIMESTAMP_SIGNING, pviewhelp->rgUsages[i]) == 0) ||
  183. (strcmp(szOID_KP_TIME_STAMP_SIGNING, pviewhelp->rgUsages[i]) == 0))
  184. {
  185. if (!fTimeStamping)
  186. {
  187. LoadAndDisplayString(hWndEditGoodFor, ID_RTF_TIMESTAMP, &fFirst);
  188. fTimeStamping = TRUE;
  189. }
  190. rgfOIDProcessed[i] = TRUE;
  191. }
  192. else if (strcmp(szOID_KP_CTL_USAGE_SIGNING, pviewhelp->rgUsages[i]) == 0)
  193. {
  194. LoadAndDisplayString(hWndEditGoodFor, ID_RTF_CTLSIGN, &fFirst);
  195. rgfOIDProcessed[i] = TRUE;
  196. }
  197. else if (strcmp("1.3.6.1.4.1.311.10.3.4", pviewhelp->rgUsages[i]) == 0) // EFS
  198. {
  199. LoadAndDisplayString(hWndEditGoodFor, ID_RTF_EFS, &fFirst);
  200. rgfOIDProcessed[i] = TRUE;
  201. }
  202. else if (strcmp(szOID_PKIX_KP_SERVER_AUTH, pviewhelp->rgUsages[i]) == 0)
  203. {
  204. LoadAndDisplayString(hWndEditGoodFor, ID_RTF_SERVERAUTH, &fFirst);
  205. rgfOIDProcessed[i] = TRUE;
  206. }
  207. else if (strcmp(szOID_PKIX_KP_CLIENT_AUTH, pviewhelp->rgUsages[i]) == 0)
  208. {
  209. LoadAndDisplayString(hWndEditGoodFor, ID_RTF_CLIENTAUTH, &fFirst);
  210. rgfOIDProcessed[i] = TRUE;
  211. }
  212. else if (strcmp(szOID_PKIX_KP_EMAIL_PROTECTION, pviewhelp->rgUsages[i]) == 0)
  213. {
  214. //LoadAndDisplayString(hWndEditGoodFor, ID_RTF_EMAIL3, &fFirst);
  215. //LoadAndDisplayString(hWndEditGoodFor, ID_RTF_EMAIL2, &fFirst);
  216. LoadAndDisplayString(hWndEditGoodFor, ID_RTF_EMAIL1, &fFirst);
  217. rgfOIDProcessed[i] = TRUE;
  218. }
  219. else if ((strcmp(szOID_PKIX_KP_CODE_SIGNING, pviewhelp->rgUsages[i]) == 0) ||
  220. (strcmp("1.3.6.1.4.1.311.2.1.22", pviewhelp->rgUsages[i]) == 0))
  221. {
  222. if (!fCommercialCodeSigning)
  223. {
  224. if (strcmp(szOID_PKIX_KP_CODE_SIGNING, pviewhelp->rgUsages[i]) == 0)
  225. {
  226. LoadAndDisplayString(hWndEditGoodFor, ID_RTF_CODESIGN_COMMERCIAL_PKIX, &fFirst);
  227. }
  228. else
  229. {
  230. LoadAndDisplayString(hWndEditGoodFor, ID_RTF_CODESIGN_COMMERCIAL, &fFirst);
  231. }
  232. if (!fIndividualCodeSigning)
  233. {
  234. LoadAndDisplayString(hWndEditGoodFor, ID_RTF_CODESIGN_GENERAL, &fFirst);
  235. }
  236. fCommercialCodeSigning = TRUE;
  237. }
  238. rgfOIDProcessed[i] = TRUE;
  239. }
  240. else if (strcmp("1.3.6.1.4.1.311.2.1.21", pviewhelp->rgUsages[i]) == 0)
  241. {
  242. LoadAndDisplayString(hWndEditGoodFor, ID_RTF_CODESIGN_INDIVIDUAL, &fFirst);
  243. if (!fCommercialCodeSigning)
  244. {
  245. LoadAndDisplayString(hWndEditGoodFor, ID_RTF_CODESIGN_GENERAL, &fFirst);
  246. }
  247. fIndividualCodeSigning = TRUE;
  248. rgfOIDProcessed[i] = TRUE;
  249. }
  250. else if ((strcmp(szOID_PKIX_KP_IPSEC_END_SYSTEM, pviewhelp->rgUsages[i]) == 0) ||
  251. (strcmp(szOID_PKIX_KP_IPSEC_TUNNEL, pviewhelp->rgUsages[i]) == 0) ||
  252. (strcmp(szOID_PKIX_KP_IPSEC_USER, pviewhelp->rgUsages[i]) == 0) ||
  253. (strcmp("1.3.6.1.5.5.8.2.2", pviewhelp->rgUsages[i]) == 0))
  254. {
  255. if (!fIPSec)
  256. {
  257. LoadAndDisplayString(hWndEditGoodFor, ID_RTF_IPSEC, &fFirst);
  258. fIPSec = TRUE;
  259. }
  260. rgfOIDProcessed[i] = TRUE;
  261. }
  262. }
  263. //
  264. // re walk the oids to add the ones that were not processed,
  265. // if they weren't processed that means we don't have a pre-defined
  266. // string for them, so just add the oid
  267. //
  268. for (i=0; i<pviewhelp->cUsages; i++)
  269. {
  270. if (!rgfOIDProcessed[i])
  271. {
  272. pOIDInfo = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, pviewhelp->rgUsages[i], 0);
  273. if (pOIDInfo != NULL)
  274. {
  275. if (fFirst)
  276. {
  277. fFirst = FALSE;
  278. }
  279. else
  280. {
  281. StreamInWrapper(hWndEditGoodFor, "\n", FALSE);
  282. }
  283. StreamInWrapper(hWndEditGoodFor, (void *) pOIDInfo->pwszName, TRUE);
  284. }
  285. else
  286. {
  287. if (fFirst)
  288. {
  289. fFirst = FALSE;
  290. }
  291. else
  292. {
  293. StreamInWrapper(hWndEditGoodFor, "\n", FALSE);
  294. }
  295. StreamInWrapper(hWndEditGoodFor, pviewhelp->rgUsages[i], FALSE);
  296. }
  297. }
  298. }
  299. free(rgfOIDProcessed);
  300. memset(&paraFormat, 0, sizeof(paraFormat));
  301. paraFormat.cbSize= sizeof(paraFormat);
  302. paraFormat.dwMask = PFM_NUMBERING;
  303. paraFormat.wNumbering = PFN_BULLET;
  304. SendMessage(hWndEditGoodFor, EM_SETSEL, 0, -1);
  305. SendMessage(hWndEditGoodFor, EM_SETPARAFORMAT, 0, (LPARAM) &paraFormat);
  306. SendMessage(hWndEditGoodFor, EM_SETSEL, -1, 0);
  307. SendMessage(hWndEditGoodFor, EM_HIDESELECTION, (WPARAM) TRUE, (LPARAM) FALSE);
  308. }
  309. //////////////////////////////////////////////////////////////////////////////////////
  310. //
  311. //////////////////////////////////////////////////////////////////////////////////////
  312. static int GetEditControlMaxLineWidth (HWND hwndEdit, HDC hdc, int cline)
  313. {
  314. int index;
  315. int line;
  316. int charwidth;
  317. int maxwidth = 0;
  318. CHAR szMaxBuffer[1024];
  319. WCHAR wsz[1024];
  320. TEXTRANGEA tr;
  321. SIZE size;
  322. tr.lpstrText = szMaxBuffer;
  323. for ( line = 0; line < cline; line++ )
  324. {
  325. index = (int)SendMessageA(hwndEdit, EM_LINEINDEX, (WPARAM)line, 0);
  326. charwidth = (int)SendMessageA(hwndEdit, EM_LINELENGTH, (WPARAM)index, 0);
  327. tr.chrg.cpMin = index;
  328. tr.chrg.cpMax = index + charwidth;
  329. SendMessageA(hwndEdit, EM_GETTEXTRANGE, 0, (LPARAM)&tr);
  330. wsz[0] = NULL;
  331. MultiByteToWideChar(0, 0, (const char *)tr.lpstrText, -1, &wsz[0], 1024);
  332. if (wsz[0])
  333. {
  334. GetTextExtentPoint32W(hdc, &wsz[0], charwidth, &size);
  335. if ( (size.cx+2) > maxwidth )
  336. {
  337. maxwidth = size.cx+2;
  338. }
  339. }
  340. }
  341. return( maxwidth );
  342. }
  343. //////////////////////////////////////////////////////////////////////////////////////
  344. //
  345. //////////////////////////////////////////////////////////////////////////////////////
  346. static void ResizeEditControl(HWND hwndDlg, HWND hwnd, BOOL fResizeHeight, BOOL fResizeWidth, RECT originalRect)
  347. {
  348. RECT rect;
  349. TEXTMETRIC tm;
  350. HDC hdc;
  351. int cline;
  352. int currentHeight;
  353. int newHeight;
  354. int newWidth;
  355. int totalRowHeight;
  356. POINT pointInFirstRow;
  357. POINT pointInSecondRow;
  358. int secondLineCharIndex;
  359. int i;
  360. SetWindowPos(hwnd,
  361. NULL,
  362. 0,
  363. 0,
  364. originalRect.right-originalRect.left,
  365. originalRect.bottom-originalRect.top,
  366. SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
  367. hdc = GetDC(hwnd);
  368. if ((hdc == NULL) && fResizeWidth)
  369. {
  370. return;
  371. }
  372. //
  373. // HACK ALERT, believe it or not there is no way to get the height of the current
  374. // font in the edit control, so get the position a character in the first row and the position
  375. // of a character in the second row, and do the subtraction to get the
  376. // height of the font
  377. //
  378. SendMessageA(hwnd, EM_POSFROMCHAR, (WPARAM) &pointInFirstRow, (LPARAM) 0);
  379. //
  380. // HACK ON TOP OF HACK ALERT,
  381. // since there may not be a second row in the edit box, keep reducing the width
  382. // by half until the first row falls over into the second row, then get the position
  383. // of the first char in the second row and finally reset the edit box size back to
  384. // it's original size
  385. //
  386. secondLineCharIndex = (int)SendMessageA(hwnd, EM_LINEINDEX, (WPARAM) 1, (LPARAM) 0);
  387. if (secondLineCharIndex == -1)
  388. {
  389. for (i=0; i<20; i++)
  390. {
  391. GetWindowRect(hwnd, &rect);
  392. SetWindowPos( hwnd,
  393. NULL,
  394. 0,
  395. 0,
  396. (rect.right-rect.left)/2,
  397. rect.bottom-rect.top,
  398. SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
  399. secondLineCharIndex = (int)SendMessageA(hwnd, EM_LINEINDEX, (WPARAM) 1, (LPARAM) 0);
  400. if (secondLineCharIndex != -1)
  401. {
  402. break;
  403. }
  404. }
  405. if (secondLineCharIndex == -1)
  406. {
  407. // if we failed after twenty tries just reset the control to its original size
  408. // and get the heck outa here!!
  409. SetWindowPos(hwnd,
  410. NULL,
  411. 0,
  412. 0,
  413. originalRect.right-originalRect.left,
  414. originalRect.bottom-originalRect.top,
  415. SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
  416. if (hdc != NULL)
  417. {
  418. ReleaseDC(hwnd, hdc);
  419. }
  420. return;
  421. }
  422. SendMessageA(hwnd, EM_POSFROMCHAR, (WPARAM) &pointInSecondRow, (LPARAM) secondLineCharIndex);
  423. SetWindowPos(hwnd,
  424. NULL,
  425. 0,
  426. 0,
  427. originalRect.right-originalRect.left,
  428. originalRect.bottom-originalRect.top,
  429. SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
  430. }
  431. else
  432. {
  433. SendMessageA(hwnd, EM_POSFROMCHAR, (WPARAM) &pointInSecondRow, (LPARAM) secondLineCharIndex);
  434. }
  435. //
  436. // if we need to resize the height then do it
  437. //
  438. if (fResizeHeight)
  439. {
  440. //
  441. // Calculate the new height needed
  442. //
  443. totalRowHeight = pointInSecondRow.y - pointInFirstRow.y;
  444. cline = (int)SendMessageA(hwnd, EM_GETLINECOUNT, 0, 0);
  445. currentHeight = originalRect.bottom - originalRect.top;
  446. // if the height required is greater than the previous height
  447. // then resize to an integral line height less than current height
  448. if ((cline * totalRowHeight) > currentHeight)
  449. {
  450. newHeight = (currentHeight / totalRowHeight) * totalRowHeight;
  451. }
  452. else
  453. {
  454. newHeight = cline * totalRowHeight;
  455. }
  456. }
  457. else
  458. {
  459. newHeight = rect.bottom - rect.top;
  460. }
  461. if (fResizeWidth)
  462. {
  463. newWidth = GetEditControlMaxLineWidth(hwnd, hdc, cline);
  464. if (newWidth > (originalRect.right - originalRect.left))
  465. {
  466. newWidth = originalRect.right - originalRect.left;
  467. }
  468. }
  469. else
  470. {
  471. newWidth = originalRect.right - originalRect.left;
  472. }
  473. SetWindowPos(hwnd, NULL, 0, 0, newWidth, newHeight, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
  474. if (hdc != NULL)
  475. {
  476. ReleaseDC(hwnd, hdc);
  477. }
  478. }
  479. //////////////////////////////////////////////////////////////////////////////////////
  480. //
  481. //////////////////////////////////////////////////////////////////////////////////////
  482. static BOOL CertificateHasPrivateKey(PCCERT_CONTEXT pccert)
  483. {
  484. DWORD cb = 0;
  485. return (CertGetCertificateContextProperty(pccert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &cb));
  486. }
  487. //////////////////////////////////////////////////////////////////////////////////////
  488. //
  489. //////////////////////////////////////////////////////////////////////////////////////
  490. INT_PTR APIENTRY ViewPageGeneral(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  491. {
  492. DWORD i;
  493. PCCERT_CONTEXT pccert;
  494. ENLINK * penlink;
  495. PROPSHEETPAGE * ps;
  496. CERT_VIEW_HELPER * pviewhelp;
  497. WCHAR rgwch[CRYPTUI_MAX_STRING_SIZE];
  498. DWORD cb;
  499. HWND hWndListView;
  500. HWND hwnd;
  501. HWND hWndEdit;
  502. LPNMLISTVIEW pnmv;
  503. LPSTR pszSubjectURL=NULL;
  504. LPSTR pszIssuerURL=NULL;
  505. CHARFORMAT chFormat;
  506. HWND hWndIssuerEdit;
  507. HWND hWndSubjectEdit;
  508. HWND hWndGoodForEdit;
  509. PLINK_SUBCLASS_DATA plsd;
  510. HANDLE hIcon;
  511. RECT tempRect;
  512. DWORD dwCertAccessProperty;
  513. int buttonPos = 1;
  514. LPWSTR pwszDateString;
  515. WCHAR szFindText[CRYPTUI_MAX_STRING_SIZE];
  516. FINDTEXTEX findText;
  517. WCHAR errorString[CRYPTUI_MAX_STRING_SIZE];
  518. WCHAR errorTitle[CRYPTUI_MAX_STRING_SIZE];
  519. BOOL fPrivateKeyExists;
  520. LPHELPINFO lpHelpInfo;
  521. HELPINFO helpInfo;
  522. LPWSTR pwszIssuerNameString = NULL;
  523. LPWSTR pwszSubjectNameString = NULL;
  524. switch ( msg ) {
  525. case WM_INITDIALOG:
  526. //
  527. // save the pviewhelp struct in DWL_USER so it can always be accessed
  528. //
  529. ps = (PROPSHEETPAGE *) lParam;
  530. pviewhelp = (CERT_VIEW_HELPER *) (ps->lParam);
  531. pccert = pviewhelp->pcvp->pCertContext;
  532. SetWindowLongPtr(hwndDlg, DWLP_USER, (DWORD_PTR) pviewhelp);
  533. pviewhelp->hwndGeneralPage = hwndDlg;
  534. //
  535. // check to see if this certificate has a private key with it
  536. //
  537. if (CertificateHasPrivateKey(pccert))
  538. {
  539. LoadStringU(HinstDll, IDS_PRIVATE_KEY_EXISTS, rgwch, ARRAYSIZE(rgwch));
  540. CryptUISetRicheditTextW(hwndDlg, IDC_CERT_PRIVATE_KEY_EDIT, rgwch);
  541. if (NULL != (plsd = (PLINK_SUBCLASS_DATA) malloc(sizeof(LINK_SUBCLASS_DATA))))
  542. {
  543. memset(plsd, 0, sizeof(plsd));
  544. plsd->hwndParent = hwndDlg;
  545. plsd->uId = IDC_CERT_PRIVATE_KEY_EDIT;
  546. LoadStringU(HinstDll, IDS_PRIVATE_KEY_EXISTS_TOOLTIP, rgwch, ARRAYSIZE(rgwch));
  547. plsd->pszURL = CertUIMkMBStr(rgwch);
  548. plsd->fNoCOM = pviewhelp->fNoCOM;
  549. plsd->fUseArrowInsteadOfHand = TRUE;
  550. CertSubclassEditControlForLink(hwndDlg, GetDlgItem(hwndDlg, IDC_CERT_PRIVATE_KEY_EDIT), plsd);
  551. }
  552. fPrivateKeyExists = TRUE;
  553. }
  554. else
  555. {
  556. ShowWindow(GetDlgItem(hwndDlg, IDC_CERT_PRIVATE_KEY_EDIT), SW_HIDE);
  557. fPrivateKeyExists = FALSE;
  558. }
  559. //
  560. // Initialize the CCertificateBmp
  561. //
  562. pviewhelp->pCCertBmp->SetWindow(hwndDlg);
  563. pviewhelp->pCCertBmp->SetHinst(HinstDll);
  564. pviewhelp->pCCertBmp->SetRevoked(pviewhelp->cUsages == 0);
  565. pviewhelp->pCCertBmp->SetCertContext(pccert, fPrivateKeyExists);
  566. pviewhelp->pCCertBmp->DoSubclass();
  567. //
  568. // deal with button states and placements
  569. //
  570. if (!(CRYPTUI_ACCEPT_DECLINE_STYLE & pviewhelp->pcvp->dwFlags))
  571. {
  572. EnableWindow(GetDlgItem(hwndDlg, IDC_ACCEPT_BUTTON), FALSE);
  573. ShowWindow(GetDlgItem(hwndDlg, IDC_ACCEPT_BUTTON), SW_HIDE);
  574. EnableWindow(GetDlgItem(hwndDlg, IDC_DECLINE_BUTTON), FALSE);
  575. ShowWindow(GetDlgItem(hwndDlg, IDC_DECLINE_BUTTON), SW_HIDE);
  576. //
  577. // check to see if there is a disclaimer in the cert
  578. //
  579. // DSIE: Bug 364742
  580. if (!IsOKToDisplayCPS(pccert, pviewhelp->dwChainError))
  581. {
  582. EnableWindow(GetDlgItem(hwndDlg, IDC_DISCLAIMER_BUTTON), FALSE);
  583. pviewhelp->fCPSDisplayed = FALSE;
  584. }
  585. else
  586. {
  587. EnableWindow(GetDlgItem(hwndDlg, IDC_DISCLAIMER_BUTTON), TRUE);
  588. pviewhelp->fCPSDisplayed = TRUE;
  589. }
  590. //
  591. // for the "Install Certificate" button, get the CERT_ACCESS_STATE_PROP_ID
  592. // and check it
  593. //
  594. cb = sizeof(DWORD);
  595. CertGetCertificateContextProperty(
  596. pccert,
  597. CERT_ACCESS_STATE_PROP_ID,
  598. (void *) &dwCertAccessProperty,
  599. &cb);
  600. if (pviewhelp->pcvp->dwFlags & CRYPTUI_ENABLE_ADDTOSTORE)
  601. {
  602. ShowWindow(GetDlgItem(hwndDlg, IDC_ADD_TO_STORE_BUTTON), SW_SHOW);
  603. }
  604. else if(pviewhelp->pcvp->dwFlags & CRYPTUI_DISABLE_ADDTOSTORE)
  605. {
  606. EnableWindow(GetDlgItem(hwndDlg, IDC_ADD_TO_STORE_BUTTON), FALSE);
  607. ShowWindow(GetDlgItem(hwndDlg, IDC_ADD_TO_STORE_BUTTON), SW_HIDE);
  608. }
  609. else
  610. {
  611. EnableWindow(GetDlgItem(hwndDlg, IDC_ADD_TO_STORE_BUTTON),
  612. (dwCertAccessProperty & CERT_ACCESS_STATE_SYSTEM_STORE_FLAG) ? FALSE : TRUE);
  613. ShowWindow(
  614. GetDlgItem(hwndDlg, IDC_ADD_TO_STORE_BUTTON),
  615. (dwCertAccessProperty & CERT_ACCESS_STATE_SYSTEM_STORE_FLAG) ? SW_HIDE : SW_SHOW);
  616. }
  617. }
  618. else
  619. {
  620. EnableWindow(GetDlgItem(hwndDlg, IDC_DISCLAIMER_BUTTON), FALSE);
  621. ShowWindow(GetDlgItem(hwndDlg, IDC_DISCLAIMER_BUTTON), SW_HIDE);
  622. EnableWindow(GetDlgItem(hwndDlg, IDC_ADD_TO_STORE_BUTTON), FALSE);
  623. ShowWindow(GetDlgItem(hwndDlg, IDC_ADD_TO_STORE_BUTTON), SW_HIDE);
  624. pviewhelp->fAccept = FALSE;
  625. }
  626. hWndGoodForEdit = GetDlgItem(hwndDlg, IDC_GOODFOR_EDIT);
  627. //
  628. // set the original rect fields of the usage edits in the viewhelp struct
  629. // so that they can be used any time a resize is needed
  630. //
  631. GetWindowRect(hWndGoodForEdit, &pviewhelp->goodForOriginalRect);
  632. //
  633. // fill in the "This certificate is intended to" bullet list
  634. //
  635. AddUsagesToEditBox(
  636. hWndGoodForEdit,
  637. pviewhelp);
  638. //
  639. // resize the edit controls so that they are an integral number of lines
  640. //
  641. ResizeEditControl(hwndDlg, hWndGoodForEdit, TRUE, FALSE, pviewhelp->goodForOriginalRect);
  642. //
  643. // do the arrow subclass on the usage edit boxes
  644. //
  645. // CertSubclassEditControlForArrowCursor(hWndGoodForEdit);
  646. //
  647. // if there are no valid usages or we couldn't validate because there wasn't
  648. // enough information, then hide the usage edit controls so we can
  649. // display more text, and tell the CCertBmp
  650. //
  651. if (pviewhelp->pwszErrorString != NULL)
  652. {
  653. EnableWindow(hWndGoodForEdit, FALSE);
  654. ShowWindow(hWndGoodForEdit, SW_HIDE);
  655. ShowWindow(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_GOODFOR_HEADER), SW_HIDE);
  656. ShowWindow(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_ERROR_EDIT), SW_SHOW);
  657. ShowWindow(GetDlgItem(hwndDlg, IDC_CERT_ISSUER_WARNING_EDIT), SW_HIDE);
  658. pviewhelp->pCCertBmp->SetChainError(pviewhelp->dwChainError, IsTrueErrorString(pviewhelp),
  659. (pviewhelp->dwChainError == 0) && (pviewhelp->cUsages == NULL));
  660. CryptUISetRicheditTextW(hwndDlg, IDC_CERT_GENERAL_ERROR_EDIT, pviewhelp->pwszErrorString);
  661. }
  662. else
  663. {
  664. ShowWindow(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_ERROR_EDIT), SW_HIDE);
  665. if (pviewhelp->fCPSDisplayed)
  666. {
  667. ShowWindow(GetDlgItem(hwndDlg, IDC_CERT_ISSUER_WARNING_EDIT), SW_SHOW);
  668. }
  669. else
  670. {
  671. ShowWindow(GetDlgItem(hwndDlg, IDC_CERT_ISSUER_WARNING_EDIT), SW_HIDE);
  672. }
  673. }
  674. hWndIssuerEdit = GetDlgItem(hwndDlg, IDC_ISSUER_EDIT);
  675. hWndSubjectEdit = GetDlgItem(hwndDlg, IDC_SUBJECT_EDIT);
  676. #if (0) //DISE: Bug 383855
  677. //
  678. // set the subject and issuer name
  679. //
  680. CertGetNameStringW(
  681. pccert,
  682. CERT_NAME_SIMPLE_DISPLAY_TYPE,
  683. 0,//CERT_NAME_ISSUER_FLAG,
  684. NULL,
  685. rgwch,
  686. ARRAYSIZE(rgwch));
  687. CryptUISetRicheditTextW(hwndDlg, IDC_SUBJECT_EDIT, rgwch);
  688. #else
  689. pwszSubjectNameString = GetDisplayNameString(pccert, 0);
  690. CryptUISetRicheditTextW(hwndDlg, IDC_SUBJECT_EDIT, pwszSubjectNameString);
  691. if (NULL != pwszSubjectNameString)
  692. {
  693. free(pwszSubjectNameString);
  694. }
  695. #endif
  696. #if (0) //DISE: Bug 383855
  697. CertGetNameStringW(
  698. pccert,
  699. CERT_NAME_SIMPLE_DISPLAY_TYPE,
  700. CERT_NAME_ISSUER_FLAG,
  701. NULL,
  702. rgwch,
  703. ARRAYSIZE(rgwch));
  704. CryptUISetRicheditTextW(hwndDlg, IDC_ISSUER_EDIT, rgwch);
  705. #else
  706. pwszIssuerNameString = GetDisplayNameString(pccert, CERT_NAME_ISSUER_FLAG);
  707. CryptUISetRicheditTextW(hwndDlg, IDC_ISSUER_EDIT, pwszIssuerNameString);
  708. if (NULL != pwszIssuerNameString)
  709. {
  710. free(pwszIssuerNameString);
  711. }
  712. #endif
  713. //
  714. // resize the name edit controls so that they just encapsulate the names
  715. //
  716. GetWindowRect(hWndSubjectEdit, &tempRect);
  717. ResizeEditControl(hwndDlg, hWndSubjectEdit, TRUE, FALSE, tempRect);
  718. GetWindowRect(hWndIssuerEdit, &tempRect);
  719. ResizeEditControl(hwndDlg, hWndIssuerEdit, TRUE, FALSE, tempRect);
  720. //
  721. // check if this should look like a link or not, if so, then set color and underline
  722. //
  723. // DSIE: Bug 367720.
  724. if (AllocAndGetSubjectURL(&pszSubjectURL, pccert) &&
  725. IsOKToFormatAsLinkA(pszSubjectURL, pviewhelp->dwChainError))
  726. {
  727. memset(&chFormat, 0, sizeof(chFormat));
  728. chFormat.cbSize = sizeof(chFormat);
  729. chFormat.dwMask = CFM_UNDERLINE | CFM_COLOR;
  730. chFormat.dwEffects = CFE_UNDERLINE;
  731. chFormat.crTextColor = RGB(0,0,255);
  732. SendMessageA(hWndSubjectEdit, EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &chFormat);
  733. if (NULL != (plsd = (PLINK_SUBCLASS_DATA) malloc(sizeof(LINK_SUBCLASS_DATA))))
  734. {
  735. memset(plsd, 0, sizeof(plsd));
  736. plsd->hwndParent = hwndDlg;
  737. plsd->uId = IDC_SUBJECT_EDIT;
  738. plsd->pszURL = pszSubjectURL;
  739. plsd->fNoCOM = pviewhelp->fNoCOM;
  740. plsd->fUseArrowInsteadOfHand = FALSE;
  741. CertSubclassEditControlForLink(hwndDlg, hWndSubjectEdit, plsd);
  742. pviewhelp->fSubjectDisplayedAsLink = TRUE;
  743. }
  744. else
  745. {
  746. free(pszSubjectURL);
  747. CertSubclassEditControlForArrowCursor(hWndSubjectEdit);
  748. }
  749. }
  750. else
  751. {
  752. if (pszSubjectURL)
  753. {
  754. free(pszSubjectURL);
  755. }
  756. CertSubclassEditControlForArrowCursor(hWndSubjectEdit);
  757. }
  758. //
  759. // check if this should look like a link or not, if so, then set color and underline
  760. //
  761. // DSIE: Bug 367720.
  762. if (AllocAndGetIssuerURL(&pszIssuerURL, pccert) &&
  763. IsOKToFormatAsLinkA(pszIssuerURL, pviewhelp->dwChainError))
  764. {
  765. memset(&chFormat, 0, sizeof(chFormat));
  766. chFormat.cbSize = sizeof(chFormat);
  767. chFormat.dwMask = CFM_UNDERLINE | CFM_COLOR;
  768. chFormat.dwEffects = CFE_UNDERLINE;
  769. chFormat.crTextColor = RGB(0,0,255);
  770. SendMessageA(hWndIssuerEdit, EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &chFormat);
  771. if (NULL != (plsd = (PLINK_SUBCLASS_DATA) malloc(sizeof(LINK_SUBCLASS_DATA))))
  772. {
  773. memset(plsd, 0, sizeof(plsd));
  774. plsd->hwndParent = hwndDlg;
  775. plsd->uId = IDC_ISSUER_EDIT;
  776. plsd->pszURL = pszIssuerURL;
  777. plsd->fNoCOM = pviewhelp->fNoCOM;
  778. plsd->fUseArrowInsteadOfHand = FALSE;
  779. CertSubclassEditControlForLink(hwndDlg, hWndIssuerEdit, plsd);
  780. pviewhelp->fIssuerDisplayedAsLink = TRUE;
  781. }
  782. else
  783. {
  784. free(pszIssuerURL);
  785. CertSubclassEditControlForArrowCursor(hWndIssuerEdit);
  786. }
  787. }
  788. else
  789. {
  790. if (pszIssuerURL)
  791. {
  792. free(pszIssuerURL);
  793. }
  794. CertSubclassEditControlForArrowCursor(hWndIssuerEdit);
  795. }
  796. //
  797. // set the text in all the header edit boxes
  798. //
  799. LoadStringU(HinstDll, IDS_CERTIFICATEINFORMATION, rgwch, ARRAYSIZE(rgwch));
  800. CryptUISetRicheditTextW(hwndDlg, IDC_CERT_GENERAL_HEADER, rgwch);
  801. LoadStringU(HinstDll, IDS_FORUSEWITH, rgwch, ARRAYSIZE(rgwch));
  802. CryptUISetRicheditTextW(hwndDlg, IDC_CERT_GENERAL_GOODFOR_HEADER, rgwch);
  803. LoadStringU(HinstDll, IDS_ISSUEDTO, rgwch, ARRAYSIZE(rgwch));
  804. CryptUISetRicheditTextW(hwndDlg, IDC_CERT_GENERAL_ISSUEDTO_HEADER, rgwch);
  805. LoadStringU(HinstDll, IDS_ISSUEDBY, rgwch, ARRAYSIZE(rgwch));
  806. CryptUISetRicheditTextW(hwndDlg, IDC_CERT_GENERAL_ISSUEDBY_HEADER, rgwch);
  807. LoadStringU(HinstDll, IDS_ISSUER_WARNING, rgwch, ARRAYSIZE(rgwch));
  808. CryptUISetRicheditTextW(hwndDlg, IDC_CERT_ISSUER_WARNING_EDIT, rgwch);
  809. //
  810. // set the font for all the header edit boxes
  811. //
  812. memset(&chFormat, 0, sizeof(chFormat));
  813. chFormat.cbSize = sizeof(chFormat);
  814. chFormat.dwMask = CFM_BOLD;
  815. chFormat.dwEffects = CFE_BOLD;
  816. SendMessageA(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_HEADER), EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &chFormat);
  817. SendMessageA(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_GOODFOR_HEADER), EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &chFormat);
  818. SendMessageA(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_ISSUEDTO_HEADER), EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &chFormat);
  819. SendMessageA(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_ISSUEDBY_HEADER), EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &chFormat);
  820. SendMessageA(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_ERROR_EDIT), EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &chFormat);
  821. //
  822. // subclass the header edit controls so they display an arrow cursor in their window
  823. //
  824. CertSubclassEditControlForArrowCursor(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_HEADER));
  825. CertSubclassEditControlForArrowCursor(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_GOODFOR_HEADER));
  826. CertSubclassEditControlForArrowCursor(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_ISSUEDTO_HEADER));
  827. CertSubclassEditControlForArrowCursor(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_ISSUEDBY_HEADER));
  828. CertSubclassEditControlForArrowCursor(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_ERROR_EDIT));
  829. CertSubclassEditControlForArrowCursor(GetDlgItem(hwndDlg, IDC_CERT_ISSUER_WARNING_EDIT));
  830. //
  831. // set the validty string
  832. //
  833. if (FormatValidityString(&pwszDateString, pccert, GetDlgItem(hwndDlg, IDC_CERT_GENERAL_VALID_EDIT)))
  834. {
  835. //
  836. // insert the string and the the font style/color
  837. //
  838. CryptUISetRicheditTextW(hwndDlg, IDC_CERT_GENERAL_VALID_EDIT, pwszDateString);
  839. free(pwszDateString);
  840. //
  841. // set the header parts of the validity string to bold
  842. //
  843. memset(&chFormat, 0, sizeof(chFormat));
  844. chFormat.cbSize = sizeof(chFormat);
  845. chFormat.dwMask = CFM_BOLD;
  846. chFormat.dwEffects = CFE_BOLD;
  847. findText.chrg.cpMin = findText.chrgText.cpMin = 0;
  848. findText.chrg.cpMax = findText.chrgText.cpMax = -1;
  849. LoadStringU(HinstDll, IDS_VALIDFROM, szFindText, ARRAYSIZE(szFindText));
  850. findText.lpstrText = CertUIMkMBStr(szFindText);
  851. SendMessageA(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_VALID_EDIT),
  852. EM_FINDTEXTEX,
  853. FR_DOWN,
  854. (LPARAM) &findText);
  855. SendMessageA(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_VALID_EDIT),
  856. EM_SETSEL,
  857. findText.chrgText.cpMin,
  858. (LPARAM) findText.chrgText.cpMax);
  859. SendMessageA(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_VALID_EDIT),
  860. EM_SETCHARFORMAT,
  861. SCF_SELECTION,
  862. (LPARAM) &chFormat);
  863. free((void *)findText.lpstrText);
  864. LoadStringU(HinstDll, IDS_VALIDTO, szFindText, ARRAYSIZE(szFindText));
  865. findText.lpstrText = CertUIMkMBStr(szFindText);
  866. SendMessageA(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_VALID_EDIT),
  867. EM_FINDTEXTEX,
  868. FR_DOWN,
  869. (LPARAM) &findText);
  870. SendMessageA(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_VALID_EDIT),
  871. EM_SETSEL,
  872. findText.chrgText.cpMin,
  873. (LPARAM) findText.chrgText.cpMax);
  874. SendMessageA(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_VALID_EDIT),
  875. EM_SETCHARFORMAT,
  876. SCF_SELECTION,
  877. (LPARAM) &chFormat);
  878. free((void *)findText.lpstrText);
  879. SendMessageA(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_VALID_EDIT),
  880. EM_SETSEL,
  881. -1,
  882. 0);
  883. }
  884. CertSubclassEditControlForArrowCursor(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_VALID_EDIT));
  885. return TRUE;
  886. case WM_MY_REINITIALIZE:
  887. pviewhelp = (CERT_VIEW_HELPER *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  888. hWndGoodForEdit = GetDlgItem(hwndDlg, IDC_GOODFOR_EDIT);
  889. ShowWindow(hWndGoodForEdit, SW_HIDE);
  890. //
  891. // re-add the usages
  892. //
  893. AddUsagesToEditBox(
  894. hWndGoodForEdit,
  895. pviewhelp);
  896. //
  897. // resize the edit controls so that they are an integral number of lines
  898. //
  899. ResizeEditControl(hwndDlg, hWndGoodForEdit, TRUE, FALSE, pviewhelp->goodForOriginalRect);
  900. //
  901. // if there are no valid usages or we couldn't validate because there wasn't
  902. // enough information, then keep the usage edit windows hidden so we can
  903. // display more text,
  904. //
  905. if (pviewhelp->pwszErrorString == NULL)
  906. {
  907. EnableWindow(hWndGoodForEdit, TRUE);
  908. ShowWindow(hWndGoodForEdit, SW_SHOW);
  909. EnableWindow(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_GOODFOR_HEADER), TRUE);
  910. ShowWindow(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_GOODFOR_HEADER), SW_SHOW);
  911. if (pviewhelp->fCPSDisplayed)
  912. {
  913. ShowWindow(GetDlgItem(hwndDlg, IDC_CERT_ISSUER_WARNING_EDIT), SW_SHOW);
  914. EnableWindow(GetDlgItem(hwndDlg, IDC_CERT_ISSUER_WARNING_EDIT), TRUE);
  915. }
  916. else
  917. {
  918. EnableWindow(GetDlgItem(hwndDlg, IDC_CERT_ISSUER_WARNING_EDIT), FALSE);
  919. ShowWindow(GetDlgItem(hwndDlg, IDC_CERT_ISSUER_WARNING_EDIT), SW_HIDE);
  920. }
  921. EnableWindow(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_ERROR_EDIT), FALSE);
  922. ShowWindow(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_ERROR_EDIT), SW_HIDE);
  923. }
  924. else
  925. {
  926. EnableWindow(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_GOODFOR_HEADER), FALSE);
  927. ShowWindow(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_GOODFOR_HEADER), SW_HIDE);
  928. EnableWindow(GetDlgItem(hwndDlg, IDC_CERT_ISSUER_WARNING_EDIT), FALSE);
  929. ShowWindow(GetDlgItem(hwndDlg, IDC_CERT_ISSUER_WARNING_EDIT), SW_HIDE);
  930. EnableWindow(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_ERROR_EDIT), TRUE);
  931. ShowWindow(GetDlgItem(hwndDlg, IDC_CERT_GENERAL_ERROR_EDIT), SW_SHOW);
  932. }
  933. //
  934. // if there is an untrusted root error, and we are ignoring untrusted root,
  935. // then set the error to 0
  936. //
  937. if (((pviewhelp->dwChainError == CERT_E_UNTRUSTEDROOT) || (pviewhelp->dwChainError == CERT_E_UNTRUSTEDTESTROOT)) &&
  938. (pviewhelp->fIgnoreUntrustedRoot))
  939. {
  940. pviewhelp->pCCertBmp->SetChainError(0, TRUE, (pviewhelp->dwChainError == 0) && (pviewhelp->cUsages == NULL));
  941. }
  942. else
  943. {
  944. pviewhelp->pCCertBmp->SetChainError(pviewhelp->dwChainError, IsTrueErrorString(pviewhelp),
  945. (pviewhelp->dwChainError == 0) && (pviewhelp->cUsages == NULL));
  946. }
  947. CryptUISetRicheditTextW(hwndDlg, IDC_CERT_GENERAL_ERROR_EDIT, pviewhelp->pwszErrorString);
  948. return TRUE;
  949. case WM_NOTIFY:
  950. pviewhelp = (CERT_VIEW_HELPER *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  951. switch (((NMHDR FAR *) lParam)->code) {
  952. case EN_LINK:
  953. penlink = (ENLINK *) lParam;
  954. if (penlink->msg == WM_LBUTTONUP) {
  955. break;
  956. }
  957. break;
  958. case PSN_SETACTIVE:
  959. break;
  960. case PSN_APPLY:
  961. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)FALSE);
  962. break;
  963. case PSN_KILLACTIVE:
  964. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)FALSE);
  965. return TRUE;
  966. case PSN_RESET:
  967. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)FALSE);
  968. break;
  969. case PSN_QUERYCANCEL:
  970. pviewhelp->fCancelled = TRUE;
  971. return FALSE;
  972. case PSN_HELP:
  973. pviewhelp = (CERT_VIEW_HELPER *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  974. if (FIsWin95) {
  975. //nHelpA(hwndDlg, (LPSTR) pviewhelp->pcvp->szHelpFileName,
  976. // HELP_CONTEXT, pviewhelp->pcvp->dwHelpId);
  977. }
  978. else {
  979. //nHelpW(hwndDlg, pviewhelp->pcvp->szHelpFileName, HELP_CONTEXT,
  980. // pviewhelp->pcvp->dwHelpId);
  981. }
  982. return TRUE;
  983. case LVN_ITEMCHANGING:
  984. pnmv = (LPNMLISTVIEW) lParam;
  985. if (pnmv->uNewState & LVIS_SELECTED)
  986. {
  987. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)TRUE);
  988. }
  989. return TRUE;
  990. case NM_DBLCLK:
  991. return TRUE;
  992. }
  993. break;
  994. case WM_COMMAND:
  995. pviewhelp = (CERT_VIEW_HELPER *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  996. switch (LOWORD(wParam))
  997. {
  998. case IDHELP:
  999. pviewhelp = (CERT_VIEW_HELPER *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  1000. if (FIsWin95)
  1001. {
  1002. //nHelpA(hwndDlg, (LPSTR) pviewhelp->pcvp->szHelpFileName,
  1003. // HELP_CONTEXT, pviewhelp->pcvp->dwHelpId);
  1004. }
  1005. else
  1006. {
  1007. //nHelpW(hwndDlg, pviewhelp->pcvp->szHelpFileName, HELP_CONTEXT,
  1008. // pviewhelp->pcvp->dwHelpId);
  1009. }
  1010. return TRUE;
  1011. case IDC_ACCEPT_BUTTON:
  1012. pviewhelp->fAccept = TRUE;
  1013. SendMessage(GetParent(hwndDlg), PSM_PRESSBUTTON, PSBTN_OK, (LPARAM) 0);
  1014. break;
  1015. case IDC_DECLINE_BUTTON:
  1016. pviewhelp->fAccept = FALSE;
  1017. SendMessage(GetParent(hwndDlg), PSM_PRESSBUTTON, PSBTN_OK, (LPARAM) 0);
  1018. break;
  1019. case IDC_DISCLAIMER_BUTTON:
  1020. if (HIWORD(wParam) == BN_CLICKED)
  1021. {
  1022. pccert = pviewhelp->pcvp->pCertContext;
  1023. DisplayCPS(hwndDlg, pccert, pviewhelp->dwChainError, pviewhelp->fNoCOM);
  1024. return TRUE;
  1025. }
  1026. break;
  1027. case IDC_ADD_TO_STORE_BUTTON:
  1028. if (HIWORD(wParam) == BN_CLICKED)
  1029. {
  1030. CRYPTUI_WIZ_IMPORT_SRC_INFO importInfo;
  1031. memset(&importInfo, 0, sizeof(importInfo));
  1032. importInfo.dwSize = sizeof(importInfo);
  1033. importInfo.dwSubjectChoice = CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_CONTEXT;
  1034. importInfo.pCertContext = pviewhelp->pcvp->pCertContext;
  1035. CryptUIWizImport(0, hwndDlg, NULL, &importInfo, NULL);
  1036. return TRUE;
  1037. }
  1038. break;
  1039. }
  1040. break;
  1041. case WM_DESTROY:
  1042. pviewhelp = (CERT_VIEW_HELPER *) GetWindowLongPtr(hwndDlg, DWLP_USER);
  1043. //
  1044. // if DWL_USER is NULL then we weren't initialized, so don't cleanup
  1045. //
  1046. if (pviewhelp == NULL)
  1047. {
  1048. return FALSE;
  1049. }
  1050. pccert = pviewhelp->pcvp->pCertContext;
  1051. SetWindowLongPtr(
  1052. GetDlgItem(hwndDlg, IDC_GOODFOR_EDIT),
  1053. GWLP_WNDPROC,
  1054. GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_GOODFOR_EDIT), GWLP_USERDATA));
  1055. //
  1056. // cleanup the private key edit box subclass
  1057. //
  1058. if (CertificateHasPrivateKey(pccert))
  1059. {
  1060. if (plsd = (PLINK_SUBCLASS_DATA) GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_CERT_PRIVATE_KEY_EDIT), GWLP_USERDATA))
  1061. {
  1062. SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_CERT_PRIVATE_KEY_EDIT), GWLP_WNDPROC, (LONG_PTR)plsd->wpPrev);
  1063. free(plsd->pszURL);
  1064. free(plsd);
  1065. }
  1066. }
  1067. //
  1068. // use this call to AllocAndGetIssuerURL to see if the issuer has an active link, and then
  1069. // do the proper unsubclass and/or free
  1070. //
  1071. if (pviewhelp->fIssuerDisplayedAsLink)
  1072. {
  1073. if (plsd = (PLINK_SUBCLASS_DATA) GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_ISSUER_EDIT), GWLP_USERDATA))
  1074. {
  1075. SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_ISSUER_EDIT), GWLP_WNDPROC, (LONG_PTR)plsd->wpPrev);
  1076. free(plsd->pszURL);
  1077. free(plsd);
  1078. }
  1079. }
  1080. else
  1081. {
  1082. SetWindowLongPtr(
  1083. GetDlgItem(hwndDlg, IDC_ISSUER_EDIT),
  1084. GWLP_WNDPROC,
  1085. GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_ISSUER_EDIT), GWLP_USERDATA));
  1086. }
  1087. //
  1088. // use this call to AllocAndGetSubjectURL to see if the subject has an active link, and then
  1089. // do the proper unsubclass and/or free
  1090. //
  1091. if (pviewhelp->fSubjectDisplayedAsLink)
  1092. {
  1093. if (plsd = (PLINK_SUBCLASS_DATA) GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_SUBJECT_EDIT), GWLP_USERDATA))
  1094. {
  1095. SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_SUBJECT_EDIT), GWLP_WNDPROC, (LONG_PTR)plsd->wpPrev);
  1096. free(plsd->pszURL);
  1097. free(plsd);
  1098. }
  1099. }
  1100. else
  1101. {
  1102. SetWindowLongPtr(
  1103. GetDlgItem(hwndDlg, IDC_SUBJECT_EDIT),
  1104. GWLP_WNDPROC,
  1105. GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_SUBJECT_EDIT), GWLP_USERDATA));
  1106. }
  1107. /*DeleteObject((HGDIOBJ)SendMessage(GetDlgItem(hwndDlg, IDC_INFO_BUTTON),
  1108. BM_GETIMAGE,
  1109. (WPARAM) IMAGE_ICON,
  1110. (LPARAM) 0));*/
  1111. return FALSE;
  1112. case WM_HELP:
  1113. case WM_CONTEXTMENU:
  1114. lpHelpInfo = (LPHELPINFO)lParam;
  1115. if (msg == WM_HELP)
  1116. {
  1117. hwnd = GetDlgItem(hwndDlg, lpHelpInfo->iCtrlId);
  1118. }
  1119. else
  1120. {
  1121. hwnd = (HWND) wParam;
  1122. }
  1123. if ((hwnd != GetDlgItem(hwndDlg, IDC_SUBJECT_EDIT)) &&
  1124. (hwnd != GetDlgItem(hwndDlg, IDC_CERT_GENERAL_ISSUEDTO_HEADER)) &&
  1125. (hwnd != GetDlgItem(hwndDlg, IDC_ISSUER_EDIT)) &&
  1126. (hwnd != GetDlgItem(hwndDlg, IDC_CERT_GENERAL_ISSUEDBY_HEADER)) &&
  1127. (hwnd != GetDlgItem(hwndDlg, IDC_ADD_TO_STORE_BUTTON)) &&
  1128. (hwnd != GetDlgItem(hwndDlg, IDC_DISCLAIMER_BUTTON)) &&
  1129. (hwnd != GetDlgItem(hwndDlg, IDC_ACCEPT_BUTTON)) &&
  1130. (hwnd != GetDlgItem(hwndDlg, IDC_DECLINE_BUTTON)) &&
  1131. (hwnd != GetDlgItem(hwndDlg, IDC_GOODFOR_EDIT)) &&
  1132. (hwnd != GetDlgItem(hwndDlg, IDC_CERT_GENERAL_GOODFOR_HEADER)) &&
  1133. (hwnd != GetDlgItem(hwndDlg, IDC_CERT_PRIVATE_KEY_EDIT)) &&
  1134. (hwnd != GetDlgItem(hwndDlg, IDC_CERT_GENERAL_VALID_EDIT)))
  1135. {
  1136. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)TRUE);
  1137. return TRUE;
  1138. }
  1139. else
  1140. {
  1141. return OnContextHelp(hwndDlg, msg, (WPARAM) hwnd, lParam, helpmap);
  1142. }
  1143. }
  1144. return FALSE;
  1145. }