A Microsoft Outlook email forum. Outlook Banter

If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

Go Back   Home » Outlook Banter forum » Microsoft Outlook Email Newsgroups » Add-ins for Outlook
Site Map Home Register Authors List Search Today's Posts Mark Forums Read Web Partners

LDAP access



 
 
Thread Tools Search this Thread Display Modes
  #1  
Old November 26th 08, 09:53 AM posted to microsoft.public.outlook.program_addins
Sergeichik
external usenet poster
 
Posts: 21
Default LDAP access

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.

Ads
  #2  
Old November 26th 08, 03:19 PM posted to microsoft.public.outlook.program_addins
[email protected]
external usenet poster
 
Posts: 24
Default 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
  #3  
Old December 2nd 08, 05:19 PM posted to microsoft.public.outlook.program_addins
Sergeichik
external usenet poster
 
Posts: 21
Default LDAP access

I have write:

bool ReadAD()
{

// 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;
};

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

//Get ั€ierarchy table
LPMAPITABLE hierh_table;
hr = rootContainer-GetHierarchyTable(0, &hierh_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];

LPSRowSet rows = NULL;

if( SUCCEEDED( HrQueryAllRows( hierh_table,
(LPSPropTagArray) &columns, &andNode, NULL, 0, &rows)))
{
if( rows-cRows)
{
int rows_count = rows-cRows;
}
FreeProws( rows);
}

if (hierh_table) hierh_table-Release();
if (rootContainer) rootContainer-Release();
if (pAddr) pAddr-Release();
if (pSess) pSess-Release();

MAPIUninitialize();

return true;
}


But rows_count is 0, although Outlook have connected AD with several
contacts in it.

What's wrong ?
  #4  
Old December 5th 08, 12:17 PM posted to microsoft.public.outlook.program_addins
Sergeichik
external usenet poster
 
Posts: 21
Default LDAP access

It's best to leave the LDAP
terminology aside;


but it is standard Outlook terminology
  #5  
Old December 5th 08, 12:19 PM posted to microsoft.public.outlook.program_addins
Sergeichik
external usenet poster
 
Posts: 21
Default LDAP access

see
topic: Outlook address books reading (C++).
http://www.microsoft.com/communities...&cr=&sloc=&p=1

  #6  
Old December 5th 08, 04:01 PM posted to microsoft.public.outlook.program_addins
[email protected]
external usenet poster
 
Posts: 24
Default LDAP access

On Dec 2, 11:19šam, Sergeichik
wrote:
I have write:

bool ReadAD()
{

// 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;

};

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

//Get าierarchy table
LPMAPITABLE hierh_table;
hr = rootContainer-GetHierarchyTable(0, &hierh_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];

LPSRowSet rows = NULL;

if( SUCCEEDED( HrQueryAllRows( hierh_table,
š (LPSPropTagArray) &columns, &andNode, NULL, 0, &rows)))
{
š š š š if( rows-cRows)
š š š š {
š š š š š š int rows_count = rows-cRows;
š š š š }
š š š š FreeProws( rows);

}

if (hierh_table) hierh_table-Release();
if (rootContainer) rootContainer-Release();
if (pAddr) pAddr-Release();
if (pSess) pSess-Release();

MAPIUninitialize();

return true;

}

But rows_count is 0, although Outlook have connected AD with several
contacts in it.

What's wrong ?


Look through your address book containers using OutlookSpy/MFCMAPI or
else take out the restriction and dump those properties for all the
rows and see what's not matching up. You're looking for a container
which is probably called "Global Address List", but querying by name
is unwise.
 




Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
LDAP access from Outlook addin Sergeichik Outlook - General Queries 3 December 5th 08 02:36 PM
LDAP Write access? ChinaLamb Outlook - General Queries 1 June 2nd 08 05:33 AM
Write access to a LDAP server. ChinaLamb Outlook - General Queries 0 May 31st 08 03:03 AM
Cannot access LDAP address book with Outlook 2002 BadCop Outlook - General Queries 2 May 8th 06 07:36 PM
LDAP Ryan Outlook - Installation 0 March 28th 06 05:18 PM


All times are GMT +1. The time now is 07:51 AM.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.Search Engine Friendly URLs by vBSEO 2.4.0
Copyright ฉ2004-2025 Outlook Banter.
The comments are property of their posters.