fsck-task.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  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 <iostream>
  19. #include <kopano/CommonUtil.h>
  20. #include <kopano/mapiext.h>
  21. #include <kopano/mapiguidext.h>
  22. #include <kopano/memory.hpp>
  23. #include <mapiutil.h>
  24. #include <mapix.h>
  25. #include <kopano/namedprops.h>
  26. #include "fsck.h"
  27. using namespace KCHL;
  28. HRESULT FsckTask::ValidateMinimalNamedFields(LPMESSAGE lpMessage)
  29. {
  30. HRESULT hr = hrSuccess;
  31. memory_ptr<SPropValue> lpPropertyArray;
  32. memory_ptr<SPropTagArray> lpPropertyTagArray;
  33. enum {
  34. E_REMINDER,
  35. TAG_COUNT
  36. };
  37. memory_ptr<MAPINAMEID *> lppTagArray;
  38. std::string strTagName[TAG_COUNT];
  39. /*
  40. * Allocate the NamedID list and initialize it to all
  41. * properties which could give us some information about the name.
  42. */
  43. hr = allocNamedIdList(TAG_COUNT, &~lppTagArray);
  44. if (hr != hrSuccess)
  45. return hr;
  46. lppTagArray[E_REMINDER]->lpguid = (LPGUID)&PSETID_Common;
  47. lppTagArray[E_REMINDER]->ulKind = MNID_ID;
  48. lppTagArray[E_REMINDER]->Kind.lID = dispidReminderSet;
  49. strTagName[E_REMINDER] = "dispidReminderSet";
  50. hr = ReadNamedProperties(lpMessage, TAG_COUNT, lppTagArray,
  51. &~lpPropertyTagArray, &~lpPropertyArray);
  52. if (FAILED(hr))
  53. return hr;
  54. for (ULONG i = 0; i < TAG_COUNT; ++i) {
  55. if (PROP_TYPE(lpPropertyArray[i].ulPropTag) == PT_ERROR) {
  56. __UPV Value;
  57. Value.b = false;
  58. hr = AddMissingProperty(lpMessage, strTagName[i],
  59. CHANGE_PROP_TYPE(lpPropertyTagArray->aulPropTag[i], PT_BOOLEAN),
  60. Value);
  61. if (hr != hrSuccess)
  62. return hr;
  63. }
  64. }
  65. return hrSuccess;
  66. }
  67. HRESULT FsckTask::ValidateTimestamps(LPMESSAGE lpMessage)
  68. {
  69. HRESULT hr = hrSuccess;
  70. memory_ptr<SPropValue> lpPropertyArray;
  71. memory_ptr<SPropTagArray> lpPropertyTagArray;
  72. memory_ptr<MAPINAMEID *> lppTagArray;
  73. enum {
  74. E_START_DATE,
  75. E_DUE_DATE,
  76. TAG_COUNT
  77. };
  78. /*
  79. * Allocate the NameID list and initialize it to all
  80. * properties which could give us some information about the timestamps.
  81. */
  82. hr = allocNamedIdList(TAG_COUNT, &~lppTagArray);
  83. if (hr != hrSuccess)
  84. return hr;
  85. lppTagArray[E_START_DATE]->lpguid = (LPGUID)&PSETID_Task;
  86. lppTagArray[E_START_DATE]->ulKind = MNID_ID;
  87. lppTagArray[E_START_DATE]->Kind.lID = dispidTaskStartDate;
  88. lppTagArray[E_DUE_DATE]->lpguid = (LPGUID)&PSETID_Task;
  89. lppTagArray[E_DUE_DATE]->ulKind = MNID_ID;
  90. lppTagArray[E_DUE_DATE]->Kind.lID = dispidTaskDueDate;
  91. hr = ReadNamedProperties(lpMessage, TAG_COUNT, lppTagArray,
  92. &~lpPropertyTagArray, &~lpPropertyArray);
  93. if (FAILED(hr))
  94. return hr;
  95. /*
  96. * Validate parameters
  97. * When Completion is set, the completion date should have been set.
  98. * No further restrictions apply, but we will fill in missing tags
  99. * based on the results of the other tags.
  100. */
  101. if (PROP_TYPE(lpPropertyArray[E_START_DATE].ulPropTag) != PT_ERROR &&
  102. PROP_TYPE(lpPropertyArray[E_DUE_DATE].ulPropTag) != PT_ERROR) {
  103. const FILETIME *lpStart = &lpPropertyArray[E_START_DATE].Value.ft;
  104. const FILETIME *lpDue = &lpPropertyArray[E_DUE_DATE].Value.ft;
  105. /*
  106. * We cannot start a task _after_ it is due.
  107. */
  108. if (*lpStart > *lpDue) {
  109. __UPV Value;
  110. Value.ft = *lpDue;
  111. hr = ReplaceProperty(lpMessage, "dispidTaskStartDate",
  112. CHANGE_PROP_TYPE(lpPropertyTagArray->aulPropTag[E_START_DATE], PT_SYSTIME),
  113. "Start date cannot be after due date",
  114. Value);
  115. if (hr != hrSuccess)
  116. return hr;
  117. }
  118. } else
  119. hr = hrSuccess;
  120. return hr;
  121. }
  122. HRESULT FsckTask::ValidateCompletion(LPMESSAGE lpMessage)
  123. {
  124. HRESULT hr = hrSuccess;
  125. memory_ptr<SPropValue> lpPropertyArray;
  126. memory_ptr<SPropTagArray> lpPropertyTagArray;
  127. memory_ptr<MAPINAMEID *> lppTagArray;
  128. bool bCompleted;
  129. enum {
  130. E_COMPLETE,
  131. E_PERCENT_COMPLETE,
  132. E_COMPLETION_DATE,
  133. TAG_COUNT
  134. };
  135. /*
  136. * Allocate the NamedID list and initialize it to all
  137. * properties which could give us some information about the completion.
  138. */
  139. hr = allocNamedIdList(TAG_COUNT, &~lppTagArray);
  140. if (hr != hrSuccess)
  141. return hr;
  142. lppTagArray[E_COMPLETE]->lpguid = (LPGUID)&PSETID_Task;
  143. lppTagArray[E_COMPLETE]->ulKind = MNID_ID;
  144. lppTagArray[E_COMPLETE]->Kind.lID = dispidTaskComplete;
  145. lppTagArray[E_PERCENT_COMPLETE]->lpguid = (LPGUID)&PSETID_Task;
  146. lppTagArray[E_PERCENT_COMPLETE]->ulKind = MNID_ID;
  147. lppTagArray[E_PERCENT_COMPLETE]->Kind.lID = dispidTaskPercentComplete;
  148. lppTagArray[E_COMPLETION_DATE]->lpguid = (LPGUID)&PSETID_Task;
  149. lppTagArray[E_COMPLETION_DATE]->ulKind = MNID_ID;
  150. lppTagArray[E_COMPLETION_DATE]->Kind.lID = dispidTaskDateCompleted;
  151. hr = ReadNamedProperties(lpMessage, TAG_COUNT, lppTagArray,
  152. &~lpPropertyTagArray, &~lpPropertyArray);
  153. if (FAILED(hr))
  154. return hr;
  155. /*
  156. * Validate parameters
  157. * When Completion is set, the completion date should have been set.
  158. * No further restrictions apply, but we will fill in missing tags
  159. * based on the results of the other tags.
  160. */
  161. if (PROP_TYPE(lpPropertyArray[E_COMPLETE].ulPropTag) == PT_ERROR) {
  162. __UPV Value;
  163. if (((PROP_TYPE(lpPropertyArray[E_PERCENT_COMPLETE].ulPropTag) != PT_ERROR) &&
  164. (lpPropertyArray[E_PERCENT_COMPLETE].Value.dbl == 1)) ||
  165. (PROP_TYPE((lpPropertyArray[E_COMPLETION_DATE].ulPropTag) != PT_ERROR)))
  166. Value.b = true;
  167. else
  168. Value.b = false;
  169. hr = AddMissingProperty(lpMessage, "dispidTaskComplete",
  170. CHANGE_PROP_TYPE(lpPropertyTagArray->aulPropTag[E_COMPLETE], PT_BOOLEAN),
  171. Value);
  172. if (hr != hrSuccess)
  173. return hr;
  174. bCompleted = Value.b;
  175. } else
  176. bCompleted = lpPropertyArray[E_COMPLETE].Value.b;
  177. if (PROP_TYPE(lpPropertyArray[E_PERCENT_COMPLETE].ulPropTag) == PT_ERROR) {
  178. __UPV Value;
  179. Value.dbl = !!bCompleted; /* Value.dbl = 1 => 100% */
  180. hr = AddMissingProperty(lpMessage, "dispidTaskPercentComplete",
  181. CHANGE_PROP_TYPE(lpPropertyTagArray->aulPropTag[E_PERCENT_COMPLETE], PT_DOUBLE),
  182. Value);
  183. if (hr != hrSuccess)
  184. return hr;
  185. }
  186. if (PROP_TYPE(lpPropertyArray[E_COMPLETION_DATE].ulPropTag) == PT_ERROR && bCompleted) {
  187. __UPV Value;
  188. GetSystemTimeAsFileTime(&Value.ft);
  189. hr = AddMissingProperty(lpMessage, "dispidTaskDateCompleted",
  190. CHANGE_PROP_TYPE(lpPropertyTagArray->aulPropTag[E_COMPLETION_DATE], PT_SYSTIME),
  191. Value);
  192. if (hr != hrSuccess)
  193. return hr;
  194. }
  195. return hrSuccess;
  196. }
  197. HRESULT FsckTask::ValidateItem(LPMESSAGE lpMessage,
  198. const std::string &strClass)
  199. {
  200. HRESULT hr;
  201. if (strClass != "IPM.Task") {
  202. std::cout << "Illegal class: \"" << strClass << "\"" << std::endl;
  203. return E_INVALIDARG;
  204. }
  205. hr = ValidateMinimalNamedFields(lpMessage);
  206. if (hr != hrSuccess)
  207. return hr;
  208. hr = ValidateTimestamps(lpMessage);
  209. if (hr != hrSuccess)
  210. return hr;
  211. hr = ValidateCompletion(lpMessage);
  212. if (hr != hrSuccess)
  213. return hr;
  214. return hrSuccess;
  215. }