![]() |
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. |
|
|
Thread Tools | Search this Thread | Display Modes |
#1
|
|||
|
|||
![]()
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
|
|||
|
|||
![]()
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
|
|||
|
|||
![]()
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
|
|||
|
|||
![]()
It's best to leave the LDAP
terminology aside; but it is standard Outlook terminology |
#5
|
|||
|
|||
![]()
see
topic: Outlook address books reading (C++). http://www.microsoft.com/communities...&cr=&sloc=&p=1 |
#6
|
|||
|
|||
![]()
On Dec 2, 11:19am, 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 |
Display Modes | |
|
|
![]() |
||||
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 |