Welcome to MSDN Blogs Sign in | Join | Help

So - You Want Forward Should Include the Body?

One of our customers reported that if they used IConverterSession::MIMEToMAPI to generate an MSG file, then opened the MSG file and hit Forward, the body would be gone. Further investigation revealed more funkiness. Reply worked, but if you tried Forward, closed the forwarded message, then tried Reply again, the body would be missing there as well. I could also repro the problem with some messages I saved to MSG from MFCMAPI.

If you've read my other article on MSG files you know this behavior doesn't surprise me. I did file a bug on this, but it got rejected since it turns out there's an easy workaround for the case my customer was hitting.

The problem basically comes down to the best body logic as it applies to an MSG file. All of the MSG files we were dealing with here had PR_BODY_HTML set, not PR_RTF_COMPRESSED. This is fine when we initially render the message, as well as when we re-render for the reply. But when we render for the forward, we go through a different code path that hinges on getting PR_STORE_SUPPORT_MASK from the store in which the message lives. But MSG files don't live in a message store. So we don't get the prop, and the code path fails to render the body. Along the way, it also clears some bits that were allowing the reply case to work, so it now fails.

MSG files saved from Outlook didn't exhibit the problem - they had PR_RTF_COMPRESSED set in them instead of PR_BODY_HTML. That sends us through yet another code path gets much more testing and doesn't have these problems. And this is the key to the workaround: When using MIMEToMAPI to generate MSG files, always include the CCSF_USE_RTF flag. This will write the body into the PR_RTF_COMPRESSED property (even if it's HTML), avoiding the problem.

Team Blog...Sort Of

There's a bunch of us here that work in developer support for the Messaging APIs that actively blog. We've been kicking around the idea of putting together a team blog, but no one wanted to give up our own blogs. So we've come up with what I think is a good compromise. Most of us use blogs.msdn.com, which has a tags url allowing you to search for a tag across all blogs. To take advantage of this, we've tagged all of our posts with the tag DevMsgTeam. Now all of our post will show up together here:

http://blogs.msdn.com/tags/DevMsgTeam/default.aspx

With the corresponding RSS feed:

http://blogs.msdn.com/search/Searchrss.aspx?tag=DevMsgTeam

So there - now we've got a "team" blog. Enjoy! :)

Posted by Stephen Griffin | 0 Comments
Filed under: ,

Getting a Referral From Exchange 2007

One of my customers reported that using the MAPI download, they were unable to get a referral from Exchange 2007, even after following the instructions in Jason Johnston's article. The same code worked if they were targeting an Exchange 2003 machine, and Outlook's MAPI had no problems getting a referral from Exchange 2007.

A little bit about how we connect to the DC Exchange's MAPI (this description does NOT apply to Outlook's MAPI, which has different logic, and leaves out a few details not relevant to the discussion, such as how we react when offline):

  1. We read in various settings from the pbGlobalProfileSectionGuid profile section, including PR_PROFILE_HOME_SERVER, PR_PROFILE_CONFIG_FLAGS, PR_PROFILE_CONNECT_FLAGS, and PR_PROFILE_UI_STATE.
  2. Now we figure out where to send our address book calls. First, we look for the "DS Server" key - if we find it, that's the server we bind to for address book lookups - if we fail to bind here, then we fail overall (hence the cautions against ever setting this key)
  3. Next, we read in various settings from the MUIDEMSAB profile section (see Jason's article), including PR_PROFILE_HOME_SERVER, PR_PROFILE_AUTH_PACKAGE, PR_PROFILE_ABP_ALLOW_RECONNECT and PR_PROFILE_SERVER_VERSION
  4. If PR_PROFILE_HOME_SERVER was set on the MUIDEMSAB section, we attempt to bind to the server specified. If we succeed, we're done. If we fail, we continue to the next step.
  5. We ask the Exchange server for a referral. If that succeeds, and we can bind to the referred server, we write the referred server name to PR_PROFILE_HOME_SERVER in the MUIDEMSAB section, and we're done.
  6. If the referral request fails, we try to bind directly to the Exchange server specified in PR_HOME_SERVER on the pbGlobalProfileSectionGuid section. The Exchange server will proxy any of our address book requests on to a GC.
  7. If we binding directly to the Exchange server fails, we try to ask for a referral one more time. If that fails, we fail overall.

We're focused on the referral step. The referral request is a Remote Procedure Call (RPC), so we have to set up for the RPC, select one of the available RPC bindings, set our authentication mechanism, and finally make the call. Given default settings, this means we'll be using the default authentication mechanism for RPC, RPC_C_AUTHN_WINNT. This is where we run in to trouble.

During the development of Exchange 2007, a few of the RPC interfaces were moved around. This created the need to consolidate how authentication was handled among the various interfaces. RPC_C_AUTHN_WINNT was cut as an authentication mechanism for the RPC interface which handles referrals, leaving RPC_C_AUTHN_GSS_NEGOTIATE as the preferred authentication mechanism. For the most part, this change had little effect. Outlook did not use RPC_C_AUTHN_WINNT as an authentication mechanism for the referral RPC, and since a failure to get a referral defaults to binding to the Exchange server, most clients didn't see a noticeable impact.

Given all the settings we read in, including the tantalizingly named PR_PROFILE_AUTH_PACKAGE, I wondered if there was any way we could work around this and get Exchange's MAPI to ask for a referral. Investigation of our source confirmed that PR_PROFILE_AUTH_PACKAGE did take an RPC authentication mechanism constant as it's value, so we could set it to RPC_C_AUTHN_GSS_NEGOTIATE (this article discusses this as well).Testing showed that didn't work though. The address book code was convinced it didn't need special authentication, so it wouldn't set the authentication mechanism I had specified.

More digging led to PR_PROFILE_CONNECT_FLAGS. If the CONNECT_NO_RPC_ENCRYPTION flag was set in this property, we'd assume we didn't need special authentication. So I tried removing this flag. Of course, this didn't work either. In fact, although I could remove the CONNECT_NO_RPC_ENCRYPTION flag, every time I tried to connect, it got set back again!

Even more digging. Basically, the if EDK_PROFILEUISTATE_ENCRYPTNETWORK flag wasn't set in PR_PROFILE_UI_STATE, we'd add CONNECT_NO_RPC_ENCRYPTION back to PR_PROFILE_CONNECT_FLAGS. Guess what? Setting the EDK_PROFILEUISTATE_ENCRYPTNETWORK flag didn't work either! But I was getting much closer: the error changed.

Previously, the RPC call had been failing with RPC_S_SERVER_UNAVAILABLE. This was because the authentication mechanism was valid, but the RPC interface we were trying to call to hadn't registered for that authentication mechanism. After I made all my settings, when we called RpcBindingSetAuthInfo we got RPC_S_UNKNOWN_AUTHN_SERVICE back. I had been testing everything locally on my Exchange 2007 server, so all RPC calls to the server used local RPC. Since RPC_C_AUTHN_GSS_NEGOTIATE isn't a valid authentication mechanism for local RPC, the RPC layer wouldn't let us use it. This was excellent news. It meant I had succeeded in forcing Exchange's MAPI to attempt a different authentication method!

I knew the customer always ran their MAPI code remotely anyway, so I tested my settings from a MAPI client on a different machine. Whereas without my settings we were always binding directly to the Exchange server for address book lookups, with the new settings, we asked for and got a referral, then bound to the GC!

Here's a summary of the settings you'll want to make on your MAPI profiles if you want to get GC referral and reconnect working against Exchange 2007. These settings will also work when connecting to Exchange 2003, though only the properties from Jason's article are strictly necessary:

In the MUIDEMSAB profile section (dca740c8c042101ab4b908002b2fe182):

  • Set PR_PROFILE_ABP_ALLOW_RECONNECT (0x66390003) to 1 per Jason's article

In the global profile section (13DBB0C8AA05101A9BB000AA002FC45A):

  • Set PR_PROFILE_UI_STATE (0x66060003) to EDK_PROFILEUISTATE_ENCRYPTNETWORK (0x4000)
  • Remove the CONNECT_NO_RPC_ENCRYPTION (0x20) flag from PR_PROFILE_CONNECT_FLAGS (0x66040003)
  • Set PR_PROFILE_AUTH_PACKAGE (0x66190003) to RPC_C_AUTHN_GSS_NEGOTIATE (9)
  • Set PR_PROFILE_SERVER_VERSION (0x661B0003) to 3000 or higher per Jason's article

I tested all of these settings using MFCMAPI, following the outline of the steps I gave here.

BTW - Global Catalog servers still lie on shutdown, so you'll also want to enable the EMSAB_UserAuth_Credentials key if that's a concern. That code was incorporated into the MAPI Download a long time ago.

MAPI Download And the EnumProtocols Bug

The latest MAPI download has an interesting fix in it. Prior to this fix, if you used Exchange's MAPI to connect to Exchange 2007 running on Windows Server 2008 you might crash when you release your message store. If Exchange was running on Windows Server 2003, the same code ran fine. At first, I didn't really believe the version of the OS on the server could trigger a crash on the client, but he had dumps and repro steps, so we debugged it to see what was going on.

Nothing was wrong with his code - we were able to build a simple repro that did nothing more than logon, open the message store, open a folder then release everything. We found some tweaks they could make in their code to avoid the crash, but nothing they were doing was wrong - we even found that MFCMAPI could be walked through to the point of crashing.

The dump of the crash showed we were cleaning up a thread that handled notifications. When we ran the code against an Exchange 2007 server running on Windows 2003, this thread didn't get cleaned up. In fact, it never got created! A bit of debugging back showed the point where we diverged. In both, we tried to register for push notifications with Exchange (these are MAPI's typical UDP based notifications). The Windows Server 2003 based machine succeeded in registering the push notification, but the Windows Server 2008 based machine returned MAPI_E_NO_SUPPORT. This sent us down a little used code path in Exchange's implementation of MAPI. It spun up a timer thread and began polling for notifications. When it tried to tear down this thread, released an object that had been created on another thread. This object had initialized COM, so it tried to uninitialize it when it's destroyed. Since the COM was never initialized on the timer thread, we crashed.

The fix, of course, is to ensure that the object that uses COM is created and destroyed on the same thread. That's the fix we put into last months MAPI download - so if you've been getting unusual crashes while shutting down MAPI clients connected to Exchange 2007 servers on Windows 2008, you'll want to grab this update. A KB article documenting the fix is in the works - I'll link it when it's ready. KB 951992 documents the fix.

Now - you may be wondering - what was happening on the server side? This thread in the newsgroups explains it. EnumProtocols is broken in both Windows 2008 and Vista. It's been replaced by WSAEnumProtocols, which is easy enough to drop in, but of course, you'll need to recompile. We've got a fix for Exchange 2007 in the works that replaces it's call of EnumProtocols with a call to WSAEnumProtocols. If you need it now, you can open a support case and ask for an interim update (ask for KB 951251). Else, it's scheduled to be in Update Rollup 4 for Exchange Server 2007 Service Pack 1 (not the next rollup, but the one after that).

Managing The Outlook Account Management Dialogs

We've decided to document another function in the Account Management API, DisplayAccountList. This function allows you to display the Account Settings dialog:

Account Settings

and Add New E-Mail Account property sheet:

Add New E-mail Account

DisplayAccountList hangs off of IOlkAccountManager interface, occupying the second slot in the v-table, like so:

interface IOlkAccountManager : IOlkErrorUnknown
{
public:
	//Init Initializes the account manager for use. 
	virtual STDMETHODIMP Init(IOlkAccountHelper* pAcctHelper, DWORD dwFlags);
	
	//DisplayAccountList Displays the account list wizard
	virtual STDMETHODIMP DisplayAccountList(
		HWND hwnd,
		DWORD dwFlags,
		LPCWSTR lpwszReserved, // Not used
		DWORD dwReserved, // Not used
		const CLSID * pclsidReserved1, // Not used
		const CLSID * pclsidReserved2); // Not used

I'm working on a little sample to demonstrate the Account Manager API that I hope to post soon. It'll have an updated header. In the meantime, here's my attempt at MSDN style documentation for the function:

IOlkAccountManager::DisplayAccountList

Initializes the account manager for use.

Quick Info

See IOlkAccountManager.

HRESULT IOlkAccountManager::DisplayAccountList ( 
	HWND hwnd,
	DWORD dwFlags,
	LPCWSTR lpwszReserved,
	DWORD dwReserved,
	const CLSID * pclsidReserved1,
	const CLSID * pclsidReserved2
);

Parameters

hwnd

[in] Handle to the window to which the displayed dialog box is modal. This parameter can be zero.

dwFlags

[in] Flags to modify behavior.
ACCTUI_NO_WARNING
Do not display the warning that changes will not take effect until Outlook is restarted. Only applies if running in process with Outlook.exe.
ACCTUI_SHOW_DATA_TAB
Show the Account Settings dialog with the Data tab selected. Only valid if ACCTUI_SHOW_ACCTWIZARD is not set.
ACCTUI_SHOW_ACCTWIZARD
Display the Add New E-Mail Account wizard.

lpwszReserved,

[in] Not used. Should be NULL.

dwReserved

[in] Not used. Must be NULL.

pclsidReserved1

[in] Not used. Must be NULL.

pclsidReserved2

[in] Not used. Must be NULL.

Return Values

S_OK

The call was successful.

E_OLK_NOT_INITIALIZED

The account manager has not been initialized for use.

MAPI_E_INVALID_PARAMETER

dwReserved, pclsidReserved1 or pclsidReserved2 were non-NULL.

E_ACCT_UI_BUSY

The account dialog class could not be created.

MAPI_E_USER_CANCEL

The Account Settings dialog box returned an error.

MAPI_E_CALL_FAILED

The Add New E-Mail property sheet returned an error.

Remarks

The client calls IOlkAccountManager::DisplayAccountList to display either the Account Settings dialog or the Add New E-mail property sheet. The parameters dwReserved, pclsidReserved1 and pclsidReserved2 are not used at this time and MUST be NULL. The parameter lpwszReserved is not used and SHOULD be NULL.

Constants

#define E_ACCT_UI_BUSY 0x800C8102
#define ACCTUI_NO_WARNING      0x0100
#define ACCTUI_SHOW_DATA_TAB   0x0200
#define ACCTUI_SHOW_ACCTWIZARD 0x0400

BTW - Hey look! Pictures! Woo hoo!

7/3/08 - Update: Added ACCTUI_SHOW_DATA_TAB flag.

Protocol Docs RTM

That's right - version 1.0 of the Exchange Server Protocol Documentation has been published in the MSDN:

http://msdn.microsoft.com/en-us/library/cc307725(EXCHG.80).aspx

Here's the press release:

http://www.microsoft.com/presspass/press/2008/jun08/06-30InteropUpdatePR.mspx?rss_fdn=Press%20Releases

And the page with links to all the licenses if you want to make use of the documentation:

http://www.microsoft.com/about/legal/intellectualproperty/protocols/default.mspx

As noted before, support for this documentation is conducted through the forums. Enjoy

MAPI And The Current Directory

In a comment on my post about the MAPI download working with Vista, JP pointed out that something in the updated DLLs is changing the current working directory. I got a chance to look at this today and here is what I found: this is the MAPI Stub's doing. In order to support some wonky old MAPI implementations, the stub library will change the current working directory to the directory of the MAPI implementation it's loading. As far as I can tell, the stub has always done this. It's only being noticed with Exchange's MAPI now because now Exchange's MAPI can be loaded through the stub library.

There's two ways to work around this if it's causing problems in your apps. One is to realize the directory might be changed on you and change it back:

  1. Call GetCurrentDirectory to get the current working directory
  2. Call MAPIInitialize to load MAPI (this is when the Stub changes the directory)
  3. Call SetCurrentDirectory to change the working directory back

The other way to work around the issue is to load Exchange's MAPI directly. You can pull the path from the same key the stub library uses (HKEY_LOCAL_MACHINE\SOFTWARE\Clients\Mail\ExchangeMAPI::DLLPathEx) and load the DLL yourself. If you're already dynamically loading MAPI this wouldn't be a major change. If you're statically linking mapi32.lib, then you'll need to use the first workaround.

The Synchronization Shuffle

I've given this solution to a couple customers so far and it appears to be working for them, so I thought I'd share it with the world.

The Problem:
You've written an application which uses IExchangeExportChanges::Synchronize to synchronize data between your back end database and Exchange. This application is typically deployed directly on an Exchange server, or a machine where the MAPI download has been installed. Occasionally, folder will have items in them which cannot be read through MAPI - typically these are messages which arrived via SMTP and which fail content conversion. From Outlook, you can usually move these messages around, but you can't open them. When the Synchronize method processes a folder containing one of these messages, it returns MAPI_E_CORRUPT_DATA and the whole folder sync is aborted.

Before we can discuss workarounds, we need to understand the problem: The client sets up to do a sync between the client and the server, possibly using IExchangeExportChanges::Config. Then the synchronization is started. During the synchronization, the client will ask the server to fill buffers with data. The server will fill these buffers with data representing the messages on the server. If the server has trouble dealing with one of the messages, for any reason, an error state is entered. If this error state is not resolved, then the entire synchronization operation fails. Exchange's MAPI doesn't know how to resolve the error state, so we fail.

Given that Exchange's implementation of IExchangeExportChanges has worked this way for over a decade, and that Exchange's MAPI implementation enters Extended support next year, there's little chance we'd be able to implement logic for resolving the error.

The Workaround:
If you dig around in edkmdh.h, you'll find an interesting interface: IExchangeExportChanges3, which introduces ConfigForSelectiveSync. This function is identical in use to Config except it adds a new parameter, lpMsgList. What this parameter allows us to do is to tell the synchronizer which messages we want it to sync. Now - we'll still have the problem that if the set of messages we've asked to synchronize includes one of these bad messages, we'll get MAPI_E_CORRUPT_DATA from Synchronize. But we can apply a little binary search style logic to get around the problem. Here's the logic:

  1. Try to sync using IExchangeExportChanges::Config - most folders will sync without problem, not requiring further processing
  2. If you get MAPI_E_CORRUPT_DATA, get the contents table and use ConfigForSelectiveSync in batches of 10-20 messages at a time. Most batches should not fail.
  3. If a batch fails, use ConfigForSelectiveSync to sync one message at a time. If it fails, you've identified a problem message, which you could report, move to another folder, delete, etc.

Of course, we could skip straight from step 1 to step 3, but on very large folders synchronizing a single message at a time could be rather slow. In fact, it might make sense to use even larger batches, say 1/10th the size of the folder. Then, if a batch fails, split it up into tenths and iterate until a single message at a time is being synchronized.

The Other Workaround:
If you're doing the synchronization manually using the Exchange Server Protocol Documentation (and that's a big IF, as it ain't easy), then you can implement code to resolve the error condition. The place to start in that document is section 2.2.4.3.4 errorInfo.

June 2008 Second Release of MFCMAPI

The June 2008 Second Release (build 6.0.0.1007) is live: http://www.codeplex.com/MFCMAPI

Yeah - that's right - second release. I had promised myself I wouldn't put out multiple updates in a month as I figured that could get confusing, but there was a regression in the June 2008 release that I had to fix ASAP- output to XML no longer output property values! I lay complete blame on my tester - send your flame mails directly to him.

Here's the change list - see the Issue Tracker on Codeplex for more details, or look at the code:

  • Export to XML works again.

Enjoy.

MFCMAPI Does Contacts

Randy Byrne and I just published an article in the MSDN showing how to use the Exchange Server Protocols documentation to create a contact. This is the first opportunity I've had to publicly show off the add-in architecture I built in to MFCMAPI last year. Over the next few months, I hope to produce a few more add-ins as we work our way through the protocol documentation. Right now I'm writing a parser for the recurrence blob and it's not as difficult as I thought it'd be. As Randy said in a mail announcing this article: "Long live MFCMAPI!"

Steve

How To Break The MAPI Stub Library

Well, that didn't take long. We just released of the latest MAPI download this weekend and yesterday we got a case from a customer who's application no longer functioned when they upgraded. The issue was quickly resolved, and I was asked to communicate some of the details in case anyone else runs in to it.

The important detail here is that in order to get Exchange's MAPI to work on Vista and Windows Server 2008, we had to make it work with the MAPI Stub Library. So we installed our binaries under Program Files and set the following registry keys*:

    Key Value
    HKEY_LOCAL_MACHINE\SOFTWARE\Clients\Mail\ExchangeMAPI::DLLPathEx <path to exmapi32.dll>
    HKEY_LOCAL_MACHINE\SOFTWARE\Clients\Mail::Default ExchangeMAPI

The first key tells the stub library where to find an Extended MAPI implementation called ExchangeMAPI, and the second key tells the stub library that when an application loads it, the default MAPI implementation to which all calls should be directed is ExchangeMAPI. In other words, when you load the stub library, it will in turn load exmapi32.dll.

This is the same as what Outlook does when it's installed - it registers itself and sets the Default key to "Microsoft Outlook".

Now, this customer had a product which had worked for years with either Outlook's or Exchange's implementation of MAPI. Apparently, they had had problems in the past with systems where Outlook was installed, but the default mail client had been set to something else, such as Hotmail. So, to work around this problem, following the advice given in Explicitly Mapping MAPI Calls to MAPI DLLs they wrote a key under HKLM\Software\Microsoft\Windows Messaging Subsystem\MSMapiApps mapping their application to the "Microsoft Outlook" implementation of MAPI. This worked on machines where Outlook was installed, since there would be a Microsoft Outlook key from which to read DLLPathEx. And on a machine where Exchange's MAPI was installed, since Exchange overwrote the stub library nothing written in any of those keys mattered.

Now, of course, it matters. When they set their application to use "Microsoft Outlook", but Outlook isn't installed, the stub doesn't know where to turn. It can't find the default mail client. It can't just start loading random MAPI binaries, so it turns to it's fallback mechanism, which is to look for MAPI32x.dll. Since that's not there either, it gives up and fails the call to MAPIInitialize.

There's not a perfect workaround here - there's no way to tell the stub that there are two MAPI implementations your application can work with and just use whichever one is available. The simplest solution here is probably to not use the MSMapiApps key and either accept whatever MAPI implementation is the default or load MAPI binaries manually and bypass the stub. The latter is what MFCMAPI does. You could also do some runtime detection of whether "Microsoft Outlook" or "ExchangeMAPI" are listed under the Mail key and set the MSMapiApps key appropriately before loading MAPI. Or, depending on where your application is meant to be installed, pick an implementation of MAPI and insist that it be the one installed with your app. No matter what you choose, this issue illustrates why I stressed to the commenter of my previous post on this update: "The move from system32 to program files is a fairly large and potentially destabilizing move though. You should definitely test your applications with this update."

*64 bit complicates this a bit by redirecting the registry keys. So for those of you playing along at home on a 64 bit box, look under HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Clients\Mail

June 2008 Release of MFCMAPI

The June 2008 Release (build 6.0.0.1006) is live: http://www.codeplex.com/MFCMAPI

I've been digging through the protocol docs. This update represents my first pass harvesting the easy stuff, like property names and flag values. I definitely plan to get to the more complex stuff, like recurrence blobs. Some of the work done here was putting in plumbing to make that possible, like consolidating all of the property parsing code into one code path. I've also introduced Smart View, which replaces the Flag column, allowing MFCMAPI to parse more kinds of data automatically. Expect to see this feature expanded greatly as I work my way through the protocol documentation.

Here's the change list - see the Issue Tracker on Codeplex for more details, or look at the code:

  • Smart View: I removed the Flags column and replaced it with the Smart View column. This column applies intelligence to the data found in the property. For PT_LONG properties, this means flag parsing. For PT_BINARY properties, this means interpreting the data as a structure!
  • Every property name, guid, error code, flag listed in the protocol docs has been added to MFCMAPI. Lemme know if I missed anything.
  • Flag parsing for named props: I couldn't do this before, but I've added it as part of the Smart View feature.
  • Unicode PST paths
  • Fixed ultra wide dialogs: The minimum width has been capped at 1000 pixels.
  • Multiple names for named props: With the protocol docs, many named props now have two or more names documented. You'll see them all.

Enjoy.

This Just In: MAPI and Windows Server 2008 Now Get Along

The MAPI/CDO download package now works on Windows Server 2008 and Vista. The main blocker to getting this to work was the fact that in Windows Server 2008 and Vista, mapi32.dll was marked as a system file. Any attempt to replace it would be blocked or undone. Exchange's MAPI has always replaced mapi32.dll with its own version, so it couldn't work on those operating systems.

The fix is modify Exchange's MAPI to take advantage of the MAPI Stub Library mechanism. We moved Exchange's MAPI binaries out of system32/syswow64 and placed them under C:\Program Files\ExchangeMAPI ("Program Files (x86)" on a 64 bit machine). We also renamed Exchange's mapi32.dll binary. It's now called ExMAPI32.dll.

Some notes:

  • If you've installed an earlier version of this download on a machine and wish to upgrade, you must uninstall the earlier version first. It will not upgrade in place, and may even claim to have successfully installed.
  • Mapi32.dll in the system directory should be version 1.0.xxxx. If it's 6.5.xxxx, then the stub is not in place. Use FixMAPI.exe to correct this before installing the updated MAPI download.
  • The version number of the Windows Server 2008/Vista compatible download is 06.05.8022.0.
  • MAPI and CDO are still 32 bit only - it will install and work on a 64 bit machine, but only when used from a 32 bit program.
  • MAPISVC.inf in the system directory will be updated with Exchange's providers, but the date may not be changed. I just noticed this when testing the installer on a machine here.
  • The installer adds the MAPI install directory to the PATH statement. This MUST NOT be removed. It is required to allow DLL dependencies to work correctly.
  • Session 0 Isolation causes problems with our fix to the deleted profile issue. With that fix in place, a normal user (who lacks SeCreateGlobalPrivilege) wouldn't be able to use MAPI at all. So we modified the fix to attempt the global namespace first (which will fail for a normal user), then fall back to a local namespace. This means it is possible for a normal user to log on to a server twice with Terminal Services and delete a profile from one session that is in use under another session. To help identify this scenario, there's a new error code which will be seen by MAPI applications if this happens: MAPI_E_PROFILE_DELETED (0x80040204).
  • The download enters Extended Support in April 2009. That doesn't mean the download will be removed then, but don't expect updates to it.

Update: Looks like the Ehlo blog picked this up. Welcome Ehlo readers! I was involved in getting this update done, so lemme know if you have any questions.

The Future of Exchange's Developer APIs

Jason Henderson, the lead PM for Exchange Web Services, just put up a roadmap for the future of development against Exchange. Key points:

  • WebDav, Store Events, CDOEX and ExOleDB all say hasta la vista in the next version of Exchange. Universal replacement: Exchange Web Services
  • MAPI's not dead yet. The Exchange team's going to stop working on MAPI client binaries, but the server itself remains a MAPI server. Outlook will still use MAPI to talk to the server and you can too. You'll just be using Outlook's libraries or the raw ROPS.
  • CDO.dll is practically dead. This binary has always been owned by the Exchange team. Even when Outlook shipped a version, it was built by Exchange. Now is the time to start migrating those CDO based apps!

I've been playing with the next release of Exchange Web Services here and I gotta say the updates they have planned are pretty sweet. This API is well on it's way towards being a complete replacement for MAPI.

Posted by Stephen Griffin | 7 Comments
Filed under: , , ,

Exchange Open Protocol Docs Updated

I'm not going to drop a post every time these docs get refreshed, but I wanted to make it clear that they are getting updated periodically. The initial release was .1, and it looks like many of the docs are now on .2. Expect these refreshes to continue until the final versions are published, some time in June.
More Posts Next page »
 
Page view tracker