|
|
// =====================================================================================
// m a p c o n v . c p p
// conver a MAPI message to and from an RFC 822/RFC 1521 (mime) internet message
// =====================================================================================
#include "pch.hxx"
#include <newimp.h>
#include "Imnapi.h"
#include "Mapiconv.h"
#include <impapi.h>
#include <import.h>
#include "demand.h"
LPSTR MapiStringDup (LPCTSTR lpcsz, LPVOID lpobj);
HRESULT HrImsgRecipToMapiRecip(LPMESSAGE lpMessage, LPIMSG lpImsg); HRESULT HrImsgAttachToMapiAttach(LPMESSAGE lpMessage, LPIMSG lpImsg);
// =====================================================================================
// MAPI Message Properties that I want
// =====================================================================================
#define PR_BODY_HTML PROP_TAG( PT_TSTRING, 0x1013)
enum { colSenderAddrType, colSenderName, colSenderEMail, colDelegateAddrType, colDelegateName, colDelegateEMail, colSubject, colReceiveTime, colSendTime, colPriority, colFlags, colLast1 };
SizedSPropTagArray (colLast1, sptMessageProps) = { colLast1, { PR_SENDER_ADDRTYPE, PR_SENDER_NAME, PR_SENDER_EMAIL_ADDRESS, PR_SENT_REPRESENTING_ADDRTYPE, PR_SENT_REPRESENTING_NAME, PR_SENT_REPRESENTING_EMAIL_ADDRESS, PR_SUBJECT, PR_MESSAGE_DELIVERY_TIME, PR_CLIENT_SUBMIT_TIME, PR_IMPORTANCE, PR_MESSAGE_FLAGS } };
// =====================================================================================
// MAPI Recip Props
// =====================================================================================
enum { colRecipAddrType, colRecipName, colRecipAddress, colRecipType, colLast2 };
SizedSPropTagArray (colLast2, sptRecipProps) = { colLast2, { PR_ADDRTYPE, PR_DISPLAY_NAME, PR_EMAIL_ADDRESS, PR_RECIPIENT_TYPE } };
// =====================================================================================
// MAPI Attachment Props
// =====================================================================================
enum { colAttMethod, colAttNum, colAttLongFilename, colAttPathname, colAttTag, colAttFilename, colAttExtension, colAttSize, colLast3 };
SizedSPropTagArray (colLast3, sptAttProps) = { colLast3, { PR_ATTACH_METHOD, PR_ATTACH_NUM, PR_ATTACH_LONG_FILENAME, PR_ATTACH_PATHNAME, PR_ATTACH_TAG, PR_ATTACH_FILENAME, PR_ATTACH_EXTENSION, PR_ATTACH_SIZE } };
char *GetRecipAddress(LPSPropValue ppropAddr, LPSPropValue ppropType) { char *sz, *szT;
sz = NULL;
if (PROP_TYPE(ppropAddr->ulPropTag) != PT_ERROR && PROP_TYPE(ppropType->ulPropTag) != PT_ERROR) { szT = ppropType->Value.lpszA;
if (lstrcmp(szT, "SMTP") == 0 || lstrcmp(szT, "MSNINET") == 0) { sz = PszDup(ppropAddr->Value.lpszA); } else if (lstrcmp(szT, "MSN") == 0 || lstrcmp(szT, "MSNLIST") == 0) { szT = ppropAddr->Value.lpszA; DWORD cch = lstrlen(szT) + 16; if (MemAlloc((void **)&sz, cch*sizeof(sz[0]))) { StrCpyN(sz, szT, cch); StrCatBuff(sz, "@msn.com", cch); } } }
return(sz); }
// =====================================================================================
// HrMapiToImsg
// =====================================================================================
HRESULT HrMapiToImsg (LPMESSAGE lpMessage, LPIMSG lpImsg) { // Locals
LPSPropValue ppropAddr, ppropType, ppropName; TCHAR szUnk[128]; int cchUnk; TCHAR *sz, *szT; HRESULT hr; ULONG cProp, i; LPSPropValue lpMsgPropValue = NULL; LPSRowSet lpRecipRows = NULL, lpAttRows = NULL; LPMAPITABLE lptblRecip = NULL, lptblAtt = NULL; LPATTACH lpAttach = NULL; LPMESSAGE lpMsgAtt = NULL; LPSTREAM lpstmBody = NULL;
cchUnk = LoadString(g_hInstImp, idsAddressUnknownFmt, szUnk, ARRAYSIZE(szUnk));
// Zero init
ZeroMemory (lpImsg, sizeof (IMSG));
// Get the propsw
hr = lpMessage->GetProps ((LPSPropTagArray)&sptMessageProps, 0, &cProp, &lpMsgPropValue); if (FAILED (hr)) goto exit;
// Subject
if (PROP_TYPE(lpMsgPropValue[colSubject].ulPropTag) != PT_ERROR) lpImsg->lpszSubject = PszDup(lpMsgPropValue[colSubject].Value.lpszA);
// Body
if (SUCCEEDED(lpMessage->OpenProperty(PR_BODY_HTML, (LPIID)&IID_IStream, 0, 0, (LPUNKNOWN *)&lpstmBody))) { if (SUCCEEDED(hr = CreateStreamOnHFile (NULL, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL, &lpImsg->lpstmHtml))) hr = HrCopyStream(lpstmBody, lpImsg->lpstmHtml, NULL);
lpstmBody->Release(); lpstmBody = NULL;
if (FAILED(hr)) goto exit; } else if (SUCCEEDED(lpMessage->OpenProperty(PR_BODY, (LPIID)&IID_IStream, 0, 0, (LPUNKNOWN *)&lpstmBody))) { if (SUCCEEDED(hr = CreateStreamOnHFile (NULL, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL, &lpImsg->lpstmBody))) hr = HrCopyStream(lpstmBody, lpImsg->lpstmBody, NULL);
lpstmBody->Release(); lpstmBody = NULL; if (FAILED(hr)) goto exit; }
// Send Time
if (PROP_TYPE(lpMsgPropValue[colSendTime].ulPropTag) != PT_ERROR) CopyMemory(&lpImsg->ftSend, &lpMsgPropValue[colSendTime].Value.ft, sizeof (FILETIME));
// Receive Time
if (PROP_TYPE(lpMsgPropValue[colReceiveTime].ulPropTag) != PT_ERROR) CopyMemory(&lpImsg->ftReceive, &lpMsgPropValue[colReceiveTime].Value.ft, sizeof (FILETIME));
// Priority
lpImsg->wPriority = PRI_NORMAL; if (PROP_TYPE(lpMsgPropValue[colPriority].ulPropTag) != PT_ERROR) { switch (lpMsgPropValue[colPriority].Value.l) { case IMPORTANCE_LOW: lpImsg->wPriority = PRI_LOW; break;
case IMPORTANCE_HIGH: lpImsg->wPriority = PRI_HIGH; break;
case IMPORTANCE_NORMAL: default: lpImsg->wPriority = PRI_NORMAL; break; } }
// message flags
if (PROP_TYPE(lpMsgPropValue[colFlags].ulPropTag) != PT_ERROR) lpImsg->uFlags = lpMsgPropValue[colFlags].Value.ul;
// Get the recipient table
hr = lpMessage->GetRecipientTable (0, &lptblRecip); if (FAILED (hr)) goto exit;
// Get all the rows of the recipient table
hr = lpHrQueryAllRows (lptblRecip, (LPSPropTagArray)&sptRecipProps, NULL, NULL, 0, &lpRecipRows); if (FAILED (hr)) goto exit;
// Allocate Recipient Array
lpImsg->cAddress = lpRecipRows->cRows + 1; if (!MemAlloc((void **)&lpImsg->lpIaddr, sizeof (IADDRINFO) * lpImsg->cAddress)) { hr = E_OUTOFMEMORY; goto exit; } ZeroMemory(lpImsg->lpIaddr, sizeof (IADDRINFO) * lpImsg->cAddress);
ppropAddr = &lpMsgPropValue[colDelegateEMail]; ppropType = &lpMsgPropValue[colDelegateAddrType]; ppropName = &lpMsgPropValue[colDelegateName];
if (PROP_TYPE(ppropAddr->ulPropTag) == PT_ERROR || PROP_TYPE(ppropType->ulPropTag) == PT_ERROR) { ppropAddr = &lpMsgPropValue[colSenderEMail]; ppropType = &lpMsgPropValue[colSenderAddrType]; ppropName = &lpMsgPropValue[colSenderName]; }
// Originator of the message "From: "
lpImsg->lpIaddr[0].dwType = IADDR_FROM; lpImsg->lpIaddr[0].lpszAddress = GetRecipAddress(ppropAddr, ppropType);
if (PROP_TYPE(ppropName->ulPropTag) != PT_ERROR) { szT = ppropName->Value.lpszA; if (lpImsg->lpIaddr[0].lpszAddress != NULL) { sz = PszDup(szT); } else { lpImsg->lpIaddr[0].lpszAddress = PszDup(szT); DWORD cchSz = lstrlen(szT) + cchUnk; if (!MemAlloc((void **)&sz, cchSz*sizeof(sz[0]))) { hr = E_OUTOFMEMORY; goto exit; } wnsprintf(sz, cchSz, szUnk, szT); }
lpImsg->lpIaddr[0].lpszDisplay = sz; } // Add in the rest of the recipients
for (i=0; i<lpRecipRows->cRows; i++) { Assert (i+1 < lpImsg->cAddress);
if (PROP_TYPE(lpRecipRows->aRow[i].lpProps[colRecipType].ulPropTag) != PT_ERROR) { switch (lpRecipRows->aRow[i].lpProps[colRecipType].Value.ul) { case MAPI_TO: case 0x10000000: /* MAPI_P1: */ lpImsg->lpIaddr[i+1].dwType = IADDR_TO; break;
case MAPI_ORIG: lpImsg->lpIaddr[i+1].dwType = IADDR_FROM; break;
case MAPI_CC: lpImsg->lpIaddr[i+1].dwType = IADDR_CC; break;
case MAPI_BCC: lpImsg->lpIaddr[i+1].dwType = IADDR_BCC; break;
default: Assert (FALSE); lpImsg->lpIaddr[i+1].dwType = IADDR_TO; break; } } else { lpImsg->lpIaddr[i+1].dwType = IADDR_TO; } lpImsg->lpIaddr[i+1].lpszAddress = GetRecipAddress(&lpRecipRows->aRow[i].lpProps[colRecipAddress], &lpRecipRows->aRow[i].lpProps[colRecipAddrType]);
if (PROP_TYPE(lpRecipRows->aRow[i].lpProps[colRecipName].ulPropTag) != PT_ERROR) { szT = lpRecipRows->aRow[i].lpProps[colRecipName].Value.lpszA; if (lpImsg->lpIaddr[i + 1].lpszAddress != NULL) { sz = PszDup(szT); } else { lpImsg->lpIaddr[i+1].lpszAddress = PszDup(szT); DWORD cchSz = lstrlen(szT) + cchUnk; if (!MemAlloc((void **)&sz, cchSz*sizeof(sz[0]))) { hr = E_OUTOFMEMORY; goto exit; } wnsprintf(sz, cchSz, szUnk, szT); }
lpImsg->lpIaddr[i + 1].lpszDisplay = sz; } }
// Free Rows
if (lpRecipRows) lpFreeProws (lpRecipRows); lpRecipRows = NULL;
// Attachments
hr = lpMessage->GetAttachmentTable (0, &lptblAtt); if (FAILED (hr)) goto exit;
// Get all the rows of the recipient table
hr = lpHrQueryAllRows (lptblAtt, (LPSPropTagArray)&sptAttProps, NULL, NULL, 0, &lpAttRows); if (FAILED (hr)) goto exit;
// Allocate files list
if (lpAttRows->cRows == 0) goto exit;
// Allocate memory
lpImsg->cAttach = lpAttRows->cRows; if (!MemAlloc((void **)&lpImsg->lpIatt, sizeof (IATTINFO) * lpImsg->cAttach)) { hr = E_OUTOFMEMORY; goto exit; }
// Zero init
ZeroMemory (lpImsg->lpIatt, sizeof (IATTINFO) * lpImsg->cAttach);
// Walk the rows
for (i=0; i<lpAttRows->cRows; i++) { if (PROP_TYPE(lpAttRows->aRow[i].lpProps[colAttMethod].ulPropTag) != PT_ERROR && PROP_TYPE(lpAttRows->aRow[i].lpProps[colAttNum].ulPropTag) != PT_ERROR) { // Basic Properties
if (PROP_TYPE(lpAttRows->aRow[i].lpProps[colAttPathname].ulPropTag) != PT_ERROR) { sz = lpAttRows->aRow[i].lpProps[colAttPathname].Value.lpszA; if (!FIsEmpty(sz)) lpImsg->lpIatt[i].lpszPathName = PszDup(sz); }
if (PROP_TYPE(lpAttRows->aRow[i].lpProps[colAttFilename].ulPropTag) != PT_ERROR) { sz = lpAttRows->aRow[i].lpProps[colAttFilename].Value.lpszA; if (!FIsEmpty(sz)) lpImsg->lpIatt[i].lpszFileName = PszDup(sz); }
if (lpImsg->lpIatt[i].lpszFileName == NULL && PROP_TYPE(lpAttRows->aRow[i].lpProps[colAttLongFilename].ulPropTag) != PT_ERROR) { sz = lpAttRows->aRow[i].lpProps[colAttLongFilename].Value.lpszA; if (!FIsEmpty(sz)) lpImsg->lpIatt[i].lpszFileName = PszDup(sz); }
if (PROP_TYPE(lpAttRows->aRow[i].lpProps[colAttExtension].ulPropTag) != PT_ERROR) { sz = lpAttRows->aRow[i].lpProps[colAttExtension].Value.lpszA; if (!FIsEmpty(sz)) lpImsg->lpIatt[i].lpszExt = PszDup(sz); }
// Open the attachment
hr = lpMessage->OpenAttach (lpAttRows->aRow[i].lpProps[colAttNum].Value.l, NULL, MAPI_BEST_ACCESS, &lpAttach); if (FAILED (hr)) { lpImsg->lpIatt[i].fError = TRUE; continue; }
// Handle the attachment method
switch (lpAttRows->aRow[i].lpProps[colAttMethod].Value.ul) { case NO_ATTACHMENT: lpImsg->lpIatt[i].dwType = 0; lpImsg->lpIatt[i].fError = TRUE; break;
case ATTACH_BY_REF_RESOLVE: case ATTACH_BY_VALUE: lpImsg->lpIatt[i].dwType = IATT_FILE; hr = lpAttach->OpenProperty (PR_ATTACH_DATA_BIN, (LPIID)&IID_IStream, 0, 0, (LPUNKNOWN *)&lpImsg->lpIatt[i].lpstmAtt); if (FAILED (hr)) lpImsg->lpIatt[i].fError = TRUE; break;
case ATTACH_BY_REF_ONLY: case ATTACH_BY_REFERENCE: lpImsg->lpIatt[i].dwType = IATT_FILE; hr = CreateStreamOnHFile (lpImsg->lpIatt[i].lpszPathName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL, &lpImsg->lpIatt[i].lpstmAtt); if (FAILED (hr)) lpImsg->lpIatt[i].fError = TRUE; break;
case ATTACH_EMBEDDED_MSG: lpImsg->lpIatt[i].dwType = IATT_MSG; hr = lpAttach->OpenProperty (PR_ATTACH_DATA_OBJ, (LPIID)&IID_IMessage, 0, 0, (LPUNKNOWN *)&lpMsgAtt); if (FAILED (hr) || lpMsgAtt == NULL) lpImsg->lpIatt[i].fError = TRUE; else { if (!MemAlloc((void **)&lpImsg->lpIatt[i].lpImsg, sizeof (IMSG))) lpImsg->lpIatt[i].fError = TRUE; else { hr = HrMapiToImsg (lpMsgAtt, lpImsg->lpIatt[i].lpImsg); if (FAILED (hr)) lpImsg->lpIatt[i].fError = TRUE; } lpMsgAtt->Release (); lpMsgAtt = NULL; } break;
case ATTACH_OLE: default: lpImsg->lpIatt[i].dwType = IATT_OLE; lpImsg->lpIatt[i].fError = TRUE; break; }
// Free Attachment
if (lpAttach) lpAttach->Release (); lpAttach = NULL; } }
hr = S_OK;
exit: // Cleanup
if (lpAttach) lpAttach->Release (); if (lptblAtt) lptblAtt->Release (); if (lpAttRows) lpFreeProws (lpAttRows); if (lpRecipRows) lpFreeProws (lpRecipRows); if (lpMsgPropValue) lpMAPIFreeBuffer (lpMsgPropValue); if (lptblRecip) lptblRecip->Release (); if (lpMsgAtt) lpMsgAtt->Release (); if (lpstmBody) lpstmBody->Release ();
// Done
return hr; }
// =====================================================================================
//
// HrImsgToMapi: lpImsg => lpMessage
//
// assumes lpMessage is initialized.
//
// =====================================================================================
HRESULT HrImsgToMapi(LPIMSG lpImsg, LPMESSAGE lpMessage) { // Locals
LPSTREAM lpstmBody; HRESULT hr = S_OK; ULONG i, cProp; LPSPropValue lpMsgPropValue = NULL; ULONG cPropMax = 13;
/*
properties to copy:
PR_SENDER_ADDRTYPE, PR_SENDER_NAME, PR_SENDER_EMAIL_ADDRESS, PR_SUBJECT, PR_MESSAGE_DELIVERY_TIME, PR_IMPORTANCE, PR_MESSAGE_FLAGS PR_MESSAGE_CLASS PR_SENT_REPRESENTING_NAME, PR_SENT_REPRESENTING_EMAIL_ADDRESS, PR_SENT_REPRESENTING_ADDRTYPE, */
Assert(lpMessage != NULL);
// create the propvalue array
hr = lpMAPIAllocateBuffer(cPropMax*sizeof(SPropValue), (LPVOID FAR*)&lpMsgPropValue); if (FAILED(hr)) goto exit;
ZeroMemory(lpMsgPropValue, cPropMax*sizeof(SPropValue)); cProp = 0; lpMsgPropValue[cProp].Value.lpszA = MapiStringDup("IPM.Note", lpMsgPropValue); lpMsgPropValue[cProp].ulPropTag = PR_MESSAGE_CLASS; cProp++;
// Subject
if (lpImsg->lpszSubject) { lpMsgPropValue[cProp].Value.lpszA = MapiStringDup(lpImsg->lpszSubject, lpMsgPropValue); lpMsgPropValue[cProp].ulPropTag = PR_SUBJECT; cProp++; Assert(cProp <= cPropMax); }
// Send Time
CopyMemory(&lpMsgPropValue[cProp].Value.ft, &lpImsg->ftSend, sizeof (FILETIME)); lpMsgPropValue[cProp].ulPropTag = PR_CLIENT_SUBMIT_TIME; cProp++; Assert(cProp <= cPropMax);
// Receive Time
CopyMemory(&lpMsgPropValue[cProp].Value.ft, &lpImsg->ftReceive, sizeof (FILETIME)); lpMsgPropValue[cProp].ulPropTag = PR_MESSAGE_DELIVERY_TIME; cProp++; Assert(cProp <= cPropMax);
// Priority
lpMsgPropValue[cProp].ulPropTag = PR_IMPORTANCE; switch (lpImsg->wPriority) { case PRI_HIGH: lpMsgPropValue[cProp].Value.l = IMPORTANCE_HIGH; break;
case PRI_LOW: lpMsgPropValue[cProp].Value.l = IMPORTANCE_LOW; break;
case PRI_NORMAL: default: lpMsgPropValue[cProp].Value.l = IMPORTANCE_NORMAL; break; } cProp++; Assert(cProp <= cPropMax);
// Message flags
lpMsgPropValue[cProp].ulPropTag = PR_MESSAGE_FLAGS; lpMsgPropValue[cProp].Value.ul = lpImsg->uFlags; cProp++; Assert(cProp <= cPropMax);
// recipients
if (FAILED(hr = HrImsgRecipToMapiRecip(lpMessage, lpImsg))) goto exit;
// sender information
for (i = 0; i < lpImsg->cAddress; i++) { Assert(lpImsg->lpIaddr != NULL);
if (lpImsg->lpIaddr[i].dwType == IADDR_FROM) { Assert(lpImsg->lpIaddr[i].lpszAddress); Assert(lpImsg->lpIaddr[i].lpszDisplay);
lpMsgPropValue[cProp].Value.lpszA = MapiStringDup(lpImsg->lpIaddr[i].lpszDisplay, lpMsgPropValue); lpMsgPropValue[cProp].ulPropTag = PR_SENDER_NAME; cProp++; lpMsgPropValue[cProp].Value.lpszA = MapiStringDup(lpImsg->lpIaddr[i].lpszDisplay, lpMsgPropValue); lpMsgPropValue[cProp].ulPropTag = PR_SENT_REPRESENTING_NAME; cProp++; Assert(cProp <= cPropMax);
lpMsgPropValue[cProp].Value.lpszA = MapiStringDup(lpImsg->lpIaddr[i].lpszAddress, lpMsgPropValue); lpMsgPropValue[cProp].ulPropTag = PR_SENDER_EMAIL_ADDRESS; cProp++; lpMsgPropValue[cProp].Value.lpszA = MapiStringDup(lpImsg->lpIaddr[i].lpszAddress, lpMsgPropValue); lpMsgPropValue[cProp].ulPropTag = PR_SENT_REPRESENTING_EMAIL_ADDRESS; cProp++; Assert(cProp <= cPropMax);
lpMsgPropValue[cProp].Value.lpszA = MapiStringDup("SMTP", lpMsgPropValue); lpMsgPropValue[cProp].ulPropTag = PR_SENDER_ADDRTYPE; cProp++; lpMsgPropValue[cProp].Value.lpszA = MapiStringDup("SMTP", lpMsgPropValue); lpMsgPropValue[cProp].ulPropTag = PR_SENT_REPRESENTING_ADDRTYPE; cProp++; Assert(cProp <= cPropMax);
break; } }
// attachment information
if (FAILED(hr = HrImsgAttachToMapiAttach(lpMessage, lpImsg))) goto exit;
// save changes
if (FAILED(hr = lpMessage->SetProps(cProp, lpMsgPropValue, NULL))) goto exit;
// Body
if (lpImsg->lpstmHtml && SUCCEEDED(lpMessage->OpenProperty(PR_BODY_HTML, (LPIID)&IID_IStream, 0, MAPI_CREATE | MAPI_MODIFY, (LPUNKNOWN *)&lpstmBody))) { hr = HrCopyStream(lpImsg->lpstmHtml, lpstmBody, NULL);
lpstmBody->Release();
if (FAILED(hr)) goto exit; }
if (lpImsg->lpstmBody && SUCCEEDED(lpMessage->OpenProperty(PR_BODY, (LPIID)&IID_IStream, 0, MAPI_CREATE | MAPI_MODIFY, (LPUNKNOWN *)&lpstmBody))) { hr = HrCopyStream(lpImsg->lpstmBody, lpstmBody, NULL);
lpstmBody->Release(); if (FAILED(hr)) goto exit; }
if (FAILED(hr = lpMessage->SaveChanges(0))) goto exit;
exit: if (lpMsgPropValue) lpMAPIFreeBuffer (lpMsgPropValue);
return hr; }
HRESULT HrImsgAttachToMapiAttach(LPMESSAGE lpMessage, LPIMSG lpImsg) { ULONG i, iAttach; HRESULT hr = S_OK;
if (!lpMessage || !lpImsg) return E_FAIL;
if (lpImsg->cAttach == 0) return S_OK;
if (!lpImsg->lpIatt) return E_FAIL;
/*
attachment properties and indices:
colAttMethod, colAttNum, colAttLongFilename, colAttPathname, colAttTag, colAttFilename, colAttExtension, colAttSize, colLast3
PR_ATTACH_METHOD, PR_ATTACH_NUM, PR_ATTACH_LONG_FILENAME, PR_ATTACH_PATHNAME, PR_ATTACH_TAG, PR_ATTACH_FILENAME, PR_ATTACH_EXTENSION, PR_ATTACH_SIZE */
for (i=0; i<lpImsg->cAttach; i++) { LPSPropValue rgPropVals = 0; ULONG cb = 0, cProp = 0; HRESULT hropen; LPMESSAGE lpmsg = NULL; LPSTREAM lpstm = 0; LPIATTINFO lpiatt = (LPIATTINFO)&(lpImsg->lpIatt[i]); LPATTACH lpAttach = 0; Assert(lpiatt);
if (lpiatt->fError) continue;
if (FAILED(lpMessage->CreateAttach(NULL, NULL, &iAttach, &lpAttach))) goto cleanup;
if (FAILED(lpMAPIAllocateBuffer(sizeof(SPropValue)*colLast3, (LPVOID*)&rgPropVals))) goto cleanup;
ZeroMemory(rgPropVals, sizeof(SPropValue)*colLast3);
if (lpiatt->lpszPathName) { rgPropVals[cProp].ulPropTag = PR_ATTACH_PATHNAME; rgPropVals[cProp].Value.lpszA = MapiStringDup(lpiatt->lpszPathName, rgPropVals); cProp++; }
if (lpiatt->lpszFileName) { rgPropVals[cProp].ulPropTag = PR_ATTACH_FILENAME; rgPropVals[cProp].Value.lpszA = MapiStringDup(lpiatt->lpszFileName, rgPropVals); cProp++; }
if (lpiatt->lpszExt) { rgPropVals[cProp].ulPropTag = PR_ATTACH_EXTENSION; rgPropVals[cProp].Value.lpszA = MapiStringDup(lpiatt->lpszExt, rgPropVals); cProp++; }
switch(lpiatt->dwType) { case IATT_FILE: rgPropVals[cProp].ulPropTag = PR_OBJECT_TYPE; rgPropVals[cProp].Value.ul = MAPI_ATTACH; cProp++;
rgPropVals[cProp].ulPropTag = PR_ATTACH_METHOD; rgPropVals[cProp].Value.ul = ATTACH_BY_VALUE; cProp++;
hropen = lpAttach->OpenProperty(PR_ATTACH_DATA_BIN, (LPIID)&IID_IStream, STGM_WRITE, MAPI_MODIFY | MAPI_CREATE, (LPUNKNOWN *)&lpstm); if (!FAILED(hropen)) { Assert(lpstm != NULL);
if (!FAILED(HrCopyStream(lpiatt->lpstmAtt, lpstm, &cb))) lpstm->Commit(0);
lpstm->Release(); lpstm=0; } break;
case IATT_MSG: rgPropVals[cProp].ulPropTag = PR_OBJECT_TYPE; rgPropVals[cProp].Value.ul = MAPI_MESSAGE; cProp++;
rgPropVals[cProp].ulPropTag = PR_ATTACH_METHOD; rgPropVals[cProp].Value.ul = ATTACH_EMBEDDED_MSG; cProp++;
hropen = lpAttach->OpenProperty(PR_ATTACH_DATA_OBJ, (LPIID)&IID_IMessage, 0, MAPI_MODIFY | MAPI_CREATE, (LPUNKNOWN *)&lpmsg); if (!FAILED(hropen)) { Assert(lpmsg != NULL);
HrImsgToMapi(lpiatt->lpImsg, lpmsg);
lpmsg->Release(); lpmsg = NULL; } break;
default: AssertSz(FALSE, "Unexpected attachment type!"); break; }
// need to set the property
hr = lpAttach->SetProps(cProp, rgPropVals, NULL); if (FAILED(hr)) goto cleanup; hr = lpAttach->SaveChanges(0); if (FAILED(hr)) goto cleanup;
cleanup: if (rgPropVals) { lpMAPIFreeBuffer(rgPropVals); rgPropVals = 0; }
if (lpAttach) { lpAttach->Release(); lpAttach = 0; } }
return hr; }
// =====================================================================================
//
// HrImsgRecipToMapiRecip:
//
// =====================================================================================
HRESULT HrImsgRecipToMapiRecip(LPMESSAGE lpMessage, LPIMSG lpImsg) { LPADRENTRY lpadrentry; ULONG cb, i; LPADRLIST lpadrlist = 0; LPSPropValue rgPropVals = 0; HRESULT hr = E_FAIL; if (lpImsg == NULL) return(E_FAIL);
if (lpImsg->cAddress == 0) return(S_OK);
if (lpMessage == NULL || lpImsg->lpIaddr == NULL) return(E_FAIL);
cb = sizeof(ADRLIST) + lpImsg->cAddress * sizeof(ADRENTRY); if (FAILED(lpMAPIAllocateBuffer(cb, (LPVOID*)&lpadrlist))) return(E_OUTOFMEMORY);
ZeroMemory(lpadrlist, cb);
// enumerate through the recipient list
for (i = 0; i < lpImsg->cAddress; i++) { if (lpImsg->lpIaddr[i].dwType == IADDR_FROM) continue;
lpadrentry = (LPADRENTRY)&(lpadrlist->aEntries[lpadrlist->cEntries]);
// this memory is freed by lpMessage
if (FAILED(lpMAPIAllocateBuffer(sizeof(SPropValue) * colLast2, (LPVOID *)&rgPropVals))) { hr = E_OUTOFMEMORY; goto exit; }
lpadrentry->cValues = 0; lpadrentry->rgPropVals = rgPropVals; lpadrlist->cEntries++;
rgPropVals[colRecipAddrType].ulPropTag = PR_ADDRTYPE; rgPropVals[colRecipAddrType].Value.lpszA = MapiStringDup("SMTP", rgPropVals); lpadrentry->cValues++; Assert(lpadrentry->cValues <= colLast2);
rgPropVals[colRecipName].ulPropTag = PR_DISPLAY_NAME; rgPropVals[colRecipName].Value.lpszA = MapiStringDup(lpImsg->lpIaddr[i].lpszDisplay, rgPropVals); lpadrentry->cValues++; Assert(lpadrentry->cValues <= colLast2);
rgPropVals[colRecipAddress].ulPropTag = PR_EMAIL_ADDRESS; rgPropVals[colRecipAddress].Value.lpszA = MapiStringDup(lpImsg->lpIaddr[i].lpszAddress, rgPropVals); lpadrentry->cValues++; Assert(lpadrentry->cValues <= colLast2);
rgPropVals[colRecipType].ulPropTag = PR_RECIPIENT_TYPE; switch(lpImsg->lpIaddr[i].dwType) { case IADDR_FROM: rgPropVals[colRecipType].Value.ul = MAPI_ORIG; break;
case IADDR_CC: rgPropVals[colRecipType].Value.ul = MAPI_CC; break;
case IADDR_BCC: rgPropVals[colRecipType].Value.ul = MAPI_BCC; break;
case IADDR_TO: default: rgPropVals[colRecipType].Value.ul = MAPI_TO; break; } lpadrentry->cValues++; Assert(lpadrentry->cValues <= colLast2);
// reset the variable so we don't free up on exit
rgPropVals = 0; }
hr = lpMessage->ModifyRecipients(MODRECIP_ADD, lpadrlist); exit: // Free the buffers
for (i = 0; i < lpadrlist->cEntries; i++) lpMAPIFreeBuffer(lpadrlist->aEntries[i].rgPropVals); lpMAPIFreeBuffer(lpadrlist);
return(hr); }
LPSTR MapiStringDup (LPCTSTR lpcsz, LPVOID lpobj) { LPSTR lpszDup = NULL;
if (lpcsz == NULL) return NULL;
INT nLen = lstrlen (lpcsz) + 1;
if (lpobj) { if (FAILED(lpMAPIAllocateMore(nLen*sizeof(TCHAR), lpobj, (LPVOID FAR*)&lpszDup))) return NULL; } else { if (FAILED(lpMAPIAllocateBuffer(nLen*sizeof(TCHAR), (LPVOID FAR*)&lpszDup))) return NULL; }
CopyMemory (lpszDup, lpcsz, nLen*sizeof(TCHAR));
return lpszDup; }
|