Acting as a Foreign Address Book Provider

A foreign provider is an address book provider that:

Acting as a foreign provider is an optional role; not all providers need to support template identifiers and their related code. Implement your provider as a foreign provider if you want to maintain control over recipients that host providers create using templates supplied by your provider.

The format that your provider uses for its entry identifiers can also be used for its template identifiers. Template identifiers must include your provider's registered MAPIUID to allow MAPI to successfully bind recipients to the appropriate providers.

MAPI calls your provider's IABLogon::OpenTemplateID method when a host provider calls IMAPISupport::OpenTemplateID. The host provider passes the template identifier of the recipient in the lpTemplateID parameter in its call to IMAPISupport::OpenTemplateID. MAPI determines that the template identifier belongs to your provider by matching the MAPIUID in the template identifier with the MAPIUID that your provider registered at logon time. MAPI then forwards the host provider's call to your provider through the IABLogon::OpenTemplateID method.

The host provider also passes a pointer to its property object implementation for the recipient in the lpMAPIPropData parameter, an interface identifier in the lpInterface parameter that corresponds to the type of interface implementation passed in lpMAPIPropData, and an optional flag, FILL_ENTRY. Your provider is expected to return in the lppMAPIPropNew parameter a pointer to a property object implementation of the type specified in lpInterface. The returned pointer can either be to the wrapped property object implemented by your provider or to the object supplied by the host provider in lpMAPIPropData. Your provider should return a wrapped property object pointer when:

The FILL_ENTRY flag indicates to your provider that the host provider wants all the properties of the recipient to be updated. Your provider is required to fulfill this request.

When a host provider calls your provider's OpenTemplateID method, your provider might:

The first two items are examples of tasks that do not require your provider to supply a wrapped property object — an implementation of IMAPIProp that is based on the host provider's implementation. Your provider can simply update the properties as necessary and return, setting the lppMAPIPropNew parameter to point to the pointer passed in by the host provider in the lpMAPIPropData parameter.

The second two tasks require that your provider return to the host provider a property object that wraps the host provider's object with additional functionality, such as the ability to display a property sheet for the entry. This property object will either be a messaging user or distribution list, depending on the type of object passed in by the host provider in the lpMAPIPropData parameter and indicated by the interface identifier in the lpInterface parameter. If the lpMAPIPropData parameter points to a messaging user, your provider's wrapped property object must be an IMailUser implementation. If lpMAPIPropData points to a distribution list, it must be an IDistList implementation.

Your provider's wrapped property object intercepts IMAPIProp method calls to perform context-specific manipulation of the host provider's recipient — the object it is wrapping. MAPI only has one requirement for wrapped property objects: all calls to IMAPIProp::OpenProperty requesting the PR_DETAILS_TABLE property should be passed to the host provider. Your provider's implementation can use the returned table to intercept display table notifications or to add its own if necessary.

The following list includes tasks that are typically implemented in the wrapped property object implemented by foreign providers:

    To implement IABLogon::OpenTemplateID
  1. Check if the template identifier passed in with the lpTemplateID parameter is valid and is in a format that your provider recognizes. If it is not, fail and return MAPI_E_INVALID_ENTRYID.
  2. Create an object of the type indicated by the template identifier, either a messaging user, distribution list, or one-off recipient.
  3. Call the IUnknown::AddRef method in the host provider's property object, the object pointed to by the lpMAPIPropData parameter.
  4. If the ulTemplateFlags parameter is set to FILL_ENTRY:
    1. If the new object is a messaging user or distribution list:
    1.    Retrieve all of the properties of the new object, possibly by calling its IMAPIProp::GetProps method.
    2.    Call the host provider's IMAPIProp::SetProps method to copy all of the retrieved properties to the host provider's property object.

  1. If the new object is a one-off recipient, call the host provider's IMAPIProp::SetProps method to set the following properties:
·    PR_ADDRTYPE to the address type handled by your provider.
·    PR_TEMPLATEID to the template identifier from the lpTemplateID and cbTemplateID parameters.
·    PR_DISPLAY_TYPE to DT_MAILUSER or DT_DISTLIST, as appropriate.

  1. Set the contents of the lppMAPIPropNew parameter to point to either your provider's new object or the property object passed in with the lpMAPIPropData parameter, depending on whether your provider determines a wrapped object is necessary.
  2. If a critical error occurs, such as a network failure or an out of memory condition, return the appropriate error value. This value should get propagated to the client with the appropriate MAPIERROR structure, a task performed by the host provider.