Sunday, March 24, 2013

Portable VirtualBox Installation and Architecture

Portable Virtualbox lets you  run a Linux or a Windows virtual machine from a USB device or a directory without installing components.

To run it, a user must have administrative privileges. It uses the privileges to install the VirtualBox device driver and the VirtualBox service and control them. At the end it stops whatever it started and removes whatever it has installed.

You get Portable VirtualBox here. The installation procedure is a little odd. I rewrote the documentation on the site (which was much worse than it now is.)

The PortableVirtualBox.exe program is a packaged version of a script written using the AutoIt scripting language.

For the rest of this post, assume that you've downloaded the installer, and unpacked it into the directory PVBX.

When you download PortableVirtualBox you decompress it into a directory, then run PortableVirtualBox script. This will install a VirtualBox installation executable in a portable way and then it will launch VirtualBox.

You can now use the PortableVirtualBox installer to download a version of VirtualBox, or download one from the VirtualBox.org site. Whichever choice you make, PortableVirtualBox will unpack the files and save them in its directory structure. The executables and DLLs will go in PVBX/data/app32 and/or PBX/data/app64 (or both) depending on the selections you make in the install GUI.

To make PortableVirtualBox entirely portable, I have it set up both. The vboxadditions directory will contain the guestadditions.iso image among other things. This will be copied to app32/64 when you run PVB and copied back when you are done.

PortableVirualBox is configured by PVBX/data/settting/settings.ini.  VirtualBox is configured by PVBX/data/.VirtualBox/VirtualBox.xml. Machines that you register end up in this file, and if something goes wrong (machine moved, corrupted) you may have to edit the file.

The sources for PortableVirtualBox can be debugged with the AutoIt debugger. To use the debugger you have to install it, and also install AutoIt. The AutoIT debugger comes with a portable install option. AutoIt does not give you that option, but Portable Freeware has a portable version, here.

To debug the script you will need to do the following:
  • Copy the files from the PVBX/source directory to PVBX. 
  • Launch a command shell in administrator mode, navigate to the PVBX directory and start the AutoIt Debugger from there.
Once the debugger is running, make sure that Test Script.au3, which is stored in the debugger's User Data directory, can be debugged
  • Then open the Portable-VirtualBox.au3 script and you are ready to debug.
The debugger is a little strange:
  • It does not have step over or step return commands. Just run, step in, and run to cursor. So you can do the following:
    • Set breakpoints and run to the breakpoint. This is my preferred method for debugging
    •  Use the "step in" command. This takes you to every source line.
    • Put your cursor somewhere and run to the cursor
  • The debugger produces a trace listing showing each line that is executed. If you click on the (+) sign for the line you will see the values of each of the variables used when executing the line.
  • Clicking on a line in the trace takes you to that line in the source
  • Pressing ESC ends your debug session. Easy to do by accident. Major nuisance
  • You can hover over variables that start with $, or right click and put them in the watch window. But you can't get the value of system variables (start with @) At least I couldn't.
  • You can't search for text while in a debug session. Nuisance.
My preferred debug technique
  • Step in to start the program
  • Read a bit of code to get a sense of where things are going
  • Step through the code (as appropriate) and periodically set breakpoints, or
  • Look ahead and set breakpoints and run to them
  • From time to time clear all the breakpoints you have set and set a new one. If the debugger runs away from you restart and run to a breakpoint. This will leave you either at, or a few breakpoints before, the place you lost control.
  • Because the debugger permits statement folding, you can skip around a large if block as follows
    • Close the If statement (click on  [-] )
    • Close the Else clause if there is one (click on [-])
    • Set a breakpoint at the statement following the collapsed Else and run to there
Outline of the PortableVirtualBox program:
  • Check for program update.exe and if it exists, remove it, and the update flag
  • Check for data/settings/settings.ini and if it does not exist, initialize it
  • Read the settings key and take action. In particular, check for updates, and notify user.
  • Save XML-Prev
  • Make sure the dlls are in the arch directories.
    • For x86: msvcr71.dll, mscvcp71.dll msvcrt.dll
    • For x64: msvcp80.dll, msvcr80.dll
  • Move the vboxadditions to the arch directory for your architecture
  • Register the VBoxSVC service, the VBOXC.dll and initialize the VBoxRT.dll
  • Register the drivers that are needed
  • Run VirtualBox and wait for it to exit
  • On return, stop what's been started, and uninstall what's been installed
    • Stop and unregister services
    • Stop all processes
    • Move vboxadditions to neutral territory

Some details:
The script will run the VirtualBox service:
PBX/appxx/VBoxSVC.exe /reregserverregsvr32.exe /S appxx/VBoxC.dll
Then this:
DllCall ($arch&"\VBoxRT.dll", "hwnd", "RTR3Init")

The script checks for the following key. If missing it will install the VBox service, start it and then stop it and delete it at the end of the program.
"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\VBoxDRV"
Command to install the service: 
cmd /c sc create VBoxDRV binpath= PVB\arcxx\drivers\VBoxDrv\VBoxDrv.sys type= kernel start= auto error= normal displayname= PortableVBoxDRVsc stop VBoxDRVsc delete VBoxDRV

Depending on the needs of the virtual machine it will also check keys and if missing install other services and drivers:
"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\VBoxUSB""HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\VBoxUSBMon""HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\VBoxNetAdp""HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\VBoxNetFlt"

If it installs a driver, it will remove it at the end. If the program terminates abnormally (for example if you debug your way into an installation and then quit the debug session the driver will remain installed, and not be removed later).

It's possible to set up the PortableVirtualBox configuration so that it automatically starts a virtual machine, but this nay create a problem if you stop the VMs in the wrong order.

On my setup, I use these commands:
cd C:\awesome\lib\Portable-VirtualBox"..\lib\AutoIt Debugger\AutoIt Debugger.exe" Portable-VirtualBox.au3