ECRulesTableProxy.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  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 <kopano/memory.hpp>
  20. #include "ECRulesTableProxy.h"
  21. #include <kopano/ECGuid.h>
  22. #include <kopano/mapi_ptr.h>
  23. #include <kopano/ECInterfaceDefs.h>
  24. #include <kopano/Trace.h>
  25. #include <kopano/charset/convert.h>
  26. #include <mapix.h>
  27. /* conversion from unicode to string8 for rules table data */
  28. static HRESULT ConvertUnicodeToString8(LPSRestriction lpRes, void *base, convert_context &converter);
  29. static HRESULT ConvertUnicodeToString8(const ACTIONS *lpActions, void *base, convert_context &converter);
  30. ECRulesTableProxy::ECRulesTableProxy(LPMAPITABLE lpTable)
  31. : m_lpTable(lpTable)
  32. {
  33. m_lpTable->AddRef();
  34. }
  35. ECRulesTableProxy::~ECRulesTableProxy()
  36. {
  37. m_lpTable->Release();
  38. }
  39. HRESULT ECRulesTableProxy::Create(LPMAPITABLE lpTable, ECRulesTableProxy **lppRulesTableProxy)
  40. {
  41. if (lpTable == NULL || lppRulesTableProxy == NULL)
  42. return MAPI_E_INVALID_PARAMETER;
  43. KCHL::object_ptr<ECRulesTableProxy> ptrRulesTableProxy(new(std::nothrow) ECRulesTableProxy(lpTable));
  44. if (ptrRulesTableProxy == nullptr)
  45. return MAPI_E_NOT_ENOUGH_MEMORY;
  46. *lppRulesTableProxy = ptrRulesTableProxy.release();
  47. return hrSuccess;
  48. }
  49. HRESULT ECRulesTableProxy::QueryInterface(REFIID refiid, void **lppInterface)
  50. {
  51. REGISTER_INTERFACE2(ECUnknown, this);
  52. REGISTER_INTERFACE2(IMAPITable, &this->m_xMAPITable);
  53. REGISTER_INTERFACE2(IUnknown, &this->m_xMAPITable);
  54. return MAPI_E_INTERFACE_NOT_SUPPORTED;
  55. }
  56. HRESULT ECRulesTableProxy::GetLastError(HRESULT hResult, ULONG ulFlags, LPMAPIERROR *lppMAPIError)
  57. {
  58. return m_lpTable->GetLastError(hResult, ulFlags, lppMAPIError);
  59. }
  60. HRESULT ECRulesTableProxy::Advise(ULONG ulEventMask, LPMAPIADVISESINK lpAdviseSink, ULONG *lpulConnection)
  61. {
  62. return m_lpTable->Advise(ulEventMask, lpAdviseSink, lpulConnection);
  63. }
  64. HRESULT ECRulesTableProxy::Unadvise(ULONG ulConnection)
  65. {
  66. return m_lpTable->Unadvise(ulConnection);
  67. }
  68. HRESULT ECRulesTableProxy::GetStatus(ULONG *lpulTableStatus, ULONG *lpulTableType)
  69. {
  70. return m_lpTable->GetStatus(lpulTableStatus, lpulTableType);
  71. }
  72. HRESULT ECRulesTableProxy::SetColumns(const SPropTagArray *lpPropTagArray,
  73. ULONG ulFlags)
  74. {
  75. return m_lpTable->SetColumns(lpPropTagArray, ulFlags);
  76. }
  77. HRESULT ECRulesTableProxy::QueryColumns(ULONG ulFlags, LPSPropTagArray *lpPropTagArray)
  78. {
  79. return m_lpTable->QueryColumns(ulFlags, lpPropTagArray);
  80. }
  81. HRESULT ECRulesTableProxy::GetRowCount(ULONG ulFlags, ULONG *lpulCount)
  82. {
  83. return m_lpTable->GetRowCount(ulFlags, lpulCount);
  84. }
  85. HRESULT ECRulesTableProxy::SeekRow(BOOKMARK bkOrigin, LONG lRowCount, LONG *lplRowsSought)
  86. {
  87. return m_lpTable->SeekRow(bkOrigin, lRowCount, lplRowsSought);
  88. }
  89. HRESULT ECRulesTableProxy::SeekRowApprox(ULONG ulNumerator, ULONG ulDenominator)
  90. {
  91. return m_lpTable->SeekRowApprox(ulNumerator, ulDenominator);
  92. }
  93. HRESULT ECRulesTableProxy::QueryPosition(ULONG *lpulRow, ULONG *lpulNumerator, ULONG *lpulDenominator)
  94. {
  95. return m_lpTable->QueryPosition(lpulRow, lpulNumerator, lpulDenominator);
  96. }
  97. HRESULT ECRulesTableProxy::FindRow(LPSRestriction lpRestriction, BOOKMARK bkOrigin, ULONG ulFlags)
  98. {
  99. return m_lpTable->FindRow(lpRestriction, bkOrigin, ulFlags);
  100. }
  101. HRESULT ECRulesTableProxy::Restrict(LPSRestriction lpRestriction, ULONG ulFlags)
  102. {
  103. return m_lpTable->Restrict(lpRestriction, ulFlags);
  104. }
  105. HRESULT ECRulesTableProxy::CreateBookmark(BOOKMARK* lpbkPosition)
  106. {
  107. return m_lpTable->CreateBookmark(lpbkPosition);
  108. }
  109. HRESULT ECRulesTableProxy::FreeBookmark(BOOKMARK bkPosition)
  110. {
  111. return m_lpTable->FreeBookmark(bkPosition);
  112. }
  113. HRESULT ECRulesTableProxy::SortTable(const SSortOrderSet *lpSortCriteria,
  114. ULONG ulFlags)
  115. {
  116. return m_lpTable->SortTable(lpSortCriteria, ulFlags);
  117. }
  118. HRESULT ECRulesTableProxy::QuerySortOrder(LPSSortOrderSet *lppSortCriteria)
  119. {
  120. return m_lpTable->QuerySortOrder(lppSortCriteria);
  121. }
  122. HRESULT ECRulesTableProxy::QueryRows(LONG lRowCount, ULONG ulFlags, LPSRowSet *lppRows)
  123. {
  124. HRESULT hr = hrSuccess;
  125. SRowSetPtr ptrRows;
  126. convert_context converter;
  127. hr = m_lpTable->QueryRows(lRowCount, ulFlags, &ptrRows);
  128. if (hr != hrSuccess)
  129. return hr;
  130. // table PR_RULE_ACTIONS and PR_RULE_CONDITION contain PT_UNICODE data, which we must convert to local charset PT_STRING8
  131. // so we update the rows before we return them to the caller.
  132. for (SRowSetPtr::size_type i = 0; i < ptrRows.size(); ++i) {
  133. auto lpRuleProp = PCpropFindProp(ptrRows[i].lpProps, ptrRows[i].cValues, PR_RULE_CONDITION);
  134. if (lpRuleProp)
  135. hr = ConvertUnicodeToString8((LPSRestriction)lpRuleProp->Value.lpszA, ptrRows[i].lpProps, converter);
  136. if (hr != hrSuccess)
  137. return hr;
  138. lpRuleProp = PCpropFindProp(ptrRows[i].lpProps, ptrRows[i].cValues, PR_RULE_ACTIONS);
  139. if (lpRuleProp)
  140. hr = ConvertUnicodeToString8((ACTIONS*)lpRuleProp->Value.lpszA, ptrRows[i].lpProps, converter);
  141. if (hr != hrSuccess)
  142. return hr;
  143. }
  144. *lppRows = ptrRows.release();
  145. return hr;
  146. }
  147. HRESULT ECRulesTableProxy::Abort()
  148. {
  149. return m_lpTable->Abort();
  150. }
  151. HRESULT ECRulesTableProxy::ExpandRow(ULONG cbInstanceKey, LPBYTE pbInstanceKey, ULONG ulRowCount, ULONG ulFlags, LPSRowSet * lppRows, ULONG *lpulMoreRows)
  152. {
  153. return m_lpTable->ExpandRow(cbInstanceKey, pbInstanceKey, ulRowCount, ulFlags, lppRows, lpulMoreRows);
  154. }
  155. HRESULT ECRulesTableProxy::CollapseRow(ULONG cbInstanceKey, LPBYTE pbInstanceKey, ULONG ulFlags, ULONG *lpulRowCount)
  156. {
  157. return m_lpTable->CollapseRow(cbInstanceKey, pbInstanceKey, ulFlags, lpulRowCount);
  158. }
  159. HRESULT ECRulesTableProxy::WaitForCompletion(ULONG ulFlags, ULONG ulTimeout, ULONG *lpulTableStatus)
  160. {
  161. return m_lpTable->WaitForCompletion(ulFlags, ulTimeout, lpulTableStatus);
  162. }
  163. HRESULT ECRulesTableProxy::GetCollapseState(ULONG ulFlags, ULONG cbInstanceKey, LPBYTE lpbInstanceKey, ULONG *lpcbCollapseState, LPBYTE *lppbCollapseState)
  164. {
  165. return m_lpTable->GetCollapseState(ulFlags, cbInstanceKey, lpbInstanceKey, lpcbCollapseState, lppbCollapseState);
  166. }
  167. HRESULT ECRulesTableProxy::SetCollapseState(ULONG ulFlags, ULONG cbCollapseState, LPBYTE pbCollapseState, BOOKMARK *lpbkLocation)
  168. {
  169. return m_lpTable->SetCollapseState(ulFlags, cbCollapseState, pbCollapseState, lpbkLocation);
  170. }
  171. DEF_ULONGMETHOD0(ECRulesTableProxy, MAPITable, AddRef, (void))
  172. DEF_ULONGMETHOD0(ECRulesTableProxy, MAPITable, Release, (void))
  173. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, QueryInterface, (REFIID, refiid), (void **, lppInterface))
  174. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, GetLastError, (HRESULT, hResult), (ULONG, ulFlags), (LPMAPIERROR *, lppMAPIError))
  175. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, Advise, (ULONG, ulEventMask), (LPMAPIADVISESINK, lpAdviseSink), (ULONG *, lpulConnection))
  176. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, Unadvise, (ULONG, ulConnection))
  177. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, GetStatus, (ULONG *, lpulTableStatus), (ULONG *, lpulTableType))
  178. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, SetColumns, (const SPropTagArray *, lpPropTagArray), (ULONG, ulFlags))
  179. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, QueryColumns, (ULONG, ulFlags), (LPSPropTagArray *, lppPropTagArray))
  180. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, GetRowCount, (ULONG, ulFlags), (ULONG *, lpulCount))
  181. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, SeekRow, (BOOKMARK, bkOrigin), (LONG, lRowCount), (LONG *, lplRowsSought))
  182. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, SeekRowApprox, (ULONG, ulNumerator), (ULONG, ulDenominator))
  183. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, QueryPosition, (ULONG *, lpulRow), (ULONG *, lpulNumerator), (ULONG *, lpulDenominator))
  184. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, FindRow, (LPSRestriction, lpRestriction), (BOOKMARK, bkOrigin), (ULONG, ulFlags))
  185. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, Restrict, (LPSRestriction, lpRestriction), (ULONG, ulFlags))
  186. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, CreateBookmark, (BOOKMARK *, lpbkPosition))
  187. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, FreeBookmark, (BOOKMARK, bkPosition))
  188. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, SortTable, (const SSortOrderSet *, lpSortCriteria), (ULONG, ulFlags))
  189. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, QuerySortOrder, (LPSSortOrderSet *, lppSortCriteria))
  190. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, QueryRows, (LONG, lRowCount), (ULONG, ulFlags), (LPSRowSet *, lppRows))
  191. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, Abort, (void))
  192. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, ExpandRow, (ULONG, cbInstanceKey), (LPBYTE, pbInstanceKey), (ULONG, ulRowCount), (ULONG, ulFlags), (LPSRowSet *, lppRows), (ULONG *, lpulMoreRows))
  193. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, CollapseRow, (ULONG, cbInstanceKey), (LPBYTE, pbInstanceKey), (ULONG, ulFlags), (ULONG *, lpulRowCount))
  194. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, WaitForCompletion, (ULONG, ulFlags), (ULONG, ulTimeout), (ULONG *, lpulTableStatus))
  195. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, GetCollapseState, (ULONG, ulFlags), (ULONG, cbInstanceKey), (LPBYTE, lpbInstanceKey), (ULONG *, lpcbCollapseState), (LPBYTE *, lppbCollapseState))
  196. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, SetCollapseState, (ULONG, ulFlags), (ULONG, cbCollapseState), (LPBYTE, pbCollapseState), (BOOKMARK *, lpbkLocation))
  197. static HRESULT ConvertUnicodeToString8(const WCHAR *lpszW, char **lppszA,
  198. void *base, convert_context &converter)
  199. {
  200. std::string local;
  201. char *lpszA = NULL;
  202. if (lpszW == NULL || lppszA == NULL)
  203. return MAPI_E_INVALID_PARAMETER;
  204. TryConvert(lpszW, local);
  205. HRESULT hr = MAPIAllocateMore((local.length() +1) * sizeof(std::string::value_type),
  206. base, reinterpret_cast<void **>(&lpszA));
  207. if (hr != hrSuccess)
  208. return hr;
  209. strcpy(lpszA, local.c_str());
  210. *lppszA = lpszA;
  211. return hrSuccess;
  212. }
  213. static HRESULT ConvertUnicodeToString8(LPSRestriction lpRestriction,
  214. void *base, convert_context &converter)
  215. {
  216. HRESULT hr = hrSuccess;
  217. ULONG i;
  218. if (lpRestriction == NULL)
  219. return hrSuccess;
  220. switch (lpRestriction->rt) {
  221. case RES_OR:
  222. for (i = 0; i < lpRestriction->res.resOr.cRes; ++i) {
  223. hr = ConvertUnicodeToString8(&lpRestriction->res.resOr.lpRes[i], base, converter);
  224. if (hr != hrSuccess)
  225. return hr;
  226. }
  227. break;
  228. case RES_AND:
  229. for (i = 0; i < lpRestriction->res.resAnd.cRes; ++i) {
  230. hr = ConvertUnicodeToString8(&lpRestriction->res.resAnd.lpRes[i], base, converter);
  231. if (hr != hrSuccess)
  232. return hr;
  233. }
  234. break;
  235. case RES_NOT:
  236. hr = ConvertUnicodeToString8(lpRestriction->res.resNot.lpRes, base, converter);
  237. if (hr != hrSuccess)
  238. return hr;
  239. break;
  240. case RES_COMMENT:
  241. if (lpRestriction->res.resComment.lpRes) {
  242. hr = ConvertUnicodeToString8(lpRestriction->res.resComment.lpRes, base, converter);
  243. if (hr != hrSuccess)
  244. return hr;
  245. }
  246. for (i = 0; i < lpRestriction->res.resComment.cValues; ++i)
  247. if (PROP_TYPE(lpRestriction->res.resComment.lpProp[i].ulPropTag) == PT_UNICODE) {
  248. hr = ConvertUnicodeToString8(lpRestriction->res.resComment.lpProp[i].Value.lpszW, &lpRestriction->res.resComment.lpProp[i].Value.lpszA, base, converter);
  249. if (hr != hrSuccess)
  250. return hr;
  251. lpRestriction->res.resComment.lpProp[i].ulPropTag = CHANGE_PROP_TYPE(lpRestriction->res.resComment.lpProp[i].ulPropTag, PT_STRING8);
  252. }
  253. break;
  254. case RES_COMPAREPROPS:
  255. break;
  256. case RES_CONTENT:
  257. if (PROP_TYPE(lpRestriction->res.resContent.ulPropTag) == PT_UNICODE) {
  258. hr = ConvertUnicodeToString8(lpRestriction->res.resContent.lpProp->Value.lpszW, &lpRestriction->res.resContent.lpProp->Value.lpszA, base, converter);
  259. if (hr != hrSuccess)
  260. return hr;
  261. lpRestriction->res.resContent.lpProp->ulPropTag = CHANGE_PROP_TYPE(lpRestriction->res.resContent.lpProp->ulPropTag, PT_STRING8);
  262. lpRestriction->res.resContent.ulPropTag = CHANGE_PROP_TYPE(lpRestriction->res.resContent.ulPropTag, PT_STRING8);
  263. }
  264. break;
  265. case RES_PROPERTY:
  266. if (PROP_TYPE(lpRestriction->res.resProperty.ulPropTag) == PT_UNICODE) {
  267. hr = ConvertUnicodeToString8(lpRestriction->res.resProperty.lpProp->Value.lpszW, &lpRestriction->res.resProperty.lpProp->Value.lpszA, base, converter);
  268. if (hr != hrSuccess)
  269. return hr;
  270. lpRestriction->res.resProperty.lpProp->ulPropTag = CHANGE_PROP_TYPE(lpRestriction->res.resProperty.lpProp->ulPropTag, PT_STRING8);
  271. lpRestriction->res.resProperty.ulPropTag = CHANGE_PROP_TYPE(lpRestriction->res.resProperty.ulPropTag, PT_STRING8);
  272. }
  273. break;
  274. case RES_SUBRESTRICTION:
  275. hr = ConvertUnicodeToString8(lpRestriction->res.resSub.lpRes, base, converter);
  276. if (hr != hrSuccess)
  277. return hr;
  278. break;
  279. }
  280. return hr;
  281. }
  282. static HRESULT ConvertUnicodeToString8(const SRow *lpRow, void *base,
  283. convert_context &converter)
  284. {
  285. if (lpRow == NULL)
  286. return hrSuccess;
  287. for (ULONG c = 0; c < lpRow->cValues; ++c) {
  288. if (PROP_TYPE(lpRow->lpProps[c].ulPropTag) == PT_UNICODE) {
  289. HRESULT hr = ConvertUnicodeToString8(lpRow->lpProps[c].Value.lpszW,
  290. &lpRow->lpProps[c].Value.lpszA, base, converter);
  291. if (hr != hrSuccess)
  292. return hr;
  293. lpRow->lpProps[c].ulPropTag = CHANGE_PROP_TYPE(lpRow->lpProps[c].ulPropTag, PT_STRING8);
  294. }
  295. }
  296. return hrSuccess;
  297. }
  298. static HRESULT ConvertUnicodeToString8(const ADRLIST *lpAdrList, void *base,
  299. convert_context &converter)
  300. {
  301. if (lpAdrList == NULL)
  302. return hrSuccess;
  303. for (ULONG c = 0; c < lpAdrList->cEntries; ++c) {
  304. // treat as row
  305. HRESULT hr = ConvertUnicodeToString8(reinterpret_cast<const SRow *>(&lpAdrList->aEntries[c]),
  306. base, converter);
  307. if (hr != hrSuccess)
  308. return hr;
  309. }
  310. return hrSuccess;
  311. }
  312. static HRESULT ConvertUnicodeToString8(const ACTIONS *lpActions, void *base, convert_context &converter)
  313. {
  314. if (lpActions == NULL)
  315. return hrSuccess;
  316. for (ULONG c = 0; c < lpActions->cActions; ++c)
  317. if (lpActions->lpAction[c].acttype == OP_FORWARD || lpActions->lpAction[c].acttype == OP_DELEGATE) {
  318. HRESULT hr = ConvertUnicodeToString8(lpActions->lpAction[c].lpadrlist, base, converter);
  319. if (hr != hrSuccess)
  320. return hr;
  321. }
  322. return hrSuccess;
  323. }