Initializing an Address Book Provider

Initializing an Address Book Provider

To implement an address book provider, you must initialize the address book provider by using the ABProviderInit function as an entry point. Once the address book provider's DLL is initialized, the IABProvider::Logon function allows MAPI to log on to 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.

After you have initialized an address book provider, you can access the resources in the address book provider and register to receive notifications when there is a change in the address book provider. For more information, see Accessing an Address Book Provider.

In addition, 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.

Initialization Routine

All address book providers must implement ABProviderInit as an entry point to initialize the provider's DLL. ABProviderInit checks to see whether the version number of the service provider interface, ulMAPIVers, is compatible with the current version number, CURRENT_SPI_VERSION. The function creates a new instance of the CABProvider class and returns it in the ppABProvider parameter.

ABProviderInit() Example

  STDINITMETHODIMP ABProviderInit(
    HINSTANCE hInst,
    LPMALLOC pMalloc,
    LPALLOCATEBUFFER pAllocBuff,
    LPALLOCATEMORE pAllocMore,
    LPFREEBUFFER pFreeBuff,
    ULONG /* ulFlags */,
    ULONG ulMAPIVers,
    ULONG *pulABVers,
    LPABPROVIDER *ppABProvider)
{
    HRESULT hRes = S_OK;
    LPCABProvider pABProv = NULL;
    *ppABProvider = NULL;
    pMalloc->Release();
vpfnAllocBuff = pAllocBuff;
vpfnAllocMore = pAllocMore;
vpfnFreeBuff  = pFreeBuff;

// Version check. 
if (ulMAPIVers < CURRENT_SPI_VERSION)
{
    *pulABVers = CURRENT_SPI_VERSION;
    return MAPI_E_VERSION;
}
*pulABVers = CURRENT_SPI_VERSION_UNICODE_ANSI;

// Create IABProvider.
pABProv = new CABProvider(hInst);
if (!pABProv)
{
    hRes = MAPI_E_NOT_ENOUGH_MEMORY;
    goto LCleanup;
}
*ppABProvider = (LPABPROVIDER) pABProv;

LCleanup: if (FAILED(hRes)) { if (pABProv) pABProv->Release(); } return hRes; }

Logon Routine

The last step in initializing the address book provider is to call IABProvider::Logon so that MAPI can log on to the address book provider. The function calls the OpenProfileSection method to get the profile properties for the user. Then the Logon function tries to open the database file by calling the CTxtABDatabase function. If a database file is not found, the function creates a new database file. The new logon object is returned in the lppABLogon parameter.

CABProvider::Logon() Example

  STDMETHODIMP CABProvider::Logon(
    LPMAPISUP lpMAPISup, 
    ULONG /* ulUIParam */,
    LPTSTR /* lpszProfileName */,
    ULONG /* ulFlags */,
    ULONG * /* lpulpcbSecurity */,
    LPBYTE * /* lppbSecurity */,
    LPMAPIERROR * /* lppMAPIError */,
    LPABLOGON * lppABLogon)
{    
    HRESULT hRes = S_OK;
    LPCABLogon pLogonObj = NULL;
    LPMAPIUID pUID = NULL;
    LPPROFSECT pProfSecn = NULL;
    ULONG ulcProps;
    LPSPropValue pProps = NULL;
    PCABDatabase pDB = NULL;
CheckParameters_IABProvider_Logon(this,
    lpMAPISup,
    ulUIParam,
    lpszProfileName,
    ulFlags,
    lpulpcbSecurity,
    lppbSecurity,
    lppMAPIError,
    lppABLogon);

EnterCriticalSection(&m_cs);
lpMAPISup->AddRef();
// Cast SABP_UID(GUID) to LPMAPIUID.
pUID = (LPMAPIUID)&SABP_UID;

// Open profile to get database file name.
if (FAILED(hRes = lpMAPISup->OpenProfileSection(pUID, MAPI_MODIFY, &pProfSecn)))
    goto LCleanup;
if (FAILED(hRes = pProfSecn->GetProps((LPSPropTagArray)&vsptLogonTags, 
    fMapiUnicode,
    &ulcProps,
    &pProps)))
{
    goto LCleanup;
}
// Validate props here.
if (!pProps || pProps[LOGON_DB_PATH].ulPropTag != PR_SMP_AB_PATH)
{
    hRes = MAPI_E_UNCONFIGURED;
    goto LCleanup;
}
// Open database.
pDB = new CTxtABDatabase(pProps[LOGON_DB_PATH].Value.LPSZ);
if (!pDB)
{
    hRes = MAPI_E_NOT_ENOUGH_MEMORY;
    goto LCleanup;
}
if (FAILED(hRes = pDB->Open()))
{
    goto LCleanup;
}
// Initiate CABLogon object.
pLogonObj = new CABLogon(m_hInst, 
     lpMAPISup, 
     *pUID,
     pDB);
if (!pLogonObj)
{
    hRes = MAPI_E_NOT_ENOUGH_MEMORY;
    goto LCleanup;
}
if (FAILED(hRes = lpMAPISup->SetProviderUID(pUID, 0)))
    goto LCleanup;
pLogonObj->HrSetStatusRow(TRUE, 0);
*lppABLogon = (LPABLOGON)pLogonObj;

LCleanup: LeaveCriticalSection(&m_cs); if (FAILED(hRes)) { if (pLogonObj) pLogonObj->Release(); if (pDB) pDB->Release(); } if (lpMAPISup) lpMAPISup->Release();

return hRes;

}

See Also

About the Sample Address Book Provider

Installing the Sample Address Book Provider

Accessing an Address Book Provider

Using an Address Book Container

Shutting Down an Address Book Provider