123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- /*
- * Copyright 2005 - 2016 Zarafa and its licensors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- #include <kopano/platform.h>
- #include "icaluid.h"
- #include <mapix.h>
- #include <kopano/stringutil.h>
- namespace KC {
- /**
- * Check if UID is of outlook format.
- *
- * The UID will start with a static GUID defined by Microsoft.
- *
- * @param[in] strUid input string UID to be checked
- * @return true: outlook format, false: assume ical format
- */
- bool IsOutlookUid(const std::string &strUid)
- {
- std::string strByteArrayID = "040000008200E00074C5B7101A82E008";
- return (strUid.compare(0, strByteArrayID.length(), strByteArrayID) == 0);
- }
- /**
- * Generates a new UID in outlook format. Format is described in VConverter::HrMakeBinaryUID
- *
- * @param[out] lpStrData returned generated UID string
- * @return MAPI error code
- */
- HRESULT HrGenerateUid(std::string *lpStrData)
- {
- std::string strByteArrayID = "040000008200E00074C5B7101A82E008";
- std::string strBinUid;
- GUID sGuid;
- FILETIME ftNow;
- ULONG ulSize = 1;
- HRESULT hr = CoCreateGuid(&sGuid);
- if (hr != hrSuccess)
- return hr;
- hr = UnixTimeToFileTime(time(NULL), &ftNow);
- if (hr != hrSuccess)
- return hr;
- strBinUid = strByteArrayID; // Outlook Guid
- strBinUid += "00000000"; // InstanceDate
- strBinUid += bin2hex(sizeof(FILETIME), (LPBYTE)&ftNow);
- strBinUid += "0000000000000000"; // Padding
- strBinUid += bin2hex(sizeof(ULONG), (LPBYTE)&ulSize); // always 1
- strBinUid += bin2hex(sizeof(GUID), (LPBYTE)&sGuid); // new guid
- lpStrData->swap(strBinUid);
- return hrSuccess;
- }
- /**
- * Generates new UID and sets it in SpropValue structure
- *
- * @param[in] ulNamedTag Property tag to set in returned property
- * @param[in] base base for allocating memory, can be NULL and returned *lppPropVal must be freed using MAPIFreeBuffer
- * @param[out] lppPropVal returned SpropValue structure
- * @return MAPI error code
- */
- HRESULT HrCreateGlobalID(ULONG ulNamedTag, void *base, LPSPropValue *lppPropVal)
- {
- HRESULT hr = hrSuccess;
- LPSPropValue lpPropVal = NULL;
- std::string strUid, strBinUid;
- if (base) {
- hr = MAPIAllocateMore(sizeof(SPropValue), base, (void**)&lpPropVal);
- } else {
- hr = MAPIAllocateBuffer(sizeof(SPropValue), (void**)&lpPropVal);
- base = lpPropVal;
- }
- if (hr != hrSuccess)
- goto exit;
- lpPropVal->ulPropTag = ulNamedTag;
- hr = HrGenerateUid(&strUid);
- if (hr != hrSuccess)
- goto exit;
- strBinUid = hex2bin(strUid);
- lpPropVal->Value.bin.cb = strBinUid.length();
- hr = MAPIAllocateMore(lpPropVal->Value.bin.cb, base, (void**)&lpPropVal->Value.bin.lpb);
- if (hr != hrSuccess)
- goto exit;
- memcpy(lpPropVal->Value.bin.lpb, strBinUid.data(), lpPropVal->Value.bin.cb);
- *lppPropVal = lpPropVal;
- exit:
- if (hr != hrSuccess && base == nullptr)
- MAPIFreeBuffer(lpPropVal);
- return hr;
- }
- /**
- * Extracts ical UID from the binary outlook UID
- *
- * If the UID is an outlook wrapped ical UID, the ical part is
- * returned, otherwise a hex string representation of the UID is
- * returned.
- *
- * @param[in] sBin binary outlook UID
- * @param[out] lpStrUid returned ical string UID
- * @return MAPI error code
- */
- HRESULT HrGetICalUidFromBinUid(const SBinary &sBin, std::string *lpStrUid)
- {
- HRESULT hr = hrSuccess;
- std::string strUid;
- if (sBin.cb > 0x34 && memcmp(sBin.lpb + 0x28, "vCal-Uid", 8) == 0)
- strUid = (char*)sBin.lpb + 0x34;
- else
- strUid = bin2hex(sBin.cb, sBin.lpb);
- lpStrUid->swap(strUid);
- return hr;
- }
- /**
- * Converts ical UID to Outlook compatible UIDs.
- *
- * Add a special Outlook GUID and marker to the Ical UID. This format
- * is used in Outlook for non-outlook UIDs send by other ICal clients.
- *
- * @param[in] strUid ical UID
- * @param[out] lpStrBinUid returned outlook compatible string UID
- * @return HRESULT
- */
- HRESULT HrMakeBinUidFromICalUid(const std::string &strUid, std::string *lpStrBinUid)
- {
- HRESULT hr = hrSuccess;
- std::string strBinUid;
- int len = 13 + strUid.length();
- 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);
- strBinUid.append((char*) &len, 4);
- strBinUid.append("vCal-Uid", 8);
- len = 1; // this is always 1
- strBinUid.append((char*)&len, 4);
- strBinUid.append(strUid);
- strBinUid.append("\x00", 1);
- lpStrBinUid->swap(strBinUid);
- return hr;
- }
- } /* namespace */
|