main.cpp 214 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612
  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/ecversion.h>
  19. #include <memory>
  20. #include <new>
  21. #include <cstdio>
  22. #include <cstdlib>
  23. #include <syslog.h>
  24. #include <ctime>
  25. #include <kopano/ECConfig.h>
  26. #include <kopano/ECLogger.h>
  27. #include <kopano/mapi_ptr.h>
  28. #include <kopano/memory.hpp>
  29. #include <kopano/tie.hpp>
  30. #include <kopano/MAPIErrors.h>
  31. #include <ICalToMAPI.h>
  32. #include <MAPIToICal.h>
  33. #include <libicalmapi/mapitovcf.hpp>
  34. #include <libicalmapi/vcftomapi.hpp>
  35. #include "php-ext/phpconfig.h"
  36. #include "php-ext/ECRulesTableProxy.h"
  37. #define LOGFILE_PATH "/var/log/kopano"
  38. /*
  39. * Things to notice when reading/editing this source:
  40. *
  41. * - RETURN_... returns in the define, the rest of the function is skipped.
  42. * - RETVAL_... only sets the return value, the rest of the function is processed.
  43. *
  44. * - do not use E_ERROR as it cannot be fetched by the php script. Use E_WARNING.
  45. *
  46. * - do not create HRESULT variables, but use MAPI_G(hr) so the php script
  47. * can retrieve the value with mapi_last_hresult()
  48. *
  49. * - all internal functions need to pass TSRMLS_CC in the end, so win32 version compiles
  50. *
  51. * - when using "l" in zend_parse_parameters(), use 'long' (64-bit) as variable type, not ULONG (32-bit)
  52. * - when using "s" in zend_parse_parameters(), the string length is 32 bits, so use 'unsigned int' or 'ULONG'
  53. *
  54. */
  55. /*
  56. * Some information on objects, refcounts, and how PHP manages memory:
  57. *
  58. * Each ZVAL is allocated when doing MAKE_STD_ZVAL or INIT_ALLOC_ZVAL. These allocate the
  59. * space for the ZVAL struct and nothing else. When you put a value in it, INTs and other small
  60. * values are stored in the ZVAL itself. When you add a string, more memory is allocated
  61. * (eg through ZVAL_STRING()) to the ZVAL. Some goes for arrays and associated arrays.
  62. *
  63. * The data is freed by PHP by traversing the entire ZVAL and freeing each part of the ZVAL
  64. * it encounters. So, for an array or string ZVAL, it will be doing more frees than just the base
  65. * value. The freeing is done in zval_dtor().
  66. *
  67. * This system means that MAKE_STD_ZVAL(&zval); ZVAL_STRING(zval, "hello", 0); zval_dtor(zval) will
  68. * segfault. This is because it will try to free the "hello" string, which was not allocated by PHP.
  69. * So, always use the 'copy' flag when using constant strings (eg ZVAL_STRING(zval, "hello", 1)). This
  70. * wastes memory, but makes life a lot easier.
  71. *
  72. * There is also a referencing system in PHP that is basically the same as the AddRef() and Release()
  73. * COM scheme. When you MAKE_STD_ZVAL or ALLOC_INIT_ZVAL, the refcount is 1. You should then always
  74. * make sure that you never destroy the value with zval_dtor (directly calls the destructor and then
  75. * calls FREE_ZVAL) when somebody else *could* have a reference to it. Using zval_dtor on values that
  76. * users may have a reference to is a security hole. (see http://www.php-security.org/MOPB/MOPB-24-2007.html)
  77. * Although I think this should only happen when you're calling into PHP user space with call_user_function()
  78. *
  79. * What you *should* do is use zval_ptr_dtor(). This is not just the same as zval_dtor!!! It first decreases
  80. * the refcount, and *then* destroys the zval, but only if the refcount is 0. So zval_ptr_dtor is the
  81. * same as Release() in COM.
  82. *
  83. * This means that you should basically always use MAKE_STD_ZVAL and then zval_ptr_dtor(), and you
  84. * should always be safe. You can easily break things by calling ZVAL_DELREF() too many times. Worst thing is,
  85. * you won't notice that you've broken it until a while later in the PHP script ...
  86. *
  87. * We have one thing here which doesn't follow this pattern: some functions use RETVAL_ZVAL to copy the value
  88. * of one zval into the 'return_value' zval. Seen as we don't want to do a real copy and then a free, we use
  89. * RETVAL_ZVAL(val, 0, 0), specifying that the value of the zval should not be copied, but just referenced, and
  90. * we also specify 0 for the 'dtor' flag. This would cause PHP to destruct the old value, but the old value is
  91. * pointing at the same data als the return_value zval! So we want to release *only* the ZVAL itself, which we do
  92. * via FREE_ZVAL.
  93. *
  94. * I think.
  95. *
  96. * Steve
  97. *
  98. */
  99. /***************************************************************
  100. * PHP Includes
  101. ***************************************************************/
  102. // we need to include this in c++ space because php.h also includes it in
  103. // 'extern "C"'-space which doesn't work in win32
  104. #include <cmath>
  105. using namespace std;
  106. extern "C" {
  107. // Remove these defines to remove warnings
  108. #undef PACKAGE_VERSION
  109. #undef PACKAGE_TARNAME
  110. #undef PACKAGE_NAME
  111. #undef PACKAGE_STRING
  112. #undef PACKAGE_BUGREPORT
  113. #if !__GNUC_PREREQ(6,0)
  114. #define zend_isnan(a) std::isnan(a)
  115. #endif
  116. #include "php.h"
  117. #include "php_globals.h"
  118. #include "php_ini.h"
  119. #include "zend_exceptions.h"
  120. #include "ext/standard/info.h"
  121. #include "ext/standard/php_string.h"
  122. }
  123. // Destructor functions needed for the PHP resources.
  124. static void _php_free_mapi_session(zend_resource *rsrc TSRMLS_DC);
  125. static void _php_free_mapi_rowset(zend_resource *rsrc TSRMLS_DC);
  126. static void _php_free_mapi_object(zend_resource *rsrc TSRMLS_DC);
  127. static void _php_free_istream(zend_resource *rsrc TSRMLS_DC);
  128. static void _php_free_fb_object(zend_resource *rsrc TSRMLS_DC);
  129. // Not defined anymore in PHP 5.3.0
  130. // we only use first and fourth versions, so just define those.
  131. #if ZEND_MODULE_API_NO >= 20071006
  132. ZEND_BEGIN_ARG_INFO(first_arg_force_ref, 0)
  133. ZEND_ARG_PASS_INFO(1)
  134. ZEND_END_ARG_INFO()
  135. ZEND_BEGIN_ARG_INFO(fourth_arg_force_ref, 0)
  136. ZEND_ARG_PASS_INFO(0)
  137. ZEND_ARG_PASS_INFO(0)
  138. ZEND_ARG_PASS_INFO(0)
  139. ZEND_ARG_PASS_INFO(1)
  140. ZEND_END_ARG_INFO()
  141. #endif
  142. #define LOG_BEGIN() { \
  143. if (mapi_debug & 1) { \
  144. php_error_docref(NULL TSRMLS_CC, E_NOTICE, "[IN] %s", __FUNCTION__); \
  145. } \
  146. }
  147. #define LOG_END() { \
  148. if (mapi_debug & 2) { \
  149. HRESULT hrx = MAPI_G(hr); \
  150. php_error_docref(NULL TSRMLS_CC, E_NOTICE, "[OUT] %s hr=0x%08x", __FUNCTION__, hrx); \
  151. } \
  152. }
  153. #define ZEND_FETCH_RESOURCE_C(rsrc, rsrc_type, passed_id, default_id, resource_type_name, resource_type) \
  154. rsrc = (rsrc_type)zend_fetch_resource(Z_RES_P(*passed_id), resource_type_name, resource_type); \
  155. if (!rsrc) \
  156. RETURN_FALSE;
  157. #define ZEND_REGISTER_RESOURCE(return_value, lpMAPISession, le_mapi_session) \
  158. ZVAL_RES(return_value, zend_register_resource(lpMAPISession, le_mapi_session));
  159. #define UOBJ_REGISTER_RESOURCE(rv, obj, categ) \
  160. ZVAL_RES(rv, zend_register_resource(static_cast<IUnknown *>(obj), (categ)));
  161. // A very, very nice PHP #define that causes link errors in MAPI when you have multiple
  162. // files referencing MAPI....
  163. #undef inline
  164. /***************************************************************
  165. * MAPI Includes
  166. ***************************************************************/
  167. #include <mapi.h>
  168. #include <mapix.h>
  169. #include <mapiutil.h>
  170. #include <mapispi.h>
  171. #include <mapitags.h>
  172. #include <mapidefs.h>
  173. #include <kopano/IECServiceAdmin.h>
  174. #include <kopano/IECSecurity.h>
  175. #include <kopano/IECUnknown.h>
  176. #include "IECExportChanges.h"
  177. #include "IECMultiStoreTable.h"
  178. #include <kopano/IECLicense.h>
  179. #include <kopano/ECTags.h>
  180. #include <kopano/ECDefs.h>
  181. #define USES_IID_IMAPIProp
  182. #define USES_IID_IMAPIContainer
  183. #define USES_IID_IMsgStore
  184. #define USES_IID_IMessage
  185. #define USES_IID_IExchangeManageStore
  186. #define USES_IID_IECExportChanges
  187. #include <string>
  188. #include "php-ext/util.h"
  189. #include "rtfutil.h"
  190. #include <kopano/CommonUtil.h>
  191. #include "ECImportContentsChangesProxy.h"
  192. #include "ECImportHierarchyChangesProxy.h"
  193. #include "ECMemStream.h"
  194. #include <inetmapi/inetmapi.h>
  195. #include <inetmapi/options.h>
  196. #include <edkmdb.h>
  197. #include <mapiguid.h>
  198. #include <kopano/ECGuid.h>
  199. #include <edkguid.h>
  200. //Freebusy includes
  201. #include "ECFreeBusySupport.h"
  202. #include "favoritesutil.h"
  203. // at last, the php-plugin extension headers
  204. #include "main.h"
  205. #include "typeconversion.h"
  206. #include "MAPINotifSink.h"
  207. #include <kopano/charset/convert.h>
  208. #include <kopano/charset/utf8string.h>
  209. #include "charset/localeutil.h"
  210. #define PMEASURE_FUNC pmeasure __pmobject(__PRETTY_FUNCTION__);
  211. using namespace KCHL;
  212. class pmeasure {
  213. public:
  214. pmeasure(const std::string &);
  215. ~pmeasure(void);
  216. private:
  217. std::string what;
  218. unsigned long long start_ts = 0;
  219. };
  220. using namespace std;
  221. static ECLogger *lpLogger = NULL;
  222. #define MAPI_ASSERT_EX
  223. static unsigned int mapi_debug;
  224. static char *perf_measure_file;
  225. pmeasure::pmeasure(const std::string &whatIn)
  226. {
  227. if (perf_measure_file == NULL || *perf_measure_file == '\0')
  228. return;
  229. what = whatIn;
  230. struct timespec ts;
  231. clock_gettime(CLOCK_MONOTONIC, &ts);
  232. start_ts = ts.tv_sec * 1000 * 1000 + ts.tv_nsec / 1000;
  233. }
  234. pmeasure::~pmeasure(void)
  235. {
  236. if (perf_measure_file == NULL || *perf_measure_file == '\0')
  237. return;
  238. struct timespec ts;
  239. clock_gettime(CLOCK_MONOTONIC, &ts);
  240. FILE *fh = fopen(perf_measure_file, "a+");
  241. if (fh == NULL) {
  242. if (lpLogger != NULL)
  243. lpLogger->Log(EC_LOGLEVEL_ERROR, "~pmeasure: cannot open \"%s\": %s", perf_measure_file, strerror(errno));
  244. return;
  245. }
  246. unsigned long long int now = ts.tv_sec * 1000 * 1000 + ts.tv_nsec / 1000;
  247. unsigned long long int tdiff = now - start_ts;
  248. fprintf(fh, "%lld %s\n", tdiff, what.c_str());
  249. fclose(fh);
  250. }
  251. /* function list so that the Zend engine will know what's here */
  252. zend_function_entry mapi_functions[] =
  253. {
  254. ZEND_FE(mapi_last_hresult, NULL)
  255. ZEND_FE(mapi_prop_type, NULL)
  256. ZEND_FE(mapi_prop_id, NULL)
  257. ZEND_FE(mapi_is_error, NULL)
  258. ZEND_FE(mapi_make_scode, NULL)
  259. ZEND_FE(mapi_prop_tag, NULL)
  260. ZEND_FE(mapi_createoneoff, NULL)
  261. ZEND_FE(mapi_parseoneoff, NULL)
  262. ZEND_FE(mapi_logon, NULL)
  263. ZEND_FE(mapi_logon_zarafa, NULL)
  264. ZEND_FE(mapi_getmsgstorestable, NULL)
  265. ZEND_FE(mapi_openmsgstore, NULL)
  266. ZEND_FE(mapi_openprofilesection, NULL)
  267. ZEND_FE(mapi_openaddressbook, NULL)
  268. ZEND_FE(mapi_openentry, NULL)
  269. ZEND_FE(mapi_ab_openentry, NULL)
  270. // TODO: add other functions for le_mapi_mailuser and le_mapi_distlist
  271. ZEND_FE(mapi_ab_resolvename, NULL)
  272. ZEND_FE(mapi_ab_getdefaultdir, NULL)
  273. ZEND_FE(mapi_msgstore_createentryid, NULL)
  274. ZEND_FE(mapi_msgstore_getarchiveentryid, NULL)
  275. ZEND_FE(mapi_msgstore_openentry, NULL)
  276. ZEND_FE(mapi_msgstore_getreceivefolder, NULL)
  277. ZEND_FE(mapi_msgstore_entryidfromsourcekey, NULL)
  278. ZEND_FE(mapi_msgstore_openmultistoretable, NULL)
  279. ZEND_FE(mapi_msgstore_advise, NULL)
  280. ZEND_FE(mapi_msgstore_unadvise, NULL)
  281. ZEND_FE(mapi_sink_create, NULL)
  282. ZEND_FE(mapi_sink_timedwait, NULL)
  283. ZEND_FE(mapi_table_queryallrows, NULL)
  284. ZEND_FE(mapi_table_queryrows, NULL)
  285. ZEND_FE(mapi_table_getrowcount, NULL)
  286. ZEND_FE(mapi_table_setcolumns, NULL)
  287. ZEND_FE(mapi_table_seekrow, NULL)
  288. ZEND_FE(mapi_table_sort, NULL)
  289. ZEND_FE(mapi_table_restrict, NULL)
  290. ZEND_FE(mapi_table_findrow, NULL)
  291. ZEND_FE(mapi_table_createbookmark, NULL)
  292. ZEND_FE(mapi_table_freebookmark, NULL)
  293. ZEND_FE(mapi_folder_gethierarchytable, NULL)
  294. ZEND_FE(mapi_folder_getcontentstable, NULL)
  295. ZEND_FE(mapi_folder_createmessage, NULL)
  296. ZEND_FE(mapi_folder_createfolder, NULL)
  297. ZEND_FE(mapi_folder_deletemessages, NULL)
  298. ZEND_FE(mapi_folder_copymessages, NULL)
  299. ZEND_FE(mapi_folder_emptyfolder, NULL)
  300. ZEND_FE(mapi_folder_copyfolder, NULL)
  301. ZEND_FE(mapi_folder_deletefolder, NULL)
  302. ZEND_FE(mapi_folder_setreadflags, NULL)
  303. ZEND_FE(mapi_folder_openmodifytable, NULL)
  304. ZEND_FE(mapi_folder_setsearchcriteria, NULL)
  305. ZEND_FE(mapi_folder_getsearchcriteria, NULL)
  306. ZEND_FE(mapi_message_getattachmenttable, NULL)
  307. ZEND_FE(mapi_message_getrecipienttable, NULL)
  308. ZEND_FE(mapi_message_openattach, NULL)
  309. ZEND_FE(mapi_message_createattach, NULL)
  310. ZEND_FE(mapi_message_deleteattach, NULL)
  311. ZEND_FE(mapi_message_modifyrecipients, NULL)
  312. ZEND_FE(mapi_message_submitmessage, NULL)
  313. ZEND_FE(mapi_message_setreadflag, NULL)
  314. ZEND_FE(mapi_openpropertytostream, NULL)
  315. ZEND_FE(mapi_stream_write, NULL)
  316. ZEND_FE(mapi_stream_read, NULL)
  317. ZEND_FE(mapi_stream_stat, NULL)
  318. ZEND_FE(mapi_stream_seek, NULL)
  319. ZEND_FE(mapi_stream_commit, NULL)
  320. ZEND_FE(mapi_stream_setsize, NULL)
  321. ZEND_FE(mapi_stream_create, NULL)
  322. ZEND_FE(mapi_attach_openobj, NULL)
  323. ZEND_FE(mapi_savechanges, NULL)
  324. ZEND_FE(mapi_getprops, NULL)
  325. ZEND_FE(mapi_setprops, NULL)
  326. ZEND_FE(mapi_copyto, NULL)
  327. ZEND_FE(mapi_openproperty, NULL)
  328. ZEND_FE(mapi_deleteprops, NULL)
  329. ZEND_FE(mapi_getnamesfromids, NULL)
  330. ZEND_FE(mapi_getidsfromnames, NULL)
  331. ZEND_FE(mapi_decompressrtf, NULL)
  332. ZEND_FE(mapi_rules_gettable, NULL)
  333. ZEND_FE(mapi_rules_modifytable, NULL)
  334. ZEND_FE(mapi_zarafa_createuser, NULL)
  335. ZEND_FE(mapi_zarafa_setuser, NULL)
  336. ZEND_FE(mapi_zarafa_getuser_by_id, NULL)
  337. ZEND_FE(mapi_zarafa_getuser_by_name, NULL)
  338. ZEND_FE(mapi_zarafa_deleteuser, NULL)
  339. ZEND_FE(mapi_zarafa_createstore, NULL)
  340. ZEND_FE(mapi_zarafa_getuserlist, NULL)
  341. ZEND_FE(mapi_zarafa_getquota, NULL)
  342. ZEND_FE(mapi_zarafa_setquota, NULL)
  343. ZEND_FE(mapi_zarafa_creategroup, NULL)
  344. ZEND_FE(mapi_zarafa_deletegroup, NULL)
  345. ZEND_FE(mapi_zarafa_addgroupmember, NULL)
  346. ZEND_FE(mapi_zarafa_deletegroupmember, NULL)
  347. ZEND_FE(mapi_zarafa_setgroup, NULL)
  348. ZEND_FE(mapi_zarafa_getgroup_by_id, NULL)
  349. ZEND_FE(mapi_zarafa_getgroup_by_name, NULL)
  350. ZEND_FE(mapi_zarafa_getgrouplist, NULL)
  351. ZEND_FE(mapi_zarafa_getgrouplistofuser, NULL)
  352. ZEND_FE(mapi_zarafa_getuserlistofgroup, NULL)
  353. ZEND_FE(mapi_zarafa_createcompany, NULL)
  354. ZEND_FE(mapi_zarafa_deletecompany, NULL)
  355. ZEND_FE(mapi_zarafa_getcompany_by_id, NULL)
  356. ZEND_FE(mapi_zarafa_getcompany_by_name, NULL)
  357. ZEND_FE(mapi_zarafa_getcompanylist, NULL)
  358. ZEND_FE(mapi_zarafa_add_company_remote_viewlist, NULL)
  359. ZEND_FE(mapi_zarafa_del_company_remote_viewlist, NULL)
  360. ZEND_FE(mapi_zarafa_get_remote_viewlist, NULL)
  361. ZEND_FE(mapi_zarafa_add_user_remote_adminlist, NULL)
  362. ZEND_FE(mapi_zarafa_del_user_remote_adminlist, NULL)
  363. ZEND_FE(mapi_zarafa_get_remote_adminlist, NULL)
  364. ZEND_FE(mapi_zarafa_add_quota_recipient, NULL)
  365. ZEND_FE(mapi_zarafa_del_quota_recipient, NULL)
  366. ZEND_FE(mapi_zarafa_get_quota_recipientlist, NULL)
  367. ZEND_FE(mapi_zarafa_check_license, NULL)
  368. ZEND_FE(mapi_zarafa_getcapabilities, NULL)
  369. ZEND_FE(mapi_zarafa_getpermissionrules, NULL)
  370. ZEND_FE(mapi_zarafa_setpermissionrules, NULL)
  371. ZEND_FE(mapi_freebusysupport_open, NULL)
  372. ZEND_FE(mapi_freebusysupport_close, NULL)
  373. ZEND_FE(mapi_freebusysupport_loaddata, NULL)
  374. ZEND_FE(mapi_freebusysupport_loadupdate, NULL)
  375. ZEND_FE(mapi_freebusydata_enumblocks, NULL)
  376. ZEND_FE(mapi_freebusydata_getpublishrange, NULL)
  377. ZEND_FE(mapi_freebusydata_setrange, NULL)
  378. ZEND_FE(mapi_freebusyenumblock_reset, NULL)
  379. ZEND_FE(mapi_freebusyenumblock_next, NULL)
  380. ZEND_FE(mapi_freebusyenumblock_skip, NULL)
  381. ZEND_FE(mapi_freebusyenumblock_restrict, NULL)
  382. ZEND_FE(mapi_freebusyupdate_publish, NULL)
  383. ZEND_FE(mapi_freebusyupdate_reset, NULL)
  384. ZEND_FE(mapi_freebusyupdate_savechanges, NULL)
  385. ZEND_FE(mapi_favorite_add, NULL)
  386. ZEND_FE(mapi_exportchanges_config, NULL)
  387. ZEND_FE(mapi_exportchanges_synchronize, NULL)
  388. ZEND_FE(mapi_exportchanges_updatestate, NULL)
  389. ZEND_FE(mapi_exportchanges_getchangecount, NULL)
  390. ZEND_FE(mapi_importcontentschanges_config, NULL)
  391. ZEND_FE(mapi_importcontentschanges_updatestate, NULL)
  392. ZEND_FE(mapi_importcontentschanges_importmessagechange, fourth_arg_force_ref)
  393. ZEND_FE(mapi_importcontentschanges_importmessagedeletion, NULL)
  394. ZEND_FE(mapi_importcontentschanges_importperuserreadstatechange, NULL)
  395. ZEND_FE(mapi_importcontentschanges_importmessagemove, NULL)
  396. ZEND_FE(mapi_importhierarchychanges_config, NULL)
  397. ZEND_FE(mapi_importhierarchychanges_updatestate, NULL)
  398. ZEND_FE(mapi_importhierarchychanges_importfolderchange, NULL)
  399. ZEND_FE(mapi_importhierarchychanges_importfolderdeletion, NULL)
  400. ZEND_FE(mapi_wrap_importcontentschanges, first_arg_force_ref)
  401. ZEND_FE(mapi_wrap_importhierarchychanges, first_arg_force_ref)
  402. ZEND_FE(mapi_inetmapi_imtoinet, NULL)
  403. ZEND_FE(mapi_inetmapi_imtomapi, NULL)
  404. ZEND_FE(mapi_icaltomapi, nullptr)
  405. ZEND_FE(mapi_mapitoical, nullptr)
  406. ZEND_FE(mapi_vcftomapi, nullptr)
  407. ZEND_FE(mapi_mapitovcf, nullptr)
  408. ZEND_FE(mapi_enable_exceptions, NULL)
  409. ZEND_FE(mapi_feature, NULL)
  410. ZEND_FALIAS(mapi_attach_openbin, mapi_openproperty, NULL)
  411. ZEND_FALIAS(mapi_msgstore_getprops, mapi_getprops, NULL)
  412. ZEND_FALIAS(mapi_msgstore_setprops, mapi_setprops, NULL)
  413. ZEND_FALIAS(mapi_folder_getprops, mapi_getprops, NULL)
  414. ZEND_FALIAS(mapi_folder_openproperty, mapi_openproperty, NULL)
  415. ZEND_FALIAS(mapi_folder_setprops, mapi_setprops, NULL)
  416. ZEND_FALIAS(mapi_message_getprops, mapi_getprops, NULL)
  417. ZEND_FALIAS(mapi_message_setprops, mapi_setprops, NULL)
  418. ZEND_FALIAS(mapi_message_openproperty, mapi_openproperty, NULL)
  419. ZEND_FALIAS(mapi_attach_getprops, mapi_getprops, NULL)
  420. ZEND_FALIAS(mapi_attach_setprops, mapi_setprops, NULL)
  421. ZEND_FALIAS(mapi_attach_openproperty, mapi_openproperty, NULL)
  422. ZEND_FALIAS(mapi_message_savechanges, mapi_savechanges, NULL)
  423. // old versions
  424. ZEND_FALIAS(mapi_zarafa_getuser, mapi_zarafa_getuser_by_name, NULL)
  425. ZEND_FALIAS(mapi_zarafa_getgroup, mapi_zarafa_getgroup_by_name, NULL)
  426. {NULL, NULL, NULL}
  427. };
  428. ZEND_DECLARE_MODULE_GLOBALS(mapi)
  429. static void php_mapi_init_globals(zend_mapi_globals *mapi_globals) {
  430. // seems to be empty ..
  431. }
  432. /* module information */
  433. zend_module_entry mapi_module_entry =
  434. {
  435. STANDARD_MODULE_HEADER,
  436. "mapi", /* name */
  437. mapi_functions, /* functionlist */
  438. PHP_MINIT(mapi), /* module startup function */
  439. PHP_MSHUTDOWN(mapi),/* module shutdown function */
  440. PHP_RINIT(mapi), /* Request init function */
  441. PHP_RSHUTDOWN(mapi),/* Request shutdown function */
  442. PHP_MINFO(mapi), /* Info function */
  443. PROJECT_VERSION_DOT_STR "-" PROJECT_SVN_REV_STR, /* version */
  444. STANDARD_MODULE_PROPERTIES
  445. };
  446. #if COMPILE_DL_MAPI
  447. BEGIN_EXTERN_C()
  448. ZEND_DLEXPORT zend_module_entry *get_module(void);
  449. ZEND_GET_MODULE(mapi)
  450. END_EXTERN_C()
  451. #endif
  452. /***************************************************************
  453. * PHP Module functions
  454. ***************************************************************/
  455. PHP_MINFO_FUNCTION(mapi)
  456. {
  457. php_info_print_table_start();
  458. php_info_print_table_row(2, "MAPI Support", "enabled");
  459. php_info_print_table_row(2, "Version", PROJECT_VERSION_EXT_STR);
  460. php_info_print_table_row(2, "Git version", PROJECT_SVN_REV_STR);
  461. php_info_print_table_end();
  462. }
  463. #define CE_PHP_MAPI_PERFORMANCE_TRACE_FILE "php_mapi_performance_trace_file"
  464. #define CE_PHP_MAPI_DEBUG "php_mapi_debug"
  465. static int LoadSettingsFile(void)
  466. {
  467. const char *const cfg_file = ECConfig::GetDefaultPath("php-mapi.cfg");
  468. struct stat st;
  469. if (stat(cfg_file, &st) == 0) {
  470. static const configsetting_t settings[] = {
  471. { "log_method", "syslog" },
  472. { "log_file", LOGFILE_PATH "/php-mapi.log" },
  473. { "log_level", "3", CONFIGSETTING_RELOADABLE },
  474. { "log_timestamp", "0" },
  475. { "log_buffer_size", "0" },
  476. { "log_buffer_size", "0" },
  477. { CE_PHP_MAPI_PERFORMANCE_TRACE_FILE, "" },
  478. { CE_PHP_MAPI_DEBUG, "0" },
  479. { NULL, NULL }
  480. };
  481. auto cfg = ECConfig::Create(std::nothrow, settings);
  482. if (!cfg)
  483. return FAILURE;
  484. if (cfg->LoadSettings(cfg_file))
  485. lpLogger = CreateLogger(cfg, "php-mapi", "PHPMapi");
  486. const char *temp = cfg->GetSetting(CE_PHP_MAPI_PERFORMANCE_TRACE_FILE);
  487. if (temp != NULL) {
  488. perf_measure_file = strdup(temp);
  489. lpLogger->Log(EC_LOGLEVEL_INFO, "Performance measuring enabled");
  490. }
  491. temp = cfg->GetSetting(CE_PHP_MAPI_DEBUG);
  492. if (temp != NULL)
  493. mapi_debug = strtoul(temp, NULL, 0);
  494. delete cfg;
  495. }
  496. if (!lpLogger)
  497. lpLogger = new(std::nothrow) ECLogger_Null();
  498. if (lpLogger == NULL)
  499. return FAILURE;
  500. lpLogger->Log(EC_LOGLEVEL_INFO, "PHP-MAPI instantiated " PROJECT_VERSION_EXT_STR);
  501. ec_log_set(lpLogger);
  502. if (mapi_debug)
  503. lpLogger->Log(EC_LOGLEVEL_INFO, "PHP-MAPI trace level set to %d", mapi_debug);
  504. return SUCCESS;
  505. }
  506. /**
  507. * Initfunction for the module, will be called once at server startup
  508. */
  509. PHP_MINIT_FUNCTION(mapi) {
  510. int ret = LoadSettingsFile();
  511. if (ret != SUCCESS)
  512. return ret;
  513. le_mapi_session = zend_register_list_destructors_ex(_php_free_mapi_session, NULL, const_cast<char *>(name_mapi_session), module_number);
  514. le_mapi_table = zend_register_list_destructors_ex(_php_free_mapi_object, NULL, const_cast<char *>(name_mapi_table), module_number);
  515. le_mapi_rowset = zend_register_list_destructors_ex(_php_free_mapi_rowset, NULL, const_cast<char *>(name_mapi_rowset), module_number);
  516. le_mapi_msgstore = zend_register_list_destructors_ex(_php_free_mapi_object, NULL, const_cast<char *>(name_mapi_msgstore), module_number);
  517. le_mapi_addrbook = zend_register_list_destructors_ex(_php_free_mapi_object, NULL, const_cast<char *>(name_mapi_addrbook), module_number);
  518. le_mapi_mailuser = zend_register_list_destructors_ex(_php_free_mapi_object, NULL, const_cast<char *>(name_mapi_mailuser), module_number);
  519. le_mapi_distlist = zend_register_list_destructors_ex(_php_free_mapi_object, NULL, const_cast<char *>(name_mapi_distlist), module_number);
  520. le_mapi_abcont = zend_register_list_destructors_ex(_php_free_mapi_object, NULL, const_cast<char *>(name_mapi_abcont), module_number);
  521. le_mapi_folder = zend_register_list_destructors_ex(_php_free_mapi_object, NULL, const_cast<char *>(name_mapi_folder), module_number);
  522. le_mapi_message = zend_register_list_destructors_ex(_php_free_mapi_object, NULL, const_cast<char *>(name_mapi_message), module_number);
  523. le_mapi_attachment = zend_register_list_destructors_ex(_php_free_mapi_object, NULL, const_cast<char *>(name_mapi_attachment), module_number);
  524. le_mapi_property = zend_register_list_destructors_ex(_php_free_mapi_object, NULL, const_cast<char *>(name_mapi_property), module_number);
  525. le_mapi_modifytable = zend_register_list_destructors_ex(_php_free_mapi_object, NULL, const_cast<char *>(name_mapi_modifytable), module_number);
  526. le_mapi_advisesink = zend_register_list_destructors_ex(_php_free_mapi_object, NULL, const_cast<char *>(name_mapi_advisesink), module_number);
  527. le_istream = zend_register_list_destructors_ex(_php_free_istream, NULL, const_cast<char *>(name_istream), module_number);
  528. // Freebusy functions
  529. le_freebusy_support = zend_register_list_destructors_ex(_php_free_fb_object, NULL, const_cast<char *>(name_fb_support), module_number);
  530. le_freebusy_data = zend_register_list_destructors_ex(_php_free_fb_object, NULL, const_cast<char *>(name_fb_data), module_number);
  531. le_freebusy_update = zend_register_list_destructors_ex(_php_free_fb_object, NULL, const_cast<char *>(name_fb_update), module_number);
  532. le_freebusy_enumblock = zend_register_list_destructors_ex(_php_free_fb_object, NULL, const_cast<char *>(name_fb_enumblock), module_number);
  533. // ICS interfaces
  534. le_mapi_exportchanges = zend_register_list_destructors_ex(_php_free_mapi_object, NULL, const_cast<char *>(name_mapi_exportchanges), module_number);
  535. le_mapi_importhierarchychanges = zend_register_list_destructors_ex(_php_free_mapi_object, NULL, const_cast<char *>(name_mapi_importhierarchychanges), module_number);
  536. le_mapi_importcontentschanges = zend_register_list_destructors_ex(_php_free_mapi_object, NULL, const_cast<char *>(name_mapi_importcontentschanges), module_number);
  537. MAPIINIT_0 MAPIINIT = { 0, MAPI_MULTITHREAD_NOTIFICATIONS };
  538. // There is also a MAPI_NT_SERVICE flag, see help page for MAPIInitialize
  539. if (MAPIInitialize(&MAPIINIT) != hrSuccess)
  540. return FAILURE;
  541. ZEND_INIT_MODULE_GLOBALS(mapi, php_mapi_init_globals, NULL);
  542. // force this program to use UTF-8, that way, we don't have to use lpszW and do all kinds of conversions from UTF-8 to WCHAR and back
  543. forceUTF8Locale(false);
  544. return SUCCESS;
  545. }
  546. // Used at the end of each MAPI call to throw exceptions if mapi_enable_exceptions() has been called
  547. #define THROW_ON_ERROR() \
  548. if (FAILED(MAPI_G(hr))) { \
  549. if (lpLogger) \
  550. lpLogger->Log(EC_LOGLEVEL_ERROR, "MAPI error: %s (%x) (method: %s, line: %d)", GetMAPIErrorMessage(MAPI_G(hr)), MAPI_G(hr), __FUNCTION__, __LINE__); \
  551. \
  552. if (MAPI_G(exceptions_enabled)) \
  553. zend_throw_exception(MAPI_G(exception_ce), "MAPI error ", MAPI_G(hr) TSRMLS_CC); \
  554. }
  555. /**
  556. *
  557. *
  558. */
  559. PHP_MSHUTDOWN_FUNCTION(mapi)
  560. {
  561. UNREGISTER_INI_ENTRIES();
  562. free(perf_measure_file);
  563. perf_measure_file = NULL;
  564. if (lpLogger)
  565. lpLogger->Log(EC_LOGLEVEL_INFO, "PHP-MAPI shutdown");
  566. MAPIUninitialize();
  567. if (lpLogger != NULL)
  568. lpLogger->Release();
  569. lpLogger = NULL;
  570. return SUCCESS;
  571. }
  572. /***************************************************************
  573. * PHP Request functions
  574. ***************************************************************/
  575. /**
  576. * Request init function, will be called before every request.
  577. *
  578. */
  579. PHP_RINIT_FUNCTION(mapi) {
  580. MAPI_G(hr) = hrSuccess;
  581. MAPI_G(exception_ce) = NULL;
  582. MAPI_G(exceptions_enabled) = false;
  583. return SUCCESS;
  584. }
  585. /**
  586. * Request shutdown function, will be called after every request.
  587. *
  588. */
  589. PHP_RSHUTDOWN_FUNCTION(mapi) {
  590. return SUCCESS;
  591. }
  592. /***************************************************************
  593. * Resource Destructor functions
  594. ***************************************************************/
  595. // This is called when our proxy object goes out of scope
  596. static void _php_free_mapi_session(zend_resource *rsrc TSRMLS_DC)
  597. {
  598. PMEASURE_FUNC;
  599. auto lpSession = static_cast<IMAPISession *>(rsrc->ptr);
  600. if(lpSession) lpSession->Release();
  601. }
  602. static void _php_free_mapi_rowset(zend_resource *rsrc TSRMLS_DC)
  603. {
  604. auto pRowSet = static_cast<SRowSet *>(rsrc->ptr);
  605. if (pRowSet) FreeProws(pRowSet);
  606. }
  607. static void _php_free_mapi_object(zend_resource *rsrc TSRMLS_DC)
  608. {
  609. auto lpUnknown = static_cast<IUnknown *>(rsrc->ptr);
  610. if (lpUnknown) lpUnknown->Release();
  611. }
  612. static void _php_free_istream(zend_resource *rsrc TSRMLS_DC)
  613. {
  614. auto pStream = static_cast<IStream *>(rsrc->ptr);
  615. if (pStream) pStream->Release();
  616. }
  617. static void _php_free_fb_object(zend_resource *rsrc TSRMLS_DC)
  618. {
  619. auto lpObj = static_cast<IUnknown *>(rsrc->ptr);
  620. if (lpObj) lpObj->Release();
  621. }
  622. static HRESULT GetECObject(LPMAPIPROP lpMapiProp,
  623. IECUnknown **lppIECUnknown TSRMLS_DC)
  624. {
  625. PMEASURE_FUNC;
  626. memory_ptr<SPropValue> lpPropVal;
  627. MAPI_G(hr) = HrGetOneProp(lpMapiProp, PR_EC_OBJECT, &~lpPropVal);
  628. if (MAPI_G(hr) == hrSuccess)
  629. *lppIECUnknown = (IECUnknown *)lpPropVal->Value.lpszA;
  630. return MAPI_G(hr);
  631. }
  632. /***************************************************************
  633. * Custom Code
  634. ***************************************************************/
  635. ZEND_FUNCTION(mapi_last_hresult)
  636. {
  637. RETURN_LONG((LONG)MAPI_G(hr));
  638. }
  639. /*
  640. * PHP casts a variable to a signed long before bitshifting. So a C++ function
  641. * is used.
  642. */
  643. ZEND_FUNCTION(mapi_prop_type)
  644. {
  645. long ulPropTag;
  646. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &ulPropTag) == FAILURE) return;
  647. RETURN_LONG(PROP_TYPE(ulPropTag));
  648. }
  649. /*
  650. * PHP casts a variable to a signed long before bitshifting. So a C++ function
  651. * is used.
  652. */
  653. ZEND_FUNCTION(mapi_prop_id)
  654. {
  655. long ulPropTag;
  656. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &ulPropTag) == FAILURE) return;
  657. RETURN_LONG(PROP_ID(ulPropTag));
  658. }
  659. /**
  660. * Checks if the severity of a errorCode is set to Fail
  661. *
  662. *
  663. */
  664. ZEND_FUNCTION(mapi_is_error)
  665. {
  666. long errorcode;
  667. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &errorcode) == FAILURE) return;
  668. RETURN_BOOL(IS_ERROR(errorcode));
  669. }
  670. /*
  671. * Makes a mapi SCODE
  672. * input:
  673. * long severity
  674. * long code
  675. *
  676. */
  677. ZEND_FUNCTION(mapi_make_scode)
  678. {
  679. long sev, code;
  680. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &sev, &code) == FAILURE) return;
  681. /*
  682. * sev has two possible values: 0 for a warning, 1 for an error
  683. * err is the error code for the specific error.
  684. */
  685. RETURN_LONG(MAKE_MAPI_SCODE(sev & 1, FACILITY_ITF, code));
  686. }
  687. /*
  688. * PHP casts a variable to a signed long before bitshifting. So a C++ function
  689. * is used.
  690. */
  691. ZEND_FUNCTION(mapi_prop_tag)
  692. {
  693. long ulPropID, ulPropType;
  694. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &ulPropType, &ulPropID) == FAILURE) return;
  695. // PHP uses variable type 'long' internally. If a number in a string as key is used in add_assoc_*(),
  696. // it is re-interpreted a a number when it's smaller than LONG_MAX.
  697. // however, LONG_MAX is 2147483647L on 32-bit systems, but 9223372036854775807L on 64-bit.
  698. // this make named props (0x80000000+) fit in the 'number' description, and so this breaks on 64-bit systems
  699. // .. well, it un-breaks on 64-bit .. so we cast the unsigned proptag to a signed number here, so
  700. // the compares within .php files can be correctly performed, so named props work.
  701. // maybe we need to rewrite this system a bit, so proptags are always a string, and never interpreted
  702. // eg. by prepending the assoc keys with 'PROPTAG' or something...
  703. RETURN_LONG((LONG)PROP_TAG(ulPropType, ulPropID));
  704. }
  705. ZEND_FUNCTION(mapi_createoneoff)
  706. {
  707. PMEASURE_FUNC;
  708. LOG_BEGIN();
  709. // params
  710. char *szDisplayName = NULL;
  711. char *szType = NULL;
  712. char *szEmailAddress = NULL;
  713. size_t ulDisplayNameLen = 0, ulTypeLen = 0, ulEmailAddressLen = 0;
  714. long ulFlags = MAPI_SEND_NO_RICH_INFO;
  715. // return value
  716. memory_ptr<ENTRYID> lpEntryID;
  717. ULONG cbEntryID = 0;
  718. // local
  719. wstring name;
  720. wstring type;
  721. wstring email;
  722. RETVAL_FALSE;
  723. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  724. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|l",
  725. &szDisplayName, &ulDisplayNameLen,
  726. &szType, &ulTypeLen,
  727. &szEmailAddress, &ulEmailAddressLen, &ulFlags) == FAILURE) return;
  728. MAPI_G(hr) = TryConvert(szDisplayName, name);
  729. if(MAPI_G(hr) != hrSuccess) {
  730. php_error_docref(NULL TSRMLS_CC, E_WARNING, "CreateOneOff name conversion failed");
  731. goto exit;
  732. }
  733. MAPI_G(hr) = TryConvert(szType, type);
  734. if(MAPI_G(hr) != hrSuccess) {
  735. php_error_docref(NULL TSRMLS_CC, E_WARNING, "CreateOneOff type conversion failed");
  736. goto exit;
  737. }
  738. MAPI_G(hr) = TryConvert(szEmailAddress, email);
  739. if(MAPI_G(hr) != hrSuccess) {
  740. php_error_docref(NULL TSRMLS_CC, E_WARNING, "CreateOneOff address conversion failed");
  741. goto exit;
  742. }
  743. MAPI_G(hr) = ECCreateOneOff((LPTSTR)name.c_str(), (LPTSTR)type.c_str(), (LPTSTR)email.c_str(), MAPI_UNICODE | ulFlags, &cbEntryID, &~lpEntryID);
  744. if(MAPI_G(hr) != hrSuccess) {
  745. php_error_docref(NULL TSRMLS_CC, E_WARNING, "CreateOneOff failed");
  746. goto exit;
  747. }
  748. RETVAL_STRINGL(reinterpret_cast<const char *>(lpEntryID.get()), cbEntryID);
  749. exit:
  750. // using RETVAL_* not RETURN_*, otherwise php will instantly return itself, and we won't be able to free...
  751. LOG_END();
  752. THROW_ON_ERROR();
  753. }
  754. ZEND_FUNCTION(mapi_parseoneoff)
  755. {
  756. PMEASURE_FUNC;
  757. LOG_BEGIN();
  758. // params
  759. LPENTRYID lpEntryID = NULL;
  760. size_t cbEntryID = 0;
  761. // return value
  762. utf8string strDisplayName;
  763. utf8string strType;
  764. utf8string strAddress;
  765. std::wstring wstrDisplayName;
  766. std::wstring wstrType;
  767. std::wstring wstrAddress;
  768. RETVAL_FALSE;
  769. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  770. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &lpEntryID, &cbEntryID) == FAILURE) return;
  771. MAPI_G(hr) = ECParseOneOff(lpEntryID, cbEntryID, wstrDisplayName, wstrType, wstrAddress);
  772. if(MAPI_G(hr) != hrSuccess) {
  773. php_error_docref(NULL TSRMLS_CC, E_WARNING, "ParseOneOff failed");
  774. goto exit;
  775. }
  776. array_init(return_value);
  777. strDisplayName = convert_to<utf8string>(wstrDisplayName);
  778. strType = convert_to<utf8string>(wstrType);
  779. strAddress = convert_to<utf8string>(wstrAddress);
  780. add_assoc_string(return_value, "name", (char*)strDisplayName.c_str());
  781. add_assoc_string(return_value, "type", (char*)strType.c_str());
  782. add_assoc_string(return_value, "address", (char*)strAddress.c_str());
  783. exit:
  784. LOG_END();
  785. THROW_ON_ERROR();
  786. }
  787. /*
  788. * How sessions and stores work:
  789. * - mapi_logon_zarafa() creates a session and returns this
  790. * - mapi_getmsgstorestable() to get the entryid of the default and public store
  791. * - mapi_openmsgstore() to open the default user store + public store
  792. * - mapi_msgstore_createentryid() retuns a store entryid of requested user
  793. * - store entryid can be used with mapi_openmsgstore() to open
  794. *
  795. * Removed, how it did work in the far past:
  796. * - mapi_openmsgstore_zarafa() creates a session, opens the user's store, and the public
  797. * and returns these store pointers in an array.
  798. * - mapi_msgstore_createentryid() is used to call Store->CreateStoreEntryID()
  799. * - mapi_openmsgstore_zarafa_other() with the prev acquired entryid opens the store of another user,
  800. * - mapi_openmsgstore_zarafa_other() is therefor called with the current user id and password (and maybe the server) as well!
  801. * Only with this info we can find the session again, to get the IMAPISession, and open another store.
  802. */
  803. ZEND_FUNCTION(mapi_logon_zarafa)
  804. {
  805. PMEASURE_FUNC;
  806. LOG_BEGIN();
  807. // params
  808. char *username = NULL;
  809. size_t username_len = 0;
  810. char *password = NULL;
  811. size_t password_len = 0;
  812. const char *server = NULL;
  813. size_t server_len = 0;
  814. const char *sslcert = "";
  815. size_t sslcert_len = 0;
  816. const char *sslpass = "";
  817. size_t sslpass_len = 0;
  818. const char *wa_version = "";
  819. size_t wa_version_len = 0;
  820. const char *misc_version = "";
  821. size_t misc_version_len = 0;
  822. long ulFlags = EC_PROFILE_FLAGS_NO_NOTIFICATIONS;
  823. // return value
  824. object_ptr<IMAPISession> lpMAPISession;
  825. // local
  826. ULONG ulProfNum = rand_mt();
  827. char szProfName[MAX_PATH];
  828. SPropValue sPropZarafa[8];
  829. RETVAL_FALSE;
  830. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  831. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|ssslss",
  832. &username, &username_len, &password, &password_len, &server, &server_len,
  833. &sslcert, &sslcert_len, &sslpass, &sslpass_len, &ulFlags,
  834. &wa_version, &wa_version_len, &misc_version, &misc_version_len) == FAILURE) return;
  835. if (!server) {
  836. server = "http://localhost:236/zarafa";
  837. server_len = strlen(server);
  838. }
  839. snprintf(szProfName, MAX_PATH-1, "www-profile%010u", ulProfNum);
  840. sPropZarafa[0].ulPropTag = PR_EC_PATH;
  841. sPropZarafa[0].Value.lpszA = const_cast<char *>(server);
  842. sPropZarafa[1].ulPropTag = PR_EC_USERNAME_A;
  843. sPropZarafa[1].Value.lpszA = const_cast<char *>(username);
  844. sPropZarafa[2].ulPropTag = PR_EC_USERPASSWORD_A;
  845. sPropZarafa[2].Value.lpszA = const_cast<char *>(password);
  846. sPropZarafa[3].ulPropTag = PR_EC_FLAGS;
  847. sPropZarafa[3].Value.ul = ulFlags;
  848. // unused by zarafa if PR_EC_PATH isn't https
  849. sPropZarafa[4].ulPropTag = PR_EC_SSLKEY_FILE;
  850. sPropZarafa[4].Value.lpszA = const_cast<char *>(sslcert);
  851. sPropZarafa[5].ulPropTag = PR_EC_SSLKEY_PASS;
  852. sPropZarafa[5].Value.lpszA = const_cast<char *>(sslpass);
  853. sPropZarafa[6].ulPropTag = PR_EC_STATS_SESSION_CLIENT_APPLICATION_VERSION;
  854. sPropZarafa[6].Value.lpszA = const_cast<char *>(wa_version);
  855. sPropZarafa[7].ulPropTag = PR_EC_STATS_SESSION_CLIENT_APPLICATION_MISC;
  856. sPropZarafa[7].Value.lpszA = const_cast<char *>(misc_version);
  857. MAPI_G(hr) = mapi_util_createprof(szProfName, "ZARAFA6", 8, sPropZarafa);
  858. if (MAPI_G(hr) != hrSuccess) {
  859. php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", mapi_util_getlasterror().c_str());
  860. goto exit; // error already displayed in mapi_util_createprof
  861. }
  862. // Logon to our new profile
  863. MAPI_G(hr) = MAPILogonEx(0, reinterpret_cast<LPTSTR>(const_cast<char *>(szProfName)),
  864. reinterpret_cast<LPTSTR>(const_cast<char *>("")),
  865. MAPI_EXTENDED | MAPI_TIMEOUT_SHORT | MAPI_NEW_SESSION,
  866. &~lpMAPISession);
  867. if (MAPI_G(hr) != hrSuccess) {
  868. mapi_util_deleteprof(szProfName);
  869. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to logon to profile");
  870. goto exit;
  871. }
  872. // Delete the profile (it will be deleted when we close our session)
  873. MAPI_G(hr) = mapi_util_deleteprof(szProfName);
  874. if (MAPI_G(hr) != hrSuccess) {
  875. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to delete profile");
  876. goto exit;
  877. }
  878. ZEND_REGISTER_RESOURCE(return_value, lpMAPISession.release(), le_mapi_session);
  879. exit:
  880. LOG_END();
  881. THROW_ON_ERROR();
  882. }
  883. /**
  884. * mapi_openentry
  885. * Opens the msgstore from the session
  886. * @param Resource IMAPISession
  887. * @param String EntryID
  888. */
  889. ZEND_FUNCTION(mapi_openentry)
  890. {
  891. PMEASURE_FUNC;
  892. LOG_BEGIN();
  893. // params
  894. zval *res;
  895. IMAPISession *lpSession = NULL;
  896. size_t cbEntryID = 0;
  897. LPENTRYID lpEntryID = NULL;
  898. long ulFlags = MAPI_BEST_ACCESS;
  899. // return value
  900. object_ptr<IUnknown> lpUnknown; // either folder or message
  901. // local
  902. ULONG ulObjType;
  903. RETVAL_FALSE;
  904. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  905. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|sl", &res, &lpEntryID, &cbEntryID, &ulFlags) == FAILURE) return;
  906. ZEND_FETCH_RESOURCE_C(lpSession, IMAPISession *, &res, -1, name_mapi_session, le_mapi_session);
  907. MAPI_G(hr) = lpSession->OpenEntry(cbEntryID, lpEntryID, nullptr,
  908. ulFlags, &ulObjType, &~lpUnknown);
  909. if (FAILED(MAPI_G(hr)))
  910. goto exit;
  911. if (ulObjType == MAPI_FOLDER) {
  912. UOBJ_REGISTER_RESOURCE(return_value, lpUnknown.release(), le_mapi_folder);
  913. }
  914. else if(ulObjType == MAPI_MESSAGE) {
  915. UOBJ_REGISTER_RESOURCE(return_value, lpUnknown.release(), le_mapi_message);
  916. } else {
  917. php_error_docref(NULL TSRMLS_CC, E_WARNING, "EntryID is not a folder or a message.");
  918. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  919. goto exit;
  920. }
  921. exit:
  922. LOG_END();
  923. THROW_ON_ERROR();
  924. }
  925. // This function cannot be used, since you currently can't create profiles directly in php
  926. ZEND_FUNCTION(mapi_logon)
  927. {
  928. PMEASURE_FUNC;
  929. LOG_BEGIN();
  930. // params
  931. const char *profilename = "";
  932. const char *profilepassword = "";
  933. size_t profilename_len = 0, profilepassword_len = 0;
  934. // return value
  935. LPMAPISESSION lpMAPISession = NULL;
  936. // local
  937. RETVAL_FALSE;
  938. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  939. if (ZEND_NUM_ARGS() > 0 &&
  940. zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",
  941. &profilename, &profilename_len, &profilepassword, &profilepassword_len) == FAILURE)
  942. return;
  943. /*
  944. * MAPI_LOGON_UI will show a dialog when a profilename is not
  945. * found or a password is not correct, without it the dialog will never appear => that's what we want
  946. * MAPI_USE_DEFAULT |
  947. */
  948. MAPI_G(hr) = MAPILogonEx(0, (LPTSTR)profilename, (LPTSTR)profilepassword, MAPI_USE_DEFAULT | MAPI_EXTENDED | MAPI_TIMEOUT_SHORT | MAPI_NEW_SESSION, &lpMAPISession);
  949. if(MAPI_G(hr) != hrSuccess)
  950. goto exit;
  951. ZEND_REGISTER_RESOURCE(return_value, lpMAPISession, le_mapi_session);
  952. exit:
  953. LOG_END();
  954. THROW_ON_ERROR();
  955. }
  956. // IMAPISession::OpenAddressBook()
  957. // must have valid session
  958. ZEND_FUNCTION(mapi_openaddressbook)
  959. {
  960. PMEASURE_FUNC;
  961. LOG_BEGIN();
  962. // params
  963. zval *res;
  964. IMAPISession *lpSession = NULL;
  965. // return value
  966. LPADRBOOK lpAddrBook;
  967. // local
  968. RETVAL_FALSE;
  969. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  970. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &res) == FAILURE) return;
  971. ZEND_FETCH_RESOURCE_C(lpSession, IMAPISession*, &res, -1, name_mapi_session, le_mapi_session);
  972. MAPI_G(hr) = lpSession->OpenAddressBook(0, NULL, AB_NO_DIALOG, &lpAddrBook);
  973. if (MAPI_G(hr) != hrSuccess)
  974. goto exit;
  975. UOBJ_REGISTER_RESOURCE(return_value, lpAddrBook, le_mapi_addrbook);
  976. exit:
  977. LOG_END();
  978. THROW_ON_ERROR();
  979. }
  980. ZEND_FUNCTION(mapi_ab_openentry) {
  981. PMEASURE_FUNC;
  982. LOG_BEGIN();
  983. // params
  984. zval *res;
  985. LPADRBOOK lpAddrBook = NULL;
  986. size_t cbEntryID = 0;
  987. LPENTRYID lpEntryID = NULL;
  988. long ulFlags = 0; //MAPI_BEST_ACCESS;
  989. // return value
  990. ULONG ulObjType;
  991. object_ptr<IUnknown> lpUnknown;
  992. RETVAL_FALSE;
  993. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  994. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|sl", &res, &lpEntryID, &cbEntryID, &ulFlags) == FAILURE) return;
  995. if(Z_RES_P(res)->type != le_mapi_addrbook) {
  996. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Resource is not a valid address book");
  997. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  998. goto exit;
  999. }
  1000. ZEND_FETCH_RESOURCE_C(lpAddrBook, LPADRBOOK, &res, -1, name_mapi_addrbook, le_mapi_addrbook);
  1001. MAPI_G(hr) = lpAddrBook->OpenEntry(cbEntryID, lpEntryID, nullptr,
  1002. ulFlags, &ulObjType, &~lpUnknown);
  1003. if (MAPI_G(hr) != hrSuccess)
  1004. goto exit;
  1005. switch (ulObjType) {
  1006. case MAPI_MAILUSER:
  1007. UOBJ_REGISTER_RESOURCE(return_value, lpUnknown.release(), le_mapi_mailuser);
  1008. break;
  1009. case MAPI_DISTLIST:
  1010. UOBJ_REGISTER_RESOURCE(return_value, lpUnknown.release(), le_mapi_distlist);
  1011. break;
  1012. case MAPI_ABCONT:
  1013. UOBJ_REGISTER_RESOURCE(return_value, lpUnknown.release(), le_mapi_abcont);
  1014. break;
  1015. default:
  1016. php_error_docref(NULL TSRMLS_CC, E_WARNING, "EntryID is not an AddressBook item");
  1017. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1018. goto exit;
  1019. }
  1020. exit:
  1021. LOG_END();
  1022. THROW_ON_ERROR();
  1023. }
  1024. ZEND_FUNCTION(mapi_ab_resolvename) {
  1025. PMEASURE_FUNC;
  1026. LOG_BEGIN();
  1027. // params
  1028. zval *res;
  1029. LPADRBOOK lpAddrBook = NULL;
  1030. zval *array;
  1031. zval rowset;
  1032. long ulFlags = 0;
  1033. // return value
  1034. // local
  1035. adrlist_ptr lpAList;
  1036. RETVAL_FALSE;
  1037. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1038. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra|l", &res, &array, &ulFlags) == FAILURE) return;
  1039. ZEND_FETCH_RESOURCE_C(lpAddrBook, LPADRBOOK, &res, -1, name_mapi_addrbook, le_mapi_addrbook);
  1040. MAPI_G(hr) = PHPArraytoAdrList(array, nullptr, &~lpAList TSRMLS_CC);
  1041. if (MAPI_G(hr) != hrSuccess)
  1042. goto exit;
  1043. MAPI_G(hr) = lpAddrBook->ResolveName(0, ulFlags, NULL, lpAList);
  1044. switch (MAPI_G(hr)) {
  1045. case hrSuccess:
  1046. // parse back lpAList and return as array
  1047. RowSettoPHPArray(reinterpret_cast<SRowSet *>(lpAList.get()), &rowset TSRMLS_CC); // binary compatible
  1048. RETVAL_ZVAL(&rowset, 0, 0);
  1049. break;
  1050. case MAPI_E_AMBIGUOUS_RECIP:
  1051. case MAPI_E_NOT_FOUND:
  1052. default:
  1053. break;
  1054. };
  1055. exit:
  1056. LOG_END();
  1057. THROW_ON_ERROR();
  1058. }
  1059. ZEND_FUNCTION(mapi_ab_getdefaultdir) {
  1060. PMEASURE_FUNC;
  1061. LOG_BEGIN();
  1062. // params
  1063. zval *res;
  1064. LPADRBOOK lpAddrBook = NULL;
  1065. // return value
  1066. memory_ptr<ENTRYID> lpEntryID;
  1067. ULONG cbEntryID = 0;
  1068. RETVAL_FALSE;
  1069. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1070. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &res) == FAILURE) return;
  1071. ZEND_FETCH_RESOURCE_C(lpAddrBook, LPADRBOOK, &res, -1, name_mapi_addrbook, le_mapi_addrbook);
  1072. MAPI_G(hr) = lpAddrBook->GetDefaultDir(&cbEntryID, &~lpEntryID);
  1073. if (MAPI_G(hr) != hrSuccess) {
  1074. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed GetDefaultDir of the addressbook. Error code: 0x%08X", MAPI_G(hr));
  1075. goto exit;
  1076. }
  1077. RETVAL_STRINGL(reinterpret_cast<const char *>(lpEntryID.get()), cbEntryID);
  1078. exit:
  1079. LOG_END();
  1080. THROW_ON_ERROR();
  1081. }
  1082. /**
  1083. * mapi_getstores
  1084. * Gets the table with the messagestores available
  1085. *
  1086. */
  1087. ZEND_FUNCTION(mapi_getmsgstorestable)
  1088. {
  1089. PMEASURE_FUNC;
  1090. LOG_BEGIN();
  1091. // params
  1092. zval *res = NULL;
  1093. IMAPISession *lpSession = NULL;
  1094. // return value
  1095. LPMAPITABLE lpTable = NULL;
  1096. RETVAL_FALSE;
  1097. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1098. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &res) == FAILURE) return;
  1099. ZEND_FETCH_RESOURCE_C(lpSession, IMAPISession *, &res, -1, name_mapi_session, le_mapi_session);
  1100. MAPI_G(hr) = lpSession->GetMsgStoresTable(0, &lpTable);
  1101. if (FAILED(MAPI_G(hr))) {
  1102. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to fetch the message store table: 0x%08X", MAPI_G(hr));
  1103. goto exit;
  1104. }
  1105. UOBJ_REGISTER_RESOURCE(return_value, lpTable, le_mapi_table);
  1106. exit:
  1107. LOG_END();
  1108. THROW_ON_ERROR();
  1109. }
  1110. /**
  1111. * mapi_openmsgstore
  1112. * Opens the messagestore for the entryid
  1113. * @param String with the entryid
  1114. * @return RowSet with messages
  1115. */
  1116. ZEND_FUNCTION(mapi_openmsgstore)
  1117. {
  1118. PMEASURE_FUNC;
  1119. LOG_BEGIN();
  1120. // params
  1121. size_t cbEntryID = 0;
  1122. LPENTRYID lpEntryID = NULL;
  1123. zval *res = NULL;
  1124. IMAPISession * lpSession = NULL;
  1125. // return value
  1126. LPMDB pMDB = NULL;
  1127. RETVAL_FALSE;
  1128. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1129. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs",
  1130. &res, (char *)&lpEntryID, &cbEntryID) == FAILURE) return;
  1131. ZEND_FETCH_RESOURCE_C(lpSession, IMAPISession *, &res, -1, name_mapi_session, le_mapi_session);
  1132. MAPI_G(hr) = lpSession->OpenMsgStore(0, cbEntryID, lpEntryID, 0, MAPI_BEST_ACCESS | MDB_NO_DIALOG, &pMDB);
  1133. if (FAILED(MAPI_G(hr))) {
  1134. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open the messagestore: 0x%08X", MAPI_G(hr));
  1135. goto exit;
  1136. }
  1137. UOBJ_REGISTER_RESOURCE(return_value, pMDB, le_mapi_msgstore);
  1138. exit:
  1139. LOG_END();
  1140. THROW_ON_ERROR();
  1141. }
  1142. /**
  1143. * Open the profile section of given guid, and returns the php-usable IMAPIProp object
  1144. *
  1145. * @param[in] Resource mapi session
  1146. * @param[in] String mapi uid of profile section
  1147. *
  1148. * @return IMAPIProp interface of IProfSect object
  1149. */
  1150. ZEND_FUNCTION(mapi_openprofilesection)
  1151. {
  1152. PMEASURE_FUNC;
  1153. LOG_BEGIN();
  1154. // params
  1155. zval *res;
  1156. IMAPISession *lpSession = NULL;
  1157. size_t uidlen;
  1158. LPMAPIUID lpUID = NULL;
  1159. // return value
  1160. IMAPIProp *lpProfSectProp = NULL;
  1161. // local
  1162. RETVAL_FALSE;
  1163. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1164. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &res, &lpUID, &uidlen) == FAILURE) return;
  1165. if (uidlen != sizeof(MAPIUID))
  1166. goto exit;
  1167. ZEND_FETCH_RESOURCE_C(lpSession, IMAPISession*, &res, -1, name_mapi_session, le_mapi_session);
  1168. // yes, you can request any compatible interface, but the return pointer is LPPROFSECT .. ohwell.
  1169. MAPI_G(hr) = lpSession->OpenProfileSection(lpUID, &IID_IMAPIProp, 0, (LPPROFSECT*)&lpProfSectProp);
  1170. if (MAPI_G(hr) != hrSuccess)
  1171. goto exit;
  1172. UOBJ_REGISTER_RESOURCE(return_value, lpProfSectProp, le_mapi_property);
  1173. exit:
  1174. LOG_END();
  1175. THROW_ON_ERROR();
  1176. }
  1177. /**
  1178. * mapi_folder_gethierarchtable
  1179. * Opens the hierarchytable from a folder
  1180. * @param Resource mapifolder
  1181. *
  1182. */
  1183. ZEND_FUNCTION(mapi_folder_gethierarchytable)
  1184. {
  1185. PMEASURE_FUNC;
  1186. LOG_BEGIN();
  1187. // params
  1188. zval *res;
  1189. LPMAPIFOLDER pFolder = NULL;
  1190. long ulFlags = 0;
  1191. // return value
  1192. LPMAPITABLE lpTable = NULL;
  1193. int type = -1;
  1194. RETVAL_FALSE;
  1195. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1196. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &res, &ulFlags) == FAILURE) return;
  1197. type = Z_RES_P(res)->type;
  1198. if(type == le_mapi_folder) {
  1199. ZEND_FETCH_RESOURCE_C(pFolder, LPMAPIFOLDER, &res, -1, name_mapi_folder, le_mapi_folder);
  1200. } else if (type == le_mapi_abcont) {
  1201. ZEND_FETCH_RESOURCE_C(pFolder, LPMAPIFOLDER, &res, -1, name_mapi_abcont, le_mapi_abcont);
  1202. } else if (type == le_mapi_distlist) {
  1203. ZEND_FETCH_RESOURCE_C(pFolder, LPMAPIFOLDER, &res, -1, name_mapi_distlist, le_mapi_distlist);
  1204. } else {
  1205. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Resource is not a valid IMAPIFolder or derivative");
  1206. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1207. goto exit;
  1208. }
  1209. MAPI_G(hr) = pFolder->GetHierarchyTable(ulFlags, &lpTable);
  1210. // return the returncode
  1211. if (FAILED(MAPI_G(hr)))
  1212. goto exit;
  1213. UOBJ_REGISTER_RESOURCE(return_value, lpTable, le_mapi_table);
  1214. exit:
  1215. LOG_END();
  1216. THROW_ON_ERROR();
  1217. }
  1218. /**
  1219. * mapi_msgstore_getcontentstable
  1220. *
  1221. * @param Resource MAPIMSGStore
  1222. * @param long Flags
  1223. * @return MAPIFolder
  1224. */
  1225. ZEND_FUNCTION(mapi_folder_getcontentstable)
  1226. {
  1227. PMEASURE_FUNC;
  1228. LOG_BEGIN();
  1229. // params
  1230. zval *res = NULL;
  1231. LPMAPICONTAINER pContainer = NULL;
  1232. long ulFlags = 0;
  1233. // return value
  1234. LPMAPITABLE pTable = NULL;
  1235. // local
  1236. int type = -1;
  1237. RETVAL_FALSE;
  1238. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1239. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &res, &ulFlags) == FAILURE) return;
  1240. type = Z_RES_P(res)->type;
  1241. if(type == le_mapi_folder) {
  1242. ZEND_FETCH_RESOURCE_C(pContainer, LPMAPICONTAINER, &res, -1, name_mapi_folder, le_mapi_folder);
  1243. } else if (type == le_mapi_abcont) {
  1244. ZEND_FETCH_RESOURCE_C(pContainer, LPMAPICONTAINER, &res, -1, name_mapi_abcont, le_mapi_abcont);
  1245. } else if( type == le_mapi_distlist) {
  1246. ZEND_FETCH_RESOURCE_C(pContainer, LPMAPICONTAINER, &res, -1, name_mapi_distlist, le_mapi_distlist);
  1247. } else {
  1248. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Resource is not a valid IMAPIContainer or derivative");
  1249. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1250. goto exit;
  1251. }
  1252. MAPI_G(hr) = pContainer->GetContentsTable(ulFlags, &pTable);
  1253. if (FAILED(MAPI_G(hr)))
  1254. goto exit;
  1255. UOBJ_REGISTER_RESOURCE(return_value, pTable, le_mapi_table);
  1256. exit:
  1257. LOG_END();
  1258. THROW_ON_ERROR();
  1259. }
  1260. /**
  1261. * mapi_folder_createmessage
  1262. *
  1263. *
  1264. */
  1265. ZEND_FUNCTION(mapi_folder_createmessage)
  1266. {
  1267. PMEASURE_FUNC;
  1268. LOG_BEGIN();
  1269. // params
  1270. zval * res;
  1271. LPMAPIFOLDER pFolder = NULL;
  1272. long ulFlags = 0;
  1273. // return value
  1274. LPMESSAGE pMessage;
  1275. RETVAL_FALSE;
  1276. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1277. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &res, &ulFlags) == FAILURE) return;
  1278. ZEND_FETCH_RESOURCE_C(pFolder, LPMAPIFOLDER, &res, -1, name_mapi_folder, le_mapi_folder);
  1279. MAPI_G(hr) = pFolder->CreateMessage(NULL, ulFlags, &pMessage);
  1280. if (FAILED(MAPI_G(hr)))
  1281. goto exit;
  1282. UOBJ_REGISTER_RESOURCE(return_value, pMessage, le_mapi_message);
  1283. exit:
  1284. LOG_END();
  1285. THROW_ON_ERROR();
  1286. }
  1287. /**
  1288. * mapi_folder_deletemessage
  1289. *
  1290. *
  1291. */
  1292. ZEND_FUNCTION(mapi_folder_deletemessages)
  1293. {
  1294. PMEASURE_FUNC;
  1295. LOG_BEGIN();
  1296. // params
  1297. LPMAPIFOLDER pFolder = NULL;
  1298. zval *res = NULL;
  1299. zval *entryid_array = NULL;
  1300. long ulFlags = 0;
  1301. // local
  1302. memory_ptr<ENTRYLIST> lpEntryList;
  1303. RETVAL_FALSE;
  1304. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1305. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra|l", &res, &entryid_array, &ulFlags) == FAILURE) return;
  1306. ZEND_FETCH_RESOURCE_C(pFolder, LPMAPIFOLDER, &res, -1, name_mapi_folder, le_mapi_folder);
  1307. MAPI_G(hr) = PHPArraytoSBinaryArray(entryid_array, NULL, &~lpEntryList TSRMLS_CC);
  1308. if(MAPI_G(hr) != hrSuccess) {
  1309. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad message list");
  1310. goto exit;
  1311. }
  1312. MAPI_G(hr) = pFolder->DeleteMessages(lpEntryList, 0, NULL, ulFlags);
  1313. if(MAPI_G(hr) != hrSuccess)
  1314. goto exit;
  1315. RETVAL_TRUE;
  1316. exit:
  1317. LOG_END();
  1318. THROW_ON_ERROR();
  1319. }
  1320. /**
  1321. * Function to copy message from the source folder to the destination folder. A folder must be opened with openentry.
  1322. *
  1323. * @param SourceFolder, Message List, DestinationFolder, flags (optional)
  1324. */
  1325. ZEND_FUNCTION(mapi_folder_copymessages)
  1326. {
  1327. PMEASURE_FUNC;
  1328. LOG_BEGIN();
  1329. // params
  1330. LPMAPIFOLDER lpSrcFolder = NULL, lpDestFolder = NULL;
  1331. zval *srcFolder = NULL, *destFolder = NULL;
  1332. zval *msgArray = NULL;
  1333. long flags = 0;
  1334. // local
  1335. memory_ptr<ENTRYLIST> lpEntryList;
  1336. RETVAL_FALSE;
  1337. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1338. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rar|l", &srcFolder, &msgArray, &destFolder, &flags) == FAILURE) return;
  1339. ZEND_FETCH_RESOURCE_C(lpSrcFolder, LPMAPIFOLDER, &srcFolder, -1, name_mapi_folder, le_mapi_folder);
  1340. ZEND_FETCH_RESOURCE_C(lpDestFolder, LPMAPIFOLDER, &destFolder, -1, name_mapi_folder, le_mapi_folder);
  1341. MAPI_G(hr) = PHPArraytoSBinaryArray(msgArray, NULL, &~lpEntryList TSRMLS_CC);
  1342. if(MAPI_G(hr) != hrSuccess) {
  1343. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad message list");
  1344. goto exit;
  1345. }
  1346. MAPI_G(hr) = lpSrcFolder->CopyMessages(lpEntryList, NULL, lpDestFolder, 0, NULL, flags);
  1347. if(MAPI_G(hr) != hrSuccess)
  1348. goto exit;
  1349. RETVAL_TRUE;
  1350. exit:
  1351. LOG_END();
  1352. THROW_ON_ERROR();
  1353. }
  1354. /*
  1355. * Function to set the read flags for a folder.
  1356. *
  1357. *
  1358. */
  1359. ZEND_FUNCTION(mapi_folder_setreadflags)
  1360. {
  1361. PMEASURE_FUNC;
  1362. LOG_BEGIN();
  1363. // params
  1364. zval *res = NULL, *entryArray = NULL;
  1365. long flags = 0;
  1366. // local
  1367. LPMAPIFOLDER lpFolder = NULL;
  1368. memory_ptr<ENTRYLIST> lpEntryList;
  1369. RETVAL_FALSE;
  1370. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1371. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra|l", &res, &entryArray, &flags) == FAILURE) return;
  1372. ZEND_FETCH_RESOURCE_C(lpFolder, LPMAPIFOLDER, &res, -1, name_mapi_folder, le_mapi_folder);
  1373. MAPI_G(hr) = PHPArraytoSBinaryArray(entryArray, NULL, &~lpEntryList TSRMLS_CC);
  1374. if(MAPI_G(hr) != hrSuccess) {
  1375. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad message list");
  1376. goto exit;
  1377. }
  1378. // Special case: if an empty array was passed, treat it as NULL
  1379. if(lpEntryList->cValues != 0)
  1380. MAPI_G(hr) = lpFolder->SetReadFlags(lpEntryList, 0, NULL, flags);
  1381. else
  1382. MAPI_G(hr) = lpFolder->SetReadFlags(NULL, 0, NULL, flags);
  1383. if(MAPI_G(hr) != hrSuccess)
  1384. goto exit;
  1385. RETVAL_TRUE;
  1386. exit:
  1387. LOG_END();
  1388. THROW_ON_ERROR();
  1389. }
  1390. ZEND_FUNCTION(mapi_folder_createfolder) {
  1391. PMEASURE_FUNC;
  1392. LOG_BEGIN();
  1393. // params
  1394. LPMAPIFOLDER lpSrcFolder = NULL;
  1395. zval *srcFolder = NULL;
  1396. long folderType = FOLDER_GENERIC, ulFlags = 0;
  1397. const char *lpszFolderName = "", *lpszFolderComment = "";
  1398. size_t FolderNameLen = 0, FolderCommentLen = 0;
  1399. // return value
  1400. LPMAPIFOLDER lpNewFolder = NULL;
  1401. RETVAL_FALSE;
  1402. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1403. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|sll", &srcFolder, &lpszFolderName, &FolderNameLen, &lpszFolderComment, &FolderCommentLen, &ulFlags, &folderType) == FAILURE) return;
  1404. if (FolderNameLen == 0) {
  1405. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Foldername cannot be empty");
  1406. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1407. goto exit;
  1408. }
  1409. if (FolderCommentLen == 0) {
  1410. lpszFolderComment = NULL;
  1411. }
  1412. ZEND_FETCH_RESOURCE_C(lpSrcFolder, LPMAPIFOLDER, &srcFolder, -1, name_mapi_folder, le_mapi_folder);
  1413. MAPI_G(hr) = lpSrcFolder->CreateFolder(folderType, (LPTSTR)lpszFolderName, (LPTSTR)lpszFolderComment, NULL, ulFlags & ~MAPI_UNICODE, &lpNewFolder);
  1414. if (FAILED(MAPI_G(hr)))
  1415. goto exit;
  1416. UOBJ_REGISTER_RESOURCE(return_value, lpNewFolder, le_mapi_folder);
  1417. exit:
  1418. LOG_END();
  1419. THROW_ON_ERROR();
  1420. }
  1421. ZEND_FUNCTION(mapi_folder_deletefolder)
  1422. {
  1423. PMEASURE_FUNC;
  1424. LOG_BEGIN();
  1425. // params
  1426. ENTRYID *lpEntryID = NULL;
  1427. size_t cbEntryID = 0;
  1428. long ulFlags = 0;
  1429. zval *res = NULL;
  1430. LPMAPIFOLDER lpFolder = NULL;
  1431. RETVAL_FALSE;
  1432. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1433. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &res, &lpEntryID, &cbEntryID, &ulFlags) == FAILURE) return;
  1434. ZEND_FETCH_RESOURCE_C(lpFolder, LPMAPIFOLDER, &res, -1, name_mapi_folder, le_mapi_folder);
  1435. MAPI_G(hr) = lpFolder->DeleteFolder(cbEntryID, lpEntryID, 0, NULL, ulFlags);
  1436. if (FAILED(MAPI_G(hr)))
  1437. goto exit;
  1438. RETVAL_TRUE;
  1439. exit:
  1440. LOG_END();
  1441. THROW_ON_ERROR();
  1442. }
  1443. ZEND_FUNCTION(mapi_folder_emptyfolder)
  1444. {
  1445. PMEASURE_FUNC;
  1446. LOG_BEGIN();
  1447. // params
  1448. zval *res;
  1449. LPMAPIFOLDER lpFolder = NULL;
  1450. long ulFlags = 0;
  1451. RETVAL_FALSE;
  1452. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1453. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &res, &ulFlags) == FAILURE) return;
  1454. ZEND_FETCH_RESOURCE_C(lpFolder, LPMAPIFOLDER, &res, -1, name_mapi_folder, le_mapi_folder);
  1455. MAPI_G(hr) = lpFolder->EmptyFolder(0, NULL, ulFlags);
  1456. if (FAILED(MAPI_G(hr)))
  1457. goto exit;
  1458. RETVAL_TRUE;
  1459. exit:
  1460. LOG_END();
  1461. THROW_ON_ERROR();
  1462. }
  1463. /**
  1464. * Function that copies (or moves) a folder to another folder.
  1465. *
  1466. *
  1467. */
  1468. ZEND_FUNCTION(mapi_folder_copyfolder)
  1469. {
  1470. PMEASURE_FUNC;
  1471. LOG_BEGIN();
  1472. // params
  1473. zval *zvalSrcFolder, *zvalDestFolder;
  1474. LPMAPIFOLDER lpSrcFolder = NULL, lpDestFolder = NULL;
  1475. ENTRYID *lpEntryID = NULL;
  1476. size_t cbEntryID = 0;
  1477. long ulFlags = 0;
  1478. LPTSTR lpszNewFolderName = NULL;
  1479. size_t cbNewFolderNameLen = 0;
  1480. RETVAL_FALSE;
  1481. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1482. // Params: (SrcFolder, entryid, DestFolder, (opt) New foldername, (opt) Flags)
  1483. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsr|sl", &zvalSrcFolder, &lpEntryID, &cbEntryID, &zvalDestFolder, &lpszNewFolderName, &cbNewFolderNameLen, &ulFlags) == FAILURE) return;
  1484. ZEND_FETCH_RESOURCE_C(lpSrcFolder, LPMAPIFOLDER, &zvalSrcFolder, -1, name_mapi_folder, le_mapi_folder);
  1485. ZEND_FETCH_RESOURCE_C(lpDestFolder, LPMAPIFOLDER, &zvalDestFolder, -1, name_mapi_folder, le_mapi_folder);
  1486. if (lpEntryID == NULL) {
  1487. php_error_docref(NULL TSRMLS_CC, E_WARNING, "EntryID must not be empty.");
  1488. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1489. goto exit;
  1490. }
  1491. // If php input is NULL, lpszNewFolderName ="" but you expect a NULL string
  1492. if(cbNewFolderNameLen == 0)
  1493. lpszNewFolderName = NULL;
  1494. MAPI_G(hr) = lpSrcFolder->CopyFolder(cbEntryID, lpEntryID, NULL, lpDestFolder, lpszNewFolderName, 0, NULL, ulFlags);
  1495. if(MAPI_G(hr) != hrSuccess)
  1496. goto exit;
  1497. RETVAL_TRUE;
  1498. exit:
  1499. LOG_END();
  1500. THROW_ON_ERROR();
  1501. }
  1502. /**
  1503. * mapi_msgstore_createentryid
  1504. * Creates an EntryID to open a store with mapi_openmsgstore.
  1505. * @param Resource IMsgStore
  1506. * String username
  1507. *
  1508. * return value: EntryID or FALSE when there's no permission...?
  1509. */
  1510. ZEND_FUNCTION(mapi_msgstore_createentryid)
  1511. {
  1512. PMEASURE_FUNC;
  1513. LOG_BEGIN();
  1514. // params
  1515. zval *res;
  1516. LPMDB pMDB = NULL;
  1517. LPSTR sMailboxDN = NULL;
  1518. size_t lMailboxDN = 0;
  1519. // return value
  1520. ULONG cbEntryID = 0;
  1521. memory_ptr<ENTRYID> lpEntryID;
  1522. // local
  1523. object_ptr<IExchangeManageStore> lpEMS;
  1524. RETVAL_FALSE;
  1525. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1526. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &res, &sMailboxDN, &lMailboxDN) == FAILURE) return;
  1527. ZEND_FETCH_RESOURCE_C(pMDB, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  1528. MAPI_G(hr) = pMDB->QueryInterface(IID_IExchangeManageStore, &~lpEMS);
  1529. if(MAPI_G(hr) != hrSuccess) {
  1530. php_error_docref(NULL TSRMLS_CC, E_WARNING, "IExchangeManageStore interface was not supported by given store.");
  1531. goto exit;
  1532. }
  1533. MAPI_G(hr) = lpEMS->CreateStoreEntryID((LPTSTR)"", (LPTSTR)sMailboxDN, 0, &cbEntryID, &~lpEntryID);
  1534. if (MAPI_G(hr) != hrSuccess)
  1535. goto exit;
  1536. RETVAL_STRINGL(reinterpret_cast<const char *>(lpEntryID.get()), cbEntryID);
  1537. exit:
  1538. LOG_END();
  1539. THROW_ON_ERROR();
  1540. }
  1541. /**
  1542. * mapi_msgstore_getearchiveentryid
  1543. * Creates an EntryID to open an archive store with mapi_openmsgstore.
  1544. * @param Resource IMsgStore
  1545. * String username
  1546. * String servername (server containing the archive)
  1547. *
  1548. * return value: EntryID or FALSE when there's no permission...?
  1549. */
  1550. ZEND_FUNCTION(mapi_msgstore_getarchiveentryid)
  1551. {
  1552. PMEASURE_FUNC;
  1553. LOG_BEGIN();
  1554. // params
  1555. zval *res;
  1556. LPMDB pMDB = NULL;
  1557. LPSTR sUser = NULL;
  1558. size_t lUser = 0;
  1559. LPSTR sServer = NULL;
  1560. size_t lServer = 0;
  1561. // return value
  1562. ULONG cbEntryID = 0;
  1563. EntryIdPtr ptrEntryID;
  1564. // local
  1565. ECServiceAdminPtr ptrSA;
  1566. RETVAL_FALSE;
  1567. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1568. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &res, &sUser, &lUser, &sServer, &lServer) == FAILURE) return;
  1569. ZEND_FETCH_RESOURCE_C(pMDB, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  1570. MAPI_G(hr) = pMDB->QueryInterface(ptrSA.iid(), &~ptrSA);
  1571. if(MAPI_G(hr) != hrSuccess) {
  1572. php_error_docref(NULL TSRMLS_CC, E_WARNING, "IECServiceAdmin interface was not supported by given store.");
  1573. goto exit;
  1574. }
  1575. MAPI_G(hr) = ptrSA->GetArchiveStoreEntryID((LPTSTR)sUser, (LPTSTR)sServer, 0, &cbEntryID, &~ptrEntryID);
  1576. if (MAPI_G(hr) != hrSuccess)
  1577. goto exit;
  1578. RETVAL_STRINGL((char *)ptrEntryID.get(), cbEntryID);
  1579. exit:
  1580. LOG_END();
  1581. THROW_ON_ERROR();
  1582. }
  1583. /**
  1584. * mapi_openentry
  1585. * Opens the msgstore to get the root folder.
  1586. * @param Resource IMsgStore
  1587. * @param String EntryID
  1588. */
  1589. ZEND_FUNCTION(mapi_msgstore_openentry)
  1590. {
  1591. PMEASURE_FUNC;
  1592. LOG_BEGIN();
  1593. // params
  1594. zval *res;
  1595. LPMDB pMDB = NULL;
  1596. size_t cbEntryID = 0;
  1597. LPENTRYID lpEntryID = NULL;
  1598. long ulFlags = MAPI_BEST_ACCESS;
  1599. // return value
  1600. object_ptr<IUnknown> lpUnknown; // either folder or message
  1601. // local
  1602. ULONG ulObjType;
  1603. RETVAL_FALSE;
  1604. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1605. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|sl", &res, &lpEntryID, &cbEntryID, &ulFlags) == FAILURE) return;
  1606. ZEND_FETCH_RESOURCE_C(pMDB, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  1607. // returns a folder
  1608. MAPI_G(hr) = pMDB->OpenEntry(cbEntryID, lpEntryID, nullptr, ulFlags,
  1609. &ulObjType, &~lpUnknown);
  1610. if (FAILED(MAPI_G(hr)))
  1611. goto exit;
  1612. if (ulObjType == MAPI_FOLDER) {
  1613. UOBJ_REGISTER_RESOURCE(return_value, lpUnknown.release(), le_mapi_folder);
  1614. }
  1615. else if(ulObjType == MAPI_MESSAGE) {
  1616. UOBJ_REGISTER_RESOURCE(return_value, lpUnknown.release(), le_mapi_message);
  1617. } else {
  1618. php_error_docref(NULL TSRMLS_CC, E_WARNING, "EntryID is not a folder or a message.");
  1619. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1620. goto exit;
  1621. }
  1622. exit:
  1623. LOG_END();
  1624. THROW_ON_ERROR();
  1625. }
  1626. ZEND_FUNCTION(mapi_msgstore_entryidfromsourcekey)
  1627. {
  1628. PMEASURE_FUNC;
  1629. LOG_BEGIN();
  1630. zval *resStore = NULL;
  1631. BYTE *lpSourceKeyMessage = NULL;
  1632. size_t cbSourceKeyMessage = 0;
  1633. LPMDB lpMsgStore = NULL;
  1634. BYTE *lpSourceKeyFolder = NULL;
  1635. size_t cbSourceKeyFolder = 0;
  1636. memory_ptr<ENTRYID> lpEntryId;
  1637. ULONG cbEntryId = 0;
  1638. object_ptr<IExchangeManageStore> lpIEMS;
  1639. RETVAL_FALSE;
  1640. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1641. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|s", &resStore, &lpSourceKeyFolder, &cbSourceKeyFolder, &lpSourceKeyMessage, &cbSourceKeyMessage) == FAILURE) return;
  1642. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &resStore, -1, name_mapi_msgstore, le_mapi_msgstore);
  1643. MAPI_G(hr) = lpMsgStore->QueryInterface(IID_IExchangeManageStore, &~lpIEMS);
  1644. if(MAPI_G(hr) != hrSuccess)
  1645. goto exit;
  1646. MAPI_G(hr) = lpIEMS->EntryIDFromSourceKey(cbSourceKeyFolder, lpSourceKeyFolder, cbSourceKeyMessage, lpSourceKeyMessage, &cbEntryId, &~lpEntryId);
  1647. if(MAPI_G(hr) != hrSuccess)
  1648. goto exit;
  1649. RETVAL_STRINGL(reinterpret_cast<const char *>(lpEntryId.get()), cbEntryId);
  1650. exit:
  1651. LOG_END();
  1652. THROW_ON_ERROR();
  1653. }
  1654. ZEND_FUNCTION(mapi_msgstore_advise)
  1655. {
  1656. PMEASURE_FUNC;
  1657. LOG_BEGIN();
  1658. zval *resStore = NULL;
  1659. zval *resSink = NULL;
  1660. LPMDB lpMsgStore = NULL;
  1661. IMAPIAdviseSink *lpSink = NULL;
  1662. LPENTRYID lpEntryId = NULL;
  1663. size_t cbEntryId = 0;
  1664. long ulMask = 0;
  1665. ULONG ulConnection = 0;
  1666. RETVAL_FALSE;
  1667. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1668. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rslr", &resStore, &lpEntryId, &cbEntryId, &ulMask, &resSink) == FAILURE) return;
  1669. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &resStore, -1, name_mapi_msgstore, le_mapi_msgstore);
  1670. ZEND_FETCH_RESOURCE_C(lpSink, MAPINotifSink *, &resSink, -1, name_mapi_advisesink, le_mapi_advisesink);
  1671. // Sanitize NULL entryids
  1672. if(cbEntryId == 0) lpEntryId = NULL;
  1673. MAPI_G(hr) = lpMsgStore->Advise(cbEntryId, lpEntryId, ulMask, lpSink, &ulConnection);
  1674. if(MAPI_G(hr) != hrSuccess)
  1675. goto exit;
  1676. RETVAL_LONG(ulConnection);
  1677. exit:
  1678. LOG_END();
  1679. THROW_ON_ERROR();
  1680. }
  1681. ZEND_FUNCTION(mapi_msgstore_unadvise)
  1682. {
  1683. PMEASURE_FUNC;
  1684. LOG_BEGIN();
  1685. zval *resStore = NULL;
  1686. LPMDB lpMsgStore = NULL;
  1687. long ulConnection = 0;
  1688. RETVAL_FALSE;
  1689. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1690. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &resStore, &ulConnection) == FAILURE) return;
  1691. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &resStore, -1, name_mapi_msgstore, le_mapi_msgstore);
  1692. MAPI_G(hr) = lpMsgStore->Unadvise(ulConnection);
  1693. if(MAPI_G(hr) != hrSuccess)
  1694. goto exit;
  1695. RETVAL_TRUE;
  1696. exit:
  1697. LOG_END();
  1698. THROW_ON_ERROR();
  1699. }
  1700. ZEND_FUNCTION(mapi_sink_create)
  1701. {
  1702. PMEASURE_FUNC;
  1703. LOG_BEGIN();
  1704. MAPINotifSink *lpSink = NULL;
  1705. RETVAL_FALSE;
  1706. MAPI_G(hr) = MAPINotifSink::Create(&lpSink);
  1707. UOBJ_REGISTER_RESOURCE(return_value, lpSink, le_mapi_advisesink);
  1708. LOG_END();
  1709. }
  1710. ZEND_FUNCTION(mapi_sink_timedwait)
  1711. {
  1712. PMEASURE_FUNC;
  1713. LOG_BEGIN();
  1714. zval *resSink = NULL;
  1715. zval notifications;
  1716. long ulTime = 0;
  1717. MAPINotifSink *lpSink = NULL;
  1718. ULONG cNotifs = 0;
  1719. memory_ptr<NOTIFICATION> lpNotifs;
  1720. RETVAL_FALSE;
  1721. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1722. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &resSink, &ulTime) == FAILURE) return;
  1723. ZEND_FETCH_RESOURCE_C(lpSink, MAPINotifSink *, &resSink, -1, name_mapi_advisesink, le_mapi_advisesink);
  1724. MAPI_G(hr) = lpSink->GetNotifications(&cNotifs, &~lpNotifs, false, ulTime);
  1725. if(MAPI_G(hr) != hrSuccess)
  1726. goto exit;
  1727. MAPI_G(hr) = NotificationstoPHPArray(cNotifs, lpNotifs, &notifications TSRMLS_CC);
  1728. if(MAPI_G(hr) != hrSuccess) {
  1729. php_error_docref(NULL TSRMLS_CC, E_WARNING, "The notifications could not be converted to a PHP array");
  1730. goto exit;
  1731. }
  1732. RETVAL_ZVAL(&notifications, 0, 0);
  1733. exit:
  1734. LOG_END();
  1735. THROW_ON_ERROR();
  1736. }
  1737. /**
  1738. * mapi_table_hrqueryallrows
  1739. * Execute htqueryallrows on a table
  1740. * @param Resource MAPITable
  1741. * @return Array
  1742. */
  1743. ZEND_FUNCTION(mapi_table_queryallrows)
  1744. {
  1745. PMEASURE_FUNC;
  1746. LOG_BEGIN();
  1747. // params
  1748. zval *res = NULL;
  1749. zval *tagArray = NULL;
  1750. zval *restrictionArray = NULL;
  1751. zval rowset;
  1752. LPMAPITABLE lpTable = NULL;
  1753. // return value
  1754. // locals
  1755. memory_ptr<SPropTagArray> lpTagArray;
  1756. memory_ptr<SRestriction> lpRestrict;
  1757. rowset_ptr pRowSet;
  1758. RETVAL_FALSE;
  1759. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1760. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|aa", &res, &tagArray, &restrictionArray) == FAILURE) return;
  1761. ZEND_FETCH_RESOURCE_C(lpTable, LPMAPITABLE, &res, -1, name_mapi_table, le_mapi_table);
  1762. if (restrictionArray != NULL) {
  1763. // create restrict array
  1764. MAPI_G(hr) = MAPIAllocateBuffer(sizeof(SRestriction), &~lpRestrict);
  1765. if (MAPI_G(hr) != hrSuccess)
  1766. goto exit;
  1767. MAPI_G(hr) = PHPArraytoSRestriction(restrictionArray, /* result */lpRestrict, /* Base */lpRestrict TSRMLS_CC);
  1768. if (MAPI_G(hr) != hrSuccess) {
  1769. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to convert the PHP srestriction array");
  1770. goto exit;
  1771. }
  1772. }
  1773. if (tagArray != NULL) {
  1774. // create proptag array
  1775. MAPI_G(hr) = PHPArraytoPropTagArray(tagArray, NULL, &~lpTagArray TSRMLS_CC);
  1776. if (MAPI_G(hr) != hrSuccess) {
  1777. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to convert the PHP proptag array");
  1778. goto exit;
  1779. }
  1780. }
  1781. // Execute
  1782. MAPI_G(hr) = HrQueryAllRows(lpTable, lpTagArray, lpRestrict, nullptr, 0, &~pRowSet);
  1783. // return the returncode
  1784. if (FAILED(MAPI_G(hr)))
  1785. goto exit;
  1786. MAPI_G(hr) = RowSettoPHPArray(pRowSet, &rowset TSRMLS_CC);
  1787. if(MAPI_G(hr) != hrSuccess) {
  1788. php_error_docref(NULL TSRMLS_CC, E_WARNING, "The resulting rowset could not be converted to a PHP array");
  1789. goto exit;
  1790. }
  1791. RETVAL_ZVAL(&rowset, 0, 0);
  1792. exit:
  1793. LOG_END();
  1794. THROW_ON_ERROR();
  1795. }
  1796. /**
  1797. * mapi_table_queryrows
  1798. * Execute queryrows on a table
  1799. * @param Resource MAPITable
  1800. * @param long
  1801. * @param array
  1802. * @return array
  1803. */
  1804. ZEND_FUNCTION(mapi_table_queryrows)
  1805. {
  1806. PMEASURE_FUNC;
  1807. LOG_BEGIN();
  1808. // params
  1809. zval *res = NULL;
  1810. LPMAPITABLE lpTable = NULL;
  1811. zval *tagArray = NULL;
  1812. zval rowset;
  1813. memory_ptr<SPropTagArray> lpTagArray;
  1814. long lRowCount = 0, start = 0;
  1815. // local
  1816. rowset_ptr pRowSet;
  1817. RETVAL_FALSE;
  1818. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1819. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|a!ll", &res, &tagArray, &start, &lRowCount) == FAILURE) return;
  1820. ZEND_FETCH_RESOURCE_C(lpTable, LPMAPITABLE, &res, -1, name_mapi_table, le_mapi_table);
  1821. if (tagArray != NULL) {
  1822. MAPI_G(hr) = PHPArraytoPropTagArray(tagArray, NULL, &~lpTagArray TSRMLS_CC);
  1823. if (MAPI_G(hr) != hrSuccess) {
  1824. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to convert the PHP Array");
  1825. goto exit;
  1826. }
  1827. MAPI_G(hr) = lpTable->SetColumns(lpTagArray, TBL_BATCH);
  1828. if (FAILED(MAPI_G(hr))) {
  1829. php_error_docref(NULL TSRMLS_CC, E_WARNING, "SetColumns failed. Error code %08X", MAPI_G(hr));
  1830. goto exit;
  1831. }
  1832. }
  1833. // move to the starting row if there is one
  1834. if (start != 0) {
  1835. MAPI_G(hr) = lpTable->SeekRow(BOOKMARK_BEGINNING, start, NULL);
  1836. if (FAILED(MAPI_G(hr))) {
  1837. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Seekrow failed. Error code %08X", MAPI_G(hr));
  1838. goto exit;
  1839. }
  1840. }
  1841. MAPI_G(hr) = lpTable->QueryRows(lRowCount, 0, &~pRowSet);
  1842. if (FAILED(MAPI_G(hr)))
  1843. goto exit;
  1844. MAPI_G(hr) = RowSettoPHPArray(pRowSet, &rowset TSRMLS_CC);
  1845. if(MAPI_G(hr) != hrSuccess) {
  1846. php_error_docref(NULL TSRMLS_CC, E_WARNING, "The resulting rowset could not be converted to a PHP array");
  1847. goto exit;
  1848. }
  1849. RETVAL_ZVAL(&rowset, 0, 0);
  1850. exit:
  1851. LOG_END();
  1852. THROW_ON_ERROR();
  1853. }
  1854. /**
  1855. * mapi_table_setcolumns
  1856. * Execute setcolumns on a table
  1857. * @param Resource MAPITable
  1858. * @param array column set
  1859. * @return true/false
  1860. */
  1861. ZEND_FUNCTION(mapi_table_setcolumns)
  1862. {
  1863. PMEASURE_FUNC;
  1864. LOG_BEGIN();
  1865. // params
  1866. zval *res = NULL;
  1867. LPMAPITABLE lpTable = NULL;
  1868. zval *tagArray = NULL;
  1869. long lFlags = 0;
  1870. // local
  1871. memory_ptr<SPropTagArray> lpTagArray;
  1872. RETVAL_FALSE;
  1873. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1874. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra|l", &res, &tagArray, &lFlags) == FAILURE) return;
  1875. ZEND_FETCH_RESOURCE_C(lpTable, LPMAPITABLE, &res, -1, name_mapi_table, le_mapi_table);
  1876. MAPI_G(hr) = PHPArraytoPropTagArray(tagArray, NULL, &~lpTagArray TSRMLS_CC);
  1877. if (MAPI_G(hr) != hrSuccess) {
  1878. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to convert the PHP Array");
  1879. goto exit;
  1880. }
  1881. MAPI_G(hr) = lpTable->SetColumns(lpTagArray, lFlags);
  1882. if (FAILED(MAPI_G(hr))) {
  1883. php_error_docref(NULL TSRMLS_CC, E_WARNING, "SetColumns failed. Error code %08X", MAPI_G(hr));
  1884. goto exit;
  1885. }
  1886. RETVAL_TRUE;
  1887. exit:
  1888. LOG_END();
  1889. THROW_ON_ERROR();
  1890. }
  1891. /**
  1892. * mapi_table_seekrow
  1893. * Execute seekrow on a table
  1894. * @param Resource MAPITable
  1895. * @param long bookmark
  1896. * @param long Flags
  1897. * @return long RowsSought
  1898. */
  1899. ZEND_FUNCTION(mapi_table_seekrow)
  1900. {
  1901. PMEASURE_FUNC;
  1902. LOG_BEGIN();
  1903. // params
  1904. zval *res = NULL;
  1905. LPMAPITABLE lpTable = NULL;
  1906. long lRowCount = 0, lbookmark = BOOKMARK_BEGINNING;
  1907. // return
  1908. long lRowsSought = 0;
  1909. RETVAL_FALSE;
  1910. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1911. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll", &res, &lbookmark, &lRowCount) == FAILURE) return;
  1912. ZEND_FETCH_RESOURCE_C(lpTable, LPMAPITABLE, &res, -1, name_mapi_table, le_mapi_table);
  1913. MAPI_G(hr) = lpTable->SeekRow((BOOKMARK)lbookmark, lRowCount, (LONG*)&lRowsSought);
  1914. if (FAILED(MAPI_G(hr))) {
  1915. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Seekrow failed. Error code %08X", MAPI_G(hr));
  1916. goto exit;
  1917. }
  1918. RETVAL_LONG(lRowsSought);
  1919. exit:
  1920. LOG_END();
  1921. THROW_ON_ERROR();
  1922. }
  1923. /**
  1924. *
  1925. *
  1926. *
  1927. */
  1928. ZEND_FUNCTION(mapi_table_sort)
  1929. {
  1930. PMEASURE_FUNC;
  1931. LOG_BEGIN();
  1932. // params
  1933. zval * res;
  1934. zval * sortArray;
  1935. long ulFlags = 0;
  1936. // local
  1937. LPMAPITABLE lpTable = NULL;
  1938. memory_ptr<SSortOrderSet> lpSortCriteria;
  1939. RETVAL_FALSE;
  1940. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1941. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra|l", &res, &sortArray, &ulFlags) == FAILURE) return;
  1942. ZEND_FETCH_RESOURCE_C(lpTable, LPMAPITABLE, &res, -1, name_mapi_table, le_mapi_table);
  1943. MAPI_G(hr) = PHPArraytoSortOrderSet(sortArray, NULL, &~lpSortCriteria TSRMLS_CC);
  1944. if(MAPI_G(hr) != hrSuccess)
  1945. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to convert sort order set from the PHP array");
  1946. MAPI_G(hr) = lpTable->SortTable(lpSortCriteria, ulFlags);
  1947. if (FAILED(MAPI_G(hr)))
  1948. goto exit;
  1949. RETVAL_TRUE;
  1950. exit:
  1951. LOG_END();
  1952. THROW_ON_ERROR();
  1953. }
  1954. /**
  1955. *
  1956. *
  1957. *
  1958. */
  1959. ZEND_FUNCTION(mapi_table_getrowcount)
  1960. {
  1961. PMEASURE_FUNC;
  1962. LOG_BEGIN();
  1963. // params
  1964. zval *res;
  1965. LPMAPITABLE lpTable = NULL;
  1966. // return value
  1967. ULONG count = 0;
  1968. RETVAL_FALSE;
  1969. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1970. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &res) == FAILURE) return;
  1971. ZEND_FETCH_RESOURCE_C(lpTable, LPMAPITABLE, &res, -1, name_mapi_table, le_mapi_table);
  1972. MAPI_G(hr) = lpTable->GetRowCount(0, &count);
  1973. if (FAILED(MAPI_G(hr)))
  1974. goto exit;
  1975. RETVAL_LONG(count);
  1976. exit:
  1977. LOG_END();
  1978. THROW_ON_ERROR();
  1979. }
  1980. /**
  1981. *
  1982. *
  1983. *
  1984. */
  1985. ZEND_FUNCTION(mapi_table_restrict)
  1986. {
  1987. PMEASURE_FUNC;
  1988. LOG_BEGIN();
  1989. // params
  1990. zval *res;
  1991. zval *restrictionArray;
  1992. ulong ulFlags = 0;
  1993. // local
  1994. LPMAPITABLE lpTable = NULL;
  1995. memory_ptr<SRestriction> lpRestrict;
  1996. RETVAL_FALSE;
  1997. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  1998. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra|l", &res, &restrictionArray, &ulFlags) == FAILURE) return;
  1999. ZEND_FETCH_RESOURCE_C(lpTable, LPMAPITABLE, &res, -1, name_mapi_table, le_mapi_table);
  2000. if (!restrictionArray || zend_hash_num_elements(Z_ARRVAL_P(restrictionArray)) == 0) {
  2001. // reset restriction
  2002. lpRestrict.reset();
  2003. } else {
  2004. // create restrict array
  2005. MAPI_G(hr) = PHPArraytoSRestriction(restrictionArray, NULL, &~lpRestrict TSRMLS_CC);
  2006. if (MAPI_G(hr) != hrSuccess) {
  2007. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to convert the PHP srestriction Array");
  2008. goto exit;
  2009. }
  2010. }
  2011. MAPI_G(hr) = lpTable->Restrict(lpRestrict, ulFlags);
  2012. if(MAPI_G(hr) != hrSuccess)
  2013. goto exit;
  2014. RETVAL_TRUE;
  2015. exit:
  2016. LOG_END();
  2017. THROW_ON_ERROR();
  2018. }
  2019. ZEND_FUNCTION(mapi_table_findrow)
  2020. {
  2021. PMEASURE_FUNC;
  2022. LOG_BEGIN();
  2023. // params
  2024. zval *res;
  2025. zval *restrictionArray;
  2026. ulong bkOrigin = BOOKMARK_BEGINNING;
  2027. ulong ulFlags = 0;
  2028. // local
  2029. LPMAPITABLE lpTable = NULL;
  2030. memory_ptr<SRestriction> lpRestrict;
  2031. ULONG ulRow = 0;
  2032. ULONG ulNumerator = 0;
  2033. ULONG ulDenominator = 0;
  2034. RETVAL_FALSE;
  2035. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2036. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra|ll", &res, &restrictionArray, &bkOrigin, &ulFlags) == FAILURE) return;
  2037. ZEND_FETCH_RESOURCE_C(lpTable, LPMAPITABLE, &res, -1, name_mapi_table, le_mapi_table);
  2038. if (!restrictionArray || zend_hash_num_elements(Z_ARRVAL_P(restrictionArray)) == 0) {
  2039. // reset restriction
  2040. lpRestrict.reset();
  2041. } else {
  2042. // create restrict array
  2043. MAPI_G(hr) = PHPArraytoSRestriction(restrictionArray, NULL, &~lpRestrict TSRMLS_CC);
  2044. if (MAPI_G(hr) != hrSuccess) {
  2045. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to convert the PHP srestriction Array");
  2046. goto exit;
  2047. }
  2048. }
  2049. MAPI_G(hr) = lpTable->FindRow(lpRestrict, bkOrigin, ulFlags);
  2050. if(MAPI_G(hr) != hrSuccess)
  2051. goto exit;
  2052. MAPI_G(hr) = lpTable->QueryPosition(&ulRow, &ulNumerator, &ulDenominator);
  2053. if (FAILED(MAPI_G(hr)))
  2054. goto exit;
  2055. RETVAL_LONG(ulRow);
  2056. exit:
  2057. LOG_END();
  2058. THROW_ON_ERROR();
  2059. }
  2060. /**
  2061. * mapi_table_createbookmark
  2062. * Execute create bookmark on a table
  2063. * @param Resource MAPITable
  2064. * @return long bookmark
  2065. */
  2066. ZEND_FUNCTION(mapi_table_createbookmark)
  2067. {
  2068. PMEASURE_FUNC;
  2069. LOG_BEGIN();
  2070. // params
  2071. zval *res = NULL;
  2072. LPMAPITABLE lpTable = NULL;
  2073. // return
  2074. long lbookmark = 0;
  2075. RETVAL_FALSE;
  2076. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2077. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &res) == FAILURE) return;
  2078. ZEND_FETCH_RESOURCE_C(lpTable, LPMAPITABLE, &res, -1, name_mapi_table, le_mapi_table);
  2079. MAPI_G(hr) = lpTable->CreateBookmark((BOOKMARK*)&lbookmark);
  2080. if (FAILED(MAPI_G(hr))) {
  2081. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Create bookmark failed. Error code %08X", MAPI_G(hr));
  2082. goto exit;
  2083. }
  2084. RETVAL_LONG(lbookmark);
  2085. exit:
  2086. LOG_END();
  2087. THROW_ON_ERROR();
  2088. }
  2089. /**
  2090. * mapi_table_freebookmark
  2091. * Execute free bookmark on a table
  2092. * @param Resource MAPITable
  2093. * @param long bookmark
  2094. * @return true/false
  2095. */
  2096. ZEND_FUNCTION(mapi_table_freebookmark)
  2097. {
  2098. PMEASURE_FUNC;
  2099. LOG_BEGIN();
  2100. // params
  2101. zval *res = NULL;
  2102. LPMAPITABLE lpTable = NULL;
  2103. long lbookmark = 0;
  2104. RETVAL_FALSE;
  2105. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2106. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &res, &lbookmark) == FAILURE) return;
  2107. ZEND_FETCH_RESOURCE_C(lpTable, LPMAPITABLE, &res, -1, name_mapi_table, le_mapi_table);
  2108. MAPI_G(hr) = lpTable->FreeBookmark((BOOKMARK)lbookmark);
  2109. if (FAILED(MAPI_G(hr))) {
  2110. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Free bookmark failed. Error code %08X", MAPI_G(hr));
  2111. goto exit;
  2112. }
  2113. RETVAL_TRUE;
  2114. exit:
  2115. LOG_END();
  2116. THROW_ON_ERROR();
  2117. }
  2118. /**
  2119. * mapi_msgstore_getreceivefolder
  2120. *
  2121. * @param Resource MAPIMSGStore
  2122. * @return MAPIFolder
  2123. */
  2124. ZEND_FUNCTION(mapi_msgstore_getreceivefolder)
  2125. {
  2126. PMEASURE_FUNC;
  2127. LOG_BEGIN();
  2128. // params
  2129. zval *res;
  2130. LPMDB pMDB = NULL;
  2131. // return value
  2132. LPUNKNOWN lpFolder = NULL;
  2133. // locals
  2134. ULONG cbEntryID = 0;
  2135. memory_ptr<ENTRYID> lpEntryID;
  2136. ULONG ulObjType = 0;
  2137. RETVAL_FALSE;
  2138. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2139. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &res) == FAILURE) return;
  2140. ZEND_FETCH_RESOURCE_C(pMDB, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  2141. MAPI_G(hr) = pMDB->GetReceiveFolder(NULL, 0, &cbEntryID, &~lpEntryID, NULL);
  2142. if(FAILED(MAPI_G(hr)))
  2143. goto exit;
  2144. MAPI_G(hr) = pMDB->OpenEntry(cbEntryID, lpEntryID, NULL, MAPI_BEST_ACCESS, &ulObjType, (LPUNKNOWN*)&lpFolder);
  2145. if(MAPI_G(hr) != hrSuccess)
  2146. goto exit;
  2147. UOBJ_REGISTER_RESOURCE(return_value, lpFolder, le_mapi_folder);
  2148. exit:
  2149. LOG_END();
  2150. THROW_ON_ERROR();
  2151. }
  2152. /**
  2153. * mapi_msgstore_openmultistoretable
  2154. *
  2155. * @param Resource MAPIMSGStore
  2156. * @param Array EntryIdList
  2157. * @param Long Flags
  2158. * @return MAPITable
  2159. */
  2160. ZEND_FUNCTION(mapi_msgstore_openmultistoretable)
  2161. {
  2162. PMEASURE_FUNC;
  2163. LOG_BEGIN();
  2164. // params
  2165. zval *res;
  2166. zval *entryid_array = NULL;
  2167. LPMDB lpMDB = NULL;
  2168. long ulFlags = 0;
  2169. // return value
  2170. LPMAPITABLE lpMultiTable = NULL;
  2171. // locals
  2172. object_ptr<IECMultiStoreTable> lpECMST;
  2173. memory_ptr<ENTRYLIST> lpEntryList;
  2174. IECUnknown *lpUnknown = NULL;
  2175. RETVAL_FALSE;
  2176. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2177. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra|l", &res, &entryid_array, &ulFlags) == FAILURE) return;
  2178. ZEND_FETCH_RESOURCE_C(lpMDB, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  2179. MAPI_G(hr) = PHPArraytoSBinaryArray(entryid_array, NULL, &~lpEntryList TSRMLS_CC);
  2180. if(MAPI_G(hr) != hrSuccess) {
  2181. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad message list");
  2182. goto exit;
  2183. }
  2184. MAPI_G(hr) = GetECObject(lpMDB, &lpUnknown TSRMLS_CC);
  2185. if(MAPI_G(hr) != hrSuccess) {
  2186. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano object");
  2187. goto exit;
  2188. }
  2189. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECMultiStoreTable, &~lpECMST);
  2190. if (FAILED(MAPI_G(hr)))
  2191. goto exit;
  2192. MAPI_G(hr) = lpECMST->OpenMultiStoreTable(lpEntryList, ulFlags, &lpMultiTable);
  2193. if (FAILED(MAPI_G(hr)))
  2194. goto exit;
  2195. UOBJ_REGISTER_RESOURCE(return_value, lpMultiTable, le_mapi_table);
  2196. exit:
  2197. LOG_END();
  2198. THROW_ON_ERROR();
  2199. }
  2200. /**
  2201. * mapi_message_modifyrecipients
  2202. * @param resource
  2203. * @param flags
  2204. * @param array
  2205. */
  2206. ZEND_FUNCTION(mapi_message_modifyrecipients)
  2207. {
  2208. PMEASURE_FUNC;
  2209. LOG_BEGIN();
  2210. // params
  2211. zval *res, *adrlist;
  2212. LPMESSAGE pMessage = NULL;
  2213. long flags = MODRECIP_ADD; // flags to use, default to ADD
  2214. // local
  2215. adrlist_ptr lpListRecipients;
  2216. RETVAL_FALSE;
  2217. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2218. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rla", &res, &flags, &adrlist) == FAILURE) return;
  2219. ZEND_FETCH_RESOURCE_C(pMessage, LPMESSAGE, &res, -1, name_mapi_message, le_mapi_message);
  2220. MAPI_G(hr) = PHPArraytoAdrList(adrlist, nullptr, &~lpListRecipients TSRMLS_CC);
  2221. if (MAPI_G(hr) != hrSuccess) {
  2222. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse recipient list");
  2223. goto exit;
  2224. }
  2225. MAPI_G(hr) = pMessage->ModifyRecipients(flags, lpListRecipients);
  2226. if (FAILED(MAPI_G(hr)))
  2227. goto exit;
  2228. RETVAL_TRUE;
  2229. exit:
  2230. LOG_END();
  2231. THROW_ON_ERROR();
  2232. }
  2233. /**
  2234. * mapi_message_submitmessage
  2235. *
  2236. *
  2237. */
  2238. ZEND_FUNCTION(mapi_message_submitmessage)
  2239. {
  2240. PMEASURE_FUNC;
  2241. LOG_BEGIN();
  2242. // params
  2243. zval * res;
  2244. LPMESSAGE pMessage = NULL;
  2245. RETVAL_FALSE;
  2246. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2247. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &res) == FAILURE) return;
  2248. ZEND_FETCH_RESOURCE_C(pMessage, LPMESSAGE, &res, -1, name_mapi_message, le_mapi_message);
  2249. MAPI_G(hr) = pMessage->SubmitMessage(0);
  2250. if (FAILED(MAPI_G(hr)))
  2251. goto exit;
  2252. RETVAL_TRUE;
  2253. exit:
  2254. LOG_END();
  2255. THROW_ON_ERROR();
  2256. }
  2257. /**
  2258. * mapi_message_getattachmenttable
  2259. * @return MAPITable
  2260. *
  2261. */
  2262. ZEND_FUNCTION(mapi_message_getattachmenttable)
  2263. {
  2264. PMEASURE_FUNC;
  2265. LOG_BEGIN();
  2266. // params
  2267. zval * res = NULL;
  2268. LPMESSAGE pMessage = NULL;
  2269. // return value
  2270. LPMAPITABLE pTable = NULL;
  2271. RETVAL_FALSE;
  2272. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2273. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &res) == FAILURE) return;
  2274. ZEND_FETCH_RESOURCE_C(pMessage, LPMESSAGE, &res, -1, name_mapi_message, le_mapi_message);
  2275. MAPI_G(hr) = pMessage->GetAttachmentTable(0, &pTable);
  2276. if (FAILED(MAPI_G(hr)))
  2277. goto exit;
  2278. UOBJ_REGISTER_RESOURCE(return_value, pTable, le_mapi_table);
  2279. exit:
  2280. LOG_END();
  2281. THROW_ON_ERROR();
  2282. }
  2283. /**
  2284. * Opens a attachment
  2285. * @param Message resource
  2286. * @param Attachment number
  2287. * @return Attachment resource
  2288. */
  2289. ZEND_FUNCTION(mapi_message_openattach)
  2290. {
  2291. PMEASURE_FUNC;
  2292. LOG_BEGIN();
  2293. // params
  2294. zval *res = NULL;
  2295. LPMESSAGE pMessage = NULL;
  2296. long attach_num = 0;
  2297. // return value
  2298. LPATTACH pAttach = NULL;
  2299. RETVAL_FALSE;
  2300. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2301. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &res, &attach_num) == FAILURE) return;
  2302. ZEND_FETCH_RESOURCE_C(pMessage, LPMESSAGE, &res, -1, name_mapi_message, le_mapi_message);
  2303. MAPI_G(hr) = pMessage->OpenAttach(attach_num, NULL, MAPI_BEST_ACCESS, &pAttach);
  2304. if (FAILED(MAPI_G(hr)))
  2305. goto exit;
  2306. UOBJ_REGISTER_RESOURCE(return_value, pAttach, le_mapi_attachment);
  2307. exit:
  2308. LOG_END();
  2309. THROW_ON_ERROR();
  2310. }
  2311. ZEND_FUNCTION(mapi_message_createattach)
  2312. {
  2313. PMEASURE_FUNC;
  2314. LOG_BEGIN();
  2315. // params
  2316. zval *zvalMessage = NULL;
  2317. LPMESSAGE lpMessage = NULL;
  2318. long ulFlags = 0;
  2319. // return value
  2320. LPATTACH lpAttach = NULL;
  2321. // local
  2322. ULONG attachNum = 0;
  2323. RETVAL_FALSE;
  2324. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2325. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &zvalMessage, &ulFlags) == FAILURE) return;
  2326. ZEND_FETCH_RESOURCE_C(lpMessage, LPMESSAGE, &zvalMessage, -1, name_mapi_message, le_mapi_message);
  2327. MAPI_G(hr) = lpMessage->CreateAttach(NULL, ulFlags, &attachNum, &lpAttach);
  2328. if (FAILED(MAPI_G(hr)))
  2329. goto exit;
  2330. UOBJ_REGISTER_RESOURCE(return_value, lpAttach, le_mapi_attachment);
  2331. exit:
  2332. LOG_END();
  2333. THROW_ON_ERROR();
  2334. }
  2335. ZEND_FUNCTION(mapi_message_deleteattach)
  2336. {
  2337. PMEASURE_FUNC;
  2338. LOG_BEGIN();
  2339. // params
  2340. zval *zvalMessage = NULL;
  2341. LPMESSAGE lpMessage = NULL;
  2342. long ulFlags = 0, attachNum = 0;
  2343. RETVAL_FALSE;
  2344. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2345. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|l", &zvalMessage, &attachNum, &ulFlags) == FAILURE) return;
  2346. ZEND_FETCH_RESOURCE_C(lpMessage, LPMESSAGE, &zvalMessage, -1, name_mapi_message, le_mapi_message);
  2347. MAPI_G(hr) = lpMessage->DeleteAttach(attachNum, 0, NULL, ulFlags);
  2348. if (FAILED(MAPI_G(hr)))
  2349. goto exit;
  2350. RETVAL_TRUE;
  2351. exit:
  2352. LOG_END();
  2353. THROW_ON_ERROR();
  2354. }
  2355. ZEND_FUNCTION(mapi_stream_read)
  2356. {
  2357. PMEASURE_FUNC;
  2358. LOG_BEGIN();
  2359. // params
  2360. zval *res = NULL;
  2361. LPSTREAM pStream = NULL;
  2362. unsigned long lgetBytes = 0;
  2363. // return value
  2364. std::unique_ptr<char[]> buf;
  2365. ULONG actualRead = 0;
  2366. RETVAL_FALSE;
  2367. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2368. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &res, &lgetBytes) == FAILURE) return;
  2369. ZEND_FETCH_RESOURCE_C(pStream, LPSTREAM, &res, -1, name_istream, le_istream);
  2370. buf.reset(new char[lgetBytes]);
  2371. MAPI_G(hr) = pStream->Read(buf.get(), lgetBytes, &actualRead);
  2372. if (MAPI_G(hr) != hrSuccess)
  2373. goto exit;
  2374. RETVAL_STRINGL(buf.get(), actualRead);
  2375. exit:
  2376. LOG_END();
  2377. THROW_ON_ERROR();
  2378. }
  2379. ZEND_FUNCTION(mapi_stream_seek)
  2380. {
  2381. PMEASURE_FUNC;
  2382. LOG_BEGIN();
  2383. // params
  2384. zval *res = NULL;
  2385. LPSTREAM pStream = NULL;
  2386. long moveBytes = 0, seekFlag = STREAM_SEEK_CUR;
  2387. // local
  2388. LARGE_INTEGER move;
  2389. ULARGE_INTEGER newPos;
  2390. RETVAL_FALSE;
  2391. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2392. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|l", &res, &moveBytes, &seekFlag) == FAILURE) return;
  2393. ZEND_FETCH_RESOURCE_C(pStream, LPSTREAM, &res, -1, name_istream, le_istream);
  2394. move.QuadPart = moveBytes;
  2395. MAPI_G(hr) = pStream->Seek(move, seekFlag, &newPos);
  2396. if (FAILED(MAPI_G(hr)))
  2397. goto exit;
  2398. RETVAL_TRUE;
  2399. exit:
  2400. LOG_END();
  2401. THROW_ON_ERROR();
  2402. }
  2403. ZEND_FUNCTION(mapi_stream_setsize)
  2404. {
  2405. PMEASURE_FUNC;
  2406. LOG_BEGIN();
  2407. // params
  2408. zval *res = NULL;
  2409. LPSTREAM pStream = NULL;
  2410. long newSize = 0;
  2411. // local
  2412. ULARGE_INTEGER libNewSize = { { 0 } };
  2413. RETVAL_FALSE;
  2414. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2415. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &res, &newSize) == FAILURE) return;
  2416. ZEND_FETCH_RESOURCE_C(pStream, LPSTREAM, &res, -1, name_istream, le_istream);
  2417. libNewSize.QuadPart = newSize;
  2418. MAPI_G(hr) = pStream->SetSize(libNewSize);
  2419. if (FAILED(MAPI_G(hr)))
  2420. goto exit;
  2421. RETVAL_TRUE;
  2422. exit:
  2423. LOG_END();
  2424. THROW_ON_ERROR();
  2425. }
  2426. ZEND_FUNCTION(mapi_stream_commit)
  2427. {
  2428. PMEASURE_FUNC;
  2429. LOG_BEGIN();
  2430. // params
  2431. zval *res = NULL;
  2432. LPSTREAM pStream = NULL;
  2433. RETVAL_FALSE;
  2434. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2435. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &res) == FAILURE) return;
  2436. ZEND_FETCH_RESOURCE_C(pStream, LPSTREAM, &res, -1, name_istream, le_istream);
  2437. MAPI_G(hr) = pStream->Commit(0);
  2438. if (FAILED(MAPI_G(hr)))
  2439. goto exit;
  2440. RETVAL_TRUE;
  2441. exit:
  2442. LOG_END();
  2443. THROW_ON_ERROR();
  2444. }
  2445. ZEND_FUNCTION(mapi_stream_write)
  2446. {
  2447. PMEASURE_FUNC;
  2448. LOG_BEGIN();
  2449. // params
  2450. zval *res = NULL;
  2451. LPSTREAM pStream = NULL;
  2452. char *pv = NULL;
  2453. size_t cb = 0;
  2454. // return value
  2455. ULONG pcbWritten = 0;
  2456. RETVAL_FALSE;
  2457. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2458. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &res, &pv, &cb) == FAILURE) return;
  2459. ZEND_FETCH_RESOURCE_C(pStream, LPSTREAM, &res, -1, name_istream, le_istream);
  2460. MAPI_G(hr) = pStream->Write(pv, cb, &pcbWritten);
  2461. if (MAPI_G(hr) != hrSuccess)
  2462. goto exit;
  2463. RETVAL_LONG(pcbWritten);
  2464. exit:
  2465. LOG_END();
  2466. THROW_ON_ERROR();
  2467. }
  2468. // FIXME: Add more output in the array
  2469. ZEND_FUNCTION(mapi_stream_stat)
  2470. {
  2471. PMEASURE_FUNC;
  2472. LOG_BEGIN();
  2473. // params
  2474. zval *res = NULL;
  2475. LPSTREAM pStream = NULL;
  2476. // return value
  2477. ULONG cb = 0;
  2478. // local
  2479. STATSTG stg = { 0 };
  2480. RETVAL_FALSE;
  2481. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2482. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &res) == FAILURE) return;
  2483. ZEND_FETCH_RESOURCE_C(pStream, LPSTREAM, &res, -1, name_istream, le_istream);
  2484. MAPI_G(hr) = pStream->Stat(&stg,STATFLAG_NONAME);
  2485. if(MAPI_G(hr) != hrSuccess)
  2486. goto exit;
  2487. cb = stg.cbSize.LowPart;
  2488. array_init(return_value);
  2489. add_assoc_long(return_value, "cb", cb);
  2490. exit:
  2491. LOG_END();
  2492. THROW_ON_ERROR();
  2493. }
  2494. /* Create a new in-memory IStream interface. Useful only to write stuff to and then
  2495. * read it back again. Kind of defeats the purpose of the memory usage limits in PHP though ..
  2496. */
  2497. ZEND_FUNCTION(mapi_stream_create)
  2498. {
  2499. PMEASURE_FUNC;
  2500. LOG_BEGIN();
  2501. object_ptr<ECMemStream> lpStream;
  2502. IStream *lpIStream = NULL;
  2503. RETVAL_FALSE;
  2504. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2505. MAPI_G(hr) = ECMemStream::Create(nullptr, 0, STGM_WRITE | STGM_SHARE_EXCLUSIVE, nullptr, nullptr, nullptr, &~lpStream);
  2506. if(MAPI_G(hr) != hrSuccess) {
  2507. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to instantiate new stream object");
  2508. goto exit;
  2509. }
  2510. MAPI_G(hr) = lpStream->QueryInterface(IID_IStream, (void**)&lpIStream);
  2511. if(MAPI_G(hr) != hrSuccess)
  2512. goto exit;
  2513. ZEND_REGISTER_RESOURCE(return_value, lpIStream, le_istream);
  2514. exit:
  2515. LOG_END();
  2516. THROW_ON_ERROR();
  2517. }
  2518. /*
  2519. Opens property to a stream
  2520. THIS FUNCTION IS DEPRECATED. USE mapi_openproperty() INSTEAD
  2521. */
  2522. ZEND_FUNCTION(mapi_openpropertytostream)
  2523. {
  2524. PMEASURE_FUNC;
  2525. LOG_BEGIN();
  2526. // params
  2527. zval *res = NULL;
  2528. LPMAPIPROP lpMapiProp = NULL;
  2529. long proptag = 0, flags = 0; // open default readable
  2530. char *guidStr = NULL; // guid is given as a char array
  2531. size_t guidLen = 0;
  2532. // return value
  2533. LPSTREAM pStream = NULL;
  2534. // local
  2535. LPGUID lpGuid; // pointer to string param or static guid
  2536. int type = -1;
  2537. RETVAL_FALSE;
  2538. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2539. php_error_docref("mapi_openpropertytostream", E_DEPRECATED, "Use of mapi_openpropertytostream is deprecated, use mapi_openproperty");
  2540. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|ls", &res, &proptag, &flags, &guidStr, &guidLen) == FAILURE) return;
  2541. type = Z_RES_P(res)->type;
  2542. if(type == le_mapi_message) {
  2543. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMESSAGE, &res, -1, name_mapi_message, le_mapi_message);
  2544. } else if (type == le_mapi_folder) {
  2545. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMAPIFOLDER, &res, -1, name_mapi_folder, le_mapi_folder);
  2546. } else if (type == le_mapi_attachment) {
  2547. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPATTACH, &res, -1, name_mapi_attachment, le_mapi_attachment);
  2548. } else if (type == le_mapi_msgstore) {
  2549. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  2550. } else {
  2551. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown resource type");
  2552. goto exit;
  2553. }
  2554. if (guidStr == NULL) {
  2555. // when no guidstring is provided default to IStream
  2556. lpGuid = (LPGUID)&IID_IStream;
  2557. } else if (guidLen == sizeof(GUID)) { // assume we have a guid if the length is right
  2558. lpGuid = (LPGUID)guidStr;
  2559. } else {
  2560. php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Using the default GUID because the given GUIDs length is not right");
  2561. lpGuid = (LPGUID)&IID_IStream;
  2562. }
  2563. MAPI_G(hr) = lpMapiProp->OpenProperty(proptag, lpGuid, 0, flags, (LPUNKNOWN *) &pStream);
  2564. if (MAPI_G(hr) != hrSuccess)
  2565. goto exit;
  2566. ZEND_REGISTER_RESOURCE(return_value, pStream, le_istream);
  2567. exit:
  2568. LOG_END();
  2569. THROW_ON_ERROR();
  2570. }
  2571. /**
  2572. * mapi_message_getreceipenttable
  2573. * @return MAPI Table
  2574. *
  2575. */
  2576. ZEND_FUNCTION(mapi_message_getrecipienttable)
  2577. {
  2578. PMEASURE_FUNC;
  2579. LOG_BEGIN();
  2580. // params
  2581. zval *res;
  2582. LPMESSAGE pMessage = NULL;
  2583. // return value
  2584. LPMAPITABLE pTable = 0;
  2585. RETVAL_FALSE;
  2586. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2587. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &res) == FAILURE) return;
  2588. ZEND_FETCH_RESOURCE_C(pMessage, LPMESSAGE, &res, -1, name_mapi_message, le_mapi_message);
  2589. MAPI_G(hr) = pMessage->GetRecipientTable(0, &pTable);
  2590. if (FAILED(MAPI_G(hr)))
  2591. goto exit;
  2592. UOBJ_REGISTER_RESOURCE(return_value, pTable, le_mapi_table);
  2593. exit:
  2594. LOG_END();
  2595. THROW_ON_ERROR();
  2596. }
  2597. ZEND_FUNCTION(mapi_message_setreadflag)
  2598. {
  2599. PMEASURE_FUNC;
  2600. LOG_BEGIN();
  2601. // params
  2602. zval *res = NULL;
  2603. LPMESSAGE pMessage = NULL;
  2604. long flag = 0;
  2605. RETVAL_FALSE;
  2606. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2607. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &res, &flag) == FAILURE) return;
  2608. ZEND_FETCH_RESOURCE_C(pMessage, LPMESSAGE, &res, -1, name_mapi_message, le_mapi_message);
  2609. MAPI_G(hr) = pMessage->SetReadFlag(flag);
  2610. if (FAILED(MAPI_G(hr)))
  2611. goto exit;
  2612. RETVAL_TRUE;
  2613. exit:
  2614. LOG_END();
  2615. THROW_ON_ERROR();
  2616. }
  2617. /**
  2618. * Read the data from an attachment.
  2619. * @param Attachment resource
  2620. * @return Message
  2621. */
  2622. ZEND_FUNCTION(mapi_attach_openobj)
  2623. {
  2624. PMEASURE_FUNC;
  2625. LOG_BEGIN();
  2626. // params
  2627. zval *res = NULL;
  2628. LPATTACH pAttach = NULL;
  2629. long ulFlags = 0;
  2630. // return value
  2631. LPMESSAGE lpMessage = NULL;
  2632. RETVAL_FALSE;
  2633. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2634. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &res, &ulFlags) == FAILURE) return;
  2635. ZEND_FETCH_RESOURCE_C(pAttach, LPATTACH, &res, -1, name_mapi_attachment, le_mapi_attachment);
  2636. MAPI_G(hr) = pAttach->OpenProperty(PR_ATTACH_DATA_OBJ, &IID_IMessage, 0, ulFlags, (LPUNKNOWN *) &lpMessage);
  2637. if (FAILED(MAPI_G(hr)))
  2638. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Fetching attachmentdata as object failed");
  2639. else
  2640. UOBJ_REGISTER_RESOURCE(return_value, lpMessage, le_mapi_message);
  2641. LOG_END();
  2642. THROW_ON_ERROR();
  2643. }
  2644. /**
  2645. * Function to get a Property ID from the name. The function expects an array
  2646. * with the property names or IDs.
  2647. *
  2648. *
  2649. */
  2650. ZEND_FUNCTION(mapi_getidsfromnames)
  2651. {
  2652. PMEASURE_FUNC;
  2653. LOG_BEGIN();
  2654. // params
  2655. zval *messageStore = NULL;
  2656. LPMDB lpMessageStore = NULL;
  2657. zval *propNameArray = NULL;
  2658. zval *guidArray = NULL;
  2659. // return value
  2660. memory_ptr<SPropTagArray> lpPropTagArray;
  2661. // local
  2662. size_t hashTotal = 0, i = 0;
  2663. memory_ptr<MAPINAMEID *> lppNamePropId;
  2664. zval *entry = NULL, *guidEntry = NULL;
  2665. HashTable *targetHash = NULL, *guidHash = NULL;
  2666. GUID guidOutlook = { 0x00062002, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}};
  2667. int multibytebufferlen = 0;
  2668. RETVAL_FALSE;
  2669. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2670. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra|a", &messageStore, &propNameArray, &guidArray) == FAILURE) return;
  2671. ZEND_FETCH_RESOURCE_C(lpMessageStore, LPMDB, &messageStore, -1, name_mapi_msgstore, le_mapi_msgstore);
  2672. targetHash = Z_ARRVAL_P(propNameArray);
  2673. if(guidArray)
  2674. guidHash = Z_ARRVAL_P(guidArray);
  2675. // get the number of items in the array
  2676. hashTotal = zend_hash_num_elements(targetHash);
  2677. if (guidHash && hashTotal != zend_hash_num_elements(guidHash))
  2678. php_error_docref(NULL TSRMLS_CC, E_WARNING, "The array with the guids is not of the same size as the array with the ids");
  2679. // allocate memory to use
  2680. MAPI_G(hr) = MAPIAllocateBuffer(sizeof(LPMAPINAMEID) * hashTotal, &~lppNamePropId);
  2681. if (MAPI_G(hr) != hrSuccess)
  2682. goto exit;
  2683. // first reset the hash, so the pointer points to the first element.
  2684. zend_hash_internal_pointer_reset(targetHash);
  2685. if(guidHash)
  2686. zend_hash_internal_pointer_reset(guidHash);
  2687. for (i = 0; i < hashTotal; ++i) {
  2688. // Gets the element that exist at the current pointer.
  2689. entry = zend_hash_get_current_data(targetHash);
  2690. if(guidHash)
  2691. guidEntry = zend_hash_get_current_data(guidHash);
  2692. MAPI_G(hr) = MAPIAllocateMore(sizeof(MAPINAMEID),lppNamePropId,(void **) &lppNamePropId[i]);
  2693. if (MAPI_G(hr) != hrSuccess)
  2694. goto exit;
  2695. // fall back to a default GUID if the passed one is not good ..
  2696. lppNamePropId[i]->lpguid = &guidOutlook;
  2697. if(guidHash) {
  2698. if (Z_TYPE_P(guidEntry) != IS_STRING || sizeof(GUID) != guidEntry->value.str->len) {
  2699. php_error_docref(NULL TSRMLS_CC, E_WARNING, "The GUID with index number %d that is passed is not of the right length, cannot convert to GUID", i);
  2700. } else {
  2701. MAPI_G(hr) = MAPIAllocateMore(sizeof(GUID),lppNamePropId,(void **) &lppNamePropId[i]->lpguid);
  2702. if (MAPI_G(hr) != hrSuccess)
  2703. goto exit;
  2704. memcpy(lppNamePropId[i]->lpguid, guidEntry->value.str->val, sizeof(GUID));
  2705. }
  2706. }
  2707. switch(Z_TYPE_P(entry))
  2708. {
  2709. case IS_LONG:
  2710. lppNamePropId[i]->ulKind = MNID_ID;
  2711. lppNamePropId[i]->Kind.lID = entry->value.lval;
  2712. break;
  2713. case IS_STRING:
  2714. multibytebufferlen = mbstowcs(NULL, entry->value.str->val, 0);
  2715. MAPI_G(hr) = MAPIAllocateMore((multibytebufferlen + 1) * sizeof(WCHAR), lppNamePropId,
  2716. (void **)&lppNamePropId[i]->Kind.lpwstrName);
  2717. if (MAPI_G(hr) != hrSuccess)
  2718. goto exit;
  2719. mbstowcs(lppNamePropId[i]->Kind.lpwstrName, entry->value.str->val, multibytebufferlen+1);
  2720. lppNamePropId[i]->ulKind = MNID_STRING;
  2721. break;
  2722. case IS_DOUBLE:
  2723. lppNamePropId[i]->ulKind = MNID_ID;
  2724. lppNamePropId[i]->Kind.lID = (LONG) entry->value.dval;
  2725. break;
  2726. default:
  2727. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Entry is of an unknown type: %08X", Z_TYPE_P(entry));
  2728. break;
  2729. }
  2730. // move the pointers of the hashtables forward.
  2731. zend_hash_move_forward(targetHash);
  2732. if(guidHash)
  2733. zend_hash_move_forward(guidHash);
  2734. }
  2735. MAPI_G(hr) = lpMessageStore->GetIDsFromNames(hashTotal, lppNamePropId, MAPI_CREATE, &~lpPropTagArray);
  2736. if (FAILED(MAPI_G(hr))) {
  2737. php_error_docref(NULL TSRMLS_CC, E_WARNING, "GetIDsFromNames failed with error code %08X", MAPI_G(hr));
  2738. goto exit;
  2739. } else {
  2740. array_init(return_value);
  2741. for (unsigned int i = 0; i < lpPropTagArray->cValues; ++i)
  2742. add_next_index_long(return_value, (LONG)lpPropTagArray->aulPropTag[i]);
  2743. }
  2744. exit:
  2745. LOG_END();
  2746. THROW_ON_ERROR();
  2747. }
  2748. ZEND_FUNCTION(mapi_setprops)
  2749. {
  2750. PMEASURE_FUNC;
  2751. LOG_BEGIN();
  2752. // params
  2753. zval *res = NULL, *propValueArray = NULL;
  2754. LPMAPIPROP lpMapiProp = NULL;
  2755. // local
  2756. int type = -1;
  2757. ULONG cValues = 0;
  2758. memory_ptr<SPropValue> pPropValueArray;
  2759. RETVAL_FALSE;
  2760. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2761. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra", &res, &propValueArray) == FAILURE) return;
  2762. type = Z_RES_P(res)->type;
  2763. if(type == le_mapi_message) {
  2764. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMESSAGE, &res, -1, name_mapi_message, le_mapi_message);
  2765. } else if (type == le_mapi_folder) {
  2766. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMAPIFOLDER, &res, -1, name_mapi_folder, le_mapi_folder);
  2767. } else if (type == le_mapi_attachment) {
  2768. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPATTACH, &res, -1, name_mapi_attachment, le_mapi_attachment);
  2769. } else if (type == le_mapi_msgstore) {
  2770. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  2771. } else if (type == le_mapi_property) {
  2772. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMAPIPROP, &res, -1, name_mapi_property, le_mapi_property);
  2773. } else {
  2774. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown resource type");
  2775. goto exit;
  2776. }
  2777. MAPI_G(hr) = PHPArraytoPropValueArray(propValueArray, NULL, &cValues, &~pPropValueArray TSRMLS_CC);
  2778. if (MAPI_G(hr) != hrSuccess) {
  2779. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to convert PHP property to MAPI");
  2780. goto exit;
  2781. }
  2782. MAPI_G(hr) = lpMapiProp->SetProps(cValues, pPropValueArray, NULL);
  2783. if (FAILED(MAPI_G(hr)))
  2784. goto exit;
  2785. RETVAL_TRUE;
  2786. exit:
  2787. LOG_END();
  2788. THROW_ON_ERROR();
  2789. }
  2790. ZEND_FUNCTION(mapi_copyto)
  2791. {
  2792. PMEASURE_FUNC;
  2793. LOG_BEGIN();
  2794. memory_ptr<SPropTagArray> lpExcludeProps;
  2795. LPMAPIPROP lpSrcObj = NULL;
  2796. LPVOID lpDstObj = NULL;
  2797. LPCIID lpInterface = NULL;
  2798. memory_ptr<IID> lpExcludeIIDs;
  2799. ULONG cExcludeIIDs = 0;
  2800. // params
  2801. zval *srcres = NULL;
  2802. zval *dstres = NULL;
  2803. zval *excludeprops = NULL;
  2804. zval *excludeiid = NULL;
  2805. long flags = 0;
  2806. // local
  2807. int type = -1;
  2808. RETVAL_FALSE;
  2809. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2810. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "raar|l", &srcres, &excludeiid, &excludeprops, &dstres, &flags) == FAILURE) return;
  2811. type = Z_RES_P(srcres)->type;
  2812. if(type == le_mapi_message) {
  2813. ZEND_FETCH_RESOURCE_C(lpSrcObj, LPMESSAGE, &srcres, -1, name_mapi_message, le_mapi_message);
  2814. } else if (type == le_mapi_folder) {
  2815. ZEND_FETCH_RESOURCE_C(lpSrcObj, LPMAPIFOLDER, &srcres, -1, name_mapi_folder, le_mapi_folder);
  2816. } else if (type == le_mapi_attachment) {
  2817. ZEND_FETCH_RESOURCE_C(lpSrcObj, LPATTACH, &srcres, -1, name_mapi_attachment, le_mapi_attachment);
  2818. } else if (type == le_mapi_msgstore) {
  2819. ZEND_FETCH_RESOURCE_C(lpSrcObj, LPMDB, &srcres, -1, name_mapi_msgstore, le_mapi_msgstore);
  2820. } else {
  2821. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown resource type");
  2822. goto exit;
  2823. }
  2824. MAPI_G(hr) = PHPArraytoGUIDArray(excludeiid, nullptr, &cExcludeIIDs, &~lpExcludeIIDs TSRMLS_CC);
  2825. if (MAPI_G(hr) != hrSuccess) {
  2826. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse IIDs");
  2827. goto exit;
  2828. }
  2829. MAPI_G(hr) = PHPArraytoPropTagArray(excludeprops, NULL, &~lpExcludeProps TSRMLS_CC);
  2830. if (MAPI_G(hr) != hrSuccess) {
  2831. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse property tag array");
  2832. goto exit;
  2833. }
  2834. type = Z_RES_P(dstres)->type;
  2835. if(type == le_mapi_message) {
  2836. ZEND_FETCH_RESOURCE_C(lpDstObj, LPMESSAGE, &dstres, -1, name_mapi_message, le_mapi_message);
  2837. lpInterface = &IID_IMessage;
  2838. } else if (type == le_mapi_folder) {
  2839. ZEND_FETCH_RESOURCE_C(lpDstObj, LPMAPIFOLDER, &dstres, -1, name_mapi_folder, le_mapi_folder);
  2840. lpInterface = &IID_IMAPIFolder;
  2841. } else if (type == le_mapi_attachment) {
  2842. ZEND_FETCH_RESOURCE_C(lpDstObj, LPATTACH, &dstres, -1, name_mapi_attachment, le_mapi_attachment);
  2843. lpInterface = &IID_IAttachment;
  2844. } else if (type == le_mapi_msgstore) {
  2845. ZEND_FETCH_RESOURCE_C(lpDstObj, LPMDB, &dstres, -1, name_mapi_msgstore, le_mapi_msgstore);
  2846. lpInterface = &IID_IMsgStore;
  2847. } else {
  2848. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown resource type");
  2849. goto exit;
  2850. }
  2851. MAPI_G(hr) = lpSrcObj->CopyTo(cExcludeIIDs, lpExcludeIIDs, lpExcludeProps, 0, NULL, lpInterface, lpDstObj, flags, NULL);
  2852. if (FAILED(MAPI_G(hr)))
  2853. goto exit;
  2854. RETVAL_TRUE;
  2855. exit:
  2856. LOG_END();
  2857. THROW_ON_ERROR();
  2858. }
  2859. ZEND_FUNCTION(mapi_savechanges)
  2860. {
  2861. PMEASURE_FUNC;
  2862. LOG_BEGIN();
  2863. // params
  2864. zval *res = NULL;
  2865. LPMAPIPROP lpMapiProp = NULL;
  2866. long flags = KEEP_OPEN_READWRITE;
  2867. // local
  2868. int type = -1;
  2869. RETVAL_FALSE;
  2870. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2871. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &res, &flags) == FAILURE) return;
  2872. if (Z_TYPE_P(res) != IS_RESOURCE) {
  2873. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported case !IS_RESOURCE.");
  2874. goto exit;
  2875. }
  2876. type = Z_RES_P(res)->type;
  2877. if (type == le_mapi_message) {
  2878. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMESSAGE, &res, -1, name_mapi_message, le_mapi_message);
  2879. } else if (type == le_mapi_folder) {
  2880. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMAPIFOLDER, &res, -1, name_mapi_folder, le_mapi_folder);
  2881. } else if (type == le_mapi_attachment) {
  2882. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPATTACH, &res, -1, name_mapi_attachment, le_mapi_attachment);
  2883. } else if (type == le_mapi_msgstore) {
  2884. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  2885. } else if (type == le_mapi_property) {
  2886. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMAPIPROP, &res, -1, name_mapi_property, le_mapi_property);
  2887. } else {
  2888. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Resource does not exist...");
  2889. goto exit;
  2890. }
  2891. MAPI_G(hr) = lpMapiProp->SaveChanges(flags);
  2892. if (FAILED(MAPI_G(hr)))
  2893. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to save the object %08X", MAPI_G(hr));
  2894. else
  2895. RETVAL_TRUE;
  2896. exit:
  2897. LOG_END();
  2898. THROW_ON_ERROR();
  2899. }
  2900. ZEND_FUNCTION(mapi_deleteprops)
  2901. {
  2902. PMEASURE_FUNC;
  2903. LOG_BEGIN();
  2904. // params
  2905. zval *res = NULL, *propTagArray = NULL;
  2906. LPMAPIPROP lpMapiProp = NULL;
  2907. memory_ptr<SPropTagArray> lpTagArray;
  2908. // local
  2909. int type = -1;
  2910. RETVAL_FALSE;
  2911. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2912. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra", &res, &propTagArray) == FAILURE) return;
  2913. type = Z_RES_P(res)->type;
  2914. if(type == le_mapi_message) {
  2915. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMESSAGE, &res, -1, name_mapi_message, le_mapi_message);
  2916. } else if (type == le_mapi_folder) {
  2917. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMAPIFOLDER, &res, -1, name_mapi_folder, le_mapi_folder);
  2918. } else if (type == le_mapi_attachment) {
  2919. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPATTACH, &res, -1, name_mapi_attachment, le_mapi_attachment);
  2920. } else if (type == le_mapi_msgstore) {
  2921. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  2922. } else {
  2923. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Resource does not exist...");
  2924. goto exit;
  2925. }
  2926. MAPI_G(hr) = PHPArraytoPropTagArray(propTagArray, NULL, &~lpTagArray TSRMLS_CC);
  2927. if (MAPI_G(hr) != hrSuccess) {
  2928. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to convert the PHP Array");
  2929. goto exit;
  2930. }
  2931. MAPI_G(hr) = lpMapiProp->DeleteProps(lpTagArray, NULL);
  2932. if(MAPI_G(hr) != hrSuccess)
  2933. goto exit;
  2934. RETVAL_TRUE;
  2935. exit:
  2936. LOG_END();
  2937. THROW_ON_ERROR();
  2938. }
  2939. ZEND_FUNCTION(mapi_openproperty)
  2940. {
  2941. PMEASURE_FUNC;
  2942. LOG_BEGIN();
  2943. // params
  2944. zval *res = NULL;
  2945. LPMAPIPROP lpMapiProp = NULL;
  2946. long proptag = 0, flags = 0, interfaceflags = 0; // open default readable
  2947. char *guidStr = NULL; // guid is given as a char array
  2948. size_t guidLen = 0;
  2949. // return value
  2950. IUnknown* lpUnk = NULL;
  2951. // local
  2952. LPGUID lpGUID = NULL; // pointer to string param or static guid
  2953. int type = -1;
  2954. bool bBackwardCompatible = false;
  2955. object_ptr<IStream> lpStream;
  2956. RETVAL_FALSE;
  2957. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2958. if(ZEND_NUM_ARGS() == 2) {
  2959. // BACKWARD COMPATIBILITY MODE.. this means that we just read the entire stream and return it as a string
  2960. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &res, &proptag) == FAILURE) return;
  2961. bBackwardCompatible = true;
  2962. guidStr = (char *)&IID_IStream;
  2963. guidLen = sizeof(GUID);
  2964. interfaceflags = 0;
  2965. flags = 0;
  2966. } else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlsll", &res, &proptag, &guidStr, &guidLen, &interfaceflags, &flags) == FAILURE) {
  2967. return;
  2968. }
  2969. type = Z_RES_P(res)->type;
  2970. if(type == le_mapi_message) {
  2971. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMESSAGE, &res, -1, name_mapi_message, le_mapi_message);
  2972. } else if (type == le_mapi_folder) {
  2973. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMAPIFOLDER, &res, -1, name_mapi_folder, le_mapi_folder);
  2974. } else if (type == le_mapi_attachment) {
  2975. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPATTACH, &res, -1, name_mapi_attachment, le_mapi_attachment);
  2976. } else if (type == le_mapi_msgstore) {
  2977. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  2978. } else {
  2979. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2980. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Resource is not a valid MAPI resource");
  2981. goto exit;
  2982. }
  2983. if (guidLen != sizeof(GUID)) {
  2984. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  2985. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified interface is not a valid interface identifier (wrong size)");
  2986. goto exit;
  2987. }
  2988. lpGUID = (LPGUID) guidStr;
  2989. MAPI_G(hr) = lpMapiProp->OpenProperty(proptag, lpGUID, interfaceflags, flags, (LPUNKNOWN *) &lpUnk);
  2990. if (MAPI_G(hr) != hrSuccess)
  2991. goto exit;
  2992. if (*lpGUID == IID_IStream) {
  2993. if(bBackwardCompatible) {
  2994. STATSTG stat;
  2995. char *data = NULL;
  2996. ULONG cRead;
  2997. // do not use queryinterface, since we don't return the stream, but the contents
  2998. lpStream.reset((IStream *)lpUnk, false);
  2999. MAPI_G(hr) = lpStream->Stat(&stat, STATFLAG_NONAME);
  3000. if(MAPI_G(hr) != hrSuccess)
  3001. goto exit;
  3002. // Use emalloc so that it can be returned directly to PHP without copying
  3003. data = (char *)emalloc(stat.cbSize.LowPart);
  3004. if (data == NULL) {
  3005. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to allocate memory");
  3006. MAPI_G(hr) = MAPI_E_NOT_ENOUGH_MEMORY;
  3007. goto exit;
  3008. }
  3009. MAPI_G(hr) = lpStream->Read(data, (ULONG)stat.cbSize.LowPart, &cRead);
  3010. if(MAPI_G(hr)) {
  3011. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to read the data");
  3012. goto exit;
  3013. }
  3014. RETVAL_STRINGL(data, cRead);
  3015. efree(data);
  3016. } else {
  3017. ZEND_REGISTER_RESOURCE(return_value, lpUnk, le_istream);
  3018. }
  3019. } else if(*lpGUID == IID_IMAPITable) {
  3020. UOBJ_REGISTER_RESOURCE(return_value, lpUnk, le_mapi_table);
  3021. } else if(*lpGUID == IID_IMessage) {
  3022. UOBJ_REGISTER_RESOURCE(return_value, lpUnk, le_mapi_message);
  3023. } else if(*lpGUID == IID_IMAPIFolder) {
  3024. UOBJ_REGISTER_RESOURCE(return_value, lpUnk, le_mapi_folder);
  3025. } else if(*lpGUID == IID_IMsgStore) {
  3026. UOBJ_REGISTER_RESOURCE(return_value, lpUnk, le_mapi_msgstore);
  3027. } else if(*lpGUID == IID_IExchangeModifyTable) {
  3028. UOBJ_REGISTER_RESOURCE(return_value, lpUnk, le_mapi_modifytable);
  3029. } else if(*lpGUID == IID_IExchangeExportChanges) {
  3030. UOBJ_REGISTER_RESOURCE(return_value, lpUnk, le_mapi_exportchanges);
  3031. } else if(*lpGUID == IID_IExchangeImportHierarchyChanges) {
  3032. UOBJ_REGISTER_RESOURCE(return_value, lpUnk, le_mapi_importhierarchychanges);
  3033. } else if(*lpGUID == IID_IExchangeImportContentsChanges) {
  3034. UOBJ_REGISTER_RESOURCE(return_value, lpUnk, le_mapi_importcontentschanges);
  3035. } else {
  3036. php_error_docref(NULL TSRMLS_CC, E_WARNING, "The openproperty call succeeded, but the PHP extension is unable to handle the requested interface");
  3037. lpUnk->Release();
  3038. MAPI_G(hr) = MAPI_E_NO_SUPPORT;
  3039. goto exit;
  3040. }
  3041. exit:
  3042. LOG_END();
  3043. THROW_ON_ERROR();
  3044. }
  3045. /*
  3046. Function that get a resource and check what type it is, when the type is a subclass from IMAPIProp
  3047. it will use it to do a getProps.
  3048. */
  3049. ZEND_FUNCTION(mapi_getprops)
  3050. {
  3051. PMEASURE_FUNC;
  3052. LOG_BEGIN();
  3053. // params
  3054. LPMAPIPROP lpMapiProp = NULL;
  3055. zval *res = NULL, *tagArray = NULL;
  3056. ULONG cValues = 0;
  3057. memory_ptr<SPropValue> lpPropValues;
  3058. memory_ptr<SPropTagArray> lpTagArray;
  3059. // return value
  3060. zval zval_prop_value;
  3061. // local
  3062. int type = -1; // list entry number of the resource.
  3063. RETVAL_FALSE;
  3064. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  3065. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|a", &res, &tagArray) == FAILURE) return;
  3066. type = Z_RES_P(res)->type;
  3067. if(type == le_mapi_message) {
  3068. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMESSAGE, &res, -1, name_mapi_message, le_mapi_message);
  3069. } else if (type == le_mapi_folder) {
  3070. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMAPIFOLDER, &res, -1, name_mapi_folder, le_mapi_folder);
  3071. } else if (type == le_mapi_attachment) {
  3072. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPATTACH, &res, -1, name_mapi_attachment, le_mapi_attachment);
  3073. } else if (type == le_mapi_msgstore) {
  3074. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  3075. } else if( type == le_mapi_mailuser) {
  3076. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMAILUSER, &res, -1, name_mapi_mailuser, le_mapi_mailuser);
  3077. } else if( type == le_mapi_distlist) {
  3078. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPDISTLIST, &res, -1, name_mapi_distlist, le_mapi_distlist);
  3079. } else if( type == le_mapi_abcont) {
  3080. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPABCONT, &res, -1, name_mapi_abcont, le_mapi_abcont);
  3081. } else if( type == le_mapi_property) {
  3082. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMAPIPROP, &res, -1, name_mapi_property, le_mapi_property);
  3083. } else {
  3084. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Resource is not a valid MAPI resource");
  3085. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  3086. goto exit;
  3087. }
  3088. if(tagArray) {
  3089. MAPI_G(hr) = PHPArraytoPropTagArray(tagArray, NULL, &~lpTagArray TSRMLS_CC);
  3090. if (MAPI_G(hr) != hrSuccess) {
  3091. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse property tag array");
  3092. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  3093. goto exit;
  3094. }
  3095. } else {
  3096. lpTagArray = NULL;
  3097. }
  3098. MAPI_G(hr) = lpMapiProp->GetProps(lpTagArray, 0, &cValues, &~lpPropValues);
  3099. if (FAILED(MAPI_G(hr)))
  3100. goto exit;
  3101. MAPI_G(hr) = PropValueArraytoPHPArray(cValues, lpPropValues, &zval_prop_value TSRMLS_CC);
  3102. if (MAPI_G(hr) != hrSuccess) {
  3103. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to convert properties to PHP values");
  3104. goto exit;
  3105. }
  3106. RETVAL_ZVAL(&zval_prop_value, 0, 0);
  3107. exit:
  3108. LOG_END();
  3109. THROW_ON_ERROR();
  3110. }
  3111. ZEND_FUNCTION(mapi_getnamesfromids)
  3112. {
  3113. PMEASURE_FUNC;
  3114. LOG_BEGIN();
  3115. // params
  3116. zval *res, *array;
  3117. LPMDB pMDB = NULL;
  3118. memory_ptr<SPropTagArray> lpPropTags;
  3119. // return value
  3120. // local
  3121. ULONG cPropNames = 0;
  3122. memory_ptr<MAPINAMEID *> pPropNames;
  3123. ULONG count = 0;
  3124. zval prop;
  3125. RETVAL_FALSE;
  3126. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  3127. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra", &res, &array) == FAILURE) return;
  3128. ZEND_FETCH_RESOURCE_C(pMDB, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  3129. MAPI_G(hr) = PHPArraytoPropTagArray(array, NULL, &~lpPropTags TSRMLS_CC);
  3130. if (MAPI_G(hr) != hrSuccess) {
  3131. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to convert proptag array from PHP array");
  3132. goto exit;
  3133. }
  3134. MAPI_G(hr) = pMDB->GetNamesFromIDs(&+lpPropTags, NULL, 0, &cPropNames, &~pPropNames);
  3135. if(FAILED(MAPI_G(hr)))
  3136. goto exit;
  3137. // This code should be moved to typeconversions.cpp
  3138. array_init(return_value);
  3139. for (count = 0; count < lpPropTags->cValues; ++count) {
  3140. if (pPropNames[count] == NULL)
  3141. continue; // FIXME: the returned array is smaller than the passed array!
  3142. char buffer[20];
  3143. snprintf(buffer, 20, "%i", lpPropTags->aulPropTag[count]);
  3144. array_init(&prop);
  3145. add_assoc_stringl(&prop, "guid", (char*)pPropNames[count]->lpguid, sizeof(GUID));
  3146. if (pPropNames[count]->ulKind == MNID_ID) {
  3147. add_assoc_long(&prop, "id", pPropNames[count]->Kind.lID);
  3148. } else {
  3149. int slen;
  3150. char *buffer;
  3151. slen = wcstombs(NULL, pPropNames[count]->Kind.lpwstrName, 0); // find string size
  3152. ++slen; // add terminator
  3153. buffer = new char[slen]; // alloc
  3154. wcstombs(buffer, pPropNames[count]->Kind.lpwstrName, slen); // convert & terminate
  3155. add_assoc_string(&prop, "name", buffer);
  3156. delete [] buffer;
  3157. }
  3158. add_assoc_zval(return_value, buffer, &prop);
  3159. }
  3160. exit:
  3161. LOG_END();
  3162. THROW_ON_ERROR();
  3163. }
  3164. /**
  3165. * Receives a string of compressed RTF. First turn this string into a Stream and than
  3166. * decompres.
  3167. *
  3168. */
  3169. ZEND_FUNCTION(mapi_decompressrtf)
  3170. {
  3171. PMEASURE_FUNC;
  3172. LOG_BEGIN();
  3173. // params
  3174. char * rtfBuffer = NULL;
  3175. size_t rtfBufferLen = 0;
  3176. // return value
  3177. std::unique_ptr<char[]> htmlbuf;
  3178. // local
  3179. ULONG actualWritten = 0;
  3180. ULONG cbRead = 0;
  3181. object_ptr<IStream> pStream, deCompressedStream;
  3182. LARGE_INTEGER begin = { { 0, 0 } };
  3183. size_t bufsize = 10240;
  3184. std::string strUncompressed;
  3185. RETVAL_FALSE;
  3186. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  3187. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &rtfBuffer, &rtfBufferLen) == FAILURE) return;
  3188. // make and fill the stream
  3189. MAPI_G(hr) = CreateStreamOnHGlobal(nullptr, true, &~pStream);
  3190. if (MAPI_G(hr) != hrSuccess || pStream == NULL) {
  3191. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to CreateStreamOnHGlobal %x", MAPI_G(hr));
  3192. goto exit;
  3193. }
  3194. pStream->Write(rtfBuffer, rtfBufferLen, &actualWritten);
  3195. pStream->Commit(0);
  3196. pStream->Seek(begin, SEEK_SET, NULL);
  3197. MAPI_G(hr) = WrapCompressedRTFStream(pStream, 0, &~deCompressedStream);
  3198. if (MAPI_G(hr) != hrSuccess) {
  3199. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to wrap uncompressed stream %x", MAPI_G(hr));
  3200. goto exit;
  3201. }
  3202. // bufsize is the size of the buffer we've allocated, and htmlsize is the
  3203. // amount of text we've read in so far. If our buffer wasn't big enough,
  3204. // we enlarge it and continue. We have to do this, instead of allocating
  3205. // it up front, because Stream::Stat() doesn't work for the unc.stream
  3206. bufsize = max(rtfBufferLen * 2, bufsize);
  3207. htmlbuf.reset(new char[bufsize]);
  3208. while(1) {
  3209. MAPI_G(hr) = deCompressedStream->Read(htmlbuf.get(), bufsize, &cbRead);
  3210. if (MAPI_G(hr) != hrSuccess) {
  3211. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Read from uncompressed stream failed %x", MAPI_G(hr));
  3212. goto exit;
  3213. }
  3214. if (cbRead == 0)
  3215. break;
  3216. strUncompressed.append(htmlbuf.get(), cbRead);
  3217. }
  3218. RETVAL_STRINGL((char *)strUncompressed.c_str(), strUncompressed.size());
  3219. exit:
  3220. LOG_END();
  3221. THROW_ON_ERROR();
  3222. }
  3223. /**
  3224. *
  3225. * Opens the rules table from the default INBOX of the given store
  3226. *
  3227. */
  3228. ZEND_FUNCTION(mapi_folder_openmodifytable) {
  3229. PMEASURE_FUNC;
  3230. LOG_BEGIN();
  3231. // params
  3232. zval *res;
  3233. LPMAPIFOLDER lpInbox = NULL;
  3234. // return value
  3235. LPEXCHANGEMODIFYTABLE lpRulesTable = NULL;
  3236. // locals
  3237. RETVAL_FALSE;
  3238. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  3239. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &res) == FAILURE) return;
  3240. ZEND_FETCH_RESOURCE_C(lpInbox, LPMAPIFOLDER, &res, -1, name_mapi_folder, le_mapi_folder);
  3241. MAPI_G(hr) = lpInbox->OpenProperty(PR_RULES_TABLE, &IID_IExchangeModifyTable, 0, 0, (LPUNKNOWN *)&lpRulesTable);
  3242. if (MAPI_G(hr) != hrSuccess)
  3243. goto exit;
  3244. UOBJ_REGISTER_RESOURCE(return_value, lpRulesTable, le_mapi_modifytable);
  3245. exit:
  3246. LOG_END();
  3247. THROW_ON_ERROR();
  3248. }
  3249. ZEND_FUNCTION(mapi_folder_getsearchcriteria) {
  3250. PMEASURE_FUNC;
  3251. LOG_BEGIN();
  3252. // params
  3253. zval *res = NULL;
  3254. zval restriction;
  3255. zval folderlist;
  3256. LPMAPIFOLDER lpFolder = NULL;
  3257. long ulFlags = 0;
  3258. // local
  3259. memory_ptr<SRestriction> lpRestriction;
  3260. memory_ptr<ENTRYLIST> lpFolderList;
  3261. ULONG ulSearchState = 0;
  3262. RETVAL_FALSE;
  3263. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  3264. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &res, &ulFlags) == FAILURE) return;
  3265. ZEND_FETCH_RESOURCE_C(lpFolder, LPMAPIFOLDER, &res, -1, name_mapi_folder, le_mapi_folder);
  3266. MAPI_G(hr) = lpFolder->GetSearchCriteria(ulFlags, &~lpRestriction, &~lpFolderList, &ulSearchState);
  3267. if (MAPI_G(hr) != hrSuccess)
  3268. goto exit;
  3269. MAPI_G(hr) = SRestrictiontoPHPArray(lpRestriction, 0, &restriction TSRMLS_CC);
  3270. if (MAPI_G(hr) != hrSuccess)
  3271. goto exit;
  3272. MAPI_G(hr) = SBinaryArraytoPHPArray(lpFolderList, &folderlist TSRMLS_CC);
  3273. if (MAPI_G(hr) != hrSuccess)
  3274. goto exit;
  3275. array_init(return_value);
  3276. add_assoc_zval(return_value, "restriction", &restriction);
  3277. add_assoc_zval(return_value, "folderlist", &folderlist);
  3278. add_assoc_long(return_value, "searchstate", ulSearchState);
  3279. exit:
  3280. LOG_END();
  3281. THROW_ON_ERROR();
  3282. }
  3283. ZEND_FUNCTION(mapi_folder_setsearchcriteria) {
  3284. PMEASURE_FUNC;
  3285. LOG_BEGIN();
  3286. // param
  3287. zval *res = NULL;
  3288. zval *restriction = NULL;
  3289. zval *folderlist = NULL;
  3290. long ulFlags = 0;
  3291. // local
  3292. LPMAPIFOLDER lpFolder = NULL;
  3293. memory_ptr<ENTRYLIST> lpFolderList;
  3294. memory_ptr<SRestriction> lpRestriction;
  3295. RETVAL_FALSE;
  3296. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  3297. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "raal", &res, &restriction, &folderlist, &ulFlags) == FAILURE) return;
  3298. ZEND_FETCH_RESOURCE_C(lpFolder, LPMAPIFOLDER, &res, -1, name_mapi_folder, le_mapi_folder);
  3299. MAPI_G(hr) = PHPArraytoSRestriction(restriction, NULL, &~lpRestriction TSRMLS_CC);
  3300. if (MAPI_G(hr) != hrSuccess)
  3301. goto exit;
  3302. MAPI_G(hr) = PHPArraytoSBinaryArray(folderlist, NULL, &~lpFolderList TSRMLS_CC);
  3303. if (MAPI_G(hr) != hrSuccess)
  3304. goto exit;
  3305. MAPI_G(hr) = lpFolder->SetSearchCriteria(lpRestriction, lpFolderList, ulFlags);
  3306. if (MAPI_G(hr) != hrSuccess)
  3307. goto exit;
  3308. RETVAL_TRUE;
  3309. exit:
  3310. LOG_END();
  3311. THROW_ON_ERROR();
  3312. }
  3313. /**
  3314. *
  3315. * returns a read-only view on the rules table
  3316. *
  3317. */
  3318. ZEND_FUNCTION(mapi_rules_gettable) {
  3319. PMEASURE_FUNC;
  3320. LOG_BEGIN();
  3321. // params
  3322. zval *res;
  3323. LPEXCHANGEMODIFYTABLE lpRulesTable = NULL;
  3324. // return value
  3325. object_ptr<IMAPITable> lpRulesView;
  3326. // locals
  3327. static constexpr const SizedSPropTagArray(11, sptaRules) =
  3328. {11, {PR_RULE_ID, PR_RULE_IDS, PR_RULE_SEQUENCE, PR_RULE_STATE,
  3329. PR_RULE_USER_FLAGS, PR_RULE_CONDITION, PR_RULE_ACTIONS,
  3330. PR_RULE_PROVIDER, PR_RULE_NAME, PR_RULE_LEVEL,
  3331. PR_RULE_PROVIDER_DATA}};
  3332. static constexpr const SizedSSortOrderSet(1, sosRules) =
  3333. {1, 0, 0, {{PR_RULE_SEQUENCE, TABLE_SORT_ASCEND}}};
  3334. ECRulesTableProxy *lpRulesTableProxy = NULL;
  3335. RETVAL_FALSE;
  3336. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  3337. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &res) == FAILURE) return;
  3338. ZEND_FETCH_RESOURCE_C(lpRulesTable, LPEXCHANGEMODIFYTABLE, &res, -1, name_mapi_modifytable, le_mapi_modifytable);
  3339. MAPI_G(hr) = lpRulesTable->GetTable(0, &~lpRulesView);
  3340. if (MAPI_G(hr) != hrSuccess)
  3341. goto exit;
  3342. MAPI_G(hr) = lpRulesView->SetColumns(sptaRules, 0);
  3343. if (MAPI_G(hr) != hrSuccess)
  3344. goto exit;
  3345. MAPI_G(hr) = lpRulesView->SortTable(sosRules, 0);
  3346. if (MAPI_G(hr) != hrSuccess)
  3347. goto exit;
  3348. MAPI_G(hr) = ECRulesTableProxy::Create(lpRulesView, &lpRulesTableProxy);
  3349. if (MAPI_G(hr) != hrSuccess)
  3350. goto exit;
  3351. MAPI_G(hr) = lpRulesTableProxy->QueryInterface(IID_IMAPITable, &~lpRulesView);
  3352. if (MAPI_G(hr) != hrSuccess)
  3353. goto exit;
  3354. UOBJ_REGISTER_RESOURCE(return_value, lpRulesView.release(), le_mapi_table);
  3355. exit:
  3356. LOG_END();
  3357. THROW_ON_ERROR();
  3358. }
  3359. /**
  3360. *
  3361. * Add's, modifies or deletes rows from the rules table
  3362. *
  3363. */
  3364. ZEND_FUNCTION(mapi_rules_modifytable) {
  3365. PMEASURE_FUNC;
  3366. LOG_BEGIN();
  3367. // params
  3368. zval *res;
  3369. LPEXCHANGEMODIFYTABLE lpRulesTable = NULL;
  3370. zval *rows;
  3371. LPROWLIST lpRowList = NULL;
  3372. long ulFlags = 0;
  3373. // return value
  3374. // locals
  3375. RETVAL_FALSE;
  3376. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  3377. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra|l", &res, &rows, &ulFlags) == FAILURE) return;
  3378. ZEND_FETCH_RESOURCE_C(lpRulesTable, LPEXCHANGEMODIFYTABLE, &res, -1, name_mapi_modifytable, le_mapi_modifytable);
  3379. MAPI_G(hr) = PHPArraytoRowList(rows, NULL, &lpRowList TSRMLS_CC);
  3380. if (MAPI_G(hr) != hrSuccess) {
  3381. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse rowlist");
  3382. goto exit;
  3383. }
  3384. MAPI_G(hr) = lpRulesTable->ModifyTable(ulFlags, lpRowList);
  3385. if (MAPI_G(hr) != hrSuccess)
  3386. goto exit;
  3387. RETVAL_TRUE;
  3388. exit:
  3389. if (lpRowList)
  3390. FreeProws((LPSRowSet)lpRowList);
  3391. LOG_END();
  3392. THROW_ON_ERROR();
  3393. }
  3394. ZEND_FUNCTION(mapi_zarafa_createuser)
  3395. {
  3396. PMEASURE_FUNC;
  3397. LOG_BEGIN();
  3398. // params
  3399. zval *res = NULL;
  3400. LPMDB lpMsgStore = NULL;
  3401. char *lpszUsername = NULL;
  3402. size_t ulUsernameLen = 0;
  3403. char *lpszFullname = NULL;
  3404. size_t ulFullname = 0;
  3405. char *lpszEmail = NULL;
  3406. size_t ulEmail = 0;
  3407. char *lpszPassword = NULL;
  3408. size_t ulPassword = 0;
  3409. long ulIsNonactive = false;
  3410. long ulIsAdmin = false;
  3411. // return value
  3412. ULONG cbUserId = 0;
  3413. memory_ptr<ENTRYID> lpUserId;
  3414. // local
  3415. IECUnknown *lpUnknown = NULL;
  3416. object_ptr<IECServiceAdmin> lpServiceAdmin;
  3417. ECUSER sUser = { 0 };
  3418. RETVAL_FALSE;
  3419. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  3420. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rssss|ll", &res,
  3421. &lpszUsername, &ulUsernameLen,
  3422. &lpszPassword, &ulPassword,
  3423. &lpszFullname, &ulFullname,
  3424. &lpszEmail, &ulEmail,
  3425. &ulIsNonactive, &ulIsAdmin) == FAILURE) return;
  3426. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  3427. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  3428. if(MAPI_G(hr) != hrSuccess) {
  3429. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  3430. goto exit;
  3431. }
  3432. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  3433. if(MAPI_G(hr) != hrSuccess) {
  3434. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object does not support the IECServiceAdmin interface");
  3435. goto exit;
  3436. }
  3437. //FIXME: Check the values
  3438. sUser.lpszUsername = (TCHAR*)lpszUsername;
  3439. sUser.lpszMailAddress = (TCHAR*)lpszEmail;
  3440. sUser.lpszPassword = (TCHAR*)lpszPassword;
  3441. sUser.ulObjClass = (ulIsNonactive ? NONACTIVE_USER : ACTIVE_USER);
  3442. sUser.lpszFullName = (TCHAR*)lpszFullname;
  3443. sUser.ulIsAdmin = ulIsAdmin;
  3444. MAPI_G(hr) = lpServiceAdmin->CreateUser(&sUser, 0, &cbUserId, &~lpUserId);
  3445. if(MAPI_G(hr) != hrSuccess)
  3446. goto exit;
  3447. RETVAL_TRUE;
  3448. exit:
  3449. LOG_END();
  3450. THROW_ON_ERROR();
  3451. }
  3452. ZEND_FUNCTION(mapi_zarafa_setuser)
  3453. {
  3454. PMEASURE_FUNC;
  3455. LOG_BEGIN();
  3456. // params
  3457. zval *res = NULL;
  3458. LPMDB lpMsgStore = NULL;
  3459. LPENTRYID lpUserId = NULL;
  3460. size_t cbUserId = 0;
  3461. char *lpszUsername = NULL;
  3462. size_t ulUsername = 0;
  3463. char *lpszFullname = NULL;
  3464. size_t ulFullname = 0;
  3465. char *lpszEmail = NULL;
  3466. size_t ulEmail = 0;
  3467. char *lpszPassword = NULL;
  3468. size_t ulPassword = 0;
  3469. long ulIsNonactive = 0;
  3470. long ulIsAdmin = 0;
  3471. // local
  3472. IECUnknown *lpUnknown = NULL;
  3473. object_ptr<IECServiceAdmin> lpServiceAdmin;
  3474. ECUSER sUser;
  3475. RETVAL_FALSE;
  3476. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  3477. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsssssll", &res, &lpUserId, &cbUserId, &lpszUsername, &ulUsername, &lpszFullname, &ulFullname, &lpszEmail, &ulEmail, &lpszPassword, &ulPassword, &ulIsNonactive, &ulIsAdmin) == FAILURE) return;
  3478. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  3479. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  3480. if(MAPI_G(hr) != hrSuccess) {
  3481. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  3482. goto exit;
  3483. }
  3484. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  3485. if(MAPI_G(hr) != hrSuccess) {
  3486. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object does not support the IECServiceAdmin interface");
  3487. goto exit;
  3488. }
  3489. //FIXME: Check the values
  3490. memset(&sUser, 0, sizeof(ECUSER));
  3491. sUser.lpszUsername = (TCHAR*)lpszUsername;
  3492. sUser.lpszPassword = (TCHAR*)lpszPassword;
  3493. sUser.lpszMailAddress = (TCHAR*)lpszEmail;
  3494. sUser.lpszFullName = (TCHAR*)lpszFullname;
  3495. sUser.sUserId.lpb = (unsigned char*)lpUserId;
  3496. sUser.sUserId.cb = cbUserId;
  3497. sUser.ulObjClass = (ulIsNonactive ? NONACTIVE_USER : ACTIVE_USER);
  3498. sUser.ulIsAdmin = ulIsAdmin;
  3499. // no support for hidden, capacity and propmaps
  3500. MAPI_G(hr) = lpServiceAdmin->SetUser(&sUser, 0);
  3501. if(MAPI_G(hr) != hrSuccess)
  3502. goto exit;
  3503. RETVAL_TRUE;
  3504. exit:
  3505. LOG_END();
  3506. THROW_ON_ERROR();
  3507. }
  3508. ZEND_FUNCTION(mapi_zarafa_deleteuser)
  3509. {
  3510. PMEASURE_FUNC;
  3511. LOG_BEGIN();
  3512. // params
  3513. zval *res = NULL;
  3514. LPMDB lpMsgStore = NULL;
  3515. ULONG cbUserId = 0;
  3516. memory_ptr<ENTRYID> lpUserId;
  3517. char* lpszUserName = NULL;
  3518. size_t ulUserName;
  3519. // local
  3520. IECUnknown *lpUnknown = NULL;
  3521. object_ptr<IECServiceAdmin> lpServiceAdmin;
  3522. RETVAL_FALSE;
  3523. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  3524. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &res, &lpszUserName, &ulUserName) == FAILURE) return;
  3525. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  3526. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  3527. if(MAPI_G(hr) != hrSuccess) {
  3528. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  3529. goto exit;
  3530. }
  3531. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  3532. if(MAPI_G(hr) != hrSuccess) {
  3533. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object does not support the IECServiceAdmin interface");
  3534. goto exit;
  3535. }
  3536. MAPI_G(hr) = lpServiceAdmin->ResolveUserName((TCHAR*)lpszUserName, 0, &cbUserId, &~lpUserId);
  3537. if(MAPI_G(hr) != hrSuccess) {
  3538. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to delete user, Can't resolve user: %08X", MAPI_G(hr));
  3539. goto exit;
  3540. }
  3541. MAPI_G(hr) = lpServiceAdmin->DeleteUser(cbUserId, lpUserId);
  3542. if(MAPI_G(hr) != hrSuccess) {
  3543. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to delete user: %08X", MAPI_G(hr));
  3544. goto exit;
  3545. }
  3546. RETVAL_TRUE;
  3547. exit:
  3548. LOG_END();
  3549. THROW_ON_ERROR();
  3550. }
  3551. ZEND_FUNCTION(mapi_zarafa_createstore)
  3552. {
  3553. PMEASURE_FUNC;
  3554. LOG_BEGIN();
  3555. // params
  3556. zval *res = NULL;
  3557. LPMDB lpMsgStore = NULL;
  3558. long ulStoreType;
  3559. LPENTRYID lpUserId = NULL;
  3560. size_t cbUserId = 0;
  3561. // local
  3562. IECUnknown *lpUnknown = NULL;
  3563. object_ptr<IECServiceAdmin> lpServiceAdmin;
  3564. memory_ptr<ENTRYID> lpStoreID, lpRootID;
  3565. ULONG cbStoreID = 0;
  3566. ULONG cbRootID = 0;
  3567. RETVAL_FALSE;
  3568. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  3569. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rls", &res, &ulStoreType, &lpUserId, &cbUserId) == FAILURE) return;
  3570. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  3571. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  3572. if(MAPI_G(hr) != hrSuccess) {
  3573. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  3574. goto exit;
  3575. }
  3576. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  3577. if(MAPI_G(hr) != hrSuccess) {
  3578. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object does not support the IECServiceAdmin interface");
  3579. goto exit;
  3580. }
  3581. MAPI_G(hr) = lpServiceAdmin->CreateStore(ulStoreType, cbUserId, lpUserId, &cbStoreID, &~lpStoreID, &cbRootID, &~lpRootID);
  3582. if(MAPI_G(hr) != hrSuccess) {
  3583. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to modify user: %08X", MAPI_G(hr));
  3584. goto exit;
  3585. }
  3586. RETVAL_TRUE;
  3587. exit:
  3588. LOG_END();
  3589. THROW_ON_ERROR();
  3590. }
  3591. /**
  3592. * Retrieve a list of users from zarafa
  3593. * @param logged on msgstore
  3594. * @param zarafa company entryid
  3595. * @return array(username => array(fullname, emaladdress, userid, admin));
  3596. */
  3597. ZEND_FUNCTION(mapi_zarafa_getuserlist)
  3598. {
  3599. PMEASURE_FUNC;
  3600. LOG_BEGIN();
  3601. // params
  3602. zval *res = NULL;
  3603. zval zval_data_value;
  3604. LPMDB lpMsgStore = NULL;
  3605. LPENTRYID lpCompanyId = NULL;
  3606. size_t cbCompanyId = 0;
  3607. // return value
  3608. // local
  3609. ULONG nUsers, i;
  3610. memory_ptr<ECUSER> lpUsers;
  3611. IECUnknown *lpUnknown = NULL;
  3612. object_ptr<IECSecurity> lpSecurity;
  3613. RETVAL_FALSE;
  3614. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  3615. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|s", &res, &lpCompanyId, &cbCompanyId) == FAILURE) return;
  3616. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  3617. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  3618. if(MAPI_G(hr) != hrSuccess) {
  3619. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  3620. goto exit;
  3621. }
  3622. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECSecurity, &~lpSecurity);
  3623. if (MAPI_G(hr) != hrSuccess)
  3624. goto exit;
  3625. MAPI_G(hr) = lpSecurity->GetUserList(cbCompanyId, lpCompanyId, 0, &nUsers, &~lpUsers);
  3626. if (MAPI_G(hr) != hrSuccess)
  3627. goto exit;
  3628. array_init(return_value);
  3629. for (i = 0; i < nUsers; ++i) {
  3630. array_init(&zval_data_value);
  3631. add_assoc_stringl(&zval_data_value, "userid", (char*)lpUsers[i].sUserId.lpb, lpUsers[i].sUserId.cb);
  3632. add_assoc_string(&zval_data_value, "username", (char*)lpUsers[i].lpszUsername);
  3633. add_assoc_string(&zval_data_value, "fullname", (char*)lpUsers[i].lpszFullName);
  3634. add_assoc_string(&zval_data_value, "emailaddress", (char*)lpUsers[i].lpszMailAddress);
  3635. add_assoc_long(&zval_data_value, "admin", lpUsers[i].ulIsAdmin);
  3636. add_assoc_long(&zval_data_value, "nonactive", (lpUsers[i].ulObjClass == ACTIVE_USER ? 0 : 1));
  3637. add_assoc_zval(return_value, (char*)lpUsers[i].lpszUsername, &zval_data_value);
  3638. }
  3639. exit:
  3640. LOG_END();
  3641. THROW_ON_ERROR();
  3642. }
  3643. /**
  3644. * Retrieve quota values of a users from zarafa
  3645. * @param logged on msgstore
  3646. * @param user entryid to get quota information from
  3647. * @return array(usedefault, isuserdefault, warnsize, softsize, hardsize);
  3648. */
  3649. ZEND_FUNCTION(mapi_zarafa_getquota)
  3650. {
  3651. PMEASURE_FUNC;
  3652. LOG_BEGIN();
  3653. // params
  3654. zval *res = NULL;
  3655. LPMDB lpMsgStore = NULL;
  3656. LPENTRYID lpUserId = NULL;
  3657. size_t cbUserId = 0;
  3658. // return value
  3659. // local
  3660. IECUnknown *lpUnknown = NULL;
  3661. object_ptr<IECServiceAdmin> lpServiceAdmin;
  3662. memory_ptr<ECQUOTA> lpQuota;
  3663. RETVAL_FALSE;
  3664. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  3665. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &res, &lpUserId, &cbUserId) == FAILURE) return;
  3666. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  3667. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  3668. if(MAPI_G(hr) != hrSuccess) {
  3669. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  3670. goto exit;
  3671. }
  3672. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  3673. if(MAPI_G(hr) != hrSuccess)
  3674. goto exit;
  3675. MAPI_G(hr) = lpServiceAdmin->GetQuota(cbUserId, lpUserId, false, &~lpQuota);
  3676. if (MAPI_G(hr) != hrSuccess)
  3677. goto exit;
  3678. array_init(return_value);
  3679. add_assoc_bool(return_value, "usedefault", lpQuota->bUseDefaultQuota);
  3680. add_assoc_bool(return_value, "isuserdefault", lpQuota->bIsUserDefaultQuota);
  3681. add_assoc_long(return_value, "warnsize", lpQuota->llWarnSize);
  3682. add_assoc_long(return_value, "softsize", lpQuota->llSoftSize);
  3683. add_assoc_long(return_value, "hardsize", lpQuota->llHardSize);
  3684. exit:
  3685. LOG_END();
  3686. THROW_ON_ERROR();
  3687. }
  3688. /**
  3689. * Update quota values for a users
  3690. * @param logged on msgstore
  3691. * @param userid to get quota information from
  3692. * @param array(usedefault, isuserdefault, warnsize, softsize, hardsize)
  3693. * @return true/false
  3694. */
  3695. ZEND_FUNCTION(mapi_zarafa_setquota)
  3696. {
  3697. PMEASURE_FUNC;
  3698. LOG_BEGIN();
  3699. // params
  3700. zval *res = NULL;
  3701. LPMDB lpMsgStore = NULL;
  3702. LPENTRYID lpUserId = NULL;
  3703. size_t cbUserId = 0;
  3704. zval *array = NULL;
  3705. // return value
  3706. // local
  3707. IECUnknown *lpUnknown = NULL;
  3708. object_ptr<IECServiceAdmin> lpServiceAdmin;
  3709. memory_ptr<ECQUOTA> lpQuota;
  3710. HashTable *data = NULL;
  3711. zval *value = NULL;
  3712. zend_string *str_usedefault = zend_string_init("usedefault", sizeof("usedefault")-1, 0);
  3713. zend_string *str_isuserdefault = zend_string_init("isuserdefault", sizeof("isuserdefault")-1, 0);
  3714. zend_string *str_warnsize = zend_string_init("warnsize", sizeof("warnsize")-1, 0);
  3715. zend_string *str_softsize = zend_string_init("softsize", sizeof("softsize")-1, 0);
  3716. zend_string *str_hardsize = zend_string_init("hardsize", sizeof("hardsize")-1, 0);
  3717. RETVAL_FALSE;
  3718. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  3719. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsa", &res, &lpUserId, &cbUserId, &array) == FAILURE) return;
  3720. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  3721. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  3722. if(MAPI_G(hr) != hrSuccess) {
  3723. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  3724. goto exit;
  3725. }
  3726. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  3727. if(MAPI_G(hr) != hrSuccess)
  3728. goto exit;
  3729. MAPI_G(hr) = lpServiceAdmin->GetQuota(cbUserId, lpUserId, false, &~lpQuota);
  3730. if (MAPI_G(hr) != hrSuccess)
  3731. goto exit;
  3732. ZVAL_DEREF(array);
  3733. data = HASH_OF(array);
  3734. zend_hash_internal_pointer_reset(data);
  3735. if ((value = zend_hash_find(data, str_usedefault)) != NULL) {
  3736. convert_to_boolean_ex(value);
  3737. lpQuota->bUseDefaultQuota = (Z_TYPE_P(value) == IS_TRUE);
  3738. }
  3739. if ((value = zend_hash_find(data, str_isuserdefault)) != NULL) {
  3740. convert_to_boolean_ex(value);
  3741. lpQuota->bIsUserDefaultQuota = (Z_TYPE_P(value) == IS_TRUE);
  3742. }
  3743. if ((value = zend_hash_find(data, str_warnsize)) != NULL) {
  3744. convert_to_long_ex(value);
  3745. lpQuota->llWarnSize = Z_LVAL_P(value);
  3746. }
  3747. if ((value = zend_hash_find(data, str_softsize)) != NULL) {
  3748. convert_to_long_ex(value);
  3749. lpQuota->llSoftSize = Z_LVAL_P(value);
  3750. }
  3751. if ((value = zend_hash_find(data, str_hardsize)) != NULL) {
  3752. convert_to_long_ex(value);
  3753. lpQuota->llHardSize = Z_LVAL_P(value);
  3754. }
  3755. MAPI_G(hr) = lpServiceAdmin->SetQuota(cbUserId, lpUserId, lpQuota);
  3756. if (MAPI_G(hr) != hrSuccess)
  3757. goto exit;
  3758. RETVAL_TRUE;
  3759. exit:
  3760. zend_string_release(str_usedefault);
  3761. zend_string_release(str_isuserdefault);
  3762. zend_string_release(str_warnsize);
  3763. zend_string_release(str_softsize);
  3764. zend_string_release(str_hardsize);
  3765. LOG_END();
  3766. THROW_ON_ERROR();
  3767. }
  3768. /**
  3769. * Retrieve user information from zarafa
  3770. * @param logged on msgstore
  3771. * @param username
  3772. * @return array(fullname, emailaddress, userid, admin);
  3773. */
  3774. ZEND_FUNCTION(mapi_zarafa_getuser_by_name)
  3775. {
  3776. PMEASURE_FUNC;
  3777. LOG_BEGIN();
  3778. // params
  3779. zval *res = NULL;
  3780. LPMDB lpMsgStore = NULL;
  3781. char *lpszUsername;
  3782. size_t ulUsername;
  3783. // return value
  3784. // local
  3785. memory_ptr<ECUSER> lpUsers;
  3786. IECUnknown *lpUnknown = NULL;
  3787. object_ptr<IECServiceAdmin> lpServiceAdmin;
  3788. memory_ptr<ENTRYID> lpUserId;
  3789. unsigned int cbUserId = 0;
  3790. RETVAL_FALSE;
  3791. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  3792. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &res, &lpszUsername, &ulUsername) == FAILURE) return;
  3793. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  3794. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  3795. if(MAPI_G(hr) != hrSuccess) {
  3796. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  3797. goto exit;
  3798. }
  3799. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  3800. if(MAPI_G(hr) != hrSuccess)
  3801. goto exit;
  3802. MAPI_G(hr) = lpServiceAdmin->ResolveUserName((TCHAR*)lpszUsername, 0, (ULONG*)&cbUserId, &~lpUserId);
  3803. if(MAPI_G(hr) != hrSuccess) {
  3804. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to resolve the user: %08X", MAPI_G(hr));
  3805. goto exit;
  3806. }
  3807. MAPI_G(hr) = lpServiceAdmin->GetUser(cbUserId, lpUserId, 0, &~lpUsers);
  3808. if (MAPI_G(hr) != hrSuccess) {
  3809. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to get the user: %08X", MAPI_G(hr));
  3810. goto exit;
  3811. }
  3812. array_init(return_value);
  3813. add_assoc_stringl(return_value, "userid", (char*)lpUsers->sUserId.lpb, lpUsers->sUserId.cb);
  3814. add_assoc_string(return_value, "username", (char*)lpUsers->lpszUsername);
  3815. add_assoc_string(return_value, "fullname", (char*)lpUsers->lpszFullName);
  3816. add_assoc_string(return_value, "emailaddress", (char*)lpUsers->lpszMailAddress);
  3817. add_assoc_long(return_value, "admin", lpUsers->ulIsAdmin);
  3818. exit:
  3819. LOG_END();
  3820. THROW_ON_ERROR();
  3821. }
  3822. /**
  3823. * Retrieve user information from zarafa
  3824. * @param logged on msgstore
  3825. * @param userid
  3826. * @return array(fullname, emailaddress, userid, admin);
  3827. */
  3828. ZEND_FUNCTION(mapi_zarafa_getuser_by_id)
  3829. {
  3830. PMEASURE_FUNC;
  3831. LOG_BEGIN();
  3832. // params
  3833. zval *res = NULL;
  3834. LPMDB lpMsgStore = NULL;
  3835. LPENTRYID lpUserId = NULL;
  3836. size_t cbUserId = 0;
  3837. // return value
  3838. // local
  3839. memory_ptr<ECUSER> lpUsers;
  3840. IECUnknown *lpUnknown = NULL;
  3841. object_ptr<IECServiceAdmin> lpServiceAdmin;
  3842. RETVAL_FALSE;
  3843. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  3844. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &res, &lpUserId, &cbUserId) == FAILURE) return;
  3845. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  3846. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  3847. if(MAPI_G(hr) != hrSuccess) {
  3848. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  3849. goto exit;
  3850. }
  3851. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  3852. if(MAPI_G(hr) != hrSuccess)
  3853. goto exit;
  3854. MAPI_G(hr) = lpServiceAdmin->GetUser(cbUserId, lpUserId, 0, &~lpUsers);
  3855. if (MAPI_G(hr) != hrSuccess) {
  3856. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to get the user: %08X", MAPI_G(hr));
  3857. goto exit;
  3858. }
  3859. array_init(return_value);
  3860. add_assoc_stringl(return_value, "userid", (char*)lpUsers->sUserId.lpb, lpUsers->sUserId.cb);
  3861. add_assoc_string(return_value, "username", (char*)lpUsers->lpszUsername);
  3862. add_assoc_string(return_value, "fullname", (char*)lpUsers->lpszFullName);
  3863. add_assoc_string(return_value, "emailaddress", (char*)lpUsers->lpszMailAddress);
  3864. add_assoc_long(return_value, "admin", lpUsers->ulIsAdmin);
  3865. exit:
  3866. LOG_END();
  3867. THROW_ON_ERROR();
  3868. }
  3869. ZEND_FUNCTION(mapi_zarafa_creategroup)
  3870. {
  3871. PMEASURE_FUNC;
  3872. LOG_BEGIN();
  3873. // params
  3874. zval *res = NULL;
  3875. LPMDB lpMsgStore = NULL;
  3876. ECGROUP sGroup;
  3877. size_t cbGroupname;
  3878. // return value
  3879. memory_ptr<ENTRYID> lpGroupId;
  3880. unsigned int cbGroupId = 0;
  3881. // locals
  3882. IECUnknown *lpUnknown = NULL;
  3883. object_ptr<IECServiceAdmin> lpServiceAdmin;
  3884. RETVAL_FALSE;
  3885. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  3886. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &res, &sGroup.lpszGroupname, &cbGroupname) == FAILURE) return;
  3887. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  3888. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  3889. if(MAPI_G(hr) != hrSuccess) {
  3890. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  3891. goto exit;
  3892. }
  3893. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  3894. if(MAPI_G(hr) != hrSuccess)
  3895. goto exit;
  3896. sGroup.lpszFullname = sGroup.lpszGroupname;
  3897. MAPI_G(hr) = lpServiceAdmin->CreateGroup(&sGroup, 0, (ULONG*)&cbGroupId, &~lpGroupId);
  3898. if (MAPI_G(hr) != hrSuccess) {
  3899. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create group: %08X", MAPI_G(hr));
  3900. goto exit;
  3901. }
  3902. RETVAL_STRINGL(reinterpret_cast<const char *>(lpGroupId.get()), cbGroupId);
  3903. exit:
  3904. LOG_END();
  3905. THROW_ON_ERROR();
  3906. }
  3907. ZEND_FUNCTION(mapi_zarafa_deletegroup)
  3908. {
  3909. PMEASURE_FUNC;
  3910. LOG_BEGIN();
  3911. // params
  3912. zval *res = NULL;
  3913. LPMDB lpMsgStore = NULL;
  3914. char *lpszGroupname;
  3915. size_t cbGroupname;
  3916. // return value
  3917. // locals
  3918. IECUnknown *lpUnknown = NULL;
  3919. object_ptr<IECServiceAdmin> lpServiceAdmin;
  3920. memory_ptr<ENTRYID> lpGroupId;
  3921. unsigned int cbGroupId = 0;
  3922. RETVAL_FALSE;
  3923. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  3924. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &res, &lpszGroupname, &cbGroupname) == FAILURE) return;
  3925. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  3926. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  3927. if(MAPI_G(hr) != hrSuccess) {
  3928. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  3929. goto exit;
  3930. }
  3931. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  3932. if(MAPI_G(hr) != hrSuccess)
  3933. goto exit;
  3934. MAPI_G(hr) = lpServiceAdmin->ResolveGroupName((TCHAR*)lpszGroupname, 0, (ULONG*)&cbGroupId, &~lpGroupId);
  3935. if (MAPI_G(hr) != hrSuccess) {
  3936. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Group not found: %08X", MAPI_G(hr));
  3937. goto exit;
  3938. }
  3939. MAPI_G(hr) = lpServiceAdmin->DeleteGroup(cbGroupId, lpGroupId);
  3940. if(MAPI_G(hr) != hrSuccess)
  3941. goto exit;
  3942. RETVAL_TRUE;
  3943. exit:
  3944. LOG_END();
  3945. THROW_ON_ERROR();
  3946. }
  3947. ZEND_FUNCTION(mapi_zarafa_addgroupmember)
  3948. {
  3949. PMEASURE_FUNC;
  3950. LOG_BEGIN();
  3951. // params
  3952. zval *res = NULL;
  3953. LPENTRYID lpGroupId = NULL;
  3954. size_t cbGroupId = 0;
  3955. LPENTRYID lpUserId = NULL;
  3956. size_t cbUserId = 0;
  3957. // return value
  3958. // locals
  3959. IECUnknown *lpUnknown = NULL;
  3960. object_ptr<IECServiceAdmin> lpServiceAdmin;
  3961. IMsgStore *lpMsgStore = NULL;
  3962. RETVAL_FALSE;
  3963. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  3964. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &res, &lpGroupId, &cbGroupId, &lpUserId, &cbUserId) == FAILURE) return;
  3965. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  3966. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  3967. if(MAPI_G(hr) != hrSuccess) {
  3968. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  3969. goto exit;
  3970. }
  3971. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  3972. if(MAPI_G(hr) != hrSuccess)
  3973. goto exit;
  3974. MAPI_G(hr) = lpServiceAdmin->AddGroupUser(cbGroupId, lpGroupId, cbUserId, lpUserId);
  3975. if(MAPI_G(hr) != hrSuccess)
  3976. goto exit;
  3977. RETVAL_TRUE;
  3978. exit:
  3979. LOG_END();
  3980. THROW_ON_ERROR();
  3981. }
  3982. ZEND_FUNCTION(mapi_zarafa_deletegroupmember)
  3983. {
  3984. PMEASURE_FUNC;
  3985. LOG_BEGIN();
  3986. // params
  3987. zval *res = NULL;
  3988. LPENTRYID lpGroupId = NULL;
  3989. size_t cbGroupId = 0;
  3990. LPENTRYID lpUserId = NULL;
  3991. size_t cbUserId = 0;
  3992. // return value
  3993. // locals
  3994. IECUnknown *lpUnknown = NULL;
  3995. object_ptr<IECServiceAdmin> lpServiceAdmin;
  3996. IMsgStore *lpMsgStore = NULL;
  3997. RETVAL_FALSE;
  3998. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  3999. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &res, &lpGroupId, &cbGroupId, &lpUserId, &cbUserId) == FAILURE) return;
  4000. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  4001. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  4002. if(MAPI_G(hr) != hrSuccess) {
  4003. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  4004. goto exit;
  4005. }
  4006. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  4007. if(MAPI_G(hr) != hrSuccess)
  4008. goto exit;
  4009. MAPI_G(hr) = lpServiceAdmin->DeleteGroupUser(cbGroupId, lpGroupId, cbUserId, lpUserId);
  4010. if(MAPI_G(hr) != hrSuccess)
  4011. goto exit;
  4012. RETVAL_TRUE;
  4013. exit:
  4014. LOG_END();
  4015. THROW_ON_ERROR();
  4016. }
  4017. ZEND_FUNCTION(mapi_zarafa_setgroup)
  4018. {
  4019. PMEASURE_FUNC;
  4020. LOG_BEGIN();
  4021. // params
  4022. zval *res = NULL;
  4023. LPMDB lpMsgStore = NULL;
  4024. char *lpszGroupname;
  4025. size_t cbGroupname;
  4026. LPENTRYID *lpGroupId = NULL;
  4027. size_t cbGroupId = 0;
  4028. // return value
  4029. // locals
  4030. IECUnknown *lpUnknown = NULL;
  4031. object_ptr<IECServiceAdmin> lpServiceAdmin;
  4032. ECGROUP sGroup;
  4033. RETVAL_FALSE;
  4034. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4035. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &res, &lpGroupId, &cbGroupId, &lpszGroupname, &cbGroupname) == FAILURE) return;
  4036. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  4037. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  4038. if(MAPI_G(hr) != hrSuccess) {
  4039. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  4040. goto exit;
  4041. }
  4042. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  4043. if(MAPI_G(hr) != hrSuccess)
  4044. goto exit;
  4045. sGroup.sGroupId.cb = cbGroupId;
  4046. sGroup.sGroupId.lpb = (unsigned char*)lpGroupId;
  4047. sGroup.lpszGroupname = (TCHAR*)lpszGroupname;
  4048. MAPI_G(hr) = lpServiceAdmin->SetGroup(&sGroup, 0);
  4049. if(MAPI_G(hr) != hrSuccess)
  4050. goto exit;
  4051. RETVAL_TRUE;
  4052. exit:
  4053. LOG_END();
  4054. THROW_ON_ERROR();
  4055. }
  4056. ZEND_FUNCTION(mapi_zarafa_getgroup_by_id)
  4057. {
  4058. PMEASURE_FUNC;
  4059. LOG_BEGIN();
  4060. // params
  4061. zval *res = NULL;
  4062. LPMDB lpMsgStore = NULL;
  4063. LPENTRYID lpGroupId = NULL;
  4064. size_t cbGroupId = 0;
  4065. // return value
  4066. // locals
  4067. IECUnknown *lpUnknown = NULL;
  4068. object_ptr<IECServiceAdmin> lpServiceAdmin;
  4069. memory_ptr<ECGROUP> lpsGroup;
  4070. RETVAL_FALSE;
  4071. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4072. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &res, &lpGroupId, &cbGroupId) == FAILURE) return;
  4073. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  4074. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  4075. if(MAPI_G(hr) != hrSuccess) {
  4076. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  4077. goto exit;
  4078. }
  4079. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  4080. if(MAPI_G(hr) != hrSuccess)
  4081. goto exit;
  4082. MAPI_G(hr) = lpServiceAdmin->GetGroup(cbGroupId, lpGroupId, 0, &~lpsGroup);
  4083. if(MAPI_G(hr) != hrSuccess)
  4084. goto exit;
  4085. array_init(return_value);
  4086. add_assoc_stringl(return_value, "groupid", (char*)lpGroupId, cbGroupId);
  4087. add_assoc_string(return_value, "groupname", (char*)lpsGroup->lpszGroupname);
  4088. exit:
  4089. LOG_END();
  4090. THROW_ON_ERROR();
  4091. }
  4092. ZEND_FUNCTION(mapi_zarafa_getgroup_by_name)
  4093. {
  4094. PMEASURE_FUNC;
  4095. LOG_BEGIN();
  4096. // params
  4097. zval *res = NULL;
  4098. char *lpszGroupname = NULL;
  4099. size_t ulGroupname;
  4100. // locals
  4101. LPMDB lpMsgStore = NULL;
  4102. IECUnknown *lpUnknown = NULL;
  4103. object_ptr<IECServiceAdmin> lpServiceAdmin;
  4104. memory_ptr<ECGROUP> lpsGroup;
  4105. // return value
  4106. memory_ptr<ENTRYID> lpGroupId;
  4107. unsigned int cbGroupId = 0;
  4108. RETVAL_FALSE;
  4109. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4110. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &res, &lpszGroupname, &ulGroupname) == FAILURE) return;
  4111. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  4112. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  4113. if(MAPI_G(hr) != hrSuccess) {
  4114. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  4115. goto exit;
  4116. }
  4117. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  4118. if(MAPI_G(hr) != hrSuccess)
  4119. goto exit;
  4120. MAPI_G(hr) = lpServiceAdmin->ResolveGroupName((TCHAR*)lpszGroupname, 0, (ULONG*)&cbGroupId, &~lpGroupId);
  4121. if(MAPI_G(hr) != hrSuccess) {
  4122. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to resolve the group: %08X", MAPI_G(hr));
  4123. goto exit;
  4124. }
  4125. MAPI_G(hr) = lpServiceAdmin->GetGroup(cbGroupId, lpGroupId, 0, &~lpsGroup);
  4126. if(MAPI_G(hr) != hrSuccess)
  4127. goto exit;
  4128. array_init(return_value);
  4129. add_assoc_stringl(return_value, "groupid", reinterpret_cast<char *>(lpGroupId.get()), cbGroupId);
  4130. add_assoc_string(return_value, "groupname", (char*)lpsGroup->lpszGroupname);
  4131. exit:
  4132. LOG_END();
  4133. THROW_ON_ERROR();
  4134. }
  4135. ZEND_FUNCTION(mapi_zarafa_getgrouplist)
  4136. {
  4137. PMEASURE_FUNC;
  4138. LOG_BEGIN();
  4139. // params
  4140. zval *res = NULL;
  4141. LPENTRYID lpCompanyId = NULL;
  4142. size_t cbCompanyId = 0;
  4143. // return value
  4144. // locals
  4145. zval zval_data_value;
  4146. LPMDB lpMsgStore = NULL;
  4147. IECUnknown *lpUnknown = NULL;
  4148. object_ptr<IECServiceAdmin> lpServiceAdmin;
  4149. ULONG ulGroups;
  4150. memory_ptr<ECGROUP> lpsGroups;
  4151. unsigned int i;
  4152. RETVAL_FALSE;
  4153. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4154. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|s", &res, &lpCompanyId, &cbCompanyId) == FAILURE) return;
  4155. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  4156. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  4157. if(MAPI_G(hr) != hrSuccess) {
  4158. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  4159. goto exit;
  4160. }
  4161. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  4162. if(MAPI_G(hr) != hrSuccess)
  4163. goto exit;
  4164. MAPI_G(hr) = lpServiceAdmin->GetGroupList(cbCompanyId, lpCompanyId, 0, &ulGroups, &~lpsGroups);
  4165. if(MAPI_G(hr) != hrSuccess)
  4166. goto exit;
  4167. array_init(return_value);
  4168. for (i = 0; i < ulGroups; ++i) {
  4169. array_init(&zval_data_value);
  4170. add_assoc_stringl(&zval_data_value, "groupid", (char*)lpsGroups[i].sGroupId.lpb, lpsGroups[i].sGroupId.cb);
  4171. add_assoc_string(&zval_data_value, "groupname", (char*)lpsGroups[i].lpszGroupname);
  4172. add_assoc_zval(return_value, (char*)lpsGroups[i].lpszGroupname, &zval_data_value);
  4173. }
  4174. exit:
  4175. LOG_END();
  4176. THROW_ON_ERROR();
  4177. }
  4178. ZEND_FUNCTION(mapi_zarafa_getgrouplistofuser)
  4179. {
  4180. PMEASURE_FUNC;
  4181. LOG_BEGIN();
  4182. // params
  4183. zval *res = NULL;
  4184. LPENTRYID lpUserId = NULL;
  4185. size_t cbUserId = 0;
  4186. // return value
  4187. // locals
  4188. zval zval_data_value;
  4189. LPMDB lpMsgStore = NULL;
  4190. IECUnknown *lpUnknown = NULL;
  4191. object_ptr<IECServiceAdmin> lpServiceAdmin;
  4192. ULONG ulGroups;
  4193. memory_ptr<ECGROUP> lpsGroups;
  4194. unsigned int i;
  4195. RETVAL_FALSE;
  4196. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4197. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &res, &lpUserId, &cbUserId) == FAILURE) return;
  4198. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  4199. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  4200. if(MAPI_G(hr) != hrSuccess) {
  4201. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  4202. goto exit;
  4203. }
  4204. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  4205. if(MAPI_G(hr) != hrSuccess)
  4206. goto exit;
  4207. MAPI_G(hr) = lpServiceAdmin->GetGroupListOfUser(cbUserId, lpUserId, 0, &ulGroups, &~lpsGroups);
  4208. if(MAPI_G(hr) != hrSuccess)
  4209. goto exit;
  4210. array_init(return_value);
  4211. for (i = 0; i < ulGroups; ++i) {
  4212. array_init(&zval_data_value);
  4213. add_assoc_stringl(&zval_data_value, "groupid", (char*)lpsGroups[i].sGroupId.lpb, lpsGroups[i].sGroupId.cb);
  4214. add_assoc_string(&zval_data_value, "groupname", (char*)lpsGroups[i].lpszGroupname);
  4215. add_assoc_zval(return_value, (char*)lpsGroups[i].lpszGroupname, &zval_data_value);
  4216. }
  4217. exit:
  4218. LOG_END();
  4219. THROW_ON_ERROR();
  4220. }
  4221. ZEND_FUNCTION(mapi_zarafa_getuserlistofgroup)
  4222. {
  4223. PMEASURE_FUNC;
  4224. LOG_BEGIN();
  4225. // params
  4226. zval *res = NULL;
  4227. LPENTRYID lpGroupId = NULL;
  4228. size_t cbGroupId = 0;
  4229. // return value
  4230. // locals
  4231. zval zval_data_value;
  4232. LPMDB lpMsgStore = NULL;
  4233. IECUnknown *lpUnknown = NULL;
  4234. object_ptr<IECServiceAdmin> lpServiceAdmin;
  4235. ULONG ulUsers;
  4236. memory_ptr<ECUSER> lpsUsers;
  4237. unsigned int i;
  4238. RETVAL_FALSE;
  4239. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4240. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &res, &lpGroupId, &cbGroupId) == FAILURE) return;
  4241. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  4242. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  4243. if(MAPI_G(hr) != hrSuccess) {
  4244. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  4245. goto exit;
  4246. }
  4247. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  4248. if(MAPI_G(hr) != hrSuccess)
  4249. goto exit;
  4250. MAPI_G(hr) = lpServiceAdmin->GetUserListOfGroup(cbGroupId, lpGroupId, 0, &ulUsers, &~lpsUsers);
  4251. if(MAPI_G(hr) != hrSuccess)
  4252. goto exit;
  4253. array_init(return_value);
  4254. for (i = 0; i < ulUsers; ++i) {
  4255. array_init(&zval_data_value);
  4256. add_assoc_stringl(&zval_data_value, "userid", (char*)lpsUsers[i].sUserId.lpb, lpsUsers[i].sUserId.cb);
  4257. add_assoc_string(&zval_data_value, "username", (char*)lpsUsers[i].lpszUsername);
  4258. add_assoc_string(&zval_data_value, "fullname", (char*)lpsUsers[i].lpszFullName);
  4259. add_assoc_string(&zval_data_value, "emailaddress", (char*)lpsUsers[i].lpszMailAddress);
  4260. add_assoc_long(&zval_data_value, "admin", lpsUsers[i].ulIsAdmin);
  4261. add_assoc_zval(return_value, (char*)lpsUsers[i].lpszUsername, &zval_data_value);
  4262. }
  4263. exit:
  4264. LOG_END();
  4265. THROW_ON_ERROR();
  4266. }
  4267. ZEND_FUNCTION(mapi_zarafa_createcompany)
  4268. {
  4269. PMEASURE_FUNC;
  4270. LOG_BEGIN();
  4271. // params
  4272. zval *res = NULL;
  4273. LPMDB lpMsgStore = NULL;
  4274. ECCOMPANY sCompany;
  4275. size_t cbCompanyname;
  4276. // return value
  4277. memory_ptr<ENTRYID> lpCompanyId;
  4278. unsigned int cbCompanyId = 0;
  4279. // locals
  4280. IECUnknown *lpUnknown = NULL;
  4281. object_ptr<IECServiceAdmin> lpServiceAdmin;
  4282. RETVAL_FALSE;
  4283. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4284. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &res, &sCompany.lpszCompanyname, &cbCompanyname) == FAILURE)
  4285. return;
  4286. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  4287. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  4288. if(MAPI_G(hr) != hrSuccess) {
  4289. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  4290. goto exit;
  4291. }
  4292. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  4293. if(MAPI_G(hr) != hrSuccess)
  4294. goto exit;
  4295. MAPI_G(hr) = lpServiceAdmin->CreateCompany(&sCompany, 0, (ULONG*)&cbCompanyId, &~lpCompanyId);
  4296. if (MAPI_G(hr) != hrSuccess) {
  4297. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create company: %08X", MAPI_G(hr));
  4298. goto exit;
  4299. }
  4300. RETVAL_STRINGL(reinterpret_cast<const char *>(lpCompanyId.get()), cbCompanyId);
  4301. exit:
  4302. LOG_END();
  4303. THROW_ON_ERROR();
  4304. }
  4305. ZEND_FUNCTION(mapi_zarafa_deletecompany)
  4306. {
  4307. PMEASURE_FUNC;
  4308. LOG_BEGIN();
  4309. // params
  4310. zval *res = NULL;
  4311. LPMDB lpMsgStore = NULL;
  4312. char *lpszCompanyname;
  4313. size_t cbCompanyname;
  4314. // return value
  4315. // locals
  4316. IECUnknown *lpUnknown = NULL;
  4317. object_ptr<IECServiceAdmin> lpServiceAdmin;
  4318. memory_ptr<ENTRYID> lpCompanyId;
  4319. unsigned int cbCompanyId = 0;
  4320. RETVAL_FALSE;
  4321. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4322. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &res, &lpszCompanyname, &cbCompanyname) == FAILURE)
  4323. return;
  4324. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  4325. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  4326. if(MAPI_G(hr) != hrSuccess) {
  4327. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  4328. goto exit;
  4329. }
  4330. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  4331. if(MAPI_G(hr) != hrSuccess)
  4332. goto exit;
  4333. MAPI_G(hr) = lpServiceAdmin->ResolveCompanyName((TCHAR*)lpszCompanyname, 0, (ULONG*)&cbCompanyId, &~lpCompanyId);
  4334. if (MAPI_G(hr) != hrSuccess) {
  4335. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Company not found: %08X", MAPI_G(hr));
  4336. goto exit;
  4337. }
  4338. MAPI_G(hr) = lpServiceAdmin->DeleteCompany(cbCompanyId, lpCompanyId);
  4339. if(MAPI_G(hr) != hrSuccess)
  4340. goto exit;
  4341. RETVAL_TRUE;
  4342. exit:
  4343. LOG_END();
  4344. THROW_ON_ERROR();
  4345. }
  4346. ZEND_FUNCTION(mapi_zarafa_getcompany_by_id)
  4347. {
  4348. PMEASURE_FUNC;
  4349. LOG_BEGIN();
  4350. // params
  4351. zval *res = NULL;
  4352. LPMDB lpMsgStore = NULL;
  4353. LPENTRYID lpCompanyId = NULL;
  4354. size_t cbCompanyId = 0;
  4355. // return value
  4356. // locals
  4357. IECUnknown *lpUnknown = NULL;
  4358. object_ptr<IECServiceAdmin> lpServiceAdmin;
  4359. memory_ptr<ECCOMPANY> lpsCompany;
  4360. RETVAL_FALSE;
  4361. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4362. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &res, &lpCompanyId, &cbCompanyId) == FAILURE)
  4363. return;
  4364. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  4365. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  4366. if(MAPI_G(hr) != hrSuccess) {
  4367. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  4368. goto exit;
  4369. }
  4370. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  4371. if(MAPI_G(hr) != hrSuccess)
  4372. goto exit;
  4373. MAPI_G(hr) = lpServiceAdmin->GetCompany(cbCompanyId, lpCompanyId, 0, &~lpsCompany);
  4374. if(MAPI_G(hr) != hrSuccess)
  4375. goto exit;
  4376. array_init(return_value);
  4377. add_assoc_stringl(return_value, "companyid", (char*)lpCompanyId, cbCompanyId);
  4378. add_assoc_string(return_value, "companyname", (char*)lpsCompany->lpszCompanyname);
  4379. exit:
  4380. LOG_END();
  4381. THROW_ON_ERROR();
  4382. }
  4383. ZEND_FUNCTION(mapi_zarafa_getcompany_by_name)
  4384. {
  4385. PMEASURE_FUNC;
  4386. LOG_BEGIN();
  4387. // params
  4388. zval *res = NULL;
  4389. LPMDB lpMsgStore = NULL;
  4390. char *lpszCompanyname = NULL;
  4391. size_t ulCompanyname;
  4392. memory_ptr<ENTRYID> lpCompanyId;
  4393. unsigned int cbCompanyId = 0;
  4394. // return value
  4395. // locals
  4396. IECUnknown *lpUnknown = NULL;
  4397. object_ptr<IECServiceAdmin> lpServiceAdmin;
  4398. memory_ptr<ECCOMPANY> lpsCompany;
  4399. RETVAL_FALSE;
  4400. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4401. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &res, &lpszCompanyname, &ulCompanyname) == FAILURE)
  4402. return;
  4403. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  4404. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  4405. if(MAPI_G(hr) != hrSuccess) {
  4406. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  4407. goto exit;
  4408. }
  4409. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  4410. if(MAPI_G(hr) != hrSuccess)
  4411. goto exit;
  4412. MAPI_G(hr) = lpServiceAdmin->ResolveCompanyName((TCHAR*)lpszCompanyname, 0, (ULONG*)&cbCompanyId, &~lpCompanyId);
  4413. if(MAPI_G(hr) != hrSuccess) {
  4414. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to resolve the company: %08X", MAPI_G(hr));
  4415. goto exit;
  4416. }
  4417. MAPI_G(hr) = lpServiceAdmin->GetCompany(cbCompanyId, lpCompanyId, 0, &~lpsCompany);
  4418. if(MAPI_G(hr) != hrSuccess)
  4419. goto exit;
  4420. array_init(return_value);
  4421. add_assoc_stringl(return_value, "companyid", reinterpret_cast<char *>(lpCompanyId.get()), cbCompanyId);
  4422. add_assoc_string(return_value, "companyname", (char*)lpsCompany->lpszCompanyname);
  4423. exit:
  4424. LOG_END();
  4425. THROW_ON_ERROR();
  4426. }
  4427. ZEND_FUNCTION(mapi_zarafa_getcompanylist)
  4428. {
  4429. PMEASURE_FUNC;
  4430. LOG_BEGIN();
  4431. // params
  4432. zval *res = NULL;
  4433. zval zval_data_value;
  4434. LPMDB lpMsgStore = NULL;
  4435. // return value
  4436. // local
  4437. ULONG nCompanies, i;
  4438. memory_ptr<ECCOMPANY> lpCompanies;
  4439. IECUnknown *lpUnknown = NULL;;
  4440. object_ptr<IECSecurity> lpSecurity;
  4441. RETVAL_FALSE;
  4442. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4443. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &res) == FAILURE)
  4444. return;
  4445. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  4446. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  4447. if(MAPI_G(hr) != hrSuccess) {
  4448. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  4449. goto exit;
  4450. }
  4451. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECSecurity, &~lpSecurity);
  4452. if(MAPI_G(hr) != hrSuccess)
  4453. goto exit;
  4454. MAPI_G(hr) = lpSecurity->GetCompanyList(0, &nCompanies, &~lpCompanies);
  4455. if (MAPI_G(hr) != hrSuccess)
  4456. goto exit;
  4457. array_init(return_value);
  4458. for (i = 0; i < nCompanies; ++i) {
  4459. array_init(&zval_data_value);
  4460. add_assoc_stringl(&zval_data_value, "companyid", (char*)lpCompanies[i].sCompanyId.lpb, lpCompanies[i].sCompanyId.cb);
  4461. add_assoc_string(&zval_data_value, "companyname", (char*)lpCompanies[i].lpszCompanyname);
  4462. add_assoc_zval(return_value, (char*)lpCompanies[i].lpszCompanyname, &zval_data_value);
  4463. }
  4464. exit:
  4465. LOG_END();
  4466. THROW_ON_ERROR();
  4467. }
  4468. ZEND_FUNCTION(mapi_zarafa_add_company_remote_viewlist)
  4469. {
  4470. PMEASURE_FUNC;
  4471. LOG_BEGIN();
  4472. zval *res = NULL;
  4473. LPENTRYID lpSetCompanyId = NULL;
  4474. size_t cbSetCompanyId = 0;
  4475. LPENTRYID lpCompanyId = NULL;
  4476. size_t cbCompanyId = 0;
  4477. /* Locals */
  4478. IECUnknown *lpUnknown = NULL;
  4479. object_ptr<IECServiceAdmin> lpServiceAdmin;
  4480. IMsgStore *lpMsgStore = NULL;
  4481. RETVAL_FALSE;
  4482. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4483. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &res, &lpSetCompanyId, &cbSetCompanyId, &lpCompanyId, &cbCompanyId) == FAILURE)
  4484. return;
  4485. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  4486. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  4487. if (MAPI_G(hr) != hrSuccess) {
  4488. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  4489. goto exit;
  4490. }
  4491. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  4492. if (MAPI_G(hr) != hrSuccess)
  4493. goto exit;
  4494. MAPI_G(hr) = lpServiceAdmin->AddCompanyToRemoteViewList(cbSetCompanyId, lpSetCompanyId, cbCompanyId, lpCompanyId);
  4495. if (MAPI_G(hr) != hrSuccess)
  4496. goto exit;
  4497. RETVAL_TRUE;
  4498. exit:
  4499. LOG_END();
  4500. THROW_ON_ERROR();
  4501. }
  4502. ZEND_FUNCTION(mapi_zarafa_del_company_remote_viewlist)
  4503. {
  4504. PMEASURE_FUNC;
  4505. LOG_BEGIN();
  4506. zval *res = NULL;
  4507. LPENTRYID lpSetCompanyId = NULL;
  4508. size_t cbSetCompanyId = 0;
  4509. LPENTRYID lpCompanyId = NULL;
  4510. size_t cbCompanyId = 0;
  4511. /* Locals */
  4512. IECUnknown *lpUnknown = NULL;
  4513. object_ptr<IECServiceAdmin> lpServiceAdmin;
  4514. IMsgStore *lpMsgStore = NULL;
  4515. RETVAL_FALSE;
  4516. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4517. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &res, &lpSetCompanyId, &cbSetCompanyId, &lpCompanyId, &cbCompanyId) == FAILURE)
  4518. return;
  4519. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  4520. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  4521. if (MAPI_G(hr) != hrSuccess) {
  4522. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  4523. goto exit;
  4524. }
  4525. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  4526. if (MAPI_G(hr) != hrSuccess)
  4527. goto exit;
  4528. MAPI_G(hr) = lpServiceAdmin->DelCompanyFromRemoteViewList(cbSetCompanyId, lpSetCompanyId, cbCompanyId, lpCompanyId);
  4529. if (MAPI_G(hr) != hrSuccess)
  4530. goto exit;
  4531. RETVAL_TRUE;
  4532. exit:
  4533. LOG_END();
  4534. THROW_ON_ERROR();
  4535. }
  4536. ZEND_FUNCTION(mapi_zarafa_get_remote_viewlist)
  4537. {
  4538. PMEASURE_FUNC;
  4539. LOG_BEGIN();
  4540. zval *res = NULL;
  4541. LPENTRYID lpCompanyId = NULL;
  4542. size_t cbCompanyId = 0;
  4543. /* Locals */
  4544. zval zval_data_value;
  4545. IECUnknown *lpUnknown = NULL;
  4546. object_ptr<IECServiceAdmin> lpServiceAdmin;
  4547. IMsgStore *lpMsgStore = NULL;
  4548. ULONG ulCompanies = 0;
  4549. memory_ptr<ECCOMPANY> lpsCompanies;
  4550. RETVAL_FALSE;
  4551. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4552. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &res, &lpCompanyId, &cbCompanyId) == FAILURE)
  4553. return;
  4554. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  4555. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  4556. if (MAPI_G(hr) != hrSuccess) {
  4557. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  4558. goto exit;
  4559. }
  4560. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  4561. if (MAPI_G(hr) != hrSuccess)
  4562. goto exit;
  4563. MAPI_G(hr) = lpServiceAdmin->GetRemoteViewList(cbCompanyId, lpCompanyId, 0, &ulCompanies, &~lpsCompanies);
  4564. if (MAPI_G(hr) != hrSuccess)
  4565. goto exit;
  4566. array_init(return_value);
  4567. for (unsigned int i = 0; i < ulCompanies; ++i) {
  4568. array_init(&zval_data_value);
  4569. add_assoc_stringl(&zval_data_value, "companyid", (char*)lpsCompanies[i].sCompanyId.lpb, lpsCompanies[i].sCompanyId.cb);
  4570. add_assoc_string(&zval_data_value, "companyname", (char*)lpsCompanies[i].lpszCompanyname);
  4571. add_assoc_zval(return_value, (char*)lpsCompanies[i].lpszCompanyname, &zval_data_value);
  4572. }
  4573. exit:
  4574. LOG_END();
  4575. THROW_ON_ERROR();
  4576. }
  4577. ZEND_FUNCTION(mapi_zarafa_add_user_remote_adminlist)
  4578. {
  4579. PMEASURE_FUNC;
  4580. LOG_BEGIN();
  4581. zval *res = NULL;
  4582. LPENTRYID lpUserId = NULL;
  4583. size_t cbUserId = 0;
  4584. LPENTRYID lpCompanyId = NULL;
  4585. size_t cbCompanyId = 0;
  4586. /* Locals */
  4587. IECUnknown *lpUnknown = NULL;
  4588. object_ptr<IECServiceAdmin> lpServiceAdmin;
  4589. IMsgStore *lpMsgStore = NULL;
  4590. RETVAL_FALSE;
  4591. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4592. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &res, &lpUserId, &cbUserId, &lpCompanyId, &cbCompanyId) == FAILURE)
  4593. return;
  4594. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  4595. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  4596. if (MAPI_G(hr) != hrSuccess) {
  4597. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  4598. goto exit;
  4599. }
  4600. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  4601. if (MAPI_G(hr) != hrSuccess)
  4602. goto exit;
  4603. MAPI_G(hr) = lpServiceAdmin->AddUserToRemoteAdminList(cbUserId, lpUserId, cbCompanyId, lpCompanyId);
  4604. if (MAPI_G(hr) != hrSuccess)
  4605. goto exit;
  4606. RETVAL_TRUE;
  4607. exit:
  4608. LOG_END();
  4609. THROW_ON_ERROR();
  4610. }
  4611. ZEND_FUNCTION(mapi_zarafa_del_user_remote_adminlist)
  4612. {
  4613. PMEASURE_FUNC;
  4614. LOG_BEGIN();
  4615. zval *res = NULL;
  4616. LPENTRYID lpUserId = NULL;
  4617. size_t cbUserId = 0;
  4618. LPENTRYID lpCompanyId = NULL;
  4619. size_t cbCompanyId = 0;
  4620. /* Locals */
  4621. IECUnknown *lpUnknown = NULL;
  4622. object_ptr<IECServiceAdmin> lpServiceAdmin;
  4623. IMsgStore *lpMsgStore = NULL;
  4624. RETVAL_FALSE;
  4625. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4626. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &res, &lpUserId, &cbUserId, &lpCompanyId, &cbCompanyId) == FAILURE)
  4627. return;
  4628. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  4629. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  4630. if (MAPI_G(hr) != hrSuccess) {
  4631. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  4632. goto exit;
  4633. }
  4634. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  4635. if (MAPI_G(hr) != hrSuccess)
  4636. goto exit;
  4637. MAPI_G(hr) = lpServiceAdmin->DelUserFromRemoteAdminList(cbUserId, lpUserId, cbCompanyId, lpCompanyId);
  4638. if (MAPI_G(hr) != hrSuccess)
  4639. goto exit;
  4640. RETVAL_TRUE;
  4641. exit:
  4642. LOG_END();
  4643. THROW_ON_ERROR();
  4644. }
  4645. ZEND_FUNCTION(mapi_zarafa_get_remote_adminlist)
  4646. {
  4647. PMEASURE_FUNC;
  4648. LOG_BEGIN();
  4649. zval *res = NULL;
  4650. LPENTRYID lpCompanyId = NULL;
  4651. size_t cbCompanyId = 0;
  4652. /* Locals */
  4653. zval zval_data_value;
  4654. IECUnknown *lpUnknown = NULL;
  4655. object_ptr<IECServiceAdmin> lpServiceAdmin;
  4656. IMsgStore *lpMsgStore = NULL;
  4657. ULONG ulUsers = 0;
  4658. memory_ptr<ECUSER> lpsUsers;
  4659. RETVAL_FALSE;
  4660. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4661. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &res, &lpCompanyId, &cbCompanyId) == FAILURE)
  4662. return;
  4663. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  4664. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  4665. if (MAPI_G(hr) != hrSuccess) {
  4666. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  4667. goto exit;
  4668. }
  4669. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, &~lpServiceAdmin);
  4670. if (MAPI_G(hr) != hrSuccess)
  4671. goto exit;
  4672. MAPI_G(hr) = lpServiceAdmin->GetRemoteAdminList(cbCompanyId, lpCompanyId, 0, &ulUsers, &~lpsUsers);
  4673. if (MAPI_G(hr) != hrSuccess)
  4674. goto exit;
  4675. array_init(return_value);
  4676. for (unsigned int i = 0; i < ulUsers; ++i) {
  4677. array_init(&zval_data_value);
  4678. add_assoc_stringl(&zval_data_value, "userid", (char*)lpsUsers[i].sUserId.lpb, lpsUsers[i].sUserId.cb);
  4679. add_assoc_string(&zval_data_value, "username", (char*)lpsUsers[i].lpszUsername);
  4680. add_assoc_zval(return_value, (char*)lpsUsers[i].lpszUsername, &zval_data_value);
  4681. }
  4682. exit:
  4683. LOG_END();
  4684. THROW_ON_ERROR();
  4685. }
  4686. ZEND_FUNCTION(mapi_zarafa_add_quota_recipient)
  4687. {
  4688. PMEASURE_FUNC;
  4689. LOG_BEGIN();
  4690. zval *res = NULL;
  4691. LPENTRYID lpRecipientId = NULL;
  4692. size_t cbRecipientId = 0;
  4693. LPENTRYID lpCompanyId = NULL;
  4694. size_t cbCompanyId = 0;
  4695. long ulType = 0;
  4696. /* Locals */
  4697. IECUnknown *lpUnknown = NULL;
  4698. IECServiceAdmin *lpServiceAdmin = NULL;
  4699. IMsgStore *lpMsgStore = NULL;
  4700. RETVAL_FALSE;
  4701. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4702. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rssl", &res, &lpCompanyId, &cbCompanyId, &lpRecipientId, &cbRecipientId, &ulType) == FAILURE)
  4703. return;
  4704. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  4705. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  4706. if (MAPI_G(hr) != hrSuccess) {
  4707. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  4708. goto exit;
  4709. }
  4710. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, (void**)&lpServiceAdmin);
  4711. if (MAPI_G(hr) != hrSuccess)
  4712. goto exit;
  4713. MAPI_G(hr) = lpServiceAdmin->AddQuotaRecipient(cbCompanyId, lpCompanyId, cbRecipientId, lpRecipientId, ulType);
  4714. if (MAPI_G(hr) != hrSuccess)
  4715. goto exit;
  4716. RETVAL_TRUE;
  4717. exit:
  4718. LOG_END();
  4719. THROW_ON_ERROR();
  4720. }
  4721. ZEND_FUNCTION(mapi_zarafa_del_quota_recipient)
  4722. {
  4723. PMEASURE_FUNC;
  4724. LOG_BEGIN();
  4725. zval *res = NULL;
  4726. LPENTRYID lpRecipientId = NULL;
  4727. size_t cbRecipientId = 0;
  4728. LPENTRYID lpCompanyId = NULL;
  4729. size_t cbCompanyId = 0;
  4730. long ulType = 0;
  4731. /* Locals */
  4732. IECUnknown *lpUnknown = NULL;
  4733. IECServiceAdmin *lpServiceAdmin = NULL;
  4734. IMsgStore *lpMsgStore = NULL;
  4735. RETVAL_FALSE;
  4736. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4737. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rssl", &res, &lpCompanyId, &cbCompanyId, &lpRecipientId, &cbRecipientId, &ulType) == FAILURE)
  4738. return;
  4739. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  4740. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  4741. if (MAPI_G(hr) != hrSuccess) {
  4742. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  4743. goto exit;
  4744. }
  4745. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, (void**)&lpServiceAdmin);
  4746. if (MAPI_G(hr) != hrSuccess)
  4747. goto exit;
  4748. MAPI_G(hr) = lpServiceAdmin->DeleteQuotaRecipient(cbCompanyId, lpCompanyId, cbRecipientId, lpRecipientId, ulType);
  4749. if (MAPI_G(hr) != hrSuccess)
  4750. goto exit;
  4751. RETVAL_TRUE;
  4752. exit:
  4753. LOG_END();
  4754. THROW_ON_ERROR();
  4755. }
  4756. ZEND_FUNCTION(mapi_zarafa_get_quota_recipientlist)
  4757. {
  4758. PMEASURE_FUNC;
  4759. LOG_BEGIN();
  4760. zval *res = NULL;
  4761. LPENTRYID lpObjectId = NULL;
  4762. size_t cbObjectId = 0;
  4763. /* Locals */
  4764. zval zval_data_value;
  4765. IECUnknown *lpUnknown = NULL;
  4766. IECServiceAdmin *lpServiceAdmin = NULL;
  4767. IMsgStore *lpMsgStore = NULL;
  4768. ULONG ulUsers = 0;
  4769. memory_ptr<ECUSER> lpsUsers;
  4770. RETVAL_FALSE;
  4771. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4772. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &res, &lpObjectId, &cbObjectId) == FAILURE)
  4773. return;
  4774. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  4775. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  4776. if (MAPI_G(hr) != hrSuccess) {
  4777. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano store");
  4778. goto exit;
  4779. }
  4780. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECServiceAdmin, (void**)&lpServiceAdmin);
  4781. if (MAPI_G(hr) != hrSuccess)
  4782. goto exit;
  4783. MAPI_G(hr) = lpServiceAdmin->GetQuotaRecipients(cbObjectId, lpObjectId, 0, &ulUsers, &~lpsUsers);
  4784. if (MAPI_G(hr) != hrSuccess)
  4785. goto exit;
  4786. array_init(return_value);
  4787. for (unsigned int i = 0; i < ulUsers; ++i) {
  4788. array_init(&zval_data_value);
  4789. add_assoc_stringl(&zval_data_value, "userid", (char*)lpsUsers[i].sUserId.lpb, lpsUsers[i].sUserId.cb);
  4790. add_assoc_string(&zval_data_value, "username", (char*)lpsUsers[i].lpszUsername);
  4791. add_assoc_zval(return_value, (char*)lpsUsers[i].lpszUsername, &zval_data_value);
  4792. }
  4793. exit:
  4794. LOG_END();
  4795. THROW_ON_ERROR();
  4796. }
  4797. ZEND_FUNCTION(mapi_zarafa_check_license)
  4798. {
  4799. PMEASURE_FUNC;
  4800. LOG_BEGIN();
  4801. zval *res = NULL;
  4802. IMsgStore *lpMsgStore = NULL;
  4803. char *szFeature = NULL;
  4804. size_t cbFeature = 0;
  4805. IECUnknown *lpUnknown = NULL;
  4806. object_ptr<IECLicense> lpLicense;
  4807. memory_ptr<char *> lpszCapas;
  4808. unsigned int ulCapas = 0;
  4809. RETVAL_FALSE;
  4810. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4811. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &res, &szFeature, &cbFeature) == FAILURE)
  4812. return;
  4813. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  4814. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  4815. if(MAPI_G(hr) != hrSuccess)
  4816. goto exit;
  4817. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECLicense, &~lpLicense);
  4818. if(MAPI_G(hr) != hrSuccess)
  4819. goto exit;
  4820. MAPI_G(hr) = lpLicense->LicenseCapa(0/*SERVICE_TYPE_ZCP*/, &~lpszCapas, &ulCapas);
  4821. if(MAPI_G(hr) != hrSuccess)
  4822. goto exit;
  4823. for (ULONG i = 0; i < ulCapas; ++i)
  4824. if(strcasecmp(lpszCapas[i], szFeature) == 0) {
  4825. RETVAL_TRUE;
  4826. break;
  4827. }
  4828. exit:
  4829. LOG_END();
  4830. THROW_ON_ERROR();
  4831. }
  4832. ZEND_FUNCTION(mapi_zarafa_getcapabilities)
  4833. {
  4834. PMEASURE_FUNC;
  4835. LOG_BEGIN();
  4836. zval *res = NULL;
  4837. IMsgStore *lpMsgStore = NULL;
  4838. IECUnknown *lpUnknown = NULL;
  4839. object_ptr<IECLicense> lpLicense;
  4840. memory_ptr<char *> lpszCapas;
  4841. unsigned int ulCapas = 0;
  4842. RETVAL_FALSE;
  4843. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4844. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &res) == FAILURE)
  4845. return;
  4846. ZEND_FETCH_RESOURCE_C(lpMsgStore, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  4847. MAPI_G(hr) = GetECObject(lpMsgStore, &lpUnknown TSRMLS_CC);
  4848. if(MAPI_G(hr) != hrSuccess)
  4849. goto exit;
  4850. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECLicense, &~lpLicense);
  4851. if(MAPI_G(hr) != hrSuccess)
  4852. goto exit;
  4853. MAPI_G(hr) = lpLicense->LicenseCapa(0/*SERVICE_TYPE_ZCP*/, &~lpszCapas, &ulCapas);
  4854. if(MAPI_G(hr) != hrSuccess)
  4855. goto exit;
  4856. array_init(return_value);
  4857. for (ULONG i = 0; i < ulCapas; ++i)
  4858. add_index_string(return_value, i, lpszCapas[i]);
  4859. exit:
  4860. LOG_END();
  4861. THROW_ON_ERROR();
  4862. }
  4863. ZEND_FUNCTION(mapi_zarafa_getpermissionrules)
  4864. {
  4865. PMEASURE_FUNC;
  4866. LOG_BEGIN();
  4867. // params
  4868. zval *res = NULL;
  4869. LPMAPIPROP lpMapiProp = NULL;
  4870. long ulType;
  4871. // return value
  4872. zval zval_data_value;
  4873. ULONG cPerms = 0;
  4874. memory_ptr<ECPERMISSION> lpECPerms;
  4875. // local
  4876. int type = -1;
  4877. IECUnknown *lpUnknown = NULL;
  4878. IECSecurity *lpSecurity = NULL;
  4879. ULONG i;
  4880. RETVAL_FALSE;
  4881. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4882. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &res, &ulType) == FAILURE) return;
  4883. type = Z_RES_P(res)->type;
  4884. if(type == le_mapi_message) {
  4885. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMESSAGE, &res, -1, name_mapi_message, le_mapi_message);
  4886. } else if (type == le_mapi_folder) {
  4887. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMAPIFOLDER, &res, -1, name_mapi_folder, le_mapi_folder);
  4888. } else if (type == le_mapi_attachment) {
  4889. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPATTACH, &res, -1, name_mapi_attachment, le_mapi_attachment);
  4890. } else if (type == le_mapi_msgstore) {
  4891. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  4892. } else {
  4893. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Resource is not a valid MAPI resource");
  4894. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4895. goto exit;
  4896. }
  4897. MAPI_G(hr) = GetECObject(lpMapiProp, &lpUnknown TSRMLS_CC);
  4898. if(MAPI_G(hr) != hrSuccess) {
  4899. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano object");
  4900. goto exit;
  4901. }
  4902. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECSecurity, (void**)&lpSecurity);
  4903. if (MAPI_G(hr) != hrSuccess)
  4904. goto exit;
  4905. MAPI_G(hr) = lpSecurity->GetPermissionRules(ulType, &cPerms, &~lpECPerms);
  4906. if (MAPI_G(hr) != hrSuccess)
  4907. goto exit;
  4908. array_init(return_value);
  4909. for (i = 0; i < cPerms; ++i) {
  4910. array_init(&zval_data_value);
  4911. add_assoc_stringl(&zval_data_value, "userid", (char*)lpECPerms[i].sUserId.lpb, lpECPerms[i].sUserId.cb);
  4912. add_assoc_long(&zval_data_value, "type", lpECPerms[i].ulType);
  4913. add_assoc_long(&zval_data_value, "rights", lpECPerms[i].ulRights);
  4914. add_assoc_long(&zval_data_value, "state", lpECPerms[i].ulState);
  4915. add_index_zval(return_value, i, &zval_data_value);
  4916. }
  4917. exit:
  4918. LOG_END();
  4919. THROW_ON_ERROR();
  4920. }
  4921. ZEND_FUNCTION(mapi_zarafa_setpermissionrules)
  4922. {
  4923. PMEASURE_FUNC;
  4924. LOG_BEGIN();
  4925. // params
  4926. zval *res = NULL;
  4927. zval *perms = NULL;
  4928. LPMAPIPROP lpMapiProp = NULL;
  4929. // local
  4930. int type = -1;
  4931. IECUnknown *lpUnknown = NULL;
  4932. object_ptr<IECSecurity> lpSecurity;
  4933. ULONG cPerms = 0;
  4934. memory_ptr<ECPERMISSION> lpECPerms;
  4935. HashTable *target_hash = NULL;
  4936. ULONG j;
  4937. zval *entry = NULL, *value = NULL;
  4938. HashTable *data = NULL;
  4939. zend_string *str_userid = zend_string_init("userid", sizeof("userid")-1, 0);
  4940. zend_string *str_type = zend_string_init("type", sizeof("type")-1, 0);
  4941. zend_string *str_rights = zend_string_init("rights", sizeof("rights")-1, 0);
  4942. zend_string *str_state = zend_string_init("state", sizeof("state")-1, 0);
  4943. RETVAL_FALSE;
  4944. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4945. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra", &res, &perms) == FAILURE) return;
  4946. type = Z_RES_P(res)->type;
  4947. if(type == le_mapi_message) {
  4948. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMESSAGE, &res, -1, name_mapi_message, le_mapi_message);
  4949. } else if (type == le_mapi_folder) {
  4950. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMAPIFOLDER, &res, -1, name_mapi_folder, le_mapi_folder);
  4951. } else if (type == le_mapi_attachment) {
  4952. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPATTACH, &res, -1, name_mapi_attachment, le_mapi_attachment);
  4953. } else if (type == le_mapi_msgstore) {
  4954. ZEND_FETCH_RESOURCE_C(lpMapiProp, LPMDB, &res, -1, name_mapi_msgstore, le_mapi_msgstore);
  4955. } else {
  4956. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Resource is not a valid MAPI resource");
  4957. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4958. goto exit;
  4959. }
  4960. MAPI_G(hr) = GetECObject(lpMapiProp, &lpUnknown TSRMLS_CC);
  4961. if(MAPI_G(hr) != hrSuccess) {
  4962. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified object is not a Kopano object");
  4963. goto exit;
  4964. }
  4965. MAPI_G(hr) = lpUnknown->QueryInterface(IID_IECSecurity, &~lpSecurity);
  4966. if (MAPI_G(hr) != hrSuccess)
  4967. goto exit;
  4968. ZVAL_DEREF(perms);
  4969. target_hash = HASH_OF(perms);
  4970. if (!target_hash) {
  4971. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  4972. goto exit;
  4973. }
  4974. // The following code should be in typeconversion.cpp
  4975. cPerms = zend_hash_num_elements(target_hash);
  4976. MAPI_G(hr) = MAPIAllocateBuffer(sizeof(ECPERMISSION)*cPerms, &~lpECPerms);
  4977. if (MAPI_G(hr) != hrSuccess)
  4978. goto exit;
  4979. memset(lpECPerms, 0, sizeof(ECPERMISSION)*cPerms);
  4980. j = 0;
  4981. ZEND_HASH_FOREACH_VAL(target_hash, entry) {
  4982. // null pointer returned if perms was not array(array()).
  4983. ZVAL_DEREF(entry);
  4984. data = HASH_OF(entry);
  4985. zend_hash_internal_pointer_reset(data);
  4986. if ((value = zend_hash_find(data, str_userid)) == nullptr)
  4987. continue;
  4988. convert_to_string_ex(value);
  4989. lpECPerms[j].sUserId.cb = Z_STRLEN_P(value);
  4990. lpECPerms[j].sUserId.lpb = (unsigned char*)Z_STRVAL_P(value);
  4991. if ((value = zend_hash_find(data, str_type)) == nullptr)
  4992. continue;
  4993. convert_to_long_ex(value);
  4994. lpECPerms[j].ulType = Z_LVAL_P(value);
  4995. if ((value = zend_hash_find(data, str_rights)) == nullptr)
  4996. continue;
  4997. convert_to_long_ex(value);
  4998. lpECPerms[j].ulRights = Z_LVAL_P(value);
  4999. if ((value = zend_hash_find(data, str_state)) != NULL) {
  5000. convert_to_long_ex(value);
  5001. lpECPerms[j].ulState = Z_LVAL_P(value);
  5002. } else {
  5003. lpECPerms[j].ulState = RIGHT_NEW|RIGHT_AUTOUPDATE_DENIED;
  5004. }
  5005. ++j;
  5006. } ZEND_HASH_FOREACH_END();
  5007. MAPI_G(hr) = lpSecurity->SetPermissionRules(j, lpECPerms);
  5008. if (MAPI_G(hr) != hrSuccess)
  5009. goto exit;
  5010. RETVAL_TRUE;
  5011. exit:
  5012. zend_string_release(str_userid);
  5013. zend_string_release(str_type);
  5014. zend_string_release(str_rights);
  5015. zend_string_release(str_state);
  5016. LOG_END();
  5017. THROW_ON_ERROR();
  5018. }
  5019. ZEND_FUNCTION(mapi_freebusysupport_open)
  5020. {
  5021. PMEASURE_FUNC;
  5022. LOG_BEGIN();
  5023. // local
  5024. object_ptr<ECFreeBusySupport> lpecFBSupport;
  5025. // extern
  5026. zval* resSession = NULL;
  5027. zval* resStore = NULL;
  5028. IMAPISession* lpSession = NULL;
  5029. IMsgStore* lpUserStore = NULL;
  5030. // return
  5031. object_ptr<IFreeBusySupport> lpFBSupport;
  5032. RETVAL_FALSE;
  5033. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5034. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|r", &resSession, &resStore) == FAILURE) return;
  5035. ZEND_FETCH_RESOURCE_C(lpSession, IMAPISession*, &resSession, -1, name_mapi_session, le_mapi_session);
  5036. if(resStore != NULL) {
  5037. ZEND_FETCH_RESOURCE_C(lpUserStore, LPMDB, &resStore, -1, name_mapi_msgstore, le_mapi_msgstore);
  5038. }
  5039. // Create the zarafa freebusy support object
  5040. MAPI_G(hr) = ECFreeBusySupport::Create(&~lpecFBSupport);
  5041. if( MAPI_G(hr) != hrSuccess)
  5042. goto exit;
  5043. MAPI_G(hr) = lpecFBSupport->QueryInterface(IID_IFreeBusySupport, &~lpFBSupport);
  5044. if( MAPI_G(hr) != hrSuccess)
  5045. goto exit;
  5046. MAPI_G(hr) = lpFBSupport->Open(lpSession, lpUserStore, (lpUserStore)?TRUE:FALSE);
  5047. if( MAPI_G(hr) != hrSuccess)
  5048. goto exit;
  5049. UOBJ_REGISTER_RESOURCE(return_value, lpFBSupport.release(), le_freebusy_support);
  5050. exit:
  5051. LOG_END();
  5052. THROW_ON_ERROR();
  5053. }
  5054. ZEND_FUNCTION(mapi_freebusysupport_close)
  5055. {
  5056. PMEASURE_FUNC;
  5057. LOG_BEGIN();
  5058. // Extern
  5059. IFreeBusySupport* lpFBSupport = NULL;
  5060. zval* resFBSupport = NULL;
  5061. RETVAL_FALSE;
  5062. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5063. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &resFBSupport) == FAILURE) return;
  5064. ZEND_FETCH_RESOURCE_C(lpFBSupport, IFreeBusySupport*, &resFBSupport, -1, name_fb_support, le_freebusy_support);
  5065. MAPI_G(hr) = lpFBSupport->Close();
  5066. if(MAPI_G(hr) != hrSuccess)
  5067. goto exit;
  5068. RETVAL_TRUE;
  5069. exit:
  5070. LOG_END();
  5071. THROW_ON_ERROR();
  5072. }
  5073. ZEND_FUNCTION(mapi_freebusysupport_loaddata)
  5074. {
  5075. PMEASURE_FUNC;
  5076. LOG_BEGIN();
  5077. HashTable* target_hash = NULL;
  5078. ULONG i, j;
  5079. zval* entry = NULL;
  5080. zend_resource * rid = NULL;
  5081. memory_ptr<FBUser> lpUsers;
  5082. IFreeBusySupport* lpFBSupport = NULL;
  5083. zval* resFBSupport = NULL;
  5084. zval* resUsers = NULL;
  5085. ULONG cUsers = 0;
  5086. IFreeBusyData** lppFBData = NULL;
  5087. ULONG cFBData = 0;
  5088. RETVAL_FALSE;
  5089. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5090. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra", &resFBSupport,&resUsers) == FAILURE) return;
  5091. ZEND_FETCH_RESOURCE_C(lpFBSupport, IFreeBusySupport*, &resFBSupport, -1, name_fb_support, le_freebusy_support);
  5092. ZVAL_DEREF(resUsers);
  5093. target_hash = HASH_OF(resUsers);
  5094. if (!target_hash) {
  5095. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5096. goto exit;
  5097. }
  5098. cUsers = zend_hash_num_elements(target_hash);
  5099. MAPI_G(hr) = MAPIAllocateBuffer(sizeof(FBUser)*cUsers, &~lpUsers);
  5100. if(MAPI_G(hr) != hrSuccess)
  5101. goto exit;
  5102. // Get the user entryids
  5103. j = 0;
  5104. ZEND_HASH_FOREACH_VAL(target_hash, entry) {
  5105. if(!entry) {
  5106. MAPI_G(hr) = MAPI_E_INVALID_ENTRYID;
  5107. goto exit;
  5108. }
  5109. lpUsers[j].m_cbEid = Z_STRLEN_P(entry);
  5110. lpUsers[j].m_lpEid = (LPENTRYID)Z_STRVAL_P(entry);
  5111. ++j;
  5112. } ZEND_HASH_FOREACH_END();
  5113. MAPI_G(hr) = MAPIAllocateBuffer(sizeof(IFreeBusyData*)*cUsers, (void**)&lppFBData);
  5114. if(MAPI_G(hr) != hrSuccess)
  5115. goto exit;
  5116. MAPI_G(hr) = lpFBSupport->LoadFreeBusyData(cUsers, lpUsers, lppFBData, NULL, &cFBData);
  5117. if(MAPI_G(hr) != hrSuccess)
  5118. goto exit;
  5119. //Return an array of IFreeBusyData interfaces
  5120. array_init(return_value);
  5121. for (i = 0; i < cUsers; ++i) {
  5122. if(lppFBData[i])
  5123. {
  5124. // Set resource relation
  5125. rid = zend_register_resource(lppFBData[i], le_freebusy_data);
  5126. // Add item to return list
  5127. add_next_index_resource(return_value, rid);
  5128. } else {
  5129. // Add empty item to return list
  5130. add_next_index_null(return_value);
  5131. }
  5132. }
  5133. exit:
  5134. // do not release fbdata, it's registered in the return_value array, but not addref'd
  5135. MAPIFreeBuffer(lppFBData);
  5136. LOG_END();
  5137. THROW_ON_ERROR();
  5138. }
  5139. ZEND_FUNCTION(mapi_freebusysupport_loadupdate)
  5140. {
  5141. PMEASURE_FUNC;
  5142. LOG_BEGIN();
  5143. HashTable* target_hash = NULL;
  5144. ULONG i, j;
  5145. zval* entry = NULL;
  5146. zend_resource * rid = NULL;
  5147. memory_ptr<FBUser> lpUsers;
  5148. IFreeBusySupport* lpFBSupport = NULL;
  5149. zval* resFBSupport = NULL;
  5150. zval* resUsers = NULL;
  5151. ULONG cUsers = 0;
  5152. memory_ptr<IFreeBusyUpdate *> lppFBUpdate;
  5153. ULONG cFBUpdate = 0;
  5154. RETVAL_FALSE;
  5155. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5156. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra", &resFBSupport,&resUsers) == FAILURE) return;
  5157. ZEND_FETCH_RESOURCE_C(lpFBSupport, IFreeBusySupport*, &resFBSupport, -1, name_fb_support, le_freebusy_support);
  5158. ZVAL_DEREF(resUsers);
  5159. target_hash = HASH_OF(resUsers);
  5160. if (!target_hash) {
  5161. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5162. goto exit;
  5163. }
  5164. cUsers = zend_hash_num_elements(target_hash);
  5165. MAPI_G(hr) = MAPIAllocateBuffer(sizeof(FBUser)*cUsers, &~lpUsers);
  5166. if(MAPI_G(hr) != hrSuccess)
  5167. goto exit;
  5168. // Get the user entryids
  5169. j = 0;
  5170. ZEND_HASH_FOREACH_VAL(target_hash, entry) {
  5171. if(!entry) {
  5172. MAPI_G(hr) = MAPI_E_INVALID_ENTRYID;
  5173. goto exit;
  5174. }
  5175. lpUsers[j].m_cbEid = Z_STRLEN_P(entry);
  5176. lpUsers[j].m_lpEid = (LPENTRYID)Z_STRVAL_P(entry);
  5177. ++j;
  5178. } ZEND_HASH_FOREACH_END();
  5179. MAPI_G(hr) = MAPIAllocateBuffer(sizeof(IFreeBusyUpdate*)*cUsers, &~lppFBUpdate);
  5180. if(MAPI_G(hr) != hrSuccess)
  5181. goto exit;
  5182. MAPI_G(hr) = lpFBSupport->LoadFreeBusyUpdate(cUsers, lpUsers, lppFBUpdate, &cFBUpdate, NULL);
  5183. if(MAPI_G(hr) != hrSuccess)
  5184. goto exit;
  5185. //Return an array of IFreeBusyUpdate interfaces
  5186. array_init(return_value);
  5187. for (i = 0; i < cUsers; ++i) {
  5188. if(lppFBUpdate[i])
  5189. {
  5190. // Set resource relation
  5191. rid = zend_register_resource(lppFBUpdate[i], le_freebusy_update);
  5192. // Add item to return list
  5193. add_next_index_resource(return_value, rid);
  5194. }else {
  5195. // Add empty item to return list
  5196. add_next_index_null(return_value);
  5197. }
  5198. }
  5199. exit:
  5200. LOG_END();
  5201. THROW_ON_ERROR();
  5202. }
  5203. ZEND_FUNCTION(mapi_freebusydata_enumblocks)
  5204. {
  5205. PMEASURE_FUNC;
  5206. LOG_BEGIN();
  5207. IFreeBusyData* lpFBData = NULL;
  5208. zval* resFBData = NULL;
  5209. FILETIME ftmStart;
  5210. FILETIME ftmEnd;
  5211. time_t ulUnixStart = 0;
  5212. time_t ulUnixEnd = 0;
  5213. IEnumFBBlock* lpEnumBlock = NULL;
  5214. RETVAL_FALSE;
  5215. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5216. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll", &resFBData, &ulUnixStart, &ulUnixEnd) == FAILURE) return;
  5217. ZEND_FETCH_RESOURCE_C(lpFBData, IFreeBusyData*, &resFBData, -1, name_fb_data, le_freebusy_data);
  5218. UnixTimeToFileTime(ulUnixStart, &ftmStart);
  5219. UnixTimeToFileTime(ulUnixEnd, &ftmEnd);
  5220. MAPI_G(hr) = lpFBData->EnumBlocks(&lpEnumBlock, ftmStart, ftmEnd);
  5221. if(MAPI_G(hr) != hrSuccess)
  5222. goto exit;
  5223. UOBJ_REGISTER_RESOURCE(return_value, lpEnumBlock, le_freebusy_enumblock);
  5224. exit:
  5225. LOG_END();
  5226. THROW_ON_ERROR();
  5227. }
  5228. ZEND_FUNCTION(mapi_freebusydata_getpublishrange)
  5229. {
  5230. PMEASURE_FUNC;
  5231. LOG_BEGIN();
  5232. IFreeBusyData* lpFBData = NULL;
  5233. zval* resFBData = NULL;
  5234. LONG rtmStart;
  5235. LONG rtmEnd;
  5236. time_t ulUnixStart = 0;
  5237. time_t ulUnixEnd = 0;
  5238. RETVAL_FALSE;
  5239. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5240. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &resFBData) == FAILURE) return;
  5241. ZEND_FETCH_RESOURCE_C(lpFBData, IFreeBusyData*, &resFBData, -1, name_fb_data, le_freebusy_data);
  5242. MAPI_G(hr) = lpFBData->GetFBPublishRange(&rtmStart, &rtmEnd);
  5243. if(MAPI_G(hr) != hrSuccess)
  5244. goto exit;
  5245. RTimeToUnixTime(rtmStart, &ulUnixStart);
  5246. RTimeToUnixTime(rtmEnd, &ulUnixEnd);
  5247. array_init(return_value);
  5248. add_assoc_long(return_value, "start", ulUnixStart);
  5249. add_assoc_long(return_value, "end", ulUnixEnd);
  5250. exit:
  5251. LOG_END();
  5252. THROW_ON_ERROR();
  5253. }
  5254. ZEND_FUNCTION(mapi_freebusydata_setrange)
  5255. {
  5256. PMEASURE_FUNC;
  5257. LOG_BEGIN();
  5258. IFreeBusyData* lpFBData = NULL;
  5259. zval* resFBData = NULL;
  5260. LONG rtmStart;
  5261. LONG rtmEnd;
  5262. time_t ulUnixStart = 0;
  5263. time_t ulUnixEnd = 0;
  5264. RETVAL_FALSE;
  5265. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5266. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll", &resFBData, &ulUnixStart, &ulUnixEnd) == FAILURE) return;
  5267. ZEND_FETCH_RESOURCE_C(lpFBData, IFreeBusyData*, &resFBData, -1, name_fb_data, le_freebusy_data);
  5268. UnixTimeToRTime(ulUnixStart, &rtmStart);
  5269. UnixTimeToRTime(ulUnixEnd, &rtmEnd);
  5270. MAPI_G(hr) = lpFBData->SetFBRange(rtmStart, rtmEnd);
  5271. if(MAPI_G(hr) != hrSuccess)
  5272. goto exit;
  5273. RETVAL_TRUE;
  5274. exit:
  5275. LOG_END();
  5276. THROW_ON_ERROR();
  5277. }
  5278. ZEND_FUNCTION(mapi_freebusyenumblock_reset)
  5279. {
  5280. PMEASURE_FUNC;
  5281. LOG_BEGIN();
  5282. IEnumFBBlock* lpEnumBlock = NULL;
  5283. zval* resEnumBlock = NULL;
  5284. RETVAL_FALSE;
  5285. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5286. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &resEnumBlock) == FAILURE) return;
  5287. ZEND_FETCH_RESOURCE_C(lpEnumBlock, IEnumFBBlock*, &resEnumBlock, -1, name_fb_enumblock, le_freebusy_enumblock);
  5288. MAPI_G(hr) = lpEnumBlock->Reset();
  5289. if(MAPI_G(hr) != hrSuccess)
  5290. goto exit;
  5291. RETVAL_TRUE;
  5292. exit:
  5293. LOG_END();
  5294. THROW_ON_ERROR();
  5295. }
  5296. ZEND_FUNCTION(mapi_freebusyenumblock_next)
  5297. {
  5298. PMEASURE_FUNC;
  5299. LOG_BEGIN();
  5300. IEnumFBBlock* lpEnumBlock = NULL;
  5301. zval* resEnumBlock = NULL;
  5302. long cElt = 0;
  5303. LONG cFetch = 0;
  5304. LONG i;
  5305. memory_ptr<FBBlock_1> lpBlk;
  5306. time_t ulUnixStart = 0;
  5307. time_t ulUnixEnd = 0;
  5308. zval zval_data_value;
  5309. RETVAL_FALSE;
  5310. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5311. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &resEnumBlock, &cElt) == FAILURE) return;
  5312. ZEND_FETCH_RESOURCE_C(lpEnumBlock, IEnumFBBlock*, &resEnumBlock, -1, name_fb_enumblock, le_freebusy_enumblock);
  5313. MAPI_G(hr) = MAPIAllocateBuffer(sizeof(FBBlock_1)*cElt, &~lpBlk);
  5314. if(MAPI_G(hr) != hrSuccess)
  5315. goto exit;
  5316. MAPI_G(hr) = lpEnumBlock->Next(cElt, lpBlk, &cFetch);
  5317. if(MAPI_G(hr) != hrSuccess)
  5318. goto exit;
  5319. array_init(return_value);
  5320. for (i = 0; i < cFetch; ++i) {
  5321. array_init(&zval_data_value);
  5322. RTimeToUnixTime(lpBlk[i].m_tmStart, &ulUnixStart);
  5323. RTimeToUnixTime(lpBlk[i].m_tmEnd, &ulUnixEnd);
  5324. add_assoc_long(&zval_data_value, "start", ulUnixStart);
  5325. add_assoc_long(&zval_data_value, "end", ulUnixEnd);
  5326. add_assoc_long(&zval_data_value, "status", (LONG)lpBlk[i].m_fbstatus);
  5327. add_next_index_zval(return_value, &zval_data_value);
  5328. }
  5329. exit:
  5330. LOG_END();
  5331. THROW_ON_ERROR();
  5332. }
  5333. ZEND_FUNCTION(mapi_freebusyenumblock_skip)
  5334. {
  5335. PMEASURE_FUNC;
  5336. LOG_BEGIN();
  5337. IEnumFBBlock* lpEnumBlock = NULL;
  5338. zval* resEnumBlock = NULL;
  5339. long ulSkip = 0;
  5340. RETVAL_FALSE;
  5341. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5342. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &resEnumBlock, &ulSkip) == FAILURE) return;
  5343. ZEND_FETCH_RESOURCE_C(lpEnumBlock, IEnumFBBlock*, &resEnumBlock, -1, name_fb_enumblock, le_freebusy_enumblock);
  5344. MAPI_G(hr) = lpEnumBlock->Skip(ulSkip);
  5345. if(MAPI_G(hr) != hrSuccess)
  5346. goto exit;
  5347. RETVAL_TRUE;
  5348. exit:
  5349. LOG_END();
  5350. THROW_ON_ERROR();
  5351. }
  5352. ZEND_FUNCTION(mapi_freebusyenumblock_restrict)
  5353. {
  5354. PMEASURE_FUNC;
  5355. LOG_BEGIN();
  5356. IEnumFBBlock* lpEnumBlock = NULL;
  5357. zval* resEnumBlock = NULL;
  5358. FILETIME ftmStart;
  5359. FILETIME ftmEnd;
  5360. time_t ulUnixStart = 0;
  5361. time_t ulUnixEnd = 0;
  5362. RETVAL_FALSE;
  5363. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5364. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll", &resEnumBlock, &ulUnixStart, &ulUnixEnd) == FAILURE) return;
  5365. ZEND_FETCH_RESOURCE_C(lpEnumBlock, IEnumFBBlock*, &resEnumBlock, -1, name_fb_enumblock, le_freebusy_enumblock);
  5366. UnixTimeToFileTime(ulUnixStart, &ftmStart);
  5367. UnixTimeToFileTime(ulUnixEnd, &ftmEnd);
  5368. MAPI_G(hr) = lpEnumBlock->Restrict(ftmStart, ftmEnd);
  5369. if(MAPI_G(hr) != hrSuccess)
  5370. goto exit;
  5371. RETVAL_TRUE;
  5372. exit:
  5373. LOG_END();
  5374. THROW_ON_ERROR();
  5375. }
  5376. ZEND_FUNCTION(mapi_freebusyupdate_publish)
  5377. {
  5378. PMEASURE_FUNC;
  5379. LOG_BEGIN();
  5380. // params
  5381. zval* resFBUpdate = NULL;
  5382. zval* aBlocks = NULL;
  5383. IFreeBusyUpdate* lpFBUpdate = NULL;
  5384. // local
  5385. memory_ptr<FBBlock_1> lpBlocks;
  5386. ULONG cBlocks = 0;
  5387. HashTable* target_hash = NULL;
  5388. ULONG i;
  5389. zval* entry = NULL;
  5390. zval* value = NULL;
  5391. HashTable* data = NULL;
  5392. zend_string *str_start = zend_string_init("start", sizeof("start")-1, 0);
  5393. zend_string *str_end = zend_string_init("end", sizeof("end")-1, 0);
  5394. zend_string *str_status = zend_string_init("status", sizeof("status")-1, 0);
  5395. RETVAL_FALSE;
  5396. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5397. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra", &resFBUpdate, &aBlocks) == FAILURE) return;
  5398. ZEND_FETCH_RESOURCE_C(lpFBUpdate, IFreeBusyUpdate*, &resFBUpdate, -1, name_fb_update, le_freebusy_update);
  5399. ZVAL_DEREF(aBlocks);
  5400. target_hash = HASH_OF(aBlocks);
  5401. if (!target_hash) {
  5402. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5403. goto exit;
  5404. }
  5405. cBlocks = zend_hash_num_elements(target_hash);
  5406. MAPI_G(hr) = MAPIAllocateBuffer(sizeof(FBBlock_1)*cBlocks, &~lpBlocks);
  5407. if(MAPI_G(hr) != hrSuccess)
  5408. goto exit;
  5409. i = 0;
  5410. ZEND_HASH_FOREACH_VAL(target_hash, entry) {
  5411. ZVAL_DEREF(entry);
  5412. data = HASH_OF(entry);
  5413. zend_hash_internal_pointer_reset(data);
  5414. if ((value = zend_hash_find(data, str_start)) != NULL) {
  5415. UnixTimeToRTime(Z_LVAL_P(value), &lpBlocks[i].m_tmStart);
  5416. } else {
  5417. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5418. goto exit;
  5419. }
  5420. if ((value = zend_hash_find(data, str_end)) != NULL ) {
  5421. UnixTimeToRTime(Z_LVAL_P(value), &lpBlocks[i].m_tmEnd);
  5422. } else {
  5423. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5424. goto exit;
  5425. }
  5426. if ((value = zend_hash_find(data, str_status)) != NULL) {
  5427. lpBlocks[i].m_fbstatus = (enum FBStatus)Z_LVAL_P(value);
  5428. } else {
  5429. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5430. goto exit;
  5431. }
  5432. ++i;
  5433. } ZEND_HASH_FOREACH_END();
  5434. MAPI_G(hr) = lpFBUpdate->PublishFreeBusy(lpBlocks, cBlocks);
  5435. if(MAPI_G(hr) != hrSuccess)
  5436. goto exit;
  5437. RETVAL_TRUE;
  5438. exit:
  5439. zend_string_release(str_start);
  5440. zend_string_release(str_end);
  5441. zend_string_release(str_status);
  5442. LOG_END();
  5443. THROW_ON_ERROR();
  5444. }
  5445. ZEND_FUNCTION(mapi_freebusyupdate_reset)
  5446. {
  5447. PMEASURE_FUNC;
  5448. LOG_BEGIN();
  5449. IFreeBusyUpdate* lpFBUpdate = NULL;
  5450. zval* resFBUpdate = NULL;
  5451. RETVAL_FALSE;
  5452. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5453. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &resFBUpdate) == FAILURE) return;
  5454. ZEND_FETCH_RESOURCE_C(lpFBUpdate, IFreeBusyUpdate*, &resFBUpdate, -1, name_fb_update, le_freebusy_update);
  5455. MAPI_G(hr) = lpFBUpdate->ResetPublishedFreeBusy();
  5456. if(MAPI_G(hr) != hrSuccess)
  5457. goto exit;
  5458. RETVAL_TRUE;
  5459. exit:
  5460. LOG_END();
  5461. THROW_ON_ERROR();
  5462. }
  5463. ZEND_FUNCTION(mapi_freebusyupdate_savechanges)
  5464. {
  5465. PMEASURE_FUNC;
  5466. LOG_BEGIN();
  5467. // params
  5468. zval* resFBUpdate = NULL;
  5469. time_t ulUnixStart = 0;
  5470. time_t ulUnixEnd = 0;
  5471. IFreeBusyUpdate* lpFBUpdate = NULL;
  5472. // local
  5473. FILETIME ftmStart;
  5474. FILETIME ftmEnd;
  5475. RETVAL_FALSE;
  5476. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5477. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll", &resFBUpdate, &ulUnixStart, &ulUnixEnd) == FAILURE) return;
  5478. ZEND_FETCH_RESOURCE_C(lpFBUpdate, IFreeBusyUpdate*, &resFBUpdate, -1, name_fb_update, le_freebusy_update);
  5479. UnixTimeToFileTime(ulUnixStart, &ftmStart);
  5480. UnixTimeToFileTime(ulUnixEnd, &ftmEnd);
  5481. MAPI_G(hr) = lpFBUpdate->SaveChanges(ftmStart, ftmEnd);
  5482. if(MAPI_G(hr) != hrSuccess)
  5483. goto exit;
  5484. RETVAL_TRUE;
  5485. exit:
  5486. LOG_END();
  5487. THROW_ON_ERROR();
  5488. }
  5489. ZEND_FUNCTION(mapi_favorite_add)
  5490. {
  5491. PMEASURE_FUNC;
  5492. LOG_BEGIN();
  5493. // params
  5494. zval * resSession = NULL;
  5495. zval * resFolder = NULL;
  5496. LPSTR lpszAliasName = NULL;
  5497. size_t cbAliasName = 0;
  5498. long ulFlags = 0;
  5499. // local
  5500. LPMAPIFOLDER lpFolder = NULL;
  5501. IMAPISession *lpSession = NULL;
  5502. object_ptr<IMAPIFolder> lpShortCutFolder;
  5503. RETVAL_FALSE;
  5504. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5505. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr|sl", &resSession, &resFolder, &lpszAliasName, &cbAliasName, &ulFlags) == FAILURE) return;
  5506. ZEND_FETCH_RESOURCE_C(lpSession, IMAPISession *, &resSession, -1, name_mapi_session, le_mapi_session);
  5507. ZEND_FETCH_RESOURCE_C(lpFolder, LPMAPIFOLDER, &resFolder, -1, name_mapi_folder, le_mapi_folder);
  5508. if(cbAliasName == 0)
  5509. lpszAliasName = NULL;
  5510. MAPI_G(hr) = GetShortcutFolder(lpSession, nullptr, nullptr, MAPI_CREATE, &~lpShortCutFolder); // use english language
  5511. if(MAPI_G(hr) != hrSuccess)
  5512. goto exit;
  5513. MAPI_G(hr) = AddFavoriteFolder(lpShortCutFolder, lpFolder, (LPCTSTR) lpszAliasName, ulFlags);
  5514. if(MAPI_G(hr) != hrSuccess)
  5515. goto exit;
  5516. RETVAL_TRUE;
  5517. exit:
  5518. LOG_END();
  5519. THROW_ON_ERROR();
  5520. }
  5521. /*
  5522. ***********************************************************************************
  5523. * ICS interfaces
  5524. ***********************************************************************************eight
  5525. */
  5526. ZEND_FUNCTION(mapi_exportchanges_config)
  5527. {
  5528. PMEASURE_FUNC;
  5529. LOG_BEGIN();
  5530. IUnknown * lpImportChanges = NULL; // may be contents or hierarchy
  5531. IExchangeExportChanges *lpExportChanges = NULL;
  5532. IStream * lpStream = NULL;
  5533. zval * resStream = NULL;
  5534. long ulFlags = 0;
  5535. long ulBuffersize = 0;
  5536. zval * resImportChanges = NULL;
  5537. zval * resExportChanges = NULL;
  5538. zval * aRestrict = NULL;
  5539. zval * aIncludeProps = NULL;
  5540. zval * aExcludeProps = NULL;
  5541. int type = -1;
  5542. memory_ptr<SRestriction> lpRestrict;
  5543. memory_ptr<SPropTagArray> lpIncludeProps, lpExcludeProps;
  5544. RETVAL_FALSE;
  5545. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5546. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrlzzzzl", &resExportChanges, &resStream, &ulFlags, &resImportChanges, &aRestrict, &aIncludeProps, &aExcludeProps, &ulBuffersize) == FAILURE) return;
  5547. ZEND_FETCH_RESOURCE_C(lpExportChanges, IExchangeExportChanges *, &resExportChanges, -1, name_mapi_exportchanges, le_mapi_exportchanges);
  5548. if(Z_TYPE_P(resImportChanges) == IS_RESOURCE) {
  5549. type = Z_RES_P(resImportChanges)->type;
  5550. if(type == le_mapi_importcontentschanges) {
  5551. ZEND_FETCH_RESOURCE_C(lpImportChanges, IUnknown *, &resImportChanges, -1, name_mapi_importcontentschanges, le_mapi_importcontentschanges);
  5552. } else if(type == le_mapi_importhierarchychanges) {
  5553. ZEND_FETCH_RESOURCE_C(lpImportChanges, IUnknown *, &resImportChanges, -1, name_mapi_importhierarchychanges, le_mapi_importhierarchychanges);
  5554. } else {
  5555. php_error_docref(NULL TSRMLS_CC, E_WARNING, "The importer must be either a contents importer or a hierarchy importer object");
  5556. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5557. goto exit;
  5558. }
  5559. } else if(Z_TYPE_P(resImportChanges) == IS_FALSE) {
  5560. lpImportChanges = NULL;
  5561. } else {
  5562. php_error_docref(NULL TSRMLS_CC, E_WARNING, "The importer must be an actual importer resource, or FALSE");
  5563. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5564. goto exit;
  5565. }
  5566. ZEND_FETCH_RESOURCE_C(lpStream, IStream *, &resStream, -1, name_istream, le_istream);
  5567. if(Z_TYPE_P(aRestrict) == IS_ARRAY) {
  5568. MAPI_G(hr) = MAPIAllocateBuffer(sizeof(SRestriction), &~lpRestrict);
  5569. if (MAPI_G(hr) != hrSuccess)
  5570. goto exit;
  5571. MAPI_G(hr) = PHPArraytoSRestriction(aRestrict, lpRestrict, lpRestrict TSRMLS_CC);
  5572. if (MAPI_G(hr) != hrSuccess)
  5573. goto exit;
  5574. }
  5575. if(Z_TYPE_P(aIncludeProps) == IS_ARRAY) {
  5576. MAPI_G(hr) = PHPArraytoPropTagArray(aIncludeProps, NULL, &~lpIncludeProps TSRMLS_CC);
  5577. if(MAPI_G(hr) != hrSuccess) {
  5578. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse includeprops array");
  5579. goto exit;
  5580. }
  5581. }
  5582. if(Z_TYPE_P(aExcludeProps) == IS_ARRAY) {
  5583. MAPI_G(hr) = PHPArraytoPropTagArray(aExcludeProps, NULL, &~lpExcludeProps TSRMLS_CC);
  5584. if(MAPI_G(hr) != hrSuccess) {
  5585. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse excludeprops array");
  5586. goto exit;
  5587. }
  5588. }
  5589. MAPI_G(hr) = lpExportChanges->Config(lpStream, ulFlags, lpImportChanges, lpRestrict, lpIncludeProps, lpExcludeProps, ulBuffersize);
  5590. if(MAPI_G(hr) != hrSuccess)
  5591. goto exit;
  5592. RETVAL_TRUE;
  5593. exit:
  5594. LOG_END();
  5595. THROW_ON_ERROR();
  5596. }
  5597. ZEND_FUNCTION(mapi_exportchanges_synchronize)
  5598. {
  5599. PMEASURE_FUNC;
  5600. LOG_BEGIN();
  5601. zval * resExportChanges = NULL;
  5602. IExchangeExportChanges *lpExportChanges = NULL;
  5603. ULONG ulSteps = 0;
  5604. ULONG ulProgress = 0;
  5605. RETVAL_FALSE;
  5606. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5607. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &resExportChanges) == FAILURE) return;
  5608. ZEND_FETCH_RESOURCE_C(lpExportChanges, IExchangeExportChanges *, &resExportChanges, -1, name_mapi_exportchanges, le_mapi_exportchanges);
  5609. MAPI_G(hr) = lpExportChanges->Synchronize(&ulSteps, &ulProgress);
  5610. if(MAPI_G(hr) == SYNC_W_PROGRESS) {
  5611. array_init(return_value);
  5612. add_next_index_long(return_value, ulSteps);
  5613. add_next_index_long(return_value, ulProgress);
  5614. } else if(MAPI_G(hr) != hrSuccess) {
  5615. goto exit;
  5616. } else {
  5617. // hr == hrSuccess
  5618. RETVAL_TRUE;
  5619. }
  5620. exit:
  5621. LOG_END();
  5622. THROW_ON_ERROR();
  5623. }
  5624. ZEND_FUNCTION(mapi_exportchanges_updatestate)
  5625. {
  5626. PMEASURE_FUNC;
  5627. LOG_BEGIN();
  5628. zval * resExportChanges = NULL;
  5629. zval * resStream = NULL;
  5630. IExchangeExportChanges *lpExportChanges = NULL;
  5631. IStream * lpStream = NULL;
  5632. RETVAL_FALSE;
  5633. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5634. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr", &resExportChanges, &resStream) == FAILURE) return;
  5635. ZEND_FETCH_RESOURCE_C(lpExportChanges, IExchangeExportChanges *, &resExportChanges, -1, name_mapi_exportchanges, le_mapi_exportchanges);
  5636. ZEND_FETCH_RESOURCE_C(lpStream, IStream *, &resStream, -1, name_istream, le_istream);
  5637. MAPI_G(hr) = lpExportChanges->UpdateState(lpStream);
  5638. if(MAPI_G(hr) != hrSuccess)
  5639. goto exit;
  5640. RETVAL_TRUE;
  5641. exit:
  5642. LOG_END();
  5643. THROW_ON_ERROR();
  5644. }
  5645. ZEND_FUNCTION(mapi_exportchanges_getchangecount)
  5646. {
  5647. PMEASURE_FUNC;
  5648. LOG_BEGIN();
  5649. zval * resExportChanges = NULL;
  5650. IExchangeExportChanges *lpExportChanges = NULL;
  5651. object_ptr<IECExportChanges> lpECExportChanges;
  5652. ULONG ulChanges;
  5653. RETVAL_FALSE;
  5654. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5655. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &resExportChanges) == FAILURE) return;
  5656. ZEND_FETCH_RESOURCE_C(lpExportChanges, IExchangeExportChanges *, &resExportChanges, -1, name_mapi_exportchanges, le_mapi_exportchanges);
  5657. MAPI_G(hr) = lpExportChanges->QueryInterface(IID_IECExportChanges, &~lpECExportChanges);
  5658. if(MAPI_G(hr) != hrSuccess) {
  5659. php_error_docref(NULL TSRMLS_CC, E_WARNING, "ExportChanges does not support IECExportChanges interface which is required for the getchangecount call");
  5660. goto exit;
  5661. }
  5662. MAPI_G(hr) = lpECExportChanges->GetChangeCount(&ulChanges);
  5663. if(MAPI_G(hr) != hrSuccess)
  5664. goto exit;
  5665. RETVAL_LONG(ulChanges);
  5666. exit:
  5667. LOG_END();
  5668. THROW_ON_ERROR();
  5669. }
  5670. ZEND_FUNCTION(mapi_importcontentschanges_config)
  5671. {
  5672. PMEASURE_FUNC;
  5673. LOG_BEGIN();
  5674. zval * resImportContentsChanges = NULL;
  5675. zval * resStream = NULL;
  5676. IExchangeImportContentsChanges *lpImportContentsChanges = NULL;
  5677. IStream * lpStream = NULL;
  5678. long ulFlags = 0;
  5679. RETVAL_FALSE;
  5680. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5681. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrl", &resImportContentsChanges, &resStream, &ulFlags) == FAILURE) return;
  5682. ZEND_FETCH_RESOURCE_C(lpImportContentsChanges, IExchangeImportContentsChanges *, &resImportContentsChanges, -1, name_mapi_importcontentschanges, le_mapi_importcontentschanges);
  5683. ZEND_FETCH_RESOURCE_C(lpStream, IStream *, &resStream, -1, name_istream, le_istream);
  5684. MAPI_G(hr) = lpImportContentsChanges->Config(lpStream, ulFlags);
  5685. if(MAPI_G(hr) != hrSuccess)
  5686. goto exit;
  5687. RETVAL_TRUE;
  5688. exit:
  5689. LOG_END();
  5690. THROW_ON_ERROR();
  5691. }
  5692. ZEND_FUNCTION(mapi_importcontentschanges_updatestate)
  5693. {
  5694. PMEASURE_FUNC;
  5695. LOG_BEGIN();
  5696. zval * resImportContentsChanges = NULL;
  5697. zval * resStream = NULL;
  5698. IExchangeImportContentsChanges *lpImportContentsChanges = NULL;
  5699. IStream * lpStream = NULL;
  5700. RETVAL_FALSE;
  5701. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5702. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|r", &resImportContentsChanges, &resStream) == FAILURE) return;
  5703. ZEND_FETCH_RESOURCE_C(lpImportContentsChanges, IExchangeImportContentsChanges *, &resImportContentsChanges, -1, name_mapi_importcontentschanges, le_mapi_importcontentschanges);
  5704. if (resStream != NULL) {
  5705. ZEND_FETCH_RESOURCE_C(lpStream, IStream *, &resStream, -1, name_istream, le_istream);
  5706. }
  5707. MAPI_G(hr) = lpImportContentsChanges->UpdateState(lpStream);
  5708. if(MAPI_G(hr) != hrSuccess)
  5709. goto exit;
  5710. RETVAL_TRUE;
  5711. exit:
  5712. LOG_END();
  5713. THROW_ON_ERROR();
  5714. }
  5715. ZEND_FUNCTION(mapi_importcontentschanges_importmessagechange)
  5716. {
  5717. PMEASURE_FUNC;
  5718. LOG_BEGIN();
  5719. zval * resImportContentsChanges = NULL;
  5720. zval * resProps = NULL;
  5721. long ulFlags = 0;
  5722. zval * resMessage = NULL;
  5723. memory_ptr<SPropValue> lpProps;
  5724. ULONG cValues = 0;
  5725. IMessage * lpMessage = NULL;
  5726. IExchangeImportContentsChanges * lpImportContentsChanges = NULL;
  5727. RETVAL_FALSE;
  5728. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5729. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ralz", &resImportContentsChanges, &resProps, &ulFlags, &resMessage) == FAILURE) return;
  5730. ZEND_FETCH_RESOURCE_C(lpImportContentsChanges, IExchangeImportContentsChanges *, &resImportContentsChanges, -1, name_mapi_importcontentschanges, le_mapi_importcontentschanges);
  5731. MAPI_G(hr) = PHPArraytoPropValueArray(resProps, NULL, &cValues, &~lpProps TSRMLS_CC);
  5732. if(MAPI_G(hr) != hrSuccess) {
  5733. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse property array");
  5734. goto exit;
  5735. }
  5736. MAPI_G(hr) = lpImportContentsChanges->ImportMessageChange(cValues, lpProps, ulFlags, &lpMessage);
  5737. if (MAPI_G(hr) != hrSuccess)
  5738. goto exit;
  5739. ZVAL_DEREF(resMessage);
  5740. UOBJ_REGISTER_RESOURCE(resMessage, lpMessage, le_mapi_message);
  5741. RETVAL_TRUE;
  5742. exit:
  5743. LOG_END();
  5744. THROW_ON_ERROR();
  5745. }
  5746. ZEND_FUNCTION(mapi_importcontentschanges_importmessagedeletion)
  5747. {
  5748. PMEASURE_FUNC;
  5749. LOG_BEGIN();
  5750. zval * resMessages;
  5751. zval * resImportContentsChanges;
  5752. IExchangeImportContentsChanges *lpImportContentsChanges = NULL;
  5753. memory_ptr<SBinaryArray> lpMessages;
  5754. long ulFlags = 0;
  5755. RETVAL_FALSE;
  5756. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5757. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rla", &resImportContentsChanges, &ulFlags, &resMessages) == FAILURE) return;
  5758. ZEND_FETCH_RESOURCE_C(lpImportContentsChanges, IExchangeImportContentsChanges *, &resImportContentsChanges, -1, name_mapi_importcontentschanges, le_mapi_importcontentschanges);
  5759. MAPI_G(hr) = PHPArraytoSBinaryArray(resMessages, NULL, &~lpMessages TSRMLS_CC);
  5760. if(MAPI_G(hr) != hrSuccess) {
  5761. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse message list");
  5762. goto exit;
  5763. }
  5764. MAPI_G(hr) = lpImportContentsChanges->ImportMessageDeletion(ulFlags, lpMessages);
  5765. if(MAPI_G(hr) != hrSuccess)
  5766. goto exit;
  5767. exit:
  5768. LOG_END();
  5769. THROW_ON_ERROR();
  5770. }
  5771. ZEND_FUNCTION(mapi_importcontentschanges_importperuserreadstatechange)
  5772. {
  5773. PMEASURE_FUNC;
  5774. LOG_BEGIN();
  5775. zval * resReadStates;
  5776. zval * resImportContentsChanges;
  5777. IExchangeImportContentsChanges *lpImportContentsChanges = NULL;
  5778. memory_ptr<READSTATE> lpReadStates;
  5779. ULONG cValues = 0;
  5780. RETVAL_FALSE;
  5781. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5782. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra", &resImportContentsChanges, &resReadStates) == FAILURE) return;
  5783. ZEND_FETCH_RESOURCE_C(lpImportContentsChanges, IExchangeImportContentsChanges *, &resImportContentsChanges, -1, name_mapi_importcontentschanges, le_mapi_importcontentschanges);
  5784. MAPI_G(hr) = PHPArraytoReadStateArray(resReadStates, NULL, &cValues, &~lpReadStates TSRMLS_CC);
  5785. if(MAPI_G(hr) != hrSuccess) {
  5786. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse readstates");
  5787. goto exit;
  5788. }
  5789. MAPI_G(hr) = lpImportContentsChanges->ImportPerUserReadStateChange(cValues, lpReadStates);
  5790. if(MAPI_G(hr) != hrSuccess)
  5791. goto exit;
  5792. RETVAL_TRUE;
  5793. exit:
  5794. LOG_END();
  5795. THROW_ON_ERROR();
  5796. }
  5797. ZEND_FUNCTION(mapi_importcontentschanges_importmessagemove)
  5798. {
  5799. PMEASURE_FUNC;
  5800. LOG_BEGIN();
  5801. size_t cbSourceKeySrcFolder = 0;
  5802. BYTE * pbSourceKeySrcFolder = NULL;
  5803. size_t cbSourceKeySrcMessage = 0;
  5804. BYTE * pbSourceKeySrcMessage = NULL;
  5805. size_t cbPCLMessage = 0;
  5806. BYTE * pbPCLMessage = NULL;
  5807. size_t cbSourceKeyDestMessage = 0;
  5808. BYTE * pbSourceKeyDestMessage = NULL;
  5809. size_t cbChangeNumDestMessage = 0;
  5810. BYTE * pbChangeNumDestMessage = NULL;
  5811. zval * resImportContentsChanges;
  5812. IExchangeImportContentsChanges *lpImportContentsChanges = NULL;
  5813. RETVAL_FALSE;
  5814. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5815. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsssss", &resImportContentsChanges,
  5816. &pbSourceKeySrcFolder, &cbSourceKeySrcFolder,
  5817. &pbSourceKeySrcMessage, &cbSourceKeySrcMessage,
  5818. &pbPCLMessage, &cbPCLMessage,
  5819. &pbSourceKeyDestMessage, &cbSourceKeyDestMessage,
  5820. &pbChangeNumDestMessage, &cbChangeNumDestMessage) == FAILURE) return;
  5821. ZEND_FETCH_RESOURCE_C(lpImportContentsChanges, IExchangeImportContentsChanges *, &resImportContentsChanges, -1, name_mapi_importcontentschanges, le_mapi_importcontentschanges);
  5822. MAPI_G(hr) = lpImportContentsChanges->ImportMessageMove(cbSourceKeySrcFolder, pbSourceKeySrcFolder, cbSourceKeySrcMessage, pbSourceKeySrcMessage, cbPCLMessage, pbPCLMessage, cbSourceKeyDestMessage, pbSourceKeyDestMessage, cbChangeNumDestMessage, pbChangeNumDestMessage);
  5823. if(MAPI_G(hr) != hrSuccess)
  5824. goto exit;
  5825. exit:
  5826. LOG_END();
  5827. THROW_ON_ERROR();
  5828. }
  5829. ZEND_FUNCTION(mapi_importhierarchychanges_config)
  5830. {
  5831. PMEASURE_FUNC;
  5832. LOG_BEGIN();
  5833. zval * resImportHierarchyChanges = NULL;
  5834. zval * resStream = NULL;
  5835. IExchangeImportHierarchyChanges *lpImportHierarchyChanges = NULL;
  5836. IStream * lpStream = NULL;
  5837. long ulFlags = 0;
  5838. RETVAL_FALSE;
  5839. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5840. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrl", &resImportHierarchyChanges, &resStream, &ulFlags) == FAILURE) return;
  5841. ZEND_FETCH_RESOURCE_C(lpImportHierarchyChanges, IExchangeImportHierarchyChanges *, &resImportHierarchyChanges, -1, name_mapi_importhierarchychanges, le_mapi_importhierarchychanges);
  5842. ZEND_FETCH_RESOURCE_C(lpStream, IStream *, &resStream, -1, name_istream, le_istream);
  5843. MAPI_G(hr) = lpImportHierarchyChanges->Config(lpStream, ulFlags);
  5844. if(MAPI_G(hr) != hrSuccess)
  5845. goto exit;
  5846. RETVAL_TRUE;
  5847. exit:
  5848. LOG_END();
  5849. THROW_ON_ERROR();
  5850. }
  5851. ZEND_FUNCTION(mapi_importhierarchychanges_updatestate)
  5852. {
  5853. PMEASURE_FUNC;
  5854. LOG_BEGIN();
  5855. zval * resImportHierarchyChanges = NULL;
  5856. zval * resStream = NULL;
  5857. IExchangeImportHierarchyChanges *lpImportHierarchyChanges = NULL;
  5858. IStream * lpStream = NULL;
  5859. RETVAL_FALSE;
  5860. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5861. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|r", &resImportHierarchyChanges, &resStream) == FAILURE) return;
  5862. ZEND_FETCH_RESOURCE_C(lpImportHierarchyChanges, IExchangeImportHierarchyChanges *, &resImportHierarchyChanges, -1, name_mapi_importhierarchychanges, le_mapi_importhierarchychanges);
  5863. if (resStream != NULL) {
  5864. ZEND_FETCH_RESOURCE_C(lpStream, IStream *, &resStream, -1, name_istream, le_istream);
  5865. }
  5866. MAPI_G(hr) = lpImportHierarchyChanges->UpdateState(lpStream);
  5867. if(MAPI_G(hr) != hrSuccess)
  5868. goto exit;
  5869. RETVAL_TRUE;
  5870. exit:
  5871. LOG_END();
  5872. THROW_ON_ERROR();
  5873. }
  5874. ZEND_FUNCTION(mapi_importhierarchychanges_importfolderchange)
  5875. {
  5876. PMEASURE_FUNC;
  5877. LOG_BEGIN();
  5878. zval * resImportHierarchyChanges = NULL;
  5879. zval * resProps = NULL;
  5880. IExchangeImportHierarchyChanges *lpImportHierarchyChanges = NULL;
  5881. memory_ptr<SPropValue> lpProps;
  5882. ULONG cValues = 0;
  5883. RETVAL_FALSE;
  5884. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5885. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra", &resImportHierarchyChanges, &resProps) == FAILURE) return;
  5886. ZEND_FETCH_RESOURCE_C(lpImportHierarchyChanges, IExchangeImportHierarchyChanges *, &resImportHierarchyChanges, -1, name_mapi_importhierarchychanges, le_mapi_importhierarchychanges);
  5887. MAPI_G(hr) = PHPArraytoPropValueArray(resProps, NULL, &cValues, &~lpProps TSRMLS_CC);
  5888. if(MAPI_G(hr) != hrSuccess) {
  5889. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to convert properties in properties array");
  5890. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5891. goto exit;
  5892. }
  5893. MAPI_G(hr) = lpImportHierarchyChanges->ImportFolderChange(cValues, lpProps);
  5894. if(MAPI_G(hr) != hrSuccess)
  5895. goto exit;
  5896. RETVAL_TRUE;
  5897. exit:
  5898. LOG_END();
  5899. THROW_ON_ERROR();
  5900. }
  5901. ZEND_FUNCTION(mapi_importhierarchychanges_importfolderdeletion)
  5902. {
  5903. PMEASURE_FUNC;
  5904. LOG_BEGIN();
  5905. zval * resImportHierarchyChanges = NULL;
  5906. zval * resFolders = NULL;
  5907. IExchangeImportHierarchyChanges *lpImportHierarchyChanges = NULL;
  5908. memory_ptr<SBinaryArray> lpFolders;
  5909. long ulFlags = 0;
  5910. RETVAL_FALSE;
  5911. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5912. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rla", &resImportHierarchyChanges, &ulFlags, &resFolders) == FAILURE) return;
  5913. ZEND_FETCH_RESOURCE_C(lpImportHierarchyChanges, IExchangeImportHierarchyChanges *, &resImportHierarchyChanges, -1, name_mapi_importhierarchychanges, le_mapi_importhierarchychanges);
  5914. MAPI_G(hr) = PHPArraytoSBinaryArray(resFolders, NULL, &~lpFolders TSRMLS_CC);
  5915. if(MAPI_G(hr) != hrSuccess) {
  5916. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse folder list");
  5917. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5918. goto exit;
  5919. }
  5920. MAPI_G(hr) = lpImportHierarchyChanges->ImportFolderDeletion(ulFlags, lpFolders);
  5921. if(MAPI_G(hr) != hrSuccess)
  5922. goto exit;
  5923. RETVAL_TRUE;
  5924. exit:
  5925. LOG_END();
  5926. THROW_ON_ERROR();
  5927. }
  5928. /*
  5929. * This function needs some explanation as it is not just a one-to-one MAPI function. This function
  5930. * accepts an object from PHP, and returns a resource. The resource is the MAPI equivalent of the passed
  5931. * object, which can then be passed to mapi_exportchanges_config(). This basically can be seen as a callback
  5932. * system whereby mapi_exportchanges_synchronize() calls back to PHP-space to give it data.
  5933. *
  5934. * The way we do this is to create a real IExchangeImportChanges class that calls back to its PHP equivalent
  5935. * in each method implementation. If the function cannot be found, we simply return an appropriate error.
  5936. *
  5937. * We also have to make sure that we do good refcounting here, as the user may wrap a PHP object, and then
  5938. * delete references to that object. We still hold an internal reference though, so we have to tell Zend
  5939. * that we still have a pointer to the object. We do this with the standard internal Zend refcounting system.
  5940. */
  5941. ZEND_FUNCTION(mapi_wrap_importcontentschanges)
  5942. {
  5943. PMEASURE_FUNC;
  5944. LOG_BEGIN();
  5945. zval * objImportContentsChanges = NULL;
  5946. ECImportContentsChangesProxy * lpImportContentsChanges = NULL;
  5947. RETVAL_FALSE;
  5948. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5949. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &objImportContentsChanges) == FAILURE) return;
  5950. lpImportContentsChanges = new ECImportContentsChangesProxy(objImportContentsChanges TSRMLS_CC);
  5951. // Simply return the wrapped object
  5952. UOBJ_REGISTER_RESOURCE(return_value, lpImportContentsChanges, le_mapi_importcontentschanges);
  5953. MAPI_G(hr) = hrSuccess;
  5954. LOG_END();
  5955. THROW_ON_ERROR();
  5956. }
  5957. // Same for IExchangeImportHierarchyChanges
  5958. ZEND_FUNCTION(mapi_wrap_importhierarchychanges)
  5959. {
  5960. PMEASURE_FUNC;
  5961. LOG_BEGIN();
  5962. zval * objImportHierarchyChanges = NULL;
  5963. ECImportHierarchyChangesProxy * lpImportHierarchyChanges = NULL;
  5964. RETVAL_FALSE;
  5965. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5966. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &objImportHierarchyChanges) == FAILURE) return;
  5967. lpImportHierarchyChanges = new ECImportHierarchyChangesProxy(objImportHierarchyChanges TSRMLS_CC);
  5968. // Simply return the wrapped object
  5969. UOBJ_REGISTER_RESOURCE(return_value, lpImportHierarchyChanges, le_mapi_importhierarchychanges);
  5970. MAPI_G(hr) = hrSuccess;
  5971. LOG_END();
  5972. THROW_ON_ERROR();
  5973. }
  5974. ZEND_FUNCTION(mapi_inetmapi_imtoinet)
  5975. {
  5976. PMEASURE_FUNC;
  5977. LOG_BEGIN();
  5978. zval *resSession;
  5979. zval *resAddrBook;
  5980. zval *resMessage;
  5981. zval *resOptions;
  5982. sending_options sopt;
  5983. object_ptr<ECMemStream> lpMemStream = NULL;
  5984. IStream *lpStream = NULL;
  5985. std::unique_ptr<char[]> lpBuffer;
  5986. imopt_default_sending_options(&sopt);
  5987. sopt.no_recipients_workaround = true;
  5988. IMAPISession *lpMAPISession = NULL;
  5989. IAddrBook *lpAddrBook = NULL;
  5990. IMessage *lpMessage = NULL;
  5991. RETVAL_FALSE;
  5992. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  5993. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrra", &resSession, &resAddrBook, &resMessage, &resOptions) == FAILURE) return;
  5994. ZEND_FETCH_RESOURCE_C(lpMAPISession, IMAPISession *, &resSession, -1, name_mapi_session, le_mapi_session);
  5995. ZEND_FETCH_RESOURCE_C(lpAddrBook, IAddrBook *, &resAddrBook, -1, name_mapi_addrbook, le_mapi_addrbook);
  5996. ZEND_FETCH_RESOURCE_C(lpMessage, IMessage *, &resMessage, -1, name_mapi_message, le_mapi_message);
  5997. MAPI_G(hr) = PHPArraytoSendingOptions(resOptions, &sopt);
  5998. if(MAPI_G(hr) != hrSuccess)
  5999. goto exit;
  6000. MAPI_G(hr) = IMToINet(lpMAPISession, lpAddrBook, lpMessage, &unique_tie(lpBuffer), sopt);
  6001. if(MAPI_G(hr) != hrSuccess)
  6002. goto exit;
  6003. MAPI_G(hr) = ECMemStream::Create(lpBuffer.get(), strlen(lpBuffer.get()), 0, nullptr, nullptr, nullptr, &~lpMemStream);
  6004. if(MAPI_G(hr) != hrSuccess)
  6005. goto exit;
  6006. MAPI_G(hr) = lpMemStream->QueryInterface(IID_IStream, (void **)&lpStream);
  6007. if(MAPI_G(hr) != hrSuccess)
  6008. goto exit;
  6009. ZEND_REGISTER_RESOURCE(return_value, lpStream, le_istream);
  6010. exit:
  6011. LOG_END();
  6012. THROW_ON_ERROR();
  6013. }
  6014. ZEND_FUNCTION(mapi_inetmapi_imtomapi)
  6015. {
  6016. PMEASURE_FUNC;
  6017. LOG_BEGIN();
  6018. zval *resSession;
  6019. zval *resStore;
  6020. zval *resAddrBook;
  6021. zval *resMessage;
  6022. zval *resOptions;
  6023. delivery_options dopt;
  6024. size_t cbString = 0;
  6025. char *szString = NULL;
  6026. imopt_default_delivery_options(&dopt);
  6027. IMAPISession *lpMAPISession = NULL;
  6028. IAddrBook *lpAddrBook = NULL;
  6029. IMessage *lpMessage = NULL;
  6030. IMsgStore *lpMsgStore = NULL;
  6031. RETVAL_FALSE;
  6032. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  6033. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrrrsa", &resSession, &resStore, &resAddrBook, &resMessage, &szString, &cbString, &resOptions) == FAILURE) return;
  6034. ZEND_FETCH_RESOURCE_C(lpMAPISession, IMAPISession *, &resSession, -1, name_mapi_session, le_mapi_session);
  6035. ZEND_FETCH_RESOURCE_C(lpMsgStore, IMsgStore *, &resStore, -1, name_mapi_msgstore, le_mapi_msgstore);
  6036. ZEND_FETCH_RESOURCE_C(lpAddrBook, IAddrBook *, &resAddrBook, -1, name_mapi_addrbook, le_mapi_addrbook);
  6037. ZEND_FETCH_RESOURCE_C(lpMessage, IMessage *, &resMessage, -1, name_mapi_message, le_mapi_message);
  6038. std::string strInput(szString, cbString);
  6039. MAPI_G(hr) = PHPArraytoDeliveryOptions(resOptions, &dopt);
  6040. if(MAPI_G(hr) != hrSuccess)
  6041. goto exit;
  6042. MAPI_G(hr) = IMToMAPI(lpMAPISession, lpMsgStore, lpAddrBook, lpMessage, strInput, dopt);
  6043. if(MAPI_G(hr) != hrSuccess)
  6044. goto exit;
  6045. RETVAL_TRUE;
  6046. exit:
  6047. LOG_END();
  6048. THROW_ON_ERROR();
  6049. return;
  6050. }
  6051. ZEND_FUNCTION(mapi_icaltomapi)
  6052. {
  6053. PMEASURE_FUNC;
  6054. LOG_BEGIN();
  6055. zval *resSession;
  6056. zval *resStore;
  6057. zval *resAddrBook;
  6058. zval *resMessage;
  6059. zend_bool *noRecipients;
  6060. size_t cbString = 0;
  6061. char *szString = nullptr;
  6062. IMAPISession *lpMAPISession = nullptr;
  6063. IAddrBook *lpAddrBook = nullptr;
  6064. IMessage *lpMessage = nullptr;
  6065. IMsgStore *lpMsgStore = nullptr;
  6066. std::unique_ptr<ICalToMapi> lpIcalToMapi;
  6067. RETVAL_FALSE;
  6068. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  6069. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrrrsb",
  6070. &resSession, &resStore, &resAddrBook, &resMessage, &szString,
  6071. &cbString, &noRecipients) == FAILURE)
  6072. return;
  6073. ZEND_FETCH_RESOURCE_C(lpMAPISession, IMAPISession *, &resSession, -1, name_mapi_session, le_mapi_session);
  6074. ZEND_FETCH_RESOURCE_C(lpMsgStore, IMsgStore *, &resStore, -1, name_mapi_msgstore, le_mapi_msgstore);
  6075. ZEND_FETCH_RESOURCE_C(lpAddrBook, IAddrBook *, &resAddrBook, -1, name_mapi_addrbook, le_mapi_addrbook);
  6076. ZEND_FETCH_RESOURCE_C(lpMessage, IMessage *, &resMessage, -1, name_mapi_message, le_mapi_message);
  6077. std::string icalMsg(szString, cbString);
  6078. // noRecpients, skip recipients from ical.
  6079. // Used for DAgent, which uses the mail recipients
  6080. CreateICalToMapi(lpMsgStore, lpAddrBook, noRecipients, &unique_tie(lpIcalToMapi));
  6081. if (lpIcalToMapi == nullptr) {
  6082. MAPI_G(hr) = MAPI_E_NOT_ENOUGH_MEMORY;
  6083. goto exit;
  6084. }
  6085. // Set the default timezone to UTC if none is set, replicating the
  6086. // behaviour of VMIMEToMAPI.
  6087. MAPI_G(hr) = lpIcalToMapi->ParseICal(icalMsg, "utf-8", "UTC", nullptr, 0);
  6088. if (MAPI_G(hr) != hrSuccess)
  6089. goto exit;
  6090. MAPI_G(hr) = lpIcalToMapi->GetItem(0, 0, lpMessage);
  6091. if (MAPI_G(hr) != hrSuccess)
  6092. goto exit;
  6093. exit:
  6094. RETVAL_TRUE;
  6095. LOG_END();
  6096. THROW_ON_ERROR();
  6097. return;
  6098. }
  6099. ZEND_FUNCTION(mapi_mapitoical)
  6100. {
  6101. PMEASURE_FUNC;
  6102. LOG_BEGIN();
  6103. zval *resSession;
  6104. zval *resAddrBook;
  6105. zval *resMessage;
  6106. zval *resOptions;
  6107. IMAPISession *lpMAPISession = nullptr;
  6108. IAddrBook *lpAddrBook = nullptr;
  6109. IMessage *lpMessage = nullptr;
  6110. std::unique_ptr<MapiToICal> lpMtIcal;
  6111. std::string strical("");
  6112. std::string method("");
  6113. RETVAL_FALSE;
  6114. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  6115. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrra",
  6116. &resSession, &resAddrBook, &resMessage, &resOptions) == FAILURE)
  6117. return;
  6118. ZEND_FETCH_RESOURCE_C(lpMAPISession, IMAPISession *, &resSession, -1, name_mapi_session, le_mapi_session);
  6119. ZEND_FETCH_RESOURCE_C(lpAddrBook, IAddrBook *, &resAddrBook, -1, name_mapi_addrbook, le_mapi_addrbook);
  6120. ZEND_FETCH_RESOURCE_C(lpMessage, IMessage *, &resMessage, -1, name_mapi_message, le_mapi_message);
  6121. // set HR
  6122. CreateMapiToICal(lpAddrBook, "utf-8", &unique_tie(lpMtIcal));
  6123. if (lpMtIcal == nullptr) {
  6124. MAPI_G(hr) = MAPI_E_NOT_ENOUGH_MEMORY;
  6125. goto exit;
  6126. }
  6127. MAPI_G(hr) = lpMtIcal->AddMessage(lpMessage, "", 0);
  6128. if (MAPI_G(hr) != hrSuccess)
  6129. goto exit;
  6130. MAPI_G(hr) = lpMtIcal->Finalize(0, &method, &strical);
  6131. RETVAL_STRING(strical.c_str());
  6132. exit:
  6133. LOG_END();
  6134. THROW_ON_ERROR();
  6135. }
  6136. ZEND_FUNCTION(mapi_vcftomapi)
  6137. {
  6138. zval *resSession;
  6139. zval *resStore;
  6140. zval *resMessage;
  6141. ULONG cbString = 0;
  6142. char *szString = nullptr;
  6143. IMAPISession *lpMAPISession = nullptr;
  6144. IMessage *lpMessage = nullptr;
  6145. IMsgStore *lpMsgStore = nullptr;
  6146. std::unique_ptr<vcftomapi> conv;
  6147. RETVAL_FALSE;
  6148. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  6149. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrrs",
  6150. &resSession, &resStore, &resMessage, &szString,
  6151. &cbString) == FAILURE)
  6152. return;
  6153. ZEND_FETCH_RESOURCE_C(lpMAPISession, IMAPISession *, &resSession, -1, name_mapi_session, le_mapi_session);
  6154. ZEND_FETCH_RESOURCE_C(lpMsgStore, IMsgStore *, &resStore, -1, name_mapi_msgstore, le_mapi_msgstore);
  6155. ZEND_FETCH_RESOURCE_C(lpMessage, IMessage *, &resMessage, -1, name_mapi_message, le_mapi_message);
  6156. std::string vcfMsg(szString, cbString);
  6157. create_vcftomapi(lpMsgStore, &unique_tie(conv));
  6158. if (conv == nullptr) {
  6159. MAPI_G(hr) = MAPI_E_NOT_ENOUGH_MEMORY;
  6160. goto exit;
  6161. }
  6162. MAPI_G(hr) = conv->parse_vcf(vcfMsg);
  6163. if (MAPI_G(hr) != hrSuccess)
  6164. goto exit;
  6165. MAPI_G(hr) = conv->get_item(lpMessage);
  6166. if (MAPI_G(hr) != hrSuccess)
  6167. goto exit;
  6168. exit:
  6169. RETVAL_TRUE;
  6170. LOG_END();
  6171. THROW_ON_ERROR();
  6172. return;
  6173. }
  6174. ZEND_FUNCTION(mapi_mapitovcf)
  6175. {
  6176. PMEASURE_FUNC;
  6177. LOG_BEGIN();
  6178. zval *resSession;
  6179. zval *resAddrBook;
  6180. zval *resMessage;
  6181. zval *resOptions;
  6182. IMAPISession *lpMAPISession = nullptr;
  6183. IMessage *lpMessage = nullptr;
  6184. std::unique_ptr<mapitovcf> conv;
  6185. std::string vcf;
  6186. MAPI_G(hr) = MAPI_E_INVALID_PARAMETER;
  6187. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrra",
  6188. &resSession, &resAddrBook, &resMessage, &resOptions) == FAILURE)
  6189. return;
  6190. ZEND_FETCH_RESOURCE_C(lpMAPISession, IMAPISession *, &resSession, -1, name_mapi_session, le_mapi_session);
  6191. ZEND_FETCH_RESOURCE_C(lpMessage, IMessage *, &resMessage, -1, name_mapi_message, le_mapi_message);
  6192. create_mapitovcf(&unique_tie(conv));
  6193. if (conv == nullptr) {
  6194. MAPI_G(hr) = MAPI_E_NOT_ENOUGH_MEMORY;
  6195. goto exit;
  6196. }
  6197. MAPI_G(hr) = conv->add_message(lpMessage);
  6198. if (MAPI_G(hr) != hrSuccess)
  6199. goto exit;
  6200. MAPI_G(hr) = conv->finalize(&vcf);
  6201. RETVAL_STRING(vcf.c_str());
  6202. exit:
  6203. LOG_END();
  6204. THROW_ON_ERROR();
  6205. }
  6206. ZEND_FUNCTION(mapi_enable_exceptions)
  6207. {
  6208. PMEASURE_FUNC;
  6209. LOG_BEGIN();
  6210. zend_class_entry *ce = NULL;
  6211. zend_string *str_class;
  6212. RETVAL_FALSE;
  6213. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &str_class) == FAILURE) return;
  6214. if ((ce = *(zend_class_entry **)zend_hash_find(CG(class_table), str_class)) != NULL) {
  6215. MAPI_G(exceptions_enabled) = true;
  6216. MAPI_G(exception_ce) = ce;
  6217. RETVAL_TRUE;
  6218. }
  6219. LOG_END();
  6220. return;
  6221. }
  6222. // Can be queried by client applications to check whether certain API features are supported or not.
  6223. ZEND_FUNCTION(mapi_feature)
  6224. {
  6225. PMEASURE_FUNC;
  6226. LOG_BEGIN();
  6227. static const char *const features[] =
  6228. {"LOGONFLAGS", "NOTIFICATIONS", "INETMAPI_IMTOMAPI"};
  6229. const char *szFeature = NULL;
  6230. size_t cbFeature = 0;
  6231. RETVAL_FALSE;
  6232. if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &szFeature, &cbFeature) == FAILURE) return;
  6233. for (size_t i = 0; i < ARRAY_SIZE(features); ++i)
  6234. if(strcasecmp(features[i], szFeature) == 0) {
  6235. RETVAL_TRUE;
  6236. break;
  6237. }
  6238. LOG_END();
  6239. return;
  6240. }