ECMsgStore.cpp 127 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154
  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 <kopano/ECInterfaceDefs.h>
  19. #include <kopano/mapi_ptr.h>
  20. #include <kopano/memory.hpp>
  21. #include <mapiutil.h>
  22. #include <edkguid.h>
  23. #include <list>
  24. #include <new>
  25. #include <kopano/ECGetText.h>
  26. #include "Mem.h"
  27. #include "ECMessage.h"
  28. #include "ECMsgStore.h"
  29. #include "ECMAPITable.h"
  30. #include "ECMAPIFolder.h"
  31. #include "ECMAPIProp.h"
  32. #include "WSTransport.h"
  33. #include <kopano/ECTags.h>
  34. #include <kopano/ECGuid.h>
  35. #include <kopano/ECDebug.h>
  36. #include <kopano/ECABEntryID.h>
  37. #include <kopano/mapiext.h>
  38. #include "freebusytags.h"
  39. #include <kopano/CommonUtil.h>
  40. #include "ClientUtil.h"
  41. #include "pcutil.hpp"
  42. #include "WSUtil.h" // used for UnWrapServerClientStoreEntry
  43. #include "ECExportAddressbookChanges.h"
  44. #include "ics.h"
  45. #include "ECExchangeExportChanges.h"
  46. #include "ECChangeAdvisor.h"
  47. #include "ProviderUtil.h"
  48. #include "EntryPoint.h"
  49. #include <kopano/stringutil.h>
  50. #include "ECExchangeModifyTable.h"
  51. #include <kopano/mapi_ptr.h>
  52. typedef KCHL::memory_ptr<char> MAPIStringPtr;
  53. typedef KCHL::object_ptr<WSTransport> WSTransportPtr;
  54. typedef KCHL::object_ptr<ECMessage, IID_ECMessage> ECMessagePtr;
  55. #include <kopano/charset/convstring.h>
  56. using namespace std;
  57. using namespace KCHL;
  58. // FIXME: from libserver/ECMAPI.h
  59. #define MSGFLAG_DELETED ((ULONG) 0x00000400)
  60. static constexpr const SizedSPropTagArray(NUM_RFT_PROPS, sPropRFTColumns) =
  61. {
  62. NUM_RFT_PROPS,
  63. {
  64. PR_ROWID,
  65. PR_INSTANCE_KEY,
  66. PR_ENTRYID,
  67. PR_RECORD_KEY,
  68. PR_MESSAGE_CLASS_A
  69. }
  70. };
  71. /**
  72. * ECMsgStore
  73. **/
  74. ECMsgStore::ECMsgStore(const char *lpszProfname, LPMAPISUP lpSupport,
  75. WSTransport *lpTransport, BOOL fModify, ULONG ulProfileFlags,
  76. BOOL fIsSpooler, BOOL fIsDefaultStore, BOOL bOfflineStore) :
  77. ECMAPIProp(NULL, MAPI_STORE, fModify, NULL, "IMsgStore"),
  78. m_ulProfileFlags(ulProfileFlags), m_fIsSpooler(fIsSpooler),
  79. m_fIsDefaultStore(fIsDefaultStore), m_bOfflineStore(bOfflineStore)
  80. {
  81. TRACE_MAPI(TRACE_ENTRY, "ECMsgStore::ECMsgStore","");
  82. this->lpSupport = lpSupport;
  83. lpSupport->AddRef();
  84. this->lpTransport = lpTransport;
  85. lpTransport->AddRef();
  86. // Add our property handlers
  87. HrAddPropHandlers(PR_ENTRYID, GetPropHandler, DefaultSetPropComputed, (void *)this);
  88. HrAddPropHandlers(PR_RECORD_KEY, GetPropHandler, DefaultSetPropComputed, (void *)this);
  89. HrAddPropHandlers(PR_SEARCH_KEY, GetPropHandler, DefaultSetPropComputed, (void *)this);
  90. HrAddPropHandlers(PR_USER_NAME , GetPropHandler, DefaultSetPropComputed, (void *)this);
  91. HrAddPropHandlers(PR_USER_ENTRYID, GetPropHandler, DefaultSetPropComputed, (void *)this);
  92. HrAddPropHandlers(PR_MAILBOX_OWNER_NAME, GetPropHandler, DefaultSetPropComputed, (void *)this);
  93. HrAddPropHandlers(PR_MAILBOX_OWNER_ENTRYID, GetPropHandler, DefaultSetPropComputed, (void *)this);
  94. HrAddPropHandlers(PR_USER_NAME, GetPropHandler, DefaultSetPropComputed, (void *)this);
  95. HrAddPropHandlers(PR_USER_ENTRYID, GetPropHandler, DefaultSetPropComputed, (void *)this);
  96. HrAddPropHandlers(PR_RECEIVE_FOLDER_SETTINGS, GetPropHandler, DefaultSetPropIgnore, (void*) this, FALSE, FALSE);
  97. HrAddPropHandlers(PR_MESSAGE_SIZE, GetPropHandler, DefaultSetPropComputed, (void*) this, FALSE, FALSE);
  98. HrAddPropHandlers(PR_MESSAGE_SIZE_EXTENDED, GetPropHandler, DefaultSetPropComputed, (void*) this, FALSE, FALSE);
  99. HrAddPropHandlers(PR_QUOTA_WARNING_THRESHOLD, GetPropHandler, DefaultSetPropComputed, (void*) this, FALSE, FALSE);
  100. HrAddPropHandlers(PR_QUOTA_SEND_THRESHOLD, GetPropHandler, DefaultSetPropComputed, (void*) this, FALSE, FALSE);
  101. HrAddPropHandlers(PR_QUOTA_RECEIVE_THRESHOLD, GetPropHandler, DefaultSetPropComputed, (void*) this, FALSE, FALSE);
  102. HrAddPropHandlers(PR_STORE_OFFLINE, GetPropHandler, DefaultSetPropComputed, (void *)this);
  103. // only on admin store? how? .. now checked on server in ECTableManager
  104. HrAddPropHandlers(PR_EC_STATSTABLE_SYSTEM, GetPropHandler, DefaultSetPropComputed, (void*) this, FALSE, TRUE);
  105. HrAddPropHandlers(PR_EC_STATSTABLE_SESSIONS, GetPropHandler, DefaultSetPropComputed, (void*) this, FALSE, TRUE);
  106. HrAddPropHandlers(PR_EC_STATSTABLE_USERS, GetPropHandler, DefaultSetPropComputed, (void*) this, FALSE, TRUE);
  107. HrAddPropHandlers(PR_EC_STATSTABLE_COMPANY, GetPropHandler, DefaultSetPropComputed, (void*) this, FALSE, TRUE);
  108. HrAddPropHandlers(PR_EC_STATSTABLE_SERVERS, GetPropHandler, DefaultSetPropComputed, (void*) this, FALSE, TRUE);
  109. HrAddPropHandlers(PR_TEST_LINE_SPEED, GetPropHandler, DefaultSetPropComputed, (void*) this, FALSE, TRUE);
  110. HrAddPropHandlers(PR_EMSMDB_SECTION_UID, GetPropHandler, DefaultSetPropComputed, (void*) this, FALSE, TRUE);
  111. HrAddPropHandlers(PR_ACL_DATA, GetPropHandler, SetPropHandler, (void*) this, FALSE, TRUE);
  112. // Basically a workaround because we can't pass 'this' in the superclass constructor.
  113. SetProvider(this);
  114. this->lpNamedProp = new ECNamedProp(lpTransport);
  115. this->isTransactedObject = FALSE;
  116. GetClientVersion(&this->m_ulClientVersion); //Ignore errors
  117. assert(lpszProfname != NULL);
  118. if(lpszProfname)
  119. this->m_strProfname = lpszProfname;
  120. }
  121. ECMsgStore::~ECMsgStore() {
  122. TRACE_MAPI(TRACE_ENTRY, "ECMsgStore::~ECMsgStore","");
  123. if(lpTransport)
  124. lpTransport->HrLogOff();
  125. // remove all advices
  126. if(m_lpNotifyClient)
  127. m_lpNotifyClient->ReleaseAll();
  128. // destruct
  129. if(m_lpNotifyClient)
  130. m_lpNotifyClient->Release();
  131. delete lpNamedProp;
  132. if(lpStorage) {
  133. // Release our propstorage since it is registered on lpTransport
  134. lpStorage->Release();
  135. /* needed because base (~ECGenericProp) also tries to release it */
  136. lpStorage = NULL;
  137. }
  138. if(lpTransport)
  139. lpTransport->Release();
  140. if(lpSupport)
  141. lpSupport->Release();
  142. TRACE_MAPI(TRACE_RETURN, "ECMsgStore::~ECMsgStore","");
  143. }
  144. //FIXME: remove duplicate profilename
  145. static HRESULT GetIMsgStoreObject(BOOL bOffline, std::string strProfname,
  146. BOOL bModify, ECMapProvider *lpmapProviders, IMAPISupport *lpMAPISup,
  147. ULONG cbEntryId, LPENTRYID lpEntryId, LPMDB *lppIMsgStore)
  148. {
  149. PROVIDER_INFO sProviderInfo;
  150. object_ptr<IProfSect> lpProfSect;
  151. memory_ptr<SPropValue> lpsPropValue;
  152. char *lpszProfileName = NULL;
  153. HRESULT hr = lpMAPISup->OpenProfileSection((LPMAPIUID)&MUID_PROFILE_INSTANCE, 0, &~lpProfSect);
  154. if(hr != hrSuccess)
  155. return hr;
  156. hr = HrGetOneProp(lpProfSect, PR_PROFILE_NAME_A, &~lpsPropValue);
  157. if(hr != hrSuccess)
  158. return hr;
  159. // Set ProfileName
  160. lpszProfileName = lpsPropValue->Value.lpszA;
  161. hr = GetProviders(lpmapProviders, lpMAPISup, lpszProfileName, 0, &sProviderInfo);
  162. if (hr != hrSuccess)
  163. return hr;
  164. return sProviderInfo.lpMSProviderOnline->Logon(lpMAPISup, 0,
  165. (LPTSTR)lpszProfileName, cbEntryId, lpEntryId,
  166. bModify ? MAPI_BEST_ACCESS | MDB_NO_DIALOG : MDB_NO_DIALOG,
  167. nullptr, nullptr, nullptr, nullptr, nullptr, lppIMsgStore);
  168. }
  169. HRESULT ECMsgStore::QueryInterface(REFIID refiid, void **lppInterface)
  170. {
  171. HRESULT hr = hrSuccess;
  172. REGISTER_INTERFACE2(ECMsgStore, this);
  173. REGISTER_INTERFACE2(ECMAPIProp, this);
  174. REGISTER_INTERFACE2(ECUnknown, this);
  175. REGISTER_INTERFACE2(IMsgStore, &this->m_xMsgStore);
  176. REGISTER_INTERFACE2(IMAPIProp, &this->m_xMsgStore);
  177. REGISTER_INTERFACE2(IUnknown, &this->m_xMsgStore);
  178. REGISTER_INTERFACE3(ISelectUnicode, IUnknown, &this->m_xUnknown);
  179. if (refiid == IID_IExchangeManageStore || refiid == IID_IExchangeManageStore6 || refiid == IID_IExchangeManageStoreEx) {
  180. if (m_bOfflineStore == FALSE) {
  181. REGISTER_INTERFACE2(IExchangeManageStore, &this->m_xExchangeManageStore);
  182. REGISTER_INTERFACE2(IExchangeManageStore6, &this->m_xExchangeManageStore6);
  183. REGISTER_INTERFACE2(IExchangeManageStoreEx, &this->m_xExchangeManageStoreEx);
  184. }
  185. }
  186. REGISTER_INTERFACE2(IECServiceAdmin, &this->m_xECServiceAdmin);
  187. REGISTER_INTERFACE2(IECSpooler, &this->m_xECSpooler);
  188. REGISTER_INTERFACE2(IECSecurity, &this->m_xECSecurity);
  189. REGISTER_INTERFACE2(IProxyStoreObject, &this->m_xProxyStoreObject);
  190. if (refiid == IID_ECMsgStoreOnline)
  191. {
  192. if (m_bOfflineStore == FALSE) {
  193. *lppInterface = &this->m_xMsgStore;
  194. AddRef();
  195. return hrSuccess;
  196. }
  197. hr = GetIMsgStoreObject(FALSE, this->m_strProfname, fModify, &g_mapProviders, lpSupport, m_cbEntryId, m_lpEntryId, (LPMDB*)lppInterface);
  198. if (hr != hrSuccess)
  199. return hr;
  200. // Add the child because mapi lookto the ref count if you work through ProxyStoreObject
  201. object_ptr<ECMsgStore> lpChild;
  202. if (((IMsgStore *)*lppInterface)->QueryInterface(IID_ECMsgStore, &~lpChild) != hrSuccess) {
  203. ((LPMDB)*lppInterface)->Release();
  204. return MAPI_E_INTERFACE_NOT_SUPPORTED;
  205. }
  206. AddChild(lpChild);
  207. return hrSuccess;
  208. }
  209. // is admin store?
  210. REGISTER_INTERFACE2(IECMultiStoreTable, &this->m_xECMultiStoreTable);
  211. REGISTER_INTERFACE2(IECLicense, &this->m_xECLicense);
  212. REGISTER_INTERFACE2(IECTestProtocol, &this->m_xECTestProtocol);
  213. return MAPI_E_INTERFACE_NOT_SUPPORTED;
  214. }
  215. HRESULT ECMsgStore::QueryInterfaceProxy(REFIID refiid, void **lppInterface)
  216. {
  217. if (refiid == IID_IProxyStoreObject) // block recusive proxy calls
  218. return MAPI_E_INTERFACE_NOT_SUPPORTED;
  219. REGISTER_INTERFACE2(IMsgStore, &this->m_xMsgStoreProxy);
  220. REGISTER_INTERFACE2(IMAPIProp, &this->m_xMsgStoreProxy);
  221. REGISTER_INTERFACE2(IUnknown, &this->m_xMsgStoreProxy);
  222. return QueryInterface(refiid, lppInterface);
  223. }
  224. ULONG ECMsgStore::Release()
  225. {
  226. // If a parent has requested a callback when we're going down, do it now.
  227. if (m_cRef == 1 && this->lpfnCallback != nullptr)
  228. lpfnCallback(this->lpCallbackObject, this);
  229. return ECUnknown::Release();
  230. }
  231. HRESULT ECMsgStore::HrSetReleaseCallback(ECUnknown *lpObject, RELEASECALLBACK lpfnCallback)
  232. {
  233. this->lpCallbackObject = lpObject;
  234. this->lpfnCallback = lpfnCallback;
  235. return hrSuccess;
  236. }
  237. HRESULT ECMsgStore::Create(const char *lpszProfname, LPMAPISUP lpSupport,
  238. WSTransport *lpTransport, BOOL fModify, ULONG ulProfileFlags,
  239. BOOL fIsSpooler, BOOL fIsDefaultStore, BOOL bOfflineStore,
  240. ECMsgStore **lppECMsgStore)
  241. {
  242. return alloc_wrap<ECMsgStore>(lpszProfname, lpSupport, lpTransport,
  243. fModify, ulProfileFlags, fIsSpooler, fIsDefaultStore,
  244. bOfflineStore).as(IID_ECMsgStore, lppECMsgStore);
  245. }
  246. HRESULT ECMsgStore::SetProps(ULONG cValues, const SPropValue *lpPropArray,
  247. SPropProblemArray **lppProblems)
  248. {
  249. HRESULT hr = ECMAPIProp::SetProps(cValues, lpPropArray, lppProblems);
  250. if (hr != hrSuccess)
  251. return hr;
  252. return ECMAPIProp::SaveChanges(KEEP_OPEN_READWRITE);
  253. }
  254. HRESULT ECMsgStore::DeleteProps(const SPropTagArray *lpPropTagArray,
  255. SPropProblemArray **lppProblems)
  256. {
  257. HRESULT hr = ECMAPIProp::DeleteProps(lpPropTagArray, lppProblems);
  258. if (hr != hrSuccess)
  259. return hr;
  260. return ECMAPIProp::SaveChanges(KEEP_OPEN_READWRITE);
  261. }
  262. HRESULT ECMsgStore::SaveChanges(ULONG ulFlags)
  263. {
  264. return hrSuccess;
  265. }
  266. HRESULT ECMsgStore::OpenProperty(ULONG ulPropTag, LPCIID lpiid, ULONG ulInterfaceOptions, ULONG ulFlags, LPUNKNOWN *lppUnk)
  267. {
  268. HRESULT hr = MAPI_E_INTERFACE_NOT_SUPPORTED;
  269. if (lpiid == NULL)
  270. return MAPI_E_INVALID_PARAMETER;
  271. if(ulPropTag == PR_RECEIVE_FOLDER_SETTINGS) {
  272. if (*lpiid == IID_IMAPITable && IsPublicStore() == false)
  273. // Non supported function for publicfolder
  274. hr = GetReceiveFolderTable(0, (LPMAPITABLE*)lppUnk);
  275. } else if(ulPropTag == PR_HIERARCHY_SYNCHRONIZER) {
  276. hr = ECExchangeExportChanges::Create(this, *lpiid, std::string(), L"store hierarchy", ICS_SYNC_HIERARCHY, (LPEXCHANGEEXPORTCHANGES*) lppUnk);
  277. } else if(ulPropTag == PR_CONTENTS_SYNCHRONIZER) {
  278. if (*lpiid == IID_IECExportAddressbookChanges) {
  279. auto lpEEAC = new(std::nothrow) ECExportAddressbookChanges(this);
  280. if (lpEEAC == nullptr)
  281. return MAPI_E_NOT_ENOUGH_MEMORY;
  282. hr = lpEEAC->QueryInterface(*lpiid, (void **)lppUnk);
  283. if (hr != hrSuccess) {
  284. delete lpEEAC;
  285. return hr;
  286. }
  287. }
  288. else
  289. hr = ECExchangeExportChanges::Create(this, *lpiid, std::string(), L"store contents", ICS_SYNC_CONTENTS, (LPEXCHANGEEXPORTCHANGES*) lppUnk);
  290. } else if (ulPropTag == PR_EC_CHANGE_ADVISOR) {
  291. object_ptr<ECChangeAdvisor> lpChangeAdvisor;
  292. hr = ECChangeAdvisor::Create(this, &~lpChangeAdvisor);
  293. if (hr == hrSuccess)
  294. hr = lpChangeAdvisor->QueryInterface(*lpiid, (void**)lppUnk);
  295. } else if(ulPropTag == PR_EC_STATSTABLE_SYSTEM) {
  296. if (*lpiid == IID_IMAPITable)
  297. hr = OpenStatsTable(TABLETYPE_STATS_SYSTEM, (LPMAPITABLE*)lppUnk);
  298. } else if(ulPropTag == PR_EC_STATSTABLE_SESSIONS) {
  299. if (*lpiid == IID_IMAPITable)
  300. hr = OpenStatsTable(TABLETYPE_STATS_SESSIONS, (LPMAPITABLE*)lppUnk);
  301. } else if(ulPropTag == PR_EC_STATSTABLE_USERS) {
  302. if (*lpiid == IID_IMAPITable)
  303. hr = OpenStatsTable(TABLETYPE_STATS_USERS, (LPMAPITABLE*)lppUnk);
  304. } else if(ulPropTag == PR_EC_STATSTABLE_COMPANY) {
  305. if (*lpiid == IID_IMAPITable)
  306. hr = OpenStatsTable(TABLETYPE_STATS_COMPANY, (LPMAPITABLE*)lppUnk);
  307. } else if(ulPropTag == PR_EC_STATSTABLE_SERVERS) {
  308. if (*lpiid == IID_IMAPITable)
  309. hr = OpenStatsTable(TABLETYPE_STATS_SERVERS, (LPMAPITABLE*)lppUnk);
  310. } else if(ulPropTag == PR_ACL_TABLE) {
  311. if(*lpiid == IID_IExchangeModifyTable)
  312. hr = ECExchangeModifyTable::CreateACLTable(this, ulInterfaceOptions, (LPEXCHANGEMODIFYTABLE*)lppUnk);
  313. } else
  314. hr = ECMAPIProp::OpenProperty(ulPropTag, lpiid, ulInterfaceOptions, ulFlags, lppUnk);
  315. return hr;
  316. }
  317. HRESULT ECMsgStore::OpenStatsTable(unsigned int ulTableType, LPMAPITABLE *lppTable)
  318. {
  319. HRESULT hr = hrSuccess;
  320. object_ptr<WSTableView> lpTableView;
  321. object_ptr<ECMAPITable> lpTable;
  322. if (lppTable == nullptr)
  323. return MAPI_E_INVALID_PARAMETER;
  324. // notifications? set 1st param: m_lpNotifyClient
  325. hr = ECMAPITable::Create("Stats table", NULL, 0, &~lpTable);
  326. if (hr != hrSuccess)
  327. return hr;
  328. // open store table view, no entryid req.
  329. hr = lpTransport->HrOpenMiscTable(ulTableType, 0, 0, NULL, this, &~lpTableView);
  330. if (hr != hrSuccess)
  331. return hr;
  332. hr = lpTable->HrSetTableOps(lpTableView, true);
  333. if (hr != hrSuccess)
  334. return hr;
  335. hr = lpTable->QueryInterface(IID_IMAPITable, (void **)lppTable);
  336. if (hr != hrSuccess)
  337. return hr;
  338. AddChild(lpTable);
  339. return hrSuccess;
  340. }
  341. /**
  342. * Register an internal advise.
  343. *
  344. * This means that the subscribe request should be sent to the server by some other means, but the
  345. * rest of the client-side handling is done just the same as a normal 'Advise()' call. Also, notifications
  346. * registered this way are marked 'synchronous' which means that they will not be offloaded to other threads
  347. * or passed to MAPI's notification system in win32; the notification callback will be called as soon as it
  348. * is received from the server, and other notifications will not be sent until the handler is done.
  349. *
  350. * @param[in] cbEntryID Size of data in lpEntryID
  351. * @param[in] lpEntryID EntryID of item to subscribe to events to
  352. * @param[in] ulEventMask Bitmask of events to susbcribe to
  353. * @param[in] lpAdviseSink Sink to send notification events to
  354. * @param[out] lpulConnection Connection ID of the registered subscription
  355. * @return result
  356. */
  357. HRESULT ECMsgStore::InternalAdvise(ULONG cbEntryID, LPENTRYID lpEntryID, ULONG ulEventMask, LPMAPIADVISESINK lpAdviseSink, ULONG *lpulConnection){
  358. HRESULT hr = hrSuccess;
  359. ecmem_ptr<ENTRYID> lpUnWrapStoreID;
  360. ULONG cbUnWrapStoreID = 0;
  361. if (m_ulProfileFlags & EC_PROFILE_FLAGS_NO_NOTIFICATIONS)
  362. return MAPI_E_NO_SUPPORT;
  363. if (lpAdviseSink == nullptr || lpulConnection == nullptr)
  364. return MAPI_E_INVALID_PARAMETER;
  365. assert(m_lpNotifyClient != NULL && (lpEntryID != NULL || this->m_lpEntryId != NULL));
  366. if(lpEntryID == NULL) {
  367. // never sent the client store entry
  368. hr = UnWrapServerClientStoreEntry(this->m_cbEntryId, this->m_lpEntryId, &cbUnWrapStoreID, &~lpUnWrapStoreID);
  369. if(hr != hrSuccess)
  370. return hr;
  371. cbEntryID = cbUnWrapStoreID;
  372. lpEntryID = lpUnWrapStoreID;
  373. }
  374. if(m_lpNotifyClient->RegisterAdvise(cbEntryID, (LPBYTE)lpEntryID, ulEventMask, true, lpAdviseSink, lpulConnection) != S_OK)
  375. hr = MAPI_E_NO_SUPPORT;
  376. if(hr != hrSuccess)
  377. return hr;
  378. m_setAdviseConnections.insert(*lpulConnection);
  379. return hrSuccess;
  380. }
  381. HRESULT ECMsgStore::Advise(ULONG cbEntryID, LPENTRYID lpEntryID, ULONG ulEventMask, LPMAPIADVISESINK lpAdviseSink, ULONG *lpulConnection){
  382. HRESULT hr = hrSuccess;
  383. ecmem_ptr<ENTRYID> lpUnWrapStoreID;
  384. ULONG cbUnWrapStoreID = 0;
  385. if (m_ulProfileFlags & EC_PROFILE_FLAGS_NO_NOTIFICATIONS)
  386. return MAPI_E_NO_SUPPORT;
  387. if (lpAdviseSink == nullptr || lpulConnection == nullptr)
  388. return MAPI_E_INVALID_PARAMETER;
  389. assert(m_lpNotifyClient != NULL && (lpEntryID != NULL || this->m_lpEntryId != NULL));
  390. if(lpEntryID == NULL) {
  391. // never sent the client store entry
  392. hr = UnWrapServerClientStoreEntry(this->m_cbEntryId, this->m_lpEntryId, &cbUnWrapStoreID, &~lpUnWrapStoreID);
  393. if(hr != hrSuccess)
  394. return hr;
  395. cbEntryID = cbUnWrapStoreID;
  396. lpEntryID = lpUnWrapStoreID;
  397. } else {
  398. // check that the given lpEntryID belongs to the store in m_lpEntryId
  399. if (memcmp(&this->GetStoreGuid(), &reinterpret_cast<EID *>(lpEntryID)->guid, sizeof(GUID)) != 0)
  400. return MAPI_E_NO_SUPPORT;
  401. }
  402. if(m_lpNotifyClient->Advise(cbEntryID, (LPBYTE)lpEntryID, ulEventMask, lpAdviseSink, lpulConnection) != S_OK)
  403. hr = MAPI_E_NO_SUPPORT;
  404. m_setAdviseConnections.insert(*lpulConnection);
  405. return hr;
  406. }
  407. HRESULT ECMsgStore::Unadvise(ULONG ulConnection) {
  408. if (m_ulProfileFlags & EC_PROFILE_FLAGS_NO_NOTIFICATIONS)
  409. return MAPI_E_NO_SUPPORT;
  410. assert(m_lpNotifyClient != NULL);
  411. m_lpNotifyClient->Unadvise(ulConnection);
  412. return hrSuccess;
  413. }
  414. HRESULT ECMsgStore::Reload(void *lpParam, ECSESSIONID sessionid)
  415. {
  416. HRESULT hr = hrSuccess;
  417. auto lpThis = static_cast<ECMsgStore *>(lpParam);
  418. for (auto conn_id : lpThis->m_setAdviseConnections)
  419. lpThis->m_lpNotifyClient->Reregister(conn_id);
  420. return hr;
  421. }
  422. HRESULT ECMsgStore::TableRowGetProp(void* lpProvider, struct propVal *lpsPropValSrc, LPSPropValue lpsPropValDst, void **lpBase, ULONG ulType)
  423. {
  424. HRESULT hr = hrSuccess;
  425. auto lpMsgStore = static_cast<ECMsgStore *>(lpProvider);
  426. switch (lpsPropValSrc->ulPropTag) {
  427. case PR_ENTRYID:
  428. {
  429. ULONG cbWrapped = 0;
  430. memory_ptr<ENTRYID> lpWrapped;
  431. hr = lpMsgStore->GetWrappedServerStoreEntryID(lpsPropValSrc->Value.bin->__size, lpsPropValSrc->Value.bin->__ptr, &cbWrapped, &~lpWrapped);
  432. if (hr != hrSuccess)
  433. return hr;
  434. hr = ECAllocateMore(cbWrapped, lpBase, reinterpret_cast<void **>(&lpsPropValDst->Value.bin.lpb));
  435. if (hr != hrSuccess)
  436. return hr;
  437. memcpy(lpsPropValDst->Value.bin.lpb, lpWrapped, cbWrapped);
  438. lpsPropValDst->Value.bin.cb = cbWrapped;
  439. lpsPropValDst->ulPropTag = PROP_TAG(PT_BINARY,PROP_ID(lpsPropValSrc->ulPropTag));
  440. break;
  441. }
  442. default:
  443. return MAPI_E_NOT_FOUND;
  444. }
  445. return hr;
  446. }
  447. /**
  448. * Compares two entry identifiers.
  449. *
  450. * Compares two entry identifiers which must match with the store MAPIUID.
  451. *
  452. * @param[in] cbEntryID1 The size in bytes of the lpEntryID1 parameter.
  453. * @param[in] lpEntryID1 A pointer to the first entry identifier.
  454. * @param[in] cbEntryID2 The size in bytes of the lpEntryID2 parameter.
  455. * @param[in] lpEntryID2 A pointer to the second entry identifier.
  456. * @param[in] ulFlags Unknown flags; MSDN says it must be zero.
  457. * @param[out] lpulResult A pointer to the result. TRUE if the two entry identifiers matching to the same object; otherwise, FALSE.
  458. *
  459. * @retval S_OK
  460. The comparison was successful.
  461. * @retval MAPI_E_INVALID_PARAMETER
  462. * One or more values are NULL.
  463. *
  464. */
  465. HRESULT ECMsgStore::CompareEntryIDs(ULONG cbEntryID1, LPENTRYID lpEntryID1, ULONG cbEntryID2, LPENTRYID lpEntryID2, ULONG ulFlags, ULONG *lpulResult)
  466. {
  467. PEID peid1 = (PEID)lpEntryID1;
  468. PEID peid2 = (PEID)lpEntryID2;
  469. PEID lpStoreId = (PEID)m_lpEntryId;
  470. if (lpulResult != nullptr)
  471. *lpulResult = false;
  472. // Apparently BlackBerry CALHelper.exe needs this
  473. if ((cbEntryID1 == 0 && cbEntryID2 != 0) || (cbEntryID1 != 0 && cbEntryID2 == 0))
  474. return hrSuccess;
  475. if (lpEntryID1 == nullptr || lpEntryID2 == nullptr ||
  476. lpulResult == nullptr)
  477. return MAPI_E_INVALID_PARAMETER;
  478. // Check if one or both of the entry identifiers contains the store guid.
  479. if (cbEntryID1 != cbEntryID2)
  480. return hrSuccess;
  481. if (cbEntryID1 < offsetof(EID, usFlags) + sizeof(peid1->usFlags) ||
  482. cbEntryID2 < offsetof(EID, usFlags) + sizeof(peid2->usFlags))
  483. return hrSuccess;
  484. if (memcmp(&lpStoreId->guid, &peid1->guid, sizeof(GUID)) != 0 ||
  485. memcmp(&lpStoreId->guid, &peid2->guid, sizeof(GUID)) != 0)
  486. return hrSuccess;
  487. if(memcmp(peid1->abFlags, peid2->abFlags, 4) != 0)
  488. return hrSuccess;
  489. if(peid1->ulVersion != peid2->ulVersion)
  490. return hrSuccess;
  491. if(peid1->usType != peid2->usType)
  492. return hrSuccess;
  493. if(peid1->ulVersion == 0) {
  494. if(cbEntryID1 != sizeof(EID_V0))
  495. return hrSuccess;
  496. if( ((EID_V0*)lpEntryID1)->ulId != ((EID_V0*)lpEntryID2)->ulId )
  497. return hrSuccess;
  498. }else {
  499. if(cbEntryID1 != CbNewEID(""))
  500. return hrSuccess;
  501. if(peid1->uniqueId != peid2->uniqueId) //comp. with the old ulId
  502. return hrSuccess;
  503. }
  504. *lpulResult = true;
  505. return hrSuccess;
  506. }
  507. HRESULT ECMsgStore::OpenEntry(ULONG cbEntryID, LPENTRYID lpEntryID, LPCIID lpInterface, ULONG ulFlags, ULONG *lpulObjType, LPUNKNOWN *lppUnk)
  508. {
  509. return OpenEntry(cbEntryID, lpEntryID, lpInterface, ulFlags, ECMessageFactory(), lpulObjType, lppUnk);
  510. }
  511. HRESULT ECMsgStore::OpenEntry(ULONG cbEntryID, LPENTRYID lpEntryID, LPCIID lpInterface, ULONG ulFlags, const IMessageFactory &refMessageFactory, ULONG *lpulObjType, LPUNKNOWN *lppUnk)
  512. {
  513. HRESULT hr = hrSuccess;
  514. memory_ptr<ENTRYID> lpRootEntryID;
  515. ULONG cbRootEntryID = 0;
  516. BOOL fModifyObject = FALSE;
  517. object_ptr<ECMAPIFolder> lpMAPIFolder;
  518. object_ptr<ECMessage> lpMessage;
  519. object_ptr<IECPropStorage> lpPropStorage;
  520. object_ptr<WSMAPIFolderOps> lpFolderOps;
  521. unsigned int ulObjType = 0;
  522. // Check input/output variables
  523. if (lpulObjType == nullptr || lppUnk == nullptr)
  524. return MAPI_E_INVALID_PARAMETER;
  525. if(ulFlags & MAPI_MODIFY) {
  526. if (!fModify)
  527. return MAPI_E_NO_ACCESS;
  528. else
  529. fModifyObject = TRUE;
  530. }
  531. if(ulFlags & MAPI_BEST_ACCESS)
  532. fModifyObject = fModify;
  533. if(cbEntryID == 0) {
  534. hr = lpTransport->HrGetStore(m_cbEntryId, m_lpEntryId, 0, NULL, &cbRootEntryID, &~lpRootEntryID);
  535. if(hr != hrSuccess)
  536. return hr;
  537. lpEntryID = lpRootEntryID;
  538. cbEntryID = cbRootEntryID;
  539. }else {
  540. hr = HrCompareEntryIdWithStoreGuid(cbEntryID, lpEntryID, &GetStoreGuid());
  541. if(hr != hrSuccess)
  542. return hr;
  543. if(!(ulFlags & MAPI_DEFERRED_ERRORS)) {
  544. hr = lpTransport->HrCheckExistObject(cbEntryID, lpEntryID, (ulFlags&(SHOW_SOFT_DELETES)));
  545. if(hr != hrSuccess)
  546. return hr;
  547. }
  548. }
  549. hr = HrGetObjTypeFromEntryId(cbEntryID, (LPBYTE)lpEntryID, &ulObjType);
  550. if(hr != hrSuccess)
  551. return hr;
  552. switch( ulObjType ) {
  553. case MAPI_FOLDER:
  554. hr = lpTransport->HrOpenFolderOps(cbEntryID, lpEntryID, &~lpFolderOps);
  555. if(hr != hrSuccess)
  556. return hr;
  557. hr = ECMAPIFolder::Create(this, fModifyObject, lpFolderOps, &~lpMAPIFolder);
  558. if(hr != hrSuccess)
  559. return hr;
  560. hr = lpTransport->HrOpenPropStorage(m_cbEntryId, m_lpEntryId, cbEntryID, lpEntryID, (ulFlags & SHOW_SOFT_DELETES) ? MSGFLAG_DELETED : 0, &~lpPropStorage);
  561. if(hr != hrSuccess)
  562. return hr;
  563. hr = lpMAPIFolder->HrSetPropStorage(lpPropStorage, !(ulFlags & MAPI_DEFERRED_ERRORS));
  564. if(hr != hrSuccess)
  565. return hr;
  566. hr = lpMAPIFolder->SetEntryId(cbEntryID, lpEntryID);
  567. if(hr != hrSuccess)
  568. return hr;
  569. AddChild(lpMAPIFolder);
  570. if(lpInterface)
  571. hr = lpMAPIFolder->QueryInterface(*lpInterface,(void **)lppUnk);
  572. else
  573. hr = lpMAPIFolder->QueryInterface(IID_IMAPIFolder, (void **)lppUnk);
  574. if(lpulObjType)
  575. *lpulObjType = MAPI_FOLDER;
  576. break;
  577. case MAPI_MESSAGE:
  578. hr = refMessageFactory.Create(this, FALSE, fModifyObject, 0, FALSE, NULL, &~lpMessage);
  579. if(hr != hrSuccess)
  580. return hr;
  581. // SC: TODO: null or my entryid ?? (this is OpenEntry(), so we don't need it?)
  582. // parent only needed on create new item .. ohwell
  583. hr = lpTransport->HrOpenPropStorage(m_cbEntryId, m_lpEntryId, cbEntryID, lpEntryID, (ulFlags & SHOW_SOFT_DELETES) ? MSGFLAG_DELETED : 0, &~lpPropStorage);
  584. if(hr != hrSuccess)
  585. return hr;
  586. hr = lpMessage->SetEntryId(cbEntryID, lpEntryID);
  587. if(hr != hrSuccess)
  588. return hr;
  589. hr = lpMessage->HrSetPropStorage(lpPropStorage, false);
  590. if(hr != hrSuccess)
  591. return hr;
  592. AddChild(lpMessage);
  593. if(lpInterface)
  594. hr = lpMessage->QueryInterface(*lpInterface,(void **)lppUnk);
  595. else
  596. hr = lpMessage->QueryInterface(IID_IMessage, (void **)lppUnk);
  597. if(lpulObjType)
  598. *lpulObjType = MAPI_MESSAGE;
  599. break;
  600. default:
  601. return MAPI_E_NOT_FOUND;
  602. }
  603. return hr;
  604. }
  605. HRESULT ECMsgStore::SetReceiveFolder(LPTSTR lpszMessageClass, ULONG ulFlags, ULONG cbEntryID, LPENTRYID lpEntryID)
  606. {
  607. // Non supported function for publicfolder
  608. if (IsPublicStore() == TRUE)
  609. return MAPI_E_NO_SUPPORT;
  610. return lpTransport->HrSetReceiveFolder(this->m_cbEntryId, this->m_lpEntryId, convstring(lpszMessageClass, ulFlags), cbEntryID, lpEntryID);
  611. }
  612. // If the open store a publicstore
  613. BOOL ECMsgStore::IsPublicStore()
  614. {
  615. BOOL fPublicStore = FALSE;
  616. if(CompareMDBProvider(&this->m_guidMDB_Provider, &KOPANO_STORE_PUBLIC_GUID))
  617. fPublicStore = TRUE;
  618. return fPublicStore;
  619. }
  620. // As the store is a delegate store
  621. BOOL ECMsgStore::IsDelegateStore()
  622. {
  623. BOOL fDelegateStore = FALSE;
  624. if(CompareMDBProvider(&this->m_guidMDB_Provider, &KOPANO_STORE_DELEGATE_GUID))
  625. fDelegateStore = TRUE;
  626. return fDelegateStore;
  627. }
  628. HRESULT ECMsgStore::GetReceiveFolder(LPTSTR lpszMessageClass, ULONG ulFlags, ULONG *lpcbEntryID, LPENTRYID *lppEntryID, LPTSTR *lppszExplicitClass)
  629. {
  630. HRESULT hr;
  631. ULONG cbEntryID = 0;
  632. LPENTRYID lpEntryID = NULL;
  633. utf8string strExplicitClass;
  634. // Non supported function for publicfolder
  635. if (IsPublicStore() == TRUE)
  636. return MAPI_E_NO_SUPPORT;
  637. // Check input/output variables
  638. if (lpcbEntryID == NULL || lppEntryID == NULL) // lppszExplicitClass may NULL
  639. return MAPI_E_INVALID_PARAMETER;
  640. hr = lpTransport->HrGetReceiveFolder(this->m_cbEntryId, this->m_lpEntryId, convstring(lpszMessageClass, ulFlags), &cbEntryID, &lpEntryID, lppszExplicitClass ? &strExplicitClass : NULL);
  641. if(hr != hrSuccess)
  642. return hr;
  643. if(lpEntryID) {
  644. *lpcbEntryID = cbEntryID;
  645. *lppEntryID = lpEntryID;
  646. } else {
  647. *lpcbEntryID = 0;
  648. *lppEntryID = NULL;
  649. }
  650. if (lppszExplicitClass == nullptr)
  651. return hrSuccess;
  652. if (ulFlags & MAPI_UNICODE) {
  653. std::wstring dst = convert_to<std::wstring>(strExplicitClass);
  654. hr = MAPIAllocateBuffer(sizeof(std::wstring::value_type) * (dst.length() + 1), (void **)lppszExplicitClass);
  655. if (hr != hrSuccess)
  656. return hr;
  657. wcscpy((wchar_t *)*lppszExplicitClass, dst.c_str());
  658. return hrSuccess;
  659. }
  660. std::string dst = convert_to<std::string>(strExplicitClass);
  661. hr = MAPIAllocateBuffer(dst.length() + 1, (void **)lppszExplicitClass);
  662. if (hr != hrSuccess)
  663. return hr;
  664. strcpy((char *)*lppszExplicitClass, dst.c_str());
  665. return hrSuccess;
  666. }
  667. HRESULT ECMsgStore::GetReceiveFolderTable(ULONG ulFlags, LPMAPITABLE *lppTable)
  668. {
  669. HRESULT hr = hrSuccess;
  670. object_ptr<ECMemTableView> lpView = NULL;
  671. object_ptr<ECMemTable> lpMemTable;
  672. rowset_ptr lpsRowSet;
  673. unsigned int i;
  674. memory_ptr<SPropTagArray> lpPropTagArray;
  675. // Non supported function for publicfolder
  676. if (IsPublicStore())
  677. return MAPI_E_NO_SUPPORT;
  678. // Check input/output variables
  679. if (lppTable == nullptr)
  680. return MAPI_E_INVALID_PARAMETER;
  681. hr = Util::HrCopyUnicodePropTagArray(ulFlags, sPropRFTColumns, &~lpPropTagArray);
  682. if(hr != hrSuccess)
  683. return hr;
  684. hr = ECMemTable::Create(lpPropTagArray, PR_ROWID, &~lpMemTable); // PR_INSTANCE_KEY
  685. if(hr != hrSuccess)
  686. return hr;
  687. //Get the receivefolder list from the server
  688. hr = lpTransport->HrGetReceiveFolderTable(ulFlags, this->m_cbEntryId, this->m_lpEntryId, &~lpsRowSet);
  689. if(hr != hrSuccess)
  690. return hr;
  691. for (i = 0; i < lpsRowSet->cRows; ++i) {
  692. hr = lpMemTable->HrModifyRow(ECKeyTable::TABLE_ROW_ADD, NULL, lpsRowSet->aRow[i].lpProps, NUM_RFT_PROPS);
  693. if(hr != hrSuccess)
  694. return hr;
  695. }
  696. hr = lpMemTable->HrGetView(createLocaleFromName(""), ulFlags & MAPI_UNICODE, &~lpView);
  697. if(hr != hrSuccess)
  698. return hr;
  699. return lpView->QueryInterface(IID_IMAPITable, (void **)lppTable);
  700. }
  701. HRESULT ECMsgStore::StoreLogoff(ULONG *lpulFlags) {
  702. return hrSuccess;
  703. }
  704. HRESULT ECMsgStore::AbortSubmit(ULONG cbEntryID, LPENTRYID lpEntryID, ULONG ulFlags)
  705. {
  706. // Non supported function for publicfolder
  707. if (IsPublicStore() == TRUE)
  708. return MAPI_E_NO_SUPPORT;
  709. // Check input/output variables
  710. if (lpEntryID == NULL)
  711. return MAPI_E_INVALID_PARAMETER;
  712. return lpTransport->HrAbortSubmit(cbEntryID, lpEntryID);
  713. }
  714. HRESULT ECMsgStore::GetOutgoingQueue(ULONG ulFlags, LPMAPITABLE *lppTable)
  715. {
  716. HRESULT hr = hrSuccess;
  717. object_ptr<ECMAPITable> lpTable;
  718. object_ptr<WSTableOutGoingQueue> lpTableOps;
  719. // Only supported by the MAPI spooler
  720. /* if (this->IsSpooler() == false)
  721. return MAPI_E_NO_SUPPORT;
  722. */
  723. // Check input/output variables
  724. if (lppTable == nullptr)
  725. return MAPI_E_INVALID_PARAMETER;
  726. hr = ECMAPITable::Create("Outgoing queue", this->m_lpNotifyClient, 0, &~lpTable);
  727. if(hr != hrSuccess)
  728. return hr;
  729. hr = this->lpTransport->HrOpenTableOutGoingQueueOps(this->m_cbEntryId, this->m_lpEntryId, this, &~lpTableOps);
  730. if(hr != hrSuccess)
  731. return hr;
  732. hr = lpTable->HrSetTableOps(lpTableOps, !(ulFlags & MAPI_DEFERRED_ERRORS));
  733. if(hr != hrSuccess)
  734. return hr;
  735. hr = lpTable->QueryInterface(IID_IMAPITable, (void **)lppTable);
  736. AddChild(lpTable);
  737. return hr;
  738. }
  739. HRESULT ECMsgStore::SetLockState(LPMESSAGE lpMessage, ULONG ulLockState)
  740. {
  741. HRESULT hr = hrSuccess;
  742. ecmem_ptr<SPropValue> lpsPropArray;
  743. ULONG cValue = 0;
  744. ULONG ulSubmitFlag = 0;
  745. ECMessagePtr ptrECMessage;
  746. static constexpr const SizedSPropTagArray(2, sptaMessageProps) =
  747. {2, {PR_SUBMIT_FLAGS, PR_ENTRYID}};
  748. enum {IDX_SUBMIT_FLAGS, IDX_ENTRYID};
  749. // Only supported by the MAPI spooler
  750. /* if (!this->IsSpooler())
  751. return MAPI_E_NO_SUPPORT; */
  752. if (lpMessage == nullptr)
  753. return MAPI_E_INVALID_PARAMETER;
  754. hr = lpMessage->GetProps(sptaMessageProps, 0, &cValue, &~lpsPropArray);
  755. if(HR_FAILED(hr))
  756. return hr;
  757. if (PROP_TYPE(lpsPropArray[IDX_ENTRYID].ulPropTag) == PT_ERROR)
  758. return lpsPropArray[IDX_ENTRYID].Value.err;
  759. if (PROP_TYPE(lpsPropArray[IDX_SUBMIT_FLAGS].ulPropTag) != PT_ERROR)
  760. ulSubmitFlag = lpsPropArray->Value.l;
  761. // set the lock state, if the message is already in the correct state
  762. // just get outta here
  763. if (ulLockState & MSG_LOCKED)
  764. {
  765. if (!(ulSubmitFlag & SUBMITFLAG_LOCKED))
  766. ulSubmitFlag |= SUBMITFLAG_LOCKED;
  767. else
  768. return hr;
  769. } else { // unlock
  770. if (ulSubmitFlag & SUBMITFLAG_LOCKED)
  771. ulSubmitFlag &= ~SUBMITFLAG_LOCKED;
  772. else
  773. return hr;
  774. }
  775. hr = lpMessage->QueryInterface(ptrECMessage.iid(), &~ptrECMessage);
  776. if (hr != hrSuccess)
  777. return hr;
  778. if (ptrECMessage->IsReadOnly())
  779. return MAPI_E_NO_ACCESS;
  780. hr = lpTransport->HrSetLockState(lpsPropArray[IDX_ENTRYID].Value.bin.cb, (LPENTRYID)lpsPropArray[IDX_ENTRYID].Value.bin.lpb, (ulSubmitFlag & SUBMITFLAG_LOCKED) == SUBMITFLAG_LOCKED);
  781. if (hr != hrSuccess)
  782. return hr;
  783. hr = ECAllocateBuffer(sizeof(SPropValue), &~lpsPropArray);
  784. if (hr != hrSuccess)
  785. return hr;
  786. lpsPropArray[0].ulPropTag = PR_SUBMIT_FLAGS;
  787. lpsPropArray[0].Value.l = ulSubmitFlag;
  788. hr = lpMessage->SetProps(1, lpsPropArray, NULL);
  789. if (hr != hrSuccess)
  790. return hr;
  791. return lpMessage->SaveChanges(KEEP_OPEN_READWRITE);
  792. }
  793. HRESULT ECMsgStore::FinishedMsg(ULONG ulFlags, ULONG cbEntryID, LPENTRYID lpEntryID)
  794. {
  795. HRESULT hr = hrSuccess;
  796. ULONG ulObjType = 0;
  797. object_ptr<IMessage> lpMessage;
  798. // Only supported by the MAPI spooler
  799. /* ifthis->IsSpooler() == false)
  800. return MAPI_E_NO_SUPPORT;
  801. */
  802. // Check input/output variables
  803. if (lpEntryID == nullptr)
  804. return MAPI_E_INVALID_PARAMETER;
  805. // Delete the message from the local outgoing queue
  806. hr = lpTransport->HrFinishedMessage(cbEntryID, lpEntryID, EC_SUBMIT_LOCAL);
  807. if(hr != hrSuccess)
  808. return hr;
  809. /**
  810. * @todo: Do we need this or can we let OpenEntry succeed if this is the same session on which the
  811. * message was locked.
  812. */
  813. hr = lpTransport->HrSetLockState(cbEntryID, lpEntryID, false);
  814. if (hr != hrSuccess)
  815. return hr;
  816. hr = OpenEntry(cbEntryID, lpEntryID, &IID_IMessage, MAPI_MODIFY, &ulObjType, &~lpMessage);
  817. if(hr != hrSuccess)
  818. return hr;
  819. // Unlock the message
  820. hr = SetLockState(lpMessage, MSG_UNLOCKED);
  821. if(hr != hrSuccess)
  822. return hr;
  823. // Information: DoSentMail released object lpMessage
  824. hr = lpSupport->DoSentMail(0, lpMessage);
  825. if(hr != hrSuccess)
  826. return hr;
  827. lpMessage.release(); /* was fed into DoSentMail */
  828. return hrSuccess;
  829. }
  830. HRESULT ECMsgStore::NotifyNewMail(LPNOTIFICATION lpNotification)
  831. {
  832. HRESULT hr;
  833. // Only supported by the MAPI spooler
  834. /* if (this->IsSpooler() == false)
  835. return MAPI_E_NO_SUPPORT;
  836. */
  837. // Check input/output variables
  838. if (lpNotification == NULL || lpNotification->info.newmail.lpParentID == NULL || lpNotification->info.newmail.lpEntryID == NULL)
  839. return MAPI_E_INVALID_PARAMETER;
  840. hr = HrCompareEntryIdWithStoreGuid(lpNotification->info.newmail.cbEntryID, lpNotification->info.newmail.lpEntryID, &GetStoreGuid());
  841. if(hr != hrSuccess)
  842. return hr;
  843. hr = HrCompareEntryIdWithStoreGuid(lpNotification->info.newmail.cbParentID, lpNotification->info.newmail.lpParentID, &GetStoreGuid());
  844. if(hr != hrSuccess)
  845. return hr;
  846. return lpTransport->HrNotify(lpNotification);
  847. }
  848. HRESULT ECMsgStore::GetPropHandler(ULONG ulPropTag, void* lpProvider, ULONG ulFlags, LPSPropValue lpsPropValue, void *lpParam, void *lpBase)
  849. {
  850. HRESULT hr = hrSuccess;
  851. object_ptr<IProfSect> lpProfSect;
  852. memory_ptr<SPropValue> lpProp;
  853. auto lpStore = static_cast<ECMsgStore *>(lpParam);
  854. switch(PROP_ID(ulPropTag)) {
  855. case PROP_ID(PR_EMSMDB_SECTION_UID): {
  856. hr = lpStore->lpSupport->OpenProfileSection(NULL, 0, &~lpProfSect);
  857. if(hr != hrSuccess)
  858. return hr;
  859. hr = HrGetOneProp(lpProfSect, PR_SERVICE_UID, &~lpProp);
  860. if(hr != hrSuccess)
  861. return hr;
  862. hr = lpStore->lpSupport->OpenProfileSection((LPMAPIUID)lpProp->Value.bin.lpb, 0, &~lpProfSect);
  863. if(hr != hrSuccess)
  864. return hr;
  865. hr = HrGetOneProp(lpProfSect, PR_EMSMDB_SECTION_UID, &~lpProp);
  866. if(hr != hrSuccess)
  867. return hr;
  868. lpsPropValue->ulPropTag = PR_EMSMDB_SECTION_UID;
  869. if ((hr = MAPIAllocateMore(sizeof(GUID), lpBase, (void **) &lpsPropValue->Value.bin.lpb)) != hrSuccess)
  870. return hr;
  871. memcpy(lpsPropValue->Value.bin.lpb, lpProp->Value.bin.lpb, sizeof(GUID));
  872. lpsPropValue->Value.bin.cb = sizeof(GUID);
  873. break;
  874. }
  875. case PROP_ID(PR_SEARCH_KEY):
  876. case PROP_ID(PR_ENTRYID):
  877. {
  878. ULONG cbWrapped = 0;
  879. memory_ptr<ENTRYID> lpWrapped;
  880. lpsPropValue->ulPropTag = ulPropTag;
  881. hr = lpStore->GetWrappedStoreEntryID(&cbWrapped, &~lpWrapped);
  882. if(hr == hrSuccess) {
  883. hr = ECAllocateMore(cbWrapped, lpBase, reinterpret_cast<void **>(&lpsPropValue->Value.bin.lpb));
  884. if (hr != hrSuccess)
  885. break;
  886. memcpy(lpsPropValue->Value.bin.lpb, lpWrapped, cbWrapped);
  887. lpsPropValue->Value.bin.cb = cbWrapped;
  888. } else {
  889. hr = MAPI_E_NOT_FOUND;
  890. }
  891. break;
  892. }
  893. case PROP_ID(PR_RECORD_KEY):
  894. lpsPropValue->ulPropTag = PR_RECORD_KEY;
  895. lpsPropValue->Value.bin.cb = sizeof(MAPIUID);
  896. hr = ECAllocateMore(sizeof(MAPIUID), lpBase, reinterpret_cast<void **>(&lpsPropValue->Value.bin.lpb));
  897. if (hr != hrSuccess)
  898. break;
  899. memcpy(lpsPropValue->Value.bin.lpb, &lpStore->GetStoreGuid(), sizeof(MAPIUID));
  900. break;
  901. case PROP_ID(PR_RECEIVE_FOLDER_SETTINGS):
  902. lpsPropValue->ulPropTag = PR_RECEIVE_FOLDER_SETTINGS;
  903. lpsPropValue->Value.x = 1;
  904. break;
  905. case PROP_ID(PR_MESSAGE_SIZE_EXTENDED):
  906. hr = lpStore->HrGetRealProp(PR_MESSAGE_SIZE_EXTENDED, ulFlags, lpBase, lpsPropValue);
  907. break;
  908. case PROP_ID(PR_QUOTA_WARNING_THRESHOLD):
  909. lpsPropValue->ulPropTag = PR_QUOTA_WARNING_THRESHOLD;
  910. hr = lpStore->HrGetRealProp(PR_QUOTA_WARNING_THRESHOLD, ulFlags, lpBase, lpsPropValue);
  911. break;
  912. case PROP_ID(PR_QUOTA_SEND_THRESHOLD):
  913. lpsPropValue->ulPropTag = PR_QUOTA_SEND_THRESHOLD;
  914. hr = lpStore->HrGetRealProp(PR_QUOTA_SEND_THRESHOLD, ulFlags, lpBase, lpsPropValue);
  915. break;
  916. case PROP_ID(PR_QUOTA_RECEIVE_THRESHOLD):
  917. lpsPropValue->ulPropTag = PR_QUOTA_RECEIVE_THRESHOLD;
  918. hr = lpStore->HrGetRealProp(PR_QUOTA_RECEIVE_THRESHOLD, ulFlags, lpBase, lpsPropValue);
  919. break;
  920. case PROP_ID(PR_MAILBOX_OWNER_NAME):
  921. if(lpStore->IsPublicStore() == TRUE || lpStore->IsOfflineStore() == TRUE) {
  922. hr = MAPI_E_NOT_FOUND;
  923. break;
  924. }
  925. lpsPropValue->ulPropTag = ulPropTag;
  926. hr = lpStore->HrGetRealProp(ulPropTag, ulFlags, lpBase, lpsPropValue);
  927. break;
  928. case PROP_ID(PR_MAILBOX_OWNER_ENTRYID):
  929. if(lpStore->IsPublicStore() == TRUE || lpStore->IsOfflineStore() == TRUE) {
  930. hr = MAPI_E_NOT_FOUND;
  931. break;
  932. }
  933. lpsPropValue->ulPropTag = PR_MAILBOX_OWNER_ENTRYID;
  934. hr = lpStore->HrGetRealProp(PR_MAILBOX_OWNER_ENTRYID, ulFlags, lpBase, lpsPropValue);
  935. break;
  936. case PROP_ID(PR_STORE_OFFLINE):
  937. // Delegate stores are always online, so ignore this property
  938. if(lpStore->IsDelegateStore() == TRUE) {
  939. hr = MAPI_E_NOT_FOUND;
  940. break;
  941. }
  942. lpsPropValue->ulPropTag = PR_STORE_OFFLINE;
  943. lpsPropValue->Value.b = !!lpStore->IsOfflineStore();
  944. break;
  945. case PROP_ID(PR_USER_NAME):
  946. lpsPropValue->ulPropTag = PR_USER_NAME;
  947. hr = lpStore->HrGetRealProp(PR_USER_NAME, ulFlags, lpBase, lpsPropValue);
  948. break;
  949. case PROP_ID(PR_USER_ENTRYID):
  950. lpsPropValue->ulPropTag = PR_USER_ENTRYID;
  951. hr = lpStore->HrGetRealProp(PR_USER_ENTRYID, ulFlags, lpBase, lpsPropValue);
  952. break;
  953. case PROP_ID(PR_EC_STATSTABLE_SYSTEM):
  954. case PROP_ID(PR_EC_STATSTABLE_SESSIONS):
  955. case PROP_ID(PR_EC_STATSTABLE_USERS):
  956. case PROP_ID(PR_EC_STATSTABLE_COMPANY):
  957. lpsPropValue->ulPropTag = ulPropTag;
  958. lpsPropValue->Value.x = 1;
  959. break;
  960. case PROP_ID(PR_TEST_LINE_SPEED):
  961. lpsPropValue->ulPropTag = ulPropTag;
  962. lpsPropValue->Value.bin.lpb = NULL;
  963. lpsPropValue->Value.bin.cb = 0;
  964. break;
  965. case PROP_ID(PR_ACL_DATA):
  966. hr = lpStore->GetSerializedACLData(lpBase, lpsPropValue);
  967. if (hr == hrSuccess)
  968. lpsPropValue->ulPropTag = PR_ACL_DATA;
  969. else {
  970. lpsPropValue->ulPropTag = CHANGE_PROP_TYPE(PR_ACL_DATA, PT_ERROR);
  971. lpsPropValue->Value.err = hr;
  972. }
  973. break;
  974. default:
  975. hr = MAPI_E_NOT_FOUND;
  976. break;
  977. }
  978. return hr;
  979. }
  980. HRESULT ECMsgStore::SetPropHandler(ULONG ulPropTag, void *lpProvider,
  981. const SPropValue *lpsPropValue, void *lpParam)
  982. {
  983. HRESULT hr = hrSuccess;
  984. auto lpStore = static_cast<ECMsgStore *>(lpParam);
  985. switch(ulPropTag) {
  986. case PR_ACL_DATA:
  987. hr = lpStore->SetSerializedACLData(lpsPropValue);
  988. break;
  989. default:
  990. hr = MAPI_E_NOT_FOUND;
  991. break;
  992. }
  993. return hr;
  994. }
  995. HRESULT ECMsgStore::SetEntryId(ULONG cbEntryId, LPENTRYID lpEntryId)
  996. {
  997. assert(m_lpNotifyClient == NULL);
  998. HRESULT hr = ECGenericProp::SetEntryId(cbEntryId, lpEntryId);
  999. if(hr != hrSuccess)
  1000. return hr;
  1001. if(! (m_ulProfileFlags & EC_PROFILE_FLAGS_NO_NOTIFICATIONS)) {
  1002. // Create Notifyclient
  1003. hr = ECNotifyClient::Create(MAPI_STORE, this, m_ulProfileFlags, lpSupport, &m_lpNotifyClient);
  1004. assert(m_lpNotifyClient != NULL);
  1005. if(hr != hrSuccess)
  1006. return hr;
  1007. }
  1008. return hrSuccess;
  1009. }
  1010. const GUID& ECMsgStore::GetStoreGuid()
  1011. {
  1012. return ((PEID)m_lpEntryId)->guid;
  1013. }
  1014. HRESULT ECMsgStore::GetWrappedStoreEntryID(ULONG* lpcbWrapped, LPENTRYID* lppWrapped)
  1015. {
  1016. //hr = WrapStoreEntryID(0, WCLIENT_DLL_NAME, CbEID(peid), (LPENTRYID)peid, &cbWrapped, &lpWrapped);
  1017. return lpSupport->WrapStoreEntryID(this->m_cbEntryId, this->m_lpEntryId, lpcbWrapped, lppWrapped);
  1018. }
  1019. // This is a function special for the spooler to get the right store entryid
  1020. // This is a problem of the master outgoing queue
  1021. HRESULT ECMsgStore::GetWrappedServerStoreEntryID(ULONG cbEntryId, LPBYTE lpEntryId, ULONG* lpcbWrapped, LPENTRYID* lppWrapped)
  1022. {
  1023. HRESULT hr = hrSuccess;
  1024. ULONG cbStoreID = 0;
  1025. ecmem_ptr<ENTRYID> lpStoreID;
  1026. entryId sEntryId;
  1027. sEntryId.__ptr = lpEntryId;
  1028. sEntryId.__size = cbEntryId;
  1029. hr = WrapServerClientStoreEntry(lpTransport->GetServerName(), &sEntryId, &cbStoreID, &~lpStoreID);
  1030. if(hr != hrSuccess)
  1031. return hr;
  1032. return lpSupport->WrapStoreEntryID(cbStoreID, lpStoreID, lpcbWrapped, lppWrapped);
  1033. }
  1034. /**
  1035. * Implementation of the IExchangeManageStore interface
  1036. *
  1037. * This method creates a store entryid for a specific user optionaly on a specific server.
  1038. *
  1039. * @param[in] lpszMsgStoreDN
  1040. * The DN of the server on which the store should be searched for. The default redirect system will be
  1041. * used if this parameter is set to NULL or an empty string.
  1042. * @param[in] lpszMailboxDN
  1043. * The username for whom to find the store.
  1044. * @param[in] ulFlags
  1045. * OPENSTORE_OVERRIDE_HOME_MDB - Don't fall back to resolving the server if the user can't be found on the specified server.
  1046. * MAPI_UNICODE - All passed strings are in Unicode.
  1047. * @param[out] lpcbEntryID
  1048. * Pointer to a ULONG variable, which will be set to the size of the returned entry id.
  1049. * @param[out] lppEntryID
  1050. * Pointer to a LPENTRYID variable, which will be set to point to the newly created entry id.
  1051. *
  1052. * @return HRESULT
  1053. * @retval MAPI_E_NOT_FOUND The mailbox was not found. User not present on server, or doesn't have a store.
  1054. * @retval MAPI_E_UNABLE_TO_COMPLETE A second redirect was returned. This usually indicates a system configuration error.
  1055. * @retval MAPI_E_INVALID_PARAMETER One of the parameters is invalid. This includes absent for obligatory parameters.
  1056. */
  1057. HRESULT ECMsgStore::CreateStoreEntryID(LPTSTR lpszMsgStoreDN, LPTSTR lpszMailboxDN, ULONG ulFlags, ULONG *lpcbEntryID, LPENTRYID *lppEntryID)
  1058. {
  1059. HRESULT hr = hrSuccess;
  1060. ULONG cbStoreEntryID = 0;
  1061. memory_ptr<ENTRYID> lpStoreEntryID;
  1062. object_ptr<WSTransport> lpTmpTransport;
  1063. convstring tstrMsgStoreDN(lpszMsgStoreDN, ulFlags);
  1064. convstring tstrMailboxDN(lpszMailboxDN, ulFlags);
  1065. if (tstrMsgStoreDN.null_or_empty()) {
  1066. // No messagestore DN provided. Just try the current server and let it redirect us if neeeded.
  1067. string strRedirServer;
  1068. hr = lpTransport->HrResolveUserStore(tstrMailboxDN, ulFlags, NULL, &cbStoreEntryID, &~lpStoreEntryID, &strRedirServer);
  1069. if (hr == MAPI_E_UNABLE_TO_COMPLETE) {
  1070. hr = lpTransport->CreateAndLogonAlternate(strRedirServer.c_str(), &~lpTmpTransport);
  1071. if (hr != hrSuccess)
  1072. return hr;
  1073. hr = lpTmpTransport->HrResolveUserStore(tstrMailboxDN, ulFlags, NULL, &cbStoreEntryID, &~lpStoreEntryID);
  1074. if (hr != hrSuccess)
  1075. return hr;
  1076. hr = lpTmpTransport->HrLogOff();
  1077. }
  1078. if(hr != hrSuccess)
  1079. return hr;
  1080. } else {
  1081. utf8string strPseudoUrl;
  1082. MAPIStringPtr ptrServerPath;
  1083. bool bIsPeer;
  1084. hr = MsgStoreDnToPseudoUrl(tstrMsgStoreDN, &strPseudoUrl);
  1085. if (hr == MAPI_E_NO_SUPPORT && (ulFlags & OPENSTORE_OVERRIDE_HOME_MDB) == 0)
  1086. // Try again old style since the MsgStoreDn contained Unknown as the server name.
  1087. return CreateStoreEntryID(nullptr, lpszMailboxDN, ulFlags, lpcbEntryID, lppEntryID);
  1088. else if (hr != hrSuccess)
  1089. return hr;
  1090. // MsgStoreDN successfully converted
  1091. hr = lpTransport->HrResolvePseudoUrl(strPseudoUrl.c_str(), &~ptrServerPath, &bIsPeer);
  1092. if (hr == MAPI_E_NOT_FOUND && (ulFlags & OPENSTORE_OVERRIDE_HOME_MDB) == 0)
  1093. // Try again old style since the MsgStoreDN contained an unknown server name or the server doesn't support multi server.
  1094. return CreateStoreEntryID(nullptr, lpszMailboxDN, ulFlags, lpcbEntryID, lppEntryID);
  1095. else if (hr != hrSuccess)
  1096. return hr;
  1097. // Pseudo URL successfully resolved
  1098. if (bIsPeer) {
  1099. hr = lpTransport->HrResolveUserStore(tstrMailboxDN, OPENSTORE_OVERRIDE_HOME_MDB, NULL, &cbStoreEntryID, &~lpStoreEntryID);
  1100. if (hr != hrSuccess)
  1101. return hr;
  1102. } else {
  1103. hr = lpTransport->CreateAndLogonAlternate(ptrServerPath, &~lpTmpTransport);
  1104. if (hr != hrSuccess)
  1105. return hr;
  1106. hr = lpTmpTransport->HrResolveUserStore(tstrMailboxDN, OPENSTORE_OVERRIDE_HOME_MDB, NULL, &cbStoreEntryID, &~lpStoreEntryID);
  1107. if (hr != hrSuccess)
  1108. return hr;
  1109. lpTmpTransport->HrLogOff();
  1110. }
  1111. }
  1112. return WrapStoreEntryID(0, (LPTSTR)WCLIENT_DLL_NAME, cbStoreEntryID, lpStoreEntryID, lpcbEntryID, lppEntryID);
  1113. }
  1114. HRESULT ECMsgStore::CreateStoreEntryID2(ULONG cValues, LPSPropValue lpProps, ULONG ulFlags, ULONG *lpcbEntryID, LPENTRYID *lppEntryID)
  1115. {
  1116. auto lpMsgStoreDN = PCpropFindProp(lpProps, cValues, PR_PROFILE_MDB_DN);
  1117. auto lpMailboxDN = PCpropFindProp(lpProps, cValues, PR_PROFILE_MAILBOX);
  1118. if (lpMsgStoreDN == NULL || lpMailboxDN == NULL)
  1119. return MAPI_E_INVALID_PARAMETER;
  1120. return CreateStoreEntryID((LPTSTR)lpMsgStoreDN->Value.lpszA, (LPTSTR)lpMailboxDN->Value.lpszA, ulFlags & ~MAPI_UNICODE, lpcbEntryID, lppEntryID);
  1121. }
  1122. HRESULT ECMsgStore::EntryIDFromSourceKey(ULONG cFolderKeySize, BYTE *lpFolderSourceKey, ULONG cMessageKeySize, BYTE *lpMessageSourceKey, ULONG *lpcbEntryID, LPENTRYID *lppEntryID)
  1123. {
  1124. return lpTransport->HrEntryIDFromSourceKey(this->m_cbEntryId, this->m_lpEntryId, cFolderKeySize, lpFolderSourceKey, cMessageKeySize, lpMessageSourceKey, lpcbEntryID, lppEntryID);
  1125. }
  1126. HRESULT ECMsgStore::GetRights(ULONG cbUserEntryID, LPENTRYID lpUserEntryID, ULONG cbEntryID, LPENTRYID lpEntryID, ULONG *lpulRights)
  1127. {
  1128. return MAPI_E_NOT_FOUND;
  1129. }
  1130. /**
  1131. * Get information about all of the mailboxes on a server.
  1132. *
  1133. * @param[in] lpszServerName Points to a string that contains the name of the server
  1134. * @param[out] lppTable Points to a IMAPITable interface containing the information about all of
  1135. * the mailboxes on the server specified in lpszServerName
  1136. * param[in] ulFlags Specifies whether the server name is Unicode or not. The server name is
  1137. * default in ASCII format. With flags MAPI_UNICODE the server name is in Unicode format.
  1138. * @return Mapi error codes
  1139. *
  1140. * @remark If named properties are used in the column set of the lppTable ensure you have the right named property id.
  1141. * The id can be different on each server.
  1142. */
  1143. HRESULT ECMsgStore::GetMailboxTable(LPTSTR lpszServerName, LPMAPITABLE *lppTable, ULONG ulFlags)
  1144. {
  1145. HRESULT hr = hrSuccess;
  1146. object_ptr<ECMAPITable> lpTable;
  1147. object_ptr<WSTableView> lpTableOps;
  1148. object_ptr<WSTransport> lpTmpTransport;
  1149. object_ptr<ECMsgStore> lpMsgStore;
  1150. object_ptr<IMsgStore> lpMsgStoreOtherServer;
  1151. ULONG cbEntryId = 0;
  1152. memory_ptr<ENTRYID> lpEntryId;
  1153. bool bIsPeer = true;
  1154. MAPIStringPtr ptrServerPath;
  1155. std::string strPseudoUrl;
  1156. convstring tstrServerName(lpszServerName, ulFlags);
  1157. const utf8string strUserName = convert_to<utf8string>("SYSTEM");
  1158. if (!tstrServerName.null_or_empty()) {
  1159. strPseudoUrl = "pseudo://";
  1160. strPseudoUrl += tstrServerName;
  1161. hr = lpTransport->HrResolvePseudoUrl(strPseudoUrl.c_str(), &~ptrServerPath, &bIsPeer);
  1162. if (hr != hrSuccess)
  1163. return hr;
  1164. if (!bIsPeer) {
  1165. hr = lpTransport->CreateAndLogonAlternate(ptrServerPath, &~lpTmpTransport);
  1166. if (hr != hrSuccess)
  1167. return hr;
  1168. hr = lpTmpTransport->HrResolveUserStore(strUserName, 0, NULL, &cbEntryId, &~lpEntryId);
  1169. if (hr != hrSuccess)
  1170. return hr;
  1171. hr = GetIMsgStoreObject(FALSE, this->m_strProfname, fModify, &g_mapProviders, lpSupport, cbEntryId, lpEntryId, &~lpMsgStoreOtherServer);
  1172. if (hr != hrSuccess)
  1173. return hr;
  1174. hr = lpMsgStoreOtherServer->QueryInterface(IID_ECMsgStore, &~lpMsgStore);
  1175. if (hr != hrSuccess)
  1176. return hr;
  1177. }
  1178. }
  1179. if (bIsPeer) {
  1180. hr = this->QueryInterface(IID_ECMsgStore, &~lpMsgStore);
  1181. if (hr != hrSuccess)
  1182. return hr;
  1183. }
  1184. assert(lpMsgStore != NULL);
  1185. hr = ECMAPITable::Create("Mailbox table", lpMsgStore->GetMsgStore()->m_lpNotifyClient, 0, &~lpTable);
  1186. if(hr != hrSuccess)
  1187. return hr;
  1188. hr = lpMsgStore->lpTransport->HrOpenMailBoxTableOps(ulFlags & MAPI_UNICODE, lpMsgStore->GetMsgStore(), &~lpTableOps);
  1189. if(hr != hrSuccess)
  1190. return hr;
  1191. hr = lpTable->HrSetTableOps(lpTableOps, !(ulFlags & MAPI_DEFERRED_ERRORS));
  1192. if(hr != hrSuccess)
  1193. return hr;
  1194. hr = lpTable->QueryInterface(IID_IMAPITable, (void **)lppTable);
  1195. if(hr != hrSuccess)
  1196. return hr;
  1197. lpMsgStore->AddChild(lpTable);
  1198. return hrSuccess;
  1199. }
  1200. /**
  1201. * Get information about all of the public mailboxes on a server. (not implement)
  1202. *
  1203. * @param[in] lpszServerName Points to a string that contains the name of the server
  1204. * @param[out] lppTable Points to a IMAPITable interface containing the information about all of
  1205. * the mailboxes on the server specified in lpszServerName
  1206. * param[in] ulFlags Specifies whether the server name is Unicode or not. The server name is
  1207. * default in ASCII format. With flags MAPI_UNICODE the server name is in Unicode format.
  1208. * Flag MDB_IPM The public folders are interpersonal message (IPM) folders.
  1209. Flag MDB_NON_IPM The public folders are non-IPM folders.
  1210. *
  1211. * @return Mapi error codes
  1212. *
  1213. *
  1214. * @todo Implement this function like GetMailboxTable
  1215. */
  1216. HRESULT ECMsgStore::GetPublicFolderTable(LPTSTR lpszServerName, LPMAPITABLE *lppTable, ULONG ulFlags)
  1217. {
  1218. return MAPI_E_NOT_FOUND;
  1219. }
  1220. // IECServiceAdmin
  1221. // Create the freebusy folder on a private store
  1222. static HRESULT CreatePrivateFreeBusyData(LPMAPIFOLDER lpRootFolder,
  1223. LPMAPIFOLDER lpInboxFolder, LPMAPIFOLDER lpCalendarFolder)
  1224. {
  1225. // Global
  1226. HRESULT hr = hrSuccess;
  1227. ecmem_ptr<SPropValue> lpPropValue, lpFBPropValue;
  1228. ULONG cValues = 0;
  1229. ULONG cCurValues = 0;
  1230. object_ptr<IMAPIFolder> lpFBFolder;
  1231. object_ptr<IMessage> lpFBMessage;
  1232. // Freebusy mv propery
  1233. // This property will be fill in on another place
  1234. hr = ECAllocateBuffer(sizeof(SPropValue), &~lpFBPropValue);
  1235. if(hr != hrSuccess)
  1236. return hr;
  1237. memset(lpFBPropValue, 0, sizeof(SPropValue));
  1238. lpFBPropValue->ulPropTag = PR_FREEBUSY_ENTRYIDS;
  1239. lpFBPropValue->Value.MVbin.cValues = 4;
  1240. hr = ECAllocateMore(sizeof(SBinary)*lpFBPropValue->Value.MVbin.cValues, lpFBPropValue, (void**)&lpFBPropValue->Value.MVbin.lpbin);
  1241. if(hr != hrSuccess)
  1242. return hr;
  1243. memset(lpFBPropValue->Value.MVbin.lpbin, 0, sizeof(SBinary)*lpFBPropValue->Value.MVbin.cValues);
  1244. // Create Freebusy Data into the rootfolder
  1245. // Folder for "freebusy data" settings
  1246. // Create the folder
  1247. hr = lpRootFolder->CreateFolder(FOLDER_GENERIC , (LPTSTR)"Freebusy Data", nullptr, &IID_IMAPIFolder, OPEN_IF_EXISTS, &~lpFBFolder);
  1248. if(hr != hrSuccess)
  1249. return hr;
  1250. // Get entryid of localfreebusy
  1251. hr = HrGetOneProp(lpFBFolder, PR_ENTRYID, &~lpPropValue);
  1252. if(hr != hrSuccess)
  1253. return hr;
  1254. //Fill in position 3 of the FBProperty, with free/busy data folder entryid
  1255. hr = ECAllocateMore(lpPropValue->Value.bin.cb, lpFBPropValue, (void**)&lpFBPropValue->Value.MVbin.lpbin[3].lpb);
  1256. if(hr != hrSuccess)
  1257. return hr;
  1258. lpFBPropValue->Value.MVbin.lpbin[3].cb = lpPropValue->Value.bin.cb;
  1259. memcpy(lpFBPropValue->Value.MVbin.lpbin[3].lpb, lpPropValue->Value.bin.lpb, lpPropValue->Value.bin.cb);
  1260. // Create localfreebusy message
  1261. // Default setting of free/busy
  1262. hr = lpFBFolder->CreateMessage(&IID_IMessage, 0, &~lpFBMessage);
  1263. if(hr != hrSuccess)
  1264. return hr;
  1265. cValues = 6;
  1266. cCurValues = 0;
  1267. hr = ECAllocateBuffer(sizeof(SPropValue) * cValues, &~lpPropValue);
  1268. if(hr != hrSuccess)
  1269. return hr;
  1270. lpPropValue[cCurValues].ulPropTag = PR_MESSAGE_CLASS_A;
  1271. lpPropValue[cCurValues++].Value.lpszA = const_cast<char *>("IPM.Microsoft.ScheduleData.FreeBusy");
  1272. lpPropValue[cCurValues].ulPropTag = PR_SUBJECT_A;
  1273. lpPropValue[cCurValues++].Value.lpszA = const_cast<char *>("LocalFreebusy");
  1274. lpPropValue[cCurValues].ulPropTag = PR_FREEBUSY_NUM_MONTHS;
  1275. lpPropValue[cCurValues++].Value.ul = ECFREEBUSY_DEFAULT_PUBLISH_MONTHS;
  1276. lpPropValue[cCurValues].ulPropTag = PR_DECLINE_RECURRING_MEETING_REQUESTS;
  1277. lpPropValue[cCurValues++].Value.b = false;
  1278. lpPropValue[cCurValues].ulPropTag = PR_DECLINE_CONFLICTING_MEETING_REQUESTS;
  1279. lpPropValue[cCurValues++].Value.b = false;
  1280. lpPropValue[cCurValues].ulPropTag = PR_PROCESS_MEETING_REQUESTS;
  1281. lpPropValue[cCurValues++].Value.b = false;
  1282. hr = lpFBMessage->SetProps(cCurValues, lpPropValue, NULL);
  1283. if(hr != hrSuccess)
  1284. return hr;
  1285. hr = lpFBMessage->SaveChanges(KEEP_OPEN_READONLY);
  1286. if(hr != hrSuccess)
  1287. return hr;
  1288. // Get entryid of localfreebusy
  1289. hr = HrGetOneProp(lpFBMessage, PR_ENTRYID, &~lpPropValue);
  1290. if(hr != hrSuccess)
  1291. return hr;
  1292. //Fill in position 1 of the FBProperty, with free/busy message entryid
  1293. hr = ECAllocateMore(lpPropValue->Value.bin.cb, lpFBPropValue, (void**)&lpFBPropValue->Value.MVbin.lpbin[1].lpb);
  1294. if(hr != hrSuccess)
  1295. return hr;
  1296. lpFBPropValue->Value.MVbin.lpbin[1].cb = lpPropValue->Value.bin.cb;
  1297. memcpy(lpFBPropValue->Value.MVbin.lpbin[1].lpb, lpPropValue->Value.bin.lpb, lpPropValue->Value.bin.cb);
  1298. // Create Associated localfreebusy message
  1299. hr = lpCalendarFolder->CreateMessage(&IID_IMessage, MAPI_ASSOCIATED, &~lpFBMessage);
  1300. if(hr != hrSuccess)
  1301. return hr;
  1302. cValues = 3;
  1303. cCurValues = 0;
  1304. hr = ECAllocateBuffer(sizeof(SPropValue) * cValues, &~lpPropValue);
  1305. if(hr != hrSuccess)
  1306. return hr;
  1307. lpPropValue[cCurValues].ulPropTag = PR_MESSAGE_CLASS_A;
  1308. lpPropValue[cCurValues++].Value.lpszA = const_cast<char *>("IPM.Microsoft.ScheduleData.FreeBusy");
  1309. lpPropValue[cCurValues].ulPropTag = PR_SUBJECT_A;
  1310. lpPropValue[cCurValues++].Value.lpszA = const_cast<char *>("LocalFreebusy");
  1311. lpPropValue[cCurValues].ulPropTag = PR_FREEBUSY_NUM_MONTHS;
  1312. lpPropValue[cCurValues++].Value.ul = ECFREEBUSY_DEFAULT_PUBLISH_MONTHS;
  1313. hr = lpFBMessage->SetProps(cCurValues, lpPropValue, NULL);
  1314. if(hr != hrSuccess)
  1315. return hr;
  1316. hr = lpFBMessage->SaveChanges(KEEP_OPEN_READONLY);
  1317. if(hr != hrSuccess)
  1318. return hr;
  1319. // Get entryid of associated localfreebusy
  1320. hr = HrGetOneProp(lpFBMessage, PR_ENTRYID, &~lpPropValue);
  1321. if(hr != hrSuccess)
  1322. return hr;
  1323. //Fill in position 0 of the FBProperty, with associated localfreebusy message entryid
  1324. hr = ECAllocateMore(lpPropValue->Value.bin.cb, lpFBPropValue, (void**)&lpFBPropValue->Value.MVbin.lpbin[0].lpb);
  1325. if(hr != hrSuccess)
  1326. return hr;
  1327. lpFBPropValue->Value.MVbin.lpbin[0].cb = lpPropValue->Value.bin.cb;
  1328. memcpy(lpFBPropValue->Value.MVbin.lpbin[0].lpb, lpPropValue->Value.bin.lpb, lpPropValue->Value.bin.cb);
  1329. // Add freebusy entryid on Inbox folder
  1330. hr = lpInboxFolder->SetProps(1, lpFBPropValue, NULL);
  1331. if(hr != hrSuccess)
  1332. return hr;
  1333. hr = lpInboxFolder->SaveChanges(KEEP_OPEN_READWRITE);
  1334. if(hr != hrSuccess)
  1335. return hr;
  1336. // Add freebusy entryid on the root folder
  1337. hr = lpRootFolder->SetProps(1, lpFBPropValue, NULL);
  1338. if(hr != hrSuccess)
  1339. return hr;
  1340. return lpRootFolder->SaveChanges(KEEP_OPEN_READWRITE);
  1341. }
  1342. /**
  1343. * Add a folder to the PR_IPM_OL2007_ENTRYIDS struct
  1344. *
  1345. * This appends the folder with the given type ID to the struct. No checking is performed on the
  1346. * data already in the property, it is just appended before the "\0\0\0\0" placeholder.
  1347. *
  1348. * @param lpFolder Folder to update the property in
  1349. * @param ulType Type ID to add
  1350. * @param lpEntryID EntryID of the folder to add
  1351. * @return result
  1352. */
  1353. HRESULT ECMsgStore::AddRenAdditionalFolder(IMAPIFolder *lpFolder, ULONG ulType, SBinary *lpEntryID)
  1354. {
  1355. memory_ptr<SPropValue> lpRenEntryIDs;
  1356. SPropValue sPropValue;
  1357. std::string strBuffer;
  1358. ULONG ulBlockType = RSF_ELID_ENTRYID;
  1359. if (HrGetOneProp(lpFolder, PR_IPM_OL2007_ENTRYIDS, &~lpRenEntryIDs) == hrSuccess)
  1360. strBuffer.assign((char *)lpRenEntryIDs->Value.bin.lpb, lpRenEntryIDs->Value.bin.cb);
  1361. // Remove trailing \0\0\0\0 if it's there
  1362. if(strBuffer.size() >= 4 && strBuffer.compare(strBuffer.size()-4, 4, "\0\0\0\0", 4) == 0)
  1363. strBuffer.resize(strBuffer.size()-4);
  1364. strBuffer.append((char *)&ulType, 2); //RSS Feeds type
  1365. strBuffer.append(1, ((lpEntryID->cb+4)&0xFF));
  1366. strBuffer.append(1, ((lpEntryID->cb+4)>>8)&0xFF);
  1367. strBuffer.append((char *)&ulBlockType, 2);
  1368. strBuffer.append(1, (lpEntryID->cb&0xFF));
  1369. strBuffer.append(1, (lpEntryID->cb>>8)&0xFF);
  1370. strBuffer.append((char*)lpEntryID->lpb, lpEntryID->cb);
  1371. strBuffer.append("\x00\x00\x00\x00", 4);
  1372. sPropValue.ulPropTag = PR_IPM_OL2007_ENTRYIDS;
  1373. sPropValue.Value.bin.cb = strBuffer.size();
  1374. sPropValue.Value.bin.lpb = (LPBYTE)strBuffer.data();
  1375. // Set on root folder
  1376. return lpFolder->SetProps(1, &sPropValue, NULL);
  1377. }
  1378. /**
  1379. * Create an outlook 2007/2010 additional folder
  1380. *
  1381. * This function creates an additional folder, and adds the folder entryid in the root folder
  1382. * and the inbox in the additional folders property.
  1383. *
  1384. * @param lpRootFolder Root folder of the store to set the property on
  1385. * @param lpInboxFolder Inbox folder of the store to set the property on
  1386. * @param lpSubTreeFolder Folder to create the folder in
  1387. * @param ulType Type ID For the additional folders struct
  1388. * @param lpszFolderName Folder name
  1389. * @param lpszComment Comment for the folder
  1390. * @param lpszContainerType Container type for the folder
  1391. * @param fHidden TRUE if the folder must be marked hidden with PR_ATTR_HIDDEN
  1392. * @return result
  1393. */
  1394. HRESULT ECMsgStore::CreateAdditionalFolder(IMAPIFolder *lpRootFolder,
  1395. IMAPIFolder *lpInboxFolder, IMAPIFolder *lpSubTreeFolder, ULONG ulType,
  1396. const TCHAR *lpszFolderName, const TCHAR *lpszComment,
  1397. const TCHAR *lpszContainerType, bool fHidden)
  1398. {
  1399. object_ptr<IMAPIFolder> lpMAPIFolder;
  1400. memory_ptr<SPropValue> lpPropValueEID;
  1401. SPropValue sPropValue;
  1402. HRESULT hr = lpSubTreeFolder->CreateFolder(FOLDER_GENERIC,
  1403. const_cast<LPTSTR>(lpszFolderName),
  1404. const_cast<LPTSTR>(lpszComment), &IID_IMAPIFolder,
  1405. OPEN_IF_EXISTS | fMapiUnicode, &~lpMAPIFolder);
  1406. if(hr != hrSuccess)
  1407. return hr;
  1408. // Get entryid of the folder
  1409. hr = HrGetOneProp(lpMAPIFolder, PR_ENTRYID, &~lpPropValueEID);
  1410. if(hr != hrSuccess)
  1411. return hr;
  1412. sPropValue.ulPropTag = PR_CONTAINER_CLASS;
  1413. sPropValue.Value.LPSZ = const_cast<LPTSTR>(lpszContainerType);
  1414. // Set container class
  1415. hr = HrSetOneProp(lpMAPIFolder, &sPropValue);
  1416. if(hr != hrSuccess)
  1417. return hr;
  1418. if(fHidden) {
  1419. sPropValue.ulPropTag = PR_ATTR_HIDDEN;
  1420. sPropValue.Value.b = true;
  1421. hr = HrSetOneProp(lpMAPIFolder, &sPropValue);
  1422. if(hr != hrSuccess)
  1423. return hr;
  1424. }
  1425. hr = AddRenAdditionalFolder(lpRootFolder, ulType, &lpPropValueEID->Value.bin);
  1426. if (hr != hrSuccess)
  1427. return hr;
  1428. return AddRenAdditionalFolder(lpInboxFolder, ulType, &lpPropValueEID->Value.bin);
  1429. }
  1430. HRESULT ECMsgStore::CreateStore(ULONG ulStoreType, ULONG cbUserId, LPENTRYID lpUserId, ULONG* lpcbStoreId, LPENTRYID* lppStoreId, ULONG* lpcbRootId, LPENTRYID *lppRootId)
  1431. {
  1432. HRESULT hr = hrSuccess;
  1433. object_ptr<WSTransport> lpTempTransport;
  1434. object_ptr<ECMsgStore> lpecMsgStore;
  1435. object_ptr<ECMAPIFolder> lpMapiFolderRoot;
  1436. /* Root container, IPM_SUBTREE and NON_IPM_SUBTREE */
  1437. object_ptr<IMAPIFolder> lpFolderRoot, lpFolderRootST, lpFolderRootNST;
  1438. object_ptr<IMAPIFolder> lpMAPIFolder, lpMAPIFolder2, lpMAPIFolder3;
  1439. object_ptr<IECPropStorage> lpStorage;
  1440. object_ptr<ECMAPIFolder> lpECMapiFolderInbox;
  1441. object_ptr<IMAPIFolder> lpInboxFolder, lpCalendarFolder;
  1442. ecmem_ptr<SPropValue> lpPropValue;
  1443. ULONG cValues = 0;
  1444. ULONG ulObjType = 0;
  1445. object_ptr<IECSecurity> lpECSecurity;
  1446. ECPERMISSION sPermission;
  1447. ecmem_ptr<ECUSER> lpECUser;
  1448. ecmem_ptr<ECCOMPANY> lpECCompany;
  1449. ecmem_ptr<ECGROUP> lpECGroup;
  1450. std::string strBuffer;
  1451. ULONG cbStoreId = 0;
  1452. LPENTRYID lpStoreId = NULL;
  1453. ULONG cbRootId = 0;
  1454. LPENTRYID lpRootId = NULL;
  1455. hr = CreateEmptyStore(ulStoreType, cbUserId, lpUserId, 0, &cbStoreId, &lpStoreId, &cbRootId, &lpRootId);
  1456. if (hr != hrSuccess)
  1457. return hr;
  1458. /*
  1459. * Create a temporary transport, because the new ECMsgStore object will
  1460. * logoff the transport, even if the refcount is not 0 yet. That would
  1461. * cause the current instance to lose its transport.
  1462. */
  1463. hr = lpTransport->CloneAndRelogon(&~lpTempTransport);
  1464. if (hr != hrSuccess)
  1465. return hr;
  1466. // Open the created messagestore
  1467. hr = ECMsgStore::Create("", lpSupport, lpTempTransport, true, MAPI_BEST_ACCESS, false, false, false, &~lpecMsgStore);
  1468. if (hr != hrSuccess)
  1469. //FIXME: wat te doen met de aangemaakte store ?
  1470. return hr;
  1471. if (ulStoreType == ECSTORE_TYPE_PRIVATE)
  1472. memcpy(&lpecMsgStore->m_guidMDB_Provider, &KOPANO_SERVICE_GUID, sizeof(MAPIUID));
  1473. else
  1474. memcpy(&lpecMsgStore->m_guidMDB_Provider, &KOPANO_STORE_PUBLIC_GUID, sizeof(MAPIUID));
  1475. // Get user or company information depending on the store type.
  1476. if (ulStoreType == ECSTORE_TYPE_PRIVATE)
  1477. hr = lpTransport->HrGetUser(cbUserId, lpUserId, 0, &~lpECUser);
  1478. else if (ABEID_ID(lpUserId) == 1)
  1479. /* Public store, ownership set to group EVERYONE*/
  1480. hr = lpTransport->HrGetGroup(cbUserId, lpUserId, 0, &~lpECGroup);
  1481. else
  1482. /* Public store, ownership set to company */
  1483. hr = lpTransport->HrGetCompany(cbUserId, lpUserId, 0, &~lpECCompany);
  1484. if (hr != hrSuccess)
  1485. return hr;
  1486. // Get a propstorage for the message store
  1487. hr = lpTransport->HrOpenPropStorage(0, NULL, cbStoreId, lpStoreId, 0, &~lpStorage);
  1488. if(hr != hrSuccess)
  1489. return hr;
  1490. // Set up the message store to use this storage
  1491. hr = lpecMsgStore->HrSetPropStorage(lpStorage, TRUE);
  1492. if(hr != hrSuccess)
  1493. return hr;
  1494. hr = lpecMsgStore->SetEntryId(cbStoreId, lpStoreId);
  1495. if(hr != hrSuccess)
  1496. return hr;
  1497. // Open rootfolder
  1498. hr = lpecMsgStore->OpenEntry(cbRootId, lpRootId, &IID_ECMAPIFolder, MAPI_MODIFY , &ulObjType, &~lpMapiFolderRoot);
  1499. if(hr != hrSuccess)
  1500. return hr;
  1501. // Set IPC folder
  1502. if(ulStoreType == ECSTORE_TYPE_PRIVATE) {
  1503. hr = lpecMsgStore->SetReceiveFolder((LPTSTR)"IPC", 0, cbRootId, lpRootId);
  1504. if(hr != hrSuccess)
  1505. return hr;
  1506. }
  1507. // Create Folder IPM_SUBTREE into the rootfolder
  1508. hr = lpMapiFolderRoot->QueryInterface(IID_IMAPIFolder, &~lpFolderRoot);
  1509. if(hr != hrSuccess)
  1510. return hr;
  1511. hr = CreateSpecialFolder(lpFolderRoot, lpecMsgStore, _T("IPM_SUBTREE"), _T(""), PR_IPM_SUBTREE_ENTRYID, 0, NULL, &~lpFolderRootST);
  1512. if(hr != hrSuccess)
  1513. return hr;
  1514. if(ulStoreType == ECSTORE_TYPE_PUBLIC) { // Public folder action
  1515. // Create Folder NON_IPM_SUBTREE into the rootfolder
  1516. hr = CreateSpecialFolder(lpFolderRoot, lpecMsgStore, _T("NON_IPM_SUBTREE"), _T(""), PR_NON_IPM_SUBTREE_ENTRYID, 0, NULL, &~lpFolderRootNST);
  1517. if (hr != hrSuccess)
  1518. return hr;
  1519. // Create Folder FINDER_ROOT into the rootfolder
  1520. hr = CreateSpecialFolder(lpFolderRoot, lpecMsgStore, _T("FINDER_ROOT"), _T(""), PR_FINDER_ENTRYID, 0, NULL, &~lpMAPIFolder3);
  1521. if (hr != hrSuccess)
  1522. return hr;
  1523. sPermission.ulRights = ecRightsFolderVisible|ecRightsReadAny|ecRightsCreateSubfolder|ecRightsEditOwned|ecRightsDeleteOwned;
  1524. sPermission.ulState = RIGHT_NEW|RIGHT_AUTOUPDATE_DENIED;
  1525. sPermission.ulType = ACCESS_TYPE_GRANT;
  1526. sPermission.sUserId.cb = g_cbEveryoneEid;
  1527. sPermission.sUserId.lpb = g_lpEveryoneEid;
  1528. hr = lpMAPIFolder3->QueryInterface(IID_IECSecurity, &~lpECSecurity);
  1529. if(hr != hrSuccess)
  1530. return hr;
  1531. hr = lpECSecurity->SetPermissionRules(1, &sPermission);
  1532. if (hr != hrSuccess)
  1533. return hr;
  1534. //Free busy time folder
  1535. hr = CreateSpecialFolder(lpFolderRootNST, lpecMsgStore,_T( "SCHEDULE+ FREE BUSY"), _T(""), PR_SPLUS_FREE_BUSY_ENTRYID, 0, NULL, &~lpMAPIFolder);
  1536. if(hr != hrSuccess)
  1537. return hr;
  1538. // Set acl's on the folder
  1539. sPermission.ulRights = ecRightsReadAny|ecRightsFolderVisible;
  1540. sPermission.ulState = RIGHT_NEW|RIGHT_AUTOUPDATE_DENIED;
  1541. sPermission.ulType = ACCESS_TYPE_GRANT;
  1542. sPermission.sUserId.cb = cbUserId;
  1543. sPermission.sUserId.lpb = (unsigned char*)lpUserId;
  1544. hr = lpMAPIFolder->QueryInterface(IID_IECSecurity, &~lpECSecurity);
  1545. if(hr != hrSuccess)
  1546. return hr;
  1547. hr = lpECSecurity->SetPermissionRules(1, &sPermission);
  1548. if(hr != hrSuccess)
  1549. return hr;
  1550. hr = CreateSpecialFolder(lpMAPIFolder, lpecMsgStore, _T("Zarafa 1"), _T(""), PR_FREE_BUSY_FOR_LOCAL_SITE_ENTRYID, 0, NULL, &~lpMAPIFolder2);
  1551. if(hr != hrSuccess)
  1552. return hr;
  1553. // Set acl's on the folder
  1554. sPermission.ulRights = ecRightsAll;//ecRightsReadAny| ecRightsCreate | ecRightsEditOwned| ecRightsDeleteOwned | ecRightsCreateSubfolder | ecRightsFolderVisible;
  1555. sPermission.ulState = RIGHT_NEW|RIGHT_AUTOUPDATE_DENIED;
  1556. sPermission.ulType = ACCESS_TYPE_GRANT;
  1557. sPermission.sUserId.cb = cbUserId;
  1558. sPermission.sUserId.lpb = (unsigned char*)lpUserId;
  1559. hr = lpMAPIFolder2->QueryInterface(IID_IECSecurity, &~lpECSecurity);
  1560. if(hr != hrSuccess)
  1561. return hr;
  1562. hr = lpECSecurity->SetPermissionRules(1, &sPermission);
  1563. if(hr != hrSuccess)
  1564. return hr;
  1565. // Set acl's on the IPM subtree folder
  1566. sPermission.ulRights = ecRightsReadAny| ecRightsCreate | ecRightsEditOwned| ecRightsDeleteOwned | ecRightsCreateSubfolder | ecRightsFolderVisible;
  1567. sPermission.ulState = RIGHT_NEW|RIGHT_AUTOUPDATE_DENIED;
  1568. sPermission.ulType = ACCESS_TYPE_GRANT;
  1569. sPermission.sUserId.cb = cbUserId;
  1570. sPermission.sUserId.lpb = (unsigned char*)lpUserId;
  1571. hr = lpFolderRootST->QueryInterface(IID_IECSecurity, &~lpECSecurity);
  1572. if (hr != hrSuccess)
  1573. return hr;
  1574. hr = lpECSecurity->SetPermissionRules(1, &sPermission);
  1575. if (hr != hrSuccess)
  1576. return hr;
  1577. // indicate, validity of the entry identifiers of the folders in a message store
  1578. // Public folder have default the mask
  1579. cValues = 2;
  1580. hr = ECAllocateBuffer(sizeof(SPropValue) * cValues, &~lpPropValue);
  1581. if (hr != hrSuccess)
  1582. return hr;
  1583. lpPropValue->ulPropTag = PR_VALID_FOLDER_MASK;
  1584. lpPropValue->Value.ul = FOLDER_FINDER_VALID | FOLDER_IPM_SUBTREE_VALID | FOLDER_IPM_INBOX_VALID | FOLDER_IPM_OUTBOX_VALID | FOLDER_IPM_WASTEBASKET_VALID | FOLDER_IPM_SENTMAIL_VALID | FOLDER_VIEWS_VALID | FOLDER_COMMON_VIEWS_VALID;
  1585. // Set store displayname
  1586. lpPropValue[1].ulPropTag = PR_DISPLAY_NAME_W;
  1587. lpPropValue[1].Value.lpszW = const_cast<wchar_t *>(L"Public folder"); //FIXME: set the right public folder name here?
  1588. // Set the property into the store
  1589. hr = lpecMsgStore->SetProps(cValues, lpPropValue, NULL);
  1590. if(hr != hrSuccess)
  1591. return hr;
  1592. }else if(ulStoreType == ECSTORE_TYPE_PRIVATE) { //Private folder
  1593. // Create Folder COMMON_VIEWS into the rootfolder
  1594. // folder holds views that are standard for the message store
  1595. hr = CreateSpecialFolder(lpFolderRoot, lpecMsgStore, _T("IPM_COMMON_VIEWS"), _T(""), PR_COMMON_VIEWS_ENTRYID, 0, NULL, NULL);
  1596. if(hr != hrSuccess)
  1597. return hr;
  1598. // Create Folder VIEWS into the rootfolder
  1599. // Personal: folder holds views that are defined by a particular user
  1600. hr = CreateSpecialFolder(lpFolderRoot, lpecMsgStore, _T("IPM_VIEWS"), _T(""), PR_VIEWS_ENTRYID, 0, NULL, NULL);
  1601. if(hr != hrSuccess)
  1602. return hr;
  1603. // Create Folder FINDER_ROOT into the rootfolder
  1604. hr = CreateSpecialFolder(lpFolderRoot, lpecMsgStore, _T("FINDER_ROOT"), _T(""), PR_FINDER_ENTRYID, 0, NULL, &~lpMAPIFolder3);
  1605. if(hr != hrSuccess)
  1606. return hr;
  1607. sPermission.ulRights = ecRightsFolderVisible|ecRightsReadAny|ecRightsCreateSubfolder|ecRightsEditOwned|ecRightsDeleteOwned;
  1608. sPermission.ulState = RIGHT_NEW|RIGHT_AUTOUPDATE_DENIED;
  1609. sPermission.ulType = ACCESS_TYPE_GRANT;
  1610. sPermission.sUserId.cb = g_cbEveryoneEid;
  1611. sPermission.sUserId.lpb = g_lpEveryoneEid;
  1612. hr = lpMAPIFolder3->QueryInterface(IID_IECSecurity, &~lpECSecurity);
  1613. if(hr != hrSuccess)
  1614. return hr;
  1615. hr = lpECSecurity->SetPermissionRules(1, &sPermission);
  1616. if(hr != hrSuccess)
  1617. return hr;
  1618. // Create Shortcuts
  1619. // Shortcuts for the favorites
  1620. hr = CreateSpecialFolder(lpFolderRoot, lpecMsgStore, _("Shortcut"), _T(""), PR_IPM_FAVORITES_ENTRYID, 0, NULL, NULL);
  1621. if(hr != hrSuccess)
  1622. return hr;
  1623. // Create Schedule folder
  1624. hr = CreateSpecialFolder(lpFolderRoot, lpecMsgStore, _T("Schedule"), _T(""), PR_SCHEDULE_FOLDER_ENTRYID, 0, NULL, NULL);
  1625. if(hr != hrSuccess)
  1626. return hr;
  1627. // Create folders into IPM_SUBTREE
  1628. // Folders like: Inbox, outbox, tasks, agenda, notes, trashcan, send items, contacts,concepts
  1629. // Create Inbox
  1630. hr = CreateSpecialFolder(lpFolderRootST, NULL, _("Inbox"), _T(""), 0, 0, NULL, &~lpInboxFolder);
  1631. if(hr != hrSuccess)
  1632. return hr;
  1633. // Get entryid of the folder
  1634. hr = HrGetOneProp(lpInboxFolder, PR_ENTRYID, &~lpPropValue);
  1635. if(hr != hrSuccess)
  1636. return hr;
  1637. hr = lpecMsgStore->SetReceiveFolder(NULL, 0, lpPropValue->Value.bin.cb, (LPENTRYID)lpPropValue->Value.bin.lpb);
  1638. if(hr != hrSuccess)
  1639. return hr;
  1640. hr = lpecMsgStore->SetReceiveFolder((LPTSTR)"IPM", 0, lpPropValue->Value.bin.cb, (LPENTRYID)lpPropValue->Value.bin.lpb);
  1641. if(hr != hrSuccess)
  1642. return hr;
  1643. hr = lpecMsgStore->SetReceiveFolder((LPTSTR)"REPORT.IPM", 0, lpPropValue->Value.bin.cb, (LPENTRYID)lpPropValue->Value.bin.lpb);
  1644. if(hr != hrSuccess)
  1645. return hr;
  1646. hr = lpInboxFolder->QueryInterface(IID_ECMAPIFolder, &~lpECMapiFolderInbox);
  1647. if(hr != hrSuccess)
  1648. return hr;
  1649. // Create Outbox
  1650. hr = CreateSpecialFolder(lpFolderRootST, lpecMsgStore, _("Outbox"), _T(""), PR_IPM_OUTBOX_ENTRYID, 0, NULL, NULL);
  1651. if(hr != hrSuccess)
  1652. return hr;
  1653. // Create Trashcan
  1654. hr = CreateSpecialFolder(lpFolderRootST, lpecMsgStore, _("Deleted Items"), _T(""), PR_IPM_WASTEBASKET_ENTRYID, 0, NULL, NULL);
  1655. if(hr != hrSuccess)
  1656. return hr;
  1657. // Create Sent Items
  1658. hr = CreateSpecialFolder(lpFolderRootST, lpecMsgStore, _("Sent Items"), _T(""), PR_IPM_SENTMAIL_ENTRYID, 0, NULL, NULL);
  1659. if(hr != hrSuccess)
  1660. return hr;
  1661. // Create Contacts
  1662. hr = CreateSpecialFolder(lpFolderRootST, lpECMapiFolderInbox, _("Contacts"), _T(""), PR_IPM_CONTACT_ENTRYID, 0, _T("IPF.Contact"), &~lpMAPIFolder);
  1663. if(hr != hrSuccess)
  1664. return hr;
  1665. hr = SetSpecialEntryIdOnFolder(lpMAPIFolder, lpMapiFolderRoot, PR_IPM_CONTACT_ENTRYID, 0);
  1666. if(hr != hrSuccess)
  1667. return hr;
  1668. // Create calendar
  1669. hr = CreateSpecialFolder(lpFolderRootST, lpECMapiFolderInbox, _("Calendar"), _T(""), PR_IPM_APPOINTMENT_ENTRYID, 0, _T("IPF.Appointment"), &~lpCalendarFolder);
  1670. if(hr != hrSuccess)
  1671. return hr;
  1672. hr = SetSpecialEntryIdOnFolder(lpCalendarFolder, lpMapiFolderRoot, PR_IPM_APPOINTMENT_ENTRYID, 0);
  1673. if(hr != hrSuccess)
  1674. return hr;
  1675. // Create Drafts
  1676. hr = CreateSpecialFolder(lpFolderRootST, lpECMapiFolderInbox, _("Drafts"), _T(""), PR_IPM_DRAFTS_ENTRYID, 0, _T("IPF.Note"), &~lpMAPIFolder);
  1677. if(hr != hrSuccess)
  1678. return hr;
  1679. hr = SetSpecialEntryIdOnFolder(lpMAPIFolder, lpMapiFolderRoot, PR_IPM_DRAFTS_ENTRYID, 0);
  1680. if(hr != hrSuccess)
  1681. return hr;
  1682. // Create journal
  1683. hr = CreateSpecialFolder(lpFolderRootST, lpECMapiFolderInbox, _("Journal"), _T(""), PR_IPM_JOURNAL_ENTRYID, 0, _T("IPF.Journal"), &~lpMAPIFolder);
  1684. if(hr != hrSuccess)
  1685. return hr;
  1686. hr = SetSpecialEntryIdOnFolder(lpMAPIFolder, lpMapiFolderRoot, PR_IPM_JOURNAL_ENTRYID, 0);
  1687. if(hr != hrSuccess)
  1688. return hr;
  1689. // Create Notes
  1690. hr = CreateSpecialFolder(lpFolderRootST, lpECMapiFolderInbox, _("Notes"), _T(""), PR_IPM_NOTE_ENTRYID, 0, _T("IPF.StickyNote"), &~lpMAPIFolder);
  1691. if(hr != hrSuccess)
  1692. return hr;
  1693. hr = SetSpecialEntryIdOnFolder(lpMAPIFolder, lpMapiFolderRoot, PR_IPM_NOTE_ENTRYID, 0);
  1694. if(hr != hrSuccess)
  1695. return hr;
  1696. // Create Tasks
  1697. hr = CreateSpecialFolder(lpFolderRootST, lpECMapiFolderInbox, _("Tasks"), _T(""), PR_IPM_TASK_ENTRYID, 0, _T("IPF.Task"), &~lpMAPIFolder);
  1698. if(hr != hrSuccess)
  1699. return hr;
  1700. hr = SetSpecialEntryIdOnFolder(lpMAPIFolder, lpMapiFolderRoot, PR_IPM_TASK_ENTRYID, 0);
  1701. if(hr != hrSuccess)
  1702. return hr;
  1703. // Create Junk mail (position 5(4 in array) in the mvprop PR_ADDITIONAL_REN_ENTRYIDS)
  1704. hr = CreateSpecialFolder(lpFolderRootST, lpECMapiFolderInbox, _("Junk E-mail"), _T(""), PR_ADDITIONAL_REN_ENTRYIDS, 4, _T("IPF.Note"), &~lpMAPIFolder);
  1705. if(hr != hrSuccess)
  1706. return hr;
  1707. hr = SetSpecialEntryIdOnFolder(lpMAPIFolder, lpMapiFolderRoot, PR_ADDITIONAL_REN_ENTRYIDS, 4);
  1708. if(hr != hrSuccess)
  1709. return hr;
  1710. // Create Freebusy folder data
  1711. hr = CreatePrivateFreeBusyData(lpFolderRoot, lpInboxFolder, lpCalendarFolder);
  1712. if(hr != hrSuccess)
  1713. return hr;
  1714. // Create Outlook 2007/2010 Additional folders
  1715. hr = CreateAdditionalFolder(lpFolderRoot, lpInboxFolder, lpFolderRootST, RSF_PID_RSS_SUBSCRIPTION, _("RSS Feeds"), _("RSS Feed comment"), _T("IPF.Note.OutlookHomepage"), false);
  1716. if(hr != hrSuccess)
  1717. return hr;
  1718. hr = CreateAdditionalFolder(lpFolderRoot, lpInboxFolder, lpFolderRootST, RSF_PID_CONV_ACTIONS, _("Conversation Action Settings"), _T(""), _T("IPF.Configuration"), true);
  1719. if(hr != hrSuccess)
  1720. return hr;
  1721. hr = CreateAdditionalFolder(lpFolderRoot, lpInboxFolder, lpFolderRootST, RSF_PID_COMBINED_ACTIONS, _("Quick Step Settings"), _T(""), _T("IPF.Configuration"), true);
  1722. if(hr != hrSuccess)
  1723. return hr;
  1724. hr = CreateAdditionalFolder(lpFolderRoot, lpInboxFolder, lpFolderRootST, RSF_PID_SUGGESTED_CONTACTS, _("Suggested Contacts"), _T(""), _T("IPF.Contact"), false);
  1725. if(hr != hrSuccess)
  1726. return hr;
  1727. // indicate, validity of the entry identifiers of the folders in a message store
  1728. cValues = 1;
  1729. hr = ECAllocateBuffer(sizeof(SPropValue) * cValues, &~lpPropValue);
  1730. if (hr != hrSuccess)
  1731. return hr;
  1732. lpPropValue[0].ulPropTag = PR_VALID_FOLDER_MASK;
  1733. lpPropValue[0].Value.ul = FOLDER_VIEWS_VALID | FOLDER_COMMON_VIEWS_VALID|FOLDER_FINDER_VALID | FOLDER_IPM_INBOX_VALID | FOLDER_IPM_OUTBOX_VALID | FOLDER_IPM_SENTMAIL_VALID | FOLDER_IPM_SUBTREE_VALID | FOLDER_IPM_WASTEBASKET_VALID;
  1734. // Set the property into the store
  1735. hr = lpecMsgStore->SetProps(cValues, lpPropValue, NULL);
  1736. if(hr != hrSuccess)
  1737. return hr;
  1738. }
  1739. *lpcbStoreId = cbStoreId;
  1740. *lppStoreId = lpStoreId;
  1741. *lpcbRootId = cbRootId;
  1742. *lppRootId = lpRootId;
  1743. return hrSuccess;
  1744. }
  1745. /**
  1746. * Create a new store that contains nothing boot the root folder.
  1747. *
  1748. * @param[in] ulStoreType
  1749. * The required store type to create. Valid values are ECSTORE_TYPE_PUBLIC and ECSTORE_TYPE_PRIVATE.
  1750. * @param[in] cbUserId
  1751. * The size of the user entryid of the user for whom the store will be created.
  1752. * @param[in] lpUserId
  1753. * Pointer to the entryid of the user for whom the store will be created.
  1754. * @param[in] ulFlags
  1755. * Flags passed to HrCreateStore
  1756. * @param[in,out] lpcbStoreId
  1757. * Pointer to a ULONG value that contains the size of the store entryid.
  1758. * @param[in,out] lppStoreId
  1759. * Pointer to a an entryid pointer that points to the store entryid.
  1760. * @param[in,out] lpcbRootId
  1761. * Pointer to a ULONG value that contains the size of the root entryid.
  1762. * @param[in,out] lppRootId
  1763. * Pointer to an entryid pointer that points to the root entryid.
  1764. *
  1765. * @remarks
  1766. * lpcbStoreId, lppStoreId, lpcbRootId and lppRootId are optional. But if a root id is specified, the store id must
  1767. * also be specified. A store id however may be passed without passing a root id.
  1768. */
  1769. HRESULT ECMsgStore::CreateEmptyStore(ULONG ulStoreType, ULONG cbUserId, LPENTRYID lpUserId, ULONG ulFlags, ULONG* lpcbStoreId, LPENTRYID* lppStoreId, ULONG* lpcbRootId, LPENTRYID* lppRootId)
  1770. {
  1771. HRESULT hr = hrSuccess;
  1772. ULONG cbStoreId = 0;
  1773. LPENTRYID lpStoreId = NULL;
  1774. ULONG cbRootId = 0;
  1775. LPENTRYID lpRootId = NULL;
  1776. GUID guidStore;
  1777. // Check requested store type
  1778. if (!ECSTORE_TYPE_ISVALID(ulStoreType) ||
  1779. (ulFlags != 0 && ulFlags != EC_OVERRIDE_HOMESERVER))
  1780. {
  1781. hr = MAPI_E_INVALID_PARAMETER;
  1782. goto exit;
  1783. }
  1784. // Check passed store and root entry ids.
  1785. if (!lpcbStoreId || !lppStoreId || !lpcbRootId || !lppRootId) {
  1786. hr = MAPI_E_INVALID_PARAMETER;
  1787. goto exit;
  1788. }
  1789. if (!*lpcbStoreId != !*lppStoreId) { // One set, one unset
  1790. hr = MAPI_E_INVALID_PARAMETER;
  1791. goto exit;
  1792. }
  1793. if (!*lpcbRootId != !*lppRootId) { // One set, one unset
  1794. hr = MAPI_E_INVALID_PARAMETER;
  1795. goto exit;
  1796. }
  1797. if (*lppRootId && !*lppStoreId) { // Root id set, but storeid unset
  1798. hr = MAPI_E_INVALID_PARAMETER;
  1799. goto exit;
  1800. }
  1801. if ((*lpcbStoreId == 0 || *lpcbRootId == 0) && CoCreateGuid(&guidStore) != S_OK) {
  1802. hr = MAPI_E_CALL_FAILED;
  1803. goto exit;
  1804. }
  1805. if (*lpcbStoreId == 0) {
  1806. // Create store entryid
  1807. hr = HrCreateEntryId(guidStore, MAPI_STORE, &cbStoreId, &lpStoreId);
  1808. if (hr != hrSuccess)
  1809. goto exit;
  1810. } else {
  1811. ULONG cbTmp = 0;
  1812. LPENTRYID lpTmp = NULL;
  1813. hr = UnWrapStoreEntryID(*lpcbStoreId, *lppStoreId, &cbTmp, &lpTmp);
  1814. if (hr == MAPI_E_INVALID_ENTRYID) { // Could just be a non-wrapped entryid
  1815. cbTmp = *lpcbStoreId;
  1816. lpTmp = *lppStoreId;
  1817. }
  1818. hr = UnWrapServerClientStoreEntry(cbTmp, lpTmp, &cbStoreId, &lpStoreId);
  1819. if (hr != hrSuccess) {
  1820. if (lpTmp != *lppStoreId)
  1821. MAPIFreeBuffer(lpTmp);
  1822. goto exit;
  1823. }
  1824. }
  1825. if (*lpcbRootId == 0) {
  1826. // create root entryid
  1827. hr = HrCreateEntryId(guidStore, MAPI_FOLDER, &cbRootId, &lpRootId);
  1828. if (hr != hrSuccess)
  1829. goto exit;
  1830. } else {
  1831. cbRootId = *lpcbRootId;
  1832. lpRootId = *lppRootId;
  1833. }
  1834. // Create the messagestore
  1835. hr = lpTransport->HrCreateStore(ulStoreType, cbUserId, lpUserId, cbStoreId, lpStoreId, cbRootId, lpRootId, ulFlags);
  1836. if (hr != hrSuccess)
  1837. goto exit;
  1838. if (*lppStoreId == 0) {
  1839. *lpcbStoreId = cbStoreId;
  1840. *lppStoreId = lpStoreId;
  1841. lpStoreId = NULL;
  1842. }
  1843. if (*lpcbRootId == 0) {
  1844. *lpcbRootId = cbRootId;
  1845. *lppRootId = lpRootId;
  1846. lpRootId = NULL;
  1847. }
  1848. exit:
  1849. if (lpcbStoreId != NULL && *lpcbStoreId == 0)
  1850. MAPIFreeBuffer(lpStoreId);
  1851. if (lpcbStoreId != NULL && *lpcbStoreId == 0)
  1852. MAPIFreeBuffer(lpRootId);
  1853. return hr;
  1854. }
  1855. HRESULT ECMsgStore::HookStore(ULONG ulStoreType, ULONG cbUserId, LPENTRYID lpUserId, LPGUID lpGuid)
  1856. {
  1857. return lpTransport->HrHookStore(ulStoreType, cbUserId, lpUserId, lpGuid, 0);
  1858. }
  1859. HRESULT ECMsgStore::UnhookStore(ULONG ulStoreType, ULONG cbUserId, LPENTRYID lpUserId)
  1860. {
  1861. return lpTransport->HrUnhookStore(ulStoreType, cbUserId, lpUserId, 0);
  1862. }
  1863. HRESULT ECMsgStore::RemoveStore(LPGUID lpGuid)
  1864. {
  1865. return lpTransport->HrRemoveStore(lpGuid, 0);
  1866. }
  1867. HRESULT ECMsgStore::ResolveStore(LPGUID lpGuid, ULONG *lpulUserID, ULONG* lpcbStoreID, LPENTRYID* lppStoreID)
  1868. {
  1869. ULONG cbStoreEntryID = 0;
  1870. memory_ptr<ENTRYID> lpStoreEntryID;
  1871. HRESULT hr = lpTransport->HrResolveStore(lpGuid, lpulUserID, &cbStoreEntryID, &~lpStoreEntryID);
  1872. if (hr != hrSuccess)
  1873. return hr;
  1874. return WrapStoreEntryID(0, (LPTSTR)WCLIENT_DLL_NAME, cbStoreEntryID,
  1875. lpStoreEntryID, lpcbStoreID, lppStoreID);
  1876. }
  1877. HRESULT ECMsgStore::SetSpecialEntryIdOnFolder(LPMAPIFOLDER lpFolder, ECMAPIProp *lpFolderPropSet, unsigned int ulPropTag, unsigned int ulMVPos)
  1878. {
  1879. ecmem_ptr<SPropValue> lpPropValue, lpPropMVValueNew;
  1880. LPSPropValue lpPropMVValue = NULL;
  1881. // Get entryid of the folder
  1882. HRESULT hr = HrGetOneProp(lpFolder, PR_ENTRYID, &~lpPropValue);
  1883. if(hr != hrSuccess)
  1884. return hr;
  1885. if (PROP_TYPE(ulPropTag) & MV_FLAG) {
  1886. hr = ECAllocateBuffer(sizeof(SPropValue), &~lpPropMVValueNew);
  1887. if (hr != hrSuccess)
  1888. return hr;
  1889. memset(lpPropMVValueNew, 0, sizeof(SPropValue));
  1890. hr = HrGetOneProp(lpFolder, ulPropTag, &lpPropMVValue);
  1891. if(hr != hrSuccess) {
  1892. lpPropMVValueNew->Value.MVbin.cValues = (ulMVPos+1);
  1893. hr = ECAllocateMore(sizeof(SBinary) * lpPropMVValueNew->Value.MVbin.cValues, lpPropMVValueNew,
  1894. reinterpret_cast<void **>(&lpPropMVValueNew->Value.MVbin.lpbin));
  1895. if (hr != hrSuccess)
  1896. return hr;
  1897. memset(lpPropMVValueNew->Value.MVbin.lpbin, 0, sizeof(SBinary)*lpPropMVValueNew->Value.MVbin.cValues);
  1898. for (unsigned int i = 0; i <lpPropMVValueNew->Value.MVbin.cValues; ++i)
  1899. if(ulMVPos == i)
  1900. lpPropMVValueNew->Value.MVbin.lpbin[i] = lpPropValue->Value.bin;
  1901. }else{
  1902. lpPropMVValueNew->Value.MVbin.cValues = (lpPropMVValue->Value.MVbin.cValues < ulMVPos)? lpPropValue->Value.bin.cb : ulMVPos+1;
  1903. hr = ECAllocateMore(sizeof(SBinary) * lpPropMVValueNew->Value.MVbin.cValues, lpPropMVValueNew,
  1904. reinterpret_cast<void **>(&lpPropMVValueNew->Value.MVbin.lpbin));
  1905. if (hr != hrSuccess)
  1906. return hr;
  1907. memset(lpPropMVValueNew->Value.MVbin.lpbin, 0, sizeof(SBinary)*lpPropMVValueNew->Value.MVbin.cValues);
  1908. for (unsigned int i = 0; i < lpPropMVValueNew->Value.MVbin.cValues; ++i)
  1909. if(ulMVPos == i)
  1910. lpPropMVValueNew->Value.MVbin.lpbin[i] = lpPropValue->Value.bin;
  1911. else
  1912. lpPropMVValueNew->Value.MVbin.lpbin[i] = lpPropMVValue->Value.MVbin.lpbin[i];
  1913. }
  1914. lpPropMVValueNew->ulPropTag = ulPropTag;
  1915. // Set the property into the right folder
  1916. hr = lpFolderPropSet->SetProps(1, lpPropMVValueNew, NULL);
  1917. if (hr != hrSuccess)
  1918. return hr;
  1919. }else{
  1920. // Set the property tag value
  1921. lpPropValue->ulPropTag = ulPropTag;
  1922. // Set the property into the right folder
  1923. hr = lpFolderPropSet->SetProps(1, lpPropValue, NULL);
  1924. if(hr != hrSuccess)
  1925. return hr;
  1926. }
  1927. return hrSuccess;
  1928. }
  1929. HRESULT ECMsgStore::CreateSpecialFolder(LPMAPIFOLDER lpFolderParent,
  1930. ECMAPIProp *lpFolderPropSet, const TCHAR *lpszFolderName,
  1931. const TCHAR *lpszFolderComment, unsigned int ulPropTag,
  1932. unsigned int ulMVPos, const TCHAR *lpszContainerClass,
  1933. LPMAPIFOLDER *lppMAPIFolder)
  1934. {
  1935. HRESULT hr = hrSuccess;
  1936. object_ptr<IMAPIFolder> lpMAPIFolder;
  1937. ecmem_ptr<SPropValue> lpPropValue;
  1938. if (lpFolderParent == NULL)
  1939. return MAPI_E_INVALID_PARAMETER;
  1940. // Add a referention at the folders
  1941. lpFolderParent->AddRef();
  1942. if (lpFolderPropSet != nullptr)
  1943. lpFolderPropSet->AddRef();
  1944. // Create the folder
  1945. hr = lpFolderParent->CreateFolder(FOLDER_GENERIC,
  1946. const_cast<LPTSTR>(lpszFolderName),
  1947. const_cast<LPTSTR>(lpszFolderComment), &IID_IMAPIFolder,
  1948. OPEN_IF_EXISTS | fMapiUnicode, &~lpMAPIFolder);
  1949. if(hr != hrSuccess)
  1950. goto exit;
  1951. // Set the special property
  1952. if(lpFolderPropSet) {
  1953. hr = SetSpecialEntryIdOnFolder(lpMAPIFolder, lpFolderPropSet, ulPropTag, ulMVPos);
  1954. if(hr != hrSuccess)
  1955. goto exit;
  1956. }
  1957. if (lpszContainerClass && _tcslen(lpszContainerClass) > 0) {
  1958. hr = ECAllocateBuffer(sizeof(SPropValue), &~lpPropValue);
  1959. if (hr != hrSuccess)
  1960. goto exit;
  1961. lpPropValue[0].ulPropTag = PR_CONTAINER_CLASS;
  1962. hr = ECAllocateMore((_tcslen(lpszContainerClass) + 1) * sizeof(TCHAR), lpPropValue,
  1963. reinterpret_cast<void **>(&lpPropValue[0].Value.LPSZ));
  1964. if (hr != hrSuccess)
  1965. goto exit;
  1966. _tcscpy(lpPropValue[0].Value.LPSZ, lpszContainerClass);
  1967. // Set the property
  1968. hr = lpMAPIFolder->SetProps(1, lpPropValue, NULL);
  1969. if(hr != hrSuccess)
  1970. goto exit;
  1971. }
  1972. if(lppMAPIFolder) {
  1973. hr = lpMAPIFolder->QueryInterface(IID_IMAPIFolder, (void**)lppMAPIFolder);
  1974. if(hr != hrSuccess)
  1975. goto exit;
  1976. }
  1977. exit:
  1978. if(lpFolderParent)
  1979. lpFolderParent->Release();
  1980. if(lpFolderPropSet)
  1981. lpFolderPropSet->Release();
  1982. return hr;
  1983. }
  1984. HRESULT ECMsgStore::CreateUser(ECUSER *lpECUser, ULONG ulFlags,
  1985. ULONG *lpcbUserId, LPENTRYID *lppUserId)
  1986. {
  1987. return lpTransport->HrCreateUser(lpECUser, ulFlags, lpcbUserId, lppUserId);
  1988. }
  1989. HRESULT ECMsgStore::SetUser(ECUSER *lpECUser, ULONG ulFlags)
  1990. {
  1991. return lpTransport->HrSetUser(lpECUser, ulFlags);
  1992. }
  1993. HRESULT ECMsgStore::GetUser(ULONG cbUserId, LPENTRYID lpUserId, ULONG ulFlags,
  1994. ECUSER **lppECUser)
  1995. {
  1996. return lpTransport->HrGetUser(cbUserId, lpUserId, ulFlags, lppECUser);
  1997. }
  1998. HRESULT ECMsgStore::DeleteUser(ULONG cbUserId, LPENTRYID lpUserId)
  1999. {
  2000. return lpTransport->HrDeleteUser(cbUserId, lpUserId);
  2001. }
  2002. HRESULT ECMsgStore::ResolveUserName(LPCTSTR lpszUserName, ULONG ulFlags, ULONG *lpcbUserId, LPENTRYID *lppUserId)
  2003. {
  2004. return lpTransport->HrResolveUserName(lpszUserName, ulFlags, lpcbUserId, lppUserId);
  2005. }
  2006. HRESULT ECMsgStore::GetSendAsList(ULONG cbUserId, LPENTRYID lpUserId,
  2007. ULONG ulFlags, ULONG *lpcSenders, ECUSER **lppSenders)
  2008. {
  2009. return lpTransport->HrGetSendAsList(cbUserId, lpUserId, ulFlags, lpcSenders, lppSenders);
  2010. }
  2011. HRESULT ECMsgStore::AddSendAsUser(ULONG cbUserId, LPENTRYID lpUserId, ULONG cbSenderId, LPENTRYID lpSenderId)
  2012. {
  2013. return lpTransport->HrAddSendAsUser(cbUserId, lpUserId, cbSenderId, lpSenderId);
  2014. }
  2015. HRESULT ECMsgStore::DelSendAsUser(ULONG cbUserId, LPENTRYID lpUserId, ULONG cbSenderId, LPENTRYID lpSenderId)
  2016. {
  2017. return lpTransport->HrDelSendAsUser(cbUserId, lpUserId, cbSenderId, lpSenderId);
  2018. }
  2019. HRESULT ECMsgStore::GetUserClientUpdateStatus(ULONG cbUserId,
  2020. LPENTRYID lpUserId, ULONG ulFlags, ECUSERCLIENTUPDATESTATUS **lppECUCUS)
  2021. {
  2022. return lpTransport->HrGetUserClientUpdateStatus(cbUserId, lpUserId, ulFlags, lppECUCUS);
  2023. }
  2024. HRESULT ECMsgStore::RemoveAllObjects(ULONG cbUserId, LPENTRYID lpUserId)
  2025. {
  2026. return lpTransport->HrRemoveAllObjects(cbUserId, lpUserId);
  2027. }
  2028. HRESULT ECMsgStore::ResolveGroupName(LPCTSTR lpszGroupName, ULONG ulFlags, ULONG *lpcbGroupId, LPENTRYID *lppGroupId)
  2029. {
  2030. return lpTransport->HrResolveGroupName(lpszGroupName, ulFlags, lpcbGroupId, lppGroupId);
  2031. }
  2032. HRESULT ECMsgStore::CreateGroup(ECGROUP *lpECGroup, ULONG ulFlags,
  2033. ULONG *lpcbGroupId, LPENTRYID *lppGroupId)
  2034. {
  2035. return lpTransport->HrCreateGroup(lpECGroup, ulFlags, lpcbGroupId, lppGroupId);
  2036. }
  2037. HRESULT ECMsgStore::SetGroup(ECGROUP *lpECGroup, ULONG ulFlags)
  2038. {
  2039. return lpTransport->HrSetGroup(lpECGroup, ulFlags);
  2040. }
  2041. HRESULT ECMsgStore::GetGroup(ULONG cbGroupId, LPENTRYID lpGroupId,
  2042. ULONG ulFlags, ECGROUP **lppECGroup)
  2043. {
  2044. return lpTransport->HrGetGroup(cbGroupId, lpGroupId, ulFlags, lppECGroup);
  2045. }
  2046. HRESULT ECMsgStore::DeleteGroup(ULONG cbGroupId, LPENTRYID lpGroupId)
  2047. {
  2048. return lpTransport->HrDeleteGroup(cbGroupId, lpGroupId);
  2049. }
  2050. //Group and user functions
  2051. HRESULT ECMsgStore::DeleteGroupUser(ULONG cbGroupId, LPENTRYID lpGroupId, ULONG cbUserId, LPENTRYID lpUserId)
  2052. {
  2053. return lpTransport->HrDeleteGroupUser(cbGroupId, lpGroupId, cbUserId, lpUserId);
  2054. }
  2055. HRESULT ECMsgStore::AddGroupUser(ULONG cbGroupId, LPENTRYID lpGroupId, ULONG cbUserId, LPENTRYID lpUserId)
  2056. {
  2057. return lpTransport->HrAddGroupUser(cbGroupId, lpGroupId, cbUserId, lpUserId);
  2058. }
  2059. HRESULT ECMsgStore::GetUserListOfGroup(ULONG cbGroupId, LPENTRYID lpGroupId,
  2060. ULONG ulFlags, ULONG *lpcUsers, ECUSER **lppsUsers)
  2061. {
  2062. return lpTransport->HrGetUserListOfGroup(cbGroupId, lpGroupId, ulFlags, lpcUsers, lppsUsers);
  2063. }
  2064. HRESULT ECMsgStore::GetGroupListOfUser(ULONG cbUserId, LPENTRYID lpUserId,
  2065. ULONG ulFlags, ULONG *lpcGroups, ECGROUP **lppsGroups)
  2066. {
  2067. return lpTransport->HrGetGroupListOfUser(cbUserId, lpUserId, ulFlags, lpcGroups, lppsGroups);
  2068. }
  2069. HRESULT ECMsgStore::CreateCompany(ECCOMPANY *lpECCompany, ULONG ulFlags,
  2070. ULONG *lpcbCompanyId, LPENTRYID *lppCompanyId)
  2071. {
  2072. return lpTransport->HrCreateCompany(lpECCompany, ulFlags, lpcbCompanyId, lppCompanyId);
  2073. }
  2074. HRESULT ECMsgStore::DeleteCompany(ULONG cbCompanyId, LPENTRYID lpCompanyId)
  2075. {
  2076. return lpTransport->HrDeleteCompany(cbCompanyId, lpCompanyId);
  2077. }
  2078. HRESULT ECMsgStore::SetCompany(ECCOMPANY *lpECCompany, ULONG ulFlags)
  2079. {
  2080. return lpTransport->HrSetCompany(lpECCompany, ulFlags);
  2081. }
  2082. HRESULT ECMsgStore::GetCompany(ULONG cbCompanyId, LPENTRYID lpCompanyId,
  2083. ULONG ulFlags, ECCOMPANY **lppECCompany)
  2084. {
  2085. return lpTransport->HrGetCompany(cbCompanyId, lpCompanyId, ulFlags, lppECCompany);
  2086. }
  2087. HRESULT ECMsgStore::ResolveCompanyName(LPCTSTR lpszCompanyName, ULONG ulFlags, ULONG *lpcbCompanyId, LPENTRYID *lppCompanyId)
  2088. {
  2089. return lpTransport->HrResolveCompanyName(lpszCompanyName, ulFlags, lpcbCompanyId, lppCompanyId);
  2090. }
  2091. HRESULT ECMsgStore::GetCompanyList(ULONG ulFlags, ULONG *lpcCompanies,
  2092. ECCOMPANY **lppsCompanies)
  2093. {
  2094. return lpTransport->HrGetCompanyList(ulFlags, lpcCompanies, lppsCompanies);
  2095. }
  2096. HRESULT ECMsgStore::AddCompanyToRemoteViewList(ULONG cbSetCompanyId, LPENTRYID lpSetCompanyId, ULONG cbCompanyId, LPENTRYID lpCompanyId)
  2097. {
  2098. return lpTransport->HrAddCompanyToRemoteViewList(cbSetCompanyId, lpSetCompanyId, cbCompanyId, lpCompanyId);
  2099. }
  2100. HRESULT ECMsgStore::DelCompanyFromRemoteViewList(ULONG cbSetCompanyId, LPENTRYID lpSetCompanyId, ULONG cbCompanyId, LPENTRYID lpCompanyId)
  2101. {
  2102. return lpTransport->HrDelCompanyFromRemoteViewList(cbSetCompanyId, lpSetCompanyId, cbCompanyId, lpCompanyId);
  2103. }
  2104. HRESULT ECMsgStore::GetRemoteViewList(ULONG cbCompanyId, LPENTRYID lpCompanyId,
  2105. ULONG ulFlags, ULONG *lpcCompanies, ECCOMPANY **lppsCompanies)
  2106. {
  2107. return lpTransport->HrGetRemoteViewList(cbCompanyId, lpCompanyId, ulFlags, lpcCompanies, lppsCompanies);
  2108. }
  2109. HRESULT ECMsgStore::AddUserToRemoteAdminList(ULONG cbUserId, LPENTRYID lpUserId, ULONG cbCompanyId, LPENTRYID lpCompanyId)
  2110. {
  2111. return lpTransport->HrAddUserToRemoteAdminList(cbUserId, lpUserId, cbCompanyId, lpCompanyId);
  2112. }
  2113. HRESULT ECMsgStore::DelUserFromRemoteAdminList(ULONG cbUserId, LPENTRYID lpUserId, ULONG cbCompanyId, LPENTRYID lpCompanyId)
  2114. {
  2115. return lpTransport->HrDelUserFromRemoteAdminList(cbUserId, lpUserId, cbCompanyId, lpCompanyId);
  2116. }
  2117. HRESULT ECMsgStore::GetRemoteAdminList(ULONG cbCompanyId,
  2118. LPENTRYID lpCompanyId, ULONG ulFlags, ULONG *lpcUsers, ECUSER **lppsUsers)
  2119. {
  2120. return lpTransport->HrGetRemoteAdminList(cbCompanyId, lpCompanyId, ulFlags, lpcUsers, lppsUsers);
  2121. }
  2122. HRESULT ECMsgStore::SyncUsers(ULONG cbCompanyId, LPENTRYID lpCompanyId)
  2123. {
  2124. return lpTransport->HrSyncUsers(cbCompanyId, lpCompanyId);
  2125. }
  2126. HRESULT ECMsgStore::GetQuota(ULONG cbUserId, LPENTRYID lpUserId,
  2127. bool bGetUserDefault, ECQUOTA **lppsQuota)
  2128. {
  2129. return lpTransport->GetQuota(cbUserId, lpUserId, bGetUserDefault, lppsQuota);
  2130. }
  2131. HRESULT ECMsgStore::SetQuota(ULONG cbUserId, LPENTRYID lpUserId,
  2132. ECQUOTA *lpsQuota)
  2133. {
  2134. return lpTransport->SetQuota(cbUserId, lpUserId, lpsQuota);
  2135. }
  2136. HRESULT ECMsgStore::AddQuotaRecipient(ULONG cbCompanyId, LPENTRYID lpCompanyId, ULONG cbRecipientId, LPENTRYID lpRecipientId, ULONG ulType)
  2137. {
  2138. return lpTransport->AddQuotaRecipient(cbCompanyId, lpCompanyId, cbRecipientId, lpRecipientId, ulType);
  2139. }
  2140. HRESULT ECMsgStore::DeleteQuotaRecipient(ULONG cbCompanyId, LPENTRYID lpCmopanyId, ULONG cbRecipientId, LPENTRYID lpRecipientId, ULONG ulType)
  2141. {
  2142. return lpTransport->DeleteQuotaRecipient(cbCompanyId, lpCmopanyId, cbRecipientId, lpRecipientId, ulType);
  2143. }
  2144. HRESULT ECMsgStore::GetQuotaRecipients(ULONG cbUserId, LPENTRYID lpUserId,
  2145. ULONG ulFlags, ULONG *lpcUsers, ECUSER **lppsUsers)
  2146. {
  2147. return lpTransport->GetQuotaRecipients(cbUserId, lpUserId, ulFlags, lpcUsers, lppsUsers);
  2148. }
  2149. HRESULT ECMsgStore::GetQuotaStatus(ULONG cbUserId, LPENTRYID lpUserId,
  2150. ECQUOTASTATUS **lppsQuotaStatus)
  2151. {
  2152. return lpTransport->GetQuotaStatus(cbUserId, lpUserId, lppsQuotaStatus);
  2153. }
  2154. HRESULT ECMsgStore::PurgeSoftDelete(ULONG ulDays)
  2155. {
  2156. return lpTransport->HrPurgeSoftDelete(ulDays);
  2157. }
  2158. HRESULT ECMsgStore::PurgeCache(ULONG ulFlags)
  2159. {
  2160. return lpTransport->HrPurgeCache(ulFlags);
  2161. }
  2162. HRESULT ECMsgStore::PurgeDeferredUpdates(ULONG *lpulRemaining)
  2163. {
  2164. return lpTransport->HrPurgeDeferredUpdates(lpulRemaining);
  2165. }
  2166. HRESULT ECMsgStore::GetServerDetails(ECSVRNAMELIST *lpServerNameList,
  2167. ULONG ulFlags, ECSERVERLIST **lppsServerList)
  2168. {
  2169. return lpTransport->HrGetServerDetails(lpServerNameList, ulFlags, lppsServerList);
  2170. }
  2171. HRESULT ECMsgStore::OpenUserStoresTable(ULONG ulFlags, LPMAPITABLE *lppTable)
  2172. {
  2173. HRESULT hr = hrSuccess;
  2174. object_ptr<WSTableView> lpTableView;
  2175. object_ptr<ECMAPITable> lpTable;
  2176. if (lppTable == nullptr)
  2177. return MAPI_E_INVALID_PARAMETER;
  2178. // notifications? set 1st param: m_lpNotifyClient
  2179. hr = ECMAPITable::Create("Userstores table", NULL, 0, &~lpTable);
  2180. if (hr != hrSuccess)
  2181. return hr;
  2182. // open store table view, no entryid req.
  2183. hr = lpTransport->HrOpenMiscTable(TABLETYPE_USERSTORES, ulFlags, 0, NULL, this, &~lpTableView);
  2184. if (hr != hrSuccess)
  2185. return hr;
  2186. hr = lpTable->HrSetTableOps(lpTableView, true);
  2187. if (hr != hrSuccess)
  2188. return hr;
  2189. hr = lpTable->QueryInterface(IID_IMAPITable, (void **)lppTable);
  2190. if (hr != hrSuccess)
  2191. return hr;
  2192. AddChild(lpTable);
  2193. return hrSuccess;
  2194. }
  2195. HRESULT ECMsgStore::ResolvePseudoUrl(const char *lpszPseudoUrl,
  2196. char **lppszServerPath, bool *lpbIsPeer)
  2197. {
  2198. return lpTransport->HrResolvePseudoUrl(lpszPseudoUrl, lppszServerPath, lpbIsPeer);
  2199. }
  2200. HRESULT ECMsgStore::GetPublicStoreEntryID(ULONG ulFlags, ULONG* lpcbStoreID, LPENTRYID* lppStoreID)
  2201. {
  2202. ULONG cbStoreID;
  2203. EntryIdPtr ptrStoreID;
  2204. std::string strRedirServer;
  2205. HRESULT hr = lpTransport->HrGetPublicStore(ulFlags, &cbStoreID, &~ptrStoreID, &strRedirServer);
  2206. if (hr == MAPI_E_UNABLE_TO_COMPLETE) {
  2207. WSTransportPtr ptrTransport;
  2208. hr = lpTransport->CreateAndLogonAlternate(strRedirServer.c_str(), &~ptrTransport);
  2209. if (hr != hrSuccess)
  2210. return hr;
  2211. hr = ptrTransport->HrGetPublicStore(ulFlags, &cbStoreID, &~ptrStoreID);
  2212. }
  2213. if (hr != hrSuccess)
  2214. return hr;
  2215. return lpSupport->WrapStoreEntryID(cbStoreID, ptrStoreID, lpcbStoreID, lppStoreID);
  2216. }
  2217. HRESULT ECMsgStore::GetArchiveStoreEntryID(LPCTSTR lpszUserName, LPCTSTR lpszServerName, ULONG ulFlags, ULONG* lpcbStoreID, LPENTRYID* lppStoreID)
  2218. {
  2219. HRESULT hr;
  2220. ULONG cbStoreID;
  2221. EntryIdPtr ptrStoreID;
  2222. if (lpszUserName == NULL || lpcbStoreID == NULL || lppStoreID == NULL)
  2223. return MAPI_E_INVALID_PARAMETER;
  2224. if (lpszServerName != NULL) {
  2225. WSTransportPtr ptrTransport;
  2226. hr = GetTransportToNamedServer(lpTransport, lpszServerName, ulFlags, &~ptrTransport);
  2227. if (hr != hrSuccess)
  2228. return hr;
  2229. hr = ptrTransport->HrResolveTypedStore(convstring(lpszUserName, ulFlags), ECSTORE_TYPE_ARCHIVE, &cbStoreID, &~ptrStoreID);
  2230. if (hr != hrSuccess)
  2231. return hr;
  2232. } else {
  2233. hr = lpTransport->HrResolveTypedStore(convstring(lpszUserName, ulFlags), ECSTORE_TYPE_ARCHIVE, &cbStoreID, &~ptrStoreID);
  2234. if (hr != hrSuccess)
  2235. return hr;
  2236. }
  2237. return lpSupport->WrapStoreEntryID(cbStoreID, ptrStoreID, lpcbStoreID, lppStoreID);
  2238. }
  2239. HRESULT ECMsgStore::ResetFolderCount(ULONG cbEntryId, LPENTRYID lpEntryId, ULONG *lpulUpdates)
  2240. {
  2241. return lpTransport->HrResetFolderCount(cbEntryId, lpEntryId, lpulUpdates);
  2242. }
  2243. // This is almost the same as getting a 'normal' outgoing table, except we pass NULL as PEID for the store
  2244. HRESULT ECMsgStore::GetMasterOutgoingTable(ULONG ulFlags, IMAPITable ** lppOutgoingTable)
  2245. {
  2246. object_ptr<ECMAPITable> lpTable;
  2247. object_ptr<WSTableOutGoingQueue> lpTableOps;
  2248. HRESULT hr = ECMAPITable::Create("Master outgoing queue", this->m_lpNotifyClient, 0, &~lpTable);
  2249. if(hr != hrSuccess)
  2250. return hr;
  2251. hr = this->lpTransport->HrOpenTableOutGoingQueueOps(0, NULL, this, &~lpTableOps);
  2252. if(hr != hrSuccess)
  2253. return hr;
  2254. hr = lpTable->HrSetTableOps(lpTableOps, !(ulFlags & MAPI_DEFERRED_ERRORS));
  2255. if(hr != hrSuccess)
  2256. return hr;
  2257. hr = lpTable->QueryInterface(IID_IMAPITable, (void **)lppOutgoingTable);
  2258. AddChild(lpTable);
  2259. return hr;
  2260. }
  2261. HRESULT ECMsgStore::DeleteFromMasterOutgoingTable(ULONG cbEntryId,
  2262. const ENTRYID *lpEntryId, ULONG ulFlags)
  2263. {
  2264. // Check input/output variables
  2265. if (lpEntryId == NULL)
  2266. return MAPI_E_INVALID_PARAMETER;
  2267. return this->lpTransport->HrFinishedMessage(cbEntryId, lpEntryId, EC_SUBMIT_MASTER | ulFlags);
  2268. }
  2269. // MAPIOfflineMgr
  2270. HRESULT ECMsgStore::SetCurrentState(ULONG ulFlags, ULONG ulMask, ULONG ulState, void* pReserved)
  2271. {
  2272. return MAPI_E_NO_SUPPORT;
  2273. }
  2274. HRESULT ECMsgStore::GetCapabilities(ULONG *pulCapabilities)
  2275. {
  2276. return MAPI_E_NO_SUPPORT;
  2277. }
  2278. HRESULT ECMsgStore::GetCurrentState(ULONG* pulState)
  2279. {
  2280. return MAPI_E_NO_SUPPORT;
  2281. }
  2282. HRESULT ECMsgStore::Advise(ULONG ulFlags, MAPIOFFLINE_ADVISEINFO* pAdviseInfo, ULONG* pulAdviseToken)
  2283. {
  2284. return MAPI_E_NO_SUPPORT;
  2285. }
  2286. HRESULT ECMsgStore::Unadvise(ULONG ulFlags,ULONG ulAdviseToken)
  2287. {
  2288. return MAPI_E_NO_SUPPORT;
  2289. }
  2290. // ProxyStoreObject
  2291. HRESULT ECMsgStore::UnwrapNoRef(LPVOID *ppvObject)
  2292. {
  2293. if (ppvObject == NULL)
  2294. return MAPI_E_INVALID_PARAMETER;
  2295. // Because the function UnwrapNoRef return a non referenced object, QueryInterface isn't needed.
  2296. *ppvObject = &this->m_xMsgStoreProxy;
  2297. return hrSuccess;
  2298. }
  2299. // ECMultiStoreTable
  2300. // open a table with given entryids and columns.
  2301. // entryids can be from any store
  2302. HRESULT ECMsgStore::OpenMultiStoreTable(LPENTRYLIST lpMsgList, ULONG ulFlags, LPMAPITABLE *lppTable) {
  2303. HRESULT hr = hrSuccess;
  2304. object_ptr<ECMAPITable> lpTable;
  2305. object_ptr<WSTableView> lpTableOps;
  2306. if (lpMsgList == nullptr || lppTable == nullptr)
  2307. return MAPI_E_INVALID_PARAMETER;
  2308. // no notifications on this table
  2309. hr = ECMAPITable::Create("Multistore table", NULL, ulFlags, &~lpTable);
  2310. if (hr != hrSuccess)
  2311. return hr;
  2312. // open a table on the server, with content specified in lpMsgList
  2313. // TODO: my entryid ?
  2314. hr = lpTransport->HrOpenMultiStoreTable(lpMsgList, ulFlags, 0, NULL, this, &~lpTableOps);
  2315. if (hr != hrSuccess)
  2316. return hr;
  2317. hr = lpTable->HrSetTableOps(lpTableOps, !(ulFlags & MAPI_DEFERRED_ERRORS));
  2318. if (hr != hrSuccess)
  2319. return hr;
  2320. hr = lpTable->QueryInterface(IID_IMAPITable, (void **)lppTable);
  2321. // add child really needed?
  2322. AddChild(lpTable);
  2323. return hr;
  2324. }
  2325. HRESULT ECMsgStore::LicenseAuth(unsigned char *lpData, unsigned int ulSize, unsigned char **lppResponse, unsigned int * lpulResponseData)
  2326. {
  2327. return lpTransport->HrLicenseAuth(lpData, ulSize, lppResponse, lpulResponseData);
  2328. }
  2329. HRESULT ECMsgStore::LicenseCapa(unsigned int ulServiceType, char ***lppszCapas, unsigned int *lpulSize)
  2330. {
  2331. return lpTransport->HrLicenseCapa(ulServiceType, lppszCapas, lpulSize);
  2332. }
  2333. HRESULT ECMsgStore::LicenseUsers(unsigned int ulServiceType, unsigned int *lpulUsers)
  2334. {
  2335. return lpTransport->HrLicenseUsers(ulServiceType, lpulUsers);
  2336. }
  2337. HRESULT ECMsgStore::TestPerform(const char *szCommand, unsigned int ulArgs,
  2338. char **lpszArgs)
  2339. {
  2340. return lpTransport->HrTestPerform(szCommand, ulArgs, lpszArgs);
  2341. }
  2342. HRESULT ECMsgStore::TestSet(const char *szName, const char *szValue)
  2343. {
  2344. return lpTransport->HrTestSet(szName, szValue);
  2345. }
  2346. HRESULT ECMsgStore::TestGet(const char *szName, char **szValue)
  2347. {
  2348. return lpTransport->HrTestGet(szName, szValue);
  2349. }
  2350. /**
  2351. * Convert a message store DN to a pseudo URL.
  2352. * A message store DN looks like the following: /o=Domain/ou=Location/cn=Configuration/cn=Servers/cn=<servername>/cn=Microsoft Private MDB
  2353. *
  2354. * This function checks if the last part is valid. This means that we have a 'cn=<servername>' followed by 'cn=Microsoft Private MDB'. The rest
  2355. * of the DN is ignored. The returned pseudo url will look like: 'pseudo://<servername>'
  2356. *
  2357. * @param[in] strMsgStoreDN
  2358. * The message store DN from which to extract the servername.
  2359. * @param[out] lpstrPseudoUrl
  2360. * Pointer to a std::string object that will be set to the resulting pseudo URL.
  2361. *
  2362. * @return HRESULT
  2363. * @retval hrSuccess Conversion succeeded.
  2364. * @retval MAPI_E_INVALID_PARAMETER The provided message store DN does not match the minimum requirements needed
  2365. * to successfully parse it.
  2366. * @retval MAPI_E_NO_SUPPORT If a server is not operating in multi server mode, the default servername is
  2367. * 'Unknown'. This cannot be resolved. In that case MAPI_E_NO_SUPPORT is returned
  2368. * So a different strategy can be selected by the calling method.
  2369. */
  2370. HRESULT ECMsgStore::MsgStoreDnToPseudoUrl(const utf8string &strMsgStoreDN, utf8string *lpstrPseudoUrl)
  2371. {
  2372. vector<string> parts;
  2373. vector<string>::const_reverse_iterator riPart;
  2374. parts = tokenize(strMsgStoreDN.str(), "/");
  2375. // We need at least 2 parts.
  2376. if (parts.size() < 2)
  2377. return MAPI_E_INVALID_PARAMETER;
  2378. // Check if the last part equals 'cn=Microsoft Private MDB'
  2379. riPart = parts.crbegin();
  2380. if (strcasecmp(riPart->c_str(), "cn=Microsoft Private MDB") != 0)
  2381. return MAPI_E_INVALID_PARAMETER;
  2382. // Check if the for last part starts with 'cn='
  2383. ++riPart;
  2384. if (strncasecmp(riPart->c_str(), "cn=", 3) != 0)
  2385. return MAPI_E_INVALID_PARAMETER;
  2386. // If the server has no home server information for a user, the servername will be set to 'Unknown'
  2387. // Return MAPI_E_NO_SUPPORT in that case.
  2388. if (strcasecmp(riPart->c_str(), "cn=Unknown") == 0)
  2389. return MAPI_E_NO_SUPPORT;
  2390. *lpstrPseudoUrl = utf8string::from_string("pseudo://" + riPart->substr(3));
  2391. return hrSuccess;
  2392. }
  2393. /**
  2394. * Export a set of messages as stream.
  2395. *
  2396. * @param[in] ulFlags Flags used to determine which messages and what data is to be exported.
  2397. * @param[in] ulPropTag PR_ENTRYID or PR_SOURCE_KEY. Specifies the identifier used in sChanges->sSourceKey
  2398. * @param[in] sChanges The complete set of changes available.
  2399. * @param[in] ulStart The index in sChanges that specifies the first message to export.
  2400. * @param[in] ulCount The number of messages to export, starting at ulStart. This number will be decreased if less messages are available.
  2401. * @param[in] lpsProps The set of proptags that will be returned as regular properties outside the stream.
  2402. * @param[out] lppsStreamExporter The streamexporter that must be used to get the individual streams.
  2403. *
  2404. * @retval MAPI_E_INVALID_PARAMETER ulStart is larger than the number of changes available.
  2405. * @retval MAPI_E_UNABLE_TO_COMPLETE ulCount is 0 after trunctation.
  2406. */
  2407. HRESULT ECMsgStore::ExportMessageChangesAsStream(ULONG ulFlags, ULONG ulPropTag,
  2408. const std::vector<ICSCHANGE> &sChanges, ULONG ulStart, ULONG ulCount,
  2409. const SPropTagArray *lpsProps, WSMessageStreamExporter **lppsStreamExporter)
  2410. {
  2411. WSMessageStreamExporterPtr ptrStreamExporter;
  2412. WSTransportPtr ptrTransport;
  2413. if (ulStart > sChanges.size())
  2414. return MAPI_E_INVALID_PARAMETER;
  2415. if (ulStart + ulCount > sChanges.size())
  2416. ulCount = sChanges.size() - ulStart;
  2417. if (ulCount == 0)
  2418. return MAPI_E_UNABLE_TO_COMPLETE;
  2419. // Need to clone the transport since we want to be able to use our own transport for other things
  2420. // while the streaming is going on; you should be able to intermix Synchronize() calls on the exporter
  2421. // with other MAPI calls which would normally be impossible since the stream is kept open between
  2422. // Synchronize() calls.
  2423. HRESULT hr = GetMsgStore()->lpTransport->CloneAndRelogon(&~ptrTransport);
  2424. if (hr != hrSuccess)
  2425. return hr;
  2426. hr = ptrTransport->HrExportMessageChangesAsStream(ulFlags, ulPropTag, &sChanges.front(), ulStart, ulCount, lpsProps, &~ptrStreamExporter);
  2427. if (hr != hrSuccess)
  2428. return hr;
  2429. *lppsStreamExporter = ptrStreamExporter.release();
  2430. return hrSuccess;
  2431. }
  2432. // IMsgStore interface
  2433. DEF_ULONGMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, AddRef, (void))
  2434. DEF_ULONGMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, Release, (void))
  2435. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, QueryInterface, (REFIID, refiid), (void **, lppInterface))
  2436. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, Advise, (ULONG, cbEntryID), (LPENTRYID, lpEntryID), (ULONG, ulEventMask), (LPMAPIADVISESINK, lpAdviseSink), (ULONG *, lpulConnection))
  2437. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, Unadvise, (ULONG, ulConnection))
  2438. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, CompareEntryIDs, (ULONG, cbEntryID1), (LPENTRYID, lpEntryID1), (ULONG, cbEntryID2), (LPENTRYID, lpEntryID2), (ULONG, ulFlags), (ULONG *, lpulResult))
  2439. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, OpenEntry, (ULONG, cbEntryID), (LPENTRYID, lpEntryID), (LPCIID, lpInterface), (ULONG, ulFlags), (ULONG *, lpulObjType), (LPUNKNOWN *, lppUnk))
  2440. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, SetReceiveFolder, (LPTSTR, lpszMessageClass), (ULONG, ulFlags), (ULONG, cbEntryID), (LPENTRYID, lpEntryID))
  2441. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, GetReceiveFolder, (LPTSTR, lpszMessageClass), (ULONG, ulFlags), (ULONG *, lpcbEntryID), (LPENTRYID *, lppEntryID), (LPTSTR *, lppszExplicitClass))
  2442. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, GetReceiveFolderTable, (ULONG, ulFlags), (LPMAPITABLE *, lppTable))
  2443. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, StoreLogoff, (ULONG *, lpulFlags))
  2444. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, AbortSubmit, (ULONG, cbEntryID), (LPENTRYID, lpEntryID), (ULONG, ulFlags))
  2445. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, GetOutgoingQueue, (ULONG, ulFlags), (LPMAPITABLE *, lppTable))
  2446. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, SetLockState, (LPMESSAGE, lpMessage), (ULONG, ulLockState))
  2447. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, FinishedMsg, (ULONG, ulFlags), (ULONG, cbEntryID), (LPENTRYID, lpEntryID))
  2448. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, NotifyNewMail, (LPNOTIFICATION, lpNotification))
  2449. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, GetLastError, (HRESULT, hError), (ULONG, ulFlags), (LPMAPIERROR *, lppMapiError))
  2450. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, SaveChanges, (ULONG, ulFlags))
  2451. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, GetProps, (const SPropTagArray *, lpPropTagArray), (ULONG, ulFlags), (ULONG *, lpcValues), (SPropValue **, lppPropArray))
  2452. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, GetPropList, (ULONG, ulFlags), (LPSPropTagArray *, lppPropTagArray))
  2453. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, OpenProperty, (ULONG, ulPropTag), (LPCIID, lpiid), (ULONG, ulInterfaceOptions), (ULONG, ulFlags), (LPUNKNOWN *, lppUnk))
  2454. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, SetProps, (ULONG, cValues), (const SPropValue *, lpPropArray), (SPropProblemArray **, lppProblems))
  2455. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, DeleteProps, (const SPropTagArray *, lpPropTagArray), (SPropProblemArray **, lppProblems))
  2456. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, CopyTo, (ULONG, ciidExclude), (LPCIID, rgiidExclude), (const SPropTagArray *, lpExcludeProps), (ULONG, ulUIParam), (LPMAPIPROGRESS, lpProgress), (LPCIID, lpInterface), (void *, lpDestObj), (ULONG, ulFlags), (SPropProblemArray **, lppProblems))
  2457. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, CopyProps, (const SPropTagArray *, lpIncludeProps), (ULONG, ulUIParam), (LPMAPIPROGRESS, lpProgress), (LPCIID, lpInterface), (void *, lpDestObj), (ULONG, ulFlags), (SPropProblemArray **, lppProblems))
  2458. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, GetNamesFromIDs, (LPSPropTagArray *, pptaga), (LPGUID, lpguid), (ULONG, ulFlags), (ULONG *, pcNames), (LPMAPINAMEID **, pppNames))
  2459. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStore, GetIDsFromNames, (ULONG, cNames), (MAPINAMEID **, ppNames), (ULONG, ulFlags), (LPSPropTagArray *, pptaga))
  2460. /*
  2461. * IExchangeManageStore interface
  2462. */
  2463. DEF_ULONGMETHOD1(TRACE_MAPI, ECMsgStore, ExchangeManageStore, AddRef, (void))
  2464. DEF_ULONGMETHOD1(TRACE_MAPI, ECMsgStore, ExchangeManageStore, Release, (void))
  2465. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ExchangeManageStore, QueryInterface, (REFIID, refiid), (void **, lppInterface))
  2466. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ExchangeManageStore, CreateStoreEntryID, (LPTSTR, lpszMsgStoreDN), (LPTSTR, lpszMailboxDN), (ULONG, ulFlags), (ULONG *, lpcbEntryID), (LPENTRYID *, lppEntryID))
  2467. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ExchangeManageStore, EntryIDFromSourceKey, (ULONG, cFolderKeySize), (BYTE *, lpFolderSourceKey), (ULONG, cMessageKeySize), (BYTE *, lpMessageSourceKey), (ULONG *, lpcbEntryID), (LPENTRYID *, lppEntryID))
  2468. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ExchangeManageStore, GetRights, (ULONG, cbUserEntryID), (LPENTRYID, lpUserEntryID), (ULONG, cbEntryID), (LPENTRYID, lpEntryID), (ULONG *, lpulRights))
  2469. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ExchangeManageStore, GetMailboxTable, (LPTSTR, lpszServerName), (LPMAPITABLE *, lppTable), (ULONG, ulFlags))
  2470. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ExchangeManageStore, GetPublicFolderTable, (LPTSTR, lpszServerName), (LPMAPITABLE *, lppTable), (ULONG, ulFlags))
  2471. // IECServiceAdmin
  2472. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, QueryInterface, (REFIID, refiid), (void **, lppInterface))
  2473. DEF_ULONGMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, AddRef, (void))
  2474. DEF_ULONGMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, Release, (void))
  2475. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, CreateStore, (ULONG, ulStoreType), (ULONG, cbUserId), (LPENTRYID, lpUserId), (ULONG*, lpcbStoreId), (LPENTRYID*, lppStoreId), (ULONG*, lpcbRootId), (LPENTRYID *, lppRootId))
  2476. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, CreateEmptyStore, (ULONG, ulStoreType), (ULONG, cbUserId), (LPENTRYID, lpUserId), (ULONG, ulFlags), (ULONG*, lpcbStoreId), (LPENTRYID*, lppStoreId), (ULONG*, lpcbRootId), (LPENTRYID *, lppRootId))
  2477. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, HookStore, (ULONG, ulStoreType), (ULONG, cbUserId), (LPENTRYID, lpUserId), (LPGUID, lpGuid))
  2478. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, UnhookStore, (ULONG, ulStoreType), (ULONG, cbUserId), (LPENTRYID, lpUserId))
  2479. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, RemoveStore, (LPGUID, lpGuid))
  2480. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, ResolveStore, (LPGUID, lpGuid), (ULONG *, lpulUserID), (ULONG*, lpcbStoreID), (LPENTRYID*, lppStoreID))
  2481. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, CreateUser, (ECUSER *, lpECUser), (ULONG, ulFlags), (ULONG *, lpcbUserId), (LPENTRYID *, lppUserId))
  2482. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, SetUser, (ECUSER *, lpECUser), (ULONG, ulFlags))
  2483. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, GetUser, (ULONG, cbUserId), (LPENTRYID, lpUserId), (ULONG, ulFlags), (ECUSER **, lppECUser))
  2484. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, DeleteUser, (ULONG, cbUserId), (LPENTRYID, lpUserId))
  2485. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, GetUserList, (ULONG, cbCompanyId), (LPENTRYID, lpCompanyId), (ULONG, ulFlags), (ULONG *, lpcUsers), (ECUSER **, lpsUsers))
  2486. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, GetSendAsList, (ULONG, cbUserId), (LPENTRYID, lpUserId), (ULONG, ulFlags), (ULONG *, lpcSenders), (ECUSER **, lppSenders))
  2487. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, AddSendAsUser, (ULONG, cbUserId), (LPENTRYID, lpUserId), (ULONG, cbSenderId), (LPENTRYID, lpSenderId))
  2488. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, DelSendAsUser, (ULONG, cbUserId), (LPENTRYID, lpUserId), (ULONG, cbSenderId), (LPENTRYID, lpSenderId))
  2489. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, GetUserClientUpdateStatus, (ULONG, cbUserId), (LPENTRYID, lpUserId), (ULONG, ulFlags), (ECUSERCLIENTUPDATESTATUS **, lppECUCUS))
  2490. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, RemoveAllObjects, (ULONG, cbUserId), (LPENTRYID, lpUserId))
  2491. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, ResolveGroupName, (LPCTSTR, lpszGroupName), (ULONG, ulFlags), (ULONG *, lpcbGroupId), (LPENTRYID *, lppGroupId))
  2492. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, ResolveUserName, (LPCTSTR, lpszUserName), (ULONG, ulFlags), (ULONG *, lpcbUserId), (LPENTRYID *, lppUserId))
  2493. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, CreateGroup, (ECGROUP *, lpECGroup), (ULONG, ulFlags), (ULONG *, lpcbGroupId), (LPENTRYID *, lppGroupId))
  2494. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, SetGroup, (ECGROUP *, lpECGroup), (ULONG, ulFlags))
  2495. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, GetGroup, (ULONG, cbGroupId), (LPENTRYID, lpGroupId), (ULONG, ulFlags), (ECGROUP **, lppECGroup))
  2496. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, DeleteGroup, (ULONG, cbGroupId), (LPENTRYID, lpGroupId))
  2497. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, GetGroupList, (ULONG, cbCompanyId), (LPENTRYID, lpCompanyId), (ULONG, ulFlags), (ULONG *, lpcGroups), (ECGROUP **, lppsGroups))
  2498. //Group and user functions
  2499. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, DeleteGroupUser, (ULONG, cbGroupId), (LPENTRYID, lpGroupId), (ULONG, cbUserId), (LPENTRYID, lpUserId))
  2500. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, AddGroupUser, (ULONG, cbGroupId), (LPENTRYID, lpGroupId), (ULONG, cbUserId), (LPENTRYID, lpUserId))
  2501. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, GetUserListOfGroup, (ULONG, cbGroupId), (LPENTRYID, lpGroupId), (ULONG, ulFlags), (ULONG *, lpcUsers), (ECUSER **, lppsUsers))
  2502. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, GetGroupListOfUser, (ULONG, cbUserId), (LPENTRYID, lpUserId), (ULONG, ulFlags), (ULONG *, lpcGroups), (ECGROUP **, lppsGroups))
  2503. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, CreateCompany, (ECCOMPANY *, lpECCompany), (ULONG, ulFlags), (ULONG *, lpcbCompanyId), (LPENTRYID *, lppCompanyId))
  2504. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, DeleteCompany, (ULONG, cbCompanyId), (LPENTRYID, lpCompanyId))
  2505. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, SetCompany, (ECCOMPANY *, lpECCompany), (ULONG, ulFlags))
  2506. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, GetCompany, (ULONG, cbCompanyId), (LPENTRYID, lpCompanyId), (ULONG, ulFlags), (ECCOMPANY **, lppECCompany))
  2507. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, ResolveCompanyName, (LPCTSTR, lpszCompanyName), (ULONG, ulFlags), (ULONG *, lpcbCompanyId), (LPENTRYID *, lppCompanyId))
  2508. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, GetCompanyList, (ULONG, ulFlags), (ULONG *, lpcCompanies), (ECCOMPANY **, lppsCompanies))
  2509. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, AddCompanyToRemoteViewList, (ULONG, cbSetCompanyId), (LPENTRYID, lpSetCompanyId), (ULONG, cbCompanyId), (LPENTRYID, lpCompanyId))
  2510. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, DelCompanyFromRemoteViewList, (ULONG, cbSetCompanyId), (LPENTRYID, lpSetCompanyId), (ULONG, cbCompanyId), (LPENTRYID, lpCompanyId))
  2511. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, GetRemoteViewList, (ULONG, cbCompanyId), (LPENTRYID, lpCompanyId), (ULONG, ulFlags), (ULONG *, lpcCompanies), (ECCOMPANY **, lppsCompanies))
  2512. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, AddUserToRemoteAdminList, (ULONG, cbUserId), (LPENTRYID, lpUserId), (ULONG, cbCompanyId), (LPENTRYID, lpCompanyId))
  2513. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, DelUserFromRemoteAdminList, (ULONG, cbUserId), (LPENTRYID, lpUserId), (ULONG, cbCompanyId), (LPENTRYID, lpCompanyId))
  2514. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, GetRemoteAdminList, (ULONG, cbCompanyId), (LPENTRYID, lpCompanyId), (ULONG, ulFlags), (ULONG *, lpcUsers), (ECUSER **, lppsUsers))
  2515. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, SyncUsers, (ULONG, cbCompanyId), (LPENTRYID, lpCompanyId))
  2516. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, GetQuota, (ULONG, cbUserId), (LPENTRYID, lpUserId), (bool, bGetUserDefault), (ECQUOTA **, lppsQuota))
  2517. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, SetQuota, (ULONG, cbUserId), (LPENTRYID, lpUserId), (ECQUOTA *, lpsQuota))
  2518. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, AddQuotaRecipient, (ULONG, cbCompanyId), (LPENTRYID, lpCompanyId), (ULONG, cbRecipientId), (LPENTRYID, lpRecipientId), (ULONG, ulType))
  2519. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, DeleteQuotaRecipient, (ULONG, cbCompanyId), (LPENTRYID, lpCmopanyId), (ULONG, cbRecipientId), (LPENTRYID, lpRecipientId), (ULONG, ulType))
  2520. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, GetQuotaRecipients, (ULONG, cbUserId), (LPENTRYID, lpUserId), (ULONG, ulFlags), (ULONG *, lpcUsers), (ECUSER **, lppsUsers))
  2521. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, GetQuotaStatus, (ULONG, cbUserId), (LPENTRYID, lpUserId), (ECQUOTASTATUS **, lppsQuotaStatus))
  2522. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, PurgeCache, (ULONG, ulFlags))
  2523. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, PurgeSoftDelete, (ULONG, ulDays))
  2524. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, PurgeDeferredUpdates, (ULONG *, lpulRemaining))
  2525. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, GetServerDetails, (ECSVRNAMELIST *, lpServerNameList), (ULONG, ulFlags), (ECSERVERLIST **, lppsServerList))
  2526. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, OpenUserStoresTable, (ULONG, ulFlags), (LPMAPITABLE *, lppTable))
  2527. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, ResolvePseudoUrl, (const char *, lpszPseudoUrl), (char **, lppszServerPath), (bool *, lpbIsPeer))
  2528. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, GetPublicStoreEntryID, (ULONG, ulFlags), (ULONG*, lpcbStoreID), (LPENTRYID*, lppStoreID))
  2529. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, GetArchiveStoreEntryID, (LPCTSTR, lpszUserName), (LPCTSTR, lpszServerName), (ULONG, ulFlags), (ULONG*, lpcbStoreID), (LPENTRYID*, lppStoreID))
  2530. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECServiceAdmin, ResetFolderCount, (ULONG, cbEntryId), (LPENTRYID, lpEntryId), (ULONG *, lpulUpdates))
  2531. // IECSpooler
  2532. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECSpooler, QueryInterface, (REFIID, refiid), (void**, lppInterface))
  2533. DEF_ULONGMETHOD1(TRACE_MAPI, ECMsgStore, ECSpooler, AddRef, (void))
  2534. DEF_ULONGMETHOD1(TRACE_MAPI, ECMsgStore, ECSpooler, Release, (void))
  2535. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECSpooler, GetMasterOutgoingTable, (ULONG, ulFlags), (IMAPITable **, lppOutgoingTable))
  2536. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECSpooler, DeleteFromMasterOutgoingTable, (ULONG, cbEntryID), (const ENTRYID *, lpEntryID), (ULONG, ulFlags))
  2537. // Interface IMAPIOfflineMgr
  2538. DEF_ULONGMETHOD1(TRACE_MAPI, ECMsgStore, MAPIOfflineMgr, AddRef, (void))
  2539. DEF_ULONGMETHOD1(TRACE_MAPI, ECMsgStore, MAPIOfflineMgr, Release, (void))
  2540. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MAPIOfflineMgr, QueryInterface, (REFIID, refiid), (void **, lppInterface))
  2541. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MAPIOfflineMgr, SetCurrentState, (ULONG, ulFlags), (ULONG, ulMask), (ULONG, ulState), (void*, pReserved))
  2542. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MAPIOfflineMgr, GetCapabilities, (ULONG *, pulCapabilities))
  2543. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MAPIOfflineMgr, GetCurrentState, (ULONG*, pulState))
  2544. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MAPIOfflineMgr, Advise, (ULONG, ulFlags), (MAPIOFFLINE_ADVISEINFO*, pAdviseInfo), (ULONG*, pulAdviseToken))
  2545. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MAPIOfflineMgr, Unadvise, (ULONG, ulFlags), (ULONG, ulAdviseToken))
  2546. // Interface IProxyStoreObject
  2547. DEF_ULONGMETHOD1(TRACE_MAPI, ECMsgStore, ProxyStoreObject, AddRef, (void))
  2548. DEF_ULONGMETHOD1(TRACE_MAPI, ECMsgStore, ProxyStoreObject, Release, (void))
  2549. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ProxyStoreObject, QueryInterface, (REFIID, refiid), (void **, lppInterface))
  2550. DEF_HRMETHOD_NOSUPPORT(TRACE_MAPI, ECMsgStore, ProxyStoreObject, PlaceHolder1, (void))
  2551. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ProxyStoreObject, UnwrapNoRef, (LPVOID *, ppvObject))
  2552. DEF_HRMETHOD_NOSUPPORT(TRACE_MAPI, ECMsgStore, ProxyStoreObject, PlaceHolder2, (void))
  2553. // IMsgStoreProxy interface
  2554. DEF_ULONGMETHOD1(TRACE_MAPI, ECMsgStore, MsgStoreProxy, AddRef, (void))
  2555. DEF_ULONGMETHOD1(TRACE_MAPI, ECMsgStore, MsgStoreProxy, Release, (void))
  2556. HRESULT ECMsgStore::xMsgStoreProxy::QueryInterface(REFIID refiid, void **lppInterface) {
  2557. TRACE_MAPI(TRACE_ENTRY, "IMsgStoreProxy::QueryInterface", "%s", DBGGUIDToString(refiid).c_str());
  2558. METHOD_PROLOGUE_(ECMsgStore, MsgStoreProxy);
  2559. HRESULT hr = pThis->QueryInterfaceProxy(refiid, lppInterface);
  2560. TRACE_MAPI(TRACE_RETURN, "IMsgStoreProxy::QueryInterface", "%s", GetMAPIErrorDescription(hr).c_str());
  2561. return hr;
  2562. }
  2563. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStoreProxy, Advise, (ULONG, cbEntryID), (LPENTRYID, lpEntryID), (ULONG, ulEventMask), (LPMAPIADVISESINK, lpAdviseSink), (ULONG *, lpulConnection))
  2564. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStoreProxy, Unadvise, (ULONG, ulConnection))
  2565. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStoreProxy, CompareEntryIDs, (ULONG, cbEntryID1), (LPENTRYID, lpEntryID1), (ULONG, cbEntryID2), (LPENTRYID, lpEntryID2), (ULONG, ulFlags), (ULONG *, lpulResult))
  2566. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStoreProxy, OpenEntry, (ULONG, cbEntryID), (LPENTRYID, lpEntryID), (LPCIID, lpInterface), (ULONG, ulFlags), (ULONG *, lpulObjType), (LPUNKNOWN *, lppUnk))
  2567. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStoreProxy, SetReceiveFolder, (LPTSTR, lpszMessageClass), (ULONG, ulFlags), (ULONG, cbEntryID), (LPENTRYID, lpEntryID))
  2568. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStoreProxy, GetReceiveFolder, (LPTSTR, lpszMessageClass), (ULONG, ulFlags), (ULONG *, lpcbEntryID), (LPENTRYID *, lppEntryID), (LPTSTR *, lppszExplicitClass))
  2569. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStoreProxy, GetReceiveFolderTable, (ULONG, ulFlags), (LPMAPITABLE *, lppTable))
  2570. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStoreProxy, StoreLogoff, (ULONG *, lpulFlags))
  2571. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStoreProxy, AbortSubmit, (ULONG, cbEntryID), (LPENTRYID, lpEntryID), (ULONG, ulFlags))
  2572. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStoreProxy, GetOutgoingQueue, (ULONG, ulFlags), (LPMAPITABLE *, lppTable))
  2573. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStoreProxy, SetLockState, (LPMESSAGE, lpMessage), (ULONG, ulLockState))
  2574. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStoreProxy, FinishedMsg, (ULONG, ulFlags), (ULONG, cbEntryID), (LPENTRYID, lpEntryID))
  2575. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStoreProxy, NotifyNewMail, (LPNOTIFICATION, lpNotification))
  2576. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStoreProxy, GetLastError, (HRESULT, hError), (ULONG, ulFlags), (LPMAPIERROR *, lppMapiError))
  2577. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStoreProxy, SaveChanges, (ULONG, ulFlags))
  2578. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStoreProxy, GetProps, (const SPropTagArray *, lpPropTagArray), (ULONG, ulFlags), (ULONG *, lpcValues), (SPropValue **, lppPropArray))
  2579. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStoreProxy, GetPropList, (ULONG, ulFlags), (LPSPropTagArray *, lppPropTagArray))
  2580. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStoreProxy, OpenProperty, (ULONG, ulPropTag), (LPCIID, lpiid), (ULONG, ulInterfaceOptions), (ULONG, ulFlags), (LPUNKNOWN *, lppUnk))
  2581. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStoreProxy, SetProps, (ULONG, cValues), (const SPropValue *, lpPropArray), (SPropProblemArray **, lppProblems))
  2582. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStoreProxy, DeleteProps, (const SPropTagArray *, lpPropTagArray), (SPropProblemArray **, lppProblems))
  2583. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStoreProxy, CopyTo, (ULONG, ciidExclude), (LPCIID, rgiidExclude), (const SPropTagArray *, lpExcludeProps), (ULONG, ulUIParam), (LPMAPIPROGRESS, lpProgress), (LPCIID, lpInterface), (void *, lpDestObj), (ULONG, ulFlags), (SPropProblemArray **, lppProblems))
  2584. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStoreProxy, CopyProps, (const SPropTagArray *, lpIncludeProps), (ULONG, ulUIParam), (LPMAPIPROGRESS, lpProgress), (LPCIID, lpInterface), (void *, lpDestObj), (ULONG, ulFlags), (SPropProblemArray **, lppProblems))
  2585. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStoreProxy, GetNamesFromIDs, (LPSPropTagArray *, pptaga), (LPGUID, lpguid), (ULONG, ulFlags), (ULONG *, pcNames), (LPMAPINAMEID **, pppNames))
  2586. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, MsgStoreProxy, GetIDsFromNames, (ULONG, cNames), (LPMAPINAMEID *, ppNames), (ULONG, ulFlags), (LPSPropTagArray *, pptaga))
  2587. // IECMultiStoreTable interface
  2588. DEF_ULONGMETHOD1(TRACE_MAPI, ECMsgStore, ECMultiStoreTable, AddRef, (void))
  2589. DEF_ULONGMETHOD1(TRACE_MAPI, ECMsgStore, ECMultiStoreTable, Release, (void))
  2590. HRESULT ECMsgStore::xECMultiStoreTable::QueryInterface(REFIID refiid, void **lppInterface) {
  2591. TRACE_MAPI(TRACE_ENTRY, "IECMultiStoreTable::QueryInterface", "%s", DBGGUIDToString(refiid).c_str());
  2592. METHOD_PROLOGUE_(ECMsgStore, ECMultiStoreTable);
  2593. HRESULT hr = pThis->QueryInterfaceProxy(refiid, lppInterface);
  2594. TRACE_MAPI(TRACE_RETURN, "IECMultiStoreTable::QueryInterface", "%s", GetMAPIErrorDescription(hr).c_str());
  2595. return hr;
  2596. }
  2597. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECMultiStoreTable, OpenMultiStoreTable, (LPENTRYLIST, lpMsgList), (ULONG, ulFlags), (LPMAPITABLE *, lppTable))
  2598. // IECLicense interface
  2599. DEF_ULONGMETHOD1(TRACE_MAPI, ECMsgStore, ECLicense, AddRef, (void))
  2600. DEF_ULONGMETHOD1(TRACE_MAPI, ECMsgStore, ECLicense, Release, (void))
  2601. HRESULT ECMsgStore::xECLicense::QueryInterface(REFIID refiid, void **lppInterface) {
  2602. TRACE_MAPI(TRACE_ENTRY, "IECLicense::QueryInterface", "%s", DBGGUIDToString(refiid).c_str());
  2603. METHOD_PROLOGUE_(ECMsgStore, ECLicense);
  2604. HRESULT hr = pThis->QueryInterfaceProxy(refiid, lppInterface);
  2605. TRACE_MAPI(TRACE_RETURN, "IECLicense::QueryInterface", "%s", GetMAPIErrorDescription(hr).c_str());
  2606. return hr;
  2607. }
  2608. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECLicense, LicenseAuth, (unsigned char *, lpData), (unsigned int, ulSize), (unsigned char **, lppResponse), (unsigned int *, lpulResponseSize))
  2609. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECLicense, LicenseCapa, (unsigned int, ulServiceType), (char ***, lppszData), (unsigned int *, lpulSize))
  2610. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECLicense, LicenseUsers, (unsigned int, ulServiceType), (unsigned int *, lpulUsers))
  2611. // IECTestProtocol interface
  2612. DEF_ULONGMETHOD1(TRACE_MAPI, ECMsgStore, ECTestProtocol, AddRef, (void))
  2613. DEF_ULONGMETHOD1(TRACE_MAPI, ECMsgStore, ECTestProtocol, Release, (void))
  2614. HRESULT ECMsgStore::xECTestProtocol::QueryInterface(REFIID refiid, void **lppInterface) {
  2615. TRACE_MAPI(TRACE_ENTRY, "IECTestProtocol::QueryInterface", "%s", DBGGUIDToString(refiid).c_str());
  2616. METHOD_PROLOGUE_(ECMsgStore, ECTestProtocol);
  2617. HRESULT hr = pThis->QueryInterfaceProxy(refiid, lppInterface);
  2618. TRACE_MAPI(TRACE_RETURN, "IECTestProtocol::QueryInterface", "%s", GetMAPIErrorDescription(hr).c_str());
  2619. return hr;
  2620. }
  2621. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECTestProtocol, TestPerform, (const char *, cmd), (unsigned int, argc), (char **, args))
  2622. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECTestProtocol, TestSet, (const char *, name), (const char *, value))
  2623. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ECTestProtocol, TestGet, (const char *, name), (char **, value))
  2624. ECMSLogon::ECMSLogon(ECMsgStore *lpStore)
  2625. {
  2626. // Note we cannot AddRef() the store. This is because the reference order is:
  2627. // ECMsgStore -> IMAPISupport -> ECMSLogon
  2628. // Therefore AddRef()'ing the store from here would create a circular reference
  2629. m_lpStore = lpStore;
  2630. }
  2631. HRESULT ECMSLogon::Create(ECMsgStore *lpStore, ECMSLogon **lppECMSLogon)
  2632. {
  2633. return alloc_wrap<ECMSLogon>(lpStore).as(IID_ECMSLogon, lppECMSLogon);
  2634. }
  2635. HRESULT ECMSLogon::QueryInterface(REFIID refiid, void **lppInterface)
  2636. {
  2637. REGISTER_INTERFACE2(ECMSLogon, this);
  2638. REGISTER_INTERFACE2(IMSLogon, &this->m_xMSLogon);
  2639. return MAPI_E_INTERFACE_NOT_SUPPORTED;
  2640. }
  2641. HRESULT ECMSLogon::GetLastError(HRESULT hResult, ULONG ulFlags, LPMAPIERROR *lppMAPIError)
  2642. {
  2643. return MAPI_E_CALL_FAILED;
  2644. }
  2645. HRESULT ECMSLogon::Logoff(ULONG *lpulFlags)
  2646. {
  2647. return hrSuccess;
  2648. }
  2649. HRESULT ECMSLogon::OpenEntry(ULONG cbEntryID, LPENTRYID lpEntryID, LPCIID lpInterface, ULONG ulFlags, ULONG *lpulObjType, LPUNKNOWN *lppUnk)
  2650. {
  2651. return m_lpStore->OpenEntry(cbEntryID, lpEntryID, lpInterface, ulFlags, lpulObjType, lppUnk);
  2652. }
  2653. HRESULT ECMSLogon::CompareEntryIDs(ULONG cbEntryID1, LPENTRYID lpEntryID1, ULONG cbEntryID2, LPENTRYID lpEntryID2, ULONG ulFlags, ULONG *lpulResult)
  2654. {
  2655. return m_lpStore->CompareEntryIDs(cbEntryID1, lpEntryID1, cbEntryID2, lpEntryID2, ulFlags, lpulResult);
  2656. }
  2657. HRESULT ECMSLogon::Advise(ULONG cbEntryID, LPENTRYID lpEntryID, ULONG ulEventMask, LPMAPIADVISESINK lpAdviseSink, ULONG *lpulConnection)
  2658. {
  2659. return m_lpStore->Advise(cbEntryID, lpEntryID, ulEventMask, lpAdviseSink, lpulConnection);
  2660. }
  2661. HRESULT ECMSLogon::Unadvise(ULONG ulConnection)
  2662. {
  2663. return m_lpStore->Unadvise(ulConnection);
  2664. }
  2665. HRESULT ECMSLogon::OpenStatusEntry(LPCIID lpInterface, ULONG ulFlags, ULONG *lpulObjType, LPVOID *lppEntry)
  2666. {
  2667. return MAPI_E_NO_SUPPORT;
  2668. }
  2669. DEF_HRMETHOD1(TRACE_MAPI, ECMSLogon, MSLogon, QueryInterface, (REFIID, refiid), (void **, lppInterface))
  2670. DEF_ULONGMETHOD1(TRACE_MAPI, ECMSLogon, MSLogon, AddRef, (void))
  2671. DEF_ULONGMETHOD1(TRACE_MAPI, ECMSLogon, MSLogon, Release, (void))
  2672. DEF_HRMETHOD1(TRACE_MAPI, ECMSLogon, MSLogon, GetLastError, (HRESULT, hResult), (ULONG, ulFlags), (LPMAPIERROR *, lppMAPIError))
  2673. DEF_HRMETHOD1(TRACE_MAPI, ECMSLogon, MSLogon, Logoff, (ULONG *, lpulFlags))
  2674. DEF_HRMETHOD1(TRACE_MAPI, ECMSLogon, MSLogon, OpenEntry, (ULONG, cbEntryID), (LPENTRYID, lpEntryID), (LPCIID, lpInterface), (ULONG, ulFlags), (ULONG *, lpulObjType), (LPUNKNOWN *, lppUnk))
  2675. DEF_HRMETHOD1(TRACE_MAPI, ECMSLogon, MSLogon, CompareEntryIDs, (ULONG, cbEntryID1), (LPENTRYID, lpEntryID1), (ULONG, cbEntryID2), (LPENTRYID, lpEntryID2), (ULONG, ulFlags), (ULONG *, lpulResult))
  2676. DEF_HRMETHOD1(TRACE_MAPI, ECMSLogon, MSLogon, Advise, (ULONG, cbEntryID), (LPENTRYID, lpEntryID), (ULONG, ulEventMask), (LPMAPIADVISESINK, lpAdviseSink), (ULONG *, lpulConnection))
  2677. DEF_HRMETHOD1(TRACE_MAPI, ECMSLogon, MSLogon, Unadvise, (ULONG, ulConnection))
  2678. DEF_HRMETHOD1(TRACE_MAPI, ECMSLogon, MSLogon, OpenStatusEntry, (LPCIID, lpInterface), (ULONG, ulFlags), (ULONG *, lpulObjType), (LPVOID *, lppEntry))
  2679. // IExchangeManageStore6
  2680. DEF_ULONGMETHOD1(TRACE_MAPI, ECMsgStore, ExchangeManageStore6, AddRef, (void))
  2681. DEF_ULONGMETHOD1(TRACE_MAPI, ECMsgStore, ExchangeManageStore6, Release, (void))
  2682. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ExchangeManageStore6, QueryInterface, (REFIID, refiid), (void **, lppInterface))
  2683. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ExchangeManageStore6, CreateStoreEntryID, (LPTSTR, lpszMsgStoreDN), (LPTSTR, lpszMailboxDN), (ULONG, ulFlags), (ULONG *, lpcbEntryID), (LPENTRYID *, lppEntryID))
  2684. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ExchangeManageStore6, EntryIDFromSourceKey, (ULONG, cFolderKeySize), (BYTE *, lpFolderSourceKey), (ULONG, cMessageKeySize), (BYTE *, lpMessageSourceKey), (ULONG *, lpcbEntryID), (LPENTRYID *, lppEntryID))
  2685. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ExchangeManageStore6, GetRights, (ULONG, cbUserEntryID), (LPENTRYID, lpUserEntryID), (ULONG, cbEntryID), (LPENTRYID, lpEntryID), (ULONG *, lpulRights))
  2686. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ExchangeManageStore6, GetMailboxTable, (LPTSTR, lpszServerName), (LPMAPITABLE *, lppTable), (ULONG, ulFlags))
  2687. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ExchangeManageStore6, GetPublicFolderTable, (LPTSTR, lpszServerName), (LPMAPITABLE *, lppTable), (ULONG, ulFlags))
  2688. HRESULT ECMsgStore::xExchangeManageStore6::CreateStoreEntryIDEx(LPTSTR lpszMsgStoreDN, LPTSTR lpszEmail, LPTSTR lpszMailboxDN, ULONG ulFlags, ULONG *lpcbEntryID, LPENTRYID *lppEntryID)
  2689. {
  2690. TRACE_MAPI(TRACE_ENTRY, "IExchangeManageStore6::CreateStoreEntryIDEx","msgStoreDN=%s , MailboxDN=%s , flags=0x%08X", (lpszMsgStoreDN)?(char*)lpszMsgStoreDN: "NULL", (lpszMailboxDN)?(char*)lpszMailboxDN:"NULL", ulFlags);
  2691. METHOD_PROLOGUE_(ECMsgStore, ExchangeManageStore6);
  2692. HRESULT hr = pThis->CreateStoreEntryID(lpszMsgStoreDN, lpszMailboxDN, ulFlags, lpcbEntryID, lppEntryID);
  2693. TRACE_MAPI(TRACE_RETURN, "IExchangeManageStore6::CreateStoreEntryIDEx","%s, cb=%d, data=%s", GetMAPIErrorDescription(hr).c_str(), (lpcbEntryID)?*lpcbEntryID:0, (lppEntryID)?bin2hex(*lpcbEntryID, (BYTE*)*lppEntryID).c_str():"NULL");
  2694. return hr;
  2695. }
  2696. // IExchangeManageStoreEx
  2697. DEF_ULONGMETHOD1(TRACE_MAPI, ECMsgStore, ExchangeManageStoreEx, AddRef, (void))
  2698. DEF_ULONGMETHOD1(TRACE_MAPI, ECMsgStore, ExchangeManageStoreEx, Release, (void))
  2699. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ExchangeManageStoreEx, QueryInterface, (REFIID, refiid), (void **, lppInterface))
  2700. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ExchangeManageStoreEx, CreateStoreEntryID, (LPTSTR, lpszMsgStoreDN), (LPTSTR, lpszMailboxDN), (ULONG, ulFlags), (ULONG *, lpcbEntryID), (LPENTRYID *, lppEntryID))
  2701. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ExchangeManageStoreEx, EntryIDFromSourceKey, (ULONG, cFolderKeySize), (BYTE *, lpFolderSourceKey), (ULONG, cMessageKeySize), (BYTE *, lpMessageSourceKey), (ULONG *, lpcbEntryID), (LPENTRYID *, lppEntryID))
  2702. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ExchangeManageStoreEx, GetRights, (ULONG, cbUserEntryID), (LPENTRYID, lpUserEntryID), (ULONG, cbEntryID), (LPENTRYID, lpEntryID), (ULONG *, lpulRights))
  2703. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ExchangeManageStoreEx, GetMailboxTable, (LPTSTR, lpszServerName), (LPMAPITABLE *, lppTable), (ULONG, ulFlags))
  2704. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ExchangeManageStoreEx, GetPublicFolderTable, (LPTSTR, lpszServerName), (LPMAPITABLE *, lppTable), (ULONG, ulFlags))
  2705. DEF_HRMETHOD1(TRACE_MAPI, ECMsgStore, ExchangeManageStoreEx, CreateStoreEntryID2, (ULONG, cValues), (LPSPropValue, lpProps), (ULONG, ulFlags), (ULONG *, lpcbEntryID), (LPENTRYID *, lppEntryID))