Platform SDK: MAPI |
The IMSProvider::Logon method logs MAPI on to one instance of a message store provider.
HRESULT Logon( LPMAPISUP lpMAPISup, ULONG ulUIParam, LPTSTR lpszProfileName, ULONG cbEntryID, LPENTRYID lpEntryID, ULONG ulFlags, LPCIID lpInterface, ULONG FAR * lpcbSpoolSecurity, LPBYTE FAR * lppbSpoolSecurity, LPMAPIERROR FAR * lppMAPIError, LPMSLOGON FAR * lppMSLogon, LPMDB FAR * lppMDB );
MAPI calls the IMSProvider::Logon method to do the majority of processing necessary to obtain access to a message store. Message store providers validate any user credentials necessary to access a particular store and return a message store object in the lppMDB parameter that the MAPI spooler and client applications can log on to.
In addition to the message store object returned for client and MAPI spooler use, the provider also returns a message store logon object for MAPI to use in controlling the opened store. The message store logon object and the message store object should be tightly linked inside the message store provider so each can affect the other. Usage of the store object and the logon object should be identical; there should be a one-to-one correspondence between the logon object and the store object such that the objects act as if they are one object exposing two interfaces. The two objects should also be created together and freed together.
The MAPI support object, created by MAPI and passed to the provider in the lpMAPISup parameter, provides access to functions in MAPI required by the provider. These include functions that save and retrieve profile information, access address books, and so on. The lpMAPISup pointer can be different for each store that is opened. While processing calls for a message store after logon, the store provider should use the lpMAPISup variable specific to that store. For any Logon call that opens a message store and succeeds in creating a message store logon object, the provider must save a pointer to the MAPI support object in the store logon object and must call the IUnknown::AddRef method to add a reference for the support object.
The ulUIParam parameter should be used if the provider presents dialog boxes during the Logon call. However, dialog boxes should not be presented if ulFlags contains the MDB_NO_DIALOG flag. If a user interface needs to be called but ulFlags does not allow it, or if for some other reason a user interface cannot be displayed, the provider should return MAPI_E_LOGON_FAILED. If Logon displays a dialog box and the user cancels logon, typically by clicking the dialog box's Cancel button, the provider should return MAPI_E_USER_CANCEL.
The lpEntryID parameter can either be NULL or point to an unwrapped store entry identifier previously created by this message store. If lpEntryID points to an unwrapped entry identifier, that entry identifier can come from one of several places:
In any of these cases, it is possible that the entry identifier was created on a different computer than the one currently being used.
When lpEntryID is not NULL, it should contain all of the information needed to identify and locate the message store. This information can include network volume names, phone numbers, user account names, and so on. If the connection to the store cannot be made using the data in the entry identifier, then the store provider should display a dialog box that enables the user to select the store to be opened. A dialog box might be required, for example, if a server has been renamed, an account name has changed, or portions of the network are not available.
When lpEntryID is NULL, the message store to use has not yet been selected. The provider can still access a store without displaying a dialog box if it supports further methods to specify the store. For example, the provider can check its initialization file, or it can look for additional properties that were placed in its or its message service's profile section at configuration.
If a provider finds that all the required information is not in the profile, it should return MAPI_E_UNCONFIGURED so that MAPI calls the provider's message service entry point function to enable the user to select a store, or even to create one, and to enter an account name and password as needed. MAPI automatically creates a new profile section for a new store; this new profile section can be temporary or permanent, depending on how it has been added. If the store provider calls the IMAPISupport::ModifyProfile method, the new profile section becomes permanent and the store is added to the list of message stores returned by the IMAPISession::GetMsgStoresTable method.
The lpInterface parameter specifies the IID of the interface required for the newly opened store object. Passing NULL in lpInterface specifies that the MAPI message store interface, IMsgStore, is required. Passing the message store object, IID_IMsgStore, also specifies that IMsgStore is required. If IID_IUnknown is passed in lpInterface, the provider should open the store using whatever interface derived from IUnknown that is best for the provider; again, this is typically IMsgStore. When IID_IUnknown is passed, after the store open operation succeeds the calling implementation uses the IUnknown::QueryInterface method to select an interface.
The IMSProvider::Logon call should return sufficient information, such as a path to the store and credentials for accessing the store, to allow the MAPI spooler to log on to the same store the store provider does without presenting a dialog box. The lpcbSpoolSecurity and lppbSpoolSecurity parameters are used to return this information. The provider allocates the memory for this data by passing a pointer to a buffer in the MSProviderInit function's lpfAllocateBuffer parameter; the provider places the size of this buffer in lpcbSpoolSecurity.
MAPI frees this buffer when appropriate. If the MAPI spooler's logon to the store can be accomplished from the information in the profile section alone, the provider can return NULL in lppbSpoolSecurity and zero for the information's size in lpcbSpoolSecurity. The MAPI spooler logon occurs as part of a different process than the store logon; because the buffer holding the passed information gets copied between processes, it might not be in memory at the same location for the MAPI spooler process as for the store provider process. Therefore, a provider shouldn't put addresses into this buffer. For more information on MAPI spooler logon, see IMSProvider::SpoolerLogon.
Most store providers use the IMAPISession::OpenProfileSection method of the support object passed in the lpMAPISup parameter for saving and retrieving user credentials and options. OpenProfileSection enables a store provider to save additional arbitrary information in a profile section and associate it with a particular resource. For example, a store provider can save the user account name and password associated with a resource and any paths or other necessary information needed to access that resource.
Properties with property identifiers 0x6600 through 0x67FF are secure properties available to the provider for its own use to store private data in profile sections. For more information on the uses of properties in profile section objects, see IProfSect : IMAPIProp.
In addition to any private data in properties with identifiers 0x6600 through 0x67FF, the store provider should provide information for the PR_DISPLAY_NAME property in its profile section. It should place in PR_DISPLAY_NAME the display name of the provider itself — an identifying string displayed to users so they can distinguish this message store from others they might have access to — for example, "Microsoft Personal Information Store." PR_DISPLAY_NAME commonly contains a server name, user account name, or path.
Some profile section properties are visible in the message store table; others are visible during setup, installation, and configuration of the MAPI subsystem. The provider typically provides information for these visible properties both for a new profile section, which does not yet include saved credentials or private information, and when it finds that property information has changed. For more information on profile sections, see IMAPISupport::OpenProfileSection.
After successfully logging a user on, and before returning to MAPI, the store provider should create the array of properties for the status row for the resource and call IMAPISupport::ModifyStatusRow.
Logon calls that open message stores already open for the current MAPI session skip much of the processing described previously. These calls do not create status rows, do not return message store logon objects, do not call AddRef for the MAPI support object, and do not return data for MAPI spooler logon. These calls do return S_OK and do return a message store object with the interface requested.
To detect such calls, the provider should maintain a list in the message store provider object of stores already open for this provider object. When processing a Logon call, the provider should scan this list of open stores and determine if the store to be logged onto is already open. If it is, user credentials do not need to be checked and dialog box display should be avoided if possible. If dialog boxes must be displayed, the provider should check information returned to see whether a store has been opened a second time. In addition, the provider should check for duplicate openings using lpEntryID at the beginning of Logon call processing.
Standard processing for a Logon call that accesses an open store is as follows:
Whenever possible, providers should return appropriate error and warning strings for Logon calls because doing so greatly eases the burden of users determining why something did not work. To do so, a provider sets the members in the MAPIERROR structure. MAPI looks for, uses, and releases the MAPIERROR structure if it is returned by a provider.
Memory for this MAPIERROR structure should be allocated using the buffer passed in lpfAllocateBuffer on the MSProviderInit call. Any error strings contained in the returned structure should be in Unicode format if MAPI_UNICODE is set in the Logon ulFlags; otherwise, they should be in the ANSI character set.
For most error values returned from Logon, MAPI disables the message services to which the failing provider belongs. MAPI will not call any providers belonging to those services for the rest of the life of the MAPI session. In contrast, when Logon returns the MAPI_E_FAILONEPROVIDER error value from its logon, MAPI does not disable the message service to which the provider belongs. Logon should return MAPI_E_FAILONEPROVIDER if it encounters an error that does not warrant disabling the entire service for the life of the session. For example, a provider might return this error when it does not allow the display of a user interface and a required password is unavailable.
If a provider returns MAPI_E_UNCONFIGURED from its logon, MAPI will call the provider's message service entry function and then retry the logon. MAPI passes MSG_SERVICE_CONFIGURE as the context, to give the service a chance to configure itself. If the client has chosen to allow a user interface on the logon, the service can present its configuration property sheet so the user can enter configuration information.
IMAPISession::GetMsgStoresTable, IMAPISession::OpenMsgStore, IMAPISession::OpenProfileSection, IMAPISupport::ModifyProfile, IMAPISupport::ModifyStatusRow, IMsgStore : IMAPIProp, IMSProvider::SpoolerLogon, IProfSect : IMAPIProp, MAPIERROR, MSProviderInit