Solved

Issue retrieving MAPI store id when using Exchange Web Services for Java with Exchange 2010 SP3

Posted on 2013-05-28
18
1,304 Views
Last Modified: 2013-10-23
Hi

I have a Java SE application that uses Exchange Web Services for Java 1.1.5 (also tried 1.2) to retrieve a folder from an Exchange server.  The app asks for an additional property which is the mailbox store entry id, which is a Base64 encoded string representing a MAPI store id (PR_STORE_ENTRYID, 0x0FFB in hex or 4091 in decimal).  This store id is passed to a MAPI client along with the folder entry id to access messages within the folder.  The code works fine with Exchange 2007 SP1, Exchange 2010, Exchange 2010 SP1 and Exchange 2010 SP2 but has stopped working with Exchange 2010 SP3.

I have debugged EWS code and the SOAP response from Exchange appear to contain a partially corrupted or invalid value for the store id.  More specifically, most of the encoded data is correct, only the last part of the data that is supposed to contain a null-terminated string for the mailbox distinguished name is garbled.  The data does not end with a null character and it looks nothing like what I expect.  For example, the mailbox DN part of the data should look something like:

/o=First Organization/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=Dev01 02

but what the app receives is:

BEö;âK¸ÈáS€øT¯çE®õ›G‹      à«·šü

The Java code looks something like:

ExtendedPropertyDefinition PR_STORE_ID_DEFN = new ExtendedPropertyDefinition(0x0FFB, MapiPropertyType.Binary);
FolderView view = new FolderView(10);
view.setPropertySet(new PropertySet(BasePropertySet.IdOnly, FolderSchema.DisplayName, FolderSchema.EffectiveRights, PR_STORE_ID_DEFN));
view.setTraversal(FolderTraversal.Shallow);
FolderId parentId = FolderId.getFolderIdFromWellKnownFolderName(WellKnownFolderName.MsgFolderRoot);
IsEqualTo filter = new SearchFilter.IsEqualTo(FolderSchema.DisplayName, "Some Folder");
FindFoldersResults folders = service.findFolders(parentId, filter, view);
Folder folder = folders.getFolders().get(0);
byte[] storeId = (byte[])folder.getExtendedPropertiesForService().getPropertyAtIndex(0).getValue();

Open in new window


(the code is missing some traversal logic that finds the folder, but it shows the general idea)

Does anyone have any idea what might be wrong?

Thanks in advance.
0
Comment
Question by:thehoff
  • 11
  • 7
18 Comments
 
LVL 31

Expert Comment

by:LeeDerbyshire
ID: 39204179
No idea what's going wrong, I'm afraid, but have you tried looking at the folder properties with EWS Editor? I can't imagine that Exchange would function at all if the STORE_ENTRYID's were really corrupted, but if EWS Editor manages to get the correct values, you can log the requests, and see how they differ from the ones being sent by your application.
0
 

Author Comment

by:thehoff
ID: 39204613
Thanks for the suggestion, I haven't used EWS Editor before.  I installed it and successfully opened up a mailbox and navigated to a folder.  I then selected 'Add Extended Property...' and entered 'PR_STORE_ENTRYID' into the 'Known Name' field and the other fields in the dialog were populated automatically (property tag 0xffb, property type binary).  When I clicked Ok, I received the following error:

Exception details:
Message: The value 'Blah' of type System.String can't be converted to a value of type System.Byte[].
Type: System.ArgumentException
Source: Microsoft.Exchange.WebServices
Stack Trace:
   at Microsoft.Exchange.WebServices.Data.MapiTypeConverterMapEntry.ChangeType(Object value)
   at Microsoft.Exchange.WebServices.Data.ExtendedProperty.set_Value(Object value)
   at Microsoft.Exchange.WebServices.Data.Folder.SetExtendedProperty(ExtendedPropertyDefinition extendedPropertyDefinition, Object value)
   at EWSEditor.Forms.FolderTreeForm.AddExtenedPropertyToolStripMenuItem_Click(Object sender, EventArgs e) in c:\Users\mstehle\Desktop\EWSEditor\Forms\FolderTreeForm.cs:line 707
   at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
   at System.Windows.Forms.ToolStripMenuItem.OnClick(EventArgs e)
   at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
   at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
   at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
   at System.Windows.Forms.ToolStripDropDown.OnMouseUp(MouseEventArgs mea)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ToolStrip.WndProc(Message& m)
   at System.Windows.Forms.ToolStripDropDown.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Exception details:
Message: Invalid cast from 'System.String' to 'System.Byte[]'.
Type: System.InvalidCastException
Source: mscorlib
Stack Trace:
   at System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider)
   at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
   at Microsoft.Exchange.WebServices.Data.MapiTypeConverterMapEntry.ChangeType(Object value)

Open in new window

Unfortunately, I don't have another Exchange environment (e.g. 2010 SP2) to compare against at the moment, so I'm not sure if this indicates a 2010 SP3 problem or not, or a problem with EWS Editor itself.  Any ideas?
0
 
LVL 31

Expert Comment

by:LeeDerbyshire
ID: 39205147
I get the same error (including the word 'Blah') when I try it, too. So I had a look at a folder using Outlook Spy. I get a value like this, which is sort of a combination of what you decribed.

    8¡»å¡» +*V  EMSMDB.DLL        Uú ªfÍ›È ª /ÄZ    W2K8S /o=First Organization/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=Lee Derbyshiredf5

The thing is, I don't know if this has changed format in SP3, because I've never used it before. Are you sure you need it? To open a folder or item, I'd have thought it was sufficient to just use the EntryID alone.
0
 

Author Comment

by:thehoff
ID: 39206127
Thanks for trying that.  The program we have uses EWS to get PR_STORE_ENTRYID and PR_ENTRYID to pass to a MAPI client, which needs both IDs.  I have used MFCMAPI (http://mfcmapi.codeplex.com/) to test both the StoreID and EntryID and it is unable to open an item using just the EntryID - I need to open the message store first before it can find the item using the EntryID, which is consistent with the MAPI client the program uses (it needs to use a MAPI client because we have a requirement to get emails in MSG format rather than EML).
0
 

Author Comment

by:thehoff
ID: 39206495
Just a quick update on using EWS Editor - I get the same error using Exchange 2007 SP1, so I assume it is a problem with the EWS Editor.
0
 
LVL 31

Expert Comment

by:LeeDerbyshire
ID: 39207013
How about if you could get at the store another way? Without knowing what the rest of your code is going to look like, can you do something like this

objOutlook = CreateObject("Outlook.Application")
objNamespace = objOutlook.GetNamespace("MAPI")
objStore = objNamespace.DefaultStore

and then work with objStore

or something like

For Each objStore2 In objNameSpace.Session.Stores
  If Left(objStore2.DisplayName, 7) = "Mailbox" Then
    objStore = objStore2
  End If
Next
0
 
LVL 31

Expert Comment

by:LeeDerbyshire
ID: 39207024
Also, since my Store ID's look the same as yours, perhaps the problem lies elsewhere in the code? Perhaps you are treating it as a string (which worked okay before), but it ought to be a byte array, or something?
0
 

Author Comment

by:thehoff
ID: 39207358
We're using the EWS Java API, and we are retrieving the value into a byte array (check the last line of the code I posted) - I just showed the string value because the mailbox DN is supposed to be a string and it's more obvious to see what the problem is.

So to be more precise, we receive the following Base64-encoded string for the store ID (this is in the SOAP response <ExtendedProperty> tag received from Exchange, before it is parsed by EWS Java API):

<t:ExtendedProperty>
<t:ExtendedFieldURI PropertyTag="0xffb" PropertyType="Binary"/>
<t:Value>
AAAAADihuxAF5RAaobsIACsqVsIAAEVNU01EQi5ETEwAAAAAAAAAABtV+iCqZhHNm8gAqgAvxFoMAAAARVhDSDIwMTAuMjAwOGVuZzAyLm9jbABCRcMdtjviS7jI4VOA+JBUr53nRa71m0eLCeCrt5r8Fw==
</t:Value>
</t:ExtendedProperty>

or as hex (only the value, not the XML tags obviously):

0000000038A1BB1005E5101AA1BB08002B2A56C20000454D534D44422E444C4C00000000000000001B55FA20AA6611CD9BC800AA002FC45A0C00000045584348323031302E32303038656E6730322E6F636C004245C31DB63BE24BB8C8E15380F89054AF9DE745AEF59B478B09E0ABB79AFC17

But using MFCMAPI shows this:

AAAAADihuxAF5RAaobsIACsqVsIAAEVNU01EQi5ETEwAAAAAAAAAABtV+iCqZhHNm8gAqgAvxFoMAAAARVhDSDIwMTAuMjAwOGVuZzAyLm9jbAAvbz1GaXJzdCBPcmdhbml6YXRpb24vb3U9RXhjaGFuZ2UgQWRtaW5pc3RyYXRpdmUgR3JvdXAgKEZZRElCT0hGMjNTUERMVCkvY249UmVjaXBpZW50cy9jbj1EZXYwMSAwMgA=

0000000038A1BB1005E5101AA1BB08002B2A56C20000454D534D44422E444C4C00000000000000001B55FA20AA6611CD9BC800AA002FC45A0C00000045584348323031302E32303038656E6730322E6F636C002F6F3D4669727374204F7267616E697A6174696F6E2F6F753D45786368616E67652041646D696E6973747261746976652047726F7570202846594449424F484632335350444C54292F636E3D526563697069656E74732F636E3D446576303120303200

The mailboxDN is the last part of this data and is supposed to be a null-terminated string (which it is in the MFCMAPI data, but not in the Exchange SOAP message).

I'll see if it's possible to translate your code using the EWS Java API as a possible workaround.  Appreciate your help!
0
 
LVL 31

Expert Comment

by:LeeDerbyshire
ID: 39207416
It's also possible you're getting the id in a different form. Maybe ConvertId will help you:

http://msdn.microsoft.com/en-us/library/exchange/bb799665(v=exchg.140).aspx

They have changed the format of these things a few times:

http://msdn.microsoft.com/en-us/library/exchange/exchangewebservices.idformattype(v=exchg.140).aspx

How you'd tell just by looking at them, I don't know, but there may be some more examples out there.
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:thehoff
ID: 39207850
I did try ConvertId previously without success, but I didn't record the results so I'll repeat the exercise just to be sure.  I doubt it is the problem though for various reasons:

The existing code works with 2007 SP1, 2010, 2010 SP1 and 2010 SP2
The documentation for ExtendedProperty states the value "Contains the value of a single-valued MAPI extended property.".  So it should be in MAPI format already, and not need to be converted.
The value is mostly correct, it's only the bytes for mailboxDN that are invalid - it's a bit unlikely that another format would only differ in this part of the data (and why would the server short name be passed as ASCII characters but the mailboxDN be some other format?).
But I'll give it go, you never know.
0
 
LVL 31

Expert Comment

by:LeeDerbyshire
ID: 39207949
Hm. I'm getting values very similar to yours. I've no explanation, I'm afraid. I'd suggest asking in the Technet Exchange development forum. There's a chance someone from MS will have something to contribute.
0
 

Author Comment

by:thehoff
ID: 39217749
Waiting on a response from Microsoft Support.
Please keep this open for a little longer and we shall post the details (if any).
0
 

Author Comment

by:thehoff
ID: 39457277
Microsoft are still investigating this issue, but they believe it is an issue with Exchange when it wraps the store entry id.
0
 

Author Comment

by:thehoff
ID: 39463224
Microsoft have reported the following:

"We found that in Exchange 2010 SP3, Exchange is no longer passing the “distinguishedName”  (aka. DN) when opening mailboxes. Instead, it uses mailbox GUID now. From the dump analysis, we can clearly see that the DN part is replaced with the mailbox GUID. We believe this is reason why we are getting the difference result."
0
 
LVL 31

Expert Comment

by:LeeDerbyshire
ID: 39463268
Sounds a bit speculative. You'd think they could just go and ask somebody.
0
 

Accepted Solution

by:
thehoff earned 0 total points
ID: 39504634
We still have not had a definitive statement from Microsoft as to whether this is an intentional change or a bug introduced in Exchange 2010 SP3.

We have worked around this problem by using LDAP to get the mailbox DN and then 'repair' the PR_STORE_ENTRYID.
0
 

Author Closing Comment

by:thehoff
ID: 39514268
Specifically, within the PR_STORE_ENTRYID structure, the mailbox DN follows the name of the Exchange server, which is null-terminated and starts at byte 61.  So we read the PR_STORE_ENTRYID from byte 61 until we reach the null terminator so we know where to put the mailbox DN.  We then take the mailbox DN (retrieved using LDAP) and replace the appropriate bytes in the PR_STORE_ENTRYID structure.  The resulting PR_STORE_ENTRYID can then be used successfully with MAPI to open the mailbox.
0
 

Author Comment

by:thehoff
ID: 39595927
The final word from Microsoft is:

Specifically, by logging in with the mailbox DN, you're forcing the backend to do a lookup in Active Directory to find the mailbox GUID, which is the only thing the backend is really interested in. E14 store made these AD lookups, E15 store does not (and WILL NOT). In order to log in to an E15 store, one can only do it by providing the mailbox GUID. The E14 code needs the ability to log in to E15 stores.
 
Given that's how the connection was made, it's all the internals have in order to make the store entry ID. If the customer code simply MUST have the DN instead, they can look up the GUID in AD (msExchMailboxGuid) and then read the legacyExchangeDN value from the object found.

Therefore, the current “issue” you are facing is actually a designed behavior. The mainly reason of the change is that In E15 Store we added some restriction on how client connects and logons, so we changed the logon from LegacyDN to GUID in order to make sure E14 can connect to E15 store. It is not possible to change it back.


In doing so, they have effectively changed the definition of PR_STORE_ENTRYID and the only solution appears to be to 'fix' it by substituting the mailbox GUID with the mailbox DN as we have done.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Resolve DNS query failed errors for Exchange
Following basic email etiquette rules will help you write a professional email and achieve a good, lasting impression with your contacts.
In this video we show how to create a mailbox database in Exchange 2013. We show this process by using the Exchange Admin Center. Log into Exchange Admin Center.: First we need to log into the Exchange Admin Center. Navigate to the Servers >> Data…
This video discusses moving either the default database or any database to a new volume.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now