icaluid.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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 "icaluid.h"
  19. #include <mapix.h>
  20. #include <kopano/stringutil.h>
  21. namespace KC {
  22. /**
  23. * Check if UID is of outlook format.
  24. *
  25. * The UID will start with a static GUID defined by Microsoft.
  26. *
  27. * @param[in] strUid input string UID to be checked
  28. * @return true: outlook format, false: assume ical format
  29. */
  30. bool IsOutlookUid(const std::string &strUid)
  31. {
  32. std::string strByteArrayID = "040000008200E00074C5B7101A82E008";
  33. return (strUid.compare(0, strByteArrayID.length(), strByteArrayID) == 0);
  34. }
  35. /**
  36. * Generates a new UID in outlook format. Format is described in VConverter::HrMakeBinaryUID
  37. *
  38. * @param[out] lpStrData returned generated UID string
  39. * @return MAPI error code
  40. */
  41. HRESULT HrGenerateUid(std::string *lpStrData)
  42. {
  43. std::string strByteArrayID = "040000008200E00074C5B7101A82E008";
  44. std::string strBinUid;
  45. GUID sGuid;
  46. FILETIME ftNow;
  47. ULONG ulSize = 1;
  48. HRESULT hr = CoCreateGuid(&sGuid);
  49. if (hr != hrSuccess)
  50. return hr;
  51. hr = UnixTimeToFileTime(time(NULL), &ftNow);
  52. if (hr != hrSuccess)
  53. return hr;
  54. strBinUid = strByteArrayID; // Outlook Guid
  55. strBinUid += "00000000"; // InstanceDate
  56. strBinUid += bin2hex(sizeof(FILETIME), (LPBYTE)&ftNow);
  57. strBinUid += "0000000000000000"; // Padding
  58. strBinUid += bin2hex(sizeof(ULONG), (LPBYTE)&ulSize); // always 1
  59. strBinUid += bin2hex(sizeof(GUID), (LPBYTE)&sGuid); // new guid
  60. lpStrData->swap(strBinUid);
  61. return hrSuccess;
  62. }
  63. /**
  64. * Generates new UID and sets it in SpropValue structure
  65. *
  66. * @param[in] ulNamedTag Property tag to set in returned property
  67. * @param[in] base base for allocating memory, can be NULL and returned *lppPropVal must be freed using MAPIFreeBuffer
  68. * @param[out] lppPropVal returned SpropValue structure
  69. * @return MAPI error code
  70. */
  71. HRESULT HrCreateGlobalID(ULONG ulNamedTag, void *base, LPSPropValue *lppPropVal)
  72. {
  73. HRESULT hr = hrSuccess;
  74. LPSPropValue lpPropVal = NULL;
  75. std::string strUid, strBinUid;
  76. if (base) {
  77. hr = MAPIAllocateMore(sizeof(SPropValue), base, (void**)&lpPropVal);
  78. } else {
  79. hr = MAPIAllocateBuffer(sizeof(SPropValue), (void**)&lpPropVal);
  80. base = lpPropVal;
  81. }
  82. if (hr != hrSuccess)
  83. goto exit;
  84. lpPropVal->ulPropTag = ulNamedTag;
  85. hr = HrGenerateUid(&strUid);
  86. if (hr != hrSuccess)
  87. goto exit;
  88. strBinUid = hex2bin(strUid);
  89. lpPropVal->Value.bin.cb = strBinUid.length();
  90. hr = MAPIAllocateMore(lpPropVal->Value.bin.cb, base, (void**)&lpPropVal->Value.bin.lpb);
  91. if (hr != hrSuccess)
  92. goto exit;
  93. memcpy(lpPropVal->Value.bin.lpb, strBinUid.data(), lpPropVal->Value.bin.cb);
  94. *lppPropVal = lpPropVal;
  95. exit:
  96. if (hr != hrSuccess && base == nullptr)
  97. MAPIFreeBuffer(lpPropVal);
  98. return hr;
  99. }
  100. /**
  101. * Extracts ical UID from the binary outlook UID
  102. *
  103. * If the UID is an outlook wrapped ical UID, the ical part is
  104. * returned, otherwise a hex string representation of the UID is
  105. * returned.
  106. *
  107. * @param[in] sBin binary outlook UID
  108. * @param[out] lpStrUid returned ical string UID
  109. * @return MAPI error code
  110. */
  111. HRESULT HrGetICalUidFromBinUid(const SBinary &sBin, std::string *lpStrUid)
  112. {
  113. HRESULT hr = hrSuccess;
  114. std::string strUid;
  115. if (sBin.cb > 0x34 && memcmp(sBin.lpb + 0x28, "vCal-Uid", 8) == 0)
  116. strUid = (char*)sBin.lpb + 0x34;
  117. else
  118. strUid = bin2hex(sBin.cb, sBin.lpb);
  119. lpStrUid->swap(strUid);
  120. return hr;
  121. }
  122. /**
  123. * Converts ical UID to Outlook compatible UIDs.
  124. *
  125. * Add a special Outlook GUID and marker to the Ical UID. This format
  126. * is used in Outlook for non-outlook UIDs send by other ICal clients.
  127. *
  128. * @param[in] strUid ical UID
  129. * @param[out] lpStrBinUid returned outlook compatible string UID
  130. * @return HRESULT
  131. */
  132. HRESULT HrMakeBinUidFromICalUid(const std::string &strUid, std::string *lpStrBinUid)
  133. {
  134. HRESULT hr = hrSuccess;
  135. std::string strBinUid;
  136. int len = 13 + strUid.length();
  137. strBinUid.insert(0, "\x04\x00\x00\x00\x82\x00\xE0\x00\x74\xC5\xB7\x10\x1A\x82\xE0\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 0x24);
  138. strBinUid.append((char*) &len, 4);
  139. strBinUid.append("vCal-Uid", 8);
  140. len = 1; // this is always 1
  141. strBinUid.append((char*)&len, 4);
  142. strBinUid.append(strUid);
  143. strBinUid.append("\x00", 1);
  144. lpStrBinUid->swap(strBinUid);
  145. return hr;
  146. }
  147. } /* namespace */