You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.html 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" >
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <!-- $Id: index.html 595 2015-04-17 09:50:36Z imoore76 $ -->
  4. <!-- Copyright (C) 2010-2015 Ian Moore (imoore76 at yahoo dot com) -->
  5. <head>
  6. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
  7. <meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" />
  8. <meta http-equiv="Expires" content="0"/>
  9. <meta http-equiv="Cache-Control" content ="no-cache"/>
  10. <meta http-equiv="Cache-Control" content ="no-store, must-revalidate, max-age=0"/>
  11. <meta http-equiv="Cache-Control" content ="post-check=0, pre-check=0"/>
  12. <meta http-equiv="Pragma" content="no-cache"/>
  13. <!-- Icon && title -->
  14. <link rel="shortcut icon" href="images/vbox/OSE/VirtualBox_win.ico"/>
  15. <link rel="icon" href="images/vbox/OSE/VirtualBox_win.ico"/>
  16. <title>phpVirtualBox - VirtualBox Web Console</title>
  17. <!-- Style sheets -->
  18. <link rel="stylesheet" type="text/css" href="css/jquery-ui.css"/>
  19. <link rel="stylesheet" type="text/css" href="css/jquery.projectPlugins.css"/>
  20. <link rel="stylesheet" type="text/css" href="css/tipped.css" />
  21. <link rel="stylesheet" type="text/css" href="css/layout.css"/>
  22. <!-- External or jQuery related scripts -->
  23. <script type="text/javascript" src="js/jquery-1.11.2.min.js"></script>
  24. <script type="text/javascript" src="js/jquery-ui-1.11.4.min.js"></script>
  25. <script type="text/javascript" src="js/jquery.tipped-2.1b.min.js"></script>
  26. <script type="text/javascript" src="js/jquery.scrollTo-min.js"></script>
  27. <script type="text/javascript" src="js/jquery.jec-1.3.1.js"></script>
  28. <!-- Oracle RDP Control -->
  29. <script type="text/javascript" src="rdpweb/webclient.js"></script>
  30. <script type="text/javascript" src="rdpweb/swfobject.js"></script>
  31. <!-- Internal / project related scripts -->
  32. <script type="text/javascript" src="endpoints/config.js"></script>
  33. <script type="text/javascript" src="js/jquery.projectPlugins.js"></script>
  34. <script type="text/javascript" src="js/phpvirtualbox.js"></script>
  35. <script type="text/javascript" src="js/utils.js"></script>
  36. <script type="text/javascript" src="js/eventlistener.js"></script>
  37. <script type="text/javascript" src="js/chooser.js"></script>
  38. <script type="text/javascript" src="js/datamediator.js"></script>
  39. <script type="text/javascript" src="js/dialogs.js"></script>
  40. <script type="text/javascript" src="js/canvasimages.js"></script>
  41. <!-- Main Setup -->
  42. <script type='text/javascript'>
  43. $(document).ready(function(){
  44. /* Synchronously load requirements */
  45. for(var i = 0; i < vboxEndpointConfig.require.length; i++) {
  46. $.ajax({
  47. type: "GET",
  48. url: vboxEndpointConfig.require[i],
  49. async: false,
  50. dataType: "script"
  51. });
  52. }
  53. /*
  54. * Parse cookies
  55. */
  56. vboxParseCookies();
  57. /*
  58. *
  59. * Begin sanity checks
  60. *
  61. */
  62. /**
  63. * Check that someone isn't accessing this from their local filesystem
  64. */
  65. try {
  66. if(window.location.toString().search('file:') == 0) {
  67. vboxAlert("You are accessing phpVirtualBox from your local filesystem.\
  68. phpVirtualBox must be accessed through your web browser. E.g. \
  69. http://localhost/phpVirtualBox (its actual URL may vary).");
  70. return;
  71. }
  72. } catch(err) {
  73. // noop
  74. }
  75. /*
  76. * If everything loaded correctly, trans() should be defined in
  77. * js/language.php and language data should be present.
  78. * If not, there is a PHP error somewhere.
  79. */
  80. if(typeof trans != "function" || typeof __vboxLangData == "undefined") {
  81. trans = function(s){return s;};
  82. vboxAlert("An unknown PHP error occurred. This is most likely a syntax error in\
  83. config.php in phpVirtualBox's folder. The most common errors are an unclosed\
  84. quote or a missing\
  85. semicolon in a configuration item that has been entered (e.g.\
  86. location, username, or password).<p>Depending on your PHP configuration,\
  87. navigating directly to <a href='config.php'>config.php</a> in your web\
  88. browser may display the PHP error message.</p>\
  89. <p>If find that this is not the case,\
  90. or have no idea what this error message means, please raise the issue\
  91. at <a href='http://sourceforge.net/p/phpvirtualbox/discussion/help/'\
  92. >http://sourceforge.net/p/phpvirtualbox/discussion/help/",{'width':'50%'});
  93. return;
  94. }
  95. // Sanity checks passed. Begin processing
  96. // Check for server setting (?server=xxxx in URL)
  97. if(location.search) {
  98. var query = location.search.substr(1).split('&');
  99. for(var kv in query) {
  100. kv = query[kv].split('=');
  101. if(kv[0] == 'server') {
  102. vboxSetCookie('vboxServer',unescape(kv[1]));
  103. location = location.href.substr(0,location.href.length-location.search.length);
  104. return;
  105. }
  106. }
  107. }
  108. /*
  109. * Resizable panes functionality
  110. */
  111. $('#vboxResizeBar').draggable({cursor:(jQuery.browser.opera ? 'e-resize' : 'col-resize'),axis:'x',zIndex:99,helper:function(){
  112. $('#vboxResizeBarTmp').remove();
  113. var h = $('#vboxResizeBar').parent().height();
  114. return $('#vboxResizeBar').clone(false)
  115. .attr({'id':'vboxResizeBarTmp'}).unbind('mouseleave')
  116. .css({'background':'#ccc','height':h+'px'});
  117. },scroll:false,'start':function(e,ui){
  118. $('#vboxResizeOverlay').remove();
  119. $('body').disableSelection().css({'cursor':(jQuery.browser.opera ? 'e-resize' : 'col-resize')});
  120. $('#vboxPane').append($('<div />').attr({'id':'vboxResizeOverlay','style':'width:100%;height:100%;border:0px;margin:0px;padding:0px;position:absolute;top:0px;left:0px;z-index:10;cursor:'+(jQuery.browser.opera ? 'e-resize' : 'col-resize')}));
  121. $('#vboxResizeBar').data('vboxX',e.pageX);
  122. },'stop':function(e){
  123. $('#vboxResizeBarTmp').remove();
  124. $('#vboxResizeOverlay').remove();
  125. $('body').enableSelection().css({'cursor':'default'});
  126. var nx = $('#vboxChooserDiv').width() + (e.pageX - $('#vboxResizeBar').data('vboxX'));
  127. $('#vboxChooserDiv').css('width',(nx)+'px');
  128. vboxSetLocalDataItem("vboxPaneX",($('#vboxChooserDiv').width()));
  129. $('#vboxChooserPane').css('width',$('#vboxChooserDiv').css('width'));
  130. $(window).trigger('resize');
  131. }}).css('cursor',(jQuery.browser.opera ? 'e-resize' : 'col-resize')).parent().disableSelection();
  132. /*
  133. progress resize n / s
  134. */
  135. $('#vboxResizeBarProgress').draggable({cursor:(jQuery.browser.opera ? 'n-resize' : 'row-resize'),axis:'y',zIndex:99,helper:function(){
  136. $('#vboxResizeBarTmp').remove();
  137. return $('#vboxResizeBarProgress').clone(false)
  138. .attr({'id':'vboxResizeBarTmp'})
  139. .css({'background':'#ccc','position':'absolute','left':'0','right':'0','margin-left':'auto','margin-right':'auto'});
  140. },scroll:false,'start':function(e,ui){
  141. $('#vboxResizeOverlay').remove();
  142. $('body').disableSelection().css({'cursor':(jQuery.browser.opera ? 'n-resize' : 'row-resize')});
  143. $('#vboxPane').append($('<div />').attr({'id':'vboxResizeOverlay','style':'width:100%;height:100%;border:0px;margin:0px;padding:0px;position:absolute;top:0px;left:0px;z-index:10;cursor:'+(jQuery.browser.opera ? 'n-resize' : 'row-resize')}));
  144. $('#vboxResizeBarProgress').data('vboxY',e.pageY);
  145. },'stop':function(e){
  146. $('#vboxResizeBarTmp').remove();
  147. $('#vboxResizeOverlay').remove();
  148. $('body').enableSelection().css({'cursor':'default'});
  149. var nx = $('#vboxProgressOps').height() + ($('#vboxResizeBarProgress').data('vboxY') - e.pageY);
  150. $('#vboxProgressOps').css({'height':(nx)+'px','overflow':'auto'}).parent().css({'height':(nx)+'px'});
  151. vboxSetLocalDataItem("vboxPaneY",($('#vboxProgressOps').height()));
  152. $('#vboxResizeBarProgressEW').css({'height':(vboxGetLocalDataItem("vboxPaneY")-4)+'px'});
  153. $(window).trigger('resize');
  154. }}).css('cursor',(jQuery.browser.opera ? 'n-resize' : 'row-resize')).parent().disableSelection();
  155. /*
  156. Progress resize E / W
  157. */
  158. var vboxOpsPaneEW = 400;
  159. if(vboxGetLocalDataItem('vboxOpsPaneEW')) {
  160. vboxOpsPaneEW = vboxGetLocalDataItem('vboxOpsPaneEW');
  161. } else {
  162. vboxSetLocalDataItem('vboxOpsPaneEW', vboxOpsPaneEW);
  163. }
  164. $('#vboxResizeBarProgressEW').css({'left':vboxOpsPaneEW+'px','top':'0'});
  165. // inject CSS
  166. $('head').append('<style type="text/css" id="vboxProgressOpsStyle">div.vboxProgressOpTitle { width: '+vboxOpsPaneEW+'px; }</style>');
  167. // Show draggablebar onmouseenter
  168. $('#vboxProgressOps').hover(function(){
  169. if($(this).children().length == 1) return;
  170. $('#vboxResizeBarProgressEW').css({'display':'inline-block','height':($(this)[0].scrollHeight-2)+'px'});
  171. },function(){
  172. $('#vboxResizeBarProgressEW').css({'display':'none'});
  173. });
  174. // Draggable bar
  175. $('#vboxResizeBarProgressEW').draggable({cursor:(jQuery.browser.opera ? 'e-resize' : 'col-resize'),axis:'x',zIndex:99,helper:function(){
  176. $('#vboxResizeBarTmp').remove();
  177. return $('#vboxResizeBarProgressEW').clone(false)
  178. .attr({'id':'vboxResizeBarProgressEWTmp'}).css({'background':'#ccc'});
  179. },scroll:false,'start':function(e,ui){
  180. $('#vboxResizeOverlay').remove();
  181. $('body').disableSelection().css({'cursor':(jQuery.browser.opera ? 'e-resize' : 'col-resize')});
  182. $('#vboxPane').append($('<div />').attr({'id':'vboxResizeOverlay','style':'width:100%;height:100%;border:0px;margin:0px;padding:0px;position:absolute;top:0px;left:0px;z-index:10;cursor:'+(jQuery.browser.opera ? 'e-resize' : 'col-resize')}));
  183. $('#vboxResizeBarProgressEW').data('vboxX',e.pageX);
  184. },'stop':function(e){
  185. $('#vboxResizeBarTmp').remove();
  186. $('#vboxResizeOverlay').remove();
  187. $('body').enableSelection().css({'cursor':'default'});
  188. var nx = parseInt(vboxGetLocalDataItem('vboxOpsPaneEW')) + (e.pageX - $('#vboxResizeBarProgressEW').data('vboxX'));
  189. $('#vboxResizeBarProgressEW').css({'left':nx+'px'});
  190. vboxSetLocalDataItem('vboxOpsPaneEW',nx);
  191. // re-inject CSS
  192. $('#vboxProgressOpsStyle').empty().remove();
  193. $('head').append('<style type="text/css" id="vboxProgressOpsStyle">div.vboxProgressOpTitle { width: '+nx+'px; }</style>');
  194. }}).css('cursor',(jQuery.browser.opera ? 'e-resize' : 'col-resize'));
  195. /*
  196. * Resize panes when the window changes sizes
  197. */
  198. $(window).resize(function(){
  199. // Hide
  200. $('#vboxChooserResizePane').children().children().css({'display':'none'});
  201. var h = $('#vboxResize').innerHeight();
  202. $('#vboxChooserResizePane').children().children().css({'height':h+'px','overflow-y':'auto','overflow-x':'hidden','display':''});
  203. // special for resize bar
  204. $('#vboxResizeBar').css({'height':(h-10)+'px'});
  205. });
  206. /*
  207. * Refresh data when host changes
  208. */
  209. $('#vboxPane').on('hostChange',function(){
  210. var l = new vboxLoader();
  211. l.add('getConfig',function(d){$('#vboxPane').data('vboxConfig',d.responseData);$('#vboxPane').trigger('configLoaded');});
  212. l.add('vboxGetGuestOSTypes',function(d){$('#vboxPane').data('vboxOSTypes',d.responseData);});
  213. l.add('vboxSystemPropertiesGet',function(d){$('#vboxPane').data('vboxSystemProperties',d.responseData);});
  214. l.add('vboxGetMedia',function(d){$('#vboxPane').data('vboxMedia',d.responseData);});
  215. l.add('hostGetDetails',function(d){$('#vboxPane').data('vboxHostDetails',d.responseData);});
  216. l.add('vboxRecentMediaGet',function(d){$('#vboxPane').data('vboxRecentMedia',d.responseData);});
  217. l.add('vboxRecentMediaPathsGet',function(d){$('#vboxPane').data('vboxRecentMediaPaths',d.responseData);});
  218. l.add('vboxGetEnumerationMap',function(d){$('#vboxPane').data('vboxMediumVariants',d.responseData);},{'class':'MediumVariant','ValueMap':1});
  219. l.onLoad = function(){
  220. $('#vboxPane').trigger('hostChanged');
  221. };
  222. l.run();
  223. });
  224. /*
  225. * Load panes all and data after valid login
  226. */
  227. $('#vboxPane').on('login', function() {
  228. var l = new vboxLoader();
  229. // Get data and store it using data()
  230. l.add('getConfig',function(d){$('#vboxPane').data('vboxConfig',d.responseData);$('#vboxPane').trigger('configLoaded');});
  231. l.add('vboxGetGuestOSTypes',function(d){$('#vboxPane').data('vboxOSTypes',d.responseData);});
  232. l.add('vboxSystemPropertiesGet',function(d){$('#vboxPane').data('vboxSystemProperties',d.responseData);});
  233. l.add('vboxGetMedia',function(d){$('#vboxPane').data('vboxMedia',d.responseData);});
  234. l.add('hostGetDetails',function(d){$('#vboxPane').data('vboxHostDetails',d.responseData);});
  235. l.add('vboxRecentMediaGet',function(d){$('#vboxPane').data('vboxRecentMedia',d.responseData);});
  236. l.add('vboxRecentMediaPathsGet',function(d){$('#vboxPane').data('vboxRecentMediaPaths',d.responseData);});
  237. l.add('vboxGetEnumerationMap',function(d){$('#vboxPane').data('vboxMediumVariants',d.responseData);},{'class':'MediumVariant','ValueMap':1});
  238. // Load HTML panes and append them to their respective locations
  239. l.addFileToDOM('panes/chooser.html',$('#vboxChooserPane'));
  240. l.addFileToDOM('panes/topmenu.html');
  241. l.addFileToDOM('panes/toolbar.html');
  242. l.addFileToDOM('panes/tabs.html',$('#vboxPaneTabContent'));
  243. l.onLoad = function() {
  244. // Resize to last setting
  245. if(vboxGetLocalDataItem('vboxPaneX')) {
  246. $('#vboxChooserDiv').css('width',(vboxGetLocalDataItem('vboxPaneX'))+'px');
  247. } else {
  248. vboxSetLocalDataItem('vboxPaneX', $('#vboxChooserDiv').innerWidth());
  249. }
  250. if(vboxGetLocalDataItem('vboxPaneY')) {
  251. var nx = vboxGetLocalDataItem('vboxPaneY');
  252. $('#vboxProgressOps').css({'height':(nx)+'px'}).parent().css({'height':(nx)+'px'});
  253. } else {
  254. vboxSetLocalDataItem('vboxPaneY', $('#vboxProgressOps').height());
  255. }
  256. $('#vboxResizeBarProgressEW').css({'height':(vboxGetLocalDataItem("vboxPaneY")-4)+'px'});
  257. // Let everyone know that no vms are selected
  258. $('#vboxPane').trigger('vmSelectionListChanged',[vboxChooser]);
  259. };
  260. // Trigger resize event to size panes
  261. l.onShow = function() { $(window).trigger('resize'); };
  262. l.hideRoot = true;
  263. l.run();
  264. });
  265. /**
  266. * Check for valid session and display login box if one does not exist
  267. * @params {Boolean} tried - true if login was attempted before this call
  268. */
  269. var vboxCheckSession = function(tried) {
  270. // check session info
  271. if($('#vboxPane').data('vboxSession') && $('#vboxPane').data('vboxSession').valid) {
  272. // Session is valid, trigger login
  273. $('#vboxPane').trigger('login');
  274. return;
  275. }
  276. // Was there an error? Assume it was displayed and just return from function
  277. if($('#vboxPane').data('vboxSession') && !$('#vboxPane').data('vboxSession').success) {
  278. return;
  279. }
  280. // No valid session. Show login pane
  281. $('#vboxLogin').find('input[name=password]').val('');
  282. $('#vboxLogin').dialog('open');
  283. if(!$('#vboxLogin').find('input[name=username]').val()) $('#vboxLogin').find('input[name=username]').focus();
  284. else $('#vboxLogin').find('input[name=password]').focus();
  285. // Display error if we tried to log in
  286. if(tried) {
  287. vboxAlert(trans('Invalid username or password.','UIUsers'),{'width':'400px'});
  288. }
  289. };
  290. /** Load login form */
  291. var login = new vboxLoader();
  292. login.add('getSession',function(d){$('#vboxPane').data('vboxSession',$.extend({'success':d.success},d.responseData));});
  293. login.addFileToDOM('panes/login.html');
  294. login.onLoad = function(loader) {
  295. var buttons = {};
  296. buttons[trans('Log in','UIUsers')] = function() {
  297. // Login button triggers login attempt
  298. var u = $('#vboxLogin').find('input[name=username]').val();
  299. var p = $('#vboxLogin').find('input[name=password]').val();
  300. if(!(u&&p)) return;
  301. $('#vboxLogin').dialog('close');
  302. // A valid login should create a valid session
  303. var trylogin = new vboxLoader();
  304. trylogin.add('login',function(d){$('#vboxPane').data('vboxSession',$.extend({'success':d.success},d.responseData));},{'u':u,'p':p});
  305. trylogin.onLoad = function() { vboxCheckSession(true);};
  306. trylogin.run();
  307. };
  308. // Create but do not open dialog
  309. if($.browser.webkit) heightadd = 5;
  310. else heightadd = 0;
  311. $('#vboxLogin').dialog({'closeOnEscape':false,'width':300,'height':'auto','buttons':buttons,'modal':true,'autoOpen':false,'dialogClass':'vboxDialogContent','title':'<img src="images/vbox/OSE/about_16px.png" class="vboxDialogTitleIcon" /> phpVirtualBox :: ' + trans('Log in','UIUsers')});
  312. $('#vboxLogin').find('input[name=username]').first().focus();
  313. // Trick loader into not showing root pane again
  314. loader.hideRoot = false;
  315. // Login form is loaded, run check for valid session
  316. vboxCheckSession();
  317. };
  318. login.hideRoot = true;
  319. login.run();
  320. }); // </ document.ready event >
  321. </script>
  322. </head>
  323. <body>
  324. <div id='vboxPane' style='height: 100%; margin: 0px; padding: 0px;'>
  325. <table id='vboxTableMain' cellpadding=0 cellspacing=0 style="height: 100%; width: 100%; padding: 0px; margin: 0px; border: 0px; border-spacing: 0px;">
  326. <tr style='vertical-align: middle;'>
  327. <td style='height:20px;border:0px;padding:0px;margin:0px;border-spacing:0px;'>
  328. <div id='vboxMenu'>
  329. <!--
  330. Top menu bar
  331. -->
  332. </div>
  333. </td>
  334. </tr>
  335. <tr style='vertical-align: middle;'>
  336. <td id='vboxToolbarMain' style='height: 1%' class='vboxToolbarGrad'>
  337. <!--
  338. VM list toolbar
  339. -->
  340. <div id='vboxPaneToolbar'></div>
  341. <!--
  342. Tabs / buttons
  343. -->
  344. <div id='vboxTabsList'></div>
  345. </td>
  346. </tr>
  347. <tr style='vertical-align: top;'>
  348. <td style='border:0px;padding:0px;margin:0px;border-spacing:0px;' id='vboxResize'>
  349. <table style='width:100%;border:0px;padding:0px;border-spacing:0px;'>
  350. <tr id='vboxChooserResizePane' style='vertical-align: top;'>
  351. <td id="vboxChooserPane" style='padding:0px;border-spacing:0px;margin:0px;'>
  352. <!--
  353. VM List
  354. -->
  355. </td>
  356. <td id='vboxResizeTD' style='border: 0px; margin: 0px; padding: 0px; text-align: center;'>
  357. <div style='margin:0px;padding:0px;width:4px;height:100%;'>
  358. <div style='position: absolute; margin: 0px; padding:2px; width: 0px; height: 100%;' id='vboxResizeBar' ></div>
  359. </div>
  360. </td>
  361. <td id="vboxPaneTabContent" style='width:100%;border:0px;padding:0px;border-spacing:0px;margin:0px'>
  362. <!--
  363. Tab content
  364. -->
  365. </td>
  366. </tr>
  367. </table>
  368. </td>
  369. </tr>
  370. <!--
  371. Progress operation list resize bar
  372. -->
  373. <tr style='padding: 0px; margin: 0px; vertical-align: middle;'>
  374. <td id='vboxResizeTDProgress' style='border: 0px; margin: 0px; padding: 0px; text-align: center; height: 5px; vertical-align: middle'>
  375. <div style='width:99%; margin:0 auto; padding:2px;' id='vboxResizeBarProgress' ></div>
  376. </td>
  377. </tr>
  378. <tr style='vertical-align: top; padding: 0px;'>
  379. <td style='border:0px;padding:0px;margin:0px;border-spacing:0px;height:1%'>
  380. <div id='vboxProgressOps' style='height:80px;overflow:auto;position:relative'>
  381. <!--
  382. Resize bar for E/ W
  383. -->
  384. <div style="position:absolute;z-index:1;margin:0px;border:0px;padding:1px;width: 0px;background:#aaa;display:none;" id='vboxResizeBarProgressEW' ></div>
  385. <!--
  386. Progress operation list
  387. -->
  388. </div>
  389. </td>
  390. </tr>
  391. </table>
  392. </div>
  393. </body>
  394. </html>