github.com/geraldss/go/src@v0.0.0-20210511222824-ac7d0ebfc235/internal/syscall/windows/syscall_windows.go (about) 1 // Copyright 2014 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package windows 6 7 import ( 8 "internal/unsafeheader" 9 "sync" 10 "syscall" 11 "unicode/utf16" 12 "unsafe" 13 ) 14 15 // UTF16PtrToString is like UTF16ToString, but takes *uint16 16 // as a parameter instead of []uint16. 17 func UTF16PtrToString(p *uint16) string { 18 if p == nil { 19 return "" 20 } 21 // Find NUL terminator. 22 end := unsafe.Pointer(p) 23 n := 0 24 for *(*uint16)(end) != 0 { 25 end = unsafe.Pointer(uintptr(end) + unsafe.Sizeof(*p)) 26 n++ 27 } 28 // Turn *uint16 into []uint16. 29 var s []uint16 30 hdr := (*unsafeheader.Slice)(unsafe.Pointer(&s)) 31 hdr.Data = unsafe.Pointer(p) 32 hdr.Cap = n 33 hdr.Len = n 34 // Decode []uint16 into string. 35 return string(utf16.Decode(s)) 36 } 37 38 const ( 39 ERROR_SHARING_VIOLATION syscall.Errno = 32 40 ERROR_LOCK_VIOLATION syscall.Errno = 33 41 ERROR_NOT_SUPPORTED syscall.Errno = 50 42 ERROR_CALL_NOT_IMPLEMENTED syscall.Errno = 120 43 ERROR_INVALID_NAME syscall.Errno = 123 44 ERROR_LOCK_FAILED syscall.Errno = 167 45 ERROR_NO_UNICODE_TRANSLATION syscall.Errno = 1113 46 ) 47 48 const GAA_FLAG_INCLUDE_PREFIX = 0x00000010 49 50 const ( 51 IF_TYPE_OTHER = 1 52 IF_TYPE_ETHERNET_CSMACD = 6 53 IF_TYPE_ISO88025_TOKENRING = 9 54 IF_TYPE_PPP = 23 55 IF_TYPE_SOFTWARE_LOOPBACK = 24 56 IF_TYPE_ATM = 37 57 IF_TYPE_IEEE80211 = 71 58 IF_TYPE_TUNNEL = 131 59 IF_TYPE_IEEE1394 = 144 60 ) 61 62 type SocketAddress struct { 63 Sockaddr *syscall.RawSockaddrAny 64 SockaddrLength int32 65 } 66 67 type IpAdapterUnicastAddress struct { 68 Length uint32 69 Flags uint32 70 Next *IpAdapterUnicastAddress 71 Address SocketAddress 72 PrefixOrigin int32 73 SuffixOrigin int32 74 DadState int32 75 ValidLifetime uint32 76 PreferredLifetime uint32 77 LeaseLifetime uint32 78 OnLinkPrefixLength uint8 79 } 80 81 type IpAdapterAnycastAddress struct { 82 Length uint32 83 Flags uint32 84 Next *IpAdapterAnycastAddress 85 Address SocketAddress 86 } 87 88 type IpAdapterMulticastAddress struct { 89 Length uint32 90 Flags uint32 91 Next *IpAdapterMulticastAddress 92 Address SocketAddress 93 } 94 95 type IpAdapterDnsServerAdapter struct { 96 Length uint32 97 Reserved uint32 98 Next *IpAdapterDnsServerAdapter 99 Address SocketAddress 100 } 101 102 type IpAdapterPrefix struct { 103 Length uint32 104 Flags uint32 105 Next *IpAdapterPrefix 106 Address SocketAddress 107 PrefixLength uint32 108 } 109 110 type IpAdapterAddresses struct { 111 Length uint32 112 IfIndex uint32 113 Next *IpAdapterAddresses 114 AdapterName *byte 115 FirstUnicastAddress *IpAdapterUnicastAddress 116 FirstAnycastAddress *IpAdapterAnycastAddress 117 FirstMulticastAddress *IpAdapterMulticastAddress 118 FirstDnsServerAddress *IpAdapterDnsServerAdapter 119 DnsSuffix *uint16 120 Description *uint16 121 FriendlyName *uint16 122 PhysicalAddress [syscall.MAX_ADAPTER_ADDRESS_LENGTH]byte 123 PhysicalAddressLength uint32 124 Flags uint32 125 Mtu uint32 126 IfType uint32 127 OperStatus uint32 128 Ipv6IfIndex uint32 129 ZoneIndices [16]uint32 130 FirstPrefix *IpAdapterPrefix 131 /* more fields might be present here. */ 132 } 133 134 type FILE_BASIC_INFO struct { 135 CreationTime syscall.Filetime 136 LastAccessTime syscall.Filetime 137 LastWriteTime syscall.Filetime 138 ChangedTime syscall.Filetime 139 FileAttributes uint32 140 } 141 142 const ( 143 IfOperStatusUp = 1 144 IfOperStatusDown = 2 145 IfOperStatusTesting = 3 146 IfOperStatusUnknown = 4 147 IfOperStatusDormant = 5 148 IfOperStatusNotPresent = 6 149 IfOperStatusLowerLayerDown = 7 150 ) 151 152 //sys GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) = iphlpapi.GetAdaptersAddresses 153 //sys GetComputerNameEx(nameformat uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW 154 //sys MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) = MoveFileExW 155 //sys GetModuleFileName(module syscall.Handle, fn *uint16, len uint32) (n uint32, err error) = kernel32.GetModuleFileNameW 156 //sys SetFileInformationByHandle(handle syscall.Handle, fileInformationClass uint32, buf uintptr, bufsize uint32) (err error) = kernel32.SetFileInformationByHandle 157 158 const ( 159 WSA_FLAG_OVERLAPPED = 0x01 160 WSA_FLAG_NO_HANDLE_INHERIT = 0x80 161 162 WSAEMSGSIZE syscall.Errno = 10040 163 164 MSG_PEEK = 0x2 165 MSG_TRUNC = 0x0100 166 MSG_CTRUNC = 0x0200 167 168 socket_error = uintptr(^uint32(0)) 169 ) 170 171 var WSAID_WSASENDMSG = syscall.GUID{ 172 Data1: 0xa441e712, 173 Data2: 0x754f, 174 Data3: 0x43ca, 175 Data4: [8]byte{0x84, 0xa7, 0x0d, 0xee, 0x44, 0xcf, 0x60, 0x6d}, 176 } 177 178 var WSAID_WSARECVMSG = syscall.GUID{ 179 Data1: 0xf689d7c8, 180 Data2: 0x6f1f, 181 Data3: 0x436b, 182 Data4: [8]byte{0x8a, 0x53, 0xe5, 0x4f, 0xe3, 0x51, 0xc3, 0x22}, 183 } 184 185 var sendRecvMsgFunc struct { 186 once sync.Once 187 sendAddr uintptr 188 recvAddr uintptr 189 err error 190 } 191 192 type WSAMsg struct { 193 Name syscall.Pointer 194 Namelen int32 195 Buffers *syscall.WSABuf 196 BufferCount uint32 197 Control syscall.WSABuf 198 Flags uint32 199 } 200 201 //sys WSASocket(af int32, typ int32, protocol int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = ws2_32.WSASocketW 202 203 func loadWSASendRecvMsg() error { 204 sendRecvMsgFunc.once.Do(func() { 205 var s syscall.Handle 206 s, sendRecvMsgFunc.err = syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP) 207 if sendRecvMsgFunc.err != nil { 208 return 209 } 210 defer syscall.CloseHandle(s) 211 var n uint32 212 sendRecvMsgFunc.err = syscall.WSAIoctl(s, 213 syscall.SIO_GET_EXTENSION_FUNCTION_POINTER, 214 (*byte)(unsafe.Pointer(&WSAID_WSARECVMSG)), 215 uint32(unsafe.Sizeof(WSAID_WSARECVMSG)), 216 (*byte)(unsafe.Pointer(&sendRecvMsgFunc.recvAddr)), 217 uint32(unsafe.Sizeof(sendRecvMsgFunc.recvAddr)), 218 &n, nil, 0) 219 if sendRecvMsgFunc.err != nil { 220 return 221 } 222 sendRecvMsgFunc.err = syscall.WSAIoctl(s, 223 syscall.SIO_GET_EXTENSION_FUNCTION_POINTER, 224 (*byte)(unsafe.Pointer(&WSAID_WSASENDMSG)), 225 uint32(unsafe.Sizeof(WSAID_WSASENDMSG)), 226 (*byte)(unsafe.Pointer(&sendRecvMsgFunc.sendAddr)), 227 uint32(unsafe.Sizeof(sendRecvMsgFunc.sendAddr)), 228 &n, nil, 0) 229 }) 230 return sendRecvMsgFunc.err 231 } 232 233 func WSASendMsg(fd syscall.Handle, msg *WSAMsg, flags uint32, bytesSent *uint32, overlapped *syscall.Overlapped, croutine *byte) error { 234 err := loadWSASendRecvMsg() 235 if err != nil { 236 return err 237 } 238 r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.sendAddr, 6, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(flags), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine))) 239 if r1 == socket_error { 240 if e1 != 0 { 241 err = errnoErr(e1) 242 } else { 243 err = syscall.EINVAL 244 } 245 } 246 return err 247 } 248 249 func WSARecvMsg(fd syscall.Handle, msg *WSAMsg, bytesReceived *uint32, overlapped *syscall.Overlapped, croutine *byte) error { 250 err := loadWSASendRecvMsg() 251 if err != nil { 252 return err 253 } 254 r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.recvAddr, 5, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(unsafe.Pointer(bytesReceived)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0) 255 if r1 == socket_error { 256 if e1 != 0 { 257 err = errnoErr(e1) 258 } else { 259 err = syscall.EINVAL 260 } 261 } 262 return err 263 } 264 265 const ( 266 ComputerNameNetBIOS = 0 267 ComputerNameDnsHostname = 1 268 ComputerNameDnsDomain = 2 269 ComputerNameDnsFullyQualified = 3 270 ComputerNamePhysicalNetBIOS = 4 271 ComputerNamePhysicalDnsHostname = 5 272 ComputerNamePhysicalDnsDomain = 6 273 ComputerNamePhysicalDnsFullyQualified = 7 274 ComputerNameMax = 8 275 276 MOVEFILE_REPLACE_EXISTING = 0x1 277 MOVEFILE_COPY_ALLOWED = 0x2 278 MOVEFILE_DELAY_UNTIL_REBOOT = 0x4 279 MOVEFILE_WRITE_THROUGH = 0x8 280 MOVEFILE_CREATE_HARDLINK = 0x10 281 MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20 282 ) 283 284 func Rename(oldpath, newpath string) error { 285 from, err := syscall.UTF16PtrFromString(oldpath) 286 if err != nil { 287 return err 288 } 289 to, err := syscall.UTF16PtrFromString(newpath) 290 if err != nil { 291 return err 292 } 293 return MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING) 294 } 295 296 //sys LockFileEx(file syscall.Handle, flags uint32, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *syscall.Overlapped) (err error) = kernel32.LockFileEx 297 //sys UnlockFileEx(file syscall.Handle, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *syscall.Overlapped) (err error) = kernel32.UnlockFileEx 298 299 const ( 300 LOCKFILE_FAIL_IMMEDIATELY = 0x00000001 301 LOCKFILE_EXCLUSIVE_LOCK = 0x00000002 302 ) 303 304 const MB_ERR_INVALID_CHARS = 8 305 306 //sys GetACP() (acp uint32) = kernel32.GetACP 307 //sys GetConsoleCP() (ccp uint32) = kernel32.GetConsoleCP 308 //sys MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar 309 //sys GetCurrentThread() (pseudoHandle syscall.Handle, err error) = kernel32.GetCurrentThread 310 311 const STYPE_DISKTREE = 0x00 312 313 type SHARE_INFO_2 struct { 314 Netname *uint16 315 Type uint32 316 Remark *uint16 317 Permissions uint32 318 MaxUses uint32 319 CurrentUses uint32 320 Path *uint16 321 Passwd *uint16 322 } 323 324 //sys NetShareAdd(serverName *uint16, level uint32, buf *byte, parmErr *uint16) (neterr error) = netapi32.NetShareAdd 325 //sys NetShareDel(serverName *uint16, netName *uint16, reserved uint32) (neterr error) = netapi32.NetShareDel 326 327 const ( 328 FILE_NAME_NORMALIZED = 0x0 329 FILE_NAME_OPENED = 0x8 330 331 VOLUME_NAME_DOS = 0x0 332 VOLUME_NAME_GUID = 0x1 333 VOLUME_NAME_NONE = 0x4 334 VOLUME_NAME_NT = 0x2 335 ) 336 337 //sys GetFinalPathNameByHandle(file syscall.Handle, filePath *uint16, filePathSize uint32, flags uint32) (n uint32, err error) = kernel32.GetFinalPathNameByHandleW 338 339 func LoadGetFinalPathNameByHandle() error { 340 return procGetFinalPathNameByHandleW.Find() 341 } 342 343 //sys CreateEnvironmentBlock(block **uint16, token syscall.Token, inheritExisting bool) (err error) = userenv.CreateEnvironmentBlock 344 //sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock 345 346 //sys RtlGenRandom(buf []byte) (err error) = advapi32.SystemFunction036