ECRulesTableProxy.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  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. SRowSetPtr ptrRows;
  125. convert_context converter;
  126. HRESULT hr = m_lpTable->QueryRows(lRowCount, ulFlags, &ptrRows);
  127. if (hr != hrSuccess)
  128. return hr;
  129. // table PR_RULE_ACTIONS and PR_RULE_CONDITION contain PT_UNICODE data, which we must convert to local charset PT_STRING8
  130. // so we update the rows before we return them to the caller.
  131. for (SRowSetPtr::size_type i = 0; i < ptrRows.size(); ++i) {
  132. auto lpRuleProp = PCpropFindProp(ptrRows[i].lpProps, ptrRows[i].cValues, PR_RULE_CONDITION);
  133. if (lpRuleProp)
  134. hr = ConvertUnicodeToString8((LPSRestriction)lpRuleProp->Value.lpszA, ptrRows[i].lpProps, converter);
  135. if (hr != hrSuccess)
  136. return hr;
  137. lpRuleProp = PCpropFindProp(ptrRows[i].lpProps, ptrRows[i].cValues, PR_RULE_ACTIONS);
  138. if (lpRuleProp)
  139. hr = ConvertUnicodeToString8((ACTIONS*)lpRuleProp->Value.lpszA, ptrRows[i].lpProps, converter);
  140. if (hr != hrSuccess)
  141. return hr;
  142. }
  143. *lppRows = ptrRows.release();
  144. return hrSuccess;
  145. }
  146. HRESULT ECRulesTableProxy::Abort()
  147. {
  148. return m_lpTable->Abort();
  149. }
  150. HRESULT ECRulesTableProxy::ExpandRow(ULONG cbInstanceKey, LPBYTE pbInstanceKey, ULONG ulRowCount, ULONG ulFlags, LPSRowSet * lppRows, ULONG *lpulMoreRows)
  151. {
  152. return m_lpTable->ExpandRow(cbInstanceKey, pbInstanceKey, ulRowCount, ulFlags, lppRows, lpulMoreRows);
  153. }
  154. HRESULT ECRulesTableProxy::CollapseRow(ULONG cbInstanceKey, LPBYTE pbInstanceKey, ULONG ulFlags, ULONG *lpulRowCount)
  155. {
  156. return m_lpTable->CollapseRow(cbInstanceKey, pbInstanceKey, ulFlags, lpulRowCount);
  157. }
  158. HRESULT ECRulesTableProxy::WaitForCompletion(ULONG ulFlags, ULONG ulTimeout, ULONG *lpulTableStatus)
  159. {
  160. return m_lpTable->WaitForCompletion(ulFlags, ulTimeout, lpulTableStatus);
  161. }
  162. HRESULT ECRulesTableProxy::GetCollapseState(ULONG ulFlags, ULONG cbInstanceKey, LPBYTE lpbInstanceKey, ULONG *lpcbCollapseState, LPBYTE *lppbCollapseState)
  163. {
  164. return m_lpTable->GetCollapseState(ulFlags, cbInstanceKey, lpbInstanceKey, lpcbCollapseState, lppbCollapseState);
  165. }
  166. HRESULT ECRulesTableProxy::SetCollapseState(ULONG ulFlags, ULONG cbCollapseState, LPBYTE pbCollapseState, BOOKMARK *lpbkLocation)
  167. {
  168. return m_lpTable->SetCollapseState(ulFlags, cbCollapseState, pbCollapseState, lpbkLocation);
  169. }
  170. DEF_ULONGMETHOD0(ECRulesTableProxy, MAPITable, AddRef, (void))
  171. DEF_ULONGMETHOD0(ECRulesTableProxy, MAPITable, Release, (void))
  172. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, QueryInterface, (REFIID, refiid), (void **, lppInterface))
  173. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, GetLastError, (HRESULT, hResult), (ULONG, ulFlags), (LPMAPIERROR *, lppMAPIError))
  174. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, Advise, (ULONG, ulEventMask), (LPMAPIADVISESINK, lpAdviseSink), (ULONG *, lpulConnection))
  175. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, Unadvise, (ULONG, ulConnection))
  176. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, GetStatus, (ULONG *, lpulTableStatus), (ULONG *, lpulTableType))
  177. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, SetColumns, (const SPropTagArray *, lpPropTagArray), (ULONG, ulFlags))
  178. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, QueryColumns, (ULONG, ulFlags), (LPSPropTagArray *, lppPropTagArray))
  179. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, GetRowCount, (ULONG, ulFlags), (ULONG *, lpulCount))
  180. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, SeekRow, (BOOKMARK, bkOrigin), (LONG, lRowCount), (LONG *, lplRowsSought))
  181. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, SeekRowApprox, (ULONG, ulNumerator), (ULONG, ulDenominator))
  182. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, QueryPosition, (ULONG *, lpulRow), (ULONG *, lpulNumerator), (ULONG *, lpulDenominator))
  183. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, FindRow, (LPSRestriction, lpRestriction), (BOOKMARK, bkOrigin), (ULONG, ulFlags))
  184. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, Restrict, (LPSRestriction, lpRestriction), (ULONG, ulFlags))
  185. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, CreateBookmark, (BOOKMARK *, lpbkPosition))
  186. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, FreeBookmark, (BOOKMARK, bkPosition))
  187. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, SortTable, (const SSortOrderSet *, lpSortCriteria), (ULONG, ulFlags))
  188. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, QuerySortOrder, (LPSSortOrderSet *, lppSortCriteria))
  189. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, QueryRows, (LONG, lRowCount), (ULONG, ulFlags), (LPSRowSet *, lppRows))
  190. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, Abort, (void))
  191. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, ExpandRow, (ULONG, cbInstanceKey), (LPBYTE, pbInstanceKey), (ULONG, ulRowCount), (ULONG, ulFlags), (LPSRowSet *, lppRows), (ULONG *, lpulMoreRows))
  192. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, CollapseRow, (ULONG, cbInstanceKey), (LPBYTE, pbInstanceKey), (ULONG, ulFlags), (ULONG *, lpulRowCount))
  193. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, WaitForCompletion, (ULONG, ulFlags), (ULONG, ulTimeout), (ULONG *, lpulTableStatus))
  194. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, GetCollapseState, (ULONG, ulFlags), (ULONG, cbInstanceKey), (LPBYTE, lpbInstanceKey), (ULONG *, lpcbCollapseState), (LPBYTE *, lppbCollapseState))
  195. DEF_HRMETHOD(TRACE_MAPI, ECRulesTableProxy, MAPITable, SetCollapseState, (ULONG, ulFlags), (ULONG, cbCollapseState), (LPBYTE, pbCollapseState), (BOOKMARK *, lpbkLocation))
  196. static HRESULT ConvertUnicodeToString8(const WCHAR *lpszW, char **lppszA,
  197. void *base, convert_context &converter)
  198. {
  199. std::string local;
  200. char *lpszA = NULL;
  201. if (lpszW == NULL || lppszA == NULL)
  202. return MAPI_E_INVALID_PARAMETER;
  203. TryConvert(lpszW, local);
  204. HRESULT hr = MAPIAllocateMore((local.length() + 1) * sizeof(std::string::value_type),
  205. base, reinterpret_cast<void **>(&lpszA));
  206. if (hr != hrSuccess)
  207. return hr;
  208. strcpy(lpszA, local.c_str());
  209. *lppszA = lpszA;
  210. return hrSuccess;
  211. }
  212. static HRESULT ConvertUnicodeToString8(LPSRestriction lpRestriction,
  213. void *base, convert_context &converter)
  214. {
  215. HRESULT hr = hrSuccess;
  216. ULONG i;
  217. if (lpRestriction == NULL)
  218. return hr;
  219. switch (lpRestriction->rt) {
  220. case RES_OR:
  221. for (i = 0; i < lpRestriction->res.resOr.cRes; ++i) {
  222. hr = ConvertUnicodeToString8(&lpRestriction->res.resOr.lpRes[i], base, converter);
  223. if (hr != hrSuccess)
  224. return hr;
  225. }
  226. break;
  227. case RES_AND:
  228. for (i = 0; i < lpRestriction->res.resAnd.cRes; ++i) {
  229. hr = ConvertUnicodeToString8(&lpRestriction->res.resAnd.lpRes[i], base, converter);
  230. if (hr != hrSuccess)
  231. return hr;
  232. }
  233. break;
  234. case RES_NOT:
  235. hr = ConvertUnicodeToString8(lpRestriction->res.resNot.lpRes, base, converter);
  236. if (hr != hrSuccess)
  237. return hr;
  238. break;
  239. case RES_COMMENT:
  240. if (lpRestriction->res.resComment.lpRes) {
  241. hr = ConvertUnicodeToString8(lpRestriction->res.resComment.lpRes, base, converter);
  242. if (hr != hrSuccess)
  243. return hr;
  244. }
  245. for (i = 0; i < lpRestriction->res.resComment.cValues; ++i)
  246. if (PROP_TYPE(lpRestriction->res.resComment.lpProp[i].ulPropTag) == PT_UNICODE) {
  247. hr = ConvertUnicodeToString8(lpRestriction->res.resComment.lpProp[i].Value.lpszW, &lpRestriction->res.resComment.lpProp[i].Value.lpszA, base, converter);
  248. if (hr != hrSuccess)
  249. return hr;
  250. lpRestriction->res.resComment.lpProp[i].ulPropTag = CHANGE_PROP_TYPE(lpRestriction->res.resComment.lpProp[i].ulPropTag, PT_STRING8);
  251. }
  252. break;
  253. case RES_COMPAREPROPS:
  254. break;
  255. case RES_CONTENT:
  256. if (PROP_TYPE(lpRestriction->res.resContent.ulPropTag) == PT_UNICODE) {
  257. hr = ConvertUnicodeToString8(lpRestriction->res.resContent.lpProp->Value.lpszW, &lpRestriction->res.resContent.lpProp->Value.lpszA, base, converter);
  258. if (hr != hrSuccess)
  259. return hr;
  260. lpRestriction->res.resContent.lpProp->ulPropTag = CHANGE_PROP_TYPE(lpRestriction->res.resContent.lpProp->ulPropTag, PT_STRING8);
  261. lpRestriction->res.resContent.ulPropTag = CHANGE_PROP_TYPE(lpRestriction->res.resContent.ulPropTag, PT_STRING8);
  262. }
  263. break;
  264. case RES_PROPERTY:
  265. if (PROP_TYPE(lpRestriction->res.resProperty.ulPropTag) == PT_UNICODE) {
  266. hr = ConvertUnicodeToString8(lpRestriction->res.resProperty.lpProp->Value.lpszW, &lpRestriction->res.resProperty.lpProp->Value.lpszA, base, converter);
  267. if (hr != hrSuccess)
  268. return hr;
  269. lpRestriction->res.resProperty.lpProp->ulPropTag = CHANGE_PROP_TYPE(lpRestriction->res.resProperty.lpProp->ulPropTag, PT_STRING8);
  270. lpRestriction->res.resProperty.ulPropTag = CHANGE_PROP_TYPE(lpRestriction->res.resProperty.ulPropTag, PT_STRING8);
  271. }
  272. break;
  273. case RES_SUBRESTRICTION:
  274. hr = ConvertUnicodeToString8(lpRestriction->res.resSub.lpRes, base, converter);
  275. if (hr != hrSuccess)
  276. return hr;
  277. break;
  278. }
  279. return hr;
  280. }
  281. static HRESULT ConvertUnicodeToString8(const SRow *lpRow, void *base,
  282. convert_context &converter)
  283. {
  284. if (lpRow == NULL)
  285. return hrSuccess;
  286. for (ULONG c = 0; c < lpRow->cValues; ++c) {
  287. if (PROP_TYPE(lpRow->lpProps[c].ulPropTag) == PT_UNICODE) {
  288. HRESULT hr = ConvertUnicodeToString8(lpRow->lpProps[c].Value.lpszW,
  289. &lpRow->lpProps[c].Value.lpszA, base, converter);
  290. if (hr != hrSuccess)
  291. return hr;
  292. lpRow->lpProps[c].ulPropTag = CHANGE_PROP_TYPE(lpRow->lpProps[c].ulPropTag, PT_STRING8);
  293. }
  294. }
  295. return hrSuccess;
  296. }
  297. static HRESULT ConvertUnicodeToString8(const ADRLIST *lpAdrList, void *base,
  298. convert_context &converter)
  299. {
  300. if (lpAdrList == NULL)
  301. return hrSuccess;
  302. for (ULONG c = 0; c < lpAdrList->cEntries; ++c) {
  303. // treat as row
  304. HRESULT hr = ConvertUnicodeToString8(reinterpret_cast<const SRow *>(&lpAdrList->aEntries[c]),
  305. base, converter);
  306. if (hr != hrSuccess)
  307. return hr;
  308. }
  309. return hrSuccess;
  310. }
  311. static HRESULT ConvertUnicodeToString8(const ACTIONS *lpActions, void *base, convert_context &converter)
  312. {
  313. if (lpActions == NULL)
  314. return hrSuccess;
  315. for (ULONG c = 0; c < lpActions->cActions; ++c)
  316. if (lpActions->lpAction[c].acttype == OP_FORWARD || lpActions->lpAction[c].acttype == OP_DELEGATE) {
  317. HRESULT hr = ConvertUnicodeToString8(lpActions->lpAction[c].lpadrlist, base, converter);
  318. if (hr != hrSuccess)
  319. return hr;
  320. }
  321. return hrSuccess;
  322. }