A while back I mentioned our MAPI Stub Library. This is a couple of .cpp files you can drop in to your project instead of linking to mapi32.lib, Alternatively, you can build your own version of mapi32.lib. You can read more about the whys and wherefores on the codeplex site or in the MSDN article on MAPI linking.
We just updated the logic used to find the correct MAPI binary to both make it more correct and to simplify it. According to the dev who did the work, we were able to eliminate two thirds of the code from StubUtils.cpp. The code is now more future proof, so if you were using the original version, you should look at incorporating the update. MFCMAPI will use this new logic in its next build.
From time to time, folks ask me what they need to do in their message store provider to support Outlook 2010’s conversation view. I tell them they need to support restrictions on message store tables as discussed in the MAPI documentation. If Outlook hands them a restriction, they can’t return MAPI_E_TOO_COMPLEX and expect the conversation view to work. I also tell them their table needs to support categorization with multivalued columns and MV_INSTANCE. Because they support categorization, they also need to return STORE_CATEGORIZE_OK in PR_STORE_SUPPORT_MASK. Basically, when you turn on a conversation view, Outlook is going to exercise more of the MAPI spec than it has before. If your provider can’t handle it, then the view won’t work.
This is all true, but as usual, there’s more to the story. The more comes about when you decide your store isn’t going to be able to handle conversations. We usually find that categorization is the feature most people have trouble getting to work. So they decide “Ok – we just won’t support conversations” and they don’t return STORE_CATEGORIZE_OK. Their store works fine in Outlook, until a user tries to configure a conversation view. Then the user gets the error “Cannot display information. There is a problem connecting to the server or an error occurred. Try starting Microsoft Outlook again.” They continue to get this error until they change to a different view.
What’s going on? When we implemented the conversation view, we took a dependency on the categorization feature working in order to get the view working quick enough to be acceptable to the user. We also implemented a fallback path in case categories weren’t implemented, but since all of our built in providers did implement categories, this path did not get well tested. In fact, there’s a logic bug in it that causes the error the user sees. We investigated this a while back and even attempted a fix. However, when we did this, we realized why having categories was so important. Without categories, the performance of the conversation view is, to be blunt, horrible, Categories, it turns out, were what allowed us to implement the conversation threads without incurring a high level of post processing on the table.
We decided we couldn’t fix that code path (or we technically, we could, but no one would want the fix), and we looked at alternatives for delivering a better experience. The obvious choice here is to disable the conversation view UI when the store doesn’t support categories. However, this presents a challenge – we didn’t consider in our original design how to handle multiple stores where some stores (like the PST) support the view but others don’t. So while we agreed this would be a good design change, it was deemed too expensive to consider in a hotfix or service pack.
One customer found that, through heavy customization of the ribbon, they could hide the UI themselves when the user was looking at one of their folders, but leave the UI enabled when someone else’s folder was selected. However, it was still possible to set a conversation view to one of their folders. This could happen because of a prompt we display when the user checks “Show as Conversations”:
If the user picks “All folders” here, the conversation view gets applied to the store that couldn’t support it. Fortunately, there’s a way to suppress this dialog. We have a policy, UpgradeToConversations, which controls conversion to/from the conversation view. 0 converts conversation views to date sorts, 1 converts them the other way, and 2 says leave them all alone. If this policy is set to any value, we don’t display the prompt. For the customer that customized the ribbon, setting the policy to 2 allowed their users to have conversation views in the PST and Exchange stores, but not get them set in their store.
The moral of this story is if you have a custom store provider, you really need to support categories if you want your users to have a good experience.
We did it! MFCMAPI is now on Wikipedia!
The March 2012 Release (build 18.104.22.1682) is live: http://mfcmapi.codeplex.com.
No UI changes this round, so no new screenshot. I did fix some interesting bugs and added a few nice features. Probably the nicest feature is new MAPI call logging. I‘ve always had error call logging in MFCMAPI via the Debug Viewer (Ctrl+D), but I never had a way to output exactly which MAPI calls were being made, whether they failed or not. Now you can get that – just turn on tag DBGMAPIFunctions (0x40000000) in the Debug Viewer and you’ll see every MAPI call that gets made. If you want more perspective on an error, I’d also add DBGGeneric (0x1) and DBGHRes (0x40). You can use 0x40000021 to turn on all of these at the same time.
Oh – and perhaps the biggest change of all: All the binaries are now code signed!
Here's a change list - see the Issue Tracker on Codeplex for more details, or look at the code:
We’ve added a couple new C++ only events to Outlook 2010 which I have been asked to document. These events were added per customer request to help fill some gaps in the transition from ECE to Com Add-In. One of the events is available as of the October 2011 Cumulative Update, and the other just shipped in the February 2012 Cumulative Update.
The two new events are:
If you’re familiar with writing Exchange Client Extensions and Com Add-Ins in C++, this is likely sufficient information to handle these events. If not, you might want to review some samples which demonstrate handling events from the IDispatch::Invoke function. For example, I found this add-in on codeproject which handles Application events. In that code, the CAppEventListener::Invoke function is where you would handle the BeforePrint event.
This week, we shipped the February Cumulative Update for Outlook 2010. One of the fixes in there relates to the MAPI<->MIME conversion API. In particular, with Outlook 2010 if you use MAPIToMIMEStm to convert a message to EML you’ll see the source message get updated. This didn’t happen with Outlook 2007. The reason for the change in behavior has to do with how we handle conversation threading, particularly for messages that don’t already have some of the conversation properties already stamped on them. In order to preserve threading should the MIME message come back in to MAPI (a scenario which occurs with POP3/SMTP profiles and replies), we would stamp the conversation properties on the source message during the export.
In general, this is fine, but it did cause a problem for some vendors who needed their export to not modify the source. So for them, in the February CU we enable a new flag:
#define CCSF_PRESERVE_SOURCE 0x40000 // don't modify the source message
Pass this new flag in to MAPIToMIMEStm and we’ll bypass the new code that saves changes back to the source message.
One caveat: We may still make changes to the message. This flag skips the SaveChanges call that commits the changes. So if your code subsequently calls SaveChanges, you’ll see the changes made during the export get committed. Of course, if your code is calling SaveChanges, you probably won’t be using this flag in the first place.
Remember Jason’s article about the reconnect logic we added to Exchange’s MAPI? The idea was that if your GC went down, Exchange’s MAPI should be able to reconnect to a different GC and proceed smoothly. Mostly smoothly though, since the last call sent to the old GC may fail with MAPI_E_END_OF_SESSION and need to be retried. What was left unsaid from that article was that if you’re using Outlook’s MAPI, which supports reconnect without special configuration, there are some other error codes that can bubble up to the client. Development has given me permissions to document a couple that have shown up in the wild:
#define MAPI_E_RECONNECTED MAKE_MAPI_E( 0x125 ) // 0x80040125
#define MAPI_E_OFFLINE MAKE_MAPI_E( 0x126 ) // 0x80040126
#define MAPI_E_RECONNECTED MAKE_MAPI_E( 0x125 ) // 0x80040125
#define MAPI_E_OFFLINE MAKE_MAPI_E( 0x126 ) // 0x80040126
MAPI_E_RECONNECTED, aka 0x80040125, is returned by the Exchange Address Book and Message Store providers when the RPC connection token is discovered to be out of date. The connection token is basically a number tracking the current connection. If the token on our current transaction is different from the token on the connection, this means we have reconnected, so MAPI_E_RECONNECTED is returned. MAPI_E_RECONNECTED can be treated the same as MAPI_E_END_OF_SESSION and the call should be retried.
MAPI_E_OFFLINE, aka 0x80040126, is returned by the Exchange Address Book and Message Store providers when we discover that we are offline. Typically this means that something has happened in the environment, such as a server going down, or loss of network connectivity. This error is most likely to occur when using a cached mode profile and attempting to bypass the cache to talk to the server. If the cache was never able to establish a connection to the server in the first place, we may be in this offline state where MAPI_E_OFFLINE could surface.
Neither one of these errors will be returned in all scenarios where it would appear they would appear to apply. In most cases, MAPI_E_NETWORK_ERROR or MAPI_E_CALL_FAILED will be returned instead. But now if you do get one of these errors you know what it means. Both of these errors are specific to Outlook’s MAPI only. They will not appear with MAPICDO.
This was an interesting scenario one of our customers came up with. They process a lot PSTs. As part of this processing, they create search folders and wait for them to complete building. They found that for many PSTs, they would never get a notification that the search folder had finished building.
Here’s the basic outline of what they were doing:
Usually this worked, but occasionally their application would end up stuck in step 5 waiting for the search folder completion. What was really strange is that if we opened MFCMAPI to look at the stuck search folder, after some poking around their application would suddenly get the completion notification!
To understand what’s going on here, we need to know a little bit about how the PST handles searches. There are two basic ways a search can be fulfilled. The most common way currently is that the PST provider leverages Windows Search to handle the search for it. That’s the default configuration, and the customer’s code always worked when it was enabled. But Windows Search can be turned off. This is when the customer’s code would have problems. Without WIndows Search to do the work for us, the PST provider falls back to the mechanism it always used before Windows Search existed: on a background thread it manually does the search and populates the search folder. It’s the handling of this background thread where we were having problems.
When you first load the PST provider, it spins up an idle thread which handles background processing such as search folder generation and updates. Since a PST can be loaded in multiple processes, with only one process actually loading the file and the various processes negotiating reads/writes through shared memory, every process which opens a MAPI profile is a candidate to be the one who manages searches. So every search folder has a process which is considered to be the owner of the search. This owner can go away, in which case the search is orphaned, and a new owner has to be selected. Originally, this was the first process who’s idle thread detected there was a search without an owner which needed to be processed. This, however, caused a problem with short lived processes. Suppose you have a processes that needs to get in and out of MAPI fairly quickly, such as to send an e-mail. This process could unwittingly become the owner of a search, meaning it’s on the hook to stay around and process the search, even though there’s little chance it will benefit from it. This caused problems, so we introduced a delay. If the PST provider has been loaded less than 5 seconds, we won’t try to take ownership of a search.
This is where the customer’s application got in trouble. They started up and got through to the SetSearchCriteria so quickly their idle thread decided it shouldn’t handle the search. And since they were doing nothing else while they were waiting, nothing ever kicked the idle thread back to life to realize there was an unfulfilled search. When MFCMAPI ran, clicking around in the UI was enough for MFCMAPI’s idle thread to spot the search and complete it. This is not to blame their application – they did everything right and nothing wrong. They just managed to walk the narrow tightrope needed to see this problem.
So – how can they avoid the hang? One workaround is obvious – Sleep for 5 seconds before creating search folders. But that’s a performance hit and nobody wants that. Fortunately, there’s a bypass for the delay. If your MAPI session was created with MAPI_BG_SESSION, we assume you’re not just some client sending e-mail, so we grab any search your process is eligible to process the first time we see it. Note that the documentation for MAPI_BG_SESSION indicates “A client application such as an indexing engine or opening a Personal Folders File (PST) for background type access are some examples of where to use MAPI_BG_SESSION”. This is precisely the sort of scenario where we intend this flag to be used.
The customer tried this flag in their code and it worked perfectly. Yay!
No one’s taking my subtle hints about Wikipedia. One more try: It sure would be nice if someone added MFCMAPI to the article about MAPI.
The January 2012 Release (build 22.214.171.1241) is live: http://mfcmapi.codeplex.com.
I’m continuing to crunch on the UI overhaul. This release has a ton of fixes for various flicker issues and glitches, especially those which show under the Windows Classic theme. Most of the problems were bad assumptions on my part that the Classic Theme helped expose. I also worked a good bit on making my various dialogs more pretty, practically rewriting the layout engine in the process. Finally, I finished up my work on painting the system buttons. This last bit required a bit of kernel debugging to figure out why Windows liked to repaint on top of my icons when I moved the mouse around. It turns out that initialization of the window’s system menu is what caused this. If you’re interested, look at how I handle WM_CREATE.
I’m continuing to tweak the colors. Here’s another hero screenshot highlighting the new new color scheme, including the new system buttons:
What’s an app got to do to get on Wikipedia? You know I can’t put it there myself – that’s against the rules.
The December 2011 Release (build 126.96.36.1990) is live: http://mfcmapi.codeplex.com.
When I started working on the UI overhaul, I knew it was going to take a few releases to get it right. After all, I’m a one man development team, and while I’ve got a number of folks who do testing for me, I can’t catch everything. Since the last release, I’ve found (or been pointed at) a number of issues with the new UI, mostly relating to the abundance of themes out there. I’ve also found a new (to me) code analysis tool which has uncovered a number of potential issues. So I’ve decided to release an off schedule build to address everything. I’m still not done with the UI, but this release should be more visually stable on more machines.
Since I’ve changed some colors in this release, I took a new screenshot:
Matt has just announced that EWSEditor has been updated and moved over to Codeplex. Read his announcement here, then go download EWSEditor here.
We had a customer recently who was using Outlook 2010’s MAPI in their application to talk to the Exchange server. They wanted to enable Kerberos authentication, but were having trouble enabling it programmatically. They had found the property that gets changed when you enable Kerberos authentication through the UI: PR_PROFILE_AUTH_PACKAGE in the global profile section gets set to RPC_C_AUTHN_GSS_KERBEROS. When they tried setting this value in their profile though, they’d find that OpenAddressBook would return MAPI_W_ERRORS_RETURNED and subsequent calls to ResolveName would return MAPI_E_CALL_FAILED. What was really strange was if they opened the profile using Outlook or MFCMAPI, the profile would somehow be “fixed”, and their application would work.
By comparing the profile before and after “fixing” it, we were able to track the difference down to a single property, which development has given me permission to document, PR_PROFILE_HOME_SERVER_FQDN (0x662A001F). This property is located in the address book section, dca740c8c042101ab4b908002b2fe182 (aka muidEMSAB). Setting this property to the DN of the user’s directory server was sufficient to turn a non-working profile into a working profile using Kerberos authentication. For example, if my DC was named ExampleDC, I might set this property to “ExampleDC.example.com”.
So why would running MFCMAPI or Outlook fix the profile? It all has to do with the flags the customer passed to MAPILogonEx. They were passing MAPI_NT_SERVICE. To the Exchange address book provider, this indicated (among other things) that we should not load our user interface (UI) support object, since we’re running in a context that doesn’t allow UI. Later, when we’re attempting to connect to the server, we check if we have been referred to a DC yet. This is the PR_PROFILE_HOME_SERVER_FQDN property. Finding this property not set, we enter the code that would normally request a referral from the Exchange server. However, this code is dependent on the UI support object, so it does not execute. Ultimately, we decide to just talk directly to the Exchange server and let it handle proxying our calls over to the DC as needed.
This all works fine as long as we’re not using Kerberos authentication. However, as we saw in the Check Names article, you cannot use Kerberos to make address book calls to the Exchange server (Exchange 2010 may fix this, but I believe this customer was using Exchange 2007). That’s why setting PR_PROFILE_HOME_SERVER_FQDN fixes the problem, since we connect directly to the DC.
Still no mention of MFCMAPI on Wikipedia. I had such high hopes. Sigh.
The November 2011 Release (build 188.8.131.529) is live: http://mfcmapi.codeplex.com.
Note that build number. That’s right. I jumped all the way from 6 (where I’ve been stuck forever) to 15. That’s the sort of jump that’s normally only accompanied by a full UI refresh. And that’s exactly what you get! I’ve overhauled just about every aspect of the UI for a more modern, some might say “Metro inspired”, look. I’ll admit, there’s still some work to be done (I didn’t get to scrollbars for instance) but this is a pretty good start. Let’s take a look:
[See the new screenshot here.]
I’ve drastically slimmed down the menus, stuffing most of the little used functionality into Advanced menus that most of you will never need to open. The old, usually empty, File menu is gone and Session now takes prominence. This should help new users immensely. Long time users of MFCMAPI may want to spend a little time figuring out where their favorite features went, but nothing’s been cut.
A note about the tree: In the past, whenever you selected or expanded a folder, MFCMAPI would register for notifications on that folder and a number of it’s child folders. This was represented in the UI by bolding the folder name. This just confused people, so now, the only time I bold a folder name is to represent the currently selected folder. You can tell if MFCMAPI is listening for notifications on a folder by looking for a little red “I’m listening”icon after the folder name. It looks like this:
It’s been a while, but we just shipped a new version of the MAPICDO download. Per tradition, I’ve put together release notes:
We have gotten a number of cases lately involving applications using Outlook 2010's MAPI failing when connecting to Exchange 2010 servers. The primary symptom observed by our customers is that random MAPI calls to Exchange return MAPI_E_CALL_FAILED. At first blush, there is no rhyme or reason as to which calls fail, except that all of the applications which see the problem have multiple threads using MAPI. It turns out the underlying problem is very complicated and we won't be able to fix it in a hotfix (though we do have a long term plan for a solution), so I wanted to get this information out there in case this problem is affecting you.
The root of this problem has to do with how the Exchange MAPI provider (henceforth called just MAPI here) packs remote operations, or rops, into the RPC buffer to send them to Exchange to be processed. In all versions up until Outlook 2003 (and including all versions of the MAPI download), most rops are sent synchronously to the server as soon as the client calls in to MAPI. So if you were to call GetProps and follow along in the debugger, you would see your call go in to emsmdb32, then to rpcrt4, at which point a packet would be sent on the wire. Your thread would then wait for Exchange to respond, then it would parse the response buffer and hand it back to the client. The MAPI_DEFERRED_ERRORS flag can cause multiple rops from the same thread to get packed together in the same buffer, but the key point here is that everything usually happens on the initial calling thread.
Outlook 2007 changed the model for how Outlook’s MAPI handles MAPI operations. Most MAPI operations are now issued asynchronously. MAPI maintains a worker thread which queues up pending MAPI operations from the various client threads and packs them into buffers as needed, resulting in fewer packets being sent between the client and server. So for instance, if one thread issued an operation to read a stream and another issued an operation to set properties at the same time, both operations could be packed into the same buffer and sent to the server. When the results come back, MAPI decodes them and sends them back to any client threads which were waiting on the results. This has the benefit of greatly reducing the amount of data sent across the wire, which is a primary concern for the developers of Outlook’s MAPI. The side effect of this change is that we can now see operations packed together in combinations that were never possible to see with Outlook 2003. This is the first change which leads to the random MAPI_E_CALL_FAILED results.
On the server side, Exchange 2010 made a series of fixes to prevent looping calls which can overwhelm networks and bring down Exchange servers. The key rop here is RopBufferTooSmall, which is the rop the Exchange server can send back to a MAPI client if the server needs to send more data back to the client than is available in the response buffer. This is a signal to the client that it retry the operation, but this time either use a larger buffer, pack fewer operations into the request buffer, or both. Through analysis of numerous hang dumps we had received over the years, the Exchange team identified a number of scenarios where the server would send this response back to the client and the client's response would be to issue the exact same request the server had just rejected. This would result in a loop, with client and server exchanging the exact same packets until one or both was shut down. The key characteristics in these loops were that RopReadStream was the operation for which the result could not fit in the response buffer, that it was the first and usually only operation in the request buffer, and that we were already using the maximum size response buffer. The fix then was to special case when RopReadStream was the first operation in the request buffer. Instead of returning the RopBufferTooSmall rop, we would return the error ecBufferTooSmall (0x47D, or 1149 in decimal). This change, being more picky about how Exchange 2010 will accept packed rops, is the second change leading to random MAPI_E_CALL_FAILED results.
We combine these changes to see how they interact: prior to Outlook 2007, if Outlook’s MAPI issued a request buffer with RopReadStream as the first operation in the buffer, it was most likely also the last operation. A single client thread was waiting synchronously for the response to this rop. If the response buffer was already maximized and the request still could not fit, re-issuing the request could not be expected to work, so Exchange’s error would be the best response, as it avoids the loop. With Outlook 2007 and higher though, this RopReadStream could be packed in the same buffer as rops for other threads. Some of these rops may carry a large payload, which complicates the math Exchange uses to calculate the remaining space in the response buffer. This calculation occurs before Exchange executes the rops (since it would do no good to execute the rops first and discover we have no room for the results) so Exchange has to assume that every rop in the buffer could potentially fail. The upshot is that RopReadStream gets the short end of the stick, and Exchange concludes it does not have enough space for its response. When RopReadStream is not the first operation in the buffer, we send RopBufferTooSmall back to the client so it can break up the operations and try again. But when it’s the first operation in the buffer, the entire packetful of rops fails outright.
And when they fail, since MAPI doesn’t have a targeted error code to match ecBufferTooSmall, everybody gets the default error of MAPI_E_CALL_FAILED.
The Exchange and Outlook development teams both take this issue very seriously and want to correct this. That said, the risk of regression when you start playing with how Outlook packs rops or how Exchange calculates response buffers is incredibly high. The amount of testing we can do for a hotfix does not reduce this risk enough for us to be comfortable approaching this as a hotfix. So the Outlook team has agreed to attempt a fix for this in the next version of Outlook, currently under development. By getting the fix in to Outlook this early in the development cycle, we’ll have plenty of opportunity to test the fix, and also to observe how it affects clients in both dogfood and beta deployments. We will evaluate our options for Outlook 2010 if/when it comes time to consider what goes in to SP2, depending heavily, of course, on how things go in the next version.
Given the nature of this problem, if your application is multithreaded, uses Outlook’s MAPI, and reads streams, there is a high likelihood you will run in to this problem at some point. Here are the options we’ve identified so far, in no particular order:
Hopefully one of the first three options is available to your application.
Given that this problem is one that is going to happen despite your best efforts to avoid it, it helps to be able to identify the issue. The best diagnostic here is to use Exchange’s RPC Client Access (aka RCA) logs, which are on by default. These logs contain an entry for every time Exchange failed a call with ecBufferTooSmall. The key word to look for in these logs is BufferTooSmallException. You should expect to find several entries with BufferTooSmall, without Exception. These are the normal retry results and can be ignored. Here are a couple of examples of the log entry you need to look for:
2011-03-17T08:23:58.188Z,2,8548,/o=org/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=User,, customerapp.exe,14.0.4760.1000,Classic,,,ncacn_ip_tcp,,,1149 (rpc::BufferTooSmall),00:00:00,, RpcDispatch: [BufferTooSmallException] Une exception de type 'Microsoft.Exchange.RpcClientAccess.BufferTooSmallException' a été levée.
2011-09-15T13:59:20.762Z,5,1351,/o=org/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=User,, customerapp.exe,14.0.4760.1000,Classic,,,ncacn_ip_tcp,,,,>ReadStream;>FastTransferDestinationPutBuffer, RpcDispatch: Exception of type 'Microsoft.Exchange.RpcClientAccess.BufferTooSmallException' was thrown.
You'll find these logs on the Client Access Server (CAS) for Exchange 2010 in the following directory: %ExchangeInstallPath%\Logging\RPC Client Access
Note that the second entry contains more information on the other operations which were included in the buffer. While you don’t need this information to identify the problem, it might be helpful in matching the logs to your own error logs. Here’s how to crank that logging higher (note that this must be done on every CAS for which you want greater logging:
Now Exchange will log the rops which were in the buffer. By the way, RCA logs are great for troubleshooting other issues as well. Any time Exchange 2010 isn’t returning the results you expect, these logs are a good place to start. Also, I should remind anyone looking at these logs that we do know at least one other reason you might see BufferTooSmallException. I discussed it in my article on Large Multivalued Properties.
This is a complicated issue that can present itself in multiple ways (due to the random nature of which calls fail). Even though I was the engineer who discovered it and figured out what was happening, I still worked two further issues where this issue was the root cause but did not recognize it. In one case I happened to get debug trace that reminded me to check for this issue, and in the other, in desperation when no other troubleshooting was working, I rolled the dice and had the customer check the RCA logs on the off chance this was their issue. It turned out it not only lined up perfectly, but the customer was able to apply the same troubleshooting to other sites experiencing issues they though were unconnected and confirmed the issue was happening there as well. So while we don’t have a fix for this yet, at least we can determine when the problem is happening and stop troubleshooting.
If development informs me of any plans to fix this earlier than the next version of Outlook, I will report them here. However, don’t ask me if or when SP2 is expected. For that, track the Office Sustained Engineering blog or the Update Center for Microsoft Office.
This issue was fixed on the Exchange 2010 side in SP2 RU3. Read the details of the update here, and get the rollup here.
If you look around for it, you’ll find a lot of posts on a 0x81002746 error that you might get from ConfigureMsgService. But no one seems to know what the error really means or why it happens. I thought I’d fill in some details.
For starters, this error has nothing to do with WSAECONNRESET, which is 0x2746. Some error lookup tools will make this connection, assuming the value was built as a traditional HRESULT and reading the Code from within it. This has lead many people down the wrong path. Actually, the error is MAIL_E_NAMENOTFOUND. Once we know the real name of the error, we can make some sense of when and why it happens.
When you call ConfigureMsgService to configure the Exchange provider, you provide the name of an Exchange server and a mailbox. The Exchange provider uses these to query the GAL to get more information to finish configuring the profile. It talks to the GAL using NSPI. In particular, it binds to the server and issues an NspiGetMatches call, passing a filter built using the mailbox name you gave to ConfigureMsgService. If this call succeeds and returns a record, it parses the results and continues configuring the message service. If it fails, we bubble up some version of the error we got back. But if the call succeeds with no records? Normally, we’d put up a dialog asking the user to check the name. But if we’re running as a service or the client passed flags to disable UI? That’s when we return MAIL_E_NAMENOTFOUND.
Let’s examine the implications of this: We asked the server for any records matching a given name. The server responded with zero matches. This means it didn’t recognize the name. In other words, we looked in the GAL and did not find the mailbox we were looking for! We can now list some common causes:
I recently had a customer encounter this error. I was able to eliminate the first two possibilities, but I knew better than to try and personally chase all the whackadoodle permissions that could be set in their Exchange environment. I’m a debugger, not an administrator! So I enlisted Kevin Carker, from our Exchange Admin team, to work with the customer and figure this out. His ace sleuthing uncovered a reason we had not previously considered: the customer had multiple GALs! They must have created them while playing around in the management console, and since nothing broke for their users, didn’t clean them up. But the way they left things configured, the user they were running their application as defaulted to one of the other GALs, which was empty. So NSPIGetMatches looked in that GAL, did not find the mailbox, and we returned MAIL_E_NAMENOTFOUND. Now, the customer could have configured everything so the presence of this empty GAL didn’t cause a problem, but, seeing as it was empty, they chose to delete it instead, at which point their account defaulted back to the regular GAL and could now configure a profile.
Hopefully, now that we understand what this error means and why it happens, no one else will need to rip their hair out trying to troubleshoot it. If you’re getting MAIL_E_NAMENOUTFOUND from ConfigureMsgService, the mailbox you looked up could not be found in the GAL you looked in. By working through the various reasons why this may be, you should be able to resolve this without making a support call.