Registrations are now open. Join us today!
There is still a lot of work to do on the wiki yet! More information about editing can be found here.
Already have an account?

Microsoft KB Archive/306962

From BetaArchive Wiki
< Microsoft KB Archive
Revision as of 13:13, 21 July 2020 by X010 (talk | contribs) (Text replacement - "&" to "&")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Article ID: 306962

Article Last Modified on 10/25/2007


  • Microsoft Exchange Server 2003 Enterprise Edition
  • Microsoft Exchange Server 2003 Standard Edition
  • Microsoft Exchange 2000 Server Standard Edition
  • Microsoft Exchange Server 5.5 Standard Edition
  • Microsoft Messaging Application Programming Interface

This article was previously published under Q306962


A common misconception is that a MAPI client, such as Microsoft Outlook or the Exchange Client, must be installed on a Microsoft Exchange Server to create MAPI profiles. Installing a MAPI client for this reason is unnecessary. For Outlook, we do not recommend that you install a MAPI client for production servers. As long as a MAPI subsystem is installed, a variety of other ways exist to create MAPI profiles. In Exchange, a MAPI subsystem is installed.


Methods of creating MAPI profiles

Microsoft provides programming examples for illustration only, without warranty either expressed or implied. This includes, but is not limited to, the implied warranties of merchantability or fitness for a particular purpose. This article assumes that you are familiar with the programming language that is being demonstrated and with the tools that are used to create and to debug procedures. Microsoft support engineers can help explain the functionality of a particular procedure, but they will not modify these examples to provide added functionality or construct procedures to meet your specific requirements.

Before you try any one of these methods, you will have to make sure that the correct entries are made in the Mapisvc.inf file on the server. For more information about how to modify this file, click the following article number to view the article in the Microsoft Knowledge Base:

294470 How to add entries for Exchange services to Mapisvc.inf

Use NewProf.exe

The NewProf.exe utility is included with Outlook. For more information about how to use this utility, visit the following Microsoft Developer Network (MSDN) Web site:

For more information, click the following article numbers to view the articles in the Microsoft Knowledge Base:

145905 Newprof.exe command-line options

148664 Description of the Profile Descriptor File

Use the ProfMan2 sample

This sample uses the MAPI IProfAdmin interface that is mentioned in the "Use the MAPI IProfAdmin interface" section. To obtain this sample, click the following article number to view the article in the Microsoft Knowledge Base:

228736 Profman2.exe - MAPI Profile Manager v2.0

Use the MAPILogonEx function

When you call the MAPILogonEx function without specifying a profile and by setting the MAPI_LOGON_UI flag, MAPI displays the profile creation wizard if no profiles are on the computer. If profiles exist, MAPI displays the Choose Profile dialog box. Click New to start the profile creation wizard.

Sample code
// CreateProfileWithMAPILogonEx function: This takes advantage of the 
// profile prompt dialog's "New" button.
bool CreateProfileWithMAPILogonEx()
    HRESULT         hRes = S_OK;        // Return code from MAPI calls.
    LPMAPISESSION   lpSession = NULL;   // MAPI Session pointer.

    // Initialize MAPI.
    if (FAILED(hRes = MAPIInitialize(NULL)))
        cout<<"Error initializing MAPI. hRes = 0x"<<hex<<hRes<<dec<<endl;
        return FALSE;

    // Instruct user to click the "New" button.
    cout<<"When the \"Choose Profile\" dialog appears, click the \"New\" button"
        <<"to configure a new profile."<<endl;

    // Call MAPILogonEx to display the profile chooser dialog box.
    if (FAILED(hRes = MAPILogonEx(NULL,
        cout<<"Error logging on. hRes = 0x"<<hex<<hRes<<dec<<endl;
        return FALSE;

    // Log off the session.
    if (FAILED(hRes = lpSession->Logoff(0,0,0)))
        cout<<"Error logging off. hRes = 0x"<<hex<<hRes<<dec<<endl;

    // Release the session.

    // Uninitialize MAPI.

    // true, which indicates success.
    return TRUE;


This function directly calls the profile creation wizard.

Sample code
// CreateProfileWithLAUNCHWIZARD function: This uses the LAUNCHWIZARDENTRY API
// to display the profile configuration UI.
bool CreateProfileWithLAUNCHWIZARD()
    HRESULT     hRes = S_OK;                    // Return code from MAPI calls.
    TCHAR       szProfName[80] = {0};           // String to hold profile name.
    LPTSTR      szServices[] = {"MSEMS", NULL}; // String to hold message service names.

    // Call LaunchWizard to add the MSEMS service.
    if (FAILED(hRes = LaunchWizard(NULL,
                                   (LPCTSTR *)szServices,
        cout<<"Error launching wizard. hRes = 0x"<<hex<<hRes<<dec<<endl;
        return FALSE;

    // Return true indicating success.
    return TRUE;

Use the MAPI IProfAdmin interface

This MAPI interface lets you programmatically create a profile without user interaction.

Sample code
// CreateProfileWithIProfAdmin function: This uses the MAPI IProfAdmin to 
// programmatically create a profile. No UI is displayed.
bool CreateProfileWithIProfAdmin()
    HRESULT         hRes = S_OK;            // Result from MAPI calls.
    LPPROFADMIN     lpProfAdmin = NULL;     // Profile Admin object.
    LPSERVICEADMIN  lpSvcAdmin = NULL;      // Service Admin object.
    LPMAPITABLE     lpMsgSvcTable = NULL;   // Table to hold services.
    LPSRowSet       lpSvcRows = NULL;       // Rowset to hold results of table query.
    SPropValue      rgval[2];               // Property structure to hold values we want to set.
    SRestriction    sres;                   // Restriction structure.
    SPropValue      SvcProps;               // Property structure for restriction.
    char            szProfile[80] = {0};    // String for profile name.
    char            szMailbox[80] = {0};    // String for mailbox name.
    char            szServer[80] = {0};     // String for server name.

    // This indicates columns we want returned from HrQueryAllRows.
    enum {iSvcName, iSvcUID, cptaSvc};
    SizedSPropTagArray(cptaSvc,sptCols) = { cptaSvc, PR_SERVICE_NAME, PR_SERVICE_UID };

    // Get configuration info from user.
    cout<<"Enter name for profile: ";
    cout<<"Enter Exchange mailbox name: ";
    cout<<"Enter Exchange server name: ";

    // Initialize MAPI.

    if (FAILED(hRes = MAPIInitialize(NULL)))
        cout<<"Error initializing MAPI.";
        goto error;

    // Get an IProfAdmin interface.

    if (FAILED(hRes = MAPIAdminProfiles(0,              // Flags.
                                        &lpProfAdmin))) // Pointer to new IProfAdmin.
        cout<<"Error getting IProfAdmin interface.";
        goto error;

    // Create a new profile.

    if (FAILED(hRes = lpProfAdmin->CreateProfile(szProfile,     // Name of new profile.
                                                 NULL,          // Password for profile.
                                                 NULL,          // Handle to parent window.
                                                 NULL)))        // Flags.
        cout<<"Error creating profile.";
        goto error;

    // Get an IMsgServiceAdmin interface off of the IProfAdmin interface.

    if (FAILED(hRes = lpProfAdmin->AdminServices(szProfile,     // Profile that we want to modify.
                                                 NULL,          // Password for that profile.
                                                 NULL,          // Handle to parent window.
                                                 0,             // Flags.
                                                 &lpSvcAdmin))) // Pointer to new IMsgServiceAdmin.
        cout<<"Error getting IMsgServiceAdmin interface.";
        goto error;

    // Create the new message service for Exchange.

    if (FAILED(hRes = lpSvcAdmin->CreateMsgService("MSEMS",     // Name of service from MAPISVC.INF.
                                                   NULL,        // Display name of service.
                                                   NULL,        // Handle to parent window.
                                                   NULL)))      // Flags.
        cout<<"Error creating Exchange message service.";
        goto error;
    // You now have to obtain the entry id for the new service.
    // You can do this by getting the message service table
    // and getting the entry that corresponds to the new service.

    if (FAILED(hRes = lpSvcAdmin->GetMsgServiceTable(0,                 // Flags.
                                                     &lpMsgSvcTable)))  // Pointer to table.
        cout<<"Error getting Message Service Table.";
        goto error;

    // Set up restriction to query table.

    sres.rt = RES_CONTENT;
    sres.res.resContent.ulFuzzyLevel = FL_FULLSTRING;
    sres.res.resContent.ulPropTag = PR_SERVICE_NAME;
    sres.res.resContent.lpProp = &SvcProps;

    SvcProps.ulPropTag = PR_SERVICE_NAME;
    SvcProps.Value.lpszA = "MSEMS";

    // Query the table to obtain the entry for the newly created message service.

    if (FAILED(hRes = HrQueryAllRows(lpMsgSvcTable,
        cout<<"Error querying table for new message service.";
        goto error;

    // Set up a SPropValue array for the properties that you have to configure.

    // First, the server name.
    ZeroMemory(&rgval[1], sizeof(SPropValue) );
    rgval[1].ulPropTag = PR_PROFILE_UNRESOLVED_SERVER;
    rgval[1].Value.lpszA = szServer;

    // Next, the mailbox name.
    ZeroMemory(&rgval[0], sizeof(SPropValue) );
    rgval[0].ulPropTag = PR_PROFILE_UNRESOLVED_NAME; 
    rgval[0].Value.lpszA = szMailbox;

    // Configure the message service by using the previous properties.

        if (FAILED(hRes = lpSvcAdmin->ConfigureMsgService(
        (LPMAPIUID)lpSvcRows->aRow->lpProps[iSvcUID].Value.bin.lpb, // Entry ID of service to configure.
        NULL,                                                       // Handle to parent window.
        0,                                                          // Flags.
        2,                                                          // Number of properties we are setting.
        rgval)))                                                    // Pointer to SPropValue array.
        cout<<"Error configuring message service.";
        goto error;

    goto cleanup;

    cout<<" hRes = 0x"<<hex<<hRes<<dec<<endl;
    return FALSE;

    // Clean up.
    if (lpSvcRows) FreeProws(lpSvcRows);
    if (lpMsgSvcTable) lpMsgSvcTable->Release();
    if (lpSvcAdmin) lpSvcAdmin->Release();
    if (lpProfAdmin) lpProfAdmin->Release();

    return TRUE;



The following file is available for download from the Microsoft Download Center:

Release Date: October 22, 2001

For more information about how to download Microsoft support files, click the following article number to view the article in the Microsoft Knowledge Base:

119591 How to obtain Microsoft support files from online services

Microsoft scanned this file for viruses. Microsoft used the most current virus-detection software that was available on the date that the file was posted. The file is stored on security-enhanced servers that help prevent any unauthorized changes to the file. Profiler.exe is a simple Microsoft Visual C++ sample that illustrates methods 3 through 5 above. The Profiler.exe file contains the following files:

File name Size
Profiler.dsw 1 KB
Profiler.dsp 5 KB
Profiler.cpp 12 KB

Keywords: kbdownload kbhowto kbmsg KB306962