none
[E2010] [EWSMA] [Java] [Windows]: Decrypting the byte array representation of a RecipientRow

    Question

  • Long story short: I'm trying to handle meeting forward notifications using EWS 1.2 Java and Exchange 2010 SP2. Forward notifications have no distinct class in the API, but they do have their own Message Class to differentiate them from other email messages. I need to get the email address of the person to whom the notification was forwarded. This address is in the body of the email, but I have no idea if that is templated, subject to change, if the user has any control over it, or if it can change in any way to break any code that tries to parse out the address.

    That leaves the PidLidForwardNotificationRecipients property, which is a binary property. This comes through as a byte array. I've checked over the structure of the RecipientRow:

    http://msdn.microsoft.com/en-us/library/ee179606%28v=exchg.80%29.aspx

    The problem is...how in the heck can I properly decode this thing? I've been able to get it partially legible and can even see the email address I'm trying to grab, but it seems that it uses different encoding for different variable-length fields and everything around it is gobbledegook. The first two bytes are supposed to be flags that give at least some information on the rest of the data, but only one bit is set out of all of them on my end, which doesn't seem right at all. These can apparently use a variable-length MBCS character encoding, too, which makes it even more fun.

    I need to be able to reliably pick this thing apart and extract that email address from it, but darned if I can find a good way of doing so. Perhaps there are better tools in C#/VB, but Java...perhaps not, or maybe I'm missing something. Why in the blazes couldn't Microsoft just attach the email(s) of the forwarded recipients outright to this thing as a separate property?

    Thursday, September 26, 2013 12:25 AM

Answers

  • What is stored in that property is a serialized stream of Mapi properties. If you looked at a normal Message in a Mapi editor and looked at a Recipient entry and saw all the properties in the Recipient row, this property is a serialized version of all those properties for each recipient Entry The property formats are roughly documented in http://msdn.microsoft.com/en-us/library/cc463916(v=exchg.80).aspx. I don't know of any open source parsers that can parse this format (maybe some of the MSG parsers could).

    A very rough way to do this would be just to focus on one property eg PR_EMAIL_ADDRESS_W which would be represented as 1F000330 in the stream. (1F00 being the property type for a String Value and 0330 being the propval it Little endian format). And then try to parse that out

                String hexVal = "01000000010000......";
                String Prop = "1F000330";
                Int32 StringPosition = 0;
                while (StringPosition < hexVal.Length)
                {
                   Int32 PropPos = hexVal.IndexOf(Prop, StringPosition);
                   if (PropPos == -1)
                   {
                       StringPosition = hexVal.Length;
                   }
                   else {
                       String PropLengthVal = hexVal.Substring((PropPos + 8), 4);
                       int lengthValue = Convert.ToInt32((PropLengthVal.Substring(2, 2) + PropLengthVal.Substring(0, 2)), 16);
                       String PropertyValue = hexVal.Substring((PropPos + 12), (lengthValue*2));
                       Console.WriteLine(UnicodeEncoding.Unicode.GetString(HexStringToByteArray(PropertyValue)));
                       StringPosition = PropPos+1;
                   }
                   
                }  

    What would be stored in the property would be either the X500 for local recipients or SMTP address for the external user.

    Cheers
    Glen

    Thursday, September 26, 2013 6:14 AM

All replies

  • What is stored in that property is a serialized stream of Mapi properties. If you looked at a normal Message in a Mapi editor and looked at a Recipient entry and saw all the properties in the Recipient row, this property is a serialized version of all those properties for each recipient Entry The property formats are roughly documented in http://msdn.microsoft.com/en-us/library/cc463916(v=exchg.80).aspx. I don't know of any open source parsers that can parse this format (maybe some of the MSG parsers could).

    A very rough way to do this would be just to focus on one property eg PR_EMAIL_ADDRESS_W which would be represented as 1F000330 in the stream. (1F00 being the property type for a String Value and 0330 being the propval it Little endian format). And then try to parse that out

                String hexVal = "01000000010000......";
                String Prop = "1F000330";
                Int32 StringPosition = 0;
                while (StringPosition < hexVal.Length)
                {
                   Int32 PropPos = hexVal.IndexOf(Prop, StringPosition);
                   if (PropPos == -1)
                   {
                       StringPosition = hexVal.Length;
                   }
                   else {
                       String PropLengthVal = hexVal.Substring((PropPos + 8), 4);
                       int lengthValue = Convert.ToInt32((PropLengthVal.Substring(2, 2) + PropLengthVal.Substring(0, 2)), 16);
                       String PropertyValue = hexVal.Substring((PropPos + 12), (lengthValue*2));
                       Console.WriteLine(UnicodeEncoding.Unicode.GetString(HexStringToByteArray(PropertyValue)));
                       StringPosition = PropPos+1;
                   }
                   
                }  

    What would be stored in the property would be either the X500 for local recipients or SMTP address for the external user.

    Cheers
    Glen

    Thursday, September 26, 2013 6:14 AM
  • Glen, you are my hero!

    I've been able to extract a clean email address from the binary string. The differences in endian between the property documentation (and what is shown in MFCMAPI) and what I was getting when I parsed out the byte array into a hexadecimal string made things even more fun. Then again, even when inspecting the property in MFCMAPI, it would show the binary view along with the smart view. Smart view showed one endian encoding for the property tag and the binary view showed the opposite endian encoding for the exact same tag, even when the binary data values didn't change at all. Not sure which is big or little in that case, but it seems more than a little inconsistent. It also inserts an additional byte between the property tag and the value (or two bytes depending on whether you read it out in big or little endian), but not in every case.

    I've worked out the format of the binary data (4 bytes of tag, 2 bytes of data length, and data, be mindful of little endian!) and have extracted the data, using ADDR_TYPE to determine if it's a plain SMTP address or an Exchange id. I still cannot fathom why Microsoft couldn't have broken this up into a few distinct properties. Not everyone working with Exchange is using C#/VB and can use provided libraries to dice up this information. Even more irksome is seeing that they've serialized a single RecipientRow in this format, but still provide no way of accessing PR_MESSAGE_RECIPIENTS directly via EWS.




    Thursday, September 26, 2013 11:03 PM