Microsoft KB Archive/934877

From BetaArchive Wiki
Knowledge Base


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:
  • 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.

#define MUIDEMSAB "\xDC\xA7\x40\xC8\xC0\x42\x10\x1A\xB4\xB9\x08\x00\x2B\x2F\xE1\x82"

To enable the MAPI global catalog server reconnect logic to work correctly in a MAPI profile, follow these steps:

  1. Start Microsoft Visual C++ 6.0.
  2. On the File menu, click New.
  3. Click Win32 Console Application, type GCReconnect in the Project Name box, and then click OK.
  4. Click An empty project, and then click Finish.
  5. In the Workspace window, click the FileView tab.
  6. In the Workspace window, right-click Header Files, and then click Add Files to Folder.
  7. In the File name box, type Profiles.h, and then click OK.
  8. In the Microsoft Visual C++ dialog box, click Yes.
  9. In the Workspace window, right-click Profiles.h, and then click Open.
  10. In the Microsoft Visual C++ dialog box, click Yes.
  11. Add the following code to the Profiles.h file.

    #pragma once
    
     
    
    // PROF SECT GUIDS
    
    #define pbGlobalProfileSectionGuid            "\x13\xDB\xB0\xC8\xAA\x05\x10\x1A\x9B\xB0\x00\xAA\x00\x2F\xC4\x5A"
    
    #define MUIDEMSAB "\xDC\xA7\x40\xC8\xC0\x42\x10\x1A\xB4\xB9\x08\x00\x2B\x2F\xE1\x82"
    
     
    
    // FLAGS
    
    #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);
    
  12. In the Workspace window, right-click Source Files, and then click Add Files to Folder.
  13. In the File name box, type Profiles.cpp, and then click OK.
  14. In the Microsoft Visual C++ dialog box, click Yes.
  15. In the Workspace window, right-click Profiles.cpp, and then click Open.
  16. In the Microsoft Visual C++ dialog box, click Yes.
  17. Add the following code to the Profiles.cpp file.

    #include <mapix.h>
    
    #include <mapiutil.h>
    
    #include <edkmdb.h>
    
    #include "Profiles.h"
    
     
    
    /***********************************************************************
    
     
    
      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)"MSEMS",                       // 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 = "MSEMS";
    
     
    
                                                                            // 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;
    
    }
    
  18. In the Workspace window, right-click Source Files, and then click Add Files to Folder.
  19. In the File name box, type Main.cpp, and then click OK.
  20. In the Microsoft Visual C++ dialog box, click Yes.
  21. In the Workspace window, right-click Main.cpp, and then click Open.
  22. In the Microsoft Visual C++ dialog box, click Yes.
  23. Add the following code to the Main.cpp file.

    #include <mapix.h>
    
    #include <mapiutil.h>
    
    #include <stdio.h>
    
    #include <conio.h>
    
    //#include <strsafe.h>
    
     
    
    #include "Profiles.h"
    
     
    
    struct MYOPTIONS
    
    {
    
                BOOL bDisplayUsage;
    
                LPSTR lpszMailbox;
    
                LPSTR lpszServer;
    
                LPSTR lpszResolveTarget;
    
    };
    
     
    
    void DisplayUsage()
    
    {
    
                printf("USAGE: GCReconnect [-?] -m MAILBOX -s SERVER -r RESOLVE NAME\n\n");
    
                printf("\t[ARGUMENTS]\n");
    
                printf("\t-?\n");
    
                printf("\t  OPTIONAL. Displays this usage information.\n\n");
    
                printf("\t-m MAILBOX\n");
    
                printf("\t  REQUIRED. Specifies the mailbox to log on to.\n\n");
    
                printf("\t-s SERVER\n");
    
                printf("\t  REQUIRED. Specifies the Exchange server where MAILBOX resides.\n\n");
    
                printf("\t-r RESOLVE NAME\n");
    
                printf("\t  REQUIRED. Specifies the name to resolve with ResolveName\n");
    
    }
    
     
    
    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], "-?") == 0)
    
                            {
    
                                        // User requests usage. Exit.
    
                                        pRunOpts->bDisplayUsage = TRUE;
    
                                        return TRUE;
    
                            }
    
                            else if (_stricmp(argv[i], "-m") == 0)
    
                            {
    
                                        // Mailbox name
    
                                        pRunOpts->lpszMailbox = argv[++i];
    
                            }
    
                            else if (_stricmp(argv[i], "-s") == 0)
    
                            {
    
                                        // Server name
    
                                        pRunOpts->lpszServer = argv[++i];
    
                            }
    
                            else if (_stricmp(argv[i], "-r") == 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("Calling MAPILogonEx\n");
    
                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("Calling QueryIdentity\n");
    
                            hRes = lpSession->QueryIdentity(&cbEID,&lpEID);
    
     
    
                            if (SUCCEEDED(hRes) && cbEID && lpEID)
    
                            {
    
                                        printf("Calling OpenAddressBook\n");
    
                                        hRes = lpSession->OpenAddressBook(0, NULL, AB_NO_DIALOG, &lpAdrBook);
    
                                        if(SUCCEEDED(hRes) && lpAdrBook)
    
                                        {
    
                                                    
    
                                                    int i = 0;
    
                                                    printf("Starting OpenEntry loop. Hit any key to exit...\n");
    
                                                    while (!_kbhit())
    
                                                    {
    
                                                                i++;
    
                                                                printf("0x%08X : ",i);
    
                                                                LPMAILUSER lpABUser = NULL;
    
                                                                ULONG ulObjType = NULL;
    
                                                                hRes = lpAdrBook->OpenEntry(
    
                                                                            cbEID,
    
                                                                            lpEID,
    
                                                                            NULL,
    
                                                                            NULL,
    
                                                                            &ulObjType,
    
                                                                            (LPUNKNOWN*) &lpABUser);
    
                                                                if(SUCCEEDED(hRes))
    
                                                                {
    
                                                                            printf("OpenEntry succeeded.\n");
    
                                                                            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("Got display name %s\n",lpVal->Value.LPSZ);
    
                                                                                        }
    
                                                                                        MAPIFreeBuffer(lpVal);
    
                                                                            }
    
                                                                }
    
                                                                else if(hRes == MAPI_E_END_OF_SESSION)
    
                                                                {
    
                                                                            printf("Session ended.  Retrying OpenEntry call.\n");
    
                                                                }
    
                                                                else
    
                                                                {
    
                                                                            printf("Error calling OpenEntry. HRESULT = 0x%08X\n", hRes);
    
                                                                }
    
                                                                if (lpABUser) lpABUser->Release();
    
                                                                lpABUser = NULL;
    
                                                    }
    
    /*                                             printf("Starting ResolveName loop. Hit any key to exit...\n");
    
                                                    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("Resolved %s successfully.\n", lpszResolveTarget);
    
                                                                                        }
    
                                                                                        else if(hRes == MAPI_E_END_OF_SESSION)
    
                                                                                        {
    
                                                                                                    printf("Session ended.  Retrying ResolveName call.\n");
    
                                                                                        }
    
                                                                                        else
    
                                                                                        {
    
                                                                                                    printf("Error calling ResolveName. HRESULT = 0x%08X\n", hRes);
    
                                                                                        }
    
                                                                            }
    
                                                                            
    
                                                                }
    
                                                                else
    
                                                                {
    
                                                                            printf("Error allocating new address list. HRESULT = 0x%08X\n", hRes);
    
                                                                }
    
                                                                
    
                                                                if(lpAdrList)FreePadrlist(lpAdrList);
    
                                                                lpAdrList = NULL;
    
                                                                
    
                                                                Sleep(1000);
    
                                                    }*/
    
                                        }
    
                                        else
    
                                        {
    
                                                    printf("Error opening address book. HRESULT = 0x%08x\n", hRes);
    
                                        }
    
                            }
    
                }
    
                else
    
                {
    
                            printf("Error logging on. HRESULT = 0x%08X\n", hRes);
    
                }
    
    }
    
     
    
    void main(int argc, char* argv[])
    
    {
    
                MYOPTIONS ProgOpts = {0};
    
     
    
                if(!ParseArgs(argc, argv, &ProgOpts) || ProgOpts.bDisplayUsage)
    
                {
    
                            DisplayUsage();
    
                            return;
    
                }
    
     
    
                printf("GC Reconnect Tester\n\n");
    
                printf("\tMailbox: %s\n", ProgOpts.lpszMailbox);
    
                printf("\tServer: %s\n", ProgOpts.lpszServer);
    
                printf("\tResolve Name: %s\n\n", ProgOpts.lpszResolveTarget);
    
     
    
                HRESULT hRes = S_OK;
    
     
    
                hRes = MAPIInitialize(NULL);
    
                if(SUCCEEDED(hRes))
    
                {
    
                            char szProfile[256] = {0};
    
                            SYSTEMTIME SysTime = {0};
    
     
    
                            GetSystemTime(&SysTime);
    
     
    
                            hRes = sprintf(szProfile, "GCReconnect%d%d%d%d%d%d", 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("Profile \"%s\" created and enabled for reconnect.\n\n", szProfile);
    
     
    
                                                                DoMAPI(szProfile, ProgOpts.lpszResolveTarget);
    
                                                    }
    
                                                    else
    
                                                    {
    
                                                                printf("Error enabling reconnect. HRESULT = 0x%08X\n", hRes);
    
                                                    }
    
                                        }
    
                                        else
    
                                        {
    
                                                    printf("Error creating profile. HRESULT = 0x%08X\n", hRes);
    
                                        }
    
     
    
                                        hRes = DeleteProfile(szProfile);
    
                                        if(SUCCEEDED(hRes))
    
                                        {
    
                                                    printf("Successfully deleted profile.\n");
    
                                        }
    
                                        else
    
                                        {
    
                                                    printf("Error deleting profile. HRESULT = 0x%08X\n", hRes);
    
                                        }
    
                            }
    
                            else
    
                            {
    
                                        printf("Error formatting profile name string. HRESULT = 0x%08X\n", hRes);
    
                            }
    
                
    
                            MAPIUninitialize();
    
                }
    
                else
    
                {
    
                            printf("Error initializing MAPI. HRESULT = 0x%08X\n", hRes);
    
                }
    
    }
    
  24. On the Build menu, click Rebuild All.


REFERENCES

The latest Edkmdb.h file is available at the Microsoft Download Center.

The following file is available for download from the Microsoft Download Center:
[GRAPHIC: Download]Download the ExchangeSDKTools.exe package now.

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

929439 A MAPI program may not obtain a referral server when the global catalog server to which the MAPI program points is shut down


Keywords: kbcode kbhowto kbexpertiseadvanced kbinfo KB934877