updating outlook from extended mapi

Joined
Oct 19, 2005
Messages
1
Reaction score
0
Hello all, I have a C# COM object that Interops with the OOM. I use this to control the user interface, create toolbars, etc..

I need to be able to create a full binary representation of the data found inside an single message, body and attachments. I need to be able to do this within code, because we are using this to create a encryption wrapper for email messages within Outlook.

I am tying into the Inspector Close and Inpector Open events. My goal is to automatically decrypt or encrypt a message based on this cycle.

I am using extended mapi now by retrieving the MAPIOBJECT from an MailItem from Inspector Object. I then retrieve the IUnknown pointer using:

Code:
//  Inside C# COM

Microsoft.Office.Interop.Outlook
OL.MailItem mi
ptr = Marshal.GetIUnknownForObject(mi.MAPIOBJECT);
I have created a basic C++ DLL, that has been setup to Interop with C# .NET by the following

Code:
//  Inside C# COM

[DllImport("MAPISHIM.dll")]
public static extern void Process_MAPIOBJ(IntPtr unk);

//  Inside C++ DLL
__declspec(dllexport) void Process_MAPIOBJ(IUnknown * pUnk);

// To Query as an IMessage

HRESULT MAPI_UTIL::processMessage(IUnknown * pUnk)

	LPMESSAGE lpMsg;
	hr = pUnk->QueryInterface(IID_IMessage,(void**)&lpMsg);
	pUnk->Release();

I then have no problem retrieving any properties from the message, such as PR_BODY, PR_BODY_HTML, PR_RTF_COMPRESSED.

My problem is trying to reinsert information back into the Message object. The following code writes some characters to PR_BODY. The problem is that this does not synch with the data inside of Outlook. The only way the data is synched is if I close outlook and reopen and the changes appear in the message. Does anyone know of a method to resynch data modified through extended mapi inside of outlook?

Thanks

tom

The following is the code for writing to PR_BODY

Code:
HRESULT MAPI_UTIL::set_MSG_rtf(LPMESSAGE lpMsg, char * rtf_buf, int rtf_buf_size)
{
	HRESULT hr;
	
	IStream * istream;

	//hr = lpMsg->OpenProperty(PR_RTF_COMPRESSED, &IID_IStream, MAPI_MODIFY | MAPI_CREATE, 0, (IUnknown**)&istream);
	//hr = lpMsg->OpenProperty(PR_RTF_COMPRESSED, &IID_IStream, STGM_WRITE, 0, (IUnknown**)&istream);
	hr = lpMsg->OpenProperty(PR_BODY, &IID_IStream, 
						STGM_READWRITE, MAPI_CREATE|MAPI_MODIFY,
						(IUnknown**)&istream);
	/*hr = lpMsg->OpenProperty(PR_BODY, &IID_IStream, 
						STGM_READWRITE , MAPI_MODIFY,
						(IUnknown**)&istream);*/


	if( ! SUCCEEDED(hr) )
	{
		lg << "set_MSG_rtf:: open RTF STGM_WRITE failed\n";
		return hr;
	}
	lg << "Open Property worked\n";
	char buf[] = {'a','b','c','d','e','f','g','h','i'};
	ULONG size = sizeof(buf);
	ULONG written = 0;
	hr = istream->Write(&buf,size,&written);

	if( ! SUCCEEDED(hr) )
	{
		lg << "set_MSG_rtf:: open RTF STGM_WRITE failed\n";
		return hr;
	}
	
	//we need to commit changes to istream object
	//supposidly acts like flush but for com objects, 
	//should force changes in parent storage
	hr = istream->Commit(STGC_OVERWRITE);
//	hr = istream->Commit(STGC_DEFAULT);
	
	if( ! SUCCEEDED(hr) )
	{
		lg << "set_MSG_rtf:: commit() failed\n";
		return hr;
	}
	
	//can't forget to release object
	istream->Release();
	
	
	
	hr = lpMsg->SaveChanges(FORCE_SAVE);
	if( ! SUCCEEDED(hr) )
	{
		lg << "set_MSG_rtf:: SaveChanges() failed\n";
		return hr;
	}

	BOOL isupdated;
	RTFSync(lpMsg,RTF_SYNC_BODY_CHANGED,&isupdated);
	if(isupdated)
	{
		lg << "ret_MSG_rtf:: Needed to sync body \n";
		lpMsg->SaveChanges(0);
	}

	stringstream ss;
	ss << "Write was success: " << written << endl;
	lg << ss.str();

	return S_OK;
}
 
Back
Top