]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/osinfo,runtime,syscall: use RtlGetVersion instead of RtlGetNtVersionNumbers
authorqmuntal <quimmuntal@gmail.com>
Tue, 12 Mar 2024 13:20:33 +0000 (14:20 +0100)
committerQuim Muntal <quimmuntal@gmail.com>
Thu, 21 Mar 2024 11:49:46 +0000 (11:49 +0000)
The RtlGetNtVersionNumbers function is not documented by Microsoft.
Use RtlGetVersion instead, which is documented and available on all
supported versions of Windows.

Cq-Include-Trybots: luci.golang.try:gotip-windows-amd64-longtest,gotip-windows-arm64
Change-Id: Ibaf0e2c28e673951476c5d863a829fd166705aea
Reviewed-on: https://go-review.googlesource.com/c/go/+/571015
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/internal/osinfo/os_windows.go
src/internal/syscall/windows/mksyscall.go
src/internal/syscall/windows/version_windows.go
src/internal/syscall/windows/zsyscall_windows.go
src/runtime/defs_windows.go
src/runtime/os_windows.go
src/syscall/syscall_windows.go
src/syscall/zsyscall_windows.go

index 8ffe4f3f6d86978d5f20638c71789d1be1e5813b..228369ea22dad2a68b638933cce804bbca9ae617 100644 (file)
@@ -14,6 +14,6 @@ import (
 
 // Version returns the OS version name/number.
 func Version() (string, error) {
-       major, minor, patch := windows.RtlGetNtVersionNumbers()
-       return fmt.Sprintf("%d.%d.%d", major, minor, patch), nil
+       info := windows.RtlGetVersion()
+       return fmt.Sprintf("%d.%d.%d", info.MajorVersion, info.MinorVersion, info.BuildNumber), nil
 }
index 81f08c627e6496ac38a316947a56d8893a4e5053..f97ab526f8150c8aa3e58357e4fca68e0efe2b1c 100644 (file)
@@ -6,4 +6,4 @@
 
 package windows
 
-//go:generate go run ../../../syscall/mksyscall_windows.go -output zsyscall_windows.go syscall_windows.go security_windows.go psapi_windows.go symlink_windows.go
+//go:generate go run ../../../syscall/mksyscall_windows.go -output zsyscall_windows.go syscall_windows.go security_windows.go psapi_windows.go symlink_windows.go version_windows.go
index 6da2d585492b94fae202728b8fc43f600c13917b..ff21fc59e5bf53320c5eefc392d9548f87a2d9b1 100644 (file)
@@ -11,19 +11,28 @@ import (
        "unsafe"
 )
 
+// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_osversioninfow
+type _OSVERSIONINFOW struct {
+       osVersionInfoSize uint32
+       majorVersion      uint32
+       minorVersion      uint32
+       buildNumber       uint32
+       platformId        uint32
+       csdVersion        [128]uint16
+}
+
+// According to documentation, RtlGetVersion function always succeeds.
+//sys  rtlGetVersion(info *_OSVERSIONINFOW) = ntdll.RtlGetVersion
+
 // version retrieves the major, minor, and build version numbers
-// of the current Windows OS from the RtlGetNtVersionNumbers API
-// and parse the results properly.
+// of the current Windows OS from the RtlGetVersion API.
 func version() (major, minor, build uint32) {
-       rtlGetNtVersionNumbers(&major, &minor, &build)
-       build &= 0x7fff
-       return
+       info := _OSVERSIONINFOW{}
+       info.osVersionInfoSize = uint32(unsafe.Sizeof(info))
+       rtlGetVersion(&info)
+       return info.majorVersion, info.minorVersion, info.buildNumber
 }
 
-//go:linkname rtlGetNtVersionNumbers syscall.rtlGetNtVersionNumbers
-//go:noescape
-func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32)
-
 var (
        supportTCPKeepAliveIdle     bool
        supportTCPKeepAliveInterval bool
index 7d3cd37b92bed1d707132fd12d8241df35af8d27..414ad2647d1abd2b14d7ac3cd77f2c73d6f90da0 100644 (file)
@@ -42,6 +42,7 @@ var (
        modiphlpapi         = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll"))
        modkernel32         = syscall.NewLazyDLL(sysdll.Add("kernel32.dll"))
        modnetapi32         = syscall.NewLazyDLL(sysdll.Add("netapi32.dll"))
+       modntdll            = syscall.NewLazyDLL(sysdll.Add("ntdll.dll"))
        modpsapi            = syscall.NewLazyDLL(sysdll.Add("psapi.dll"))
        moduserenv          = syscall.NewLazyDLL(sysdll.Add("userenv.dll"))
        modws2_32           = syscall.NewLazyDLL(sysdll.Add("ws2_32.dll"))
@@ -82,6 +83,7 @@ var (
        procNetShareAdd                       = modnetapi32.NewProc("NetShareAdd")
        procNetShareDel                       = modnetapi32.NewProc("NetShareDel")
        procNetUserGetLocalGroups             = modnetapi32.NewProc("NetUserGetLocalGroups")
+       procRtlGetVersion                     = modntdll.NewProc("RtlGetVersion")
        procGetProcessMemoryInfo              = modpsapi.NewProc("GetProcessMemoryInfo")
        procCreateEnvironmentBlock            = moduserenv.NewProc("CreateEnvironmentBlock")
        procDestroyEnvironmentBlock           = moduserenv.NewProc("DestroyEnvironmentBlock")
@@ -391,6 +393,11 @@ func NetUserGetLocalGroups(serverName *uint16, userName *uint16, level uint32, f
        return
 }
 
+func rtlGetVersion(info *_OSVERSIONINFOW) {
+       syscall.Syscall(procRtlGetVersion.Addr(), 1, uintptr(unsafe.Pointer(info)), 0, 0)
+       return
+}
+
 func GetProcessMemoryInfo(handle syscall.Handle, memCounters *PROCESS_MEMORY_COUNTERS, cb uint32) (err error) {
        r1, _, e1 := syscall.Syscall(procGetProcessMemoryInfo.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(memCounters)), uintptr(cb))
        if r1 == 0 {
index 2dbe1446898e59ee9c012953cfcd8a60c60268b7..2f09afbe1fef4cd5c61634afce76d23665bc63dd 100644 (file)
@@ -89,3 +89,13 @@ type memoryBasicInformation struct {
        protect           uint32
        type_             uint32
 }
+
+// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_osversioninfow
+type _OSVERSIONINFOW struct {
+       osVersionInfoSize uint32
+       majorVersion      uint32
+       minorVersion      uint32
+       buildNumber       uint32
+       platformId        uint32
+       csdVersion        [128]uint16
+}
index b5258bb57d1c5d707de3636db57d2091954984a7..244ab23dad180ed20025661978da97738484055d 100644 (file)
@@ -135,7 +135,7 @@ var (
        _NtAssociateWaitCompletionPacket stdFunction
        _NtCancelWaitCompletionPacket    stdFunction
        _RtlGetCurrentPeb                stdFunction
-       _RtlGetNtVersionNumbers          stdFunction
+       _RtlGetVersion                   stdFunction
 
        // These are from non-kernel32.dll, so we prefer to LoadLibraryEx them.
        _timeBeginPeriod,
@@ -268,7 +268,7 @@ func loadOptionalSyscalls() {
                }
        }
        _RtlGetCurrentPeb = windowsFindfunc(n32, []byte("RtlGetCurrentPeb\000"))
-       _RtlGetNtVersionNumbers = windowsFindfunc(n32, []byte("RtlGetNtVersionNumbers\000"))
+       _RtlGetVersion = windowsFindfunc(n32, []byte("RtlGetVersion\000"))
 }
 
 func monitorSuspendResume() {
@@ -437,9 +437,10 @@ func initLongPathSupport() {
        )
 
        // Check that we're ≥ 10.0.15063.
-       var maj, min, build uint32
-       stdcall3(_RtlGetNtVersionNumbers, uintptr(unsafe.Pointer(&maj)), uintptr(unsafe.Pointer(&min)), uintptr(unsafe.Pointer(&build)))
-       if maj < 10 || (maj == 10 && min == 0 && build&0xffff < 15063) {
+       info := _OSVERSIONINFOW{}
+       info.osVersionInfoSize = uint32(unsafe.Sizeof(info))
+       stdcall1(_RtlGetVersion, uintptr(unsafe.Pointer(&info)))
+       if info.majorVersion < 10 || (info.majorVersion == 10 && info.minorVersion == 0 && info.buildNumber < 15063) {
                return
        }
 
index 59ce2b020685ecc1d5a1d54e38f5477c10ba750b..d49ee522c4fe883fd1f27ec05348d6d154b30a96 100644 (file)
@@ -233,7 +233,6 @@ func NewCallbackCDecl(fn any) uintptr {
 //sys  FreeLibrary(handle Handle) (err error)
 //sys  GetProcAddress(module Handle, procname string) (proc uintptr, err error)
 //sys  GetVersion() (ver uint32, err error)
-//sys  rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) = ntdll.RtlGetNtVersionNumbers
 //sys  formatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW
 //sys  ExitProcess(exitcode uint32)
 //sys  CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) [failretval==InvalidHandle] = CreateFileW
index 630270812db49d28ace56d84b877b979c0a12be4..d8d8594a55611129f05179e898d30980409f6ec2 100644 (file)
@@ -43,7 +43,6 @@ var (
        modkernel32 = NewLazyDLL(sysdll.Add("kernel32.dll"))
        modmswsock  = NewLazyDLL(sysdll.Add("mswsock.dll"))
        modnetapi32 = NewLazyDLL(sysdll.Add("netapi32.dll"))
-       modntdll    = NewLazyDLL(sysdll.Add("ntdll.dll"))
        modsecur32  = NewLazyDLL(sysdll.Add("secur32.dll"))
        modshell32  = NewLazyDLL(sysdll.Add("shell32.dll"))
        moduserenv  = NewLazyDLL(sysdll.Add("userenv.dll"))
@@ -168,7 +167,6 @@ var (
        procNetApiBufferFree                   = modnetapi32.NewProc("NetApiBufferFree")
        procNetGetJoinInformation              = modnetapi32.NewProc("NetGetJoinInformation")
        procNetUserGetInfo                     = modnetapi32.NewProc("NetUserGetInfo")
-       procRtlGetNtVersionNumbers             = modntdll.NewProc("RtlGetNtVersionNumbers")
        procGetUserNameExW                     = modsecur32.NewProc("GetUserNameExW")
        procTranslateNameW                     = modsecur32.NewProc("TranslateNameW")
        procCommandLineToArgvW                 = modshell32.NewProc("CommandLineToArgvW")
@@ -1212,11 +1210,6 @@ func NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **by
        return
 }
 
-func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) {
-       Syscall(procRtlGetNtVersionNumbers.Addr(), 3, uintptr(unsafe.Pointer(majorVersion)), uintptr(unsafe.Pointer(minorVersion)), uintptr(unsafe.Pointer(buildNumber)))
-       return
-}
-
 func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) {
        r1, _, e1 := Syscall(procGetUserNameExW.Addr(), 3, uintptr(nameFormat), uintptr(unsafe.Pointer(nameBuffre)), uintptr(unsafe.Pointer(nSize)))
        if r1&0xff == 0 {