12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831 |
- <?php
- /**
- *
- * Connects to vboxwebsrv, calls SOAP methods, and returns data.
- *
- * @author Ian Moore (imoore76 at yahoo dot com)
- * @copyright Copyright (C) 2010-2015 Ian Moore (imoore76 at yahoo dot com)
- * @version $Id: vboxconnector.php 599 2015-07-27 10:40:37Z imoore76 $
- * @package phpVirtualBox
- *
- */
-
- class vboxconnector {
-
- /**
- * Error with safe HTML
- * @var integer
- */
- const PHPVB_ERRNO_HTML = 1;
-
- /**
- * Error number describing a fatal error
- * @var integer
- */
- const PHPVB_ERRNO_FATAL = 32;
-
- /**
- * Error number describing a connection error
- * @var integer
- */
- const PHPVB_ERRNO_CONNECT = 64;
-
- /**
- * phpVirtualBox groups extra value key
- * @var string
- */
- const phpVboxGroupKey = 'phpvb/Groups';
-
- /**
- * Holds any errors that occur during processing. Errors are placed in here
- * when we want calling functions to be aware of the error, but do not want to
- * halt processing
- *
- * @var array
- */
- var $errors = array();
-
- /**
- * Holds any debug messages
- *
- * @var array
- */
- var $messages = array();
-
- /**
- * Settings object
- * @var phpVBoxConfigClass
- * @see phpVBoxConfigClass
- */
- var $settings = null;
-
- /**
- * true if connected to vboxwebsrv
- * @var boolean
- */
- var $connected = false;
-
- /**
- * IVirtualBox instance
- * @var IVirtualBox
- */
- var $vbox = null;
-
- /**
- * VirtualBox web session manager
- * @var IWebsessionManager
- */
- var $websessionManager = null;
-
- /**
- * Holds IWebsessionManager session object if created
- * during processing so that it can be properly shutdown
- * in __destruct
- * @var ISession
- * @see vboxconnector::__destruct()
- */
- var $session = null;
-
- /**
- * Holds VirtualBox version information
- * @var array
- */
- var $version = null;
-
- /**
- * If true, vboxconnector will not verify that there is a valid
- * (PHP) session before connecting.
- * @var boolean
- */
- var $skipSessionCheck = false;
-
- /**
- * Holds items that should persist accross requests
- * @var array
- */
- var $persistentRequest = array();
-
- /**
- * Holds VirtualBox host OS specific directory separator set by getDSep()
- * @var string
- * @see vboxconnector::getDsep()
- */
- var $dsep = null;
-
- /**
- * Obtain configuration settings and set object vars
- * @param boolean $useAuthMaster use the authentication master obtained from configuration class
- * @see phpVBoxConfigClass
- */
- public function __construct($useAuthMaster = false) {
-
- require_once(dirname(__FILE__).'/language.php');
- require_once(dirname(__FILE__).'/vboxServiceWrappers.php');
-
- /* Set up.. .. settings */
-
- /** @var phpVBoxConfigClass */
- $this->settings = new phpVBoxConfigClass();
-
- // Are default settings being used?
- if(@$this->settings->warnDefault) {
- throw new Exception("No configuration found. Rename the file <b>config.php-example</b> in phpVirtualBox's folder to ".
- "<b>config.php</b> and edit as needed.<p>For more detailed instructions, please see the installation wiki on ".
- "phpVirtualBox's web site. <p><a href='https://github.com/phpvirtualbox/phpvirtualbox/wiki' target=_blank>".
- "https://github.com/phpvirtualbox/phpvirtualbox/wiki</a>.</p>",
- (vboxconnector::PHPVB_ERRNO_FATAL + vboxconnector::PHPVB_ERRNO_HTML));
- }
-
- // Check for SoapClient class
- if(!class_exists('SoapClient')) {
- throw new Exception('PHP does not have the SOAP extension enabled.',vboxconnector::PHPVB_ERRNO_FATAL);
- }
-
- // use authentication master server?
- if(@$useAuthMaster) {
- $this->settings->setServer($this->settings->getServerAuthMaster());
- }
-
- }
-
- /**
- * Connect to vboxwebsrv
- * @see SoapClient
- * @see phpVBoxConfigClass
- * @return boolean true on success or if already connected
- */
- public function connect() {
-
- // Already connected?
- if(@$this->connected)
- return true;
-
- // Valid session?
- if(!@$this->skipSessionCheck && !$_SESSION['valid']) {
- throw new Exception(trans('Not logged in.','UIUsers'),vboxconnector::PHPVB_ERRNO_FATAL);
- }
-
- // Persistent server?
- if(@$this->persistentRequest['vboxServer']) {
- $this->settings->setServer($this->persistentRequest['vboxServer']);
- }
-
- //Connect to webservice
- $pvbxver = substr(@constant('PHPVBOX_VER'),0,(strpos(@constant('PHPVBOX_VER'),'-')));
- $this->client = new SoapClient(dirname(__FILE__)."/vboxwebService-".$pvbxver.".wsdl",
- array(
- 'features' => (SOAP_USE_XSI_ARRAY_TYPE + SOAP_SINGLE_ELEMENT_ARRAYS),
- 'cache_wsdl' => WSDL_CACHE_BOTH,
- 'trace' => (@$this->settings->debugSoap),
- 'connection_timeout' => (@$this->settings->connectionTimeout ? $this->settings->connectionTimeout : 20),
- 'location' => @$this->settings->location
- ));
-
-
- // Persistent handles?
- if(@$this->persistentRequest['vboxHandle']) {
-
- try {
-
- // Check for existing sessioin
- $this->websessionManager = new IWebsessionManager($this->client);
- $this->vbox = new IVirtualBox($this->client, $this->persistentRequest['vboxHandle']);
-
- // force valid vbox check
- $ev = $this->vbox->eventSource;
-
- if($this->vbox->handle)
- return ($this->connected = true);
-
-
- } catch (Exception $e) {
- // nothing. Fall through to new login.
-
- }
- }
-
- /* Try / catch / throw here hides login credentials from exception if one is thrown */
- try {
- $this->websessionManager = new IWebsessionManager($this->client);
- $this->vbox = $this->websessionManager->logon($this->settings->username,$this->settings->password);
-
-
- } catch (Exception $e) {
-
- if(!($msg = $e->getMessage()))
- $msg = 'Error logging in to vboxwebsrv.';
- else
- $msg .= " ({$this->settings->location})";
-
- throw new Exception($msg,vboxconnector::PHPVB_ERRNO_CONNECT);
- }
-
-
- // Error logging in
- if(!$this->vbox->handle) {
- throw new Exception('Error logging in or connecting to vboxwebsrv.',vboxconnector::PHPVB_ERRNO_CONNECT);
- }
-
- // Hold handle
- if(array_key_exists('vboxHandle',$this->persistentRequest)) {
- $this->persistentRequest['vboxHandle'] = $this->vbox->handle;
- }
-
- return ($this->connected = true);
-
- }
-
-
- /**
- * Get VirtualBox version
- * @return array version information
- */
- public function getVersion() {
-
- if(!@$this->version) {
-
- $this->connect();
-
- $this->version = explode('.',$this->vbox->version);
- $this->version = array(
- 'ose' => (stripos($this->version[2],'ose') > 0),
- 'string' => join('.',$this->version),
- 'major' => intval(array_shift($this->version)),
- 'minor' => intval(array_shift($this->version)),
- 'sub' => intval(array_shift($this->version)),
- 'revision' => (string)$this->vbox->revision,
- 'settingsFilePath' => $this->vbox->settingsFilePath
- );
- }
-
- return $this->version;
-
- }
-
- /**
- *
- * Log out of vboxwebsrv
- */
- public function __destruct() {
-
- // Do not logout if there are persistent handles
- if($this->connected && @$this->vbox->handle && !array_key_exists('vboxHandle' ,$this->persistentRequest)) {
-
- // Failsafe to close session
- if(@$this->session && @(string)$this->session->state == 'Locked') {
- try {$this->session->unlockMachine();}
- catch (Exception $e) { }
- }
-
- // Logoff
- if($this->vbox->handle)
- $this->websessionManager->logoff($this->vbox->handle);
-
- }
-
- unset($this->client);
- }
-
- /**
- * Add a machine event listener to the listener list
- *
- * @param string $vm id of virtual machine to subscribe to
- */
- private function _machineSubscribeEvents($vm) {
-
- // Check for existing listener
- if($this->persistentRequest['vboxEventListeners'][$vm]) {
-
- try {
-
- $listener = new IEventListener($this->client, $this->persistentRequest['vboxEventListeners'][$vm]['listener']);
- $source = new IEventSource($this->client, $this->persistentRequest['vboxEventListeners'][$vm]['source']);
-
- $source->unregisterListener($listener);
-
- $listener->releaseRemote();
- $source->releaseRemote();
-
- } catch (Exception $e) {
- // Pass
- }
- }
-
- try {
-
- /* @var $machine IMachine */
- $machine = $this->vbox->findMachine($vm);
-
- /* Ignore if not running */
- $state = (string)$machine->state;
- if($state != 'Running' && $state != 'Paused') {
- $machine->releaseRemote();
- return;
- }
-
- $this->session = $this->websessionManager->getSessionObject($this->vbox->handle);
- $machine->lockMachine($this->session->handle, 'Shared');
-
- // Create and register event listener
- $listener = $this->session->console->eventSource->createListener();
- $this->session->console->eventSource->registerListener($listener,array('Any'), false);
-
- // Add to event listener list
- $this->persistentRequest['vboxEventListeners'][$vm] = array(
- 'listener' => $listener->handle,
- 'source' => $this->session->console->eventSource->handle);
-
-
- $machine->releaseRemote();
-
- } catch (Exception $e) {
- // pass
- }
-
- if($this->session) {
- try {
- $this->session->unlockMachine();
- } catch (Exception $e) {
- // pass
- }
- unset($this->session);
- }
-
- // Machine events before vbox events. This is in place to handle the "DrvVD_DEKMISSING"
- // IRuntimeErrorEvent which tells us that a medium attached to a VM requires a password.
- // This event needs to be presented to the client before the VM state change. This way
- // the client can track whether or not the runtime error occurred in response to its
- // startup request because the machine's RunTimeError will occur before vbox's
- // StateChange.
- uksort($this->persistentRequest['vboxEventListeners'], function($a, $b){
- if($a == 'vbox') return 1;
- if($b == 'vbox') return -1;
- return 0;
- });
-
- }
-
- /**
- * Get pending vbox and machine events
- *
- * @param array $args array of arguments. See function body for details.
- * @return array list of events
- */
- public function remote_getEvents($args) {
-
- $this->connect();
-
- $eventlist = array();
-
- // This should be an array
- if(!is_array($this->persistentRequest['vboxEventListeners'])) {
-
- $this->persistentRequest['vboxEventListeners'] = array();
- $listenerWait = 1000;
-
- } else {
-
- // The amount of time we will wait for events is determined by
- // the amount of listeners - at least half a second
- $listenerWait = max(100,intval(500/count($this->persistentRequest['vboxEventListeners'])));
- }
-
- // Get events from each configured event listener
- foreach($this->persistentRequest['vboxEventListeners'] as $k => $el) {
-
- try {
-
- $listener = new IEventListener($this->client, $el['listener']);
- $source = new IEventSource($this->client, $el['source']);
-
- $event = $source->getEvent($listener,$listenerWait);
-
- try {
-
- while($event->handle) {
-
- $eventData = $this->_getEventData($event, $k);
- $source->eventProcessed($listener, $event);
- $event->releaseRemote();
-
-
- // Only keep the last event of one particular type
- //$eventlist[$eventData['dedupId']] = $eventData;
-
- if($eventData)
- $eventlist[$eventData['dedupId']] = $eventData;
-
- $event = $source->getEvent($listener,100);
- }
-
- } catch (Exception $e) {
-
- $this->errors[] = $e;
-
- }
-
- } catch (Exception $e) {
-
- // Machine powered off or client has stale MO reference
- if($listener)
- try { $listener->releaseRemote(); } catch (Exceptoin $e) {
- /// pass
- }
- if($source)
- try { $source->releaseRemote(); } catch (Exceptoin $e) {
- // pass
- }
-
- // Remove listener from list
- unset($this->persistentRequest['vboxEventListeners'][$k]);
-
- }
-
- }
-
- // Enrich events
- foreach($eventlist as $k=>$event) {
-
- switch($event['eventType']) {
-
- /* Network adapter changed */
- case 'OnNetworkAdapterChanged':
-
- try {
-
- $machine = $this->vbox->findMachine($event['sourceId']);
- $this->session = $this->websessionManager->getSessionObject($this->vbox->handle);
-
- // Session locked?
- if((string)$this->session->state != 'Unlocked')
- $this->session->unlockMachine();
-
- $machine->lockMachine($this->session->handle, 'Shared');
-
- try {
-
- list($eventlist[$k]['enrichmentData']) = $this->_machineGetNetworkAdapters($this->session->machine, $event['networkAdapterSlot']);
-
- } catch (Exception $e) {
- // Just unlock the machine
- $eventlist[$k]['enrichmentData'] = array($e->getMessage());
- }
-
- $this->session->unlockMachine();
- $machine->releaseRemote();
-
- } catch (Exception $e) {
- $eventlist[$k]['enrichmentData'] = array($e->getMessage());
- }
- break;
-
-
- /* VRDE server changed */
- case 'OnVRDEServerChanged':
- try {
-
- $machine = $this->vbox->findMachine($event['sourceId']);
- $this->session = $this->websessionManager->getSessionObject($this->vbox->handle);
-
- // Session locked?
- if((string)$this->session->state != 'Unlocked')
- $this->session->unlockMachine();
-
- $machine->lockMachine($this->session->handle, 'Shared');
- $vrde = $this->session->machine->VRDEServer;
-
- try {
- $eventlist[$k]['enrichmentData'] = (!$vrde ? null : array(
- 'enabled' => $vrde->enabled,
- 'ports' => $vrde->getVRDEProperty('TCP/Ports'),
- 'netAddress' => $vrde->getVRDEProperty('TCP/Address'),
- 'VNCPassword' => $vrde->getVRDEProperty('VNCPassword'),
- 'authType' => (string)$vrde->authType,
- 'authTimeout' => $vrde->authTimeout
- )
- );
- } catch (Exception $e) {
- // Just unlock the machine
- $eventlist[$k]['enrichmentData'] = array($e->getMessage());
- }
-
- $this->session->unlockMachine();
- $machine->releaseRemote();
-
- } catch (Exception $e) {
- $eventlist[$k]['enrichmentData'] = array($e->getMessage());
- }
- break;
-
-
-
- /* VRDE server info changed. Just need port and enabled/disabled */
- case 'OnVRDEServerInfoChanged':
- try {
-
- $machine = $this->vbox->findMachine($event['sourceId']);
- $this->session = $this->websessionManager->getSessionObject($this->vbox->handle);
-
- // Session locked?
- if((string)$this->session->state != 'Unlocked')
- $this->session->unlockMachine();
-
- $machine->lockMachine($this->session->handle, 'Shared');
-
- try {
- $eventlist[$k]['enrichmentData'] = array(
- 'port' => $this->session->console->VRDEServerInfo->port,
- 'enabled' => $this->session->machine->VRDEServer->enabled
- );
- } catch (Exception $e) {
- // Just unlock the machine
- $eventlist[$k]['enrichmentData'] = array($e->getMessage());
- }
-
- $this->session->unlockMachine();
- $machine->releaseRemote();
-
- } catch (Exception $e) {
- $eventlist[$k]['enrichmentData'] = array($e->getMessage());
- }
- break;
-
- /* Machine registered */
- case 'OnMachineRegistered':
-
- if(!$event['registered']) break;
-
- // Get same data that is in VM list data
- $vmdata = $this->remote_vboxGetMachines(array('vm'=>$event['machineId']));
- $eventlist[$k]['enrichmentData'] = $vmdata[0];
- unset($vmdata);
-
- break;
-
- /* enrich with basic machine data */
- case 'OnMachineDataChanged':
-
- try {
-
- $machine = $this->vbox->findMachine($event['machineId']);
-
- if($this->settings->phpVboxGroups) {
- $groups = explode(',',$machine->getExtraData(vboxconnector::phpVboxGroupKey));
- if(!is_array($groups) || (count($groups) == 1 && !$groups[0])) $groups = array("/");
- } else {
- $groups = $machine->groups;
- }
-
- usort($groups, 'strnatcasecmp');
-
- $eventlist[$k]['enrichmentData'] = array(
- 'id' => $event['machineId'],
- 'name' => @$this->settings->enforceVMOwnership ? preg_replace('/^' . preg_quote($_SESSION['user']) . '_/', '', $machine->name) : $machine->name,
- 'OSTypeId' => $machine->getOSTypeId(),
- 'owner' => (@$this->settings->enforceVMOwnership ? $machine->getExtraData("phpvb/sso/owner") : ''),
- 'groups' => $groups
- );
- $machine->releaseRemote();
-
- } catch (Exception $e) {
- // pass
- }
- break;
-
- /* Update lastStateChange on OnMachineStateChange events */
- case 'OnMachineStateChanged':
- try {
-
- $machine = $this->vbox->findMachine($event['machineId']);
- $eventlist[$k]['enrichmentData'] = array(
- 'lastStateChange' => (string)($machine->lastStateChange/1000),
- 'currentStateModified' => $machine->currentStateModified
- );
- $machine->releaseRemote();
-
- } catch (Exception $e) {
- $eventlist[$k]['enrichmentData'] = array('lastStateChange' => 0);
- }
- break;
-
- /* enrich with snapshot name and new snapshot count*/
- case 'OnSnapshotTaken':
- case 'OnSnapshotDeleted':
- case 'OnSnapshotRestored':
- case 'OnSnapshotChanged':
-
- try {
- $machine = $this->vbox->findMachine($event['machineId']);
- $eventlist[$k]['enrichmentData'] = array(
- 'currentSnapshotName' => ($machine->currentSnapshot->handle ? $machine->currentSnapshot->name : ''),
- 'snapshotCount' => $machine->snapshotCount,
- 'currentStateModified' => $machine->currentStateModified
- );
- $machine->releaseRemote();
-
- } catch (Exception $e) {
- // pass
- $this->errors[] = $e;
- }
- break;
-
- }
-
- }
-
- return array_values($eventlist);
-
- }
-
- /**
- * Subscribe to a single machine's events
- *
- * @param array $args array of arguments. See function body for details.
- * @return boolean true on success
- */
- public function remote_machineSubscribeEvents($args) {
-
- $this->connect();
- foreach($args['vms'] as $vm)
- $this->_machineSubscribeEvents($vm);
-
- return true;
- }
-
- /**
- * Unsubscribe from vbox and machine events
- *
- * @param array $args array of arguments. See function body for details.
- * @return boolean true on success
- */
- public function remote_unsubscribeEvents($args) {
-
- $this->connect();
-
- if(!is_array($this->persistentRequest['vboxEventListeners']))
- $this->persistentRequest['vboxEventListeners'] = array();
-
- // Get events from each configured event listener
- foreach($this->persistentRequest['vboxEventListeners'] as $k => $el) {
-
- try {
-
- $listener = new IEventListener($this->client, $el['listener']);
- $source = new IEventSource($this->client, $el['source']);
-
- $source->unregisterListener($listener);
-
- $source->releaseRemote();
- $listener->releaseRemote();
-
-
-
- } catch (Exception $e) {
- $this->errors[] = $e;
- }
-
- $this->persistentRequest['vboxEventListeners'][$k] = null;
-
- }
-
- $this->websessionManager->logoff($this->vbox->handle);
- unset($this->vbox);
-
- return true;
- }
-
- /**
- * Subscribe to vbox and machine events
- *
- * @param array $args array of arguments. See function body for details.
- * @return boolean true on success
- */
- public function remote_subscribeEvents($args) {
-
- $this->connect();
-
- // Check for existing listener
- if($this->persistentRequest['vboxEventListeners']['vbox']) {
-
- try {
-
- $listener = new IEventListener($this->client, $this->persistentRequest['vboxEventListeners']['vbox']['listener']);
- $source = new IEventSource($this->client, $this->persistentRequest['vboxEventListeners']['vbox']['source']);
-
- $source->unregisterListener($listener);
-
- $listener->releaseRemote();
- $source->releaseRemote();
-
- } catch (Exception $e) {
- // Pass
- }
- }
-
- // Create and register event listener
- $listener = $this->vbox->eventSource->createListener();
- $this->vbox->eventSource->registerListener($listener,array('MachineEvent', 'SnapshotEvent', 'OnMediumRegistered', 'OnExtraDataChanged', 'OnSnapshotRestored'), false);
-
- // Add to event listener list
- $this->persistentRequest['vboxEventListeners']['vbox'] = array(
- 'listener' => $listener->handle,
- 'source' => $this->vbox->eventSource->handle);
-
- // Subscribe to each machine in list
- foreach($args['vms'] as $vm) {
- $this->_machineSubscribeEvents($vm);
- }
-
- $this->persistentRequest['vboxHandle'] = $this->vbox->handle;
-
- return true;
-
- }
-
- /**
- * Return relevant event data for the event.
- *
- * @param IEvent $event
- * @param String $listenerKey Key of event listener - 'vbox' or
- * machine id
- * @return array associative array of event attributes
- */
- private function _getEventData($event, $listenerKey) {
-
- $data = array('eventType'=>(string)$event->type,'sourceId'=>$listenerKey);
-
- // Convert to parent class
- $parentClass = 'I'.substr($data['eventType'],2).'Event';
- $eventDataObject = new $parentClass($this->client, $event->handle);
-
- // Dedup ID is at least listener key ('vbox' or machine id) and event type
- $data['dedupId'] = $listenerKey.'-'.$data['eventType'];
-
- switch($data['eventType']) {
-
- case 'OnMachineStateChanged':
- $data['machineId'] = $eventDataObject->machineId;
- $data['state'] = (string)$eventDataObject->state;
- $data['dedupId'] .= '-'. $data['machineId'];
- break;
-
- case 'OnMachineDataChanged':
- $data['machineId'] = $eventDataObject->machineId;
- $data['dedupId'] .= '-'. $data['machineId'];
- break;
-
- case 'OnExtraDataCanChange':
- case 'OnExtraDataChanged':
- $data['machineId'] = $eventDataObject->machineId;
- $data['key'] = $eventDataObject->key;
- $data['value'] = $eventDataObject->value;
- $data['dedupId'] .= '-'. $data['machineId'] .'-' . $data['key'];
- break;
-
- case 'OnMediumRegistered':
- $data['machineId'] = $data['sourceId'];
- $data['mediumId'] = $eventDataObject->mediumId;
- $data['registered'] = $eventDataObject->registered;
- $data['dedupId'] .= '-'. $data['mediumId'];
- break;
-
- case 'OnMachineRegistered':
- $data['machineId'] = $eventDataObject->machineId;
- $data['registered'] = $eventDataObject->registered;
- $data['dedupId'] .= '-'. $data['machineId'];
- break;
-
- case 'OnSessionStateChanged':
- $data['machineId'] = $eventDataObject->machineId;
- $data['state'] = (string)$eventDataObject->state;
- $data['dedupId'] .= '-'. $data['machineId'];
- break;
-
- /* Snapshot events */
- case 'OnSnapshotTaken':
- case 'OnSnapshotDeleted':
- case 'OnSnapshotRestored':
- case 'OnSnapshotChanged':
- $data['machineId'] = $eventDataObject->machineId;
- $data['snapshotId'] = $eventDataObject->snapshotId;
- $data['dedupId'] .= '-'. $data['machineId'] .'-' . $data['snapshotId'];
- break;
-
- case 'OnGuestPropertyChanged':
- $data['machineId'] = $eventDataObject->machineId;
- $data['name'] = $eventDataObject->name;
- $data['value'] = $eventDataObject->value;
- $data['flags'] = $eventDataObject->flags;
- $data['dedupId'] .= '-'. $data['machineId'] .'-' . $data['name'];
- break;
-
- case 'OnCPUChanged':
- $data['machineId'] = $data['sourceId'];
- $data['cpu'] = $eventDataObject->cpu;
- $data['add'] = $eventDataObject->add;
- $data['dedupId'] .= '-' . $data['cpu'];
- break;
-
- /* Same end-result as network adapter changed */
- case 'OnNATRedirect':
- $data['machineId'] = $data['sourceId'];
- $data['eventType'] = 'OnNetworkAdapterChanged';
- $data['networkAdapterSlot'] = $eventDataObject->slot;
- $data['dedupId'] = $listenerKey .'-OnNetworkAdapterChanged-'. $data['networkAdapterSlot'];
- break;
-
- case 'OnNetworkAdapterChanged':
- $data['machineId'] = $data['sourceId'];
- $data['networkAdapterSlot'] = $eventDataObject->networkAdapter->slot;
- $data['dedupId'] .= '-'. $data['networkAdapterSlot'];
- break;
-
- /* Storage controller of VM changed */
- case 'OnStorageControllerChanged':
- $data['machineId'] = $eventDataObject->machineId;
- $data['dedupId'] .= '-'. $data['machineId'];
- break;
-
- /* Medium attachment changed */
- case 'OnMediumChanged':
- $data['machineId'] = $data['sourceId'];
- $ma = $eventDataObject->mediumAttachment;
- $data['controller'] = $ma->controller;
- $data['port'] = $ma->port;
- $data['device'] = $ma->device;
- try {
- $data['medium'] = $ma->medium->id;
- } catch (Exception $e) {
- $data['medium'] = '';
- }
- $data['dedupId'] .= '-'. $data['controller'] .'-'. $data['port'] .'-'.$data['device'];
- break;
-
- /* Generic machine changes that should query IMachine */
- case 'OnVRDEServerChanged':
- $data['machineId'] = $data['sourceId'];
- break;
- case 'OnUSBControllerChanged':
- $data['machineId'] = $data['sourceId'];
- break;
- case 'OnSharedFolderChanged':
- $data['machineId'] = $data['sourceId'];
- $data['scope'] = (string)$eventDataObject->scope;
- break;
- case 'OnVRDEServerInfoChanged':
- $data['machineId'] = $data['sourceId'];
- break;
- case 'OnCPUExecutionCapChanged':
- $data['machineId'] = $data['sourceId'];
- $data['executionCap'] = $eventDataObject->executionCap;
- break;
-
-
- /* Notification when a USB device is attached to or detached from the virtual USB controller */
- case 'OnUSBDeviceStateChanged':
- $data['machineId'] = $data['sourceId'];
- $data['deviceId'] = $eventDataObject->device->id;
- $data['attached'] = $eventDataObject->attached;
- $data['dedupId'] .= '-'. $data['deviceId'];
- break;
-
- /* Machine execution error */
- case 'OnRuntimeError':
- $data['id'] = (string)$eventDataObject->id;
- $data['machineId'] = $data['sourceId'];
- $data['message'] = $eventDataObject->message;
- $data['fatal'] = $eventDataObject->fatal;
- $data['dedupId'] .= '-' . $data['id'];
- break;
-
- /* Notification when a storage device is attached or removed. */
- case 'OnStorageDeviceChanged':
- $data['machineId'] = $eventDataObject->machineId;
- $data['storageDevice'] = $eventDataObject->storageDevice;
- $data['removed'] = $eventDataObject->removed;
- break;
-
- /* On nat network delete / create */
- case 'OnNATNetworkCreationDeletion':
- $data['creationEvent'] = $eventDataObject->creationEvent;
- /* NAT network change */
- case 'OnNATNetworkSetting':
- $data['networkName'] = $eventDataObject->networkName;
- $data['dedupId'] .= '-' . $data['networkName'];
- break;
-
- default:
- return null;
- }
-
-
- return $data;
-
- }
-
-
- /**
- * Call overloader.
- * Returns result of method call. Here is where python's decorators would come in handy.
- *
- * @param string $fn method to call
- * @param array $args arguments for method
- * @throws Exception
- * @return array
- */
- function __call($fn,$args) {
-
- // Valid session?
- global $_SESSION;
-
- if(!@$this->skipSessionCheck && !$_SESSION['valid']) {
- throw new Exception(trans('Not logged in.','UIUsers'),vboxconnector::PHPVB_ERRNO_FATAL);
- }
-
- $req = &$args[0];
-
-
- # Access to undefined methods prefixed with remote_
- if(method_exists($this,'remote_'.$fn)) {
-
- $args[1][0]['data']['responseData'] = $this->{'remote_'.$fn}($req);
- $args[1][0]['data']['success'] = ($args[1][0]['data']['responseData'] !== false);
- $args[1][0]['data']['key'] = $this->settings->key;
-
- // Not found
- } else {
-
- throw new Exception('Undefined method: ' . $fn ." - Clear your web browser's cache.",vboxconnector::PHPVB_ERRNO_FATAL);
-
- }
-
- return true;
- }
-
- /**
- * Enumerate guest properties of a vm
- *
- * @param array $args array of arguments. See function body for details.
- * @return array of guest properties
- */
- public function remote_machineEnumerateGuestProperties($args) {
-
- $this->connect();
-
- /* @var $m IMachine */
- $m = $this->vbox->findMachine($args['vm']);
-
- $props = $m->enumerateGuestProperties($args['pattern']);
- $m->releaseRemote();
-
- return $props;
-
- }
-
- /**
- * Set extra data of a vm
- *
- * @param array $args array of arguments. See function body for details.
- * @return array of extra data
- */
- public function remote_machineSetExtraData($args) {
-
- $this->connect();
-
- /* @var $m IMachine */
- $m = $this->vbox->findMachine($args['vm']);
-
- $m->setExtraData($args['key'],$args['value']);
- $m->releaseRemote();
-
- return true;
-
- }
-
- /**
- * Enumerate extra data of a vm
- *
- * @param array $args array of arguments. See function body for details.
- * @return array of extra data
- */
- public function remote_machineEnumerateExtraData($args) {
-
- $this->connect();
-
- /* @var $m IMachine */
- $m = $this->vbox->findMachine($args['vm']);
-
- $props = array();
-
- $keys = $m->getExtraDataKeys();
-
- usort($keys,'strnatcasecmp');
-
- foreach($keys as $k) {
- $props[$k] = $m->getExtraData($k);
- }
- $m->releaseRemote();
-
- return $props;
-
- }
-
- /**
- * Uses VirtualBox's vfsexplorer to check if a file exists
- *
- * @param array $args array of arguments. See function body for details.
- * @return boolean true if file exists
- */
- public function remote_fileExists($args) {
-
- /* No need to go through vfs explorer if local browser is true */
- if($this->settings->browserLocal) {
- return file_exists($args['file']);
- }
-
- $this->connect();
-
- $dsep = $this->getDsep();
-
- $path = str_replace($dsep.$dsep,$dsep,$args['file']);
- $dir = dirname($path);
- $file = basename($path);
-
- if(substr($dir,-1) != $dsep) $dir .= $dsep;
-
- /* @var $appl IAppliance */
- $appl = $this->vbox->createAppliance();
-
-
- /* @var $vfs IVFSExplorer */
- $vfs = $appl->createVFSExplorer('file://'.$dir);
-
- /* @var $progress IProgress */
- $progress = $vfs->update();
- $progress->waitForCompletion(-1);
- $progress->releaseRemote();
-
- $exists = $vfs->exists(array($file));
-
- $vfs->releaseRemote();
- $appl->releaseRemote();
-
-
- return count($exists);
-
- }
-
- /**
- * Install guest additions
- *
- * @param array $args array of arguments. See function body for details.
- * @return array result data
- */
- public function remote_consoleGuestAdditionsInstall($args) {
-
- $this->connect();
-
- $results = array('errored' => 0);
-
- /* @var $gem IMedium|null */
- $gem = null;
- foreach($this->vbox->DVDImages as $m) { /* @var $m IMedium */
- if(strtolower($m->name) == 'vboxguestadditions.iso') {
- $gem = $m;
- break;
- }
- $m->releaseRemote();
- }
-
- // Not in media registry. Try to register it.
- if(!$gem) {
- $checks = array(
- 'linux' => '/usr/share/virtualbox/VBoxGuestAdditions.iso',
- 'osx' => '/Applications/VirtualBox.app/Contents/MacOS/VBoxGuestAdditions.iso',
- 'sunos' => '/opt/VirtualBox/additions/VBoxGuestAdditions.iso',
- 'windows' => 'C:\Program Files\Oracle\VirtualBox\VBoxGuestAdditions.iso',
- 'windowsx86' => 'C:\Program Files (x86)\Oracle\VirtualBox\VBoxGuestAdditions.iso' // Does this exist?
- );
- $hostos = $this->vbox->host->operatingSystem;
- if(stripos($hostos,'windows') !== false) {
- $checks = array($checks['windows'],$checks['windowsx86']);
- } elseif(stripos($hostos,'solaris') !== false || stripos($hostos,'sunos') !== false) {
- $checks = array($checks['sunos']);
- // not sure of uname returned on Mac. This should cover all of them
- } elseif(stripos($hostos,'mac') !== false || stripos($hostos,'apple') !== false || stripos($hostos,'osx') !== false || stripos($hostos,'os x') !== false || stripos($hostos,'darwin') !== false) {
- $checks = array($checks['osx']);
- } elseif(stripos($hostos,'linux') !== false) {
- $checks = array($checks['linux']);
- }
-
- // Check for config setting
- if(@$this->settings->vboxGuestAdditionsISO)
- $checks = array($this->settings->vboxGuestAdditionsISO);
-
- // Unknown os and no config setting leaves all checks in place.
- // Try to register medium.
- foreach($checks as $iso) {
- try {
- $gem = $this->vbox->openMedium($iso,'DVD','ReadOnly',false);
- break;
- } catch (Exception $e) {
- // Ignore
- }
- }
- $results['sources'] = $checks;
- }
-
- // No guest additions found
- if(!$gem) {
- $results['result'] = 'noadditions';
- return $results;
- }
-
- // create session and lock machine
- /* @var $machine IMachine */
- $machine = $this->vbox->findMachine($args['vm']);
- $this->session = $this->websessionManager->getSessionObject($this->vbox->handle);
- $machine->lockMachine($this->session->handle, 'Shared');
-
- // Try update from guest if it is supported
- if(!@$args['mount_only']) {
- try {
-
- /* @var $progress IProgress */
- $progress = $this->session->console->guest->updateGuestAdditions($gem->location,array(),'WaitForUpdateStartOnly');
-
- // No error info. Save progress.
- $gem->releaseRemote();
- $this->_util_progressStore($progress);
- $results['progress'] = $progress->handle;
- return $results;
-
- } catch (Exception $e) {
-
- if(!empty($results['progress']))
- unset($results['progress']);
-
- // Try to mount medium
- $results['errored'] = 1;
- }
- }
-
- // updateGuestAdditions is not supported. Just try to mount image.
- $results['result'] = 'nocdrom';
- $mounted = false;
- foreach($machine->storageControllers as $sc) { /* @var $sc IStorageController */
- foreach($machine->getMediumAttachmentsOfController($sc->name) as $ma) { /* @var $ma IMediumAttachment */
- if((string)$ma->type == 'DVD') {
- $this->session->machine->mountMedium($sc->name, $ma->port, $ma->device, $gem->handle, true);
- $results['result'] = 'mounted';
- $mounted = true;
- break;
- }
- }
- $sc->releaseRemote();
- if($mounted) break;
- }
-
-
- $this->session->unlockMachine();
- unset($this->session);
- $machine->releaseRemote();
- $gem->releaseRemote();
-
- return $results;
- }
-
- /**
- * Attach USB device identified by $args['id'] to a running VM
- *
- * @param array $args array of arguments. See function body for details.
- * @return boolean true on success
- */
- public function remote_consoleUSBDeviceAttach($args) {
-
- $this->connect();
-
- // create session and lock machine
- /* @var $machine IMachine */
- $machine = $this->vbox->findMachine($args['vm']);
- $this->session = $this->websessionManager->getSessionObject($this->vbox->handle);
- $machine->lockMachine($this->session->handle, 'Shared');
-
- $this->session->console->attachUSBDevice($args['id']);
-
- $this->session->unlockMachine();
- unset($this->session);
- $machine->releaseRemote();
-
- return true;
- }
-
- /**
- * Detach USB device identified by $args['id'] from a running VM
- *
- * @param array $args array of arguments. See function body for details.
- * @return boolean true on success
- */
- public function remote_consoleUSBDeviceDetach($args) {
-
- $this->connect();
-
- // create session and lock machine
- /* @var $machine IMachine */
- $machine = $this->vbox->findMachine($args['vm']);
- $this->session = $this->websessionManager->getSessionObject($this->vbox->handle);
- $machine->lockMachine($this->session->handle, 'Shared');
-
- $this->session->console->detachUSBDevice($args['id']);
-
- $this->session->unlockMachine();
- unset($this->session);
- $machine->releaseRemote();
-
- return true;
- }
-
- /**
- * Save vms' groups if they have changed
- *
- * @param array $args array of arguments. See function body for details.
- * @return array response data
- */
- public function remote_machinesSaveGroups($args) {
-
- $this->connect();
-
- $response = array('saved'=>array(),'errored'=>false);
-
- foreach($args['vms'] as $vm) {
-
- // create session and lock machine
- /* @var $machine IMachine */
- try {
- $machine = $this->vbox->findMachine($vm['id']);
- } catch (Exception $null) {
- continue;
- }
-
- $newGroups = $vm['groups'];
-
- if($this->settings->phpVboxGroups) {
-
- $oldGroups = explode(',',$machine->getExtraData(vboxconnector::phpVboxGroupKey));
- if(!is_array($oldGroups)) $oldGroups = array("/");
- if(!count(array_diff($oldGroups,$newGroups)) && !count(array_diff($newGroups,$oldGroups))) {
- continue;
- }
-
- } else {
-
- $oldGroups = $machine->groups;
-
- if((string)$machine->sessionState != 'Unlocked' || (!count(array_diff($oldGroups,$newGroups)) && !count(array_diff($newGroups,$oldGroups)))) {
- $machine->releaseRemote();
- continue;
- }
-
- }
-
- try {
-
- $this->session = $this->websessionManager->getSessionObject($this->vbox->handle);
-
- $machine->lockMachine($this->session->handle, 'Shared');
-
- usort($newGroups,'strnatcasecmp');
-
- if($this->settings->phpVboxGroups) {
- $this->session->machine->setExtraData(vboxconnector::phpVboxGroupKey, implode(',', $newGroups));
- } else {
- $this->session->machine->groups = $newGroups;
- }
-
- $this->session->machine->saveSettings();
- $this->session->unlockMachine();
-
- unset($this->session);
- $machine->releaseRemote();
-
- } catch (Exception $e) {
-
- $this->errors[] = $e;
- $response['errored'] = true;
-
- try {
- $this->session->unlockMachine();
- unset($this->session);
- } catch (Exception $e) {
- // pass
- }
-
- continue;
-
- }
-
- // Add to saved list
- $response['saved'][] = $vm['id'];
-
- }
-
-
- return $response;
-
-
- }
-
-
- /**
- * Clone a virtual machine
- *
- * @param array $args array of arguments. See function body for details.
- * @return array response data
- */
- public function remote_machineClone($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- /* @var $src IMachine */
- $src = $this->vbox->findMachine($args['src']);
-
- if($args['snapshot'] && $args['snapshot']['id']) {
- /* @var $nsrc ISnapshot */
- $nsrc = $src->findSnapshot($args['snapshot']['id']);
- $src->releaseRemote();
- $src = null;
- $src = $nsrc->machine;
- }
- /* @var $m IMachine */
- $m = $this->vbox->createMachine($this->vbox->composeMachineFilename($args['name'],null,null,null),$args['name'],null,null,null,false);
- $sfpath = $m->settingsFilePath;
-
- /* @var $cm CloneMode */
- $cm = new CloneMode(null,$args['vmState']);
- $state = $cm->ValueMap[$args['vmState']];
-
-
- $opts = array();
- if(!$args['reinitNetwork']) $opts[] = 'KeepAllMACs';
- if($args['link']) $opts[] = 'Link';
-
- /* @var $progress IProgress */
- $progress = $src->cloneTo($m->handle,$args['vmState'],$opts);
-
- // Does an exception exist?
- try {
- if($progress->errorInfo->handle) {
- $this->errors[] = new Exception($progress->errorInfo->text);
- $progress->releaseRemote();
- return false;
- }
- } catch (Exception $null) {}
-
- $m->releaseRemote();
- $src->releaseRemote();
-
- $this->_util_progressStore($progress);
-
- return array(
- 'progress' => $progress->handle,
- 'settingsFilePath' => $sfpath);
-
- }
-
-
- /**
- * Turn VRDE on / off on a running VM
- *
- * @param array $args array of arguments. See function body for details.
- * @return boolean true on success
- */
- public function remote_consoleVRDEServerSave($args) {
-
- $this->connect();
-
- // create session and lock machine
- /* @var $m IMachine */
- $m = $this->vbox->findMachine($args['vm']);
- $this->session = $this->websessionManager->getSessionObject($this->vbox->handle);
- $m->lockMachine($this->session->handle, 'Shared');
-
- if(intval($args['enabled']) == -1) {
- $args['enabled'] = intval(!$this->session->machine->VRDEServer->enabled);
- }
-
- $this->session->machine->VRDEServer->enabled = intval($args['enabled']);
-
- $this->session->unlockMachine();
- unset($this->session);
-
- $m->releaseRemote();
-
- return true;
- }
-
- /**
- * Save running VM settings. Called from machineSave method if the requested VM is running.
- *
- * @param array $args array of machine configuration items.
- * @param string $state state of virtual machine.
- * @return boolean true on success
- */
- private function _machineSaveRunning($args, $state) {
-
- // Client and server must agree on advanced config setting
- $this->settings->enableAdvancedConfig = (@$this->settings->enableAdvancedConfig && @$args['clientConfig']['enableAdvancedConfig']);
- $this->settings->enableHDFlushConfig = (@$this->settings->enableHDFlushConfig && @$args['clientConfig']['enableHDFlushConfig']);
-
- // Shorthand
- /* @var $m IMachine */
- $m = &$this->session->machine;
-
- $m->CPUExecutionCap = $args['CPUExecutionCap'];
- $m->description = $args['description'];
-
- // Start / stop config
- if(@$this->settings->startStopConfig) {
- $m->setExtraData('pvbx/startupMode', $args['startupMode']);
- }
-
- // VirtualBox style start / stop config
- if(@$this->settings->vboxAutostartConfig && @$args['clientConfig']['vboxAutostartConfig']) {
-
- $m->autostopType = $args['autostopType'];
- $m->autostartEnabled = $args['autostartEnabled'];
- $m->autostartDelay = $args['autostartDelay'];
-
- }
-
- // Custom Icon
- if(@$this->settings->enableCustomIcons) {
- $m->setExtraData('phpvb/icon', $args['customIcon']);
- }
-
- // VRDE settings
- try {
- if($m->VRDEServer && $this->vbox->systemProperties->defaultVRDEExtPack) {
- $m->VRDEServer->enabled = $args['VRDEServer']['enabled'];
- $m->VRDEServer->setVRDEProperty('TCP/Ports',$args['VRDEServer']['ports']);
- $m->VRDEServer->setVRDEProperty('VNCPassword',$args['VRDEServer']['VNCPassword'] ? $args['VRDEServer']['VNCPassword'] : null);
- $m->VRDEServer->authType = ($args['VRDEServer']['authType'] ? $args['VRDEServer']['authType'] : null);
- $m->VRDEServer->authTimeout = $args['VRDEServer']['authTimeout'];
- }
- } catch (Exception $e) {
- }
-
- // Storage Controllers if machine is in a valid state
- if($state != 'Saved') {
-
- $scs = $m->storageControllers;
- $attachedEx = $attachedNew = array();
- foreach($scs as $sc) { /* @var $sc IStorageController */
- $mas = $m->getMediumAttachmentsOfController($sc->name);
- foreach($mas as $ma) { /* @var $ma IMediumAttachment */
- $attachedEx[$sc->name.$ma->port.$ma->device] = (($ma->medium->handle && $ma->medium->id) ? $ma->medium->id : null);
- }
- }
-
- // Incoming list
- foreach($args['storageControllers'] as $sc) {
-
- $sc['name'] = trim($sc['name']);
- $name = ($sc['name'] ? $sc['name'] : $sc['bus']);
-
- // Medium attachments
- foreach($sc['mediumAttachments'] as $ma) {
-
- if($ma['medium'] == 'null') $ma['medium'] = null;
-
- $attachedNew[$name.$ma['port'].$ma['device']] = $ma['medium']['id'];
-
- // Compare incoming list with existing
- if($ma['type'] != 'HardDisk' && $attachedNew[$name.$ma['port'].$ma['device']] != $attachedEx[$name.$ma['port'].$ma['device']]) {
-
- if(is_array($ma['medium']) && $ma['medium']['id'] && $ma['type']) {
-
- // Host drive
- if(strtolower($ma['medium']['hostDrive']) == 'true' || $ma['medium']['hostDrive'] === true) {
- // CD / DVD Drive
- if($ma['type'] == 'DVD') {
- $drives = $this->vbox->host->DVDDrives;
- // floppy drives
- } else {
- $drives = $this->vbox->host->floppyDrives;
- }
- foreach($drives as $md) {
- if($md->id == $ma['medium']['id']) {
- $med = &$md;
- break;
- }
- $md->releaseRemote();
- }
- } else {
- $med = $this->vbox->openMedium($ma['medium']['location'],$ma['type'],'ReadWrite',false);
- }
- } else {
- $med = null;
- }
- $m->mountMedium($name,$ma['port'],$ma['device'],(is_object($med) ? $med->handle : null),true);
- if(is_object($med)) $med->releaseRemote();
- }
-
- // Set Live CD/DVD
- if($ma['type'] == 'DVD') {
- if(!$ma['medium']['hostDrive'])
- $m->temporaryEjectDevice($name, $ma['port'], $ma['device'], $ma['temporaryEject']);
-
- // Set IgnoreFlush
- } elseif($ma['type'] == 'HardDisk') {
-
- // Remove IgnoreFlush key?
- if($this->settings->enableHDFlushConfig) {
-
- $xtra = $this->_util_getIgnoreFlushKey($ma['port'], $ma['device'], $sc['controllerType']);
-
- if($xtra) {
- if((bool)($ma['ignoreFlush'])) {
- $m->setExtraData($xtra, '0');
- } else {
- $m->setExtraData($xtra, '');
- }
- }
- }
-
-
- }
- }
-
- }
- }
-
-
- /* Networking */
- $netprops = array('enabled','attachmentType','bridgedInterface','hostOnlyInterface','internalNetwork','NATNetwork','promiscModePolicy','genericDriver');
- if(@$this->settings->enableVDE) $netprops[] = 'VDENetwork';
-
- for($i = 0; $i < count($args['networkAdapters']); $i++) {
-
- /* @var $n INetworkAdapter */
- $n = $m->getNetworkAdapter($i);
-
- // Skip disabled adapters
- if(!$n->enabled) {
- $n->releaseRemote();
- continue;
- }
-
- for($p = 0; $p < count($netprops); $p++) {
- switch($netprops[$p]) {
- case 'enabled':
- case 'cableConnected':
- break;
- default:
- if((string)$n->{$netprops[$p]} != (string)$args['networkAdapters'][$i][$netprops[$p]])
- $n->{$netprops[$p]} = $args['networkAdapters'][$i][$netprops[$p]];
- }
- }
-
- /// Not if in "Saved" state
- if($state != 'Saved') {
-
- // Network properties
- $eprops = $n->getProperties(null);
- $eprops = array_combine($eprops[1],$eprops[0]);
- $iprops = array_map(function($a){$b=explode("=",$a); return array($b[0]=>$b[1]);},preg_split('/[\r|\n]+/',$args['networkAdapters'][$i]['properties']));
- $inprops = array();
- foreach($iprops as $a) {
- foreach($a as $k=>$v)
- $inprops[$k] = $v;
- }
-
- // Remove any props that are in the existing properties array
- // but not in the incoming properties array
- foreach(array_diff(array_keys($eprops),array_keys($inprops)) as $dk) {
- $n->setProperty($dk, '');
- }
-
- // Set remaining properties
- foreach($inprops as $k => $v) {
- if(!$k) continue;
- $n->setProperty($k, $v);
- }
-
- if($n->cableConnected != $args['networkAdapters'][$i]['cableConnected'])
- $n->cableConnected = $args['networkAdapters'][$i]['cableConnected'];
-
- }
-
- if($args['networkAdapters'][$i]['attachmentType'] == 'NAT') {
-
- // Remove existing redirects
- foreach($n->NATEngine->getRedirects() as $r) {
- $n->NATEngine->removeRedirect(array_shift(explode(',',$r)));
- }
- // Add redirects
- foreach($args['networkAdapters'][$i]['redirects'] as $r) {
- $r = explode(',',$r);
- $n->NATEngine->addRedirect($r[0],$r[1],$r[2],$r[3],$r[4],$r[5]);
- }
-
- // Advanced NAT settings
- if($state != 'Saved' && @$this->settings->enableAdvancedConfig) {
- $aliasMode = $n->NATEngine->aliasMode & 1;
- if(intval($args['networkAdapters'][$i]['NATEngine']['aliasMode'] & 2)) $aliasMode |= 2;
- if(intval($args['networkAdapters'][$i]['NATEngine']['aliasMode'] & 4)) $aliasMode |= 4;
- $n->NATEngine->aliasMode = $aliasMode;
- $n->NATEngine->DNSProxy = $args['networkAdapters'][$i]['NATEngine']['DNSProxy'];
- $n->NATEngine->DNSPassDomain = $args['networkAdapters'][$i]['NATEngine']['DNSPassDomain'];
- $n->NATEngine->DNSUseHostResolver = $args['networkAdapters'][$i]['NATEngine']['DNSUseHostResolver'];
- $n->NATEngine->hostIP = $args['networkAdapters'][$i]['NATEngine']['hostIP'];
- }
-
- } else if($args['networkAdapters'][$i]['attachmentType'] == 'NATNetwork') {
-
- if($n->NATNetwork = $args['networkAdapters'][$i]['NATNetwork']);
- }
-
- $n->releaseRemote();
-
- }
-
- /* Shared Folders */
- $sf_inc = array();
- foreach($args['sharedFolders'] as $s) {
- $sf_inc[$s['name']] = $s;
- }
-
-
- // Get list of perm shared folders
- $psf_tmp = $m->sharedFolders;
- $psf = array();
- foreach($psf_tmp as $sf) {
- $psf[$sf->name] = $sf;
- }
-
- // Get a list of temp shared folders
- $tsf_tmp = $this->session->console->sharedFolders;
- $tsf = array();
- foreach($tsf_tmp as $sf) {
- $tsf[$sf->name] = $sf;
- }
-
- /*
- * Step through list and remove non-matching folders
- */
- foreach($sf_inc as $sf) {
-
- // Already exists in perm list. Check Settings.
- if($sf['type'] == 'machine' && $psf[$sf['name']]) {
-
- /* Remove if it doesn't match */
- if($sf['hostPath'] != $psf[$sf['name']]->hostPath || (bool)$sf['autoMount'] != (bool)$psf[$sf['name']]->autoMount || (bool)$sf['writable'] != (bool)$psf[$sf['name']]->writable) {
-
- $m->removeSharedFolder($sf['name']);
- $m->createSharedFolder($sf['name'],$sf['hostPath'],(bool)$sf['writable'],(bool)$sf['autoMount']);
- }
-
- unset($psf[$sf['name']]);
-
- // Already exists in perm list. Check Settings.
- } else if($sf['type'] != 'machine' && $tsf[$sf['name']]) {
-
- /* Remove if it doesn't match */
- if($sf['hostPath'] != $tsf[$sf['name']]->hostPath || (bool)$sf['autoMount'] != (bool)$tsf[$sf['name']]->autoMount || (bool)$sf['writable'] != (bool)$tsf[$sf['name']]->writable) {
-
- $this->session->console->removeSharedFolder($sf['name']);
- $this->session->console->createSharedFolder($sf['name'],$sf['hostPath'],(bool)$sf['writable'],(bool)$sf['autoMount']);
-
- }
-
- unset($tsf[$sf['name']]);
-
- } else {
-
- // Does not exist or was removed. Add it.
- if($sf['type'] != 'machine') $this->session->console->createSharedFolder($sf['name'],$sf['hostPath'],(bool)$sf['writable'],(bool)$sf['autoMount']);
- else $this->session->machine->createSharedFolder($sf['name'],$sf['hostPath'],(bool)$sf['writable'],(bool)$sf['autoMount']);
- }
-
- }
-
- /*
- * Remove remaining
- */
- foreach($psf as $sf) $m->removeSharedFolder($sf->name);
- foreach($tsf as $sf) $this->session->console->removeSharedFolder($sf->name);
-
- /*
- * USB Filters
- */
-
- $usbEx = array();
- $usbNew = array();
-
- $usbc = $this->_machineGetUSBControllers($this->session->machine);
-
- $deviceFilters = $this->_machineGetUSBDeviceFilters($this->session->machine);
-
- if($state != 'Saved') {
-
- // filters
- if(!is_array($args['USBDeviceFilters'])) $args['USBDeviceFilters'] = array();
-
- if(count($deviceFilters) != count($args['USBDeviceFilters']) || @serialize($deviceFilters) != @serialize($args['USBDeviceFilters'])) {
-
- // usb filter properties to change
- $usbProps = array('vendorId','productId','revision','manufacturer','product','serialNumber','port','remote');
-
- // Remove and Add filters
- try {
-
-
- $max = max(count($deviceFilters),count($args['USBDeviceFilters']));
- $offset = 0;
-
- // Remove existing
- for($i = 0; $i < $max; $i++) {
-
- // Only if filter differs
- if(@serialize($deviceFilters[$i]) != @serialize($args['USBDeviceFilters'][$i])) {
-
- // Remove existing?
- if($i < count($deviceFilters)) {
- $m->USBDeviceFilters->removeDeviceFilter(($i-$offset));
- $offset++;
- }
-
- // Exists in new?
- if(count($args['USBDeviceFilters'][$i])) {
-
- // Create filter
- $f = $m->USBDeviceFilters->createDeviceFilter($args['USBDeviceFilters'][$i]['name']);
- $f->active = (bool)$args['USBDeviceFilters'][$i]['active'];
-
- foreach($usbProps as $p) {
- $f->$p = $args['USBDeviceFilters'][$i][$p];
- }
-
- $m->USBDeviceFilters->insertDeviceFilter($i,$f->handle);
- $f->releaseRemote();
- $offset--;
- }
- }
-
- }
-
- } catch (Exception $e) { $this->errors[] = $e; }
-
- }
-
- }
-
-
- $this->session->machine->saveSettings();
- $this->session->unlockMachine();
- unset($this->session);
- $m->releaseRemote();
-
- return true;
-
- }
-
- /**
- * Save virtual machine settings.
- *
- * @param array $args array of arguments. See function body for details.
- * @return boolean true on success
- */
- public function remote_machineSave($args) {
-
- $this->connect();
-
- // create session and lock machine
- /* @var $machine IMachine */
- $machine = $this->vbox->findMachine($args['id']);
-
- $vmState = (string)$machine->state;
- $vmRunning = ($vmState == 'Running' || $vmState == 'Paused' || $vmState == 'Saved');
- $this->session = $this->websessionManager->getSessionObject($this->vbox->handle);
- $machine->lockMachine($this->session->handle, ($vmRunning ? 'Shared' : 'Write'));
-
- // Switch to machineSaveRunning()?
- if($vmRunning) {
- return $this->_machineSaveRunning($args, $vmState);
- }
-
-
- // Client and server must agree on advanced config setting
- $this->settings->enableAdvancedConfig = (@$this->settings->enableAdvancedConfig && @$args['clientConfig']['enableAdvancedConfig']);
- $this->settings->enableHDFlushConfig = (@$this->settings->enableHDFlushConfig && @$args['clientConfig']['enableHDFlushConfig']);
-
- // Shorthand
- /* @var $m IMachine */
- $m = $this->session->machine;
-
- // General machine settings
- if (@$this->settings->enforceVMOwnership ) {
-
- $args['name'] = "{$_SESSION['user']}_" . preg_replace('/^' . preg_quote($_SESSION['user']) . '_/', '', $args['name']);
-
- if ( ($owner = $machine->getExtraData("phpvb/sso/owner")) && $owner !== $_SESSION['user'] && !$_SESSION['admin'] )
- {
- // skip this VM as it is not owned by the user we're logged in as
- throw new Exception("Not authorized to modify this VM");
- }
-
- }
-
- // Change OS type and update LongMode
- if(strcasecmp($m->OSTypeId,$args['OSTypeId']) != 0) {
-
- $m->OSTypeId = $args['OSTypeId'];
-
- $guestOS = $this->vbox->getGuestOSType($args['OSTypeId']);
-
- $m->setCPUProperty('LongMode', ($guestOS->is64Bit ? 1 : 0));
- }
-
- $m->CPUCount = $args['CPUCount'];
- $m->memorySize = $args['memorySize'];
- $m->firmwareType = $args['firmwareType'];
- if($args['chipsetType']) $m->chipsetType = $args['chipsetType'];
- if($m->snapshotFolder != $args['snapshotFolder']) $m->snapshotFolder = $args['snapshotFolder'];
- $m->RTCUseUTC = ($args['RTCUseUTC'] ? 1 : 0);
- $m->setCpuProperty('PAE', ($args['CpuProperties']['PAE'] ? 1 : 0));
- $m->setCPUProperty('LongMode', (strpos($args['OSTypeId'],'_64') > - 1 ? 1 : 0));
-
- // IOAPIC
- $m->BIOSSettings->IOAPICEnabled = ($args['BIOSSettings']['IOAPICEnabled'] ? 1 : 0);
- $m->CPUExecutionCap = $args['CPUExecutionCap'];
- $m->description = $args['description'];
-
- // Start / stop config
- if(@$this->settings->startStopConfig) {
- $m->setExtraData('pvbx/startupMode', $args['startupMode']);
- }
-
-
- // VirtualBox style start / stop config
- if(@$this->settings->vboxAutostartConfig && @$args['clientConfig']['vboxAutostartConfig']) {
-
- $m->autostopType = $args['autostopType'];
- $m->autostartEnabled = $args['autostartEnabled'];
- $m->autostartDelay = $args['autostartDelay'];
-
- }
-
- // Determine if host is capable of hw accel
- $hwAccelAvail = $this->vbox->host->getProcessorFeature('HWVirtEx');
-
- $m->paravirtProvider = $args['paravirtProvider'];
- $m->setHWVirtExProperty('Enabled', $args['HWVirtExProperties']['Enabled']);
- $m->setHWVirtExProperty('NestedPaging', ($args['HWVirtExProperties']['Enabled'] && $hwAccelAvail && $args['HWVirtExProperties']['NestedPaging']));
-
- /* Only if advanced configuration is enabled */
- if(@$this->settings->enableAdvancedConfig) {
-
- /** @def VBOX_WITH_PAGE_SHARING
- * Enables the page sharing code.
- * @remarks This must match GMMR0Init; currently we only support page fusion on
- * all 64-bit hosts except Mac OS X */
-
- if($this->vbox->host->getProcessorFeature('LongMode')) {
-
- $m->pageFusionEnabled = $args['pageFusionEnabled'];
- }
-
- $m->HPETEnabled = $args['HPETEnabled'];
- $m->setExtraData("VBoxInternal/Devices/VMMDev/0/Config/GetHostTimeDisabled", $args['disableHostTimeSync']);
- $m->keyboardHIDType = $args['keyboardHIDType'];
- $m->pointingHIDType = $args['pointingHIDType'];
- $m->setHWVirtExProperty('LargePages', $args['HWVirtExProperties']['LargePages']);
- $m->setHWVirtExProperty('UnrestrictedExecution', $args['HWVirtExProperties']['UnrestrictedExecution']);
- $m->setHWVirtExProperty('VPID', $args['HWVirtExProperties']['VPID']);
-
- }
-
- /* Custom Icon */
- if(@$this->settings->enableCustomIcons)
- $m->setExtraData('phpvb/icon', $args['customIcon']);
-
- $m->VRAMSize = $args['VRAMSize'];
-
- // Video
- $m->accelerate3DEnabled = $args['accelerate3DEnabled'];
- $m->accelerate2DVideoEnabled = $args['accelerate2DVideoEnabled'];
-
- // VRDE settings
- try {
- if($m->VRDEServer && $this->vbox->systemProperties->defaultVRDEExtPack) {
- $m->VRDEServer->enabled = $args['VRDEServer']['enabled'];
- $m->VRDEServer->setVRDEProperty('TCP/Ports',$args['VRDEServer']['ports']);
- if(@$this->settings->enableAdvancedConfig)
- $m->VRDEServer->setVRDEProperty('TCP/Address',$args['VRDEServer']['netAddress']);
- $m->VRDEServer->setVRDEProperty('VNCPassword',$args['VRDEServer']['VNCPassword'] ? $args['VRDEServer']['VNCPassword'] : null);
- $m->VRDEServer->authType = ($args['VRDEServer']['authType'] ? $args['VRDEServer']['authType'] : null);
- $m->VRDEServer->authTimeout = $args['VRDEServer']['authTimeout'];
- $m->VRDEServer->allowMultiConnection = $args['VRDEServer']['allowMultiConnection'];
- }
- } catch (Exception $e) {
- }
-
- // Audio controller settings
- $m->audioAdapter->enabled = ($args['audioAdapter']['enabled'] ? 1 : 0);
- $m->audioAdapter->audioController = $args['audioAdapter']['audioController'];
- $m->audioAdapter->audioDriver = $args['audioAdapter']['audioDriver'];
-
- // Boot order
- $mbp = $this->vbox->systemProperties->maxBootPosition;
- for($i = 0; $i < $mbp; $i ++) {
- if($args['bootOrder'][$i]) {
- $m->setBootOrder(($i + 1),$args['bootOrder'][$i]);
- } else {
- $m->setBootOrder(($i + 1),'Null');
- }
- }
-
- // Storage Controllers
- $scs = $m->storageControllers;
- $attachedEx = $attachedNew = array();
- foreach($scs as $sc) { /* @var $sc IStorageController */
-
- $mas = $m->getMediumAttachmentsOfController($sc->name);
-
- $cType = (string)$sc->controllerType;
-
- foreach($mas as $ma) { /* @var $ma IMediumAttachment */
-
- $attachedEx[$sc->name.$ma->port.$ma->device] = (($ma->medium->handle && $ma->medium->id) ? $ma->medium->id : null);
-
- // Remove IgnoreFlush key?
- if($this->settings->enableHDFlushConfig && (string)$ma->type == 'HardDisk') {
- $xtra = $this->_util_getIgnoreFlushKey($ma->port, $ma->device, $cType);
- if($xtra) {
- $m->setExtraData($xtra,'');
- }
- }
-
- if($ma->controller) {
- $m->detachDevice($ma->controller,$ma->port,$ma->device);
- }
-
- }
- $scname = $sc->name;
- $sc->releaseRemote();
- $m->removeStorageController($scname);
- }
-
- // Add New
- foreach($args['storageControllers'] as $sc) {
-
- $sc['name'] = trim($sc['name']);
- $name = ($sc['name'] ? $sc['name'] : $sc['bus']);
-
-
- $bust = new StorageBus(null,$sc['bus']);
- $c = $m->addStorageController($name,(string)$bust);
- $c->controllerType = $sc['controllerType'];
- $c->useHostIOCache = $sc['useHostIOCache'];
-
- // Set sata port count
- if($sc['bus'] == 'SATA') {
- $max = max(1,intval(@$sc['portCount']));
- foreach($sc['mediumAttachments'] as $ma) {
- $max = max($max,(intval($ma['port'])+1));
- }
- $c->portCount = min(intval($c->maxPortCount),max(count($sc['mediumAttachments']),$max));
-
- }
- $c->releaseRemote();
-
-
- // Medium attachments
- foreach($sc['mediumAttachments'] as $ma) {
-
- if($ma['medium'] == 'null') $ma['medium'] = null;
-
- $attachedNew[$name.$ma['port'].$ma['device']] = $ma['medium']['id'];
-
- if(is_array($ma['medium']) && $ma['medium']['id'] && $ma['type']) {
-
- // Host drive
- if(strtolower($ma['medium']['hostDrive']) == 'true' || $ma['medium']['hostDrive'] === true) {
- // CD / DVD Drive
- if($ma['type'] == 'DVD') {
- $drives = $this->vbox->host->DVDDrives;
- // floppy drives
- } else {
- $drives = $this->vbox->host->floppyDrives;
- }
- foreach($drives as $md) { /* @var $md IMedium */
- if($md->id == $ma['medium']['id']) {
- $med = &$md;
- break;
- }
- $md->releaseRemote();
- }
- } else {
- /* @var $med IMedium */
- $med = $this->vbox->openMedium($ma['medium']['location'],$ma['type'], 'ReadWrite', false);
- }
- } else {
- $med = null;
- }
- $m->attachDevice($name,$ma['port'],$ma['device'],$ma['type'],(is_object($med) ? $med->handle : null));
-
- // CD / DVD medium attachment type
- if($ma['type'] == 'DVD') {
-
- if($ma['medium']['hostDrive'])
- $m->passthroughDevice($name, $ma['port'], $ma['device'], $ma['passthrough']);
- else
- $m->temporaryEjectDevice($name, $ma['port'], $ma['device'], $ma['temporaryEject']);
-
- // HardDisk medium attachment type
- } else if($ma['type'] == 'HardDisk') {
-
- $m->nonRotationalDevice($name, $ma['port'], $ma['device'], $ma['nonRotational']);
-
- // Remove IgnoreFlush key?
- if($this->settings->enableHDFlushConfig) {
-
- $xtra = $this->_util_getIgnoreFlushKey($ma['port'], $ma['device'], $sc['controllerType']);
-
- if($xtra) {
- if($ma['ignoreFlush']) {
- $m->setExtraData($xtra, '');
- } else {
- $m->setExtraData($xtra, 0);
- }
- }
- }
-
-
- }
-
- if($sc['bus'] == 'SATA' || $sc['bus'] == 'USB') {
- $m->setHotPluggableForDevice($name, $ma['port'], $ma['device'], $ma['hotPluggable']);
- }
-
- if(is_object($med))
- $med->releaseRemote();
- }
-
- }
-
- /*
- *
- * Network Adapters
- *
- */
-
- $netprops = array('enabled','attachmentType','adapterType','MACAddress','bridgedInterface',
- 'hostOnlyInterface','internalNetwork','NATNetwork','cableConnected','promiscModePolicy','genericDriver');
-
- for($i = 0; $i < count($args['networkAdapters']); $i++) {
- if(@$this->settings->enableVDE) $netprops[] = 'VDENetwork';
-
- $n = $m->getNetworkAdapter($i);
-
- // Skip disabled adapters
- if(!($n->enabled || @$args['networkAdapters'][$i]['enabled']))
- continue;
-
- for($p = 0; $p < count($netprops); $p++) {
- /*
- switch($netprops[$p]) {
- case 'enabled':
- case 'cableConnected':
- continue;
- }
- */
- $n->{$netprops[$p]} = @$args['networkAdapters'][$i][$netprops[$p]];
- }
-
- // Special case for boolean values
- /*
- $n->enabled = $args['networkAdapters'][$i]['enabled'];
- $n->cableConnected = $args['networkAdapters'][$i]['cableConnected'];
- */
-
- // Network properties
- $eprops = $n->getProperties(null);
- $eprops = array_combine($eprops[1],$eprops[0]);
- $iprops = array_map(function($a){$b=explode("=",$a); return array($b[0]=>$b[1]);},preg_split('/[\r|\n]+/',$args['networkAdapters'][$i]['properties']));
- $inprops = array();
- foreach($iprops as $a) {
- foreach($a as $k=>$v)
- $inprops[$k] = $v;
- }
- // Remove any props that are in the existing properties array
- // but not in the incoming properties array
- foreach(array_diff(array_keys($eprops),array_keys($inprops)) as $dk)
- $n->setProperty($dk, '');
-
- // Set remaining properties
- foreach($inprops as $k => $v)
- $n->setProperty($k, $v);
-
- // Nat redirects and advanced settings
- if($args['networkAdapters'][$i]['attachmentType'] == 'NAT') {
-
- // Remove existing redirects
- foreach($n->NATEngine->getRedirects() as $r) {
- $n->NATEngine->removeRedirect(array_shift(explode(',',$r)));
- }
- // Add redirects
- foreach($args['networkAdapters'][$i]['redirects'] as $r) {
- $r = explode(',',$r);
- $n->NATEngine->addRedirect($r[0],$r[1],$r[2],$r[3],$r[4],$r[5]);
- }
-
- // Advanced NAT settings
- if(@$this->settings->enableAdvancedConfig) {
- $aliasMode = $n->NATEngine->aliasMode & 1;
- if(intval($args['networkAdapters'][$i]['NATEngine']['aliasMode'] & 2)) $aliasMode |= 2;
- if(intval($args['networkAdapters'][$i]['NATEngine']['aliasMode'] & 4)) $aliasMode |= 4;
- $n->NATEngine->aliasMode = $aliasMode;
- $n->NATEngine->DNSProxy = $args['networkAdapters'][$i]['NATEngine']['DNSProxy'];
- $n->NATEngine->DNSPassDomain = $args['networkAdapters'][$i]['NATEngine']['DNSPassDomain'];
- $n->NATEngine->DNSUseHostResolver = $args['networkAdapters'][$i]['NATEngine']['DNSUseHostResolver'];
- $n->NATEngine->hostIP = $args['networkAdapters'][$i]['NATEngine']['hostIP'];
- }
-
- } else if($args['networkAdapters'][$i]['attachmentType'] == 'NATNetwork') {
-
- if($n->NATNetwork = $args['networkAdapters'][$i]['NATNetwork']);
- }
-
- $n->releaseRemote();
- }
-
- // Serial Ports
- for($i = 0; $i < count($args['serialPorts']); $i++) {
-
- /* @var $p ISerialPort */
- $p = $m->getSerialPort($i);
-
- if(!($p->enabled || $args['serialPorts'][$i]['enabled']))
- continue;
-
- try {
- $p->enabled = $args['serialPorts'][$i]['enabled'];
- $p->IOBase = @hexdec($args['serialPorts'][$i]['IOBase']);
- $p->IRQ = intval($args['serialPorts'][$i]['IRQ']);
- if($args['serialPorts'][$i]['path']) {
- $p->path = $args['serialPorts'][$i]['path'];
- $p->hostMode = $args['serialPorts'][$i]['hostMode'];
- } else {
- $p->hostMode = $args['serialPorts'][$i]['hostMode'];
- $p->path = $args['serialPorts'][$i]['path'];
- }
- $p->server = $args['serialPorts'][$i]['server'];
- $p->releaseRemote();
- } catch (Exception $e) {
- $this->errors[] = $e;
- }
- }
-
- // LPT Ports
- if(@$this->settings->enableLPTConfig) {
- $lptChanged = false;
-
- for($i = 0; $i < count($args['parallelPorts']); $i++) {
-
- /* @var $p IParallelPort */
- $p = $m->getParallelPort($i);
-
- if(!($p->enabled || $args['parallelPorts'][$i]['enabled']))
- continue;
-
- $lptChanged = true;
- try {
- $p->IOBase = @hexdec($args['parallelPorts'][$i]['IOBase']);
- $p->IRQ = intval($args['parallelPorts'][$i]['IRQ']);
- $p->path = $args['parallelPorts'][$i]['path'];
- $p->enabled = $args['parallelPorts'][$i]['enabled'];
- $p->releaseRemote();
- } catch (Exception $e) {
- $this->errors[] = $e;
- }
- }
- }
-
-
- $sharedEx = array();
- $sharedNew = array();
- foreach($this->_machineGetSharedFolders($m) as $s) {
- $sharedEx[$s['name']] = array('name'=>$s['name'],'hostPath'=>$s['hostPath'],'autoMount'=>(bool)$s['autoMount'],'writable'=>(bool)$s['writable']);
- }
- foreach($args['sharedFolders'] as $s) {
- $sharedNew[$s['name']] = array('name'=>$s['name'],'hostPath'=>$s['hostPath'],'autoMount'=>(bool)$s['autoMount'],'writable'=>(bool)$s['writable']);
- }
- // Compare
- if(count($sharedEx) != count($sharedNew) || (@serialize($sharedEx) != @serialize($sharedNew))) {
- foreach($sharedEx as $s) { $m->removeSharedFolder($s['name']);}
- try {
- foreach($sharedNew as $s) {
- $m->createSharedFolder($s['name'],$s['hostPath'],(bool)$s['writable'],(bool)$s['autoMount']);
- }
- } catch (Exception $e) { $this->errors[] = $e; }
- }
-
- // USB Filters
-
- $usbEx = array();
- $usbNew = array();
-
- $usbc = $this->_machineGetUSBControllers($this->session->machine);
- if(!$args['USBControllers'] || !is_array($args['USBControllers'])) $args['USBControllers'] = array();
-
- // Remove old
- $newNames = array();
- $newByName = array();
- foreach($args['USBControllers'] as $c) {
- $newNames[] = $c['name'];
- $newByName[$c['name']] = $c;
- }
- $exNames = array();
- foreach($usbc as $c) {
- $exNames[] = $c['name'];
- if(in_array($c['name'], $newNames)) continue;
- $this->session->machine->removeUSBController($c['name']);
- }
-
- $addNames = array_diff($newNames, $exNames);
- foreach($addNames as $name) {
- $this->session->machine->addUSBController($name, $newByName[$name]['type']);
- }
-
- // filters
- $deviceFilters = $this->_machineGetUSBDeviceFilters($this->session->machine);
- if(!is_array($args['USBDeviceFilters'])) $args['USBDeviceFilters'] = array();
-
- if(count($deviceFilters) != count($args['USBDeviceFilters']) || @serialize($deviceFilters) != @serialize($args['USBDeviceFilters'])) {
-
- // usb filter properties to change
- $usbProps = array('vendorId','productId','revision','manufacturer','product','serialNumber','port','remote');
-
- // Remove and Add filters
- try {
-
-
- $max = max(count($deviceFilters),count($args['USBDeviceFilters']));
- $offset = 0;
-
- // Remove existing
- for($i = 0; $i < $max; $i++) {
-
- // Only if filter differs
- if(@serialize($deviceFilters[$i]) != @serialize($args['USBDeviceFilters'][$i])) {
-
- // Remove existing?
- if($i < count($deviceFilters)) {
- $m->USBDeviceFilters->removeDeviceFilter(($i-$offset));
- $offset++;
- }
-
- // Exists in new?
- if(count($args['USBDeviceFilters'][$i])) {
-
- // Create filter
- $f = $m->USBDeviceFilters->createDeviceFilter($args['USBDeviceFilters'][$i]['name']);
- $f->active = (bool)$args['USBDeviceFilters'][$i]['active'];
-
- foreach($usbProps as $p) {
- $f->$p = $args['USBDeviceFilters'][$i][$p];
- }
-
- $m->USBDeviceFilters->insertDeviceFilter($i,$f->handle);
- $f->releaseRemote();
- $offset--;
- }
- }
-
- }
-
- } catch (Exception $e) { $this->errors[] = $e; }
-
- }
-
- // Rename goes last
- if($m->name != $args['name']) {
- $m->name = $args['name'];
- }
- $this->session->machine->saveSettings();
-
-
- $this->session->unlockMachine();
- unset($this->session);
- $machine->releaseRemote();
-
- return true;
-
- }
-
- /**
- * Add a virtual machine via its settings file.
- *
- * @param array $args array of arguments. See function body for details.
- * @return boolean true on success
- */
- public function remote_machineAdd($args) {
-
- $this->connect();
-
-
- /* @var $m IMachine */
- $m = $this->vbox->openMachine($args['file']);
- $this->vbox->registerMachine($m->handle);
-
- $m->releaseRemote();
-
- return true;
-
- }
-
- /**
- * Get progress operation status. On completion, destory progress operation.
- *
- * @param array $args array of arguments. See function body for details.
- * @return array response data
- */
- public function remote_progressGet($args) {
-
- // progress operation result
- $response = array();
- $error = 0;
-
- // Connect to vboxwebsrv
- $this->connect();
-
- try {
-
- try {
-
- // Force web call to keep session open.
- if($this->persistentRequest['sessionHandle']) {
- $this->session = new ISession($this->client, $this->persistentRequest['sessionHandle']);
- if((string)$this->session->state) {}
- }
-
- /* @var $progress IProgress */
- $progress = new IProgress($this->client, $args['progress']);
-
- } catch (Exception $e) {
- $this->errors[] = $e;
- throw new Exception('Could not obtain progress operation: '.$args['progress']);
- }
-
- $response['progress'] = $args['progress'];
-
- $response['info'] = array(
- 'completed' => $progress->completed,
- 'canceled' => $progress->canceled,
- 'description' => $progress->description,
- 'operationDescription' => $progress->operationDescription,
- 'timeRemaining' => $this->_util_splitTime($progress->timeRemaining),
- 'timeElapsed' => $this->_util_splitTime((time() - $pop['started'])),
- 'percent' => $progress->percent
- );
-
-
- // Completed? Do not return. Fall to _util_progressDestroy() called later
- if($response['info']['completed'] || $response['info']['canceled']) {
-
- try {
- if(!$response['info']['canceled'] && $progress->errorInfo->handle) {
- $error = array('message'=>$progress->errorInfo->text,'err'=>$this->_util_resultCodeText($progress->resultCode));
- }
- } catch (Exception $null) {}
-
-
- } else {
-
- $response['info']['cancelable'] = $progress->cancelable;
-
- return $response;
- }
-
-
- } catch (Exception $e) {
-
- // Force progress dialog closure
- $response['info'] = array('completed'=>1);
-
- // Does an exception exist?
- try {
- if($progress->errorInfo->handle) {
- $error = array('message'=>$progress->errorInfo->text,'err'=>$this->_util_resultCodeText($progress->resultCode));
- }
- } catch (Exception $null) {}
-
- }
-
- if($error) {
- if(@$args['catcherrs']) $response['error'] = $error;
- else $this->errors[] = new Exception($error['message']);
-
- }
-
- $this->_util_progressDestroy($pop);
-
- return $response;
-
- }
-
- /**
- * Cancel a running progress operation
- *
- * @param array $args array of arguments. See function body for details.
- * @param array $response response data passed byref populated by the function
- * @return boolean true on success
- */
- public function remote_progressCancel($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- try {
- /* @var $progress IProgress */
- $progress = new IProgress($this->client,$args['progress']);
- if(!($progress->completed || $progress->canceled))
- $progress->cancel();
- } catch (Exception $e) {
- $this->errors[] = $e;
- }
-
- return true;
- }
-
- /**
- * Destory a progress operation.
- *
- * @param array $pop progress operation details
- * @return boolean true on success
- */
- private function _util_progressDestroy($pop) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- try {
- /* @var $progress IProgress */
- $progress = new IProgress($this->client,$pop['progress']);
- $progress->releaseRemote();
- } catch (Exception $e) {}
- try {
-
- // Close session and logoff
- try {
-
- if($this->session->handle) {
- if((string)$this->session->state != 'Unlocked') {
- $this->session->unlockMachine();
- }
- $this->session->releaseRemote();
- unset($this->session);
- }
-
-
- } catch (Exception $e) {
- $this->errors[] = $e;
- }
-
-
- // Logoff session associated with progress operation
- $this->websessionManager->logoff($this->vbox->handle);
- unset($this->vbox);
-
- } catch (Exception $e) {
- $this->errors[] = $e;
- }
-
- // Remove progress handles
- $this->persistentRequest = array();
-
- return true;
- }
-
- /**
- * Returns a key => value mapping of an enumeration class contained
- * in vboxServiceWrappers.php (classes that extend VBox_Enum).
- *
- * @param array $args array of arguments. See function body for details.
- * @return array response data
- * @see vboxServiceWrappers.php
- */
- public function remote_vboxGetEnumerationMap($args) {
-
- $c = new $args['class'](null, null);
- return (@isset($args['ValueMap']) ? $c->ValueMap : $c->NameMap);
- }
-
- /**
- * Save VirtualBox system properties
- *
- * @param array $args array of arguments. See function body for details.
- * @return boolean true on success
- */
- public function remote_vboxSystemPropertiesSave($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- $this->vbox->systemProperties->defaultMachineFolder = $args['SystemProperties']['defaultMachineFolder'];
- $this->vbox->systemProperties->VRDEAuthLibrary = $args['SystemProperties']['VRDEAuthLibrary'];
- if(@$this->settings->vboxAutostartConfig) {
- $this->vbox->systemProperties->autostartDatabasePath = $args['SystemProperties']['autostartDatabasePath'];
- }
-
- return true;
-
- }
-
- /**
- * Import a virtual appliance
- *
- * @param array $args array of arguments. See function body for details.
- * @return array response data
- */
- public function remote_applianceImport($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- /* @var $app IAppliance */
- $app = $this->vbox->createAppliance();
-
- /* @var $progress IProgress */
- $progress = $app->read($args['file']);
-
- // Does an exception exist?
- try {
- if($progress->errorInfo->handle) {
- $this->errors[] = new Exception($progress->errorInfo->text);
- $app->releaseRemote();
- return false;
- }
- } catch (Exception $null) {}
-
- $progress->waitForCompletion(-1);
-
- $app->interpret();
-
- $a = 0;
- foreach($app->virtualSystemDescriptions as $d) { /* @var $d IVirtualSystemDescription */
- // Replace with passed values
- $args['descriptions'][$a][5] = array_pad($args['descriptions'][$a][5], count($args['descriptions'][$a][3]),true);
- foreach(array_keys($args['descriptions'][$a][5]) as $k) $args['descriptions'][$a][5][$k] = (bool)$args['descriptions'][$a][5][$k];
- $d->setFinalValues($args['descriptions'][$a][5],$args['descriptions'][$a][3],$args['descriptions'][$a][4]);
- $a++;
- }
-
- /* @var $progress IProgress */
- $progress = $app->importMachines(array($args['reinitNetwork'] ? 'KeepNATMACs' : 'KeepAllMACs'));
-
- $app->releaseRemote();
-
- // Does an exception exist?
- try {
- if($progress->errorInfo->handle) {
- $this->errors[] = new Exception($progress->errorInfo->text);
- $progress->releaseRemote();
- return false;
- }
- } catch (Exception $null) {}
-
- // Save progress
- $this->_util_progressStore($progress);
-
- return array('progress' => $progress->handle);
-
- }
-
- /**
- * Get a list of VMs that are available for export.
- *
- * @param array $args array of arguments. See function body for details.
- * @return array list of exportable machiens
- */
- public function remote_vboxGetExportableMachines($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- //Get a list of registered machines
- $machines = $this->vbox->machines;
-
- $response = array();
-
- foreach ($machines as $machine) { /* @var $machine IMachine */
-
- if ( @$this->settings->enforceVMOwnership && ($owner = $machine->getExtraData("phpvb/sso/owner")) && $owner !== $_SESSION['user'] && !$_SESSION['admin'] )
- {
- // skip this VM as it is not owned by the user we're logged in as
- continue;
- }
-
- try {
- $response[] = array(
- 'name' => @$this->settings->enforceVMOwnership ? preg_replace('/^' . preg_quote($_SESSION['user']) . '_/', '', $machine->name) : $machine->name,
- 'state' => (string)$machine->state,
- 'OSTypeId' => $machine->getOSTypeId(),
- 'id' => $machine->id,
- 'description' => $machine->description
- );
- $machine->releaseRemote();
-
- } catch (Exception $e) {
- // Ignore. Probably inaccessible machine.
- }
- }
- return $response;
- }
-
-
- /**
- * Read and interpret virtual appliance file
- *
- * @param array $args array of arguments. See function body for details.
- * @return array appliance file content descriptions
- */
- public function remote_applianceReadInterpret($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- /* @var $app IAppliance */
- $app = $this->vbox->createAppliance();
-
- /* @var $progress IProgress */
- $progress = $app->read($args['file']);
-
- // Does an exception exist?
- try {
- if($progress->errorInfo->handle) {
- $this->errors[] = new Exception($progress->errorInfo->text);
- $app->releaseRemote();
- return false;
- }
- } catch (Exception $null) {}
-
- $progress->waitForCompletion(-1);
-
- $app->interpret();
-
- $response = array('warnings' => $app->getWarnings(),
- 'descriptions' => array());
-
- $i = 0;
- foreach($app->virtualSystemDescriptions as $d) { /* @var $d IVirtualSystemDescription */
- $desc = array();
- $response['descriptions'][$i] = $d->getDescription();
- foreach($response['descriptions'][$i][0] as $ddesc) {
- $desc[] = (string)$ddesc;
- }
- $response['descriptions'][$i][0] = $desc;
- $i++;
- $d->releaseRemote();
- }
- $app->releaseRemote();
- $app=null;
-
- return $response;
-
- }
-
-
- /**
- * Export VMs to a virtual appliance file
- *
- * @param array $args array of arguments. See function body for details.
- * @return array response data
- */
- public function remote_applianceExport($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- /* @var $app IAppliance */
- $app = $this->vbox->createAppliance();
-
- // Overwrite existing file?
- if($args['overwrite']) {
-
- $dsep = $this->getDsep();
-
- $path = str_replace($dsep.$dsep,$dsep,$args['file']);
- $dir = dirname($path);
- $file = basename($path);
-
- if(substr($dir,-1) != $dsep) $dir .= $dsep;
-
- /* @var $vfs IVFSExplorer */
- $vfs = $app->createVFSExplorer('file://'.$dir);
-
- /* @var $progress IProgress */
- $progress = $vfs->remove(array($file));
- $progress->waitForCompletion(-1);
- $progress->releaseRemote();
-
- $vfs->releaseRemote();
- }
-
- $appProps = array(
- 'name' => 'Name',
- 'description' => 'Description',
- 'product' => 'Product',
- 'vendor' => 'Vendor',
- 'version' => 'Version',
- 'product-url' => 'ProductUrl',
- 'vendor-url' => 'VendorUrl',
- 'license' => 'License');
-
-
- foreach($args['vms'] as $vm) {
-
- /* @var $m IMachine */
- $m = $this->vbox->findMachine($vm['id']);
- if (@$this->settings->enforceVMOwnership && ($owner = $m->getExtraData("phpvb/sso/owner")) && $owner !== $_SESSION['user'] && !$_SESSION['admin'] )
- {
- // skip this VM as it is not owned by the user we're logged in as
- continue;
- }
- $desc = $m->exportTo($app->handle, $args['file']);
- $props = $desc->getDescription();
- $ptypes = array();
- foreach($props[0] as $p) {$ptypes[] = (string)$p;}
- $typecount = 0;
- foreach($appProps as $k=>$v) {
- // Check for existing property
- if(($i=array_search($v,$ptypes)) !== false) {
- $props[3][$i] = $vm[$k];
- } else {
- $desc->addDescription($v,$vm[$k],null);
- $props[3][] = $vm[$k];
- $props[4][] = null;
- }
- $typecount++;
- }
- $enabled = array_pad(array(),count($props[3]),true);
- foreach(array_keys($enabled) as $k) $enabled[$k] = (bool)$enabled[$k];
- $desc->setFinalValues($enabled,$props[3],$props[4]);
- $desc->releaseRemote();
- $m->releaseRemote();
- }
-
- /* @var $progress IProgress */
- $progress = $app->write($args['format'],($args['manifest'] ? array('CreateManifest') : array()),$args['file']);
- $app->releaseRemote();
-
- // Does an exception exist?
- try {
- if($progress->errorInfo->handle) {
- $this->errors[] = new Exception($progress->errorInfo->text);
- $progress->releaseRemote();
- return false;
- }
- } catch (Exception $null) {}
-
- // Save progress
- $this->_util_progressStore($progress);
-
- return array('progress' => $progress->handle);
-
- }
-
- /**
- * Get nat network info
- *
- * @param unused $args
- * @param array $response response data passed byref populated by the function
- * @return array networking info data
- */
- public function remote_vboxNATNetworksGet($args) {
-
- $this->connect();
-
- $props = array('networkName','enabled','network','IPv6Enabled',
- 'advertiseDefaultIPv6RouteEnabled','needDhcpServer','portForwardRules4',
- 'portForwardRules6');
-
- $natNetworks = array();
-
- foreach($this->vbox->NATNetworks as $n) {
-
-
- $netDetails = array();
- foreach($props as $p) {
- $netDetails[$p] = $n->$p;
- }
-
- $natNetworks[] = $netDetails;
- }
-
- return $natNetworks;
-
- }
-
- /**
- * Get nat network details
- *
- * @param array $args contains network name
- * @param array $response response data passed byref populated by the function
- * @return array networking info data
- */
- public function remote_vboxNATNetworksSave($args) {
-
- $this->connect();
-
- $props = array('networkName','enabled','network','IPv6Enabled',
- 'advertiseDefaultIPv6RouteEnabled','needDhcpServer');
-
- $exNetworks = array();
- foreach($this->vbox->NATNetworks as $n) { $exNetworks[$n->networkName] = false; }
-
- /* Incoming network list */
- foreach($args['networks'] as $net) {
-
- /* Existing network */
- if($net['orig_networkName']) {
-
- $network = $this->vbox->findNATNetworkByName($net['orig_networkName']);
-
-
- $exNetworks[$net['orig_networkName']] = true;
-
- foreach($props as $p) {
- $network->$p = $net[$p];
- }
-
- foreach(array('portForwardRules4','portForwardRules6') as $rules) {
-
- if(!$net[$rules] || !is_array($net[$rules])) $net[$rules] = array();
-
- $rules_remove = array_diff($network->$rules, $net[$rules]);
- $rules_add = array_diff($net[$rules], $network->$rules);
-
- foreach($rules_remove as $rule) {
- $network->removePortForwardRule((strpos($rules,'6')>-1), array_shift(preg_split('/:/',$rule)));
- }
- foreach($rules_add as $r) {
- preg_match('/(.*?):(.+?):\[(.*?)\]:(\d+):\[(.*?)\]:(\d+)/', $r, $rule);
- array_shift($rule);
- $network->addPortForwardRule((strpos($rules,'6')>-1), $rule[0],strtoupper($rule[1]),$rule[2],$rule[3],$rule[4],$rule[5]);
- }
- }
-
- /* New network */
- } else {
-
- $network = $this->vbox->createNATNetwork($net['networkName']);
-
- foreach($props as $p) {
- if($p == 'network' && $net[$p] == '') continue;
- $network->$p = $net[$p];
- }
-
- foreach($net['portForwardRules4'] as $r) {
- preg_match('/(.*?):(.+?):\[(.*?)\]:(\d+):\[(.*?)\]:(\d+)/', $r, $rule);
- array_shift($rule);
- $network->addPortForwardRule(false, $rule[0],strtoupper($rule[1]),$rule[2],$rule[3],$rule[4],$rule[5]);
- }
- foreach($net['portForwardRules6'] as $r) {
- preg_match('/(.*?):(.+?):\[(.*?)\]:(\d+):\[(.*?)\]:(\d+)/', $r, $rule);
- array_shift($rule);
- $network->addPortForwardRule(true, $rule[0],strtoupper($rule[1]),$rule[2],$rule[3],$rule[4],$rule[5]);
- }
-
- }
-
- }
-
- /* Remove networks not in list */
- foreach($exNetworks as $n=>$v) {
- if($v) continue;
- $n = $this->vbox->findNATNetworkByName($n);
- $this->vbox->removeNATNetwork($n);
- }
-
- return true;
-
- }
-
- /**
- * Get networking info
- *
- * @param unused $args
- * @param array $response response data passed byref populated by the function
- * @return array networking info data
- */
- public function remote_getNetworking($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- $response = array();
- $networks = array();
- $nics = array();
- $genericDrivers = array();
- $vdenetworks = array();
-
- /* Get host nics */
- foreach($this->vbox->host->networkInterfaces as $d) { /* @var $d IHostNetworkInterface */
- $nics[] = $d->name;
- $d->releaseRemote();
- }
-
- /* Get internal Networks */
- $networks = $this->vbox->internalNetworks;
- /* Generic Drivers */
- $genericDrivers = $this->vbox->genericNetworkDrivers;
-
- $natNetworks = array();
- foreach($this->vbox->NATNetworks as $n) {
- $natNetworks[] = $n->networkName;
- }
-
- return array(
- 'nics' => $nics,
- 'networks' => $networks,
- 'genericDrivers' => $genericDrivers,
- 'vdenetworks' => $vdenetworks,
- 'natNetworks' => $natNetworks
- );
-
- }
-
- /**
- * Get host-only interface information
- *
- * @param unused $args
- * @return array host only interface data
- */
- public function remote_hostOnlyInterfacesGet($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- /*
- * NICs
- */
- $response = array('networkInterfaces' => array());
- foreach($this->vbox->host->networkInterfaces as $d) { /* @var $d IHostNetworkInterface */
-
- if((string)$d->interfaceType != 'HostOnly') {
- $d->releaseRemote();
- continue;
- }
-
-
- // Get DHCP Info
- try {
- /* @var $dhcp IDHCPServer */
- $dhcp = $this->vbox->findDHCPServerByNetworkName($d->networkName);
- if($dhcp->handle) {
- $dhcpserver = array(
- 'enabled' => $dhcp->enabled,
- 'IPAddress' => $dhcp->IPAddress,
- 'networkMask' => $dhcp->networkMask,
- 'networkName' => $dhcp->networkName,
- 'lowerIP' => $dhcp->lowerIP,
- 'upperIP' => $dhcp->upperIP
- );
- $dhcp->releaseRemote();
- } else {
- $dhcpserver = array();
- }
- } catch (Exception $e) {
- $dhcpserver = array();
- }
-
- $response['networkInterfaces'][] = array(
- 'id' => $d->id,
- 'IPV6Supported' => $d->IPV6Supported,
- 'name' => $d->name,
- 'IPAddress' => $d->IPAddress,
- 'networkMask' => $d->networkMask,
- 'IPV6Address' => $d->IPV6Address,
- 'IPV6NetworkMaskPrefixLength' => $d->IPV6NetworkMaskPrefixLength,
- 'DHCPEnabled' => $d->DHCPEnabled,
- 'networkName' => $d->networkName,
- 'dhcpServer' => $dhcpserver
- );
- $d->releaseRemote();
- }
-
- return $response;
- }
-
-
- /**
- * Save host-only interface information
- *
- * @param array $args array of arguments. See function body for details.
- * @return boolean true on success
- */
- public function remote_hostOnlyInterfacesSave($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- $nics = $args['networkInterfaces'];
-
- for($i = 0; $i < count($nics); $i++) {
-
- /* @var $nic IHostNetworkInterface */
- $nic = $this->vbox->host->findHostNetworkInterfaceById($nics[$i]['id']);
-
- // Common settings
- if($nic->IPAddress != $nics[$i]['IPAddress'] || $nic->networkMask != $nics[$i]['networkMask']) {
- $nic->enableStaticIPConfig($nics[$i]['IPAddress'],$nics[$i]['networkMask']);
- }
- if($nics[$i]['IPV6Supported'] &&
- ($nic->IPV6Address != $nics[$i]['IPV6Address'] || $nic->IPV6NetworkMaskPrefixLength != $nics[$i]['IPV6NetworkMaskPrefixLength'])) {
- $nic->enableStaticIPConfigV6($nics[$i]['IPV6Address'],intval($nics[$i]['IPV6NetworkMaskPrefixLength']));
- }
-
- // Get DHCP Info
- try {
- $dhcp = $this->vbox->findDHCPServerByNetworkName($nic->networkName);
- } catch (Exception $e) {$dhcp = null;};
-
- // Create DHCP server?
- if((bool)@$nics[$i]['dhcpServer']['enabled'] && !$dhcp) {
- $dhcp = $this->vbox->createDHCPServer($nic->networkName);
- }
- if($dhcp->handle) {
- $dhcp->enabled = @$nics[$i]['dhcpServer']['enabled'];
- $dhcp->setConfiguration($nics[$i]['dhcpServer']['IPAddress'],$nics[$i]['dhcpServer']['networkMask'],$nics[$i]['dhcpServer']['lowerIP'],$nics[$i]['dhcpServer']['upperIP']);
- $dhcp->releaseRemote();
- }
- $nic->releaseRemote();
-
- }
-
- return true;
-
- }
-
- /**
- * Add Host-only interface
- *
- * @param array $args array of arguments. See function body for details.
- * @return array response data
- */
- public function remote_hostOnlyInterfaceCreate($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- /* @var $progress IProgress */
- list($int,$progress) = $this->vbox->host->createHostOnlyNetworkInterface();
- $int->releaseRemote();
-
- // Does an exception exist?
- try {
- if($progress->errorInfo->handle) {
- $this->errors[] = new Exception($progress->errorInfo->text);
- $progress->releaseRemote();
- return false;
- }
- } catch (Exception $null) {}
-
- // Save progress
- $this->_util_progressStore($progress);
-
- return array('progress' => $progress->handle);
-
-
- }
-
-
- /**
- * Remove a host-only interface
- *
- * @param array $args array of arguments. See function body for details.
- * @return array response data
- */
- public function remote_hostOnlyInterfaceRemove($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- /* @var $progress IProgress */
- $progress = $this->vbox->host->removeHostOnlyNetworkInterface($args['id']);
-
- if(!$progress->handle) return false;
-
- // Does an exception exist?
- try {
- if($progress->errorInfo->handle) {
- $this->errors[] = new Exception($progress->errorInfo->text);
- $progress->releaseRemote();
- return false;
- }
- } catch (Exception $null) {}
-
- // Save progress
- $this->_util_progressStore($progress);
-
- return array('progress' => $progress->handle);
-
- }
-
- /**
- * Get a list of Guest OS Types supported by this VirtualBox installation
- *
- * @param unused $args
- * @return array of os types
- */
- public function remote_vboxGetGuestOSTypes($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- $response = array();
-
- $ts = $this->vbox->getGuestOSTypes();
-
- $supp64 = ($this->vbox->host->getProcessorFeature('LongMode') && $this->vbox->host->getProcessorFeature('HWVirtEx'));
-
- foreach($ts as $g) { /* @var $g IGuestOSType */
-
- // Avoid multiple calls
- $bit64 = $g->is64Bit;
- $response[] = array(
- 'familyId' => $g->familyId,
- 'familyDescription' => $g->familyDescription,
- 'id' => $g->id,
- 'description' => $g->description,
- 'is64Bit' => $bit64,
- 'recommendedRAM' => $g->recommendedRAM,
- 'recommendedHDD' => ($g->recommendedHDD/1024)/1024,
- 'supported' => (bool)(!$bit64 || $supp64)
- );
- }
-
- return $response;
- }
-
- /**
- * Set virtual machine state. Running, power off, save state, pause, etc..
- *
- * @param array $args array of arguments. See function body for details.
- * @return array response data or boolean true on success
- */
- public function remote_machineSetState($args) {
-
- $vm = $args['vm'];
- $state = $args['state'];
-
- $states = array(
- 'powerDown' => array('result'=>'PoweredOff','progress'=>2),
- 'reset' => array(),
- 'saveState' => array('result'=>'Saved','progress'=>2),
- 'powerButton' => array('acpi'=>true),
- 'sleepButton' => array('acpi'=>true),
- 'pause' => array('result'=>'Paused','progress'=>false),
- 'resume' => array('result'=>'Running','progress'=>false),
- 'powerUp' => array('result'=>'Running'),
- 'discardSavedState' => array('result'=>'poweredOff','lock'=>'shared','force'=>true)
- );
-
- // Check for valid state
- if(!is_array($states[$state])) {
- throw new Exception('Invalid state: ' . $state);
- }
-
- // Connect to vboxwebsrv
- $this->connect();
-
- // Machine state
- /* @var $machine IMachine */
- $machine = $this->vbox->findMachine($vm);
- $mstate = (string)$machine->state;
-
- if (@$this->settings->enforceVMOwnership && !$this->skipSessionCheck && ($owner = $machine->getExtraData("phpvb/sso/owner")) && $owner !== $_SESSION['user'] && !$_SESSION['admin'] )
- {
- // skip this VM as it is not owned by the user we're logged in as
- throw new Exception("Not authorized to change state of this VM");
- }
-
- // If state has an expected result, check
- // that we are not already in it
- if($states[$state]['result']) {
- if($mstate == $states[$state]['result']) {
- $machine->releaseRemote();
- return false;
- }
- }
-
- // Special case for power up
- if($state == 'powerUp' && $mstate == 'Paused')
- $state = 'resume';
-
- if($state == 'powerUp') {
-
-
- # Try opening session for VM
- try {
-
- // create session
- $this->session = $this->websessionManager->getSessionObject($this->vbox->handle);
-
- // set first run
- if($machine->getExtraData('GUI/FirstRun') == 'yes') {
- $machine->lockMachine($this->session->handle, 'Write');
- $this->session->machine->setExtraData('GUI/FirstRun', 'no');
- $this->session->unlockMachine();
- }
-
- /* @var $progress IProgress */
- $progress = $machine->launchVMProcess($this->session->handle, "headless", "");
-
- } catch (Exception $e) {
- // Error opening session
- $this->errors[] = $e;
- return false;
- }
-
- // Does an exception exist?
- try {
- if($progress->errorInfo->handle) {
- $this->errors[] = new Exception($progress->errorInfo->text);
- $progress->releaseRemote();
- return false;
- }
- } catch (Exception $null) {
- }
-
- $this->_util_progressStore($progress);
-
- return array('progress' => $progress->handle);
-
-
- }
-
- // Open session to machine
- $this->session = $this->websessionManager->getSessionObject($this->vbox->handle);
-
- // Lock machine
- $machine->lockMachine($this->session->handle,($states[$state]['lock'] == 'write' ? 'Write' : 'Shared'));
-
- // If this operation returns a progress object save progress
- $progress = null;
- if($states[$state]['progress']) {
-
- /* @var $progress IProgress */
- if($state == 'saveState') {
- $progress = $this->session->machine->saveState();
- } else {
- $progress = $this->session->console->$state();
- }
-
- if(!$progress->handle) {
-
- // should never get here
- try {
- $this->session->unlockMachine();
- $this->session = null;
- } catch (Exception $e) {};
-
- $machine->releaseRemote();
-
- throw new Exception('Unknown error settings machine to requested state.');
- }
-
- // Does an exception exist?
- try {
- if($progress->errorInfo->handle) {
- $this->errors[] = new Exception($progress->errorInfo->text);
- $progress->releaseRemote();
- return false;
- }
- } catch (Exception $null) {}
-
- // Save progress
- $this->_util_progressStore($progress);
-
- return array('progress' => $progress->handle);
-
- // Operation does not return a progress object
- // Just call the function
- } else {
-
- if($state == 'discardSavedState') {
- $this->session->machine->$state(($states[$state]['force'] ? true : null));
- } else {
- $this->session->console->$state(($states[$state]['force'] ? true : null));
- }
-
- }
-
- $vmname = $machine->name;
- $machine->releaseRemote();
-
- // Check for ACPI button
- if($states[$state]['acpi'] && !$this->session->console->getPowerButtonHandled()) {
- $this->session->console->releaseRemote();
- $this->session->unlockMachine();
- $this->session = null;
- return false;
- }
-
-
- if(!$progress->handle) {
- $this->session->console->releaseRemote();
- $this->session->unlockMachine();
- unset($this->session);
- }
-
- return true;
-
- }
-
-
- /**
- * Get VirtualBox host memory usage information
- *
- * @param unused $args
- * @return array response data
- */
- public function remote_hostGetMeminfo($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- return $this->vbox->host->memoryAvailable;
-
- }
-
- /**
- * Get VirtualBox host details
- *
- * @param unused $args
- * @return array response data
- */
- public function remote_hostGetDetails($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- /* @var $host IHost */
- $host = &$this->vbox->host;
- $response = array(
- 'id' => 'host',
- 'operatingSystem' => $host->operatingSystem,
- 'OSVersion' => $host->OSVersion,
- 'memorySize' => $host->memorySize,
- 'acceleration3DAvailable' => $host->acceleration3DAvailable,
- 'cpus' => array(),
- 'networkInterfaces' => array(),
- 'DVDDrives' => array(),
- 'floppyDrives' => array()
- );
-
- /*
- * Processors
- */
- // TODO https://github.com/phpvirtualbox/phpvirtualbox/issues/53
- $response['cpus'][0] = $host->getProcessorDescription(0);
- for($i = 1; $i < $host->processorCount; $i++) {
- $response['cpus'][$i] = $response['cpus'][0];
- }
-
- /*
- * Supported CPU features?
- */
- $response['cpuFeatures'] = array();
- foreach(array('HWVirtEx'=>'HWVirtEx','PAE'=>'PAE','NestedPaging'=>'Nested Paging','LongMode'=>'Long Mode (64-bit)') as $k=>$v) {
- $response['cpuFeatures'][$v] = $host->getProcessorFeature($k);
- }
-
- /*
- * NICs
- */
- foreach($host->networkInterfaces as $d) { /* @var $d IHostNetworkInterface */
- $response['networkInterfaces'][] = array(
- 'name' => $d->name,
- 'IPAddress' => $d->IPAddress,
- 'networkMask' => $d->networkMask,
- 'IPV6Supported' => $d->IPV6Supported,
- 'IPV6Address' => $d->IPV6Address,
- 'IPV6NetworkMaskPrefixLength' => $d->IPV6NetworkMaskPrefixLength,
- 'status' => (string)$d->status,
- 'mediumType' => (string)$d->mediumType,
- 'interfaceType' => (string)$d->interfaceType,
- 'hardwareAddress' => $d->hardwareAddress,
- 'networkName' => $d->networkName,
- );
- $d->releaseRemote();
- }
-
- /*
- * Medium types (DVD and Floppy)
- */
- foreach($host->DVDDrives as $d) { /* @var $d IMedium */
-
- $response['DVDDrives'][] = array(
- 'id' => $d->id,
- 'name' => $d->name,
- 'location' => $d->location,
- 'description' => $d->description,
- 'deviceType' => 'DVD',
- 'hostDrive' => true
- );
- $d->releaseRemote();
- }
-
- foreach($host->floppyDrives as $d) { /* @var $d IMedium */
-
- $response['floppyDrives'][] = array(
- 'id' => $d->id,
- 'name' => $d->name,
- 'location' => $d->location,
- 'description' => $d->description,
- 'deviceType' => 'Floppy',
- 'hostDrive' => true,
- );
- $d->releaseRemote();
- }
- $host->releaseRemote();
-
- return $response;
- }
-
- /**
- * Get a list of USB devices attached to the VirtualBox host
- *
- * @param unused $args
- * @return array of USB devices
- */
- public function remote_hostGetUSBDevices($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- $response = array();
-
- foreach($this->vbox->host->USBDevices as $d) { /* @var $d IUSBDevice */
-
- $response[] = array(
- 'id' => $d->id,
- 'vendorId' => sprintf('%04s',dechex($d->vendorId)),
- 'productId' => sprintf('%04s',dechex($d->productId)),
- 'revision' => sprintf('%04s',dechex($d->revision)),
- 'manufacturer' => $d->manufacturer,
- 'product' => $d->product,
- 'serialNumber' => $d->serialNumber,
- 'address' => $d->address,
- 'port' => $d->port,
- 'version' => $d->version,
- 'portVersion' => $d->portVersion,
- 'remote' => $d->remote,
- 'state' => (string)$d->state,
- );
- $d->releaseRemote();
- }
-
- return $response;
- }
-
-
- /**
- * Get virtual machine or virtualbox host details
- *
- * @param array $args array of arguments. See function body for details.
- * @param ISnapshot $snapshot snapshot instance to use if obtaining snapshot details.
- * @see hostGetDetails()
- * @return array machine details
- */
- public function remote_machineGetDetails($args, $snapshot=null) {
-
- // Host instead of vm info
- if($args['vm'] == 'host') {
-
- $response = $this->remote_hostGetDetails($args);
-
- return $response;
- }
-
-
- // Connect to vboxwebsrv
- $this->connect();
-
- //Get registered machine or snapshot machine
- if($snapshot) {
-
- /* @var $machine ISnapshot */
- $machine = &$snapshot;
-
- } else {
-
- /* @var $machine IMachine */
- $machine = $this->vbox->findMachine($args['vm']);
-
-
- // For correct caching, always use id even if a name was passed
- $args['vm'] = $machine->id;
-
- // Check for accessibility
- if(!$machine->accessible) {
-
- return array(
- 'name' => $machine->id,
- 'state' => 'Inaccessible',
- 'OSTypeId' => 'Other',
- 'id' => $machine->id,
- 'sessionState' => 'Inaccessible',
- 'accessible' => 0,
- 'accessError' => array(
- 'resultCode' => $this->_util_resultCodeText($machine->accessError->resultCode),
- 'component' => $machine->accessError->component,
- 'text' => $machine->accessError->text)
- );
- }
-
- }
-
- // Basic data
- $data = $this->_machineGetDetails($machine);
-
- // Network Adapters
- $data['networkAdapters'] = $this->_machineGetNetworkAdapters($machine);
-
- // Storage Controllers
- $data['storageControllers'] = $this->_machineGetStorageControllers($machine);
-
- // Serial Ports
- $data['serialPorts'] = $this->_machineGetSerialPorts($machine);
-
- // LPT Ports
- $data['parallelPorts'] = $this->_machineGetParallelPorts($machine);
-
- // Shared Folders
- $data['sharedFolders'] = $this->_machineGetSharedFolders($machine);
-
- // USB Controllers
- $data['USBControllers'] = $this->_machineGetUSBControllers($machine);
- $data['USBDeviceFilters'] = $this->_machineGetUSBDeviceFilters($machine);
-
-
- if (@$this->settings->enforceVMOwnership )
- {
- $data['name'] = preg_replace('/^' . preg_quote($_SESSION['user']) . '_/', '', $data['name']);
- }
-
- // Items when not obtaining snapshot machine info
- if(!$snapshot) {
-
- $data['currentSnapshot'] = ($machine->currentSnapshot->handle ? array('id'=>$machine->currentSnapshot->id,'name'=>$machine->currentSnapshot->name) : null);
- $data['snapshotCount'] = $machine->snapshotCount;
-
- // Start / stop config
- if(@$this->settings->startStopConfig) {
- $data['startupMode'] = $machine->getExtraData('pvbx/startupMode');
- }
-
-
- }
-
- $machine->releaseRemote();
-
- $data['accessible'] = 1;
- return $data;
- }
-
- /**
- * Get runtime data of machine.
- *
- * @param array $args array of arguments. See function body for details.
- * @return array of machine runtime data
- */
- public function remote_machineGetRuntimeData($args) {
-
- $this->connect();
-
- /* @var $machine IMachine */
- $machine = $this->vbox->findMachine($args['vm']);
- $data = array(
- 'id' => $args['vm'],
- 'state' => (string)$machine->state
- );
-
- /*
- * TODO:
- *
- * 5.13.13 getGuestEnteredACPIMode
- boolean IConsole::getGuestEnteredACPIMode()
- Checks if the guest entered the ACPI mode G0 (working) or G1 (sleeping). If this method
- returns false, the guest will most likely not respond to external ACPI events.
- If this method fails, the following error codes may be reported:
- VBOX_E_INVALID_VM_STATE: Virtual machine not in Running state.
- */
-
- // Get current console port
- if($data['state'] == 'Running' || $data['state'] == 'Paused') {
-
- $this->session = $this->websessionManager->getSessionObject($this->vbox->handle);
- $machine->lockMachine($this->session->handle, 'Shared');
- $console = $this->session->console;
-
- // Get guest additions version
- if(@$this->settings->enableGuestAdditionsVersionDisplay) {
- $data['guestAdditionsVersion'] = $console->guest->additionsVersion;
- }
-
- $smachine = $this->session->machine;
-
- $data['CPUExecutionCap'] = $smachine->CPUExecutionCap;
- $data['VRDEServerInfo'] = array('port' => $console->VRDEServerInfo->port);
-
- $vrde = $smachine->VRDEServer;
-
- $data['VRDEServer'] = (!$vrde ? null : array(
- 'enabled' => $vrde->enabled,
- 'ports' => $vrde->getVRDEProperty('TCP/Ports'),
- 'netAddress' => $vrde->getVRDEProperty('TCP/Address'),
- 'VNCPassword' => $vrde->getVRDEProperty('VNCPassword'),
- 'authType' => (string)$vrde->authType,
- 'authTimeout' => $vrde->authTimeout,
- 'VRDEExtPack' => (string)$vrde->VRDEExtPack
- ));
-
- // Get removable media
- $data['storageControllers'] = $this->_machineGetStorageControllers($smachine);
-
- // Get network adapters
- $data['networkAdapters'] = $this->_machineGetNetworkAdapters($smachine);
-
- $machine->releaseRemote();
-
- // Close session and unlock machine
- $this->session->unlockMachine();
- unset($this->session);
-
- }
-
-
- return $data;
-
- }
-
- /**
- * Remove a virtual machine
- *
- * @param array $args array of arguments. See function body for details.
- * @return boolean true on success or array of response data
- */
- public function remote_machineRemove($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- /* @var $machine IMachine */
- $machine = $this->vbox->findMachine($args['vm']);
-
- // Only unregister or delete?
- if(!$args['delete']) {
-
- $machine->unregister('DetachAllReturnNone');
- $machine->releaseRemote();
-
- } else {
-
- $hds = array();
- $delete = $machine->unregister('DetachAllReturnHardDisksOnly');
- foreach($delete as $hd) {
- $hds[] = $this->vbox->openMedium($hd->location,'HardDisk','ReadWrite',false)->handle;
- }
-
- /* @var $progress IProgress */
- $progress = $machine->deleteConfig($hds);
-
- $machine->releaseRemote();
-
- // Does an exception exist?
- if($progress) {
- try {
- if($progress->errorInfo->handle) {
- $this->errors[] = new Exception($progress->errorInfo->text);
- $progress->releaseRemote();
- return false;
- }
- } catch (Exception $null) {}
-
- $this->_util_progressStore($progress);
-
- return array('progress' => $progress->handle);
-
- }
-
-
- }
-
- return true;
-
-
- }
-
-
- /**
- * Create a new Virtual Machine
- *
- * @param array $args array of arguments. See function body for details.
- * @return boolean true on success
- */
- public function remote_machineCreate($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- $response = array();
-
- // quota enforcement
- if ( isset($_SESSION['user']) )
- {
- if ( @isset($this->settings->vmQuotaPerUser) && @$this->settings->vmQuotaPerUser > 0 && !$_SESSION['admin'] )
- {
- $newresp = array('data' => array());
- $this->vboxGetMachines(array(), array(&$newresp));
- if ( count($newresp['data']['responseData']) >= $this->settings->vmQuotaPerUser )
- {
- // we're over quota!
- // delete the disk we just created
- if ( isset($args['disk']) )
- {
- $this->mediumRemove(array(
- 'medium' => $args['disk'],
- 'type' => 'HardDisk',
- 'delete' => true
- ), $newresp);
- }
- throw new Exception("Sorry, you're over quota. You can only create up to {$this->settings->vmQuotaPerUser} VMs.");
- }
- }
- }
-
- // create machine
- if (@$this->settings->enforceVMOwnership )
- $args['name'] = $_SESSION['user'] . '_' . $args['name'];
-
- /* Check if file exists */
- $filename = $this->vbox->composeMachineFilename($args['name'],($this->settings->phpVboxGroups ? '' : $args['group']),$this->vbox->systemProperties->defaultMachineFolder,null);
-
- if($this->remote_fileExists(array('file'=>$filename))) {
- return array('exists' => $filename);
- }
-
-
- /* @var $m IMachine */
- $m = $this->vbox->createMachine(null,$args['name'],($this->settings->phpVboxGroups ? '' : $args['group']),$args['ostype'],null,null);
-
- /* Check for phpVirtualBox groups */
- if($this->settings->phpVboxGroups && $args['group']) {
- $m->setExtraData(vboxconnector::phpVboxGroupKey, $args['group']);
- }
-
- // Set memory
- $m->memorySize = intval($args['memory']);
-
-
- // Save and register
- $m->saveSettings();
- $this->vbox->registerMachine($m->handle);
- $vm = $m->id;
- $m->releaseRemote();
-
- try {
-
- $this->session = $this->websessionManager->getSessionObject($this->vbox->handle);
-
- // Lock VM
- /* @var $machine IMachine */
- $machine = $this->vbox->findMachine($vm);
- $machine->lockMachine($this->session->handle,'Write');
-
- // OS defaults
- $defaults = $this->vbox->getGuestOSType($args['ostype']);
-
- // Ownership enforcement
- if ( isset($_SESSION['user']) )
- {
- $this->session->machine->setExtraData('phpvb/sso/owner', $_SESSION['user']);
- }
-
- // set the vboxauthsimple in VM config
- $this->session->machine->setExtraData('VBoxAuthSimple/users/'.$_SESSION['user'].'', $_SESSION['uHash']);
-
- // Always set
- $this->session->machine->setExtraData('GUI/FirstRun', 'yes');
-
- try {
- if($this->session->machine->VRDEServer && $this->vbox->systemProperties->defaultVRDEExtPack) {
- $this->session->machine->VRDEServer->enabled = 1;
- $this->session->machine->VRDEServer->authTimeout = 5000;
- $this->session->machine->VRDEServer->setVRDEProperty('TCP/Ports',($this->settings->vrdeports ? $this->settings->vrdeports : '3390-5000'));
- $this->session->machine->VRDEServer->setVRDEProperty('TCP/Address',($this->settings->vrdeaddress ? $this->settings->vrdeaddress : '127.0.0.1'));
- }
- } catch (Exception $e) {
- //Ignore
- }
-
- // Other defaults
- $this->session->machine->BIOSSettings->IOAPICEnabled = $defaults->recommendedIOAPIC;
- $this->session->machine->RTCUseUTC = $defaults->recommendedRTCUseUTC;
- $this->session->machine->firmwareType = (string)$defaults->recommendedFirmware;
- $this->session->machine->chipsetType = (string)$defaults->recommendedChipset;
- if(intval($defaults->recommendedVRAM) > 0) $this->session->machine->VRAMSize = intval($defaults->recommendedVRAM);
- $this->session->machine->setCpuProperty('PAE',$defaults->recommendedPAE);
-
- // USB input devices
- if($defaults->recommendedUSBHid) {
- $this->session->machine->pointingHIDType = 'USBMouse';
- $this->session->machine->keyboardHIDType = 'USBKeyboard';
- }
-
- /* Only if acceleration configuration is available */
- if($this->vbox->host->getProcessorFeature('HWVirtEx')) {
- $this->session->machine->setHWVirtExProperty('Enabled',$defaults->recommendedVirtEx);
- }
-
- /*
- * Hard Disk and DVD/CD Drive
- */
- $DVDbusType = (string)$defaults->recommendedDVDStorageBus;
- $DVDconType = (string)$defaults->recommendedDVDStorageController;
-
- // Attach harddisk?
- if($args['disk']) {
-
- $HDbusType = (string)$defaults->recommendedHDStorageBus;
- $HDconType = (string)$defaults->recommendedHDStorageController;
-
- $bus = new StorageBus(null,$HDbusType);
- $sc = $this->session->machine->addStorageController(trans($HDbusType,'UIMachineSettingsStorage'),(string)$bus);
- $sc->controllerType = $HDconType;
- $sc->useHostIOCache = (bool)$this->vbox->systemProperties->getDefaultIoCacheSettingForStorageController($HDconType);
-
- // Set port count?
- if($HDbusType == 'SATA') {
- $sc->portCount = (($HDbusType == $DVDbusType) ? 2 : 1);
- }
-
- $sc->releaseRemote();
-
- $m = $this->vbox->openMedium($args['disk'],'HardDisk','ReadWrite',false);
-
- $this->session->machine->attachDevice(trans($HDbusType,'UIMachineSettingsStorage'),0,0,'HardDisk',$m->handle);
-
- $m->releaseRemote();
-
- }
-
- // Attach DVD/CDROM
- if($DVDbusType) {
-
- if(!$args['disk'] || ($HDbusType != $DVDbusType)) {
-
- $bus = new StorageBus(null,$DVDbusType);
- $sc = $this->session->machine->addStorageController(trans($DVDbusType,'UIMachineSettingsStorage'),(string)$bus);
- $sc->controllerType = $DVDconType;
- $sc->useHostIOCache = (bool)$this->vbox->systemProperties->getDefaultIoCacheSettingForStorageController($DVDconType);
-
- // Set port count?
- if($DVDbusType == 'SATA') {
- $sc->portCount = ($args['disk'] ? 1 : 2);
- }
-
- $sc->releaseRemote();
- }
-
- $this->session->machine->attachDevice(trans($DVDbusType,'UIMachineSettingsStorage'),1,0,'DVD',null);
-
- }
-
- $this->session->machine->saveSettings();
- $this->session->unlockMachine();
- $this->session = null;
-
- $machine->releaseRemote();
-
- } catch (Exception $e) {
- $this->errors[] = $e;
- return false;
- }
-
- return true;
-
- }
-
-
- /**
- * Return a list of network adapters attached to machine $m
- *
- * @param IMachine $m virtual machine instance
- * @param int $slot optional slot of single network adapter to get
- * @return array of network adapter information
- */
- private function _machineGetNetworkAdapters(&$m, $slot=false) {
-
- $adapters = array();
-
- for($i = ($slot === false ? 0 : $slot); $i < ($slot === false ? $this->settings->nicMax : ($slot+1)); $i++) {
-
- /* @var $n INetworkAdapter */
- $n = $m->getNetworkAdapter($i);
-
- // Avoid duplicate calls
- $at = (string)$n->attachmentType;
- if($at == 'NAT') $nd = $n->NATEngine; /* @var $nd INATEngine */
- else $nd = null;
-
- $props = $n->getProperties(null);
- $props = implode("\n",array_map(function($a,$b){return "$a=$b";},$props[1],$props[0]));
-
- $adapters[] = array(
- 'adapterType' => (string)$n->adapterType,
- 'slot' => $n->slot,
- 'enabled' => $n->enabled,
- 'MACAddress' => $n->MACAddress,
- 'attachmentType' => $at,
- 'genericDriver' => $n->genericDriver,
- 'hostOnlyInterface' => $n->hostOnlyInterface,
- 'bridgedInterface' => $n->bridgedInterface,
- 'properties' => $props,
- 'internalNetwork' => $n->internalNetwork,
- 'NATNetwork' => $n->NATNetwork,
- 'promiscModePolicy' => (string)$n->promiscModePolicy,
- 'VDENetwork' => ($this->settings->enableVDE ? $n->VDENetwork : ''),
- 'cableConnected' => $n->cableConnected,
- 'NATEngine' => ($at == 'NAT' ?
- array('aliasMode' => intval($nd->aliasMode),'DNSPassDomain' => $nd->DNSPassDomain, 'DNSProxy' => $nd->DNSProxy, 'DNSUseHostResolver' => $nd->DNSUseHostResolver, 'hostIP' => $nd->hostIP)
- : array('aliasMode' => 0,'DNSPassDomain' => 0, 'DNSProxy' => 0, 'DNSUseHostResolver' => 0, 'hostIP' => '')),
- 'lineSpeed' => $n->lineSpeed,
- 'redirects' => (
- $at == 'NAT' ?
- $nd->getRedirects()
- : array()
- )
- );
-
- $n->releaseRemote();
- }
-
- return $adapters;
-
- }
-
-
- /**
- * Return a list of virtual machines along with their states and other basic info
- *
- * @param array $args array of arguments. See function body for details.
- * @return array list of machines
- */
- public function remote_vboxGetMachines($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- $vmlist = array();
-
- // Look for a request for a single vm
- if($args['vm']) {
-
- $machines = array($this->vbox->findMachine($args['vm']));
-
- // Full list
- } else {
- //Get a list of registered machines
- $machines = $this->vbox->machines;
-
- }
-
-
-
- foreach ($machines as $machine) { /* @var $machine IMachine */
-
-
- try {
-
- if(!$machine->accessible) {
-
- $vmlist[] = array(
- 'name' => $machine->id,
- 'state' => 'Inaccessible',
- 'OSTypeId' => 'Other',
- 'id' => $machine->id,
- 'sessionState' => 'Inaccessible',
- 'accessible' => 0,
- 'accessError' => array(
- 'resultCode' => $this->_util_resultCodeText($machine->accessError->resultCode),
- 'component' => $machine->accessError->component,
- 'text' => $machine->accessError->text),
- 'lastStateChange' => 0,
- 'groups' => array(),
- 'currentSnapshot' => ''
-
- );
-
- continue;
- }
-
- if($this->settings->phpVboxGroups) {
- $groups = explode(',',$machine->getExtraData(vboxconnector::phpVboxGroupKey));
- if(!is_array($groups) || (count($groups) == 1 && !$groups[0])) $groups = array("/");
- } else {
- $groups = $machine->groups;
- }
-
- usort($groups, 'strnatcasecmp');
-
- $vmlist[] = array(
- 'name' => @$this->settings->enforceVMOwnership ? preg_replace('/^' . preg_quote($_SESSION['user']) . '_/', '', $machine->name) : $machine->name,
- 'state' => (string)$machine->state,
- 'OSTypeId' => $machine->getOSTypeId(),
- 'owner' => (@$this->settings->enforceVMOwnership ? $machine->getExtraData("phpvb/sso/owner") : ''),
- 'groups' => $groups,
- 'lastStateChange' => (string)($machine->lastStateChange/1000),
- 'id' => $machine->id,
- 'currentStateModified' => $machine->currentStateModified,
- 'sessionState' => (string)$machine->sessionState,
- 'currentSnapshotName' => ($machine->currentSnapshot->handle ? $machine->currentSnapshot->name : ''),
- 'customIcon' => (@$this->settings->enableCustomIcons ? $machine->getExtraData('phpvb/icon') : '')
- );
- if($machine->currentSnapshot->handle) $machine->currentSnapshot->releaseRemote();
-
-
- } catch (Exception $e) {
-
- if($machine) {
-
- $vmlist[] = array(
- 'name' => $machine->id,
- 'state' => 'Inaccessible',
- 'OSTypeId' => 'Other',
- 'id' => $machine->id,
- 'sessionState' => 'Inaccessible',
- 'lastStateChange' => 0,
- 'groups' => array(),
- 'currentSnapshot' => ''
- );
-
- } else {
- $this->errors[] = $e;
- }
- }
-
- try {
- $machine->releaseRemote();
- } catch (Exception $e) { }
- }
-
- return $vmlist;
-
- }
-
- /**
- * Creates a new exception so that input can be debugged.
- *
- * @param array $args array of arguments. See function body for details.
- * @return boolean true on success
- */
- public function debugInput($args) {
- $this->errors[] = new Exception('debug');
- return true;
- }
-
- /**
- * Get a list of media registered with VirtualBox
- *
- * @param unused $args
- * @param array $response response data passed byref populated by the function
- * @return array of media
- */
- public function remote_vboxGetMedia($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- $response = array();
- $mds = array($this->vbox->hardDisks,$this->vbox->DVDImages,$this->vbox->floppyImages);
- for($i=0;$i<3;$i++) {
- foreach($mds[$i] as $m) {
- /* @var $m IMedium */
- $response[] = $this->_mediumGetDetails($m);
- $m->releaseRemote();
- }
- }
- return $response;
- }
-
- /**
- * Get USB controller information
- *
- * @param IMachine $m virtual machine instance
- * @return array USB controller info
- */
- private function _machineGetUSBControllers(&$m) {
-
- /* @var $u IUSBController */
- $controllers = &$m->USBControllers;
-
- $rcons = array();
- foreach($controllers as $c) {
- $rcons[] = array(
- 'name' => $c->name,
- 'type' => (string)$c->type
- );
- $c->releaseRemote();
- }
-
- return $rcons;
- }
-
- /**
- * Get USB device filters
- *
- * @param IMachine $m virtual machine instance
- * @return array USB device filters
- */
- private function _machineGetUSBDeviceFilters(&$m) {
-
- $deviceFilters = array();
- foreach($m->USBDeviceFilters->deviceFilters as $df) { /* @var $df IUSBDeviceFilter */
-
- $deviceFilters[] = array(
- 'name' => $df->name,
- 'active' => $df->active,
- 'vendorId' => $df->vendorId,
- 'productId' => $df->productId,
- 'revision' => $df->revision,
- 'manufacturer' => $df->manufacturer,
- 'product' => $df->product,
- 'serialNumber' => $df->serialNumber,
- 'port' => $df->port,
- 'remote' => $df->remote
- );
- $df->releaseRemote();
- }
- return $deviceFilters;
- }
-
- /**
- * Return top-level virtual machine or snapshot information
- *
- * @param IMachine $m virtual machine instance
- * @return array vm or snapshot data
- */
- private function _machineGetDetails(&$m) {
-
- if($this->settings->phpVboxGroups) {
- $groups = explode(',',$m->getExtraData(vboxconnector::phpVboxGroupKey));
- if(!is_array($groups) || (count($groups) == 1 && !$groups[0])) $groups = array("/");
- } else {
- $groups = $m->groups;
- }
-
- usort($groups, 'strnatcasecmp');
-
- return array(
- 'name' => @$this->settings->enforceVMOwnership ? preg_replace('/^' . preg_quote($_SESSION['user']) . '_/', '', $m->name) : $m->name,
- 'description' => $m->description,
- 'groups' => $groups,
- 'id' => $m->id,
- 'autostopType' => ($this->settings->vboxAutostartConfig ? (string)$m->autostopType : ''),
- 'autostartEnabled' => ($this->settings->vboxAutostartConfig && $m->autostartEnabled),
- 'autostartDelay' => ($this->settings->vboxAutostartConfig ? intval($m->autostartDelay) : '0'),
- 'settingsFilePath' => $m->settingsFilePath,
- 'paravirtProvider' => (string)$m->paravirtProvider,
- 'OSTypeId' => $m->OSTypeId,
- 'OSTypeDesc' => $this->vbox->getGuestOSType($m->OSTypeId)->description,
- 'CPUCount' => $m->CPUCount,
- 'HPETEnabled' => $m->HPETEnabled,
- 'memorySize' => $m->memorySize,
- 'VRAMSize' => $m->VRAMSize,
- 'pointingHIDType' => (string)$m->pointingHIDType,
- 'keyboardHIDType' => (string)$m->keyboardHIDType,
- 'accelerate3DEnabled' => $m->accelerate3DEnabled,
- 'accelerate2DVideoEnabled' => $m->accelerate2DVideoEnabled,
- 'BIOSSettings' => array(
- 'ACPIEnabled' => $m->BIOSSettings->ACPIEnabled,
- 'IOAPICEnabled' => $m->BIOSSettings->IOAPICEnabled,
- 'timeOffset' => $m->BIOSSettings->timeOffset
- ),
- 'firmwareType' => (string)$m->firmwareType,
- 'snapshotFolder' => $m->snapshotFolder,
- 'monitorCount' => $m->monitorCount,
- 'pageFusionEnabled' => $m->pageFusionEnabled,
- 'VRDEServer' => (!$m->VRDEServer ? null : array(
- 'enabled' => $m->VRDEServer->enabled,
- 'ports' => $m->VRDEServer->getVRDEProperty('TCP/Ports'),
- 'netAddress' => $m->VRDEServer->getVRDEProperty('TCP/Address'),
- 'VNCPassword' => $m->VRDEServer->getVRDEProperty('VNCPassword'),
- 'authType' => (string)$m->VRDEServer->authType,
- 'authTimeout' => $m->VRDEServer->authTimeout,
- 'allowMultiConnection' => $m->VRDEServer->allowMultiConnection,
- 'VRDEExtPack' => (string)$m->VRDEServer->VRDEExtPack
- )),
- 'audioAdapter' => array(
- 'enabled' => $m->audioAdapter->enabled,
- 'audioController' => (string)$m->audioAdapter->audioController,
- 'audioDriver' => (string)$m->audioAdapter->audioDriver,
- ),
- 'RTCUseUTC' => $m->RTCUseUTC,
- 'EffectiveParavirtProvider' => (string)$m->getEffectiveParavirtProvider(),
- 'HWVirtExProperties' => array(
- 'Enabled' => $m->getHWVirtExProperty('Enabled'),
- 'NestedPaging' => $m->getHWVirtExProperty('NestedPaging'),
- 'LargePages' => $m->getHWVirtExProperty('LargePages'),
- 'UnrestrictedExecution' => $m->getHWVirtExProperty('UnrestrictedExecution'),
- 'VPID' => $m->getHWVirtExProperty('VPID')
- ),
- 'CpuProperties' => array(
- 'PAE' => $m->getCpuProperty('PAE')
- ),
- 'bootOrder' => $this->_machineGetBootOrder($m),
- 'chipsetType' => (string)$m->chipsetType,
- 'GUI' => array(
- 'FirstRun' => $m->getExtraData('GUI/FirstRun'),
- ),
- 'customIcon' => (@$this->settings->enableCustomIcons ? $m->getExtraData('phpvb/icon') : ''),
- 'disableHostTimeSync' => intval($m->getExtraData("VBoxInternal/Devices/VMMDev/0/Config/GetHostTimeDisabled")),
- 'CPUExecutionCap' => $m->CPUExecutionCap
- );
-
- }
-
- /**
- * Get virtual machine boot order
- *
- * @param IMachine $m virtual machine instance
- * @return array boot order
- */
- private function _machineGetBootOrder(&$m) {
- $return = array();
- $mbp = $this->vbox->systemProperties->maxBootPosition;
- for($i = 0; $i < $mbp; $i ++) {
- if(($b = (string)$m->getBootOrder($i + 1)) == 'Null') continue;
- $return[] = $b;
- }
- return $return;
- }
-
- /**
- * Get serial port configuration for a virtual machine or snapshot
- *
- * @param IMachine $m virtual machine instance
- * @return array serial port info
- */
- private function _machineGetSerialPorts(&$m) {
- $ports = array();
- $max = $this->vbox->systemProperties->serialPortCount;
- for($i = 0; $i < $max; $i++) {
- try {
- /* @var $p ISerialPort */
- $p = $m->getSerialPort($i);
- $ports[] = array(
- 'slot' => $p->slot,
- 'enabled' => $p->enabled,
- 'IOBase' => '0x'.strtoupper(sprintf('%3s',dechex($p->IOBase))),
- 'IRQ' => $p->IRQ,
- 'hostMode' => (string)$p->hostMode,
- 'server' => $p->server,
- 'path' => $p->path
- );
- $p->releaseRemote();
- } catch (Exception $e) {
- // Ignore
- }
- }
- return $ports;
- }
-
- /**
- * Get parallel port configuration for a virtual machine or snapshot
- *
- * @param IMachine $m virtual machine instance
- * @return array parallel port info
- */
- private function _machineGetParallelPorts(&$m) {
- if(!@$this->settings->enableLPTConfig) return array();
- $ports = array();
- $max = $this->vbox->systemProperties->parallelPortCount;
- for($i = 0; $i < $max; $i++) {
- try {
- /* @var $p IParallelPort */
- $p = $m->getParallelPort($i);
- $ports[] = array(
- 'slot' => $p->slot,
- 'enabled' => $p->enabled,
- 'IOBase' => '0x'.strtoupper(sprintf('%3s',dechex($p->IOBase))),
- 'IRQ' => $p->IRQ,
- 'path' => $p->path
- );
- $p->releaseRemote();
- } catch (Exception $e) {
- // Ignore
- }
- }
- return $ports;
- }
-
- /**
- * Get shared folder configuration for a virtual machine or snapshot
- *
- * @param IMachine $m virtual machine instance
- * @return array shared folder info
- */
- private function _machineGetSharedFolders(&$m) {
- $sfs = &$m->sharedFolders;
- $return = array();
- foreach($sfs as $sf) { /* @var $sf ISharedFolder */
- $return[] = array(
- 'name' => $sf->name,
- 'hostPath' => $sf->hostPath,
- 'accessible' => $sf->accessible,
- 'writable' => $sf->writable,
- 'autoMount' => $sf->autoMount,
- 'lastAccessError' => $sf->lastAccessError,
- 'type' => 'machine'
- );
- }
- return $return;
- }
-
- /**
- * Add encryption password to VM console
- *
- * @param array $args array of arguments. See function body for details.
- * @return true on success
- */
- public function remote_consoleAddDiskEncryptionPasswords($args) {
-
- $this->connect();
-
- /* @var $machine IMachine */
- $machine = $this->vbox->findMachine($args['vm']);
-
- $this->session = $this->websessionManager->getSessionObject($this->vbox->handle);
- $machine->lockMachine($this->session->handle,'Shared');
-
- $response = array('accepted'=>array(),'failed'=>array(),'errors'=>array());
-
- foreach($args['passwords'] as $creds) {
- try {
- $this->session->console->removeDiskEncryptionPassword($creds['id']);
- } catch(Exception $e) {
- // It may not exist yet
- }
-
- try {
- $this->session->console->addDiskEncryptionPassword($creds['id'], $creds['password'], (bool)@$args['clearOnSuspend']);
- $response['accepted'][] = $creds['id'];
- } catch (Exception $e) {
- $response['failed'][] = $creds['id'];
- $response['errors'][] = $e->getMessage();
- }
- }
-
- $this->session->unlockMachine();
- unset($this->session);
- $machine->releaseRemote();
-
- return $response;
- }
-
- /**
- * Get a list of transient (temporary) shared folders
- *
- * @param array $args array of arguments. See function body for details.
- * @return array of shared folders
- */
- public function remote_consoleGetSharedFolders($args) {
-
- $this->connect();
-
- /* @var $machine IMachine */
- $machine = $this->vbox->findMachine($args['vm']);
-
- // No need to continue if machine is not running
- if((string)$machine->state != 'Running') {
- $machine->releaseRemote();
- return true;
- }
-
- $this->session = $this->websessionManager->getSessionObject($this->vbox->handle);
- $machine->lockMachine($this->session->handle,'Shared');
-
- $sfs = $this->session->console->sharedFolders;
-
- $response = array();
-
- foreach($sfs as $sf) { /* @var $sf ISharedFolder */
-
- $response[] = array(
- 'name' => $sf->name,
- 'hostPath' => $sf->hostPath,
- 'accessible' => $sf->accessible,
- 'writable' => $sf->writable,
- 'autoMount' => $sf->autoMount,
- 'lastAccessError' => $sf->lastAccessError,
- 'type' => 'transient'
- );
- }
-
- $this->session->unlockMachine();
- unset($this->session);
- $machine->releaseRemote();
-
- return $response;
- }
-
- /**
- * Get VirtualBox Host OS specific directory separator
- *
- * @return string directory separator string
- */
- public function getDsep() {
-
- if(!$this->dsep) {
-
- /* No need to go through vbox if local browser is true */
- if($this->settings->browserLocal) {
-
- $this->dsep = DIRECTORY_SEPARATOR;
-
- } else {
-
- $this->connect();
-
- if(stripos($this->vbox->host->operatingSystem,'windows') !== false) {
- $this->dsep = '\\';
- } else {
- $this->dsep = '/';
- }
- }
-
-
- }
-
- return $this->dsep;
- }
-
- /**
- * Get medium attachment information for all medium attachments in $mas
- *
- * @param IMediumAttachment[] $mas list of IMediumAttachment instances
- * @return array medium attachment info
- */
- private function _machineGetMediumAttachments(&$mas) {
-
- $return = array();
-
- foreach($mas as $ma) { /** @var $ma IMediumAttachment */
- $return[] = array(
- 'medium' => ($ma->medium->handle ? array('id'=>$ma->medium->id) : null),
- 'controller' => $ma->controller,
- 'port' => $ma->port,
- 'device' => $ma->device,
- 'type' => (string)$ma->type,
- 'passthrough' => $ma->passthrough,
- 'temporaryEject' => $ma->temporaryEject,
- 'nonRotational' => $ma->nonRotational,
- 'hotPluggable' => $ma->hotPluggable,
- );
- }
-
- // sort by port then device
- usort($return,function($a,$b){if($a["port"] == $b["port"]) { if($a["device"] < $b["device"]) { return -1; } if($a["device"] > $b["device"]) { return 1; } return 0; } if($a["port"] < $b["port"]) { return -1; } return 1;});
-
- return $return;
- }
-
- /**
- * Save snapshot details ( description or name)
- *
- * @param array $args array of arguments. See function body for details.
- * @return boolean true on success
- */
- public function remote_snapshotSave($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- /* @var $vm IMachine */
- $vm = $this->vbox->findMachine($args['vm']);
-
- /* @var $snapshot ISnapshot */
- $snapshot = $vm->findSnapshot($args['snapshot']);
- $snapshot->name = $args['name'];
- $snapshot->description = $args['description'];
-
- // cleanup
- $snapshot->releaseRemote();
- $vm->releaseRemote();
-
- return true;
- }
-
- /**
- * Get snapshot details
- *
- * @param array $args array of arguments. See function body for details.
- * @return array containing snapshot details
- */
- public function remote_snapshotGetDetails($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- /* @var $vm IMachine */
- $vm = $this->vbox->findMachine($args['vm']);
-
- /* @var $snapshot ISnapshot */
- $snapshot = $vm->findSnapshot($args['snapshot']);
-
- $response = $this->_snapshotGetDetails($snapshot,false);
- $response['machine'] = $this->remote_machineGetDetails(array(),$snapshot->machine);
-
- // cleanup
- $snapshot->releaseRemote();
- $vm->releaseRemote();
-
- return $response;
-
- }
-
- /**
- * Restore a snapshot
- *
- * @param array $args array of arguments. See function body for details.
- * @return array response data containing progress operation id
- */
- public function remote_snapshotRestore($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- $progress = $this->session = null;
-
- try {
-
- // Open session to machine
- $this->session = $this->websessionManager->getSessionObject($this->vbox->handle);
-
- /* @var $machine IMachine */
- $machine = $this->vbox->findMachine($args['vm']);
- $machine->lockMachine($this->session->handle, 'Write');
-
- /* @var $snapshot ISnapshot */
- $snapshot = $this->session->machine->findSnapshot($args['snapshot']);
-
- /* @var $progress IProgress */
- $progress = $this->session->machine->restoreSnapshot($snapshot->handle);
-
- $snapshot->releaseRemote();
- $machine->releaseRemote();
-
- // Does an exception exist?
- try {
- if($progress->errorInfo->handle) {
- $this->errors[] = new Exception($progress->errorInfo->text);
- $progress->releaseRemote();
- return false;
- }
- } catch (Exception $null) {}
-
- $this->_util_progressStore($progress);
-
- } catch (Exception $e) {
-
- $this->errors[] = $e;
-
- if($this->session->handle) {
- try{$this->session->unlockMachine();}catch(Exception $e){}
- }
- return false;
- }
-
- return array('progress' => $progress->handle);
-
- }
-
- /**
- * Delete a snapshot
- *
- * @param array $args array of arguments. See function body for details.
- * @return array response data containing progress operation id
- */
- public function remote_snapshotDelete($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- $progress = $this->session = null;
-
- try {
-
- // Open session to machine
- $this->session = $this->websessionManager->getSessionObject($this->vbox->handle);
-
- /* @var $machine IMachine */
- $machine = $this->vbox->findMachine($args['vm']);
- $machine->lockMachine($this->session->handle, 'Shared');
-
- /* @var $progress IProgress */
- $progress = $this->session->machine->deleteSnapshot($args['snapshot']);
-
- $machine->releaseRemote();
-
- // Does an exception exist?
- try {
- if($progress->errorInfo->handle) {
- $this->errors[] = new Exception($progress->errorInfo->text);
- $progress->releaseRemote();
- return false;
- }
- } catch (Exception $null) {}
-
- $this->_util_progressStore($progress);
-
-
- } catch (Exception $e) {
-
- $this->errors[] = $e;
-
- if($this->session->handle) {
- try{$this->session->unlockMachine();$this->session=null;}catch(Exception $e){}
- }
-
- return false;
- }
-
- return array('progress' => $progress->handle);
-
- }
-
- /**
- * Take a snapshot
- *
- * @param array $args array of arguments. See function body for details.
- * @return array response data containing progress operation id
- */
- public function remote_snapshotTake($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- /* @var $machine IMachine */
- $machine = $this->vbox->findMachine($args['vm']);
-
- $progress = $this->session = null;
-
- try {
-
- // Open session to machine
- $this->session = $this->websessionManager->getSessionObject($this->vbox->handle);
- $machine->lockMachine($this->session->handle, ((string)$machine->sessionState == 'Unlocked' ? 'Write' : 'Shared'));
-
- /* @var $progress IProgress */
- list($progress, $snapshotId) = $this->session->machine->takeSnapshot($args['name'], $args['description'], null);
-
- // Does an exception exist?
- try {
- if($progress->errorInfo->handle) {
- $this->errors[] = new Exception($progress->errorInfo->text);
- $progress->releaseRemote();
- try{$this->session->unlockMachine(); $this->session=null;}catch(Exception $ed){}
- return false;
- }
- } catch (Exception $null) {}
-
-
- $this->_util_progressStore($progress);
-
- } catch (Exception $e) {
-
- if(!$progress->handle && $this->session->handle) {
- try{$this->session->unlockMachine();$this->session=null;}catch(Exception $e){}
- }
-
- return false;
- }
-
- return array('progress' => $progress->handle);
-
- }
-
- /**
- * Get a list of snapshots for a machine
- *
- * @param array $args array of arguments. See function body for details.
- * @return array list of snapshots
- */
- public function remote_machineGetSnapshots($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- /* @var $machine IMachine */
- $machine = $this->vbox->findMachine($args['vm']);
-
- $response = array('vm' => $args['vm'],
- 'snapshot' => array(),
- 'currentSnapshotId' => null);
-
- /* No snapshots? Empty array */
- if($machine->snapshotCount < 1) {
- return $response;
- } else {
-
- /* @var $s ISnapshot */
- $s = $machine->findSnapshot(null);
- $response['snapshot'] = $this->_snapshotGetDetails($s,true);
- $s->releaseRemote();
- }
-
- $response['currentSnapshotId'] = ($machine->currentSnapshot->handle ? $machine->currentSnapshot->id : '');
- if($machine->currentSnapshot->handle) $machine->currentSnapshot->releaseRemote();
- $machine->releaseRemote();
-
- return $response;
- }
-
-
- /**
- * Return details about snapshot $s
- *
- * @param ISnapshot $s snapshot instance
- * @param boolean $sninfo traverse child snapshots
- * @return array snapshot info
- */
- private function _snapshotGetDetails(&$s,$sninfo=false) {
-
- $children = array();
-
- if($sninfo)
- foreach($s->children as $c) { /* @var $c ISnapshot */
- $children[] = $this->_snapshotGetDetails($c, true);
- $c->releaseRemote();
- }
-
- // Avoid multiple soap calls
- $timestamp = (string)$s->timeStamp;
-
- return array(
- 'id' => $s->id,
- 'name' => $s->name,
- 'description' => $s->description,
- 'timeStamp' => floor($timestamp/1000),
- 'timeStampSplit' => $this->_util_splitTime(time() - floor($timestamp/1000)),
- 'online' => $s->online
- ) + (
- ($sninfo ? array('children' => $children) : array())
- );
- }
-
- /**
- * Return details about storage controllers for machine $m
- *
- * @param IMachine $m virtual machine instance
- * @return array storage controllers' details
- */
- private function _machineGetStorageControllers(&$m) {
-
- $sc = array();
- $scs = $m->storageControllers;
-
- foreach($scs as $c) { /* @var $c IStorageController */
- $sc[] = array(
- 'name' => $c->name,
- 'maxDevicesPerPortCount' => $c->maxDevicesPerPortCount,
- 'useHostIOCache' => $c->useHostIOCache,
- 'minPortCount' => $c->minPortCount,
- 'maxPortCount' => $c->maxPortCount,
- 'portCount' => $c->portCount,
- 'bus' => (string)$c->bus,
- 'controllerType' => (string)$c->controllerType,
- 'mediumAttachments' => $this->_machineGetMediumAttachments($m->getMediumAttachmentsOfController($c->name), $m->id)
- );
- $c->releaseRemote();
- }
-
- for($i = 0; $i < count($sc); $i++) {
-
- for($a = 0; $a < count($sc[$i]['mediumAttachments']); $a++) {
-
- // Value of '' means it is not applicable
- $sc[$i]['mediumAttachments'][$a]['ignoreFlush'] = '';
-
- // Only valid for HardDisks
- if($sc[$i]['mediumAttachments'][$a]['type'] != 'HardDisk') continue;
-
- // Get appropriate key
- $xtra = $this->_util_getIgnoreFlushKey($sc[$i]['mediumAttachments'][$a]['port'], $sc[$i]['mediumAttachments'][$a]['device'], $sc[$i]['controllerType']);
-
- // No such setting for this bus type
- if(!$xtra) continue;
-
- $sc[$i]['mediumAttachments'][$a]['ignoreFlush'] = $m->getExtraData($xtra);
-
- if(trim($sc[$i]['mediumAttachments'][$a]['ignoreFlush']) === '')
- $sc[$i]['mediumAttachments'][$a]['ignoreFlush'] = 1;
- else
- $sc[$i]['mediumAttachments'][$a]['ignoreFlush'] = $sc[$i]['mediumAttachments'][$a]['ignoreFlush'];
-
- }
- }
-
- return $sc;
- }
-
- /**
- * Check medium encryption password
- *
- * @param array $args array of arguments. See function body for details.
- * @return array response data
- */
- public function remote_mediumCheckEncryptionPassword($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- $m = $this->vbox->openMedium($args['medium'],'HardDisk','ReadWrite',false);
-
- $retval = $m->checkEncryptionPassword($args['password']);
-
- $m->releaseRemote();
-
- return $retval;
-
- }
-
- /**
- * Change medium encryption
- *
- * @param array $args array of arguments. See function body for details.
- * @return array response data containing progress id or true
- */
- public function remote_mediumChangeEncryption($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- $m = $this->vbox->openMedium($args['medium'], 'HardDisk', 'ReadWrite', false);
-
- /* @var $progress IProgress */
- $progress = $m->changeEncryption($args['old_password'],
- $args['cipher'], $args['password'], $args['id']);
-
- // Does an exception exist?
- try {
- if($progress->errorInfo->handle) {
- $this->errors[] = new Exception($progress->errorInfo->text);
- $progress->releaseRemote();
- $m->releaseRemote();
- return false;
- }
- } catch (Exception $null) {
- }
-
- if($args['waitForCompletion']) {
- $progress->waitForCompletion(-1);
- $progress->releaseRemote();
- $m->releaseRemote();
- return true;
- }
-
- $this->_util_progressStore($progress);
-
- return array('progress' => $progress->handle);
-
- }
-
- /**
- * Resize a medium. Currently unimplemented in GUI.
- *
- * @param array $args array of arguments. See function body for details.
- * @return array response data containing progress id
- */
- public function remote_mediumResize($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- $m = $this->vbox->openMedium($args['medium'], 'HardDisk', 'ReadWrite', false);
-
- /* @var $progress IProgress */
- $progress = $m->resize($args['bytes']);
-
- // Does an exception exist?
- try {
- if($progress->errorInfo->handle) {
- $this->errors[] = new Exception($progress->errorInfo->text);
- $progress->releaseRemote();
- return false;
- }
- } catch (Exception $null) {
- }
-
- $this->_util_progressStore($progress);
-
- return array('progress' => $progress->handle);
-
- }
-
- /**
- * Clone a medium
- *
- * @param array $args array of arguments. See function body for details.
- * @return array response data containing progress id
- */
- public function remote_mediumCloneTo($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- $format = strtoupper($args['format']);
- /* @var $target IMedium */
- $target = $this->vbox->createMedium($format, $args['location'], 'ReadWrite', 'HardDisk');
- $mid = $target->id;
-
- /* @var $src IMedium */
- $src = $this->vbox->openMedium($args['src'], 'HardDisk', 'ReadWrite', false);
-
- $type = array(($args['type'] == 'fixed' ? 'Fixed' : 'Standard'));
- if($args['split']) $type[] = 'VmdkSplit2G';
-
- /* @var $progress IProgress */
- $progress = $src->cloneTo($target->handle,$type,null);
-
- $src->releaseRemote();
- $target->releaseRemote();
-
- // Does an exception exist?
- try {
- if($progress->errorInfo->handle) {
- $this->errors[] = new Exception($progress->errorInfo->text);
- $progress->releaseRemote();
- return false;
- }
- } catch (Exception $null) {}
-
- $this->_util_progressStore($progress);
-
- return array('progress' => $progress->handle, 'id' => $mid);
-
- }
-
- /**
- * Set medium to a specific type
- *
- * @param array $args array of arguments. See function body for details.
- * @return boolean true on success
- */
- public function remote_mediumSetType($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- /* @var $m IMedium */
- $m = $this->vbox->openMedium($args['medium'], 'HardDisk', 'ReadWrite', false);
- $m->type = $args['type'];
- $m->releaseRemote();
-
- return true;
- }
-
- /**
- * Add iSCSI medium
- *
- * @param array $args array of arguments. See function body for details.
- * @return response data
- */
- public function remote_mediumAddISCSI($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- // {'server':server,'port':port,'intnet':intnet,'target':target,'lun':lun,'enclun':enclun,'targetUser':user,'targetPass':pass}
-
- // Fix LUN
- $args['lun'] = intval($args['lun']);
- if($args['enclun']) $args['lun'] = 'enc'.$args['lun'];
-
- // Compose name
- $name = $args['server'].'|'.$args['target'];
- if($args['lun'] != 0 && $args['lun'] != 'enc0')
- $name .= '|'.$args['lun'];
-
- // Create disk
- /* @var $hd IMedium */
- $hd = $this->vbox->createMedium('iSCSI',$name, 'ReadWrite', 'HardDisk');
-
- if($args['port']) $args['server'] .= ':'.intval($args['port']);
-
- $arrProps = array();
-
- $arrProps["TargetAddress"] = $args['server'];
- $arrProps["TargetName"] = $args['target'];
- $arrProps["LUN"] = $args['lun'];
- if($args['targetUser']) $arrProps["InitiatorUsername"] = $args['targetUser'];
- if($args['targetPass']) $arrProps["InitiatorSecret"] = $args['targetPass'];
- if($args['intnet']) $arrProps["HostIPStack"] = '0';
-
- $hd->setProperties(array_keys($arrProps),array_values($arrProps));
-
- $hdid = $hd->id;
- $hd->releaseRemote();
-
- return array('id' => $hdid);
- }
-
- /**
- * Add existing medium by file location
- *
- * @param array $args array of arguments. See function body for details.
- * @return resposne data containing new medium's id
- */
- public function remote_mediumAdd($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- /* @var $m IMedium */
- $m = $this->vbox->openMedium($args['path'], $args['type'], 'ReadWrite', false);
-
- $mid = $m->id;
- $m->releaseRemote();
-
- return array('id'=>$mid);
- }
-
- /**
- * Get VirtualBox generated machine configuration file name
- *
- * @param array $args array of arguments. See function body for details.
- * @return string filename
- */
- public function remote_vboxGetComposedMachineFilename($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- return $this->vbox->composeMachineFilename($args['name'],($this->settings->phpVboxGroups ? '' : $args['group']),$this->vbox->systemProperties->defaultMachineFolder,null);
-
- }
-
- /**
- * Create base storage medium (virtual hard disk)
- *
- * @param array $args array of arguments. See function body for details.
- * @return response data containing progress id
- */
- public function remote_mediumCreateBaseStorage($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- $format = strtoupper($args['format']);
-
- $type = array(($args['type'] == 'fixed' ? 'Fixed' : 'Standard'));
- if($args['split']) $type[] = 'VmdkSplit2G';
-
- /* @var $hd IMedium */
- $hd = $this->vbox->createMedium($format, $args['file'], 'ReadWrite', 'HardDisk');
-
- /* @var $progress IProgress */
- $progress = $hd->createBaseStorage(intval($args['size'])*1024*1024,$type);
-
- // Does an exception exist?
- try {
- if($progress->errorInfo->handle) {
- $this->errors[] = new Exception($progress->errorInfo->text);
- $progress->releaseRemote();
- return false;
- }
- } catch (Exception $null) {}
-
- $this->_util_progressStore($progress);
-
- $hd->releaseRemote();
-
- return array('progress' => $progress->handle);
-
- }
-
- /**
- * Release medium from all attachments
- *
- * @param array $args array of arguments. See function body for details.
- * @return boolean true
- */
- public function remote_mediumRelease($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- /* @var $m IMedium */
- $m = $this->vbox->openMedium($args['medium'],$args['type'], 'ReadWrite', false);
- $mediumid = $m->id;
-
- // connected to...
- $machines = $m->machineIds;
- $released = array();
- foreach($machines as $uuid) {
-
- // Find medium attachment
- try {
- /* @var $mach IMachine */
- $mach = $this->vbox->findMachine($uuid);
- } catch (Exception $e) {
- $this->errors[] = $e;
- continue;
- }
- $attach = $mach->mediumAttachments;
- $remove = array();
- foreach($attach as $a) {
- if($a->medium->handle && $a->medium->id == $mediumid) {
- $remove[] = array(
- 'controller' => $a->controller,
- 'port' => $a->port,
- 'device' => $a->device);
- break;
- }
- }
- // save state
- $state = (string)$mach->sessionState;
-
- if(!count($remove)) continue;
-
- $released[] = $uuid;
-
- // create session
- $this->session = $this->websessionManager->getSessionObject($this->vbox->handle);
-
- // Hard disk requires machine to be stopped
- if($args['type'] == 'HardDisk' || $state == 'Unlocked') {
-
- $mach->lockMachine($this->session->handle, 'Write');
-
- } else {
-
- $mach->lockMachine($this->session->handle, 'Shared');
-
- }
-
- foreach($remove as $r) {
- if($args['type'] == 'HardDisk') {
- $this->session->machine->detachDevice($r['controller'],$r['port'],$r['device']);
- } else {
- $this->session->machine->mountMedium($r['controller'],$r['port'],$r['device'],null,true);
- }
- }
-
- $this->session->machine->saveSettings();
- $this->session->machine->releaseRemote();
- $this->session->unlockMachine();
- unset($this->session);
- $mach->releaseRemote();
-
- }
- $m->releaseRemote();
-
- return true;
- }
-
- /**
- * Remove a medium
- *
- * @param array $args array of arguments. See function body for details.
- * @return response data possibly containing progress operation id
- */
- public function remote_mediumRemove($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- if(!$args['type']) $args['type'] = 'HardDisk';
-
- /* @var $m IMedium */
- $m = $this->vbox->openMedium($args['medium'],$args['type'], 'ReadWrite', false);
-
- if($args['delete'] && @$this->settings->deleteOnRemove && (string)$m->deviceType == 'HardDisk') {
-
- /* @var $progress IProgress */
- $progress = $m->deleteStorage();
-
- $m->releaseRemote();
-
- // Does an exception exist?
- try {
- if($progress->errorInfo->handle) {
- $this->errors[] = new Exception($progress->errorInfo->text);
- $progress->releaseRemote();
- return false;
- }
- } catch (Exception $null) { }
-
- $this->_util_progressStore($progress);
- return array('progress' => $progress->handle);
-
- } else {
- $m->close();
- $m->releaseRemote();
- }
-
- return true;
- }
-
- /**
- * Get a list of recent media
- *
- * @param array $args array of arguments. See function body for details.
- * @return array of recent media
- */
- public function remote_vboxRecentMediaGet($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- $mlist = array();
- foreach(array(
- array('type'=>'HardDisk','key'=>'GUI/RecentListHD'),
- array('type'=>'DVD','key'=>'GUI/RecentListCD'),
- array('type'=>'Floppy','key'=>'GUI/RecentListFD')) as $r) {
- $list = $this->vbox->getExtraData($r['key']);
- $mlist[$r['type']] = array_filter(explode(';', trim($list,';')));
- }
- return $mlist;
- }
-
- /**
- * Get a list of recent media paths
- *
- * @param array $args array of arguments. See function body for details.
- * @return array of recent media paths
- */
- public function remote_vboxRecentMediaPathsGet($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- $mlist = array();
- foreach(array(
- array('type'=>'HardDisk','key'=>'GUI/RecentFolderHD'),
- array('type'=>'DVD','key'=>'GUI/RecentFolderCD'),
- array('type'=>'Floppy','key'=>'GUI/RecentFolderFD')) as $r) {
- $mlist[$r['type']] = $this->vbox->getExtraData($r['key']);
- }
- return $mlist;
- }
-
-
- /**
- * Update recent medium path list
- *
- * @param array $args array of arguments. See function body for details.
- * @return boolean true on success
- */
- public function remote_vboxRecentMediaPathSave($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- $types = array(
- 'HardDisk'=>'GUI/RecentFolderHD',
- 'DVD'=>'GUI/RecentFolderCD',
- 'Floppy'=>'GUI/RecentFolderFD'
- );
-
- $this->vbox->setExtraData($types[$args['type']], $args['folder']);
-
- return true;
- }
-
- /**
- * Update recent media list
- *
- * @param array $args array of arguments. See function body for details.
- * @return boolean true on success
- */
- public function remote_vboxRecentMediaSave($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- $types = array(
- 'HardDisk'=>'GUI/RecentListHD',
- 'DVD'=>'GUI/RecentListCD',
- 'Floppy'=>'GUI/RecentListFD'
- );
-
- $this->vbox->setExtraData($types[$args['type']], implode(';',array_unique($args['list'])).';');
-
- return true;
-
- }
-
- /**
- * Mount a medium on the VM
- *
- * @param array $args array of arguments. See function body for details.
- * @return boolean true on success
- */
- public function remote_mediumMount($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- // Find medium attachment
- /* @var $machine IMachine */
- $machine = $this->vbox->findMachine($args['vm']);
- $state = (string)$machine->sessionState;
-
- // create session
- $this->session = $this->websessionManager->getSessionObject($this->vbox->handle);
-
- if($state == 'Unlocked') {
- $machine->lockMachine($this->session->handle,'Write');
- $save = true; // force save on closed session as it is not a "run-time" change
- } else {
-
- $machine->lockMachine($this->session->handle, 'Shared');
- }
-
- // Empty medium / eject
- if($args['medium'] == 0) {
- $med = null;
- } else {
- // Host drive
- if(strtolower($args['medium']['hostDrive']) == 'true' || $args['medium']['hostDrive'] === true) {
- // CD / DVD Drive
- if($args['medium']['deviceType'] == 'DVD') {
- $drives = $this->vbox->host->DVDDrives;
- // floppy drives
- } else {
- $drives = $this->vbox->host->floppyDrives;
- }
- foreach($drives as $m) { /* @var $m IMedium */
- if($m->id == $args['medium']['id']) {
- /* @var $med IMedium */
- $med = &$m;
- break;
- }
- $m->releaseRemote();
- }
- // Normal medium
- } else {
- /* @var $med IMedium */
- $med = $this->vbox->openMedium($args['medium']['location'],$args['medium']['deviceType'],'ReadWrite',false);
- }
- }
-
- $this->session->machine->mountMedium($args['controller'],$args['port'],$args['device'],(is_object($med) ? $med->handle : null),true);
-
- if(is_object($med)) $med->releaseRemote();
-
- if($save) $this->session->machine->saveSettings();
-
- $this->session->unlockMachine();
- $machine->releaseRemote();
- unset($this->session);
-
- return true;
- }
-
- /**
- * Get medium details
- *
- * @param IMedium $m medium instance
- * @return array medium details
- */
- private function _mediumGetDetails(&$m) {
-
- $children = array();
- $attachedTo = array();
- $machines = $m->machineIds;
- $hasSnapshots = 0;
-
- foreach($m->children as $c) { /* @var $c IMedium */
- $children[] = $this->_mediumGetDetails($c);
- $c->releaseRemote();
- }
-
- foreach($machines as $mid) {
- $sids = $m->getSnapshotIds($mid);
- try {
- /* @var $mid IMachine */
- $mid = $this->vbox->findMachine($mid);
- } catch (Exception $e) {
- $attachedTo[] = array('machine' => $mid .' ('.$e->getMessage().')', 'snapshots' => array());
- continue;
- }
-
- $c = count($sids);
- $hasSnapshots = max($hasSnapshots,$c);
- for($i = 0; $i < $c; $i++) {
- if($sids[$i] == $mid->id) {
- unset($sids[$i]);
- } else {
- try {
- /* @var $sn ISnapshot */
- $sn = $mid->findSnapshot($sids[$i]);
- $sids[$i] = $sn->name;
- $sn->releaseRemote();
- } catch(Exception $e) { }
- }
- }
- $hasSnapshots = (count($sids) ? 1 : 0);
- $attachedTo[] = array('machine'=>$mid->name,'snapshots'=>$sids);
- $mid->releaseRemote();
- }
-
- // For $fixed value
- $mvenum = new MediumVariant(null, null);
- $variant = 0;
-
- foreach($m->variant as $mv) {
- $variant += $mvenum->ValueMap[(string)$mv];
- }
-
- // Encryption settings
- $encryptionSettings = null;
- if((string)$m->deviceType == 'HardDisk') {
- try {
- list($id, $cipher) = $m->getEncryptionSettings();
- if($id) {
- $encryptionSettings = array(
- 'id' => $id,
- 'cipher' => $cipher,
- );
- }
- } catch (Exception $e) {
- // Pass. Encryption is not configured
- }
-
- }
- return array(
- 'id' => $m->id,
- 'description' => $m->description,
- 'state' => (string)$m->refreshState(),
- 'location' => $m->location,
- 'name' => $m->name,
- 'deviceType' => (string)$m->deviceType,
- 'hostDrive' => $m->hostDrive,
- 'size' => (string)$m->size, /* (string) to support large disks. Bypass integer limit */
- 'format' => $m->format,
- 'type' => (string)$m->type,
- 'parent' => (((string)$m->deviceType == 'HardDisk' && $m->parent->handle) ? $m->parent->id : null),
- 'children' => $children,
- 'base' => (((string)$m->deviceType == 'HardDisk' && $m->base->handle) ? $m->base->id : null),
- 'readOnly' => $m->readOnly,
- 'logicalSize' => ($m->logicalSize/1024)/1024,
- 'autoReset' => $m->autoReset,
- 'hasSnapshots' => $hasSnapshots,
- 'lastAccessError' => $m->lastAccessError,
- 'variant' => $variant,
- 'machineIds' => array(),
- 'attachedTo' => $attachedTo,
- 'encryptionSettings' => $encryptionSettings
- );
-
- }
-
- /**
- * Store a progress operation so that its status can be polled via progressGet()
- *
- * @param IProgress $progress progress operation instance
- * @return string progress operation handle / id
- */
- private function _util_progressStore(&$progress) {
-
- /* Store vbox and session handle */
- $this->persistentRequest['vboxHandle'] = $this->vbox->handle;
- if($this->session->handle) {
- $this->persistentRequest['sessionHandle'] = $this->session->handle;
- }
-
- /* Store server if multiple servers are configured */
- if(@is_array($this->settings->servers) && count($this->settings->servers) > 1)
- $this->persistentRequest['vboxServer'] = $this->settings->name;
-
- return $progress->handle;
- }
-
- /**
- * Get VirtualBox system properties
- * @param array $args array of arguments. See function body for details.
- * @return array of system properties
- */
- public function remote_vboxSystemPropertiesGet($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- $mediumFormats = array();
-
- // Shorthand
- $sp = $this->vbox->systemProperties;
-
- // capabilities
- $mfCap = new MediumFormatCapabilities(null,'');
- foreach($sp->mediumFormats as $mf) { /* @var $mf IMediumFormat */
- $exts = $mf->describeFileExtensions();
- $dtypes = array();
- foreach($exts[1] as $t) $dtypes[] = (string)$t;
- $caps = array();
- foreach($mf->capabilities as $c) {
- $caps[] = (string)$c;
- }
-
- $mediumFormats[] = array('id'=>$mf->id,'name'=>$mf->name,'extensions'=>array_map('strtolower',$exts[0]),'deviceTypes'=>$dtypes,'capabilities'=>$caps);
-
- }
-
- $scs = array();
-
- $scts = array('LsiLogic',
- 'BusLogic',
- 'IntelAhci',
- 'PIIX4',
- 'ICH6',
- 'I82078',
- 'USB');
-
- foreach($scts as $t) {
- $scs[$t] = $sp->getStorageControllerHotplugCapable($t);
- }
-
- return array(
- 'minGuestRAM' => (string)$sp->minGuestRAM,
- 'maxGuestRAM' => (string)$sp->maxGuestRAM,
- 'minGuestVRAM' => (string)$sp->minGuestVRAM,
- 'maxGuestVRAM' => (string)$sp->maxGuestVRAM,
- 'minGuestCPUCount' => (string)$sp->minGuestCPUCount,
- 'maxGuestCPUCount' => (string)$sp->maxGuestCPUCount,
- 'autostartDatabasePath' => (@$this->settings->vboxAutostartConfig ? $sp->autostartDatabasePath : ''),
- 'infoVDSize' => (string)$sp->infoVDSize,
- 'networkAdapterCount' => 8, // static value for now
- 'maxBootPosition' => (string)$sp->maxBootPosition,
- 'defaultMachineFolder' => (string)$sp->defaultMachineFolder,
- 'defaultHardDiskFormat' => (string)$sp->defaultHardDiskFormat,
- 'homeFolder' => $this->vbox->homeFolder,
- 'VRDEAuthLibrary' => (string)$sp->VRDEAuthLibrary,
- 'defaultAudioDriver' => (string)$sp->defaultAudioDriver,
- 'defaultVRDEExtPack' => $sp->defaultVRDEExtPack,
- 'serialPortCount' => $sp->serialPortCount,
- 'parallelPortCount' => $sp->parallelPortCount,
- 'mediumFormats' => $mediumFormats,
- 'scs' => $scs
- );
- }
-
- /**
- * Get a list of VM log file names
- *
- * @param array $args array of arguments. See function body for details.
- * @return array of log file names
- */
- public function remote_machineGetLogFilesList($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- /* @var $m IMachine */
- $m = $this->vbox->findMachine($args['vm']);
-
- $logs = array();
-
- try { $i = 0; while($l = $m->queryLogFilename($i++)) $logs[] = $l;
- } catch (Exception $null) {}
-
- $lf = $m->logFolder;
- $m->releaseRemote();
-
- return array('path' => $lf, 'logs' => $logs);
-
- }
-
- /**
- * Get VM log file contents
- *
- * @param array $args array of arguments. See function body for details.
- * @return string log file contents
- */
- public function remote_machineGetLogFile($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- /* @var $m IMachine */
- $m = $this->vbox->findMachine($args['vm']);
- $log = '';
- try {
- // Read in 8k chunks
- while($l = $m->readLog(intval($args['log']),strlen($log),8192)) {
- if(!count($l) || !strlen($l[0])) break;
- $log .= base64_decode($l[0]);
- }
- } catch (Exception $null) {}
- $m->releaseRemote();
-
- // Attempt to UTF-8 encode string or json_encode may choke
- // and return an empty string
- if(function_exists('utf8_encode'))
- return utf8_encode($log);
-
- return $log;
- }
-
- /**
- * Get a list of USB devices attached to a given VM
- *
- * @param array $args array of arguments. See function body for details.
- * @return array list of devices
- */
- public function remote_consoleGetUSBDevices($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- /* @var $machine IMachine */
- $machine = $this->vbox->findMachine($args['vm']);
- $this->session = $this->websessionManager->getSessionObject($this->vbox->handle);
- $machine->lockMachine($this->session->handle, 'Shared');
-
- $response = array();
- foreach($this->session->console->USBDevices as $u) { /* @var $u IUSBDevice */
- $response[$u->id] = array('id'=>$u->id,'remote'=>$u->remote);
- $u->releaseRemote();
- }
-
- $this->session->unlockMachine();
- unset($this->session);
- $machine->releaseRemote();
-
- return $response;
-
- }
-
- /**
- * Return a string representing the VirtualBox ExtraData key
- * for this port + device + bus type IgnoreFlush setting
- *
- * @param integer port medium attachment port number
- * @param integer device medium attachment device number
- * @param string cType controller type
- * @return string extra data setting string
- */
- private function _util_getIgnoreFlushKey($port,$device,$cType) {
-
- $cTypes = array(
- 'piix3' => 'piix3ide',
- 'piix4' => 'piix3ide',
- 'ich6' => 'piix3ide',
- 'intelahci' => 'ahci',
- 'lsilogic' => 'lsilogicscsi',
- 'buslogic' => 'buslogic',
- 'lsilogicsas' => 'lsilogicsas'
- );
-
- if(!isset($cTypes[strtolower($cType)])) {
- $this->errors[] = new Exception('Invalid controller type: ' . $cType);
- return '';
- }
-
- $lun = ((intval($device)*2) + intval($port));
-
- return str_replace('[b]',$lun,str_replace('[a]',$cTypes[strtolower($cType)],"VBoxInternal/Devices/[a]/0/LUN#[b]/Config/IgnoreFlush"));
-
- }
-
- /**
- * Get a newly generated MAC address from VirtualBox
- *
- * @param array $args array of arguments. See function body for details
- * @return string mac address
- */
- public function remote_vboxGenerateMacAddress($args) {
-
- // Connect to vboxwebsrv
- $this->connect();
-
- return $this->vbox->host->generateMACAddress();
-
- }
-
- /**
- * Set group definition
- *
- * @param array $args array of arguments. See function body for details
- * @return boolean true on success
- */
- public function remote_vboxGroupDefinitionsSet($args) {
-
- $this->connect();
-
- // Save a list of valid paths
- $validGroupPaths = array();
-
- $groupKey = ($this->settings->phpVboxGroups ? vboxconnector::phpVboxGroupKey : 'GUI/GroupDefinitions');
-
- // Write out each group definition
- foreach($args['groupDefinitions'] as $groupDef) {
-
- $this->vbox->setExtraData($groupKey.$groupDef['path'], $groupDef['order']);
- $validGroupPaths[] = $groupDef['path'];
-
- }
-
- // Remove any unused group definitions
- $keys = $this->vbox->getExtraDataKeys();
- foreach($keys as $k) {
- if(strpos($k,$groupKey) !== 0) continue;
- if(array_search(substr($k,strlen($groupKey)), $validGroupPaths) === false)
- $this->vbox->setExtraData($k,'');
- }
-
- return true;
- }
-
- /**
- * Return group definitions
- *
- * @param array $args array of arguments. See function body for details
- * @return array group definitions
- */
- public function remote_vboxGroupDefinitionsGet($args) {
-
- $this->connect();
-
- $response = array();
-
- $keys = $this->vbox->getExtraDataKeys();
-
- $groupKey = ($this->settings->phpVboxGroups ? vboxconnector::phpVboxGroupKey : 'GUI/GroupDefinitions');
- foreach($keys as $grouppath) {
-
- if(strpos($grouppath,$groupKey) !== 0) continue;
-
- $subgroups = array();
- $machines = array();
-
- $response[] = array(
- 'name' => substr($grouppath,strrpos($grouppath,'/')+1),
- 'path' => substr($grouppath,strlen($groupKey)),
- 'order' => $this->vbox->getExtraData($grouppath)
- );
- }
-
- return $response;
-
- }
-
- /**
- * Format a time span in seconds into days / hours / minutes / seconds
- * @param integer $t number of seconds
- * @return array containing number of days / hours / minutes / seconds
- */
- private function _util_splitTime($t) {
-
- $spans = array(
- 'days' => 86400,
- 'hours' => 3600,
- 'minutes' => 60,
- 'seconds' => 1);
-
- $time = array();
-
- foreach($spans as $k => $v) {
- if(!(floor($t / $v) > 0)) continue;
- $time[$k] = floor($t / $v);
- $t -= floor($time[$k] * $v);
- }
-
- return $time;
- }
-
-
- /**
- * Return VBOX result code text for result code
- *
- * @param integer result code number
- * @return string result code text
- */
- private function _util_resultCodeText($c) {
-
- $rcodes = new ReflectionClass('VirtualBox_COM_result_codes');
- $rcodes = array_flip($rcodes->getConstants());
- $rcodes['0x80004005'] = 'NS_ERROR_FAILURE';
-
- return @$rcodes['0x'.strtoupper(dechex($c))] . ' (0x'.strtoupper(dechex($c)).')';
- }
- }
|