so i managed to solve it! i'll explain. the Value is really union type, and i did get to the correct memory area but have read it wrong.
when we read this area of memory, we have the following:
- uint that represents the "Value" type and the command, i divided it into 2 ushorts (the first one - which is the higher bits is the returned type: PT_MV_TSTRINGS which is equal to MV_FLAGS|PT_UNICODE (multivalued + unicode string)
- uint of dwAlignedPad
- SWStringArray - which is the actual "Value", which has uint of the the array length, and followed by uint of the actual strings array (pointer to an array pointer)
so i created the following struct and read the HrGetOneProp into this:
private struct SMultivalueStructure
{
public ushort PropType; // Type of returned value
public ushort Command; //Command we entered (PR_EMS_PROXY...)
public uint dwAlignPad; // Reserved - usually 4 bytes of 0
public uint stringArrayLength; // SWStringArray length
public uint pStringArrayMemoryAddress; //SWStringArray pointer to string array
}
so after the marshal
SMultivalueStructure propValue = (SMultivalueStructure)Marshal.PtrToStructure(pPropValue, typeof(SMultivalueStructure));
i created a pointer array with the correct length to hold the pointers to the strings:
IntPtr[] pStrings = new IntPtr[propValue.stringArrayLength];
then i have the memory address of the strings array in the struct, so i will copy the pointers into the array i just created:
Marshal.Copy(new IntPtr(propValue.pStringArrayMemoryAddress), pStrings, 0, (int)propValue.stringArrayLength);
now i have array of the memory addresses for each string, now just marshal it to string:
for (int i = 0; i < pStrings.Length; ++i)
{
string smtpTest = Marshal.PtrToStringAnsi(pStrings[i]);
}
by the way, there are 2 possible values that the string array can be: (http://msdn.microsoft.com/en-us/library/bb446176.aspx)
- PT_MV_STRING8 - SLPSTRArray
- PT_MV_UNICODE - SWStringArray
so i added a check (against PropType) - should be MV_FLAG | PT_STRING8 for ANSI string, and MV_FLAG | PT_UNICODE for unicode, then used the correct MarshalPtrToStringAnsi / Uni
few issues i need to check:
- in 64 bit outlook - is this code ok? or do i have to handle that differently
- check that for every outlook version (2003,2007,2010,2010 64 bit)