cmdutil.hpp 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  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 KC_CMDUTIL_HPP
  18. #define KC_CMDUTIL_HPP 1
  19. #include <kopano/zcdefs.h>
  20. #include <stdexcept>
  21. #include "ECICS.h"
  22. #include "SOAPUtils.h"
  23. #include <map>
  24. #include <set>
  25. #include <list>
  26. #include <string>
  27. namespace KC {
  28. // Above EC_TABLE_CHANGE_THRESHOLD, a TABLE_CHANGE notification is sent instead of individual notifications
  29. #define EC_TABLE_CHANGE_THRESHOLD 10
  30. class EntryId _kc_final {
  31. public:
  32. EntryId() {
  33. updateStruct();
  34. }
  35. EntryId(const EntryId &s) {
  36. m_data = s.m_data;
  37. updateStruct();
  38. }
  39. EntryId(EntryId &&o) :
  40. m_data(std::move(o.m_data))
  41. {
  42. updateStruct();
  43. }
  44. EntryId(const entryId *entryid) {
  45. if(entryid)
  46. m_data = std::string((char *)entryid->__ptr, entryid->__size);
  47. else
  48. m_data.clear();
  49. updateStruct();
  50. }
  51. EntryId(const entryId& entryid) {
  52. m_data = std::string((char *)entryid.__ptr, entryid.__size);
  53. updateStruct();
  54. }
  55. EntryId(const std::string& data) {
  56. m_data = data;
  57. updateStruct();
  58. }
  59. ~EntryId() {
  60. }
  61. EntryId& operator= (const EntryId &s) {
  62. m_data = s.m_data;
  63. updateStruct();
  64. return *this;
  65. }
  66. /* EID_V0 is marked packed, so direct-access w/o memcpy is ok */
  67. unsigned int type() const {
  68. auto d = reinterpret_cast<EID_V0 *>(const_cast<char *>(m_data.data()));
  69. if (m_data.size() >= offsetof(EID_V0, usType) + sizeof(d->usType))
  70. return d->usType;
  71. ec_log_err("K-1570: %s: entryid has size %zu; not enough for EID_V0.usType (%zu)",
  72. __func__, m_data.size(), offsetof(EID_V0, usType) + sizeof(d->usType));
  73. throw runtime_error("K-1570: entryid is not of type EID_V0");
  74. }
  75. void setFlags(unsigned int ulFlags) {
  76. auto d = reinterpret_cast<EID_V0 *>(const_cast<char *>(m_data.data()));
  77. if (m_data.size() < offsetof(EID_V0, usFlags) + sizeof(d->usFlags)) {
  78. ec_log_err("K-1571: %s: entryid has size %zu; not enough for EID_V0.usFlags (%zu)",
  79. __func__, m_data.size(), offsetof(EID_V0, usFlags) + sizeof(d->usFlags));
  80. throw runtime_error("K-1571: entryid is not of type EID_V0");
  81. }
  82. d->usFlags = ulFlags;
  83. }
  84. bool operator == (const EntryId &s) const {
  85. return m_data == s.m_data;
  86. }
  87. bool operator < (const EntryId &s) const {
  88. return m_data < s.m_data;
  89. }
  90. operator const std::string& () const { return m_data; }
  91. operator unsigned char *() const { return (unsigned char *)m_data.data(); }
  92. operator entryId *() { return &m_sEntryId; }
  93. unsigned int size() const { return m_data.size(); }
  94. bool empty() const { return m_data.empty(); }
  95. private:
  96. void updateStruct() {
  97. m_sEntryId.__size = m_data.size();
  98. m_sEntryId.__ptr = (unsigned char *)m_data.data();
  99. }
  100. entryId m_sEntryId;
  101. std::string m_data;
  102. };
  103. // this belongs to the DeleteObjects function
  104. struct DELETEITEM {
  105. unsigned int ulId;
  106. unsigned int ulParent;
  107. bool fRoot;
  108. bool fInOGQueue;
  109. short ulObjType;
  110. short ulParentType;
  111. unsigned int ulFlags;
  112. unsigned int ulStoreId;
  113. unsigned int ulObjSize;
  114. unsigned int ulMessageFlags;
  115. SOURCEKEY sSourceKey;
  116. SOURCEKEY sParentSourceKey;
  117. entryId sEntryId; //fixme: auto destroy entryid
  118. };
  119. // Used to group notify flags and object type.
  120. struct TABLECHANGENOTIFICATION {
  121. TABLECHANGENOTIFICATION(unsigned int t, unsigned int f): ulFlags(f), ulType(t) {}
  122. bool operator<(const TABLECHANGENOTIFICATION &rhs) const { return ulFlags < rhs.ulFlags || (ulFlags == rhs.ulFlags && ulType < rhs.ulType); }
  123. unsigned int ulFlags;
  124. unsigned int ulType;
  125. };
  126. class PARENTINFO _kc_final {
  127. public:
  128. int lItems = 0, lFolders = 0, lAssoc = 0;
  129. int lDeleted = 0, lDeletedFolders = 0, lDeletedAssoc = 0;
  130. int lUnread = 0;
  131. unsigned int ulStoreId = 0;
  132. };
  133. #define EC_DELETE_FOLDERS 0x00000001
  134. #define EC_DELETE_MESSAGES 0x00000002
  135. #define EC_DELETE_RECIPIENTS 0x00000004
  136. #define EC_DELETE_ATTACHMENTS 0x00000008
  137. #define EC_DELETE_CONTAINER 0x00000010
  138. #define EC_DELETE_HARD_DELETE 0x00000020
  139. #define EC_DELETE_STORE 0x00000040
  140. #define EC_DELETE_NOT_ASSOCIATED_MSG 0x00000080
  141. typedef std::list<DELETEITEM> ECListDeleteItems;
  142. typedef std::set<TABLECHANGENOTIFICATION> ECSetTableChangeNotifications;
  143. typedef std::map<unsigned int, ECSetTableChangeNotifications> ECMapTableChangeNotifications;
  144. void FreeDeleteItem(DELETEITEM *src);
  145. void FreeDeletedItems(ECListDeleteItems *lplstDeleteItems);
  146. class ECAttachmentStorage;
  147. ECRESULT GetSourceKey(unsigned int ulObjId, SOURCEKEY *lpSourceKey);
  148. ECRESULT ValidateDeleteObject(ECSession *lpSession, bool bCheckPermission, unsigned int ulFlags, const DELETEITEM &sItem);
  149. ECRESULT ExpandDeletedItems(ECSession *lpSession, ECDatabase *lpDatabase, ECListInt *lpsObjectList, unsigned int ulFlags, bool bCheckPermission, ECListDeleteItems *lplstDeleteItems);
  150. ECRESULT DeleteObjectUpdateICS(ECSession *lpSession, unsigned int ulFlags, ECListDeleteItems &lstDeleted, unsigned int ulSyncId);
  151. ECRESULT DeleteObjectSoft(ECSession *lpSession, ECDatabase *lpDatabase, unsigned int ulFlags, ECListDeleteItems &lstDeleteItems, ECListDeleteItems &lstDeleted);
  152. ECRESULT DeleteObjectHard(ECSession *lpSession, ECDatabase *lpDatabase, ECAttachmentStorage *lpAttachmentStorage, unsigned int ulFlags, ECListDeleteItems &lstDeleteItems, bool bNoTransaction, ECListDeleteItems &lstDeleted);
  153. ECRESULT DeleteObjectStoreSize(ECSession *lpSession, ECDatabase *lpDatabase, unsigned int ulFlags, ECListDeleteItems &lstDeleted);
  154. ECRESULT DeleteObjectCacheUpdate(ECSession *lpSession, unsigned int ulFlags, ECListDeleteItems &lstDeleted);
  155. ECRESULT DeleteObjectNotifications(ECSession *lpSession, unsigned int ulFlags, ECListDeleteItems &lstDeleted);
  156. ECRESULT DeleteObjects(ECSession *lpSession, ECDatabase *lpDatabase, ECListInt *lpsObjectList, unsigned int ulFlags, unsigned int ulSyncId, bool bNoTransaction, bool bCheckPermission);
  157. ECRESULT DeleteObjects(ECSession *lpSession, ECDatabase *lpDatabase, unsigned int ulObjectId, unsigned int ulFlags, unsigned int ulSyncId, bool bNoTransaction, bool bCheckPermission);
  158. ECRESULT MarkStoreAsDeleted(ECSession *lpSession, ECDatabase *lpDatabase, unsigned int ulStoreHierarchyId, unsigned int ulSyncId);
  159. ECRESULT WriteLocalCommitTimeMax(struct soap *soap, ECDatabase *lpDatabase, unsigned int ulFolderId, propVal **ppvTime);
  160. ECRESULT UpdateTProp(ECDatabase *lpDatabase, unsigned int ulPropTag, unsigned int ulFolderId, ECListInt *lpObjectIDs);
  161. ECRESULT UpdateTProp(ECDatabase *lpDatabase, unsigned int ulPropTag, unsigned int ulFolderId, unsigned int ulObjId);
  162. ECRESULT UpdateFolderCount(ECDatabase *lpDatabase, unsigned int ulFolderId, unsigned int ulPropTag, int lDelta);
  163. ECRESULT CheckQuota(ECSession *lpecSession, ULONG ulStoreId);
  164. ECRESULT MapEntryIdToObjectId(ECSession *lpecSession, ECDatabase *lpDatabase, ULONG ulObjId, const entryId &sEntryId);
  165. ECRESULT UpdateFolderCounts(ECDatabase *lpDatabase, ULONG ulParentId, ULONG ulFlags, propValArray *lpModProps);
  166. ECRESULT ProcessSubmitFlag(ECDatabase *lpDatabase, ULONG ulSyncId, ULONG ulStoreId, ULONG ulObjId, bool bNewItem, propValArray *lpModProps);
  167. ECRESULT CreateNotifications(ULONG ulObjId, ULONG ulObjType, ULONG ulParentId, ULONG ulGrandParentId, bool bNewItem, propValArray *lpModProps, struct propVal *lpvCommitTime);
  168. ECRESULT WriteSingleProp(ECDatabase *lpDatabase, unsigned int ulObjId, unsigned int ulFolderId, struct propVal *lpPropVal, bool bColumnProp, unsigned int ulMaxQuerySize, std::string &strInsertQuery);
  169. ECRESULT WriteProp(ECDatabase *lpDatabase, unsigned int ulObjId, unsigned int ulParentId, struct propVal *lpPropVal);
  170. ECRESULT GetNamesFromIDs(struct soap *soap, ECDatabase *lpDatabase, struct propTagArray *lpPropTags, struct namedPropArray *lpsNames);
  171. ECRESULT ResetFolderCount(ECSession *lpSession, unsigned int ulObjId, unsigned int *lpulUpdates = NULL);
  172. ECRESULT RemoveStaleIndexedProp(ECDatabase *lpDatabase, unsigned int ulPropTag, unsigned char *lpData, unsigned int cbSize);
  173. ECRESULT ApplyFolderCounts(ECDatabase *lpDatabase, unsigned int ulFolderId, const PARENTINFO &pi);
  174. ECRESULT ApplyFolderCounts(ECDatabase *lpDatabase, const std::map<unsigned int, PARENTINFO> &mapFolderCounts);
  175. #define LOCK_SHARED 0x00000001
  176. #define LOCK_EXCLUSIVE 0x00000002
  177. // Lock folders and start transaction:
  178. ECRESULT BeginLockFolders(ECDatabase *lpDatabase, const std::set<SOURCEKEY>& setObjects, unsigned int ulFlags); // may be mixed list of folders and messages
  179. ECRESULT BeginLockFolders(ECDatabase *lpDatabase, const std::set<EntryId>& setObjects, unsigned int ulFlags); // may be mixed list of folders and messages
  180. ECRESULT BeginLockFolders(ECDatabase *lpDatabase, const EntryId &entryid, unsigned int ulFlags); // single entryid, folder or message
  181. ECRESULT BeginLockFolders(ECDatabase *lpDatabase, const SOURCEKEY &sourcekey, unsigned int ulFlags); // single sourcekey, folder or message
  182. struct NAMEDPROPDEF {
  183. GUID guid;
  184. unsigned int ulKind;
  185. unsigned int ulId;
  186. std::string strName;
  187. };
  188. typedef std::map<unsigned int, NAMEDPROPDEF> NamedPropDefMap;
  189. struct CHILDPROPS {
  190. DynamicPropValArray *lpPropVals;
  191. DynamicPropTagArray *lpPropTags;
  192. };
  193. typedef std::map<unsigned int, CHILDPROPS> ChildPropsMap;
  194. ECRESULT PrepareReadProps(struct soap *soap, ECDatabase *lpDatabase, bool fDoQuery, bool fUnicode, unsigned int ulObjId, unsigned int ulParentId, unsigned int ulMaxSize, ChildPropsMap *lpChildProps, NamedPropDefMap *lpNamedProps);
  195. ECRESULT FreeChildProps(std::map<unsigned int, CHILDPROPS> *lpChildProps);
  196. } /* namespace */
  197. #endif /* KC_CMDUTIL_HPP */