123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023 |
- /*
- * 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 <new>
- #include "ECPropertyEntry.h"
- #include "Mem.h"
- #include <kopano/charset/convert.h>
- //
- // ECPropertyEntry
- //
- DEF_INVARIANT_CHECK(ECPropertyEntry) {
- // There should always be a proptag set.
- assert(ulPropTag != 0);
- assert(PROP_ID(ulPropTag) != 0);
- // PT_STRING8 and PT_MV_STRING8 are never stored.
- assert(PROP_TYPE(ulPropTag) != PT_STRING8);
- assert(PROP_TYPE(ulPropTag) != PT_MV_STRING8);
- }
- ECPropertyEntry::ECPropertyEntry(ULONG ulPropTag) :
- lpProperty(nullptr)
- {
- this->ulPropTag = ulPropTag;
- DEBUG_CHECK_INVARIANT;
- }
- ECPropertyEntry::ECPropertyEntry(ECProperty *property)
- {
- this->ulPropTag = property->GetPropTag();
- this->lpProperty = property;
- DEBUG_CHECK_INVARIANT;
- }
- ECPropertyEntry::~ECPropertyEntry()
- {
- DEBUG_CHECK_INVARIANT;
- }
- // NOTE: lpsPropValue must be checked already
- HRESULT ECPropertyEntry::HrSetProp(const SPropValue *lpsPropValue)
- {
- DEBUG_GUARD;
- HRESULT hr = hrSuccess;
- assert(this->ulPropTag != 0);
- assert(this->ulPropTag == lpsPropValue->ulPropTag);
- if(this->lpProperty)
- this->lpProperty->CopyFrom(lpsPropValue);
- else
- this->lpProperty = new ECProperty(lpsPropValue);
- this->fDirty = TRUE;
- return hr;
- }
- HRESULT ECPropertyEntry::HrSetProp(ECProperty *property)
- {
- DEBUG_GUARD;
- HRESULT hr = hrSuccess;
- assert(property->GetPropTag() != 0);
- assert(this->lpProperty == NULL);
- this->lpProperty = property;
- this->fDirty = TRUE;
- return hr;
- }
- HRESULT ECPropertyEntry::HrSetClean()
- {
- DEBUG_GUARD;
- this->fDirty = FALSE;
- return hrSuccess;
- }
- void ECPropertyEntry::DeleteProperty()
- {
- delete this->lpProperty;
- this->lpProperty = NULL;
- }
- //
- //
- //
- // ECProperty
- //
- // C++ class representing a property
- //
- //
- //
- //
- DEF_INVARIANT_CHECK(ECProperty) {
- // There should always be a proptag set.
- assert(ulPropTag != 0);
- assert(PROP_ID(ulPropTag) != 0);
- // PT_STRING8 and PT_MV_STRING8 are never stored.
- assert(PROP_TYPE(ulPropTag) != PT_STRING8);
- assert(PROP_TYPE(ulPropTag) != PT_MV_STRING8);
- }
- ECProperty::ECProperty(const ECProperty &Property) {
- SPropValue sPropValue;
- assert(Property.ulPropTag != 0);
- sPropValue.ulPropTag = Property.ulPropTag;
- sPropValue.Value = Property.Value;
- memset(&this->Value, 0, sizeof(union __UPV));
- this->ulSize = 0;
- CopyFromInternal(&sPropValue);
- DEBUG_CHECK_INVARIANT;
- }
-
- ECProperty::ECProperty(const SPropValue *lpsProp)
- {
- memset(&this->Value, 0, sizeof(union __UPV));
- this->ulSize = 0;
- assert(lpsProp->ulPropTag != 0);
- CopyFromInternal(lpsProp);
- DEBUG_CHECK_INVARIANT;
- }
- HRESULT ECProperty::CopyFrom(const SPropValue *lpsProp)
- {
- DEBUG_GUARD;
- return CopyFromInternal(lpsProp);
- }
- HRESULT ECProperty::CopyFromInternal(const SPropValue *lpsProp)
- {
- ULONG ulNewSize = 0;
- unsigned int i;
- if (lpsProp == NULL)
- return dwLastError = MAPI_E_INVALID_PARAMETER;
- this->dwLastError = 0;
- this->ulPropTag = lpsProp->ulPropTag;
- assert(lpsProp->ulPropTag != 0);
- switch(PROP_TYPE(lpsProp->ulPropTag)) {
- case PT_I2:
- this->ulSize = 4;
- this->Value.i = lpsProp->Value.i;
- break;
- case PT_I4:
- this->ulSize = 4;
- this->Value.l = lpsProp->Value.l;
- break;
- case PT_R4:
- this->ulSize = 4;
- this->Value.flt = lpsProp->Value.flt;
- break;
- case PT_R8:
- this->ulSize = 4;
- this->Value.dbl = lpsProp->Value.dbl;
- break;
- case PT_BOOLEAN:
- this->ulSize = 4;
- this->Value.b = lpsProp->Value.b;
- break;
- case PT_CURRENCY:
- this->ulSize = 4;
- this->Value.cur = lpsProp->Value.cur;
- break;
- case PT_APPTIME:
- this->ulSize = 4;
- this->Value.at = lpsProp->Value.at;
- break;
- case PT_SYSTIME:
- this->ulSize = 4;
- this->Value.ft = lpsProp->Value.ft;
- break;
- case PT_STRING8: {
- std::wstring wstrTmp;
- if (lpsProp->Value.lpszA == NULL)
- return dwLastError = MAPI_E_INVALID_PARAMETER;
- if (TryConvert(lpsProp->Value.lpszA, wstrTmp) != hrSuccess)
- return dwLastError = MAPI_E_INVALID_PARAMETER;
- ulNewSize = wstrTmp.length() + 1;
- if(ulSize < ulNewSize) {
- delete[] this->Value.lpszW;
- this->Value.lpszW = new(std::nothrow) WCHAR[ulNewSize];
- if (this->Value.lpszW == NULL)
- return dwLastError = MAPI_E_NOT_ENOUGH_MEMORY;
- }
- ulSize = ulNewSize;
-
- this->ulPropTag = CHANGE_PROP_TYPE(lpsProp->ulPropTag, PT_UNICODE);
- wcscpy(this->Value.lpszW, wstrTmp.c_str());
- break;
- }
- case PT_BINARY: {
- if (lpsProp->Value.bin.lpb == NULL && lpsProp->Value.bin.cb)
- return dwLastError = MAPI_E_INVALID_PARAMETER;
- ulNewSize = lpsProp->Value.bin.cb;
- if(ulNewSize == 0) {
- delete[] this->Value.bin.lpb;
- this->Value.bin.lpb = NULL;
- this->Value.bin.cb = 0;
- ulSize = 0;
- break;
- }
- if(ulSize < ulNewSize) {
- delete[] this->Value.bin.lpb;
- this->Value.bin.lpb = new(std::nothrow) BYTE[ulNewSize];
- if (this->Value.bin.lpb == NULL)
- return dwLastError = MAPI_E_NOT_ENOUGH_MEMORY;
- }
- ulSize = ulNewSize;
- this->Value.bin.cb = lpsProp->Value.bin.cb;
- memcpy(this->Value.bin.lpb, lpsProp->Value.bin.lpb, lpsProp->Value.bin.cb);
-
- break;
- }
- case PT_UNICODE: {
- if (lpsProp->Value.lpszW == NULL)
- return dwLastError = MAPI_E_INVALID_PARAMETER;
- ulNewSize = wcslen(lpsProp->Value.lpszW)+1;
- if(ulSize < ulNewSize) {
- delete[] this->Value.lpszW;
- this->Value.lpszW = new(std::nothrow) WCHAR[ulNewSize];
- if (this->Value.lpszW == NULL)
- return dwLastError = MAPI_E_NOT_ENOUGH_MEMORY;
- }
- ulSize = ulNewSize;
-
- wcscpy(this->Value.lpszW, lpsProp->Value.lpszW);
- break;
- }
- case PT_CLSID: {
- if (lpsProp->Value.lpguid == NULL)
- return dwLastError = MAPI_E_INVALID_PARAMETER;
- if(ulSize != sizeof(GUID)) {
- ulSize = sizeof(GUID);
- this->Value.lpguid = new(std::nothrow) GUID;
- if (this->Value.lpguid == NULL)
- return dwLastError = MAPI_E_NOT_ENOUGH_MEMORY;
- }
- memcpy(this->Value.lpguid, lpsProp->Value.lpguid, sizeof(GUID));
- break;
- }
- case PT_I8:
- ulSize = 8;
- this->Value.li = lpsProp->Value.li;
- break;
- case PT_MV_I2: {
- if (lpsProp->Value.MVi.lpi == NULL)
- return dwLastError = MAPI_E_INVALID_PARAMETER;
- ulNewSize = sizeof(short int)*lpsProp->Value.MVi.cValues;
- if(ulSize < ulNewSize) {
- delete[] this->Value.MVi.lpi;
- this->Value.MVi.lpi = new(std::nothrow) short int[lpsProp->Value.MVi.cValues];
- if (this->Value.MVi.lpi == NULL)
- return dwLastError = MAPI_E_NOT_ENOUGH_MEMORY;
- }
- ulSize = ulNewSize;
- this->Value.MVi.cValues = lpsProp->Value.MVi.cValues;
- memcpy(this->Value.MVi.lpi, lpsProp->Value.MVi.lpi, lpsProp->Value.MVi.cValues * sizeof(short int));
- break;
- }
- case PT_MV_LONG: {
- if (lpsProp->Value.MVl.lpl == NULL)
- return dwLastError = MAPI_E_INVALID_PARAMETER;
- ulNewSize = sizeof(LONG) * lpsProp->Value.MVl.cValues;
- if(ulSize < ulNewSize) {
- delete[] this->Value.MVl.lpl;
- this->Value.MVl.lpl = new(std::nothrow) LONG[lpsProp->Value.MVl.cValues];
- if (this->Value.MVl.lpl == NULL)
- return dwLastError = MAPI_E_NOT_ENOUGH_MEMORY;
- }
-
- ulSize = ulNewSize;
- this->Value.MVl.cValues = lpsProp->Value.MVl.cValues;
- memcpy(this->Value.MVl.lpl, lpsProp->Value.MVl.lpl, lpsProp->Value.MVl.cValues * sizeof(int));
-
- break;
- }
- case PT_MV_R4: {
- if (lpsProp->Value.MVflt.lpflt == NULL)
- return dwLastError = MAPI_E_INVALID_PARAMETER;
- ulNewSize = sizeof(float) * lpsProp->Value.MVflt.cValues;
- if(ulSize < ulNewSize) {
- delete[] this->Value.MVflt.lpflt;
- this->Value.MVflt.lpflt = new(std::nothrow) float[lpsProp->Value.MVflt.cValues];
- if (this->Value.MVflt.lpflt == NULL)
- return dwLastError = MAPI_E_NOT_ENOUGH_MEMORY;
- }
-
- ulSize = ulNewSize;
- this->Value.MVflt.cValues = lpsProp->Value.MVflt.cValues;
- memcpy(this->Value.MVflt.lpflt, lpsProp->Value.MVflt.lpflt, lpsProp->Value.MVflt.cValues * sizeof(float));
-
- break;
- }
- case PT_MV_DOUBLE: {
- if (lpsProp->Value.MVdbl.lpdbl == NULL)
- return dwLastError = MAPI_E_INVALID_PARAMETER;
- ulNewSize = sizeof(double) * lpsProp->Value.MVdbl.cValues;
- if(ulSize < ulNewSize) {
- delete[] this->Value.MVdbl.lpdbl;
- this->Value.MVdbl.lpdbl = new(std::nothrow) double[lpsProp->Value.MVdbl.cValues];
- if (this->Value.MVdbl.lpdbl == NULL)
- return dwLastError = MAPI_E_NOT_ENOUGH_MEMORY;
- }
- ulSize = ulNewSize;
- this->Value.MVdbl.cValues = lpsProp->Value.MVdbl.cValues;
- memcpy(this->Value.MVdbl.lpdbl, lpsProp->Value.MVdbl.lpdbl, lpsProp->Value.MVdbl.cValues * sizeof(double));
- break;
- }
- case PT_MV_CURRENCY: {
- if (lpsProp->Value.MVcur.lpcur == NULL)
- return dwLastError = MAPI_E_INVALID_PARAMETER;
- ulNewSize = sizeof(CURRENCY) * lpsProp->Value.MVcur.cValues;
- if(ulSize < ulNewSize) {
- delete[] this->Value.MVcur.lpcur;
- this->Value.MVcur.lpcur = new(std::nothrow) CURRENCY[lpsProp->Value.MVcur.cValues];
- if (this->Value.MVcur.lpcur == NULL)
- return dwLastError = MAPI_E_NOT_ENOUGH_MEMORY;
- }
-
- ulSize = ulNewSize;
- this->Value.MVcur.cValues = lpsProp->Value.MVcur.cValues;
- memcpy(this->Value.MVcur.lpcur, lpsProp->Value.MVcur.lpcur, lpsProp->Value.MVcur.cValues * sizeof(CURRENCY));
- break;
- }
- case PT_MV_APPTIME: {
- if (lpsProp->Value.MVat.lpat == NULL)
- return dwLastError = MAPI_E_INVALID_PARAMETER;
- ulNewSize = sizeof(double) * lpsProp->Value.MVat.cValues;
- if(ulSize < ulNewSize) {
- if(this->Value.MVat.lpat)
- delete[] this->Value.MVat.lpat;
- this->Value.MVat.lpat = new(std::nothrow) double[lpsProp->Value.MVat.cValues];
- if (this->Value.MVat.lpat == NULL)
- return dwLastError = MAPI_E_NOT_ENOUGH_MEMORY;
- }
- ulSize = ulNewSize;
- this->Value.MVat.cValues = lpsProp->Value.MVat.cValues;
- memcpy(this->Value.MVat.lpat, lpsProp->Value.MVat.lpat, lpsProp->Value.MVat.cValues * sizeof(double));
-
- break;
- }
- case PT_MV_SYSTIME: {
- if (lpsProp->Value.MVft.lpft == NULL)
- return dwLastError = MAPI_E_INVALID_PARAMETER;
- ulNewSize = sizeof(FILETIME) * lpsProp->Value.MVft.cValues;
- if(ulSize < ulNewSize) {
- delete[] this->Value.MVft.lpft;
- this->Value.MVft.lpft = new(std::nothrow) FILETIME[lpsProp->Value.MVft.cValues];
- if (this->Value.MVft.lpft == NULL)
- return dwLastError = MAPI_E_NOT_ENOUGH_MEMORY;
- }
-
- ulSize = ulNewSize;
-
- this->Value.MVft.cValues = lpsProp->Value.MVft.cValues;
- memcpy(this->Value.MVft.lpft, lpsProp->Value.MVft.lpft, lpsProp->Value.MVft.cValues * sizeof(FILETIME));
-
- break;
- }
- case PT_MV_BINARY: {
- if (lpsProp->Value.MVbin.lpbin == NULL)
- return dwLastError = MAPI_E_INVALID_PARAMETER;
- ulNewSize = sizeof(void *) * lpsProp->Value.MVbin.cValues;
- if(ulSize < ulNewSize) {
-
- if(this->Value.MVbin.lpbin){
- for (unsigned int i = 0; i < this->Value.MVbin.cValues; ++i)
- delete[] this->Value.MVbin.lpbin[i].lpb;
- delete[] this->Value.MVbin.lpbin;
- }
- this->Value.MVbin.lpbin = new(std::nothrow) SBinary[lpsProp->Value.MVbin.cValues];
- if (this->Value.MVbin.lpbin == NULL)
- return dwLastError = MAPI_E_NOT_ENOUGH_MEMORY;
- memset(this->Value.MVbin.lpbin, 0, sizeof(SBinary) * lpsProp->Value.MVbin.cValues);
- }
- else {
- for(unsigned int i = lpsProp->Value.MVbin.cValues; i < this->Value.MVbin.cValues; ++i)
- delete[] this->Value.MVbin.lpbin[i].lpb;
- }
- ulSize = ulNewSize;
- this->Value.MVbin.cValues = lpsProp->Value.MVbin.cValues;
- for (unsigned int i = 0; i < lpsProp->Value.MVbin.cValues; ++i) {
- if(lpsProp->Value.MVbin.lpbin[i].cb > 0)
- {
- if (lpsProp->Value.MVbin.lpbin[i].lpb == NULL)
- return dwLastError = MAPI_E_INVALID_PARAMETER;
- if(this->Value.MVbin.lpbin[i].lpb == NULL || this->Value.MVbin.lpbin[i].cb < lpsProp->Value.MVbin.lpbin[i].cb) {
- delete[] this->Value.MVbin.lpbin[i].lpb;
- this->Value.MVbin.lpbin[i].lpb = new BYTE [lpsProp->Value.MVbin.lpbin[i].cb];
- }
-
- memcpy(this->Value.MVbin.lpbin[i].lpb, lpsProp->Value.MVbin.lpbin[i].lpb, lpsProp->Value.MVbin.lpbin[i].cb);
- }else {
- delete[] this->Value.MVbin.lpbin[i].lpb;
- this->Value.MVbin.lpbin[i].lpb = NULL;
- }
- this->Value.MVbin.lpbin[i].cb = lpsProp->Value.MVbin.lpbin[i].cb;
- }
- break;
- }
- case PT_MV_STRING8: {
- convert_context converter;
- if (lpsProp->Value.MVszA.lppszA == NULL)
- return dwLastError = MAPI_E_INVALID_PARAMETER;
- ulNewSize = sizeof(void *) * lpsProp->Value.MVszA.cValues;
- if(ulSize < ulNewSize) {
-
- if(this->Value.MVszW.lppszW) {
- for (i = 0; i < this->Value.MVszW.cValues; ++i)
- delete [] this->Value.MVszW.lppszW[i];
- delete [] this->Value.MVszW.lppszW;
- }
- this->Value.MVszW.lppszW = new(std::nothrow) wchar_t *[lpsProp->Value.MVszA.cValues];
- if (this->Value.MVszW.lppszW == NULL)
- return dwLastError = MAPI_E_NOT_ENOUGH_MEMORY;
- memset(this->Value.MVszW.lppszW, 0, sizeof(wchar_t *) * lpsProp->Value.MVszA.cValues);
- }
- else {
- for(unsigned int i = lpsProp->Value.MVszW.cValues; i < this->Value.MVszW.cValues; ++i)
- delete[] this->Value.MVszW.lppszW[i];
- }
- ulSize = ulNewSize;
- this->Value.MVszW.cValues = lpsProp->Value.MVszA.cValues;
- for (unsigned int i = 0; i < lpsProp->Value.MVszA.cValues; ++i) {
- std::wstring wstrTmp;
- if (lpsProp->Value.MVszA.lppszA[i] == NULL)
- return dwLastError = MAPI_E_INVALID_PARAMETER;
- if (TryConvert(lpsProp->Value.MVszA.lppszA[i], wstrTmp) != hrSuccess)
- return dwLastError = MAPI_E_INVALID_PARAMETER;
- if(this->Value.MVszW.lppszW[i] == NULL || wcslen(this->Value.MVszW.lppszW[i]) < wstrTmp.length())
- {
- delete[] this->Value.MVszW.lppszW[i];
- this->Value.MVszW.lppszW[i] = new WCHAR [wstrTmp.length() + sizeof(wchar_t)];
- }
- wcscpy(this->Value.MVszW.lppszW[i], wstrTmp.c_str());
- }
- this->ulPropTag = CHANGE_PROP_TYPE(lpsProp->ulPropTag, PT_MV_UNICODE);
- break;
- }
- case PT_MV_UNICODE: {
- if (lpsProp->Value.MVszW.lppszW == NULL)
- return dwLastError = MAPI_E_INVALID_PARAMETER;
- ulNewSize = sizeof(void *) * lpsProp->Value.MVszW.cValues;
- if(ulSize < ulNewSize) {
- if(this->Value.MVszW.lppszW) {
- for (unsigned int i = 0; i < this->Value.MVszW.cValues; ++i)
- delete[] this->Value.MVszW.lppszW[i];
- delete[] this->Value.MVszW.lppszW;
- }
- this->Value.MVszW.lppszW = new(std::nothrow) wchar_t *[lpsProp->Value.MVszW.cValues];
- if (this->Value.MVszW.lppszW == NULL)
- return dwLastError = MAPI_E_NOT_ENOUGH_MEMORY;
- memset(this->Value.MVszW.lppszW, 0, sizeof(WCHAR *) * lpsProp->Value.MVszW.cValues);
- }
- else {
- for(unsigned int i = lpsProp->Value.MVszW.cValues; i < this->Value.MVszW.cValues; ++i)
- delete[] this->Value.MVszW.lppszW[i];
- }
-
- ulSize = ulNewSize;
- this->Value.MVszW.cValues = lpsProp->Value.MVszW.cValues;
- for (unsigned int i = 0; i < lpsProp->Value.MVszW.cValues; ++i) {
- if (lpsProp->Value.MVszW.lppszW[i] == NULL)
- return dwLastError = MAPI_E_INVALID_PARAMETER;
- if(this->Value.MVszW.lppszW[i] == NULL || wcslen(this->Value.MVszW.lppszW[i]) < wcslen(lpsProp->Value.MVszW.lppszW[i])) {
- delete[] this->Value.MVszW.lppszW[i];
- this->Value.MVszW.lppszW[i] = new WCHAR [wcslen(lpsProp->Value.MVszW.lppszW[i])+sizeof(WCHAR)];
- }
- wcscpy(this->Value.MVszW.lppszW[i], lpsProp->Value.MVszW.lppszW[i]);
- }
- break;
- }
- case PT_MV_CLSID: {
- if (lpsProp->Value.MVguid.lpguid == NULL)
- return dwLastError = MAPI_E_INVALID_PARAMETER;
- ulNewSize = sizeof(GUID) * lpsProp->Value.MVguid.cValues;
- if(ulSize < ulNewSize) {
- delete[] this->Value.MVguid.lpguid;
- this->Value.MVguid.lpguid = new(std::nothrow) GUID[lpsProp->Value.MVguid.cValues];
- if (this->Value.MVguid.lpguid == NULL)
- return dwLastError = MAPI_E_NOT_ENOUGH_MEMORY;
- }
- ulSize = ulNewSize;
- this->Value.MVguid.cValues = lpsProp->Value.MVguid.cValues;
- memcpy(this->Value.MVguid.lpguid, lpsProp->Value.MVguid.lpguid, sizeof(GUID) * lpsProp->Value.MVguid.cValues);
-
- break;
- }
- case PT_MV_I8: {
- if (lpsProp->Value.MVli.lpli == NULL)
- return dwLastError = MAPI_E_INVALID_PARAMETER;
- ulNewSize = sizeof(LARGE_INTEGER) * lpsProp->Value.MVli.cValues;
- if(ulSize < ulNewSize) {
- delete[] this->Value.MVli.lpli;
- this->Value.MVli.lpli = new(std::nothrow) LARGE_INTEGER[lpsProp->Value.MVli.cValues];
- if (this->Value.MVli.lpli == NULL)
- return dwLastError = MAPI_E_NOT_ENOUGH_MEMORY;
- }
- ulSize = ulNewSize;
- this->Value.MVli.cValues = lpsProp->Value.MVli.cValues;
- memcpy(this->Value.MVli.lpli, lpsProp->Value.MVli.lpli, lpsProp->Value.MVli.cValues * sizeof(LARGE_INTEGER));
- break;
- }
- case PT_ERROR:
- this->Value.err = lpsProp->Value.err;
- break;
- default:
- // Unknown type (PR_NULL not include)
- assert(false);
- dwLastError = MAPI_E_INVALID_PARAMETER;
- break;
- }
- return dwLastError;
- }
- ECProperty::~ECProperty()
- {
- DEBUG_GUARD;
- switch(PROP_TYPE(ulPropTag)) {
- case PT_I2:
- case PT_I4:
- case PT_R4:
- case PT_R8:
- case PT_BOOLEAN:
- case PT_CURRENCY:
- case PT_APPTIME:
- case PT_SYSTIME:
- case PT_I8:
- break;
- case PT_BINARY:
- delete[] this->Value.bin.lpb;
- break;
- case PT_STRING8:
- assert("We should never have PT_STRING8 storage" == nullptr);
- // Deliberate fallthrough
- case PT_UNICODE:
- delete [] this->Value.lpszW;
- break;
- case PT_CLSID:
- delete this->Value.lpguid;
- break;
- case PT_MV_I2:
- delete [] Value.MVi.lpi;
- break;
- case PT_MV_LONG:
- delete [] this->Value.MVl.lpl;
- break;
- case PT_MV_R4:
- delete [] this->Value.MVflt.lpflt;
- break;
- case PT_MV_DOUBLE:
- delete [] this->Value.MVdbl.lpdbl;
- break;
- case PT_MV_CURRENCY:
- delete [] this->Value.MVcur.lpcur;
- break;
- case PT_MV_APPTIME:
- delete [] this->Value.MVat.lpat;
- break;
- case PT_MV_SYSTIME:
- delete [] this->Value.MVft.lpft;
- break;
- case PT_MV_BINARY: {
- for (unsigned int i = 0; i <this->Value.MVbin.cValues; ++i)
- delete[] this->Value.MVbin.lpbin[i].lpb;
- delete [] this->Value.MVbin.lpbin;
- break;
- }
- case PT_MV_STRING8:
- assert("We should never have PT_MV_STRING8 storage" == nullptr);
- // Deliberate fallthrough
- case PT_MV_UNICODE: {
- for (unsigned int i = 0; i < this->Value.MVszW.cValues; ++i)
- delete [] this->Value.MVszW.lppszW[i];
- delete [] this->Value.MVszW.lppszW;
- break;
- }
- case PT_MV_CLSID: {
- delete [] this->Value.MVguid.lpguid;
- break;
- }
- case PT_MV_I8:
- delete [] this->Value.MVli.lpli;
- break;
- case PT_ERROR:
- break;
- default:
- break;
- }
- }
- HRESULT ECProperty::CopyToByRef(LPSPropValue lpsProp) const
- {
- DEBUG_GUARD;
- HRESULT hr = hrSuccess;
-
- lpsProp->ulPropTag = this->ulPropTag;
- memcpy(&lpsProp->Value, &this->Value, sizeof(union __UPV));
- return hr;
- }
- HRESULT ECProperty::CopyTo(LPSPropValue lpsProp, void *lpBase, ULONG ulRequestPropTag) {
- DEBUG_GUARD;
- HRESULT hr = hrSuccess;
- assert
- (
- PROP_TYPE(ulRequestPropTag) == PROP_TYPE(this->ulPropTag) ||
- ((PROP_TYPE(ulRequestPropTag) == PT_STRING8 || PROP_TYPE(ulRequestPropTag) == PT_UNICODE) && PROP_TYPE(this->ulPropTag) == PT_UNICODE) ||
- ((PROP_TYPE(ulRequestPropTag) == PT_MV_STRING8 || PROP_TYPE(ulRequestPropTag) == PT_MV_UNICODE) && PROP_TYPE(this->ulPropTag) == PT_MV_UNICODE)
- );
- lpsProp->ulPropTag = ulRequestPropTag;
- switch(PROP_TYPE(this->ulPropTag)) {
- case PT_I2:
- lpsProp->Value.i = this->Value.i;
- break;
- case PT_I4:
- lpsProp->Value.l = this->Value.l;
- break;
- case PT_R4:
- lpsProp->Value.flt = this->Value.flt;
- break;
- case PT_R8:
- lpsProp->Value.dbl = this->Value.dbl;
- break;
- case PT_BOOLEAN:
- lpsProp->Value.b = this->Value.b;
- break;
- case PT_CURRENCY:
- lpsProp->Value.cur = this->Value.cur;
- break;
- case PT_APPTIME:
- lpsProp->Value.at = this->Value.at;
- break;
- case PT_SYSTIME:
- lpsProp->Value.ft = this->Value.ft;
- break;
- case PT_BINARY: {
- if (this->Value.bin.cb == 0) {
- lpsProp->Value.bin.lpb = NULL;
- lpsProp->Value.bin.cb = this->Value.bin.cb;
- } else {
- BYTE *lpBin = NULL;
- hr = ECAllocateMore(this->Value.bin.cb, lpBase, (LPVOID *)&lpBin);
- if(hr != hrSuccess)
- dwLastError = hr;
- else {
- memcpy(lpBin, this->Value.bin.lpb, this->Value.bin.cb);
- lpsProp->Value.bin.lpb = lpBin;
- lpsProp->Value.bin.cb = this->Value.bin.cb;
- }
- }
- break;
- }
- case PT_STRING8:
- assert("We should never have PT_STRING8 storage" == nullptr);
- // Deliberate fallthrough
- case PT_UNICODE: {
- if (PROP_TYPE(ulRequestPropTag) == PT_UNICODE) {
- hr = ECAllocateMore(sizeof(WCHAR) * (wcslen(this->Value.lpszW) + 1), lpBase, (LPVOID*)&lpsProp->Value.lpszW);
- if (hr != hrSuccess)
- dwLastError = hr;
- else
- wcscpy(lpsProp->Value.lpszW, this->Value.lpszW);
- }
- else {
- std::string dst;
- if (TryConvert(this->Value.lpszW, dst) != hrSuccess) {
- dwLastError = MAPI_E_INVALID_PARAMETER;
- return hr;
- }
- hr = ECAllocateMore(dst.length() + 1, lpBase, (LPVOID*)&lpsProp->Value.lpszA);
- if (hr != hrSuccess)
- dwLastError = hr;
- else
- strcpy(lpsProp->Value.lpszA, dst.c_str());
- }
- break;
- }
- case PT_CLSID: {
- GUID *lpGUID;
- hr = ECAllocateMore(sizeof(GUID), lpBase, (LPVOID *)&lpGUID);
- if(hr != hrSuccess)
- dwLastError = hr;
- else {
- memcpy(lpGUID, this->Value.lpguid, sizeof(GUID));
- lpsProp->Value.lpguid = lpGUID;
- }
- break;
- }
- case PT_I8:
- lpsProp->Value.li = this->Value.li;
- break;
- case PT_MV_I2: {
- short int *lpShort;
- hr = ECAllocateMore(this->Value.MVi.cValues * sizeof(short int), lpBase, (LPVOID *)&lpShort);
- if(hr != hrSuccess)
- dwLastError = hr;
- else {
- lpsProp->Value.MVi.cValues = this->Value.MVi.cValues;
- memcpy(lpShort, this->Value.MVi.lpi, this->Value.MVi.cValues * sizeof(short int));
- lpsProp->Value.MVi.lpi = lpShort;
- }
- break;
- }
- case PT_MV_LONG: {
- LONG *lpLong;
- hr = ECAllocateMore(this->Value.MVl.cValues * sizeof(LONG), lpBase, (LPVOID *)&lpLong);
- if(hr != hrSuccess)
- dwLastError = hr;
- else {
- lpsProp->Value.MVl.cValues = this->Value.MVl.cValues;
- memcpy(lpLong, this->Value.MVl.lpl, this->Value.MVl.cValues * sizeof(LONG));
- lpsProp->Value.MVl.lpl = lpLong;
- }
- break;
- }
- case PT_MV_R4: {
- float *lpFloat;
- hr = ECAllocateMore(this->Value.MVflt.cValues * sizeof(float), lpBase, (LPVOID *)&lpFloat);
- if(hr != hrSuccess)
- dwLastError = hr;
- else {
- lpsProp->Value.MVflt.cValues = this->Value.MVflt.cValues;
- memcpy(lpFloat, this->Value.MVflt.lpflt, this->Value.MVflt.cValues * sizeof(float));
- lpsProp->Value.MVflt.lpflt = lpFloat;
- }
- break;
- }
- case PT_MV_DOUBLE: {
- double *lpDouble;
- hr = ECAllocateMore(this->Value.MVdbl.cValues * sizeof(double), lpBase, (LPVOID *)&lpDouble);
- if(hr != hrSuccess)
- dwLastError = hr;
- else {
- lpsProp->Value.MVdbl.cValues = this->Value.MVdbl.cValues;
- memcpy(lpDouble, this->Value.MVdbl.lpdbl, this->Value.MVdbl.cValues * sizeof(double));
- lpsProp->Value.MVdbl.lpdbl = lpDouble;
- }
- break;
- }
- case PT_MV_CURRENCY: {
- CURRENCY *lpCurrency;
- hr = ECAllocateMore(this->Value.MVcur.cValues * sizeof(CURRENCY), lpBase, (LPVOID *)&lpCurrency);
- if(hr != hrSuccess)
- dwLastError = hr;
- else {
- lpsProp->Value.MVcur.cValues = this->Value.MVcur.cValues;
- memcpy(lpCurrency, this->Value.MVcur.lpcur, this->Value.MVcur.cValues * sizeof(CURRENCY));
- lpsProp->Value.MVcur.lpcur = lpCurrency;
- }
- break;
- }
- case PT_MV_APPTIME: {
- double *lpApptime;
- hr = ECAllocateMore(this->Value.MVat.cValues * sizeof(double), lpBase, (LPVOID *)&lpApptime);
- if(hr != hrSuccess)
- dwLastError = hr;
- else {
- lpsProp->Value.MVat.cValues = this->Value.MVat.cValues;
- memcpy(lpApptime, this->Value.MVat.lpat, this->Value.MVat.cValues * sizeof(double));
- lpsProp->Value.MVat.lpat = lpApptime;
- }
- break;
- }
- case PT_MV_SYSTIME: {
- FILETIME *lpFiletime;
- hr = ECAllocateMore(this->Value.MVft.cValues * sizeof(FILETIME), lpBase, (LPVOID *)&lpFiletime);
- if(hr != hrSuccess)
- dwLastError = hr;
- else {
- lpsProp->Value.MVft.cValues = this->Value.MVft.cValues;
- memcpy(lpFiletime, this->Value.MVft.lpft, this->Value.MVft.cValues * sizeof(FILETIME));
- lpsProp->Value.MVft.lpft = lpFiletime;
- }
- break;
- }
- case PT_MV_BINARY: {
- SBinary *lpBin;
- hr = ECAllocateMore(this->Value.MVbin.cValues * sizeof(SBinary), lpBase, (LPVOID *)&lpBin);
- if(hr != hrSuccess)
- dwLastError = hr;
- else {
- lpsProp->Value.MVbin.cValues = this->Value.MVbin.cValues;
- lpsProp->Value.MVbin.lpbin = lpBin;
-
- for (unsigned int i = 0; i < this->Value.MVbin.cValues; ++i) {
- lpsProp->Value.MVbin.lpbin[i].cb = this->Value.MVbin.lpbin[i].cb;
- if(lpsProp->Value.MVbin.lpbin[i].cb > 0)
- {
- hr = ECAllocateMore(this->Value.MVbin.lpbin[i].cb, lpBase, reinterpret_cast<void **>(&lpsProp->Value.MVbin.lpbin[i].lpb));
- if (hr != hrSuccess)
- return hr;
- memcpy(lpsProp->Value.MVbin.lpbin[i].lpb, this->Value.MVbin.lpbin[i].lpb, lpsProp->Value.MVbin.lpbin[i].cb);
- }else
- lpsProp->Value.MVbin.lpbin[i].lpb = NULL;
- }
- }
- break;
- }
- case PT_MV_STRING8:
- assert("We should never have PT_MV_STRING8 storage" == nullptr);
- // Deliberate fallthrough
- case PT_MV_UNICODE: {
- if (PROP_TYPE(ulRequestPropTag) == PT_MV_STRING8) {
- lpsProp->Value.MVszA.cValues = this->Value.MVszW.cValues;
- hr = ECAllocateMore(this->Value.MVszW.cValues * sizeof(LPSTR), lpBase, (LPVOID*)&lpsProp->Value.MVszA.lppszA);
- if (hr != hrSuccess)
- dwLastError = hr;
- else {
- convert_context converter;
- for (ULONG i = 0; hr == hrSuccess && i < this->Value.MVszW.cValues; ++i) {
- std::string strDst;
- if (TryConvert(this->Value.MVszW.lppszW[i], strDst) != hrSuccess) {
- dwLastError = MAPI_E_INVALID_PARAMETER;
- return hr;
- }
- hr = ECAllocateMore(strDst.size() + 1, lpBase, (LPVOID*)&lpsProp->Value.MVszA.lppszA[i]);
- if (hr != hrSuccess)
- dwLastError = hr;
- else
- strcpy(lpsProp->Value.MVszA.lppszA[i], strDst.c_str());
- }
- }
- } else {
- lpsProp->Value.MVszW.cValues = this->Value.MVszW.cValues;
- hr = ECAllocateMore(this->Value.MVszW.cValues * sizeof(LPWSTR), lpBase, (LPVOID*)&lpsProp->Value.MVszW.lppszW);
- if (hr != hrSuccess)
- dwLastError = hr;
- else {
- for (ULONG i = 0; hr == hrSuccess && i < this->Value.MVszW.cValues; ++i) {
- hr = ECAllocateMore(sizeof(WCHAR) * (wcslen(this->Value.MVszW.lppszW[i]) + 1), lpBase, (LPVOID*)&lpsProp->Value.MVszW.lppszW[i]);
- if (hr != hrSuccess)
- dwLastError = hr;
- else
- wcscpy(lpsProp->Value.MVszW.lppszW[i], this->Value.MVszW.lppszW[i]);
- }
- }
- }
- break;
- }
- case PT_MV_CLSID: {
- GUID *lpGuid;
- hr = ECAllocateMore(this->Value.MVguid.cValues * sizeof(GUID), lpBase, (LPVOID *)&lpGuid);
- if(hr != hrSuccess)
- dwLastError = hr;
- else {
- memcpy(lpGuid, this->Value.MVguid.lpguid, sizeof(GUID) * this->Value.MVguid.cValues);
- lpsProp->Value.MVguid.cValues = this->Value.MVguid.cValues;
- lpsProp->Value.MVguid.lpguid = lpGuid;
- }
- break;
- }
- case PT_MV_I8: {
- LARGE_INTEGER *lpLarge;
- hr = ECAllocateMore(this->Value.MVli.cValues * sizeof(LARGE_INTEGER), lpBase, (LPVOID *)&lpLarge);
- if(hr != hrSuccess)
- dwLastError = hr;
- else {
- lpsProp->Value.MVli.cValues = this->Value.MVli.cValues;
- memcpy(lpLarge, this->Value.MVli.lpli, this->Value.MVli.cValues * sizeof(LARGE_INTEGER));
- lpsProp->Value.MVli.lpli = lpLarge;
- }
- break;
- }
- case PT_ERROR:
- lpsProp->Value.err = this->Value.err;
- break;
- default: // I hope there are no pointers involved here!
- assert(false);
- lpsProp->Value = this->Value;
- break;
- }
- return hr;
- }
- bool ECProperty::operator==(const ECProperty &property) const {
- DEBUG_GUARD;
- return property.ulPropTag == this->ulPropTag ||
- (
- PROP_ID(property.ulPropTag) == PROP_ID(this->ulPropTag) &&
- (
- (PROP_TYPE(property.ulPropTag) == PT_STRING8 && PROP_TYPE(this->ulPropTag) == PT_UNICODE) ||
- (PROP_TYPE(property.ulPropTag) == PT_MV_STRING8 && PROP_TYPE(this->ulPropTag) == PT_MV_UNICODE)
- )
- );
- }
- SPropValue ECProperty::GetMAPIPropValRef(void) const
- {
- DEBUG_GUARD;
- SPropValue ret;
- ret.ulPropTag = this->ulPropTag;
- ret.dwAlignPad = 0;
- ret.Value = this->Value;
- return ret;
- }
|