mapi32, AddressEntry.MAPIOBJECT and C# problem

  • Thread starter Thread starter Keith Ball
  • Start date Start date
K

Keith Ball

I am writing an Outlook Add-In for Outlook 2003. I have a mapi class that
reads properties from an AddressEntry.MAPIOBJECT. I get an exeption when
reading in a property.

System.OverflowException: Arithmetic operation resulted in an overflow.
at System.IntPtr..ctor(Int64 value)
at BrainloopOutlookAddin.MAPI.GetMAPIProperty(Object oMAPIObject, UInt32
uiPropertyTag)

The strange thing is that the code works fine when the AddressEntry.Type is
"EX" but not when "SMTP". I would like to use mapi32 for both to avoid the
security popups.

Can anyone see where the problem may be?

// example calling code...
WriteToFile( "OutputAddressEntry() PR_EMAIL_ADDRESS: " +
MAPI.GetMAPIProperty( oAddressEntry.MAPIOBJECT, MAPI.PR_EMAIL_ADDRESS ) );

// mapi class
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using Extensibility;
using System.Diagnostics;
using System.Reflection;

namespace ReadMAPIEmailAddress
{

class MAPI
{

#region MAPI Interface ID'S
// The Interface ID's are used to retrieve the specific MAPI
Interfaces from the IUnknown Object

private const string IID_IMAPISession =
"00020300-0000-0000-C000-000000000046";
private const string IID_IMAPIProp =
"00020303-0000-0000-C000-000000000046";
private const string IID_IMAPITable =
"00020301-0000-0000-C000-000000000046";
private const string IID_IMAPIMsgStore =
"00020306-0000-0000-C000-000000000046";
private const string IID_IMAPIFolder =
"0002030C-0000-0000-C000-000000000046";
private const string IID_IMAPISpoolerService =
"0002031E-0000-0000-C000-000000000046";
private const string IID_IMAPIStatus =
"0002031E-0000-0000-C000-000000000046";
private const string IID_IMessage =
"00020307-0000-0000-C000-000000000046";
private const string IID_IAddrBook =
"00020309-0000-0000-C000-000000000046";
private const string IID_IProfSect =
"00020304-0000-0000-C000-000000000046";
private const string IID_IMAPIContainer =
"0002030B-0000-0000-C000-000000000046";
private const string IID_IABContainer =
"0002030D-0000-0000-C000-000000000046";
private const string IID_IMsgServiceAdmin =
"0002031D-0000-0000-C000-000000000046";
private const string IID_IProfAdmin =
"0002031C-0000-0000-C000-000000000046";
private const string IID_IMailUser =
"0002030A-0000-0000-C000-000000000046";
private const string IID_IDistList =
"0002030E-0000-0000-C000-000000000046";
private const string IID_IAttachment =
"00020308-0000-0000-C000-000000000046";
private const string IID_IMAPIControl =
"0002031B-0000-0000-C000-000000000046";
private const string IID_IMAPILogonRemote =
"00020346-0000-0000-C000-000000000046";
private const string IID_IMAPIForm =
"00020327-0000-0000-C000-000000000046";

#endregion

#region MAPI Properties

// MAPI Properties
public const uint PR_TRANSPORT_MESSAGE_HEADERS = 0x7D001E;
public const uint PR_BODY = 0x1000001E;
public const uint PR_BODY_HTML = 0x1013001E;
public const uint PR_HTML = 0x10130102;
public const uint PR_DISPLAY_NAME = 0x3001001E;
public const uint PR_SUBJECT = 0x0037001E;
public const uint PR_EMAIL_ADDRESS = 0x3003001E;
//public const uint PR_NEG_EMAIL_ADDRESS = -2146496482;
public const uint PR_SMTP_ADDRESS = 0x39FE001E;
public const uint PR_ADDRTYPE = 0x3002001E;

#endregion

private struct SPropValue
{
public uint ulPropTag;
public uint dwAlignPad;
public long Value;
}

// return codes
private const int S_OK = 0;

#region MAPI Functions

[DllImport("MAPI32.DLL", CharSet = CharSet.Ansi, EntryPoint =
"HrGetOneProp@12")]
private static extern void HrGetOneProp(IntPtr pmp, uint ulPropTag,
out IntPtr ppProp);

[DllImport("MAPI32.DLL", CharSet = CharSet.Ansi, EntryPoint =
"HrSetOneProp@8")]
private static extern void HrSetOneProp(IntPtr pmp, IntPtr pprop);

[DllImport("MAPI32.DLL", CharSet = CharSet.Ansi, EntryPoint =
"MAPIFreeBuffer@4")]
private static extern void MAPIFreeBuffer(IntPtr lpBuffer);

[DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
private static extern int MAPIInitialize(IntPtr lpMapiInit);

[DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
private static extern void MAPIUninitialize();

/// <summary>
/// The MAPISendMail function sends a message.
///
/// This function differs from the MAPISendDocuments function in
that it allows greater
/// flexibility in message generation.
/// </summary>
//[DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
//public static extern uint MAPISendMail(IntPtr lhSession, IntPtr
ulUIParam, MapiMessage lpMessage, uint flFlags, uint ulReserved);

/// <summary>
/// The MAPIResolveName function transforms a message recipient's
name as entered by a user
/// to an unambiguous address list entry.
/// MapiRecipDesc mpd = null;
/// MAPIResolveName(lhSessionNull, this.Handle, new
String(textbox.Text.ToCharArray()), Mapi.MAPI_DIALOG, 0, ref mpd);
/// </summary>
//[DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
//public static extern uint MAPIResolveName(IntPtr lhSession, IntPtr
ulUIParam, string lpszName, uint flFlags, uint ulReserved, ref MapiRecipDesc
lppRecips);

#endregion


/// <summary>
/// Get a property from a passed MAPI object
/// </summary>
/// <param name="oMAPIObject"></param>
/// <param name="uiPropertyTag"></param>
/// <returns></returns>
public static string GetMAPIProperty(object oMAPIObject, uint
uiPropertyTag)
{

if (oMAPIObject == null)
{
//Util.ToLog("No MAPI Object");
return "";
}

string sProperty = "";
IntPtr pPropValue = IntPtr.Zero;

IntPtr IUnknown = IntPtr.Zero;
IntPtr IMAPIProperty = IntPtr.Zero;

try
{

// initialize MAPI
MAPI.MAPIInitialize(IntPtr.Zero);

// get the unknown object.
IUnknown = Marshal.GetIUnknownForObject(oMAPIObject);

//get the property
Guid guidIMAPIProp = new Guid(IID_IMAPIProp);
if (Marshal.QueryInterface(IUnknown, ref guidIMAPIProp, out
IMAPIProperty) != MAPI.S_OK)
{
//Util.ToLog("Failed to get IMAPIProperty");
return "";
}

try
{

// get the field from the MAPI Property
MAPI.HrGetOneProp(IMAPIProperty, uiPropertyTag, out
pPropValue);
// Is the property actually there?
if (pPropValue == IntPtr.Zero) return "";
// Get the value back
MAPI.SPropValue propValue =
(MAPI.SPropValue)Marshal.PtrToStructure(pPropValue,
typeof(MAPI.SPropValue));
// convert to string
sProperty = Marshal.PtrToStringAnsi(new
IntPtr(propValue.Value));

} catch (Exception ex)
{
//Util.ToLog("Query Failed!! [ " +
uiPropertyTag.ToString() + " ] Ex [ " + ex + " ]");
}


} finally
{
// CLEAN UP
if (pPropValue != IntPtr.Zero)
MAPI.MAPIFreeBuffer(pPropValue);

if (IMAPIProperty != IntPtr.Zero)
Marshal.Release(IMAPIProperty);
if (IUnknown != IntPtr.Zero) Marshal.Release(IUnknown);

MAPI.MAPIUninitialize();
}

return sProperty;
}

}
}


-Keith Ball
 
Hello Keith,

As I know you have to get the Iunknown from MAPIObject first,
Then query for the e.g. IMessage Interface from IUnknown.
Then you can query the IMAPIProps.

I have a small sample here, but only for MailItem.
But it should work similar for IID_IABContainer.

Here are my samples:

http://www.x4u.de/Outlook/Snippets/tabid/56/Default.aspx

And

http://www.outlookcode.com/codedetail.aspx?id=1112

See:

// We can pass NULL here as parameter, so we do it.
MAPIInitialize(NULL);

// retrive the IUnknon Interface from our MAPIObject
comming from Outlook.
IUnknown = Marshal.GetIUnknownForObject(mapiObject);

// since HrGetOneProp needs a IMessage Interface, we
must query our IUnknown interface for the IMessage interface.
// create a Guid that we pass to retreive the IMessage
Interface.
Guid guidIMessage = new Guid(IID_IMessage);

// try to retrieve the IMessage interface, if we don't
get it, everything else is sensless.
if ( Marshal.QueryInterface(IUnknown, ref guidIMessage,
out IMessage) != S_OK) return "";

// create a Guid that we pass to retreive the IMAPIProp
Interface.
Guid guidIMAPIProp = new Guid(IID_IMAPIProp);

// try to retrieve the IMAPIProp interface from IMessage
Interface, everything else is sensless.
if ( Marshal.QueryInterface(IMessage, ref guidIMAPIProp,
out IMAPIProp) != S_OK) return "";

// double check, if we wave no pointer, exit...
if (IMAPIProp == NULL) return "";

// try to get the Property ( Property Tags can be found
with Outlook Spy from Dmitry Streblechenko )
// we pass the IMAPIProp Interface, the PropertyTag and
the pointer to the SPropValue to the function.
HrGetOneProp(IMAPIProp, propertyTag, out ptrPropValue);


Hope that helps...


with regards / mit freundlichen Grüßen


Helmut Obertanner
MCSD MCSE MCAD.NET CACP
Microsoft Licensing Specialist 2005
X4U electronix | web: www.x4u.de

.... X4U rocks !

-----Original Message-----
From: Keith Ball [mailto:[email protected]]
Posted At: Thursday, December 08, 2005 12:53 PM
Posted To: microsoft.public.outlook.program_addins
Conversation: mapi32, AddressEntry.MAPIOBJECT and C# problem
Subject: mapi32, AddressEntry.MAPIOBJECT and C# problem


I am writing an Outlook Add-In for Outlook 2003. I have a
mapi class that reads properties from an
AddressEntry.MAPIOBJECT. I get an exeption when reading in a
property.

System.OverflowException: Arithmetic operation resulted in an
overflow.
at System.IntPtr..ctor(Int64 value)
at BrainloopOutlookAddin.MAPI.GetMAPIProperty(Object
oMAPIObject, UInt32
uiPropertyTag)

The strange thing is that the code works fine when the
AddressEntry.Type is "EX" but not when "SMTP". I would like
to use mapi32 for both to avoid the security popups.

Can anyone see where the problem may be?

// example calling code...
WriteToFile( "OutputAddressEntry() PR_EMAIL_ADDRESS: " +
MAPI.GetMAPIProperty( oAddressEntry.MAPIOBJECT,
MAPI.PR_EMAIL_ADDRESS ) );

// mapi class
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using Extensibility;
using System.Diagnostics;
using System.Reflection;

namespace ReadMAPIEmailAddress
{

class MAPI
{

#region MAPI Interface ID'S
// The Interface ID's are used to retrieve the
specific MAPI Interfaces from the IUnknown Object

private const string IID_IMAPISession =
"00020300-0000-0000-C000-000000000046";
private const string IID_IMAPIProp =
"00020303-0000-0000-C000-000000000046";
private const string IID_IMAPITable =
"00020301-0000-0000-C000-000000000046";
private const string IID_IMAPIMsgStore =
"00020306-0000-0000-C000-000000000046";
private const string IID_IMAPIFolder =
"0002030C-0000-0000-C000-000000000046";
private const string IID_IMAPISpoolerService =
"0002031E-0000-0000-C000-000000000046";
private const string IID_IMAPIStatus =
"0002031E-0000-0000-C000-000000000046";
private const string IID_IMessage =
"00020307-0000-0000-C000-000000000046";
private const string IID_IAddrBook =
"00020309-0000-0000-C000-000000000046";
private const string IID_IProfSect =
"00020304-0000-0000-C000-000000000046";
private const string IID_IMAPIContainer =
"0002030B-0000-0000-C000-000000000046";
private const string IID_IABContainer =
"0002030D-0000-0000-C000-000000000046";
private const string IID_IMsgServiceAdmin =
"0002031D-0000-0000-C000-000000000046";
private const string IID_IProfAdmin =
"0002031C-0000-0000-C000-000000000046";
private const string IID_IMailUser =
"0002030A-0000-0000-C000-000000000046";
private const string IID_IDistList =
"0002030E-0000-0000-C000-000000000046";
private const string IID_IAttachment =
"00020308-0000-0000-C000-000000000046";
private const string IID_IMAPIControl =
"0002031B-0000-0000-C000-000000000046";
private const string IID_IMAPILogonRemote =
"00020346-0000-0000-C000-000000000046";
private const string IID_IMAPIForm =
"00020327-0000-0000-C000-000000000046";

#endregion

#region MAPI Properties

// MAPI Properties
public const uint PR_TRANSPORT_MESSAGE_HEADERS = 0x7D001E;
public const uint PR_BODY = 0x1000001E;
public const uint PR_BODY_HTML = 0x1013001E;
public const uint PR_HTML = 0x10130102;
public const uint PR_DISPLAY_NAME = 0x3001001E;
public const uint PR_SUBJECT = 0x0037001E;
public const uint PR_EMAIL_ADDRESS = 0x3003001E;
//public const uint PR_NEG_EMAIL_ADDRESS = -2146496482;
public const uint PR_SMTP_ADDRESS = 0x39FE001E;
public const uint PR_ADDRTYPE = 0x3002001E;

#endregion

private struct SPropValue
{
public uint ulPropTag;
public uint dwAlignPad;
public long Value;
}

// return codes
private const int S_OK = 0;

#region MAPI Functions

[DllImport("MAPI32.DLL", CharSet = CharSet.Ansi,
EntryPoint = "HrGetOneProp@12")]
private static extern void HrGetOneProp(IntPtr pmp,
uint ulPropTag, out IntPtr ppProp);

[DllImport("MAPI32.DLL", CharSet = CharSet.Ansi,
EntryPoint = "HrSetOneProp@8")]
private static extern void HrSetOneProp(IntPtr pmp,
IntPtr pprop);

[DllImport("MAPI32.DLL", CharSet = CharSet.Ansi,
EntryPoint = "MAPIFreeBuffer@4")]
private static extern void MAPIFreeBuffer(IntPtr lpBuffer);

[DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
private static extern int MAPIInitialize(IntPtr lpMapiInit);

[DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
private static extern void MAPIUninitialize();

/// <summary>
/// The MAPISendMail function sends a message.
///
/// This function differs from the MAPISendDocuments
function in that it allows greater
/// flexibility in message generation.
/// </summary>
//[DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
//public static extern uint MAPISendMail(IntPtr
lhSession, IntPtr ulUIParam, MapiMessage lpMessage, uint
flFlags, uint ulReserved);

/// <summary>
/// The MAPIResolveName function transforms a message
recipient's name as entered by a user
/// to an unambiguous address list entry.
/// MapiRecipDesc mpd = null;
/// MAPIResolveName(lhSessionNull, this.Handle, new
String(textbox.Text.ToCharArray()), Mapi.MAPI_DIALOG, 0, ref mpd);
/// </summary>
//[DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
//public static extern uint MAPIResolveName(IntPtr
lhSession, IntPtr ulUIParam, string lpszName, uint flFlags,
uint ulReserved, ref MapiRecipDesc lppRecips);

#endregion


/// <summary>
/// Get a property from a passed MAPI object
/// </summary>
/// <param name="oMAPIObject"></param>
/// <param name="uiPropertyTag"></param>
/// <returns></returns>
public static string GetMAPIProperty(object oMAPIObject, uint
uiPropertyTag)
{

if (oMAPIObject == null)
{
//Util.ToLog("No MAPI Object");
return "";
}

string sProperty = "";
IntPtr pPropValue = IntPtr.Zero;

IntPtr IUnknown = IntPtr.Zero;
IntPtr IMAPIProperty = IntPtr.Zero;

try
{

// initialize MAPI
MAPI.MAPIInitialize(IntPtr.Zero);

// get the unknown object.
IUnknown = Marshal.GetIUnknownForObject(oMAPIObject);

//get the property
Guid guidIMAPIProp = new Guid(IID_IMAPIProp);
if (Marshal.QueryInterface(IUnknown, ref
guidIMAPIProp, out
IMAPIProperty) != MAPI.S_OK)
{
//Util.ToLog("Failed to get IMAPIProperty");
return "";
}

try
{

// get the field from the MAPI Property
MAPI.HrGetOneProp(IMAPIProperty,
uiPropertyTag, out pPropValue);
// Is the property actually there?
if (pPropValue == IntPtr.Zero) return "";
// Get the value back
MAPI.SPropValue propValue =
(MAPI.SPropValue)Marshal.PtrToStructure(pPropValue,
typeof(MAPI.SPropValue));
// convert to string
sProperty = Marshal.PtrToStringAnsi(new
IntPtr(propValue.Value));

} catch (Exception ex)
{
//Util.ToLog("Query Failed!! [ " +
uiPropertyTag.ToString() + " ] Ex [ " + ex + " ]");
}


} finally
{
// CLEAN UP
if (pPropValue != IntPtr.Zero)
MAPI.MAPIFreeBuffer(pPropValue);

if (IMAPIProperty != IntPtr.Zero)
Marshal.Release(IMAPIProperty);
if (IUnknown != IntPtr.Zero)
Marshal.Release(IUnknown);

MAPI.MAPIUninitialize();
}

return sProperty;
}

}
}


-Keith Ball
 
I tried your sample code only....
When i tried to use PR_ENTRYID(i.e. public const uint PR_ENTRYID =
0x0FFF0102;), it gives me the same error...

Thanks
Satya
 
Back
Top