How Outlook, CDO, MAPI, and Providers Work Together

Letztes Änderungsdatum des Themas: 2005-09-15

by Jason Nelson

When you diagnose problems with Microsoft® Exchange Server, particularly Exchange Server clients such as Microsoft Outlook®, or API consumers such as server applications, it is common to encounter confusion about which components are actually doing the work for any particular operation. It's common to hear descriptions of connection problems, address resolution problems, and even calendaring issues as "MAPI problems."

For purposes of this article, the following terms and definitions will be used:

MAPI will generally mean MAPI32.dll, or the APIs contained therein.
MAPI is a glue API, implemented largely in MAPI32.dll (Messaging Application Programming Interface, 32 bit build).
In MAPI, developers implement a series of Providers. Providers come in three major types, Transport Providers, Message Store Providers, and Address Book Providers. Providers are DLLs that implement a specific pseudo COM API, such as IMessageStore, and the underlying required interfaces, such as IMAPIProp.
A MAPI application simply means any application that uses the MAPI calls. MAPI applications work against sets of data sources grouped into Profiles. Profiles are created, saved, and deleted by the Profile Provider. The Profile Provider is implemented in MAPI32.dll in two forms:

The normal profile provider, which stores profile data in the registry.

An empty profile gives a MAPI application no data access, so MAPI applications add Providers (also called Services) to the profile. A common thing for MAPI applications to do is add services for EMSMDB and EMSABP to a profile, granting the ability to access data from Exchange Server. Providers do all of the actual work in MAPI. When you submit a message, although the call might pass through MAPI32, it is EMSMDB (or your provider) that does the actual work for sending. When saving a message, it is not MAPI32 that saved the message; it's the message store provider (usually EMSMDB for Exchange Server). When you resolve a recipient, it is not MAPI32 that searches for the user in the address book. It is the Address Book Provider, implementing the IAddrBook interface (probably EMSABP).

Collaboration Data Objects (CDO) refers to CDO.DLL, not CDONTS, CDOSRV, CDOSYS, CDOEX, EXCDO, or CDOEXM.
CDO and Outlook are both MAPI applications, meaning that they use MAPI APIs to access their data and, therefore, the underlying providers. CDO and Outlook share a common set of Properties that, when taken together, define different classes of messages and different functionality. This works similar to the schema in a database; however, MAPI32 does not implement the storage. The Message Store Provider does. In the case of Exchange Server, this provider is EMSMDB, and Exchange Server is mostly agnostic about the semantics of the data that applications choose to store. Exchange Server 5.5 has almost no knowledge of individual named property meanings. Exchange 2000 Server and Exchange Server 2003 are considerably more aware of the significance of particular named properties on different message classes, in particular, calendar items. This logic is implemented in EXOLEDB and EXCDO. In general, it is up to users of a particular set of properties to agree on what those properties mean and how they are manipulated.
CDO implements an API to manipulate sets of properties together to accomplish tasks, such as scheduling a meeting. Outlook also implements APIs to manipulate sets of properties, and does presentation of that data to the end user. If CDO and Outlook don't agree on what particular properties mean, or on the mechanisms used to control processing logic (for instance, when an appointment has been updated), potential for problems interoperating between Outlook and CDO exist. Although Outlook continues to be updated and expanded with every version, CDO.dll is more or less static at the same level of functionality it has possessed for years. Newer libraries for manipulating calendar data, such as CDOEX, are considerably more up to date.

EMSMDB refers to the Exchange transport provider, EMSMDB32.
One example of a provider is EMSMDB2, the "Electronic Messaging System Microsoft Data Base, 32 bit build" provider. EMSMDB implements both a transport and a message store and, as such, is a dual provider.
The transport is the ability to submit messages to Exchange Server; the message store is the ability to read (and possible write) messages to an Exchange store process.

EMSABP refers to the Exchange address book provider, EMSABP32.
The other common provider involved with Exchange Server is EMSABP, which is an Address Book Provider (Electronic Messaging System Address Book Provider, 32 bit build). EMSABP implements IAddrBook and allows access to the Exchange global address list through Name Service Provider Interface (NSPI).

It is important to understand how the components communicate with each other. For example, an application (for example, ScheduleMe.exe) uses CDO, with the intention of scheduling a meeting. Here is a high level overview of what happens. Please note that this is very much abbreviated; there are numerous interactions at each point not relevant to the overall goals of this discussion.

Application uses MAPI32's profile services to create a profile and add EMSMDB and EMSABP to it.

Application asks CDO to log on to that profile.

CDO uses MAPI APIs (MapiLogonEx) to log on to the session. CDO is also capable of calling the appropriate APIs to create a profile and populate it with Exchange Server services, dependent on the parameters used to log on.

Application asks CDO to create a meeting request.

CDO uses MAPI interfaces implemented by EMSMDB to access storage for what we will call "a message."

CDO uses MAPI interfaces (IMapiProp) implemented by EMSMDB to set a set of default properties that Outlook and CDO agree constitute "a meeting request."

Application supplies the appropriate values for subject, location, time, and so on.

CDO uses MAPI Interfaces (IMapiProp) to set the properties that Outlook and CDO agree represent those data bits, as well as any intrinsic properties needed to support this.

Application calls CDO API to send the meeting request.

CDO uses MAPI Interfaces (IMessage::Submit) implemented by EMSMDB to send the message, in the process using APIs implemented by EMSABP (ResolveNames) to resolve the recipients.

Change control is essential for good server management, and most administrators do not apply random fixes to servers for experimentation purposes. However, when troubleshooting certain classes of problems, updating the involved binaries makes a lot of sense. (We will ignore issues of memory leaks or heap corruption; in those cases, it is unlikely that an argument can be made against updating if any such fixes have been made in more recent builds.)

Take for instance, deadlocks. Deadlocks could be caused by anything in the application chain: the application, the top level API (CDO), the glue layer (MAPI32), or the providers (EMSMDB/EMSABP in this instance). Updating MAPI32 (the dll for the glue layer), CDO.dll (the .dll for the top level API), the providers (EMSMDB or EMSABP), or the application would be appropriate.

Next, consider disappearing profiles, which often manifest as failure to open information stores. Referencing the data above, you should see that profile services are implemented in MAPI32. Therefore, MAPI32 would be a possibility for updating, as would be the application, because the application might be deleting its own profile.

What about profiles not being deleted? Profile deletion might be the work of the program (if it calls MAPI directly), the top level API (CDO), or, on rare occasions, the provider (MAPI). In this case, the application, CDO.dll, and MAPI32.dll are all good candidates for updates.

Next, consider problems with context specific data such as meeting requests, free/busy, or appointments. Updating MAPI32, the glue layer that provides interfaces to the providers, but does not store or interpret data is not likely to resolve the issue. EMSMDB, the agnostic storage provider, is also not a likely candidate. What about CDO? CDO implements the sets of properties that define specific classes of messages such as meeting requests. It has to agree with Outlook about how these properties work, and the behavior can be unpredictable. In this case, updating CDO.dll makes sense. Finally, there's the application. A number of applications have attempted to operate directly against the calendar data, often with disastrous results. Always consider the application.

In the following figure, anything in one layer that touches another layer talks directly to that layer. This figure is a generalization, not a flow diagram. For instance, Outlook can use CDO, and Outlook can in later versions communicate directly with EMSMDB. The vital things to note here are that only the providers actually communicate with the server, and that these providers do not talk directly to their counterpart DLLs on the server. That means that CDO on the client does not communicate with CDO on the server, nor does MAPI, EMSMDB, or EMSABP.

Question My application doesn't run on the server. Do the server binaries need to be the same version as the client?Answer No. EMSMDB32 on the client does not communicate with EMSMDB32 on the server. It communicates with Store.exe.

Question Does MAPI32 on the client communicate with MAPI32 on the server?Answer No, it does not. MAPI32 interfaces with the providers and the application.

Question Does CDO on the client communicate with CDO on the server?Answer No, it does not. CDO interfaces with MAPI and the applications using it.

Question What if I have a CDO application that runs on the server?Answer Update the binaries "Where the application runs." If your application runs on the server, update it there.

Question But I also have it running on another computer.Answer Update where the binaries run. If it runs on the client, update it on the client. If it runs on the server, update it on the server. If the application runs on both, update both.

Question I have a third computer that runs this binary.Answer Same answer: Update where the binaries run. If it runs on the client, update it on the client. If it runs on the server, update it on the server. If the application runs on both, update both.

The area of client and server versions of the Exchange Server Providers, MAPI32, EMSMDB, EMSABP and MSPST32 almost always causes confusion. The Exchange Server team wrote each of these DLLs originally, and the Outlook client used the server versions directly for years. However, as time passed, the DLLs diverged to meet different goals, even though they retain the same name. Starting with Microsoft Office Outlook 2000, Outlook shipped its own client optimized builds of MAPI32, EMSABP, and EMSMDB.

EMSMDB32 on the client was modified to support RPC canceling instead of waiting on the server as well as RPC over HTTP and Kerberos authentication. EMSMDB32 on the server went through a series of multithreading changes to improve performance for server applications. EMSABP32 on the client gained the ability to rebind to global catalog servers, where the server version originally did not. MAPI32 was further adapted to work well with third-party providers, while the server version received additional fixes to the temp profile provider.

CDO is almost exactly the same code on the server as it is on the client, but CDO.dll on the server does not have any security warning messages, as you would not want your system service displaying messages, asking if you want to access data. CDO.dll on the client, on the other hand, does show these messages, because e-mail worms are bad. Finally, MSPTS32, the PST provider, has grown far, far richer under Outlook than the original server version. The Outlook version supports Unicode PSTs, PSTs larger than 2 GB, and sundry other improvements. The server version is still the original. People often ask why the Mailbox Merge Wizard (Exmerge.exe) doesn't create PSTs larger than 2 GB. The answer is that the server version of the DLL is not capable of it.