ECSyncContext.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  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. #ifndef ECSYNCCONTEXT_H
  18. #define ECSYNCCONTEXT_H
  19. #include <mutex>
  20. #include <kopano/zcdefs.h>
  21. #include <mapidefs.h>
  22. #include "../provider/client/ics_client.hpp"
  23. #include <map>
  24. #include <set>
  25. #include <string>
  26. #include <IECChangeAdvisor.h>
  27. #include <IECChangeAdviseSink.h>
  28. namespace KC {
  29. typedef std::map<std::string, IStream *> StatusStreamMap;
  30. typedef std::map<std::string,SSyncState> SyncStateMap;
  31. typedef std::map<ULONG,ULONG> NotifiedSyncIdMap;
  32. class ECLogger;
  33. class ECSyncSettings;
  34. /**
  35. * ECSyncContext: This class encapsulates all synchronization related information that is
  36. * only related to one side of the sync process (online or offline).
  37. */
  38. class ECSyncContext _kc_final {
  39. public:
  40. /**
  41. * Construct a sync context.
  42. *
  43. * @param[in] lpStore
  44. * The store for which to create the sync context.
  45. * @param[in] lpLogger
  46. * The logger to log to.
  47. */
  48. ECSyncContext(LPMDB lpStore, ECLogger *lpLogger);
  49. /**
  50. * Destructor.
  51. */
  52. ~ECSyncContext();
  53. /**
  54. * Get a pointer to the message store on which this sync context operates.
  55. * The underlying objects reference will be incremented, so the obtained
  56. * pointer needs to be released when it's not needed anymore.
  57. *
  58. * @param[out] lppMsgStore
  59. * Pointer to a IMsgStore pointer, which will contain
  60. * a pointer to the requested messages store upon successful
  61. * completion.
  62. */
  63. HRESULT HrGetMsgStore(LPMDB *lppMsgStore);
  64. /**
  65. * Get the receive folder of the message store on which this sync context operates.
  66. * The underlying objects reference will be incremented, so the obtained
  67. * pointer needs to be released when it's not needed anymore.
  68. *
  69. * @param[out] lppInboxFolder
  70. * Pointer to a IMAPIFolder pointer, which will contain a
  71. * pointer to the requested folder upon successful completion.
  72. */
  73. HRESULT HrGetReceiveFolder(LPMAPIFOLDER *lppInboxFolder);
  74. /**
  75. * Get the change advisor for this sync context.
  76. * The underlying objects reference will be incremented, so the obtained
  77. * pointer needs to be released when it's not needed anymore.
  78. *
  79. * @param[out] lppChangeAdvisor
  80. * Pointer to a IECChangeAdvisor pointer, which will contain a
  81. * pointer to the change advisor upon successful completion.
  82. * @return MAPI_E_NO_SUPPORT if the change notification system is disabled.
  83. */
  84. HRESULT HrGetChangeAdvisor(IECChangeAdvisor **lppChangeAdvisor);
  85. /**
  86. * Replace the change advisor. This causes all the registered change advises
  87. * to be dropped. Also the map with received states is cleared.
  88. */
  89. HRESULT HrResetChangeAdvisor();
  90. /**
  91. * Get the change advise sink for this sync context.
  92. * The underlying objects reference will be incremented, so the obtained
  93. * pointer needs to be released when it's not needed anymore.
  94. *
  95. * @param[out] lppChangeAdviseSink
  96. * Pointer to a IECChangeAdviseSInk pointer, which will contain a
  97. * pointer to the change advise sink upon successful completion.
  98. */
  99. HRESULT HrGetChangeAdviseSink(IECChangeAdviseSink **lppChangeAdviseSink);
  100. /**
  101. * Get the full hierarchy for the store on which this sync context operates.
  102. *
  103. * @param[in] lpsPropTags
  104. * The proptags of the properties that should be obtained
  105. * from the hierarchy table.
  106. * @param[out] lppRows
  107. * Pointer to a SRowSet pointer, which will be populated with
  108. * the rows from the hierarchy table. Needs to be freed with
  109. * FreePRows by the caller.
  110. */
  111. HRESULT HrQueryHierarchyTable(LPSPropTagArray lpsPropTags, LPSRowSet *lppRows);
  112. /**
  113. * Get the root folder for the current sync context.
  114. *
  115. * @param[in] lppRootFolder
  116. * Pointer to a IMAPIFolder pointer that will contain a pointer
  117. * to the root folder upon successful completion.
  118. * @param[in] lppMsgStore
  119. * Pointer to a IMsgStore pointer that will contain a pointer to
  120. * the message store upon successful completion. Passing NULL will
  121. * cause no MsgStore pointer to be returned.
  122. */
  123. HRESULT HrOpenRootFolder(LPMAPIFOLDER *lppRootFolder, LPMDB *lppMsgStore = NULL);
  124. /**
  125. * Open a folder using the store used by the current sync context.
  126. *
  127. * @param[in] lpsEntryID
  128. * Pointer to a SBinary structure that will be interpreted as the
  129. * entry id of the folder to open.
  130. * @param[out] lppFolder
  131. * Pointer to a IMAPIFolder pointer that will contain a pointer to
  132. * the requested folder upon successful completion.
  133. */
  134. HRESULT HrOpenFolder(SBinary *lpsEntryID, LPMAPIFOLDER *lppFolder);
  135. /**
  136. * Send a new mail notification through the current sync context.
  137. *
  138. * @Param[in] lpNotification
  139. * Pointer to a NOTIFICATION structure that will be send as the
  140. * new mail notification.
  141. */
  142. HRESULT HrNotifyNewMail(LPNOTIFICATION lpNotification);
  143. /**
  144. * Get the number of steps necessary to complete a sync on a particular folder.
  145. *
  146. * @param[in] lpEntryID
  147. * Pointer to a SBinary structure that will be interpreted as the
  148. * entry id of the folder to synchronize.
  149. * @param[in] lpSourceKey
  150. * Pointer to a SBinary structure that will be interpreted as the
  151. * source key of the folder to synchronize.
  152. * @param[in] ulSyncFlags
  153. * Flags that control the behavior of the sync operation.
  154. * @param[out] lpulSteps
  155. * Pointer to a ULONG variable that will contain the number of steps
  156. * to complete a synchronization on the selected folder upon successful
  157. * completion.
  158. */
  159. HRESULT HrGetSteps(SBinary *lpEntryID, SBinary *lpSourceKey, ULONG ulSyncFlags, ULONG *lpulSteps);
  160. /**
  161. * Update the change id for a particular sync id, based on a state stream.
  162. * This will cause folders that have pending changes to be removed if the change id
  163. * in the stream is greater or equal to the change id for which the pending change
  164. * was queued.
  165. *
  166. * @param[in] lpStream
  167. * The state stream from which the sync id and change id will be
  168. * extracted.
  169. */
  170. HRESULT HrUpdateChangeId(LPSTREAM lpStream);
  171. /**
  172. * Check if the sync status streams have been loaded.
  173. *
  174. * @return true if sync status streams have been loaded, false otherwise.
  175. */
  176. bool SyncStatusLoaded() const;
  177. /**
  178. * Clear the sync status streams.
  179. */
  180. HRESULT HrClearSyncStatus();
  181. /**
  182. * Load the sync status streams.
  183. *
  184. * @param[in] lpsSyncState
  185. * The SBinary structure containing the data to be decoded.
  186. */
  187. HRESULT HrLoadSyncStatus(SBinary *lpsSyncState);
  188. /**
  189. * Save the sync status streams.
  190. *
  191. * @param[in] lppSyncStatusProp
  192. * Pointer to a SPropValue pointer that will be populated with
  193. * the binary data that's made out of the status streams.
  194. */
  195. HRESULT HrSaveSyncStatus(LPSPropValue *lppSyncStatusProp);
  196. /**
  197. * Get the sync status stream for a particular folder.
  198. *
  199. * @param[in] lpFolder
  200. * The folder for which to get the sync status stream.
  201. * @param[out] lppStream
  202. * Pointer to a IStream pointer that will contain the
  203. * sync status stream on successful completion.
  204. */
  205. HRESULT HrGetSyncStatusStream(LPMAPIFOLDER lpFolder, LPSTREAM *lppStream);
  206. /**
  207. * Get the sync status stream for a particular folder.
  208. *
  209. * @param[in] lpSourceKey
  210. * An SBinary structure that will be interprested as a
  211. * sourcekey that specifies a folder.
  212. * @param[out] lppStream
  213. * Pointer to a IStream pointer that will contain the
  214. * sync status stream on successful completion.
  215. */
  216. HRESULT HrGetSyncStatusStream(SBinary *lpsSourceKey, LPSTREAM *lppStream);
  217. /**
  218. * Get the resync id from the store.
  219. * This id is incremented with kopano-admin on the online store if a folder
  220. * resync is required. If the online and offline id differ, a resync will be
  221. * initiated. Afterwards the offline id is copied from the online id.
  222. *
  223. * @param[out] lpulResyncID The requested id.
  224. */
  225. HRESULT GetResyncID(ULONG *lpulResyncID);
  226. /**
  227. * Set the resync id on the store.
  228. * @see GetResyncID
  229. *
  230. * @param[in] ulResyncID The id to set.
  231. */
  232. HRESULT SetResyncID(ULONG ulResyncID);
  233. /**
  234. * Get stored server UID.
  235. * Get the stored onlinse server UID. This is compared to the current online
  236. * server UID in order to determine if the online store was relocated. In that
  237. * case a resync must be performed in order for ICS to function properly.
  238. * This server UID is stored during the first folder sync step or whenever it's
  239. * absent (for older profiles).
  240. * Only applicable on offline stores.
  241. *
  242. * @param[out] lpServerUid The requested server UID.
  243. */
  244. HRESULT GetStoredServerUid(LPGUID lpServerUid);
  245. /**
  246. * Set stored server UID.
  247. * @see GetStoredServerUid
  248. *
  249. * @param[in] lpServerUid The server uid to set.
  250. */
  251. HRESULT SetStoredServerUid(LPGUID lpServerUid);
  252. /**
  253. * Get the server UID.
  254. * This is used to compare with the stores server UID.
  255. * @see GetStoredServerUid
  256. *
  257. * @param[out] lpServerUid The requested server UID.
  258. */
  259. HRESULT GetServerUid(LPGUID lpServerUid);
  260. private: // methods
  261. /**
  262. * Get the sync state for a sourcekey
  263. *
  264. * @param[in] lpSourceKey
  265. * The sourcekey for which to get the sync state.
  266. * @param[out] lpsSyncState
  267. * Pointer to a SSyncState structure that will be populated
  268. * with the retrieved sync state.
  269. */
  270. HRESULT HrGetSyncStateFromSourceKey(SBinary *lpSourceKey, SSyncState *lpsSyncState);
  271. /**
  272. * Handle change events (through the ChangeAdviseSink).
  273. *
  274. * @param[in] ulFlags
  275. * Unused
  276. * @param[in] lpEntryList
  277. * List of sync states that have changes pending.
  278. * @return 0
  279. */
  280. ULONG OnChange(ULONG ulFlags, LPENTRYLIST lpEntryList);
  281. /**
  282. * Release the change advisor and clear the map with received states.
  283. */
  284. HRESULT HrReleaseChangeAdvisor();
  285. LPMDB m_lpStore;
  286. ECLogger *m_lpLogger;
  287. ECSyncSettings *m_lpSettings;
  288. IECChangeAdvisor *m_lpChangeAdvisor = nullptr;
  289. IECChangeAdviseSink *m_lpChangeAdviseSink = nullptr;
  290. StatusStreamMap m_mapSyncStatus;
  291. SyncStateMap m_mapStates;
  292. NotifiedSyncIdMap m_mapNotifiedSyncIds;
  293. std::mutex m_hMutex;
  294. };
  295. } /* namespace */
  296. #endif // ndef ECSYNCCONTEXT_H