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