diff options
Diffstat (limited to 'endpoints/screen.php')
-rw-r--r-- | endpoints/screen.php | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/endpoints/screen.php b/endpoints/screen.php new file mode 100644 index 0000000..f8f9e68 --- /dev/null +++ b/endpoints/screen.php @@ -0,0 +1,224 @@ +<?php +/** + * Virtual machine PNG screenshot generation + * + * @author Ian Moore (imoore76 at yahoo dot com) + * @copyright Copyright (C) 2010-2015 Ian Moore (imoore76 at yahoo dot com) + * @version $Id: screen.php 591 2015-04-11 22:40:47Z imoore76 $ + * @package phpVirtualBox + * + */ + +# Turn off PHP notices +error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT & ~E_WARNING); + +require_once(dirname(__FILE__).'/lib/config.php'); +require_once(dirname(__FILE__).'/lib/utils.php'); +require_once(dirname(__FILE__).'/lib/vboxconnector.php'); + + +// Allow caching of some screenshot data +@Header('ETag: "' . $_REQUEST['vm'].'_'.$_REQUEST['randid'].'"'); +session_cache_limiter('private_no_expire'); + +// Check for valid session +global $_SESSION; +session_init(); +if(!@$_SESSION['valid']) { + return; +} + +// Clean request +$_REQUEST = array_merge(@$_GET,@$_POST); + +$settings = new phpVBoxConfigClass(); +$vbox = new vboxconnector(); +$vbox->connect(); + +// Set width. Else assume we want real time updates if VM is running below +if($_REQUEST['width']) { + $force_width = $_REQUEST['width']; +} + +try { + + // Is VM Specified + if(!$_REQUEST['vm']) { + echo("Please specify a VM to take a screen shot of. E.g. http://webserver/phpvirtualbox/screen.php?vm=VMName"); + exit; + } + + $machine = $vbox->vbox->findMachine($_REQUEST['vm']); + + // Is snapshot specified? + if($_REQUEST['snapshot']) { + + $snapshot = $machine->findSnapshot($_REQUEST['snapshot']); + $machine->releaseRemote(); + $machine = &$snapshot->machine; + + } else { + + // Get machine state + switch($machine->state->__toString()) { + case 'Running': + case 'Saved': + case 'Restoring': + break; + default: + $machine->releaseRemote(); + throw new Exception('The specified virtual machine is not in a Running state.'); + } + + } + + // Date last modified + $dlm = floor($machine->lastStateChange/1000); + + // Set last modified header + header("Last-Modified: " . gmdate("D, d M Y H:i:s", $dlm) . " GMT"); + + $_REQUEST['vm'] = $machine->id; + + + + // Take active screenshot if machine is running + if(!$_REQUEST['snapshot'] && $machine->state->__toString() == 'Running') { + + // Let the browser cache images for 3 seconds + $ctime = 0; + if(strpos($_SERVER['HTTP_IF_NONE_MATCH'],'_')) { + $ctime = preg_replace("/.*_/",str_replace('"','',$_SERVER['HTTP_IF_NONE_MATCH'])); + } else if(strpos($_ENV['HTTP_IF_NONE_MATCH'],'_')) { + $ctime = preg_replace("/.*_/",str_replace('"','',$_ENV['HTTP_IF_NONE_MATCH'])); + } else if(strpos($_SERVER['HTTP_IF_MODIFIED_SINCE'],'GMT')) { + $ctime = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']); + } else if(strpos($_ENV['HTTP_IF_MODIFIED_SINCE'],'GMT')) { + $ctime = strtotime($_ENV['HTTP_IF_MODIFIED_SINCE']); + } + + if($ctime >= (time()-3)) { + if (strpos(strtolower(php_sapi_name()),'cgi') !== false) { + Header("Status: 304 Not Modified"); + } else { + Header("HTTP/1.0 304 Not Modified"); + } + exit; + } + + + header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); + + $vbox->session = $vbox->websessionManager->getSessionObject($vbox->vbox->handle); + $machine->lockMachine($vbox->session->handle,'Shared'); + $machine->releaseRemote(); + + + $res = $vbox->session->console->display->getScreenResolution(0); + + $screenWidth = array_shift($res); + $screenHeight = array_shift($res); + + + // Force screenshot width while maintaining aspect ratio + if($force_width) { + + $factor = (float)$force_width / (float)$screenWidth; + + $screenWidth = $force_width; + if($factor > 0) { + $screenHeight = $factor * $screenHeight; + } else { + $screenHeight = ($screenWidth * 9.0/16.0); + } + + // If no width is set, we were reached from Open in New Window + } else if(!$_REQUEST['width']) { + + //Set no caching + header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); + header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); + header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0"); + + } + + // If we were unable to get screen dimensions, set it to something + if(!$screenWidth || !$screenHeight) { + $screenWidth = 640; + $screenHeight = 480; + } + // array() for compatibility with readSavedScreenshotPNGToArray return value + try { + $imageraw = array($vbox->session->console->display->takeScreenShotToArray(0, $screenWidth, $screenHeight, 'PNG')); + } catch (Exception $e) { + // For some reason this is required or you get "Could not take a screenshot (VERR_TRY_AGAIN)" in some cases. + // I think it's a bug in the Linux guest additions, but cannot prove it. + $vbox->session->console->display->invalidateAndUpdate(); + $imageraw = array($vbox->session->console->display->takeScreenShotToArray(0, $screenWidth, $screenHeight, 'PNG')); + } + + $vbox->session->unlockMachine(); + $vbox->session->releaseRemote(); + + } else { + + // Let the browser cache saved state images + $ctime = 0; + if(strpos($_SERVER['HTTP_IF_NONE_MATCH'],'_')) { + $ctime = preg_replace("/.*_/",str_replace('"','',$_SERVER['HTTP_IF_NONE_MATCH'])); + } else if(strpos($_ENV['HTTP_IF_NONE_MATCH'],'_')) { + $ctime = preg_replace("/.*_/",str_replace('"','',$_ENV['HTTP_IF_NONE_MATCH'])); + } else if(strpos($_SERVER['HTTP_IF_MODIFIED_SINCE'],'GMT')) { + $ctime = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']); + } else if(strpos($_ENV['HTTP_IF_MODIFIED_SINCE'],'GMT')) { + $ctime = strtotime($_ENV['HTTP_IF_MODIFIED_SINCE']); + } + + if($dlm <= $ctime) { + if (strpos(strtolower(php_sapi_name()),'cgi') !== false) { + Header("Status: 304 Not Modified"); + } else { + Header("HTTP/1.0 304 Not Modified"); + } + exit; + } + + + if($_REQUEST['full']) $imageraw = $machine->readSavedScreenshotPNGToArray(0); + else $imageraw = $machine->readSavedThumbnailToArray(0, 'PNG'); + + $machine->releaseRemote(); + + } + $vbox->session = null; + + header("Content-type: image/png",true); + + foreach($imageraw as $i) { + if(is_array($i)) echo(base64_decode($i[0])); + } + + +} catch (Exception $ex) { + + // Ensure we close the VM Session if we hit a error, ensure we don't have a aborted VM + if($vbox && $vbox->session && $vbox->session->handle) { + try { + $vbox->session->unlockMachine(); + unset($vbox->session); + } catch (Exception $e) { + } + } + + if($_REQUEST['full'] && strpos($ex->faultstring,'VERR_NOT_SUPPORTED') > 0) { + @header("Content-type: text/html"); + echo("Screen shots are not supported by your VirtualBox installation. To enable screen shots, please install a VirtualBox exteionsion pack that supports VRDE "); + echo("such as the Oracle VM VirtualBox Extension Pack found in the Downloads section of <a href='http://www.virtualbox.org'>http://www.virtualbox.org</a>."); + } else if($_REQUEST['full'] || $_REQUEST['debug']) { + header("Content-type: text/html", true); + echo("<pre>"); + print_r($ex); + echo("</pre>"); + } +} + |