BUG: IAdrBook::OpenEntry() Fails on Outlook Contacts

Last reviewed: September 26, 1997
Article ID: Q174394
The information in this article applies to:
  • Extended Messaging Application Programming Interface (MAPI), version 1.0

SYMPTOMS

If you attempt to use the PR_ENTRYID property for Outlook Contacts returned by IAdrBook::Address(), IAdrBook::OpenEntry() will fail with the error code MAPI_E_UNKNOWN_ENTRYID.

RESOLUTION

This problem does not occur when selecting addresses from the Exchange Global Address List or the Personal Address Book.

The only available workaround at this time is to use these steps after calling IAdrBook::Address() and before calling IAdrBook::OpenEntry():

  1. Create a message (if one has not already been created).

  2. Call IMessage::ModifyRecipients() with the ADRLIST structure returned from IAdrBook::Address.

  3. Call IMessage::GetRecipientsTable().

  4. Call HrQueryAllRows() or IMAPITable::QueryRows() to retrieve the rows of the table and have access to the entry IDs of the recipients.

STATUS

Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article. We are researching this bug and will post new information here in the Microsoft Knowledge Base as it becomes available.

MORE INFORMATION

The following code both reproduces the problem and demonstrates the workaround described in the Resolution section of this article.

Steps to Reproduce Behavior

  1. Create a Console Application containing a program with code shown below step 3.

  2. Add Mapi32.lib to the "Object/Library modules" text box in the Link tab of the Project Settings dialog box.

  3. Compile, link, and run the application. When prompted to choose recipients, be sure to select some recipients from your Outlook Address Book in order to reproduce the problem.

Sample Code

    #include <mapiutil.h>
    #include <stdio.h>

    void _FreeRowSet( LPSRowSet );
    HRESULT OpenDefStore( LPMAPISESSION, LPMDB* );

    void main ( void )
    {
      printf ( "**** Begin program ****\r\n" );

      HRESULT       hResult    = 0;
      LPMAPISESSION lpSession  = NULL;
      LPMDB         lpMsgStore = NULL;
      LPMAPIFOLDER  lpInbox    = NULL;
      LPADRBOOK     lpAdrBook  = NULL;
      LPADRLIST     lpadrlist  = NULL;

      printf ( "1. Initializing MAPI..." );
      {
        if ( FAILED(hResult = MAPIInitialize( NULL )))
        {
           printf ( " FAILED with error: %X\r\n", hResult );
           goto error;
        }
        else
           printf ( " OK\r\n" );
      }

      printf ( "2. Logging on...");
      {
        ULONG       ulFlags     = 0;

        ulFlags = ulFlags | MAPI_LOGON_UI | MAPI_NO_MAIL |
                  MAPI_EXTENDED | MAPI_NEW_SESSION;

        if( FAILED(hResult = MAPILogonEx( 0, NULL,
                       NULL, ulFlags,
                       (LPMAPISESSION FAR *) &lpSession )))
        {
          printf ( " FAILED with error: %X\r\n", hResult );
          goto error;
        }
        else
          printf ( " OK\r\n" );
      }

      printf ("3. Opening Address Book...");
      {
        if( FAILED(hResult = lpSession->OpenAddressBook( 0,
                                    NULL, 0, &lpAdrBook )))
        {
          printf ( " FAILED with error: %X\r\n", hResult );
          goto error;
        }
        else
          printf ( " OK\r\n" );
      }

      printf ("4. Display AddressBook dialog box with one well..." );
      {
        LPSTR    rglpszDestTitles[1];
        ULONG    rgulDestComps[1];
        ULONG    ulFlags           = 0;
        ULONG    ulUIParam         = 0;

        ulFlags = ulFlags | DIALOG_MODAL;

        rglpszDestTitles[0]        = "To";
        rgulDestComps[0]           = MAPI_TO;

        ADRPARM  adrparm;
        adrparm.cbABContEntryID    = 0;
        adrparm.lpABContEntryID    = NULL;
        adrparm.ulFlags            = ulFlags;
        adrparm.lpReserved         = NULL;
        adrparm.ulHelpContext      = 0;
        adrparm.lpszHelpFileName   = NULL;
        adrparm.lpfnABSDI          = NULL;
        adrparm.lpfnDismiss        = NULL;
        adrparm.lpvDismissContext  = NULL;
        adrparm.lpszCaption        = "MAPI ITP tests Address 1";
        adrparm.lpszNewEntryTitle  = "For this test dialog";
        adrparm.lpszDestWellsTitle = "Selected Recipients:";
        adrparm.cDestFields        = 1;
        adrparm.nDestFieldFocus    = 0;
        adrparm.lppszDestTitles    = rglpszDestTitles;
        adrparm.lpulDestComps      = rgulDestComps;
        adrparm.lpContRestriction  = NULL;
        adrparm.lpHierRestriction  = NULL;

        if( FAILED(hResult = lpAdrBook->Address( &ulUIParam,
                                        &adrparm, &lpadrlist )))
        {
          printf ( " FAILED with error: %X\r\n", hResult );
          goto error;
        }
        else
          printf ( " OK\r\n" );
      }

      if (!lpadrlist)
        goto error;

      printf ( "5. Getting Entry IDs and opening each " );
      printf ( "ADRENTRY...\r\n" );
      {
        ULONG   cEntry   = 0;
        ULONG   cProp   = 0;

        for(cEntry=0; cEntry<lpadrlist->cEntries; cEntry++)
        {
          for(cProp=0;
              cProp < lpadrlist->aEntries[cEntry].cValues;
              cProp++)
          {
            printf ( "   >Name: " );
            if( lpadrlist->aEntries[cEntry].rgPropVals[cProp].ulPropTag
                == PR_DISPLAY_NAME )
            {
              printf (
               lpadrlist->aEntries[cEntry].rgPropVals[cProp].Value.LPSZ
                     );
              printf ( " ...\r\n" );
              break;
            }
          }

          printf ( "    -->Find EntryID " );

          LPSPropValue lpsPropVal = NULL;
          lpsPropVal = PpropFindProp (
                           lpadrlist->aEntries[cEntry].rgPropVals,
                           lpadrlist->aEntries[cEntry].cValues,
                           PR_ENTRYID );

          if (NULL == lpsPropVal)
            printf ( " FAILED\r\n " );
          else
            printf ( " OK ... \r\n" );

          printf ( "    -->OpenEntry " );
          {
            ULONG       ulObjType       = 0;
            LPMAPIPROP  lpEntry         = NULL;
            ULONG       ulFlags         = 0;
            ulFlags = ulFlags | MAPI_BEST_ACCESS;

            if( FAILED(hResult =
                lpAdrBook->OpenEntry(lpsPropVal->Value.bin.cb,
                         (LPENTRYID)lpsPropVal->Value.bin.lpb,
                         NULL, ulFlags, &ulObjType,
                         (LPUNKNOWN*)&lpEntry)))
              printf ( " FAILED with error: %X\r\n", hResult );
            else
            {
              printf ( " OK\r\n" );
              lpEntry->Release();
            }
          }

          if (lpsPropVal)
            MAPIFreeBuffer(lpsPropVal);
        }

        printf ( "6. Opening Default Message Store ... " );
        {
          if (FAILED(hResult = OpenDefStore(lpSession, &lpMsgStore)))
          {
            printf ( " FAILED with error: %X\r\n", hResult );
            goto error;
          }
          else
            printf ( " OK\r\n" );
        }

        printf ( "7a. Get Receive Folder... " );
        {
          SBinary sbInboxEID = {0, NULL};
          ULONG         ulObjType   = 0;

          if (FAILED(hResult =
              lpMsgStore->GetReceiveFolder("IPM.Note", 0,
                          &sbInboxEID.cb,
                          (LPENTRYID *) &sbInboxEID.lpb, NULL)))
          {
            printf ( " FAILED with error: %X\r\n", hResult );
            goto error;
          }
          else
            printf ( " OK\r\n" );

          printf ( "7b. OpenEntry on Inbox[ASCII 133] " );
          if (FAILED(hResult =
              lpSession->OpenEntry(sbInboxEID.cb,
                         (LPENTRYID) sbInboxEID.lpb, NULL,
                         MAPI_MODIFY, &ulObjType,
                         (LPUNKNOWN *) &lpInbox)))
            printf ( " FAILED with error: %X\r\n", hResult);
          else
            printf ( "    Open Inbox OK\r\n", hResult);

          if (sbInboxEID.cb)
            MAPIFreeBuffer(sbInboxEID.lpb);

          if (!lpInbox)
            goto error;
        }

        printf ( "8. Creating Message... " );
        {
          LPMESSAGE lpMsg = NULL;

          if (FAILED(hResult =
              lpInbox->CreateMessage(NULL, 0, &lpMsg)))
            printf ( " FAILED with error: %X\r\n", hResult);
          else
            printf ( " OK\r\n" );


          if (lpMsg)
          {
            printf ( "9. Modify Recipients... " );
            if (FAILED(hResult =
                lpMsg->ModifyRecipients(MODRECIP_ADD, lpadrlist)))
              printf( " FAILED with error: %X\r\n", hResult);
            else
            {
              printf( " OK\r\n");

              printf ( "10. Get Recipient table... " );
              LPMAPITABLE lpRecips = NULL;
              if (FAILED(hResult =
                  lpMsg->GetRecipientTable(0, &lpRecips)))
                printf ( " FAILED with error: %X\r\n", hResult);
              else
              {
                printf ( " OK\r\n" );

                printf ( "11. GetRowCount... " );
                LPSRowSet lpsRowSet = NULL;
                ULONG     uRowCnt   = 0;

                if (FAILED(hResult =
                    lpRecips->GetRowCount(0, &uRowCnt)))
                  printf (" FAILED with error: %X\r\n", hResult);
                else
                  printf (" OK with Count: %u\r\n", uRowCnt );

                printf ("13. Getting Entry IDs/OpenEntry...\r\n");
                for (ULONG uRows=0; uRows < uRowCnt; uRows++)
                {
                  printf ( "   >QueryRows... " );
                  if (FAILED(hResult =
                    lpRecips->QueryRows( (ULONG)1, 0, &lpsRowSet)))
                  printf (" FAILED with error: %X\r\n", hResult);
                else
                {
                  printf (" OK\r\n" );

                  LPSPropValue lpsPropVal1 = NULL;
                  lpsPropVal1 = PpropFindProp (
                                  lpsRowSet->aRow[0].lpProps,
                                  lpsRowSet->aRow[0].cValues,
                                  PR_DISPLAY_NAME );
                  if (NULL != lpsPropVal1)
                  {
                    printf( "   -->Name: " );
                    printf( lpsPropVal1->Value.LPSZ );
                    printf( "\r\n" );
                  }

                  printf ( "   ----->Find EntryID..." );
                  LPSPropValue lpsPropVal = NULL;
                  lpsPropVal = PpropFindProp (
                                  lpsRowSet->aRow[0].lpProps,
                                  lpsRowSet->aRow[0].cValues,
                                  PR_ENTRYID );

                  if (NULL == lpsPropVal)
                      printf ( " FAILED\r\n" );
                    else
                    {
                      printf ( " OK \r\n" );

                      ULONG       ulObjType       = 0;
                      LPMAPIPROP  lpEntry         = NULL;
                      ULONG       ulFlags         = 0;
                      ulFlags = ulFlags | MAPI_BEST_ACCESS;

                      printf ( "   ----->OpenEntry...");
                      if ( FAILED(hResult =
                          lpAdrBook->OpenEntry(
                                 lpsPropVal->Value.bin.cb,
                                 (LPENTRYID)lpsPropVal->Value.bin.lpb,
                                 NULL, ulFlags, &ulObjType,
                                 (LPUNKNOWN*)&lpEntry)))
                        printf ( " FAILED with error: %X\r\n",
                                hResult );
                      else
                      {
                        printf ( " OK\r\n" );
                        lpEntry->Release();
                      }

                      MAPIFreeBuffer(lpsPropVal);
                    }

                    MAPIFreeBuffer(lpsRowSet);
                  }
                }

                lpRecips->Release();
              }

            }
            lpMsg->Release();
          }

        }

      }

      error:
        if (lpInbox)
          lpInbox->Release();

        if (lpMsgStore)
        {
           ULONG uflags = 0;
           lpMsgStore->StoreLogoff(&uflags);
           lpMsgStore->Release();
        }

        if (lpadrlist)
          _FreeRowSet((LPSRowSet) lpadrlist);

        if (lpAdrBook)
          lpAdrBook->Release();

        if (lpSession)
        {
          lpSession->Logoff(0,0,0);
          lpSession->Release();
        }

        printf ( "***** END PROGRAM *****\r\n" );

      return;
    }

    void _FreeRowSet( LPSRowSet lpRows )
    {
      ULONG cRows;

      if ( !lpRows )
        return;

      for( cRows = 0; cRows < lpRows->cRows; ++cRows )
      {
        MAPIFreeBuffer( lpRows->aRow[cRows].lpProps );
      }

      MAPIFreeBuffer( lpRows );
    }

    HRESULT OpenDefStore(LPMAPISESSION m_pSess, LPMDB *m_pMDB)
    {
      LPMAPITABLE         pStoresTbl = NULL;
      LPSRowSet           pRow       = NULL;
      SBinary             sbEID      = {0,NULL};
      static SRestriction sres;
      SPropValue          spv;
      HRESULT             hRes;

      static SizedSPropTagArray(2,sptCols) =
                        {2,PR_ENTRYID,PR_DEFAULT_STORE};

      if (FAILED(hRes = m_pSess -> GetMsgStoresTable(0, &pStoresTbl)))
      {
        goto Quit;
      }

      sres.rt = RES_PROPERTY;
      sres.res.resProperty.relop = RELOP_EQ;
      sres.res.resProperty.ulPropTag = PR_DEFAULT_STORE;
      sres.res.resProperty.lpProp = &spv;

      spv.ulPropTag = PR_DEFAULT_STORE;
      spv.Value.b   = TRUE;

      if (FAILED(hRes = HrQueryAllRows(pStoresTbl,
                              (LPSPropTagArray) &sptCols,
                              &sres, NULL, 0, &pRow)))
        goto Quit;

      if (pRow                    &&
          pRow -> cRows           &&
          pRow -> aRow[0].cValues &&
          PR_ENTRYID == pRow -> aRow[0].lpProps[0].ulPropTag)
        sbEID  = pRow -> aRow[0].lpProps[0].Value.bin;

      else
      {
        hRes = MAPI_E_NOT_FOUND;
        goto Quit;
      }

      if (FAILED(hRes =
          m_pSess -> OpenMsgStore(0, sbEID.cb,
                                  (LPENTRYID)sbEID.lpb,
                                  NULL, MDB_WRITE, m_pMDB)))
        goto Quit;

      Quit:
        FreeProws(pRow);

        if (pStoresTbl)
          pStoresTbl -> Release();

      return hRes;
    }

REFERENCES

Excerpts of code were used from the following samples:

Keywords          : kbcode EMAPI MAPIIAB
Version           : WINDOWS:1.0
Platform          : WINDOWS
Issue type        : kbbug


================================================================================


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: September 26, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.