LDAP access
On Nov 26, 3:53*am, Sergeichik
wrote:
I'm trying to read AD(Active directory) content from Outlook addin (C++,
MAPI) by the following way:
(AD's in Outlook are represented by LDAP, and neither I nor plugin don't
know their logins or passwords, hidden somewhere in depth of Outlook internal
data)
accessing containers:
//////////////////////////////////////////////
* HRESULT hr;
* CComPtrIMAPISession pSess;
* hr = MAPILogonEx(0, NULL, NULL, MAPI_EXTENDED|MAPI_UNICODE, &pSess);
* if(FAILED(hr))
* {
* * * * * errorMes = _T("MAPI Logon failed.");
* * * * * return false;
* }
* // open address book
* CComPtrIAddrBook pAddr;
* hr = pSess-OpenAddressBook(0, 0, 0, &pAddr);
* if(FAILED(hr))
* {
* * pSess-Logoff(0, 0, 0);
* * return false;
* };
* * * * LPSRowSet containers;
* * * * hr = pAddr-GetSearchPath(MAPI_UNICODE , &containers);
* * * * if (hr!=S_OK)
* * * * {
* * * * * * * * * * pAddr.Release();
* * * * * * * * * * pSess-Logoff(0, 0, 0);
* * * * * * * * * * return false;
* * * * }
* * * * // number of folders in address book
* * * * long cont_count = containers-cRows;
* * * * if (cont_count = 0)
* * * * {
* * * * * * * * pAddr.Release();
* * * * * * * * pSess-Logoff(0, 0, 0);
* * * * * * * * return false;
* * * * }
* * * * for (int folder_number = 0; folder_number cont_count; folder_number++)
* * * * {
* * * * * * WCHAR tx [30];
* * * * * * _itow(folder_number, tx, 10);
* * * * * * CAtlString f_mess = _T("Processing folder number '"); * *
* * * * * * f_mess += CAtlString(tx); f_mess += _T("' from address book.");
* * * * * * * * SRow* folder_row = &containers-aRow[folder_number];
* * * * * * * * if (!folder_row)
* * * * * * * * {
* * * * * * * * * * * * continue;
* * * * * * * * }
* * * * * * * * LPSPropValue lpDN_cont =
PpropFindProp(folder_row-lpProps,folder_row-cValues,PR_ENTRYID);
* * * * * * * * if (!lpDN_cont)
* * * * * * * * {
* * * * * * * * * * * * continue;
* * * * * * * * }
* * * * * * * * _PV* ContainerEntryId = NULL;
* * * * * * * * ContainerEntryId = &lpDN_cont-Value;
* * * * * * * * if (!ContainerEntryId)
* * * * * * * * {
* * * * * * * * * * * * continue;
* * * * * * * * }
* * * * * * * * ReadContainerContents(pAddr, ContainerEntryId);
* * * * }
///////////////////////////////////////////////////////////////////////////////
// reading container ..
void ReadContainerContents(CComPtrIAddrBook& pAddr, _PV* ContainerEntryId)
{
* * HRESULT * * *hr = S_OK;
* * ULONG * * *ulCount = NULL;
* * LPSRowSet * * *pRows = * NULL;
* * ULONG cbeid = 0L;
* * LPENTRYID lpeid = NULL;
* * LPMAPITABLE lpMAPItbl = NULL;
* * LPABCONT lpGAL = NULL;
* * * * if ((pAddr == NULL)||(ContainerEntryId == NULL)) return;
// * * *SizedSPropTagArray(2, Columns) =
// * * * * * * *{2, {PR_ENTRYID, PR_DISPLAY_TYPE}};
* * * * * * * * LPUNKNOWN lpIUnknown = NULL;
* * * * * * * * ULONG ulObjType = NULL;
* * * * * * * * if (FAILED(pAddr-OpenEntry(ContainerEntryId-bin.cb,
(LPENTRYID)ContainerEntryId-bin.lpb, NULL, MAPI_BEST_ACCESS,
* * * * * * * * * * * * * * * * * * * * * * * * * * *&ulObjType, (LPUNKNOWN*)&lpIUnknown)))
* * * * * * * * * {
* * * * * * * * * * * * * return;
* * * * * * * * * }
//See if it is an address book container *
* * * * // If no, return ...
* * * * * * * * if (ulObjType != MAPI_ABCONT))
* * * * * * * * {
* * * * * * * * * * * * return;
* * * * * * * * }
* * * * * * * * ULONG ulFlags = NULL;
* * * * * * * * IABContainer* lpABContainer = static_castIABContainer*(lpIUnknown);
//cast the IUnknown pointer returned from previous function to what we need
* * * * * * * * hr = lpABContainer-GetContentsTable(ulFlags, &lpMAPItbl);
// * * * * * * *ASSERT(lpMAPItbl);
* * * * * * * * if (hr!=S_OK)
* * * * * * * * {
* * * * * * * * * * * * if (lpABContainer) lpABContainer-Release();
* * * * * * * * * * * * return;
* * * * * * * * }
* * * * * * * * ULONG ulRows; //Number of rows in the MAPI table
* * * * * * * * hr = lpMAPItbl-GetRowCount(0, &ulRows);
* * * * * * * * if (hr!=S_OK)
* * * * * * * * {
* * * * * * * * * * * * if (lpMAPItbl) lpMAPItbl-Release();
* * * * * * * * * * * * if (lpABContainer) lpABContainer-Release();
* * * * * * * * * * * * return;
* * * * * * * * }
* * * * * * * * if (ulRows = 0)
* * * * * * * * {
// * * * * * * * * *MessageBox("No contacts was finded");
* * * * * * * * * * * * if (lpMAPItbl) lpMAPItbl-Release();
* * * * * * * * * * * * if (lpABContainer) lpABContainer-Release();
* * * * * * * * * * * * return;
* * * * * * * * }
// * * * * * * *... process here founded contacts ..
}
/////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
But haven't any success in case of AD!!
I can read the names of AD LDAP directories(by such a way) as well as usual
local 'Address book' folders,
* * * * but if I try to read the count of contacts in them, I receive 0(zero).
Though, local folders quering return valid number of contcts (not zero) and
then I can read all of them fully.
Sure, there are some contacts in my LDAP directory exist certain and can be
viewed from the Outlook contacts book !!
And I can access them through another technology (ADO).
But need through MAPI(for example), without knowing login and password which
is already stored somewhere in Outlook and I don't authorized to know them.
Best regards, SergK.
You're looking for the Global Address List (GAL), which is a MAPI
interface onto the Global Catalog (GC). It's best to leave the LDAP
terminology aside; that's what's going on underneath, but it's not
going to help you understand what you need to do in MAPI. In
psuedocode, what you want to do is:
session-OpenAddressBook( &ab);
ab-OpenEntry( 0, NULL, NULL, 0, ..., &rootContainer); //Open the root
container by passing a NULL entry ID
rootContainer-GetHierarchyTagble( &table); //Get the container table
The rest is actual code:
SizedSPropTagArray( 1, columns) = { 1, PR_ENTRYID};
SPropValue criteria[ 2];
SRestriction restrictions[ 2];
SRestriction andNode;
criteria[ 0].ulPropTag = PR_AB_PROVIDER_ID;
criteria[ 0].Value.bin.cb = 16;
const BYTE muid[] = MUIDEMSAB;
criteria[ 0].Value.bin.lpb = (BYTE *) muid;
restrictions[ 0].rt = RES_PROPERTY;
restrictions[ 0].res.resProperty.relop = RELOP_EQ;
restrictions[ 0].res.resProperty.ulPropTag = PR_AB_PROVIDER_ID;
restrictions[ 0].res.resProperty.lpProp = &criteria[ 0];
criteria[ 1].ulPropTag = PR_EMS_AB_CONTAINERID;
criteria[ 1].Value.l = 0;
restrictions[ 1].rt = RES_PROPERTY;
restrictions[ 1].res.resProperty.relop = RELOP_EQ;
restrictions[ 1].res.resProperty.ulPropTag = PR_EMS_AB_CONTAINERID;
restrictions[ 1].res.resProperty.lpProp = &criteria[ 1];
andNode.rt = RES_AND;
andNode.res.resAnd.cRes = 2;
andNode.res.resAnd.lpRes = &restrictions[ 0];
CMapiAbContainer *retval = NULL;
LPSRowSet rows = NULL;
if( SUCCEEDED( LogMapiResult( HrQueryAllRows( table,
(LPSPropTagArray) &columns, &andNode, NULL, 0, &rows), table, _T
( "HrQueryAllRows on IABContainer hierarchy table"))))
{
if( rows-cRows)
{
if( rows-cRows 1)
LogEntry( cLogError, _T( "Found %d entries matching GAL
properties"), rows-cRows);
LPABCONT mapiContainer = NULL;
ULONG objectType = 0;
hResult = LogMapiResult( GetContainer()-OpenEntry( rows-aRow
[ 0].lpProps[ 0].Value.bin.cb, (LPENTRYID) rows-aRow[ 0].lpProps
[ 0].Value.bin.lpb, NULL, GetMapiSession()-GetAccessFlags(),
&objectType, (LPUNKNOWN *) &mapiContainer), GetContainer(), _T
( "IABContainer::OpenEntry"));
if( SUCCEEDED( hResult))
{
assert( objectType == MAPI_ABCONT);
*gal = new CMapiAbContainer( mMapiSession, mapiContainer);
hResult = S_OK;
}
}
else
{
LogEntry( cLogError, _T( "No entries matching GAL properties
found"));
hResult = MAPI_E_NOT_FOUND;
}
FreeProws( rows);
}
You're doing a restriction on the AB containers inside the address
book to find the GAL, then opening it.
Here's the definition of MUIDEMSAB:
#ifndef MUIDEMSAB
#define MUIDEMSAB { 0xDC, 0xA7, 0x40, 0xC8, 0xC0, 0x42, 0x10, 0x1A,
0xB4, 0xB9, 0x08, 0x00, 0x2B, 0x2F, 0xE1, 0x82}
#endif
|