• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1671
  • Last Modified:

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


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));
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.
  • 11
  • 7
1 Solution
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.
thehoffAuthor Commented:
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?
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.
Simplify Active Directory Administration

Administration of Active Directory does not have to be hard.  Too often what should be a simple task is made more difficult than it needs to be.The solution?  Hyena from SystemTools Software.  With ease-of-use as well as powerful importing and bulk updating capabilities.

thehoffAuthor Commented:
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).
thehoffAuthor Commented:
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.
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
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?
thehoffAuthor Commented:
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:ExtendedFieldURI PropertyTag="0xffb" PropertyType="Binary"/>

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


But using MFCMAPI shows this:



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!
It's also possible you're getting the id in a different form. Maybe ConvertId will help you:


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


How you'd tell just by looking at them, I don't know, but there may be some more examples out there.
thehoffAuthor Commented:
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.
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.
thehoffAuthor Commented:
Waiting on a response from Microsoft Support.
Please keep this open for a little longer and we shall post the details (if any).
thehoffAuthor Commented:
Microsoft are still investigating this issue, but they believe it is an issue with Exchange when it wraps the store entry id.
thehoffAuthor Commented:
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."
Sounds a bit speculative. You'd think they could just go and ask somebody.
thehoffAuthor Commented:
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.
thehoffAuthor Commented:
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.
thehoffAuthor Commented:
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.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

  • 11
  • 7
Tackle projects and never again get stuck behind a technical roadblock.
Join Now