package system

import (
	"fmt"
	"github.com/buildkite/agent/v3/logger"
	"golang.org/x/sys/windows"
)

func VersionDump(_ logger.Logger) (string, error) {
	info := windows.RtlGetVersion()

	return fmt.Sprintf("Windows version %d.%d (Build %d)\n", info.MajorVersion, info.MinorVersion, info.BuildNumber), nil
}

package system

import (
	"fmt"
	"syscall"

	"github.com/buildkite/agent/v3/logger"
)

func VersionDump(_ logger.Logger) (string, error) {
	dll := syscall.MustLoadDLL("kernel32.dll")
	p := dll.MustFindProc("GetVersion")
	v, _, _ := p.Call()

	return fmt.Sprintf("Windows version %d.%d (Build %d)\n", byte(v), uint8(v>>8), uint16(v>>16)), nil
}

--- 
+++ 
@@ -2,15 +2,12 @@
 
 import (
 	"fmt"
-	"syscall"
-
 	"github.com/buildkite/agent/v3/logger"
+	"golang.org/x/sys/windows"
 )
 
 func VersionDump(_ logger.Logger) (string, error) {
-	dll := syscall.MustLoadDLL("kernel32.dll")
-	p := dll.MustFindProc("GetVersion")
-	v, _, _ := p.Call()
+	info := windows.RtlGetVersion()
 
-	return fmt.Sprintf("Windows version %d.%d (Build %d)\n", byte(v), uint8(v>>8), uint16(v>>16)), nil
+	return fmt.Sprintf("Windows version %d.%d (Build %d)\n", info.MajorVersion, info.MinorVersion, info.BuildNumber), nil
 }
Update the way we detect windows versions

While running the agent on Windows 10 I noticed we were submitting the
version as "Windows version 6.2", which maps to windows 8 [1].

According to MSDN, the GetVersion call we're using always reports
windows 8 for compatibility reasons[2]:

> GetVersion may be altered or unavailable for releases after Windows 8.1.
> Instead, use the Version Helper functions. For Windows 10 apps, please see
> [Targeting your applications for
> Windows](/windows/win32/sysinfo/targeting-your-application-at-windows-8-1).
>
> With the release of Windows 8.1, the behavior of the GetVersion API has changed
> in the value it will return for the operating system version. The value
> returned by the GetVersion function now depends on how the application is
> manifested.
>
> Applications not manifested for Windows 8.1 or Windows 10 will return the
> Windows 8 OS version value (6.2).

Adding a manifest seems to involve embedding XML in the executable, which doesn't sound like fun.

Lucky for us there's an alternative syscall that doesn't lie about the
version: RtlGetVersion [3].

I've tested this on:

1. Windows 10 (1909) and it reports version "10.0".
2. Windows 7 and it reports "6.1"

MSDN says RtlGetVersion is available from Windows 2000.

[1] https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_versions
[2] https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getversion
[3] https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlgetversion
