Add support for VMWare Workstation on Windows XP, fixes #237

This commit is contained in:
Ross Smith II 2013-08-01 23:55:56 -07:00 committed by Mitchell Hashimoto
parent 72a7a5e69c
commit d4c45b412e
4 changed files with 130 additions and 44 deletions

View File

@ -135,3 +135,7 @@ func (d *Workstation9Driver) ToolsIsoPath(flavor string) string {
func (d *Workstation9Driver) DhcpLeasesPath(device string) string { func (d *Workstation9Driver) DhcpLeasesPath(device string) string {
return workstationDhcpLeasesPath(device) return workstationDhcpLeasesPath(device)
} }
func (d *Workstation9Driver) VmnetnatConfPath() string {
return workstationVmnetnatConfPath()
}

View File

@ -41,3 +41,7 @@ func workstationDhcpLeasesPath(device string) string {
func workstationToolsIsoPath(flavor string) string { func workstationToolsIsoPath(flavor string) string {
return "/usr/lib/vmware/isoimages/" + flavor + ".iso" return "/usr/lib/vmware/isoimages/" + flavor + ".iso"
} }
func workstationVmnetnatConfPath() string {
return ""
}

View File

@ -18,63 +18,44 @@ func workstationCheckLicense() error {
} }
func workstationFindVdiskManager() (string, error) { func workstationFindVdiskManager() (string, error) {
path, err := exec.LookPath("vmware-vdiskmanager.exe") path, _ := exec.LookPath("vmware-vdiskmanager.exe")
if err == nil { if fileExists(path) {
return path, nil return path, nil
} }
path, err = workstationVMwareRoot() return findProgramFile("vmware-vdiskmanager.exe"), nil
if err != nil {
return "", err
}
return filepath.Join(path, "vmware-vdiskmanager.exe"), nil
} }
func workstationFindVMware() (string, error) { func workstationFindVMware() (string, error) {
path, err := exec.LookPath("vmware.exe") path, _ := exec.LookPath("vmware.exe")
if err == nil { if fileExists(path) {
return path, nil return path, nil
} }
path, err = workstationVMwareRoot() return findProgramFile("vmware.exe"), nil
if err != nil {
return "", err
}
return filepath.Join(path, "vmware.exe"), nil
} }
func workstationFindVmrun() (string, error) { func workstationFindVmrun() (string, error) {
path, err := exec.LookPath("vmrun.exe") path, _ := exec.LookPath("vmrun.exe")
if err == nil { if fileExists(path) {
return path, nil return path, nil
} }
path, err = workstationVMwareRoot() return findProgramFile("vmrun.exe"), nil
if err != nil {
return "", err
}
return filepath.Join(path, "vmrun.exe"), nil
} }
func workstationToolsIsoPath(flavor string) string { func workstationToolsIsoPath(flavor string) string {
path, err := workstationVMwareRoot() return findProgramFile(flavor + ".iso")
if err != nil {
return ""
}
return filepath.Join(path, flavor+".iso")
} }
func workstationDhcpLeasesPath(device string) string { func workstationDhcpLeasesPath(device string) string {
programData := os.Getenv("ProgramData") path, _ := workstationVmnetDhcpLeasesPathFromRegistry()
if programData == "" {
return "" if fileExists(path) {
return path
} }
return filepath.Join(programData, "/VMware/vmnetdhcp.leases") return findDataFile("vmnetdhcp.leases")
} }
// See http://blog.natefinch.com/2012/11/go-win-stuff.html // See http://blog.natefinch.com/2012/11/go-win-stuff.html
@ -126,6 +107,101 @@ func workstationVMwareRoot() (s string, err error) {
return return
} }
s = strings.Replace(s, "\\", "/", -1) return normalizePath(s), nil
return }
// This reads the VMware DHCP leases path from the Windows registry.
func workstationVmnetDhcpLeasesPathFromRegistry() (s string, err error) {
key := "SYSTEM\\CurrentControlSet\\services\\VMnetDHCP\\Parameters"
subkey := "LeaseFile"
s, err = readRegString(syscall.HKEY_LOCAL_MACHINE, key, subkey)
if err != nil {
log.Printf(`Unable to read registry key %s\%s`, key, subkey)
return
}
return normalizePath(s), nil
}
func fileExists(file string) bool {
if file == "" {
return false
}
if _, err := os.Stat(file); err != nil {
if os.IsNotExist(err) {
return false
}
log.Println(err.Error())
}
return true
}
func normalizePath(path string) string {
path = strings.Replace(path, "\\", "/", -1)
path = strings.Replace(path, "//", "/", -1)
path = strings.TrimRight(path, "/")
return path
}
type Paths [][]string
func findFile(file string, paths Paths) string {
for _, a := range paths {
if a[0] == "" {
continue
}
path := filepath.Join(a[0], a[1], file)
path = normalizePath(path)
log.Printf("Searching for file '%s'", path)
if fileExists(path) {
log.Printf("Found file '%s'", path)
return path
}
}
log.Printf("File not found: '%s'", file)
return ""
}
func findProgramFile(file string) string {
path, _ := workstationVMwareRoot()
paths := Paths{
[]string{os.Getenv("VMWARE_HOME"), ""},
[]string{path, ""},
[]string{os.Getenv("ProgramFiles(x86)"), "/VMware/VMware Workstation"},
[]string{os.Getenv("ProgramFiles"), "/VMware/VMware Workstation"},
}
return findFile(file, paths)
}
func findDataFile(file string) string {
path, _ := workstationVmnetDhcpLeasesPathFromRegistry()
if path != "" {
path = filepath.Dir(path)
}
paths := Paths{
[]string{os.Getenv("VMWARE_DATA"), ""},
[]string{path, ""},
[]string{os.Getenv("ProgramData"), "/VMWare"},
[]string{os.Getenv("ALLUSERSPROFILE"), "/VMWare"},
}
return findFile(file, paths)
}
func workstationVmnetnatConfPath() string {
const VMNETNAT_CONF = "vmnetnat.conf"
return findDataFile(VMNETNAT_CONF)
} }

View File

@ -6,7 +6,6 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"path/filepath"
"regexp" "regexp"
"strings" "strings"
) )
@ -17,15 +16,18 @@ import (
type VMnetNatConfIPFinder struct{} type VMnetNatConfIPFinder struct{}
func (*VMnetNatConfIPFinder) HostIP() (string, error) { func (*VMnetNatConfIPFinder) HostIP() (string, error) {
programData := os.Getenv("ProgramData") const VMNETNAT_CONF = "vmnetnat.conf"
if programData == "" {
return "", errors.New("ProgramData directory not found.") driver := &Workstation9Driver{}
vmnetnat := driver.VmnetnatConfPath()
if vmnetnat == "" {
return "", fmt.Errorf("Could not find %s", VMNETNAT_CONF)
} }
programData = strings.Replace(programData, "\\", "/", -1)
vmnetnat := filepath.Join(programData, "/VMware/vmnetnat.conf")
if _, err := os.Stat(vmnetnat); err != nil { if _, err := os.Stat(vmnetnat); err != nil {
return "", fmt.Errorf("Error with vmnetnat.conf: %s", err) return "", fmt.Errorf("Error with %s: %s", VMNETNAT_CONF, err)
} }
f, err := os.Open(vmnetnat) f, err := os.Open(vmnetnat)
@ -62,5 +64,5 @@ func (*VMnetNatConfIPFinder) HostIP() (string, error) {
} }
} }
return "", errors.New("host IP not found in NAT config") return "", errors.New("host IP not found in " + vmnetnat)
} }