/// <summary> /// <para name='Name'>AllocAdrList</para> /// <para name='Purpose'>Allocate and AdrList structure</para> /// </summary> /// <param name='ulNumProps'>Number of properties to allocate</param> /// <param name='lpAdrList'>[out]The returned pointer to the AdrList</param> /// <returns>HRESULT</returns> /// <remarks> /// <para name='Notes'>Taken from MFCMapi's MAPIABFunctions.cpp as HrAllocAdrList</para> /// <para name='Author'></para> /// <para name='LastModified'></para> /// </remarks> STDMETHODIMP ZybraxiSoft::CMailbox::AllocAdrList(ULONG ulNumProps, LPADRLIST * lpAdrList) { HRESULT hr = S_OK; LPADRLIST lpLocalAdrList = NULL; // HrAllocAdrList just nulls the out variable // *lpAdrList = NULL; // ...but I think, if it's not null, it should be freed(?) if (*lpAdrList) { FreePadrlist(*lpAdrList); *lpAdrList = NULL; } // Allocate memory for the new SRowSet structure if (SUCCEEDED(hr = MAPIAllocateBuffer( CbNewSRowSet(1), (LPVOID*)&lpLocalAdrList))) { // Zero out our SRowSet memory ZeroMemory(lpLocalAdrList, CbNewSRowSet(1)); // Allocate the memory for the internal SPropValue if (SUCCEEDED(hr = MAPIAllocateBuffer( ulNumProps * sizeof(SPropValue), (LPVOID*)&lpLocalAdrList->aEntries[0].rgPropVals))) { // Zero out our SPropValue if (lpLocalAdrList->aEntries[0].rgPropVals) ZeroMemory(lpLocalAdrList->aEntries[0].rgPropVals, ulNumProps * sizeof(SPropValue)); } else { FATAL("MAPIAllocateBuffer(SPropVal)", hr); FreePadrlist(lpLocalAdrList); } if (SUCCEEDED(hr)) { *lpAdrList = lpLocalAdrList; } else { FreePadrlist(lpLocalAdrList); } } else { FATAL(_T("MAPIAllocateBuffer(SRowSet)"), hr); } return hr; }
// @object PySPropValueArray|A sequence of <o PySPropValue>, as passed to many MAPI functions. BOOL PyMAPIObject_AsSPropValueArray(PyObject *obs, SPropValue **ppv, ULONG *pcValues) { int seqLen = PySequence_Length(obs); SPropValue *pPV; HRESULT hr; if (S_OK != (hr=MAPIAllocateBuffer(sizeof(SPropValue) * seqLen, (void **)&pPV))) { OleSetOleError(hr); return FALSE; } for (ULONG i=0; i<(ULONG)seqLen; i++) { PyObject *myob = PySequence_GetItem(obs, i); if (myob==NULL) { MAPIFreeBuffer(pPV); return FALSE; } BOOL rc = PyMAPIObject_AsSPropValue(myob, pPV+i, pPV); Py_DECREF(myob); if (!rc) { MAPIFreeBuffer(pPV); return FALSE; } } *pcValues = seqLen; *ppv = pPV; return TRUE; }
void CTagArrayEditor::WriteListToTagArray(ULONG ulListNum) { if (!IsValidList(ulListNum)) return; // If we're not dirty, don't write if (!IsDirty(ulListNum)) return; HRESULT hRes = S_OK; ULONG ulListCount = GetListCount(ulListNum); EC_H(MAPIAllocateBuffer( CbNewSPropTagArray(ulListCount), (LPVOID*)&m_lpOutputTagArray)); if (m_lpOutputTagArray) { m_lpOutputTagArray->cValues = ulListCount; ULONG iTagCount = 0; for (iTagCount = 0; iTagCount < m_lpOutputTagArray->cValues; iTagCount++) { SortListData* lpData = GetListRowData(ulListNum, iTagCount); if (lpData) m_lpOutputTagArray->aulPropTag[iTagCount] = lpData->data.Tag.ulPropTag; } } } // CTagArrayEditor::WriteListToTagArray
HRESULT MailboxDataCollector::GetRequiredPropTags(LPMAPIPROP lpProp, LPSPropTagArray *lppPropTagArray) const { HRESULT hr = hrSuccess; SPropTagArrayPtr ptrPropTagArray; PROPMAP_START PROPMAP_NAMED_ID(STORE_ENTRYIDS, PT_MV_BINARY, PSETID_Archive, "store-entryids") PROPMAP_NAMED_ID(ITEM_ENTRYIDS, PT_MV_BINARY, PSETID_Archive, "item-entryids") PROPMAP_INIT(lpProp); hr = MAPIAllocateBuffer(CbNewSPropTagArray(4), &ptrPropTagArray); if (hr != hrSuccess) goto exit; ptrPropTagArray->cValues = 4; ptrPropTagArray->aulPropTag[0] = PR_ENTRYID; ptrPropTagArray->aulPropTag[1] = PR_MAILBOX_OWNER_ENTRYID; ptrPropTagArray->aulPropTag[2] = PROP_STORE_ENTRYIDS; ptrPropTagArray->aulPropTag[3] = PROP_ITEM_ENTRYIDS; *lppPropTagArray = ptrPropTagArray.release(); exit: return hr; }
LPSPropValue Workshare::Mail::Mapi::GetMessageTag(LPMESSAGE lpMessage, const std::tstring& sTag) { LPSPropValue pPropVal = 0; IMAPIPropPtr spMapiProp; HRESULT hr = lpMessage->QueryInterface(IID_IMAPIProp, (void**) &spMapiProp); if(SUCCEEDED(hr)) { LPMAPINAMEID pTagName = 0; hr = MAPIAllocateBuffer(sizeof(MAPINAMEID), (LPVOID*)&pTagName); if(SUCCEEDED(hr)) { pTagName[0].lpguid = (LPGUID)&PS_PUBLIC_STRINGS; pTagName[0].ulKind = MNID_STRING; _bstr_t bsTag(sTag.c_str()); pTagName[0].Kind.lpwstrName = bsTag; LPSPropTagArray pPropTag = 0; hr = spMapiProp->GetIDsFromNames(1, &pTagName, 0, &pPropTag); if (!FAILED(hr)) { if(1 == pPropTag->cValues && PT_ERROR != PROP_TYPE(pPropTag->aulPropTag[0])) { ULONG ulCount = 0; spMapiProp->GetProps(pPropTag, 0, &ulCount, &pPropVal); } MAPIFreeBuffer(pPropTag); } MAPIFreeBuffer(pTagName); } } return pPropVal; }
/************************************************************************** * MAPIAllocateMore (MAPI32.14) * MAPIAllocateMore@12 (MAPI32.15) * * Allocate a block of memory linked to a previous allocation. * * PARAMS * cbSize [I] Size of the block to allocate in bytes * lpOrig [I] Initial allocation to link to, from MAPIAllocateBuffer() * lppBuffer [O] Destination for pointer to allocated memory * * RETURNS * Success: S_OK. *lppBuffer is filled with a pointer to a memory block of * length cbSize bytes. * Failure: MAPI_E_INVALID_PARAMETER, if lpOrig or lppBuffer is invalid. * MAPI_E_NOT_ENOUGH_MEMORY, if memory allocation fails. * * NOTES * Memory allocated with this function and stored in *lppBuffer is freed * when lpOrig is passed to MAPIFreeBuffer(). It should not be freed independently. */ SCODE WINAPI MAPIAllocateMore(ULONG cbSize, LPVOID lpOrig, LPVOID *lppBuffer) { LPMAPIALLOCBUFFER lpBuff = lpOrig; TRACE("(%d,%p,%p)\n", cbSize, lpOrig, lppBuffer); if (mapiFunctions.MAPIAllocateMore) return mapiFunctions.MAPIAllocateMore(cbSize, lpOrig, lppBuffer); if (!lppBuffer || !lpBuff || !--lpBuff) return E_INVALIDARG; /* Find the last allocation in the chain */ while (*lpBuff) { TRACE("linked:%p->%p\n", lpBuff, *lpBuff); lpBuff = *lpBuff; } if (SUCCEEDED(MAPIAllocateBuffer(cbSize, lppBuffer))) { *lpBuff = ((LPMAPIALLOCBUFFER)*lppBuffer) - 1; TRACE("linking %p->%p\n", lpBuff, *lpBuff); } return *lppBuffer ? S_OK : MAPI_E_NOT_ENOUGH_MEMORY; }
/** * Delete the messages that are queued for deletion. * @return HRESULT */ HRESULT Deleter::PurgeQueuedMessages() { HRESULT hr = hrSuccess; EntryListPtr ptrEntryList; list<entryid_t>::const_iterator iEntryId; ULONG ulIdx = 0; if (m_lstEntryIds.empty()) goto exit; hr = MAPIAllocateBuffer(sizeof(ENTRYLIST), &ptrEntryList); if (hr != hrSuccess) goto exit; hr = MAPIAllocateMore(m_lstEntryIds.size() * sizeof(SBinary), ptrEntryList, (LPVOID*)&ptrEntryList->lpbin); if (hr != hrSuccess) goto exit; ptrEntryList->cValues = m_lstEntryIds.size(); for (iEntryId = m_lstEntryIds.begin(); iEntryId != m_lstEntryIds.end(); ++iEntryId, ++ulIdx) { ptrEntryList->lpbin[ulIdx].cb = iEntryId->size(); ptrEntryList->lpbin[ulIdx].lpb = *iEntryId; } hr = CurrentFolder()->DeleteMessages(ptrEntryList, 0, NULL, 0); if (hr != hrSuccess) { Logger()->Log(EC_LOGLEVEL_FATAL, "Failed to delete %u messages. (hr=%s)", ptrEntryList->cValues, stringify(hr, true).c_str()); goto exit; } m_lstEntryIds.clear(); exit: return hr; }
void CAclDlg::OnAddItem() { HRESULT hRes = S_OK; CEditor MyData( this, IDS_ACLADDITEM, IDS_ACLADDITEMPROMPT, 2, CEDITOR_BUTTON_OK|CEDITOR_BUTTON_CANCEL); MyData.SetPromptPostFix(AllFlagsToString(PROP_ID(PR_MEMBER_RIGHTS),true)); MyData.InitPane(0, CreateSingleLinePane(IDS_USEREID, NULL, false)); MyData.InitPane(1, CreateSingleLinePane(IDS_MASKINHEX, NULL, false)); MyData.SetHex(1,0); WC_H(MyData.DisplayDialog()); if (S_OK != hRes) { DebugPrint(DBGGeneric,_T("OnAddItem cancelled.\n")); return; } LPROWLIST lpNewItem = NULL; EC_H(MAPIAllocateBuffer(CbNewROWLIST(1),(LPVOID*) &lpNewItem)); if (lpNewItem) { lpNewItem->cEntries = 1; lpNewItem->aEntries[0].ulRowFlags = ROW_ADD; lpNewItem->aEntries[0].cValues = 2; lpNewItem->aEntries[0].rgPropVals = 0; EC_H(MAPIAllocateMore(2 * sizeof(SPropValue), lpNewItem, (LPVOID*)&lpNewItem->aEntries[0].rgPropVals)); if (lpNewItem->aEntries[0].rgPropVals) { LPENTRYID lpEntryID = NULL; size_t cbBin = 0; EC_H(MyData.GetEntryID(0, false, &cbBin, &lpEntryID)); lpNewItem->aEntries[0].rgPropVals[0].ulPropTag = PR_MEMBER_ENTRYID; lpNewItem->aEntries[0].rgPropVals[0].Value.bin.cb = (ULONG)cbBin; lpNewItem->aEntries[0].rgPropVals[0].Value.bin.lpb = (LPBYTE)lpEntryID; lpNewItem->aEntries[0].rgPropVals[1].ulPropTag = PR_MEMBER_RIGHTS; lpNewItem->aEntries[0].rgPropVals[1].Value.ul = MyData.GetHex(1); EC_MAPI(m_lpExchTbl->ModifyTable( m_ulTableFlags, lpNewItem)); MAPIFreeBuffer(lpNewItem); if (S_OK == hRes) OnRefreshView(); delete[] lpEntryID; } } } // CAclDlg::OnAddItem
// @object PySBinaryArray|A sequence of strings containing binary data. BOOL PyMAPIObject_AsSBinaryArray(PyObject *ob, SBinaryArray *pba) { BOOL bSeq = TRUE; int seqLen; if (PyString_Check(ob)) { seqLen = 1; bSeq = FALSE; } else if (PySequence_Check(ob)) { seqLen = PySequence_Length(ob); } else { PyErr_SetString(PyExc_TypeError, "SBinaryArray must be a sequence of strings"); return FALSE; } DWORD cBytes = (seqLen * sizeof(SBinary)); SBinary *pBin; HRESULT hr = MAPIAllocateBuffer(cBytes, (void **)&pBin); pba->lpbin = pBin; if (FAILED(hr)) { OleSetOleError(hr); return FALSE; } pba->cValues = seqLen; if (bSeq) { for (ULONG i=0; i<(ULONG)seqLen; i++) { PyObject *obItem = PySequence_GetItem(ob, i); if (obItem==NULL) { MAPIFreeBuffer(pba); return FALSE; } if (!PyString_Check(obItem)) { PyErr_SetString(PyExc_TypeError, "SBinary must be a string"); Py_DECREF(obItem); MAPIFreeBuffer(pba); return FALSE; } pBin[i].cb = PyString_Size(obItem); pBin[i].lpb = (LPBYTE )PyString_AsString(obItem); Py_DECREF(obItem); } } else { if (!PyString_Check(ob)) { PyErr_SetString(PyExc_TypeError, "SBinary must be a string"); MAPIFreeBuffer(pba); return FALSE; } // Simple string pBin[0].cb = PyString_Size(ob); pBin[0].lpb = (LPBYTE)PyString_AsString(ob); } return TRUE; }
_Check_return_ HRESULT HrAllocAdrList(ULONG ulNumProps, _Deref_out_opt_ LPADRLIST* lpAdrList) { if (!lpAdrList || ulNumProps > ULONG_MAX / sizeof(SPropValue)) return MAPI_E_INVALID_PARAMETER; HRESULT hRes = S_OK; LPADRLIST lpLocalAdrList = NULL; *lpAdrList = NULL; // Allocate memory for new SRowSet structure. EC_H(MAPIAllocateBuffer(CbNewSRowSet(1), (LPVOID*)&lpLocalAdrList)); if (lpLocalAdrList) { // Zero out allocated memory. ZeroMemory(lpLocalAdrList, CbNewSRowSet(1)); // Allocate memory for SPropValue structure that indicates what // recipient properties will be set. EC_H(MAPIAllocateBuffer( ulNumProps * sizeof(SPropValue), (LPVOID*)&lpLocalAdrList->aEntries[0].rgPropVals)); // Zero out allocated memory. if (lpLocalAdrList->aEntries[0].rgPropVals) ZeroMemory(lpLocalAdrList->aEntries[0].rgPropVals, ulNumProps * sizeof(SPropValue)); if (SUCCEEDED(hRes)) { *lpAdrList = lpLocalAdrList; } else { FreePadrlist(lpLocalAdrList); } } return hRes; } // HrAllocAdrList
// @object PySPropTagArray|A sequence of integers BOOL PyMAPIObject_AsSPropTagArray(PyObject *obta, SPropTagArray **ppta) { if (obta==Py_None) { *ppta = NULL; return TRUE; } BOOL bSeq = TRUE; int seqLen; if (PySequence_Check(obta)) { seqLen = PySequence_Length(obta); } else if (PyInt_Check(obta)) { seqLen = 1; bSeq = FALSE; } else { PyErr_SetString(PyExc_TypeError, "SPropTagArray must be a sequence of integers"); return FALSE; } DWORD cBytes = (seqLen * sizeof(ULONG)) + sizeof(ULONG); SPropTagArray *pta; HRESULT hr = MAPIAllocateBuffer(cBytes, (void **)&pta); if (FAILED(hr)) { OleSetOleError(hr); return FALSE; } pta->cValues = seqLen; if (bSeq) { for (ULONG i=0; i<(ULONG)seqLen; i++) { PyObject *obItem = PySequence_GetItem(obta, i); if (obItem==NULL) { MAPIFreeBuffer(pta); return FALSE; } pta->aulPropTag[i] = PyInt_AsLong(obItem); if (PyErr_Occurred()) { Py_DECREF(obItem); MAPIFreeBuffer(pta); return FALSE; } Py_DECREF(obItem); } } else { // Simple int. pta->aulPropTag[0] = PyInt_AsLong(obta); } *ppta = pta; return TRUE; }
BOOL PyMAPIObject_AsSRestriction(PyObject *ob, SRestriction **pRest, BOOL bNoneOK /*= TRUE*/) { HRESULT hr; if (ob==Py_None) { if (bNoneOK) { *pRest = NULL; return TRUE; } else { PyErr_SetString(PyExc_ValueError, "None is not a valid SRestriction in this context"); return FALSE; } } if (S_OK != (hr=MAPIAllocateBuffer(sizeof(SRestriction), (void **)pRest))) { OleSetOleError(hr); return FALSE; } BOOL ok = PyMAPIObject_AsSingleSRestriction(ob, *pRest, *pRest); if (!ok) MAPIFreeBuffer(*pRest); return ok; }
void Workshare::Mail::Mapi::RemoveMessageTag(LPMESSAGE lpMessage, const std::tstring& sTag) { IMAPIPropPtr spMapiProp = lpMessage; if(spMapiProp == 0) throw Workshare::Exception(_T("Failed to extract the IID_IMAPIProp interface from lpMessage")); LPMAPINAMEID pTagName = 0; HRESULT hr = MAPIAllocateBuffer(sizeof(MAPINAMEID), (LPVOID*)&pTagName); if(FAILED(hr)) throw MapiException(hr, _T("Failed to allocate MAPI memory for the tag name")); pTagName[0].lpguid = (LPGUID)&PS_PUBLIC_STRINGS; pTagName[0].ulKind = MNID_STRING; _bstr_t bsTag(sTag.c_str()); pTagName[0].Kind.lpwstrName = bsTag; LPSPropTagArray pPropTag = 0; hr = spMapiProp->GetIDsFromNames(1, &pTagName, 0, &pPropTag); if(FAILED(hr)) { MAPIFreeBuffer(pTagName); std::tostringstream error; error << _T("Failed to determine the ID from the tag name \"") << sTag.c_str() << _T("\"") << std::ends; throw MapiException(hr, error.str().c_str()); } if(1 == pPropTag->cValues && PT_ERROR != PROP_TYPE(pPropTag->aulPropTag[0])) { spMapiProp->DeleteProps(pPropTag, 0); } else { std::tostringstream error; error << _T("Failed to delete the message tag \"") << sTag.c_str() << _T("\"") << std::ends; LOG_WS_INFO(error.str().c_str()); } MAPIFreeBuffer(pPropTag); MAPIFreeBuffer(pTagName); }
/** * Generates new UID and sets it in SpropValue structure * * @param[in] ulNamedTag Property tag to set in returned property * @param[in] base base for allocating memory, can be NULL and returned *lppPropVal must be freed using MAPIFreeBuffer * @param[out] lppPropVal returned SpropValue structure * @return MAPI error code */ HRESULT HrCreateGlobalID(ULONG ulNamedTag, void *base, LPSPropValue *lppPropVal) { HRESULT hr = hrSuccess; LPSPropValue lpPropVal = NULL; std::string strUid, strBinUid; if (base) { hr = MAPIAllocateMore(sizeof(SPropValue), base, (void**)&lpPropVal); } else { hr = MAPIAllocateBuffer(sizeof(SPropValue), (void**)&lpPropVal); base = lpPropVal; } if (hr != hrSuccess) goto exit; lpPropVal->ulPropTag = ulNamedTag; hr = HrGenerateUid(&strUid); if (hr != hrSuccess) goto exit; strBinUid = hex2bin(strUid); lpPropVal->Value.bin.cb = strBinUid.length(); hr = MAPIAllocateMore(lpPropVal->Value.bin.cb, base, (void**)&lpPropVal->Value.bin.lpb); if (hr != hrSuccess) goto exit; memcpy(lpPropVal->Value.bin.lpb, strBinUid.data(), lpPropVal->Value.bin.cb); *lppPropVal = lpPropVal; exit: if (hr != hrSuccess && lpPropVal) MAPIFreeBuffer(lpPropVal); return hr; }
//$--HrMAPICreateSizedAddressList------------------------------------------------ // Create a sized address list. // ----------------------------------------------------------------------------- HRESULT HrMAPICreateSizedAddressList( // RETURNS: return code IN ULONG cEntries, // count of entries in address list OUT LPADRLIST *lppAdrList) // pointer to address list pointer { HRESULT hr = NOERROR; SCODE sc = 0; ULONG cBytes = 0; DEBUGPUBLIC("HrMAPICreateAddressList()\n"); hr = CHK_HrMAPICreateSizedAddressList( cEntries, lppAdrList); if(FAILED(hr)) RETURN(hr); *lppAdrList = NULL; cBytes = CbNewADRLIST(cEntries); sc = MAPIAllocateBuffer(cBytes, (LPVOID*)lppAdrList); if(FAILED(sc)) { hr = HR_LOG(E_OUTOFMEMORY); goto cleanup; } // Initialize ADRLIST structure ZeroMemory(*lppAdrList, cBytes); (*lppAdrList)->cEntries = cEntries; cleanup: RETURN(hr); }
// @object PySSortOrderSet|An object describing a SortOrderSet. // @pyparm ( <o PySSortOrderItem>, ...)|sortItems||The items to sort by // @pyparm int|cCategories|0| // @pyparm int|cExpanded|0| BOOL PyMAPIObject_AsSSortOrderSet(PyObject *obsos, SSortOrderSet **ppsos, BOOL bNoneOK /*= TRUE */) { if (obsos==Py_None) { if (bNoneOK) { *ppsos = NULL; return TRUE; } else { PyErr_SetString(PyExc_ValueError, "None is not a valid SSortOrderSet in this context"); return FALSE; } } else { ULONG cCategories=0, cExpanded=0; PyObject *obSorts; if (!PyArg_ParseTuple(obsos, "O|ll", &obSorts, &cCategories, &cExpanded)) { PyErr_Clear(); PyErr_SetString(PyExc_TypeError, "A SortOrder object must be tuple of (sequence, cCategories=0, cExpanded=0)"); return FALSE; } if (!PySequence_Check(obSorts)) { PyErr_SetString(PyExc_TypeError, "The first object must be a sequence"); return FALSE; } ULONG numSorts = PySequence_Length(obSorts); HRESULT hr; if (S_OK != (hr=MAPIAllocateBuffer(sizeof(SSortOrderSet) + (sizeof(SSortOrder) * numSorts), (void **)ppsos))) { OleSetOleError(hr); return FALSE; } BOOL ok = TRUE; (*ppsos)->cSorts = numSorts; (*ppsos)->cCategories = cCategories; (*ppsos)->cExpanded = cExpanded; ok = ok && PyMAPIObject_BuildSSortOrderSet(obSorts, *ppsos); if (!ok) MAPIFreeBuffer(*ppsos); return ok; } }
// If the value is a string, get it... BOOL CMapiApi::GetEntryIdFromProp( LPSPropValue pVal, ULONG& cbEntryId, LPENTRYID& lpEntryId, BOOL delVal) { if (!pVal) return( FALSE); BOOL bResult = TRUE; switch( PROP_TYPE( pVal->ulPropTag)) { case PT_BINARY: cbEntryId = pVal->Value.bin.cb; MAPIAllocateBuffer( cbEntryId, (LPVOID *) &lpEntryId); memcpy( lpEntryId, pVal->Value.bin.lpb, cbEntryId); break; default: MAPI_TRACE0( "EntryId not in BINARY prop value\n"); bResult = FALSE; break; } if (pVal && delVal) MAPIFreeBuffer( pVal); return( bResult); }
HRESULT MAPITask::InitNamedPropsForTask() { // init named props nameIds[0] = 0x8126; nameIds[1] = 0x8116; nameIds[2] = 0x8101; nameIds[3] = 0x8102; nameIds[4] = 0x8104; nameIds[5] = 0x8105; nameIds[6] = 0x8111; nameIds[7] = 0x8110; nameIdsC[0] = 0x8539; nameIdsC[1] = 0x8534; nameIdsC[2] = 0x8535; nameIdsC[3] = 0x8503; nameIdsC[4] = 0x8560; nameIdsC[5] = 0x8506; HRESULT hr = S_OK; Zimbra::Util::ScopedBuffer<SPropValue> pPropValMsgClass; if (FAILED(hr = HrGetOneProp(m_pMessage, PR_MESSAGE_CLASS, pPropValMsgClass.getptr()))) throw MAPITaskException(hr, L"InitNamedPropsForTask(): HrGetOneProp Failed.", ERR_MAPI_TASK, __LINE__, __FILE__); // initialize the MAPINAMEID structure GetIDsFromNames requires LPMAPINAMEID ppNames[N_NUMTASKPROPS] = { 0 }; for (int i = 0; i < N_NUMTASKPROPS; i++) { MAPIAllocateBuffer(sizeof (MAPINAMEID), (LPVOID *)&(ppNames[i])); ppNames[i]->ulKind = MNID_ID; ppNames[i]->lpguid = (LPGUID)(&PS_OUTLOOK_TASK); ppNames[i]->Kind.lID = nameIds[i]; } LPMAPINAMEID ppNamesC[N_NUMCOMMONTPROPS] = { 0 }; for (int i = 0; i < N_NUMCOMMONTPROPS; i++) { MAPIAllocateBuffer(sizeof (MAPINAMEID), (LPVOID *)&(ppNamesC[i])); ppNamesC[i]->ulKind = MNID_ID; ppNamesC[i]->lpguid = (LPGUID)(&PS_OUTLOOK_COMMON); ppNamesC[i]->Kind.lID = nameIdsC[i]; } // get the real prop tag ID's LPSPropTagArray pTaskTags = NULL; LPSPropTagArray pTaskTagsC = NULL; if (FAILED(hr = m_pMessage->GetIDsFromNames(N_NUMTASKPROPS, ppNames, MAPI_CREATE, &pTaskTags))) throw MAPITaskException(hr, L"Init(): GetIDsFromNames on pTaskTags Failed.", ERR_MAPI_TASK, __LINE__, __FILE__); if (FAILED(hr = m_pMessage->GetIDsFromNames(N_NUMCOMMONTPROPS, ppNamesC, MAPI_CREATE, &pTaskTagsC))) throw MAPITaskException(hr, L"Init(): GetIDsFromNames on pAppointmentTagsC Failed.", ERR_MAPI_TASK, __LINE__, __FILE__); // give the prop tag ID's a type pr_isrecurringt = SetPropType(pTaskTags->aulPropTag[N_ISRECURT], PT_BOOLEAN); pr_recurstreamt = SetPropType(pTaskTags->aulPropTag[N_RECURSTREAMT], PT_BINARY); pr_status = SetPropType(pTaskTags->aulPropTag[N_STATUS], PT_LONG); pr_percentcomplete = SetPropType(pTaskTags->aulPropTag[N_PERCENTCOMPLETE], PT_DOUBLE); pr_taskstart = SetPropType(pTaskTags->aulPropTag[N_TASKSTART], PT_SYSTIME); pr_taskdue = SetPropType(pTaskTags->aulPropTag[N_TASKDUE], PT_SYSTIME); pr_totalwork = SetPropType(pTaskTags->aulPropTag[N_TOTALWORK], PT_LONG); pr_actualwork = SetPropType(pTaskTags->aulPropTag[N_ACTUALWORK], PT_LONG); pr_companies = SetPropType(pTaskTagsC->aulPropTag[N_COMPANIES], PT_MV_TSTRING); pr_mileage = SetPropType(pTaskTagsC->aulPropTag[N_MILEAGE], PT_TSTRING); pr_billinginfo = SetPropType(pTaskTagsC->aulPropTag[N_BILLING], PT_TSTRING); pr_taskreminderset = SetPropType(pTaskTagsC->aulPropTag[N_TASKREMINDERSET], PT_BOOLEAN); pr_taskflagdueby = SetPropType(pTaskTagsC->aulPropTag[N_TASKFLAGDUEBY], PT_SYSTIME); pr_private = SetPropType(pTaskTagsC->aulPropTag[N_TPRIVATE], PT_BOOLEAN); // free the memory we allocated on the head for (int i = 0; i < N_NUMTASKPROPS; i++) { MAPIFreeBuffer(ppNames[i]); } for (int i = 0; i < N_NUMCOMMONTPROPS; i++) { MAPIFreeBuffer(ppNamesC[i]); } MAPIFreeBuffer(pTaskTags); MAPIFreeBuffer(pTaskTagsC); //MAPITask::m_bNamedPropsInitialized = true; return S_OK; }
HRESULT MAPIAppointment::InitNamedPropsForAppt() { // init named props nameIds[0] = 0x0023; nameIds[1] = 0x820D; nameIds[2] = 0x820E; nameIds[3] = 0x8208; nameIds[4] = 0x8205; nameIds[5] = 0x8215; nameIds[6] = 0x8223; nameIds[7] = 0x8216; nameIds[8] = 0x8234; nameIds[9] = 0x8218; nameIds[10] = 0x8228; nameIdsC[0] = 0x8501; nameIdsC[1] = 0x8506; nameIdsC[2] = 0x8503; HRESULT hr = S_OK; Zimbra::Util::ScopedBuffer<SPropValue> pPropValMsgClass; if (FAILED(hr = HrGetOneProp(m_pMessage, PR_MESSAGE_CLASS, pPropValMsgClass.getptr()))) throw MAPIAppointmentException(hr, L"InitNamedPropsForAppt(): HrGetOneProp Failed.", ERR_MAPI_APPOINTMENT, __LINE__, __FILE__); // initialize the MAPINAMEID structure GetIDsFromNames requires LPMAPINAMEID ppNames[N_NUMAPPTPROPS] = { 0 }; for (int i = 0; i < N_NUMAPPTPROPS; i++) { MAPIAllocateBuffer(sizeof (MAPINAMEID), (LPVOID *)&(ppNames[i])); ppNames[i]->ulKind = MNID_ID; ppNames[i]->lpguid = (i == N_UID) ? (LPGUID)(&PS_OUTLOOK_MTG) : (LPGUID)(&PS_OUTLOOK_APPT); ppNames[i]->Kind.lID = nameIds[i]; } LPMAPINAMEID ppNamesC[N_NUMCOMMONPROPS] = { 0 }; for (int i = 0; i < N_NUMCOMMONPROPS; i++) { MAPIAllocateBuffer(sizeof (MAPINAMEID), (LPVOID *)&(ppNamesC[i])); ppNamesC[i]->ulKind = MNID_ID; ppNamesC[i]->lpguid = (LPGUID)(&PS_OUTLOOK_COMMON); ppNamesC[i]->Kind.lID = nameIdsC[i]; } // get the real prop tag ID's LPSPropTagArray pAppointmentTags = NULL; LPSPropTagArray pAppointmentTagsC = NULL; if (FAILED(hr = m_pMessage->GetIDsFromNames(N_NUMAPPTPROPS, ppNames, MAPI_CREATE, &pAppointmentTags))) throw MAPIAppointmentException(hr, L"Init(): GetIDsFromNames on pAppointmentTags Failed.", ERR_MAPI_APPOINTMENT, __LINE__, __FILE__); if (FAILED(hr = m_pMessage->GetIDsFromNames(N_NUMCOMMONPROPS, ppNamesC, MAPI_CREATE, &pAppointmentTagsC))) throw MAPIAppointmentException(hr, L"Init(): GetIDsFromNames on pAppointmentTagsC Failed.", ERR_MAPI_APPOINTMENT, __LINE__, __FILE__); // give the prop tag ID's a type pr_clean_global_objid = SetPropType(pAppointmentTags->aulPropTag[N_UID], PT_BINARY); pr_appt_start = SetPropType(pAppointmentTags->aulPropTag[N_APPTSTART], PT_SYSTIME); pr_appt_end = SetPropType(pAppointmentTags->aulPropTag[N_APPTEND], PT_SYSTIME); pr_location = SetPropType(pAppointmentTags->aulPropTag[N_LOCATION], PT_TSTRING); pr_busystatus = SetPropType(pAppointmentTags->aulPropTag[N_BUSYSTATUS], PT_LONG); pr_allday = SetPropType(pAppointmentTags->aulPropTag[N_ALLDAY], PT_BOOLEAN); pr_isrecurring = SetPropType(pAppointmentTags->aulPropTag[N_ISRECUR], PT_BOOLEAN); pr_recurstream = SetPropType(pAppointmentTags->aulPropTag[N_RECURSTREAM], PT_BINARY); pr_timezoneid = SetPropType(pAppointmentTags->aulPropTag[N_TIMEZONEID], PT_TSTRING); pr_responsestatus = SetPropType(pAppointmentTags->aulPropTag[N_RESPONSESTATUS], PT_LONG); pr_exceptionreplacetime = SetPropType(pAppointmentTags->aulPropTag[N_EXCEPTIONREPLACETIME], PT_SYSTIME); pr_reminderminutes = SetPropType(pAppointmentTagsC->aulPropTag[N_REMINDERMINUTES], PT_LONG); pr_private = SetPropType(pAppointmentTagsC->aulPropTag[N_PRIVATE], PT_BOOLEAN); pr_reminderset = SetPropType(pAppointmentTagsC->aulPropTag[N_REMINDERSET], PT_BOOLEAN); // free the memory we allocated on the head for (int i = 0; i < N_NUMAPPTPROPS; i++) { MAPIFreeBuffer(ppNames[i]); } for (int i = 0; i < N_NUMCOMMONPROPS; i++) { MAPIFreeBuffer(ppNamesC[i]); } MAPIFreeBuffer(pAppointmentTags); MAPIFreeBuffer(pAppointmentTagsC); //MAPIAppointment::m_bNamedPropsInitialized = true; return S_OK; }
_Check_return_ HRESULT CRulesDlg::GetSelectedItems(ULONG ulFlags, ULONG ulRowFlags, _In_ LPROWLIST* lppRowList) { if (!lppRowList || !m_lpContentsTableListCtrl) return MAPI_E_INVALID_PARAMETER; *lppRowList = NULL; HRESULT hRes = S_OK; int iNumItems = m_lpContentsTableListCtrl->GetSelectedCount(); if (!iNumItems) return S_OK; if (iNumItems > MAXNewROWLIST) return MAPI_E_INVALID_PARAMETER; LPROWLIST lpTempList = NULL; EC_H(MAPIAllocateBuffer(CbNewROWLIST(iNumItems),(LPVOID*) &lpTempList)); if (lpTempList) { lpTempList->cEntries = iNumItems; int iArrayPos = 0; int iSelectedItem = -1; for (iArrayPos = 0 ; iArrayPos < iNumItems ; iArrayPos++) { lpTempList->aEntries[iArrayPos].ulRowFlags = ulRowFlags; lpTempList->aEntries[iArrayPos].cValues = 0; lpTempList->aEntries[iArrayPos].rgPropVals = 0; iSelectedItem = m_lpContentsTableListCtrl->GetNextItem( iSelectedItem, LVNI_SELECTED); if (-1 != iSelectedItem) { SortListData* lpData = (SortListData*) m_lpContentsTableListCtrl->GetItemData(iSelectedItem); if (lpData) { if (ulFlags & RULE_INCLUDE_ID && ulFlags & RULE_INCLUDE_OTHER) { EC_H(MAPIAllocateMore( lpData->cSourceProps * sizeof(SPropValue), lpTempList, (LPVOID*) &lpTempList->aEntries[iArrayPos].rgPropVals)); if (SUCCEEDED(hRes) && lpTempList->aEntries[iArrayPos].rgPropVals) { ULONG ulSrc = 0; ULONG ulDst = 0; for (ulSrc = 0; ulSrc < lpData->cSourceProps; ulSrc++) { if (lpData->lpSourceProps[ulSrc].ulPropTag == PR_RULE_PROVIDER_DATA) { if (!lpData->lpSourceProps[ulSrc].Value.bin.cb || !lpData->lpSourceProps[ulSrc].Value.bin.lpb) { // PR_RULE_PROVIDER_DATA was NULL - we don't want this continue; } } EC_H(MyPropCopyMore( &lpTempList->aEntries[iArrayPos].rgPropVals[ulDst], &lpData->lpSourceProps[ulSrc], MAPIAllocateMore, lpTempList)); ulDst++; } lpTempList->aEntries[iArrayPos].cValues = ulDst; } } else if (ulFlags & RULE_INCLUDE_ID) { lpTempList->aEntries[iArrayPos].cValues = 1; lpTempList->aEntries[iArrayPos].rgPropVals = PpropFindProp( lpData->lpSourceProps, lpData->cSourceProps, PR_RULE_ID); } } } } } *lppRowList = lpTempList; return hRes; } // CRulesDlg::GetSelectedItems
// Same as CreatePropertyStringRestriction, but skips the existence part. _Check_return_ HRESULT CreateANRRestriction(ULONG ulPropTag, _In_z_ LPCTSTR szString, _In_opt_ LPVOID lpParent, _Deref_out_opt_ LPSRestriction* lppRes) { HRESULT hRes = S_OK; LPSRestriction lpRes = NULL; LPSPropValue lpspvSubject = NULL; LPVOID lpAllocationParent = NULL; *lppRes = NULL; // Allocate and create our SRestriction // Allocate base memory: if (lpParent) { EC_H(MAPIAllocateMore( sizeof(SRestriction), lpParent, (LPVOID*)&lpRes)); lpAllocationParent = lpParent; } else { EC_H(MAPIAllocateBuffer( sizeof(SRestriction), (LPVOID*)&lpRes)); lpAllocationParent = lpRes; } EC_H(MAPIAllocateMore( sizeof(SPropValue), lpAllocationParent, (LPVOID*)&lpspvSubject)); if (lpRes && lpspvSubject) { // Zero out allocated memory. ZeroMemory(lpRes, sizeof(SRestriction)); ZeroMemory(lpspvSubject, sizeof(SPropValue)); // Root Node lpRes->rt = RES_PROPERTY; lpRes->res.resProperty.relop = RELOP_EQ; lpRes->res.resProperty.ulPropTag = ulPropTag; lpRes->res.resProperty.lpProp = lpspvSubject; // Allocate and fill out properties: lpspvSubject->ulPropTag = ulPropTag; lpspvSubject->Value.LPSZ = NULL; if (szString) { EC_H(CopyString( &lpspvSubject->Value.LPSZ, szString, lpAllocationParent)); } DebugPrint(DBGGeneric, _T("CreateANRRestriction built restriction:\n")); DebugPrintRestriction(DBGGeneric, lpRes, NULL); *lppRes = lpRes; } if (hRes != S_OK) { DebugPrint(DBGGeneric, _T("Failed to create restriction\n")); MAPIFreeBuffer(lpRes); *lppRes = NULL; } return hRes; } // CreateANRRestriction
// 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
HRESULT MAPIContact::Init() { HRESULT hr = S_OK; Zimbra::Util::ScopedBuffer<SPropValue> pPropValMsgClass; if (FAILED(hr = HrGetOneProp(m_pMessage, PR_MESSAGE_CLASS, pPropValMsgClass.getptr()))) throw MAPIContactException(hr, L"Init(): HrGetOneProp Failed.", ERR_MAPI_CONTACT, __LINE__, __FILE__); if ((pPropValMsgClass->ulPropTag == PR_MESSAGE_CLASS_W) && (_tcsicmp( pPropValMsgClass->Value.LPSZ, L"ipm.distlist") == 0)) m_bPersonalDL = true; // initialize the MAPINAMEID structure GetIDsFromNames requires LPMAPINAMEID ppNames[N_NUM_NAMES] = { 0 }; for (int i = 0; i < N_NUM_NAMES; i++) { MAPIAllocateBuffer(sizeof (MAPINAMEID), (LPVOID *)&(ppNames[i])); ppNames[i]->ulKind = MNID_ID; ppNames[i]->lpguid = (LPGUID)(&PS_CONTACT_PROPERTIES); ppNames[i]->Kind.lID = nameIds[i]; } // get the real prop tag ID's LPSPropTagArray pContactTags = NULL; if (FAILED(hr = m_pMessage->GetIDsFromNames(N_NUM_NAMES, ppNames, MAPI_CREATE, &pContactTags))) throw MAPIContactException(hr, L"Init(): GetIDsFromNames Failed.", ERR_MAPI_CONTACT, __LINE__, __FILE__); // give the prop tag ID's a type pr_mail1address = SetPropType(pContactTags->aulPropTag[N_MAIL1], PT_TSTRING); pr_mail1entryid = SetPropType(pContactTags->aulPropTag[N_MAIL1EID], PT_BINARY); pr_mail1type = SetPropType(pContactTags->aulPropTag[N_MAIL1TYPE], PT_TSTRING); pr_mail1dispname = SetPropType(pContactTags->aulPropTag[N_MAIL1DISPNAME], PT_TSTRING); pr_mail2address = SetPropType(pContactTags->aulPropTag[N_MAIL2], PT_TSTRING); pr_mail2entryid = SetPropType(pContactTags->aulPropTag[N_MAIL2EID], PT_BINARY); pr_mail2type = SetPropType(pContactTags->aulPropTag[N_MAIL2TYPE], PT_TSTRING); pr_mail2dispname = SetPropType(pContactTags->aulPropTag[N_MAIL2DISPNAME], PT_TSTRING); pr_mail3address = SetPropType(pContactTags->aulPropTag[N_MAIL3], PT_TSTRING); pr_mail3entryid = SetPropType(pContactTags->aulPropTag[N_MAIL3EID], PT_BINARY); pr_mail3type = SetPropType(pContactTags->aulPropTag[N_MAIL3TYPE], PT_TSTRING); pr_mail3dispname = SetPropType(pContactTags->aulPropTag[N_MAIL3DISPNAME], PT_TSTRING); pr_fileas = SetPropType(pContactTags->aulPropTag[N_FILEAS], PT_TSTRING); pr_fileasID = SetPropType(pContactTags->aulPropTag[N_FILEAS_ID], PT_LONG); pr_business_address_city = SetPropType(pContactTags->aulPropTag[N_BUS_CITY], PT_TSTRING); pr_business_address_country = SetPropType(pContactTags->aulPropTag[N_BUS_COUNTRY], PT_TSTRING); pr_business_address_postal_code = SetPropType(pContactTags->aulPropTag[N_BUS_ZIP], PT_TSTRING); pr_business_address_state = SetPropType(pContactTags->aulPropTag[N_BUS_STATE], PT_TSTRING); pr_business_address_street = SetPropType(pContactTags->aulPropTag[N_BUS_STREET], PT_TSTRING); pr_contact_user1_idx = SetPropType(pContactTags->aulPropTag[N_CONTACT_USER1_IDX], PT_TSTRING); pr_contact_user2_idx = SetPropType(pContactTags->aulPropTag[N_CONTACT_USER2_IDX], PT_TSTRING); pr_contact_user3_idx = SetPropType(pContactTags->aulPropTag[N_CONTACT_USER3_IDX], PT_TSTRING); pr_contact_user4_idx = SetPropType(pContactTags->aulPropTag[N_CONTACT_USER4_IDX], PT_TSTRING); pr_contact_oneoffmemebrs = SetPropType( pContactTags->aulPropTag[N_CONTACT_ONEOFFMEMEBRS_IDX], PT_MV_BINARY); pr_imaddress = SetPropType(pContactTags->aulPropTag[N_IMADDRESS], PT_TSTRING); pr_anniversary = SetPropType(pContactTags->aulPropTag[N_ANNIVERSARY], PT_TSTRING); // free the memory we allocated on the head for (int i = 0; i < N_NUM_NAMES; i++) MAPIFreeBuffer(ppNames[i]); MAPIFreeBuffer(pContactTags); // these are the contact properties we need to get SizedSPropTagArray(C_NUM_PROPS, contactProps) = { C_NUM_PROPS, { PR_CALLBACK_TELEPHONE_NUMBER, PR_CAR_TELEPHONE_NUMBER, PR_COMPANY_NAME, pr_mail1address, pr_mail1entryid, pr_mail1type, pr_mail1dispname, pr_mail2address, pr_mail2entryid, pr_mail2type, pr_mail2dispname, pr_mail3address, pr_mail3entryid, pr_mail3type, pr_mail3dispname, pr_fileas, pr_fileasID, PR_GIVEN_NAME, PR_HOME_ADDRESS_CITY, PR_HOME_ADDRESS_COUNTRY, PR_HOME_FAX_NUMBER, PR_HOME_TELEPHONE_NUMBER, PR_HOME2_TELEPHONE_NUMBER, PR_HOME_ADDRESS_POSTAL_CODE, PR_HOME_ADDRESS_STATE_OR_PROVINCE, PR_HOME_ADDRESS_STREET, PR_TITLE, PR_SURNAME, PR_MIDDLE_NAME, PR_CELLULAR_TELEPHONE_NUMBER, PR_DISPLAY_NAME_PREFIX, PR_GENERATION, // notes is PR_BODY and PR_BODY_HTML PR_OTHER_ADDRESS_CITY, PR_OTHER_ADDRESS_COUNTRY, PR_PRIMARY_FAX_NUMBER, // other fax PR_OTHER_TELEPHONE_NUMBER, PR_OTHER_ADDRESS_POSTAL_CODE, PR_OTHER_ADDRESS_STATE_OR_PROVINCE, PR_OTHER_ADDRESS_STREET, PR_PAGER_TELEPHONE_NUMBER, pr_business_address_city, pr_business_address_country, PR_BUSINESS_FAX_NUMBER, PR_OFFICE_TELEPHONE_NUMBER, pr_business_address_postal_code, pr_business_address_state, pr_business_address_street, PR_BUSINESS_HOME_PAGE, PR_BIRTHDAY, pr_contact_user1_idx, pr_contact_user2_idx, pr_contact_user3_idx, pr_contact_user4_idx, pr_contact_oneoffmemebrs, pr_imaddress, PR_WEDDING_ANNIVERSARY } }; ULONG cVals = 0; if (FAILED(hr = m_pMessage->GetProps((LPSPropTagArray) & contactProps, fMapiUnicode, &cVals, &m_pPropVals))) throw MAPIContactException(hr, L"Init(): GetProps Failed.", ERR_MAPI_CONTACT, __LINE__, __FILE__); // see if there is a file-as id LONG zimbraFileAsId = 0; if (m_bPersonalDL) // PDL's always have a custom file-as { zimbraFileAsId = 8; Type(L"group"); } else if (m_pPropVals[C_FILEASID].ulPropTag == contactProps.aulPropTag[C_FILEASID]) { switch (m_pPropVals[C_FILEASID].Value.l) { case OFA_LAST_C_FIRST: zimbraFileAsId = 1; break; case OFA_FIRST_LAST: zimbraFileAsId = 2; break; case OFA_COMPANY: zimbraFileAsId = 3; break; case OFA_LAST_C_FIRST_COMPANY: zimbraFileAsId = 4; break; case OFA_COMPANY_LAST_C_FIRST: zimbraFileAsId = 6; break; case OFA_CUSTOM: zimbraFileAsId = 8; break; } } // process all "String" properties if (m_pPropVals[C_CALLBACK_TELEPHONE_NUMBER].ulPropTag == contactProps.aulPropTag[C_CALLBACK_TELEPHONE_NUMBER]) CallbackPhone(m_pPropVals[C_CALLBACK_TELEPHONE_NUMBER].Value.lpszW); if (m_pPropVals[C_CAR_TELEPHONE_NUMBER].ulPropTag == contactProps.aulPropTag[C_CAR_TELEPHONE_NUMBER]) CarPhone(m_pPropVals[C_CAR_TELEPHONE_NUMBER].Value.lpszW); if (m_pPropVals[C_COMPANY_NAME].ulPropTag == contactProps.aulPropTag[C_COMPANY_NAME]) Company(m_pPropVals[C_COMPANY_NAME].Value.lpszW); if (m_pPropVals[C_FILEAS].ulPropTag == contactProps.aulPropTag[C_FILEAS]) { if (zimbraFileAsId == 8) { LPWSTR pwszFileAsValue = m_pPropVals[C_FILEAS].Value.lpszW; if ((pwszFileAsValue != NULL) && (wcsicmp(pwszFileAsValue, L"") != 0)) { LPWSTR pwszTemp = new WCHAR[wcslen(m_pPropVals[C_FILEAS].Value.lpszW) + 3]; // there is a legit string for the custom fileas value wsprintf(pwszTemp, L"8:%s", pwszFileAsValue); FileAs(pwszTemp); // PDL's require a nickname if (m_bPersonalDL) NickName(m_pPropVals[C_FILEAS].Value.lpszW); delete[] pwszTemp; } else { LPWSTR pwszNONAME = new WCHAR[wcslen(L"NO_NAME") + 1]; wsprintf(pwszNONAME, L"%s", L"NO_NAME"); LPWSTR pwszTemp = new WCHAR[wcslen(pwszNONAME) + 3]; // there is a legit string for the custom fileas value wsprintf(pwszTemp, L"8:%s", pwszNONAME); FileAs(pwszTemp); // PDL's require a nickname if (m_bPersonalDL) NickName(pwszNONAME); delete[] pwszTemp; delete[] pwszNONAME; } } else if (zimbraFileAsId) { WCHAR pwszTemp[3]; _ltow(zimbraFileAsId, pwszTemp, 10); FileAs(pwszTemp); } } if (m_pPropVals[C_GIVEN_NAME].ulPropTag == contactProps.aulPropTag[C_GIVEN_NAME]) FirstName(m_pPropVals[C_GIVEN_NAME].Value.lpszW); if (m_pPropVals[C_HOME_ADDRESS_CITY].ulPropTag == contactProps.aulPropTag[C_HOME_ADDRESS_CITY]) HomeCity(m_pPropVals[C_HOME_ADDRESS_CITY].Value.lpszW); if (m_pPropVals[C_HOME_ADDRESS_COUNTRY].ulPropTag == contactProps.aulPropTag[C_HOME_ADDRESS_COUNTRY]) HomeCountry(m_pPropVals[C_HOME_ADDRESS_COUNTRY].Value.lpszW); if (m_pPropVals[C_HOME_FAX_NUMBER].ulPropTag == contactProps.aulPropTag[C_HOME_FAX_NUMBER]) HomeFax(m_pPropVals[C_HOME_FAX_NUMBER].Value.lpszW); if (m_pPropVals[C_HOME_TELEPHONE_NUMBER].ulPropTag == contactProps.aulPropTag[C_HOME_TELEPHONE_NUMBER]) HomePhone(m_pPropVals[C_HOME_TELEPHONE_NUMBER].Value.lpszW); if (m_pPropVals[C_HOME2_TELEPHONE_NUMBER].ulPropTag == contactProps.aulPropTag[C_HOME2_TELEPHONE_NUMBER]) HomePhone2(m_pPropVals[C_HOME2_TELEPHONE_NUMBER].Value.lpszW); if (m_pPropVals[C_HOME_ADDRESS_POSTAL_CODE].ulPropTag == contactProps.aulPropTag[C_HOME_ADDRESS_POSTAL_CODE]) HomePostalCode(m_pPropVals[C_HOME_ADDRESS_POSTAL_CODE].Value.lpszW); if (m_pPropVals[C_HOME_ADDRESS_STATE_OR_PROVINCE].ulPropTag == contactProps.aulPropTag[C_HOME_ADDRESS_STATE_OR_PROVINCE]) HomeState(m_pPropVals[C_HOME_ADDRESS_STATE_OR_PROVINCE].Value.lpszW); if (m_pPropVals[C_HOME_ADDRESS_STREET].ulPropTag == contactProps.aulPropTag[C_HOME_ADDRESS_STREET]) HomeStreet(m_pPropVals[C_HOME_ADDRESS_STREET].Value.lpszW); if (m_pPropVals[C_TITLE].ulPropTag == contactProps.aulPropTag[C_TITLE]) JobTitle(m_pPropVals[C_TITLE].Value.lpszW); if (m_pPropVals[C_SURNAME].ulPropTag == contactProps.aulPropTag[C_SURNAME]) LastName(m_pPropVals[C_SURNAME].Value.lpszW); if (m_pPropVals[C_MIDDLE_NAME].ulPropTag == contactProps.aulPropTag[C_MIDDLE_NAME]) MiddleName(m_pPropVals[C_MIDDLE_NAME].Value.lpszW); if (m_pPropVals[C_CELLULAR_TELEPHONE_NUMBER].ulPropTag == contactProps.aulPropTag[C_CELLULAR_TELEPHONE_NUMBER]) MobilePhone(m_pPropVals[C_CELLULAR_TELEPHONE_NUMBER].Value.lpszW); if (m_pPropVals[C_DISPLAY_NAME_PREFIX].ulPropTag == contactProps.aulPropTag[C_DISPLAY_NAME_PREFIX]) NamePrefix(m_pPropVals[C_DISPLAY_NAME_PREFIX].Value.lpszW); if (m_pPropVals[C_GENERATION].ulPropTag == contactProps.aulPropTag[C_GENERATION]) NameSuffix(m_pPropVals[C_GENERATION].Value.lpszW); if (m_pPropVals[C_OTHER_ADDRESS_CITY].ulPropTag == contactProps.aulPropTag[C_OTHER_ADDRESS_CITY]) OtherCity(m_pPropVals[C_OTHER_ADDRESS_CITY].Value.lpszW); if (m_pPropVals[C_OTHER_ADDRESS_COUNTRY].ulPropTag == contactProps.aulPropTag[C_OTHER_ADDRESS_COUNTRY]) OtherCountry(m_pPropVals[C_OTHER_ADDRESS_COUNTRY].Value.lpszW); if (m_pPropVals[C_PRIMARY_FAX_NUMBER].ulPropTag == contactProps.aulPropTag[C_PRIMARY_FAX_NUMBER]) OtherFax(m_pPropVals[C_PRIMARY_FAX_NUMBER].Value.lpszW); if (m_pPropVals[C_OTHER_TELEPHONE_NUMBER].ulPropTag == contactProps.aulPropTag[C_OTHER_TELEPHONE_NUMBER]) OtherPhone(m_pPropVals[C_OTHER_TELEPHONE_NUMBER].Value.lpszW); if (m_pPropVals[C_OTHER_ADDRESS_POSTAL_CODE].ulPropTag == contactProps.aulPropTag[C_OTHER_ADDRESS_POSTAL_CODE]) OtherPostalCode(m_pPropVals[C_OTHER_ADDRESS_POSTAL_CODE].Value.lpszW); if (m_pPropVals[C_OTHER_ADDRESS_STATE_OR_PROVINCE].ulPropTag == contactProps.aulPropTag[C_OTHER_ADDRESS_STATE_OR_PROVINCE]) OtherState(m_pPropVals[C_OTHER_ADDRESS_STATE_OR_PROVINCE].Value.lpszW); if (m_pPropVals[C_OTHER_ADDRESS_STREET].ulPropTag == contactProps.aulPropTag[C_OTHER_ADDRESS_STREET]) OtherStreet(m_pPropVals[C_OTHER_ADDRESS_STREET].Value.lpszW); if (m_pPropVals[C_PAGER_TELEPHONE_NUMBER].ulPropTag == contactProps.aulPropTag[C_PAGER_TELEPHONE_NUMBER]) Pager(m_pPropVals[C_PAGER_TELEPHONE_NUMBER].Value.lpszW); if (m_pPropVals[C_BUSINESS_ADDRESS_CITY].ulPropTag == contactProps.aulPropTag[C_BUSINESS_ADDRESS_CITY]) WorkCity(m_pPropVals[C_BUSINESS_ADDRESS_CITY].Value.lpszW); if (m_pPropVals[C_BUSINESS_ADDRESS_COUNTRY].ulPropTag == contactProps.aulPropTag[C_BUSINESS_ADDRESS_COUNTRY]) WorkCountry(m_pPropVals[C_BUSINESS_ADDRESS_COUNTRY].Value.lpszW); if (m_pPropVals[C_BUSINESS_FAX_NUMBER].ulPropTag == contactProps.aulPropTag[C_BUSINESS_FAX_NUMBER]) WorkFax(m_pPropVals[C_BUSINESS_FAX_NUMBER].Value.lpszW); if (m_pPropVals[C_OFFICE_TELEPHONE_NUMBER].ulPropTag == contactProps.aulPropTag[C_OFFICE_TELEPHONE_NUMBER]) WorkPhone(m_pPropVals[C_OFFICE_TELEPHONE_NUMBER].Value.lpszW); if (m_pPropVals[C_BUSINESS_ADDRESS_POSTAL_CODE].ulPropTag == contactProps.aulPropTag[C_BUSINESS_ADDRESS_POSTAL_CODE]) WorkPostalCode(m_pPropVals[C_BUSINESS_ADDRESS_POSTAL_CODE].Value.lpszW); if (m_pPropVals[C_BUSINESS_ADDRESS_STATE].ulPropTag == contactProps.aulPropTag[C_BUSINESS_ADDRESS_STATE]) WorkState(m_pPropVals[C_BUSINESS_ADDRESS_STATE].Value.lpszW); if (m_pPropVals[C_BUSINESS_ADDRESS_STREET].ulPropTag == contactProps.aulPropTag[C_BUSINESS_ADDRESS_STREET]) WorkStreet(m_pPropVals[C_BUSINESS_ADDRESS_STREET].Value.lpszW); if (m_pPropVals[C_BUSINESS_HOME_PAGE].ulPropTag == contactProps.aulPropTag[C_BUSINESS_HOME_PAGE]) WorkURL(m_pPropVals[C_BUSINESS_HOME_PAGE].Value.lpszW); if (m_pPropVals[C_CONTACT_USER1_IDX].ulPropTag == contactProps.aulPropTag[C_CONTACT_USER1_IDX]) UserField1(m_pPropVals[C_CONTACT_USER1_IDX].Value.lpszW); if (m_pPropVals[C_CONTACT_USER2_IDX].ulPropTag == contactProps.aulPropTag[C_CONTACT_USER2_IDX]) UserField2(m_pPropVals[C_CONTACT_USER2_IDX].Value.lpszW); if (m_pPropVals[C_CONTACT_USER3_IDX].ulPropTag == contactProps.aulPropTag[C_CONTACT_USER3_IDX]) UserField3(m_pPropVals[C_CONTACT_USER3_IDX].Value.lpszW); if (m_pPropVals[C_CONTACT_USER4_IDX].ulPropTag == contactProps.aulPropTag[C_CONTACT_USER4_IDX]) UserField4(m_pPropVals[C_CONTACT_USER4_IDX].Value.lpszW); if (m_pPropVals[C_BIRTHDAY].ulPropTag == contactProps.aulPropTag[C_BIRTHDAY]) { SYSTEMTIME st = { 0 }; FileTimeToSystemTime(&(m_pPropVals[C_BIRTHDAY].Value.ft), &st); // We get PR_BIRTHDAY in UTC so let's convert it into local time TIME_ZONE_INFORMATION tzInfo = { 0 }; GetTimeZoneInformation(&tzInfo); SystemTimeToTzSpecificLocalTime(&tzInfo, &st, &st); TCHAR pszBDay[11]; swprintf(pszBDay, 11, _T("%4d-%02d-%02d"), st.wYear, st.wMonth, st.wDay); Birthday(pszBDay); } if (m_pPropVals[C_ANNIVERSARY].ulPropTag == contactProps.aulPropTag[C_ANNIVERSARY]) { SYSTEMTIME st = { 0 }; FileTimeToSystemTime(&(m_pPropVals[C_ANNIVERSARY].Value.ft), &st); // We get PR_ANNIVERSARY in UTC so let's convert it into local time TIME_ZONE_INFORMATION tzInfo = { 0 }; GetTimeZoneInformation(&tzInfo); SystemTimeToTzSpecificLocalTime(&tzInfo, &st, &st); TCHAR pszAnniv[11]; swprintf(pszAnniv, 11, _T("%4d-%02d-%02d"), st.wYear, st.wMonth, st.wDay); Anniversary(pszAnniv); } // email 1 RECIP_INFO tempRecip; if ((m_pPropVals[C_MAIL1TYPE].ulPropTag == contactProps.aulPropTag[C_MAIL1TYPE]) && (m_pPropVals[C_MAIL1ADDRESS].ulPropTag == contactProps.aulPropTag[C_MAIL1ADDRESS])) { if (wcscmp(m_pPropVals[C_MAIL1TYPE].Value.lpszW, L"SMTP") == 0) { Email(m_pPropVals[C_MAIL1ADDRESS].Value.lpszW); } else if (wcscmp(m_pPropVals[C_MAIL1TYPE].Value.lpszW, L"EX") == 0) { tempRecip.pAddrType = m_pPropVals[C_MAIL1TYPE].Value.lpszW; tempRecip.pEmailAddr = m_pPropVals[C_MAIL1ADDRESS].Value.lpszW; tempRecip.cbEid = m_pPropVals[C_MAIL1EID].Value.bin.cb; tempRecip.pEid = (LPENTRYID)(m_pPropVals[C_MAIL1EID].Value.bin.lpb); wstring strSenderEmail(_TEXT("")); HRESULT hr = Zimbra::MAPI::Util::HrMAPIGetSMTPAddress(*m_session, tempRecip, strSenderEmail); if (hr != S_OK) Email(m_pPropVals[C_MAIL1DISPNAME].Value.lpszW); else Email((LPTSTR)strSenderEmail.c_str()); } } // email 2 if ((m_pPropVals[C_MAIL2TYPE].ulPropTag == contactProps.aulPropTag[C_MAIL2TYPE]) && (m_pPropVals[C_MAIL2ADDRESS].ulPropTag == contactProps.aulPropTag[C_MAIL2ADDRESS])) { if (wcscmp(m_pPropVals[C_MAIL2TYPE].Value.lpszW, L"SMTP") == 0) { Email2(m_pPropVals[C_MAIL2ADDRESS].Value.lpszW); } else if (wcscmp(m_pPropVals[C_MAIL2TYPE].Value.lpszW, L"EX") == 0) { tempRecip.pAddrType = m_pPropVals[C_MAIL2TYPE].Value.lpszW; tempRecip.pEmailAddr = m_pPropVals[C_MAIL2ADDRESS].Value.lpszW; tempRecip.cbEid = m_pPropVals[C_MAIL2EID].Value.bin.cb; tempRecip.pEid = (LPENTRYID)(m_pPropVals[C_MAIL2EID].Value.bin.lpb); wstring strSenderEmail(_TEXT("")); HRESULT hr = Zimbra::MAPI::Util::HrMAPIGetSMTPAddress(*m_session, tempRecip, strSenderEmail); if (hr != S_OK) Email(m_pPropVals[C_MAIL2DISPNAME].Value.lpszW); else Email2((LPTSTR)strSenderEmail.c_str()); } } // email 3 if ((m_pPropVals[C_MAIL3TYPE].ulPropTag == contactProps.aulPropTag[C_MAIL3TYPE]) && (m_pPropVals[C_MAIL3ADDRESS].ulPropTag == contactProps.aulPropTag[C_MAIL3ADDRESS])) { if (wcscmp(m_pPropVals[C_MAIL3TYPE].Value.lpszW, L"SMTP") == 0) { Email3(m_pPropVals[C_MAIL3ADDRESS].Value.lpszW); } else if (wcscmp(m_pPropVals[C_MAIL3TYPE].Value.lpszW, L"EX") == 0) { tempRecip.pAddrType = m_pPropVals[C_MAIL3TYPE].Value.lpszW; tempRecip.pEmailAddr = m_pPropVals[C_MAIL3ADDRESS].Value.lpszW; tempRecip.cbEid = m_pPropVals[C_MAIL3EID].Value.bin.cb; tempRecip.pEid = (LPENTRYID)(m_pPropVals[C_MAIL3EID].Value.bin.lpb); wstring strSenderEmail(_TEXT("")); HRESULT hr = Zimbra::MAPI::Util::HrMAPIGetSMTPAddress(*m_session, tempRecip, strSenderEmail); if (hr != S_OK) Email(m_pPropVals[C_MAIL3DISPNAME].Value.lpszW); else Email3((LPTSTR)strSenderEmail.c_str()); } } if (m_pPropVals[C_IMADDRESS].ulPropTag == contactProps.aulPropTag[C_IMADDRESS]) IMAddress1(m_pPropVals[C_IMADDRESS].Value.lpszW); // add the 'notes' section if (m_mapiMessage->HasTextPart()) { LPTSTR pBody = NULL; UINT nText = 0; m_mapiMessage->TextBody(&pBody, nText); LPTSTR psz = pBody; if (psz) { const char SPACE = ' ', TAB = '\t', CR = 0x0d, LF = 0x0a; while (*psz) { // Replace control characters with space // Exclude carriage return and new line characters while doing the same if ((*psz < SPACE) && (*psz != CR) && (*psz != LF)) *psz = _T(' '); psz++; } // We'll add the body only if it has data other than white spaces and new lines bool bHasValidChars = false; psz = pBody; while (*psz) { if ((*psz == SPACE) || (*psz == TAB) || (*psz == CR) || (*psz == LF)) { psz++; continue; } else { bHasValidChars = true; break; } } if (bHasValidChars) Notes(pBody); MAPIFreeBuffer(pBody); } } // if its a distribution list, add the dist list members to the property wstring strInvalidGroupContacts; if (m_bPersonalDL) { std::wstring dlist = L""; if (m_pPropVals[C_ONEOFFMEMEBRS_IDX].ulPropTag == contactProps.aulPropTag[C_ONEOFFMEMEBRS_IDX]) { bool bFirst = true; for (ULONG i = 0; i < m_pPropVals[C_ONEOFFMEMEBRS_IDX].Value.MVbin.cValues; i++) { DWORD dwObjType; SBinary &bin = m_pPropVals[C_ONEOFFMEMEBRS_IDX].Value.MVbin.lpbin[i]; IMailUser *pUser = NULL; hr = m_session->OpenEntry(bin.cb, (LPENTRYID)bin.lpb, NULL, 0, &dwObjType, (LPUNKNOWN *)&pUser); if (FAILED(hr) || !pUser) continue; LPSPropValue pDNProp = NULL; LPSPropValue pAddrProp = NULL; std::wstring user = L""; BOOL bIsInvalidContact = TRUE; HrGetOneProp(pUser, PR_DISPLAY_NAME_W, &pDNProp); HrGetOneProp(pUser, PR_EMAIL_ADDRESS_W, &pAddrProp); if (pDNProp && (pDNProp->ulPropTag == PR_DISPLAY_NAME_W) && wcslen( pDNProp->Value.lpszW)) user += pDNProp->Value.lpszW; if (pAddrProp && (pAddrProp->ulPropTag == PR_EMAIL_ADDRESS_W) && wcslen( pAddrProp->Value.lpszW)) { std::wstring temp = pAddrProp->Value.lpszW; if (temp.find(L'@') != std::wstring::npos) bIsInvalidContact = FALSE; if (!user.empty()) user += L" "; user += L"<"; user += temp; user += L">"; } if (bIsInvalidContact) { if (!user.empty()) { if (!strInvalidGroupContacts.empty()) strInvalidGroupContacts += _T(", "); strInvalidGroupContacts += user.c_str(); } } else { if (bFirst) bFirst = false; else dlist += L","; dlist += user; } pUser->Release(); MAPIFreeBuffer(pDNProp); MAPIFreeBuffer(pAddrProp); } } //set DL values DList((LPTSTR)dlist.c_str()); } //user define props if (!m_bPersonalDL) { LPMAPINAMEID FAR *lppPropNames = NULL; LPSPropTagArray tagArray; ULONG lCount = 0; hr = m_pMessage->GetPropList(MAPI_UNICODE, &tagArray); if (hr == S_OK) { hr = m_pMessage->GetNamesFromIDs(&tagArray, (LPGUID)&PS_PUBLIC_STRINGS, 0, &lCount, &lppPropNames); if (SUCCEEDED(hr)) { WCHAR wszProps2GUID[40] = { 0 }; Zimbra::Util::Guid nameProps2Guid(OUTLOOK_NAME_PROPS_GUID_2); nameProps2Guid.toString(wszProps2GUID); WCHAR wszContactPropGUID[40] = { 0 }; WCHAR wszVal[1024]={0}; for (ULONG i = 0; i < lCount; i++) { Zimbra::Util::ScopedBuffer<SPropValue> pPropVal; hr = HrGetOneProp(m_pMessage, tagArray->aulPropTag[i], pPropVal.getptr()); if (lppPropNames[i] != NULL) // FBS bug 71786 -- 3/20/12 { if (lppPropNames[i]->ulKind == MNID_STRING) { Zimbra::Util::Guid propGuid(*lppPropNames[i]->lpguid); propGuid.toString(wszContactPropGUID); if (lstrcmpiW(wszContactPropGUID, wszProps2GUID) == 0) { LPWSTR szPropName = lppPropNames[i]->Kind.lpwstrName; // now format a string depending on the type ULONG ulPropType = PROP_TYPE(pPropVal->ulPropTag); BOOL bSetAttribute = TRUE; switch (ulPropType) { case PT_UNICODE: wcscpy(wszVal, pPropVal->Value.lpszW); break; case PT_SYSTIME: { SYSTEMTIME sysTime = { 0 }; if (FileTimeToSystemTime(&(pPropVal->Value.ft), &sysTime)) { TIME_ZONE_INFORMATION tzInfo = { 0 }; GetTimeZoneInformation(&tzInfo); SystemTimeToTzSpecificLocalTime(&tzInfo, &sysTime, &sysTime); wsprintf(wszVal, L"%4d-%02d-%02d", sysTime.wYear, sysTime.wMonth, sysTime.wDay); } break; } case PT_LONG: wsprintf(wszVal, L"%d", pPropVal->Value.l); break; case PT_DOUBLE: { CHAR tmp[36]; _gcvt(pPropVal->Value.dbl, 6, tmp); LPWSTR wszTmp = Zimbra::Util::AnsiiToUnicode(tmp); wcscpy(wszVal, wszTmp); break; } case PT_BOOLEAN: if (pPropVal->Value.b) wcscpy(wszVal, L"TRUE"); else wcscpy(wszVal, L"FALSE"); break; case PT_CURRENCY: { LONGLONG lCurrency; CURRENCY currency; currency = pPropVal->Value.cur; lCurrency = currency.int64; lCurrency = lCurrency / 10000; wsprintf(wszVal, L"$%I64d", lCurrency); break; } default: // can't deal with these other types bSetAttribute = FALSE; //LOG("%hs: MAPI type %0x not supported: user defined field %s will not be synced"), // __FUNCTION__, ulPropType, szPropName); } ContactUDFields cudf; cudf.Name = szPropName; cudf.value = wszVal; AddUserDefinedField(cudf); } } } } MAPIFreeBuffer(lppPropNames); } MAPIFreeBuffer(tagArray); } } // Save image path wstring wstrImagePath; if (m_mapiMessage->HasAttach()) { if (!FAILED(hr = GetContactImage(wstrImagePath))) ContactImagePath((LPTSTR)wstrImagePath.c_str()); } return S_OK; }
//$--HrMAPISetPropFromFile------------------------------------------------------- // Set a property from a given file. // ----------------------------------------------------------------------------- HRESULT HrMAPISetPropFromFile( // RETURNS: return code IN LPMAPIPROP lpObj, // pointer to object IN ULONG ulPropTag, // property tag IN LPSTR lpszFilename, // pointer to source file name OUT ULONG *lpcbProp) // pointer to count of bytes address // variable { HRESULT hr = NOERROR; HRESULT hrT = NOERROR; SCODE sc = 0; LPSTREAM lpStream = NULL; HFILE hFile = HFILE_ERROR; OFSTRUCT ofStruct = {0}; DWORD dwBytesRead = 0; LPBYTE lpbBlock = NULL; ULONG ulBytesWritten = 0; ULARGE_INTEGER ll = {0,0}; ULONG ulFileSize = 0; BYTE bLastByte = 0xFF; ULONG cbProp = 0; DEBUGPUBLIC("HrMAPISetPropFromFile()\n"); hr = CHK_HrMAPISetPropFromFile( lpObj, ulPropTag, lpszFilename, lpcbProp); if(FAILED(hr)) RETURN(hr); *lpcbProp = 0; // Open a stream on the property hrT = MAPICALL(lpObj)->OpenProperty( /*lpObj,*/ ulPropTag, (LPIID)&IID_IStream, STGM_DIRECT | STGM_WRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, MAPI_CREATE | MAPI_MODIFY | MAPI_DEFERRED_ERRORS, (LPUNKNOWN *)&lpStream); if(FAILED(hrT)) { // Streams are not supported by provider if((hrT == MAPI_E_NO_SUPPORT) || (hrT == MAPI_E_INTERFACE_NOT_SUPPORTED)) { lpStream = NULL; } else { hr = HR_LOG(E_FAIL); goto cleanup; } } hFile = OpenFile( lpszFilename, &ofStruct, OF_READ); if(hFile == HFILE_ERROR) { hr = HR_LOG(E_FAIL); goto cleanup; } // Get file size if((ulFileSize = GetFileSize((HANDLE)hFile, NULL)) == (DWORD)HFILE_ERROR) { hr = HR_LOG(E_FAIL); goto cleanup; } if(PROP_TYPE(ulPropTag) == PT_UNICODE) { if((ulFileSize % sizeof(wchar_t)) != 0) { hr = HR_LOG(E_FAIL); goto cleanup; } } cbProp = ulFileSize; // Copy propery value to the file if(lpStream != NULL) { // Allocate memory for the block buffer sc = MAPIAllocateBuffer(EDK_CBTRANSFER, (void **)&lpbBlock); // An error occured allocating the block buffer if(FAILED(sc)) { hr = HR_LOG(E_OUTOFMEMORY); goto cleanup; } ll.LowPart = ulFileSize; ll.HighPart = 0L; hrT = /*OLECALL*/(lpStream)->SetSize(/*lpStream,*/ ll); if(FAILED(hrT)) { hr = HR_LOG(E_FAIL); goto cleanup; } for (;;) { BOOL fStatus; // Read a block from the file fStatus = ReadFile( (HANDLE)hFile, lpbBlock, EDK_CBTRANSFER, &dwBytesRead, NULL); if(fStatus == FALSE) { hr = HR_LOG(E_FAIL); goto cleanup; } if(dwBytesRead == 0L) break; bLastByte = lpbBlock[dwBytesRead - 1L]; // Write a block to the stream hrT = /*OLECALL*/(lpStream)->Write( /*lpStream,*/ lpbBlock, dwBytesRead, &ulBytesWritten); if(FAILED(hrT)) { hr = HR_LOG(E_FAIL); goto cleanup; } if(ulBytesWritten < dwBytesRead) { hr = HR_LOG(MAPI_E_NOT_ENOUGH_DISK); goto cleanup; } } if((PROP_TYPE(ulPropTag) == PT_STRING8) || (PROP_TYPE(ulPropTag) == PT_UNICODE)) { // NULL terminate if not already if(bLastByte != 0) { // Initialize with enough zeroes for a NULL character ZeroMemory(lpbBlock, sizeof(wchar_t)); if(PROP_TYPE(ulPropTag) == PT_UNICODE) { dwBytesRead = sizeof(wchar_t); } else { dwBytesRead = 1L; } ulBytesWritten = 0L; // Write a block to the stream hrT = /*OLECALL*/(lpStream)->Write( /*lpStream,*/ lpbBlock, dwBytesRead, &ulBytesWritten); if(FAILED(hrT)) { hr = HR_LOG(E_FAIL); goto cleanup; } if(ulBytesWritten < dwBytesRead) { hr = HR_LOG(MAPI_E_NOT_ENOUGH_DISK); goto cleanup; } cbProp += ulBytesWritten; } } } else { BOOL fStatus = FALSE; ULONG PropType = 0; // Allocate the memory for the property value sc = MAPIAllocateBuffer( ulFileSize + 2 * sizeof(wchar_t), (void **)&lpbBlock); // An error occured allocating the block buffer if(FAILED(sc)) { hr = HR_LOG(E_FAIL); goto cleanup; } // Read the property value into memory fStatus = ReadFile( (HANDLE)hFile, lpbBlock, ulFileSize, &dwBytesRead, NULL); if(fStatus == FALSE) { hr = HR_LOG(E_FAIL); goto cleanup; } // Check if the entire file was read if(dwBytesRead != ulFileSize) { hr = HR_LOG(E_FAIL); goto cleanup; } if((PROP_TYPE(ulPropTag) == PT_STRING8) || (PROP_TYPE(ulPropTag) == PT_UNICODE)) { // NULL terminate if not already bLastByte = lpbBlock[dwBytesRead - 1L]; if(bLastByte != 0) { if(PROP_TYPE(ulPropTag) == PT_UNICODE) { ((wchar_t *)lpbBlock)[dwBytesRead/sizeof(wchar_t)] = '\0'; ulFileSize += sizeof(wchar_t); } else { lpbBlock[dwBytesRead] = 0; ulFileSize++; } cbProp = ulFileSize; } } PropType = PROP_TYPE(ulPropTag); // Set property switch(PropType) { case PT_BINARY: hr = HrMAPISetPropBinary( lpObj, ulPropTag, ulFileSize, &lpbBlock); break; default: hr = HrMAPISetPropString( lpObj, ulPropTag, &lpbBlock); } } cleanup: // Close the file if(hFile != HFILE_ERROR) { if(CloseHandle((HANDLE)hFile) == FALSE) { hr = HR_LOG(E_FAIL); } } // Release the stream //ULOLERELEASE(lpStream); if(lpStream != NULL) { lpStream->Release(); } lpStream = NULL; MAPIFREEBUFFER(lpbBlock); if(SUCCEEDED(hr)) { *lpcbProp = cbProp; } RETURN(hr); }
// @object PyMAPINAMEIDArray|A sequence (<o PyIID>, string/int) objects BOOL PyMAPIObject_AsMAPINAMEIDArray(PyObject *ob, MAPINAMEID ***pppNameId, ULONG *pNumIds, BOOL bNoneOK /*= FALSE*/ ) { if (bNoneOK && ob==Py_None) { *pppNameId = NULL; *pNumIds = 0; return TRUE; } PyErr_Clear(); ULONG len = (ULONG)PySequence_Length(ob); if (PyErr_Occurred()) { PyErr_Clear(); PyErr_SetString(PyExc_TypeError, "MAPINAMEID array list be a sequence of tuples"); return FALSE; } MAPINAMEID **ppNew = NULL; MAPINAMEID *prgIds = NULL; IID *pIIDs = NULL; HRESULT hr = MAPIAllocateBuffer(len * sizeof(MAPINAMEID *), (void **)&ppNew); if (SUCCEEDED(hr)) hr = MAPIAllocateMore(len * sizeof(MAPINAMEID), ppNew, (void **)&prgIds); if (SUCCEEDED(hr)) hr = MAPIAllocateMore(len * sizeof(IID), ppNew, (void **)&pIIDs); if (FAILED(hr)) { MAPIFreeBuffer(ppNew); OleSetOleError(hr); return FALSE; } for (ULONG i=0; i<len; i++) { ppNew[i] = prgIds+i; MAPINAMEID *pNew = prgIds+i; PyObject *obIID, *obPropId; PyObject *pMe = PySequence_GetItem(ob, i); if (pMe==NULL) { goto loop_error; } if (!PyArg_ParseTuple(pMe, "OO", &obIID, &obPropId )) { PyErr_Clear(); PyErr_SetString(PyExc_TypeError, "MAPINAMEIDArray must be a sequence of (iid, string/int) tuples"); goto loop_error; } pNew->lpguid = pIIDs+i; BSTR bstrVal; if (!PyWinObject_AsIID(obIID, pIIDs+i)) goto loop_error; if (PyInt_Check(obPropId)) { pNew->ulKind = MNID_ID; pNew->Kind.lID = PyInt_AsLong(obPropId); } else if (PyWinObject_AsBstr(obPropId, &bstrVal)) { // Make a copy of the string pNew->ulKind = MNID_STRING; DWORD strLen = SysStringLen(bstrVal); hr = MAPIAllocateMore(sizeof(WCHAR) * (strLen+1), ppNew, (void **)&pNew->Kind.lpwstrName); if (FAILED(hr)) { PyWinObject_FreeBstr(bstrVal); OleSetOleError(hr); goto loop_error; } wcsncpy(pNew->Kind.lpwstrName, bstrVal, strLen+1); PyWinObject_FreeBstr(bstrVal); } else { PyErr_SetString(PyExc_TypeError, "The type of property ID is invalid - must be string/unicode or int"); goto loop_error; } Py_DECREF(pMe); continue; loop_error: Py_XDECREF(pMe); MAPIFreeBuffer(ppNew); return NULL; } *pppNameId = ppNew; *pNumIds = len; return TRUE; }
//$--HrMAPIAppendSPropValues----------------------------------------------------- // Append one set of SPropValue's to another. // ----------------------------------------------------------------------------- HRESULT HrMAPIAppendSPropValues( // RETURNS: return code IN ULONG cHeadProps, // count of property values in head IN LPSPropValue lpHeadProps, // pointer to property values in // head IN ULONG cTailProps, // count of property values in tail IN LPSPropValue lpTailProps, // pointer to property values in // tail OUT ULONG *lpcNewProps, // pointer to count of property // values OUT LPSPropValue *lppNewProps) // pointer to property values { HRESULT hr = NOERROR; SCODE sc = 0; ULONG cNewProps = 0; LPSPropValue lpTmpProps = NULL; LPSPropValue lpNewProps = NULL; ULONG cBytes = 0; ULONG i = 0; ULONG j = 0; DEBUGPUBLIC("HrMAPIAppendSPropValues()\n"); hr = CHK_HrMAPIAppendSPropValues( cHeadProps, lpHeadProps, cTailProps, lpTailProps, lpcNewProps, lppNewProps); if(FAILED(hr)) RETURN(hr); *lpcNewProps = 0; *lppNewProps = NULL; cNewProps = cHeadProps + cTailProps; cBytes = CbSPropValue(cNewProps); sc = MAPIAllocateBuffer(cBytes, (void **)&lpTmpProps); if(FAILED(sc)) { hr = HR_LOG(E_OUTOFMEMORY); goto cleanup; } // Copy existing property values for(i = 0; i < cHeadProps; i++) { lpTmpProps[i] = lpHeadProps[i]; } for(i = cHeadProps, j = 0; i < cNewProps; i++, j++) { lpTmpProps[i] = lpTailProps[j]; } sc = ScDupPropset( cNewProps, lpTmpProps, MAPIAllocateBuffer, &lpNewProps); if(FAILED(sc)) { hr = HR_LOG(E_FAIL); goto cleanup; } *lpcNewProps = cNewProps; *lppNewProps = lpNewProps; cleanup: MAPIFREEBUFFER(lpTmpProps); RETURN(hr); }
// @object PySRowSet|A sequence of <o PySRow> objects, as passed to many MAPI functions. BOOL PyMAPIObject_AsSRowSet(PyObject *obSeq, SRowSet **ppResult, BOOL bNoneOK) { if (ppResult==NULL || obSeq==NULL) return FALSE; if (obSeq==NULL) return FALSE; *ppResult=NULL; if (obSeq==Py_None) { if (bNoneOK) return TRUE; PyErr_SetString(PyExc_ValueError, "None is not a valid SRowSet/ADRLIST in this context"); return FALSE; } PyObject *rowObject = NULL; PyObject *propObject = NULL; BOOL rc = FALSE; HRESULT hr; ULONG i; DWORD allocSize; int seqLen = PySequence_Length(obSeq); if (seqLen==-1) { PyErr_SetString(PyExc_TypeError, "ADRLIST/SRowSet items must be a sequence"); goto done; } allocSize = sizeof(SRowSet) + (sizeof(SRow) * seqLen); if (S_OK != (hr=MAPIAllocateBuffer(allocSize, (void **)ppResult))) { OleSetOleError(hr); goto done; } ZeroMemory(*ppResult, allocSize); // so cleanup works correctly. (*ppResult)->cRows = seqLen; for (i=0; i<(ULONG)seqLen; i++) { rowObject = PySequence_GetItem(obSeq, i); if (rowObject==NULL) goto done; // myob is expected to represent an SRow structure. This is really an array // of property values. SRow *pRow = (*ppResult)->aRow+i; pRow->cValues = PySequence_Length(rowObject); if (pRow->cValues==-1) goto done; if (pRow->cValues==0) pRow->lpProps = NULL; else { allocSize = sizeof(SPropValue) * pRow->cValues; hr = MAPIAllocateBuffer(allocSize, (void **)&pRow->lpProps); if (FAILED(hr)) { OleSetOleError(hr); goto done; } for (ULONG j=0; j<pRow->cValues; j++) { propObject = PySequence_GetItem(rowObject, j); if (propObject==NULL) goto done; if (!PyMAPIObject_AsSPropValue(propObject, pRow->lpProps+j, *ppResult)) goto done; Py_DECREF(propObject); propObject = NULL; // important for cleanup } } Py_DECREF(rowObject); rowObject = NULL; // important for cleanup } rc = TRUE; done: if (!rc && (*ppResult)) { PyMAPIObject_FreeSRowSet(*ppResult); } Py_XDECREF(propObject); Py_XDECREF(rowObject); return rc; }
//$--HrMAPIGetPropBinary--------------------------------------------------------- // Get a binary property. // ----------------------------------------------------------------------------- HRESULT HrMAPIGetPropBinary( // RETURNS: return code IN LPMAPIPROP lpObj, // pointer to object IN ULONG ulPropTag, // property tag OUT ULONG *lpcbProp, // count of bytes in property OUT LPVOID *lppvProp) // pointer to property address variable { HRESULT hr = NOERROR; HRESULT hrT = NOERROR; ULONG cValues = 0; LPSPropValue lpPropValue = NULL; ULONG cbProp = 0; SCODE sc = 0; SizedSPropTagArray(1, rgPropTag) = { 1, { 0 } }; DEBUGPUBLIC("HrMAPIGetPropBinary()\n"); hr = CHK_HrMAPIGetPropBinary( lpObj, ulPropTag, lpcbProp, lppvProp); if(FAILED(hr)) RETURN(hr); *lpcbProp = 0L; *lppvProp = NULL; rgPropTag.cValues = 1; rgPropTag.aulPropTag[0] = ulPropTag; hrT = MAPICALL(lpObj)->GetProps( /*lpObj,*/ (LPSPropTagArray)&rgPropTag, fMapiUnicode, &cValues, &lpPropValue); if(hrT == MAPI_W_ERRORS_RETURNED) { if((lpPropValue != NULL) && (lpPropValue->Value.ul == MAPI_E_NOT_FOUND)) { hr = HR_LOG(MAPI_E_NOT_FOUND); } else { hr = HR_LOG(E_FAIL); } goto cleanup; } if(FAILED(hrT)) { lpPropValue = NULL; hr = HR_LOG(E_FAIL); goto cleanup; } ASSERTERROR(cValues != 0, "ZERO cValues variable"); ASSERTERROR(lpPropValue != NULL, "NULL lpPropValue variable"); cbProp = lpPropValue->Value.bin.cb; sc = MAPIAllocateBuffer(cbProp, lppvProp); if(FAILED(sc)) { hr = HR_LOG(E_OUTOFMEMORY); goto cleanup; } ASSERTERROR(*lppvProp != NULL, "NULL *lppvProp pointer"); // Copy property value memcpy(*lppvProp, lpPropValue->Value.bin.lpb, cbProp); *lpcbProp = cbProp; cleanup: MAPIFREEBUFFER(lpPropValue); RETURN(hr); }
//$--HrMAPIGetPropToFile--------------------------------------------------------- // Get a property and put in a given file. // ----------------------------------------------------------------------------- HRESULT HrMAPIGetPropToFile( // RETURNS: return code IN LPMAPIPROP lpObj, // pointer to object IN ULONG ulPropTag, // property tag IN LPSTR lpszFilename, // pointer to destination file name OUT ULONG *lpcbProp) // pointer to count of bytes address // variable { HRESULT hr = NOERROR; HRESULT hrT = NOERROR; SCODE sc = 0; LPSTREAM lpStream = NULL; HANDLE hFile = NULL; ULONG ulBytesRead = 0; LPBYTE lpbBlock = NULL; DWORD dwBytesWritten = 0; DEBUGPUBLIC("HrMAPIGetPropToFile()\n"); hr = CHK_HrMAPIGetPropToFile( lpObj, ulPropTag, lpszFilename, lpcbProp); if(FAILED(hr)) RETURN(hr); // Open a stream on the property hrT = MAPICALL(lpObj)->OpenProperty( /*lpObj,*/ ulPropTag, (LPIID)&IID_IStream, STGM_READ, MAPI_DEFERRED_ERRORS, (LPUNKNOWN *)&lpStream); if(FAILED(hrT)) { // Streams are not supported by provider if((hrT == MAPI_E_NO_SUPPORT) || (hrT == MAPI_E_INTERFACE_NOT_SUPPORTED)) { ULONG PropType = 0; lpStream = NULL; MODULE_WARNING1("Streams are not supported by provider [%08lx]",hrT); PropType = PROP_TYPE(ulPropTag); // Read property into memory switch(PropType) { case PT_BINARY: hr = HrMAPIGetPropBinary( lpObj, ulPropTag, &ulBytesRead, (void **)&lpbBlock); break; default: hr = HrMAPIGetPropString( lpObj, ulPropTag, &ulBytesRead, (void **)&lpbBlock); } } else { hr = HR_LOG(E_FAIL); goto cleanup; } if(FAILED(hr)) { goto cleanup; } } hFile = CreateFile( lpszFilename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); if(hFile == INVALID_HANDLE_VALUE) { hr = HR_LOG(E_FAIL); goto cleanup; } // Copy propery value to the file if(lpStream != NULL) { sc = MAPIAllocateBuffer(EDK_CBTRANSFER, (void **)&lpbBlock); // An error occured allocating the block buffer if(FAILED(sc)) { hr = HR_LOG(E_OUTOFMEMORY); goto cleanup; } for (;;) { // Read a block from the stream hrT = /*OLECALL*/(lpStream)->Read( /*lpStream,*/ lpbBlock, EDK_CBTRANSFER, &ulBytesRead); if(FAILED(hrT)) { hr = HR_LOG(E_FAIL); goto cleanup; } if(ulBytesRead == 0L) break; // Write the block to the file hr = _HrWriteFile(hFile, ulBytesRead, lpbBlock); if(FAILED(hr)) { goto cleanup; } } } else { // Write the block to the file hr = _HrWriteFile(hFile, ulBytesRead, lpbBlock); if(FAILED(hr)) { goto cleanup; } } cleanup: // Close the file if(hFile != NULL) { if(CloseHandle(hFile) == FALSE) { hr = HR_LOG(E_FAIL); } } // Release the stream //ULOLERELEASE(lpStream); if (lpStream != NULL) { lpStream->Release(); } lpStream = NULL; MAPIFREEBUFFER(lpbBlock); RETURN(hr); }
_Check_return_ HRESULT CAclDlg::GetSelectedItems(ULONG ulFlags, ULONG ulRowFlags, _In_ LPROWLIST* lppRowList) { if (!lppRowList || !m_lpContentsTableListCtrl) return MAPI_E_INVALID_PARAMETER; *lppRowList = NULL; HRESULT hRes = S_OK; int iNumItems = m_lpContentsTableListCtrl->GetSelectedCount(); if (!iNumItems) return S_OK; if (iNumItems > MAXNewROWLIST) return MAPI_E_INVALID_PARAMETER; LPROWLIST lpTempList = NULL; EC_H(MAPIAllocateBuffer(CbNewROWLIST(iNumItems),(LPVOID*) &lpTempList)); if (lpTempList) { lpTempList->cEntries = iNumItems; int iArrayPos = 0; int iSelectedItem = -1; for (iArrayPos = 0 ; iArrayPos < iNumItems ; iArrayPos++) { lpTempList->aEntries[iArrayPos].ulRowFlags = ulRowFlags; lpTempList->aEntries[iArrayPos].cValues = 0; lpTempList->aEntries[iArrayPos].rgPropVals = 0; iSelectedItem = m_lpContentsTableListCtrl->GetNextItem( iSelectedItem, LVNI_SELECTED); if (-1 != iSelectedItem) { SortListData* lpData = (SortListData*) m_lpContentsTableListCtrl->GetItemData(iSelectedItem); if (lpData) { if (ulFlags & ACL_INCLUDE_ID && ulFlags & ACL_INCLUDE_OTHER) { LPSPropValue lpSPropValue = NULL; EC_H(MAPIAllocateMore(2 * sizeof(SPropValue), lpTempList, (LPVOID*)&lpTempList->aEntries[iArrayPos].rgPropVals)); lpTempList->aEntries[iArrayPos].cValues = 2; lpSPropValue = PpropFindProp( lpData->lpSourceProps, lpData->cSourceProps, PR_MEMBER_ID); lpTempList->aEntries[iArrayPos].rgPropVals[0].ulPropTag = lpSPropValue->ulPropTag; lpTempList->aEntries[iArrayPos].rgPropVals[0].Value = lpSPropValue->Value; lpSPropValue = PpropFindProp( lpData->lpSourceProps, lpData->cSourceProps, PR_MEMBER_RIGHTS); lpTempList->aEntries[iArrayPos].rgPropVals[1].ulPropTag = lpSPropValue->ulPropTag; lpTempList->aEntries[iArrayPos].rgPropVals[1].Value = lpSPropValue->Value; } else if (ulFlags & ACL_INCLUDE_ID) { lpTempList->aEntries[iArrayPos].cValues = 1; lpTempList->aEntries[iArrayPos].rgPropVals = PpropFindProp( lpData->lpSourceProps, lpData->cSourceProps, PR_MEMBER_ID); } } } } } *lppRowList = lpTempList; return hRes; } // CAclDlg::GetSelectedItems