Microsoft KB Archive/171636

= How to add more Exchange mailboxes to a MAPI profile =

Article ID: 171636

Article Last Modified on 10/25/2007

-

APPLIES TO


 * 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 Q171636





IN THIS TASK
SUMMARY
 * Sample Code



SUMMARY
This step-by-step article details the process of adding a mailbox to a MAPI profile. This will allow you to open this additional mailbox with delegate access. The owner of this mailbox must grant you delegate access prior to following this process.

This process is the programmatic equivalent to:
 * 1) Launching the mail program from the control panel.
 * 2) Selecting a profile that has the Microsoft Exchange Server service installed.
 * 3) Pulling up the Properties for Microsoft Exchange Server.
 * 4) Selecting the Advanced tab.
 * 5) Adding an additional mailbox to open.

The sample code below illustrates the steps needed to add an additional mailbox to an existing MAPI profile.

back to the top

Sample Code
Microsoft provides programming examples for illustration only, without warranty either expressed or implied, including, but not limited to, the implied warranties of merchantability and/or fitness for a particular purpose. This article assumes that you are familiar with the programming language being demonstrated and the tools used to create and debug procedures. Microsoft support professionals 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 needs. If you have limited programming experience, you may want to contact a Microsoft Certified Partner or the Microsoft fee-based consulting line at (800) 936-5200. For more information about Microsoft Certified Partners, please visit the following Microsoft Web site:

https://partner.microsoft.com/global/30000104

For more information about the support options that are available and about how to contact Microsoft, visit the following Microsoft Web site:

http://support.microsoft.com/default.aspx?scid=fh;EN-US;CNTACTMS

//The following headers may be required if not already in the project:
 * 1) include 
 * 2) include 
 * 3) include 
 * 4) include 
 * 5) include 

/*******************************************************************************

AddMailbox

This function will add an additional Exchange mailbox to an existing MAPI profile. It assumes that you have already initialized MAPI.

Parameters: lpszProfile        The name of the profile you are going to modify. lpszMailboxDisplay The string that will be displayed in the profile UI. Outlook uses the format "Mailbox - John Doe" lpszMailboxDN      The distinguished name of the mailbox to add. Ex. "/o=Microsoft/ou=Test/cn=Recipients/cn=JohnD" lpszServer         The DNS name of the server where the additional mailbox resides. lpszServerDN       The distinguished name of the server where the additional mailbox resides. Ex. "/o=Microsoft/ou=Test/cn=Configuration/cn=TestSrv"

Output: HRESULT hRes       Returns S_OK if completed successfully, otherwise returns a MAPI error.

HRESULT AddMailbox(LPSTR lpszProfile,                   LPSTR lpszMailboxDisplay,                   LPSTR lpszMailboxDN,                   LPSTR lpszServer,                   LPSTR lpszServerDN) {   HRESULT             hRes = S_OK;            // Result code returned from MAPI calls. LPPROFADMIN        lpProfAdmin = NULL;     // Profile Admin pointer. LPSERVICEADMIN     lpSvcAdmin = NULL;      // Message Service Admin pointer. LPPROVIDERADMIN    lpProvAdmin = NULL;     // Provider Admin pointer. LPMAPITABLE        lpMsgSvcTable = NULL;   // MAPI table pointer. LPPROFSECT         lpProfileSection = NULL;// Profile Section Pointer. LPSRowSet          lpSvcRows = NULL;       // Row set pointer. SPropValue         rgval[4];               // Property value structure to hold configuration info. SPropValue         NewVals;                // Property value structure to hold global profile info. SRestriction       sres;                   // Restriction structure (used in HrQueryAllRows). SPropValue         SvcProps;               // Property value structure used in restriction. LPSPropValue       lpGlobalVals = NULL;    // Property value struct pointer for global profile section. ULONG              ulProps = 0;            // Count of props. ULONG              cbNewBuffer = 0;        // Count of bytes for new buffer.

// Enumeration for convenience. enum {iDispName, iSvcName, iSvcUID, cptaSvc};

// This structure tells HrQueryAllRows what columns we want returned. SizedSPropTagArray(cptaSvc,sptCols) = { cptaSvc, PR_DISPLAY_NAME, PR_SERVICE_NAME, PR_SERVICE_UID };

// This structure tells our GetProps call what properties to get from the global profile section. SizedSPropTagArray(1, sptGlobal) = { 1, PR_STORE_PROVIDERS };

// Get an IProfAdmin interface.

hRes = MAPIAdminProfiles(0,            // Flags                             &lpProfAdmin); // Pointer to new IProfAdmin if (FAILED(hRes)) goto error_handler; printf("Retrieved IProfAdmin interface.\n");

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

hRes = lpProfAdmin->AdminServices(lpszProfile, // Profile that we want to modify.                                      "",           // Password for that profile.                                      NULL,         // Handle to parent window.                                      0,            // Flags.                                      &lpSvcAdmin); // Pointer to new IMsgServiceAdmin. if (FAILED(hRes)) goto error_handler; printf("Retrieved IMsgServiceAdmin interface.\n"); // We now need to get the entry id for the Exchange service. // First, we get the Message service table.

hRes = lpSvcAdmin->GetMsgServiceTable(0,               // Flags                                          &lpMsgSvcTable);  // Pointer to table if (FAILED(hRes)) goto error_handler; printf("Retrieved message service table from profile.\n");

// Set up restriction to query table.

sres.rt = RES_PROPERTY; sres.res.resProperty.relop = RELOP_EQ; sres.res.resProperty.ulPropTag = PR_SERVICE_NAME; sres.res.resProperty.lpProp = &SvcProps;

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

// Query the table to get the entry for the Exchange message service.

hRes = HrQueryAllRows(lpMsgSvcTable,                         (LPSPropTagArray)&sptCols,                          &sres,                          NULL,                          0,                          &lpSvcRows); if (FAILED(hRes)) goto error_handler; printf("Queried table for Exchange message service.\n");

// Get a provider admin pointer. hRes = lpSvcAdmin->AdminProviders((LPMAPIUID)lpSvcRows->aRow->lpProps[iSvcUID].Value.bin.lpb,                                     0,                                      &lpProvAdmin); if (FAILED(hRes)) goto error_handler; printf("Retrieved IProviderAdmin interface\n");

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

// First, display name. ZeroMemory(&rgval[0], sizeof(SPropValue) ); rgval[0].ulPropTag = PR_DISPLAY_NAME; rgval[0].Value.lpszA = lpszMailboxDisplay;

// Next, the DN of the mailbox. ZeroMemory(&rgval[1], sizeof(SPropValue) ); rgval[1].ulPropTag = PR_PROFILE_MAILBOX; rgval[1].Value.lpszA = lpszMailboxDN;

// Next the name of the server the mailbox is on. ZeroMemory(&rgval[2], sizeof(SPropValue) ); rgval[2].ulPropTag = PR_PROFILE_SERVER; rgval[2].Value.lpszA = lpszServer;

// Finally, the DN of the server the mailbox is on. ZeroMemory(&rgval[3], sizeof(SPropValue) ); rgval[3].ulPropTag = PR_PROFILE_SERVER_DN; rgval[3].Value.lpszA = lpszServerDN;

// Create the message service with the above properties. hRes = lpProvAdmin->CreateProvider("EMSDelegate",                                      4,                                       rgval,                                       0,                                       0,                                       (LPMAPIUID)lpSvcRows->aRow->lpProps[iSvcUID].Value.bin.lpb); if (FAILED(hRes)) goto error_handler; printf("The new mailbox is added.\n");

// Now let's set the props we need so that the additional mailbox // will display in the UI.

// Open the global profile section. hRes = lpProvAdmin->OpenProfileSection((LPMAPIUID)pbGlobalProfileSectionGuid,                                          NULL,                                           MAPI_MODIFY,                                           &lpProfileSection); if (FAILED(hRes)) goto error_handler; printf("Opened global profile section.\n");

// Get the list of store providers in PR_STORE_PROVIDERS. hRes = lpProfileSection->GetProps((LPSPropTagArray)&sptGlobal,                                     0,                                      &ulProps,                                      &lpGlobalVals); if (FAILED(hRes)) goto error_handler; printf("Got the list of mailboxes being opened.\n");

// Now we set up an SPropValue structure with the original // list + the UID of the new service.

// Compute the new byte count cbNewBuffer = lpSvcRows->aRow->lpProps[iSvcUID].Value.bin.cb + lpGlobalVals->Value.bin.cb;

// Allocate space for the new list of UIDs. hRes = MAPIAllocateBuffer( cbNewBuffer,                             (LPVOID *)&NewVals.Value.bin.lpb); if (FAILED(hRes)) goto error_handler; printf("Allocated buffer to hold new list of mailboxes to be opened.\n");

// Copy the bits into the list. // First, copy the existing list. memcpy(NewVals.Value.bin.lpb,          lpGlobalVals->Value.bin.lpb,           lpGlobalVals->Value.bin.cb);

// Next, copy the new UID onto the end of the list. memcpy(NewVals.Value.bin.lpb + lpGlobalVals->Value.bin.cb,          lpSvcRows->aRow->lpProps[iSvcUID].Value.bin.lpb,           lpSvcRows->aRow->lpProps[iSvcUID].Value.bin.cb); printf("Concatenated list of mailboxes and new mailbox.\n");

// Set the count of bytes on the SPropValue variable. NewVals.Value.bin.cb = cbNewBuffer; // Initialize dwAlignPad. NewVals.dwAlignPad = 0; // Set the prop tag. NewVals.ulPropTag = PR_STORE_PROVIDERS;

// Set the property on the global profile section. hRes = lpProfileSection->SetProps(ulProps,                                     &NewVals,                                      NULL); if (FAILED(hRes)) goto error_handler; printf("Set the new list on the global profile section.\n");

goto cleanup; error_handler: printf("ERROR: hRes = %0x\n", hRes);

cleanup: // Clean up. if (NewVals.Value.bin.lpb) MAPIFreeBuffer(NewVals.Value.bin.lpb); if (lpGlobalVals) MAPIFreeBuffer(lpGlobalVals); if (lpSvcRows) FreeProws(lpSvcRows); if (lpMsgSvcTable) lpMsgSvcTable->Release; if (lpSvcAdmin) lpSvcAdmin->Release; if (lpProfAdmin) lpProfAdmin->Release; if (lpProvAdmin) lpProvAdmin->Release; if (lpProfileSection) lpProfileSection->Release;

printf("Done cleaning up.\n");

return hRes; } The following code demonstrates how to call this sample function: void main(void) {   HRESULT hRes = S_OK;

MAPIInitialize(NULL); hRes = AddMailbox(       "My Profile",        "Mr Mailbox",        "/o=MyOrganization/ou=My-Site/cn=Recipients/cn=MMailbox",        "MyServer",        "/o=MyOrganization/ou=My-Site/cn=Configuration/cn=MyServer"); MAPIUninitialize; } back to the top

Additional query words: EMSDelegate Mailboxes

Keywords: kbhowtomaster kbmsg KB171636

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.