github.com/sneal/packer@v0.5.2/builder/vmware/common/driver_workstation9_windows.go (about) 1 // +build windows 2 3 package common 4 5 import ( 6 "log" 7 "os" 8 "os/exec" 9 "path/filepath" 10 "strings" 11 "syscall" 12 "unsafe" 13 ) 14 15 func workstationCheckLicense() error { 16 // Not implemented on Windows 17 return nil 18 } 19 20 func workstationFindVdiskManager() (string, error) { 21 path, err := exec.LookPath("vmware-vdiskmanager.exe") 22 if err == nil { 23 return path, nil 24 } 25 26 return findFile("vmware-vdiskmanager.exe", workstationProgramFilePaths()), nil 27 } 28 29 func workstationFindVMware() (string, error) { 30 path, err := exec.LookPath("vmware.exe") 31 if err == nil { 32 return path, nil 33 } 34 35 return findFile("vmware.exe", workstationProgramFilePaths()), nil 36 } 37 38 func workstationFindVmrun() (string, error) { 39 path, err := exec.LookPath("vmrun.exe") 40 if err == nil { 41 return path, nil 42 } 43 44 return findFile("vmrun.exe", workstationProgramFilePaths()), nil 45 } 46 47 func workstationToolsIsoPath(flavor string) string { 48 return findFile(flavor+".iso", workstationProgramFilePaths()) 49 } 50 51 func workstationDhcpLeasesPath(device string) string { 52 path, err := workstationDhcpLeasesPathRegistry() 53 if err != nil { 54 log.Printf("Error finding leases in registry: %s", err) 55 } else if _, err := os.Stat(path); err == nil { 56 return path 57 } 58 59 return findFile("vmnetdhcp.leases", workstationDataFilePaths()) 60 } 61 62 func workstationVmnetnatConfPath() string { 63 return findFile("vmnetnat.conf", workstationDataFilePaths()) 64 } 65 66 // See http://blog.natefinch.com/2012/11/go-win-stuff.html 67 // 68 // This is used by workstationVMwareRoot in order to read some registry data. 69 func readRegString(hive syscall.Handle, subKeyPath, valueName string) (value string, err error) { 70 var h syscall.Handle 71 err = syscall.RegOpenKeyEx(hive, syscall.StringToUTF16Ptr(subKeyPath), 0, syscall.KEY_READ, &h) 72 if err != nil { 73 return 74 } 75 defer syscall.RegCloseKey(h) 76 77 var typ uint32 78 var bufSize uint32 79 err = syscall.RegQueryValueEx( 80 h, 81 syscall.StringToUTF16Ptr(valueName), 82 nil, 83 &typ, 84 nil, 85 &bufSize) 86 if err != nil { 87 return 88 } 89 90 data := make([]uint16, bufSize/2+1) 91 err = syscall.RegQueryValueEx( 92 h, 93 syscall.StringToUTF16Ptr(valueName), 94 nil, 95 &typ, 96 (*byte)(unsafe.Pointer(&data[0])), 97 &bufSize) 98 if err != nil { 99 return 100 } 101 102 return syscall.UTF16ToString(data), nil 103 } 104 105 // This reads the VMware installation path from the Windows registry. 106 func workstationVMwareRoot() (s string, err error) { 107 key := `SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\vmware.exe` 108 subkey := "Path" 109 s, err = readRegString(syscall.HKEY_LOCAL_MACHINE, key, subkey) 110 if err != nil { 111 log.Printf(`Unable to read registry key %s\%s`, key, subkey) 112 return 113 } 114 115 return normalizePath(s), nil 116 } 117 118 // This reads the VMware DHCP leases path from the Windows registry. 119 func workstationDhcpLeasesPathRegistry() (s string, err error) { 120 key := "SYSTEM\\CurrentControlSet\\services\\VMnetDHCP\\Parameters" 121 subkey := "LeaseFile" 122 s, err = readRegString(syscall.HKEY_LOCAL_MACHINE, key, subkey) 123 if err != nil { 124 log.Printf(`Unable to read registry key %s\%s`, key, subkey) 125 return 126 } 127 128 return normalizePath(s), nil 129 } 130 131 func normalizePath(path string) string { 132 path = strings.Replace(path, "\\", "/", -1) 133 path = strings.Replace(path, "//", "/", -1) 134 path = strings.TrimRight(path, "/") 135 return path 136 } 137 138 func findFile(file string, paths []string) string { 139 for _, path := range paths { 140 path = filepath.Join(path, file) 141 path = normalizePath(path) 142 log.Printf("Searching for file '%s'", path) 143 144 if _, err := os.Stat(path); err == nil { 145 log.Printf("Found file '%s'", path) 146 return path 147 } 148 } 149 150 log.Printf("File not found: '%s'", file) 151 return "" 152 } 153 154 // workstationProgramFilesPaths returns a list of paths that are eligible 155 // to contain program files we may want just as vmware.exe. 156 func workstationProgramFilePaths() []string { 157 path, err := workstationVMwareRoot() 158 if err != nil { 159 log.Printf("Error finding VMware root: %s", err) 160 } 161 162 paths := make([]string, 0, 5) 163 if os.Getenv("VMWARE_HOME") != "" { 164 paths = append(paths, os.Getenv("VMWARE_HOME")) 165 } 166 167 if path != "" { 168 paths = append(paths, path) 169 } 170 171 if os.Getenv("ProgramFiles(x86)") != "" { 172 paths = append(paths, 173 filepath.Join(os.Getenv("ProgramFiles(x86)"), "/VMware/VMware Workstation")) 174 } 175 176 if os.Getenv("ProgramFiles") != "" { 177 paths = append(paths, 178 filepath.Join(os.Getenv("ProgramFiles"), "/VMware/VMware Workstation")) 179 } 180 181 return paths 182 } 183 184 // workstationDataFilePaths returns a list of paths that are eligible 185 // to contain data files we may want such as vmnet NAT configuration files. 186 func workstationDataFilePaths() []string { 187 leasesPath, err := workstationDhcpLeasesPathRegistry() 188 if err != nil { 189 log.Printf("Error getting DHCP leases path: %s", err) 190 } 191 192 if leasesPath != "" { 193 leasesPath = filepath.Dir(leasesPath) 194 } 195 196 paths := make([]string, 0, 5) 197 if os.Getenv("VMWARE_DATA") != "" { 198 paths = append(paths, os.Getenv("VMWARE_DATA")) 199 } 200 201 if leasesPath != "" { 202 paths = append(paths, leasesPath) 203 } 204 205 if os.Getenv("ProgramData") != "" { 206 paths = append(paths, 207 filepath.Join(os.Getenv("ProgramData"), "/VMware")) 208 } 209 210 if os.Getenv("ALLUSERSPROFILE") != "" { 211 paths = append(paths, 212 filepath.Join(os.Getenv("ALLUSERSPROFILE"), "/Application Data/VMware")) 213 } 214 215 return paths 216 }