deleter.cpp 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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 "ECArchiverLogger.h"
  19. #include "deleter.h"
  20. using namespace std;
  21. namespace KC { namespace operations {
  22. /**
  23. * @param[in] lpLogger
  24. * Pointer to the logger.
  25. */
  26. Deleter::Deleter(ECArchiverLogger *lpLogger, int ulAge, bool bProcessUnread)
  27. : ArchiveOperationBaseEx(lpLogger, ulAge, bProcessUnread, ARCH_NEVER_DELETE)
  28. { }
  29. Deleter::~Deleter()
  30. {
  31. PurgeQueuedMessages();
  32. }
  33. HRESULT Deleter::LeaveFolder()
  34. {
  35. // Folder is still available, purge now!
  36. return PurgeQueuedMessages();
  37. }
  38. HRESULT Deleter::DoProcessEntry(ULONG cProps, const LPSPropValue &lpProps)
  39. {
  40. auto lpEntryId = PCpropFindProp(lpProps, cProps, PR_ENTRYID);
  41. if (lpEntryId == NULL) {
  42. Logger()->Log(EC_LOGLEVEL_FATAL, "PR_ENTRYID missing");
  43. return MAPI_E_NOT_FOUND;
  44. }
  45. if (m_lstEntryIds.size() >= 50) {
  46. HRESULT hr = PurgeQueuedMessages();
  47. if (hr != hrSuccess)
  48. return hr;
  49. }
  50. m_lstEntryIds.push_back(lpEntryId->Value.bin);
  51. return hrSuccess;
  52. }
  53. /**
  54. * Delete the messages that are queued for deletion.
  55. */
  56. HRESULT Deleter::PurgeQueuedMessages()
  57. {
  58. HRESULT hr;
  59. EntryListPtr ptrEntryList;
  60. ULONG ulIdx = 0;
  61. if (m_lstEntryIds.empty())
  62. return hrSuccess;
  63. hr = MAPIAllocateBuffer(sizeof(ENTRYLIST), &~ptrEntryList);
  64. if (hr != hrSuccess)
  65. return hr;
  66. hr = MAPIAllocateMore(m_lstEntryIds.size() * sizeof(SBinary), ptrEntryList, (LPVOID*)&ptrEntryList->lpbin);
  67. if (hr != hrSuccess)
  68. return hr;
  69. ptrEntryList->cValues = m_lstEntryIds.size();
  70. for (const auto &e : m_lstEntryIds) {
  71. ptrEntryList->lpbin[ulIdx].cb = e.size();
  72. ptrEntryList->lpbin[ulIdx++].lpb = e;
  73. }
  74. hr = CurrentFolder()->DeleteMessages(ptrEntryList, 0, NULL, 0);
  75. if (hr != hrSuccess) {
  76. Logger()->Log(EC_LOGLEVEL_FATAL, "Failed to delete %u messages. (hr=%s)", ptrEntryList->cValues, stringify(hr, true).c_str());
  77. return hr;
  78. }
  79. m_lstEntryIds.clear();
  80. return hrSuccess;
  81. }
  82. }} /* namespace */