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:
I have created a basic C++ DLL, that has been setup to Interop with C# .NET by the following
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
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);
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;
}