📄 sendmail.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
#include <mapidefs.h>
#include <mapicode.h>
#include <mapitags.h>
#include <mapix.h>
#include <mapiutil.h>
#include <cemapi.h>
//Macros
#ifndef EXIT_ON_FAILED
#define EXIT_ON_FAILED(_hr)\
if (FAILED(_hr))\
{ \
RETAILMSG(1,(_T("CEMAPI: FAILED(%x)at %hs:%d\n"), \
_hr, __FILE__, __LINE__)); \
goto FuncExit; \
}
#endif //EXIT_ON_FAILED
#ifndef RELEASE_OBJ
#define RELEASE_OBJ(s)\
if (s != NULL)\
{ \
s->Release(); \
s = NULL; \
}
#endif //RELEASE_OBJ
//Function Prototypes
HRESULT CEMAPI_SetMessageRecipients(LPMESSAGE pmsg);
HRESULT CEMAPI_SetMessageProps(LPMESSAGE pmsg);
void CEMAPI_AddRecipients(LPWSTR pszSrc, ULONG ulType, ADRLIST* plst, LPWSTR& pszLocalRecips, LPSPropValue& pval);
ULONG CountRecipsInString(LPCWSTR psz);
HRESULT CEMAPI_AttachFile(LPMESSAGE pmsg);
// **************************************************************************
// Function Name: WinMain
// Purpose: Standard Win32 entry point
// Arguments:
// none are used for this sample
//
// Return Values:
// int
// app exit code
//
// Description:
//
// This function controls the main flow of the application. A summary:
// Logon to the message store
// Get the message stores table
// For each entry(i.e. local account)
// Open current store entry
// Get the Drafts folder(necessary for outgoing mail)
// Create a new message in this folder
// Set relevant message properties(Recipients, Subject, Body, etc)
// Send the message
// Clean up
//
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPWSTR lpCmdLine,
int CmdShow
)
{
HRESULT hr;
IMAPISession * pSession = NULL;
IMAPITable * pTable = NULL;
SRowSet * psrs = NULL;
IMsgStore * pStore = NULL;
ULONG rgTags[] = { 1, PR_CE_IPM_DRAFTS_ENTRYID };
ULONG cValues = 0;
SPropValue * rgprops = NULL;
SPropValue * rgpropsMsg = NULL;
LPMAPIFOLDER pfldrDrafts = NULL;
IMessage * pmsg = NULL;
// First logon to the store.
hr = MAPILogonEx(NULL, NULL, NULL, NULL, &pSession);
EXIT_ON_FAILED(hr);
// Get the message stores table
hr = pSession->GetMsgStoresTable(MAPI_UNICODE, &pTable);
EXIT_ON_FAILED(hr);
while (SUCCEEDED(pTable->QueryRows(1, 0, &psrs)))
{
// Check number of rows returned. Since the above call only asks for one,
// anything else means we are at the end of the table
if (1 != psrs->cRows)
{
break;
}
// Make sure we got the props we need
if ((1 > psrs->aRow[0].cValues)||(PR_ENTRYID != psrs->aRow[0].lpProps[0].ulPropTag))
{
MessageBox(NULL, L"Store missing PR_ENTRYID!", L"Error", MB_OK);
hr = E_FAIL;
break;
}
// Open this message store
hr = pSession->OpenMsgStore(NULL,
psrs->aRow[0].lpProps[0].Value.bin.cb,
(ENTRYID *)psrs->aRow[0].lpProps[0].Value.bin.lpb,
NULL,
0,
&pStore);
EXIT_ON_FAILED(hr);
// Now get the Drafts folder. In order for a message to be sent by MAPI, it must be created
// in the Drafts folder
hr = pStore->GetProps((SPropTagArray *)rgTags, MAPI_UNICODE, &cValues, &rgprops);
EXIT_ON_FAILED(hr);
ASSERT(rgprops);
ASSERT(rgprops[0].ulPropTag == PR_CE_IPM_DRAFTS_ENTRYID);
hr = pStore->OpenEntry(rgprops[0].Value.bin.cb,
(LPENTRYID)rgprops[0].Value.bin.lpb,
NULL,
MAPI_MODIFY,
NULL,
reinterpret_cast <IUnknown **>(&pfldrDrafts));
EXIT_ON_FAILED(hr);
ASSERT(pfldrDrafts);
// Now create a message...
hr = pfldrDrafts->CreateMessage(NULL, 0, &pmsg);
EXIT_ON_FAILED(hr);
ASSERT(pmsg);
// Now set the some properies on the message....
CEMAPI_SetMessageProps(pmsg);
// attach a bogus file
hr=CEMAPI_AttachFile(pmsg);
EXIT_ON_FAILED(hr);
// Now send the message
hr = pmsg->SubmitMessage(0);
EXIT_ON_FAILED(hr);
// Clean up
MAPIFreeBuffer(rgprops);
MAPIFreeBuffer(rgpropsMsg);
FreeProws(psrs);
rgprops = NULL;
rgpropsMsg = NULL;
psrs = NULL;
RELEASE_OBJ(pmsg);
RELEASE_OBJ(pfldrDrafts);
RELEASE_OBJ(pStore);
}
FuncExit:
//Clean up
MAPIFreeBuffer(rgprops);
MAPIFreeBuffer(rgpropsMsg);
FreeProws(psrs);
RELEASE_OBJ(pmsg);
RELEASE_OBJ(pfldrDrafts);
RELEASE_OBJ(pStore);
RELEASE_OBJ(pTable);
RELEASE_OBJ(pSession);
return 0;
}
// **************************************************************************
// Function Name: CountRecipsInString
// Purpose: Counts the number of recipient addresses in a given string
// Arguments:
// IN LPCWSTR psz - string of recipients
//
// Return Values:
// ULONG
// Count of recipients(number of semi-colons + 1)contained in the input string
//
// Description:
//
// This function merely counts the number of semi-colons in a string and returns that
// number + 1. This can be interpreted as the number of recipients in a properly formatted
// recipient list
//
ULONG CountRecipsInString(
LPCWSTR psz
)
{
ULONG cRecips = 0;
if (psz != NULL)
{
if (*psz != '\0')
{
++cRecips;
}
while (*psz != L'\0')
{
if (*psz == L';')
{
++cRecips;
}
++psz;
}
}
return cRecips;
}
// **************************************************************************
// Function Name: CEMAPI_AddRecipients
// Purpose: Sets a message's recipient(s)to a hard-coded value
// Arguments:
// IN LPWSTR pszSrc - semi-colon delimited recipient list
// IN ULONG ulType - Recipient type(To, Cc, or Bcc)
// INOUT ADRLIST* plst - Recipient buffer, pointer is incremented and returned
// IN LPWSTR pszLocalRecips& - local copy of pszSrc
// INOUT LPSPropValue& - buffer to hold message props(address type, recip type, etc),
// incremented and returned
//
// Return Values:
// void
//
// Description:
//
// This function sets recipient properties for a list of recipients. Properties include
// the recipient type(To, Cc, or Bcc), the address type(always SMTP), and the e-mail
// address list. The properties are returned through the plst parameter.
//
void CEMAPI_AddRecipients(
LPWSTR pszSrc,
ULONG ulType,
ADRLIST* plst,
LPWSTR& pszLocalRecips,
LPSPropValue& pval
)
{
if (pszSrc == NULL)
{
return;
}
LPWSTR psz = pszSrc;
while (*psz != L'\0')
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -