aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/version/version_windows.go
blob: b583d160d97e7b1b97851599fb6453e72409ce72 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/* SPDX-License-Identifier: MIT
 *
 * Copyright (C) 2019 WireGuard LLC. All Rights Reserved.
 */

package version

import (
	"os"
	"runtime"
	"unsafe"

	"golang.org/x/sys/windows"
)

//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

var cachedVersion, cachedName string

func RunningNameVersion() (name, version string) {
	if len(cachedVersion) != 0 || len(cachedName) != 0 {
		return cachedName, cachedVersion
	}
	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 val16 *uint16
	err = VerQueryValue(&buffer[0], windows.StringToUTF16Ptr(`\StringFileInfo\040904b0\ProductName`), (**byte)(unsafe.Pointer(&val16)), &size)
	if err != nil {
		panic(err)
	}
	name = windows.UTF16ToString((*[(1 << 30) - 1]uint16)(unsafe.Pointer(val16))[:size])
	err = VerQueryValue(&buffer[0], windows.StringToUTF16Ptr(`\StringFileInfo\040904b0\ProductVersion`), (**byte)(unsafe.Pointer(&val16)), &size)
	if err != nil {
		panic(err)
	}
	version = windows.UTF16ToString((*[(1 << 30) - 1]uint16)(unsafe.Pointer(val16))[:size])
	runtime.KeepAlive(buffer)

	cachedName = name
	cachedVersion = version
	return
}