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.

564 lines
18 KiB

  1. /*
  2. ** s e c h t m l . c p p
  3. **
  4. ** Purpose:
  5. ** Defines an inline script for the preview pane that will show general
  6. ** security UI. An ActiveX control sits on top of this and passes
  7. ** the results to our command target
  8. **
  9. ** History
  10. ** 4/02/97: (t-erikne) Created.
  11. ** 7/15/97: (t-erikne) Removed ActiveX control
  12. ** 7/16/97: (t-erikne) updated to HTML 4.0
  13. **
  14. ** Copyright (C) Microsoft Corp. 1997.
  15. */
  16. ///////////////////////////////////////////////////////////////////////////
  17. //
  18. // Depends on
  19. //
  20. #include <pch.hxx>
  21. #include <resource.h>
  22. #include <docobj.h>
  23. #include "oleutil.h"
  24. #include "ourguid.h"
  25. #include <error.h>
  26. #include <mimeole.h>
  27. #include "secutil.h"
  28. #include <shlwapi.h>
  29. #include "demand.h"
  30. ///////////////////////////////////////////////////////////////////////////
  31. //
  32. // Macros
  33. //
  34. #define THIS_AS_UNK ((IUnknown *)(IObjectWithSite *)this)
  35. ///////////////////////////////////////////////////////////////////////////
  36. //
  37. // Statics
  38. //
  39. static const TCHAR s_szHTMLRow[] =
  40. "<TR>"
  41. "<TD WIDTH=5%%>"
  42. "<IMG SRC=\"res://msoeres.dll/%s\">"
  43. "</TD>"
  44. "<TD CLASS=%s>"
  45. "%s"
  46. "</TD>"
  47. "</TR>\r\n";
  48. static const TCHAR s_szHTMLRowForRec[] =
  49. "<TR>"
  50. "<TD CLASS=GOOD>"
  51. "%s %s"
  52. "</TD>"
  53. "</TR>\r\n";
  54. // WARNING: If you change the order here, make sure to change it in the order of
  55. // sprintf parameters where it is used in HrOutputSecurityScript.
  56. static const TCHAR s_szHTMLmain[] =
  57. "document.all.hightext.className=\"%s\";"
  58. "document.all.btnCert.disabled=%d;"
  59. "document.all.chkShowAgain.readonly=%d;"
  60. "document.all.chkShowAgain.disabled=%d;"
  61. "document.all.btnTrust.disabled=%d;"
  62. "}\r\n";
  63. static const TCHAR s_szHTMLCloseAll[] =
  64. "</SCRIPT>"
  65. "</BODY></HTML>";
  66. static const TCHAR s_szHTMLgifUNK[] =
  67. "quest.gif";
  68. static const TCHAR s_szHTMLgifGOOD[] =
  69. "check.gif";
  70. static const TCHAR s_szHTMLgifBAD[] =
  71. "eks.gif";
  72. static const TCHAR s_szHTMLclassGOOD[] =
  73. "GOOD";
  74. static const TCHAR s_szHTMLclassBAD[] =
  75. "BAD";
  76. static const TCHAR s_szHTMLclassUNK[] =
  77. "UNK";
  78. static const TCHAR s_szHTMLRowNoIcon[] =
  79. "<TR>"
  80. "<TD WIDTH=5%%>"
  81. "</TD>"
  82. "<TD CLASS=%s>" // "BAD", "GOOD", "UNK"
  83. "%s%s" // label, email address
  84. "</TD>"
  85. "</TR>\r\n";
  86. static const TCHAR s_szHMTLEndTable[] =
  87. "</TABLE>\r\n<p>\r\n<p>" ;
  88. static const TCHAR s_szHTMLEnd[] =
  89. "</BODY></HTML>";
  90. ///////////////////////////////////////////////////////////////////////////
  91. //
  92. // Code
  93. //
  94. HRESULT HrOutputSecurityScript(LPSTREAM *ppstm, SECSTATE *pSecState, BOOL fDisableCheckbox)
  95. {
  96. HRESULT hr;
  97. TCHAR szRes[CCHMAX_STRINGRES];
  98. TCHAR szBuf[CCHMAX_STRINGRES];
  99. UINT ids;
  100. ULONG ul;
  101. int i;
  102. BOOL fBadThingsHappened = FALSE;
  103. const WORD wTrusted = LOWORD(pSecState->user_validity);
  104. hr = LoadResourceToHTMLStream("secwarn1.htm", ppstm);
  105. if (FAILED(hr))
  106. goto exit;
  107. ul = ULONG(HIWORD(pSecState->user_validity));
  108. // Top level Messages
  109. //N8 one of the places that we need to pay attention
  110. // to cryptdlg's flags, see wTrusted. I assume that
  111. // we get ATHSEC_NOTRUSTUNKNOWN in a certain set
  112. // of cases. see the chain code in secutil.cpp
  113. // 1. Tamper
  114. if (AthLoadString(
  115. (pSecState->ro_msg_validity & MSV_SIGNATURE_MASK)
  116. ? (pSecState->ro_msg_validity & MSV_BADSIGNATURE)
  117. ? idsWrnSecurityMsgTamper
  118. : idsUnkSecurityMsgTamper
  119. : (pSecState->fHaveCert ? idsOkSecurityMsgTamper : idsUnkSecurityMsgTamper),
  120. szRes, ARRAYSIZE(szRes)))
  121. {
  122. wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLRow,
  123. (pSecState->ro_msg_validity & MSV_SIGNATURE_MASK)
  124. ? ((pSecState->ro_msg_validity & MSV_BADSIGNATURE)
  125. ? s_szHTMLgifBAD
  126. : s_szHTMLgifUNK)
  127. : (pSecState->fHaveCert ? s_szHTMLgifGOOD : s_szHTMLgifUNK),
  128. (pSecState->ro_msg_validity & MSV_SIGNATURE_MASK)
  129. ? ((pSecState->ro_msg_validity & MSV_BADSIGNATURE)
  130. ? s_szHTMLclassBAD
  131. : s_szHTMLclassUNK)
  132. : (pSecState->fHaveCert ? s_szHTMLclassGOOD : s_szHTMLclassUNK),
  133. szRes);
  134. (*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
  135. }
  136. // 2. Trust
  137. if (AthLoadString(
  138. (wTrusted)
  139. ? (wTrusted & ATHSEC_NOTRUSTUNKNOWN)
  140. ? idsUnkSecurityTrust
  141. : idsWrnSecurityTrustNotTrusted
  142. : idsOkSecurityTrustNotTrusted,
  143. szRes, ARRAYSIZE(szRes)))
  144. {
  145. wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLRow,
  146. (wTrusted)
  147. ? (wTrusted & ATHSEC_NOTRUSTUNKNOWN)
  148. ? s_szHTMLgifUNK
  149. : s_szHTMLgifBAD
  150. : s_szHTMLgifGOOD,
  151. (wTrusted)
  152. ? (wTrusted & ATHSEC_NOTRUSTUNKNOWN)
  153. ? s_szHTMLclassUNK
  154. : s_szHTMLclassBAD
  155. : s_szHTMLclassGOOD,
  156. szRes);
  157. (*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
  158. }
  159. // 3. Expire
  160. if (AthLoadString(
  161. (pSecState->ro_msg_validity & MSV_EXPIRED_SIGNINGCERT)
  162. ? idsWrnSecurityTrustExpired
  163. : idsOkSecurityTrustExpired,
  164. szRes, ARRAYSIZE(szRes)))
  165. {
  166. wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLRow,
  167. (pSecState->ro_msg_validity & MSV_EXPIRED_SIGNINGCERT)
  168. ? s_szHTMLgifBAD
  169. : s_szHTMLgifGOOD,
  170. (pSecState->ro_msg_validity & MSV_EXPIRED_SIGNINGCERT)
  171. ? s_szHTMLclassBAD
  172. : s_szHTMLclassGOOD,
  173. szRes);
  174. (*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
  175. }
  176. // Validity Messages
  177. ids = idsWrnSecurityTrustAddress; //base
  178. for (i=ATHSEC_NUMVALIDITYBITS; i; i--)
  179. {
  180. if (!AthLoadString(
  181. (ul & 0x1)
  182. ? ids
  183. : ids+OFFSET_SMIMEOK,
  184. szRes, ARRAYSIZE(szRes)))
  185. {
  186. continue;
  187. }
  188. wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLRow,
  189. (ul & 0x1) ? s_szHTMLgifBAD : s_szHTMLgifGOOD,
  190. (ul & 0x1) ? s_szHTMLclassBAD : s_szHTMLclassGOOD,
  191. szRes);
  192. if (ul & 0x1)
  193. {
  194. fBadThingsHappened = TRUE;
  195. }
  196. (*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
  197. if (ul & 0x1 && ids == idsWrnSecurityTrustAddress)
  198. {
  199. // Output the email addresses
  200. // Certificate first
  201. if (AthLoadString(idsWrnSecurityTrustAddressSigner, szRes, ARRAYSIZE(szRes))) {
  202. wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLRowNoIcon,
  203. s_szHTMLclassBAD,
  204. szRes,
  205. pSecState->szSignerEmail ? pSecState->szSignerEmail : "");
  206. (*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
  207. }
  208. // Then the Sender
  209. if (AthLoadString(idsWrnSecurityTrustAddressSender , szRes, ARRAYSIZE(szRes))) {
  210. wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLRowNoIcon,
  211. s_szHTMLclassBAD,
  212. szRes,
  213. pSecState->szSenderEmail ? pSecState->szSenderEmail : "");
  214. (*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
  215. }
  216. }
  217. ul >>= 1;
  218. ids++;
  219. }
  220. Assert(0==ul);
  221. // Response script
  222. CHECKHR(hr = HrLoadStreamFileFromResource("secwarn2.htm", ppstm));
  223. // main() function
  224. if ((pSecState->ro_msg_validity & MSV_BADSIGNATURE) ||
  225. (pSecState->ro_msg_validity & MSV_EXPIRED_SIGNINGCERT) ||
  226. (wTrusted & ATHSEC_NOTRUSTNOTTRUSTED))
  227. fBadThingsHappened = TRUE;
  228. wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLmain,
  229. fBadThingsHappened ? s_szHTMLclassBAD : s_szHTMLclassUNK,
  230. !pSecState->fHaveCert, // fDisableCheckbox,
  231. fDisableCheckbox,
  232. fDisableCheckbox, // !pSecState->fHaveCert,
  233. !pSecState->fHaveCert);
  234. CHECKHR(hr = (*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL));
  235. // Finish
  236. CHECKHR(hr = (*ppstm)->Write(s_szHTMLCloseAll, sizeof(s_szHTMLCloseAll)-sizeof(TCHAR), NULL));
  237. #ifdef DEBUG
  238. WriteStreamToFile(*ppstm, "c:\\oesecstm.htm", CREATE_ALWAYS, GENERIC_WRITE);
  239. #endif
  240. exit:
  241. return hr;
  242. }
  243. HRESULT HrDumpLineToStream(LPSTREAM *ppstm, UINT *ids, TCHAR *szPar)
  244. {
  245. TCHAR szRes[CCHMAX_STRINGRES];
  246. TCHAR szBuf[CCHMAX_STRINGRES];
  247. if(*ids)
  248. {
  249. AthLoadString(*ids, szRes, ARRAYSIZE(szRes));
  250. wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLRowForRec, szRes, szPar);
  251. (*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
  252. *ids = 0;
  253. }
  254. return(S_OK);
  255. }
  256. HRESULT HrOutputRecHasProblems(LPSTREAM *ppstm, SECSTATE *pSecState)
  257. {
  258. HRESULT hr = S_OK;
  259. const WORD wTrusted = LOWORD(pSecState->user_validity);
  260. UINT ids = 0;
  261. UINT ids1 = 0;
  262. TCHAR szBuf[CCHMAX_STRINGRES];
  263. ULONG ul = ULONG(HIWORD(pSecState->user_validity));
  264. int i;
  265. if(AthLoadString(idsRecHasProblems, szBuf, ARRAYSIZE(szBuf)))
  266. (*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
  267. // 1. Tamper
  268. if(pSecState->ro_msg_validity & MSV_SIGNATURE_MASK)
  269. ids = (pSecState->ro_msg_validity & MSV_BADSIGNATURE) ? idsWrnSecurityMsgTamper : idsUnkSecurityMsgTamper;
  270. else if(!pSecState->fHaveCert)
  271. ids = idsUnkSecurityMsgTamper;
  272. HrDumpLineToStream(ppstm, &ids, NULL);
  273. // 2. Trust
  274. if(wTrusted)
  275. {
  276. ids = (wTrusted & ATHSEC_NOTRUSTUNKNOWN) ? idsUnkSecurityTrust : idsWrnSecurityTrustNotTrusted;
  277. HrDumpLineToStream(ppstm, &ids, NULL);
  278. }
  279. // 3. Expire
  280. if(pSecState->ro_msg_validity & MSV_EXPIRED_SIGNINGCERT)
  281. {
  282. ids = idsWrnSecurityTrustExpired;
  283. HrDumpLineToStream(ppstm, &ids, NULL);
  284. }
  285. // Validity Messages
  286. ids = idsWrnSecurityTrustAddress; //base
  287. for (i=ATHSEC_NUMVALIDITYBITS; i; i--)
  288. {
  289. if (ul & 0x1)
  290. {
  291. if(ids == idsWrnSecurityTrustAddress)
  292. {
  293. ids1 = idsWrnSecurityTrustAddress;
  294. HrDumpLineToStream(ppstm, &ids1, NULL);
  295. ids1 = idsWrnSecurityTrustAddressSigner;
  296. HrDumpLineToStream(ppstm, &ids1, pSecState->szSignerEmail);
  297. ids1 = idsWrnSecurityTrustAddressSender;
  298. HrDumpLineToStream(ppstm, &ids1, pSecState->szSenderEmail);
  299. }
  300. else
  301. {
  302. ids1 = ids;
  303. HrDumpLineToStream(ppstm, &ids1, NULL);
  304. }
  305. }
  306. ul >>= 1;
  307. ids++;
  308. }
  309. return(S_OK);
  310. }
  311. HRESULT HrOutputSecureReceipt(LPSTREAM *ppstm, TCHAR * pszSubject, TCHAR * pszFrom, FILETIME * pftSentTime, FILETIME * pftSigningTime, SECSTATE *pSecState)
  312. {
  313. HRESULT hr = S_OK;
  314. TCHAR szRes[CCHMAX_STRINGRES];
  315. CHAR szTmp[CCHMAX_STRINGRES];
  316. TCHAR szBuf[CCHMAX_STRINGRES*2];
  317. SYSTEMTIME SysTime;
  318. int size = 0;
  319. IF_FAILEXIT(hr = LoadResourceToHTMLStream("secrec.htm", ppstm));
  320. // Add To line
  321. if(AthLoadString(idsToField, szRes, ARRAYSIZE(szRes)))
  322. {
  323. size = lstrlen(pszFrom);
  324. if(size == 0)
  325. {
  326. if(!AthLoadString(idsRecUnknown, szTmp, ARRAYSIZE(szTmp)))
  327. szTmp[0] = _T('\0');
  328. wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLRowForRec, szRes, szTmp);
  329. }
  330. else
  331. {
  332. if(size >= (CCHMAX_STRINGRES - lstrlen(s_szHTMLRowForRec) - lstrlen(szRes) - 2))
  333. pszFrom[CCHMAX_STRINGRES - lstrlen(s_szHTMLRowForRec) - lstrlen(szRes) - 3] = _T('\0');
  334. wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLRowForRec, szRes, pszFrom);
  335. }
  336. (*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
  337. }
  338. // Add Subject line
  339. if(AthLoadString(idsSubjectField, szRes, ARRAYSIZE(szRes)))
  340. {
  341. if(lstrlen(pszSubject) >= (CCHMAX_STRINGRES - lstrlen(s_szHTMLRowForRec) - lstrlen(szRes) - 2))
  342. pszSubject[CCHMAX_STRINGRES - lstrlen(s_szHTMLRowForRec) - lstrlen(szRes) - 3] = _T('\0');
  343. wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLRowForRec, szRes, pszSubject);
  344. (*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
  345. }
  346. // Add Sent line
  347. if(AthLoadString(idsSentField, szRes, ARRAYSIZE(szRes)))
  348. {
  349. CchFileTimeToDateTimeSz(pftSentTime, szTmp, CCHMAX_STRINGRES - lstrlen(szRes) - 2, DTM_NOSECONDS);
  350. wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLRowForRec, szRes, szTmp);
  351. (*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
  352. }
  353. // End of table
  354. CHECKHR(hr = (*ppstm)->Write(s_szHMTLEndTable, sizeof(s_szHMTLEndTable)-sizeof(TCHAR), NULL));
  355. // Final message
  356. if(AthLoadString(idsReceiptField, szRes, ARRAYSIZE(szRes)))
  357. {
  358. CchFileTimeToDateTimeSz(pftSigningTime, szTmp, CCHMAX_STRINGRES - lstrlen(szRes) - 2, DTM_NOSECONDS);
  359. wnsprintf(szBuf, ARRAYSIZE(szBuf), szRes, szTmp);
  360. (*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
  361. }
  362. if(!IsSignTrusted(pSecState))
  363. {
  364. HrOutputRecHasProblems(ppstm, pSecState) ;
  365. // End of table again
  366. CHECKHR(hr = (*ppstm)->Write(s_szHMTLEndTable, sizeof(s_szHMTLEndTable)-sizeof(TCHAR), NULL));
  367. }
  368. // End of HTML file
  369. CHECKHR(hr = (*ppstm)->Write(s_szHTMLEnd, sizeof(s_szHTMLEnd)-sizeof(TCHAR), NULL));
  370. exit:
  371. return(hr);
  372. }
  373. // user's itself secure receipt
  374. HRESULT HrOutputUserSecureReceipt(LPSTREAM *ppstm, IMimeMessage *pMsg)
  375. {
  376. HRESULT hr = S_OK;
  377. LPSTR lpszSubj = NULL;
  378. LPSTR lpszTo = NULL;
  379. CHAR szTmp[CCHMAX_STRINGRES];
  380. TCHAR szRes[CCHMAX_STRINGRES];
  381. TCHAR szBuf[CCHMAX_STRINGRES*2];
  382. PROPVARIANT Var;
  383. int size;
  384. IF_FAILEXIT(hr = LoadResourceToHTMLStream("srsentit.htm", ppstm));
  385. MimeOleGetBodyPropA(pMsg, HBODY_ROOT, PIDTOSTR(PID_HDR_SUBJECT), NOFLAGS, &lpszSubj);
  386. MimeOleGetBodyPropA(pMsg, HBODY_ROOT, PIDTOSTR(PID_HDR_TO), NOFLAGS, &lpszTo);
  387. // Add To line
  388. if(AthLoadString(idsToField, szRes, ARRAYSIZE(szRes)))
  389. {
  390. // we have a name in <[email protected]>",
  391. // need remove '<' and '>' for HTML
  392. size = lstrlen(lpszTo);
  393. if(lpszTo[size - 1] == _T('>'))
  394. lpszTo[size - 1] = _T('\0');
  395. if(lpszTo[0] == _T('<'))
  396. lpszTo[0] = _T(' ');
  397. if(size >= ((int) (CCHMAX_STRINGRES - sizeof(s_szHTMLRowForRec) - lstrlen(szRes) - 2)))
  398. lpszTo[CCHMAX_STRINGRES - sizeof(s_szHTMLRowForRec) - lstrlen(szRes) - 3] = _T('\0');
  399. wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLRowForRec, szRes, lpszTo);
  400. (*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
  401. }
  402. // Add Subject line
  403. if(AthLoadString(idsSubjectField, szRes, ARRAYSIZE(szRes)))
  404. {
  405. size = lstrlen(szRes);
  406. if(lstrlen(lpszSubj) >= ((int) (CCHMAX_STRINGRES - sizeof(s_szHTMLRowForRec) - size - 2)))
  407. lpszSubj[CCHMAX_STRINGRES - sizeof(s_szHTMLRowForRec) - size - 3] = _T('\0');
  408. wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLRowForRec, szRes, lpszSubj);
  409. (*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
  410. }
  411. // End of table
  412. CHECKHR(hr = (*ppstm)->Write(s_szHMTLEndTable, sizeof(s_szHMTLEndTable)-sizeof(TCHAR), NULL));
  413. // Final message
  414. if(AthLoadString(idsFinalSelfReceipt, szRes, ARRAYSIZE(szRes)))
  415. {
  416. FILETIME ftSigningTime;
  417. PCCERT_CONTEXT pcSigningCert = NULL;
  418. THUMBBLOB tbSigner = {0};
  419. BLOB blSymCaps = {0};
  420. GetSigningCert(pMsg, &pcSigningCert, &tbSigner, &blSymCaps, &ftSigningTime);
  421. CchFileTimeToDateTimeSz(&ftSigningTime, szTmp, ARRAYSIZE(szTmp),
  422. DTM_NOSECONDS);
  423. wnsprintf(szBuf, ARRAYSIZE(szBuf), szRes, szTmp);
  424. (*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
  425. if(pcSigningCert)
  426. CertFreeCertificateContext(pcSigningCert);
  427. SafeMemFree(tbSigner.pBlobData);
  428. SafeMemFree(blSymCaps.pBlobData);
  429. }
  430. // End of HTML file
  431. CHECKHR(hr = (*ppstm)->Write(s_szHTMLEnd, sizeof(s_szHTMLEnd)-sizeof(TCHAR), NULL));
  432. exit:
  433. SafeMemFree(lpszSubj);
  434. SafeMemFree(lpszTo);
  435. return(hr);
  436. }
  437. // secure receipt error screen
  438. HRESULT HrOutputErrSecReceipt(LPSTREAM *ppstm, HRESULT hrError, SECSTATE *pSecState)
  439. {
  440. HRESULT hr = S_OK;
  441. TCHAR szRes[CCHMAX_STRINGRES];
  442. TCHAR szTmp[CCHMAX_STRINGRES];
  443. TCHAR szBuf[CCHMAX_STRINGRES*2];
  444. UINT ids = 0;
  445. switch(hrError)
  446. {
  447. case MIME_E_SECURITY_RECEIPT_CANTFINDSENTITEM:
  448. case MIME_E_SECURITY_RECEIPT_CANTFINDORGMSG:
  449. hr = LoadResourceToHTMLStream("srecerr.htm", ppstm);
  450. break;
  451. case MIME_E_SECURITY_RECEIPT_NOMATCHINGRECEIPTBODY:
  452. case MIME_E_SECURITY_RECEIPT_MSGHASHMISMATCH:
  453. hr = LoadResourceToHTMLStream("recerr2.htm", ppstm);
  454. break;
  455. default:
  456. hr = LoadResourceToHTMLStream("recerr3.htm", ppstm);
  457. break;
  458. }
  459. if(FAILED(hr))
  460. goto exit;
  461. if(!IsSignTrusted(pSecState))
  462. {
  463. HrOutputRecHasProblems(ppstm, pSecState);
  464. // End of table again
  465. CHECKHR(hr = (*ppstm)->Write(s_szHMTLEndTable, sizeof(s_szHMTLEndTable)-sizeof(TCHAR), NULL));
  466. }
  467. // End of HTML file
  468. if(AthLoadString(idsOESignature, szRes, ARRAYSIZE(szRes)))
  469. (*ppstm)->Write(szRes, lstrlen(szRes)*sizeof(TCHAR), NULL);
  470. CHECKHR(hr = (*ppstm)->Write(s_szHTMLEnd, sizeof(s_szHTMLEnd)-sizeof(TCHAR), NULL));
  471. exit:
  472. return(hr);
  473. }