ZCMAPIProp.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. /*
  2. * Copyright 2005 - 2016 Zarafa and its licensors
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Affero General Public License, version 3,
  6. * as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU Affero General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Affero General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. *
  16. */
  17. #include <kopano/platform.h>
  18. #include <new>
  19. #include "ZCMAPIProp.h"
  20. #include "ZCABData.h"
  21. #include <mapidefs.h>
  22. #include <mapiguid.h>
  23. #include <mapicode.h>
  24. #include <mapiutil.h>
  25. #include <kopano/Util.h>
  26. #include <kopano/ECGuid.h>
  27. #include <kopano/ECInterfaceDefs.h>
  28. #include <kopano/mapi_ptr.h>
  29. #include <kopano/memory.hpp>
  30. #include <kopano/namedprops.h>
  31. #include <kopano/mapiguidext.h>
  32. ZCMAPIProp::ZCMAPIProp(ULONG ulObjType, const char *szClassName) :
  33. ECUnknown(szClassName), m_ulObject(ulObjType)
  34. {
  35. }
  36. ZCMAPIProp::~ZCMAPIProp()
  37. {
  38. MAPIFreeBuffer(m_base);
  39. }
  40. #define ADD_PROP_OR_EXIT(dest, src, base, propid) { \
  41. if (src) { \
  42. hr = Util::HrCopyProperty(&dest, src, base); \
  43. if (hr != hrSuccess) \
  44. goto exitm; \
  45. dest.ulPropTag = propid; \
  46. m_mapProperties.insert(std::make_pair(PROP_ID(propid), dest)); \
  47. src = NULL; \
  48. } \
  49. }
  50. /**
  51. * Add properties required to make an IMailUser. Properties are the
  52. * same list as Outlook Contacts Provider does.
  53. *
  54. * @param[in] cValues number of props in lpProps
  55. * @param[in] lpProps properties of the original contact
  56. *
  57. * @return
  58. */
  59. HRESULT ZCMAPIProp::ConvertMailUser(LPSPropTagArray lpNames, ULONG cValues, LPSPropValue lpProps, ULONG ulIndex)
  60. {
  61. HRESULT hr = hrSuccess;
  62. // LPSPropValue lpProp = NULL;
  63. SPropValue sValue, sSource;
  64. std::string strSearchKey;
  65. convert_context converter;
  66. auto lpProp = PCpropFindProp(lpProps, cValues, PR_BODY);
  67. if (lpProp) {
  68. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_BODY);
  69. } else {
  70. sValue.ulPropTag = PR_BODY;
  71. sValue.Value.lpszW = empty;
  72. m_mapProperties.insert(std::make_pair(PROP_ID(PR_BODY), sValue));
  73. }
  74. lpProp = PCpropFindProp(lpProps, cValues, PR_BUSINESS_ADDRESS_CITY);
  75. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_BUSINESS_ADDRESS_CITY);
  76. lpProp = PCpropFindProp(lpProps, cValues, PR_BUSINESS_ADDRESS_STATE_OR_PROVINCE);
  77. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_BUSINESS_ADDRESS_STATE_OR_PROVINCE);
  78. lpProp = PCpropFindProp(lpProps, cValues, PR_BUSINESS_FAX_NUMBER);
  79. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_BUSINESS_FAX_NUMBER);
  80. lpProp = PCpropFindProp(lpProps, cValues, PR_COMPANY_NAME);
  81. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_COMPANY_NAME);
  82. if (lpNames)
  83. lpProp = PCpropFindProp(lpProps, cValues, CHANGE_PROP_TYPE(lpNames->aulPropTag[0], PT_UNICODE));
  84. if (!lpProp)
  85. lpProp = PCpropFindProp(lpProps, cValues, PR_DISPLAY_NAME);
  86. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_DISPLAY_NAME);
  87. sValue.ulPropTag = PR_DISPLAY_TYPE;
  88. sValue.Value.ul = DT_MAILUSER;
  89. m_mapProperties.insert(std::make_pair(PROP_ID(PR_DISPLAY_TYPE), sValue));
  90. if (lpNames)
  91. lpProp = PCpropFindProp(lpProps, cValues, CHANGE_PROP_TYPE(lpNames->aulPropTag[1], PT_UNICODE));
  92. if (!lpProp)
  93. lpProp = PCpropFindProp(lpProps, cValues, PR_ADDRTYPE);
  94. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_ADDRTYPE);
  95. if (lpNames)
  96. lpProp = PCpropFindProp(lpProps, cValues, CHANGE_PROP_TYPE(lpNames->aulPropTag[2], PT_UNICODE));
  97. if (!lpProp)
  98. lpProp = PCpropFindProp(lpProps, cValues, PR_EMAIL_ADDRESS);
  99. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_EMAIL_ADDRESS);
  100. lpProp = PCpropFindProp(lpProps, cValues, PR_GIVEN_NAME);
  101. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_GIVEN_NAME);
  102. lpProp = PCpropFindProp(lpProps, cValues, PR_MIDDLE_NAME);
  103. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_MIDDLE_NAME);
  104. lpProp = PCpropFindProp(lpProps, cValues, PR_NORMALIZED_SUBJECT);
  105. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_NORMALIZED_SUBJECT);
  106. sValue.ulPropTag = PR_OBJECT_TYPE;
  107. sValue.Value.ul = MAPI_MAILUSER;
  108. m_mapProperties.insert(std::make_pair(PROP_ID(PR_OBJECT_TYPE), sValue));
  109. if (lpNames)
  110. lpProp = PCpropFindProp(lpProps, cValues, CHANGE_PROP_TYPE(lpNames->aulPropTag[3], PT_UNICODE));
  111. if (!lpProp)
  112. lpProp = PCpropFindProp(lpProps, cValues, PR_DISPLAY_NAME);
  113. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_ORIGINAL_DISPLAY_NAME);
  114. if (lpNames)
  115. lpProp = PCpropFindProp(lpProps, cValues, CHANGE_PROP_TYPE(lpNames->aulPropTag[4], PT_BINARY));
  116. if (!lpProp)
  117. lpProp = PCpropFindProp(lpProps, cValues, PR_ENTRYID);
  118. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_ORIGINAL_ENTRYID);
  119. lpProp = PCpropFindProp(lpProps, cValues, PR_RECORD_KEY);
  120. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_RECORD_KEY);
  121. if (lpNames) {
  122. lpProp = PCpropFindProp(lpProps, cValues, CHANGE_PROP_TYPE(lpNames->aulPropTag[1], PT_UNICODE));
  123. if (lpProp) {
  124. strSearchKey += converter.convert_to<std::string>(lpProp->Value.lpszW) + ":";
  125. } else {
  126. strSearchKey += "SMTP:";
  127. }
  128. lpProp = PCpropFindProp(lpProps, cValues, CHANGE_PROP_TYPE(lpNames->aulPropTag[2], PT_UNICODE));
  129. if (lpProp)
  130. strSearchKey += converter.convert_to<std::string>(lpProp->Value.lpszW);
  131. sSource.ulPropTag = PR_SEARCH_KEY;
  132. sSource.Value.bin.cb = strSearchKey.size();
  133. sSource.Value.bin.lpb = (LPBYTE)strSearchKey.data();
  134. lpProp = &sSource;
  135. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_SEARCH_KEY);
  136. }
  137. lpProp = PCpropFindProp(lpProps, cValues, PR_TITLE);
  138. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_TITLE);
  139. lpProp = PCpropFindProp(lpProps, cValues, PR_TRANSMITABLE_DISPLAY_NAME);
  140. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_TRANSMITABLE_DISPLAY_NAME);
  141. lpProp = PCpropFindProp(lpProps, cValues, PR_ENTRYID);
  142. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_ZC_ORIGINAL_ENTRYID);
  143. lpProp = PCpropFindProp(lpProps, cValues, PR_PARENT_ENTRYID);
  144. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_ZC_ORIGINAL_PARENT_ENTRYID);
  145. lpProp = PCpropFindProp(lpProps, cValues, PR_SOURCE_KEY);
  146. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_ZC_ORIGINAL_SOURCE_KEY);
  147. lpProp = PCpropFindProp(lpProps, cValues, PR_PARENT_SOURCE_KEY);
  148. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_ZC_ORIGINAL_PARENT_SOURCE_KEY);
  149. lpProp = PCpropFindProp(lpProps, cValues, PR_CHANGE_KEY);
  150. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_ZC_ORIGINAL_CHANGE_KEY);
  151. exitm:
  152. return hr;
  153. }
  154. HRESULT ZCMAPIProp::ConvertDistList(LPSPropTagArray lpNames, ULONG cValues, LPSPropValue lpProps)
  155. {
  156. HRESULT hr = hrSuccess;
  157. // LPSPropValue lpProp = NULL;
  158. SPropValue sValue, sSource;
  159. sSource.ulPropTag = PR_ADDRTYPE;
  160. sSource.Value.lpszW = const_cast<wchar_t *>(L"MAPIPDL");
  161. const SPropValue *lpProp = &sSource;
  162. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_ADDRTYPE);
  163. lpProp = PCpropFindProp(lpProps, cValues, PR_DISPLAY_NAME);
  164. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_DISPLAY_NAME);
  165. sValue.ulPropTag = PR_DISPLAY_TYPE;
  166. sValue.Value.ul = DT_PRIVATE_DISTLIST;
  167. m_mapProperties.insert(std::make_pair(PROP_ID(PR_DISPLAY_TYPE), sValue));
  168. sValue.ulPropTag = PR_OBJECT_TYPE;
  169. sValue.Value.ul = MAPI_DISTLIST;
  170. m_mapProperties.insert(std::make_pair(PROP_ID(PR_OBJECT_TYPE), sValue));
  171. lpProp = PCpropFindProp(lpProps, cValues, PR_RECORD_KEY);
  172. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_RECORD_KEY);
  173. // above are all the props present in the Outlook Contact Provider ..
  174. // but I need the props below too
  175. // one off members in 0x81041102
  176. lpProp = PCpropFindProp(lpProps, cValues, 0x81041102);
  177. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, 0x81041102);
  178. // real eid members in 0x81051102 (gab, maybe I only need this one)
  179. lpProp = PCpropFindProp(lpProps, cValues, 0x81051102);
  180. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, 0x81051102);
  181. lpProp = PCpropFindProp(lpProps, cValues, PR_ENTRYID);
  182. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_ZC_ORIGINAL_ENTRYID);
  183. lpProp = PCpropFindProp(lpProps, cValues, PR_PARENT_ENTRYID);
  184. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_ZC_ORIGINAL_PARENT_ENTRYID);
  185. lpProp = PCpropFindProp(lpProps, cValues, PR_SOURCE_KEY);
  186. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_ZC_ORIGINAL_SOURCE_KEY);
  187. lpProp = PCpropFindProp(lpProps, cValues, PR_PARENT_SOURCE_KEY);
  188. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_ZC_ORIGINAL_PARENT_SOURCE_KEY);
  189. lpProp = PCpropFindProp(lpProps, cValues, PR_CHANGE_KEY);
  190. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_ZC_ORIGINAL_CHANGE_KEY);
  191. exitm:
  192. return hr;
  193. }
  194. /**
  195. * Get Props from the contact and remembers them is this object.
  196. *
  197. * @param[in] lpContact
  198. * @param[in] ulIndex index in named properties
  199. *
  200. * @return
  201. */
  202. HRESULT ZCMAPIProp::ConvertProps(IMAPIProp *lpContact, ULONG cbEntryID, LPENTRYID lpEntryID, ULONG ulIndex)
  203. {
  204. HRESULT hr = hrSuccess;
  205. ULONG cValues = 0;
  206. SPropValuePtr ptrContactProps;
  207. SPropValue sValue, sSource;
  208. LPSPropValue lpProp = NULL;
  209. // named properties
  210. SPropTagArrayPtr ptrNameTags;
  211. KCHL::memory_ptr<MAPINAMEID *> lppNames;
  212. ULONG ulNames = 5;
  213. MAPINAMEID mnNamedProps[5] = {
  214. {(LPGUID)&PSETID_Address, MNID_ID, {dispidEmail1DisplayName}},
  215. {(LPGUID)&PSETID_Address, MNID_ID, {dispidEmail1AddressType}},
  216. {(LPGUID)&PSETID_Address, MNID_ID, {dispidEmail1Address}},
  217. {(LPGUID)&PSETID_Address, MNID_ID, {dispidEmail1OriginalDisplayName}},
  218. {(LPGUID)&PSETID_Address, MNID_ID, {dispidEmail1OriginalEntryID}}
  219. };
  220. hr = MAPIAllocateBuffer(sizeof(LPMAPINAMEID) * ulNames, &~lppNames);
  221. if (hr != hrSuccess)
  222. goto exitm;
  223. if (ulIndex < 3) {
  224. for (ULONG i = 0; i < ulNames; ++i) {
  225. mnNamedProps[i].Kind.lID += (ulIndex * 0x10);
  226. lppNames[i] = &mnNamedProps[i];
  227. }
  228. hr = lpContact->GetIDsFromNames(ulNames, lppNames, MAPI_CREATE, &~ptrNameTags);
  229. if (FAILED(hr))
  230. goto exitm;
  231. }
  232. hr = lpContact->GetProps(NULL, MAPI_UNICODE, &cValues, &~ptrContactProps);
  233. if (FAILED(hr))
  234. goto exitm;
  235. hr = MAPIAllocateBuffer(sizeof(SPropValue), (void**)&m_base);
  236. if (hr != hrSuccess)
  237. goto exitm;
  238. sSource.ulPropTag = PR_ENTRYID;
  239. sSource.Value.bin.cb = cbEntryID;
  240. sSource.Value.bin.lpb = (LPBYTE)lpEntryID;
  241. lpProp = &sSource;
  242. ADD_PROP_OR_EXIT(sValue, lpProp, m_base, PR_ENTRYID);
  243. if (m_ulObject == MAPI_MAILUSER)
  244. hr = ConvertMailUser(ptrNameTags, cValues, ptrContactProps, ulIndex);
  245. else
  246. hr = ConvertDistList(ptrNameTags, cValues, ptrContactProps);
  247. exitm:
  248. return hr;
  249. }
  250. HRESULT ZCMAPIProp::Create(IMAPIProp *lpContact, ULONG cbEntryID, LPENTRYID lpEntryID, ZCMAPIProp **lppZCMAPIProp)
  251. {
  252. HRESULT hr = hrSuccess;
  253. ZCMAPIProp *lpZCMAPIProp = NULL;
  254. auto lpCABEntryID = reinterpret_cast<cabEntryID *>(lpEntryID);
  255. if (lpCABEntryID->ulObjType != MAPI_MAILUSER && lpCABEntryID->ulObjType != MAPI_DISTLIST) {
  256. hr = MAPI_E_INVALID_OBJECT;
  257. goto exit;
  258. }
  259. lpZCMAPIProp = new(std::nothrow) ZCMAPIProp(lpCABEntryID->ulObjType);
  260. if (lpZCMAPIProp == nullptr) {
  261. hr = MAPI_E_NOT_ENOUGH_MEMORY;
  262. goto exit;
  263. }
  264. hr = lpZCMAPIProp->ConvertProps(lpContact, cbEntryID, lpEntryID, lpCABEntryID->ulOffset);
  265. if (hr != hrSuccess)
  266. goto exit;
  267. hr = lpZCMAPIProp->QueryInterface(IID_ZCMAPIProp, (void**)lppZCMAPIProp);
  268. exit:
  269. if (hr != hrSuccess)
  270. delete lpZCMAPIProp;
  271. return hr;
  272. }
  273. HRESULT ZCMAPIProp::QueryInterface(REFIID refiid, void **lppInterface)
  274. {
  275. REGISTER_INTERFACE2(ZCMAPIProp, this);
  276. REGISTER_INTERFACE2(ECUnknown, this);
  277. REGISTER_INTERFACE2(IMAPIProp, &this->m_xMAPIProp);
  278. REGISTER_INTERFACE2(IUnknown, &this->m_xMAPIProp);
  279. if (m_ulObject == MAPI_MAILUSER) {
  280. REGISTER_INTERFACE(IID_IMailUser, &this->m_xMAPIProp);
  281. }
  282. return MAPI_E_INTERFACE_NOT_SUPPORTED;
  283. }
  284. HRESULT ZCMAPIProp::GetLastError(HRESULT hResult, ULONG ulFlags, LPMAPIERROR * lppMAPIError)
  285. {
  286. return MAPI_E_NO_SUPPORT;
  287. }
  288. HRESULT ZCMAPIProp::SaveChanges(ULONG ulFlags)
  289. {
  290. return MAPI_E_NO_SUPPORT;
  291. }
  292. HRESULT ZCMAPIProp::CopyOneProp(convert_context &converter, ULONG ulFlags,
  293. const std::map<short, SPropValue>::const_iterator &i, LPSPropValue lpProp,
  294. LPSPropValue lpBase)
  295. {
  296. HRESULT hr;
  297. if ((ulFlags & MAPI_UNICODE) == 0 && PROP_TYPE(i->second.ulPropTag) == PT_UNICODE) {
  298. std::string strAnsi;
  299. // copy from unicode to string8
  300. lpProp->ulPropTag = CHANGE_PROP_TYPE(i->second.ulPropTag, PT_STRING8);
  301. strAnsi = converter.convert_to<std::string>(i->second.Value.lpszW);
  302. hr = MAPIAllocateMore(strAnsi.size() + 1, lpBase, (void**)&lpProp->Value.lpszA);
  303. if (hr != hrSuccess)
  304. return hr;
  305. strcpy(lpProp->Value.lpszA, strAnsi.c_str());
  306. } else {
  307. hr = Util::HrCopyProperty(lpProp, &i->second, lpBase);
  308. if (hr != hrSuccess)
  309. return hr;
  310. }
  311. return hrSuccess;
  312. }
  313. /**
  314. * return property data of this object
  315. *
  316. * @param[in] lpPropTagArray requested properties or NULL for all
  317. * @param[in] ulFlags MAPI_UNICODE when lpPropTagArray is NULL
  318. * @param[out] lpcValues number of properties returned
  319. * @param[out] lppPropArray properties
  320. *
  321. * @return MAPI Error code
  322. */
  323. HRESULT ZCMAPIProp::GetProps(const SPropTagArray *lpPropTagArray, ULONG ulFlags,
  324. ULONG *lpcValues, SPropValue **lppPropArray)
  325. {
  326. HRESULT hr = hrSuccess;
  327. KCHL::memory_ptr<SPropValue> lpProps;
  328. convert_context converter;
  329. if((lpPropTagArray != NULL && lpPropTagArray->cValues == 0) || Util::ValidatePropTagArray(lpPropTagArray) == false)
  330. return MAPI_E_INVALID_PARAMETER;
  331. if (lpPropTagArray == NULL) {
  332. // check ulFlags for MAPI_UNICODE
  333. hr = MAPIAllocateBuffer(sizeof(SPropValue) * m_mapProperties.size(), &~lpProps);
  334. if (hr != hrSuccess)
  335. return hr;
  336. ULONG j = 0;
  337. for (auto i = m_mapProperties.cbegin();
  338. i != m_mapProperties.cend(); ++i) {
  339. hr = CopyOneProp(converter, ulFlags, i, &lpProps[j], lpProps);
  340. if (hr != hrSuccess)
  341. return hr;
  342. ++j;
  343. }
  344. *lpcValues = m_mapProperties.size();
  345. } else {
  346. // check lpPropTagArray->aulPropTag[x].ulPropTag for PT_UNICODE or PT_STRING8
  347. hr = MAPIAllocateBuffer(sizeof(SPropValue) * lpPropTagArray->cValues, &~lpProps);
  348. if (hr != hrSuccess)
  349. return hr;
  350. for (ULONG n = 0, j = 0; n < lpPropTagArray->cValues; ++n, ++j) {
  351. auto i = m_mapProperties.find(PROP_ID(lpPropTagArray->aulPropTag[n]));
  352. if (i == m_mapProperties.cend()) {
  353. lpProps[j].ulPropTag = CHANGE_PROP_TYPE(lpPropTagArray->aulPropTag[n], PT_ERROR);
  354. lpProps[j].Value.ul = MAPI_E_NOT_FOUND;
  355. continue;
  356. }
  357. hr = CopyOneProp(converter, ulFlags, i, &lpProps[j], lpProps);
  358. if (hr != hrSuccess)
  359. return hr;
  360. }
  361. *lpcValues = lpPropTagArray->cValues;
  362. }
  363. *lppPropArray = lpProps.release();
  364. return hrSuccess;
  365. }
  366. /**
  367. * Return a list of all properties on this object
  368. *
  369. * @param[in] ulFlags 0 for PT_STRING8, MAPI_UNICODE for PT_UNICODE properties
  370. * @param[out] lppPropTagArray list of all existing properties
  371. *
  372. * @return MAPI Error code
  373. */
  374. HRESULT ZCMAPIProp::GetPropList(ULONG ulFlags, LPSPropTagArray * lppPropTagArray)
  375. {
  376. LPSPropTagArray lpPropTagArray = NULL;
  377. std::map<short, SPropValue>::const_iterator i;
  378. ULONG j = 0;
  379. HRESULT hr = MAPIAllocateBuffer(CbNewSPropTagArray(m_mapProperties.size()),
  380. reinterpret_cast<void **>(&lpPropTagArray));
  381. if (hr != hrSuccess)
  382. return hr;
  383. lpPropTagArray->cValues = m_mapProperties.size();
  384. for (i = m_mapProperties.begin(); i != m_mapProperties.end(); ++i, ++j) {
  385. lpPropTagArray->aulPropTag[j] = i->second.ulPropTag;
  386. if ((ulFlags & MAPI_UNICODE) == 0 && PROP_TYPE(lpPropTagArray->aulPropTag[j]) == PT_UNICODE)
  387. lpPropTagArray->aulPropTag[j] = CHANGE_PROP_TYPE(lpPropTagArray->aulPropTag[j], PT_STRING8);
  388. }
  389. *lppPropTagArray = lpPropTagArray;
  390. return hrSuccess;
  391. }
  392. HRESULT ZCMAPIProp::OpenProperty(ULONG ulPropTag, LPCIID lpiid, ULONG ulInterfaceOptions, ULONG ulFlags, LPUNKNOWN * lppUnk)
  393. {
  394. return MAPI_E_NO_SUPPORT;
  395. }
  396. HRESULT ZCMAPIProp::SetProps(ULONG vals, const SPropValue *,
  397. SPropProblemArray **)
  398. {
  399. return MAPI_E_NO_SUPPORT;
  400. }
  401. HRESULT ZCMAPIProp::DeleteProps(const SPropTagArray *lpPropTagArray,
  402. SPropProblemArray **lppProblems)
  403. {
  404. return MAPI_E_NO_SUPPORT;
  405. }
  406. HRESULT ZCMAPIProp::CopyTo(ULONG ciidExclude, LPCIID rgiidExclude,
  407. const SPropTagArray *, ULONG ui_param, LPMAPIPROGRESS, LPCIID intf,
  408. void *dest_obj, ULONG flags, SPropProblemArray **)
  409. {
  410. return MAPI_E_NO_SUPPORT;
  411. }
  412. HRESULT ZCMAPIProp::CopyProps(const SPropTagArray *, ULONG ui_param,
  413. LPMAPIPROGRESS, LPCIID intf, void *dest_obj, ULONG flags,
  414. SPropProblemArray **)
  415. {
  416. return MAPI_E_NO_SUPPORT;
  417. }
  418. HRESULT ZCMAPIProp::GetNamesFromIDs(LPSPropTagArray * lppPropTags, LPGUID lpPropSetGuid, ULONG ulFlags, ULONG * lpcPropNames, LPMAPINAMEID ** lpppPropNames)
  419. {
  420. return MAPI_E_NO_SUPPORT;
  421. }
  422. HRESULT ZCMAPIProp::GetIDsFromNames(ULONG cPropNames, LPMAPINAMEID * lppPropNames, ULONG ulFlags, LPSPropTagArray * lppPropTags)
  423. {
  424. return MAPI_E_NO_SUPPORT;
  425. }
  426. // Interface IMAPIProp
  427. DEF_HRMETHOD0(ZCMAPIProp, MAPIProp, QueryInterface, (REFIID, refiid), (void **, lppInterface))
  428. DEF_ULONGMETHOD0(ZCMAPIProp, MAPIProp, AddRef, (void))
  429. DEF_ULONGMETHOD0(ZCMAPIProp, MAPIProp, Release, (void))
  430. DEF_HRMETHOD0(ZCMAPIProp, MAPIProp, GetLastError, (HRESULT, hError), (ULONG, ulFlags), (LPMAPIERROR *, lppMapiError))
  431. DEF_HRMETHOD0(ZCMAPIProp, MAPIProp, SaveChanges, (ULONG, ulFlags))
  432. DEF_HRMETHOD0(ZCMAPIProp, MAPIProp, GetProps, (const SPropTagArray *, lpPropTagArray), (ULONG, ulFlags), (ULONG *, lpcValues), (SPropValue **, lppPropArray))
  433. DEF_HRMETHOD0(ZCMAPIProp, MAPIProp, GetPropList, (ULONG, ulFlags), (LPSPropTagArray *, lppPropTagArray))
  434. DEF_HRMETHOD0(ZCMAPIProp, MAPIProp, OpenProperty, (ULONG, ulPropTag), (LPCIID, lpiid), (ULONG, ulInterfaceOptions), (ULONG, ulFlags), (LPUNKNOWN *, lppUnk))
  435. DEF_HRMETHOD0(ZCMAPIProp, MAPIProp, SetProps, (ULONG, cValues), (const SPropValue *, lpPropArray), (SPropProblemArray **, lppProblems))
  436. DEF_HRMETHOD0(ZCMAPIProp, MAPIProp, DeleteProps, (const SPropTagArray *, lpPropTagArray), (SPropProblemArray **, lppProblems))
  437. DEF_HRMETHOD0(ZCMAPIProp, MAPIProp, CopyTo, (ULONG, ciidExclude), (LPCIID, rgiidExclude), (const SPropTagArray *, lpExcludeProps), (ULONG, ulUIParam), (LPMAPIPROGRESS, lpProgress), (LPCIID, lpInterface), (void *, lpDestObj), (ULONG, ulFlags), (SPropProblemArray **, lppProblems))
  438. DEF_HRMETHOD0(ZCMAPIProp, MAPIProp, CopyProps, (const SPropTagArray *, lpIncludeProps), (ULONG, ulUIParam), (LPMAPIPROGRESS, lpProgress), (LPCIID, lpInterface), (void *, lpDestObj), (ULONG, ulFlags), (SPropProblemArray **, lppProblems))
  439. DEF_HRMETHOD0(ZCMAPIProp, MAPIProp, GetNamesFromIDs, (LPSPropTagArray *, pptaga), (LPGUID, lpguid), (ULONG, ulFlags), (ULONG *, pcNames), (LPMAPINAMEID **, pppNames))
  440. DEF_HRMETHOD0(ZCMAPIProp, MAPIProp, GetIDsFromNames, (ULONG, cNames), (LPMAPINAMEID *, ppNames), (ULONG, ulFlags), (LPSPropTagArray *, pptaga))