Article ID: 171636
Article Last Modified on 10/25/2007
//The following headers may be required if not already in the project:
#include <stdio.h>
#include <mapix.h>
#include <MAPITAGS.H>
#include <MAPIUTIL.H>
#include <edkmdb.h>
/*******************************************************************************
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