ECRestriction.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  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 <utility>
  19. #include <kopano/ECRestriction.h>
  20. #include <kopano/Util.h>
  21. #include <kopano/mapi_ptr.h>
  22. #include <mapicode.h>
  23. #include <mapix.h>
  24. namespace KC {
  25. /**
  26. * Allocate and populate a MAPI SRestriction structure based on the current
  27. * ECRestriction object.
  28. * @param[out] lppRestriction The resulting SRestriction structure.
  29. * @retval MAPI_E_INVALID_PARAMTER lppRestriction is NULL.
  30. */
  31. HRESULT ECRestriction::CreateMAPIRestriction(LPSRestriction *lppRestriction, ULONG ulFlags) const {
  32. SRestrictionPtr ptrRestriction;
  33. if (lppRestriction == NULL)
  34. return MAPI_E_INVALID_PARAMETER;
  35. HRESULT hr = MAPIAllocateBuffer(sizeof(SRestrictionPtr::value_type), &~ptrRestriction);
  36. if (hr != hrSuccess)
  37. return hr;
  38. hr = GetMAPIRestriction(ptrRestriction, ptrRestriction, ulFlags);
  39. if (hr != hrSuccess)
  40. return hr;
  41. *lppRestriction = ptrRestriction.release();
  42. return hrSuccess;
  43. }
  44. HRESULT ECRestriction::RestrictTable(IMAPITable *lpTable,
  45. unsigned int flags) const
  46. {
  47. SRestrictionPtr ptrRestriction;
  48. if (lpTable == NULL)
  49. return MAPI_E_INVALID_PARAMETER;
  50. HRESULT hr = CreateMAPIRestriction(&~ptrRestriction, ECRestriction::Cheap);
  51. if (hr != hrSuccess)
  52. return hr;
  53. return lpTable->Restrict(ptrRestriction, flags);
  54. }
  55. HRESULT ECRestriction::FindRowIn(LPMAPITABLE lpTable, BOOKMARK BkOrigin, ULONG ulFlags) const
  56. {
  57. SRestrictionPtr ptrRestriction;
  58. if (lpTable == NULL)
  59. return MAPI_E_INVALID_PARAMETER;
  60. HRESULT hr = CreateMAPIRestriction(&~ptrRestriction, ECRestriction::Cheap);
  61. if (hr != hrSuccess)
  62. return hr;
  63. return lpTable->FindRow(ptrRestriction, BkOrigin, ulFlags);
  64. }
  65. /**
  66. * Copy a property into a newly allocated SPropValue.
  67. * @param[in] lpPropSrc The source property.
  68. * @param[in] lpBase An optional base pointer for MAPIAllocateMore.
  69. * @param[out] lppPropDst Pointer to an SPropValue pointer that will be set to
  70. * the address of the newly allocated SPropValue.
  71. * @retval MAPI_E_INVALID_PARAMETER lpPropSrc or lppPropDst is NULL.
  72. */
  73. HRESULT ECRestriction::CopyProp(SPropValue *lpPropSrc, void *lpBase,
  74. ULONG ulFlags, SPropValue **lppPropDst)
  75. {
  76. HRESULT hr = hrSuccess;
  77. LPSPropValue lpPropDst = NULL;
  78. if (lpPropSrc == NULL || lppPropDst == NULL) {
  79. hr = MAPI_E_INVALID_PARAMETER;
  80. goto exit;
  81. }
  82. if (lpBase == NULL)
  83. hr = MAPIAllocateBuffer(sizeof *lpPropDst, (LPVOID*)&lpPropDst);
  84. else
  85. hr = MAPIAllocateMore(sizeof *lpPropDst, lpBase, (LPVOID*)&lpPropDst);
  86. if (hr != hrSuccess)
  87. goto exit;
  88. if (ulFlags & Shallow)
  89. hr = Util::HrCopyPropertyByRef(lpPropDst, lpPropSrc);
  90. else
  91. hr = Util::HrCopyProperty(lpPropDst, lpPropSrc, lpBase ? lpBase : lpPropDst);
  92. if (hr != hrSuccess)
  93. goto exit;
  94. *lppPropDst = lpPropDst;
  95. lpPropDst = NULL;
  96. exit:
  97. if (lpBase != NULL)
  98. MAPIFreeBuffer(lpPropDst);
  99. return hr;
  100. }
  101. /**
  102. * Copy a property array into a newly allocated SPropValue array.
  103. * @param[in] cValues The size of the array.
  104. * @param[in] lpPropSrc The source property array.
  105. * @param[in] lpBase An optional base pointer for MAPIAllocateMore.
  106. * @param[out] lppPropDst Pointer to an SPropValue pointer that will be set to
  107. * the address of the newly allocated SPropValue array.
  108. * @retval MAPI_E_INVALID_PARAMETER lpPropSrc or lppPropDst is NULL.
  109. */
  110. HRESULT ECRestriction::CopyPropArray(ULONG cValues, SPropValue *lpPropSrc,
  111. void *lpBase, ULONG ulFlags, SPropValue **lppPropDst)
  112. {
  113. HRESULT hr = hrSuccess;
  114. LPSPropValue lpPropDst = NULL;
  115. if (lpPropSrc == NULL || lppPropDst == NULL) {
  116. hr = MAPI_E_INVALID_PARAMETER;
  117. goto exit;
  118. }
  119. if (lpBase == NULL)
  120. hr = MAPIAllocateBuffer(cValues * sizeof *lpPropDst, (LPVOID*)&lpPropDst);
  121. else
  122. hr = MAPIAllocateMore(cValues * sizeof *lpPropDst, lpBase, (LPVOID*)&lpPropDst);
  123. if (hr != hrSuccess)
  124. goto exit;
  125. if (ulFlags & Shallow)
  126. hr = Util::HrCopyPropertyArrayByRef(lpPropSrc, cValues, lpPropDst);
  127. else
  128. hr = Util::HrCopyPropertyArray(lpPropSrc, cValues, lpPropDst, lpBase ? lpBase : lpPropDst);
  129. if (hr != hrSuccess)
  130. goto exit;
  131. *lppPropDst = lpPropDst;
  132. lpPropDst = NULL;
  133. exit:
  134. if (lpBase != NULL)
  135. MAPIFreeBuffer(lpPropDst);
  136. return hr;
  137. }
  138. inline void ECRestriction::DummyFree(LPVOID) {}
  139. /**
  140. * ECAndRestriction
  141. */
  142. ECAndRestriction::ECAndRestriction(const ECRestrictionList &list): m_lstRestrictions(list.m_list) {}
  143. void ECAndRestriction::operator+=(const ECRestrictionList &list)
  144. {
  145. m_lstRestrictions.insert(m_lstRestrictions.end(), list.m_list.begin(), list.m_list.end());
  146. }
  147. void ECAndRestriction::operator+=(ECRestrictionList &&o)
  148. {
  149. ResList &dst = m_lstRestrictions, &src = o.m_list;
  150. if (dst.empty()) {
  151. dst = std::move(src);
  152. return;
  153. }
  154. std::move(std::begin(src), std::end(src), std::back_inserter(dst));
  155. src.clear();
  156. }
  157. HRESULT ECAndRestriction::GetMAPIRestriction(LPVOID lpBase, LPSRestriction lpRestriction, ULONG ulFlags) const {
  158. SRestriction restriction = {0};
  159. ULONG i = 0;
  160. if (lpBase == NULL || lpRestriction == NULL)
  161. return MAPI_E_INVALID_PARAMETER;
  162. restriction.rt = RES_AND;
  163. restriction.res.resAnd.cRes = m_lstRestrictions.size();
  164. HRESULT hr = MAPIAllocateMore(restriction.res.resAnd.cRes *
  165. sizeof(*restriction.res.resAnd.lpRes), lpBase,
  166. reinterpret_cast<LPVOID *>(&restriction.res.resAnd.lpRes));
  167. if (hr != hrSuccess)
  168. return hr;
  169. for (const auto &r : m_lstRestrictions) {
  170. hr = r->GetMAPIRestriction(lpBase, restriction.res.resAnd.lpRes + i, ulFlags);
  171. if (hr != hrSuccess)
  172. return hr;
  173. ++i;
  174. }
  175. *lpRestriction = std::move(restriction);
  176. return hrSuccess;
  177. }
  178. ECRestriction *ECAndRestriction::Clone(void) const _kc_lvqual
  179. {
  180. auto lpNew = new ECAndRestriction;
  181. lpNew->m_lstRestrictions.assign(m_lstRestrictions.begin(), m_lstRestrictions.end());
  182. return lpNew;
  183. }
  184. /**
  185. * ECOrRestriction
  186. */
  187. ECOrRestriction::ECOrRestriction(const ECRestrictionList &list): m_lstRestrictions(list.m_list) {}
  188. void ECOrRestriction::operator+=(const ECRestrictionList &list)
  189. {
  190. m_lstRestrictions.insert(m_lstRestrictions.end(), list.m_list.begin(), list.m_list.end());
  191. }
  192. void ECOrRestriction::operator+=(ECRestrictionList &&o)
  193. {
  194. ResList &dst = m_lstRestrictions, &src = o.m_list;
  195. if (dst.empty()) {
  196. dst = std::move(src);
  197. return;
  198. }
  199. std::move(std::begin(src), std::end(src), std::back_inserter(dst));
  200. src.clear();
  201. }
  202. HRESULT ECOrRestriction::GetMAPIRestriction(LPVOID lpBase, LPSRestriction lpRestriction, ULONG ulFlags) const {
  203. SRestriction restriction = {0};
  204. ULONG i = 0;
  205. if (lpBase == NULL || lpRestriction == NULL)
  206. return MAPI_E_INVALID_PARAMETER;
  207. restriction.rt = RES_OR;
  208. restriction.res.resOr.cRes = m_lstRestrictions.size();
  209. HRESULT hr = MAPIAllocateMore(restriction.res.resOr.cRes *
  210. sizeof(*restriction.res.resOr.lpRes), lpBase,
  211. reinterpret_cast<LPVOID *>(&restriction.res.resOr.lpRes));
  212. if (hr != hrSuccess)
  213. return hr;
  214. for (const auto &r : m_lstRestrictions) {
  215. hr = r->GetMAPIRestriction(lpBase, restriction.res.resOr.lpRes + i, ulFlags);
  216. if (hr != hrSuccess)
  217. return hr;
  218. ++i;
  219. }
  220. *lpRestriction = std::move(restriction);
  221. return hrSuccess;
  222. }
  223. ECRestriction *ECOrRestriction::Clone(void) const _kc_lvqual
  224. {
  225. auto lpNew = new ECOrRestriction;
  226. lpNew->m_lstRestrictions.assign(m_lstRestrictions.begin(), m_lstRestrictions.end());
  227. return lpNew;
  228. }
  229. /**
  230. * ECNotRestriction
  231. */
  232. ECNotRestriction::ECNotRestriction(ResPtr ptrRestriction): m_ptrRestriction(ptrRestriction) {}
  233. HRESULT ECNotRestriction::GetMAPIRestriction(LPVOID lpBase, LPSRestriction lpRestriction, ULONG ulFlags) const {
  234. SRestriction restriction = {0};
  235. if (lpBase == NULL || lpRestriction == NULL)
  236. return MAPI_E_INVALID_PARAMETER;
  237. restriction.rt = RES_NOT;
  238. HRESULT hr = MAPIAllocateMore(sizeof(*restriction.res.resNot.lpRes),
  239. lpBase, reinterpret_cast<LPVOID *>(&restriction.res.resNot.lpRes));
  240. if (hr != hrSuccess)
  241. return hr;
  242. hr = m_ptrRestriction->GetMAPIRestriction(lpBase, restriction.res.resNot.lpRes, ulFlags);
  243. if (hr != hrSuccess)
  244. return hr;
  245. *lpRestriction = std::move(restriction);
  246. return hrSuccess;
  247. }
  248. ECRestriction *ECNotRestriction::Clone(void) const _kc_lvqual
  249. {
  250. return new ECNotRestriction(m_ptrRestriction);
  251. }
  252. /**
  253. * ECContentRestriction
  254. */
  255. ECContentRestriction::ECContentRestriction(ULONG ulFuzzyLevel, ULONG ulPropTag,
  256. const SPropValue *lpProp, ULONG ulFlags) :
  257. m_ulFuzzyLevel(ulFuzzyLevel), m_ulPropTag(ulPropTag)
  258. {
  259. auto np = const_cast<SPropValue *>(lpProp);
  260. if (ulFlags & ECRestriction::Cheap)
  261. m_ptrProp.reset(np, &ECRestriction::DummyFree);
  262. else if (CopyProp(np, nullptr, ulFlags, &np) == hrSuccess)
  263. m_ptrProp.reset(np, &MAPIFreeBuffer);
  264. }
  265. ECContentRestriction::ECContentRestriction(ULONG ulFuzzyLevel, ULONG ulPropTag, PropPtr ptrProp)
  266. : m_ulFuzzyLevel(ulFuzzyLevel)
  267. , m_ulPropTag(ulPropTag)
  268. , m_ptrProp(ptrProp)
  269. {}
  270. HRESULT ECContentRestriction::GetMAPIRestriction(LPVOID lpBase, LPSRestriction lpRestriction, ULONG ulFlags) const {
  271. SRestriction restriction = {0};
  272. if (lpBase == NULL || lpRestriction == NULL)
  273. return MAPI_E_INVALID_PARAMETER;
  274. if (!m_ptrProp)
  275. return MAPI_E_NOT_ENOUGH_MEMORY;
  276. restriction.rt = RES_CONTENT;
  277. restriction.res.resContent.ulFuzzyLevel = m_ulFuzzyLevel;
  278. restriction.res.resContent.ulPropTag = m_ulPropTag;
  279. if (ulFlags & ECRestriction::Cheap)
  280. restriction.res.resContent.lpProp = m_ptrProp.get();
  281. else {
  282. HRESULT hr = CopyProp(m_ptrProp.get(), lpBase, ulFlags, &restriction.res.resContent.lpProp);
  283. if (hr != hrSuccess)
  284. return hr;
  285. }
  286. *lpRestriction = std::move(restriction);
  287. return hrSuccess;
  288. }
  289. ECRestriction *ECContentRestriction::Clone(void) const _kc_lvqual
  290. {
  291. return new ECContentRestriction(m_ulFuzzyLevel, m_ulPropTag, m_ptrProp);
  292. }
  293. /**
  294. * ECBitMaskRestriction
  295. */
  296. HRESULT ECBitMaskRestriction::GetMAPIRestriction(LPVOID lpBase, LPSRestriction lpRestriction, ULONG /*ulFlags*/) const {
  297. if (lpBase == NULL || lpRestriction == NULL)
  298. return MAPI_E_INVALID_PARAMETER;
  299. lpRestriction->rt = RES_BITMASK;
  300. lpRestriction->res.resBitMask.relBMR = m_relBMR;
  301. lpRestriction->res.resBitMask.ulMask = m_ulMask;
  302. lpRestriction->res.resBitMask.ulPropTag = m_ulPropTag;
  303. return hrSuccess;
  304. }
  305. ECRestriction *ECBitMaskRestriction::Clone(void) const _kc_lvqual
  306. {
  307. return new ECBitMaskRestriction(m_relBMR, m_ulPropTag, m_ulMask);
  308. }
  309. /**
  310. * ECPropertyRestriction
  311. */
  312. ECPropertyRestriction::ECPropertyRestriction(ULONG relop, ULONG ulPropTag,
  313. const SPropValue *lpProp, ULONG ulFlags) :
  314. m_relop(relop), m_ulPropTag(ulPropTag)
  315. {
  316. auto np = const_cast<SPropValue *>(lpProp);
  317. if (ulFlags & ECRestriction::Cheap)
  318. m_ptrProp.reset(np, &ECRestriction::DummyFree);
  319. else if (CopyProp(np, nullptr, ulFlags, &np) == hrSuccess)
  320. m_ptrProp.reset(np, &MAPIFreeBuffer);
  321. }
  322. ECPropertyRestriction::ECPropertyRestriction(ULONG relop, ULONG ulPropTag, PropPtr ptrProp)
  323. : m_relop(relop)
  324. , m_ulPropTag(ulPropTag)
  325. , m_ptrProp(ptrProp)
  326. {}
  327. HRESULT ECPropertyRestriction::GetMAPIRestriction(LPVOID lpBase, LPSRestriction lpRestriction, ULONG ulFlags) const {
  328. SRestriction restriction = {0};
  329. if (lpBase == NULL || lpRestriction == NULL)
  330. return MAPI_E_INVALID_PARAMETER;
  331. if (!m_ptrProp)
  332. return MAPI_E_NOT_ENOUGH_MEMORY;
  333. restriction.rt = RES_PROPERTY;
  334. restriction.res.resProperty.relop = m_relop;
  335. restriction.res.resProperty.ulPropTag = m_ulPropTag;
  336. if (ulFlags & ECRestriction::Cheap)
  337. restriction.res.resProperty.lpProp = m_ptrProp.get();
  338. else {
  339. HRESULT hr = CopyProp(m_ptrProp.get(), lpBase, ulFlags, &restriction.res.resContent.lpProp);
  340. if (hr != hrSuccess)
  341. return hr;
  342. }
  343. *lpRestriction = std::move(restriction);
  344. return hrSuccess;
  345. }
  346. ECRestriction *ECPropertyRestriction::Clone(void) const _kc_lvqual
  347. {
  348. return new ECPropertyRestriction(m_relop, m_ulPropTag, m_ptrProp);
  349. }
  350. /**
  351. * ECComparePropsRestriction
  352. */
  353. HRESULT ECComparePropsRestriction::GetMAPIRestriction(LPVOID lpBase, LPSRestriction lpRestriction, ULONG /*ulFlags*/) const {
  354. if (lpBase == NULL || lpRestriction == NULL)
  355. return MAPI_E_INVALID_PARAMETER;
  356. lpRestriction->rt = RES_COMPAREPROPS;
  357. lpRestriction->res.resCompareProps.relop = m_relop;
  358. lpRestriction->res.resCompareProps.ulPropTag1 = m_ulPropTag1;
  359. lpRestriction->res.resCompareProps.ulPropTag2 = m_ulPropTag2;
  360. return hrSuccess;
  361. }
  362. ECRestriction *ECComparePropsRestriction::Clone(void) const _kc_lvqual
  363. {
  364. return new ECComparePropsRestriction(m_relop, m_ulPropTag1, m_ulPropTag2);
  365. }
  366. /**
  367. * ECExistRestriction
  368. */
  369. HRESULT ECExistRestriction::GetMAPIRestriction(LPVOID lpBase, LPSRestriction lpRestriction, ULONG /*ulFlags*/) const {
  370. if (lpBase == NULL || lpRestriction == NULL)
  371. return MAPI_E_INVALID_PARAMETER;
  372. lpRestriction->rt = RES_EXIST;
  373. lpRestriction->res.resExist.ulPropTag = m_ulPropTag;
  374. return hrSuccess;
  375. }
  376. ECRestriction *ECExistRestriction::Clone(void) const _kc_lvqual
  377. {
  378. return new ECExistRestriction(m_ulPropTag);
  379. }
  380. /**
  381. * ECRawRestriction
  382. */
  383. ECRawRestriction::ECRawRestriction(const SRestriction *lpRestriction,
  384. ULONG ulFlags)
  385. {
  386. if (ulFlags & ECRestriction::Cheap) {
  387. m_ptrRestriction.reset(const_cast<SRestriction *>(lpRestriction), &ECRestriction::DummyFree);
  388. return;
  389. }
  390. SRestrictionPtr ptrResTmp;
  391. HRESULT hr = MAPIAllocateBuffer(sizeof(SRestrictionPtr::value_type), &~ptrResTmp);
  392. if (hr != hrSuccess)
  393. return;
  394. if (ulFlags & ECRestriction::Shallow)
  395. *ptrResTmp = *lpRestriction;
  396. else {
  397. hr = Util::HrCopySRestriction(ptrResTmp, lpRestriction, ptrResTmp);
  398. if (hr != hrSuccess)
  399. return;
  400. }
  401. m_ptrRestriction.reset(ptrResTmp.release(), &MAPIFreeBuffer);
  402. }
  403. ECRawRestriction::ECRawRestriction(RawResPtr ptrRestriction)
  404. : m_ptrRestriction(ptrRestriction)
  405. { }
  406. HRESULT ECRawRestriction::GetMAPIRestriction(LPVOID lpBase, LPSRestriction lpRestriction, ULONG ulFlags) const {
  407. HRESULT hr = hrSuccess;
  408. if (lpBase == NULL || lpRestriction == NULL)
  409. return MAPI_E_INVALID_PARAMETER;
  410. if (!m_ptrRestriction)
  411. return MAPI_E_NOT_ENOUGH_MEMORY;
  412. if (ulFlags & (ECRestriction::Cheap | ECRestriction::Shallow))
  413. *lpRestriction = *m_ptrRestriction;
  414. else
  415. hr = Util::HrCopySRestriction(lpRestriction, m_ptrRestriction.get(), lpBase);
  416. return hr;
  417. }
  418. ECRestriction *ECRawRestriction::Clone(void) const _kc_lvqual
  419. {
  420. return new ECRawRestriction(m_ptrRestriction);
  421. }
  422. } /* namespace KC */