github.phpd.cn/hashicorp/packer@v1.3.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 workstationDhcpConfPath(device string) string { 63 // device isn't used on a windows host 64 return findFile("vmnetdhcp.conf", workstationDataFilePaths()) 65 } 66 67 func workstationVmnetnatConfPath(device string) string { 68 // device isn't used on a windows host 69 return findFile("vmnetnat.conf", workstationDataFilePaths()) 70 } 71 72 func workstationNetmapConfPath() string { 73 return findFile("netmap.conf", workstationDataFilePaths()) 74 } 75 76 // See http://blog.natefinch.com/2012/11/go-win-stuff.html 77 // 78 // This is used by workstationVMwareRoot in order to read some registry data. 79 func readRegString(hive syscall.Handle, subKeyPath, valueName string) (value string, err error) { 80 var h syscall.Handle 81 err = syscall.RegOpenKeyEx(hive, syscall.StringToUTF16Ptr(subKeyPath), 0, syscall.KEY_READ, &h) 82 if err != nil { 83 return 84 } 85 defer syscall.RegCloseKey(h) 86 87 var typ uint32 88 var bufSize uint32 89 err = syscall.RegQueryValueEx( 90 h, 91 syscall.StringToUTF16Ptr(valueName), 92 nil, 93 &typ, 94 nil, 95 &bufSize) 96 if err != nil { 97 return 98 } 99 100 data := make([]uint16, bufSize/2+1) 101 err = syscall.RegQueryValueEx( 102 h, 103 syscall.StringToUTF16Ptr(valueName), 104 nil, 105 &typ, 106 (*byte)(unsafe.Pointer(&data[0])), 107 &bufSize) 108 if err != nil { 109 return 110 } 111 112 return syscall.UTF16ToString(data), nil 113 } 114 115 // This reads the VMware installation path from the Windows registry. 116 func workstationVMwareRoot() (s string, err error) { 117 key := `SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\vmware.exe` 118 subkey := "Path" 119 s, err = readRegString(syscall.HKEY_LOCAL_MACHINE, key, subkey) 120 if err != nil { 121 log.Printf(`Unable to read registry key %s\%s`, key, subkey) 122 return 123 } 124 125 return normalizePath(s), nil 126 } 127 128 // This reads the VMware DHCP leases path from the Windows registry. 129 func workstationDhcpLeasesPathRegistry() (s string, err error) { 130 key := "SYSTEM\\CurrentControlSet\\services\\VMnetDHCP\\Parameters" 131 subkey := "LeaseFile" 132 s, err = readRegString(syscall.HKEY_LOCAL_MACHINE, key, subkey) 133 if err != nil { 134 log.Printf(`Unable to read registry key %s\%s`, key, subkey) 135 return 136 } 137 138 return normalizePath(s), nil 139 } 140 141 func normalizePath(path string) string { 142 path = strings.Replace(path, "\\", "/", -1) 143 path = strings.Replace(path, "//", "/", -1) 144 path = strings.TrimRight(path, "/") 145 return path 146 } 147 148 func findFile(file string, paths []string) string { 149 for _, path := range paths { 150 path = filepath.Join(path, file) 151 path = normalizePath(path) 152 log.Printf("Searching for file '%s'", path) 153 154 if _, err := os.Stat(path); err == nil { 155 log.Printf("Found file '%s'", path) 156 return path 157 } 158 } 159 160 log.Printf("File not found: '%s'", file) 161 return "" 162 } 163 164 // workstationProgramFilesPaths returns a list of paths that are eligible 165 // to contain program files we may want just as vmware.exe. 166 func workstationProgramFilePaths() []string { 167 path, err := workstationVMwareRoot() 168 if err != nil { 169 log.Printf("Error finding VMware root: %s", err) 170 } 171 172 paths := make([]string, 0, 5) 173 if os.Getenv("VMWARE_HOME") != "" { 174 paths = append(paths, os.Getenv("VMWARE_HOME")) 175 } 176 177 if path != "" { 178 paths = append(paths, path) 179 } 180 181 if os.Getenv("ProgramFiles(x86)") != "" { 182 paths = append(paths, 183 filepath.Join(os.Getenv("ProgramFiles(x86)"), "/VMware/VMware Workstation")) 184 } 185 186 if os.Getenv("ProgramFiles") != "" { 187 paths = append(paths, 188 filepath.Join(os.Getenv("ProgramFiles"), "/VMware/VMware Workstation")) 189 } 190 191 return paths 192 } 193 194 // workstationDataFilePaths returns a list of paths that are eligible 195 // to contain data files we may want such as vmnet NAT configuration files. 196 func workstationDataFilePaths() []string { 197 leasesPath, err := workstationDhcpLeasesPathRegistry() 198 if err != nil { 199 log.Printf("Error getting DHCP leases path: %s", err) 200 } 201 202 if leasesPath != "" { 203 leasesPath = filepath.Dir(leasesPath) 204 } 205 206 paths := make([]string, 0, 5) 207 if os.Getenv("VMWARE_DATA") != "" { 208 paths = append(paths, os.Getenv("VMWARE_DATA")) 209 } 210 211 if leasesPath != "" { 212 paths = append(paths, leasesPath) 213 } 214 215 if os.Getenv("ProgramData") != "" { 216 paths = append(paths, 217 filepath.Join(os.Getenv("ProgramData"), "/VMware")) 218 } 219 220 if os.Getenv("ALLUSERSPROFILE") != "" { 221 paths = append(paths, 222 filepath.Join(os.Getenv("ALLUSERSPROFILE"), "/Application Data/VMware")) 223 } 224 225 return paths 226 }