HRESULT MailboxDataCollector::CollectData(LPMAPITABLE lpStoreTable) { HRESULT hr = hrSuccess; SRowSetPtr ptrRows; enum {IDX_ENTRYID, IDX_MAILBOX_OWNER_ENTRYID, IDX_STORE_ENTRYIDS, IDX_ITEM_ENTRYIDS, IDX_MAX}; while (true) { hr = lpStoreTable->QueryRows(50, 0, &ptrRows); if (hr != hrSuccess) goto exit; if (ptrRows.size() == 0) break; for (SRowSetPtr::size_type i = 0; i < ptrRows.size(); ++i) { std::pair<ArchiveStateCollector::ArchiveInfoMap::iterator, bool> res; bool bComplete = true; abentryid_t userId; for (unsigned j = 0; bComplete && j < IDX_MAX; ++j) { if (PROP_TYPE(ptrRows[i].lpProps[j].ulPropTag) == PT_ERROR) { m_lpLogger->Log(EC_LOGLEVEL_WARNING, "Got uncomplete row, row %u, column %u contains error 0x%08x", i, j, ptrRows[i].lpProps[j].Value.err); bComplete = false; } } if (!bComplete) continue; if (ptrRows[i].lpProps[IDX_STORE_ENTRYIDS].Value.MVbin.cValues != ptrRows[i].lpProps[IDX_ITEM_ENTRYIDS].Value.MVbin.cValues) { m_lpLogger->Log(EC_LOGLEVEL_DEBUG, "Mismatch in archive prop count, %u vs. %u", ptrRows[i].lpProps[IDX_STORE_ENTRYIDS].Value.MVbin.cValues, ptrRows[i].lpProps[IDX_ITEM_ENTRYIDS].Value.MVbin.cValues); continue; } userId.assign(ptrRows[i].lpProps[IDX_MAILBOX_OWNER_ENTRYID].Value.bin); res = m_mapArchiveInfo.insert(std::make_pair(userId, ArchiveStateCollector::ArchiveInfo())); if (res.second == true) m_lpLogger->Log(EC_LOGLEVEL_DEBUG, "Inserting row for user id %s", userId.tostring().c_str()); else m_lpLogger->Log(EC_LOGLEVEL_DEBUG, "Updating row for user '" TSTRING_PRINTF "'", res.first->second.userName.c_str()); // Assign entryid res.first->second.storeId.assign(ptrRows[i].lpProps[IDX_ENTRYID].Value.bin); // Assign archives m_lpLogger->Log(EC_LOGLEVEL_DEBUG, "Adding %u archive(s)", ptrRows[i].lpProps[IDX_STORE_ENTRYIDS].Value.MVbin.cValues); for (ULONG j = 0; j < ptrRows[i].lpProps[IDX_STORE_ENTRYIDS].Value.MVbin.cValues; ++j) { SObjectEntry objEntry; objEntry.sStoreEntryId.assign(entryid_t(ptrRows[i].lpProps[IDX_STORE_ENTRYIDS].Value.MVbin.lpbin[j])); objEntry.sItemEntryId.assign(entryid_t(ptrRows[i].lpProps[IDX_ITEM_ENTRYIDS].Value.MVbin.lpbin[j])); res.first->second.lstArchives.push_back(objEntry); } } } exit: return hr; }
HRESULT GetCurrentProfileName(IN LPMAPISESSION& lpSession, OUT std::string* szProfileName) { if ( !szProfileName->empty() ) return S_OK; HRESULT hr = GetCurrentMAPISession(lpSession); if ( FAILED(hr) ) return hr; LPMAPITABLE lpStatusTable = NULL; SRestriction sres; SPropValue spvResType; LPSRowSet pRows = NULL; LPTSTR lpszProfileName = NULL; SizedSPropTagArray(2, Columns) = { 2, PR_DISPLAY_NAME, PR_RESOURCE_TYPE }; hr = lpSession->GetStatusTable(NULL, &lpStatusTable); if ( SUCCEEDED(hr) ) hr = lpStatusTable->SetColumns((LPSPropTagArray)&Columns, NULL); if ( SUCCEEDED(hr) ) { spvResType.ulPropTag = PR_RESOURCE_TYPE; spvResType.Value.ul = MAPI_SUBSYSTEM; sres.rt = RES_PROPERTY; sres.res.resProperty.relop = RELOP_EQ; sres.res.resProperty.ulPropTag = PR_RESOURCE_TYPE; sres.res.resProperty.lpProp = &spvResType; if ( SUCCEEDED(hr) ) hr = lpStatusTable->Restrict(&sres, TBL_ASYNC); if ( SUCCEEDED(hr) ) hr = lpStatusTable->FindRow(&sres, BOOKMARK_BEGINNING, 0); if ( SUCCEEDED(hr) ) hr = lpStatusTable->QueryRows(1,0,&pRows); if (SUCCEEDED(hr)) { lpszProfileName = pRows->aRow[0].lpProps[0].Value.lpszA; *szProfileName = lpszProfileName; } } ULRELEASE(lpStatusTable); FREEPROWS(pRows); if ( FAILED(hr) ) PR_TRACE((0, prtIMPORTANT, "GetCurrentProfileName failed")); return hr; }
void PrintReceiveFolderTable(_In_ LPMDB lpMDB) { HRESULT hRes = S_OK; LPMAPITABLE lpReceiveFolderTable = NULL; WC_MAPI(lpMDB->GetReceiveFolderTable(0, &lpReceiveFolderTable)); if (FAILED(hRes)) { printf(_T("<receivefoldertable error=0x%x />\n"), hRes); return; } printf(_T("<receivefoldertable>\n")); if (lpReceiveFolderTable) { LPSPropTagArray sTags = (LPSPropTagArray)&sptRECEIVECols; WC_MAPI(lpReceiveFolderTable->SetColumns(sTags, TBL_ASYNC)); } if (SUCCEEDED(hRes)) { LPSRowSet lpRows = NULL; ULONG iRow = 0; for (;;) { hRes = S_OK; if (lpRows) FreeProws(lpRows); lpRows = NULL; WC_MAPI(lpReceiveFolderTable->QueryRows( 10, NULL, &lpRows)); if (FAILED(hRes) || !lpRows || !lpRows->cRows) break; ULONG i = 0; for (i = 0; i < lpRows->cRows; i++) { printf(_T("<properties index=\"%u\">\n"), iRow); _OutputProperties(DBGNoDebug, stdout, lpRows->aRow[i].cValues, lpRows->aRow[i].lpProps, NULL, false); printf(_T("</properties>\n")); iRow++; } } if (lpRows) FreeProws(lpRows); } printf(_T("</receivefoldertable>\n")); if (lpReceiveFolderTable) { lpReceiveFolderTable->Release(); } } // PrintReceiveFolderTable
BOOL CMapiMessage::IterateAttachTable( void) { LPMAPITABLE lpTable = m_pAttachTable; ULONG rowCount; HRESULT hr = lpTable->GetRowCount( 0, &rowCount); if (!rowCount) { return( TRUE); } hr = lpTable->SetColumns( (LPSPropTagArray)&ptaEid, 0); if (FAILED(hr)) { MAPI_TRACE2( "SetColumns for attachment table failed: 0x%lx, %d\r\n", (long)hr, (int)hr); return( FALSE); } hr = lpTable->SeekRow( BOOKMARK_BEGINNING, 0, NULL); if (FAILED(hr)) { MAPI_TRACE2( "SeekRow for attachment table failed: 0x%lx, %d\r\n", (long)hr, (int)hr); return( FALSE); } int cNumRows = 0; LPSRowSet lpRow; BOOL bResult = TRUE; do { lpRow = NULL; hr = lpTable->QueryRows( 1, 0, &lpRow); if(HR_FAILED(hr)) { MAPI_TRACE2( "QueryRows for attachment table failed: 0x%lx, %d\n", (long)hr, (int)hr); bResult = FALSE; break; } if (lpRow) { cNumRows = lpRow->cRows; if (cNumRows) { DWORD aNum = lpRow->aRow[0].lpProps[ieidPR_ATTACH_NUM].Value.ul; m_attachNums.AppendElement(aNum); MAPI_TRACE1( "\t\t****Attachment found - #%d\r\n", (int)aNum); } CMapiApi::FreeProws( lpRow); } } while ( SUCCEEDED(hr) && cNumRows && lpRow); return( bResult); }
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 CProcessor::ImportWAB() { HINSTANCE hinstLib; HRESULT hRes; LPADRBOOK lpAdrBook; LPWABOBJECT lpWABObject; DWORD Reserved2 = NULL; fWABOpen procWABOpen; { TCHAR szWABDllPath[MAX_PATH]; DWORD dwType = 0; ULONG cbData = sizeof(szWABDllPath); HKEY hKey = NULL; *szWABDllPath = '\0'; // First we look under the default WAB DLL path location in the // Registry. // WAB_DLL_PATH_KEY is defined in wabapi.h // if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, WAB_DLL_PATH_KEY, 0, KEY_READ, &hKey)) RegQueryValueEx( hKey, "", NULL, &dwType, (LPBYTE) szWABDllPath, &cbData); if(hKey) RegCloseKey(hKey); // if the Registry came up blank, we do a loadlibrary on the wab32.dll // WAB_DLL_NAME is defined in wabapi.h // hinstLib = LoadLibrary( (lstrlen(szWABDllPath)) ? szWABDllPath : WAB_DLL_NAME ); } if (hinstLib != NULL) { procWABOpen = (fWABOpen) GetProcAddress(hinstLib, "WABOpen"); if (procWABOpen != NULL) { hRes = (procWABOpen)(&lpAdrBook,&lpWABObject,NULL,Reserved2); // WABOpen _ASSERTE(hRes == S_OK); if (hRes != S_OK) return; ULONG lpcbEntryID; ENTRYID *lpEntryID; hRes = lpAdrBook->GetPAB( &lpcbEntryID, &lpEntryID ); _ASSERTE(hRes == S_OK); if (hRes != S_OK) return; ULONG ulFlags = MAPI_BEST_ACCESS; ULONG ulObjType = NULL; LPUNKNOWN lpUnk = NULL; hRes = lpAdrBook->OpenEntry( lpcbEntryID, lpEntryID, NULL, ulFlags, &ulObjType, &lpUnk ); ulFlags = NULL; //IABTable *lpTable; if (ulObjType == MAPI_ABCONT) { IABContainer *lpContainer = static_cast <IABContainer *>(lpUnk); LPMAPITABLE lpTable = NULL; hRes = lpContainer->GetContentsTable( ulFlags, &lpTable ); _ASSERT(lpTable); ULONG ulRows, ulFound = 0, ulExisted = 0; hRes = lpTable->GetRowCount(0,&ulRows); _ASSERTE(hRes == S_OK); SRowSet *lpRows; hRes = lpTable->SetColumns( (LPSPropTagArray)&ptaEid, 0 ); hRes = lpTable->QueryRows( ulRows, // Get all Rows 0, &lpRows ); for(ULONG i=0;i<lpRows->cRows;i++) { bool bBirthdayProcessed = false; CBirthday* pbd = new CBirthday; SRow *lpRow = &lpRows->aRow[i]; for(ULONG j=0;j<lpRow->cValues;j++) { SPropValue *lpProp = &lpRow->lpProps[j]; if(lpProp->ulPropTag == PR_BIRTHDAY) { SYSTEMTIME st; FileTimeToSystemTime(&lpProp->Value.ft,&st); pbd->m_date = CDate((BYTE)st.wDay, (BYTE)st.wMonth, (UINT)st.wYear); bBirthdayProcessed = true; } if(lpProp->ulPropTag == PR_DISPLAY_NAME_A) { pbd->m_name = lpProp->Value.lpszA; } } if( bBirthdayProcessed && pbd->m_date.ValidDate() ) { ulFound++; if( !WABExists(pbd) ) { pbd->m_medium = MEDIUM_WAB; Add( pbd ); } else { delete pbd; ulExisted++; } } else delete pbd; lpWABObject->FreeBuffer(lpRow); } CString c; c.Format( "Processed %d contacts\r\n\r\nFound %d birthdays of which\r\n%d already existed", ulRows, ulFound, ulExisted ); AfxMessageBox( c, MB_OK|MB_SYSTEMMODAL, 0 ); lpWABObject->FreeBuffer(lpRows); } if(lpAdrBook) lpAdrBook->Release(); if(lpWABObject) lpWABObject->Release(); } // This would be nice but leads to crashing Trillian // FreeLibrary(hinstLib); } }
/** * Checks in the ECStatsTable PR_EC_STATSTABLE_USERS for quota * information per connected server given in lpAdminStore. * * @param[in] cUsers number of users in lpsUserList * @param[in] lpsUserList array of ECUser struct, containing all Zarafa from all companies, on any server * @param[in] lpecCompany same company struct as in ECQuotaMonitor::CheckCompanyQuota() * @param[in] lpAdminStore IMsgStore of SYSTEM user on a specific server instance. * @return hrSuccess or any MAPI error code. */ HRESULT ECQuotaMonitor::CheckServerQuota(ULONG cUsers, LPECUSER lpsUserList, LPECCOMPANY lpecCompany, LPMDB lpAdminStore) { HRESULT hr = hrSuccess; LPSRestriction lpsRestriction = NULL; SPropValue sRestrictProp; LPMAPITABLE lpTable = NULL; LPSRowSet lpRowSet = NULL; ECQUOTASTATUS sQuotaStatus; ULONG i, u; SizedSPropTagArray(5, sCols) = { 5, { PR_EC_USERNAME_A, PR_MESSAGE_SIZE_EXTENDED, PR_QUOTA_WARNING_THRESHOLD, PR_QUOTA_SEND_THRESHOLD, PR_QUOTA_RECEIVE_THRESHOLD, } }; hr = lpAdminStore->OpenProperty(PR_EC_STATSTABLE_USERS, &IID_IMAPITable, 0, 0, (LPUNKNOWN*)&lpTable); if (hr != hrSuccess) { m_lpThreadMonitor->lpLogger->Log(EC_LOGLEVEL_FATAL, "Unable to open stats table for quota sizes, error 0x%08X", hr); goto exit; } hr = lpTable->SetColumns((LPSPropTagArray)&sCols, MAPI_DEFERRED_ERRORS); if (hr != hrSuccess) { m_lpThreadMonitor->lpLogger->Log(EC_LOGLEVEL_FATAL, "Unable to set columns on stats table for quota sizes, error 0x%08X", hr); goto exit; } if (lpecCompany->sCompanyId.cb != 0 && lpecCompany->sCompanyId.lpb != NULL) { sRestrictProp.ulPropTag = PR_EC_COMPANY_NAME_A; sRestrictProp.Value.lpszA = (char*)lpecCompany->lpszCompanyname; CREATE_RESTRICTION(lpsRestriction); CREATE_RES_OR(lpsRestriction, lpsRestriction, 2); CREATE_RES_NOT(lpsRestriction, &lpsRestriction->res.resOr.lpRes[0]); DATA_RES_EXIST(lpsRestriction, lpsRestriction->res.resOr.lpRes[0].res.resNot.lpRes[0], PR_EC_COMPANY_NAME_A); DATA_RES_PROPERTY(lpsRestriction, lpsRestriction->res.resOr.lpRes[1], RELOP_EQ, PR_EC_COMPANY_NAME_A, &sRestrictProp); hr = lpTable->Restrict(lpsRestriction, MAPI_DEFERRED_ERRORS); if (hr != hrSuccess) { m_lpThreadMonitor->lpLogger->Log(EC_LOGLEVEL_FATAL, "Unable to restrict stats table, error 0x%08X", hr); goto exit; } } while (TRUE) { hr = lpTable->QueryRows(50, 0, &lpRowSet); if (hr != hrSuccess) { m_lpThreadMonitor->lpLogger->Log(EC_LOGLEVEL_FATAL, "Unable to receive stats table data, error 0x%08X", hr); goto exit; } if (lpRowSet->cRows == 0) break; for (i = 0; i < lpRowSet->cRows; i++) { LPSPropValue lpUsername = NULL; LPSPropValue lpStoreSize = NULL; LPSPropValue lpQuotaWarn = NULL; LPSPropValue lpQuotaSoft = NULL; LPSPropValue lpQuotaHard = NULL; MsgStorePtr ptrStore; lpUsername = PpropFindProp(lpRowSet->aRow[i].lpProps, lpRowSet->aRow[i].cValues, PR_EC_USERNAME_A); lpStoreSize = PpropFindProp(lpRowSet->aRow[i].lpProps, lpRowSet->aRow[i].cValues, PR_MESSAGE_SIZE_EXTENDED); lpQuotaWarn = PpropFindProp(lpRowSet->aRow[i].lpProps, lpRowSet->aRow[i].cValues, PR_QUOTA_WARNING_THRESHOLD); lpQuotaSoft = PpropFindProp(lpRowSet->aRow[i].lpProps, lpRowSet->aRow[i].cValues, PR_QUOTA_SEND_THRESHOLD); lpQuotaHard = PpropFindProp(lpRowSet->aRow[i].lpProps, lpRowSet->aRow[i].cValues, PR_QUOTA_RECEIVE_THRESHOLD); if (!lpUsername || !lpStoreSize) continue; // don't log error: could be for several valid reasons (contacts, other server, etc) if (lpStoreSize->Value.li.QuadPart == 0) continue; m_ulProcessed++; memset(&sQuotaStatus, 0, sizeof(ECQUOTASTATUS)); sQuotaStatus.llStoreSize = lpStoreSize->Value.li.QuadPart; sQuotaStatus.quotaStatus = QUOTA_OK; if (lpQuotaHard && lpQuotaHard->Value.ul > 0 && lpStoreSize->Value.li.QuadPart > ((long long)lpQuotaHard->Value.ul * 1024)) sQuotaStatus.quotaStatus = QUOTA_HARDLIMIT; else if (lpQuotaSoft && lpQuotaSoft->Value.ul > 0 && lpStoreSize->Value.li.QuadPart > ((long long)lpQuotaSoft->Value.ul * 1024)) sQuotaStatus.quotaStatus = QUOTA_SOFTLIMIT; else if (lpQuotaWarn && lpQuotaWarn->Value.ul > 0 && lpStoreSize->Value.li.QuadPart > ((long long)lpQuotaWarn->Value.ul * 1024)) sQuotaStatus.quotaStatus = QUOTA_WARN; if (sQuotaStatus.quotaStatus == QUOTA_OK) continue; m_lpThreadMonitor->lpLogger->Log(EC_LOGLEVEL_FATAL, "Mailbox of user %s has exceeded its %s limit", lpUsername->Value.lpszA, sQuotaStatus.quotaStatus == QUOTA_WARN ? "warning" : sQuotaStatus.quotaStatus == QUOTA_SOFTLIMIT ? "soft" : "hard"); // find the user in the full users list for (u = 0; u < cUsers; u++) { if (strcmp((char*)lpsUserList[u].lpszUsername, lpUsername->Value.lpszA) == 0) break; } if (u == cUsers) { m_lpThreadMonitor->lpLogger->Log(EC_LOGLEVEL_ERROR, "Unable to find user %s in userlist", lpUsername->Value.lpszA); m_ulFailed++; continue; } hr = OpenUserStore(lpsUserList[u].lpszUsername, &ptrStore); if (hr != hrSuccess) { hr = hrSuccess; continue; } hr = Notify(&lpsUserList[u], lpecCompany, &sQuotaStatus, ptrStore); if (hr != hrSuccess) m_ulFailed++; } if (lpRowSet) FreeProws(lpRowSet); lpRowSet = NULL; } exit: if (lpRowSet) FreeProws(lpRowSet); if (lpsRestriction) MAPIFreeBuffer(lpsRestriction); if (lpTable) lpTable->Release(); return hr; }
nsresult nsOEAddressIterator::EnumList(const char16_t * pName, LPENTRYID pEid, ULONG cbEid, LPMAPITABLE lpTable) { // If no name provided then we're done. if (!pName || !(*pName)) return NS_OK; nsresult rv = NS_ERROR_FAILURE; HRESULT hr = E_FAIL; // Make sure we have db to work with. if (!m_database) return rv; nsCOMPtr <nsIMdbRow> listRow; rv = m_database->GetNewListRow(getter_AddRefs(listRow)); NS_ENSURE_SUCCESS(rv, rv); rv = m_database->AddListName(listRow, NS_ConvertUTF16toUTF8(pName).get()); NS_ENSURE_SUCCESS(rv, rv); rv = m_database->AddCardRowToDB(listRow); NS_ENSURE_SUCCESS(rv, rv); rv = m_database->AddListDirNode(listRow); NS_ENSURE_SUCCESS(rv, rv); LPSRowSet lpRowAB = NULL; ULONG lpcbEID = 0; LPENTRYID lpEID = NULL; ULONG rowCount = 0; int cNumRows = 0; int numListElems = 0; nsAutoString uniStr; hr = lpTable->GetRowCount(0, &rowCount); // hr = lpTable->SeekRow(BOOKMARK_BEGINNING, 0, NULL); if(HR_FAILED(hr)) return NS_ERROR_FAILURE; // Read all the rows of the table one by one do { hr = lpTable->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 distribution lists, we will only consider MAILUSER // objects since we can't nest lists yet. if(lpRowAB->aRow[0].lpProps[ieidPR_OBJECT_TYPE].Value.l == MAPI_MAILUSER) { LPMAILUSER pUser = m_pWab->GetUser(cbEID, lpEID); LPSPropValue pProp = m_pWab->GetUserProperty(pUser, PR_EMAIL_ADDRESS); nsString eMail; nsCOMPtr <nsIMdbRow> cardRow; m_pWab->GetValueString(pProp, eMail); SanitizeValue(eMail); FindListRow(eMail, getter_AddRefs(cardRow)); if (cardRow) { nsCOMPtr <nsIAbCard> userCard; nsCOMPtr <nsIAbCard> newCard; userCard = do_CreateInstance(NS_ABMDBCARD_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); m_database->InitCardFromRow(userCard,cardRow); m_database->AddListCardColumnsToRow(userCard, listRow, ++numListElems, getter_AddRefs(newCard), true, nullptr, nullptr); } m_pWab->FreeProperty(pProp); m_pWab->ReleaseUser(pUser); } } m_pWab->FreeProws(lpRowAB); } } while (SUCCEEDED(hr) && cNumRows && lpRowAB); m_database->SetListAddressTotal(listRow, numListElems); return rv; }
BOOL CMapiApi::IterateStores( CMapiFolderList& stores) { stores.ClearAll(); if (!m_lpSession) { MAPI_TRACE0( "IterateStores called before session is open\n"); m_lastError = -1; return( FALSE); } HRESULT hr; /* -- Some Microsoft sample code just to see if things are working --- *//* ULONG cbEIDStore; LPENTRYID lpEIDStore; hr = HrMAPIFindDefaultMsgStore( m_lpSession, &cbEIDStore, &lpEIDStore); if (HR_FAILED(hr)) { MAPI_TRACE0( "Default message store not found\n"); // MessageBox(NULL,"Message Store Not Found",NULL,MB_OK); } else { LPMDB lpStore; MAPI_TRACE0( "Default Message store FOUND\n"); hr = m_lpSession->OpenMsgStore( NULL, cbEIDStore, lpEIDStore, NULL, MDB_NO_MAIL | MDB_NO_DIALOG, &lpStore); if (HR_FAILED(hr)) { MAPI_TRACE1( "Unable to open default message store: 0x%lx\n", hr); } else { MAPI_TRACE0( "Default message store OPENED\n"); lpStore->Release(); } } */ LPMAPITABLE lpTable; hr = m_lpSession->GetMsgStoresTable( 0, &lpTable); if (FAILED(hr)) { MAPI_TRACE0( "GetMsgStoresTable failed\n"); m_lastError = hr; return( FALSE); } ULONG rowCount; hr = lpTable->GetRowCount( 0, &rowCount); MAPI_TRACE1( "MsgStores Table rowCount: %ld\n", rowCount); hr = lpTable->SetColumns( (LPSPropTagArray)&ptaTbl, 0); if (FAILED(hr)) { lpTable->Release(); MAPI_TRACE2( "SetColumns failed: 0x%lx, %d\n", (long)hr, (int)hr); m_lastError = hr; return( FALSE); } hr = lpTable->SeekRow( BOOKMARK_BEGINNING, 0, NULL); if (FAILED(hr)) { lpTable->Release(); MAPI_TRACE2( "SeekRow failed: 0x%lx, %d\n", (long)hr, (int)hr); m_lastError = hr; return( FALSE); } int cNumRows = 0; LPSRowSet lpRow; BOOL keepGoing = TRUE; BOOL bResult = TRUE; do { lpRow = NULL; hr = lpTable->QueryRows( 1, 0, &lpRow); if(HR_FAILED(hr)) { MAPI_TRACE2( "QueryRows failed: 0x%lx, %d\n", (long)hr, (int)hr); bResult = FALSE; m_lastError = hr; break; } if(lpRow) { cNumRows = lpRow->cRows; if (cNumRows) { LPCTSTR lpStr = (LPCTSTR) lpRow->aRow[0].lpProps[itblPR_DISPLAY_NAME].Value.LPSZ; LPENTRYID lpEID = (LPENTRYID) lpRow->aRow[0].lpProps[itblPR_ENTRYID].Value.bin.lpb; ULONG cbEID = lpRow->aRow[0].lpProps[itblPR_ENTRYID].Value.bin.cb; // In the future, GetStoreInfo needs to somehow return // whether or not the store is from an IMAP server. // Currently, GetStoreInfo opens the store and attempts // to get the hierarchy tree. If the tree is empty or // does not exist, then szContents will be zero. We'll // assume that any store that doesn't have anything in // it's hierarchy tree is not a store we want to import - // there would be nothing to import from anyway! // Currently, this does exclude IMAP server accounts // which is the desired behaviour. int strLen = strlen(lpStr); PRUnichar * pwszStr = (PRUnichar *) nsMemory::Alloc((strLen + 1) * sizeof(WCHAR)); if (!pwszStr) { // out of memory FreeProws( lpRow); lpTable->Release(); return FALSE; } ::MultiByteToWideChar(CP_ACP, 0, lpStr, strlen(lpStr) + 1, pwszStr, (strLen + 1) * sizeof(WCHAR)); CMapiFolder *pFolder = new CMapiFolder( pwszStr, cbEID, lpEID, 0, MAPI_STORE); nsMemory::Free(pwszStr); long szContents = 1; GetStoreInfo( pFolder, &szContents); MAPI_TRACE1( " DisplayName: %s\n", lpStr); if (szContents) { stores.AddItem( pFolder); } else { delete pFolder; MAPI_TRACE0( " ^^^^^ Not added to store list\n"); } keepGoing = TRUE; } FreeProws( lpRow); } } while ( SUCCEEDED(hr) && cNumRows && lpRow && keepGoing); lpTable->Release(); return( bResult); }
BOOL CMapiApi::IterateContents( CMapiContentIter *pIter, LPMAPIFOLDER pFolder, ULONG flags) { // flags can be 0 or MAPI_ASSOCIATED // MAPI_ASSOCIATED is usually used for forms and views HRESULT hr; LPMAPITABLE lpTable; hr = pFolder->GetContentsTable( flags, &lpTable); if (FAILED(hr)) { MAPI_TRACE2( "GetContentsTable failed: 0x%lx, %d\n", (long)hr, (int)hr); return( FALSE); } ULONG rowCount; hr = lpTable->GetRowCount( 0, &rowCount); if (!rowCount) { MAPI_TRACE0( " Empty Table\n"); } hr = lpTable->SetColumns( (LPSPropTagArray)&ptaEid, 0); if (FAILED(hr)) { lpTable->Release(); MAPI_TRACE2( "SetColumns failed: 0x%lx, %d\n", (long)hr, (int)hr); return( FALSE); } hr = lpTable->SeekRow( BOOKMARK_BEGINNING, 0, NULL); if (FAILED(hr)) { lpTable->Release(); MAPI_TRACE2( "SeekRow failed: 0x%lx, %d\n", (long)hr, (int)hr); return( FALSE); } int cNumRows = 0; LPSRowSet lpRow; BOOL keepGoing = TRUE; BOOL bResult = TRUE; do { lpRow = NULL; hr = lpTable->QueryRows( 1, 0, &lpRow); if(HR_FAILED(hr)) { MAPI_TRACE2( "QueryRows failed: 0x%lx, %d\n", (long)hr, (int)hr); bResult = FALSE; break; } if(lpRow) { cNumRows = lpRow->cRows; if (cNumRows) { LPENTRYID lpEID = (LPENTRYID) lpRow->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.lpb; ULONG cbEID = lpRow->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.cb; ULONG oType = lpRow->aRow[0].lpProps[ieidPR_OBJECT_TYPE].Value.ul; keepGoing = HandleContentsItem( oType, cbEID, lpEID); MAPI_TRACE1( " ObjectType: %ld\n", oType); } FreeProws( lpRow); } } while ( SUCCEEDED(hr) && cNumRows && lpRow && keepGoing); lpTable->Release(); return( bResult); }
/** * Remove a favorite in the private store. also the sub favorites will be deleted * * @param lpShortcutFolder The shortcut folder in the private store. * @param lpPropSourceKey Pointer to the sourcekey of a favorite folder */ HRESULT DelFavoriteFolder(IMAPIFolder *lpShortcutFolder, LPSPropValue lpPropSourceKey) { HRESULT hr = hrSuccess; LPMAPITABLE lpTable = NULL; LPSRestriction lpRestriction = NULL; SRowSet *lpRows = NULL; LPENTRYLIST lpsMsgList = NULL; SizedSPropTagArray(2, sPropDelFavo) = {2, { PR_ENTRYID, PR_FAV_PUBLIC_SOURCE_KEY }}; std::list<string> listSourceKey; std::list<string>::iterator ilistSourceKey; string strSourceKey; SPropValue sPropSourceKey; ULONG ulMaxRows = 0; if (lpShortcutFolder == NULL || lpPropSourceKey == NULL) { hr = MAPI_E_INVALID_PARAMETER; goto exit; } hr = lpShortcutFolder->GetContentsTable(0, &lpTable); if (hr != hrSuccess) goto exit; hr = lpTable->GetRowCount(0, &ulMaxRows); if (hr != hrSuccess) goto exit; hr = lpTable->SetColumns((LPSPropTagArray)&sPropDelFavo, 0); if (hr != hrSuccess) goto exit; // build restriction CREATE_RESTRICTION(lpRestriction); CREATE_RES_AND(lpRestriction, lpRestriction, 1); DATA_RES_PROPERTY(lpRestriction, lpRestriction->res.resAnd.lpRes[0], RELOP_EQ, PR_FAV_PUBLIC_SOURCE_KEY, lpPropSourceKey); if (lpTable->FindRow(lpRestriction, BOOKMARK_BEGINNING , 0) != hrSuccess) goto exit; // Folder already removed hr = lpTable->QueryRows (1, 0, &lpRows); if (hr != hrSuccess) goto exit; if (lpRows->cRows == 0) goto exit; // Folder already removed hr = MAPIAllocateBuffer(sizeof(ENTRYLIST), (void**)&lpsMsgList); if (hr != hrSuccess) goto exit; hr = MAPIAllocateMore(sizeof(SBinary)*ulMaxRows, lpsMsgList, (void**)&lpsMsgList->lpbin); if (hr != hrSuccess) goto exit; //FIXME: check the properties in the row!!!! lpsMsgList->cValues = 0; // add entryid lpsMsgList->lpbin[lpsMsgList->cValues].cb = lpRows->aRow[0].lpProps[0].Value.bin.cb; MAPIAllocateMore(lpsMsgList->lpbin[lpsMsgList->cValues].cb, lpsMsgList, (void **) &lpsMsgList->lpbin[lpsMsgList->cValues].lpb); memcpy(lpsMsgList->lpbin[lpsMsgList->cValues].lpb, lpRows->aRow[0].lpProps[0].Value.bin.lpb, lpsMsgList->lpbin[lpsMsgList->cValues].cb); lpsMsgList->cValues++; strSourceKey.assign((char*)lpRows->aRow[0].lpProps[1].Value.bin.lpb, lpRows->aRow[0].lpProps[1].Value.bin.cb); listSourceKey.push_back(strSourceKey); if (lpRows){ FreeProws(lpRows); lpRows = NULL; } FREE_RESTRICTION(lpRestriction); for(ilistSourceKey = listSourceKey.begin(); ilistSourceKey != listSourceKey.end(); ilistSourceKey++) { sPropSourceKey.ulPropTag = PR_FAV_PUBLIC_SOURCE_KEY; sPropSourceKey.Value.bin.cb = ilistSourceKey->size(); sPropSourceKey.Value.bin.lpb = (LPBYTE)ilistSourceKey->c_str(); CREATE_RESTRICTION(lpRestriction); CREATE_RES_AND(lpRestriction, lpRestriction, 1); DATA_RES_PROPERTY(lpRestriction, lpRestriction->res.resAnd.lpRes[0], RELOP_EQ, PR_FAV_PARENT_SOURCE_KEY, &sPropSourceKey); hr = lpTable->Restrict(lpRestriction, TBL_BATCH ); if (hr != hrSuccess) goto exit; hr = lpTable->SeekRow(BOOKMARK_BEGINNING, 0, NULL); if (hr != hrSuccess) goto exit; while(true) { hr = lpTable->QueryRows (1, 0, &lpRows); if (hr != hrSuccess) goto exit; if (lpRows->cRows == 0) break; // no rows //FIXME: check the properties in the row!!!! // add entryid lpsMsgList->lpbin[lpsMsgList->cValues].cb = lpRows->aRow[0].lpProps[0].Value.bin.cb; MAPIAllocateMore(lpsMsgList->lpbin[lpsMsgList->cValues].cb, lpsMsgList, (void **) &lpsMsgList->lpbin[lpsMsgList->cValues].lpb); memcpy(lpsMsgList->lpbin[lpsMsgList->cValues].lpb, lpRows->aRow[0].lpProps[0].Value.bin.lpb, lpsMsgList->lpbin[lpsMsgList->cValues].cb); lpsMsgList->cValues++; // Add sourcekey into the list strSourceKey.assign((char*)lpRows->aRow[0].lpProps[1].Value.bin.lpb, lpRows->aRow[0].lpProps[1].Value.bin.cb); listSourceKey.push_back(strSourceKey); } //while(true) FREE_RESTRICTION(lpRestriction); if (lpRows){ FreeProws(lpRows); lpRows = NULL; } } hr = lpShortcutFolder->DeleteMessages(lpsMsgList, 0, NULL, 0); if (hr != hrSuccess) goto exit; exit: FREE_RESTRICTION(lpRestriction); if (lpTable) lpTable->Release(); if (lpRows) FreeProws(lpRows); if (lpsMsgList) MAPIFreeBuffer(lpsMsgList); return hr; }
// 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
ULONGLONG ComputeFolderSize( _In_z_ LPWSTR lpszProfile, _In_ LPMAPIFOLDER lpFolder, _In_ ULONG ulFolder, _In_z_ LPWSTR lpszFolder) { DebugPrint(DBGGeneric,"ComputeFolderSize: Calculating size (including subfolders) for folder %u / %ws from profile %ws \n", ulFolder, lpszFolder?lpszFolder:L"", lpszProfile); // printf("ComputeFolderSize: Calculating size (including subfolders) for folder %i / %ws from profile %ws \n", ulFolder, lpszFolder?lpszFolder:L"", lpszProfile); HRESULT hRes = S_OK; if (lpFolder) { LPMAPITABLE lpTable = NULL; LPSRowSet lpRow = NULL; ULONG i = 0; ULONGLONG ullSize = 0; enum { ePR_DISPLAY_NAME_W, ePR_ENTRYID, ePR_FOLDER_TYPE, NUM_COLS }; static const SizedSPropTagArray(NUM_COLS, rgColProps) = { NUM_COLS, PR_DISPLAY_NAME_W, PR_ENTRYID, PR_FOLDER_TYPE, }; // Size of this folder ullSize += ComputeSingleFolderSize(lpFolder); // Size of children WC_MAPI(lpFolder->GetHierarchyTable(MAPI_DEFERRED_ERRORS, &lpTable)); if (SUCCEEDED(hRes) && lpTable) { WC_MAPI(lpTable->SetColumns((LPSPropTagArray)&rgColProps, TBL_ASYNC)); if (!FAILED(hRes)) for (;;) { hRes = S_OK; if (lpRow) FreeProws(lpRow); lpRow = NULL; WC_MAPI(lpTable->QueryRows( 50, NULL, &lpRow)); if (FAILED(hRes) || !lpRow || !lpRow->cRows) break; for (i = 0; i < lpRow->cRows; i++) { hRes = S_OK; // Don't look at search folders if (PR_FOLDER_TYPE == lpRow->aRow[i].lpProps[ePR_FOLDER_TYPE].ulPropTag && FOLDER_SEARCH == lpRow->aRow[i].lpProps[ePR_FOLDER_TYPE].Value.ul) { continue; } if (PR_ENTRYID == lpRow->aRow[i].lpProps[ePR_ENTRYID].ulPropTag) { ULONG ulObjType = NULL; LPMAPIFOLDER lpSubfolder = NULL; WC_MAPI(lpFolder->OpenEntry(lpRow->aRow[i].lpProps[ePR_ENTRYID].Value.bin.cb, (LPENTRYID)lpRow->aRow[i].lpProps[ePR_ENTRYID].Value.bin.lpb, NULL, MAPI_BEST_ACCESS, &ulObjType, (LPUNKNOWN *) &lpSubfolder)); if (SUCCEEDED(hRes) && lpSubfolder) { LPWSTR szDisplayName = L""; if (PR_DISPLAY_NAME_W == lpRow->aRow[i].lpProps[ePR_DISPLAY_NAME_W].ulPropTag) { szDisplayName = lpRow->aRow[i].lpProps[ePR_DISPLAY_NAME_W].Value.lpszW; } ullSize += ComputeFolderSize(lpszProfile, lpSubfolder, 0, szDisplayName); } if (lpSubfolder) lpSubfolder->Release(); } } } if (lpRow) FreeProws(lpRow); } if (lpTable) lpTable->Release(); return ullSize; } return 0; } // ComputeFolderSize
void DumpHierarchyTable( _In_z_ LPWSTR lpszProfile, _In_ LPMAPIFOLDER lpFolder, _In_ ULONG ulFolder, _In_z_ LPWSTR lpszFolder, _In_ ULONG ulDepth) { if (0 == ulDepth) { DebugPrint(DBGGeneric,"DumpHierarchyTable: Outputting hierarchy table for folder %u / %ws from profile %ws \n", ulFolder, lpszFolder?lpszFolder:L"", lpszProfile); } HRESULT hRes = S_OK; if (lpFolder) { LPMAPITABLE lpTable = NULL; LPSRowSet lpRow = NULL; ULONG i = 0; enum { ePR_DISPLAY_NAME_W, ePR_ENTRYID, NUM_COLS }; static const SizedSPropTagArray(NUM_COLS, rgColProps) = { NUM_COLS, PR_DISPLAY_NAME_W, PR_ENTRYID, }; WC_MAPI(lpFolder->GetHierarchyTable(MAPI_DEFERRED_ERRORS, &lpTable)); if (SUCCEEDED(hRes) && lpTable) { WC_MAPI(lpTable->SetColumns((LPSPropTagArray)&rgColProps, TBL_ASYNC)); if (!FAILED(hRes)) for (;;) { hRes = S_OK; if (lpRow) FreeProws(lpRow); lpRow = NULL; WC_MAPI(lpTable->QueryRows( 50, NULL, &lpRow)); if (FAILED(hRes) || !lpRow || !lpRow->cRows) break; for (i = 0; i < lpRow->cRows; i++) { hRes = S_OK; if (ulDepth >= 1) { ULONG iTab = 0; for (iTab = 0; iTab < ulDepth; iTab++) { printf(" "); } } if (PR_DISPLAY_NAME_W == lpRow->aRow[i].lpProps[ePR_DISPLAY_NAME_W].ulPropTag) { printf("%ws\n",lpRow->aRow[i].lpProps[ePR_DISPLAY_NAME_W].Value.lpszW); } if (PR_ENTRYID == lpRow->aRow[i].lpProps[ePR_ENTRYID].ulPropTag) { ULONG ulObjType = NULL; LPMAPIFOLDER lpSubfolder = NULL; WC_MAPI(lpFolder->OpenEntry(lpRow->aRow[i].lpProps[ePR_ENTRYID].Value.bin.cb, (LPENTRYID)lpRow->aRow[i].lpProps[ePR_ENTRYID].Value.bin.lpb, NULL, MAPI_BEST_ACCESS, &ulObjType, (LPUNKNOWN *) &lpSubfolder)); if (SUCCEEDED(hRes) && lpSubfolder) { DumpHierarchyTable(lpszProfile, lpSubfolder, 0, L"", ulDepth + 1); } if (lpSubfolder) lpSubfolder->Release(); } } } if (lpRow) FreeProws(lpRow); } if (lpTable) lpTable->Release(); } } // DumpHierarchyTable
HRESULT RunStoreValidation(char* strHost, char* strUser, char* strPass, char *strAltUser, bool bPublic, CHECKMAP checkmap) { HRESULT hr = hrSuccess; LPMAPISESSION lpSession = NULL; LPMDB lpStore = NULL; LPMDB lpAltStore = NULL; LPMDB lpReadStore = NULL; LPMAPIFOLDER lpRootFolder = NULL; LPMAPITABLE lpHierarchyTable = NULL; LPSRowSet lpRows = NULL; ULONG ulObjectType; ULONG ulCount; LPEXCHANGEMANAGESTORE lpIEMS = NULL; // user ULONG cbUserStoreEntryID = 0; LPENTRYID lpUserStoreEntryID = NULL; wstring strwUsername; wstring strwAltUsername; wstring strwPassword; std::set<std::string> setFolderIgnore; LPSPropValue lpAddRenProp = NULL; ULONG cbEntryIDSrc = 0; LPENTRYID lpEntryIDSrc = NULL; ECLogger *const lpLogger = new ECLogger_File(EC_LOGLEVEL_FATAL, 0, "-"); hr = MAPIInitialize(NULL); if (hr != hrSuccess) { cout << "Unable to initialize session" << endl; goto exit; } // input from commandline is current locale if (strUser) strwUsername = convert_to<wstring>(strUser); if (strPass) strwPassword = convert_to<wstring>(strPass); if (strAltUser) strwAltUsername = convert_to<wstring>(strAltUser); hr = HrOpenECSession(lpLogger, &lpSession, "zarafa-fsck", PROJECT_SVN_REV_STR, strwUsername.c_str(), strwPassword.c_str(), (const char *)strHost, 0, NULL, NULL); lpLogger->Release(); if(hr != hrSuccess) { cout << "Wrong username or password." << endl; goto exit; } if (bPublic) { hr = HrOpenECPublicStore(lpSession, &lpStore); if (hr != hrSuccess) { cout << "Failed to open public store." << endl; goto exit; } } else { hr = HrOpenDefaultStore(lpSession, &lpStore); if (hr != hrSuccess) { cout << "Failed to open default store." << endl; goto exit; } } if (!strwAltUsername.empty()) { hr = lpStore->QueryInterface(IID_IExchangeManageStore, (void **)&lpIEMS); if (hr != hrSuccess) { cout << "Cannot open ExchangeManageStore object" << endl; goto exit; } hr = lpIEMS->CreateStoreEntryID(L"", (LPTSTR)strwAltUsername.c_str(), MAPI_UNICODE | OPENSTORE_HOME_LOGON, &cbUserStoreEntryID, &lpUserStoreEntryID); if (hr != hrSuccess) { cout << "Cannot get user store id for user" << endl; goto exit; } hr = lpSession->OpenMsgStore(0, cbUserStoreEntryID, lpUserStoreEntryID, NULL, MDB_WRITE | MDB_NO_DIALOG | MDB_NO_MAIL | MDB_TEMPORARY, &lpAltStore); if (hr != hrSuccess) { cout << "Cannot open user store of user" << endl; goto exit; } lpReadStore = lpAltStore; } else { lpReadStore = lpStore; } hr = lpReadStore->OpenEntry(0, NULL, &IID_IMAPIFolder, 0, &ulObjectType, (IUnknown **)&lpRootFolder); if(hr != hrSuccess) { cout << "Failed to open root folder." << endl; goto exit; } if (HrGetOneProp(lpRootFolder, PR_IPM_OL2007_ENTRYIDS /*PR_ADDITIONAL_REN_ENTRYIDS_EX*/, &lpAddRenProp) == hrSuccess && Util::ExtractSuggestedContactsEntryID(lpAddRenProp, &cbEntryIDSrc, &lpEntryIDSrc) == hrSuccess) { setFolderIgnore.insert(string((const char*)lpEntryIDSrc, cbEntryIDSrc)); } hr = lpRootFolder->GetHierarchyTable(CONVENIENT_DEPTH, &lpHierarchyTable); if (hr != hrSuccess) { cout << "Failed to open hierarchy." << endl; goto exit; } /* * Check if we have found at least *something*. */ hr = lpHierarchyTable->GetRowCount(0, &ulCount); if(hr != hrSuccess) { cout << "Failed to count number of rows." << endl; goto exit; } else if (!ulCount) { cout << "No entries inside Calendar." << endl; goto exit; } /* * Loop through each row/entry and validate. */ while (true) { hr = lpHierarchyTable->QueryRows(20, 0, &lpRows); if (hr != hrSuccess) break; if (lpRows->cRows == 0) break; for (ULONG i = 0; i < lpRows->cRows; i++) RunFolderValidation(setFolderIgnore, lpRootFolder, &lpRows->aRow[i], checkmap); if (lpRows) { FreeProws(lpRows); lpRows = NULL; } } exit: if (lpUserStoreEntryID) MAPIFreeBuffer(lpUserStoreEntryID); if (lpIEMS) lpIEMS->Release(); if (lpRows) { FreeProws(lpRows); lpRows = NULL; } if (lpEntryIDSrc) MAPIFreeBuffer(lpEntryIDSrc); if (lpAddRenProp) MAPIFreeBuffer(lpAddRenProp); if(lpHierarchyTable) lpHierarchyTable->Release(); if (lpRootFolder) lpRootFolder->Release(); if (lpAltStore) lpAltStore->Release(); if (lpStore) lpStore->Release(); if (lpSession) lpSession->Release(); MAPIUninitialize(); return hr; }
BOOL CExMapi::OpenNextMessageStore(LPMAPITABLE lpMsgStoreTable, ULONG ulFlags) { if(!m_pSession) return FALSE; if(!lpMsgStoreTable) return FALSE; BOOL doLog = m_pCtrl->IsEnableLog(); if(doLog) { m_logHelper.LogPAB(L"Function OpenNextMessageStore START."); } m_ulMDBFlags = ulFlags; LPSRowSet pRows = NULL; const int nProperties = 1; SizedSPropTagArray(nProperties,Columns)={nProperties,{PR_ENTRYID}}; BOOL bResult = FALSE; try { if(lpMsgStoreTable->SetColumns((LPSPropTagArray)&Columns, 0) == S_OK) { while(TRUE) { bResult = FALSE; if(lpMsgStoreTable->QueryRows(1,0,&pRows) != S_OK) MAPIFreeBuffer(pRows); else if(pRows->cRows!=1) FreeProws(pRows); else { LPMDB pMsgStore = NULL; ULONG cbEntryId = pRows->aRow[0].lpProps[0].Value.bin.cb; LPENTRYID lpEntryId = (ENTRYID*)pRows->aRow[0].lpProps[0].Value.bin.lpb; bResult = (m_pSession->OpenMsgStore(NULL, cbEntryId, lpEntryId, NULL, MDB_NO_DIALOG | MAPI_BEST_ACCESS, &pMsgStore) == S_OK); if(bResult) { if(m_pMsgStore) { //check if new open msg store is the same as opened msg store. if(AreSame(m_pMsgStore,pMsgStore)) { if(doLog) { m_logHelper.LogPAB(L"Message Store is already opend."); } RELEASE(pMsgStore); FreeProws(pRows); continue; } else { RELEASE(m_pMsgStore); m_pMsgStore = pMsgStore; bResult = TRUE; } } else { m_pMsgStore = pMsgStore; } } FreeProws(pRows); } break; } } } catch(_com_error& e) { if(doLog) { m_logHelper.LogPAB(L"OpenNextMessageStore Exception:"); m_logHelper.LogPAB(e.ErrorMessage()); } return FALSE; } if(doLog) { m_logHelper.LogPAB(L"Function OpenNextMessageStore END."); } return bResult; }
/** * Add new folders to the favorites folder * * @param lpSession Pointer to the current mapi session * @param lpFolder Pointer to a folder in the public store, except a folder from the favorites folder * @param lpAliasName Pointer to a string containing another name for the folder * @param ulFlags Bitmask of flags that controls how the folder is added. The following flags can be set: * FAVO_FOLDER_LEVEL_BASE * Add only the folder itself * FAVO_FOLDER_LEVEL_ONE * Add the folder and the immediate subfolders only * FAVO_FOLDER_LEVEL_SUB * Add the folder and all subfolders * MAPI_UNICODE * lpAliasName parameter is in wide or multibyte format */ HRESULT AddFavoriteFolder(LPMAPIFOLDER lpShortcutFolder, LPMAPIFOLDER lpFolder, LPCTSTR lpAliasName, ULONG ulFlags) { HRESULT hr = hrSuccess; LPMAPITABLE lpTable = NULL; LPSPropValue lpsPropArray = NULL; LPSPropValue lpPropDepth = NULL; // No free needed SRowSet *lpRows = NULL; ULONG ulFolderFlags = 0; ULONG cValues = 0; SizedSPropTagArray(5, sPropsFolderInfo) = {5, { PR_DEPTH, PR_SOURCE_KEY, PR_PARENT_SOURCE_KEY, PR_DISPLAY_NAME, PR_CONTAINER_CLASS}}; // FIXME: check vaiables // Add folders to the shorcut folder hr = lpFolder->GetProps((LPSPropTagArray)&sPropsFolderInfo, 0, &cValues, &lpsPropArray); if (FAILED(hr) != hrSuccess) //Gives always a warning goto exit; hr = AddToFavorite(lpShortcutFolder, 1, lpAliasName, ulFlags, cValues, lpsPropArray); if (hr != hrSuccess) goto exit; if (lpsPropArray) { MAPIFreeBuffer(lpsPropArray); lpsPropArray = NULL; } if (ulFlags == FAVO_FOLDER_LEVEL_SUB) { ulFolderFlags = CONVENIENT_DEPTH; } else if(ulFlags == FAVO_FOLDER_LEVEL_ONE) { ulFolderFlags = 0; }else { hr = hrSuccess; // Done goto exit; } // Get subfolders hr = lpFolder->GetHierarchyTable(ulFolderFlags, &lpTable); if (hr != hrSuccess) goto exit; hr = lpTable->SetColumns((LPSPropTagArray)&sPropsFolderInfo, 0); if (hr != hrSuccess) goto exit; // Add the favorite recusive depended what the flags are while(true) { hr = lpTable->QueryRows (1, 0, &lpRows); if (hr != hrSuccess) goto exit; if (lpRows->cRows == 0) break; lpPropDepth = PpropFindProp(lpRows->aRow[0].lpProps,lpRows->aRow[0].cValues, PR_DEPTH); if (lpPropDepth == NULL) { hr = MAPI_E_CORRUPT_DATA;// Break the action goto exit; } hr = AddToFavorite(lpShortcutFolder, lpPropDepth->Value.ul + 1, NULL, 0, lpRows->aRow[0].cValues, lpRows->aRow[0].lpProps); if (hr != hrSuccess) { // Break the action goto exit; } FreeProws(lpRows); lpRows = NULL; } //while(true) exit: if (lpTable) lpTable->Release(); if (lpRows) FreeProws(lpRows); if (lpsPropArray) MAPIFreeBuffer(lpsPropArray); return hr; }
BOOL CMapiApi::IterateHierarchy( CMapiHierarchyIter *pIter, LPMAPIFOLDER pFolder, ULONG flags) { // flags can be CONVENIENT_DEPTH or 0 // CONVENIENT_DEPTH will return all depths I believe instead // of just children HRESULT hr; LPMAPITABLE lpTable; hr = pFolder->GetHierarchyTable( flags, &lpTable); if (HR_FAILED(hr)) { m_lastError = hr; MAPI_TRACE2( "IterateHierarchy: GetContentsTable failed: 0x%lx, %d\n", (long)hr, (int)hr); return( FALSE); } ULONG rowCount; hr = lpTable->GetRowCount( 0, &rowCount); if (!rowCount) { lpTable->Release(); return( TRUE); } hr = lpTable->SetColumns( (LPSPropTagArray)&ptaEid, 0); if (HR_FAILED(hr)) { m_lastError = hr; lpTable->Release(); MAPI_TRACE2( "IterateHierarchy: SetColumns failed: 0x%lx, %d\n", (long)hr, (int)hr); return( FALSE); } hr = lpTable->SeekRow( BOOKMARK_BEGINNING, 0, NULL); if (HR_FAILED(hr)) { m_lastError = hr; lpTable->Release(); MAPI_TRACE2( "IterateHierarchy: SeekRow failed: 0x%lx, %d\n", (long)hr, (int)hr); return( FALSE); } int cNumRows = 0; LPSRowSet lpRow; BOOL keepGoing = TRUE; BOOL bResult = TRUE; do { lpRow = NULL; hr = lpTable->QueryRows( 1, 0, &lpRow); if(HR_FAILED(hr)) { MAPI_TRACE2( "QueryRows failed: 0x%lx, %d\n", (long)hr, (int)hr); m_lastError = hr; bResult = FALSE; break; } if(lpRow) { cNumRows = lpRow->cRows; if (cNumRows) { LPENTRYID lpEntry = (LPENTRYID) lpRow->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.lpb; ULONG cb = lpRow->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.cb; ULONG oType = lpRow->aRow[0].lpProps[ieidPR_OBJECT_TYPE].Value.ul; if (pIter) keepGoing = pIter->HandleHierarchyItem( oType, cb, lpEntry); else keepGoing = HandleHierarchyItem( oType, cb, lpEntry); } FreeProws( lpRow); } } while ( SUCCEEDED(hr) && cNumRows && lpRow && keepGoing); lpTable->Release(); if (bResult && !keepGoing) bResult = FALSE; return( bResult); }
/** * Check if the favorite is exist. If the favorite is exist, it will returns the favorite data * @param ulFlags unicode flag (unused, since SetColumns always sets the correct tags) */ HRESULT GetFavorite(IMAPIFolder *lpShortcutFolder, ULONG ulFlags, IMAPIFolder *lpMapiFolder, ULONG *lpcValues, LPSPropValue *lppShortCutPropValues) { HRESULT hr = hrSuccess; LPSPropValue lpPropSourceKey = NULL; LPMAPITABLE lpTable = NULL; LPSPropValue lpShortCutPropValues = NULL; ULONG cShortCutValues = 0; LPSRestriction lpRestriction = NULL; SRowSet *lpRows = NULL; if (lpShortcutFolder == NULL || lpMapiFolder == NULL) { hr = MAPI_E_INVALID_PARAMETER; goto exit; } hr = HrGetOneProp(lpMapiFolder, PR_SOURCE_KEY, &lpPropSourceKey); if (hr != hrSuccess) { hr = MAPI_E_CORRUPT_DATA; goto exit; } // Check for duplicates hr = lpShortcutFolder->GetContentsTable(ulFlags, &lpTable); if (hr != hrSuccess) goto exit; hr = lpTable->SetColumns(GetShortCutTagArray(), 0); if(hr != hrSuccess) goto exit; // build restriction CREATE_RESTRICTION(lpRestriction); CREATE_RES_AND(lpRestriction, lpRestriction, 1); DATA_RES_PROPERTY(lpRestriction, lpRestriction->res.resAnd.lpRes[0], RELOP_EQ, PR_FAV_PUBLIC_SOURCE_KEY, lpPropSourceKey); hr = lpTable->FindRow(lpRestriction, BOOKMARK_BEGINNING, 0); if (hr != hrSuccess) goto exit; // Favorite is exist, get the information hr = lpTable->QueryRows (1, 0, &lpRows); if (hr != hrSuccess) goto exit; if (lpRows->cRows == 0) { hr = MAPI_E_NOT_FOUND; goto exit; // Folder gone? } cShortCutValues = 0; hr = Util::HrCopyPropertyArray(lpRows->aRow[0].lpProps, lpRows->aRow[0].cValues, &lpShortCutPropValues, &cShortCutValues, true); if (hr != hrSuccess) goto exit; *lppShortCutPropValues = lpShortCutPropValues; *lpcValues = cShortCutValues; exit: if (hr != hrSuccess && lpShortCutPropValues) MAPIFreeBuffer(lpShortCutPropValues); if (lpPropSourceKey) MAPIFreeBuffer(lpPropSourceKey); if (lpTable) lpTable->Release(); FREE_RESTRICTION(lpRestriction); return hr; }
/* open special folder */ bool Mapix::openSpecialFolder(CString folderName, SBinary bin, LPMDB msgStore) { LPMAPITABLE table = NULL; LPMAPIFOLDER m_folder= NULL; ULONG objectType = NULL; LPSRowSet pRows = NULL; result = msgStore->OpenEntry(bin.cb, (LPENTRYID)bin.lpb, NULL, MAPI_MODIFY|MAPI_BEST_ACCESS, &objectType, (LPUNKNOWN*)&m_folder); if(result != S_OK) { setError(result); return 0; } else { result = m_folder->GetHierarchyTable(NULL, &table); if(result == S_OK) { const int nProperties = 2; SizedSPropTagArray(nProperties, Column) = {nProperties, {PR_DISPLAY_NAME, PR_ENTRYID}}; result = table->SetColumns((LPSPropTagArray)&Column, 0); if(result == S_OK) { while(table->QueryRows(1,0, &pRows) == S_OK) { if(pRows->cRows != 1) break; else { CString nameOfFolder( pRows->aRow[0].lpProps[0].Value.lpszW); if(nameOfFolder == folderName) { sBin = pRows->aRow[0].lpProps[1].Value.bin; m_lpInboxMsgStore = msgStore; m_folder->Release(); table->Release(); pRows = NULL; return 1; } // open enumarate folder openSpecialFolder(folderName, pRows->aRow[0].lpProps[1].Value.bin, msgStore); } } } else { setError(result); return 0; } } else { setError(result); return 0; } } return 0; }
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; }