[Esbox-commits] r2251 - in branches/work_Andre: org.maemo.esbox.help/html/images org.maemo.esbox.help/html/images/debian org.maemo.esbox.help/html/tasks org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/internal/api/maemosdk/ui/preferences org.maemo.esbox.product org.maemo.esbox.scratchbox.sb1/src/org/maemo/esbox/internal/scratchbox/sb1/core org.maemo.esbox.tests org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/ui org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/ui/preferences org.maemo.esbox.vm/src/org/maemo/esbox/internal/vm org.maemo.esbox.vm/src/org/maemo/esbox/vm/core org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu org.maemo.esbox.vm.qemu/src/org/maemo/esbox/vm/qemu org.maemo.esbox.vm.tests/src/org/maemo/esbox/vm/tests org.maemo.esbox.vm.virtualbox/src/org/maemo/esbox/internal/vm/virtualbox org.maemo.esbox.vm.virtualbox/src/org/maemo/esbox/vm/virtualbox org.maemo.esbox.vm.vmware org.maemo.esbox.vm.vmware/conf org.maemo.esbox.vm.vmware/src/org/maemo/esbox/internal/vm/vmware org.maemo.esbox.vm.vmware/src/org/maemo/esbox/vm/vmware

andregomes at garage.maemo.org andregomes at garage.maemo.org
Fri Oct 2 00:01:55 EEST 2009


Author: andregomes
Date: 2009-10-02 00:01:25 +0300 (Fri, 02 Oct 2009)
New Revision: 2251

Added:
   branches/work_Andre/org.maemo.esbox.help/html/images/debian/wiz-debian-deploy-package-logging-opts.png
   branches/work_Andre/org.maemo.esbox.help/html/images/debian/wiz-debian-deploy-package-main.png
   branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/LaunchedMachineInfo.java
Removed:
   branches/work_Andre/org.maemo.esbox.tests/asthelper.completions
Modified:
   branches/work_Andre/org.maemo.esbox.help/html/images/menu-context-device-target.png
   branches/work_Andre/org.maemo.esbox.help/html/images/menu-debian-package.png
   branches/work_Andre/org.maemo.esbox.help/html/tasks/DebianPackage.html
   branches/work_Andre/org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/internal/api/maemosdk/ui/preferences/BuildMachinePreferencePage.java
   branches/work_Andre/org.maemo.esbox.product/about.mappings
   branches/work_Andre/org.maemo.esbox.product/plugin_customization.ini
   branches/work_Andre/org.maemo.esbox.scratchbox.sb1/src/org/maemo/esbox/internal/scratchbox/sb1/core/Scratchbox1SDK.java
   branches/work_Andre/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuMachineController.java
   branches/work_Andre/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuSettingsPreferencePage.java
   branches/work_Andre/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/vm/qemu/IQemuConfiguration.java
   branches/work_Andre/org.maemo.esbox.vm.tests/src/org/maemo/esbox/vm/tests/TestVMPreferences.java
   branches/work_Andre/org.maemo.esbox.vm.virtualbox/src/org/maemo/esbox/internal/vm/virtualbox/VirtualBoxMachineController.java
   branches/work_Andre/org.maemo.esbox.vm.virtualbox/src/org/maemo/esbox/internal/vm/virtualbox/VirtualBoxSettingsPreferencePage.java
   branches/work_Andre/org.maemo.esbox.vm.virtualbox/src/org/maemo/esbox/vm/virtualbox/IVirtualBoxConfiguration.java
   branches/work_Andre/org.maemo.esbox.vm.vmware/conf/vmware_prefs.xml
   branches/work_Andre/org.maemo.esbox.vm.vmware/plugin.xml
   branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/internal/vm/vmware/VMwareConfiguration.java
   branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/internal/vm/vmware/VMwareMachineController.java
   branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/internal/vm/vmware/VMwarePreferenceConstants.java
   branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/internal/vm/vmware/VMwarePreferenceMigrator.java
   branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/internal/vm/vmware/VMwareSettingsPreferencePage.java
   branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/internal/vm/vmware/VMwareUtils.java
   branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/vm/vmware/IVMwareConfiguration.java
   branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BaseLaunchableVirtualMachineController.java
   branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BaseVirtualMachine.java
   branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BaseVirtualMachineConfiguration.java
   branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BaseVirtualMachineController.java
   branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/ui/LaunchVirtualMachineDialog.java
   branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/ui/preferences/CommonVirtualMachineSettingsPreferencePage.java
   branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/vm/ManualVirtualMachineController.java
   branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/vm/core/IVirtualMachineConfiguration.java
Log:
Merging with trunk.

Copied: branches/work_Andre/org.maemo.esbox.help/html/images/debian/wiz-debian-deploy-package-logging-opts.png (from rev 2245, trunk/org.maemo.esbox.help/html/images/debian/wiz-debian-deploy-package-logging-opts.png)
===================================================================
(Binary files differ)

Copied: branches/work_Andre/org.maemo.esbox.help/html/images/debian/wiz-debian-deploy-package-main.png (from rev 2245, trunk/org.maemo.esbox.help/html/images/debian/wiz-debian-deploy-package-main.png)
===================================================================
(Binary files differ)

Modified: branches/work_Andre/org.maemo.esbox.help/html/images/menu-context-device-target.png
===================================================================
(Binary files differ)

Modified: branches/work_Andre/org.maemo.esbox.help/html/images/menu-debian-package.png
===================================================================
(Binary files differ)

Modified: branches/work_Andre/org.maemo.esbox.help/html/tasks/DebianPackage.html
===================================================================
--- branches/work_Andre/org.maemo.esbox.help/html/tasks/DebianPackage.html	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.help/html/tasks/DebianPackage.html	2009-10-01 21:01:25 UTC (rev 2251)
@@ -86,28 +86,31 @@
 <p>ESbox allows you to deploy and install the generated .deb package.</p>
 	<p>You may choose to create the package in this step, or re-install a previously generated package.</p>
 	
-<p>To install your application on the Internet Tablet:</p>
+<p>To install your application on any target, including Internet Tablets:</p>
 
 <ol>
 
   <li>Select a project in Project Explorer, right-click and select  Debian&nbsp;Package in the context menu.</li>
 
-  <li>Click on <strong>Install&nbsp;Debian&nbsp;Package&nbsp;on&nbsp;Device</strong>.
+  <li>Click on <strong>Install&nbsp;Debian&nbsp;Package&nbsp;on&nbsp;Target</strong>.
 
 
-  <p>This item opens the dialog with name of the project, the last known or guessed package location, and the device address.</p>
-	<p>Also, you may expand the dialog to show extra logging options to help debug the
+  <p>The first wizard page shows a page with name of the project, the last known or guessed package location, and the list of available targets.</p>
+	
+	<p/><img src="../images/debian/wiz-debian-deploy-package-main.png" alt="debian3" ></p>
+	
+	<p>The second page provide extra options. You may expand the dialog to show extra logging options to help debug the
 	installation process.
 	</p>
-    <p/><img src="../images/debian/wiz-debian-deploy-package.png" alt="debian3" ></p>
+    <p/><img src="../images/debian/wiz-debian-deploy-package-logging-opts.png" alt="debian4" ></p>
 
 </li>
   <li>Click on <strong>Browse...</strong> to select a package if you haven't deployed it before, or type in the path to the package 
   if you're planning to build it for the first time in this step.</li>
-  <li>Check <strong>Install package on device</strong> to install the package.  When enabled, the <strong>Device Address</strong> field is enabled.</li> 
-  <li>Check <strong>Enable extra logging</strong> to log more information about the package installation.  When enabled, the <strong>Extra Logging Options</strong> group is enabled. Common extra logging options are set as default.</li>
+  <li>Check <strong>Install package on target</strong> to install the package.  When enabled, the <strong>Target</strong> selection area is enabled.</li> 
+  <li>On second page, check <strong>Enable extra logging</strong> to log more information about the package installation.  When enabled, the <strong>Extra Logging Options</strong> group is enabled. Common extra logging options are set as default.</li>
   <li>Click <strong>Finish</strong>.</li>
-  <li>You may need to provide the root password to perform package management on the device:
+  <li>In this case, since a remote target was selected, you may need to provide the root password to perform package management on the device:
       <p><img alt="password prompt" src="../images/dialog-device-root-password.png"></p>
   </li> 
 	  

Modified: branches/work_Andre/org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/internal/api/maemosdk/ui/preferences/BuildMachinePreferencePage.java
===================================================================
--- branches/work_Andre/org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/internal/api/maemosdk/ui/preferences/BuildMachinePreferencePage.java	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.maemosdk.ui/src/org/maemo/esbox/internal/api/maemosdk/ui/preferences/BuildMachinePreferencePage.java	2009-10-01 21:01:25 UTC (rev 2251)
@@ -50,6 +50,7 @@
 import org.eclipse.ui.IWorkbenchPreferencePage;
 import org.maemo.esbox.internal.maemosdk.ui.IHelpID;
 import org.maemo.esbox.internal.maemosdk.ui.UIActivator;
+import org.maemo.mica.common.core.NetworkUtils;
 import org.maemo.mica.common.core.machine.IBuildMachine;
 import org.maemo.mica.common.core.machine.IComposablePreferencePage;
 import org.maemo.mica.common.core.machine.ILocalMachine;
@@ -430,7 +431,11 @@
 		
 		for (int i = 0; i < currentMachines_.length; i++) {
 			IMachine machine = currentMachines_[i];
-			if (machine instanceof ILocalMachine) {
+			
+			// don't shut down local host, either if it was directly selected
+			// or the local host over the local SSH port was used to configure a VM
+			if (machine instanceof ILocalMachine ||
+					(NetworkUtils.isLocalURI(machine.getURI()) && machine.getURI().getPort() == 22)) {
 				currentMachines_[i] = null;	// don't dare shut this down
 				continue;
 			}

Modified: branches/work_Andre/org.maemo.esbox.product/about.mappings
===================================================================
--- branches/work_Andre/org.maemo.esbox.product/about.mappings	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.product/about.mappings	2009-10-01 21:01:25 UTC (rev 2251)
@@ -7,4 +7,4 @@
 # e.g. "0=20020612"
 # This value will be added automatically via the build scripts
 0=20090211-1700
-1=I20090819
+1=I20091007

Modified: branches/work_Andre/org.maemo.esbox.product/plugin_customization.ini
===================================================================
--- branches/work_Andre/org.maemo.esbox.product/plugin_customization.ini	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.product/plugin_customization.ini	2009-10-01 21:01:25 UTC (rev 2251)
@@ -29,3 +29,19 @@
 
 # Initial page layout of the Universal Welcome
 org.eclipse.ui.intro.universal/INTRO_DATA = product:introData.xml
+
+# switch to debug perspective without asking
+org.eclipse.debug.ui/org.eclipse.debug.ui.switch_to_perspective=always
+
+# from org.eclipse.core.resource.ResourcesPlugin
+# turn off Build Automatically
+org.eclipse.core.resources/description.autobuilding=false
+
+# save before build on by default
+org.eclipse.ui.ide/SAVE_ALL_BEFORE_BUILD=true
+
+# launch last launch configuration 
+org.eclipse.debug.ui.UseContextualLaunch=false
+
+# increase debugger delay due to SBRSH issues
+org.python.pydev.prefs/CONNECT_TIMEOUT=60000

Modified: branches/work_Andre/org.maemo.esbox.scratchbox.sb1/src/org/maemo/esbox/internal/scratchbox/sb1/core/Scratchbox1SDK.java
===================================================================
--- branches/work_Andre/org.maemo.esbox.scratchbox.sb1/src/org/maemo/esbox/internal/scratchbox/sb1/core/Scratchbox1SDK.java	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.scratchbox.sb1/src/org/maemo/esbox/internal/scratchbox/sb1/core/Scratchbox1SDK.java	2009-10-01 21:01:25 UTC (rev 2251)
@@ -978,6 +978,7 @@
 	public void forceShutdown(IProgressMonitor monitor) throws MicaException {
 		monitor.beginTask("", 2);
 		
+		monitor.subTask("Killing Scratchbox sessions...");
 		try {
 			killSessions();
 		} catch (MicaException e) {

Deleted: branches/work_Andre/org.maemo.esbox.tests/asthelper.completions
===================================================================
(Binary files differ)

Modified: branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BaseLaunchableVirtualMachineController.java
===================================================================
--- branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BaseLaunchableVirtualMachineController.java	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BaseLaunchableVirtualMachineController.java	2009-10-01 21:01:25 UTC (rev 2251)
@@ -17,7 +17,6 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.SubProgressMonitor;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Shell;
@@ -33,7 +32,6 @@
 import org.maemo.mica.common.core.machine.MachineManager;
 import org.maemo.mica.common.core.machine.MachineRegistry;
 import org.maemo.mica.common.core.process.*;
-import org.maemo.mica.common.core.process.ProcessLauncherUtils.LaunchResults;
 import org.maemo.mica.common.core.sdk.ISDK;
 import org.maemo.mica.common.core.sdk.SDKManager;
 import org.maemo.mica.internal.api.common.core.SudoWrappedProcessLauncherFactory;
@@ -112,86 +110,6 @@
 	 */
 	abstract protected ProcessLauncherParameters constructLaunchParameters();
 
-	static public class LaunchedMachineInfo {
-		public LaunchedMachineInfo(
-				IVirtualMachineConfiguration configuration,
-				IProcessLauncher processLauncher) {
-			this.configuration = configuration;
-			this.launcher = processLauncher;
-			this.monitor = processLauncher.createProcessMonitor();
-			this.streamGrabber = new StringBuilderStreamTextMonitor(false);
-			this.monitor.addMonitor(streamGrabber);
-		}
-		public LaunchedMachineInfo(IStatus failedStatus) {
-			this.failedStatus = failedStatus;
-		}
-
-		public IProcessLauncher launcher;
-		public IProcessMonitor monitor;
-		public StringBuilderStreamTextMonitor streamGrabber;
-		public IVirtualMachineConfiguration configuration;
-		private IStatus failedStatus;
-		
-		public boolean isAlive() {
-			if (monitor == null)
-				return false;
-			
-			return !monitor.isCompleted();
-		}
-		
-		/**
-		 * Return an status describing the output if the machine died.
-		 * @return IStatus
-		 */
-		public IStatus checkAlive() {
-			if (isAlive())
-				return Status.OK_STATUS;
-
-			String msg;
-			if (launcher != null) {
-				LaunchResults results = new LaunchResults(launcher.getLastCreatedProcess().exitValue(),
-						streamGrabber.stdout.toString(),
-						streamGrabber.stderr.toString());
-				msg = results.reportResults("Virtual machine died unexpectedly");
-				return Activator.createErrorStatus(msg, null);
-			} else {
-				return failedStatus != null ? failedStatus : 
-					Activator.createErrorStatus("The machine was never launched", null);
-			}
-		}
-
-		/**
-		 * @return the failed
-		 */
-		public boolean isFailed() {
-			return failedStatus != null;
-		}
-		
-		/**
-		 * Indicate that this launch failed
-		 * @param status 
-		 */
-		public void setFailed(IStatus status) {
-			if (this.failedStatus == null)
-				this.failedStatus = status;
-		}
-		/**
-		 * @return the failedStatus
-		 */
-		public IStatus getFailedStatus() {
-			return failedStatus;
-		}
-		/**
-		 * 
-		 */
-		public void cancel() {
-			setFailed(CANCEL_STATUS);
-
-			// don't cancel anything else here... we can't distinguish explicit user cancel from 
-			// a nested cancellation (e.g. refresh SDKs launches machine, then the refresh is canceled).
-			// This can result in killing a perfectly fine machine
-		}
-	}
 	/**
 	 * Launch the machine and return an {@link IProcessLauncher} to track it.
 	 * The launcher is not quite ready upon return -- you need to call {@link LaunchedMachineStatus#monitor#runBlocking()}
@@ -217,91 +135,6 @@
 		return status;
 	}
 	
-	/**
-	 * Probe the machine until the connection is established.  Since this
-	 * may be never-ending (since we can't contact the machine if its network
-	 * is misconfigured), in non-unit test mode, we show a dialog where the 
-	 * user can edit the machine settings.
-	 * @param launchInfo info used to track the process, or <code>null</code> if it is not relevant or cannot be tracked
-	 * @param monitor
-	 * @return status of connection: OK or CANCEL
-	 * @throws MachineException
-	 */
-	protected IStatus probeUntilConnect(LaunchedMachineInfo launchInfo,  
-			IProgressMonitor monitor) {
-		final int PROBE_COUNT = 10;
-		
-		long timeout = System.currentTimeMillis() + 300 * 1000;
-		while (true) {
-			IStatus status;
-			
-			// see if the process died
-			if (launchInfo != null) {
-				status = launchInfo.checkAlive();
-				if (!status.isOK()) {
-					return status;
-				}
-			} else {
-				if (!isMachineRunning()) {
-					return Activator.createErrorStatus("Machine is no longer running", null);
-				}
-			}
-			
-			// spend some time
-			for (int cnt = 0; cnt < PROBE_COUNT; cnt++) {
-				monitor.worked(1);
-				if (monitor.isCanceled())
-					return CANCEL_STATUS;
-
-				try {
-					Thread.sleep(100);
-				} catch (InterruptedException e) {
-					return CANCEL_STATUS;
-				}
-				
-				Display display = Display.getCurrent();
-				if (display != null) {
-					while (display.readAndDispatch()) ;
-				}
-			}
-			
-			// test the connection
-			scheduleProbe();
-			status = doProbeMachine(new SubProgressMonitor(monitor, 1));
-			if (status.isOK()) {
-				// XXX: do this more intelligently
-				// sshd starts a few moments before /etc/rc.local is run, 
-				// so kernel parameters like vdso might not be configured yet... 
-				// wait a few seconds more to avoid immediately invoking
-				// scratchbox commands and failing.
-				for (int cnt = 0; cnt < 50; cnt++) {
-					Display display = Display.getCurrent();
-					if (display != null) {
-						while (display.readAndDispatch()) ;
-					}
-					
-					monitor.worked(1);
-					if (monitor.isCanceled())
-						return CANCEL_STATUS;
-
-					try {
-						Thread.sleep(100);
-					} catch (InterruptedException e) {
-						return CANCEL_STATUS;
-					}
-				}
-				break;
-			}
-			
-			if (System.currentTimeMillis() >= timeout) {
-				return Activator.createErrorStatus("Timed out while trying to establish SSH connection to " 
-						+ getName() + "; network settings may be wrong", null);
-			}
-		}
-		
-		return Status.OK_STATUS;
-	}
-	
 	protected MachineException cancelled() {
 		return new MachineException(null, new CoreException(CANCEL_STATUS));
 	}
@@ -450,15 +283,4 @@
 	protected LaunchedMachineInfo getMachineLaunchInfo() {
 		return launchInfo;
 	}
-
-	/**
-	 * Tell if the virtual machine or engine is running.  This either detects
-	 * existing instances of the machine running on the host, or verifies
-	 * that a previously launched instance via {@link #startMachine(IProgressMonitor)} 
-	 * is still valid.
-	 * @return true if it is likely running, false if we either don't know
-	 * or if it is not running.  If unsure, return false.
-	 */
-	abstract public boolean isMachineRunning();
-	
 }

Modified: branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BaseVirtualMachine.java
===================================================================
--- branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BaseVirtualMachine.java	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BaseVirtualMachine.java	2009-10-01 21:01:25 UTC (rev 2251)
@@ -36,11 +36,14 @@
 	 */
 	@Override
 	public boolean isAlive() {
+		if (!super.isAlive())
+			return false;
+		
 		if (getMachineController() instanceof BaseLaunchableVirtualMachineController) {
 			boolean isVMRunning = ((BaseLaunchableVirtualMachineController) getMachineController()).isMachineRunning();
 			if (!isVMRunning)
 				return false;
 		}
-		return super.isAlive();
+		return true;
 	}
 }

Modified: branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BaseVirtualMachineConfiguration.java
===================================================================
--- branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BaseVirtualMachineConfiguration.java	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BaseVirtualMachineConfiguration.java	2009-10-01 21:01:25 UTC (rev 2251)
@@ -14,9 +14,15 @@
 import java.io.IOException;
 import java.io.StringWriter;
 import java.net.URI;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Comparator;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.eclipse.jface.dialogs.IDialogSettings;
 import org.maemo.esbox.internal.api.vm.core.URIQueryParser.IURIQueryDecoder;
@@ -71,9 +77,19 @@
 			// ignore the section name, since it's not predictable
 			fullString = fullString.replaceAll("name=\"[^\"]+\"", "name=\"temp\"");
 			
-			// the lines are not necessarily sorted...
-			String[] lines1 = fullString.split("\n");
-			Arrays.sort(lines1,
+			// the lines are not necessarily sorted and may include obsolete prefs...
+			List<String> lines = new ArrayList<String>(Arrays.asList(fullString.split("\n")));
+			Pattern itemPattern = Pattern.compile("key=\"([^\"]*)\"");
+			Set<String> registeredKeys = CorePreferenceManager.getInstance().getRegisteredKeys();
+			for (Iterator<String> iterator = lines.iterator(); iterator.hasNext();) {
+				String string = iterator.next();
+				Matcher matcher = itemPattern.matcher(string);
+				if (matcher.find()) {
+					if (!registeredKeys.contains(matcher.group(1)))
+						iterator.remove();
+				}
+			}
+			Collections.sort(lines,
 					new Comparator<String>() {
 
 						public int compare(String o1, String o2) {
@@ -84,7 +100,7 @@
 						}
 				
 			});
-			return TextUtils.catenateStrings(lines1, "\n");
+			return TextUtils.catenateStrings(lines.toArray(), "\n");
 		}
 		return "";
 	}

Modified: branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BaseVirtualMachineController.java
===================================================================
--- branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BaseVirtualMachineController.java	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/BaseVirtualMachineController.java	2009-10-01 21:01:25 UTC (rev 2251)
@@ -23,6 +23,7 @@
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.SubProgressMonitor;
 import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.preference.PreferenceDialog;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Shell;
@@ -79,6 +80,103 @@
 		return machineConfiguration.getSSHConfiguration(); 
 	}
 	
+
+	/**
+	 * Tell if the virtual machine or engine is running.  This either detects
+	 * existing instances of the machine running on the host, or verifies
+	 * that a previously launched instance via {@link #startMachine(IProgressMonitor)} 
+	 * is still valid.
+	 * @return true if it is likely running, false if we either don't know
+	 * or if it is not running.  If unsure, return false.
+	 */
+	abstract public boolean isMachineRunning();
+	
+	/**
+	 * Probe the machine until the connection is established.  Since this
+	 * may be never-ending (since we can't contact the machine if its network
+	 * is misconfigured), in non-unit test mode, we show a dialog where the 
+	 * user can edit the machine settings.
+	 * @param launchInfo info used to track the process, or <code>null</code> if it is not relevant or cannot be tracked
+	 * @param monitor
+	 * @return status of connection: OK or CANCEL
+	 * @throws MachineException
+	 */
+	protected IStatus probeUntilConnect(LaunchedMachineInfo launchInfo,  
+			IProgressMonitor monitor) {
+		final int PROBE_COUNT = 10;
+		
+		long timeout = System.currentTimeMillis() + 300 * 1000;
+		while (true) {
+			IStatus status;
+			
+			// see if the process died
+			if (launchInfo != null) {
+				status = launchInfo.checkAlive();
+				if (!status.isOK()) {
+					return status;
+				}
+			} else {
+				if (!isMachineRunning()) {
+					return Activator.createErrorStatus("Machine is no longer running", null);
+				}
+			}
+			
+			// spend some time
+			for (int cnt = 0; cnt < PROBE_COUNT; cnt++) {
+				monitor.worked(1);
+				if (monitor.isCanceled())
+					return CANCEL_STATUS;
+
+				try {
+					Thread.sleep(100);
+				} catch (InterruptedException e) {
+					return CANCEL_STATUS;
+				}
+				
+				Display display = Display.getCurrent();
+				if (display != null) {
+					while (display.readAndDispatch()) ;
+				}
+			}
+			
+			// test the connection
+			scheduleProbe();
+			status = doProbeMachine(new SubProgressMonitor(monitor, 1));
+			if (status.isOK()) {
+				// XXX: do this more intelligently
+				// sshd starts a few moments before /etc/rc.local is run, 
+				// so kernel parameters like vdso might not be configured yet... 
+				// wait a few seconds more to avoid immediately invoking
+				// scratchbox commands and failing.
+				for (int cnt = 0; cnt < 50; cnt++) {
+					Display display = Display.getCurrent();
+					if (display != null) {
+						while (display.readAndDispatch()) ;
+					}
+					
+					monitor.worked(1);
+					if (monitor.isCanceled())
+						return CANCEL_STATUS;
+
+					try {
+						Thread.sleep(100);
+					} catch (InterruptedException e) {
+						return CANCEL_STATUS;
+					}
+				}
+				break;
+			}
+			
+			if (System.currentTimeMillis() >= timeout) {
+				return Activator.createErrorStatus("Timed out while trying to establish SSH connection to " 
+						+ getName() + "; network settings may be wrong", null);
+			}
+		}
+		
+		return Status.OK_STATUS;
+	}
+	
+
 	@Override
 	protected final IStatus doStartMachine(final IMachine machine, IProgressMonitor monitor_) throws MachineException {
 		if (monitor_ == null)
@@ -90,6 +188,7 @@
 		IStatus status;
 		
 		boolean doLaunch; 
+		boolean retryLaunch = false;
 		
 		if (WorkbenchUtils.isJUnitRunning()) {
 			doLaunch = true;
@@ -118,28 +217,69 @@
 						ProductUtils.getProductName(),
 						name);
 			
-			final boolean launchRet[] = { false };
+			final boolean launchRet[] = { false, false };
 			Display.getDefault().syncExec(new Runnable() {
 				public void run() {
+					String[] choices;
+					int launchIndex;
+					int retryIndex;
+					if (BaseVirtualMachineController.this instanceof BaseLaunchableVirtualMachineController) {
+						choices = new String[] { 
+							"Launch now",
+							"I launched it",
+							IDialogConstants.CANCEL_LABEL
+							};
+						launchIndex = 0;
+						retryIndex = 1;
+					} else {
+						choices = new String[] { 
+							"I launched it",
+							IDialogConstants.CANCEL_LABEL
+						};
+						launchIndex = -1;
+						retryIndex = 0;
+					}
+					
 					LaunchVirtualMachineDialog dialog = new LaunchVirtualMachineDialog(
-							null, "Virtual Machine Needed",
+							null, "Virtual Machine Needed", null,
 							message,
+							MessageDialog.QUESTION,
 							"If the machine has already booted, you may need to synchronize the network settings or look for other problems.",
 							new ILookHereProvider[] {
 								getLookAtBuildMachinePrefs(),
 								getLookAtNetworkPrefs(),
 								getLookAtMaemoVMWare()
-							});
+							},
+							choices,
+						    launchIndex >= 0 ? launchIndex : retryIndex
+					);
 					
 					if (likelyNetworkIssue) {
 						dialog.setHelpExpanded(true);
 					}
-					launchRet[0] = dialog.open() == IDialogConstants.OK_ID;		
+					int ret = dialog.open();
+					launchRet[0] = ret == launchIndex;		
+					launchRet[1] = ret == retryIndex;
+					// else, cancel
 				}
 			});
 			doLaunch = launchRet[0];
+			retryLaunch = launchRet[1];
 		}
 		
+		if (retryLaunch) {
+			scheduleProbe();
+			status = probeUntilConnect(
+					null,
+					new SubProgressMonitor(monitor, 8));
+			
+			if (monitor.isCanceled() || status.getSeverity() == IStatus.CANCEL) {
+				return CANCEL_STATUS;
+			}
+			
+			return status;
+		}
+		
 		if (!doLaunch)
 			return Status.CANCEL_STATUS;
 		
@@ -159,7 +299,7 @@
 					// the VM or engine cannot even start. 
 					monitorDialog[0] = new SlowVirtualMachineLaunchMonitorDialog(
 							machine, BaseVirtualMachineController.this, 
-							WorkbenchUtils.getSafeShell(),
+							null,
 							1000 * 15);
 					launchMonitor.setProgressPart(monitorDialog[0].getProgressPart());
 					launchMonitor.beginTask("", IProgressMonitor.UNKNOWN);

Copied: branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/LaunchedMachineInfo.java (from rev 2245, trunk/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/LaunchedMachineInfo.java)
===================================================================
--- branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/LaunchedMachineInfo.java	                        (rev 0)
+++ branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/core/LaunchedMachineInfo.java	2009-10-01 21:01:25 UTC (rev 2251)
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Nokia Corporation
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Ed Swartz (Nokia) - initial API and implementation
+ *******************************************************************************/
+
+package org.maemo.esbox.internal.api.vm.core;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.maemo.esbox.internal.vm.Activator;
+import org.maemo.esbox.vm.core.IVirtualMachineConfiguration;
+import org.maemo.mica.common.core.process.IProcessLauncher;
+import org.maemo.mica.common.core.process.IProcessMonitor;
+import org.maemo.mica.common.core.process.StringBuilderStreamTextMonitor;
+import org.maemo.mica.common.core.process.ProcessLauncherUtils.LaunchResults;
+
+public class LaunchedMachineInfo {
+	public LaunchedMachineInfo(
+			IVirtualMachineConfiguration configuration,
+			IProcessLauncher processLauncher) {
+		this.configuration = configuration;
+		this.launcher = processLauncher;
+		this.monitor = processLauncher.createProcessMonitor();
+		this.streamGrabber = new StringBuilderStreamTextMonitor(false);
+		this.monitor.addMonitor(streamGrabber);
+	}
+	public LaunchedMachineInfo(IStatus failedStatus) {
+		this.failedStatus = failedStatus;
+	}
+
+	public IProcessLauncher launcher;
+	public IProcessMonitor monitor;
+	public StringBuilderStreamTextMonitor streamGrabber;
+	public IVirtualMachineConfiguration configuration;
+	private IStatus failedStatus;
+	
+	public boolean isAlive() {
+		if (monitor == null)
+			return false;
+		
+		return !monitor.isCompleted();
+	}
+	
+	/**
+	 * Return an status describing the output if the machine died.
+	 * @return IStatus
+	 */
+	public IStatus checkAlive() {
+		if (isAlive())
+			return Status.OK_STATUS;
+
+		String msg;
+		if (launcher != null) {
+			LaunchResults results = new LaunchResults(launcher.getLastCreatedProcess().exitValue(),
+					streamGrabber.stdout.toString(),
+					streamGrabber.stderr.toString());
+			msg = results.reportResults("Virtual machine died unexpectedly");
+			return Activator.createErrorStatus(msg, null);
+		} else {
+			return failedStatus != null ? failedStatus : 
+				Activator.createErrorStatus("The machine was never launched", null);
+		}
+	}
+
+	/**
+	 * @return the failed
+	 */
+	public boolean isFailed() {
+		return failedStatus != null;
+	}
+	
+	/**
+	 * Indicate that this launch failed
+	 * @param status 
+	 */
+	public void setFailed(IStatus status) {
+		if (this.failedStatus == null)
+			this.failedStatus = status;
+	}
+	/**
+	 * @return the failedStatus
+	 */
+	public IStatus getFailedStatus() {
+		return failedStatus;
+	}
+	/**
+	 * 
+	 */
+	public void cancel() {
+		setFailed(BaseLaunchableVirtualMachineController.CANCEL_STATUS);
+
+		// don't cancel anything else here... we can't distinguish explicit user cancel from 
+		// a nested cancellation (e.g. refresh SDKs launches machine, then the refresh is canceled).
+		// This can result in killing a perfectly fine machine
+	}
+}
\ No newline at end of file

Modified: branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/ui/LaunchVirtualMachineDialog.java
===================================================================
--- branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/ui/LaunchVirtualMachineDialog.java	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/ui/LaunchVirtualMachineDialog.java	2009-10-01 21:01:25 UTC (rev 2251)
@@ -11,8 +11,6 @@
 
 package org.maemo.esbox.internal.api.vm.ui;
 
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.widgets.Shell;
 import org.maemo.esbox.internal.vm.Activator;
@@ -28,17 +26,27 @@
  */
 public class LaunchVirtualMachineDialog extends AbstractExpandableLookHereDialog {
 
-	public LaunchVirtualMachineDialog(Shell parent, 
-			String title,
-			String mainMessage, 
-			String helpMessage,
-			ILookHereProvider[] providers) {
-		super(parent, title, null, mainMessage, MessageDialog.QUESTION,
-				helpMessage,
-				providers,
-				new String[] { "Launch", IDialogConstants.CANCEL_LABEL }, 0);
+	
+	/**
+	 * @param parentShell
+	 * @param dialogTitle
+	 * @param dialogTitleImage
+	 * @param dialogMessage
+	 * @param dialogImageType
+	 * @param helpMessage
+	 * @param providers
+	 * @param dialogButtonLabels
+	 * @param defaultIndex
+	 */
+	public LaunchVirtualMachineDialog(Shell parentShell, String dialogTitle,
+			Image dialogTitleImage, String dialogMessage, int dialogImageType,
+			String helpMessage, ILookHereProvider[] providers,
+			String[] dialogButtonLabels, int defaultIndex) {
+		super(parentShell, dialogTitle, dialogTitleImage, dialogMessage,
+				dialogImageType, helpMessage, providers, dialogButtonLabels,
+				defaultIndex);
 	}
-	
+
 	/* (non-Javadoc)
 	 * @see org.eclipse.jface.dialogs.IconAndMessageDialog#getImage()
 	 */

Modified: branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/ui/preferences/CommonVirtualMachineSettingsPreferencePage.java
===================================================================
--- branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/ui/preferences/CommonVirtualMachineSettingsPreferencePage.java	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/api/vm/ui/preferences/CommonVirtualMachineSettingsPreferencePage.java	2009-10-01 21:01:25 UTC (rev 2251)
@@ -26,6 +26,7 @@
 import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Text;
@@ -46,6 +47,34 @@
  */
 public class CommonVirtualMachineSettingsPreferencePage extends BaseComposableFieldEditorPreferencePage 
 	implements IVirtualMachineSettingsPreferencePage {
+	/**
+	 * @author eswartz
+	 *
+	 */
+	public static class PortFieldEditor extends IntegerFieldEditor {
+		/**
+		 * @param name
+		 * @param labelText
+		 * @param parent
+		 * @param textLimit
+		 */
+		public PortFieldEditor(String name, String labelText, Composite parent,
+				int textLimit) {
+			super(name, labelText, parent, textLimit);
+		}
+
+		@Override
+		protected boolean checkState() {
+			if (!super.checkState())
+				return false;
+			int port = Integer.parseInt(getTextControl().getText());
+			if (port > 0 && port < 65536)
+				return true;
+			showErrorMessage("Port is invalid (" + port + "); must be between 1 and 65535");
+			return false;
+		}
+	}
+
 	private StringFieldEditor feUserName;
 	private StringFieldEditor feUserPassword;
 	private AddressFieldEditor feSshTargetAddr;
@@ -179,10 +208,10 @@
 		});
 		*/
 		
-		feSshTargetPort = new IntegerFieldEditor(
-				VirtualMachinePreferenceConstants.VM_SSH_TARGET_PORT,
-				"Target SSH port:",
-				getFieldEditorParent(),
+		feSshTargetPort = new PortFieldEditor(
+				VirtualMachinePreferenceConstants.VM_SSH_TARGET_PORT, 
+				"Target SSH port:", 
+				getFieldEditorParent(), 
 				5);
 		addField(feSshTargetPort);
 		text = feSshTargetPort.getTextControl(getFieldEditorParent());
@@ -203,7 +232,7 @@
 		String currentHost = getPreferenceStore().getString(feSshHostAddr.getPreferenceName());
 		hostAddressProvider.setCurrentValue(currentHost);
 		
-		feSshHostPort = new IntegerFieldEditor(
+		feSshHostPort = new PortFieldEditor(
 				VirtualMachinePreferenceConstants.VM_SSH_HOST_PORT,
 				"Host SSH port:",
 				getFieldEditorParent(),
@@ -213,7 +242,7 @@
 		text = feSshHostPort.getTextControl(getFieldEditorParent());
 		text.setToolTipText("Specify the SSH port visible in the machine.\nThis may be different from the port seen inside the machine,\nespecially if the port is redirected to be visible to the host.");
 		/*
-		feCifsHostPort = new IntegerFieldEditor(
+		feCifsHostPort = new PortFieldEditor(
 				VirtualMachinePreferenceConstants.VM_CIFS_TARGET_PORT,
 				"Target Samba port:",
 				getFieldEditorParent(),

Modified: branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/vm/ManualVirtualMachineController.java
===================================================================
--- branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/vm/ManualVirtualMachineController.java	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/internal/vm/ManualVirtualMachineController.java	2009-10-01 21:01:25 UTC (rev 2251)
@@ -53,4 +53,12 @@
 	protected IStatus doStopVirtualMachine(IProgressMonitor monitor) {
 		return Activator.createErrorStatus("The build machine must be manually stopped.", null);
 	}
+	
+	/* (non-Javadoc)
+	 * @see org.maemo.esbox.internal.api.vm.core.BaseVirtualMachineController#isMachineRunning()
+	 */
+	@Override
+	public boolean isMachineRunning() {
+		return false;
+	}
 }

Modified: branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/vm/core/IVirtualMachineConfiguration.java
===================================================================
--- branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/vm/core/IVirtualMachineConfiguration.java	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.vm/src/org/maemo/esbox/vm/core/IVirtualMachineConfiguration.java	2009-10-01 21:01:25 UTC (rev 2251)
@@ -29,22 +29,6 @@
 	 */
 	IDialogSettings getSettings();
 	
-	/** Get the name (path + filename) of the program to launch. */
-	String getExecutable();
-	
-	/** Set the name (path + filename) of the program to launch. */
-	void setExecutable(String executable);
-	
-	/** Get the command launch pattern.
-	 * @return a pattern suitable for ShellTemplateSubstitutor 
-	 */
-	String getCommandLaunchPattern();
-
-	/** Set the command launch pattern.
-	 * @param launchPattern a pattern suitable for ShellTemplateSubstitutor 
-	 */
-	void setCommandLaunchPattern(String launchPattern);
-
 	/** Get the SSH configuration.  This combines most of the other VM settings
 	 * (username, password, target addr/port, host addr).
 	 * This should have a valid user/password specified at all times. 

Modified: branches/work_Andre/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuMachineController.java
===================================================================
--- branches/work_Andre/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuMachineController.java	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuMachineController.java	2009-10-01 21:01:25 UTC (rev 2251)
@@ -23,6 +23,7 @@
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.SubProgressMonitor;
 import org.maemo.esbox.internal.api.vm.core.BaseLaunchableVirtualMachineController;
+import org.maemo.esbox.internal.api.vm.core.LaunchedMachineInfo;
 import org.maemo.esbox.vm.core.IVirtualMachine;
 import org.maemo.esbox.vm.qemu.IQemuConfiguration;
 import org.maemo.mica.common.core.MicaException;

Modified: branches/work_Andre/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuSettingsPreferencePage.java
===================================================================
--- branches/work_Andre/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuSettingsPreferencePage.java	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/internal/vm/qemu/QemuSettingsPreferencePage.java	2009-10-01 21:01:25 UTC (rev 2251)
@@ -98,11 +98,12 @@
 	 * @see org.maemo.esbox.internal.api.vm.ui.preferences.IVirtualMachineSettingsPreferencePage#saveTo(org.maemo.esbox.vm.core.IVirtualMachineConfiguration)
 	 */
 	public void saveTo(IVirtualMachineConfiguration config) {
-		config.setCommandLaunchPattern(feQemuLaunchPattern.getStringValue());
-		config.setExecutable(feQemuExeName.getStringValue());
-		((IQemuConfiguration) config).setDiskImagePaths(feDiskPath.getStringValue().split(","));
-		((IQemuConfiguration) config).setMemorySize(feRamSize.getIntValue());
-		((IQemuConfiguration) config).setInstallPath(feQemuPath.getStringValue());
+		IQemuConfiguration qconfig = (IQemuConfiguration) config;
+		qconfig.setCommandLaunchPattern(feQemuLaunchPattern.getStringValue());
+		qconfig.setExecutable(feQemuExeName.getStringValue());
+		qconfig.setDiskImagePaths(feDiskPath.getStringValue().split(","));
+		qconfig.setMemorySize(feRamSize.getIntValue());
+		qconfig.setInstallPath(feQemuPath.getStringValue());
 				
 	}
 }

Modified: branches/work_Andre/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/vm/qemu/IQemuConfiguration.java
===================================================================
--- branches/work_Andre/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/vm/qemu/IQemuConfiguration.java	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.vm.qemu/src/org/maemo/esbox/vm/qemu/IQemuConfiguration.java	2009-10-01 21:01:25 UTC (rev 2251)
@@ -23,7 +23,23 @@
  *
  */
 public interface IQemuConfiguration extends IVirtualMachineConfiguration {
+	/** Get the name (path + filename) of the program to launch. */
+	String getExecutable();
+	
+	/** Set the name (path + filename) of the program to launch. */
+	void setExecutable(String executable);
+	
+	/** Get the command launch pattern.
+	 * @return a pattern suitable for ShellTemplateSubstitutor 
+	 */
+	String getCommandLaunchPattern();
 
+	/** Set the command launch pattern.
+	 * @param launchPattern a pattern suitable for ShellTemplateSubstitutor 
+	 */
+	void setCommandLaunchPattern(String launchPattern);
+
+
 	/** Get the installation path. */
 	String getInstallPath();
 

Modified: branches/work_Andre/org.maemo.esbox.vm.tests/src/org/maemo/esbox/vm/tests/TestVMPreferences.java
===================================================================
--- branches/work_Andre/org.maemo.esbox.vm.tests/src/org/maemo/esbox/vm/tests/TestVMPreferences.java	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.vm.tests/src/org/maemo/esbox/vm/tests/TestVMPreferences.java	2009-10-01 21:01:25 UTC (rev 2251)
@@ -109,8 +109,6 @@
 		assertEquals("1.20.30.40", configuration.getSSHConfiguration().getTargetAddress());
 		assertEquals(2345, configuration.getSSHConfiguration().getHostPort());
 		assertEquals("128.0.0.1", configuration.getSSHConfiguration().getHostAddress());
-		assertNull(configuration.getExecutable());
-		assertNull(configuration.getCommandLaunchPattern());
 		
 		List<ISharedFolder> folders = machine.getConfiguration().getSharedFolders();
 		assertEquals(provider.getSharedFolders(), folders);
@@ -172,7 +170,7 @@
 		ISharedFilesystemProvider provider = createTestSharedFilesystemProvider(); 
 		IVirtualMachine machine = (IVirtualMachine) MachineRegistry.getInstance().createMachine(
 				"test",
-				URI.create("vmware+ssh://foo:bar@10.20.30.40?vmxPath=d:/v/vm.vmx&executable=VMwarePlayer.exe&commandLaunchPattern=%24%7Bfoo%7D%20%24%7Bbar%7D&sshHostPort=2244&sshHostAddress=127.0.0.2"),
+				URI.create("vmware+ssh://foo:bar@10.20.30.40?vmxPath=d:/v/vm.vmx&installPath=c:/Program%20Files/VMware/VMware%20Player&sshHostPort=2244&sshHostAddress=127.0.0.2"),
 				provider);
 		
 		IVMwareConfiguration configuration = (IVMwareConfiguration) machine.getConfiguration();
@@ -183,10 +181,11 @@
 		assertEquals(2244, configuration.getSSHConfiguration().getHostPort());
 		assertEquals("127.0.0.2", configuration.getSSHConfiguration().getHostAddress());
 
-		assertEquals("${foo} ${bar}", configuration.getCommandLaunchPattern());
+		//assertEquals("${foo} ${bar}", configuration.getCommandLaunchPattern());
 		assertEquals("d:/v/vm.vmx", configuration.getVmxPath());
-		assertEquals("VMwarePlayer.exe", configuration.getExecutable());
-
+		//assertEquals("VMwarePlayer.exe", configuration.getExecutable());
+		assertEquals("c:/Program Files/VMware/VMware Player", configuration.getInstallPath());
+		
 		List<ISharedFolder> folders = machine.getConfiguration().getSharedFolders();
 		assertEquals(provider.getSharedFolders(), folders);
 
@@ -312,19 +311,16 @@
 	}
 	
 	private void checkVMwareSettings(IVMwareConfiguration configuration) {
-		assertFalse("la/dee ${daa}".equals(configuration.getCommandLaunchPattern()));
-		assertFalse("prog.exe".equals(configuration.getExecutable()));
+		//assertFalse("la/dee ${daa}".equals(configuration.getCommandLaunchPattern()));
+		assertFalse("t:/snurf/baah/".equals(configuration.getInstallPath()));
 		assertFalse("//network/foo/blah.vmx".equals(configuration.getVmxPath()));
 		
 		configuration.getSettings().put(
-				VMwarePreferenceConstants.VMWARE_LAUNCH_PATTERN, "la/dee ${daa}");
+				VMwarePreferenceConstants.VMWARE_INSTALL_PATH, "t:/snurf/baah/");
 		configuration.getSettings().put(
-				VMwarePreferenceConstants.VMWARE_EXE_NAME, "prog.exe");
-		configuration.getSettings().put(
 				VMwarePreferenceConstants.VMWARE_VMX_PATH, "//network/foo/blah.vmx");
 		
-		assertEquals("la/dee ${daa}", configuration.getCommandLaunchPattern());
-		assertEquals("prog.exe", configuration.getExecutable());
+		assertEquals("t:/snurf/baah/", configuration.getInstallPath());
 		assertEquals("//network/foo/blah.vmx", configuration.getVmxPath());
 	}
 	

Modified: branches/work_Andre/org.maemo.esbox.vm.virtualbox/src/org/maemo/esbox/internal/vm/virtualbox/VirtualBoxMachineController.java
===================================================================
--- branches/work_Andre/org.maemo.esbox.vm.virtualbox/src/org/maemo/esbox/internal/vm/virtualbox/VirtualBoxMachineController.java	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.vm.virtualbox/src/org/maemo/esbox/internal/vm/virtualbox/VirtualBoxMachineController.java	2009-10-01 21:01:25 UTC (rev 2251)
@@ -27,6 +27,7 @@
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Shell;
 import org.maemo.esbox.internal.api.vm.core.BaseLaunchableVirtualMachineController;
+import org.maemo.esbox.internal.api.vm.core.LaunchedMachineInfo;
 import org.maemo.esbox.vm.core.IVirtualMachine;
 import org.maemo.esbox.vm.core.IVirtualMachineConfiguration;
 import org.maemo.esbox.vm.virtualbox.IVirtualBoxConfiguration;

Modified: branches/work_Andre/org.maemo.esbox.vm.virtualbox/src/org/maemo/esbox/internal/vm/virtualbox/VirtualBoxSettingsPreferencePage.java
===================================================================
--- branches/work_Andre/org.maemo.esbox.vm.virtualbox/src/org/maemo/esbox/internal/vm/virtualbox/VirtualBoxSettingsPreferencePage.java	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.vm.virtualbox/src/org/maemo/esbox/internal/vm/virtualbox/VirtualBoxSettingsPreferencePage.java	2009-10-01 21:01:25 UTC (rev 2251)
@@ -221,9 +221,10 @@
 	 * @see org.maemo.esbox.internal.api.vm.ui.preferences.IVirtualMachineSettingsPreferencePage#saveTo(org.maemo.esbox.vm.core.IVirtualMachineConfiguration)
 	 */
 	public void saveTo(IVirtualMachineConfiguration config) {
-		config.setCommandLaunchPattern(feLaunchPattern.getStringValue());
-		config.setExecutable(feExeName.getStringValue());
-		((IVirtualBoxConfiguration) config).setMachineName(feVboxMachineName.getPreferenceValue());
+		IVirtualBoxConfiguration vconfig = (IVirtualBoxConfiguration) config;
+		vconfig.setCommandLaunchPattern(feLaunchPattern.getStringValue());
+		vconfig.setExecutable(feExeName.getStringValue());
+		vconfig.setMachineName(feVboxMachineName.getPreferenceValue());
 	}
 	
 	protected void validate() {

Modified: branches/work_Andre/org.maemo.esbox.vm.virtualbox/src/org/maemo/esbox/vm/virtualbox/IVirtualBoxConfiguration.java
===================================================================
--- branches/work_Andre/org.maemo.esbox.vm.virtualbox/src/org/maemo/esbox/vm/virtualbox/IVirtualBoxConfiguration.java	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.vm.virtualbox/src/org/maemo/esbox/vm/virtualbox/IVirtualBoxConfiguration.java	2009-10-01 21:01:25 UTC (rev 2251)
@@ -23,7 +23,23 @@
  *
  */
 public interface IVirtualBoxConfiguration extends IVirtualMachineConfiguration {
+	/** Get the name (path + filename) of the program to launch. */
+	String getExecutable();
+	
+	/** Set the name (path + filename) of the program to launch. */
+	void setExecutable(String executable);
+	
+	/** Get the command launch pattern.
+	 * @return a pattern suitable for ShellTemplateSubstitutor 
+	 */
+	String getCommandLaunchPattern();
 
+	/** Set the command launch pattern.
+	 * @param launchPattern a pattern suitable for ShellTemplateSubstitutor 
+	 */
+	void setCommandLaunchPattern(String launchPattern);
+
+
 	/** Get the name of the VirtualBox machine, which is one of the registered
 	 * machines available via 'VBoxManage list vms' */
 	String getMachineName();

Modified: branches/work_Andre/org.maemo.esbox.vm.vmware/conf/vmware_prefs.xml
===================================================================
--- branches/work_Andre/org.maemo.esbox.vm.vmware/conf/vmware_prefs.xml	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.vm.vmware/conf/vmware_prefs.xml	2009-10-01 21:01:25 UTC (rev 2251)
@@ -10,23 +10,27 @@
 	
 	See the org.maemo.mica.common.core.preference_set_provider extension.
 	</comment>
-	
+
+	<!-- these are only used when not running vmrun -->	
+	<!--
 	<entry key="VMWARE_LAUNCH_PATTERN_WIN32">"${VMWARE}" -x "${VMX_PATH}"</entry>
 	<entry key="VMWARE_LAUNCH_PATTERN_UNIX">"${VMWARE}" -x "${VMX_PATH}"</entry>
 	<entry key="VMWARE_LAUNCH_PATTERN_OSX">"${VMWARE}" "${VMX_PATH}"</entry>
+	-->
 	
 	<entry key="VMWARE_PRODUCT">unknown</entry>
 	
 	<!-- VM_STD_IMAGE_BASE is defined in the PreferenceInitializer for this plugin -->
 	<entry key="VMWARE_VM_IMAGE">$(org.maemo.esbox.vm/VM_STD_IMAGE_BASE).vmx</entry>
 
+	<!--
 	<entry key="VMWARE_EXE_NAME_WIN32">c:/Program Files/VMware/VMware Player/vmware.exe</entry>
+	<entry key="VMWARE_EXE_NAME_OSX">/Applications/VMware Fusion.app/Contents/MacOS/vmware</entry>
+	<entry key="VMWARE_EXE_NAME_UNIX">/usr/bin/vmware</entry>
+	-->
+	
 	<entry key="VMWARE_VMX_PATH_WIN32">c:/MaemoVMWare/$(VMWARE_VM_IMAGE)</entry>
-
-	<entry key="VMWARE_EXE_NAME_OSX">/Applications/VMware Fusion.app/Contents/MacOS/vmware</entry>
 	<entry key="VMWARE_VMX_PATH_OSX">/Users/$(user.name)/MaemoVMWare/$(VMWARE_VM_IMAGE)</entry>
-
-	<entry key="VMWARE_EXE_NAME_UNIX">/usr/bin/vmware</entry>
 	<entry key="VMWARE_VMX_PATH_UNIX">/home/$(user.name)/MaemoVMWare/$(VMWARE_VM_IMAGE)</entry>
 	
 </properties>
\ No newline at end of file

Modified: branches/work_Andre/org.maemo.esbox.vm.vmware/plugin.xml
===================================================================
--- branches/work_Andre/org.maemo.esbox.vm.vmware/plugin.xml	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.vm.vmware/plugin.xml	2009-10-01 21:01:25 UTC (rev 2251)
@@ -15,7 +15,7 @@
              preferenceConstantsClass="org.maemo.esbox.internal.vm.vmware.VMwarePreferenceConstants"
              preferenceMigratorClass="org.maemo.esbox.internal.vm.vmware.VMwarePreferenceMigrator"
              preferenceStoreBundle="org.maemo.esbox.vm.vmware"
-             version="1">
+             version="2">
        </preferenceSetProvider>
     </extension>
    <extension

Modified: branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/internal/vm/vmware/VMwareConfiguration.java
===================================================================
--- branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/internal/vm/vmware/VMwareConfiguration.java	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/internal/vm/vmware/VMwareConfiguration.java	2009-10-01 21:01:25 UTC (rev 2251)
@@ -70,8 +70,8 @@
 	protected IURIQueryDecoder getURIQueryDecoder() {
 		return new BaseVirtualMachineURIQueryDecoder(this) {
 			private static final String VMX_PATH = "vmxPath";
-			private static final String COMMAND_LAUNCH_PATTERN = "commandLaunchPattern";
-			private static final String EXECUTABLE = "executable";
+			private static final String INSTALL_PATH = "installPath";
+			private static final String PRODUCT = "product";
 
 			/* (non-Javadoc)
 			 * @see org.maemo.esbox.internal.api.vm.core.BaseVirtualMachineURIQueryDecoder#decode(java.lang.String, java.lang.String)
@@ -83,10 +83,10 @@
 				
 				if (key.equals(VMX_PATH)) {
 					getSettings().put(VMwarePreferenceConstants.VMWARE_VMX_PATH, value);
-				} else if (key.equals(COMMAND_LAUNCH_PATTERN)) {
-					getSettings().put(VMwarePreferenceConstants.VMWARE_LAUNCH_PATTERN, value);
-				} else if (key.equals(EXECUTABLE)) {
-					getSettings().put(VMwarePreferenceConstants.VMWARE_EXE_NAME, value);
+				} else if (key.equals(INSTALL_PATH)) {
+					getSettings().put(VMwarePreferenceConstants.VMWARE_INSTALL_PATH, value);
+				} else if (key.equals(PRODUCT)) {
+					getSettings().put(VMwarePreferenceConstants.VMWARE_PRODUCT, value);
 				} else {
 					return false;
 				}
@@ -102,17 +102,16 @@
 	public void setVmxPath(String vmx) {
 		setPreference(VMwarePreferenceConstants.VMWARE_VMX_PATH, vmx); 
 	}
-	public String getExecutable() {
-		return getPreference(VMwarePreferenceConstants.VMWARE_EXE_NAME); 
+	public String getProduct() {
+		return getPreference(VMwarePreferenceConstants.VMWARE_PRODUCT); 
 	}
-	public void setExecutable(String exe) {
-		setPreference(VMwarePreferenceConstants.VMWARE_EXE_NAME, exe); 
+	public void setProduct(String product) {
+		setPreference(VMwarePreferenceConstants.VMWARE_PRODUCT, product); 
 	}
-	
-	public String getCommandLaunchPattern() {
-		return getPreference(VMwarePreferenceConstants.VMWARE_LAUNCH_PATTERN); 
+	public String getInstallPath() {
+		return getPreference(VMwarePreferenceConstants.VMWARE_INSTALL_PATH); 
 	}
-	public void setCommandLaunchPattern(String pattern) {
-		setPreference(VMwarePreferenceConstants.VMWARE_LAUNCH_PATTERN, pattern); 
+	public void setInstallPath(String path) {
+		setPreference(VMwarePreferenceConstants.VMWARE_INSTALL_PATH, path); 
 	}
 }

Modified: branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/internal/vm/vmware/VMwareMachineController.java
===================================================================
--- branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/internal/vm/vmware/VMwareMachineController.java	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/internal/vm/vmware/VMwareMachineController.java	2009-10-01 21:01:25 UTC (rev 2251)
@@ -22,6 +22,7 @@
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.SubProgressMonitor;
 import org.maemo.esbox.internal.api.vm.core.BaseLaunchableVirtualMachineController;
+import org.maemo.esbox.internal.api.vm.core.LaunchedMachineInfo;
 import org.maemo.esbox.vm.core.IVirtualMachine;
 import org.maemo.esbox.vm.vmware.IVMwareConfiguration;
 import org.maemo.mica.common.core.HostUtils;
@@ -30,9 +31,8 @@
 import org.maemo.mica.common.core.machine.IProcessLister;
 import org.maemo.mica.common.core.machine.MachineException;
 import org.maemo.mica.common.core.machine.MachineRegistry;
-import org.maemo.mica.common.core.process.CommandLineArguments;
 import org.maemo.mica.common.core.process.ProcessLauncherParameters;
-import org.maemo.mica.common.core.process.ShellTemplateSubstitutor;
+import org.maemo.mica.common.core.process.ProcessLauncherUtils.LaunchResults;
 
 /**
  * This is the basic implementation of a QEMU machine
@@ -61,11 +61,13 @@
 		List<IProcess> matches = new ArrayList<IProcess>();
 		
 		// First, see if we find the vmx referenced.
+		//
 		// (On OS X, a separate process handles the VMX itself, so it
-		// won't necessarily be the program we expect)
+		// won't necessarily be the program we expect.)
 		for (IProcess process : allProcesses) {
 			if (process.getCommandLine().contains(vmx.getName())) {
 				if (process.getName().contains(program.getName())
+						|| process.getName().toLowerCase().contains("vmware")
 						|| process.getName().contains("vmware-vmx")) {
 					matches.add(process);
 				}
@@ -92,20 +94,42 @@
 	 * @see org.maemo.esbox.internal.api.vm.core.IVirtualMachineController#isMachineRunning()
 	 */
 	public boolean isMachineRunning() {
-		// we can't tell if the machine stopped running just based on the process stopping
-		// (VMware may have used another instance to host the machine)
+		// We can't tell if the machine stopped running just based on the process stopping
+		// (VMware may have used another instance to host the machine, or, vmrun has exited
+		// right away)
 		if (launchInfo != null && launchInfo.isAlive()) {
 			return true;
 		}
 		
-		// TODO: check the product and use vmrun if possible (or not... that utility
-		// is not available widely enough to be of any use)
+		// vmrun is VERY VERY SLOW on Windows, so do something quick first
+
 		IVMwareConfiguration config = (IVMwareConfiguration) machineConfiguration;
+		File vmx = new File(config.getVmxPath());
+		File exe = getExecutablePath(config).toFile();
 		
-		File exe = new File(config.getExecutable());
-		File vmx = new File(config.getVmxPath());
-		IProcess[] runningVMwares = getRunningVMwareVMXInstances(exe, vmx);
-		return (runningVMwares.length > 0);
+		if (HostUtils.isWindows()) {
+			IProcess[] runningVMwares = getRunningVMwareVMXInstances(exe, vmx);
+			if (runningVMwares.length == 0) {
+				return false;
+			}
+		}
+
+		IPath[] vmxPaths = VMwareUtils.getRunningVMXs(config);
+		if (vmxPaths != null) {
+			for (IPath vmxPath : vmxPaths) {
+				if (vmx.equals(vmxPath.toFile())) {
+					return true;
+				}
+			}
+		}
+		else {
+			if (HostUtils.isWindows()) {
+				// we can't really tell by the command line, but tested above that the 
+				// process was running; assume it is
+				return true;
+			}
+		}
+		return false;
 	}
 	
 	/* (non-Javadoc)
@@ -115,18 +139,39 @@
 	protected ProcessLauncherParameters constructLaunchParameters() {
 		IVMwareConfiguration vmwareConfiguration = (IVMwareConfiguration) machineConfiguration;
 		
-		String launchPattern = vmwareConfiguration.getCommandLaunchPattern();
-		ShellTemplateSubstitutor substitutor = new ShellTemplateSubstitutor();
+		List<String> cmdLine = VMwareUtils.createVmrunCmdLine(vmwareConfiguration,
+				"start", vmwareConfiguration.getVmxPath());
 		
-		IPath launchPath = new Path(vmwareConfiguration.getExecutable());
-		substitutor.define("VMWARE", launchPath.toOSString());
-		substitutor.define("VMX_PATH", new Path(vmwareConfiguration.getVmxPath()).toOSString());
-		
-		launchPattern = substitutor.substitute(launchPattern);
-		List<String> cmdLine = CommandLineArguments.createFromHostCommandLine(launchPattern);
-		
+		// if not vmrun, generate directly
+		if (cmdLine == null) {
+			cmdLine = new ArrayList<String>();
+			
+			IPath launchPath = getExecutablePath(vmwareConfiguration);
+			
+			cmdLine.add(launchPath.toOSString());
+			if (!HostUtils.isOSX() && !vmwareConfiguration.getProduct().equals(IVMwareConfiguration.PRODUCT_PLAYER)) {
+				cmdLine.add("-x");
+			}
+			cmdLine.add(new Path(vmwareConfiguration.getVmxPath()).toOSString());
+		}
+
 		return ProcessLauncherParameters.create(cmdLine);
 	}
+
+	/**
+	 * Get a path to a non-vmrun executable (last ditch)
+	 * @param vmwareConfiguration
+	 * @return
+	 */
+	private IPath getExecutablePath(IVMwareConfiguration vmwareConfiguration) {
+		IPath launchPath = new Path(vmwareConfiguration.getInstallPath());
+		String product = vmwareConfiguration.getProduct();
+		if (product.equals(IVMwareConfiguration.PRODUCT_PLAYER))
+			launchPath = launchPath.append("vmplayer");
+		else
+			launchPath = launchPath.append("vmware");
+		return launchPath;
+	}
 	
 	/* (non-Javadoc)
 	 * @see org.maemo.esbox.internal.api.vm.core.BaseVirtualMachineController#doStartMachineImpl(org.eclipse.core.runtime.IProgressMonitor)
@@ -136,19 +181,25 @@
 			throws MachineException {
 		
 		monitor.beginTask("Starting VMware...", 10);
+
+		IVMwareConfiguration config = (IVMwareConfiguration) machineConfiguration;
+		boolean usingVMrun = VMwareUtils.findVmrunExecutable(config.getInstallPath()) != null;
+		
 		monitor.subTask("Checking existing VMware instances...");
 		
-		// First, see if we recognize any other VMware instances at all.
-		// We don't care about our vmx itself, but for the fact that
-		// the new process exits immediately if the executable is
-		// already running
-		IVMwareConfiguration config = (IVMwareConfiguration) machineConfiguration;
-		File exe = new File(config.getExecutable());
-		IProcess[] runningEngines;
-		try {
-			runningEngines = getRunningProcesses(exe, null);
-		} catch (MicaException e) {
-			runningEngines = new IProcess[0];
+		IProcess[] runningEngines = new IProcess[0];
+		
+		if (!usingVMrun) {
+			// First, see if we recognize any other VMware instances at all.
+			// We don't care about our vmx itself, but for the fact that
+			// the new process exits immediately if the executable is
+			// already running
+			IPath exe = getExecutablePath(config);
+			try {
+				runningEngines = getRunningProcesses(exe.toFile(), null);
+			} catch (MicaException e) {
+				runningEngines = new IProcess[0];
+			}
 		}
 		monitor.worked(1);
 
@@ -161,12 +212,39 @@
 		
 		launchInfo.monitor.runNonBlocking();
 		
-		// depending on whether others were running, it's either important or not
-		// if the subsequent launch succeeds
 		LaunchedMachineInfo watchStatus = null;
-		if (runningEngines.length == 0)
-			watchStatus = launchInfo;
 		
+		if (usingVMrun) {
+			// wait for this to finish
+			launchInfo.monitor.waitForCompletion(null);
+			
+			// we need a little delay between that exit
+			// and the actual launch, since it takes some time 
+			// before the machine appears in the runningvms list.
+			int timeout = 5000;
+			while (timeout > 0) {
+				if (isMachineRunning())
+					break;
+				try {
+					Thread.sleep(500);
+				} catch (InterruptedException e) {
+					break;
+				}
+				monitor.worked(500);
+				if (monitor.isCanceled()) {
+					cancelled();
+				}
+				timeout -= 500;
+			}
+		
+		} else {
+			// depending on whether others were running, it's either important or not
+			// if the subsequent launch succeeds
+			
+			if (runningEngines.length == 0)
+				watchStatus = launchInfo;
+		}
+		
 		status = probeUntilConnect(
 				watchStatus,
 				new SubProgressMonitor(monitor, 8));
@@ -190,7 +268,6 @@
 	@Override
 	protected IStatus doStopVirtualMachine(IProgressMonitor monitor) {
 		
-		// don't waste time if not running
 		try {
 			doHaltMachine(monitor);
 		} catch (MachineException e) {
@@ -199,13 +276,19 @@
 		if (monitor.isCanceled())
 			return Status.CANCEL_STATUS;
 		
-		// then be mean if we launched it ourselves
-		if (launchInfo != null) {
-			
-			Process process = launchInfo.launcher.getLastCreatedProcess();
-			if (process != null)
-				process.destroy();
-			launchInfo = null;
+
+		IVMwareConfiguration config = (IVMwareConfiguration) machineConfiguration;
+		File vmx = new File(config.getVmxPath());
+		LaunchResults results = VMwareUtils.launchAndRunVmrun(config, 30, "stop", vmx.getAbsolutePath());
+		if (results == null) {
+			// no vmrun; be mean if we launched it ourselves
+			if (launchInfo != null) {
+				
+				Process process = launchInfo.launcher.getLastCreatedProcess();
+				if (process != null)
+					process.destroy();
+				launchInfo = null;
+			}
 		}
 		return Status.OK_STATUS;
 	}

Modified: branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/internal/vm/vmware/VMwarePreferenceConstants.java
===================================================================
--- branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/internal/vm/vmware/VMwarePreferenceConstants.java	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/internal/vm/vmware/VMwarePreferenceConstants.java	2009-10-01 21:01:25 UTC (rev 2251)
@@ -27,8 +27,12 @@
 	public static final int VERSION_MAJOR = 1;
 	public static final int VERSION_MINOR = 1;
 	
-	public static final String VMWARE_EXE_NAME = "VMWARE_EXE_NAME";
-	public static final String VMWARE_LAUNCH_PATTERN = "VMWARE_LAUNCH_PATTERN";
+	public static final String VMWARE_INSTALL_PATH = "VMWARE_INSTALL_PATH";
+	
+	//public static final String VMWARE_EXE_NAME = "VMWARE_EXE_NAME"; 
+	// only used when not running vmrun
+	//public static final String VMWARE_LAUNCH_PATTERN = "VMWARE_LAUNCH_PATTERN";
+	
 	public static final String VMWARE_VMX_PATH = "VMWARE_VMX_PATH";
 	
 	/** product type, see VMwareUtils */

Modified: branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/internal/vm/vmware/VMwarePreferenceMigrator.java
===================================================================
--- branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/internal/vm/vmware/VMwarePreferenceMigrator.java	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/internal/vm/vmware/VMwarePreferenceMigrator.java	2009-10-01 21:01:25 UTC (rev 2251)
@@ -12,11 +12,19 @@
 package org.maemo.esbox.internal.vm.vmware;
 
 import org.eclipse.cdt.utils.WindowsRegistry;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
 import org.eclipse.jface.preference.IPreferenceStore;
+import org.maemo.esbox.vm.vmware.IVMwareConfiguration;
+import org.maemo.mica.common.core.HostUtils;
+import org.maemo.mica.common.core.machine.MachineRegistry;
+import org.maemo.mica.common.core.machine.MachineUtils;
 import org.maemo.mica.common.core.preferences.CorePreferenceManager;
 import org.maemo.mica.common.core.preferences.PreferenceMigratorAdapter;
 
 import java.io.File;
+import java.util.Map;
 import java.util.Properties;
 
 /**
@@ -31,11 +39,17 @@
 	public void adjustDefaultSettings(Properties newPropertyDefaults) {
 		// adjust any environment-dependent defaults
 		CorePreferenceManager.selectDefaultForOS(newPropertyDefaults,
-				VMwarePreferenceConstants.VMWARE_LAUNCH_PATTERN);
-		CorePreferenceManager.selectDefaultForOS(newPropertyDefaults,
-				VMwarePreferenceConstants.VMWARE_EXE_NAME);
-		CorePreferenceManager.selectDefaultForOS(newPropertyDefaults,
 				VMwarePreferenceConstants.VMWARE_VMX_PATH);
+		
+		if (HostUtils.isWindows())
+			guessWindowsVMwareInfo(newPropertyDefaults);
+		else if (HostUtils.isOSX())
+			guessOSXVMwareInfo(newPropertyDefaults);
+		else
+			guessUnixVMwareInfo(newPropertyDefaults);
+		
+		String product = HostUtils.isOSX() ? IVMwareConfiguration.PRODUCT_FUSION : IVMwareConfiguration.PRODUCT_WORKSTATION;
+		newPropertyDefaults.setProperty(VMwarePreferenceConstants.VMWARE_PRODUCT, product);
 	}
 
 	/* (non-Javadoc)
@@ -45,51 +59,187 @@
 			int oldMajor, Properties existingSettings,
 			Properties newPropertyDefaults) {
 		
+		// fallback
+		String product = newPropertyDefaults.getProperty(VMwarePreferenceConstants.VMWARE_PRODUCT);
+		if (product == null)
+			product = existingSettings.getProperty(VMwarePreferenceConstants.VMWARE_PRODUCT);
+		if (product == null || product.equals(IVMwareConfiguration.PRODUCT_UNKNOWN)) {
+			product = HostUtils.isOSX() ? IVMwareConfiguration.PRODUCT_FUSION : IVMwareConfiguration.PRODUCT_WORKSTATION;
+			newPropertyDefaults.setProperty(VMwarePreferenceConstants.VMWARE_PRODUCT, product);
+		}
+	}
+
+	/**
+	 * @param existingSettings
+	 * @param newPropertyDefaults
+	 */
+	private void guessWindowsVMwareInfo(Properties newPropertyDefaults) {
+		String product = null;
+		
 		// this isn't strictly a conversion from an older version, 
 		// but a change that reflects changes in any current installation
-		if (!existingSettings.containsKey(VMwarePreferenceConstants.VMWARE_EXE_NAME)) {
-			WindowsRegistry registry = WindowsRegistry.getRegistry();
-			if (registry != null) {
-				// look for some, on Windows, where it's a hassle
+		WindowsRegistry registry = WindowsRegistry.getRegistry();
+		if (registry != null) {
+			String installPath;
+			
+			product = IVMwareConfiguration.PRODUCT_WORKSTATION;
+			installPath = registry.getLocalMachineValue("SOFTWARE\\VMware, Inc.\\VMware Workstation", "InstallPath");
+			if (installPath == null) {
+				product = IVMwareConfiguration.PRODUCT_SERVER;
+				installPath = registry.getLocalMachineValue("SOFTWARE\\VMware, Inc.\\VMware Server", "InstallPath");
+			}
+			if (installPath == null) {
+				product = IVMwareConfiguration.PRODUCT_PLAYER;
+				installPath = registry.getLocalMachineValue("SOFTWARE\\VMware, Inc.\\VMware Player", "InstallPath");
+			}
+			
+			String[] progs = {
+				"vmrun.exe",
+				"vmware.exe",
+				"vmplayer.exe",
+			};
+			
+			if (installPath != null) {
+				// look here, where it was officially installed
+				if (null == firstMatchInDirectory(installPath, progs)) {
+					installPath = null;
+				}
+			}
+			
+			if (installPath == null) {
+				// see if it was not quite installed
+				product = null;
+				
 				String progFiles = registry.getLocalMachineValue("SOFTWARE\\Microsoft\\Windows\\CurrentVersion", "ProgramFilesDir");
 				if (progFiles == null)
 					progFiles = "C:\\Program Files";
+				
 				String prefix = progFiles + "\\VMWare\\";
 				String[] candidates = {
 					"VMware Workstation",
 					"VMware Server",
 					"VMware Player"
 				};
-				String[] progs = {
-					"vmware.exe",
-					"vmplayer.exe",
-				};
-				String exePath = null;
-				for (String candidate : candidates) {
-					if (exePath != null) break;
-					File dir = new File(prefix + candidate); 
-					if (dir.exists()) {
-						for (String prog : progs) {
-							File exe = new File(dir, prog);
-							if (exe.exists()) {
-								exePath = exe.getAbsolutePath();
-								break;
-							}
-						}
-					}
+				
+				File candidate = firstMatchInDirectory(prefix, candidates);
+				if (candidate != null && 
+						firstMatchInDirectory(candidate.getAbsolutePath(), progs) != null) {
+					installPath = candidate.getAbsolutePath();
 				}
-				if (exePath != null) {
-					newPropertyDefaults.put(VMwarePreferenceConstants.VMWARE_EXE_NAME, 
-							exePath);
-				}
 			}
-			if (!existingSettings.containsKey(VMwarePreferenceConstants.VMWARE_PRODUCT)) {
-				// guess from path
-				String exePath = existingSettings.getProperty(VMwarePreferenceConstants.VMWARE_EXE_NAME);
+			
+			if (installPath != null) {
+				newPropertyDefaults.put(VMwarePreferenceConstants.VMWARE_INSTALL_PATH, 
+						installPath);
+			}
+			
+			if (product == null && installPath != null) {
+				product = VMwareUtils.guessProductFromPath(installPath);
+			}				
+		
+			if (product != null) {
 				newPropertyDefaults.put(VMwarePreferenceConstants.VMWARE_PRODUCT, 
-						VMwareUtils.guessProductFromPath(exePath));
+						product);
 			}
 		}
 	}
 
+	/**
+	 * @param installPath
+	 * @param progs
+	 * @return
+	 */
+	private File firstMatchInDirectory(String installPath, String[] progs) {
+		File dir = new File(installPath);
+		if (!dir.exists())
+			return null;
+		
+		for (String prog : progs) {
+			File candidate = new File(dir, prog);
+			if (candidate.exists())
+				return candidate;
+		}
+		return null;
+	}
+
+	/**
+	 * @param existingSettings
+	 * @param newPropertyDefaults
+	 */
+	private void guessOSXVMwareInfo(Properties newPropertyDefaults) {
+		
+		String product = IVMwareConfiguration.PRODUCT_FUSION;
+		
+		File installPath;
+		
+		installPath = new File("/Applications/VMware Fusion.app");
+		if (!installPath.exists()) {
+			installPath = null;
+		}
+		
+		if (installPath != null) {
+			newPropertyDefaults.put(VMwarePreferenceConstants.VMWARE_INSTALL_PATH, 
+					installPath.getAbsolutePath());
+		}
+		
+		newPropertyDefaults.put(VMwarePreferenceConstants.VMWARE_PRODUCT, 
+				product);
+	}
+	
+	/**
+	 * @param existingSettings
+	 * @param newPropertyDefaults
+	 */
+	private void guessUnixVMwareInfo(Properties newPropertyDefaults) {
+		String product = IVMwareConfiguration.PRODUCT_UNKNOWN;
+		IPath exePath = null;
+		String installPath = null;
+		
+		try {
+			Map<String, String> confKeys = VMwareUtils.readKeyValueFile("/etc/vmware/config");
+			installPath = confKeys.get("bindir");
+			if (!new File(installPath).exists()) {
+				installPath = null;
+			
+				String exe = confKeys.get("vmware.fullpath");
+				if (exe != null) {
+					exePath = new Path(exe);
+					if (!exePath.toFile().exists()) {
+						installPath = exePath.removeLastSegments(1).toOSString();
+					}
+				}
+			}
+			
+			String productName = confKeys.get("product.name");
+			if (productName != null) {
+				if (productName.toLowerCase().contains("workstation"))
+					product = IVMwareConfiguration.PRODUCT_WORKSTATION;
+				else if (productName.toLowerCase().contains("server"))
+					product = IVMwareConfiguration.PRODUCT_SERVER;
+				else if (productName.toLowerCase().contains("player"))
+					product = IVMwareConfiguration.PRODUCT_PLAYER;
+			}
+		} catch (CoreException e) {
+			product = IVMwareConfiguration.PRODUCT_WORKSTATION;
+			
+			exePath = MachineUtils.findProgramOnPath(MachineRegistry.getInstance().getLocalMachine(), 
+						"vmrun");
+			if (exePath == null)
+				 exePath = MachineUtils.findProgramOnPath(MachineRegistry.getInstance().getLocalMachine(), 
+						"vmware");
+			
+			if (exePath != null)
+				installPath = exePath.removeLastSegments(1).toOSString();
+		}
+		
+		if (installPath != null) {
+			newPropertyDefaults.put(VMwarePreferenceConstants.VMWARE_INSTALL_PATH, 
+					installPath);
+		}
+	
+		if (product != null) {
+			newPropertyDefaults.put(VMwarePreferenceConstants.VMWARE_PRODUCT, 
+					product);
+		}
+	}
 }

Modified: branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/internal/vm/vmware/VMwareSettingsPreferencePage.java
===================================================================
--- branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/internal/vm/vmware/VMwareSettingsPreferencePage.java	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/internal/vm/vmware/VMwareSettingsPreferencePage.java	2009-10-01 21:01:25 UTC (rev 2251)
@@ -11,11 +11,13 @@
 
 package org.maemo.esbox.internal.vm.vmware;
 
-import java.text.MessageFormat;
+import java.lang.reflect.Field;
 
+import org.eclipse.jface.preference.DirectoryFieldEditor;
 import org.eclipse.jface.preference.FileFieldEditor;
 import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.jface.preference.StringFieldEditor;
+import org.eclipse.jface.preference.RadioGroupFieldEditor;
+import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Text;
 import org.maemo.esbox.internal.api.maemosdk.ui.preferences.BaseMachinePreferencePage;
 import org.maemo.esbox.internal.api.vm.ui.preferences.IVirtualMachineSettingsPreferencePage;
@@ -34,9 +36,11 @@
 public class VMwareSettingsPreferencePage extends BaseComposableFieldEditorPreferencePage implements IVirtualMachineSettingsPreferencePage {
 
 	private FileFieldEditor feVmxPath;
-	private StringFieldEditor feVMWAREExeName;
-	private StringFieldEditor feVMWARELaunchPattern;
+	//private StringFieldEditor feVMWAREExeName;
+	//private StringFieldEditor feVMWARELaunchPattern;
 	/*private*/ final BaseMachinePreferencePage vmPrefPage;
+	private RadioGroupFieldEditor feVMwareProductType;
+	private DirectoryFieldEditor feVMWAREPath;
 
 	/**
 	 * @param preferenceStore 
@@ -56,25 +60,48 @@
 	protected void createFieldEditors() {
 		Text text;
 		
+		String[][] namesAndValues;
+		if (HostUtils.isOSX()) {
+			namesAndValues = new String[][] {
+					{ "Fusion", IVMwareConfiguration.PRODUCT_FUSION }
+			};
+		} else {
+			namesAndValues = new String[][] {
+					{ "Player", IVMwareConfiguration.PRODUCT_PLAYER },
+					{ "Workstation", IVMwareConfiguration.PRODUCT_WORKSTATION },
+					{ "Server", IVMwareConfiguration.PRODUCT_SERVER },
+			};
+		}
+		feVMwareProductType = new RadioGroupFieldEditor(
+				VMwarePreferenceConstants.VMWARE_PRODUCT,
+				"Product Type:",
+				3, namesAndValues,
+				getFieldEditorParent());
+		
+		Composite radioBoxControl = feVMwareProductType.getRadioBoxControl(getFieldEditorParent());
+		radioBoxControl.setToolTipText("Set the VMware product type to use.");
+		addField(feVMwareProductType);
+		
 		/*
-		feVMWAREPath = new NonValidatingDirectoryFieldEditor(
-				VMwarePreferenceConstants.VMWARE_INSTALL_PATH,
-				"Installation directory:", getFieldEditorParent());
-		addField(feVMWAREPath);
-		text = feVMWAREPath.getTextControl(getFieldEditorParent()); 
-		text.setToolTipText(
-			"Specify the full path to a VMware installation.");
-		*/
-		
 		feVMWAREExeName = new FileFieldEditor(
 				VMwarePreferenceConstants.VMWARE_EXE_NAME,
 				"Executable:", getFieldEditorParent());
 		addField(feVMWAREExeName);
 		text = feVMWAREExeName.getTextControl(getFieldEditorParent()); 
 		text.setToolTipText(MessageFormat.format(
-				"Specify the VMware executable to launch{0}.\n\nIf the program lives in the installation directory or on the PATH, provide a bare filename.\n\nOtherwise, provide a full path to the executable.",
-				HostUtils.isOSX() ? "" : " (Player, Server, or Workstation)"));
+				"Specify the VMware executable to launch (for {0}) or the VMware Player executable.",
+				HostUtils.isOSX() ? "Fusion" : "Player, Server, or Workstation"));
+		*/
 		
+		feVMWAREPath = new DirectoryFieldEditor(
+				VMwarePreferenceConstants.VMWARE_INSTALL_PATH,
+				"Installation directory:", getFieldEditorParent());
+		addField(feVMWAREPath);
+		text = feVMWAREPath.getTextControl(getFieldEditorParent()); 
+		text.setToolTipText(
+						"Specify the full path to a VMware installation");
+
+		/*
 		feVMWARELaunchPattern = new StringFieldEditor(
 				VMwarePreferenceConstants.VMWARE_LAUNCH_PATTERN,
 				"Command pattern:",
@@ -83,8 +110,9 @@
 		addField(feVMWARELaunchPattern);
 		text = feVMWARELaunchPattern.getTextControl(getFieldEditorParent());
 		text.setToolTipText(
-			"Specify the specific command pattern to use to launch the virtual machine.");
-
+			"Override the specific command pattern to use to launch the virtual machine.");
+		*/
+		
 		feVmxPath = new NonValidatingFileFieldEditor(
 				VMwarePreferenceConstants.VMWARE_VMX_PATH,
 				"VMX path:", getFieldEditorParent());
@@ -120,8 +148,27 @@
 	 * @see org.maemo.esbox.internal.api.vm.ui.preferences.IVirtualMachineSettingsPreferencePage#saveTo(org.maemo.esbox.vm.core.IVirtualMachineConfiguration)
 	 */
 	public void saveTo(IVirtualMachineConfiguration config) {
-		config.setCommandLaunchPattern(feVMWARELaunchPattern.getStringValue());
-		config.setExecutable(feVMWAREExeName.getStringValue());
-		((IVMwareConfiguration) config).setVmxPath(feVmxPath.getStringValue());
+		//config.setCommandLaunchPattern(feVMWARELaunchPattern.getStringValue());
+		IVMwareConfiguration vconfig = (IVMwareConfiguration) config;
+		vconfig.setInstallPath(feVMWAREPath.getStringValue());
+		vconfig.setVmxPath(feVmxPath.getStringValue());
+		String product = getCurrentProductName();
+		vconfig.setProduct(product);
 	}
+
+	/**
+	 * @return
+	 */
+	private String getCurrentProductName() {
+		// horrible horrible private fields
+		Field field;
+		try {
+			field = RadioGroupFieldEditor.class.getDeclaredField("value");
+			field.setAccessible(true);
+			
+			return (String) field.get(feVMwareProductType);
+		} catch (Exception e) {
+			return null;
+		}
+	}
 }

Modified: branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/internal/vm/vmware/VMwareUtils.java
===================================================================
--- branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/internal/vm/vmware/VMwareUtils.java	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/internal/vm/vmware/VMwareUtils.java	2009-10-01 21:01:25 UTC (rev 2251)
@@ -18,15 +18,32 @@
 import java.net.NetworkInterface;
 import java.net.SocketException;
 import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.eclipse.cdt.utils.WindowsRegistry;
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.maemo.esbox.vm.vmware.IVMwareConfiguration;
+import org.maemo.mica.common.core.HostUtils;
+import org.maemo.mica.common.core.MicaException;
+import org.maemo.mica.common.core.NetworkUtils;
+import org.maemo.mica.common.core.TimeoutProgressMonitor;
+import org.maemo.mica.common.core.machine.MachineRegistry;
+import org.maemo.mica.common.core.process.CommandLineArguments;
+import org.maemo.mica.common.core.process.IProcessLauncher;
+import org.maemo.mica.common.core.process.ProcessLauncherParameters;
+import org.maemo.mica.common.core.process.ProcessLauncherUtils;
+import org.maemo.mica.common.core.process.ShellTemplateSubstitutor;
+import org.maemo.mica.common.core.process.ProcessLauncherUtils.LaunchResults;
 
 import com.nokia.cpp.internal.api.utils.core.FileUtils;
 
@@ -36,17 +53,6 @@
  *
  */
 public class VMwareUtils {
-	/** unknown product */
-	public static String PRODUCT_UNKNOWN = "unknown";
-	/** VMware Player */
-	public static String PRODUCT_PLAYER = "player";
-	/** VMware Fusion */
-	public static String PRODUCT_FUSION = "fusion";
-	/** VMware Workstation (note: value is special) */
-	public static String PRODUCT_WORKSTATION = "ws";
-	/** VMware Server (note: value is special) */
-	public static String PRODUCT_SERVER = "server";
-	
 	public static String NETWORK_CONFIG_HOSTONLY = "hostonly";
 	public static String NETWORK_CONFIG_NAT = "nat";
 	public static String NETWORK_CONFIG_BRIDGED = "bridged";
@@ -101,16 +107,14 @@
 		return addresses;
 	}
 	
-	private static final Pattern VMX_VARIABLE = Pattern.compile("\\s*(\\S+)\\s*=\\s*\"(.*)\"");
-	public static Map<String, String> readVMXFile(String vmx) throws CoreException {
-		if (!vmx.toLowerCase().endsWith(".vmx"))
-			throw new CoreException(Activator.createErrorStatus("This does not look like a VMX file: " + vmx, null));
-		
-		String text = new String(FileUtils.readFileContents(new File(vmx), null));
+	private static final Pattern KEY_VALUE_PATTERN = Pattern.compile("\\s*(\\S+)\\s*=\\s*\"(.*)\"");
+	
+	public static Map<String, String> readKeyValueFile(String file) throws CoreException {
+		String text = new String(FileUtils.readFileContents(new File(file), null));
 		String[] lines = text.split("(\r\n|\r|\n)");
 		Map<String, String> settings = new LinkedHashMap<String, String>();
 		for (String line : lines) {
-			Matcher matcher = VMX_VARIABLE.matcher(line);
+			Matcher matcher = KEY_VALUE_PATTERN.matcher(line);
 			if (matcher.matches()) {
 				settings.put(matcher.group(1), matcher.group(2));
 			}
@@ -118,18 +122,36 @@
 		return settings;
 	}
 	
+	public static Map<String, String> readVMXFile(String vmx) throws CoreException {
+		if (!vmx.toLowerCase().endsWith(".vmx"))
+			throw new CoreException(Activator.createErrorStatus("This does not look like a VMX file: " + vmx, null));
+		
+		return readKeyValueFile(vmx);
+	}
+	
 	/**
 	 * Get the first network configuration
 	 * @param vmxSettings
 	 * @return String, {@value #NETWORK_CONFIG_BRIDGED}, {@value #NETWORK_CONFIG_HOSTONLY}, {@value #NETWORK_CONFIG_NAT}
 	 */
 	public static String getNetworkConfig(Map<String, String> vmxSettings) {
+		String config = null;
 		for (Map.Entry<String, String> entry : vmxSettings.entrySet()) {
+			if (entry.getKey().matches("ethernet.*\\.vnet")) {
+				String vmnet = entry.getValue();
+				if (vmnet.endsWith("vmnet8")) {
+					return NETWORK_CONFIG_NAT;
+				} else if (vmnet.endsWith("vmnet1")) {
+					return NETWORK_CONFIG_HOSTONLY;
+				} else if (vmnet.endsWith("vmnet0")) {
+					return NETWORK_CONFIG_BRIDGED;
+				} 
+			}
 			if (entry.getKey().matches("ethernet.*\\.connectionType")) {
-				return entry.getValue();
+				config = entry.getValue();
 			}
 		}
-		return null;
+		return config;
 	}
 
 	/**
@@ -147,12 +169,14 @@
 				for (int last = 131; last > 128; last--) {
 					addr[3] = (byte) last;
 					InetAddress candidate = InetAddress.getByAddress(addr);
-					try {
-						if (candidate.isReachable(100)) {
-							return candidate;
+					if (!NetworkUtils.isLocalAddress(candidate)) {
+						try {
+							if (candidate.isReachable(100)) {
+								return candidate;
+							}
+						} catch (IOException e) {
+							// nope
 						}
-					} catch (IOException e) {
-						// nope
 					}
 				}
 				
@@ -211,16 +235,137 @@
 	 */
 	public static String guessProductFromPath(String exePath) {
 		if (exePath == null) 
-			return PRODUCT_UNKNOWN;
+			return IVMwareConfiguration.PRODUCT_UNKNOWN;
 		String lower = exePath.toLowerCase();
 		if (lower.contains("player"))
-			return PRODUCT_PLAYER;
+			return IVMwareConfiguration.PRODUCT_PLAYER;
 		if (lower.contains("server"))
-			return PRODUCT_SERVER;
+			return IVMwareConfiguration.PRODUCT_SERVER;
 		if (lower.contains("workstation"))
-			return PRODUCT_WORKSTATION;
+			return IVMwareConfiguration.PRODUCT_WORKSTATION;
 		if (lower.contains("fusion"))
-			return PRODUCT_FUSION;
-		return PRODUCT_UNKNOWN;
+			return IVMwareConfiguration.PRODUCT_FUSION;
+		return IVMwareConfiguration.PRODUCT_UNKNOWN;
 	}
+	
+	/**
+	 * Get the path to vmrun from the path either to vmware or vmrun itself.
+	 * @param path the full path to installation
+	 * @return updated path to vmrun, or <code>null</code> if we can't find it.
+	 */
+	public static File findVmrunExecutable(String installPath) {
+		File installdir = new File(installPath);
+		if (HostUtils.isOSX()) {
+			// vmrun is jammed in a different location
+			for (String productName : installPath.split("/")) {
+				if (productName.toLowerCase().contains("vmware")
+						&& productName.endsWith(".app")) {
+					productName = productName.substring(0, productName.length() - 4);
+					String vmrunSuffix = "/Library/Application Support/" + productName + "/vmrun";
+					
+					File runFile;
+					
+					// maybe local install
+					IPath homeDir = MachineRegistry.getInstance().getLocalMachine().getUserHome();
+					runFile = homeDir.append(vmrunSuffix).toFile();
+					if (runFile.exists()) {
+						return runFile;
+					}
+					
+					// likelier
+					runFile = new File(vmrunSuffix);
+					if (runFile.exists()) {
+						return runFile;
+					}
+				}
+			}
+		}
+		
+		// fall through (in case OS X ever follows other OS patterns)
+		if (installdir.exists()) {
+			File runFile = new File(installdir, 
+					HostUtils.isWindows() ? "vmrun.exe" : "vmrun");
+			if (runFile.exists()) {
+				return runFile;
+			}
+		}
+		
+		return null;
+	}
+
+	/**
+	 * Create a command line that launches vmrun.
+	 * @return command line
+	 */
+	public static List<String> createVmrunCmdLine(IVMwareConfiguration configuration,
+			String command, String... arguments) {
+		String launchPattern = "\"${VMWARE_EXECUTABLE}\" -T ${VMWARE_PRODUCT} ${COMMAND} ${ARGUMENTS}";
+		ShellTemplateSubstitutor substitutor = new ShellTemplateSubstitutor();
+		
+		File vmrun = VMwareUtils.findVmrunExecutable(configuration.getInstallPath());
+		if (vmrun == null)
+			return null;
+		
+		substitutor.define("VMWARE_EXECUTABLE", vmrun.getAbsolutePath());
+		substitutor.define("VMWARE_PRODUCT", configuration.getProduct());
+		substitutor.define("COMMAND", command);
+		substitutor.define("ARGUMENTS", CommandLineArguments.toCommandLine(Arrays.asList(arguments)));
+		
+		launchPattern = substitutor.substitute(launchPattern);
+		List<String> cmdLine = CommandLineArguments.createFromHostCommandLine(launchPattern);
+		return cmdLine;
+	}
+	
+	
+	/**
+	 * Run vmrun for the given command and arguments, packaging results.
+	 * @param command
+	 * @param arguments
+	 * @param timeout in seconds
+	 * @return Results if ran, else <code>null</code> if no vmrun known or failed to launch (error logged)
+	 */
+	public static LaunchResults launchAndRunVmrun(IVMwareConfiguration configuration, int timeout, 
+			String command, String... arguments) {
+		List<String> cmdLine = createVmrunCmdLine(configuration, command, arguments);
+		if (cmdLine == null) {
+			return null;
+		}
+		LaunchResults results = null;
+		try {
+			IProcessLauncher processLauncher = MachineRegistry.getInstance().getLocalMachine().getProcessLauncherFactory().createProcessLauncher(
+			ProcessLauncherParameters.create(cmdLine));
+			results = ProcessLauncherUtils.launchAndReadStandardStreams(
+					processLauncher, new TimeoutProgressMonitor(timeout * 1000));
+		} catch (MicaException e) {
+			Activator.getErrorLogger().logError("Failed to run vmrun tool", e);
+		}
+		return results;
+	}
+
+	/**
+	 * Get the list of running machines.
+	 * @return array of running VMXs, or <code>null</code> if vmrun can 
+	 */
+	public static IPath[] getRunningVMXs(IVMwareConfiguration config) {
+		LaunchResults results = launchAndRunVmrun(config, 60, "list");
+		if (results == null)
+			return null;
+		
+		if (results.exitCode != 0) {
+			Activator.getErrorLogger().logError(
+					results.reportResults("Failed to list running virtual machines"), 
+					null);
+		}
+		
+		List<IPath> vmxPaths = new ArrayList<IPath>();
+		for (String line : results.getStdoutLines()) {
+			IPath vmxPath = new Path(line);
+			if (vmxPath.toFile().exists()) {
+				vmxPaths.add(vmxPath);
+			}
+		}
+		return (IPath[]) vmxPaths.toArray(new IPath[vmxPaths.size()]);
+	}
+
+
 }

Modified: branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/vm/vmware/IVMwareConfiguration.java
===================================================================
--- branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/vm/vmware/IVMwareConfiguration.java	2009-10-01 14:38:54 UTC (rev 2250)
+++ branches/work_Andre/org.maemo.esbox.vm.vmware/src/org/maemo/esbox/vm/vmware/IVMwareConfiguration.java	2009-10-01 21:01:25 UTC (rev 2251)
@@ -24,6 +24,23 @@
  */
 public interface IVMwareConfiguration extends IVirtualMachineConfiguration {
 
+	/** unknown product */
+	public static String PRODUCT_UNKNOWN = "unknown";
+	/** VMware Player */
+	public static String PRODUCT_PLAYER = "player";
+	/** VMware Fusion */
+	public static String PRODUCT_FUSION = "fusion";
+	/** VMware Workstation (note: value is special) */
+	public static String PRODUCT_WORKSTATION = "ws";
+	/** VMware Server (note: value is special) */
+	public static String PRODUCT_SERVER = "server";
+
+	/** Get the full path of the VMware installation */
+	String getInstallPath();
+	
+	/** Set the full path of the VMware installation */
+	void setInstallPath(String path);
+
 	/** Get the VMX path 
 	 * @return full path to *.vmx file
 	 */
@@ -35,4 +52,26 @@
 	 */
 	void setVmxPath(String path);
 	
+	/**
+	 * Get the VMware product type
+	 * @return String 
+	 * @value {@value #PRODUCT_FUSION}
+	 * @value {@value #PRODUCT_PLAYER}
+	 * @value {@value #PRODUCT_SERVER}
+	 * @value {@value #PRODUCT_WORKSTATION}
+	 * @value {@value #PRODUCT_UNKNOWN}
+	 */
+	String getProduct();
+	
+	/**
+	 * Set the VMware product type
+	 * @param type String 
+	 * @value {@value #PRODUCT_FUSION}
+	 * @value {@value #PRODUCT_PLAYER}
+	 * @value {@value #PRODUCT_SERVER}
+	 * @value {@value #PRODUCT_WORKSTATION}
+	 * @value {@value #PRODUCT_UNKNOWN}
+	 */
+	void setProduct(String product);
+	
 }



More information about the Esbox-commits mailing list