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 http://www.virtualbox.org."); } else if($_REQUEST['full'] || $_REQUEST['debug']) { header("Content-type: text/html", true); echo("
"); print_r($ex); echo(""); } }