Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

CopyTo() Fails with E_OUTOFMEMORY for Large Recipient List

98 views
Skip to first unread message

Sameer

unread,
Jun 24, 2011, 7:09:25 AM6/24/11
to Devesh....@gmail.com
I am trying to export the .msg (calendar item) to PST and during the
process CopyTo() function fails with error E_OUTOFMEMORY.

I am using Outlook 2003 SP3, Windows 2003 Enterprise Edition SP2.

I have gone through MS KB articles, applied the HF, configured
registry key "RecipientMax" to big value (50000).
Outlook 2003: http://support.microsoft.com/kb/948074
Outlook 2007: http://support.microsoft.com/kb/952295

Also gone through the web/group articles, and the once which is very
close to my issue is as follows. I see that Mr. Devesh Sarwate was
finally resolved his issue and hoping his helping hand here.
http://groups.google.com/group/microsoft.public.platformsdk.mapi/browse_thread/thread/30214cda42256ff4/574632a785dbc638?lnk=gst&q=CopyTo+fails+large+recipients#574632a785dbc638

I have used STGOPTIONS myOpts.ulSectorSize = 4096; as well.

When I use ::StgOpenStorage() or ::StgOpenStorageEx(), CopyTo() fails
with E_OUTOFMEMORY. When I use the ::StgCreateStorageEx(), CopyTo
succeeds but nothing is written or copied to message. When I open the
newly created PST, the message is pain empty without any fields.

My complete code is as follows...

// Get memory allocation function
LPMALLOC pMalloc = MAPIGetDefaultMalloc();

// Convert new file name to WideChar
cbStrSize = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (TCHAR *)
(LPCTSTR)szFileName, -1, lpWideCharStr, 0);

MAPIAllocateBuffer(cbStrSize * sizeof(WCHAR), (LPVOID
*)&lpWideCharStr);

MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (TCHAR *)
(LPCTSTR)szFileName, -1, lpWideCharStr, cbStrSize);

// Open the compound file
/* if (FAILED(hr = ::StgOpenStorage( lpWideCharStr,
NULL,
STGM_READWRITE | STGM_TRANSACTED,
NULL,
0,
&pStorage)))
{
MAPIFreeBuffer(lpWideCharStr);
return hr;
}
*/
STGOPTIONS myOpts = {0};
myOpts.usVersion = 1,//STGOPTIONS_VERSION;
myOpts.reserved = 0;
myOpts.ulSectorSize = 4096;

if (FAILED( hr = ::StgCreateStorageEx(
lpWideCharStr,
STGM_CREATE | STGM_READWRITE | STGM_TRANSACTED |
STGM_SHARE_EXCLUSIVE,
STGFMT_DOCFILE,
0, //FILE_FLAG_NO_BUFFERING,
&myOpts,
0,
__uuidof(IStorage),
(LPVOID*)&pStorage) ))
{
MAPIFreeBuffer(lpWideCharStr);
return hr;
}

// Create new message
if (!FAILED(hr = lpFolder->CreateMessage(0, 0, &pNewMsg)))
{
// Open an IMessage interface on an IStorage object
if (!FAILED(hr = ::OpenIMsgOnIStg( NULL,
MAPIAllocateBuffer,
MAPIAllocateMore,
MAPIFreeBuffer,
pMalloc,
NULL,
pStorage,
NULL, 0, 0, &pIMsg)))
{
//The body of Latin2 messages changes inappropriately when RTFSync
is called
DWORD dwCodePage = 0;
DWORD dwLocaleID = 0;

BOOL bSkipSync = (SUCCEEDED(GetMessageCodePage(pIMsg, &dwCodePage,
&dwLocaleID)) && (dwCodePage == 1250));

if (!bSkipSync)
{
// If the PR_RTF_IN_SYNC property is missing or is FALSE, we must
call RTFSync
// on pIMsg with the RTF_SYNC_BODY_CHANGED flag set before reading
pIMsg's
// PR_RTF_COMPRESSED property (see documentation on RTFSync
function).
ULONG ulFlags = 0;
LPSPropValue pSPVRtfInSync = NULL;
hr = HrGetOneProp(pIMsg, PR_RTF_IN_SYNC, &pSPVRtfInSync);
if (FAILED(hr) || !pSPVRtfInSync->Value.b)
{
bMsgUpdated = FALSE;
ulFlags |= RTF_SYNC_BODY_CHANGED;
}

if (pSPVRtfInSync)
{
MAPIFreeBuffer(pSPVRtfInSync);
pSPVRtfInSync = NULL;
}

// If the PR_STORE_SUPPORT_MASK property and if the STORE_RTF_OK
flag is not
// set, then we must call RTFSync on pIMsg with the
RTF_SYNC_RTF_CHANGES flag
// set to resync the PR_BODY property from the PR_RTF_COMPRESSED
property.
LPSPropValue pSPVStoreSupportMask = NULL;
hr = HrGetOneProp(pIMsg, PR_STORE_SUPPORT_MASK,
&pSPVStoreSupportMask);
if ((SUCCEEDED(hr)) && ((pSPVStoreSupportMask->Value.l &
STORE_RTF_OK) != 0))
{
bMsgUpdated = FALSE;
ulFlags |= RTF_SYNC_RTF_CHANGED;
}

if (pSPVStoreSupportMask)
{
MAPIFreeBuffer(pSPVStoreSupportMask);
pSPVStoreSupportMask = NULL;
}

// Finally, if there is NO PR_BODY property, then let's call
RTFSync on pIMsg
// with the RTF_SYNC_RTF_CHANGES flag set to recreate the PR_BODY
property from
// the PR_RTF_COMPRESSED property.
LPSPropValue pSPVBody = NULL;
hr = HrGetOneProp(pIMsg, PR_BODY, &pSPVBody);
if (FAILED(hr))
{
bMsgUpdated = FALSE;
// If the Compressed type is "MELA" then do not set the below
flag,
// otherwise it will hang on RTFSync() call inside SafeRTFSync()
function
if (!IsRTFCompressTypeMatch(pIMsg, "MELA"))
ulFlags |= RTF_SYNC_RTF_CHANGED;
}

if (pSPVBody)
{
MAPIFreeBuffer(pSPVBody);
pSPVBody = NULL;
}

if (0 != ulFlags)
{
bMsgUpdated = FALSE;
hr = SafeRTFSync(pIMsg, ulFlags, &bMsgUpdated);
}


}

// Specify properties to exclude in the copy operation. These are
// the properties that Exchange excludes to save bits and time.
// Should not be necessary to exclude these, but speeds the process
// when a lot of messages are being copied.
SizedSPropTagArray(19, excludeTags);
excludeTags.cValues = 18;
excludeTags.aulPropTag[0] = 0x664b0014;
excludeTags.aulPropTag[1] = PR_DISPLAY_BCC;
excludeTags.aulPropTag[2] = PR_DISPLAY_CC;
excludeTags.aulPropTag[3] = PR_DISPLAY_TO;
excludeTags.aulPropTag[4] = PR_ENTRYID;
excludeTags.aulPropTag[5] = PR_MESSAGE_SIZE;
excludeTags.aulPropTag[6] = PR_PARENT_ENTRYID;
excludeTags.aulPropTag[7] = PR_RECORD_KEY;
excludeTags.aulPropTag[8] = PR_STORE_ENTRYID;
excludeTags.aulPropTag[9] = PR_STORE_RECORD_KEY;
excludeTags.aulPropTag[10] = PR_MDB_PROVIDER;
excludeTags.aulPropTag[11] = PR_ACCESS;
excludeTags.aulPropTag[12] = PR_HASATTACH;
excludeTags.aulPropTag[13] = PR_OBJECT_TYPE;
excludeTags.aulPropTag[14] = PR_ACCESS_LEVEL;
excludeTags.aulPropTag[15] = 0x664a000b;
excludeTags.aulPropTag[16] = 0x6644001e;
excludeTags.aulPropTag[17] = 0x3fea000b;

// Emails show RTF message as plain text when retrieved from being
shortcut
if(!
FAILED(hr=HrGetOneProp((LPMAPIPROP)pIMsg,PR_MESSAGE_CLASS,&lpMessageClassPropValue)))
{
csMessageClass = lpMessageClassPropValue->Value.lpszA;
csMessageClass.MakeLower();
if(csMessageClass.Find(_T("report.ipm.note.ipnrn")) != -1)
{
//SDR 31176- Need to exclude the PR_RTF_COMPRESSED property to
avoid
//corrupt body for read recipient mail in search client
excludeTags.cValues = 19;
excludeTags.aulPropTag[18] = PR_RTF_COMPRESSED;

}
MAPIFreeBuffer(lpMessageClassPropValue);
}

if (!FAILED(hr = pIMsg->CopyTo( 0, NULL,
(LPSPropTagArray)&excludeTags,
0, NULL, &IID_IMessage, pNewMsg, 0, NULL)))
{
if (!bSkipSync)
{
// If the STORE_RTF_OK flag is not set in the
PR_STORE_SUPPORT_MASK property,
// we must call RTFSync with the RTF_SYNC_RTF_CHANGED flag set
after we modify
// the new message's PR_RTF_COMPRESSED property by calling CopyTo
(see
// documentation on RTFSync function)
if (!(dwStoreSupportMask & STORE_RTF_OK))
{
bMsgUpdated = FALSE;
hr = SafeRTFSync(pNewMsg, RTF_SYNC_RTF_CHANGED, &bMsgUpdated);
}
}


// If we were passed a proparray...
if (lpPropArray)
{
if(FAILED(pNewMsg->SetProps(dwNumProps, lpPropArray, NULL)))
{
OutputDebugString("SetProps failed; Setting Prop Array. \n");
}

}
else // just set the read flag
{
SPropValue spUpdatedValue[1];

spUpdatedValue[0].dwAlignPad = 0;
spUpdatedValue[0].ulPropTag = PR_MESSAGE_FLAGS;
spUpdatedValue[0].Value.l = MSGFLAG_READ;

if(FAILED(pNewMsg->SetProps(1, spUpdatedValue, NULL)))
{
OutputDebugString("SetProps failed; Setting Message as Read.
\n");
}

}

// save changes to IMessage object.
if (!FAILED(hr = pNewMsg->SaveChanges(KEEP_OPEN_READWRITE)))
{
// save changes in storage of new doc file
hr = pStorage->Commit(STGC_DEFAULT);

ULONG ulObjType;
LPSPropValue pEid = NULL;
LPSPropValue *lppEid = lppRetEid == NULL ? &pEid : lppRetEid;

if (!FAILED(hr = HrGetOneProp(pNewMsg, PR_ENTRYID, lppEid)))
{
hr = lpFolder->OpenEntry((*lppEid)->Value.bin.cb,
(LPENTRYID)(*lppEid)->Value.bin.lpb,
NULL,
MAPI_MODIFY,
&ulObjType,
(LPUNKNOWN *)&lpNewMsg);
}
if (lppRetEid == NULL)
MAPIFreeBuffer(pEid);
}

}

pIMsg->Release();
}

pNewMsg->Release();
}

// free objects and clean up memory
MAPIFreeBuffer(lpWideCharStr);

pStorage->Release();

if (lppMsg)
*lppMsg = lpNewMsg;
else
UlRelease(lpNewMsg);

0 new messages