Last modified: July 23, 2011
Applies to: Outlook
Logs MAPI on to one instance of a message store provider.
HRESULT Logon( LPMAPISUP lpMAPISup, ULONG_PTR ulUIParam, LPSTR 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 returned message store object 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. The use 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 that exposes 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 that the provider requires. 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 that is 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 the 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 that this message store previously created. If lpEntryID points to an unwrapped entry identifier, that entry identifier can come from one of several places:
It can be an entry identifier that the store provider previously wrapped and wrote to the profile section as a PR_ENTRYID (PidTagEntryId) property.
It can be an entry identifier that the provider previously wrapped and returned to a calling client as a PR_STORE_ENTRYID (PidTagStoreEntryId) property.
It can be an entry identifier that the provider previously wrapped and returned to a calling client as the PR_ENTRYID property of a message store object.
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 by using the data in the entry identifier, 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. MAPI will then call 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 by using whatever interface derived from IUnknown is best for the provider (again, this is typically IMsgStore). When IID_IUnknown is passed, the calling implementation uses the IUnknown::QueryInterface method to select an interface after the store open operation succeeds.
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 that 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 0 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 that contains 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 about MAPI spooler logon, see the IMSProvider::SpoolerLogon method.
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 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 about the uses of properties in profile section objects, see the IProfSect : IMAPIProp method.
In addition to any private data in properties with identifiers 0x6600 through 0x67FF, the store provider should provide information for the PR_DISPLAY_NAME (PidTagDisplayName) property in its profile section. It should put in PR_DISPLAY_NAME the display name of the provider itself — an identifying string (for example, "Microsoft Personal Information Store") that is displayed to users so they can distinguish this message store from others they might have access to. 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 about profile sections, see IMAPISupport::OpenProfileSection.
After successfully logging on a user, and before returning to MAPI, the store provider should create the array of properties for the status row for the resource and call the IMAPISupport::ModifyStatusRow method.
Logon calls that open message stores that are already open for the current MAPI session skip much of the processing previously described. These calls do not create status rows, return message store logon objects, call AddRef for the MAPI support object, or return data for MAPI spooler logon. These calls do return S_OK and return a message store object with the requested interface.
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 whether the store to be logged on to is already open. If it is, user credentials do not need to be checked and the display of a dialog box should be avoided, if possible. If dialog boxes must be displayed, the provider should check returned information to see whether a store has been opened a second time. In addition, the provider should check for duplicate openings by using lpEntryID at the beginning of Logon call processing.
Standard processing for a Logon call that accesses an open store is as follows:
The store provider calls AddRef for the existing store object if the new interface being requested is the same as the interface for the existing store. Otherwise, it calls QueryInterface to get the new interface. If the store does not support the new interface, the provider should return the error value MAPI_E_INTERFACE_NOT_SUPPORTED.
The provider returns a pointer to the required interface of the existing store object in lppMDB.
The provider returns null in lppMSLogon.
The provider should not open the profile for the support object passed in the call. In addition, it should not register a provider unique identifier, register a status row, or return MAPI spooler logon data.
The provider should not call AddRef for the support object, because it does not require a pointer to the object.
Whenever possible, providers should return appropriate error and warning strings for Logon calls, because doing so greatly eases the burden of users in determining why something did not work. To return these strings, 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 by 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 LogonulFlags; 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 that belong to those services for 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.