12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121 |
- /*
- * 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 <memory>
- #include <new>
- #include <cstdlib>
- #include <cmath> // for pow()
- #include "m4l.mapiutil.h"
- #include "m4l.mapidefs.h"
- #include "m4l.mapix.h"
- #include "m4l.debug.h"
- #include <mapi.h>
- #include <mapix.h>
- #include <mapiutil.h>
- #include <mapidefs.h>
- #include <kopano/ECDebug.h>
- #include <kopano/ECTags.h>
- #include <kopano/memory.hpp>
- #include <kopano/stringutil.h>
- #include <kopano/Util.h>
- #include "ECMemStream.h"
- #include <kopano/mapiguidext.h>
- #include "rtf.h"
- #include <kopano/charset/convstring.h>
- using namespace KCHL;
- ULONG __stdcall UlRelease(LPVOID lpUnknown)
- {
- TRACE_MAPILIB(TRACE_ENTRY, "UlRelease", "");
- if(lpUnknown)
- return ((IUnknown *)lpUnknown)->Release();
- else
- return 0;
- }
- void __stdcall DeinitMapiUtil(void)
- {
- TRACE_MAPILIB(TRACE_ENTRY, "DeInitMAPIUtil", "");
- TRACE_MAPILIB(TRACE_RETURN, "DeInitMAPIUtil", "");
- }
- SPropValue * __stdcall PpropFindProp(SPropValue *lpPropArray, ULONG cValues,
- ULONG ulPropTag)
- {
- return const_cast<SPropValue *>(PCpropFindProp(lpPropArray, cValues, ulPropTag));
- }
- const SPropValue * __stdcall PCpropFindProp(const SPropValue *lpPropArray,
- ULONG cValues, ULONG ulPropTag)
- {
- TRACE_MAPILIB1(TRACE_ENTRY, "PpropFindProp", "%08x", ulPropTag);
- const SPropValue *lpValue = NULL;
- if (lpPropArray == NULL)
- goto exit;
- for (ULONG i = 0; i<cValues; ++i) {
- if ((lpPropArray[i].ulPropTag == ulPropTag) ||
- (PROP_TYPE(ulPropTag) == PT_UNSPECIFIED && PROP_ID(lpPropArray[i].ulPropTag) == PROP_ID(ulPropTag))) {
- lpValue = &lpPropArray[i];
- break;
- }
- }
- exit:
- TRACE_MAPILIB2(TRACE_RETURN, "PpropFindProp", "%s: %08x", (lpValue ? "SUCCESS" : "FAILED"), ulPropTag);
- return lpValue;
- }
- // Find a property with a given property Id in a property array. NOTE: doesn't care about prop type!
- LPSPropValue __stdcall LpValFindProp(ULONG ulPropTag, ULONG cValues, LPSPropValue lpProps)
- {
- TRACE_MAPILIB1(TRACE_ENTRY, "LpValFindProp", "%08x", ulPropTag);
- LPSPropValue lpValue = NULL;
- if (lpProps == NULL)
- goto exit;
- for (ULONG i = 0; i < cValues; ++i) {
- if(PROP_ID(lpProps[i].ulPropTag) == PROP_ID(ulPropTag)) {
- lpValue = &lpProps[i];
- break;
- }
- }
- exit:
- TRACE_MAPILIB2(TRACE_RETURN, "LpValFindProp", "%s: %08x", (lpValue ? "SUCCESS" : "FAILED"), ulPropTag);
- return lpValue;
- }
- SCODE __stdcall PropCopyMore( LPSPropValue lpSPropValueDest, LPSPropValue lpSPropValueSrc, ALLOCATEMORE * lpfAllocMore, LPVOID lpvObject)
- {
- HRESULT hr = hrSuccess;
- TRACE_MAPILIB1(TRACE_ENTRY, "PropCopyMore", "%s", PropNameFromPropArray(1, lpSPropValueSrc).c_str());
- hr = Util::HrCopyProperty(lpSPropValueDest, lpSPropValueSrc, lpvObject, lpfAllocMore);
- TRACE_MAPILIB2(TRACE_RETURN, "PropCopyMore", "%s: %s", GetMAPIErrorDescription(hr).c_str(), PropNameFromPropArray(1, lpSPropValueDest).c_str());
- return hr;
- }
- HRESULT __stdcall WrapStoreEntryID(ULONG ulFlags, LPTSTR lpszDLLName, ULONG cbOrigEntry,
- LPENTRYID lpOrigEntry, ULONG *lpcbWrappedEntry, LPENTRYID *lppWrappedEntry) {
- TRACE_MAPILIB(TRACE_ENTRY, "WrapStoreEntryID", "");
- HRESULT hr = hrSuccess;
- ULONG cbDLLName = 0;
- ULONG cbPad = 0;
- std::string strDLLName = convstring(lpszDLLName, ulFlags);
- if (lpszDLLName == NULL || lpOrigEntry == NULL || lpcbWrappedEntry == NULL || lppWrappedEntry == NULL || cbOrigEntry <= (4+sizeof(GUID)) ) {
- hr = MAPI_E_INVALID_PARAMETER;
- goto exit;
- }
- // The format of a wrapped entryid is:
- // - flags (4)
- // - static guid (16) (see m4l.common.h)
- // - 2 bytes unknown data
- // - then the dll name + termination char + padding to 32 bits
- // - then the entry id
- cbDLLName = strDLLName.size() + 1;
- cbPad = (4 - ((4+sizeof(GUID)+2+cbDLLName) & 0x03)) & 0x03;
- *lpcbWrappedEntry = 4+sizeof(GUID)+2+cbDLLName+cbPad+cbOrigEntry;
- hr = MAPIAllocateBuffer(*lpcbWrappedEntry, (void**)lppWrappedEntry);
- if (hr != hrSuccess)
- goto exit;
-
- memset(*lppWrappedEntry, 0, *lpcbWrappedEntry);
- memcpy((*lppWrappedEntry)->ab, &muidStoreWrap, sizeof(GUID));
- strcpy(((char*)*lppWrappedEntry)+4+sizeof(GUID)+2, strDLLName.c_str());
- memcpy(((BYTE*)*lppWrappedEntry)+4+sizeof(GUID)+2+cbDLLName+cbPad, lpOrigEntry, cbOrigEntry);
-
- exit:
- TRACE_MAPILIB1(TRACE_ENTRY, "WrapStoreEntryID", "0x%08x", hr);
- return hr;
- }
- void __stdcall FreeProws(LPSRowSet lpRows) {
- TRACE_MAPILIB(TRACE_ENTRY, "FreeProws", "");
- unsigned int i;
-
- if(lpRows == NULL)
- return;
- for (i = 0; i < lpRows->cRows; ++i)
- MAPIFreeBuffer(lpRows->aRow[i].lpProps);
- MAPIFreeBuffer(lpRows);
- TRACE_MAPILIB(TRACE_RETURN, "FreeProws", "");
- }
- void __stdcall FreePadrlist(LPADRLIST lpAdrlist) {
- TRACE_MAPILIB(TRACE_ENTRY, "FreePadrlist", "");
- // it's the same in mapi4linux
- FreeProws((LPSRowSet) lpAdrlist);
- TRACE_MAPILIB(TRACE_RETURN, "FreePadrlist", "");
- }
- // M4LMAPIAdviseSink is in mapidefs.cpp
- HRESULT __stdcall HrAllocAdviseSink(LPNOTIFCALLBACK lpFunction, void *lpContext, LPMAPIADVISESINK *lppSink)
- {
- TRACE_MAPILIB(TRACE_ENTRY, "HrAllocAdviseSink", "");
- HRESULT hr = hrSuccess;
- IMAPIAdviseSink *lpSink = NULL;
- lpSink = new(std::nothrow) M4LMAPIAdviseSink(lpFunction, lpContext);
- if (!lpSink) {
- hr = MAPI_E_NOT_ENOUGH_MEMORY;
- goto exit;
- }
- lpSink->AddRef();
- *lppSink = lpSink;
- exit:
- TRACE_MAPILIB1(TRACE_RETURN, "HrAllocAdviseSink", "0x%08x", hr);
- return hr;
- }
- // Linux always has multithreaded advise sinks
- HRESULT __stdcall HrThisThreadAdviseSink(LPMAPIADVISESINK lpAdviseSink, LPMAPIADVISESINK *lppAdviseSink) {
- TRACE_MAPILIB(TRACE_ENTRY, "HrThisThreadAdviseSink", "");
- *lppAdviseSink = lpAdviseSink;
- lpAdviseSink->AddRef();
- TRACE_MAPILIB1(TRACE_RETURN, "HrThisThreadAdviseSink", "0x%08x", hrSuccess);
- return hrSuccess;
- }
- // rtf funcions
- // This is called when a user calls Commit() on a wrapped (uncompressed) RTF Stream
- static HRESULT RTFCommitFunc(IStream *lpUncompressedStream, void *lpData)
- {
- HRESULT hr = hrSuccess;
- auto lpCompressedStream = static_cast<IStream *>(lpData);
- STATSTG sStatStg;
- std::unique_ptr<char[]> lpUncompressed;
- char *lpReadPtr = NULL;
- ULONG ulRead = 0;
- ULONG ulWritten = 0;
- unsigned int ulCompressedSize;
- char *lpCompressed = NULL;
- ULARGE_INTEGER zero = {{0,0}};
- LARGE_INTEGER front = {{0,0}};
- hr = lpUncompressedStream->Stat(&sStatStg, STATFLAG_NONAME);
- if(hr != hrSuccess)
- goto exit;
- lpUncompressed.reset(new(std::nothrow) char[sStatStg.cbSize.LowPart]);
- if(lpUncompressed == NULL) {
- hr = MAPI_E_NOT_ENOUGH_MEMORY;
- goto exit;
- }
- lpReadPtr = lpUncompressed.get();
- while(1) {
- hr = lpUncompressedStream->Read(lpReadPtr, 1024, &ulRead);
- if(hr != hrSuccess || ulRead == 0)
- break;
- lpReadPtr += ulRead;
- }
- // We now have the complete uncompressed data in lpUncompressed
- if (rtf_compress(&lpCompressed, &ulCompressedSize, lpUncompressed.get(), sStatStg.cbSize.LowPart) != 0) {
- hr = MAPI_E_CALL_FAILED;
- goto exit;
- }
- // lpCompressed is the compressed RTF stream, write it to lpCompressedStream
- lpReadPtr = lpCompressed;
- lpCompressedStream->SetSize(zero);
- lpCompressedStream->Seek(front,SEEK_SET,NULL);
- while(ulCompressedSize) {
- hr = lpCompressedStream->Write(lpReadPtr, ulCompressedSize > 16384 ? 16384 : ulCompressedSize, &ulWritten);
- if(hr != hrSuccess)
- break;
- lpReadPtr += ulWritten;
- ulCompressedSize -= ulWritten;
- }
- exit:
- free(lpCompressed);
- return hr;
- }
- HRESULT __stdcall WrapCompressedRTFStream(LPSTREAM lpCompressedRTFStream, ULONG ulFlags, LPSTREAM * lppUncompressedStream) {
- // This functions doesn't really wrap the stream, but decodes the
- // compressed stream, and writes the uncompressed data to the
- // Uncompressed stream. This is usually not a problem, as the whole
- // stream is read out in one go anyway.
- //
- // Also, not much streaming is done on the input data, the function
- // therefore is quite memory-hungry.
- STATSTG sStatStg;
- HRESULT hr = hrSuccess;
- std::unique_ptr<char[]> lpCompressed, lpUncompressed;
- char *lpReadPtr = NULL;
- ULONG ulRead = 0;
- object_ptr<ECMemStream> lpUncompressedStream;
- ULONG ulUncompressedLen = 0;
-
- hr = lpCompressedRTFStream->Stat(&sStatStg, STATFLAG_NONAME);
- if(hr != hrSuccess)
- return hr;
- if(sStatStg.cbSize.LowPart > 0) {
- lpCompressed.reset(new(std::nothrow) char[sStatStg.cbSize.LowPart]);
- if (lpCompressed == nullptr)
- return MAPI_E_NOT_ENOUGH_MEMORY;
- // Read in the whole compressed data buffer
- lpReadPtr = lpCompressed.get();
- while(1) {
- hr = lpCompressedRTFStream->Read(lpReadPtr, 1024, &ulRead);
- if(hr != hrSuccess)
- return hr;
- if(ulRead == 0)
- break;
-
- lpReadPtr += ulRead;
- }
- ulUncompressedLen = rtf_get_uncompressed_length(lpCompressed.get(), sStatStg.cbSize.LowPart);
- lpUncompressed.reset(new(std::nothrow) char[ulUncompressedLen]);
- if (lpUncompressed == nullptr)
- return MAPI_E_NOT_ENOUGH_MEMORY;
- if (rtf_decompress(lpUncompressed.get(), lpCompressed.get(), sStatStg.cbSize.LowPart) != 0)
- return MAPI_E_INVALID_PARAMETER;
- // We now have the uncompressed data, create a stream and write the uncompressed data into it
- }
-
- hr = ECMemStream::Create(lpUncompressed.get(), ulUncompressedLen,
- STGM_WRITE | STGM_TRANSACTED, RTFCommitFunc,
- nullptr /* no cleanup */,
- lpCompressedRTFStream, &~lpUncompressedStream);
- if(hr != hrSuccess)
- return hr;
- return lpUncompressedStream->QueryInterface(IID_IStream,
- reinterpret_cast<void **>(lppUncompressedStream));
- }
- // RTFSync is not much use even in windows, so we don't implement it
- HRESULT __stdcall RTFSync(LPMESSAGE lpMessage, ULONG ulFlags, BOOL * lpfMessageUpdated) {
- TRACE_MAPILIB(TRACE_ENTRY, "RTFSync", "");
- HRESULT hr = MAPI_E_NO_SUPPORT;
- TRACE_MAPILIB1(TRACE_RETURN, "RTFSync", "0x%08x", hr);
- return hr;
- }
- //--- php-ext used functions
- HRESULT __stdcall HrQueryAllRows(LPMAPITABLE lpTable,
- const SPropTagArray *lpPropTags, LPSRestriction lpRestriction,
- const SSortOrderSet *lpSortOrderSet, LONG crowsMax, LPSRowSet *lppRows)
- {
- TRACE_MAPILIB1(TRACE_ENTRY, "HrQueryAllRows", "%s", PropNameFromPropTagArray(lpPropTags).c_str());
- HRESULT hr = hrSuccess;
- hr = lpTable->SeekRow(BOOKMARK_BEGINNING, 0, NULL);
- if (hr != hrSuccess)
- goto exit;
- if (lpPropTags) {
- hr = lpTable->SetColumns(lpPropTags, TBL_BATCH);
- if (hr != hrSuccess)
- goto exit;
- }
- if (lpRestriction) {
- hr = lpTable->Restrict(lpRestriction, TBL_BATCH);
- if (hr != hrSuccess)
- goto exit;
- }
- if (lpSortOrderSet) {
- hr = lpTable->SortTable(lpSortOrderSet, TBL_BATCH);
- if (hr != hrSuccess)
- goto exit;
- }
- if (crowsMax == 0)
- crowsMax = 0x7FFFFFFF;
- hr = lpTable->QueryRows(crowsMax, 0, lppRows);
- exit:
- TRACE_MAPILIB1(TRACE_RETURN, "HrQueryAllRows", "0x%08x", hr);
- return hr;
- }
- HRESULT __stdcall HrGetOneProp(IMAPIProp *lpProp, ULONG ulPropTag, LPSPropValue *lppPropVal) {
- TRACE_MAPILIB1(TRACE_ENTRY, "HrGetOneProp", "%08x", ulPropTag);
- HRESULT hr = hrSuccess;
- SizedSPropTagArray(1, sPropTag) = { 1, { ulPropTag } };
- ULONG cValues = 0;
- memory_ptr<SPropValue> lpPropVal;
- hr = lpProp->GetProps(sPropTag, 0, &cValues, &~lpPropVal);
- if(HR_FAILED(hr))
- goto exit;
-
- if(cValues != 1 || lpPropVal->ulPropTag != ulPropTag) {
- hr = MAPI_E_NOT_FOUND;
- goto exit;
- }
- *lppPropVal = lpPropVal.release();
- exit:
- TRACE_MAPILIB1(TRACE_RETURN, "HrGetOneProp", "0x%08x", hr);
- return hr;
- }
- HRESULT __stdcall HrSetOneProp(LPMAPIPROP lpMapiProp, const SPropValue *lpProp)
- {
- TRACE_MAPILIB1(TRACE_ENTRY, "HrSetOneProp", "%s", PropNameFromPropArray(1, lpProp).c_str());
- HRESULT hr = hrSuccess;
- hr = lpMapiProp->SetProps(1, lpProp, NULL);
- // convert ProblemArray into HRESULT error?
- TRACE_MAPILIB1(TRACE_RETURN, "HrSetOneProp", "0x%08x", hr);
- return hr;
- }
- BOOL __stdcall FPropExists(LPMAPIPROP lpMapiProp, ULONG ulPropTag)
- {
- TRACE_MAPILIB1(TRACE_ENTRY, "FPropExists", "%08x", ulPropTag);
- HRESULT hr = hrSuccess;
- memory_ptr<SPropValue> lpPropVal = NULL;
- hr = HrGetOneProp(lpMapiProp, ulPropTag, &~lpPropVal);
- TRACE_MAPILIB1(TRACE_RETURN, "FPropExists", "0x%08x", hr);
- return (hr == hrSuccess);
- }
- /* Actually not part of MAPI */
- HRESULT __stdcall CreateStreamOnHGlobal(void *hGlobal, BOOL fDeleteOnRelease, IStream **lppStream)
- {
- HRESULT hr = hrSuccess;
- object_ptr<ECMemStream> lpStream;
-
- if (hGlobal != nullptr || fDeleteOnRelease != TRUE)
- return MAPI_E_INVALID_PARAMETER;
- hr = ECMemStream::Create(nullptr, 0, STGM_WRITE, nullptr, nullptr, nullptr, &~lpStream); // NULLs: no callbacks and custom data
- if(hr != hrSuccess)
- return hr;
- return lpStream->QueryInterface(IID_IStream, reinterpret_cast<void **>(lppStream));
- }
- HRESULT __stdcall OpenStreamOnFile(LPALLOCATEBUFFER lpAllocateBuffer, LPFREEBUFFER lpFreeBuffer, ULONG ulFlags,
- LPTSTR lpszFileName, LPTSTR lpszPrefix, LPSTREAM *lppStream)
- {
- TRACE_MAPILIB(TRACE_ENTRY, "OpenStreamOnFile", "");
- HRESULT hr = MAPI_E_NOT_FOUND;
- TRACE_MAPILIB1(TRACE_RETURN, "OpenStreamOnFile", "0x%08x", hr);
- return hr;
- }
- HRESULT __stdcall BuildDisplayTable(LPALLOCATEBUFFER lpAllocateBuffer, LPALLOCATEMORE lpAllocateMore,
- LPFREEBUFFER lpFreeBuffer, LPMALLOC lpMalloc,
- HINSTANCE hInstance, UINT cPages,
- LPDTPAGE lpPage, ULONG ulFlags,
- LPMAPITABLE * lppTable, LPTABLEDATA * lppTblData)
- {
- TRACE_MAPILIB(TRACE_ENTRY, "BuildDisplayTable", "");
- HRESULT hr = MAPI_E_NO_SUPPORT;
- TRACE_MAPILIB1(TRACE_RETURN, "BuildDisplayTable", "0x%08x", hr);
- return hr;
- }
- #pragma pack(push, 1)
- struct CONVERSATION_INDEX {
- char ulReserved1;
- char ftTime[5];
- GUID guid;
- };
- #pragma pack(pop)
- HRESULT __stdcall ScCreateConversationIndex (ULONG cbParent,
- LPBYTE lpbParent,
- ULONG *lpcbConvIndex,
- LPBYTE *lppbConvIndex)
- {
- HRESULT hr;
- TRACE_MAPILIB1(TRACE_ENTRY, "ScCreateConversationIndex", "%s", lpbParent ? bin2hex(cbParent, lpbParent).c_str() : "<null>");
- ULONG cbConvIndex = 0;
- BYTE *pbConvIndex = NULL;
- if(cbParent == 0) {
- FILETIME ft;
- if ((hr = MAPIAllocateBuffer(sizeof(CONVERSATION_INDEX), (void **)&pbConvIndex)) != hrSuccess)
- return hr;
- cbConvIndex = sizeof(CONVERSATION_INDEX);
- auto ci = reinterpret_cast<CONVERSATION_INDEX *>(pbConvIndex);
- ci->ulReserved1 = 1;
- UnixTimeToFileTime(time(NULL), &ft);
- memcpy(ci->ftTime, &ft, 5);
- CoCreateGuid(&ci->guid);
- } else {
- FILETIME now;
- FILETIME parent;
- FILETIME diff;
- if ((hr = MAPIAllocateBuffer(cbParent + 5, (void **)&pbConvIndex)) != hrSuccess)
- return hr;
- cbConvIndex = cbParent+5;
- memcpy(pbConvIndex, lpbParent, cbParent);
- memset(&parent, 0, sizeof(FILETIME));
- memcpy(&parent, ((CONVERSATION_INDEX*)lpbParent)->ftTime, 5);
- UnixTimeToFileTime(time(NULL), &now);
- diff = FtSubFt(now, parent);
- memcpy(pbConvIndex + sizeof(CONVERSATION_INDEX), &diff, 5);
- }
- *lppbConvIndex = pbConvIndex;
- *lpcbConvIndex = cbConvIndex;
- TRACE_MAPILIB1(TRACE_RETURN, "ScCreateConversationIndex", "%s", bin2hex(cbConvIndex, pbConvIndex).c_str());
- return hrSuccess;
- }
- SCODE __stdcall ScDupPropset( int cprop, LPSPropValue rgprop, LPALLOCATEBUFFER lpAllocateBuffer, LPSPropValue *prgprop )
- {
- TRACE_MAPILIB(TRACE_ENTRY, "ScDupPropset", "");
- HRESULT hr = hrSuccess;
- LPSPropValue lpDst = NULL;
- ULONG ulSize = 0;
- hr = ScCountProps(cprop, rgprop, &ulSize);
- if(hr != hrSuccess)
- goto exit;
- hr = lpAllocateBuffer(ulSize, (void **)&lpDst);
- if(hr != hrSuccess)
- goto exit;
- hr = ScCopyProps(cprop, rgprop, lpDst, NULL);
- if(hr != hrSuccess)
- goto exit;
- *prgprop = lpDst;
- exit:
- TRACE_MAPILIB1(TRACE_RETURN, "ScDupPropset", "0x%08x", hr);
- return hr;
- }
- SCODE __stdcall ScRelocProps(int cprop, LPSPropValue rgprop, LPVOID pvBaseOld, LPVOID pvBaseNew, ULONG *pcb)
- {
- TRACE_MAPILIB(TRACE_ENTRY, "ScRelocProps", "");
- TRACE_MAPILIB1(TRACE_RETURN, "ScRelocProps", "0x%08x", S_FALSE);
- return S_FALSE;
- }
- ULONG __stdcall CbOfEncoded(LPCSTR lpszEnc)
- {
- TRACE_MAPILIB(TRACE_ENTRY, "CbOfEncoded", "");
- ULONG ulRet = 0;
- if (lpszEnc)
- ulRet = (((strlen(lpszEnc) | 3) >> 2) + 1) * 3;
- TRACE_MAPILIB(TRACE_RETURN, "CbOfEncoded", "");
- return ulRet;
- }
- ULONG __stdcall CchOfEncoding(LPCSTR lpszEnd)
- {
- TRACE_MAPILIB(TRACE_ENTRY, "CchOfEncoding", "");
- TRACE_MAPILIB(TRACE_RETURN, "CchOfEncoding", "");
- return 0;
- }
- SCODE __stdcall ScCopyProps( int cprop, LPSPropValue rgprop, LPVOID pvDst, ULONG *pcb )
- {
- TRACE_MAPILIB1(TRACE_ENTRY, "ScCopyProps", "%s", PropNameFromPropArray(cprop, rgprop).c_str());
- auto lpHeap = static_cast<BYTE *>(pvDst) + sizeof(SPropValue) * cprop;
- LPSPropValue lpProp = (LPSPropValue)pvDst;
- for (int i = 0 ; i < cprop; ++i) {
- lpProp[i] = rgprop[i];
- switch(PROP_TYPE(rgprop[i].ulPropTag)) {
- case PT_ERROR:
- lpProp[i].Value.err = rgprop[i].Value.err;
- break;
- case PT_NULL:
- case PT_OBJECT:
- lpProp[i].Value.x = rgprop[i].Value.x;
- break;
- case PT_BOOLEAN:
- lpProp[i].Value.b = rgprop[i].Value.b;
- break;
- case PT_SHORT:
- lpProp[i].Value.i = rgprop[i].Value.i;
- break;
- case PT_MV_SHORT:
- for (ULONG j = 0; j < rgprop[i].Value.MVi.cValues; ++j)
- lpProp[i].Value.MVi.lpi[j] = rgprop[i].Value.MVi.lpi[j];
- break;
- case PT_LONG:
- lpProp[i].Value.l = rgprop[i].Value.l;
- break;
- case PT_MV_LONG:
- for (ULONG j = 0; j < rgprop[i].Value.MVl.cValues; ++j)
- lpProp[i].Value.MVl.lpl[j] = rgprop[i].Value.MVl.lpl[j];
- break;
- case PT_LONGLONG:
- memcpy(&lpProp[i].Value.li, &rgprop[i].Value.li, sizeof(rgprop[i].Value.li));
- break;
- case PT_MV_LONGLONG:
- for (ULONG j = 0; j < rgprop[i].Value.MVli.cValues; ++j)
- memcpy(&lpProp[i].Value.MVli.lpli[j], &rgprop[i].Value.MVli.lpli[j], sizeof(rgprop[i].Value.MVli.lpli[j]));
- break;
- case PT_FLOAT:
- lpProp[i].Value.flt = rgprop[i].Value.flt;
- break;
- case PT_MV_FLOAT:
- for (ULONG j = 0; j < rgprop[i].Value.MVflt.cValues; ++j)
- lpProp[i].Value.MVflt.lpflt[j] = rgprop[i].Value.MVflt.lpflt[j];
- break;
- case PT_DOUBLE:
- lpProp[i].Value.dbl = rgprop[i].Value.dbl;
- break;
- case PT_MV_DOUBLE:
- for (ULONG j = 0; j < rgprop[i].Value.MVdbl.cValues; ++j)
- lpProp[i].Value.MVdbl.lpdbl[j] = rgprop[i].Value.MVdbl.lpdbl[j];
- break;
- case PT_CURRENCY:
- memcpy(&lpProp[i].Value.cur, &rgprop[i].Value.cur, sizeof(rgprop[i].Value.cur));
- break;
- case PT_MV_CURRENCY:
- for (ULONG j = 0; j < rgprop[i].Value.MVcur.cValues; ++j)
- memcpy(&lpProp[i].Value.MVcur.lpcur[j], &rgprop[i].Value.MVcur.lpcur[j], sizeof(rgprop[i].Value.MVcur.lpcur[j]));
- break;
- case PT_SYSTIME:
- memcpy(&lpProp[i].Value.ft, &rgprop[i].Value.ft, sizeof(rgprop[i].Value.ft));
- break;
- case PT_MV_SYSTIME:
- for (ULONG j = 0; j < rgprop[i].Value.MVft.cValues; ++j)
- memcpy(&lpProp[i].Value.MVft.lpft[j], &rgprop[i].Value.MVft.lpft[j], sizeof(rgprop[i].Value.MVft.lpft[j]));
- break;
- case PT_APPTIME:
- lpProp[i].Value.at = rgprop[i].Value.at;
- break;
- case PT_MV_APPTIME:
- for (ULONG j = 0; j < rgprop[i].Value.MVat.cValues; ++j)
- lpProp[i].Value.MVat.lpat[j] = rgprop[i].Value.MVat.lpat[j];
- break;
- case PT_CLSID:
- memcpy(lpHeap, rgprop[i].Value.lpguid, sizeof(GUID));
- lpProp[i].Value.lpguid = (LPGUID)lpHeap;
- lpHeap += sizeof(GUID);
- break;
- case PT_MV_CLSID:
- memcpy(lpHeap, rgprop[i].Value.MVguid.lpguid, sizeof(GUID) * rgprop[i].Value.MVguid.cValues);
- lpProp[i].Value.MVguid.lpguid = (LPGUID)lpHeap;
- lpHeap += sizeof(GUID) * rgprop[i].Value.MVguid.cValues;
- break;
- #define COPY_STRING8(__heap, __target, __source) \
- { \
- strcpy((char *)(__heap), (__source)); \
- (__target) = (char *)(__heap); \
- (__heap) += strlen((__source)) + 1; \
- }
- case PT_STRING8:
- COPY_STRING8(lpHeap, lpProp[i].Value.lpszA, rgprop[i].Value.lpszA);
- break;
- case PT_MV_STRING8:
- for (ULONG j = 0; j < rgprop[i].Value.MVszA.cValues; ++j)
- COPY_STRING8(lpHeap, lpProp[i].Value.MVszA.lppszA[j], rgprop[i].Value.MVszA.lppszA[j]);
- break;
- #define COPY_BINARY(__heap, __target, __source) \
- { \
- memcpy((__heap), (__source).lpb, (__source).cb);\
- (__target).lpb = (__heap); \
- (__target).cb = (__source).cb; \
- (__heap) += (__source).cb; \
- }
- case PT_BINARY:
- COPY_BINARY(lpHeap, lpProp[i].Value.bin, rgprop[i].Value.bin);
- break;
- case PT_MV_BINARY:
- for (ULONG j = 0; j < rgprop[i].Value.MVbin.cValues; ++j)
- COPY_BINARY(lpHeap, lpProp[i].Value.MVbin.lpbin[j], rgprop[i].Value.MVbin.lpbin[j]);
- break;
- #define COPY_UNICODE(__heap, __target, __source) \
- { \
- (__target) = lstrcpyW((WCHAR *)(__heap), (__source)); \
- (__heap) += (lstrlenW((__source)) + 1) * sizeof(WCHAR); \
- }
- case PT_UNICODE:
- COPY_UNICODE(lpHeap, lpProp[i].Value.lpszW, rgprop[i].Value.lpszW);
- break;
- case PT_MV_UNICODE:
- for (ULONG j = 0; j < rgprop[i].Value.MVszW.cValues; ++j)
- COPY_UNICODE(lpHeap, lpProp[i].Value.MVszW.lppszW[j], rgprop[i].Value.MVszW.lppszW[j]);
- break;
- default:
- break;
- }
- }
- if(pcb)
- *pcb = lpHeap - (BYTE *)pvDst;
- TRACE_MAPILIB1(TRACE_RETURN, "ScCopyProps", "%s", PropNameFromPropArray(cprop, (LPSPropValue)pvDst).c_str());
- return S_OK;
- }
- SCODE __stdcall ScCountProps(int cValues, LPSPropValue lpPropArray, ULONG *lpcb)
- {
- SCODE sc = S_OK;
- ULONG ulSize = 0;
- for (int i = 0; i < cValues; ++i) {
- ulSize += sizeof(SPropValue);
- switch(PROP_TYPE(lpPropArray[i].ulPropTag)) {
- case PROP_ID_NULL:
- case PROP_ID_INVALID:
- sc = MAPI_E_INVALID_PARAMETER;
- break;
- case PT_STRING8:
- ulSize += strlen(lpPropArray[i].Value.lpszA)+1;
- break;
- case PT_MV_STRING8:
- ulSize += sizeof(LPTSTR) * lpPropArray[i].Value.MVszA.cValues;
- for (unsigned int j = 0; j < lpPropArray[i].Value.MVszA.cValues; ++j)
- ulSize += strlen(lpPropArray[i].Value.MVszA.lppszA[j])+1;
- break;
- case PT_BINARY:
- ulSize += lpPropArray[i].Value.bin.cb;
- break;
- case PT_MV_BINARY:
- ulSize += sizeof(SBinary) * lpPropArray[i].Value.MVbin.cValues;
- for (unsigned int j = 0; j < lpPropArray[i].Value.MVbin.cValues; ++j)
- ulSize += lpPropArray[i].Value.MVbin.lpbin[j].cb;
- break;
- case PT_UNICODE:
- ulSize += (lstrlenW(lpPropArray[i].Value.lpszW) + 1) * sizeof(WCHAR);
- break;
- case PT_MV_UNICODE:
- ulSize += sizeof(LPWSTR) * lpPropArray[i].Value.MVszW.cValues;
- for (unsigned int j = 0; j < lpPropArray[i].Value.MVszW.cValues; ++j)
- ulSize += (lstrlenW(lpPropArray[i].Value.MVszW.lppszW[j]) + 1) * sizeof(WCHAR);
- break;
- case PT_CLSID:
- ulSize += sizeof(GUID);
- break;
- case PT_MV_CLSID:
- ulSize += (lpPropArray[i].Value.MVguid.cValues * sizeof(GUID));
- break;
- default:
- break;
- }
- }
- if (lpcb)
- *lpcb = ulSize;
- TRACE_MAPILIB1(TRACE_RETURN, "ScCountProps", "%d", ulSize);
- return sc;
- }
- SCODE __stdcall ScInitMapiUtil(ULONG ulFlags)
- {
- TRACE_MAPILIB(TRACE_ENTRY, "ScInitMAPIUtil", "");
- TRACE_MAPILIB1(TRACE_RETURN, "ScInitMAPIUtil", "0x%08x", S_OK);
- return S_OK;
- }
- BOOL __stdcall FBinFromHex(LPTSTR sz, LPBYTE pb)
- {
- TRACE_MAPILIB1(TRACE_ENTRY, "FBinFromHex", "%s", sz);
- ULONG len;
- memory_ptr<BYTE> lpBin;
- Util::hex2bin((char *)sz, strlen((char *)sz), &len, &~lpBin);
- memcpy(pb, lpBin, len);
- TRACE_MAPILIB1(TRACE_RETURN, "FBinFromHex", "%s", sz);
- return true;
- }
- void __stdcall HexFromBin(LPBYTE pb, int cb, LPTSTR sz)
- {
- std::string hex = bin2hex(cb, pb);
- TRACE_MAPILIB1(TRACE_ENTRY, "HexFromBin", "%s", hex.c_str());
- strcpy((char *)sz, hex.c_str());
- TRACE_MAPILIB1(TRACE_RETURN, "HexFromBin", "%s", sz);
- }
- // @todo according to MSDN, this function also supports Unicode strings
- // but I don't see how that's easy possible
- LPTSTR __stdcall SzFindCh(LPCTSTR lpsz, USHORT ch)
- {
- TRACE_MAPILIB(TRACE_ENTRY, "SzFindCh", "");
- LPTSTR lpszFind = (LPTSTR)strchr((char*)lpsz, ch);
- TRACE_MAPILIB(TRACE_RETURN, "SzFindCh", "");
- return lpszFind;
- }
- int __stdcall MNLS_CompareStringW(LCID Locale, DWORD dwCmpFlags, LPCWSTR lpString1, int cchCount1, LPCWSTR lpString2, int cchCount2)
- {
- TRACE_MAPILIB4(TRACE_ENTRY, "MNLS_CompareStringW", "%d %S, %d %S", cchCount1, lpString1, cchCount2, lpString2);
- // FIXME: we're ignoring Locale, dwCmpFlags, cchCount1 and cchCount2
- int ulCmp = wcscmp((LPWSTR)lpString1, (LPWSTR)lpString2);
- TRACE_MAPILIB1(TRACE_RETURN, "MNLS_CompareStringW", "%d", ulCmp);
- return ulCmp;
- }
- int __stdcall MNLS_lstrlenW(LPCWSTR lpString)
- {
- TRACE_MAPILIB1(TRACE_ENTRY, "MNLS_lstrlenW", "%S", lpString);
- int ulLen = lstrlenW(lpString);
- TRACE_MAPILIB2(TRACE_RETURN, "MNLS_lstrlenW", "%S: %d", lpString, ulLen);
- return ulLen;
- }
- int __stdcall MNLS_lstrlen(LPCSTR lpString)
- {
- TRACE_MAPILIB1(TRACE_ENTRY, "MNLS_lstrlen", "%S", lpString);
- int ulLen = lstrlenW((LPCWSTR)lpString);
- TRACE_MAPILIB2(TRACE_RETURN, "MNLS_lstrlen", "%S: %d", lpString, ulLen);
- return ulLen;
- }
- int __stdcall MNLS_lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
- {
- TRACE_MAPILIB2(TRACE_ENTRY, "lstrcmpW", "%S, %S", lpString1, lpString2);
- int ulCmp = lstrcmpW(lpString1, lpString2);
- TRACE_MAPILIB3(TRACE_RETURN, "lstrcmpW", "%S, %S: %d", lpString1, lpString2, ulCmp);
- return ulCmp;
- }
- LPWSTR __stdcall MNLS_lstrcpyW(LPWSTR lpString1, LPCWSTR lpString2)
- {
- TRACE_MAPILIB1(TRACE_ENTRY, "MNLS_lstrcpyW", "%S", lpString2);
- LPWSTR str = lstrcpyW(lpString1, lpString2);
- TRACE_MAPILIB(TRACE_RETURN, "MNLS_lstrcpyW", "");
- return str;
- }
- FILETIME __stdcall FtAddFt( FILETIME Addend1, FILETIME Addend2 )
- {
- TRACE_MAPILIB4(TRACE_ENTRY, "FtAddFt", "(%u,%u) (%u,%u)", Addend1.dwHighDateTime, Addend1.dwLowDateTime, Addend2.dwHighDateTime, Addend2.dwLowDateTime);
- FILETIME ft;
- unsigned long long l = ((unsigned long long)Addend1.dwHighDateTime << 32) + Addend1.dwLowDateTime;
- l += ((unsigned long long)Addend2.dwHighDateTime << 32) + Addend2.dwLowDateTime;
- ft.dwHighDateTime = l >> 32;
- ft.dwLowDateTime = l & 0xffffffff;
- TRACE_MAPILIB2(TRACE_RETURN, "FtAddFt", "(%u,%u)", ft.dwHighDateTime, ft.dwLowDateTime);
- return ft;
- }
- FILETIME __stdcall FtSubFt( FILETIME Minuend, FILETIME Subtrahend )
- {
- TRACE_MAPILIB4(TRACE_ENTRY, "FtSubFt", "(%u,%u) (%u,%u)", Minuend.dwHighDateTime, Minuend.dwLowDateTime, Subtrahend.dwHighDateTime, Subtrahend.dwLowDateTime);
- FILETIME ft;
- unsigned long long l = ((unsigned long long)Minuend.dwHighDateTime << 32) + Minuend.dwLowDateTime;
- l -= ((unsigned long long)Subtrahend.dwHighDateTime << 32) + Subtrahend.dwLowDateTime;
- ft.dwHighDateTime = l >> 32;
- ft.dwLowDateTime = l & 0xffffffff;
- TRACE_MAPILIB2(TRACE_RETURN, "FtSubFt", "(%u,%u)", ft.dwHighDateTime, ft.dwLowDateTime);
- return ft;
- }
- FILETIME __stdcall FtDivFtBogus(FILETIME f, FILETIME f2, DWORD n)
- {
- TRACE_MAPILIB5(TRACE_ENTRY, "FtDivFtBogus", "(%u, %u), (%u, %u), %u", f.dwHighDateTime, f.dwLowDateTime, f2.dwHighDateTime, f2.dwLowDateTime, n);
- // Obtained by experiment: this function does (f*f2) >> (n+64)
- // Since we don't have a good int64 * int64, we do our own addition_plus_bitshift
- // which discards the lowest 64 bits on the fly.
- unsigned long long shift = 0;
- unsigned long long ret = (unsigned long long)f.dwHighDateTime * f2.dwHighDateTime;
- ret += ((unsigned long long)f.dwLowDateTime * f2.dwHighDateTime) >> 32;
- ret += ((unsigned long long)f.dwHighDateTime * f2.dwLowDateTime) >> 32;
- // The remainder may give us a few more, use the top 32 bits of the remainder.
- shift += (((unsigned long long)f.dwLowDateTime * f2.dwHighDateTime) & 0xFFFFFFFF);
- shift += (((unsigned long long)f.dwHighDateTime * f2.dwLowDateTime) & 0xFFFFFFFF);
- shift += ((unsigned long long)f.dwLowDateTime * f2.dwLowDateTime) >> 32;
- ret += shift >> 32;
- ret >>= n;
- FILETIME ft;
- ft.dwHighDateTime = ret >> 32;
- ft.dwLowDateTime = ret & 0xFFFFFFFF;
- TRACE_MAPILIB2(TRACE_RETURN, "FtDivFtBogus", "(%u %u)", ft.dwHighDateTime, ft.dwLowDateTime);
- return ft;
- }
- FILETIME __stdcall FtMulDw(DWORD ftMultiplier, FILETIME ftMultiplicand)
- {
- TRACE_MAPILIB3(TRACE_ENTRY, "FtMulDw", "%d x (%d, %d)", ftMultiplier, ftMultiplicand.dwHighDateTime, ftMultiplicand.dwLowDateTime);
- FILETIME ft;
- unsigned long long t = ((unsigned long long)ftMultiplicand.dwHighDateTime << 32) + (ftMultiplicand.dwLowDateTime & 0xffffffff);
- t *= ftMultiplier;
- ft.dwHighDateTime = t >> 32;
- ft.dwLowDateTime = t & 0xFFFFFFFF;
- TRACE_MAPILIB2(TRACE_RETURN, "FtMulDw", "%(%d, %d)", ft.dwHighDateTime, ft.dwLowDateTime);
- return ft;
- }
- LONG __stdcall MAPIInitIdle( LPVOID lpvReserved )
- {
- TRACE_MAPILIB(TRACE_ENTRY, "MAPIInitIdle", "");
- TRACE_MAPILIB(TRACE_RETURN, "MAPIInitIdle", "");
- return 0;
- }
- void __stdcall MAPIDeinitIdle(void)
- {
- TRACE_MAPILIB(TRACE_ENTRY, "MAPIDeinitIdle", "");
- TRACE_MAPILIB(TRACE_RETURN, "MAPIDeinitIdle", "");
- }
- void __stdcall DeregisterIdleRoutine( FTG ftg )
- {
- TRACE_MAPILIB(TRACE_ENTRY, "DeregisterIdleRoutine", "");
- TRACE_MAPILIB(TRACE_RETURN, "DeregisterIdleRoutine", "");
- }
- void __stdcall EnableIdleRoutine( FTG ftg, BOOL fEnable )
- {
- TRACE_MAPILIB(TRACE_ENTRY, "EnableIdleRoutine", "");
- TRACE_MAPILIB(TRACE_RETURN, "EnableIdleRoutine", "");
- }
- void __stdcall ChangeIdleRoutine(FTG ftg, PFNIDLE pfnIdle, LPVOID pvIdleParam, short priIdle, ULONG csecIdle, USHORT iroIdle, USHORT ircIdle)
- {
- TRACE_MAPILIB(TRACE_ENTRY, "ChangeIdleRoutine", "");
- TRACE_MAPILIB(TRACE_RETURN, "ChangeIdleRoutine", "");
- }
- FTG __stdcall FtgRegisterIdleRoutine(PFNIDLE pfnIdle, LPVOID pvIdleParam, short priIdle, ULONG csecIdle, USHORT iroIdle)
- {
- TRACE_MAPILIB(TRACE_ENTRY, "FtgRegisterIdleRoutine", "");
- FTG f = NULL;
- TRACE_MAPILIB(TRACE_RETURN, "FtgRegisterIdleRoutine", "");
- return f;
- }
- const WORD kwBaseOffset = 0xAC00; // Hangul char range (AC00-D7AF)
- LPWSTR __stdcall EncodeID(ULONG cbEID, LPENTRYID rgbID, LPWSTR *lpWString)
- {
- TRACE_MAPILIB(TRACE_ENTRY, "EncodeID", "");
- ULONG i = 0;
- LPWSTR pwzDst = NULL;
- LPBYTE pbSrc = NULL;
- LPWSTR pwzIDEncoded = NULL;
- // rgbID is the item Entry ID or the attachment ID
- // cbID is the size in bytes of rgbID
- // Allocate memory for pwzIDEncoded
- pwzIDEncoded = new WCHAR[cbEID+1];
- if (!pwzIDEncoded)
- goto exit;
- for (i = 0, pbSrc = (LPBYTE)rgbID, pwzDst = pwzIDEncoded;
- i < cbEID; ++i, ++pbSrc, ++pwzDst)
- *pwzDst = (WCHAR) (*pbSrc + kwBaseOffset);
- // Ensure NULL terminated
- *pwzDst = L'\0';
- exit:
- // pwzIDEncoded now contains the entry ID encoded.
- TRACE_MAPILIB1(TRACE_RETURN, "EncodeID", "%s", (pwzIDEncoded ? "SUCCESS" : "FAILED"));
- return pwzIDEncoded;
- }
- void __stdcall FDecodeID(LPCSTR lpwEncoded, LPENTRYID *lpDecoded, ULONG *cbEncoded)
- {
- TRACE_MAPILIB(TRACE_ENTRY, "FDecodeID", "");
- TRACE_MAPILIB(TRACE_RETURN, "FDecodeID", "");
- // ?
- }
- BOOL __stdcall FBadRglpszA(const TCHAR *, ULONG cStrings)
- {
- TRACE_MAPILIB(TRACE_ENTRY, "FBadRglpszA", "");
- TRACE_MAPILIB(TRACE_RETURN, "FBadRglpszA", "");
- return FALSE;
- }
- BOOL __stdcall FBadRglpszW(const wchar_t *, ULONG cStrings)
- {
- TRACE_MAPILIB(TRACE_ENTRY, "FBadRglpszW", "");
- TRACE_MAPILIB(TRACE_RETURN, "FBadRglpszW", "");
- return FALSE;
- }
- BOOL __stdcall FBadRowSet(const SRowSet *)
- {
- TRACE_MAPILIB(TRACE_ENTRY, "FBadRowSet", "");
- TRACE_MAPILIB(TRACE_RETURN, "FBadRowSet", "");
- return FALSE;
- }
- BOOL __stdcall FBadRglpNameID(LPMAPINAMEID *lppNameId, ULONG cNames)
- {
- TRACE_MAPILIB(TRACE_ENTRY, "FBadRglpNameID", "");
- TRACE_MAPILIB(TRACE_RETURN, "FBadRglpNameID", "");
- return FALSE;
- }
- ULONG __stdcall FBadPropTag(ULONG ulPropTag)
- {
- TRACE_MAPILIB(TRACE_ENTRY, "FBadPropTag", "");
- TRACE_MAPILIB(TRACE_RETURN, "FBadPropTag", "");
- return FALSE;
- }
- ULONG __stdcall FBadRow(const SRow *)
- {
- TRACE_MAPILIB(TRACE_ENTRY, "FBadRow", "");
- TRACE_MAPILIB(TRACE_RETURN, "FBadRow", "");
- return FALSE;
- }
- ULONG __stdcall FBadProp(const SPropValue *)
- {
- TRACE_MAPILIB(TRACE_ENTRY, "FBadProp", "");
- TRACE_MAPILIB(TRACE_RETURN, "FBadProp", "");
- return FALSE;
- }
- ULONG __stdcall FBadColumnSet(const SPropTagArray *lpptaCols)
- {
- TRACE_MAPILIB(TRACE_ENTRY, "FBadColumnSet", "");
- TRACE_MAPILIB(TRACE_RETURN, "FBadColumnSet", "");
- return FALSE;
- }
- ULONG __stdcall FBadSortOrderSet(const SSortOrderSet *)
- {
- TRACE_MAPILIB(TRACE_ENTRY, "FBadSortOrderSet", "");
- TRACE_MAPILIB(TRACE_RETURN, "FBadSortOrderSet", "");
- return FALSE;
- }
- BOOL __stdcall FBadEntryList(const SBinaryArray *lpEntryList)
- {
- TRACE_MAPILIB(TRACE_ENTRY, "FBadEntryList", "");
- TRACE_MAPILIB(TRACE_RETURN, "FBadEntryList", "");
- return FALSE;
- }
- ULONG __stdcall FBadRestriction(const SRestriction *)
- {
- TRACE_MAPILIB(TRACE_ENTRY, "FBadRestriction", "");
- TRACE_MAPILIB(TRACE_RETURN, "FBadRestriction", "");
- return FALSE;
- }
- HRESULT GetConnectionProperties(LPSPropValue lpServer, LPSPropValue lpUsername, ULONG *lpcValues, LPSPropValue *lppProps)
- {
- HRESULT hr = hrSuccess;
- memory_ptr<SPropValue> lpProps;
- char *szUsername;
- std::string strServerPath;
- ULONG cProps = 0;
- if (lpServer == nullptr || lpUsername == nullptr)
- return MAPI_E_UNCONFIGURED;
- hr = MAPIAllocateBuffer(sizeof(SPropValue) * 5, &~lpProps);
- if (hr != hrSuccess)
- return hr;
- if (m4l_lpConfig->GetSetting("server_address")[0])
- strServerPath = (std::string)"https://" + m4l_lpConfig->GetSetting("server_address") + ":" + m4l_lpConfig->GetSetting("ssl_port") + "/";
- else
- strServerPath = (std::string)"https://" + lpServer->Value.lpszA + ":" + m4l_lpConfig->GetSetting("ssl_port") + "/";
- szUsername = lpUsername->Value.lpszA;
- if(strrchr(szUsername, '='))
- szUsername = strrchr(szUsername, '=')+1;
- lpProps[cProps].ulPropTag = PR_EC_PATH;
- if ((hr = MAPIAllocateMore(strServerPath.size() + 1, lpProps, (void**)&lpProps[cProps].Value.lpszA)) != hrSuccess)
- return hr;
- memcpy(lpProps[cProps++].Value.lpszA, strServerPath.c_str(),strServerPath.size() + 1);
- lpProps[cProps].ulPropTag = PR_EC_USERNAME_A;
- if ((hr = MAPIAllocateMore(strlen(szUsername) + 1, lpProps, (void**)&lpProps[cProps].Value.lpszA)) != hrSuccess)
- return hr;
- memcpy(lpProps[cProps++].Value.lpszA, szUsername, strlen(szUsername) + 1);
- lpProps[cProps].ulPropTag = PR_EC_USERPASSWORD_A;
- if ((hr = MAPIAllocateMore(1, lpProps, (void**)&lpProps[cProps].Value.lpszA)) != hrSuccess)
- return hr;
- memcpy(lpProps[cProps++].Value.lpszA, "", 1);
- lpProps[cProps].ulPropTag = PR_EC_SSLKEY_FILE;
- if ((hr = MAPIAllocateMore(strlen(m4l_lpConfig->GetSetting("ssl_key_file")) + 1, lpProps, (void**)&lpProps[cProps].Value.lpszA)) != hrSuccess)
- return hr;
- memcpy(lpProps[cProps++].Value.lpszA, m4l_lpConfig->GetSetting("ssl_key_file"), strlen(m4l_lpConfig->GetSetting("ssl_key_file")) + 1);
- lpProps[cProps].ulPropTag = PR_EC_SSLKEY_PASS;
- if ((hr = MAPIAllocateMore(strlen(m4l_lpConfig->GetSetting("ssl_key_pass")) + 1, lpProps, (void**)&lpProps[cProps].Value.lpszA)) != hrSuccess)
- return hr;
- memcpy(lpProps[cProps++].Value.lpszA, m4l_lpConfig->GetSetting("ssl_key_pass"), strlen(m4l_lpConfig->GetSetting("ssl_key_pass")) + 1);
- *lpcValues = cProps;
- *lppProps = lpProps.release();
- return hrSuccess;
- }
|