Microsoft KB Archive/934877

= How to enable the MAPI global catalog server reconnect logic in Exchange 2003 or in Exchange 2000 =

Article ID: 934877

Article Last Modified on 10/25/2007

-

APPLIES TO


 * Microsoft Exchange Server 2003 Enterprise Edition
 * Microsoft Exchange Server 2003 Standard Edition
 * Microsoft Exchange 2000 Enterprise Server
 * Microsoft Exchange 2000 Server Standard Edition

-



INTRODUCTION
This article describes how to enable the MAPI global catalog server reconnect logic to work correctly in a MAPI profile. This logic is added when you install either of the following Microsoft Exchange Server updates:  Microsoft Exchange Server 2003 Service Pack 1 (SP1)

For more information, visit the following Microsoft Web site:

http://technet.microsoft.com/en-us/exchange/2003/bb288485.aspx

 The August 2004 Exchange 2000 post-Service Pack 3 (SP3) Update Rollup

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

870540 Availability of the August 2004 Exchange 2000 Server Post-Service Pack 3 Update Rollup





MORE INFORMATION
If a global catalog server is unavailable, the MAPI global catalog server reconnect logic lets a MAPI program recover dynamically by releasing the unavailable server. Then, the MAPI global catalog server reconnect logic obtains a new referral from Exchange Server without starting a new MAPI session.

The MAPI global catalog reconnect logic uses the following properties in a MAPI profile:
 * PR_PROFILE_ABP_ALLOW_RECONNECT
 * Any value that is greater than zero enables the reconnect logic.
 * PR_PROFILE_ABP_MTHREAD_TIMEOUT_SECS
 * This property indicates the number of seconds that multiple threads that are accessing the address book at the same time should block while they wait for the first thread that enters the reconnect logic to finish.
 * PR_PROFILE_SERVER_VERSION
 * The Exchange Server address book provider (EMSABP32.dll) checks this property on the global profile section to determine the Exchange Server version. A value of 3000 indicates Exchange 2000.

Therefore, you must set the PR_PROFILE_ABP_ALLOW_RECONNECT property to a positive value to turn on the reconnect logic. Additionally, set the PR_PROFILE_SERVER_VERSION property to 3000 if there are no servers that are running Microsoft Exchange Server 5.5 servers in your organization.

These properties are set on the EMSABP profile section. Use the OpenProfileSection function and the following UID. To enable the MAPI global catalog server reconnect logic to work correctly in a MAPI profile, follow these steps:  Start Microsoft Visual C++ 6.0. On the File menu, click New. Click Win32 Console Application, type GCReconnect in the Project Name box, and then click OK. Click An empty project, and then click Finish.</li> In the Workspace window, click the FileView tab.</li> In the Workspace window, right-click Header Files, and then click Add Files to Folder.</li> In the File name box, type Profiles.h, and then click OK.</li> In the Microsoft Visual C++ dialog box, click Yes.</li> In the Workspace window, right-click Profiles.h, and then click Open.</li> In the Microsoft Visual C++ dialog box, click Yes.</li>  Add the following code to the Profiles.h file.
 * 1) define MUIDEMSAB &quot;\xDC\xA7\x40\xC8\xC0\x42\x10\x1A\xB4\xB9\x08\x00\x2B\x2F\xE1\x82&quot;
 * 1) pragma once

// PROF SECT GUIDS


 * 1) define pbGlobalProfileSectionGuid           &quot;\x13\xDB\xB0\xC8\xAA\x05\x10\x1A\x9B\xB0\x00\xAA\x00\x2F\xC4\x5A&quot;


 * 1) define MUIDEMSAB &quot;\xDC\xA7\x40\xC8\xC0\x42\x10\x1A\xB4\xB9\x08\x00\x2B\x2F\xE1\x82&quot;

// FLAGS


 * 1) define MAPI_FORCE_ACCESS      0x00080000

STDMETHODIMP CreateProfile(LPSTR lpszProfileName,

LPSTR lpszExchangeServer,

LPSTR lpszMailbox);

STDMETHODIMP DeleteProfile(LPSTR lpszProfileName);

STDMETHODIMP OpenGlobalProfileSection(LPSTR lpszProfile, LPPROFSECT * lppProfSect);

STDMETHODIMP SvcAdminOpenProfileSection(LPSERVICEADMIN lpSvcAdmin,

LPMAPIUID lpUID,

LPCIID lpInterface,

ULONG ulFlags,

LPPROFSECT FAR * lppProfSect);

STDMETHODIMP ProvAdminOpenProfileSection(LPPROVIDERADMIN lpProvAdmin,

LPMAPIUID lpUID,

LPCIID lpInterface,

ULONG ulFlags,

LPPROFSECT FAR * lppProfSect);

STDMETHODIMP EnableReconnect(LPSTR lpszProfile); </li> In the Workspace window, right-click Source Files, and then click Add Files to Folder.</li> In the File name box, type Profiles.cpp, and then click OK.</li> In the Microsoft Visual C++ dialog box, click Yes.</li> In the Workspace window, right-click Profiles.cpp, and then click Open.</li> In the Microsoft Visual C++ dialog box, click Yes.</li>  Add the following code to the Profiles.cpp file.
 * 1) include <mapix.h>


 * 1) include <mapiutil.h>


 * 1) include <edkmdb.h>


 * 1) include &quot;Profiles.h&quot;

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

STDMETHODIMP CreateProfile(LPSTR lpszProfileName,

LPSTR lpszExchangeServer,

LPSTR lpszMailbox)

- lpszProfileName:                   [in] Name of profile to be created

- lpszExchangeServer:  [in] Name of the Exchange server

- lpszMailbox:                          [in] Name of the mailbox

This procedure is fairly straightforward. It creates a profile by using the MAPI interfaces.



STDMETHODIMP CreateProfile(LPSTR lpszProfileName,

LPSTR lpszExchangeServer,

LPSTR lpszMailbox)

{

HRESULT        hRes = S_OK;                                   // Result from MAPI calls

LPPROFADMIN    lpProfAdmin = NULL;             // Profile Admin object

// Get an IProfAdmin interface

hRes = MAPIAdminProfiles(0,                            // Flags

&lpProfAdmin); // Pointer to new IProfAdmin

if(SUCCEEDED(hRes) && lpProfAdmin)

{

// Create a new profile

hRes = lpProfAdmin->CreateProfile((LPTSTR)lpszProfileName,         // Name of new profile

NULL,                                              // Password for profile

NULL,                                              // Handle to parent window

NULL);                                 // Flags

if(SUCCEEDED(hRes))

{

LPSERVICEADMIN lpSvcAdmin = NULL;              // Service Admin object

// Get an IMsgServiceAdmin interface off the IProfAdmin interface

hRes = lpProfAdmin->AdminServices((LPTSTR)lpszProfileName,      // Profile that we want to modify

NULL,                                              // Password for that profile

NULL,                                              // Handle to parent window

0,                                          // Flags

&lpSvcAdmin);                     // Pointer to new IMsgServiceAdmin

if(SUCCEEDED(hRes) && lpSvcAdmin)

{

// Create the new message service for Exchange

hRes = lpSvcAdmin->CreateMsgService((LPTSTR)&quot;MSEMS&quot;,                      // Name of service from MAPISVC.INF

NULL,                        // Display name of service

NULL,                        // Handle to parent window

NULL);                                   // Flags

if(SUCCEEDED(hRes))

{

// We now have to obtain the entry ID for the new service.

// You can do this by obtaining the message service table

// and by obtaining the entry that corresponds to the new service.

LPMAPITABLE    lpMsgSvcTable = NULL;  // Table to hold services

hRes = lpSvcAdmin->GetMsgServiceTable(0,                                     // Flags

&lpMsgSvcTable);      // Pointer to table

if(SUCCEEDED(hRes) && lpMsgSvcTable)

{

LPSRowSet      lpSvcRows = NULL;             // Rowset to hold results of table query

SRestriction     sres;                                                     // Restriction structure

SPropValue                 SvcProps;                                            // Property structure for restriction

// Set up restriction to query table.

sres.rt = RES_CONTENT;

sres.res.resContent.ulFuzzyLevel = FL_FULLSTRING;

sres.res.resContent.ulPropTag = PR_SERVICE_NAME_A;

sres.res.resContent.lpProp = &SvcProps;

SvcProps.ulPropTag = PR_SERVICE_NAME;

SvcProps.Value.lpszA = &quot;MSEMS&quot;;

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

// This indicates the columns that we want to be returned from HrQueryAllRows

enum {iSvcName, iSvcUID, cptaSvc};

SizedSPropTagArray(cptaSvc,sptCols) = { cptaSvc, PR_SERVICE_NAME_A, PR_SERVICE_UID };

hRes = HrQueryAllRows(lpMsgSvcTable,

(LPSPropTagArray)&sptCols,

&sres,

NULL,

0,

&lpSvcRows);

if(SUCCEEDED(hRes) && lpSvcRows)

{

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

SPropValue rgval[2];

int i = 0;

// First, the server name

ZeroMemory(&rgval[i], sizeof(SPropValue) );

rgval[i].ulPropTag = PR_PROFILE_UNRESOLVED_SERVER;

rgval[i++].Value.lpszA = lpszExchangeServer;

// Next, the mailbox name

ZeroMemory(&rgval[i], sizeof(SPropValue) );

rgval[i].ulPropTag = PR_PROFILE_UNRESOLVED_NAME;

rgval[i++].Value.lpszA = lpszMailbox;

hRes = lpSvcAdmin->ConfigureMsgService((LPMAPIUID)lpSvcRows->aRow[0].lpProps[1].Value.bin.lpb, // Entry ID of service to configure

NULL,                                                                                                                                             // Handle to parent window

0,                                                                                                                                                     // Flags

i,                                                                                                                                                      // Number of properties that we are setting

rgval);                                                                                                                                               // Pointer to SPropValue array

}

if (lpSvcRows) FreeProws(lpSvcRows);

}

if (lpMsgSvcTable) lpMsgSvcTable->Release;

}

}

if (lpSvcAdmin) lpSvcAdmin->Release;

}

}

if (lpProfAdmin) lpProfAdmin->Release;

return hRes;

}

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

STDMETHODIMP DeleteProfile(LPSTR lpszProfileName)

- lpszProfileName:                   [in] Name of profile to delete

This procedure is fairly straightforward. It deletes the indicated profile by using the

MAPI interfaces.



STDMETHODIMP DeleteProfile(LPSTR lpszProfileName)

{

HRESULT                              hRes = S_OK;

LPPROFADMIN    lpProfAdmin = NULL;

// Get an IProfAdmin interface

hRes = MAPIAdminProfiles(0,                            // Flags

&lpProfAdmin); // Pointer to new IProfAdmin

if(SUCCEEDED(hRes) && lpProfAdmin)

{

hRes = lpProfAdmin->DeleteProfile(lpszProfileName, 0);

}

if (lpProfAdmin) lpProfAdmin->Release;

return hRes;

}

STDMETHODIMP OpenGlobalProfileSection(LPSTR lpszProfile, LPPROFSECT * lppProfSect)

{

HRESULT hRes = S_OK;

LPPROFADMIN lpProfAdmin = NULL;

hRes = MAPIAdminProfiles(0, &lpProfAdmin);

if(SUCCEEDED(hRes) && lpProfAdmin)

{

LPSERVICEADMIN lpSvcAdmin = NULL;

hRes = lpProfAdmin->AdminServices((LPTSTR)lpszProfile,

NULL,

NULL,

0,

&lpSvcAdmin);

if(SUCCEEDED(hRes) && lpSvcAdmin)

{

hRes = lpSvcAdmin->OpenProfileSection((LPMAPIUID)&pbGlobalProfileSectionGuid,

NULL,

0,

lppProfSect);

lpSvcAdmin->Release;

}

lpProfAdmin->Release;

}

return hRes;

}

STDMETHODIMP SvcAdminOpenProfileSection(LPSERVICEADMIN lpSvcAdmin,

LPMAPIUID lpUID,

LPCIID lpInterface,

ULONG ulFlags,

LPPROFSECT FAR * lppProfSect)

{

HRESULT hRes = S_OK;

// Note: We have to open the profile section with full access.

// MAPI discriminates who can modify profiles, especially

// in certain sections. The way to force access has changed in

// different versions of Outlook. Therefore, there are two methods. See KB article 822977

// for more information.

// First, let us try the easier method of passing the MAPI_FORCE_ACCESS flag

// to OpenProfileSection. This method is available only in Outlook 2003 and in later versions of Outlook.

hRes = lpSvcAdmin->OpenProfileSection(lpUID,

lpInterface,

ulFlags | MAPI_FORCE_ACCESS,

lppProfSect);

if(FAILED(hRes))

{

// If this does not succeed, it may be because you are using an earlier version of Outlook.

// In this case, use the sample code

// from KB article 228736 for more information. Note: This information was compiled from that sample.

//

///////////////////////////////////////////////////////////////////

// MAPI will always return E_ACCESSDENIED

// when we open a profile section on the service if we are a client. The workaround

// is to call into one of MAPI's internal functions that bypasses

// the security check. We build an interface to it, and then point to it from our

// offset of 0x48. USE THIS METHOD AT YOUR OWN RISK! THIS METHOD IS NOT SUPPORTED!

interface IOpenSectionHack : public IUnknown

{

public:

virtual HRESULT STDMETHODCALLTYPE OpenSection(LPMAPIUID, ULONG, LPPROFSECT*) = 0;

};

IOpenSectionHack** ppProfile = (IOpenSectionHack**)((((BYTE*)lpSvcAdmin) + 0x48));

// Now, we want to open the Services Profile Section and store that

// interface with the Object

hRes = (*ppProfile)->OpenSection(lpUID,

ulFlags,

lppProfSect);

//

///////////////////////////////////////////////////////////////////

}

return hRes;

}

STDMETHODIMP ProvAdminOpenProfileSection(LPPROVIDERADMIN lpProvAdmin,

LPMAPIUID lpUID,

LPCIID lpInterface,

ULONG ulFlags,

LPPROFSECT FAR * lppProfSect)

{

HRESULT hRes = S_OK;

hRes = lpProvAdmin->OpenProfileSection(lpUID,

lpInterface,

ulFlags | MAPI_FORCE_ACCESS,

lppProfSect);

if((FAILED(hRes)) && (MAPI_E_UNKNOWN_FLAGS == hRes))

{

// The MAPI_FORCE_ACCESS flag is implemented only in Outlook 2002 and in later versions of Outlook.

//

//

//                                    Makes MAPI think we are a service and not a client.

//                                    MAPI grants us Service Access. This makes it all possible.

*(((BYTE*)lpProvAdmin) + 0x60) = 0x2; // USE THIS METHOD AT YOUR OWN RISK! THIS METHOD IS NOT SUPPORTED!

hRes = lpProvAdmin->OpenProfileSection(lpUID,

lpInterface,

ulFlags,

lppProfSect);

}

return hRes;

}

STDMETHODIMP EnableReconnect(LPSTR lpszProfile)

{

HRESULT hRes = S_OK;

LPPROFADMIN lpProfAdmin = NULL;

hRes = MAPIAdminProfiles(0, &lpProfAdmin);

if(SUCCEEDED(hRes) && lpProfAdmin)

{

LPSERVICEADMIN lpSvcAdmin = NULL;

hRes = lpProfAdmin->AdminServices((LPTSTR)lpszProfile,

NULL,

NULL,

0,

&lpSvcAdmin);

if(SUCCEEDED(hRes) && lpSvcAdmin)

{

LPPROFSECT lpABProfSect = NULL;

hRes = SvcAdminOpenProfileSection(lpSvcAdmin,

(LPMAPIUID)&MUIDEMSAB, NULL, MAPI_MODIFY, &lpABProfSect);

if(SUCCEEDED(hRes) && lpABProfSect)

{

SPropValue spReconnectProps[2] = {0};

spReconnectProps[0].ulPropTag = PR_PROFILE_ABP_ALLOW_RECONNECT;

spReconnectProps[0].Value.l = 1;

spReconnectProps[1].ulPropTag = PR_PROFILE_ABP_MTHREAD_TIMEOUT_SECS;

spReconnectProps[1].Value.l = 10;

hRes = lpABProfSect->SetProps(2, spReconnectProps, NULL);

if(SUCCEEDED(hRes))

{

LPPROFSECT lpGlobalProfSect = NULL;

hRes = SvcAdminOpenProfileSection(lpSvcAdmin,

(LPMAPIUID)&pbGlobalProfileSectionGuid, NULL, MAPI_MODIFY, &lpGlobalProfSect);

if(SUCCEEDED(hRes) && lpGlobalProfSect)

{

SPropValue spServerVersion = {0};

spServerVersion.ulPropTag = PR_PROFILE_SERVER_VERSION;

spServerVersion.Value.l = 3000;

hRes = lpGlobalProfSect->SetProps(1, &spServerVersion, NULL);

}

if(lpGlobalProfSect)

lpGlobalProfSect->Release;

}

}

if(lpABProfSect)

lpABProfSect->Release;

}

if(lpSvcAdmin)

lpSvcAdmin->Release;

}

if(lpProfAdmin)

lpProfAdmin->Release;

return hRes;

} </li> In the Workspace window, right-click Source Files, and then click Add Files to Folder.</li> In the File name box, type Main.cpp, and then click OK.</li> In the Microsoft Visual C++ dialog box, click Yes.</li> <li>In the Workspace window, right-click Main.cpp, and then click Open.</li> <li>In the Microsoft Visual C++ dialog box, click Yes.</li> <li> Add the following code to the Main.cpp file.
 * 1) include <mapix.h>


 * 1) include <mapiutil.h>


 * 1) include <stdio.h>


 * 1) include <conio.h>

//#include <strsafe.h>


 * 1) include &quot;Profiles.h&quot;

struct MYOPTIONS

{

BOOL bDisplayUsage;

LPSTR lpszMailbox;

LPSTR lpszServer;

LPSTR lpszResolveTarget;

};

void DisplayUsage

{

printf(&quot;USAGE: GCReconnect [-?] -m MAILBOX -s SERVER -r RESOLVE NAME\n\n&quot;);

printf(&quot;\t[ARGUMENTS]\n&quot;);

printf(&quot;\t-?\n&quot;);

printf(&quot;\t OPTIONAL. Displays this usage information.\n\n&quot;);

printf(&quot;\t-m MAILBOX\n&quot;);

printf(&quot;\t REQUIRED. Specifies the mailbox to log on to.\n\n&quot;);

printf(&quot;\t-s SERVER\n&quot;);

printf(&quot;\t REQUIRED. Specifies the Exchange server where MAILBOX resides.\n\n&quot;);

printf(&quot;\t-r RESOLVE NAME\n&quot;);

printf(&quot;\t REQUIRED. Specifies the name to resolve with ResolveName\n&quot;);

}

BOOL ParseArgs(int argc, char * argv[], MYOPTIONS * pRunOpts)

{

if(!pRunOpts)

return FALSE;

ZeroMemory(pRunOpts, sizeof(MYOPTIONS));

for(int i = 1; i < argc; i++)

{

if (_stricmp(argv[i], &quot;-?&quot;) == 0)

{

// User requests usage. Exit.

pRunOpts->bDisplayUsage = TRUE;

return TRUE;

}

else if (_stricmp(argv[i], &quot;-m&quot;) == 0)

{

// Mailbox name

pRunOpts->lpszMailbox = argv[++i];

}

else if (_stricmp(argv[i], &quot;-s&quot;) == 0)

{

// Server name

pRunOpts->lpszServer = argv[++i];

}

else if (_stricmp(argv[i], &quot;-r&quot;) == 0)

{

// Name to resolve

pRunOpts->lpszResolveTarget = argv[++i];

}

}

if(!pRunOpts->lpszMailbox || !pRunOpts->lpszServer || !pRunOpts->lpszResolveTarget)

return FALSE;

return TRUE;

}

void DoMAPI(LPSTR lpszProfile, LPSTR lpszResolveTarget)

{

HRESULT hRes = S_OK;

LPMAPISESSION lpSession = NULL;

printf(&quot;Calling MAPILogonEx\n&quot;);

hRes = MAPILogonEx(0, lpszProfile, NULL, MAPI_NEW_SESSION | MAPI_EXTENDED | MAPI_NO_MAIL, &lpSession);

if(SUCCEEDED(hRes) && lpSession)

{

LPADRBOOK lpAdrBook = NULL;

LPENTRYID lpEID = NULL;

ULONG    cbEID = NULL;

printf(&quot;Calling QueryIdentity\n&quot;);

hRes = lpSession->QueryIdentity(&cbEID,&lpEID);

if (SUCCEEDED(hRes) && cbEID && lpEID)

{

printf(&quot;Calling OpenAddressBook\n&quot;);

hRes = lpSession->OpenAddressBook(0, NULL, AB_NO_DIALOG, &lpAdrBook);

if(SUCCEEDED(hRes) && lpAdrBook)

{

int i = 0;

printf(&quot;Starting OpenEntry loop. Hit any key to exit...\n&quot;);

while (!_kbhit)

{

i++;

printf(&quot;0x%08X : &quot;,i);

LPMAILUSER lpABUser = NULL;

ULONG ulObjType = NULL;

hRes = lpAdrBook->OpenEntry(

cbEID,

lpEID,

NULL,

NULL,

&ulObjType,

(LPUNKNOWN*) &lpABUser);

if(SUCCEEDED(hRes))

{

printf(&quot;OpenEntry succeeded.\n&quot;);

if (lpABUser)

{

SPropTagArray sTag;

sTag.cValues = 1;

sTag.aulPropTag[0] = PR_DISPLAY_NAME;

ULONG ulVal = NULL;

LPSPropValue lpVal = NULL;

hRes = lpABUser->GetProps(&sTag,NULL,&ulVal,&lpVal);

if(SUCCEEDED(hRes) && 1 == ulVal && lpVal && lpVal->ulPropTag == PR_DISPLAY_NAME && lpVal->Value.LPSZ)

{

printf(&quot;Got display name %s\n&quot;,lpVal->Value.LPSZ);

}

MAPIFreeBuffer(lpVal);

}

}

else if(hRes == MAPI_E_END_OF_SESSION)

{

printf(&quot;Session ended. Retrying OpenEntry call.\n&quot;);

}

else

{

printf(&quot;Error calling OpenEntry. HRESULT = 0x%08X\n&quot;, hRes);

}

if (lpABUser) lpABUser->Release;

lpABUser = NULL;

}

/*                                            printf(&quot;Starting ResolveName loop. Hit any key to exit...\n&quot;);

while (!_kbhit)

{

LPADRLIST lpAdrList = NULL;

int cb = CbNewADRLIST(1);

hRes = MAPIAllocateBuffer(cb, (LPVOID*)&lpAdrList);

if(SUCCEEDED(hRes) && lpAdrList)

{

hRes = MAPIAllocateBuffer(sizeof(SPropValue), (LPVOID FAR*)&lpAdrList->aEntries[0].rgPropVals);

if(SUCCEEDED(hRes) && lpAdrList->aEntries[0].rgPropVals)

{

lpAdrList->cEntries = 1;

lpAdrList->aEntries[0].cValues = 1;

lpAdrList->aEntries[0].rgPropVals[0].ulPropTag = PR_DISPLAY_NAME;

lpAdrList->aEntries[0].rgPropVals[0].Value.lpszA = lpszResolveTarget;

hRes = lpAdrBook->ResolveName(0, 0, NULL, lpAdrList);

if(SUCCEEDED(hRes))

{

printf(&quot;Resolved %s successfully.\n&quot;, lpszResolveTarget);

}

else if(hRes == MAPI_E_END_OF_SESSION)

{

printf(&quot;Session ended. Retrying ResolveName call.\n&quot;);

}

else

{

printf(&quot;Error calling ResolveName. HRESULT = 0x%08X\n&quot;, hRes);

}

}

}

else

{

printf(&quot;Error allocating new address list. HRESULT = 0x%08X\n&quot;, hRes);

}

if(lpAdrList)FreePadrlist(lpAdrList);

lpAdrList = NULL;

Sleep(1000);

}*/

}

else

{

printf(&quot;Error opening address book. HRESULT = 0x%08x\n&quot;, hRes);

}

}

}

else

{

printf(&quot;Error logging on. HRESULT = 0x%08X\n&quot;, hRes);

}

}

void main(int argc, char* argv[])

{

MYOPTIONS ProgOpts = {0};

if(!ParseArgs(argc, argv, &ProgOpts) || ProgOpts.bDisplayUsage)

{

DisplayUsage;

return;

}

printf(&quot;GC Reconnect Tester\n\n&quot;);

printf(&quot;\tMailbox: %s\n&quot;, ProgOpts.lpszMailbox);

printf(&quot;\tServer: %s\n&quot;, ProgOpts.lpszServer);

printf(&quot;\tResolve Name: %s\n\n&quot;, ProgOpts.lpszResolveTarget);

HRESULT hRes = S_OK;

hRes = MAPIInitialize(NULL);

if(SUCCEEDED(hRes))

{

char szProfile[256] = {0};

SYSTEMTIME SysTime = {0};

GetSystemTime(&SysTime);

hRes = sprintf(szProfile, &quot;GCReconnect%d%d%d%d%d%d&quot;, SysTime.wMonth, SysTime.wDay,

SysTime.wYear, SysTime.wHour, SysTime.wMinute, SysTime.wSecond);

if(SUCCEEDED(hRes))

{

hRes = CreateProfile(szProfile, ProgOpts.lpszServer, ProgOpts.lpszMailbox);

if(SUCCEEDED(hRes))

{

hRes = EnableReconnect(szProfile);

if(SUCCEEDED(hRes))

{

printf(&quot;Profile \&quot;%s\&quot; created and enabled for reconnect.\n\n&quot;, szProfile);

DoMAPI(szProfile, ProgOpts.lpszResolveTarget);

}

else

{

printf(&quot;Error enabling reconnect. HRESULT = 0x%08X\n&quot;, hRes);

}

}

else

{

printf(&quot;Error creating profile. HRESULT = 0x%08X\n&quot;, hRes);

}

hRes = DeleteProfile(szProfile);

if(SUCCEEDED(hRes))

{

printf(&quot;Successfully deleted profile.\n&quot;);

}

else

{

printf(&quot;Error deleting profile. HRESULT = 0x%08X\n&quot;, hRes);

}

}

else

{

printf(&quot;Error formatting profile name string. HRESULT = 0x%08X\n&quot;, hRes);

}

MAPIUninitialize;

}

else

{

printf(&quot;Error initializing MAPI. HRESULT = 0x%08X\n&quot;, hRes);

}

} </li> <li>On the Build menu, click Rebuild All.</li></ol>

<div class="references_section">