WSTransport.cpp 128 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657
  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/lockhelper.hpp>
  19. #include <kopano/memory.hpp>
  20. #include <mapidefs.h>
  21. #include <mapicode.h>
  22. #include <mapitags.h>
  23. #include <mapiutil.h>
  24. #include <fstream>
  25. #include <new>
  26. #include <kopano/ECIConv.h>
  27. #include <kopano/ECLogger.h>
  28. #include "WSTransport.h"
  29. #include "ProviderUtil.h"
  30. #include "SymmetricCrypt.h"
  31. #include "soapH.h"
  32. #include "pcutil.hpp"
  33. // The header files we use for communication with the server
  34. #include <kopano/kcodes.h>
  35. #include "soapKCmdProxy.h"
  36. #include "KCmd.nsmap"
  37. #include "Mem.h"
  38. #include <kopano/ECGuid.h>
  39. #include "SOAPUtils.h"
  40. #include "WSUtil.h"
  41. #include <kopano/mapiext.h>
  42. #include "WSABTableView.h"
  43. #include "WSABPropStorage.h"
  44. #include <kopano/ecversion.h>
  45. #include "ClientUtil.h"
  46. #include "ECSessionGroupManager.h"
  47. #include <kopano/stringutil.h>
  48. #include "versions.h"
  49. #include <kopano/charset/convert.h>
  50. #include <kopano/charset/utf8string.h>
  51. #include <kopano/charset/convstring.h>
  52. #include "SOAPSock.h"
  53. #include <kopano/mapi_ptr.h>
  54. #include "WSMessageStreamExporter.h"
  55. #include "WSMessageStreamImporter.h"
  56. #ifdef HAVE_GSSAPI
  57. # include <gssapi/gssapi.h>
  58. #endif
  59. using namespace std;
  60. using namespace KCHL;
  61. /*
  62. *
  63. * This is the main WebServices transport object. All communications with the
  64. * web service server is done through this object. Also, this file is the
  65. * coupling point between MAPI and our internal (network) formats, and
  66. * codes. This means that any classes communicating with this one either
  67. * use MAPI syntax (ie. MAPI_E_NOT_ENOUGH_MEMORY) OR use the EC syntax
  68. * (ie. EC_E_NOT_FOUND), but never BOTH.
  69. *
  70. */
  71. #define START_SOAP_CALL retry: \
  72. if(m_lpCmd == NULL) { \
  73. hr = MAPI_E_NETWORK_ERROR; \
  74. goto exitm; \
  75. }
  76. #define END_SOAP_CALL \
  77. if (er == KCERR_END_OF_SESSION && HrReLogon() == hrSuccess) \
  78. goto retry; \
  79. hr = kcerr_to_mapierr(er, MAPI_E_NOT_FOUND); \
  80. if(hr != hrSuccess) \
  81. goto exitm;
  82. WSTransport::WSTransport(ULONG ulUIFlags) :
  83. ECUnknown("WSTransport"), m_ulUIFlags(ulUIFlags),
  84. m_ResolveResultCache("ResolveResult", 4096, 300), m_has_session(false)
  85. {
  86. memset(&m_sServerGuid, 0, sizeof(m_sServerGuid));
  87. }
  88. WSTransport::~WSTransport()
  89. {
  90. if (m_lpCmd != NULL)
  91. this->HrLogOff();
  92. }
  93. HRESULT WSTransport::QueryInterface(REFIID refiid, void **lppInterface)
  94. {
  95. REGISTER_INTERFACE3(ECTransport, WSTransport, this);
  96. return MAPI_E_INTERFACE_NOT_SUPPORTED;
  97. }
  98. HRESULT WSTransport::Create(ULONG ulUIFlags, WSTransport **lppTransport)
  99. {
  100. return alloc_wrap<WSTransport>(ulUIFlags)
  101. .as(IID_ECTransport, lppTransport);
  102. }
  103. /* Creates a transport working on the same session and session group as this transport */
  104. HRESULT WSTransport::HrClone(WSTransport **lppTransport)
  105. {
  106. HRESULT hr;
  107. WSTransport *lpTransport = NULL;
  108. hr = WSTransport::Create(m_ulUIFlags, &lpTransport);
  109. if(hr != hrSuccess)
  110. return hr;
  111. hr = CreateSoapTransport(m_ulUIFlags, m_sProfileProps, &lpTransport->m_lpCmd);
  112. if(hr != hrSuccess)
  113. return hr;
  114. lpTransport->m_ecSessionId = this->m_ecSessionId;
  115. lpTransport->m_ecSessionGroupId = this->m_ecSessionGroupId;
  116. *lppTransport = lpTransport;
  117. return hrSuccess;
  118. }
  119. HRESULT WSTransport::HrOpenTransport(LPMAPISUP lpMAPISup, WSTransport **lppTransport, BOOL bOffline)
  120. {
  121. HRESULT hr = hrSuccess;
  122. object_ptr<WSTransport> lpTransport;
  123. std::string strServerPath;
  124. sGlobalProfileProps sProfileProps;
  125. // Get the username and password from the profile settings
  126. hr = ClientUtil::GetGlobalProfileProperties(lpMAPISup, &sProfileProps);
  127. if(hr != hrSuccess)
  128. return hr;
  129. // TODO: check usernameand serverpath
  130. // Create a transport for this user
  131. hr = WSTransport::Create(MDB_NO_DIALOG, &~lpTransport);
  132. if(hr != hrSuccess)
  133. return hr;
  134. // Log on the transport to the server
  135. hr = lpTransport->HrLogon(sProfileProps);
  136. if(hr != hrSuccess)
  137. return hr;
  138. *lppTransport = lpTransport.release();
  139. return hrSuccess;
  140. }
  141. HRESULT WSTransport::LockSoap()
  142. {
  143. m_hDataLock.lock();
  144. return erSuccess;
  145. }
  146. HRESULT WSTransport::UnLockSoap()
  147. {
  148. //Clean up data create with soap_malloc
  149. if (m_lpCmd && m_lpCmd->soap) {
  150. soap_destroy(m_lpCmd->soap);
  151. soap_end(m_lpCmd->soap);
  152. }
  153. m_hDataLock.unlock();
  154. return erSuccess;
  155. }
  156. HRESULT WSTransport::HrLogon2(const struct sGlobalProfileProps &sProfileProps)
  157. {
  158. HRESULT hr = hrSuccess;
  159. ECRESULT er = erSuccess;
  160. unsigned int ulCapabilities = 0;
  161. unsigned int ulLogonFlags = 0;
  162. unsigned int ulServerCapabilities = 0;
  163. ECSESSIONID ecSessionId = 0;
  164. KCmd* lpCmd = NULL;
  165. bool bPipeConnection = false;
  166. unsigned int ulServerVersion = 0;
  167. struct logonResponse sResponse;
  168. struct xsd__base64Binary sLicenseRequest = {0,0};
  169. convert_context converter;
  170. utf8string strUserName = converter.convert_to<utf8string>(sProfileProps.strUserName);
  171. utf8string strPassword = converter.convert_to<utf8string>(sProfileProps.strPassword);
  172. utf8string strImpersonateUser = converter.convert_to<utf8string>(sProfileProps.strImpersonateUser);
  173. LockSoap();
  174. if (strncmp("file:", sProfileProps.strServerPath.c_str(), 5) == 0)
  175. bPipeConnection = true;
  176. else
  177. bPipeConnection = false;
  178. if (m_lpCmd != nullptr) {
  179. lpCmd = m_lpCmd;
  180. } else if (CreateSoapTransport(m_ulUIFlags, sProfileProps, &lpCmd) != hrSuccess) {
  181. hr = MAPI_E_INVALID_PARAMETER;
  182. goto exit;
  183. }
  184. assert(!sProfileProps.strProfileName.empty());
  185. // Attach session to sessiongroup
  186. m_ecSessionGroupId = g_ecSessionManager.GetSessionGroupId(sProfileProps);
  187. ulCapabilities |= KOPANO_CAP_MAILBOX_OWNER | KOPANO_CAP_MULTI_SERVER | KOPANO_CAP_ENHANCED_ICS | KOPANO_CAP_UNICODE | KOPANO_CAP_MSGLOCK | KOPANO_CAP_MAX_ABCHANGEID | KOPANO_CAP_EXTENDED_ANON;
  188. if (sizeof(ECSESSIONID) == 8)
  189. ulCapabilities |= KOPANO_CAP_LARGE_SESSIONID;
  190. if (bPipeConnection == false) {
  191. /*
  192. * All connections except pipes request compression. The server
  193. * can still reject the request.
  194. */
  195. if(! (sProfileProps.ulProfileFlags & EC_PROFILE_FLAGS_NO_COMPRESSION))
  196. ulCapabilities |= KOPANO_CAP_COMPRESSION; // only to remote server .. windows?
  197. } else if (sProfileProps.ulProfileFlags & EC_PROFILE_FLAGS_NO_UID_AUTH) {
  198. ulLogonFlags |= KOPANO_LOGON_NO_UID_AUTH;
  199. }
  200. // try single signon logon
  201. er = TrySSOLogon(lpCmd, GetServerNameFromPath(sProfileProps.strServerPath.c_str()).c_str(), strUserName, strImpersonateUser, ulCapabilities, m_ecSessionGroupId, (char *)GetAppName().c_str(), &ecSessionId, &ulServerCapabilities, &m_llFlags, &m_sServerGuid, sProfileProps.strClientAppVersion, sProfileProps.strClientAppMisc);
  202. if (er == erSuccess)
  203. goto auth;
  204. // Login with username and password
  205. if (SOAP_OK != lpCmd->ns__logon(const_cast<char *>(strUserName.c_str()),
  206. const_cast<char *>(strPassword.c_str()),
  207. const_cast<char *>(strImpersonateUser.c_str()),
  208. const_cast<char *>(PROJECT_VERSION_CLIENT_STR), ulCapabilities,
  209. ulLogonFlags, sLicenseRequest, m_ecSessionGroupId,
  210. const_cast<char *>(GetAppName().c_str()),
  211. const_cast<char *>(sProfileProps.strClientAppVersion.c_str()),
  212. const_cast<char *>(sProfileProps.strClientAppMisc.c_str()),
  213. &sResponse)) {
  214. const char *d = soap_check_faultdetail(lpCmd->soap);
  215. ec_log_err("gsoap connect: %s", d == nullptr ? "()" : d);
  216. er = KCERR_SERVER_NOT_RESPONDING;
  217. } else {
  218. er = sResponse.er;
  219. }
  220. // If the user was denied, and the server did not support encryption, and the password was encrypted, decrypt it now
  221. // so that we support older servers. If the password was not encrypted, then it was just wrong, and if the server supported encryption
  222. // then the password was also simply wrong.
  223. if (er == KCERR_LOGON_FAILED &&
  224. SymmetricIsCrypted(sProfileProps.strPassword.c_str()) &&
  225. !(sResponse.ulCapabilities & KOPANO_CAP_CRYPT)) {
  226. // Login with username and password
  227. if (SOAP_OK != lpCmd->ns__logon(const_cast<char *>(strUserName.c_str()),
  228. const_cast<char *>(SymmetricDecrypt(sProfileProps.strPassword.c_str()).c_str()),
  229. const_cast<char *>(strImpersonateUser.c_str()),
  230. const_cast<char *>(PROJECT_VERSION_CLIENT_STR),
  231. ulCapabilities, ulLogonFlags, sLicenseRequest,
  232. m_ecSessionGroupId,
  233. const_cast<char *>(GetAppName().c_str()),
  234. const_cast<char *>(sProfileProps.strClientAppVersion.c_str()),
  235. const_cast<char *>(sProfileProps.strClientAppMisc.c_str()),
  236. &sResponse))
  237. er = KCERR_SERVER_NOT_RESPONDING;
  238. else
  239. er = sResponse.er;
  240. }
  241. hr = kcerr_to_mapierr(er, MAPI_E_LOGON_FAILED);
  242. if (hr != hrSuccess)
  243. goto exit;
  244. /*
  245. * Version is retrieved but not analyzed because we want to be able to
  246. * connect to old servers for development.
  247. */
  248. er = ParseKopanoVersion(sResponse.lpszVersion, &ulServerVersion);
  249. if (er != erSuccess) {
  250. hr = MAPI_E_VERSION;
  251. goto exit;
  252. }
  253. ecSessionId = sResponse.ulSessionId;
  254. ulServerCapabilities = sResponse.ulCapabilities;
  255. if (sResponse.sServerGuid.__ptr != NULL && sResponse.sServerGuid.__size == sizeof(m_sServerGuid))
  256. memcpy(&m_sServerGuid, sResponse.sServerGuid.__ptr, sizeof(m_sServerGuid));
  257. // From here the login is ok
  258. auth: // User have a logon
  259. // See if the server supports impersonation. If it doesn't but imporsonation was attempted,
  260. // we should fail now because the client won't expect his own store to be returned.
  261. if (!strImpersonateUser.empty() && (sResponse.ulCapabilities & KOPANO_CAP_IMPERSONATION) == 0) {
  262. hr = MAPI_E_NO_SUPPORT; // or just MAPI_E_LOGON_FAILED?
  263. goto exit;
  264. }
  265. if (ulServerCapabilities & KOPANO_CAP_COMPRESSION) {
  266. /*
  267. * GSOAP autodetects incoming compression, so even if not
  268. * explicitly enabled, it will be accepted.
  269. */
  270. soap_set_imode(lpCmd->soap, SOAP_ENC_ZLIB);
  271. soap_set_omode(lpCmd->soap, SOAP_ENC_ZLIB | SOAP_IO_CHUNK);
  272. }
  273. m_sProfileProps = sProfileProps;
  274. m_ulServerCapabilities = ulServerCapabilities;
  275. m_ecSessionId = ecSessionId;
  276. m_has_session = true;
  277. m_lpCmd = lpCmd;
  278. exit:
  279. UnLockSoap();
  280. if (hr != hrSuccess && lpCmd != nullptr && lpCmd != m_lpCmd)
  281. // UGLY FIX: due to the ugly code above that does lpCmd = m_lpCmd
  282. // we need to check that we're not deleting our m_lpCmd. We also cannot
  283. // set m_lpCmd to NULL since various functions in WSTransport rely on the
  284. // fact that m_lpCmd is good after a successful HrLogon() call.
  285. DestroySoapTransport(lpCmd);
  286. return hr;
  287. }
  288. HRESULT WSTransport::HrLogon(const struct sGlobalProfileProps &in_props)
  289. {
  290. if (m_has_session)
  291. logoff_nd();
  292. if (in_props.strServerPath.compare("default:") != 0)
  293. return HrLogon2(in_props);
  294. struct sGlobalProfileProps p = in_props;
  295. p.strServerPath = "file:///var/run/kopano/server.sock";
  296. return HrLogon2(p);
  297. }
  298. HRESULT WSTransport::HrSetRecvTimeout(unsigned int ulSeconds)
  299. {
  300. if (this->m_lpCmd == NULL)
  301. return MAPI_E_NOT_INITIALIZED;
  302. this->m_lpCmd->soap->recv_timeout = ulSeconds;
  303. return hrSuccess;
  304. }
  305. HRESULT WSTransport::CreateAndLogonAlternate(LPCSTR szServer, WSTransport **lppTransport) const
  306. {
  307. HRESULT hr = hrSuccess;
  308. object_ptr<WSTransport> lpTransport;
  309. sGlobalProfileProps sProfileProps = m_sProfileProps;
  310. if (lppTransport == nullptr)
  311. return MAPI_E_INVALID_PARAMETER;
  312. hr = WSTransport::Create(m_ulUIFlags, &~lpTransport);
  313. if (hr != hrSuccess)
  314. return hr;
  315. sProfileProps.strServerPath = szServer;
  316. hr = lpTransport->HrLogon(sProfileProps);
  317. if (hr != hrSuccess)
  318. return hr;
  319. *lppTransport = lpTransport.release();
  320. return hrSuccess;
  321. }
  322. /**
  323. * Create a new transport based on the current configuration and
  324. * logon to the server.
  325. *
  326. * @param[out] lppTransport The new transport
  327. * @return HRESULT
  328. */
  329. HRESULT WSTransport::CloneAndRelogon(WSTransport **lppTransport) const
  330. {
  331. HRESULT hr = hrSuccess;
  332. object_ptr<WSTransport> lpTransport;
  333. if (lppTransport == nullptr)
  334. return MAPI_E_INVALID_PARAMETER;
  335. hr = WSTransport::Create(m_ulUIFlags, &~lpTransport);
  336. if (hr != hrSuccess)
  337. return hr;
  338. hr = lpTransport->HrLogon(m_sProfileProps);
  339. if (hr != hrSuccess)
  340. return hr;
  341. *lppTransport = lpTransport.release();
  342. return hrSuccess;
  343. }
  344. HRESULT WSTransport::HrReLogon()
  345. {
  346. HRESULT hr = HrLogon(m_sProfileProps);
  347. if(hr != hrSuccess)
  348. return hr;
  349. // Notify new session to listeners
  350. scoped_rlock lock(m_mutexSessionReload);
  351. for (const auto &p : m_mapSessionReload)
  352. p.second.second(p.second.first, this->m_ecSessionId);
  353. return hrSuccess;
  354. }
  355. ECRESULT WSTransport::TrySSOLogon(KCmd* lpCmd, LPCSTR szServer, utf8string strUsername, utf8string strImpersonateUser, unsigned int ulCapabilities, ECSESSIONGROUPID ecSessionGroupId, char *szAppName, ECSESSIONID* lpSessionId, unsigned int* lpulServerCapabilities, unsigned long long *lpllFlags, LPGUID lpsServerGuid, const std::string appVersion, const std::string appMisc)
  356. {
  357. #define KOPANO_GSS_SERVICE "kopano"
  358. ECRESULT er = KCERR_LOGON_FAILED;
  359. #ifdef HAVE_GSSAPI
  360. OM_uint32 minor, major;
  361. gss_buffer_desc pr_buf;
  362. gss_name_t principal = GSS_C_NO_NAME;
  363. gss_ctx_id_t gss_ctx = GSS_C_NO_CONTEXT;
  364. gss_OID_desc mech_spnego = {6, const_cast<char *>("\053\006\001\005\005\002")};
  365. gss_buffer_desc secbufout, secbufin;
  366. struct xsd__base64Binary sso_data;
  367. struct ssoLogonResponse resp;
  368. struct xsd__base64Binary licreq = {0, 0};
  369. pr_buf.value = const_cast<char *>(KOPANO_GSS_SERVICE);
  370. pr_buf.length = sizeof(KOPANO_GSS_SERVICE) - 1;
  371. /* GSSAPI automagically appends @server */
  372. major = gss_import_name(&minor, &pr_buf,
  373. GSS_C_NT_HOSTBASED_SERVICE, &principal);
  374. if (GSS_ERROR(major))
  375. goto exit;
  376. resp.ulSessionId = 0;
  377. do {
  378. major = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL,
  379. &gss_ctx, principal, &mech_spnego, GSS_C_CONF_FLAG,
  380. GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS,
  381. resp.ulSessionId == 0 ? GSS_C_NO_BUFFER : &secbufin,
  382. nullptr, &secbufout, nullptr, nullptr);
  383. if (GSS_ERROR(major))
  384. goto exit;
  385. /* Send GSS state to kopano-server */
  386. sso_data.__ptr = reinterpret_cast<unsigned char *>(secbufout.value);
  387. sso_data.__size = secbufout.length;
  388. if (lpCmd->ns__ssoLogon(resp.ulSessionId,
  389. const_cast<char *>(strUsername.c_str()),
  390. const_cast<char *>(strImpersonateUser.c_str()), &sso_data,
  391. const_cast<char *>(PROJECT_VERSION_CLIENT_STR),
  392. ulCapabilities, licreq, ecSessionGroupId, szAppName,
  393. const_cast<char *>(appVersion.c_str()),
  394. const_cast<char *>(appMisc.c_str()), &resp) != SOAP_OK)
  395. goto exit;
  396. if (resp.er != KCERR_SSO_CONTINUE)
  397. break;
  398. secbufin.value = static_cast<void *>(resp.lpOutput->__ptr);
  399. secbufin.length = resp.lpOutput->__size;
  400. gss_release_buffer(&minor, &secbufout);
  401. /* Return kopano-server response to GSS */
  402. } while (true);
  403. er = resp.er;
  404. if (er != erSuccess)
  405. goto exit;
  406. *lpSessionId = resp.ulSessionId;
  407. *lpulServerCapabilities = resp.ulCapabilities;
  408. if (resp.sServerGuid.__ptr != nullptr &&
  409. resp.sServerGuid.__size == sizeof(*lpsServerGuid))
  410. memcpy(lpsServerGuid, resp.sServerGuid.__ptr, sizeof(*lpsServerGuid));
  411. exit:
  412. gss_release_buffer(&minor, &secbufout);
  413. gss_delete_sec_context(&minor, &gss_ctx, nullptr);
  414. gss_release_name(&minor, &principal);
  415. #endif
  416. return er;
  417. #undef KOPANO_GSS_SERVICE
  418. }
  419. HRESULT WSTransport::HrGetPublicStore(ULONG ulFlags, ULONG* lpcbStoreID, LPENTRYID* lppStoreID, string *lpstrRedirServer)
  420. {
  421. ECRESULT er = erSuccess;
  422. HRESULT hr = hrSuccess;
  423. struct getStoreResponse sResponse;
  424. LockSoap();
  425. if ((ulFlags & ~EC_OVERRIDE_HOMESERVER) != 0) {
  426. hr = MAPI_E_UNKNOWN_FLAGS;
  427. goto exitm;
  428. }
  429. if(lppStoreID == NULL) {
  430. hr = MAPI_E_INVALID_PARAMETER;
  431. goto exitm;
  432. }
  433. START_SOAP_CALL
  434. {
  435. if(SOAP_OK != m_lpCmd->ns__getPublicStore(m_ecSessionId, ulFlags, &sResponse))
  436. er = KCERR_SERVER_NOT_RESPONDING;
  437. else
  438. er = sResponse.er;
  439. }
  440. //END_SOAP_CALL
  441. if (er == KCERR_END_OF_SESSION && HrReLogon() == hrSuccess)
  442. goto retry;
  443. hr = kcerr_to_mapierr(er, MAPI_E_NOT_FOUND);
  444. if (hr == MAPI_E_UNABLE_TO_COMPLETE)
  445. {
  446. if (lpstrRedirServer)
  447. *lpstrRedirServer = sResponse.lpszServerPath;
  448. else
  449. hr = MAPI_E_NOT_FOUND;
  450. }
  451. if(hr != hrSuccess)
  452. goto exitm;
  453. // Create a client store entry, add the servername
  454. hr = WrapServerClientStoreEntry(sResponse.lpszServerPath ? sResponse.lpszServerPath : m_sProfileProps.strServerPath.c_str(), &sResponse.sStoreId, lpcbStoreID, lppStoreID);
  455. if(hr != hrSuccess)
  456. goto exitm;
  457. exitm:
  458. UnLockSoap();
  459. return hr;
  460. }
  461. HRESULT WSTransport::HrGetStore(ULONG cbMasterID, LPENTRYID lpMasterID, ULONG* lpcbStoreID, LPENTRYID* lppStoreID, ULONG* lpcbRootID, LPENTRYID* lppRootID, string *lpstrRedirServer)
  462. {
  463. ECRESULT er = erSuccess;
  464. HRESULT hr = hrSuccess;
  465. entryId sEntryId = {0,0}; // Do not free
  466. struct getStoreResponse sResponse;
  467. ecmem_ptr<ENTRYID> lpUnWrapStoreID;
  468. ULONG cbUnWrapStoreID = 0;
  469. LockSoap();
  470. if(lpMasterID) {
  471. hr = UnWrapServerClientStoreEntry(cbMasterID, lpMasterID, &cbUnWrapStoreID, &~lpUnWrapStoreID);
  472. if(hr != hrSuccess)
  473. goto exitm;
  474. sEntryId.__ptr = reinterpret_cast<unsigned char *>(lpUnWrapStoreID.get());
  475. sEntryId.__size = cbUnWrapStoreID;
  476. }
  477. START_SOAP_CALL
  478. {
  479. if(SOAP_OK != m_lpCmd->ns__getStore(m_ecSessionId, (lpMasterID)?&sEntryId:NULL, &sResponse))
  480. er = KCERR_SERVER_NOT_RESPONDING;
  481. else
  482. er = sResponse.er;
  483. }
  484. //END_SOAP_CALL
  485. if (er == KCERR_END_OF_SESSION && HrReLogon() == hrSuccess)
  486. goto retry;
  487. hr = kcerr_to_mapierr(er, MAPI_E_NOT_FOUND);
  488. if (hr == MAPI_E_UNABLE_TO_COMPLETE)
  489. {
  490. if (lpstrRedirServer)
  491. *lpstrRedirServer = sResponse.lpszServerPath;
  492. else
  493. hr = MAPI_E_NOT_FOUND;
  494. }
  495. if(hr != hrSuccess)
  496. goto exitm;
  497. if(lppRootID && lpcbRootID) {
  498. hr = CopySOAPEntryIdToMAPIEntryId(&sResponse.sRootId, lpcbRootID, lppRootID);
  499. if(hr != hrSuccess)
  500. goto exitm;
  501. }
  502. if(lppStoreID && lpcbStoreID) {
  503. // Create a client store entry, add the servername
  504. hr = WrapServerClientStoreEntry(sResponse.lpszServerPath ? sResponse.lpszServerPath : m_sProfileProps.strServerPath.c_str(), &sResponse.sStoreId, lpcbStoreID, lppStoreID);
  505. if(hr != hrSuccess)
  506. goto exitm;
  507. }
  508. exitm:
  509. UnLockSoap();
  510. return hr;
  511. }
  512. HRESULT WSTransport::HrGetStoreName(ULONG cbStoreID, LPENTRYID lpStoreID, ULONG ulFlags, LPTSTR *lppszStoreName)
  513. {
  514. ECRESULT er = erSuccess;
  515. HRESULT hr = hrSuccess;
  516. entryId sEntryId; // Do not free
  517. struct getStoreNameResponse sResponse;
  518. ecmem_ptr<ENTRYID> lpUnWrapStoreID;
  519. ULONG cbUnWrapStoreID = 0;
  520. LockSoap();
  521. if(lpStoreID == NULL || lppszStoreName == NULL) {
  522. hr = MAPI_E_INVALID_PARAMETER;
  523. goto exitm;
  524. }
  525. // Remove the servername
  526. hr = UnWrapServerClientStoreEntry(cbStoreID, lpStoreID, &cbUnWrapStoreID, &~lpUnWrapStoreID);
  527. if(hr != hrSuccess)
  528. goto exitm;
  529. sEntryId.__ptr = reinterpret_cast<unsigned char *>(lpUnWrapStoreID.get());
  530. sEntryId.__size = cbUnWrapStoreID;
  531. START_SOAP_CALL
  532. {
  533. if(SOAP_OK != m_lpCmd->ns__getStoreName(m_ecSessionId, sEntryId, &sResponse))
  534. er = KCERR_SERVER_NOT_RESPONDING;
  535. else
  536. er = sResponse.er;
  537. }
  538. END_SOAP_CALL
  539. hr = Utf8ToTString(sResponse.lpszStoreName, ulFlags, NULL, NULL, lppszStoreName);
  540. exitm:
  541. UnLockSoap();
  542. return hr;
  543. }
  544. HRESULT WSTransport::HrGetStoreType(ULONG cbStoreID, LPENTRYID lpStoreID, ULONG *lpulStoreType)
  545. {
  546. ECRESULT er = erSuccess;
  547. HRESULT hr = hrSuccess;
  548. entryId sEntryId; // Do not free
  549. struct getStoreTypeResponse sResponse;
  550. ecmem_ptr<ENTRYID> lpUnWrapStoreID;
  551. ULONG cbUnWrapStoreID = 0;
  552. LockSoap();
  553. if(lpStoreID == NULL || lpulStoreType == NULL) {
  554. hr = MAPI_E_INVALID_PARAMETER;
  555. goto exitm;
  556. }
  557. // Remove the servername
  558. hr = UnWrapServerClientStoreEntry(cbStoreID, lpStoreID, &cbUnWrapStoreID, &~lpUnWrapStoreID);
  559. if(hr != hrSuccess)
  560. goto exitm;
  561. sEntryId.__ptr = reinterpret_cast<unsigned char *>(lpUnWrapStoreID.get());
  562. sEntryId.__size = cbUnWrapStoreID;
  563. START_SOAP_CALL
  564. {
  565. if(SOAP_OK != m_lpCmd->ns__getStoreType(m_ecSessionId, sEntryId, &sResponse))
  566. er = KCERR_SERVER_NOT_RESPONDING;
  567. else
  568. er = sResponse.er;
  569. }
  570. END_SOAP_CALL
  571. *lpulStoreType = sResponse.ulStoreType;
  572. exitm:
  573. UnLockSoap();
  574. return hr;
  575. }
  576. HRESULT WSTransport::HrLogOff()
  577. {
  578. HRESULT hr = hrSuccess;
  579. ECRESULT er = erSuccess;
  580. LockSoap();
  581. START_SOAP_CALL
  582. {
  583. if(SOAP_OK != m_lpCmd->ns__logoff(m_ecSessionId, &er) )
  584. er = KCERR_NETWORK_ERROR;
  585. else
  586. m_has_session = false;
  587. DestroySoapTransport(m_lpCmd);
  588. m_lpCmd = NULL;
  589. }
  590. END_SOAP_CALL
  591. exitm:
  592. UnLockSoap();
  593. return hrSuccess; // NOTE hrSuccess, never fails since we don't really mind that it failed.
  594. }
  595. HRESULT WSTransport::logoff_nd(void)
  596. {
  597. HRESULT hr = hrSuccess;
  598. ECRESULT er = erSuccess;
  599. LockSoap();
  600. START_SOAP_CALL
  601. {
  602. if (m_lpCmd->ns__logoff(m_ecSessionId, &er) != SOAP_OK)
  603. er = KCERR_NETWORK_ERROR;
  604. else
  605. m_has_session = false;
  606. }
  607. END_SOAP_CALL
  608. exitm:
  609. UnLockSoap();
  610. return er;
  611. }
  612. HRESULT WSTransport::HrCheckExistObject(ULONG cbEntryID, LPENTRYID lpEntryID, ULONG ulFlags)
  613. {
  614. HRESULT hr = hrSuccess;
  615. ECRESULT er = erSuccess;
  616. entryId sEntryId = {0}; // Do not free
  617. LockSoap();
  618. if(cbEntryID == 0 || lpEntryID == NULL) {
  619. hr = MAPI_E_INVALID_ENTRYID;
  620. goto exitm;
  621. }
  622. hr = CopyMAPIEntryIdToSOAPEntryId(cbEntryID, lpEntryID, &sEntryId, true);
  623. if(hr != hrSuccess)
  624. goto exitm;
  625. START_SOAP_CALL
  626. {
  627. if(SOAP_OK != m_lpCmd->ns__checkExistObject(m_ecSessionId, sEntryId, ulFlags, &er))
  628. er = KCERR_SERVER_NOT_RESPONDING;
  629. }
  630. END_SOAP_CALL
  631. exitm:
  632. UnLockSoap();
  633. return hr;
  634. }
  635. HRESULT WSTransport::HrOpenPropStorage(ULONG cbParentEntryID, LPENTRYID lpParentEntryID, ULONG cbEntryID, LPENTRYID lpEntryID, ULONG ulFlags, IECPropStorage **lppPropStorage)
  636. {
  637. HRESULT hr = hrSuccess;
  638. object_ptr<WSMAPIPropStorage> lpPropStorage;
  639. ecmem_ptr<ENTRYID> lpUnWrapParentID, lpUnWrapEntryID;
  640. ULONG cbUnWrapParentID = 0;
  641. ULONG cbUnWrapEntryID = 0;
  642. if (lpParentEntryID) {
  643. hr = UnWrapServerClientStoreEntry(cbParentEntryID, lpParentEntryID, &cbUnWrapParentID, &~lpUnWrapParentID);
  644. if(hr != hrSuccess)
  645. return hr;
  646. }
  647. hr = UnWrapServerClientStoreEntry(cbEntryID, lpEntryID, &cbUnWrapEntryID, &~lpUnWrapEntryID);
  648. if(hr != hrSuccess)
  649. return hr;
  650. hr = WSMAPIPropStorage::Create(cbUnWrapParentID, lpUnWrapParentID,
  651. cbUnWrapEntryID, lpUnWrapEntryID, ulFlags, m_lpCmd, m_hDataLock,
  652. m_ecSessionId, this->m_ulServerCapabilities, this, &~lpPropStorage);
  653. if(hr != hrSuccess)
  654. return hr;
  655. return lpPropStorage->QueryInterface(IID_IECPropStorage, (void **)lppPropStorage);
  656. }
  657. HRESULT WSTransport::HrOpenParentStorage(ECGenericProp *lpParentObject, ULONG ulUniqueId, ULONG ulObjId, IECPropStorage *lpServerStorage, IECPropStorage **lppPropStorage)
  658. {
  659. HRESULT hr = hrSuccess;
  660. object_ptr<ECParentStorage> lpPropStorage;
  661. hr = ECParentStorage::Create(lpParentObject, ulUniqueId, ulObjId, lpServerStorage, &~lpPropStorage);
  662. if(hr != hrSuccess)
  663. return hr;
  664. return lpPropStorage->QueryInterface(IID_IECPropStorage,
  665. reinterpret_cast<void **>(lppPropStorage));
  666. }
  667. HRESULT WSTransport::HrOpenABPropStorage(ULONG cbEntryID, LPENTRYID lpEntryID, IECPropStorage **lppPropStorage)
  668. {
  669. HRESULT hr = hrSuccess;
  670. object_ptr<WSABPropStorage> lpPropStorage;
  671. ecmem_ptr<ENTRYID> lpUnWrapStoreID;
  672. ULONG cbUnWrapStoreID = 0;
  673. hr = UnWrapServerClientABEntry(cbEntryID, lpEntryID, &cbUnWrapStoreID, &~lpUnWrapStoreID);
  674. if(hr != hrSuccess)
  675. return hr;
  676. hr = WSABPropStorage::Create(cbUnWrapStoreID, lpUnWrapStoreID, m_lpCmd,
  677. m_hDataLock, m_ecSessionId, this, &~lpPropStorage);
  678. if(hr != hrSuccess)
  679. return hr;
  680. return lpPropStorage->QueryInterface(IID_IECPropStorage,
  681. reinterpret_cast<void **>(lppPropStorage));
  682. }
  683. HRESULT WSTransport::HrOpenFolderOps(ULONG cbEntryID, LPENTRYID lpEntryID, WSMAPIFolderOps **lppFolderOps)
  684. {
  685. HRESULT hr = hrSuccess;
  686. ecmem_ptr<ENTRYID> lpUnWrapStoreID;
  687. ULONG cbUnWrapStoreID = 0;
  688. //FIXME: create this function
  689. // hr = CheckEntryIDType(cbEntryID, lpEntryID, MAPI_FOLDER);
  690. // if( hr != hrSuccess)
  691. //return hr;
  692. hr = UnWrapServerClientStoreEntry(cbEntryID, lpEntryID, &cbUnWrapStoreID, &~lpUnWrapStoreID);
  693. if(hr != hrSuccess)
  694. return hr;
  695. return WSMAPIFolderOps::Create(m_lpCmd, m_hDataLock, m_ecSessionId,
  696. cbUnWrapStoreID, lpUnWrapStoreID, this, lppFolderOps);
  697. }
  698. HRESULT WSTransport::HrOpenTableOps(ULONG ulType, ULONG ulFlags, ULONG cbEntryID, LPENTRYID lpEntryID, ECMsgStore *lpMsgStore, WSTableView **lppTableOps)
  699. {
  700. /*
  701. FIXME: Do a check ?
  702. if (peid->ulType != MAPI_FOLDER && peid->ulType != MAPI_MESSAGE)
  703. return MAPI_E_INVALID_ENTRYID;
  704. */
  705. return WSStoreTableView::Create(ulType, ulFlags, m_lpCmd, m_hDataLock,
  706. m_ecSessionId, cbEntryID, lpEntryID, lpMsgStore, this,
  707. lppTableOps);
  708. }
  709. HRESULT WSTransport::HrOpenABTableOps(ULONG ulType, ULONG ulFlags, ULONG cbEntryID, LPENTRYID lpEntryID, ECABLogon* lpABLogon, WSTableView **lppTableOps)
  710. {
  711. /*if (peid->ulType != MAPI_FOLDER && peid->ulType != MAPI_MESSAGE)
  712. return MAPI_E_INVALID_ENTRYID;
  713. */
  714. return WSABTableView::Create(ulType, ulFlags, m_lpCmd, m_hDataLock,
  715. m_ecSessionId, cbEntryID, lpEntryID, lpABLogon, this,
  716. lppTableOps);
  717. }
  718. HRESULT WSTransport::HrOpenMailBoxTableOps(ULONG ulFlags, ECMsgStore *lpMsgStore, WSTableView **lppTableView)
  719. {
  720. HRESULT hr = hrSuccess;
  721. object_ptr<WSTableMailBox> lpWSTable;
  722. hr = WSTableMailBox::Create(ulFlags, m_lpCmd, m_hDataLock,
  723. m_ecSessionId, lpMsgStore, this, &~lpWSTable);
  724. if(hr != hrSuccess)
  725. return hr;
  726. return lpWSTable->QueryInterface(IID_ECTableView,
  727. reinterpret_cast<void **>(lppTableView));
  728. }
  729. HRESULT WSTransport::HrOpenTableOutGoingQueueOps(ULONG cbStoreEntryID, LPENTRYID lpStoreEntryID, ECMsgStore *lpMsgStore, WSTableOutGoingQueue **lppTableOutGoingQueueOps)
  730. {
  731. HRESULT hr = hrSuccess;
  732. ecmem_ptr<ENTRYID> lpUnWrapStoreID;
  733. ULONG cbUnWrapStoreID = 0;
  734. // lpStoreEntryID == null for master queue
  735. if(lpStoreEntryID) {
  736. hr = UnWrapServerClientStoreEntry(cbStoreEntryID, lpStoreEntryID, &cbUnWrapStoreID, &~lpUnWrapStoreID);
  737. if(hr != hrSuccess)
  738. return hr;
  739. }
  740. return WSTableOutGoingQueue::Create(m_lpCmd, m_hDataLock, m_ecSessionId,
  741. cbUnWrapStoreID, lpUnWrapStoreID, lpMsgStore, this,
  742. lppTableOutGoingQueueOps);
  743. }
  744. HRESULT WSTransport::HrDeleteObjects(ULONG ulFlags, LPENTRYLIST lpMsgList, ULONG ulSyncId)
  745. {
  746. ECRESULT er = erSuccess;
  747. HRESULT hr = hrSuccess;
  748. struct entryList sEntryList;
  749. LockSoap();
  750. memset(&sEntryList, 0, sizeof(struct entryList));
  751. if(lpMsgList->cValues == 0)
  752. goto exitm;
  753. hr = CopyMAPIEntryListToSOAPEntryList(lpMsgList, &sEntryList);
  754. if(hr != hrSuccess)
  755. goto exitm;
  756. START_SOAP_CALL
  757. {
  758. if(SOAP_OK != m_lpCmd->ns__deleteObjects(m_ecSessionId, ulFlags, &sEntryList, ulSyncId, &er))
  759. er = KCERR_NETWORK_ERROR;
  760. }
  761. END_SOAP_CALL
  762. exitm:
  763. UnLockSoap();
  764. FreeEntryList(&sEntryList, false);
  765. return hr;
  766. }
  767. HRESULT WSTransport::HrNotify(LPNOTIFICATION lpNotification)
  768. {
  769. HRESULT hr = hrSuccess;
  770. ECRESULT er = erSuccess;
  771. struct notification sNotification;
  772. int ulSize = 0;
  773. memset(&sNotification, 0, sizeof(struct notification));
  774. LockSoap();
  775. //FIMXE: also notify other types ?
  776. if(lpNotification == NULL || lpNotification->ulEventType != fnevNewMail)
  777. {
  778. hr = MAPI_E_NO_ACCESS;
  779. goto exitm;
  780. }
  781. sNotification.ulConnection = 0;// The connection id should be calculate on the server side
  782. sNotification.ulEventType = lpNotification->ulEventType;
  783. sNotification.newmail = s_alloc<notificationNewMail>(nullptr);
  784. memset(sNotification.newmail, 0, sizeof(notificationNewMail));
  785. hr = CopyMAPIEntryIdToSOAPEntryId(lpNotification->info.newmail.cbEntryID, (LPENTRYID)lpNotification->info.newmail.lpEntryID, &sNotification.newmail->pEntryId);
  786. if(hr != hrSuccess)
  787. goto exitm;
  788. hr = CopyMAPIEntryIdToSOAPEntryId(lpNotification->info.newmail.cbParentID, (LPENTRYID)lpNotification->info.newmail.lpParentID, &sNotification.newmail->pParentId);
  789. if(hr != hrSuccess)
  790. goto exitm;
  791. if(lpNotification->info.newmail.lpszMessageClass){
  792. utf8string strMessageClass = convstring(lpNotification->info.newmail.lpszMessageClass, lpNotification->info.newmail.ulFlags);
  793. ulSize = strMessageClass.size() + 1;
  794. sNotification.newmail->lpszMessageClass = s_alloc<char>(nullptr, ulSize);
  795. memcpy(sNotification.newmail->lpszMessageClass, strMessageClass.c_str(), ulSize);
  796. }
  797. sNotification.newmail->ulMessageFlags = lpNotification->info.newmail.ulMessageFlags;
  798. START_SOAP_CALL
  799. {
  800. if(SOAP_OK != m_lpCmd->ns__notify(m_ecSessionId, sNotification, &er)) {
  801. er = KCERR_NETWORK_ERROR;
  802. }
  803. }
  804. END_SOAP_CALL
  805. exitm:
  806. UnLockSoap();
  807. FreeNotificationStruct(&sNotification, false);
  808. return hr;
  809. }
  810. HRESULT WSTransport::HrSubscribe(ULONG cbKey, LPBYTE lpKey, ULONG ulConnection, ULONG ulEventMask)
  811. {
  812. HRESULT hr = hrSuccess;
  813. ECRESULT er = erSuccess;
  814. notifySubscribe notSubscribe{__gszeroinit};
  815. LockSoap();
  816. notSubscribe.ulConnection = ulConnection;
  817. notSubscribe.sKey.__size = cbKey;
  818. notSubscribe.sKey.__ptr = lpKey;
  819. notSubscribe.ulEventMask = ulEventMask;
  820. START_SOAP_CALL
  821. {
  822. if(SOAP_OK != m_lpCmd->ns__notifySubscribe(m_ecSessionId, &notSubscribe, &er))
  823. er = KCERR_NETWORK_ERROR;
  824. }
  825. END_SOAP_CALL
  826. exitm:
  827. UnLockSoap();
  828. return hr;
  829. }
  830. HRESULT WSTransport::HrSubscribe(ULONG ulSyncId, ULONG ulChangeId, ULONG ulConnection, ULONG ulEventMask)
  831. {
  832. HRESULT hr = hrSuccess;
  833. ECRESULT er = erSuccess;
  834. notifySubscribe notSubscribe{__gszeroinit};
  835. LockSoap();
  836. notSubscribe.ulConnection = ulConnection;
  837. notSubscribe.sSyncState.ulSyncId = ulSyncId;
  838. notSubscribe.sSyncState.ulChangeId = ulChangeId;
  839. notSubscribe.ulEventMask = ulEventMask;
  840. START_SOAP_CALL
  841. {
  842. if(SOAP_OK != m_lpCmd->ns__notifySubscribe(m_ecSessionId, &notSubscribe, &er))
  843. er = KCERR_NETWORK_ERROR;
  844. }
  845. END_SOAP_CALL
  846. exitm:
  847. UnLockSoap();
  848. return hr;
  849. }
  850. HRESULT WSTransport::HrSubscribeMulti(const ECLISTSYNCADVISE &lstSyncAdvises, ULONG ulEventMask)
  851. {
  852. HRESULT hr = hrSuccess;
  853. ECRESULT er = erSuccess;
  854. notifySubscribeArray notSubscribeArray{__gszeroinit};
  855. unsigned i = 0;
  856. LockSoap();
  857. notSubscribeArray.__size = lstSyncAdvises.size();
  858. hr = MAPIAllocateBuffer(notSubscribeArray.__size * sizeof *notSubscribeArray.__ptr, (void**)&notSubscribeArray.__ptr);
  859. if (hr != hrSuccess)
  860. goto exitm;
  861. memset(notSubscribeArray.__ptr, 0, notSubscribeArray.__size * sizeof *notSubscribeArray.__ptr);
  862. for (const auto &adv : lstSyncAdvises) {
  863. notSubscribeArray.__ptr[i].ulConnection = adv.ulConnection;
  864. notSubscribeArray.__ptr[i].sSyncState.ulSyncId = adv.sSyncState.ulSyncId;
  865. notSubscribeArray.__ptr[i].sSyncState.ulChangeId = adv.sSyncState.ulChangeId;
  866. notSubscribeArray.__ptr[i].ulEventMask = ulEventMask;
  867. ++i;
  868. }
  869. START_SOAP_CALL
  870. {
  871. if(SOAP_OK != m_lpCmd->ns__notifySubscribeMulti(m_ecSessionId, &notSubscribeArray, &er))
  872. er = KCERR_NETWORK_ERROR;
  873. }
  874. END_SOAP_CALL
  875. exitm:
  876. MAPIFreeBuffer(notSubscribeArray.__ptr);
  877. UnLockSoap();
  878. return hr;
  879. }
  880. HRESULT WSTransport::HrUnSubscribe(ULONG ulConnection)
  881. {
  882. HRESULT hr = hrSuccess;
  883. ECRESULT er = erSuccess;
  884. LockSoap();
  885. START_SOAP_CALL
  886. {
  887. if(SOAP_OK != m_lpCmd->ns__notifyUnSubscribe(m_ecSessionId, ulConnection, &er) )
  888. er = KCERR_NETWORK_ERROR;
  889. }
  890. END_SOAP_CALL
  891. exitm:
  892. UnLockSoap();
  893. return hr;
  894. }
  895. HRESULT WSTransport::HrUnSubscribeMulti(const ECLISTCONNECTION &lstConnections)
  896. {
  897. HRESULT hr = hrSuccess;
  898. ECRESULT er = erSuccess;
  899. mv_long ulConnArray = {0};
  900. unsigned i = 0;
  901. ulConnArray.__size = lstConnections.size();
  902. ulConnArray.__ptr = s_alloc<unsigned int>(nullptr, ulConnArray.__size);
  903. LockSoap();
  904. for (const auto &p : lstConnections)
  905. ulConnArray.__ptr[i++] = p.second;
  906. START_SOAP_CALL
  907. {
  908. if(SOAP_OK != m_lpCmd->ns__notifyUnSubscribeMulti(m_ecSessionId, &ulConnArray, &er) )
  909. er = KCERR_NETWORK_ERROR;
  910. }
  911. END_SOAP_CALL
  912. exitm:
  913. UnLockSoap();
  914. s_free(nullptr, ulConnArray.__ptr);
  915. return hr;
  916. }
  917. /**
  918. * Export a set of messages as stream.
  919. * This method MUST be called on a WSTransport that's dedicated for exporting because no locking is performed.
  920. *
  921. * @param[in] ulFlags Flags used to determine which messages and what data is to be exported.
  922. * @param[in] ulPropTag Either PR_ENTRYID or PR_SOURCE_KEY. Indicates which identifier is used in lpChanges[x].sSourceKey
  923. * @param[in] lpChanges The complete set of changes available.
  924. * @param[in] ulStart The index in sChanges that specifies the first message to export.
  925. * @param[in] ulChanges The number of messages to export, starting at ulStart. ulStart and ulCount must not me larger than the amount of available changes.
  926. * @param[in] lpsProps The set of proptags that will be returned as regular properties outside the stream.
  927. * @param[out] lppsStreamExporter The streamexporter that must be used to get the individual streams.
  928. *
  929. * @retval MAPI_E_INVALID_PARAMETER lpChanges or lpsProps == NULL
  930. * @retval MAPI_E_NETWORK_ERROR The actual call to the server failed or no streams are returned
  931. */
  932. HRESULT WSTransport::HrExportMessageChangesAsStream(ULONG ulFlags,
  933. ULONG ulPropTag, const ICSCHANGE *lpChanges, ULONG ulStart,
  934. ULONG ulChanges, const SPropTagArray *lpsProps,
  935. WSMessageStreamExporter **lppsStreamExporter)
  936. {
  937. typedef KCHL::memory_ptr<sourceKeyPairArray> sourceKeyPairArrayPtr;
  938. ECRESULT er = erSuccess;
  939. HRESULT hr = hrSuccess;
  940. sourceKeyPairArrayPtr ptrsSourceKeyPairs;
  941. WSMessageStreamExporterPtr ptrStreamExporter;
  942. propTagArray sPropTags = {0, 0};
  943. exportMessageChangesAsStreamResponse sResponse{__gszeroinit};
  944. if (lpChanges == NULL || lpsProps == NULL) {
  945. hr = MAPI_E_INVALID_PARAMETER;
  946. goto exitm;
  947. }
  948. if ((m_ulServerCapabilities & KOPANO_CAP_ENHANCED_ICS) == 0) {
  949. hr = MAPI_E_NO_SUPPORT;
  950. goto exitm;
  951. }
  952. hr = CopyICSChangeToSOAPSourceKeys(ulChanges, lpChanges + ulStart, &~ptrsSourceKeyPairs);
  953. if (hr != hrSuccess)
  954. goto exitm;
  955. sPropTags.__size = lpsProps->cValues;
  956. sPropTags.__ptr = (unsigned int*)lpsProps->aulPropTag;
  957. // Make sure to get the mime attachments ourselves
  958. soap_post_check_mime_attachments(m_lpCmd->soap);
  959. START_SOAP_CALL
  960. {
  961. if (m_lpCmd->ns__exportMessageChangesAsStream(m_ecSessionId, ulFlags, sPropTags, *ptrsSourceKeyPairs, ulPropTag, &sResponse) != SOAP_OK)
  962. er = MAPI_E_NETWORK_ERROR;
  963. else
  964. er = sResponse.er;
  965. }
  966. END_SOAP_CALL
  967. if (sResponse.sMsgStreams.__size > 0 && !soap_check_mime_attachments(m_lpCmd->soap)) {
  968. hr = MAPI_E_NETWORK_ERROR;
  969. goto exitm;
  970. }
  971. hr = WSMessageStreamExporter::Create(ulStart, ulChanges, sResponse.sMsgStreams, this, &~ptrStreamExporter);
  972. if (hr != hrSuccess)
  973. goto exitm;
  974. *lppsStreamExporter = ptrStreamExporter.release();
  975. exitm:
  976. return hr;
  977. }
  978. HRESULT WSTransport::HrGetMessageStreamImporter(ULONG ulFlags, ULONG ulSyncId, ULONG cbEntryID, LPENTRYID lpEntryID, ULONG cbFolderEntryID, LPENTRYID lpFolderEntryID, bool bNewMessage, LPSPropValue lpConflictItems, WSMessageStreamImporter **lppStreamImporter)
  979. {
  980. HRESULT hr;
  981. WSMessageStreamImporterPtr ptrStreamImporter;
  982. if ((m_ulServerCapabilities & KOPANO_CAP_ENHANCED_ICS) == 0)
  983. return MAPI_E_NO_SUPPORT;
  984. hr = WSMessageStreamImporter::Create(ulFlags, ulSyncId, cbEntryID, lpEntryID, cbFolderEntryID, lpFolderEntryID, bNewMessage, lpConflictItems, this, &~ptrStreamImporter);
  985. if (hr != hrSuccess)
  986. return hr;
  987. *lppStreamImporter = ptrStreamImporter.release();
  988. return hrSuccess;
  989. }
  990. HRESULT WSTransport::HrGetIDsFromNames(LPMAPINAMEID *lppPropNames, ULONG cNames, ULONG ulFlags, ULONG **lpServerIDs)
  991. {
  992. ECRESULT er = erSuccess;
  993. HRESULT hr = hrSuccess;
  994. struct namedPropArray sNamedProps;
  995. struct getIDsFromNamesResponse sResponse;
  996. unsigned int i=0;
  997. convert_context convertContext;
  998. LockSoap();
  999. // Convert our data into a structure that the server can take
  1000. sNamedProps.__size = cNames;
  1001. er = ECAllocateBuffer(sizeof(struct namedProp) * cNames, reinterpret_cast<void **>(&sNamedProps.__ptr));
  1002. if (er != erSuccess)
  1003. goto exitm;
  1004. memset(sNamedProps.__ptr, 0 , sizeof(struct namedProp) * cNames);
  1005. for (i = 0; i < cNames; ++i) {
  1006. switch(lppPropNames[i]->ulKind) {
  1007. case MNID_ID:
  1008. er = ECAllocateMore(sizeof(unsigned int), sNamedProps.__ptr, reinterpret_cast<void **>(&sNamedProps.__ptr[i].lpId));
  1009. if (er != erSuccess)
  1010. goto exitm;
  1011. *sNamedProps.__ptr[i].lpId = lppPropNames[i]->Kind.lID;
  1012. break;
  1013. case MNID_STRING: {
  1014. // The string is actually UTF-8, not windows-1252. This enables full support for wide char strings.
  1015. utf8string strNameUTF8 = convertContext.convert_to<utf8string>(lppPropNames[i]->Kind.lpwstrName);
  1016. er = ECAllocateMore(strNameUTF8.length() + 1, sNamedProps.__ptr, reinterpret_cast<void **>(&sNamedProps.__ptr[i].lpString));
  1017. if (er != erSuccess)
  1018. goto exitm;
  1019. strcpy(sNamedProps.__ptr[i].lpString, strNameUTF8.c_str());
  1020. break;
  1021. }
  1022. default:
  1023. hr = MAPI_E_INVALID_PARAMETER;
  1024. goto exitm;
  1025. }
  1026. if(lppPropNames[i]->lpguid) {
  1027. er = ECAllocateMore(sizeof( xsd__base64Binary) , sNamedProps.__ptr, reinterpret_cast<void **>(&sNamedProps.__ptr[i].lpguid));
  1028. if (er != erSuccess)
  1029. goto exitm;
  1030. sNamedProps.__ptr[i].lpguid->__ptr = (unsigned char *)lppPropNames[i]->lpguid;
  1031. sNamedProps.__ptr[i].lpguid->__size = sizeof(GUID);
  1032. } else {
  1033. sNamedProps.__ptr[i].lpguid = NULL;
  1034. }
  1035. }
  1036. // Send the call off the the server
  1037. START_SOAP_CALL
  1038. {
  1039. if(SOAP_OK != m_lpCmd->ns__getIDsFromNames(m_ecSessionId, &sNamedProps, ulFlags, &sResponse))
  1040. er = KCERR_NETWORK_ERROR;
  1041. else
  1042. er = sResponse.er;
  1043. }
  1044. END_SOAP_CALL
  1045. // Make sure we response with the same amount of data that we requested
  1046. if((ULONG)sResponse.lpsPropTags.__size != cNames) {
  1047. hr = MAPI_E_NO_ACCESS;
  1048. goto exitm;
  1049. }
  1050. hr = ECAllocateBuffer(sizeof(ULONG) * sResponse.lpsPropTags.__size, reinterpret_cast<void **>(lpServerIDs));
  1051. if (hr != hrSuccess)
  1052. goto exitm;
  1053. memcpy(*lpServerIDs, sResponse.lpsPropTags.__ptr, sizeof(ULONG) * sResponse.lpsPropTags.__size);
  1054. exitm:
  1055. UnLockSoap();
  1056. if(sNamedProps.__ptr)
  1057. ECFreeBuffer(sNamedProps.__ptr);
  1058. return hr;
  1059. }
  1060. HRESULT WSTransport::HrGetNamesFromIDs(LPSPropTagArray lpsPropTags, LPMAPINAMEID **lpppNames, ULONG *lpcResolved)
  1061. {
  1062. HRESULT hr = hrSuccess;
  1063. ECRESULT er = erSuccess;
  1064. struct getNamesFromIDsResponse sResponse;
  1065. struct propTagArray sPropTags;
  1066. LPMAPINAMEID *lppNames = NULL;
  1067. convert_context convertContext;
  1068. sPropTags.__size = lpsPropTags->cValues;
  1069. sPropTags.__ptr = (unsigned int *)&lpsPropTags->aulPropTag[0];
  1070. LockSoap();
  1071. START_SOAP_CALL
  1072. {
  1073. if(SOAP_OK != m_lpCmd->ns__getNamesFromIDs(m_ecSessionId, &sPropTags, &sResponse))
  1074. er = KCERR_NETWORK_ERROR;
  1075. else
  1076. er = sResponse.er;
  1077. }
  1078. END_SOAP_CALL
  1079. er = ECAllocateBuffer(sizeof(LPMAPINAMEID) * sResponse.lpsNames.__size, reinterpret_cast<void **>(&lppNames));
  1080. if (er != erSuccess)
  1081. goto exitm;
  1082. // Loop through all the returned names, and put it into the return value
  1083. for (gsoap_size_t i = 0; i < sResponse.lpsNames.__size; ++i) {
  1084. // Each MAPINAMEID must be allocated
  1085. er = ECAllocateMore(sizeof(MAPINAMEID), lppNames, reinterpret_cast<void **>(&lppNames[i]));
  1086. if (er != erSuccess)
  1087. goto exitm;
  1088. if(sResponse.lpsNames.__ptr[i].lpguid && sResponse.lpsNames.__ptr[i].lpguid->__ptr) {
  1089. er = ECAllocateMore(sizeof(GUID), lppNames, reinterpret_cast<void **>(&lppNames[i]->lpguid));
  1090. if (er != erSuccess)
  1091. goto exitm;
  1092. memcpy(lppNames[i]->lpguid, sResponse.lpsNames.__ptr[i].lpguid->__ptr, sizeof(GUID));
  1093. }
  1094. if(sResponse.lpsNames.__ptr[i].lpId) {
  1095. lppNames[i]->Kind.lID = *sResponse.lpsNames.__ptr[i].lpId;
  1096. lppNames[i]->ulKind = MNID_ID;
  1097. } else if(sResponse.lpsNames.__ptr[i].lpString) {
  1098. std::wstring strNameW = convertContext.convert_to<std::wstring>(sResponse.lpsNames.__ptr[i].lpString, rawsize(sResponse.lpsNames.__ptr[i].lpString), "UTF-8");
  1099. er = ECAllocateMore((strNameW.size() + 1) * sizeof(wchar_t), lppNames,
  1100. reinterpret_cast<void **>(&lppNames[i]->Kind.lpwstrName));
  1101. if (er != erSuccess)
  1102. goto exitm;
  1103. memcpy(lppNames[i]->Kind.lpwstrName, strNameW.c_str(), (strNameW.size() + 1) * sizeof(WCHAR)); // Also copy the trailing '\0'
  1104. lppNames[i]->ulKind = MNID_STRING;
  1105. } else {
  1106. // not found by server, we have actually allocated memory but it doesn't really matter
  1107. lppNames[i] = NULL;
  1108. }
  1109. }
  1110. *lpcResolved = sResponse.lpsNames.__size;
  1111. *lpppNames = lppNames;
  1112. exitm:
  1113. UnLockSoap();
  1114. return hr;
  1115. }
  1116. HRESULT WSTransport::HrGetReceiveFolderTable(ULONG ulFlags, ULONG cbStoreEntryID, LPENTRYID lpStoreEntryID, LPSRowSet* lppsRowSet)
  1117. {
  1118. struct receiveFolderTableResponse sReceiveFolders;
  1119. ECRESULT er = erSuccess;
  1120. HRESULT hr = hrSuccess;
  1121. LPSRowSet lpsRowSet = NULL;
  1122. ULONG ulRowId = 0;
  1123. int nLen = 0;
  1124. entryId sEntryId = {0}; // Do not free
  1125. ecmem_ptr<ENTRYID> lpUnWrapStoreID;
  1126. ULONG cbUnWrapStoreID = 0;
  1127. std::wstring unicode;
  1128. convert_context converter;
  1129. LockSoap();
  1130. hr = UnWrapServerClientStoreEntry(cbStoreEntryID, lpStoreEntryID, &cbUnWrapStoreID, &~lpUnWrapStoreID);
  1131. if(hr != hrSuccess)
  1132. goto exitm;
  1133. sEntryId.__ptr = reinterpret_cast<unsigned char *>(lpUnWrapStoreID.get());
  1134. sEntryId.__size = cbUnWrapStoreID;
  1135. // Get ReceiveFolder information from the server
  1136. START_SOAP_CALL
  1137. {
  1138. if(SOAP_OK != m_lpCmd->ns__getReceiveFolderTable(m_ecSessionId, sEntryId, &sReceiveFolders))
  1139. er = KCERR_NETWORK_ERROR;
  1140. else
  1141. er = sReceiveFolders.er;
  1142. }
  1143. END_SOAP_CALL
  1144. er = ECAllocateBuffer(CbNewSRowSet(sReceiveFolders.sFolderArray.__size), reinterpret_cast<void **>(&lpsRowSet));
  1145. if (er != erSuccess)
  1146. goto exitm;
  1147. memset(lpsRowSet, 0, CbNewSRowSet(sReceiveFolders.sFolderArray.__size));
  1148. lpsRowSet->cRows = sReceiveFolders.sFolderArray.__size;
  1149. for (gsoap_size_t i = 0; i < sReceiveFolders.sFolderArray.__size; ++i) {
  1150. ulRowId = i+1;
  1151. lpsRowSet->aRow[i].cValues = NUM_RFT_PROPS;
  1152. er = ECAllocateBuffer(sizeof(SPropValue) * NUM_RFT_PROPS, reinterpret_cast<void **>(&lpsRowSet->aRow[i].lpProps));
  1153. if (er != erSuccess)
  1154. goto exitm;
  1155. memset(lpsRowSet->aRow[i].lpProps, 0, sizeof(SPropValue)*NUM_RFT_PROPS);
  1156. lpsRowSet->aRow[i].lpProps[RFT_ROWID].ulPropTag = PR_ROWID;
  1157. lpsRowSet->aRow[i].lpProps[RFT_ROWID].Value.ul = ulRowId;
  1158. lpsRowSet->aRow[i].lpProps[RFT_INST_KEY].ulPropTag = PR_INSTANCE_KEY;
  1159. lpsRowSet->aRow[i].lpProps[RFT_INST_KEY].Value.bin.cb = 4; //fixme: maybe fix, normal 8 now
  1160. er = ECAllocateMore(lpsRowSet->aRow[i].lpProps[RFT_INST_KEY].Value.bin.cb, lpsRowSet->aRow[i].lpProps,
  1161. reinterpret_cast<void **>(&lpsRowSet->aRow[i].lpProps[RFT_INST_KEY].Value.bin.lpb));
  1162. if (er != erSuccess)
  1163. goto exitm;
  1164. memset(lpsRowSet->aRow[i].lpProps[RFT_INST_KEY].Value.bin.lpb, 0, lpsRowSet->aRow[i].lpProps[RFT_INST_KEY].Value.bin.cb);
  1165. memcpy(lpsRowSet->aRow[i].lpProps[RFT_INST_KEY].Value.bin.lpb, &ulRowId, sizeof(ulRowId));
  1166. lpsRowSet->aRow[i].lpProps[RFT_ENTRYID].ulPropTag = PR_ENTRYID;
  1167. lpsRowSet->aRow[i].lpProps[RFT_ENTRYID].Value.bin.cb = sReceiveFolders.sFolderArray.__ptr[i].sEntryId.__size;
  1168. er = ECAllocateMore(lpsRowSet->aRow[i].lpProps[RFT_ENTRYID].Value.bin.cb, lpsRowSet->aRow[i].lpProps,
  1169. reinterpret_cast<void **>(&lpsRowSet->aRow[i].lpProps[RFT_ENTRYID].Value.bin.lpb));
  1170. if (er != erSuccess)
  1171. goto exitm;
  1172. memcpy(lpsRowSet->aRow[i].lpProps[RFT_ENTRYID].Value.bin.lpb, sReceiveFolders.sFolderArray.__ptr[i].sEntryId.__ptr, lpsRowSet->aRow[i].lpProps[RFT_ENTRYID].Value.bin.cb);
  1173. // Use the entryid for record key
  1174. lpsRowSet->aRow[i].lpProps[RFT_RECORD_KEY].ulPropTag = PR_RECORD_KEY;
  1175. lpsRowSet->aRow[i].lpProps[RFT_RECORD_KEY].Value.bin.cb = sReceiveFolders.sFolderArray.__ptr[i].sEntryId.__size;
  1176. er = ECAllocateMore(lpsRowSet->aRow[i].lpProps[RFT_RECORD_KEY].Value.bin.cb, lpsRowSet->aRow[i].lpProps,
  1177. reinterpret_cast<void **>(&lpsRowSet->aRow[i].lpProps[RFT_RECORD_KEY].Value.bin.lpb));
  1178. if (er != erSuccess)
  1179. goto exitm;
  1180. memcpy(lpsRowSet->aRow[i].lpProps[RFT_RECORD_KEY].Value.bin.lpb, sReceiveFolders.sFolderArray.__ptr[i].sEntryId.__ptr, lpsRowSet->aRow[i].lpProps[RFT_RECORD_KEY].Value.bin.cb);
  1181. if (ulFlags & MAPI_UNICODE) {
  1182. lpsRowSet->aRow[i].lpProps[RFT_MSG_CLASS].ulPropTag = PR_MESSAGE_CLASS_W;
  1183. unicode = converter.convert_to<std::wstring>(sReceiveFolders.sFolderArray.__ptr[i].lpszAExplicitClass);
  1184. er = ECAllocateMore((unicode.length() + 1) * sizeof(wchar_t), lpsRowSet->aRow[i].lpProps, reinterpret_cast<void **>(&lpsRowSet->aRow[i].lpProps[RFT_MSG_CLASS].Value.lpszW));
  1185. if (er != erSuccess)
  1186. goto exitm;
  1187. memcpy(lpsRowSet->aRow[i].lpProps[RFT_MSG_CLASS].Value.lpszW, unicode.c_str(), (unicode.length()+1)*sizeof(WCHAR));
  1188. } else {
  1189. lpsRowSet->aRow[i].lpProps[RFT_MSG_CLASS].ulPropTag = PR_MESSAGE_CLASS_A;
  1190. nLen = strlen(sReceiveFolders.sFolderArray.__ptr[i].lpszAExplicitClass)+1;
  1191. er = ECAllocateMore(nLen, lpsRowSet->aRow[i].lpProps, reinterpret_cast<void **>(&lpsRowSet->aRow[i].lpProps[RFT_MSG_CLASS].Value.lpszA));
  1192. if (er != erSuccess)
  1193. goto exitm;
  1194. memcpy(lpsRowSet->aRow[i].lpProps[RFT_MSG_CLASS].Value.lpszA, sReceiveFolders.sFolderArray.__ptr[i].lpszAExplicitClass, nLen);
  1195. }
  1196. }
  1197. *lppsRowSet = lpsRowSet;
  1198. exitm:
  1199. UnLockSoap();
  1200. return hr;
  1201. }
  1202. HRESULT WSTransport::HrGetReceiveFolder(ULONG cbStoreEntryID, LPENTRYID lpStoreEntryID, const utf8string &strMessageClass, ULONG* lpcbEntryID, LPENTRYID* lppEntryID, utf8string *lpstrExplicitClass)
  1203. {
  1204. struct receiveFolderResponse sReceiveFolderTable;
  1205. ECRESULT er = erSuccess;
  1206. HRESULT hr = hrSuccess;
  1207. entryId sEntryId = {0}; // Do not free
  1208. ULONG cbEntryID = 0;
  1209. ecmem_ptr<ENTRYID> lpEntryID, lpUnWrapStoreID;
  1210. ULONG cbUnWrapStoreID = 0;
  1211. LockSoap();
  1212. hr = UnWrapServerClientStoreEntry(cbStoreEntryID, lpStoreEntryID, &cbUnWrapStoreID, &~lpUnWrapStoreID);
  1213. if(hr != hrSuccess)
  1214. goto exitm;
  1215. sEntryId.__ptr = reinterpret_cast<unsigned char *>(lpUnWrapStoreID.get());
  1216. sEntryId.__size = cbUnWrapStoreID;
  1217. if(lpstrExplicitClass)
  1218. lpstrExplicitClass->clear();
  1219. // Get ReceiveFolder information from the server
  1220. START_SOAP_CALL
  1221. {
  1222. if(SOAP_OK != m_lpCmd->ns__getReceiveFolder(m_ecSessionId, sEntryId, (char*)strMessageClass.c_str(), &sReceiveFolderTable))
  1223. er = KCERR_NETWORK_ERROR;
  1224. else
  1225. er = sReceiveFolderTable.er;
  1226. }
  1227. END_SOAP_CALL
  1228. if(er == KCERR_NOT_FOUND && lpstrExplicitClass)
  1229. {
  1230. // This is only by an empty message store ??
  1231. *lpcbEntryID = 0;
  1232. *lppEntryID = NULL;
  1233. hr = hrSuccess;
  1234. goto exitm;
  1235. }
  1236. hr = CopySOAPEntryIdToMAPIEntryId(&sReceiveFolderTable.sReceiveFolder.sEntryId,
  1237. &cbEntryID, &~lpEntryID, nullptr);
  1238. if(hr != hrSuccess)
  1239. goto exitm;
  1240. if(er != KCERR_NOT_FOUND && lpstrExplicitClass != NULL)
  1241. *lpstrExplicitClass = utf8string::from_string(sReceiveFolderTable.sReceiveFolder.lpszAExplicitClass);
  1242. *lppEntryID = lpEntryID.release();
  1243. *lpcbEntryID = cbEntryID;
  1244. exitm:
  1245. UnLockSoap();
  1246. return hr;
  1247. }
  1248. HRESULT WSTransport::HrSetReceiveFolder(ULONG cbStoreID, LPENTRYID lpStoreID, const utf8string &strMessageClass, ULONG cbEntryID, LPENTRYID lpEntryID)
  1249. {
  1250. HRESULT hr = hrSuccess;
  1251. ECRESULT er = erSuccess;
  1252. unsigned int result;
  1253. entryId sStoreId = {0}; // Do not free
  1254. entryId sEntryId = {0}; // Do not free
  1255. ecmem_ptr<ENTRYID> lpUnWrapStoreID;
  1256. ULONG cbUnWrapStoreID = 0;
  1257. LockSoap();
  1258. hr = UnWrapServerClientStoreEntry(cbStoreID, lpStoreID, &cbUnWrapStoreID, &~lpUnWrapStoreID);
  1259. if(hr != hrSuccess)
  1260. goto exitm;
  1261. sStoreId.__ptr = reinterpret_cast<unsigned char *>(lpUnWrapStoreID.get());
  1262. sStoreId.__size = cbUnWrapStoreID;
  1263. // Ignore error
  1264. CopyMAPIEntryIdToSOAPEntryId(cbEntryID, lpEntryID, &sEntryId, true);
  1265. START_SOAP_CALL
  1266. {
  1267. if(SOAP_OK != m_lpCmd->ns__setReceiveFolder(m_ecSessionId, sStoreId, (lpEntryID)?&sEntryId : NULL, (char*)strMessageClass.c_str(), &result))
  1268. er = KCERR_NETWORK_ERROR;
  1269. else
  1270. er = result;
  1271. }
  1272. END_SOAP_CALL
  1273. exitm:
  1274. UnLockSoap();
  1275. return hr;
  1276. }
  1277. HRESULT WSTransport::HrSetReadFlag(ULONG cbEntryID, LPENTRYID lpEntryID, ULONG ulFlags, ULONG ulSyncId)
  1278. {
  1279. HRESULT hr = hrSuccess;
  1280. ECRESULT er = erSuccess;
  1281. struct entryList sEntryList;
  1282. entryId sEntryId;
  1283. sEntryId.__ptr = (unsigned char*)lpEntryID;
  1284. sEntryId.__size = cbEntryID;
  1285. sEntryList.__size = 1;
  1286. sEntryList.__ptr = &sEntryId;
  1287. LockSoap();
  1288. START_SOAP_CALL
  1289. {
  1290. if(SOAP_OK != m_lpCmd->ns__setReadFlags(m_ecSessionId, ulFlags, NULL, &sEntryList, ulSyncId, &er))
  1291. er = KCERR_NETWORK_ERROR;
  1292. }
  1293. END_SOAP_CALL
  1294. exitm:
  1295. UnLockSoap();
  1296. return hr;
  1297. }
  1298. HRESULT WSTransport::HrSubmitMessage(ULONG cbMessageID, LPENTRYID lpMessageID, ULONG ulFlags)
  1299. {
  1300. HRESULT hr = hrSuccess;
  1301. ECRESULT er = erSuccess;
  1302. entryId sEntryId = {0}; // Do not free
  1303. LockSoap();
  1304. hr = CopyMAPIEntryIdToSOAPEntryId(cbMessageID, lpMessageID, &sEntryId, true);
  1305. if(hr != hrSuccess)
  1306. goto exitm;
  1307. START_SOAP_CALL
  1308. {
  1309. if(SOAP_OK != m_lpCmd->ns__submitMessage(m_ecSessionId, sEntryId, ulFlags, &er))
  1310. er = KCERR_NETWORK_ERROR;
  1311. }
  1312. END_SOAP_CALL
  1313. exitm:
  1314. UnLockSoap();
  1315. return hr;
  1316. }
  1317. HRESULT WSTransport::HrFinishedMessage(ULONG cbEntryID,
  1318. const ENTRYID *lpEntryID, ULONG ulFlags)
  1319. {
  1320. HRESULT hr = hrSuccess;
  1321. ECRESULT er = erSuccess;
  1322. entryId sEntryId = {0}; // Do not free
  1323. LockSoap();
  1324. hr = CopyMAPIEntryIdToSOAPEntryId(cbEntryID, lpEntryID, &sEntryId, true);
  1325. if(hr != hrSuccess)
  1326. goto exitm;
  1327. START_SOAP_CALL
  1328. {
  1329. if(SOAP_OK != m_lpCmd->ns__finishedMessage(m_ecSessionId, sEntryId, ulFlags, &er))
  1330. er = KCERR_NETWORK_ERROR;
  1331. }
  1332. END_SOAP_CALL
  1333. exitm:
  1334. UnLockSoap();
  1335. return hr;
  1336. }
  1337. HRESULT WSTransport::HrAbortSubmit(ULONG cbEntryID, LPENTRYID lpEntryID)
  1338. {
  1339. HRESULT hr = hrSuccess;
  1340. ECRESULT er = erSuccess;
  1341. entryId sEntryId = {0}; // Do not free
  1342. LockSoap();
  1343. hr = CopyMAPIEntryIdToSOAPEntryId(cbEntryID, lpEntryID, &sEntryId, true);
  1344. if(hr != hrSuccess)
  1345. goto exitm;
  1346. START_SOAP_CALL
  1347. {
  1348. if(SOAP_OK != m_lpCmd->ns__abortSubmit(m_ecSessionId, sEntryId, &er))
  1349. er = KCERR_NETWORK_ERROR;
  1350. }
  1351. END_SOAP_CALL
  1352. exitm:
  1353. UnLockSoap();
  1354. return hr;
  1355. }
  1356. HRESULT WSTransport::HrIsMessageInQueue(ULONG cbEntryID, LPENTRYID lpEntryID)
  1357. {
  1358. HRESULT hr = hrSuccess;
  1359. ECRESULT er = erSuccess;
  1360. entryId sEntryId = {0}; // Do not free
  1361. LockSoap();
  1362. hr = CopyMAPIEntryIdToSOAPEntryId(cbEntryID, lpEntryID, &sEntryId, true);
  1363. if(hr != hrSuccess)
  1364. goto exitm;
  1365. START_SOAP_CALL
  1366. {
  1367. if(SOAP_OK != m_lpCmd->ns__isMessageInQueue(m_ecSessionId, sEntryId, &er))
  1368. er = KCERR_NETWORK_ERROR;
  1369. }
  1370. END_SOAP_CALL
  1371. exitm:
  1372. UnLockSoap();
  1373. return hr;
  1374. }
  1375. HRESULT WSTransport::HrResolveStore(LPGUID lpGuid, ULONG *lpulUserID, ULONG* lpcbStoreID, LPENTRYID* lppStoreID)
  1376. {
  1377. HRESULT hr = hrSuccess;
  1378. ECRESULT er = erSuccess;
  1379. struct resolveUserStoreResponse sResponse;
  1380. struct xsd__base64Binary sStoreGuid = {0,0};
  1381. LockSoap();
  1382. if (!lpGuid){
  1383. hr = MAPI_E_INVALID_PARAMETER;
  1384. goto exitm;
  1385. }
  1386. sStoreGuid.__ptr = (unsigned char*)lpGuid;
  1387. sStoreGuid.__size = sizeof(GUID);
  1388. START_SOAP_CALL
  1389. {
  1390. if(SOAP_OK != m_lpCmd->ns__resolveStore(m_ecSessionId, sStoreGuid, &sResponse))
  1391. er = KCERR_NETWORK_ERROR;
  1392. else
  1393. er = sResponse.er;
  1394. }
  1395. END_SOAP_CALL
  1396. if(lpulUserID)
  1397. *lpulUserID = sResponse.ulUserId;
  1398. if(lpcbStoreID && lppStoreID) {
  1399. // Create a client store entry, add the servername
  1400. hr = WrapServerClientStoreEntry(sResponse.lpszServerPath ? sResponse.lpszServerPath : m_sProfileProps.strServerPath.c_str(), &sResponse.sStoreId, lpcbStoreID, lppStoreID);
  1401. if(hr != hrSuccess)
  1402. goto exitm;
  1403. }
  1404. exitm:
  1405. UnLockSoap();
  1406. return hr;
  1407. }
  1408. HRESULT WSTransport::HrResolveUserStore(const utf8string &strUserName, ULONG ulFlags, ULONG *lpulUserID, ULONG* lpcbStoreID, LPENTRYID* lppStoreID, std::string *lpstrRedirServer)
  1409. {
  1410. HRESULT hr = hrSuccess;
  1411. ECRESULT er = erSuccess;
  1412. struct resolveUserStoreResponse sResponse;
  1413. LockSoap();
  1414. if(strUserName.empty()){
  1415. hr = MAPI_E_INVALID_PARAMETER;
  1416. goto exitm;
  1417. }
  1418. START_SOAP_CALL
  1419. {
  1420. if(SOAP_OK != m_lpCmd->ns__resolveUserStore(m_ecSessionId, (char*)strUserName.c_str(), ECSTORE_TYPE_MASK_PRIVATE | ECSTORE_TYPE_MASK_PUBLIC, ulFlags, &sResponse))
  1421. er = KCERR_NETWORK_ERROR;
  1422. else
  1423. er = sResponse.er;
  1424. }
  1425. //END_SOAP_CALL
  1426. if (er == KCERR_END_OF_SESSION && HrReLogon() == hrSuccess)
  1427. goto retry;
  1428. hr = kcerr_to_mapierr(er, MAPI_E_NOT_FOUND);
  1429. if (hr == MAPI_E_UNABLE_TO_COMPLETE)
  1430. {
  1431. if (lpstrRedirServer)
  1432. *lpstrRedirServer = sResponse.lpszServerPath;
  1433. else
  1434. hr = MAPI_E_NOT_FOUND;
  1435. }
  1436. if(hr != hrSuccess)
  1437. goto exitm;
  1438. if (lpulUserID != nullptr)
  1439. *lpulUserID = sResponse.ulUserId;
  1440. if(lpcbStoreID && lppStoreID) {
  1441. // Create a client store entry, add the servername
  1442. hr = WrapServerClientStoreEntry(sResponse.lpszServerPath ? sResponse.lpszServerPath : m_sProfileProps.strServerPath.c_str(), &sResponse.sStoreId, lpcbStoreID, lppStoreID);
  1443. if(hr != hrSuccess)
  1444. goto exitm;
  1445. }
  1446. exitm:
  1447. UnLockSoap();
  1448. return hr;
  1449. }
  1450. /**
  1451. * Resolve a specific store type for a user.
  1452. *
  1453. * @param[in] strUserName The name of the user for whom to resolve the store. If left
  1454. * empty, the store for the current user will be resolved.
  1455. * @param[in] ulStoreType The type of the store to resolve.
  1456. * @param[out] lpcbStoreID The length of the returned entry id.
  1457. * @param[out] lppStoreID The returned store entry id.
  1458. *
  1459. * @note This method should be called on a transport that's already connected to the
  1460. * right server as redirection is not supported.
  1461. */
  1462. HRESULT WSTransport::HrResolveTypedStore(const utf8string &strUserName, ULONG ulStoreType, ULONG* lpcbStoreID, LPENTRYID* lppStoreID)
  1463. {
  1464. HRESULT hr = hrSuccess;
  1465. ECRESULT er = erSuccess;
  1466. struct resolveUserStoreResponse sResponse;
  1467. LockSoap();
  1468. // Currently only archive stores are supported.
  1469. if (ulStoreType != ECSTORE_TYPE_ARCHIVE || lpcbStoreID == NULL || lppStoreID == NULL) {
  1470. hr = MAPI_E_INVALID_PARAMETER;
  1471. goto exitm;
  1472. }
  1473. START_SOAP_CALL
  1474. {
  1475. if(SOAP_OK != m_lpCmd->ns__resolveUserStore(m_ecSessionId, (char*)strUserName.c_str(), (1 << ulStoreType), 0, &sResponse))
  1476. er = KCERR_NETWORK_ERROR;
  1477. else
  1478. er = sResponse.er;
  1479. }
  1480. END_SOAP_CALL
  1481. if(lpcbStoreID && lppStoreID) {
  1482. // Create a client store entry, add the servername
  1483. hr = WrapServerClientStoreEntry(sResponse.lpszServerPath ? sResponse.lpszServerPath : m_sProfileProps.strServerPath.c_str(), &sResponse.sStoreId, lpcbStoreID, lppStoreID);
  1484. if(hr != hrSuccess)
  1485. goto exitm;
  1486. }
  1487. exitm:
  1488. UnLockSoap();
  1489. return hr;
  1490. }
  1491. /**
  1492. * Create a new user.
  1493. *
  1494. * @param[in] lpECUser Pointer to an ECUSER object that contains the details of the user
  1495. * @param[in] ulFlags MAPI_UNICODE, values in user struct will be PT_UNICODE, otherwise in PT_STRING8
  1496. * @param[out] lpcbUserId The size in bytes of the entryid
  1497. * @param[out] lppUserId The entry id of the new user
  1498. * @return HRESULT MAPI error code.
  1499. */
  1500. HRESULT WSTransport::HrCreateUser(ECUSER *lpECUser, ULONG ulFlags,
  1501. ULONG *lpcbUserId, LPENTRYID *lppUserId)
  1502. {
  1503. HRESULT hr = hrSuccess;
  1504. ECRESULT er = erSuccess;
  1505. struct user sUser{__gszeroinit};
  1506. struct setUserResponse sResponse;
  1507. convert_context converter;
  1508. LockSoap();
  1509. if(lpECUser == NULL || lpcbUserId == NULL || lppUserId == NULL) {
  1510. hr = MAPI_E_INVALID_PARAMETER;
  1511. goto exitm;
  1512. }
  1513. sUser.lpszUsername = TO_UTF8_DEF((char *)lpECUser->lpszUsername);
  1514. sUser.lpszPassword = TO_UTF8_DEF((char *)lpECUser->lpszPassword);
  1515. sUser.lpszMailAddress = TO_UTF8_DEF((char *)lpECUser->lpszMailAddress);
  1516. sUser.ulUserId = 0;
  1517. sUser.ulObjClass = lpECUser->ulObjClass;
  1518. sUser.ulIsNonActive = lpECUser->ulObjClass; // Keep 6.40.0 servers happy
  1519. sUser.ulIsAdmin = lpECUser->ulIsAdmin;
  1520. sUser.lpszFullName = TO_UTF8_DEF((char *)lpECUser->lpszFullName);
  1521. sUser.ulIsABHidden = lpECUser->ulIsABHidden;
  1522. sUser.ulCapacity = lpECUser->ulCapacity;
  1523. sUser.lpsPropmap = NULL;
  1524. sUser.lpsMVPropmap = NULL;
  1525. hr = CopyABPropsToSoap(&lpECUser->sPropmap, &lpECUser->sMVPropmap, ulFlags,
  1526. &sUser.lpsPropmap, &sUser.lpsMVPropmap);
  1527. if (hr != hrSuccess)
  1528. goto exitm;
  1529. START_SOAP_CALL
  1530. {
  1531. if(SOAP_OK != m_lpCmd->ns__createUser(m_ecSessionId, &sUser, &sResponse))
  1532. er = KCERR_NETWORK_ERROR;
  1533. else
  1534. er = sResponse.er;
  1535. }
  1536. END_SOAP_CALL
  1537. hr = CopySOAPEntryIdToMAPIEntryId(&sResponse.sUserId, sResponse.ulUserId, lpcbUserId, lppUserId);
  1538. exitm:
  1539. UnLockSoap();
  1540. FreeABProps(sUser.lpsPropmap, sUser.lpsMVPropmap);
  1541. return hr;
  1542. }
  1543. /**
  1544. * Get user struct on a specific user, or the user you're connected as.
  1545. *
  1546. * @param[in] cbUserID Length as lpUserID
  1547. * @param[in] lpUserID EntryID of a user, use NULL to retrieve 'yourself'
  1548. * @param[in] ulFlags MAPI_UNICODE, return values in user struct will be PT_UNICODE, otherwise in PT_STRING8
  1549. * @param[out] lppECUser Pointer to an ECUSER object that contains the user details
  1550. * @return HRESULT MAPI error code.
  1551. */
  1552. HRESULT WSTransport::HrGetUser(ULONG cbUserID, LPENTRYID lpUserID,
  1553. ULONG ulFlags, ECUSER **lppECUser)
  1554. {
  1555. HRESULT hr = hrSuccess;
  1556. ECRESULT er = erSuccess;
  1557. struct getUserResponse sResponse;
  1558. ecmem_ptr<ECUSER> lpECUser;
  1559. entryId sUserId = {0};
  1560. ULONG ulUserId = 0;
  1561. LockSoap();
  1562. if (lppECUser == NULL) {
  1563. hr = MAPI_E_INVALID_PARAMETER;
  1564. goto exitm;
  1565. }
  1566. if (lpUserID)
  1567. ulUserId = ABEID_ID(lpUserID);
  1568. hr = CopyMAPIEntryIdToSOAPEntryId(cbUserID, lpUserID, &sUserId, true);
  1569. if(hr != hrSuccess)
  1570. goto exitm;
  1571. START_SOAP_CALL
  1572. {
  1573. if(SOAP_OK != m_lpCmd->ns__getUser(m_ecSessionId, ulUserId, sUserId, &sResponse))
  1574. er = KCERR_NETWORK_ERROR;
  1575. else
  1576. er = sResponse.er;
  1577. }
  1578. END_SOAP_CALL
  1579. hr = SoapUserToUser(sResponse.lpsUser, ulFlags, &~lpECUser);
  1580. if(hr != hrSuccess)
  1581. goto exitm;
  1582. *lppECUser = lpECUser.release();
  1583. exitm:
  1584. UnLockSoap();
  1585. return hr;
  1586. }
  1587. /**
  1588. * Update an existing user.
  1589. *
  1590. * This function can create a new user on an offline server.
  1591. *
  1592. * @param[in] lpECUser Pointer to an ECUSER object that contains the details of the user
  1593. * @param[in] ulFlags MAPI_UNICODE, values in user struct will be PT_UNICODE, otherwise in PT_STRING8
  1594. * @return HRESULT MAPI error code.
  1595. */
  1596. HRESULT WSTransport::HrSetUser(ECUSER *lpECUser, ULONG ulFlags)
  1597. {
  1598. HRESULT hr = hrSuccess;
  1599. ECRESULT er = erSuccess;
  1600. struct user sUser{__gszeroinit};
  1601. unsigned int result = 0;
  1602. convert_context converter;
  1603. LockSoap();
  1604. if(lpECUser == NULL) {
  1605. hr = MAPI_E_INVALID_PARAMETER;
  1606. goto exitm;
  1607. }
  1608. sUser.lpszUsername = TO_UTF8_DEF(lpECUser->lpszUsername);
  1609. sUser.lpszPassword = TO_UTF8_DEF(lpECUser->lpszPassword);
  1610. sUser.lpszMailAddress = TO_UTF8_DEF(lpECUser->lpszMailAddress);
  1611. sUser.ulUserId = ABEID_ID(lpECUser->sUserId.lpb);
  1612. sUser.ulObjClass = lpECUser->ulObjClass;
  1613. sUser.ulIsNonActive = lpECUser->ulObjClass; // Keep 6.40.0 servers happy
  1614. sUser.ulIsAdmin = lpECUser->ulIsAdmin;
  1615. sUser.lpszFullName = TO_UTF8_DEF(lpECUser->lpszFullName);
  1616. sUser.sUserId.__ptr = lpECUser->sUserId.lpb;
  1617. sUser.sUserId.__size = lpECUser->sUserId.cb;
  1618. sUser.ulIsABHidden = lpECUser->ulIsABHidden;
  1619. sUser.ulCapacity = lpECUser->ulCapacity;
  1620. sUser.lpsPropmap = NULL;
  1621. sUser.lpsMVPropmap = NULL;
  1622. hr = CopyABPropsToSoap(&lpECUser->sPropmap, &lpECUser->sMVPropmap, ulFlags,
  1623. &sUser.lpsPropmap, &sUser.lpsMVPropmap);
  1624. if (hr != hrSuccess)
  1625. goto exitm;
  1626. START_SOAP_CALL
  1627. {
  1628. if(SOAP_OK != m_lpCmd->ns__setUser(m_ecSessionId, &sUser, &result))
  1629. er = KCERR_NETWORK_ERROR;
  1630. else
  1631. er = result;
  1632. }
  1633. END_SOAP_CALL
  1634. exitm:
  1635. UnLockSoap();
  1636. FreeABProps(sUser.lpsPropmap, sUser.lpsMVPropmap);
  1637. return hr;
  1638. }
  1639. /**
  1640. * Creates a new store. This can be a store for a user or the public
  1641. * store (for a company or everyone).
  1642. *
  1643. * @param ulStoreType ECSTORE_TYPE_PRIVATE or ECSTORE_TYPE_PUBLIC
  1644. * @param cbUserID Number of bytes in lpUserID
  1645. * @param lpUserID EntryID of a user, everyone (public) or a company (public)
  1646. * @param cbStoreID Number of bytes in lpStoreID
  1647. * @param lpStoreID Store entryid for the new store
  1648. * @param cbRootID Number of bytes in lpRootID
  1649. * @param lpRootID Root folder entryid for the new store
  1650. * @param ulFlags Flags
  1651. * @arg @c EC_OVERRIDE_HOMESERVER Allow the store to be created on
  1652. * another server than the users
  1653. * homeserver.
  1654. *
  1655. * @return MAPI error code
  1656. * @retval MAPI_E_NOT_FOUND User described in lpUserID does not exist
  1657. * @retval MAPI_E_COLLISION Store already exists
  1658. */
  1659. HRESULT WSTransport::HrCreateStore(ULONG ulStoreType, ULONG cbUserID, LPENTRYID lpUserID, ULONG cbStoreID, LPENTRYID lpStoreID, ULONG cbRootID, LPENTRYID lpRootID, ULONG ulFlags)
  1660. {
  1661. HRESULT hr = hrSuccess;
  1662. ECRESULT er = erSuccess;
  1663. entryId sUserId = {0};
  1664. entryId sStoreId = {0};
  1665. entryId sRootId = {0};
  1666. LockSoap();
  1667. if(lpUserID == NULL || lpStoreID == NULL || lpRootID == NULL) {
  1668. hr = MAPI_E_INVALID_PARAMETER;
  1669. goto exitm;
  1670. }
  1671. hr = CopyMAPIEntryIdToSOAPEntryId(cbUserID, lpUserID, &sUserId, true);
  1672. if(hr != hrSuccess)
  1673. goto exitm;
  1674. hr = CopyMAPIEntryIdToSOAPEntryId(cbStoreID, lpStoreID, &sStoreId, true);
  1675. if(hr != hrSuccess)
  1676. goto exitm;
  1677. hr = CopyMAPIEntryIdToSOAPEntryId(cbRootID, lpRootID, &sRootId, true);
  1678. if(hr != hrSuccess)
  1679. goto exitm;
  1680. START_SOAP_CALL
  1681. {
  1682. if(SOAP_OK != m_lpCmd->ns__createStore(m_ecSessionId, ulStoreType, ABEID_ID(lpUserID), sUserId, sStoreId, sRootId, ulFlags, &er))
  1683. er = KCERR_NETWORK_ERROR;
  1684. }
  1685. END_SOAP_CALL
  1686. exitm:
  1687. UnLockSoap();
  1688. return hr;
  1689. }
  1690. HRESULT WSTransport::HrHookStore(ULONG ulStoreType, ULONG cbUserId, LPENTRYID lpUserId, LPGUID lpGuid, ULONG ulSyncId)
  1691. {
  1692. HRESULT hr = hrSuccess;
  1693. ECRESULT er = erSuccess;
  1694. entryId sUserId = {0};
  1695. struct xsd__base64Binary sStoreGuid = {0,0};
  1696. LockSoap();
  1697. if (cbUserId == 0 || lpUserId == NULL || lpGuid == NULL) {
  1698. hr = MAPI_E_INVALID_PARAMETER;
  1699. goto exitm;
  1700. }
  1701. hr = CopyMAPIEntryIdToSOAPEntryId(cbUserId, lpUserId, &sUserId, true);
  1702. if(hr != hrSuccess)
  1703. goto exitm;
  1704. sStoreGuid.__ptr = (unsigned char*)lpGuid;
  1705. sStoreGuid.__size = sizeof(GUID);
  1706. START_SOAP_CALL
  1707. {
  1708. if(SOAP_OK != m_lpCmd->ns__hookStore(m_ecSessionId, ulStoreType, sUserId, sStoreGuid, ulSyncId, &er))
  1709. er = KCERR_NETWORK_ERROR;
  1710. }
  1711. END_SOAP_CALL
  1712. exitm:
  1713. UnLockSoap();
  1714. return hr;
  1715. }
  1716. HRESULT WSTransport::HrUnhookStore(ULONG ulStoreType, ULONG cbUserId, LPENTRYID lpUserId, ULONG ulSyncId)
  1717. {
  1718. HRESULT hr = hrSuccess;
  1719. ECRESULT er = erSuccess;
  1720. entryId sUserId = {0};
  1721. LockSoap();
  1722. if (cbUserId == 0 || lpUserId == NULL) {
  1723. hr = MAPI_E_INVALID_PARAMETER;
  1724. goto exitm;
  1725. }
  1726. hr = CopyMAPIEntryIdToSOAPEntryId(cbUserId, lpUserId, &sUserId, true);
  1727. if(hr != hrSuccess)
  1728. goto exitm;
  1729. START_SOAP_CALL
  1730. {
  1731. if(SOAP_OK != m_lpCmd->ns__unhookStore(m_ecSessionId, ulStoreType, sUserId, ulSyncId, &er))
  1732. er = KCERR_NETWORK_ERROR;
  1733. }
  1734. END_SOAP_CALL
  1735. exitm:
  1736. UnLockSoap();
  1737. return hr;
  1738. }
  1739. HRESULT WSTransport::HrRemoveStore(LPGUID lpGuid, ULONG ulSyncId)
  1740. {
  1741. HRESULT hr = hrSuccess;
  1742. ECRESULT er = erSuccess;
  1743. struct xsd__base64Binary sStoreGuid = {0,0};
  1744. LockSoap();
  1745. if (lpGuid == NULL) {
  1746. hr = MAPI_E_INVALID_PARAMETER;
  1747. goto exitm;
  1748. }
  1749. sStoreGuid.__ptr = (unsigned char*)lpGuid;
  1750. sStoreGuid.__size = sizeof(GUID);
  1751. START_SOAP_CALL
  1752. {
  1753. if(SOAP_OK != m_lpCmd->ns__removeStore(m_ecSessionId, sStoreGuid, ulSyncId, &er))
  1754. er = KCERR_NETWORK_ERROR;
  1755. }
  1756. END_SOAP_CALL
  1757. exitm:
  1758. UnLockSoap();
  1759. return hr;
  1760. }
  1761. HRESULT WSTransport::HrDeleteUser(ULONG cbUserId, LPENTRYID lpUserId)
  1762. {
  1763. ECRESULT er = erSuccess;
  1764. HRESULT hr = hrSuccess;
  1765. entryId sUserId = {0};
  1766. LockSoap();
  1767. if(cbUserId < CbNewABEID("") || lpUserId == NULL) {
  1768. hr = MAPI_E_INVALID_PARAMETER;
  1769. goto exitm;
  1770. }
  1771. hr = CopyMAPIEntryIdToSOAPEntryId(cbUserId, lpUserId, &sUserId, true);
  1772. if (hr != hrSuccess)
  1773. goto exitm;
  1774. START_SOAP_CALL
  1775. {
  1776. if(SOAP_OK != m_lpCmd->ns__deleteUser(m_ecSessionId, ABEID_ID(lpUserId), sUserId, &er))
  1777. er = KCERR_NETWORK_ERROR;
  1778. }
  1779. END_SOAP_CALL
  1780. exitm:
  1781. UnLockSoap();
  1782. return hr;
  1783. }
  1784. /**
  1785. * Get the list of users for a specific company.
  1786. *
  1787. * @param[in] cbCompanyId The size in bytes of the entryid of the company
  1788. * @param[in] lpCompanyId Pointer to the entryid of the company
  1789. * @param[in] ulFlags MAPI_UNICODE, return values in user struct will be PT_UNICODE, otherwise in PT_STRING8
  1790. * @param[out] lpcUsers Number of users returned.
  1791. * @param[out] lppsUsers Array of ECUSER objects.
  1792. * @return HRESULT MAPI error code.
  1793. */
  1794. HRESULT WSTransport::HrGetUserList(ULONG cbCompanyId, LPENTRYID lpCompanyId,
  1795. ULONG ulFlags, ULONG *lpcUsers, ECUSER **lppsUsers)
  1796. {
  1797. ECRESULT er = erSuccess;
  1798. HRESULT hr = hrSuccess;
  1799. entryId sCompanyId = {0};
  1800. struct userListResponse sResponse;
  1801. LockSoap();
  1802. if(lpcUsers == NULL || lppsUsers == NULL) {
  1803. hr = MAPI_E_INVALID_PARAMETER;
  1804. goto exitm;
  1805. }
  1806. if (cbCompanyId > 0 && lpCompanyId != NULL)
  1807. {
  1808. hr = CopyMAPIEntryIdToSOAPEntryId(cbCompanyId, lpCompanyId, &sCompanyId, true);
  1809. if (hr != hrSuccess)
  1810. goto exitm;
  1811. }
  1812. *lpcUsers = 0;
  1813. START_SOAP_CALL
  1814. {
  1815. if(SOAP_OK != m_lpCmd->ns__getUserList(m_ecSessionId, ABEID_ID(lpCompanyId), sCompanyId, &sResponse))
  1816. er = KCERR_NETWORK_ERROR;
  1817. else
  1818. er = sResponse.er;
  1819. }
  1820. END_SOAP_CALL
  1821. hr = SoapUserArrayToUserArray(&sResponse.sUserArray, ulFlags, lpcUsers, lppsUsers);
  1822. if(hr != hrSuccess)
  1823. goto exitm;
  1824. exitm:
  1825. UnLockSoap();
  1826. return hr;
  1827. }
  1828. // IECServiceAdmin group functions
  1829. /**
  1830. * Create a new group.
  1831. *
  1832. * @param[in] lpECGroup Pointer to an ECGROUP object that contains the details of the group
  1833. * @param[in] ulFlags MAPI_UNICODE, values in group struct will be PT_UNICODE, otherwise in PT_STRING8
  1834. * @param[out] lpcbUserId The size in bytes of the entryid
  1835. * @param[out] lppUserId The entry id of the new group
  1836. * @return HRESULT MAPI error code.
  1837. */
  1838. HRESULT WSTransport::HrCreateGroup(ECGROUP *lpECGroup, ULONG ulFlags,
  1839. ULONG *lpcbGroupId, LPENTRYID *lppGroupId)
  1840. {
  1841. ECRESULT er = erSuccess;
  1842. HRESULT hr = hrSuccess;
  1843. struct group sGroup{__gszeroinit};
  1844. struct setGroupResponse sResponse;
  1845. convert_context converter;
  1846. LockSoap();
  1847. if(lpECGroup == NULL || lpcbGroupId == NULL || lppGroupId == NULL) {
  1848. hr = MAPI_E_INVALID_PARAMETER;
  1849. goto exitm;
  1850. }
  1851. sGroup.ulGroupId = 0;
  1852. sGroup.lpszGroupname = TO_UTF8_DEF(lpECGroup->lpszGroupname);
  1853. sGroup.lpszFullname = TO_UTF8_DEF(lpECGroup->lpszFullname);
  1854. sGroup.lpszFullEmail = TO_UTF8_DEF(lpECGroup->lpszFullEmail);
  1855. sGroup.ulIsABHidden = lpECGroup->ulIsABHidden;
  1856. sGroup.lpsPropmap = NULL;
  1857. sGroup.lpsMVPropmap = NULL;
  1858. hr = CopyABPropsToSoap(&lpECGroup->sPropmap, &lpECGroup->sMVPropmap, ulFlags,
  1859. &sGroup.lpsPropmap, &sGroup.lpsMVPropmap);
  1860. if (hr != hrSuccess)
  1861. goto exitm;
  1862. START_SOAP_CALL
  1863. {
  1864. if(SOAP_OK != m_lpCmd->ns__createGroup(m_ecSessionId, &sGroup, &sResponse))
  1865. er = KCERR_NETWORK_ERROR;
  1866. else
  1867. er = sResponse.er;
  1868. }
  1869. END_SOAP_CALL
  1870. hr = CopySOAPEntryIdToMAPIEntryId(&sResponse.sGroupId, sResponse.ulGroupId, lpcbGroupId, lppGroupId);
  1871. exitm:
  1872. UnLockSoap();
  1873. FreeABProps(sGroup.lpsPropmap, sGroup.lpsMVPropmap);
  1874. return hr;
  1875. }
  1876. /**
  1877. * Update an existing group.
  1878. *
  1879. * This function can create a new group on an offline server.
  1880. *
  1881. * @param[in] lpECGroup Pointer to an ECGROUP object that contains the details of the group
  1882. * @param[in] ulFlags MAPI_UNICODE, values in group struct will be PT_UNICODE, otherwise in PT_STRING8
  1883. * @return HRESULT MAPI error code.
  1884. */
  1885. HRESULT WSTransport::HrSetGroup(ECGROUP *lpECGroup, ULONG ulFlags)
  1886. {
  1887. ECRESULT er = erSuccess;
  1888. HRESULT hr = hrSuccess;
  1889. convert_context converter;
  1890. struct group sGroup{__gszeroinit};
  1891. LockSoap();
  1892. if(lpECGroup == NULL || lpECGroup->lpszGroupname == NULL || lpECGroup->lpszFullname == NULL) {
  1893. hr = MAPI_E_INVALID_PARAMETER;
  1894. goto exitm;
  1895. }
  1896. sGroup.lpszFullname = TO_UTF8_DEF(lpECGroup->lpszFullname);
  1897. sGroup.lpszGroupname = TO_UTF8_DEF(lpECGroup->lpszGroupname);
  1898. sGroup.lpszFullEmail = TO_UTF8_DEF(lpECGroup->lpszFullEmail);
  1899. sGroup.sGroupId.__size = lpECGroup->sGroupId.cb;
  1900. sGroup.sGroupId.__ptr = lpECGroup->sGroupId.lpb;
  1901. sGroup.ulGroupId = ABEID_ID(lpECGroup->sGroupId.lpb);
  1902. sGroup.ulIsABHidden = lpECGroup->ulIsABHidden;
  1903. sGroup.lpsPropmap = NULL;
  1904. sGroup.lpsMVPropmap = NULL;
  1905. hr = CopyABPropsToSoap(&lpECGroup->sPropmap, &lpECGroup->sMVPropmap, ulFlags,
  1906. &sGroup.lpsPropmap, &sGroup.lpsMVPropmap);
  1907. if (hr != hrSuccess)
  1908. goto exitm;
  1909. START_SOAP_CALL
  1910. {
  1911. if(SOAP_OK != m_lpCmd->ns__setGroup(m_ecSessionId, &sGroup, &er))
  1912. er = KCERR_NETWORK_ERROR;
  1913. }
  1914. END_SOAP_CALL
  1915. exitm:
  1916. UnLockSoap();
  1917. FreeABProps(sGroup.lpsPropmap, sGroup.lpsMVPropmap);
  1918. return hr;
  1919. }
  1920. /**
  1921. * Get group struct on a specific group.
  1922. *
  1923. * @param[in] cbGroupID Length as lpGroupID
  1924. * @param[in] lpGroupID EntryID of a group
  1925. * @param[in] ulFlags MAPI_UNICODE, return values in group struct will be PT_UNICODE, otherwise in PT_STRING8
  1926. * @param[out] lppECGroup Pointer to an ECGROUP object that contains the group details
  1927. * @return HRESULT MAPI error code.
  1928. */
  1929. HRESULT WSTransport::HrGetGroup(ULONG cbGroupID, LPENTRYID lpGroupID,
  1930. ULONG ulFlags, ECGROUP **lppECGroup)
  1931. {
  1932. ECRESULT er = erSuccess;
  1933. HRESULT hr = hrSuccess;
  1934. ECGROUP *lpGroup = NULL;
  1935. entryId sGroupId = {0};
  1936. struct getGroupResponse sResponse;
  1937. LockSoap();
  1938. if (lpGroupID == NULL || lppECGroup == NULL)
  1939. {
  1940. hr = MAPI_E_INVALID_PARAMETER;
  1941. goto exitm;
  1942. }
  1943. hr = CopyMAPIEntryIdToSOAPEntryId(cbGroupID, lpGroupID, &sGroupId, true);
  1944. if (hr != hrSuccess)
  1945. goto exitm;
  1946. START_SOAP_CALL
  1947. {
  1948. if(SOAP_OK != m_lpCmd->ns__getGroup(m_ecSessionId, ABEID_ID(lpGroupID), sGroupId, &sResponse))
  1949. er = KCERR_NETWORK_ERROR;
  1950. else
  1951. er = sResponse.er;
  1952. }
  1953. END_SOAP_CALL
  1954. hr = SoapGroupToGroup(sResponse.lpsGroup, ulFlags, &lpGroup);
  1955. if (hr != hrSuccess)
  1956. goto exitm;
  1957. *lppECGroup = lpGroup;
  1958. exitm:
  1959. UnLockSoap();
  1960. return hr;
  1961. }
  1962. HRESULT WSTransport::HrDeleteGroup(ULONG cbGroupId, LPENTRYID lpGroupId)
  1963. {
  1964. ECRESULT er = erSuccess;
  1965. HRESULT hr = hrSuccess;
  1966. entryId sGroupId = {0};
  1967. LockSoap();
  1968. if(cbGroupId < CbNewABEID("") || lpGroupId == NULL) {
  1969. hr = MAPI_E_INVALID_PARAMETER;
  1970. goto exitm;
  1971. }
  1972. hr = CopyMAPIEntryIdToSOAPEntryId(cbGroupId, lpGroupId, &sGroupId, true);
  1973. if (hr != hrSuccess)
  1974. goto exitm;
  1975. START_SOAP_CALL
  1976. {
  1977. if(SOAP_OK != m_lpCmd->ns__groupDelete(m_ecSessionId, ABEID_ID(lpGroupId), sGroupId, &er))
  1978. er = KCERR_NETWORK_ERROR;
  1979. }
  1980. END_SOAP_CALL
  1981. exitm:
  1982. UnLockSoap();
  1983. return hr;
  1984. }
  1985. /**
  1986. * Get the send-as-list of a specific user.
  1987. *
  1988. * @param[in] cbUserId Size in bytes of the user entryid.
  1989. * @param[in] lpUserId Entryid of the user.
  1990. * @param[in] ulFlags MAPI_UNICODE, return values in user structs will be PT_UNICODE, otherwise PT_STRING8
  1991. * @param[out] lpcSenders The number of results.
  1992. * @param[out] lppSenders Array of ECUSER objects.
  1993. * @return HRESULT MAPI error code.
  1994. */
  1995. HRESULT WSTransport::HrGetSendAsList(ULONG cbUserId, LPENTRYID lpUserId,
  1996. ULONG ulFlags, ULONG *lpcSenders, ECUSER **lppSenders)
  1997. {
  1998. ECRESULT er = erSuccess;
  1999. HRESULT hr = hrSuccess;
  2000. struct userListResponse sResponse;
  2001. entryId sUserId = {0};
  2002. LockSoap();
  2003. if(cbUserId < CbNewABEID("") || lpUserId == NULL || lpcSenders == NULL || lppSenders == NULL) {
  2004. hr = MAPI_E_INVALID_PARAMETER;
  2005. goto exitm;
  2006. }
  2007. hr = CopyMAPIEntryIdToSOAPEntryId(cbUserId, lpUserId, &sUserId, true);
  2008. if (hr != hrSuccess)
  2009. goto exitm;
  2010. START_SOAP_CALL
  2011. {
  2012. if(SOAP_OK != m_lpCmd->ns__getSendAsList(m_ecSessionId, ABEID_ID(lpUserId), sUserId, &sResponse))
  2013. er = KCERR_NETWORK_ERROR;
  2014. else
  2015. er = sResponse.er;
  2016. }
  2017. END_SOAP_CALL
  2018. hr = SoapUserArrayToUserArray(&sResponse.sUserArray, ulFlags, lpcSenders, lppSenders);
  2019. if(hr != hrSuccess)
  2020. goto exitm;
  2021. exitm:
  2022. UnLockSoap();
  2023. return hr;
  2024. }
  2025. HRESULT WSTransport::HrAddSendAsUser(ULONG cbUserId, LPENTRYID lpUserId, ULONG cbSenderId, LPENTRYID lpSenderId)
  2026. {
  2027. ECRESULT er = erSuccess;
  2028. HRESULT hr = hrSuccess;
  2029. entryId sUserId = {0};
  2030. entryId sSenderId = {0};
  2031. LockSoap();
  2032. if (cbUserId < CbNewABEID("") || lpUserId == NULL || cbSenderId < CbNewABEID("") || lpSenderId == NULL)
  2033. {
  2034. hr = MAPI_E_INVALID_PARAMETER;
  2035. goto exitm;
  2036. }
  2037. hr = CopyMAPIEntryIdToSOAPEntryId(cbUserId, lpUserId, &sUserId, true);
  2038. if (hr != hrSuccess)
  2039. goto exitm;
  2040. hr = CopyMAPIEntryIdToSOAPEntryId(cbSenderId, lpSenderId, &sSenderId, true);
  2041. if (hr != hrSuccess)
  2042. goto exitm;
  2043. START_SOAP_CALL
  2044. {
  2045. if(SOAP_OK != m_lpCmd->ns__addSendAsUser(m_ecSessionId, ABEID_ID(lpUserId), sUserId, ABEID_ID(lpSenderId), sSenderId, &er))
  2046. er = KCERR_NETWORK_ERROR;
  2047. }
  2048. END_SOAP_CALL
  2049. exitm:
  2050. UnLockSoap();
  2051. return hr;
  2052. }
  2053. HRESULT WSTransport::HrDelSendAsUser(ULONG cbUserId, LPENTRYID lpUserId, ULONG cbSenderId, LPENTRYID lpSenderId)
  2054. {
  2055. ECRESULT er = erSuccess;
  2056. HRESULT hr = hrSuccess;
  2057. entryId sUserId = {0};
  2058. entryId sSenderId = {0};
  2059. LockSoap();
  2060. if (cbUserId < CbNewABEID("") || lpUserId == NULL || cbSenderId < CbNewABEID("") || lpSenderId == NULL)
  2061. {
  2062. hr = MAPI_E_INVALID_PARAMETER;
  2063. goto exitm;
  2064. }
  2065. hr = CopyMAPIEntryIdToSOAPEntryId(cbUserId, lpUserId, &sUserId, true);
  2066. if (hr != hrSuccess)
  2067. goto exitm;
  2068. hr = CopyMAPIEntryIdToSOAPEntryId(cbSenderId, lpSenderId, &sSenderId, true);
  2069. if (hr != hrSuccess)
  2070. goto exitm;
  2071. START_SOAP_CALL
  2072. {
  2073. if(SOAP_OK != m_lpCmd->ns__delSendAsUser(m_ecSessionId, ABEID_ID(lpUserId), sUserId, ABEID_ID(lpSenderId), sSenderId, &er))
  2074. er = KCERR_NETWORK_ERROR;
  2075. }
  2076. END_SOAP_CALL
  2077. exitm:
  2078. UnLockSoap();
  2079. return hr;
  2080. }
  2081. HRESULT WSTransport::HrGetUserClientUpdateStatus(ULONG cbUserId,
  2082. LPENTRYID lpUserId, ULONG ulFlags, ECUSERCLIENTUPDATESTATUS **lppECUCUS)
  2083. {
  2084. ECRESULT er = erSuccess;
  2085. HRESULT hr = hrSuccess;
  2086. entryId sUserId = {0};
  2087. struct userClientUpdateStatusResponse sResponse;
  2088. LockSoap();
  2089. if (cbUserId < CbNewABEID("") || lpUserId == NULL) {
  2090. hr = MAPI_E_INVALID_PARAMETER;
  2091. goto exitm;
  2092. }
  2093. hr = CopyMAPIEntryIdToSOAPEntryId(cbUserId, lpUserId, &sUserId, true);
  2094. if (hr != hrSuccess)
  2095. goto exitm;
  2096. START_SOAP_CALL
  2097. {
  2098. if(SOAP_OK != m_lpCmd->ns__getUserClientUpdateStatus(m_ecSessionId, sUserId, &sResponse) )
  2099. er = KCERR_NETWORK_ERROR;
  2100. }
  2101. END_SOAP_CALL
  2102. hr = CopyUserClientUpdateStatusFromSOAP(sResponse, ulFlags, lppECUCUS);
  2103. if (hr != hrSuccess)
  2104. goto exitm;
  2105. exitm:
  2106. UnLockSoap();
  2107. return hr;
  2108. }
  2109. HRESULT WSTransport::HrRemoveAllObjects(ULONG cbUserId, LPENTRYID lpUserId)
  2110. {
  2111. ECRESULT er = erSuccess;
  2112. HRESULT hr = hrSuccess;
  2113. entryId sUserId = {0};
  2114. LockSoap();
  2115. if (cbUserId < CbNewABEID("") || lpUserId == NULL)
  2116. {
  2117. hr = MAPI_E_INVALID_PARAMETER;
  2118. goto exitm;
  2119. }
  2120. hr = CopyMAPIEntryIdToSOAPEntryId(cbUserId, lpUserId, &sUserId, true);
  2121. if (hr != hrSuccess)
  2122. goto exitm;
  2123. START_SOAP_CALL
  2124. {
  2125. if(SOAP_OK != m_lpCmd->ns__removeAllObjects(m_ecSessionId, sUserId, &er))
  2126. er = KCERR_NETWORK_ERROR;
  2127. }
  2128. END_SOAP_CALL
  2129. exitm:
  2130. UnLockSoap();
  2131. return hr;
  2132. }
  2133. /**
  2134. * Resolve a users entryid by name.
  2135. *
  2136. * @param[in] lpszUserName The username to resolve.
  2137. * @param[in] ulFlags MAPI_UNICODE, lpszUserName is in PT_UNICODE, otherwise in PT_STRING8
  2138. * @param[out] lpcbUserId The size in bytes of the entryid.
  2139. * @param[out] lppUserId The entryid of the resolved user.
  2140. * @return HRESULT MAPI error code.
  2141. */
  2142. HRESULT WSTransport::HrResolveUserName(LPCTSTR lpszUserName, ULONG ulFlags, ULONG *lpcbUserId, LPENTRYID *lppUserId)
  2143. {
  2144. ECRESULT er = erSuccess;
  2145. HRESULT hr = hrSuccess;
  2146. struct resolveUserResponse sResponse;
  2147. LockSoap();
  2148. if(lpszUserName == NULL || lpcbUserId == NULL || lppUserId == NULL) {
  2149. hr = MAPI_E_INVALID_PARAMETER;
  2150. goto exitm;
  2151. }
  2152. //Resolve userid from username
  2153. START_SOAP_CALL
  2154. {
  2155. if(SOAP_OK != m_lpCmd->ns__resolveUsername(m_ecSessionId, (char*)convstring(lpszUserName, ulFlags).u8_str(), &sResponse))
  2156. er = KCERR_NETWORK_ERROR;
  2157. else
  2158. er = sResponse.er;
  2159. }
  2160. END_SOAP_CALL
  2161. hr = CopySOAPEntryIdToMAPIEntryId(&sResponse.sUserId, sResponse.ulUserId, lpcbUserId, lppUserId);
  2162. exitm:
  2163. UnLockSoap();
  2164. return hr;
  2165. }
  2166. /**
  2167. * Resolve a group entryid by name.
  2168. *
  2169. * @param[in] lpszGroupName The groupname to resolve.
  2170. * @param[in] ulFlags MAPI_UNICODE, lpszGroupName is in PT_UNICODE, otherwise in PT_STRING8
  2171. * @param[out] lpcbUserId The size in bytes of the entryid.
  2172. * @param[out] lppUserId The entryid of the resolved group.
  2173. * @return HRESULT MAPI error code.
  2174. */
  2175. HRESULT WSTransport::HrResolveGroupName(LPCTSTR lpszGroupName, ULONG ulFlags, ULONG *lpcbGroupId, LPENTRYID *lppGroupId)
  2176. {
  2177. ECRESULT er = erSuccess;
  2178. HRESULT hr = hrSuccess;
  2179. struct resolveGroupResponse sResponse;
  2180. LockSoap();
  2181. if(lpszGroupName == NULL || lpcbGroupId == NULL || lppGroupId == NULL) {
  2182. hr = MAPI_E_INVALID_PARAMETER;
  2183. goto exitm;
  2184. }
  2185. //Resolve groupid from groupname
  2186. START_SOAP_CALL
  2187. {
  2188. if(SOAP_OK != m_lpCmd->ns__resolveGroupname(m_ecSessionId, (char*)convstring(lpszGroupName, ulFlags).u8_str(), &sResponse))
  2189. er = KCERR_NETWORK_ERROR;
  2190. else
  2191. er = sResponse.er;
  2192. }
  2193. END_SOAP_CALL
  2194. hr = CopySOAPEntryIdToMAPIEntryId(&sResponse.sGroupId, sResponse.ulGroupId, lpcbGroupId, lppGroupId);
  2195. exitm:
  2196. UnLockSoap();
  2197. return hr;
  2198. }
  2199. /**
  2200. * Get the list of groups for a specific company.
  2201. *
  2202. * @param[in] cbCompanyId The size in bytes of the entryid of the company
  2203. * @param[in] lpCompanyId Pointer to the entryid of the company
  2204. * @param[in] ulFlags MAPI_UNICODE, return values in group struct will be PT_UNICODE, otherwise in PT_STRING8
  2205. * @param[out] lpcGroups Number of groups returned.
  2206. * @param[out] lppsGroups Array of ECGROUP objects.
  2207. * @return HRESULT MAPI error code.
  2208. */
  2209. HRESULT WSTransport::HrGetGroupList(ULONG cbCompanyId, LPENTRYID lpCompanyId,
  2210. ULONG ulFlags, ULONG *lpcGroups, ECGROUP **lppsGroups)
  2211. {
  2212. ECRESULT er = erSuccess;
  2213. HRESULT hr = hrSuccess;
  2214. struct groupListResponse sResponse;
  2215. entryId sCompanyId = {0};
  2216. LockSoap();
  2217. if(lpcGroups == NULL || lppsGroups == NULL) {
  2218. hr = MAPI_E_INVALID_PARAMETER;
  2219. goto exitm;
  2220. }
  2221. hr = CopyMAPIEntryIdToSOAPEntryId(cbCompanyId, lpCompanyId, &sCompanyId, true);
  2222. if (hr != hrSuccess)
  2223. goto exitm;
  2224. *lpcGroups = 0;
  2225. START_SOAP_CALL
  2226. {
  2227. if(SOAP_OK != m_lpCmd->ns__getGroupList(m_ecSessionId, ABEID_ID(lpCompanyId), sCompanyId, &sResponse))
  2228. er = KCERR_NETWORK_ERROR;
  2229. else
  2230. er = sResponse.er;
  2231. }
  2232. END_SOAP_CALL
  2233. hr = SoapGroupArrayToGroupArray(&sResponse.sGroupArray, ulFlags, lpcGroups, lppsGroups);
  2234. if(hr != hrSuccess)
  2235. goto exitm;
  2236. exitm:
  2237. UnLockSoap();
  2238. return hr;
  2239. }
  2240. HRESULT WSTransport::HrDeleteGroupUser(ULONG cbGroupId, LPENTRYID lpGroupId, ULONG cbUserId, LPENTRYID lpUserId)
  2241. {
  2242. ECRESULT er = erSuccess;
  2243. HRESULT hr = hrSuccess;
  2244. entryId sGroupId = {0};
  2245. entryId sUserId = {0};
  2246. LockSoap();
  2247. if (!lpGroupId || !lpUserId) {
  2248. hr = MAPI_E_INVALID_PARAMETER;
  2249. goto exitm;
  2250. }
  2251. hr = CopyMAPIEntryIdToSOAPEntryId(cbGroupId, lpGroupId, &sGroupId, true);
  2252. if (hr != hrSuccess)
  2253. goto exitm;
  2254. hr = CopyMAPIEntryIdToSOAPEntryId(cbUserId, lpUserId, &sUserId, true);
  2255. if (hr != hrSuccess)
  2256. goto exitm;
  2257. // Remove group
  2258. START_SOAP_CALL
  2259. {
  2260. if(SOAP_OK != m_lpCmd->ns__deleteGroupUser(m_ecSessionId, ABEID_ID(lpGroupId), sGroupId, ABEID_ID(lpUserId), sUserId, &er))
  2261. er = KCERR_NETWORK_ERROR;
  2262. }
  2263. END_SOAP_CALL
  2264. exitm:
  2265. UnLockSoap();
  2266. return hr;
  2267. }
  2268. HRESULT WSTransport::HrAddGroupUser(ULONG cbGroupId, LPENTRYID lpGroupId, ULONG cbUserId, LPENTRYID lpUserId)
  2269. {
  2270. ECRESULT er = erSuccess;
  2271. HRESULT hr = hrSuccess;
  2272. entryId sGroupId = {0};
  2273. entryId sUserId = {0};
  2274. LockSoap();
  2275. if (!lpGroupId || !lpUserId) {
  2276. hr = MAPI_E_INVALID_PARAMETER;
  2277. goto exitm;
  2278. }
  2279. hr = CopyMAPIEntryIdToSOAPEntryId(cbGroupId, lpGroupId, &sGroupId, true);
  2280. if (hr != hrSuccess)
  2281. goto exitm;
  2282. hr = CopyMAPIEntryIdToSOAPEntryId(cbUserId, lpUserId, &sUserId, true);
  2283. if (hr != hrSuccess)
  2284. goto exitm;
  2285. // Remove group
  2286. START_SOAP_CALL
  2287. {
  2288. if(SOAP_OK != m_lpCmd->ns__addGroupUser(m_ecSessionId, ABEID_ID(lpGroupId), sGroupId, ABEID_ID(lpUserId), sUserId, &er))
  2289. er = KCERR_NETWORK_ERROR;
  2290. }
  2291. END_SOAP_CALL
  2292. exitm:
  2293. UnLockSoap();
  2294. return hr;
  2295. }
  2296. /**
  2297. * Get the list of users in a specific group.
  2298. *
  2299. * @param[in] cbGroupId The size in bytes of the entryid of the group
  2300. * @param[in] lpGroupId Pointer to the entryid of the group
  2301. * @param[in] ulFlags MAPI_UNICODE, return values in user struct will be PT_UNICODE, otherwise in PT_STRING8
  2302. * @param[out] lpcUsers Number of users returned.
  2303. * @param[out] lppsUsers Array of ECUSER objects.
  2304. * @return HRESULT MAPI error code.
  2305. */
  2306. HRESULT WSTransport::HrGetUserListOfGroup(ULONG cbGroupId, LPENTRYID lpGroupId,
  2307. ULONG ulFlags, ULONG *lpcUsers, ECUSER **lppsUsers)
  2308. {
  2309. ECRESULT er = erSuccess;
  2310. HRESULT hr = hrSuccess;
  2311. struct userListResponse sResponse;
  2312. entryId sGroupId = {0};
  2313. LockSoap();
  2314. if(lpGroupId == NULL || lpcUsers == NULL || lppsUsers == NULL) {
  2315. hr = MAPI_E_INVALID_PARAMETER;
  2316. goto exitm;
  2317. }
  2318. hr = CopyMAPIEntryIdToSOAPEntryId(cbGroupId, lpGroupId, &sGroupId, true);
  2319. if (hr != hrSuccess)
  2320. goto exitm;
  2321. // Get an userlist of a group
  2322. START_SOAP_CALL
  2323. {
  2324. if(SOAP_OK != m_lpCmd->ns__getUserListOfGroup(m_ecSessionId, ABEID_ID(lpGroupId), sGroupId, &sResponse))
  2325. er = KCERR_NETWORK_ERROR;
  2326. else
  2327. er = sResponse.er;
  2328. }
  2329. END_SOAP_CALL
  2330. hr = SoapUserArrayToUserArray(&sResponse.sUserArray, ulFlags, lpcUsers, lppsUsers);
  2331. if(hr != hrSuccess)
  2332. goto exitm;
  2333. exitm:
  2334. UnLockSoap();
  2335. return hr;
  2336. }
  2337. /**
  2338. * Get the list of groups of which a specifi user is a member.
  2339. *
  2340. * @param[in] cbUserId The size in bytes of the entryid of the user
  2341. * @param[in] cbUserId Pointer to the entryid of the user
  2342. * @param[in] ulFlags MAPI_UNICODE, return values in group struct will be PT_UNICODE, otherwise in PT_STRING8
  2343. * @param[out] lpcGroup Number of groups returned.
  2344. * @param[out] lppsGroups Array of ECGROUP objects.
  2345. * @return HRESULT MAPI error code.
  2346. */
  2347. HRESULT WSTransport::HrGetGroupListOfUser(ULONG cbUserId, LPENTRYID lpUserId,
  2348. ULONG ulFlags, ULONG *lpcGroup, ECGROUP **lppsGroups)
  2349. {
  2350. ECRESULT er = erSuccess;
  2351. HRESULT hr = hrSuccess;
  2352. struct groupListResponse sResponse;
  2353. entryId sUserId = {0};
  2354. LockSoap();
  2355. if(lpcGroup == NULL || lpUserId == NULL || lppsGroups == NULL) {
  2356. hr = MAPI_E_INVALID_PARAMETER;
  2357. goto exitm;
  2358. }
  2359. hr = CopyMAPIEntryIdToSOAPEntryId(cbUserId, lpUserId, &sUserId, true);
  2360. if (hr != hrSuccess)
  2361. goto exitm;
  2362. // Get a grouplist of an user
  2363. START_SOAP_CALL
  2364. {
  2365. if(SOAP_OK != m_lpCmd->ns__getGroupListOfUser(m_ecSessionId, ABEID_ID(lpUserId), sUserId, &sResponse))
  2366. er = KCERR_NETWORK_ERROR;
  2367. else
  2368. er = sResponse.er;
  2369. }
  2370. END_SOAP_CALL
  2371. hr = SoapGroupArrayToGroupArray(&sResponse.sGroupArray, ulFlags, lpcGroup, lppsGroups);
  2372. if(hr != hrSuccess)
  2373. goto exitm;
  2374. exitm:
  2375. UnLockSoap();
  2376. return hr;
  2377. }
  2378. /**
  2379. * Create a new company.
  2380. *
  2381. * @param[in] lpECCompany Pointer to an ECCOMPANY object that contains the details of the company
  2382. * @param[in] ulFlags MAPI_UNICODE, values in company struct will be PT_UNICODE, otherwise in PT_STRING8
  2383. * @param[out] lpcbCompanyId The size in bytes of the entryid
  2384. * @param[out] lppCompanyId The entry id of the new company
  2385. * @return HRESULT MAPI error code.
  2386. */
  2387. HRESULT WSTransport::HrCreateCompany(ECCOMPANY *lpECCompany, ULONG ulFlags,
  2388. ULONG *lpcbCompanyId, LPENTRYID *lppCompanyId)
  2389. {
  2390. ECRESULT er = erSuccess;
  2391. HRESULT hr = hrSuccess;
  2392. struct company sCompany{__gszeroinit};
  2393. struct setCompanyResponse sResponse;
  2394. convert_context converter;
  2395. LockSoap();
  2396. if(lpECCompany == NULL || lpcbCompanyId == NULL || lppCompanyId == NULL) {
  2397. hr = MAPI_E_INVALID_PARAMETER;
  2398. goto exitm;
  2399. }
  2400. sCompany.ulAdministrator = 0;
  2401. sCompany.lpszCompanyname = TO_UTF8_DEF(lpECCompany->lpszCompanyname);
  2402. sCompany.ulIsABHidden = lpECCompany->ulIsABHidden;
  2403. sCompany.lpsPropmap = NULL;
  2404. sCompany.lpsMVPropmap = NULL;
  2405. hr = CopyABPropsToSoap(&lpECCompany->sPropmap, &lpECCompany->sMVPropmap, ulFlags,
  2406. &sCompany.lpsPropmap, &sCompany.lpsMVPropmap);
  2407. if (hr != hrSuccess)
  2408. goto exitm;
  2409. START_SOAP_CALL
  2410. {
  2411. if(SOAP_OK != m_lpCmd->ns__createCompany(m_ecSessionId, &sCompany, &sResponse))
  2412. er = KCERR_NETWORK_ERROR;
  2413. else
  2414. er = sResponse.er;
  2415. }
  2416. END_SOAP_CALL
  2417. hr = CopySOAPEntryIdToMAPIEntryId(&sResponse.sCompanyId, sResponse.ulCompanyId, MAPI_ABCONT, lpcbCompanyId, lppCompanyId);
  2418. exitm:
  2419. UnLockSoap();
  2420. FreeABProps(sCompany.lpsPropmap, sCompany.lpsMVPropmap);
  2421. return hr;
  2422. }
  2423. HRESULT WSTransport::HrDeleteCompany(ULONG cbCompanyId, LPENTRYID lpCompanyId)
  2424. {
  2425. ECRESULT er = erSuccess;
  2426. HRESULT hr = hrSuccess;
  2427. entryId sCompanyId = {0};
  2428. LockSoap();
  2429. if(cbCompanyId < CbNewABEID("") || lpCompanyId == NULL) {
  2430. hr = MAPI_E_INVALID_PARAMETER;
  2431. goto exitm;
  2432. }
  2433. hr = CopyMAPIEntryIdToSOAPEntryId(cbCompanyId, lpCompanyId, &sCompanyId, true);
  2434. if (hr != hrSuccess)
  2435. goto exitm;
  2436. START_SOAP_CALL
  2437. {
  2438. if(SOAP_OK != m_lpCmd->ns__deleteCompany(m_ecSessionId, ABEID_ID(lpCompanyId), sCompanyId, &er))
  2439. er = KCERR_NETWORK_ERROR;
  2440. }
  2441. END_SOAP_CALL
  2442. exitm:
  2443. UnLockSoap();
  2444. return hr;
  2445. }
  2446. /**
  2447. * Update an existing company.
  2448. *
  2449. * This function can create a new comapyn on an offline server.
  2450. *
  2451. * @param[in] lpECCompany Pointer to an ECCOMPANY object that contains the details of the company
  2452. * @param[in] ulFlags MAPI_UNICODE, values in company struct will be PT_UNICODE, otherwise in PT_STRING8
  2453. * @return HRESULT MAPI error code.
  2454. */
  2455. HRESULT WSTransport::HrSetCompany(ECCOMPANY *lpECCompany, ULONG ulFlags)
  2456. {
  2457. ECRESULT er = erSuccess;
  2458. HRESULT hr = hrSuccess;
  2459. struct company sCompany{__gszeroinit};
  2460. convert_context converter;
  2461. LockSoap();
  2462. if(lpECCompany == NULL || lpECCompany->lpszCompanyname == NULL) {
  2463. hr = MAPI_E_INVALID_PARAMETER;
  2464. goto exitm;
  2465. }
  2466. sCompany.lpszCompanyname = TO_UTF8_DEF(lpECCompany->lpszCompanyname);
  2467. sCompany.ulCompanyId = ABEID_ID(lpECCompany->sCompanyId.lpb);
  2468. sCompany.sCompanyId.__size = lpECCompany->sCompanyId.cb;
  2469. sCompany.sCompanyId.__ptr = lpECCompany->sCompanyId.lpb;
  2470. sCompany.ulAdministrator = ABEID_ID(lpECCompany->sAdministrator.lpb);
  2471. sCompany.sAdministrator.__size = lpECCompany->sAdministrator.cb;
  2472. sCompany.sAdministrator.__ptr = lpECCompany->sAdministrator.lpb;
  2473. sCompany.ulIsABHidden = lpECCompany->ulIsABHidden;
  2474. sCompany.lpsPropmap = NULL;
  2475. sCompany.lpsMVPropmap = NULL;
  2476. hr = CopyABPropsToSoap(&lpECCompany->sPropmap, &lpECCompany->sMVPropmap, ulFlags,
  2477. &sCompany.lpsPropmap, &sCompany.lpsMVPropmap);
  2478. if (hr != hrSuccess)
  2479. goto exitm;
  2480. START_SOAP_CALL
  2481. {
  2482. if(SOAP_OK != m_lpCmd->ns__setCompany(m_ecSessionId, &sCompany, &er))
  2483. er = KCERR_NETWORK_ERROR;
  2484. }
  2485. END_SOAP_CALL
  2486. exitm:
  2487. UnLockSoap();
  2488. FreeABProps(sCompany.lpsPropmap, sCompany.lpsMVPropmap);
  2489. return hr;
  2490. }
  2491. /**
  2492. * Get company struct on a specific company.
  2493. *
  2494. * @param[in] cbCompanyId Length as lpCompanyId
  2495. * @param[in] lpCompanyId EntryID of a company
  2496. * @param[in] ulFlags MAPI_UNICODE, return values in company struct will be PT_UNICODE, otherwise in PT_STRING8
  2497. * @param[out] lppECCompany Pointer to an ECOMPANY object that contains the company details
  2498. * @return HRESULT MAPI error code.
  2499. */
  2500. HRESULT WSTransport::HrGetCompany(ULONG cbCompanyId, LPENTRYID lpCompanyId,
  2501. ULONG ulFlags, ECCOMPANY **lppECCompany)
  2502. {
  2503. ECRESULT er = erSuccess;
  2504. HRESULT hr = hrSuccess;
  2505. ECCOMPANY *lpCompany = NULL;
  2506. struct getCompanyResponse sResponse;
  2507. entryId sCompanyId = {0};
  2508. LockSoap();
  2509. if (lpCompanyId == NULL || lppECCompany == NULL)
  2510. {
  2511. hr = MAPI_E_INVALID_PARAMETER;
  2512. goto exitm;
  2513. }
  2514. hr = CopyMAPIEntryIdToSOAPEntryId(cbCompanyId, lpCompanyId, &sCompanyId, true);
  2515. if (hr != hrSuccess)
  2516. goto exitm;
  2517. START_SOAP_CALL
  2518. {
  2519. if(SOAP_OK != m_lpCmd->ns__getCompany(m_ecSessionId, ABEID_ID(lpCompanyId), sCompanyId, &sResponse))
  2520. er = KCERR_NETWORK_ERROR;
  2521. else
  2522. er = sResponse.er;
  2523. }
  2524. END_SOAP_CALL
  2525. hr = SoapCompanyToCompany(sResponse.lpsCompany, ulFlags, &lpCompany);
  2526. if (hr != hrSuccess)
  2527. goto exitm;
  2528. *lppECCompany = lpCompany;
  2529. exitm:
  2530. UnLockSoap();
  2531. return hr;
  2532. }
  2533. /**
  2534. * Resolve a company's entryid by name.
  2535. *
  2536. * @param[in] lpszCompanyName The companyname to resolve.
  2537. * @param[in] ulFlags MAPI_UNICODE, lpszCompanyName is in PT_UNICODE, otherwise in PT_STRING8
  2538. * @param[out] lpcbCompanyId The size in bytes of the entryid.
  2539. * @param[out] lppCompanyId The entryid of the resolved company.
  2540. * @return HRESULT MAPI error code.
  2541. */
  2542. HRESULT WSTransport::HrResolveCompanyName(LPCTSTR lpszCompanyName, ULONG ulFlags, ULONG *lpcbCompanyId, LPENTRYID *lppCompanyId)
  2543. {
  2544. ECRESULT er = erSuccess;
  2545. HRESULT hr = hrSuccess;
  2546. struct resolveCompanyResponse sResponse;
  2547. LockSoap();
  2548. if(lpszCompanyName == NULL || lpcbCompanyId == NULL || lppCompanyId == NULL) {
  2549. hr = MAPI_E_INVALID_PARAMETER;
  2550. goto exitm;
  2551. }
  2552. //Resolve companyid from companyname
  2553. START_SOAP_CALL
  2554. {
  2555. if(SOAP_OK != m_lpCmd->ns__resolveCompanyname(m_ecSessionId, (char*)convstring(lpszCompanyName, ulFlags).u8_str(), &sResponse))
  2556. er = KCERR_NETWORK_ERROR;
  2557. else
  2558. er = sResponse.er;
  2559. }
  2560. END_SOAP_CALL
  2561. hr = CopySOAPEntryIdToMAPIEntryId(&sResponse.sCompanyId, sResponse.ulCompanyId, MAPI_ABCONT, lpcbCompanyId, lppCompanyId);
  2562. exitm:
  2563. UnLockSoap();
  2564. return hr;
  2565. }
  2566. /**
  2567. * Get the list of available companies.
  2568. *
  2569. * @param[in] ulFlags MAPI_UNICODE, return values in company structs are in PT_UNICODE, otherwise in PT_STRING8
  2570. * @param[out] lpcCompanies The number of companies.
  2571. * @param[out] lppsCompanies Pointer to an array of ECCOMPANY objects.
  2572. * @return HRESULT MAPI error code.
  2573. */
  2574. HRESULT WSTransport::HrGetCompanyList(ULONG ulFlags, ULONG *lpcCompanies,
  2575. ECCOMPANY **lppsCompanies)
  2576. {
  2577. ECRESULT er = erSuccess;
  2578. HRESULT hr = hrSuccess;
  2579. struct companyListResponse sResponse;
  2580. LockSoap();
  2581. if(lpcCompanies == NULL || lppsCompanies == NULL) {
  2582. hr = MAPI_E_INVALID_PARAMETER;
  2583. goto exitm;
  2584. }
  2585. *lpcCompanies = 0;
  2586. START_SOAP_CALL
  2587. {
  2588. if(SOAP_OK != m_lpCmd->ns__getCompanyList(m_ecSessionId, &sResponse))
  2589. er = KCERR_NETWORK_ERROR;
  2590. else
  2591. er = sResponse.er;
  2592. }
  2593. END_SOAP_CALL
  2594. hr = SoapCompanyArrayToCompanyArray(&sResponse.sCompanyArray, ulFlags, lpcCompanies, lppsCompanies);
  2595. if(hr != hrSuccess)
  2596. goto exitm;
  2597. exitm:
  2598. UnLockSoap();
  2599. return hr;
  2600. }
  2601. HRESULT WSTransport::HrAddCompanyToRemoteViewList(ULONG cbSetCompanyId, LPENTRYID lpSetCompanyId, ULONG cbCompanyId, LPENTRYID lpCompanyId)
  2602. {
  2603. ECRESULT er = erSuccess;
  2604. HRESULT hr = hrSuccess;
  2605. entryId sSetCompanyId = {0};
  2606. entryId sCompanyId = {0};
  2607. LockSoap();
  2608. if (lpSetCompanyId == NULL || lpCompanyId == NULL)
  2609. {
  2610. hr = MAPI_E_INVALID_PARAMETER;
  2611. goto exitm;
  2612. }
  2613. hr = CopyMAPIEntryIdToSOAPEntryId(cbSetCompanyId, lpSetCompanyId, &sSetCompanyId, true);
  2614. if (hr != hrSuccess)
  2615. goto exitm;
  2616. hr = CopyMAPIEntryIdToSOAPEntryId(cbCompanyId, lpCompanyId, &sCompanyId, true);
  2617. if (hr != hrSuccess)
  2618. goto exitm;
  2619. START_SOAP_CALL
  2620. {
  2621. if(SOAP_OK != m_lpCmd->ns__addCompanyToRemoteViewList(m_ecSessionId, ABEID_ID(lpSetCompanyId), sSetCompanyId, ABEID_ID(lpCompanyId), sCompanyId, &er))
  2622. er = KCERR_NETWORK_ERROR;
  2623. }
  2624. END_SOAP_CALL
  2625. exitm:
  2626. UnLockSoap();
  2627. return hr;
  2628. }
  2629. HRESULT WSTransport::HrDelCompanyFromRemoteViewList(ULONG cbSetCompanyId, LPENTRYID lpSetCompanyId, ULONG cbCompanyId, LPENTRYID lpCompanyId)
  2630. {
  2631. ECRESULT er = erSuccess;
  2632. HRESULT hr = hrSuccess;
  2633. entryId sSetCompanyId = {0};
  2634. entryId sCompanyId = {0};
  2635. LockSoap();
  2636. if (lpSetCompanyId == NULL || lpCompanyId == NULL)
  2637. {
  2638. hr = MAPI_E_INVALID_PARAMETER;
  2639. goto exitm;
  2640. }
  2641. hr = CopyMAPIEntryIdToSOAPEntryId(cbSetCompanyId, lpSetCompanyId, &sSetCompanyId, true);
  2642. if (hr != hrSuccess)
  2643. goto exitm;
  2644. hr = CopyMAPIEntryIdToSOAPEntryId(cbCompanyId, lpCompanyId, &sCompanyId, true);
  2645. if (hr != hrSuccess)
  2646. goto exitm;
  2647. START_SOAP_CALL
  2648. {
  2649. if(SOAP_OK != m_lpCmd->ns__delCompanyFromRemoteViewList(m_ecSessionId, ABEID_ID(lpSetCompanyId), sSetCompanyId, ABEID_ID(lpCompanyId), sCompanyId, &er))
  2650. er = KCERR_NETWORK_ERROR;
  2651. }
  2652. END_SOAP_CALL
  2653. exitm:
  2654. UnLockSoap();
  2655. return hr;
  2656. }
  2657. /**
  2658. * Get the remote-view-list of a specific company.
  2659. *
  2660. * @param[in] cbCompanyId Size in bytes of the company entryid.
  2661. * @param[in] lpCompanyId Entryid of the company.
  2662. * @param[in] ulFlags MAPI_UNICODE, return values in company structs will be PT_UNICODE, otherwise PT_STRING8
  2663. * @param[out] lpcCompanies The number of results.
  2664. * @param[out] lppsCompanies Array of ECCOMPANY objects.
  2665. * @return HRESULT MAPI error code.
  2666. */
  2667. HRESULT WSTransport::HrGetRemoteViewList(ULONG cbCompanyId,
  2668. LPENTRYID lpCompanyId, ULONG ulFlags, ULONG *lpcCompanies,
  2669. ECCOMPANY **lppsCompanies)
  2670. {
  2671. ECRESULT er = erSuccess;
  2672. HRESULT hr = hrSuccess;
  2673. struct companyListResponse sResponse;
  2674. entryId sCompanyId = {0};
  2675. LockSoap();
  2676. if(lpcCompanies == NULL || lpCompanyId == NULL || lppsCompanies == NULL) {
  2677. hr = MAPI_E_INVALID_PARAMETER;
  2678. goto exitm;
  2679. }
  2680. hr = CopyMAPIEntryIdToSOAPEntryId(cbCompanyId, lpCompanyId, &sCompanyId, true);
  2681. if (hr != hrSuccess)
  2682. goto exitm;
  2683. *lpcCompanies = 0;
  2684. START_SOAP_CALL
  2685. {
  2686. if(SOAP_OK != m_lpCmd->ns__getRemoteViewList(m_ecSessionId, ABEID_ID(lpCompanyId), sCompanyId, &sResponse))
  2687. er = KCERR_NETWORK_ERROR;
  2688. else
  2689. er = sResponse.er;
  2690. }
  2691. END_SOAP_CALL
  2692. hr = SoapCompanyArrayToCompanyArray(&sResponse.sCompanyArray, ulFlags, lpcCompanies, lppsCompanies);
  2693. if(hr != hrSuccess)
  2694. goto exitm;
  2695. exitm:
  2696. UnLockSoap();
  2697. return hr;
  2698. }
  2699. HRESULT WSTransport::HrAddUserToRemoteAdminList(ULONG cbUserId, LPENTRYID lpUserId, ULONG cbCompanyId, LPENTRYID lpCompanyId)
  2700. {
  2701. ECRESULT er = erSuccess;
  2702. HRESULT hr = hrSuccess;
  2703. entryId sUserId = {0};
  2704. entryId sCompanyId = {0};
  2705. LockSoap();
  2706. if (lpUserId == NULL || lpCompanyId == NULL)
  2707. {
  2708. hr = MAPI_E_INVALID_PARAMETER;
  2709. goto exitm;
  2710. }
  2711. hr = CopyMAPIEntryIdToSOAPEntryId(cbUserId, lpUserId, &sUserId, true);
  2712. if (hr != hrSuccess)
  2713. goto exitm;
  2714. hr = CopyMAPIEntryIdToSOAPEntryId(cbCompanyId, lpCompanyId, &sCompanyId, true);
  2715. if (hr != hrSuccess)
  2716. goto exitm;
  2717. START_SOAP_CALL
  2718. {
  2719. if(SOAP_OK != m_lpCmd->ns__addUserToRemoteAdminList(m_ecSessionId, ABEID_ID(lpUserId), sUserId, ABEID_ID(lpCompanyId), sCompanyId, &er))
  2720. er = KCERR_NETWORK_ERROR;
  2721. }
  2722. END_SOAP_CALL
  2723. exitm:
  2724. UnLockSoap();
  2725. return hr;
  2726. }
  2727. HRESULT WSTransport::HrDelUserFromRemoteAdminList(ULONG cbUserId, LPENTRYID lpUserId, ULONG cbCompanyId, LPENTRYID lpCompanyId)
  2728. {
  2729. ECRESULT er = erSuccess;
  2730. HRESULT hr = hrSuccess;
  2731. entryId sUserId = {0};
  2732. entryId sCompanyId = {0};
  2733. LockSoap();
  2734. if (lpUserId == NULL || lpCompanyId == NULL)
  2735. {
  2736. hr = MAPI_E_INVALID_PARAMETER;
  2737. goto exitm;
  2738. }
  2739. hr = CopyMAPIEntryIdToSOAPEntryId(cbUserId, lpUserId, &sUserId, true);
  2740. if (hr != hrSuccess)
  2741. goto exitm;
  2742. hr = CopyMAPIEntryIdToSOAPEntryId(cbCompanyId, lpCompanyId, &sCompanyId, true);
  2743. if (hr != hrSuccess)
  2744. goto exitm;
  2745. START_SOAP_CALL
  2746. {
  2747. if(SOAP_OK != m_lpCmd->ns__delUserFromRemoteAdminList(m_ecSessionId, ABEID_ID(lpUserId), sUserId, ABEID_ID(lpCompanyId), sCompanyId, &er))
  2748. er = KCERR_NETWORK_ERROR;
  2749. }
  2750. END_SOAP_CALL
  2751. exitm:
  2752. UnLockSoap();
  2753. return hr;
  2754. }
  2755. /**
  2756. * Get the remote-admin-list of a specific company.
  2757. *
  2758. * @param[in] cbCompanyId Size in bytes of the company entryid.
  2759. * @param[in] lpCompanyId Entryid of the company.
  2760. * @param[in] ulFlags MAPI_UNICODE, return values in user structs will be PT_UNICODE, otherwise PT_STRING8
  2761. * @param[out] lpcUsers The number of results.
  2762. * @param[out] lppsUsers Array of ECUSER objects.
  2763. * @return HRESULT MAPI error code.
  2764. */
  2765. HRESULT WSTransport::HrGetRemoteAdminList(ULONG cbCompanyId,
  2766. LPENTRYID lpCompanyId, ULONG ulFlags, ULONG *lpcUsers, ECUSER **lppsUsers)
  2767. {
  2768. ECRESULT er = erSuccess;
  2769. HRESULT hr = hrSuccess;
  2770. struct userListResponse sResponse;
  2771. entryId sCompanyId = {0};
  2772. LockSoap();
  2773. if(lpcUsers == NULL || lpCompanyId == NULL || lppsUsers == NULL) {
  2774. hr = MAPI_E_INVALID_PARAMETER;
  2775. goto exitm;
  2776. }
  2777. hr = CopyMAPIEntryIdToSOAPEntryId(cbCompanyId, lpCompanyId, &sCompanyId, true);
  2778. if (hr != hrSuccess)
  2779. goto exitm;
  2780. *lpcUsers = 0;
  2781. START_SOAP_CALL
  2782. {
  2783. if(SOAP_OK != m_lpCmd->ns__getRemoteAdminList(m_ecSessionId, ABEID_ID(lpCompanyId), sCompanyId, &sResponse))
  2784. er = KCERR_NETWORK_ERROR;
  2785. else
  2786. er = sResponse.er;
  2787. }
  2788. END_SOAP_CALL
  2789. hr = SoapUserArrayToUserArray(&sResponse.sUserArray, ulFlags, lpcUsers, lppsUsers);
  2790. if(hr != hrSuccess)
  2791. goto exitm;
  2792. exitm:
  2793. UnLockSoap();
  2794. return hr;
  2795. }
  2796. HRESULT WSTransport::HrGetPermissionRules(int ulType, ULONG cbEntryID,
  2797. LPENTRYID lpEntryID, ULONG *lpcPermissions,
  2798. ECPERMISSION **lppECPermissions)
  2799. {
  2800. ECRESULT er = erSuccess;
  2801. HRESULT hr = hrSuccess;
  2802. entryId sEntryId = {0}; // Do not free
  2803. ecmem_ptr<ECPERMISSION> lpECPermissions;
  2804. ecmem_ptr<ENTRYID> lpUnWrapStoreID;
  2805. ULONG cbUnWrapStoreID = 0;
  2806. struct rightsResponse sRightResponse;
  2807. LockSoap();
  2808. if(lpcPermissions == NULL || lppECPermissions == NULL) {
  2809. hr = MAPI_E_INVALID_PARAMETER;
  2810. goto exitm;
  2811. }
  2812. // Remove servername, always
  2813. hr = UnWrapServerClientStoreEntry(cbEntryID, lpEntryID, &cbUnWrapStoreID, &~lpUnWrapStoreID);
  2814. if(hr != hrSuccess)
  2815. goto exitm;
  2816. sEntryId.__ptr = reinterpret_cast<unsigned char *>(lpUnWrapStoreID.get());
  2817. sEntryId.__size = cbUnWrapStoreID;
  2818. START_SOAP_CALL
  2819. {
  2820. if(SOAP_OK != m_lpCmd->ns__getRights(m_ecSessionId, sEntryId, ulType, &sRightResponse))
  2821. er = KCERR_NETWORK_ERROR;
  2822. else
  2823. er = sRightResponse.er;
  2824. }
  2825. END_SOAP_CALL
  2826. hr = ECAllocateBuffer(sizeof(ECPERMISSION) * sRightResponse.pRightsArray->__size,
  2827. &~lpECPermissions);
  2828. if (hr != erSuccess)
  2829. goto exitm;
  2830. for (gsoap_size_t i = 0; i < sRightResponse.pRightsArray->__size; ++i) {
  2831. lpECPermissions[i].ulRights = sRightResponse.pRightsArray->__ptr[i].ulRights;
  2832. lpECPermissions[i].ulState = sRightResponse.pRightsArray->__ptr[i].ulState;
  2833. lpECPermissions[i].ulType = sRightResponse.pRightsArray->__ptr[i].ulType;
  2834. hr = CopySOAPEntryIdToMAPIEntryId(&sRightResponse.pRightsArray->__ptr[i].sUserId, sRightResponse.pRightsArray->__ptr[i].ulUserid, MAPI_MAILUSER, (ULONG*)&lpECPermissions[i].sUserId.cb, (LPENTRYID*)&lpECPermissions[i].sUserId.lpb, lpECPermissions);
  2835. if (hr != hrSuccess)
  2836. goto exitm;
  2837. }
  2838. *lppECPermissions = lpECPermissions.release();
  2839. *lpcPermissions = sRightResponse.pRightsArray->__size;
  2840. lpECPermissions = NULL;
  2841. exitm:
  2842. UnLockSoap();
  2843. return hr;
  2844. }
  2845. HRESULT WSTransport::HrSetPermissionRules(ULONG cbEntryID, LPENTRYID lpEntryID,
  2846. ULONG cPermissions, ECPERMISSION *lpECPermissions)
  2847. {
  2848. ECRESULT er = erSuccess;
  2849. HRESULT hr = hrSuccess;
  2850. entryId sEntryId = {0}; // Do not free
  2851. int nChangedItems = 0;
  2852. unsigned int i,
  2853. nItem;
  2854. ecmem_ptr<ENTRYID> lpUnWrapStoreID;
  2855. ULONG cbUnWrapStoreID = 0;
  2856. struct rightsArray rArray;
  2857. LockSoap();
  2858. if(cPermissions == 0 || lpECPermissions == NULL) {
  2859. hr = MAPI_E_INVALID_PARAMETER;
  2860. goto exitm;
  2861. }
  2862. // Remove servername, always
  2863. hr = UnWrapServerClientStoreEntry(cbEntryID, lpEntryID, &cbUnWrapStoreID, &~lpUnWrapStoreID);
  2864. if(hr != hrSuccess)
  2865. goto exitm;
  2866. sEntryId.__ptr = reinterpret_cast<unsigned char *>(lpUnWrapStoreID.get());
  2867. sEntryId.__size = cbUnWrapStoreID;
  2868. // Count the updated items
  2869. for (i = 0; i < cPermissions; ++i)
  2870. if(lpECPermissions[i].ulState != RIGHT_NORMAL)
  2871. ++nChangedItems;
  2872. rArray.__ptr = s_alloc<rights>(m_lpCmd->soap, nChangedItems);
  2873. rArray.__size = nChangedItems;
  2874. nItem = 0;
  2875. for (i = 0 ; i < cPermissions; ++i) {
  2876. if(lpECPermissions[i].ulState != RIGHT_NORMAL){
  2877. rArray.__ptr[nItem].ulRights = lpECPermissions[i].ulRights;
  2878. rArray.__ptr[nItem].ulState = lpECPermissions[i].ulState;
  2879. rArray.__ptr[nItem].ulType = lpECPermissions[i].ulType;
  2880. rArray.__ptr[nItem].ulUserid = ABEID_ID(lpECPermissions[i].sUserId.lpb);
  2881. hr = CopyMAPIEntryIdToSOAPEntryId(lpECPermissions[i].sUserId.cb, (LPENTRYID)lpECPermissions[i].sUserId.lpb, &rArray.__ptr[nItem].sUserId, true);
  2882. if (hr != hrSuccess)
  2883. goto exitm;
  2884. ++nItem;
  2885. }
  2886. }
  2887. START_SOAP_CALL
  2888. {
  2889. if(SOAP_OK != m_lpCmd->ns__setRights(m_ecSessionId, sEntryId, &rArray, &er))
  2890. er = KCERR_NETWORK_ERROR;
  2891. }
  2892. END_SOAP_CALL
  2893. exitm:
  2894. UnLockSoap();
  2895. return hr;
  2896. }
  2897. HRESULT WSTransport::HrGetOwner(ULONG cbEntryID, LPENTRYID lpEntryID, ULONG *lpcbOwnerId, LPENTRYID *lppOwnerId)
  2898. {
  2899. ECRESULT er = erSuccess;
  2900. HRESULT hr = hrSuccess;
  2901. entryId sEntryId = {0}; // Do not free
  2902. struct getOwnerResponse sResponse;
  2903. ecmem_ptr<ENTRYID> lpUnWrapStoreID;
  2904. ULONG cbUnWrapStoreID = 0;
  2905. LockSoap();
  2906. if (lpcbOwnerId == NULL || lppOwnerId == NULL)
  2907. {
  2908. hr = MAPI_E_INVALID_PARAMETER;
  2909. goto exitm;
  2910. }
  2911. // Remove servername, always
  2912. hr = UnWrapServerClientStoreEntry(cbEntryID, lpEntryID, &cbUnWrapStoreID, &~lpUnWrapStoreID);
  2913. if(hr != hrSuccess)
  2914. goto exitm;
  2915. sEntryId.__ptr = reinterpret_cast<unsigned char *>(lpUnWrapStoreID.get());
  2916. sEntryId.__size = cbUnWrapStoreID;
  2917. START_SOAP_CALL
  2918. {
  2919. if(SOAP_OK != m_lpCmd->ns__getOwner(m_ecSessionId, sEntryId, &sResponse))
  2920. er = KCERR_NETWORK_ERROR;
  2921. else
  2922. er = sResponse.er;
  2923. }
  2924. END_SOAP_CALL
  2925. hr = CopySOAPEntryIdToMAPIEntryId(&sResponse.sOwner, sResponse.ulOwner, lpcbOwnerId, lppOwnerId);
  2926. exitm:
  2927. UnLockSoap();
  2928. return hr;
  2929. }
  2930. /**
  2931. * Calls ns__abResolveNames.
  2932. *
  2933. * Converts client input to SOAP structs, and calls ns__abResolveNames
  2934. * on server. Server soap results are converted back into lpAdrList
  2935. * and lpFlagList.
  2936. *
  2937. * @param[in] lpPropTagArray Requested properties from server in rows of lpAdrList. May not be NULL.
  2938. * @param[in] ulFlags Client flags passed to server.
  2939. * @param[in/out] lpAdrList Contains one search request per row, using PR_DISPLAY_NAME.
  2940. * @param[in/out] lpFlagList Contains current status of matching row in lpAdrList, eg MAPI_(UN)RESOLVED.
  2941. * @return HRESULT MAPI error code.
  2942. */
  2943. HRESULT WSTransport::HrResolveNames(const SPropTagArray *lpPropTagArray,
  2944. ULONG ulFlags, LPADRLIST lpAdrList, LPFlagList lpFlagList)
  2945. {
  2946. ECRESULT er = erSuccess;
  2947. HRESULT hr = hrSuccess;
  2948. struct propTagArray aPropTag;
  2949. struct rowSet* lpsRowSet = NULL;
  2950. struct flagArray aFlags;
  2951. struct abResolveNamesResponse sResponse;
  2952. convert_context converter;
  2953. LockSoap();
  2954. aPropTag.__ptr = (unsigned int *)&lpPropTagArray->aulPropTag; // just a reference
  2955. aPropTag.__size = lpPropTagArray->cValues;
  2956. aFlags.__ptr = (unsigned int *)&lpFlagList->ulFlag;
  2957. aFlags.__size = lpFlagList->cFlags;
  2958. hr = CopyMAPIRowSetToSOAPRowSet((LPSRowSet)lpAdrList, &lpsRowSet, &converter);
  2959. if(hr != hrSuccess)
  2960. goto exitm;
  2961. START_SOAP_CALL
  2962. {
  2963. if(SOAP_OK != m_lpCmd->ns__abResolveNames(m_ecSessionId, &aPropTag, lpsRowSet, &aFlags, ulFlags, &sResponse))
  2964. er = KCERR_NETWORK_ERROR;
  2965. else
  2966. er = sResponse.er;
  2967. }
  2968. END_SOAP_CALL
  2969. assert(sResponse.aFlags.__size == lpFlagList->cFlags);
  2970. assert(static_cast<ULONG>(sResponse.sRowSet.__size) == lpAdrList->cEntries);
  2971. for (gsoap_size_t i = 0; i < sResponse.aFlags.__size; ++i) {
  2972. // Set the resolved items
  2973. if(lpFlagList->ulFlag[i] == MAPI_UNRESOLVED && sResponse.aFlags.__ptr[i] == MAPI_RESOLVED)
  2974. {
  2975. lpAdrList->aEntries[i].cValues = sResponse.sRowSet.__ptr[i].__size;
  2976. ECFreeBuffer(lpAdrList->aEntries[i].rgPropVals);
  2977. hr = ECAllocateBuffer(sizeof(SPropValue) * lpAdrList->aEntries[i].cValues,
  2978. reinterpret_cast<void **>(&lpAdrList->aEntries[i].rgPropVals));
  2979. if (hr != hrSuccess)
  2980. goto exitm;
  2981. hr = CopySOAPRowToMAPIRow(&sResponse.sRowSet.__ptr[i], lpAdrList->aEntries[i].rgPropVals, (void*)lpAdrList->aEntries[i].rgPropVals, &converter);
  2982. if(hr != hrSuccess)
  2983. goto exitm;
  2984. lpFlagList->ulFlag[i] = sResponse.aFlags.__ptr[i];
  2985. }else { // MAPI_AMBIGUOUS or MAPI_UNRESOLVED
  2986. // only set the flag, do nothing with the row
  2987. lpFlagList->ulFlag[i] = sResponse.aFlags.__ptr[i];
  2988. }
  2989. }
  2990. exitm:
  2991. UnLockSoap();
  2992. if(lpsRowSet)
  2993. FreeRowSet(lpsRowSet, true);
  2994. return hr;
  2995. }
  2996. HRESULT WSTransport::HrSyncUsers(ULONG cbCompanyId, LPENTRYID lpCompanyId)
  2997. {
  2998. ECRESULT er = erSuccess;
  2999. HRESULT hr = hrSuccess;
  3000. unsigned int sResponse;
  3001. entryId sCompanyId = {0};
  3002. ULONG ulCompanyId = 0;
  3003. LockSoap();
  3004. if (lpCompanyId)
  3005. {
  3006. hr = CopyMAPIEntryIdToSOAPEntryId(cbCompanyId, lpCompanyId, &sCompanyId, true);
  3007. if (hr != hrSuccess)
  3008. goto exitm;
  3009. ulCompanyId = ABEID_ID(lpCompanyId);
  3010. }
  3011. START_SOAP_CALL
  3012. {
  3013. if(SOAP_OK != m_lpCmd->ns__syncUsers(m_ecSessionId, ulCompanyId, sCompanyId, &sResponse))
  3014. er = KCERR_NETWORK_ERROR;
  3015. else
  3016. er = (ECRESULT) sResponse;
  3017. }
  3018. END_SOAP_CALL
  3019. exitm:
  3020. UnLockSoap();
  3021. return hr;
  3022. }
  3023. HRESULT WSTransport::GetQuota(ULONG cbUserId, LPENTRYID lpUserId,
  3024. bool bGetUserDefault, ECQUOTA **lppsQuota)
  3025. {
  3026. ECRESULT er = erSuccess;
  3027. HRESULT hr = hrSuccess;
  3028. struct quotaResponse sResponse;
  3029. ECQUOTA *lpsQuota = NULL;
  3030. entryId sUserId = {0};
  3031. LockSoap();
  3032. if(lppsQuota == NULL || lpUserId == NULL) {
  3033. hr = MAPI_E_INVALID_PARAMETER;
  3034. goto exitm;
  3035. }
  3036. hr = CopyMAPIEntryIdToSOAPEntryId(cbUserId, lpUserId, &sUserId, true);
  3037. if (hr != hrSuccess)
  3038. goto exitm;
  3039. START_SOAP_CALL
  3040. {
  3041. if(SOAP_OK != m_lpCmd->ns__GetQuota(m_ecSessionId, ABEID_ID(lpUserId), sUserId, bGetUserDefault, &sResponse))
  3042. er = KCERR_NETWORK_ERROR;
  3043. else
  3044. er = (ECRESULT) sResponse.er;
  3045. }
  3046. END_SOAP_CALL
  3047. er = ECAllocateBuffer(sizeof(ECQUOTA), reinterpret_cast<void **>(&lpsQuota));
  3048. if (er != erSuccess)
  3049. goto exitm;
  3050. lpsQuota->bUseDefaultQuota = sResponse.sQuota.bUseDefaultQuota;
  3051. lpsQuota->bIsUserDefaultQuota = sResponse.sQuota.bIsUserDefaultQuota;
  3052. lpsQuota->llHardSize = sResponse.sQuota.llHardSize;
  3053. lpsQuota->llSoftSize = sResponse.sQuota.llSoftSize;
  3054. lpsQuota->llWarnSize = sResponse.sQuota.llWarnSize;
  3055. *lppsQuota = lpsQuota;
  3056. exitm:
  3057. UnLockSoap();
  3058. return hr;
  3059. }
  3060. HRESULT WSTransport::SetQuota(ULONG cbUserId, LPENTRYID lpUserId,
  3061. ECQUOTA *lpsQuota)
  3062. {
  3063. ECRESULT er = erSuccess;
  3064. HRESULT hr = hrSuccess;
  3065. unsigned int sResponse;
  3066. struct quota sQuota;
  3067. entryId sUserId = {0};
  3068. LockSoap();
  3069. if(lpsQuota == NULL || lpUserId == NULL) {
  3070. hr = MAPI_E_INVALID_PARAMETER;
  3071. goto exitm;
  3072. }
  3073. hr = CopyMAPIEntryIdToSOAPEntryId(cbUserId, lpUserId, &sUserId, true);
  3074. if (hr != hrSuccess)
  3075. goto exitm;
  3076. sQuota.bUseDefaultQuota = lpsQuota->bUseDefaultQuota;
  3077. sQuota.bIsUserDefaultQuota = lpsQuota->bIsUserDefaultQuota;
  3078. sQuota.llHardSize = lpsQuota->llHardSize;
  3079. sQuota.llSoftSize = lpsQuota->llSoftSize;
  3080. sQuota.llWarnSize = lpsQuota->llWarnSize;
  3081. START_SOAP_CALL
  3082. {
  3083. if(SOAP_OK != m_lpCmd->ns__SetQuota(m_ecSessionId, ABEID_ID(lpUserId), sUserId, &sQuota, &sResponse))
  3084. er = KCERR_NETWORK_ERROR;
  3085. else
  3086. er = (ECRESULT) sResponse;
  3087. }
  3088. END_SOAP_CALL
  3089. exitm:
  3090. UnLockSoap();
  3091. return hr;
  3092. }
  3093. HRESULT WSTransport::AddQuotaRecipient(ULONG cbCompanyId, LPENTRYID lpCompanyId, ULONG cbRecipientId, LPENTRYID lpRecipientId, ULONG ulType)
  3094. {
  3095. ECRESULT er = erSuccess;
  3096. HRESULT hr = hrSuccess;
  3097. entryId sCompanyId = {0};
  3098. entryId sRecipientId = {0};
  3099. LockSoap();
  3100. if (lpCompanyId == NULL || lpRecipientId == NULL)
  3101. {
  3102. hr = MAPI_E_INVALID_PARAMETER;
  3103. goto exitm;
  3104. }
  3105. hr = CopyMAPIEntryIdToSOAPEntryId(cbCompanyId, lpCompanyId, &sCompanyId, true);
  3106. if (hr != hrSuccess)
  3107. goto exitm;
  3108. hr = CopyMAPIEntryIdToSOAPEntryId(cbRecipientId, lpRecipientId, &sRecipientId, true);
  3109. if (hr != hrSuccess)
  3110. goto exitm;
  3111. START_SOAP_CALL
  3112. {
  3113. if(SOAP_OK != m_lpCmd->ns__AddQuotaRecipient(m_ecSessionId, ABEID_ID(lpCompanyId), sCompanyId, ABEID_ID(lpRecipientId), sRecipientId, ulType, &er))
  3114. er = KCERR_NETWORK_ERROR;
  3115. }
  3116. END_SOAP_CALL
  3117. exitm:
  3118. UnLockSoap();
  3119. return hr;
  3120. }
  3121. HRESULT WSTransport::DeleteQuotaRecipient(ULONG cbCompanyId, LPENTRYID lpCompanyId, ULONG cbRecipientId, LPENTRYID lpRecipientId, ULONG ulType)
  3122. {
  3123. ECRESULT er = erSuccess;
  3124. HRESULT hr = hrSuccess;
  3125. entryId sCompanyId = {0};
  3126. entryId sRecipientId = {0};
  3127. LockSoap();
  3128. if (lpCompanyId == NULL || lpRecipientId == NULL)
  3129. {
  3130. hr = MAPI_E_INVALID_PARAMETER;
  3131. goto exitm;
  3132. }
  3133. hr = CopyMAPIEntryIdToSOAPEntryId(cbCompanyId, lpCompanyId, &sCompanyId, true);
  3134. if (hr != hrSuccess)
  3135. goto exitm;
  3136. hr = CopyMAPIEntryIdToSOAPEntryId(cbRecipientId, lpRecipientId, &sRecipientId, true);
  3137. if (hr != hrSuccess)
  3138. goto exitm;
  3139. START_SOAP_CALL
  3140. {
  3141. if(SOAP_OK != m_lpCmd->ns__DeleteQuotaRecipient(m_ecSessionId, ABEID_ID(lpCompanyId), sCompanyId, ABEID_ID(lpRecipientId), sRecipientId, ulType, &er))
  3142. er = KCERR_NETWORK_ERROR;
  3143. }
  3144. END_SOAP_CALL
  3145. exitm:
  3146. UnLockSoap();
  3147. return hr;
  3148. }
  3149. HRESULT WSTransport::GetQuotaRecipients(ULONG cbUserId, LPENTRYID lpUserId,
  3150. ULONG ulFlags, ULONG *lpcUsers, ECUSER **lppsUsers)
  3151. {
  3152. ECRESULT er = erSuccess;
  3153. HRESULT hr = hrSuccess;
  3154. entryId sUserId = {0};
  3155. struct userListResponse sResponse;
  3156. LockSoap();
  3157. if(lpcUsers == NULL || lppsUsers == NULL) {
  3158. hr = MAPI_E_INVALID_PARAMETER;
  3159. goto exitm;
  3160. }
  3161. hr = CopyMAPIEntryIdToSOAPEntryId(cbUserId, lpUserId, &sUserId, true);
  3162. if (hr != hrSuccess)
  3163. goto exitm;
  3164. *lpcUsers = 0;
  3165. START_SOAP_CALL
  3166. {
  3167. if(SOAP_OK != m_lpCmd->ns__GetQuotaRecipients(m_ecSessionId, ABEID_ID(lpUserId), sUserId, &sResponse))
  3168. er = KCERR_NETWORK_ERROR;
  3169. else
  3170. er = sResponse.er;
  3171. }
  3172. END_SOAP_CALL
  3173. hr = SoapUserArrayToUserArray(&sResponse.sUserArray, ulFlags, lpcUsers, lppsUsers);
  3174. if(hr != hrSuccess)
  3175. goto exitm;
  3176. exitm:
  3177. UnLockSoap();
  3178. return hr;
  3179. }
  3180. HRESULT WSTransport::GetQuotaStatus(ULONG cbUserId, LPENTRYID lpUserId,
  3181. ECQUOTASTATUS **lppsQuotaStatus)
  3182. {
  3183. ECRESULT er = erSuccess;
  3184. HRESULT hr = hrSuccess;
  3185. struct quotaStatus sResponse;
  3186. ECQUOTASTATUS *lpsQuotaStatus = NULL;
  3187. entryId sUserId = {0};
  3188. LockSoap();
  3189. if(lppsQuotaStatus == NULL) {
  3190. hr = MAPI_E_INVALID_PARAMETER;
  3191. goto exitm;
  3192. }
  3193. hr = CopyMAPIEntryIdToSOAPEntryId(cbUserId, lpUserId, &sUserId, true);
  3194. if (hr != hrSuccess)
  3195. goto exitm;
  3196. START_SOAP_CALL
  3197. {
  3198. if(SOAP_OK != m_lpCmd->ns__GetQuotaStatus(m_ecSessionId, ABEID_ID(lpUserId), sUserId, &sResponse))
  3199. er = KCERR_NETWORK_ERROR;
  3200. else
  3201. er = (ECRESULT) sResponse.er;
  3202. }
  3203. END_SOAP_CALL
  3204. er = ECAllocateBuffer(sizeof(ECQUOTASTATUS), reinterpret_cast<void **>(&lpsQuotaStatus));
  3205. if (er != erSuccess)
  3206. goto exitm;
  3207. lpsQuotaStatus->llStoreSize = sResponse.llStoreSize;
  3208. lpsQuotaStatus->quotaStatus = (eQuotaStatus)sResponse.ulQuotaStatus;
  3209. *lppsQuotaStatus = lpsQuotaStatus;
  3210. exitm:
  3211. UnLockSoap();
  3212. return hr;
  3213. }
  3214. HRESULT WSTransport::HrPurgeSoftDelete(ULONG ulDays)
  3215. {
  3216. HRESULT hr = hrSuccess;
  3217. ECRESULT er = erSuccess;
  3218. LockSoap();
  3219. START_SOAP_CALL
  3220. {
  3221. if(SOAP_OK != m_lpCmd->ns__purgeSoftDelete(m_ecSessionId, ulDays, &er))
  3222. er = KCERR_NETWORK_ERROR;
  3223. }
  3224. END_SOAP_CALL
  3225. exitm:
  3226. UnLockSoap();
  3227. return hr;
  3228. }
  3229. HRESULT WSTransport::HrPurgeCache(ULONG ulFlags)
  3230. {
  3231. HRESULT hr = hrSuccess;
  3232. ECRESULT er = erSuccess;
  3233. LockSoap();
  3234. START_SOAP_CALL
  3235. {
  3236. if(SOAP_OK != m_lpCmd->ns__purgeCache(m_ecSessionId, ulFlags, &er))
  3237. er = KCERR_NETWORK_ERROR;
  3238. }
  3239. END_SOAP_CALL
  3240. exitm:
  3241. UnLockSoap();
  3242. return hr;
  3243. }
  3244. HRESULT WSTransport::HrPurgeDeferredUpdates(ULONG *lpulRemaining)
  3245. {
  3246. HRESULT hr = hrSuccess;
  3247. ECRESULT er = erSuccess;
  3248. struct purgeDeferredUpdatesResponse sResponse;
  3249. LockSoap();
  3250. START_SOAP_CALL
  3251. {
  3252. if(SOAP_OK != m_lpCmd->ns__purgeDeferredUpdates(m_ecSessionId, &sResponse))
  3253. er = KCERR_NETWORK_ERROR;
  3254. else
  3255. er = sResponse.er;
  3256. *lpulRemaining = sResponse.ulDeferredRemaining;
  3257. }
  3258. END_SOAP_CALL
  3259. exitm:
  3260. UnLockSoap();
  3261. return hr;
  3262. }
  3263. HRESULT WSTransport::HrResolvePseudoUrl(const char *lpszPseudoUrl, char **lppszServerPath, bool *lpbIsPeer)
  3264. {
  3265. ECRESULT er = erSuccess;
  3266. HRESULT hr = hrSuccess;
  3267. struct resolvePseudoUrlResponse sResponse{__gszeroinit};
  3268. char *lpszServerPath = NULL;
  3269. unsigned int ulLen = 0;
  3270. ECsResolveResult *lpCachedResult = NULL;
  3271. ECsResolveResult cachedResult;
  3272. if (lpszPseudoUrl == NULL || lppszServerPath == NULL)
  3273. return MAPI_E_INVALID_PARAMETER;
  3274. // First try the cache
  3275. ulock_rec l_cache(m_ResolveResultCacheMutex);
  3276. er = m_ResolveResultCache.GetCacheItem(lpszPseudoUrl, &lpCachedResult);
  3277. if (er == erSuccess) {
  3278. hr = lpCachedResult->hr;
  3279. if (hr == hrSuccess) {
  3280. ulLen = lpCachedResult->serverPath.length() + 1;
  3281. hr = ECAllocateBuffer(ulLen, (void**)&lpszServerPath);
  3282. if (hr == hrSuccess) {
  3283. memcpy(lpszServerPath, lpCachedResult->serverPath.c_str(), ulLen);
  3284. *lppszServerPath = lpszServerPath;
  3285. *lpbIsPeer = lpCachedResult->isPeer;
  3286. }
  3287. }
  3288. return hr; // Early exit
  3289. }
  3290. l_cache.unlock();
  3291. // Cache failed. Try the server
  3292. LockSoap();
  3293. START_SOAP_CALL
  3294. {
  3295. if(SOAP_OK != m_lpCmd->ns__resolvePseudoUrl(m_ecSessionId, (char*)lpszPseudoUrl, &sResponse))
  3296. er = KCERR_NETWORK_ERROR;
  3297. else
  3298. er = (ECRESULT)sResponse.er;
  3299. }
  3300. END_SOAP_CALL
  3301. cachedResult.hr = hr;
  3302. if (hr == hrSuccess) {
  3303. cachedResult.isPeer = sResponse.bIsPeer;
  3304. cachedResult.serverPath = sResponse.lpszServerPath;
  3305. }
  3306. {
  3307. scoped_rlock lock(m_ResolveResultCacheMutex);
  3308. m_ResolveResultCache.AddCacheItem(lpszPseudoUrl, cachedResult);
  3309. }
  3310. ulLen = strlen(sResponse.lpszServerPath) + 1;
  3311. hr = ECAllocateBuffer(ulLen, (void**)&lpszServerPath);
  3312. if (hr != hrSuccess)
  3313. goto exitm;
  3314. memcpy(lpszServerPath, sResponse.lpszServerPath, ulLen);
  3315. *lppszServerPath = lpszServerPath;
  3316. *lpbIsPeer = sResponse.bIsPeer;
  3317. exitm:
  3318. UnLockSoap();
  3319. return hr;
  3320. }
  3321. HRESULT WSTransport::HrGetServerDetails(ECSVRNAMELIST *lpServerNameList,
  3322. ULONG ulFlags, ECSERVERLIST **lppsServerList)
  3323. {
  3324. ECRESULT er = erSuccess;
  3325. HRESULT hr = hrSuccess;
  3326. struct getServerDetailsResponse sResponse{__gszeroinit};
  3327. ecmem_ptr<struct mv_string8> lpsSvrNameList;
  3328. LockSoap();
  3329. if (lpServerNameList == NULL || lppsServerList == NULL)
  3330. {
  3331. hr = MAPI_E_INVALID_PARAMETER;
  3332. goto exitm;
  3333. }
  3334. hr = SvrNameListToSoapMvString8(lpServerNameList, ulFlags & MAPI_UNICODE, &~lpsSvrNameList);
  3335. if (hr != hrSuccess)
  3336. goto exitm;
  3337. START_SOAP_CALL
  3338. {
  3339. if( SOAP_OK != m_lpCmd->ns__getServerDetails(m_ecSessionId, *lpsSvrNameList, ulFlags & ~MAPI_UNICODE, &sResponse))
  3340. er = KCERR_NETWORK_ERROR;
  3341. else
  3342. er = (ECRESULT)sResponse.er;
  3343. }
  3344. END_SOAP_CALL
  3345. hr = SoapServerListToServerList(&sResponse.sServerList, ulFlags & MAPI_UNICODE, lppsServerList);
  3346. if (hr != hrSuccess)
  3347. goto exitm;
  3348. exitm:
  3349. UnLockSoap();
  3350. return hr;
  3351. }
  3352. HRESULT WSTransport::HrGetChanges(const std::string& sourcekey, ULONG ulSyncId, ULONG ulChangeId, ULONG ulSyncType, ULONG ulFlags, LPSRestriction lpsRestrict, ULONG *lpulMaxChangeId, ULONG* lpcChanges, ICSCHANGE **lppChanges){
  3353. HRESULT hr = hrSuccess;
  3354. ECRESULT er = erSuccess;
  3355. struct icsChangeResponse sResponse;
  3356. ecmem_ptr<ICSCHANGE> lpChanges;
  3357. struct xsd__base64Binary sSourceKey;
  3358. struct restrictTable *lpsSoapRestrict = NULL;
  3359. sSourceKey.__ptr = (unsigned char *)sourcekey.c_str();
  3360. sSourceKey.__size = sourcekey.size();
  3361. LockSoap();
  3362. if(lpsRestrict) {
  3363. hr = CopyMAPIRestrictionToSOAPRestriction(&lpsSoapRestrict, lpsRestrict);
  3364. if(hr != hrSuccess)
  3365. goto exitm;
  3366. }
  3367. START_SOAP_CALL
  3368. {
  3369. if(SOAP_OK != m_lpCmd->ns__getChanges(m_ecSessionId, sSourceKey, ulSyncId, ulChangeId, ulSyncType, ulFlags, lpsSoapRestrict, &sResponse))
  3370. er = KCERR_NETWORK_ERROR;
  3371. else
  3372. er = (ECRESULT) sResponse.er;
  3373. }
  3374. END_SOAP_CALL
  3375. er = ECAllocateBuffer(sResponse.sChangesArray.__size * sizeof(ICSCHANGE), &~lpChanges);
  3376. if (er != erSuccess)
  3377. goto exitm;
  3378. for (gsoap_size_t i = 0; i < sResponse.sChangesArray.__size; ++i) {
  3379. lpChanges[i].ulChangeId = sResponse.sChangesArray.__ptr[i].ulChangeId;
  3380. lpChanges[i].ulChangeType = sResponse.sChangesArray.__ptr[i].ulChangeType;
  3381. lpChanges[i].ulFlags = sResponse.sChangesArray.__ptr[i].ulFlags;
  3382. if(sResponse.sChangesArray.__ptr[i].sSourceKey.__size > 0) {
  3383. er = ECAllocateMore(sResponse.sChangesArray.__ptr[i].sSourceKey.__size,
  3384. lpChanges, reinterpret_cast<void **>(&lpChanges[i].sSourceKey.lpb));
  3385. if (er != erSuccess)
  3386. goto exitm;
  3387. lpChanges[i].sSourceKey.cb = sResponse.sChangesArray.__ptr[i].sSourceKey.__size;
  3388. memcpy(lpChanges[i].sSourceKey.lpb, sResponse.sChangesArray.__ptr[i].sSourceKey.__ptr, sResponse.sChangesArray.__ptr[i].sSourceKey.__size);
  3389. }
  3390. if(sResponse.sChangesArray.__ptr[i].sParentSourceKey.__size > 0) {
  3391. er = ECAllocateMore( sResponse.sChangesArray.__ptr[i].sParentSourceKey.__size,
  3392. lpChanges, reinterpret_cast<void **>(&lpChanges[i].sParentSourceKey.lpb));
  3393. if (er != erSuccess)
  3394. goto exitm;
  3395. lpChanges[i].sParentSourceKey.cb = sResponse.sChangesArray.__ptr[i].sParentSourceKey.__size;
  3396. memcpy(lpChanges[i].sParentSourceKey.lpb, sResponse.sChangesArray.__ptr[i].sParentSourceKey.__ptr, sResponse.sChangesArray.__ptr[i].sParentSourceKey.__size);
  3397. }
  3398. }
  3399. *lpulMaxChangeId = sResponse.ulMaxChangeId;
  3400. *lpcChanges = sResponse.sChangesArray.__size;
  3401. *lppChanges = lpChanges.release();
  3402. exitm:
  3403. UnLockSoap();
  3404. if(lpsSoapRestrict)
  3405. FreeRestrictTable(lpsSoapRestrict);
  3406. return hr;
  3407. }
  3408. HRESULT WSTransport::HrSetSyncStatus(const std::string& sourcekey, ULONG ulSyncId, ULONG ulChangeId, ULONG ulSyncType, ULONG ulFlags, ULONG* lpulSyncId){
  3409. HRESULT hr = hrSuccess;
  3410. ECRESULT er = erSuccess;
  3411. struct setSyncStatusResponse sResponse;
  3412. struct xsd__base64Binary sSourceKey;
  3413. sSourceKey.__size = sourcekey.size();
  3414. sSourceKey.__ptr = (unsigned char *)sourcekey.c_str();
  3415. LockSoap();
  3416. START_SOAP_CALL
  3417. {
  3418. if(SOAP_OK != m_lpCmd->ns__setSyncStatus(m_ecSessionId, sSourceKey, ulSyncId, ulChangeId, ulSyncType, ulFlags, &sResponse))
  3419. er = KCERR_NETWORK_ERROR;
  3420. else
  3421. er = (ECRESULT) sResponse.er;
  3422. }
  3423. END_SOAP_CALL
  3424. *lpulSyncId = sResponse.ulSyncId;
  3425. exitm:
  3426. UnLockSoap();
  3427. return hr;
  3428. }
  3429. HRESULT WSTransport::HrEntryIDFromSourceKey(ULONG cbStoreID, LPENTRYID lpStoreID, ULONG ulFolderSourceKeySize, BYTE * lpFolderSourceKey, ULONG ulMessageSourceKeySize, BYTE * lpMessageSourceKey, ULONG * lpcbEntryID, LPENTRYID * lppEntryID)
  3430. {
  3431. HRESULT hr = hrSuccess;
  3432. ECRESULT er = erSuccess;
  3433. entryId sStoreId;
  3434. ecmem_ptr<ENTRYID> lpUnWrapStoreID;
  3435. ULONG cbUnWrapStoreID = 0;
  3436. struct xsd__base64Binary folderSourceKey;
  3437. struct xsd__base64Binary messageSourceKey;
  3438. struct getEntryIDFromSourceKeyResponse sResponse;
  3439. LockSoap();
  3440. if(ulFolderSourceKeySize == 0 || lpFolderSourceKey == NULL){
  3441. hr = MAPI_E_INVALID_PARAMETER;
  3442. goto exitm;
  3443. }
  3444. hr = UnWrapServerClientStoreEntry(cbStoreID, lpStoreID, &cbUnWrapStoreID, &~lpUnWrapStoreID);
  3445. if(hr != hrSuccess)
  3446. goto exitm;
  3447. sStoreId.__ptr = reinterpret_cast<unsigned char *>(lpUnWrapStoreID.get());
  3448. sStoreId.__size = cbUnWrapStoreID;
  3449. folderSourceKey.__size = ulFolderSourceKeySize;
  3450. folderSourceKey.__ptr = lpFolderSourceKey;
  3451. messageSourceKey.__size = ulMessageSourceKeySize; // can be zero
  3452. messageSourceKey.__ptr = lpMessageSourceKey;
  3453. START_SOAP_CALL
  3454. {
  3455. if(SOAP_OK != m_lpCmd->ns__getEntryIDFromSourceKey(m_ecSessionId, sStoreId, folderSourceKey, messageSourceKey, &sResponse))
  3456. er = KCERR_NETWORK_ERROR;
  3457. else
  3458. er = (ECRESULT) sResponse.er;
  3459. }
  3460. END_SOAP_CALL
  3461. hr = CopySOAPEntryIdToMAPIEntryId(&sResponse.sEntryId, lpcbEntryID, lppEntryID, NULL);
  3462. if(hr != hrSuccess)
  3463. goto exitm;
  3464. exitm:
  3465. UnLockSoap();
  3466. return hr;
  3467. }
  3468. HRESULT WSTransport::HrGetSyncStates(const ECLISTSYNCID &lstSyncId, ECLISTSYNCSTATE *lplstSyncState)
  3469. {
  3470. HRESULT hr = hrSuccess;
  3471. ECRESULT er = erSuccess;
  3472. mv_long ulaSyncId = {0};
  3473. getSyncStatesReponse sResponse{__gszeroinit};
  3474. SSyncState sSyncState = {0};
  3475. assert(lplstSyncState != NULL);
  3476. LockSoap();
  3477. if (lstSyncId.empty())
  3478. goto exitm;
  3479. ulaSyncId.__ptr = s_alloc<unsigned int>(nullptr, lstSyncId.size());
  3480. for (auto sync_id : lstSyncId)
  3481. ulaSyncId.__ptr[ulaSyncId.__size++] = sync_id;
  3482. START_SOAP_CALL
  3483. {
  3484. if(SOAP_OK != m_lpCmd->ns__getSyncStates(m_ecSessionId, ulaSyncId, &sResponse))
  3485. er = KCERR_NETWORK_ERROR;
  3486. else
  3487. er = (ECRESULT) sResponse.er;
  3488. }
  3489. END_SOAP_CALL
  3490. for (gsoap_size_t i = 0; i < sResponse.sSyncStates.__size; ++i) {
  3491. sSyncState.ulSyncId = sResponse.sSyncStates.__ptr[i].ulSyncId;
  3492. sSyncState.ulChangeId = sResponse.sSyncStates.__ptr[i].ulChangeId;
  3493. lplstSyncState->push_back(sSyncState);
  3494. }
  3495. exitm:
  3496. UnLockSoap();
  3497. s_free(nullptr, ulaSyncId.__ptr);
  3498. return hr;
  3499. }
  3500. const char* WSTransport::GetServerName()
  3501. {
  3502. return m_sProfileProps.strServerPath.c_str();
  3503. }
  3504. bool WSTransport::IsConnected()
  3505. {
  3506. return m_lpCmd != NULL;
  3507. }
  3508. HRESULT WSTransport::HrOpenMultiStoreTable(LPENTRYLIST lpMsgList, ULONG ulFlags, ULONG cbEntryID, LPENTRYID lpEntryID, ECMsgStore *lpMsgStore, WSTableView **lppTableView)
  3509. {
  3510. HRESULT hr = hrSuccess;
  3511. object_ptr<WSTableMultiStore> lpMultiStoreTable;
  3512. if (lpMsgList == nullptr || lpMsgList->cValues == 0)
  3513. return MAPI_E_INVALID_PARAMETER;
  3514. hr = WSTableMultiStore::Create(ulFlags, m_lpCmd, m_hDataLock,
  3515. m_ecSessionId, cbEntryID, lpEntryID, lpMsgStore, this,
  3516. &~lpMultiStoreTable);
  3517. if (hr != hrSuccess)
  3518. return hr;
  3519. hr = lpMultiStoreTable->HrSetEntryIDs(lpMsgList);
  3520. if (hr != hrSuccess)
  3521. return hr;
  3522. return lpMultiStoreTable->QueryInterface(IID_ECTableView,
  3523. reinterpret_cast<void **>(lppTableView));
  3524. }
  3525. HRESULT WSTransport::HrOpenMiscTable(ULONG ulTableType, ULONG ulFlags, ULONG cbEntryID, LPENTRYID lpEntryID, ECMsgStore *lpMsgStore, WSTableView **lppTableView)
  3526. {
  3527. HRESULT hr = hrSuccess;
  3528. object_ptr<WSTableMisc> lpMiscTable;
  3529. if (ulTableType != TABLETYPE_STATS_SYSTEM && ulTableType != TABLETYPE_STATS_SESSIONS &&
  3530. ulTableType != TABLETYPE_STATS_USERS && ulTableType != TABLETYPE_STATS_COMPANY &&
  3531. ulTableType != TABLETYPE_USERSTORES && ulTableType != TABLETYPE_STATS_SERVERS)
  3532. return MAPI_E_INVALID_PARAMETER;
  3533. hr = WSTableMisc::Create(ulTableType, ulFlags, m_lpCmd, m_hDataLock,
  3534. m_ecSessionId, cbEntryID, lpEntryID, lpMsgStore, this,
  3535. &~lpMiscTable);
  3536. if (hr != hrSuccess)
  3537. return hr;
  3538. return lpMiscTable->QueryInterface(IID_ECTableView,
  3539. reinterpret_cast<void **>(lppTableView));
  3540. }
  3541. HRESULT WSTransport::HrSetLockState(ULONG cbEntryID, LPENTRYID lpEntryID, bool bLocked)
  3542. {
  3543. HRESULT hr = hrSuccess;
  3544. ECRESULT er = erSuccess;
  3545. entryId eidMessage;
  3546. if ((m_ulServerCapabilities & KOPANO_CAP_MSGLOCK) == 0)
  3547. return hrSuccess;
  3548. LockSoap();
  3549. hr = CopyMAPIEntryIdToSOAPEntryId(cbEntryID, lpEntryID, &eidMessage, true);
  3550. if (hr != hrSuccess)
  3551. goto exitm;
  3552. START_SOAP_CALL
  3553. {
  3554. if (SOAP_OK != m_lpCmd->ns__setLockState(m_ecSessionId, eidMessage, bLocked, &er))
  3555. er = KCERR_NETWORK_ERROR;
  3556. /* else: er is already set and good to use */
  3557. }
  3558. END_SOAP_CALL
  3559. exitm:
  3560. UnLockSoap();
  3561. return hr;
  3562. }
  3563. HRESULT WSTransport::HrCheckCapabilityFlags(ULONG ulFlags, BOOL *lpbResult)
  3564. {
  3565. if (lpbResult == NULL)
  3566. return MAPI_E_INVALID_PARAMETER;
  3567. *lpbResult = ((m_ulServerCapabilities & ulFlags) == ulFlags) ? TRUE : FALSE;
  3568. return hrSuccess;
  3569. }
  3570. HRESULT WSTransport::HrLicenseAuth(unsigned char *lpData, unsigned int ulSize, unsigned char **lppResponseData, unsigned int *lpulSize)
  3571. {
  3572. HRESULT hr = hrSuccess;
  3573. ECRESULT er = erSuccess;
  3574. struct getLicenseAuthResponse sResponse;
  3575. struct xsd__base64Binary sData;
  3576. sData.__ptr = lpData;
  3577. sData.__size = ulSize;
  3578. LockSoap();
  3579. START_SOAP_CALL
  3580. {
  3581. if(SOAP_OK != m_lpCmd->ns__getLicenseAuth(m_ecSessionId, sData, &sResponse))
  3582. er = KCERR_NETWORK_ERROR;
  3583. else
  3584. er = sResponse.er;
  3585. }
  3586. END_SOAP_CALL
  3587. hr = MAPIAllocateBuffer(sResponse.sAuthResponse.__size, (void **) lppResponseData);
  3588. if(hr != hrSuccess)
  3589. goto exitm;
  3590. memcpy(*lppResponseData, sResponse.sAuthResponse.__ptr, sResponse.sAuthResponse.__size);
  3591. *lpulSize = sResponse.sAuthResponse.__size;
  3592. exitm:
  3593. UnLockSoap();
  3594. return hr;
  3595. }
  3596. HRESULT WSTransport::HrLicenseCapa(unsigned int ulServiceType, char ***lppszCapas, unsigned int * lpulSize)
  3597. {
  3598. HRESULT hr = hrSuccess;
  3599. ECRESULT er = erSuccess;
  3600. struct getLicenseCapaResponse sResponse;
  3601. char **lpszCapas = NULL;
  3602. LockSoap();
  3603. START_SOAP_CALL
  3604. {
  3605. if(SOAP_OK != m_lpCmd->ns__getLicenseCapa(m_ecSessionId, ulServiceType, &sResponse))
  3606. er = KCERR_NETWORK_ERROR;
  3607. else
  3608. er = sResponse.er;
  3609. }
  3610. END_SOAP_CALL
  3611. hr = MAPIAllocateBuffer(sResponse.sCapabilities.__size * sizeof(char *), (void **)&lpszCapas);
  3612. if(hr != hrSuccess)
  3613. goto exitm;
  3614. for (gsoap_size_t i = 0; i < sResponse.sCapabilities.__size; ++i) {
  3615. if ((hr = MAPIAllocateMore(strlen(sResponse.sCapabilities.__ptr[i])+1, lpszCapas, (void **) &lpszCapas[i])) != hrSuccess)
  3616. goto exitm;
  3617. strcpy(lpszCapas[i], sResponse.sCapabilities.__ptr[i]);
  3618. }
  3619. *lppszCapas = lpszCapas;
  3620. *lpulSize = sResponse.sCapabilities.__size;
  3621. exitm:
  3622. UnLockSoap();
  3623. return hr;
  3624. }
  3625. HRESULT WSTransport::HrLicenseUsers(unsigned int ulServiceType, unsigned int *lpulUsers)
  3626. {
  3627. HRESULT hr = hrSuccess;
  3628. ECRESULT er = erSuccess;
  3629. struct getLicenseUsersResponse sResponse;
  3630. LockSoap();
  3631. START_SOAP_CALL
  3632. {
  3633. if(SOAP_OK != m_lpCmd->ns__getLicenseUsers(m_ecSessionId, ulServiceType, &sResponse))
  3634. er = KCERR_NETWORK_ERROR;
  3635. else
  3636. er = sResponse.er;
  3637. }
  3638. END_SOAP_CALL
  3639. *lpulUsers = sResponse.ulUsers;
  3640. exitm:
  3641. UnLockSoap();
  3642. return hr;
  3643. }
  3644. HRESULT WSTransport::HrTestPerform(const char *szCommand, unsigned int ulArgs,
  3645. char **lpszArgs)
  3646. {
  3647. HRESULT hr = hrSuccess;
  3648. ECRESULT er = erSuccess;
  3649. struct testPerformArgs sTestPerform;
  3650. sTestPerform.__size = ulArgs;
  3651. sTestPerform.__ptr = lpszArgs;
  3652. LockSoap();
  3653. START_SOAP_CALL
  3654. {
  3655. if(SOAP_OK != m_lpCmd->ns__testPerform(m_ecSessionId, szCommand, sTestPerform, &er))
  3656. er = KCERR_NETWORK_ERROR;
  3657. }
  3658. END_SOAP_CALL;
  3659. exitm:
  3660. UnLockSoap();
  3661. return hr;
  3662. }
  3663. HRESULT WSTransport::HrTestSet(const char *szName, const char *szValue)
  3664. {
  3665. HRESULT hr = hrSuccess;
  3666. ECRESULT er = erSuccess;
  3667. LockSoap();
  3668. START_SOAP_CALL
  3669. {
  3670. if (m_lpCmd->ns__testSet(m_ecSessionId, const_cast<char *>(szName),
  3671. const_cast<char *>(szValue), &er) != SOAP_OK)
  3672. er = KCERR_NETWORK_ERROR;
  3673. }
  3674. END_SOAP_CALL
  3675. exitm:
  3676. UnLockSoap();
  3677. return hr;
  3678. }
  3679. HRESULT WSTransport::HrTestGet(const char *szName, char **lpszValue)
  3680. {
  3681. HRESULT hr = hrSuccess;
  3682. ECRESULT er = erSuccess;
  3683. char *szValue = NULL;
  3684. struct testGetResponse sResponse;
  3685. LockSoap();
  3686. START_SOAP_CALL
  3687. {
  3688. if (m_lpCmd->ns__testGet(m_ecSessionId,
  3689. const_cast<char *>(szName), &sResponse) != SOAP_OK)
  3690. er = KCERR_NETWORK_ERROR;
  3691. else
  3692. er = sResponse.er;
  3693. }
  3694. END_SOAP_CALL
  3695. hr = MAPIAllocateBuffer(strlen(sResponse.szValue)+1, (void **)&szValue);
  3696. if(hr != hrSuccess)
  3697. goto exitm;
  3698. strcpy(szValue, sResponse.szValue);
  3699. *lpszValue = szValue;
  3700. exitm:
  3701. UnLockSoap();
  3702. return hr;
  3703. }
  3704. HRESULT WSTransport::HrGetSessionId(ECSESSIONID *lpSessionId, ECSESSIONGROUPID *lpSessionGroupId)
  3705. {
  3706. HRESULT hr = hrSuccess;
  3707. if (lpSessionId)
  3708. *lpSessionId = m_ecSessionId;
  3709. if (lpSessionGroupId)
  3710. *lpSessionGroupId = m_ecSessionGroupId;
  3711. return hr;
  3712. }
  3713. sGlobalProfileProps WSTransport::GetProfileProps()
  3714. {
  3715. return m_sProfileProps;
  3716. }
  3717. HRESULT WSTransport::GetLicenseFlags(unsigned long long *lpllFlags)
  3718. {
  3719. *lpllFlags = m_llFlags;
  3720. return hrSuccess;
  3721. }
  3722. HRESULT WSTransport::GetServerGUID(LPGUID lpsServerGuid)
  3723. {
  3724. if (m_sServerGuid == GUID_NULL)
  3725. return MAPI_E_NOT_FOUND;
  3726. *lpsServerGuid = m_sServerGuid;
  3727. return hrSuccess;
  3728. }
  3729. HRESULT WSTransport::AddSessionReloadCallback(void *lpParam, SESSIONRELOADCALLBACK callback, ULONG *lpulId)
  3730. {
  3731. SESSIONRELOADLIST::mapped_type data(lpParam, callback);
  3732. scoped_rlock lock(m_mutexSessionReload);
  3733. m_mapSessionReload[m_ulReloadId] = data;
  3734. if(lpulId)
  3735. *lpulId = m_ulReloadId;
  3736. ++m_ulReloadId;
  3737. return hrSuccess;
  3738. }
  3739. HRESULT WSTransport::RemoveSessionReloadCallback(ULONG ulId)
  3740. {
  3741. scoped_rlock lock(m_mutexSessionReload);
  3742. return m_mapSessionReload.erase(ulId) == 0 ? MAPI_E_NOT_FOUND : hrSuccess;
  3743. }
  3744. SOAP_SOCKET WSTransport::RefuseConnect(struct soap* soap, const char* endpoint, const char* host, int port)
  3745. {
  3746. soap->error = SOAP_TCP_ERROR;
  3747. return SOAP_ERR;
  3748. }
  3749. HRESULT WSTransport::HrCancelIO()
  3750. {
  3751. /* This looks like an ugly hack, but in practice it works very well: we want
  3752. * to make sure that no blocking call is running or will run in this class instance
  3753. * after HrCancelIO() returns.
  3754. *
  3755. * To do this, we first disable sending new requests by override the fsend() function
  3756. * in gSOAP. If a request was already started but still 'before' the fsend() call
  3757. * then the call will return directly after the fsend() because it will return an error.
  3758. * On the other hand, if fsend() has already been called, then the next blocking part
  3759. * will be the frecv() call. We therefore shutdown the socket here as well, so that
  3760. * any blocking recv() call will return with an error immediately.
  3761. *
  3762. * Please note though, that this last part (shutdown() on a socket will cause other threads
  3763. * with a blocking recv() on the socket to return with an error), is not 100% portable.
  3764. * Apparently (and this is untested), some UNIX variants don't return until some data
  3765. * is received on the socket. Bummer. It works in Linux though.
  3766. */
  3767. if (m_lpCmd == NULL || m_lpCmd->soap == NULL)
  3768. return hrSuccess;
  3769. // Override the SOAP connect (fopen) so that all new connections will fail with a network error
  3770. m_lpCmd->soap->fopen = WSTransport::RefuseConnect;
  3771. // If there is a socket currently open, close it now
  3772. int s = m_lpCmd->soap->socket;
  3773. if (s != SOAP_INVALID_SOCKET)
  3774. m_lpCmd->soap->fshutdownsocket(m_lpCmd->soap, (SOAP_SOCKET)s, 2);
  3775. return hrSuccess;
  3776. }
  3777. HRESULT WSTransport::HrGetNotify(struct notificationArray **lppsArrayNotifications)
  3778. {
  3779. HRESULT hr = hrSuccess;
  3780. ECRESULT er = erSuccess;
  3781. struct notifyResponse sNotifications;
  3782. LockSoap();
  3783. if(SOAP_OK != m_lpCmd->ns__notifyGetItems(m_ecSessionId, &sNotifications))
  3784. er = KCERR_NETWORK_ERROR;
  3785. else
  3786. er = sNotifications.er; // hrSuccess or KCWARN_KEEP_ALIVE only
  3787. hr = kcerr_to_mapierr(er);
  3788. if(hr != erSuccess)
  3789. goto exit;
  3790. if(sNotifications.pNotificationArray != NULL) {
  3791. *lppsArrayNotifications = s_alloc<notificationArray>(nullptr);
  3792. CopyNotificationArrayStruct(sNotifications.pNotificationArray, *lppsArrayNotifications);
  3793. }else
  3794. *lppsArrayNotifications = NULL;
  3795. exit:
  3796. UnLockSoap();
  3797. if(m_lpCmd->soap) {
  3798. soap_destroy(m_lpCmd->soap);
  3799. soap_end(m_lpCmd->soap);
  3800. }
  3801. return hr;
  3802. }
  3803. std::string WSTransport::GetAppName()
  3804. {
  3805. if (!m_strAppName.empty())
  3806. return m_strAppName;
  3807. std::string procpath = "/proc/" + stringify(getpid()) + "/cmdline";
  3808. std::string s;
  3809. std::ifstream in(procpath.c_str());
  3810. if (!getline(in, s))
  3811. m_strAppName = "<unknown>";
  3812. else
  3813. m_strAppName = basename((char *)s.c_str());
  3814. return m_strAppName;
  3815. }
  3816. /**
  3817. * Ensure that the session is still active
  3818. *
  3819. * This function simply calls a random transport request, which will check the session
  3820. * validity. Since it doesn't matter which call we run, we'll use the normally-disabled
  3821. * testGet function. Any failed session will automatically be reloaded by the autodetection
  3822. * code.
  3823. */
  3824. HRESULT WSTransport::HrEnsureSession()
  3825. {
  3826. HRESULT hr = hrSuccess;
  3827. memory_ptr<char> szValue;
  3828. hr = HrTestGet("ensure_transaction", &~szValue);
  3829. if(hr != MAPI_E_NETWORK_ERROR && hr != MAPI_E_END_OF_SESSION)
  3830. hr = hrSuccess;
  3831. return hr;
  3832. }
  3833. HRESULT WSTransport::HrResetFolderCount(ULONG cbEntryId, LPENTRYID lpEntryId, ULONG *lpulUpdates)
  3834. {
  3835. HRESULT hr = hrSuccess;
  3836. ECRESULT er = erSuccess;
  3837. entryId eidFolder;
  3838. resetFolderCountResponse sResponse{__gszeroinit};
  3839. LockSoap();
  3840. hr = CopyMAPIEntryIdToSOAPEntryId(cbEntryId, lpEntryId, &eidFolder, true);
  3841. if (hr != hrSuccess)
  3842. goto exitm;
  3843. START_SOAP_CALL
  3844. {
  3845. if (SOAP_OK != m_lpCmd->ns__resetFolderCount(m_ecSessionId, eidFolder, &sResponse))
  3846. er = KCERR_NETWORK_ERROR;
  3847. else
  3848. er = sResponse.er;
  3849. }
  3850. END_SOAP_CALL
  3851. if (lpulUpdates)
  3852. *lpulUpdates = sResponse.ulUpdates;
  3853. exitm:
  3854. UnLockSoap();
  3855. return hr;
  3856. }