Using an Address Book Container

Using an Address Book Container

Before you can access an address book container, 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 address book container. The IABContainer::CreateEntry and IABContainer::DeleteEntries functions create and delete records in the address book container database. The IABContainer::ResolveNames function resolves recipient names against the address book container's content table.

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 container, you can access address book provider resources and register to receive notifications when there is a change in the address book provider. For more information, see Accessing an Address Book Provider.

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.

Create Entry Routine

The IABContainer::CreateEntry function creates an entry in the address book container and adds it to the database by creating a record. This entry can be used by a messaging user, a distribution list, or another container. A point to a pointer to the entry is returned in the lppMAPIPropEntry parameter.

CABContainer::CreateEntry() Example

  STDMETHODIMP CABContainer::CreateEntry(
    ULONG cbEntryID,
    LPENTRYID lpEntryID,
    ULONG /* ulCreateFlags */,
    LPMAPIPROP *lppMAPIPropEntry)
{
    HRESULT hRes = S_OK;
    PSABP_EID pEID = (PSABP_EID)lpEntryID;
    ULONG ulEntryType;
    CheckParameters_IABContainer_CreateEntry(this,
        cbEntryID,
        lpEntryID,
        ulCreateFlags,
        lppMAPIPropEntry);
EnterCriticalSection(&m_cs);
assert(m_pLogon);
ulEntryType = m_pLogon->CheckEID(cbEntryID, lpEntryID);
*lppMAPIPropEntry = NULL;
switch(ulEntryType)
{
case MAPI_MAILUSER:
    hRes = HrCreateMailUser(pEID); //lppMAPIPropEntry);
    break;

default:
    hRes = MAPI_E_NO_SUPPORT;
    break;
}
LeaveCriticalSection(&m_cs);
return hRes;

}

Resolve Names Routine

The IABContainer::ResolveNames function resolves names by calling the DoANR function. DoANR resolves names for one or more recipients by comparing their names with the address book container's contents table. A pointer to an ADRLIST structure that contains the list of unresolved recipients is passed in through the lpAdrList parameter. A pointer to an ADRLIST structure that contains the list of resolved names is passed out through the lpAdrList parameter.

CABContainer::ResolveNames() Example

  STDMETHODIMP CABContainer::ResolveNames(
    LPSPropTagArray lpPropTagArray,         
    ULONG           ulFlags,                
    LPADRLIST       lpAdrList,              
    LPFlagList      lpFlagList)
{
    HRESULT hRes = S_OK; 
    LPMAPITABLE pCntTbl = NULL;
    SRow ResolvedRow = {0, 0, NULL};
    LPSPropTagArray pCols;
    Validate_IABContainer_ResolveNames(this,
        lpPropTagArray,
        ulFlags,
        lpAdrList,
        lpFlagList);
    pCols = (!lpPropTagArray ? (LPSPropTagArray) &vsptCntTbl : lpPropTagArray);
    EnterCriticalSection(&m_cs);
// Contents table is sorted
if (FAILED(hRes = GetContentsTable(0,&pCntTbl)))
    goto LCleanup;
if (FAILED(hRes = pCntTbl->SetColumns(pCols, TBL_BATCH)))
    goto LCleanup;
// If a name is unresolved, parse it
for (ULONG i = 0; i < lpFlagList->cFlags; i++)       
{   
    if (MAPI_UNRESOLVED == lpFlagList->ulFlag[i])
    {
        LPSPropValue pProp = PpropFindProp(lpAdrList->aEntries[i].rgPropVals,
            lpAdrList->aEntries[i].cValues,
            PR_DISPLAY_NAME);
        if (!pProp)
            continue;
        hRes = DoANR(pProp->Value.LPSZ,
            pCntTbl, 
            &ResolvedRow,
            PR_DISPLAY_NAME);
        switch (hRes)
        {
            case S_OK : 
                // Copy props to ADRENTRY
                lpFlagList->ulFlag[i] = MAPI_RESOLVED;
                hRes = HrCopyAdrEntry(pCols,
                    &ResolvedRow,
                    &(lpAdrList->aEntries[i]));
                break;
            case MAPI_E_AMBIGUOUS_RECIP:
                lpFlagList->ulFlag[i] = MAPI_AMBIGUOUS;
                hRes = S_OK;
                break;
            case MAPI_E_NOT_FOUND:
                hRes = S_OK;
                break;
            default:
                break;
        }
    } 
}        

LCleanup: vpfnFreeBuff((LPVOID)ResolvedRow.lpProps); if (pCntTbl) pCntTbl->Release(); LeaveCriticalSection(&m_cs);

return hRes;

}

Delete Entries Routine

The IABContainer::DeleteEntries function deletes entries from the address book container. The entries are typically messaging users, distribution lists, or other containers. A pointer to an array of ENTRYLIST structures that contain the identifiers of the entries to be deleted is passed in through the lpEntries parameter. This parameter is converted into a list and each child is deleted from the address book container database.

CABContainer::DeleteEntries() Example

  STDMETHODIMP CABContainer::DeleteEntries(
    LPENTRYLIST lpEntries,
    ULONG /* ulFlags */)
{
    HRESULT hRes = S_OK;
    SPropValue prop = {0};
    SizedSPropTagArray(1, sptTag) = {1, PR_CONTAINER_CONTENTS};
    assert(m_pDB);
for(ULONG i=0; i<lpEntries->cValues; i++)
{
    PSABP_EID pEID = (PSABP_EID)lpEntries->lpbin[i].lpb;
    prop.ulPropTag = PR_INSTANCE_KEY;
    prop.Value.bin.cb = sizeof(pEID->ID.Num);
    prop.Value.bin.lpb = (LPBYTE) & (pEID->ID.Num);
    if (m_pCntsTblData)
    {
        if (FAILED(m_pCntsTblData->HrDeleteRow(&prop)))
        {
            hRes = MAPI_W_PARTIAL_COMPLETION;
            goto LCleanup;
        }
    }
    // Remove the entry from database
    if (FAILED(m_pDB->Delete(pEID->ID.Num)))
    {
        hRes = MAPI_W_PARTIAL_COMPLETION;
        goto LCleanup;
    }
}
hRes = m_pDB->Save();

LCleanup: vpfnFreeBuff(&prop); vpfnFreeBuff(&sptTag);

return hRes;

}

See Also

About the Sample Address Book Provider

Installing the Sample Address Book Provider

Initializing an Address Book Provider

Accessing an Address Book Provider

Shutting Down an Address Book Provider