1
2
3
4
5 package windows
6
7 import (
8 "errors"
9 "sync"
10 "syscall"
11 "unsafe"
12 )
13
14
15 type _OSVERSIONINFOEXW struct {
16 osVersionInfoSize uint32
17 majorVersion uint32
18 minorVersion uint32
19 buildNumber uint32
20 platformId uint32
21 csdVersion [128]uint16
22 servicePackMajor uint16
23 servicePackMinor uint16
24 suiteMask uint16
25 productType byte
26 reserved byte
27 }
28
29
30
31
32
33
34 func getVersionInfo() *_OSVERSIONINFOEXW {
35 info := _OSVERSIONINFOEXW{}
36 info.osVersionInfoSize = uint32(unsafe.Sizeof(info))
37 rtlGetVersion(&info)
38 return &info
39 }
40
41
42
43 func Version() (major, minor, build uint32) {
44 info := getVersionInfo()
45 return info.majorVersion, info.minorVersion, info.buildNumber
46 }
47
48
49
50
51
52
53
54
55
56 var SupportUnlimitedTransmitFile = sync.OnceValue(func() bool {
57 info := getVersionInfo()
58 return info.productType != VER_NT_WORKSTATION
59 })
60
61 var (
62 supportTCPKeepAliveIdle bool
63 supportTCPKeepAliveInterval bool
64 supportTCPKeepAliveCount bool
65 )
66
67 var initTCPKeepAlive = sync.OnceFunc(func() {
68 s, err := WSASocket(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_TCP, nil, 0, WSA_FLAG_NO_HANDLE_INHERIT)
69 if err != nil {
70
71 major, _, build := Version()
72 supportTCPKeepAliveIdle = major >= 10 && build >= 16299
73 supportTCPKeepAliveInterval = major >= 10 && build >= 16299
74 supportTCPKeepAliveCount = major >= 10 && build >= 15063
75 return
76 }
77 defer syscall.Closesocket(s)
78 var optSupported = func(opt int) bool {
79 err := syscall.SetsockoptInt(s, syscall.IPPROTO_TCP, opt, 1)
80 return !errors.Is(err, syscall.WSAENOPROTOOPT)
81 }
82 supportTCPKeepAliveIdle = optSupported(TCP_KEEPIDLE)
83 supportTCPKeepAliveInterval = optSupported(TCP_KEEPINTVL)
84 supportTCPKeepAliveCount = optSupported(TCP_KEEPCNT)
85 })
86
87
88
89 func SupportTCPKeepAliveIdle() bool {
90 initTCPKeepAlive()
91 return supportTCPKeepAliveIdle
92 }
93
94
95
96 func SupportTCPKeepAliveInterval() bool {
97 initTCPKeepAlive()
98 return supportTCPKeepAliveInterval
99 }
100
101
102
103
104 func SupportTCPKeepAliveCount() bool {
105 initTCPKeepAlive()
106 return supportTCPKeepAliveCount
107 }
108
109
110
111
112 var SupportTCPInitialRTONoSYNRetransmissions = sync.OnceValue(func() bool {
113 major, _, build := Version()
114 return major >= 10 && build >= 16299
115 })
116
117
118
119
120 var SupportUnixSocket = sync.OnceValue(func() bool {
121 var size uint32
122
123
124 _, _ = syscall.WSAEnumProtocols(nil, nil, &size)
125 n := int32(size) / int32(unsafe.Sizeof(syscall.WSAProtocolInfo{}))
126
127 buf := make([]syscall.WSAProtocolInfo, n)
128 n, err := syscall.WSAEnumProtocols(nil, &buf[0], &size)
129 if err != nil {
130 return false
131 }
132 for i := int32(0); i < n; i++ {
133 if buf[i].AddressFamily == syscall.AF_UNIX {
134 return true
135 }
136 }
137 return false
138 })
139
View as plain text