123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450 |
- #include <kopano/platform.h>
- #include <mapitags.h>
- #include <mapidefs.h>
- #include <mapicode.h>
- #include <list>
- #include "Mem.h"
- #include "ECNamedProp.h"
- #include "WSTransport.h"
- static const struct _sLocalNames {
- GUID guid;
- LONG ulMin;
- LONG ulMax;
- ULONG ulMappedId;
- } sLocalNames[] = {{{ 0x62002, 0x0, 0x0, { 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x46 } }, 0x8200, 0x826F, 0x8000 },
- {{ 0x62003, 0x0, 0x0, { 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x46 } }, 0x8100, 0x813F, 0x8070 },
- {{ 0x62004, 0x0, 0x0, { 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x46 } }, 0x8000, 0x80EF, 0x80B0 },
- {{ 0x62008, 0x0, 0x0, { 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x46 } }, 0x8500, 0x85FF, 0x81A0 },
- {{ 0x6200A, 0x0, 0x0, { 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x46 } }, 0x8700, 0x871F, 0x82A0 },
- {{ 0x6200B, 0x0, 0x0, { 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x46 } }, 0x8800, 0x881F, 0x82C0 },
- {{ 0x6200E, 0x0, 0x0, { 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x46 } }, 0x8B00, 0x8B1F, 0x82E0 },
- {{ 0x62013, 0x0, 0x0, { 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x46 } }, 0x8D00, 0x8D1F, 0x8300 },
- {{ 0x62014, 0x0, 0x0, { 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x46 } }, 0x8F00, 0x8F1F, 0x8320 },
- {{ 0x6ED8DA90, 0x450B, 0x101B, { 0x98, 0xDA, 0x00, 0xAA, 0x00, 0x3F, 0x13, 0x05} } , 0x0000, 0x003F, 0x8340}};
- #define SERVER_NAMED_OFFSET 0x8500
- ECNamedProp::ECNamedProp(WSTransport *lpTransport)
- {
- this->lpTransport = lpTransport;
- lpTransport->AddRef();
- }
- ECNamedProp::~ECNamedProp()
- {
-
- for (const auto &p : mapNames)
- if (p.first)
- ECFreeBuffer(p.first);
- if(lpTransport)
- lpTransport->Release();
- }
- HRESULT ECNamedProp::GetNamesFromIDs(LPSPropTagArray *lppPropTags, LPGUID lpPropSetGuid, ULONG ulFlags, ULONG *lpcPropNames, LPMAPINAMEID **lpppPropNames)
- {
- HRESULT hr = hrSuccess;
- unsigned int i = 0;
- LPSPropTagArray lpsPropTags = NULL;
- ecmem_ptr<MAPINAMEID *> lppPropNames, lppResolved;
- ecmem_ptr<SPropTagArray> lpsUnresolved;
- ULONG cResolved = 0;
- ULONG cUnresolved = 0;
-
- if(lppPropTags == NULL || *lppPropTags == NULL) {
- hr = MAPI_E_TOO_BIG;
- goto exit;
- }
- lpsPropTags = *lppPropTags;
-
- hr = ECAllocateBuffer(sizeof(LPMAPINAMEID) * lpsPropTags->cValues, &~lppPropNames);
- if (hr != hrSuccess)
- goto exit;
-
- for (i = 0; i < lpsPropTags->cValues; ++i)
- if (ResolveReverseLocal(PROP_ID(lpsPropTags->aulPropTag[i]),
- lpPropSetGuid, ulFlags, lppPropNames,
- &lppPropNames[i]) != hrSuccess)
- lppPropNames[i] = NULL;
-
- for (i = 0; i < lpsPropTags->cValues; ++i) {
- if (lppPropNames[i] != NULL)
- continue;
- if (PROP_ID(lpsPropTags->aulPropTag[i]) > SERVER_NAMED_OFFSET)
- ResolveReverseCache(PROP_ID(lpsPropTags->aulPropTag[i]), lpPropSetGuid, ulFlags, lppPropNames, &lppPropNames[i]);
-
-
- }
- hr = ECAllocateBuffer(CbNewSPropTagArray(lpsPropTags->cValues), &~lpsUnresolved);
- if (hr != hrSuccess)
- goto exit;
- cUnresolved = 0;
-
- for (i = 0; i < lpsPropTags->cValues; ++i)
- if (lppPropNames[i] == NULL)
- if(PROP_ID(lpsPropTags->aulPropTag[i]) > SERVER_NAMED_OFFSET) {
- lpsUnresolved->aulPropTag[cUnresolved] = PROP_ID(lpsPropTags->aulPropTag[i]) - SERVER_NAMED_OFFSET;
- ++cUnresolved;
- }
- lpsUnresolved->cValues = cUnresolved;
- if(cUnresolved > 0) {
- hr = lpTransport->HrGetNamesFromIDs(lpsUnresolved, &~lppResolved, &cResolved);
- if(hr != hrSuccess)
- goto exit;
-
- if(cResolved != cUnresolved) {
- hr = MAPI_E_CALL_FAILED;
- goto exit;
- }
- for (i = 0; i < cResolved; ++i)
- if(lppResolved[i] != NULL)
- UpdateCache(lpsUnresolved->aulPropTag[i] + SERVER_NAMED_OFFSET, lppResolved[i]);
-
- for (i = 0; i < lpsPropTags->cValues; ++i)
- if (lppPropNames[i] == NULL)
- if (PROP_ID(lpsPropTags->aulPropTag[i]) > SERVER_NAMED_OFFSET)
- ResolveReverseCache(PROP_ID(lpsPropTags->aulPropTag[i]), lpPropSetGuid, ulFlags, lppPropNames, &lppPropNames[i]);
- }
-
- for (i = 0; i < lpsPropTags->cValues; ++i)
- if(lppPropNames[i] == NULL)
- hr = MAPI_W_ERRORS_RETURNED;
- *lpppPropNames = lppPropNames.release();
- *lpcPropNames = lpsPropTags->cValues;
- exit:
- return hr;
- }
- HRESULT ECNamedProp::GetIDsFromNames(ULONG cPropNames, LPMAPINAMEID *lppPropNames, ULONG ulFlags, LPSPropTagArray *lppPropTags)
- {
- HRESULT hr = hrSuccess;
- unsigned int i=0;
- LPSPropTagArray lpsPropTagArray = NULL;
- std::unique_ptr<MAPINAMEID *[]> lppPropNamesUnresolved;
- ULONG cUnresolved = 0;
- ULONG* lpServerIDs = NULL;
-
- if(cPropNames == 0 || lppPropNames == NULL) {
- hr = MAPI_E_TOO_BIG;
- goto exit;
- }
-
- for (i = 0; i < cPropNames; ++i) {
- if(lppPropNames[i] == NULL) {
- hr = MAPI_E_INVALID_PARAMETER;
- goto exit;
- }
- }
-
- hr = ECAllocateBuffer(CbNewSPropTagArray(cPropNames), (void **)&lpsPropTagArray);
- if(hr != hrSuccess)
- goto exit;
- lpsPropTagArray->cValues = cPropNames;
-
- for (i = 0; i < cPropNames; ++i)
- if(lppPropNames[i] == NULL || ResolveLocal(lppPropNames[i], &lpsPropTagArray->aulPropTag[i]) != hrSuccess)
- lpsPropTagArray->aulPropTag[i] = PROP_TAG(PT_ERROR, 0);
-
- for (i = 0; i < cPropNames; ++i)
- if (lppPropNames[i] != NULL && lpsPropTagArray->aulPropTag[i] == PROP_TAG(PT_ERROR, 0))
- ResolveCache(lppPropNames[i], &lpsPropTagArray->aulPropTag[i]);
-
- lppPropNamesUnresolved.reset(new MAPINAMEID *[lpsPropTagArray->cValues]);
-
- for (i = 0; i < cPropNames; ++i)
- if(lpsPropTagArray->aulPropTag[i] == PROP_TAG(PT_ERROR, 0) && lppPropNames[i] != NULL ) {
- lppPropNamesUnresolved[cUnresolved] = lppPropNames[i];
- ++cUnresolved;
- }
- if(cUnresolved) {
-
- hr = lpTransport->HrGetIDsFromNames(lppPropNamesUnresolved.get(), cUnresolved, ulFlags, &lpServerIDs);
- if(hr != hrSuccess)
- goto exit;
-
- for (i = 0; i < cUnresolved; ++i)
- if(lpServerIDs[i] != 0)
- UpdateCache(lpServerIDs[i] + SERVER_NAMED_OFFSET, lppPropNamesUnresolved[i]);
-
- for (i = 0; i < cPropNames; ++i)
- if (lppPropNames[i] != NULL &&
- lpsPropTagArray->aulPropTag[i] == PROP_TAG(PT_ERROR, 0))
- ResolveCache(lppPropNames[i], &lpsPropTagArray->aulPropTag[i]);
- }
-
-
- hr = hrSuccess;
- for (i = 0; i < cPropNames; ++i)
- if(lpsPropTagArray->aulPropTag[i] == PROP_TAG(PT_ERROR, 0)) {
- hr = MAPI_W_ERRORS_RETURNED;
- break;
- }
- *lppPropTags = lpsPropTagArray;
- lpsPropTagArray = NULL;
- exit:
- if(lpsPropTagArray)
- ECFreeBuffer(lpsPropTagArray);
- if(lpServerIDs)
- ECFreeBuffer(lpServerIDs);
- return hr;
- }
- HRESULT ECNamedProp::ResolveLocal(MAPINAMEID *lpName, ULONG *ulPropTag)
- {
-
- if (lpName->ulKind != MNID_ID)
- return MAPI_E_NOT_FOUND;
-
- for (size_t i = 0; i < ARRAY_SIZE(sLocalNames); ++i) {
- if(memcmp(&sLocalNames[i].guid,lpName->lpguid,sizeof(GUID))==0 && sLocalNames[i].ulMin <= lpName->Kind.lID && sLocalNames[i].ulMax >= lpName->Kind.lID) {
-
- *ulPropTag = PROP_TAG(PT_UNSPECIFIED, sLocalNames[i].ulMappedId + lpName->Kind.lID - sLocalNames[i].ulMin);
- return hrSuccess;
- }
- }
-
- return MAPI_E_NOT_FOUND;
- }
- HRESULT ECNamedProp::ResolveReverseCache(ULONG ulId, LPGUID lpGuid, ULONG ulFlags, void *lpBase, MAPINAMEID **lppName)
- {
- HRESULT hr = MAPI_E_NOT_FOUND;
-
-
- for (const auto &p : mapNames)
- if (p.second == ulId) {
- if (lpGuid != nullptr)
- assert(memcmp(lpGuid, p.first->lpguid, sizeof(GUID)) == 0);
-
- hr = HrCopyNameId(p.first, lppName, lpBase);
- break;
- }
- return hr;
- }
- HRESULT ECNamedProp::ResolveReverseLocal(ULONG ulId, LPGUID lpGuid, ULONG ulFlags, void *lpBase, MAPINAMEID **lppName)
- {
- MAPINAMEID* lpName = NULL;
-
- if (ulFlags & MAPI_NO_IDS)
- return MAPI_E_NOT_FOUND;
-
- for (size_t i = 0; i < ARRAY_SIZE(sLocalNames); ++i) {
- if((lpGuid == NULL || memcmp(&sLocalNames[i].guid, lpGuid, sizeof(GUID)) == 0) && ulId >= sLocalNames[i].ulMappedId && ulId < sLocalNames[i].ulMappedId + (sLocalNames[i].ulMax - sLocalNames[i].ulMin + 1)) {
-
- auto hr = ECAllocateMore(sizeof(MAPINAMEID), lpBase, reinterpret_cast<void **>(&lpName));
- if (hr != hrSuccess)
- return hr;
- hr = ECAllocateMore(sizeof(GUID), lpBase, reinterpret_cast<void **>(&lpName->lpguid));
- if (hr != hrSuccess)
- return hr;
- lpName->ulKind = MNID_ID;
- memcpy(lpName->lpguid, &sLocalNames[i].guid, sizeof(GUID));
- lpName->Kind.lID = sLocalNames[i].ulMin + (ulId - sLocalNames[i].ulMappedId);
- break;
- }
- }
- if (lpName == NULL)
- return MAPI_E_NOT_FOUND;
- *lppName = lpName;
- return hrSuccess;
- }
- HRESULT ECNamedProp::UpdateCache(ULONG ulId, MAPINAMEID *lpName)
- {
- HRESULT hr = hrSuccess;
- MAPINAMEID* lpNameCopy = NULL;
- if(mapNames.find(lpName) != mapNames.end()) {
-
- hr = MAPI_E_NOT_FOUND;
- goto exit;
- }
- hr = HrCopyNameId(lpName, &lpNameCopy, NULL);
- if(hr != hrSuccess)
- goto exit;
- mapNames[lpNameCopy] = ulId;
- exit:
- if(hr != hrSuccess && lpNameCopy)
- ECFreeBuffer(lpNameCopy);
- return hr;
- }
- HRESULT ECNamedProp::ResolveCache(MAPINAMEID *lpName, ULONG *lpulPropTag)
- {
- std::map<MAPINAMEID *, ULONG, ltmap>::const_iterator iterMap;
- iterMap = mapNames.find(lpName);
- if (iterMap == mapNames.cend())
- return MAPI_E_NOT_FOUND;
- *lpulPropTag = PROP_TAG(PT_UNSPECIFIED, iterMap->second);
- return hrSuccess;
- }
- HRESULT ECNamedProp::HrCopyNameId(LPMAPINAMEID lpSrc, LPMAPINAMEID *lppDst, void *lpBase)
- {
- HRESULT hr = hrSuccess;
- LPMAPINAMEID lpDst = NULL;
- if(lpBase == NULL)
- hr = ECAllocateBuffer(sizeof(MAPINAMEID), (void **) &lpDst);
- else
- hr = ECAllocateMore(sizeof(MAPINAMEID), lpBase, (void **) &lpDst);
- if(hr != hrSuccess)
- goto exit;
- lpDst->ulKind = lpSrc->ulKind;
- if(lpSrc->lpguid) {
- if(lpBase)
- hr = ECAllocateMore(sizeof(GUID), lpBase, (void **) &lpDst->lpguid);
- else
- hr = ECAllocateMore(sizeof(GUID), lpDst, (void **) &lpDst->lpguid);
- if(hr != hrSuccess)
- goto exit;
- memcpy(lpDst->lpguid, lpSrc->lpguid, sizeof(GUID));
- } else {
- lpDst->lpguid = NULL;
- }
- switch(lpSrc->ulKind) {
- case MNID_ID:
- lpDst->Kind.lID = lpSrc->Kind.lID;
- break;
- case MNID_STRING:
- if(lpBase)
- hr = ECAllocateMore(wcslen(lpSrc->Kind.lpwstrName) * sizeof(wchar_t) + sizeof(wchar_t),
- lpBase, reinterpret_cast<void **>(&lpDst->Kind.lpwstrName));
- else
- hr = ECAllocateMore(wcslen(lpSrc->Kind.lpwstrName) * sizeof(wchar_t) + sizeof(wchar_t),
- lpDst, reinterpret_cast<void **>(&lpDst->Kind.lpwstrName));
- if (hr != hrSuccess)
- return hr;
- wcscpy(lpDst->Kind.lpwstrName, lpSrc->Kind.lpwstrName);
- break;
- default:
- hr = MAPI_E_INVALID_TYPE;
- goto exit;
- }
- *lppDst = lpDst;
- exit:
- if(hr != hrSuccess && !lpBase && lpDst)
- ECFreeBuffer(lpDst);
- return hr;
- }
|