_Check_return_ HRESULT GetABContainerTable(_In_ LPADRBOOK lpAdrBook, _Deref_out_opt_ LPMAPITABLE* lpABContainerTable) { HRESULT hRes = S_OK; LPABCONT lpABRootContainer = NULL; LPMAPITABLE lpTable = NULL; *lpABContainerTable = NULL; if (!lpAdrBook) return MAPI_E_INVALID_PARAMETER; // Open root address book (container). EC_H(CallOpenEntry( NULL, lpAdrBook, NULL, NULL, NULL, NULL, NULL, NULL, (LPUNKNOWN*)&lpABRootContainer)); if (lpABRootContainer) { // Get a table of all of the Address Books. EC_MAPI(lpABRootContainer->GetHierarchyTable(CONVENIENT_DEPTH | fMapiUnicode, &lpTable)); *lpABContainerTable = lpTable; lpABRootContainer->Release(); } return hRes; } // GetABContainerTable
HRESULT CWAB::IterateWABContents(CWabIterator *pIter, int *pDone) { if (!m_bInitialized || !m_lpAdrBook) return( E_FAIL); ULONG ulObjType = 0; LPMAPITABLE lpAB = NULL; ULONG cRows = 0; LPSRowSet lpRowAB = NULL; LPABCONT lpContainer = NULL; int cNumRows = 0; nsresult keepGoing; HRESULT hr = E_FAIL; ULONG lpcbEID = 0; LPENTRYID lpEID = NULL; ULONG rowCount = 0; ULONG curCount = 0; nsString uniStr; // Get the entryid of the root PAB container // hr = m_lpAdrBook->GetPAB( &lpcbEID, &lpEID); if (HR_FAILED( hr)) goto exit; ulObjType = 0; // Open the root PAB container // This is where all the WAB contents reside // hr = m_lpAdrBook->OpenEntry(lpcbEID, (LPENTRYID)lpEID, NULL, 0, &ulObjType, (LPUNKNOWN *)&lpContainer); m_lpWABObject->FreeBuffer(lpEID); lpEID = NULL; if(HR_FAILED(hr)) goto exit; // Get a contents table of all the contents in the // WABs root container // hr = lpContainer->GetContentsTable( 0, &lpAB); if(HR_FAILED(hr)) goto exit; hr = lpAB->GetRowCount( 0, &rowCount); if (HR_FAILED(hr)) rowCount = 100; if (rowCount == 0) rowCount = 1; // Order the columns in the ContentsTable to conform to the // ones we want - which are mainly DisplayName, EntryID and // ObjectType // The table is gauranteed to set the columns in the order // requested // hr =lpAB->SetColumns( (LPSPropTagArray)&ptaEid, 0 ); if(HR_FAILED(hr)) goto exit; // Reset to the beginning of the table // hr = lpAB->SeekRow( BOOKMARK_BEGINNING, 0, NULL ); if(HR_FAILED(hr)) goto exit; // Read all the rows of the table one by one // do { hr = lpAB->QueryRows(1, 0, &lpRowAB); if(HR_FAILED(hr)) break; if(lpRowAB) { cNumRows = lpRowAB->cRows; if (cNumRows) { LPTSTR lpsz = lpRowAB->aRow[0].lpProps[ieidPR_DISPLAY_NAME].Value.lpszA; LPENTRYID lpEID = (LPENTRYID) lpRowAB->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.lpb; ULONG cbEID = lpRowAB->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.cb; // There are 2 kinds of objects - the MAPI_MAILUSER contact object // and the MAPI_DISTLIST contact object // For the purposes of this sample, we will only consider MAILUSER // objects // if(lpRowAB->aRow[0].lpProps[ieidPR_OBJECT_TYPE].Value.l == MAPI_MAILUSER) { // We will now take the entry-id of each object and cache it // on the listview item representing that object. This enables // us to uniquely identify the object later if we need to // CStrToUnicode( lpsz, uniStr); keepGoing = pIter->EnumUser( uniStr.get(), lpEID, cbEID); curCount++; if (pDone) { *pDone = (curCount * 100) / rowCount; if (*pDone > 100) *pDone = 100; } } } FreeProws(lpRowAB ); } } while ( SUCCEEDED(hr) && cNumRows && lpRowAB && NS_SUCCEEDED(keepGoing) ) ; hr = lpAB->SeekRow( BOOKMARK_BEGINNING, 0, NULL ); if(HR_FAILED(hr)) goto exit; // Read all the rows of the table one by one // keepGoing = TRUE; do { hr = lpAB->QueryRows(1, 0, &lpRowAB); if(HR_FAILED(hr)) break; if(lpRowAB) { cNumRows = lpRowAB->cRows; if (cNumRows) { LPTSTR lpsz = lpRowAB->aRow[0].lpProps[ieidPR_DISPLAY_NAME].Value.lpszA; LPENTRYID lpEID = (LPENTRYID) lpRowAB->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.lpb; ULONG cbEID = lpRowAB->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.cb; // There are 2 kinds of objects - the MAPI_MAILUSER contact object // and the MAPI_DISTLIST contact object // For the purposes of this sample, we will only consider MAILUSER // objects // if(lpRowAB->aRow[0].lpProps[ieidPR_OBJECT_TYPE].Value.l == MAPI_DISTLIST) { LPABCONT distListContainer = NULL; // We will now take the entry-id of each object and cache it // on the listview item representing that object. This enables // us to uniquely identify the object later if we need to // hr = m_lpAdrBook->OpenEntry(cbEID, lpEID, NULL, 0,&ulObjType,(LPUNKNOWN *)&distListContainer); LPMAPITABLE distListTable = NULL; // Get a contents table of the dist list // hr = distListContainer->GetContentsTable( 0, &distListTable); if (lpAB) { hr = distListTable->GetRowCount( 0, &rowCount); if (HR_FAILED(hr)) rowCount = 100; if (rowCount == 0) rowCount = 1; // Order the columns in the ContentsTable to conform to the // ones we want - which are mainly DisplayName, EntryID and // ObjectType // The table is gauranteed to set the columns in the order // requested // hr = distListTable->SetColumns( (LPSPropTagArray)&ptaEid, 0 ); CStrToUnicode( lpsz, uniStr); keepGoing = pIter->EnumList( uniStr.get(), lpEID, cbEID, distListTable); curCount++; if (pDone) { *pDone = (curCount * 100) / rowCount; if (*pDone > 100) *pDone = 100; } } if (distListContainer) distListContainer->Release(); if (distListTable) distListTable->Release(); } } FreeProws(lpRowAB ); } } while ( SUCCEEDED(hr) && cNumRows && lpRowAB && NS_SUCCEEDED(keepGoing) ) ; exit: if ( lpContainer ) lpContainer->Release(); if ( lpAB ) lpAB->Release(); return hr; }
void COLFolderBase::ExtractChildFolders() { m_childs.clear(); if (!m_initRef->Inited()) return; if (!m_pABCont) return; LPMAPITABLE pChildTable = NULL; if (SUCCEEDED(m_pABCont->GetHierarchyTable(0, &pChildTable))) { SizedSPropTagArray ( 2, sptCols ) = {2, PR_DISPLAY_NAME, PR_ENTRYID}; LPSRowSet pRowSet = NULL; if (SUCCEEDED(g_pMAPIEDK->pHrQueryAllRows(pChildTable, reinterpret_cast<SPropTagArray*>(&sptCols), NULL, NULL, 0, &pRowSet))) { for (ULONG i = 0; i < pRowSet->cRows; ++i) { string name; if (LPSPropValue pPVN = g_pMAPIEDK->pPpropFindProp(pRowSet->aRow[i].lpProps, pRowSet->aRow[i].cValues, PR_DISPLAY_NAME)) { name = pPVN->Value.lpszA ? pPVN->Value.lpszA : ""; } LPABCONT pChildContainer = NULL; if (LPSPropValue pPVE = g_pMAPIEDK->pPpropFindProp(pRowSet->aRow[i].lpProps, pRowSet->aRow[i].cValues, PR_ENTRYID)) { SBinary entry = pPVE->Value.bin; ULONG ulObjType = 0; LPUNKNOWN pUnk = NULL; if (SUCCEEDED(m_pABCont->OpenEntry(entry.cb, (LPENTRYID)entry.lpb, NULL, MAPI_BEST_ACCESS, &ulObjType, &pUnk))) { if (MAPI_ABCONT == ulObjType) { pChildContainer = (LPABCONT)pUnk; pChildContainer->AddRef(); } } if (pUnk) pUnk->Release(); } if (pChildContainer) { m_childs.push_back(TAddrFolderPtr(new COLAddrFolder(name.c_str(), m_initRef, pChildContainer))); pChildContainer->Release(); } } g_pMAPIEDK->pFreeProws(pRowSet); } } if (pChildTable) pChildTable->Release(); }
// Manually resolve a name in the address book and add it to the message _Check_return_ HRESULT ManualResolve( _In_ LPMAPISESSION lpMAPISession, _In_ LPMESSAGE lpMessage, _In_z_ LPCTSTR szName, ULONG PropTagToCompare) { HRESULT hRes = S_OK; ULONG ulObjType = 0; LPADRBOOK lpAdrBook = NULL; LPSRowSet lpABRow = NULL; LPMAPITABLE lpABContainerTable = NULL; LPADRLIST lpAdrList = NULL; LPABCONT lpABContainer = NULL; LPMAPITABLE pTable = NULL; LPSPropValue lpFoundRow = NULL; enum { abcPR_ENTRYID, abcPR_DISPLAY_NAME, abcNUM_COLS }; static const SizedSPropTagArray(abcNUM_COLS, abcCols) = { abcNUM_COLS, PR_ENTRYID, PR_DISPLAY_NAME, }; enum { abPR_ENTRYID, abPR_DISPLAY_NAME, abPR_RECIPIENT_TYPE, abPR_ADDRTYPE, abPR_DISPLAY_TYPE, abPropTagToCompare, abNUM_COLS }; if (!lpMAPISession) return MAPI_E_INVALID_PARAMETER; DebugPrint(DBGGeneric, _T("ManualResolve: Asked to resolve \"%s\"\n"), szName); EC_MAPI(lpMAPISession->OpenAddressBook( NULL, NULL, NULL, &lpAdrBook)); EC_H(GetABContainerTable(lpAdrBook, &lpABContainerTable)); if (lpABContainerTable) { // Restrict the table to the properties that we are interested in. EC_MAPI(lpABContainerTable->SetColumns((LPSPropTagArray)&abcCols, TBL_BATCH)); if (!FAILED(hRes)) for (;;) { hRes = S_OK; FreeProws(lpABRow); lpABRow = NULL; EC_MAPI(lpABContainerTable->QueryRows( 1, NULL, &lpABRow)); if (FAILED(hRes) || !lpABRow || (lpABRow && !lpABRow->cRows)) break; // From this point forward, consider any error an error with the current address book container, so just continue and try the next one. if (PR_ENTRYID == lpABRow->aRow->lpProps[abcPR_ENTRYID].ulPropTag) { DebugPrint(DBGGeneric, _T("ManualResolve: Searching this container\n")); DebugPrintBinary(DBGGeneric, &lpABRow->aRow->lpProps[abcPR_ENTRYID].Value.bin); if (lpABContainer) lpABContainer->Release(); lpABContainer = NULL; EC_H(CallOpenEntry( NULL, lpAdrBook, NULL, NULL, lpABRow->aRow->lpProps[abcPR_ENTRYID].Value.bin.cb, (ENTRYID*)lpABRow->aRow->lpProps[abcPR_ENTRYID].Value.bin.lpb, NULL, NULL, &ulObjType, (LPUNKNOWN*)&lpABContainer)); if (!lpABContainer) continue; DebugPrint(DBGGeneric, _T("ManualResolve: Object opened as 0x%X\n"), ulObjType); if (lpABContainer && ulObjType == MAPI_ABCONT) { if (pTable) pTable->Release(); pTable = NULL; WC_MAPI(lpABContainer->GetContentsTable(fMapiUnicode, &pTable)); if (!pTable) { DebugPrint(DBGGeneric, _T("ManualResolve: Container did not support contents table\n")); if (MAPI_E_NO_SUPPORT == hRes) hRes = S_OK; continue; } MAPIFreeBuffer(lpFoundRow); lpFoundRow = NULL; EC_H(SearchContentsTableForName( pTable, szName, PropTagToCompare, &lpFoundRow)); if (!lpFoundRow) continue; if (lpAdrList) FreePadrlist(lpAdrList); lpAdrList = NULL; // Allocate memory for new Address List structure. EC_H(MAPIAllocateBuffer(CbNewADRLIST(1), (LPVOID*)&lpAdrList)); if (!lpAdrList) continue; ZeroMemory(lpAdrList, CbNewADRLIST(1)); lpAdrList->cEntries = 1; // Allocate memory for SPropValue structure that indicates what // recipient properties will be set. To resolve a name that // already exists in the Address book, this will always be 1. EC_H(MAPIAllocateBuffer( (ULONG)(abNUM_COLS * sizeof(SPropValue)), (LPVOID*)&lpAdrList->aEntries->rgPropVals)); if (!lpAdrList->aEntries->rgPropVals) continue; // TODO: We are setting 5 properties below. If this changes, modify these two lines. ZeroMemory(lpAdrList->aEntries->rgPropVals, 5 * sizeof(SPropValue)); lpAdrList->aEntries->cValues = 5; // Fill out addresslist with required property values. LPSPropValue pProps = lpAdrList->aEntries->rgPropVals; LPSPropValue pProp; // Just a pointer, do not free. pProp = &pProps[abPR_ENTRYID]; pProp->ulPropTag = PR_ENTRYID; EC_H(CopySBinary(&pProp->Value.bin, &lpFoundRow[abPR_ENTRYID].Value.bin, lpAdrList)); pProp = &pProps[abPR_RECIPIENT_TYPE]; pProp->ulPropTag = PR_RECIPIENT_TYPE; pProp->Value.l = MAPI_TO; pProp = &pProps[abPR_DISPLAY_NAME]; pProp->ulPropTag = PR_DISPLAY_NAME; if (!CheckStringProp(&lpFoundRow[abPR_DISPLAY_NAME], PT_TSTRING)) continue; EC_H(CopyString( &pProp->Value.LPSZ, lpFoundRow[abPR_DISPLAY_NAME].Value.LPSZ, lpAdrList)); pProp = &pProps[abPR_ADDRTYPE]; pProp->ulPropTag = PR_ADDRTYPE; if (!CheckStringProp(&lpFoundRow[abPR_ADDRTYPE], PT_TSTRING)) continue; EC_H(CopyString( &pProp->Value.LPSZ, lpFoundRow[abPR_ADDRTYPE].Value.LPSZ, lpAdrList)); pProp = &pProps[abPR_DISPLAY_TYPE]; pProp->ulPropTag = PR_DISPLAY_TYPE; pProp->Value.l = lpFoundRow[abPR_DISPLAY_TYPE].Value.l; EC_MAPI(lpMessage->ModifyRecipients( MODRECIP_ADD, lpAdrList)); if (lpAdrList) FreePadrlist(lpAdrList); lpAdrList = NULL; EC_MAPI(lpMessage->SaveChanges(KEEP_OPEN_READWRITE)); // since we're done with our work, let's get out of here. break; } } } lpABContainerTable->Release(); } FreeProws(lpABRow); MAPIFreeBuffer(lpFoundRow); if (lpAdrList) FreePadrlist(lpAdrList); if (pTable) pTable->Release(); if (lpABContainer) lpABContainer->Release(); if (lpAdrBook) lpAdrBook->Release(); return hRes; } // ManualResolve
BOOL ReadWAB(LPADRBOOK pAdrBook, LPWABOBJECT pWABObject, AdrBookTable **ppTable, UINT *pNumEntries) { ULONG ulObjType = 0; LPMAPITABLE lpAB = NULL; LPTSTR * lppszArray=NULL; ULONG cRows = 0; LPSRowSet lpRow = NULL; LPSRowSet lpRowAB = NULL; LPABCONT lpContainer = NULL; int cNumRows = 0; int nRows=0; int nCount = 0; HRESULT hr = E_FAIL; ULONG lpcbEID; LPENTRYID lpEID = NULL; // Get the entryid of the root PAB container // hr = pAdrBook->GetPAB( &lpcbEID, &lpEID); ulObjType = 0; // Open the root PAB container // This is where all the WAB contents reside // hr = pAdrBook->OpenEntry(lpcbEID, (LPENTRYID)lpEID, NULL, 0, &ulObjType, (LPUNKNOWN *)&lpContainer); pWABObject->FreeBuffer(lpEID); lpEID = NULL; if(HR_FAILED(hr)) goto exit; // Get a contents table of all the contents in the // WABs root container // hr = lpContainer->GetContentsTable( 0, &lpAB); if(HR_FAILED(hr)) goto exit; // Order the columns in the ContentsTable to conform to the // ones we want - which are mainly DisplayName, EntryID and // ObjectType // The table is gauranteed to set the columns in the order // requested // hr =lpAB->SetColumns( (LPSPropTagArray)&ptaEid, 0 ); if(HR_FAILED(hr)) goto exit; // Reset to the beginning of the table // hr = lpAB->SeekRow( BOOKMARK_BEGINNING, 0, NULL ); if(HR_FAILED(hr)) goto exit; // Read all the rows of the table one by one // do { hr = lpAB->QueryRows(1, 0, &lpRowAB); if(HR_FAILED(hr)) break; if(lpRowAB) { cNumRows = lpRowAB->cRows; if (cNumRows) { LPTSTR szName = lpRowAB->aRow[0].lpProps[ieidPR_DISPLAY_NAME].Value.lpszA; LPTSTR szEmail = NULL; LPENTRYID lpEID = (LPENTRYID) lpRowAB->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.lpb; ULONG cbEID = lpRowAB->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.cb; LPMAILUSER pMailUser = NULL; ULONG ulObjType = 0; ULONG ulValues; LPSPropValue lpPropArray; *ppTable = (AdrBookTable *) realloc(*ppTable, sizeof(AdrBookTable) * (nCount+1)); (*ppTable)[nCount].szName = (char *) calloc(strlen(szName)+1, 1); strcpy((*ppTable)[nCount].szName, szName); if (lpRowAB->aRow[0].lpProps[ieidPR_OBJECT_TYPE].Value.l == MAPI_MAILUSER) { pAdrBook->OpenEntry(cbEID, lpEID, NULL, // interface 0, // flags &ulObjType, (LPUNKNOWN *)&pMailUser); if(pMailUser) { pMailUser->GetProps((LPSPropTagArray) &ptaEmail, 0, &ulValues, &lpPropArray); pMailUser->Release(); } if ((lpPropArray[iemailPR_EMAIL_ADDRESS].ulPropTag & 0xffff) == PT_ERROR) { szEmail = lpPropArray[iemailPR_DISPLAY_NAME].Value.lpszA; } else szEmail = lpPropArray[iemailPR_EMAIL_ADDRESS].Value.lpszA; if (szEmail != NULL) { (*ppTable)[nCount].szEmail = (char *) calloc(strlen(szEmail)+1, 1); strcpy((*ppTable)[nCount].szEmail, szEmail); } else { (*ppTable)[nCount].szEmail = (char *) calloc(strlen("")+1, 1); strcpy((*ppTable)[nCount].szEmail, ""); } pWABObject->FreeBuffer(lpPropArray); } else (*ppTable)[nCount].szEmail = NULL; nCount++; } FreeProws(pWABObject, lpRowAB); } }while ( SUCCEEDED(hr) && cNumRows && lpRowAB) ; exit: if ( lpContainer ) lpContainer->Release(); if ( lpAB ) lpAB->Release(); *pNumEntries = nCount; if (SUCCEEDED(hr)) return TRUE; else return FALSE; }