aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-05-01 11:14:12 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2019-05-01 11:14:12 +0200
commitcff4e77bfe62606c19c205e02fd63b3777855392 (patch)
treeec8573073bf68253267ed741b60bf23b8e4554a3
parentui: support clipboard copying for log items (diff)
downloadwireguard-windows-cff4e77bfe62606c19c205e02fd63b3777855392.tar.xz
wireguard-windows-cff4e77bfe62606c19c205e02fd63b3777855392.zip
version: dynamically get file version
-rw-r--r--Makefile2
-rw-r--r--installer/build.bat2
-rw-r--r--quickinstall.bat2
-rw-r--r--resources.rc8
-rw-r--r--ui/ui.go2
-rw-r--r--updater/versions.go2
-rw-r--r--version.h3
-rw-r--r--version/debugging_linux.go (renamed from version/os_linux.go)14
-rw-r--r--version/mksyscall.go2
-rw-r--r--version/official_linux.go12
-rw-r--r--version/useragent.go (renamed from version/version.go)6
-rw-r--r--version/version_windows.go83
-rw-r--r--version/zsyscall_windows.go45
13 files changed, 147 insertions, 36 deletions
diff --git a/Makefile b/Makefile
index c287f30a..c9a26d0a 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/ui/ui.go b/ui/ui.go
index 03ebfc7d..2625423a 100644
--- a/ui/ui.go
+++ b/ui/ui.go
@@ -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")
}
diff --git a/version.h b/version.h
index fc42a077..a309fd6d 100644
--- a/version.h
+++ b/version.h
@@ -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
+}