Outlook address books reading (C++).

  • Thread starter Thread starter Sergeichik
  • Start date Start date
S

Sergeichik

There are at least 2 types of address books in Outlook: 'MAPI' and 'LDAP'.
I try to read all of it by the following working code:

///////////////////////////////////////
bool ReadAddressBooks()
{

// Initialize MAPI.
HRESULT hRes = S_OK;

if (FAILED(hRes = MAPIInitialize(NULL)))
{
return false;
}

HRESULT hr;
LPMAPISESSION pSess;
hr = MAPILogonEx(0, NULL, NULL, MAPI_EXTENDED, &pSess);
if(FAILED(hr))
{
MAPIUninitialize();
return false;
}


// open address book
LPADRBOOK pAddr;
hr = pSess->OpenAddressBook(0, 0, 0, &pAddr);
if(FAILED(hr))
{
pSess->Logoff(0, 0, 0);
MAPIUninitialize();
return false;
};

ULONG obj_type;

// open root container by passing a NULL entry ID
LPMAPICONTAINER rootContainer = NULL;
hr = pAddr->OpenEntry( 0, NULL, NULL, 0, &obj_type,
(LPUNKNOWN*)&rootContainer);

//Get hierarchy table
LPMAPITABLE root_hierh_table, hierh_table;
hr = rootContainer->GetHierarchyTable(0, &root_hierh_table);

// columns
SizedSPropTagArray( 2, columns) = { 2, PR_ENTRYID, PR_DISPLAY_NAME};


LPSRowSet rows = NULL;

//if( SUCCEEDED( HrQueryAllRows( hierh_table,
// (LPSPropTagArray) &columns, &andNode, NULL, 0, &rows)))
if( SUCCEEDED( HrQueryAllRows( root_hierh_table,
(LPSPropTagArray) &columns, NULL, NULL, 0, &rows)))
{
if( rows->cRows)
{
int rows_count = rows->cRows;
for (int row_number = 0; row_number < rows_count; row_number++)
{
LPMAPICONTAINER mapiContainer = NULL;
LPMAPITABLE lpContenTstable = NULL;
ULONG objectType = 0;

LPSPropValue lpDN_contN =
PpropFindProp(rows->aRow[ row_number].lpProps,rows->aRow[
row_number].cValues,PR_DISPLAY_NAME);

CString Cont_Name = lpDN_contN->Value.lpszW;

LPSPropValue lpDN_cont =
PpropFindProp(rows->aRow[ row_number].lpProps,rows->aRow[
row_number].cValues,PR_ENTRYID);

_PV* ContainerEntryId = NULL;
ContainerEntryId = &lpDN_cont->Value;
if (!ContainerEntryId)
{ continue;};

// open container
HRESULT hResult = pSess->OpenEntry(ContainerEntryId->bin.cb,
(LPENTRYID)ContainerEntryId->bin.lpb,
NULL, MAPI_BEST_ACCESS, &objectType, (LPUNKNOWN *) &mapiContainer);

if( FAILED( hResult))
{
continue;
}

ULONG ulFlags = NULL;
lpContenTstable = NULL;
hr = mapiContainer->GetContentsTable(ulFlags, &lpContenTstable);
if (hr!=S_OK)
{
}

hierh_table = NULL;
hr = mapiContainer->GetHierarchyTable(0, &hierh_table);

ULONG ulRows; //Number of rows in the MAPI table

ulRows = 0;
if (lpContenTstable)
hr = lpContenTstable->GetRowCount(0, &ulRows);

ulRows = 0;
if (hierh_table)
hr = hierh_table->GetRowCount(0, &ulRows);

if (hierh_table) hierh_table->Release();
if (lpContenTstable) lpContenTstable->Release();
if (mapiContainer) mapiContainer->Release();
} //for all rows (containers)
}// if rows count > 0
FreeProws( rows);
}//HrQueryAllRows

if (root_hierh_table) root_hierh_table->Release();
if (rootContainer) rootContainer->Release();
if (pAddr) pAddr->Release();
if (pSess) pSess->Release();

MAPIUninitialize();
return true;
}
///////////////////////////////////////////////////////////////////////////////////


In 'Cont_Name' I have sequentially receiving 2 names of address books:
- 'Outlook address book' (standart)
- 'name of my LDAP address book'

Then I receive valid number of folders in 'Outlook address book' and all
contacts in they (not in this code).
This part is working good.

And I can't receive any item in 'Hierarchy' or 'Contents' tables of 'LDAP
address book'.
Received contained items count is 0 (zero) in both cases.
Why ?
How can I read 'LDAP'-type Outlook address book contents programmatically ?
My 'LDAP'-connection contain several contacts, sure !
And I see them in Outlook.
 
LDAP address book provider does not display anythign in the contents table,
it only lets you search and displays the search results.
You can onserver this behavior in the Outlook UI.
This has to do with the fact that very few LDAP servers supports windowing
extensions (that allow to retrieve only a subset of entries) and retrieving
a large number (thousands) of entries is very expensive.

--
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
-
Sergeichik said:
There are at least 2 types of address books in Outlook: 'MAPI' and
'LDAP'.
I try to read all of it by the following working code:

///////////////////////////////////////
bool ReadAddressBooks()
{

// Initialize MAPI.
HRESULT hRes = S_OK;

if (FAILED(hRes = MAPIInitialize(NULL)))
{
return false;
}

HRESULT hr;
LPMAPISESSION pSess;
hr = MAPILogonEx(0, NULL, NULL, MAPI_EXTENDED, &pSess);
if(FAILED(hr))
{
MAPIUninitialize();
return false;
}


// open address book
LPADRBOOK pAddr;
hr = pSess->OpenAddressBook(0, 0, 0, &pAddr);
if(FAILED(hr))
{
pSess->Logoff(0, 0, 0);
MAPIUninitialize();
return false;
};

ULONG obj_type;

// open root container by passing a NULL entry ID
LPMAPICONTAINER rootContainer = NULL;
hr = pAddr->OpenEntry( 0, NULL, NULL, 0, &obj_type,
(LPUNKNOWN*)&rootContainer);

//Get hierarchy table
LPMAPITABLE root_hierh_table, hierh_table;
hr = rootContainer->GetHierarchyTable(0, &root_hierh_table);

// columns
SizedSPropTagArray( 2, columns) = { 2, PR_ENTRYID, PR_DISPLAY_NAME};


LPSRowSet rows = NULL;

//if( SUCCEEDED( HrQueryAllRows( hierh_table,
// (LPSPropTagArray) &columns, &andNode, NULL, 0, &rows)))
if( SUCCEEDED( HrQueryAllRows( root_hierh_table,
(LPSPropTagArray) &columns, NULL, NULL, 0, &rows)))
{
if( rows->cRows)
{
int rows_count = rows->cRows;
for (int row_number = 0; row_number < rows_count; row_number++)
{
LPMAPICONTAINER mapiContainer = NULL;
LPMAPITABLE lpContenTstable = NULL;
ULONG objectType = 0;

LPSPropValue lpDN_contN =
PpropFindProp(rows->aRow[ row_number].lpProps,rows->aRow[
row_number].cValues,PR_DISPLAY_NAME);

CString Cont_Name = lpDN_contN->Value.lpszW;

LPSPropValue lpDN_cont =
PpropFindProp(rows->aRow[ row_number].lpProps,rows->aRow[
row_number].cValues,PR_ENTRYID);

_PV* ContainerEntryId = NULL;
ContainerEntryId = &lpDN_cont->Value;
if (!ContainerEntryId)
{ continue;};

// open container
HRESULT hResult = pSess->OpenEntry(ContainerEntryId->bin.cb,
(LPENTRYID)ContainerEntryId->bin.lpb,
NULL, MAPI_BEST_ACCESS, &objectType, (LPUNKNOWN *) &mapiContainer);

if( FAILED( hResult))
{
continue;
}

ULONG ulFlags = NULL;
lpContenTstable = NULL;
hr = mapiContainer->GetContentsTable(ulFlags, &lpContenTstable);
if (hr!=S_OK)
{
}

hierh_table = NULL;
hr = mapiContainer->GetHierarchyTable(0, &hierh_table);

ULONG ulRows; //Number of rows in the MAPI table

ulRows = 0;
if (lpContenTstable)
hr = lpContenTstable->GetRowCount(0, &ulRows);

ulRows = 0;
if (hierh_table)
hr = hierh_table->GetRowCount(0, &ulRows);

if (hierh_table) hierh_table->Release();
if (lpContenTstable) lpContenTstable->Release();
if (mapiContainer) mapiContainer->Release();
} //for all rows (containers)
}// if rows count > 0
FreeProws( rows);
}//HrQueryAllRows

if (root_hierh_table) root_hierh_table->Release();
if (rootContainer) rootContainer->Release();
if (pAddr) pAddr->Release();
if (pSess) pSess->Release();

MAPIUninitialize();
return true;
}
///////////////////////////////////////////////////////////////////////////////////


In 'Cont_Name' I have sequentially receiving 2 names of address books:
- 'Outlook address book' (standart)
- 'name of my LDAP address book'

Then I receive valid number of folders in 'Outlook address book' and all
contacts in they (not in this code).
This part is working good.

And I can't receive any item in 'Hierarchy' or 'Contents' tables of 'LDAP
address book'.
Received contained items count is 0 (zero) in both cases.
Why ?
How can I read 'LDAP'-type Outlook address book contents programmatically
?
My 'LDAP'-connection contain several contacts, sure !
And I see them in Outlook.
 
Back
Top