// if I try to use MAPI_UNICODE when UNICODE is defined I get the MAPI_E_BAD_CHARWIDTH // error so I force narrow strings here LPCTSTR CExMapi::GetProfileName() { if(!m_pSession) return NULL; static CString strProfileName; LPSRowSet pRows=NULL; const int nProperties=2; SizedSPropTagArray(nProperties,Columns)={nProperties,{PR_DISPLAY_NAME_A, PR_RESOURCE_TYPE}}; IMAPITable* pStatusTable; if(m_pSession->GetStatusTable(0,&pStatusTable)==S_OK) { if(pStatusTable->SetColumns((LPSPropTagArray)&Columns, 0)==S_OK) { while(TRUE) { if(pStatusTable->QueryRows(1,0,&pRows)!=S_OK) MAPIFreeBuffer(pRows); else if(pRows->cRows!=1) FreeProws(pRows); else if(pRows->aRow[0].lpProps[1].Value.ul==MAPI_SUBSYSTEM) { strProfileName=(LPSTR)GetValidString(pRows->aRow[0].lpProps[0]); FreeProws(pRows); } else { FreeProws(pRows); continue; } break; } } RELEASE(pStatusTable); } return strProfileName; }
BOOL CExMapi::OpenDefaultMessageStore(LPCTSTR szStore,ULONG ulFlags) { if(!m_pSession) return FALSE; m_ulMDBFlags=ulFlags; LPSRowSet pRows = NULL; const int nProperties = 3; SizedSPropTagArray(nProperties,Columns)={nProperties,{PR_DISPLAY_NAME, PR_ENTRYID, PR_DEFAULT_STORE}}; BOOL bResult = FALSE; IMAPITable* pMsgStoresTable; if(m_pSession->GetMsgStoresTable(0, &pMsgStoresTable) == S_OK) { if(pMsgStoresTable->SetColumns((LPSPropTagArray)&Columns, 0) == S_OK) { while(TRUE) { if(pMsgStoresTable->QueryRows(1,0,&pRows) != S_OK) MAPIFreeBuffer(pRows); else if(pRows->cRows!=1) FreeProws(pRows); else { if(!szStore) { if(pRows->aRow[0].lpProps[2].Value.b) bResult=TRUE; } else { CString strStore = GetValidString(pRows->aRow[0].lpProps[0]); if(strStore.Find(szStore) != -1) bResult = TRUE; } if(!bResult) { FreeProws(pRows); continue; } } break; } if(bResult) { RELEASE(m_pMsgStore); bResult = (m_pSession->OpenMsgStore(NULL,pRows->aRow[0].lpProps[1].Value.bin.cb,(ENTRYID*)pRows->aRow[0].lpProps[1].Value.bin.lpb,NULL,MDB_NO_DIALOG | MAPI_BEST_ACCESS,&m_pMsgStore) == S_OK); FreeProws(pRows); } } RELEASE(pMsgStoresTable); } return bResult; }
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
LPMAPIFOLDER CExMapi::GetNextSubFolder(CString& strFolderName,LPMAPIFOLDER pFolder) { if(!m_pHierarchy) return NULL; if(!pFolder) { pFolder=m_pFolder; if(!pFolder) return FALSE; } DWORD dwObjType; LPSRowSet pRows=NULL; LPMAPIFOLDER pSubFolder=NULL; if(m_pHierarchy->QueryRows(1,0,&pRows)==S_OK) { if(pRows->cRows) { if(pFolder->OpenEntry(pRows->aRow[0].lpProps[PROP_ENTRYID].Value.bin.cb,(LPENTRYID)pRows->aRow[0].lpProps[PROP_ENTRYID].Value.bin.lpb, NULL, MAPI_MODIFY, &dwObjType,(LPUNKNOWN*)&pSubFolder)==S_OK) { strFolderName=CString(GetValidString(pRows->aRow[0].lpProps[0])); } } FreeProws(pRows); MAPIFreeBuffer(pRows); } return pSubFolder; }
BOOL CMAPIEx::GetNextMessage(CMAPIMessage& message, BOOL bUnreadOnly) { if (!m_pContents) return FALSE; DWORD dwMessageFlags; LPSRowSet pRows = NULL; BOOL bResult = FALSE; while (m_pContents->QueryRows(1, 0, &pRows) == S_OK) { if (pRows->cRows) { dwMessageFlags = pRows->aRow[0].lpProps[PROP_MESSAGE_FLAGS].Value.ul; if (bUnreadOnly && dwMessageFlags & MSGFLAG_READ) { FreeProws(pRows); continue; } bResult = message.Open(this, pRows->aRow[0].lpProps[PROP_ENTRYID].Value.bin, dwMessageFlags); } FreeProws(pRows); break; } MAPIFreeBuffer(pRows); return bResult; }
BOOL CMAPIEx::GetNextContact(CMAPIContact& contact) { if (!m_pContents) return FALSE; LPSRowSet pRows = NULL; BOOL bResult = FALSE; while (m_pContents->QueryRows(1, 0, &pRows) == S_OK) { if (pRows->cRows) bResult = contact.Open(this, pRows->aRow[0].lpProps[PROP_ENTRYID].Value.bin); FreeProws(pRows); break; } MAPIFreeBuffer(pRows); return bResult; }
// if I try to use MAPI_UNICODE when UNICODE is defined I get the MAPI_E_BAD_CHARWIDTH // error so I force narrow strings here BOOL CMAPIEx::GetProfileName(CString& strProfileName) { BOOL bResult=FALSE; #ifndef _WIN32_WCE if(!m_pSession) return FALSE; LPSRowSet pRows=NULL; const int nProperties=2; SizedSPropTagArray(nProperties, Columns)={nProperties,{PR_DISPLAY_NAME_A, PR_RESOURCE_TYPE}}; IMAPITable* pStatusTable; if(m_pSession->GetStatusTable(0, &pStatusTable)==S_OK) { if(pStatusTable->SetColumns((LPSPropTagArray)&Columns, 0)==S_OK) { while(pStatusTable->QueryRows(1, 0, &pRows)==S_OK) { if(pRows->cRows!=1) FreeProws(pRows); else if(pRows->aRow[0].lpProps[1].Value.ul==MAPI_SUBSYSTEM) { strProfileName=(LPSTR)GetValidString(pRows->aRow[0].lpProps[0]); FreeProws(pRows); bResult=TRUE; } else { FreeProws(pRows); continue; } break; } } RELEASE(pStatusTable); } #endif return bResult; }
SRow *MAPITableIterator::GetNext() { HRESULT hr = S_OK; if (0 == m_totalRows) return NULL; if (m_currRow >= m_pRows->cRows) { if (m_rowsVisited >= m_totalRows) return NULL; FreeProws(m_pRows); m_pRows = NULL; if (m_totalRows - m_rowsVisited < m_batchSize) { hr = m_pTable->QueryRows((m_totalRows - m_rowsVisited), 0, &m_pRows); if (m_pRows && (m_pRows->cRows < (m_totalRows - m_rowsVisited))) { // "**Warning**: %d Table Rows Requested, Got just %d, hr = %d"), _totalRows - _rowsVisited, _pRows->cRows, hr m_rowsVisited = m_totalRows - m_pRows->cRows; } } else { hr = m_pTable->QueryRows(m_batchSize, 0, &m_pRows); if (m_pRows && (m_pRows->cRows < m_batchSize)) { // "**Warning**: %d Table Rows Requested, Got just %d, hr = %d"), _batchSize, _pRows->cRows, hr m_rowsVisited += m_batchSize - m_pRows->cRows; } } if (FAILED(hr)) { throw GenericException(hr, L"MAPITableIterator::GetNext():QueryRows Failed.",ERR_GET_NEXT, __LINE__, __FILE__); } m_currRow = 0; } if (!m_pRows->cRows) return NULL; SRow *pRow = &(m_pRows->aRow[m_currRow]); m_currRow++; m_rowsVisited++; return pRow; }
void MAPITableIterator::Initialize(LPMAPITABLE pTable, LPMAPIFOLDER pFolder, MAPISession &session, ULONG ulItemTypeMask) { UNREFERENCED_PARAMETER(ulItemTypeMask); HRESULT hr = S_OK; m_session = &session; if (m_pParentFolder != NULL) { UlRelease(m_pParentFolder); m_pParentFolder = NULL; } if (m_pRows != NULL) FreeProws(m_pRows); m_pParentFolder = pFolder; m_pTable = pTable; hr = m_pTable->SetColumns(GetProps(), 0); if (FAILED(hr)) { throw GenericException(hr, L"MAPITableIterator::Initialize():SetColumns Failed.",ERR_SET_RESTRICTION, __LINE__, __FILE__); } if (GetSortOrder() != NULL) { if (FAILED(hr = m_pTable->SortTable(GetSortOrder(), 0))) { throw GenericException(hr, L"MAPITableIterator::Initialize():SortTable Failed.",ERR_SET_RESTRICTION, __LINE__, __FILE__); } } if (FAILED(hr = m_pTable->GetRowCount(0, &m_totalRows))) { throw GenericException(hr, L"MAPITableIterator::Initialize():GetRowCount Failed.",ERR_SET_RESTRICTION, __LINE__, __FILE__); } if (FAILED(hr = m_pTable->QueryRows(m_batchSize, 0, &m_pRows))) { throw GenericException(hr, L"MAPITableIterator::Initialize():QueryRows Failed.",ERR_SET_RESTRICTION, __LINE__, __FILE__); } }
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; }
HRESULT ConfigMsgService(){ HRESULT hr = 0; LPPROFADMIN lpProfAdmin = NULL; LPSERVICEADMIN lpServiceAdmin = NULL; LPMAPITABLE lpMapiTable = NULL; SRestriction sres; // Restriction structure. SPropValue SvcProps; // Property structure for restriction. LPSRowSet lpSvcRows = NULL; // Rowset to hold results of table query. LPSTR szServer = "155.35.79.109"; LPSTR szMailbox = "InputedBox"; SPropValue rgval[2]; // Property structure to hold values we want to set. enum { iSvcName, iSvcUID, cptaSvc }; SizedSPropTagArray(cptaSvc, sptCols) = { cptaSvc, PR_SERVICE_NAME, PR_SERVICE_UID }; do{ // if not profile, create profile. // else use exist profile DEFINE_IF_HR_NT_OK_BREAK(MAPIAdminProfiles(0, &lpProfAdmin)); LPTSTR strProfileName = L"lhytest"; LPTSTR strProfilePsw = L"123.com"; hr = lpProfAdmin->CreateProfile(strProfileName, NULL, NULL, 0); if (hr == MAPI_E_NO_ACCESS){ // profile exist; break; } else if (hr == S_OK){ DEFINE_IF_HR_NT_OK_BREAK(lpProfAdmin->AdminServices(strProfileName, NULL, NULL, 0, &lpServiceAdmin)); DEFINE_IF_HR_NT_OK_BREAK(lpServiceAdmin->CreateMsgService((LPTSTR)"MSEMS", NULL, 0, 0)); // todo config MsgService. hr = lpServiceAdmin->GetMsgServiceTable(0, &lpMapiTable); DEFINE_IF_HR_NT_OK_BREAK(hr); sres.rt = RES_CONTENT; sres.res.resContent.ulFuzzyLevel = FL_FULLSTRING; sres.res.resContent.ulPropTag = PR_SERVICE_NAME; sres.res.resContent.lpProp = &SvcProps; SvcProps.ulPropTag = PR_SERVICE_NAME; SvcProps.Value.lpszA = "MSEMS"; // Query the table to obtain the entry for the newly created message service. if (FAILED(hr = HrQueryAllRows(lpMapiTable, (LPSPropTagArray)&sptCols, &sres, NULL, 0, &lpSvcRows))) { break; } // Set up a SPropValue array for the properties that you have to configure. // First, the server name. ZeroMemory(&rgval[1], sizeof(SPropValue)); rgval[1].ulPropTag = PR_PROFILE_UNRESOLVED_SERVER; rgval[1].Value.lpszA = szServer; // Next, the mailbox name. ZeroMemory(&rgval[0], sizeof(SPropValue)); rgval[0].ulPropTag = PR_PROFILE_UNRESOLVED_NAME; rgval[0].Value.lpszA = szMailbox; // Configure the message service by using the previous properties. if (FAILED(hr = lpServiceAdmin->ConfigureMsgService( (LPMAPIUID)lpSvcRows->aRow->lpProps[iSvcUID].Value.bin.lpb, // Entry ID of service to configure. NULL, // Handle to parent window. 0, // Flags. 2, // Number of properties we are setting. rgval))) // Pointer to SPropValue array. { break; } } else { break; } } while (0); if (lpSvcRows != NULL){ FreeProws(lpSvcRows); lpSvcRows = NULL; } if (lpMapiTable != NULL){ lpMapiTable->Release(); lpMapiTable = NULL; } if (lpServiceAdmin != NULL){ lpServiceAdmin->Release(); lpServiceAdmin = NULL; } if (lpProfAdmin != NULL){ lpProfAdmin->Release(); lpProfAdmin = NULL; } return hr; }
/// <summary> /// <para name='Name'>OpenDefaultMessageStore</para> /// <para name='Purpose'>Find and open the default message store</para> /// </summary> /// <param name='lppDefaultMDB'>[out] Pointer to the opened default message store</param> /// <returns>HRESULT</returns> /// <remarks> /// <para name='Notes'>Adapted from MFCMapi's MAPIStoreFunctions.cpp\OpenDefaultMessageStore()</para> /// <para name='Author'></para> /// <para name='LastModified'>29Jan2016</para> /// </remarks> STDMETHODIMP ZybraxiSoft::CMailbox::OpenDefaultMessageStore(LPMDB * lppDefaultMDB) { HRESULT hr = S_OK; LPMAPITABLE pStoresTable = NULL; SPropValue sPropVal; static SRestriction sRes; LPSRowSet pSRowSet = NULL; // Set up an enum to mask the numbers into pretty text enum { EID, NUM_COLS }; // Set up a constant SPropTagArray /*static const SizedSPropTagArray(NUM_COLS, sptEIDCol) = { NUM_COLS, PR_ENTRYID, };*/ static const struct _SPropTagArray_sptEIDCol { ULONG NUM_COLS; ULONG aulPropTag[1]; } sptEIDCol = { NUM_COLS, PR_ENTRYID }; // Get our message stores table // See https://msdn.microsoft.com/en-us/library/cc839751(v=office.15).aspx if (FAILED(hr = m_lpSession->GetMsgStoresTable( 0, // ulFlags (not sure why we don't use MAPI_UNICODE) &pStoresTable))) // [out] lppTable { ERROR_MSG_W_HR("Unable to get message stores table", hr); goto CLEANUP; } // Set up our property value to restrict against sPropVal.ulPropTag = PR_DEFAULT_STORE; // The proptag to check sPropVal.Value.b = true; // what to check against // Set up to restrict so QueryRows gets only the default store sRes.rt = RES_PROPERTY; // Compare if property sRes.res.resProperty.ulPropTag = PR_DEFAULT_STORE; // PR_DEFAULT_STORE sRes.res.resProperty.relop = RELOP_EQ; // is equal to sRes.res.resProperty.lpProp = &sPropVal; // this property value // Run the query // See https://msdn.microsoft.com/en-us/library/office/cc815764.aspx if (FAILED(hr = HrQueryAllRows( pStoresTable, (LPSPropTagArray)&sptEIDCol, &sRes, NULL, 0, &pSRowSet))) { ERROR_MSG_W_HR("HrQueryAllRows failed", hr); goto CLEANUP; } // Always check to see if we actually returned some rows if (pSRowSet && pSRowSet->cRows) { // Check to make sure we only returned one default // We'll use the first one regardless, but let's sound // a warning anyway. if (pSRowSet->cRows > 1) { WARN("We returned more than on Default store!"); } // Open the message store if (FAILED(hr = DoOpenMsgStore( &pSRowSet->aRow[0].lpProps[EID].Value.bin, MDB_WRITE, lppDefaultMDB))) { ERROR_MSG_W_HR("DoOpenMsgStore failed.", hr); goto CLEANUP; } } else hr = MAPI_E_NOT_FOUND; CLEANUP: if (pSRowSet) { FreeProws(pSRowSet); pSRowSet = NULL; } if (pStoresTable) { pStoresTable->Release(); pStoresTable = NULL; } return hr; }
void Test(){ HRESULT hr = 0; LPMAPISESSION lpMapiSession = NULL; LPMDB lpMdb = NULL; IMAPITable* pIStoreTable = NULL; LPSRowSet pRows = NULL; IUnknown* lpExchManageStroe = NULL; SPropValue* pAllFoldersPropValue = NULL; do{ MAPIINIT_0 mapiInit = { 0, MAPI_MULTITHREAD_NOTIFICATIONS }; hr = MAPIInitialize(&mapiInit); DEFINE_IF_HR_NT_OK_BREAK(hr); //L"Outlook" hr = MAPILogonEx(0, NULL , NULL, MAPI_NEW_SESSION | MAPI_USE_DEFAULT | MAPI_EXTENDED, &lpMapiSession); DEFINE_IF_HR_NT_OK_BREAK(hr); enum{ PR_DEFAULT_STORE_, PR_ENTRYID_, PR_RESOURCE_FLAGS_, PR_MDB_PROVIDER_, PR_DISPLAY_NAME_, COUNT }; SizedSPropTagArray(COUNT, storeEntryID) = { COUNT, { PR_DEFAULT_STORE, PR_ENTRYID, PR_RESOURCE_FLAGS, PR_MDB_PROVIDER, PR_DISPLAY_NAME} }; ULONG ulRowCount = 0; ULONG ulRowIndex = 0; BOOL bFind = FALSE; hr = lpMapiSession->GetMsgStoresTable(0, &pIStoreTable); DEFINE_IF_HR_NT_OK_BREAK(hr); hr = pIStoreTable->SetColumns((LPSPropTagArray)&storeEntryID, 0); DEFINE_IF_HR_NT_OK_BREAK(hr); hr = pIStoreTable->GetRowCount(0, &ulRowCount); DEFINE_IF_HR_NT_OK_BREAK(hr); hr = pIStoreTable->QueryRows(ulRowCount, 0, &pRows); DEFINE_IF_HR_NT_OK_BREAK(hr); ulRowIndex = 0; while (ulRowIndex<pRows->cRows) { _SRow row = pRows->aRow[ulRowIndex]; if (row.lpProps[PR_DEFAULT_STORE_].Value.b == TRUE && (row.lpProps[PR_RESOURCE_FLAGS_].Value.ul & STATUS_DEFAULT_STORE) ) { bFind = TRUE; break; } ulRowIndex++; } if (bFind) { hr = lpMapiSession->OpenMsgStore(0, pRows->aRow[ulRowIndex].lpProps[PR_ENTRYID_].Value.bin.cb, (ENTRYID*)pRows->aRow[ulRowIndex].lpProps[PR_ENTRYID_].Value.bin.lpb, NULL, MDB_WRITE | MAPI_BEST_ACCESS | MDB_NO_DIALOG, (IMsgStore**)&lpMdb); DEFINE_IF_HR_NT_OK_BREAK(hr); } else { break; } enum { PR_IPM_OUTBOX_ENTRYID_, PR_VALID_FOLDER_MASK_, COUNT_ }; SizedSPropTagArray(COUNT_, rgPropTag) = { COUNT_, { PR_IPM_OUTBOX_ENTRYID, PR_VALID_FOLDER_MASK } }; ULONG ulValues = 0; hr = lpMdb->GetProps((LPSPropTagArray)&rgPropTag, 0, &ulValues, &pAllFoldersPropValue); DEFINE_IF_HR_NT_OK_BREAK(hr); ULONG lpObjType = 0; IMAPIFolder* lpMapiFolder = NULL; if (pAllFoldersPropValue[PR_VALID_FOLDER_MASK_].Value.ul & FOLDER_IPM_OUTBOX_VALID){ hr = lpMdb->OpenEntry(pAllFoldersPropValue[PR_IPM_OUTBOX_ENTRYID_].Value.bin.cb, (ENTRYID*)pAllFoldersPropValue[PR_IPM_OUTBOX_ENTRYID_].Value.bin.lpb, NULL, MAPI_BEST_ACCESS | MAPI_MODIFY, &lpObjType, (IUnknown**)&lpMapiFolder); DEFINE_IF_HR_NT_OK_BREAK(hr); } hr = AddMailW(lpMapiSession, lpMapiFolder, L"ceshi测试12", L"lhy测试12", L"*****@*****.**", false, false, true, false); DEFINE_IF_HR_NT_OK_BREAK(hr); } while (0); DWORD dError = GetLastError(); if (pAllFoldersPropValue){ MAPIFREEBUFFER(pAllFoldersPropValue); } if (lpExchManageStroe) { lpExchManageStroe->Release(); lpExchManageStroe = NULL; } if (lpMdb) { ULONG ulLogOffTag = LOGOFF_NO_WAIT; lpMdb->StoreLogoff(&ulLogOffTag); lpMdb->Release(); lpMdb = NULL; } if (pRows) { FreeProws(pRows); pRows = NULL; } if (pIStoreTable) { pIStoreTable->Release(); pIStoreTable = NULL; } if (lpMapiSession){ lpMapiSession->Logoff(0, 0, 0); lpMapiSession->Release(); lpMapiSession = NULL; } MAPIUninitialize(); }
// 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
// Search folder for entry ID of child folder by name. HRESULT HrMAPIFindFolderW( _In_ LPMAPIFOLDER lpFolder, // pointer to folder _In_z_ LPCWSTR lpszName, // name of child folder to find _Out_opt_ ULONG* lpcbeid, // pointer to count of bytes in entry ID _Deref_out_opt_ LPENTRYID* lppeid) // pointer to entry ID pointer { DebugPrint(DBGGeneric,"HrMAPIFindFolderW: Locating folder \"%ws\"\n", lpszName); HRESULT hRes = S_OK; LPMAPITABLE lpTable = NULL; LPSRowSet lpRow = NULL; LPSPropValue lpRowProp = 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 }; if (!lpcbeid || !lppeid) return MAPI_E_INVALID_PARAMETER; *lpcbeid = 0; *lppeid = NULL; if (!lpFolder) return MAPI_E_INVALID_PARAMETER; WC_MAPI(lpFolder->GetHierarchyTable(MAPI_UNICODE | MAPI_DEFERRED_ERRORS, &lpTable)); if (SUCCEEDED(hRes) && lpTable) { WC_MAPI(HrQueryAllRows(lpTable, (LPSPropTagArray)&rgColProps, NULL, NULL, 0, &lpRow)); } if (SUCCEEDED(hRes) && lpRow) { for (i = 0; i < lpRow->cRows; i++) { lpRowProp = lpRow->aRow[i].lpProps; if (PR_DISPLAY_NAME_W == lpRowProp[ePR_DISPLAY_NAME_W].ulPropTag && _wcsicmp(lpRowProp[ePR_DISPLAY_NAME_W].Value.lpszW, lpszName) == 0 && PR_ENTRYID == lpRowProp[ePR_ENTRYID].ulPropTag) { WC_H(MAPIAllocateBuffer(lpRowProp[ePR_ENTRYID].Value.bin.cb, (LPVOID*)lppeid)); if (SUCCEEDED(hRes) && lppeid) { *lpcbeid = lpRowProp[ePR_ENTRYID].Value.bin.cb; CopyMemory(*lppeid, lpRowProp[ePR_ENTRYID].Value.bin.lpb, *lpcbeid); } break; } } } if (!*lpcbeid) { hRes = MAPI_E_NOT_FOUND; } FreeProws(lpRow); if (lpTable) lpTable->Release(); return hRes; } // HrMAPIFindFolderW
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
/* Internal function to send a message via Extended MAPI. Wrapper around the Simple MAPI function MAPISendMail. */ static ULONG sendmail_extended_mapi(LHANDLE mapi_session, ULONG_PTR uiparam, lpMapiMessageW message, FLAGS flags) { ULONG tags[] = {1, 0}; char *subjectA = NULL, *bodyA = NULL; ULONG retval = MAPI_E_FAILURE; IMAPISession *session = NULL; BOOL unicode_aware = FALSE; IMAPITable* msg_table; LPSRowSet rows = NULL; IMsgStore* msg_store; IMAPIFolder* folder = NULL, *draft_folder = NULL; LPENTRYID entry_id; LPSPropValue props; ULONG entry_len; DWORD obj_type; IMessage* msg; ULONG values; HRESULT ret; TRACE("Using Extended MAPI wrapper for MAPISendMail\n"); /* Attempt to log on via Extended MAPI */ ret = MAPILogonEx(0, NULL, NULL, MAPI_EXTENDED | MAPI_USE_DEFAULT | MAPI_NEW_SESSION, &session); TRACE("MAPILogonEx: %x\n", ret); if (ret != S_OK) { retval = MAPI_E_LOGIN_FAILURE; goto cleanup; } /* Open the default message store */ if (IMAPISession_GetMsgStoresTable(session, 0, &msg_table) == S_OK) { /* We want the default store */ SizedSPropTagArray(2, columns) = {2, {PR_ENTRYID, PR_DEFAULT_STORE}}; /* Set the columns we want */ if (IMAPITable_SetColumns(msg_table, (LPSPropTagArray) &columns, 0) == S_OK) { while (1) { if (IMAPITable_QueryRows(msg_table, 1, 0, &rows) != S_OK) { MAPIFreeBuffer(rows); rows = NULL; } else if (rows->cRows != 1) { FreeProws(rows); rows = NULL; } else { /* If it's not the default store, try the next row */ if (!rows->aRow[0].lpProps[1].Value.b) { FreeProws(rows); continue; } } break; } } IMAPITable_Release(msg_table); } /* Did we manage to get the right store? */ if (!rows) goto logoff; /* Open the message store */ IMAPISession_OpenMsgStore(session, 0, rows->aRow[0].lpProps[0].Value.bin.cb, (ENTRYID *) rows->aRow[0].lpProps[0].Value.bin.lpb, NULL, MDB_NO_DIALOG | MAPI_BEST_ACCESS, &msg_store); /* We don't need this any more */ FreeProws(rows); /* Check if the message store supports Unicode */ tags[1] = PR_STORE_SUPPORT_MASK; ret = IMsgStore_GetProps(msg_store, (LPSPropTagArray) tags, 0, &values, &props); if ((ret == S_OK) && (props[0].Value.l & STORE_UNICODE_OK)) unicode_aware = TRUE; else { /* Don't convert to ANSI */ if (flags & MAPI_FORCE_UNICODE) { WARN("No Unicode-capable mail client, and MAPI_FORCE_UNICODE is specified. MAPISendMail failed.\n"); retval = MAPI_E_UNICODE_NOT_SUPPORTED; IMsgStore_Release(msg_store); goto logoff; } } /* First open the inbox, from which the drafts folder can be opened */ if (IMsgStore_GetReceiveFolder(msg_store, NULL, 0, &entry_len, &entry_id, NULL) == S_OK) { IMsgStore_OpenEntry(msg_store, entry_len, entry_id, NULL, 0, &obj_type, (LPUNKNOWN*) &folder); MAPIFreeBuffer(entry_id); } tags[1] = PR_IPM_DRAFTS_ENTRYID; /* Open the drafts folder, or failing that, try asking the message store for the outbox */ if ((folder == NULL) || ((ret = IMAPIFolder_GetProps(folder, (LPSPropTagArray) tags, 0, &values, &props)) != S_OK)) { TRACE("Unable to open Drafts folder; opening Outbox instead\n"); tags[1] = PR_IPM_OUTBOX_ENTRYID; ret = IMsgStore_GetProps(msg_store, (LPSPropTagArray) tags, 0, &values, &props); } if (ret != S_OK) goto logoff; IMsgStore_OpenEntry(msg_store, props[0].Value.bin.cb, (LPENTRYID) props[0].Value.bin.lpb, NULL, MAPI_MODIFY, &obj_type, (LPUNKNOWN *) &draft_folder); /* Create a new message */ if (IMAPIFolder_CreateMessage(draft_folder, NULL, 0, &msg) == S_OK) { ULONG token; SPropValue p; /* Define message properties */ p.ulPropTag = PR_MESSAGE_FLAGS; p.Value.l = MSGFLAG_FROMME | MSGFLAG_UNSENT; IMessage_SetProps(msg, 1, &p, NULL); p.ulPropTag = PR_SENTMAIL_ENTRYID; p.Value.bin.cb = props[0].Value.bin.cb; p.Value.bin.lpb = props[0].Value.bin.lpb; IMessage_SetProps(msg, 1,&p, NULL); /* Set message subject */ if (message->lpszSubject) { if (unicode_aware) { p.ulPropTag = PR_SUBJECT_W; p.Value.lpszW = message->lpszSubject; } else { subjectA = convert_from_unicode(message->lpszSubject); p.ulPropTag = PR_SUBJECT_A; p.Value.lpszA = subjectA; } IMessage_SetProps(msg, 1, &p, NULL); } /* Set message body */ if (message->lpszNoteText) { LPSTREAM stream = NULL; if (IMessage_OpenProperty(msg, unicode_aware ? PR_BODY_W : PR_BODY_A, &IID_IStream, 0, MAPI_MODIFY | MAPI_CREATE, (LPUNKNOWN*) &stream) == S_OK) { if (unicode_aware) IStream_Write(stream, message->lpszNoteText, (lstrlenW(message->lpszNoteText)+1) * sizeof(WCHAR), NULL); else { bodyA = convert_from_unicode(message->lpszNoteText); IStream_Write(stream, bodyA, strlen(bodyA)+1, NULL); } IStream_Release(stream); } } /* Add message attachments */ if (message->nFileCount > 0) { ULONG num_attach = 0; unsigned int i; for (i = 0; i < message->nFileCount; i++) { IAttach* attachment = NULL; char *filenameA = NULL; SPropValue prop[4]; LPCWSTR filename; HANDLE file; if (!message->lpFiles[i].lpszPathName) continue; /* Open the attachment for reading */ file = CreateFileW(message->lpFiles[i].lpszPathName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (file == INVALID_HANDLE_VALUE) continue; /* Check if a display filename has been given; if not, get one ourselves from path name */ filename = message->lpFiles[i].lpszFileName; if (!filename) { int j; filename = message->lpFiles[i].lpszPathName; for (j = lstrlenW(message->lpFiles[i].lpszPathName)-1; j >= 0; j--) { if (message->lpFiles[i].lpszPathName[i] == '\\' || message->lpFiles[i].lpszPathName[i] == '/') { filename = &message->lpFiles[i].lpszPathName[i+1]; break; } } } TRACE("Attachment %u path: '%s'; filename: '%s'\n", i, debugstr_w(message->lpFiles[i].lpszPathName), debugstr_w(filename)); /* Create the attachment */ if (IMessage_CreateAttach(msg, NULL, 0, &num_attach, &attachment) != S_OK) { TRACE("Unable to create attachment\n"); CloseHandle(file); continue; } /* Set the attachment properties */ ZeroMemory(prop, sizeof(prop)); prop[0].ulPropTag = PR_ATTACH_METHOD; prop[0].Value.ul = ATTACH_BY_VALUE; if (unicode_aware) { prop[1].ulPropTag = PR_ATTACH_LONG_FILENAME_W; prop[1].Value.lpszW = (LPWSTR) filename; prop[2].ulPropTag = PR_ATTACH_FILENAME_W; prop[2].Value.lpszW = (LPWSTR) filename; } else { filenameA = convert_from_unicode(filename); prop[1].ulPropTag = PR_ATTACH_LONG_FILENAME_A; prop[1].Value.lpszA = (LPSTR) filenameA; prop[2].ulPropTag = PR_ATTACH_FILENAME_A; prop[2].Value.lpszA = (LPSTR) filenameA; } prop[3].ulPropTag = PR_RENDERING_POSITION; prop[3].Value.l = -1; if (IAttach_SetProps(attachment, 4, prop, NULL) == S_OK) { LPSTREAM stream = NULL; if (IAttach_OpenProperty(attachment, PR_ATTACH_DATA_BIN, &IID_IStream, 0, MAPI_MODIFY | MAPI_CREATE, (LPUNKNOWN*) &stream) == S_OK) { BYTE data[READ_BUF_SIZE]; DWORD size = 0, read, written; while (ReadFile(file, data, READ_BUF_SIZE, &read, NULL) && (read != 0)) { IStream_Write(stream, data, read, &written); size += read; } TRACE("%d bytes written of attachment\n", size); IStream_Commit(stream, STGC_DEFAULT); IStream_Release(stream); prop[0].ulPropTag = PR_ATTACH_SIZE; prop[0].Value.ul = size; IAttach_SetProps(attachment, 1, prop, NULL); IAttach_SaveChanges(attachment, KEEP_OPEN_READONLY); num_attach++; } } CloseHandle(file); IAttach_Release(attachment); HeapFree(GetProcessHeap(), 0, filenameA); } } IMessage_SaveChanges(msg, KEEP_OPEN_READWRITE); /* Prepare the message form */ if (IMAPISession_PrepareForm(session, NULL, msg, &token) == S_OK) { ULONG access = 0, status = 0, message_flags = 0, pc = 0; ULONG pT[2] = {1, PR_MSG_STATUS}; /* Retrieve message status, flags, access rights and class */ if (IMessage_GetProps(msg, (LPSPropTagArray) pT, 0, &pc, &props) == S_OK) { status = props->Value.ul; MAPIFreeBuffer(props); } pT[1] = PR_MESSAGE_FLAGS; if (IMessage_GetProps(msg, (LPSPropTagArray) pT, 0, &pc, &props) == S_OK) { message_flags = props->Value.ul; MAPIFreeBuffer(props); } pT[1] = PR_ACCESS; if (IMessage_GetProps(msg, (LPSPropTagArray) pT, 0, &pc, &props) == S_OK) { access = props->Value.ul; MAPIFreeBuffer(props); } pT[1] = PR_MESSAGE_CLASS_A; if (IMessage_GetProps(msg, (LPSPropTagArray) pT, 0, &pc, &props) == S_OK) { /* Show the message form (edit window) */ ret = IMAPISession_ShowForm(session, 0, msg_store, draft_folder, NULL, token, NULL, 0, status, message_flags, access, props->Value.lpszA); switch (ret) { case S_OK: retval = SUCCESS_SUCCESS; break; case MAPI_E_USER_CANCEL: retval = MAPI_E_USER_ABORT; break; default: TRACE("ShowForm failure: %x\n", ret); break; } } } IMessage_Release(msg); } /* Free up the resources we've used */ IMAPIFolder_Release(draft_folder); if (folder) IMAPIFolder_Release(folder); IMsgStore_Release(msg_store); HeapFree(GetProcessHeap(), 0, subjectA); HeapFree(GetProcessHeap(), 0, bodyA); logoff: ; IMAPISession_Logoff(session, 0, 0, 0); IMAPISession_Release(session); cleanup: ; MAPIUninitialize(); return retval; }
_Check_return_ HRESULT SearchContentsTableForName( _In_ LPMAPITABLE pTable, _In_z_ LPCTSTR szName, ULONG PropTagToCompare, _Deref_out_opt_ LPSPropValue *lppPropsFound) { HRESULT hRes = S_OK; LPSRowSet pRows = NULL; enum { abPR_ENTRYID, abPR_DISPLAY_NAME, abPR_RECIPIENT_TYPE, abPR_ADDRTYPE, abPR_DISPLAY_TYPE, abPropTagToCompare, abNUM_COLS }; const SizedSPropTagArray(abNUM_COLS, abCols) = { abNUM_COLS, PR_ENTRYID, PR_DISPLAY_NAME, PR_RECIPIENT_TYPE, PR_ADDRTYPE, PR_DISPLAY_TYPE, PropTagToCompare }; *lppPropsFound = NULL; if (!pTable || !szName) return MAPI_E_INVALID_PARAMETER; DebugPrint(DBGGeneric, _T("SearchContentsTableForName: Looking for \"%s\"\n"), szName); // Set a restriction so we only find close matches LPSRestriction lpSRes = NULL; EC_H(CreateANRRestriction( PR_ANR, szName, NULL, &lpSRes)); EC_MAPI(pTable->SetColumns((LPSPropTagArray)&abCols, TBL_BATCH)); // Jump to the top of the table... EC_MAPI(pTable->SeekRow( BOOKMARK_BEGINNING, 0, NULL)); // ..and jump to the first matching entry in the table EC_MAPI(pTable->Restrict( lpSRes, NULL )); // Now we iterate through each of the matching entries if (!FAILED(hRes)) for (;;) { hRes = S_OK; if (pRows) FreeProws(pRows); pRows = NULL; EC_MAPI(pTable->QueryRows( 1, NULL, &pRows)); if (FAILED(hRes) || !pRows || (pRows && !pRows->cRows)) break; // An error at this point is an error with the current entry, so we can continue this for statement // Unless it's an allocation error. Those are bad. if (PropTagToCompare == pRows->aRow->lpProps[abPropTagToCompare].ulPropTag && CheckStringProp(&pRows->aRow->lpProps[abPropTagToCompare], PT_TSTRING)) { DebugPrint(DBGGeneric, _T("SearchContentsTableForName: found \"%s\"\n"), pRows->aRow->lpProps[abPropTagToCompare].Value.LPSZ); if (lstrcmpi(szName, pRows->aRow->lpProps[abPropTagToCompare].Value.LPSZ) == 0) { DebugPrint(DBGGeneric, _T("SearchContentsTableForName: This is an exact match!\n")); // We found a match! Return it! EC_MAPI(ScDupPropset( abNUM_COLS, pRows->aRow->lpProps, MAPIAllocateBuffer, lppPropsFound)); break; } } } if (!*lppPropsFound) { DebugPrint(DBGGeneric, _T("SearchContentsTableForName: No exact match found.\n")); } MAPIFreeBuffer(lpSRes); if (pRows) FreeProws(pRows); return hRes; } // SearchContentsTableForName
MAPITableIterator::~MAPITableIterator() { if (m_pRows != NULL) FreeProws(m_pRows); }
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 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; }
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); }
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; }
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); }
bool MAPIStorageAdviser::AdviseAll() { IMAPISession* pSession = InitIMAPISession(); IMAPITable* pStoresTable = GetStoresTable(pSession); SizedSPropTagArray(2, tblColumns) = {2, {PR_DISPLAY_NAME, PR_ENTRYID}}; pStoresTable->SetColumns((LPSPropTagArray)&tblColumns, 0); for(;;) { SRowSet * pRowSet = NULL; pStoresTable->QueryRows(1, 0, &pRowSet); if(pRowSet->cRows != 1) break; ASSERT(pRowSet->aRow[0].cValues == tblColumns.cValues); SPropValue* pVal = pRowSet->aRow[0].lpProps; ASSERT(pVal[0].ulPropTag == PR_DISPLAY_NAME); ASSERT(pVal[1].ulPropTag == PR_ENTRYID); LPWSTR lpStoreName = pRowSet->aRow[0].lpProps[0].Value.lpszW; // Open Store LPBYTE pEntry = (LPBYTE)pRowSet->aRow[0].lpProps[1].Value.bin.lpb; ULONG ulStoreBytes = pRowSet->aRow[0].lpProps[1].Value.bin.cb; IMsgStore* pStore = _GetStoreFromEntryID(pSession, ulStoreBytes, pEntry); if (pStore == NULL) { continue; } if (AddSink(pStore) == true) { }else{ } pStore->Release(); FreeProws(pRowSet); } pStoresTable->Release(); pSession->Release(); return true; }