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.
1086 lines
36 KiB
1086 lines
36 KiB
#include "pch.hxx"
|
|
#include <cryptdlg.h>
|
|
#include "strconst.h"
|
|
#include "msoert.h"
|
|
#include "resource.h"
|
|
#include "mailutil.h"
|
|
#include "ipab.h"
|
|
#include "receipts.h"
|
|
#include "oestore.h"
|
|
#include "shlwapip.h"
|
|
#include "goptions.h"
|
|
#include "conman.h"
|
|
#include "multlang.h"
|
|
#include "demand.h"
|
|
#include "secutil.h"
|
|
|
|
#ifdef SMIME_V3
|
|
HRESULT ProcessSecureReceipt(IMimeMessage * pMsg, IStoreCallback *pStoreCB);
|
|
INT_PTR CALLBACK SecRecResDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
|
#endif // SMIME_V3
|
|
|
|
const WCHAR c_szReadableTextFirst[] = L"This is a receipt for the mail you sent to\r\n";
|
|
const WCHAR c_szReadableTextSecond[] = L"\r\n\r\nThis receipt verifies that the message has been displayed on the recipient's computer at ";
|
|
const WCHAR c_szReceiptsAt[] = L" at ";
|
|
const WCHAR c_szReadReceipt[] = L"Read: %s";
|
|
|
|
const WCHAR c_szSecReadReceipt[] = L"Secure Receipt: %s";
|
|
|
|
//Does not include NULL
|
|
const int cbReadableTextFirst = sizeof(c_szReadableTextFirst) - sizeof(*c_szReadableTextFirst);
|
|
const int cbReadableTextSecond = sizeof(c_szReadableTextSecond) - sizeof(*c_szReadableTextSecond);
|
|
const int cbReceiptsAt = sizeof(c_szReceiptsAt) - sizeof(*c_szReceiptsAt);
|
|
|
|
//Include NULL
|
|
const int cbReadReceipt = sizeof(c_szReadReceipt);
|
|
|
|
|
|
//Not wide, does not include NULL
|
|
const TCHAR c_szDisposition[] = TEXT("\r\nDisposition: manual-action/");
|
|
const TCHAR c_szMDNSendAutomatically[] = TEXT("MDN-sent-automatically; ");
|
|
const TCHAR c_szMDNSendManually[] = TEXT("MDN-sent-manually; ");
|
|
const TCHAR c_szOriginalRecipient[] = TEXT("\r\nOriginal-Recipient: rfc822;");
|
|
const TCHAR c_szFinalRecipient[] = TEXT("Final-Recipient: rfc822;");
|
|
const TCHAR c_szOriginalMessageId[] = TEXT("\r\nOriginal-Message-ID: ");
|
|
const TCHAR c_szDisplayed[] = TEXT("displayed\r\n");
|
|
|
|
//Does not include NULL
|
|
const int cbDisposition = sizeof(c_szDisposition) - sizeof(*c_szDisposition);
|
|
const int cbMDNSendAutomatically = sizeof(c_szMDNSendAutomatically) - sizeof(*c_szMDNSendAutomatically);
|
|
const int cbMDNSendManually = sizeof(c_szMDNSendManually) - sizeof(*c_szMDNSendManually);
|
|
const int cbOriginalRecipient = sizeof(c_szOriginalRecipient) - sizeof(*c_szOriginalRecipient);
|
|
const int cbFinalRecipient = sizeof(c_szFinalRecipient) - sizeof(*c_szFinalRecipient);
|
|
const int cbOriginalMessageId = sizeof(c_szOriginalMessageId) - sizeof(*c_szOriginalMessageId);
|
|
const int cbDisplayed = sizeof(c_szDisplayed) - sizeof(*c_szDisplayed);
|
|
|
|
|
|
HRESULT ProcessReturnReceipts(IMessageTable *pTable,
|
|
IStoreCallback *pStoreCB,
|
|
ROWINDEX iRow,
|
|
RECEIPTTYPE ReceiptType,
|
|
FOLDERID IdFolder,
|
|
IMimeMessage *pMsg)
|
|
{
|
|
IMimeMessage *pMessage = NULL;
|
|
IMimeMessage *pMessageRcpt = NULL;
|
|
BOOL fSendImmediate = FALSE;
|
|
BOOL fMail = TRUE;
|
|
LPWABAL lpWabal = NULL;
|
|
LPWSTR lpsz = NULL;
|
|
MESSAGEINFO *pMsgInfo = NULL;
|
|
IImnAccount *pTempAccount = NULL;
|
|
HRESULT hr = S_OK;
|
|
DWORD dwOption;
|
|
PROPVARIANT var = {0};
|
|
FOLDERINFO FolderInfo = {0};
|
|
|
|
TraceCall("ProcessReturnReceipts");
|
|
|
|
if (!pTable || !g_pAcctMan)
|
|
return TraceResult(E_INVALIDARG);
|
|
|
|
IF_FAILEXIT(hr = g_pStore->GetFolderInfo(IdFolder, &FolderInfo));
|
|
|
|
if (FolderInfo.tySpecial == FOLDER_OUTBOX || FolderInfo.tyFolder == FOLDER_NEWS)
|
|
{
|
|
goto exit;
|
|
}
|
|
|
|
//First of all check if this has already been processed
|
|
IF_FAILEXIT(hr = pTable->GetRow(iRow, &pMsgInfo));
|
|
|
|
if ((!pMsgInfo) || (pMsgInfo->dwFlags & (ARF_RCPT_PROCESSED | ARF_NEWSMSG)))
|
|
goto exit;
|
|
|
|
//Mark this flag as having been processed
|
|
IF_FAILEXIT(hr = pTable->Mark(&iRow, 1, APPLY_SPECIFIED, MARK_MESSAGE_RCPT_PROCESSED, pStoreCB));
|
|
|
|
if(!pMsg)
|
|
IF_FAILEXIT(hr = pTable->OpenMessage(iRow, 0, &pMessage, pStoreCB));
|
|
else
|
|
pMessage = pMsg;
|
|
|
|
#ifdef SMIME_V3
|
|
// Secure receipt check
|
|
hr = ProcessSecureReceipt(pMessage, pStoreCB);
|
|
if(hr != S_OK)
|
|
goto exit;
|
|
#endif // SMIME_V3
|
|
|
|
dwOption = DwGetOption(OPT_MDN_SEND_RECEIPT);
|
|
if (dwOption == MDN_DONT_SENDRECEIPT)
|
|
goto exit;
|
|
|
|
hr = MimeOleGetBodyPropW(pMessage, HBODY_ROOT, STR_HDR_DISP_NOTIFICATION_TO,
|
|
NOFLAGS, &lpsz);
|
|
|
|
if (FAILED(hr) || !lpsz || !*lpsz)
|
|
{
|
|
//Check if there is a Return-Receipt-To header
|
|
hr = MimeOleGetBodyPropW(pMessage, HBODY_ROOT, PIDTOSTR(PID_HDR_RETRCPTTO),
|
|
NOFLAGS, &lpsz);
|
|
|
|
if (FAILED(hr) || !lpsz || !*lpsz)
|
|
{
|
|
if (hr == MIME_E_NOT_FOUND)
|
|
{
|
|
//this is a legitimate error, so we don't want to show an error to the user
|
|
hr = S_OK;
|
|
}
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
if (dwOption == MDN_PROMPTFOR_SENDRECEIPT)
|
|
{
|
|
if (!PromptReturnReceipts(pStoreCB))
|
|
goto exit;
|
|
}
|
|
|
|
var.vt = VT_LPSTR;
|
|
|
|
IF_FAILEXIT(hr = pMessage->GetProp(PIDTOSTR(PID_ATT_ACCOUNTID), NOFLAGS, &var));
|
|
|
|
IF_FAILEXIT(hr = g_pAcctMan->FindAccount(AP_ACCOUNT_ID, var.pszVal, &pTempAccount));
|
|
|
|
if ((dwOption == MDN_SENDRECEIPT_AUTO) && (!!DwGetOption(OPT_TO_CC_LINE_RCPT)))
|
|
{
|
|
IF_FAILEXIT(hr = CheckForLists(pMessage, pStoreCB, pTempAccount));
|
|
|
|
if (hr == S_FALSE)
|
|
{
|
|
// My name is not found in the list. So we don't send a receipt.
|
|
// However this is not failure.
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
IF_FAILEXIT(hr = HrCreateMessage (&pMessageRcpt));
|
|
|
|
IF_FAILEXIT(hr = SetRootHeaderFields(pMessageRcpt, pMessage, lpsz, READRECEIPT));
|
|
|
|
IF_FAILEXIT(hr = HrSetAccountByAccount(pMessageRcpt, pTempAccount));
|
|
|
|
IF_FAILEXIT(hr = HrGetWabalFromMsg(pMessageRcpt, &lpWabal));
|
|
|
|
IF_FAILEXIT(hr = HrSetSenderInfoUtil(pMessageRcpt, pTempAccount, lpWabal, TRUE, 0, FALSE));
|
|
|
|
IF_FAILEXIT(hr = HrSetWabalOnMsg(pMessageRcpt, lpWabal));
|
|
|
|
fSendImmediate = (DwGetOption(OPT_SENDIMMEDIATE) && !g_pConMan->IsGlobalOffline());
|
|
|
|
IF_FAILEXIT(hr = SendMailToOutBox((IStoreCallback*)pStoreCB, pMessageRcpt, fSendImmediate, FALSE, fMail));
|
|
|
|
exit:
|
|
|
|
//Show an error if it failed
|
|
if (FAILED(hr))
|
|
ShowErrorMessage(pStoreCB);
|
|
|
|
g_pStore->FreeRecord(&FolderInfo);
|
|
|
|
SafeMemFree(var.pszVal);
|
|
|
|
pTable->ReleaseRow(pMsgInfo);
|
|
|
|
SafeRelease(pMessageRcpt);
|
|
|
|
SafeRelease(pTempAccount);
|
|
|
|
SafeRelease(lpWabal);
|
|
|
|
SafeMemFree(lpsz);
|
|
|
|
if(!pMsg)
|
|
SafeRelease(pMessage);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT SetRootHeaderFields(IMimeMessage *pMessageRcpt,
|
|
IMimeMessage *pOriginalMsg,
|
|
LPWSTR lpszNotificationTo,
|
|
RECEIPTTYPE ReceiptType)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
LPWSTR lpsz = NULL;
|
|
LPWSTR szParam = NULL;
|
|
UINT ResId;
|
|
LPWSTR pszRefs = NULL;
|
|
LPWSTR pszOrigRefs = NULL;
|
|
LPWSTR pszNewRef = NULL;
|
|
WCHAR lpBuffer[CCHMAX_STRINGRES];
|
|
int cch = 0;
|
|
|
|
// Trace
|
|
TraceCall("_SetRootHeaderFields");
|
|
|
|
// Set the subject and the To field.
|
|
IF_FAILEXIT(hr = MimeOleSetBodyPropW(pMessageRcpt, HBODY_ROOT, PIDTOSTR(PID_HDR_TO), NOFLAGS, lpszNotificationTo));
|
|
|
|
IF_FAILEXIT(hr = MimeOleGetBodyPropW(pOriginalMsg, HBODY_ROOT, STR_ATT_NORMSUBJ, NOFLAGS, &lpsz));
|
|
|
|
switch (ReceiptType)
|
|
{
|
|
case DELETERECEIPT:
|
|
ResId = idsDeleteReceipt;
|
|
break;
|
|
|
|
case READRECEIPT:
|
|
default:
|
|
ResId = idsReadReceipt;
|
|
break;
|
|
}
|
|
|
|
if (fMessageEncodingMatch(pOriginalMsg))
|
|
{
|
|
AthLoadStringW(ResId, lpBuffer, ARRAYSIZE(lpBuffer));
|
|
}
|
|
else
|
|
{
|
|
//The encoding didn't match, so we just load english headers
|
|
StrCpyNW(lpBuffer, c_szReadReceipt, ARRAYSIZE(lpBuffer));
|
|
}
|
|
|
|
cch = lstrlenW(lpsz) + lstrlenW(lpBuffer) + 1;
|
|
IF_FAILEXIT(hr = HrAlloc((LPVOID*)&szParam, cch * sizeof(WCHAR)));
|
|
|
|
wnsprintfW(szParam, cch, lpBuffer, lpsz);
|
|
|
|
IF_FAILEXIT(hr = MimeOleSetBodyPropW(pMessageRcpt, HBODY_ROOT, PIDTOSTR(PID_HDR_SUBJECT), NOFLAGS, szParam));
|
|
|
|
//Set Time
|
|
IF_FAILEXIT(hr = HrSetSentTimeProp(pMessageRcpt, NULL));
|
|
|
|
//Set References property
|
|
IF_FAILEXIT(hr = MimeOleGetBodyPropW(pOriginalMsg, HBODY_ROOT, PIDTOSTR(PID_HDR_MESSAGEID), NOFLAGS, &pszNewRef));
|
|
|
|
//No need to check for return value. It gets handled correctly in HrCreateReferences
|
|
MimeOleGetBodyPropW(pOriginalMsg, HBODY_ROOT, PIDTOSTR(PID_HDR_REFS), NOFLAGS, &pszOrigRefs);
|
|
|
|
IF_FAILEXIT(hr = HrCreateReferences(pszOrigRefs, pszNewRef, &pszRefs));
|
|
|
|
IF_FAILEXIT(hr = MimeOleSetBodyPropW(pMessageRcpt, HBODY_ROOT, PIDTOSTR(PID_HDR_REFS), NOFLAGS, pszRefs));
|
|
|
|
//Readable text
|
|
//TODO: Change the file name depending on the ReceiptType
|
|
IF_FAILEXIT(hr = InsertReadableText(pMessageRcpt, pOriginalMsg));
|
|
|
|
//Create the second part
|
|
IF_FAILEXIT(hr = InsertSecondComponent(pMessageRcpt, pOriginalMsg));
|
|
|
|
//Set Content-type field. Content-type: multipart/report; report-type=disposition-notification;
|
|
//Content-type is multipart, sub-content-type is report and report-type is a parameter whose
|
|
//value should be set to disposition-notification
|
|
IF_FAILEXIT(hr = MimeOleSetBodyPropA(pMessageRcpt, HBODY_ROOT, PIDTOSTR(PID_HDR_CNTTYPE), NOFLAGS, c_szMultiPartReport));
|
|
|
|
IF_FAILEXIT(hr = MimeOleSetBodyPropA(pMessageRcpt, HBODY_ROOT, STR_PAR_REPORTTYPE, PDF_ENCODED, c_szDispositionNotification));
|
|
|
|
exit:
|
|
SafeMemFree(lpsz);
|
|
SafeMimeOleFree(pszNewRef);
|
|
SafeMemFree(szParam);
|
|
SafeMimeOleFree(pszOrigRefs);
|
|
SafeMemFree(pszRefs);
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT InsertReadableText(IMimeMessage *pMessageRcpt, IMimeMessage *pOriginalMsg)
|
|
{
|
|
HBODY hBody;
|
|
IStream *pStream = NULL;
|
|
HRESULT hr = S_OK;
|
|
LPWSTR lpsz = NULL;
|
|
ULONG cbWritten;
|
|
WCHAR lpBuffer[CCHMAX_STRINGRES];
|
|
HCHARSET hCharset = NULL;
|
|
WCHAR wszReceiptSentDate[CCHMAX_STRINGRES];
|
|
WCHAR wszOriginalSentDate[CCHMAX_STRINGRES];
|
|
PROPVARIANT varOriginal;
|
|
PROPVARIANT var;
|
|
INETCSETINFO CsetInfo = {0};
|
|
|
|
IF_FAILEXIT(hr = MimeOleGetBodyPropW(pOriginalMsg, HBODY_ROOT, PIDTOSTR(PID_HDR_TO), NOFLAGS, &lpsz));
|
|
|
|
IF_FAILEXIT(hr = MimeOleCreateVirtualStream((IStream**)&pStream));
|
|
|
|
varOriginal.vt = VT_FILETIME;
|
|
IF_FAILEXIT(hr = pOriginalMsg->GetProp(PIDTOSTR(PID_ATT_SENTTIME), 0, &varOriginal));
|
|
|
|
|
|
var.vt = VT_FILETIME;
|
|
IF_FAILEXIT(hr = pMessageRcpt->GetProp(PIDTOSTR(PID_ATT_SENTTIME), 0, &var));
|
|
|
|
if (fMessageEncodingMatch(pOriginalMsg))
|
|
{
|
|
AthLoadStringW(idsReadableTextFirst, lpBuffer, CCHMAX_STRINGRES);
|
|
|
|
IF_FAILEXIT(hr = pStream->Write(lpBuffer, lstrlenW(lpBuffer) * sizeof(WCHAR), &cbWritten));
|
|
|
|
IF_FAILEXIT(hr = pStream->Write(lpsz, lstrlenW(lpsz) * sizeof(WCHAR), &cbWritten));
|
|
|
|
*lpBuffer = 0;
|
|
|
|
AthLoadStringW(idsReceiptAt, lpBuffer, CCHMAX_STRINGRES);
|
|
|
|
IF_FAILEXIT(hr = pStream->Write(lpBuffer, lstrlenW(lpBuffer) * sizeof(WCHAR), &cbWritten));
|
|
|
|
*wszOriginalSentDate = 0;
|
|
AthFileTimeToDateTimeW(&varOriginal.filetime, wszOriginalSentDate, ARRAYSIZE(wszOriginalSentDate),
|
|
DTM_NOSECONDS);
|
|
|
|
IF_FAILEXIT(hr = pStream->Write(wszOriginalSentDate, lstrlenW(wszOriginalSentDate) * sizeof(*wszOriginalSentDate),
|
|
&cbWritten));
|
|
|
|
AthLoadStringW(idsReadableTextSecond, lpBuffer, CCHMAX_STRINGRES);
|
|
|
|
IF_FAILEXIT(hr = pStream->Write(lpBuffer, lstrlenW(lpBuffer) * sizeof(WCHAR), &cbWritten));
|
|
|
|
*wszReceiptSentDate = 0;
|
|
AthFileTimeToDateTimeW(&var.filetime, wszReceiptSentDate, ARRAYSIZE(wszReceiptSentDate),
|
|
DTM_NOSECONDS);
|
|
}
|
|
else
|
|
{
|
|
//Insert English headers and content
|
|
|
|
IF_FAILEXIT(hr = pStream->Write(c_szReadableTextFirst, cbReadableTextFirst, &cbWritten));
|
|
|
|
IF_FAILEXIT(hr = pStream->Write(lpsz, lstrlenW(lpsz) * sizeof(WCHAR), &cbWritten));
|
|
|
|
IF_FAILEXIT(hr = pStream->Write(c_szReceiptsAt, cbReceiptsAt, &cbWritten));
|
|
|
|
//Original Sent Date
|
|
*wszOriginalSentDate = 0;
|
|
AthFileTimeToDateTimeW(&varOriginal.filetime, wszOriginalSentDate, ARRAYSIZE(wszOriginalSentDate),
|
|
DTM_FORCEWESTERN | DTM_NOSECONDS);
|
|
|
|
IF_FAILEXIT(hr = pStream->Write(wszOriginalSentDate, lstrlenW(wszOriginalSentDate) * sizeof(*wszOriginalSentDate),
|
|
&cbWritten));
|
|
|
|
//Second line of readable text
|
|
IF_FAILEXIT(hr = pStream->Write(c_szReadableTextSecond, cbReadableTextSecond, &cbWritten));
|
|
|
|
|
|
//Receipt Sent Date
|
|
*wszReceiptSentDate = 0;
|
|
AthFileTimeToDateTimeW(&var.filetime, wszReceiptSentDate, ARRAYSIZE(wszReceiptSentDate),
|
|
DTM_FORCEWESTERN | DTM_NOSECONDS);
|
|
}
|
|
|
|
IF_FAILEXIT(hr = pStream->Write(wszReceiptSentDate, lstrlenW(wszReceiptSentDate) * sizeof(*wszReceiptSentDate),
|
|
&cbWritten));
|
|
|
|
IF_FAILEXIT(hr = pOriginalMsg->GetCharset(&hCharset));
|
|
|
|
// re-map CP_JAUTODETECT and CP_KAUTODETECT if necessary
|
|
// re-map iso-2022-jp to default charset if they are in the same category
|
|
IF_FAILEXIT(hr = MimeOleGetCharsetInfo(hCharset, &CsetInfo));
|
|
|
|
IF_NULLEXIT(hCharset = GetMimeCharsetFromCodePage(GetMapCP(CsetInfo.cpiInternet, FALSE)));
|
|
|
|
IF_FAILEXIT(hr = pMessageRcpt->SetCharset(hCharset, CSET_APPLY_ALL));
|
|
|
|
IF_FAILEXIT(hr = pMessageRcpt->SetTextBody(TXT_PLAIN, IET_UNICODE, NULL, pStream, &hBody));
|
|
|
|
exit:
|
|
SafeRelease(pStream);
|
|
SafeMemFree(lpsz);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT InsertSecondComponent(IMimeMessage *pMessageRcpt, IMimeMessage *pOriginalMsg)
|
|
{
|
|
HBODY hBody;
|
|
ULONG cbWritten;
|
|
IStream *pStream = NULL;
|
|
LPTSTR lpsz = NULL;
|
|
HRESULT hr = S_OK;
|
|
|
|
IF_FAILEXIT(hr = MimeOleCreateVirtualStream((IStream**)&pStream));
|
|
|
|
//Final Recipient
|
|
IF_FAILEXIT(hr = AddOriginalAndFinalRecipient(pOriginalMsg, pMessageRcpt, pStream));
|
|
|
|
//Original Message Id
|
|
IF_FAILEXIT(hr = MimeOleGetBodyPropA(pOriginalMsg, HBODY_ROOT, PIDTOSTR(PID_HDR_MESSAGEID), NOFLAGS, &lpsz));
|
|
|
|
IF_FAILEXIT(hr = pStream->Write(c_szOriginalMessageId, cbOriginalMessageId, &cbWritten));
|
|
|
|
IF_FAILEXIT(hr = pStream->Write(lpsz, lstrlen(lpsz) * sizeof(TCHAR), &cbWritten));
|
|
|
|
|
|
//TODO:If the receipt type is deleted, change the last parameter to reflect the correct string
|
|
|
|
IF_FAILEXIT(hr = pStream->Write(c_szDisposition, cbDisposition, &cbWritten));
|
|
|
|
if (DwGetOption(OPT_MDN_SEND_RECEIPT) == MDN_PROMPTFOR_SENDRECEIPT)
|
|
IF_FAILEXIT(hr = pStream->Write(c_szMDNSendManually, cbMDNSendManually, &cbWritten));
|
|
else
|
|
IF_FAILEXIT(hr = pStream->Write(c_szMDNSendAutomatically, cbMDNSendAutomatically, &cbWritten));
|
|
|
|
IF_FAILEXIT(hr = pStream->Write(c_szDisplayed, cbDisplayed, &cbWritten));
|
|
|
|
IF_FAILEXIT(hr = pStream->Commit(STGC_DEFAULT));
|
|
|
|
IF_FAILEXIT(hr = pMessageRcpt->AttachObject(IID_IStream, pStream, &hBody));
|
|
|
|
IF_FAILEXIT(hr = MimeOleSetBodyPropA(pMessageRcpt, hBody, PIDTOSTR(PID_HDR_CNTTYPE), NOFLAGS, c_szMessageDispNotification));
|
|
|
|
//Change the content-disposition header field to inline, so that this body gets copied and not get attached.
|
|
IF_FAILEXIT(hr = MimeOleSetBodyPropA(pMessageRcpt, hBody, PIDTOSTR(PID_HDR_CNTDISP), NOFLAGS, STR_DIS_INLINE));
|
|
|
|
exit:
|
|
MemFree(lpsz);
|
|
ReleaseObj(pStream);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT AddOriginalAndFinalRecipient(IMimeMessage *pOriginalMsg,
|
|
IMimeMessage *pMessageRcpt,
|
|
IStream *pStream)
|
|
{
|
|
IMimeEnumAddressTypes *pEnumAddrTypes = NULL;
|
|
HRESULT hr = S_OK;
|
|
ULONG cbWritten;
|
|
ULONG Count;
|
|
ADDRESSPROPS AddressProps;
|
|
ULONG cFetched;
|
|
IMimeAddressTable *pAddrTable = NULL;
|
|
LPTSTR lpszOriginalRecip = NULL;
|
|
ADDRESSLIST addrList = {0};
|
|
|
|
IF_FAILEXIT(hr = pOriginalMsg->BindToObject(HBODY_ROOT, IID_IMimeAddressTable, (LPVOID*)&pAddrTable));
|
|
|
|
IF_FAILEXIT(hr = pAddrTable->EnumTypes(IAT_FROM, IAP_EMAIL, &pEnumAddrTypes));
|
|
|
|
#ifdef DEBUG
|
|
IF_FAILEXIT(hr = pEnumAddrTypes->Count(&Count));
|
|
|
|
Assert (Count == 1);
|
|
#endif DEBUG
|
|
|
|
IF_FAILEXIT(hr = pEnumAddrTypes->Next(1, &AddressProps, &cFetched));
|
|
|
|
Assert(cFetched == 1);
|
|
|
|
if (!(AddressProps.pszEmail) || !(*AddressProps.pszEmail))
|
|
{
|
|
hr = E_FAIL;
|
|
goto exit;
|
|
}
|
|
|
|
IF_FAILEXIT(hr = pStream->Write(c_szFinalRecipient, cbFinalRecipient, &cbWritten));
|
|
|
|
IF_FAILEXIT(hr = pStream->Write(AddressProps.pszEmail, lstrlen(AddressProps.pszEmail) * sizeof(TCHAR), &cbWritten));
|
|
|
|
hr = MimeOleGetBodyPropA(pOriginalMsg, HBODY_ROOT, STR_HDR_ORIG_RECIPIENT, NOFLAGS, &lpszOriginalRecip);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
IF_FAILEXIT(hr = MimeOleParseRfc822Address(IAT_TO, IET_ENCODED, lpszOriginalRecip, &addrList));
|
|
|
|
if (addrList.cAdrs > 0)
|
|
{
|
|
IF_FAILEXIT(hr = pStream->Write(c_szOriginalRecipient, cbOriginalRecipient, &cbWritten));
|
|
|
|
IF_FAILEXIT(hr = pStream->Write(addrList.prgAdr[0].pszEmail, lstrlen(addrList.prgAdr[0].pszEmail), &cbWritten));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (hr == MIME_E_NOT_FOUND)
|
|
hr = S_OK;
|
|
}
|
|
|
|
exit:
|
|
if (g_pMoleAlloc)
|
|
{
|
|
g_pMoleAlloc->FreeAddressProps(&AddressProps);
|
|
|
|
if (addrList.cAdrs)
|
|
g_pMoleAlloc->FreeAddressList(&addrList);
|
|
}
|
|
|
|
ReleaseObj(pEnumAddrTypes);
|
|
|
|
ReleaseObj(pAddrTable);
|
|
|
|
MemFree(lpszOriginalRecip);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CheckForLists(IMimeMessage *pOriginalMsg, IStoreCallback *pStoreCB, IImnAccount *pDefAccount)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IMimeEnumAddressTypes *pEnumAddrTypes = NULL;
|
|
ULONG cbAddrTypes;
|
|
ULONG cFetched;
|
|
ADDRESSPROPS *prgAddress = NULL;
|
|
TCHAR szEmail[CCHMAX_EMAIL_ADDRESS];
|
|
DWORD index;
|
|
|
|
IF_FAILEXIT(hr = pOriginalMsg->EnumAddressTypes(IAT_TO | IAT_CC, IAP_EMAIL, &pEnumAddrTypes));
|
|
|
|
IF_FAILEXIT(hr = pEnumAddrTypes->Count(&cbAddrTypes));
|
|
|
|
IF_FAILEXIT(hr = HrAlloc((LPVOID*)&prgAddress, cbAddrTypes * sizeof(ADDRESSPROPS)));
|
|
|
|
IF_FAILEXIT(hr = pEnumAddrTypes->Next(cbAddrTypes, prgAddress, &cFetched));
|
|
|
|
IF_FAILEXIT(hr = pDefAccount->GetPropSz(AP_SMTP_EMAIL_ADDRESS, szEmail, ARRAYSIZE(szEmail)));
|
|
|
|
if (!(*szEmail))
|
|
{
|
|
hr = E_FAIL;
|
|
goto exit;
|
|
}
|
|
|
|
for (index = 0; index < cFetched; index++)
|
|
{
|
|
if (lstrcmpi(szEmail, (prgAddress + index)->pszEmail) == 0)
|
|
break;
|
|
}
|
|
|
|
if (index == cFetched)
|
|
{
|
|
//We did not find it.
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
exit:
|
|
|
|
if (g_pMoleAlloc && prgAddress)
|
|
{
|
|
for (index = 0; index < cFetched; index++)
|
|
{
|
|
g_pMoleAlloc->FreeAddressProps(&prgAddress[index]);
|
|
}
|
|
}
|
|
|
|
MemFree(prgAddress);
|
|
|
|
ReleaseObj(pEnumAddrTypes);
|
|
|
|
return hr;
|
|
}
|
|
|
|
void ShowErrorMessage(IStoreCallback *pStoreCB)
|
|
{
|
|
HWND hwnd;
|
|
|
|
Assert(pStoreCB);
|
|
|
|
if (SUCCEEDED(pStoreCB->GetParentWindow(0, &hwnd)))
|
|
{
|
|
AthMessageBoxW(hwnd, MAKEINTRESOURCEW(idsAthena), MAKEINTRESOURCEW(idsReceiptsError),
|
|
0, MB_OK);
|
|
}
|
|
}
|
|
|
|
BOOL PromptReturnReceipts(IStoreCallback *pStoreCB)
|
|
{
|
|
HWND hwnd;
|
|
int idAnswer;
|
|
BOOL fRet = FALSE;
|
|
// HWND hwndFocus;
|
|
|
|
if (SUCCEEDED(pStoreCB->GetParentWindow(0, &hwnd)))
|
|
{
|
|
/*
|
|
hwndFocus = GetFocus();
|
|
if (hwndFocus != hwnd)
|
|
hwnd = hwndFocus;
|
|
*/
|
|
|
|
idAnswer = AthMessageBoxW(hwnd, MAKEINTRESOURCEW(idsAthena), MAKEINTRESOURCEW(idsPromptReturnReceipts),
|
|
0, MB_YESNO | MB_ICONEXCLAMATION );
|
|
|
|
fRet = (idAnswer == IDYES);
|
|
}
|
|
|
|
return fRet;
|
|
}
|
|
|
|
BOOL IsMDN(IMimeMessage *pMsg)
|
|
{
|
|
LPTSTR lpsz = NULL;
|
|
BOOL fRetVal = FALSE;
|
|
|
|
|
|
if (SUCCEEDED(MimeOleGetBodyPropA(pMsg, HBODY_ROOT, STR_PAR_REPORTTYPE, NOFLAGS, &lpsz)) && (lpsz) && (*lpsz))
|
|
{
|
|
if (lstrcmp(c_szDispositionNotification, lpsz))
|
|
{
|
|
fRetVal = TRUE;
|
|
}
|
|
|
|
MemFree(lpsz);
|
|
}
|
|
return fRetVal;
|
|
}
|
|
|
|
DWORD GetLockKeyValue(LPCTSTR pszValue)
|
|
{
|
|
DWORD cbData;
|
|
DWORD dwLocked = FALSE;
|
|
DWORD dwType;
|
|
HKEY hKeyLM;
|
|
|
|
cbData = sizeof(DWORD);
|
|
if ((ERROR_SUCCESS != SHGetValue(HKEY_LOCAL_MACHINE, STR_REG_PATH_POLICY, c_szRequestMDNLocked, &dwType, (LPBYTE)&dwLocked, &cbData)) &&
|
|
(ERROR_SUCCESS != AthUserGetValue(NULL, pszValue, &dwType, (LPBYTE)&dwLocked, &cbData)))
|
|
dwLocked = FALSE;
|
|
|
|
return dwLocked;
|
|
}
|
|
|
|
BOOL fMessageEncodingMatch(IMimeMessage *pMsg)
|
|
{
|
|
INETCSETINFO CharsetInfo;
|
|
BOOL fret = FALSE;
|
|
HRESULT hr = S_OK;
|
|
HCHARSET hCharset = NULL;
|
|
CODEPAGEINFO CodePage = {0};
|
|
|
|
Assert(pMsg);
|
|
|
|
IF_FAILEXIT(hr = pMsg->GetCharset(&hCharset));
|
|
|
|
IF_FAILEXIT(hr = MimeOleGetCharsetInfo(hCharset, &CharsetInfo));
|
|
|
|
/*
|
|
if (CharsetInfo.cpiWindows == GetACP() || CharsetInfo.cpiWindows == CP_UNICODE)
|
|
fret = TRUE;
|
|
*/
|
|
|
|
IF_FAILEXIT(hr = MimeOleGetCodePageInfo(CharsetInfo.cpiInternet, &CodePage));
|
|
|
|
if (CodePage.cpiFamily == GetACP() || CodePage.cpiFamily == CP_UNICODE)
|
|
fret = TRUE;
|
|
exit:
|
|
|
|
return fret;
|
|
}
|
|
|
|
#ifdef SMIME_V3
|
|
|
|
static const BYTE RgbASNForSHASign[11] =
|
|
{
|
|
0x30, 0x09, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e,
|
|
0x03, 0x02, 0x1a
|
|
};
|
|
|
|
|
|
// Auto association of signing certificate for secure receipt
|
|
BOOL AutoAssociateCert(BOOL *fAllowTryAgain, HWND hwnd, IImnAccount *pTempAccount)
|
|
{
|
|
if(*fAllowTryAgain)
|
|
{
|
|
*fAllowTryAgain = FALSE;
|
|
if (SUCCEEDED(_HrFindMyCertForAccount(hwnd, NULL, pTempAccount, FALSE)))
|
|
return(TRUE);
|
|
}
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
void ErrorSendSecReceipt(HWND hwnd, HRESULT hr, IImnAccount *pAccount)
|
|
{
|
|
if(hr == HR_E_ATHSEC_NOCERTTOSIGN)
|
|
{
|
|
if(DialogBoxParam(g_hLocRes,
|
|
MAKEINTRESOURCE(iddErrSecurityNoSigningCert), hwnd,
|
|
ErrSecurityNoSigningCertDlgProc, NULL) == idGetDigitalIDs)
|
|
GetDigitalIDs(pAccount);
|
|
}
|
|
else
|
|
AthMessageBoxW(hwnd, MAKEINTRESOURCEW(idsAthena), MAKEINTRESOURCEW(idsCannotSendSecReceipt),
|
|
0, MB_OK | MB_ICONSTOP);
|
|
return;
|
|
}
|
|
|
|
// Process secure receipts
|
|
HRESULT ProcessSecureReceipt(IMimeMessage * pMsg, IStoreCallback *pStoreCB)
|
|
{
|
|
|
|
IMimeMessage *pMessageRcpt = NULL;
|
|
IMimeBody * pBody = NULL;
|
|
IMimeBody * pBodyRec = NULL;
|
|
IMimeSecurity2 * pSMIME3 = NULL;
|
|
CERT_NAME_BLOB *rgReceiptFromList = NULL;
|
|
DWORD cReceiptFromList = 0;
|
|
PCX509CERT pCert = NULL;
|
|
THUMBBLOB tbCert = {0, 0};
|
|
HCERTSTORE hMyCertStore = NULL;
|
|
X509CERTRESULT certResult;
|
|
CERTSTATE cs;
|
|
LPVOID pv = NULL;
|
|
DWORD dwBits = 40;
|
|
DWORD cb = 0;
|
|
LPBYTE pBlobData = NULL;
|
|
ULONG ulSecurityType = MST_CLASS_SMIME_V1;
|
|
|
|
LPWABAL lpWabal = NULL;
|
|
PROPVARIANT var = {0};
|
|
DWORD dwOption = 0;
|
|
UINT uiRes = 0;
|
|
HRESULT hr = S_OK;
|
|
IImnAccount *pTempAccount = NULL;
|
|
HWND hwnd = NULL;
|
|
TCHAR szEmail[CCHMAX_EMAIL_ADDRESS];
|
|
BOOL fSendImmediate = FALSE;
|
|
LPWSTR lpsz = NULL;
|
|
WCHAR lpBuffer[CCHMAX_STRINGRES];
|
|
LPWSTR szParam = NULL;
|
|
SECSTATE secStateRec = {0};
|
|
BOOL fAllowTryAgain = TRUE;
|
|
PCCERT_CONTEXT *rgCertChain = NULL;
|
|
DWORD cCertChain = 0;
|
|
const DWORD dwIgnore = CERT_VALIDITY_NO_CRL_FOUND;
|
|
DWORD dwTrust = 0;
|
|
LPWSTR pszRefs = NULL;
|
|
LPWSTR pszOrigRefs = NULL;
|
|
LPWSTR pszNewRef = NULL;
|
|
HCHARSET hCharset = NULL;
|
|
INETCSETINFO CsetInfo = {0};
|
|
HBODY hBody = NULL;
|
|
int cch;
|
|
|
|
Assert(pMsg != NULL);
|
|
|
|
// get windof for error messages
|
|
IF_FAILEXIT(hr = pStoreCB->GetParentWindow(0, &hwnd));
|
|
|
|
// if option set DO NOT send secure receipt then exit
|
|
dwOption = DwGetOption(OPT_MDN_SEC_RECEIPT);
|
|
if (dwOption == MDN_DONT_SENDRECEIPT)
|
|
goto exit;
|
|
|
|
// check do we have secure receipt request in message?
|
|
IF_FAILEXIT(hr = HrGetInnerLayer(pMsg, &hBody));
|
|
|
|
IF_FAILEXIT(hr = pMsg->BindToObject(hBody ? hBody : HBODY_ROOT, IID_IMimeBody, (void**)&pBody));
|
|
|
|
IF_FAILEXIT(hr = pBody->GetOption(OID_SECURITY_TYPE, &var));
|
|
|
|
if(!(var.ulVal & MST_RECEIPT_REQUEST))
|
|
{
|
|
var.ulVal = 0; // Set to 0, because var.pszVal and var.ulVal point to the same address.
|
|
hr = S_OK;
|
|
goto exit;
|
|
}
|
|
// Check do we trust this message: Bug 78118
|
|
IF_FAILEXIT(hr = HrGetSecurityState(pMsg, &secStateRec, NULL));
|
|
if(!IsSignTrusted(&secStateRec))
|
|
{
|
|
// do not show any error message in this case, just exit
|
|
hr = S_OK;
|
|
goto exit;
|
|
}
|
|
|
|
// we have request, check that we would like to send receipt
|
|
if (dwOption == MDN_PROMPTFOR_SENDRECEIPT)
|
|
{
|
|
uiRes = (UINT) DialogBoxParamWrapW(g_hLocRes, MAKEINTRESOURCEW(iddSecResponse),
|
|
hwnd, SecRecResDlgProc, (LPARAM) 0);
|
|
|
|
if(uiRes == 0)
|
|
{
|
|
hr = S_FALSE;
|
|
goto exit;
|
|
}
|
|
else if((uiRes != IDOK) && (uiRes != IDYES)) // IDYES means we will encrypt receipt
|
|
{
|
|
hr = S_OK;
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
// Get SMIME3 Security interface on message
|
|
IF_FAILEXIT(hr = pMsg->BindToObject(HBODY_ROOT, IID_IMimeSecurity2, (LPVOID *) &pSMIME3));
|
|
|
|
// Get List of people who should send receipts
|
|
IF_FAILEXIT(hr = pSMIME3->GetReceiptSendersList(0, &cReceiptFromList,&rgReceiptFromList));
|
|
|
|
// Check if asking for receipt from noone
|
|
if (hr == S_FALSE)
|
|
{
|
|
hr = S_OK;
|
|
goto exit;
|
|
}
|
|
|
|
// Check account information
|
|
var.vt = VT_LPSTR;
|
|
|
|
IF_FAILEXIT(hr = pMsg->GetProp(PIDTOSTR(PID_ATT_ACCOUNTID), NOFLAGS, &var));
|
|
|
|
if(FAILED(hr = g_pAcctMan->FindAccount(AP_ACCOUNT_ID, var.pszVal, &pTempAccount)))
|
|
{
|
|
MemFree(var.pszVal);
|
|
goto exit;
|
|
}
|
|
|
|
SafeMemFree(var.pszVal);
|
|
|
|
// Check that we are in secure list
|
|
IF_FAILEXIT(hr = pTempAccount->GetPropSz(AP_SMTP_EMAIL_ADDRESS, szEmail, ARRAYSIZE(szEmail)));
|
|
|
|
if(!FNameInList(szEmail, cReceiptFromList,rgReceiptFromList))
|
|
{
|
|
// we are not in list
|
|
hr = S_FALSE;
|
|
goto exit;
|
|
}
|
|
|
|
// Get a certificate for receipt
|
|
Try_agian:
|
|
if((hr = pTempAccount->GetProp(AP_SMTP_CERTIFICATE, NULL, &tbCert.cbSize)) != S_OK)
|
|
{
|
|
if(AutoAssociateCert(&fAllowTryAgain, hwnd, pTempAccount))
|
|
goto Try_agian;
|
|
else
|
|
{
|
|
hr = HR_E_ATHSEC_NOCERTTOSIGN;
|
|
goto exit;
|
|
}
|
|
|
|
}
|
|
IF_FAILEXIT(hr = HrAlloc((void**)&tbCert.pBlobData, tbCert.cbSize));
|
|
IF_FAILEXIT(hr = pTempAccount->GetProp(AP_SMTP_CERTIFICATE, tbCert.pBlobData, &tbCert.cbSize));
|
|
|
|
hMyCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, X509_ASN_ENCODING,
|
|
NULL, CERT_SYSTEM_STORE_CURRENT_USER, c_szMyCertStore);
|
|
|
|
if (hMyCertStore == NULL)
|
|
goto exit;
|
|
|
|
certResult.cEntries = 1;
|
|
certResult.rgcs = &cs;
|
|
certResult.rgpCert = &pCert;
|
|
|
|
if((hr = MimeOleGetCertsFromThumbprints(&tbCert, &certResult, &hMyCertStore, 1) != S_OK))
|
|
{
|
|
if(AutoAssociateCert(&fAllowTryAgain, hwnd, pTempAccount))
|
|
goto Try_agian;
|
|
else
|
|
{
|
|
hr = HR_E_ATHSEC_NOCERTTOSIGN;
|
|
goto exit;
|
|
}
|
|
|
|
}
|
|
|
|
// Check certificate
|
|
// As to CRLs, if we'll ever have one!
|
|
dwTrust = DwGenerateTrustedChain(hwnd, NULL, pCert,
|
|
dwIgnore, TRUE, &cCertChain, &rgCertChain);
|
|
|
|
if (rgCertChain)
|
|
{
|
|
for (cCertChain--; int(cCertChain)>=0; cCertChain--)
|
|
CertFreeCertificateContext(rgCertChain[cCertChain]);
|
|
MemFree(rgCertChain);
|
|
rgCertChain = NULL;
|
|
}
|
|
|
|
if (dwTrust)
|
|
{
|
|
if(AutoAssociateCert(&fAllowTryAgain, hwnd, pTempAccount))
|
|
goto Try_agian;
|
|
else
|
|
{
|
|
hr = HR_E_ATHSEC_NOCERTTOSIGN;
|
|
goto exit;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// Create receipt message
|
|
IF_FAILEXIT(hr = pSMIME3->CreateReceipt(0, lstrlen(szEmail), (const BYTE *) szEmail, 1, &pCert, &pMessageRcpt));
|
|
|
|
// IF_FAILEXIT(hr = HrCreateMessage (&pMessageRcpt));
|
|
|
|
// IF_FAILEXIT(hr = SetRootHeaderFields(pMessageRcpt, pMsg, szEmail, READRECEIPT)); // szEmail is bug!
|
|
|
|
// Subject
|
|
IF_FAILEXIT(hr = MimeOleGetBodyPropW(pMsg, HBODY_ROOT, STR_ATT_NORMSUBJ, NOFLAGS, &lpsz));
|
|
if (fMessageEncodingMatch(pMsg))
|
|
{
|
|
AthLoadStringW(idsSecureReceiptText, lpBuffer, ARRAYSIZE(lpBuffer));
|
|
}
|
|
else
|
|
{
|
|
//The encoding didn't match, so we just load english headers
|
|
StrCpyNW(lpBuffer, c_szSecReadReceipt, ARRAYSIZE(lpBuffer));
|
|
}
|
|
|
|
// Init security options
|
|
#if 0
|
|
if(DwGetOption(OPT_MAIL_INCLUDECERT))
|
|
{
|
|
ulSecurityType |= ((DwGetOption(OPT_OPAQUE_SIGN)) ? MST_THIS_BLOBSIGN : MST_THIS_SIGN);
|
|
HrInitSecurityOptions(pMessageRcpt, ulSecurityType);
|
|
}
|
|
#endif // 0
|
|
|
|
cch = lstrlenW(lpsz) + lstrlenW(lpBuffer) + 1;
|
|
IF_FAILEXIT(hr = HrAlloc((LPVOID*)&szParam, cch * sizeof(WCHAR)));
|
|
|
|
wnsprintfW(szParam, cch, lpBuffer, lpsz);
|
|
|
|
IF_FAILEXIT(hr = MimeOleSetBodyPropW(pMessageRcpt, HBODY_ROOT, PIDTOSTR(PID_HDR_SUBJECT), NOFLAGS, szParam));
|
|
|
|
//Set Time
|
|
IF_FAILEXIT(hr = HrSetSentTimeProp(pMessageRcpt, NULL));
|
|
|
|
//Set References property
|
|
IF_FAILEXIT(hr = MimeOleGetBodyPropW(pMsg, HBODY_ROOT, PIDTOSTR(PID_HDR_MESSAGEID), NOFLAGS, &pszNewRef));
|
|
|
|
//No need to check for return value. It gets handled correctly in HrCreateReferences
|
|
MimeOleGetBodyPropW(pMsg, HBODY_ROOT, PIDTOSTR(PID_HDR_REFS), NOFLAGS, &pszOrigRefs);
|
|
|
|
IF_FAILEXIT(hr = HrCreateReferences(pszOrigRefs, pszNewRef, &pszRefs));
|
|
|
|
IF_FAILEXIT(hr = MimeOleSetBodyPropW(pMessageRcpt, HBODY_ROOT, PIDTOSTR(PID_HDR_REFS), NOFLAGS, pszRefs));
|
|
|
|
IF_FAILEXIT(hr = HrSetAccountByAccount(pMessageRcpt, pTempAccount));
|
|
//
|
|
IF_FAILEXIT(hr = HrGetWabalFromMsg(pMessageRcpt, &lpWabal));
|
|
|
|
IF_FAILEXIT(hr = HrSetSenderInfoUtil(pMessageRcpt, pTempAccount, lpWabal, TRUE, 0, FALSE));
|
|
|
|
IF_FAILEXIT(hr = HrSetWabalOnMsg(pMessageRcpt, lpWabal));
|
|
|
|
//#if 0
|
|
IF_FAILEXIT(hr = pMessageRcpt->BindToObject(HBODY_ROOT, IID_IMimeBody, (LPVOID *) &pBodyRec));
|
|
|
|
// Set hash algorithm
|
|
// Init with no symcap gives max allowed by providers
|
|
MimeOleSMimeCapInit(NULL, NULL, &pv);
|
|
|
|
MimeOleSMimeCapGetHashAlg(pv, NULL, &cb, &dwBits);
|
|
|
|
var.vt = VT_BLOB;
|
|
if(cb > 0)
|
|
{
|
|
if(!MemAlloc((LPVOID *)&pBlobData, cb))
|
|
goto exit;
|
|
|
|
// ZeroMemory(&pBlobData, cb);
|
|
|
|
MimeOleSMimeCapGetHashAlg(pv, pBlobData, &cb, &dwBits);
|
|
var.blob.cbSize = cb;
|
|
var.blob.pBlobData = pBlobData;
|
|
}
|
|
else
|
|
{
|
|
var.blob.cbSize = sizeof(RgbASNForSHASign);
|
|
var.blob.pBlobData = (LPBYTE) RgbASNForSHASign;
|
|
}
|
|
|
|
IF_FAILEXIT(hr = pBodyRec->SetOption(OID_SECURITY_ALG_HASH, &var));
|
|
|
|
#ifdef _WIN64
|
|
var.vt = VT_UI8;
|
|
var.pulVal = (ULONG *) hwnd;
|
|
IF_FAILEXIT(hr = pBody->SetOption(OID_SECURITY_HWND_OWNER_64, &var));
|
|
#else
|
|
var.vt = VT_UI4;
|
|
var.ulVal = (DWORD) hwnd;
|
|
IF_FAILEXIT(hr = pBodyRec->SetOption(OID_SECURITY_HWND_OWNER, &var));
|
|
var.ulVal = 0; // Set to 0, because var.pszVal and var.ulVal point to the same address.
|
|
#endif // _WIN64
|
|
|
|
// IF_FAILEXIT(hr = pMessageRcpt->Commit(0));
|
|
// #endif //0
|
|
|
|
IF_FAILEXIT(hr = pMsg->GetCharset(&hCharset));
|
|
|
|
// re-map CP_JAUTODETECT and CP_KAUTODETECT if necessary
|
|
// re-map iso-2022-jp to default charset if they are in the same category
|
|
|
|
IF_FAILEXIT(hr = MimeOleGetCharsetInfo(hCharset, &CsetInfo));
|
|
|
|
IF_NULLEXIT(hCharset = GetMimeCharsetFromCodePage(GetMapCP(CsetInfo.cpiInternet, FALSE)));
|
|
|
|
IF_FAILEXIT(hr = pMessageRcpt->SetCharset(hCharset, CSET_APPLY_ALL));
|
|
|
|
// should be new header
|
|
|
|
fSendImmediate = (DwGetOption(OPT_SENDIMMEDIATE) && !g_pConMan->IsGlobalOffline());
|
|
|
|
if (DwGetOption(OPT_MAIL_INCLUDECERT))
|
|
IF_FAILEXIT(hr = SendSecureMailToOutBox((IStoreCallback*)pStoreCB, pMessageRcpt, fSendImmediate, FALSE, TRUE, NULL));
|
|
else
|
|
IF_FAILEXIT(hr = SendMailToOutBox((IStoreCallback*)pStoreCB, pMessageRcpt, fSendImmediate, FALSE, TRUE));
|
|
exit:
|
|
if(FAILED(hr))
|
|
ErrorSendSecReceipt(hwnd, hr, pTempAccount);
|
|
|
|
CleanupSECSTATE(&secStateRec);
|
|
SafeMemFree(lpsz);
|
|
SafeMemFree(szParam);
|
|
SafeMemFree(pBlobData);
|
|
SafeMemFree(pv);
|
|
SafeRelease(pBodyRec);
|
|
SafeRelease(pMessageRcpt);
|
|
|
|
if(hMyCertStore)
|
|
CertCloseStore(hMyCertStore, 0);
|
|
|
|
if(pCert)
|
|
CertFreeCertificateContext(pCert);
|
|
|
|
// if(tbCert.pBlobData)
|
|
SafeMemFree(tbCert.pBlobData);
|
|
SafeRelease(lpWabal);
|
|
|
|
SafeRelease(pTempAccount);
|
|
SafeRelease(pSMIME3);
|
|
SafeRelease(pBody);
|
|
SafeMimeOleFree(pszNewRef);
|
|
SafeMimeOleFree(pszOrigRefs);
|
|
MemFree(pszRefs);
|
|
return(hr);
|
|
}
|
|
|
|
INT_PTR CALLBACK SecRecResDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch(msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
CenterDialog(hwndDlg);
|
|
CheckDlgButton(hwndDlg, IDC_ENCRECEIPT, (!!DwGetOption(OPT_SECREC_ENCRYPT)) ? BST_CHECKED : BST_UNCHECKED);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDOK:
|
|
|
|
EndDialog(hwndDlg, IsDlgButtonChecked(hwndDlg, IDC_ENCRECEIPT) ? IDYES : IDOK);
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
EndDialog(hwndDlg, IDCANCEL);
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
#endif // SMIME_V3
|