diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-05-01 11:14:12 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-05-01 11:14:12 +0200 |
commit | 2e4f8e31dad639e9e40b29552380d5ca4629d1bd (patch) | |
tree | ec8573073bf68253267ed741b60bf23b8e4554a3 | |
parent | ui: support clipboard copying for log items (diff) | |
download | wireguard-windows-2e4f8e31dad639e9e40b29552380d5ca4629d1bd.tar.xz wireguard-windows-2e4f8e31dad639e9e40b29552380d5ca4629d1bd.zip |
version: dynamically get file version
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | installer/build.bat | 2 | ||||
-rw-r--r-- | quickinstall.bat | 2 | ||||
-rw-r--r-- | resources.rc | 8 | ||||
-rw-r--r-- | ui/ui.go | 2 | ||||
-rw-r--r-- | updater/versions.go | 2 | ||||
-rw-r--r-- | version.h | 3 | ||||
-rw-r--r-- | version/debugging_linux.go (renamed from version/os_linux.go) | 14 | ||||
-rw-r--r-- | version/mksyscall.go | 2 | ||||
-rw-r--r-- | version/official_linux.go | 12 | ||||
-rw-r--r-- | version/useragent.go (renamed from version/version.go) | 6 | ||||
-rw-r--r-- | version/version_windows.go | 83 | ||||
-rw-r--r-- | version/zsyscall_windows.go | 45 |
13 files changed, 147 insertions, 36 deletions
@@ -8,7 +8,7 @@ export GOROOT := $(PWD)/.deps/goroot rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d)) SOURCE_FILES := $(call rwildcard,,*.go *.c *.h) .deps/prepared -RESOURCE_FILES := resources.rc manifest.xml ui/icon/icon.ico +RESOURCE_FILES := resources.rc version.h manifest.xml ui/icon/icon.ico DEPLOYMENT_HOST ?= winvm DEPLOYMENT_PATH ?= Desktop diff --git a/installer/build.bat b/installer/build.bat index 918f932a..e3513d54 100644 --- a/installer/build.bat +++ b/installer/build.bat @@ -2,7 +2,7 @@ rem SPDX-License-Identifier: MIT rem Copyright (C) 2019 WireGuard LLC. All Rights Reserved. -for /f "tokens=3" %%a in ('findstr /r "[0-9.]*" ..\version.h') do set WIREGUARD_VERSION=%%a +for /f "tokens=3" %%a in ('findstr /r "WIREGUARD_WINDOWS_VERSION_STRING.*[0-9.]*" ..\version.h') do set WIREGUARD_VERSION=%%a set WIREGUARD_VERSION=%WIREGUARD_VERSION:"=% set STARTDIR=%cd% diff --git a/quickinstall.bat b/quickinstall.bat index cd62f8e3..f7f0c3c3 100644 --- a/quickinstall.bat +++ b/quickinstall.bat @@ -10,7 +10,7 @@ call .\build.bat || exit /b 1 echo [+] Uninstalling old versions for /f %%a in ('reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /s /d /c /e /f WireGuard ^| findstr CurrentVersion\Uninstall') do msiexec /qb /x %%~na echo [+] Installing new version -for /f "tokens=3" %%a in ('findstr /r "[0-9.]*" ..\version.h') do set WIREGUARD_VERSION=%%a +for /f "tokens=3" %%a in ('findstr /r "WIREGUARD_WINDOWS_VERSION_STRING.*[0-9.]*" ..\version.h') do set WIREGUARD_VERSION=%%a set WIREGUARD_VERSION=%WIREGUARD_VERSION:"=% @echo on cd .\dist diff --git a/resources.rc b/resources.rc index fd3a521d..1677ae13 100644 --- a/resources.rc +++ b/resources.rc @@ -11,8 +11,8 @@ CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST manifest.xml 1 ICON ui/icon/icon.ico VS_VERSION_INFO VERSIONINFO -FILEVERSION 0,0,0,1 -PRODUCTVERSION 0,0,0,1 +FILEVERSION WIREGUARD_WINDOWS_VERSION_ARRAY +PRODUCTVERSION WIREGUARD_WINDOWS_VERSION_ARRAY FILEOS VOS_NT_WINDOWS32 FILETYPE VFT_APP FILESUBTYPE VFT2_UNKNOWN @@ -23,12 +23,12 @@ BEGIN BEGIN VALUE "CompanyName", "WireGuard LLC" VALUE "FileDescription", "WireGuard: Fast, Modern, Secure VPN Tunnel" - VALUE "FileVersion", WIREGUARD_WINDOWS_VERSION + VALUE "FileVersion", WIREGUARD_WINDOWS_VERSION_STRING VALUE "InternalName", "wireguard" VALUE "LegalCopyright", "Copyright \xa9 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved." VALUE "OriginalFilename", "wireguard.exe" VALUE "ProductName", "WireGuard" - VALUE "ProductVersion", WIREGUARD_WINDOWS_VERSION + VALUE "ProductVersion", WIREGUARD_WINDOWS_VERSION_STRING VALUE "Comments", "https://www.wireguard.com/" END END @@ -155,7 +155,7 @@ Golang version: %s %s Copyright © 2015-2019 WireGuard LLC. All Rights Reserved.`, - version.WireGuardWindowsVersion, device.WireGuardGoVersion, runtime.Version(), runtime.GOARCH, version.OsName())) + version.RunningVersion(), device.WireGuardGoVersion, runtime.Version(), runtime.GOARCH, version.OsName())) hbl := walk.NewHBoxLayout() hbl.SetMargins(walk.Margins{VNear: 10}) diff --git a/updater/versions.go b/updater/versions.go index a5b6c258..3d1fd38f 100644 --- a/updater/versions.go +++ b/updater/versions.go @@ -16,7 +16,7 @@ import ( func versionNewerThanUs(candidate string) (bool, error) { candidateParts := strings.Split(candidate, ".") - ourParts := strings.Split(version.WireGuardWindowsVersion, ".") + ourParts := strings.Split(version.RunningVersion(), ".") if len(candidateParts) == 0 || len(ourParts) == 0 { return false, errors.New("Empty version") } @@ -1 +1,2 @@ -#define WIREGUARD_WINDOWS_VERSION "0.0.1" +#define WIREGUARD_WINDOWS_VERSION_ARRAY 0,0,1 +#define WIREGUARD_WINDOWS_VERSION_STRING "0.0.1" diff --git a/version/os_linux.go b/version/debugging_linux.go index 7e5c4f1c..df5dbd2f 100644 --- a/version/os_linux.go +++ b/version/debugging_linux.go @@ -5,13 +5,11 @@ package version -import ( - "bytes" - "fmt" - "golang.org/x/sys/unix" -) +// For testing the updater package from linux. Debug stuff only. -// This isn't a Linux program, yes, but having the updater package work across platforms is quite helpful for testing. +func IsOfficialPath(path string) bool { + return true +} func utsToStr(u [65]byte) string { i := bytes.IndexByte(u[:], 0) @@ -28,3 +26,7 @@ func OsName() string { } return fmt.Sprintf("%s %s %s", utsToStr(utsname.Sysname), utsToStr(utsname.Release), utsToStr(utsname.Version)) } + +func RunningVersion() string { + return "0.0.0.0" +} diff --git a/version/mksyscall.go b/version/mksyscall.go index abd538e5..3c993928 100644 --- a/version/mksyscall.go +++ b/version/mksyscall.go @@ -5,4 +5,4 @@ package version -//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go os_windows.go +//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go os_windows.go version_windows.go diff --git a/version/official_linux.go b/version/official_linux.go deleted file mode 100644 index d3ca3349..00000000 --- a/version/official_linux.go +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. - */ - -package version - -// For testing the updater package from linux. Debug stuff only. - -func IsOfficialPath(path string) bool { - return true -} diff --git a/version/version.go b/version/useragent.go index 951d2731..321bc0a6 100644 --- a/version/version.go +++ b/version/useragent.go @@ -5,16 +5,12 @@ package version -// #include "../version.h" -import "C" import ( "fmt" "golang.zx2c4.com/wireguard/device" "runtime" ) -const WireGuardWindowsVersion = C.WIREGUARD_WINDOWS_VERSION - func UserAgent() string { - return fmt.Sprintf("WireGuard/%s (wireguard-go %s; %s; %s; %s)", WireGuardWindowsVersion, device.WireGuardGoVersion, OsName(), runtime.Version(), runtime.GOARCH) + return fmt.Sprintf("WireGuard/%s (wireguard-go %s; %s; %s; %s)", RunningVersion(), device.WireGuardGoVersion, OsName(), runtime.Version(), runtime.GOARCH) } diff --git a/version/version_windows.go b/version/version_windows.go new file mode 100644 index 00000000..e567e7a0 --- /dev/null +++ b/version/version_windows.go @@ -0,0 +1,83 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. + */ + +package version + +import ( + "errors" + "fmt" + "golang.org/x/sys/windows" + "os" + "runtime" + "strings" + "unsafe" +) + +//sys GetFileVersionInfoSize(filename *uint16, zero *uint32) (size uint32, err error) = version.GetFileVersionInfoSizeW +//sys GetFileVersionInfo(filename *uint16, zero uint32, size uint32, block *byte) (err error) = version.GetFileVersionInfoW +//sys VerQueryValue(block *byte, section *uint16, value **byte, size *uint32) (err error) = version.VerQueryValueW + +type vsFixedFileInfo struct { + Signature uint32 + StrucVersion uint32 + FileVersionMS uint32 + FileVersionLS uint32 + ProductVersionMS uint32 + ProductVersionLS uint32 + FileFlagsMask uint32 + FileFlags uint32 + FileOS uint32 + FileType uint32 + FileSubtype uint32 + FileDateMS uint32 + FileDateLS uint32 +} + +const vsFixedFileInfoSignature = 0xFEEF04BD + +var cachedVersion string + +func RunningVersion() string { + if len(cachedVersion) != 0 { + return cachedVersion + } + key16 := []uint16{'\\', 0x00} + self, err := os.Executable() + if err != nil { + panic(err) + } + self16, err := windows.UTF16PtrFromString(self) + if err != nil { + panic(err) + } + var zero uint32 + size, err := GetFileVersionInfoSize(self16, &zero) + if err != nil { + panic(err) + } + buffer := make([]byte, size) + err = GetFileVersionInfo(self16, zero, size, &buffer[0]) + if err != nil { + panic(err) + } + var fixedFileInfo *vsFixedFileInfo + err = VerQueryValue(&buffer[0], &key16[0], (**byte)(unsafe.Pointer(&fixedFileInfo)), &size) + if err != nil { + panic(err) + } + if uintptr(size) < unsafe.Sizeof(vsFixedFileInfo{}) || fixedFileInfo == nil || fixedFileInfo.Signature != vsFixedFileInfoSignature { + panic(errors.New("Incorrect return of VS_FIXEDFILEINFO")) + } + version := fmt.Sprintf("%d.%d.%d.%d", (fixedFileInfo.FileVersionMS>>16)&0xffff, (fixedFileInfo.FileVersionMS>>0)&0xffff, (fixedFileInfo.FileVersionLS>>16)&0xffff, (fixedFileInfo.FileVersionLS>>0)&0xffff) + runtime.KeepAlive(buffer) // The win32 API aliases it in fixedFileInfo, but Go doesn't know that. + if strings.HasSuffix(version, ".0") { + version = version[:len(version)-2] + } + if strings.HasSuffix(version, ".0") { + version = version[:len(version)-2] + } + cachedVersion = version + return version +} diff --git a/version/zsyscall_windows.go b/version/zsyscall_windows.go index 9f11ce70..ef4e11d7 100644 --- a/version/zsyscall_windows.go +++ b/version/zsyscall_windows.go @@ -37,9 +37,13 @@ func errnoErr(e syscall.Errno) error { } var ( - modntdll = windows.NewLazySystemDLL("ntdll.dll") + modntdll = windows.NewLazySystemDLL("ntdll.dll") + modversion = windows.NewLazySystemDLL("version.dll") - procRtlGetVersion = modntdll.NewProc("RtlGetVersion") + procRtlGetVersion = modntdll.NewProc("RtlGetVersion") + procGetFileVersionInfoSizeW = modversion.NewProc("GetFileVersionInfoSizeW") + procGetFileVersionInfoW = modversion.NewProc("GetFileVersionInfoW") + procVerQueryValueW = modversion.NewProc("VerQueryValueW") ) func rtlGetVersion(versionInfo *osVersionInfo) (nterr uint32) { @@ -47,3 +51,40 @@ func rtlGetVersion(versionInfo *osVersionInfo) (nterr uint32) { nterr = uint32(r0) return } + +func GetFileVersionInfoSize(filename *uint16, zero *uint32) (size uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetFileVersionInfoSizeW.Addr(), 2, uintptr(unsafe.Pointer(filename)), uintptr(unsafe.Pointer(zero)), 0) + size = uint32(r0) + if size == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func GetFileVersionInfo(filename *uint16, zero uint32, size uint32, block *byte) (err error) { + r1, _, e1 := syscall.Syscall6(procGetFileVersionInfoW.Addr(), 4, uintptr(unsafe.Pointer(filename)), uintptr(zero), uintptr(size), uintptr(unsafe.Pointer(block)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func VerQueryValue(block *byte, section *uint16, value **byte, size *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procVerQueryValueW.Addr(), 4, uintptr(unsafe.Pointer(block)), uintptr(unsafe.Pointer(section)), uintptr(unsafe.Pointer(value)), uintptr(unsafe.Pointer(size)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} |