none
Get GAL content via MAPI on Windows 7 fail with 0x80040200 (MAPI_E_END_OF_SESSION) RRS feed

  • Question

  • Hi everyone. I try to get GAL through Outlook default profile. It's OK on Windows XP, but fail on Windows 7(both x32/x64).

    I'm use QT 4.8.4. Here code sample:

    HRESULT printGAL() {
      HRESULT       hr          = S_OK;
      LPMAPISESSION lpSession   = NULL;
      LPADRBOOK     lpAddrBook  = NULL;
    
      #define MAPI_INIT_VERSION 0
      MAPIINIT_0 mapiInit = {MAPI_INIT_VERSION, 0};
      hr = MAPIInitialize(&mapiInit);
      hr = MAPILogonEx( 0, NULL, NULL, MAPI_EXTENDED | MAPI_LOGON_UI, &lpSession);
      hr = lpSession->OpenAddressBook(0, NULL, 0, &lpAddrBook);
      if (hr == S_OK) {
        lpAddrBook ->AddRef();
      } else {
        return hr;
      }
    
      LPSRowSet       pRow            = 0;
      ULONG           ulObjType       = 0;
      LPMAPITABLE     lpContentsTable = NULL;
      LPMAPICONTAINER lpGAL           = NULL;
      LPMAPICONTAINER pIABRoot        = NULL;
      LPMAPITABLE     pHTable         = NULL;
      
      hr = lpAddrBook->OpenEntry(0, NULL, NULL, 0, &ulObjType, (LPUNKNOWN *)&pIABRoot);
      if (hr != S_OK) return hr;
    
      hr = pIABRoot->GetHierarchyTable(CONVENIENT_DEPTH, &pHTable);
      if (hr != S_OK) return hr;
    
      SPropValue    prop;
      SRestriction  restriction;
      SBinary sbEID = {0, NULL};
      ULONG objType = 0;
    
      SizedSPropTagArray(2, IDArray) = {2, {PR_ENTRYID, PR_DISPLAY_NAME}};
    
      hr = pHTable->SetColumns((LPSPropTagArray)&IDArray, TBL_BATCH);
      if (hr != S_OK) return hr;
    
      restriction.rt = RES_CONTENT;
      restriction.res.resContent.ulFuzzyLevel = FL_FULLSTRING;
      restriction.res.resContent.ulPropTag = PR_DISPLAY_NAME_A;
      prop.ulPropTag = PR_DISPLAY_NAME_A;
      prop.Value.lpszA = "Global Address List";
      restriction.res.resContent.lpProp = ∝
    
      hr = pHTable->Restrict(&restriction, TBL_BATCH);
      if (hr != S_OK) return hr;
      hr = pHTable->QueryRows(1, 0, &pRow);
      if (hr != S_OK) return hr;
    
      if (pRow->cRows > 0 &&
              PROP_TYPE(pRow->aRow[0].lpProps[0].ulPropTag) != PT_ERROR) {
        sbEID = pRow->aRow[0].lpProps[0].Value.bin;
        hr = lpAddrBook->OpenEntry(sbEID.cb, (LPENTRYID)sbEID.lpb, NULL,
                                   0, &objType, (LPUNKNOWN*)&lpGAL);
        if (hr != S_OK) return hr;
      }
    
      hr = lpGAL->GetContentsTable(0L, &lpContentsTable);
      if (hr != S_OK) return hr;
      SizedSPropTagArray ( 2, sptCols ) = { 2,
                         PR_ENTRYID,
                         PR_DISPLAY_NAME };
      hr = lpContentsTable->SetColumns((LPSPropTagArray)&sptCols,
                                    TBL_BATCH);
      if (hr != S_OK) return hr;
    
      for (;;) {
        hr = lpContentsTable -> QueryRows ( 255, 0L, &pRow );
        if (FAILED(hr) || !pRow || !pRow->cRows) {
          if (FAILED(hr)) return hr;
          break;
        }
        for (uint j = 0;j < pRow->cRows; j++) {
          int propCount = pRow->aRow[j].cValues;
          for (int i = 0;i < propCount; i++){ // read properties
            if (pRow->aRow[j].lpProps[i].ulPropTag == PR_DISPLAY_NAME ||
                pRow->aRow[j].lpProps[i].ulPropTag == PR_DISPLAY_NAME_A ||
                pRow->aRow[j].lpProps[i].ulPropTag == PR_DISPLAY_NAME_W) {
              QString name = QString::fromWCharArray(pRow->aRow[j].lpProps[i].Value.lpszW);
              qDebug() << name;
            }
          }
        }
      }
    
      hr = lpSession->Logoff(0, NULL, 0);
      hr = lpSession->Release();
      MAPIUninitialize();
      return S_OK;
    }

    Error returned on line 70 in QueryRows method.

    I'm tried recall QueryRows, in first time it's works, but on next fail again and again.

    Also if I call it and then wait few seconds it's work and returned full GAL.

    Have someone something like this? Any suggestions?



    • Edited by sasha_plh Tuesday, July 9, 2013 11:07 AM
    Tuesday, July 9, 2013 9:10 AM

All replies

  • What is the exact error code returned by QueryRows?

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Tuesday, July 9, 2013 2:30 PM
  • It return 2147220992 in decimal, it's MAPI_E_END_OF_SESSION (0x80040200) how I found.
    It error not only in QueryRows, if I try call GetRowCount before QueryRows same error returned.
    Also MAPI session looks good. If I continue QueryRows return RowSet but only one time.

    Sorry for my english.

    Tuesday, July 9, 2013 2:46 PM
  • Do you always get that error?

    Is Outlook running at the time the call is executed?


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Tuesday, July 9, 2013 3:46 PM
  • Yes, it stable error on Windows 7, on XP it's worked.

    Outlook run and not run, the same result.

    Wednesday, July 10, 2013 8:03 AM
  • But if I make FreeProws(pRow) after error and wait some seconds, it returns GAL fully...
    Wednesday, July 10, 2013 12:23 PM
  • I have the same issue.  It works on Windows 2012 Server in my test environment.  But it fails on a Windows Azure VM.

    I will try waiting a few seconds and retrying.

    Thursday, July 18, 2013 5:39 PM
  • Seems that problem not only with me one.
    Has anyone solved it? Without bad things as mock call QueryRows in first.
    Friday, July 19, 2013 10:08 AM
  • No.  I just had to call QueryRows in a loop.  But if you only need to know the number of rows, without fetching the actual rows, then you still have a problem.  :-(
    Wednesday, August 7, 2013 2:34 PM