Accessing an Address Book Provider

Accessing an Address Book Provider

Before you can access an address book provider, you must initialize the address book provider, and MAPI must log on to the address book provider. For more information, see Initializing an Address Book Provider.

After you have initialized an address book provider, you can access the resources in the address book provider. The IABLogon::OpenEntry function opens containers, messaging users, or distribution lists. The IABLogon::Advise function registers to receive notifications when there is a change in the address book provider.

In this topic, these functions are demonstrated by using code examples from the Sample Address Book Provider. The Sample Address Book Provider implements the required features of an address book provider, as well as more advanced features such as name resolution. For more information about the required features of an address book provider, see Required Features for Address Book Providers. For more information about downloading and installing the Sample Address Book Provider, see Installing the Sample Address Book Provider.

In addition to accessing the address book provider resources, you can access the address book container and implement more advanced features such as name resolution. For more information, see Using an Address Book Container.

When you are finished using an address book provider, you must implement functions to properly log off and shut down the address book provider. For more information, see Shutting Down an Address Book Provider.

Open Entry Routine

The IABLogon::OpenEntry function opens a container, messaging user, or distribution list. A pointer to the type of the opened object is returned in the lpulObjType parameter. A pointer to the opened object is returned in the lppUnk parameter.

CABLogon::OpenEntry() Example

  STDMETHODIMP CABLogon::OpenEntry(
    ULONG cbEntryID, 
    LPENTRYID lpEntryID, 
    LPCIID lpInterface, 
    ULONG /* ulFlags */,
    ULONG *lpulObjType, 
    LPUNKNOWN *lppUnk)
{
    CheckParameters_IABLogon_OpenEntry(this,
        cbEntryID, 
        lpEntryID,
        lpInterface,
        ulFlags,
        lpulObjType,
        lppUnk);
    HRESULT hRes = S_OK;
    PSABP_EID pEID = (PSABP_EID)(lpEntryID);
    LPCMailUser pMailUser = NULL;
if (lpInterface    != NULL
    && (REFIID)*lpInterface != IID_IMAPIContainer
    && (REFIID)*lpInterface != IID_IABContainer
    && (REFIID)*lpInterface != IID_IDistList
    && (REFIID)*lpInterface != IID_IMailUser 
    && (REFIID)*lpInterface != IID_IMAPIProp)
{
    return MAPI_E_INTERFACE_NOT_SUPPORTED;
}
// Validate the EID
ULONG ulEntryType = CheckEID(cbEntryID,lpEntryID);
EnterCriticalSection(&m_cs);
switch (ulEntryType)
{
    case MAPI_ABCONT:
        // Root Container
        if (!pEID || pEID->ID.Num == ROOT_ID_NUM)
        {
            if (m_pRootCont)
            {
                m_pRootCont->AddRef();
                *lppUnk = static_cast<LPUNKNOWN>(m_pRootCont);
                *lpulObjType = MAPI_ABCONT;
            }
            else
            {
                hRes = HrOpenRoot(lpulObjType, lppUnk);
            }
            break;
        }
        // Dir Container
        if (pEID->ID.Num == DIR_ID_NUM)
        {
            if (m_pDirCont)
            {
                m_pDirCont->AddRef();
                *lppUnk = static_cast<LPUNKNOWN>(m_pDirCont);
                *lpulObjType = MAPI_ABCONT;
                break;
            }
        }
        hRes = HrOpenContainer(pEID, lpulObjType, lppUnk);
        break;

    case MAPI_MAILUSER:
        pMailUser = new CMailUser(m_hInst, pEID, this, m_pSupObj, m_pDB);
        if (!pMailUser)
        {
            hRes = MAPI_E_NOT_ENOUGH_MEMORY;
            goto LCleanup;
        }
        if (FAILED(hRes = pMailUser->HrInit()))
        {
            pMailUser->Release();
            goto LCleanup;
        }
        *lppUnk = (LPUNKNOWN)pMailUser;
        *lpulObjType = MAPI_MAILUSER;            
        break;

    default:
        hRes = MAPI_E_INVALID_ENTRYID;
        break;
}

LCleanup:
    LeaveCriticalSection(&m_cs);

return hRes;

}

Advise Routine

The IABLogon::Advise function registers to be notified when there is a change in the address book provider's container. Notifications can be registered on messaging users, distribution lists, or containers. The ulEventMask parameter contains a mask of values that indicate which events the address book provider is interested in. For more information, see NOTIFICATION.

CABLogon::Advise() Example

  STDMETHODIMP CABLogon::Advise(
    ULONG             cbEntryID,
    LPENTRYID         lpEntryID,
    ULONG             ulEventMask,
    LPMAPIADVISESINK  lpAdviseSink,
    ULONG            *lpulConnection)
{
    HRESULT hRes = S_OK;
    ULONG ulCnx;
    ULONG ulEntryType;
    SizedNOTIFKEY(sizeof SABP_EID, Key);
    CheckParameters_IABLogon_Advise(this,
        cbEntryID,
        lpEntryID,
        ulEventMask,
        lpAdviseSink,
        lpulConnection);
    EnterCriticalSection(&m_cs);
// Validate the entryID
ulEntryType = CheckEID(cbEntryID, lpEntryID);
if (ulEntryType == FOREIGN_ENTRY || ulEntryType == MAPI_E_INVALID_ENTRYID)
{
    hRes = MAPI_E_INVALID_ENTRYID;
    goto LCleanup;
}
// Verify event support
if (ulEventMask & ~SUPPORTED_EVENTS)
{
    hRes = MAPI_E_NO_SUPPORT;
    goto LCleanup;
}
Key.cb = cbEntryID;
memcpy((LPVOID)Key.ab, (LPVOID)lpEntryID, Key.cb);
assert(m_pSupObj);
if (FAILED(hRes = m_pSupObj->Subscribe((LPNOTIFKEY)&Key,
    ulEventMask,
    0,
    lpAdviseSink,  
    & ulCnx)))
{
    goto LCleanup;
}
// Save the cnx number
m_ullstAdviseCnx.push_back(ulCnx);
*lpulConnection = ulCnx;    

LCleanup:
    LeaveCriticalSection(&m_cs);

return hRes;

}

See Also

About the Sample Address Book Provider

Installing the Sample Address Book Provider

Initializing an Address Book Provider

Using an Address Book Container