aboutsummaryrefslogtreecommitdiff
path: root/src/internal/syscall/windows
diff options
context:
space:
mode:
authorShibi J M <shibisjm@gmail.com>2025-05-20 03:59:15 +0000
committerGopher Robot <gobot@golang.org>2025-05-20 11:06:59 -0700
commitbe0cc937ec9c109da90ec4d7da5af89606f8c0cf (patch)
tree7081272ffb6c8b02282455e8072df8514a621749 /src/internal/syscall/windows
parent0c7311e9ca8440801b40928878db623f98e3008f (diff)
downloadgo-be0cc937ec9c109da90ec4d7da5af89606f8c0cf.tar.xz
net: avoid using Windows' TransmitFile on non-server machines
Windows API's TransmitFile function is limited to two concurrent operations on workstation and client versions of Windows. This change modifies the net.sendFile function to perform no work in such cases so that TransmitFile is avoided. Fixes #73746 Change-Id: Iba70d5d2758bf986e80c78254c8e9e10b39bb368 GitHub-Last-Rev: 315ddc0cd8034f52632dc31baf35057a8bad9bcd GitHub-Pull-Request: golang/go#73758 Reviewed-on: https://go-review.googlesource.com/c/go/+/673855 Reviewed-by: Alex Brainman <alex.brainman@gmail.com> Auto-Submit: Damien Neil <dneil@google.com> Reviewed-by: Quim Muntal <quimmuntal@gmail.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Damien Neil <dneil@google.com>
Diffstat (limited to 'src/internal/syscall/windows')
-rw-r--r--src/internal/syscall/windows/types_windows.go4
-rw-r--r--src/internal/syscall/windows/version_windows.go37
-rw-r--r--src/internal/syscall/windows/zsyscall_windows.go2
3 files changed, 36 insertions, 7 deletions
diff --git a/src/internal/syscall/windows/types_windows.go b/src/internal/syscall/windows/types_windows.go
index 9f8f61f6d9..93664b4b7d 100644
--- a/src/internal/syscall/windows/types_windows.go
+++ b/src/internal/syscall/windows/types_windows.go
@@ -256,3 +256,7 @@ type FILE_COMPLETION_INFORMATION struct {
Port syscall.Handle
Key uintptr
}
+
+// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-osversioninfoexa
+// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_osversioninfoexw
+const VER_NT_WORKSTATION = 0x0000001
diff --git a/src/internal/syscall/windows/version_windows.go b/src/internal/syscall/windows/version_windows.go
index cb5f6ba6cd..5edf7a01e2 100644
--- a/src/internal/syscall/windows/version_windows.go
+++ b/src/internal/syscall/windows/version_windows.go
@@ -11,28 +11,53 @@ import (
"unsafe"
)
-// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_osversioninfow
-type _OSVERSIONINFOW struct {
+// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ns-wdm-_osversioninfoexw
+type _OSVERSIONINFOEXW struct {
osVersionInfoSize uint32
majorVersion uint32
minorVersion uint32
buildNumber uint32
platformId uint32
csdVersion [128]uint16
+ servicePackMajor uint16
+ servicePackMinor uint16
+ suiteMask uint16
+ productType byte
+ reserved byte
}
// According to documentation, RtlGetVersion function always succeeds.
-//sys rtlGetVersion(info *_OSVERSIONINFOW) = ntdll.RtlGetVersion
+//sys rtlGetVersion(info *_OSVERSIONINFOEXW) = ntdll.RtlGetVersion
+
+// Retrieves version information of the current Windows OS
+// from the RtlGetVersion API.
+func getVersionInfo() *_OSVERSIONINFOEXW {
+ info := _OSVERSIONINFOEXW{}
+ info.osVersionInfoSize = uint32(unsafe.Sizeof(info))
+ rtlGetVersion(&info)
+ return &info
+}
// Version retrieves the major, minor, and build version numbers
// of the current Windows OS from the RtlGetVersion API.
func Version() (major, minor, build uint32) {
- info := _OSVERSIONINFOW{}
- info.osVersionInfoSize = uint32(unsafe.Sizeof(info))
- rtlGetVersion(&info)
+ info := getVersionInfo()
return info.majorVersion, info.minorVersion, info.buildNumber
}
+// SupportUnlimitedTransmitFile indicates whether the current
+// Windows version's TransmitFile function imposes any
+// concurrent operation limits.
+// Workstation and client versions of Windows limit the number
+// of concurrent TransmitFile operations allowed on the system
+// to a maximum of two. Please see:
+// https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nf-mswsock-transmitfile
+// https://golang.org/issue/73746
+var SupportUnlimitedTransmitFile = sync.OnceValue(func() bool {
+ info := getVersionInfo()
+ return info.productType != VER_NT_WORKSTATION
+})
+
var (
supportTCPKeepAliveIdle bool
supportTCPKeepAliveInterval bool
diff --git a/src/internal/syscall/windows/zsyscall_windows.go b/src/internal/syscall/windows/zsyscall_windows.go
index 8dcb377c3e..90cf0b92a4 100644
--- a/src/internal/syscall/windows/zsyscall_windows.go
+++ b/src/internal/syscall/windows/zsyscall_windows.go
@@ -539,7 +539,7 @@ func NtSetInformationFile(handle syscall.Handle, iosb *IO_STATUS_BLOCK, inBuffer
return
}
-func rtlGetVersion(info *_OSVERSIONINFOW) {
+func rtlGetVersion(info *_OSVERSIONINFOEXW) {
syscall.Syscall(procRtlGetVersion.Addr(), 1, uintptr(unsafe.Pointer(info)), 0, 0)
return
}