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.

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